From aea43f98d10769f78118082921ca7df406fc83a9 Mon Sep 17 00:00:00 2001 From: matt123p Date: Thu, 12 Sep 2019 17:56:13 +0100 Subject: [PATCH 001/551] Add thread locking to improve stability. (#585) * Add thread locking to improve stability. * Do not use thread locking with the ESP8266, but instead use an empty placeholder class that can be used to implement locking at a later date. --- src/AsyncWebSocket.cpp | 4 ++ src/AsyncWebSocket.h | 4 ++ src/AsyncWebSynchronization.h | 87 +++++++++++++++++++++++++++++++++++ 3 files changed, 95 insertions(+) create mode 100644 src/AsyncWebSynchronization.h diff --git a/src/AsyncWebSocket.cpp b/src/AsyncWebSocket.cpp index 9bd037a14..3f2ad13c2 100644 --- a/src/AsyncWebSocket.cpp +++ b/src/AsyncWebSocket.cpp @@ -1197,6 +1197,7 @@ AsyncWebSocketMessageBuffer * AsyncWebSocket::makeBuffer(size_t size) { AsyncWebSocketMessageBuffer * buffer = new AsyncWebSocketMessageBuffer(size); if (buffer) { + AsyncWebLockGuard l(_lock); _buffers.add(buffer); } return buffer; @@ -1207,6 +1208,7 @@ AsyncWebSocketMessageBuffer * AsyncWebSocket::makeBuffer(uint8_t * data, size_t AsyncWebSocketMessageBuffer * buffer = new AsyncWebSocketMessageBuffer(data, size); if (buffer) { + AsyncWebLockGuard l(_lock); _buffers.add(buffer); } @@ -1215,6 +1217,8 @@ AsyncWebSocketMessageBuffer * AsyncWebSocket::makeBuffer(uint8_t * data, size_t void AsyncWebSocket::_cleanBuffers() { + AsyncWebLockGuard l(_lock); + for(AsyncWebSocketMessageBuffer * c: _buffers){ if(c && c->canDelete()){ _buffers.remove(c); diff --git a/src/AsyncWebSocket.h b/src/AsyncWebSocket.h index 2a47a0d83..8e2954eb5 100644 --- a/src/AsyncWebSocket.h +++ b/src/AsyncWebSocket.h @@ -31,6 +31,8 @@ #endif #include +#include "AsyncWebSynchronization.h" + #ifdef ESP8266 #include #endif @@ -236,6 +238,8 @@ class AsyncWebSocket: public AsyncWebHandler { uint32_t _cNextId; AwsEventHandler _eventHandler; bool _enabled; + AsyncWebLock _lock; + public: AsyncWebSocket(const String& url); ~AsyncWebSocket(); diff --git a/src/AsyncWebSynchronization.h b/src/AsyncWebSynchronization.h new file mode 100644 index 000000000..f36c52dcf --- /dev/null +++ b/src/AsyncWebSynchronization.h @@ -0,0 +1,87 @@ +#ifndef ASYNCWEBSYNCHRONIZATION_H_ +#define ASYNCWEBSYNCHRONIZATION_H_ + +// Synchronisation is only available on ESP32, as the ESP8266 isn't using FreeRTOS by default + +#include + +#ifdef ESP32 + +// This is the ESP32 version of the Sync Lock, using the FreeRTOS Semaphore +class AsyncWebLock +{ +private: + SemaphoreHandle_t _lock; + mutable void *_lockedBy; + +public: + AsyncWebLock() { + _lock = xSemaphoreCreateBinary(); + _lockedBy = NULL; + xSemaphoreGive(_lock); + } + + ~AsyncWebLock() { + vSemaphoreDelete(_lock); + } + + bool lock() const { + extern void *pxCurrentTCB; + if (_lockedBy != pxCurrentTCB) { + xSemaphoreTake(_lock, portMAX_DELAY); + _lockedBy = pxCurrentTCB; + return true; + } + return false; + } + + void unlock() const { + _lockedBy = NULL; + xSemaphoreGive(_lock); + } +}; + +#else + +// This is the 8266 version of the Sync Lock which is currently unimplemented +class AsyncWebLock +{ + +public: + AsyncWebLock() { + } + + ~AsyncWebLock() { + } + + bool lock() const { + return false; + } + + void unlock() const { + } +}; +#endif + +class AsyncWebLockGuard +{ +private: + const AsyncWebLock *_lock; + +public: + AsyncWebLockGuard(const AsyncWebLock &l) { + if (l.lock()) { + _lock = &l; + } else { + _lock = NULL; + } + } + + ~AsyncWebLockGuard() { + if (_lock) { + _lock->unlock(); + } + } +}; + +#endif // ASYNCWEBSYNCHRONIZATION_H_ \ No newline at end of file From 0769521ef88b599324db1fcb288706762a8c400a Mon Sep 17 00:00:00 2001 From: Me No Dev Date: Sat, 21 Sep 2019 11:46:53 +0300 Subject: [PATCH 002/551] Try to build against PIO (#598) --- .travis.yml | 10 ++++++++++ travis/build-pio.sh | 24 ++++++++++++++++++++++++ 2 files changed, 34 insertions(+) create mode 100644 travis/build-pio.sh diff --git a/.travis.yml b/.travis.yml index 204ffe379..fd1f74785 100644 --- a/.travis.yml +++ b/.travis.yml @@ -24,6 +24,16 @@ jobs: stage: build script: bash $TRAVIS_BUILD_DIR/travis/build.sh esp8266 + - name: "Build Platformio ESP32" + if: tag IS blank AND (type = pull_request OR (type = push AND branch = master)) + stage: build + script: bash $TRAVIS_BUILD_DIR/travis/build-pio.sh esp32dev + + - name: "Build Platformio ESP8266" + if: tag IS blank AND (type = pull_request OR (type = push AND branch = master)) + stage: build + script: bash $TRAVIS_BUILD_DIR/travis/build-pio.sh esp12e + notifications: email: on_success: change diff --git a/travis/build-pio.sh b/travis/build-pio.sh new file mode 100644 index 000000000..ff433516f --- /dev/null +++ b/travis/build-pio.sh @@ -0,0 +1,24 @@ +#!/bin/bash + +BOARD=$1 + +echo -e "travis_fold:start:install_pio" +pip install -U platformio + +platformio lib install https://github.com/bblanchon/ArduinoJson.git + +case $BOARD in +esp32dev) + platformio lib -g install https://github.com/me-no-dev/AsyncTCP.git + ;; +esp12e) + platformio lib -g install https://github.com/me-no-dev/ESPAsyncTCP.git || true + ;; +esac +echo -e "travis_fold:end:install_pio" + +echo -e "travis_fold:start:test_pio" +for EXAMPLE in $PWD/examples/*/*.ino; do + platformio ci $EXAMPLE -l '.' -b $BOARD +done +echo -e "travis_fold:end:test_pio" From 41cf4893c6867d413a935d96131fee2f709408a6 Mon Sep 17 00:00:00 2001 From: Me No Dev Date: Sat, 21 Sep 2019 12:48:38 +0300 Subject: [PATCH 003/551] Setup Github CI (#599) * Setup Github CI * Update main.yml * Update build-pio.sh * Add error checks to PIO script * Update build-pio.sh --- .github/workflows/main.yml | 54 ++++++++++++++++++++++++++++++++++++++ travis/build-pio.sh | 15 ++++++++--- 2 files changed, 65 insertions(+), 4 deletions(-) create mode 100644 .github/workflows/main.yml diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 000000000..04c813074 --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,54 @@ +name: ESP Async Web Server CI + +on: + push: + branches: + - master + - release/* + pull_request: + +jobs: + + build-arduino-esp32: + name: Build Arduino ESP32 + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - name: Build Tests + env: + TRAVIS_BUILD_DIR: ${{ github.workspace }} + run: bash $TRAVIS_BUILD_DIR/travis/build.sh esp32 + + build-arduino-esp8266: + name: Build Arduino ESP8266 + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - name: Build Tests + env: + TRAVIS_BUILD_DIR: ${{ github.workspace }} + run: bash $TRAVIS_BUILD_DIR/travis/build.sh esp8266 + + build-pio-esp32: + name: Build PlatformIO ESP32 + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - name: Install Python Wheel + run: pip install wheel + - name: Build Tests + env: + TRAVIS_BUILD_DIR: ${{ github.workspace }} + run: bash $TRAVIS_BUILD_DIR/travis/build-pio.sh esp32dev + + build-pio-esp8266: + name: Build PlatformIO ESP8266 + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - name: Install Python Wheel + run: pip install wheel + - name: Build Tests + env: + TRAVIS_BUILD_DIR: ${{ github.workspace }} + run: bash $TRAVIS_BUILD_DIR/travis/build-pio.sh esp12e diff --git a/travis/build-pio.sh b/travis/build-pio.sh index ff433516f..e2a3f3d26 100644 --- a/travis/build-pio.sh +++ b/travis/build-pio.sh @@ -4,21 +4,28 @@ BOARD=$1 echo -e "travis_fold:start:install_pio" pip install -U platformio +if [ $? -ne 0 ]; then exit 1; fi -platformio lib install https://github.com/bblanchon/ArduinoJson.git +python -m platformio lib --storage-dir $PWD +if [ $? -ne 0 ]; then exit 1; fi + +python -m platformio lib -g install https://github.com/bblanchon/ArduinoJson.git +if [ $? -ne 0 ]; then exit 1; fi case $BOARD in esp32dev) - platformio lib -g install https://github.com/me-no-dev/AsyncTCP.git + python -m platformio lib -g install https://github.com/me-no-dev/AsyncTCP.git ;; esp12e) - platformio lib -g install https://github.com/me-no-dev/ESPAsyncTCP.git || true + python -m platformio lib -g install https://github.com/me-no-dev/ESPAsyncTCP.git || true ;; esac +if [ $? -ne 0 ]; then exit 1; fi echo -e "travis_fold:end:install_pio" echo -e "travis_fold:start:test_pio" for EXAMPLE in $PWD/examples/*/*.ino; do - platformio ci $EXAMPLE -l '.' -b $BOARD + python -m platformio ci $EXAMPLE -l '.' -b $BOARD + if [ $? -ne 0 ]; then exit 1; fi done echo -e "travis_fold:end:test_pio" From 5ea49e313d7df1e004d32fa988547753ce4c4220 Mon Sep 17 00:00:00 2001 From: matt123p Date: Sat, 21 Sep 2019 11:27:34 +0100 Subject: [PATCH 004/551] Prevent an assertion failure when using WebSockets (#584) Frequently when using Web Sockets you will get the assert failure: assertion "new_rcv_ann_wnd <= 0xffff" failed: file "/Users/ficeto/Desktop/ESP32/ESP32/esp-idf-public/components/lwip/lwip/src/core/tcp.c", line 779, function: tcp_update_rcv_ann_wnd This will happen particulary when you close the browser window. This change prevents the issue from occuring. --- src/AsyncWebSocket.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/AsyncWebSocket.cpp b/src/AsyncWebSocket.cpp index 3f2ad13c2..dc99d3933 100644 --- a/src/AsyncWebSocket.cpp +++ b/src/AsyncWebSocket.cpp @@ -680,6 +680,7 @@ void AsyncWebSocketClient::_onData(void *pbuf, size_t plen){ _client->close(true); } else { _status = WS_DISCONNECTING; + _client->ackLater(); _queueControl(new AsyncWebSocketControl(WS_DISCONNECT, data, datalen)); } } else if(_pinfo.opcode == WS_PING){ From 052df0b6a81a5edc6003d6fe2b0ff2d09f1525b1 Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Sat, 21 Sep 2019 15:16:09 +0300 Subject: [PATCH 005/551] Update build-pio.sh --- travis/build-pio.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/travis/build-pio.sh b/travis/build-pio.sh index e2a3f3d26..fe6530bc9 100644 --- a/travis/build-pio.sh +++ b/travis/build-pio.sh @@ -6,7 +6,7 @@ echo -e "travis_fold:start:install_pio" pip install -U platformio if [ $? -ne 0 ]; then exit 1; fi -python -m platformio lib --storage-dir $PWD +python -m platformio lib --storage-dir $TRAVIS_BUILD_DIR install if [ $? -ne 0 ]; then exit 1; fi python -m platformio lib -g install https://github.com/bblanchon/ArduinoJson.git @@ -24,7 +24,7 @@ if [ $? -ne 0 ]; then exit 1; fi echo -e "travis_fold:end:install_pio" echo -e "travis_fold:start:test_pio" -for EXAMPLE in $PWD/examples/*/*.ino; do +for EXAMPLE in $TRAVIS_BUILD_DIR/examples/*/*.ino; do python -m platformio ci $EXAMPLE -l '.' -b $BOARD if [ $? -ne 0 ]; then exit 1; fi done From 2b1c5c4d78e743e3f38eed22fa1b87f3e33cb7ec Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Sat, 21 Sep 2019 15:44:55 +0300 Subject: [PATCH 006/551] Create stale.yml --- .github/stale.yml | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 .github/stale.yml diff --git a/.github/stale.yml b/.github/stale.yml new file mode 100644 index 000000000..ce7a8e3f7 --- /dev/null +++ b/.github/stale.yml @@ -0,0 +1,31 @@ +# Configuration for probot-stale - https://github.com/probot/stale + +daysUntilStale: 60 +daysUntilClose: 14 +limitPerRun: 30 +staleLabel: stale +exemptLabels: + - pinned + - security + - "to be implemented" + - "for reference" + - "move to PR" + - "enhancement" + +only: issues +onlyLabels: [] +exemptProjects: false +exemptMilestones: false +exemptAssignees: false + +markComment: > + [STALE_SET] This issue has been automatically marked as stale because it has not had + recent activity. It will be closed in 14 days if no further activity occurs. Thank you + for your contributions. + +unmarkComment: > + [STALE_CLR] This issue has been removed from the stale queue. Please ensure activity to keep it openin the future. + +closeComment: > + [STALE_DEL] This stale issue has been automatically closed. Thank you for your contributions. + From 7c6118f2a0110fc78d6c8510b31ca097333f196e Mon Sep 17 00:00:00 2001 From: ray Date: Sun, 22 Sep 2019 13:58:15 +0800 Subject: [PATCH 007/551] arg should be closed by va_end() (#601) --- src/AsyncWebSocket.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/AsyncWebSocket.cpp b/src/AsyncWebSocket.cpp index dc99d3933..fd1c7b845 100644 --- a/src/AsyncWebSocket.cpp +++ b/src/AsyncWebSocket.cpp @@ -711,6 +711,7 @@ size_t AsyncWebSocketClient::printf(const char *format, ...) { va_start(arg, format); char* temp = new char[MAX_PRINTF_LEN]; if(!temp){ + va_end(arg); return 0; } char* buffer = temp; @@ -741,6 +742,7 @@ size_t AsyncWebSocketClient::printf_P(PGM_P formatP, ...) { va_start(arg, formatP); char* temp = new char[MAX_PRINTF_LEN]; if(!temp){ + va_end(arg); return 0; } char* buffer = temp; From a627e66d532aa845797d590f6e3db4894c24b994 Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Tue, 24 Sep 2019 16:08:59 +0300 Subject: [PATCH 008/551] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index cbcf648cc..415c017c5 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# ESPAsyncWebServer [![Build Status](https://travis-ci.org/me-no-dev/ESPAsyncWebServer.svg?branch=master)](https://travis-ci.org/me-no-dev/ESPAsyncWebServer) +# ESPAsyncWebServer [![Build Status](https://travis-ci.org/me-no-dev/ESPAsyncWebServer.svg?branch=master)](https://travis-ci.org/me-no-dev/ESPAsyncWebServer) [![Codacy Badge](https://api.codacy.com/project/badge/Grade/395dd42cfc674e6ca2e326af3af80ffc)](https://www.codacy.com/manual/me-no-dev/ESPAsyncWebServer?utm_source=github.com&utm_medium=referral&utm_content=me-no-dev/ESPAsyncWebServer&utm_campaign=Badge_Grade) For help and support [![Join the chat at https://gitter.im/me-no-dev/ESPAsyncWebServer](https://badges.gitter.im/me-no-dev/ESPAsyncWebServer.svg)](https://gitter.im/me-no-dev/ESPAsyncWebServer?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) From 69aaf767eb54f2a173fe1738fb6bc9f34d486564 Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Tue, 24 Sep 2019 20:13:55 +0300 Subject: [PATCH 009/551] Update README.md --- README.md | 58 ++++++++++++++++++++++++------------------------------- 1 file changed, 25 insertions(+), 33 deletions(-) diff --git a/README.md b/README.md index 415c017c5..0c1609d0d 100644 --- a/README.md +++ b/README.md @@ -1371,48 +1371,40 @@ void loop(){ ### Setup global and class functions as request handlers -```arduino +```cpp #include #include #include #include -void handleRequest(AsyncWebServerRequest *request) -{ -} +void handleRequest(AsyncWebServerRequest *request){} -class WebClass -{ +class WebClass { public : - WebClass(){ - }; + AsyncWebServer classWebServer = AsyncWebServer(81); - AsyncWebServer classWebServer = AsyncWebServer(80); + WebClass(){}; - void classRequest (AsyncWebServerRequest *request) - { - } + void classRequest (AsyncWebServerRequest *request){} - void begin(){ + void begin(){ + // attach global request handler + classWebServer.on("/example", HTTP_ANY, handleRequest); - // attach global request handler - classWebServer.on("/example", HTTP_ANY, handleRequest); - - // attach class request handler - classWebServer.on("/example", HTTP_ANY, std::bind(&WebClass::classRequest, this, std::placeholders::_1)); - } + // attach class request handler + classWebServer.on("/example", HTTP_ANY, std::bind(&WebClass::classRequest, this, std::placeholders::_1)); + } }; AsyncWebServer globalWebServer(80); WebClass webClassInstance; void setup() { + // attach global request handler + globalWebServer.on("/example", HTTP_ANY, handleRequest); - // attach global request handler - globalWebServer.on("/example", HTTP_ANY, handleRequest); - - // attach class request handler - globalWebServer.on("/example", HTTP_ANY, std::bind(&WebClass::classRequest, webClassInstance, std::placeholders::_1)); + // attach class request handler + globalWebServer.on("/example", HTTP_ANY, std::bind(&WebClass::classRequest, webClassInstance, std::placeholders::_1)); } void loop() { @@ -1422,7 +1414,7 @@ void loop() { ### Methods for controlling websocket connections -```arduino +```cpp // Disable client connections if it was activated if ( ws.enabled() ) ws.enable(false); @@ -1434,7 +1426,7 @@ void loop() { Example of OTA code -```arduino +```cpp // OTA callbacks ArduinoOTA.onStart([]() { // Clean SPIFFS @@ -1461,7 +1453,7 @@ The DefaultHeaders singleton allows you to do this. Example: -```arduino +```cpp DefaultHeaders::Instance().addHeader("Access-Control-Allow-Origin", "*"); webServer.begin(); ``` @@ -1470,12 +1462,12 @@ webServer.begin(); This is one option: -```arduino +```cpp webServer.onNotFound([](AsyncWebServerRequest *request) { - if (request->method() == HTTP_OPTIONS) { - request->send(200); - } else { - request->send(404); - } + if (request->method() == HTTP_OPTIONS) { + request->send(200); + } else { + request->send(404); + } }); ``` From 59066bd1e4b51bc3a161e94adce10a89cde0a616 Mon Sep 17 00:00:00 2001 From: Mike Dunston Date: Tue, 24 Sep 2019 11:24:18 -0700 Subject: [PATCH 010/551] PrettyAsyncJsonResponse for ArduinoJson 6.x (#539) * PrettyAsyncJsonResponse for ArduinoJson 6.x add support for PrettyAsyncJsonResponse in ArduinoJson 6.x * Update AsyncJson.h Maintain order of args to AsyncJsonResponse between ArduinoJson 5.x and 6.x compatibility for ease of migration --- src/AsyncJson.h | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/AsyncJson.h b/src/AsyncJson.h index 4a6d6ba69..6118afe47 100644 --- a/src/AsyncJson.h +++ b/src/AsyncJson.h @@ -101,7 +101,7 @@ class AsyncJsonResponse: public AsyncAbstractResponse { _root = _jsonBuffer.createObject(); } #else - AsyncJsonResponse(size_t maxJsonBufferSize = DYNAMIC_JSON_DOCUMENT_SIZE, bool isArray=false) : _jsonBuffer(maxJsonBufferSize), _isValid{false} { + AsyncJsonResponse(bool isArray=false, size_t maxJsonBufferSize = DYNAMIC_JSON_DOCUMENT_SIZE) : _jsonBuffer(maxJsonBufferSize), _isValid{false} { _code = 200; _contentType = JSON_MIMETYPE; if(isArray) @@ -140,18 +140,25 @@ class AsyncJsonResponse: public AsyncAbstractResponse { } }; -#ifdef ARDUINOJSON_5_COMPATIBILITY class PrettyAsyncJsonResponse: public AsyncJsonResponse { public: PrettyAsyncJsonResponse (bool isArray=false) : AsyncJsonResponse{isArray} {} size_t setLength () { +#ifdef ARDUINOJSON_5_COMPATIBILITY _contentLength = _root.measurePrettyLength (); +#else + _contentLength = measureJsonPretty(_root); +#endif if (_contentLength) {_isValid = true;} return _contentLength; } size_t _fillBuffer (uint8_t *data, size_t len) { ChunkPrint dest (data, _sentLength, len); +#ifdef ARDUINOJSON_5_COMPATIBILITY _root.prettyPrintTo (dest); +#else + serializeJsonPretty(_root, dest); +#endif return len; } }; From f5ee1935c57967620f202f1eb2d90fc75b5daa23 Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Tue, 24 Sep 2019 22:33:23 +0300 Subject: [PATCH 011/551] Update README.md --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 0c1609d0d..f227c5502 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,5 @@ -# ESPAsyncWebServer [![Build Status](https://travis-ci.org/me-no-dev/ESPAsyncWebServer.svg?branch=master)](https://travis-ci.org/me-no-dev/ESPAsyncWebServer) [![Codacy Badge](https://api.codacy.com/project/badge/Grade/395dd42cfc674e6ca2e326af3af80ffc)](https://www.codacy.com/manual/me-no-dev/ESPAsyncWebServer?utm_source=github.com&utm_medium=referral&utm_content=me-no-dev/ESPAsyncWebServer&utm_campaign=Badge_Grade) +# ESPAsyncWebServer +[![Build Status](https://travis-ci.org/me-no-dev/ESPAsyncWebServer.svg?branch=master)](https://travis-ci.org/me-no-dev/ESPAsyncWebServer) ![](https://github.com/me-no-dev/ESPAsyncWebServer/workflows/ESP%20Async%20Web%20Server%20CI/badge.svg) [![Codacy Badge](https://api.codacy.com/project/badge/Grade/395dd42cfc674e6ca2e326af3af80ffc)](https://www.codacy.com/manual/me-no-dev/ESPAsyncWebServer?utm_source=github.com&utm_medium=referral&utm_content=me-no-dev/ESPAsyncWebServer&utm_campaign=Badge_Grade) For help and support [![Join the chat at https://gitter.im/me-no-dev/ESPAsyncWebServer](https://badges.gitter.im/me-no-dev/ESPAsyncWebServer.svg)](https://gitter.im/me-no-dev/ESPAsyncWebServer?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) From 2f3703702987e31249d4c5c9d1f90cebf1ffa9e8 Mon Sep 17 00:00:00 2001 From: matt123p Date: Tue, 24 Sep 2019 20:42:40 +0100 Subject: [PATCH 012/551] Add function so that the total number of web-socket clients can be limited (#591) * Add function so that the total number of web-socket clients can be limited easily. This is to cope with a problem when a browser does not close the web-socket connection correctly. I have observed this on Chromium based browsers. The memory leak will eventually lead to the server crashing. Normally only one connection per client is required, so limiting the number of connections would not normally cause any problems. * Prevent an assertion failure when using WebSockets Frequently when using Web Sockets you will get the assert failure: assertion "new_rcv_ann_wnd <= 0xffff" failed: file "/Users/ficeto/Desktop/ESP32/ESP32/esp-idf-public/components/lwip/lwip/src/core/tcp.c", line 779, function: tcp_update_rcv_ann_wnd This will happen particulary when you close the browser window. This change prevents the issue from occuring. * Do not use thread locking with the ESP8266, but instead use an empty placeholder class that can be used to implement locking at a later date. * Do not use thread locking with the ESP8266, but instead use an empty placeholder class that can be used to implement locking at a later date. * Add function so that the total number of web-socket clients can be limited easily. This is to cope with a problem when a browser does not close the web-socket connection correctly. I have observed this on Chromium based browsers. The memory leak will eventually lead to the server crashing. Normally only one connection per client is required, so limiting the number of connections would not normally cause any problems. * Set the default number of ws clients dependent on processor. --- README.md | 11 +++++++++++ examples/ESP_AsyncFSBrowser/ESP_AsyncFSBrowser.ino | 1 + src/AsyncWebSocket.cpp | 7 +++++++ src/AsyncWebSocket.h | 7 +++++++ 4 files changed, 26 insertions(+) diff --git a/README.md b/README.md index f227c5502..c1bd7157c 100644 --- a/README.md +++ b/README.md @@ -79,6 +79,7 @@ To use this library you might need to have the latest git versions of [ESP32](ht - [Async WebSocket Event](#async-websocket-event) - [Methods for sending data to a socket client](#methods-for-sending-data-to-a-socket-client) - [Direct access to web socket message buffer](#direct-access-to-web-socket-message-buffer) + - [Limiting the number of web socket clients](#limiting-the-number-of-web-socket-clients) - [Async Event Source Plugin](#async-event-source-plugin) - [Setup Event Source on the server](#setup-event-source-on-the-server) - [Setup Event Source in the browser](#setup-event-source-in-the-browser) @@ -1126,6 +1127,16 @@ void sendDataWs(AsyncWebSocketClient * client) } ``` +### Limiting the number of web socket clients +Browsers sometimes do not correctly close the websocket connection, even when the close() function is called in javascript. This will eventually exhaust the web server's resources and will cause the server to crash. Periodically calling the cleanClients() function from the main loop() function limits the number of clients by closing the oldest client when the maximum number of clients has been exceeded. This can called be every cycle, however, if you wish to use less power, then calling as infrequently as once per second is sufficient. + +```cpp +void loop(){ + ws.cleanupClients(); +} +``` + + ## Async Event Source Plugin The server includes EventSource (Server-Sent Events) plugin which can be used to send short text events to the browser. Difference between EventSource and WebSockets is that EventSource is single direction, text-only protocol. diff --git a/examples/ESP_AsyncFSBrowser/ESP_AsyncFSBrowser.ino b/examples/ESP_AsyncFSBrowser/ESP_AsyncFSBrowser.ino index 73451c520..0323cc1f6 100644 --- a/examples/ESP_AsyncFSBrowser/ESP_AsyncFSBrowser.ino +++ b/examples/ESP_AsyncFSBrowser/ESP_AsyncFSBrowser.ino @@ -217,4 +217,5 @@ void setup(){ void loop(){ ArduinoOTA.handle(); + ws.cleanupClients(); } diff --git a/src/AsyncWebSocket.cpp b/src/AsyncWebSocket.cpp index fd1c7b845..d1b3eab9f 100644 --- a/src/AsyncWebSocket.cpp +++ b/src/AsyncWebSocket.cpp @@ -927,6 +927,13 @@ void AsyncWebSocket::closeAll(uint16_t code, const char * message){ } } +void AsyncWebSocket::cleanupClients(uint16_t maxClients) +{ + if (count() > maxClients){ + _clients.front()->close(); + } +} + void AsyncWebSocket::ping(uint32_t id, uint8_t *data, size_t len){ AsyncWebSocketClient * c = client(id); if(c) diff --git a/src/AsyncWebSocket.h b/src/AsyncWebSocket.h index 8e2954eb5..0234dd7c0 100644 --- a/src/AsyncWebSocket.h +++ b/src/AsyncWebSocket.h @@ -37,6 +37,12 @@ #include #endif +#ifdef ESP32 +#define DEFAULT_MAX_WS_CLIENTS 8 +#else +#define DEFAULT_MAX_WS_CLIENTS 4 +#endif + class AsyncWebSocket; class AsyncWebSocketResponse; class AsyncWebSocketClient; @@ -255,6 +261,7 @@ class AsyncWebSocket: public AsyncWebHandler { void close(uint32_t id, uint16_t code=0, const char * message=NULL); void closeAll(uint16_t code=0, const char * message=NULL); + void cleanupClients(uint16_t maxClients = DEFAULT_MAX_WS_CLIENTS); void ping(uint32_t id, uint8_t *data=NULL, size_t len=0); void pingAll(uint8_t *data=NULL, size_t len=0); // done From 3c6f5f914c3cdea92200a73934f002260b38f3f7 Mon Sep 17 00:00:00 2001 From: Me No Dev Date: Wed, 2 Oct 2019 10:32:15 +0300 Subject: [PATCH 013/551] Ci update (#610) --- .github/scripts/install-arduino-core-esp32.sh | 36 +++ .../scripts/install-arduino-core-esp8266.sh | 29 +++ .github/scripts/install-arduino-ide.sh | 213 ++++++++++++++++ .github/scripts/install-platformio-esp32.sh | 150 +++++++++++ .github/scripts/on-push.sh | 70 ++++++ .github/workflows/main.yml | 54 ---- .github/workflows/push.yml | 34 +++ .travis.yml | 8 +- .../ESP_AsyncFSBrowser/ESP_AsyncFSBrowser.ino | 2 +- travis/build-pio.sh | 31 --- travis/build.sh | 237 ------------------ 11 files changed, 537 insertions(+), 327 deletions(-) create mode 100755 .github/scripts/install-arduino-core-esp32.sh create mode 100644 .github/scripts/install-arduino-core-esp8266.sh create mode 100755 .github/scripts/install-arduino-ide.sh create mode 100644 .github/scripts/install-platformio-esp32.sh create mode 100755 .github/scripts/on-push.sh delete mode 100644 .github/workflows/main.yml create mode 100644 .github/workflows/push.yml delete mode 100644 travis/build-pio.sh delete mode 100644 travis/build.sh diff --git a/.github/scripts/install-arduino-core-esp32.sh b/.github/scripts/install-arduino-core-esp32.sh new file mode 100755 index 000000000..cf1026d6a --- /dev/null +++ b/.github/scripts/install-arduino-core-esp32.sh @@ -0,0 +1,36 @@ +#!/bin/bash + +export ARDUINO_ESP32_PATH="$ARDUINO_USR_PATH/hardware/espressif/esp32" +if [ ! -d "$ARDUINO_ESP32_PATH" ]; then + echo "Installing ESP32 Arduino Core ..." + script_init_path="$PWD" + mkdir -p "$ARDUINO_USR_PATH/hardware/espressif" + cd "$ARDUINO_USR_PATH/hardware/espressif" + + echo "Installing Python Serial ..." + pip install pyserial > /dev/null + + if [ "$OS_IS_WINDOWS" == "1" ]; then + echo "Installing Python Requests ..." + pip install requests > /dev/null + fi + + if [ "$GITHUB_REPOSITORY" == "espressif/arduino-esp32" ]; then + echo "Linking Core..." + ln -s $GITHUB_WORKSPACE esp32 + else + echo "Cloning Core Repository..." + git clone https://github.com/espressif/arduino-esp32.git esp32 > /dev/null 2>&1 + fi + + echo "Updating Submodules ..." + cd esp32 + git submodule update --init --recursive > /dev/null 2>&1 + + echo "Installing Platform Tools ..." + cd tools && python get.py + cd $script_init_path + + echo "ESP32 Arduino has been installed in '$ARDUINO_ESP32_PATH'" + echo "" +fi diff --git a/.github/scripts/install-arduino-core-esp8266.sh b/.github/scripts/install-arduino-core-esp8266.sh new file mode 100644 index 000000000..048cd0246 --- /dev/null +++ b/.github/scripts/install-arduino-core-esp8266.sh @@ -0,0 +1,29 @@ +#!/bin/bash + +echo "Installing ESP8266 Arduino Core ..." +script_init_path="$PWD" +mkdir -p "$ARDUINO_USR_PATH/hardware/esp8266com" +cd "$ARDUINO_USR_PATH/hardware/esp8266com" + +echo "Installing Python Serial ..." +pip install pyserial > /dev/null + +if [ "$OS_IS_WINDOWS" == "1" ]; then + echo "Installing Python Requests ..." + pip install requests > /dev/null +fi + +echo "Cloning Core Repository ..." +git clone https://github.com/esp8266/Arduino.git esp8266 > /dev/null 2>&1 + +echo "Updating submodules ..." +cd esp8266 +git submodule update --init --recursive > /dev/null 2>&1 + +echo "Installing Platform Tools ..." +cd tools +python get.py > /dev/null +cd $script_init_path + +echo "ESP8266 Arduino has been installed in '$ARDUINO_USR_PATH/hardware/esp8266com'" +echo "" diff --git a/.github/scripts/install-arduino-ide.sh b/.github/scripts/install-arduino-ide.sh new file mode 100755 index 000000000..acf4695ac --- /dev/null +++ b/.github/scripts/install-arduino-ide.sh @@ -0,0 +1,213 @@ +#!/bin/bash + +#OSTYPE: 'linux-gnu', ARCH: 'x86_64' => linux64 +#OSTYPE: 'msys', ARCH: 'x86_64' => win32 +#OSTYPE: 'darwin18', ARCH: 'i386' => macos + +OSBITS=`arch` +if [[ "$OSTYPE" == "linux"* ]]; then + export OS_IS_LINUX="1" + ARCHIVE_FORMAT="tar.xz" + if [[ "$OSBITS" == "i686" ]]; then + OS_NAME="linux32" + elif [[ "$OSBITS" == "x86_64" ]]; then + OS_NAME="linux64" + elif [[ "$OSBITS" == "armv7l" || "$OSBITS" == "aarch64" ]]; then + OS_NAME="linuxarm" + else + OS_NAME="$OSTYPE-$OSBITS" + echo "Unknown OS '$OS_NAME'" + exit 1 + fi +elif [[ "$OSTYPE" == "darwin"* ]]; then + export OS_IS_MACOS="1" + ARCHIVE_FORMAT="zip" + OS_NAME="macosx" +elif [[ "$OSTYPE" == "cygwin" ]] || [[ "$OSTYPE" == "msys" ]] || [[ "$OSTYPE" == "win32" ]]; then + export OS_IS_WINDOWS="1" + ARCHIVE_FORMAT="zip" + OS_NAME="windows" +else + OS_NAME="$OSTYPE-$OSBITS" + echo "Unknown OS '$OS_NAME'" + exit 1 +fi +export OS_NAME + +ARDUINO_BUILD_DIR="$HOME/.arduino/build.tmp" +ARDUINO_CACHE_DIR="$HOME/.arduino/cache.tmp" + +if [ "$OS_IS_MACOS" == "1" ]; then + export ARDUINO_IDE_PATH="/Applications/Arduino.app/Contents/Java" + export ARDUINO_USR_PATH="$HOME/Documents/Arduino" +else + export ARDUINO_IDE_PATH="$HOME/arduino_ide" + export ARDUINO_USR_PATH="$HOME/Arduino" +fi + +if [ ! -d "$ARDUINO_IDE_PATH" ]; then + echo "Installing Arduino IDE on $OS_NAME ..." + echo "Downloading 'arduino-nightly-$OS_NAME.$ARCHIVE_FORMAT' to 'arduino.$ARCHIVE_FORMAT' ..." + if [ "$OS_IS_LINUX" == "1" ]; then + wget -O "arduino.$ARCHIVE_FORMAT" "https://www.arduino.cc/download.php?f=/arduino-nightly-$OS_NAME.$ARCHIVE_FORMAT" > /dev/null 2>&1 + echo "Extracting 'arduino.$ARCHIVE_FORMAT' ..." + tar xf "arduino.$ARCHIVE_FORMAT" > /dev/null + mv arduino-nightly "$ARDUINO_IDE_PATH" + else + curl -o "arduino.$ARCHIVE_FORMAT" -L "https://www.arduino.cc/download.php?f=/arduino-nightly-$OS_NAME.$ARCHIVE_FORMAT" > /dev/null 2>&1 + echo "Extracting 'arduino.$ARCHIVE_FORMAT' ..." + unzip "arduino.$ARCHIVE_FORMAT" > /dev/null + if [ "$OS_IS_MACOS" == "1" ]; then + mv "Arduino.app" "/Applications/Arduino.app" + else + mv arduino-nightly "$ARDUINO_IDE_PATH" + fi + fi + rm -rf "arduino.$ARCHIVE_FORMAT" + + mkdir -p "$ARDUINO_USR_PATH/libraries" + mkdir -p "$ARDUINO_USR_PATH/hardware" + + echo "Arduino IDE Installed in '$ARDUINO_IDE_PATH'" + echo "" +fi + +function build_sketch(){ # build_sketch [extra-options] + if [ "$#" -lt 2 ]; then + echo "ERROR: Illegal number of parameters" + echo "USAGE: build_sketch [extra-options]" + return 1 + fi + + local fqbn="$1" + local sketch="$2" + local xtra_opts="$3" + local win_opts="" + if [ "$OS_IS_WINDOWS" == "1" ]; then + local ctags_version=`ls "$ARDUINO_IDE_PATH/tools-builder/ctags/"` + local preprocessor_version=`ls "$ARDUINO_IDE_PATH/tools-builder/arduino-preprocessor/"` + win_opts="-prefs=runtime.tools.ctags.path=$ARDUINO_IDE_PATH/tools-builder/ctags/$ctags_version -prefs=runtime.tools.arduino-preprocessor.path=$ARDUINO_IDE_PATH/tools-builder/arduino-preprocessor/$preprocessor_version" + fi + + echo "" + echo "Compiling '"$(basename "$sketch")"' ..." + mkdir -p "$ARDUINO_BUILD_DIR" + mkdir -p "$ARDUINO_CACHE_DIR" + $ARDUINO_IDE_PATH/arduino-builder -compile -logger=human -core-api-version=10810 \ + -fqbn=$fqbn \ + -warnings="all" \ + -tools "$ARDUINO_IDE_PATH/tools-builder" \ + -tools "$ARDUINO_IDE_PATH/tools" \ + -built-in-libraries "$ARDUINO_IDE_PATH/libraries" \ + -hardware "$ARDUINO_IDE_PATH/hardware" \ + -hardware "$ARDUINO_USR_PATH/hardware" \ + -libraries "$ARDUINO_USR_PATH/libraries" \ + -build-cache "$ARDUINO_CACHE_DIR" \ + -build-path "$ARDUINO_BUILD_DIR" \ + $win_opts $xtra_opts "$sketch" +} + +function count_sketches() # count_sketches +{ + local examples="$1" + local sketches=$(find $examples -name *.ino) + local sketchnum=0 + rm -rf sketches.txt + for sketch in $sketches; do + local sketchdir=$(dirname $sketch) + local sketchdirname=$(basename $sketchdir) + local sketchname=$(basename $sketch) + if [[ "${sketchdirname}.ino" != "$sketchname" ]]; then + continue + fi; + if [[ -f "$sketchdir/.test.skip" ]]; then + continue + fi + echo $sketch >> sketches.txt + sketchnum=$(($sketchnum + 1)) + done + return $sketchnum +} + +function build_sketches() # build_sketches [extra-options] +{ + local fqbn=$1 + local examples=$2 + local chunk_idex=$3 + local chunks_num=$4 + local xtra_opts=$5 + + if [ "$#" -lt 2 ]; then + echo "ERROR: Illegal number of parameters" + echo "USAGE: build_sketches [ ] [extra-options]" + return 1 + fi + + if [ "$#" -lt 4 ]; then + chunk_idex="0" + chunks_num="1" + xtra_opts=$3 + fi + + if [ "$chunks_num" -le 0 ]; then + echo "ERROR: Chunks count must be positive number" + return 1 + fi + if [ "$chunk_idex" -ge "$chunks_num" ]; then + echo "ERROR: Chunk index must be less than chunks count" + return 1 + fi + + set +e + count_sketches "$examples" + local sketchcount=$? + set -e + local sketches=$(cat sketches.txt) + rm -rf sketches.txt + + local chunk_size=$(( $sketchcount / $chunks_num )) + local all_chunks=$(( $chunks_num * $chunk_size )) + if [ "$all_chunks" -lt "$sketchcount" ]; then + chunk_size=$(( $chunk_size + 1 )) + fi + + local start_index=$(( $chunk_idex * $chunk_size )) + if [ "$sketchcount" -le "$start_index" ]; then + echo "Skipping job" + return 0 + fi + + local end_index=$(( $(( $chunk_idex + 1 )) * $chunk_size )) + if [ "$end_index" -gt "$sketchcount" ]; then + end_index=$sketchcount + fi + + local start_num=$(( $start_index + 1 )) + echo "Found $sketchcount Sketches"; + echo "Chunk Count : $chunks_num" + echo "Chunk Size : $chunk_size" + echo "Start Sketch: $start_num" + echo "End Sketch : $end_index" + + local sketchnum=0 + for sketch in $sketches; do + local sketchdir=$(dirname $sketch) + local sketchdirname=$(basename $sketchdir) + local sketchname=$(basename $sketch) + if [ "${sketchdirname}.ino" != "$sketchname" ] \ + || [ -f "$sketchdir/.test.skip" ]; then + continue + fi + sketchnum=$(($sketchnum + 1)) + if [ "$sketchnum" -le "$start_index" ] \ + || [ "$sketchnum" -gt "$end_index" ]; then + continue + fi + build_sketch "$fqbn" "$sketch" "$xtra_opts" + local result=$? + if [ $result -ne 0 ]; then + return $result + fi + done + return 0 +} diff --git a/.github/scripts/install-platformio-esp32.sh b/.github/scripts/install-platformio-esp32.sh new file mode 100644 index 000000000..f7f59c729 --- /dev/null +++ b/.github/scripts/install-platformio-esp32.sh @@ -0,0 +1,150 @@ +#!/bin/bash + +export PLATFORMIO_ESP32_PATH="$HOME/.platformio/packages/framework-arduinoespressif32" + +echo "Installing Python Wheel ..." +pip install wheel > /dev/null 2>&1 + +echo "Installing PlatformIO ..." +pip install -U https://github.com/platformio/platformio/archive/develop.zip > /dev/null 2>&1 + +echo "Installing Platform ESP32 ..." +python -m platformio platform install https://github.com/platformio/platform-espressif32.git#feature/stage > /dev/null 2>&1 + +echo "Replacing the framework version ..." +if [[ "$OSTYPE" == "darwin"* ]]; then + sed 's/https:\/\/github\.com\/espressif\/arduino-esp32\.git/*/' "$HOME/.platformio/platforms/espressif32/platform.json" > "platform.json" + mv -f "platform.json" "$HOME/.platformio/platforms/espressif32/platform.json" +else + sed -i 's/https:\/\/github\.com\/espressif\/arduino-esp32\.git/*/' "$HOME/.platformio/platforms/espressif32/platform.json" +fi + +if [ "$GITHUB_REPOSITORY" == "espressif/arduino-esp32" ]; then + echo "Linking Core ..." + ln -s $GITHUB_WORKSPACE "$PLATFORMIO_ESP32_PATH" +else + echo "Cloning Core Repository ..." + git clone https://github.com/espressif/arduino-esp32.git "$PLATFORMIO_ESP32_PATH" > /dev/null 2>&1 +fi + +echo "PlatformIO for ESP32 has been installed" +echo "" + + +function build_pio_sketch(){ # build_pio_sketch + if [ "$#" -lt 2 ]; then + echo "ERROR: Illegal number of parameters" + echo "USAGE: build_pio_sketch " + return 1 + fi + + local board="$1" + local sketch="$2" + local sketch_dir=$(dirname "$sketch") + echo "" + echo "Compiling '"$(basename "$sketch")"' ..." + python -m platformio ci -l '.' --board "$board" "$sketch_dir" --project-option="board_build.partitions = huge_app.csv" +} + +function count_sketches() # count_sketches +{ + local examples="$1" + local sketches=$(find $examples -name *.ino) + local sketchnum=0 + rm -rf sketches.txt + for sketch in $sketches; do + local sketchdir=$(dirname $sketch) + local sketchdirname=$(basename $sketchdir) + local sketchname=$(basename $sketch) + if [[ "${sketchdirname}.ino" != "$sketchname" ]]; then + continue + fi; + if [[ -f "$sketchdir/.test.skip" ]]; then + continue + fi + echo $sketch >> sketches.txt + sketchnum=$(($sketchnum + 1)) + done + return $sketchnum +} + +function build_pio_sketches() # build_pio_sketches +{ + if [ "$#" -lt 2 ]; then + echo "ERROR: Illegal number of parameters" + echo "USAGE: build_pio_sketches [ ]" + return 1 + fi + + local board=$1 + local examples=$2 + local chunk_idex=$3 + local chunks_num=$4 + + if [ "$#" -lt 4 ]; then + chunk_idex="0" + chunks_num="1" + fi + + if [ "$chunks_num" -le 0 ]; then + echo "ERROR: Chunks count must be positive number" + return 1 + fi + if [ "$chunk_idex" -ge "$chunks_num" ]; then + echo "ERROR: Chunk index must be less than chunks count" + return 1 + fi + + set +e + count_sketches "$examples" + local sketchcount=$? + set -e + local sketches=$(cat sketches.txt) + rm -rf sketches.txt + + local chunk_size=$(( $sketchcount / $chunks_num )) + local all_chunks=$(( $chunks_num * $chunk_size )) + if [ "$all_chunks" -lt "$sketchcount" ]; then + chunk_size=$(( $chunk_size + 1 )) + fi + + local start_index=$(( $chunk_idex * $chunk_size )) + if [ "$sketchcount" -le "$start_index" ]; then + echo "Skipping job" + return 0 + fi + + local end_index=$(( $(( $chunk_idex + 1 )) * $chunk_size )) + if [ "$end_index" -gt "$sketchcount" ]; then + end_index=$sketchcount + fi + + local start_num=$(( $start_index + 1 )) + echo "Found $sketchcount Sketches"; + echo "Chunk Count : $chunks_num" + echo "Chunk Size : $chunk_size" + echo "Start Sketch: $start_num" + echo "End Sketch : $end_index" + + local sketchnum=0 + for sketch in $sketches; do + local sketchdir=$(dirname $sketch) + local sketchdirname=$(basename $sketchdir) + local sketchname=$(basename $sketch) + if [ "${sketchdirname}.ino" != "$sketchname" ] \ + || [ -f "$sketchdir/.test.skip" ]; then + continue + fi + sketchnum=$(($sketchnum + 1)) + if [ "$sketchnum" -le "$start_index" ] \ + || [ "$sketchnum" -gt "$end_index" ]; then + continue + fi + build_pio_sketch "$board" "$sketch" + local result=$? + if [ $result -ne 0 ]; then + return $result + fi + done + return 0 +} diff --git a/.github/scripts/on-push.sh b/.github/scripts/on-push.sh new file mode 100755 index 000000000..76bd20f67 --- /dev/null +++ b/.github/scripts/on-push.sh @@ -0,0 +1,70 @@ +#!/bin/bash + +set -e + +if [ ! -z "$TRAVIS_BUILD_DIR" ]; then + export GITHUB_WORKSPACE="$TRAVIS_BUILD_DIR" + export GITHUB_REPOSITORY="$TRAVIS_REPO_SLUG" +elif [ -z "$GITHUB_WORKSPACE" ]; then + export GITHUB_WORKSPACE="$PWD" + export GITHUB_REPOSITORY="me-no-dev/ESPAsyncWebServer" +fi + +TARGET_PLATFORM="$1" +CHUNK_INDEX=$2 +CHUNKS_CNT=$3 +BUILD_PIO=0 +if [ "$#" -lt 1 ]; then + TARGET_PLATFORM="esp32" +fi +if [ "$#" -lt 3 ] || [ "$CHUNKS_CNT" -le 0 ]; then + CHUNK_INDEX=0 + CHUNKS_CNT=1 +elif [ "$CHUNK_INDEX" -gt "$CHUNKS_CNT" ]; then + CHUNK_INDEX=$CHUNKS_CNT +elif [ "$CHUNK_INDEX" -eq "$CHUNKS_CNT" ]; then + BUILD_PIO=1 +fi + +if [ "$BUILD_PIO" -eq 0 ]; then + # ArduinoIDE Test + source ./.github/scripts/install-arduino-ide.sh + + echo "Installing ESPAsyncWebServer ..." + cp -rf "$GITHUB_WORKSPACE" "$ARDUINO_USR_PATH/libraries/ESPAsyncWebServer" + echo "Installing ArduinoJson ..." + git clone https://github.com/bblanchon/ArduinoJson "$ARDUINO_USR_PATH/libraries/ArduinoJson" > /dev/null 2>&1 + + if [[ "$TARGET_PLATFORM" == "esp32" ]]; then + echo "Installing AsyncTCP ..." + git clone https://github.com/me-no-dev/AsyncTCP "$ARDUINO_USR_PATH/libraries/AsyncTCP" > /dev/null 2>&1 + FQBN="espressif:esp32:esp32:PSRAM=enabled,PartitionScheme=huge_app" + source ./.github/scripts/install-arduino-core-esp32.sh + echo "BUILDING ESP32 EXAMPLES" + else + echo "Installing ESPAsyncTCP ..." + git clone https://github.com/me-no-dev/ESPAsyncTCP "$ARDUINO_USR_PATH/libraries/ESPAsyncTCP" > /dev/null 2>&1 + FQBN="esp8266com:esp8266:generic:eesz=4M1M,ip=lm2f" + source ./.github/scripts/install-arduino-core-esp8266.sh + echo "BUILDING ESP8266 EXAMPLES" + fi + build_sketches "$FQBN" "$GITHUB_WORKSPACE/examples" "$CHUNK_INDEX" "$CHUNKS_CNT" +else + # PlatformIO Test + source ./.github/scripts/install-platformio-esp32.sh + python -m platformio lib --storage-dir "$GITHUB_WORKSPACE" install + echo "Installing ArduinoJson ..." + python -m platformio lib -g install https://github.com/bblanchon/ArduinoJson.git > /dev/null 2>&1 + if [[ "$TARGET_PLATFORM" == "esp32" ]]; then + BOARD="esp32dev" + echo "Installing AsyncTCP ..." + python -m platformio lib -g install https://github.com/me-no-dev/AsyncTCP.git > /dev/null 2>&1 + echo "BUILDING ESP32 EXAMPLES" + else + BOARD="esp12e" + echo "Installing ESPAsyncTCP ..." + python -m platformio lib -g install https://github.com/me-no-dev/ESPAsyncTCP.git > /dev/null 2>&1 + echo "BUILDING ESP8266 EXAMPLES" + fi + build_pio_sketches "$BOARD" "$GITHUB_WORKSPACE/examples" +fi diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml deleted file mode 100644 index 04c813074..000000000 --- a/.github/workflows/main.yml +++ /dev/null @@ -1,54 +0,0 @@ -name: ESP Async Web Server CI - -on: - push: - branches: - - master - - release/* - pull_request: - -jobs: - - build-arduino-esp32: - name: Build Arduino ESP32 - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v1 - - name: Build Tests - env: - TRAVIS_BUILD_DIR: ${{ github.workspace }} - run: bash $TRAVIS_BUILD_DIR/travis/build.sh esp32 - - build-arduino-esp8266: - name: Build Arduino ESP8266 - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v1 - - name: Build Tests - env: - TRAVIS_BUILD_DIR: ${{ github.workspace }} - run: bash $TRAVIS_BUILD_DIR/travis/build.sh esp8266 - - build-pio-esp32: - name: Build PlatformIO ESP32 - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v1 - - name: Install Python Wheel - run: pip install wheel - - name: Build Tests - env: - TRAVIS_BUILD_DIR: ${{ github.workspace }} - run: bash $TRAVIS_BUILD_DIR/travis/build-pio.sh esp32dev - - build-pio-esp8266: - name: Build PlatformIO ESP8266 - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v1 - - name: Install Python Wheel - run: pip install wheel - - name: Build Tests - env: - TRAVIS_BUILD_DIR: ${{ github.workspace }} - run: bash $TRAVIS_BUILD_DIR/travis/build-pio.sh esp12e diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml new file mode 100644 index 000000000..abdea4627 --- /dev/null +++ b/.github/workflows/push.yml @@ -0,0 +1,34 @@ +name: ESP Async Web Server CI + +on: + push: + branches: + - master + - release/* + pull_request: + +jobs: + + build-arduino: + name: Arduino for ${{ matrix.board }} on ${{ matrix.os }} + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-latest, windows-latest, macOS-latest] + board: [esp32, esp8266] + steps: + - uses: actions/checkout@v1 + - name: Build Tests + run: bash ./.github/scripts/on-push.sh ${{ matrix.board }} 0 1 + + build-pio: + name: PlatformIO for ${{ matrix.board }} on ${{ matrix.os }} + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-latest, windows-latest, macOS-latest] + board: [esp32, esp8266] + steps: + - uses: actions/checkout@v1 + - name: Build Tests + run: bash ./.github/scripts/on-push.sh ${{ matrix.board }} 1 1 diff --git a/.travis.yml b/.travis.yml index fd1f74785..e1b703527 100644 --- a/.travis.yml +++ b/.travis.yml @@ -17,22 +17,22 @@ jobs: - name: "Build Arduino ESP32" if: tag IS blank AND (type = pull_request OR (type = push AND branch = master)) stage: build - script: bash $TRAVIS_BUILD_DIR/travis/build.sh esp32 + script: bash $TRAVIS_BUILD_DIR/.github/scripts/on-push.sh esp32 - name: "Build Arduino ESP8266" if: tag IS blank AND (type = pull_request OR (type = push AND branch = master)) stage: build - script: bash $TRAVIS_BUILD_DIR/travis/build.sh esp8266 + script: bash $TRAVIS_BUILD_DIR/.github/scripts/on-push.sh esp8266 - name: "Build Platformio ESP32" if: tag IS blank AND (type = pull_request OR (type = push AND branch = master)) stage: build - script: bash $TRAVIS_BUILD_DIR/travis/build-pio.sh esp32dev + script: bash $TRAVIS_BUILD_DIR/.github/scripts/on-push.sh esp32 1 1 - name: "Build Platformio ESP8266" if: tag IS blank AND (type = pull_request OR (type = push AND branch = master)) stage: build - script: bash $TRAVIS_BUILD_DIR/travis/build-pio.sh esp12e + script: bash $TRAVIS_BUILD_DIR/.github/scripts/on-push.sh esp8266 1 1 notifications: email: diff --git a/examples/ESP_AsyncFSBrowser/ESP_AsyncFSBrowser.ino b/examples/ESP_AsyncFSBrowser/ESP_AsyncFSBrowser.ino index 0323cc1f6..bf42d0038 100644 --- a/examples/ESP_AsyncFSBrowser/ESP_AsyncFSBrowser.ino +++ b/examples/ESP_AsyncFSBrowser/ESP_AsyncFSBrowser.ino @@ -24,7 +24,7 @@ void onWsEvent(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventT client->printf("Hello Client %u :)", client->id()); client->ping(); } else if(type == WS_EVT_DISCONNECT){ - Serial.printf("ws[%s][%u] disconnect: %u\n", server->url(), client->id()); + Serial.printf("ws[%s][%u] disconnect\n", server->url(), client->id()); } else if(type == WS_EVT_ERROR){ Serial.printf("ws[%s][%u] error(%u): %s\n", server->url(), client->id(), *((uint16_t*)arg), (char*)data); } else if(type == WS_EVT_PONG){ diff --git a/travis/build-pio.sh b/travis/build-pio.sh deleted file mode 100644 index fe6530bc9..000000000 --- a/travis/build-pio.sh +++ /dev/null @@ -1,31 +0,0 @@ -#!/bin/bash - -BOARD=$1 - -echo -e "travis_fold:start:install_pio" -pip install -U platformio -if [ $? -ne 0 ]; then exit 1; fi - -python -m platformio lib --storage-dir $TRAVIS_BUILD_DIR install -if [ $? -ne 0 ]; then exit 1; fi - -python -m platformio lib -g install https://github.com/bblanchon/ArduinoJson.git -if [ $? -ne 0 ]; then exit 1; fi - -case $BOARD in -esp32dev) - python -m platformio lib -g install https://github.com/me-no-dev/AsyncTCP.git - ;; -esp12e) - python -m platformio lib -g install https://github.com/me-no-dev/ESPAsyncTCP.git || true - ;; -esac -if [ $? -ne 0 ]; then exit 1; fi -echo -e "travis_fold:end:install_pio" - -echo -e "travis_fold:start:test_pio" -for EXAMPLE in $TRAVIS_BUILD_DIR/examples/*/*.ino; do - python -m platformio ci $EXAMPLE -l '.' -b $BOARD - if [ $? -ne 0 ]; then exit 1; fi -done -echo -e "travis_fold:end:test_pio" diff --git a/travis/build.sh b/travis/build.sh deleted file mode 100644 index 0ed99f040..000000000 --- a/travis/build.sh +++ /dev/null @@ -1,237 +0,0 @@ -#!/bin/bash - -PLATFORM=$1 -CHUNK_INDEX=$2 -CHUNKS_CNT=$3 -if [ "$#" -lt 3 ]; then - echo "Building all sketches" - CHUNK_INDEX=0 - CHUNKS_CNT=1 -fi -if [ "$CHUNKS_CNT" -le 0 ]; then - echo "Chunks count must be positive number" - exit 1 -fi -if [ "$CHUNK_INDEX" -ge "$CHUNKS_CNT" ]; then - echo "Chunk index must be less than chunks count" - exit 1 -fi - -if [ $PLATFORM == "esp32" ]; then - echo "BUILDING ESP32 EXAMPLES" -elif [ $PLATFORM == "esp8266" ]; then - echo "BUILDING ESP8266 EXAMPLES" -else - echo "UNKNOWN PLATFORM $PLATFORM" - exit 1 -fi - -echo -e "travis_fold:start:prep_arduino_ide" -# Install Arduino IDE -wget -O arduino.tar.xz https://www.arduino.cc/download.php?f=/arduino-nightly-linux64.tar.xz -tar xf arduino.tar.xz -mv arduino-nightly $HOME/arduino_ide -mkdir -p $HOME/Arduino/libraries -mkdir -p $HOME/Arduino/hardware -echo -e "travis_fold:end:prep_arduino_ide" - -echo -e "travis_fold:start:sketch_test_env_prepare" -cd $HOME/Arduino/libraries -cp -rf $TRAVIS_BUILD_DIR ESPAsyncWebServer -git clone https://github.com/bblanchon/ArduinoJson -#wget https://github.com/bblanchon/ArduinoJson/releases/download/v6.11.0/ArduinoJson-v6.11.0.zip && unzip ArduinoJson-v6.11.0.zip -PLATFORM_EXAMPLES=$TRAVIS_BUILD_DIR/examples - -if [ $PLATFORM == "esp32" ]; then - # ESP32 - cd $HOME/Arduino/libraries - git clone https://github.com/me-no-dev/AsyncTCP - cd $HOME/Arduino/hardware - pip install pyserial - mkdir espressif - cd espressif - git clone https://github.com/espressif/arduino-esp32.git esp32 - cd esp32 - git submodule update --init --recursive - cd tools - python get.py - PLATFORM_FQBN="espressif:esp32:esp32:PSRAM=enabled,PartitionScheme=huge_app,CPUFreq=240,FlashMode=qio,FlashFreq=80,FlashSize=4M,UploadSpeed=921600,DebugLevel=none" - PLATFORM_SIZE_BIN=$HOME/Arduino/hardware/espressif/esp32/tools/xtensa-esp32-elf/bin/xtensa-esp32-elf-size -elif [ $PLATFORM == "esp8266" ]; then - # ESP8266 - cd $HOME/Arduino/libraries - git clone https://github.com/me-no-dev/ESPAsyncTCP - cd $HOME/Arduino/hardware - mkdir esp8266com - cd esp8266com - git clone https://github.com/esp8266/Arduino.git esp8266 - cd esp8266 - git submodule update --init --recursive - cd tools - python get.py - PLATFORM_FQBN="esp8266com:esp8266:generic:xtal=80,FlashFreq=40,FlashMode=qio,baud=921600,eesz=4M1M,ip=lm2f,ResetMethod=nodemcu" - PLATFORM_SIZE_BIN=$HOME/Arduino/hardware/esp8266com/esp8266/tools/xtensa-lx106-elf/bin/xtensa-lx106-elf-size -fi -echo -e "travis_fold:end:sketch_test_env_prepare" - -cd $TRAVIS_BUILD_DIR - -ARDUINO_IDE_PATH=$HOME/arduino_ide -ARDUINO_USR_PATH=$HOME/Arduino -ARDUINO_BUILD_DIR=$HOME/build.tmp -ARDUINO_CACHE_DIR=$HOME/cache.tmp -ARDUINO_BUILD_CMD="$ARDUINO_IDE_PATH/arduino-builder -compile -logger=human -core-api-version=10810 -hardware \"$ARDUINO_IDE_PATH/hardware\" -hardware \"$ARDUINO_USR_PATH/hardware\" -tools \"$ARDUINO_IDE_PATH/tools-builder\" -built-in-libraries \"$ARDUINO_IDE_PATH/libraries\" -libraries \"$ARDUINO_USR_PATH/libraries\" -fqbn=$PLATFORM_FQBN -warnings=\"all\" -build-cache \"$ARDUINO_CACHE_DIR\" -build-path \"$ARDUINO_BUILD_DIR\" -verbose" - -function print_size_info() -{ - elf_file=$1 - - if [ -z "$elf_file" ]; then - if [ $PLATFORM == "esp32" ]; then - printf "sketch iram0.text flash.text flash.rodata dram0.data dram0.bss dram flash\n" - elif [ $PLATFORM == "esp8266" ]; then - printf "sketch data rodata bss text irom0.text dram flash\n" - fi - return 0 - fi - - elf_name=$(basename $elf_file) - sketch_name="${elf_name%.*}" - declare -A segments - while read -a tokens; do - seg=${tokens[0]} - seg=${seg//./} - size=${tokens[1]} - addr=${tokens[2]} - if [ "$addr" -eq "$addr" -a "$addr" -ne "0" ] 2>/dev/null; then - segments[$seg]=$size - fi - done < <($PLATFORM_SIZE_BIN --format=sysv $elf_file) - - if [ $PLATFORM == "esp32" ]; then - total_ram=$((${segments[dram0data]} + ${segments[dram0bss]})) - total_flash=$((${segments[iram0text]} + ${segments[flashtext]} + ${segments[dram0data]} + ${segments[flashrodata]})) - printf "%-32s %-8d %-8d %-8d %-8d %-8d %-8d %-8d\n" $sketch_name ${segments[iram0text]} ${segments[flashtext]} ${segments[flashrodata]} ${segments[dram0data]} ${segments[dram0bss]} $total_ram $total_flash - elif [ $PLATFORM == "esp8266" ]; then - total_ram=$((${segments[data]} + ${segments[rodata]} + ${segments[bss]})) - total_flash=$((${segments[data]} + ${segments[rodata]} + ${segments[text]} + ${segments[irom0text]})) - printf "%-28s %-8d %-8d %-8d %-8d %-8d %-8d %-8d\n" $sketch_name ${segments[data]} ${segments[rodata]} ${segments[bss]} ${segments[text]} ${segments[irom0text]} $total_ram $total_flash - fi - return 0 -} - -function build_sketch() -{ - local sketch=$1 - echo -e "\n------------ Building $sketch ------------\n"; - rm -rf $ARDUINO_BUILD_DIR/* - time ($ARDUINO_BUILD_CMD $sketch >build.log) - local result=$? - if [ $result -ne 0 ]; then - echo "Build failed ($1)" - echo "Build log:" - cat build.log - return $result - fi - rm build.log - return 0 -} - -function count_sketches() -{ - local sketches=$(find $PLATFORM_EXAMPLES -name *.ino) - local sketchnum=0 - rm -rf sketches.txt - for sketch in $sketches; do - local sketchdir=$(dirname $sketch) - local sketchdirname=$(basename $sketchdir) - local sketchname=$(basename $sketch) - if [[ "${sketchdirname}.ino" != "$sketchname" ]]; then - continue - fi - echo $sketch >> sketches.txt - sketchnum=$(($sketchnum + 1)) - done - return $sketchnum -} - -function build_sketches() -{ - mkdir -p $ARDUINO_BUILD_DIR - mkdir -p $ARDUINO_CACHE_DIR - mkdir -p $ARDUINO_USR_PATH/libraries - mkdir -p $ARDUINO_USR_PATH/hardware - - local chunk_idex=$1 - local chunks_num=$2 - count_sketches - local sketchcount=$? - local sketches=$(cat sketches.txt) - - local chunk_size=$(( $sketchcount / $chunks_num )) - local all_chunks=$(( $chunks_num * $chunk_size )) - if [ "$all_chunks" -lt "$sketchcount" ]; then - chunk_size=$(( $chunk_size + 1 )) - fi - - local start_index=$(( $chunk_idex * $chunk_size )) - if [ "$sketchcount" -le "$start_index" ]; then - echo "Skipping job" - return 0 - fi - - local end_index=$(( $(( $chunk_idex + 1 )) * $chunk_size )) - if [ "$end_index" -gt "$sketchcount" ]; then - end_index=$sketchcount - fi - - local start_num=$(( $start_index + 1 )) - #echo -e "Sketches: \n$sketches\n" - echo "Found $sketchcount Sketches"; - echo "Chunk Count : $chunks_num" - echo "Chunk Size : $chunk_size" - echo "Start Sketch: $start_num" - echo "End Sketch : $end_index" - - local sketchnum=0 - print_size_info >size.log - for sketch in $sketches; do - local sketchdir=$(dirname $sketch) - local sketchdirname=$(basename $sketchdir) - local sketchname=$(basename $sketch) - if [[ "${sketchdirname}.ino" != "$sketchname" ]]; then - #echo "Skipping $sketch, beacause it is not the main sketch file"; - continue - fi; - if [[ -f "$sketchdir/.test.skip" ]]; then - #echo "Skipping $sketch marked"; - continue - fi - sketchnum=$(($sketchnum + 1)) - if [ "$sketchnum" -le "$start_index" ]; then - #echo "Skipping $sketch index low" - continue - fi - if [ "$sketchnum" -gt "$end_index" ]; then - #echo "Skipping $sketch index high" - continue - fi - build_sketch $sketch - local result=$? - if [ $result -ne 0 ]; then - return $result - fi - print_size_info $ARDUINO_BUILD_DIR/*.elf >>size.log - done - return 0 -} - -echo -e "travis_fold:start:test_arduino_ide" -# Build Examples -build_sketches $CHUNK_INDEX $CHUNKS_CNT -if [ $? -ne 0 ]; then exit 1; fi -echo -e "travis_fold:end:test_arduino_ide" - -echo -e "travis_fold:start:size_report" -cat size.log -echo -e "travis_fold:end:size_report" From a19c32bba3caea1940d3acf8c994f610bff2b128 Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Wed, 2 Oct 2019 10:47:32 +0300 Subject: [PATCH 014/551] Simpler pio install --- ...tformio-esp32.sh => install-platformio.sh} | 27 +++---------------- .github/scripts/on-push.sh | 3 ++- 2 files changed, 5 insertions(+), 25 deletions(-) rename .github/scripts/{install-platformio-esp32.sh => install-platformio.sh} (75%) diff --git a/.github/scripts/install-platformio-esp32.sh b/.github/scripts/install-platformio.sh similarity index 75% rename from .github/scripts/install-platformio-esp32.sh rename to .github/scripts/install-platformio.sh index f7f59c729..eb22a7421 100644 --- a/.github/scripts/install-platformio-esp32.sh +++ b/.github/scripts/install-platformio.sh @@ -1,33 +1,12 @@ #!/bin/bash -export PLATFORMIO_ESP32_PATH="$HOME/.platformio/packages/framework-arduinoespressif32" - echo "Installing Python Wheel ..." pip install wheel > /dev/null 2>&1 echo "Installing PlatformIO ..." -pip install -U https://github.com/platformio/platformio/archive/develop.zip > /dev/null 2>&1 - -echo "Installing Platform ESP32 ..." -python -m platformio platform install https://github.com/platformio/platform-espressif32.git#feature/stage > /dev/null 2>&1 - -echo "Replacing the framework version ..." -if [[ "$OSTYPE" == "darwin"* ]]; then - sed 's/https:\/\/github\.com\/espressif\/arduino-esp32\.git/*/' "$HOME/.platformio/platforms/espressif32/platform.json" > "platform.json" - mv -f "platform.json" "$HOME/.platformio/platforms/espressif32/platform.json" -else - sed -i 's/https:\/\/github\.com\/espressif\/arduino-esp32\.git/*/' "$HOME/.platformio/platforms/espressif32/platform.json" -fi - -if [ "$GITHUB_REPOSITORY" == "espressif/arduino-esp32" ]; then - echo "Linking Core ..." - ln -s $GITHUB_WORKSPACE "$PLATFORMIO_ESP32_PATH" -else - echo "Cloning Core Repository ..." - git clone https://github.com/espressif/arduino-esp32.git "$PLATFORMIO_ESP32_PATH" > /dev/null 2>&1 -fi - -echo "PlatformIO for ESP32 has been installed" +pip install -U platformio > /dev/null 2>&1 + +echo "PlatformIO has been installed" echo "" diff --git a/.github/scripts/on-push.sh b/.github/scripts/on-push.sh index 76bd20f67..96fff573e 100755 --- a/.github/scripts/on-push.sh +++ b/.github/scripts/on-push.sh @@ -51,7 +51,8 @@ if [ "$BUILD_PIO" -eq 0 ]; then build_sketches "$FQBN" "$GITHUB_WORKSPACE/examples" "$CHUNK_INDEX" "$CHUNKS_CNT" else # PlatformIO Test - source ./.github/scripts/install-platformio-esp32.sh + source ./.github/scripts/install-platformio.sh + python -m platformio lib --storage-dir "$GITHUB_WORKSPACE" install echo "Installing ArduinoJson ..." python -m platformio lib -g install https://github.com/bblanchon/ArduinoJson.git > /dev/null 2>&1 From 14798d0e6a268c3d0276fda3d19253a01e980ff7 Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Wed, 2 Oct 2019 11:41:16 +0300 Subject: [PATCH 015/551] build fixes --- .github/scripts/install-arduino-ide.sh | 6 +++++- .github/scripts/install-platformio.sh | 8 ++++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/.github/scripts/install-arduino-ide.sh b/.github/scripts/install-arduino-ide.sh index acf4695ac..7950a49f3 100755 --- a/.github/scripts/install-arduino-ide.sh +++ b/.github/scripts/install-arduino-ide.sh @@ -110,9 +110,13 @@ function build_sketch(){ # build_sketch [extra-options] function count_sketches() # count_sketches { local examples="$1" + rm -rf sketches.txt + if [ ! -d "$examples" ]; then + touch sketches.txt + return 0 + fi local sketches=$(find $examples -name *.ino) local sketchnum=0 - rm -rf sketches.txt for sketch in $sketches; do local sketchdir=$(dirname $sketch) local sketchdirname=$(basename $sketchdir) diff --git a/.github/scripts/install-platformio.sh b/.github/scripts/install-platformio.sh index eb22a7421..61c94fec8 100644 --- a/.github/scripts/install-platformio.sh +++ b/.github/scripts/install-platformio.sh @@ -27,10 +27,14 @@ function build_pio_sketch(){ # build_pio_sketch function count_sketches() # count_sketches { - local examples="$1" + local examples="$1" + rm -rf sketches.txt + if [ ! -d "$examples" ]; then + touch sketches.txt + return 0 + fi local sketches=$(find $examples -name *.ino) local sketchnum=0 - rm -rf sketches.txt for sketch in $sketches; do local sketchdir=$(dirname $sketch) local sketchdirname=$(basename $sketchdir) From 7949d83e917af001c8cb0a8b4eb74eda2e2beb29 Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Wed, 2 Oct 2019 12:09:21 +0300 Subject: [PATCH 016/551] bump version --- library.json | 2 +- library.properties | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/library.json b/library.json index 57d1e7dd4..4c9e1413e 100644 --- a/library.json +++ b/library.json @@ -12,7 +12,7 @@ "type": "git", "url": "https://github.com/me-no-dev/ESPAsyncWebServer.git" }, - "version": "1.2.2", + "version": "1.2.3", "license": "LGPL-3.0", "frameworks": "arduino", "platforms": ["espressif8266", "espressif32"], diff --git a/library.properties b/library.properties index 34b89fe86..401b04173 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=ESP Async WebServer -version=1.2.2 +version=1.2.3 author=Me-No-Dev maintainer=Me-No-Dev sentence=Async Web Server for ESP8266 and ESP31B From e88fc12de836626785bf9396a51752a319fe4cf1 Mon Sep 17 00:00:00 2001 From: CODeRUS Date: Wed, 2 Oct 2019 12:26:01 +0300 Subject: [PATCH 017/551] Make PrettyAsyncJsonResponse to use maxJsonBufferSize for ArduinoJson 6 (#607) --- src/AsyncJson.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/AsyncJson.h b/src/AsyncJson.h index 6118afe47..a6c461ba3 100644 --- a/src/AsyncJson.h +++ b/src/AsyncJson.h @@ -142,7 +142,11 @@ class AsyncJsonResponse: public AsyncAbstractResponse { class PrettyAsyncJsonResponse: public AsyncJsonResponse { public: - PrettyAsyncJsonResponse (bool isArray=false) : AsyncJsonResponse{isArray} {} +#ifdef ARDUINOJSON_5_COMPATIBILITY + PrettyAsyncJsonResponse (bool isArray=false) : AsyncJsonResponse{isArray} {} +#else + PrettyAsyncJsonResponse (bool isArray=false, size_t maxJsonBufferSize = DYNAMIC_JSON_DOCUMENT_SIZE) : AsyncJsonResponse{isArray, maxJsonBufferSize} {} +#endif size_t setLength () { #ifdef ARDUINOJSON_5_COMPATIBILITY _contentLength = _root.measurePrettyLength (); From 7b1a3d238b78768a746789c168d96f610c7d3b60 Mon Sep 17 00:00:00 2001 From: Marcus Klein Date: Wed, 2 Oct 2019 11:33:46 +0200 Subject: [PATCH 018/551] added dependency for PlatformIO ldf_mode off (#605) --- library.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/library.json b/library.json index 4c9e1413e..556592793 100644 --- a/library.json +++ b/library.json @@ -24,6 +24,10 @@ { "name": "AsyncTCP", "platforms": "espressif32" + }, + { + "name": "Hash", + "platforms": "espressif8266" } ] } From c7ece88eacaf59ae8d16a240053384eb5182788e Mon Sep 17 00:00:00 2001 From: Mike Dunston Date: Wed, 2 Oct 2019 03:27:29 -0700 Subject: [PATCH 019/551] Update AsyncJson.h (#604) remove extra #endif that should have been dropped as part of https://github.com/me-no-dev/ESPAsyncWebServer/commit/59066bd1e4b51bc3a161e94adce10a89cde0a616 --- src/AsyncJson.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/AsyncJson.h b/src/AsyncJson.h index a6c461ba3..27b4a26f6 100644 --- a/src/AsyncJson.h +++ b/src/AsyncJson.h @@ -166,7 +166,6 @@ class PrettyAsyncJsonResponse: public AsyncJsonResponse { return len; } }; -#endif typedef std::function ArJsonRequestHandlerFunction; From 8451c0d0e7bae42e1f8dabb6a922a898ebfa0a21 Mon Sep 17 00:00:00 2001 From: Robert Alfaro Date: Wed, 2 Oct 2019 04:06:04 -0700 Subject: [PATCH 020/551] Add CMakeLists.txt file for ESP-IDF (#603) --- CMakeLists.txt | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 000000000..64292eca4 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,17 @@ +set(COMPONENT_SRCDIRS + "src" +) + +set(COMPONENT_ADD_INCLUDEDIRS + "src" +) + +set(COMPONENT_REQUIRES + "arduino-esp32" + "AsyncTCP" +) + +register_component() + +target_compile_definitions(${COMPONENT_TARGET} PUBLIC -DESP32) +target_compile_options(${COMPONENT_TARGET} PRIVATE -fno-rtti) From 403752a942f797d735539606a904fefc312e91eb Mon Sep 17 00:00:00 2001 From: sascha lammers Date: Wed, 2 Oct 2019 04:16:43 -0700 Subject: [PATCH 021/551] Added method to access clients of AsyncWebSocket (#583) * Added method to access clients of AsyncWebSocket * https://github.com/me-no-dev/ESPAsyncWebServer/issues/571 * Conflict with crypto library --- src/AsyncWebSocket.cpp | 3 +++ src/AsyncWebSocket.h | 9 ++++++++- src/WebResponses.cpp | 1 + 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/AsyncWebSocket.cpp b/src/AsyncWebSocket.cpp index d1b3eab9f..e4592a399 100644 --- a/src/AsyncWebSocket.cpp +++ b/src/AsyncWebSocket.cpp @@ -1236,6 +1236,9 @@ void AsyncWebSocket::_cleanBuffers() } } +AsyncWebSocket::AsyncWebSocketClientLinkedList AsyncWebSocket::getClients() const { + return _clients; +} /* * Response to Web Socket request - sends the authorization and detaches the TCP Client from the web server diff --git a/src/AsyncWebSocket.h b/src/AsyncWebSocket.h index 0234dd7c0..40cc03ffd 100644 --- a/src/AsyncWebSocket.h +++ b/src/AsyncWebSocket.h @@ -35,6 +35,9 @@ #ifdef ESP8266 #include +#ifdef CRYPTO_HASH_h // include Hash.h from espressif framework if the first include was from the crypto library +#include <../src/Hash.h> +#endif #endif #ifdef ESP32 @@ -238,9 +241,11 @@ typedef std::function AsyncWebSocketClientLinkedList; private: String _url; - LinkedList _clients; + AsyncWebSocketClientLinkedList _clients; uint32_t _cNextId; AwsEventHandler _eventHandler; bool _enabled; @@ -325,6 +330,8 @@ class AsyncWebSocket: public AsyncWebHandler { AsyncWebSocketMessageBuffer * makeBuffer(uint8_t * data, size_t size); LinkedList _buffers; void _cleanBuffers(); + + AsyncWebSocketClientLinkedList getClients() const; }; //WebServer response to authenticate the socket and detach the tcp client from the web server request diff --git a/src/WebResponses.cpp b/src/WebResponses.cpp index cca6b5324..272ab7065 100644 --- a/src/WebResponses.cpp +++ b/src/WebResponses.cpp @@ -446,6 +446,7 @@ size_t AsyncAbstractResponse::_fillBufferAndProcessTemplates(uint8_t* data, size _cache.insert(_cache.begin(), &data[originalLen - (pTemplateStart + numBytesCopied - pTemplateEnd - 1)], &data[len]); //2. parameter value is longer than placeholder text, push the data after placeholder which not saved into cache further to the end memmove(pTemplateStart + numBytesCopied, pTemplateEnd + 1, &data[originalLen] - pTemplateStart - numBytesCopied); + len = originalLen; // fix issue with truncated data, not sure if it has any side effects } else if(pTemplateEnd + 1 != pTemplateStart + numBytesCopied) //2. Either parameter value is shorter than placeholder text OR there is enough free space in buffer to fit. // Move the entire data after the placeholder From 6a4e2f532912f229ed8cb4699cd5114ba0b946c3 Mon Sep 17 00:00:00 2001 From: Bob Date: Wed, 2 Oct 2019 13:37:55 +0200 Subject: [PATCH 022/551] Support route parameters with regex patterns (#560) * Fix compile warnings * first test * Add regex path * Add simple example * add support for esp8266 * Update AsyncJson.h --- examples/regex_patterns/regex_patterns.ino | 65 ++++++++++++++++++++++ src/ESPAsyncWebServer.h | 5 ++ src/WebHandlerImpl.h | 23 +++++++- src/WebRequest.cpp | 11 ++++ 4 files changed, 101 insertions(+), 3 deletions(-) create mode 100644 examples/regex_patterns/regex_patterns.ino diff --git a/examples/regex_patterns/regex_patterns.ino b/examples/regex_patterns/regex_patterns.ino new file mode 100644 index 000000000..ad66daecb --- /dev/null +++ b/examples/regex_patterns/regex_patterns.ino @@ -0,0 +1,65 @@ +// +// A simple server implementation with regex routes: +// * serve static messages +// * read GET and POST parameters +// * handle missing pages / 404s +// + +#include +#ifdef ESP32 +#include +#include +#elif defined(ESP8266) +#include +#include +#endif +#include + +AsyncWebServer server(80); + +const char* ssid = "YOUR_SSID"; +const char* password = "YOUR_PASSWORD"; + +const char* PARAM_MESSAGE = "message"; + +void notFound(AsyncWebServerRequest *request) { + request->send(404, "text/plain", "Not found"); +} + +void setup() { + + Serial.begin(115200); + WiFi.mode(WIFI_STA); + WiFi.begin(ssid, password); + if (WiFi.waitForConnectResult() != WL_CONNECTED) { + Serial.printf("WiFi Failed!\n"); + return; + } + + Serial.print("IP Address: "); + Serial.println(WiFi.localIP()); + + server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){ + request->send(200, "text/plain", "Hello, world"); + }); + + // Send a GET request to /sensor/ + server.on("^\\/sensor\\/([0-9]+)$", HTTP_GET, [] (AsyncWebServerRequest *request) { + String sensorNumber = request->pathArg(0); + request->send(200, "text/plain", "Hello, sensor: " + sensorNumber); + }); + + // Send a GET request to /sensor//action/ + server.on("^\\/sensor\\/([0-9]+)\\/action\//([a-zA-Z0-9]+)$", HTTP_GET, [] (AsyncWebServerRequest *request) { + String sensorNumber = request->pathArg(0); + String action = request->pathArg(1); + request->send(200, "text/plain", "Hello, sensor: " + sensorNumber + ", with action: " + action); + }); + + server.onNotFound(notFound); + + server.begin(); +} + +void loop() { +} diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index cfe1fa73d..4f0574a38 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -129,6 +129,7 @@ class AsyncWebServerRequest { using File = fs::File; using FS = fs::FS; friend class AsyncWebServer; + friend class AsyncCallbackWebHandler; private: AsyncClient* _client; AsyncWebServer* _server; @@ -158,6 +159,7 @@ class AsyncWebServerRequest { LinkedList _headers; LinkedList _params; + LinkedList _pathParams; uint8_t _multiParseState; uint8_t _boundaryPosition; @@ -179,6 +181,7 @@ class AsyncWebServerRequest { void _onData(void *buf, size_t len); void _addParam(AsyncWebParameter*); + void _addPathParam(const char *param); bool _parseReqHead(); bool _parseReqHeader(); @@ -268,6 +271,8 @@ class AsyncWebServerRequest { bool hasArg(const char* name) const; // check if argument exists bool hasArg(const __FlashStringHelper * data) const; // check if F(argument) exists + const String& pathArg(size_t i) const; + const String& header(const char* name) const;// get request header value by name const String& header(const __FlashStringHelper * data) const;// get request header value by F(name) const String& header(size_t i) const; // get request header value by number diff --git a/src/WebHandlerImpl.h b/src/WebHandlerImpl.h index 65b580f05..5ae7b493a 100644 --- a/src/WebHandlerImpl.h +++ b/src/WebHandlerImpl.h @@ -21,6 +21,8 @@ #ifndef ASYNCWEBSERVERHANDLERIMPL_H_ #define ASYNCWEBSERVERHANDLERIMPL_H_ +#include +#include #include "stddef.h" #include @@ -67,9 +69,13 @@ class AsyncCallbackWebHandler: public AsyncWebHandler { ArRequestHandlerFunction _onRequest; ArUploadHandlerFunction _onUpload; ArBodyHandlerFunction _onBody; + bool _isRegex; public: - AsyncCallbackWebHandler() : _uri(), _method(HTTP_ANY), _onRequest(NULL), _onUpload(NULL), _onBody(NULL){} - void setUri(const String& uri){ _uri = uri; } + AsyncCallbackWebHandler() : _uri(), _method(HTTP_ANY), _onRequest(NULL), _onUpload(NULL), _onBody(NULL), _isRegex(false){} + void setUri(const String& uri){ + _uri = uri; + _isRegex = uri.startsWith("^") && uri.endsWith("$"); + } void setMethod(WebRequestMethodComposite method){ _method = method; } void onRequest(ArRequestHandlerFunction fn){ _onRequest = fn; } void onUpload(ArUploadHandlerFunction fn){ _onUpload = fn; } @@ -83,7 +89,18 @@ class AsyncCallbackWebHandler: public AsyncWebHandler { if(!(_method & request->method())) return false; - if (_uri.length() && _uri.endsWith("*")) { + if (_isRegex) { + std::regex rgx(_uri.c_str()); + std::smatch matches; + std::string s(request->url().c_str()); + if(std::regex_search(s, matches, rgx)) { + for (size_t i = 1; i < matches.size(); ++i) { // start from 1 + request->_addPathParam(matches[i].str().c_str()); + } + } else { + return false; + } + } else if (_uri.length() && _uri.endsWith("*")) { String uriTemplate = String(_uri); uriTemplate = uriTemplate.substring(0, uriTemplate.length() - 1); if (!request->url().startsWith(uriTemplate)) diff --git a/src/WebRequest.cpp b/src/WebRequest.cpp index dbcb92766..45a0a3976 100644 --- a/src/WebRequest.cpp +++ b/src/WebRequest.cpp @@ -55,6 +55,7 @@ AsyncWebServerRequest::AsyncWebServerRequest(AsyncWebServer* s, AsyncClient* c) , _parsedLength(0) , _headers(LinkedList([](AsyncWebHeader *h){ delete h; })) , _params(LinkedList([](AsyncWebParameter *p){ delete p; })) + , _pathParams(LinkedList([](String *p){ delete p; })) , _multiParseState(0) , _boundaryPosition(0) , _itemStartIndex(0) @@ -80,6 +81,7 @@ AsyncWebServerRequest::~AsyncWebServerRequest(){ _headers.free(); _params.free(); + _pathParams.free(); _interestingHeaders.free(); @@ -230,6 +232,10 @@ void AsyncWebServerRequest::_addParam(AsyncWebParameter *p){ _params.add(p); } +void AsyncWebServerRequest::_addPathParam(const char *p){ + _pathParams.add(new String(p)); +} + void AsyncWebServerRequest::_addGetParams(const String& params){ size_t start = 0; while (start < params.length()){ @@ -912,6 +918,11 @@ const String& AsyncWebServerRequest::argName(size_t i) const { return getParam(i)->name(); } +const String& AsyncWebServerRequest::pathArg(size_t i) const { + auto param = _pathParams.nth(i); + return param ? **param : SharedEmptyString; +} + const String& AsyncWebServerRequest::header(const char* name) const { AsyncWebHeader* h = getHeader(String(name)); return h ? h->value() : SharedEmptyString; From d1747e530fdf89c5fbd9028ca88ec3ce582dbd63 Mon Sep 17 00:00:00 2001 From: Me No Dev Date: Wed, 2 Oct 2019 14:49:18 +0300 Subject: [PATCH 023/551] Set theme jekyll-theme-hacker --- _config.yml | 1 + 1 file changed, 1 insertion(+) create mode 100644 _config.yml diff --git a/_config.yml b/_config.yml new file mode 100644 index 000000000..fc24e7a62 --- /dev/null +++ b/_config.yml @@ -0,0 +1 @@ +theme: jekyll-theme-hacker \ No newline at end of file From b9c41705286c4b7635a05635092897ed461b8174 Mon Sep 17 00:00:00 2001 From: Me No Dev Date: Wed, 2 Oct 2019 14:55:37 +0300 Subject: [PATCH 024/551] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index c1bd7157c..c1992a939 100644 --- a/README.md +++ b/README.md @@ -102,6 +102,7 @@ To use this library you might need to have the latest git versions of [ESP32](ht - [Instruction for Espressif 8266](http://docs.platformio.org/en/latest/platforms/espressif8266.html#using-arduino-framework-with-staging-version) - [Instruction for Espressif 32](http://docs.platformio.org/en/latest/platforms/espressif32.html#using-arduino-framework-with-staging-version) 4. Add "ESP Async WebServer" to project using [Project Configuration File `platformio.ini`](http://docs.platformio.org/page/projectconf.html) and [lib_deps](http://docs.platformio.org/page/projectconf/section_env_library.html#lib-deps) option: + ```ini [env:myboard] platform = espressif... From e1be51fc8f71c7b3e69d19ae82ce2b581fef17d8 Mon Sep 17 00:00:00 2001 From: Me No Dev Date: Wed, 2 Oct 2019 14:57:20 +0300 Subject: [PATCH 025/551] Set theme jekyll-theme-cayman --- _config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_config.yml b/_config.yml index fc24e7a62..c4192631f 100644 --- a/_config.yml +++ b/_config.yml @@ -1 +1 @@ -theme: jekyll-theme-hacker \ No newline at end of file +theme: jekyll-theme-cayman \ No newline at end of file From 4a34b46cc029bbee584c138f78461aa2148f7de3 Mon Sep 17 00:00:00 2001 From: SharkSharp Date: Wed, 2 Oct 2019 08:16:35 -0400 Subject: [PATCH 026/551] make the query parameters available by passing the request to WS_EVT_CONNECT (#559) Signed-off-by: Arthur Frederico Neves --- src/AsyncWebSocket.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/AsyncWebSocket.cpp b/src/AsyncWebSocket.cpp index e4592a399..f8850218d 100644 --- a/src/AsyncWebSocket.cpp +++ b/src/AsyncWebSocket.cpp @@ -492,7 +492,7 @@ AsyncWebSocketClient::AsyncWebSocketClient(AsyncWebServerRequest *request, Async _client->onData([](void *r, AsyncClient* c, void *buf, size_t len){ ((AsyncWebSocketClient*)(r))->_onData(buf, len); }, this); _client->onPoll([](void *r, AsyncClient* c){ ((AsyncWebSocketClient*)(r))->_onPoll(); }, this); _server->_addClient(this); - _server->_handleEvent(this, WS_EVT_CONNECT, NULL, NULL, 0); + _server->_handleEvent(this, WS_EVT_CONNECT, request, NULL, 0); delete request; } From 01019542c2e1fd484332c831f8f11e8369fd4649 Mon Sep 17 00:00:00 2001 From: Phil Bowles Date: Wed, 2 Oct 2019 14:33:18 +0200 Subject: [PATCH 027/551] Add methods to determine Average Queue length (#509) * Add methods to determine Average Queue length --- src/AsyncEventSource.cpp | 21 +++++++++++++++++++-- src/AsyncEventSource.h | 2 ++ 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/src/AsyncEventSource.cpp b/src/AsyncEventSource.cpp index 0707d4a3a..c56076df3 100644 --- a/src/AsyncEventSource.cpp +++ b/src/AsyncEventSource.cpp @@ -288,9 +288,26 @@ void AsyncEventSource::close(){ } } -void AsyncEventSource::send(const char *message, const char *event, uint32_t id, uint32_t reconnect){ +// pmb fix +size_t AsyncEventSource::avgPacketsWaiting() const { if(_clients.isEmpty()) - return; + return 0; + + size_t aql=0; + uint32_t nConnectedClients=0; + + for(const auto &c: _clients){ + if(c->connected()) { + aql+=c->packetsWaiting(); + ++nConnectedClients; + } + } +// return aql / nConnectedClients; + return ((aql) + (nConnectedClients/2))/(nConnectedClients); // round up +} + +void AsyncEventSource::send(const char *message, const char *event, uint32_t id, uint32_t reconnect){ + String ev = generateEventMessage(message, event, id, reconnect); for(const auto &c: _clients){ diff --git a/src/AsyncEventSource.h b/src/AsyncEventSource.h index 1b4d604dc..7c212e9f5 100644 --- a/src/AsyncEventSource.h +++ b/src/AsyncEventSource.h @@ -69,6 +69,7 @@ class AsyncEventSourceClient { void send(const char *message, const char *event=NULL, uint32_t id=0, uint32_t reconnect=0); bool connected() const { return (_client != NULL) && _client->connected(); } uint32_t lastId() const { return _lastId; } + size_t packetsWaiting() const { return _messageQueue.length(); } //system callbacks (do not call) void _onAck(size_t len, uint32_t time); @@ -91,6 +92,7 @@ class AsyncEventSource: public AsyncWebHandler { void onConnect(ArEventHandlerFunction cb); void send(const char *message, const char *event=NULL, uint32_t id=0, uint32_t reconnect=0); size_t count() const; //number clinets connected + size_t avgPacketsWaiting() const; //system callbacks (do not call) void _addClient(AsyncEventSourceClient * client); From 83f6b96958f4269cc629da56a3daf50990463bde Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Wed, 2 Oct 2019 20:02:39 +0300 Subject: [PATCH 028/551] Update install-arduino-ide.sh --- .github/scripts/install-arduino-ide.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/scripts/install-arduino-ide.sh b/.github/scripts/install-arduino-ide.sh index 7950a49f3..7e268b1ff 100755 --- a/.github/scripts/install-arduino-ide.sh +++ b/.github/scripts/install-arduino-ide.sh @@ -40,6 +40,9 @@ ARDUINO_CACHE_DIR="$HOME/.arduino/cache.tmp" if [ "$OS_IS_MACOS" == "1" ]; then export ARDUINO_IDE_PATH="/Applications/Arduino.app/Contents/Java" export ARDUINO_USR_PATH="$HOME/Documents/Arduino" +elif [ "$OS_IS_WINDOWS" == "1" ]; then + export ARDUINO_IDE_PATH="$HOME/arduino_ide" + export ARDUINO_USR_PATH="$HOME/Documents/Arduino" else export ARDUINO_IDE_PATH="$HOME/arduino_ide" export ARDUINO_USR_PATH="$HOME/Arduino" From 6a1fb03fc4d06e424b19767e63e5aaf113a7de35 Mon Sep 17 00:00:00 2001 From: frippe75 Date: Sun, 6 Oct 2019 10:08:59 +0200 Subject: [PATCH 029/551] Fixes #614 with incorrect regex in the example sketch (#615) --- examples/regex_patterns/regex_patterns.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/regex_patterns/regex_patterns.ino b/examples/regex_patterns/regex_patterns.ino index ad66daecb..4ec9c8557 100644 --- a/examples/regex_patterns/regex_patterns.ino +++ b/examples/regex_patterns/regex_patterns.ino @@ -50,7 +50,7 @@ void setup() { }); // Send a GET request to /sensor//action/ - server.on("^\\/sensor\\/([0-9]+)\\/action\//([a-zA-Z0-9]+)$", HTTP_GET, [] (AsyncWebServerRequest *request) { + server.on("^\\/sensor\\/([0-9]+)\\/action\\/([a-zA-Z0-9]+)$", HTTP_GET, [] (AsyncWebServerRequest *request) { String sensorNumber = request->pathArg(0); String action = request->pathArg(1); request->send(200, "text/plain", "Hello, sensor: " + sensorNumber + ", with action: " + action); From 75acf88d5f387691c5c364eba4efc03b6f5c7486 Mon Sep 17 00:00:00 2001 From: Bob Date: Sun, 6 Oct 2019 10:11:51 +0200 Subject: [PATCH 030/551] Add support for Content-Type with charset (#561) --- src/WebRequest.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/WebRequest.cpp b/src/WebRequest.cpp index 45a0a3976..fa06be667 100644 --- a/src/WebRequest.cpp +++ b/src/WebRequest.cpp @@ -316,13 +316,11 @@ bool AsyncWebServerRequest::_parseReqHeader(){ if(name.equalsIgnoreCase("Host")){ _host = value; } else if(name.equalsIgnoreCase("Content-Type")){ + _contentType = value.substring(0, value.indexOf(';')); if (value.startsWith("multipart/")){ _boundary = value.substring(value.indexOf('=')+1); _boundary.replace("\"",""); - _contentType = value.substring(0, value.indexOf(';')); _isMultipart = true; - } else { - _contentType = value; } } else if(name.equalsIgnoreCase("Content-Length")){ _contentLength = atoi(value.c_str()); From f3ebe2dea987e8e511a62cb0273467748f264c74 Mon Sep 17 00:00:00 2001 From: Develo Date: Mon, 14 Oct 2019 05:30:06 -0300 Subject: [PATCH 031/551] Remove warnings for unused params (#620) --- src/AsyncEventSource.cpp | 5 +++-- src/AsyncWebSocket.cpp | 14 +++++++++----- src/AsyncWebSocket.h | 4 ++-- src/WebRequest.cpp | 13 +++++++------ src/WebResponses.cpp | 4 +++- 5 files changed, 24 insertions(+), 16 deletions(-) diff --git a/src/AsyncEventSource.cpp b/src/AsyncEventSource.cpp index c56076df3..ad188e8fb 100644 --- a/src/AsyncEventSource.cpp +++ b/src/AsyncEventSource.cpp @@ -124,6 +124,7 @@ AsyncEventSourceMessage::~AsyncEventSourceMessage() { } size_t AsyncEventSourceMessage::ack(size_t len, uint32_t time) { + (void)time; // If the whole message is now acked... if(_acked + len > _len){ // Return the number of extra bytes acked (they will be carried on to the next message) @@ -161,8 +162,8 @@ AsyncEventSourceClient::AsyncEventSourceClient(AsyncWebServerRequest *request, A _client->setRxTimeout(0); _client->onError(NULL, NULL); - _client->onAck([](void *r, AsyncClient* c, size_t len, uint32_t time){ ((AsyncEventSourceClient*)(r))->_onAck(len, time); }, this); - _client->onPoll([](void *r, AsyncClient* c){ ((AsyncEventSourceClient*)(r))->_onPoll(); }, this); + _client->onAck([](void *r, AsyncClient* c, size_t len, uint32_t time){ (void)c; ((AsyncEventSourceClient*)(r))->_onAck(len, time); }, this); + _client->onPoll([](void *r, AsyncClient* c){ (void)c; ((AsyncEventSourceClient*)(r))->_onPoll(); }, this); _client->onData(NULL, NULL); _client->onTimeout([this](void *r, AsyncClient* c __attribute__((unused)), uint32_t time){ ((AsyncEventSourceClient*)(r))->_onTimeout(time); }, this); _client->onDisconnect([this](void *r, AsyncClient* c){ ((AsyncEventSourceClient*)(r))->_onDisconnect(); delete c; }, this); diff --git a/src/AsyncWebSocket.cpp b/src/AsyncWebSocket.cpp index f8850218d..52dcd75f0 100644 --- a/src/AsyncWebSocket.cpp +++ b/src/AsyncWebSocket.cpp @@ -321,6 +321,7 @@ AsyncWebSocketBasicMessage::~AsyncWebSocketBasicMessage() { } void AsyncWebSocketBasicMessage::ack(size_t len, uint32_t time) { + (void)time; _acked += len; if(_sent == _len && _acked == _ack){ _status = WS_MSG_SENT; @@ -416,6 +417,7 @@ AsyncWebSocketMultiMessage::~AsyncWebSocketMultiMessage() { } void AsyncWebSocketMultiMessage::ack(size_t len, uint32_t time) { + (void)time; _acked += len; if(_sent >= _len && _acked >= _ack){ _status = WS_MSG_SENT; @@ -485,12 +487,12 @@ AsyncWebSocketClient::AsyncWebSocketClient(AsyncWebServerRequest *request, Async _lastMessageTime = millis(); _keepAlivePeriod = 0; _client->setRxTimeout(0); - _client->onError([](void *r, AsyncClient* c, int8_t error){ ((AsyncWebSocketClient*)(r))->_onError(error); }, this); - _client->onAck([](void *r, AsyncClient* c, size_t len, uint32_t time){ ((AsyncWebSocketClient*)(r))->_onAck(len, time); }, this); + _client->onError([](void *r, AsyncClient* c, int8_t error){ (void)c; ((AsyncWebSocketClient*)(r))->_onError(error); }, this); + _client->onAck([](void *r, AsyncClient* c, size_t len, uint32_t time){ (void)c; ((AsyncWebSocketClient*)(r))->_onAck(len, time); }, this); _client->onDisconnect([](void *r, AsyncClient* c){ ((AsyncWebSocketClient*)(r))->_onDisconnect(); delete c; }, this); - _client->onTimeout([](void *r, AsyncClient* c, uint32_t time){ ((AsyncWebSocketClient*)(r))->_onTimeout(time); }, this); - _client->onData([](void *r, AsyncClient* c, void *buf, size_t len){ ((AsyncWebSocketClient*)(r))->_onData(buf, len); }, this); - _client->onPoll([](void *r, AsyncClient* c){ ((AsyncWebSocketClient*)(r))->_onPoll(); }, this); + _client->onTimeout([](void *r, AsyncClient* c, uint32_t time){ (void)c; ((AsyncWebSocketClient*)(r))->_onTimeout(time); }, this); + _client->onData([](void *r, AsyncClient* c, void *buf, size_t len){ (void)c; ((AsyncWebSocketClient*)(r))->_onData(buf, len); }, this); + _client->onPoll([](void *r, AsyncClient* c){ (void)c; ((AsyncWebSocketClient*)(r))->_onPoll(); }, this); _server->_addClient(this); _server->_handleEvent(this, WS_EVT_CONNECT, request, NULL, 0); delete request; @@ -607,6 +609,7 @@ void AsyncWebSocketClient::ping(uint8_t *data, size_t len){ void AsyncWebSocketClient::_onError(int8_t){} void AsyncWebSocketClient::_onTimeout(uint32_t time){ + (void)time; _client->close(true); } @@ -1292,6 +1295,7 @@ void AsyncWebSocketResponse::_respond(AsyncWebServerRequest *request){ } size_t AsyncWebSocketResponse::_ack(AsyncWebServerRequest *request, size_t len, uint32_t time){ + (void)time; if(len){ new AsyncWebSocketClient(request, _server); } diff --git a/src/AsyncWebSocket.h b/src/AsyncWebSocket.h index 40cc03ffd..5b03aceb9 100644 --- a/src/AsyncWebSocket.h +++ b/src/AsyncWebSocket.h @@ -94,8 +94,8 @@ class AsyncWebSocketMessageBuffer { AsyncWebSocketMessageBuffer(const AsyncWebSocketMessageBuffer &); AsyncWebSocketMessageBuffer(AsyncWebSocketMessageBuffer &&); ~AsyncWebSocketMessageBuffer(); - void operator ++(int i) { _count++; } - void operator --(int i) { if (_count > 0) { _count--; } ; } + void operator ++(int i) { (void)i; _count++; } + void operator --(int i) { (void)i; if (_count > 0) { _count--; } ; } bool reserve(size_t size); void lock() { _lock = true; } void unlock() { _lock = false; } diff --git a/src/WebRequest.cpp b/src/WebRequest.cpp index fa06be667..bbce5ca4c 100644 --- a/src/WebRequest.cpp +++ b/src/WebRequest.cpp @@ -69,12 +69,12 @@ AsyncWebServerRequest::AsyncWebServerRequest(AsyncWebServer* s, AsyncClient* c) , _itemIsFile(false) , _tempObject(NULL) { - c->onError([](void *r, AsyncClient* c, int8_t error){ AsyncWebServerRequest *req = (AsyncWebServerRequest*)r; req->_onError(error); }, this); - c->onAck([](void *r, AsyncClient* c, size_t len, uint32_t time){ AsyncWebServerRequest *req = (AsyncWebServerRequest*)r; req->_onAck(len, time); }, this); + c->onError([](void *r, AsyncClient* c, int8_t error){ (void)c; AsyncWebServerRequest *req = (AsyncWebServerRequest*)r; req->_onError(error); }, this); + c->onAck([](void *r, AsyncClient* c, size_t len, uint32_t time){ (void)c; AsyncWebServerRequest *req = (AsyncWebServerRequest*)r; req->_onAck(len, time); }, this); c->onDisconnect([](void *r, AsyncClient* c){ AsyncWebServerRequest *req = (AsyncWebServerRequest*)r; req->_onDisconnect(); delete c; }, this); - c->onTimeout([](void *r, AsyncClient* c, uint32_t time){ AsyncWebServerRequest *req = (AsyncWebServerRequest*)r; req->_onTimeout(time); }, this); - c->onData([](void *r, AsyncClient* c, void *buf, size_t len){ AsyncWebServerRequest *req = (AsyncWebServerRequest*)r; req->_onData(buf, len); }, this); - c->onPoll([](void *r, AsyncClient* c){ AsyncWebServerRequest *req = (AsyncWebServerRequest*)r; req->_onPoll(); }, this); + c->onTimeout([](void *r, AsyncClient* c, uint32_t time){ (void)c; AsyncWebServerRequest *req = (AsyncWebServerRequest*)r; req->_onTimeout(time); }, this); + c->onData([](void *r, AsyncClient* c, void *buf, size_t len){ (void)c; AsyncWebServerRequest *req = (AsyncWebServerRequest*)r; req->_onData(buf, len); }, this); + c->onPoll([](void *r, AsyncClient* c){ (void)c; AsyncWebServerRequest *req = ( AsyncWebServerRequest*)r; req->_onPoll(); }, this); } AsyncWebServerRequest::~AsyncWebServerRequest(){ @@ -208,10 +208,11 @@ void AsyncWebServerRequest::_onAck(size_t len, uint32_t time){ } void AsyncWebServerRequest::_onError(int8_t error){ - + (void)error; } void AsyncWebServerRequest::_onTimeout(uint32_t time){ + (void)time; //os_printf("TIMEOUT: %u, state: %s\n", time, _client->stateToString()); _client->close(); } diff --git a/src/WebResponses.cpp b/src/WebResponses.cpp index 272ab7065..a22e991aa 100644 --- a/src/WebResponses.cpp +++ b/src/WebResponses.cpp @@ -161,7 +161,7 @@ bool AsyncWebServerResponse::_finished() const { return _state > RESPONSE_WAIT_A bool AsyncWebServerResponse::_failed() const { return _state == RESPONSE_FAILED; } bool AsyncWebServerResponse::_sourceValid() const { return false; } void AsyncWebServerResponse::_respond(AsyncWebServerRequest *request){ _state = RESPONSE_END; request->client()->close(); } -size_t AsyncWebServerResponse::_ack(AsyncWebServerRequest *request, size_t len, uint32_t time){ return 0; } +size_t AsyncWebServerResponse::_ack(AsyncWebServerRequest *request, size_t len, uint32_t time){ (void)request; (void)len; (void)time; return 0; } /* * String/Code Response @@ -213,6 +213,7 @@ void AsyncBasicResponse::_respond(AsyncWebServerRequest *request){ } size_t AsyncBasicResponse::_ack(AsyncWebServerRequest *request, size_t len, uint32_t time){ + (void)time; _ackedLength += len; if(_state == RESPONSE_CONTENT){ size_t available = _contentLength - _sentLength; @@ -261,6 +262,7 @@ void AsyncAbstractResponse::_respond(AsyncWebServerRequest *request){ } size_t AsyncAbstractResponse::_ack(AsyncWebServerRequest *request, size_t len, uint32_t time){ + (void)time; if(!_sourceValid()){ _state = RESPONSE_FAILED; request->client()->close(); From a84f16989aa472658df2ed13b0399c0cdf3d7ece Mon Sep 17 00:00:00 2001 From: Bob Date: Mon, 14 Oct 2019 22:06:38 +0200 Subject: [PATCH 032/551] Make regex a define exclusive (#617) * Change compiler error to runtime error. Add compiler warining when a ASYNCWEBSERVER_REGEX function is used, but not enabled * Update docs for usage in Arduino IDE * Update docs for platform.local.txt --- .github/scripts/install-arduino-ide.sh | 16 +++++++--- .github/scripts/install-platformio.sh | 17 +++++++---- README.md | 35 ++++++++++++++++++++++ examples/regex_patterns/.test.build_flags | 1 + examples/regex_patterns/regex_patterns.ino | 12 ++++++++ src/ESPAsyncWebServer.h | 8 ++++- src/WebHandlerImpl.h | 15 ++++++---- 7 files changed, 89 insertions(+), 15 deletions(-) create mode 100644 examples/regex_patterns/.test.build_flags diff --git a/.github/scripts/install-arduino-ide.sh b/.github/scripts/install-arduino-ide.sh index 7e268b1ff..ce60cb82f 100755 --- a/.github/scripts/install-arduino-ide.sh +++ b/.github/scripts/install-arduino-ide.sh @@ -75,16 +75,17 @@ if [ ! -d "$ARDUINO_IDE_PATH" ]; then echo "" fi -function build_sketch(){ # build_sketch [extra-options] +function build_sketch(){ # build_sketch [extra-options] if [ "$#" -lt 2 ]; then echo "ERROR: Illegal number of parameters" - echo "USAGE: build_sketch [extra-options]" + echo "USAGE: build_sketch [extra-options]" return 1 fi local fqbn="$1" local sketch="$2" - local xtra_opts="$3" + local build_flags="$3" + local xtra_opts="$4" local win_opts="" if [ "$OS_IS_WINDOWS" == "1" ]; then local ctags_version=`ls "$ARDUINO_IDE_PATH/tools-builder/ctags/"` @@ -107,6 +108,7 @@ function build_sketch(){ # build_sketch [extra-options] -libraries "$ARDUINO_USR_PATH/libraries" \ -build-cache "$ARDUINO_CACHE_DIR" \ -build-path "$ARDUINO_BUILD_DIR" \ + -prefs=compiler.cpp.extra_flags="$build_flags" \ $win_opts $xtra_opts "$sketch" } @@ -210,7 +212,13 @@ function build_sketches() # build_sketches - if [ "$#" -lt 2 ]; then +function build_pio_sketch(){ # build_pio_sketch + if [ "$#" -lt 3 ]; then echo "ERROR: Illegal number of parameters" - echo "USAGE: build_pio_sketch " + echo "USAGE: build_pio_sketch " return 1 fi local board="$1" local sketch="$2" + local buildFlags="$3" local sketch_dir=$(dirname "$sketch") echo "" echo "Compiling '"$(basename "$sketch")"' ..." - python -m platformio ci -l '.' --board "$board" "$sketch_dir" --project-option="board_build.partitions = huge_app.csv" + python -m platformio ci -l '.' --board "$board" "$sketch_dir" --project-option="board_build.partitions = huge_app.csv" --project-option="build_flags=$buildFlags" } function count_sketches() # count_sketches @@ -118,12 +119,18 @@ function build_pio_sketches() # build_pio_sketches pathArg(0); + }); +``` +*NOTE*: All regex patterns starts with `^` and ends with `$` + +To enable the `Path variable` support, you have to define the buildflag `-DASYNCWEBSERVER_REGEX`. + + +For Arduino IDE create/update `platform.local.txt`: + +`Windows`: C:\Users\(username)\AppData\Local\Arduino15\packages\\`{espxxxx}`\hardware\\`espxxxx`\\`{version}`\platform.local.txt + +`Linux`: ~/.arduino15/packages/`{espxxxx}`/hardware/`{espxxxx}`/`{version}`/platform.local.txt + +Add/Update the following line: +``` + compiler.cpp.extra_flags=-DDASYNCWEBSERVER_REGEX +``` + +For platformio modify `platformio.ini`: +```ini +[env:myboard] +build_flags = + -DASYNCWEBSERVER_REGEX +``` +*NOTE*: By enabling `ASYNCWEBSERVER_REGEX`, `` will be included. This will add an 100k to your binary. diff --git a/examples/regex_patterns/.test.build_flags b/examples/regex_patterns/.test.build_flags new file mode 100644 index 000000000..9ea3bb74a --- /dev/null +++ b/examples/regex_patterns/.test.build_flags @@ -0,0 +1 @@ +-DASYNCWEBSERVER_REGEX=1 diff --git a/examples/regex_patterns/regex_patterns.ino b/examples/regex_patterns/regex_patterns.ino index 4ec9c8557..fb013063e 100644 --- a/examples/regex_patterns/regex_patterns.ino +++ b/examples/regex_patterns/regex_patterns.ino @@ -5,6 +5,18 @@ // * handle missing pages / 404s // +// Add buildflag ASYNCWEBSERVER_REGEX to enable the regex support + +// For platformio: platformio.ini: +// build_flags = +// -DASYNCWEBSERVER_REGEX + +// For arduino IDE: create/update platform.local.txt +// Windows: C:\Users\(username)\AppData\Local\Arduino15\packages\espxxxx\hardware\espxxxx\{version}\platform.local.txt +// Linux: ~/.arduino15/packages/espxxxx/hardware/espxxxx/{version}/platform.local.txt +// +// compiler.cpp.extra_flags=-DASYNCWEBSERVER_REGEX=1 + #include #ifdef ESP32 #include diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index 4f0574a38..7cd21aa86 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -38,6 +38,12 @@ #error Platform not supported #endif +#ifdef ASYNCWEBSERVER_REGEX +#define ASYNCWEBSERVER_REGEX_ATTRIBUTE +#else +#define ASYNCWEBSERVER_REGEX_ATTRIBUTE __attribute__((warning("ASYNCWEBSERVER_REGEX not defined"))) +#endif + #define DEBUGF(...) //Serial.printf(__VA_ARGS__) class AsyncWebServer; @@ -271,7 +277,7 @@ class AsyncWebServerRequest { bool hasArg(const char* name) const; // check if argument exists bool hasArg(const __FlashStringHelper * data) const; // check if F(argument) exists - const String& pathArg(size_t i) const; + const String& ASYNCWEBSERVER_REGEX_ATTRIBUTE pathArg(size_t i) const; const String& header(const char* name) const;// get request header value by name const String& header(const __FlashStringHelper * data) const;// get request header value by F(name) diff --git a/src/WebHandlerImpl.h b/src/WebHandlerImpl.h index 5ae7b493a..d121fa7a3 100644 --- a/src/WebHandlerImpl.h +++ b/src/WebHandlerImpl.h @@ -22,7 +22,9 @@ #define ASYNCWEBSERVERHANDLERIMPL_H_ #include +#ifdef ASYNCWEBSERVER_REGEX #include +#endif #include "stddef.h" #include @@ -71,10 +73,10 @@ class AsyncCallbackWebHandler: public AsyncWebHandler { ArBodyHandlerFunction _onBody; bool _isRegex; public: - AsyncCallbackWebHandler() : _uri(), _method(HTTP_ANY), _onRequest(NULL), _onUpload(NULL), _onBody(NULL), _isRegex(false){} + AsyncCallbackWebHandler() : _uri(), _method(HTTP_ANY), _onRequest(NULL), _onUpload(NULL), _onBody(NULL), _isRegex(false) {} void setUri(const String& uri){ _uri = uri; - _isRegex = uri.startsWith("^") && uri.endsWith("$"); + _isRegex = uri.startsWith("^") && uri.endsWith("$"); } void setMethod(WebRequestMethodComposite method){ _method = method; } void onRequest(ArRequestHandlerFunction fn){ _onRequest = fn; } @@ -89,18 +91,21 @@ class AsyncCallbackWebHandler: public AsyncWebHandler { if(!(_method & request->method())) return false; +#ifdef ASYNCWEBSERVER_REGEX if (_isRegex) { - std::regex rgx(_uri.c_str()); + std::regex pattern(_uri.c_str()); std::smatch matches; std::string s(request->url().c_str()); - if(std::regex_search(s, matches, rgx)) { + if(std::regex_search(s, matches, pattern)) { for (size_t i = 1; i < matches.size(); ++i) { // start from 1 request->_addPathParam(matches[i].str().c_str()); } } else { return false; } - } else if (_uri.length() && _uri.endsWith("*")) { + } else +#endif + if (_uri.length() && _uri.endsWith("*")) { String uriTemplate = String(_uri); uriTemplate = uriTemplate.substring(0, uriTemplate.length() - 1); if (!request->url().startsWith(uriTemplate)) From f13685ee97675be2ac9502d177d3024ebc49c1e0 Mon Sep 17 00:00:00 2001 From: Arjan Filius Date: Thu, 17 Oct 2019 09:05:13 +0200 Subject: [PATCH 033/551] AsyncEvents/ServerSideEvents: prevent internal DOS by prevent overflowing messageQueue (#621) * Prevent tcp/wifi DOS lockup by preventing number of messages in queue, drop otherwise * Define (renamed) MAX_SSE_Clients --- src/AsyncEventSource.cpp | 12 ++++++++---- src/AsyncEventSource.h | 17 +++++++++++++++++ 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/src/AsyncEventSource.cpp b/src/AsyncEventSource.cpp index ad188e8fb..f2914df54 100644 --- a/src/AsyncEventSource.cpp +++ b/src/AsyncEventSource.cpp @@ -184,10 +184,14 @@ void AsyncEventSourceClient::_queueMessage(AsyncEventSourceMessage *dataMessage) delete dataMessage; return; } - - _messageQueue.add(dataMessage); - - _runQueue(); + if(_messageQueue.length() >= SSE_MAX_QUEUED_MESSAGES){ + ets_printf("ERROR: Too many messages queued\n"); + delete dataMessage; + } else { + _messageQueue.add(dataMessage); + } + if(_client->canSend()) + _runQueue(); } void AsyncEventSourceClient::_onAck(size_t len, uint32_t time){ diff --git a/src/AsyncEventSource.h b/src/AsyncEventSource.h index 7c212e9f5..b097fa623 100644 --- a/src/AsyncEventSource.h +++ b/src/AsyncEventSource.h @@ -23,11 +23,28 @@ #include #ifdef ESP32 #include +#define SSE_MAX_QUEUED_MESSAGES 32 #else #include +#define SSE_MAX_QUEUED_MESSAGES 8 #endif #include +#include "AsyncWebSynchronization.h" + +#ifdef ESP8266 +#include +#ifdef CRYPTO_HASH_h // include Hash.h from espressif framework if the first include was from the crypto library +#include <../src/Hash.h> +#endif +#endif + +#ifdef ESP32 +#define DEFAULT_MAX_SSE_CLIENTS 8 +#else +#define DEFAULT_MAX_SSE_CLIENTS 4 +#endif + class AsyncEventSource; class AsyncEventSourceResponse; class AsyncEventSourceClient; From 406f21c5ddd39a112c5bb90bf95580c39733bde7 Mon Sep 17 00:00:00 2001 From: lorol Date: Wed, 11 Mar 2020 23:21:50 -0400 Subject: [PATCH 034/551] Applied important changes of other forks after master ESPAsyncWebServer release (at the moment) - fixes - SPIFFSEditor is changed to be standalone - works with acefull.js.gz, see the example Added a real SmartSwitch application to examples --- examples/SmartSwitch/ESPAsyncWiFiManager.cpp | 1177 ++++ examples/SmartSwitch/ESPAsyncWiFiManager.h | 279 + examples/SmartSwitch/PinOut_Notes.txt | 13 + examples/SmartSwitch/SmartSwitch.ino | 479 ++ examples/SmartSwitch/data/.exclude.files | 2 + examples/SmartSwitch/data/acefull.js.gz | Bin 0 -> 111691 bytes examples/SmartSwitch/data/app.css.gz | Bin 0 -> 2740 bytes examples/SmartSwitch/data/app.min.js.gz | Bin 0 -> 38439 bytes examples/SmartSwitch/data/favicon.ico.gz | Bin 0 -> 4314 bytes examples/SmartSwitch/data/index.htm.gz | Bin 0 -> 3834 bytes examples/SmartSwitch/data/index2.htm | 585 ++ examples/SmartSwitch/data_src/acefull.js | 1 + examples/SmartSwitch/data_src/app.css | 1 + examples/SmartSwitch/data_src/app.min.js | 533 ++ examples/SmartSwitch/data_src/desktop.ini | 2 + examples/SmartSwitch/data_src/favicon.ico | Bin 0 -> 15406 bytes examples/SmartSwitch/data_src/index.htm | 585 ++ .../data_src/js_css_src/.exclude.files | 2 + .../SmartSwitch/data_src/js_css_src/ace.js | 14 + .../SmartSwitch/data_src/js_css_src/app.js | 5787 +++++++++++++++++ .../data_src/js_css_src/desktop.ini | 2 + .../data_src/js_css_src/ext-searchbox.js | 5 + .../js_css_src/js-time-picker/1-inline.html | 30 + .../js_css_src/js-time-picker/2-popup.html | 27 + .../js_css_src/js-time-picker/README.txt | 29 + .../js-time-picker/tpick-light-pop.css | 65 + .../js_css_src/js-time-picker/tpick-light.css | 47 + .../js_css_src/js-time-picker/tpick-pop.js | 136 + .../js_css_src/js-time-picker/tpick.js | 116 + .../justgage-1.2.2/examples/auto-adjust.htm | 94 + .../justgage-1.2.2/examples/counter.html | 58 + .../examples/custom-interval.htm | 82 + .../justgage-1.2.2/examples/custom-node.html | 130 + .../examples/custom-sectors.html | 88 + .../examples/custom-value-renderer.html | 116 + .../examples/customize-style.htm | 137 + .../justgage-1.2.2/examples/defaults.html | 60 + .../justgage-1.2.2/examples/font-options.html | 62 + .../examples/format-number.html | 56 + .../examples/html5-data-attribute-config.html | 54 + .../examples/human-friendly-numbers.html | 109 + .../justgage-1.2.2/examples/pointer.html | 168 + .../examples/refresh-maximum.html | 91 + .../examples/responsive-gauges.htm | 71 + .../justgage-1.2.2/examples/reverse.html | 144 + .../js_css_src/justgage-1.2.2/justgage.js | 1220 ++++ .../justgage-1.2.2/raphael-2.1.4.min.js | 12 + .../data_src/js_css_src/mode-css.js | 1 + .../data_src/js_css_src/mode-html.js | 1 + .../data_src/js_css_src/mode-javascript.js | 1 + .../js_css_src/styled-notifications/.babelrc | 3 + .../styled-notifications/.eslintrc.js | 31 + .../styled-notifications/.gitignore | 30 + .../styled-notifications/.travis.yml | 3 + .../styled-notifications/LICENSE.md | 7 + .../__tests__/helpers.test.js | 104 + .../__tests__/index.tests.js | 144 + .../styled-notifications/demo/demo.js | 34 + .../styled-notifications/demo/index.html | 101 + .../styled-notifications/demo/index_my.html | 37 + .../dist/notifications.css | 1 + .../dist/notifications.css.gz | Bin 0 -> 2487 bytes .../dist/notifications.js | 1 + .../dist/notifications.js.gz | Bin 0 -> 1723 bytes .../styled-notifications/package.json | 58 + .../js_css_src/styled-notifications/readme.md | 82 + .../styled-notifications/src/helpers.js | 24 + .../styled-notifications/src/index.js | 148 + .../src/polyfills/classList.js | 68 + .../styled-notifications/src/style.scss | 134 + .../styled-notifications/webpack.config.js | 41 + .../data_src/js_css_src/worker-html.js | 1 + examples/SmartSwitch/desktop.ini | 2 + src/AsyncWebSocket.cpp | 1 + src/SPIFFSEditor.cpp | 525 +- src/WebRequest.cpp | 4 + src/edit.htm | 628 +- 77 files changed, 13995 insertions(+), 889 deletions(-) create mode 100644 examples/SmartSwitch/ESPAsyncWiFiManager.cpp create mode 100644 examples/SmartSwitch/ESPAsyncWiFiManager.h create mode 100644 examples/SmartSwitch/PinOut_Notes.txt create mode 100644 examples/SmartSwitch/SmartSwitch.ino create mode 100644 examples/SmartSwitch/data/.exclude.files create mode 100644 examples/SmartSwitch/data/acefull.js.gz create mode 100644 examples/SmartSwitch/data/app.css.gz create mode 100644 examples/SmartSwitch/data/app.min.js.gz create mode 100644 examples/SmartSwitch/data/favicon.ico.gz create mode 100644 examples/SmartSwitch/data/index.htm.gz create mode 100644 examples/SmartSwitch/data/index2.htm create mode 100644 examples/SmartSwitch/data_src/acefull.js create mode 100644 examples/SmartSwitch/data_src/app.css create mode 100644 examples/SmartSwitch/data_src/app.min.js create mode 100644 examples/SmartSwitch/data_src/desktop.ini create mode 100644 examples/SmartSwitch/data_src/favicon.ico create mode 100644 examples/SmartSwitch/data_src/index.htm create mode 100644 examples/SmartSwitch/data_src/js_css_src/.exclude.files create mode 100644 examples/SmartSwitch/data_src/js_css_src/ace.js create mode 100644 examples/SmartSwitch/data_src/js_css_src/app.js create mode 100644 examples/SmartSwitch/data_src/js_css_src/desktop.ini create mode 100644 examples/SmartSwitch/data_src/js_css_src/ext-searchbox.js create mode 100644 examples/SmartSwitch/data_src/js_css_src/js-time-picker/1-inline.html create mode 100644 examples/SmartSwitch/data_src/js_css_src/js-time-picker/2-popup.html create mode 100644 examples/SmartSwitch/data_src/js_css_src/js-time-picker/README.txt create mode 100644 examples/SmartSwitch/data_src/js_css_src/js-time-picker/tpick-light-pop.css create mode 100644 examples/SmartSwitch/data_src/js_css_src/js-time-picker/tpick-light.css create mode 100644 examples/SmartSwitch/data_src/js_css_src/js-time-picker/tpick-pop.js create mode 100644 examples/SmartSwitch/data_src/js_css_src/js-time-picker/tpick.js create mode 100644 examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/auto-adjust.htm create mode 100644 examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/counter.html create mode 100644 examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/custom-interval.htm create mode 100644 examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/custom-node.html create mode 100644 examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/custom-sectors.html create mode 100644 examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/custom-value-renderer.html create mode 100644 examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/customize-style.htm create mode 100644 examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/defaults.html create mode 100644 examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/font-options.html create mode 100644 examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/format-number.html create mode 100644 examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/html5-data-attribute-config.html create mode 100644 examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/human-friendly-numbers.html create mode 100644 examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/pointer.html create mode 100644 examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/refresh-maximum.html create mode 100644 examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/responsive-gauges.htm create mode 100644 examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/reverse.html create mode 100644 examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/justgage.js create mode 100644 examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/raphael-2.1.4.min.js create mode 100644 examples/SmartSwitch/data_src/js_css_src/mode-css.js create mode 100644 examples/SmartSwitch/data_src/js_css_src/mode-html.js create mode 100644 examples/SmartSwitch/data_src/js_css_src/mode-javascript.js create mode 100644 examples/SmartSwitch/data_src/js_css_src/styled-notifications/.babelrc create mode 100644 examples/SmartSwitch/data_src/js_css_src/styled-notifications/.eslintrc.js create mode 100644 examples/SmartSwitch/data_src/js_css_src/styled-notifications/.gitignore create mode 100644 examples/SmartSwitch/data_src/js_css_src/styled-notifications/.travis.yml create mode 100644 examples/SmartSwitch/data_src/js_css_src/styled-notifications/LICENSE.md create mode 100644 examples/SmartSwitch/data_src/js_css_src/styled-notifications/__tests__/helpers.test.js create mode 100644 examples/SmartSwitch/data_src/js_css_src/styled-notifications/__tests__/index.tests.js create mode 100644 examples/SmartSwitch/data_src/js_css_src/styled-notifications/demo/demo.js create mode 100644 examples/SmartSwitch/data_src/js_css_src/styled-notifications/demo/index.html create mode 100644 examples/SmartSwitch/data_src/js_css_src/styled-notifications/demo/index_my.html create mode 100644 examples/SmartSwitch/data_src/js_css_src/styled-notifications/dist/notifications.css create mode 100644 examples/SmartSwitch/data_src/js_css_src/styled-notifications/dist/notifications.css.gz create mode 100644 examples/SmartSwitch/data_src/js_css_src/styled-notifications/dist/notifications.js create mode 100644 examples/SmartSwitch/data_src/js_css_src/styled-notifications/dist/notifications.js.gz create mode 100644 examples/SmartSwitch/data_src/js_css_src/styled-notifications/package.json create mode 100644 examples/SmartSwitch/data_src/js_css_src/styled-notifications/readme.md create mode 100644 examples/SmartSwitch/data_src/js_css_src/styled-notifications/src/helpers.js create mode 100644 examples/SmartSwitch/data_src/js_css_src/styled-notifications/src/index.js create mode 100644 examples/SmartSwitch/data_src/js_css_src/styled-notifications/src/polyfills/classList.js create mode 100644 examples/SmartSwitch/data_src/js_css_src/styled-notifications/src/style.scss create mode 100644 examples/SmartSwitch/data_src/js_css_src/styled-notifications/webpack.config.js create mode 100644 examples/SmartSwitch/data_src/js_css_src/worker-html.js create mode 100644 examples/SmartSwitch/desktop.ini diff --git a/examples/SmartSwitch/ESPAsyncWiFiManager.cpp b/examples/SmartSwitch/ESPAsyncWiFiManager.cpp new file mode 100644 index 000000000..44552582f --- /dev/null +++ b/examples/SmartSwitch/ESPAsyncWiFiManager.cpp @@ -0,0 +1,1177 @@ +/************************************************************** + AsyncWiFiManager is a library for the ESP8266/Arduino platform + (https://github.com/esp8266/Arduino) to enable easy + configuration and reconfiguration of WiFi credentials using a Captive Portal + inspired by: + http://www.esp8266.com/viewtopic.php?f=29&t=2520 + https://github.com/chriscook8/esp-arduino-apboot + https://github.com/esp8266/Arduino/tree/esp8266/hardware/esp8266com/esp8266/libraries/DNSServer/examples/CaptivePortalAdvanced + Built by AlexT https://github.com/tzapu + Ported to Async Web Server by https://github.com/alanswx + Licensed under MIT license + **************************************************************/ + +#include "ESPAsyncWiFiManager.h" + +AsyncWiFiManagerParameter::AsyncWiFiManagerParameter(const char *custom) { + _id = NULL; + _placeholder = NULL; + _length = 0; + _value = NULL; + + _customHTML = custom; +} + +AsyncWiFiManagerParameter::AsyncWiFiManagerParameter(const char *id, const char *placeholder, const char *defaultValue, int length) { + init(id, placeholder, defaultValue, length, ""); +} + +AsyncWiFiManagerParameter::AsyncWiFiManagerParameter(const char *id, const char *placeholder, const char *defaultValue, int length, const char *custom) { + init(id, placeholder, defaultValue, length, custom); +} + +void AsyncWiFiManagerParameter::init(const char *id, const char *placeholder, const char *defaultValue, int length, const char *custom) { + _id = id; + _placeholder = placeholder; + _length = length; + _value = new char[length + 1]; + for (int i = 0; i < length; i++) { + _value[i] = 0; + } + if (defaultValue != NULL) { + strncpy(_value, defaultValue, length); + } + + _customHTML = custom; +} + +const char* AsyncWiFiManagerParameter::getValue() { + return _value; +} +const char* AsyncWiFiManagerParameter::getID() { + return _id; +} +const char* AsyncWiFiManagerParameter::getPlaceholder() { + return _placeholder; +} +int AsyncWiFiManagerParameter::getValueLength() { + return _length; +} +const char* AsyncWiFiManagerParameter::getCustomHTML() { + return _customHTML; +} + +#ifdef USE_EADNS +AsyncWiFiManager::AsyncWiFiManager(AsyncWebServer *server, AsyncDNSServer *dns) :server(server), dnsServer(dns) { +#else +AsyncWiFiManager::AsyncWiFiManager(AsyncWebServer *server, DNSServer *dns) :server(server), dnsServer(dns) { +#endif + wifiSSIDs = NULL; + wifiSSIDscan=true; + _modeless=false; + shouldscan=true; +} + +void AsyncWiFiManager::addParameter(AsyncWiFiManagerParameter *p) { + _params[_paramsCount] = p; + _paramsCount++; + DEBUG_WM("Adding parameter"); + DEBUG_WM(p->getID()); +} + +void AsyncWiFiManager::setupConfigPortal() { + // dnsServer.reset(new DNSServer()); + // server.reset(new ESP8266WebServer(80)); + server->reset(); + + DEBUG_WM(F("")); + _configPortalStart = millis(); + + DEBUG_WM(F("Configuring access point... ")); + DEBUG_WM(_apName); + if (_apPassword != NULL) { + if (strlen(_apPassword) < 8 || strlen(_apPassword) > 63) { + // fail passphrase to short or long! + DEBUG_WM(F("Invalid AccessPoint password. Ignoring")); + _apPassword = NULL; + } + DEBUG_WM(_apPassword); + } + + //optional soft ip config + if (_ap_static_ip) { + DEBUG_WM(F("Custom AP IP/GW/Subnet")); + WiFi.softAPConfig(_ap_static_ip, _ap_static_gw, _ap_static_sn); + } + + if (_apPassword != NULL) { + WiFi.softAP(_apName, _apPassword);//password option + } else { + WiFi.softAP(_apName); + } + + delay(500); // Without delay I've seen the IP address blank + DEBUG_WM(F("AP IP address: ")); + DEBUG_WM(WiFi.softAPIP()); + + /* Setup the DNS server redirecting all the domains to the apIP */ + #ifdef USE_EADNS + dnsServer->setErrorReplyCode(AsyncDNSReplyCode::NoError); + #else + dnsServer->setErrorReplyCode(DNSReplyCode::NoError); + #endif + dnsServer->start(DNS_PORT, "*", WiFi.softAPIP()); + + setInfo(); + + /* Setup web pages: root, wifi config pages, SO captive portal detectors and not found. */ + server->on("/", std::bind(&AsyncWiFiManager::handleRoot, this,std::placeholders::_1)).setFilter(ON_AP_FILTER); + server->on("/wifi", std::bind(&AsyncWiFiManager::handleWifi, this, std::placeholders::_1,true)).setFilter(ON_AP_FILTER); + server->on("/0wifi", std::bind(&AsyncWiFiManager::handleWifi, this,std::placeholders::_1, false)).setFilter(ON_AP_FILTER); + server->on("/wifisave", std::bind(&AsyncWiFiManager::handleWifiSave,this,std::placeholders::_1)).setFilter(ON_AP_FILTER); + server->on("/i", std::bind(&AsyncWiFiManager::handleInfo,this, std::placeholders::_1)).setFilter(ON_AP_FILTER); + server->on("/r", std::bind(&AsyncWiFiManager::handleReset, this,std::placeholders::_1)).setFilter(ON_AP_FILTER); + //server->on("/generate_204", std::bind(&AsyncWiFiManager::handle204, this)); //Android/Chrome OS captive portal check. + server->on("/fwlink", std::bind(&AsyncWiFiManager::handleRoot, this,std::placeholders::_1)).setFilter(ON_AP_FILTER); //Microsoft captive portal. Maybe not needed. Might be handled by notFound handler. + server->onNotFound (std::bind(&AsyncWiFiManager::handleNotFound,this,std::placeholders::_1)); + server->begin(); // Web server start + DEBUG_WM(F("HTTP server started")); + +} + +static const char HEX_CHAR_ARRAY[17] = "0123456789ABCDEF"; +/** +* convert char array (hex values) to readable string by seperator +* buf: buffer to convert +* length: data length +* strSeperator seperator between each hex value +* return: formated value as String +*/ +static String byteToHexString(uint8_t* buf, uint8_t length, String strSeperator="-") { + String dataString = ""; + for (uint8_t i = 0; i < length; i++) { + byte v = buf[i] / 16; + byte w = buf[i] % 16; + if (i>0) { + dataString += strSeperator; + } + dataString += String(HEX_CHAR_ARRAY[v]); + dataString += String(HEX_CHAR_ARRAY[w]); + } + dataString.toUpperCase(); + return dataString; +} // byteToHexString + +#if !defined(ESP8266) +String getESP32ChipID() { + uint64_t chipid; + chipid=ESP.getEfuseMac();//The chip ID is essentially its MAC address(length: 6 bytes). + int chipid_size = 6; + uint8_t chipid_arr[chipid_size]; + for (uint8_t i=0; i < chipid_size; i++) { + chipid_arr[i] = (chipid >> (8 * i)) & 0xff; + } + return byteToHexString(chipid_arr, chipid_size, ""); +} +#endif + +boolean AsyncWiFiManager::autoConnect(unsigned long maxConnectRetries, unsigned long retryDelayMs) { + String ssid = "ESP"; + #if defined(ESP8266) + ssid += String(ESP.getChipId()); + #else + ssid += getESP32ChipID(); + #endif + return autoConnect(ssid.c_str(), NULL); +} + +boolean AsyncWiFiManager::autoConnect(char const *apName, char const *apPassword, unsigned long maxConnectRetries, unsigned long retryDelayMs) { + DEBUG_WM(F("")); + + // read eeprom for ssid and pass + //String ssid = getSSID(); + //String pass = getPassword(); + + // attempt to connect; should it fail, fall back to AP + WiFi.mode(WIFI_STA); + + for(unsigned long tryNumber = 0; tryNumber < maxConnectRetries; tryNumber++) { + DEBUG_WM(F("AutoConnect Try No.:")); + DEBUG_WM(tryNumber); + + if (connectWifi("", "") == WL_CONNECTED) { + DEBUG_WM(F("IP Address:")); + DEBUG_WM(WiFi.localIP()); + //connected + return true; + } + + if(tryNumber + 1 < maxConnectRetries) { + + // we might connect during the delay + unsigned long restDelayMs = retryDelayMs; + while(restDelayMs != 0) { + if(WiFi.status() == WL_CONNECTED) { + DEBUG_WM(F("IP Address (connected during delay):")); + DEBUG_WM(WiFi.localIP()); + return true; + } + unsigned long thisDelay = std::min(restDelayMs, 100ul); + delay(thisDelay); + restDelayMs -= thisDelay; + } + + } + } + + + return startConfigPortal(apName, apPassword); +} + + +String AsyncWiFiManager::networkListAsString() +{ + String pager ; + //display networks in page + for (int i = 0; i < wifiSSIDCount; i++) { + if (wifiSSIDs[i].duplicate == true) continue; // skip dups + int quality = getRSSIasQuality(wifiSSIDs[i].RSSI); + + if (_minimumQuality == -1 || _minimumQuality < quality) { + String item = FPSTR(HTTP_ITEM); + String rssiQ; + rssiQ += quality; + item.replace("{v}", wifiSSIDs[i].SSID); + item.replace("{r}", rssiQ); +#if defined(ESP8266) + if (wifiSSIDs[i].encryptionType != ENC_TYPE_NONE) { +#else + if (wifiSSIDs[i].encryptionType != WIFI_AUTH_OPEN) { +#endif + item.replace("{i}", "l"); + } else { + item.replace("{i}", ""); + } + pager += item; + + } else { + DEBUG_WM(F("Skipping due to quality")); + } + + } + return pager; +} + +String AsyncWiFiManager::scanModal() +{ + shouldscan=true; + scan(); + String pager=networkListAsString(); + return pager; +} + +void AsyncWiFiManager::scan() +{ + if (!shouldscan) return; + DEBUG_WM(F("About to scan()")); + if (wifiSSIDscan) + { + delay(100); + } + + if (wifiSSIDscan) + { + wifi_ssid_count_t n = WiFi.scanNetworks(); + DEBUG_WM(F("Scan done")); + if(n == WIFI_SCAN_FAILED) { + DEBUG_WM(F("scanNetworks returned: WIFI_SCAN_FAILED!")); + } else if(n == WIFI_SCAN_RUNNING) { + DEBUG_WM(F("scanNetworks returned: WIFI_SCAN_RUNNING!")); + } else if(n < 0) { + DEBUG_WM(F("scanNetworks failed with unknown error code!")); + } else if (n == 0) { + DEBUG_WM(F("No networks found")); + // page += F("No networks found. Refresh to scan again."); + } else { + + + if (wifiSSIDscan) + { + /* WE SHOULD MOVE THIS IN PLACE ATOMICALLY */ + if (wifiSSIDs) delete [] wifiSSIDs; + wifiSSIDs = new WiFiResult[n]; + wifiSSIDCount = n; + + if (n>0) + shouldscan=false; + + for (wifi_ssid_count_t i=0;i wifiSSIDs[i].RSSI) { + std::swap(wifiSSIDs[i], wifiSSIDs[j]); + } + } + } + + + // remove duplicates ( must be RSSI sorted ) + if (_removeDuplicateAPs) { + String cssid; + for (int i = 0; i < n; i++) { + if (wifiSSIDs[i].duplicate == true) continue; + cssid = wifiSSIDs[i].SSID; + for (int j = i + 1; j < n; j++) { + if (cssid == wifiSSIDs[j].SSID) { + DEBUG_WM("DUP AP: " +wifiSSIDs[j].SSID); + wifiSSIDs[j].duplicate=true; // set dup aps to NULL + } + } + } + } + + } + } + } +} + + +void AsyncWiFiManager::startConfigPortalModeless(char const *apName, char const *apPassword) { + + _modeless =true; + _apName = apName; + _apPassword = apPassword; + + /* + AJS - do we want this? + + */ + + //setup AP + WiFi.mode(WIFI_AP_STA); + DEBUG_WM("SET AP STA"); + + // try to connect + if (connectWifi("", "") == WL_CONNECTED) { + DEBUG_WM(F("IP Address:")); + DEBUG_WM(WiFi.localIP()); + //connected + // call the callback! + if ( _savecallback != NULL) { + //todo: check if any custom parameters actually exist, and check if they really changed maybe + _savecallback(); + } + } + + + + //notify we entered AP mode + if ( _apcallback != NULL) { + _apcallback(this); + } + + connect = false; + setupConfigPortal(); + scannow= -1 ; + +} + +void AsyncWiFiManager::loop(){ + safeLoop(); + criticalLoop(); +} + +void AsyncWiFiManager::setInfo() { + if (needInfo) { + pager = infoAsString(); + wifiStatus = WiFi.status(); + needInfo = false; + } +} + +/** + * Anything that accesses WiFi, ESP or EEPROM goes here + */ +void AsyncWiFiManager::criticalLoop(){ + if (_modeless) + { + + if ( scannow==-1 || millis() > scannow + 60000) + { + scan(); + scannow= millis() ; + } + if (connect) { + connect = false; + //delay(2000); + DEBUG_WM(F("Connecting to new AP")); + + // using user-provided _ssid, _pass in place of system-stored ssid and pass + if (connectWifi(_ssid, _pass) != WL_CONNECTED) { + DEBUG_WM(F("Failed to connect.")); + } else { + //connected + // alanswx - should we have a config to decide if we should shut down AP? + // WiFi.mode(WIFI_STA); + //notify that configuration has changed and any optional parameters should be saved + if ( _savecallback != NULL) { + //todo: check if any custom parameters actually exist, and check if they really changed maybe + _savecallback(); + } + + return; + } + + if (_shouldBreakAfterConfig) { + //flag set to exit after config after trying to connect + //notify that configuration has changed and any optional parameters should be saved + if ( _savecallback != NULL) { + //todo: check if any custom parameters actually exist, and check if they really changed maybe + _savecallback(); + } + } + } + } +} + +/* + * Anything that doesn't access WiFi, ESP or EEPROM can go here + */ +void AsyncWiFiManager::safeLoop(){ + #ifndef USE_EADNS + dnsServer->processNextRequest(); + #endif +} + +boolean AsyncWiFiManager::startConfigPortal(char const *apName, char const *apPassword) { + //setup AP + WiFi.mode(WIFI_AP_STA); + DEBUG_WM("SET AP STA"); + + _apName = apName; + _apPassword = apPassword; + + //notify we entered AP mode + if ( _apcallback != NULL) { + _apcallback(this); + } + + connect = false; + setupConfigPortal(); + scannow= -1 ; + while (_configPortalTimeout == 0 || millis() < _configPortalStart + _configPortalTimeout) { + //DNS + #ifndef USE_EADNS + dnsServer->processNextRequest(); + #endif + + // + // we should do a scan every so often here and + // try to reconnect to AP while we are at it + // + if ( scannow == -1 || millis() > scannow + 10000) + { + DEBUG_WM(F("About to scan()")); + shouldscan=true; // since we are modal, we can scan every time + #if defined(ESP8266) + // we might still be connecting, so that has to stop for scanning + ETS_UART_INTR_DISABLE (); + wifi_station_disconnect (); + ETS_UART_INTR_ENABLE (); + #else + WiFi.disconnect (false); + #endif + scan(); + if(_tryConnectDuringConfigPortal) WiFi.begin(); // try to reconnect to AP + scannow= millis() ; + } + + // attempts to reconnect were successful + if(WiFi.status() == WL_CONNECTED) { + //connected + WiFi.mode(WIFI_STA); + //notify that configuration has changed and any optional parameters should be saved + if ( _savecallback != NULL) { + //todo: check if any custom parameters actually exist, and check if they really changed maybe + _savecallback(); + } + break; + } + + + if (connect) { + connect = false; + delay(2000); + DEBUG_WM(F("Connecting to new AP")); + + // using user-provided _ssid, _pass in place of system-stored ssid and pass + if (connectWifi(_ssid, _pass) == WL_CONNECTED) { + //connected + WiFi.mode(WIFI_STA); + //notify that configuration has changed and any optional parameters should be saved + if ( _savecallback != NULL) { + //todo: check if any custom parameters actually exist, and check if they really changed maybe + _savecallback(); + } + break; + } else { + DEBUG_WM(F("Failed to connect.")); + } + + if (_shouldBreakAfterConfig) { + //flag set to exit after config after trying to connect + //notify that configuration has changed and any optional parameters should be saved + if ( _savecallback != NULL) { + //todo: check if any custom parameters actually exist, and check if they really changed maybe + _savecallback(); + } + break; + } + } + yield(); + } + + server->reset(); + #ifdef USE_EADNS + *dnsServer=AsyncDNSServer(); + #else + *dnsServer=DNSServer(); + #endif + + return WiFi.status() == WL_CONNECTED; +} + + +int AsyncWiFiManager::connectWifi(String ssid, String pass) { + DEBUG_WM(F("Connecting as wifi client...")); + + // check if we've got static_ip settings, if we do, use those. + if (_sta_static_ip) { + DEBUG_WM(F("Custom STA IP/GW/Subnet/DNS")); + WiFi.config(_sta_static_ip, _sta_static_gw, _sta_static_sn, _sta_static_dns1, _sta_static_dns2); + DEBUG_WM(WiFi.localIP()); + } + //fix for auto connect racing issue + // if (WiFi.status() == WL_CONNECTED) { + // DEBUG_WM("Already connected. Bailing out."); + // return WL_CONNECTED; + // } + //check if we have ssid and pass and force those, if not, try with last saved values + if (ssid != "") { + #if defined(ESP8266) + //trying to fix connection in progress hanging + ETS_UART_INTR_DISABLE(); + wifi_station_disconnect(); + ETS_UART_INTR_ENABLE(); + #else + WiFi.disconnect(false); + #endif + + WiFi.begin(ssid.c_str(), pass.c_str()); + } else { + + if (WiFi.SSID().length() > 0) { + DEBUG_WM("Using last saved values, should be faster"); +#if defined(ESP8266) + //trying to fix connection in progress hanging + ETS_UART_INTR_DISABLE(); + wifi_station_disconnect(); + ETS_UART_INTR_ENABLE(); +#else + WiFi.disconnect(false); +#endif + + WiFi.begin(); + } else { + DEBUG_WM("Try to connect with saved credentials"); + WiFi.begin(); + } + } + + int connRes = waitForConnectResult(); + DEBUG_WM ("Connection result: "); + DEBUG_WM ( connRes ); + //not connected, WPS enabled, no pass - first attempt +#ifdef NO_EXTRA_4K_HEAP + if (_tryWPS && connRes != WL_CONNECTED && pass == "") { + startWPS(); + //should be connected at the end of WPS + connRes = waitForConnectResult(); + } +#endif + needInfo = true; + setInfo(); + return connRes; +} + +uint8_t AsyncWiFiManager::waitForConnectResult() { + if (_connectTimeout == 0) { + return WiFi.waitForConnectResult(); + } else { + DEBUG_WM (F("Waiting for connection result with time out")); + unsigned long start = millis(); + boolean keepConnecting = true; + uint8_t status; + while (keepConnecting) { + status = WiFi.status(); + if (millis() > start + _connectTimeout) { + keepConnecting = false; + DEBUG_WM (F("Connection timed out")); + } + if (status == WL_CONNECTED || status == WL_CONNECT_FAILED) { + keepConnecting = false; + } + delay(100); + } + return status; + } +} +#ifdef NO_EXTRA_4K_HEAP +void AsyncWiFiManager::startWPS() { + DEBUG_WM("START WPS"); +#if defined(ESP8266) + WiFi.beginWPSConfig(); +#else + //esp_wps_config_t config = WPS_CONFIG_INIT_DEFAULT(ESP_WPS_MODE); + esp_wps_config_t config = {}; + config.wps_type = ESP_WPS_MODE; + config.crypto_funcs = &g_wifi_default_wps_crypto_funcs; + strcpy(config.factory_info.manufacturer,"ESPRESSIF"); + strcpy(config.factory_info.model_number, "ESP32"); + strcpy(config.factory_info.model_name, "ESPRESSIF IOT"); + strcpy(config.factory_info.device_name,"ESP STATION"); + + esp_wifi_wps_enable(&config); + esp_wifi_wps_start(0); +#endif + DEBUG_WM("END WPS"); + +} +#endif +/* +String AsyncWiFiManager::getSSID() { +if (_ssid == "") { +DEBUG_WM(F("Reading SSID")); +_ssid = WiFi.SSID(); +DEBUG_WM(F("SSID: ")); +DEBUG_WM(_ssid); +} +return _ssid; +} + +String AsyncWiFiManager::getPassword() { +if (_pass == "") { +DEBUG_WM(F("Reading Password")); +_pass = WiFi.psk(); +DEBUG_WM("Password: " + _pass); +//DEBUG_WM(_pass); +} +return _pass; +} +*/ +String AsyncWiFiManager::getConfigPortalSSID() { + return _apName; +} + +void AsyncWiFiManager::resetSettings() { + DEBUG_WM(F("settings invalidated")); + DEBUG_WM(F("THIS MAY CAUSE AP NOT TO START UP PROPERLY. YOU NEED TO COMMENT IT OUT AFTER ERASING THE DATA.")); + WiFi.disconnect(true); + //delay(200); +} +void AsyncWiFiManager::setTimeout(unsigned long seconds) { + setConfigPortalTimeout(seconds); +} + +void AsyncWiFiManager::setConfigPortalTimeout(unsigned long seconds) { + _configPortalTimeout = seconds * 1000; +} + +void AsyncWiFiManager::setConnectTimeout(unsigned long seconds) { + _connectTimeout = seconds * 1000; +} + +void AsyncWiFiManager::setTryConnectDuringConfigPortal(boolean v) { + _tryConnectDuringConfigPortal = v; +} + +void AsyncWiFiManager::setDebugOutput(boolean debug) { + _debug = debug; +} + +void AsyncWiFiManager::setAPStaticIPConfig(IPAddress ip, IPAddress gw, IPAddress sn) { + _ap_static_ip = ip; + _ap_static_gw = gw; + _ap_static_sn = sn; +} + +void AsyncWiFiManager::setSTAStaticIPConfig(IPAddress ip, IPAddress gw, IPAddress sn, IPAddress dns1, IPAddress dns2) { + _sta_static_ip = ip; + _sta_static_gw = gw; + _sta_static_sn = sn; + _sta_static_dns1 = dns1; + _sta_static_dns2 = dns2; +} + +void AsyncWiFiManager::setMinimumSignalQuality(int quality) { + _minimumQuality = quality; +} + +void AsyncWiFiManager::setBreakAfterConfig(boolean shouldBreak) { + _shouldBreakAfterConfig = shouldBreak; +} + +/** Handle root or redirect to captive portal */ +void AsyncWiFiManager::handleRoot(AsyncWebServerRequest *request) { + // AJS - maybe we should set a scan when we get to the root??? + // and only scan on demand? timer + on demand? plus a link to make it happen? + shouldscan=true; + scannow= -1 ; + DEBUG_WM(F("Handle root")); + if (captivePortal(request)) { // If captive portal redirect instead of displaying the page. + return; + } + + String page = FPSTR(WFM_HTTP_HEAD); + page.replace("{v}", "Options"); + page += FPSTR(HTTP_SCRIPT); + page += FPSTR(HTTP_STYLE); + page += _customHeadElement; + page += FPSTR(HTTP_HEAD_END); + page += "

"; + page += _apName; + page += "

"; + page += F("

AsyncWiFiManager

"); + page += FPSTR(HTTP_PORTAL_OPTIONS); + page += _customOptionsElement; + page += FPSTR(HTTP_END); + + request->send(200, "text/html", page); + +} + +/** Wifi config page handler */ +void AsyncWiFiManager::handleWifi(AsyncWebServerRequest *request,boolean scan) { + shouldscan=true; + scannow= -1 ; + + DEBUG_WM(F("Handle wifi")); + + String page = FPSTR(WFM_HTTP_HEAD); + page.replace("{v}", "Config ESP"); + page += FPSTR(HTTP_SCRIPT); + page += FPSTR(HTTP_STYLE); + page += _customHeadElement; + page += FPSTR(HTTP_HEAD_END); + + if (scan) { + wifiSSIDscan=false; + + + + DEBUG_WM(F("Scan done")); + if (wifiSSIDCount==0) { + DEBUG_WM(F("No networks found")); + page += F("No networks found. Refresh to scan again."); + } else { + + + //display networks in page + String pager = networkListAsString(); + + page += pager; + page += "
"; + } + + } + wifiSSIDscan=true; + + page += FPSTR(HTTP_FORM_START); + char parLength[2]; + // add the extra parameters to the form + for (int i = 0; i < _paramsCount; i++) { + if (_params[i] == NULL) { + break; + } + + String pitem = FPSTR(HTTP_FORM_PARAM); + if (_params[i]->getID() != NULL) { + pitem.replace("{i}", _params[i]->getID()); + pitem.replace("{n}", _params[i]->getID()); + pitem.replace("{p}", _params[i]->getPlaceholder()); + snprintf(parLength, 2, "%d", _params[i]->getValueLength()); + pitem.replace("{l}", parLength); + pitem.replace("{v}", _params[i]->getValue()); + pitem.replace("{c}", _params[i]->getCustomHTML()); + } else { + pitem = _params[i]->getCustomHTML(); + } + + page += pitem; + } + if (_params[0] != NULL) { + page += "
"; + } + + if (_sta_static_ip) { + + String item = FPSTR(HTTP_FORM_PARAM); + item.replace("{i}", "ip"); + item.replace("{n}", "ip"); + item.replace("{p}", "Static IP"); + item.replace("{l}", "15"); + item.replace("{v}", _sta_static_ip.toString()); + + page += item; + + item = FPSTR(HTTP_FORM_PARAM); + item.replace("{i}", "gw"); + item.replace("{n}", "gw"); + item.replace("{p}", "Static Gateway"); + item.replace("{l}", "15"); + item.replace("{v}", _sta_static_gw.toString()); + + page += item; + + item = FPSTR(HTTP_FORM_PARAM); + item.replace("{i}", "sn"); + item.replace("{n}", "sn"); + item.replace("{p}", "Subnet"); + item.replace("{l}", "15"); + item.replace("{v}", _sta_static_sn.toString()); + + page += item; + + item = FPSTR(HTTP_FORM_PARAM); + item.replace("{i}", "dns1"); + item.replace("{n}", "dns1"); + item.replace("{p}", "DNS1"); + item.replace("{l}", "15"); + item.replace("{v}", _sta_static_dns1.toString()); + + page += item; + + item = FPSTR(HTTP_FORM_PARAM); + item.replace("{i}", "dns2"); + item.replace("{n}", "dns2"); + item.replace("{p}", "DNS2"); + item.replace("{l}", "15"); + item.replace("{v}", _sta_static_dns2.toString()); + + page += item; + + page += "
"; + } + + page += FPSTR(HTTP_FORM_END); + page += FPSTR(HTTP_SCAN_LINK); + + page += FPSTR(HTTP_END); + + request->send(200, "text/html", page); + + + DEBUG_WM(F("Sent config page")); +} + +/** Handle the WLAN save form and redirect to WLAN config page again */ +void AsyncWiFiManager::handleWifiSave(AsyncWebServerRequest *request) { + DEBUG_WM(F("WiFi save")); + + //SAVE/connect here + needInfo = true; + _ssid = request->arg("s").c_str(); + _pass = request->arg("p").c_str(); + + //parameters + for (int i = 0; i < _paramsCount; i++) { + if (_params[i] == NULL) { + break; + } + //read parameter + String value = request->arg(_params[i]->getID()).c_str(); + //store it in array + value.toCharArray(_params[i]->_value, _params[i]->_length); + DEBUG_WM(F("Parameter")); + DEBUG_WM(_params[i]->getID()); + DEBUG_WM(value); + } + + if (request->hasArg("ip")) { + DEBUG_WM(F("static ip")); + DEBUG_WM(request->arg("ip")); + //_sta_static_ip.fromString(request->arg("ip")); + String ip = request->arg("ip"); + optionalIPFromString(&_sta_static_ip, ip.c_str()); + } + if (request->hasArg("gw")) { + DEBUG_WM(F("static gateway")); + DEBUG_WM(request->arg("gw")); + String gw = request->arg("gw"); + optionalIPFromString(&_sta_static_gw, gw.c_str()); + } + if (request->hasArg("sn")) { + DEBUG_WM(F("static netmask")); + DEBUG_WM(request->arg("sn")); + String sn = request->arg("sn"); + optionalIPFromString(&_sta_static_sn, sn.c_str()); + } + if (request->hasArg("dns1")) { + DEBUG_WM(F("static DNS 1")); + DEBUG_WM(request->arg("dns1")); + String dns1 = request->arg("dns1"); + optionalIPFromString(&_sta_static_dns1, dns1.c_str()); + } + if (request->hasArg("dns2")) { + DEBUG_WM(F("static DNS 2")); + DEBUG_WM(request->arg("dns2")); + String dns2 = request->arg("dns2"); + optionalIPFromString(&_sta_static_dns2, dns2.c_str()); + } + + String page = FPSTR(WFM_HTTP_HEAD); + page.replace("{v}", "Credentials Saved"); + page += FPSTR(HTTP_SCRIPT); + page += FPSTR(HTTP_STYLE); + page += _customHeadElement; + page += F(""); + page += FPSTR(HTTP_HEAD_END); + page += FPSTR(HTTP_SAVED); + page += FPSTR(HTTP_END); + + request->send(200, "text/html", page); + + DEBUG_WM(F("Sent wifi save page")); + + connect = true; //signal ready to connect/reset +} + +/** Handle the info page */ +String AsyncWiFiManager::infoAsString() +{ + String page; + page += F("
Chip ID
"); +#if defined(ESP8266) + page += ESP.getChipId(); +#else + page += getESP32ChipID(); +#endif + page += F("
"); + page += F("
Flash Chip ID
"); +#if defined(ESP8266) + page += ESP.getFlashChipId(); +#else + page += F("N/A for ESP32"); +#endif + page += F("
"); + page += F("
IDE Flash Size
"); + page += ESP.getFlashChipSize(); + page += F(" bytes
"); + page += F("
Real Flash Size
"); +#if defined(ESP8266) + page += ESP.getFlashChipRealSize(); +#else + page += F("N/A for ESP32"); +#endif + page += F(" bytes
"); + page += F("
Soft AP IP
"); + page += WiFi.softAPIP().toString(); + page += F("
"); + page += F("
Soft AP MAC
"); + page += WiFi.softAPmacAddress(); + page += F("
"); + page += F("
Station SSID
"); + page += WiFi.SSID(); + page += F("
"); + page += F("
Station IP
"); + page += WiFi.localIP().toString(); + page += F("
"); + page += F("
Station MAC
"); + page += WiFi.macAddress(); + page += F("
"); + page += F(""); + return page; +} + +void AsyncWiFiManager::handleInfo(AsyncWebServerRequest *request) { + DEBUG_WM(F("Info")); + + String page = FPSTR(WFM_HTTP_HEAD); + page.replace("{v}", "Info"); + page += FPSTR(HTTP_SCRIPT); + page += FPSTR(HTTP_STYLE); + page += _customHeadElement; + if (connect==true) + page += F(""); + page += FPSTR(HTTP_HEAD_END); + page += F("
"); + if (connect==true) + { + page += F("
Trying to connect
"); + page += wifiStatus; + page += F("
"); + } + + page +=pager; + page += FPSTR(HTTP_END); + + request->send(200, "text/html", page); + + DEBUG_WM(F("Sent info page")); +} + +/** Handle the reset page */ +void AsyncWiFiManager::handleReset(AsyncWebServerRequest *request) { + DEBUG_WM(F("Reset")); + + String page = FPSTR(WFM_HTTP_HEAD); + page.replace("{v}", "Info"); + page += FPSTR(HTTP_SCRIPT); + page += FPSTR(HTTP_STYLE); + page += _customHeadElement; + page += FPSTR(HTTP_HEAD_END); + page += F("Module will reset in a few seconds."); + page += FPSTR(HTTP_END); + request->send(200, "text/html", page); + + DEBUG_WM(F("Sent reset page")); + delay(5000); + #if defined(ESP8266) + ESP.reset(); + #else + ESP.restart(); + #endif + delay(2000); +} + + + +//removed as mentioned here https://github.com/tzapu/AsyncWiFiManager/issues/114 +/*void AsyncWiFiManager::handle204(AsyncWebServerRequest *request) { +DEBUG_WM(F("204 No Response")); +request->sendHeader("Cache-Control", "no-cache, no-store, must-revalidate"); +request->sendHeader("Pragma", "no-cache"); +request->sendHeader("Expires", "-1"); +request->send ( 204, "text/plain", ""); + +}*/ + +void AsyncWiFiManager::handleNotFound(AsyncWebServerRequest *request) { + DEBUG_WM(F("Handle not found")); + if (captivePortal(request)) { // If captive portal redirect instead of displaying the error page. + return; + } + String message = "File Not Found\n\n"; + message += "URI: "; + message += request->url(); + message += "\nMethod: "; + message += ( request->method() == HTTP_GET ) ? "GET" : "POST"; + message += "\nArguments: "; + message += request->args(); + message += "\n"; + + for ( uint8_t i = 0; i < request->args(); i++ ) { + message += " " + request->argName ( i ) + ": " + request->arg ( i ) + "\n"; + } + AsyncWebServerResponse *response = request->beginResponse(404,"text/plain",message); + response->addHeader("Cache-Control", "no-cache, no-store, must-revalidate"); + response->addHeader("Pragma", "no-cache"); + response->addHeader("Expires", "-1"); + request->send (response ); +} + + +/** Redirect to captive portal if we got a request for another domain. Return true in that case so the page handler do not try to handle the request again. */ +boolean AsyncWiFiManager::captivePortal(AsyncWebServerRequest *request) { + if (!isIp(request->host()) ) { + DEBUG_WM(F("Request redirected to captive portal")); + AsyncWebServerResponse *response = request->beginResponse(302,"text/plain",""); + response->addHeader("Location", String("http://") + toStringIp(request->client()->localIP())); + request->send ( response); + return true; + } + return false; +} + +//start up config portal callback +void AsyncWiFiManager::setAPCallback( void (*func)(AsyncWiFiManager* myAsyncWiFiManager) ) { + _apcallback = func; +} + +//start up save config callback +void AsyncWiFiManager::setSaveConfigCallback( void (*func)(void) ) { + _savecallback = func; +} + +//sets a custom element to add to head, like a new style tag +void AsyncWiFiManager::setCustomHeadElement(const char* element) { + _customHeadElement = element; +} + +//sets a custom element to add to options page +void AsyncWiFiManager::setCustomOptionsElement(const char* element) { + _customOptionsElement = element; +} + +//if this is true, remove duplicated Access Points - defaut true +void AsyncWiFiManager::setRemoveDuplicateAPs(boolean removeDuplicates) { + _removeDuplicateAPs = removeDuplicates; +} + + + +template +void AsyncWiFiManager::DEBUG_WM(Generic text) { + if (_debug) { + Serial.print("*WM: "); + Serial.println(text); + } +} + +int AsyncWiFiManager::getRSSIasQuality(int RSSI) { + int quality = 0; + + if (RSSI <= -100) { + quality = 0; + } else if (RSSI >= -50) { + quality = 100; + } else { + quality = 2 * (RSSI + 100); + } + return quality; +} + +/** Is this an IP? */ +boolean AsyncWiFiManager::isIp(String str) { + for (int i = 0; i < str.length(); i++) { + int c = str.charAt(i); + if (c != '.' && (c < '0' || c > '9')) { + return false; + } + } + return true; +} + +/** IP to String? */ +String AsyncWiFiManager::toStringIp(IPAddress ip) { + String res = ""; + for (int i = 0; i < 3; i++) { + res += String((ip >> (8 * i)) & 0xFF) + "."; + } + res += String(((ip >> 8 * 3)) & 0xFF); + return res; +} diff --git a/examples/SmartSwitch/ESPAsyncWiFiManager.h b/examples/SmartSwitch/ESPAsyncWiFiManager.h new file mode 100644 index 000000000..f6e2e5b7e --- /dev/null +++ b/examples/SmartSwitch/ESPAsyncWiFiManager.h @@ -0,0 +1,279 @@ +/************************************************************** + WiFiManager is a library for the ESP8266/Arduino platform + (https://github.com/esp8266/Arduino) to enable easy + configuration and reconfiguration of WiFi credentials using a Captive Portal + inspired by: + http://www.esp8266.com/viewtopic.php?f=29&t=2520 + https://github.com/chriscook8/esp-arduino-apboot + https://github.com/esp8266/Arduino/tree/esp8266/hardware/esp8266com/esp8266/libraries/DNSServer/examples/CaptivePortalAdvanced + Built by AlexT https://github.com/tzapu + Ported to Async Web Server by https://github.com/alanswx + Licensed under MIT license + **************************************************************/ + +#ifndef ESPAsyncWiFiManager_h +#define ESPAsyncWiFiManager_h + +#if defined(ESP8266) +#include //https://github.com/esp8266/Arduino +#else +#include +#include "esp_wps.h" +#define ESP_WPS_MODE WPS_TYPE_PBC +#endif +#include + +//#define USE_EADNS //Uncomment to use ESPAsyncDNSServer +#ifdef USE_EADNS +#include //https://github.com/devyte/ESPAsyncDNSServer + //https://github.com/me-no-dev/ESPAsyncUDP +#else +#include +#endif +#include + +// fix crash on ESP32 (see https://github.com/alanswx/ESPAsyncWiFiManager/issues/44) +#if defined(ESP8266) +typedef int wifi_ssid_count_t; +#else +typedef int16_t wifi_ssid_count_t; +#endif + +#if defined(ESP8266) +extern "C" { + #include "user_interface.h" +} +#else +#include +#endif + +const char WFM_HTTP_HEAD[] PROGMEM = "{v}"; +const char HTTP_STYLE[] PROGMEM = ""; +const char HTTP_SCRIPT[] PROGMEM = ""; +const char HTTP_HEAD_END[] PROGMEM = "
"; +const char HTTP_PORTAL_OPTIONS[] PROGMEM = "



"; +const char HTTP_ITEM[] PROGMEM = "
{v} {r}%
"; +const char HTTP_FORM_START[] PROGMEM = "


"; +const char HTTP_FORM_PARAM[] PROGMEM = "
"; +const char HTTP_FORM_END[] PROGMEM = "
"; +const char HTTP_SCAN_LINK[] PROGMEM = "
"; +const char HTTP_SAVED[] PROGMEM = "
Credentials Saved
Trying to connect ESP to network.
If it fails reconnect to AP to try again
"; +const char HTTP_END[] PROGMEM = "
"; + +#define WIFI_MANAGER_MAX_PARAMS 10 + +class AsyncWiFiManagerParameter { +public: + AsyncWiFiManagerParameter(const char *custom); + AsyncWiFiManagerParameter(const char *id, const char *placeholder, const char *defaultValue, int length); + AsyncWiFiManagerParameter(const char *id, const char *placeholder, const char *defaultValue, int length, const char *custom); + + const char *getID(); + const char *getValue(); + const char *getPlaceholder(); + int getValueLength(); + const char *getCustomHTML(); +private: + const char *_id; + const char *_placeholder; + char *_value; + int _length; + const char *_customHTML; + + void init(const char *id, const char *placeholder, const char *defaultValue, int length, const char *custom); + + friend class AsyncWiFiManager; +}; + + +class WiFiResult +{ +public: + bool duplicate; + String SSID; + uint8_t encryptionType; + int32_t RSSI; + uint8_t* BSSID; + int32_t channel; + bool isHidden; + + WiFiResult() + { + } + + +}; + +class AsyncWiFiManager +{ +public: + #ifdef USE_EADNS + AsyncWiFiManager(AsyncWebServer * server, AsyncDNSServer *dns); + #else + AsyncWiFiManager(AsyncWebServer * server, DNSServer *dns); + #endif + + void scan(); + String scanModal(); + void loop(); + void safeLoop(); + void criticalLoop(); + String infoAsString(); + + boolean autoConnect(unsigned long maxConnectRetries = 1, unsigned long retryDelayMs = 1000); + boolean autoConnect(char const *apName, char const *apPassword = NULL, unsigned long maxConnectRetries = 1, unsigned long retryDelayMs = 1000); + + //if you want to always start the config portal, without trying to connect first + boolean startConfigPortal(char const *apName, char const *apPassword = NULL); + void startConfigPortalModeless(char const *apName, char const *apPassword); + + // get the AP name of the config portal, so it can be used in the callback + String getConfigPortalSSID(); + + void resetSettings(); + + //sets timeout before webserver loop ends and exits even if there has been no setup. + //usefully for devices that failed to connect at some point and got stuck in a webserver loop + //in seconds setConfigPortalTimeout is a new name for setTimeout + void setConfigPortalTimeout(unsigned long seconds); + void setTimeout(unsigned long seconds); + + //sets timeout for which to attempt connecting, usefull if you get a lot of failed connects + void setConnectTimeout(unsigned long seconds); + + //wether or not the wifi manager tries to connect to configured access point even when + //configuration portal (ESP as access point) is running [default true/on] + void setTryConnectDuringConfigPortal(boolean v); + + + void setDebugOutput(boolean debug); + //defaults to not showing anything under 8% signal quality if called + void setMinimumSignalQuality(int quality = 8); + //sets a custom ip /gateway /subnet configuration + void setAPStaticIPConfig(IPAddress ip, IPAddress gw, IPAddress sn); + //sets config for a static IP + void setSTAStaticIPConfig(IPAddress ip, IPAddress gw, IPAddress sn, IPAddress dns1=(uint32_t)0x00000000, IPAddress dns2=(uint32_t)0x00000000); + //called when AP mode and config portal is started + void setAPCallback( void (*func)(AsyncWiFiManager*) ); + //called when settings have been changed and connection was successful + void setSaveConfigCallback( void (*func)(void) ); + //adds a custom parameter + void addParameter(AsyncWiFiManagerParameter *p); + //if this is set, it will exit after config, even if connection is unsucessful. + void setBreakAfterConfig(boolean shouldBreak); + //if this is set, try WPS setup when starting (this will delay config portal for up to 2 mins) + //TODO + //if this is set, customise style + void setCustomHeadElement(const char* element); + //if this is true, remove duplicated Access Points - defaut true + void setRemoveDuplicateAPs(boolean removeDuplicates); + //sets a custom element to add to options page + void setCustomOptionsElement(const char* element); + +private: + AsyncWebServer *server; + #ifdef USE_EADNS + AsyncDNSServer *dnsServer; + #else + DNSServer *dnsServer; + #endif + + + boolean _modeless; + int scannow; + int shouldscan; + boolean needInfo = true; + + //const int WM_DONE = 0; + //const int WM_WAIT = 10; + + //const String HTTP_HEAD = "{v}"; + + void setupConfigPortal(); +#ifdef NO_EXTRA_4K_HEAP + void startWPS(); +#endif + String pager; + wl_status_t wifiStatus; + const char* _apName = "no-net"; + const char* _apPassword = NULL; + String _ssid = ""; + String _pass = ""; + unsigned long _configPortalTimeout = 0; + unsigned long _connectTimeout = 0; + unsigned long _configPortalStart = 0; + + IPAddress _ap_static_ip; + IPAddress _ap_static_gw; + IPAddress _ap_static_sn; + IPAddress _sta_static_ip; + IPAddress _sta_static_gw; + IPAddress _sta_static_sn; + IPAddress _sta_static_dns1= (uint32_t)0x00000000; + IPAddress _sta_static_dns2= (uint32_t)0x00000000; + + int _paramsCount = 0; + int _minimumQuality = -1; + boolean _removeDuplicateAPs = true; + boolean _shouldBreakAfterConfig = false; +#ifdef NO_EXTRA_4K_HEAP + boolean _tryWPS = false; +#endif + const char* _customHeadElement = ""; + const char* _customOptionsElement = ""; + + //String getEEPROMString(int start, int len); + //void setEEPROMString(int start, int len, String string); + + int status = WL_IDLE_STATUS; + int connectWifi(String ssid, String pass); + uint8_t waitForConnectResult(); + void setInfo(); + + String networkListAsString(); + + void handleRoot(AsyncWebServerRequest *); + void handleWifi(AsyncWebServerRequest*,boolean scan); + void handleWifiSave(AsyncWebServerRequest*); + void handleInfo(AsyncWebServerRequest*); + void handleReset(AsyncWebServerRequest*); + void handleNotFound(AsyncWebServerRequest*); + void handle204(AsyncWebServerRequest*); + boolean captivePortal(AsyncWebServerRequest*); + + // DNS server + const byte DNS_PORT = 53; + + //helpers + int getRSSIasQuality(int RSSI); + boolean isIp(String str); + String toStringIp(IPAddress ip); + + boolean connect; + boolean _debug = true; + + WiFiResult *wifiSSIDs; + wifi_ssid_count_t wifiSSIDCount; + boolean wifiSSIDscan; + + boolean _tryConnectDuringConfigPortal = true; + + void (*_apcallback)(AsyncWiFiManager*) = NULL; + void (*_savecallback)(void) = NULL; + + AsyncWiFiManagerParameter* _params[WIFI_MANAGER_MAX_PARAMS]; + + template + void DEBUG_WM(Generic text); + + template + auto optionalIPFromString(T *obj, const char *s) -> decltype( obj->fromString(s) ) { + return obj->fromString(s); + } + auto optionalIPFromString(...) -> bool { + DEBUG_WM("NO fromString METHOD ON IPAddress, you need ESP8266 core 2.1.0 or newer for Custom IP configuration to work."); + return false; + } +}; + +#endif diff --git a/examples/SmartSwitch/PinOut_Notes.txt b/examples/SmartSwitch/PinOut_Notes.txt new file mode 100644 index 000000000..c8c2a50a9 --- /dev/null +++ b/examples/SmartSwitch/PinOut_Notes.txt @@ -0,0 +1,13 @@ +ESP12 + +static const uint8_t D0 = 16; +static const uint8_t D1 = 5; +static const uint8_t D2 = 4; // DHT DATA I/O +static const uint8_t D3 = 0; // BUTTON - most modules have it populated on PCB +static const uint8_t D4 = 2; // LED (RELAY) - most modules have it populated on PCB +static const uint8_t D5 = 14; +static const uint8_t D6 = 12; +static const uint8_t D7 = 13; +static const uint8_t D8 = 15; +static const uint8_t D9 = 3; +static const uint8_t D10 = 1; \ No newline at end of file diff --git a/examples/SmartSwitch/SmartSwitch.ino b/examples/SmartSwitch/SmartSwitch.ino new file mode 100644 index 000000000..22d9998ee --- /dev/null +++ b/examples/SmartSwitch/SmartSwitch.ino @@ -0,0 +1,479 @@ +/* +SmartSwitch application +Based on ESP_AsyncFSBrowser +Temperature Control for heater with schedule +Main purpose - for winter outside car block heater or battery charger +Wide browser compatibility, no other server-side needed. +HTTP server and WebSocket, single port +Standalone, no JS dependencies for the browser from Internet (I hope) +Based on ESP_AsyncFSBrowser +Real Time (NTP) w/ Time Zones +Memorized settings to EEPROM +Multiple clients can be connected at same time, they see each other requests +Use latest ESP core lib (from github) +*/ + +#define USE_WFM // to use ESPAsyncWiFiManager + +#include +#ifdef ESP32 + #include + #include + #include + #include + #include +#elif defined(ESP8266) + #include + #include + #include +#endif +#include +#ifdef USE_WFM + #include "ESPAsyncWiFiManager.h" +#endif +#include +#include +#include +#include +#include +#define MYTZ TZ_America_Toronto +#define RTC_UTC_TEST 1577836800 // Some Date + +#define EESC 100 // fixed eeprom address for sched choice +#define EECH 104 // fixed eeprom address to keep selected active channel, only for reference here +#define EEBEGIN EECH + 1 +#define EEMARK 0x5A +#define MEMMAX 1 // 0,1,2... last max index (only 2 channels) +#define EEALL 512 + +#define HYST 0.5 // C +/- hysteresis + +// DHT +#define DHTTYPE DHT22 // DHT 11 // DHT 22, AM2302, AM2321 // DHT 21, AM2301 +#define DHTPIN 4 //D2 + +DHT dht(DHTPIN, DHTTYPE); + +// SKETCH BEGIN MAIN DECLARATIONS +Ticker tim; +AsyncWebServer server(80); //single port - easy for forwarding +AsyncWebSocket ws("/ws"); + +#ifdef USE_WFM + DNSServer dns; +#else + const char* ssid = "MYSSD"; + const char* password = "MYPASSWD"; +#endif +const char * hostName = "smartsw"; +const char* http_username = "smart"; // for SPIFFSEditor (and static html) +const char* http_password = "switch"; + +// RTC +static timeval tv; +static time_t now; + +// HW I/O +const int btnPin = 0; //D3 +const int ledPin = 2; //D4 +int btnState = HIGH; + +// Globals +uint8_t count = 0; +uint8_t sched = 0; // automatic schedule +byte memch = 0; // select memory "channel" to work with +float t = 0; +float h = 0; +bool udht = false; +bool heat_enabled_prev = false; +int ledState; + +struct EE_bl { + byte memid; //here goes the EEMARK stamp + uint8_t hstart; + uint8_t mstart; + uint8_t hstop; + uint8_t mstop; + float tempe; +}; + +EE_bl ee = {0,0,0,0,0,0.1}; //populate as initial + +// SUBS +void writeEE() { + ee.memid = EEMARK; + //EEPROM.put(EESC, sched); // only separately when needed with commit() + //EEPROM.put(EECH, memch); // not need to store and retrieve memch + EEPROM.put(EEBEGIN + memch*sizeof(ee), ee); + EEPROM.commit(); //needed for ESP8266? +} + +void readEE() { + byte ChkEE; + if (memch > MEMMAX) memch = 0; + EEPROM.get(EEBEGIN + memch*sizeof(ee), ChkEE); + if (ChkEE == EEMARK){ //otherwise stays with defaults + EEPROM.get(EEBEGIN + memch*sizeof(ee), ee); + EEPROM.get(EESC, sched); + if (sched > MEMMAX + 1) sched = 0; + } +} + +void showTime() +{ + byte tmpch = 0; + bool heat_enabled = false; + + gettimeofday(&tv, nullptr); + now = time(nullptr); + const tm* tm = localtime(&now); + ws.printfAll("Now,Clock,%02d:%02d,%d", tm->tm_hour, tm->tm_min, tm->tm_wday); + if ((2==tm->tm_hour )&&(2==tm->tm_min)) { + configTime(MYTZ, "pool.ntp.org"); + Serial.print(F("Sync Clock at 02:02\n")); + } + Serial.printf("RTC: %02d:%02d\n", tm->tm_hour, tm->tm_min); + + if (sched == 0) { // automatic + if ((tm->tm_wday > 0)&&(tm->tm_wday < 6)) tmpch = 0; //weekdays + else tmpch = 0; //weekend + } else { // manual + tmpch = sched - 1; //and stays + } + + if (tmpch != memch) { // update if different + memch = tmpch; + readEE(); + ws.printfAll("Now,Setting,%02d:%02d,%02d:%02d,%+2.1f", ee.hstart, ee.mstart, ee.hstop, ee.mstop, ee.tempe); + } + + // process smart switch by time and temperature + uint16_t xmi = (uint16_t)(60*tm->tm_hour) + tm->tm_min; // max 24h = 1440min, current time + uint16_t bmi = (uint16_t)(60*ee.hstart) + ee.mstart; // begin in minutes + uint16_t emi = (uint16_t)(60*ee.hstop) + ee.mstop; // end in minutes + + if (bmi == emi) heat_enabled = false; + else { //enable smart if different + + if (((bmi < emi)&&(bmi <= xmi)&&(xmi < emi))|| + ((emi < bmi)&&((bmi <= xmi)||(xmi < emi)))) { + heat_enabled = true; + } else heat_enabled = false; + } + + if (heat_enabled_prev) { // smart control (delayed one cycle) + if (((t - HYST) < ee.tempe)&&(ledState == HIGH)) { // OFF->ON once + ledState = LOW; + digitalWrite(ledPin, ledState); // apply change + ws.textAll("led,ledon"); + } + if ((((t + HYST) > ee.tempe)&&(ledState == LOW))||(!heat_enabled)) { // ON->OFF once, also turn off at end of period. + ledState = HIGH; + digitalWrite(ledPin, ledState); // apply change + ws.textAll("led,ledoff"); + } + Serial.printf(ledState ? "LED OFF" : "LED ON"); + Serial.print(F(", Smart enabled\n")); + } + heat_enabled_prev = heat_enabled; //update +} + +void updateDHT(){ + h = dht.readHumidity(); + t = dht.readTemperature(); //Celsius or dht.readTemperature(true) for Fahrenheit + if (isnan(h) || isnan(t)) { + Serial.print(F("Failed to read from DHT sensor!")); + h = 0; // debug w/o sensor + t = 0; + } +} + +void analogSample() +{ + ws.printfAll("wpMeter,Arduino,%+2.1f,%2.1f,%d", t, h, heat_enabled_prev); + Serial.printf("T/H.: %+2.1f°C/%2.1f%%,%d\n", t, h, heat_enabled_prev); +} + +void checkPhysicalButton() +{ + if (digitalRead(btnPin) == LOW) { + if (btnState != LOW) { // btnState is used to avoid sequential toggles + ledState = !ledState; + digitalWrite(ledPin, ledState); + if (ledState) ws.textAll("led,ledoff"); + else ws.textAll("led,ledon"); + } + btnState = LOW; + } else { + btnState = HIGH; + } +} + +void mytimer() { + ++count; //200ms increments + checkPhysicalButton(); + if ((count % 25) == 1) { // update temp every 5 seconds + analogSample(); + udht = true; + } + if ((count % 50) == 0) { // update temp every 10 seconds + ws.cleanupClients(); + } + if (count >= 150) { // cycle every 30 sec + showTime(); + count = 0; + } +} + +// server +void onWsEvent(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventType type, void * arg, uint8_t *data, size_t len){ + if(type == WS_EVT_CONNECT){ + Serial.printf("ws[%s][%u] connect\n", server->url(), client->id()); + //client->printf("Hello Client %u :)", client->id()); + //client->ping(); + + IPAddress ip = client->remoteIP(); + Serial.printf("[%u] Connected from %d.%d.%d.%d\n", client->id(), ip[0], ip[1], ip[2], ip[3]); + showTime(); + analogSample(); + if (ledState) ws.textAll("led,ledoff"); + else ws.textAll("led,ledon"); + + ws.printfAll("Now,Setting,%02d:%02d,%02d:%02d,%+2.1f", ee.hstart, ee.mstart, ee.hstop, ee.mstop, ee.tempe); + ws.printfAll("Now,sched,%d", sched); + + } else if(type == WS_EVT_DISCONNECT){ + Serial.printf("ws[%s][%u] disconnect\n", server->url(), client->id()); + ws.textAll("Now,remoff"); + + } else if(type == WS_EVT_ERROR){ + Serial.printf("ws[%s][%u] error(%u): %s\n", server->url(), client->id(), *((uint16_t*)arg), (char*)data); + } else if(type == WS_EVT_PONG){ + Serial.printf("ws[%s][%u] pong[%u]: %s\n", server->url(), client->id(), len, (len)?(char*)data:""); + } else if(type == WS_EVT_DATA){ + AwsFrameInfo * info = (AwsFrameInfo*)arg; + String msg = ""; + if(info->final && info->index == 0 && info->len == len){ + //the whole message is in a single frame and we got all of it's data + Serial.printf("ws[%s][%u] %s-message[%llu]: ", server->url(), client->id(), (info->opcode == WS_TEXT)?"text":"binary", info->len); + + if(info->opcode == WS_TEXT){ + for(size_t i=0; i < info->len; i++) { //debug + msg += (char) data[i]; + } + if(data[0] == 'L') { // LED + if(data[1] == '1') { + ledState = LOW; + ws.textAll("led,ledon"); // for others + } + else if(data[1] == '0') { + ledState = HIGH; + ws.textAll("led,ledoff"); + } + digitalWrite(ledPin, ledState); // apply change + + + } else if(data[0] == 'T') { // timeset + if (len > 11) { + data[3] = data[6] = data[9] = data[12] = 0; // cut strings + ee.hstart = (uint8_t) atoi((const char *) &data[1]); + ee.mstart = (uint8_t) atoi((const char *) &data[4]); + ee.hstop = (uint8_t) atoi((const char *) &data[7]); + ee.mstop = (uint8_t) atoi((const char *) &data[10]); + Serial.printf("[%u] Timer set %02d:%02d - %02d:%02d\n", client->id(), ee.hstart, ee.mstart, ee.hstop, ee.mstop); + writeEE(); + memch = 255; // to force showTime()to send Setting + showTime(); + } + } else if(data[0] == 'W') { // temperatureset + if (len > 3) { + if (ee.tempe != (float) atof((const char *) &data[1])){ + ee.tempe = (float) atof((const char *) &data[1]); + Serial.printf("[%u] Temp set %+2.1f\n", client->id(), ee.tempe); + writeEE(); + memch = 255; // to force showTime()to send Setting + showTime(); + } + } + } else if ((data[0] == 'Z')&&(len > 2)) { // sched + data[2] = 0; + if (sched != (uint8_t) atoi((const char *) &data[1])){ + sched = (uint8_t) atoi((const char *) &data[1]); + EEPROM.put(EESC, sched); //separately + EEPROM.commit(); //needed for ESP8266? + ws.printfAll("Now,sched,%d", sched); + showTime(); + } + } + + } else { + char buff[3]; + for(size_t i=0; i < info->len; i++) { + sprintf(buff, "%02x ", (uint8_t) data[i]); + msg += buff ; + } + } + Serial.printf("%s\n",msg.c_str()); + + if(info->opcode == WS_TEXT) + client->text("I got your text message"); + else + client->binary("I got your binary message"); + + } else { + //message is comprised of multiple frames or the frame is split into multiple packets + if(info->index == 0){ + if(info->num == 0) + Serial.printf("ws[%s][%u] %s-message start\n", server->url(), client->id(), (info->message_opcode == WS_TEXT)?"text":"binary"); + Serial.printf("ws[%s][%u] frame[%u] start[%llu]\n", server->url(), client->id(), info->num, info->len); + } + + Serial.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 < len; i++) { + msg += (char) data[i]; + } + } else { + char buff[3]; + for(size_t i=0; i < len; i++) { + sprintf(buff, "%02x ", (uint8_t) data[i]); + msg += buff ; + } + } + Serial.printf("%s\n",msg.c_str()); + + if((info->index + len) == info->len){ + Serial.printf("ws[%s][%u] frame[%u] end[%llu]\n", server->url(), client->id(), info->num, info->len); + if(info->final){ + Serial.printf("ws[%s][%u] %s-message end\n", server->url(), client->id(), (info->message_opcode == WS_TEXT)?"text":"binary"); + if(info->message_opcode == WS_TEXT) + client->text("I got your text message"); + else + client->binary("I got your binary message"); + } + } + } + } +} + + +// setup ----------------------------------- + +void setup(){ + Serial.begin(115200); + Serial.setDebugOutput(true); + +//Wifi +#ifdef USE_WFM + AsyncWiFiManager wifiManager(&server,&dns); + //wifiManager.resetSettings(); + wifiManager.autoConnect("SmartSW"); +#else + //WiFi.mode(WIFI_AP_STA); // Core SVN 5179 use STA as default interface in mDNS (#7042) + //WiFi.softAP(hostName); // Core SVN 5179 use STA as default interface in mDNS (#7042) + WiFi.mode(WIFI_STA); // Core SVN 5179 use STA as default interface in mDNS (#7042) + WiFi.begin(ssid, password); + if (WiFi.waitForConnectResult() != WL_CONNECTED) { + Serial.print(F("STA: Failed!\n")); + WiFi.disconnect(false); + delay(1000); + WiFi.begin(ssid, password); + } +#endif + + Serial.print(F("*CONNECTED*\n")); + +//DHT + dht.begin(); + updateDHT(); //first reading takes time, hold here than the loop; + +//Real Time + time_t rtc = RTC_UTC_TEST; + timeval tv = { rtc, 0 }; + //timezone tz = { 0, 0 }; //(insert) <#5194 + settimeofday(&tv, nullptr); //settimeofday(&tv, &tz); // <#5194 + configTime(MYTZ, "pool.ntp.org"); + +//MDNS (not needed) + // MDNS.begin(hostName); + // MDNS.addService("http","tcp",80); // Core SVN 5179 use STA as default interface in mDNS (#7042) + +//I/O & DHT + pinMode(ledPin, OUTPUT); + pinMode(btnPin, INPUT_PULLUP); + +//EE + EEPROM.begin(EEALL); + //EEPROM.get(EECH, memch); //current channel, no need + readEE(); // populate structure if healthy + digitalWrite(ledPin, ledState); + Serial.printf("Timer set %02d:%02d - %02d:%02d\n", ee.hstart, ee.mstart, ee.hstop, ee.mstop); + Serial.printf("Temp set %+2.1f\n", ee.tempe); + +//SPIFFS + SPIFFS.begin(); + + ws.onEvent(onWsEvent); + server.addHandler(&ws); + +#ifdef ESP32 + server.addHandler(new SPIFFSEditor(SPIFFS, http_username,http_password)); +#elif defined(ESP8266) + server.addHandler(new SPIFFSEditor(http_username,http_password)); +#endif + + server.on("/free-ram", HTTP_GET, [](AsyncWebServerRequest *request){ // direct request->answer + request->send(200, "text/plain", String(ESP.getFreeHeap())); + }); + + server.on("/hw-reset", HTTP_GET, [](AsyncWebServerRequest *request){ + request->onDisconnect([]() { +#ifdef ESP32 + ESP.restart(); +#elif defined(ESP8266) + ESP.reset(); +#endif + }); + request->send(200, "text/plain","Restarting ..."); + }); + + server.on("/erase-wifi", HTTP_GET, [](AsyncWebServerRequest *request){ + request->onDisconnect([]() { + WiFi.disconnect(true); + }); + request->send(200, "text/plain","Erasing WiFi data ..."); + }); + + server.serveStatic("/", SPIFFS, "/").setDefaultFile("index.htm"); //.setAuthentication(http_username,http_password); //append or remove auth part + + + server.onNotFound([](AsyncWebServerRequest *request){ // nothing known + Serial.print(F("NOT_FOUND: ")); + if (request->method() == HTTP_OPTIONS) request->send(200); //CORS + else request->send(404); + }); + + DefaultHeaders::Instance().addHeader("Access-Control-Allow-Origin", "*");//CORS + server.begin(); + + //Timer tick + tim.attach(0.2, mytimer); //every 0.2s + + //OTA + ArduinoOTA.setHostname(hostName); + ArduinoOTA.onStart([]() { + Serial.print(F("OTA Started ...\n")); + ws.textAll("Now,OTA"); // for all clients + }); + ArduinoOTA.begin(); +} // setup end + +// loop ----------------------------------- +void loop(){ + if (udht){ // 5sec + updateDHT(); + udht = false; + } + ArduinoOTA.handle(); +} diff --git a/examples/SmartSwitch/data/.exclude.files b/examples/SmartSwitch/data/.exclude.files new file mode 100644 index 000000000..4aacf0d7a --- /dev/null +++ b/examples/SmartSwitch/data/.exclude.files @@ -0,0 +1,2 @@ +/*.gz +/.exclude.files diff --git a/examples/SmartSwitch/data/acefull.js.gz b/examples/SmartSwitch/data/acefull.js.gz new file mode 100644 index 0000000000000000000000000000000000000000..e10ad62d2aa6c854fa9364434369bc33ec30f5a3 GIT binary patch literal 111691 zcmV(-K-|9{iwFq*S-)HY0AXWgW_4_AE^2cC+*?_4Gc^#tiak(a2FpvJpumoB{p=KL z5h$o~3^lP8TQDA(89Dg_c2(Gy2M)js+<-f96T(IKTGDKuF)7vuUgFW#-TKt(mRcSE zViV7_RIwj?av3Hq!Alj1(3>P~>7`6}elTi_qa$w<&&7p|#oTLieZ3ayqID(Xxw<+! z@&&h_!H7tyf|OvI$>0+&)rpK39?wRKvHu9?VY1k)M6Aqv!jDsx$B=J6(qf?%k6Dv=8rhtatB?1k%fbnVkLSk5aL`ZE=$DiS@B zBr5T}d7{>9h}W`YTjydHZc@>*^KD&)Y5b6Gg)KXYo)@r;fKI}h@PlAC%4Oo8>{uZ% zN(K_3z>*p)^1`nnqwR9Ud`7*35&F;++dK~3s>q`w=?5&{i3maxjfpz{K+JUOUXp~@ zQ_$kCn~L5#QCfj8Bvq$Y`dJu7z7B#4(9tB&u5k8phIKyKN74I~G;2uzV!PT6oON+KsooWSQ4E zx@&pmj)hh71a$Yf%`rgn%ARr_)7a5hl7xdCdLNNxcdmQvWP%<{P9sKF&(Y_>5sH3A8n`-2i9$y+A z60wd*z4~YUv))<1&xl4*J9+P{KkZPPYxQ#2^^VQT2#~7r(0o{J z<@$(;721r>fs>Kc9NI1CL&-LY9MZzwU#mo?!xh1 z$6})xY0pt$W$Ad#<{}bWv?_A!G_UsBZgnyJk>r9wbPq@oy1tlbSQ7IC$pa=ied4!g zH#zjwef2Wo(Y>%FJZsKJaK&mvczZx36Y-|#7JcO#MI2%aW4u}{Ss}rU=$r4g;<29DVDd4)p7tuy6G4bC@ZWqF2rXe%Pnt$V!lQ^LgfSqp)gPA^rP1S^qbYhv;90V*{Iy+x$XVS2rVH^lIcANS-U zR*85fOvTufdF^TwX&K2Fm8+~0*l7Xz=VR}FUYBY)`|x_~U7H#P!X#I)FM)7|G_?p| za}|1Acrd|_N8)7vFwuQvB!EY*J$XA$4FG_CoN5I-a5gx+f8Xw=qoYa@!mI(Hcr9Fs zG|1R0uvPimjue=|kHU6|6SymQd6xu1Ajw5NC3hjN$!LVQ7?PiuQ zg=d9!H}2B9c9%DlRcn#^KfN!P{sX!6A-Pz)tpVZ{Wv2MDQt3PeKvT{p73wC+Q z%uFZOnS-&1AjkF%9P&h>uR+60p$4dmJO*D-DoX6N-HfajQQ8%hQ5c3wMEaRD4twSx(aU%9Q z?&J{j3#%^qZeqs)OADEdJtKKQAk|?!BO%i4iXqE3H16RT4Yd7zk^p8@SwdjNIUzoz zftj-B#Qu=dE+Zw2xngxxQR1Z*mX_)XGsQ|h?PY_dI}1j_LKd+ZTe1zW18PKJbG~QX z*`jthXBT{K4INwYjadkPk)PNDwk|4{Vfy-2oawT0KK_!g{RQ*hf8Q$l3qos=y#Kxz zkgZ9IvHKmcDeH}=d1F*=gzA2{Sr;Q`^~QW;z#eJy$uWCm3LkFI!GW_JnvWWqF58a_1$+gP~w~QIFA{ zJ34HO>7gCK9>E?MPNqA1TfAGgvQf!>8w}Z4o(N;rWH2<>GG_tBi8Xe{uC2oRzU&A_ z@QaQr@tijuXgCL3<@^iXG0Q073`TP^Vkb@x3G2wf zmvmfo5-4-nQQd^iAWX=X_?r;n=p@YD`GyZho0A#ty_!%D3!OPdzmlmBS;Mjh=dK zGu#UM`v7_9cFAzWsDtD!QxNP z8`joq!E48gB3=18qPT4&P{ZT|R|y<*6Nd{A=J3LvqNNjPX_LuMt+ zR0C$>QY5sk8|(i~{rZ=oQh-W9sg%9ADyLU%2U7}_Qd6d&Qknlf9_5a>4pXXD0w^_A z|NlTbjL~3}fz^OfBIcVJq14#$FXHsi0Yh<>7;%;Q148p<$Ih%pahcUxU$;VK{s|rFc1t?a z?W&W(KP9Qt6JkdA-=QK5l8ow#Qjbeg7?bnKfE`b>Dj(Oq0LpV8=<9V>pjb8Xgy8p8Dl=!JN_mgvaA}nBQLpOm^Y`VO5#MQ?XPwAZFvLq8?YR zV`ZaYHN48z;M9GTKx-WO-vcM{br`zhVimJJ6w5HmZXVzQh*UX>yWKL10uU0CjVQX% z$U^8hGB{qp07Q-T4fmRsKs>@A`TqMDCg@t6>SQz1Dj8Qw1>VC&0M6}#MJdAatVm~x zT%&*R$sHZ)PmZ2lC9hq27HA03!5P~NH5bhr{|?5bpj`+f5O*!xA)6rY#1v8#6!fzQ>KWT*p65`z+xd;Nr+_*r|3PDua=6|fit7}$g}TjPeYK#icx6I- z^#}CQoW`|0iBIx26B*glnPSZXR0Zq^_%M5NsJGs~k^`TPx0c^^Ddw zJ{H)S-{-MU4+S6cA_=B=>zk{YF@@O0zWdHld@d4HLWYUF^a6V}xsL$KhXIj&hBxxu zQLo09?e>}Alg5@>X30Nmed-Jgn^U(qO}u3zZ<+I!&AfAVb7$=&7_K&{MvhJ^j9Ud? zY4|=9l%9W{u_qlXKeND;UU!UPl+1Hyr2u7ebk?A4x7MBociO=$JHZ$%v#Fg4W94ox zS*P5dZ=Uvnlj*_))YH~cE45z$o!~Z;cWOurU|w532rokmQ41~`P1ry*J)%MnzKPWg zvXlWc4XJGiT?2}F{)pJ^nzsy@+ygCp79+EE(s=z~?Slun9eR?JOjB}6ZVL*jlg`?!2H?n6J1lc>>8+#+Ofe_%ZPZX}v0a4zFl1_9bcW<}xDTcCpeBxy;(PLiK zU82JINPJa2Fe)mp7Ud?7jOvmf_onO>e$O4F^O?PgP4P)4gFQ0@knMO>lDLH1zhTaa z#esvPbG@3L*DBjs1OVJ@V{N0B*65xFMMerm!(PGNDW$uU1zqubIPIH-RK-wLN>bc9`ZN)04#LlEe){8YH#cXSM+T2PVg5dO zwz&`&7oPFewVWiBSKICT=9k_9!5BxF_i=WyIaJSa64GVXc<-T!8Xxuo_Ex#Y);*J^1YcO|WXbuSwoFe>FkQEtjtcIPn!nB7+;%(YUN z;*f``^=FX=<6QXjZhF=JZFmjnA47$zY7nwo=qwIY-1nWc>8cJTrJ0r&w; z5-u?C@1+7#`bO{dQ~t>-FTM8myF<_XcqzSHszuNcM;ZRlFkO&3#*CnV3&UZpWOZE8J!rUdlxXYnmO#{Jf?I-PbTbE1PWS z_gCR;i(K?=L_GQu2f2x-^iseQ2b94?=Ke|~l(^>8<8wiY@ViI&jY!6KWXwGff)p`x zv)~@6y9zf8?iogT!nzWBo?}bO&_TQLhyniz5mip6*+t-_1Ypm z_|?;U>-CE&#a0|cGg9$AJ)!Lv>*Z>p+aE6EI{$+{=jMt+%@UXBzwaxFzlcwnfG5b()gRA;jMp4Lfwk^|! zyykhQ@938^d^PW(n1gJ&DFU;wHH`Tdn26h^^mA?t@q-2qU3%D zSBpNyRIqI;oiL5$_0v|y1^Q(!H^RW=A0DYt1% zPPARX`3GD^MB(=vNKr7AqQUP%}hqvK5G9zHIz9xMEpPm!|-A=lY+&TNPL|g9o6hK z>h@+bqZG6yf5bj!CVaUsof9i!agNd>oZ}u|I;Mh3mOSFu!{IaJ@s7M1V&zk25^-UP#}o>uJ4j@+pxP8(is3h`b zk$kA%)l%#Au;0JBy6Rm$+EdA*fBfW=PxkLG^(yk1 z2!_q0F;$3FKHVgHS50z&u}EHg>(y7d=b`i7wrZS&ud%@D3ga?>bN<2Jch5lLE=`VsJ?cY!g=ko&; zE8JZCszRDW;XAs7x$Ar|YQsyTt3r+P|5B2Le8zgxBUc=lm&{R~SQ#Tfcvm9EWw8TE z9IY0M=x>O_VmO#grnFI})X9XN$1E2tg5cNs~_T)XcJGtl_fJ3?)lNqMsH3T=)tV7cxn;p&nGBg#hVNh<&45 zoHYCiT_HaFowaM-YTO3GuTtEW#zhHn0=r;vb66JIoGyg}^s;3sHHlc%CU$B&-L@p} z-fwjARS=E?cjhtE0D_KWU>wJ)v9k1K{++ikjDk6o{>CXNtvhTTc1aW%ZO7>Xbvx29o zb32JgziS=KPCcGyM4cQ!RAoBViBmz02M!L7;|U-fMvi-TpwtFmiWmkGOcZw$ScjZ@ zF~-gWd4~I*hN&|i|xNWSYduatwm|=%C=k5+OgCx6G=2FQ=bw^Tz zGm2LbB+^e`VBQftQl(G~D|>%I-Wkb~J#_#DEY^>@ux4Y#(4`J^@0bRreG%2Sx@pKA zmVp7|I9OO7mU<$Txs6$a%&%D4guZkc2su!{Ik>nvytueI_-=S|a5+5v4s&rS`||wY zyNlz~^OFmmKfHN;HVoE;+KDd~Pu)KEI@|kZcR1#MVsbwdfAPtA2)3B5qUkU*#XWgy zw`aInU(b&eBR%S~B#ctBKA^Go#<Z7J36{K@dh_N^C~7+5m~Qqktm{q>vZ?Q(WYG5?lo5}!XPf=VWXA;N zrN2b<^eGvqo6H%0igPd~=##c8?h2(!Jl2cYKRw?Pi!OiGMPapfCg|GLFDjL_f`^mS z*TduC(fQ4{M{h6u2k(XNT-=L0tZLp%-#N^Z31U0Gb1*?xueSx`BF{o7`hdSdWz-n~ z$j59j$^0IRXG8;$l(6_)Ov=#TVN+B?fO%~iMq`Ri@w;Tl-+y;V-;ZVhq+a1Rbvi?1 z9k%N`m*Fiq==;vO>}tf3c^0Cv;0G)or6Y&+dth5t>G!GlJ^y}&_?C*lhGK)%HlU+1 zB533{@sxmp;0?w*VjwK506V$vA#1DaJF4au;lVUbnLsimt%Bk&06>RX#3|z6&2bTL z+(qK0Nq9)?m_!eWU6bfL3=5`7ZBfcIsclO2OzH)t`X=>~Qd=gqL#b_(+I1L~;l5+i zM`YIoga=&59!2_y^eD20NS`9xh!Ay>{4o(GxgQfv68kZc^L7y-O1&;3yA<&VVV7bO zwMVf&#R&P9VoxpF9`)FTTwi6zlAWCozq>qm_2x*6oP_rYdK2Wj2tW+zwn3_g0EGGo z0J4PuB(@O%{|f{_{1O2e-$4MjcM+iap2J?CUVs1~Ap(HhA^^w;0SJu|01|?G2|{-W zP~klS5V}VILIME@{e}Qoen$W-69m9AMF1=j0$_<9wgW6P1iu4+wzeF9g8yH%14r{6i8&;Rc1sZj%6z-$6)q_b5bpfRJi43N_rWhT8=j zn-qeNU-6lc0Iv{|{NBBz2mr1r1i%+WKv(F3z?aTaIYCJWDAB2Wpe_$;IagWTSTA6V zQAX4uS)_o~E#s?-9|+4?&&OysAbN5Yn1CyDnahfz5`{)ty@AN!^x1$dMS?QYQHYgC zMv%k-Hsb0S8@zch`_}>b-+tx&%E3ejDbXy60J9{1<>ZJtTrae<_(QA5%<}+H_{qUn zbj%b>>Y2HA)3R8hvh@-yzh0WBOxn1^kDn!aumsQrvrajq?IA}*&>-8$2lSrlos6X} zlg7P6Y`-qGo!+v2NkLXiq-h0}w`#PB{|=_?!}~Bf%(rtDQ9rsqO8<&yFOamFuC_SO z8>&cgU%k4wzSmZYwXw35!<4A*Pm}U}5|725;K@Z6X3z~SnK;b9AdTEs0`eLT@UfeBDi|CWXDr|g3{mgv>ekw(ZnPe>cbD2!vjzz+R8y-nipj0bL1594DBdqf zFm+678m_#{zBH!;PDhPymyH`oBW$9aL`QTJl}uc3M4Iu4TOYLI1aL$RGEl~*(=3rk zD{G$i8V<7zCVmOvJ~W&^g?75>za7(E9Hy;vg%fU^=Do9!m#JPd4z<^5D7!p9T!AHR`sEHa9+DuhrN=9_TMw z1Gs{b*GmVyf!y^udN>;K$*cJ-`E6n2(jZsGS}PpXGbB#cnjfT7x8f9&)vI}y#WvqE zXM8(>83g)VfTamDJzab!hpG&=x+%6?dH!ONPnx_#i{Q8XZ@M{1(}aoAa!83m&$lpp zE1AIF#P6~mb{1Q{x4bgh*WlE=-qIK=)fYz~Zz%_wX%IGsTJ9B0E6O~TWeyOnbyvgA zq5MUwAjkMn(=1Ff4QtHW`deMig$7*B0>D<&CsVnCy^QCh`;$k$x=1fBEUr!}C~`8Y zs8Kex0^X73oSw?rOM^@s&VFKX9)FAV-j0>p{UlPkAh*2yoU(W(j>y4U3ghhLryy;M zoUYD%8^n3$Tb2f*#8{CZDHkf;MJLq7KT>U5ACV#vM^X%+pkJsNG#XX_)LLfjO`1V$ zDzosXK`U=WyHc>ZleeT=@^*8_^^02FN5BBZGU?vxgX^alw(y#M5Yp4OGbU8fW{@`u z$!EIr`t;=H_0gNlgPXJAPe*V3oRLm{`%7Knr^TXRt6cCF1$*iMsDTdNM@N2>$ide~ z1&!@5TO|^1K?4OP67EvBywO%5mO_?$)mo!5Tm41%@>EE2`sVa}`12{&^EWpKKMgMi ztvVxFC?-`#x^~&rD;U|Bfk#hu5o6MdVHtet?X%KkmuY808c?NK9JvE%2EMm%s13IE zH#SC6=kr`2KWr?0f6S-0y5|T%^p+*|Qlqwqv+);Q^cz%C;w=es+AIuma_&;yV3Lba8jM(kCm&ks3mZ$L z4R_hr{>Vj>3ndn5J?BdB`>WA4;Fe{*AEP4ktT7zUfw1H(2E8OAbblEw#YeZ2u$@D$USl!nFoz-)vT z3&gbJ7mWW{!f)d+QOctu%n`-FqBV8FvQY;HSlL}lhZC&@P_m>JZ0QWLAyRq=>7{SS zYM`EvmAJ^U(yB5q@6+_2*Fr2Tw$S&;zSbY?p|WrSqxEAoA6KQPiK>=@^r~Ad@@~Z^ z)q1RB^II?K7?$LP&4H3@nc*nlW)qL~*1$p0N>hhfS{BO}KO+)&{$fwMipbQaTRP5aeCm(`ont&_4Z5se-In~Mc_2Cquk#|gQy zJUViWS1eh-c$yuU<4CFoOuBR$|8xE%zz2T&yU3n~nWj&d$JS!E+>SxHO{KVciB3;l zeo;^rNL8*cttP=FjNbE)@}IXpfX*WA>Myr6!2_;H_?(U4=rDzWX~|?6kH)G*n34zv z^Rl=JjLwq(nA(8lY z{ZDXPrpl#!6T86xT?TG{MbL(B6&4ue;M` zB6ABy&@<0v1HEEr0tF2gip(6QK^}uhjQR7wM=VHdg+O)IT3I?WuZmvg{}&oH5>;%- zd=@SnbCx;9j!RdPTktou_+Y0+F9%meJK+1Z41DkWt8(XK&S*~hgY2uIF(zO}MQu~J z0NoEvUI9oGQMTViK?uI8gM0O<=i|R3BD7+z{+RE5uoC-F4uy{+@bN93h}k*rQa0a} zDYNiZ=1S|NQXR4lPb&|QiZV~s;P<(!VR;D>KoyP++Gr(OQ-cskO~hv7Cl6@lN|4fd zR#BA+ohp_G{b0P!DZ2Ry66;+$%PWb;IDQM&hPu9`TR>%LvuriTX_I42CiEIt!Sdre z8D%`JdesKhlGUe+m1NecWby$OSL@oET54y#kzi*M&Qe|-l%)x>F_p*%v}@ypb(wi; zt6oy(nNDi4^|E8AKmx2#KSv4Y(Ibjn$)WdBL!N2B;}QjziIsq$oZA-^hq?h~)vT(4 zhCkW`zxum2u50SBZ9U%z3Sk%^lP*B8pV1Go7OsmfD+{+qx!i!7D#)tsK?7p*)jfrZ zOUcQ)i-p0}Hdy{2Bw$L(H-5yWV}jC;+rnk?1vcxwtSjS81CuPVqMTCB`JbfET5A-K zv2_v!*3y17$SR|l@i2Sz{)^+_EwyaV_14MlMPLNDtd)KBRp3dN1f+{whRT>q{}1I| z`Y!!)lcm9?jD5DbXUJV9VoDB*c9zYP0uj?Z7L~|{aYe1v)EdRJzm?B{4EoRO0$}HpZOK z4gp%Z7;1l*Bcr>S#SPB9M}qy6SwnG5F=Phb5Hwt9RG9 zxBl+h-F(mB5c!$sl+e*tMhmi*Lyu+^2-m6Z`ltP!J*SlG=-jPJ?iV_Dx01WBa$j`! zh`e$RqpS6&^72V))vGWL8*R%f25Wsm?je>~{Ne$~=KtNfW-8{J{+4f62=y7=@g(8n zLk!905KtCXQC2Q=9w!rQWRpdty;jI>UN(~o#^o_-WK=qsPg0!k(*h7gYN>ookun%T zmJl#a!vq2=@{HjVKJ;Mr(FVIE@0IEZ96G`=lO)wf;8G$Hzq-Khze0B3ilzSqg zp2$l72_;ojD|JQ9LM>coK?0JkwCKjP*^Q0<1C!0(vy&tK0sdsa2>{qEx4-L?tW9zh zBB#@pUY&IxP}@T))rSZwDn`vM^f_kXOX*qHDG_zqNs(7^xjR<*hB$Igb&g>GS;OEY z_c7e}cG!KZq{Z-UqPIU_q$6;ChNcfr{J+QO#4`7R=Lf$m5S z(VZ35+^4JP7MGI;YsJS-?2Co$N`p)gY0mgq;UcSt3ZhBG7K#s2IewWFmyOYI}G(7 zLXPWK#AvjI$ih9bdFkG;yy!?}Z9Np{)h7ZRasZpS>?zbL6B@rKkw=14nI;D zdnftB9*cz$7{niC7vL&zJY4Wn7-m!@qn|%fk9~m3b{ll%^LteMcX0_X#2EO~^f1=w zdFjo@%gQO?oH;b)st2pkz99HGdW90C+25c^%TJ@K9HiB{#XrLQm$oZmZk-0gf2Hws z2Ae8rd7P6}WXj_lZg^btI3{V_#*o^s8n4YAP~Rd4{&05W_A%bGloaXWT*)46QL|6M`hR|EYp2k^?C4x!LF;Oop$QXh9St7;zd*)#;6Dnj*##$PVf3_kO&63 z^p^@W&0iBdNn7Cu6JH-;G&wfeg+kbT6**IH_8@~uNS2@gEL&v_5h@fIpR6b6yZTFv zB2fgxdc)Bf6K#YyDfwYHy~KE5$es4+j2V4~{UU(-#&6#t4x7&YyFr~1^nY?(kEjjQ zv;GK^pP?MHWCwNUEBMpD{J8{5j!X}zY5IC0TUDu$ZycqD4Q0yEz`TY#G(x*HBawHO z&C)kU5+aA?h%Ezl{EA}=tB0sJaIAxLy#dly1YVw*I$*k^3k(9fA%9`?m&Q+JF1=ns z1KEj-YETKA&iSNKk9)EWL_eZIf)n$IirZ=$v_!3tG*EkCY(4RxG2EzQr6F0Hp&L(f zizI*meI3bKgX)L^Db+^_AbeEWK+`;wpoc}Qha>cWaa$2J66Oot@U)?BD!-dbb+g#N zadL86c`oNqk$^y|^k@xeKBu{g2TL#T=Mx4!xw;*@TEk9jdw!O8H%TUpt?IN zvYDrGW!~{ua|44k`QzL0Z&U8Ry%%|s>*$-xMQ1b|tk(gLSuheU5g=Bd& z1VAOI|EzCdGpkv@a-M#LjdGY4gn7llIeyMcSg*0RHLw3uM}P~9G-t4gr~PD-dVL#<4@|S~JH3OtfKMA*p&4CL^!54N zp~-q2feLLtdlpx4O?S+gxD2J~way~!JOeCdE;73$&G9)w40<-KRkO=N%0(7D0pWVr z(k$fY(Mmc?UUW+WNtblh)QRMdNwGN5JBPjvR*|f8%J?IeffY@}(@4&iz@G@%7N;XJ zGNUF6aR1OI;BTrKBya^zp{*UXH>iF~mX@Q>jas%-diBh%GGn{J8m-Q919tIG(S&b( z0Za35yGid%|3K1S^Mq&Nt%sOMjRS@^{%*Tsi`db6a)@SDUzVF2F1j_FxKO+Ll6<;8 z(>L@FtNN4AKggnO8I1G-iROk(&iEd8iTBF-kG!UH9bKbo&C}y|kQYAYUUu+IntCYV z2EkcMI@{^V*DDzA=4d(YcEsc_6gLMmXWR`zNHZa-(l3{0lz4Fw7#ynj=Khgm6>%Na5*X)GGr~9ToGP6@hsZW9*jc!V1G)wav4>ohZ**c< z9@Fy5=b7Kd_U4D8UGvS<;$%=;7p_XZP@lspHYo5H@e+r;X@ASF=Uu+2m#0Y~pV`FqSB8mH{l4Np{H zTeG87u@Cb^%O$5LlhbBJ6ALp*>9LVA6)%wF~6w&(Es0HI;7oZ!7Wd6WD~&5RGa zwb5tI>mhlSC`qsz_&W1y(VeLvdCO61U4@jBWmTj1XVsQF&FHB~haSFYy@G`4>A$Y>@z=oi*|0j+kgX%_Q;57`9|xpKKli5z3_HbCF)x)3!BYu?NNZwYnj*wCvnoG`f<6Le`-q zp;S<4ARz$Unu<0=b;;&Sg0<&Myl3sU)7Q-JHQv3Z%Tqiwl9&k0JD&PE11kmX)@!66 zaB>S(o_UHK-eKtBvgQN;*ATl3U_r zND?~QXJ&~a*kD0_zGjOUf^x+S)GEhyu(}E4!lofD{(iVE=mP*+Yq5(O;qYEO);4>; zt(8Qpc^N}fBtw{8FPy_+9!*fwDjiKID6`KkC}QMBGq%Fs`NobyZc zVF$WQN?Qzn`J`g^RY4EZ(_FSF^xlo0mPoX4obLt+)%J({nA%iM*Y=*&tq|8U_3~`H zv~Kv5S6ib;smr-fcb`#e(P3L7*Vg#8ySuP9zP;)h_roQ<2FA9&YF-V<_Wy=eH9I|- z->Qd@sje;-AQ|}N7WPw@i%-sTMOE0NDy~Zr*wA%1XjDzODD5JsCmP@XvQ-7nl$_q~ ze&xw0*MfY?(^Lb*J@@=281*{#%+bu#w2WOq-SZTiIyK~B+Z~CT7q?>peI{og=@ad_ zdYC<$7=9lV-GyJlQubJ#jAV6@DY9=aX##ZtK;)aDbT5oF;7<0@gUYE&dgq~ zUC*)-PnO=o2W(-UgW3_x{ItSWE=u&Q)$RXM?cNwx%4;EpVp!iuD&vqgPREmG;c!L& z@~|ZbYXb&j7@YuMy+}?FUG$k;zOgctaD%u%pBgYuqxHME?wvK6!UZuWfCD*yM_kPY z+YFHV*ANG}i{YYq;fUphhK+?6`yh{($B-;-y{DWuF7-SkY@%Zm)TM0nv$4qWQ&Gcx z8!WmbDQBGBGxu!o!x8dO*IiL{&BML6`o74o>18N>ZpDmfgOw^}@o!fOMASoA9K;=S z*aw!fdc;y%3y}Izg)x4+_IUTJPa&Oa2Qff+R%4|y{t3;-%tSbbf*Fd#8@@RqQd2e5 z2UiffV$hFHi}%EX(EYf{PQ;N)KVRf3p2 z5;rZ=sDNhqMw=3{jxIIi9=j^8(aVDHN&l`Kq;`I}2+^!j5)UJmu>PCUcHZVlixExb z*-56kjGZIcanbY}y@ydi)5RNQ$<_P`A-455Ta0t@Bs;R-Fx|m-25!S+8D{CpDLtT% zhuDjE`%D8Epx&V$sUBz5vVG)+732Nl)%)bj*Lr!chG%i3($iuC%u}ab#Mkza=^l&H zH{CiKKK`cIp#Dzq?*W}H6KljFHrf(#ycNMIzxS__FA1hue?V?e+4$~7^!23-&7;Bl zTDJta*CR1Rt?#LB?^aAWr~j^V*KG)McLk3_JcMiT*c=@|8-r>b zL(mGYl>NKB?7qSAqMw~Zlb=~ku)6`ziA6H5=OEfM4(WjX=BG5-zU#VKWO_Uy=u&H~ zOB_?(BzfCT5l;0l`ri%yhet>FdS1ce*zwR|4eVKWJ8<5G$y3u9(tT0kCT0eD+)NRp z{V!3ww4YSk&8#_nlid+lGOdoNRCfFX1=IS7vhkq?u#nc1U3FYTYE05w_7o=}{PY;B zLaXi~Rs?KAEv#N8o1{Eni4&q98x8`pIF+y6SJ%1zGqqja4YX)Akfgilmt&hs(^9y0 z?hQRdmy*Y)u0`#RBRO;dg=M}c8Hw%O#yUcx8AD8Ba#)l_>~%EkvWZ5}3CGp7 zk}x0(O7+4@l~tK1z1alen1cG9PWSPL-r=d--MMLdyktvvlmMN=c2SlkFC=kcVUVl& zF(M*9P}4;`boK1%8i*PqwS!ke^)lEm<6a6|F5*2r^Q!cGW(5K5dhH4KbiJ;wdrE>T zKqfd?A9`q3*vOgcM}ZQZ*{X*f55Mp3`rXH4kNLHvd%Ru;9zBA+11cG9JC1;E!(|Sw z`0X}^RsDv^fYMZO4e;aeqwDMPy1IUoakcNI3;=uZ8O9$EbK-%>gF=J!@|oJ$vV8D~ z=Mr+!yf!aAk0zcVRdG`4Z2Ekn{O?F>&2!?Z8n>!V&m^yMDLNd|Ma0CfR%vz|nE}nL zvLUKc(%|*q)E?OW%;cD$XG}L3AzYZqZtOZgxSS}1nhF&ktg4EMMg}OG5)^`6z$&$; z-$g0~8!KsvrzVXcwaBqO<^T$skI79O||DmN%{XKu^xT13on=l+ltR?-9Vf1;H! zQSOQKd3W|P?M&UgyHHHnKdXCpqut=;%zDnRhp(-o?mP@cdgW*BM=r{sKYBM~R@K4= z^^%(UT<=Z-WD~^yZ3Qz{v~1&RUbn>hepmn^KzRT~Q=<ZOc8MKk#$Zkum#V+@tmyOiV_9WlLePzWms@hWd*S zVWS=B^aS2#oW=kOGHohk3oG<1;|RcGU9zsUSHr2zzggQNReNZ~`HLJ{T&PQ#?BRkTe!UE%B;|%0lRh#fcVh9Z*9@?RNtrM4jO$(WtLB5^;r-C4 z6&xI|6SJ8#xjlq5l^y>QsUB3Zp5skbCrg!$GOw9G(1fwQ*-sxRXbf|rF5!l+V<1K= zAoWXL#CQw5ygr`&%DWF&pq0DXPF_B|A1=fdxHGvEElC=El@%ZxGgPeNq%fvYNg8jE zs(*q)4W#z0#_n_=GmHN6lw(<_95dGqv-bO|1RiB~cj#{8N|>GTOK zEoCvjrfbJTPnbg0$wcJt7f!}&YD3qAryPNJvcU@5Yg@cbM|&Qy?G5W5#rc}1e9OwP z7h}abh*}x2Dh6VFu?IkIK`y6PW9B1-;v!H$E5Kiop{CPZuP1-0cJRaKx^DdJ8*T-E zbpv2nl^0K5P2Iyx>P(B`u2XHoZd>Uv|J z+nEkmqVb0di=A}1W4aQn9-hr`N#9X?hWU%RMg|xaK7`sGDFaxgHCN+M(*ld4* zUFIX4N+8}4zV`%BuaU~XX40Y1Xq7}lR(4P53uK^3uO%^&m@d8nwh2@p?cqvsll4l(69_x`` zT(EF}U!%g1u+D&7N%ypj*D9p4woN->Yo#y26=m~As^D`=F=79#@jP%>ovm!o)2qh^K0`cmrfu@`+TNbp`mp> zqBEE6Im)9lu+YAl(CjYpnj5_O8-$GS^fu6k0h=F6r`SbMR6>OVBg&;SchT8Kvm)F` zvP0SCdSCD#dT|Z0#{*69Vz&S%s*gJu(#aF8B1+)+31`Vu8d(g4WB7MH({ss!U5Ye~3O1qOE4)LTKi8*lNyPD6^H>z)jH zxx2)RnDGx7?z0h$wH3jT^lsKY)6(c#X5vxD6rRZLQ(WUI-KV#fYx6%{rw1k+#a%#k z0YHZ2;pDBT?ZT5~TzQfUsD%{dY60F{2Eis*l6}B^+jBz^j`7PE|JM*xJx2ZJX-;iM zgO?xoXZhkq-W~XOe0VCMqGCnl#H_8j%ljKd_uaO3am<_{YiqndtdzG0eVnc3+FiwW ziZQmDTDMHAraM74c)R^n-KY3f806IV3ZV(gT82f~7}?4Q3Q}_lb~S|CGU&u^6z$^> zoO6LGUn>1b3z)qHRUGL14kvmO1ikH&dV65RYq9NlNJt*6fjyM;cGUy50Jk~`(fq+W z8^Wlhhhz8F!o#PJL*a3$aNTi&f4GQP8s?AJA!TmpY3~*G+lZL;?6IamH0iFIth-td z>!)^vT?DE3$pc2}tEqCb6$5%)jo+Ksk~_@8gXAUjUOQUQb}&98HKZT)n8U*>-o5So zw}(mqLo<~S(g9RM_6kt!ODSi09NJ$_E(_0;?fX2@0_J3@=;SOPoNL?D z)3j^V)zb_oZMnuMM$OK&hbFH%7jdX17XYtAW);^6kL!bn1{%P71|rdb6uaLs^s>{> z$xHT=w*T4o$hr_k`6#D;xMHeHUE;tSHvH>YB=w95%Z@3aGVPFQ?|~aufBYQJku?it z1wjk~TQGJp`fm}=-IJMmK`u4}Z9JM@yL z#``2+ep<9yZ|8y;AK0fI4ReQaib*)=65?6JuCKSD^!bHUGGmUu4DAPXM70RrXrq(^ zF-pq(;U~z)YlV6`oLYaAVH{H#V(pP1KmY9Gw%zK0o4DLnxRa&HM;|;(1p9jtNGfY0 z5xiy98>>%U-vC+`6E4A^$KFrryV+Kya%7b4`O2joKXDv_O|@9zWxd$8(ZI#QW6#HE znsiMp5rbt%i(WJ1`CNEb1fPeN58v>C}Tot+46@;2|} zur1ZSUFxS)zP4n00tm(NEG}-o`{uJg5g(lRBC+JCUJ38$bU+6S~w@W1qF|9wP0-2MwT&~HAhD-+!e( zbPMGGERmXx_N`*WpU}gq^CL=h7Rz>3;EW0Q2^Nftvab~u15+H^7(T3^HGs*qhnQ3O zZF);op#V?~5a>7C(z-$fa@rT2G}*vidnOv=eqDz)ZmhH#rf%ccMr1D9mE*#;Y-cajyoJ2<#9i<&2)I;K1k664rpdaoy|*T!p?W+(cla)^Jr)u8k=O>!{jqu%r5Mi$u+<)3HT0uAapik3*+5HIs!!-1R66TJk<~QEF5Ofu)Tjf=jZW% zXUP*kawCUosB4Z@QzKZpAY#hN6&McvV{*Ny%kWE6A)RCiQSe&WW&J*=>x#Yl7AkCi zE9@~f*mF*GI-hAVIJ0)%c4yWGGwUS<(4G`uD1FLz%Z&6d#g#8sb*^wBKJhBg@pyyBGw<_mMg>zs*l5^+isDV zZKxb^5>Av@-daFTTVi@mWDx$rOmCuJ$iF8SulPs{w{BdDF@_jbhOSMT`1OeO@*z}+ z1%t=vI@UQ5tPi7*rnrvpo2@Iw(|)0cP4g|nU7)?z61UgkPI$}%F7*diXL#NC-cmkq zfxKzyA$P1#zW{eSrHaPu{J=n)ke3c&76(}1D5Qz-1paw`MH&Fc*5N8mg79pWOihwL0qN7WO(Jrx z(``RI5zX!bx*pSH@;ktLsKEPOy=idm5F`lsfgAo1_n`MS z)pANV{Vh?>-ec>MELgt0F6pM5*DW2qnc^fI*OGi!{!v0?d7!{_01TWSBu6gt?UHpo zwv(nO`+E5+!gexgSV&nNdN4M-F02zb$C`16xi!z|sEDEq2p2cWna-A15Rq zOPaF4Egk61kqt<^^t^D9IDrsJHb>cMGRAUAFY`5K$rH8qO0588q_hr`2rMcFYMT5C z(tDIV|M}#rXyfuBbj)==1UwJ8H`X}D{HxYj^+rj z5_?)JJ-2#}%!$LgV;Uo$E+vNp1Z#@4kqz83=8(wskz@$f7-f0X92w3jO%%>1nZ}gQ z2UaGw3Kj1Uhc`^BQ14%4Ts6G9!3q@T2O7KwApcB; z4#18d@Yv}ftZEzz==eHc5+o0FH^=&WT;~`wsSjkK0GC!_ORQIqg46M0E$Fh_<;1KI z>4aX{ue-Y!-tTL5c4Lv%Uz=s+eXZc|)Ep15@nqt=y2f8#Y2R}Bw;+QK;D&@#py+vR zo)%p3%rk&%-n)6WxFiP%?rlNTkT%vfB-yM!IxML97|TaL|`a1mrUO-iLmYWX8sox!MmhE^Intc4kp|V~ipzPgUEXXWU zo6rVf$i05rIM2VJeC{K#_02MK8L)bAjrp}FcaKgv1=SoRpZ!DKwJpcd6X93EOMn?x zc6OaO39}xy@`r>|AQa(P8phzrP6}c6)PqYE>vj&Pl0Zn9q8!W{G{C{`^ z9Z)vTrP@d}&jw>NO>3GP&d2Z>dxURr#Na04s*!McgZPYX{tH zuW}=E;-zk@rMzV`2rOCqu6f3b4~Dat-#gUf!C>>DJ3}lMUCC1hxJNkO;4Tu##rQ6& zEfegE4Szc@-8O?w-mcW|j-8c6QS@SkXO#@(hr0u$fm1TuYf2N9jvU#k2c7a$q{s&m z!?H@lAb@wrX!@!3Ti3Kaw2pFexfOv+T8u}2m6yf=5|7d)(u=*KubcKm)yDj5XZ7GE zPxVcAJ8=aqgAA{lElo@w)D!`7Y0I8Q| zFsa@vg>IhOSOODWs$s%ZAqMr1chGit{JQg1&}vm0 zukK7|;4AQnMx*}pgGPQLpX#vFr-F96Y8C(4%7;FEm5l{h_vBGxZ^dH2meQdGse*;O z_%{u98-D`Ycmzl64;5GH)oMv|m7RBcft=W)f8*gc+No9+q<-wge&Zmt!VBnas+|>{ zu_N9R)W1b{_IlIjRGaJg^t+_$Hau zri1Q|d+yBPnvO1A7QMRafvTcWF@(33>V8z(j#?zb$Z6*&^ryQKnH_G0QEt3X*Xl6y z^k|a7G16!~0St1RbOWDzpYb&k2`Yra`>o$`5YL-I(*?x}3oRF)?wIV|%458ff%!5P zv5$LAtNM2dJHFN`pimLTsfMS%N++h+Dh++*=aup_qC!cXW)*F^0X_L{V+`y0&t=rW zNq*KstL+73Yh{#$s-}1xZ{M-&|0o^E)ivihh4uEsy0~H+pS!C(;#7Hu->%>xv?tEw zbXP@zUfv7thrO0~)WN%l{IeYbIce(vX?m}`ZEdmw+ZW~=2SS(rmh1lALThEJu>G?2 z+KTz+ztddHf8Q$rnz@jdA$&%$AQeq+%7ZNYwhyEf6K5&neT|Y+7-M>u8yYh=8AI61 z6~l6t4mY-6OFA2F4m*Ypd=9qO*|$`qsV=0 z2)C&`7NtcX8hpTh*ffYB|GzIr3tGadWQq;&8QRGqT z%!>Ve@O6^3-uFdu;xTsO5J=Y!O{3LypzD(+9}(wb(3oUQyikkE)5N3*7egq}P=8tp z3rZGo5k?yRg4?0ru!=x!VYk5nm(oyPfbR8T6;=6Er?gc^Jt?w*S%|Zz@x9#H{K(zETcqM#tm}@23U#kbe<*XRil0)JAP8B`a4xD^AhE9bi zVvo%Rf8TF5zfLvtb9g^NZs6JuiTNBsgpP|Dm+uyT zh@A)8df9hE6bvW`93j=XBml&>uWCc*382JzIemtMOQ#8YMjnz7M<$ZW?iE z2P)yIumo~c^Gt=pSWzepK)BBMXPLdDbLag0OeURWO2VvU^0|J0H$ThHW!g)VM#i9} zO#Hr1d?w%D>i7D13Po}}{c7Hs(`W2sRnt_um!D%~@8xGmYzWt}PHd1ke}=oJ`7)a` zurysp+GNjCS;2Ev0bosz>$!xNy-sr~3^2!?H54;ge3+kS3cVj>=q!|jzK??ZQJZ?s zXXNyj>gI576*(Y~$TQOHcujB%6#T&~Ezqedzy07=_nnNO*z$q_x=_BuP^fAo>Wgkl z^c_4grVkH~j`LF-aX_HJ2a^Yz&7+5hPafs@DJ$hUK@ie)Enl)z+e_niwA{M=z?qrw zdHx#Im5rA;zSceV>wGUE#(=p}etD|D+@lUxO?n|2=9T>UvHbZ={(RG6tgjiy*jjGA za@Nco;gRGIRu2=tqU)<)ePXVlr3=lcUqNrquh|(mJED~Pi#OMkqpwW&>F4a>$$e~X zwjF@Z5w|6KWU@S(PWJhypuZ2_@ypQ}{arrdm+~S1eJo#=4y5m762v13;?Y<5?>qT& z>SR32rsxk+qJE%?oXH|*U$MEs3oo+=$VKYdasK4+$>VvuI6OM~BHDC#^pHP1I+{Ls zbPPZ*vuEtn@}2|oO$3os{F?sUqd&jO7Yl6ALJOOU3H>_}=KT==ocG6g#g9rj!oP=N zYBC&7>A#154hC@|et~MZG?h@L?E9g4Kg9ck-ur_GNI*6Kxd!^QS8<*ninIKIc$Pmz zM3f^$KzSry=8whq^C#kM{uS{&pH9RN^66B3C!ZdQ7y0yocm>uM-^6_k;>Y>)k@ze} zbH0{OpNKkNd`kALUkKcqf${$1bw z-@mH7*CPDA^S`&$dawQ061JucxA~c=_1wju&S);aFJk`~K1ZK>cDH}rcQ3>%@lEk# z@fk4uf&RCn9QVuJYde{(4qoQhVs-HSe2Kr$znh=q=hb)Lem{SJho|2Kuj1p|Z{$b# z{R|w7x0lcJ$N2r)s~_Z}zx;WG$7S;wG?MR^*!&HTUh+CmiT&e4C6@ImOY1F7(G+>Z zNc!N`ssyIJXzDs&z~P!?V>S_?t}aav@8`eBekB@dN?*&Lf`3S95jwPe4t?xeJ}>3Z zIYB3FsAk27hHycD8eV|);`$_q49AZ=`i!8VkW9bMSxzmX5G|2&iJa8>CI`gD z5_(KdT1pK@TBfM|@Zp56e`}%Qz*`Z9kuTCn?BA;3wkUf~ zQ^XJhiA<0DY5I|2yq_7L!u%TOAcE!@9e+JTp6}1jpyqY-{C>NoTXlr)R4AyXU;+5W zu~|E{q#_go3Idd$U0S{zi6h8q&{X>}h{JY}djS@w+_pU%F@hp=9v@Vcq5_ ztr%0m_eanNR?_6dOZ{-hrgYj2HisO62QBIuNk;dj#QdAfUkzacL@MaLK@&A^UgNi#)PW8BV8!QifRC{4OMA{6Qvar8%~raMk?Q9 z`SPSVeRF*{IsEM8z6j52Ydg6%T2htYDX!q;&F|W?8+Wg;sI-}W2)y!w-?`U0T)DN& zK7aKR)5RZ0_By(6*6*vf!v0!o;(1o>_q)~CsuyEn`&V?28(`bo`YBb*u6pH}-9>id ziIz1DpuAT4FF08pvr7XjG{fQ+l-?$2I_Ak|CJop^l(V^WC(-j*P^ zZu)1ki-B3M%MYwn(6$b}L+^8q#cUp95^V}%_kw~8Vm?rm;ZALpRqhS>7NQ+Jn8Y42 zu;KL`{3*EN2&HqEwc*30?+( zg^aOh$Q@HDDL@SN6Hzx}P}Khv{$A2P+4Js92^7Ntuau@K7<=+cl;g2fJW8KmXOH(pam31eAPO{JZKc|%^_{!YyFY~j zCF%D4@~SMlgc~MWP`TWC>C%f4uhX=BePv7Yq7p7Ld7?+2vV$(9?|AK4XNm_gWZCCTBn((St$ONDt43%%kbN)D9!-8hQ&qUk@aPcKk7WsjU1Y8XH8G86$(1C(nA zWf}-}o~03~HtDDpb4;M0P~0sHEl>wI|EN871hCBNtr&)oW_<|kKmff<;z5RJM+F9{ zuom%LLHGUX+!@Tn`UxA=DopKRr&EaX59_Kc;gwfrQ1!A7JyQ%V)RU^Wq#zsLz!F0= zm|FL4s1D>jCWWVkz2FOndlW$*U2H5y@+ff4XMme=FofI1+L%CYt_7{umE=@O5`%`% zC#k;-wR!Cfu|NH?r(k8?dpHpTNH`bTEp32nMYg~*M7ym{W3 zLD7;kdrbX|SQHk}0|F51YrQZsP7IuiV+Kv%%id?4azDm6YRJ=wPD-~+Cn^3T>)lPG zGS2(lO<|7%fxGv3HE!-79+%R8pc?0msEOQGNBjuUAg`X-#?Tp$fza0MmvWdD-q~(> zbC+d>Got57d0atu?Czmt>2;3+?;PpT zT3LqzKdN+g_PzCe!EU&ybzp>TP0Fq?iky$D#y9pb7R^p;EVO{WqqDl%*1P@Bq{<^p z{EQ6CTmw--tCi-24RlqY;Dnvo?zPnll|%G9`ozqs(q8@S9X0LreGTfU58L)MJS?x| z5j|a2DuE#D9`dMTp%Cl307Q;gz)*n8$P-*&D_ii)@)@gLuapIolruP9n+qXJ8A(IE zLzJQL(k-Ygjt-rMTFH&13~nR;nHKn`Rck-SV5_iEa0mT1)pwBB;!ZkpZaITqfs6gF zDB)yLDP{%1XZ!nW2(yIf)!T>5H*H#0;RFfOs{N6cSTvB!EDOxiB3KT1ict?C@NKUf zTMLnMTXYmG`5M%*i{SI1+)ECdpShKX%?XR#nI70rK*$yfB-npj2MRCU*qVL8qG#w4kqsZ29BMfYDQ6J6ZA zVUhIS^>)MHxU@{Sl2`79pk00>xhcMTefbWHy6-&w$=e@2efh)ZL4pCQNg41pC&!PK z&r3QPnw9cgh^UdGo-_V3i(pmBlQH__Rn4!pdIdINk$lL{qDMZZGKP1c%-pF%6WN~* zD9w|eyGE;>>b#GHq42u4Am8SzVqIzmvVdJU!8{j3R>`&ajFm(RY&K!@kO=ork0BdY zs)kw6bPwzSHaR#-;0`!nBFCksA7Vk2HimAW?SIgCtQbKk*yeO^=awVY2O8eLU)~+G zWe={vd=GJst4?uLZF(Hd-Oxhp+{XXVu}R0RUZI_*tsJJD$)n?eY!37j!?Kv z9}G-UcZGr?K9H*B$RBrwWXgr$a1i{?z_?T&)Qf8MPk=(HI4DN;?!aP=L`2u+KhuY% zTnO%;=u2J9Dl`l!HicDZc0be1XxIm{qN~g+DV1_PTj|xlXUMa40Cd=ppu589H3_gy z{OO*)#PuAjztXS|wvC@U*l~MGEoEmz$XN0*^K$Bd#cx!zLgAdEgMGHA-iy{piO;M` zW3qL-%G-HTyN6sUd`Ha?(ySJH+)r~3oW?fjN<=pXs#LorWKP~O9H+xUdHa6h?6zM5 zftU|Z3!nWu*;loPGVtbdPO%To^=e6eKXfAZb#vBX<8|O%k?vm6n#XZx$b3wuWt(Zg zbF!swWu-FqMc;yiH)()wFGl=oa^=HC?mQO zNCMCW&1p${!BUHL0#Wl#JH7{MvK8JIsKG=5MZBR5vV=NeoGkHy2O5R5i5|MM=rSl; zXUN)NSr|bg-PqLUp2B+9p%LOQKwZaW3_DD{UaBeP+%GV0;DuDQ%JFj2pK-e|gY*X* zkg+`RPr1w6h;(g@bZrCaO8V~*etcTGW`EdmzOxbH7R?N3gK_s&%bZ574tw6@iOyAt z3hh?jR>bRGM@g@Lx?PPAduM0o4X)`2IdZpd#MZNbC2yXIMfFc=Mp9}-;mR}X7WzyD zwj)U!nWfX7H)Ul)CatxrpgLNuCE%xz9C0Iiw|wwp{}$}s=B-k4cjisQI%7;x9pmpH z&v%em5tZ5SIy>0L*S#^W4%__i;A&cbY>n|27Cm0cVou;Pp@mRXEEF&c;V?)PAr@*u zf5sa|kpp(LirHDls7bngI7Z!I9?O2|NV2BxYZP-aK80S#6#UGDb^XUiE0kBk_a5dw>*a9 z0BeZ%^!Yam6hbLulfZXp^3@0VWGkJw1{fBZ<9Z0(oa0^a?-t&gws(`^q4*w_$TPJH zu5>6TxM9R3IlK7Bh+P@ic){9bK=KcNE?uzbldq& z`eBl0H;%a^jsckA(-8oWq5AFTtq7Kbabw+$3p%?Z>9ebOGfbsVfRMXRsT}yDzNGee zSyFqj@RrV#DjzOuT}ukmWj^N3wwjB{oC`82~?Wt!UY z6>L`TZo^bm#v>v0Knm%t#YUX!yBS;;iA}V91CR-uu0qQBQk7e*z9oG}DVu1~v2&Vp z?txu7Uac!2R|eZfgS!KzD7CL!uBP6oyuioa`(_i#q!8(v5RGti-MPoW_|MF>Dqw_D z?^QU8g8mekUh%=cs4tw~?!`b;vCR%0W%?cPP|D{OwS<;8d8 zmCj{4m6yem$n)WGFV&0ZfWU%FC_E8n*6UZ_wK&^zP-}M5z`zmBPqG0F^aY9Bxv! zZCmDq$hMC#WNHNAR1A-I7X|C}_WYOdO7^LhlqT?+&jWC2GbU{Rn{s8Gav&HBV$bF? z3oWmkH6lsr(%UK5qddU7FhO2h9xtgyL_JL60n)nzL#1dWabAj7zu6tMBD`U2w^y`t zCD(`iuzcV}mM~PHOXke|8ukp_ny)c!O_T}VX@JZ571)7OoigrGF_X-6;~+h#c_NxT z1cMCuM-}sy%|Y3S&bE%|@`(|A#0wNw!3-O|mkV+n{JEi8sX!TJ&fJSIieTrRtb-yc$sBb#+L8pUN>Yd*y zuTJHiZ#tK_?p+d_%(G-Pz8H_vO>&T?qg2J?EbK<{p?4SRskGpvbL=3iXEPFzbUjyz z`Xh#Rc8$=YUgmk?-yfYQhXuL-^OWMNt1B=W@2k(9V@+|@es0;6ZT+S0bKH>#?7s$s zW~YL`@+hUs!0RCvX{K@KhUhOQCy^d6xNL(!YrjLv%Kg@+StK&CDh%_JDT%JJP^QP% za|sDNw~~-DO+taM$bA80+nYB_rF!bVpQ{JwB>9_UG1>ph$v7Q6GX7>XPTBQ$}|+7b0ykw zel2R5e34pWZZ?)AN@?9%u1Ok-TQt!HaYHd67V*nv9n`po)OiFBbkLP+{s6BC#q8Q7 zl)5s7hJAk!jK;N!Hj-}eKaYlc>4=KM-#+Hb`<>!f+?C96J-LS1gd0rOexDC%OSU=6 zUTOw!s?1Sp)G#RNepNC{ab`20dvZcogV<48j-&~&iXv_lty8Ey21 zlUxD92L+4rY>iF=y*L;o!8PHf#_D8tW3zcq)l;k#!v^gNXlomZ9l)v~b)+GPZOV78 zR$fzT+Z35=>jsw^9vyis;Iun14>oTWkfrpn_!$N>&Vqh<^9I+eF0y>@WRtu}hHr75 zlN27IpTMkxEFHSYkw~@I%mPL}Qa2y)Nlscet}su|96S@?ml86l5U2sObWZOn{w&@s zfVGdMs07FNwOaVR$VVp-25r{jac`2<^8}hM#g%~a1*)$|Da;#qXsEOtvyfOL##>hL z5zw&!=FaWnI@_8G@V0S-@n3HBWXJ&7s+k(ArU@azAJddg1--B!8dy5^^KKQ7{S2+J zr=2ATB#xmtjqbVMY;X$BG|ovv2}gpIBI)?rc0+2?9`NpY>&YP!c4ZflvRyj*e0O;@ zlBXBR9w!9@FijyY)jcB@74JTExp`I|I(pbBeT>j!a*Ralsz@9OnT^0hpRK;yh;^t# zQ5GER%W1X{mo99Q z9hduOs++!gDj{6;7~)je9O>+uuR6-}<@{P6^BU(@St3&r*<4OU*Qr5wsc^l*Al3AE zPc8t*jn$Lh%UE*yE@B}1o?8aZTy#i3Lb}>`1HsPH*mSl`&!JUK!T;w6m*tu+Uy=Q@N8NUdzB+@}V|w?@IIiKw z%CKylEt&OYH!oE;b0@2EOLS<82B0}+=`8mMi6MzLxF7thALQ!f;;V;WE{)I&yQQkJ zF00TpD;y-1SG`v?-!bp3(mrwz@%@BZC&&y;)5h%7hFVOcZIdnP4~Nq+t;$lt?H*yy zTc6=-Dm24~S38oLTW$EFq=1CIE~S$Nm9*Uj1>G$*S> z>E&&cld?2R8kR6PfTYD0W}a}c%3SK4I6oWBq(cD(1x9iCkP7~loUBUO1h1(5fbz~8 zW><%*i*8&&t(O74yf(YpkcrxDCuWauRxh)KROS+^Q$^=cN77V_-Ci?Kpez6nQ(cl~ z>_t(hUa%6~4Qmc5ygosT>1Wn!Re@GXRlZ5pnyDKXtU>p$9(ug2g77~yl{gf>fjJTR^lr8gQbgJ!40%_Kl#R|eG zU@5{_MtyfEID7T(=P=IET_Y`KC4apO#!bxWm*t{^sfjx8)Z84a*+B-|t=wR{T#9d$ zI8ni_JtI!bBP(wOnbNT2hv1c~eRawMUsY1BQbel+K_VZhJ5`$O$iB2v3pEI_&V3(` zNC($quBDgFM%Ta^&FBho6o8T{klTVGMFIapXWe9e>mfjDX~MU z!)zYvLKQ$TaF}hO3dm%l1v88h7Aq0}I&ldrm55Lx6v3Q>Y;%SsXU_UgXjugO zESeM4%_3=pP9&KOsg=Fl?=$mlc&DfI^ihCFb$NEEqZIPN?3v>ncp!JO`w^c{6&zoIC#PVPc1>kqRoYYE*Y*r!2)f9FlW z;)SH^Pta?AUx+UEv4AMD4k9zx6k2JLSKRp|vf!#r&h=CR41U6fIwQn%?ihyFA2w_o zUxus@wO1hzw-PS8@hS#_7wzl^rpj<_x?wbp)QLs36VCIv>=7f~4%@y^t&+BRyHjVm zf7;T?%R7h73w58Ew7M90k3iZdh`2O4EmnL@lv3XxSR;L^rOVrAZqaa{2zTRA>SdwH*f{X&INzkSaJGV+3Ig<-3Q=vhv0Gx?K$EUvqT zRzGX_J$|;vyjFH?HW6+z#0;jwUXrr)!-_60i(kJhLkKqAg6OB2BfzwXe8N~ z)g>n!s&d$3SVeZ8x=0zt`_i8?QEaumWami315*bcdSA8dl14)+yYc1x8iw%Ds-%G zTaJT%bMJ1kvL=e!2Ez|`)wEn8U2JB0;_3iardT%9ys&lLI9}eosi}1^0K8e_(eRQs z1dVjhGWjBiq;dz(y-7kg?(85s)>CmMgJ4Agrjoq7>8mVAATH6C_aYqPel%nh0g1PU zVfW05X4dxDE~_SW@V|^po7e*a7d+@vL%O|FU7R(W8=Ex?0k7pbt0gRmI!J|f+3QIq z>Y?#+%scL=AL1ZgED-GHAQCY|L{(;qaR5OZP( zxo6y3*R$Py8Qar!z2vcIX9LW(zu#{yPu9C-F%OKy8w|~WU|q+^(pbT|zNI|nQH@%~ zDBUSfk$*@ardFyYX*lq$R7-=2BR==6ylyMZ+`}MNPS+K>+lspg!qf`FqAv)GU4jr( z(5DK*kU#z%qahh_$ZRzh(p!%OU;XeB4%5LQ5sY%s`j(u(_^)vO0?3_w3g@3#&R?9| z#Q7(m&iN<*63##Q-{E}4A^#5EU-WqYK_IfyajMlja_hhln<{q_f z>fZA}Zq77d>`hM3U!$5bq%S&+eu8*=V*?XC>lfp8Z4Y|AtL1s(EKj3fTPS3u}!Ruc%Sc`Z8p&?XPkxWUPAJv$z^_pE_t6C zkZ*`dd%5uq+4iP3($5u~+}`(4lZo#GbU$bgHE}pT1mTF@4!#4wyw^4IbV<0aiKFjHnr@z`_L5Yy9lI)ZgG3{ zp~gPu6$Ak}1Ze5>FA_||0K>9rI}7GFZ`JT{2h+BiSKN&NYD&aHoup(SmS@-R+?XPT8OARW_29u3 z=T;1tJQ@+q9>qiDB7Sgspm*B5>#6k~s1ZtVgY8l-Y%za|H92l8%uSmo!nAr^>HI#8 zLJH}eQ4+;_G$50{dgwS#ZJaSx!6AYU#mtT5A@0Cdx5l^B_zq&tJDY@>(Oq}8dFJTjW+&^mqK2*l;W`AQb5A3XgVRD(fOy`&0O_kLjQrH z@C2#g3GT)teg{+ueu_QN99`HH*D%*DSNPl_6 zW8?u1N}|&f;E2>Iqs@&xLg~jSquTd~e?S--+Q_S0jaPa*VtxbZ)F@#Bpfo=KJep7F zV^nhw0e{J1_`@R-xhVzA09aJ{W1<2{4w5{NxF$KoB_(+%0rHVh{0O!I1jV?I0h!VX zpNIGc)RZtGewg5YKm&LbX4>)t0K5Hz{G8*^kqG>(Bm;Mx{KW0zQ8l50kQ9udB>G z-3%~s>VPitNIIF} z@6BPz`562Un&J@!m|;+6%KfCq9D|ukTpr*f_bL8Pf|+@W9-!8tcJu$CKE;hQAi;5s z{4iDbk+$QUPHCh9fB8tXN(bTaNhU%;KOpy5x>vf*<#rTDe0e5snb$tn(s?(%>5$c3 zqKF7T0LiZNS~vN#xJr`ehZ6NwxvTG?ywuSNXi}>Li+^fQqA3TKcstUFyRq_V2^*IB z+My_9#ip^TxECHgW5<`>{xMga&3CB`uP*a^quW?W1my^C5S69{K_9iXsuyzMXN%Fe zuzWX$@$TN+lQB954d7xNqBmADnP-ci#Y%79yn%Jrfx)&4(=CIJaHbQ@fu)Oni(`qK z4IvewPYlE}=9^S_^>MrEXr0bUu{0>R6;T^AcJ9^XtgGhq7xIfu?3(lQmCld#Q2!8H zE8S*P3MkWa+|H|6cbwO=4z9&z(zpRfyL2l}bR4!#tmziFg8r=X>HUc~MY?+%178k3 z8#17?X}y2IB%Uw5jGNi{D9XJ9X{MDNlgh{*eAwYUUTQH>2kb8Me%W~KgK%b-9;bpK zznoHVhw&w1ihOQ9Li;5_e%O}wDv8;LxG_-Ou5iibIAeUN7E^sif@twJ(QmW8C5qRA z&UWFZmz=*X+I%a?Suc3NYVwKJt zb%nhGDZMYX|HW!6uG4H+mU9Y{@GfqWxYTuS0~zfeenZSG)#B2IZJedG4BT9Q;S^UG z+mKmQl1lXpz-wL=QFR|4pU%1HDQ>jKLk_oI#}OnLXr=;nJTb_i4!NC$UpN}yFzFboH!stZlnG*oTj^R;+&akd*=j16o1Zls{t;;ZN9a3#v z_}380Ybqd+ZADDY=`vI=PW_{$tNW+vmro(jlVbiMd!KIIS>rQ@S%;i0L$;QI$3O0w zBc&}{Fq1Z?2jyoVNT*58nU^n<&c9$L4Nd=OSkhUaSm8YT5jvBUMJEV%U-gb+^FsEH z6(gtOVm6pN{~jkI3QWihn&L4XR}i#z*TZBmID8e6;#!o zI#xyj81CtkL{7fv%&T`KF%}}G9qlJwFtQ{u zT|zW#k9&HiAZzwi1+K$IpXX~;YEjAPNX~mMcTF)3=tKZMEICxff1rR*=j?nJRZ=it&UUqzy?4)*d5MXLtim_Q38l7dKCb!6F4FAh)aHaA`t z^v9fLW`I;WZ zHasgH9<`Oi#taLcPcy!^0GF{7WO$^$1WNTQ^dT91V}hB;cKq>LcYYXe0iB{EPuy2W z);I0-6&cYsEyhQ2t{snTPIB~O@xo~;g6GV5JvMv-KURgov&dY zn?*rmuFfqkdIort9E|605L_@to|!_qHruhHHbK-do(B3NueK(fdZhIu1!b@wBJwM4?g{KkNi60;q-=gAt_hiM4T{G0=Ahf^mGT5%44{bx2Ur z!qKCoGgxI;WFrL|hpCKMu9mrH+|`E=SN%hXG&kp~h*_A2=39vOuK2W#>rRgHuMwo7 zNy5FG*blDX&_vHcTxKd*0w6LF87@J2hmJDo?U{FM*wJG)rNVjB3oY5EW0eWQcIc8;4PHR4gm!@GZLz{=hhFssqj z)jVFYn^2^g#yA0leR6+`V7fZ#mBBn8;|ad|;qC`e`K^2p>HfC7C-11FN6z#Ux7r_jlxOZ%rlc8v;ldhb% znI2B^S9Pk=D0Ng^HeQGojNEig7wUjLeeNGVm(N>K=K<>AN-cr%TuUafVA9T~8Jvc` zoR~4Y@5nhUK>RG`;&AVhoI*=Pn(607#+k)MQUUuqoio;zi*lv$%`TD^8oSraHE#TT z_%R+SMPAg z*Rt20&O%!6YTtHu_s;aky!P4L0F#Mt+v>b7RrEZCO*FThc`ss7e%73*(M#3T zEQ&}}C{~kTQ9&anxsA#@_rGR6a{8S`YOj-$fKC1Djf~mgJ!1EqB(aD2kCXcHA%Sr~SU;^j&fIah`qiW{nv3 zbaXmZu=shK?F7T043N#6`o3eN>dI5q;#h}SQ|G~#=ZS@o-oMoGqsT0$0d(^Y2AYfz zi%thJADcaaxfr6jMZ|=GlXca$yjtRXfM(i!Xh)fBtvvZJmkV$u`ISvas`BN?6k!7N zHyg@^2`czP&IUdPNTeJi!}PXseM$xe)g6{0z;ZXyLaHG>#^nKYb8%Fxw_WN1I}V|s zA2`KU>y`B?l#9obSEco6DMnMM698m?-3|3QQ!4V=YOPC1RORPfv_!ZnmslnE_s8l*@>TF@ zY&XQ+W>`HlQK9uKfq{|LLN2B=y}lMKzA|haY-xqb=*p`c2@Ntuc&J6u_enQ1#+`Cr z=2eD81b!!3biSZ$~#oORPrjM;3Yp^SnV67g&e$v_J3e0@bi zAv`!(`@L3eS-i#b{*zUb)AY8wqA+Aj=r#&btAT)G`hQObYNQ{A2Mgy zy5WoaMT{1}C%CV7myGJT6_sg)L{7INs`_|Ew`tH+Z(_AVI5e9D&0vdI8%eHqHKk^J z+B-MJ7Tux zXz8SM<$b13oX&jL@Ate0`EGs0>sSNzK2oWkHdupHRcQOY@qY0hp)cj~eg z@!M&yOJZ74c^st{&xQkd+4F}j*<>wr zuQYqB+1>?v0u<{q-XG{NERPP$hsPRFXf%3SFB!F$1*SNKwm=a~tZiZkk~BpPnCHus z)Z1a8VWX}4u)@r_YGJ<{lZUvQBUGvrtadR zOGm6_p)tgPNrsm>Sn{M$!Ilyvvb42gZ|AeMsv+vtklZN zNc}YvWVQws#^ZI`jzNL7#aK^w?O1D~W^<+JyQ!Exs3Nk{@(%vgbb)lee5-xD{vVta z`u!qD)pbqb=FE1u+VMECx1~F;r_wo_CvasHv}e;w6(^69l?nTU=dsHh>xHhdV|vET)nJ+*UM&Hfdn}QDufe`h+`poYo>>Hveh2ODVJRgOBXe8pV-el{y(P@% zDp3&qmd1B@k*V#V3$F_NblX{fioNFI*a62+!HXJ;dx)k>en)JO)bu}_9pc`i+i9Wp zYKj)@JAqkB3>UL`!g3&)e2y`iJG#W{{6h@E$jhB9E&a^GaFEwqPw8Nlpmy z{&&9axes~m5TFW zO?MiIfk$FBM1tr`hEK64M4RAeq$Q#CJ@BY#w;^j|)kGd12iG*l7SCD0;lwH)xrlYU z^ob?o-)EH(4we7>rw-=CLA-123^3uC;McGI^zH9n{pP1%zAm24X2NgNTZm2!YhEj~ zN-%9svOXQxCFpW-YVN&~m?reM>kGHKH4VT#^O10J-Qa(Hae+bgS?vgqgxhtlL!$>sks&U1V0jVbf`%b?EWD$XNztvZ z1GVHYQ`ap)iE-B-oYjUxVCjDt?(S=@0{IOHwo*+SkxA zsg#%8+Fcn$yT^i;z2^yC6cc^sGd^Mx`qn!9UqBJN3G-}YI)n2q{{BD8gI$a#-8!m zqFVPoo~$x=N-SS#X38jHy6bQe_roml*ux8}T>7iQV`y!b>CXF9mcpS{i3@t3!t&#X zX1qX~;`@aUc)T{g={|rgVnxvUFslO#gO(CjNjX6Gpz3J>!J@9h3S!+fs)Lri1!5Rz zK>u&x3$norwJsTY{rcQCLkSsM$nsfrU%yX?(@#7kt9IU(o4=)>utcv6?Cg-(`OMOJ zM)z6-QyEN$dj!pvo0HBQL({1;`!9;DFS4fS$g_HC84^Ib7Z^sy@MS)r6{R%QRB4Ta z*v3O67X=b6SH%y5%Yheev4Pf$Z%CUUFQ;tdc1TYQk z^d}b2Mn37HsVTDB&IQ}lCdh*r47Sk4hTcH`R#Pyq@`A)%TYbfBl7+CK>hlWfhmo;3 z$Gzu^r}SkuzGUK&GgQ%K)g^a}%7LZQT-siss0e?g1A)5)10;|_jlQ14EA zdy}c#3NZ&d?`(qKtm?^n*yd5?JbF@zA2bzSEEFz+J_hJuXASC=#NVU`L-0_dvR&mT zzs9uM>ZUwetopaj?Wuap!KbxOXLc#t-og!4*(=N1zp`k4uUIGUDm;6*pY+4$4Yj;U z7-9I&up$m#PNi8&9N)tIy2VDnGU3ZUFr}S)IZcb6Zu)czHQwQ)UJP*9fE;YlL`$fZ zlqQ><=x7I}%H#PmyO_!73PhZO)RwD*{@`eV*pw%wJXp!)(y;0mNT2Hyhkn}wCn3z* zceDbqgoDA_H-3O9jf0AVT5F~>QE_#va+Giy=odD{K?D5~3NK+%WGEI6>;n>oSuoi+ zJ-y9N*`>Q-Z;X(5NIW^DRG_y}JO-BOrb(y; zz7i6AZ<#O?QjcGB_BM73w2lR9ZDWDWvASw+b>R*z8h&c&wlH z?#`KcIEb_##x}+#&i5f;$H%Y1Kui1~pcD(vX*UU#?GUD?V|q?v?8E zRL*^~14A>|wKhDjv^({V?$fmfTZ>r1p6m4m5f^(UQT}}!;^&Bw(|&#F4csy!o=d*o9y zGGpzP+}>9EgGQ{21H-e_>PNbHyWmy(v=y%0iwAIc<#9nT3;he&^|SU(79x&C7VUXd zep?|Rkpdi^RQ^D1FU4b&ZJA})*`zPX$}}KX{cVFT~HPg zHic24zC&aLGD&Y6G`iUsB`U)rg+J41F_|%9((RjmUF7WCMFuE?q97ksgjkaeuX-jP zc9C&39iP|ur%(f1U-7=Xq;@FnFDmlP4)Z~QmO$G)*tth%5mG}wCnCics0UMu-E zbrlPdC_c5t1?Np=)7!+;g<=6X#~n{@k*93q-3QXHkT<`ChL@GJ+Lvj2Lq$dBST8E~ z1t)sAvF|ln092%Xq!>1zVCswTy4Tv6MjdG}`A4)BLd1N@_b1<{uVr(wn>#xI+)e&|TW*jOW*G)wtFFgy5U=FB!*|PTIS*1sO*!Rx+}aqxU2KU)Et*CXHR_$Xc?7PGV0EF8Fa8tmli;2-$V_h zoD$0%TOJ%ky?F%Gn>5rLf;uQ^;Qjnl8T4hOqVN>fI@&n?R`a$h+1Qyo4EYwUMs3NX z)zY}Dg`Zv;y=2T9+ivCQ)j6lvL(VIV`msk=T76(NGZ~!ZAriW)Way4-PIbD?jr>sD z*gTaiZXXmTWGRoLfPQQ7K4rZc3lr%U(sr&yY8p@4@2SPGI9xhTb-ktPHxa${x`0wq zzmkqgb==MnIsM{f?*{Z(6_(<6yr7(dv2*>0@)G}f6R*$FTOr?3%zFhLm`lsf%|&fk zkonU08`~s?-$ay(Akla|+Ali!7I%c5F7FDa(UL1G1k0z+(tGNZ%3CGT3T}c4&N|&& zE*tkcJ$5=($Jm-wag0#Pj#ShR2KqF11A%4i;umQe?Z9c3K3AQyA3XsluNR*bTIj;R~}tKx?jdKkD4LZ4|64vX*1!m(UMgkdy-RnHKdi%_92+U zg*~w?^W=_Xd&A-*+1PwE(yA?6C6y*y^~MNu?Jwi3lVd?_bt2Iw1bY$ zbz|8Eo-~ZWWLBU_Z!DxBslLgR_v1UubE)IM>TLnGP4@~dq9S2|V4aUSM+g^9qii1r z7Aw~Ftx>_%aQZ9{BT{f{Jx8JduHCrSY=_xfc~hnF#nMrmQMq^wUfb>C?*C#iN#K(Z zGISh%^~cbf9a8!YX*h=isOKuBhdS}xRLke4RzreK;jASBayTKvSf0>Wq1RHbngg_2 zE-*g5V3FJ*7a3fjLvBa?=4LEf8mS(F#~hIO;2VXcAbI>nM4elqi^;9^exLwIO>*j# zgME%?SbMX=k+{fe74~5ud&m=vZ*>)22d^+jEs13O8(Wdhz9RvD96jB2taKa{a*A^A(9imX@) zt-`m}9@Gh8m(mY=M|*2+zS-}+ug{08NuU(#+o7acGPk^W6~v!lMW&c*b72&<=kObZ z!``w(TGS$wKKO8(7v>QrH#gPZIflgCYGn=X-WyXjr58DA+okg%O>OOKq7|VzwSpox z!}c8ziE))$Kp?fD83wxp+Cb;qtK{T{JzGWQSiy-^i#!MC1DClMz9qJHr56I6p`N3&<~Ffba{O7a=-=3RWJv;Ww&u$@nG%(2E@6; zdK~rPDro|A+gyxtIYdCDUU9VoC!?LP#@-a!*Aoz*FY02_+#=vgXG3sQD_OBZ#ZhM` ziwS9J*9}Vh&Pd4nEIFMSyD_sZOdg%?TG!MOwJgoeEf4XSVeb0-x?oIbSOZqICUtMg zbte@~_V?rKCvq*vuBwCPCT|pRZ7)iV;qw+%)FhMAPioYz(nWCL{z(l2Sbj)&SrX*w z_oG}eJ?nN64Od~E4;Wj@*q5h0{mKBv#)49maKdV&1FSorjR*sVlRoF4 z10dud^+{`VfUP^V7B#lzlpmb-$;aKIvv9cA=7!DO1C-jaqvLVCg#9uxU5D{ z4$yQvi>yysk$T{l>m4(kGp{>aGeXH+ z*0d4)$ct%SNSI5P4IGCtOM=YX)6qRsDAr1`lskl180pbo`>OYC8A6(gonf^6!5I8n z8JGO1gK=twrt*A6S9wqA6GUUx@S|hB(CY3*Eds6Esc`k(pwPA$??^ed_FVDzx}o_N zKxFqqF%Cq&u=G_%Ut=sWazjKx%V2BRp*DR3Yj{E+bJ0BCec0`@HeWhyDiH+cf%qjK zi#MLTQTq^PXK>&~@2J3w^OZ*v?6G)wAvm0{*q+wZui+TF=Dj6JN7f~rU7=&`&*@mx zlMYNEI=s$uPmFd1m2O9lvt!LI~y%b_xPSy&mt3!Ki22ytY?BvuNBzeAv5Vbk5xq__1_2W z5sKSq)pvA3e=Kd#tusLu${B+!t7VvRSw-WdAruIfzu}Q!6wioNu>wyP#6pm7@|Q#R zLD3IyXEQMoEv5zlcd-Nz{KJ~J8JgSDe;gU+>*2$O0(oAS4fGZkb8!uu@VC`v-MGK$ zv0@%oD<-DE#43^K+(=Erug$(0;)nCP!E&gT1!hm>7GwuAot#dlUvuESL&R0E8 zkY4OfK>W@ogzd130!2(I+D5+x5Hw^6Ex z6~AGChxzl<$=U9fBE^Y)q@btzFCVn+(7#w@@e4BZA_K-nS1grtnVe!Br3=#g7)sOWZSiKD!p zSP0lnunoru#2}Gc>$~-r(#_ej0lx)(mv3pJ4&HM$#cws_yrb`bQ(hBgb3egW?NJ>? zZ6`#j(h$T!{o~n)FZ>q%Ttr^kDKs0VX~J>)U~V-RZODCB%={ERy!ST7r=hYWHkuE5 z4hSDW_bL$3py(oC!jUA}<-LoFy=ih!SWf$0cvfc-sNJZPRm_>=G&+H;dNk4_h~Wir zET-0L#JH;&-?&OkrBrQ8rc!-*V!*XdHQa>K6}uqT#mg+iLtW5#1Bbt z$3cADDr;-CEAO3~L9ZnUHYM`Oe$A2{Z~*QTEBD=p3v4VJ6+IgC(W3A3MT|u0C{d&j zyHE2|7n}_b_f}`?{F_ec;)axIWtc1Pz40-<8w)5?E(bYbWSj%?iL)^tQk(?hlu!vWrr5?TmOjOY4KFrr zAP_k-sOe^xiZVejs@OQXqS7LmkXwY5M+7Z{$WGs6Z%*HQJj?I!Gkq*CaKr_CT^f};qWp;Mml&aF=n1Va>cmh*OUzBb zV^DmQf^kZ;0Y<+Vk7EKU;DdT#7y-?G>!O^y1)h|wyer1A$)!Z7LN^qp|8Ucx8!`~c#&+zvYe^2rE41Yi3?-qZz`1=umPw@BUMBx7m{N9SOA&m(7{QgfXHry7i zE4>OrDwC#GEFWUl3AjL}FV8}GOgnOFSAI9i-n=DnS;c=~mVs6yN||FX2f+nTg{&9fd=gIj*J8%YKS>mnB-?GC+jt zSkk#)%S%9~MVnmLIHYNryRMao( z%N>Dw%?&|)qr>V6yFHDqP;BJjd)(WPc#6Hp7G?*R_i5hlBY&|ir+8?}4}XNOpUE#3 z4p?I?7n=t;%-6i1MI`cH>)&F{nHH_W5=RxVTJ*X8l#LlAH#?`yBP8>{=sUq+BNEH6PoeP(qB=)Ucvz*(i+zwYo6iGO9MvJ3oH~UU1sexk)>kQCs-)^vI?i9Y3SAqaV6y z&!2MI^XE40>9ZNq@aL&bJAV3{(vFXvKAs(;F8z7oq&o+0ho z?AY`{A1^o!^I_8FGvJE;Ja^KLWZIFN_H<5ZN6+Ur?dcD>9NM*MXer-DQ7$(5!$MI& zHlcov`Em(1dM+{>#v;d#A1}z?Z!ZlAMqfdS3!WAu+XPJzcpJ0wXivuJVYxJYV+b{w z^g5t8ZYbJAg_J-|b>i58?qL#?jD(ljAFP#%bHADrMhRd4l zSmI3Ua112Nhb1lm6s0>IHOrZa#)csyAfUHsjDe=j%a_EjSL)RU2H$yI^Z=F^MXlo2 z=GMHaDI7O$do_MX^XSf5S``=pHIzoNJy<(WlNjl#>CI*jS$Q^OOMJ|YOa2nwxw^Gs zV{Sw7FyrIPR7CmY&>S(WU3&Jx@aJS!j)(UF05%M-@$0fFFDsVB zBiU+0MJ3oV-A7Lan~?>koVD;4gX=|(x{*=u@?qtK#lJVc%KkMRe(uO;cK$&Fc%2Shswk#7p4OdNA%cYRwrZs650ZcI1c2$>|>TkK%GUs@vB z7ipz(>wn6(FUK{RY!z{%W(#po$4UFZki*MrE&*rumamaigP@+=bhgG&Inv*0zrHCP7TdqEmx86O;5F%62UWDG~BycZy=x({~!%=2BZv7(q+$bVD5 zt1rm}tVT-nAlx=Vl^D&tn+>2&H>vj*j@<5jR}U41Y&6j5#Cu^iRbBAn$}vQyqNk*g ztQSF)?FVf*HlRPfB{|zqjOZyi;3CNs#|g_)$pyu-O=XZe&}2F!S)d;oK^RQ)0wcUn z0IkT<08d;IJp+T3M*xH=vKgsm6N>fhUQAc4(vraCj?mCv`BMty478J~l}(;3A3iLO zUYCR~4c@~r77sj_IX0r070Pxh8UP2_jt2{sz6DO?YN+;7x#E+D?aj*P=>Z!{if6}+ zrwU(Wi^tryP#T1lAlc@E0xn2DR9yus-&NgWq8qdFPZ+u}&n7sK)&gBLUy;OkvA^Gl znu7FO1%oV>D3hXOo3@s zj=ZqR7oTOajUu_^NM}A-+zVM4Ld}t}6Z=@33GeH@I7pLEF+i3nEu>Bl<$Ls&Ssrd*TqhOa?gU^qU@Od z*mem!G}(Bl10{8fqzikRQheosD0Z~EzX zl!mnq+mBAgKw(PrzIgJcf5N483k_nvt45TGkOaN83MB^z5YrjBS`8Oeo>^9~)l5f+ zx}9;I|Hg`yxh+&AsEcs7eKQMV&mlFHJ=)JjSxv zw55Hy9v4Tah1y!H)Mu7s!x4tl-c0+VQ$L(U*5Gx%e}2v>-ZN^<72s(qe)W|(gcAd= z|L&rM-)aW6-gPBNA@ioxlC_4c^8(Eb+C9!dPJ?Wm+4pA4U{twq%QR=C*K!Yleqrep zm1XD|q zS{`^o1)PHrQ2^*%BxeQ549zyu1>iO?H*vLlkxvTo+eBXpGZR4TA+{n&-OhnDVA6gY z`6dMfmzylhg}3djfR6W$Dx?>mzg(pbn!E|2D|Xq%nlJjzRI9wD_pyVqWn9+==x^BO zINaNLyxCpQYNaS2mf{&dr)+zIMRa2v7;lO0pe6bC(a*c?d0JHZmk16?$oH~DJ6w&nMxzZCAluDhO73RV3Yoe9s59=ov_}N?j}gsh;59P$DR~b4y#9j zb2BTN81-$mAmjV{d$lYx_Y>Sjhp70#HCC{j;fGUU5aNc(OxUaB2qf{2j8#@!{G+6jxfFj7q~|&dhfkC=weVD3Gv90Yx~~Xw`>^yd;^)J4ITd4q`6BlEML%R zP{V@lH^{}p2=mi?v}qedaBoj0JppylvJd*Ns*53lofBi=ZH)-}s6ZNg+k61O%@`km zDdJVDs^*X6YHqY1`S-XTDlU{c@${9!%F1}LF}$G3{B`*cuUc=r%NJqFRwNsUfKzXC z`$Y(eY}djbXD+p{E?sCOgaIgw3+GGaL&zJ=HbRVq8@P_K7~ZUX{eZi>R4Ohxu^U7^ z*btS4rD?yaL5mzgrOWlcl6TdfgXpF7EXbX#=<)wHaLc27v#wglZximvqAau`f%brH zqWpFz8~$73C3Iu`7)dp{;R9*r+Gi*aecU6iXjQ>-B+GE{XOX_Y_$uL$%N+%r01M!3>mV)U%Op zS;luN%= zV-||ls5!feqMzDuVU03m#EnG4+`Vn&{P2*B7Eu+N_ zf_w`X+DB-SiQX_cj3fEb=brHZu|LR*Cf_gTNULN~LNXEK?TO&Vo zn_G=)g%Q~>04fnR!>MD9_%ZLuQp|U!WE=7Uofe(#4j+6Y=Y+yJ7=qVa+T+eTSrifk;elKOCiZC<0F9c&BqoC zJBWlTHCZSgY_vk_qIQhvh9{S?j!%|*!KM(4pcps`LBLu3ykQ1QMih6VxzYA5_Lu-RwlsxqitFC3~V~UZyzXgSl;++8v~U zw~msl!Wi2q2QrjcHjL)uprD8mTb^_8LGU;HqImf0SAY8U53hdp`!7Lb(j>UeAGe*M zC+cp&hPEKZgdra}>1)K|UIuxYX55`Z(?*m4Us1Ao!wBcwDBehVBAf#W2+N#LkhUtIb@?JlNzTW;F7)MTk)C0r$zmLe4S>jo z+4Td;M_3sw>Y{=%km)E09400Z>J-msu|x>BjG&y74t&InN!=qXk5F;k)(=Hfcvy-0 z;EcHEDt3&Yws8m)$i0Q=+y5xHKUm7icmrskNJ~OcYM`1}H@73>G&?gIkwp+vEG|QK zK80@D9|hadCv!0c$ff6u@wuvaqDX$Y+j@xA(_i&JsXKB<9jyw0aX*f%BHUkZdpp{s z`b7%jWlclk0Q&A3}mTN+m;1;ZZo&B&M1n4C0C`4G%#P~^# zKO0*>NDk=v*rH9MP{RQn>gUY#KqL0bzVK$1rQ000Nz|NZ2yM-Yj$iyltERyKLGdE? z32l0b14t{@3^U_SdCJH30k4FyZGhdm%Zx2nf{00ysEsT`H0B1@t00kJ+f>x5UPTh? z4qDvLv=<^j-U+QBJo1*g=eVp;m*rCkRSbQCPF^4}pPbq7tfgH1>p-Zz+>Bn-qp%Vi z*~FDJNxF_*`163^74n+6wcl|~V6E!|afoR2jZ>%O;#xYWq(kRGfqENv(B{kA?|ttU z0;Fp!%3Brj=^E9GTZ+`R)}d>VHdU@du1?lkdUQq7BLKcWz48L>7rnfS`ao>EqO}g0 z&K3CwaOcM7TPtP~)=TJ)`KQGq^@Op!^c})oit~IKPKg*taGUE;Sl3>hMJ(06hJu4! zS&d;Nz@%TS(9kt^JB0Zp7IDT5raPLsPRz`_9oUNSRf?ujJ*v1W(Y3T9oOB#WC@UKM|r0PkZt>BjZ@wQ*aO(&E&*yLo%a0 zOGK90h?-(kbR7CA9iGLJFQ||!AW|AC8&5^sgqn+SP7jI2g%d}39)?k-_{qh!+#91U zmcVfk)y4KffgE&9-QLr-vN9!6o|@lhs^WAG%$_41omifa3a=^kn3|74`I1G(Xzs zkf!{HxM}i*wbhtJ!g&~L2A5&&xAZpG_c}_s%6(&=-ZAFUtS>n>rLuEWuk&hJSVstR zj^n_;j*w|$T&uu{DBBvh2o$3d#S1dFr;OYcGTi1{ir%Iqti?H@v>1@U0n3;cRw@o} z??*dv?2+W!Hw8#`BsTc}+SzBX`X96RC6y%mtIo-Kj%JBGFr8Sw^ymkzcn(FC{dobv zwFKj0)1t@f$x$xONy>0=eo`NlOFc*B6e$v6CqN!NQsTj0{XWZaHrh~tl(J99oBVNY zSHPtOqB+Pa{O{$l$@tACZ@ix{K)Wf6F7Kyljc9F?U{TQRQHk%rzRlLSO;Yu@w^_aZE=A$hp)RV9}tdy6AK zh2<2N?&xGdJ#clGI7(rSRZa^$51dS=GBC@9y&RzJY^-B(k>_E*;0Ke=%=l<-V@GB- z6QYVZ+BkvN6k{POFG$11DQ%eYa=O9rX?U%>3NH03@E-6ljT@h(?MkEeLf(jJQb<$% zUE#97Bt08HA>N179y(O-Ia=xa(|2bG;rs4;-+OP_hMVHOqVuAo5?C2`ckfSi34Br% zIp^}&Cc+z&*pS}Ci)~vLynH?@N#o{rAZLJ_pb~II!|xIF9xHoa7THMCoxq(cY*|9q;l4Bn7aWr@07O!KaXU_R%KNBJk3Gaf3kvPq z79d_Uf>m}gN_5U;{6+`Pe1YP=ak3wY6UCK^-E}d$hhp5s6oX3N*gNq%)W6W7Mv5EI zk!6m{fp`aFU$`)Kdc9E;WF~ZZIwwGMRyUTNbl>WGy%Ddc_w4x#5`>NI)E$R?Tp@kf zk8x$6+%Se0G0cpTgpf!KyrI*xWHp(S0%c`2kausCAUIpj8r7 zkeF!II=2?lVe)MgB{JKw;r#mkC zbUDv(O=rD5=gzP0`=girmQo2~JX=X^3k zxsK<+zWO=y3G*2XN%KXZiGwb3^k@?bb1B!JNo=Et|IWlG{Wj0~+bP|hY+r|JOJEG;f8BHqgHY6#KZyTASN=dVtmm zISOIqOYbrJuI(y&UDD}Qz8^`pF*9LOQ6*JF(n?fm{F16n-QZ9uH|!{NA%R3D$+fPCgM0;)}cGX^eBOB6O%R`XB0shiP8Qs z9s=X~i4j=$gEa9GFpY76Vw>CTZ6%;7yS=N#qre2+gMgjgSg#Oa%Ukjx`z6j7`MB^WrEoHU!OM!{~j8!m&gVTfUQuh!Xl|vaSsZ_-0*ZvG=B=yu1O0{zu(p zUJKfs-*IuNnvOC40Sx-h2N{0bZ^b&!iK|y3%$mK!OvGN-`@#oL^R&zt=tzSZa3bxP zH2bzcXAG;mxLzT~s5{mIkVTYQ|94C}J-G0@axZyV^Fx0^#DbK+)i*MX5>i?d*;N%K zv05e}5p?wCqIE_L1<Z?+;pz?69dSENT11E6bF9UtNRgRS~ajs8ZHZV#hhF%9;o` zN&!}f06a=UUxOV-w$xB1hz0IW;4_G?B`kARTZz`MMDN#xu_idpZ98S~=;l6t`>UvHP>zA-`%V`UD7jb+yWHtggZQc~`q^;Y&A zKX_0|hj5qc=qOq361^o%7t0o?_RM>EM-1(++V@pQ&1PV&VJnTSg8o6)?{98&*21Lw zRki>{1(}){;WQb4q!5>|B3D#zuWm41&6+MnvaH4lVWQB*B<(Ywj8y&MRlxaxzuXY{ zd&DlR`gM6@Cy)#w-(R&GVsYsKqke#u^^-U6l>hdHd(T9V9yN$AO{*#W zs;oFa-%9;%9lQ;sGx4H^4b$@dDrg_tyDH!Tpcx8M9 z_~_>{5X+eH3rL~KUy${EX>%OcK zFOyuYW)4)w+AB))Mu z33^ZMFmmXIo^$=86}{}_5$$ZZ{D|{O0Fw^ifagV0^V2=e?gz2g_5^W752pAqkc`o- z)yhj-_it9!!5TtdNy)MXZ`k_exH4}G4F`AD+|n)47Fm3ML&{QMyNIVMT2%Elu-41Y z@?4qMBy5m#+hTWSupkZFIm$C zqSxDPE+w_SE2$k+q|KsFT*3cVeR$h~SU$Nb`>StNMA8S}$Wgm@K5u&v@=K7}U3YPF zmb+$rIE)4g)WWuT?IAXAxn51K%QdL#`?}Gp{Lp5;2AFj7_7Z+sefUw`kht6Az%t>- zs1}U>e6iAreOFNuzWXaNi;W`^6?%gm4_!^6-~m{`uQqfBlo! zOJ{CWQX2O5w%*Y9&#=r`q!hQ8Wn=Yn_iC(66MRYs;43gJ)h?wOO3H>(Kr;U|HcMU68k3(YXO~vAxm#_b z)(PCH=7rhW$fH&ZzCq_(#jk5Ly0~dY$CNa=7|;xB$tul{%B%$NrnqEy8|@5fik>9m zCA6zxm1G}@ye(RxU|LjyreM+XOu%#AHkWF0mF6AqCV4^tq>tJObJc{H%3un-fj!_ce)(y3$BlhM3^--BAK%MBaN0+tfvgR)D>0;W`oa)B6|21Fe zI;yI~gj7%}brU0T(&}TfQ7#MXlP+t?R6(Bq+tzkA6N7qdQ`?c+ib=l37BB?>SZvDk z-y`LoHB_TH#vK6?Q=dU!>)Z_hKS030%ErUX#5R)J>T>H0TN9T#D4@2G`T;@{j)pL& zXo62Xps0n&L(2Sct+|fO{bq_U_@LP^ggkrp|{>3)Y{#HwQX!m6ynu46Z zIe0TY%jBPY^#nlI8{9gxRKN~QQf+8WQ^4AbS3`OD)$f1v<8OZc^>4n#G5(sCW?jUI zJ^(gY>)=b4J_37-T1XlJ^HRRD;5e|cKqqAH$?F6sf>+Cz137INmYB8TOk19y$uc3Q zBs-#^=@Ubr1-Fgl5YO%YRrZ*XVP@SREFwt0dg$vAFp658PH=?cH`X!k=KWpKZBxVU zw?-__b9^5ou%Yl+gML^@6Fkh6YEUw=$YJI-5t1aj-Qkb`sRq_Yn(mE_0AxIW1FUo^ zVCy zzC5~5kG)Dsca=v&)>nxNoANr~r_HOPxwmACi_)OMdO3z5;nWBIw}1OS;HkRh=|n?Q{3$6Gc^5O6%NU!~;bfxRx&| zBpb#8L{O^%DbPT!xea>CGSr;#Sf*y(N(dD0iO|^4jTe4QlHcjFLIv-p*grgwEvTUSjv@??9p~Lj0 zgjuI%uc+N|766QCACG8eSV^86m&uE#4lCLA%K3hCdS+9LA{*r6 zhTk9na0Zg(BNJDDyMNjFp7RMliKyA>-13?@3P9-Mj_2lrjrOl4dXuy)?K@C`W%(oO z8`OdR6!ec2PB1Jag5flLZgYLQb^ht5W=aS4?e06vR4CtXb;76U&w!1)s4rdhna7Ik z6hHS~dCQ{9&6Xvu_Dtdq?YX8q1;@$>fs)N~u%f-wk1SaL3k=h}Y8Zg){?}D=J2A2c zijFaKn*)I{DCFUHF8H41uH)VY0aAzrBl4tIjedL0t@_^YNIeTxF)d;L8690hQ*+j! zQjlJ@-?U^(@g?!a9+%v*meqd5k!F+|*lj?*XR43i8n0oA zN;O=a5Ts%$wWF_zxs`}}rF^BU17Q*^4~gaU>bPwP;N*ffVDm=^ye*^C`1?@*7GeDCl6-# zLrQH)^6_X8zJ_0_nAXmKqE7@t*fhEB-2e(oxsVUno}-IAejfp8$*q)xnlsX{hj2a` zdjO%q@e&ivUpjF7G~G2-#@YNi*FOVvqmIxRD8_^b8mHU`pgxa3Cy;U}eBFJe5D-lz zAY_2kfVpc48n)Lrzj$kVx@-}4A2|e z=%BP+$$xzu5`DKf-Z0Dr2=mkBZ2m>vl`glD8{t=pSWb$wgk;I7{0OOu%67cD6PMRH zWo2tDj-*Mb8HF=kuOsof@;^_OuN(Kpk!)>Jsjam*I2w%x&}cLo-LD@oFu%WfFvr=f z`!2(AE?KM%uw^_IhAG^{;8GX}4F^MWUH6ZMm!0@^VsY!k4zj{okF;RYlkfZoPJ00P z?@ju27yZt;-Qo_7PkGe%?@st7(DJ(BkY6|-?zI2y0|tibKK{gyuvYk5On*Bz{i*18 zwg3w>+hj9P4?sY?h!CZKmHIzQ^cctn%*xSK=1EjYDYLL zY%QKI#<&I*{Z6^Yy1Bf{vW+*$4EY8pK9q4#oku5c9{mt;{v2l>RO~zB9(9{hUNLqt z^WfAwE3UW_%>(%esy{C6b3M{nds2x?Gkth9&O=c4@rNOvDn9u?ZFYYrGdo6ABguc2 zj&_W9P}%Q}dE8W&fmoy{_!=239_0`Asz_Fiu3$$xdb6N4fb>Ag&cuzxgibXyu^li! zCB^@cZjJzjjpb>!xk*wCXQ@2BWPu!P4K+_IR34!egU{0`LfoL7Cr2KlY!&b#zD*zr z`6RMyFr0c_uNBrWK9X6}voD+sTmi#+j&CE`HPX*(S^_(c!#|E=ICK}Sq~Vo%ur%MD2?$&A55Je+)08|k&vJCQNnh>acU%m7L&3pRGhDj~xC zeY9~2G~4FiaJC*gemj=z@@u7M&FPG&KI}(S{n62Q_&shOIjhYQ&gVT5-8+0tRAE#h z?Px|&{mn#ppZ7#nJTA63Ro?@*9`6S5QW84jkmn~kR)JSjRFh4r04@od+>a#IaONg` zW0lphq4pDkMQ(anajzKw>{>_F`uZK7dW|~|vQ+ZI+Lr+je#d3O-QAfRDIJ#;1t=b9 zU3u5{IR>+9wA_Kf7^S7JC(^F-HHx6^Y(o~9L^EwQ@Keh+@H?{?nW&tf)-9@Pu`$6w z4Y4w7!o!VIau^zrk4AqKl>23x)qfS<|EKXHC|SChnKw$hU>hO^j)fLu_S9m9-$nkm z=OsfhsExIsM;*8LLx|psRd@b()k1D$pN1ow!#4)G8{d25%Fhly%Gc?T2{U+7j&qLA z3Arw?>CtCSJr@{Bi8hh-u_>XqgqO{vr=%f3{FfhW`F@j%{))-Ui4l#XpvK(<>ricFGYn714Qmk1c>W zc&>47cBDC~Ki*v2*YNNYOxLKtoI28DDstaG=a4YXk2XtC9@H#e7Wx-C{L*kD)Q>y4 z?JB*S%FOS(SRhhYGs5=9up-wc{Y|)Rl@?p)-I-rn8ns#3qIYub@9qN>)t}u32xDKv zK$Kr@M%}Qqj73!Yq97?C+7}Uzi?4*0zYlS!Y1e^G+eOf~ojrsElT9N&K-13HQsH%XmvuJrQ!ph>Ykz1VPG0EbTuo!Sj7lwExtOxIxQ9FFfB>ud-LI z?y&e%|4s|l_nP_k3ieU(&0p{s+S^4iiWjNFKO3=bGmuN-1b>4&+KI5g)7ZQxQTca( z@pz(g(?$qMRI*4k?ISkNJyKMOhv{@8)Q@p`JmOJ@!8UCgr!$Sy*$$k3(LORt4cqw1 z=S3OKfh_XbYh8jNC*Hf;IX{rt;OSId@jVf$&_i9Ju8i>hxcE$5_?bSj(u{@n@6toS z)rh>GyIhBL)%G_XjS0P%%^9WsNl%HlX?zTrUrR7av@&(9)}yDx=QzsUhI{~!!@|V< z$V8|gX+*69fzKyhx9UDfJhJC+Pb-?o34RkkA1AA><;^*Vl>5-eqUE}IrKhCc&QNPd*6sPP7BUHVbiTZ0G0rhJx`+0kQg%%3Y z0>)UO`R+zUUm9UYJ5J_>&tai-^f1xIrQml!kvlzzh2sXZeb;~SRKSUY0l41Ttf|2RT?Vg8%{$-XktxeNZh{mv((o$^Mnb{FR@Ob#irq`BI3(C=t6Dpb>RWe` zsDq-WK;RMHgg==UDb2U=>S-deo6jrReQ_ux63@gTkSY*Ptvm6k%+6(a#=h-ToyG*E zkL~oMLbI;Go9lZG{ZIOn9&Q_ZG17it+~17V*(zaJZ>MB(edT#aet<-i>Dpi>VC$_- zelSbV-Q};IJ%%q@Rrr`j9Ijf^6aCC}OMHmX>8%?&y(_IRaRzhR8Q0Bw>`;VLEQ3R0 z0|z6HKkO^7k_gI6M+<@?{$Q5S)J6fvbM)PvpQfsXO&ns@`4vT6rW{r#t~oh1M#TYb#lN86qT*7? z0fUZXS;RY%Z8!n*-yHFPw;yM)zv)M<4F>029D_7#vm(xD>`6@0F z9`kghK^??t(DRDnz+I}A`<{cT8oZU`n8L@BD_1C2`k)Ae>8W;B?o3Q>s+vlO^n2y` zZ27yHaa{16Gc_DJwMyQdHU*srrW_}YL=IgB|A1m2-%=1Zw3bSAJjM9rw60*1z;qK$ z+aOj9rUQ+*_My}3-hTZAb6L`Yr*e6NeSqxMmM_VFNjA`xV#v3;C$z}eti%0s1K{Oz zU^aJEFE{$ZUD7vBtKA1pJO&7?q8=D<(;prc7CpW2DcoR#xbGU1yE`d8OeSdT8%!7* zT1OGR(Wu*u21P9`^k&J$w+lJ-aWZs>*M+{Wmb-_ibn5OJbe3OieRrAlcAFaY&=;45pf1wx?rf5t4%+X$ z3*MI6n&58w^}E`+Bu+IjNzD(t_6oNj?#fq5#*?72aU_><(wUiblBLAsx82R$XXPe+ zJ2nb75o)Jje)YTGg1H3Kew=*dmyO)~*N#&(6Y?V%Ealx3Rbqm}YUi-qFG5Ev5BMN_i3I{(12kWq{J4-G67=@%*Yl%s)tZFx9vN@In% za0*P4gCbAix&e7=KKN0wVBfy7x&bVKQHA>fbD;!k^||%;ojemO*U3qP?8Vdx8O}iq zs-A*gV_(om$z!A<3?wJxpqj$f@DYP`hu~G#SKJEZ3}<%Q zg&+fKcey#gNG+4+v=Nk@@VHe5g1^Ue7*kl~C?R%Q&^gx-fI|7Fc}mFHOspa>j>{Sz z53Q5qQ`ZDS8fo}fCTB^JCtArCJRyvW!J+E4!p1=o>m!2+DK+f^uD#`ob?kl9dh)R> zORt8ByeApl!UWal#<^{BtMO7dH%+FOw2ieCIxkmk53bZztfC$!u=Z=ee}0B=DWGUrlvHW(l=npLINZF=kef7y&zISlX>` zR3s6tGK3pf0=!TRkC&<)enbjzWiU+iaLe|^i`%W)`799S+1*W|$bCi>)zV9=19wZA ztPr^x7)qzsOP!XiF{rZ*tW}rQ;8c6-XT){GP`I{1H#uL=1d9%8+Kk(k{`RNdrcYsUeaZS5c@U;BC6b_37Du(r*KYsVpiZDp2p z#wOrbdb_t3P1619(%qD;Y|~_I9pE(F>s_UH;{ugv=epq)H85;xlcXwaJstoSa57CV zQHfxf>Yk%&QuQ^4a4+eWy)+Xr*gm{Z1W zbNXo04`RewCMz3`(?=SYitd4rA5zn!iHr=v zk(0(98982qtPCqaPG+qlC$pGRii2KrSfCLpJC=Xj^n+pasP5-)cz649Lq1W9d7xrZ zhn)PT?gu_FW2EnXZxxpFT7XfjWQye!Yh;0U2ff2v zJ1Do8l}Nolw{rKCH)%<8Vgj!)uUh@SQsYru^F4 z9&i&Q_?vS2K7o*%2}it>={faJ3r(MY<`k zCAq=8R-q%oQ>D^`kAZxleLaEe9Jo3U=IXv#$D)L@O~ICND^ z&ze-qYG@j^f%#gMfg+e~*;$+SBixroljCi58BUD7xQI74o8;J_)adYR{PNKVZSFHd zo77kcIRYQ18bnBZQUW(rQ^h=Iuu~bK8n@a|0>7W0%!lf7zq_g1JNm(@Ql$%S4>%}^ z3Do1S2Mh`-I17Mu)hacZ_6rr~ngKc?K6T5)B&IS7dwug|wU>gaQVYde0i{7%NSN2}(0$1NsEkd-KWhQzr>g zz7ZTYW< zc4NIwbu>!F?6fH{`#I0CAD{nRK)K|x9bW&EucTQA#rpb^YSl}2RAP;iB(SM5UWqd} z-PX@-*|wr>%7pw}Z9HYZUxBkt*{t)-{+p)XR4Xt= zu8eFqa2fZS1ObcB3&uW=4kky0&QZ|jRkN(e(4lq$Y=|;0GEdH(W12_N`0S$F({&@& zW^7mPOCB40d?KrIdvjglLtR&&m|ydwr-zFK8p=P6Q(ZJ-NS}|WtBH7PQC5TX!_A<(ABPqxZZmN5r3K0(Oy zqxVvY?eQi4#I3nnN@j|TK5?P~yhNgHl=iWXZ9(9b2wM-!iV4pHyx)L{1Z_aRt-dAH zu-QWh@|LUn3Iu?sN5^5+rsb*zHh?=ML!R2&P`fS$f457QgdJ`U2ycHzUf;{Lgf;0N z0BU9rwLSpIPw*9tG1@AJSW>Ter1yD<1^HF1YwqSGi&!Hst}#@(URgdT5y%t+Wk(D7 zkNHf;tVSnRY-9DNRB7W3o7aIe*EEfTp^S?ZB2KdkuB2m((WTEruf{fSD%IN6>@7>w zk5NhuzvC*aEw)m~_j!SWTrcSzK8V4YZi9sWuc_dh`Vy~B(6qO#44i3y4}LZZJ}tG` zQ&&t7{V8T@!hb_bZ!GMSFgw)?(Um}B^IqDafWED4a{8nChbEFf zT1DLR5AT*|>R{IuItI9FhK@j?eP3V0v!Ke;YYx{<#3njF5 z4a*G*2rVif3%qB;!Jjc%%N8qhid;h~&gzy&WFxmI$+$^H^f(wUX`$ql)?-j?NrIA7 zaOa^w=C{TAKs504z+IwS0GF|(5u}F?o@DA@Ki2@7zIb(U&Z^f_wSBa*N>essjxI|5 zisM2`9xs12)=MJ9h~C(LAe>vy4(yk3UquyS){ttQ5ax{WC%B@)HqVP#$t5}en8hth z9-60|k}GF}zKI^Hf!;p#?DgB^u52l!J%khd#dApaz|h$blB#B27YsvkN)@vK=UvHL zZt18vuT9wLfDN<%Q0!vw5A;LBvN>5FaHR=y_?Mj~D4u=sz)^oSNXl_V>0z|mW(aGM zFV0Yt&um(EO7J5uT>UH(5Vf~Y$`Xx&>bm*#mu@<`xFMgve;MGg#nI;?DoFOJWoc%}J}>f85e>F=3s|f|T5+=7(DyiCNbgtp2wt zI3xdvIT`rbZ(kiqqc*ojc41*cIt0N({`I@|?%n$CUHg>w%8~YoO1*wYZX<*1q~mAM znf4S^TF>Zs>;tzgGOoUTZ@n%x*u|Qn&@;YO*`2P>7M1Ii);Myi3SlTv$iloTA!>gq5JGHizun{Ues5(=<878RZE7`ODP5!?js$a zfI`>LW#ilghrgfpQp!czhFunoh(%(g~NPqYZx7PEcvOmglX53xxH3E#;1$+!#25 z;;ht4Rgt*KnyxWx%raT$rPjVo*JhxxYve}a2%O;!2uqHC>bc#heL@c=FEWMhPpShc zdt#-2b@$|Hq1|OvN}Mz$3%?+s&Z@i<&!%Dcad7fGP8=ES&^3Rwuzs>7yaxfmaUg9h^p@Z})fo{ygM(yh|2oqjk3$db3D9`ZG_~ zQa-%4ThDy9y17|>1edu1(+nO)5-y9>UiGruv}{^own{sjn_}L8CnpTyw<6hKirX)6 zxXF=`Z$BLprGG4#hy>9bxxN7nEo`F6F^x^ipn-nnI8eyw|t~Xez8Z5@y77 z3Z|3Q$f3L|jMVahC#ut%AT~NdC(SoZR36$#50>g>oC&}?I%(&n+H`(Z#}Dx1*=P&P zG8#bW4aj^I)99jI79y0I5VW~@b7}(1B_G1vX^-!_4n+#r27mpB37MUC{7o)VEKaWH=jmSZP4xSmnV1m?Kep znB=dy*`YpbLE@vUjg32x^KAS}rM}GQAVxJvY3-CfzX#W3y{os16izKW5U4%<(!dz- z(|bpz*Gj9#zb`;xqXX$qJL5j_Oy9Fv1p-5pijb#&eb>*Ps5`kek=1RgTq`ipUi6e# zLP4EU%M3ZS3@3;F%`J_YYl+hX(C=<@0W2#9$0wm;pk+u9ZWg6@B^!u$Bz1EeGT2 z^kmwQViotA&*>6qW`84Km2eG*kRa5r8Isr zTK48+?p0hjA zU3{L&k1Kr~+bv(NOpgy9$Kpj()+zB~&yyD#06Q-O%cXh=Tl^k4DB+LY2kH17oOP~@ zWY5`1R?uCRy0C9^CPsa!K1C;ssOS6`n>7-&56-t8&g``|`VTH+xC4oYo?mqr1P&+{ z>Lzr5{ryg?${Rn{1pJ+g%6VK-l_<7ADmjYw2@0v}2S2D5MUc8LDqOgZ&Vr#p<3yFM zBB9HhSJGH5Pxf(A^AuANL(=ms3*052+fJ?8sWa{19wgUL-iwEq*8zfU4JCbZ7#kPU zX@iGpM~5Pd7}3CkIYfBXoke?Ga*yx}TYV$lcn@ZZwsafBEl-n|-a#0N7tLwAuUa}Y zk4fUdpCjXI&PBP6UoQ6He$&sMrD8-d4Boh=?egPDptb|!GD@azwd_QbVb1wp#ModD z@n@%Z?v??#o~JD)U~IX6c5-^S|Kqb6-q*c5kUxu)rip8qJEq^>L z^ozJgT5+`MGQHt!dRMJ}&w5tf_7XPtGsV>?mMNU-i3EL58IGm$sn144^DtanoG=c8WJ(ef{OC!|ihhQML`!)zbhxP4+LF zZ=pm%Q&)!83TrV)Fd4z>N}MMSC#cSC;GM%%_x?yUvvb{dpA^_Pq&2_82v`<0rgApz zbp_s0o}NyahfKtTmIHh{o+47yrpEV01xTFmvF`ERcKq?7Sq@kDysDwFP!%}P!26B@ z&2xf^6vw(OPGJB3a7o1<-{SX2{&iVXslJwl&`EsZT?T)_V`uYEddj{+BE<%2&hZmD zto|benx#Y!R`B@b6QoSo5IP*o6kp1LD^l3~GAF^tkP$*f`h*YySd_3CdJVP3IzW}Eipi5B1pG0k zgFTxJ*84DuMFfvSs3N)&TfgEFqQd_x#$?fA<_~0>M9|Oz*!|aMv!`_KiA@@Lqk#N6 zt4(Mj@Ed-+Td}jtTC8l};%GdpAefC<&w8Xrl;pe$c_gM+TWf=Oj#ZyrW@3XaX>)v~ zEfhBpW^|=xd3Cxu6PGA)d0ZYXF14U@QO@=*#dWD^K>S3#ADI00-Mjwe>yznZc5_ho z=haQEa+ar;XT@w%Q2rBg+&Ynt1+I$}nCU4-=&yGuT*RQRPmdVX^a&RLuuA{~Ar_$sx90|o}5ujxwXA&KD!f<~VYHPAt{=@hPD8-x}3k95S9Jjy;f( zh^&CU7%Upx1GbXn9Y>p-o~Yt;w%5V>7&JLMF=+9^+92U6i>gp|f~%BkQ72B1jcD~i z_<^S5w+$wHdPEI`m41J-tIB>@hwu$dhLT1*rm$x+WMgrUH+vY>8Sfug3X)TjvuGpU z&a&Nut=82z(-!u-byK&P=|($~Sp;1Xn9RFfXw(vr(zqB-4(Ft1R))IFwGXjbFm+#i zgw7FPJ=^K}&3A=se%r?e=x&nSr9G`lA$IiIeGDQuCp_9Rw@Bg&to!Qtd~u~Y_ojpq z`svk~#=4?|t>yRA9HppEQ7DRBmXaom*^Gb}x2qrgzy-P@puA7)g0_(ElrJREz4EeP zNA5iMHvK1;vm=#pSzd6nTf+B>lsnn6TZ+rXfT8mMhTRTCDAuPNj|u`i--5h8fQ&3n zSKHKRs==ZIQz6`utA>Y;+!44&iazc#v8s)dY#wt*T$Zm^)lFY3HOnm%ZyuhY-pJc& zc_CH13cppAFHSc-wb5tVr+kiGDMR$|j(t3s;#?pF#rgrrn}j&UiKk^C1=m}#hX)rK z_imlY_6IimAySSSl*CnBXuqx=0xYiKxb(o6N>9#?pOl#%kRrZ5=G-y(wEKS?ZzS$K zSB#sC`<5u`ECHL$CeLH!vR0oj_;|h9x7JF<}5L!+!7FMEidK{d$!K8YD9krNq&=Gq0;)9CI z3co<+hO#Rg8!%#_e**+;^1tx9AlUm3HQnqE>miyrJOwsE7at;fC_;q8!ZJi$jii-) zC0|^*?1t{XO&tZ5#v8JA6g}?MR8(iYCBF&=3R5}HB;8WT464%p7zmA`jUm{=x{L-S z-gep{VQO2*-%hm3EuVL;4TB!{WgB_sV|NaC z`{}uF^K{eXJ&oQfo>QE!t5Sp8*V@}nc{?c(F>wk#$W;A3!{1ZlLQ8eVWdsWn%Cf!0zsj2OvNAZalRMeO;t1Mn9cUFlTyrm7>tz55vgnti2_E zu>fBYm@aMLjFQO2v%F7q^nBIzJk6JM*1{?3;p2W})-9-Vfz$WsiVD}uMS7)N&>A69 z(@#{BivnDgc@jSj-`Nai^HNSNzOT67q(VJZ&ev+|8;4{_K$;?2ys)-ic@t5fIzDpw1LJ;8+)o?^9p>ZA!@B(c(qnWu(O=&j zz20e6%bd0@3DBY@#~#_{2&(I7EpJFD`O{*w*I{47ez3{@<9CF>-nS=UnV;W}qzQf& zz0lZx9J)1xABW9l^N_>v2KR=HvJZpoQe+(VLnz`s85xJJOFsmVeW(aI zIvA1T=8mJR57rff&0#P2fz}=uJDUA8#$)iX{`f|nU&t(s?|+U)O^o?2@qUqEp;fc) z1PWl`cMu2f&*~%U$K8}xRN6#G8-6i}K5tK#-Y$)eq*5!I2T=?5lD@y+6)`1GyE7&x zY$!F!M=9DfZ30+nEpFa|tTsE0RBM*g!Kc~U4E6xoOlp|QlzkMphfd51kgxmyib1L9 z@JY3dZP32gGw*nL++qQZ9;k4j?Z}B3I5!NxJuc11+5@ zBs5<)-!>HE6hs*bnY^G*mZgSBQgyx4PVer{cQ@I|E~@$*1Hje~?Rwl8%%b(xdSZ9G zg^1S1t!xwS)l#_w(zpfCH?GPV^H!S%kFgLlmpPJf-KtxNlYZW-@P(9It<;2Ob4Q9? zbnspaODC$kB|lJ^^S`A^V|V@WIx&5Brw{qu36_S*L%06k+^9nwdG|D}&v7{^P}qg^ zTA7>Wpy6`|Jn67agnf^I#fOXf9!%B*smz3gU)+xc*NVQp*!e1Bj}EWHX!PyIM%r0+ z!S0q1kj6V%gXcDC#p~+UwpH^6%0#8Ru_56Fgcs9&vW`U2+7HpKu{_boOe`{9-{&lfF*^k7jt#s78nk({RAz`S{d;{_R$dH1s|TkPHJbKqG_ zqlMh?r)=}hStNe+^yBytZl$IJ|7_$vF4jJO%L22;xe@)zho*%oFUAp+l1YV(Q9{z8 zo)D;2wzJ6%42X5oibUXn|9Bay#nNfS7U0Qd7UY^OJbM)|zgRqIjgVtRe*0d3Z>%2A z%3Q?WkaeI~Fa_E~k#Hh5j#lc)y6*Mm3VS2UnKPc7BIpc9Ul)TvAHC_Z;0tr!IIg>H zxOxEs|D723)1JT8`#KH=h^eQuOBEqXJM4hrG;GW%(t9mhHb&|Dm$01a0lSu*LODBM zHP`#H{eB{z(x+_#-90$3AdY{8bO1FR2V4^0faP6a*p&?EW{OFz0|WZLn&$W(=I+pD zB0J{&p<7^pPQf-vJlYC+K+#kyj;c48VHvg}_QMonFz&=TfX#wI(l1fmw{)z`G)O&S zA(SwnjqCIUxtUoQHv#b|?Vx$QK|qdca@k}n7K<2k9$QwL_w!S^G$u3w@kdT}{NP!9 z=C{U0w<2(oI=|JR_E?!Zsa7AVk3A|!G!H$vxhlhtVj7HbFe2+#z=_`b z4wC54*&p*d59U{XK^~M#l+7L92(a|d_lqTFGS}+As!9A+qoCW$`{d(pkF{iDTn5cx z`7D=p%MB`^nI>)6)3L@BoLwzlb?oC)zNqTs76WE{$xhLj88aS!by|8s1=xAqn8>D6 zKlA0!pa1q}ufG1-@87XopnnA2FuCr@0<%wqn;HL*={ju=L6;RQ5+)!RsG zpr^7}gV8^)BXxx_pXk0##5dzbVpnrscIEj~b8~vnt(lkO`|NVFZUT>4ab{e{_c#=_ zl*w8~KFy+!wf{7RkGoPY7<5Du2qd0Ap z$1&7Y6uKyL=sH~N++eU)uqyry7=#NF)*(B+*FEQ)=^{* zH_iG9a8ivTxxs>J69oq8rog7~j^ljFH}v(A>i*HsB5eb2pibJghpAHkJSlILwrQSv zhCVeH%5}nP{{BEZvDwjVIvoG_Wb*HS!6FAI%h_bY9GPd=JoBnUKe*&0igu8!ZT+Xx zDE|$4M=lci&x$W_udQQFa64Ne1+}0XL!J%ic<@$8zUOhtI>Y~;=wx|5uXlt-m-rR# zhg3$;2DYp}p-FBNr-9LuCM+b*ET4kj7H^WIC{ljJaT(H;lJKV_X+0&~&$U#`Oz2%| z{f|wX7p)STsFzYh}5N?3Byn@HloGZ<_Y^IF?`psJ68$|+9N55}W+@tF6fP$85q4}j1NGLVGa zW(gHJDIg2ZAg>>IUg%}uT_HJRvb5=48+fabrcTTPL)1z66H3DjG9_HoR133nZz*CD ziPlLRR3g8EgMy*JU#KqdfZJ797R5Pf@L@!zu4maLja!KS7Kj#W#*!nyo%2jOD&+HQ z*~Z?38$sq+6Z=jZdzp^#U){>*_Jmv68*S!O`yx|M0piRK?3%KzBb3I(W>_?Iv#!(W z?hS5$bRK&Ji8_%k)J6cnD^rjzHlIe2YGm~oqoyWi#mmY~*kFGiCO9#YhcU3&S?Briv65mb@d{MowtP7e| z=)@V+-YbfT^`h$_Ftx?lay!@C;8oZ;i7c{!Ew>hBSSVNaAw(@r1E&DDq%&Flq})j!IwO_hs@i1Sr+8rvm9BNG*9* z1fOV3=0o}!gx;E!Po)m;7oF&Rhk_K!lvp}B6#PZqd=hGcFCqnFKJSEF%5$~QU14JB z2A3F04T57V6pWPwh9qh1pkXxW4J0aL(6VKIO2*OxNCRZ>oT2w z{kkq!(;g-Vzz%q=(Npnk&%Bl;duv2EIhppF$Q?YI9Eml>LZO^O5TrSM-`zQ-1SUR3 zV=uP4Nyrj9w?(eu!t6@yGJfp?nf^`vO?fEfCvgl?!I=m}tl}dIOv9@1FrsuiWkNxr za_X&6g=2F9zeOOvSIQ(hOt20Rbn&i1O-2tY1S#asOI9cO_NxIGz&zo?a)ls~OSQB{ z*Jm@A5`}S^vS)S@DBsmaV$*;?fGqKnpe;s#1VBp#BggMF1XVSa3#D2BPcm&aNN+Vn zp3(?<^RsogxyjjiScK$0YQZR*R|Kd0#bt|~I1K4U#nqcXOEG%MY^98V=Ij;Ot`O@( z3abONUU`sO!iAZ7Tg_i+fsz>qei0Gk?OV9yh-k42$hiY6g%bL8TUB^fH5nF3N>Tr_Q)1B=g0 z@)^+=u3*h9Sxea%|ImC`&_~&$j!G#hNS`DALYKSUP8+*T%6rec^jM?4@lm+HsQMby zYp=9a0o(J-*!?2N0QV~*7JjH~s<87?EP0_Qr_U6SE-gIlUrc&Aa6LAU!D8s~Q-gW` zu{{UE(;{y9$SxYH9ml;&@}(4&;!fr0X33^y9e){4)AfY62D7sV28;I4gt2zcQv>Eh zD&8pxBNXfuCJSNPqR9=v?L}B18LqPCsk;m|F-iJDIa&?iWX1Pg_jg9yol-;t9dObvDceUQ(?LBp zyf6^*`(as@rm}Iz`OB|<_glA;%Aom^$-=D$lgFi%$>ILH#Ly_dq{Cbp;cL5N3RrTe zF}y)XhL3zTm2^sRLSOTC8jKCpc<&%%>_aa&Yr};Po-*|Z=gzuwLhwVB;0boP13V3qDpLgx!>-yIL7sve`HBTLuEEJpihi{3?}O*Ccn29bjT zKtxN2g$HoIkLO8@EvILFm$~r1Xp|qKUo*$_!avER9M9t^=`mW=aobE3KdtpH&|fu) zXDUz5X;!~P(W$AV%36O6*x2t`5hYDE-qJ%$*60rA*4E|en}J*qjc_pB(cMQ>z@)-~rG4&qa&ZiXZpBL_RlOQ3JDhHc|O)w?uzH(AuS*eS!8NB!7QXwG*?U__dlsNag5< zSeCIV+-=ZPrr54yz*JJ){o>#ieZP{QqT_;!5QQ8h;mR6;u=F7{iGs;-^i*ANA$MODgAZ+Wr$)SJgDS&v4*Iq%`+ys4i{qT z!YJv>C*Mrcsw54_hYK+2_vg>h4H1{ zH;C9@Z8f<*3S7z4Ll~I=-VDV>g|1~3JFQXUmG!L@{#f3n3cRp zQ|k75T9W&nwlj1ZL+Q8=Zpqptalt06nwC<>Z?wcD!kgIuH2-EI33&3%ByPAKteiL*v^WU}IWN^L?4^u`YLkdaWei9q8z|Yb5`6;?Zp`a6_MIo2{_p5D8uzZD zG>gA_IciB9qiV?;eGI8xl-_&EvBqVsNe1G+IGOoT_oRrM%CVsBoS_;(x6RR1mb`3} zhT7uSK{XtAv*oP7B+=d_!;RRa^=(mK%^gEjruypw7C6YMS|@b|ABkA#|F|CTM%eW6W|E$X-TcB{Y&0$CUat988R7tYdtwG@9#F}+o2rMH zK?)6eaxvds{(w5Dd>&c-&aE;a82G+0a zW_LJ?Jgc~~%wuz$C|vQQmCQ#(eFbCzw$}6`~oay4Y0*t0@ z+75@-qAi3liCjgMtgV0qJPpp50d%#xy)d2Wj9OP_u951UI$fMC%?3b+;9zitfnFFD z;8-L{aH0f``?C^)SDmLO*Js|a!v}J*+9IhZgSBWOSkG!(2uqu3EARblDX!u1I$*eX zxv&zp4gK3D(pDo2316)*e5Ib8l|iN&^#hflf0nSev+CHYYznPZ5h}H#OCe|`poLl( zT=dC?Br{{klBDFdFHbEnlBTN*I`?B|7;)U~ZSgs!dYzOnE2iYk}Q<}~K zg?sPseev|Oy(gdUvlDCP#bswJN>?q*WQpW1Dc9F%;5;>BX*iuuIcNi%=qWE0x1eNo zG6+xp-bBC65rKbsz4n)%93mI6^%u>-UkN+w!uYFa1KFkbrD&vpb9G>wpE#TDlY|`$ zUOnf>P*6HoI)`i`g4a0yG>?#PA9^zDh3tG}nBf&A(hfcvoTm{0L_oX0@k~U3pubPC zd%JF%VV_Y}a`k!~O}dEs0(~-PF2qq&2BmooPU)S|v6WMtPW ze(>iOe%-X;G{Y1k{L@S{)M2&Q0jvfG9zlFq`W)8=l+)gfKL_1_%Hu*{jYlXh)(t=s{U z_)rmmzaMwDgWI8FPI(UzckPoAqh0$1%s<2)@k+7(u^28PAZq;Dt$T4}H&^)95l_N` z2Z%TabD{<%DTo$ZbaW&xX8I6T zSZa!pyC!|+_RUoK9V+P0EJ8~w;Q440kV&A(n}s03a7llmkQP&*AUUHOb*G?>eF`dO z4&DThK@ox5T!Fp4dDJN#`MEY-m3PqChED;jzj6wQE!^l7(6@-vjIQS%Z}8=A-u!0c zvo$mC`+^nxypl({ym{IG1~z(nrwkxb+N9BvHN~TfV21t7t-?W0Q@arv1eA&k^9_Ia%{u*o zG+{7&Gefw=qa|f^g)m%4uH993Y5Jg_-9vf8(Cx51aaFB@*19L=sb*6Roiw@)t645Y zwCF^>7aDP1(V>>;)Z-?*n#&|)Dp|6^-uUi2)Cor|H6~D2v@~40wSA7yA{3E&;2;sd3tA1NYjRf6S|9gw{N&Pkrv11HgkBE{4nLvmn{ zqC^~zIF>d3tU{bc(Wu!q8H4vaugHh4#h`8B2QYm4dRuVTYCVOw`Cb|fnL$WyO<2is zhdp9w&TuLAJ^}-&43kexlnE1WZJfp>TUy-9N_Li{<&iMIc`B7Ur@;Uzn^3h@%p zU~NE?TG}1r!H4iigY_=>89Ni8RN+fNwH%D6*(``KBqtN7B%6&UOQS3cvsccJSuuzS zGlRXzSI8ieTow&t%5i;--@zDWU8@nZ@nn=-$BXINY=?eb!mroq7h&@dekRaY616cS za|eHDgu9r!*Pc)C%+Rzj&Fsm@?E5M~Ez7`0`qj#vfN=h!Q+E5c&u7JPA>GiR%RUGJ z#ZCC=wmDvKT$yW}Cz6f>76uXvqeDE^7fmomZgqgAsf6|R^xlFMT{n%5{sXd!OJqrB z{I`q)S>?WS5)B&M45m_WPGSEDaT&#-5C?&h0>BSQDEY4TX4F#J9MPAH)Fzl7K13!# zFnjQfZbyq9O#=BYuE!v%qDt)T&p1T|*`tq)J3jU3><&U_80w>8?a=Us4oKpLYm|nX zyHI0nzmG^)?O%l1U8uFiBfN3%KsDP5)JP=}#jT(33PChF~I;%-a zy7d6md$ur#ShWy+ycxuz47FjD3~dr79%Ha_<;=5i#2}Ttp3Q=+l^Lv6n$%w?>erI` z;V~2L02-jTn_TTCroryBZu7Pdb25|oN$>r)4QL||&t>O@#$a4RM*N-hQVjn10_OVF zDNG@ooT-tzt>qHb6Ar?Y)UZxifB?FcwQl7|jZz4gx1l9JwwYT>Y$2PdV zC((TU=H9nzrd_#XNMFf9M{G~t`(Xd+ll>3g`Q%+b z&R_4Nl7ExdebALHIXWieJQwGvq-B1r))jm$D-y=IZM1FW5pSW*+;&ZTa-gJV#lpm; zmR*NP46elAMvK&U8}OVwee!6u1yed5QD{}BJ_`w|mC-Nf`#Fw52y_c9cx+Vn3}JE5 z03TZ`@a=)hHAlmI2^v1vxvj=~uz&zwoMAHl*sLgG9w=@9xXvF^2OKly3uI{?mp_efDg>CB|uj#+LKx5T$}+u+bs9@!~4w$oZT z^wQw1l)&9S7l1m4_95pigo*K{xbLIZIvIM~O%CJbgEEoxQ#Zx%rKO72cR-}GbS!~g z#rwgmp3!hf%JRyra4Es%hGo8w!w7u{jPa7)0KVkvu8;n}8kM#3`Im+;}K3r~HAGR;OCL|Ts%H~q;;VEX1Sk3WP8hp|aLE8b3Y|2n6 zhgj_egb7j)6$ydNrJl2xGLst;R)&b}XO`41dB%N`+Bwr(u}3?o9R|p};qfKZal|Wj zOTdi-xa$ty_m?ET_PmH|;Y7_pZ^9dgWb^G3Xjo4y>MCBhWv(sJFf&5!Yga$KbB z1P&(x&{?SGT8MLpX6hL-Yu}^dDAmg#nt7_&!+7;3Y~muGC3cJf1@d=e1AOnZPL(C7Zfb?KQ;wMp&?U~NE(_iOUtsZyq$qw+dJXd5I3~Z3&HYd^OCi! zrQ4Tvr)p^l3^|KzV^~Q%9S)>EJ;mf`(wi8CZKK0?7Q+*qmfh`{G||lO%zqkMYF%qc zlS+=iY6Jdfh30mYr#`8_&MSEZ7gno=E@t7cQvI^WhRE+*e`9-`7XV+255W#A-WtH? z%foL*qv7E<4>m?OB|9RPuU_Tak@SmB>X zkLddr1?Ic(oeQMqZ{Nr7TmM2})!JnNYb_suWkJvH%dHsl;!k_yjA=b{u4PGIXcc@Qzxy@T~ zr+ijP7ojDSG08;i{YsT(fR`E688sMhXQtjaxR*U~_N{E8tkP>WziHD3r2$wD6cVXj zOKok0&X2@tGF7xaLRHs*pAW~KkN&d+3E-;&p5KWoK<{p!uTloo=3e%!bF6JQ?71>b z_ldgjiF)QL15|@A@4Rs;E-Q=U+cfkt+)#xq+)r@&1|$U&NDAFKX6qYd-JsohwU&#F zbIL02&ptO=@76veaxA|3dTV{3PgGuqC_YfLMKGqq^f*mks0Lr%aZ5wUp8D9_;GS)> zv0ds}BbihVPr7UGm%=s0QIcD*GsD-yg}^f!P*#2I=C#9nFj+=hl$fw}{E(6jal|=+ zL7nGwi*AK@$3@*2CtzVZCKe$tAY`M@a+iW?V>GC27jZ(cFcftmuX^&S+Su3Pi49go z4?q-CUUi!=jE=UT&FD+j^jRNQLtedX>AGGsL&~2$IkLB#(x=gKW?XGKuiW}qWZQx& zs%^qWV~9A3%BoE&0}vb4Cix6GfkbG<4S}6~=;Tww?iY$3mz4(7cn|6>ZAlWX{4U5* zcBsQg%I`POOX|G>jf!25SecfvQAjBDz3)=p`(8jllqe=F1mBZ?6wcvxTv&gMOvcq( z1-q^@-p|2t#?El3mY}k&r~r61?8@CBlz|FO>!jhHgbe^1wqUSKRD-Udm=Q>8q|3j_ z>vR&1zBSS1NG*^I?FR`Gfjb(uq5XZ6}xWB=Qa5g3Szk(;;^VbQNYu zv@ndG{htd;C8?FL|CoQclWY>?coz1mZjR~qvOYZpnFJpq zj94q@DD^x%kM#TSGEH7MibfD)NdnPy0r-EtwXC<=Jl{I6oBZCrdvCht9j&iI@@F;q z$`CMeL5vah8<8ZC-}GT_q!M-87$8ddw(`;pkqT?AhBY{v18n5Yf&SG2RC8v$Hux$x zgo3NA{5tM4mlH4k=d(sW=z=2WL`a}aKJIdpOk$iOE$GDjSvS##wXY-b^1uLJAF?FZ z=`y7oJOl0}vB99?T!rLpNt1B9O%HR#wOL3nlFMP6bTe-;#H=;1t+f?m0duRl1PXu2 z7S}fkYK#YJP~qY}hM_YhcL2G4?o+20GOG4L`(`m)S&NHSn*gC@3CxT7OKzb6k9K6N z5~@LMX4z|)-z6vdDXg0wC2PRM#RB-L_Hh+=rXD$9UVm$r4qbCZDPzSYN8xYauKm6* zd|#>ID~yZ3VoON)Z|=ynP>)tCV;!^)hb8iBV1v$B<{3u7ZP~m5R^j7(S44|9>UC}j zKwy9dEoPW2=bXyh6!E>IAJ^H`{?1 zcddsZ7y1waT|lXGh+04dn$MzW0wO`Tw$rH#G<2^j&K)nGy3*XPbjh{LOso{0WlEVN zQ()e{Yy>#JlLpaw8>N7!d@$N1!#cVP_~7C}c5GxD!0A@i7okQiI2!H=&C^g(tE?6#wVq17src5Dqfd3qD06+4Bc=xJ9n|VX`n}!5J19jj$~3YjFQ!iMyX2?fW*M86jOpf4uXvh^E~t-@wYcQ^bKd5yeL@qqOpF44r3OY zprIq*-8*>t_~78_-Usi!zxT;|AAXPoR-)L@7hAUAHg$PFo=@P9U1(@5rdDgV(`bv7v zU_xa#N`*@l@nkCf>7Ip+m;B2YVx|*sXB;Idl+wPL4Y6?AYR8~8@8v-uD++jM0iKFG zt2MUrO{EAQs0WX(uPI?V0%gQ_S|kE=W34{$+U5W>o}OHt@kU6BX?Igiq|KagOb#L# zB4%62OnSO2hOEgfHiX~I^zbG9fw6^t{RzR-4M9e2Ntj*sN;udhL)Hd8;l!>#3t_2a zm(vzRxqDKOBoi~I?|cVUM5 zENkxM4kO(R{Oea1RXzGLqSgS^6rrI*R6|kguO?<;IPzhcZk#dm9 zCYw2OC*;%}!SVfMaNqFX{?d6-2^>IBs{rg-4s%o+mn=(|(F-m+^Jw_o>3i2tp3P1a zXOqW5Sx2++HrJh@c0JA@EZ~oPIM5?;>QrL~Uya8@usn!$6%f3k5KS3z$JsB?Yv#l* zeFItDVWK7H&<##~6~*GZneLg%$m$Qe&Z)H(vZ*0HcPs*|8>_fmKwgm$RGjFt9FT|v3dW zRgD|0mSO~#?nqy3JkoJ%AcwkYmN&$M1PFIyYydO|t~E{<>&NNYig9Wa5d?R;Sq^$S zo`uJY1K}n~*oqMoyh-hj6ithXalhMtRwOhH_K%7{d2eTzm3Gi5y@&DS)5(j))d63-HNc@yk$7q=NfTO7AgKqb|9ZE>v}N z(v4;`_h`TO9_SWgFq=-fbfivH3+VW>97(GbJ%!)08~;$J zE9NtzLdy(X=N1j&2^y2c)VvCB&om&r#s--Zrz^U}jdn7=g`8EX(h|G97joAkDEI`J zaD~ejyxjlvT-@%zJJ&7YT@Y|HnAG2HXQa8_-wj#YA>V&XQ( z3dM+XBzJwX^>N;U_2!4q0N``TgO1ErdY{P4&<05D-=S>QUN&THNg4^YpH>%_fPIv> zloi#V1xJMi#15R!`RAePcnf%5`uj0LA&~9@3vB3mP!|gjKH$e|#~kpBi0#~eKxJGv zBK(DtMD;qmn2C(Aky9NUCzFu3j(FYHt=zQYFqPdIU#+m6*c4@#%bHYNv;@)}-Dq_2 z4MvgaPf_CGbtKMXBGzxD24K%XS95?C_B^`4c_9OFNCSBfOFa=jvK6t5?naFvRe2&zf zEMtG&%fS+s90o|Y=4sJ8(q71+qMF3S5R#344aPVioG=@ad-8`rx2*S?LrfUwv14#dx;8Th+$$296hd1$3NZb%5bJX1?EVNv4f<-E2&ln3^q&Qs6HUTc!DzGf zwBf7?ThTbg%^x{ELXqnA7>?BZKGbRv%@8Yde%|rQAEX^!Z<{diub{pZC#DHWyAPtM z58dnDwmmG3CPFAd1zdsIrdIjyyYmOJ11M!wRpL8e&c3rbpFcS37C-~TwULm3Eb<Po^#`ca!u^x>yXEXd6({0b`*o?Eu1#orT9(80$j4{8fLH;i+cQ<%OevU^I7ITq67?K);$t^uo6xT95 zFjhh@4SCBY(U6m#`SBZnJHa;{JTUT@@^y#YxE{yM6!24^fE0jaR#0~u>kKb8GPcL2 z6kAU*QX&hAKNM^Y+Nwo6ZD^-ww9KZRNW#e(RcQ=e7cS=5aJi+)(I?v;r6a>!e`fW- zlV2MX(zKhhV*TC7B`SndsTovIUqUkz;R7Nv5eq;ZOvDlp^*VJ6_ki9ient3Ixfv!Z zfI~tE-DAb4H537v8RBT7P(Gp}M2RWCe#4n-<5RgPvs+_pKEcNf`WgNVAzwm1!7qxG zNJ006LJB!2Sa?W|^2KFndH^(ICVDN_eGlZKZaKlqCj#^(m>XeE55~N?W1{>!EqNVg zzx2%rqo>K@oPizRRNi3*sP784)`TF`sM~;7!w-R|^LOir4UK#Gwx^mzzaF$^1kBW3*k>bln znzlu{yv)_<;S~Ud#p|}=wPT#K+@`ij@7`VPWnLe8r5(=e<2ZE;E9}#mzO3?W($7Qn zWzqz8Gx_sgeGTX3kJ8t`!WI|$*AQOI0SX;m*zEv~k1p(PRFjOZjZv9+pK?|@Zzq?v zjI$7L>|E)kp}>&~Lo2kEf#WY;{>}RPy_-E_m%gu0lMp zqGDNCNvL9V8O2@%u95dr3X&X1MZ}2J9tQA8)+OWRN`%l3vorx1g;;ri;@xw~Js!Sz z&E<%|D`O?pKG}ufCp+q&C^6+o5rd#@-@Gj-I_u7SB{e5fVf37cqinhywS>0v^2)=Z z*OTWE0|(D<0G7SB(YodxIc>~8-mYxtNgxWpN;NS?QKtf>t;P$sLTf2|7vc@HFi^IZ z9ejC#Quj4cN&e2pd~>#$oHNW1!}-Kf$Ns>?u#^*j`z-6DRif1|DS9X{JkiJN#03 z1KF=yy}x_>nJ5Qkp_5iopMJ(K#_fN=HP8Fk+VoV9zas5cFcbg#G=4L{UYAr+zP+4Ys?m7#l4z6X-S0OV!=JQMEwwwM zzW&bgpIGB?^13IX9d>@HK2{C)w1a;>&692isF&4{{g!~fY$r*#e16u`3r%Rh8s$m* z+VOsKwyyw}2)6jCP2kVGEhQ@D_$>!xvb{E{?y@>;a}?QKGEE9y8n5NK*42s&O4zb{ zaKB_FEf=H(bPsRS!|-SBIMQL1I&4Ih2U2yrNA>if-O?qcILjUr1TmcOE`L&LE7d#< zXmv5yyaZ9}Gtg^as(Io^4?wJFVMuGGV#7v;xPS(}hE)$TTo4sAG(|+7l+2i_>QlnCRxY6RS!zf9@1_h!j-|1d_`T0#Bk{4y<@)lO(>3cno36cr!iY_S(ZMX+GaL5JxNowKzWfZ0v~KA#;56t{T< z&m9>Po4jpD>X%rmT+5asX07T9wdK#IaRhrNT|jP0xfzqBZs291k1i97UtHJdrPwJ&16W z-;nHvSI1P=i{B$Mwyz$c# zgtm*<(eCz8f3Q-NW)gW3{I_cb8E)@u#jMl&koG)EYGZ*(+UJ24@L-BHAP@YZotaH8 z_dH3HPyz+lfW&9)gtNG$wX%yZFKN;N?PZUbX^$VX47h5An?!nFu6YJT=VO=83p4>y z13;{u!DUR~G3S7W@A2mwF9F$N+4so;&C7QV$o#HM*U_H6(~&Ke-L#=DJ+}gOn^z>I zybPzxUYxBX?4^MbjfO<_-kyj}94m|yA)0|-Fc)<-2hT7c%a3)kdHHsN>`gzNpsJJ3 z={-z3%(EY`@>apo7?Ug+p_i1rIIyJ^ORjo=@ga|v*XueWKr_n^Cw{gKPfu}Ru|9g%)n<>;I?J@CjZeqZ(^)xA1dWudcn$N*PAPYUPE8yYK{neNX^94m zQhG{VSn`K<{O6|XMNa(J?XGTdHS?07}9P-A>T7quZ%l)=qCL#0;MZV?&V zRdCoTljAW6q`vEFtoswK1w{SX81HJNUU%|gjBenPB4%mZng1Q;(M^*K$sJxxf zhvo8jOvbK_I15Djawl)+=KnQ$eZ+!eUGB z^ut@9G=$0^xl-Y^y@&4}AKd(M|^&hM1mfZfOv`t^c zY5h~B+oQ8v=+PbYG26J94+jwPh^v{>~9N3D7xu3aQG&=www0z=Q3A4Wcj8^eq@0R*l$z z{|w&iL>`~s;B|Hu76f_P_u;+zHuv#z3Q2?<=hjL$z#dY~wt8@Em1LS!AAVFfV=Kos z)nh8oHb=Dvo8r6HFm;ca8!Fgi6G~E8Ccp~Ch(<)x!I?aWB)T=r$4GE@*A$mrU@GGt z6kwrWMWc3CQn_R0o2)92ZGp9b&*YfG@u^F?_5fA7$`>zCBuZ_>)>4qkun0Z!vb}E? z6ENfuiMWO*$}2SY=%svoe{}7azE{TfC!fpcjBfl6J}Dda^~Hw(4G_Prf4OKr*%ir) z?u-h68Ix!i>gtBUkjutkV_lSz!Y7kM^tfzhQLDo;;a!4120wAbQpYnGa*cU>yG8L+ z;!a0N{o>-?$&TwQqQOUBNX3iwisec>!rBv7`hq$ zp7#1_(Qk3Dp3B~4ne_mqZ+p_=MNa=|5f7(tLy;Vh`4e(GmVG=h&E?V#2N_i!iVN6D%7W0UY#KfTI0--{!2a zWmhv0rAYrp$g2>@GvGGCYmf!u^)GYs!Uq2DD%0@P6(F19=_h(WkL>b1@UzNrAz?x z1FWuoBYeKioKBU>vp^KTL4vwuaFp4VVRt|VS* z^#y}BdS$*N>s#Sp-S<5C@Ql@5ebP{j%2}4XyY^_H z-4_N+#ci^KlEyc>h1T%Cz2-j@>yjnc>zjT1fVgpoJ5O27IJKqbpeQv~4d8(6EVY_G z`JnBlDP@WLk8m0hPTvHaZnt$*`XNpW_ZLn-0Zy+xZGhaa$a|tEvgJyzKY21$t0(bw zOTd&gZW?WKqPwdiMaj1culbz+&Uk5cm@tM2-mopR{R3kYu%uj-41dz#$hr|b$ zVnGlJr-sB--N)CtPnXXx*4U|k{I4Sari$=M6*+T6MP^td#}MFsM;Ng z^G(~WlxLY$v!i7}I0_**eOcw`Q3iF4StLp4gn8=L&z$;$bmVm_`GdFuET9CzouS|hWOuWUz>#X z{4_VnfNF38V~!<9W>E{Bg^KPqjl)^qoK0S@Zfq9aj$K~pcQpx3tmby#w~pmq`{vYg zdu4leQ*57YX*;q+e&|W)CroXh1XVUzFb4m`{s zlFUurmA4?7wa8A-PH(Y(Ej7vx(zoh(d+^-;qRO+obxAEtgYH;2XIq^+PFJJ(M6T+}#apM} z*^b5=tAV z!vY|Z+E6J*lQQ<<^;4yMF8T*a{A1b>>wL2T*!aH>3}BdQ3y z-@NVX{;^_XTfb<*F$H{(}D2 z*)It3Hv~@{7IVP zlFMXCKYJ_LUTWS$`#Ktzq>T$1L=d5`1!dWM_=jmrM>QQ4+Kt4X z$d?f+^Bm8G4nAxZt0j1a;FP7x#9%s<)UxWKoI~n<#P~U}gVij+KAWxu4?t7lho^-= zrh4!TQKZVgR2NoQu)OpIW9KASO~kXfDd^oxg{#Dq7;EvuwivU4OsCbNr z7!SdCh<{K82P=#g^^PH+{q8tUaz4j#+aVDDOl#seiSx3Z+|QWLD23)5#=QYqzq1si zF1s`&@UJDya2KgB8$34r6j-sLTmHF`QOlKsgKkJwOi!AU9r83>pW z_aN1MhfZi~F3kZxFkDQ>$gQJWu!^v@1#gr8h>#*zQoAM*rTaC3ZMZhG00YJ5OO;MpLiT4)Gay~|M?Obe~Z@!N+c?IA4w0lA$@7r9eyep zU`7dzj^U>SIKCF|9D-H`SYie{2ymNLl`5ycl1F%EBL?$IH1u!PPH1pS_14LnuOz&v zhC=8D)WRqKvH|P+g##-mV4V;26(&miVO3IqG){7bgv+Zx;~lOv_}ieOUeBoi!lDxPTATwX&w-S=u7!z3?-`i_KRoFpFA^zqMP{W=Cg-;&&)-Zc<;r* z0VG~xiO+98d$PZ8uChcM0Tw#d^d#?`wqLr6^@Mh0|c_{0Cd+X-yhh}i`YAWyU zvnP)a3_!3Hu@KGW0k7eHXyKrL@lqjhz&_|w7wDw4p+q20JI3YnR7Aj%$!0w-Yz_h7 z?~+~)icpGQp7XUX!#`k+B8|5~qS#~!zO)r!dG=fK+i!C-9%tyOeevqne3ow?^Xbf) zI39_*6sa7U@_i^ouK3tJjdO@E4T=1SE|X;w$_#Z6 zdL{KPo-H*do-g%3kxyeGa|xPl^L|94+I;LvrG(UhSO+830plg8<7KoAwhb#ZFze)m znVoFD>e3Z{(_g)UwXv1ag=7w|9pJY~#&^?F10+f?Jhu>GFcL0qbXN5|;n=#~k8z3TdUM!L0O>g_*mU1Znv(#bEg))M62= zyScMHgV8k)n4BbapUxAwAqm;+_X;D3gCxLL8945kSq>@Tr#Rt zGfrKaNTDE@{w$Znz@he?1-Om_0^wt`g*gNB-*-0v*4p4*=^i41nHF|{8I0p;8?w>4 z-p0(;=}coM>M)%ki&XP&tgNU5yqCqUwSGZ;5iz#7Co`rd0~$R#p?EazCIky{0j|qf z;2=wHDU@A?hpZjcbJ2`cBLa4wUKf&$wwKVt1sa>^(m6S$n_SoheST)bcF_Z1`|Qd4 zPv7dsCL>IKmM@nT2C`oodGZCUz4ow~!fp!d(D5Q?llvlX*G4O27a1iG&~x!eavE=?EDXg7eWG&j9Ng$WDWUE>mkp9gqEs_q zW97wjEM8>MxK;N7nzYEO3klObA0Qrik$1DC8bYIK~XHTt7kcZby- zcc1+Ll#*F<@7whKR{Y+JQpB`YnM%><>~NGw%zS>Vmoukj!z~zTUDerjaj~Q6xxQUu zGV_*6W_sInmaMB`U)-vfftWhTSZILNb&3b?*VrR z8$PA(hZ}m=WNT-yWp*g(SvM7idRKL}`ATy{N_=^_c`lb?^V~af7F!}?LrioQ44pnP zju8P$Ox`UL6)2ojq`WR(!>)+tA&N)0+!m#4(cD4|wyffL=&(UX`O51Ol3$2y>mp-x zg2yI~yK~Bc)nn(T*XEmUV2$J$j@yVA!#3~+SJcXZiQ*31cjKDovFf0}2OHauhcZXW z7N??*Y!FJkqC9|BR!UJ)M5$!B&1x&(w${@YfjyKym}?RJk+uP{36S}5g9)!+rv(*K z_`oTYZU>Ee8t4eWU<9_;^t|(aKLf22eE^c3jLpmnoyRD>*6ODh4BUfQ)CTdt!IX9r zaa5OP=B+av7fG_C+#+)?dgh{w(^dE4 zYn|T3k&-jY=B0@){qq~Dnme)fz0tG5`0NSmBDPbRVO&uV>4h|Zt2Q+C#AoUQ;mlmP zi<%c}8c1Yyhl~aqb^<3wy`pk}=>DDa8#c=jI@Wr|<CiZeo-YJRct^`$A>j?J?sSQ+ zZjnVEUsiPcyG>8O{JTD?o)qCR+{UpYJ4y?K(DrX0eV_aYp-xqk{V+{WlG7RLR)E5k zTLLdn*wW)oEq(b1Ej`v-%FPQ3XS#WlJl{T^DjK8SmyEoj0mOJe8r(UK>M3kjd$ae} zbzPdQDWfAhKbIhmUh>_j%Ep#AJh|5t>#sJXKR%A_oK-#fTH;s~O+u(a^q#FATDmat<2Qdr5i8c3M> z<(K6OGtLwyuGy2dY%12@AU6Jq9ULlj`^n` zL-zAjgkKN)fLwuN@ovYB5m@d;d}|g)(Wz>jTB_}oB{hD^lhy*|>5d&cEr+SqKhCz? zJjQCbhf$7~IO->9sX(3bU9nQDF2EtrlQsVb5htYiwy)gkJWrVly)5-0Dj%hu5>0!X-wt8h(Sz*LK`XhDOb2!*l@T1v zJHOdG8s;{3;$KOQ0(Z6S*y#tY9X*q_DHL8?Xy1beY3N++OLEk{Gk52tA@+~qmoUR0 z;xDkfl1?Y-WV?l7h8bSLxzp)mwOXxKtKC(Y9`QrF8#sbT3F&nAxw?%tEt07M-PxnJ zXUiyA?`5MqI|TqV-g(xtsZyG+FpHvA!@#DgpXH=V>$rlFrz9L~Q%~G$>L*GD^zU|# zr^Rncy`3a~-SI($N~T(xK#{o1~o|8%eD$VagzYY)J(uG7OSsiKP{+h})} zG+IF6Q8!@=uB9!1cP+YrCJVxW9KL0fxUPM~Y9VnjHdB-xpKzC1BGkW7qH)o>w(dHfoAV@G`a;WT=QFTW(YvsM0j(kb1tE(VHctb zco(b!>bQT-ZuE-R4#EwVrINB3AR%Hcv&yRd25RrP2=89rKc^nu<9&Iq;!$Mnb69Cn z+zapV*1bLpi`8nXGVHE*mg;83WNocVeK*4I>Qi~4fSCpnL(=mx)F|>gu$Hw0t1*eR zGwZeO%z9b7w%jzGS$FWZWfIPKl0MMKXPPHr?A>Q2GZfP@y8oOhPB#R!?^ zou+vqs8G$JUTWi5+*Wt^!13_`r^Rn<@LwPQfZIpdL!P|(#dp8NqI^r9&VzoW#rR## zS({uvx!*FuEC)NDj=Uu;89+3n-Xn7f3vCc=mqU zsCX)f_eCAi$I{okH0_q5tg6Z)!L9BW*XkBixh<4oXibdR)=wUg9qodu1uV%tb(o3=oiD_qYKHGnl=9g{Y3jXKq0nDtRgU2X z90%1#W>JI62^oO<`9EXnwf}pYCv1P8`;RY`7Js`j7Y<~}rPWW)Gm_ecJr+K~#-GLX zCZ%&s5Y|ynh?DUK!;zsWQH}DWS*I9>umOU<-{c)FovxYH7ou zXpbR;hx&B|y5gN{ASj|182q+XdZO9;IlG!?G^yKbGDU3VDr1`p_(`&5Ckov#ibKQB zvf~NTWb24jRTNU$=IgY)2HA3co)iJ+)$Jn5FZM`u6Y-G}9Un;^4DZM*Gw$aAt`>`U zXg9kb3Jt16tiP9~b{%{F-N|p>^CwC>7tbc|t7K8O#k*q}6P~KNAS?Lk+2{hs3%&po z$VZ({85O<7vb+k>;rO7DH>|oLhUkdyi}|*IEp!TMg9lM(5OuPs2E4F_4~1^O+17S^ zIzxfz8db=Bx_&$#94eP+Yf;&V*Zl!3n5mrV(ici(K=ZwvNyjYrTN}phmTB|mI$1TB zVa${4bFp~0t)B+soR2-c;)N;!5+iK|5pxNK#S!N!8pK-QC2J52i5{cYIyqfXGlXvC z!<112!+g!?c>NUy0|m2ZwIfUC7$Pk5EL9*hrO2h4IqvBb|CBXq;ZU@$y}@;I*{^Z< zwXH-$+}i?Ab^#`{pEfC1ItW@q5=Up9^-JCT){F89A+(Skpc!3`O%V`;caP;n(T zrcSgdMzoN!#*K>dXxNa@b0sLyx?ZStJ!WM(1;2LKAH@(ZrK@5V{xB>RmsCo8v<>+G zSZ*E5FB=pVf6dr?q*d#*r55F4t+Oof^rcku6cwF2P19X*$TGgssf9pN6|<6?Ti?*H z!cWU*@P_9{86HisBpUlN6L8QFjveF{gl?c+CARBgVQ8rhdsCz4&mz7|ei)|GPr)(C z!_R*h(ztch|o3Et$#*$uZ?9mN=lq_-G0A+qBoq5v7;ikB!edgd?!!OX( z=yedW4ISh`u+f;xHL9}$_Q*&DJjil%)E*|%oAcGwm{$m}P^*VY)8CT??bl!jEI@#p zj_!?tCdl3JCnj%E`c)asc%+o`-{qeYoX&ygzHUGWP1s6J#7zh?G|9TYCS5yp2m-T{ zR%6YSf#j5snDdv4n4Ud5Q-z6t#i%=sNEc7_!r_uOH!W(6nR7L`KFR1_9Oyr@hmKk`U;+M;em*zBM} zyFZ#86>(5obavQ z_L49ml>~0jG2g4{eyvW}1Io`r5n3*RphrY3M66MD1v73Bqc@)v1)vh<=5jX8ep>C# z@_4#8&vE~_7j)82u$RNyUhPd&`V5MR8D1X;a8huFdnwGIM(doCBIe!!p?SQ9gEb?V z!wXgdyAo$^HL|H(x-TQai~=bm1Sw!;ob=@Du#q0hva8kIIvPJ5YQbXE)HA~_yZLGa zl&&JCI?IiI$Rxc~IDqTy(i5OHSD-G#37|k)zJRBQ$!!>5+VEcl+IOQbh7sofh|@Q& zCRY?KAq)t-Z((ecX~6FA4QE`$1c|Km{8a+F9?{fOopchat4r4u4=yNayn}tEw@srY zOdBrz6;G8_XHKqyYDDoO>NKAHj=c5r9#Z0KBE;}iG#G${&l0WCS98Nvej7blo57+j z*_DRECj%uy@u<&lvzA)6ic&_{7s1QjI<^H<6P!9Q>Y{iUqQZZ#uDGhegb8GDx?|~G zo*M@oyIknP%r2{nrwNcle%q|g+0Us=ZPJhawg&w&a-Z;~w#bQZt9=x8>1L_j?MB-A>I7NaZJxQo z+`fLY5gaYvGdrNe6SC{yLy5-*-UTPz-(obs?-;#r$B;e}aLDEQO98vy0@(F`0H_NY zxOzuMlyta=Y18Vap(^8v6C1m2vJMVK`!C~pI=git@U)={cw1RBBfPFU6InSe4kV_=jg_4(&TxU12>emE`-a~&NF_^NCtJAFt3$MjAhO% z$V#!9-mG2*y#q= z)Qaz-YgSO|W4L6f13iuW7O~L?oFjyHGMfe^BR zPo@i4YJVDZvff`%b$fC9{kv}=Unlr!GzvylaVx2VHt<+&cv_uFB|{J|P#-}D+XsJ+ zuj7*H3)azkf*Uy1Udo|xc#~!z@At5dXUi0|ajTU~`+ai$>$Gb7@;d)(Be_0lNM(3L z+#{!m0D{a156lf*I#aG-fIikO+$86p(h5={8M^W9`Ja;sCP3vQ-FZ1wA*f57M4VKj zqj4DYdNol+EYm4OSP`4Z6qmT79_@Hf#4EcJ85Ommn#ka6y#}?cR<*gf=!7PPx3j4{ zIYsQ;66;_fuF^?}zHv~@oSOBOfZP|!tcriTOqL06OLVW@qCL90(2cjGwOkP+JHX9X zJ0tDJ@KRCG5e&?flHaY3K0qz=)=JF_w^IAwsY%4PV9-%UvXUlt+{@y5@?HLYF$2~W z_bTxe$|v6V9x*vz7XW%pUN@_iDiUQpTdl5of`712#zllK= zNo8}@W(!yB{TY}asbhnWfwTfG0C^*n9g33}=Bp9+_B1);y1qmg1qB4D)Wd`D15_G~ z!w=)${b+pefCW(Tx}G2gWzE7Ysw1HzC50vv3Rr2UD8ZHusMu0X1sTKNpko9WV~vY>iU z(ZE#mE~Hz7Fm#=vNiof=a8|6g57w<_K^wP=bTO)B&1yQgbbx*mhhvj@3_@&z?719P zFp)H?YcuRmmDQldB0HUtMN`=sTGokUjVxN%ur>Wfa2c{-#pPd61>l1I;;;e@>lc0} zne9-g^<)w&D`>s>ffCpxpBmZmeZ6V&(_{p^(8M#QUsKeuC{HvNtqrxKwns2X&>C}> zLTF$UJse>G0yPP)AZ3zoD7}Qy86Fbn*=Ax{x1~A&X(Gn;-AVzYU4}A!I#2Rt6}BzV z44th45g9t*!0ckGer(kws6s{OO~mn8G~AL4TB2^a&APsIR#oZ>A$OKO0zr0X zQx8DXP4}B`2IKb8sIwcRGOTG_4~?KCAU&<{U22^!9yxvgN{9i%s>GRtH2VbTB?gGg zxey+uBpFU3vaV*ayx>^Pm1oO~3)l=69=V=b`vA=;oGk1^*X)}x6mYisuoz~B1aR8-=@xpBN!Llv919v1~n}qp($(fS$r4dpEoG|L4A7WyuJi8)>wR=|q=A}1z} zt2nvh(epUXNOjFiDf)q$q9{d@3M8Fp-;+Lx)2n=Q_8Zp4lz~+^Qt#9N&(y2*E}_Fp zgAX<)Y9qDinI(`;6i)>T<*5u6LcRSSq^{R-1{7O_5gcE@>w8?_Rx97*aU0J zwZN_}`yyEYnq!IY`lxTYz$kdy%BFz{0dCORVe3ZY(%xWYQKJQ$0i|5z;R^lC^vNdB zHAv#71KtF(%769#?Hdd7G<&_ARjF{u6h7HznfGwSI7^7G6&)e!GdVMlv&j`q?Rree zdPu(sD~@C}YB*6H+}xv7HYZjm5GZL31WgLehX7c^uJ0{ocO1FpwH+G# zV@SVlwE$zO;1*71f{YUV9d4Sj*#ls8oSCnkRAOKE*+4$d--glHhHkd>vZXJBk+MBX z@aDy%Mi#ZYBw&H$w<>ECfbD$U?;6UQ8*2Or@bnQW%nu{-D<DZ@n3zPN%yhik$3 z^(Z9bGYHkj2Q^RdHM%p~f&r9Xc3N`PqAOJ?2cs)1m9IndwcE_fGH!nTM#CTyG>GE; zNM~^8UT45cZZ&6RM{Kz0Qj%MK8$&j9`dt@h+Em-tB#iIQN09;mR~1@iU|@H^$tOpvm<J#?a7 zIdKchUZ@c_U%M%Y#x|i1nrBjSn$oe9J8&ikiKv&WysX za5&JpywdEEyO3&rXxcrK&_+)Ug7E=i%~RSMC}oFVvi6LDr;aT$sa2mXl=RKdP0igT&L+vs zns8k-&});S#RkxgB;-iutm0u}N$*-%j}(_|YlEdA1EfdQD1{|I>EXxFnB&l$Rw-Ey znu}9hWJqRiD;2G4rAXeif~$JJ!7b@8X-mrUmM!Z%UzYHTa`#73=|?&r-m-&rcCC$f zsIZ7HA+2+2h8kRH=8ny+Rw*1JiKsCg zs*!6nn{ibioA8+?6?VmEE(mNXdg8c#39EL^PAR4zl&7L1$7(f!4xh{y)h*sFdmJv= zR7Cgt%;xZW%NBfAll(P2E6Yo-pJ#Z%<`kR|F*@trBl=X{S@)6*{d9k|oG(B(oLoeJ za>N1rj$@u_i#%8fgCU&XKn0W}U_PPJXqO&ynN_0`D%lsB`j}IBwhwyEOnKl_w%uyP zDjK9vQxOz4`y=^QbD$$eZF3$ICZ*uoxY|QsMLyan!_N`>jD!TKfZOFP79MEN z5N`m@b;O)`4>m$-%8}pJfb-Aw*~4cb#wN*xn83Hx0pXf+jFbtm)Ov@u`NL)i4oRYJ zPa+VQ@m`jEJh8P?L!7!f1_W&*bJjXl?*TN~_?j>L&aZNah7)^8mdG?|Z`K{ieHc86 z1BB=N)971ZHVa@QNjTHih^AJYCo+ch4{TmP|6y%p`V>Z1Ad&Z*M_LUN5EYQPg9 zyXTvggcD}r7LuBKk^ZPUQjLr%khb)!1wug2?+x>I8>JE3lc9v(`y!k?$Nk@-jsui{ z1V-`+tWYs5wqbp>AuZFu;QaD{{+4`BE9)y(-1ABA*gqp(q^%7>+Kh=vNo z;5jUm-Q!u+{T`N!c|0*wl>MmUF~izjrGPo{Hk;j&J);fLvt*Xv>;%yUfKZGiknFVG zfpXFG{!_Yu*8)goM~uO?!4Knmlw4iZQTo4)z%PY$JE%5N^_QmAiMLt1fC4L=9Z$RAK5lh?0(Lk5`mP-rCOwza=s@gzt89yKXie4D+e8cE47?6Xldc`U_9 zZoCQWgCt^<`i_KFnN26SIh)kL?F2KYkabm7o#N*8_kn{3NvGJ*(2b6-bzxb?`(?K_ z!^AYFlOKc4rBoTBr71}SIi@KpAh&t>9LBZ)8tH*{2DwE0UA;{;-J-)Fh{z61s7Df> zYULX$y-uVtgvc~15R6)vov;Arr2y8|Ee@V=p5VlNP7?iom?#YpDv(LPD4*v^6~iN_ zjM}wI)fkj~oB9B}sw}VKv=E)?N5fM1?MJK)V${N9EuYS3%L2ck=Y_zBvUqoSO>WIo#*g2YRZF zX(Wd1Jj8fO`e5>QFgi2Qz^Lp#t%@qLB)=J?B(^EZiVP`AX_|~o|4S`)FnHtpk zEc|LMCFqVZII^$~ti?A*p=orlNgF4UTS%#Tt;;d$!#Ci74sI&4Co&FZHzHmgWtz$y zZu);FqP$izOM?~vn2oB9coR`V{V)+omcH14sjYoS`z%OY5vB)@3c4fPo1=}!+v}v5 zft@ZOgYuM)^4D&bilNP~ugkhun!sE%TV%9xvNeXCf}D`mabn+7qgsai zRsvEYLo__KIx6S4x#hPFfgC<=%yzpmR`KLCsSUEuSjuk+k;Hn+FahLCKaWbRKQ5CE z>p|C&hg`{6rB*LxBPUL>?ow{{%~;pc5^wIgfo*9?0&=P?2Js$jWlBhg;+%^k>MSDb zHu06ks*E^)Ez~QEMTX`|srC6r&tn$rn_RuQ3RXywc7}v8sk?^X}>m*Fj#_m}qgAE750Pn4ONqA!{$ zG(qzEBP)1Kelf3)Z1I{N^(-b&&MRFc(M2jCwL$*?Q7WK&MZ!bg>wt5bsDQY5nr zP9LZZNUUUHLWwzs7!Pxd6>>?Bm-NW_1w5y)l<0{v=a-}T5x*GCRs6+;Nk_XyBA&Ax zCOq3UGalTMShmnd!!!rbIOmElhzl(_U_zK4ErsdPl|&yT$fqch9=oEdlxkq4kBym7#GPx=-uI z19zJ)J^!q1RxT~^`YTeRZ(`g(=SK%oxa!ab8&REykhBd9E#*cdG^>Px2ftnV#XJH&3iA{mb~`3@9(5~tjjT){3+-?fK1!T`>m3jxq1s_5=gtpu z2-5bnUq1o2Z{ao!hytSg&p=^m%pEA)jSw(|&6*A!3zH_eQc>$&66$cDr4*?ivHWZE zC?<^U!x>RZYp%;gnSiJw0iHtzZ5=v+5C1NvB&zHa1MgK_O_is%k=ckl?TC?m0rn(` zd?^BDvHuPZU2A-Oj-fa|VA$7gn~kyR2uo{=T;wWg6YoL|(o8v~YNCt>QuGWsZ^T!I+R8~bHm7`%x6=s%EL-cQ}Vq{=V zZ}yC2SN9w-BZEit7B;0K8es=FmN>6fEwN_iz95-mz(ZFB9|SnL zz5)hA47H(gbuB4s1~S~`9aU+3Kil7MN0Uzv+1Y{`1U5bL2mP0 z-C7fZUJ4Js|D0n8{75-8aUQ1i4mG-OTuc}Q($d`|biLc8;C6m!oz0ly(|S85M#f`` zU>{e0_1KVl-x(J@WpLE(ugyJm#ht=Rr6f8c^`-uN<5X=|m9lY6>c63U8>;Ukx>IOh zXkb<=1G#9gyijTntq74<9o1JD$-hvCd>U_=ANsR*WgXgiyu3hy7p%9J zCCPLqP6FjK6IXqxSG7s=Q6P2AbO?ozEehuj0EOc z!FSUtlK*fgVXAf-&$OXmobf`aOUV&$$6jUTw2#Pr6&c)QT8mq=Po_q7j zPx>GLM@N)VPa;j{*DvdJ>gCBq`ua9$yO;P?^m0_x=l+$+4C4r7fusIdXDGzkdNh== z&+0H`QF|*nSEy9(Sfi>ASQ@hezp$@D)H-dEh|`8d>~J*Cd5u9Q(1DGMqGa%fG=#l2 zsiJIjqBNk^v#>khJQ>Tc!;;vfv)*cMk0%U@2wB0<2UxFMD$9h!#K$wD8J;JxD}Bw* zO%X3pE2fjwQdl(8&efqWffqBe%7r-$FP^GQOyDOH_z3}Tu(V}{7gNBr_4i4A+~Q_P z_H4aJ5oC5{ew$6yCxvVGl6lAaCO3z^;<>>h60Svex`CRb`TGo|YFiyITgCC#S9-(# zIOWYxYa$+P+M}k*K2NkTewVcdNvgd5uxmBZ`!ME%gFYPv&f|p}RH_CB`je}3Y7ycp zlGVeTk|%|f6CQkce{iXU3>Xv$CoU%)U@S9;gM^on$5y@4=4o>;-?4VaAWfe|AlI(P@jxI-n?fZ&N++zKsZg&F3 zCUmAe5y#8?ijHhA(PK;KG2GJ_x^hA|*uar4v@4}?aJ|Agj(jk@U`z8bN>L8E%}$ip zEZzhmw#31QEQmVv%a*{(O=gXktTn0P;`Bn>O6b@+mf)fWhO7r17)^;<+q0()?~)cO zPoj05)o?^PJv@`cQTbSa5H!7eqrORACX$ zXl21=Vg^5IW8vo}a}4#1VaLn+QP{gbj_8S6fB@tN+8A~$?{X~1ArSIujXVY{SVPMS zczaMIb{LkOyi@Eq3v?RUJB`ffUW}IhtTeI{8=~ZIj8qefh~-CEul{U+6|v$QvndnK z2*z;;;oQ~{A*vc@!+1O!YlJz2)iDOC9=e?eYnTl;)c)o5>3F-7rqQ|MVA6I1q60#L zKE{x-(SFfAkR{taJzXrbK;ULZ9lVj%6(#7D+SpL5H3ei33Au>z-poY7!?i)HbN(7J zC%b9TX`Pw+3pEm2PqSJIS+<<+X`fq+;sw|d(f#T*EbXeQzMy=>XlPByv&|T_b8kne zTV^{x-7>qOvuZ(SwktNPR%~WFBhzdD3!H3o(l52=Mv$(0c-NnO zFtc_|!X$|AQA~Or>uVa!kNLv>hBBePPSCRzPio0At%V0qt3sm8qH#bHTQCgfkba(A zLg{Q8a9kVOVRF;$8nJ?55Ug7OCww{3OHdo}>QcI~Fvd)qY(;T*#mYv%D~!rrs?8Va zA1TaTuI2Xv&z6COkMAx z{^9v7FLg~}#d1~>@G2l0?#%U7m8Z1ZK2zWc(NkEZ+Xm|?~vVJwz^#ttb*lQ*vm8* zZ{bMRrE)vR3Y_NiZM>+Gw_B5`QGGQw$11wjJP>KLS^8;Dr0wC~kK$Usy*t!WT^9Kg zRO)*_y6EG-5%f1N;Pt_S2cxx7if)AM&gn|ny*s)+d$>1Pd>$FqBv0_4RTPP;*<4q( z^7z@$4o@EI+--SY(tirD^BLr@swXW1^k+ksR9!M$=PEAG!@<)5+fzT0RivzP43fx< zL@>j;0rg~~tz}|ElV>msvdU`dXKe2=v@?i2+3DqcnIbneiavS5_I`HA_6{FD-dJ{q zhV=ljQ~2pFh12sQE^dvo2=1dk{5*_YY=T1298z5{4i6taVtak@zaI2heM_b`j+YCZ z0Q9U#-GreJoku_b2ya>47ccz&q9lCzE5;dRj%5ESRCzc6oE{!h#V&c!Gw|&q1{$(T zKg7;Ffu9GD?9xJ8VdQ@R8T*d`2kz+2=ZV!}LevBN>HG52GaRrP<@#6xhy;dhOEH15 z*o1L#_yjSHXnDGsyfZkKD^jQNJ~Z8Tng%wW#`cVTh^;(0#6f*(7x+A%br*??Zu)T{ zgKnkOEj?mjly(~YQ6K(0KD3HnB{9rW8w)T>Z8)T$04gixeDX-}f`<-aVweLP#}Y}0 z)ak=^nxV%cxlBGcVbb$3vYH`5tvkbuSt&)^?3=5C02gU}@WAR@&$4B;>Y+E12B60L zbGM{x@rQeT`1fG(d9M%uzqv}QWV98uDp^=iQP%{)V&`_K0!p{^?D0dyE0R=yu)UUZ z5*VOAVhtSbbz$|R4s~f6go&R3;xVzzkv&oy$bHq%_BLX=BB6_+=pA_Du&=qQnBnfK z-Zg5l`STu7^mKy%w&P41dv%eawc#JYz#pOtPv;N&G_^%e8(tyWcQ2Re)avUJFM6b_ ziqbhOXa|ez5`>I0f#FJj_w4PvoBpqVahV^(e{bG@e|7TxB|e_u&-3TUf51O~ygdIy zMydVT$!~x6+gJ17|K{NV{CDy2{M*^>!NIeeR<8yfB=IR)lPTrP`5m(Xc$5wlw#g|=j>%IaHcBy_?(jJGBF zDm67=Zil_OadT#sz$8z81xC;cakMrsypm>En5ap9pykxLWX9RUuFWb3x%8 zbPZMt92B%B;$D(GgY@<2K<&RT;zh&S^&TGMzW@dU1;$QFeH}`t8p8kAYy)B1XW5_fbQrxg`(M0rv~##NErZr+^MPJ#$A z<0PAg+_EKo_q_fbHoo&Dg6~NSBVma?z(t}wrkf ze4$IU^9h_P>J+7cGeK908jy>NU0}D0YzJN*$QX0CL0Wh?llti^nTg-tB8FZ(S+|J1Q69VI$8&p$-9ctUdV`ykkx1J z1($K&RcRJeJb@VE3B+jjeHx!ZZ}5+tJG=mW&S{RR#W)4aDEP_s#~~(hOd5vt$Yo}F z5xxu&Gm1oZzx@Y!{vo;uwXsH{ubDQB=%$zp9VxQNxPV9_uJ(^iI|G(QzA?O^kAY3NQV2x{d9URQ zWkXU*iG0bjq=MY{YQ^LzYQBjKEaA;WV61qw>4Sx)c(m3Y)*7G2==;jAR{p9ro_%&C zQJdGXx#9^OEgmI?&2I53qIq9A^S<&=bNUA3X>kUOWU~bTp46hC0jpwMnvvF=4+iS0 zn$K|2BS?wI@LXQlr=ki5)ATxs1aC^SEGd5Z-Rp0;C>k+YGN;goQmm$WgeSU&^SKJ- zuIeh$A+xuT7Q(<|&P&krk|?h~|Me9)Og&<$js%Z{4?SqGMP_l*KBi0nr^PR5O9mw1 z*7+ck#`=l4t>BjlZa1JW#yiJ?G9ZOW(Z#gX5b77Rx`VVwJ34XCKMk9#W#rmyDwY0m zCF)~+X=is2)wf*UCRO@pEtT5WtQ$^OP8(ePY^;PEK+(|r#1rLKXw+^vmm+NHa^pKH zIwT!GH46-nTe8FAstlcjlYg72%(dtGt7Jd{%6Y9kUqLf)&q4iOID&W$E))xg+A`nX|8_fvG{mYl4+kTx?Y$2 zI9!nSE#&?>M1eHt(uhe+F<2=`ZNiUWgCUetVxkHAoDZ}r3YS7A|_c{KSnH< znc~ls30hKl)KjKNebh%R?vr0gggzWbtz6g2nl*7<6EHV<#UXa5CoG6~+H`3f6?o@p z(dlR}l;TWYsud%#;-g%1qgaa|RleZeLBHRHuUc9_jY-rA7M}wVVIXeK3!v$E*Lgxs zNAjL^s~dp%-(ZWiYZg&Sp)HEhnGOLQ#hT8c@mYtbjahJiBhAOs8o}!FteeXDNWGL1 zoZ_aaHtr9>b%!2_I7hKLuO~3uqgms-{vf6wP^$(@>Y0ry>

DGr@6Bj9gJJHt!Hm(l@j7z#kgk_|BXI#tWAkkeSr2!7@ zIzkuie4J}>aaaNs6FdcrH(8J!XIU<6uRtK`0mxOjz(_49y$VAZ+94>OCpQRAjau2$ zCmSst((MR%n6lT&I^{Rt3|PTa46cF~C5y;zMU?TpGa#Nst9@7;^&@4glaETCcL!^^ zedvZ+2YesGj1ga{8uxoK2lSE_#gcc+E}6D-)sb<@`$sA80v&#ChyiEu4nY5$^iUls8S--xo6b!OzQ5EMi33+t8yK<7i-!&r6Ol*HNpxPc!f5eunkXxZ}a?9 zxp$f8(|uqTWR&rSE;AuRi%-DU65C~tDvem;znd>pLHvkT#0=ED7H=?%!c!J z^#r13Xw1JgyW$gIz{bkhUOHmSowGuCm%8^{G$^^@#~5C2_JU5Kb4Y7dJqTMC<1C_8 zY_x1HY157_-&`BJkHlJspnHMBW0eIi7FWJ3Cd80WYk9;iuhPTl=)Cv_FnzTXmMDge z&4|?Xuc$GhyKXpz7YYQm(Ob<|CYoKcI~km67@(*Mv^J{0Hg%ebbwOTQzQ)(z6hN2B z6qP{R<9uB@ONgt*okZeRN;l{htKo98l%*$wymQoFw)rJmvt&!Cw@WIXZ3Qmd0$Zj* z^OZC|w4YKVh$ilcT=T3pPbZt#$+FZpx9sLf%fPIqs`B}8Vs8d9qWj#j00{Qrzh2wq z*t^@4|22&u((EcJ(rTo>k^P37EDbNRJWKF(?X&{58(F&`3J;}?#vz!kSYJh_+A=7s zmq%#yQm0B`bqFRjkp8f*3kdU`Zn*#+J=|LqNf-M&YKM|6LMVa32Zycc&vtK=oz}(0 zqxez0p>lA?Myp>>^*V#EftQ09PX<5R&_D|7j<Z=+c-wb>H$x|_X^H&=i)w&gE z+E9w{;hs{2TZADg0!M%35|nC_qDlzm=DwH!aaP&+X*2RgC14%eu>cWwR{^;WSP-LF&OGF^)>Odlm1Qpq~Vy;W?+Dr-ZByRtUi8c~(?Htx#3;wWvq zS83TAj+tfKZXRN#$f1Vmh{Yopf3P6p*o`|D2qRTp zMN)6FY4Z~%T*mxqUMTkL_7z?#6v06R&wP4V+o(wLg}KwQ7Fw*9~^3R?88bKD-O|$5(zX(N0yMCB@KxEbtO0 zq;W0U4HSZ{Qy}U<<(H~BV!}2@N@>Q$_E%D}-Km;bj*!+k;;_j(rhR@*!Qs=|sp`qgr~N0#YqRj~ zzEzJNJ$n3TU=(llm^%E~;giF|y49CY;NPK9%<-Gj8T)R=-TeiA^ziA!Cl5}HD*k;( zfx1TyXuJChkb}#UL-K|2*Yfqo{;gf#*~(uNOdtQ*mH4gu-J!>SZu#v7{=4_c^`=AG z1c!`=QzNh6%?8#_X64k*Q|=dXi}4lIo_Y;JetP)$XKfU}z-hlEwIkd3RXgG64d#Ve zq3hmMAK{vH`(5>ne13naZP{|*gpFx@eDY-Q@}&)|cH6Tj{K%psjX{4M^gK;KvYEi@ zy17a}Sbj%7=FR5u(|Y{)#nThB_AS1r$B$1A4^QMw?pn;!OJv$-(8=OD4*K)d)$GAy z4y>Q_t)Shh0J)RVhE8qwU1PrNnpSqmBKTAVg8TUrv^dy`Rm%0z(^y^mv(gJl!cZa1 zl#Shg`Qqu%22S@~N68u9xJGe)i~RgGV-a+r5$gL(WK_YG~- zVqD@4)B(E^HAWw=pr14B>&F5Le~tGOe4>4?Q`asB%tA}h@N$t_f%Xcc9wPXcD)k*E zvfK&AevficOayy9dY~@Op~%;ds}ue)w=6 zj)&j9eerhn^3@NoPgXzt@Wbkt$IpKq!Ixky!KX+gyEoUU{ouog`{9_wZxpZ$j{y@^ z=}9*Isw(e8t&O^>9$2$Hr<~SE^4v$Te~z!?a#Ey=f1h5rPl11ztlJ{p*)*uoa{vgx ze;|-^YEhn5#Dh^dNn1eI)*eFj5b1`>4^-v5Lv(NTr+*I|8Ntut1v#Z`9IVJoPOSJ+ zP7?FrH17WOxckQsAMSnp$KSgD{QKX}>Xd0C@qWN&9yb)J`uMdFt6$SuQ+OBD3$caLP7#tR69odVC_DzE3fO zex@AsY-D)?i{5;ZOhpQ*4Ob^1xY83=mlTiyd{D>Oi)iw#z=FC~p$xvK5BRzhL2Qp&!7$vqX4eFlSYn8w0r}LPMo&0lNdRy>tanbc7V}ia5(XrOVF9)mq$tp)7b&UwQyzSP|6s-b zeA@3mjk_1e-Ir%~hwIg{`Th{z@0tk%_ISNsLCWD7{QT_fuFs&%1A3;P@#^%Ue(puV z$Pj$8{G(var=~a%20)`-5{m%3EDTh}Kr?re^0jdEQ;-IFN)`zIBEPOZ*?$^P_MfWk zPJWF^xy!Cs!aiW>^z#pA4Lo#Kr})MjlboELcDiR{c>i!7jdgveCVjD>shv=9yuHa86e(ci*dQ7G3p zu1qKeGQ-_+r!a16f~gZ5JB9`pemn0yNl8r!_b?38BXX=`?_I4Vn^U>Hwds}c5iG^L z!Db}<(!u3q`Jh|s_gCD~%+`eKcu!BPy)CD+FS z+}gOrLL53?LyLY4&A*Dk_ksS0d9$FmKgzjf{(rap8wB}%klO$Su>YuBwK?`jW$XNJ z%a%s_HBf$k^eB`wf5ON4!AG!{rDN7V=-f9d!&Dh;Q}~B5fpN%S)F}wFtP6 zY5NB|dD8mJ{bjh_59dA_HhLO=?ErpJxVU_&W0(2wfE_(*ef(IzbKagEIDF*j@#X%> zPyJKRH!pSC!~Q6qo%1IytZXi5+miNqoBp$<58r80ec1#rYS{!k7ESM;A3Csd{P3xd znFw&dqUd){Jym=+bV1~jkmhyDCkyh8yGs=@yh z@pFAOOQ?uR?hDRtq=TeB1>IYtu^|T*sc+MuCqBZWN_e*-q*#!^PO% zWBYs9R>GN8Qkj35f-`_-4eFG}tR7-z0yG}F4t}i6*_`_CEM-UA>ij;-*q^~^`DuP1ySyBzq<_+k7cC~ANWtntX% zsLXNBR09WmB5!_&kks;uXig zerqFSYu0h)OCZSrV?W@atKly5M5{@SuWuFtI8Vc!cj1OJFk2weTd@D|d~QgKmo*AC zXSF`5;mp72-L$>~#!$esnoZVreJ*A-5q8#$O49>+JXs}_B%98=pgo4OINMJqWR-sx zOn4Etv)9Bn8-sC41j@=lfzsZg$NH7!%@A&T1&pmyToMy)W3H{LNl_5q=cOqAhTP3&M&2wq$)BJE&}xvJ$>{Ad0E%Y?t&QZN$c!b+uLov=I#8 zUS2>MfdJoyN`ZEs?v{%xJ8GM3+Yp*lPkNruD66xv=`sH3v6d9h_-e(LC1mSa*_RTL z6!RP2_|OImGSOB;*5mzH;LSN2N zfeUEhko7F}My)PkUs7+%zHiCcufDPPdJS)9WXqxvdyhol9i0$>CSN6OrUv5wqWy}^ zziP!uW!QH@g09-w2<4IZX2n~PP<^F&0lnBDC%a+yH{k4Up^h`Y6|WoDfon0A?60Um zw(FdDHYpOzhLQyYy47|#A_Nq2$_R334$&f`?WJ!y#T9U)?HC(LgsczbH8C7Hmp{_` z+9V8Q8k5c2$kdK(1}VR#w04{r<6yKCcBmbfyi?n?G@&@qbjRjYObPbD3w90NPSwxc z+LC2HxU#F=jV`z&VkdG;AR}&*+y(&I(ykQ+V2%f;uOZywCo|@7C^Zo4je%g}ds#zk z1wXS?bg&_Ajv7sRvL#jXejUNML>H5eD|+^rt)_WyB$zXx<&4je51HFgkyxP8ey{~@ zXsd%U_O8m*EFZg0FqNh=SdpBnEeeTb6R(5qyT-kqEmrB~R~SZ?4bwJT!&X{$&wxjF z49h|K)B-n4&bVjTeN_my@}^oKf~`4MTl}UqM!y*{tu~M+DB*n(eIa_PEltOa!W43q zh9lw8-%e$R<&znbLD1Npgcc165VlW&_tZhEU(`1FV{2aW9Aa%UE)B@9Ag_S$oVt#z zS`fOI)My2d45X)4)Eu1h%s~}d+BGr})u#5C#^z>}L|dN~ogxzgm&jgm4M(3`-f$Gv z()p;acl*V|?#%~l)_v>?PC64eKCOfKMfBJbYEB>-tkU{ev6H3Ib-~A6O-tnKNAk{N zAJwE1@208NF zRSAsdDiEh)oQRP-gZj)F$%ukF=o*>nyr+6aT`B+oqjQ>b_?8D)sa9!W@m<;a`XDwu|7i(#Z!{djAplYZ+o8eUhW{hF02XvmHW9ktOE6mzz*|b3u3VAqqdRASsV9K!+FpUG}Hj?P+lnB0ET{$rt35< z*PZJsuG!hO5WNv?wo%}QvPVw6sTjKSWwF)7MUF8igi7d9=E!TRJlkw59dTE)-bk!y zqW}m@2d9 zhZp2?1FW&~*ML@Go`>^btSm}n#ueNKyTrEltk~}AdcLB&f<*RrFg*3F-W?CK(RA~8 z3$8Y@VXyCei_izHQl9us+|}(W4Fus=(UoWy7Al%}fz~D(Z@kb%FT7}rqBc1g1f_UI zd3V2={p(Wp0BT}R4uS6O?9S}$bpPg?9EX_Yp%@LT79WFoUg__Hc~#_9Tju-6>fpQf z#F@2T!F$38|~mhPm;miqkd;V0Z!J?QwU1ulz*uj=Y=7vU=&9it{U(57Q(E!RFVPtG6v1dD)h=*wPNecyBv-e}Hx)s3Xl9 zW__R#O=Zo#UV8#l%H0EgH&g%Wgbuvn(pF<%G|B>9f}l8rxjCGw&MlR%%|D}va_;$L z$vbP_msYlIB*V7`muM`Ii8(C!`D@WE371tE_eR51c$N~LEkWX*UBl3Ej~T+8=xpex zR1qrCA88KPe3EK8*lW7cwsnfh%mR?!*@;|I zEh%>KNX{OCH1I#OBhn0aKCQ-M@JwIYmOcTj6{w~ACZ#I&8svz4vG`Va*Di`t!aNA* z5IO(?842VW)4tOLahZgP+F2WPE5Jm_gF2>&e|9tpO4x|{C{P`&fq0hYVpN;XMPK<1 zO5v53Q^cWrAx-O)mzM?Bw`O54R8$cI3z?V}XVml$de}~!x9gKYQQQlF_~R0@~_TCTKCXg(MQ6^Sy@iTlt2yAh?~?T zJ4$No>97|Ix#sXP6~m?9;M} z`Lui|g8^x>&vX3|2hX$=|F{zFJd{-_tKpy}WlG46Os27Rr*jlQVH6!Eg()iAc~Lgy5Rc$cmfF${ zN7jet>rnB=v+7-)rM{xckV@d^z!ZWOz^8*68!d#tenBm8h!mU$xm$ds@?O5>r1G=L z{xOJu{Q_q^SwG169|mlPfw)xwHo!XI#d}Q;5~Bj~MBF-2kDMlpaA%tP)RWoy&4pm#Z7s1_ z?5KmXfr+if?5}-mm~mz~L55LNJali2se>9?ptBZ)7fKuZ%(^5TsC?mc%3Lzggle!v z4nZrz|_bNcpEIo?Gvrh0A1n$o-D96!=K$G7$A_P z=V9x@<{wmi7~F!$z4Ib~EhMpq0wfWut+9vs%vr>CJcdzB=q2J!Bcwlt#Fx(q)q59? zWZeNB6)w=pLp>kH@P9OGG@oJy(% z7m6V!PCoGOm;6($IB!ob$o7)Iys!yMBS?l)3g&e;J*0+X000|m(@c4Jrfr_N2Jq8W zFxTPI{QOHWwYup|txRxGGg|pYl!-JIn%w8k%i6+6h;%4aO*quURM>g`&tIDzIa*>B z%`0i_3-I26_#|fd_h#V@`k4kJuL>gbklx~BM`~gz@X{NL&ut>@$mT~40rr!nFq=D2 z1$^c00S3f(n@i3qAFfFK8>$`h$ z(opKp!f{+&dJ>>NX_}_c8wM029SrgzX1ncJy*#E(x?ElI zZ!eD@J z?%%`UlJpV4_x7_+?TYpf&*&P>Ywm!cr#~-fYesDjyt2)pMhDOlR&yu|Vox1*j1vR< z@_WmtqZPVVZNh719j=WppTKyv*j}>-jPZF;4=tv5`5*wyTx|`%ciDc2LcbRZOJ8o2 z?alQHE4K@ zvmISO?WsM(nB9Lk#mV(29wS&94zvSIk z#0ct3jmAj`#gaN+b;meJXgIBGrgCe=_?*)QA_*O{h6lGA6kBt~+O&ql$~GKU&^Qp= zTyS$DWiv{whiJl#+3w?+6Mgca^uK0@@d47EvfRtjU3~~C>j#(eUGQIc=q@fzNnyQ{ z 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 literal 0 HcmV?d00001 diff --git a/examples/SmartSwitch/data/app.css.gz b/examples/SmartSwitch/data/app.css.gz new file mode 100644 index 0000000000000000000000000000000000000000..a5beb7d7e4f80b82d9860430de622bd7f38ff88d GIT binary patch literal 2740 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 literal 0 HcmV?d00001 diff --git a/examples/SmartSwitch/data/favicon.ico.gz b/examples/SmartSwitch/data/favicon.ico.gz new file mode 100644 index 0000000000000000000000000000000000000000..0cab430e3937861565e9a75680255486ee4df01c GIT binary patch literal 4314 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 IB`!Pw0Np(IrT_o{ literal 0 HcmV?d00001 diff --git a/examples/SmartSwitch/data/index.htm.gz b/examples/SmartSwitch/data/index.htm.gz new file mode 100644 index 0000000000000000000000000000000000000000..807a1fecf780f80d98171a8fc05cdccaf7a2011a GIT binary patch literal 3834 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 literal 0 HcmV?d00001 diff --git a/examples/SmartSwitch/data/index2.htm b/examples/SmartSwitch/data/index2.htm new file mode 100644 index 000000000..44c86bfc0 --- /dev/null +++ b/examples/SmartSwitch/data/index2.htm @@ -0,0 +1,585 @@ + + + + + + Smart Switch + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + +
+
+ + + + + + + + +
+ + + + + +
+
+ +
+
+
+ +
+
+
+ +
+
+
+
+
+ +
+
+ +

+
+
+
+ +
+
+ + + + + + + + \ No newline at end of file diff --git a/examples/SmartSwitch/data_src/acefull.js b/examples/SmartSwitch/data_src/acefull.js new file mode 100644 index 000000000..46b3712d0 --- /dev/null +++ b/examples/SmartSwitch/data_src/acefull.js @@ -0,0 +1 @@ +(function(){var e=function(){return this}();!e&&"undefined"!=typeof window&&(e=window);var o=function(e,t,i){"string"==typeof e?(2==arguments.length&&(i=t),o.modules[e]||(o.payloads[e]=i,o.modules[e]=null)):o.original?o.original.apply(this,arguments):(console.error("dropping module because define wasn't a string."),console.trace())};o.modules={},o.payloads={};var t,i,r=function(e,t,i){if("string"==typeof t){var n=c(e,t);if(null!=n)return i&&i(),n}else if("[object Array]"===Object.prototype.toString.call(t)){for(var s=[],o=0,r=t.length;os.index&&this.lastIndex--}return s},l||(RegExp.prototype.test=function(e){var t=r.exec.call(this,e);return t&&this.global&&!t[0].length&&this.lastIndex>t.index&&this.lastIndex--,!!t}))}),ace.define("ace/lib/es5-shim",["require","exports","module"],function(e,t,i){function o(){}function n(e){try{return Object.defineProperty(e,"sentinel",{}),"sentinel"in e}catch(e){}}function s(e){return(e=+e)!=e?e=0:0!==e&&e!==1/0&&e!==-1/0&&(e=(0>>0;if("[object Function]"!=m(e))throw new TypeError;for(;++s>>0,s=Array(n),o=arguments[1];if("[object Function]"!=m(e))throw new TypeError(e+" is not a function");for(var r=0;r>>0,o=[],r=arguments[1];if("[object Function]"!=m(e))throw new TypeError(e+" is not a function");for(var a=0;a>>0,s=arguments[1];if("[object Function]"!=m(e))throw new TypeError(e+" is not a function");for(var o=0;o>>0,s=arguments[1];if("[object Function]"!=m(e))throw new TypeError(e+" is not a function");for(var o=0;o>>0;if("[object Function]"!=m(e))throw new TypeError(e+" is not a function");if(!n&&1==arguments.length)throw new TypeError("reduce of empty array with no initial value");var s,o=0;if(2<=arguments.length)s=arguments[1];else for(;;){if(o in i){s=i[o++];break}if(++o>=n)throw new TypeError("reduce of empty array with no initial value")}for(;o>>0;if("[object Function]"!=m(e))throw new TypeError(e+" is not a function");if(!n&&1==arguments.length)throw new TypeError("reduceRight of empty array with no initial value");var s,o=n-1;if(2<=arguments.length)s=arguments[1];else for(;;){if(o in i){s=i[o--];break}if(--o<0)throw new TypeError("reduceRight of empty array with no initial value")}for(;o in this&&(s=e.call(void 0,s,i[o],o,t)),o--;);return s}),Array.prototype.indexOf&&-1==[0,1].indexOf(1,2)||(Array.prototype.indexOf=function(e){var t=$&&"[object String]"==m(this)?this.split(""):M(this),i=t.length>>>0;if(!i)return-1;var n=0;for(1>>0;if(!i)return-1;var n=i-1;for(1 ["+this.end.row+"/"+this.end.column+"]"},this.contains=function(e,t){return 0==this.compare(e,t)},this.compareRange=function(e){var t,i=e.end,n=e.start;return 1==(t=this.compare(i.row,i.column))?1==(t=this.compare(n.row,n.column))?2:0==t?1:0:-1==t?-2:-1==(t=this.compare(n.row,n.column))?-1:1==t?42:0},this.comparePoint=function(e){return this.compare(e.row,e.column)},this.containsRange=function(e){return 0==this.comparePoint(e.start)&&0==this.comparePoint(e.end)},this.intersects=function(e){var t=this.compareRange(e);return-1==t||0==t||1==t},this.isEnd=function(e,t){return this.end.row==e&&this.end.column==t},this.isStart=function(e,t){return this.start.row==e&&this.start.column==t},this.setStart=function(e,t){"object"==typeof e?(this.start.column=e.column,this.start.row=e.row):(this.start.row=e,this.start.column=t)},this.setEnd=function(e,t){"object"==typeof e?(this.end.column=e.column,this.end.row=e.row):(this.end.row=e,this.end.column=t)},this.inside=function(e,t){return 0==this.compare(e,t)&&(!this.isEnd(e,t)&&!this.isStart(e,t))},this.insideStart=function(e,t){return 0==this.compare(e,t)&&!this.isEnd(e,t)},this.insideEnd=function(e,t){return 0==this.compare(e,t)&&!this.isStart(e,t)},this.compare=function(e,t){return this.isMultiLine()||e!==this.start.row?ethis.end.row?1:this.start.row===e?t>=this.start.column?0:-1:this.end.row===e?t<=this.end.column?0:1:0:tthis.end.column?1:0},this.compareStart=function(e,t){return this.start.row==e&&this.start.column==t?-1:this.compare(e,t)},this.compareEnd=function(e,t){return this.end.row==e&&this.end.column==t?1:this.compare(e,t)},this.compareInside=function(e,t){return this.end.row==e&&this.end.column==t?1:this.start.row==e&&this.start.column==t?-1:this.compare(e,t)},this.clipRows=function(e,t){if(this.end.row>t)var i={row:t+1,column:0};else if(this.end.rowt)var n={row:t+1,column:0};else if(this.start.row>=1)&&(e+=e);return i};var n=/^\s\s*/,s=/\s\s*$/;t.stringTrimLeft=function(e){return e.replace(n,"")},t.stringTrimRight=function(e){return e.replace(s,"")},t.copyObject=function(e){var t={};for(var i in e)t[i]=e[i];return t},t.copyArray=function(e){for(var t=[],i=0,n=e.length;ii+1?a.length:s,s+=o.length+1,o=o+"\n"+a}400w-1&&v[v.length-c]==e[e.length-c];)c++,o--;return a-=c-1,l-=c-1,r=r.slice(0,r.length-c+1),t||a!=r.length||s||o||l?(f=!0,r&&!s&&!o&&!a&&!l||p?h.onTextInput(r):h.onTextInput(r,{extendLeft:s,extendRight:o,restoreStart:a,restoreEnd:l}),f=!1,v=e,w=i,b=n,r):""},o=function(e){if(g)return A();var t=u.value,i=s(t,!0);(500=v.length&&t.value===v&&v&&t.selectionEnd!==b&&(h.selectAll(),$()))}),T.addListener(u,"input",o),T.addListener(u,"cut",k),T.addListener(u,"copy",C),T.addListener(u,"paste",S),(!("oncut"in u)||!("oncopy"in u)||!("onpaste"in u))&&T.addListener(e,"keydown",function(e){if((!M.isMac||e.metaKey)&&e.ctrlKey)switch(e.keyCode){case 67:C(e);break;case 86:S(e);break;case 88:k(e)}});var A=function(){if(g&&h.onCompositionUpdate&&!h.$readOnly){if(p)return i();if(g.useTextareaForIME)h.onCompositionUpdate(u.value);else{var e=u.value;s(e),g.markerRange&&(g.context&&(g.markerRange.start.column=g.selectionStart=g.context.compositionStartOffset),g.markerRange.end.column=g.markerRange.start.column+b-g.selectionStart)}}},L=function(e){h.onCompositionEnd&&!h.$readOnly&&(g=!1,h.onCompositionEnd(),h.off("mousedown",i),e&&o())},R=O.delayedCall(A,50).schedule.bind(null,null);T.addListener(u,"compositionstart",function(e){if(!g&&h.onCompositionStart&&!h.$readOnly&&(g={},!p)){setTimeout(A,0),h.on("mousedown",i);var t=h.getSelectionRange();t.end.row=t.start.row,t.end.column=t.start.column,g.markerRange=t,g.selectionStart=w,h.onCompositionStart(g),g.useTextareaForIME?(u.value="",v="",b=w=0):(u.msGetInputContext&&(g.context=u.msGetInputContext()),u.getInputContext&&(g.context=u.getInputContext()))}}),T.addListener(u,"compositionupdate",A),T.addListener(u,"keyup",function(e){27==e.keyCode&&u.value.lengththis.$focusTimeout)&&this.startSelect(this.mousedownEvent.getDocumentPosition())},this.onDoubleClick=function(e){var t=e.getDocumentPosition(),i=this.editor,n=i.session.getBracketRange(t);n?(n.isEmpty()&&(n.start.column--,n.end.column++),this.setState("select")):(n=i.selection.getWordRange(t.row,t.column),this.setState("selectByWords")),this.$clickSelection=n,this.select()},this.onTripleClick=function(e){var t=e.getDocumentPosition(),i=this.editor;this.setState("selectByLines");var n=i.getSelectionRange();n.isMultiLine()&&n.contains(t.row,t.column)?(this.$clickSelection=i.selection.getLineRange(n.start.row),this.$clickSelection.end=i.selection.getLineRange(n.end.row).end):this.$clickSelection=i.selection.getLineRange(t.row),this.select()},this.onQuadClick=function(e){var t=this.editor;t.selectAll(),this.$clickSelection=t.getSelectionRange(),this.setState("selectAll")},this.onMouseWheel=function(e){if(!e.getAccelKey()){e.getShiftKey()&&e.wheelY&&!e.wheelX&&(e.wheelX=e.wheelY,e.wheelY=0);var t=this.editor;this.$lastScroll||(this.$lastScroll={t:0,vx:0,vy:0,allowed:0});var i=this.$lastScroll,n=e.domEvent.timeStamp,s=n-i.t,o=s?e.wheelX/s:i.vx,r=s?e.wheelY/s:i.vy;s<550&&(o=(o+i.vx)/2,r=(r+i.vy)/2);var a=Math.abs(o/r),l=!1;if(1<=a&&t.renderer.isScrollableBy(e.wheelX*e.speed,0)&&(l=!0),a<=1&&t.renderer.isScrollableBy(0,e.wheelY*e.speed)&&(l=!0),l)i.allowed=n;else if(n-i.allowed<550){var c=Math.abs(o)<=1.5*Math.abs(i.vx)&&Math.abs(r)<=1.5*Math.abs(i.vy);i.allowed=c?(l=!0,n):0}return i.t=n,i.vx=o,i.vy=r,l?(t.renderer.scrollBy(e.wheelX*e.speed,e.wheelY*e.speed),e.stop()):void 0}},this.onTouchMove=function(e){this.editor._emit("mousewheel",e)}}).call(n.prototype),t.DefaultHandlers=n}),ace.define("ace/tooltip",["require","exports","module","ace/lib/oop","ace/lib/dom"],function(e,t,i){"use strict";function n(e){this.isOpen=!1,this.$element=null,this.$parentNode=e}e("./lib/oop");var s=e("./lib/dom");(function(){this.$init=function(){return this.$element=s.createElement("div"),this.$element.className="ace_tooltip",this.$element.style.display="none",this.$parentNode.appendChild(this.$element),this.$element},this.getElement=function(){return this.$element||this.$init()},this.setText=function(e){this.getElement().textContent=e},this.setHtml=function(e){this.getElement().innerHTML=e},this.setPosition=function(e,t){this.getElement().style.left=e+"px",this.getElement().style.top=t+"px"},this.setClassName=function(e){s.addCssClass(this.getElement(),e)},this.show=function(e,t,i){null!=e&&this.setText(e),null!=t&&null!=i&&this.setPosition(t,i),this.isOpen||(this.getElement().style.display="block",this.isOpen=!0)},this.hide=function(){this.isOpen&&(this.getElement().style.display="none",this.isOpen=!1)},this.getHeight=function(){return this.getElement().offsetHeight},this.getWidth=function(){return this.getElement().offsetWidth},this.destroy=function(){this.isOpen=!1,this.$element&&this.$element.parentNode&&this.$element.parentNode.removeChild(this.$element)}}).call(n.prototype),t.Tooltip=n}),ace.define("ace/mouse/default_gutter_handler",["require","exports","module","ace/lib/dom","ace/lib/oop","ace/lib/event","ace/tooltip"],function(e,t,i){"use strict";function n(e){r.call(this,e)}var s=e("../lib/dom"),o=e("../lib/oop"),f=e("../lib/event"),r=e("../tooltip").Tooltip;o.inherits(n,r),function(){this.setPosition=function(e,t){var i=window.innerWidth||document.documentElement.clientWidth,n=window.innerHeight||document.documentElement.clientHeight,s=this.getWidth(),o=this.getHeight();i<(e+=15)+s&&(e-=e+s-i),n<(t+=15)+o&&(t-=20+o),r.prototype.setPosition.call(this,e,t)}}.call(n.prototype),t.GutterHandler=function(r){function a(){i&&(i=clearTimeout(i)),h&&(g.hide(),h=null,u._signal("hideGutterTooltip",g),u.removeEventListener("mousewheel",a))}function l(e){g.setPosition(e.x,e.y)}var i,c,h,u=r.editor,d=u.renderer.$gutterLayer,g=new n(u.container);r.editor.setDefaultHandler("guttermousedown",function(e){if(u.isFocused()&&0==e.getButton()&&"foldWidgets"!=d.getRegion(e)){var t=e.getDocumentPosition().row,i=u.session.selection;if(e.getShiftKey())i.selectTo(t,0);else{if(2==e.domEvent.detail)return u.selectAll(),e.preventDefault();r.$clickSelection=u.selection.getLineRange(t)}return r.setState("selectByLines"),r.captureMouse(e),e.preventDefault()}}),r.editor.setDefaultHandler("guttermousemove",function(e){var t=e.domEvent.target||e.domEvent.srcElement;if(s.hasCssClass(t,"ace_fold-widget"))return a();h&&r.$tooltipFollowsMouse&&l(e),c=e,i||(i=setTimeout(function(){i=null,c&&!r.isMousePressed?function(){var e=c.getDocumentPosition().row,t=d.$annotations[e];if(!t)return a();if(e==u.session.getLength()){var i=u.renderer.pixelToScreenCoordinates(0,c.y).row,n=c.$pos;if(i>u.session.documentToScreenRow(n.row,n.column))return a()}if(h!=t)if(h=t.text.join("
"),g.setHtml(h),g.show(),u._signal("showGutterTooltip",g),u.on("mousewheel",a),r.$tooltipFollowsMouse)l(c);else{var s=c.domEvent.target.getBoundingClientRect(),o=g.getElement().style;o.left=s.right+"px",o.top=s.bottom+"px"}}():a()},50))}),f.addListener(u.renderer.$gutter,"mouseout",function(e){c=null,h&&!i&&(i=setTimeout(function(){i=null,a()},50))}),u.on("changeSession",a)}}),ace.define("ace/mouse/mouse_event",["require","exports","module","ace/lib/event","ace/lib/useragent"],function(e,t,i){"use strict";var n=e("../lib/event"),s=e("../lib/useragent"),o=t.MouseEvent=function(e,t){this.domEvent=e,this.editor=t,this.x=this.clientX=e.clientX,this.y=this.clientY=e.clientY,this.$pos=null,this.$inSelection=null,this.propagationStopped=!1,this.defaultPrevented=!1};(function(){this.stopPropagation=function(){n.stopPropagation(this.domEvent),this.propagationStopped=!0},this.preventDefault=function(){n.preventDefault(this.domEvent),this.defaultPrevented=!0},this.stop=function(){this.stopPropagation(),this.preventDefault()},this.getDocumentPosition=function(){return this.$pos||(this.$pos=this.editor.renderer.screenToTextCoordinates(this.clientX,this.clientY)),this.$pos},this.inSelection=function(){if(null!==this.$inSelection)return this.$inSelection;var e=this.editor.getSelectionRange();if(e.isEmpty())this.$inSelection=!1;else{var t=this.getDocumentPosition();this.$inSelection=e.contains(t.row,t.column)}return this.$inSelection},this.getButton=function(){return n.getButton(this.domEvent)},this.getShiftKey=function(){return this.domEvent.shiftKey},this.getAccelKey=s.isMac?function(){return this.domEvent.metaKey}:function(){return this.domEvent.ctrlKey}}).call(o.prototype)}),ace.define("ace/mouse/dragdrop_handler",["require","exports","module","ace/lib/dom","ace/lib/event","ace/lib/useragent"],function(e,t,i){"use strict";function n(t){function e(){var e,t,i,n,s,o=u;u=g.renderer.screenToTextCoordinates(f,m),e=u,t=o,i=Date.now(),n=!t||e.row!=t.row,s=!t||e.column!=t.column,!w||n||s?(g.moveCursorToPosition(e),w=i,b={x:f,y:m}):5this.editor.getDragDelay()&&this.startDrag()},this.dragWaitEnd=function(){this.editor.container.draggable=!1,this.startSelect(this.mousedownEvent.getDocumentPosition()),this.selectEnd()},this.dragReadyEnd=function(e){this.editor.renderer.$cursorLayer.setBlinking(!this.editor.getReadOnly()),this.editor.unsetStyle("ace_dragging"),this.editor.renderer.setCursorStyle(""),this.dragWaitEnd()},this.startDrag=function(){this.cancelDrag=!1;var e=this.editor;e.container.draggable=!0,e.renderer.$cursorLayer.setBlinking(!1),e.setStyle("ace_dragging");var t=A.isWin?"default":"move";e.renderer.setCursorStyle(t),this.setState("dragReady")},this.onMouseDrag=function(e){var t=this.editor.container;A.isIE&&"dragReady"==this.state&&(3=e){for(n=l+1;n=e;)n++;for(s=l,o=n-1;s=t.length||(s=i[n-1])!=g&&s!=f||(o=t[n+1])!=g&&o!=f?C:(b&&(o=f),o==s?o:C);case E:return(s=0>8;return 0==i?191L&&t[a]t.row||e.row==t.row&&e.column>t.column},this.getRange=function(){var e=this.anchor,t=this.lead;return this.$isEmpty?a.fromPoints(t,t):this.isBackwards()?a.fromPoints(t,e):a.fromPoints(e,t)},this.clearSelection=function(){this.$isEmpty||(this.$isEmpty=!0,this._emit("changeSelection"))},this.selectAll=function(){this.$setSelection(0,0,Number.MAX_VALUE,Number.MAX_VALUE)},this.setRange=this.setSelectionRange=function(e,t){var i=t?e.end:e.start,n=t?e.start:e.end;this.$setSelection(i.row,i.column,n.row,n.column)},this.$setSelection=function(e,t,i,n){var s=this.$isEmpty,o=this.inMultiSelectMode;this.$silent=!0,this.$cursorChanged=this.$anchorChanged=!1,this.anchor.setPosition(e,t),this.cursor.setPosition(i,n),this.$isEmpty=!a.comparePoints(this.anchor,this.cursor),this.$silent=!1,this.$cursorChanged&&this._emit("changeCursor"),(this.$cursorChanged||this.$anchorChanged||s!=this.$isEmpty||o)&&this._emit("changeSelection")},this.$moveSelection=function(e){var t=this.lead;this.$isEmpty&&this.setSelectionAnchor(t.row,t.column),e.call(this)},this.selectTo=function(e,t){this.$moveSelection(function(){this.moveCursorTo(e,t)})},this.selectToPosition=function(e){this.$moveSelection(function(){this.moveCursorToPosition(e)})},this.moveTo=function(e,t){this.clearSelection(),this.moveCursorTo(e,t)},this.moveToPosition=function(e){this.clearSelection(),this.moveCursorToPosition(e)},this.selectUp=function(){this.$moveSelection(this.moveCursorUp)},this.selectDown=function(){this.$moveSelection(this.moveCursorDown)},this.selectRight=function(){this.$moveSelection(this.moveCursorRight)},this.selectLeft=function(){this.$moveSelection(this.moveCursorLeft)},this.selectLineStart=function(){this.$moveSelection(this.moveCursorLineStart)},this.selectLineEnd=function(){this.$moveSelection(this.moveCursorLineEnd)},this.selectFileEnd=function(){this.$moveSelection(this.moveCursorFileEnd)},this.selectFileStart=function(){this.$moveSelection(this.moveCursorFileStart)},this.selectWordRight=function(){this.$moveSelection(this.moveCursorWordRight)},this.selectWordLeft=function(){this.$moveSelection(this.moveCursorWordLeft)},this.getWordRange=function(e,t){if(void 0===t){var i=e||this.lead;e=i.row,t=i.column}return this.session.getWordRange(e,t)},this.selectWord=function(){this.setSelectionRange(this.getWordRange())},this.selectAWord=function(){var e=this.getCursor(),t=this.session.getAWordRange(e.row,e.column);this.setSelectionRange(t)},this.getLineRange=function(e,t){var i,n="number"==typeof e?e:this.lead.row,s=this.session.getFoldLine(n);return i=s?(n=s.start.row,s.end.row):n,!0===t?new a(n,0,i,this.session.getLine(i).length):new a(n,0,i+1,0)},this.selectLine=function(){this.setSelectionRange(this.getLineRange())},this.moveCursorUp=function(){this.moveCursorBy(-1,0)},this.moveCursorDown=function(){this.moveCursorBy(1,0)},this.wouldMoveIntoSoftTab=function(e,t,i){var n=e.column,s=e.column+t;return i<0&&(n=e.column-t,s=e.column),this.session.isTabStop(e)&&this.doc.getLine(e.row).slice(n,s).split(" ").length-1==t},this.moveCursorLeft=function(){var e,t=this.lead.getPosition();if(e=this.session.getFoldAt(t.row,t.column,-1))this.moveCursorTo(e.start.row,e.start.column);else if(0===t.column)0=i.length)return this.moveCursorTo(e,i.length),this.moveCursorRight(),void(ec){var p=e.substring(c,m-f.length);u.type==d?u.value+=p:(u.type&&l.push(u),u={type:d,value:p})}for(var v=0;vw){for(h>2*e.length&&this.reportError("infinite loop with in ace tokenizer",{startState:t,line:e});c=this.$rowTokens.length;){if(this.$row+=1,e||(e=this.$session.getLength()),this.$row>=e)return this.$row=e-1,null;this.$rowTokens=this.$session.getTokens(this.$row),this.$tokenIndex=0}return this.$rowTokens[this.$tokenIndex]},this.getCurrentToken=function(){return this.$rowTokens[this.$tokenIndex]},this.getCurrentTokenRow=function(){return this.$row},this.getCurrentTokenColumn=function(){var e=this.$rowTokens,t=this.$tokenIndex,i=e[t].start;if(void 0!==i)return i;for(i=0;0e.length&&(y=e.length)}),l==1/0&&(l=y,a=r=!1),h&&l%c!=0&&(l=Math.floor(l/c)*c),t(a?w:v)},this.toggleBlockComment=function(e,t,i,n){var s=this.blockComment;if(s){!s.start&&s[0]&&(s=s[0]);var o,r,a=(g=new m(t,n.row,n.column)).getCurrentToken(),l=(t.selection,t.selection.toOrientedRange());if(a&&/comment/.test(a.type)){for(var c,h;a&&/comment/.test(a.type);){if(-1!=(f=a.value.indexOf(s.start))){var u=g.getCurrentTokenRow(),d=g.getCurrentTokenColumn()+f;c=new p(u,d,u,d+s.start.length);break}a=g.stepBackward()}var g;for(a=(g=new m(t,n.row,n.column)).getCurrentToken();a&&/comment/.test(a.type);){var f;if(-1!=(f=a.value.indexOf(s.end))){u=g.getCurrentTokenRow(),d=g.getCurrentTokenColumn()+f;h=new p(u,d,u,d+s.end.length);break}a=g.stepForward()}h&&t.remove(h),c&&(t.remove(c),o=c.start.row,r=-s.start.length)}else r=s.start.length,o=i.start.row,t.insert(i.end,s.end),t.insert(i.start,s.start);l.start.row==o&&(l.start.column+=r),l.end.row==o&&(l.end.column+=r),t.selection.fromOrientedRange(l)}},this.getNextLineIndent=function(e,t,i){return this.$getIndent(t)},this.checkOutdent=function(e,t,i){return!1},this.autoOutdent=function(e,t,i){},this.$getIndent=function(e){return e.match(/^\s*/)[0]},this.createWorker=function(e){return null},this.createModeDelegates=function(e){for(var n in this.$embeds=[],this.$modes={},e)if(e[n]){var t=e[n],i=t.prototype.$id,s=r.$modes[i];s||(r.$modes[i]=s=new t),r.$modes[n]||(r.$modes[n]=s),this.$embeds.push(n),this.$modes[n]=s}var o=["toggleBlockComment","toggleCommentLines","getNextLineIndent","checkOutdent","autoOutdent","transformAction","getCompletions"];for(n=0;nthis.row)){var t,i,n,s,o,r,a,l,c=(t=e,i={row:this.row,column:this.column},n=this.$insertRight,s="insert"==t.action,o=(s?1:-1)*(t.end.row-t.start.row),r=(s?1:-1)*(t.end.column-t.start.column),a=t.start,l=s?a:t.end,h(i,a,n)?{row:i.row,column:i.column}:h(l,i,!n)?{row:i.row+o,column:i.column+(i.row==l.row?r:0)}:{row:a.row,column:a.column});this.setPosition(c.row,c.column,!0)}},this.setPosition=function(e,t,i){var n;if(n=i?{row:e,column:t}:this.$clipPositionToDocument(e,t),this.row!=n.row||this.column!=n.column){var s={row:this.row,column:this.column};this.row=n.row,this.column=n.column,this._signal("change",{old:s,value:n})}},this.detach=function(){this.document.removeEventListener("change",this.$onChange)},this.attach=function(e){this.document=e||this.document,this.document.on("change",this.$onChange)},this.$clipPositionToDocument=function(e,t){var i={};return e>=this.document.getLength()?(i.row=Math.max(0,this.document.getLength()-1),i.column=this.document.getLine(i.row).length):i.column=e<0?i.row=0:(i.row=e,Math.min(this.document.getLine(i.row).length,Math.max(0,t))),t<0&&(i.column=0),i}}).call(o.prototype)}),ace.define("ace/document",["require","exports","module","ace/lib/oop","ace/apply_delta","ace/lib/event_emitter","ace/range","ace/anchor"],function(e,t,i){"use strict";var n=e("./lib/oop"),s=e("./apply_delta").applyDelta,o=e("./lib/event_emitter").EventEmitter,h=e("./range").Range,r=e("./anchor").Anchor,a=function(e){this.$lines=[""],0===e.length?this.$lines=[""]:Array.isArray(e)?this.insertMergedLines({row:0,column:0},e):this.insert({row:0,column:0},e)};(function(){n.implement(this,o),this.setValue=function(e){var t=this.getLength()-1;this.remove(new h(0,0,t,this.getLine(t).length)),this.insert({row:0,column:0},e)},this.getValue=function(){return this.getAllLines().join(this.getNewLineCharacter())},this.createAnchor=function(e,t){return new r(this,e,t)},0==="aaa".split(/a/).length?this.$split=function(e){return e.replace(/\r\n|\r/g,"\n").split("\n")}:this.$split=function(e){return e.split(/\r\n|\r|\n/)},this.$detectNewLine=function(e){var t=e.match(/^.*?(\r\n|\r|\n)/m);this.$autoNewLine=t?t[1]:"\n",this._signal("changeNewLineMode")},this.getNewLineCharacter=function(){switch(this.$newLineMode){case"windows":return"\r\n";case"unix":return"\n";default:return this.$autoNewLine||"\n"}},this.$autoNewLine="",this.$newLineMode="auto",this.setNewLineMode=function(e){this.$newLineMode!==e&&(this.$newLineMode=e,this._signal("changeNewLineMode"))},this.getNewLineMode=function(){return this.$newLineMode},this.isNewLine=function(e){return"\r\n"==e||"\r"==e||"\n"==e},this.getLine=function(e){return this.$lines[e]||""},this.getLines=function(e,t){return this.$lines.slice(e,t+1)},this.getAllLines=function(){return this.getLines(0,this.getLength())},this.getLength=function(){return this.$lines.length},this.getTextRange=function(e){return this.getLinesForRange(e).join(this.getNewLineCharacter())},this.getLinesForRange=function(e){var t;if(e.start.row===e.end.row)t=[this.getLine(e.start.row).substring(e.start.column,e.end.column)];else{(t=this.getLines(e.start.row,e.end.row))[0]=(t[0]||"").substring(e.start.column);var i=t.length-1;e.end.row-e.start.row==i&&(t[i]=t[i].substring(0,e.end.column))}return t},this.insertLines=function(e,t){return console.warn("Use of document.insertLines is deprecated. Use the insertFullLines method instead."),this.insertFullLines(e,t)},this.removeLines=function(e,t){return console.warn("Use of document.removeLines is deprecated. Use the removeFullLines method instead."),this.removeFullLines(e,t)},this.insertNewLine=function(e){return console.warn("Use of document.insertNewLine is deprecated. Use insertMergedLines(position, ['', '']) instead."),this.insertMergedLines(e,["",""])},this.insert=function(e,t){return this.getLength()<=1&&this.$detectNewLine(t),this.insertMergedLines(e,this.$split(t))},this.insertInLine=function(e,t){var i=this.clippedPos(e.row,e.column),n=this.pos(e.row,e.column+t.length);return this.applyDelta({start:i,end:n,action:"insert",lines:[t]},!0),this.clonePos(n)},this.clippedPos=function(e,t){var i=this.getLength();void 0===e?e=i:e<0?e=0:i<=e&&(e=i-1,t=void 0);var n=this.getLine(e);return null==t&&(t=n.length),{row:e,column:t=Math.min(Math.max(t,0),n.length)}},this.clonePos=function(e){return{row:e.row,column:e.column}},this.pos=function(e,t){return{row:e,column:t}},this.$clipPosition=function(e){var t=this.getLength();return e.row>=t?(e.row=Math.max(0,t-1),e.column=this.getLine(t-1).length):(e.row=Math.max(0,e.row),e.column=Math.min(Math.max(e.column,0),this.getLine(e.row).length)),e},this.insertFullLines=function(e,t){var i=0;i=(e=Math.min(Math.max(e,0),this.getLength()))e+1&&(this.currentLine=e+1)):this.currentLine==e&&(this.currentLine=e+1),this.lines[e]=n.tokens}}).call(o.prototype),t.BackgroundTokenizer=o}),ace.define("ace/search_highlight",["require","exports","module","ace/lib/lang","ace/lib/oop","ace/range"],function(e,t,i){"use strict";var c=e("./lib/lang"),h=(e("./lib/oop"),e("./range").Range),n=function(e,t,i){this.setRegexp(e),this.clazz=t,this.type=i||"text"};(function(){this.MAX_RANGES=500,this.setRegexp=function(e){this.regExp+""!=e+""&&(this.regExp=e,this.cache=[])},this.update=function(e,t,i,n){if(this.regExp)for(var s=n.firstRow,o=n.lastRow,r=s;r<=o;r++){var a=this.cache[r];null==a&&((a=c.getMatchOffsets(i.getLine(r),this.regExp)).length>this.MAX_RANGES&&(a=a.slice(0,this.MAX_RANGES)),a=a.map(function(e){return new h(r,e.offset,r,e.offset+e.length)}),this.cache[r]=a.length?a:"");for(var l=a.length;l--;)t.drawSingleLineMarker(e,a[l].toScreenRange(i),this.clazz,n)}}}).call(n.prototype),t.SearchHighlight=n}),ace.define("ace/edit_session/fold_line",["require","exports","module","ace/range"],function(e,t,i){"use strict";function c(e,t){this.foldData=e,Array.isArray(t)?this.folds=t:t=this.folds=[t];var i=t[t.length-1];this.range=new n(t[0].start.row,t[0].start.column,i.end.row,i.end.column),this.start=this.range.start,this.end=this.range.end,this.folds.forEach(function(e){e.setFoldLine(this)},this)}var n=e("../range").Range;(function(){this.shiftRow=function(t){this.start.row+=t,this.end.row+=t,this.folds.forEach(function(e){e.start.row+=t,e.end.row+=t})},this.addFold=function(e){if(e.sameRow){if(e.start.rowthis.endRow)throw new Error("Can't add a fold to this FoldLine as it has no connection");this.folds.push(e),this.folds.sort(function(e,t){return-e.range.compareEnd(t.start.row,t.start.column)}),0=this.start.row&&e<=this.end.row},this.walk=function(e,t,i){var n,s,o=0,r=this.folds,a=!0;null==t&&(t=this.end.row,i=this.end.column);for(var l=0;lt||i[i.length-1].start.row=n)break}if("insert"==e.action)for(var l=s-n,c=-t.column+i.column;rn)break;if(h.start.row==n&&h.start.column>=t.column&&(h.start.column!=t.column||!this.$insertRight)&&(h.start.column+=c,h.start.row+=l),h.end.row==n&&h.end.column>=t.column){if(h.end.column==t.column&&this.$insertRight)continue;h.end.column==t.column&&0h.start.column&&h.end.column==o[r+1].start.column&&(h.end.column-=c),h.end.column+=c,h.end.row+=l}}else for(l=n-s,c=t.column-i.column;rs)break;h.end.rowt.column)&&(h.end.column=t.column,h.end.row=t.row):(h.end.column+=c,h.end.row+=l):h.end.row>s&&(h.end.row+=l),h.start.rowt.column)&&(h.start.column=t.column,h.start.row=t.row):(h.start.column+=c,h.start.row+=l):h.start.row>s&&(h.start.row+=l)}if(0!=l&&r=e)return s;if(s.end.row>e)return null}return null},this.getNextFoldLine=function(e,t){var i=this.$foldData,n=0;for(t&&(n=i.indexOf(t)),-1==n&&(n=0);n=e)return s}return null},this.getFoldedRowCount=function(e,t){for(var i=this.$foldData,n=t-e+1,s=0;sl)break}while(s&&r.test(s.type));s=n.stepBackward()}else s=n.getCurrentToken();return a.end.row=n.getCurrentTokenRow(),a.end.column=n.getCurrentTokenColumn()+s.value.length-2,a}},this.foldAll=function(e,t,i){null==i&&(i=1e5);var n=this.foldWidgets;if(n){t=t||this.getLength();for(var s=e=e||0;s=e){s=o.end.row;try{var r=this.addFold("...",o);r&&(r.collapseChildren=i)}catch(e){}}}}},this.$foldStyles={manual:1,markbegin:1,markbeginend:1},this.$foldStyle="markbegin",this.setFoldStyle=function(e){if(!this.$foldStyles[e])throw new Error("invalid fold style: "+e+"["+Object.keys(this.$foldStyles).join(", ")+"]");if(this.$foldStyle!=e){"manual"==(this.$foldStyle=e)&&this.unfold();var t=this.$foldMode;this.$setFolding(null),this.$setFolding(t)}},this.$setFolding=function(e){this.$foldMode!=e&&(this.$foldMode=e,this.off("change",this.$updateFoldWidgets),this.off("tokenizerUpdate",this.$tokenizerUpdateFoldWidgets),this._signal("changeAnnotation"),e&&"manual"!=this.$foldStyle?(this.foldWidgets=[],this.getFoldWidget=e.getFoldWidget.bind(e,this,this.$foldStyle),this.getFoldWidgetRange=e.getFoldWidgetRange.bind(e,this,this.$foldStyle),this.$updateFoldWidgets=this.updateFoldWidgets.bind(this),this.$tokenizerUpdateFoldWidgets=this.tokenizerUpdateFoldWidgets.bind(this),this.on("change",this.$updateFoldWidgets),this.on("tokenizerUpdate",this.$tokenizerUpdateFoldWidgets)):this.foldWidgets=null)},this.getParentFoldRangeData=function(e,t){var i=this.foldWidgets;if(!i||t&&i[e])return{};for(var n,s=e-1;0<=s;){var o=i[s];if(null==o&&(o=i[s]=this.getFoldWidget(s)),"start"==o){var r=this.getFoldWidgetRange(s);if(n||(n=r),r&&r.end.row>=e)break}s--}return{range:-1!==s&&r,firstRange:n}},this.onFoldWidgetClick=function(e,t){var i={children:(t=t.domEvent).shiftKey,all:t.ctrlKey||t.metaKey,siblings:t.altKey};if(!this.$toggleFoldWidget(e,i)){var n=t.target||t.srcElement;n&&/ace_fold-widget/.test(n.className)&&(n.className+=" ace_invalid")}},this.$toggleFoldWidget=function(e,t){if(this.getFoldWidget){var i=this.getFoldWidget(e),n=this.getLine(e),s="end"===i?-1:1,o=this.getFoldAt(e,-1===s?0:n.length,s);if(o)return t.children||t.all?this.removeFold(o):this.expandFold(o),o;var r=this.getFoldWidgetRange(e,!0);if(r&&!r.isMultiLine()&&(o=this.getFoldAt(r.start.row,r.start.column,1))&&r.isEqual(o.range))return this.removeFold(o),o;if(t.siblings){var a=this.getParentFoldRangeData(e);if(a.range)var l=a.range.start.row+1,c=a.range.end.row;this.foldAll(l,c,t.all?1e4:0)}else t.children?(c=r?r.end.row:this.getLength(),this.foldAll(e+1,c,t.all?1e4:0)):r&&(t.all&&(r.collapseChildren=1e4),this.addFold("...",r));return r}},this.toggleFoldWidget=function(e){var t=this.selection.getCursor().row;t=this.getRowFoldStart(t);var i=this.$toggleFoldWidget(t,{});if(!i){var n=this.getParentFoldRangeData(t,!0);if(i=n.range||n.firstRange){t=i.start.row;var s=this.getFoldAt(t,this.getLine(t).length,1);s?this.removeFold(s):this.addFold("...",i)}}},this.updateFoldWidgets=function(e){var t=e.start.row,i=e.end.row-t;if(0===i)this.foldWidgets[t]=null;else if("remove"==e.action)this.foldWidgets.splice(t,i+1,null);else{var n=Array(i+1);n.unshift(t,1),this.foldWidgets.splice.apply(this.foldWidgets,n)}},this.tokenizerUpdateFoldWidgets=function(e){var t=e.data;t.first!=t.last&&this.foldWidgets.length>t.first&&this.foldWidgets.splice(t.first,this.foldWidgets.length)}}}),ace.define("ace/edit_session/bracket_match",["require","exports","module","ace/token_iterator","ace/range"],function(e,t,i){"use strict";var u=e("../token_iterator").TokenIterator,a=e("../range").Range;t.BracketMatch=function(){this.findMatchingBracket=function(e,t){if(0==e.column)return null;var i=t||this.getLine(e.row).charAt(e.column-1);if(""==i)return null;var n=i.match(/([\(\[\{])|([\)\]\}])/);return n?n[1]?this.$findClosingBracket(n[1],e):this.$findOpeningBracket(n[2],e):null},this.getBracketRange=function(e){var t,i=this.getLine(e.row),n=!0,s=i.charAt(e.column-1),o=s&&s.match(/([\(\[\{])|([\)\]\}])/);if(o||(s=i.charAt(e.column),e={row:e.row,column:e.column+1},o=s&&s.match(/([\(\[\{])|([\)\]\}])/),n=!1),!o)return null;if(o[1]){if(!(r=this.$findClosingBracket(o[1],e)))return null;t=a.fromPoints(e,r),n||(t.end.column++,t.start.column--),t.cursor=t.end}else{var r;if(!(r=this.$findOpeningBracket(o[2],e)))return null;t=a.fromPoints(r,e),n||(t.start.column++,t.end.column--),t.cursor=t.start}return t},this.$brackets={")":"(","(":")","]":"[","[":"]","{":"}","}":"{","<":">",">":"<"},this.$findOpeningBracket=function(e,t,i){var n=this.$brackets[e],s=1,o=new u(this,t.row,t.column),r=o.getCurrentToken();if(r||(r=o.stepForward()),r){i||(i=new RegExp("(\\.?"+r.type.replace(".","\\.").replace("rparen",".paren").replace(/\b(?:end)\b/,"(?:start|begin|end)")+")+"));for(var a=t.column-o.getCurrentTokenColumn()-2,l=r.value;;){for(;0<=a;){var c=l.charAt(a);if(c==n){if(0==(s-=1))return{row:o.getCurrentTokenRow(),column:a+o.getCurrentTokenColumn()}}else c==e&&(s+=1);a-=1}for(;(r=o.stepBackward())&&!i.test(r.type););if(null==r)break;a=(l=r.value).length-1}return null}},this.$findClosingBracket=function(e,t,i){var n=this.$brackets[e],s=1,o=new u(this,t.row,t.column),r=o.getCurrentToken();if(r||(r=o.stepForward()),r){i||(i=new RegExp("(\\.?"+r.type.replace(".","\\.").replace("lparen",".paren").replace(/\b(?:start|begin)\b/,"(?:start|begin|end)")+")+"));for(var a=t.column-o.getCurrentTokenColumn();;){for(var l=r.value,c=l.length;a>1,o=e[s];if(ot&&(t=e.screenWidth)}),this.lineWidgetWidth=t},this.$computeWidth=function(e){if(this.$modified||e){if(this.$modified=!1,this.$useWrapMode)return this.screenWidth=this.$wrapLimit;for(var t=this.doc.getAllLines(),i=this.$rowLengthCache,n=0,s=0,o=this.$foldData[s],r=o?o.start.row:1/0,a=t.length,l=0;ln&&(n=i[l])}this.screenWidth=n}},this.getLine=function(e){return this.doc.getLine(e)},this.getLines=function(e,t){return this.doc.getLines(e,t)},this.getLength=function(){return this.doc.getLength()},this.getTextRange=function(e){return this.doc.getTextRange(e||this.selection.getRange())},this.insert=function(e,t){return this.doc.insert(e,t)},this.remove=function(e){return this.doc.remove(e)},this.removeFullLines=function(e,t){return this.doc.removeFullLines(e,t)},this.undoChanges=function(e,t){if(e.length){this.$fromUndo=!0;for(var i=e.length-1;-1!=i;i--){var n=e[i];"insert"==n.action||"remove"==n.action?this.doc.revertDelta(n):n.folds&&this.addFolds(n.folds)}!t&&this.$undoSelect&&(e.selectionBefore?this.selection.fromJSON(e.selectionBefore):this.selection.setRange(this.$getUndoSelection(e,!0))),this.$fromUndo=!1}},this.redoChanges=function(e,t){if(e.length){this.$fromUndo=!0;for(var i=0;ie.end.column&&(o.start.column+=c),o.end.row==e.end.row&&o.end.column>e.end.column&&(o.end.column+=c)),r&&o.start.row>=e.end.row&&(o.start.row+=r,o.end.row+=r)}if(o.end=this.insert(o.start,n),s.length){var a=e.start,l=o.start,c=(r=l.row-a.row,l.column-a.column);this.addFolds(s.map(function(e){return(e=e.clone()).start.row==a.row&&(e.start.column+=c),e.end.row==a.row&&(e.end.column+=c),e.start.row+=r,e.end.row+=r,e}))}return o},this.indentRows=function(e,t,i){i=i.replace(/\t/g,this.getTabString());for(var n=e;n<=t;n++)this.doc.insertInLine({row:n,column:0},i)},this.outdentRows=function(e){for(var t=e.collapseRows(),i=new h(0,0,0,0),n=this.getTabSize(),s=t.start.row;s<=t.end.row;++s){var o=this.getLine(s);i.start.row=s,i.end.row=s;for(var r=0;rthis.doc.getLength()-1)return 0;n=s-t}else{e=this.$clipRowToDocument(e);n=(t=this.$clipRowToDocument(t))-e+1}var o=new h(e,0,t,Number.MAX_VALUE),r=this.getFoldsInRange(o).map(function(e){return(e=e.clone()).start.row+=n,e.end.row+=n,e}),a=0==i?this.doc.getLines(e,t):this.doc.removeFullLines(e,t);return this.doc.insertFullLines(e+n,a),r.length&&this.addFolds(r),n},this.moveLinesUp=function(e,t){return this.$moveLines(e,t,-1)},this.moveLinesDown=function(e,t){return this.$moveLines(e,t,1)},this.duplicateLines=function(e,t){return this.$moveLines(e,t,0)},this.$clipRowToDocument=function(e){return Math.max(0,Math.min(e,this.doc.getLength()-1))},this.$clipColumnToRow=function(e,t){return t<0?0:Math.min(this.doc.getLine(e).length,t)},this.$clipPositionToDocument=function(e,t){if(t=Math.max(0,t),e<0)t=e=0;else{var i=this.doc.getLength();t=i<=e?(e=i-1,this.doc.getLine(i-1).length):Math.min(this.doc.getLine(e).length,t)}return{row:e,column:t}},this.$clipRangeToDocument=function(e){e.start.row<0?(e.start.row=0,e.start.column=0):e.start.column=this.$clipColumnToRow(e.start.row,e.start.column);var t=this.doc.getLength()-1;return e.end.row>t?(e.end.row=t,e.end.column=this.doc.getLine(t).length):e.end.column=this.$clipColumnToRow(e.end.row,e.end.column),e},this.$wrapLimit=80,this.$useWrapMode=!1,this.$wrapLimitRange={min:null,max:null},this.setUseWrapMode=function(e){if(e!=this.$useWrapMode){if(this.$useWrapMode=e,this.$modified=!0,this.$resetRowCache(0),e){var t=this.getLength();this.$wrapData=Array(t),this.$updateWrapData(0,t-1)}this._signal("changeWrapMode")}},this.getUseWrapMode=function(){return this.$useWrapMode},this.setWrapLimitRange=function(e,t){this.$wrapLimitRange.min===e&&this.$wrapLimitRange.max===t||(this.$wrapLimitRange={min:e,max:t},this.$modified=!0,this.$bidiHandler.markAsDirty(),this.$useWrapMode&&this._signal("changeWrapMode"))},this.adjustWrapLimit=function(e,t){var i=this.$wrapLimitRange;i.max<0&&(i={min:t,max:t});var n=this.$constrainWrapLimit(e,i.min,i.max);return n!=this.$wrapLimit&&1=s.row&&m.shiftRow(-a)}r=o}else{var d=Array(a);d.unshift(o,0);var g=t?this.$wrapData:this.$rowLengthCache;g.splice.apply(g,d);c=this.$foldData,h=0;if(m=this.getFoldLine(o)){var f=m.range.compareInside(n.row,n.column);0==f?(m=m.split(n.row,n.column))&&(m.shiftRow(a),m.addRemoveChars(r,0,s.column-n.column)):-1==f&&(m.addRemoveChars(o,0,s.column-n.column),m.shiftRow(a)),h=c.indexOf(m)+1}for(;h=o&&m.shiftRow(a)}}else a=Math.abs(e.start.column-e.end.column),"remove"===i&&(l=this.getFoldsInRange(e),this.removeFolds(l),a=-a),(m=this.getFoldLine(o))&&m.addRemoveChars(o,n.column,a);return t&&this.$wrapData.length!=this.doc.getLength()&&console.error("doc.getLength() and $wrapData.length have to be the same!"),this.$updating=!1,t?this.$updateWrapData(o,r):this.$updateRowLengthCache(o,r),l},this.$updateRowLengthCache=function(e,t,i){this.$rowLengthCache[e]=null,this.$rowLengthCache[t]=null},this.$updateWrapData=function(e,t){var r,i,a=this.doc.getAllLines(),n=this.getTabSize(),s=this.$wrapData,o=this.$wrapLimit,l=e;for(t=Math.min(t,a.length-1);l<=t;)(i=this.getFoldLine(l,i))?(r=[],i.walk(function(e,t,i,n){var s;if(null!=e){(s=this.$getDisplayTokens(e,r.length))[0]=f;for(var o=1;o>2)),a-1);gc[u-1]}else d=!u;for(var g=this.getLength()-1,f=this.getNextFoldLine(o),m=f?f.start.row:1/0;a<=e&&!(el[h-1]}else u=!h;for(var d=this.getNextFoldLine(a),g=d?d.start.row:1/0;a=p[v];)s++,v++;f=f.substring(p[v-1]||0,f.length),m=0g||(s.push(r=new $(c,g,c+a-1,f)),2b&&s[h].end.row==i.end.row;)h--;for(s=s.slice(m,h+1),m=0,h=s.length;m=s.length)break;u.lastIndex=r+=1}if(n.index+a>t)break;o.push(n.index,a)}for(var l=o.length-1;0<=l;l-=2){var c=o[l-1];if(i(e,c,e,c+(a=o[l])))return!0}};else a=function(e,t,i){var n,s,o=h.getLine(e);for(u.lastIndex=t;s=u.exec(o);){var r=s[0].length;if(i(e,n=s.index,e,n+r))return!0;if(!r&&(u.lastIndex=n+=1,n>=o.length))return!1}};return{forEach:r}}}).call(s.prototype),t.Search=s}),ace.define("ace/keyboard/hash_handler",["require","exports","module","ace/lib/keys","ace/lib/useragent"],function(e,t,i){"use strict";function n(e,t){this.platform=t||(o.isMac?"mac":"win"),this.commands={},this.commandKeyBinding={},this.addCommands(e),this.$singleCommand=!0}function s(e,t){n.call(this,e,t),this.$singleCommand=!1}var a=e("../lib/keys"),o=e("../lib/useragent"),l=a.KEY_MODS;s.prototype=n.prototype,function(){function r(e){return"object"==typeof e&&e.bindKey&&e.bindKey.position||(e.isDefault?-100:0)}this.addCommand=function(e){this.commands[e.name]&&this.removeCommand(e),(this.commands[e.name]=e).bindKey&&this._buildKeyHash(e)},this.removeCommand=function(e,t){var i=e&&("string"==typeof e?e:e.name);e=this.commands[i],t||delete this.commands[i];var n=this.commandKeyBinding;for(var s in n){var o=n[s];if(o==e)delete n[s];else if(Array.isArray(o)){var r=o.indexOf(e);-1!=r&&(o.splice(r,1),1==o.length&&(n[s]=o[0]))}}},this.bindKey=function(e,o,r){if("object"==typeof e&&e&&(null==r&&(r=e.position),e=e[this.platform]),e)return"function"==typeof o?this.addCommand({exec:o,bindKey:e,name:o.name||e}):void e.split("|").forEach(function(e){var n="";if(-1!=e.indexOf(" ")){var t=e.split(/\s+/);e=t.pop(),t.forEach(function(e){var t=this.parseKeys(e),i=l[t.hashId]+t.key;n+=(n?" ":"")+i,this._addCommandToBinding(n,"chainKeys")},this),n+=" "}var i=this.parseKeys(e),s=l[i.hashId]+i.key;this._addCommandToBinding(n+s,o,r)},this)},this._addCommandToBinding=function(e,t,i){var n,s=this.commandKeyBinding;if(t)if(!s[e]||this.$singleCommand)s[e]=t;else{Array.isArray(s[e])?-1!=(n=s[e].indexOf(t))&&s[e].splice(n,1):s[e]=[s[e]],"number"!=typeof i&&(i=r(t));var o=s[e];for(n=0;ns?s+1:s,e.selection.moveCursorTo(i.row,s))},multiSelectAction:"forEach",readOnly:!0},{name:"invertSelection",bindKey:n(null,null),exec:function(e){var t=e.session.doc.getLength()-1,i=e.session.doc.getLine(t).length,n=e.selection.rangeList.ranges,s=[];n.length<1&&(n=[e.selection.getRange()]);for(var o=0;o=s.lastRow||n.end.row<=s.firstRow)&&this.renderer.scrollSelectionIntoView(this.selection.anchor,this.selection.lead)}"animate"==i&&this.renderer.animateScrolling(this.curOp.scrollTop)}var o=this.selection.toJSON();this.curOp.selectionAfter=o,this.$lastSel=this.selection.toJSON(),this.session.getUndoManager().addSelection(o),this.prevOp=this.curOp,this.curOp=null}},this.$mergeableCommands=["backspace","del","insertstring"],this.$historyTracker=function(e){if(this.$mergeUndoDeltas){var t=this.prevOp,i=this.$mergeableCommands,n=t.command&&e.command.name==t.command.name;if("insertstring"==e.command.name){var s=e.args;void 0===this.mergeNextCommand&&(this.mergeNextCommand=!0),n=n&&this.mergeNextCommand&&(!/\s/.test(s)||/\s/.test(t.args)),this.mergeNextCommand=!0}else n=n&&-1!==i.indexOf(e.command.name);"always"!=this.$mergeUndoDeltas&&2e3o.length||s.length<2||!s[1])return this.commands.exec("insertstring",this,t);for(var r=o.length;r--;){var a=o[r];a.isEmpty()||n.remove(a),n.insert(a.start,s[r])}}},this.execCommand=function(e,t){return this.commands.exec(e,this,t)},this.insert=function(e,t){var i=this.session,n=i.getMode(),s=this.getCursorPosition();if(this.getBehavioursEnabled()&&!t){var o=n.transformAction(i.getState(s.row),"insertion",this,i,e);o&&(e!==o.text&&(this.inVirtualSelectionMode||(this.session.mergeUndoDeltas=!1,this.mergeNextCommand=!1)),e=o.text)}if("\t"==e&&(e=this.session.getTabString()),this.selection.isEmpty()){if(this.session.getOverwrite()&&-1==e.indexOf("\n")){(r=new m.fromPoints(s,s)).end.column+=e.length,this.session.remove(r)}}else{var r=this.getSelectionRange();s=this.session.remove(r),this.clearSelection()}if("\n"==e||"\r\n"==e){var a=i.getLine(s.row);if(s.column>a.search(/\S|$/)){var l=a.substr(s.column).search(/\S|$/);i.doc.removeInLine(s.row,s.column,s.column+l)}}this.clearSelection();var c=s.column,h=i.getState(s.row),u=(a=i.getLine(s.row),n.checkOutdent(h,a,e));i.insert(s,e);if(o&&o.selection&&(2==o.selection.length?this.selection.setSelectionRange(new m(s.row,c+o.selection[0],s.row,c+o.selection[1])):this.selection.setSelectionRange(new m(s.row+o.selection[0],o.selection[1],s.row+o.selection[2],o.selection[3]))),i.getDocument().isNewLine(e)){var d=n.getNextLineIndent(h,a.slice(0,s.column),i.getTabString());i.insert({row:s.row+1,column:0},d)}u&&n.autoOutdent(h,i,s.row)},this.onTextInput=function(e,t){if(!t)return this.keyBinding.onTextInput(e);this.startOperation({command:{name:"insertstring"}});var i=this.applyComposition.bind(this,e,t);this.selection.rangeCount?this.forEachSelection(i):i(),this.endOperation()},this.applyComposition=function(e,t){var i;(t.extendLeft||t.extendRight)&&((i=this.selection.getRange()).start.column-=t.extendLeft,i.end.column+=t.extendRight,this.selection.setRange(i),!e&&!i.isEmpty()&&this.remove());((e||!this.selection.isEmpty())&&this.insert(e,!0),t.restoreStart||t.restoreEnd)&&((i=this.selection.getRange()).start.column-=t.restoreStart,i.end.column-=t.restoreEnd,this.selection.setRange(i))},this.onCommandKey=function(e,t,i){this.keyBinding.onCommandKey(e,t,i)},this.setOverwrite=function(e){this.session.setOverwrite(e)},this.getOverwrite=function(){return this.session.getOverwrite()},this.toggleOverwrite=function(){this.session.toggleOverwrite()},this.setScrollSpeed=function(e){this.setOption("scrollSpeed",e)},this.getScrollSpeed=function(){return this.getOption("scrollSpeed")},this.setDragDelay=function(e){this.setOption("dragDelay",e)},this.getDragDelay=function(){return this.getOption("dragDelay")},this.setSelectionStyle=function(e){this.setOption("selectionStyle",e)},this.getSelectionStyle=function(){return this.getOption("selectionStyle")},this.setHighlightActiveLine=function(e){this.setOption("highlightActiveLine",e)},this.getHighlightActiveLine=function(){return this.getOption("highlightActiveLine")},this.setHighlightGutterLine=function(e){this.setOption("highlightGutterLine",e)},this.getHighlightGutterLine=function(){return this.getOption("highlightGutterLine")},this.setHighlightSelectedWord=function(e){this.setOption("highlightSelectedWord",e)},this.getHighlightSelectedWord=function(){return this.$highlightSelectedWord},this.setAnimatedScroll=function(e){this.renderer.setAnimatedScroll(e)},this.getAnimatedScroll=function(){return this.renderer.getAnimatedScroll()},this.setShowInvisibles=function(e){this.renderer.setShowInvisibles(e)},this.getShowInvisibles=function(){return this.renderer.getShowInvisibles()},this.setDisplayIndentGuides=function(e){this.renderer.setDisplayIndentGuides(e)},this.getDisplayIndentGuides=function(){return this.renderer.getDisplayIndentGuides()},this.setShowPrintMargin=function(e){this.renderer.setShowPrintMargin(e)},this.getShowPrintMargin=function(){return this.renderer.getShowPrintMargin()},this.setPrintMarginColumn=function(e){this.renderer.setPrintMarginColumn(e)},this.getPrintMarginColumn=function(){return this.renderer.getPrintMarginColumn()},this.setReadOnly=function(e){this.setOption("readOnly",e)},this.getReadOnly=function(){return this.getOption("readOnly")},this.setBehavioursEnabled=function(e){this.setOption("behavioursEnabled",e)},this.getBehavioursEnabled=function(){return this.getOption("behavioursEnabled")},this.setWrapBehavioursEnabled=function(e){this.setOption("wrapBehavioursEnabled",e)},this.getWrapBehavioursEnabled=function(){return this.getOption("wrapBehavioursEnabled")},this.setShowFoldWidgets=function(e){this.setOption("showFoldWidgets",e)},this.getShowFoldWidgets=function(){return this.getOption("showFoldWidgets")},this.setFadeFoldWidgets=function(e){this.setOption("fadeFoldWidgets",e)},this.getFadeFoldWidgets=function(){return this.getOption("fadeFoldWidgets")},this.remove=function(e){this.selection.isEmpty()&&("left"==e?this.selection.selectLeft():this.selection.selectRight());var t=this.getSelectionRange();if(this.getBehavioursEnabled()){var i=this.session,n=i.getState(t.start.row),s=i.getMode().transformAction(n,"deletion",this,i,t);if(0===t.end.column){var o=i.getTextRange(t);if("\n"==o[o.length-1]){var r=i.getLine(t.end.row);/^\s+$/.test(r)&&(t.end.column=r.length)}}s&&(t=s)}this.session.remove(t),this.clearSelection()},this.removeWordRight=function(){this.selection.isEmpty()&&this.selection.selectWordRight(),this.session.remove(this.getSelectionRange()),this.clearSelection()},this.removeWordLeft=function(){this.selection.isEmpty()&&this.selection.selectWordLeft(),this.session.remove(this.getSelectionRange()),this.clearSelection()},this.removeToLineStart=function(){this.selection.isEmpty()&&this.selection.selectLineStart(),this.selection.isEmpty()&&this.selection.selectLeft(),this.session.remove(this.getSelectionRange()),this.clearSelection()},this.removeToLineEnd=function(){this.selection.isEmpty()&&this.selection.selectLineEnd();var e=this.getSelectionRange();e.start.column==e.end.column&&e.start.row==e.end.row&&(e.end.column=0,e.end.row++),this.session.remove(e),this.clearSelection()},this.splitLine=function(){this.selection.isEmpty()||(this.session.remove(this.getSelectionRange()),this.clearSelection());var e=this.getCursorPosition();this.insert("\n"),this.moveCursorToPosition(e)},this.transposeLetters=function(){if(this.selection.isEmpty()){var e=this.getCursorPosition(),t=e.column;if(0!==t){var i,n,s=this.session.getLine(e.row);n=tt.toLowerCase()?1:0});var s=new m(0,0,0,0);for(n=e.first;n<=e.last;n++){var o=t.getLine(n);s.start.row=n,s.end.row=n,s.end.column=o.length,t.replace(s,i[n-e.first])}},this.toggleCommentLines=function(){var e=this.session.getState(this.getCursorPosition().row),t=this.$getSelectedRows();this.session.getMode().toggleCommentLines(e,this.session,t.first,t.last)},this.toggleBlockComment=function(){var e=this.getCursorPosition(),t=this.session.getState(e.row),i=this.getSelectionRange();this.session.getMode().toggleBlockComment(t,this.session,i,e)},this.getNumberAt=function(e,t){var i=/[\-]?[0-9]+(?:\.[0-9]+)?/g;i.lastIndex=0;for(var n=this.session.getLine(e);i.lastIndex=t)return{value:s[0],start:s.index,end:s.index+s[0].length}}return null},this.modifyNumber=function(e){var t=this.selection.getCursor().row,i=this.selection.getCursor().column,n=new m(t,i-1,t,i),s=this.session.getTextRange(n);if(!isNaN(parseFloat(s))&&isFinite(s)){var o=this.getNumberAt(t,i);if(o){var r=0<=o.value.indexOf(".")?o.start+o.value.indexOf(".")+1:o.end,a=o.start+o.value.length-r,l=parseFloat(o.value);l*=Math.pow(10,a),r!==o.end&&ig+1)break;g=f.last}for(h--,a=this.session.$moveLines(d,g,t?0:e),t&&-1==e&&(u=h+1);u<=h;)r[u].moveBy(a,0),u++;t||(a=0),l+=a}s.fromOrientedRange(s.ranges[0]),s.rangeList.attach(this.session),this.inVirtualSelectionMode=!1}},this.$getSelectedRows=function(e){return e=(e||this.getSelectionRange()).collapseRows(),{first:this.session.getRowFoldStart(e.start.row),last:this.session.getRowFoldEnd(e.end.row)}},this.onCompositionStart=function(e){this.renderer.showComposition(e)},this.onCompositionUpdate=function(e){this.renderer.setCompositionText(e)},this.onCompositionEnd=function(){this.renderer.hideComposition()},this.getFirstVisibleRow=function(){return this.renderer.getFirstVisibleRow()},this.getLastVisibleRow=function(){return this.renderer.getLastVisibleRow()},this.isRowVisible=function(e){return e>=this.getFirstVisibleRow()&&e<=this.getLastVisibleRow()},this.isRowFullyVisible=function(e){return e>=this.renderer.getFirstFullyVisibleRow()&&e<=this.renderer.getLastFullyVisibleRow()},this.$getVisibleRowCount=function(){return this.renderer.getScrollBottomRow()-this.renderer.getScrollTopRow()+1},this.$moveByPage=function(e,t){var i=this.renderer,n=this.renderer.layerConfig,s=e*Math.floor(n.height/n.lineHeight);!0===t?this.selection.$moveSelection(function(){this.moveCursorBy(s,0)}):!1===t&&(this.selection.moveCursorBy(s,0),this.selection.clearSelection());var o=i.scrollTop;i.scrollBy(0,s*n.lineHeight),null!=t&&i.scrollCursorIntoView(null,.5),i.animateScrolling(o)},this.selectPageDown=function(){this.$moveByPage(1,!0)},this.selectPageUp=function(){this.$moveByPage(-1,!0)},this.gotoPageDown=function(){this.$moveByPage(1,!1)},this.gotoPageUp=function(){this.$moveByPage(-1,!1)},this.scrollPageDown=function(){this.$moveByPage(1)},this.scrollPageUp=function(){this.$moveByPage(-1)},this.scrollToRow=function(e){this.renderer.scrollToRow(e)},this.scrollToLine=function(e,t,i,n){this.renderer.scrollToLine(e,t,i,n)},this.centerSelection=function(){var e=this.getSelectionRange(),t={row:Math.floor(e.start.row+(e.end.row-e.start.row)/2),column:Math.floor(e.start.column+(e.end.column-e.start.column)/2)};this.renderer.alignCursor(t,.5)},this.getCursorPosition=function(){return this.selection.getCursor()},this.getCursorPositionScreen=function(){return this.session.documentToScreenPosition(this.getCursorPosition())},this.getSelectionRange=function(){return this.selection.getRange()},this.selectAll=function(){this.selection.selectAll()},this.clearSelection=function(){this.selection.clearSelection()},this.moveCursorTo=function(e,t){this.selection.moveCursorTo(e,t)},this.moveCursorToPosition=function(e){this.selection.moveCursorToPosition(e)},this.jumpToMatching=function(e,t){var i=this.getCursorPosition(),n=new w(this.session,i.row,i.column),s=n.getCurrentToken(),o=s||n.stepForward();if(o){var r,a,l=!1,c={},h=i.column-o.start,u={")":"(","(":"(","]":"[","[":"[","{":"{","}":"{"};do{if(o.value.match(/[{}()\[\]]/g)){for(;hwindow.innerHeight)&&null)&&(a.style.top=n+"px",a.style.left=t.left+"px",a.style.height=i.lineHeight+"px",a.scrollIntoView(r)),r=s=null}});this.setAutoScrollEditorIntoView=function(e){e||(delete this.setAutoScrollEditorIntoView,this.off("changeSelection",t),this.renderer.off("afterRender",n),this.renderer.off("beforeRender",i))}}},this.$resetCursorStyle=function(){var e=this.$cursorStyle||"ace",t=this.renderer.$cursorLayer;t&&(t.setSmoothBlinking(/smooth/.test(e)),t.isBlinking=!this.$readOnly&&"wide"!=e,n.setCssClass(t.element,"ace_slim-cursors",/slim/.test(e)))}}.call(y.prototype),v.defineOptions(y.prototype,"editor",{selectionStyle:{set:function(e){this.onSelectionChange(),this._signal("changeSelectionStyle",{data:e})},initialValue:"line"},highlightActiveLine:{set:function(){this.$updateHighlightActiveLine()},initialValue:!0},highlightSelectedWord:{set:function(e){this.$onSelectionChange()},initialValue:!0},readOnly:{set:function(e){this.textInput.setReadOnly(e),this.$resetCursorStyle()},initialValue:!1},copyWithEmptySelection:{set:function(e){this.textInput.setCopyWithEmptySelection(e)},initialValue:!1},cursorStyle:{set:function(e){this.$resetCursorStyle()},values:["ace","slim","smooth","wide"],initialValue:"ace"},mergeUndoDeltas:{values:[!1,!0,"always"],initialValue:!0},behavioursEnabled:{initialValue:!0},wrapBehavioursEnabled:{initialValue:!0},autoScrollEditorIntoView:{set:function(e){this.setAutoScrollEditorIntoView(e)}},keyboardHandler:{set:function(e){this.setKeyboardHandler(e)},get:function(){return this.$keybindingId},handlesSet:!0},value:{set:function(e){this.session.setValue(e)},get:function(){return this.getValue()},handlesSet:!0,hidden:!0},session:{set:function(e){this.setSession(e)},get:function(){return this.session},handlesSet:!0,hidden:!0},showLineNumbers:{set:function(e){this.renderer.$gutterLayer.setShowLineNumbers(e),this.renderer.$loop.schedule(this.renderer.CHANGE_GUTTER),e&&this.$relativeLineNumbers?$.attach(this):$.detach(this)},initialValue:!0},relativeLineNumbers:{set:function(e){this.$showLineNumbers&&e?$.attach(this):$.detach(this)}},hScrollBarAlwaysVisible:"renderer",vScrollBarAlwaysVisible:"renderer",highlightGutterLine:"renderer",animatedScroll:"renderer",showInvisibles:"renderer",showPrintMargin:"renderer",printMarginColumn:"renderer",printMargin:"renderer",fadeFoldWidgets:"renderer",showFoldWidgets:"renderer",displayIndentGuides:"renderer",showGutter:"renderer",fontSize:"renderer",fontFamily:"renderer",maxLines:"renderer",minLines:"renderer",scrollPastEnd:"renderer",fixedWidthGutter:"renderer",theme:"renderer",hasCssTransforms:"renderer",maxPixelHeight:"renderer",useTextareaForIME:"renderer",scrollSpeed:"$mouseHandler",dragDelay:"$mouseHandler",dragEnabled:"$mouseHandler",focusTimeout:"$mouseHandler",tooltipFollowsMouse:"$mouseHandler",firstLineNumber:"session",overwrite:"session",newLineMode:"session",useWorker:"session",useSoftTabs:"session",navigateWithinSoftTabs:"session",tabSize:"session",wrap:"session",indentedSoftWrap:"session",foldStyle:"session",mode:"session"});var $={getText:function(e,t){return(Math.abs(e.selection.lead.row-t)||t+1+(t<9?"·":""))+""},getWidth:function(e,t,i){return Math.max(t.toString().length,(i.lastRow+1).toString().length,2)*i.characterWidth},update:function(e,t){t.renderer.$loop.schedule(t.renderer.CHANGE_GUTTER)},attach:function(e){e.renderer.$gutterLayer.$renderer=this,e.on("changeSelection",this.update),this.update(null,e)},detach:function(e){e.renderer.$gutterLayer.$renderer==this&&(e.renderer.$gutterLayer.$renderer=null),e.off("changeSelection",this.update),this.update(null,e)}};t.Editor=y}),ace.define("ace/undomanager",["require","exports","module","ace/range"],function(e,t,i){"use strict";function a(e){return{row:e.row,column:e.column}}function n(e){if(e=e||this,Array.isArray(e))return e.map(n).join("\n");var t="";return e.action?(t="insert"==e.action?"+":"-",t+="["+e.lines+"]"):e.value&&(t=Array.isArray(e.value)?e.value.map(s).join("\n"):s(e.value)),e.start&&(t+=s(e)),(e.id||e.rev)&&(t+="\t("+(e.id||e.rev)+")"),t}function s(e){return e.start.row+":"+e.start.column+"=>"+e.end.row+":"+e.end.column}function o(e,t){var i="insert"==e.action,n="insert"==t.action;if(i&&n)if(0<=m(t.start,e.end))c(t,e,-1);else{if(!(m(t.start,e.start)<=0))return null;c(e,t,1)}else if(i&&!n)if(0<=m(t.start,e.end))c(t,e,-1);else{if(!(m(t.end,e.start)<=0))return null;c(e,t,-1)}else if(!i&&n)if(0<=m(t.start,e.start))c(t,e,1);else{if(!(m(t.start,e.start)<=0))return null;c(e,t,1)}else if(!i&&!n)if(0<=m(t.start,e.start))c(t,e,1);else{if(!(m(t.end,e.start)<=0))return null;c(e,t,-1)}return[t,e]}function r(e,t){for(var i=e.length;i--;)for(var n=0;na+1;)this.$lines.pop();break}(r=this.$lines.get(++a))?r.row=l:(r=this.$lines.createCell(l,e,this.session,c),this.$lines.push(r)),this.$renderCell(r,e,s,l),l++}this._signal("afterRender"),this.$updateGutterWidth(e)},this.$updateGutterWidth=function(e){var t=this.session,i=t.gutterRenderer||this.$renderer,n=t.$firstLineNumber,s=this.$lines.last()?this.$lines.last().text:"";(this.$fixedWidth||t.$useWrapMode)&&(s=t.getLength()+n-1);var o=i?i.getWidth(t,s,e):s.toString().length*e.characterWidth,r=this.$padding||this.$computePadding();(o+=r.left+r.right)!==this.gutterWidth&&!isNaN(o)&&(this.gutterWidth=o,this.element.parentNode.style.width=this.element.style.width=Math.ceil(this.gutterWidth)+"px",this._signal("changeGutterWidth",o))},this.$updateCursorRow=function(){if(this.$highlightGutterLine){var e=this.session.selection.getCursor();this.$cursorRow!==e.row&&(this.$cursorRow=e.row)}},this.updateLineHighlight=function(){if(this.$highlightGutterLine){var e=this.session.selection.cursor.row;if(this.$cursorRow=e,!this.$cursorCell||this.$cursorCell.row!=e){this.$cursorCell&&(this.$cursorCell.element.className=this.$cursorCell.element.className.replace("ace_gutter-active-line ",""));var t=this.$lines.cells;this.$cursorCell=null;for(var i=0;i=this.$cursorRow){if(n.row>this.$cursorRow){var s=this.session.getFoldLine(this.$cursorRow);if(!(0i.right-t.right?"foldWidgets":void 0}}).call(r.prototype),t.Gutter=r}),ace.define("ace/layer/marker",["require","exports","module","ace/range","ace/lib/dom"],function(e,t,i){"use strict";var g=e("../range").Range,n=e("../lib/dom"),s=function(e){this.element=n.createElement("div"),this.element.className="ace_layer ace_marker-layer",e.appendChild(this.element)};(function(){this.$padding=0,this.setPadding=function(e){this.$padding=e},this.setSession=function(e){this.session=e},this.setMarkers=function(e){this.markers=e},this.elt=function(e,t){var i=-1!=this.i&&this.element.childNodes[this.i];i?this.i++:(i=document.createElement("div"),this.element.appendChild(i),this.i=-1),i.style.cssText=t,i.className=e},this.update=function(e){if(e){var t;for(var i in this.config=e,this.i=0,this.markers){var n=this.markers[i];if(n.range){var s=n.range.clipRows(e.firstRow,e.lastRow);if(!s.isEmpty())if(s=s.toScreenRange(this.session),n.renderer){var o=this.$getTop(s.start.row,e),r=this.$padding+s.start.column*e.characterWidth;n.renderer(t,s,r,o,e)}else"fullLine"==n.type?this.drawFullLineMarker(t,s,n.clazz,e):"screenLine"==n.type?this.drawScreenLineMarker(t,s,n.clazz,e):s.isMultiLine()?"text"==n.type?this.drawTextMarker(t,s,n.clazz,e):this.drawMultiLineMarker(t,s,n.clazz,e):this.drawSingleLineMarker(t,s,n.clazz+" ace_start ace_br15",e)}else n.update(t,this,this.session,e)}if(-1!=this.i)for(;this.ie.lastRow)for(s=this.session.getFoldedRowCount(e.lastRow+1,t.lastRow);0t.lastRow&&this.$lines.push(this.$renderLinesFragment(e,t.lastRow+1,e.lastRow))},this.$renderLinesFragment=function(e,t,i){for(var n=[],s=t,o=this.session.getNextFoldLine(s),r=o?o.start.row:1/0;r=o;)r=this.$renderToken(a,r,c,h.substring(0,o-n)),h=h.substring(o-n),n=o,a=this.$createLineElement(),e.appendChild(a),a.appendChild(this.dom.createTextNode(b.stringRepeat(" ",i.indent),this.element)),r=0,o=i[++s]||Number.MAX_VALUE;0!=h.length&&(n+=h.length,r=this.$renderToken(a,r,c,h))}}},this.$renderSimpleLine=function(e,t){var i=0,n=t[0],s=n.value;this.displayIndentGuides&&(s=this.renderIndentGuide(e,s)),s&&(i=this.$renderToken(e,i,n,s));for(var o=1;othis.MAX_LINE_LENGTH)return this.$renderOverflowMessage(e,i,n,s);i=this.$renderToken(e,i,n,s)}},this.$renderOverflowMessage=function(e,t,i,n){this.$renderToken(e,t,i,n.slice(0,this.MAX_LINE_LENGTH-t));var s=this.dom.createElement("span");s.className="ace_inline_button ace_keyword ace_toggle_wrap",s.style.position="absolute",s.style.right="0",s.textContent="",e.appendChild(s)},this.$renderLine=function(e,t,i){if(!i&&0!=i&&(i=this.session.getFoldLine(t)),i)var n=this.$getFoldLineTokens(t,i);else n=this.session.getTokens(t);var s=e;if(n.length){var o=this.session.getRowSplitData(t);if(o&&o.length){this.$renderWrappedLine(e,n,o);s=e.lastChild}else{s=e;this.$useLineGroups()&&(s=this.$createLineElement(),e.appendChild(s)),this.$renderSimpleLine(s,n)}}else this.$useLineGroups()&&(s=this.$createLineElement(),e.appendChild(s));if(this.showInvisibles&&s){i&&(t=i.end.row);var r=this.dom.createElement("span");r.className="ace_invisible ace_invisible_eol",r.textContent=t==this.session.getLength()-1?this.EOF_CHAR:this.EOL_CHAR,s.appendChild(r)}},this.$getFoldLineTokens=function(e,t){var o=this.session,r=[],a=o.getTokens(e);return t.walk(function(e,t,i,n,s){null!=e?r.push({type:"fold",value:e}):(s&&(a=o.getTokens(t)),a.length&&function(e,t,i){for(var n=0,s=0;s+e[n].value.lengthi-t&&(o=o.substring(0,i-t)),r.push({type:e[n].type,value:o}),s=t+o.length,n+=1);si?r.push({type:e[n].type,value:o.substring(0,i-s)}):r.push(e[n]),s+=o.length,n+=1}}(a,n,i))},t.end.row,this.session.getLine(t.end.row).length),r},this.$useLineGroups=function(){return this.session.getUseWrapMode()},this.destroy=function(){}}).call(r.prototype),t.Text=r}),ace.define("ace/layer/cursor",["require","exports","module","ace/lib/dom"],function(e,t,i){"use strict";var c=e("../lib/dom"),n=function(e){this.element=c.createElement("div"),this.element.className="ace_layer ace_cursor-layer",e.appendChild(this.element),this.isVisible=!1,this.isBlinking=!0,this.blinkInterval=1e3,this.smoothBlinking=!1,this.cursors=[],this.cursor=this.addCursor(),c.addCssClass(this.element,"ace_hidden-cursors"),this.$updateCursors=this.$updateOpacity.bind(this)};(function(){this.$updateOpacity=function(e){for(var t=this.cursors,i=t.length;i--;)c.setStyle(t[i].style,"opacity",e?"":"0")},this.$startCssAnimation=function(){for(var e=this.cursors,t=e.length;t--;)e[t].style.animationDuration=this.blinkInterval+"ms";setTimeout(function(){c.addCssClass(this.element,"ace_animate-blinking")}.bind(this))},this.$stopCssAnimation=function(){c.removeCssClass(this.element,"ace_animate-blinking")},this.$padding=0,this.setPadding=function(e){this.$padding=e},this.setSession=function(e){this.session=e},this.setBlinking=function(e){e!=this.isBlinking&&(this.isBlinking=e,this.restartTimer())},this.setBlinkInterval=function(e){e!=this.blinkInterval&&(this.blinkInterval=e,this.restartTimer())},this.setSmoothBlinking=function(e){e!=this.smoothBlinking&&(this.smoothBlinking=e,c.setCssClass(this.element,"ace_smooth-blinking",e),this.$updateCursors(!0),this.restartTimer())},this.addCursor=function(){var e=c.createElement("div");return e.className="ace_cursor",this.element.appendChild(e),this.cursors.push(e),e},this.removeCursor=function(){if(1e.height+e.offset||o.top<0)&&1n;)this.removeCursor();var l=this.session.getOverwrite();this.$setOverwrite(l),this.$pixelPos=o,this.restartTimer()},this.drawCursor=null,this.$setOverwrite=function(e){e!=this.overwrite&&((this.overwrite=e)?c.addCssClass(this.element,"ace_overwrite-cursors"):c.removeCssClass(this.element,"ace_overwrite-cursors"))},this.destroy=function(){clearInterval(this.intervalId),clearTimeout(this.timeoutId)}}).call(n.prototype),t.Cursor=n}),ace.define("ace/scrollbar",["require","exports","module","ace/lib/oop","ace/lib/dom","ace/lib/event","ace/lib/event_emitter"],function(e,t,i){"use strict";var n=e("./lib/oop"),s=e("./lib/dom"),o=e("./lib/event"),r=e("./lib/event_emitter").EventEmitter,a=function(e){this.element=s.createElement("div"),this.element.className="ace_scrollbar ace_scrollbar"+this.classSuffix,this.inner=s.createElement("div"),this.inner.className="ace_scrollbar-inner",this.element.appendChild(this.inner),e.appendChild(this.element),this.setVisible(!1),this.skipEvent=!1,o.addListener(this.element,"scroll",this.onScroll.bind(this)),o.addListener(this.element,"mousedown",o.preventDefault)};(function(){n.implement(this,r),this.setVisible=function(e){this.element.style.display=e?"":"none",this.isVisible=e,this.coeff=1}}).call(a.prototype);var l=function(e,t){a.call(this,e),this.scrollTop=0,this.scrollHeight=0,t.$scrollbarWidth=this.width=s.scrollbarWidth(e.ownerDocument),this.inner.style.width=this.element.style.width=(this.width||15)+5+"px",this.$minWidth=0};n.inherits(l,a),function(){this.classSuffix="-v",this.onScroll=function(){if(!this.skipEvent){if(this.scrollTop=this.element.scrollTop,1!=this.coeff){var e=this.element.clientHeight/this.scrollHeight;this.scrollTop=this.scrollTop*(1-e)/(this.coeff-e)}this._emit("scroll",{data:this.scrollTop})}this.skipEvent=!1},this.getWidth=function(){return Math.max(this.isVisible?this.width:0,this.$minWidth||0)},this.setHeight=function(e){this.element.style.height=e+"px"},this.setInnerHeight=this.setScrollHeight=function(e){32768<(this.scrollHeight=e)?(this.coeff=32768/e,e=32768):1!=this.coeff&&(this.coeff=1),this.inner.style.height=e+"px"},this.setScrollTop=function(e){this.scrollTop!=e&&(this.skipEvent=!0,this.scrollTop=e,this.element.scrollTop=e*this.coeff)}}.call(l.prototype);var c=function(e,t){a.call(this,e),this.scrollLeft=0,this.height=t.$scrollbarWidth,this.inner.style.height=this.element.style.height=(this.height||15)+5+"px"};n.inherits(c,a),function(){this.classSuffix="-h",this.onScroll=function(){this.skipEvent||(this.scrollLeft=this.element.scrollLeft,this._emit("scroll",{data:this.scrollLeft})),this.skipEvent=!1},this.getHeight=function(){return this.isVisible?this.height:0},this.setWidth=function(e){this.element.style.width=e+"px"},this.setInnerWidth=function(e){this.inner.style.width=e+"px"},this.setScrollWidth=function(e){this.inner.style.width=e+"px"},this.setScrollLeft=function(e){this.scrollLeft!=e&&(this.skipEvent=!0,this.scrollLeft=this.element.scrollLeft=e)}}.call(c.prototype),t.ScrollBar=l,t.ScrollBarV=l,t.ScrollBarH=c,t.VScrollBar=l,t.HScrollBar=c}),ace.define("ace/renderloop",["require","exports","module","ace/lib/event"],function(e,t,i){"use strict";var n=e("./lib/event"),s=function(e,t){this.onRender=e,this.pending=!1,this.changes=0,this.$recursionLimit=2,this.window=t||window;var i=this;this._flush=function(e){i.pending=!1;var t=i.changes;if(t&&(n.blockIdle(100),i.changes=0,i.onRender(t)),i.changes){if(i.$recursionLimit--<0)return;i.schedule()}else i.$recursionLimit=2}};(function(){this.schedule=function(e){this.changes=this.changes|e,this.changes&&!this.pending&&(n.nextFrame(this._flush),this.pending=!0)},this.clear=function(e){var t=this.changes;return this.changes=0,t}}).call(s.prototype),t.RenderLoop=s}),ace.define("ace/layer/font_metrics",["require","exports","module","ace/lib/oop","ace/lib/dom","ace/lib/lang","ace/lib/event","ace/lib/useragent","ace/lib/event_emitter"],function(e,t,i){var n=e("../lib/oop"),s=e("../lib/dom"),o=e("../lib/lang"),r=e("../lib/event"),a=e("../lib/useragent"),l=e("../lib/event_emitter").EventEmitter,c="function"==typeof ResizeObserver,h=t.FontMetrics=function(e){this.el=s.createElement("div"),this.$setMeasureNodeStyles(this.el.style,!0),this.$main=s.createElement("div"),this.$setMeasureNodeStyles(this.$main.style),this.$measureNode=s.createElement("div"),this.$setMeasureNodeStyles(this.$measureNode.style),this.el.appendChild(this.$main),this.el.appendChild(this.$measureNode),e.appendChild(this.el),this.$measureNode.innerHTML=o.stringRepeat("X",256),this.$characterSize={width:0,height:0},c?this.$addObserver():this.checkForSizeChanges()};(function(){n.implement(this,l),this.$characterSize={width:0,height:0},this.$setMeasureNodeStyles=function(e,t){e.width=e.height="auto",e.left=e.top="0px",e.visibility="hidden",e.position="absolute",e.whiteSpace="pre",a.isIE<8?e["font-family"]="inherit":e.font="inherit",e.overflow=t?"hidden":"visible"},this.checkForSizeChanges=function(e){if(void 0===e&&(e=this.$measureSizes()),e&&(this.$characterSize.width!==e.width||this.$characterSize.height!==e.height)){this.$measureNode.style.fontWeight="bold";var t=this.$measureSizes();this.$measureNode.style.fontWeight="",this.$characterSize=e,this.charSizes=Object.create(null),this.allowBoldFonts=t&&t.width===e.width&&t.height===e.height,this._emit("changeCharacterSize",{data:e})}},this.$addObserver=function(){var i=this;this.$observer=new window.ResizeObserver(function(e){var t=e[0].contentRect;i.checkForSizeChanges({height:t.height,width:t.width/256})}),this.$observer.observe(this.$measureNode)},this.$pollSizeChanges=function(){if(this.$pollSizeChangesTimer||this.$observer)return this.$pollSizeChangesTimer;var t=this;return this.$pollSizeChangesTimer=r.onIdle(function e(){t.checkForSizeChanges(),r.onIdle(e,500)},500)},this.setPolling=function(e){e?this.$pollSizeChanges():this.$pollSizeChangesTimer&&(clearInterval(this.$pollSizeChangesTimer),this.$pollSizeChangesTimer=0)},this.$measureSizes=function(e){var t={height:(e||this.$measureNode).clientHeight,width:(e||this.$measureNode).clientWidth/256};return 0===t.width||0===t.height?null:t},this.$measureCharWidth=function(e){return this.$main.innerHTML=o.stringRepeat(e,256),this.$main.getBoundingClientRect().width/256},this.getCharacterWidth=function(e){var t=this.charSizes[e];return void 0===t&&(t=this.charSizes[e]=this.$measureCharWidth(e)/this.$characterSize.width),t},this.destroy=function(){clearInterval(this.$pollSizeChangesTimer),this.$observer&&this.$observer.disconnect(),this.el&&this.el.parentNode&&this.el.parentNode.removeChild(this.el)},this.$getZoom=function e(t){return t?(window.getComputedStyle(t).zoom||1)*e(t.parentElement):1},this.$initTransformMeasureNodes=function(){var e=function(e,t){return["div",{style:"position: absolute;top:"+e+"px;left:"+t+"px;"}]};this.els=s.buildDom([e(0,0),e(200,0),e(0,200),e(200,200)],this.el)},this.transformCoordinates=function(e,t){function i(e,t,i){var n=e[1]*t[0]-e[0]*t[1];return[(-t[1]*i[0]+t[0]*i[1])/n,(+e[1]*i[0]-e[0]*i[1])/n]}function n(e,t){return[e[0]-t[0],e[1]-t[1]]}function s(e,t){return[e[0]+t[0],e[1]+t[1]]}function o(e,t){return[e*t[0],e*t[1]]}function r(e){var t=e.getBoundingClientRect();return[t.left,t.top]}e&&(e=o(1/this.$getZoom(this.el),e));this.els||this.$initTransformMeasureNodes();var a=r(this.els[0]),l=r(this.els[1]),c=r(this.els[2]),h=r(this.els[3]),u=i(n(h,l),n(h,c),n(s(l,c),s(h,a))),d=o(1+u[0],n(l,a)),g=o(1+u[1],n(c,a));if(t){var f=t;return s(o(1/(u[0]*f[0]/200+u[1]*f[1]/200+1)/200,s(o(f[0],d),o(f[1],g))),a)}var m=n(e,a);return o(200,i(n(d,o(u[0],m)),n(g,o(u[1],m)),m))}}).call(h.prototype)}),ace.define("ace/virtual_renderer",["require","exports","module","ace/lib/oop","ace/lib/dom","ace/config","ace/layer/gutter","ace/layer/marker","ace/layer/text","ace/layer/cursor","ace/scrollbar","ace/scrollbar","ace/renderloop","ace/layer/font_metrics","ace/lib/event_emitter","ace/lib/useragent"],function(e,t,i){"use strict";var n=e("./lib/oop"),c=e("./lib/dom"),o=e("./config"),s=e("./layer/gutter").Gutter,r=e("./layer/marker").Marker,a=e("./layer/text").Text,l=e("./layer/cursor").Cursor,h=e("./scrollbar").HScrollBar,u=e("./scrollbar").VScrollBar,d=e("./renderloop").RenderLoop,g=e("./layer/font_metrics").FontMetrics,f=e("./lib/event_emitter").EventEmitter,m='.ace_br1 {border-top-left-radius : 3px;}.ace_br2 {border-top-right-radius : 3px;}.ace_br3 {border-top-left-radius : 3px; border-top-right-radius: 3px;}.ace_br4 {border-bottom-right-radius: 3px;}.ace_br5 {border-top-left-radius : 3px; border-bottom-right-radius: 3px;}.ace_br6 {border-top-right-radius : 3px; border-bottom-right-radius: 3px;}.ace_br7 {border-top-left-radius : 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px;}.ace_br8 {border-bottom-left-radius : 3px;}.ace_br9 {border-top-left-radius : 3px; border-bottom-left-radius: 3px;}.ace_br10{border-top-right-radius : 3px; border-bottom-left-radius: 3px;}.ace_br11{border-top-left-radius : 3px; border-top-right-radius: 3px; border-bottom-left-radius: 3px;}.ace_br12{border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;}.ace_br13{border-top-left-radius : 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;}.ace_br14{border-top-right-radius : 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;}.ace_br15{border-top-left-radius : 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;}.ace_editor {position: relative;overflow: hidden;font: 12px/normal \'Monaco\', \'Menlo\', \'Ubuntu Mono\', \'Consolas\', \'source-code-pro\', monospace;direction: ltr;text-align: left;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);}.ace_scroller {position: absolute;overflow: hidden;top: 0;bottom: 0;background-color: inherit;-ms-user-select: none;-moz-user-select: none;-webkit-user-select: none;user-select: none;cursor: text;}.ace_content {position: absolute;box-sizing: border-box;min-width: 100%;contain: style size layout;}.ace_dragging .ace_scroller:before{position: absolute;top: 0;left: 0;right: 0;bottom: 0;content: \'\';background: rgba(250, 250, 250, 0.01);z-index: 1000;}.ace_dragging.ace_dark .ace_scroller:before{background: rgba(0, 0, 0, 0.01);}.ace_selecting, .ace_selecting * {cursor: text !important;}.ace_gutter {position: absolute;overflow : hidden;width: auto;top: 0;bottom: 0;left: 0;cursor: default;z-index: 4;-ms-user-select: none;-moz-user-select: none;-webkit-user-select: none;user-select: none;contain: style size layout;}.ace_gutter-active-line {position: absolute;left: 0;right: 0;}.ace_scroller.ace_scroll-left {box-shadow: 17px 0 16px -16px rgba(0, 0, 0, 0.4) inset;}.ace_gutter-cell {position: absolute;top: 0;left: 0;right: 0;padding-left: 19px;padding-right: 6px;background-repeat: no-repeat;}.ace_gutter-cell.ace_error {background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAABOFBMVEX/////////QRswFAb/Ui4wFAYwFAYwFAaWGAfDRymzOSH/PxswFAb/SiUwFAYwFAbUPRvjQiDllog5HhHdRybsTi3/Tyv9Tir+Syj/UC3////XurebMBIwFAb/RSHbPx/gUzfdwL3kzMivKBAwFAbbvbnhPx66NhowFAYwFAaZJg8wFAaxKBDZurf/RB6mMxb/SCMwFAYwFAbxQB3+RB4wFAb/Qhy4Oh+4QifbNRcwFAYwFAYwFAb/QRzdNhgwFAYwFAbav7v/Uy7oaE68MBK5LxLewr/r2NXewLswFAaxJw4wFAbkPRy2PyYwFAaxKhLm1tMwFAazPiQwFAaUGAb/QBrfOx3bvrv/VC/maE4wFAbRPBq6MRO8Qynew8Dp2tjfwb0wFAbx6eju5+by6uns4uH9/f36+vr/GkHjAAAAYnRSTlMAGt+64rnWu/bo8eAA4InH3+DwoN7j4eLi4xP99Nfg4+b+/u9B/eDs1MD1mO7+4PHg2MXa347g7vDizMLN4eG+Pv7i5evs/v79yu7S3/DV7/498Yv24eH+4ufQ3Ozu/v7+y13sRqwAAADLSURBVHjaZc/XDsFgGIBhtDrshlitmk2IrbHFqL2pvXf/+78DPokj7+Fz9qpU/9UXJIlhmPaTaQ6QPaz0mm+5gwkgovcV6GZzd5JtCQwgsxoHOvJO15kleRLAnMgHFIESUEPmawB9ngmelTtipwwfASilxOLyiV5UVUyVAfbG0cCPHig+GBkzAENHS0AstVF6bacZIOzgLmxsHbt2OecNgJC83JERmePUYq8ARGkJx6XtFsdddBQgZE2nPR6CICZhawjA4Fb/chv+399kfR+MMMDGOQAAAABJRU5ErkJggg==");background-repeat: no-repeat;background-position: 2px center;}.ace_gutter-cell.ace_warning {background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAmVBMVEX///8AAAD///8AAAAAAABPSzb/5sAAAAB/blH/73z/ulkAAAAAAAD85pkAAAAAAAACAgP/vGz/rkDerGbGrV7/pkQICAf////e0IsAAAD/oED/qTvhrnUAAAD/yHD/njcAAADuv2r/nz//oTj/p064oGf/zHAAAAA9Nir/tFIAAAD/tlTiuWf/tkIAAACynXEAAAAAAAAtIRW7zBpBAAAAM3RSTlMAABR1m7RXO8Ln31Z36zT+neXe5OzooRDfn+TZ4p3h2hTf4t3k3ucyrN1K5+Xaks52Sfs9CXgrAAAAjklEQVR42o3PbQ+CIBQFYEwboPhSYgoYunIqqLn6/z8uYdH8Vmdnu9vz4WwXgN/xTPRD2+sgOcZjsge/whXZgUaYYvT8QnuJaUrjrHUQreGczuEafQCO/SJTufTbroWsPgsllVhq3wJEk2jUSzX3CUEDJC84707djRc5MTAQxoLgupWRwW6UB5fS++NV8AbOZgnsC7BpEAAAAABJRU5ErkJggg==");background-position: 2px center;}.ace_gutter-cell.ace_info {background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAAAAAA6mKC9AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAAJ0Uk5TAAB2k804AAAAPklEQVQY02NgIB68QuO3tiLznjAwpKTgNyDbMegwisCHZUETUZV0ZqOquBpXj2rtnpSJT1AEnnRmL2OgGgAAIKkRQap2htgAAAAASUVORK5CYII=");background-position: 2px center;}.ace_dark .ace_gutter-cell.ace_info {background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAJFBMVEUAAAChoaGAgIAqKiq+vr6tra1ZWVmUlJSbm5s8PDxubm56enrdgzg3AAAAAXRSTlMAQObYZgAAAClJREFUeNpjYMAPdsMYHegyJZFQBlsUlMFVCWUYKkAZMxZAGdxlDMQBAG+TBP4B6RyJAAAAAElFTkSuQmCC");}.ace_scrollbar {contain: strict;position: absolute;right: 0;bottom: 0;z-index: 6;}.ace_scrollbar-inner {position: absolute;cursor: text;left: 0;top: 0;}.ace_scrollbar-v{overflow-x: hidden;overflow-y: scroll;top: 0;}.ace_scrollbar-h {overflow-x: scroll;overflow-y: hidden;left: 0;}.ace_print-margin {position: absolute;height: 100%;}.ace_text-input {position: absolute;z-index: 0;width: 0.5em;height: 1em;opacity: 0;background: transparent;-moz-appearance: none;appearance: none;border: none;resize: none;outline: none;overflow: hidden;font: inherit;padding: 0 1px;margin: 0 -1px;contain: strict;-ms-user-select: text;-moz-user-select: text;-webkit-user-select: text;user-select: text;white-space: pre!important;}.ace_text-input.ace_composition {background: transparent;color: inherit;z-index: 1000;opacity: 1;}.ace_composition_placeholder { color: transparent }.ace_composition_marker { border-bottom: 1px solid;position: absolute;border-radius: 0;margin-top: 1px;}[ace_nocontext=true] {transform: none!important;filter: none!important;perspective: none!important;clip-path: none!important;mask : none!important;contain: none!important;perspective: none!important;mix-blend-mode: initial!important;z-index: auto;}.ace_layer {z-index: 1;position: absolute;overflow: hidden;word-wrap: normal;white-space: pre;height: 100%;width: 100%;box-sizing: border-box;pointer-events: none;}.ace_gutter-layer {position: relative;width: auto;text-align: right;pointer-events: auto;height: 1000000px;contain: style size layout;}.ace_text-layer {font: inherit !important;position: absolute;height: 1000000px;width: 1000000px;contain: style size layout;}.ace_text-layer > .ace_line, .ace_text-layer > .ace_line_group {contain: style size layout;position: absolute;top: 0;left: 0;right: 0;}.ace_hidpi .ace_text-layer,.ace_hidpi .ace_gutter-layer,.ace_hidpi .ace_content,.ace_hidpi .ace_gutter {contain: strict;will-change: transform;}.ace_hidpi .ace_text-layer > .ace_line, .ace_hidpi .ace_text-layer > .ace_line_group {contain: strict;}.ace_cjk {display: inline-block;text-align: center;}.ace_cursor-layer {z-index: 4;}.ace_cursor {z-index: 4;position: absolute;box-sizing: border-box;border-left: 2px solid;transform: translatez(0);}.ace_multiselect .ace_cursor {border-left-width: 1px;}.ace_slim-cursors .ace_cursor {border-left-width: 1px;}.ace_overwrite-cursors .ace_cursor {border-left-width: 0;border-bottom: 1px solid;}.ace_hidden-cursors .ace_cursor {opacity: 0.2;}.ace_smooth-blinking .ace_cursor {transition: opacity 0.18s;}.ace_animate-blinking .ace_cursor {animation-duration: 1000ms;animation-timing-function: step-end;animation-name: blink-ace-animate;animation-iteration-count: infinite;}.ace_animate-blinking.ace_smooth-blinking .ace_cursor {animation-duration: 1000ms;animation-timing-function: ease-in-out;animation-name: blink-ace-animate-smooth;}@keyframes blink-ace-animate {from, to { opacity: 1; }60% { opacity: 0; }}@keyframes blink-ace-animate-smooth {from, to { opacity: 1; }45% { opacity: 1; }60% { opacity: 0; }85% { opacity: 0; }}.ace_marker-layer .ace_step, .ace_marker-layer .ace_stack {position: absolute;z-index: 3;}.ace_marker-layer .ace_selection {position: absolute;z-index: 5;}.ace_marker-layer .ace_bracket {position: absolute;z-index: 6;}.ace_marker-layer .ace_active-line {position: absolute;z-index: 2;}.ace_marker-layer .ace_selected-word {position: absolute;z-index: 4;box-sizing: border-box;}.ace_line .ace_fold {box-sizing: border-box;display: inline-block;height: 11px;margin-top: -2px;vertical-align: middle;background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABEAAAAJCAYAAADU6McMAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAJpJREFUeNpi/P//PwOlgAXGYGRklAVSokD8GmjwY1wasKljQpYACtpCFeADcHVQfQyMQAwzwAZI3wJKvCLkfKBaMSClBlR7BOQikCFGQEErIH0VqkabiGCAqwUadAzZJRxQr/0gwiXIal8zQQPnNVTgJ1TdawL0T5gBIP1MUJNhBv2HKoQHHjqNrA4WO4zY0glyNKLT2KIfIMAAQsdgGiXvgnYAAAAASUVORK5CYII="),url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAA3CAYAAADNNiA5AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAACJJREFUeNpi+P//fxgTAwPDBxDxD078RSX+YeEyDFMCIMAAI3INmXiwf2YAAAAASUVORK5CYII=");background-repeat: no-repeat, repeat-x;background-position: center center, top left;color: transparent;border: 1px solid black;border-radius: 2px;cursor: pointer;pointer-events: auto;}.ace_dark .ace_fold {}.ace_fold:hover{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABEAAAAJCAYAAADU6McMAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAJpJREFUeNpi/P//PwOlgAXGYGRklAVSokD8GmjwY1wasKljQpYACtpCFeADcHVQfQyMQAwzwAZI3wJKvCLkfKBaMSClBlR7BOQikCFGQEErIH0VqkabiGCAqwUadAzZJRxQr/0gwiXIal8zQQPnNVTgJ1TdawL0T5gBIP1MUJNhBv2HKoQHHjqNrA4WO4zY0glyNKLT2KIfIMAAQsdgGiXvgnYAAAAASUVORK5CYII="),url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAA3CAYAAADNNiA5AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAACBJREFUeNpi+P//fz4TAwPDZxDxD5X4i5fLMEwJgAADAEPVDbjNw87ZAAAAAElFTkSuQmCC");}.ace_tooltip {background-color: #FFF;background-image: linear-gradient(to bottom, transparent, rgba(0, 0, 0, 0.1));border: 1px solid gray;border-radius: 1px;box-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);color: black;max-width: 100%;padding: 3px 4px;position: fixed;z-index: 999999;box-sizing: border-box;cursor: default;white-space: pre;word-wrap: break-word;line-height: normal;font-style: normal;font-weight: normal;letter-spacing: normal;pointer-events: none;}.ace_folding-enabled > .ace_gutter-cell {padding-right: 13px;}.ace_fold-widget {box-sizing: border-box;margin: 0 -12px 0 1px;display: none;width: 11px;vertical-align: top;background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAANElEQVR42mWKsQ0AMAzC8ixLlrzQjzmBiEjp0A6WwBCSPgKAXoLkqSot7nN3yMwR7pZ32NzpKkVoDBUxKAAAAABJRU5ErkJggg==");background-repeat: no-repeat;background-position: center;border-radius: 3px;border: 1px solid transparent;cursor: pointer;}.ace_folding-enabled .ace_fold-widget {display: inline-block; }.ace_fold-widget.ace_end {background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAANElEQVR42m3HwQkAMAhD0YzsRchFKI7sAikeWkrxwScEB0nh5e7KTPWimZki4tYfVbX+MNl4pyZXejUO1QAAAABJRU5ErkJggg==");}.ace_fold-widget.ace_closed {background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAGCAYAAAAG5SQMAAAAOUlEQVR42jXKwQkAMAgDwKwqKD4EwQ26sSOkVWjgIIHAzPiCgaqiqnJHZnKICBERHN194O5b9vbLuAVRL+l0YWnZAAAAAElFTkSuQmCCXA==");}.ace_fold-widget:hover {border: 1px solid rgba(0, 0, 0, 0.3);background-color: rgba(255, 255, 255, 0.2);box-shadow: 0 1px 1px rgba(255, 255, 255, 0.7);}.ace_fold-widget:active {border: 1px solid rgba(0, 0, 0, 0.4);background-color: rgba(0, 0, 0, 0.05);box-shadow: 0 1px 1px rgba(255, 255, 255, 0.8);}.ace_dark .ace_fold-widget {background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHklEQVQIW2P4//8/AzoGEQ7oGCaLLAhWiSwB146BAQCSTPYocqT0AAAAAElFTkSuQmCC");}.ace_dark .ace_fold-widget.ace_end {background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAH0lEQVQIW2P4//8/AxQ7wNjIAjDMgC4AxjCVKBirIAAF0kz2rlhxpAAAAABJRU5ErkJggg==");}.ace_dark .ace_fold-widget.ace_closed {background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAFCAYAAACAcVaiAAAAHElEQVQIW2P4//+/AxAzgDADlOOAznHAKgPWAwARji8UIDTfQQAAAABJRU5ErkJggg==");}.ace_dark .ace_fold-widget:hover {box-shadow: 0 1px 1px rgba(255, 255, 255, 0.2);background-color: rgba(255, 255, 255, 0.1);}.ace_dark .ace_fold-widget:active {box-shadow: 0 1px 1px rgba(255, 255, 255, 0.2);}.ace_inline_button {border: 1px solid lightgray;display: inline-block;margin: -1px 8px;padding: 0 5px;pointer-events: auto;cursor: pointer;}.ace_inline_button:hover {border-color: gray;background: rgba(200,200,200,0.2);display: inline-block;pointer-events: auto;}.ace_fold-widget.ace_invalid {background-color: #FFB4B4;border-color: #DE5555;}.ace_fade-fold-widgets .ace_fold-widget {transition: opacity 0.4s ease 0.05s;opacity: 0;}.ace_fade-fold-widgets:hover .ace_fold-widget {transition: opacity 0.05s ease 0.05s;opacity:1;}.ace_underline {text-decoration: underline;}.ace_bold {font-weight: bold;}.ace_nobold .ace_bold {font-weight: normal;}.ace_italic {font-style: italic;}.ace_error-marker {background-color: rgba(255, 0, 0,0.2);position: absolute;z-index: 9;}.ace_highlight-marker {background-color: rgba(255, 255, 0,0.2);position: absolute;z-index: 8;}',p=e("./lib/useragent"),v=p.isIE;c.importCssString(m,"ace_editor.css");var w=function(e,t){var i=this;this.container=e||c.createElement("div"),c.addCssClass(this.container,"ace_editor"),c.HI_DPI&&c.addCssClass(this.container,"ace_hidpi"),this.setTheme(t),this.$gutter=c.createElement("div"),this.$gutter.className="ace_gutter",this.container.appendChild(this.$gutter),this.$gutter.setAttribute("aria-hidden",!0),this.scroller=c.createElement("div"),this.scroller.className="ace_scroller",this.container.appendChild(this.scroller),this.content=c.createElement("div"),this.content.className="ace_content",this.scroller.appendChild(this.content),this.$gutterLayer=new s(this.$gutter),this.$gutterLayer.on("changeGutterWidth",this.onGutterResize.bind(this)),this.$markerBack=new r(this.content);var n=this.$textLayer=new a(this.content);this.canvas=n.element,this.$markerFront=new r(this.content),this.$cursorLayer=new l(this.content),this.$horizScroll=!1,this.$vScroll=!1,this.scrollBar=this.scrollBarV=new u(this.container,this),this.scrollBarH=new h(this.container,this),this.scrollBarV.addEventListener("scroll",function(e){i.$scrollAnimation||i.session.setScrollTop(e.data-i.scrollMargin.top)}),this.scrollBarH.addEventListener("scroll",function(e){i.$scrollAnimation||i.session.setScrollLeft(e.data-i.scrollMargin.left)}),this.scrollTop=0,this.scrollLeft=0,this.cursorPos={row:0,column:0},this.$fontMetrics=new g(this.container),this.$textLayer.$setFontMetrics(this.$fontMetrics),this.$textLayer.addEventListener("changeCharacterSize",function(e){i.updateCharacterSize(),i.onResize(!0,i.gutterWidth,i.$size.width,i.$size.height),i._signal("changeCharacterSize",e)}),this.$size={width:0,height:0,scrollerHeight:0,scrollerWidth:0,$dirty:!0},this.layerConfig={width:1,padding:0,firstRow:0,firstRowScreen:0,lastRow:0,lineHeight:0,characterWidth:0,minHeight:1,maxHeight:1,offset:0,height:1,gutterOffset:1},this.scrollMargin={left:0,right:0,top:0,bottom:0,v:0,h:0},this.margin={left:0,right:0,top:0,bottom:0,v:0,h:0},this.$keepTextAreaAtCursor=!p.isIOS,this.$loop=new d(this.$renderChanges.bind(this),this.container.ownerDocument.defaultView),this.$loop.schedule(this.CHANGE_FULL),this.updateCharacterSize(),this.setPadding(4),o.resetOptions(this),o._emit("renderer",this)};(function(){this.CHANGE_CURSOR=1,this.CHANGE_MARKER=2,this.CHANGE_GUTTER=4,this.CHANGE_SCROLL=8,this.CHANGE_LINES=16,this.CHANGE_TEXT=32,this.CHANGE_SIZE=64,this.CHANGE_MARKER_BACK=128,this.CHANGE_MARKER_FRONT=256,this.CHANGE_FULL=512,this.CHANGE_H_SCROLL=1024,n.implement(this,f),this.updateCharacterSize=function(){this.$textLayer.allowBoldFonts!=this.$allowBoldFonts&&(this.$allowBoldFonts=this.$textLayer.allowBoldFonts,this.setStyle("ace_nobold",!this.$allowBoldFonts)),this.layerConfig.characterWidth=this.characterWidth=this.$textLayer.getCharacterWidth(),this.layerConfig.lineHeight=this.lineHeight=this.$textLayer.getLineHeight(),this.$updatePrintMargin()},this.setSession=function(e){this.session&&this.session.doc.off("changeNewLineMode",this.onChangeNewLineMode),(this.session=e)&&this.scrollMargin.top&&e.getScrollTop()<=0&&e.setScrollTop(-this.scrollMargin.top),this.$cursorLayer.setSession(e),this.$markerBack.setSession(e),this.$markerFront.setSession(e),this.$gutterLayer.setSession(e),this.$textLayer.setSession(e),e&&(this.$loop.schedule(this.CHANGE_FULL),this.session.$setFontMetrics(this.$fontMetrics),this.scrollBarH.scrollLeft=this.scrollBarV.scrollTop=null,this.onChangeNewLineMode=this.onChangeNewLineMode.bind(this),this.onChangeNewLineMode(),this.session.doc.on("changeNewLineMode",this.onChangeNewLineMode))},this.updateLines=function(e,t,i){if(void 0===t&&(t=1/0),this.$changedLines?(this.$changedLines.firstRow>e&&(this.$changedLines.firstRow=e),this.$changedLines.lastRowthis.layerConfig.lastRow||this.$loop.schedule(this.CHANGE_LINES)},this.onChangeNewLineMode=function(){this.$loop.schedule(this.CHANGE_TEXT),this.$textLayer.$updateEolChar(),this.session.$bidiHandler.setEolChar(this.$textLayer.EOL_CHAR)},this.onChangeTabSize=function(){this.$loop.schedule(this.CHANGE_TEXT|this.CHANGE_MARKER),this.$textLayer.onChangeTabSize()},this.updateText=function(){this.$loop.schedule(this.CHANGE_TEXT)},this.updateFull=function(e){e?this.$renderChanges(this.CHANGE_FULL,!0):this.$loop.schedule(this.CHANGE_FULL)},this.updateFontSize=function(){this.$textLayer.checkForSizeChanges()},this.$changes=0,this.$updateSizeAsync=function(){this.$loop.pending?this.$size.$dirty=!0:this.onResize()},this.onResize=function(e,t,i,n){if(!(2n.height-r)c.translate(this.textarea,0,0);else{var a=1;if(i)if(i.useTextareaForIME){var l=this.textarea.value;a=this.characterWidth*this.session.$getStringScreenWidth(l)[0],r+=2}else s+=this.lineHeight+2;else s+=this.lineHeight;(o-=this.scrollLeft)>this.$size.scrollerWidth-a&&(o=this.$size.scrollerWidth-a),o+=this.gutterWidth+this.margin.left,c.setStyle(e,"height",r+"px"),c.setStyle(e,"width",a+"px"),c.translate(this.textarea,Math.min(o,this.$size.scrollerWidth-a),Math.min(s,this.$size.height-r))}}}else c.translate(this.textarea,-100,0)},this.getFirstVisibleRow=function(){return this.layerConfig.firstRow},this.getFirstFullyVisibleRow=function(){return this.layerConfig.firstRow+(0===this.layerConfig.offset?0:1)},this.getLastFullyVisibleRow=function(){var e=this.layerConfig,t=e.lastRow;return this.session.documentToScreenRow(t,0)*e.lineHeight-this.session.getScrollTop()>e.height-e.lineHeight?t-1:t},this.getLastVisibleRow=function(){return this.layerConfig.lastRow},this.$padding=null,this.setPadding=function(e){this.$padding=e,this.$textLayer.setPadding(e),this.$cursorLayer.setPadding(e),this.$markerFront.setPadding(e),this.$markerBack.setPadding(e),this.$loop.schedule(this.CHANGE_FULL),this.$updatePrintMargin()},this.setScrollMargin=function(e,t,i,n){var s=this.scrollMargin;s.top=0|e,s.bottom=0|t,s.right=0|n,s.left=0|i,s.v=s.top+s.bottom,s.h=s.left+s.right,s.top&&this.scrollTop<=0&&this.session&&this.session.setScrollTop(-s.top),this.updateFull()},this.setMargin=function(e,t,i,n){var s=this.margin;s.top=0|e,s.bottom=0|t,s.right=0|n,s.left=0|i,s.v=s.top+s.bottom,s.h=s.left+s.right,this.$updateCachedSize(!0,this.gutterWidth,this.$size.width,this.$size.height),this.updateFull()},this.getHScrollBarAlwaysVisible=function(){return this.$hScrollBarAlwaysVisible},this.setHScrollBarAlwaysVisible=function(e){this.setOption("hScrollBarAlwaysVisible",e)},this.getVScrollBarAlwaysVisible=function(){return this.$vScrollBarAlwaysVisible},this.setVScrollBarAlwaysVisible=function(e){this.setOption("vScrollBarAlwaysVisible",e)},this.$updateScrollBarV=function(){var e=this.layerConfig.maxHeight,t=this.$size.scrollerHeight;!this.$maxLines&&this.$scrollPastEnd&&(e-=(t-this.lineHeight)*this.$scrollPastEnd,this.scrollTop>e-t&&(e=this.scrollTop+t,this.scrollBarV.scrollTop=null)),this.scrollBarV.setScrollHeight(e+this.scrollMargin.v),this.scrollBarV.setScrollTop(this.scrollTop+this.scrollMargin.top)},this.$updateScrollBarH=function(){this.scrollBarH.setScrollWidth(this.layerConfig.width+2*this.$padding+this.scrollMargin.h),this.scrollBarH.setScrollLeft(this.scrollLeft+this.scrollMargin.left)},this.$frozen=!1,this.freeze=function(){this.$frozen=!0},this.unfreeze=function(){this.$frozen=!1},this.$renderChanges=function(e,t){if(this.$changes&&(e|=this.$changes,this.$changes=0),this.session&&this.container.offsetWidth&&!this.$frozen&&(e||t)){if(this.$size.$dirty)return this.$changes|=e,this.onResize(!0);this.lineHeight||this.$textLayer.checkForSizeChanges(),this._signal("beforeRender"),this.session&&this.session.$bidiHandler&&this.session.$bidiHandler.updateCharacterWidths(this.$fontMetrics);var i=this.layerConfig;if(e&this.CHANGE_FULL||e&this.CHANGE_SIZE||e&this.CHANGE_TEXT||e&this.CHANGE_LINES||e&this.CHANGE_SCROLL||e&this.CHANGE_H_SCROLL){if(e|=this.$computeLayerConfig()|this.$loop.clear(),i.firstRow!=this.layerConfig.firstRow&&i.firstRowScreen==this.layerConfig.firstRowScreen){var n=this.scrollTop+(i.firstRow-this.layerConfig.firstRow)*this.lineHeight;0this.$maxPixelHeight&&(i=this.$maxPixelHeight);var n=!(i<=2*this.lineHeight)&&th.top),d=a!==u;d&&(this.$vScroll=u,this.scrollBarV.setVisible(u));var g,f,m=this.scrollTop%this.lineHeight,p=Math.ceil(l/this.lineHeight)-1,v=Math.max(0,Math.round((this.scrollTop-m)/this.lineHeight)),w=v+p,b=this.lineHeight;v=e.screenToDocumentRow(v,0);var y=e.getFoldLine(v);y&&(v=y.start.row),g=e.documentToScreenRow(v,0),f=e.getRowLength(v)*b,w=Math.min(e.screenToDocumentRow(w,0),e.getLength()-1),l=t.scrollerHeight+e.getRowLength(w)*b+f,m=this.scrollTop-g*b;var $=0;return(this.layerConfig.width!=s||r)&&($=this.CHANGE_H_SCROLL),(r||d)&&($=this.$updateCachedSize(!0,this.gutterWidth,t.width,t.height),this._signal("scrollbarVisibilityChanged"),d&&(s=this.$getLongestLine())),this.layerConfig={width:s,padding:this.$padding,firstRow:v,firstRowScreen:g,lastRow:w,lineHeight:b,characterWidth:this.characterWidth,minHeight:l,maxHeight:n,offset:m,gutterOffset:b?Math.max(0,Math.ceil((m+t.height-t.scrollerHeight)/b)):0,height:this.$size.scrollerHeight},this.session.$bidiHandler&&this.session.$bidiHandler.setContentWidth(s-this.$padding),$},this.$updateLines=function(){if(this.$changedLines){var e=this.$changedLines.firstRow,t=this.$changedLines.lastRow;this.$changedLines=null;var i=this.layerConfig;if(!(e>i.lastRow+1||tthis.$textLayer.MAX_LINE_LENGTH&&(e=this.$textLayer.MAX_LINE_LENGTH+30),Math.max(this.$size.scrollerWidth-2*this.$padding,Math.round(e*this.characterWidth))},this.updateFrontMarkers=function(){this.$markerFront.setMarkers(this.session.getMarkers(!0)),this.$loop.schedule(this.CHANGE_MARKER_FRONT)},this.updateBackMarkers=function(){this.$markerBack.setMarkers(this.session.getMarkers()),this.$loop.schedule(this.CHANGE_MARKER_BACK)},this.addGutterDecoration=function(e,t){this.$gutterLayer.addGutterDecoration(e,t)},this.removeGutterDecoration=function(e,t){this.$gutterLayer.removeGutterDecoration(e,t)},this.updateBreakpoints=function(e){this.$loop.schedule(this.CHANGE_GUTTER)},this.setAnnotations=function(e){this.$gutterLayer.setAnnotations(e),this.$loop.schedule(this.CHANGE_GUTTER)},this.updateCursor=function(){this.$loop.schedule(this.CHANGE_CURSOR)},this.hideCursor=function(){this.$cursorLayer.hideCursor()},this.showCursor=function(){this.$cursorLayer.showCursor()},this.scrollSelectionIntoView=function(e,t,i){this.scrollCursorIntoView(e,i),this.scrollCursorIntoView(t,i)},this.scrollCursorIntoView=function(e,t,i){if(0!==this.$size.scrollerHeight){var n=this.$cursorLayer.getPixelPosition(e),s=n.left,o=n.top,r=i&&i.top||0,a=i&&i.bottom||0,l=this.$scrollAnimation?this.session.getScrollTop():this.scrollTop;oo+this.lineHeight&&(o-=t*this.$size.scrollerHeight),0===o&&(o=-this.scrollMargin.top),this.session.setScrollTop(o)):l+this.$size.scrollerHeight-a=1-this.scrollMargin.top||(0=1-this.scrollMargin.left||(0this.$doc.getLength()>>1?this.call("setValue",[this.$doc.getValue()]):this.emit("change",{data:e}))}}).call(u.prototype);e.UIWorkerClient=function(e,t,i){var n=null,s=!1,o=Object.create(c),r=[],a=new u({messageBuffer:r,terminate:function(){},postMessage:function(e){r.push(e),n&&(s?setTimeout(l):l())}});a.setEmitSync=function(e){s=e};var l=function(){var e=r.shift();e.command?n[e.command].apply(n,e.args):e.event&&o._signal(e.event,e.data)};return o.postMessage=function(e){a.onMessage({data:e})},o.callback=function(e,t){this.postMessage({type:"call",id:t,data:e})},o.emit=function(e,t){this.postMessage({type:"event",name:e,data:t})},h.loadModule(["worker",t],function(e){for(n=new e[i](o);r.length;)l()}),a},e.WorkerClient=u,e.createWorker=l}),ace.define("ace/placeholder",["require","exports","module","ace/range","ace/lib/event_emitter","ace/lib/oop"],function(e,t,i){"use strict";var l=e("./range").Range,n=e("./lib/event_emitter").EventEmitter,s=e("./lib/oop"),o=function(e,t,i,n,s,o){var r=this;this.length=t,this.session=e,this.doc=e.getDocument(),this.mainClass=s,this.othersClass=o,this.$onUpdate=this.onUpdate.bind(this),this.doc.on("change",this.$onUpdate),this.$others=n,this.$onCursorChange=function(){setTimeout(function(){r.onCursorChange()})},this.$pos=i;var a=e.getUndoManager().$undoStack||e.getUndoManager().$undostack||{length:-1};this.$undoStackDepth=a.length,this.setup(),e.selection.on("changeCursor",this.$onCursorChange)};(function(){s.implement(this,n),this.setup=function(){var i=this,n=this.doc,e=this.session;this.selectionBefore=e.selection.toJSON(),e.selection.inMultiSelectMode&&e.selection.toSingleRange(),this.pos=n.createAnchor(this.$pos.row,this.$pos.column);var t=this.pos;t.$insertRight=!0,t.detach(),t.markerId=e.addMarker(new l(t.row,t.column,t.row,t.column+this.length),this.mainClass,null,!1),this.others=[],this.$others.forEach(function(e){var t=n.createAnchor(e.row,e.column);t.$insertRight=!0,t.detach(),i.others.push(t)}),e.setUndoSelect(!1)},this.showOtherMarkers=function(){if(!this.othersActive){var t=this.session,i=this;this.othersActive=!0,this.others.forEach(function(e){e.markerId=t.addMarker(new l(e.row,e.column,e.row,e.column+i.length),i.othersClass,null,!1)})}},this.hideOtherMarkers=function(){if(this.othersActive){this.othersActive=!1;for(var e=0;e=this.pos.column&&t.start.column<=this.pos.column+this.length+1,s=t.start.column-this.pos.column;if(this.updateAnchors(e),n&&(this.length+=i),n&&!this.session.$fromUndo)if("insert"===e.action)for(var o=this.others.length-1;0<=o;o--){var r={row:(a=this.others[o]).row,column:a.column+s};this.doc.insertMergedLines(r,e.lines)}else if("remove"===e.action)for(o=this.others.length-1;0<=o;o--){var a;r={row:(a=this.others[o]).row,column:a.column+s};this.doc.remove(new l(r.row,r.column,r.row,r.column-i))}this.$updating=!1,this.updateMarkers()}},this.updateAnchors=function(e){this.pos.onChange(e);for(var t=this.others.length;t--;)this.others[t].onChange(e);this.updateMarkers()},this.updateMarkers=function(){if(!this.$updating){var i=this,n=this.session,e=function(e,t){n.removeMarker(e.markerId),e.markerId=n.addMarker(new l(e.row,e.column,e.row,e.column+i.length),t,null,!1)};e(this.pos,this.mainClass);for(var t=this.others.length;t--;)e(this.others[t],this.othersClass)}},this.onCursorChange=function(e){if(!this.$updating&&this.session){var t=this.session.selection.getCursor();t.row===this.pos.row&&t.column>=this.pos.column&&t.column<=this.pos.column+this.length?(this.showOtherMarkers(),this._emit("cursorEnter",e)):(this.hideOtherMarkers(),this._emit("cursorLeave",e))}},this.detach=function(){this.session.removeMarker(this.pos&&this.pos.markerId),this.hideOtherMarkers(),this.doc.removeEventListener("change",this.$onUpdate),this.session.selection.removeEventListener("changeCursor",this.$onCursorChange),this.session.setUndoSelect(!0),this.session=null},this.cancel=function(){if(-1!==this.$undoStackDepth){for(var e=this.session.getUndoManager(),t=(e.$undoStack||e.$undostack).length-this.$undoStackDepth,i=0;ir&&(r=t.column),it[1].length&&(s=t[1].length),ot[3].length&&(r=t[3].length)),t):[e]}).map(t?n:a?l?function(e){return e[2]?i(s+o-e[2].length)+e[2]+i(r)+e[4].replace(/^([=:])\s+/,"$1 "):e[0]}:n:function(e){return e[2]?i(s)+e[2]+i(r)+e[4].replace(/^([=:])\s+/,"$1 "):e[0]})}}).call(c.prototype),t.onSessionChange=function(e){var t=e.session;t&&!t.multiSelect&&(t.$selectionMarkers=[],t.selection.$initRangeList(),t.multiSelect=t.selection),this.multiSelect=t&&t.multiSelect;var i=e.oldSession;i&&(i.multiSelect.off("addRange",this.$onAddRange),i.multiSelect.off("removeRange",this.$onRemoveRange),i.multiSelect.off("multiSelect",this.$onMultiSelect),i.multiSelect.off("singleSelect",this.$onSingleSelect),i.multiSelect.lead.off("change",this.$checkMultiselectChange),i.multiSelect.anchor.off("change",this.$checkMultiselectChange)),t&&(t.multiSelect.on("addRange",this.$onAddRange),t.multiSelect.on("removeRange",this.$onRemoveRange),t.multiSelect.on("multiSelect",this.$onMultiSelect),t.multiSelect.on("singleSelect",this.$onSingleSelect),t.multiSelect.lead.on("change",this.$checkMultiselectChange),t.multiSelect.anchor.on("change",this.$checkMultiselectChange)),t&&this.inMultiSelectMode!=t.selection.inMultiSelectMode&&(t.selection.inMultiSelectMode?this.$onMultiSelect():this.$onSingleSelect())},t.MultiSelect=n,e("./config").defineOptions(c.prototype,"editor",{enableMultiselect:{set:function(e){n(this),e?(this.on("changeSession",this.$multiselectOnSessionChange),this.on("mousedown",o)):(this.off("changeSession",this.$multiselectOnSessionChange),this.off("mousedown",o))},value:!0},enableBlockSelect:{set:function(e){this.$blockSelectEnabled=e},value:!0}})}),ace.define("ace/mode/folding/fold_mode",["require","exports","module","ace/range"],function(e,t,i){"use strict";var d=e("../../range").Range,n=t.FoldMode=function(){};(function(){this.foldingStartMarker=null,this.foldingStopMarker=null,this.getFoldWidget=function(e,t,i){var n=e.getLine(i);return this.foldingStartMarker.test(n)?"start":"markbeginend"==t&&this.foldingStopMarker&&this.foldingStopMarker.test(n)?"end":""},this.getFoldWidgetRange=function(e,t,i){return null},this.indentationBlock=function(e,t,i){var n=/\S/,s=e.getLine(t),o=s.search(n);if(-1!=o){for(var r=i||s.length,a=e.getLength(),l=t,c=t;++to.row&&(r.row--,r.column=e.getLine(r.row).length),d.fromPoints(o,r)}},this.closingBracketBlock=function(e,t,i,n,s){var o={row:i,column:n},r=e.$findOpeningBracket(t,o);if(r)return r.column++,o.column--,d.fromPoints(r,o)}}).call(n.prototype)}),ace.define("ace/theme/textmate",["require","exports","module","ace/lib/dom"],function(e,t,i){"use strict";t.isDark=!1,t.cssClass="ace-tm",t.cssText='.ace-tm .ace_gutter {background: #f0f0f0;color: #333;}.ace-tm .ace_print-margin {width: 1px;background: #e8e8e8;}.ace-tm .ace_fold {background-color: #6B72E6;}.ace-tm {background-color: #FFFFFF;color: black;}.ace-tm .ace_cursor {color: black;}.ace-tm .ace_invisible {color: rgb(191, 191, 191);}.ace-tm .ace_storage,.ace-tm .ace_keyword {color: blue;}.ace-tm .ace_constant {color: rgb(197, 6, 11);}.ace-tm .ace_constant.ace_buildin {color: rgb(88, 72, 246);}.ace-tm .ace_constant.ace_language {color: rgb(88, 92, 246);}.ace-tm .ace_constant.ace_library {color: rgb(6, 150, 14);}.ace-tm .ace_invalid {background-color: rgba(255, 0, 0, 0.1);color: red;}.ace-tm .ace_support.ace_function {color: rgb(60, 76, 114);}.ace-tm .ace_support.ace_constant {color: rgb(6, 150, 14);}.ace-tm .ace_support.ace_type,.ace-tm .ace_support.ace_class {color: rgb(109, 121, 222);}.ace-tm .ace_keyword.ace_operator {color: rgb(104, 118, 135);}.ace-tm .ace_string {color: rgb(3, 106, 7);}.ace-tm .ace_comment {color: rgb(76, 136, 107);}.ace-tm .ace_comment.ace_doc {color: rgb(0, 102, 255);}.ace-tm .ace_comment.ace_doc.ace_tag {color: rgb(128, 159, 191);}.ace-tm .ace_constant.ace_numeric {color: rgb(0, 0, 205);}.ace-tm .ace_variable {color: rgb(49, 132, 149);}.ace-tm .ace_xml-pe {color: rgb(104, 104, 91);}.ace-tm .ace_entity.ace_name.ace_function {color: #0000A2;}.ace-tm .ace_heading {color: rgb(12, 7, 255);}.ace-tm .ace_list {color:rgb(185, 6, 144);}.ace-tm .ace_meta.ace_tag {color:rgb(0, 22, 142);}.ace-tm .ace_string.ace_regex {color: rgb(255, 0, 0)}.ace-tm .ace_marker-layer .ace_selection {background: rgb(181, 213, 255);}.ace-tm.ace_multiselect .ace_selection.ace_start {box-shadow: 0 0 3px 0px white;}.ace-tm .ace_marker-layer .ace_step {background: rgb(252, 255, 0);}.ace-tm .ace_marker-layer .ace_stack {background: rgb(164, 229, 101);}.ace-tm .ace_marker-layer .ace_bracket {margin: -1px 0 0 -1px;border: 1px solid rgb(192, 192, 192);}.ace-tm .ace_marker-layer .ace_active-line {background: rgba(0, 0, 0, 0.07);}.ace-tm .ace_gutter-active-line {background-color : #dcdcdc;}.ace-tm .ace_marker-layer .ace_selected-word {background: rgb(250, 250, 255);border: 1px solid rgb(200, 200, 250);}.ace-tm .ace_indent-guide {background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAE0lEQVQImWP4////f4bLly//BwAmVgd1/w11/gAAAABJRU5ErkJggg==") right repeat-y;}',t.$id="ace/theme/textmate",e("../lib/dom").importCssString(t.cssText,t.cssClass)}),ace.define("ace/line_widgets",["require","exports","module","ace/lib/oop","ace/lib/dom","ace/range"],function(e,t,i){"use strict";function n(e){this.session=e,(this.session.widgetManager=this).session.getRowLength=this.getRowLength,this.session.$getWidgetScreenLength=this.$getWidgetScreenLength,this.updateOnChange=this.updateOnChange.bind(this),this.renderWidgets=this.renderWidgets.bind(this),this.measureWidgets=this.measureWidgets.bind(this),this.session._changedWidgets=[],this.$onChangeEditor=this.$onChangeEditor.bind(this),this.session.on("change",this.updateOnChange),this.session.on("changeFold",this.updateOnFold),this.session.on("changeEditor",this.$onChangeEditor)}e("./lib/oop");var o=e("./lib/dom");e("./range").Range;(function(){this.getRowLength=function(e){var t;return t=this.lineWidgets&&this.lineWidgets[e]&&this.lineWidgets[e].rowCount||0,this.$useWrapMode&&this.$wrapData[e]?this.$wrapData[e].length+1+t:1+t},this.$getWidgetScreenLength=function(){var t=0;return this.lineWidgets.forEach(function(e){e&&e.rowCount&&!e.hidden&&(t+=e.rowCount)}),t},this.$onChangeEditor=function(e){this.attach(e.editor)},this.attach=function(e){e&&e.widgetManager&&e.widgetManager!=this&&e.widgetManager.detach(),this.editor!=e&&(this.detach(),(this.editor=e)&&(e.widgetManager=this,e.renderer.on("beforeRender",this.measureWidgets),e.renderer.on("afterRender",this.renderWidgets)))},this.detach=function(e){var t=this.editor;if(t){this.editor=null,t.widgetManager=null,t.renderer.off("beforeRender",this.measureWidgets),t.renderer.off("afterRender",this.renderWidgets);var i=this.session.lineWidgets;i&&i.forEach(function(e){e&&e.el&&e.el.parentNode&&(e._inDocument=!1,e.el.parentNode.removeChild(e.el))})}},this.updateOnFold=function(e,t){var i=t.lineWidgets;if(i&&e.action){for(var n=e.data,s=n.start.row,o=n.end.row,r="add"==e.action,a=s+1;a>1,r=i(t,e[o]);if(0=n.length?s=0"),h.appendChild(m.createElement("div"));var g=function(e,t,i){if(0===t&&("esc"===i||"return"===i))return c.destroy(),{command:"null"}};c.destroy=function(){e.$mouseHandler.isMousePressed||(e.keyBinding.removeKeyboardHandler(g),i.widgetManager.removeLineWidget(c),e.off("changeSelection",c.destroy),e.off("changeSession",c.destroy),e.off("mouseup",c.destroy),e.off("change",c.destroy))},e.keyBinding.addKeyboardHandler(g),e.on("changeSelection",c.destroy),e.on("changeSession",c.destroy),e.on("mouseup",c.destroy),e.on("change",c.destroy),e.session.widgetManager.addLineWidget(c),c.el.onmousedown=e.focus.bind(e),e.renderer.scrollCursorIntoView(null,.5,{bottom:c.el.offsetHeight})},m.importCssString(" .error_widget_wrapper { background: inherit; color: inherit; border:none } .error_widget { border-top: solid 2px; border-bottom: solid 2px; margin: 5px 0; padding: 10px 40px; white-space: pre-wrap; } .error_widget.ace_error, .error_widget_arrow.ace_error{ border-color: #ff5a5a } .error_widget.ace_warning, .error_widget_arrow.ace_warning{ border-color: #F1D817 } .error_widget.ace_info, .error_widget_arrow.ace_info{ border-color: #5a5a5a } .error_widget.ace_ok, .error_widget_arrow.ace_ok{ border-color: #5aaa5a } .error_widget_arrow { position: absolute; border: solid 5px; border-top-color: transparent!important; border-right-color: transparent!important; border-left-color: transparent!important; top: -5px; }","")}),ace.define("ace/ace",["require","exports","module","ace/lib/fixoldbrowsers","ace/lib/dom","ace/lib/event","ace/range","ace/editor","ace/edit_session","ace/undomanager","ace/virtual_renderer","ace/worker/worker_client","ace/keyboard/hash_handler","ace/placeholder","ace/multi_select","ace/mode/folding/fold_mode","ace/theme/textmate","ace/ext/error_marker","ace/config"],function(e,l,t){"use strict";e("./lib/fixoldbrowsers");var c=e("./lib/dom"),h=e("./lib/event"),i=e("./range").Range,u=e("./editor").Editor,n=e("./edit_session").EditSession,s=e("./undomanager").UndoManager,d=e("./virtual_renderer").VirtualRenderer;e("./worker/worker_client"),e("./keyboard/hash_handler"),e("./placeholder"),e("./multi_select"),e("./mode/folding/fold_mode"),e("./theme/textmate"),e("./ext/error_marker"),l.config=e("./config"),l.require=e,"function"==typeof define&&(l.define=define),l.edit=function(e,t){if("string"==typeof e){var i=e;if(!(e=document.getElementById(i)))throw new Error("ace.edit can't find div #"+i)}if(e&&e.env&&e.env.editor instanceof u)return e.env.editor;var n="";if(e&&/input|textarea/i.test(e.tagName)){var s=e;n=s.value,e=c.createElement("pre"),s.parentNode.replaceChild(e,s)}else e&&(n=e.textContent,e.innerHTML="");var o=l.createEditSession(n),r=new u(new d(e),o,t),a={document:o,editor:r,onResize:r.resize.bind(r,null)};return s&&(a.textarea=s),h.addListener(window,"resize",a.onResize),r.on("destroy",function(){h.removeListener(window,"resize",a.onResize),a.editor.container.env=null}),r.container.env=r.env=a,r},l.createEditSession=function(e,t){var i=new n(e,t);return i.setUndoManager(new s),i},l.Range=i,l.Editor=u,l.EditSession=n,l.UndoManager=s,l.VirtualRenderer=d,l.version="1.4.3"}),ace.require(["ace/ace"],function(e){for(var t in e&&(e.config.init(!0),e.define=ace.define),window.ace||(window.ace=e),e)e.hasOwnProperty(t)&&(window.ace[t]=e[t]);window.ace.default=window.ace,"object"==typeof module&&"object"==typeof exports&&module&&(module.exports=window.ace)}),ace.define("ace/theme/monokai",["require","exports","module","ace/lib/dom"],function(e,t,i){t.isDark=!0,t.cssClass="ace-monokai",t.cssText=".ace-monokai .ace_gutter {background: #2F3129;color: #8F908A}.ace-monokai .ace_print-margin {width: 1px;background: #555651}.ace-monokai {background-color: #272822;color: #F8F8F2}.ace-monokai .ace_cursor {color: #F8F8F0}.ace-monokai .ace_marker-layer .ace_selection {background: #49483E}.ace-monokai.ace_multiselect .ace_selection.ace_start {box-shadow: 0 0 3px 0px #272822;}.ace-monokai .ace_marker-layer .ace_step {background: rgb(102, 82, 0)}.ace-monokai .ace_marker-layer .ace_bracket {margin: -1px 0 0 -1px;border: 1px solid #49483E}.ace-monokai .ace_marker-layer .ace_active-line {background: #202020}.ace-monokai .ace_gutter-active-line {background-color: #272727}.ace-monokai .ace_marker-layer .ace_selected-word {border: 1px solid #49483E}.ace-monokai .ace_invisible {color: #52524d}.ace-monokai .ace_entity.ace_name.ace_tag,.ace-monokai .ace_keyword,.ace-monokai .ace_meta.ace_tag,.ace-monokai .ace_storage {color: #F92672}.ace-monokai .ace_punctuation,.ace-monokai .ace_punctuation.ace_tag {color: #fff}.ace-monokai .ace_constant.ace_character,.ace-monokai .ace_constant.ace_language,.ace-monokai .ace_constant.ace_numeric,.ace-monokai .ace_constant.ace_other {color: #AE81FF}.ace-monokai .ace_invalid {color: #F8F8F0;background-color: #F92672}.ace-monokai .ace_invalid.ace_deprecated {color: #F8F8F0;background-color: #AE81FF}.ace-monokai .ace_support.ace_constant,.ace-monokai .ace_support.ace_function {color: #66D9EF}.ace-monokai .ace_fold {background-color: #A6E22E;border-color: #F8F8F2}.ace-monokai .ace_storage.ace_type,.ace-monokai .ace_support.ace_class,.ace-monokai .ace_support.ace_type {font-style: italic;color: #66D9EF}.ace-monokai .ace_entity.ace_name.ace_function,.ace-monokai .ace_entity.ace_other,.ace-monokai .ace_entity.ace_other.ace_attribute-name,.ace-monokai .ace_variable {color: #A6E22E}.ace-monokai .ace_variable.ace_parameter {font-style: italic;color: #FD971F}.ace-monokai .ace_string {color: #E6DB74}.ace-monokai .ace_comment {color: #75715E}.ace-monokai .ace_indent-guide {background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWPQ0FD0ZXBzd/wPAAjVAoxeSgNeAAAAAElFTkSuQmCC) right repeat-y}",e("../lib/dom").importCssString(t.cssText,t.cssClass)}),ace.require(["ace/theme/monokai"],function(e){"object"==typeof module&&"object"==typeof exports&&module&&(module.exports=e)}),ace.define("ace/mode/doc_comment_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,i){"use strict";var n=e("../lib/oop"),s=e("./text_highlight_rules").TextHighlightRules,o=function(){this.$rules={start:[{token:"comment.doc.tag",regex:"@[\\w\\d_]+"},o.getTagRule(),{defaultToken:"comment.doc",caseInsensitive:!0}]}};n.inherits(o,s),o.getTagRule=function(e){return{token:"comment.doc.tag.storage.type",regex:"\\b(?:TODO|FIXME|XXX|HACK)\\b"}},o.getStartRule=function(e){return{token:"comment.doc",regex:"\\/\\*(?=\\*)",next:e}},o.getEndRule=function(e){return{token:"comment.doc",regex:"\\*\\/",next:e}},t.DocCommentHighlightRules=o}),ace.define("ace/mode/javascript_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/doc_comment_highlight_rules","ace/mode/text_highlight_rules"],function(e,t,i){"use strict";function n(e){return[{token:"comment",regex:/\/\*/,next:[o.getTagRule(),{token:"comment",regex:"\\*\\/",next:e||"pop"},{defaultToken:"comment",caseInsensitive:!0}]},{token:"comment",regex:"\\/\\/",next:[o.getTagRule(),{token:"comment",regex:"$|^",next:e||"pop"},{defaultToken:"comment",caseInsensitive:!0}]}]}var s=e("../lib/oop"),o=e("./doc_comment_highlight_rules").DocCommentHighlightRules,r=e("./text_highlight_rules").TextHighlightRules,a="[a-zA-Z\\$_¡-￿][a-zA-Z\\d\\$_¡-￿]*",l=function(e){var t=this.createKeywordMapper({"variable.language":"Array|Boolean|Date|Function|Iterator|Number|Object|RegExp|String|Proxy|Namespace|QName|XML|XMLList|ArrayBuffer|Float32Array|Float64Array|Int16Array|Int32Array|Int8Array|Uint16Array|Uint32Array|Uint8Array|Uint8ClampedArray|Error|EvalError|InternalError|RangeError|ReferenceError|StopIteration|SyntaxError|TypeError|URIError|decodeURI|decodeURIComponent|encodeURI|encodeURIComponent|eval|isFinite|isNaN|parseFloat|parseInt|JSON|Math|this|arguments|prototype|window|document",keyword:"const|yield|import|get|set|async|await|break|case|catch|continue|default|delete|do|else|finally|for|function|if|in|of|instanceof|new|return|switch|throw|try|typeof|let|var|while|with|debugger|__parent__|__count__|escape|unescape|with|__proto__|class|enum|extends|super|export|implements|private|public|interface|package|protected|static","storage.type":"const|let|var|function","constant.language":"null|Infinity|NaN|undefined","support.function":"alert","constant.language.boolean":"true|false"},"identifier"),i="\\\\(?:x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|u{[0-9a-fA-F]{1,6}}|[0-2][0-7]{0,2}|3[0-7][0-7]?|[4-7][0-7]?|.)";this.$rules={no_regex:[o.getStartRule("doc-start"),n("no_regex"),{token:"string",regex:"'(?=.)",next:"qstring"},{token:"string",regex:'"(?=.)',next:"qqstring"},{token:"constant.numeric",regex:/0(?:[xX][0-9a-fA-F]+|[oO][0-7]+|[bB][01]+)\b/},{token:"constant.numeric",regex:/(?:\d\d*(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+\b)?/},{token:["storage.type","punctuation.operator","support.function","punctuation.operator","entity.name.function","text","keyword.operator"],regex:"("+a+")(\\.)(prototype)(\\.)("+a+")(\\s*)(=)",next:"function_arguments"},{token:["storage.type","punctuation.operator","entity.name.function","text","keyword.operator","text","storage.type","text","paren.lparen"],regex:"("+a+")(\\.)("+a+")(\\s*)(=)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["entity.name.function","text","keyword.operator","text","storage.type","text","paren.lparen"],regex:"("+a+")(\\s*)(=)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["storage.type","punctuation.operator","entity.name.function","text","keyword.operator","text","storage.type","text","entity.name.function","text","paren.lparen"],regex:"("+a+")(\\.)("+a+")(\\s*)(=)(\\s*)(function)(\\s+)(\\w+)(\\s*)(\\()",next:"function_arguments"},{token:["storage.type","text","entity.name.function","text","paren.lparen"],regex:"(function)(\\s+)("+a+")(\\s*)(\\()",next:"function_arguments"},{token:["entity.name.function","text","punctuation.operator","text","storage.type","text","paren.lparen"],regex:"("+a+")(\\s*)(:)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["text","text","storage.type","text","paren.lparen"],regex:"(:)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:"keyword",regex:"from(?=\\s*('|\"))"},{token:"keyword",regex:"(?:case|do|else|finally|in|instanceof|return|throw|try|typeof|yield|void)\\b",next:"start"},{token:["support.constant"],regex:/that\b/},{token:["storage.type","punctuation.operator","support.function.firebug"],regex:/(console)(\.)(warn|info|log|error|time|trace|timeEnd|assert)\b/},{token:t,regex:a},{token:"punctuation.operator",regex:/[.](?![.])/,next:"property"},{token:"storage.type",regex:/=>/,next:"start"},{token:"keyword.operator",regex:/--|\+\+|\.{3}|===|==|=|!=|!==|<+=?|>+=?|!|&&|\|\||\?:|[!$%&*+\-~\/^]=?/,next:"start"},{token:"punctuation.operator",regex:/[?:,;.]/,next:"start"},{token:"paren.lparen",regex:/[\[({]/,next:"start"},{token:"paren.rparen",regex:/[\])}]/},{token:"comment",regex:/^#!.*$/}],property:[{token:"text",regex:"\\s+"},{token:["storage.type","punctuation.operator","entity.name.function","text","keyword.operator","text","storage.type","text","entity.name.function","text","paren.lparen"],regex:"("+a+")(\\.)("+a+")(\\s*)(=)(\\s*)(function)(?:(\\s+)(\\w+))?(\\s*)(\\()",next:"function_arguments"},{token:"punctuation.operator",regex:/[.](?![.])/},{token:"support.function",regex:/(s(?:h(?:ift|ow(?:Mod(?:elessDialog|alDialog)|Help))|croll(?:X|By(?:Pages|Lines)?|Y|To)?|t(?:op|rike)|i(?:n|zeToContent|debar|gnText)|ort|u(?:p|b(?:str(?:ing)?)?)|pli(?:ce|t)|e(?:nd|t(?:Re(?:sizable|questHeader)|M(?:i(?:nutes|lliseconds)|onth)|Seconds|Ho(?:tKeys|urs)|Year|Cursor|Time(?:out)?|Interval|ZOptions|Date|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Date|FullYear)|FullYear|Active)|arch)|qrt|lice|avePreferences|mall)|h(?:ome|andleEvent)|navigate|c(?:har(?:CodeAt|At)|o(?:s|n(?:cat|textual|firm)|mpile)|eil|lear(?:Timeout|Interval)?|a(?:ptureEvents|ll)|reate(?:StyleSheet|Popup|EventObject))|t(?:o(?:GMTString|S(?:tring|ource)|U(?:TCString|pperCase)|Lo(?:caleString|werCase))|est|a(?:n|int(?:Enabled)?))|i(?:s(?:NaN|Finite)|ndexOf|talics)|d(?:isableExternalCapture|ump|etachEvent)|u(?:n(?:shift|taint|escape|watch)|pdateCommands)|j(?:oin|avaEnabled)|p(?:o(?:p|w)|ush|lugins.refresh|a(?:ddings|rse(?:Int|Float)?)|r(?:int|ompt|eference))|e(?:scape|nableExternalCapture|val|lementFromPoint|x(?:p|ec(?:Script|Command)?))|valueOf|UTC|queryCommand(?:State|Indeterm|Enabled|Value)|f(?:i(?:nd|le(?:ModifiedDate|Size|CreatedDate|UpdatedDate)|xed)|o(?:nt(?:size|color)|rward)|loor|romCharCode)|watch|l(?:ink|o(?:ad|g)|astIndexOf)|a(?:sin|nchor|cos|t(?:tachEvent|ob|an(?:2)?)|pply|lert|b(?:s|ort))|r(?:ou(?:nd|teEvents)|e(?:size(?:By|To)|calc|turnValue|place|verse|l(?:oad|ease(?:Capture|Events)))|andom)|g(?:o|et(?:ResponseHeader|M(?:i(?:nutes|lliseconds)|onth)|Se(?:conds|lection)|Hours|Year|Time(?:zoneOffset)?|Da(?:y|te)|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Da(?:y|te)|FullYear)|FullYear|A(?:ttention|llResponseHeaders)))|m(?:in|ove(?:B(?:y|elow)|To(?:Absolute)?|Above)|ergeAttributes|a(?:tch|rgins|x))|b(?:toa|ig|o(?:ld|rderWidths)|link|ack))\b(?=\()/},{token:"support.function.dom",regex:/(s(?:ub(?:stringData|mit)|plitText|e(?:t(?:NamedItem|Attribute(?:Node)?)|lect))|has(?:ChildNodes|Feature)|namedItem|c(?:l(?:ick|o(?:se|neNode))|reate(?:C(?:omment|DATASection|aption)|T(?:Head|extNode|Foot)|DocumentFragment|ProcessingInstruction|E(?:ntityReference|lement)|Attribute))|tabIndex|i(?:nsert(?:Row|Before|Cell|Data)|tem)|open|delete(?:Row|C(?:ell|aption)|T(?:Head|Foot)|Data)|focus|write(?:ln)?|a(?:dd|ppend(?:Child|Data))|re(?:set|place(?:Child|Data)|move(?:NamedItem|Child|Attribute(?:Node)?)?)|get(?:NamedItem|Element(?:sBy(?:Name|TagName|ClassName)|ById)|Attribute(?:Node)?)|blur)\b(?=\()/},{token:"support.constant",regex:/(s(?:ystemLanguage|cr(?:ipts|ollbars|een(?:X|Y|Top|Left))|t(?:yle(?:Sheets)?|atus(?:Text|bar)?)|ibling(?:Below|Above)|ource|uffixes|e(?:curity(?:Policy)?|l(?:ection|f)))|h(?:istory|ost(?:name)?|as(?:h|Focus))|y|X(?:MLDocument|SLDocument)|n(?:ext|ame(?:space(?:s|URI)|Prop))|M(?:IN_VALUE|AX_VALUE)|c(?:haracterSet|o(?:n(?:structor|trollers)|okieEnabled|lorDepth|mp(?:onents|lete))|urrent|puClass|l(?:i(?:p(?:boardData)?|entInformation)|osed|asses)|alle(?:e|r)|rypto)|t(?:o(?:olbar|p)|ext(?:Transform|Indent|Decoration|Align)|ags)|SQRT(?:1_2|2)|i(?:n(?:ner(?:Height|Width)|put)|ds|gnoreCase)|zIndex|o(?:scpu|n(?:readystatechange|Line)|uter(?:Height|Width)|p(?:sProfile|ener)|ffscreenBuffering)|NEGATIVE_INFINITY|d(?:i(?:splay|alog(?:Height|Top|Width|Left|Arguments)|rectories)|e(?:scription|fault(?:Status|Ch(?:ecked|arset)|View)))|u(?:ser(?:Profile|Language|Agent)|n(?:iqueID|defined)|pdateInterval)|_content|p(?:ixelDepth|ort|ersonalbar|kcs11|l(?:ugins|atform)|a(?:thname|dding(?:Right|Bottom|Top|Left)|rent(?:Window|Layer)?|ge(?:X(?:Offset)?|Y(?:Offset)?))|r(?:o(?:to(?:col|type)|duct(?:Sub)?|mpter)|e(?:vious|fix)))|e(?:n(?:coding|abledPlugin)|x(?:ternal|pando)|mbeds)|v(?:isibility|endor(?:Sub)?|Linkcolor)|URLUnencoded|P(?:I|OSITIVE_INFINITY)|f(?:ilename|o(?:nt(?:Size|Family|Weight)|rmName)|rame(?:s|Element)|gColor)|E|whiteSpace|l(?:i(?:stStyleType|n(?:eHeight|kColor))|o(?:ca(?:tion(?:bar)?|lName)|wsrc)|e(?:ngth|ft(?:Context)?)|a(?:st(?:M(?:odified|atch)|Index|Paren)|yer(?:s|X)|nguage))|a(?:pp(?:MinorVersion|Name|Co(?:deName|re)|Version)|vail(?:Height|Top|Width|Left)|ll|r(?:ity|guments)|Linkcolor|bove)|r(?:ight(?:Context)?|e(?:sponse(?:XML|Text)|adyState))|global|x|m(?:imeTypes|ultiline|enubar|argin(?:Right|Bottom|Top|Left))|L(?:N(?:10|2)|OG(?:10E|2E))|b(?:o(?:ttom|rder(?:Width|RightWidth|BottomWidth|Style|Color|TopWidth|LeftWidth))|ufferDepth|elow|ackground(?:Color|Image)))\b/},{token:"identifier",regex:a},{regex:"",token:"empty",next:"no_regex"}],start:[o.getStartRule("doc-start"),n("start"),{token:"string.regexp",regex:"\\/",next:"regex"},{token:"text",regex:"\\s+|^$",next:"start"},{token:"empty",regex:"",next:"no_regex"}],regex:[{token:"regexp.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"string.regexp",regex:"/[sxngimy]*",next:"no_regex"},{token:"invalid",regex:/\{\d+\b,?\d*\}[+*]|[+*$^?][+*]|[$^][?]|\?{3,}/},{token:"constant.language.escape",regex:/\(\?[:=!]|\)|\{\d+\b,?\d*\}|[+*]\?|[()$^+*?.]/},{token:"constant.language.delimiter",regex:/\|/},{token:"constant.language.escape",regex:/\[\^?/,next:"regex_character_class"},{token:"empty",regex:"$",next:"no_regex"},{defaultToken:"string.regexp"}],regex_character_class:[{token:"regexp.charclass.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"constant.language.escape",regex:"]",next:"regex"},{token:"constant.language.escape",regex:"-"},{token:"empty",regex:"$",next:"no_regex"},{defaultToken:"string.regexp.charachterclass"}],function_arguments:[{token:"variable.parameter",regex:a},{token:"punctuation.operator",regex:"[, ]+"},{token:"punctuation.operator",regex:"$"},{token:"empty",regex:"",next:"no_regex"}],qqstring:[{token:"constant.language.escape",regex:i},{token:"string",regex:"\\\\$",consumeLineEnd:!0},{token:"string",regex:'"|$',next:"no_regex"},{defaultToken:"string"}],qstring:[{token:"constant.language.escape",regex:i},{token:"string",regex:"\\\\$",consumeLineEnd:!0},{token:"string",regex:"'|$",next:"no_regex"},{defaultToken:"string"}]},e&&e.noES6||(this.$rules.no_regex.unshift({regex:"[{}]",onMatch:function(e,t,i){if(this.next="{"==e?this.nextState:"","{"==e&&i.length)i.unshift("start",t);else if("}"==e&&i.length&&(i.shift(),this.next=i.shift(),-1!=this.next.indexOf("string")||-1!=this.next.indexOf("jsx")))return"paren.quasi.end";return"{"==e?"paren.lparen":"paren.rparen"},nextState:"start"},{token:"string.quasi.start",regex:/`/,push:[{token:"constant.language.escape",regex:i},{token:"paren.quasi.start",regex:/\${/,push:"start"},{token:"string.quasi.end",regex:/`/,next:"pop"},{defaultToken:"string.quasi"}]}),(!e||0!=e.jsx)&&function(){var e=a.replace("\\d","\\d\\-"),t={onMatch:function(e,t,i){var n="/"==e.charAt(1)?2:1;return 1==n?(t!=this.nextState?i.unshift(this.next,this.nextState,0):i.unshift(this.next),i[2]++):2==n&&t==this.nextState&&(i[1]--,(!i[1]||i[1]<0)&&(i.shift(),i.shift())),[{type:"meta.tag.punctuation."+(1==n?"":"end-")+"tag-open.xml",value:e.slice(0,n)},{type:"meta.tag.tag-name.xml",value:e.substr(n)}]},regex:"",onMatch:function(e,t,i){return t==i[0]&&i.shift(),2==e.length&&(i[0]==this.nextState&&i[1]--,(!i[1]||i[1]<0)&&i.splice(0,2)),this.next=i[0]||"start",[{type:this.token,value:e}]},nextState:"jsx"},i,n("jsxAttributes"),{token:"entity.other.attribute-name.xml",regex:e},{token:"keyword.operator.attribute-equals.xml",regex:"="},{token:"text.tag-whitespace.xml",regex:"\\s+"},{token:"string.attribute-value.xml",regex:"'",stateName:"jsx_attr_q",push:[{token:"string.attribute-value.xml",regex:"'",next:"pop"},{include:"reference"},{defaultToken:"string.attribute-value.xml"}]},{token:"string.attribute-value.xml",regex:'"',stateName:"jsx_attr_qq",push:[{token:"string.attribute-value.xml",regex:'"',next:"pop"},{include:"reference"},{defaultToken:"string.attribute-value.xml"}]},t],this.$rules.reference=[{token:"constant.language.escape.reference.xml",regex:"(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)"}]}.call(this)),this.embedRules(o,"doc-",[o.getEndRule("no_regex")]),this.normalizeRules()};s.inherits(l,r),t.JavaScriptHighlightRules=l}),ace.define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],function(e,t,i){"use strict";var r=e("../range").Range,n=function(){};(function(){this.checkOutdent=function(e,t){return!!/^\s+$/.test(e)&&/^\s*\}/.test(t)},this.autoOutdent=function(e,t){var i=e.getLine(t).match(/^(\s*\})/);if(!i)return 0;var n=i[1].length,s=e.findMatchingBracket({row:t,column:n});if(!s||s.row==t)return 0;var o=this.$getIndent(e.getLine(s.row));e.replace(new r(t,0,t,n-1),o)},this.$getIndent=function(e){return e.match(/^\s*/)[0]}}).call(n.prototype),t.MatchingBraceOutdent=n}),ace.define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],function(e,t,i){"use strict";var n=e("../../lib/oop"),h=e("../../range").Range,s=e("./fold_mode").FoldMode,o=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end)))};n.inherits(o,s),function(){this.foldingStartMarker=/([\{\[\(])[^\}\]\)]*$|^\s*(\/\*)/,this.foldingStopMarker=/^[^\[\{\(]*([\}\]\)])|^[\s\*]*(\*\/)/,this.singleLineBlockCommentRe=/^\s*(\/\*).*\*\/\s*$/,this.tripleStarBlockCommentRe=/^\s*(\/\*\*\*).*\*\/\s*$/,this.startRegionRe=/^\s*(\/\*|\/\/)#?region\b/,this._getFoldWidgetBase=this.getFoldWidget,this.getFoldWidget=function(e,t,i){var n=e.getLine(i);if(this.singleLineBlockCommentRe.test(n)&&!this.startRegionRe.test(n)&&!this.tripleStarBlockCommentRe.test(n))return"";var s=this._getFoldWidgetBase(e,t,i);return!s&&this.startRegionRe.test(n)?"start":s},this.getFoldWidgetRange=function(e,t,i,n){var s,o=e.getLine(i);if(this.startRegionRe.test(o))return this.getCommentRegionBlock(e,o,i);if(s=o.match(this.foldingStartMarker)){var r=s.index;if(s[1])return this.openingBracketBlock(e,s[1],i,r);var a=e.getCommentFoldRange(i,r+s[0].length,1);return a&&!a.isMultiLine()&&(n?a=this.getSectionRange(e,i):"all"!=t&&(a=null)),a}if("markbegin"!==t&&(s=o.match(this.foldingStopMarker))){r=s.index+s[0].length;return s[1]?this.closingBracketBlock(e,s[1],i,r):e.getCommentFoldRange(i,r,-1)}},this.getSectionRange=function(e,t){for(var i=e.getLine(t),n=i.search(/\S/),s=t,o=i.length,r=t+=1,a=e.getLength();++t",next:"start"}],doctype:[{include:"whitespace"},{include:"string"},{token:"xml-pe.doctype.xml",regex:">",next:"start"},{token:"xml-pe.xml",regex:"[-_a-zA-Z0-9:]+"},{token:"punctuation.int-subset",regex:"\\[",push:"int_subset"}],int_subset:[{token:"text.xml",regex:"\\s+"},{token:"punctuation.int-subset.xml",regex:"]",next:"pop"},{token:["punctuation.markup-decl.xml","keyword.markup-decl.xml"],regex:"(<\\!)("+t+")",push:[{token:"text",regex:"\\s+"},{token:"punctuation.markup-decl.xml",regex:">",next:"pop"},{include:"string"}]}],cdata:[{token:"string.cdata.xml",regex:"\\]\\]>",next:"start"},{token:"text.xml",regex:"\\s+"},{token:"text.xml",regex:"(?:[^\\]]|\\](?!\\]>))+"}],comment:[{token:"comment.end.xml",regex:"--\x3e",next:"start"},{defaultToken:"comment.xml"}],reference:[{token:"constant.language.escape.reference.xml",regex:"(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)"}],attr_reference:[{token:"constant.language.escape.reference.attribute-value.xml",regex:"(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)"}],tag:[{token:["meta.tag.punctuation.tag-open.xml","meta.tag.punctuation.end-tag-open.xml","meta.tag.tag-name.xml"],regex:"(?:(<)|(",next:"start"}]}],tag_whitespace:[{token:"text.tag-whitespace.xml",regex:"\\s+"}],whitespace:[{token:"text.whitespace.xml",regex:"\\s+"}],string:[{token:"string.xml",regex:"'",push:[{token:"string.xml",regex:"'",next:"pop"},{defaultToken:"string.xml"}]},{token:"string.xml",regex:'"',push:[{token:"string.xml",regex:'"',next:"pop"},{defaultToken:"string.xml"}]}],attributes:[{token:"entity.other.attribute-name.xml",regex:t},{token:"keyword.operator.attribute-equals.xml",regex:"="},{include:"tag_whitespace"},{include:"attribute_value"}],attribute_value:[{token:"string.attribute-value.xml",regex:"'",push:[{token:"string.attribute-value.xml",regex:"'",next:"pop"},{include:"attr_reference"},{defaultToken:"string.attribute-value.xml"}]},{token:"string.attribute-value.xml",regex:'"',push:[{token:"string.attribute-value.xml",regex:'"',next:"pop"},{include:"attr_reference"},{defaultToken:"string.attribute-value.xml"}]}]},this.constructor===o&&this.normalizeRules()};(function(){this.embedTagRules=function(e,t,i){this.$rules.tag.unshift({token:["meta.tag.punctuation.tag-open.xml","meta.tag."+i+".tag-name.xml"],regex:"(<)("+i+"(?=\\s|>|$))",next:[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:t+"start"}]}),this.$rules[i+"-end"]=[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:"start",onMatch:function(e,t,i){return i.splice(0),this.token}}],this.embedRules(e,t,[{token:["meta.tag.punctuation.end-tag-open.xml","meta.tag."+i+".tag-name.xml"],regex:"(|$))",next:i+"-end"},{token:"string.cdata.xml",regex:"<\\!\\[CDATA\\["},{token:"string.cdata.xml",regex:"\\]\\]>"}])}}).call(s.prototype),n.inherits(o,s),t.XmlHighlightRules=o}),ace.define("ace/mode/html_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/css_highlight_rules","ace/mode/javascript_highlight_rules","ace/mode/xml_highlight_rules"],function(e,t,i){"use strict";var n=e("../lib/oop"),s=e("../lib/lang"),o=e("./css_highlight_rules").CssHighlightRules,r=e("./javascript_highlight_rules").JavaScriptHighlightRules,a=e("./xml_highlight_rules").XmlHighlightRules,l=s.createMap({a:"anchor",button:"form",form:"form",img:"image",input:"form",label:"form",option:"form",script:"script",select:"form",textarea:"form",style:"style",table:"table",tbody:"table",td:"table",tfoot:"table",th:"table",tr:"table"}),c=function(){a.call(this),this.addRules({attributes:[{include:"tag_whitespace"},{token:"entity.other.attribute-name.xml",regex:"[-_a-zA-Z0-9:.]+"},{token:"keyword.operator.attribute-equals.xml",regex:"=",push:[{include:"tag_whitespace"},{token:"string.unquoted.attribute-value.html",regex:"[^<>='\"`\\s]+",next:"pop"},{token:"empty",regex:"",next:"pop"}]},{include:"attribute_value"}],tag:[{token:function(e,t){var i=l[t];return["meta.tag.punctuation."+("<"==e?"":"end-")+"tag-open.xml","meta.tag"+(i?"."+i:"")+".tag-name.xml"]},regex:"(",next:"start"}]}),this.embedTagRules(o,"css-","style"),this.embedTagRules(new r({jsx:!1}).getRules(),"js-","script"),this.constructor===c&&this.normalizeRules()};n.inherits(c,a),t.HtmlHighlightRules=c}),ace.define("ace/mode/behaviour/xml",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator","ace/lib/lang"],function(e,t,i){"use strict";function g(e,t){return e&&-1"==l)||g(h,"decl-attribute-equals")&&(u||"?"==l))return{text:o+o,selection:[1,1]}}}),this.add("string_dquotes","deletion",function(e,t,i,n,s){var o=n.doc.getTextRange(s);if(!s.isMultiLine()&&('"'==o||"'"==o)&&n.doc.getLine(s.start.row).substring(s.start.column+1,s.start.column+2)==o)return s.end.column++,s}),this.add("autoclosing","insertion",function(e,t,i,n,s){if(">"==s){var o=i.getSelectionRange().start,r=new f(n,o.row,o.column),a=r.getCurrentToken()||r.stepBackward();if(!a||!(g(a,"tag-name")||g(a,"tag-whitespace")||g(a,"attribute-name")||g(a,"attribute-equals")||g(a,"attribute-value")))return;if(g(a,"reference.attribute-value"))return;if(g(a,"attribute-value")){var l=r.getCurrentTokenColumn()+a.value.length;if(o.column/.test(n.getLine(o.row).slice(o.column)))return;for(;!g(a,"tag-name");)if("<"==(a=r.stepBackward()).value){a=r.stepForward();break}var h=r.getCurrentTokenRow(),u=r.getCurrentTokenColumn();if(g(r.stepBackward(),"end-tag-open"))return;var d=a.value;if(h==o.row&&(d=d.substring(0,o.column-u)),this.voidElements.hasOwnProperty(d.toLowerCase()))return;return{text:">",selection:[1,1]}}}),this.add("autoindent","insertion",function(e,t,i,n,s){if("\n"==s){var o=i.getCursorPosition(),r=n.getLine(o.row),a=new f(n,o.row,o.column),l=a.getCurrentToken();if(l&&-1!==l.type.indexOf("tag-close")){if("/>"==l.value)return;for(;l&&-1===l.type.indexOf("tag-name");)l=a.stepBackward();if(!l)return;var c=l.value,h=a.getCurrentTokenRow();if(!(l=a.stepBackward())||-1!==l.type.indexOf("end-tag"))return;if(this.voidElements&&!this.voidElements[c]){var u=n.getTokenAt(o.row,o.column+1),d=(r=n.getLine(h),this.$getIndent(r)),g=d+n.getTabString();return u&&""==o.value;break}return n}if(l(o,"tag-close"))return n.selfClosing="/>"==o.value,n;n.start.column+=o.value.length}return null},this._findEndTagInLine=function(e,t,i,n){for(var s=e.getTokens(t),o=0,r=0;r"==t.value,i.end.row=e.getCurrentTokenRow(),i.end.column=e.getCurrentTokenColumn()+t.value.length)}while(t=e.stepBackward());return null},this._pop=function(e,t){for(;e.length;){var i=e[e.length-1];if(!t||i.tagName==t.tagName)return e.pop();if(!this.optionalEndTags.hasOwnProperty(i.tagName))return null;e.pop()}},this.getFoldWidgetRange=function(e,t,i){var n=this._getFirstTagInLine(e,i);if(!n)return this.getCommentFoldWidget(e,i)&&e.getCommentFoldRange(i,e.getLine(i).length);var s,o=[];if(n.closing||n.selfClosing){a=new h(e,i,n.end.column);for(var r={row:i,column:n.start.column};s=this._readTagBackward(a);)if(s.selfClosing){if(!o.length)return s.start.column+=s.tagName.length+2,s.end.column-=2,c.fromPoints(s.start,s.end)}else if(s.closing)o.push(s);else if(this._pop(o,s),0==o.length)return s.start.column+=s.tagName.length+2,s.start.row==s.end.row&&s.start.column23){value=0;}}else if(type=="m"){value=parseInt(value);if(direction){value+=5;}else{value-=5;} +if(value<0){value=55;}else if(value>59){value=0;} +if(value<10){value="0"+value;}} +field.value=('00'+value).substr(-2);},set:function(el){var parent=el.parentElement;while(parent.classList.contains("tpop")==false){parent=parent.parentElement;} +var input=parent.querySelectorAll("input[type=text]");var time=input[0].value+":"+input[1].value;document.getElementById(parent.dataset.target).value=time;parent.classList.remove("show");}};var fpick={attach:function(target){var dig=document.getElementById(target).value.split(".");var t1=dig[0]||"1";var t2=dig[1]||"2";var uniqueID=0;while(document.getElementById("fpick-"+uniqueID)!=null){uniqueID=Math.floor(Math.random()*(100-2))+1;} +var tw=document.createElement("div");tw.id="fpick-"+uniqueID;tw.classList.add("tpop");tw.dataset.target=target;tw.addEventListener("click",function(evt){if(evt.target.classList.contains("tpop")){this.classList.remove("show");}});var tp=document.createElement("div");tp.classList.add("fpicker");tp.appendChild(this.draw("h",t1));tp.appendChild(this.draw("m",t2));var bottom=document.createElement("div"),ok=document.createElement("input");ok.setAttribute("type","button");ok.value="OK";ok.addEventListener("click",function(){fpick.set(this);});bottom.classList.add("fpicker-btn");bottom.appendChild(ok);tp.appendChild(bottom);tw.appendChild(tp);document.body.appendChild(tw);var target=document.getElementById(target);target.dataset.dp=uniqueID;target.onfocus=function(){document.getElementById("fpick-"+this.dataset.dp).classList.add("show");};},draw:function(type,tv){var docket=document.createElement("div"),up=document.createElement("div"),down=document.createElement("div"),text=document.createElement("input");docket.classList.add("fpicker-"+type);up.classList.add("fpicker-up");down.classList.add("fpicker-down");up.innerHTML="︿";down.innerHTML="﹀";text.readOnly=true;text.setAttribute("type","text");if(type=="h"){text.value=tv;up.addEventListener("click",function(){fpick.spin("h",1,this);});down.addEventListener("click",function(){fpick.spin("h",0,this);});}else if(type=="m"){text.value=tv;up.addEventListener("click",function(){fpick.spin("m",1,this);});down.addEventListener("click",function(){fpick.spin("m",0,this);});} +docket.appendChild(up);docket.appendChild(text);docket.appendChild(down);return docket;},spin:function(type,direction,el){var parent=el.parentElement,field=parent.getElementsByTagName("input")[0],value=field.value;if(type=="h"){value=parseInt(value);if(direction){value++;}else{value--;} +if(value==-41){value=99;}else if(value>99){value=-40;}}else if(type=="m"){value=parseInt(value);if(direction){value++;}else{value--;} +if(value<0){value=9;}else if(value>9){value=0;}} +field.value=value;},set:function(el){var parent=el.parentElement;while(parent.classList.contains("tpop")==false){parent=parent.parentElement;} +var input=parent.querySelectorAll("input[type=text]");var temperature=input[0].value+"."+input[1].value;document.getElementById(parent.dataset.target).value=temperature;parent.classList.remove("show");}};!function(t){function n(i){if(e[i]) +return e[i].exports;var o=e[i]={i:i,l:!1,exports:{}};return t[i].call(o.exports,o,o.exports,n),o.l=!0,o.exports} +var e={};n.m=t,n.c=e,n.d=function(t,e,i){n.o(t,e)||Object.defineProperty(t,e,{configurable:!1,enumerable:!0,get:i})},n.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return n.d(e,"a",e),e},n.o=function(t,n){return Object.prototype.hasOwnProperty.call(t,n)},n.p="",n(n.s=0)} +([function(t,n,e){e(1),t.exports=e(4)},function(t,n,e){"use strict";var i=Object.assign||function(t){for(var n=1;n-1} +(t.positionClass)||(console.warn("An invalid notification position class has been specified."),t.positionClass=c.positionClass),t.onclick&&"function"!=typeof t.onclick&&(console.warn("Notification on click must be a function."),t.onclick=c.onclick),"number"!=typeof t.showDuration&&(t.showDuration=c.showDuration),(0,o.isString)(t.theme)&&0!==t.theme.length||(console.warn("Notification theme must be a string with length"),t.theme=c.theme),t} +function e(t){return t=n(t),function(){var n=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},e=n.title,i=n.message,c=r(t.positionClass);if(!e&&!i) +return console.warn("Notification must contain a title or a message!");var a=(0,o.createElement)("div","ncf",t.theme);if(!0===t.closeOnClick&&a.addEventListener("click",function(){return c.removeChild(a)}),t.onclick&&a.addEventListener("click",function(n){return t.onclick(n)}),t.displayCloseButton){var s=(0,o.createElement)("button");s.innerText="X",!1===t.closeOnClick&&s.addEventListener("click",function(){return c.removeChild(a)}),(0,o.append)(a,s)} +if((0,o.isString)(e)&&e.length&&(0,o.append)(a,(0,o.createParagraph)("ncf-title")(e)),(0,o.isString)(i)&&i.length&&(0,o.append)(a,(0,o.createParagraph)("nfc-message")(i)),(0,o.append)(c,a),t.showDuration&&t.showDuration>0){var l=setTimeout(function(){c.removeChild(a),0===c.querySelectorAll(".ncf").length&&document.body.removeChild(c)},t.showDuration);(t.closeOnClick||t.displayCloseButton)&&a.addEventListener("click",function(){return clearTimeout(l)})}}} +function r(t){var n=document.querySelector("."+t);return n||(n=(0,o.createElement)("div","ncf-container",t),(0,o.append)(document.body,n)),n} +var c={closeOnClick:!0,displayCloseButton:!1,positionClass:"nfc-top-right",onclick:!1,showDuration:3500,theme:"success"};t.createNotification?console.warn("Window already contains a create notification function. Have you included the script twice?"):t.createNotification=e} +(window)},function(t,n,e){"use strict";!function(){function t(t){this.el=t;for(var n=t.className.replace(/^\s+|\s+$/g,"").split(/\s+/),i=0;i1?n-1:0),i=1;i1?n-1:0),i=1;i1?n-1:0),i=1;i1?n-1:0),c=1;cp;p++)"zIndex"in i[p]&&(l.push(i[p].zIndex),i[p].zIndex<0&&(m[i[p].zIndex]=i[p]));for(l.sort(h);l[k]<0;) +if(e=m[l[k++]],n.push(e.apply(d,g)),b) +return b=f,n;for(p=0;q>p;p++) +if(e=i[p],"zIndex"in e) +if(e.zIndex==l[k]){if(n.push(e.apply(d,g)),b) +break;do +if(k++,e=m[l[k]],e&&n.push(e.apply(d,g)),b) +break;while(e)}else +m[e.zIndex]=e;else if(n.push(e.apply(d,g)),b) +break;return b=f,a=o,n.length?n:null};return j._events=i,j.listeners=function(a){var b,c,d,g,h,j,k,l,m=a.split(e),n=i,o=[n],p=[];for(g=0,h=m.length;h>g;g++){for(l=[],j=0,k=o.length;k>j;j++) +for(n=o[j].n,c=[n[m[g]],n[f]],d=2;d--;) +b=c[d],b&&(l.push(b),p=p.concat(b.f||[]));o=l} +return p},j.on=function(a,b){if(a=String(a),"function"!=typeof b) +return function(){};for(var c=a.split(e),d=i,f=0,h=c.length;h>f;f++) +d=d.n,d=d.hasOwnProperty(c[f])&&d[c[f]]||(d[c[f]]={n:{}});for(d.f=d.f||[],f=0,h=d.f.length;h>f;f++) +if(d.f[f]==b) +return g;return d.f.push(b),function(a){+a==+a&&(b.zIndex=+a)}},j.f=function(a){var b=[].slice.call(arguments,1);return function(){j.apply(null,[a,null].concat(b).concat([].slice.call(arguments,0)))}},j.stop=function(){b=1},j.nt=function(b){return b?new RegExp("(?:\\.|\\/|^)"+b+"(?:\\.|\\/|$)").test(a):a},j.nts=function(){return a.split(e)},j.off=j.unbind=function(a,b){if(!a) +return void(j._events=i={n:{}});var c,g,h,k,l,m,n,o=a.split(e),p=[i];for(k=0,l=o.length;l>k;k++) +for(m=0;mk;k++) +for(c=p[k];c.n;){if(b){if(c.f){for(m=0,n=c.f.length;n>m;m++) +if(c.f[m]==b){c.f.splice(m,1);break} +!c.f.length&&delete c.f} +for(g in c.n) +if(c.n[d](g)&&c.n[g].f){var q=c.n[g].f;for(m=0,n=q.length;n>m;m++) +if(q[m]==b){q.splice(m,1);break} +!q.length&&delete c.n[g].f}}else{delete c.f;for(g in c.n) +c.n[d](g)&&c.n[g].f&&delete c.n[g].f} +c=c.n}},j.once=function(a,b){var c=function(){return j.unbind(a,c),b.apply(this,arguments)};return j.on(a,c)},j.version=c,j.toString=function(){return"You are running Eve "+c},j}),function(a,b){"function"==typeof define&&define.amd?define("raphael.core",["eve"],function(a){return b(a)}):"object"==typeof exports?module.exports=b(require("eve")):a.Raphael=b(a.eve)} +(this,function(a){function b(c){if(b.is(c,"function")) +return t?c():a.on("raphael.DOMload",c);if(b.is(c,U)) +return b._engine.create[C](b,c.splice(0,3+b.is(c[0],S))).add(c);var d=Array.prototype.slice.call(arguments,0);if(b.is(d[d.length-1],"function")){var e=d.pop();return t?e.call(b._engine.create[C](b,d)):a.on("raphael.DOMload",function(){e.call(b._engine.create[C](b,d))})} +return b._engine.create[C](b,arguments)} +function c(a){if("function"==typeof a||Object(a)!==a) +return a;var b=new a.constructor;for(var d in a) +a[y](d)&&(b[d]=c(a[d]));return b} +function d(a,b){for(var c=0,d=a.length;d>c;c++) +if(a[c]===b) +return a.push(a.splice(c,1)[0])} +function e(a,b,c){function e(){var f=Array.prototype.slice.call(arguments,0),g=f.join("␀"),h=e.cache=e.cache||{},i=e.count=e.count||[];return h[y](g)?(d(i,g),c?c(h[g]):h[g]):(i.length>=1e3&&delete h[i.shift()],i.push(g),h[g]=a[C](b,f),c?c(h[g]):h[g])} +return e} +function f(){return this.hex} +function g(a,b){for(var c=[],d=0,e=a.length;e-2*!b>d;d+=2){var f=[{x:+a[d-2],y:+a[d-1]},{x:+a[d],y:+a[d+1]},{x:+a[d+2],y:+a[d+3]},{x:+a[d+4],y:+a[d+5]}];b?d?e-4==d?f[3]={x:+a[0],y:+a[1]}:e-2==d&&(f[2]={x:+a[0],y:+a[1]},f[3]={x:+a[2],y:+a[3]}):f[0]={x:+a[e-2],y:+a[e-1]}:e-4==d?f[3]=f[2]:d||(f[0]={x:+a[d],y:+a[d+1]}),c.push(["C",(-f[0].x+6*f[1].x+f[2].x)/6,(-f[0].y+6*f[1].y+f[2].y)/6,(f[1].x+6*f[2].x-f[3].x)/6,(f[1].y+6*f[2].y-f[3].y)/6,f[2].x,f[2].y])} +return c} +function h(a,b,c,d,e){var f=-3*b+9*c-9*d+3*e,g=a*f+6*b-12*c+6*d;return a*g-3*b+3*c} +function i(a,b,c,d,e,f,g,i,j){null==j&&(j=1),j=j>1?1:0>j?0:j;for(var k=j/2,l=12,m=[-.1252,.1252,-.3678,.3678,-.5873,.5873,-.7699,.7699,-.9041,.9041,-.9816,.9816],n=[.2491,.2491,.2335,.2335,.2032,.2032,.1601,.1601,.1069,.1069,.0472,.0472],o=0,p=0;l>p;p++){var q=k*m[p]+k,r=h(q,a,c,e,g),s=h(q,b,d,f,i),t=r*r+s*s;o+=n[p]*M.sqrt(t)} +return k*o} +function j(a,b,c,d,e,f,g,h,j){if(!(0>j||i(a,b,c,d,e,f,g,h)o;) +m/=2,n+=(j>k?1:-1)*m,k=i(a,b,c,d,e,f,g,h,n);return n}} +function k(a,b,c,d,e,f,g,h){if(!(N(a,c)N(e,g)||N(b,d)N(f,h))){var i=(a*d-b*c)*(e-g)-(a-c)*(e*h-f*g),j=(a*d-b*c)*(f-h)-(b-d)*(e*h-f*g),k=(a-c)*(f-h)-(b-d)*(e-g);if(k){var l=i/k,m=j/k,n=+l.toFixed(2),o=+m.toFixed(2);if(!(n<+O(a,c).toFixed(2)||n>+N(a,c).toFixed(2)||n<+O(e,g).toFixed(2)||n>+N(e,g).toFixed(2)||o<+O(b,d).toFixed(2)||o>+N(b,d).toFixed(2)||o<+O(f,h).toFixed(2)||o>+N(f,h).toFixed(2))) +return{x:l,y:m}}}} +function l(a,c,d){var e=b.bezierBBox(a),f=b.bezierBBox(c);if(!b.isBBoxIntersect(e,f)) +return d?0:[];for(var g=i.apply(0,a),h=i.apply(0,c),j=N(~~(g/5),1),l=N(~~(h/5),1),m=[],n=[],o={},p=d?0:[],q=0;j+1>q;q++){var r=b.findDotsAtSegment.apply(b,a.concat(q/j));m.push({x:r.x,y:r.y,t:q/j})} +for(q=0;l+1>q;q++) +r=b.findDotsAtSegment.apply(b,c.concat(q/l)),n.push({x:r.x,y:r.y,t:q/l});for(q=0;j>q;q++) +for(var s=0;l>s;s++){var t=m[q],u=m[q+1],v=n[s],w=n[s+1],x=P(u.x-t.x)<.001?"y":"x",y=P(w.x-v.x)<.001?"y":"x",z=k(t.x,t.y,u.x,u.y,v.x,v.y,w.x,w.y);if(z){if(o[z.x.toFixed(4)]==z.y.toFixed(4)) +continue;o[z.x.toFixed(4)]=z.y.toFixed(4);var A=t.t+P((z[x]-t[x])/(u[x]-t[x]))*(u.t-t.t),B=v.t+P((z[y]-v[y])/(w[y]-v[y]))*(w.t-v.t);A>=0&&1.001>=A&&B>=0&&1.001>=B&&(d?p++:p.push({x:z.x,y:z.y,t1:O(A,1),t2:O(B,1)}))}} +return p} +function m(a,c,d){a=b._path2curve(a),c=b._path2curve(c);for(var e,f,g,h,i,j,k,m,n,o,p=d?0:[],q=0,r=a.length;r>q;q++){var s=a[q];if("M"==s[0]) +e=i=s[1],f=j=s[2];else{"C"==s[0]?(n=[e,f].concat(s.slice(1)),e=n[6],f=n[7]):(n=[e,f,e,f,i,j,i,j],e=i,f=j);for(var t=0,u=c.length;u>t;t++){var v=c[t];if("M"==v[0]) +g=k=v[1],h=m=v[2];else{"C"==v[0]?(o=[g,h].concat(v.slice(1)),g=o[6],h=o[7]):(o=[g,h,g,h,k,m,k,m],g=k,h=m);var w=l(n,o,d);if(d) +p+=w;else{for(var x=0,y=w.length;y>x;x++) +w[x].segment1=q,w[x].segment2=t,w[x].bez1=n,w[x].bez2=o;p=p.concat(w)}}}}} +return p} +function n(a,b,c,d,e,f){null!=a?(this.a=+a,this.b=+b,this.c=+c,this.d=+d,this.e=+e,this.f=+f):(this.a=1,this.b=0,this.c=0,this.d=1,this.e=0,this.f=0)} +function o(){return this.x+G+this.y+G+this.width+" × "+this.height} +function p(a,b,c,d,e,f){function g(a){return((l*a+k)*a+j)*a} +function h(a,b){var c=i(a,b);return((o*c+n)*c+m)*c} +function i(a,b){var c,d,e,f,h,i;for(e=a,i=0;8>i;i++){if(f=g(e)-a,P(f)e) +return c;if(e>d) +return d;for(;d>c;){if(f=g(e),P(f-a)f?c=e:d=e,e=(d-c)/2+c} +return e} +var j=3*b,k=3*(d-b)-j,l=1-j-k,m=3*c,n=3*(e-c)-m,o=1-m-n;return h(a,1/(200*f))} +function q(a,b){var c=[],d={};if(this.ms=b,this.times=1,a){for(var e in a) +a[y](e)&&(d[$(e)]=a[e],c.push($(e)));c.sort(ka)} +this.anim=d,this.top=c[c.length-1],this.percents=c} +function r(c,d,e,f,g,h){e=$(e);var i,j,k,l,m,o,q=c.ms,r={},s={},t={};if(f) +for(w=0,x=fb.length;x>w;w++){var u=fb[w];if(u.el.id==d.id&&u.anim==c){u.percent!=e?(fb.splice(w,1),k=1):j=u,d.attr(u.totalOrigin);break}} +else +f=+s;for(var w=0,x=c.percents.length;x>w;w++){if(c.percents[w]==e||c.percents[w]>f*c.top){e=c.percents[w],m=c.percents[w-1]||0,q=q/c.top*(e-m),l=c.percents[w+1],i=c.anim[e];break} +f&&d.attr(c.anim[c.percents[w]])} +if(i){if(j) +j.initstatus=f,j.start=new Date-j.ms*f;else{for(var z in i) +if(i[y](z)&&(ca[y](z)||d.paper.customAttributes[y](z))) +switch(r[z]=d.attr(z),null==r[z]&&(r[z]=ba[z]),s[z]=i[z],ca[z]){case S:t[z]=(s[z]-r[z])/q;break;case"colour":r[z]=b.getRGB(r[z]);var A=b.getRGB(s[z]);t[z]={r:(A.r-r[z].r)/q,g:(A.g-r[z].g)/q,b:(A.b-r[z].b)/q};break;case"path":var B=Ia(r[z],s[z]),C=B[1];for(r[z]=B[0],t[z]=[],w=0,x=r[z].length;x>w;w++){t[z][w]=[0];for(var E=1,F=r[z][w].length;F>E;E++) +t[z][w][E]=(C[w][E]-r[z][w][E])/q} +break;case"transform":var G=d._,J=Na(G[z],s[z]);if(J) +for(r[z]=J.from,s[z]=J.to,t[z]=[],t[z].real=!0,w=0,x=r[z].length;x>w;w++) +for(t[z][w]=[r[z][w][0]],E=1,F=r[z][w].length;F>E;E++) +t[z][w][E]=(s[z][w][E]-r[z][w][E])/q;else{var K=d.matrix||new n,L={_:{transform:G.transform},getBBox:function(){return d.getBBox(1)}};r[z]=[K.a,K.b,K.c,K.d,K.e,K.f],La(L,s[z]),s[z]=L._.transform,t[z]=[(L.matrix.a-K.a)/q,(L.matrix.b-K.b)/q,(L.matrix.c-K.c)/q,(L.matrix.d-K.d)/q,(L.matrix.e-K.e)/q,(L.matrix.f-K.f)/q]} +break;case"csv":var M=H(i[z])[I](v),N=H(r[z])[I](v);if("clip-rect"==z) +for(r[z]=N,t[z]=[],w=N.length;w--;) +t[z][w]=(M[w]-r[z][w])/q;s[z]=M;break;default:for(M=[][D](i[z]),N=[][D](r[z]),t[z]=[],w=d.paper.customAttributes[z].length;w--;) +t[z][w]=((M[w]||0)-(N[w]||0))/q} +var O=i.easing,P=b.easing_formulas[O];if(!P) +if(P=H(O).match(Y),P&&5==P.length){var Q=P;P=function(a){return p(a,+Q[1],+Q[2],+Q[3],+Q[4],q)}}else +P=la;if(o=i.start||c.start||+new Date,u={anim:c,percent:e,timestamp:o,start:o+(c.del||0),status:0,initstatus:f||0,stop:!1,ms:q,easing:P,from:r,diff:t,to:s,el:d,callback:i.callback,prev:m,next:l,repeat:h||c.times,origin:d.attr(),totalOrigin:g},fb.push(u),f&&!j&&!k&&(u.stop=!0,u.start=new Date-q*f,1==fb.length)) +return hb();k&&(u.start=new Date-u.ms*f),1==fb.length&&gb(hb)} +a("raphael.anim.start."+d.id,d,c)}} +function s(a){for(var b=0;be;e++) +for(i=a[e],f=1,h=i.length;h>f;f+=2) +c=b.x(i[f],i[f+1]),d=b.y(i[f],i[f+1]),i[f]=c,i[f+1]=d;return a};if(b._g=z,b.type=z.win.SVGAngle||z.doc.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure","1.1")?"SVG":"VML","VML"==b.type){var qa,ra=z.doc.createElement("div");if(ra.innerHTML='',qa=ra.firstChild,qa.style.behavior="url(#default#VML)",!qa||"object"!=typeof qa.adj) +return b.type=F;ra=null} +b.svg=!(b.vml="VML"==b.type),b._Paper=B,b.fn=u=B.prototype=b.prototype,b._id=0,b._oid=0,b.is=function(a,b){return b=L.call(b),"finite"==b?!X[y](+a):"array"==b?a instanceof Array:"null"==b&&null===a||b==typeof a&&null!==a||"object"==b&&a===Object(a)||"array"==b&&Array.isArray&&Array.isArray(a)||V.call(a).slice(8,-1).toLowerCase()==b},b.angle=function(a,c,d,e,f,g){if(null==f){var h=a-d,i=c-e;return h||i?(180+180*M.atan2(-i,-h)/R+360)%360:0} +return b.angle(a,c,f,g)-b.angle(d,e,f,g)},b.rad=function(a){return a%360*R/180},b.deg=function(a){return Math.round(180*a/R%360*1e3)/1e3},b.snapTo=function(a,c,d){if(d=b.is(d,"finite")?d:10,b.is(a,U)){for(var e=a.length;e--;) +if(P(a[e]-c)<=d) +return a[e]}else{a=+a;var f=c%a;if(d>f) +return c-f;if(f>a-d) +return c-f+a} +return c};b.createUUID=function(a,b){return function(){return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(a,b).toUpperCase()}} +(/[xy]/g,function(a){var b=16*M.random()|0,c="x"==a?b:3&b|8;return c.toString(16)});b.setWindow=function(c){a("raphael.setWindow",b,z.win,c),z.win=c,z.doc=z.win.document,b._engine.initWin&&b._engine.initWin(z.win)};var sa=function(a){if(b.vml){var c,d=/^\s+|\s+$/g;try{var f=new ActiveXObject("htmlfile");f.write(""),f.close(),c=f.body}catch(g){c=createPopup().document.body} +var h=c.createTextRange();sa=e(function(a){try{c.style.color=H(a).replace(d,F);var b=h.queryCommandValue("ForeColor");return b=(255&b)<<16|65280&b|(16711680&b)>>>16,"#"+("000000"+b.toString(16)).slice(-6)}catch(e){return"none"}})}else{var i=z.doc.createElement("i");i.title="Raphaël Colour Picker",i.style.display="none",z.doc.body.appendChild(i),sa=e(function(a){return i.style.color=a,z.doc.defaultView.getComputedStyle(i,F).getPropertyValue("color")})} +return sa(a)},ta=function(){return"hsb("+[this.h,this.s,this.b]+")"},ua=function(){return"hsl("+[this.h,this.s,this.l]+")"},va=function(){return this.hex},wa=function(a,c,d){if(null==c&&b.is(a,"object")&&"r"in a&&"g"in a&&"b"in a&&(d=a.b,c=a.g,a=a.r),null==c&&b.is(a,T)){var e=b.getRGB(a);a=e.r,c=e.g,d=e.b} +return(a>1||c>1||d>1)&&(a/=255,c/=255,d/=255),[a,c,d]},xa=function(a,c,d,e){a*=255,c*=255,d*=255;var f={r:a,g:c,b:d,hex:b.rgb(a,c,d),toString:va};return b.is(e,"finite")&&(f.opacity=e),f};b.color=function(a){var c;return b.is(a,"object")&&"h"in a&&"s"in a&&"b"in a?(c=b.hsb2rgb(a),a.r=c.r,a.g=c.g,a.b=c.b,a.hex=c.hex):b.is(a,"object")&&"h"in a&&"s"in a&&"l"in a?(c=b.hsl2rgb(a),a.r=c.r,a.g=c.g,a.b=c.b,a.hex=c.hex):(b.is(a,"string")&&(a=b.getRGB(a)),b.is(a,"object")&&"r"in a&&"g"in a&&"b"in a?(c=b.rgb2hsl(a),a.h=c.h,a.s=c.s,a.l=c.l,c=b.rgb2hsb(a),a.v=c.b):(a={hex:"none"},a.r=a.g=a.b=a.h=a.s=a.v=a.l=-1)),a.toString=va,a},b.hsb2rgb=function(a,b,c,d){this.is(a,"object")&&"h"in a&&"s"in a&&"b"in a&&(c=a.b,b=a.s,d=a.o,a=a.h),a*=360;var e,f,g,h,i;return a=a%360/60,i=c*b,h=i*(1-P(a%2-1)),e=f=g=c-i,a=~~a,e+=[i,h,0,0,h,i][a],f+=[h,i,i,h,0,0][a],g+=[0,0,h,i,i,h][a],xa(e,f,g,d)},b.hsl2rgb=function(a,b,c,d){this.is(a,"object")&&"h"in a&&"s"in a&&"l"in a&&(c=a.l,b=a.s,a=a.h),(a>1||b>1||c>1)&&(a/=360,b/=100,c/=100),a*=360;var e,f,g,h,i;return a=a%360/60,i=2*b*(.5>c?c:1-c),h=i*(1-P(a%2-1)),e=f=g=c-i/2,a=~~a,e+=[i,h,0,0,h,i][a],f+=[h,i,i,h,0,0][a],g+=[0,0,h,i,i,h][a],xa(e,f,g,d)},b.rgb2hsb=function(a,b,c){c=wa(a,b,c),a=c[0],b=c[1],c=c[2];var d,e,f,g;return f=N(a,b,c),g=f-O(a,b,c),d=0==g?null:f==a?(b-c)/g:f==b?(c-a)/g+2:(a-b)/g+4,d=(d+360)%6*60/360,e=0==g?0:g/f,{h:d,s:e,b:f,toString:ta}},b.rgb2hsl=function(a,b,c){c=wa(a,b,c),a=c[0],b=c[1],c=c[2];var d,e,f,g,h,i;return g=N(a,b,c),h=O(a,b,c),i=g-h,d=0==i?null:g==a?(b-c)/i:g==b?(c-a)/i+2:(a-b)/i+4,d=(d+360)%6*60/360,f=(g+h)/2,e=0==i?0:.5>f?i/(2*f):i/(2-2*f),{h:d,s:e,l:f,toString:ua}},b._path2string=function(){return this.join(",").replace(fa,"$1")};b._preload=function(a,b){var c=z.doc.createElement("img");c.style.cssText="position:absolute;left:-9999em;top:-9999em",c.onload=function(){b.call(this),this.onload=null,z.doc.body.removeChild(this)},c.onerror=function(){z.doc.body.removeChild(this)},z.doc.body.appendChild(c),c.src=a};b.getRGB=e(function(a){if(!a||(a=H(a)).indexOf("-")+1) +return{r:-1,g:-1,b:-1,hex:"none",error:1,toString:f};if("none"==a) +return{r:-1,g:-1,b:-1,hex:"none",toString:f};!(ea[y](a.toLowerCase().substring(0,2))||"#"==a.charAt())&&(a=sa(a));var c,d,e,g,h,i,j=a.match(W);return j?(j[2]&&(e=_(j[2].substring(5),16),d=_(j[2].substring(3,5),16),c=_(j[2].substring(1,3),16)),j[3]&&(e=_((h=j[3].charAt(3))+h,16),d=_((h=j[3].charAt(2))+h,16),c=_((h=j[3].charAt(1))+h,16)),j[4]&&(i=j[4][I](da),c=$(i[0]),"%"==i[0].slice(-1)&&(c*=2.55),d=$(i[1]),"%"==i[1].slice(-1)&&(d*=2.55),e=$(i[2]),"%"==i[2].slice(-1)&&(e*=2.55),"rgba"==j[1].toLowerCase().slice(0,4)&&(g=$(i[3])),i[3]&&"%"==i[3].slice(-1)&&(g/=100)),j[5]?(i=j[5][I](da),c=$(i[0]),"%"==i[0].slice(-1)&&(c*=2.55),d=$(i[1]),"%"==i[1].slice(-1)&&(d*=2.55),e=$(i[2]),"%"==i[2].slice(-1)&&(e*=2.55),("deg"==i[0].slice(-3)||"°"==i[0].slice(-1))&&(c/=360),"hsba"==j[1].toLowerCase().slice(0,4)&&(g=$(i[3])),i[3]&&"%"==i[3].slice(-1)&&(g/=100),b.hsb2rgb(c,d,e,g)):j[6]?(i=j[6][I](da),c=$(i[0]),"%"==i[0].slice(-1)&&(c*=2.55),d=$(i[1]),"%"==i[1].slice(-1)&&(d*=2.55),e=$(i[2]),"%"==i[2].slice(-1)&&(e*=2.55),("deg"==i[0].slice(-3)||"°"==i[0].slice(-1))&&(c/=360),"hsla"==j[1].toLowerCase().slice(0,4)&&(g=$(i[3])),i[3]&&"%"==i[3].slice(-1)&&(g/=100),b.hsl2rgb(c,d,e,g)):(j={r:c,g:d,b:e,toString:f},j.hex="#"+(16777216|e|d<<8|c<<16).toString(16).slice(1),b.is(g,"finite")&&(j.opacity=g),j)):{r:-1,g:-1,b:-1,hex:"none",error:1,toString:f}},b),b.hsb=e(function(a,c,d){return b.hsb2rgb(a,c,d).hex}),b.hsl=e(function(a,c,d){return b.hsl2rgb(a,c,d).hex}),b.rgb=e(function(a,b,c){function d(a){return a+.5|0} +return"#"+(16777216|d(c)|d(b)<<8|d(a)<<16).toString(16).slice(1)}),b.getColor=function(a){var b=this.getColor.start=this.getColor.start||{h:0,s:1,b:a||.75},c=this.hsb2rgb(b.h,b.s,b.b);return b.h+=.075,b.h>1&&(b.h=0,b.s-=.2,b.s<=0&&(this.getColor.start={h:0,s:1,b:b.b})),c.hex},b.getColor.reset=function(){delete this.start},b.parsePathString=function(a){if(!a) +return null;var c=ya(a);if(c.arr) +return Aa(c.arr);var d={a:7,c:6,h:1,l:2,m:2,r:4,q:4,s:4,t:2,v:1,z:0},e=[];return b.is(a,U)&&b.is(a[0],U)&&(e=Aa(a)),e.length||H(a).replace(ga,function(a,b,c){var f=[],g=b.toLowerCase();if(c.replace(ia,function(a,b){b&&f.push(+b)}),"m"==g&&f.length>2&&(e.push([b][D](f.splice(0,2))),g="l",b="m"==b?"l":"L"),"r"==g) +e.push([b][D](f));else +for(;f.length>=d[g]&&(e.push([b][D](f.splice(0,d[g]))),d[g]););}),e.toString=b._path2string,c.arr=Aa(e),e},b.parseTransformString=e(function(a){if(!a) +return null;var c=[];return b.is(a,U)&&b.is(a[0],U)&&(c=Aa(a)),c.length||H(a).replace(ha,function(a,b,d){{var e=[];L.call(b)} +d.replace(ia,function(a,b){b&&e.push(+b)}),c.push([b][D](e))}),c.toString=b._path2string,c});var ya=function(a){var b=ya.ps=ya.ps||{};return b[a]?b[a].sleep=100:b[a]={sleep:100},setTimeout(function(){for(var c in b) +b[y](c)&&c!=a&&(b[c].sleep--,!b[c].sleep&&delete b[c])}),b[a]};b.findDotsAtSegment=function(a,b,c,d,e,f,g,h,i){var j=1-i,k=Q(j,3),l=Q(j,2),m=i*i,n=m*i,o=k*a+3*l*i*c+3*j*i*i*e+n*g,p=k*b+3*l*i*d+3*j*i*i*f+n*h,q=a+2*i*(c-a)+m*(e-2*c+a),r=b+2*i*(d-b)+m*(f-2*d+b),s=c+2*i*(e-c)+m*(g-2*e+c),t=d+2*i*(f-d)+m*(h-2*f+d),u=j*a+i*c,v=j*b+i*d,w=j*e+i*g,x=j*f+i*h,y=90-180*M.atan2(q-s,r-t)/R;return(q>s||t>r)&&(y+=180),{x:o,y:p,m:{x:q,y:r},n:{x:s,y:t},start:{x:u,y:v},end:{x:w,y:x},alpha:y}},b.bezierBBox=function(a,c,d,e,f,g,h,i){b.is(a,"array")||(a=[a,c,d,e,f,g,h,i]);var j=Ha.apply(null,a);return{x:j.min.x,y:j.min.y,x2:j.max.x,y2:j.max.y,width:j.max.x-j.min.x,height:j.max.y-j.min.y}},b.isPointInsideBBox=function(a,b,c){return b>=a.x&&b<=a.x2&&c>=a.y&&c<=a.y2},b.isBBoxIntersect=function(a,c){var d=b.isPointInsideBBox;return d(c,a.x,a.y)||d(c,a.x2,a.y)||d(c,a.x,a.y2)||d(c,a.x2,a.y2)||d(a,c.x,c.y)||d(a,c.x2,c.y)||d(a,c.x,c.y2)||d(a,c.x2,c.y2)||(a.xc.x||c.xa.x)&&(a.yc.y||c.ya.y)},b.pathIntersection=function(a,b){return m(a,b)},b.pathIntersectionNumber=function(a,b){return m(a,b,1)},b.isPointInsidePath=function(a,c,d){var e=b.pathBBox(a);return b.isPointInsideBBox(e,c,d)&&m(a,[["M",c,d],["H",e.x2+10]],1)%2==1},b._removedFactory=function(b){return function(){a("raphael.log",null,"Raphaël: you are calling to method “"+b+"” of removed object",b)}};var za=b.pathBBox=function(a){var b=ya(a);if(b.bbox) +return c(b.bbox);if(!a) +return{x:0,y:0,width:0,height:0,x2:0,y2:0};a=Ia(a);for(var d,e=0,f=0,g=[],h=[],i=0,j=a.length;j>i;i++) +if(d=a[i],"M"==d[0]) +e=d[1],f=d[2],g.push(e),h.push(f);else{var k=Ha(e,f,d[1],d[2],d[3],d[4],d[5],d[6]);g=g[D](k.min.x,k.max.x),h=h[D](k.min.y,k.max.y),e=d[5],f=d[6]} +var l=O[C](0,g),m=O[C](0,h),n=N[C](0,g),o=N[C](0,h),p=n-l,q=o-m,r={x:l,y:m,x2:n,y2:o,width:p,height:q,cx:l+p/2,cy:m+q/2};return b.bbox=c(r),r},Aa=function(a){var d=c(a);return d.toString=b._path2string,d},Ba=b._pathToRelative=function(a){var c=ya(a);if(c.rel) +return Aa(c.rel);b.is(a,U)&&b.is(a&&a[0],U)||(a=b.parsePathString(a));var d=[],e=0,f=0,g=0,h=0,i=0;"M"==a[0][0]&&(e=a[0][1],f=a[0][2],g=e,h=f,i++,d.push(["M",e,f]));for(var j=i,k=a.length;k>j;j++){var l=d[j]=[],m=a[j];if(m[0]!=L.call(m[0])) +switch(l[0]=L.call(m[0]),l[0]){case"a":l[1]=m[1],l[2]=m[2],l[3]=m[3],l[4]=m[4],l[5]=m[5],l[6]=+(m[6]-e).toFixed(3),l[7]=+(m[7]-f).toFixed(3);break;case"v":l[1]=+(m[1]-f).toFixed(3);break;case"m":g=m[1],h=m[2];default:for(var n=1,o=m.length;o>n;n++) +l[n]=+(m[n]-(n%2?e:f)).toFixed(3)} +else{l=d[j]=[],"m"==m[0]&&(g=m[1]+e,h=m[2]+f);for(var p=0,q=m.length;q>p;p++) +d[j][p]=m[p]} +var r=d[j].length;switch(d[j][0]){case"z":e=g,f=h;break;case"h":e+=+d[j][r-1];break;case"v":f+=+d[j][r-1];break;default:e+=+d[j][r-2],f+=+d[j][r-1]}} +return d.toString=b._path2string,c.rel=Aa(d),d},Ca=b._pathToAbsolute=function(a){var c=ya(a);if(c.abs) +return Aa(c.abs);if(b.is(a,U)&&b.is(a&&a[0],U)||(a=b.parsePathString(a)),!a||!a.length) +return[["M",0,0]];var d=[],e=0,f=0,h=0,i=0,j=0;"M"==a[0][0]&&(e=+a[0][1],f=+a[0][2],h=e,i=f,j++,d[0]=["M",e,f]);for(var k,l,m=3==a.length&&"M"==a[0][0]&&"R"==a[1][0].toUpperCase()&&"Z"==a[2][0].toUpperCase(),n=j,o=a.length;o>n;n++){if(d.push(k=[]),l=a[n],l[0]!=aa.call(l[0])) +switch(k[0]=aa.call(l[0]),k[0]){case"A":k[1]=l[1],k[2]=l[2],k[3]=l[3],k[4]=l[4],k[5]=l[5],k[6]=+(l[6]+e),k[7]=+(l[7]+f);break;case"V":k[1]=+l[1]+f;break;case"H":k[1]=+l[1]+e;break;case"R":for(var p=[e,f][D](l.slice(1)),q=2,r=p.length;r>q;q++) +p[q]=+p[q]+e,p[++q]=+p[q]+f;d.pop(),d=d[D](g(p,m));break;case"M":h=+l[1]+e,i=+l[2]+f;default:for(q=1,r=l.length;r>q;q++) +k[q]=+l[q]+(q%2?e:f)} +else if("R"==l[0]) +p=[e,f][D](l.slice(1)),d.pop(),d=d[D](g(p,m)),k=["R"][D](l.slice(-2));else +for(var s=0,t=l.length;t>s;s++) +k[s]=l[s];switch(k[0]){case"Z":e=h,f=i;break;case"H":e=k[1];break;case"V":f=k[1];break;case"M":h=k[k.length-2],i=k[k.length-1];default:e=k[k.length-2],f=k[k.length-1]}} +return d.toString=b._path2string,c.abs=Aa(d),d},Da=function(a,b,c,d){return[a,b,c,d,c,d]},Ea=function(a,b,c,d,e,f){var g=1/3,h=2/3;return[g*a+h*c,g*b+h*d,g*e+h*c,g*f+h*d,e,f]},Fa=function(a,b,c,d,f,g,h,i,j,k){var l,m=120*R/180,n=R/180*(+f||0),o=[],p=e(function(a,b,c){var d=a*M.cos(c)-b*M.sin(c),e=a*M.sin(c)+b*M.cos(c);return{x:d,y:e}});if(k) +y=k[0],z=k[1],w=k[2],x=k[3];else{l=p(a,b,-n),a=l.x,b=l.y,l=p(i,j,-n),i=l.x,j=l.y;var q=(M.cos(R/180*f),M.sin(R/180*f),(a-i)/2),r=(b-j)/2,s=q*q/(c*c)+r*r/(d*d);s>1&&(s=M.sqrt(s),c=s*c,d=s*d);var t=c*c,u=d*d,v=(g==h?-1:1)*M.sqrt(P((t*u-t*r*r-u*q*q)/(t*r*r+u*q*q))),w=v*c*r/d+(a+i)/2,x=v* -d*q/c+(b+j)/2,y=M.asin(((b-x)/d).toFixed(9)),z=M.asin(((j-x)/d).toFixed(9));y=w>a?R-y:y,z=w>i?R-z:z,0>y&&(y=2*R+y),0>z&&(z=2*R+z),h&&y>z&&(y-=2*R),!h&&z>y&&(z-=2*R)} +var A=z-y;if(P(A)>m){var B=z,C=i,E=j;z=y+m*(h&&z>y?1:-1),i=w+c*M.cos(z),j=x+d*M.sin(z),o=Fa(i,j,c,d,f,0,h,C,E,[z,B,w,x])} +A=z-y;var F=M.cos(y),G=M.sin(y),H=M.cos(z),J=M.sin(z),K=M.tan(A/4),L=4/3*c*K,N=4/3*d*K,O=[a,b],Q=[a+L*G,b-N*F],S=[i+L*J,j-N*H],T=[i,j];if(Q[0]=2*O[0]-Q[0],Q[1]=2*O[1]-Q[1],k) +return[Q,S,T][D](o);o=[Q,S,T][D](o).join()[I](",");for(var U=[],V=0,W=o.length;W>V;V++) +U[V]=V%2?p(o[V-1],o[V],n).y:p(o[V],o[V+1],n).x;return U},Ga=function(a,b,c,d,e,f,g,h,i){var j=1-i;return{x:Q(j,3)*a+3*Q(j,2)*i*c+3*j*i*i*e+Q(i,3)*g,y:Q(j,3)*b+3*Q(j,2)*i*d+3*j*i*i*f+Q(i,3)*h}},Ha=e(function(a,b,c,d,e,f,g,h){var i,j=e-2*c+a-(g-2*e+c),k=2*(c-a)-2*(e-c),l=a-c,m=(-k+M.sqrt(k*k-4*j*l))/2/j,n=(-k-M.sqrt(k*k-4*j*l))/2/j,o=[b,h],p=[a,g];return P(m)>"1e12"&&(m=.5),P(n)>"1e12"&&(n=.5),m>0&&1>m&&(i=Ga(a,b,c,d,e,f,g,h,m),p.push(i.x),o.push(i.y)),n>0&&1>n&&(i=Ga(a,b,c,d,e,f,g,h,n),p.push(i.x),o.push(i.y)),j=f-2*d+b-(h-2*f+d),k=2*(d-b)-2*(f-d),l=b-d,m=(-k+M.sqrt(k*k-4*j*l))/2/j,n=(-k-M.sqrt(k*k-4*j*l))/2/j,P(m)>"1e12"&&(m=.5),P(n)>"1e12"&&(n=.5),m>0&&1>m&&(i=Ga(a,b,c,d,e,f,g,h,m),p.push(i.x),o.push(i.y)),n>0&&1>n&&(i=Ga(a,b,c,d,e,f,g,h,n),p.push(i.x),o.push(i.y)),{min:{x:O[C](0,p),y:O[C](0,o)},max:{x:N[C](0,p),y:N[C](0,o)}}}),Ia=b._path2curve=e(function(a,b){var c=!b&&ya(a);if(!b&&c.curve) +return Aa(c.curve);for(var d=Ca(a),e=b&&Ca(b),f={x:0,y:0,bx:0,by:0,X:0,Y:0,qx:null,qy:null},g={x:0,y:0,bx:0,by:0,X:0,Y:0,qx:null,qy:null},h=(function(a,b,c){var d,e,f={T:1,Q:1};if(!a) +return["C",b.x,b.y,b.x,b.y,b.x,b.y];switch(!(a[0]in f)&&(b.qx=b.qy=null),a[0]){case"M":b.X=a[1],b.Y=a[2];break;case"A":a=["C"][D](Fa[C](0,[b.x,b.y][D](a.slice(1))));break;case"S":"C"==c||"S"==c?(d=2*b.x-b.bx,e=2*b.y-b.by):(d=b.x,e=b.y),a=["C",d,e][D](a.slice(1));break;case"T":"Q"==c||"T"==c?(b.qx=2*b.x-b.qx,b.qy=2*b.y-b.qy):(b.qx=b.x,b.qy=b.y),a=["C"][D](Ea(b.x,b.y,b.qx,b.qy,a[1],a[2]));break;case"Q":b.qx=a[1],b.qy=a[2],a=["C"][D](Ea(b.x,b.y,a[1],a[2],a[3],a[4]));break;case"L":a=["C"][D](Da(b.x,b.y,a[1],a[2]));break;case"H":a=["C"][D](Da(b.x,b.y,a[1],b.y));break;case"V":a=["C"][D](Da(b.x,b.y,b.x,a[1]));break;case"Z":a=["C"][D](Da(b.x,b.y,b.X,b.Y))} +return a}),i=function(a,b){if(a[b].length>7){a[b].shift();for(var c=a[b];c.length;) +k[b]="A",e&&(l[b]="A"),a.splice(b++,0,["C"][D](c.splice(0,6)));a.splice(b,1),p=N(d.length,e&&e.length||0)}},j=function(a,b,c,f,g){a&&b&&"M"==a[g][0]&&"M"!=b[g][0]&&(b.splice(g,0,["M",f.x,f.y]),c.bx=0,c.by=0,c.x=a[g][1],c.y=a[g][2],p=N(d.length,e&&e.length||0))},k=[],l=[],m="",n="",o=0,p=N(d.length,e&&e.length||0);p>o;o++){d[o]&&(m=d[o][0]),"C"!=m&&(k[o]=m,o&&(n=k[o-1])),d[o]=h(d[o],f,n),"A"!=k[o]&&"C"==m&&(k[o]="C"),i(d,o),e&&(e[o]&&(m=e[o][0]),"C"!=m&&(l[o]=m,o&&(n=l[o-1])),e[o]=h(e[o],g,n),"A"!=l[o]&&"C"==m&&(l[o]="C"),i(e,o)),j(d,e,f,g,o),j(e,d,g,f,o);var q=d[o],r=e&&e[o],s=q.length,t=e&&r.length;f.x=q[s-2],f.y=q[s-1],f.bx=$(q[s-4])||f.x,f.by=$(q[s-3])||f.y,g.bx=e&&($(r[t-4])||g.x),g.by=e&&($(r[t-3])||g.y),g.x=e&&r[t-2],g.y=e&&r[t-1]} +return e||(c.curve=Aa(d)),e?[d,e]:d},null,Aa),Ja=(b._parseDots=e(function(a){for(var c=[],d=0,e=a.length;e>d;d++){var f={},g=a[d].match(/^([^:]*):?([\d\.]*)/);if(f.color=b.getRGB(g[1]),f.color.error) +return null;f.opacity=f.color.opacity,f.color=f.color.hex,g[2]&&(f.offset=g[2]+"%"),c.push(f)} +for(d=1,e=c.length-1;e>d;d++) +if(!c[d].offset){for(var h=$(c[d-1].offset||0),i=0,j=d+1;e>j;j++) +if(c[j].offset){i=c[j].offset;break} +i||(i=100,j=e),i=$(i);for(var k=(i-h)/(j-d+1);j>d;d++) +h+=k,c[d].offset=h+"%"} +return c}),b._tear=function(a,b){a==b.top&&(b.top=a.prev),a==b.bottom&&(b.bottom=a.next),a.next&&(a.next.prev=a.prev),a.prev&&(a.prev.next=a.next)}),Ka=(b._tofront=function(a,b){b.top!==a&&(Ja(a,b),a.next=null,a.prev=b.top,b.top.next=a,b.top=a)},b._toback=function(a,b){b.bottom!==a&&(Ja(a,b),a.next=b.bottom,a.prev=null,b.bottom.prev=a,b.bottom=a)},b._insertafter=function(a,b,c){Ja(a,c),b==c.top&&(c.top=a),b.next&&(b.next.prev=a),a.next=b.next,a.prev=b,b.next=a},b._insertbefore=function(a,b,c){Ja(a,c),b==c.bottom&&(c.bottom=a),b.prev&&(b.prev.next=a),a.prev=b.prev,b.prev=a,a.next=b},b.toMatrix=function(a,b){var c=za(a),d={_:{transform:F},getBBox:function(){return c}};return La(d,b),d.matrix}),La=(b.transformPath=function(a,b){return pa(a,Ka(a,b))},b._extractTransform=function(a,c){if(null==c) +return a._.transform;c=H(c).replace(/\.{3}|\u2026/g,a._.transform||F);var d=b.parseTransformString(c),e=0,f=0,g=0,h=1,i=1,j=a._,k=new n;if(j.transform=d||[],d) +for(var l=0,m=d.length;m>l;l++){var o,p,q,r,s,t=d[l],u=t.length,v=H(t[0]).toLowerCase(),w=t[0]!=v,x=w?k.invert():0;"t"==v&&3==u?w?(o=x.x(0,0),p=x.y(0,0),q=x.x(t[1],t[2]),r=x.y(t[1],t[2]),k.translate(q-o,r-p)):k.translate(t[1],t[2]):"r"==v?2==u?(s=s||a.getBBox(1),k.rotate(t[1],s.x+s.width/2,s.y+s.height/2),e+=t[1]):4==u&&(w?(q=x.x(t[2],t[3]),r=x.y(t[2],t[3]),k.rotate(t[1],q,r)):k.rotate(t[1],t[2],t[3]),e+=t[1]):"s"==v?2==u||3==u?(s=s||a.getBBox(1),k.scale(t[1],t[u-1],s.x+s.width/2,s.y+s.height/2),h*=t[1],i*=t[u-1]):5==u&&(w?(q=x.x(t[3],t[4]),r=x.y(t[3],t[4]),k.scale(t[1],t[2],q,r)):k.scale(t[1],t[2],t[3],t[4]),h*=t[1],i*=t[2]):"m"==v&&7==u&&k.add(t[1],t[2],t[3],t[4],t[5],t[6]),j.dirtyT=1,a.matrix=k} +a.matrix=k,j.sx=h,j.sy=i,j.deg=e,j.dx=f=k.e,j.dy=g=k.f,1==h&&1==i&&!e&&j.bbox?(j.bbox.x+=+f,j.bbox.y+=+g):j.dirtyT=1}),Ma=function(a){var b=a[0];switch(b.toLowerCase()){case"t":return[b,0,0];case"m":return[b,1,0,0,1,0,0];case"r":return 4==a.length?[b,0,a[2],a[3]]:[b,0];case"s":return 5==a.length?[b,1,1,a[3],a[4]]:3==a.length?[b,1,1]:[b,1]}},Na=b._equaliseTransform=function(a,c){c=H(c).replace(/\.{3}|\u2026/g,a),a=b.parseTransformString(a)||[],c=b.parseTransformString(c)||[];for(var d,e,f,g,h=N(a.length,c.length),i=[],j=[],k=0;h>k;k++){if(f=a[k]||Ma(c[k]),g=c[k]||Ma(f),f[0]!=g[0]||"r"==f[0].toLowerCase()&&(f[2]!=g[2]||f[3]!=g[3])||"s"==f[0].toLowerCase()&&(f[3]!=g[3]||f[4]!=g[4])) +return;for(i[k]=[],j[k]=[],d=0,e=N(f.length,g.length);e>d;d++) +d in f&&(i[k][d]=f[d]),d in g&&(j[k][d]=g[d])} +return{from:i,to:j}};b._getContainer=function(a,c,d,e){var f;return f=null!=e||b.is(a,"object")?a:z.doc.getElementById(a),null!=f?f.tagName?null==c?{container:f,width:f.style.pixelWidth||f.offsetWidth,height:f.style.pixelHeight||f.offsetHeight}:{container:f,width:c,height:d}:{container:1,x:a,y:c,width:d,height:e}:void 0},b.pathToRelative=Ba,b._engine={},b.path2curve=Ia,b.matrix=function(a,b,c,d,e,f){return new n(a,b,c,d,e,f)},function(a){function c(a){return a[0]*a[0]+a[1]*a[1]} +function d(a){var b=M.sqrt(c(a));a[0]&&(a[0]/=b),a[1]&&(a[1]/=b)} +a.add=function(a,b,c,d,e,f){var g,h,i,j,k=[[],[],[]],l=[[this.a,this.c,this.e],[this.b,this.d,this.f],[0,0,1]],m=[[a,c,e],[b,d,f],[0,0,1]];for(a&&a instanceof n&&(m=[[a.a,a.c,a.e],[a.b,a.d,a.f],[0,0,1]]),g=0;3>g;g++) +for(h=0;3>h;h++){for(j=0,i=0;3>i;i++) +j+=l[g][i]*m[i][h];k[g][h]=j} +this.a=k[0][0],this.b=k[1][0],this.c=k[0][1],this.d=k[1][1],this.e=k[0][2],this.f=k[1][2]},a.invert=function(){var a=this,b=a.a*a.d-a.b*a.c;return new n(a.d/b,-a.b/b,-a.c/b,a.a/b,(a.c*a.f-a.d*a.e)/b,(a.b*a.e-a.a*a.f)/b)},a.clone=function(){return new n(this.a,this.b,this.c,this.d,this.e,this.f)},a.translate=function(a,b){this.add(1,0,0,1,a,b)},a.scale=function(a,b,c,d){null==b&&(b=a),(c||d)&&this.add(1,0,0,1,c,d),this.add(a,0,0,b,0,0),(c||d)&&this.add(1,0,0,1,-c,-d)},a.rotate=function(a,c,d){a=b.rad(a),c=c||0,d=d||0;var e=+M.cos(a).toFixed(9),f=+M.sin(a).toFixed(9);this.add(e,f,-f,e,c,d),this.add(1,0,0,1,-c,-d)},a.x=function(a,b){return a*this.a+b*this.c+this.e},a.y=function(a,b){return a*this.b+b*this.d+this.f},a.get=function(a){return+this[H.fromCharCode(97+a)].toFixed(4)},a.toString=function(){return b.svg?"matrix("+[this.get(0),this.get(1),this.get(2),this.get(3),this.get(4),this.get(5)].join()+")":[this.get(0),this.get(2),this.get(1),this.get(3),0,0].join()},a.toFilter=function(){return"progid:DXImageTransform.Microsoft.Matrix(M11="+this.get(0)+", M12="+this.get(2)+", M21="+this.get(1)+", M22="+this.get(3)+", Dx="+this.get(4)+", Dy="+this.get(5)+", sizingmethod='auto expand')"},a.offset=function(){return[this.e.toFixed(4),this.f.toFixed(4)]},a.split=function(){var a={};a.dx=this.e,a.dy=this.f;var e=[[this.a,this.c],[this.b,this.d]];a.scalex=M.sqrt(c(e[0])),d(e[0]),a.shear=e[0][0]*e[1][0]+e[0][1]*e[1][1],e[1]=[e[1][0]-e[0][0]*a.shear,e[1][1]-e[0][1]*a.shear],a.scaley=M.sqrt(c(e[1])),d(e[1]),a.shear/=a.scaley;var f=-e[0][1],g=e[1][1];return 0>g?(a.rotate=b.deg(M.acos(g)),0>f&&(a.rotate=360-a.rotate)):a.rotate=b.deg(M.asin(f)),a.isSimple=!(+a.shear.toFixed(9)||a.scalex.toFixed(9)!=a.scaley.toFixed(9)&&a.rotate),a.isSuperSimple=!+a.shear.toFixed(9)&&a.scalex.toFixed(9)==a.scaley.toFixed(9)&&!a.rotate,a.noRotation=!+a.shear.toFixed(9)&&!a.rotate,a},a.toTransformString=function(a){var b=a||this[I]();return b.isSimple?(b.scalex=+b.scalex.toFixed(4),b.scaley=+b.scaley.toFixed(4),b.rotate=+b.rotate.toFixed(4),(b.dx||b.dy?"t"+[b.dx,b.dy]:F)+(1!=b.scalex||1!=b.scaley?"s"+[b.scalex,b.scaley,0,0]:F)+(b.rotate?"r"+[b.rotate,0,0]:F)):"m"+[this.get(0),this.get(1),this.get(2),this.get(3),this.get(4),this.get(5)]}} +(n.prototype);for(var Oa=function(){this.returnValue=!1},Pa=function(){return this.originalEvent.preventDefault()},Qa=function(){this.cancelBubble=!0},Ra=function(){return this.originalEvent.stopPropagation()},Sa=function(a){var b=z.doc.documentElement.scrollTop||z.doc.body.scrollTop,c=z.doc.documentElement.scrollLeft||z.doc.body.scrollLeft;return{x:a.clientX+c,y:a.clientY+b}},Ta=function(){return z.doc.addEventListener?function(a,b,c,d){var e=function(a){var b=Sa(a);return c.call(d,a,b.x,b.y)};if(a.addEventListener(b,e,!1),E&&K[b]){var f=function(b){for(var e=Sa(b),f=b,g=0,h=b.targetTouches&&b.targetTouches.length;h>g;g++) +if(b.targetTouches[g].target==a){b=b.targetTouches[g],b.originalEvent=f,b.preventDefault=Pa,b.stopPropagation=Ra;break} +return c.call(d,b,e.x,e.y)};a.addEventListener(K[b],f,!1)} +return function(){return a.removeEventListener(b,e,!1),E&&K[b]&&a.removeEventListener(K[b],f,!1),!0}}:z.doc.attachEvent?function(a,b,c,d){var e=function(a){a=a||z.win.event;var b=z.doc.documentElement.scrollTop||z.doc.body.scrollTop,e=z.doc.documentElement.scrollLeft||z.doc.body.scrollLeft,f=a.clientX+e,g=a.clientY+b;return a.preventDefault=a.preventDefault||Oa,a.stopPropagation=a.stopPropagation||Qa,c.call(d,a,f,g)};a.attachEvent("on"+b,e);var f=function(){return a.detachEvent("on"+b,e),!0};return f}:void 0} +(),Ua=[],Va=function(b){for(var c,d=b.clientX,e=b.clientY,f=z.doc.documentElement.scrollTop||z.doc.body.scrollTop,g=z.doc.documentElement.scrollLeft||z.doc.body.scrollLeft,h=Ua.length;h--;){if(c=Ua[h],E&&b.touches){for(var i,j=b.touches.length;j--;) +if(i=b.touches[j],i.identifier==c.el._drag.id){d=i.clientX,e=i.clientY,(b.originalEvent?b.originalEvent:b).preventDefault();break}}else +b.preventDefault();var k,l=c.el.node,m=l.nextSibling,n=l.parentNode,o=l.style.display;z.win.opera&&n.removeChild(l),l.style.display="none",k=c.el.paper.getElementByPoint(d,e),l.style.display=o,z.win.opera&&(m?n.insertBefore(l,m):n.appendChild(l)),k&&a("raphael.drag.over."+c.el.id,c.el,k),d+=g,e+=f,a("raphael.drag.move."+c.el.id,c.move_scope||c.el,d-c.el._drag.x,e-c.el._drag.y,d,e,b)}},Wa=function(c){b.unmousemove(Va).unmouseup(Wa);for(var d,e=Ua.length;e--;) +d=Ua[e],d.el._drag={},a("raphael.drag.end."+d.el.id,d.end_scope||d.start_scope||d.move_scope||d.el,c);Ua=[]},Xa=b.el={},Ya=J.length;Ya--;) +!function(a){b[a]=Xa[a]=function(c,d){return b.is(c,"function")&&(this.events=this.events||[],this.events.push({name:a,f:c,unbind:Ta(this.shape||this.node||z.doc,a,c,d||this)})),this},b["un"+a]=Xa["un"+a]=function(c){for(var d=this.events||[],e=d.length;e--;) +d[e].name!=a||!b.is(c,"undefined")&&d[e].f!=c||(d[e].unbind(),d.splice(e,1),!d.length&&delete this.events);return this}} +(J[Ya]);Xa.data=function(c,d){var e=ja[this.id]=ja[this.id]||{};if(0==arguments.length) +return e;if(1==arguments.length){if(b.is(c,"object")){for(var f in c) +c[y](f)&&this.data(f,c[f]);return this} +return a("raphael.data.get."+this.id,this,e[c],c),e[c]} +return e[c]=d,a("raphael.data.set."+this.id,this,d,c),this},Xa.removeData=function(a){return null==a?ja[this.id]={}:ja[this.id]&&delete ja[this.id][a],this},Xa.getData=function(){return c(ja[this.id]||{})},Xa.hover=function(a,b,c,d){return this.mouseover(a,c).mouseout(b,d||c)},Xa.unhover=function(a,b){return this.unmouseover(a).unmouseout(b)};var Za=[];Xa.drag=function(c,d,e,f,g,h){function i(i){(i.originalEvent||i).preventDefault();var j=i.clientX,k=i.clientY,l=z.doc.documentElement.scrollTop||z.doc.body.scrollTop,m=z.doc.documentElement.scrollLeft||z.doc.body.scrollLeft;if(this._drag.id=i.identifier,E&&i.touches) +for(var n,o=i.touches.length;o--;) +if(n=i.touches[o],this._drag.id=n.identifier,n.identifier==this._drag.id){j=n.clientX,k=n.clientY;break} +this._drag.x=j+m,this._drag.y=k+l,!Ua.length&&b.mousemove(Va).mouseup(Wa),Ua.push({el:this,move_scope:f,start_scope:g,end_scope:h}),d&&a.on("raphael.drag.start."+this.id,d),c&&a.on("raphael.drag.move."+this.id,c),e&&a.on("raphael.drag.end."+this.id,e),a("raphael.drag.start."+this.id,g||f||this,i.clientX+m,i.clientY+l,i)} +return this._drag={},Za.push({el:this,start:i}),this.mousedown(i),this},Xa.onDragOver=function(b){b?a.on("raphael.drag.over."+this.id,b):a.unbind("raphael.drag.over."+this.id)},Xa.undrag=function(){for(var c=Za.length;c--;) +Za[c].el==this&&(this.unmousedown(Za[c].start),Za.splice(c,1),a.unbind("raphael.drag.*."+this.id));!Za.length&&b.unmousemove(Va).unmouseup(Wa),Ua=[]},u.circle=function(a,c,d){var e=b._engine.circle(this,a||0,c||0,d||0);return this.__set__&&this.__set__.push(e),e},u.rect=function(a,c,d,e,f){var g=b._engine.rect(this,a||0,c||0,d||0,e||0,f||0);return this.__set__&&this.__set__.push(g),g},u.ellipse=function(a,c,d,e){var f=b._engine.ellipse(this,a||0,c||0,d||0,e||0);return this.__set__&&this.__set__.push(f),f},u.path=function(a){a&&!b.is(a,T)&&!b.is(a[0],U)&&(a+=F);var c=b._engine.path(b.format[C](b,arguments),this);return this.__set__&&this.__set__.push(c),c},u.image=function(a,c,d,e,f){var g=b._engine.image(this,a||"about:blank",c||0,d||0,e||0,f||0);return this.__set__&&this.__set__.push(g),g},u.text=function(a,c,d){var e=b._engine.text(this,a||0,c||0,H(d));return this.__set__&&this.__set__.push(e),e},u.set=function(a){!b.is(a,"array")&&(a=Array.prototype.splice.call(arguments,0,arguments.length));var c=new jb(a);return this.__set__&&this.__set__.push(c),c.paper=this,c.type="set",c},u.setStart=function(a){this.__set__=a||this.set()},u.setFinish=function(a){var b=this.__set__;return delete this.__set__,b},u.getSize=function(){var a=this.canvas.parentNode;return{width:a.offsetWidth,height:a.offsetHeight}},u.setSize=function(a,c){return b._engine.setSize.call(this,a,c)},u.setViewBox=function(a,c,d,e,f){return b._engine.setViewBox.call(this,a,c,d,e,f)},u.top=u.bottom=null,u.raphael=b;var $a=function(a){var b=a.getBoundingClientRect(),c=a.ownerDocument,d=c.body,e=c.documentElement,f=e.clientTop||d.clientTop||0,g=e.clientLeft||d.clientLeft||0,h=b.top+(z.win.pageYOffset||e.scrollTop||d.scrollTop)-f,i=b.left+(z.win.pageXOffset||e.scrollLeft||d.scrollLeft)-g;return{y:h,x:i}};u.getElementByPoint=function(a,b){var c=this,d=c.canvas,e=z.doc.elementFromPoint(a,b);if(z.win.opera&&"svg"==e.tagName){var f=$a(d),g=d.createSVGRect();g.x=a-f.x,g.y=b-f.y,g.width=g.height=1;var h=d.getIntersectionList(g,null);h.length&&(e=h[h.length-1])} +if(!e) +return null;for(;e.parentNode&&e!=d.parentNode&&!e.raphael;) +e=e.parentNode;return e==c.canvas.parentNode&&(e=d),e=e&&e.raphael?c.getById(e.raphaelid):null},u.getElementsByBBox=function(a){var c=this.set();return this.forEach(function(d){b.isBBoxIntersect(d.getBBox(),a)&&c.push(d)}),c},u.getById=function(a){for(var b=this.bottom;b;){if(b.id==a) +return b;b=b.next} +return null},u.forEach=function(a,b){for(var c=this.bottom;c;){if(a.call(b,c)===!1) +return this;c=c.next} +return this},u.getElementsByPoint=function(a,b){var c=this.set();return this.forEach(function(d){d.isPointInside(a,b)&&c.push(d)}),c},Xa.isPointInside=function(a,c){var d=this.realPath=oa[this.type](this);return this.attr("transform")&&this.attr("transform").length&&(d=b.transformPath(d,this.attr("transform"))),b.isPointInsidePath(d,a,c)},Xa.getBBox=function(a){if(this.removed) +return{};var b=this._;return a?((b.dirty||!b.bboxwt)&&(this.realPath=oa[this.type](this),b.bboxwt=za(this.realPath),b.bboxwt.toString=o,b.dirty=0),b.bboxwt):((b.dirty||b.dirtyT||!b.bbox)&&((b.dirty||!this.realPath)&&(b.bboxwt=0,this.realPath=oa[this.type](this)),b.bbox=za(pa(this.realPath,this.matrix)),b.bbox.toString=o,b.dirty=b.dirtyT=0),b.bbox)},Xa.clone=function(){if(this.removed) +return null;var a=this.paper[this.type]().attr(this.attr());return this.__set__&&this.__set__.push(a),a},Xa.glow=function(a){if("text"==this.type) +return null;a=a||{};var b={width:(a.width||10)+(+this.attr("stroke-width")||1),fill:a.fill||!1,opacity:null==a.opacity?.5:a.opacity,offsetx:a.offsetx||0,offsety:a.offsety||0,color:a.color||"#000"},c=b.width/2,d=this.paper,e=d.set(),f=this.realPath||oa[this.type](this);f=this.matrix?pa(f,this.matrix):f;for(var g=1;c+1>g;g++) +e.push(d.path(f).attr({stroke:b.color,fill:b.fill?b.color:"none","stroke-linejoin":"round","stroke-linecap":"round","stroke-width":+(b.width/c*g).toFixed(3),opacity:+(b.opacity/c).toFixed(3)}));return e.insertBefore(this).translate(b.offsetx,b.offsety)};var _a=function(a,c,d,e,f,g,h,k,l){return null==l?i(a,c,d,e,f,g,h,k):b.findDotsAtSegment(a,c,d,e,f,g,h,k,j(a,c,d,e,f,g,h,k,l))},ab=function(a,c){return function(d,e,f){d=Ia(d);for(var g,h,i,j,k,l="",m={},n=0,o=0,p=d.length;p>o;o++){if(i=d[o],"M"==i[0]) +g=+i[1],h=+i[2];else{if(j=_a(g,h,i[1],i[2],i[3],i[4],i[5],i[6]),n+j>e){if(c&&!m.start){if(k=_a(g,h,i[1],i[2],i[3],i[4],i[5],i[6],e-n),l+=["C"+k.start.x,k.start.y,k.m.x,k.m.y,k.x,k.y],f) +return l;m.start=l,l=["M"+k.x,k.y+"C"+k.n.x,k.n.y,k.end.x,k.end.y,i[5],i[6]].join(),n+=j,g=+i[5],h=+i[6];continue} +if(!a&&!c) +return k=_a(g,h,i[1],i[2],i[3],i[4],i[5],i[6],e-n),{x:k.x,y:k.y,alpha:k.alpha}} +n+=j,g=+i[5],h=+i[6]} +l+=i.shift()+i} +return m.end=l,k=a?n:c?m:b.findDotsAtSegment(g,h,i[0],i[1],i[2],i[3],i[4],i[5],1),k.alpha&&(k={x:k.x,y:k.y,alpha:k.alpha}),k}},bb=ab(1),cb=ab(),db=ab(0,1);b.getTotalLength=bb,b.getPointAtLength=cb,b.getSubpath=function(a,b,c){if(this.getTotalLength(a)-c<1e-6) +return db(a,b).end;var d=db(a,c,1);return b?db(d,b).end:d},Xa.getTotalLength=function(){var a=this.getPath();if(a) +return this.node.getTotalLength?this.node.getTotalLength():bb(a)},Xa.getPointAtLength=function(a){var b=this.getPath();if(b) +return cb(b,a)},Xa.getPath=function(){var a,c=b._getPath[this.type];if("text"!=this.type&&"set"!=this.type) +return c&&(a=c(this)),a},Xa.getSubpath=function(a,c){var d=this.getPath();if(d) +return b.getSubpath(d,a,c)};var eb=b.easing_formulas={linear:function(a){return a},"<":function(a){return Q(a,1.7)},">":function(a){return Q(a,.48)},"<>":function(a){var b=.48-a/1.04,c=M.sqrt(.1734+b*b),d=c-b,e=Q(P(d),1/3)*(0>d?-1:1),f=-c-b,g=Q(P(f),1/3)*(0>f?-1:1),h=e+g+.5;return 3*(1-h)*h*h+h*h*h},backIn:function(a){var b=1.70158;return a*a*((b+1)*a-b)},backOut:function(a){a-=1;var b=1.70158;return a*a*((b+1)*a+b)+1},elastic:function(a){return a==!!a?a:Q(2,-10*a)*M.sin(2*(a-.075)*R/.3)+1},bounce:function(a){var b,c=7.5625,d=2.75;return 1/d>a?b=c*a*a:2/d>a?(a-=1.5/d,b=c*a*a+.75):2.5/d>a?(a-=2.25/d,b=c*a*a+.9375):(a-=2.625/d,b=c*a*a+.984375),b}};eb.easeIn=eb["ease-in"]=eb["<"],eb.easeOut=eb["ease-out"]=eb[">"],eb.easeInOut=eb["ease-in-out"]=eb["<>"],eb["back-in"]=eb.backIn,eb["back-out"]=eb.backOut;var fb=[],gb=window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(a){setTimeout(a,16)},hb=function(){for(var c=+new Date,d=0;dh)) +if(i>h){var q=j(h/i);for(var s in k) +if(k[y](s)){switch(ca[s]){case S:f=+k[s]+q*i*l[s];break;case"colour":f="rgb("+[ib(Z(k[s].r+q*i*l[s].r)),ib(Z(k[s].g+q*i*l[s].g)),ib(Z(k[s].b+q*i*l[s].b))].join(",")+")";break;case"path":f=[];for(var t=0,u=k[s].length;u>t;t++){f[t]=[k[s][t][0]];for(var v=1,w=k[s][t].length;w>v;v++) +f[t][v]=+k[s][t][v]+q*i*l[s][t][v];f[t]=f[t].join(G)} +f=f.join(G);break;case"transform":if(l[s].real) +for(f=[],t=0,u=k[s].length;u>t;t++) +for(f[t]=[k[s][t][0]],v=1,w=k[s][t].length;w>v;v++) +f[t][v]=k[s][t][v]+q*i*l[s][t][v];else{var x=function(a){return+k[s][a]+q*i*l[s][a]};f=[["m",x(0),x(1),x(2),x(3),x(4),x(5)]]} +break;case"csv":if("clip-rect"==s) +for(f=[],t=4;t--;) +f[t]=+k[s][t]+q*i*l[s][t];break;default:var z=[][D](k[s]);for(f=[],t=n.paper.customAttributes[s].length;t--;) +f[t]=+z[t]+q*i*l[s][t]} +o[s]=f} +n.attr(o),function(b,c,d){setTimeout(function(){a("raphael.anim.frame."+b,c,d)})} +(n.id,n,e.anim)}else{if(function(c,d,e){setTimeout(function(){a("raphael.anim.frame."+d.id,d,e),a("raphael.anim.finish."+d.id,d,e),b.is(c,"function")&&c.call(d)})} +(e.callback,n,e.anim),n.attr(m),fb.splice(d--,1),e.repeat>1&&!e.next){for(g in m) +m[y](g)&&(p[g]=e.totalOrigin[g]);e.el.attr(p),r(e.anim,e.el,e.anim.percents[0],null,e.totalOrigin,e.repeat-1)} +e.next&&!e.stop&&r(e.anim,e.el,e.next,null,e.totalOrigin,e.repeat)}}} +fb.length&&gb(hb)},ib=function(a){return a>255?255:0>a?0:a};Xa.animateWith=function(a,c,d,e,f,g){var h=this;if(h.removed) +return g&&g.call(h),h;var i=d instanceof q?d:b.animation(d,e,f,g);r(i,h,i.percents[0],null,h.attr());for(var j=0,k=fb.length;k>j;j++) +if(fb[j].anim==c&&fb[j].el==a){fb[k-1].start=fb[j].start;break} +return h},Xa.onAnimation=function(b){return b?a.on("raphael.anim.frame."+this.id,b):a.unbind("raphael.anim.frame."+this.id),this},q.prototype.delay=function(a){var b=new q(this.anim,this.ms);return b.times=this.times,b.del=+a||0,b},q.prototype.repeat=function(a){var b=new q(this.anim,this.ms);return b.del=this.del,b.times=M.floor(N(a,0))||1,b},b.animation=function(a,c,d,e){if(a instanceof q) +return a;(b.is(d,"function")||!d)&&(e=e||d||null,d=null),a=Object(a),c=+c||0;var f,g,h={};for(g in a) +a[y](g)&&$(g)!=g&&$(g)+"%"!=g&&(f=!0,h[g]=a[g]);if(f) +return d&&(h.easing=d),e&&(h.callback=e),new q({100:h},c);if(e){var i=0;for(var j in a){var k=_(j);a[y](j)&&k>i&&(i=k)} +i+="%",!a[i].callback&&(a[i].callback=e)} +return new q(a,c)},Xa.animate=function(a,c,d,e){var f=this;if(f.removed) +return e&&e.call(f),f;var g=a instanceof q?a:b.animation(a,c,d,e);return r(g,f,g.percents[0],null,f.attr()),f},Xa.setTime=function(a,b){return a&&null!=b&&this.status(a,O(b,a.ms)/a.ms),this},Xa.status=function(a,b){var c,d,e=[],f=0;if(null!=b) +return r(a,this,-1,O(b,1)),this;for(c=fb.length;c>f;f++) +if(d=fb[f],d.el.id==this.id&&(!a||d.anim==a)){if(a) +return d.status;e.push({anim:d.anim,status:d.status})} +return a?0:e},Xa.pause=function(b){for(var c=0;cb;b++) +!a[b]||a[b].constructor!=Xa.constructor&&a[b].constructor!=jb||(this[this.items.length]=this.items[this.items.length]=a[b],this.length++)},kb=jb.prototype;kb.push=function(){for(var a,b,c=0,d=arguments.length;d>c;c++) +a=arguments[c],!a||a.constructor!=Xa.constructor&&a.constructor!=jb||(b=this.items.length,this[b]=this.items[b]=a,this.length++);return this},kb.pop=function(){return this.length&&delete this[this.length--],this.items.pop()},kb.forEach=function(a,b){for(var c=0,d=this.items.length;d>c;c++) +if(a.call(b,this.items[c],c)===!1) +return this;return this};for(var lb in Xa) +Xa[y](lb)&&(kb[lb]=function(a){return function(){var b=arguments;return this.forEach(function(c){c[a][C](c,b)})}} +(lb));return kb.attr=function(a,c){if(a&&b.is(a,U)&&b.is(a[0],"object")) +for(var d=0,e=a.length;e>d;d++) +this.items[d].attr(a[d]);else +for(var f=0,g=this.items.length;g>f;f++) +this.items[f].attr(a,c);return this},kb.clear=function(){for(;this.length;) +this.pop()},kb.splice=function(a,b,c){a=0>a?N(this.length+a,0):a,b=N(0,O(this.length-a,b));var d,e=[],f=[],g=[];for(d=2;dd;d++) +f.push(this[a+d]);for(;dd?g[d]:e[d-h];for(d=this.items.length=this.length-=b-h;this[d];) +delete this[d++];return new jb(f)},kb.exclude=function(a){for(var b=0,c=this.length;c>b;b++) +if(this[b]==a) +return this.splice(b,1),!0},kb.animate=function(a,c,d,e){(b.is(d,"function")||!d)&&(e=d||null);var f,g,h=this.items.length,i=h,j=this;if(!h) +return this;e&&(g=function(){!--h&&e.call(j)}),d=b.is(d,T)?d:g;var k=b.animation(a,c,d,g);for(f=this.items[--i].animate(k);i--;) +this.items[i]&&!this.items[i].removed&&this.items[i].animateWith(f,k,k),this.items[i]&&!this.items[i].removed||h--;return this},kb.insertAfter=function(a){for(var b=this.items.length;b--;) +this.items[b].insertAfter(a);return this},kb.getBBox=function(){for(var a=[],b=[],c=[],d=[],e=this.items.length;e--;) +if(!this.items[e].removed){var f=this.items[e].getBBox();a.push(f.x),b.push(f.y),c.push(f.x+f.width),d.push(f.y+f.height)} +return a=O[C](0,a),b=O[C](0,b),c=N[C](0,c),d=N[C](0,d),{x:a,y:b,x2:c,y2:d,width:c-a,height:d-b}},kb.clone=function(a){a=this.paper.set();for(var b=0,c=this.items.length;c>b;b++) +a.push(this.items[b].clone());return a},kb.toString=function(){return"Raphaël‘s set"},kb.glow=function(a){var b=this.paper.set();return this.forEach(function(c,d){var e=c.glow(a);null!=e&&e.forEach(function(a,c){b.push(a)})}),b},kb.isPointInside=function(a,b){var c=!1;return this.forEach(function(d){return d.isPointInside(a,b)?(c=!0,!1):void 0}),c},b.registerFont=function(a){if(!a.face) +return a;this.fonts=this.fonts||{};var b={w:a.w,face:{},glyphs:{}},c=a.face["font-family"];for(var d in a.face) +a.face[y](d)&&(b.face[d]=a.face[d]);if(this.fonts[c]?this.fonts[c].push(b):this.fonts[c]=[b],!a.svg){b.face["units-per-em"]=_(a.face["units-per-em"],10);for(var e in a.glyphs) +if(a.glyphs[y](e)){var f=a.glyphs[e];if(b.glyphs[e]={w:f.w,k:{},d:f.d&&"M"+f.d.replace(/[mlcxtrv]/g,function(a){return{l:"L",c:"C",x:"z",t:"m",r:"l",v:"c"} +[a]||"M"})+"z"},f.k) +for(var g in f.k) +f[y](g)&&(b.glyphs[e].k[g]=f.k[g])}} +return a},u.getFont=function(a,c,d,e){if(e=e||"normal",d=d||"normal",c=+c||{normal:400,bold:700,lighter:300,bolder:800} +[c]||400,b.fonts){var f=b.fonts[a];if(!f){var g=new RegExp("(^|\\s)"+a.replace(/[^\w\d\s+!~.:_-]/g,F)+"(\\s|$)","i");for(var h in b.fonts) +if(b.fonts[y](h)&&g.test(h)){f=b.fonts[h];break}} +var i;if(f) +for(var j=0,k=f.length;k>j&&(i=f[j],i.face["font-weight"]!=c||i.face["font-style"]!=d&&i.face["font-style"]||i.face["font-stretch"]!=e);j++);return i}},u.print=function(a,c,d,e,f,g,h,i){g=g||"middle",h=N(O(h||0,1),-1),i=N(O(i||1,3),1);var j,k=H(d)[I](F),l=0,m=0,n=F;if(b.is(e,"string")&&(e=this.getFont(e)),e){j=(f||16)/e.face["units-per-em"];for(var o=e.face.bbox[I](v),p=+o[0],q=o[3]-o[1],r=0,s=+o[1]+("baseline"==g?q+ +e.face.descent:q/2),t=0,u=k.length;u>t;t++){if("\n"==k[t]) +l=0,x=0,m=0,r+=q*i;else{var w=m&&e.glyphs[k[t-1]]||{},x=e.glyphs[k[t]];l+=m?(w.w||e.w)+(w.k&&w.k[k[t]]||0)+e.w*h:0,m=1} +x&&x.d&&(n+=b.transformPath(x.d,["t",l*j,r*j,"s",j,j,p,s,"t",(a-p)/j,(c-s)/j]))}} +return this.path(n).attr({fill:"#000",stroke:"none"})},u.add=function(a){if(b.is(a,"array")) +for(var c,d=this.set(),e=0,f=a.length;f>e;e++) +c=a[e]||{},w[y](c.type)&&d.push(this[c.type]().attr(c));return d},b.format=function(a,c){var d=b.is(c,U)?[0][D](c):arguments;return a&&b.is(a,T)&&d.length-1&&(a=a.replace(x,function(a,b){return null==d[++b]?F:d[b]})),a||F},b.fullfill=function(){var a=/\{([^\}]+)\}/g,b=/(?:(?:^|\.)(.+?)(?=\[|\.|$|\()|\[('|")(.+?)\2\])(\(\))?/g,c=function(a,c,d){var e=d;return c.replace(b,function(a,b,c,d,f){b=b||d,e&&(b in e&&(e=e[b]),"function"==typeof e&&f&&(e=e()))}),e=(null==e||e==d?a:e)+""};return function(b,d){return String(b).replace(a,function(a,b){return c(a,b,d)})}} +(),b.ninja=function(){return A.was?z.win.Raphael=A.is:delete Raphael,b},b.st=kb,a.on("raphael.DOMload",function(){t=!0}),function(a,c,d){function e(){/in/.test(a.readyState)?setTimeout(e,9):b.eve("raphael.DOMload")} +null==a.readyState&&a.addEventListener&&(a.addEventListener(c,d=function(){a.removeEventListener(c,d,!1),a.readyState="complete"},!1),a.readyState="loading"),e()} +(document,"DOMContentLoaded"),b}),function(a,b){"function"==typeof define&&define.amd?define("raphael.svg",["raphael.core"],function(a){return b(a)}):b("object"==typeof exports?require("./raphael.core"):a.Raphael)} +(this,function(a){if(!a||a.svg){var b="hasOwnProperty",c=String,d=parseFloat,e=parseInt,f=Math,g=f.max,h=f.abs,i=f.pow,j=/[, ]+/,k=a.eve,l="",m=" ",n="http://www.w3.org/1999/xlink",o={block:"M5,0 0,2.5 5,5z",classic:"M5,0 0,2.5 5,5 3.5,3 3.5,2z",diamond:"M2.5,0 5,2.5 2.5,5 0,2.5z",open:"M6,1 1,3.5 6,6",oval:"M2.5,0A2.5,2.5,0,0,1,2.5,5 2.5,2.5,0,0,1,2.5,0z"},p={};a.toString=function(){return"Your browser supports SVG.\nYou are running Raphaël "+this.version};var q=function(d,e){if(e){"string"==typeof d&&(d=q(d));for(var f in e) +e[b](f)&&("xlink:"==f.substring(0,6)?d.setAttributeNS(n,f.substring(6),c(e[f])):d.setAttribute(f,c(e[f])))}else +d=a._g.doc.createElementNS("http://www.w3.org/2000/svg",d),d.style&&(d.style.webkitTapHighlightColor="rgba(0,0,0,0)");return d},r=function(b,e){var j="linear",k=b.id+e,m=.5,n=.5,o=b.node,p=b.paper,r=o.style,s=a._g.doc.getElementById(k);if(!s){if(e=c(e).replace(a._radial_gradient,function(a,b,c){if(j="radial",b&&c){m=d(b),n=d(c);var e=2*(n>.5)-1;i(m-.5,2)+i(n-.5,2)>.25&&(n=f.sqrt(.25-i(m-.5,2))*e+.5)&&.5!=n&&(n=n.toFixed(5)-1e-5*e)} +return l}),e=e.split(/\s*\-\s*/),"linear"==j){var t=e.shift();if(t=-d(t),isNaN(t)) +return null;var u=[0,0,f.cos(a.rad(t)),f.sin(a.rad(t))],v=1/(g(h(u[2]),h(u[3]))||1);u[2]*=v,u[3]*=v,u[2]<0&&(u[0]=-u[2],u[2]=0),u[3]<0&&(u[1]=-u[3],u[3]=0)} +var w=a._parseDots(e);if(!w) +return null;if(k=k.replace(/[\(\)\s,\xb0#]/g,"_"),b.gradient&&k!=b.gradient.id&&(p.defs.removeChild(b.gradient),delete b.gradient),!b.gradient){s=q(j+"Gradient",{id:k}),b.gradient=s,q(s,"radial"==j?{fx:m,fy:n}:{x1:u[0],y1:u[1],x2:u[2],y2:u[3],gradientTransform:b.matrix.invert()}),p.defs.appendChild(s);for(var x=0,y=w.length;y>x;x++) +s.appendChild(q("stop",{offset:w[x].offset?w[x].offset:x?"100%":"0%","stop-color":w[x].color||"#fff","stop-opacity":isFinite(w[x].opacity)?w[x].opacity:1}))}} +return q(o,{fill:"url('"+document.location.origin+document.location.pathname+"#"+k+"')",opacity:1,"fill-opacity":1}),r.fill=l,r.opacity=1,r.fillOpacity=1,1},s=function(a){var b=a.getBBox(1);q(a.pattern,{patternTransform:a.matrix.invert()+" translate("+b.x+","+b.y+")"})},t=function(d,e,f){if("path"==d.type){for(var g,h,i,j,k,m=c(e).toLowerCase().split("-"),n=d.paper,r=f?"end":"start",s=d.node,t=d.attrs,u=t["stroke-width"],v=m.length,w="classic",x=3,y=3,z=5;v--;) +switch(m[v]){case"block":case"classic":case"oval":case"diamond":case"open":case"none":w=m[v];break;case"wide":y=5;break;case"narrow":y=2;break;case"long":x=5;break;case"short":x=2} +if("open"==w?(x+=2,y+=2,z+=2,i=1,j=f?4:1,k={fill:"none",stroke:t.stroke}):(j=i=x/2,k={fill:t.stroke,stroke:"none"}),d._.arrows?f?(d._.arrows.endPath&&p[d._.arrows.endPath]--,d._.arrows.endMarker&&p[d._.arrows.endMarker]--):(d._.arrows.startPath&&p[d._.arrows.startPath]--,d._.arrows.startMarker&&p[d._.arrows.startMarker]--):d._.arrows={},"none"!=w){var A="raphael-marker-"+w,B="raphael-marker-"+r+w+x+y+"-obj"+d.id;a._g.doc.getElementById(A)?p[A]++:(n.defs.appendChild(q(q("path"),{"stroke-linecap":"round",d:o[w],id:A})),p[A]=1);var C,D=a._g.doc.getElementById(B);D?(p[B]++,C=D.getElementsByTagName("use")[0]):(D=q(q("marker"),{id:B,markerHeight:y,markerWidth:x,orient:"auto",refX:j,refY:y/2}),C=q(q("use"),{"xlink:href":"#"+A,transform:(f?"rotate(180 "+x/2+" "+y/2+") ":l)+"scale("+x/z+","+y/z+")","stroke-width":(1/((x/z+y/z)/2)).toFixed(4)}),D.appendChild(C),n.defs.appendChild(D),p[B]=1),q(C,k);var E=i*("diamond"!=w&&"oval"!=w);f?(g=d._.arrows.startdx*u||0,h=a.getTotalLength(t.path)-E*u):(g=E*u,h=a.getTotalLength(t.path)-(d._.arrows.enddx*u||0)),k={},k["marker-"+r]="url(#"+B+")",(h||g)&&(k.d=a.getSubpath(t.path,g,h)),q(s,k),d._.arrows[r+"Path"]=A,d._.arrows[r+"Marker"]=B,d._.arrows[r+"dx"]=E,d._.arrows[r+"Type"]=w,d._.arrows[r+"String"]=e}else +f?(g=d._.arrows.startdx*u||0,h=a.getTotalLength(t.path)-g):(g=0,h=a.getTotalLength(t.path)-(d._.arrows.enddx*u||0)),d._.arrows[r+"Path"]&&q(s,{d:a.getSubpath(t.path,g,h)}),delete d._.arrows[r+"Path"],delete d._.arrows[r+"Marker"],delete d._.arrows[r+"dx"],delete d._.arrows[r+"Type"],delete d._.arrows[r+"String"];for(k in p) +if(p[b](k)&&!p[k]){var F=a._g.doc.getElementById(k);F&&F.parentNode.removeChild(F)}}},u={"-":[3,1],".":[1,1],"-.":[3,1,1,1],"-..":[3,1,1,1,1,1],". ":[1,3],"- ":[4,3],"--":[8,3],"- .":[4,3,1,3],"--.":[8,3,1,3],"--..":[8,3,1,3,1,3]},v=function(a,b,d){if(b=u[c(b).toLowerCase()]){for(var e=a.attrs["stroke-width"]||"1",f={round:e,square:e,butt:0} +[a.attrs["stroke-linecap"]||d["stroke-linecap"]]||0,g=[],h=b.length;h--;) +g[h]=b[h]*e+(h%2?1:-1)*f;q(a.node,{"stroke-dasharray":g.join(",")})}else +q(a.node,{"stroke-dasharray":"none"})},w=function(d,f){var i=d.node,k=d.attrs,m=i.style.visibility;i.style.visibility="hidden";for(var o in f) +if(f[b](o)){if(!a._availableAttrs[b](o)) +continue;var p=f[o];switch(k[o]=p,o){case"blur":d.blur(p);break;case"title":var u=i.getElementsByTagName("title");if(u.length&&(u=u[0])) +u.firstChild.nodeValue=p;else{u=q("title");var w=a._g.doc.createTextNode(p);u.appendChild(w),i.appendChild(u)} +break;case"href":case"target":var x=i.parentNode;if("a"!=x.tagName.toLowerCase()){var z=q("a");x.insertBefore(z,i),z.appendChild(i),x=z}"target"==o?x.setAttributeNS(n,"show","blank"==p?"new":p):x.setAttributeNS(n,o,p);break;case"cursor":i.style.cursor=p;break;case"transform":d.transform(p);break;case"arrow-start":t(d,p);break;case"arrow-end":t(d,p,1);break;case"clip-rect":var A=c(p).split(j);if(4==A.length){d.clip&&d.clip.parentNode.parentNode.removeChild(d.clip.parentNode);var B=q("clipPath"),C=q("rect");B.id=a.createUUID(),q(C,{x:A[0],y:A[1],width:A[2],height:A[3]}),B.appendChild(C),d.paper.defs.appendChild(B),q(i,{"clip-path":"url(#"+B.id+")"}),d.clip=C} +if(!p){var D=i.getAttribute("clip-path");if(D){var E=a._g.doc.getElementById(D.replace(/(^url\(#|\)$)/g,l));E&&E.parentNode.removeChild(E),q(i,{"clip-path":l}),delete d.clip}} +break;case"path":"path"==d.type&&(q(i,{d:p?k.path=a._pathToAbsolute(p):"M0,0"}),d._.dirty=1,d._.arrows&&("startString"in d._.arrows&&t(d,d._.arrows.startString),"endString"in d._.arrows&&t(d,d._.arrows.endString,1)));break;case"width":if(i.setAttribute(o,p),d._.dirty=1,!k.fx) +break;o="x",p=k.x;case"x":k.fx&&(p=-k.x-(k.width||0));case"rx":if("rx"==o&&"rect"==d.type) +break;case"cx":i.setAttribute(o,p),d.pattern&&s(d),d._.dirty=1;break;case"height":if(i.setAttribute(o,p),d._.dirty=1,!k.fy) +break;o="y",p=k.y;case"y":k.fy&&(p=-k.y-(k.height||0));case"ry":if("ry"==o&&"rect"==d.type) +break;case"cy":i.setAttribute(o,p),d.pattern&&s(d),d._.dirty=1;break;case"r":"rect"==d.type?q(i,{rx:p,ry:p}):i.setAttribute(o,p),d._.dirty=1;break;case"src":"image"==d.type&&i.setAttributeNS(n,"href",p);break;case"stroke-width":(1!=d._.sx||1!=d._.sy)&&(p/=g(h(d._.sx),h(d._.sy))||1),i.setAttribute(o,p),k["stroke-dasharray"]&&v(d,k["stroke-dasharray"],f),d._.arrows&&("startString"in d._.arrows&&t(d,d._.arrows.startString),"endString"in d._.arrows&&t(d,d._.arrows.endString,1));break;case"stroke-dasharray":v(d,p,f);break;case"fill":var F=c(p).match(a._ISURL);if(F){B=q("pattern");var G=q("image");B.id=a.createUUID(),q(B,{x:0,y:0,patternUnits:"userSpaceOnUse",height:1,width:1}),q(G,{x:0,y:0,"xlink:href":F[1]}),B.appendChild(G),function(b){a._preload(F[1],function(){var a=this.offsetWidth,c=this.offsetHeight;q(b,{width:a,height:c}),q(G,{width:a,height:c})})} +(B),d.paper.defs.appendChild(B),q(i,{fill:"url(#"+B.id+")"}),d.pattern=B,d.pattern&&s(d);break} +var H=a.getRGB(p);if(H.error){if(("circle"==d.type||"ellipse"==d.type||"r"!=c(p).charAt())&&r(d,p)){if("opacity"in k||"fill-opacity"in k){var I=a._g.doc.getElementById(i.getAttribute("fill").replace(/^url\(#|\)$/g,l));if(I){var J=I.getElementsByTagName("stop");q(J[J.length-1],{"stop-opacity":("opacity"in k?k.opacity:1)*("fill-opacity"in k?k["fill-opacity"]:1)})}} +k.gradient=p,k.fill="none";break}}else +delete f.gradient,delete k.gradient,!a.is(k.opacity,"undefined")&&a.is(f.opacity,"undefined")&&q(i,{opacity:k.opacity}),!a.is(k["fill-opacity"],"undefined")&&a.is(f["fill-opacity"],"undefined")&&q(i,{"fill-opacity":k["fill-opacity"]});H[b]("opacity")&&q(i,{"fill-opacity":H.opacity>1?H.opacity/100:H.opacity});case"stroke":H=a.getRGB(p),i.setAttribute(o,H.hex),"stroke"==o&&H[b]("opacity")&&q(i,{"stroke-opacity":H.opacity>1?H.opacity/100:H.opacity}),"stroke"==o&&d._.arrows&&("startString"in d._.arrows&&t(d,d._.arrows.startString),"endString"in d._.arrows&&t(d,d._.arrows.endString,1));break;case"gradient":("circle"==d.type||"ellipse"==d.type||"r"!=c(p).charAt())&&r(d,p);break;case"opacity":k.gradient&&!k[b]("stroke-opacity")&&q(i,{"stroke-opacity":p>1?p/100:p});case"fill-opacity":if(k.gradient){I=a._g.doc.getElementById(i.getAttribute("fill").replace(/^url\(#|\)$/g,l)),I&&(J=I.getElementsByTagName("stop"),q(J[J.length-1],{"stop-opacity":p}));break} +default:"font-size"==o&&(p=e(p,10)+"px");var K=o.replace(/(\-.)/g,function(a){return a.substring(1).toUpperCase()});i.style[K]=p,d._.dirty=1,i.setAttribute(o,p)}} +y(d,f),i.style.visibility=m},x=1.2,y=function(d,f){if("text"==d.type&&(f[b]("text")||f[b]("font")||f[b]("font-size")||f[b]("x")||f[b]("y"))){var g=d.attrs,h=d.node,i=h.firstChild?e(a._g.doc.defaultView.getComputedStyle(h.firstChild,l).getPropertyValue("font-size"),10):10;if(f[b]("text")){for(g.text=f.text;h.firstChild;) +h.removeChild(h.firstChild);for(var j,k=c(f.text).split("\n"),m=[],n=0,o=k.length;o>n;n++) +j=q("tspan"),n&&q(j,{dy:i*x,x:g.x}),j.appendChild(a._g.doc.createTextNode(k[n])),h.appendChild(j),m[n]=j}else +for(m=h.getElementsByTagName("tspan"),n=0,o=m.length;o>n;n++) +n?q(m[n],{dy:i*x,x:g.x}):q(m[0],{dy:0});q(h,{x:g.x,y:g.y}),d._.dirty=1;var p=d._getBBox(),r=g.y-(p.y+p.height/2);r&&a.is(r,"finite")&&q(m[0],{dy:r})}},z=function(a){return a.parentNode&&"a"===a.parentNode.tagName.toLowerCase()?a.parentNode:a},A=function(b,c){this[0]=this.node=b,b.raphael=!0,this.id=a._oid++,b.raphaelid=this.id,this.matrix=a.matrix(),this.realPath=null,this.paper=c,this.attrs=this.attrs||{},this._={transform:[],sx:1,sy:1,deg:0,dx:0,dy:0,dirty:1},!c.bottom&&(c.bottom=this),this.prev=c.top,c.top&&(c.top.next=this),c.top=this,this.next=null},B=a.el;A.prototype=B,B.constructor=A,a._engine.path=function(a,b){var c=q("path");b.canvas&&b.canvas.appendChild(c);var d=new A(c,b);return d.type="path",w(d,{fill:"none",stroke:"#000",path:a}),d},B.rotate=function(a,b,e){if(this.removed) +return this;if(a=c(a).split(j),a.length-1&&(b=d(a[1]),e=d(a[2])),a=d(a[0]),null==e&&(b=e),null==b||null==e){var f=this.getBBox(1);b=f.x+f.width/2,e=f.y+f.height/2} +return this.transform(this._.transform.concat([["r",a,b,e]])),this},B.scale=function(a,b,e,f){if(this.removed) +return this;if(a=c(a).split(j),a.length-1&&(b=d(a[1]),e=d(a[2]),f=d(a[3])),a=d(a[0]),null==b&&(b=a),null==f&&(e=f),null==e||null==f) +var g=this.getBBox(1);return e=null==e?g.x+g.width/2:e,f=null==f?g.y+g.height/2:f,this.transform(this._.transform.concat([["s",a,b,e,f]])),this},B.translate=function(a,b){return this.removed?this:(a=c(a).split(j),a.length-1&&(b=d(a[1])),a=d(a[0])||0,b=+b||0,this.transform(this._.transform.concat([["t",a,b]])),this)},B.transform=function(c){var d=this._;if(null==c) +return d.transform;if(a._extractTransform(this,c),this.clip&&q(this.clip,{transform:this.matrix.invert()}),this.pattern&&s(this),this.node&&q(this.node,{transform:this.matrix}),1!=d.sx||1!=d.sy){var e=this.attrs[b]("stroke-width")?this.attrs["stroke-width"]:1;this.attr({"stroke-width":e})} +return this},B.hide=function(){return this.removed||(this.node.style.display="none"),this},B.show=function(){return this.removed||(this.node.style.display=""),this},B.remove=function(){var b=z(this.node);if(!this.removed&&b.parentNode){var c=this.paper;c.__set__&&c.__set__.exclude(this),k.unbind("raphael.*.*."+this.id),this.gradient&&c.defs.removeChild(this.gradient),a._tear(this,c),b.parentNode.removeChild(b),this.removeData();for(var d in this) +this[d]="function"==typeof this[d]?a._removedFactory(d):null;this.removed=!0}},B._getBBox=function(){if("none"==this.node.style.display){this.show();var a=!0} +var b,c=!1;this.paper.canvas.parentElement?b=this.paper.canvas.parentElement.style:this.paper.canvas.parentNode&&(b=this.paper.canvas.parentNode.style),b&&"none"==b.display&&(c=!0,b.display="");var d={};try{d=this.node.getBBox()}catch(e){d={x:this.node.clientLeft,y:this.node.clientTop,width:this.node.clientWidth,height:this.node.clientHeight}} +finally{d=d||{},c&&(b.display="none")} +return a&&this.hide(),d},B.attr=function(c,d){if(this.removed) +return this;if(null==c){var e={};for(var f in this.attrs) +this.attrs[b](f)&&(e[f]=this.attrs[f]);return e.gradient&&"none"==e.fill&&(e.fill=e.gradient)&&delete e.gradient,e.transform=this._.transform,e} +if(null==d&&a.is(c,"string")){if("fill"==c&&"none"==this.attrs.fill&&this.attrs.gradient) +return this.attrs.gradient;if("transform"==c) +return this._.transform;for(var g=c.split(j),h={},i=0,l=g.length;l>i;i++) +c=g[i],c in this.attrs?h[c]=this.attrs[c]:a.is(this.paper.customAttributes[c],"function")?h[c]=this.paper.customAttributes[c].def:h[c]=a._availableAttrs[c];return l-1?h:h[g[0]]} +if(null==d&&a.is(c,"array")){for(h={},i=0,l=c.length;l>i;i++) +h[c[i]]=this.attr(c[i]);return h} +if(null!=d){var m={};m[c]=d}else +null!=c&&a.is(c,"object")&&(m=c);for(var n in m) +k("raphael.attr."+n+"."+this.id,this,m[n]);for(n in this.paper.customAttributes) +if(this.paper.customAttributes[b](n)&&m[b](n)&&a.is(this.paper.customAttributes[n],"function")){var o=this.paper.customAttributes[n].apply(this,[].concat(m[n]));this.attrs[n]=m[n];for(var p in o) +o[b](p)&&(m[p]=o[p])} +return w(this,m),this},B.toFront=function(){if(this.removed) +return this;var b=z(this.node);b.parentNode.appendChild(b);var c=this.paper;return c.top!=this&&a._tofront(this,c),this},B.toBack=function(){if(this.removed) +return this;var b=z(this.node),c=b.parentNode;c.insertBefore(b,c.firstChild),a._toback(this,this.paper);this.paper;return this},B.insertAfter=function(b){if(this.removed||!b) +return this;var c=z(this.node),d=z(b.node||b[b.length-1].node);return d.nextSibling?d.parentNode.insertBefore(c,d.nextSibling):d.parentNode.appendChild(c),a._insertafter(this,b,this.paper),this},B.insertBefore=function(b){if(this.removed||!b) +return this;var c=z(this.node),d=z(b.node||b[0].node);return d.parentNode.insertBefore(c,d),a._insertbefore(this,b,this.paper),this},B.blur=function(b){var c=this;if(0!==+b){var d=q("filter"),e=q("feGaussianBlur");c.attrs.blur=b,d.id=a.createUUID(),q(e,{stdDeviation:+b||1.5}),d.appendChild(e),c.paper.defs.appendChild(d),c._blur=d,q(c.node,{filter:"url(#"+d.id+")"})}else +c._blur&&(c._blur.parentNode.removeChild(c._blur),delete c._blur,delete c.attrs.blur),c.node.removeAttribute("filter");return c},a._engine.circle=function(a,b,c,d){var e=q("circle");a.canvas&&a.canvas.appendChild(e);var f=new A(e,a);return f.attrs={cx:b,cy:c,r:d,fill:"none",stroke:"#000"},f.type="circle",q(e,f.attrs),f},a._engine.rect=function(a,b,c,d,e,f){var g=q("rect");a.canvas&&a.canvas.appendChild(g);var h=new A(g,a);return h.attrs={x:b,y:c,width:d,height:e,rx:f||0,ry:f||0,fill:"none",stroke:"#000"},h.type="rect",q(g,h.attrs),h},a._engine.ellipse=function(a,b,c,d,e){var f=q("ellipse");a.canvas&&a.canvas.appendChild(f);var g=new A(f,a);return g.attrs={cx:b,cy:c,rx:d,ry:e,fill:"none",stroke:"#000"},g.type="ellipse",q(f,g.attrs),g},a._engine.image=function(a,b,c,d,e,f){var g=q("image");q(g,{x:c,y:d,width:e,height:f,preserveAspectRatio:"none"}),g.setAttributeNS(n,"href",b),a.canvas&&a.canvas.appendChild(g);var h=new A(g,a);return h.attrs={x:c,y:d,width:e,height:f,src:b},h.type="image",h},a._engine.text=function(b,c,d,e){var f=q("text");b.canvas&&b.canvas.appendChild(f);var g=new A(f,b);return g.attrs={x:c,y:d,"text-anchor":"middle",text:e,"font-family":a._availableAttrs["font-family"],"font-size":a._availableAttrs["font-size"],stroke:"none",fill:"#000"},g.type="text",w(g,g.attrs),g},a._engine.setSize=function(a,b){return this.width=a||this.width,this.height=b||this.height,this.canvas.setAttribute("width",this.width),this.canvas.setAttribute("height",this.height),this._viewBox&&this.setViewBox.apply(this,this._viewBox),this},a._engine.create=function(){var b=a._getContainer.apply(0,arguments),c=b&&b.container,d=b.x,e=b.y,f=b.width,g=b.height;if(!c) +throw new Error("SVG container not found.");var h,i=q("svg"),j="overflow:hidden;";return d=d||0,e=e||0,f=f||512,g=g||342,q(i,{height:g,version:1.1,width:f,xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink"}),1==c?(i.style.cssText=j+"position:absolute;left:"+d+"px;top:"+e+"px",a._g.doc.body.appendChild(i),h=1):(i.style.cssText=j+"position:relative",c.firstChild?c.insertBefore(i,c.firstChild):c.appendChild(i)),c=new a._Paper,c.width=f,c.height=g,c.canvas=i,c.clear(),c._left=c._top=0,h&&(c.renderfix=function(){}),c.renderfix(),c},a._engine.setViewBox=function(a,b,c,d,e){k("raphael.setViewBox",this,this._viewBox,[a,b,c,d,e]);var f,h,i=this.getSize(),j=g(c/i.width,d/i.height),l=this.top,n=e?"xMidYMid meet":"xMinYMin";for(null==a?(this._vbSize&&(j=1),delete this._vbSize,f="0 0 "+this.width+m+this.height):(this._vbSize=j,f=a+m+b+m+c+m+d),q(this.canvas,{viewBox:f,preserveAspectRatio:n});j&&l;) +h="stroke-width"in l.attrs?l.attrs["stroke-width"]:1,l.attr({"stroke-width":h}),l._.dirty=1,l._.dirtyT=1,l=l.prev;return this._viewBox=[a,b,c,d,!!e],this},a.prototype.renderfix=function(){var a,b=this.canvas,c=b.style;try{a=b.getScreenCTM()||b.createSVGMatrix()}catch(d){a=b.createSVGMatrix()} +var e=-a.e%1,f=-a.f%1;(e||f)&&(e&&(this._left=(this._left+e)%1,c.left=this._left+"px"),f&&(this._top=(this._top+f)%1,c.top=this._top+"px"))},a.prototype.clear=function(){a.eve("raphael.clear",this);for(var b=this.canvas;b.firstChild;) +b.removeChild(b.firstChild);this.bottom=this.top=null,(this.desc=q("desc")).appendChild(a._g.doc.createTextNode("Created with Raphaël "+a.version)),b.appendChild(this.desc),b.appendChild(this.defs=q("defs"))},a.prototype.remove=function(){k("raphael.remove",this),this.canvas.parentNode&&this.canvas.parentNode.removeChild(this.canvas);for(var b in this) +this[b]="function"==typeof this[b]?a._removedFactory(b):null};var C=a.st;for(var D in B) +B[b](D)&&!C[b](D)&&(C[D]=function(a){return function(){var b=arguments;return this.forEach(function(c){c[a].apply(c,b)})}} +(D))}}),function(a,b){"function"==typeof define&&define.amd?define("raphael.vml",["raphael.core"],function(a){return b(a)}):b("object"==typeof exports?require("./raphael.core"):a.Raphael)} +(this,function(a){if(!a||a.vml){var b="hasOwnProperty",c=String,d=parseFloat,e=Math,f=e.round,g=e.max,h=e.min,i=e.abs,j="fill",k=/[, ]+/,l=a.eve,m=" progid:DXImageTransform.Microsoft",n=" ",o="",p={M:"m",L:"l",C:"c",Z:"x",m:"t",l:"r",c:"v",z:"x"},q=/([clmz]),?([^clmz]*)/gi,r=/ progid:\S+Blur\([^\)]+\)/g,s=/-?[^,\s-]+/g,t="position:absolute;left:0;top:0;width:1px;height:1px;behavior:url(#default#VML)",u=21600,v={path:1,rect:1,image:1},w={circle:1,ellipse:1},x=function(b){var d=/[ahqstv]/gi,e=a._pathToAbsolute;if(c(b).match(d)&&(e=a._path2curve),d=/[clmz]/g,e==a._pathToAbsolute&&!c(b).match(d)){var g=c(b).replace(q,function(a,b,c){var d=[],e="m"==b.toLowerCase(),g=p[b];return c.replace(s,function(a){e&&2==d.length&&(g+=d+p["m"==b?"l":"L"],d=[]),d.push(f(a*u))}),g+d});return g} +var h,i,j=e(b);g=[];for(var k=0,l=j.length;l>k;k++){h=j[k],i=j[k][0].toLowerCase(),"z"==i&&(i="x");for(var m=1,r=h.length;r>m;m++) +i+=f(h[m]*u)+(m!=r-1?",":o);g.push(i)} +return g.join(n)},y=function(b,c,d){var e=a.matrix();return e.rotate(-b,.5,.5),{dx:e.x(c,d),dy:e.y(c,d)}},z=function(a,b,c,d,e,f){var g=a._,h=a.matrix,k=g.fillpos,l=a.node,m=l.style,o=1,p="",q=u/b,r=u/c;if(m.visibility="hidden",b&&c){if(l.coordsize=i(q)+n+i(r),m.rotation=f*(0>b*c?-1:1),f){var s=y(f,d,e);d=s.dx,e=s.dy} +if(0>b&&(p+="x"),0>c&&(p+=" y")&&(o=-1),m.flip=p,l.coordorigin=d* -q+n+e* -r,k||g.fillsize){var t=l.getElementsByTagName(j);t=t&&t[0],l.removeChild(t),k&&(s=y(f,h.x(k[0],k[1]),h.y(k[0],k[1])),t.position=s.dx*o+n+s.dy*o),g.fillsize&&(t.size=g.fillsize[0]*i(b)+n+g.fillsize[1]*i(c)),l.appendChild(t)} +m.visibility="visible"}};a.toString=function(){return"Your browser doesn’t support SVG. Falling down to VML.\nYou are running Raphaël "+this.version};var A=function(a,b,d){for(var e=c(b).toLowerCase().split("-"),f=d?"end":"start",g=e.length,h="classic",i="medium",j="medium";g--;) +switch(e[g]){case"block":case"classic":case"oval":case"diamond":case"open":case"none":h=e[g];break;case"wide":case"narrow":j=e[g];break;case"long":case"short":i=e[g]} +var k=a.node.getElementsByTagName("stroke")[0];k[f+"arrow"]=h,k[f+"arrowlength"]=i,k[f+"arrowwidth"]=j},B=function(e,i){e.attrs=e.attrs||{};var l=e.node,m=e.attrs,p=l.style,q=v[e.type]&&(i.x!=m.x||i.y!=m.y||i.width!=m.width||i.height!=m.height||i.cx!=m.cx||i.cy!=m.cy||i.rx!=m.rx||i.ry!=m.ry||i.r!=m.r),r=w[e.type]&&(m.cx!=i.cx||m.cy!=i.cy||m.r!=i.r||m.rx!=i.rx||m.ry!=i.ry),s=e;for(var t in i) +i[b](t)&&(m[t]=i[t]);if(q&&(m.path=a._getPath[e.type](e),e._.dirty=1),i.href&&(l.href=i.href),i.title&&(l.title=i.title),i.target&&(l.target=i.target),i.cursor&&(p.cursor=i.cursor),"blur"in i&&e.blur(i.blur),(i.path&&"path"==e.type||q)&&(l.path=x(~c(m.path).toLowerCase().indexOf("r")?a._pathToAbsolute(m.path):m.path),e._.dirty=1,"image"==e.type&&(e._.fillpos=[m.x,m.y],e._.fillsize=[m.width,m.height],z(e,1,1,0,0,0))),"transform"in i&&e.transform(i.transform),r){var y=+m.cx,B=+m.cy,D=+m.rx||+m.r||0,E=+m.ry||+m.r||0;l.path=a.format("ar{0},{1},{2},{3},{4},{1},{4},{1}x",f((y-D)*u),f((B-E)*u),f((y+D)*u),f((B+E)*u),f(y*u)),e._.dirty=1} +if("clip-rect"in i){var G=c(i["clip-rect"]).split(k);if(4==G.length){G[2]=+G[2]+ +G[0],G[3]=+G[3]+ +G[1];var H=l.clipRect||a._g.doc.createElement("div"),I=H.style;I.clip=a.format("rect({1}px {2}px {3}px {0}px)",G),l.clipRect||(I.position="absolute",I.top=0,I.left=0,I.width=e.paper.width+"px",I.height=e.paper.height+"px",l.parentNode.insertBefore(H,l),H.appendChild(l),l.clipRect=H)} +i["clip-rect"]||l.clipRect&&(l.clipRect.style.clip="auto")} +if(e.textpath){var J=e.textpath.style;i.font&&(J.font=i.font),i["font-family"]&&(J.fontFamily='"'+i["font-family"].split(",")[0].replace(/^['"]+|['"]+$/g,o)+'"'),i["font-size"]&&(J.fontSize=i["font-size"]),i["font-weight"]&&(J.fontWeight=i["font-weight"]),i["font-style"]&&(J.fontStyle=i["font-style"])} +if("arrow-start"in i&&A(s,i["arrow-start"]),"arrow-end"in i&&A(s,i["arrow-end"],1),null!=i.opacity||null!=i["stroke-width"]||null!=i.fill||null!=i.src||null!=i.stroke||null!=i["stroke-width"]||null!=i["stroke-opacity"]||null!=i["fill-opacity"]||null!=i["stroke-dasharray"]||null!=i["stroke-miterlimit"]||null!=i["stroke-linejoin"]||null!=i["stroke-linecap"]){var K=l.getElementsByTagName(j),L=!1;if(K=K&&K[0],!K&&(L=K=F(j)),"image"==e.type&&i.src&&(K.src=i.src),i.fill&&(K.on=!0),(null==K.on||"none"==i.fill||null===i.fill)&&(K.on=!1),K.on&&i.fill){var M=c(i.fill).match(a._ISURL);if(M){K.parentNode==l&&l.removeChild(K),K.rotate=!0,K.src=M[1],K.type="tile";var N=e.getBBox(1);K.position=N.x+n+N.y,e._.fillpos=[N.x,N.y],a._preload(M[1],function(){e._.fillsize=[this.offsetWidth,this.offsetHeight]})}else +K.color=a.getRGB(i.fill).hex,K.src=o,K.type="solid",a.getRGB(i.fill).error&&(s.type in{circle:1,ellipse:1}||"r"!=c(i.fill).charAt())&&C(s,i.fill,K)&&(m.fill="none",m.gradient=i.fill,K.rotate=!1)} +if("fill-opacity"in i||"opacity"in i){var O=((+m["fill-opacity"]+1||2)-1)*((+m.opacity+1||2)-1)*((+a.getRGB(i.fill).o+1||2)-1);O=h(g(O,0),1),K.opacity=O,K.src&&(K.color="none")} +l.appendChild(K);var P=l.getElementsByTagName("stroke")&&l.getElementsByTagName("stroke")[0],Q=!1;!P&&(Q=P=F("stroke")),(i.stroke&&"none"!=i.stroke||i["stroke-width"]||null!=i["stroke-opacity"]||i["stroke-dasharray"]||i["stroke-miterlimit"]||i["stroke-linejoin"]||i["stroke-linecap"])&&(P.on=!0),("none"==i.stroke||null===i.stroke||null==P.on||0==i.stroke||0==i["stroke-width"])&&(P.on=!1);var R=a.getRGB(i.stroke);P.on&&i.stroke&&(P.color=R.hex),O=((+m["stroke-opacity"]+1||2)-1)*((+m.opacity+1||2)-1)*((+R.o+1||2)-1);var S=.75*(d(i["stroke-width"])||1);if(O=h(g(O,0),1),null==i["stroke-width"]&&(S=m["stroke-width"]),i["stroke-width"]&&(P.weight=S),S&&1>S&&(O*=S)&&(P.weight=1),P.opacity=O,i["stroke-linejoin"]&&(P.joinstyle=i["stroke-linejoin"]||"miter"),P.miterlimit=i["stroke-miterlimit"]||8,i["stroke-linecap"]&&(P.endcap="butt"==i["stroke-linecap"]?"flat":"square"==i["stroke-linecap"]?"square":"round"),"stroke-dasharray"in i){var T={"-":"shortdash",".":"shortdot","-.":"shortdashdot","-..":"shortdashdotdot",". ":"dot","- ":"dash","--":"longdash","- .":"dashdot","--.":"longdashdot","--..":"longdashdotdot"};P.dashstyle=T[b](i["stroke-dasharray"])?T[i["stroke-dasharray"]]:o} +Q&&l.appendChild(P)} +if("text"==s.type){s.paper.canvas.style.display=o;var U=s.paper.span,V=100,W=m.font&&m.font.match(/\d+(?:\.\d*)?(?=px)/);p=U.style,m.font&&(p.font=m.font),m["font-family"]&&(p.fontFamily=m["font-family"]),m["font-weight"]&&(p.fontWeight=m["font-weight"]),m["font-style"]&&(p.fontStyle=m["font-style"]),W=d(m["font-size"]||W&&W[0])||10,p.fontSize=W*V+"px",s.textpath.string&&(U.innerHTML=c(s.textpath.string).replace(/"));var X=U.getBoundingClientRect();s.W=m.w=(X.right-X.left)/V,s.H=m.h=(X.bottom-X.top)/V,s.X=m.x,s.Y=m.y+s.H/2,("x"in i||"y"in i)&&(s.path.v=a.format("m{0},{1}l{2},{1}",f(m.x*u),f(m.y*u),f(m.x*u)+1));for(var Y=["x","y","text","font","font-family","font-weight","font-style","font-size"],Z=0,$=Y.length;$>Z;Z++) +if(Y[Z]in i){s._.dirty=1;break} +switch(m["text-anchor"]){case"start":s.textpath.style["v-text-align"]="left",s.bbx=s.W/2;break;case"end":s.textpath.style["v-text-align"]="right",s.bbx=-s.W/2;break;default:s.textpath.style["v-text-align"]="center",s.bbx=0} +s.textpath.style["v-text-kern"]=!0}},C=function(b,f,g){b.attrs=b.attrs||{};var h=(b.attrs,Math.pow),i="linear",j=".5 .5";if(b.attrs.gradient=f,f=c(f).replace(a._radial_gradient,function(a,b,c){return i="radial",b&&c&&(b=d(b),c=d(c),h(b-.5,2)+h(c-.5,2)>.25&&(c=e.sqrt(.25-h(b-.5,2))*(2*(c>.5)-1)+.5),j=b+n+c),o}),f=f.split(/\s*\-\s*/),"linear"==i){var k=f.shift();if(k=-d(k),isNaN(k)) +return null} +var l=a._parseDots(f);if(!l) +return null;if(b=b.shape||b.node,l.length){b.removeChild(g),g.on=!0,g.method="none",g.color=l[0].color,g.color2=l[l.length-1].color;for(var m=[],p=0,q=l.length;q>p;p++) +l[p].offset&&m.push(l[p].offset+n+l[p].color);g.colors=m.length?m.join():"0% "+g.color,"radial"==i?(g.type="gradientTitle",g.focus="100%",g.focussize="0 0",g.focusposition=j,g.angle=0):(g.type="gradient",g.angle=(270-k)%360),b.appendChild(g)} +return 1},D=function(b,c){this[0]=this.node=b,b.raphael=!0,this.id=a._oid++,b.raphaelid=this.id,this.X=0,this.Y=0,this.attrs={},this.paper=c,this.matrix=a.matrix(),this._={transform:[],sx:1,sy:1,dx:0,dy:0,deg:0,dirty:1,dirtyT:1},!c.bottom&&(c.bottom=this),this.prev=c.top,c.top&&(c.top.next=this),c.top=this,this.next=null},E=a.el;D.prototype=E,E.constructor=D,E.transform=function(b){if(null==b) +return this._.transform;var d,e=this.paper._viewBoxShift,f=e?"s"+[e.scale,e.scale]+"-1-1t"+[e.dx,e.dy]:o;e&&(d=b=c(b).replace(/\.{3}|\u2026/g,this._.transform||o)),a._extractTransform(this,f+b);var g,h=this.matrix.clone(),i=this.skew,j=this.node,k=~c(this.attrs.fill).indexOf("-"),l=!c(this.attrs.fill).indexOf("url(");if(h.translate(1,1),l||k||"image"==this.type) +if(i.matrix="1 0 0 1",i.offset="0 0",g=h.split(),k&&g.noRotation||!g.isSimple){j.style.filter=h.toFilter();var m=this.getBBox(),p=this.getBBox(1),q=m.x-p.x,r=m.y-p.y;j.coordorigin=q* -u+n+r* -u,z(this,1,1,q,r,0)}else +j.style.filter=o,z(this,g.scalex,g.scaley,g.dx,g.dy,g.rotate);else +j.style.filter=o,i.matrix=c(h),i.offset=h.offset();return null!==d&&(this._.transform=d,a._extractTransform(this,d)),this},E.rotate=function(a,b,e){if(this.removed) +return this;if(null!=a){if(a=c(a).split(k),a.length-1&&(b=d(a[1]),e=d(a[2])),a=d(a[0]),null==e&&(b=e),null==b||null==e){var f=this.getBBox(1);b=f.x+f.width/2,e=f.y+f.height/2} +return this._.dirtyT=1,this.transform(this._.transform.concat([["r",a,b,e]])),this}},E.translate=function(a,b){return this.removed?this:(a=c(a).split(k),a.length-1&&(b=d(a[1])),a=d(a[0])||0,b=+b||0,this._.bbox&&(this._.bbox.x+=a,this._.bbox.y+=b),this.transform(this._.transform.concat([["t",a,b]])),this)},E.scale=function(a,b,e,f){if(this.removed) +return this;if(a=c(a).split(k),a.length-1&&(b=d(a[1]),e=d(a[2]),f=d(a[3]),isNaN(e)&&(e=null),isNaN(f)&&(f=null)),a=d(a[0]),null==b&&(b=a),null==f&&(e=f),null==e||null==f) +var g=this.getBBox(1);return e=null==e?g.x+g.width/2:e,f=null==f?g.y+g.height/2:f,this.transform(this._.transform.concat([["s",a,b,e,f]])),this._.dirtyT=1,this},E.hide=function(){return!this.removed&&(this.node.style.display="none"),this},E.show=function(){return!this.removed&&(this.node.style.display=o),this},E.auxGetBBox=a.el.getBBox,E.getBBox=function(){var a=this.auxGetBBox();if(this.paper&&this.paper._viewBoxShift){var b={},c=1/this.paper._viewBoxShift.scale;return b.x=a.x-this.paper._viewBoxShift.dx,b.x*=c,b.y=a.y-this.paper._viewBoxShift.dy,b.y*=c,b.width=a.width*c,b.height=a.height*c,b.x2=b.x+b.width,b.y2=b.y+b.height,b} +return a},E._getBBox=function(){return this.removed?{}:{x:this.X+(this.bbx||0)-this.W/2,y:this.Y-this.H,width:this.W,height:this.H}},E.remove=function(){if(!this.removed&&this.node.parentNode){this.paper.__set__&&this.paper.__set__.exclude(this),a.eve.unbind("raphael.*.*."+this.id),a._tear(this,this.paper),this.node.parentNode.removeChild(this.node),this.shape&&this.shape.parentNode.removeChild(this.shape);for(var b in this) +this[b]="function"==typeof this[b]?a._removedFactory(b):null;this.removed=!0}},E.attr=function(c,d){if(this.removed) +return this;if(null==c){var e={};for(var f in this.attrs) +this.attrs[b](f)&&(e[f]=this.attrs[f]);return e.gradient&&"none"==e.fill&&(e.fill=e.gradient)&&delete e.gradient,e.transform=this._.transform,e} +if(null==d&&a.is(c,"string")){if(c==j&&"none"==this.attrs.fill&&this.attrs.gradient) +return this.attrs.gradient;for(var g=c.split(k),h={},i=0,m=g.length;m>i;i++) +c=g[i],c in this.attrs?h[c]=this.attrs[c]:a.is(this.paper.customAttributes[c],"function")?h[c]=this.paper.customAttributes[c].def:h[c]=a._availableAttrs[c];return m-1?h:h[g[0]]} +if(this.attrs&&null==d&&a.is(c,"array")){for(h={},i=0,m=c.length;m>i;i++) +h[c[i]]=this.attr(c[i]);return h} +var n;null!=d&&(n={},n[c]=d),null==d&&a.is(c,"object")&&(n=c);for(var o in n) +l("raphael.attr."+o+"."+this.id,this,n[o]);if(n){for(o in this.paper.customAttributes) +if(this.paper.customAttributes[b](o)&&n[b](o)&&a.is(this.paper.customAttributes[o],"function")){var p=this.paper.customAttributes[o].apply(this,[].concat(n[o]));this.attrs[o]=n[o];for(var q in p) +p[b](q)&&(n[q]=p[q])} +n.text&&"text"==this.type&&(this.textpath.string=n.text),B(this,n)} +return this},E.toFront=function(){return!this.removed&&this.node.parentNode.appendChild(this.node),this.paper&&this.paper.top!=this&&a._tofront(this,this.paper),this},E.toBack=function(){return this.removed?this:(this.node.parentNode.firstChild!=this.node&&(this.node.parentNode.insertBefore(this.node,this.node.parentNode.firstChild),a._toback(this,this.paper)),this)},E.insertAfter=function(b){return this.removed?this:(b.constructor==a.st.constructor&&(b=b[b.length-1]),b.node.nextSibling?b.node.parentNode.insertBefore(this.node,b.node.nextSibling):b.node.parentNode.appendChild(this.node),a._insertafter(this,b,this.paper),this)},E.insertBefore=function(b){return this.removed?this:(b.constructor==a.st.constructor&&(b=b[0]),b.node.parentNode.insertBefore(this.node,b.node),a._insertbefore(this,b,this.paper),this)},E.blur=function(b){var c=this.node.runtimeStyle,d=c.filter;return d=d.replace(r,o),0!==+b?(this.attrs.blur=b,c.filter=d+n+m+".Blur(pixelradius="+(+b||1.5)+")",c.margin=a.format("-{0}px 0 0 -{0}px",f(+b||1.5))):(c.filter=d,c.margin=0,delete this.attrs.blur),this},a._engine.path=function(a,b){var c=F("shape");c.style.cssText=t,c.coordsize=u+n+u,c.coordorigin=b.coordorigin;var d=new D(c,b),e={fill:"none",stroke:"#000"};a&&(e.path=a),d.type="path",d.path=[],d.Path=o,B(d,e),b.canvas.appendChild(c);var f=F("skew");return f.on=!0,c.appendChild(f),d.skew=f,d.transform(o),d},a._engine.rect=function(b,c,d,e,f,g){var h=a._rectPath(c,d,e,f,g),i=b.path(h),j=i.attrs;return i.X=j.x=c,i.Y=j.y=d,i.W=j.width=e,i.H=j.height=f,j.r=g,j.path=h,i.type="rect",i},a._engine.ellipse=function(a,b,c,d,e){{var f=a.path();f.attrs} +return f.X=b-d,f.Y=c-e,f.W=2*d,f.H=2*e,f.type="ellipse",B(f,{cx:b,cy:c,rx:d,ry:e}),f},a._engine.circle=function(a,b,c,d){{var e=a.path();e.attrs} +return e.X=b-d,e.Y=c-d,e.W=e.H=2*d,e.type="circle",B(e,{cx:b,cy:c,r:d}),e},a._engine.image=function(b,c,d,e,f,g){var h=a._rectPath(d,e,f,g),i=b.path(h).attr({stroke:"none"}),k=i.attrs,l=i.node,m=l.getElementsByTagName(j)[0];return k.src=c,i.X=k.x=d,i.Y=k.y=e,i.W=k.width=f,i.H=k.height=g,k.path=h,i.type="image",m.parentNode==l&&l.removeChild(m),m.rotate=!0,m.src=c,m.type="tile",i._.fillpos=[d,e],i._.fillsize=[f,g],l.appendChild(m),z(i,1,1,0,0,0),i},a._engine.text=function(b,d,e,g){var h=F("shape"),i=F("path"),j=F("textpath");d=d||0,e=e||0,g=g||"",i.v=a.format("m{0},{1}l{2},{1}",f(d*u),f(e*u),f(d*u)+1),i.textpathok=!0,j.string=c(g),j.on=!0,h.style.cssText=t,h.coordsize=u+n+u,h.coordorigin="0 0";var k=new D(h,b),l={fill:"#000",stroke:"none",font:a._availableAttrs.font,text:g};k.shape=h,k.path=i,k.textpath=j,k.type="text",k.attrs.text=c(g),k.attrs.x=d,k.attrs.y=e,k.attrs.w=1,k.attrs.h=1,B(k,l),h.appendChild(j),h.appendChild(i),b.canvas.appendChild(h);var m=F("skew");return m.on=!0,h.appendChild(m),k.skew=m,k.transform(o),k},a._engine.setSize=function(b,c){var d=this.canvas.style;return this.width=b,this.height=c,b==+b&&(b+="px"),c==+c&&(c+="px"),d.width=b,d.height=c,d.clip="rect(0 "+b+" "+c+" 0)",this._viewBox&&a._engine.setViewBox.apply(this,this._viewBox),this},a._engine.setViewBox=function(b,c,d,e,f){a.eve("raphael.setViewBox",this,this._viewBox,[b,c,d,e,f]);var g,h,i=this.getSize(),j=i.width,k=i.height;return f&&(g=k/e,h=j/d,j>d*g&&(b-=(j-d*g)/2/g),k>e*h&&(c-=(k-e*h)/2/h)),this._viewBox=[b,c,d,e,!!f],this._viewBoxShift={dx:-b,dy:-c,scale:i},this.forEach(function(a){a.transform("...")}),this};var F;a._engine.initWin=function(a){var b=a.document;b.styleSheets.length<31?b.createStyleSheet().addRule(".rvml","behavior:url(#default#VML)"):b.styleSheets[0].addRule(".rvml","behavior:url(#default#VML)");try{!b.namespaces.rvml&&b.namespaces.add("rvml","urn:schemas-microsoft-com:vml"),F=function(a){return b.createElement("')}}catch(c){F=function(a){return b.createElement("<"+a+' xmlns="urn:schemas-microsoft.com:vml" class="rvml">')}}},a._engine.initWin(a._g.win),a._engine.create=function(){var b=a._getContainer.apply(0,arguments),c=b.container,d=b.height,e=b.width,f=b.x,g=b.y;if(!c) +throw new Error("VML container not found.");var h=new a._Paper,i=h.canvas=a._g.doc.createElement("div"),j=i.style;return f=f||0,g=g||0,e=e||512,d=d||342,h.width=e,h.height=d,e==+e&&(e+="px"),d==+d&&(d+="px"),h.coordsize=1e3*u+n+1e3*u,h.coordorigin="0 0",h.span=a._g.doc.createElement("span"),h.span.style.cssText="position:absolute;left:-9999em;top:-9999em;padding:0;margin:0;line-height:1;",i.appendChild(h.span),j.cssText=a.format("top:0;left:0;width:{0};height:{1};display:inline-block;position:relative;clip:rect(0 {0} {1} 0);overflow:hidden",e,d),1==c?(a._g.doc.body.appendChild(i),j.left=f+"px",j.top=g+"px",j.position="absolute"):c.firstChild?c.insertBefore(i,c.firstChild):c.appendChild(i),h.renderfix=function(){},h},a.prototype.clear=function(){a.eve("raphael.clear",this),this.canvas.innerHTML=o,this.span=a._g.doc.createElement("span"),this.span.style.cssText="position:absolute;left:-9999em;top:-9999em;padding:0;margin:0;line-height:1;display:inline;",this.canvas.appendChild(this.span),this.bottom=this.top=null},a.prototype.remove=function(){a.eve("raphael.remove",this),this.canvas.parentNode.removeChild(this.canvas);for(var b in this) +this[b]="function"==typeof this[b]?a._removedFactory(b):null;return!0};var G=a.st;for(var H in E) +E[b](H)&&!G[b](H)&&(G[H]=function(a){return function(){var b=arguments;return this.forEach(function(c){c[a].apply(c,b)})}} +(H))}});JustGage=function(config){var obj=this;if(config===null||config===undefined){console.log('* justgage: Make sure to pass options to the constructor!');return false;} +var node;if(config.id!==null&&config.id!==undefined){node=document.getElementById(config.id);if(!node){console.log('* justgage: No element with id : %s found',config.id);return false;}}else if(config.parentNode!==null&&config.parentNode!==undefined){node=config.parentNode;}else{console.log('* justgage: Make sure to pass the existing element id or parentNode to the constructor.');return false;} +var dataset=node.dataset?node.dataset:{};var defaults=(config.defaults!==null&&config.defaults!==undefined)?config.defaults:false;if(defaults!==false){config=extend({},config,defaults);delete config.defaults;} +obj.config={id:config.id,value:kvLookup('value',config,dataset,0,'float'),defaults:kvLookup('defaults',config,dataset,0,false),parentNode:kvLookup('parentNode',config,dataset,null),width:kvLookup('width',config,dataset,null),height:kvLookup('height',config,dataset,null),title:kvLookup('title',config,dataset,""),titleFontColor:kvLookup('titleFontColor',config,dataset,"#999999"),titleFontFamily:kvLookup('titleFontFamily',config,dataset,"sans-serif"),titlePosition:kvLookup('titlePosition',config,dataset,"above"),valueFontColor:kvLookup('valueFontColor',config,dataset,"#010101"),valueFontFamily:kvLookup('valueFontFamily',config,dataset,"Arial"),symbol:kvLookup('symbol',config,dataset,''),min:kvLookup('min',config,dataset,0,'float'),max:kvLookup('max',config,dataset,100,'float'),reverse:kvLookup('reverse',config,dataset,false),humanFriendlyDecimal:kvLookup('humanFriendlyDecimal',config,dataset,0),textRenderer:kvLookup('textRenderer',config,dataset,null),gaugeWidthScale:kvLookup('gaugeWidthScale',config,dataset,1.0),gaugeColor:kvLookup('gaugeColor',config,dataset,"#edebeb"),label:kvLookup('label',config,dataset,''),labelFontColor:kvLookup('labelFontColor',config,dataset,"#b3b3b3"),shadowOpacity:kvLookup('shadowOpacity',config,dataset,0.2),shadowSize:kvLookup('shadowSize',config,dataset,5),shadowVerticalOffset:kvLookup('shadowVerticalOffset',config,dataset,3),levelColors:kvLookup('levelColors',config,dataset,["#a9d70b","#f9c802","#ff0000"],'array',','),startAnimationTime:kvLookup('startAnimationTime',config,dataset,700),startAnimationType:kvLookup('startAnimationType',config,dataset,'>'),refreshAnimationTime:kvLookup('refreshAnimationTime',config,dataset,700),refreshAnimationType:kvLookup('refreshAnimationType',config,dataset,'>'),donutStartAngle:kvLookup('donutStartAngle',config,dataset,90),valueMinFontSize:kvLookup('valueMinFontSize',config,dataset,16),titleMinFontSize:kvLookup('titleMinFontSize',config,dataset,10),labelMinFontSize:kvLookup('labelMinFontSize',config,dataset,10),minLabelMinFontSize:kvLookup('minLabelMinFontSize',config,dataset,10),maxLabelMinFontSize:kvLookup('maxLabelMinFontSize',config,dataset,10),hideValue:kvLookup('hideValue',config,dataset,false),hideMinMax:kvLookup('hideMinMax',config,dataset,false),hideInnerShadow:kvLookup('hideInnerShadow',config,dataset,false),humanFriendly:kvLookup('humanFriendly',config,dataset,false),noGradient:kvLookup('noGradient',config,dataset,false),donut:kvLookup('donut',config,dataset,false),relativeGaugeSize:kvLookup('relativeGaugeSize',config,dataset,false),counter:kvLookup('counter',config,dataset,false),decimals:kvLookup('decimals',config,dataset,0),customSectors:kvLookup('customSectors',config,dataset,[]),formatNumber:kvLookup('formatNumber',config,dataset,false),pointer:kvLookup('pointer',config,dataset,false),pointerOptions:kvLookup('pointerOptions',config,dataset,[])};var +canvasW,canvasH,widgetW,widgetH,aspect,dx,dy,titleFontSize,titleX,titleY,valueFontSize,valueX,valueY,labelFontSize,labelX,labelY,minFontSize,minX,minY,maxFontSize,maxX,maxY;if(obj.config.value>obj.config.max) +obj.config.value=obj.config.max;if(obj.config.valuecanvasH){widgetH=canvasH;widgetW=widgetH;}else if(canvasWcanvasH){aspect=widgetH/canvasH;widgetH=widgetH/aspect;widgetW=widgetH/aspect;}}else{widgetW=canvasW;widgetH=widgetW;} +dx=(canvasW-widgetW)/2;dy=(canvasH-widgetH)/2;titleFontSize=((widgetH/8)>10)?(widgetH/10):10;titleX=dx+widgetW/2;titleY=dy+widgetH/11;valueFontSize=((widgetH/6.4)>16)?(widgetH/5.4):18;valueX=dx+widgetW/2;if(obj.config.label!==''){valueY=dy+widgetH/1.85;}else{valueY=dy+widgetH/1.7;} +labelFontSize=((widgetH/16)>10)?(widgetH/16):10;labelX=dx+widgetW/2;labelY=valueY+labelFontSize;minFontSize=((widgetH/16)>10)?(widgetH/16):10;minX=dx+(widgetW/10)+(widgetW/6.666666666666667*obj.config.gaugeWidthScale)/2;minY=labelY;maxFontSize=((widgetH/16)>10)?(widgetH/16):10;maxX=dx+widgetW-(widgetW/10)-(widgetW/6.666666666666667*obj.config.gaugeWidthScale)/2;maxY=labelY;}else{if(canvasW>canvasH){widgetH=canvasH;widgetW=widgetH*1.25;if(widgetW>canvasW){aspect=widgetW/canvasW;widgetW=widgetW/aspect;widgetH=widgetH/aspect;}}else if(canvasWcanvasH){aspect=widgetH/canvasH;widgetH=widgetH/aspect;widgetW=widgetH/aspect;}}else{widgetW=canvasW;widgetH=widgetW*0.75;} +dx=(canvasW-widgetW)/2;dy=(canvasH-widgetH)/2;if(obj.config.titlePosition==='below'){dy-=(widgetH/6.4);} +titleFontSize=((widgetH/8)>obj.config.titleMinFontSize)?(widgetH/10):obj.config.titleMinFontSize;titleX=dx+widgetW/2;titleY=dy+(obj.config.titlePosition==='below'?(widgetH*1.07):(widgetH/6.4));valueFontSize=((widgetH/6.5)>obj.config.valueMinFontSize)?(widgetH/6.5):obj.config.valueMinFontSize;valueX=dx+widgetW/2;valueY=dy+widgetH/1.275;labelFontSize=((widgetH/16)>obj.config.labelMinFontSize)?(widgetH/16):obj.config.labelMinFontSize;labelX=dx+widgetW/2;labelY=valueY+valueFontSize/2+5;minFontSize=((widgetH/16)>obj.config.minLabelMinFontSize)?(widgetH/16):obj.config.minLabelMinFontSize;minX=dx+(widgetW/10)+(widgetW/6.666666666666667*obj.config.gaugeWidthScale)/2;minY=labelY;maxFontSize=((widgetH/16)>obj.config.maxLabelMinFontSize)?(widgetH/16):obj.config.maxLabelMinFontSize;maxX=dx+widgetW-(widgetW/10)-(widgetW/6.666666666666667*obj.config.gaugeWidthScale)/2;maxY=labelY;} +obj.params={canvasW:canvasW,canvasH:canvasH,widgetW:widgetW,widgetH:widgetH,dx:dx,dy:dy,titleFontSize:titleFontSize,titleX:titleX,titleY:titleY,valueFontSize:valueFontSize,valueX:valueX,valueY:valueY,labelFontSize:labelFontSize,labelX:labelX,labelY:labelY,minFontSize:minFontSize,minX:minX,minY:minY,maxFontSize:maxFontSize,maxX:maxX,maxY:maxY};canvasW,canvasH,widgetW,widgetH,aspect,dx,dy,titleFontSize,titleX,titleY,valueFontSize,valueX,valueY,labelFontSize,labelX,labelY,minFontSize,minX,minY,maxFontSize,maxX,maxY=null;obj.canvas.customAttributes.pki=function(value,min,max,w,h,dx,dy,gws,donut,reverse){var alpha,Ro,Ri,Cx,Cy,Xo,Yo,Xi,Yi,path;if(donut){alpha=(1-2*(value-min)/(max-min))*Math.PI;Ro=w/2-w/7;Ri=Ro-w/6.666666666666667*gws;Cx=w/2+dx;Cy=h/1.95+dy;Xo=w/2+dx+Ro*Math.cos(alpha);Yo=h-(h-Cy)-Ro*Math.sin(alpha);Xi=w/2+dx+Ri*Math.cos(alpha);Yi=h-(h-Cy)-Ri*Math.sin(alpha);path="M"+(Cx-Ri)+","+Cy+" ";path+="L"+(Cx-Ro)+","+Cy+" ";if(value>((max-min)/2)){path+="A"+Ro+","+Ro+" 0 0 1 "+(Cx+Ro)+","+Cy+" ";} +path+="A"+Ro+","+Ro+" 0 0 1 "+Xo+","+Yo+" ";path+="L"+Xi+","+Yi+" ";if(value>((max-min)/2)){path+="A"+Ri+","+Ri+" 0 0 0 "+(Cx+Ri)+","+Cy+" ";} +path+="A"+Ri+","+Ri+" 0 0 0 "+(Cx-Ri)+","+Cy+" ";path+="Z ";return{path:path};}else{alpha=(1-(value-min)/(max-min))*Math.PI;Ro=w/2-w/10;Ri=Ro-w/6.666666666666667*gws;Cx=w/2+dx;Cy=h/1.25+dy;Xo=w/2+dx+Ro*Math.cos(alpha);Yo=h-(h-Cy)-Ro*Math.sin(alpha);Xi=w/2+dx+Ri*Math.cos(alpha);Yi=h-(h-Cy)-Ri*Math.sin(alpha);path="M"+(Cx-Ri)+","+Cy+" ";path+="L"+(Cx-Ro)+","+Cy+" ";path+="A"+Ro+","+Ro+" 0 0 1 "+Xo+","+Yo+" ";path+="L"+Xi+","+Yi+" ";path+="A"+Ri+","+Ri+" 0 0 0 "+(Cx-Ri)+","+Cy+" ";path+="Z ";return{path:path};} +alpha,Ro,Ri,Cx,Cy,Xo,Yo,Xi,Yi,path=null;};obj.canvas.customAttributes.ndl=function(value,min,max,w,h,dx,dy,gws,donut){var dlt=w*3.5/100;var dlb=w/15;var dw=w/100;if(obj.config.pointerOptions.toplength!=null&&obj.config.pointerOptions.toplength!=undefined) +dlt=obj.config.pointerOptions.toplength;if(obj.config.pointerOptions.bottomlength!=null&&obj.config.pointerOptions.bottomlength!=undefined) +dlb=obj.config.pointerOptions.bottomlength;if(obj.config.pointerOptions.bottomwidth!=null&&obj.config.pointerOptions.bottomwidth!=undefined) +dw=obj.config.pointerOptions.bottomwidth;var alpha,Ro,Ri,Cx,Cy,Xo,Yo,Xi,Yi,Xc,Yc,Xz,Yz,Xa,Ya,Xb,Yb,path;if(donut){alpha=(1-2*(value-min)/(max-min))*Math.PI;Ro=w/2-w/7;Ri=Ro-w/6.666666666666667*gws;Cx=w/2+dx;Cy=h/1.95+dy;Xo=w/2+dx+Ro*Math.cos(alpha);Yo=h-(h-Cy)-Ro*Math.sin(alpha);Xi=w/2+dx+Ri*Math.cos(alpha);Yi=h-(h-Cy)-Ri*Math.sin(alpha);Xc=Xo+dlt*Math.cos(alpha);Yc=Yo-dlt*Math.sin(alpha);Xz=Xi-dlb*Math.cos(alpha);Yz=Yi+dlb*Math.sin(alpha);Xa=Xz+dw*Math.sin(alpha);Ya=Yz+dw*Math.cos(alpha);Xb=Xz-dw*Math.sin(alpha);Yb=Yz-dw*Math.cos(alpha);path='M'+Xa+','+Ya+' ';path+='L'+Xb+','+Yb+' ';path+='L'+Xc+','+Yc+' ';path+='Z ';return{path:path};}else{alpha=(1-(value-min)/(max-min))*Math.PI;Ro=w/2-w/10;Ri=Ro-w/6.666666666666667*gws;Cx=w/2+dx;Cy=h/1.25+dy;Xo=w/2+dx+Ro*Math.cos(alpha);Yo=h-(h-Cy)-Ro*Math.sin(alpha);Xi=w/2+dx+Ri*Math.cos(alpha);Yi=h-(h-Cy)-Ri*Math.sin(alpha);Xc=Xo+dlt*Math.cos(alpha);Yc=Yo-dlt*Math.sin(alpha);Xz=Xi-dlb*Math.cos(alpha);Yz=Yi+dlb*Math.sin(alpha);Xa=Xz+dw*Math.sin(alpha);Ya=Yz+dw*Math.cos(alpha);Xb=Xz-dw*Math.sin(alpha);Yb=Yz-dw*Math.cos(alpha);path='M'+Xa+','+Ya+' ';path+='L'+Xb+','+Yb+' ';path+='L'+Xc+','+Yc+' ';path+='Z ';return{path:path};} +alpha,Ro,Ri,Cx,Cy,Xo,Yo,Xi,Yi,Xc,Yc,Xz,Yz,Xa,Ya,Xb,Yb,path=null;};obj.gauge=obj.canvas.path().attr({"stroke":"none","fill":obj.config.gaugeColor,pki:[obj.config.max,obj.config.min,obj.config.max,obj.params.widgetW,obj.params.widgetH,obj.params.dx,obj.params.dy,obj.config.gaugeWidthScale,obj.config.donut,obj.config.reverse]});obj.level=obj.canvas.path().attr({"stroke":"none","fill":getColor(obj.config.value,(obj.config.value-obj.config.min)/(obj.config.max-obj.config.min),obj.config.levelColors,obj.config.noGradient,obj.config.customSectors),pki:[obj.config.min,obj.config.min,obj.config.max,obj.params.widgetW,obj.params.widgetH,obj.params.dx,obj.params.dy,obj.config.gaugeWidthScale,obj.config.donut,obj.config.reverse]});if(obj.config.donut){obj.level.transform("r"+obj.config.donutStartAngle+", "+(obj.params.widgetW/2+obj.params.dx)+", "+(obj.params.widgetH/1.95+obj.params.dy));} +if(obj.config.pointer){obj.needle=obj.canvas.path().attr({"stroke":(obj.config.pointerOptions.stroke!==null&&obj.config.pointerOptions.stroke!==undefined)?obj.config.pointerOptions.stroke:"none","stroke-width":(obj.config.pointerOptions.stroke_width!==null&&obj.config.pointerOptions.stroke_width!==undefined)?obj.config.pointerOptions.stroke_width:0,"stroke-linecap":(obj.config.pointerOptions.stroke_linecap!==null&&obj.config.pointerOptions.stroke_linecap!==undefined)?obj.config.pointerOptions.stroke_linecap:"square","fill":(obj.config.pointerOptions.color!==null&&obj.config.pointerOptions.color!==undefined)?obj.config.pointerOptions.color:"#000000",ndl:[obj.config.min,obj.config.min,obj.config.max,obj.params.widgetW,obj.params.widgetH,obj.params.dx,obj.params.dy,obj.config.gaugeWidthScale,obj.config.donut]});if(obj.config.donut){obj.needle.transform("r"+obj.config.donutStartAngle+", "+(obj.params.widgetW/2+obj.params.dx)+", "+(obj.params.widgetH/1.95+obj.params.dy));}} +obj.txtTitle=obj.canvas.text(obj.params.titleX,obj.params.titleY,obj.config.title);obj.txtTitle.attr({"font-size":obj.params.titleFontSize,"font-weight":"bold","font-family":obj.config.titleFontFamily,"fill":obj.config.titleFontColor,"fill-opacity":"1"});setDy(obj.txtTitle,obj.params.titleFontSize,obj.params.titleY);obj.txtValue=obj.canvas.text(obj.params.valueX,obj.params.valueY,0);obj.txtValue.attr({"font-size":obj.params.valueFontSize,"font-weight":"bold","font-family":obj.config.valueFontFamily,"fill":obj.config.valueFontColor,"fill-opacity":"0"});setDy(obj.txtValue,obj.params.valueFontSize,obj.params.valueY);obj.txtLabel=obj.canvas.text(obj.params.labelX,obj.params.labelY,obj.config.label);obj.txtLabel.attr({"font-size":obj.params.labelFontSize,"font-weight":"normal","font-family":"Arial","fill":obj.config.labelFontColor,"fill-opacity":"0"});setDy(obj.txtLabel,obj.params.labelFontSize,obj.params.labelY);var min=obj.config.min;if(obj.config.reverse){min=obj.config.max;} +obj.txtMinimum=min;if(obj.config.humanFriendly){obj.txtMinimum=humanFriendlyNumber(min,obj.config.humanFriendlyDecimal);}else if(obj.config.formatNumber){obj.txtMinimum=formatNumber(min);} +obj.txtMin=obj.canvas.text(obj.params.minX,obj.params.minY,obj.txtMinimum);obj.txtMin.attr({"font-size":obj.params.minFontSize,"font-weight":"normal","font-family":"Arial","fill":obj.config.labelFontColor,"fill-opacity":(obj.config.hideMinMax||obj.config.donut)?"0":"1"});setDy(obj.txtMin,obj.params.minFontSize,obj.params.minY);var max=obj.config.max;if(obj.config.reverse){max=obj.config.min;} +obj.txtMaximum=max;if(obj.config.humanFriendly){obj.txtMaximum=humanFriendlyNumber(max,obj.config.humanFriendlyDecimal);}else if(obj.config.formatNumber){obj.txtMaximum=formatNumber(max);} +obj.txtMax=obj.canvas.text(obj.params.maxX,obj.params.maxY,obj.txtMaximum);obj.txtMax.attr({"font-size":obj.params.maxFontSize,"font-weight":"normal","font-family":"Arial","fill":obj.config.labelFontColor,"fill-opacity":(obj.config.hideMinMax||obj.config.donut)?"0":"1"});setDy(obj.txtMax,obj.params.maxFontSize,obj.params.maxY);var defs=obj.canvas.canvas.childNodes[1];var svg="http://www.w3.org/2000/svg";if(ie!=='undefined'&&ie<9){} +else if(ie!=='undefined'){onCreateElementNsReady(function(){obj.generateShadow(svg,defs);});}else{obj.generateShadow(svg,defs);} +defs,svg=null;if(obj.config.textRenderer){obj.originalValue=obj.config.textRenderer(obj.originalValue);}else if(obj.config.humanFriendly){obj.originalValue=humanFriendlyNumber(obj.originalValue,obj.config.humanFriendlyDecimal)+obj.config.symbol;}else if(obj.config.formatNumber){obj.originalValue=formatNumber(obj.originalValue)+obj.config.symbol;}else{obj.originalValue=(obj.originalValue*1).toFixed(obj.config.decimals)+obj.config.symbol;} +if(obj.config.counter===true){eve.on("raphael.anim.frame."+(obj.level.id),function(){var currentValue=obj.level.attr("pki")[0];if(obj.config.reverse){currentValue=(obj.config.max*1)+(obj.config.min*1)-(obj.level.attr("pki")[0]*1);} +if(obj.config.textRenderer){obj.txtValue.attr("text",obj.config.textRenderer(Math.floor(currentValue)));}else if(obj.config.humanFriendly){obj.txtValue.attr("text",humanFriendlyNumber(Math.floor(currentValue),obj.config.humanFriendlyDecimal)+obj.config.symbol);}else if(obj.config.formatNumber){obj.txtValue.attr("text",formatNumber(Math.floor(currentValue))+obj.config.symbol);}else{obj.txtValue.attr("text",(currentValue*1).toFixed(obj.config.decimals)+obj.config.symbol);} +setDy(obj.txtValue,obj.params.valueFontSize,obj.params.valueY);currentValue=null;});eve.on("raphael.anim.finish."+(obj.level.id),function(){obj.txtValue.attr({"text":obj.originalValue});setDy(obj.txtValue,obj.params.valueFontSize,obj.params.valueY);});}else{eve.on("raphael.anim.start."+(obj.level.id),function(){obj.txtValue.attr({"text":obj.originalValue});setDy(obj.txtValue,obj.params.valueFontSize,obj.params.valueY);});} +var rvl=obj.config.value;if(obj.config.reverse){rvl=(obj.config.max*1)+(obj.config.min*1)-(obj.config.value*1);} +obj.level.animate({pki:[rvl,obj.config.min,obj.config.max,obj.params.widgetW,obj.params.widgetH,obj.params.dx,obj.params.dy,obj.config.gaugeWidthScale,obj.config.donut,obj.config.reverse]},obj.config.startAnimationTime,obj.config.startAnimationType);if(obj.config.pointer){obj.needle.animate({ndl:[rvl,obj.config.min,obj.config.max,obj.params.widgetW,obj.params.widgetH,obj.params.dx,obj.params.dy,obj.config.gaugeWidthScale,obj.config.donut]},obj.config.startAnimationTime,obj.config.startAnimationType);} +obj.txtValue.animate({"fill-opacity":(obj.config.hideValue)?"0":"1"},obj.config.startAnimationTime,obj.config.startAnimationType);obj.txtLabel.animate({"fill-opacity":"1"},obj.config.startAnimationTime,obj.config.startAnimationType);};JustGage.prototype.refresh=function(val,max){var obj=this;var displayVal,color,max=max||null;if(max!==null){obj.config.max=max;obj.txtMaximum=obj.config.max;if(obj.config.humanFriendly){obj.txtMaximum=humanFriendlyNumber(obj.config.max,obj.config.humanFriendlyDecimal);}else if(obj.config.formatNumber){obj.txtMaximum=formatNumber(obj.config.max);} +if(!obj.config.reverse){obj.txtMax.attr({"text":obj.txtMaximum});setDy(obj.txtMax,obj.params.maxFontSize,obj.params.maxY);}else{obj.txtMin.attr({"text":obj.txtMaximum});setDy(obj.txtMin,obj.params.minFontSize,obj.params.minY);}} +displayVal=val;if((val*1)>(obj.config.max*1)){val=(obj.config.max*1);} +if((val*1)<(obj.config.min*1)){val=(obj.config.min*1);} +color=getColor(val,(val-obj.config.min)/(obj.config.max-obj.config.min),obj.config.levelColors,obj.config.noGradient,obj.config.customSectors);if(obj.config.textRenderer){displayVal=obj.config.textRenderer(displayVal);}else if(obj.config.humanFriendly){displayVal=humanFriendlyNumber(displayVal,obj.config.humanFriendlyDecimal)+obj.config.symbol;}else if(obj.config.formatNumber){displayVal=formatNumber((displayVal*1).toFixed(obj.config.decimals))+obj.config.symbol;}else{displayVal=(displayVal*1).toFixed(obj.config.decimals)+obj.config.symbol;} +obj.originalValue=displayVal;obj.config.value=val*1;if(!obj.config.counter){obj.txtValue.attr({"text":displayVal});setDy(obj.txtValue,obj.params.valueFontSize,obj.params.valueY);} +var rvl=obj.config.value;if(obj.config.reverse){rvl=(obj.config.max*1)+(obj.config.min*1)-(obj.config.value*1);} +obj.level.animate({pki:[rvl,obj.config.min,obj.config.max,obj.params.widgetW,obj.params.widgetH,obj.params.dx,obj.params.dy,obj.config.gaugeWidthScale,obj.config.donut,obj.config.reverse],"fill":color},obj.config.refreshAnimationTime,obj.config.refreshAnimationType);if(obj.config.pointer){obj.needle.animate({ndl:[rvl,obj.config.min,obj.config.max,obj.params.widgetW,obj.params.widgetH,obj.params.dx,obj.params.dy,obj.config.gaugeWidthScale,obj.config.donut]},obj.config.refreshAnimationTime,obj.config.refreshAnimationType);} +obj,displayVal,color,max=null;};JustGage.prototype.generateShadow=function(svg,defs){var obj=this;var sid="inner-shadow-"+obj.config.id;var gaussFilter,feOffset,feGaussianBlur,feComposite1,feFlood,feComposite2,feComposite3;gaussFilter=document.createElementNS(svg,"filter");gaussFilter.setAttribute("id",sid);defs.appendChild(gaussFilter);feOffset=document.createElementNS(svg,"feOffset");feOffset.setAttribute("dx",0);feOffset.setAttribute("dy",obj.config.shadowVerticalOffset);gaussFilter.appendChild(feOffset);feGaussianBlur=document.createElementNS(svg,"feGaussianBlur");feGaussianBlur.setAttribute("result","offset-blur");feGaussianBlur.setAttribute("stdDeviation",obj.config.shadowSize);gaussFilter.appendChild(feGaussianBlur);feComposite1=document.createElementNS(svg,"feComposite");feComposite1.setAttribute("operator","out");feComposite1.setAttribute("in","SourceGraphic");feComposite1.setAttribute("in2","offset-blur");feComposite1.setAttribute("result","inverse");gaussFilter.appendChild(feComposite1);feFlood=document.createElementNS(svg,"feFlood");feFlood.setAttribute("flood-color","black");feFlood.setAttribute("flood-opacity",obj.config.shadowOpacity);feFlood.setAttribute("result","color");gaussFilter.appendChild(feFlood);feComposite2=document.createElementNS(svg,"feComposite");feComposite2.setAttribute("operator","in");feComposite2.setAttribute("in","color");feComposite2.setAttribute("in2","inverse");feComposite2.setAttribute("result","shadow");gaussFilter.appendChild(feComposite2);feComposite3=document.createElementNS(svg,"feComposite");feComposite3.setAttribute("operator","over");feComposite3.setAttribute("in","shadow");feComposite3.setAttribute("in2","SourceGraphic");gaussFilter.appendChild(feComposite3);if(!obj.config.hideInnerShadow){obj.canvas.canvas.childNodes[2].setAttribute("filter","url(#"+sid+")");obj.canvas.canvas.childNodes[3].setAttribute("filter","url(#"+sid+")");} +gaussFilter,feOffset,feGaussianBlur,feComposite1,feFlood,feComposite2,feComposite3=null;};function kvLookup(key,tablea,tableb,defval,datatype,delimiter){var val=defval;var canConvert=false;if(!(key===null||key===undefined)){if(tableb!==null&&tableb!==undefined&&typeof tableb==="object"&&key in tableb){val=tableb[key];canConvert=true;}else if(tablea!==null&&tablea!==undefined&&typeof tablea==="object"&&key in tablea){val=tablea[key];canConvert=true;}else{val=defval;} +if(canConvert===true){if(datatype!==null&&datatype!==undefined){switch(datatype){case'int':val=parseInt(val,10);break;case'float':val=parseFloat(val);break;default:break;}}}} +return val;};function getColor(val,pct,col,noGradient,custSec){var no,inc,colors,percentage,rval,gval,bval,lower,upper,range,rangePct,pctLower,pctUpper,color;var noGradient=noGradient||custSec.length>0;if(custSec.length>0){for(var i=0;icustSec[i].lo&&val<=custSec[i].hi){return custSec[i].color;}}} +no=col.length;if(no===1) +return col[0];inc=(noGradient)?(1/no):(1/(no-1));colors=[];for(i=0;i9)&&elem.node.firstChild.attributes.dy){elem.node.firstChild.attributes.dy.value=0;}} +function getRandomInt(min,max){return Math.floor(Math.random()*(max-min+1))+min;} +function cutHex(str){return(str.charAt(0)=="#")?str.substring(1,7):str;} +function humanFriendlyNumber(n,d){var p,d2,i,s;p=Math.pow;d2=p(10,d);i=7;while(i){s=p(10,i-- *3);if(s<=n){n=Math.round(n*d2/s)/d2+"KMGTPE"[i];}} +return n;} +function formatNumber(x){var parts=x.toString().split(".");parts[0]=parts[0].replace(/\B(?=(\d{3})+(?!\d))/g,",");return parts.join(".");} +function getStyle(oElm,strCssRule){var strValue="";if(document.defaultView&&document.defaultView.getComputedStyle){strValue=document.defaultView.getComputedStyle(oElm,"").getPropertyValue(strCssRule);}else if(oElm.currentStyle){strCssRule=strCssRule.replace(/\-(\w)/g,function(strMatch,p1){return p1.toUpperCase();});strValue=oElm.currentStyle[strCssRule];} +return strValue;} +function onCreateElementNsReady(func){if(document.createElementNS!==undefined){func();}else{setTimeout(function(){onCreateElementNsReady(func);},100);}} +var ie=(function(){var undef,v=3,div=document.createElement('div'),all=div.getElementsByTagName('i');while(div.innerHTML='',all[0]);return v>4?v:undef;} +());function extend(out){out=out||{};for(var i=1;il#$}4M(9jq&>BeA4QV~fmX|+Udl~OUG z&{FOqR0ziyS|YcQYYxx+e^1~3)_cBl;nYcH%{*)U&w1bXd*65e_kQ-?&wifg4TWMt znL`B%g!Df))F(?Q)F2cJ#m4@09$zpNnx<>DYlnZY5(=#;8Vbeh9zCKbe!8xI>22Bc z0I!gQQ1)~@9HV=yXU&>*UcrI|j}|Um_;~KzxfkkMU4h?HYnk*zW}#l@%$X0BDpkr= zs8GRGs#M8UtXR?MeaH1%)9^jq8*KS?GEjIWOO`CVa^%S2a^=e9B-exUn3x!+-}iA( z_+E6Q$$Ft#g1?7*^W@3n#N9plp6uq&pYO_)DdX?sox_F=b8FVDaWiJja4)|2qWkpIPkEka{qu9@&UG)n z^pbz}-FM%0bLPzPIw1dr7hZ6E`t&((cXp3H`lwsHc(K>%z4zWjelwx4aH2?&BHn&*u2G|gyYa>wU3`4J z>(Qf!w_id+f&w;1_p9rgP`bZFSHp=;W-sk`;oTb;NZ7q2FIAgvhSeKGQ->UzgK`Os0>;CQua z)fVX4E5%PV7mHu~JU#In{hl<>$uqG+bAkMn!3|r{N7x#WAFgCS-SUeYGO!u8D<#AV zaY7jZf6XD7@8~c?8+wv+>F+VhTkGZ5hlC?K-lA($1oB`J0l&@2#`{VNLzIJ0=F6AQ zl`dV{=U-x(d`wPKjy$h>CJ5yP{466HdY6`tGbP*S&?;4`5H~&_5RWx$*7V?d&YU^P zAIpV`!q4GA|DiAa42nti6pbH_TuwehSH>Z1Ku#!Iwrm895qbvvQ@}^?33%|%EBS_( zr~9f34Cf8hzx|avE+IR6_UwNALIzMyN&<8jSCh~GXM~1AeW9{YOn^^Hjq5dq`NBED zzX!dMYhx$lXAsEbH|`NnN3OMJqyF{$r+qP|U2M->MoZA6<@7lG? zpI*Lv+2@V0O!}SJ7#5WO+H0@56DLl1y|MSnlP4YZ3-TU*_+htu_io>p)KNo+4mB}8 z4|VU}J#uab?b@~TeUNfhYQFi=0*z<{lEI^D}O8FJYzL&`}XawXwjm+enB5> z1O^Nk;D1Li^1@wr-Q~}Ne_FI?;pT)cFJAOIKk&cB?HEL9<@~Mkx)N|B#fLe{# zvSmwO%TfEP=J9y!vB&&x=uaN3Teq&a(GyQR;romqZ@cZb)a0Xk68-PL|9*Gm$PxF@ zLl3!S%a-|?kUl?l?3nA{zkfu2Y;3Fps+S}3ImbV#v8WNTAFWNBHfhPH49^m0yW6l~gPSsCis!X;>sIe;%s;4SY3R>5*riJsf6Tcx)ug^wwDW-d zP5)=C|3CWZBZvQMe&pYC>Cz={XX?`xD^|E#wQBj=m;Pkz#U?c5agMKV*|NoL-n`j; z@x>R8=i&RwC!d&j&sp+Dg>BEc^cR!AW5*6(kCXep{`zb0_i({yiD7DW>TP6^6R@o{ z`kp?(4~Pxo1%2+h=N`}7?z`iTJMh1L0`bq7$XIt-aE%)`_RlenP+xP7eEO5vQqAky zwr%TWb4(q8zO%#$JB1CkRJqN4*3W9 z-{)w?D|lcN>OjUu_18(&jMSs!guy~R0om5?I!w~wgk2b$;ZjsJO%IK`mynOn*cv^N zck|6RyCzMVIL1f7eD0>3Zu0kqYvOy?b{_>Ay z@?C10ppPYcaXK!Lqe_ayV2!aS;DCK?9>AIa5U2CX$>VizIU%ED8%=UmLHR>n#lvXD z!g|HxA^GEB@z^Z6ljWz4bq{e3-(REAkN6P28JvHX)_Ea;u`D&;)=wGM%r~)#R#0eJ9xpYh}`K|i|zrfz`E-N$=x(TlcYcx;)m+)_4lg{S| ze-@ex6@+VM+J*#$M`S<|T~PT06L?XLjn@-U7aMEp@OlCz z4f|tj>R|)*X%O76KCs$%sNP3EU>9TrW$HBDjpum}u?b(^3$PLX-cH;TSeFC%JGC_P zGI-%5_>rw;P@_kKHK#CtbT}gP74S#$F0zO%WRs_e4>(;-Gv4HFa$&4cB@FUlWBJS? z@xE+ppYXT!Fk6qa*kzsuR|Dt73H_#b1+hivzZ2qx$^!Y9dJzs*qr)w&#_#Bijq3{d zCb^K@2jHRB^A(%YYF5y6aLl62SH67?5 z#z%a+ov>9nEiflG8D2KrjWgV^XKFwf?lC=i7M~;LQ_vwICoB`$aDYpDfqV&N&Ga~0M!SZiVLG#c#X0`^70^y$<6z1$xJYeGG>Mn_IS z*Dxoz!4a;(hCak*ePN}L#O6Bpy3p_RKemK>kT?ErAV5iSZT+Ma$lzrpUdPeDvZ$0<3K_4$lw-+%wTYu~;-oZtq>qC&6_h}kMa zf{=_m*XTpDz4;9MgS^S1K``%U|2`ucYi#&Zm?QZK&NTXg`nHphB6qIiJJGf`?r^rf z1J;y+U=KVa8g^j4mbIfWS2)8R6cU)9C*#lh#gHLG{Fr2Z&pe+PrBC4wU&bfa&{}FO znsLm)T2rv`Ex@a)f$gPWnB>dsP8soWh z=lnMXw;Y9WKn3`BISo#vp&jM!t_B2jf5NJ>e_Zjr}yPB_<}ir=Nb>+nO~;_Cny#daQx# zLH_L9&^OpIE&kk-5`Wh7#1pR3{FB%pUpGHluwa4Tw_+U@{n@vpKWL1h_#}RA{OKbD z*Q5F4|IBBImE*^cd$2Evt!UVvd(z+!SA53&KbilKQ}7e|%=T_NcI@Z?*DSA)N3bQi z-uRQB&%SSAb-9E<1g$r(BO}bY4C@u*`FA|my+dUo@@FrK#y4{03%FxPay-Y(50Q&6u{TX0pci#paQ?{t zK{S8*hFG$_s|dmH0pA>AKXTBjRjVRDBP+~5=>OOsUDgYc{K@x!G`=mQ)->Pb8gWgZ zvzJTbJ486OZr$4ZF}m4Y7yIwsyVu{xAMAmC@TYI_O9OcUj$qTKO+LQKan{(YVs9c59zkJTFekM82RSfFNrKQ#n%0@jow_UAiF{24nk z7QoeVU8hc+Jb$=xjs0KpB>V3xSFVhV6O2*h820R~v0sc0i4Wr3Vww2GPoI7ES-&q# ze^MX5^Ugc=sP8ZC5zonj)jw8$cGI=UyoJ2MHwfea`13B}jU0q5?2in-(?Bv;JvopX5wp1>dH2`|`^#Js39txrX|0iM%!MOd?S~#Hi3V!{x(clDlp#Bcc04^M{OQME+c-; z_Lg^o+~EW_#!cgh4)_*&(qF_q`m5$Sr#!JaEQ@+(nJ`?aBM_fyt-tAK-_QXa`8I&{ zu2`X>z?{E^-akloIm0{*{`d|YEMD<<>`XlgUu=twsgFR=*64uFjMw6SN%g{X$*3i; z7J|GA0^=Pz|ZBZM^kOQzqr=ox@#=h zOAf+^7`O0y{2gw@C$>ii><&04X8E1|BFD;qPAXo9=$+*S`uf-4tk*^w??+B4>Cjnz zw2OLz`35nFFA$gb6#ikcKz(iVEVyHP#mrGX_cy&OPQXX6*1vV@FKWm^hmwltw(_HO z(&1cc8MgnVheIGvAEZAm|nTgXe6 zPsKY?=iB9L6Qy$tJx6}~Ex1dpZ|Fcg`2A~*4ULqWx{2FV`NeAa(;mgIvL^rU-;j&z<&S;kYJnu literal 0 HcmV?d00001 diff --git a/examples/SmartSwitch/data_src/index.htm b/examples/SmartSwitch/data_src/index.htm new file mode 100644 index 000000000..44c86bfc0 --- /dev/null +++ b/examples/SmartSwitch/data_src/index.htm @@ -0,0 +1,585 @@ + + + + + + Smart Switch + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + +
+
+ + + + + + + + +
+ + + + + +
+
+ +
+
+
+ +
+
+
+ +
+
+
+
+
+ +
+
+ +
+
+
+
+ +
+
+ + + + + + + + \ No newline at end of file diff --git a/examples/SmartSwitch/data_src/js_css_src/.exclude.files b/examples/SmartSwitch/data_src/js_css_src/.exclude.files new file mode 100644 index 000000000..955397fa2 --- /dev/null +++ b/examples/SmartSwitch/data_src/js_css_src/.exclude.files @@ -0,0 +1,2 @@ +/*.js.gz +/.exclude.files diff --git a/examples/SmartSwitch/data_src/js_css_src/ace.js b/examples/SmartSwitch/data_src/js_css_src/ace.js new file mode 100644 index 000000000..f54ebb2e1 --- /dev/null +++ b/examples/SmartSwitch/data_src/js_css_src/ace.js @@ -0,0 +1,14 @@ +(function(){function o(n){var i=e;n&&(e[n]||(e[n]={}),i=e[n]);if(!i.define||!i.define.packaged)t.original=i.define,i.define=t,i.define.packaged=!0;if(!i.require||!i.require.packaged)r.original=i.require,i.require=r,i.require.packaged=!0}var ACE_NAMESPACE="",e=function(){return this}();!e&&typeof window!="undefined"&&(e=window);if(!ACE_NAMESPACE&&typeof requirejs!="undefined")return;var t=function(e,n,r){if(typeof e!="string"){t.original?t.original.apply(this,arguments):(console.error("dropping module because define wasn't a string."),console.trace());return}arguments.length==2&&(r=n),t.modules[e]||(t.payloads[e]=r,t.modules[e]=null)};t.modules={},t.payloads={};var n=function(e,t,n){if(typeof t=="string"){var i=s(e,t);if(i!=undefined)return n&&n(),i}else if(Object.prototype.toString.call(t)==="[object Array]"){var o=[];for(var u=0,a=t.length;u1&&u(t,"")>-1&&(a=RegExp(this.source,r.replace.call(o(this),"g","")),r.replace.call(e.slice(t.index),a,function(){for(var e=1;et.index&&this.lastIndex--}return t},s||(RegExp.prototype.test=function(e){var t=r.exec.call(this,e);return t&&this.global&&!t[0].length&&this.lastIndex>t.index&&this.lastIndex--,!!t})}),define("ace/lib/es5-shim",["require","exports","module"],function(e,t,n){function r(){}function w(e){try{return Object.defineProperty(e,"sentinel",{}),"sentinel"in e}catch(t){}}function H(e){return e=+e,e!==e?e=0:e!==0&&e!==1/0&&e!==-1/0&&(e=(e>0||-1)*Math.floor(Math.abs(e))),e}function B(e){var t=typeof e;return e===null||t==="undefined"||t==="boolean"||t==="number"||t==="string"}function j(e){var t,n,r;if(B(e))return e;n=e.valueOf;if(typeof n=="function"){t=n.call(e);if(B(t))return t}r=e.toString;if(typeof r=="function"){t=r.call(e);if(B(t))return t}throw new TypeError}Function.prototype.bind||(Function.prototype.bind=function(t){var n=this;if(typeof n!="function")throw new TypeError("Function.prototype.bind called on incompatible "+n);var i=u.call(arguments,1),s=function(){if(this instanceof s){var e=n.apply(this,i.concat(u.call(arguments)));return Object(e)===e?e:this}return n.apply(t,i.concat(u.call(arguments)))};return n.prototype&&(r.prototype=n.prototype,s.prototype=new r,r.prototype=null),s});var i=Function.prototype.call,s=Array.prototype,o=Object.prototype,u=s.slice,a=i.bind(o.toString),f=i.bind(o.hasOwnProperty),l,c,h,p,d;if(d=f(o,"__defineGetter__"))l=i.bind(o.__defineGetter__),c=i.bind(o.__defineSetter__),h=i.bind(o.__lookupGetter__),p=i.bind(o.__lookupSetter__);if([1,2].splice(0).length!=2)if(!function(){function e(e){var t=new Array(e+2);return t[0]=t[1]=0,t}var t=[],n;t.splice.apply(t,e(20)),t.splice.apply(t,e(26)),n=t.length,t.splice(5,0,"XXX"),n+1==t.length;if(n+1==t.length)return!0}())Array.prototype.splice=function(e,t){var n=this.length;e>0?e>n&&(e=n):e==void 0?e=0:e<0&&(e=Math.max(n+e,0)),e+ta)for(h=l;h--;)this[f+h]=this[a+h];if(s&&e===c)this.length=c,this.push.apply(this,i);else{this.length=c+s;for(h=0;h>>0;if(a(t)!="[object Function]")throw new TypeError;while(++s>>0,s=Array(i),o=arguments[1];if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");for(var u=0;u>>0,s=[],o,u=arguments[1];if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");for(var f=0;f>>0,s=arguments[1];if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");for(var o=0;o>>0,s=arguments[1];if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");for(var o=0;o>>0;if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");if(!i&&arguments.length==1)throw new TypeError("reduce of empty array with no initial value");var s=0,o;if(arguments.length>=2)o=arguments[1];else do{if(s in r){o=r[s++];break}if(++s>=i)throw new TypeError("reduce of empty array with no initial value")}while(!0);for(;s>>0;if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");if(!i&&arguments.length==1)throw new TypeError("reduceRight of empty array with no initial value");var s,o=i-1;if(arguments.length>=2)s=arguments[1];else do{if(o in r){s=r[o--];break}if(--o<0)throw new TypeError("reduceRight of empty array with no initial value")}while(!0);do o in this&&(s=t.call(void 0,s,r[o],o,n));while(o--);return s});if(!Array.prototype.indexOf||[0,1].indexOf(1,2)!=-1)Array.prototype.indexOf=function(t){var n=g&&a(this)=="[object String]"?this.split(""):F(this),r=n.length>>>0;if(!r)return-1;var i=0;arguments.length>1&&(i=H(arguments[1])),i=i>=0?i:Math.max(0,r+i);for(;i>>0;if(!r)return-1;var i=r-1;arguments.length>1&&(i=Math.min(i,H(arguments[1]))),i=i>=0?i:r-Math.abs(i);for(;i>=0;i--)if(i in n&&t===n[i])return i;return-1};Object.getPrototypeOf||(Object.getPrototypeOf=function(t){return t.__proto__||(t.constructor?t.constructor.prototype:o)});if(!Object.getOwnPropertyDescriptor){var y="Object.getOwnPropertyDescriptor called on a non-object: ";Object.getOwnPropertyDescriptor=function(t,n){if(typeof t!="object"&&typeof t!="function"||t===null)throw new TypeError(y+t);if(!f(t,n))return;var r,i,s;r={enumerable:!0,configurable:!0};if(d){var u=t.__proto__;t.__proto__=o;var i=h(t,n),s=p(t,n);t.__proto__=u;if(i||s)return i&&(r.get=i),s&&(r.set=s),r}return r.value=t[n],r}}Object.getOwnPropertyNames||(Object.getOwnPropertyNames=function(t){return Object.keys(t)});if(!Object.create){var b;Object.prototype.__proto__===null?b=function(){return{__proto__:null}}:b=function(){var e={};for(var t in e)e[t]=null;return e.constructor=e.hasOwnProperty=e.propertyIsEnumerable=e.isPrototypeOf=e.toLocaleString=e.toString=e.valueOf=e.__proto__=null,e},Object.create=function(t,n){var r;if(t===null)r=b();else{if(typeof t!="object")throw new TypeError("typeof prototype["+typeof t+"] != 'object'");var i=function(){};i.prototype=t,r=new i,r.__proto__=t}return n!==void 0&&Object.defineProperties(r,n),r}}if(Object.defineProperty){var E=w({}),S=typeof document=="undefined"||w(document.createElement("div"));if(!E||!S)var x=Object.defineProperty}if(!Object.defineProperty||x){var T="Property description must be an object: ",N="Object.defineProperty called on non-object: ",C="getters & setters can not be defined on this javascript engine";Object.defineProperty=function(t,n,r){if(typeof t!="object"&&typeof t!="function"||t===null)throw new TypeError(N+t);if(typeof r!="object"&&typeof r!="function"||r===null)throw new TypeError(T+r);if(x)try{return x.call(Object,t,n,r)}catch(i){}if(f(r,"value"))if(d&&(h(t,n)||p(t,n))){var s=t.__proto__;t.__proto__=o,delete t[n],t[n]=r.value,t.__proto__=s}else t[n]=r.value;else{if(!d)throw new TypeError(C);f(r,"get")&&l(t,n,r.get),f(r,"set")&&c(t,n,r.set)}return t}}Object.defineProperties||(Object.defineProperties=function(t,n){for(var r in n)f(n,r)&&Object.defineProperty(t,r,n[r]);return t}),Object.seal||(Object.seal=function(t){return t}),Object.freeze||(Object.freeze=function(t){return t});try{Object.freeze(function(){})}catch(k){Object.freeze=function(t){return function(n){return typeof n=="function"?n:t(n)}}(Object.freeze)}Object.preventExtensions||(Object.preventExtensions=function(t){return t}),Object.isSealed||(Object.isSealed=function(t){return!1}),Object.isFrozen||(Object.isFrozen=function(t){return!1}),Object.isExtensible||(Object.isExtensible=function(t){if(Object(t)===t)throw new TypeError;var n="";while(f(t,n))n+="?";t[n]=!0;var r=f(t,n);return delete t[n],r});if(!Object.keys){var L=!0,A=["toString","toLocaleString","valueOf","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","constructor"],O=A.length;for(var M in{toString:null})L=!1;Object.keys=function I(e){if(typeof e!="object"&&typeof e!="function"||e===null)throw new TypeError("Object.keys called on a non-object");var I=[];for(var t in e)f(e,t)&&I.push(t);if(L)for(var n=0,r=O;n=0?parseFloat((i.match(/(?:MSIE |Trident\/[0-9]+[\.0-9]+;.*rv:)([0-9]+[\.0-9]+)/)||[])[1]):parseFloat((i.match(/(?:Trident\/[0-9]+[\.0-9]+;.*rv:)([0-9]+[\.0-9]+)/)||[])[1]),t.isOldIE=t.isIE&&t.isIE<9,t.isGecko=t.isMozilla=(window.Controllers||window.controllers)&&window.navigator.product==="Gecko",t.isOldGecko=t.isGecko&&parseInt((i.match(/rv:(\d+)/)||[])[1],10)<4,t.isOpera=window.opera&&Object.prototype.toString.call(window.opera)=="[object Opera]",t.isWebKit=parseFloat(i.split("WebKit/")[1])||undefined,t.isChrome=parseFloat(i.split(" Chrome/")[1])||undefined,t.isAIR=i.indexOf("AdobeAIR")>=0,t.isIPad=i.indexOf("iPad")>=0,t.isTouchPad=i.indexOf("TouchPad")>=0,t.isChromeOS=i.indexOf(" CrOS ")>=0}),define("ace/lib/event",["require","exports","module","ace/lib/keys","ace/lib/useragent"],function(e,t,n){"use strict";function a(e,t,n){var a=u(t);if(!i.isMac&&s){t.getModifierState&&(t.getModifierState("OS")||t.getModifierState("Win"))&&(a|=8);if(s.altGr){if((3&a)==3)return;s.altGr=0}if(n===18||n===17){var f="location"in t?t.location:t.keyLocation;if(n===17&&f===1)s[n]==1&&(o=t.timeStamp);else if(n===18&&a===3&&f===2){var l=t.timeStamp-o;l<50&&(s.altGr=!0)}}}n in r.MODIFIER_KEYS&&(n=-1),a&8&&n>=91&&n<=93&&(n=-1);if(!a&&n===13){var f="location"in t?t.location:t.keyLocation;if(f===3){e(t,a,-n);if(t.defaultPrevented)return}}if(i.isChromeOS&&a&8){e(t,a,n);if(t.defaultPrevented)return;a&=-9}return!!a||n in r.FUNCTION_KEYS||n in r.PRINTABLE_KEYS?e(t,a,n):!1}function f(){s=Object.create(null)}var r=e("./keys"),i=e("./useragent"),s=null,o=0;t.addListener=function(e,t,n){if(e.addEventListener)return e.addEventListener(t,n,!1);if(e.attachEvent){var r=function(){n.call(e,window.event)};n._wrapper=r,e.attachEvent("on"+t,r)}},t.removeListener=function(e,t,n){if(e.removeEventListener)return e.removeEventListener(t,n,!1);e.detachEvent&&e.detachEvent("on"+t,n._wrapper||n)},t.stopEvent=function(e){return t.stopPropagation(e),t.preventDefault(e),!1},t.stopPropagation=function(e){e.stopPropagation?e.stopPropagation():e.cancelBubble=!0},t.preventDefault=function(e){e.preventDefault?e.preventDefault():e.returnValue=!1},t.getButton=function(e){return e.type=="dblclick"?0:e.type=="contextmenu"||i.isMac&&e.ctrlKey&&!e.altKey&&!e.shiftKey?2:e.preventDefault?e.button:{1:0,2:2,4:1}[e.button]},t.capture=function(e,n,r){function i(e){n&&n(e),r&&r(e),t.removeListener(document,"mousemove",n,!0),t.removeListener(document,"mouseup",i,!0),t.removeListener(document,"dragstart",i,!0)}return t.addListener(document,"mousemove",n,!0),t.addListener(document,"mouseup",i,!0),t.addListener(document,"dragstart",i,!0),i},t.addTouchMoveListener=function(e,n){if("ontouchmove"in e){var r,i;t.addListener(e,"touchstart",function(e){var t=e.changedTouches[0];r=t.clientX,i=t.clientY}),t.addListener(e,"touchmove",function(e){var t=1,s=e.changedTouches[0];e.wheelX=-(s.clientX-r)/t,e.wheelY=-(s.clientY-i)/t,r=s.clientX,i=s.clientY,n(e)})}},t.addMouseWheelListener=function(e,n){"onmousewheel"in e?t.addListener(e,"mousewheel",function(e){var t=8;e.wheelDeltaX!==undefined?(e.wheelX=-e.wheelDeltaX/t,e.wheelY=-e.wheelDeltaY/t):(e.wheelX=0,e.wheelY=-e.wheelDelta/t),n(e)}):"onwheel"in e?t.addListener(e,"wheel",function(e){var t=.35;switch(e.deltaMode){case e.DOM_DELTA_PIXEL:e.wheelX=e.deltaX*t||0,e.wheelY=e.deltaY*t||0;break;case e.DOM_DELTA_LINE:case e.DOM_DELTA_PAGE:e.wheelX=(e.deltaX||0)*5,e.wheelY=(e.deltaY||0)*5}n(e)}):t.addListener(e,"DOMMouseScroll",function(e){e.axis&&e.axis==e.HORIZONTAL_AXIS?(e.wheelX=(e.detail||0)*5,e.wheelY=0):(e.wheelX=0,e.wheelY=(e.detail||0)*5),n(e)})},t.addMultiMouseDownListener=function(e,n,r,s){function c(e){t.getButton(e)!==0?o=0:e.detail>1?(o++,o>4&&(o=1)):o=1;if(i.isIE){var c=Math.abs(e.clientX-u)>5||Math.abs(e.clientY-a)>5;if(!f||c)o=1;f&&clearTimeout(f),f=setTimeout(function(){f=null},n[o-1]||600),o==1&&(u=e.clientX,a=e.clientY)}e._clicks=o,r[s]("mousedown",e);if(o>4)o=0;else if(o>1)return r[s](l[o],e)}function h(e){o=2,f&&clearTimeout(f),f=setTimeout(function(){f=null},n[o-1]||600),r[s]("mousedown",e),r[s](l[o],e)}var o=0,u,a,f,l={2:"dblclick",3:"tripleclick",4:"quadclick"};Array.isArray(e)||(e=[e]),e.forEach(function(e){t.addListener(e,"mousedown",c),i.isOldIE&&t.addListener(e,"dblclick",h)})};var u=!i.isMac||!i.isOpera||"KeyboardEvent"in window?function(e){return 0|(e.ctrlKey?1:0)|(e.altKey?2:0)|(e.shiftKey?4:0)|(e.metaKey?8:0)}:function(e){return 0|(e.metaKey?1:0)|(e.altKey?2:0)|(e.shiftKey?4:0)|(e.ctrlKey?8:0)};t.getModifierString=function(e){return r.KEY_MODS[u(e)]},t.addCommandKeyListener=function(e,n){var r=t.addListener;if(i.isOldGecko||i.isOpera&&!("KeyboardEvent"in window)){var o=null;r(e,"keydown",function(e){o=e.keyCode}),r(e,"keypress",function(e){return a(n,e,o)})}else{var u=null;r(e,"keydown",function(e){s[e.keyCode]=(s[e.keyCode]||0)+1;var t=a(n,e,e.keyCode);return u=e.defaultPrevented,t}),r(e,"keypress",function(e){u&&(e.ctrlKey||e.altKey||e.shiftKey||e.metaKey)&&(t.stopEvent(e),u=null)}),r(e,"keyup",function(e){s[e.keyCode]=null}),s||(f(),r(window,"focus",f))}};if(typeof window=="object"&&window.postMessage&&!i.isOldIE){var l=1;t.nextTick=function(e,n){n=n||window;var r="zero-timeout-message-"+l;t.addListener(n,"message",function i(s){s.data==r&&(t.stopPropagation(s),t.removeListener(n,"message",i),e())}),n.postMessage(r,"*")}}t.nextFrame=typeof window=="object"&&(window.requestAnimationFrame||window.mozRequestAnimationFrame||window.webkitRequestAnimationFrame||window.msRequestAnimationFrame||window.oRequestAnimationFrame),t.nextFrame?t.nextFrame=t.nextFrame.bind(window):t.nextFrame=function(e){setTimeout(e,17)}}),define("ace/lib/lang",["require","exports","module"],function(e,t,n){"use strict";t.last=function(e){return e[e.length-1]},t.stringReverse=function(e){return e.split("").reverse().join("")},t.stringRepeat=function(e,t){var n="";while(t>0){t&1&&(n+=e);if(t>>=1)e+=e}return n};var r=/^\s\s*/,i=/\s\s*$/;t.stringTrimLeft=function(e){return e.replace(r,"")},t.stringTrimRight=function(e){return e.replace(i,"")},t.copyObject=function(e){var t={};for(var n in e)t[n]=e[n];return t},t.copyArray=function(e){var t=[];for(var n=0,r=e.length;n=53&&O()},I=o.delayedCall(j,50);r.addListener(n,"compositionstart",B),i.isGecko?r.addListener(n,"text",function(){I.schedule()}):(r.addListener(n,"keyup",function(){I.schedule()}),r.addListener(n,"keydown",function(){I.schedule()})),r.addListener(n,"compositionend",F),this.getElement=function(){return n},this.setReadOnly=function(e){n.readOnly=e},this.onContextMenu=function(e){L=!0,b(t.selection.isEmpty()),t._emit("nativecontextmenu",{target:t,domEvent:e}),this.moveToMouse(e,!0)},this.moveToMouse=function(e,o){if(!o&&i.isOldIE)return;p||(p=n.style.cssText),n.style.cssText=(o?"z-index:100000;":"")+"height:"+n.style.height+";"+(i.isIE?"opacity:0.1;":"");var u=t.container.getBoundingClientRect(),a=s.computedStyle(t.container),f=u.top+(parseInt(a.borderTopWidth)||0),l=u.left+(parseInt(u.borderLeftWidth)||0),c=u.bottom-f-n.clientHeight-2,h=function(e){n.style.left=e.clientX-l-2+"px",n.style.top=Math.min(e.clientY-f-2,c)+"px"};h(e);if(e.type!="mousedown")return;t.renderer.$keepTextAreaAtCursor&&(t.renderer.$keepTextAreaAtCursor=null),clearTimeout(q),i.isWin&&!i.isOldIE&&r.capture(t.container,h,R)},this.onContextMenuClose=R;var q,U=function(e){t.textInput.onContextMenu(e),R()};r.addListener(n,"mouseup",U),r.addListener(n,"mousedown",function(e){e.preventDefault(),R()}),r.addListener(t.renderer.scroller,"contextmenu",U),r.addListener(n,"contextmenu",U)};t.TextInput=f}),define("ace/mouse/default_handlers",["require","exports","module","ace/lib/dom","ace/lib/event","ace/lib/useragent"],function(e,t,n){"use strict";function u(e){e.$clickSelection=null;var t=e.editor;t.setDefaultHandler("mousedown",this.onMouseDown.bind(e)),t.setDefaultHandler("dblclick",this.onDoubleClick.bind(e)),t.setDefaultHandler("tripleclick",this.onTripleClick.bind(e)),t.setDefaultHandler("quadclick",this.onQuadClick.bind(e)),t.setDefaultHandler("mousewheel",this.onMouseWheel.bind(e)),t.setDefaultHandler("touchmove",this.onTouchMove.bind(e));var n=["select","startSelect","selectEnd","selectAllEnd","selectByWordsEnd","selectByLinesEnd","dragWait","dragWaitEnd","focusWait"];n.forEach(function(t){e[t]=this[t]},this),e.selectByLines=this.extendSelectionBy.bind(e,"getLineRange"),e.selectByWords=this.extendSelectionBy.bind(e,"getWordRange")}function a(e,t,n,r){return Math.sqrt(Math.pow(n-e,2)+Math.pow(r-t,2))}function f(e,t){if(e.start.row==e.end.row)var n=2*t.column-e.start.column-e.end.column;else if(e.start.row==e.end.row-1&&!e.start.column&&!e.end.column)var n=t.column-4;else var n=2*t.row-e.start.row-e.end.row;return n<0?{cursor:e.start,anchor:e.end}:{cursor:e.end,anchor:e.start}}var r=e("../lib/dom"),i=e("../lib/event"),s=e("../lib/useragent"),o=0;(function(){this.onMouseDown=function(e){var t=e.inSelection(),n=e.getDocumentPosition();this.mousedownEvent=e;var r=this.editor,i=e.getButton();if(i!==0){var s=r.getSelectionRange(),o=s.isEmpty();r.$blockScrolling++,(o||i==1)&&r.selection.moveToPosition(n),r.$blockScrolling--,i==2&&r.textInput.onContextMenu(e.domEvent);return}this.mousedownEvent.time=Date.now();if(t&&!r.isFocused()){r.focus();if(this.$focusTimout&&!this.$clickSelection&&!r.inMultiSelectMode){this.setState("focusWait"),this.captureMouse(e);return}}return this.captureMouse(e),this.startSelect(n,e.domEvent._clicks>1),e.preventDefault()},this.startSelect=function(e,t){e=e||this.editor.renderer.screenToTextCoordinates(this.x,this.y);var n=this.editor;n.$blockScrolling++,this.mousedownEvent.getShiftKey()?n.selection.selectToPosition(e):t||n.selection.moveToPosition(e),t||this.select(),n.renderer.scroller.setCapture&&n.renderer.scroller.setCapture(),n.setStyle("ace_selecting"),this.setState("select"),n.$blockScrolling--},this.select=function(){var e,t=this.editor,n=t.renderer.screenToTextCoordinates(this.x,this.y);t.$blockScrolling++;if(this.$clickSelection){var r=this.$clickSelection.comparePoint(n);if(r==-1)e=this.$clickSelection.end;else if(r==1)e=this.$clickSelection.start;else{var i=f(this.$clickSelection,n);n=i.cursor,e=i.anchor}t.selection.setSelectionAnchor(e.row,e.column)}t.selection.selectToPosition(n),t.$blockScrolling--,t.renderer.scrollCursorIntoView()},this.extendSelectionBy=function(e){var t,n=this.editor,r=n.renderer.screenToTextCoordinates(this.x,this.y),i=n.selection[e](r.row,r.column);n.$blockScrolling++;if(this.$clickSelection){var s=this.$clickSelection.comparePoint(i.start),o=this.$clickSelection.comparePoint(i.end);if(s==-1&&o<=0){t=this.$clickSelection.end;if(i.end.row!=r.row||i.end.column!=r.column)r=i.start}else if(o==1&&s>=0){t=this.$clickSelection.start;if(i.start.row!=r.row||i.start.column!=r.column)r=i.end}else if(s==-1&&o==1)r=i.end,t=i.start;else{var u=f(this.$clickSelection,r);r=u.cursor,t=u.anchor}n.selection.setSelectionAnchor(t.row,t.column)}n.selection.selectToPosition(r),n.$blockScrolling--,n.renderer.scrollCursorIntoView()},this.selectEnd=this.selectAllEnd=this.selectByWordsEnd=this.selectByLinesEnd=function(){this.$clickSelection=null,this.editor.unsetStyle("ace_selecting"),this.editor.renderer.scroller.releaseCapture&&this.editor.renderer.scroller.releaseCapture()},this.focusWait=function(){var e=a(this.mousedownEvent.x,this.mousedownEvent.y,this.x,this.y),t=Date.now();(e>o||t-this.mousedownEvent.time>this.$focusTimout)&&this.startSelect(this.mousedownEvent.getDocumentPosition())},this.onDoubleClick=function(e){var t=e.getDocumentPosition(),n=this.editor,r=n.session,i=r.getBracketRange(t);i?(i.isEmpty()&&(i.start.column--,i.end.column++),this.setState("select")):(i=n.selection.getWordRange(t.row,t.column),this.setState("selectByWords")),this.$clickSelection=i,this.select()},this.onTripleClick=function(e){var t=e.getDocumentPosition(),n=this.editor;this.setState("selectByLines");var r=n.getSelectionRange();r.isMultiLine()&&r.contains(t.row,t.column)?(this.$clickSelection=n.selection.getLineRange(r.start.row),this.$clickSelection.end=n.selection.getLineRange(r.end.row).end):this.$clickSelection=n.selection.getLineRange(t.row),this.select()},this.onQuadClick=function(e){var t=this.editor;t.selectAll(),this.$clickSelection=t.getSelectionRange(),this.setState("selectAll")},this.onMouseWheel=function(e){if(e.getAccelKey())return;e.getShiftKey()&&e.wheelY&&!e.wheelX&&(e.wheelX=e.wheelY,e.wheelY=0);var t=e.domEvent.timeStamp,n=t-(this.$lastScrollTime||0),r=this.editor,i=r.renderer.isScrollableBy(e.wheelX*e.speed,e.wheelY*e.speed);if(i||n<200)return this.$lastScrollTime=t,r.renderer.scrollBy(e.wheelX*e.speed,e.wheelY*e.speed),e.stop()},this.onTouchMove=function(e){var t=e.domEvent.timeStamp,n=t-(this.$lastScrollTime||0),r=this.editor,i=r.renderer.isScrollableBy(e.wheelX*e.speed,e.wheelY*e.speed);if(i||n<200)return this.$lastScrollTime=t,r.renderer.scrollBy(e.wheelX*e.speed,e.wheelY*e.speed),e.stop()}}).call(u.prototype),t.DefaultHandlers=u}),define("ace/tooltip",["require","exports","module","ace/lib/oop","ace/lib/dom"],function(e,t,n){"use strict";function s(e){this.isOpen=!1,this.$element=null,this.$parentNode=e}var r=e("./lib/oop"),i=e("./lib/dom");(function(){this.$init=function(){return this.$element=i.createElement("div"),this.$element.className="ace_tooltip",this.$element.style.display="none",this.$parentNode.appendChild(this.$element),this.$element},this.getElement=function(){return this.$element||this.$init()},this.setText=function(e){i.setInnerText(this.getElement(),e)},this.setHtml=function(e){this.getElement().innerHTML=e},this.setPosition=function(e,t){this.getElement().style.left=e+"px",this.getElement().style.top=t+"px"},this.setClassName=function(e){i.addCssClass(this.getElement(),e)},this.show=function(e,t,n){e!=null&&this.setText(e),t!=null&&n!=null&&this.setPosition(t,n),this.isOpen||(this.getElement().style.display="block",this.isOpen=!0)},this.hide=function(){this.isOpen&&(this.getElement().style.display="none",this.isOpen=!1)},this.getHeight=function(){return this.getElement().offsetHeight},this.getWidth=function(){return this.getElement().offsetWidth}}).call(s.prototype),t.Tooltip=s}),define("ace/mouse/default_gutter_handler",["require","exports","module","ace/lib/dom","ace/lib/oop","ace/lib/event","ace/tooltip"],function(e,t,n){"use strict";function u(e){function l(){var r=u.getDocumentPosition().row,s=n.$annotations[r];if(!s)return c();var o=t.session.getLength();if(r==o){var a=t.renderer.pixelToScreenCoordinates(0,u.y).row,l=u.$pos;if(a>t.session.documentToScreenRow(l.row,l.column))return c()}if(f==s)return;f=s.text.join("
"),i.setHtml(f),i.show(),t._signal("showGutterTooltip",i),t.on("mousewheel",c);if(e.$tooltipFollowsMouse)h(u);else{var p=u.domEvent.target,d=p.getBoundingClientRect(),v=i.getElement().style;v.left=d.right+"px",v.top=d.bottom+"px"}}function c(){o&&(o=clearTimeout(o)),f&&(i.hide(),f=null,t._signal("hideGutterTooltip",i),t.removeEventListener("mousewheel",c))}function h(e){i.setPosition(e.x,e.y)}var t=e.editor,n=t.renderer.$gutterLayer,i=new a(t.container);e.editor.setDefaultHandler("guttermousedown",function(r){if(!t.isFocused()||r.getButton()!=0)return;var i=n.getRegion(r);if(i=="foldWidgets")return;var s=r.getDocumentPosition().row,o=t.session.selection;if(r.getShiftKey())o.selectTo(s,0);else{if(r.domEvent.detail==2)return t.selectAll(),r.preventDefault();e.$clickSelection=t.selection.getLineRange(s)}return e.setState("selectByLines"),e.captureMouse(r),r.preventDefault()});var o,u,f;e.editor.setDefaultHandler("guttermousemove",function(t){var n=t.domEvent.target||t.domEvent.srcElement;if(r.hasCssClass(n,"ace_fold-widget"))return c();f&&e.$tooltipFollowsMouse&&h(t),u=t;if(o)return;o=setTimeout(function(){o=null,u&&!e.isMousePressed?l():c()},50)}),s.addListener(t.renderer.$gutter,"mouseout",function(e){u=null;if(!f||o)return;o=setTimeout(function(){o=null,c()},50)}),t.on("changeSession",c)}function a(e){o.call(this,e)}var r=e("../lib/dom"),i=e("../lib/oop"),s=e("../lib/event"),o=e("../tooltip").Tooltip;i.inherits(a,o),function(){this.setPosition=function(e,t){var n=window.innerWidth||document.documentElement.clientWidth,r=window.innerHeight||document.documentElement.clientHeight,i=this.getWidth(),s=this.getHeight();e+=15,t+=15,e+i>n&&(e-=e+i-n),t+s>r&&(t-=20+s),o.prototype.setPosition.call(this,e,t)}}.call(a.prototype),t.GutterHandler=u}),define("ace/mouse/mouse_event",["require","exports","module","ace/lib/event","ace/lib/useragent"],function(e,t,n){"use strict";var r=e("../lib/event"),i=e("../lib/useragent"),s=t.MouseEvent=function(e,t){this.domEvent=e,this.editor=t,this.x=this.clientX=e.clientX,this.y=this.clientY=e.clientY,this.$pos=null,this.$inSelection=null,this.propagationStopped=!1,this.defaultPrevented=!1};(function(){this.stopPropagation=function(){r.stopPropagation(this.domEvent),this.propagationStopped=!0},this.preventDefault=function(){r.preventDefault(this.domEvent),this.defaultPrevented=!0},this.stop=function(){this.stopPropagation(),this.preventDefault()},this.getDocumentPosition=function(){return this.$pos?this.$pos:(this.$pos=this.editor.renderer.screenToTextCoordinates(this.clientX,this.clientY),this.$pos)},this.inSelection=function(){if(this.$inSelection!==null)return this.$inSelection;var e=this.editor,t=e.getSelectionRange();if(t.isEmpty())this.$inSelection=!1;else{var n=this.getDocumentPosition();this.$inSelection=t.contains(n.row,n.column)}return this.$inSelection},this.getButton=function(){return r.getButton(this.domEvent)},this.getShiftKey=function(){return this.domEvent.shiftKey},this.getAccelKey=i.isMac?function(){return this.domEvent.metaKey}:function(){return this.domEvent.ctrlKey}}).call(s.prototype)}),define("ace/mouse/dragdrop_handler",["require","exports","module","ace/lib/dom","ace/lib/event","ace/lib/useragent"],function(e,t,n){"use strict";function f(e){function T(e,n){var r=Date.now(),i=!n||e.row!=n.row,s=!n||e.column!=n.column;if(!S||i||s)t.$blockScrolling+=1,t.moveCursorToPosition(e),t.$blockScrolling-=1,S=r,x={x:p,y:d};else{var o=l(x.x,x.y,p,d);o>a?S=null:r-S>=u&&(t.renderer.scrollCursorIntoView(),S=null)}}function N(e,n){var r=Date.now(),i=t.renderer.layerConfig.lineHeight,s=t.renderer.layerConfig.characterWidth,u=t.renderer.scroller.getBoundingClientRect(),a={x:{left:p-u.left,right:u.right-p},y:{top:d-u.top,bottom:u.bottom-d}},f=Math.min(a.x.left,a.x.right),l=Math.min(a.y.top,a.y.bottom),c={row:e.row,column:e.column};f/s<=2&&(c.column+=a.x.left=o&&t.renderer.scrollCursorIntoView(c):E=r:E=null}function C(){var e=g;g=t.renderer.screenToTextCoordinates(p,d),T(g,e),N(g,e)}function k(){m=t.selection.toOrientedRange(),h=t.session.addMarker(m,"ace_selection",t.getSelectionStyle()),t.clearSelection(),t.isFocused()&&t.renderer.$cursorLayer.setBlinking(!1),clearInterval(v),C(),v=setInterval(C,20),y=0,i.addListener(document,"mousemove",O)}function L(){clearInterval(v),t.session.removeMarker(h),h=null,t.$blockScrolling+=1,t.selection.fromOrientedRange(m),t.$blockScrolling-=1,t.isFocused()&&!w&&t.renderer.$cursorLayer.setBlinking(!t.getReadOnly()),m=null,g=null,y=0,E=null,S=null,i.removeListener(document,"mousemove",O)}function O(){A==null&&(A=setTimeout(function(){A!=null&&h&&L()},20))}function M(e){var t=e.types;return!t||Array.prototype.some.call(t,function(e){return e=="text/plain"||e=="Text"})}function _(e){var t=["copy","copymove","all","uninitialized"],n=["move","copymove","linkmove","all","uninitialized"],r=s.isMac?e.altKey:e.ctrlKey,i="uninitialized";try{i=e.dataTransfer.effectAllowed.toLowerCase()}catch(e){}var o="none";return r&&t.indexOf(i)>=0?o="copy":n.indexOf(i)>=0?o="move":t.indexOf(i)>=0&&(o="copy"),o}var t=e.editor,n=r.createElement("img");n.src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==",s.isOpera&&(n.style.cssText="width:1px;height:1px;position:fixed;top:0;left:0;z-index:2147483647;opacity:0;");var f=["dragWait","dragWaitEnd","startDrag","dragReadyEnd","onMouseDrag"];f.forEach(function(t){e[t]=this[t]},this),t.addEventListener("mousedown",this.onMouseDown.bind(e));var c=t.container,h,p,d,v,m,g,y=0,b,w,E,S,x;this.onDragStart=function(e){if(this.cancelDrag||!c.draggable){var r=this;return setTimeout(function(){r.startSelect(),r.captureMouse(e)},0),e.preventDefault()}m=t.getSelectionRange();var i=e.dataTransfer;i.effectAllowed=t.getReadOnly()?"copy":"copyMove",s.isOpera&&(t.container.appendChild(n),n.scrollTop=0),i.setDragImage&&i.setDragImage(n,0,0),s.isOpera&&t.container.removeChild(n),i.clearData(),i.setData("Text",t.session.getTextRange()),w=!0,this.setState("drag")},this.onDragEnd=function(e){c.draggable=!1,w=!1,this.setState(null);if(!t.getReadOnly()){var n=e.dataTransfer.dropEffect;!b&&n=="move"&&t.session.remove(t.getSelectionRange()),t.renderer.$cursorLayer.setBlinking(!0)}this.editor.unsetStyle("ace_dragging"),this.editor.renderer.setCursorStyle("")},this.onDragEnter=function(e){if(t.getReadOnly()||!M(e.dataTransfer))return;return p=e.clientX,d=e.clientY,h||k(),y++,e.dataTransfer.dropEffect=b=_(e),i.preventDefault(e)},this.onDragOver=function(e){if(t.getReadOnly()||!M(e.dataTransfer))return;return p=e.clientX,d=e.clientY,h||(k(),y++),A!==null&&(A=null),e.dataTransfer.dropEffect=b=_(e),i.preventDefault(e)},this.onDragLeave=function(e){y--;if(y<=0&&h)return L(),b=null,i.preventDefault(e)},this.onDrop=function(e){if(!g)return;var n=e.dataTransfer;if(w)switch(b){case"move":m.contains(g.row,g.column)?m={start:g,end:g}:m=t.moveText(m,g);break;case"copy":m=t.moveText(m,g,!0)}else{var r=n.getData("Text");m={start:g,end:t.session.insert(g,r)},t.focus(),b=null}return L(),i.preventDefault(e)},i.addListener(c,"dragstart",this.onDragStart.bind(e)),i.addListener(c,"dragend",this.onDragEnd.bind(e)),i.addListener(c,"dragenter",this.onDragEnter.bind(e)),i.addListener(c,"dragover",this.onDragOver.bind(e)),i.addListener(c,"dragleave",this.onDragLeave.bind(e)),i.addListener(c,"drop",this.onDrop.bind(e));var A=null}function l(e,t,n,r){return Math.sqrt(Math.pow(n-e,2)+Math.pow(r-t,2))}var r=e("../lib/dom"),i=e("../lib/event"),s=e("../lib/useragent"),o=200,u=200,a=5;(function(){this.dragWait=function(){var e=Date.now()-this.mousedownEvent.time;e>this.editor.getDragDelay()&&this.startDrag()},this.dragWaitEnd=function(){var e=this.editor.container;e.draggable=!1,this.startSelect(this.mousedownEvent.getDocumentPosition()),this.selectEnd()},this.dragReadyEnd=function(e){this.editor.renderer.$cursorLayer.setBlinking(!this.editor.getReadOnly()),this.editor.unsetStyle("ace_dragging"),this.editor.renderer.setCursorStyle(""),this.dragWaitEnd()},this.startDrag=function(){this.cancelDrag=!1;var e=this.editor,t=e.container;t.draggable=!0,e.renderer.$cursorLayer.setBlinking(!1),e.setStyle("ace_dragging");var n=s.isWin?"default":"move";e.renderer.setCursorStyle(n),this.setState("dragReady")},this.onMouseDrag=function(e){var t=this.editor.container;if(s.isIE&&this.state=="dragReady"){var n=l(this.mousedownEvent.x,this.mousedownEvent.y,this.x,this.y);n>3&&t.dragDrop()}if(this.state==="dragWait"){var n=l(this.mousedownEvent.x,this.mousedownEvent.y,this.x,this.y);n>0&&(t.draggable=!1,this.startSelect(this.mousedownEvent.getDocumentPosition()))}},this.onMouseDown=function(e){if(!this.$dragEnabled)return;this.mousedownEvent=e;var t=this.editor,n=e.inSelection(),r=e.getButton(),i=e.domEvent.detail||1;if(i===1&&r===0&&n){if(e.editor.inMultiSelectMode&&(e.getAccelKey()||e.getShiftKey()))return;this.mousedownEvent.time=Date.now();var o=e.domEvent.target||e.domEvent.srcElement;"unselectable"in o&&(o.unselectable="on");if(t.getDragDelay()){if(s.isWebKit){this.cancelDrag=!0;var u=t.container;u.draggable=!0}this.setState("dragWait")}else this.startDrag();this.captureMouse(e,this.onMouseDrag.bind(this)),e.defaultPrevented=!0}}}).call(f.prototype),t.DragdropHandler=f}),define("ace/lib/net",["require","exports","module","ace/lib/dom"],function(e,t,n){"use strict";var r=e("./dom");t.get=function(e,t){var n=new XMLHttpRequest;n.open("GET",e,!0),n.onreadystatechange=function(){n.readyState===4&&t(n.responseText)},n.send(null)},t.loadScript=function(e,t){var n=r.getDocumentHead(),i=document.createElement("script");i.src=e,n.appendChild(i),i.onload=i.onreadystatechange=function(e,n){if(n||!i.readyState||i.readyState=="loaded"||i.readyState=="complete")i=i.onload=i.onreadystatechange=null,n||t()}},t.qualifyURL=function(e){var t=document.createElement("a");return t.href=e,t.href}}),define("ace/lib/event_emitter",["require","exports","module"],function(e,t,n){"use strict";var r={},i=function(){this.propagationStopped=!0},s=function(){this.defaultPrevented=!0};r._emit=r._dispatchEvent=function(e,t){this._eventRegistry||(this._eventRegistry={}),this._defaultHandlers||(this._defaultHandlers={});var n=this._eventRegistry[e]||[],r=this._defaultHandlers[e];if(!n.length&&!r)return;if(typeof t!="object"||!t)t={};t.type||(t.type=e),t.stopPropagation||(t.stopPropagation=i),t.preventDefault||(t.preventDefault=s),n=n.slice();for(var o=0;o1&&(i=n[n.length-2]);var o=a[t+"Path"];return o==null?o=a.basePath:r=="/"&&(t=r=""),o&&o.slice(-1)!="/"&&(o+="/"),o+t+r+i+this.get("suffix")},t.setModuleUrl=function(e,t){return a.$moduleUrls[e]=t},t.$loading={},t.loadModule=function(n,r){var i,o;Array.isArray(n)&&(o=n[0],n=n[1]);try{i=e(n)}catch(u){}if(i&&!t.$loading[n])return r&&r(i);t.$loading[n]||(t.$loading[n]=[]),t.$loading[n].push(r);if(t.$loading[n].length>1)return;var a=function(){e([n],function(e){t._emit("load.module",{name:n,module:e});var r=t.$loading[n];t.$loading[n]=null,r.forEach(function(t){t&&t(e)})})};if(!t.get("packaged"))return a();s.loadScript(t.moduleUrl(n,o),a)},t.init=f}),define("ace/mouse/mouse_handler",["require","exports","module","ace/lib/event","ace/lib/useragent","ace/mouse/default_handlers","ace/mouse/default_gutter_handler","ace/mouse/mouse_event","ace/mouse/dragdrop_handler","ace/config"],function(e,t,n){"use strict";var r=e("../lib/event"),i=e("../lib/useragent"),s=e("./default_handlers").DefaultHandlers,o=e("./default_gutter_handler").GutterHandler,u=e("./mouse_event").MouseEvent,a=e("./dragdrop_handler").DragdropHandler,f=e("../config"),l=function(e){var t=this;this.editor=e,new s(this),new o(this),new a(this);var n=function(t){var n=!document.hasFocus||!document.hasFocus()||!e.isFocused()&&document.activeElement==(e.textInput&&e.textInput.getElement());n&&window.focus(),e.focus()},u=e.renderer.getMouseEventTarget();r.addListener(u,"click",this.onMouseEvent.bind(this,"click")),r.addListener(u,"mousemove",this.onMouseMove.bind(this,"mousemove")),r.addMultiMouseDownListener([u,e.renderer.scrollBarV&&e.renderer.scrollBarV.inner,e.renderer.scrollBarH&&e.renderer.scrollBarH.inner,e.textInput&&e.textInput.getElement()].filter(Boolean),[400,300,250],this,"onMouseEvent"),r.addMouseWheelListener(e.container,this.onMouseWheel.bind(this,"mousewheel")),r.addTouchMoveListener(e.container,this.onTouchMove.bind(this,"touchmove"));var f=e.renderer.$gutter;r.addListener(f,"mousedown",this.onMouseEvent.bind(this,"guttermousedown")),r.addListener(f,"click",this.onMouseEvent.bind(this,"gutterclick")),r.addListener(f,"dblclick",this.onMouseEvent.bind(this,"gutterdblclick")),r.addListener(f,"mousemove",this.onMouseEvent.bind(this,"guttermousemove")),r.addListener(u,"mousedown",n),r.addListener(f,"mousedown",n),i.isIE&&e.renderer.scrollBarV&&(r.addListener(e.renderer.scrollBarV.element,"mousedown",n),r.addListener(e.renderer.scrollBarH.element,"mousedown",n)),e.on("mousemove",function(n){if(t.state||t.$dragDelay||!t.$dragEnabled)return;var r=e.renderer.screenToTextCoordinates(n.x,n.y),i=e.session.selection.getRange(),s=e.renderer;!i.isEmpty()&&i.insideStart(r.row,r.column)?s.setCursorStyle("default"):s.setCursorStyle("")})};(function(){this.onMouseEvent=function(e,t){this.editor._emit(e,new u(t,this.editor))},this.onMouseMove=function(e,t){var n=this.editor._eventRegistry&&this.editor._eventRegistry.mousemove;if(!n||!n.length)return;this.editor._emit(e,new u(t,this.editor))},this.onMouseWheel=function(e,t){var n=new u(t,this.editor);n.speed=this.$scrollSpeed*2,n.wheelX=t.wheelX,n.wheelY=t.wheelY,this.editor._emit(e,n)},this.onTouchMove=function(e,t){var n=new u(t,this.editor);n.speed=1,n.wheelX=t.wheelX,n.wheelY=t.wheelY,this.editor._emit(e,n)},this.setState=function(e){this.state=e},this.captureMouse=function(e,t){this.x=e.x,this.y=e.y,this.isMousePressed=!0;var n=this.editor.renderer;n.$keepTextAreaAtCursor&&(n.$keepTextAreaAtCursor=null);var s=this,o=function(e){if(!e)return;if(i.isWebKit&&!e.which&&s.releaseMouse)return s.releaseMouse();s.x=e.clientX,s.y=e.clientY,t&&t(e),s.mouseEvent=new u(e,s.editor),s.$mouseMoved=!0},a=function(e){clearInterval(l),f(),s[s.state+"End"]&&s[s.state+"End"](e),s.state="",n.$keepTextAreaAtCursor==null&&(n.$keepTextAreaAtCursor=!0,n.$moveTextAreaToCursor()),s.isMousePressed=!1,s.$onCaptureMouseMove=s.releaseMouse=null,e&&s.onMouseEvent("mouseup",e)},f=function(){s[s.state]&&s[s.state](),s.$mouseMoved=!1};if(i.isOldIE&&e.domEvent.type=="dblclick")return setTimeout(function(){a(e)});s.$onCaptureMouseMove=o,s.releaseMouse=r.capture(this.editor.container,o,a);var l=setInterval(f,20)},this.releaseMouse=null,this.cancelContextMenu=function(){var e=function(t){if(t&&t.domEvent&&t.domEvent.type!="contextmenu")return;this.editor.off("nativecontextmenu",e),t&&t.domEvent&&r.stopEvent(t.domEvent)}.bind(this);setTimeout(e,10),this.editor.on("nativecontextmenu",e)}}).call(l.prototype),f.defineOptions(l.prototype,"mouseHandler",{scrollSpeed:{initialValue:2},dragDelay:{initialValue:i.isMac?150:0},dragEnabled:{initialValue:!0},focusTimout:{initialValue:0},tooltipFollowsMouse:{initialValue:!0}}),t.MouseHandler=l}),define("ace/mouse/fold_handler",["require","exports","module"],function(e,t,n){"use strict";function r(e){e.on("click",function(t){var n=t.getDocumentPosition(),r=e.session,i=r.getFoldAt(n.row,n.column,1);i&&(t.getAccelKey()?r.removeFold(i):r.expandFold(i),t.stop())}),e.on("gutterclick",function(t){var n=e.renderer.$gutterLayer.getRegion(t);if(n=="foldWidgets"){var r=t.getDocumentPosition().row,i=e.session;i.foldWidgets&&i.foldWidgets[r]&&e.session.onFoldWidgetClick(r,t),e.isFocused()||e.focus(),t.stop()}}),e.on("gutterdblclick",function(t){var n=e.renderer.$gutterLayer.getRegion(t);if(n=="foldWidgets"){var r=t.getDocumentPosition().row,i=e.session,s=i.getParentFoldRangeData(r,!0),o=s.range||s.firstRange;if(o){r=o.start.row;var u=i.getFoldAt(r,i.getLine(r).length,1);u?i.removeFold(u):(i.addFold("...",o),e.renderer.scrollCursorIntoView({row:o.start.row,column:0}))}t.stop()}})}t.FoldHandler=r}),define("ace/keyboard/keybinding",["require","exports","module","ace/lib/keys","ace/lib/event"],function(e,t,n){"use strict";var r=e("../lib/keys"),i=e("../lib/event"),s=function(e){this.$editor=e,this.$data={editor:e},this.$handlers=[],this.setDefaultHandler(e.commands)};(function(){this.setDefaultHandler=function(e){this.removeKeyboardHandler(this.$defaultHandler),this.$defaultHandler=e,this.addKeyboardHandler(e,0)},this.setKeyboardHandler=function(e){var t=this.$handlers;if(t[t.length-1]==e)return;while(t[t.length-1]&&t[t.length-1]!=this.$defaultHandler)this.removeKeyboardHandler(t[t.length-1]);this.addKeyboardHandler(e,1)},this.addKeyboardHandler=function(e,t){if(!e)return;typeof e=="function"&&!e.handleKeyboard&&(e.handleKeyboard=e);var n=this.$handlers.indexOf(e);n!=-1&&this.$handlers.splice(n,1),t==undefined?this.$handlers.push(e):this.$handlers.splice(t,0,e),n==-1&&e.attach&&e.attach(this.$editor)},this.removeKeyboardHandler=function(e){var t=this.$handlers.indexOf(e);return t==-1?!1:(this.$handlers.splice(t,1),e.detach&&e.detach(this.$editor),!0)},this.getKeyboardHandler=function(){return this.$handlers[this.$handlers.length-1]},this.getStatusText=function(){var e=this.$data,t=e.editor;return this.$handlers.map(function(n){return n.getStatusText&&n.getStatusText(t,e)||""}).filter(Boolean).join(" ")},this.$callKeyboardHandlers=function(e,t,n,r){var s,o=!1,u=this.$editor.commands;for(var a=this.$handlers.length;a--;){s=this.$handlers[a].handleKeyboard(this.$data,e,t,n,r);if(!s||!s.command)continue;s.command=="null"?o=!0:o=u.exec(s.command,this.$editor,s.args,r),o&&r&&e!=-1&&s.passEvent!=1&&s.command.passEvent!=1&&i.stopEvent(r);if(o)break}return!o&&e==-1&&(s={command:"insertstring"},o=u.exec("insertstring",this.$editor,t)),o&&this.$editor._signal&&this.$editor._signal("keyboardActivity",s),o},this.onCommandKey=function(e,t,n){var i=r.keyCodeToString(n);this.$callKeyboardHandlers(t,i,n,e)},this.onTextInput=function(e){this.$callKeyboardHandlers(-1,e)}}).call(s.prototype),t.KeyBinding=s}),define("ace/range",["require","exports","module"],function(e,t,n){"use strict";var r=function(e,t){return e.row-t.row||e.column-t.column},i=function(e,t,n,r){this.start={row:e,column:t},this.end={row:n,column:r}};(function(){this.isEqual=function(e){return this.start.row===e.start.row&&this.end.row===e.end.row&&this.start.column===e.start.column&&this.end.column===e.end.column},this.toString=function(){return"Range: ["+this.start.row+"/"+this.start.column+"] -> ["+this.end.row+"/"+this.end.column+"]"},this.contains=function(e,t){return this.compare(e,t)==0},this.compareRange=function(e){var t,n=e.end,r=e.start;return t=this.compare(n.row,n.column),t==1?(t=this.compare(r.row,r.column),t==1?2:t==0?1:0):t==-1?-2:(t=this.compare(r.row,r.column),t==-1?-1:t==1?42:0)},this.comparePoint=function(e){return this.compare(e.row,e.column)},this.containsRange=function(e){return this.comparePoint(e.start)==0&&this.comparePoint(e.end)==0},this.intersects=function(e){var t=this.compareRange(e);return t==-1||t==0||t==1},this.isEnd=function(e,t){return this.end.row==e&&this.end.column==t},this.isStart=function(e,t){return this.start.row==e&&this.start.column==t},this.setStart=function(e,t){typeof e=="object"?(this.start.column=e.column,this.start.row=e.row):(this.start.row=e,this.start.column=t)},this.setEnd=function(e,t){typeof e=="object"?(this.end.column=e.column,this.end.row=e.row):(this.end.row=e,this.end.column=t)},this.inside=function(e,t){return this.compare(e,t)==0?this.isEnd(e,t)||this.isStart(e,t)?!1:!0:!1},this.insideStart=function(e,t){return this.compare(e,t)==0?this.isEnd(e,t)?!1:!0:!1},this.insideEnd=function(e,t){return this.compare(e,t)==0?this.isStart(e,t)?!1:!0:!1},this.compare=function(e,t){return!this.isMultiLine()&&e===this.start.row?tthis.end.column?1:0:ethis.end.row?1:this.start.row===e?t>=this.start.column?0:-1:this.end.row===e?t<=this.end.column?0:1:0},this.compareStart=function(e,t){return this.start.row==e&&this.start.column==t?-1:this.compare(e,t)},this.compareEnd=function(e,t){return this.end.row==e&&this.end.column==t?1:this.compare(e,t)},this.compareInside=function(e,t){return this.end.row==e&&this.end.column==t?1:this.start.row==e&&this.start.column==t?-1:this.compare(e,t)},this.clipRows=function(e,t){if(this.end.row>t)var n={row:t+1,column:0};else if(this.end.rowt)var r={row:t+1,column:0};else if(this.start.rowt.row||e.row==t.row&&e.column>t.column},this.getRange=function(){var e=this.anchor,t=this.lead;return this.isEmpty()?o.fromPoints(t,t):this.isBackwards()?o.fromPoints(t,e):o.fromPoints(e,t)},this.clearSelection=function(){this.$isEmpty||(this.$isEmpty=!0,this._emit("changeSelection"))},this.selectAll=function(){var e=this.doc.getLength()-1;this.setSelectionAnchor(0,0),this.moveCursorTo(e,this.doc.getLine(e).length)},this.setRange=this.setSelectionRange=function(e,t){t?(this.setSelectionAnchor(e.end.row,e.end.column),this.selectTo(e.start.row,e.start.column)):(this.setSelectionAnchor(e.start.row,e.start.column),this.selectTo(e.end.row,e.end.column)),this.getRange().isEmpty()&&(this.$isEmpty=!0),this.$desiredColumn=null},this.$moveSelection=function(e){var t=this.lead;this.$isEmpty&&this.setSelectionAnchor(t.row,t.column),e.call(this)},this.selectTo=function(e,t){this.$moveSelection(function(){this.moveCursorTo(e,t)})},this.selectToPosition=function(e){this.$moveSelection(function(){this.moveCursorToPosition(e)})},this.moveTo=function(e,t){this.clearSelection(),this.moveCursorTo(e,t)},this.moveToPosition=function(e){this.clearSelection(),this.moveCursorToPosition(e)},this.selectUp=function(){this.$moveSelection(this.moveCursorUp)},this.selectDown=function(){this.$moveSelection(this.moveCursorDown)},this.selectRight=function(){this.$moveSelection(this.moveCursorRight)},this.selectLeft=function(){this.$moveSelection(this.moveCursorLeft)},this.selectLineStart=function(){this.$moveSelection(this.moveCursorLineStart)},this.selectLineEnd=function(){this.$moveSelection(this.moveCursorLineEnd)},this.selectFileEnd=function(){this.$moveSelection(this.moveCursorFileEnd)},this.selectFileStart=function(){this.$moveSelection(this.moveCursorFileStart)},this.selectWordRight=function(){this.$moveSelection(this.moveCursorWordRight)},this.selectWordLeft=function(){this.$moveSelection(this.moveCursorWordLeft)},this.getWordRange=function(e,t){if(typeof t=="undefined"){var n=e||this.lead;e=n.row,t=n.column}return this.session.getWordRange(e,t)},this.selectWord=function(){this.setSelectionRange(this.getWordRange())},this.selectAWord=function(){var e=this.getCursor(),t=this.session.getAWordRange(e.row,e.column);this.setSelectionRange(t)},this.getLineRange=function(e,t){var n=typeof e=="number"?e:this.lead.row,r,i=this.session.getFoldLine(n);return i?(n=i.start.row,r=i.end.row):r=n,t===!0?new o(n,0,r,this.session.getLine(r).length):new o(n,0,r+1,0)},this.selectLine=function(){this.setSelectionRange(this.getLineRange())},this.moveCursorUp=function(){this.moveCursorBy(-1,0)},this.moveCursorDown=function(){this.moveCursorBy(1,0)},this.moveCursorLeft=function(){var e=this.lead.getPosition(),t;if(t=this.session.getFoldAt(e.row,e.column,-1))this.moveCursorTo(t.start.row,t.start.column);else if(e.column===0)e.row>0&&this.moveCursorTo(e.row-1,this.doc.getLine(e.row-1).length);else{var n=this.session.getTabSize();this.session.isTabStop(e)&&this.doc.getLine(e.row).slice(e.column-n,e.column).split(" ").length-1==n?this.moveCursorBy(0,-n):this.moveCursorBy(0,-1)}},this.moveCursorRight=function(){var e=this.lead.getPosition(),t;if(t=this.session.getFoldAt(e.row,e.column,1))this.moveCursorTo(t.end.row,t.end.column);else if(this.lead.column==this.doc.getLine(this.lead.row).length)this.lead.row0&&(t.column=r)}}this.moveCursorTo(t.row,t.column)},this.moveCursorFileEnd=function(){var e=this.doc.getLength()-1,t=this.doc.getLine(e).length;this.moveCursorTo(e,t)},this.moveCursorFileStart=function(){this.moveCursorTo(0,0)},this.moveCursorLongWordRight=function(){var e=this.lead.row,t=this.lead.column,n=this.doc.getLine(e),r=n.substring(t),i;this.session.nonTokenRe.lastIndex=0,this.session.tokenRe.lastIndex=0;var s=this.session.getFoldAt(e,t,1);if(s){this.moveCursorTo(s.end.row,s.end.column);return}if(i=this.session.nonTokenRe.exec(r))t+=this.session.nonTokenRe.lastIndex,this.session.nonTokenRe.lastIndex=0,r=n.substring(t);if(t>=n.length){this.moveCursorTo(e,n.length),this.moveCursorRight(),e0&&this.moveCursorWordLeft();return}if(o=this.session.tokenRe.exec(s))t-=this.session.tokenRe.lastIndex,this.session.tokenRe.lastIndex=0;this.moveCursorTo(e,t)},this.$shortWordEndIndex=function(e){var t,n=0,r,i=/\s/,s=this.session.tokenRe;s.lastIndex=0;if(t=this.session.tokenRe.exec(e))n=this.session.tokenRe.lastIndex;else{while((r=e[n])&&i.test(r))n++;if(n<1){s.lastIndex=0;while((r=e[n])&&!s.test(r)){s.lastIndex=0,n++;if(i.test(r)){if(n>2){n--;break}while((r=e[n])&&i.test(r))n++;if(n>2)break}}}}return s.lastIndex=0,n},this.moveCursorShortWordRight=function(){var e=this.lead.row,t=this.lead.column,n=this.doc.getLine(e),r=n.substring(t),i=this.session.getFoldAt(e,t,1);if(i)return this.moveCursorTo(i.end.row,i.end.column);if(t==n.length){var s=this.doc.getLength();do e++,r=this.doc.getLine(e);while(e0&&/^\s*$/.test(r));t=r.length,/\s+$/.test(r)||(r="")}var s=i.stringReverse(r),o=this.$shortWordEndIndex(s);return this.moveCursorTo(e,t-o)},this.moveCursorWordRight=function(){this.session.$selectLongWords?this.moveCursorLongWordRight():this.moveCursorShortWordRight()},this.moveCursorWordLeft=function(){this.session.$selectLongWords?this.moveCursorLongWordLeft():this.moveCursorShortWordLeft()},this.moveCursorBy=function(e,t){var n=this.session.documentToScreenPosition(this.lead.row,this.lead.column);t===0&&(this.$desiredColumn?n.column=this.$desiredColumn:this.$desiredColumn=n.column);var r=this.session.screenToDocumentPosition(n.row+e,n.column);e!==0&&t===0&&r.row===this.lead.row&&r.column===this.lead.column&&this.session.lineWidgets&&this.session.lineWidgets[r.row]&&(r.row>0||e>0)&&r.row++,this.moveCursorTo(r.row,r.column+t,t===0)},this.moveCursorToPosition=function(e){this.moveCursorTo(e.row,e.column)},this.moveCursorTo=function(e,t,n){var r=this.session.getFoldAt(e,t,1);r&&(e=r.start.row,t=r.start.column),this.$keepDesiredColumnOnChange=!0,this.lead.setPosition(e,t),this.$keepDesiredColumnOnChange=!1,n||(this.$desiredColumn=null)},this.moveCursorToScreen=function(e,t,n){var r=this.session.screenToDocumentPosition(e,t);this.moveCursorTo(r.row,r.column,n)},this.detach=function(){this.lead.detach(),this.anchor.detach(),this.session=this.doc=null},this.fromOrientedRange=function(e){this.setSelectionRange(e,e.cursor==e.start),this.$desiredColumn=e.desiredColumn||this.$desiredColumn},this.toOrientedRange=function(e){var t=this.getRange();return e?(e.start.column=t.start.column,e.start.row=t.start.row,e.end.column=t.end.column,e.end.row=t.end.row):e=t,e.cursor=this.isBackwards()?e.start:e.end,e.desiredColumn=this.$desiredColumn,e},this.getRangeOfMovements=function(e){var t=this.getCursor();try{e(this);var n=this.getCursor();return o.fromPoints(t,n)}catch(r){return o.fromPoints(t,t)}finally{this.moveCursorToPosition(t)}},this.toJSON=function(){if(this.rangeCount)var e=this.ranges.map(function(e){var t=e.clone();return t.isBackwards=e.cursor==e.start,t});else{var e=this.getRange();e.isBackwards=this.isBackwards()}return e},this.fromJSON=function(e){if(e.start==undefined){if(this.rangeList){this.toSingleRange(e[0]);for(var t=e.length;t--;){var n=o.fromPoints(e[t].start,e[t].end);e[t].isBackwards&&(n.cursor=n.start),this.addRange(n,!0)}return}e=e[0]}this.rangeList&&this.toSingleRange(e),this.setSelectionRange(e,e.isBackwards)},this.isEqual=function(e){if((e.length||this.rangeCount)&&e.length!=this.rangeCount)return!1;if(!e.length||!this.ranges)return this.getRange().isEqual(e);for(var t=this.ranges.length;t--;)if(!this.ranges[t].isEqual(e[t]))return!1;return!0}}).call(u.prototype),t.Selection=u}),define("ace/tokenizer",["require","exports","module","ace/config"],function(e,t,n){"use strict";var r=e("./config"),i=2e3,s=function(e){this.states=e,this.regExps={},this.matchMappings={};for(var t in this.states){var n=this.states[t],r=[],i=0,s=this.matchMappings[t]={defaultToken:"text"},o="g",u=[];for(var a=0;a1?f.onMatch=this.$applyToken:f.onMatch=f.token),c>1&&(/\\\d/.test(f.regex)?l=f.regex.replace(/\\([0-9]+)/g,function(e,t){return"\\"+(parseInt(t,10)+i+1)}):(c=1,l=this.removeCapturingGroups(f.regex)),!f.splitRegex&&typeof f.token!="string"&&u.push(f)),s[i]=a,i+=c,r.push(l),f.onMatch||(f.onMatch=null)}r.length||(s[0]=0,r.push("$")),u.forEach(function(e){e.splitRegex=this.createSplitterRegexp(e.regex,o)},this),this.regExps[t]=new RegExp("("+r.join(")|(")+")|($)",o)}};(function(){this.$setMaxTokenCount=function(e){i=e|0},this.$applyToken=function(e){var t=this.splitRegex.exec(e).slice(1),n=this.token.apply(this,t);if(typeof n=="string")return[{type:n,value:e}];var r=[];for(var i=0,s=n.length;il){var g=e.substring(l,m-v.length);h.type==p?h.value+=g:(h.type&&f.push(h),h={type:p,value:g})}for(var y=0;yi){c>2*e.length&&this.reportError("infinite loop with in ace tokenizer",{startState:t,line:e});while(l1&&n[0]!==r&&n.unshift("#tmp",r),{tokens:f,state:n.length?n:r}},this.reportError=r.reportError}).call(s.prototype),t.Tokenizer=s}),define("ace/mode/text_highlight_rules",["require","exports","module","ace/lib/lang"],function(e,t,n){"use strict";var r=e("../lib/lang"),i=function(){this.$rules={start:[{token:"empty_line",regex:"^$"},{defaultToken:"text"}]}};(function(){this.addRules=function(e,t){if(!t){for(var n in e)this.$rules[n]=e[n];return}for(var n in e){var r=e[n];for(var i=0;i=this.$rowTokens.length){this.$row+=1,e||(e=this.$session.getLength());if(this.$row>=e)return this.$row=e-1,null;this.$rowTokens=this.$session.getTokens(this.$row),this.$tokenIndex=0}return this.$rowTokens[this.$tokenIndex]},this.getCurrentToken=function(){return this.$rowTokens[this.$tokenIndex]},this.getCurrentTokenRow=function(){return this.$row},this.getCurrentTokenColumn=function(){var e=this.$rowTokens,t=this.$tokenIndex,n=e[t].start;if(n!==undefined)return n;n=0;while(t>0)t-=1,n+=e[t].value.length;return n},this.getCurrentTokenPosition=function(){return{row:this.$row,column:this.getCurrentTokenColumn()}}}).call(r.prototype),t.TokenIterator=r}),define("ace/mode/behaviour/cstyle",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator","ace/lib/lang"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("../../token_iterator").TokenIterator,o=e("../../lib/lang"),u=["text","paren.rparen","punctuation.operator"],a=["text","paren.rparen","punctuation.operator","comment"],f,l={},c=function(e){var t=-1;e.multiSelect&&(t=e.selection.index,l.rangeCount!=e.multiSelect.rangeCount&&(l={rangeCount:e.multiSelect.rangeCount}));if(l[t])return f=l[t];f=l[t]={autoInsertedBrackets:0,autoInsertedRow:-1,autoInsertedLineEnd:"",maybeInsertedBrackets:0,maybeInsertedRow:-1,maybeInsertedLineStart:"",maybeInsertedLineEnd:""}},h=function(e,t,n,r){var i=e.end.row-e.start.row;return{text:n+t+r,selection:[0,e.start.column+1,i,e.end.column+(i?0:1)]}},p=function(){this.add("braces","insertion",function(e,t,n,r,i){var s=n.getCursorPosition(),u=r.doc.getLine(s.row);if(i=="{"){c(n);var a=n.getSelectionRange(),l=r.doc.getTextRange(a);if(l!==""&&l!=="{"&&n.getWrapBehavioursEnabled())return h(a,l,"{","}");if(p.isSaneInsertion(n,r))return/[\]\}\)]/.test(u[s.column])||n.inMultiSelectMode?(p.recordAutoInsert(n,r,"}"),{text:"{}",selection:[1,1]}):(p.recordMaybeInsert(n,r,"{"),{text:"{",selection:[1,1]})}else if(i=="}"){c(n);var d=u.substring(s.column,s.column+1);if(d=="}"){var v=r.$findOpeningBracket("}",{column:s.column+1,row:s.row});if(v!==null&&p.isAutoInsertedClosing(s,u,i))return p.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}else{if(i=="\n"||i=="\r\n"){c(n);var m="";p.isMaybeInsertedClosing(s,u)&&(m=o.stringRepeat("}",f.maybeInsertedBrackets),p.clearMaybeInsertedClosing());var d=u.substring(s.column,s.column+1);if(d==="}"){var g=r.findMatchingBracket({row:s.row,column:s.column+1},"}");if(!g)return null;var y=this.$getIndent(r.getLine(g.row))}else{if(!m){p.clearMaybeInsertedClosing();return}var y=this.$getIndent(u)}var b=y+r.getTabString();return{text:"\n"+b+"\n"+y+m,selection:[1,b.length,1,b.length]}}p.clearMaybeInsertedClosing()}}),this.add("braces","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="{"){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.end.column,i.end.column+1);if(u=="}")return i.end.column++,i;f.maybeInsertedBrackets--}}),this.add("parens","insertion",function(e,t,n,r,i){if(i=="("){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return h(s,o,"(",")");if(p.isSaneInsertion(n,r))return p.recordAutoInsert(n,r,")"),{text:"()",selection:[1,1]}}else if(i==")"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f==")"){var l=r.$findOpeningBracket(")",{column:u.column+1,row:u.row});if(l!==null&&p.isAutoInsertedClosing(u,a,i))return p.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("parens","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="("){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==")")return i.end.column++,i}}),this.add("brackets","insertion",function(e,t,n,r,i){if(i=="["){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return h(s,o,"[","]");if(p.isSaneInsertion(n,r))return p.recordAutoInsert(n,r,"]"),{text:"[]",selection:[1,1]}}else if(i=="]"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f=="]"){var l=r.$findOpeningBracket("]",{column:u.column+1,row:u.row});if(l!==null&&p.isAutoInsertedClosing(u,a,i))return p.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("brackets","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="["){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u=="]")return i.end.column++,i}}),this.add("string_dquotes","insertion",function(e,t,n,r,i){if(i=='"'||i=="'"){if(this.lineCommentStart&&this.lineCommentStart.indexOf(i)!=-1)return;c(n);var s=i,o=n.getSelectionRange(),u=r.doc.getTextRange(o);if(u!==""&&u!=="'"&&u!='"'&&n.getWrapBehavioursEnabled())return h(o,u,s,s);if(!u){var a=n.getCursorPosition(),f=r.doc.getLine(a.row),l=f.substring(a.column-1,a.column),p=f.substring(a.column,a.column+1),d=r.getTokenAt(a.row,a.column),v=r.getTokenAt(a.row,a.column+1);if(l=="\\"&&d&&/escape/.test(d.type))return null;var m=d&&/string|escape/.test(d.type),g=!v||/string|escape/.test(v.type),y;if(p==s)y=m!==g,y&&/string\.end/.test(v.type)&&(y=!1);else{if(m&&!g)return null;if(m&&g)return null;var b=r.$mode.tokenRe;b.lastIndex=0;var w=b.test(l);b.lastIndex=0;var E=b.test(l);if(w||E)return null;if(p&&!/[\s;,.})\]\\]/.test(p))return null;y=!0}return{text:y?s+s:"",selection:[1,1]}}}}),this.add("string_dquotes","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&(s=='"'||s=="'")){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==s)return i.end.column++,i}})};p.isSaneInsertion=function(e,t){var n=e.getCursorPosition(),r=new s(t,n.row,n.column);if(!this.$matchTokenType(r.getCurrentToken()||"text",u)){var i=new s(t,n.row,n.column+1);if(!this.$matchTokenType(i.getCurrentToken()||"text",u))return!1}return r.stepForward(),r.getCurrentTokenRow()!==n.row||this.$matchTokenType(r.getCurrentToken()||"text",a)},p.$matchTokenType=function(e,t){return t.indexOf(e.type||e)>-1},p.recordAutoInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isAutoInsertedClosing(r,i,f.autoInsertedLineEnd[0])||(f.autoInsertedBrackets=0),f.autoInsertedRow=r.row,f.autoInsertedLineEnd=n+i.substr(r.column),f.autoInsertedBrackets++},p.recordMaybeInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isMaybeInsertedClosing(r,i)||(f.maybeInsertedBrackets=0),f.maybeInsertedRow=r.row,f.maybeInsertedLineStart=i.substr(0,r.column)+n,f.maybeInsertedLineEnd=i.substr(r.column),f.maybeInsertedBrackets++},p.isAutoInsertedClosing=function(e,t,n){return f.autoInsertedBrackets>0&&e.row===f.autoInsertedRow&&n===f.autoInsertedLineEnd[0]&&t.substr(e.column)===f.autoInsertedLineEnd},p.isMaybeInsertedClosing=function(e,t){return f.maybeInsertedBrackets>0&&e.row===f.maybeInsertedRow&&t.substr(e.column)===f.maybeInsertedLineEnd&&t.substr(0,e.column)==f.maybeInsertedLineStart},p.popAutoInsertedClosing=function(){f.autoInsertedLineEnd=f.autoInsertedLineEnd.substr(1),f.autoInsertedBrackets--},p.clearMaybeInsertedClosing=function(){f&&(f.maybeInsertedBrackets=0,f.maybeInsertedRow=-1)},r.inherits(p,i),t.CstyleBehaviour=p}),define("ace/unicode",["require","exports","module"],function(e,t,n){"use strict";function r(e){var n=/\w{4}/g;for(var r in e)t.packages[r]=e[r].replace(n,"\\u$&")}t.packages={},r({L:"0041-005A0061-007A00AA00B500BA00C0-00D600D8-00F600F8-02C102C6-02D102E0-02E402EC02EE0370-037403760377037A-037D03860388-038A038C038E-03A103A3-03F503F7-0481048A-05250531-055605590561-058705D0-05EA05F0-05F20621-064A066E066F0671-06D306D506E506E606EE06EF06FA-06FC06FF07100712-072F074D-07A507B107CA-07EA07F407F507FA0800-0815081A082408280904-0939093D09500958-0961097109720979-097F0985-098C098F09900993-09A809AA-09B009B209B6-09B909BD09CE09DC09DD09DF-09E109F009F10A05-0A0A0A0F0A100A13-0A280A2A-0A300A320A330A350A360A380A390A59-0A5C0A5E0A72-0A740A85-0A8D0A8F-0A910A93-0AA80AAA-0AB00AB20AB30AB5-0AB90ABD0AD00AE00AE10B05-0B0C0B0F0B100B13-0B280B2A-0B300B320B330B35-0B390B3D0B5C0B5D0B5F-0B610B710B830B85-0B8A0B8E-0B900B92-0B950B990B9A0B9C0B9E0B9F0BA30BA40BA8-0BAA0BAE-0BB90BD00C05-0C0C0C0E-0C100C12-0C280C2A-0C330C35-0C390C3D0C580C590C600C610C85-0C8C0C8E-0C900C92-0CA80CAA-0CB30CB5-0CB90CBD0CDE0CE00CE10D05-0D0C0D0E-0D100D12-0D280D2A-0D390D3D0D600D610D7A-0D7F0D85-0D960D9A-0DB10DB3-0DBB0DBD0DC0-0DC60E01-0E300E320E330E40-0E460E810E820E840E870E880E8A0E8D0E94-0E970E99-0E9F0EA1-0EA30EA50EA70EAA0EAB0EAD-0EB00EB20EB30EBD0EC0-0EC40EC60EDC0EDD0F000F40-0F470F49-0F6C0F88-0F8B1000-102A103F1050-1055105A-105D106110651066106E-10701075-1081108E10A0-10C510D0-10FA10FC1100-1248124A-124D1250-12561258125A-125D1260-1288128A-128D1290-12B012B2-12B512B8-12BE12C012C2-12C512C8-12D612D8-13101312-13151318-135A1380-138F13A0-13F41401-166C166F-167F1681-169A16A0-16EA1700-170C170E-17111720-17311740-17511760-176C176E-17701780-17B317D717DC1820-18771880-18A818AA18B0-18F51900-191C1950-196D1970-19741980-19AB19C1-19C71A00-1A161A20-1A541AA71B05-1B331B45-1B4B1B83-1BA01BAE1BAF1C00-1C231C4D-1C4F1C5A-1C7D1CE9-1CEC1CEE-1CF11D00-1DBF1E00-1F151F18-1F1D1F20-1F451F48-1F4D1F50-1F571F591F5B1F5D1F5F-1F7D1F80-1FB41FB6-1FBC1FBE1FC2-1FC41FC6-1FCC1FD0-1FD31FD6-1FDB1FE0-1FEC1FF2-1FF41FF6-1FFC2071207F2090-209421022107210A-211321152119-211D212421262128212A-212D212F-2139213C-213F2145-2149214E218321842C00-2C2E2C30-2C5E2C60-2CE42CEB-2CEE2D00-2D252D30-2D652D6F2D80-2D962DA0-2DA62DA8-2DAE2DB0-2DB62DB8-2DBE2DC0-2DC62DC8-2DCE2DD0-2DD62DD8-2DDE2E2F300530063031-3035303B303C3041-3096309D-309F30A1-30FA30FC-30FF3105-312D3131-318E31A0-31B731F0-31FF3400-4DB54E00-9FCBA000-A48CA4D0-A4FDA500-A60CA610-A61FA62AA62BA640-A65FA662-A66EA67F-A697A6A0-A6E5A717-A71FA722-A788A78BA78CA7FB-A801A803-A805A807-A80AA80C-A822A840-A873A882-A8B3A8F2-A8F7A8FBA90A-A925A930-A946A960-A97CA984-A9B2A9CFAA00-AA28AA40-AA42AA44-AA4BAA60-AA76AA7AAA80-AAAFAAB1AAB5AAB6AAB9-AABDAAC0AAC2AADB-AADDABC0-ABE2AC00-D7A3D7B0-D7C6D7CB-D7FBF900-FA2DFA30-FA6DFA70-FAD9FB00-FB06FB13-FB17FB1DFB1F-FB28FB2A-FB36FB38-FB3CFB3EFB40FB41FB43FB44FB46-FBB1FBD3-FD3DFD50-FD8FFD92-FDC7FDF0-FDFBFE70-FE74FE76-FEFCFF21-FF3AFF41-FF5AFF66-FFBEFFC2-FFC7FFCA-FFCFFFD2-FFD7FFDA-FFDC",Ll:"0061-007A00AA00B500BA00DF-00F600F8-00FF01010103010501070109010B010D010F01110113011501170119011B011D011F01210123012501270129012B012D012F01310133013501370138013A013C013E014001420144014601480149014B014D014F01510153015501570159015B015D015F01610163016501670169016B016D016F0171017301750177017A017C017E-0180018301850188018C018D019201950199-019B019E01A101A301A501A801AA01AB01AD01B001B401B601B901BA01BD-01BF01C601C901CC01CE01D001D201D401D601D801DA01DC01DD01DF01E101E301E501E701E901EB01ED01EF01F001F301F501F901FB01FD01FF02010203020502070209020B020D020F02110213021502170219021B021D021F02210223022502270229022B022D022F02310233-0239023C023F0240024202470249024B024D024F-02930295-02AF037103730377037B-037D039003AC-03CE03D003D103D5-03D703D903DB03DD03DF03E103E303E503E703E903EB03ED03EF-03F303F503F803FB03FC0430-045F04610463046504670469046B046D046F04710473047504770479047B047D047F0481048B048D048F04910493049504970499049B049D049F04A104A304A504A704A904AB04AD04AF04B104B304B504B704B904BB04BD04BF04C204C404C604C804CA04CC04CE04CF04D104D304D504D704D904DB04DD04DF04E104E304E504E704E904EB04ED04EF04F104F304F504F704F904FB04FD04FF05010503050505070509050B050D050F05110513051505170519051B051D051F0521052305250561-05871D00-1D2B1D62-1D771D79-1D9A1E011E031E051E071E091E0B1E0D1E0F1E111E131E151E171E191E1B1E1D1E1F1E211E231E251E271E291E2B1E2D1E2F1E311E331E351E371E391E3B1E3D1E3F1E411E431E451E471E491E4B1E4D1E4F1E511E531E551E571E591E5B1E5D1E5F1E611E631E651E671E691E6B1E6D1E6F1E711E731E751E771E791E7B1E7D1E7F1E811E831E851E871E891E8B1E8D1E8F1E911E931E95-1E9D1E9F1EA11EA31EA51EA71EA91EAB1EAD1EAF1EB11EB31EB51EB71EB91EBB1EBD1EBF1EC11EC31EC51EC71EC91ECB1ECD1ECF1ED11ED31ED51ED71ED91EDB1EDD1EDF1EE11EE31EE51EE71EE91EEB1EED1EEF1EF11EF31EF51EF71EF91EFB1EFD1EFF-1F071F10-1F151F20-1F271F30-1F371F40-1F451F50-1F571F60-1F671F70-1F7D1F80-1F871F90-1F971FA0-1FA71FB0-1FB41FB61FB71FBE1FC2-1FC41FC61FC71FD0-1FD31FD61FD71FE0-1FE71FF2-1FF41FF61FF7210A210E210F2113212F21342139213C213D2146-2149214E21842C30-2C5E2C612C652C662C682C6A2C6C2C712C732C742C76-2C7C2C812C832C852C872C892C8B2C8D2C8F2C912C932C952C972C992C9B2C9D2C9F2CA12CA32CA52CA72CA92CAB2CAD2CAF2CB12CB32CB52CB72CB92CBB2CBD2CBF2CC12CC32CC52CC72CC92CCB2CCD2CCF2CD12CD32CD52CD72CD92CDB2CDD2CDF2CE12CE32CE42CEC2CEE2D00-2D25A641A643A645A647A649A64BA64DA64FA651A653A655A657A659A65BA65DA65FA663A665A667A669A66BA66DA681A683A685A687A689A68BA68DA68FA691A693A695A697A723A725A727A729A72BA72DA72F-A731A733A735A737A739A73BA73DA73FA741A743A745A747A749A74BA74DA74FA751A753A755A757A759A75BA75DA75FA761A763A765A767A769A76BA76DA76FA771-A778A77AA77CA77FA781A783A785A787A78CFB00-FB06FB13-FB17FF41-FF5A",Lu:"0041-005A00C0-00D600D8-00DE01000102010401060108010A010C010E01100112011401160118011A011C011E01200122012401260128012A012C012E01300132013401360139013B013D013F0141014301450147014A014C014E01500152015401560158015A015C015E01600162016401660168016A016C016E017001720174017601780179017B017D018101820184018601870189-018B018E-0191019301940196-0198019C019D019F01A001A201A401A601A701A901AC01AE01AF01B1-01B301B501B701B801BC01C401C701CA01CD01CF01D101D301D501D701D901DB01DE01E001E201E401E601E801EA01EC01EE01F101F401F6-01F801FA01FC01FE02000202020402060208020A020C020E02100212021402160218021A021C021E02200222022402260228022A022C022E02300232023A023B023D023E02410243-02460248024A024C024E03700372037603860388-038A038C038E038F0391-03A103A3-03AB03CF03D2-03D403D803DA03DC03DE03E003E203E403E603E803EA03EC03EE03F403F703F903FA03FD-042F04600462046404660468046A046C046E04700472047404760478047A047C047E0480048A048C048E04900492049404960498049A049C049E04A004A204A404A604A804AA04AC04AE04B004B204B404B604B804BA04BC04BE04C004C104C304C504C704C904CB04CD04D004D204D404D604D804DA04DC04DE04E004E204E404E604E804EA04EC04EE04F004F204F404F604F804FA04FC04FE05000502050405060508050A050C050E05100512051405160518051A051C051E0520052205240531-055610A0-10C51E001E021E041E061E081E0A1E0C1E0E1E101E121E141E161E181E1A1E1C1E1E1E201E221E241E261E281E2A1E2C1E2E1E301E321E341E361E381E3A1E3C1E3E1E401E421E441E461E481E4A1E4C1E4E1E501E521E541E561E581E5A1E5C1E5E1E601E621E641E661E681E6A1E6C1E6E1E701E721E741E761E781E7A1E7C1E7E1E801E821E841E861E881E8A1E8C1E8E1E901E921E941E9E1EA01EA21EA41EA61EA81EAA1EAC1EAE1EB01EB21EB41EB61EB81EBA1EBC1EBE1EC01EC21EC41EC61EC81ECA1ECC1ECE1ED01ED21ED41ED61ED81EDA1EDC1EDE1EE01EE21EE41EE61EE81EEA1EEC1EEE1EF01EF21EF41EF61EF81EFA1EFC1EFE1F08-1F0F1F18-1F1D1F28-1F2F1F38-1F3F1F48-1F4D1F591F5B1F5D1F5F1F68-1F6F1FB8-1FBB1FC8-1FCB1FD8-1FDB1FE8-1FEC1FF8-1FFB21022107210B-210D2110-211221152119-211D212421262128212A-212D2130-2133213E213F214521832C00-2C2E2C602C62-2C642C672C692C6B2C6D-2C702C722C752C7E-2C802C822C842C862C882C8A2C8C2C8E2C902C922C942C962C982C9A2C9C2C9E2CA02CA22CA42CA62CA82CAA2CAC2CAE2CB02CB22CB42CB62CB82CBA2CBC2CBE2CC02CC22CC42CC62CC82CCA2CCC2CCE2CD02CD22CD42CD62CD82CDA2CDC2CDE2CE02CE22CEB2CEDA640A642A644A646A648A64AA64CA64EA650A652A654A656A658A65AA65CA65EA662A664A666A668A66AA66CA680A682A684A686A688A68AA68CA68EA690A692A694A696A722A724A726A728A72AA72CA72EA732A734A736A738A73AA73CA73EA740A742A744A746A748A74AA74CA74EA750A752A754A756A758A75AA75CA75EA760A762A764A766A768A76AA76CA76EA779A77BA77DA77EA780A782A784A786A78BFF21-FF3A",Lt:"01C501C801CB01F21F88-1F8F1F98-1F9F1FA8-1FAF1FBC1FCC1FFC",Lm:"02B0-02C102C6-02D102E0-02E402EC02EE0374037A0559064006E506E607F407F507FA081A0824082809710E460EC610FC17D718431AA71C78-1C7D1D2C-1D611D781D9B-1DBF2071207F2090-20942C7D2D6F2E2F30053031-3035303B309D309E30FC-30FEA015A4F8-A4FDA60CA67FA717-A71FA770A788A9CFAA70AADDFF70FF9EFF9F",Lo:"01BB01C0-01C3029405D0-05EA05F0-05F20621-063F0641-064A066E066F0671-06D306D506EE06EF06FA-06FC06FF07100712-072F074D-07A507B107CA-07EA0800-08150904-0939093D09500958-096109720979-097F0985-098C098F09900993-09A809AA-09B009B209B6-09B909BD09CE09DC09DD09DF-09E109F009F10A05-0A0A0A0F0A100A13-0A280A2A-0A300A320A330A350A360A380A390A59-0A5C0A5E0A72-0A740A85-0A8D0A8F-0A910A93-0AA80AAA-0AB00AB20AB30AB5-0AB90ABD0AD00AE00AE10B05-0B0C0B0F0B100B13-0B280B2A-0B300B320B330B35-0B390B3D0B5C0B5D0B5F-0B610B710B830B85-0B8A0B8E-0B900B92-0B950B990B9A0B9C0B9E0B9F0BA30BA40BA8-0BAA0BAE-0BB90BD00C05-0C0C0C0E-0C100C12-0C280C2A-0C330C35-0C390C3D0C580C590C600C610C85-0C8C0C8E-0C900C92-0CA80CAA-0CB30CB5-0CB90CBD0CDE0CE00CE10D05-0D0C0D0E-0D100D12-0D280D2A-0D390D3D0D600D610D7A-0D7F0D85-0D960D9A-0DB10DB3-0DBB0DBD0DC0-0DC60E01-0E300E320E330E40-0E450E810E820E840E870E880E8A0E8D0E94-0E970E99-0E9F0EA1-0EA30EA50EA70EAA0EAB0EAD-0EB00EB20EB30EBD0EC0-0EC40EDC0EDD0F000F40-0F470F49-0F6C0F88-0F8B1000-102A103F1050-1055105A-105D106110651066106E-10701075-1081108E10D0-10FA1100-1248124A-124D1250-12561258125A-125D1260-1288128A-128D1290-12B012B2-12B512B8-12BE12C012C2-12C512C8-12D612D8-13101312-13151318-135A1380-138F13A0-13F41401-166C166F-167F1681-169A16A0-16EA1700-170C170E-17111720-17311740-17511760-176C176E-17701780-17B317DC1820-18421844-18771880-18A818AA18B0-18F51900-191C1950-196D1970-19741980-19AB19C1-19C71A00-1A161A20-1A541B05-1B331B45-1B4B1B83-1BA01BAE1BAF1C00-1C231C4D-1C4F1C5A-1C771CE9-1CEC1CEE-1CF12135-21382D30-2D652D80-2D962DA0-2DA62DA8-2DAE2DB0-2DB62DB8-2DBE2DC0-2DC62DC8-2DCE2DD0-2DD62DD8-2DDE3006303C3041-3096309F30A1-30FA30FF3105-312D3131-318E31A0-31B731F0-31FF3400-4DB54E00-9FCBA000-A014A016-A48CA4D0-A4F7A500-A60BA610-A61FA62AA62BA66EA6A0-A6E5A7FB-A801A803-A805A807-A80AA80C-A822A840-A873A882-A8B3A8F2-A8F7A8FBA90A-A925A930-A946A960-A97CA984-A9B2AA00-AA28AA40-AA42AA44-AA4BAA60-AA6FAA71-AA76AA7AAA80-AAAFAAB1AAB5AAB6AAB9-AABDAAC0AAC2AADBAADCABC0-ABE2AC00-D7A3D7B0-D7C6D7CB-D7FBF900-FA2DFA30-FA6DFA70-FAD9FB1DFB1F-FB28FB2A-FB36FB38-FB3CFB3EFB40FB41FB43FB44FB46-FBB1FBD3-FD3DFD50-FD8FFD92-FDC7FDF0-FDFBFE70-FE74FE76-FEFCFF66-FF6FFF71-FF9DFFA0-FFBEFFC2-FFC7FFCA-FFCFFFD2-FFD7FFDA-FFDC",M:"0300-036F0483-04890591-05BD05BF05C105C205C405C505C70610-061A064B-065E067006D6-06DC06DE-06E406E706E806EA-06ED07110730-074A07A6-07B007EB-07F30816-0819081B-08230825-08270829-082D0900-0903093C093E-094E0951-0955096209630981-098309BC09BE-09C409C709C809CB-09CD09D709E209E30A01-0A030A3C0A3E-0A420A470A480A4B-0A4D0A510A700A710A750A81-0A830ABC0ABE-0AC50AC7-0AC90ACB-0ACD0AE20AE30B01-0B030B3C0B3E-0B440B470B480B4B-0B4D0B560B570B620B630B820BBE-0BC20BC6-0BC80BCA-0BCD0BD70C01-0C030C3E-0C440C46-0C480C4A-0C4D0C550C560C620C630C820C830CBC0CBE-0CC40CC6-0CC80CCA-0CCD0CD50CD60CE20CE30D020D030D3E-0D440D46-0D480D4A-0D4D0D570D620D630D820D830DCA0DCF-0DD40DD60DD8-0DDF0DF20DF30E310E34-0E3A0E47-0E4E0EB10EB4-0EB90EBB0EBC0EC8-0ECD0F180F190F350F370F390F3E0F3F0F71-0F840F860F870F90-0F970F99-0FBC0FC6102B-103E1056-1059105E-10601062-10641067-106D1071-10741082-108D108F109A-109D135F1712-17141732-1734175217531772177317B6-17D317DD180B-180D18A91920-192B1930-193B19B0-19C019C819C91A17-1A1B1A55-1A5E1A60-1A7C1A7F1B00-1B041B34-1B441B6B-1B731B80-1B821BA1-1BAA1C24-1C371CD0-1CD21CD4-1CE81CED1CF21DC0-1DE61DFD-1DFF20D0-20F02CEF-2CF12DE0-2DFF302A-302F3099309AA66F-A672A67CA67DA6F0A6F1A802A806A80BA823-A827A880A881A8B4-A8C4A8E0-A8F1A926-A92DA947-A953A980-A983A9B3-A9C0AA29-AA36AA43AA4CAA4DAA7BAAB0AAB2-AAB4AAB7AAB8AABEAABFAAC1ABE3-ABEAABECABEDFB1EFE00-FE0FFE20-FE26",Mn:"0300-036F0483-04870591-05BD05BF05C105C205C405C505C70610-061A064B-065E067006D6-06DC06DF-06E406E706E806EA-06ED07110730-074A07A6-07B007EB-07F30816-0819081B-08230825-08270829-082D0900-0902093C0941-0948094D0951-095509620963098109BC09C1-09C409CD09E209E30A010A020A3C0A410A420A470A480A4B-0A4D0A510A700A710A750A810A820ABC0AC1-0AC50AC70AC80ACD0AE20AE30B010B3C0B3F0B41-0B440B4D0B560B620B630B820BC00BCD0C3E-0C400C46-0C480C4A-0C4D0C550C560C620C630CBC0CBF0CC60CCC0CCD0CE20CE30D41-0D440D4D0D620D630DCA0DD2-0DD40DD60E310E34-0E3A0E47-0E4E0EB10EB4-0EB90EBB0EBC0EC8-0ECD0F180F190F350F370F390F71-0F7E0F80-0F840F860F870F90-0F970F99-0FBC0FC6102D-10301032-10371039103A103D103E10581059105E-10601071-1074108210851086108D109D135F1712-17141732-1734175217531772177317B7-17BD17C617C9-17D317DD180B-180D18A91920-19221927192819321939-193B1A171A181A561A58-1A5E1A601A621A65-1A6C1A73-1A7C1A7F1B00-1B031B341B36-1B3A1B3C1B421B6B-1B731B801B811BA2-1BA51BA81BA91C2C-1C331C361C371CD0-1CD21CD4-1CE01CE2-1CE81CED1DC0-1DE61DFD-1DFF20D0-20DC20E120E5-20F02CEF-2CF12DE0-2DFF302A-302F3099309AA66FA67CA67DA6F0A6F1A802A806A80BA825A826A8C4A8E0-A8F1A926-A92DA947-A951A980-A982A9B3A9B6-A9B9A9BCAA29-AA2EAA31AA32AA35AA36AA43AA4CAAB0AAB2-AAB4AAB7AAB8AABEAABFAAC1ABE5ABE8ABEDFB1EFE00-FE0FFE20-FE26",Mc:"0903093E-09400949-094C094E0982098309BE-09C009C709C809CB09CC09D70A030A3E-0A400A830ABE-0AC00AC90ACB0ACC0B020B030B3E0B400B470B480B4B0B4C0B570BBE0BBF0BC10BC20BC6-0BC80BCA-0BCC0BD70C01-0C030C41-0C440C820C830CBE0CC0-0CC40CC70CC80CCA0CCB0CD50CD60D020D030D3E-0D400D46-0D480D4A-0D4C0D570D820D830DCF-0DD10DD8-0DDF0DF20DF30F3E0F3F0F7F102B102C10311038103B103C105610571062-10641067-106D108310841087-108C108F109A-109C17B617BE-17C517C717C81923-19261929-192B193019311933-193819B0-19C019C819C91A19-1A1B1A551A571A611A631A641A6D-1A721B041B351B3B1B3D-1B411B431B441B821BA11BA61BA71BAA1C24-1C2B1C341C351CE11CF2A823A824A827A880A881A8B4-A8C3A952A953A983A9B4A9B5A9BAA9BBA9BD-A9C0AA2FAA30AA33AA34AA4DAA7BABE3ABE4ABE6ABE7ABE9ABEAABEC",Me:"0488048906DE20DD-20E020E2-20E4A670-A672",N:"0030-003900B200B300B900BC-00BE0660-066906F0-06F907C0-07C90966-096F09E6-09EF09F4-09F90A66-0A6F0AE6-0AEF0B66-0B6F0BE6-0BF20C66-0C6F0C78-0C7E0CE6-0CEF0D66-0D750E50-0E590ED0-0ED90F20-0F331040-10491090-10991369-137C16EE-16F017E0-17E917F0-17F91810-18191946-194F19D0-19DA1A80-1A891A90-1A991B50-1B591BB0-1BB91C40-1C491C50-1C5920702074-20792080-20892150-21822185-21892460-249B24EA-24FF2776-27932CFD30073021-30293038-303A3192-31953220-32293251-325F3280-328932B1-32BFA620-A629A6E6-A6EFA830-A835A8D0-A8D9A900-A909A9D0-A9D9AA50-AA59ABF0-ABF9FF10-FF19",Nd:"0030-00390660-066906F0-06F907C0-07C90966-096F09E6-09EF0A66-0A6F0AE6-0AEF0B66-0B6F0BE6-0BEF0C66-0C6F0CE6-0CEF0D66-0D6F0E50-0E590ED0-0ED90F20-0F291040-10491090-109917E0-17E91810-18191946-194F19D0-19DA1A80-1A891A90-1A991B50-1B591BB0-1BB91C40-1C491C50-1C59A620-A629A8D0-A8D9A900-A909A9D0-A9D9AA50-AA59ABF0-ABF9FF10-FF19",Nl:"16EE-16F02160-21822185-218830073021-30293038-303AA6E6-A6EF",No:"00B200B300B900BC-00BE09F4-09F90BF0-0BF20C78-0C7E0D70-0D750F2A-0F331369-137C17F0-17F920702074-20792080-20892150-215F21892460-249B24EA-24FF2776-27932CFD3192-31953220-32293251-325F3280-328932B1-32BFA830-A835",P:"0021-00230025-002A002C-002F003A003B003F0040005B-005D005F007B007D00A100AB00B700BB00BF037E0387055A-055F0589058A05BE05C005C305C605F305F40609060A060C060D061B061E061F066A-066D06D40700-070D07F7-07F90830-083E0964096509700DF40E4F0E5A0E5B0F04-0F120F3A-0F3D0F850FD0-0FD4104A-104F10FB1361-13681400166D166E169B169C16EB-16ED1735173617D4-17D617D8-17DA1800-180A1944194519DE19DF1A1E1A1F1AA0-1AA61AA8-1AAD1B5A-1B601C3B-1C3F1C7E1C7F1CD32010-20272030-20432045-20512053-205E207D207E208D208E2329232A2768-277527C527C627E6-27EF2983-299829D8-29DB29FC29FD2CF9-2CFC2CFE2CFF2E00-2E2E2E302E313001-30033008-30113014-301F3030303D30A030FBA4FEA4FFA60D-A60FA673A67EA6F2-A6F7A874-A877A8CEA8CFA8F8-A8FAA92EA92FA95FA9C1-A9CDA9DEA9DFAA5C-AA5FAADEAADFABEBFD3EFD3FFE10-FE19FE30-FE52FE54-FE61FE63FE68FE6AFE6BFF01-FF03FF05-FF0AFF0C-FF0FFF1AFF1BFF1FFF20FF3B-FF3DFF3FFF5BFF5DFF5F-FF65",Pd:"002D058A05BE140018062010-20152E172E1A301C303030A0FE31FE32FE58FE63FF0D",Ps:"0028005B007B0F3A0F3C169B201A201E2045207D208D23292768276A276C276E27702772277427C527E627E827EA27EC27EE2983298529872989298B298D298F299129932995299729D829DA29FC2E222E242E262E283008300A300C300E3010301430163018301A301DFD3EFE17FE35FE37FE39FE3BFE3DFE3FFE41FE43FE47FE59FE5BFE5DFF08FF3BFF5BFF5FFF62",Pe:"0029005D007D0F3B0F3D169C2046207E208E232A2769276B276D276F27712773277527C627E727E927EB27ED27EF298429862988298A298C298E2990299229942996299829D929DB29FD2E232E252E272E293009300B300D300F3011301530173019301B301E301FFD3FFE18FE36FE38FE3AFE3CFE3EFE40FE42FE44FE48FE5AFE5CFE5EFF09FF3DFF5DFF60FF63",Pi:"00AB2018201B201C201F20392E022E042E092E0C2E1C2E20",Pf:"00BB2019201D203A2E032E052E0A2E0D2E1D2E21",Pc:"005F203F20402054FE33FE34FE4D-FE4FFF3F",Po:"0021-00230025-0027002A002C002E002F003A003B003F0040005C00A100B700BF037E0387055A-055F058905C005C305C605F305F40609060A060C060D061B061E061F066A-066D06D40700-070D07F7-07F90830-083E0964096509700DF40E4F0E5A0E5B0F04-0F120F850FD0-0FD4104A-104F10FB1361-1368166D166E16EB-16ED1735173617D4-17D617D8-17DA1800-18051807-180A1944194519DE19DF1A1E1A1F1AA0-1AA61AA8-1AAD1B5A-1B601C3B-1C3F1C7E1C7F1CD3201620172020-20272030-2038203B-203E2041-20432047-205120532055-205E2CF9-2CFC2CFE2CFF2E002E012E06-2E082E0B2E0E-2E162E182E192E1B2E1E2E1F2E2A-2E2E2E302E313001-3003303D30FBA4FEA4FFA60D-A60FA673A67EA6F2-A6F7A874-A877A8CEA8CFA8F8-A8FAA92EA92FA95FA9C1-A9CDA9DEA9DFAA5C-AA5FAADEAADFABEBFE10-FE16FE19FE30FE45FE46FE49-FE4CFE50-FE52FE54-FE57FE5F-FE61FE68FE6AFE6BFF01-FF03FF05-FF07FF0AFF0CFF0EFF0FFF1AFF1BFF1FFF20FF3CFF61FF64FF65",S:"0024002B003C-003E005E0060007C007E00A2-00A900AC00AE-00B100B400B600B800D700F702C2-02C502D2-02DF02E5-02EB02ED02EF-02FF03750384038503F604820606-0608060B060E060F06E906FD06FE07F609F209F309FA09FB0AF10B700BF3-0BFA0C7F0CF10CF20D790E3F0F01-0F030F13-0F170F1A-0F1F0F340F360F380FBE-0FC50FC7-0FCC0FCE0FCF0FD5-0FD8109E109F13601390-139917DB194019E0-19FF1B61-1B6A1B74-1B7C1FBD1FBF-1FC11FCD-1FCF1FDD-1FDF1FED-1FEF1FFD1FFE20442052207A-207C208A-208C20A0-20B8210021012103-21062108210921142116-2118211E-2123212521272129212E213A213B2140-2144214A-214D214F2190-2328232B-23E82400-24262440-244A249C-24E92500-26CD26CF-26E126E326E8-26FF2701-27042706-2709270C-27272729-274B274D274F-27522756-275E2761-276727942798-27AF27B1-27BE27C0-27C427C7-27CA27CC27D0-27E527F0-29822999-29D729DC-29FB29FE-2B4C2B50-2B592CE5-2CEA2E80-2E992E9B-2EF32F00-2FD52FF0-2FFB300430123013302030363037303E303F309B309C319031913196-319F31C0-31E33200-321E322A-32503260-327F328A-32B032C0-32FE3300-33FF4DC0-4DFFA490-A4C6A700-A716A720A721A789A78AA828-A82BA836-A839AA77-AA79FB29FDFCFDFDFE62FE64-FE66FE69FF04FF0BFF1C-FF1EFF3EFF40FF5CFF5EFFE0-FFE6FFE8-FFEEFFFCFFFD",Sm:"002B003C-003E007C007E00AC00B100D700F703F60606-060820442052207A-207C208A-208C2140-2144214B2190-2194219A219B21A021A321A621AE21CE21CF21D221D421F4-22FF2308-230B23202321237C239B-23B323DC-23E125B725C125F8-25FF266F27C0-27C427C7-27CA27CC27D0-27E527F0-27FF2900-29822999-29D729DC-29FB29FE-2AFF2B30-2B442B47-2B4CFB29FE62FE64-FE66FF0BFF1C-FF1EFF5CFF5EFFE2FFE9-FFEC",Sc:"002400A2-00A5060B09F209F309FB0AF10BF90E3F17DB20A0-20B8A838FDFCFE69FF04FFE0FFE1FFE5FFE6",Sk:"005E006000A800AF00B400B802C2-02C502D2-02DF02E5-02EB02ED02EF-02FF0375038403851FBD1FBF-1FC11FCD-1FCF1FDD-1FDF1FED-1FEF1FFD1FFE309B309CA700-A716A720A721A789A78AFF3EFF40FFE3",So:"00A600A700A900AE00B000B60482060E060F06E906FD06FE07F609FA0B700BF3-0BF80BFA0C7F0CF10CF20D790F01-0F030F13-0F170F1A-0F1F0F340F360F380FBE-0FC50FC7-0FCC0FCE0FCF0FD5-0FD8109E109F13601390-1399194019E0-19FF1B61-1B6A1B74-1B7C210021012103-21062108210921142116-2118211E-2123212521272129212E213A213B214A214C214D214F2195-2199219C-219F21A121A221A421A521A7-21AD21AF-21CD21D021D121D321D5-21F32300-2307230C-231F2322-2328232B-237B237D-239A23B4-23DB23E2-23E82400-24262440-244A249C-24E92500-25B625B8-25C025C2-25F72600-266E2670-26CD26CF-26E126E326E8-26FF2701-27042706-2709270C-27272729-274B274D274F-27522756-275E2761-276727942798-27AF27B1-27BE2800-28FF2B00-2B2F2B452B462B50-2B592CE5-2CEA2E80-2E992E9B-2EF32F00-2FD52FF0-2FFB300430123013302030363037303E303F319031913196-319F31C0-31E33200-321E322A-32503260-327F328A-32B032C0-32FE3300-33FF4DC0-4DFFA490-A4C6A828-A82BA836A837A839AA77-AA79FDFDFFE4FFE8FFEDFFEEFFFCFFFD",Z:"002000A01680180E2000-200A20282029202F205F3000",Zs:"002000A01680180E2000-200A202F205F3000",Zl:"2028",Zp:"2029",C:"0000-001F007F-009F00AD03780379037F-0383038B038D03A20526-05300557055805600588058B-059005C8-05CF05EB-05EF05F5-0605061C061D0620065F06DD070E070F074B074C07B2-07BF07FB-07FF082E082F083F-08FF093A093B094F095609570973-097809800984098D098E0991099209A909B109B3-09B509BA09BB09C509C609C909CA09CF-09D609D8-09DB09DE09E409E509FC-0A000A040A0B-0A0E0A110A120A290A310A340A370A3A0A3B0A3D0A43-0A460A490A4A0A4E-0A500A52-0A580A5D0A5F-0A650A76-0A800A840A8E0A920AA90AB10AB40ABA0ABB0AC60ACA0ACE0ACF0AD1-0ADF0AE40AE50AF00AF2-0B000B040B0D0B0E0B110B120B290B310B340B3A0B3B0B450B460B490B4A0B4E-0B550B58-0B5B0B5E0B640B650B72-0B810B840B8B-0B8D0B910B96-0B980B9B0B9D0BA0-0BA20BA5-0BA70BAB-0BAD0BBA-0BBD0BC3-0BC50BC90BCE0BCF0BD1-0BD60BD8-0BE50BFB-0C000C040C0D0C110C290C340C3A-0C3C0C450C490C4E-0C540C570C5A-0C5F0C640C650C70-0C770C800C810C840C8D0C910CA90CB40CBA0CBB0CC50CC90CCE-0CD40CD7-0CDD0CDF0CE40CE50CF00CF3-0D010D040D0D0D110D290D3A-0D3C0D450D490D4E-0D560D58-0D5F0D640D650D76-0D780D800D810D840D97-0D990DB20DBC0DBE0DBF0DC7-0DC90DCB-0DCE0DD50DD70DE0-0DF10DF5-0E000E3B-0E3E0E5C-0E800E830E850E860E890E8B0E8C0E8E-0E930E980EA00EA40EA60EA80EA90EAC0EBA0EBE0EBF0EC50EC70ECE0ECF0EDA0EDB0EDE-0EFF0F480F6D-0F700F8C-0F8F0F980FBD0FCD0FD9-0FFF10C6-10CF10FD-10FF1249124E124F12571259125E125F1289128E128F12B112B612B712BF12C112C612C712D7131113161317135B-135E137D-137F139A-139F13F5-13FF169D-169F16F1-16FF170D1715-171F1737-173F1754-175F176D17711774-177F17B417B517DE17DF17EA-17EF17FA-17FF180F181A-181F1878-187F18AB-18AF18F6-18FF191D-191F192C-192F193C-193F1941-1943196E196F1975-197F19AC-19AF19CA-19CF19DB-19DD1A1C1A1D1A5F1A7D1A7E1A8A-1A8F1A9A-1A9F1AAE-1AFF1B4C-1B4F1B7D-1B7F1BAB-1BAD1BBA-1BFF1C38-1C3A1C4A-1C4C1C80-1CCF1CF3-1CFF1DE7-1DFC1F161F171F1E1F1F1F461F471F4E1F4F1F581F5A1F5C1F5E1F7E1F7F1FB51FC51FD41FD51FDC1FF01FF11FF51FFF200B-200F202A-202E2060-206F20722073208F2095-209F20B9-20CF20F1-20FF218A-218F23E9-23FF2427-243F244B-245F26CE26E226E4-26E727002705270A270B2728274C274E2753-2755275F27602795-279727B027BF27CB27CD-27CF2B4D-2B4F2B5A-2BFF2C2F2C5F2CF2-2CF82D26-2D2F2D66-2D6E2D70-2D7F2D97-2D9F2DA72DAF2DB72DBF2DC72DCF2DD72DDF2E32-2E7F2E9A2EF4-2EFF2FD6-2FEF2FFC-2FFF3040309730983100-3104312E-3130318F31B8-31BF31E4-31EF321F32FF4DB6-4DBF9FCC-9FFFA48D-A48FA4C7-A4CFA62C-A63FA660A661A674-A67BA698-A69FA6F8-A6FFA78D-A7FAA82C-A82FA83A-A83FA878-A87FA8C5-A8CDA8DA-A8DFA8FC-A8FFA954-A95EA97D-A97FA9CEA9DA-A9DDA9E0-A9FFAA37-AA3FAA4EAA4FAA5AAA5BAA7C-AA7FAAC3-AADAAAE0-ABBFABEEABEFABFA-ABFFD7A4-D7AFD7C7-D7CAD7FC-F8FFFA2EFA2FFA6EFA6FFADA-FAFFFB07-FB12FB18-FB1CFB37FB3DFB3FFB42FB45FBB2-FBD2FD40-FD4FFD90FD91FDC8-FDEFFDFEFDFFFE1A-FE1FFE27-FE2FFE53FE67FE6C-FE6FFE75FEFD-FF00FFBF-FFC1FFC8FFC9FFD0FFD1FFD8FFD9FFDD-FFDFFFE7FFEF-FFFBFFFEFFFF",Cc:"0000-001F007F-009F",Cf:"00AD0600-060306DD070F17B417B5200B-200F202A-202E2060-2064206A-206FFEFFFFF9-FFFB",Co:"E000-F8FF",Cs:"D800-DFFF",Cn:"03780379037F-0383038B038D03A20526-05300557055805600588058B-059005C8-05CF05EB-05EF05F5-05FF06040605061C061D0620065F070E074B074C07B2-07BF07FB-07FF082E082F083F-08FF093A093B094F095609570973-097809800984098D098E0991099209A909B109B3-09B509BA09BB09C509C609C909CA09CF-09D609D8-09DB09DE09E409E509FC-0A000A040A0B-0A0E0A110A120A290A310A340A370A3A0A3B0A3D0A43-0A460A490A4A0A4E-0A500A52-0A580A5D0A5F-0A650A76-0A800A840A8E0A920AA90AB10AB40ABA0ABB0AC60ACA0ACE0ACF0AD1-0ADF0AE40AE50AF00AF2-0B000B040B0D0B0E0B110B120B290B310B340B3A0B3B0B450B460B490B4A0B4E-0B550B58-0B5B0B5E0B640B650B72-0B810B840B8B-0B8D0B910B96-0B980B9B0B9D0BA0-0BA20BA5-0BA70BAB-0BAD0BBA-0BBD0BC3-0BC50BC90BCE0BCF0BD1-0BD60BD8-0BE50BFB-0C000C040C0D0C110C290C340C3A-0C3C0C450C490C4E-0C540C570C5A-0C5F0C640C650C70-0C770C800C810C840C8D0C910CA90CB40CBA0CBB0CC50CC90CCE-0CD40CD7-0CDD0CDF0CE40CE50CF00CF3-0D010D040D0D0D110D290D3A-0D3C0D450D490D4E-0D560D58-0D5F0D640D650D76-0D780D800D810D840D97-0D990DB20DBC0DBE0DBF0DC7-0DC90DCB-0DCE0DD50DD70DE0-0DF10DF5-0E000E3B-0E3E0E5C-0E800E830E850E860E890E8B0E8C0E8E-0E930E980EA00EA40EA60EA80EA90EAC0EBA0EBE0EBF0EC50EC70ECE0ECF0EDA0EDB0EDE-0EFF0F480F6D-0F700F8C-0F8F0F980FBD0FCD0FD9-0FFF10C6-10CF10FD-10FF1249124E124F12571259125E125F1289128E128F12B112B612B712BF12C112C612C712D7131113161317135B-135E137D-137F139A-139F13F5-13FF169D-169F16F1-16FF170D1715-171F1737-173F1754-175F176D17711774-177F17DE17DF17EA-17EF17FA-17FF180F181A-181F1878-187F18AB-18AF18F6-18FF191D-191F192C-192F193C-193F1941-1943196E196F1975-197F19AC-19AF19CA-19CF19DB-19DD1A1C1A1D1A5F1A7D1A7E1A8A-1A8F1A9A-1A9F1AAE-1AFF1B4C-1B4F1B7D-1B7F1BAB-1BAD1BBA-1BFF1C38-1C3A1C4A-1C4C1C80-1CCF1CF3-1CFF1DE7-1DFC1F161F171F1E1F1F1F461F471F4E1F4F1F581F5A1F5C1F5E1F7E1F7F1FB51FC51FD41FD51FDC1FF01FF11FF51FFF2065-206920722073208F2095-209F20B9-20CF20F1-20FF218A-218F23E9-23FF2427-243F244B-245F26CE26E226E4-26E727002705270A270B2728274C274E2753-2755275F27602795-279727B027BF27CB27CD-27CF2B4D-2B4F2B5A-2BFF2C2F2C5F2CF2-2CF82D26-2D2F2D66-2D6E2D70-2D7F2D97-2D9F2DA72DAF2DB72DBF2DC72DCF2DD72DDF2E32-2E7F2E9A2EF4-2EFF2FD6-2FEF2FFC-2FFF3040309730983100-3104312E-3130318F31B8-31BF31E4-31EF321F32FF4DB6-4DBF9FCC-9FFFA48D-A48FA4C7-A4CFA62C-A63FA660A661A674-A67BA698-A69FA6F8-A6FFA78D-A7FAA82C-A82FA83A-A83FA878-A87FA8C5-A8CDA8DA-A8DFA8FC-A8FFA954-A95EA97D-A97FA9CEA9DA-A9DDA9E0-A9FFAA37-AA3FAA4EAA4FAA5AAA5BAA7C-AA7FAAC3-AADAAAE0-ABBFABEEABEFABFA-ABFFD7A4-D7AFD7C7-D7CAD7FC-D7FFFA2EFA2FFA6EFA6FFADA-FAFFFB07-FB12FB18-FB1CFB37FB3DFB3FFB42FB45FBB2-FBD2FD40-FD4FFD90FD91FDC8-FDEFFDFEFDFFFE1A-FE1FFE27-FE2FFE53FE67FE6C-FE6FFE75FEFDFEFEFF00FFBF-FFC1FFC8FFC9FFD0FFD1FFD8FFD9FFDD-FFDFFFE7FFEF-FFF8FFFEFFFF"})}),define("ace/mode/text",["require","exports","module","ace/tokenizer","ace/mode/text_highlight_rules","ace/mode/behaviour/cstyle","ace/unicode","ace/lib/lang","ace/token_iterator","ace/range"],function(e,t,n){"use strict";var r=e("../tokenizer").Tokenizer,i=e("./text_highlight_rules").TextHighlightRules,s=e("./behaviour/cstyle").CstyleBehaviour,o=e("../unicode"),u=e("../lib/lang"),a=e("../token_iterator").TokenIterator,f=e("../range").Range,l=function(){this.HighlightRules=i};(function(){this.$defaultBehaviour=new s,this.tokenRe=new RegExp("^["+o.packages.L+o.packages.Mn+o.packages.Mc+o.packages.Nd+o.packages.Pc+"\\$_]+","g"),this.nonTokenRe=new RegExp("^(?:[^"+o.packages.L+o.packages.Mn+o.packages.Mc+o.packages.Nd+o.packages.Pc+"\\$_]|\\s])+","g"),this.getTokenizer=function(){return this.$tokenizer||(this.$highlightRules=this.$highlightRules||new this.HighlightRules(this.$highlightRuleConfig),this.$tokenizer=new r(this.$highlightRules.getRules())),this.$tokenizer},this.lineCommentStart="",this.blockComment="",this.toggleCommentLines=function(e,t,n,r){function w(e){for(var t=n;t<=r;t++)e(i.getLine(t),t)}var i=t.doc,s=!0,o=!0,a=Infinity,f=t.getTabSize(),l=!1;if(!this.lineCommentStart){if(!this.blockComment)return!1;var c=this.blockComment.start,h=this.blockComment.end,p=new RegExp("^(\\s*)(?:"+u.escapeRegExp(c)+")"),d=new RegExp("(?:"+u.escapeRegExp(h)+")\\s*$"),v=function(e,t){if(g(e,t))return;if(!s||/\S/.test(e))i.insertInLine({row:t,column:e.length},h),i.insertInLine({row:t,column:a},c)},m=function(e,t){var n;(n=e.match(d))&&i.removeInLine(t,e.length-n[0].length,e.length),(n=e.match(p))&&i.removeInLine(t,n[1].length,n[0].length)},g=function(e,n){if(p.test(e))return!0;var r=t.getTokens(n);for(var i=0;i2?r%f!=f-1:r%f==0}}var E=Infinity;w(function(e,t){var n=e.search(/\S/);n!==-1?(ne.length&&(E=e.length)}),a==Infinity&&(a=E,s=!1,o=!1),l&&a%f!=0&&(a=Math.floor(a/f)*f),w(o?m:v)},this.toggleBlockComment=function(e,t,n,r){var i=this.blockComment;if(!i)return;!i.start&&i[0]&&(i=i[0]);var s=new a(t,r.row,r.column),o=s.getCurrentToken(),u=t.selection,l=t.selection.toOrientedRange(),c,h;if(o&&/comment/.test(o.type)){var p,d;while(o&&/comment/.test(o.type)){var v=o.value.indexOf(i.start);if(v!=-1){var m=s.getCurrentTokenRow(),g=s.getCurrentTokenColumn()+v;p=new f(m,g,m,g+i.start.length);break}o=s.stepBackward()}var s=new a(t,r.row,r.column),o=s.getCurrentToken();while(o&&/comment/.test(o.type)){var v=o.value.indexOf(i.end);if(v!=-1){var m=s.getCurrentTokenRow(),g=s.getCurrentTokenColumn()+v;d=new f(m,g,m,g+i.end.length);break}o=s.stepForward()}d&&t.remove(d),p&&(t.remove(p),c=p.start.row,h=-i.start.length)}else h=i.start.length,c=n.start.row,t.insert(n.end,i.end),t.insert(n.start,i.start);l.start.row==c&&(l.start.column+=h),l.end.row==c&&(l.end.column+=h),t.selection.fromOrientedRange(l)},this.getNextLineIndent=function(e,t,n){return this.$getIndent(t)},this.checkOutdent=function(e,t,n){return!1},this.autoOutdent=function(e,t,n){},this.$getIndent=function(e){return e.match(/^\s*/)[0]},this.createWorker=function(e){return null},this.createModeDelegates=function(e){this.$embeds=[],this.$modes={};for(var t in e)e[t]&&(this.$embeds.push(t),this.$modes[t]=new e[t]);var n=["toggleBlockComment","toggleCommentLines","getNextLineIndent","checkOutdent","autoOutdent","transformAction","getCompletions"];for(var t=0;t=0&&t.row=0&&t.column<=e[t.row].length}function s(e,t){t.action!="insert"&&t.action!="remove"&&r(t,"delta.action must be 'insert' or 'remove'"),t.lines instanceof Array||r(t,"delta.lines must be an Array"),(!t.start||!t.end)&&r(t,"delta.start/end must be an present");var n=t.start;i(e,t.start)||r(t,"delta.start must be contained in document");var s=t.end;t.action=="remove"&&!i(e,s)&&r(t,"delta.end must contained in document for 'remove' actions");var o=s.row-n.row,u=s.column-(o==0?n.column:0);(o!=t.lines.length-1||t.lines[o].length!=u)&&r(t,"delta.range must match delta lines")}t.applyDelta=function(e,t,n){var r=t.start.row,i=t.start.column,s=e[r]||"";switch(t.action){case"insert":var o=t.lines;if(o.length===1)e[r]=s.substring(0,i)+t.lines[0]+s.substring(i);else{var u=[r,1].concat(t.lines);e.splice.apply(e,u),e[r]=s.substring(0,i)+e[r],e[r+t.lines.length-1]+=s.substring(i)}break;case"remove":var a=t.end.column,f=t.end.row;r===f?e[r]=s.substring(0,i)+s.substring(a):e.splice(r,f-r+1,s.substring(0,i)+e[f].substring(a))}}}),define("ace/anchor",["require","exports","module","ace/lib/oop","ace/lib/event_emitter"],function(e,t,n){"use strict";var r=e("./lib/oop"),i=e("./lib/event_emitter").EventEmitter,s=t.Anchor=function(e,t,n){this.$onChange=this.onChange.bind(this),this.attach(e),typeof n=="undefined"?this.setPosition(t.row,t.column):this.setPosition(t,n)};(function(){function e(e,t,n){var r=n?e.column<=t.column:e.columnthis.row)return;var n=t(e,{row:this.row,column:this.column},this.$insertRight);this.setPosition(n.row,n.column,!0)},this.setPosition=function(e,t,n){var r;n?r={row:e,column:t}:r=this.$clipPositionToDocument(e,t);if(this.row==r.row&&this.column==r.column)return;var i={row:this.row,column:this.column};this.row=r.row,this.column=r.column,this._signal("change",{old:i,value:r})},this.detach=function(){this.document.removeEventListener("change",this.$onChange)},this.attach=function(e){this.document=e||this.document,this.document.on("change",this.$onChange)},this.$clipPositionToDocument=function(e,t){var n={};return e>=this.document.getLength()?(n.row=Math.max(0,this.document.getLength()-1),n.column=this.document.getLine(n.row).length):e<0?(n.row=0,n.column=0):(n.row=e,n.column=Math.min(this.document.getLine(n.row).length,Math.max(0,t))),t<0&&(n.column=0),n}}).call(s.prototype)}),define("ace/document",["require","exports","module","ace/lib/oop","ace/apply_delta","ace/lib/event_emitter","ace/range","ace/anchor"],function(e,t,n){"use strict";var r=e("./lib/oop"),i=e("./apply_delta").applyDelta,s=e("./lib/event_emitter").EventEmitter,o=e("./range").Range,u=e("./anchor").Anchor,a=function(e){this.$lines=[""],e.length===0?this.$lines=[""]:Array.isArray(e)?this.insertMergedLines({row:0,column:0},e):this.insert({row:0,column:0},e)};(function(){r.implement(this,s),this.setValue=function(e){var t=this.getLength()-1;this.remove(new o(0,0,t,this.getLine(t).length)),this.insert({row:0,column:0},e)},this.getValue=function(){return this.getAllLines().join(this.getNewLineCharacter())},this.createAnchor=function(e,t){return new u(this,e,t)},"aaa".split(/a/).length===0?this.$split=function(e){return e.replace(/\r\n|\r/g,"\n").split("\n")}:this.$split=function(e){return e.split(/\r\n|\r|\n/)},this.$detectNewLine=function(e){var t=e.match(/^.*?(\r\n|\r|\n)/m);this.$autoNewLine=t?t[1]:"\n",this._signal("changeNewLineMode")},this.getNewLineCharacter=function(){switch(this.$newLineMode){case"windows":return"\r\n";case"unix":return"\n";default:return this.$autoNewLine||"\n"}},this.$autoNewLine="",this.$newLineMode="auto",this.setNewLineMode=function(e){if(this.$newLineMode===e)return;this.$newLineMode=e,this._signal("changeNewLineMode")},this.getNewLineMode=function(){return this.$newLineMode},this.isNewLine=function(e){return e=="\r\n"||e=="\r"||e=="\n"},this.getLine=function(e){return this.$lines[e]||""},this.getLines=function(e,t){return this.$lines.slice(e,t+1)},this.getAllLines=function(){return this.getLines(0,this.getLength())},this.getLength=function(){return this.$lines.length},this.getTextRange=function(e){return this.getLinesForRange(e).join(this.getNewLineCharacter())},this.getLinesForRange=function(e){var t;if(e.start.row===e.end.row)t=[this.getLine(e.start.row).substring(e.start.column,e.end.column)];else{t=this.getLines(e.start.row,e.end.row),t[0]=(t[0]||"").substring(e.start.column);var n=t.length-1;e.end.row-e.start.row==n&&(t[n]=t[n].substring(0,e.end.column))}return t},this.insertLines=function(e,t){return console.warn("Use of document.insertLines is deprecated. Use the insertFullLines method instead."),this.insertFullLines(e,t)},this.removeLines=function(e,t){return console.warn("Use of document.removeLines is deprecated. Use the removeFullLines method instead."),this.removeFullLines(e,t)},this.insertNewLine=function(e){return console.warn("Use of document.insertNewLine is deprecated. Use insertMergedLines(position, ['', '']) instead."),this.insertMergedLines(e,["",""])},this.insert=function(e,t){return this.getLength()<=1&&this.$detectNewLine(t),this.insertMergedLines(e,this.$split(t))},this.insertInLine=function(e,t){var n=this.clippedPos(e.row,e.column),r=this.pos(e.row,e.column+t.length);return this.applyDelta({start:n,end:r,action:"insert",lines:[t]},!0),this.clonePos(r)},this.clippedPos=function(e,t){var n=this.getLength();e===undefined?e=n:e<0?e=0:e>=n&&(e=n-1,t=undefined);var r=this.getLine(e);return t==undefined&&(t=r.length),t=Math.min(Math.max(t,0),r.length),{row:e,column:t}},this.clonePos=function(e){return{row:e.row,column:e.column}},this.pos=function(e,t){return{row:e,column:t}},this.$clipPosition=function(e){var t=this.getLength();return e.row>=t?(e.row=Math.max(0,t-1),e.column=this.getLine(t-1).length):(e.row=Math.max(0,e.row),e.column=Math.min(Math.max(e.column,0),this.getLine(e.row).length)),e},this.insertFullLines=function(e,t){e=Math.min(Math.max(e,0),this.getLength());var n=0;e0,r=t=0&&this.applyDelta({start:this.pos(e,this.getLine(e).length),end:this.pos(e+1,0),action:"remove",lines:["",""]})},this.replace=function(e,t){e instanceof o||(e=o.fromPoints(e.start,e.end));if(t.length===0&&e.isEmpty())return e.start;if(t==this.getTextRange(e))return e.end;this.remove(e);var n;return t?n=this.insert(e.start,t):n=e.start,n},this.applyDeltas=function(e){for(var t=0;t=0;t--)this.revertDelta(e[t])},this.applyDelta=function(e,t){var n=e.action=="insert";if(n?e.lines.length<=1&&!e.lines[0]:!o.comparePoints(e.start,e.end))return;n&&e.lines.length>2e4&&this.$splitAndapplyLargeDelta(e,2e4),i(this.$lines,e,t),this._signal("change",e)},this.$splitAndapplyLargeDelta=function(e,t){var n=e.lines,r=n.length,i=e.start.row,s=e.start.column,o=0,u=0;do{o=u,u+=t-1;var a=n.slice(o,u);if(u>r){e.lines=a,e.start.row=i+o,e.start.column=s;break}a.push(""),this.applyDelta({start:this.pos(i+o,s),end:this.pos(i+u,s=0),action:e.action,lines:a},!0)}while(!0)},this.revertDelta=function(e){this.applyDelta({start:this.clonePos(e.start),end:this.clonePos(e.end),action:e.action=="insert"?"remove":"insert",lines:e.lines.slice()})},this.indexToPosition=function(e,t){var n=this.$lines||this.getAllLines(),r=this.getNewLineCharacter().length;for(var i=t||0,s=n.length;i20){n.running=setTimeout(n.$worker,20);break}}n.currentLine=t,s<=r&&n.fireUpdateEvent(s,r)}};(function(){r.implement(this,i),this.setTokenizer=function(e){this.tokenizer=e,this.lines=[],this.states=[],this.start(0)},this.setDocument=function(e){this.doc=e,this.lines=[],this.states=[],this.stop()},this.fireUpdateEvent=function(e,t){var n={first:e,last:t};this._signal("update",{data:n})},this.start=function(e){this.currentLine=Math.min(e||0,this.currentLine,this.doc.getLength()),this.lines.splice(this.currentLine,this.lines.length),this.states.splice(this.currentLine,this.states.length),this.stop(),this.running=setTimeout(this.$worker,700)},this.scheduleStart=function(){this.running||(this.running=setTimeout(this.$worker,700))},this.$updateOnChange=function(e){var t=e.start.row,n=e.end.row-t;if(n===0)this.lines[t]=null;else if(e.action=="remove")this.lines.splice(t,n+1,null),this.states.splice(t,n+1,null);else{var r=Array(n+1);r.unshift(t,1),this.lines.splice.apply(this.lines,r),this.states.splice.apply(this.states,r)}this.currentLine=Math.min(t,this.currentLine,this.doc.getLength()),this.stop()},this.stop=function(){this.running&&clearTimeout(this.running),this.running=!1},this.getTokens=function(e){return this.lines[e]||this.$tokenizeRow(e)},this.getState=function(e){return this.currentLine==e&&this.$tokenizeRow(e),this.states[e]||"start"},this.$tokenizeRow=function(e){var t=this.doc.getLine(e),n=this.states[e-1],r=this.tokenizer.getLineTokens(t,n,e);return this.states[e]+""!=r.state+""?(this.states[e]=r.state,this.lines[e+1]=null,this.currentLine>e+1&&(this.currentLine=e+1)):this.currentLine==e&&(this.currentLine=e+1),this.lines[e]=r.tokens}}).call(s.prototype),t.BackgroundTokenizer=s}),define("ace/search_highlight",["require","exports","module","ace/lib/lang","ace/lib/oop","ace/range"],function(e,t,n){"use strict";var r=e("./lib/lang"),i=e("./lib/oop"),s=e("./range").Range,o=function(e,t,n){this.setRegexp(e),this.clazz=t,this.type=n||"text"};(function(){this.MAX_RANGES=500,this.setRegexp=function(e){if(this.regExp+""==e+"")return;this.regExp=e,this.cache=[]},this.update=function(e,t,n,i){if(!this.regExp)return;var o=i.firstRow,u=i.lastRow;for(var a=o;a<=u;a++){var f=this.cache[a];f==null&&(f=r.getMatchOffsets(n.getLine(a),this.regExp),f.length>this.MAX_RANGES&&(f=f.slice(0,this.MAX_RANGES)),f=f.map(function(e){return new s(a,e.offset,a,e.offset+e.length)}),this.cache[a]=f.length?f:"");for(var l=f.length;l--;)t.drawSingleLineMarker(e,f[l].toScreenRange(n),this.clazz,i)}}}).call(o.prototype),t.SearchHighlight=o}),define("ace/edit_session/fold_line",["require","exports","module","ace/range"],function(e,t,n){"use strict";function i(e,t){this.foldData=e,Array.isArray(t)?this.folds=t:t=this.folds=[t];var n=t[t.length-1];this.range=new r(t[0].start.row,t[0].start.column,n.end.row,n.end.column),this.start=this.range.start,this.end=this.range.end,this.folds.forEach(function(e){e.setFoldLine(this)},this)}var r=e("../range").Range;(function(){this.shiftRow=function(e){this.start.row+=e,this.end.row+=e,this.folds.forEach(function(t){t.start.row+=e,t.end.row+=e})},this.addFold=function(e){if(e.sameRow){if(e.start.rowthis.endRow)throw new Error("Can't add a fold to this FoldLine as it has no connection");this.folds.push(e),this.folds.sort(function(e,t){return-e.range.compareEnd(t.start.row,t.start.column)}),this.range.compareEnd(e.start.row,e.start.column)>0?(this.end.row=e.end.row,this.end.column=e.end.column):this.range.compareStart(e.end.row,e.end.column)<0&&(this.start.row=e.start.row,this.start.column=e.start.column)}else if(e.start.row==this.end.row)this.folds.push(e),this.end.row=e.end.row,this.end.column=e.end.column;else{if(e.end.row!=this.start.row)throw new Error("Trying to add fold to FoldRow that doesn't have a matching row");this.folds.unshift(e),this.start.row=e.start.row,this.start.column=e.start.column}e.foldLine=this},this.containsRow=function(e){return e>=this.start.row&&e<=this.end.row},this.walk=function(e,t,n){var r=0,i=this.folds,s,o,u,a=!0;t==null&&(t=this.end.row,n=this.end.column);for(var f=0;f0)continue;var a=i(e,o.start);return u===0?t&&a!==0?-s-2:s:a>0||a===0&&!t?s:-s-1}return-s-1},this.add=function(e){var t=!e.isEmpty(),n=this.pointIndex(e.start,t);n<0&&(n=-n-1);var r=this.pointIndex(e.end,t,n);return r<0?r=-r-1:r++,this.ranges.splice(n,r-n,e)},this.addList=function(e){var t=[];for(var n=e.length;n--;)t.push.apply(t,this.add(e[n]));return t},this.substractPoint=function(e){var t=this.pointIndex(e);if(t>=0)return this.ranges.splice(t,1)},this.merge=function(){var e=[],t=this.ranges;t=t.sort(function(e,t){return i(e.start,t.start)});var n=t[0],r;for(var s=1;s=0},this.containsPoint=function(e){return this.pointIndex(e)>=0},this.rangeAtPoint=function(e){var t=this.pointIndex(e);if(t>=0)return this.ranges[t]},this.clipRows=function(e,t){var n=this.ranges;if(n[0].start.row>t||n[n.length-1].start.rowr)break;l.start.row==r&&l.start.column>=t.column&&(l.start.column!=t.column||!this.$insertRight)&&(l.start.column+=o,l.start.row+=s);if(l.end.row==r&&l.end.column>=t.column){if(l.end.column==t.column&&this.$insertRight)continue;l.end.column==t.column&&o>0&&al.start.column&&l.end.column==u[a+1].start.column&&(l.end.column-=o),l.end.column+=o,l.end.row+=s}}if(s!=0&&a=e)return i;if(i.end.row>e)return null}return null},this.getNextFoldLine=function(e,t){var n=this.$foldData,r=0;t&&(r=n.indexOf(t)),r==-1&&(r=0);for(r;r=e)return i}return null},this.getFoldedRowCount=function(e,t){var n=this.$foldData,r=t-e+1;for(var i=0;i=t){u=e?r-=t-u:r=0);break}o>=e&&(u>=e?r-=o-u:r-=o-e+1)}return r},this.$addFoldLine=function(e){return this.$foldData.push(e),this.$foldData.sort(function(e,t){return e.start.row-t.start.row}),e},this.addFold=function(e,t){var n=this.$foldData,r=!1,o;e instanceof s?o=e:(o=new s(t,e),o.collapseChildren=t.collapseChildren),this.$clipRangeToDocument(o.range);var u=o.start.row,a=o.start.column,f=o.end.row,l=o.end.column;if(u0&&(this.removeFolds(p),p.forEach(function(e){o.addSubFold(e)}));for(var d=0;d0&&this.foldAll(e.start.row+1,e.end.row,e.collapseChildren-1),e.subFolds=[]},this.expandFolds=function(e){e.forEach(function(e){this.expandFold(e)},this)},this.unfold=function(e,t){var n,i;e==null?(n=new r(0,0,this.getLength(),0),t=!0):typeof e=="number"?n=new r(e,0,e,this.getLine(e).length):"row"in e?n=r.fromPoints(e,e):n=e,i=this.getFoldsInRangeList(n);if(t)this.removeFolds(i);else{var s=i;while(s.length)this.expandFolds(s),s=this.getFoldsInRangeList(n)}if(i.length)return i},this.isRowFolded=function(e,t){return!!this.getFoldLine(e,t)},this.getRowFoldEnd=function(e,t){var n=this.getFoldLine(e,t);return n?n.end.row:e},this.getRowFoldStart=function(e,t){var n=this.getFoldLine(e,t);return n?n.start.row:e},this.getFoldDisplayLine=function(e,t,n,r,i){r==null&&(r=e.start.row),i==null&&(i=0),t==null&&(t=e.end.row),n==null&&(n=this.getLine(t).length);var s=this.doc,o="";return e.walk(function(e,t,n,u){if(t=e){i=s.end.row;try{var o=this.addFold("...",s);o&&(o.collapseChildren=n)}catch(u){}}}},this.$foldStyles={manual:1,markbegin:1,markbeginend:1},this.$foldStyle="markbegin",this.setFoldStyle=function(e){if(!this.$foldStyles[e])throw new Error("invalid fold style: "+e+"["+Object.keys(this.$foldStyles).join(", ")+"]");if(this.$foldStyle==e)return;this.$foldStyle=e,e=="manual"&&this.unfold();var t=this.$foldMode;this.$setFolding(null),this.$setFolding(t)},this.$setFolding=function(e){if(this.$foldMode==e)return;this.$foldMode=e,this.off("change",this.$updateFoldWidgets),this.off("tokenizerUpdate",this.$tokenizerUpdateFoldWidgets),this._signal("changeAnnotation");if(!e||this.$foldStyle=="manual"){this.foldWidgets=null;return}this.foldWidgets=[],this.getFoldWidget=e.getFoldWidget.bind(e,this,this.$foldStyle),this.getFoldWidgetRange=e.getFoldWidgetRange.bind(e,this,this.$foldStyle),this.$updateFoldWidgets=this.updateFoldWidgets.bind(this),this.$tokenizerUpdateFoldWidgets=this.tokenizerUpdateFoldWidgets.bind(this),this.on("change",this.$updateFoldWidgets),this.on("tokenizerUpdate",this.$tokenizerUpdateFoldWidgets)},this.getParentFoldRangeData=function(e,t){var n=this.foldWidgets;if(!n||t&&n[e])return{};var r=e-1,i;while(r>=0){var s=n[r];s==null&&(s=n[r]=this.getFoldWidget(r));if(s=="start"){var o=this.getFoldWidgetRange(r);i||(i=o);if(o&&o.end.row>=e)break}r--}return{range:r!==-1&&o,firstRange:i}},this.onFoldWidgetClick=function(e,t){t=t.domEvent;var n={children:t.shiftKey,all:t.ctrlKey||t.metaKey,siblings:t.altKey},r=this.$toggleFoldWidget(e,n);if(!r){var i=t.target||t.srcElement;i&&/ace_fold-widget/.test(i.className)&&(i.className+=" ace_invalid")}},this.$toggleFoldWidget=function(e,t){if(!this.getFoldWidget)return;var n=this.getFoldWidget(e),r=this.getLine(e),i=n==="end"?-1:1,s=this.getFoldAt(e,i===-1?0:r.length,i);if(s)return t.children||t.all?this.removeFold(s):this.expandFold(s),s;var o=this.getFoldWidgetRange(e,!0);if(o&&!o.isMultiLine()){s=this.getFoldAt(o.start.row,o.start.column,1);if(s&&o.isEqual(s.range))return this.removeFold(s),s}if(t.siblings){var u=this.getParentFoldRangeData(e);if(u.range)var a=u.range.start.row+1,f=u.range.end.row;this.foldAll(a,f,t.all?1e4:0)}else t.children?(f=o?o.end.row:this.getLength(),this.foldAll(e+1,f,t.all?1e4:0)):o&&(t.all&&(o.collapseChildren=1e4),this.addFold("...",o));return o},this.toggleFoldWidget=function(e){var t=this.selection.getCursor().row;t=this.getRowFoldStart(t);var n=this.$toggleFoldWidget(t,{});if(n)return;var r=this.getParentFoldRangeData(t,!0);n=r.range||r.firstRange;if(n){t=n.start.row;var i=this.getFoldAt(t,this.getLine(t).length,1);i?this.removeFold(i):this.addFold("...",n)}},this.updateFoldWidgets=function(e){var t=e.start.row,n=e.end.row-t;if(n===0)this.foldWidgets[t]=null;else if(e.action=="remove")this.foldWidgets.splice(t,n+1,null);else{var r=Array(n+1);r.unshift(t,1),this.foldWidgets.splice.apply(this.foldWidgets,r)}},this.tokenizerUpdateFoldWidgets=function(e){var t=e.data;t.first!=t.last&&this.foldWidgets.length>t.first&&this.foldWidgets.splice(t.first,this.foldWidgets.length)}}var r=e("../range").Range,i=e("./fold_line").FoldLine,s=e("./fold").Fold,o=e("../token_iterator").TokenIterator;t.Folding=u}),define("ace/edit_session/bracket_match",["require","exports","module","ace/token_iterator","ace/range"],function(e,t,n){"use strict";function s(){this.findMatchingBracket=function(e,t){if(e.column==0)return null;var n=t||this.getLine(e.row).charAt(e.column-1);if(n=="")return null;var r=n.match(/([\(\[\{])|([\)\]\}])/);return r?r[1]?this.$findClosingBracket(r[1],e):this.$findOpeningBracket(r[2],e):null},this.getBracketRange=function(e){var t=this.getLine(e.row),n=!0,r,s=t.charAt(e.column-1),o=s&&s.match(/([\(\[\{])|([\)\]\}])/);o||(s=t.charAt(e.column),e={row:e.row,column:e.column+1},o=s&&s.match(/([\(\[\{])|([\)\]\}])/),n=!1);if(!o)return null;if(o[1]){var u=this.$findClosingBracket(o[1],e);if(!u)return null;r=i.fromPoints(e,u),n||(r.end.column++,r.start.column--),r.cursor=r.end}else{var u=this.$findOpeningBracket(o[2],e);if(!u)return null;r=i.fromPoints(u,e),n||(r.start.column++,r.end.column--),r.cursor=r.start}return r},this.$brackets={")":"(","(":")","]":"[","[":"]","{":"}","}":"{"},this.$findOpeningBracket=function(e,t,n){var i=this.$brackets[e],s=1,o=new r(this,t.row,t.column),u=o.getCurrentToken();u||(u=o.stepForward());if(!u)return;n||(n=new RegExp("(\\.?"+u.type.replace(".","\\.").replace("rparen",".paren").replace(/\b(?:end)\b/,"(?:start|begin|end)")+")+"));var a=t.column-o.getCurrentTokenColumn()-2,f=u.value;for(;;){while(a>=0){var l=f.charAt(a);if(l==i){s-=1;if(s==0)return{row:o.getCurrentTokenRow(),column:a+o.getCurrentTokenColumn()}}else l==e&&(s+=1);a-=1}do u=o.stepBackward();while(u&&!n.test(u.type));if(u==null)break;f=u.value,a=f.length-1}return null},this.$findClosingBracket=function(e,t,n){var i=this.$brackets[e],s=1,o=new r(this,t.row,t.column),u=o.getCurrentToken();u||(u=o.stepForward());if(!u)return;n||(n=new RegExp("(\\.?"+u.type.replace(".","\\.").replace("lparen",".paren").replace(/\b(?:start|begin)\b/,"(?:start|begin|end)")+")+"));var a=t.column-o.getCurrentTokenColumn();for(;;){var f=u.value,l=f.length;while(a=4352&&e<=4447||e>=4515&&e<=4519||e>=4602&&e<=4607||e>=9001&&e<=9002||e>=11904&&e<=11929||e>=11931&&e<=12019||e>=12032&&e<=12245||e>=12272&&e<=12283||e>=12288&&e<=12350||e>=12353&&e<=12438||e>=12441&&e<=12543||e>=12549&&e<=12589||e>=12593&&e<=12686||e>=12688&&e<=12730||e>=12736&&e<=12771||e>=12784&&e<=12830||e>=12832&&e<=12871||e>=12880&&e<=13054||e>=13056&&e<=19903||e>=19968&&e<=42124||e>=42128&&e<=42182||e>=43360&&e<=43388||e>=44032&&e<=55203||e>=55216&&e<=55238||e>=55243&&e<=55291||e>=63744&&e<=64255||e>=65040&&e<=65049||e>=65072&&e<=65106||e>=65108&&e<=65126||e>=65128&&e<=65131||e>=65281&&e<=65376||e>=65504&&e<=65510}r.implement(this,o),this.setDocument=function(e){this.doc&&this.doc.removeListener("change",this.$onChange),this.doc=e,e.on("change",this.$onChange),this.bgTokenizer&&this.bgTokenizer.setDocument(this.getDocument()),this.resetCaches()},this.getDocument=function(){return this.doc},this.$resetRowCache=function(e){if(!e){this.$docRowCache=[],this.$screenRowCache=[];return}var t=this.$docRowCache.length,n=this.$getRowCacheIndex(this.$docRowCache,e)+1;t>n&&(this.$docRowCache.splice(n,t),this.$screenRowCache.splice(n,t))},this.$getRowCacheIndex=function(e,t){var n=0,r=e.length-1;while(n<=r){var i=n+r>>1,s=e[i];if(t>s)n=i+1;else{if(!(t=t)break}return r=n[s],r?(r.index=s,r.start=i-r.value.length,r):null},this.setUndoManager=function(e){this.$undoManager=e,this.$deltas=[],this.$deltasDoc=[],this.$deltasFold=[],this.$informUndoManager&&this.$informUndoManager.cancel();if(e){var t=this;this.$syncInformUndoManager=function(){t.$informUndoManager.cancel(),t.$deltasFold.length&&(t.$deltas.push({group:"fold",deltas:t.$deltasFold}),t.$deltasFold=[]),t.$deltasDoc.length&&(t.$deltas.push({group:"doc",deltas:t.$deltasDoc}),t.$deltasDoc=[]),t.$deltas.length>0&&e.execute({action:"aceupdate",args:[t.$deltas,t],merge:t.mergeUndoDeltas}),t.mergeUndoDeltas=!1,t.$deltas=[]},this.$informUndoManager=i.delayedCall(this.$syncInformUndoManager)}},this.markUndoGroup=function(){this.$syncInformUndoManager&&this.$syncInformUndoManager()},this.$defaultUndoManager={undo:function(){},redo:function(){},reset:function(){}},this.getUndoManager=function(){return this.$undoManager||this.$defaultUndoManager},this.getTabString=function(){return this.getUseSoftTabs()?i.stringRepeat(" ",this.getTabSize()):" "},this.setUseSoftTabs=function(e){this.setOption("useSoftTabs",e)},this.getUseSoftTabs=function(){return this.$useSoftTabs&&!this.$mode.$indentWithTabs},this.setTabSize=function(e){this.setOption("tabSize",e)},this.getTabSize=function(){return this.$tabSize},this.isTabStop=function(e){return this.$useSoftTabs&&e.column%this.$tabSize===0},this.$overwrite=!1,this.setOverwrite=function(e){this.setOption("overwrite",e)},this.getOverwrite=function(){return this.$overwrite},this.toggleOverwrite=function(){this.setOverwrite(!this.$overwrite)},this.addGutterDecoration=function(e,t){this.$decorations[e]||(this.$decorations[e]=""),this.$decorations[e]+=" "+t,this._signal("changeBreakpoint",{})},this.removeGutterDecoration=function(e,t){this.$decorations[e]=(this.$decorations[e]||"").replace(" "+t,""),this._signal("changeBreakpoint",{})},this.getBreakpoints=function(){return this.$breakpoints},this.setBreakpoints=function(e){this.$breakpoints=[];for(var t=0;t0&&(r=!!n.charAt(t-1).match(this.tokenRe)),r||(r=!!n.charAt(t).match(this.tokenRe));if(r)var i=this.tokenRe;else if(/^\s+$/.test(n.slice(t-1,t+1)))var i=/\s/;else var i=this.nonTokenRe;var s=t;if(s>0){do s--;while(s>=0&&n.charAt(s).match(i));s++}var o=t;while(oe&&(e=t.screenWidth)}),this.lineWidgetWidth=e},this.$computeWidth=function(e){if(this.$modified||e){this.$modified=!1;if(this.$useWrapMode)return this.screenWidth=this.$wrapLimit;var t=this.doc.getAllLines(),n=this.$rowLengthCache,r=0,i=0,s=this.$foldData[i],o=s?s.start.row:Infinity,u=t.length;for(var a=0;ao){a=s.end.row+1;if(a>=u)break;s=this.$foldData[i++],o=s?s.start.row:Infinity}n[a]==null&&(n[a]=this.$getStringScreenWidth(t[a])[0]),n[a]>r&&(r=n[a])}this.screenWidth=r}},this.getLine=function(e){return this.doc.getLine(e)},this.getLines=function(e,t){return this.doc.getLines(e,t)},this.getLength=function(){return this.doc.getLength()},this.getTextRange=function(e){return this.doc.getTextRange(e||this.selection.getRange())},this.insert=function(e,t){return this.doc.insert(e,t)},this.remove=function(e){return this.doc.remove(e)},this.removeFullLines=function(e,t){return this.doc.removeFullLines(e,t)},this.undoChanges=function(e,t){if(!e.length)return;this.$fromUndo=!0;var n=null;for(var r=e.length-1;r!=-1;r--){var i=e[r];i.group=="doc"?(this.doc.revertDeltas(i.deltas),n=this.$getUndoSelection(i.deltas,!0,n)):i.deltas.forEach(function(e){this.addFolds(e.folds)},this)}return this.$fromUndo=!1,n&&this.$undoSelect&&!t&&this.selection.setSelectionRange(n),n},this.redoChanges=function(e,t){if(!e.length)return;this.$fromUndo=!0;var n=null;for(var r=0;re.end.column&&(s.start.column+=u),s.end.row==e.end.row&&s.end.column>e.end.column&&(s.end.column+=u)),o&&s.start.row>=e.end.row&&(s.start.row+=o,s.end.row+=o)}s.end=this.insert(s.start,r);if(i.length){var a=e.start,l=s.start,o=l.row-a.row,u=l.column-a.column;this.addFolds(i.map(function(e){return e=e.clone(),e.start.row==a.row&&(e.start.column+=u),e.end.row==a.row&&(e.end.column+=u),e.start.row+=o,e.end.row+=o,e}))}return s},this.indentRows=function(e,t,n){n=n.replace(/\t/g,this.getTabString());for(var r=e;r<=t;r++)this.doc.insertInLine({row:r,column:0},n)},this.outdentRows=function(e){var t=e.collapseRows(),n=new f(0,0,0,0),r=this.getTabSize();for(var i=t.start.row;i<=t.end.row;++i){var s=this.getLine(i);n.start.row=i,n.end.row=i;for(var o=0;o0){var r=this.getRowFoldEnd(t+n);if(r>this.doc.getLength()-1)return 0;var i=r-t}else{e=this.$clipRowToDocument(e),t=this.$clipRowToDocument(t);var i=t-e+1}var s=new f(e,0,t,Number.MAX_VALUE),o=this.getFoldsInRange(s).map(function(e){return e=e.clone(),e.start.row+=i,e.end.row+=i,e}),u=n==0?this.doc.getLines(e,t):this.doc.removeFullLines(e,t);return this.doc.insertFullLines(e+i,u),o.length&&this.addFolds(o),i},this.moveLinesUp=function(e,t){return this.$moveLines(e,t,-1)},this.moveLinesDown=function(e,t){return this.$moveLines(e,t,1)},this.duplicateLines=function(e,t){return this.$moveLines(e,t,0)},this.$clipRowToDocument=function(e){return Math.max(0,Math.min(e,this.doc.getLength()-1))},this.$clipColumnToRow=function(e,t){return t<0?0:Math.min(this.doc.getLine(e).length,t)},this.$clipPositionToDocument=function(e,t){t=Math.max(0,t);if(e<0)e=0,t=0;else{var n=this.doc.getLength();e>=n?(e=n-1,t=this.doc.getLine(n-1).length):t=Math.min(this.doc.getLine(e).length,t)}return{row:e,column:t}},this.$clipRangeToDocument=function(e){e.start.row<0?(e.start.row=0,e.start.column=0):e.start.column=this.$clipColumnToRow(e.start.row,e.start.column);var t=this.doc.getLength()-1;return e.end.row>t?(e.end.row=t,e.end.column=this.doc.getLine(t).length):e.end.column=this.$clipColumnToRow(e.end.row,e.end.column),e},this.$wrapLimit=80,this.$useWrapMode=!1,this.$wrapLimitRange={min:null,max:null},this.setUseWrapMode=function(e){if(e!=this.$useWrapMode){this.$useWrapMode=e,this.$modified=!0,this.$resetRowCache(0);if(e){var t=this.getLength();this.$wrapData=Array(t),this.$updateWrapData(0,t-1)}this._signal("changeWrapMode")}},this.getUseWrapMode=function(){return this.$useWrapMode},this.setWrapLimitRange=function(e,t){if(this.$wrapLimitRange.min!==e||this.$wrapLimitRange.max!==t)this.$wrapLimitRange={min:e,max:t},this.$modified=!0,this.$useWrapMode&&this._signal("changeWrapMode")},this.adjustWrapLimit=function(e,t){var n=this.$wrapLimitRange;n.max<0&&(n={min:t,max:t});var r=this.$constrainWrapLimit(e,n.min,n.max);return r!=this.$wrapLimit&&r>1?(this.$wrapLimit=r,this.$modified=!0,this.$useWrapMode&&(this.$updateWrapData(0,this.getLength()-1),this.$resetRowCache(0),this._signal("changeWrapLimit")),!0):!1},this.$constrainWrapLimit=function(e,t,n){return t&&(e=Math.max(t,e)),n&&(e=Math.min(n,e)),e},this.getWrapLimit=function(){return this.$wrapLimit},this.setWrapLimit=function(e){this.setWrapLimitRange(e,e)},this.getWrapLimitRange=function(){return{min:this.$wrapLimitRange.min,max:this.$wrapLimitRange.max}},this.$updateInternalDataOnChange=function(e){var t=this.$useWrapMode,n=e.action,r=e.start,i=e.end,s=r.row,o=i.row,u=o-s,a=null;this.$updating=!0;if(u!=0)if(n==="remove"){this[t?"$wrapData":"$rowLengthCache"].splice(s,u);var f=this.$foldData;a=this.getFoldsInRange(e),this.removeFolds(a);var l=this.getFoldLine(i.row),c=0;if(l){l.addRemoveChars(i.row,i.column,r.column-i.column),l.shiftRow(-u);var h=this.getFoldLine(s);h&&h!==l&&(h.merge(l),l=h),c=f.indexOf(l)+1}for(c;c=i.row&&l.shiftRow(-u)}o=s}else{var p=Array(u);p.unshift(s,0);var d=t?this.$wrapData:this.$rowLengthCache;d.splice.apply(d,p);var f=this.$foldData,l=this.getFoldLine(s),c=0;if(l){var v=l.range.compareInside(r.row,r.column);v==0?(l=l.split(r.row,r.column),l&&(l.shiftRow(u),l.addRemoveChars(o,0,i.column-r.column))):v==-1&&(l.addRemoveChars(s,0,i.column-r.column),l.shiftRow(u)),c=f.indexOf(l)+1}for(c;c=s&&l.shiftRow(u)}}else{u=Math.abs(e.start.column-e.end.column),n==="remove"&&(a=this.getFoldsInRange(e),this.removeFolds(a),u=-u);var l=this.getFoldLine(s);l&&l.addRemoveChars(s,r.column,u)}return t&&this.$wrapData.length!=this.doc.getLength()&&console.error("doc.getLength() and $wrapData.length have to be the same!"),this.$updating=!1,t?this.$updateWrapData(s,o):this.$updateRowLengthCache(s,o),a},this.$updateRowLengthCache=function(e,t,n){this.$rowLengthCache[e]=null,this.$rowLengthCache[t]=null},this.$updateWrapData=function(e,t){var r=this.doc.getAllLines(),i=this.getTabSize(),s=this.$wrapData,o=this.$wrapLimit,a,f,l=e;t=Math.min(t,r.length-1);while(l<=t)f=this.getFoldLine(l,f),f?(a=[],f.walk(function(e,t,i,s){var o;if(e!=null){o=this.$getDisplayTokens(e,a.length),o[0]=n;for(var f=1;fr-b){var w=a+r-b;if(e[w-1]>=p&&e[w]>=p){y(w);continue}if(e[w]==n||e[w]==u){for(w;w!=a-1;w--)if(e[w]==n)break;if(w>a){y(w);continue}w=a+r;for(w;w>2)),a-1);while(w>E&&e[w]E&&e[w]E&&e[w]==l)w--}else while(w>E&&e[w]E){y(++w);continue}w=a+r,e[w]==t&&w--,y(w-b)}return s},this.$getDisplayTokens=function(n,r){var i=[],s;r=r||0;for(var o=0;o39&&u<48||u>57&&u<64?i.push(l):u>=4352&&m(u)?i.push(e,t):i.push(e)}return i},this.$getStringScreenWidth=function(e,t,n){if(t==0)return[0,0];t==null&&(t=Infinity),n=n||0;var r,i;for(i=0;i=4352&&m(r)?n+=2:n+=1;if(n>t)break}return[n,i]},this.lineWidgets=null,this.getRowLength=function(e){if(this.lineWidgets)var t=this.lineWidgets[e]&&this.lineWidgets[e].rowCount||0;else t=0;return!this.$useWrapMode||!this.$wrapData[e]?1+t:this.$wrapData[e].length+1+t},this.getRowLineCount=function(e){return!this.$useWrapMode||!this.$wrapData[e]?1:this.$wrapData[e].length+1},this.getRowWrapIndent=function(e){if(this.$useWrapMode){var t=this.screenToDocumentPosition(e,Number.MAX_VALUE),n=this.$wrapData[t.row];return n.length&&n[0]=0)var o=a[f],r=this.$docRowCache[f],c=e>a[l-1];else var c=!l;var h=this.getLength()-1,p=this.getNextFoldLine(r),d=p?p.start.row:Infinity;while(o<=e){u=this.getRowLength(r);if(o+u>e||r>=h)break;o+=u,r++,r>d&&(r=p.end.row+1,p=this.getNextFoldLine(r,p),d=p?p.start.row:Infinity),c&&(this.$docRowCache.push(r),this.$screenRowCache.push(o))}if(p&&p.start.row<=r)n=this.getFoldDisplayLine(p),r=p.start.row;else{if(o+u<=e||r>h)return{row:h,column:this.getLine(h).length};n=this.getLine(r),p=null}var v=0;if(this.$useWrapMode){var m=this.$wrapData[r];if(m){var g=Math.floor(e-o);s=m[g],g>0&&m.length&&(v=m.indent,i=m[g-1]||m[m.length-1],n=n.substring(i))}}return i+=this.$getStringScreenWidth(n,t-v)[1],this.$useWrapMode&&i>=s&&(i=s-1),p?p.idxToPosition(i):{row:r,column:i}},this.documentToScreenPosition=function(e,t){if(typeof t=="undefined")var n=this.$clipPositionToDocument(e.row,e.column);else n=this.$clipPositionToDocument(e,t);e=n.row,t=n.column;var r=0,i=null,s=null;s=this.getFoldAt(e,t,1),s&&(e=s.start.row,t=s.start.column);var o,u=0,a=this.$docRowCache,f=this.$getRowCacheIndex(a,e),l=a.length;if(l&&f>=0)var u=a[f],r=this.$screenRowCache[f],c=e>a[l-1];else var c=!l;var h=this.getNextFoldLine(u),p=h?h.start.row:Infinity;while(u=p){o=h.end.row+1;if(o>e)break;h=this.getNextFoldLine(o,h),p=h?h.start.row:Infinity}else o=u+1;r+=this.getRowLength(u),u=o,c&&(this.$docRowCache.push(u),this.$screenRowCache.push(r))}var d="";h&&u>=p?(d=this.getFoldDisplayLine(h,e,t),i=h.start.row):(d=this.getLine(e).substring(0,t),i=e);var v=0;if(this.$useWrapMode){var m=this.$wrapData[i];if(m){var g=0;while(d.length>=m[g])r++,g++;d=d.substring(m[g-1]||0,d.length),v=g>0?m.indent:0}}return{row:r,column:v+this.$getStringScreenWidth(d)[0]}},this.documentToScreenColumn=function(e,t){return this.documentToScreenPosition(e,t).column},this.documentToScreenRow=function(e,t){return this.documentToScreenPosition(e,t).row},this.getScreenLength=function(){var e=0,t=null;if(!this.$useWrapMode){e=this.getLength();var n=this.$foldData;for(var r=0;ro&&(s=t.end.row+1,t=this.$foldData[r++],o=t?t.start.row:Infinity)}}return this.lineWidgets&&(e+=this.$getWidgetScreenLength()),e},this.$setFontMetrics=function(e){if(!this.$enableVarChar)return;this.$getStringScreenWidth=function(t,n,r){if(n===0)return[0,0];n||(n=Infinity),r=r||0;var i,s;for(s=0;sn)break}return[r,s]}},this.destroy=function(){this.bgTokenizer&&(this.bgTokenizer.setDocument(null),this.bgTokenizer=null),this.$stopWorker()}}).call(p.prototype),e("./edit_session/folding").Folding.call(p.prototype),e("./edit_session/bracket_match").BracketMatch.call(p.prototype),s.defineOptions(p.prototype,"session",{wrap:{set:function(e){!e||e=="off"?e=!1:e=="free"?e=!0:e=="printMargin"?e=-1:typeof e=="string"&&(e=parseInt(e,10)||!1);if(this.$wrap==e)return;this.$wrap=e;if(!e)this.setUseWrapMode(!1);else{var t=typeof e=="number"?e:null;this.setWrapLimitRange(t,t),this.setUseWrapMode(!0)}},get:function(){return this.getUseWrapMode()?this.$wrap==-1?"printMargin":this.getWrapLimitRange().min?this.$wrap:"free":"off"},handlesSet:!0},wrapMethod:{set:function(e){e=e=="auto"?this.$mode.type!="text":e!="text",e!=this.$wrapAsCode&&(this.$wrapAsCode=e,this.$useWrapMode&&(this.$modified=!0,this.$resetRowCache(0),this.$updateWrapData(0,this.getLength()-1)))},initialValue:"auto"},indentedSoftWrap:{initialValue:!0},firstLineNumber:{set:function(){this._signal("changeBreakpoint")},initialValue:1},useWorker:{set:function(e){this.$useWorker=e,this.$stopWorker(),e&&this.$startWorker()},initialValue:!0},useSoftTabs:{initialValue:!0},tabSize:{set:function(e){if(isNaN(e)||this.$tabSize===e)return;this.$modified=!0,this.$rowLengthCache=[],this.$tabSize=e,this._signal("changeTabSize")},initialValue:4,handlesSet:!0},overwrite:{set:function(e){this._signal("changeOverwrite")},initialValue:!1},newLineMode:{set:function(e){this.doc.setNewLineMode(e)},get:function(){return this.doc.getNewLineMode()},handlesSet:!0},mode:{set:function(e){this.setMode(e)},get:function(){return this.$modeId}}}),t.EditSession=p}),define("ace/search",["require","exports","module","ace/lib/lang","ace/lib/oop","ace/range"],function(e,t,n){"use strict";function u(e,t){function n(e){return/\w/.test(e)||t.regExp?"\\b":""}return n(e[0])+e+n(e[e.length-1])}var r=e("./lib/lang"),i=e("./lib/oop"),s=e("./range").Range,o=function(){this.$options={}};(function(){this.set=function(e){return i.mixin(this.$options,e),this},this.getOptions=function(){return r.copyObject(this.$options)},this.setOptions=function(e){this.$options=e},this.find=function(e){var t=this.$options,n=this.$matchIterator(e,t);if(!n)return!1;var r=null;return n.forEach(function(e,n,i){if(!e.start){var o=e.offset+(i||0);r=new s(n,o,n,o+e.length);if(!e.length&&t.start&&t.start.start&&t.skipCurrent!=0&&r.isEqual(t.start))return r=null,!1}else r=e;return!0}),r},this.findAll=function(e){var t=this.$options;if(!t.needle)return[];this.$assembleRegExp(t);var n=t.range,i=n?e.getLines(n.start.row,n.end.row):e.doc.getAllLines(),o=[],u=t.re;if(t.$isMultiLine){var a=u.length,f=i.length-a,l;e:for(var c=u.offset||0;c<=f;c++){for(var h=0;hv)continue;o.push(l=new s(c,v,c+a-1,m)),a>2&&(c=c+a-2)}}else for(var g=0;gE&&o[h].end.row==n.end.row)h--;o=o.slice(g,h+1);for(g=0,h=o.length;g=0;u--)if(i(o[u],t,s))return!0};else var u=function(e,t,s){var o=r.getMatchOffsets(e,n);for(var u=0;u=o;r--)if(n(e.getLine(r),r))return;if(t.wrap==0)return;for(r=u,o=s.row;r>=o;r--)if(n(e.getLine(r),r))return}:function(n){var r=s.row,i=e.getLine(r).substr(s.column);if(n(i,r,s.column))return;for(r+=1;r<=u;r++)if(n(e.getLine(r),r))return;if(t.wrap==0)return;for(r=o,u=s.row;r<=u;r++)if(n(e.getLine(r),r))return};return{forEach:a}}}).call(o.prototype),t.Search=o}),define("ace/keyboard/hash_handler",["require","exports","module","ace/lib/keys","ace/lib/useragent"],function(e,t,n){"use strict";function o(e,t){this.platform=t||(i.isMac?"mac":"win"),this.commands={},this.commandKeyBinding={},this.addCommands(e),this.$singleCommand=!0}function u(e,t){o.call(this,e,t),this.$singleCommand=!1}var r=e("../lib/keys"),i=e("../lib/useragent"),s=r.KEY_MODS;u.prototype=o.prototype,function(){function e(e){return typeof e=="object"&&e.bindKey&&e.bindKey.position||0}this.addCommand=function(e){this.commands[e.name]&&this.removeCommand(e),this.commands[e.name]=e,e.bindKey&&this._buildKeyHash(e)},this.removeCommand=function(e,t){var n=e&&(typeof e=="string"?e:e.name);e=this.commands[n],t||delete this.commands[n];var r=this.commandKeyBinding;for(var i in r){var s=r[i];if(s==e)delete r[i];else if(Array.isArray(s)){var o=s.indexOf(e);o!=-1&&(s.splice(o,1),s.length==1&&(r[i]=s[0]))}}},this.bindKey=function(e,t,n){typeof e=="object"&&e&&(n==undefined&&(n=e.position),e=e[this.platform]);if(!e)return;if(typeof t=="function")return this.addCommand({exec:t,bindKey:e,name:t.name||e});e.split("|").forEach(function(e){var r="";if(e.indexOf(" ")!=-1){var i=e.split(/\s+/);e=i.pop(),i.forEach(function(e){var t=this.parseKeys(e),n=s[t.hashId]+t.key;r+=(r?" ":"")+n,this._addCommandToBinding(r,"chainKeys")},this),r+=" "}var o=this.parseKeys(e),u=s[o.hashId]+o.key;this._addCommandToBinding(r+u,t,n)},this)},this._addCommandToBinding=function(t,n,r){var i=this.commandKeyBinding,s;if(!n)delete i[t];else if(!i[t]||this.$singleCommand)i[t]=n;else{Array.isArray(i[t])?(s=i[t].indexOf(n))!=-1&&i[t].splice(s,1):i[t]=[i[t]],typeof r!="number"&&(r||n.isDefault?r=-100:r=e(n));var o=i[t];for(s=0;sr)break}o.splice(s,0,n)}},this.addCommands=function(e){e&&Object.keys(e).forEach(function(t){var n=e[t];if(!n)return;if(typeof n=="string")return this.bindKey(n,t);typeof n=="function"&&(n={exec:n});if(typeof n!="object")return;n.name||(n.name=t),this.addCommand(n)},this)},this.removeCommands=function(e){Object.keys(e).forEach(function(t){this.removeCommand(e[t])},this)},this.bindKeys=function(e){Object.keys(e).forEach(function(t){this.bindKey(t,e[t])},this)},this._buildKeyHash=function(e){this.bindKey(e.bindKey,e)},this.parseKeys=function(e){var t=e.toLowerCase().split(/[\-\+]([\-\+])?/).filter(function(e){return e}),n=t.pop(),i=r[n];if(r.FUNCTION_KEYS[i])n=r.FUNCTION_KEYS[i].toLowerCase();else{if(!t.length)return{key:n,hashId:-1};if(t.length==1&&t[0]=="shift")return{key:n.toUpperCase(),hashId:-1}}var s=0;for(var o=t.length;o--;){var u=r.KEY_MODS[t[o]];if(u==null)return typeof console!="undefined"&&console.error("invalid modifier "+t[o]+" in "+e),!1;s|=u}return{key:n,hashId:s}},this.findKeyCommand=function(t,n){var r=s[t]+n;return this.commandKeyBinding[r]},this.handleKeyboard=function(e,t,n,r){if(r<0)return;var i=s[t]+n,o=this.commandKeyBinding[i];e.$keyChain&&(e.$keyChain+=" "+i,o=this.commandKeyBinding[e.$keyChain]||o);if(o)if(o=="chainKeys"||o[o.length-1]=="chainKeys")return e.$keyChain=e.$keyChain||i,{command:"null"};if(e.$keyChain)if(!!t&&t!=4||n.length!=1){if(t==-1||r>0)e.$keyChain=""}else e.$keyChain=e.$keyChain.slice(0,-i.length-1);return{command:o}},this.getStatusText=function(e,t){return t.$keyChain||""}}.call(o.prototype),t.HashHandler=o,t.MultiHashHandler=u}),define("ace/commands/command_manager",["require","exports","module","ace/lib/oop","ace/keyboard/hash_handler","ace/lib/event_emitter"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../keyboard/hash_handler").MultiHashHandler,s=e("../lib/event_emitter").EventEmitter,o=function(e,t){i.call(this,t,e),this.byName=this.commands,this.setDefaultHandler("exec",function(e){return e.command.exec(e.editor,e.args||{})})};r.inherits(o,i),function(){r.implement(this,s),this.exec=function(e,t,n){if(Array.isArray(e)){for(var r=e.length;r--;)if(this.exec(e[r],t,n))return!0;return!1}typeof e=="string"&&(e=this.commands[e]);if(!e)return!1;if(t&&t.$readOnly&&!e.readOnly)return!1;var i={editor:t,command:e,args:n};return i.returnValue=this._emit("exec",i),this._signal("afterExec",i),i.returnValue===!1?!1:!0},this.toggleRecording=function(e){if(this.$inReplay)return;return e&&e._emit("changeStatus"),this.recording?(this.macro.pop(),this.removeEventListener("exec",this.$addCommandToMacro),this.macro.length||(this.macro=this.oldMacro),this.recording=!1):(this.$addCommandToMacro||(this.$addCommandToMacro=function(e){this.macro.push([e.command,e.args])}.bind(this)),this.oldMacro=this.macro,this.macro=[],this.on("exec",this.$addCommandToMacro),this.recording=!0)},this.replay=function(e){if(this.$inReplay||!this.macro)return;if(this.recording)return this.toggleRecording(e);try{this.$inReplay=!0,this.macro.forEach(function(t){typeof t=="string"?this.exec(t,e):this.exec(t[0],e,t[1])},this)}finally{this.$inReplay=!1}},this.trimMacro=function(e){return e.map(function(e){return typeof e[0]!="string"&&(e[0]=e[0].name),e[1]||(e=e[0]),e})}}.call(o.prototype),t.CommandManager=o}),define("ace/commands/default_commands",["require","exports","module","ace/lib/lang","ace/config","ace/range"],function(e,t,n){"use strict";function o(e,t){return{win:e,mac:t}}var r=e("../lib/lang"),i=e("../config"),s=e("../range").Range;t.commands=[{name:"showSettingsMenu",bindKey:o("Ctrl-,","Command-,"),exec:function(e){i.loadModule("ace/ext/settings_menu",function(t){t.init(e),e.showSettingsMenu()})},readOnly:!0},{name:"goToNextError",bindKey:o("Alt-E","F4"),exec:function(e){i.loadModule("ace/ext/error_marker",function(t){t.showErrorMarker(e,1)})},scrollIntoView:"animate",readOnly:!0},{name:"goToPreviousError",bindKey:o("Alt-Shift-E","Shift-F4"),exec:function(e){i.loadModule("ace/ext/error_marker",function(t){t.showErrorMarker(e,-1)})},scrollIntoView:"animate",readOnly:!0},{name:"selectall",bindKey:o("Ctrl-A","Command-A"),exec:function(e){e.selectAll()},readOnly:!0},{name:"centerselection",bindKey:o(null,"Ctrl-L"),exec:function(e){e.centerSelection()},readOnly:!0},{name:"gotoline",bindKey:o("Ctrl-L","Command-L"),exec:function(e){var t=parseInt(prompt("Enter line number:"),10);isNaN(t)||e.gotoLine(t)},readOnly:!0},{name:"fold",bindKey:o("Alt-L|Ctrl-F1","Command-Alt-L|Command-F1"),exec:function(e){e.session.toggleFold(!1)},multiSelectAction:"forEach",scrollIntoView:"center",readOnly:!0},{name:"unfold",bindKey:o("Alt-Shift-L|Ctrl-Shift-F1","Command-Alt-Shift-L|Command-Shift-F1"),exec:function(e){e.session.toggleFold(!0)},multiSelectAction:"forEach",scrollIntoView:"center",readOnly:!0},{name:"toggleFoldWidget",bindKey:o("F2","F2"),exec:function(e){e.session.toggleFoldWidget()},multiSelectAction:"forEach",scrollIntoView:"center",readOnly:!0},{name:"toggleParentFoldWidget",bindKey:o("Alt-F2","Alt-F2"),exec:function(e){e.session.toggleFoldWidget(!0)},multiSelectAction:"forEach",scrollIntoView:"center",readOnly:!0},{name:"foldall",bindKey:o(null,"Ctrl-Command-Option-0"),exec:function(e){e.session.foldAll()},scrollIntoView:"center",readOnly:!0},{name:"foldOther",bindKey:o("Alt-0","Command-Option-0"),exec:function(e){e.session.foldAll(),e.session.unfold(e.selection.getAllRanges())},scrollIntoView:"center",readOnly:!0},{name:"unfoldall",bindKey:o("Alt-Shift-0","Command-Option-Shift-0"),exec:function(e){e.session.unfold()},scrollIntoView:"center",readOnly:!0},{name:"findnext",bindKey:o("Ctrl-K","Command-G"),exec:function(e){e.findNext()},multiSelectAction:"forEach",scrollIntoView:"center",readOnly:!0},{name:"findprevious",bindKey:o("Ctrl-Shift-K","Command-Shift-G"),exec:function(e){e.findPrevious()},multiSelectAction:"forEach",scrollIntoView:"center",readOnly:!0},{name:"selectOrFindNext",bindKey:o("Alt-K","Ctrl-G"),exec:function(e){e.selection.isEmpty()?e.selection.selectWord():e.findNext()},readOnly:!0},{name:"selectOrFindPrevious",bindKey:o("Alt-Shift-K","Ctrl-Shift-G"),exec:function(e){e.selection.isEmpty()?e.selection.selectWord():e.findPrevious()},readOnly:!0},{name:"find",bindKey:o("Ctrl-F","Command-F"),exec:function(e){i.loadModule("ace/ext/searchbox",function(t){t.Search(e)})},readOnly:!0},{name:"overwrite",bindKey:"Insert",exec:function(e){e.toggleOverwrite()},readOnly:!0},{name:"selecttostart",bindKey:o("Ctrl-Shift-Home","Command-Shift-Home|Command-Shift-Up"),exec:function(e){e.getSelection().selectFileStart()},multiSelectAction:"forEach",readOnly:!0,scrollIntoView:"animate",aceCommandGroup:"fileJump"},{name:"gotostart",bindKey:o("Ctrl-Home","Command-Home|Command-Up"),exec:function(e){e.navigateFileStart()},multiSelectAction:"forEach",readOnly:!0,scrollIntoView:"animate",aceCommandGroup:"fileJump"},{name:"selectup",bindKey:o("Shift-Up","Shift-Up|Ctrl-Shift-P"),exec:function(e){e.getSelection().selectUp()},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"golineup",bindKey:o("Up","Up|Ctrl-P"),exec:function(e,t){e.navigateUp(t.times)},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"selecttoend",bindKey:o("Ctrl-Shift-End","Command-Shift-End|Command-Shift-Down"),exec:function(e){e.getSelection().selectFileEnd()},multiSelectAction:"forEach",readOnly:!0,scrollIntoView:"animate",aceCommandGroup:"fileJump"},{name:"gotoend",bindKey:o("Ctrl-End","Command-End|Command-Down"),exec:function(e){e.navigateFileEnd()},multiSelectAction:"forEach",readOnly:!0,scrollIntoView:"animate",aceCommandGroup:"fileJump"},{name:"selectdown",bindKey:o("Shift-Down","Shift-Down|Ctrl-Shift-N"),exec:function(e){e.getSelection().selectDown()},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"golinedown",bindKey:o("Down","Down|Ctrl-N"),exec:function(e,t){e.navigateDown(t.times)},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"selectwordleft",bindKey:o("Ctrl-Shift-Left","Option-Shift-Left"),exec:function(e){e.getSelection().selectWordLeft()},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"gotowordleft",bindKey:o("Ctrl-Left","Option-Left"),exec:function(e){e.navigateWordLeft()},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"selecttolinestart",bindKey:o("Alt-Shift-Left","Command-Shift-Left|Ctrl-Shift-A"),exec:function(e){e.getSelection().selectLineStart()},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"gotolinestart",bindKey:o("Alt-Left|Home","Command-Left|Home|Ctrl-A"),exec:function(e){e.navigateLineStart()},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"selectleft",bindKey:o("Shift-Left","Shift-Left|Ctrl-Shift-B"),exec:function(e){e.getSelection().selectLeft()},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"gotoleft",bindKey:o("Left","Left|Ctrl-B"),exec:function(e,t){e.navigateLeft(t.times)},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"selectwordright",bindKey:o("Ctrl-Shift-Right","Option-Shift-Right"),exec:function(e){e.getSelection().selectWordRight()},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"gotowordright",bindKey:o("Ctrl-Right","Option-Right"),exec:function(e){e.navigateWordRight()},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"selecttolineend",bindKey:o("Alt-Shift-Right","Command-Shift-Right|Shift-End|Ctrl-Shift-E"),exec:function(e){e.getSelection().selectLineEnd()},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"gotolineend",bindKey:o("Alt-Right|End","Command-Right|End|Ctrl-E"),exec:function(e){e.navigateLineEnd()},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"selectright",bindKey:o("Shift-Right","Shift-Right"),exec:function(e){e.getSelection().selectRight()},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"gotoright",bindKey:o("Right","Right|Ctrl-F"),exec:function(e,t){e.navigateRight(t.times)},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"selectpagedown",bindKey:"Shift-PageDown",exec:function(e){e.selectPageDown()},readOnly:!0},{name:"pagedown",bindKey:o(null,"Option-PageDown"),exec:function(e){e.scrollPageDown()},readOnly:!0},{name:"gotopagedown",bindKey:o("PageDown","PageDown|Ctrl-V"),exec:function(e){e.gotoPageDown()},readOnly:!0},{name:"selectpageup",bindKey:"Shift-PageUp",exec:function(e){e.selectPageUp()},readOnly:!0},{name:"pageup",bindKey:o(null,"Option-PageUp"),exec:function(e){e.scrollPageUp()},readOnly:!0},{name:"gotopageup",bindKey:"PageUp",exec:function(e){e.gotoPageUp()},readOnly:!0},{name:"scrollup",bindKey:o("Ctrl-Up",null),exec:function(e){e.renderer.scrollBy(0,-2*e.renderer.layerConfig.lineHeight)},readOnly:!0},{name:"scrolldown",bindKey:o("Ctrl-Down",null),exec:function(e){e.renderer.scrollBy(0,2*e.renderer.layerConfig.lineHeight)},readOnly:!0},{name:"selectlinestart",bindKey:"Shift-Home",exec:function(e){e.getSelection().selectLineStart()},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"selectlineend",bindKey:"Shift-End",exec:function(e){e.getSelection().selectLineEnd()},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"togglerecording",bindKey:o("Ctrl-Alt-E","Command-Option-E"),exec:function(e){e.commands.toggleRecording(e)},readOnly:!0},{name:"replaymacro",bindKey:o("Ctrl-Shift-E","Command-Shift-E"),exec:function(e){e.commands.replay(e)},readOnly:!0},{name:"jumptomatching",bindKey:o("Ctrl-P","Ctrl-P"),exec:function(e){e.jumpToMatching()},multiSelectAction:"forEach",scrollIntoView:"animate",readOnly:!0},{name:"selecttomatching",bindKey:o("Ctrl-Shift-P","Ctrl-Shift-P"),exec:function(e){e.jumpToMatching(!0)},multiSelectAction:"forEach",scrollIntoView:"animate",readOnly:!0},{name:"expandToMatching",bindKey:o("Ctrl-Shift-M","Ctrl-Shift-M"),exec:function(e){e.jumpToMatching(!0,!0)},multiSelectAction:"forEach",scrollIntoView:"animate",readOnly:!0},{name:"passKeysToBrowser",bindKey:o(null,null),exec:function(){},passEvent:!0,readOnly:!0},{name:"copy",exec:function(e){},readOnly:!0},{name:"cut",exec:function(e){var t=e.getSelectionRange();e._emit("cut",t),e.selection.isEmpty()||(e.session.remove(t),e.clearSelection())},scrollIntoView:"cursor",multiSelectAction:"forEach"},{name:"paste",exec:function(e,t){e.$handlePaste(t)},scrollIntoView:"cursor"},{name:"removeline",bindKey:o("Ctrl-D","Command-D"),exec:function(e){e.removeLines()},scrollIntoView:"cursor",multiSelectAction:"forEachLine"},{name:"duplicateSelection",bindKey:o("Ctrl-Shift-D","Command-Shift-D"),exec:function(e){e.duplicateSelection()},scrollIntoView:"cursor",multiSelectAction:"forEach"},{name:"sortlines",bindKey:o("Ctrl-Alt-S","Command-Alt-S"),exec:function(e){e.sortLines()},scrollIntoView:"selection",multiSelectAction:"forEachLine"},{name:"togglecomment",bindKey:o("Ctrl-/","Command-/"),exec:function(e){e.toggleCommentLines()},multiSelectAction:"forEachLine",scrollIntoView:"selectionPart"},{name:"toggleBlockComment",bindKey:o("Ctrl-Shift-/","Command-Shift-/"),exec:function(e){e.toggleBlockComment()},multiSelectAction:"forEach",scrollIntoView:"selectionPart"},{name:"modifyNumberUp",bindKey:o("Ctrl-Shift-Up","Alt-Shift-Up"),exec:function(e){e.modifyNumber(1)},scrollIntoView:"cursor",multiSelectAction:"forEach"},{name:"modifyNumberDown",bindKey:o("Ctrl-Shift-Down","Alt-Shift-Down"),exec:function(e){e.modifyNumber(-1)},scrollIntoView:"cursor",multiSelectAction:"forEach"},{name:"replace",bindKey:o("Ctrl-H","Command-Option-F"),exec:function(e){i.loadModule("ace/ext/searchbox",function(t){t.Search(e,!0)})}},{name:"undo",bindKey:o("Ctrl-Z","Command-Z"),exec:function(e){e.undo()}},{name:"redo",bindKey:o("Ctrl-Shift-Z|Ctrl-Y","Command-Shift-Z|Command-Y"),exec:function(e){e.redo()}},{name:"copylinesup",bindKey:o("Alt-Shift-Up","Command-Option-Up"),exec:function(e){e.copyLinesUp()},scrollIntoView:"cursor"},{name:"movelinesup",bindKey:o("Alt-Up","Option-Up"),exec:function(e){e.moveLinesUp()},scrollIntoView:"cursor"},{name:"copylinesdown",bindKey:o("Alt-Shift-Down","Command-Option-Down"),exec:function(e){e.copyLinesDown()},scrollIntoView:"cursor"},{name:"movelinesdown",bindKey:o("Alt-Down","Option-Down"),exec:function(e){e.moveLinesDown()},scrollIntoView:"cursor"},{name:"del",bindKey:o("Delete","Delete|Ctrl-D|Shift-Delete"),exec:function(e){e.remove("right")},multiSelectAction:"forEach",scrollIntoView:"cursor"},{name:"backspace",bindKey:o("Shift-Backspace|Backspace","Ctrl-Backspace|Shift-Backspace|Backspace|Ctrl-H"),exec:function(e){e.remove("left")},multiSelectAction:"forEach",scrollIntoView:"cursor"},{name:"cut_or_delete",bindKey:o("Shift-Delete",null),exec:function(e){if(!e.selection.isEmpty())return!1;e.remove("left")},multiSelectAction:"forEach",scrollIntoView:"cursor"},{name:"removetolinestart",bindKey:o("Alt-Backspace","Command-Backspace"),exec:function(e){e.removeToLineStart()},multiSelectAction:"forEach",scrollIntoView:"cursor"},{name:"removetolineend",bindKey:o("Alt-Delete","Ctrl-K"),exec:function(e){e.removeToLineEnd()},multiSelectAction:"forEach",scrollIntoView:"cursor"},{name:"removewordleft",bindKey:o("Ctrl-Backspace","Alt-Backspace|Ctrl-Alt-Backspace"),exec:function(e){e.removeWordLeft()},multiSelectAction:"forEach",scrollIntoView:"cursor"},{name:"removewordright",bindKey:o("Ctrl-Delete","Alt-Delete"),exec:function(e){e.removeWordRight()},multiSelectAction:"forEach",scrollIntoView:"cursor"},{name:"outdent",bindKey:o("Shift-Tab","Shift-Tab"),exec:function(e){e.blockOutdent()},multiSelectAction:"forEach",scrollIntoView:"selectionPart"},{name:"indent",bindKey:o("Tab","Tab"),exec:function(e){e.indent()},multiSelectAction:"forEach",scrollIntoView:"selectionPart"},{name:"blockoutdent",bindKey:o("Ctrl-[","Ctrl-["),exec:function(e){e.blockOutdent()},multiSelectAction:"forEachLine",scrollIntoView:"selectionPart"},{name:"blockindent",bindKey:o("Ctrl-]","Ctrl-]"),exec:function(e){e.blockIndent()},multiSelectAction:"forEachLine",scrollIntoView:"selectionPart"},{name:"insertstring",exec:function(e,t){e.insert(t)},multiSelectAction:"forEach",scrollIntoView:"cursor"},{name:"inserttext",exec:function(e,t){e.insert(r.stringRepeat(t.text||"",t.times||1))},multiSelectAction:"forEach",scrollIntoView:"cursor"},{name:"splitline",bindKey:o(null,"Ctrl-O"),exec:function(e){e.splitLine()},multiSelectAction:"forEach",scrollIntoView:"cursor"},{name:"transposeletters",bindKey:o("Ctrl-T","Ctrl-T"),exec:function(e){e.transposeLetters()},multiSelectAction:function(e){e.transposeSelections(1)},scrollIntoView:"cursor"},{name:"touppercase",bindKey:o("Ctrl-U","Ctrl-U"),exec:function(e){e.toUpperCase()},multiSelectAction:"forEach",scrollIntoView:"cursor"},{name:"tolowercase",bindKey:o("Ctrl-Shift-U","Ctrl-Shift-U"),exec:function(e){e.toLowerCase()},multiSelectAction:"forEach",scrollIntoView:"cursor"},{name:"expandtoline",bindKey:o("Ctrl-Shift-L","Command-Shift-L"),exec:function(e){var t=e.selection.getRange();t.start.column=t.end.column=0,t.end.row++,e.selection.setRange(t,!1)},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"joinlines",bindKey:o(null,null),exec:function(e){var t=e.selection.isBackwards(),n=t?e.selection.getSelectionLead():e.selection.getSelectionAnchor(),i=t?e.selection.getSelectionAnchor():e.selection.getSelectionLead(),o=e.session.doc.getLine(n.row).length,u=e.session.doc.getTextRange(e.selection.getRange()),a=u.replace(/\n\s*/," ").length,f=e.session.doc.getLine(n.row);for(var l=n.row+1;l<=i.row+1;l++){var c=r.stringTrimLeft(r.stringTrimRight(e.session.doc.getLine(l)));c.length!==0&&(c=" "+c),f+=c}i.row+10?(e.selection.moveCursorTo(n.row,n.column),e.selection.selectTo(n.row,n.column+a)):(o=e.session.doc.getLine(n.row).length>o?o+1:o,e.selection.moveCursorTo(n.row,o))},multiSelectAction:"forEach",readOnly:!0},{name:"invertSelection",bindKey:o(null,null),exec:function(e){var t=e.session.doc.getLength()-1,n=e.session.doc.getLine(t).length,r=e.selection.rangeList.ranges,i=[];r.length<1&&(r=[e.selection.getRange()]);for(var o=0;o0&&this.$blockScrolling--;var n=t&&t.scrollIntoView;if(n){switch(n){case"center-animate":n="animate";case"center":this.renderer.scrollCursorIntoView(null,.5);break;case"animate":case"cursor":this.renderer.scrollCursorIntoView();break;case"selectionPart":var r=this.selection.getRange(),i=this.renderer.layerConfig;(r.start.row>=i.lastRow||r.end.row<=i.firstRow)&&this.renderer.scrollSelectionIntoView(this.selection.anchor,this.selection.lead);break;default:}n=="animate"&&this.renderer.animateScrolling(this.curOp.scrollTop)}this.prevOp=this.curOp,this.curOp=null}},this.$mergeableCommands=["backspace","del","insertstring"],this.$historyTracker=function(e){if(!this.$mergeUndoDeltas)return;var t=this.prevOp,n=this.$mergeableCommands,r=t.command&&e.command.name==t.command.name;if(e.command.name=="insertstring"){var i=e.args;this.mergeNextCommand===undefined&&(this.mergeNextCommand=!0),r=r&&this.mergeNextCommand&&(!/\s/.test(i)||/\s/.test(t.args)),this.mergeNextCommand=!0}else r=r&&n.indexOf(e.command.name)!==-1;this.$mergeUndoDeltas!="always"&&Date.now()-this.sequenceStartTime>2e3&&(r=!1),r?this.session.mergeUndoDeltas=!0:n.indexOf(e.command.name)!==-1&&(this.sequenceStartTime=Date.now())},this.setKeyboardHandler=function(e,t){if(e&&typeof e=="string"){this.$keybindingId=e;var n=this;g.loadModule(["keybinding",e],function(r){n.$keybindingId==e&&n.keyBinding.setKeyboardHandler(r&&r.handler),t&&t()})}else this.$keybindingId=null,this.keyBinding.setKeyboardHandler(e),t&&t()},this.getKeyboardHandler=function(){return this.keyBinding.getKeyboardHandler()},this.setSession=function(e){if(this.session==e)return;this.curOp&&this.endOperation(),this.curOp={};var t=this.session;if(t){this.session.off("change",this.$onDocumentChange),this.session.off("changeMode",this.$onChangeMode),this.session.off("tokenizerUpdate",this.$onTokenizerUpdate),this.session.off("changeTabSize",this.$onChangeTabSize),this.session.off("changeWrapLimit",this.$onChangeWrapLimit),this.session.off("changeWrapMode",this.$onChangeWrapMode),this.session.off("changeFold",this.$onChangeFold),this.session.off("changeFrontMarker",this.$onChangeFrontMarker),this.session.off("changeBackMarker",this.$onChangeBackMarker),this.session.off("changeBreakpoint",this.$onChangeBreakpoint),this.session.off("changeAnnotation",this.$onChangeAnnotation),this.session.off("changeOverwrite",this.$onCursorChange),this.session.off("changeScrollTop",this.$onScrollTopChange),this.session.off("changeScrollLeft",this.$onScrollLeftChange);var n=this.session.getSelection();n.off("changeCursor",this.$onCursorChange),n.off("changeSelection",this.$onSelectionChange)}this.session=e,e?(this.$onDocumentChange=this.onDocumentChange.bind(this),e.on("change",this.$onDocumentChange),this.renderer.setSession(e),this.$onChangeMode=this.onChangeMode.bind(this),e.on("changeMode",this.$onChangeMode),this.$onTokenizerUpdate=this.onTokenizerUpdate.bind(this),e.on("tokenizerUpdate",this.$onTokenizerUpdate),this.$onChangeTabSize=this.renderer.onChangeTabSize.bind(this.renderer),e.on("changeTabSize",this.$onChangeTabSize),this.$onChangeWrapLimit=this.onChangeWrapLimit.bind(this),e.on("changeWrapLimit",this.$onChangeWrapLimit),this.$onChangeWrapMode=this.onChangeWrapMode.bind(this),e.on("changeWrapMode",this.$onChangeWrapMode),this.$onChangeFold=this.onChangeFold.bind(this),e.on("changeFold",this.$onChangeFold),this.$onChangeFrontMarker=this.onChangeFrontMarker.bind(this),this.session.on("changeFrontMarker",this.$onChangeFrontMarker),this.$onChangeBackMarker=this.onChangeBackMarker.bind(this),this.session.on("changeBackMarker",this.$onChangeBackMarker),this.$onChangeBreakpoint=this.onChangeBreakpoint.bind(this),this.session.on("changeBreakpoint",this.$onChangeBreakpoint),this.$onChangeAnnotation=this.onChangeAnnotation.bind(this),this.session.on("changeAnnotation",this.$onChangeAnnotation),this.$onCursorChange=this.onCursorChange.bind(this),this.session.on("changeOverwrite",this.$onCursorChange),this.$onScrollTopChange=this.onScrollTopChange.bind(this),this.session.on("changeScrollTop",this.$onScrollTopChange),this.$onScrollLeftChange=this.onScrollLeftChange.bind(this),this.session.on("changeScrollLeft",this.$onScrollLeftChange),this.selection=e.getSelection(),this.selection.on("changeCursor",this.$onCursorChange),this.$onSelectionChange=this.onSelectionChange.bind(this),this.selection.on("changeSelection",this.$onSelectionChange),this.onChangeMode(),this.$blockScrolling+=1,this.onCursorChange(),this.$blockScrolling-=1,this.onScrollTopChange(),this.onScrollLeftChange(),this.onSelectionChange(),this.onChangeFrontMarker(),this.onChangeBackMarker(),this.onChangeBreakpoint(),this.onChangeAnnotation(),this.session.getUseWrapMode()&&this.renderer.adjustWrapLimit(),this.renderer.updateFull()):(this.selection=null,this.renderer.setSession(e)),this._signal("changeSession",{session:e,oldSession:t}),this.curOp=null,t&&t._signal("changeEditor",{oldEditor:this}),e&&e._signal("changeEditor",{editor:this})},this.getSession=function(){return this.session},this.setValue=function(e,t){return this.session.doc.setValue(e),t?t==1?this.navigateFileEnd():t==-1&&this.navigateFileStart():this.selectAll(),e},this.getValue=function(){return this.session.getValue()},this.getSelection=function(){return this.selection},this.resize=function(e){this.renderer.onResize(e)},this.setTheme=function(e,t){this.renderer.setTheme(e,t)},this.getTheme=function(){return this.renderer.getTheme()},this.setStyle=function(e){this.renderer.setStyle(e)},this.unsetStyle=function(e){this.renderer.unsetStyle(e)},this.getFontSize=function(){return this.getOption("fontSize")||i.computedStyle(this.container,"fontSize")},this.setFontSize=function(e){this.setOption("fontSize",e)},this.$highlightBrackets=function(){this.session.$bracketHighlight&&(this.session.removeMarker(this.session.$bracketHighlight),this.session.$bracketHighlight=null);if(this.$highlightPending)return;var e=this;this.$highlightPending=!0,setTimeout(function(){e.$highlightPending=!1;var t=e.session;if(!t||!t.bgTokenizer)return;var n=t.findMatchingBracket(e.getCursorPosition());if(n)var r=new p(n.row,n.column,n.row,n.column+1);else if(t.$mode.getMatching)var r=t.$mode.getMatching(e.session);r&&(t.$bracketHighlight=t.addMarker(r,"ace_bracket","text"))},50)},this.$highlightTags=function(){if(this.$highlightTagPending)return;var e=this;this.$highlightTagPending=!0,setTimeout(function(){e.$highlightTagPending=!1;var t=e.session;if(!t||!t.bgTokenizer)return;var n=e.getCursorPosition(),r=new y(e.session,n.row,n.column),i=r.getCurrentToken();if(!i||!/\b(?:tag-open|tag-name)/.test(i.type)){t.removeMarker(t.$tagHighlight),t.$tagHighlight=null;return}if(i.type.indexOf("tag-open")!=-1){i=r.stepForward();if(!i)return}var s=i.value,o=0,u=r.stepBackward();if(u.value=="<"){do u=i,i=r.stepForward(),i&&i.value===s&&i.type.indexOf("tag-name")!==-1&&(u.value==="<"?o++:u.value==="=0)}else{do i=u,u=r.stepBackward(),i&&i.value===s&&i.type.indexOf("tag-name")!==-1&&(u.value==="<"?o++:u.value==="1)&&(t=!1)}if(e.$highlightLineMarker&&!t)e.removeMarker(e.$highlightLineMarker.id),e.$highlightLineMarker=null;else if(!e.$highlightLineMarker&&t){var n=new p(t.row,t.column,t.row,Infinity);n.id=e.addMarker(n,"ace_active-line","screenLine"),e.$highlightLineMarker=n}else t&&(e.$highlightLineMarker.start.row=t.row,e.$highlightLineMarker.end.row=t.row,e.$highlightLineMarker.start.column=t.column,e._signal("changeBackMarker"))},this.onSelectionChange=function(e){var t=this.session;t.$selectionMarker&&t.removeMarker(t.$selectionMarker),t.$selectionMarker=null;if(!this.selection.isEmpty()){var n=this.selection.getRange(),r=this.getSelectionStyle();t.$selectionMarker=t.addMarker(n,"ace_selection",r)}else this.$updateHighlightActiveLine();var i=this.$highlightSelectedWord&&this.$getSelectionHighLightRegexp();this.session.highlight(i),this._signal("changeSelection")},this.$getSelectionHighLightRegexp=function(){var e=this.session,t=this.getSelectionRange();if(t.isEmpty()||t.isMultiLine())return;var n=t.start.column-1,r=t.end.column+1,i=e.getLine(t.start.row),s=i.length,o=i.substring(Math.max(n,0),Math.min(r,s));if(n>=0&&/^[\w\d]/.test(o)||r<=s&&/[\w\d]$/.test(o))return;o=i.substring(t.start.column,t.end.column);if(!/^[\w\d]+$/.test(o))return;var u=this.$search.$assembleRegExp({wholeWord:!0,caseSensitive:!0,needle:o});return u},this.onChangeFrontMarker=function(){this.renderer.updateFrontMarkers()},this.onChangeBackMarker=function(){this.renderer.updateBackMarkers()},this.onChangeBreakpoint=function(){this.renderer.updateBreakpoints()},this.onChangeAnnotation=function(){this.renderer.setAnnotations(this.session.getAnnotations())},this.onChangeMode=function(e){this.renderer.updateText(),this._emit("changeMode",e)},this.onChangeWrapLimit=function(){this.renderer.updateFull()},this.onChangeWrapMode=function(){this.renderer.onResize(!0)},this.onChangeFold=function(){this.$updateHighlightActiveLine(),this.renderer.updateFull()},this.getSelectedText=function(){return this.session.getTextRange(this.getSelectionRange())},this.getCopyText=function(){var e=this.getSelectedText();return this._signal("copy",e),e},this.onCopy=function(){this.commands.exec("copy",this)},this.onCut=function(){this.commands.exec("cut",this)},this.onPaste=function(e,t){var n={text:e,event:t};this.commands.exec("paste",this,n)},this.$handlePaste=function(e){typeof e=="string"&&(e={text:e}),this._signal("paste",e);var t=e.text;if(!this.inMultiSelectMode||this.inVirtualSelectionMode)this.insert(t);else{var n=t.split(/\r\n|\r|\n/),r=this.selection.rangeList.ranges;if(n.length>r.length||n.length<2||!n[1])return this.commands.exec("insertstring",this,t);for(var i=r.length;i--;){var s=r[i];s.isEmpty()||this.session.remove(s),this.session.insert(s.start,n[i])}}},this.execCommand=function(e,t){return this.commands.exec(e,this,t)},this.insert=function(e,t){var n=this.session,r=n.getMode(),i=this.getCursorPosition();if(this.getBehavioursEnabled()&&!t){var s=r.transformAction(n.getState(i.row),"insertion",this,n,e);s&&(e!==s.text&&(this.session.mergeUndoDeltas=!1,this.$mergeNextCommand=!1),e=s.text)}e==" "&&(e=this.session.getTabString());if(!this.selection.isEmpty()){var o=this.getSelectionRange();i=this.session.remove(o),this.clearSelection()}else if(this.session.getOverwrite()){var o=new p.fromPoints(i,i);o.end.column+=e.length,this.session.remove(o)}if(e=="\n"||e=="\r\n"){var u=n.getLine(i.row);if(i.column>u.search(/\S|$/)){var a=u.substr(i.column).search(/\S|$/);n.doc.removeInLine(i.row,i.column,i.column+a)}}this.clearSelection();var f=i.column,l=n.getState(i.row),u=n.getLine(i.row),c=r.checkOutdent(l,u,e),h=n.insert(i,e);s&&s.selection&&(s.selection.length==2?this.selection.setSelectionRange(new p(i.row,f+s.selection[0],i.row,f+s.selection[1])):this.selection.setSelectionRange(new p(i.row+s.selection[0],s.selection[1],i.row+s.selection[2],s.selection[3])));if(n.getDocument().isNewLine(e)){var d=r.getNextLineIndent(l,u.slice(0,i.column),n.getTabString());n.insert({row:i.row+1,column:0},d)}c&&r.autoOutdent(l,n,i.row)},this.onTextInput=function(e){this.keyBinding.onTextInput(e)},this.onCommandKey=function(e,t,n){this.keyBinding.onCommandKey(e,t,n)},this.setOverwrite=function(e){this.session.setOverwrite(e)},this.getOverwrite=function(){return this.session.getOverwrite()},this.toggleOverwrite=function(){this.session.toggleOverwrite()},this.setScrollSpeed=function(e){this.setOption("scrollSpeed",e)},this.getScrollSpeed=function(){return this.getOption("scrollSpeed")},this.setDragDelay=function(e){this.setOption("dragDelay",e)},this.getDragDelay=function(){return this.getOption("dragDelay")},this.setSelectionStyle=function(e){this.setOption("selectionStyle",e)},this.getSelectionStyle=function(){return this.getOption("selectionStyle")},this.setHighlightActiveLine=function(e){this.setOption("highlightActiveLine",e)},this.getHighlightActiveLine=function(){return this.getOption("highlightActiveLine")},this.setHighlightGutterLine=function(e){this.setOption("highlightGutterLine",e)},this.getHighlightGutterLine=function(){return this.getOption("highlightGutterLine")},this.setHighlightSelectedWord=function(e){this.setOption("highlightSelectedWord",e)},this.getHighlightSelectedWord=function(){return this.$highlightSelectedWord},this.setAnimatedScroll=function(e){this.renderer.setAnimatedScroll(e)},this.getAnimatedScroll=function(){return this.renderer.getAnimatedScroll()},this.setShowInvisibles=function(e){this.renderer.setShowInvisibles(e)},this.getShowInvisibles=function(){return this.renderer.getShowInvisibles()},this.setDisplayIndentGuides=function(e){this.renderer.setDisplayIndentGuides(e)},this.getDisplayIndentGuides=function(){return this.renderer.getDisplayIndentGuides()},this.setShowPrintMargin=function(e){this.renderer.setShowPrintMargin(e)},this.getShowPrintMargin=function(){return this.renderer.getShowPrintMargin()},this.setPrintMarginColumn=function(e){this.renderer.setPrintMarginColumn(e)},this.getPrintMarginColumn=function(){return this.renderer.getPrintMarginColumn()},this.setReadOnly=function(e){this.setOption("readOnly",e)},this.getReadOnly=function(){return this.getOption("readOnly")},this.setBehavioursEnabled=function(e){this.setOption("behavioursEnabled",e)},this.getBehavioursEnabled=function(){return this.getOption("behavioursEnabled")},this.setWrapBehavioursEnabled=function(e){this.setOption("wrapBehavioursEnabled",e)},this.getWrapBehavioursEnabled=function(){return this.getOption("wrapBehavioursEnabled")},this.setShowFoldWidgets=function(e){this.setOption("showFoldWidgets",e)},this.getShowFoldWidgets=function(){return this.getOption("showFoldWidgets")},this.setFadeFoldWidgets=function(e){this.setOption("fadeFoldWidgets",e)},this.getFadeFoldWidgets=function(){return this.getOption("fadeFoldWidgets")},this.remove=function(e){this.selection.isEmpty()&&(e=="left"?this.selection.selectLeft():this.selection.selectRight());var t=this.getSelectionRange();if(this.getBehavioursEnabled()){var n=this.session,r=n.getState(t.start.row),i=n.getMode().transformAction(r,"deletion",this,n,t);if(t.end.column===0){var s=n.getTextRange(t);if(s[s.length-1]=="\n"){var o=n.getLine(t.end.row);/^\s+$/.test(o)&&(t.end.column=o.length)}}i&&(t=i)}this.session.remove(t),this.clearSelection()},this.removeWordRight=function(){this.selection.isEmpty()&&this.selection.selectWordRight(),this.session.remove(this.getSelectionRange()),this.clearSelection()},this.removeWordLeft=function(){this.selection.isEmpty()&&this.selection.selectWordLeft(),this.session.remove(this.getSelectionRange()),this.clearSelection()},this.removeToLineStart=function(){this.selection.isEmpty()&&this.selection.selectLineStart(),this.session.remove(this.getSelectionRange()),this.clearSelection()},this.removeToLineEnd=function(){this.selection.isEmpty()&&this.selection.selectLineEnd();var e=this.getSelectionRange();e.start.column==e.end.column&&e.start.row==e.end.row&&(e.end.column=0,e.end.row++),this.session.remove(e),this.clearSelection()},this.splitLine=function(){this.selection.isEmpty()||(this.session.remove(this.getSelectionRange()),this.clearSelection());var e=this.getCursorPosition();this.insert("\n"),this.moveCursorToPosition(e)},this.transposeLetters=function(){if(!this.selection.isEmpty())return;var e=this.getCursorPosition(),t=e.column;if(t===0)return;var n=this.session.getLine(e.row),r,i;tt.toLowerCase()?1:0});var r=new p(0,0,0,0);for(var i=e.first;i<=e.last;i++){var s=t.getLine(i);r.start.row=i,r.end.row=i,r.end.column=s.length,t.replace(r,n[i-e.first])}},this.toggleCommentLines=function(){var e=this.session.getState(this.getCursorPosition().row),t=this.$getSelectedRows();this.session.getMode().toggleCommentLines(e,this.session,t.first,t.last)},this.toggleBlockComment=function(){var e=this.getCursorPosition(),t=this.session.getState(e.row),n=this.getSelectionRange();this.session.getMode().toggleBlockComment(t,this.session,n,e)},this.getNumberAt=function(e,t){var n=/[\-]?[0-9]+(?:\.[0-9]+)?/g;n.lastIndex=0;var r=this.session.getLine(e);while(n.lastIndex=t){var s={value:i[0],start:i.index,end:i.index+i[0].length};return s}}return null},this.modifyNumber=function(e){var t=this.selection.getCursor().row,n=this.selection.getCursor().column,r=new p(t,n-1,t,n),i=this.session.getTextRange(r);if(!isNaN(parseFloat(i))&&isFinite(i)){var s=this.getNumberAt(t,n);if(s){var o=s.value.indexOf(".")>=0?s.start+s.value.indexOf(".")+1:s.end,u=s.start+s.value.length-o,a=parseFloat(s.value);a*=Math.pow(10,u),o!==s.end&&np+1)break;p=d.last}l--,u=this.session.$moveLines(h,p,t?0:e),t&&e==-1&&(c=l+1);while(c<=l)o[c].moveBy(u,0),c++;t||(u=0),a+=u}i.fromOrientedRange(i.ranges[0]),i.rangeList.attach(this.session),this.inVirtualSelectionMode=!1}},this.$getSelectedRows=function(e){return e=(e||this.getSelectionRange()).collapseRows(),{first:this.session.getRowFoldStart(e.start.row),last:this.session.getRowFoldEnd(e.end.row)}},this.onCompositionStart=function(e){this.renderer.showComposition(this.getCursorPosition())},this.onCompositionUpdate=function(e){this.renderer.setCompositionText(e)},this.onCompositionEnd=function(){this.renderer.hideComposition()},this.getFirstVisibleRow=function(){return this.renderer.getFirstVisibleRow()},this.getLastVisibleRow=function(){return this.renderer.getLastVisibleRow()},this.isRowVisible=function(e){return e>=this.getFirstVisibleRow()&&e<=this.getLastVisibleRow()},this.isRowFullyVisible=function(e){return e>=this.renderer.getFirstFullyVisibleRow()&&e<=this.renderer.getLastFullyVisibleRow()},this.$getVisibleRowCount=function(){return this.renderer.getScrollBottomRow()-this.renderer.getScrollTopRow()+1},this.$moveByPage=function(e,t){var n=this.renderer,r=this.renderer.layerConfig,i=e*Math.floor(r.height/r.lineHeight);this.$blockScrolling++,t===!0?this.selection.$moveSelection(function(){this.moveCursorBy(i,0)}):t===!1&&(this.selection.moveCursorBy(i,0),this.selection.clearSelection()),this.$blockScrolling--;var s=n.scrollTop;n.scrollBy(0,i*r.lineHeight),t!=null&&n.scrollCursorIntoView(null,.5),n.animateScrolling(s)},this.selectPageDown=function(){this.$moveByPage(1,!0)},this.selectPageUp=function(){this.$moveByPage(-1,!0)},this.gotoPageDown=function(){this.$moveByPage(1,!1)},this.gotoPageUp=function(){this.$moveByPage(-1,!1)},this.scrollPageDown=function(){this.$moveByPage(1)},this.scrollPageUp=function(){this.$moveByPage(-1)},this.scrollToRow=function(e){this.renderer.scrollToRow(e)},this.scrollToLine=function(e,t,n,r){this.renderer.scrollToLine(e,t,n,r)},this.centerSelection=function(){var e=this.getSelectionRange(),t={row:Math.floor(e.start.row+(e.end.row-e.start.row)/2),column:Math.floor(e.start.column+(e.end.column-e.start.column)/2)};this.renderer.alignCursor(t,.5)},this.getCursorPosition=function(){return this.selection.getCursor()},this.getCursorPositionScreen=function(){return this.session.documentToScreenPosition(this.getCursorPosition())},this.getSelectionRange=function(){return this.selection.getRange()},this.selectAll=function(){this.$blockScrolling+=1,this.selection.selectAll(),this.$blockScrolling-=1},this.clearSelection=function(){this.selection.clearSelection()},this.moveCursorTo=function(e,t){this.selection.moveCursorTo(e,t)},this.moveCursorToPosition=function(e){this.selection.moveCursorToPosition(e)},this.jumpToMatching=function(e,t){var n=this.getCursorPosition(),r=new y(this.session,n.row,n.column),i=r.getCurrentToken(),s=i||r.stepForward();if(!s)return;var o,u=!1,a={},f=n.column-s.start,l,c={")":"(","(":"(","]":"[","[":"[","{":"{","}":"{"};do{if(s.value.match(/[{}()\[\]]/g))for(;f=0;--s)this.$tryReplace(n[s],e)&&r++;return this.selection.setSelectionRange(i),this.$blockScrolling-=1,r},this.$tryReplace=function(e,t){var n=this.session.getTextRange(e);return t=this.$search.replace(n,t),t!==null?(e.end=this.session.replace(e,t),e):null},this.getLastSearchOptions=function(){return this.$search.getOptions()},this.find=function(e,t,n){t||(t={}),typeof e=="string"||e instanceof RegExp?t.needle=e:typeof e=="object"&&r.mixin(t,e);var i=this.selection.getRange();t.needle==null&&(e=this.session.getTextRange(i)||this.$search.$options.needle,e||(i=this.session.getWordRange(i.start.row,i.start.column),e=this.session.getTextRange(i)),this.$search.set({needle:e})),this.$search.set(t),t.start||this.$search.set({start:i});var s=this.$search.find(this.session);if(t.preventScroll)return s;if(s)return this.revealRange(s,n),s;t.backwards?i.start=i.end:i.end=i.start,this.selection.setRange(i)},this.findNext=function(e,t){this.find({skipCurrent:!0,backwards:!1},e,t)},this.findPrevious=function(e,t){this.find(e,{skipCurrent:!0,backwards:!0},t)},this.revealRange=function(e,t){this.$blockScrolling+=1,this.session.unfold(e),this.selection.setSelectionRange(e),this.$blockScrolling-=1;var n=this.renderer.scrollTop;this.renderer.scrollSelectionIntoView(e.start,e.end,.5),t!==!1&&this.renderer.animateScrolling(n)},this.undo=function(){this.$blockScrolling++,this.session.getUndoManager().undo(),this.$blockScrolling--,this.renderer.scrollCursorIntoView(null,.5)},this.redo=function(){this.$blockScrolling++,this.session.getUndoManager().redo(),this.$blockScrolling--,this.renderer.scrollCursorIntoView(null,.5)},this.destroy=function(){this.renderer.destroy(),this._signal("destroy",this),this.session&&this.session.destroy()},this.setAutoScrollEditorIntoView=function(e){if(!e)return;var t,n=this,r=!1;this.$scrollAnchor||(this.$scrollAnchor=document.createElement("div"));var i=this.$scrollAnchor;i.style.cssText="position:absolute",this.container.insertBefore(i,this.container.firstChild);var s=this.on("changeSelection",function(){r=!0}),o=this.renderer.on("beforeRender",function(){r&&(t=n.renderer.container.getBoundingClientRect())}),u=this.renderer.on("afterRender",function(){if(r&&t&&(n.isFocused()||n.searchBox&&n.searchBox.isFocused())){var e=n.renderer,s=e.$cursorLayer.$pixelPos,o=e.layerConfig,u=s.top-o.offset;s.top>=0&&u+t.top<0?r=!0:s.topwindow.innerHeight?r=!1:r=null,r!=null&&(i.style.top=u+"px",i.style.left=s.left+"px",i.style.height=o.lineHeight+"px",i.scrollIntoView(r)),r=t=null}});this.setAutoScrollEditorIntoView=function(e){if(e)return;delete this.setAutoScrollEditorIntoView,this.off("changeSelection",s),this.renderer.off("afterRender",u),this.renderer.off("beforeRender",o)}},this.$resetCursorStyle=function(){var e=this.$cursorStyle||"ace",t=this.renderer.$cursorLayer;if(!t)return;t.setSmoothBlinking(/smooth/.test(e)),t.isBlinking=!this.$readOnly&&e!="wide",i.setCssClass(t.element,"ace_slim-cursors",/slim/.test(e))}}).call(b.prototype),g.defineOptions(b.prototype,"editor",{selectionStyle:{set:function(e){this.onSelectionChange(),this._signal("changeSelectionStyle",{data:e})},initialValue:"line"},highlightActiveLine:{set:function(){this.$updateHighlightActiveLine()},initialValue:!0},highlightSelectedWord:{set:function(e){this.$onSelectionChange()},initialValue:!0},readOnly:{set:function(e){this.$resetCursorStyle()},initialValue:!1},cursorStyle:{set:function(e){this.$resetCursorStyle()},values:["ace","slim","smooth","wide"],initialValue:"ace"},mergeUndoDeltas:{values:[!1,!0,"always"],initialValue:!0},behavioursEnabled:{initialValue:!0},wrapBehavioursEnabled:{initialValue:!0},autoScrollEditorIntoView:{set:function(e){this.setAutoScrollEditorIntoView(e)}},keyboardHandler:{set:function(e){this.setKeyboardHandler(e)},get:function(){return this.keybindingId},handlesSet:!0},hScrollBarAlwaysVisible:"renderer",vScrollBarAlwaysVisible:"renderer",highlightGutterLine:"renderer",animatedScroll:"renderer",showInvisibles:"renderer",showPrintMargin:"renderer",printMarginColumn:"renderer",printMargin:"renderer",fadeFoldWidgets:"renderer",showFoldWidgets:"renderer",showLineNumbers:"renderer",showGutter:"renderer",displayIndentGuides:"renderer",fontSize:"renderer",fontFamily:"renderer",maxLines:"renderer",minLines:"renderer",scrollPastEnd:"renderer",fixedWidthGutter:"renderer",theme:"renderer",scrollSpeed:"$mouseHandler",dragDelay:"$mouseHandler",dragEnabled:"$mouseHandler",focusTimout:"$mouseHandler",tooltipFollowsMouse:"$mouseHandler",firstLineNumber:"session",overwrite:"session",newLineMode:"session",useWorker:"session",useSoftTabs:"session",tabSize:"session",wrap:"session",indentedSoftWrap:"session",foldStyle:"session",mode:"session"}),t.Editor=b}),define("ace/undomanager",["require","exports","module"],function(e,t,n){"use strict";var r=function(){this.reset()};(function(){function e(e){return{action:e.action,start:e.start,end:e.end,lines:e.lines.length==1?null:e.lines,text:e.lines.length==1?e.lines[0]:null}}function t(e){return{action:e.action,start:e.start,end:e.end,lines:e.lines||[e.text]}}function n(e,t){var n=new Array(e.length);for(var r=0;r0},this.hasRedo=function(){return this.$redoStack.length>0},this.markClean=function(){this.dirtyCounter=0},this.isClean=function(){return this.dirtyCounter===0},this.$serializeDeltas=function(t){return n(t,e)},this.$deserializeDeltas=function(e){return n(e,t)}}).call(r.prototype),t.UndoManager=r}),define("ace/layer/gutter",["require","exports","module","ace/lib/dom","ace/lib/oop","ace/lib/lang","ace/lib/event_emitter"],function(e,t,n){"use strict";var r=e("../lib/dom"),i=e("../lib/oop"),s=e("../lib/lang"),o=e("../lib/event_emitter").EventEmitter,u=function(e){this.element=r.createElement("div"),this.element.className="ace_layer ace_gutter-layer",e.appendChild(this.element),this.setShowFoldWidgets(this.$showFoldWidgets),this.gutterWidth=0,this.$annotations=[],this.$updateAnnotations=this.$updateAnnotations.bind(this),this.$cells=[]};(function(){i.implement(this,o),this.setSession=function(e){this.session&&this.session.removeEventListener("change",this.$updateAnnotations),this.session=e,e&&e.on("change",this.$updateAnnotations)},this.addGutterDecoration=function(e,t){window.console&&console.warn&&console.warn("deprecated use session.addGutterDecoration"),this.session.addGutterDecoration(e,t)},this.removeGutterDecoration=function(e,t){window.console&&console.warn&&console.warn("deprecated use session.removeGutterDecoration"),this.session.removeGutterDecoration(e,t)},this.setAnnotations=function(e){this.$annotations=[];for(var t=0;to&&(v=s.end.row+1,s=t.getNextFoldLine(v,s),o=s?s.start.row:Infinity);if(v>i){while(this.$cells.length>d+1)p=this.$cells.pop(),this.element.removeChild(p.element);break}p=this.$cells[++d],p||(p={element:null,textNode:null,foldWidget:null},p.element=r.createElement("div"),p.textNode=document.createTextNode(""),p.element.appendChild(p.textNode),this.element.appendChild(p.element),this.$cells[d]=p);var m="ace_gutter-cell ";a[v]&&(m+=a[v]),f[v]&&(m+=f[v]),this.$annotations[v]&&(m+=this.$annotations[v].className),p.element.className!=m&&(p.element.className=m);var g=t.getRowLength(v)*e.lineHeight+"px";g!=p.element.style.height&&(p.element.style.height=g);if(u){var y=u[v];y==null&&(y=u[v]=t.getFoldWidget(v))}if(y){p.foldWidget||(p.foldWidget=r.createElement("span"),p.element.appendChild(p.foldWidget));var m="ace_fold-widget ace_"+y;y=="start"&&v==o&&vn.right-t.right)return"foldWidgets"}}).call(u.prototype),t.Gutter=u}),define("ace/layer/marker",["require","exports","module","ace/range","ace/lib/dom"],function(e,t,n){"use strict";var r=e("../range").Range,i=e("../lib/dom"),s=function(e){this.element=i.createElement("div"),this.element.className="ace_layer ace_marker-layer",e.appendChild(this.element)};(function(){function e(e,t,n,r){return(e?1:0)|(t?2:0)|(n?4:0)|(r?8:0)}this.$padding=0,this.setPadding=function(e){this.$padding=e},this.setSession=function(e){this.session=e},this.setMarkers=function(e){this.markers=e},this.update=function(e){var e=e||this.config;if(!e)return;this.config=e;var t=[];for(var n in this.markers){var r=this.markers[n];if(!r.range){r.update(t,this,this.session,e);continue}var i=r.range.clipRows(e.firstRow,e.lastRow);if(i.isEmpty())continue;i=i.toScreenRange(this.session);if(r.renderer){var s=this.$getTop(i.start.row,e),o=this.$padding+i.start.column*e.characterWidth;r.renderer(t,i,o,s,e)}else r.type=="fullLine"?this.drawFullLineMarker(t,i,r.clazz,e):r.type=="screenLine"?this.drawScreenLineMarker(t,i,r.clazz,e):i.isMultiLine()?r.type=="text"?this.drawTextMarker(t,i,r.clazz,e):this.drawMultiLineMarker(t,i,r.clazz,e):this.drawSingleLineMarker(t,i,r.clazz+" ace_start"+" ace_br15",e)}this.element.innerHTML=t.join("")},this.$getTop=function(e,t){return(e-t.firstRowScreen)*t.lineHeight},this.drawTextMarker=function(t,n,i,s,o){var u=this.session,a=n.start.row,f=n.end.row,l=a,c=0,h=0,p=u.getScreenLastRowColumn(l),d=new r(l,n.start.column,l,h);for(;l<=f;l++)d.start.row=d.end.row=l,d.start.column=l==a?n.start.column:u.getRowWrapIndent(l),d.end.column=p,c=h,h=p,p=l+1p,l==f),s,l==f?0:1,o)},this.drawMultiLineMarker=function(e,t,n,r,i){var s=this.$padding,o=r.lineHeight,u=this.$getTop(t.start.row,r),a=s+t.start.column*r.characterWidth;i=i||"",e.push("
"),u=this.$getTop(t.end.row,r);var f=t.end.column*r.characterWidth;e.push("
"),o=(t.end.row-t.start.row-1)*r.lineHeight;if(o<=0)return;u=this.$getTop(t.start.row+1,r);var l=(t.start.column?1:0)|(t.end.column?0:8);e.push("
")},this.drawSingleLineMarker=function(e,t,n,r,i,s){var o=r.lineHeight,u=(t.end.column+(i||0)-t.start.column)*r.characterWidth,a=this.$getTop(t.start.row,r),f=this.$padding+t.start.column*r.characterWidth;e.push("
")},this.drawFullLineMarker=function(e,t,n,r,i){var s=this.$getTop(t.start.row,r),o=r.lineHeight;t.start.row!=t.end.row&&(o+=this.$getTop(t.end.row,r)-s),e.push("
")},this.drawScreenLineMarker=function(e,t,n,r,i){var s=this.$getTop(t.start.row,r),o=r.lineHeight;e.push("
")}}).call(s.prototype),t.Marker=s}),define("ace/layer/text",["require","exports","module","ace/lib/oop","ace/lib/dom","ace/lib/lang","ace/lib/useragent","ace/lib/event_emitter"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/dom"),s=e("../lib/lang"),o=e("../lib/useragent"),u=e("../lib/event_emitter").EventEmitter,a=function(e){this.element=i.createElement("div"),this.element.className="ace_layer ace_text-layer",e.appendChild(this.element),this.$updateEolChar=this.$updateEolChar.bind(this)};(function(){r.implement(this,u),this.EOF_CHAR="\u00b6",this.EOL_CHAR_LF="\u00ac",this.EOL_CHAR_CRLF="\u00a4",this.EOL_CHAR=this.EOL_CHAR_LF,this.TAB_CHAR="\u2014",this.SPACE_CHAR="\u00b7",this.$padding=0,this.$updateEolChar=function(){var e=this.session.doc.getNewLineCharacter()=="\n"?this.EOL_CHAR_LF:this.EOL_CHAR_CRLF;if(this.EOL_CHAR!=e)return this.EOL_CHAR=e,!0},this.setPadding=function(e){this.$padding=e,this.element.style.padding="0 "+e+"px"},this.getLineHeight=function(){return this.$fontMetrics.$characterSize.height||0},this.getCharacterWidth=function(){return this.$fontMetrics.$characterSize.width||0},this.$setFontMetrics=function(e){this.$fontMetrics=e,this.$fontMetrics.on("changeCharacterSize",function(e){this._signal("changeCharacterSize",e)}.bind(this)),this.$pollSizeChanges()},this.checkForSizeChanges=function(){this.$fontMetrics.checkForSizeChanges()},this.$pollSizeChanges=function(){return this.$pollSizeChangesTimer=this.$fontMetrics.$pollSizeChanges()},this.setSession=function(e){this.session=e,e&&this.$computeTabString()},this.showInvisibles=!1,this.setShowInvisibles=function(e){return this.showInvisibles==e?!1:(this.showInvisibles=e,this.$computeTabString(),!0)},this.displayIndentGuides=!0,this.setDisplayIndentGuides=function(e){return this.displayIndentGuides==e?!1:(this.displayIndentGuides=e,this.$computeTabString(),!0)},this.$tabStrings=[],this.onChangeTabSize=this.$computeTabString=function(){var e=this.session.getTabSize();this.tabSize=e;var t=this.$tabStrings=[0];for(var n=1;n"+s.stringRepeat(this.TAB_CHAR,n)+""):t.push(s.stringRepeat(" ",n));if(this.displayIndentGuides){this.$indentGuideRe=/\s\S| \t|\t |\s$/;var r="ace_indent-guide",i="",o="";if(this.showInvisibles){r+=" ace_invisible",i=" ace_invisible_space",o=" ace_invisible_tab";var u=s.stringRepeat(this.SPACE_CHAR,this.tabSize),a=s.stringRepeat(this.TAB_CHAR,this.tabSize)}else var u=s.stringRepeat(" ",this.tabSize),a=u;this.$tabStrings[" "]=""+u+"",this.$tabStrings[" "]=""+a+""}},this.updateLines=function(e,t,n){(this.config.lastRow!=e.lastRow||this.config.firstRow!=e.firstRow)&&this.scrollLines(e),this.config=e;var r=Math.max(t,e.firstRow),i=Math.min(n,e.lastRow),s=this.element.childNodes,o=0;for(var u=e.firstRow;uf&&(u=a.end.row+1,a=this.session.getNextFoldLine(u,a),f=a?a.start.row:Infinity);if(u>i)break;var l=s[o++];if(l){var c=[];this.$renderLine(c,u,!this.$useLineGroups(),u==f?a:!1),l.style.height=e.lineHeight*this.session.getRowLength(u)+"px",l.innerHTML=c.join("")}u++}},this.scrollLines=function(e){var t=this.config;this.config=e;if(!t||t.lastRow0;r--)n.removeChild(n.firstChild);if(t.lastRow>e.lastRow)for(var r=this.session.getFoldedRowCount(e.lastRow+1,t.lastRow);r>0;r--)n.removeChild(n.lastChild);if(e.firstRowt.lastRow){var i=this.$renderLinesFragment(e,t.lastRow+1,e.lastRow);n.appendChild(i)}},this.$renderLinesFragment=function(e,t,n){var r=this.element.ownerDocument.createDocumentFragment(),s=t,o=this.session.getNextFoldLine(s),u=o?o.start.row:Infinity;for(;;){s>u&&(s=o.end.row+1,o=this.session.getNextFoldLine(s,o),u=o?o.start.row:Infinity);if(s>n)break;var a=i.createElement("div"),f=[];this.$renderLine(f,s,!1,s==u?o:!1),a.innerHTML=f.join("");if(this.$useLineGroups())a.className="ace_line_group",r.appendChild(a),a.style.height=e.lineHeight*this.session.getRowLength(s)+"px";else while(a.firstChild)r.appendChild(a.firstChild);s++}return r},this.update=function(e){this.config=e;var t=[],n=e.firstRow,r=e.lastRow,i=n,s=this.session.getNextFoldLine(i),o=s?s.start.row:Infinity;for(;;){i>o&&(i=s.end.row+1,s=this.session.getNextFoldLine(i,s),o=s?s.start.row:Infinity);if(i>r)break;this.$useLineGroups()&&t.push("
"),this.$renderLine(t,i,!1,i==o?s:!1),this.$useLineGroups()&&t.push("
"),i++}this.element.innerHTML=t.join("")},this.$textToken={text:!0,rparen:!0,lparen:!0},this.$renderToken=function(e,t,n,r){var i=this,o=/\t|&|<|>|( +)|([\x00-\x1f\x80-\xa0\xad\u1680\u180E\u2000-\u200f\u2028\u2029\u202F\u205F\u3000\uFEFF\uFFF9-\uFFFC])|[\u1100-\u115F\u11A3-\u11A7\u11FA-\u11FF\u2329-\u232A\u2E80-\u2E99\u2E9B-\u2EF3\u2F00-\u2FD5\u2FF0-\u2FFB\u3000-\u303E\u3041-\u3096\u3099-\u30FF\u3105-\u312D\u3131-\u318E\u3190-\u31BA\u31C0-\u31E3\u31F0-\u321E\u3220-\u3247\u3250-\u32FE\u3300-\u4DBF\u4E00-\uA48C\uA490-\uA4C6\uA960-\uA97C\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFAFF\uFE10-\uFE19\uFE30-\uFE52\uFE54-\uFE66\uFE68-\uFE6B\uFF01-\uFF60\uFFE0-\uFFE6]/g,u=function(e,n,r,o,u){if(n)return i.showInvisibles?""+s.stringRepeat(i.SPACE_CHAR,e.length)+"":e;if(e=="&")return"&";if(e=="<")return"<";if(e==">")return">";if(e==" "){var a=i.session.getScreenTabSize(t+o);return t+=a-1,i.$tabStrings[a]}if(e=="\u3000"){var f=i.showInvisibles?"ace_cjk ace_invisible ace_invisible_space":"ace_cjk",l=i.showInvisibles?i.SPACE_CHAR:"";return t+=1,""+l+""}return r?""+i.SPACE_CHAR+"":(t+=1,""+e+"")},a=r.replace(o,u);if(!this.$textToken[n.type]){var f="ace_"+n.type.replace(/\./g," ace_"),l="";n.type=="fold"&&(l=" style='width:"+n.value.length*this.config.characterWidth+"px;' "),e.push("",a,"")}else e.push(a);return t+r.length},this.renderIndentGuide=function(e,t,n){var r=t.search(this.$indentGuideRe);return r<=0||r>=n?t:t[0]==" "?(r-=r%this.tabSize,e.push(s.stringRepeat(this.$tabStrings[" "],r/this.tabSize)),t.substr(r)):t[0]==" "?(e.push(s.stringRepeat(this.$tabStrings[" "],r)),t.substr(r)):t},this.$renderWrappedLine=function(e,t,n,r){var i=0,o=0,u=n[0],a=0;for(var f=0;f=u)a=this.$renderToken(e,a,l,c.substring(0,u-i)),c=c.substring(u-i),i=u,r||e.push("","
"),e.push(s.stringRepeat("\u00a0",n.indent)),o++,a=0,u=n[o]||Number.MAX_VALUE;c.length!=0&&(i+=c.length,a=this.$renderToken(e,a,l,c))}}},this.$renderSimpleLine=function(e,t){var n=0,r=t[0],i=r.value;this.displayIndentGuides&&(i=this.renderIndentGuide(e,i)),i&&(n=this.$renderToken(e,n,r,i));for(var s=1;s");if(i.length){var s=this.session.getRowSplitData(t);s&&s.length?this.$renderWrappedLine(e,i,s,n):this.$renderSimpleLine(e,i)}this.showInvisibles&&(r&&(t=r.end.row),e.push("",t==this.session.getLength()-1?this.EOF_CHAR:this.EOL_CHAR,"")),n||e.push("
")},this.$getFoldLineTokens=function(e,t){function i(e,t,n){var i=0,s=0;while(s+e[i].value.lengthn-t&&(o=o.substring(0,n-t)),r.push({type:e[i].type,value:o}),s=t+o.length,i+=1}while(sn?r.push({type:e[i].type,value:o.substring(0,n-s)}):r.push(e[i]),s+=o.length,i+=1}}var n=this.session,r=[],s=n.getTokens(e);return t.walk(function(e,t,o,u,a){e!=null?r.push({type:"fold",value:e}):(a&&(s=n.getTokens(t)),s.length&&i(s,u,o))},t.end.row,this.session.getLine(t.end.row).length),r},this.$useLineGroups=function(){return this.session.getUseWrapMode()},this.destroy=function(){clearInterval(this.$pollSizeChangesTimer),this.$measureNode&&this.$measureNode.parentNode.removeChild(this.$measureNode),delete this.$measureNode}}).call(a.prototype),t.Text=a}),define("ace/layer/cursor",["require","exports","module","ace/lib/dom"],function(e,t,n){"use strict";var r=e("../lib/dom"),i,s=function(e){this.element=r.createElement("div"),this.element.className="ace_layer ace_cursor-layer",e.appendChild(this.element),i===undefined&&(i=!("opacity"in this.element.style)),this.isVisible=!1,this.isBlinking=!0,this.blinkInterval=1e3,this.smoothBlinking=!1,this.cursors=[],this.cursor=this.addCursor(),r.addCssClass(this.element,"ace_hidden-cursors"),this.$updateCursors=(i?this.$updateVisibility:this.$updateOpacity).bind(this)};(function(){this.$updateVisibility=function(e){var t=this.cursors;for(var n=t.length;n--;)t[n].style.visibility=e?"":"hidden"},this.$updateOpacity=function(e){var t=this.cursors;for(var n=t.length;n--;)t[n].style.opacity=e?"":"0"},this.$padding=0,this.setPadding=function(e){this.$padding=e},this.setSession=function(e){this.session=e},this.setBlinking=function(e){e!=this.isBlinking&&(this.isBlinking=e,this.restartTimer())},this.setBlinkInterval=function(e){e!=this.blinkInterval&&(this.blinkInterval=e,this.restartTimer())},this.setSmoothBlinking=function(e){e!=this.smoothBlinking&&!i&&(this.smoothBlinking=e,r.setCssClass(this.element,"ace_smooth-blinking",e),this.$updateCursors(!0),this.$updateCursors=this.$updateOpacity.bind(this),this.restartTimer())},this.addCursor=function(){var e=r.createElement("div");return e.className="ace_cursor",this.element.appendChild(e),this.cursors.push(e),e},this.removeCursor=function(){if(this.cursors.length>1){var e=this.cursors.pop();return e.parentNode.removeChild(e),e}},this.hideCursor=function(){this.isVisible=!1,r.addCssClass(this.element,"ace_hidden-cursors"),this.restartTimer()},this.showCursor=function(){this.isVisible=!0,r.removeCssClass(this.element,"ace_hidden-cursors"),this.restartTimer()},this.restartTimer=function(){var e=this.$updateCursors;clearInterval(this.intervalId),clearTimeout(this.timeoutId),this.smoothBlinking&&r.removeCssClass(this.element,"ace_smooth-blinking"),e(!0);if(!this.isBlinking||!this.blinkInterval||!this.isVisible)return;this.smoothBlinking&&setTimeout(function(){r.addCssClass(this.element,"ace_smooth-blinking")}.bind(this));var t=function(){this.timeoutId=setTimeout(function(){e(!1)},.6*this.blinkInterval)}.bind(this);this.intervalId=setInterval(function(){e(!0),t()},this.blinkInterval),t()},this.getPixelPosition=function(e,t){if(!this.config||!this.session)return{left:0,top:0};e||(e=this.session.selection.getCursor());var n=this.session.documentToScreenPosition(e),r=this.$padding+n.column*this.config.characterWidth,i=(n.row-(t?this.config.firstRowScreen:0))*this.config.lineHeight;return{left:r,top:i}},this.update=function(e){this.config=e;var t=this.session.$selectionMarkers,n=0,r=0;if(t===undefined||t.length===0)t=[{cursor:null}];for(var n=0,i=t.length;ne.height+e.offset||s.top<0)&&n>1)continue;var o=(this.cursors[r++]||this.addCursor()).style;this.drawCursor?this.drawCursor(o,s,e,t[n],this.session):(o.left=s.left+"px",o.top=s.top+"px",o.width=e.characterWidth+"px",o.height=e.lineHeight+"px")}while(this.cursors.length>r)this.removeCursor();var u=this.session.getOverwrite();this.$setOverwrite(u),this.$pixelPos=s,this.restartTimer()},this.drawCursor=null,this.$setOverwrite=function(e){e!=this.overwrite&&(this.overwrite=e,e?r.addCssClass(this.element,"ace_overwrite-cursors"):r.removeCssClass(this.element,"ace_overwrite-cursors"))},this.destroy=function(){clearInterval(this.intervalId),clearTimeout(this.timeoutId)}}).call(s.prototype),t.Cursor=s}),define("ace/scrollbar",["require","exports","module","ace/lib/oop","ace/lib/dom","ace/lib/event","ace/lib/event_emitter"],function(e,t,n){"use strict";var r=e("./lib/oop"),i=e("./lib/dom"),s=e("./lib/event"),o=e("./lib/event_emitter").EventEmitter,u=32768,a=function(e){this.element=i.createElement("div"),this.element.className="ace_scrollbar ace_scrollbar"+this.classSuffix,this.inner=i.createElement("div"),this.inner.className="ace_scrollbar-inner",this.element.appendChild(this.inner),e.appendChild(this.element),this.setVisible(!1),this.skipEvent=!1,s.addListener(this.element,"scroll",this.onScroll.bind(this)),s.addListener(this.element,"mousedown",s.preventDefault)};(function(){r.implement(this,o),this.setVisible=function(e){this.element.style.display=e?"":"none",this.isVisible=e,this.coeff=1}}).call(a.prototype);var f=function(e,t){a.call(this,e),this.scrollTop=0,this.scrollHeight=0,t.$scrollbarWidth=this.width=i.scrollbarWidth(e.ownerDocument),this.inner.style.width=this.element.style.width=(this.width||15)+5+"px"};r.inherits(f,a),function(){this.classSuffix="-v",this.onScroll=function(){if(!this.skipEvent){this.scrollTop=this.element.scrollTop;if(this.coeff!=1){var e=this.element.clientHeight/this.scrollHeight;this.scrollTop=this.scrollTop*(1-e)/(this.coeff-e)}this._emit("scroll",{data:this.scrollTop})}this.skipEvent=!1},this.getWidth=function(){return this.isVisible?this.width:0},this.setHeight=function(e){this.element.style.height=e+"px"},this.setInnerHeight=this.setScrollHeight=function(e){this.scrollHeight=e,e>u?(this.coeff=u/e,e=u):this.coeff!=1&&(this.coeff=1),this.inner.style.height=e+"px"},this.setScrollTop=function(e){this.scrollTop!=e&&(this.skipEvent=!0,this.scrollTop=e,this.element.scrollTop=e*this.coeff)}}.call(f.prototype);var l=function(e,t){a.call(this,e),this.scrollLeft=0,this.height=t.$scrollbarWidth,this.inner.style.height=this.element.style.height=(this.height||15)+5+"px"};r.inherits(l,a),function(){this.classSuffix="-h",this.onScroll=function(){this.skipEvent||(this.scrollLeft=this.element.scrollLeft,this._emit("scroll",{data:this.scrollLeft})),this.skipEvent=!1},this.getHeight=function(){return this.isVisible?this.height:0},this.setWidth=function(e){this.element.style.width=e+"px"},this.setInnerWidth=function(e){this.inner.style.width=e+"px"},this.setScrollWidth=function(e){this.inner.style.width=e+"px"},this.setScrollLeft=function(e){this.scrollLeft!=e&&(this.skipEvent=!0,this.scrollLeft=this.element.scrollLeft=e)}}.call(l.prototype),t.ScrollBar=f,t.ScrollBarV=f,t.ScrollBarH=l,t.VScrollBar=f,t.HScrollBar=l}),define("ace/renderloop",["require","exports","module","ace/lib/event"],function(e,t,n){"use strict";var r=e("./lib/event"),i=function(e,t){this.onRender=e,this.pending=!1,this.changes=0,this.window=t||window};(function(){this.schedule=function(e){this.changes=this.changes|e;if(!this.pending&&this.changes){this.pending=!0;var t=this;r.nextFrame(function(){t.pending=!1;var e;while(e=t.changes)t.changes=0,t.onRender(e)},this.window)}}}).call(i.prototype),t.RenderLoop=i}),define("ace/layer/font_metrics",["require","exports","module","ace/lib/oop","ace/lib/dom","ace/lib/lang","ace/lib/useragent","ace/lib/event_emitter"],function(e,t,n){var r=e("../lib/oop"),i=e("../lib/dom"),s=e("../lib/lang"),o=e("../lib/useragent"),u=e("../lib/event_emitter").EventEmitter,a=0,f=t.FontMetrics=function(e){this.el=i.createElement("div"),this.$setMeasureNodeStyles(this.el.style,!0),this.$main=i.createElement("div"),this.$setMeasureNodeStyles(this.$main.style),this.$measureNode=i.createElement("div"),this.$setMeasureNodeStyles(this.$measureNode.style),this.el.appendChild(this.$main),this.el.appendChild(this.$measureNode),e.appendChild(this.el),a||this.$testFractionalRect(),this.$measureNode.innerHTML=s.stringRepeat("X",a),this.$characterSize={width:0,height:0},this.checkForSizeChanges()};(function(){r.implement(this,u),this.$characterSize={width:0,height:0},this.$testFractionalRect=function(){var e=i.createElement("div");this.$setMeasureNodeStyles(e.style),e.style.width="0.2px",document.documentElement.appendChild(e);var t=e.getBoundingClientRect().width;t>0&&t<1?a=50:a=100,e.parentNode.removeChild(e)},this.$setMeasureNodeStyles=function(e,t){e.width=e.height="auto",e.left=e.top="0px",e.visibility="hidden",e.position="absolute",e.whiteSpace="pre",o.isIE<8?e["font-family"]="inherit":e.font="inherit",e.overflow=t?"hidden":"visible"},this.checkForSizeChanges=function(){var e=this.$measureSizes();if(e&&(this.$characterSize.width!==e.width||this.$characterSize.height!==e.height)){this.$measureNode.style.fontWeight="bold";var t=this.$measureSizes();this.$measureNode.style.fontWeight="",this.$characterSize=e,this.charSizes=Object.create(null),this.allowBoldFonts=t&&t.width===e.width&&t.height===e.height,this._emit("changeCharacterSize",{data:e})}},this.$pollSizeChanges=function(){if(this.$pollSizeChangesTimer)return this.$pollSizeChangesTimer;var e=this;return this.$pollSizeChangesTimer=setInterval(function(){e.checkForSizeChanges()},500)},this.setPolling=function(e){e?this.$pollSizeChanges():this.$pollSizeChangesTimer&&(clearInterval(this.$pollSizeChangesTimer),this.$pollSizeChangesTimer=0)},this.$measureSizes=function(){if(a===50){var e=null;try{e=this.$measureNode.getBoundingClientRect()}catch(t){e={width:0,height:0}}var n={height:e.height,width:e.width/a}}else var n={height:this.$measureNode.clientHeight,width:this.$measureNode.clientWidth/a};return n.width===0||n.height===0?null:n},this.$measureCharWidth=function(e){this.$main.innerHTML=s.stringRepeat(e,a);var t=this.$main.getBoundingClientRect();return t.width/a},this.getCharacterWidth=function(e){var t=this.charSizes[e];return t===undefined&&(t=this.charSizes[e]=this.$measureCharWidth(e)/this.$characterSize.width),t},this.destroy=function(){clearInterval(this.$pollSizeChangesTimer),this.el&&this.el.parentNode&&this.el.parentNode.removeChild(this.el)}}).call(f.prototype)}),define("ace/virtual_renderer",["require","exports","module","ace/lib/oop","ace/lib/dom","ace/config","ace/lib/useragent","ace/layer/gutter","ace/layer/marker","ace/layer/text","ace/layer/cursor","ace/scrollbar","ace/scrollbar","ace/renderloop","ace/layer/font_metrics","ace/lib/event_emitter"],function(e,t,n){"use strict";var r=e("./lib/oop"),i=e("./lib/dom"),s=e("./config"),o=e("./lib/useragent"),u=e("./layer/gutter").Gutter,a=e("./layer/marker").Marker,f=e("./layer/text").Text,l=e("./layer/cursor").Cursor,c=e("./scrollbar").HScrollBar,h=e("./scrollbar").VScrollBar,p=e("./renderloop").RenderLoop,d=e("./layer/font_metrics").FontMetrics,v=e("./lib/event_emitter").EventEmitter,m='.ace_editor {position: relative;overflow: hidden;font: 12px/normal \'Monaco\', \'Menlo\', \'Ubuntu Mono\', \'Consolas\', \'source-code-pro\', monospace;direction: ltr;text-align: left;}.ace_scroller {position: absolute;overflow: hidden;top: 0;bottom: 0;background-color: inherit;-ms-user-select: none;-moz-user-select: none;-webkit-user-select: none;user-select: none;cursor: text;}.ace_content {position: absolute;-moz-box-sizing: border-box;-webkit-box-sizing: border-box;box-sizing: border-box;min-width: 100%;}.ace_dragging .ace_scroller:before{position: absolute;top: 0;left: 0;right: 0;bottom: 0;content: \'\';background: rgba(250, 250, 250, 0.01);z-index: 1000;}.ace_dragging.ace_dark .ace_scroller:before{background: rgba(0, 0, 0, 0.01);}.ace_selecting, .ace_selecting * {cursor: text !important;}.ace_gutter {position: absolute;overflow : hidden;width: auto;top: 0;bottom: 0;left: 0;cursor: default;z-index: 4;-ms-user-select: none;-moz-user-select: none;-webkit-user-select: none;user-select: none;}.ace_gutter-active-line {position: absolute;left: 0;right: 0;}.ace_scroller.ace_scroll-left {box-shadow: 17px 0 16px -16px rgba(0, 0, 0, 0.4) inset;}.ace_gutter-cell {padding-left: 19px;padding-right: 6px;background-repeat: no-repeat;}.ace_gutter-cell.ace_error {background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAABOFBMVEX/////////QRswFAb/Ui4wFAYwFAYwFAaWGAfDRymzOSH/PxswFAb/SiUwFAYwFAbUPRvjQiDllog5HhHdRybsTi3/Tyv9Tir+Syj/UC3////XurebMBIwFAb/RSHbPx/gUzfdwL3kzMivKBAwFAbbvbnhPx66NhowFAYwFAaZJg8wFAaxKBDZurf/RB6mMxb/SCMwFAYwFAbxQB3+RB4wFAb/Qhy4Oh+4QifbNRcwFAYwFAYwFAb/QRzdNhgwFAYwFAbav7v/Uy7oaE68MBK5LxLewr/r2NXewLswFAaxJw4wFAbkPRy2PyYwFAaxKhLm1tMwFAazPiQwFAaUGAb/QBrfOx3bvrv/VC/maE4wFAbRPBq6MRO8Qynew8Dp2tjfwb0wFAbx6eju5+by6uns4uH9/f36+vr/GkHjAAAAYnRSTlMAGt+64rnWu/bo8eAA4InH3+DwoN7j4eLi4xP99Nfg4+b+/u9B/eDs1MD1mO7+4PHg2MXa347g7vDizMLN4eG+Pv7i5evs/v79yu7S3/DV7/498Yv24eH+4ufQ3Ozu/v7+y13sRqwAAADLSURBVHjaZc/XDsFgGIBhtDrshlitmk2IrbHFqL2pvXf/+78DPokj7+Fz9qpU/9UXJIlhmPaTaQ6QPaz0mm+5gwkgovcV6GZzd5JtCQwgsxoHOvJO15kleRLAnMgHFIESUEPmawB9ngmelTtipwwfASilxOLyiV5UVUyVAfbG0cCPHig+GBkzAENHS0AstVF6bacZIOzgLmxsHbt2OecNgJC83JERmePUYq8ARGkJx6XtFsdddBQgZE2nPR6CICZhawjA4Fb/chv+399kfR+MMMDGOQAAAABJRU5ErkJggg==");background-repeat: no-repeat;background-position: 2px center;}.ace_gutter-cell.ace_warning {background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAmVBMVEX///8AAAD///8AAAAAAABPSzb/5sAAAAB/blH/73z/ulkAAAAAAAD85pkAAAAAAAACAgP/vGz/rkDerGbGrV7/pkQICAf////e0IsAAAD/oED/qTvhrnUAAAD/yHD/njcAAADuv2r/nz//oTj/p064oGf/zHAAAAA9Nir/tFIAAAD/tlTiuWf/tkIAAACynXEAAAAAAAAtIRW7zBpBAAAAM3RSTlMAABR1m7RXO8Ln31Z36zT+neXe5OzooRDfn+TZ4p3h2hTf4t3k3ucyrN1K5+Xaks52Sfs9CXgrAAAAjklEQVR42o3PbQ+CIBQFYEwboPhSYgoYunIqqLn6/z8uYdH8Vmdnu9vz4WwXgN/xTPRD2+sgOcZjsge/whXZgUaYYvT8QnuJaUrjrHUQreGczuEafQCO/SJTufTbroWsPgsllVhq3wJEk2jUSzX3CUEDJC84707djRc5MTAQxoLgupWRwW6UB5fS++NV8AbOZgnsC7BpEAAAAABJRU5ErkJggg==");background-position: 2px center;}.ace_gutter-cell.ace_info {background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAAAAAA6mKC9AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAAJ0Uk5TAAB2k804AAAAPklEQVQY02NgIB68QuO3tiLznjAwpKTgNyDbMegwisCHZUETUZV0ZqOquBpXj2rtnpSJT1AEnnRmL2OgGgAAIKkRQap2htgAAAAASUVORK5CYII=");background-position: 2px center;}.ace_dark .ace_gutter-cell.ace_info {background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAJFBMVEUAAAChoaGAgIAqKiq+vr6tra1ZWVmUlJSbm5s8PDxubm56enrdgzg3AAAAAXRSTlMAQObYZgAAAClJREFUeNpjYMAPdsMYHegyJZFQBlsUlMFVCWUYKkAZMxZAGdxlDMQBAG+TBP4B6RyJAAAAAElFTkSuQmCC");}.ace_scrollbar {position: absolute;right: 0;bottom: 0;z-index: 6;}.ace_scrollbar-inner {position: absolute;cursor: text;left: 0;top: 0;}.ace_scrollbar-v{overflow-x: hidden;overflow-y: scroll;top: 0;}.ace_scrollbar-h {overflow-x: scroll;overflow-y: hidden;left: 0;}.ace_print-margin {position: absolute;height: 100%;}.ace_text-input {position: absolute;z-index: 0;width: 0.5em;height: 1em;opacity: 0;background: transparent;-moz-appearance: none;appearance: none;border: none;resize: none;outline: none;overflow: hidden;font: inherit;padding: 0 1px;margin: 0 -1px;text-indent: -1em;-ms-user-select: text;-moz-user-select: text;-webkit-user-select: text;user-select: text;white-space: pre!important;}.ace_text-input.ace_composition {background: inherit;color: inherit;z-index: 1000;opacity: 1;text-indent: 0;}.ace_layer {z-index: 1;position: absolute;overflow: hidden;word-wrap: normal;white-space: pre;height: 100%;width: 100%;-moz-box-sizing: border-box;-webkit-box-sizing: border-box;box-sizing: border-box;pointer-events: none;}.ace_gutter-layer {position: relative;width: auto;text-align: right;pointer-events: auto;}.ace_text-layer {font: inherit !important;}.ace_cjk {display: inline-block;text-align: center;}.ace_cursor-layer {z-index: 4;}.ace_cursor {z-index: 4;position: absolute;-moz-box-sizing: border-box;-webkit-box-sizing: border-box;box-sizing: border-box;border-left: 2px solid;transform: translatez(0);}.ace_slim-cursors .ace_cursor {border-left-width: 1px;}.ace_overwrite-cursors .ace_cursor {border-left-width: 0;border-bottom: 1px solid;}.ace_hidden-cursors .ace_cursor {opacity: 0.2;}.ace_smooth-blinking .ace_cursor {-webkit-transition: opacity 0.18s;transition: opacity 0.18s;}.ace_editor.ace_multiselect .ace_cursor {border-left-width: 1px;}.ace_marker-layer .ace_step, .ace_marker-layer .ace_stack {position: absolute;z-index: 3;}.ace_marker-layer .ace_selection {position: absolute;z-index: 5;}.ace_marker-layer .ace_bracket {position: absolute;z-index: 6;}.ace_marker-layer .ace_active-line {position: absolute;z-index: 2;}.ace_marker-layer .ace_selected-word {position: absolute;z-index: 4;-moz-box-sizing: border-box;-webkit-box-sizing: border-box;box-sizing: border-box;}.ace_line .ace_fold {-moz-box-sizing: border-box;-webkit-box-sizing: border-box;box-sizing: border-box;display: inline-block;height: 11px;margin-top: -2px;vertical-align: middle;background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABEAAAAJCAYAAADU6McMAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAJpJREFUeNpi/P//PwOlgAXGYGRklAVSokD8GmjwY1wasKljQpYACtpCFeADcHVQfQyMQAwzwAZI3wJKvCLkfKBaMSClBlR7BOQikCFGQEErIH0VqkabiGCAqwUadAzZJRxQr/0gwiXIal8zQQPnNVTgJ1TdawL0T5gBIP1MUJNhBv2HKoQHHjqNrA4WO4zY0glyNKLT2KIfIMAAQsdgGiXvgnYAAAAASUVORK5CYII="),url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAA3CAYAAADNNiA5AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAACJJREFUeNpi+P//fxgTAwPDBxDxD078RSX+YeEyDFMCIMAAI3INmXiwf2YAAAAASUVORK5CYII=");background-repeat: no-repeat, repeat-x;background-position: center center, top left;color: transparent;border: 1px solid black;border-radius: 2px;cursor: pointer;pointer-events: auto;}.ace_dark .ace_fold {}.ace_fold:hover{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABEAAAAJCAYAAADU6McMAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAJpJREFUeNpi/P//PwOlgAXGYGRklAVSokD8GmjwY1wasKljQpYACtpCFeADcHVQfQyMQAwzwAZI3wJKvCLkfKBaMSClBlR7BOQikCFGQEErIH0VqkabiGCAqwUadAzZJRxQr/0gwiXIal8zQQPnNVTgJ1TdawL0T5gBIP1MUJNhBv2HKoQHHjqNrA4WO4zY0glyNKLT2KIfIMAAQsdgGiXvgnYAAAAASUVORK5CYII="),url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAA3CAYAAADNNiA5AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAACBJREFUeNpi+P//fz4TAwPDZxDxD5X4i5fLMEwJgAADAEPVDbjNw87ZAAAAAElFTkSuQmCC");}.ace_tooltip {background-color: #FFF;background-image: -webkit-linear-gradient(top, transparent, rgba(0, 0, 0, 0.1));background-image: linear-gradient(to bottom, transparent, rgba(0, 0, 0, 0.1));border: 1px solid gray;border-radius: 1px;box-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);color: black;max-width: 100%;padding: 3px 4px;position: fixed;z-index: 999999;-moz-box-sizing: border-box;-webkit-box-sizing: border-box;box-sizing: border-box;cursor: default;white-space: pre;word-wrap: break-word;line-height: normal;font-style: normal;font-weight: normal;letter-spacing: normal;pointer-events: none;}.ace_folding-enabled > .ace_gutter-cell {padding-right: 13px;}.ace_fold-widget {-moz-box-sizing: border-box;-webkit-box-sizing: border-box;box-sizing: border-box;margin: 0 -12px 0 1px;display: none;width: 11px;vertical-align: top;background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAANElEQVR42mWKsQ0AMAzC8ixLlrzQjzmBiEjp0A6WwBCSPgKAXoLkqSot7nN3yMwR7pZ32NzpKkVoDBUxKAAAAABJRU5ErkJggg==");background-repeat: no-repeat;background-position: center;border-radius: 3px;border: 1px solid transparent;cursor: pointer;}.ace_folding-enabled .ace_fold-widget {display: inline-block; }.ace_fold-widget.ace_end {background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAANElEQVR42m3HwQkAMAhD0YzsRchFKI7sAikeWkrxwScEB0nh5e7KTPWimZki4tYfVbX+MNl4pyZXejUO1QAAAABJRU5ErkJggg==");}.ace_fold-widget.ace_closed {background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAGCAYAAAAG5SQMAAAAOUlEQVR42jXKwQkAMAgDwKwqKD4EwQ26sSOkVWjgIIHAzPiCgaqiqnJHZnKICBERHN194O5b9vbLuAVRL+l0YWnZAAAAAElFTkSuQmCCXA==");}.ace_fold-widget:hover {border: 1px solid rgba(0, 0, 0, 0.3);background-color: rgba(255, 255, 255, 0.2);box-shadow: 0 1px 1px rgba(255, 255, 255, 0.7);}.ace_fold-widget:active {border: 1px solid rgba(0, 0, 0, 0.4);background-color: rgba(0, 0, 0, 0.05);box-shadow: 0 1px 1px rgba(255, 255, 255, 0.8);}.ace_dark .ace_fold-widget {background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHklEQVQIW2P4//8/AzoGEQ7oGCaLLAhWiSwB146BAQCSTPYocqT0AAAAAElFTkSuQmCC");}.ace_dark .ace_fold-widget.ace_end {background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAH0lEQVQIW2P4//8/AxQ7wNjIAjDMgC4AxjCVKBirIAAF0kz2rlhxpAAAAABJRU5ErkJggg==");}.ace_dark .ace_fold-widget.ace_closed {background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAFCAYAAACAcVaiAAAAHElEQVQIW2P4//+/AxAzgDADlOOAznHAKgPWAwARji8UIDTfQQAAAABJRU5ErkJggg==");}.ace_dark .ace_fold-widget:hover {box-shadow: 0 1px 1px rgba(255, 255, 255, 0.2);background-color: rgba(255, 255, 255, 0.1);}.ace_dark .ace_fold-widget:active {box-shadow: 0 1px 1px rgba(255, 255, 255, 0.2);}.ace_fold-widget.ace_invalid {background-color: #FFB4B4;border-color: #DE5555;}.ace_fade-fold-widgets .ace_fold-widget {-webkit-transition: opacity 0.4s ease 0.05s;transition: opacity 0.4s ease 0.05s;opacity: 0;}.ace_fade-fold-widgets:hover .ace_fold-widget {-webkit-transition: opacity 0.05s ease 0.05s;transition: opacity 0.05s ease 0.05s;opacity:1;}.ace_underline {text-decoration: underline;}.ace_bold {font-weight: bold;}.ace_nobold .ace_bold {font-weight: normal;}.ace_italic {font-style: italic;}.ace_error-marker {background-color: rgba(255, 0, 0,0.2);position: absolute;z-index: 9;}.ace_highlight-marker {background-color: rgba(255, 255, 0,0.2);position: absolute;z-index: 8;}.ace_br1 {border-top-left-radius : 3px;}.ace_br2 {border-top-right-radius : 3px;}.ace_br3 {border-top-left-radius : 3px; border-top-right-radius: 3px;}.ace_br4 {border-bottom-right-radius: 3px;}.ace_br5 {border-top-left-radius : 3px; border-bottom-right-radius: 3px;}.ace_br6 {border-top-right-radius : 3px; border-bottom-right-radius: 3px;}.ace_br7 {border-top-left-radius : 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px;}.ace_br8 {border-bottom-left-radius : 3px;}.ace_br9 {border-top-left-radius : 3px; border-bottom-left-radius: 3px;}.ace_br10{border-top-right-radius : 3px; border-bottom-left-radius: 3px;}.ace_br11{border-top-left-radius : 3px; border-top-right-radius: 3px; border-bottom-left-radius: 3px;}.ace_br12{border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;}.ace_br13{border-top-left-radius : 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;}.ace_br14{border-top-right-radius : 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;}.ace_br15{border-top-left-radius : 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;}';i.importCssString(m,"ace_editor.css");var g=function(e,t){var n=this;this.container=e||i.createElement("div"),this.$keepTextAreaAtCursor=!o.isOldIE,i.addCssClass(this.container,"ace_editor"),this.setTheme(t),this.$gutter=i.createElement("div"),this.$gutter.className="ace_gutter",this.container.appendChild(this.$gutter),this.scroller=i.createElement("div"),this.scroller.className="ace_scroller",this.container.appendChild(this.scroller),this.content=i.createElement("div"),this.content.className="ace_content",this.scroller.appendChild(this.content),this.$gutterLayer=new u(this.$gutter),this.$gutterLayer.on("changeGutterWidth",this.onGutterResize.bind(this)),this.$markerBack=new a(this.content);var r=this.$textLayer=new f(this.content);this.canvas=r.element,this.$markerFront=new a(this.content),this.$cursorLayer=new l(this.content),this.$horizScroll=!1,this.$vScroll=!1,this.scrollBar=this.scrollBarV=new h(this.container,this),this.scrollBarH=new c(this.container,this),this.scrollBarV.addEventListener("scroll",function(e){n.$scrollAnimation||n.session.setScrollTop(e.data-n.scrollMargin.top)}),this.scrollBarH.addEventListener("scroll",function(e){n.$scrollAnimation||n.session.setScrollLeft(e.data-n.scrollMargin.left)}),this.scrollTop=0,this.scrollLeft=0,this.cursorPos={row:0,column:0},this.$fontMetrics=new d(this.container),this.$textLayer.$setFontMetrics(this.$fontMetrics),this.$textLayer.addEventListener("changeCharacterSize",function(e){n.updateCharacterSize(),n.onResize(!0,n.gutterWidth,n.$size.width,n.$size.height),n._signal("changeCharacterSize",e)}),this.$size={width:0,height:0,scrollerHeight:0,scrollerWidth:0,$dirty:!0},this.layerConfig={width:1,padding:0,firstRow:0,firstRowScreen:0,lastRow:0,lineHeight:0,characterWidth:0,minHeight:1,maxHeight:1,offset:0,height:1,gutterOffset:1},this.scrollMargin={left:0,right:0,top:0,bottom:0,v:0,h:0},this.$loop=new p(this.$renderChanges.bind(this),this.container.ownerDocument.defaultView),this.$loop.schedule(this.CHANGE_FULL),this.updateCharacterSize(),this.setPadding(4),s.resetOptions(this),s._emit("renderer",this)};(function(){this.CHANGE_CURSOR=1,this.CHANGE_MARKER=2,this.CHANGE_GUTTER=4,this.CHANGE_SCROLL=8,this.CHANGE_LINES=16,this.CHANGE_TEXT=32,this.CHANGE_SIZE=64,this.CHANGE_MARKER_BACK=128,this.CHANGE_MARKER_FRONT=256,this.CHANGE_FULL=512,this.CHANGE_H_SCROLL=1024,r.implement(this,v),this.updateCharacterSize=function(){this.$textLayer.allowBoldFonts!=this.$allowBoldFonts&&(this.$allowBoldFonts=this.$textLayer.allowBoldFonts,this.setStyle("ace_nobold",!this.$allowBoldFonts)),this.layerConfig.characterWidth=this.characterWidth=this.$textLayer.getCharacterWidth(),this.layerConfig.lineHeight=this.lineHeight=this.$textLayer.getLineHeight(),this.$updatePrintMargin()},this.setSession=function(e){this.session&&this.session.doc.off("changeNewLineMode",this.onChangeNewLineMode),this.session=e,e&&this.scrollMargin.top&&e.getScrollTop()<=0&&e.setScrollTop(-this.scrollMargin.top),this.$cursorLayer.setSession(e),this.$markerBack.setSession(e),this.$markerFront.setSession(e),this.$gutterLayer.setSession(e),this.$textLayer.setSession(e);if(!e)return;this.$loop.schedule(this.CHANGE_FULL),this.session.$setFontMetrics(this.$fontMetrics),this.scrollBarV.scrollLeft=this.scrollBarV.scrollTop=null,this.onChangeNewLineMode=this.onChangeNewLineMode.bind(this),this.onChangeNewLineMode(),this.session.doc.on("changeNewLineMode",this.onChangeNewLineMode)},this.updateLines=function(e,t,n){t===undefined&&(t=Infinity),this.$changedLines?(this.$changedLines.firstRow>e&&(this.$changedLines.firstRow=e),this.$changedLines.lastRowthis.layerConfig.lastRow)return;this.$loop.schedule(this.CHANGE_LINES)},this.onChangeNewLineMode=function(){this.$loop.schedule(this.CHANGE_TEXT),this.$textLayer.$updateEolChar()},this.onChangeTabSize=function(){this.$loop.schedule(this.CHANGE_TEXT|this.CHANGE_MARKER),this.$textLayer.onChangeTabSize()},this.updateText=function(){this.$loop.schedule(this.CHANGE_TEXT)},this.updateFull=function(e){e?this.$renderChanges(this.CHANGE_FULL,!0):this.$loop.schedule(this.CHANGE_FULL)},this.updateFontSize=function(){this.$textLayer.checkForSizeChanges()},this.$changes=0,this.$updateSizeAsync=function(){this.$loop.pending?this.$size.$dirty=!0:this.onResize()},this.onResize=function(e,t,n,r){if(this.resizing>2)return;this.resizing>0?this.resizing++:this.resizing=e?1:0;var i=this.container;r||(r=i.clientHeight||i.scrollHeight),n||(n=i.clientWidth||i.scrollWidth);var s=this.$updateCachedSize(e,t,n,r);if(!this.$size.scrollerHeight||!n&&!r)return this.resizing=0;e&&(this.$gutterLayer.$padding=null),e?this.$renderChanges(s|this.$changes,!0):this.$loop.schedule(s|this.$changes),this.resizing&&(this.resizing=0),this.scrollBarV.scrollLeft=this.scrollBarV.scrollTop=null},this.$updateCachedSize=function(e,t,n,r){r-=this.$extraHeight||0;var i=0,s=this.$size,o={width:s.width,height:s.height,scrollerHeight:s.scrollerHeight,scrollerWidth:s.scrollerWidth};r&&(e||s.height!=r)&&(s.height=r,i|=this.CHANGE_SIZE,s.scrollerHeight=s.height,this.$horizScroll&&(s.scrollerHeight-=this.scrollBarH.getHeight()),this.scrollBarV.element.style.bottom=this.scrollBarH.getHeight()+"px",i|=this.CHANGE_SCROLL);if(n&&(e||s.width!=n)){i|=this.CHANGE_SIZE,s.width=n,t==null&&(t=this.$showGutter?this.$gutter.offsetWidth:0),this.gutterWidth=t,this.scrollBarH.element.style.left=this.scroller.style.left=t+"px",s.scrollerWidth=Math.max(0,n-t-this.scrollBarV.getWidth()),this.scrollBarH.element.style.right=this.scroller.style.right=this.scrollBarV.getWidth()+"px",this.scroller.style.bottom=this.scrollBarH.getHeight()+"px";if(this.session&&this.session.getUseWrapMode()&&this.adjustWrapLimit()||e)i|=this.CHANGE_FULL}return s.$dirty=!n||!r,i&&this._signal("resize",o),i},this.onGutterResize=function(){var e=this.$showGutter?this.$gutter.offsetWidth:0;e!=this.gutterWidth&&(this.$changes|=this.$updateCachedSize(!0,e,this.$size.width,this.$size.height)),this.session.getUseWrapMode()&&this.adjustWrapLimit()?this.$loop.schedule(this.CHANGE_FULL):this.$size.$dirty?this.$loop.schedule(this.CHANGE_FULL):(this.$computeLayerConfig(),this.$loop.schedule(this.CHANGE_MARKER))},this.adjustWrapLimit=function(){var e=this.$size.scrollerWidth-this.$padding*2,t=Math.floor(e/this.characterWidth);return this.session.adjustWrapLimit(t,this.$showPrintMargin&&this.$printMarginColumn)},this.setAnimatedScroll=function(e){this.setOption("animatedScroll",e)},this.getAnimatedScroll=function(){return this.$animatedScroll},this.setShowInvisibles=function(e){this.setOption("showInvisibles",e)},this.getShowInvisibles=function(){return this.getOption("showInvisibles")},this.getDisplayIndentGuides=function(){return this.getOption("displayIndentGuides")},this.setDisplayIndentGuides=function(e){this.setOption("displayIndentGuides",e)},this.setShowPrintMargin=function(e){this.setOption("showPrintMargin",e)},this.getShowPrintMargin=function(){return this.getOption("showPrintMargin")},this.setPrintMarginColumn=function(e){this.setOption("printMarginColumn",e)},this.getPrintMarginColumn=function(){return this.getOption("printMarginColumn")},this.getShowGutter=function(){return this.getOption("showGutter")},this.setShowGutter=function(e){return this.setOption("showGutter",e)},this.getFadeFoldWidgets=function(){return this.getOption("fadeFoldWidgets")},this.setFadeFoldWidgets=function(e){this.setOption("fadeFoldWidgets",e)},this.setHighlightGutterLine=function(e){this.setOption("highlightGutterLine",e)},this.getHighlightGutterLine=function(){return this.getOption("highlightGutterLine")},this.$updateGutterLineHighlight=function(){var e=this.$cursorLayer.$pixelPos,t=this.layerConfig.lineHeight;if(this.session.getUseWrapMode()){var n=this.session.selection.getCursor();n.column=0,e=this.$cursorLayer.getPixelPosition(n,!0),t*=this.session.getRowLength(n.row)}this.$gutterLineHighlight.style.top=e.top-this.layerConfig.offset+"px",this.$gutterLineHighlight.style.height=t+"px"},this.$updatePrintMargin=function(){if(!this.$showPrintMargin&&!this.$printMarginEl)return;if(!this.$printMarginEl){var e=i.createElement("div");e.className="ace_layer ace_print-margin-layer",this.$printMarginEl=i.createElement("div"),this.$printMarginEl.className="ace_print-margin",e.appendChild(this.$printMarginEl),this.content.insertBefore(e,this.content.firstChild)}var t=this.$printMarginEl.style;t.left=this.characterWidth*this.$printMarginColumn+this.$padding+"px",t.visibility=this.$showPrintMargin?"visible":"hidden",this.session&&this.session.$wrap==-1&&this.adjustWrapLimit()},this.getContainerElement=function(){return this.container},this.getMouseEventTarget=function(){return this.scroller},this.getTextAreaContainer=function(){return this.container},this.$moveTextAreaToCursor=function(){if(!this.$keepTextAreaAtCursor)return;var e=this.layerConfig,t=this.$cursorLayer.$pixelPos.top,n=this.$cursorLayer.$pixelPos.left;t-=e.offset;var r=this.textarea.style,i=this.lineHeight;if(t<0||t>e.height-i){r.top=r.left="0";return}var s=this.characterWidth;if(this.$composition){var o=this.textarea.value.replace(/^\x01+/,"");s*=this.session.$getStringScreenWidth(o)[0]+2,i+=2}n-=this.scrollLeft,n>this.$size.scrollerWidth-s&&(n=this.$size.scrollerWidth-s),n+=this.gutterWidth,r.height=i+"px",r.width=s+"px",r.left=Math.min(n,this.$size.scrollerWidth-s)+"px",r.top=Math.min(t,this.$size.height-i)+"px"},this.getFirstVisibleRow=function(){return this.layerConfig.firstRow},this.getFirstFullyVisibleRow=function(){return this.layerConfig.firstRow+(this.layerConfig.offset===0?0:1)},this.getLastFullyVisibleRow=function(){var e=this.layerConfig,t=e.lastRow,n=this.session.documentToScreenRow(t,0)*e.lineHeight;return n-this.session.getScrollTop()>e.height-e.lineHeight?t-1:t},this.getLastVisibleRow=function(){return this.layerConfig.lastRow},this.$padding=null,this.setPadding=function(e){this.$padding=e,this.$textLayer.setPadding(e),this.$cursorLayer.setPadding(e),this.$markerFront.setPadding(e),this.$markerBack.setPadding(e),this.$loop.schedule(this.CHANGE_FULL),this.$updatePrintMargin()},this.setScrollMargin=function(e,t,n,r){var i=this.scrollMargin;i.top=e|0,i.bottom=t|0,i.right=r|0,i.left=n|0,i.v=i.top+i.bottom,i.h=i.left+i.right,i.top&&this.scrollTop<=0&&this.session&&this.session.setScrollTop(-i.top),this.updateFull()},this.getHScrollBarAlwaysVisible=function(){return this.$hScrollBarAlwaysVisible},this.setHScrollBarAlwaysVisible=function(e){this.setOption("hScrollBarAlwaysVisible",e)},this.getVScrollBarAlwaysVisible=function(){return this.$vScrollBarAlwaysVisible},this.setVScrollBarAlwaysVisible=function(e){this.setOption("vScrollBarAlwaysVisible",e)},this.$updateScrollBarV=function(){var e=this.layerConfig.maxHeight,t=this.$size.scrollerHeight;!this.$maxLines&&this.$scrollPastEnd&&(e-=(t-this.lineHeight)*this.$scrollPastEnd,this.scrollTop>e-t&&(e=this.scrollTop+t,this.scrollBarV.scrollTop=null)),this.scrollBarV.setScrollHeight(e+this.scrollMargin.v),this.scrollBarV.setScrollTop(this.scrollTop+this.scrollMargin.top)},this.$updateScrollBarH=function(){this.scrollBarH.setScrollWidth(this.layerConfig.width+2*this.$padding+this.scrollMargin.h),this.scrollBarH.setScrollLeft(this.scrollLeft+this.scrollMargin.left)},this.$frozen=!1,this.freeze=function(){this.$frozen=!0},this.unfreeze=function(){this.$frozen=!1},this.$renderChanges=function(e,t){this.$changes&&(e|=this.$changes,this.$changes=0);if(!this.session||!this.container.offsetWidth||this.$frozen||!e&&!t){this.$changes|=e;return}if(this.$size.$dirty)return this.$changes|=e,this.onResize(!0);this.lineHeight||this.$textLayer.checkForSizeChanges(),this._signal("beforeRender");var n=this.layerConfig;if(e&this.CHANGE_FULL||e&this.CHANGE_SIZE||e&this.CHANGE_TEXT||e&this.CHANGE_LINES||e&this.CHANGE_SCROLL||e&this.CHANGE_H_SCROLL){e|=this.$computeLayerConfig();if(n.firstRow!=this.layerConfig.firstRow&&n.firstRowScreen==this.layerConfig.firstRowScreen){var r=this.scrollTop+(n.firstRow-this.layerConfig.firstRow)*this.lineHeight;r>0&&(this.scrollTop=r,e|=this.CHANGE_SCROLL,e|=this.$computeLayerConfig())}n=this.layerConfig,this.$updateScrollBarV(),e&this.CHANGE_H_SCROLL&&this.$updateScrollBarH(),this.$gutterLayer.element.style.marginTop=-n.offset+"px",this.content.style.marginTop=-n.offset+"px",this.content.style.width=n.width+2*this.$padding+"px",this.content.style.height=n.minHeight+"px"}e&this.CHANGE_H_SCROLL&&(this.content.style.marginLeft=-this.scrollLeft+"px",this.scroller.className=this.scrollLeft<=0?"ace_scroller":"ace_scroller ace_scroll-left");if(e&this.CHANGE_FULL){this.$textLayer.update(n),this.$showGutter&&this.$gutterLayer.update(n),this.$markerBack.update(n),this.$markerFront.update(n),this.$cursorLayer.update(n),this.$moveTextAreaToCursor(),this.$highlightGutterLine&&this.$updateGutterLineHighlight(),this._signal("afterRender");return}if(e&this.CHANGE_SCROLL){e&this.CHANGE_TEXT||e&this.CHANGE_LINES?this.$textLayer.update(n):this.$textLayer.scrollLines(n),this.$showGutter&&this.$gutterLayer.update(n),this.$markerBack.update(n),this.$markerFront.update(n),this.$cursorLayer.update(n),this.$highlightGutterLine&&this.$updateGutterLineHighlight(),this.$moveTextAreaToCursor(),this._signal("afterRender");return}e&this.CHANGE_TEXT?(this.$textLayer.update(n),this.$showGutter&&this.$gutterLayer.update(n)):e&this.CHANGE_LINES?(this.$updateLines()||e&this.CHANGE_GUTTER&&this.$showGutter)&&this.$gutterLayer.update(n):(e&this.CHANGE_TEXT||e&this.CHANGE_GUTTER)&&this.$showGutter&&this.$gutterLayer.update(n),e&this.CHANGE_CURSOR&&(this.$cursorLayer.update(n),this.$moveTextAreaToCursor(),this.$highlightGutterLine&&this.$updateGutterLineHighlight()),e&(this.CHANGE_MARKER|this.CHANGE_MARKER_FRONT)&&this.$markerFront.update(n),e&(this.CHANGE_MARKER|this.CHANGE_MARKER_BACK)&&this.$markerBack.update(n),this._signal("afterRender")},this.$autosize=function(){var e=this.session.getScreenLength()*this.lineHeight,t=this.$maxLines*this.lineHeight,n=Math.min(t,Math.max((this.$minLines||1)*this.lineHeight,e))+this.scrollMargin.v+(this.$extraHeight||0);this.$horizScroll&&(n+=this.scrollBarH.getHeight()),this.$maxPixelHeight&&n>this.$maxPixelHeight&&(n=this.$maxPixelHeight);var r=e>t;if(n!=this.desiredHeight||this.$size.height!=this.desiredHeight||r!=this.$vScroll){r!=this.$vScroll&&(this.$vScroll=r,this.scrollBarV.setVisible(r));var i=this.container.clientWidth;this.container.style.height=n+"px",this.$updateCachedSize(!0,this.$gutterWidth,i,n),this.desiredHeight=n,this._signal("autosize")}},this.$computeLayerConfig=function(){var e=this.session,t=this.$size,n=t.height<=2*this.lineHeight,r=this.session.getScreenLength(),i=r*this.lineHeight,s=this.$getLongestLine(),o=!n&&(this.$hScrollBarAlwaysVisible||t.scrollerWidth-s-2*this.$padding<0),u=this.$horizScroll!==o;u&&(this.$horizScroll=o,this.scrollBarH.setVisible(o));var a=this.$vScroll;this.$maxLines&&this.lineHeight>1&&this.$autosize();var f=this.scrollTop%this.lineHeight,l=t.scrollerHeight+this.lineHeight,c=!this.$maxLines&&this.$scrollPastEnd?(t.scrollerHeight-this.lineHeight)*this.$scrollPastEnd:0;i+=c;var h=this.scrollMargin;this.session.setScrollTop(Math.max(-h.top,Math.min(this.scrollTop,i-t.scrollerHeight+h.bottom))),this.session.setScrollLeft(Math.max(-h.left,Math.min(this.scrollLeft,s+2*this.$padding-t.scrollerWidth+h.right)));var p=!n&&(this.$vScrollBarAlwaysVisible||t.scrollerHeight-i+c<0||this.scrollTop>h.top),d=a!==p;d&&(this.$vScroll=p,this.scrollBarV.setVisible(p));var v=Math.ceil(l/this.lineHeight)-1,m=Math.max(0,Math.round((this.scrollTop-f)/this.lineHeight)),g=m+v,y,b,w=this.lineHeight;m=e.screenToDocumentRow(m,0);var E=e.getFoldLine(m);E&&(m=E.start.row),y=e.documentToScreenRow(m,0),b=e.getRowLength(m)*w,g=Math.min(e.screenToDocumentRow(g,0),e.getLength()-1),l=t.scrollerHeight+e.getRowLength(g)*w+b,f=this.scrollTop-y*w;var S=0;this.layerConfig.width!=s&&(S=this.CHANGE_H_SCROLL);if(u||d)S=this.$updateCachedSize(!0,this.gutterWidth,t.width,t.height),this._signal("scrollbarVisibilityChanged"),d&&(s=this.$getLongestLine());return this.layerConfig={width:s,padding:this.$padding,firstRow:m,firstRowScreen:y,lastRow:g,lineHeight:w,characterWidth:this.characterWidth,minHeight:l,maxHeight:i,offset:f,gutterOffset:w?Math.max(0,Math.ceil((f+t.height-t.scrollerHeight)/w)):0,height:this.$size.scrollerHeight},S},this.$updateLines=function(){var e=this.$changedLines.firstRow,t=this.$changedLines.lastRow;this.$changedLines=null;var n=this.layerConfig;if(e>n.lastRow+1)return;if(ts?(t&&a+o>s+this.lineHeight&&(s-=t*this.$size.scrollerHeight),s===0&&(s=-this.scrollMargin.top),this.session.setScrollTop(s)):a+this.$size.scrollerHeight-ui?(i=1-this.scrollMargin.top)return!0;if(t>0&&this.session.getScrollTop()+this.$size.scrollerHeight-this.layerConfig.maxHeight<-1+this.scrollMargin.bottom)return!0;if(e<0&&this.session.getScrollLeft()>=1-this.scrollMargin.left)return!0;if(e>0&&this.session.getScrollLeft()+this.$size.scrollerWidth-this.layerConfig.width<-1+this.scrollMargin.right)return!0},this.pixelToScreenCoordinates=function(e,t){var n=this.scroller.getBoundingClientRect(),r=(e+this.scrollLeft-n.left-this.$padding)/this.characterWidth,i=Math.floor((t+this.scrollTop-n.top)/this.lineHeight),s=Math.round(r);return{row:i,column:s,side:r-s>0?1:-1}},this.screenToTextCoordinates=function(e,t){var n=this.scroller.getBoundingClientRect(),r=Math.round((e+this.scrollLeft-n.left-this.$padding)/this.characterWidth),i=(t+this.scrollTop-n.top)/this.lineHeight;return this.session.screenToDocumentPosition(i,Math.max(r,0))},this.textToScreenCoordinates=function(e,t){var n=this.scroller.getBoundingClientRect(),r=this.session.documentToScreenPosition(e,t),i=this.$padding+Math.round(r.column*this.characterWidth),s=r.row*this.lineHeight;return{pageX:n.left+i-this.scrollLeft,pageY:n.top+s-this.scrollTop}},this.visualizeFocus=function(){i.addCssClass(this.container,"ace_focus")},this.visualizeBlur=function(){i.removeCssClass(this.container,"ace_focus")},this.showComposition=function(e){this.$composition||(this.$composition={keepTextAreaAtCursor:this.$keepTextAreaAtCursor,cssText:this.textarea.style.cssText}),this.$keepTextAreaAtCursor=!0,i.addCssClass(this.textarea,"ace_composition"),this.textarea.style.cssText="",this.$moveTextAreaToCursor()},this.setCompositionText=function(e){this.$moveTextAreaToCursor()},this.hideComposition=function(){if(!this.$composition)return;i.removeCssClass(this.textarea,"ace_composition"),this.$keepTextAreaAtCursor=this.$composition.keepTextAreaAtCursor,this.textarea.style.cssText=this.$composition.cssText,this.$composition=null},this.setTheme=function(e,t){function o(r){if(n.$themeId!=e)return t&&t();if(!r||!r.cssClass)throw new Error("couldn't load module "+e+" or it didn't call define");i.importCssString(r.cssText,r.cssClass,n.container.ownerDocument),n.theme&&i.removeCssClass(n.container,n.theme.cssClass);var s="padding"in r?r.padding:"padding"in(n.theme||{})?4:n.$padding;n.$padding&&s!=n.$padding&&n.setPadding(s),n.$theme=r.cssClass,n.theme=r,i.addCssClass(n.container,r.cssClass),i.setCssClass(n.container,"ace_dark",r.isDark),n.$size&&(n.$size.width=0,n.$updateSizeAsync()),n._dispatchEvent("themeLoaded",{theme:r}),t&&t()}var n=this;this.$themeId=e,n._dispatchEvent("themeChange",{theme:e});if(!e||typeof e=="string"){var r=e||this.$options.theme.initialValue;s.loadModule(["theme",r],o)}else o(e)},this.getTheme=function(){return this.$themeId},this.setStyle=function(e,t){i.setCssClass(this.container,e,t!==!1)},this.unsetStyle=function(e){i.removeCssClass(this.container,e)},this.setCursorStyle=function(e){this.scroller.style.cursor!=e&&(this.scroller.style.cursor=e)},this.setMouseCursor=function(e){this.scroller.style.cursor=e},this.destroy=function(){this.$textLayer.destroy(),this.$cursorLayer.destroy()}}).call(g.prototype),s.defineOptions(g.prototype,"renderer",{animatedScroll:{initialValue:!1},showInvisibles:{set:function(e){this.$textLayer.setShowInvisibles(e)&&this.$loop.schedule(this.CHANGE_TEXT)},initialValue:!1},showPrintMargin:{set:function(){this.$updatePrintMargin()},initialValue:!0},printMarginColumn:{set:function(){this.$updatePrintMargin()},initialValue:80},printMargin:{set:function(e){typeof e=="number"&&(this.$printMarginColumn=e),this.$showPrintMargin=!!e,this.$updatePrintMargin()},get:function(){return this.$showPrintMargin&&this.$printMarginColumn}},showGutter:{set:function(e){this.$gutter.style.display=e?"block":"none",this.$loop.schedule(this.CHANGE_FULL),this.onGutterResize()},initialValue:!0},fadeFoldWidgets:{set:function(e){i.setCssClass(this.$gutter,"ace_fade-fold-widgets",e)},initialValue:!1},showFoldWidgets:{set:function(e){this.$gutterLayer.setShowFoldWidgets(e)},initialValue:!0},showLineNumbers:{set:function(e){this.$gutterLayer.setShowLineNumbers(e),this.$loop.schedule(this.CHANGE_GUTTER)},initialValue:!0},displayIndentGuides:{set:function(e){this.$textLayer.setDisplayIndentGuides(e)&&this.$loop.schedule(this.CHANGE_TEXT)},initialValue:!0},highlightGutterLine:{set:function(e){if(!this.$gutterLineHighlight){this.$gutterLineHighlight=i.createElement("div"),this.$gutterLineHighlight.className="ace_gutter-active-line",this.$gutter.appendChild(this.$gutterLineHighlight);return}this.$gutterLineHighlight.style.display=e?"":"none",this.$cursorLayer.$pixelPos&&this.$updateGutterLineHighlight()},initialValue:!1,value:!0},hScrollBarAlwaysVisible:{set:function(e){(!this.$hScrollBarAlwaysVisible||!this.$horizScroll)&&this.$loop.schedule(this.CHANGE_SCROLL)},initialValue:!1},vScrollBarAlwaysVisible:{set:function(e){(!this.$vScrollBarAlwaysVisible||!this.$vScroll)&&this.$loop.schedule(this.CHANGE_SCROLL)},initialValue:!1},fontSize:{set:function(e){typeof e=="number"&&(e+="px"),this.container.style.fontSize=e,this.updateFontSize()},initialValue:12},fontFamily:{set:function(e){this.container.style.fontFamily=e,this.updateFontSize()}},maxLines:{set:function(e){this.updateFull()}},minLines:{set:function(e){this.updateFull()}},maxPixelHeight:{set:function(e){this.updateFull()},initialValue:0},scrollPastEnd:{set:function(e){e=+e||0;if(this.$scrollPastEnd==e)return;this.$scrollPastEnd=e,this.$loop.schedule(this.CHANGE_SCROLL)},initialValue:0,handlesSet:!0},fixedWidthGutter:{set:function(e){this.$gutterLayer.$fixedWidth=!!e,this.$loop.schedule(this.CHANGE_GUTTER)}},theme:{set:function(e){this.setTheme(e)},get:function(){return this.$themeId||this.theme},initialValue:"./theme/textmate",handlesSet:!0}}),t.VirtualRenderer=g}),define("ace/worker/worker_client",["require","exports","module","ace/lib/oop","ace/lib/net","ace/lib/event_emitter","ace/config"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/net"),s=e("../lib/event_emitter").EventEmitter,o=e("../config"),u=function(t,n,r,i){this.$sendDeltaQueue=this.$sendDeltaQueue.bind(this),this.changeListener=this.changeListener.bind(this),this.onMessage=this.onMessage.bind(this),e.nameToUrl&&!e.toUrl&&(e.toUrl=e.nameToUrl);if(o.get("packaged")||!e.toUrl)i=i||o.moduleUrl(n,"worker");else{var s=this.$normalizePath;i=i||s(e.toUrl("ace/worker/worker.js",null,"_"));var u={};t.forEach(function(t){u[t]=s(e.toUrl(t,null,"_").replace(/(\.js)?(\?.*)?$/,""))})}try{this.$worker=new Worker(i)}catch(a){if(!(a instanceof window.DOMException))throw a;var f=this.$workerBlob(i),l=window.URL||window.webkitURL,c=l.createObjectURL(f);this.$worker=new Worker(c),l.revokeObjectURL(c)}this.$worker.postMessage({init:!0,tlns:u,module:n,classname:r}),this.callbackId=1,this.callbacks={},this.$worker.onmessage=this.onMessage};(function(){r.implement(this,s),this.onMessage=function(e){var t=e.data;switch(t.type){case"event":this._signal(t.name,{data:t.data});break;case"call":var n=this.callbacks[t.id];n&&(n(t.data),delete this.callbacks[t.id]);break;case"error":this.reportError(t.data);break;case"log":window.console&&console.log&&console.log.apply(console,t.data)}},this.reportError=function(e){window.console&&console.error&&console.error(e)},this.$normalizePath=function(e){return i.qualifyURL(e)},this.terminate=function(){this._signal("terminate",{}),this.deltaQueue=null,this.$worker.terminate(),this.$worker=null,this.$doc&&this.$doc.off("change",this.changeListener),this.$doc=null},this.send=function(e,t){this.$worker.postMessage({command:e,args:t})},this.call=function(e,t,n){if(n){var r=this.callbackId++;this.callbacks[r]=n,t.push(r)}this.send(e,t)},this.emit=function(e,t){try{this.$worker.postMessage({event:e,data:{data:t.data}})}catch(n){console.error(n.stack)}},this.attachToDocument=function(e){this.$doc&&this.terminate(),this.$doc=e,this.call("setValue",[e.getValue()]),e.on("change",this.changeListener)},this.changeListener=function(e){this.deltaQueue||(this.deltaQueue=[],setTimeout(this.$sendDeltaQueue,0)),e.action=="insert"?this.deltaQueue.push(e.start,e.lines):this.deltaQueue.push(e.start,e.end)},this.$sendDeltaQueue=function(){var e=this.deltaQueue;if(!e)return;this.deltaQueue=null,e.length>50&&e.length>this.$doc.getLength()>>1?this.call("setValue",[this.$doc.getValue()]):this.emit("change",{data:e})},this.$workerBlob=function(e){var t="importScripts('"+i.qualifyURL(e)+"');";try{return new Blob([t],{type:"application/javascript"})}catch(n){var r=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder,s=new r;return s.append(t),s.getBlob("application/javascript")}}}).call(u.prototype);var a=function(e,t,n){this.$sendDeltaQueue=this.$sendDeltaQueue.bind(this),this.changeListener=this.changeListener.bind(this),this.callbackId=1,this.callbacks={},this.messageBuffer=[];var r=null,i=!1,u=Object.create(s),a=this;this.$worker={},this.$worker.terminate=function(){},this.$worker.postMessage=function(e){a.messageBuffer.push(e),r&&(i?setTimeout(f):f())},this.setEmitSync=function(e){i=e};var f=function(){var e=a.messageBuffer.shift();e.command?r[e.command].apply(r,e.args):e.event&&u._signal(e.event,e.data)};u.postMessage=function(e){a.onMessage({data:e})},u.callback=function(e,t){this.postMessage({type:"call",id:t,data:e})},u.emit=function(e,t){this.postMessage({type:"event",name:e,data:t})},o.loadModule(["worker",t],function(e){r=new e[n](u);while(a.messageBuffer.length)f()})};a.prototype=u.prototype,t.UIWorkerClient=a,t.WorkerClient=u}),define("ace/placeholder",["require","exports","module","ace/range","ace/lib/event_emitter","ace/lib/oop"],function(e,t,n){"use strict";var r=e("./range").Range,i=e("./lib/event_emitter").EventEmitter,s=e("./lib/oop"),o=function(e,t,n,r,i,s){var o=this;this.length=t,this.session=e,this.doc=e.getDocument(),this.mainClass=i,this.othersClass=s,this.$onUpdate=this.onUpdate.bind(this),this.doc.on("change",this.$onUpdate),this.$others=r,this.$onCursorChange=function(){setTimeout(function(){o.onCursorChange()})},this.$pos=n;var u=e.getUndoManager().$undoStack||e.getUndoManager().$undostack||{length:-1};this.$undoStackDepth=u.length,this.setup(),e.selection.on("changeCursor",this.$onCursorChange)};(function(){s.implement(this,i),this.setup=function(){var e=this,t=this.doc,n=this.session;this.selectionBefore=n.selection.toJSON(),n.selection.inMultiSelectMode&&n.selection.toSingleRange(),this.pos=t.createAnchor(this.$pos.row,this.$pos.column);var i=this.pos;i.$insertRight=!0,i.detach(),i.markerId=n.addMarker(new r(i.row,i.column,i.row,i.column+this.length),this.mainClass,null,!1),this.others=[],this.$others.forEach(function(n){var r=t.createAnchor(n.row,n.column);r.$insertRight=!0,r.detach(),e.others.push(r)}),n.setUndoSelect(!1)},this.showOtherMarkers=function(){if(this.othersActive)return;var e=this.session,t=this;this.othersActive=!0,this.others.forEach(function(n){n.markerId=e.addMarker(new r(n.row,n.column,n.row,n.column+t.length),t.othersClass,null,!1)})},this.hideOtherMarkers=function(){if(!this.othersActive)return;this.othersActive=!1;for(var e=0;e=this.pos.column&&t.start.column<=this.pos.column+this.length+1,s=t.start.column-this.pos.column;this.updateAnchors(e),i&&(this.length+=n);if(i&&!this.session.$fromUndo)if(e.action==="insert")for(var o=this.others.length-1;o>=0;o--){var u=this.others[o],a={row:u.row,column:u.column+s};this.doc.insertMergedLines(a,e.lines)}else if(e.action==="remove")for(var o=this.others.length-1;o>=0;o--){var u=this.others[o],a={row:u.row,column:u.column+s};this.doc.remove(new r(a.row,a.column,a.row,a.column-n))}this.$updating=!1,this.updateMarkers()},this.updateAnchors=function(e){this.pos.onChange(e);for(var t=this.others.length;t--;)this.others[t].onChange(e);this.updateMarkers()},this.updateMarkers=function(){if(this.$updating)return;var e=this,t=this.session,n=function(n,i){t.removeMarker(n.markerId),n.markerId=t.addMarker(new r(n.row,n.column,n.row,n.column+e.length),i,null,!1)};n(this.pos,this.mainClass);for(var i=this.others.length;i--;)n(this.others[i],this.othersClass)},this.onCursorChange=function(e){if(this.$updating||!this.session)return;var t=this.session.selection.getCursor();t.row===this.pos.row&&t.column>=this.pos.column&&t.column<=this.pos.column+this.length?(this.showOtherMarkers(),this._emit("cursorEnter",e)):(this.hideOtherMarkers(),this._emit("cursorLeave",e))},this.detach=function(){this.session.removeMarker(this.pos&&this.pos.markerId),this.hideOtherMarkers(),this.doc.removeEventListener("change",this.$onUpdate),this.session.selection.removeEventListener("changeCursor",this.$onCursorChange),this.session.setUndoSelect(!0),this.session=null},this.cancel=function(){if(this.$undoStackDepth===-1)return;var e=this.session.getUndoManager(),t=(e.$undoStack||e.$undostack).length-this.$undoStackDepth;for(var n=0;n1&&!this.inMultiSelectMode&&(this._signal("multiSelect"),this.inMultiSelectMode=!0,this.session.$undoSelect=!1,this.rangeList.attach(this.session)),t||this.fromOrientedRange(e)},this.toSingleRange=function(e){e=e||this.ranges[0];var t=this.rangeList.removeAll();t.length&&this.$onRemoveRange(t),e&&this.fromOrientedRange(e)},this.substractPoint=function(e){var t=this.rangeList.substractPoint(e);if(t)return this.$onRemoveRange(t),t[0]},this.mergeOverlappingRanges=function(){var e=this.rangeList.merge();e.length?this.$onRemoveRange(e):this.ranges[0]&&this.fromOrientedRange(this.ranges[0])},this.$onAddRange=function(e){this.rangeCount=this.rangeList.ranges.length,this.ranges.unshift(e),this._signal("addRange",{range:e})},this.$onRemoveRange=function(e){this.rangeCount=this.rangeList.ranges.length;if(this.rangeCount==1&&this.inMultiSelectMode){var t=this.rangeList.ranges.pop();e.push(t),this.rangeCount=0}for(var n=e.length;n--;){var r=this.ranges.indexOf(e[n]);this.ranges.splice(r,1)}this._signal("removeRange",{ranges:e}),this.rangeCount===0&&this.inMultiSelectMode&&(this.inMultiSelectMode=!1,this._signal("singleSelect"),this.session.$undoSelect=!0,this.rangeList.detach(this.session)),t=t||this.ranges[0],t&&!t.isEqual(this.getRange())&&this.fromOrientedRange(t)},this.$initRangeList=function(){if(this.rangeList)return;this.rangeList=new r,this.ranges=[],this.rangeCount=0},this.getAllRanges=function(){return this.rangeCount?this.rangeList.ranges.concat():[this.getRange()]},this.splitIntoLines=function(){if(this.rangeCount>1){var e=this.rangeList.ranges,t=e[e.length-1],n=i.fromPoints(e[0].start,t.end);this.toSingleRange(),this.setSelectionRange(n,t.cursor==t.start)}else{var n=this.getRange(),r=this.isBackwards(),s=n.start.row,o=n.end.row;if(s==o){if(r)var u=n.end,a=n.start;else var u=n.start,a=n.end;this.addRange(i.fromPoints(a,a)),this.addRange(i.fromPoints(u,u));return}var f=[],l=this.getLineRange(s,!0);l.start.column=n.start.column,f.push(l);for(var c=s+1;c1){var e=this.rangeList.ranges,t=e[e.length-1],n=i.fromPoints(e[0].start,t.end);this.toSingleRange(),this.setSelectionRange(n,t.cursor==t.start)}else{var r=this.session.documentToScreenPosition(this.selectionLead),s=this.session.documentToScreenPosition(this.selectionAnchor),o=this.rectangularRangeBlock(r,s);o.forEach(this.addRange,this)}},this.rectangularRangeBlock=function(e,t,n){var r=[],s=e.column0)d--;if(d>0){var m=0;while(r[m].isEmpty())m++}for(var g=d;g>=m;g--)r[g].isEmpty()&&r.splice(g,1)}return r}}.call(s.prototype);var d=e("./editor").Editor;(function(){this.updateSelectionMarkers=function(){this.renderer.updateCursor(),this.renderer.updateBackMarkers()},this.addSelectionMarker=function(e){e.cursor||(e.cursor=e.end);var t=this.getSelectionStyle();return e.marker=this.session.addMarker(e,"ace_selection",t),this.session.$selectionMarkers.push(e),this.session.selectionMarkerCount=this.session.$selectionMarkers.length,e},this.removeSelectionMarker=function(e){if(!e.marker)return;this.session.removeMarker(e.marker);var t=this.session.$selectionMarkers.indexOf(e);t!=-1&&this.session.$selectionMarkers.splice(t,1),this.session.selectionMarkerCount=this.session.$selectionMarkers.length},this.removeSelectionMarkers=function(e){var t=this.session.$selectionMarkers;for(var n=e.length;n--;){var r=e[n];if(!r.marker)continue;this.session.removeMarker(r.marker);var i=t.indexOf(r);i!=-1&&t.splice(i,1)}this.session.selectionMarkerCount=t.length},this.$onAddRange=function(e){this.addSelectionMarker(e.range),this.renderer.updateCursor(),this.renderer.updateBackMarkers()},this.$onRemoveRange=function(e){this.removeSelectionMarkers(e.ranges),this.renderer.updateCursor(),this.renderer.updateBackMarkers()},this.$onMultiSelect=function(e){if(this.inMultiSelectMode)return;this.inMultiSelectMode=!0,this.setStyle("ace_multiselect"),this.keyBinding.addKeyboardHandler(f.keyboardHandler),this.commands.setDefaultHandler("exec",this.$onMultiSelectExec),this.renderer.updateCursor(),this.renderer.updateBackMarkers()},this.$onSingleSelect=function(e){if(this.session.multiSelect.inVirtualMode)return;this.inMultiSelectMode=!1,this.unsetStyle("ace_multiselect"),this.keyBinding.removeKeyboardHandler(f.keyboardHandler),this.commands.removeDefaultHandler("exec",this.$onMultiSelectExec),this.renderer.updateCursor(),this.renderer.updateBackMarkers(),this._emit("changeSelection")},this.$onMultiSelectExec=function(e){var t=e.command,n=e.editor;if(!n.multiSelect)return;if(!t.multiSelectAction){var r=t.exec(n,e.args||{});n.multiSelect.addRange(n.multiSelect.toOrientedRange()),n.multiSelect.mergeOverlappingRanges()}else t.multiSelectAction=="forEach"?r=n.forEachSelection(t,e.args):t.multiSelectAction=="forEachLine"?r=n.forEachSelection(t,e.args,!0):t.multiSelectAction=="single"?(n.exitMultiSelectMode(),r=t.exec(n,e.args||{})):r=t.multiSelectAction(n,e.args||{});return r},this.forEachSelection=function(e,t,n){if(this.inVirtualSelectionMode)return;var r=n&&n.keepOrder,i=n==1||n&&n.$byLines,o=this.session,u=this.selection,a=u.rangeList,f=(r?u:a).ranges,l;if(!f.length)return e.exec?e.exec(this,t||{}):e(this,t||{});var c=u._eventRegistry;u._eventRegistry={};var h=new s(o);this.inVirtualSelectionMode=!0;for(var p=f.length;p--;){if(i)while(p>0&&f[p].start.row==f[p-1].end.row)p--;h.fromOrientedRange(f[p]),h.index=p,this.selection=o.selection=h;var d=e.exec?e.exec(this,t||{}):e(this,t||{});!l&&d!==undefined&&(l=d),h.toOrientedRange(f[p])}h.detach(),this.selection=o.selection=u,this.inVirtualSelectionMode=!1,u._eventRegistry=c,u.mergeOverlappingRanges();var v=this.renderer.$scrollAnimation;return this.onCursorChange(),this.onSelectionChange(),v&&v.from==v.to&&this.renderer.animateScrolling(v.from),l},this.exitMultiSelectMode=function(){if(!this.inMultiSelectMode||this.inVirtualSelectionMode)return;this.multiSelect.toSingleRange()},this.getSelectedText=function(){var e="";if(this.inMultiSelectMode&&!this.inVirtualSelectionMode){var t=this.multiSelect.rangeList.ranges,n=[];for(var r=0;r0);u<0&&(u=0),f>=c&&(f=c-1)}var p=this.session.removeFullLines(u,f);p=this.$reAlignText(p,l),this.session.insert({row:u,column:0},p.join("\n")+"\n"),l||(o.start.column=0,o.end.column=p[p.length-1].length),this.selection.setRange(o)}else{s.forEach(function(e){t.substractPoint(e.cursor)});var d=0,v=Infinity,m=n.map(function(t){var n=t.cursor,r=e.getLine(n.row),i=r.substr(n.column).search(/\S/g);return i==-1&&(i=0),n.column>d&&(d=n.column),io?e.insert(r,a.stringRepeat(" ",s-o)):e.remove(new i(r.row,r.column,r.row,r.column-s+o)),t.start.column=t.end.column=d,t.start.row=t.end.row=r.row,t.cursor=t.end}),t.fromOrientedRange(n[0]),this.renderer.updateCursor(),this.renderer.updateBackMarkers()}},this.$reAlignText=function(e,t){function u(e){return a.stringRepeat(" ",e)}function f(e){return e[2]?u(i)+e[2]+u(s-e[2].length+o)+e[4].replace(/^([=:])\s+/,"$1 "):e[0]}function l(e){return e[2]?u(i+s-e[2].length)+e[2]+u(o," ")+e[4].replace(/^([=:])\s+/,"$1 "):e[0]}function c(e){return e[2]?u(i)+e[2]+u(o)+e[4].replace(/^([=:])\s+/,"$1 "):e[0]}var n=!0,r=!0,i,s,o;return e.map(function(e){var t=e.match(/(\s*)(.*?)(\s*)([=:].*)/);return t?i==null?(i=t[1].length,s=t[2].length,o=t[3].length,t):(i+s+o!=t[1].length+t[2].length+t[3].length&&(r=!1),i!=t[1].length&&(n=!1),i>t[1].length&&(i=t[1].length),st[3].length&&(o=t[3].length),t):[e]}).map(t?f:n?r?l:f:c)}}).call(d.prototype),t.onSessionChange=function(e){var t=e.session;t&&!t.multiSelect&&(t.$selectionMarkers=[],t.selection.$initRangeList(),t.multiSelect=t.selection),this.multiSelect=t&&t.multiSelect;var n=e.oldSession;n&&(n.multiSelect.off("addRange",this.$onAddRange),n.multiSelect.off("removeRange",this.$onRemoveRange),n.multiSelect.off("multiSelect",this.$onMultiSelect),n.multiSelect.off("singleSelect",this.$onSingleSelect),n.multiSelect.lead.off("change",this.$checkMultiselectChange),n.multiSelect.anchor.off("change",this.$checkMultiselectChange)),t&&(t.multiSelect.on("addRange",this.$onAddRange),t.multiSelect.on("removeRange",this.$onRemoveRange),t.multiSelect.on("multiSelect",this.$onMultiSelect),t.multiSelect.on("singleSelect",this.$onSingleSelect),t.multiSelect.lead.on("change",this.$checkMultiselectChange),t.multiSelect.anchor.on("change",this.$checkMultiselectChange)),t&&this.inMultiSelectMode!=t.selection.inMultiSelectMode&&(t.selection.inMultiSelectMode?this.$onMultiSelect():this.$onSingleSelect())},t.MultiSelect=m,e("./config").defineOptions(d.prototype,"editor",{enableMultiselect:{set:function(e){m(this),e?(this.on("changeSession",this.$multiselectOnSessionChange),this.on("mousedown",o)):(this.off("changeSession",this.$multiselectOnSessionChange),this.off("mousedown",o))},value:!0},enableBlockSelect:{set:function(e){this.$blockSelectEnabled=e},value:!0}})}),define("ace/mode/folding/fold_mode",["require","exports","module","ace/range"],function(e,t,n){"use strict";var r=e("../../range").Range,i=t.FoldMode=function(){};(function(){this.foldingStartMarker=null,this.foldingStopMarker=null,this.getFoldWidget=function(e,t,n){var r=e.getLine(n);return this.foldingStartMarker.test(r)?"start":t=="markbeginend"&&this.foldingStopMarker&&this.foldingStopMarker.test(r)?"end":""},this.getFoldWidgetRange=function(e,t,n){return null},this.indentationBlock=function(e,t,n){var i=/\S/,s=e.getLine(t),o=s.search(i);if(o==-1)return;var u=n||s.length,a=e.getLength(),f=t,l=t;while(++tf){var h=e.getLine(l).length;return new r(f,u,l,h)}},this.openingBracketBlock=function(e,t,n,i,s){var o={row:n,column:i+1},u=e.$findClosingBracket(t,o,s);if(!u)return;var a=e.foldWidgets[u.row];return a==null&&(a=e.getFoldWidget(u.row)),a=="start"&&u.row>o.row&&(u.row--,u.column=e.getLine(u.row).length),r.fromPoints(o,u)},this.closingBracketBlock=function(e,t,n,i,s){var o={row:n,column:i},u=e.$findOpeningBracket(t,o);if(!u)return;return u.column++,o.column--,r.fromPoints(u,o)}}).call(i.prototype)}),define("ace/theme/textmate",["require","exports","module","ace/lib/dom"],function(e,t,n){"use strict";t.isDark=!1,t.cssClass="ace-tm",t.cssText='.ace-tm .ace_gutter {background: #f0f0f0;color: #333;}.ace-tm .ace_print-margin {width: 1px;background: #e8e8e8;}.ace-tm .ace_fold {background-color: #6B72E6;}.ace-tm {background-color: #FFFFFF;color: black;}.ace-tm .ace_cursor {color: black;}.ace-tm .ace_invisible {color: rgb(191, 191, 191);}.ace-tm .ace_storage,.ace-tm .ace_keyword {color: blue;}.ace-tm .ace_constant {color: rgb(197, 6, 11);}.ace-tm .ace_constant.ace_buildin {color: rgb(88, 72, 246);}.ace-tm .ace_constant.ace_language {color: rgb(88, 92, 246);}.ace-tm .ace_constant.ace_library {color: rgb(6, 150, 14);}.ace-tm .ace_invalid {background-color: rgba(255, 0, 0, 0.1);color: red;}.ace-tm .ace_support.ace_function {color: rgb(60, 76, 114);}.ace-tm .ace_support.ace_constant {color: rgb(6, 150, 14);}.ace-tm .ace_support.ace_type,.ace-tm .ace_support.ace_class {color: rgb(109, 121, 222);}.ace-tm .ace_keyword.ace_operator {color: rgb(104, 118, 135);}.ace-tm .ace_string {color: rgb(3, 106, 7);}.ace-tm .ace_comment {color: rgb(76, 136, 107);}.ace-tm .ace_comment.ace_doc {color: rgb(0, 102, 255);}.ace-tm .ace_comment.ace_doc.ace_tag {color: rgb(128, 159, 191);}.ace-tm .ace_constant.ace_numeric {color: rgb(0, 0, 205);}.ace-tm .ace_variable {color: rgb(49, 132, 149);}.ace-tm .ace_xml-pe {color: rgb(104, 104, 91);}.ace-tm .ace_entity.ace_name.ace_function {color: #0000A2;}.ace-tm .ace_heading {color: rgb(12, 7, 255);}.ace-tm .ace_list {color:rgb(185, 6, 144);}.ace-tm .ace_meta.ace_tag {color:rgb(0, 22, 142);}.ace-tm .ace_string.ace_regex {color: rgb(255, 0, 0)}.ace-tm .ace_marker-layer .ace_selection {background: rgb(181, 213, 255);}.ace-tm.ace_multiselect .ace_selection.ace_start {box-shadow: 0 0 3px 0px white;}.ace-tm .ace_marker-layer .ace_step {background: rgb(252, 255, 0);}.ace-tm .ace_marker-layer .ace_stack {background: rgb(164, 229, 101);}.ace-tm .ace_marker-layer .ace_bracket {margin: -1px 0 0 -1px;border: 1px solid rgb(192, 192, 192);}.ace-tm .ace_marker-layer .ace_active-line {background: rgba(0, 0, 0, 0.07);}.ace-tm .ace_gutter-active-line {background-color : #dcdcdc;}.ace-tm .ace_marker-layer .ace_selected-word {background: rgb(250, 250, 255);border: 1px solid rgb(200, 200, 250);}.ace-tm .ace_indent-guide {background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAE0lEQVQImWP4////f4bLly//BwAmVgd1/w11/gAAAABJRU5ErkJggg==") right repeat-y;}';var r=e("../lib/dom");r.importCssString(t.cssText,t.cssClass)}),define("ace/line_widgets",["require","exports","module","ace/lib/oop","ace/lib/dom","ace/range"],function(e,t,n){"use strict";function o(e){this.session=e,this.session.widgetManager=this,this.session.getRowLength=this.getRowLength,this.session.$getWidgetScreenLength=this.$getWidgetScreenLength,this.updateOnChange=this.updateOnChange.bind(this),this.renderWidgets=this.renderWidgets.bind(this),this.measureWidgets=this.measureWidgets.bind(this),this.session._changedWidgets=[],this.$onChangeEditor=this.$onChangeEditor.bind(this),this.session.on("change",this.updateOnChange),this.session.on("changeFold",this.updateOnFold),this.session.on("changeEditor",this.$onChangeEditor)}var r=e("./lib/oop"),i=e("./lib/dom"),s=e("./range").Range;(function(){this.getRowLength=function(e){var t;return this.lineWidgets?t=this.lineWidgets[e]&&this.lineWidgets[e].rowCount||0:t=0,!this.$useWrapMode||!this.$wrapData[e]?1+t:this.$wrapData[e].length+1+t},this.$getWidgetScreenLength=function(){var e=0;return this.lineWidgets.forEach(function(t){t&&t.rowCount&&!t.hidden&&(e+=t.rowCount)}),e},this.$onChangeEditor=function(e){this.attach(e.editor)},this.attach=function(e){e&&e.widgetManager&&e.widgetManager!=this&&e.widgetManager.detach();if(this.editor==e)return;this.detach(),this.editor=e,e&&(e.widgetManager=this,e.renderer.on("beforeRender",this.measureWidgets),e.renderer.on("afterRender",this.renderWidgets))},this.detach=function(e){var t=this.editor;if(!t)return;this.editor=null,t.widgetManager=null,t.renderer.off("beforeRender",this.measureWidgets),t.renderer.off("afterRender",this.renderWidgets);var n=this.session.lineWidgets;n&&n.forEach(function(e){e&&e.el&&e.el.parentNode&&(e._inDocument=!1,e.el.parentNode.removeChild(e.el))})},this.updateOnFold=function(e,t){var n=t.lineWidgets;if(!n||!e.action)return;var r=e.data,i=r.start.row,s=r.end.row,o=e.action=="add";for(var u=i+1;u0&&!r[i])i--;this.firstRow=n.firstRow,this.lastRow=n.lastRow,t.$cursorLayer.config=n;for(var o=i;o<=s;o++){var u=r[o];if(!u||!u.el)continue;if(u.hidden){u.el.style.top=-100-(u.pixelHeight||0)+"px";continue}u._inDocument||(u._inDocument=!0,t.container.appendChild(u.el));var a=t.$cursorLayer.getPixelPosition({row:o,column:0},!0).top;u.coverLine||(a+=n.lineHeight*this.session.getRowLineCount(u.row)),u.el.style.top=a-n.offset+"px";var f=u.coverGutter?0:t.gutterWidth;u.fixedWidth||(f-=t.scrollLeft),u.el.style.left=f+"px",u.fullWidth&&u.screenWidth&&(u.el.style.minWidth=n.width+2*n.padding+"px"),u.fixedWidth?u.el.style.right=t.scrollBar.getWidth()+"px":u.el.style.right=""}}}).call(o.prototype),t.LineWidgets=o}),define("ace/ext/error_marker",["require","exports","module","ace/line_widgets","ace/lib/dom","ace/range"],function(e,t,n){"use strict";function o(e,t,n){var r=0,i=e.length-1;while(r<=i){var s=r+i>>1,o=n(t,e[s]);if(o>0)r=s+1;else{if(!(o<0))return s;i=s-1}}return-(r+1)}function u(e,t,n){var r=e.getAnnotations().sort(s.comparePoints);if(!r.length)return;var i=o(r,{row:t,column:-1},s.comparePoints);i<0&&(i=-i-1),i>=r.length?i=n>0?0:r.length-1:i===0&&n<0&&(i=r.length-1);var u=r[i];if(!u||!n)return;if(u.row===t){do u=r[i+=n];while(u&&u.row===t);if(!u)return r.slice()}var a=[];t=u.row;do a[n<0?"unshift":"push"](u),u=r[i+=n];while(u&&u.row==t);return a.length&&a}var r=e("../line_widgets").LineWidgets,i=e("../lib/dom"),s=e("../range").Range;t.showErrorMarker=function(e,t){var n=e.session;n.widgetManager||(n.widgetManager=new r(n),n.widgetManager.attach(e));var s=e.getCursorPosition(),o=s.row,a=n.widgetManager.getWidgetsAtRow(o).filter(function(e){return e.type=="errorMarker"})[0];a?a.destroy():o-=t;var f=u(n,o,t),l;if(f){var c=f[0];s.column=(c.pos&&typeof c.column!="number"?c.pos.sc:c.column)||0,s.row=c.row,l=e.renderer.$gutterLayer.$annotations[s.row]}else{if(a)return;l={text:["Looks good!"],className:"ace_ok"}}e.session.unfold(s.row),e.selection.moveToPosition(s);var h={row:s.row,fixedWidth:!0,coverGutter:!0,el:i.createElement("div"),type:"errorMarker"},p=h.el.appendChild(i.createElement("div")),d=h.el.appendChild(i.createElement("div"));d.className="error_widget_arrow "+l.className;var v=e.renderer.$cursorLayer.getPixelPosition(s).left;d.style.left=v+e.renderer.gutterWidth-5+"px",h.el.className="error_widget_wrapper",p.className="error_widget "+l.className,p.innerHTML=l.text.join("
"),p.appendChild(i.createElement("div"));var m=function(e,t,n){if(t===0&&(n==="esc"||n==="return"))return h.destroy(),{command:"null"}};h.destroy=function(){if(e.$mouseHandler.isMousePressed)return;e.keyBinding.removeKeyboardHandler(m),n.widgetManager.removeLineWidget(h),e.off("changeSelection",h.destroy),e.off("changeSession",h.destroy),e.off("mouseup",h.destroy),e.off("change",h.destroy)},e.keyBinding.addKeyboardHandler(m),e.on("changeSelection",h.destroy),e.on("changeSession",h.destroy),e.on("mouseup",h.destroy),e.on("change",h.destroy),e.session.widgetManager.addLineWidget(h),h.el.onmousedown=e.focus.bind(e),e.renderer.scrollCursorIntoView(null,.5,{bottom:h.el.offsetHeight})},i.importCssString(" .error_widget_wrapper { background: inherit; color: inherit; border:none } .error_widget { border-top: solid 2px; border-bottom: solid 2px; margin: 5px 0; padding: 10px 40px; white-space: pre-wrap; } .error_widget.ace_error, .error_widget_arrow.ace_error{ border-color: #ff5a5a } .error_widget.ace_warning, .error_widget_arrow.ace_warning{ border-color: #F1D817 } .error_widget.ace_info, .error_widget_arrow.ace_info{ border-color: #5a5a5a } .error_widget.ace_ok, .error_widget_arrow.ace_ok{ border-color: #5aaa5a } .error_widget_arrow { position: absolute; border: solid 5px; border-top-color: transparent!important; border-right-color: transparent!important; border-left-color: transparent!important; top: -5px; }","")}),define("ace/ace",["require","exports","module","ace/lib/fixoldbrowsers","ace/lib/dom","ace/lib/event","ace/editor","ace/edit_session","ace/undomanager","ace/virtual_renderer","ace/worker/worker_client","ace/keyboard/hash_handler","ace/placeholder","ace/multi_select","ace/mode/folding/fold_mode","ace/theme/textmate","ace/ext/error_marker","ace/config"],function(e,t,n){"use strict";e("./lib/fixoldbrowsers");var r=e("./lib/dom"),i=e("./lib/event"),s=e("./editor").Editor,o=e("./edit_session").EditSession,u=e("./undomanager").UndoManager,a=e("./virtual_renderer").VirtualRenderer;e("./worker/worker_client"),e("./keyboard/hash_handler"),e("./placeholder"),e("./multi_select"),e("./mode/folding/fold_mode"),e("./theme/textmate"),e("./ext/error_marker"),t.config=e("./config"),t.require=e,typeof define=="function"&&(t.define=define),t.edit=function(e){if(typeof e=="string"){var n=e;e=document.getElementById(n);if(!e)throw new Error("ace.edit can't find div #"+n)}if(e&&e.env&&e.env.editor instanceof s)return e.env.editor;var o="";if(e&&/input|textarea/i.test(e.tagName)){var u=e;o=u.value,e=r.createElement("pre"),u.parentNode.replaceChild(e,u)}else e&&(o=r.getInnerText(e),e.innerHTML="");var f=t.createEditSession(o),l=new s(new a(e));l.setSession(f);var c={document:f,editor:l,onResize:l.resize.bind(l,null)};return u&&(c.textarea=u),i.addListener(window,"resize",c.onResize),l.on("destroy",function(){i.removeListener(window,"resize",c.onResize),c.editor.container.env=null}),l.container.env=l.env=c,l},t.createEditSession=function(e,t){var n=new o(e,t);return n.setUndoManager(new u),n},t.EditSession=o,t.UndoManager=u,t.version="1.2.6"}); + (function() { + window.require(["ace/ace"], function(a) { + if (a) { + a.config.init(true); + a.define = window.define; + } + if (!window.ace) + window.ace = a; + for (var key in a) if (a.hasOwnProperty(key)) + window.ace[key] = a[key]; + }); + })(); + \ No newline at end of file diff --git a/examples/SmartSwitch/data_src/js_css_src/app.js b/examples/SmartSwitch/data_src/js_css_src/app.js new file mode 100644 index 000000000..46305f295 --- /dev/null +++ b/examples/SmartSwitch/data_src/js_css_src/app.js @@ -0,0 +1,5787 @@ +var tpick = { + attach: function (target) { + + var dig = document.getElementById(target).value.split(":"); + var t1 = dig[0] || "23"; + var t2 = dig[1] || "59"; + + var uniqueID = 0; + while (document.getElementById("tpick-" + uniqueID) != null) { + uniqueID = Math.floor(Math.random() * (100 - 2)) + 1; + } + var tw = document.createElement("div"); + tw.id = "tpick-" + uniqueID; + tw.classList.add("tpop"); + tw.dataset.target = target; + tw.addEventListener("click", function (evt) { + if (evt.target.classList.contains("tpop")) { + this.classList.remove("show"); + } + }); + var tp = document.createElement("div"); + tp.classList.add("tpicker"); + tp.appendChild(this.draw("h",t1)); + tp.appendChild(this.draw("m",t2)); + var bottom = document.createElement("div"), + ok = document.createElement("input"); + ok.setAttribute("type", "button"); + ok.value = "OK"; + ok.addEventListener("click", function () { + tpick.set(this); + }); + bottom.classList.add("tpicker-btn"); + bottom.appendChild(ok); + tp.appendChild(bottom); + tw.appendChild(tp); + document.body.appendChild(tw); + var target = document.getElementById(target); + target.dataset.dp = uniqueID; + target.onfocus = function () { + document.getElementById("tpick-" + this.dataset.dp).classList.add("show"); + }; + }, + draw: function (type,tv) { + var docket = document.createElement("div"), + up = document.createElement("div"), + down = document.createElement("div"), + text = document.createElement("input"); + docket.classList.add("tpicker-" + type); + up.classList.add("tpicker-up"); + down.classList.add("tpicker-down"); + up.innerHTML = "︿"; + down.innerHTML = "﹀"; + text.readOnly = true; + text.setAttribute("type", "text"); + if (type == "h") { + text.value = tv; + up.addEventListener("click", function () { + tpick.spin("h", 1, this); + }); + down.addEventListener("click", function () { + tpick.spin("h", 0, this); + }); + } else if (type == "m") { + text.value = tv; + up.addEventListener("click", function () { + tpick.spin("m", 1, this); + }); + down.addEventListener("click", function () { + tpick.spin("m", 0, this); + }); + } + docket.appendChild(up); + docket.appendChild(text); + docket.appendChild(down); + return docket; + }, + spin: function (type, direction, el) { + var parent = el.parentElement, + field = parent.getElementsByTagName("input")[0], + value = field.value; + if (type == "h") { + value = parseInt(value); + if (direction) { + value++; + } else { + value--; + } + if (value == -1) { + value = 23; + } else if (value > 23) { + value = 0; + } + } else if (type == "m") { + value = parseInt(value); + if (direction) { + value += 5; + } else { + value -= 5; + } + if (value < 0) { + value = 55; + } else if (value > 59) { + value = 0; + } + if (value < 10) { + value = "0" + value; + } + } + field.value = ('00' + value).substr(-2); + }, + set: function (el) { + var parent = el.parentElement; + while (parent.classList.contains("tpop") == false) { + parent = parent.parentElement; + } + var input = parent.querySelectorAll("input[type=text]"); + var time = input[0].value + ":" + input[1].value; + document.getElementById(parent.dataset.target).value = time; + parent.classList.remove("show"); + } +}; +var fpick = { + attach: function (target) { + + var dig = document.getElementById(target).value.split("."); + var t1 = dig[0] || "1"; + var t2 = dig[1] || "2"; + var uniqueID = 0; + while (document.getElementById("fpick-" + uniqueID) != null) { + uniqueID = Math.floor(Math.random() * (100 - 2)) + 1; + } + var tw = document.createElement("div"); + tw.id = "fpick-" + uniqueID; + tw.classList.add("tpop"); + tw.dataset.target = target; + tw.addEventListener("click", function (evt) { + if (evt.target.classList.contains("tpop")) { + this.classList.remove("show"); + } + }); + var tp = document.createElement("div"); + tp.classList.add("fpicker"); + tp.appendChild(this.draw("h",t1)); + tp.appendChild(this.draw("m",t2)); + var bottom = document.createElement("div"), + ok = document.createElement("input"); + ok.setAttribute("type", "button"); + ok.value = "OK"; + ok.addEventListener("click", function () { + fpick.set(this); + }); + bottom.classList.add("fpicker-btn"); + bottom.appendChild(ok); + tp.appendChild(bottom); + tw.appendChild(tp); + document.body.appendChild(tw); + var target = document.getElementById(target); + target.dataset.dp = uniqueID; + target.onfocus = function () { + document.getElementById("fpick-" + this.dataset.dp).classList.add("show"); + }; + }, + draw: function (type,tv) { + + var docket = document.createElement("div"), + up = document.createElement("div"), + down = document.createElement("div"), + text = document.createElement("input"); + docket.classList.add("fpicker-" + type); + up.classList.add("fpicker-up"); + down.classList.add("fpicker-down"); + up.innerHTML = "︿"; + down.innerHTML = "﹀"; + text.readOnly = true; + text.setAttribute("type", "text"); + if (type == "h") { + text.value = tv; + up.addEventListener("click", function () { + fpick.spin("h", 1, this); + }); + down.addEventListener("click", function () { + fpick.spin("h", 0, this); + }); + } else if (type == "m") { + text.value = tv; + up.addEventListener("click", function () { + fpick.spin("m", 1, this); + }); + down.addEventListener("click", function () { + fpick.spin("m", 0, this); + }); + } + docket.appendChild(up); + docket.appendChild(text); + docket.appendChild(down); + return docket; + }, + spin: function (type, direction, el) { + var parent = el.parentElement, + field = parent.getElementsByTagName("input")[0], + value = field.value; + if (type == "h") { + value = parseInt(value); + if (direction) { + value++; + } else { + value--; + } + if (value == -41) { + value = 99; + } else if (value > 99) { + value = -40; + } + } else if (type == "m") { + value = parseInt(value); + if (direction) { + value++; + } else { + value--; + } + if (value < 0) { + value = 9; + } else if (value > 9) { + value = 0; + } + } + field.value = value; + }, + set: function (el) { + var parent = el.parentElement; + while (parent.classList.contains("tpop") == false) { + parent = parent.parentElement; + } + var input = parent.querySelectorAll("input[type=text]"); + var temperature = input[0].value + "." + input[1].value; + document.getElementById(parent.dataset.target).value = temperature; + parent.classList.remove("show"); + } +}; +!function (t) { + function n(i) { + if (e[i]) + return e[i].exports; + var o = e[i] = { + i: i, + l: !1, + exports: {} + }; + return t[i].call(o.exports, o, o.exports, n), + o.l = !0, + o.exports + } + var e = {}; + n.m = t, + n.c = e, + n.d = function (t, e, i) { + n.o(t, e) || Object.defineProperty(t, e, { + configurable: !1, + enumerable: !0, + get: i + }) + }, + n.n = function (t) { + var e = t && t.__esModule ? function () { + return t.default + } + : function () { + return t + }; + return n.d(e, "a", e), + e + }, + n.o = function (t, n) { + return Object.prototype.hasOwnProperty.call(t, n) + }, + n.p = "", + n(n.s = 0) +} +([function (t, n, e) { + e(1), + t.exports = e(4) + }, function (t, n, e) { + "use strict"; + var i = Object.assign || function (t) { + for (var n = 1; n < arguments.length; n++) { + var e = arguments[n]; + for (var i in e) + Object.prototype.hasOwnProperty.call(e, i) && (t[i] = e[i]) + } + return t + }; + e(2); + var o = e(3); + !function (t) { + function n(t) { + return t = i({}, c, t), + function (t) { + return ["nfc-top-left", "nfc-top-right", "nfc-bottom-left", "nfc-bottom-right"].indexOf(t) > -1 + } + (t.positionClass) || (console.warn("An invalid notification position class has been specified."), t.positionClass = c.positionClass), + t.onclick && "function" != typeof t.onclick && (console.warn("Notification on click must be a function."), t.onclick = c.onclick), + "number" != typeof t.showDuration && (t.showDuration = c.showDuration), + (0, o.isString)(t.theme) && 0 !== t.theme.length || (console.warn("Notification theme must be a string with length"), t.theme = c.theme), + t + } + function e(t) { + return t = n(t), + function () { + var n = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : {}, + e = n.title, + i = n.message, + c = r(t.positionClass); + if (!e && !i) + return console.warn("Notification must contain a title or a message!"); + var a = (0, o.createElement)("div", "ncf", t.theme); + if (!0 === t.closeOnClick && a.addEventListener("click", function () { + return c.removeChild(a) + }), t.onclick && a.addEventListener("click", function (n) { + return t.onclick(n) + }), t.displayCloseButton) { + var s = (0, o.createElement)("button"); + s.innerText = "X", + !1 === t.closeOnClick && s.addEventListener("click", function () { + return c.removeChild(a) + }), + (0, o.append)(a, s) + } + if ((0, o.isString)(e) && e.length && (0, o.append)(a, (0, o.createParagraph)("ncf-title")(e)), (0, o.isString)(i) && i.length && (0, o.append)(a, (0, o.createParagraph)("nfc-message")(i)), (0, o.append)(c, a), t.showDuration && t.showDuration > 0) { + var l = setTimeout(function () { + c.removeChild(a), + 0 === c.querySelectorAll(".ncf").length && document.body.removeChild(c) + }, t.showDuration); + (t.closeOnClick || t.displayCloseButton) && a.addEventListener("click", function () { + return clearTimeout(l) + }) + } + } + } + function r(t) { + var n = document.querySelector("." + t); + return n || (n = (0, o.createElement)("div", "ncf-container", t), (0, o.append)(document.body, n)), + n + } + var c = { + closeOnClick: !0, + displayCloseButton: !1, + positionClass: "nfc-top-right", + onclick: !1, + showDuration: 3500, + theme: "success" + }; + t.createNotification ? console.warn("Window already contains a create notification function. Have you included the script twice?") : t.createNotification = e + } + (window) + }, function (t, n, e) { + "use strict"; + !function () { + function t(t) { + this.el = t; + for (var n = t.className.replace(/^\s+|\s+$/g, "").split(/\s+/), i = 0; i < n.length; i++) + e.call(this, n[i]) + } + if (!(void 0 === window.Element || "classList" in document.documentElement)) { + var n = Array.prototype, + e = n.push, + i = n.splice, + o = n.join; + t.prototype = { + add: function (t) { + this.contains(t) || (e.call(this, t), this.el.className = this.toString()) + }, + contains: function (t) { + return -1 != this.el.className.indexOf(t) + }, + item: function (t) { + return this[t] || null + }, + remove: function (t) { + if (this.contains(t)) { + for (var n = 0; n < this.length && this[n] != t; n++); + i.call(this, n, 1), + this.el.className = this.toString() + } + }, + toString: function () { + return o.call(this, " ") + }, + toggle: function (t) { + return this.contains(t) ? this.remove(t) : this.add(t), + this.contains(t) + } + }, + window.DOMTokenList = t, + function (t, n, e) { + Object.defineProperty ? Object.defineProperty(t, n, { + get: e + }) : t.__defineGetter__(n, e) + } + (Element.prototype, "classList", function () { + return new t(this) + }) + } + } + () + }, function (t, n, e) { + "use strict"; + Object.defineProperty(n, "__esModule", { + value: !0 + }); + var i = n.partial = function (t) { + for (var n = arguments.length, e = Array(n > 1 ? n - 1 : 0), i = 1; i < n; i++) + e[i - 1] = arguments[i]; + return function () { + for (var n = arguments.length, i = Array(n), o = 0; o < n; o++) + i[o] = arguments[o]; + return t.apply(void 0, e.concat(i)) + } + }, + o = (n.append = function (t) { + for (var n = arguments.length, e = Array(n > 1 ? n - 1 : 0), i = 1; i < n; i++) + e[i - 1] = arguments[i]; + return e.forEach(function (n) { + return t.appendChild(n) + }) + }, n.isString = function (t) { + return "string" == typeof t + }, n.createElement = function (t) { + for (var n = arguments.length, e = Array(n > 1 ? n - 1 : 0), i = 1; i < n; i++) + e[i - 1] = arguments[i]; + var o = document.createElement(t); + return e.length && e.forEach(function (t) { + return o.classList.add(t) + }), + o + }), + r = function (t, n) { + return t.innerText = n, + t + }, + c = function (t) { + for (var n = arguments.length, e = Array(n > 1 ? n - 1 : 0), c = 1; c < n; c++) + e[c - 1] = arguments[c]; + return i(r, o.apply(void 0, [t].concat(e))) + }; + n.createParagraph = function () { + for (var t = arguments.length, n = Array(t), e = 0; e < t; e++) + n[e] = arguments[e]; + return c.apply(void 0, ["p"].concat(n)) + } + }, function (t, n) {} + ]); +!function (a, b) { + "function" == typeof define && define.amd ? define("eve", function () { + return b() + }) : "object" == typeof exports ? module.exports = b() : a.eve = b() +} +(this, function () { + var a, + b, + c = "0.4.2", + d = "hasOwnProperty", + e = /[\.\/]/, + f = "*", + g = function () {}, + h = function (a, b) { + return a - b + }, + i = { + n: {} + }, + j = function (c, d) { + c = String(c); + var e, + f = b, + g = Array.prototype.slice.call(arguments, 2), + i = j.listeners(c), + k = 0, + l = [], + m = {}, + n = [], + o = a; + a = c, + b = 0; + for (var p = 0, q = i.length; q > p; p++) + "zIndex" in i[p] && (l.push(i[p].zIndex), i[p].zIndex < 0 && (m[i[p].zIndex] = i[p])); + for (l.sort(h); l[k] < 0; ) + if (e = m[l[k++]], n.push(e.apply(d, g)), b) + return b = f, n; + for (p = 0; q > p; p++) + if (e = i[p], "zIndex" in e) + if (e.zIndex == l[k]) { + if (n.push(e.apply(d, g)), b) + break; + do + if (k++, e = m[l[k]], e && n.push(e.apply(d, g)), b) + break; + while (e) + } else + m[e.zIndex] = e; + else if (n.push(e.apply(d, g)), b) + break; + return b = f, + a = o, + n.length ? n : null + }; + return j._events = i, + j.listeners = function (a) { + var b, + c, + d, + g, + h, + j, + k, + l, + m = a.split(e), + n = i, + o = [n], + p = []; + for (g = 0, h = m.length; h > g; g++) { + for (l = [], j = 0, k = o.length; k > j; j++) + for (n = o[j].n, c = [n[m[g]], n[f]], d = 2; d--; ) + b = c[d], b && (l.push(b), p = p.concat(b.f || [])); + o = l + } + return p + }, + j.on = function (a, b) { + if (a = String(a), "function" != typeof b) + return function () {}; + for (var c = a.split(e), d = i, f = 0, h = c.length; h > f; f++) + d = d.n, d = d.hasOwnProperty(c[f]) && d[c[f]] || (d[c[f]] = { + n: {} + }); + for (d.f = d.f || [], f = 0, h = d.f.length; h > f; f++) + if (d.f[f] == b) + return g; + return d.f.push(b), + function (a) { + +a == +a && (b.zIndex = +a) + } + }, + j.f = function (a) { + var b = [].slice.call(arguments, 1); + return function () { + j.apply(null, [a, null].concat(b).concat([].slice.call(arguments, 0))) + } + }, + j.stop = function () { + b = 1 + }, + j.nt = function (b) { + return b ? new RegExp("(?:\\.|\\/|^)" + b + "(?:\\.|\\/|$)").test(a) : a + }, + j.nts = function () { + return a.split(e) + }, + j.off = j.unbind = function (a, b) { + if (!a) + return void(j._events = i = { + n: {} + }); + var c, + g, + h, + k, + l, + m, + n, + o = a.split(e), + p = [i]; + for (k = 0, l = o.length; l > k; k++) + for (m = 0; m < p.length; m += h.length - 2) { + if (h = [m, 1], c = p[m].n, o[k] != f) + c[o[k]] && h.push(c[o[k]]); + else + for (g in c) + c[d](g) && h.push(c[g]); + p.splice.apply(p, h) + } + for (k = 0, l = p.length; l > k; k++) + for (c = p[k]; c.n; ) { + if (b) { + if (c.f) { + for (m = 0, n = c.f.length; n > m; m++) + if (c.f[m] == b) { + c.f.splice(m, 1); + break + } + !c.f.length && delete c.f + } + for (g in c.n) + if (c.n[d](g) && c.n[g].f) { + var q = c.n[g].f; + for (m = 0, n = q.length; n > m; m++) + if (q[m] == b) { + q.splice(m, 1); + break + } + !q.length && delete c.n[g].f + } + } else { + delete c.f; + for (g in c.n) + c.n[d](g) && c.n[g].f && delete c.n[g].f + } + c = c.n + } + }, + j.once = function (a, b) { + var c = function () { + return j.unbind(a, c), + b.apply(this, arguments) + }; + return j.on(a, c) + }, + j.version = c, + j.toString = function () { + return "You are running Eve " + c + }, + j +}), function (a, b) { + "function" == typeof define && define.amd ? define("raphael.core", ["eve"], function (a) { + return b(a) + }) : "object" == typeof exports ? module.exports = b(require("eve")) : a.Raphael = b(a.eve) +} +(this, function (a) { + function b(c) { + if (b.is(c, "function")) + return t ? c() : a.on("raphael.DOMload", c); + if (b.is(c, U)) + return b._engine.create[C](b, c.splice(0, 3 + b.is(c[0], S))).add(c); + var d = Array.prototype.slice.call(arguments, 0); + if (b.is(d[d.length - 1], "function")) { + var e = d.pop(); + return t ? e.call(b._engine.create[C](b, d)) : a.on("raphael.DOMload", function () { + e.call(b._engine.create[C](b, d)) + }) + } + return b._engine.create[C](b, arguments) + } + function c(a) { + if ("function" == typeof a || Object(a) !== a) + return a; + var b = new a.constructor; + for (var d in a) + a[y](d) && (b[d] = c(a[d])); + return b + } + function d(a, b) { + for (var c = 0, d = a.length; d > c; c++) + if (a[c] === b) + return a.push(a.splice(c, 1)[0]) + } + function e(a, b, c) { + function e() { + var f = Array.prototype.slice.call(arguments, 0), + g = f.join("␀"), + h = e.cache = e.cache || {}, + i = e.count = e.count || []; + return h[y](g) ? (d(i, g), c ? c(h[g]) : h[g]) : (i.length >= 1e3 && delete h[i.shift()], i.push(g), h[g] = a[C](b, f), c ? c(h[g]) : h[g]) + } + return e + } + function f() { + return this.hex + } + function g(a, b) { + for (var c = [], d = 0, e = a.length; e - 2 * !b > d; d += 2) { + var f = [{ + x: +a[d - 2], + y: +a[d - 1] + }, { + x: +a[d], + y: +a[d + 1] + }, { + x: +a[d + 2], + y: +a[d + 3] + }, { + x: +a[d + 4], + y: +a[d + 5] + } + ]; + b ? d ? e - 4 == d ? f[3] = { + x: +a[0], + y: +a[1] + } + : e - 2 == d && (f[2] = { + x: +a[0], + y: +a[1] + }, f[3] = { + x: +a[2], + y: +a[3] + }) : f[0] = { + x: +a[e - 2], + y: +a[e - 1] + } + : e - 4 == d ? f[3] = f[2] : d || (f[0] = { + x: +a[d], + y: +a[d + 1] + }), + c.push(["C", (-f[0].x + 6 * f[1].x + f[2].x) / 6, (-f[0].y + 6 * f[1].y + f[2].y) / 6, (f[1].x + 6 * f[2].x - f[3].x) / 6, (f[1].y + 6 * f[2].y - f[3].y) / 6, f[2].x, f[2].y]) + } + return c + } + function h(a, b, c, d, e) { + var f = -3 * b + 9 * c - 9 * d + 3 * e, + g = a * f + 6 * b - 12 * c + 6 * d; + return a * g - 3 * b + 3 * c + } + function i(a, b, c, d, e, f, g, i, j) { + null == j && (j = 1), + j = j > 1 ? 1 : 0 > j ? 0 : j; + for (var k = j / 2, l = 12, m = [ - .1252, .1252, - .3678, .3678, - .5873, .5873, - .7699, .7699, - .9041, .9041, - .9816, .9816], n = [.2491, .2491, .2335, .2335, .2032, .2032, .1601, .1601, .1069, .1069, .0472, .0472], o = 0, p = 0; l > p; p++) { + var q = k * m[p] + k, + r = h(q, a, c, e, g), + s = h(q, b, d, f, i), + t = r * r + s * s; + o += n[p] * M.sqrt(t) + } + return k * o + } + function j(a, b, c, d, e, f, g, h, j) { + if (!(0 > j || i(a, b, c, d, e, f, g, h) < j)) { + var k, + l = 1, + m = l / 2, + n = l - m, + o = .01; + for (k = i(a, b, c, d, e, f, g, h, n); P(k - j) > o; ) + m /= 2, n += (j > k ? 1 : -1) * m, k = i(a, b, c, d, e, f, g, h, n); + return n + } + } + function k(a, b, c, d, e, f, g, h) { + if (!(N(a, c) < O(e, g) || O(a, c) > N(e, g) || N(b, d) < O(f, h) || O(b, d) > N(f, h))) { + var i = (a * d - b * c) * (e - g) - (a - c) * (e * h - f * g), + j = (a * d - b * c) * (f - h) - (b - d) * (e * h - f * g), + k = (a - c) * (f - h) - (b - d) * (e - g); + if (k) { + var l = i / k, + m = j / k, + n = +l.toFixed(2), + o = +m.toFixed(2); + if (!(n < +O(a, c).toFixed(2) || n > +N(a, c).toFixed(2) || n < +O(e, g).toFixed(2) || n > +N(e, g).toFixed(2) || o < +O(b, d).toFixed(2) || o > +N(b, d).toFixed(2) || o < +O(f, h).toFixed(2) || o > +N(f, h).toFixed(2))) + return { + x: l, + y: m + } + } + } + } + function l(a, c, d) { + var e = b.bezierBBox(a), + f = b.bezierBBox(c); + if (!b.isBBoxIntersect(e, f)) + return d ? 0 : []; + for (var g = i.apply(0, a), h = i.apply(0, c), j = N(~~(g / 5), 1), l = N(~~(h / 5), 1), m = [], n = [], o = {}, p = d ? 0 : [], q = 0; j + 1 > q; q++) { + var r = b.findDotsAtSegment.apply(b, a.concat(q / j)); + m.push({ + x: r.x, + y: r.y, + t: q / j + }) + } + for (q = 0; l + 1 > q; q++) + r = b.findDotsAtSegment.apply(b, c.concat(q / l)), n.push({ + x: r.x, + y: r.y, + t: q / l + }); + for (q = 0; j > q; q++) + for (var s = 0; l > s; s++) { + var t = m[q], + u = m[q + 1], + v = n[s], + w = n[s + 1], + x = P(u.x - t.x) < .001 ? "y" : "x", + y = P(w.x - v.x) < .001 ? "y" : "x", + z = k(t.x, t.y, u.x, u.y, v.x, v.y, w.x, w.y); + if (z) { + if (o[z.x.toFixed(4)] == z.y.toFixed(4)) + continue; + o[z.x.toFixed(4)] = z.y.toFixed(4); + var A = t.t + P((z[x] - t[x]) / (u[x] - t[x])) * (u.t - t.t), + B = v.t + P((z[y] - v[y]) / (w[y] - v[y])) * (w.t - v.t); + A >= 0 && 1.001 >= A && B >= 0 && 1.001 >= B && (d ? p++ : p.push({ + x: z.x, + y: z.y, + t1: O(A, 1), + t2: O(B, 1) + })) + } + } + return p + } + function m(a, c, d) { + a = b._path2curve(a), + c = b._path2curve(c); + for (var e, f, g, h, i, j, k, m, n, o, p = d ? 0 : [], q = 0, r = a.length; r > q; q++) { + var s = a[q]; + if ("M" == s[0]) + e = i = s[1], f = j = s[2]; + else { + "C" == s[0] ? (n = [e, f].concat(s.slice(1)), e = n[6], f = n[7]) : (n = [e, f, e, f, i, j, i, j], e = i, f = j); + for (var t = 0, u = c.length; u > t; t++) { + var v = c[t]; + if ("M" == v[0]) + g = k = v[1], h = m = v[2]; + else { + "C" == v[0] ? (o = [g, h].concat(v.slice(1)), g = o[6], h = o[7]) : (o = [g, h, g, h, k, m, k, m], g = k, h = m); + var w = l(n, o, d); + if (d) + p += w; + else { + for (var x = 0, y = w.length; y > x; x++) + w[x].segment1 = q, w[x].segment2 = t, w[x].bez1 = n, w[x].bez2 = o; + p = p.concat(w) + } + } + } + } + } + return p + } + function n(a, b, c, d, e, f) { + null != a ? (this.a = +a, this.b = +b, this.c = +c, this.d = +d, this.e = +e, this.f = +f) : (this.a = 1, this.b = 0, this.c = 0, this.d = 1, this.e = 0, this.f = 0) + } + function o() { + return this.x + G + this.y + G + this.width + " × " + this.height + } + function p(a, b, c, d, e, f) { + function g(a) { + return ((l * a + k) * a + j) * a + } + function h(a, b) { + var c = i(a, b); + return ((o * c + n) * c + m) * c + } + function i(a, b) { + var c, + d, + e, + f, + h, + i; + for (e = a, i = 0; 8 > i; i++) { + if (f = g(e) - a, P(f) < b) + return e; + if (h = (3 * l * e + 2 * k) * e + j, P(h) < 1e-6) + break; + e -= f / h + } + if (c = 0, d = 1, e = a, c > e) + return c; + if (e > d) + return d; + for (; d > c; ) { + if (f = g(e), P(f - a) < b) + return e; + a > f ? c = e : d = e, + e = (d - c) / 2 + c + } + return e + } + var j = 3 * b, + k = 3 * (d - b) - j, + l = 1 - j - k, + m = 3 * c, + n = 3 * (e - c) - m, + o = 1 - m - n; + return h(a, 1 / (200 * f)) + } + function q(a, b) { + var c = [], + d = {}; + if (this.ms = b, this.times = 1, a) { + for (var e in a) + a[y](e) && (d[$(e)] = a[e], c.push($(e))); + c.sort(ka) + } + this.anim = d, + this.top = c[c.length - 1], + this.percents = c + } + function r(c, d, e, f, g, h) { + e = $(e); + var i, + j, + k, + l, + m, + o, + q = c.ms, + r = {}, + s = {}, + t = {}; + if (f) + for (w = 0, x = fb.length; x > w; w++) { + var u = fb[w]; + if (u.el.id == d.id && u.anim == c) { + u.percent != e ? (fb.splice(w, 1), k = 1) : j = u, + d.attr(u.totalOrigin); + break + } + } + else + f = +s; + for (var w = 0, x = c.percents.length; x > w; w++) { + if (c.percents[w] == e || c.percents[w] > f * c.top) { + e = c.percents[w], + m = c.percents[w - 1] || 0, + q = q / c.top * (e - m), + l = c.percents[w + 1], + i = c.anim[e]; + break + } + f && d.attr(c.anim[c.percents[w]]) + } + if (i) { + if (j) + j.initstatus = f, j.start = new Date - j.ms * f; + else { + for (var z in i) + if (i[y](z) && (ca[y](z) || d.paper.customAttributes[y](z))) + switch (r[z] = d.attr(z), null == r[z] && (r[z] = ba[z]), s[z] = i[z], ca[z]) { + case S: + t[z] = (s[z] - r[z]) / q; + break; + case "colour": + r[z] = b.getRGB(r[z]); + var A = b.getRGB(s[z]); + t[z] = { + r: (A.r - r[z].r) / q, + g: (A.g - r[z].g) / q, + b: (A.b - r[z].b) / q + }; + break; + case "path": + var B = Ia(r[z], s[z]), + C = B[1]; + for (r[z] = B[0], t[z] = [], w = 0, x = r[z].length; x > w; w++) { + t[z][w] = [0]; + for (var E = 1, F = r[z][w].length; F > E; E++) + t[z][w][E] = (C[w][E] - r[z][w][E]) / q + } + break; + case "transform": + var G = d._, + J = Na(G[z], s[z]); + if (J) + for (r[z] = J.from, s[z] = J.to, t[z] = [], t[z].real = !0, w = 0, x = r[z].length; x > w; w++) + for (t[z][w] = [r[z][w][0]], E = 1, F = r[z][w].length; F > E; E++) + t[z][w][E] = (s[z][w][E] - r[z][w][E]) / q; + else { + var K = d.matrix || new n, + L = { + _: { + transform: G.transform + }, + getBBox: function () { + return d.getBBox(1) + } + }; + r[z] = [K.a, K.b, K.c, K.d, K.e, K.f], + La(L, s[z]), + s[z] = L._.transform, + t[z] = [(L.matrix.a - K.a) / q, (L.matrix.b - K.b) / q, (L.matrix.c - K.c) / q, (L.matrix.d - K.d) / q, (L.matrix.e - K.e) / q, (L.matrix.f - K.f) / q] + } + break; + case "csv": + var M = H(i[z])[I](v), + N = H(r[z])[I](v); + if ("clip-rect" == z) + for (r[z] = N, t[z] = [], w = N.length; w--; ) + t[z][w] = (M[w] - r[z][w]) / q; + s[z] = M; + break; + default: + for (M = [][D](i[z]), N = [][D](r[z]), t[z] = [], w = d.paper.customAttributes[z].length; w--; ) + t[z][w] = ((M[w] || 0) - (N[w] || 0)) / q + } + var O = i.easing, + P = b.easing_formulas[O]; + if (!P) + if (P = H(O).match(Y), P && 5 == P.length) { + var Q = P; + P = function (a) { + return p(a, +Q[1], +Q[2], +Q[3], +Q[4], q) + } + } else + P = la; + if (o = i.start || c.start || +new Date, u = { + anim: c, + percent: e, + timestamp: o, + start: o + (c.del || 0), + status: 0, + initstatus: f || 0, + stop: !1, + ms: q, + easing: P, + from: r, + diff: t, + to: s, + el: d, + callback: i.callback, + prev: m, + next: l, + repeat: h || c.times, + origin: d.attr(), + totalOrigin: g + }, fb.push(u), f && !j && !k && (u.stop = !0, u.start = new Date - q * f, 1 == fb.length)) + return hb(); + k && (u.start = new Date - u.ms * f), + 1 == fb.length && gb(hb) + } + a("raphael.anim.start." + d.id, d, c) + } + } + function s(a) { + for (var b = 0; b < fb.length; b++) + fb[b].el.paper == a && fb.splice(b--, 1) + } + b.version = "2.1.4", + b.eve = a; + var t, + u, + v = /[, ]+/, + w = { + circle: 1, + rect: 1, + path: 1, + ellipse: 1, + text: 1, + image: 1 + }, + x = /\{(\d+)\}/g, + y = "hasOwnProperty", + z = { + doc: document, + win: window + }, + A = { + was: Object.prototype[y].call(z.win, "Raphael"), + is: z.win.Raphael + }, + B = function () { + this.ca = this.customAttributes = {} + }, + C = "apply", + D = "concat", + E = "ontouchstart" in z.win || z.win.DocumentTouch && z.doc instanceof DocumentTouch, + F = "", + G = " ", + H = String, + I = "split", + J = "click dblclick mousedown mousemove mouseout mouseover mouseup touchstart touchmove touchend touchcancel"[I](G), + K = { + mousedown: "touchstart", + mousemove: "touchmove", + mouseup: "touchend" + }, + L = H.prototype.toLowerCase, + M = Math, + N = M.max, + O = M.min, + P = M.abs, + Q = M.pow, + R = M.PI, + S = "number", + T = "string", + U = "array", + V = Object.prototype.toString, + W = (b._ISURL = /^url\(['"]?(.+?)['"]?\)$/i, /^\s*((#[a-f\d]{6})|(#[a-f\d]{3})|rgba?\(\s*([\d\.]+%?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+%?(?:\s*,\s*[\d\.]+%?)?)\s*\)|hsba?\(\s*([\d\.]+(?:deg|\xb0|%)?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+(?:%?\s*,\s*[\d\.]+)?)%?\s*\)|hsla?\(\s*([\d\.]+(?:deg|\xb0|%)?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+(?:%?\s*,\s*[\d\.]+)?)%?\s*\))\s*$/i), + X = { + NaN: 1, + Infinity: 1, + "-Infinity": 1 + }, + Y = /^(?:cubic-)?bezier\(([^,]+),([^,]+),([^,]+),([^\)]+)\)/, + Z = M.round, + $ = parseFloat, + _ = parseInt, + aa = H.prototype.toUpperCase, + ba = b._availableAttrs = { + "arrow-end": "none", + "arrow-start": "none", + blur: 0, + "clip-rect": "0 0 1e9 1e9", + cursor: "default", + cx: 0, + cy: 0, + fill: "#fff", + "fill-opacity": 1, + font: '10px "Arial"', + "font-family": '"Arial"', + "font-size": "10", + "font-style": "normal", + "font-weight": 400, + gradient: 0, + height: 0, + href: "http://raphaeljs.com/", + "letter-spacing": 0, + opacity: 1, + path: "M0,0", + r: 0, + rx: 0, + ry: 0, + src: "", + stroke: "#000", + "stroke-dasharray": "", + "stroke-linecap": "butt", + "stroke-linejoin": "butt", + "stroke-miterlimit": 0, + "stroke-opacity": 1, + "stroke-width": 1, + target: "_blank", + "text-anchor": "middle", + title: "Raphael", + transform: "", + width: 0, + x: 0, + y: 0 + }, + ca = b._availableAnimAttrs = { + blur: S, + "clip-rect": "csv", + cx: S, + cy: S, + fill: "colour", + "fill-opacity": S, + "font-size": S, + height: S, + opacity: S, + path: "path", + r: S, + rx: S, + ry: S, + stroke: "colour", + "stroke-opacity": S, + "stroke-width": S, + transform: "transform", + width: S, + x: S, + y: S + }, + da = /[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029]*,[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029]*/, + ea = { + hs: 1, + rg: 1 + }, + fa = /,?([achlmqrstvxz]),?/gi, + ga = /([achlmrqstvz])[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029,]*((-?\d*\.?\d*(?:e[\-+]?\d+)?[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029]*,?[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029]*)+)/gi, + ha = /([rstm])[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029,]*((-?\d*\.?\d*(?:e[\-+]?\d+)?[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029]*,?[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029]*)+)/gi, + ia = /(-?\d*\.?\d*(?:e[\-+]?\d+)?)[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029]*,?[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029]*/gi, + ja = (b._radial_gradient = /^r(?:\(([^,]+?)[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029]*,[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029]*([^\)]+?)\))?/, {}), + ka = function (a, b) { + return $(a) - $(b) + }, + la = function (a) { + return a + }, + ma = b._rectPath = function (a, b, c, d, e) { + return e ? [["M", a + e, b], ["l", c - 2 * e, 0], ["a", e, e, 0, 0, 1, e, e], ["l", 0, d - 2 * e], ["a", e, e, 0, 0, 1, -e, e], ["l", 2 * e - c, 0], ["a", e, e, 0, 0, 1, -e, -e], ["l", 0, 2 * e - d], ["a", e, e, 0, 0, 1, e, -e], ["z"]] : [["M", a, b], ["l", c, 0], ["l", 0, d], ["l", -c, 0], ["z"]] + }, + na = function (a, b, c, d) { + return null == d && (d = c), + [["M", a, b], ["m", 0, -d], ["a", c, d, 0, 1, 1, 0, 2 * d], ["a", c, d, 0, 1, 1, 0, -2 * d], ["z"]] + }, + oa = b._getPath = { + path: function (a) { + return a.attr("path") + }, + circle: function (a) { + var b = a.attrs; + return na(b.cx, b.cy, b.r) + }, + ellipse: function (a) { + var b = a.attrs; + return na(b.cx, b.cy, b.rx, b.ry) + }, + rect: function (a) { + var b = a.attrs; + return ma(b.x, b.y, b.width, b.height, b.r) + }, + image: function (a) { + var b = a.attrs; + return ma(b.x, b.y, b.width, b.height) + }, + text: function (a) { + var b = a._getBBox(); + return ma(b.x, b.y, b.width, b.height) + }, + set: function (a) { + var b = a._getBBox(); + return ma(b.x, b.y, b.width, b.height) + } + }, + pa = b.mapPath = function (a, b) { + if (!b) + return a; + var c, + d, + e, + f, + g, + h, + i; + for (a = Ia(a), e = 0, g = a.length; g > e; e++) + for (i = a[e], f = 1, h = i.length; h > f; f += 2) + c = b.x(i[f], i[f + 1]), d = b.y(i[f], i[f + 1]), i[f] = c, i[f + 1] = d; + return a + }; + if (b._g = z, b.type = z.win.SVGAngle || z.doc.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1") ? "SVG" : "VML", "VML" == b.type) { + var qa, + ra = z.doc.createElement("div"); + if (ra.innerHTML = '', qa = ra.firstChild, qa.style.behavior = "url(#default#VML)", !qa || "object" != typeof qa.adj) + return b.type = F; + ra = null + } + b.svg = !(b.vml = "VML" == b.type), + b._Paper = B, + b.fn = u = B.prototype = b.prototype, + b._id = 0, + b._oid = 0, + b.is = function (a, b) { + return b = L.call(b), + "finite" == b ? !X[y](+a) : "array" == b ? a instanceof Array : "null" == b && null === a || b == typeof a && null !== a || "object" == b && a === Object(a) || "array" == b && Array.isArray && Array.isArray(a) || V.call(a).slice(8, -1).toLowerCase() == b + }, + b.angle = function (a, c, d, e, f, g) { + if (null == f) { + var h = a - d, + i = c - e; + return h || i ? (180 + 180 * M.atan2(-i, -h) / R + 360) % 360 : 0 + } + return b.angle(a, c, f, g) - b.angle(d, e, f, g) + }, + b.rad = function (a) { + return a % 360 * R / 180 + }, + b.deg = function (a) { + return Math.round(180 * a / R % 360 * 1e3) / 1e3 + }, + b.snapTo = function (a, c, d) { + if (d = b.is(d, "finite") ? d : 10, b.is(a, U)) { + for (var e = a.length; e--; ) + if (P(a[e] - c) <= d) + return a[e] + } else { + a = +a; + var f = c % a; + if (d > f) + return c - f; + if (f > a - d) + return c - f + a + } + return c + }; + b.createUUID = function (a, b) { + return function () { + return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(a, b).toUpperCase() + } + } + (/[xy]/g, function (a) { + var b = 16 * M.random() | 0, + c = "x" == a ? b : 3 & b | 8; + return c.toString(16) + }); + b.setWindow = function (c) { + a("raphael.setWindow", b, z.win, c), + z.win = c, + z.doc = z.win.document, + b._engine.initWin && b._engine.initWin(z.win) + }; + var sa = function (a) { + if (b.vml) { + var c, + d = /^\s+|\s+$/g; + try { + var f = new ActiveXObject("htmlfile"); + f.write(""), + f.close(), + c = f.body + } catch (g) { + c = createPopup().document.body + } + var h = c.createTextRange(); + sa = e(function (a) { + try { + c.style.color = H(a).replace(d, F); + var b = h.queryCommandValue("ForeColor"); + return b = (255 & b) << 16 | 65280 & b | (16711680 & b) >>> 16, + "#" + ("000000" + b.toString(16)).slice(-6) + } catch (e) { + return "none" + } + }) + } else { + var i = z.doc.createElement("i"); + i.title = "Raphaël Colour Picker", + i.style.display = "none", + z.doc.body.appendChild(i), + sa = e(function (a) { + return i.style.color = a, + z.doc.defaultView.getComputedStyle(i, F).getPropertyValue("color") + }) + } + return sa(a) + }, + ta = function () { + return "hsb(" + [this.h, this.s, this.b] + ")" + }, + ua = function () { + return "hsl(" + [this.h, this.s, this.l] + ")" + }, + va = function () { + return this.hex + }, + wa = function (a, c, d) { + if (null == c && b.is(a, "object") && "r" in a && "g" in a && "b" in a && (d = a.b, c = a.g, a = a.r), null == c && b.is(a, T)) { + var e = b.getRGB(a); + a = e.r, + c = e.g, + d = e.b + } + return (a > 1 || c > 1 || d > 1) && (a /= 255, c /= 255, d /= 255), + [a, c, d] + }, + xa = function (a, c, d, e) { + a *= 255, + c *= 255, + d *= 255; + var f = { + r: a, + g: c, + b: d, + hex: b.rgb(a, c, d), + toString: va + }; + return b.is(e, "finite") && (f.opacity = e), + f + }; + b.color = function (a) { + var c; + return b.is(a, "object") && "h" in a && "s" in a && "b" in a ? (c = b.hsb2rgb(a), a.r = c.r, a.g = c.g, a.b = c.b, a.hex = c.hex) : b.is(a, "object") && "h" in a && "s" in a && "l" in a ? (c = b.hsl2rgb(a), a.r = c.r, a.g = c.g, a.b = c.b, a.hex = c.hex) : (b.is(a, "string") && (a = b.getRGB(a)), b.is(a, "object") && "r" in a && "g" in a && "b" in a ? (c = b.rgb2hsl(a), a.h = c.h, a.s = c.s, a.l = c.l, c = b.rgb2hsb(a), a.v = c.b) : (a = { + hex: "none" + }, a.r = a.g = a.b = a.h = a.s = a.v = a.l = -1)), + a.toString = va, + a + }, + b.hsb2rgb = function (a, b, c, d) { + this.is(a, "object") && "h" in a && "s" in a && "b" in a && (c = a.b, b = a.s, d = a.o, a = a.h), + a *= 360; + var e, + f, + g, + h, + i; + return a = a % 360 / 60, + i = c * b, + h = i * (1 - P(a % 2 - 1)), + e = f = g = c - i, + a = ~~a, + e += [i, h, 0, 0, h, i][a], + f += [h, i, i, h, 0, 0][a], + g += [0, 0, h, i, i, h][a], + xa(e, f, g, d) + }, + b.hsl2rgb = function (a, b, c, d) { + this.is(a, "object") && "h" in a && "s" in a && "l" in a && (c = a.l, b = a.s, a = a.h), + (a > 1 || b > 1 || c > 1) && (a /= 360, b /= 100, c /= 100), + a *= 360; + var e, + f, + g, + h, + i; + return a = a % 360 / 60, + i = 2 * b * (.5 > c ? c : 1 - c), + h = i * (1 - P(a % 2 - 1)), + e = f = g = c - i / 2, + a = ~~a, + e += [i, h, 0, 0, h, i][a], + f += [h, i, i, h, 0, 0][a], + g += [0, 0, h, i, i, h][a], + xa(e, f, g, d) + }, + b.rgb2hsb = function (a, b, c) { + c = wa(a, b, c), + a = c[0], + b = c[1], + c = c[2]; + var d, + e, + f, + g; + return f = N(a, b, c), + g = f - O(a, b, c), + d = 0 == g ? null : f == a ? (b - c) / g : f == b ? (c - a) / g + 2 : (a - b) / g + 4, + d = (d + 360) % 6 * 60 / 360, + e = 0 == g ? 0 : g / f, { + h: d, + s: e, + b: f, + toString: ta + } + }, + b.rgb2hsl = function (a, b, c) { + c = wa(a, b, c), + a = c[0], + b = c[1], + c = c[2]; + var d, + e, + f, + g, + h, + i; + return g = N(a, b, c), + h = O(a, b, c), + i = g - h, + d = 0 == i ? null : g == a ? (b - c) / i : g == b ? (c - a) / i + 2 : (a - b) / i + 4, + d = (d + 360) % 6 * 60 / 360, + f = (g + h) / 2, + e = 0 == i ? 0 : .5 > f ? i / (2 * f) : i / (2 - 2 * f), { + h: d, + s: e, + l: f, + toString: ua + } + }, + b._path2string = function () { + return this.join(",").replace(fa, "$1") + }; + b._preload = function (a, b) { + var c = z.doc.createElement("img"); + c.style.cssText = "position:absolute;left:-9999em;top:-9999em", + c.onload = function () { + b.call(this), + this.onload = null, + z.doc.body.removeChild(this) + }, + c.onerror = function () { + z.doc.body.removeChild(this) + }, + z.doc.body.appendChild(c), + c.src = a + }; + b.getRGB = e(function (a) { + if (!a || (a = H(a)).indexOf("-") + 1) + return { + r: -1, + g: -1, + b: -1, + hex: "none", + error: 1, + toString: f + }; + if ("none" == a) + return { + r: -1, + g: -1, + b: -1, + hex: "none", + toString: f + }; + !(ea[y](a.toLowerCase().substring(0, 2)) || "#" == a.charAt()) && (a = sa(a)); + var c, + d, + e, + g, + h, + i, + j = a.match(W); + return j ? (j[2] && (e = _(j[2].substring(5), 16), d = _(j[2].substring(3, 5), 16), c = _(j[2].substring(1, 3), 16)), j[3] && (e = _((h = j[3].charAt(3)) + h, 16), d = _((h = j[3].charAt(2)) + h, 16), c = _((h = j[3].charAt(1)) + h, 16)), j[4] && (i = j[4][I](da), c = $(i[0]), "%" == i[0].slice(-1) && (c *= 2.55), d = $(i[1]), "%" == i[1].slice(-1) && (d *= 2.55), e = $(i[2]), "%" == i[2].slice(-1) && (e *= 2.55), "rgba" == j[1].toLowerCase().slice(0, 4) && (g = $(i[3])), i[3] && "%" == i[3].slice(-1) && (g /= 100)), j[5] ? (i = j[5][I](da), c = $(i[0]), "%" == i[0].slice(-1) && (c *= 2.55), d = $(i[1]), "%" == i[1].slice(-1) && (d *= 2.55), e = $(i[2]), "%" == i[2].slice(-1) && (e *= 2.55), ("deg" == i[0].slice(-3) || "°" == i[0].slice(-1)) && (c /= 360), "hsba" == j[1].toLowerCase().slice(0, 4) && (g = $(i[3])), i[3] && "%" == i[3].slice(-1) && (g /= 100), b.hsb2rgb(c, d, e, g)) : j[6] ? (i = j[6][I](da), c = $(i[0]), "%" == i[0].slice(-1) && (c *= 2.55), d = $(i[1]), "%" == i[1].slice(-1) && (d *= 2.55), e = $(i[2]), "%" == i[2].slice(-1) && (e *= 2.55), ("deg" == i[0].slice(-3) || "°" == i[0].slice(-1)) && (c /= 360), "hsla" == j[1].toLowerCase().slice(0, 4) && (g = $(i[3])), i[3] && "%" == i[3].slice(-1) && (g /= 100), b.hsl2rgb(c, d, e, g)) : (j = { + r: c, + g: d, + b: e, + toString: f + }, j.hex = "#" + (16777216 | e | d << 8 | c << 16).toString(16).slice(1), b.is(g, "finite") && (j.opacity = g), j)) : { + r: -1, + g: -1, + b: -1, + hex: "none", + error: 1, + toString: f + } + }, b), + b.hsb = e(function (a, c, d) { + return b.hsb2rgb(a, c, d).hex + }), + b.hsl = e(function (a, c, d) { + return b.hsl2rgb(a, c, d).hex + }), + b.rgb = e(function (a, b, c) { + function d(a) { + return a + .5 | 0 + } + return "#" + (16777216 | d(c) | d(b) << 8 | d(a) << 16).toString(16).slice(1) + }), + b.getColor = function (a) { + var b = this.getColor.start = this.getColor.start || { + h: 0, + s: 1, + b: a || .75 + }, + c = this.hsb2rgb(b.h, b.s, b.b); + return b.h += .075, + b.h > 1 && (b.h = 0, b.s -= .2, b.s <= 0 && (this.getColor.start = { + h: 0, + s: 1, + b: b.b + })), + c.hex + }, + b.getColor.reset = function () { + delete this.start + }, + b.parsePathString = function (a) { + if (!a) + return null; + var c = ya(a); + if (c.arr) + return Aa(c.arr); + var d = { + a: 7, + c: 6, + h: 1, + l: 2, + m: 2, + r: 4, + q: 4, + s: 4, + t: 2, + v: 1, + z: 0 + }, + e = []; + return b.is(a, U) && b.is(a[0], U) && (e = Aa(a)), + e.length || H(a).replace(ga, function (a, b, c) { + var f = [], + g = b.toLowerCase(); + if (c.replace(ia, function (a, b) { + b && f.push(+b) + }), "m" == g && f.length > 2 && (e.push([b][D](f.splice(0, 2))), g = "l", b = "m" == b ? "l" : "L"), "r" == g) + e.push([b][D](f)); + else + for (; f.length >= d[g] && (e.push([b][D](f.splice(0, d[g]))), d[g]); ); + }), + e.toString = b._path2string, + c.arr = Aa(e), + e + }, + b.parseTransformString = e(function (a) { + if (!a) + return null; + var c = []; + return b.is(a, U) && b.is(a[0], U) && (c = Aa(a)), + c.length || H(a).replace(ha, function (a, b, d) { { + var e = []; + L.call(b) + } + d.replace(ia, function (a, b) { + b && e.push(+b) + }), + c.push([b][D](e)) + }), + c.toString = b._path2string, + c + }); + var ya = function (a) { + var b = ya.ps = ya.ps || {}; + return b[a] ? b[a].sleep = 100 : b[a] = { + sleep: 100 + }, + setTimeout(function () { + for (var c in b) + b[y](c) && c != a && (b[c].sleep--, !b[c].sleep && delete b[c]) + }), + b[a] + }; + b.findDotsAtSegment = function (a, b, c, d, e, f, g, h, i) { + var j = 1 - i, + k = Q(j, 3), + l = Q(j, 2), + m = i * i, + n = m * i, + o = k * a + 3 * l * i * c + 3 * j * i * i * e + n * g, + p = k * b + 3 * l * i * d + 3 * j * i * i * f + n * h, + q = a + 2 * i * (c - a) + m * (e - 2 * c + a), + r = b + 2 * i * (d - b) + m * (f - 2 * d + b), + s = c + 2 * i * (e - c) + m * (g - 2 * e + c), + t = d + 2 * i * (f - d) + m * (h - 2 * f + d), + u = j * a + i * c, + v = j * b + i * d, + w = j * e + i * g, + x = j * f + i * h, + y = 90 - 180 * M.atan2(q - s, r - t) / R; + return (q > s || t > r) && (y += 180), { + x: o, + y: p, + m: { + x: q, + y: r + }, + n: { + x: s, + y: t + }, + start: { + x: u, + y: v + }, + end: { + x: w, + y: x + }, + alpha: y + } + }, + b.bezierBBox = function (a, c, d, e, f, g, h, i) { + b.is(a, "array") || (a = [a, c, d, e, f, g, h, i]); + var j = Ha.apply(null, a); + return { + x: j.min.x, + y: j.min.y, + x2: j.max.x, + y2: j.max.y, + width: j.max.x - j.min.x, + height: j.max.y - j.min.y + } + }, + b.isPointInsideBBox = function (a, b, c) { + return b >= a.x && b <= a.x2 && c >= a.y && c <= a.y2 + }, + b.isBBoxIntersect = function (a, c) { + var d = b.isPointInsideBBox; + return d(c, a.x, a.y) || d(c, a.x2, a.y) || d(c, a.x, a.y2) || d(c, a.x2, a.y2) || d(a, c.x, c.y) || d(a, c.x2, c.y) || d(a, c.x, c.y2) || d(a, c.x2, c.y2) || (a.x < c.x2 && a.x > c.x || c.x < a.x2 && c.x > a.x) && (a.y < c.y2 && a.y > c.y || c.y < a.y2 && c.y > a.y) + }, + b.pathIntersection = function (a, b) { + return m(a, b) + }, + b.pathIntersectionNumber = function (a, b) { + return m(a, b, 1) + }, + b.isPointInsidePath = function (a, c, d) { + var e = b.pathBBox(a); + return b.isPointInsideBBox(e, c, d) && m(a, [["M", c, d], ["H", e.x2 + 10]], 1) % 2 == 1 + }, + b._removedFactory = function (b) { + return function () { + a("raphael.log", null, "Raphaël: you are calling to method “" + b + "” of removed object", b) + } + }; + var za = b.pathBBox = function (a) { + var b = ya(a); + if (b.bbox) + return c(b.bbox); + if (!a) + return { + x: 0, + y: 0, + width: 0, + height: 0, + x2: 0, + y2: 0 + }; + a = Ia(a); + for (var d, e = 0, f = 0, g = [], h = [], i = 0, j = a.length; j > i; i++) + if (d = a[i], "M" == d[0]) + e = d[1], f = d[2], g.push(e), h.push(f); + else { + var k = Ha(e, f, d[1], d[2], d[3], d[4], d[5], d[6]); + g = g[D](k.min.x, k.max.x), + h = h[D](k.min.y, k.max.y), + e = d[5], + f = d[6] + } + var l = O[C](0, g), + m = O[C](0, h), + n = N[C](0, g), + o = N[C](0, h), + p = n - l, + q = o - m, + r = { + x: l, + y: m, + x2: n, + y2: o, + width: p, + height: q, + cx: l + p / 2, + cy: m + q / 2 + }; + return b.bbox = c(r), + r + }, + Aa = function (a) { + var d = c(a); + return d.toString = b._path2string, + d + }, + Ba = b._pathToRelative = function (a) { + var c = ya(a); + if (c.rel) + return Aa(c.rel); + b.is(a, U) && b.is(a && a[0], U) || (a = b.parsePathString(a)); + var d = [], + e = 0, + f = 0, + g = 0, + h = 0, + i = 0; + "M" == a[0][0] && (e = a[0][1], f = a[0][2], g = e, h = f, i++, d.push(["M", e, f])); + for (var j = i, k = a.length; k > j; j++) { + var l = d[j] = [], + m = a[j]; + if (m[0] != L.call(m[0])) + switch (l[0] = L.call(m[0]), l[0]) { + case "a": + l[1] = m[1], + l[2] = m[2], + l[3] = m[3], + l[4] = m[4], + l[5] = m[5], + l[6] = + (m[6] - e).toFixed(3), + l[7] = + (m[7] - f).toFixed(3); + break; + case "v": + l[1] = + (m[1] - f).toFixed(3); + break; + case "m": + g = m[1], + h = m[2]; + default: + for (var n = 1, o = m.length; o > n; n++) + l[n] = + (m[n] - (n % 2 ? e : f)).toFixed(3) + } + else { + l = d[j] = [], + "m" == m[0] && (g = m[1] + e, h = m[2] + f); + for (var p = 0, q = m.length; q > p; p++) + d[j][p] = m[p] + } + var r = d[j].length; + switch (d[j][0]) { + case "z": + e = g, + f = h; + break; + case "h": + e += +d[j][r - 1]; + break; + case "v": + f += +d[j][r - 1]; + break; + default: + e += +d[j][r - 2], + f += +d[j][r - 1] + } + } + return d.toString = b._path2string, + c.rel = Aa(d), + d + }, + Ca = b._pathToAbsolute = function (a) { + var c = ya(a); + if (c.abs) + return Aa(c.abs); + if (b.is(a, U) && b.is(a && a[0], U) || (a = b.parsePathString(a)), !a || !a.length) + return [["M", 0, 0]]; + var d = [], + e = 0, + f = 0, + h = 0, + i = 0, + j = 0; + "M" == a[0][0] && (e = +a[0][1], f = +a[0][2], h = e, i = f, j++, d[0] = ["M", e, f]); + for (var k, l, m = 3 == a.length && "M" == a[0][0] && "R" == a[1][0].toUpperCase() && "Z" == a[2][0].toUpperCase(), n = j, o = a.length; o > n; n++) { + if (d.push(k = []), l = a[n], l[0] != aa.call(l[0])) + switch (k[0] = aa.call(l[0]), k[0]) { + case "A": + k[1] = l[1], + k[2] = l[2], + k[3] = l[3], + k[4] = l[4], + k[5] = l[5], + k[6] = + (l[6] + e), + k[7] = + (l[7] + f); + break; + case "V": + k[1] = +l[1] + f; + break; + case "H": + k[1] = +l[1] + e; + break; + case "R": + for (var p = [e, f][D](l.slice(1)), q = 2, r = p.length; r > q; q++) + p[q] = +p[q] + e, p[++q] = +p[q] + f; + d.pop(), + d = d[D](g(p, m)); + break; + case "M": + h = +l[1] + e, + i = +l[2] + f; + default: + for (q = 1, r = l.length; r > q; q++) + k[q] = +l[q] + (q % 2 ? e : f) + } + else if ("R" == l[0]) + p = [e, f][D](l.slice(1)), d.pop(), d = d[D](g(p, m)), k = ["R"][D](l.slice(-2)); + else + for (var s = 0, t = l.length; t > s; s++) + k[s] = l[s]; + switch (k[0]) { + case "Z": + e = h, + f = i; + break; + case "H": + e = k[1]; + break; + case "V": + f = k[1]; + break; + case "M": + h = k[k.length - 2], + i = k[k.length - 1]; + default: + e = k[k.length - 2], + f = k[k.length - 1] + } + } + return d.toString = b._path2string, + c.abs = Aa(d), + d + }, + Da = function (a, b, c, d) { + return [a, b, c, d, c, d] + }, + Ea = function (a, b, c, d, e, f) { + var g = 1 / 3, + h = 2 / 3; + return [g * a + h * c, g * b + h * d, g * e + h * c, g * f + h * d, e, f] + }, + Fa = function (a, b, c, d, f, g, h, i, j, k) { + var l, + m = 120 * R / 180, + n = R / 180 * (+f || 0), + o = [], + p = e(function (a, b, c) { + var d = a * M.cos(c) - b * M.sin(c), + e = a * M.sin(c) + b * M.cos(c); + return { + x: d, + y: e + } + }); + if (k) + y = k[0], z = k[1], w = k[2], x = k[3]; + else { + l = p(a, b, -n), + a = l.x, + b = l.y, + l = p(i, j, -n), + i = l.x, + j = l.y; + var q = (M.cos(R / 180 * f), M.sin(R / 180 * f), (a - i) / 2), + r = (b - j) / 2, + s = q * q / (c * c) + r * r / (d * d); + s > 1 && (s = M.sqrt(s), c = s * c, d = s * d); + var t = c * c, + u = d * d, + v = (g == h ? -1 : 1) * M.sqrt(P((t * u - t * r * r - u * q * q) / (t * r * r + u * q * q))), + w = v * c * r / d + (a + i) / 2, + x = v * -d * q / c + (b + j) / 2, + y = M.asin(((b - x) / d).toFixed(9)), + z = M.asin(((j - x) / d).toFixed(9)); + y = w > a ? R - y : y, + z = w > i ? R - z : z, + 0 > y && (y = 2 * R + y), + 0 > z && (z = 2 * R + z), + h && y > z && (y -= 2 * R), + !h && z > y && (z -= 2 * R) + } + var A = z - y; + if (P(A) > m) { + var B = z, + C = i, + E = j; + z = y + m * (h && z > y ? 1 : -1), + i = w + c * M.cos(z), + j = x + d * M.sin(z), + o = Fa(i, j, c, d, f, 0, h, C, E, [z, B, w, x]) + } + A = z - y; + var F = M.cos(y), + G = M.sin(y), + H = M.cos(z), + J = M.sin(z), + K = M.tan(A / 4), + L = 4 / 3 * c * K, + N = 4 / 3 * d * K, + O = [a, b], + Q = [a + L * G, b - N * F], + S = [i + L * J, j - N * H], + T = [i, j]; + if (Q[0] = 2 * O[0] - Q[0], Q[1] = 2 * O[1] - Q[1], k) + return [Q, S, T][D](o); + o = [Q, S, T][D](o).join()[I](","); + for (var U = [], V = 0, W = o.length; W > V; V++) + U[V] = V % 2 ? p(o[V - 1], o[V], n).y : p(o[V], o[V + 1], n).x; + return U + }, + Ga = function (a, b, c, d, e, f, g, h, i) { + var j = 1 - i; + return { + x: Q(j, 3) * a + 3 * Q(j, 2) * i * c + 3 * j * i * i * e + Q(i, 3) * g, + y: Q(j, 3) * b + 3 * Q(j, 2) * i * d + 3 * j * i * i * f + Q(i, 3) * h + } + }, + Ha = e(function (a, b, c, d, e, f, g, h) { + var i, + j = e - 2 * c + a - (g - 2 * e + c), + k = 2 * (c - a) - 2 * (e - c), + l = a - c, + m = (-k + M.sqrt(k * k - 4 * j * l)) / 2 / j, + n = (-k - M.sqrt(k * k - 4 * j * l)) / 2 / j, + o = [b, h], + p = [a, g]; + return P(m) > "1e12" && (m = .5), + P(n) > "1e12" && (n = .5), + m > 0 && 1 > m && (i = Ga(a, b, c, d, e, f, g, h, m), p.push(i.x), o.push(i.y)), + n > 0 && 1 > n && (i = Ga(a, b, c, d, e, f, g, h, n), p.push(i.x), o.push(i.y)), + j = f - 2 * d + b - (h - 2 * f + d), + k = 2 * (d - b) - 2 * (f - d), + l = b - d, + m = (-k + M.sqrt(k * k - 4 * j * l)) / 2 / j, + n = (-k - M.sqrt(k * k - 4 * j * l)) / 2 / j, + P(m) > "1e12" && (m = .5), + P(n) > "1e12" && (n = .5), + m > 0 && 1 > m && (i = Ga(a, b, c, d, e, f, g, h, m), p.push(i.x), o.push(i.y)), + n > 0 && 1 > n && (i = Ga(a, b, c, d, e, f, g, h, n), p.push(i.x), o.push(i.y)), { + min: { + x: O[C](0, p), + y: O[C](0, o) + }, + max: { + x: N[C](0, p), + y: N[C](0, o) + } + } + }), + Ia = b._path2curve = e(function (a, b) { + var c = !b && ya(a); + if (!b && c.curve) + return Aa(c.curve); + for (var d = Ca(a), e = b && Ca(b), f = { + x: 0, + y: 0, + bx: 0, + by: 0, + X: 0, + Y: 0, + qx: null, + qy: null + }, g = { + x: 0, + y: 0, + bx: 0, + by: 0, + X: 0, + Y: 0, + qx: null, + qy: null + }, h = (function (a, b, c) { + var d, + e, + f = { + T: 1, + Q: 1 + }; + if (!a) + return ["C", b.x, b.y, b.x, b.y, b.x, b.y]; + switch (!(a[0]in f) && (b.qx = b.qy = null), a[0]) { + case "M": + b.X = a[1], + b.Y = a[2]; + break; + case "A": + a = ["C"][D](Fa[C](0, [b.x, b.y][D](a.slice(1)))); + break; + case "S": + "C" == c || "S" == c ? (d = 2 * b.x - b.bx, e = 2 * b.y - b.by) : (d = b.x, e = b.y), + a = ["C", d, e][D](a.slice(1)); + break; + case "T": + "Q" == c || "T" == c ? (b.qx = 2 * b.x - b.qx, b.qy = 2 * b.y - b.qy) : (b.qx = b.x, b.qy = b.y), + a = ["C"][D](Ea(b.x, b.y, b.qx, b.qy, a[1], a[2])); + break; + case "Q": + b.qx = a[1], + b.qy = a[2], + a = ["C"][D](Ea(b.x, b.y, a[1], a[2], a[3], a[4])); + break; + case "L": + a = ["C"][D](Da(b.x, b.y, a[1], a[2])); + break; + case "H": + a = ["C"][D](Da(b.x, b.y, a[1], b.y)); + break; + case "V": + a = ["C"][D](Da(b.x, b.y, b.x, a[1])); + break; + case "Z": + a = ["C"][D](Da(b.x, b.y, b.X, b.Y)) + } + return a + }), i = function (a, b) { + if (a[b].length > 7) { + a[b].shift(); + for (var c = a[b]; c.length; ) + k[b] = "A", e && (l[b] = "A") , a.splice(b++, 0, ["C"][D](c.splice(0, 6))); + a.splice(b, 1), + p = N(d.length, e && e.length || 0) + } + }, j = function (a, b, c, f, g) { + a && b && "M" == a[g][0] && "M" != b[g][0] && (b.splice(g, 0, ["M", f.x, f.y]), c.bx = 0, c.by = 0, c.x = a[g][1], c.y = a[g][2], p = N(d.length, e && e.length || 0)) + }, k = [], l = [], m = "", n = "", o = 0, p = N(d.length, e && e.length || 0); p > o; o++) { + d[o] && (m = d[o][0]), + "C" != m && (k[o] = m, o && (n = k[o - 1])), + d[o] = h(d[o], f, n), + "A" != k[o] && "C" == m && (k[o] = "C"), + i(d, o), + e && (e[o] && (m = e[o][0]), "C" != m && (l[o] = m, o && (n = l[o - 1])), e[o] = h(e[o], g, n), "A" != l[o] && "C" == m && (l[o] = "C"), i(e, o)), + j(d, e, f, g, o), + j(e, d, g, f, o); + var q = d[o], + r = e && e[o], + s = q.length, + t = e && r.length; + f.x = q[s - 2], + f.y = q[s - 1], + f.bx = $(q[s - 4]) || f.x, + f.by = $(q[s - 3]) || f.y, + g.bx = e && ($(r[t - 4]) || g.x), + g.by = e && ($(r[t - 3]) || g.y), + g.x = e && r[t - 2], + g.y = e && r[t - 1] + } + return e || (c.curve = Aa(d)), + e ? [d, e] : d + }, null, Aa), + Ja = (b._parseDots = e(function (a) { + for (var c = [], d = 0, e = a.length; e > d; d++) { + var f = {}, + g = a[d].match(/^([^:]*):?([\d\.]*)/); + if (f.color = b.getRGB(g[1]), f.color.error) + return null; + f.opacity = f.color.opacity, + f.color = f.color.hex, + g[2] && (f.offset = g[2] + "%"), + c.push(f) + } + for (d = 1, e = c.length - 1; e > d; d++) + if (!c[d].offset) { + for (var h = $(c[d - 1].offset || 0), i = 0, j = d + 1; e > j; j++) + if (c[j].offset) { + i = c[j].offset; + break + } + i || (i = 100, j = e), + i = $(i); + for (var k = (i - h) / (j - d + 1); j > d; d++) + h += k, c[d].offset = h + "%" + } + return c + }), b._tear = function (a, b) { + a == b.top && (b.top = a.prev), + a == b.bottom && (b.bottom = a.next), + a.next && (a.next.prev = a.prev), + a.prev && (a.prev.next = a.next) + }), + Ka = (b._tofront = function (a, b) { + b.top !== a && (Ja(a, b), a.next = null, a.prev = b.top, b.top.next = a, b.top = a) + }, b._toback = function (a, b) { + b.bottom !== a && (Ja(a, b), a.next = b.bottom, a.prev = null, b.bottom.prev = a, b.bottom = a) + }, b._insertafter = function (a, b, c) { + Ja(a, c), + b == c.top && (c.top = a), + b.next && (b.next.prev = a), + a.next = b.next, + a.prev = b, + b.next = a + }, b._insertbefore = function (a, b, c) { + Ja(a, c), + b == c.bottom && (c.bottom = a), + b.prev && (b.prev.next = a), + a.prev = b.prev, + b.prev = a, + a.next = b + }, b.toMatrix = function (a, b) { + var c = za(a), + d = { + _: { + transform: F + }, + getBBox: function () { + return c + } + }; + return La(d, b), + d.matrix + }), + La = (b.transformPath = function (a, b) { + return pa(a, Ka(a, b)) + }, b._extractTransform = function (a, c) { + if (null == c) + return a._.transform; + c = H(c).replace(/\.{3}|\u2026/g, a._.transform || F); + var d = b.parseTransformString(c), + e = 0, + f = 0, + g = 0, + h = 1, + i = 1, + j = a._, + k = new n; + if (j.transform = d || [], d) + for (var l = 0, m = d.length; m > l; l++) { + var o, + p, + q, + r, + s, + t = d[l], + u = t.length, + v = H(t[0]).toLowerCase(), + w = t[0] != v, + x = w ? k.invert() : 0; + "t" == v && 3 == u ? w ? (o = x.x(0, 0), p = x.y(0, 0), q = x.x(t[1], t[2]), r = x.y(t[1], t[2]), k.translate(q - o, r - p)) : k.translate(t[1], t[2]) : "r" == v ? 2 == u ? (s = s || a.getBBox(1), k.rotate(t[1], s.x + s.width / 2, s.y + s.height / 2), e += t[1]) : 4 == u && (w ? (q = x.x(t[2], t[3]), r = x.y(t[2], t[3]), k.rotate(t[1], q, r)) : k.rotate(t[1], t[2], t[3]), e += t[1]) : "s" == v ? 2 == u || 3 == u ? (s = s || a.getBBox(1), k.scale(t[1], t[u - 1], s.x + s.width / 2, s.y + s.height / 2), h *= t[1], i *= t[u - 1]) : 5 == u && (w ? (q = x.x(t[3], t[4]), r = x.y(t[3], t[4]), k.scale(t[1], t[2], q, r)) : k.scale(t[1], t[2], t[3], t[4]), h *= t[1], i *= t[2]) : "m" == v && 7 == u && k.add(t[1], t[2], t[3], t[4], t[5], t[6]), + j.dirtyT = 1, + a.matrix = k + } + a.matrix = k, + j.sx = h, + j.sy = i, + j.deg = e, + j.dx = f = k.e, + j.dy = g = k.f, + 1 == h && 1 == i && !e && j.bbox ? (j.bbox.x += +f, j.bbox.y += +g) : j.dirtyT = 1 + }), + Ma = function (a) { + var b = a[0]; + switch (b.toLowerCase()) { + case "t": + return [b, 0, 0]; + case "m": + return [b, 1, 0, 0, 1, 0, 0]; + case "r": + return 4 == a.length ? [b, 0, a[2], a[3]] : [b, 0]; + case "s": + return 5 == a.length ? [b, 1, 1, a[3], a[4]] : 3 == a.length ? [b, 1, 1] : [b, 1] + } + }, + Na = b._equaliseTransform = function (a, c) { + c = H(c).replace(/\.{3}|\u2026/g, a), + a = b.parseTransformString(a) || [], + c = b.parseTransformString(c) || []; + for (var d, e, f, g, h = N(a.length, c.length), i = [], j = [], k = 0; h > k; k++) { + if (f = a[k] || Ma(c[k]), g = c[k] || Ma(f), f[0] != g[0] || "r" == f[0].toLowerCase() && (f[2] != g[2] || f[3] != g[3]) || "s" == f[0].toLowerCase() && (f[3] != g[3] || f[4] != g[4])) + return; + for (i[k] = [], j[k] = [], d = 0, e = N(f.length, g.length); e > d; d++) + d in f && (i[k][d] = f[d]), d in g && (j[k][d] = g[d]) + } + return { + from: i, + to: j + } + }; + b._getContainer = function (a, c, d, e) { + var f; + return f = null != e || b.is(a, "object") ? a : z.doc.getElementById(a), + null != f ? f.tagName ? null == c ? { + container: f, + width: f.style.pixelWidth || f.offsetWidth, + height: f.style.pixelHeight || f.offsetHeight + } + : { + container: f, + width: c, + height: d + } + : { + container: 1, + x: a, + y: c, + width: d, + height: e + } + : void 0 + }, + b.pathToRelative = Ba, + b._engine = {}, + b.path2curve = Ia, + b.matrix = function (a, b, c, d, e, f) { + return new n(a, b, c, d, e, f) + }, + function (a) { + function c(a) { + return a[0] * a[0] + a[1] * a[1] + } + function d(a) { + var b = M.sqrt(c(a)); + a[0] && (a[0] /= b), + a[1] && (a[1] /= b) + } + a.add = function (a, b, c, d, e, f) { + var g, + h, + i, + j, + k = [[], [], []], + l = [[this.a, this.c, this.e], [this.b, this.d, this.f], [0, 0, 1]], + m = [[a, c, e], [b, d, f], [0, 0, 1]]; + for (a && a instanceof n && (m = [[a.a, a.c, a.e], [a.b, a.d, a.f], [0, 0, 1]]), g = 0; 3 > g; g++) + for (h = 0; 3 > h; h++) { + for (j = 0, i = 0; 3 > i; i++) + j += l[g][i] * m[i][h]; + k[g][h] = j + } + this.a = k[0][0], + this.b = k[1][0], + this.c = k[0][1], + this.d = k[1][1], + this.e = k[0][2], + this.f = k[1][2] + }, + a.invert = function () { + var a = this, + b = a.a * a.d - a.b * a.c; + return new n(a.d / b, -a.b / b, -a.c / b, a.a / b, (a.c * a.f - a.d * a.e) / b, (a.b * a.e - a.a * a.f) / b) + }, + a.clone = function () { + return new n(this.a, this.b, this.c, this.d, this.e, this.f) + }, + a.translate = function (a, b) { + this.add(1, 0, 0, 1, a, b) + }, + a.scale = function (a, b, c, d) { + null == b && (b = a), + (c || d) && this.add(1, 0, 0, 1, c, d), + this.add(a, 0, 0, b, 0, 0), + (c || d) && this.add(1, 0, 0, 1, -c, -d) + }, + a.rotate = function (a, c, d) { + a = b.rad(a), + c = c || 0, + d = d || 0; + var e = +M.cos(a).toFixed(9), + f = +M.sin(a).toFixed(9); + this.add(e, f, -f, e, c, d), + this.add(1, 0, 0, 1, -c, -d) + }, + a.x = function (a, b) { + return a * this.a + b * this.c + this.e + }, + a.y = function (a, b) { + return a * this.b + b * this.d + this.f + }, + a.get = function (a) { + return +this[H.fromCharCode(97 + a)].toFixed(4) + }, + a.toString = function () { + return b.svg ? "matrix(" + [this.get(0), this.get(1), this.get(2), this.get(3), this.get(4), this.get(5)].join() + ")" : [this.get(0), this.get(2), this.get(1), this.get(3), 0, 0].join() + }, + a.toFilter = function () { + return "progid:DXImageTransform.Microsoft.Matrix(M11=" + this.get(0) + ", M12=" + this.get(2) + ", M21=" + this.get(1) + ", M22=" + this.get(3) + ", Dx=" + this.get(4) + ", Dy=" + this.get(5) + ", sizingmethod='auto expand')" + }, + a.offset = function () { + return [this.e.toFixed(4), this.f.toFixed(4)] + }, + a.split = function () { + var a = {}; + a.dx = this.e, + a.dy = this.f; + var e = [[this.a, this.c], [this.b, this.d]]; + a.scalex = M.sqrt(c(e[0])), + d(e[0]), + a.shear = e[0][0] * e[1][0] + e[0][1] * e[1][1], + e[1] = [e[1][0] - e[0][0] * a.shear, e[1][1] - e[0][1] * a.shear], + a.scaley = M.sqrt(c(e[1])), + d(e[1]), + a.shear /= a.scaley; + var f = -e[0][1], + g = e[1][1]; + return 0 > g ? (a.rotate = b.deg(M.acos(g)), 0 > f && (a.rotate = 360 - a.rotate)) : a.rotate = b.deg(M.asin(f)), + a.isSimple = !(+a.shear.toFixed(9) || a.scalex.toFixed(9) != a.scaley.toFixed(9) && a.rotate), + a.isSuperSimple = !+a.shear.toFixed(9) && a.scalex.toFixed(9) == a.scaley.toFixed(9) && !a.rotate, + a.noRotation = !+a.shear.toFixed(9) && !a.rotate, + a + }, + a.toTransformString = function (a) { + var b = a || this[I](); + return b.isSimple ? (b.scalex = +b.scalex.toFixed(4), b.scaley = +b.scaley.toFixed(4), b.rotate = +b.rotate.toFixed(4), (b.dx || b.dy ? "t" + [b.dx, b.dy] : F) + (1 != b.scalex || 1 != b.scaley ? "s" + [b.scalex, b.scaley, 0, 0] : F) + (b.rotate ? "r" + [b.rotate, 0, 0] : F)) : "m" + [this.get(0), this.get(1), this.get(2), this.get(3), this.get(4), this.get(5)] + } + } + (n.prototype); + for (var Oa = function () { + this.returnValue = !1 + }, Pa = function () { + return this.originalEvent.preventDefault() + }, Qa = function () { + this.cancelBubble = !0 + }, Ra = function () { + return this.originalEvent.stopPropagation() + }, Sa = function (a) { + var b = z.doc.documentElement.scrollTop || z.doc.body.scrollTop, + c = z.doc.documentElement.scrollLeft || z.doc.body.scrollLeft; + return { + x: a.clientX + c, + y: a.clientY + b + } + }, Ta = function () { + return z.doc.addEventListener ? function (a, b, c, d) { + var e = function (a) { + var b = Sa(a); + return c.call(d, a, b.x, b.y) + }; + if (a.addEventListener(b, e, !1), E && K[b]) { + var f = function (b) { + for (var e = Sa(b), f = b, g = 0, h = b.targetTouches && b.targetTouches.length; h > g; g++) + if (b.targetTouches[g].target == a) { + b = b.targetTouches[g], + b.originalEvent = f, + b.preventDefault = Pa, + b.stopPropagation = Ra; + break + } + return c.call(d, b, e.x, e.y) + }; + a.addEventListener(K[b], f, !1) + } + return function () { + return a.removeEventListener(b, e, !1), + E && K[b] && a.removeEventListener(K[b], f, !1), + !0 + } + } + : z.doc.attachEvent ? function (a, b, c, d) { + var e = function (a) { + a = a || z.win.event; + var b = z.doc.documentElement.scrollTop || z.doc.body.scrollTop, + e = z.doc.documentElement.scrollLeft || z.doc.body.scrollLeft, + f = a.clientX + e, + g = a.clientY + b; + return a.preventDefault = a.preventDefault || Oa, + a.stopPropagation = a.stopPropagation || Qa, + c.call(d, a, f, g) + }; + a.attachEvent("on" + b, e); + var f = function () { + return a.detachEvent("on" + b, e), + !0 + }; + return f + } + : void 0 + } + (), Ua = [], Va = function (b) { + for (var c, d = b.clientX, e = b.clientY, f = z.doc.documentElement.scrollTop || z.doc.body.scrollTop, g = z.doc.documentElement.scrollLeft || z.doc.body.scrollLeft, h = Ua.length; h--; ) { + if (c = Ua[h], E && b.touches) { + for (var i, j = b.touches.length; j--; ) + if (i = b.touches[j], i.identifier == c.el._drag.id) { + d = i.clientX, + e = i.clientY, + (b.originalEvent ? b.originalEvent : b).preventDefault(); + break + } + } else + b.preventDefault(); + var k, + l = c.el.node, + m = l.nextSibling, + n = l.parentNode, + o = l.style.display; + z.win.opera && n.removeChild(l), + l.style.display = "none", + k = c.el.paper.getElementByPoint(d, e), + l.style.display = o, + z.win.opera && (m ? n.insertBefore(l, m) : n.appendChild(l)), + k && a("raphael.drag.over." + c.el.id, c.el, k), + d += g, + e += f, + a("raphael.drag.move." + c.el.id, c.move_scope || c.el, d - c.el._drag.x, e - c.el._drag.y, d, e, b) + } + }, Wa = function (c) { + b.unmousemove(Va).unmouseup(Wa); + for (var d, e = Ua.length; e--; ) + d = Ua[e], d.el._drag = {}, + a("raphael.drag.end." + d.el.id, d.end_scope || d.start_scope || d.move_scope || d.el, c); + Ua = [] + }, Xa = b.el = {}, Ya = J.length; Ya--; ) + !function (a) { + b[a] = Xa[a] = function (c, d) { + return b.is(c, "function") && (this.events = this.events || [], this.events.push({ + name: a, + f: c, + unbind: Ta(this.shape || this.node || z.doc, a, c, d || this) + })), + this + }, + b["un" + a] = Xa["un" + a] = function (c) { + for (var d = this.events || [], e = d.length; e--; ) + d[e].name != a || !b.is(c, "undefined") && d[e].f != c || (d[e].unbind(), d.splice(e, 1), !d.length && delete this.events); + return this + } + } + (J[Ya]); + Xa.data = function (c, d) { + var e = ja[this.id] = ja[this.id] || {}; + if (0 == arguments.length) + return e; + if (1 == arguments.length) { + if (b.is(c, "object")) { + for (var f in c) + c[y](f) && this.data(f, c[f]); + return this + } + return a("raphael.data.get." + this.id, this, e[c], c), + e[c] + } + return e[c] = d, + a("raphael.data.set." + this.id, this, d, c), + this + }, + Xa.removeData = function (a) { + return null == a ? ja[this.id] = {} + : ja[this.id] && delete ja[this.id][a], + this + }, + Xa.getData = function () { + return c(ja[this.id] || {}) + }, + Xa.hover = function (a, b, c, d) { + return this.mouseover(a, c).mouseout(b, d || c) + }, + Xa.unhover = function (a, b) { + return this.unmouseover(a).unmouseout(b) + }; + var Za = []; + Xa.drag = function (c, d, e, f, g, h) { + function i(i) { + (i.originalEvent || i).preventDefault(); + var j = i.clientX, + k = i.clientY, + l = z.doc.documentElement.scrollTop || z.doc.body.scrollTop, + m = z.doc.documentElement.scrollLeft || z.doc.body.scrollLeft; + if (this._drag.id = i.identifier, E && i.touches) + for (var n, o = i.touches.length; o--; ) + if (n = i.touches[o], this._drag.id = n.identifier, n.identifier == this._drag.id) { + j = n.clientX, + k = n.clientY; + break + } + this._drag.x = j + m, + this._drag.y = k + l, + !Ua.length && b.mousemove(Va).mouseup(Wa), + Ua.push({ + el: this, + move_scope: f, + start_scope: g, + end_scope: h + }), + d && a.on("raphael.drag.start." + this.id, d), + c && a.on("raphael.drag.move." + this.id, c), + e && a.on("raphael.drag.end." + this.id, e), + a("raphael.drag.start." + this.id, g || f || this, i.clientX + m, i.clientY + l, i) + } + return this._drag = {}, + Za.push({ + el: this, + start: i + }), + this.mousedown(i), + this + }, + Xa.onDragOver = function (b) { + b ? a.on("raphael.drag.over." + this.id, b) : a.unbind("raphael.drag.over." + this.id) + }, + Xa.undrag = function () { + for (var c = Za.length; c--; ) + Za[c].el == this && (this.unmousedown(Za[c].start), Za.splice(c, 1), a.unbind("raphael.drag.*." + this.id)); + !Za.length && b.unmousemove(Va).unmouseup(Wa), + Ua = [] + }, + u.circle = function (a, c, d) { + var e = b._engine.circle(this, a || 0, c || 0, d || 0); + return this.__set__ && this.__set__.push(e), + e + }, + u.rect = function (a, c, d, e, f) { + var g = b._engine.rect(this, a || 0, c || 0, d || 0, e || 0, f || 0); + return this.__set__ && this.__set__.push(g), + g + }, + u.ellipse = function (a, c, d, e) { + var f = b._engine.ellipse(this, a || 0, c || 0, d || 0, e || 0); + return this.__set__ && this.__set__.push(f), + f + }, + u.path = function (a) { + a && !b.is(a, T) && !b.is(a[0], U) && (a += F); + var c = b._engine.path(b.format[C](b, arguments), this); + return this.__set__ && this.__set__.push(c), + c + }, + u.image = function (a, c, d, e, f) { + var g = b._engine.image(this, a || "about:blank", c || 0, d || 0, e || 0, f || 0); + return this.__set__ && this.__set__.push(g), + g + }, + u.text = function (a, c, d) { + var e = b._engine.text(this, a || 0, c || 0, H(d)); + return this.__set__ && this.__set__.push(e), + e + }, + u.set = function (a) { + !b.is(a, "array") && (a = Array.prototype.splice.call(arguments, 0, arguments.length)); + var c = new jb(a); + return this.__set__ && this.__set__.push(c), + c.paper = this, + c.type = "set", + c + }, + u.setStart = function (a) { + this.__set__ = a || this.set() + }, + u.setFinish = function (a) { + var b = this.__set__; + return delete this.__set__, + b + }, + u.getSize = function () { + var a = this.canvas.parentNode; + return { + width: a.offsetWidth, + height: a.offsetHeight + } + }, + u.setSize = function (a, c) { + return b._engine.setSize.call(this, a, c) + }, + u.setViewBox = function (a, c, d, e, f) { + return b._engine.setViewBox.call(this, a, c, d, e, f) + }, + u.top = u.bottom = null, + u.raphael = b; + var $a = function (a) { + var b = a.getBoundingClientRect(), + c = a.ownerDocument, + d = c.body, + e = c.documentElement, + f = e.clientTop || d.clientTop || 0, + g = e.clientLeft || d.clientLeft || 0, + h = b.top + (z.win.pageYOffset || e.scrollTop || d.scrollTop) - f, + i = b.left + (z.win.pageXOffset || e.scrollLeft || d.scrollLeft) - g; + return { + y: h, + x: i + } + }; + u.getElementByPoint = function (a, b) { + var c = this, + d = c.canvas, + e = z.doc.elementFromPoint(a, b); + if (z.win.opera && "svg" == e.tagName) { + var f = $a(d), + g = d.createSVGRect(); + g.x = a - f.x, + g.y = b - f.y, + g.width = g.height = 1; + var h = d.getIntersectionList(g, null); + h.length && (e = h[h.length - 1]) + } + if (!e) + return null; + for (; e.parentNode && e != d.parentNode && !e.raphael; ) + e = e.parentNode; + return e == c.canvas.parentNode && (e = d), + e = e && e.raphael ? c.getById(e.raphaelid) : null + }, + u.getElementsByBBox = function (a) { + var c = this.set(); + return this.forEach(function (d) { + b.isBBoxIntersect(d.getBBox(), a) && c.push(d) + }), + c + }, + u.getById = function (a) { + for (var b = this.bottom; b; ) { + if (b.id == a) + return b; + b = b.next + } + return null + }, + u.forEach = function (a, b) { + for (var c = this.bottom; c; ) { + if (a.call(b, c) === !1) + return this; + c = c.next + } + return this + }, + u.getElementsByPoint = function (a, b) { + var c = this.set(); + return this.forEach(function (d) { + d.isPointInside(a, b) && c.push(d) + }), + c + }, + Xa.isPointInside = function (a, c) { + var d = this.realPath = oa[this.type](this); + return this.attr("transform") && this.attr("transform").length && (d = b.transformPath(d, this.attr("transform"))), + b.isPointInsidePath(d, a, c) + }, + Xa.getBBox = function (a) { + if (this.removed) + return {}; + var b = this._; + return a ? ((b.dirty || !b.bboxwt) && (this.realPath = oa[this.type](this), b.bboxwt = za(this.realPath), b.bboxwt.toString = o, b.dirty = 0), b.bboxwt) : ((b.dirty || b.dirtyT || !b.bbox) && ((b.dirty || !this.realPath) && (b.bboxwt = 0, this.realPath = oa[this.type](this)), b.bbox = za(pa(this.realPath, this.matrix)), b.bbox.toString = o, b.dirty = b.dirtyT = 0), b.bbox) + }, + Xa.clone = function () { + if (this.removed) + return null; + var a = this.paper[this.type]().attr(this.attr()); + return this.__set__ && this.__set__.push(a), + a + }, + Xa.glow = function (a) { + if ("text" == this.type) + return null; + a = a || {}; + var b = { + width: (a.width || 10) + (+this.attr("stroke-width") || 1), + fill: a.fill || !1, + opacity: null == a.opacity ? .5 : a.opacity, + offsetx: a.offsetx || 0, + offsety: a.offsety || 0, + color: a.color || "#000" + }, + c = b.width / 2, + d = this.paper, + e = d.set(), + f = this.realPath || oa[this.type](this); + f = this.matrix ? pa(f, this.matrix) : f; + for (var g = 1; c + 1 > g; g++) + e.push(d.path(f).attr({ + stroke: b.color, + fill: b.fill ? b.color : "none", + "stroke-linejoin": "round", + "stroke-linecap": "round", + "stroke-width": + (b.width / c * g).toFixed(3), + opacity: + (b.opacity / c).toFixed(3) + })); + return e.insertBefore(this).translate(b.offsetx, b.offsety) + }; + var _a = function (a, c, d, e, f, g, h, k, l) { + return null == l ? i(a, c, d, e, f, g, h, k) : b.findDotsAtSegment(a, c, d, e, f, g, h, k, j(a, c, d, e, f, g, h, k, l)) + }, + ab = function (a, c) { + return function (d, e, f) { + d = Ia(d); + for (var g, h, i, j, k, l = "", m = {}, n = 0, o = 0, p = d.length; p > o; o++) { + if (i = d[o], "M" == i[0]) + g = +i[1], h = +i[2]; + else { + if (j = _a(g, h, i[1], i[2], i[3], i[4], i[5], i[6]), n + j > e) { + if (c && !m.start) { + if (k = _a(g, h, i[1], i[2], i[3], i[4], i[5], i[6], e - n), l += ["C" + k.start.x, k.start.y, k.m.x, k.m.y, k.x, k.y], f) + return l; + m.start = l, + l = ["M" + k.x, k.y + "C" + k.n.x, k.n.y, k.end.x, k.end.y, i[5], i[6]].join(), + n += j, + g = +i[5], + h = +i[6]; + continue + } + if (!a && !c) + return k = _a(g, h, i[1], i[2], i[3], i[4], i[5], i[6], e - n), { + x: k.x, + y: k.y, + alpha: k.alpha + } + } + n += j, + g = +i[5], + h = +i[6] + } + l += i.shift() + i + } + return m.end = l, + k = a ? n : c ? m : b.findDotsAtSegment(g, h, i[0], i[1], i[2], i[3], i[4], i[5], 1), + k.alpha && (k = { + x: k.x, + y: k.y, + alpha: k.alpha + }), + k + } + }, + bb = ab(1), + cb = ab(), + db = ab(0, 1); + b.getTotalLength = bb, + b.getPointAtLength = cb, + b.getSubpath = function (a, b, c) { + if (this.getTotalLength(a) - c < 1e-6) + return db(a, b).end; + var d = db(a, c, 1); + return b ? db(d, b).end : d + }, + Xa.getTotalLength = function () { + var a = this.getPath(); + if (a) + return this.node.getTotalLength ? this.node.getTotalLength() : bb(a) + }, + Xa.getPointAtLength = function (a) { + var b = this.getPath(); + if (b) + return cb(b, a) + }, + Xa.getPath = function () { + var a, + c = b._getPath[this.type]; + if ("text" != this.type && "set" != this.type) + return c && (a = c(this)), a + }, + Xa.getSubpath = function (a, c) { + var d = this.getPath(); + if (d) + return b.getSubpath(d, a, c) + }; + var eb = b.easing_formulas = { + linear: function (a) { + return a + }, + "<": function (a) { + return Q(a, 1.7) + }, + ">": function (a) { + return Q(a, .48) + }, + "<>": function (a) { + var b = .48 - a / 1.04, + c = M.sqrt(.1734 + b * b), + d = c - b, + e = Q(P(d), 1 / 3) * (0 > d ? -1 : 1), + f = -c - b, + g = Q(P(f), 1 / 3) * (0 > f ? -1 : 1), + h = e + g + .5; + return 3 * (1 - h) * h * h + h * h * h + }, + backIn: function (a) { + var b = 1.70158; + return a * a * ((b + 1) * a - b) + }, + backOut: function (a) { + a -= 1; + var b = 1.70158; + return a * a * ((b + 1) * a + b) + 1 + }, + elastic: function (a) { + return a == !!a ? a : Q(2, -10 * a) * M.sin(2 * (a - .075) * R / .3) + 1 + }, + bounce: function (a) { + var b, + c = 7.5625, + d = 2.75; + return 1 / d > a ? b = c * a * a : 2 / d > a ? (a -= 1.5 / d, b = c * a * a + .75) : 2.5 / d > a ? (a -= 2.25 / d, b = c * a * a + .9375) : (a -= 2.625 / d, b = c * a * a + .984375), + b + } + }; + eb.easeIn = eb["ease-in"] = eb["<"], + eb.easeOut = eb["ease-out"] = eb[">"], + eb.easeInOut = eb["ease-in-out"] = eb["<>"], + eb["back-in"] = eb.backIn, + eb["back-out"] = eb.backOut; + var fb = [], + gb = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function (a) { + setTimeout(a, 16) + }, + hb = function () { + for (var c = +new Date, d = 0; d < fb.length; d++) { + var e = fb[d]; + if (!e.el.removed && !e.paused) { + var f, + g, + h = c - e.start, + i = e.ms, + j = e.easing, + k = e.from, + l = e.diff, + m = e.to, + n = (e.t, e.el), + o = {}, + p = {}; + if (e.initstatus ? (h = (e.initstatus * e.anim.top - e.prev) / (e.percent - e.prev) * i, e.status = e.initstatus, delete e.initstatus, e.stop && fb.splice(d--, 1)) : e.status = (e.prev + (e.percent - e.prev) * (h / i)) / e.anim.top, !(0 > h)) + if (i > h) { + var q = j(h / i); + for (var s in k) + if (k[y](s)) { + switch (ca[s]) { + case S: + f = +k[s] + q * i * l[s]; + break; + case "colour": + f = "rgb(" + [ib(Z(k[s].r + q * i * l[s].r)), ib(Z(k[s].g + q * i * l[s].g)), ib(Z(k[s].b + q * i * l[s].b))].join(",") + ")"; + break; + case "path": + f = []; + for (var t = 0, u = k[s].length; u > t; t++) { + f[t] = [k[s][t][0]]; + for (var v = 1, w = k[s][t].length; w > v; v++) + f[t][v] = +k[s][t][v] + q * i * l[s][t][v]; + f[t] = f[t].join(G) + } + f = f.join(G); + break; + case "transform": + if (l[s].real) + for (f = [], t = 0, u = k[s].length; u > t; t++) + for (f[t] = [k[s][t][0]], v = 1, w = k[s][t].length; w > v; v++) + f[t][v] = k[s][t][v] + q * i * l[s][t][v]; + else { + var x = function (a) { + return +k[s][a] + q * i * l[s][a] + }; + f = [["m", x(0), x(1), x(2), x(3), x(4), x(5)]] + } + break; + case "csv": + if ("clip-rect" == s) + for (f = [], t = 4; t--; ) + f[t] = +k[s][t] + q * i * l[s][t]; + break; + default: + var z = [][D](k[s]); + for (f = [], t = n.paper.customAttributes[s].length; t--; ) + f[t] = +z[t] + q * i * l[s][t] + } + o[s] = f + } + n.attr(o), + function (b, c, d) { + setTimeout(function () { + a("raphael.anim.frame." + b, c, d) + }) + } + (n.id, n, e.anim) + } else { + if (function (c, d, e) { + setTimeout(function () { + a("raphael.anim.frame." + d.id, d, e), + a("raphael.anim.finish." + d.id, d, e), + b.is(c, "function") && c.call(d) + }) + } + (e.callback, n, e.anim), n.attr(m), fb.splice(d--, 1), e.repeat > 1 && !e.next) { + for (g in m) + m[y](g) && (p[g] = e.totalOrigin[g]); + e.el.attr(p), + r(e.anim, e.el, e.anim.percents[0], null, e.totalOrigin, e.repeat - 1) + } + e.next && !e.stop && r(e.anim, e.el, e.next, null, e.totalOrigin, e.repeat) + } + } + } + fb.length && gb(hb) + }, + ib = function (a) { + return a > 255 ? 255 : 0 > a ? 0 : a + }; + Xa.animateWith = function (a, c, d, e, f, g) { + var h = this; + if (h.removed) + return g && g.call(h), h; + var i = d instanceof q ? d : b.animation(d, e, f, g); + r(i, h, i.percents[0], null, h.attr()); + for (var j = 0, k = fb.length; k > j; j++) + if (fb[j].anim == c && fb[j].el == a) { + fb[k - 1].start = fb[j].start; + break + } + return h + }, + Xa.onAnimation = function (b) { + return b ? a.on("raphael.anim.frame." + this.id, b) : a.unbind("raphael.anim.frame." + this.id), + this + }, + q.prototype.delay = function (a) { + var b = new q(this.anim, this.ms); + return b.times = this.times, + b.del = +a || 0, + b + }, + q.prototype.repeat = function (a) { + var b = new q(this.anim, this.ms); + return b.del = this.del, + b.times = M.floor(N(a, 0)) || 1, + b + }, + b.animation = function (a, c, d, e) { + if (a instanceof q) + return a; + (b.is(d, "function") || !d) && (e = e || d || null, d = null), + a = Object(a), + c = +c || 0; + var f, + g, + h = {}; + for (g in a) + a[y](g) && $(g) != g && $(g) + "%" != g && (f = !0, h[g] = a[g]); + if (f) + return d && (h.easing = d), e && (h.callback = e), new q({ + 100: h + }, c); + if (e) { + var i = 0; + for (var j in a) { + var k = _(j); + a[y](j) && k > i && (i = k) + } + i += "%", + !a[i].callback && (a[i].callback = e) + } + return new q(a, c) + }, + Xa.animate = function (a, c, d, e) { + var f = this; + if (f.removed) + return e && e.call(f), f; + var g = a instanceof q ? a : b.animation(a, c, d, e); + return r(g, f, g.percents[0], null, f.attr()), + f + }, + Xa.setTime = function (a, b) { + return a && null != b && this.status(a, O(b, a.ms) / a.ms), + this + }, + Xa.status = function (a, b) { + var c, + d, + e = [], + f = 0; + if (null != b) + return r(a, this, -1, O(b, 1)), this; + for (c = fb.length; c > f; f++) + if (d = fb[f], d.el.id == this.id && (!a || d.anim == a)) { + if (a) + return d.status; + e.push({ + anim: d.anim, + status: d.status + }) + } + return a ? 0 : e + }, + Xa.pause = function (b) { + for (var c = 0; c < fb.length; c++) + fb[c].el.id != this.id || b && fb[c].anim != b || a("raphael.anim.pause." + this.id, this, fb[c].anim) !== !1 && (fb[c].paused = !0); + return this + }, + Xa.resume = function (b) { + for (var c = 0; c < fb.length; c++) + if (fb[c].el.id == this.id && (!b || fb[c].anim == b)) { + var d = fb[c]; + a("raphael.anim.resume." + this.id, this, d.anim) !== !1 && (delete d.paused, this.status(d.anim, d.status)) + } + return this + }, + Xa.stop = function (b) { + for (var c = 0; c < fb.length; c++) + fb[c].el.id != this.id || b && fb[c].anim != b || a("raphael.anim.stop." + this.id, this, fb[c].anim) !== !1 && fb.splice(c--, 1); + return this + }, + a.on("raphael.remove", s), + a.on("raphael.clear", s), + Xa.toString = function () { + return "Raphaël’s object" + }; + var jb = function (a) { + if (this.items = [], this.length = 0, this.type = "set", a) + for (var b = 0, c = a.length; c > b; b++) + !a[b] || a[b].constructor != Xa.constructor && a[b].constructor != jb || (this[this.items.length] = this.items[this.items.length] = a[b], this.length++) + }, + kb = jb.prototype; + kb.push = function () { + for (var a, b, c = 0, d = arguments.length; d > c; c++) + a = arguments[c], !a || a.constructor != Xa.constructor && a.constructor != jb || (b = this.items.length, this[b] = this.items[b] = a, this.length++); + return this + }, + kb.pop = function () { + return this.length && delete this[this.length--], + this.items.pop() + }, + kb.forEach = function (a, b) { + for (var c = 0, d = this.items.length; d > c; c++) + if (a.call(b, this.items[c], c) === !1) + return this; + return this + }; + for (var lb in Xa) + Xa[y](lb) && (kb[lb] = function (a) { + return function () { + var b = arguments; + return this.forEach(function (c) { + c[a][C](c, b) + }) + } + } + (lb)); + return kb.attr = function (a, c) { + if (a && b.is(a, U) && b.is(a[0], "object")) + for (var d = 0, e = a.length; e > d; d++) + this.items[d].attr(a[d]); + else + for (var f = 0, g = this.items.length; g > f; f++) + this.items[f].attr(a, c); + return this + }, + kb.clear = function () { + for (; this.length; ) + this.pop() + }, + kb.splice = function (a, b, c) { + a = 0 > a ? N(this.length + a, 0) : a, + b = N(0, O(this.length - a, b)); + var d, + e = [], + f = [], + g = []; + for (d = 2; d < arguments.length; d++) + g.push(arguments[d]); + for (d = 0; b > d; d++) + f.push(this[a + d]); + for (; d < this.length - a; d++) + e.push(this[a + d]); + var h = g.length; + for (d = 0; d < h + e.length; d++) + this.items[a + d] = this[a + d] = h > d ? g[d] : e[d - h]; + for (d = this.items.length = this.length -= b - h; this[d]; ) + delete this[d++]; + return new jb(f) + }, + kb.exclude = function (a) { + for (var b = 0, c = this.length; c > b; b++) + if (this[b] == a) + return this.splice(b, 1), !0 + }, + kb.animate = function (a, c, d, e) { + (b.is(d, "function") || !d) && (e = d || null); + var f, + g, + h = this.items.length, + i = h, + j = this; + if (!h) + return this; + e && (g = function () { + !--h && e.call(j) + }), + d = b.is(d, T) ? d : g; + var k = b.animation(a, c, d, g); + for (f = this.items[--i].animate(k); i--; ) + this.items[i] && !this.items[i].removed && this.items[i].animateWith(f, k, k), this.items[i] && !this.items[i].removed || h--; + return this + }, + kb.insertAfter = function (a) { + for (var b = this.items.length; b--; ) + this.items[b].insertAfter(a); + return this + }, + kb.getBBox = function () { + for (var a = [], b = [], c = [], d = [], e = this.items.length; e--; ) + if (!this.items[e].removed) { + var f = this.items[e].getBBox(); + a.push(f.x), + b.push(f.y), + c.push(f.x + f.width), + d.push(f.y + f.height) + } + return a = O[C](0, a), + b = O[C](0, b), + c = N[C](0, c), + d = N[C](0, d), { + x: a, + y: b, + x2: c, + y2: d, + width: c - a, + height: d - b + } + }, + kb.clone = function (a) { + a = this.paper.set(); + for (var b = 0, c = this.items.length; c > b; b++) + a.push(this.items[b].clone()); + return a + }, + kb.toString = function () { + return "Raphaël‘s set" + }, + kb.glow = function (a) { + var b = this.paper.set(); + return this.forEach(function (c, d) { + var e = c.glow(a); + null != e && e.forEach(function (a, c) { + b.push(a) + }) + }), + b + }, + kb.isPointInside = function (a, b) { + var c = !1; + return this.forEach(function (d) { + return d.isPointInside(a, b) ? (c = !0, !1) : void 0 + }), + c + }, + b.registerFont = function (a) { + if (!a.face) + return a; + this.fonts = this.fonts || {}; + var b = { + w: a.w, + face: {}, + glyphs: {} + }, + c = a.face["font-family"]; + for (var d in a.face) + a.face[y](d) && (b.face[d] = a.face[d]); + if (this.fonts[c] ? this.fonts[c].push(b) : this.fonts[c] = [b], !a.svg) { + b.face["units-per-em"] = _(a.face["units-per-em"], 10); + for (var e in a.glyphs) + if (a.glyphs[y](e)) { + var f = a.glyphs[e]; + if (b.glyphs[e] = { + w: f.w, + k: {}, + d: f.d && "M" + f.d.replace(/[mlcxtrv]/g, function (a) { + return { + l: "L", + c: "C", + x: "z", + t: "m", + r: "l", + v: "c" + } + [a] || "M" + }) + "z" + }, f.k) + for (var g in f.k) + f[y](g) && (b.glyphs[e].k[g] = f.k[g]) + } + } + return a + }, + u.getFont = function (a, c, d, e) { + if (e = e || "normal", d = d || "normal", c = +c || { + normal: 400, + bold: 700, + lighter: 300, + bolder: 800 + } + [c] || 400, b.fonts) { + var f = b.fonts[a]; + if (!f) { + var g = new RegExp("(^|\\s)" + a.replace(/[^\w\d\s+!~.:_-]/g, F) + "(\\s|$)", "i"); + for (var h in b.fonts) + if (b.fonts[y](h) && g.test(h)) { + f = b.fonts[h]; + break + } + } + var i; + if (f) + for (var j = 0, k = f.length; k > j && (i = f[j], i.face["font-weight"] != c || i.face["font-style"] != d && i.face["font-style"] || i.face["font-stretch"] != e); j++); + return i + } + }, + u.print = function (a, c, d, e, f, g, h, i) { + g = g || "middle", + h = N(O(h || 0, 1), -1), + i = N(O(i || 1, 3), 1); + var j, + k = H(d)[I](F), + l = 0, + m = 0, + n = F; + if (b.is(e, "string") && (e = this.getFont(e)), e) { + j = (f || 16) / e.face["units-per-em"]; + for (var o = e.face.bbox[I](v), p = +o[0], q = o[3] - o[1], r = 0, s = +o[1] + ("baseline" == g ? q + +e.face.descent : q / 2), t = 0, u = k.length; u > t; t++) { + if ("\n" == k[t]) + l = 0, x = 0, m = 0, r += q * i; + else { + var w = m && e.glyphs[k[t - 1]] || {}, + x = e.glyphs[k[t]]; + l += m ? (w.w || e.w) + (w.k && w.k[k[t]] || 0) + e.w * h : 0, + m = 1 + } + x && x.d && (n += b.transformPath(x.d, ["t", l * j, r * j, "s", j, j, p, s, "t", (a - p) / j, (c - s) / j])) + } + } + return this.path(n).attr({ + fill: "#000", + stroke: "none" + }) + }, + u.add = function (a) { + if (b.is(a, "array")) + for (var c, d = this.set(), e = 0, f = a.length; f > e; e++) + c = a[e] || {}, + w[y](c.type) && d.push(this[c.type]().attr(c)); + return d + }, + b.format = function (a, c) { + var d = b.is(c, U) ? [0][D](c) : arguments; + return a && b.is(a, T) && d.length - 1 && (a = a.replace(x, function (a, b) { + return null == d[++b] ? F : d[b] + })), + a || F + }, + b.fullfill = function () { + var a = /\{([^\}]+)\}/g, + b = /(?:(?:^|\.)(.+?)(?=\[|\.|$|\()|\[('|")(.+?)\2\])(\(\))?/g, + c = function (a, c, d) { + var e = d; + return c.replace(b, function (a, b, c, d, f) { + b = b || d, + e && (b in e && (e = e[b]), "function" == typeof e && f && (e = e())) + }), + e = (null == e || e == d ? a : e) + "" + }; + return function (b, d) { + return String(b).replace(a, function (a, b) { + return c(a, b, d) + }) + } + } + (), + b.ninja = function () { + return A.was ? z.win.Raphael = A.is : delete Raphael, + b + }, + b.st = kb, + a.on("raphael.DOMload", function () { + t = !0 + }), + function (a, c, d) { + function e() { + /in/.test(a.readyState) ? setTimeout(e, 9) : b.eve("raphael.DOMload") + } + null == a.readyState && a.addEventListener && (a.addEventListener(c, d = function () { + a.removeEventListener(c, d, !1), + a.readyState = "complete" + }, !1), a.readyState = "loading"), + e() + } + (document, "DOMContentLoaded"), + b +}), function (a, b) { + "function" == typeof define && define.amd ? define("raphael.svg", ["raphael.core"], function (a) { + return b(a) + }) : b("object" == typeof exports ? require("./raphael.core") : a.Raphael) +} +(this, function (a) { + if (!a || a.svg) { + var b = "hasOwnProperty", + c = String, + d = parseFloat, + e = parseInt, + f = Math, + g = f.max, + h = f.abs, + i = f.pow, + j = /[, ]+/, + k = a.eve, + l = "", + m = " ", + n = "http://www.w3.org/1999/xlink", + o = { + block: "M5,0 0,2.5 5,5z", + classic: "M5,0 0,2.5 5,5 3.5,3 3.5,2z", + diamond: "M2.5,0 5,2.5 2.5,5 0,2.5z", + open: "M6,1 1,3.5 6,6", + oval: "M2.5,0A2.5,2.5,0,0,1,2.5,5 2.5,2.5,0,0,1,2.5,0z" + }, + p = {}; + a.toString = function () { + return "Your browser supports SVG.\nYou are running Raphaël " + this.version + }; + var q = function (d, e) { + if (e) { + "string" == typeof d && (d = q(d)); + for (var f in e) + e[b](f) && ("xlink:" == f.substring(0, 6) ? d.setAttributeNS(n, f.substring(6), c(e[f])) : d.setAttribute(f, c(e[f]))) + } else + d = a._g.doc.createElementNS("http://www.w3.org/2000/svg", d), d.style && (d.style.webkitTapHighlightColor = "rgba(0,0,0,0)"); + return d + }, + r = function (b, e) { + var j = "linear", + k = b.id + e, + m = .5, + n = .5, + o = b.node, + p = b.paper, + r = o.style, + s = a._g.doc.getElementById(k); + if (!s) { + if (e = c(e).replace(a._radial_gradient, function (a, b, c) { + if (j = "radial", b && c) { + m = d(b), + n = d(c); + var e = 2 * (n > .5) - 1; + i(m - .5, 2) + i(n - .5, 2) > .25 && (n = f.sqrt(.25 - i(m - .5, 2)) * e + .5) && .5 != n && (n = n.toFixed(5) - 1e-5 * e) + } + return l + }), e = e.split(/\s*\-\s*/), "linear" == j) { + var t = e.shift(); + if (t = -d(t), isNaN(t)) + return null; + var u = [0, 0, f.cos(a.rad(t)), f.sin(a.rad(t))], + v = 1 / (g(h(u[2]), h(u[3])) || 1); + u[2] *= v, + u[3] *= v, + u[2] < 0 && (u[0] = -u[2], u[2] = 0), + u[3] < 0 && (u[1] = -u[3], u[3] = 0) + } + var w = a._parseDots(e); + if (!w) + return null; + if (k = k.replace(/[\(\)\s,\xb0#]/g, "_"), b.gradient && k != b.gradient.id && (p.defs.removeChild(b.gradient), delete b.gradient), !b.gradient) { + s = q(j + "Gradient", { + id: k + }), + b.gradient = s, + q(s, "radial" == j ? { + fx: m, + fy: n + } + : { + x1: u[0], + y1: u[1], + x2: u[2], + y2: u[3], + gradientTransform: b.matrix.invert() + }), + p.defs.appendChild(s); + for (var x = 0, y = w.length; y > x; x++) + s.appendChild(q("stop", { + offset: w[x].offset ? w[x].offset : x ? "100%" : "0%", + "stop-color": w[x].color || "#fff", + "stop-opacity": isFinite(w[x].opacity) ? w[x].opacity : 1 + })) + } + } + return q(o, { + fill: "url('" + document.location.origin + document.location.pathname + "#" + k + "')", + opacity: 1, + "fill-opacity": 1 + }), + r.fill = l, + r.opacity = 1, + r.fillOpacity = 1, + 1 + }, + s = function (a) { + var b = a.getBBox(1); + q(a.pattern, { + patternTransform: a.matrix.invert() + " translate(" + b.x + "," + b.y + ")" + }) + }, + t = function (d, e, f) { + if ("path" == d.type) { + for (var g, h, i, j, k, m = c(e).toLowerCase().split("-"), n = d.paper, r = f ? "end" : "start", s = d.node, t = d.attrs, u = t["stroke-width"], v = m.length, w = "classic", x = 3, y = 3, z = 5; v--; ) + switch (m[v]) { + case "block": + case "classic": + case "oval": + case "diamond": + case "open": + case "none": + w = m[v]; + break; + case "wide": + y = 5; + break; + case "narrow": + y = 2; + break; + case "long": + x = 5; + break; + case "short": + x = 2 + } + if ("open" == w ? (x += 2, y += 2, z += 2, i = 1, j = f ? 4 : 1, k = { + fill: "none", + stroke: t.stroke + }) : (j = i = x / 2, k = { + fill: t.stroke, + stroke: "none" + }), d._.arrows ? f ? (d._.arrows.endPath && p[d._.arrows.endPath]--, d._.arrows.endMarker && p[d._.arrows.endMarker]--) : (d._.arrows.startPath && p[d._.arrows.startPath]--, d._.arrows.startMarker && p[d._.arrows.startMarker]--) : d._.arrows = {}, "none" != w) { + var A = "raphael-marker-" + w, + B = "raphael-marker-" + r + w + x + y + "-obj" + d.id; + a._g.doc.getElementById(A) ? p[A]++ : (n.defs.appendChild(q(q("path"), { + "stroke-linecap": "round", + d: o[w], + id: A + })), p[A] = 1); + var C, + D = a._g.doc.getElementById(B); + D ? (p[B]++, C = D.getElementsByTagName("use")[0]) : (D = q(q("marker"), { + id: B, + markerHeight: y, + markerWidth: x, + orient: "auto", + refX: j, + refY: y / 2 + }), C = q(q("use"), { + "xlink:href": "#" + A, + transform: (f ? "rotate(180 " + x / 2 + " " + y / 2 + ") " : l) + "scale(" + x / z + "," + y / z + ")", + "stroke-width": (1 / ((x / z + y / z) / 2)).toFixed(4) + }), D.appendChild(C), n.defs.appendChild(D), p[B] = 1), + q(C, k); + var E = i * ("diamond" != w && "oval" != w); + f ? (g = d._.arrows.startdx * u || 0, h = a.getTotalLength(t.path) - E * u) : (g = E * u, h = a.getTotalLength(t.path) - (d._.arrows.enddx * u || 0)), + k = {}, + k["marker-" + r] = "url(#" + B + ")", + (h || g) && (k.d = a.getSubpath(t.path, g, h)), + q(s, k), + d._.arrows[r + "Path"] = A, + d._.arrows[r + "Marker"] = B, + d._.arrows[r + "dx"] = E, + d._.arrows[r + "Type"] = w, + d._.arrows[r + "String"] = e + } else + f ? (g = d._.arrows.startdx * u || 0, h = a.getTotalLength(t.path) - g) : (g = 0, h = a.getTotalLength(t.path) - (d._.arrows.enddx * u || 0)), d._.arrows[r + "Path"] && q(s, { + d: a.getSubpath(t.path, g, h) + }), delete d._.arrows[r + "Path"], delete d._.arrows[r + "Marker"], delete d._.arrows[r + "dx"], delete d._.arrows[r + "Type"], delete d._.arrows[r + "String"]; + for (k in p) + if (p[b](k) && !p[k]) { + var F = a._g.doc.getElementById(k); + F && F.parentNode.removeChild(F) + } + } + }, + u = { + "-": [3, 1], + ".": [1, 1], + "-.": [3, 1, 1, 1], + "-..": [3, 1, 1, 1, 1, 1], + ". ": [1, 3], + "- ": [4, 3], + "--": [8, 3], + "- .": [4, 3, 1, 3], + "--.": [8, 3, 1, 3], + "--..": [8, 3, 1, 3, 1, 3] + }, + v = function (a, b, d) { + if (b = u[c(b).toLowerCase()]) { + for (var e = a.attrs["stroke-width"] || "1", f = { + round: e, + square: e, + butt: 0 + } + [a.attrs["stroke-linecap"] || d["stroke-linecap"]] || 0, g = [], h = b.length; h--; ) + g[h] = b[h] * e + (h % 2 ? 1 : -1) * f; + q(a.node, { + "stroke-dasharray": g.join(",") + }) + } else + q(a.node, { + "stroke-dasharray": "none" + }) + }, + w = function (d, f) { + var i = d.node, + k = d.attrs, + m = i.style.visibility; + i.style.visibility = "hidden"; + for (var o in f) + if (f[b](o)) { + if (!a._availableAttrs[b](o)) + continue; + var p = f[o]; + switch (k[o] = p, o) { + case "blur": + d.blur(p); + break; + case "title": + var u = i.getElementsByTagName("title"); + if (u.length && (u = u[0])) + u.firstChild.nodeValue = p; + else { + u = q("title"); + var w = a._g.doc.createTextNode(p); + u.appendChild(w), + i.appendChild(u) + } + break; + case "href": + case "target": + var x = i.parentNode; + if ("a" != x.tagName.toLowerCase()) { + var z = q("a"); + x.insertBefore(z, i), + z.appendChild(i), + x = z + } + "target" == o ? x.setAttributeNS(n, "show", "blank" == p ? "new" : p) : x.setAttributeNS(n, o, p); + break; + case "cursor": + i.style.cursor = p; + break; + case "transform": + d.transform(p); + break; + case "arrow-start": + t(d, p); + break; + case "arrow-end": + t(d, p, 1); + break; + case "clip-rect": + var A = c(p).split(j); + if (4 == A.length) { + d.clip && d.clip.parentNode.parentNode.removeChild(d.clip.parentNode); + var B = q("clipPath"), + C = q("rect"); + B.id = a.createUUID(), + q(C, { + x: A[0], + y: A[1], + width: A[2], + height: A[3] + }), + B.appendChild(C), + d.paper.defs.appendChild(B), + q(i, { + "clip-path": "url(#" + B.id + ")" + }), + d.clip = C + } + if (!p) { + var D = i.getAttribute("clip-path"); + if (D) { + var E = a._g.doc.getElementById(D.replace(/(^url\(#|\)$)/g, l)); + E && E.parentNode.removeChild(E), + q(i, { + "clip-path": l + }), + delete d.clip + } + } + break; + case "path": + "path" == d.type && (q(i, { + d: p ? k.path = a._pathToAbsolute(p) : "M0,0" + }), d._.dirty = 1, d._.arrows && ("startString" in d._.arrows && t(d, d._.arrows.startString), "endString" in d._.arrows && t(d, d._.arrows.endString, 1))); + break; + case "width": + if (i.setAttribute(o, p), d._.dirty = 1, !k.fx) + break; + o = "x", + p = k.x; + case "x": + k.fx && (p = -k.x - (k.width || 0)); + case "rx": + if ("rx" == o && "rect" == d.type) + break; + case "cx": + i.setAttribute(o, p), + d.pattern && s(d), + d._.dirty = 1; + break; + case "height": + if (i.setAttribute(o, p), d._.dirty = 1, !k.fy) + break; + o = "y", + p = k.y; + case "y": + k.fy && (p = -k.y - (k.height || 0)); + case "ry": + if ("ry" == o && "rect" == d.type) + break; + case "cy": + i.setAttribute(o, p), + d.pattern && s(d), + d._.dirty = 1; + break; + case "r": + "rect" == d.type ? q(i, { + rx: p, + ry: p + }) : i.setAttribute(o, p), + d._.dirty = 1; + break; + case "src": + "image" == d.type && i.setAttributeNS(n, "href", p); + break; + case "stroke-width": + (1 != d._.sx || 1 != d._.sy) && (p /= g(h(d._.sx), h(d._.sy)) || 1), + i.setAttribute(o, p), + k["stroke-dasharray"] && v(d, k["stroke-dasharray"], f), + d._.arrows && ("startString" in d._.arrows && t(d, d._.arrows.startString), "endString" in d._.arrows && t(d, d._.arrows.endString, 1)); + break; + case "stroke-dasharray": + v(d, p, f); + break; + case "fill": + var F = c(p).match(a._ISURL); + if (F) { + B = q("pattern"); + var G = q("image"); + B.id = a.createUUID(), + q(B, { + x: 0, + y: 0, + patternUnits: "userSpaceOnUse", + height: 1, + width: 1 + }), + q(G, { + x: 0, + y: 0, + "xlink:href": F[1] + }), + B.appendChild(G), + function (b) { + a._preload(F[1], function () { + var a = this.offsetWidth, + c = this.offsetHeight; + q(b, { + width: a, + height: c + }), + q(G, { + width: a, + height: c + }) + }) + } + (B), + d.paper.defs.appendChild(B), + q(i, { + fill: "url(#" + B.id + ")" + }), + d.pattern = B, + d.pattern && s(d); + break + } + var H = a.getRGB(p); + if (H.error) { + if (("circle" == d.type || "ellipse" == d.type || "r" != c(p).charAt()) && r(d, p)) { + if ("opacity" in k || "fill-opacity" in k) { + var I = a._g.doc.getElementById(i.getAttribute("fill").replace(/^url\(#|\)$/g, l)); + if (I) { + var J = I.getElementsByTagName("stop"); + q(J[J.length - 1], { + "stop-opacity": ("opacity" in k ? k.opacity : 1) * ("fill-opacity" in k ? k["fill-opacity"] : 1) + }) + } + } + k.gradient = p, + k.fill = "none"; + break + } + } else + delete f.gradient, delete k.gradient, !a.is(k.opacity, "undefined") && a.is(f.opacity, "undefined") && q(i, { + opacity: k.opacity + }), !a.is(k["fill-opacity"], "undefined") && a.is(f["fill-opacity"], "undefined") && q(i, { + "fill-opacity": k["fill-opacity"] + }); + H[b]("opacity") && q(i, { + "fill-opacity": H.opacity > 1 ? H.opacity / 100 : H.opacity + }); + case "stroke": + H = a.getRGB(p), + i.setAttribute(o, H.hex), + "stroke" == o && H[b]("opacity") && q(i, { + "stroke-opacity": H.opacity > 1 ? H.opacity / 100 : H.opacity + }), + "stroke" == o && d._.arrows && ("startString" in d._.arrows && t(d, d._.arrows.startString), "endString" in d._.arrows && t(d, d._.arrows.endString, 1)); + break; + case "gradient": + ("circle" == d.type || "ellipse" == d.type || "r" != c(p).charAt()) && r(d, p); + break; + case "opacity": + k.gradient && !k[b]("stroke-opacity") && q(i, { + "stroke-opacity": p > 1 ? p / 100 : p + }); + case "fill-opacity": + if (k.gradient) { + I = a._g.doc.getElementById(i.getAttribute("fill").replace(/^url\(#|\)$/g, l)), + I && (J = I.getElementsByTagName("stop"), q(J[J.length - 1], { + "stop-opacity": p + })); + break + } + default: + "font-size" == o && (p = e(p, 10) + "px"); + var K = o.replace(/(\-.)/g, function (a) { + return a.substring(1).toUpperCase() + }); + i.style[K] = p, + d._.dirty = 1, + i.setAttribute(o, p) + } + } + y(d, f), + i.style.visibility = m + }, + x = 1.2, + y = function (d, f) { + if ("text" == d.type && (f[b]("text") || f[b]("font") || f[b]("font-size") || f[b]("x") || f[b]("y"))) { + var g = d.attrs, + h = d.node, + i = h.firstChild ? e(a._g.doc.defaultView.getComputedStyle(h.firstChild, l).getPropertyValue("font-size"), 10) : 10; + if (f[b]("text")) { + for (g.text = f.text; h.firstChild; ) + h.removeChild(h.firstChild); + for (var j, k = c(f.text).split("\n"), m = [], n = 0, o = k.length; o > n; n++) + j = q("tspan"), n && q(j, { + dy: i * x, + x: g.x + }), j.appendChild(a._g.doc.createTextNode(k[n])), h.appendChild(j), m[n] = j + } else + for (m = h.getElementsByTagName("tspan"), n = 0, o = m.length; o > n; n++) + n ? q(m[n], { + dy: i * x, + x: g.x + }) : q(m[0], { + dy: 0 + }); + q(h, { + x: g.x, + y: g.y + }), + d._.dirty = 1; + var p = d._getBBox(), + r = g.y - (p.y + p.height / 2); + r && a.is(r, "finite") && q(m[0], { + dy: r + }) + } + }, + z = function (a) { + return a.parentNode && "a" === a.parentNode.tagName.toLowerCase() ? a.parentNode : a + }, + A = function (b, c) { + this[0] = this.node = b, + b.raphael = !0, + this.id = a._oid++, + b.raphaelid = this.id, + this.matrix = a.matrix(), + this.realPath = null, + this.paper = c, + this.attrs = this.attrs || {}, + this._ = { + transform: [], + sx: 1, + sy: 1, + deg: 0, + dx: 0, + dy: 0, + dirty: 1 + }, + !c.bottom && (c.bottom = this), + this.prev = c.top, + c.top && (c.top.next = this), + c.top = this, + this.next = null + }, + B = a.el; + A.prototype = B, + B.constructor = A, + a._engine.path = function (a, b) { + var c = q("path"); + b.canvas && b.canvas.appendChild(c); + var d = new A(c, b); + return d.type = "path", + w(d, { + fill: "none", + stroke: "#000", + path: a + }), + d + }, + B.rotate = function (a, b, e) { + if (this.removed) + return this; + if (a = c(a).split(j), a.length - 1 && (b = d(a[1]), e = d(a[2])), a = d(a[0]), null == e && (b = e), null == b || null == e) { + var f = this.getBBox(1); + b = f.x + f.width / 2, + e = f.y + f.height / 2 + } + return this.transform(this._.transform.concat([["r", a, b, e]])), + this + }, + B.scale = function (a, b, e, f) { + if (this.removed) + return this; + if (a = c(a).split(j), a.length - 1 && (b = d(a[1]), e = d(a[2]), f = d(a[3])), a = d(a[0]), null == b && (b = a), null == f && (e = f), null == e || null == f) + var g = this.getBBox(1); + return e = null == e ? g.x + g.width / 2 : e, + f = null == f ? g.y + g.height / 2 : f, + this.transform(this._.transform.concat([["s", a, b, e, f]])), + this + }, + B.translate = function (a, b) { + return this.removed ? this : (a = c(a).split(j), a.length - 1 && (b = d(a[1])), a = d(a[0]) || 0, b = +b || 0, this.transform(this._.transform.concat([["t", a, b]])), this) + }, + B.transform = function (c) { + var d = this._; + if (null == c) + return d.transform; + if (a._extractTransform(this, c), this.clip && q(this.clip, { + transform: this.matrix.invert() + }), this.pattern && s(this), this.node && q(this.node, { + transform: this.matrix + }), 1 != d.sx || 1 != d.sy) { + var e = this.attrs[b]("stroke-width") ? this.attrs["stroke-width"] : 1; + this.attr({ + "stroke-width": e + }) + } + return this + }, + B.hide = function () { + return this.removed || (this.node.style.display = "none"), + this + }, + B.show = function () { + return this.removed || (this.node.style.display = ""), + this + }, + B.remove = function () { + var b = z(this.node); + if (!this.removed && b.parentNode) { + var c = this.paper; + c.__set__ && c.__set__.exclude(this), + k.unbind("raphael.*.*." + this.id), + this.gradient && c.defs.removeChild(this.gradient), + a._tear(this, c), + b.parentNode.removeChild(b), + this.removeData(); + for (var d in this) + this[d] = "function" == typeof this[d] ? a._removedFactory(d) : null; + this.removed = !0 + } + }, + B._getBBox = function () { + if ("none" == this.node.style.display) { + this.show(); + var a = !0 + } + var b, + c = !1; + this.paper.canvas.parentElement ? b = this.paper.canvas.parentElement.style : this.paper.canvas.parentNode && (b = this.paper.canvas.parentNode.style), + b && "none" == b.display && (c = !0, b.display = ""); + var d = {}; + try { + d = this.node.getBBox() + } catch (e) { + d = { + x: this.node.clientLeft, + y: this.node.clientTop, + width: this.node.clientWidth, + height: this.node.clientHeight + } + } + finally { + d = d || {}, + c && (b.display = "none") + } + return a && this.hide(), + d + }, + B.attr = function (c, d) { + if (this.removed) + return this; + if (null == c) { + var e = {}; + for (var f in this.attrs) + this.attrs[b](f) && (e[f] = this.attrs[f]); + return e.gradient && "none" == e.fill && (e.fill = e.gradient) && delete e.gradient, + e.transform = this._.transform, + e + } + if (null == d && a.is(c, "string")) { + if ("fill" == c && "none" == this.attrs.fill && this.attrs.gradient) + return this.attrs.gradient; + if ("transform" == c) + return this._.transform; + for (var g = c.split(j), h = {}, i = 0, l = g.length; l > i; i++) + c = g[i], c in this.attrs ? h[c] = this.attrs[c] : a.is(this.paper.customAttributes[c], "function") ? h[c] = this.paper.customAttributes[c].def : h[c] = a._availableAttrs[c]; + return l - 1 ? h : h[g[0]] + } + if (null == d && a.is(c, "array")) { + for (h = {}, i = 0, l = c.length; l > i; i++) + h[c[i]] = this.attr(c[i]); + return h + } + if (null != d) { + var m = {}; + m[c] = d + } else + null != c && a.is(c, "object") && (m = c); + for (var n in m) + k("raphael.attr." + n + "." + this.id, this, m[n]); + for (n in this.paper.customAttributes) + if (this.paper.customAttributes[b](n) && m[b](n) && a.is(this.paper.customAttributes[n], "function")) { + var o = this.paper.customAttributes[n].apply(this, [].concat(m[n])); + this.attrs[n] = m[n]; + for (var p in o) + o[b](p) && (m[p] = o[p]) + } + return w(this, m), + this + }, + B.toFront = function () { + if (this.removed) + return this; + var b = z(this.node); + b.parentNode.appendChild(b); + var c = this.paper; + return c.top != this && a._tofront(this, c), + this + }, + B.toBack = function () { + if (this.removed) + return this; + var b = z(this.node), + c = b.parentNode; + c.insertBefore(b, c.firstChild), + a._toback(this, this.paper); + this.paper; + return this + }, + B.insertAfter = function (b) { + if (this.removed || !b) + return this; + var c = z(this.node), + d = z(b.node || b[b.length - 1].node); + return d.nextSibling ? d.parentNode.insertBefore(c, d.nextSibling) : d.parentNode.appendChild(c), + a._insertafter(this, b, this.paper), + this + }, + B.insertBefore = function (b) { + if (this.removed || !b) + return this; + var c = z(this.node), + d = z(b.node || b[0].node); + return d.parentNode.insertBefore(c, d), + a._insertbefore(this, b, this.paper), + this + }, + B.blur = function (b) { + var c = this; + if (0 !== +b) { + var d = q("filter"), + e = q("feGaussianBlur"); + c.attrs.blur = b, + d.id = a.createUUID(), + q(e, { + stdDeviation: +b || 1.5 + }), + d.appendChild(e), + c.paper.defs.appendChild(d), + c._blur = d, + q(c.node, { + filter: "url(#" + d.id + ")" + }) + } else + c._blur && (c._blur.parentNode.removeChild(c._blur), delete c._blur, delete c.attrs.blur), c.node.removeAttribute("filter"); + return c + }, + a._engine.circle = function (a, b, c, d) { + var e = q("circle"); + a.canvas && a.canvas.appendChild(e); + var f = new A(e, a); + return f.attrs = { + cx: b, + cy: c, + r: d, + fill: "none", + stroke: "#000" + }, + f.type = "circle", + q(e, f.attrs), + f + }, + a._engine.rect = function (a, b, c, d, e, f) { + var g = q("rect"); + a.canvas && a.canvas.appendChild(g); + var h = new A(g, a); + return h.attrs = { + x: b, + y: c, + width: d, + height: e, + rx: f || 0, + ry: f || 0, + fill: "none", + stroke: "#000" + }, + h.type = "rect", + q(g, h.attrs), + h + }, + a._engine.ellipse = function (a, b, c, d, e) { + var f = q("ellipse"); + a.canvas && a.canvas.appendChild(f); + var g = new A(f, a); + return g.attrs = { + cx: b, + cy: c, + rx: d, + ry: e, + fill: "none", + stroke: "#000" + }, + g.type = "ellipse", + q(f, g.attrs), + g + }, + a._engine.image = function (a, b, c, d, e, f) { + var g = q("image"); + q(g, { + x: c, + y: d, + width: e, + height: f, + preserveAspectRatio: "none" + }), + g.setAttributeNS(n, "href", b), + a.canvas && a.canvas.appendChild(g); + var h = new A(g, a); + return h.attrs = { + x: c, + y: d, + width: e, + height: f, + src: b + }, + h.type = "image", + h + }, + a._engine.text = function (b, c, d, e) { + var f = q("text"); + b.canvas && b.canvas.appendChild(f); + var g = new A(f, b); + return g.attrs = { + x: c, + y: d, + "text-anchor": "middle", + text: e, + "font-family": a._availableAttrs["font-family"], + "font-size": a._availableAttrs["font-size"], + stroke: "none", + fill: "#000" + }, + g.type = "text", + w(g, g.attrs), + g + }, + a._engine.setSize = function (a, b) { + return this.width = a || this.width, + this.height = b || this.height, + this.canvas.setAttribute("width", this.width), + this.canvas.setAttribute("height", this.height), + this._viewBox && this.setViewBox.apply(this, this._viewBox), + this + }, + a._engine.create = function () { + var b = a._getContainer.apply(0, arguments), + c = b && b.container, + d = b.x, + e = b.y, + f = b.width, + g = b.height; + if (!c) + throw new Error("SVG container not found."); + var h, + i = q("svg"), + j = "overflow:hidden;"; + return d = d || 0, + e = e || 0, + f = f || 512, + g = g || 342, + q(i, { + height: g, + version: 1.1, + width: f, + xmlns: "http://www.w3.org/2000/svg", + "xmlns:xlink": "http://www.w3.org/1999/xlink" + }), + 1 == c ? (i.style.cssText = j + "position:absolute;left:" + d + "px;top:" + e + "px", a._g.doc.body.appendChild(i), h = 1) : (i.style.cssText = j + "position:relative", c.firstChild ? c.insertBefore(i, c.firstChild) : c.appendChild(i)), + c = new a._Paper, + c.width = f, + c.height = g, + c.canvas = i, + c.clear(), + c._left = c._top = 0, + h && (c.renderfix = function () {}), + c.renderfix(), + c + }, + a._engine.setViewBox = function (a, b, c, d, e) { + k("raphael.setViewBox", this, this._viewBox, [a, b, c, d, e]); + var f, + h, + i = this.getSize(), + j = g(c / i.width, d / i.height), + l = this.top, + n = e ? "xMidYMid meet" : "xMinYMin"; + for (null == a ? (this._vbSize && (j = 1), delete this._vbSize, f = "0 0 " + this.width + m + this.height) : (this._vbSize = j, f = a + m + b + m + c + m + d), q(this.canvas, { + viewBox: f, + preserveAspectRatio: n + }); j && l; ) + h = "stroke-width" in l.attrs ? l.attrs["stroke-width"] : 1, l.attr({ + "stroke-width": h + }), l._.dirty = 1, l._.dirtyT = 1, l = l.prev; + return this._viewBox = [a, b, c, d, !!e], + this + }, + a.prototype.renderfix = function () { + var a, + b = this.canvas, + c = b.style; + try { + a = b.getScreenCTM() || b.createSVGMatrix() + } catch (d) { + a = b.createSVGMatrix() + } + var e = -a.e % 1, + f = -a.f % 1; + (e || f) && (e && (this._left = (this._left + e) % 1, c.left = this._left + "px"), f && (this._top = (this._top + f) % 1, c.top = this._top + "px")) + }, + a.prototype.clear = function () { + a.eve("raphael.clear", this); + for (var b = this.canvas; b.firstChild; ) + b.removeChild(b.firstChild); + this.bottom = this.top = null, + (this.desc = q("desc")).appendChild(a._g.doc.createTextNode("Created with Raphaël " + a.version)), + b.appendChild(this.desc), + b.appendChild(this.defs = q("defs")) + }, + a.prototype.remove = function () { + k("raphael.remove", this), + this.canvas.parentNode && this.canvas.parentNode.removeChild(this.canvas); + for (var b in this) + this[b] = "function" == typeof this[b] ? a._removedFactory(b) : null + }; + var C = a.st; + for (var D in B) + B[b](D) && !C[b](D) && (C[D] = function (a) { + return function () { + var b = arguments; + return this.forEach(function (c) { + c[a].apply(c, b) + }) + } + } + (D)) + } +}), function (a, b) { + "function" == typeof define && define.amd ? define("raphael.vml", ["raphael.core"], function (a) { + return b(a) + }) : b("object" == typeof exports ? require("./raphael.core") : a.Raphael) +} +(this, function (a) { + if (!a || a.vml) { + var b = "hasOwnProperty", + c = String, + d = parseFloat, + e = Math, + f = e.round, + g = e.max, + h = e.min, + i = e.abs, + j = "fill", + k = /[, ]+/, + l = a.eve, + m = " progid:DXImageTransform.Microsoft", + n = " ", + o = "", + p = { + M: "m", + L: "l", + C: "c", + Z: "x", + m: "t", + l: "r", + c: "v", + z: "x" + }, + q = /([clmz]),?([^clmz]*)/gi, + r = / progid:\S+Blur\([^\)]+\)/g, + s = /-?[^,\s-]+/g, + t = "position:absolute;left:0;top:0;width:1px;height:1px;behavior:url(#default#VML)", + u = 21600, + v = { + path: 1, + rect: 1, + image: 1 + }, + w = { + circle: 1, + ellipse: 1 + }, + x = function (b) { + var d = /[ahqstv]/gi, + e = a._pathToAbsolute; + if (c(b).match(d) && (e = a._path2curve), d = /[clmz]/g, e == a._pathToAbsolute && !c(b).match(d)) { + var g = c(b).replace(q, function (a, b, c) { + var d = [], + e = "m" == b.toLowerCase(), + g = p[b]; + return c.replace(s, function (a) { + e && 2 == d.length && (g += d + p["m" == b ? "l" : "L"], d = []), + d.push(f(a * u)) + }), + g + d + }); + return g + } + var h, + i, + j = e(b); + g = []; + for (var k = 0, l = j.length; l > k; k++) { + h = j[k], + i = j[k][0].toLowerCase(), + "z" == i && (i = "x"); + for (var m = 1, r = h.length; r > m; m++) + i += f(h[m] * u) + (m != r - 1 ? "," : o); + g.push(i) + } + return g.join(n) + }, + y = function (b, c, d) { + var e = a.matrix(); + return e.rotate(-b, .5, .5), { + dx: e.x(c, d), + dy: e.y(c, d) + } + }, + z = function (a, b, c, d, e, f) { + var g = a._, + h = a.matrix, + k = g.fillpos, + l = a.node, + m = l.style, + o = 1, + p = "", + q = u / b, + r = u / c; + if (m.visibility = "hidden", b && c) { + if (l.coordsize = i(q) + n + i(r), m.rotation = f * (0 > b * c ? -1 : 1), f) { + var s = y(f, d, e); + d = s.dx, + e = s.dy + } + if (0 > b && (p += "x"), 0 > c && (p += " y") && (o = -1), m.flip = p, l.coordorigin = d * -q + n + e * -r, k || g.fillsize) { + var t = l.getElementsByTagName(j); + t = t && t[0], + l.removeChild(t), + k && (s = y(f, h.x(k[0], k[1]), h.y(k[0], k[1])), t.position = s.dx * o + n + s.dy * o), + g.fillsize && (t.size = g.fillsize[0] * i(b) + n + g.fillsize[1] * i(c)), + l.appendChild(t) + } + m.visibility = "visible" + } + }; + a.toString = function () { + return "Your browser doesn’t support SVG. Falling down to VML.\nYou are running Raphaël " + this.version + }; + var A = function (a, b, d) { + for (var e = c(b).toLowerCase().split("-"), f = d ? "end" : "start", g = e.length, h = "classic", i = "medium", j = "medium"; g--; ) + switch (e[g]) { + case "block": + case "classic": + case "oval": + case "diamond": + case "open": + case "none": + h = e[g]; + break; + case "wide": + case "narrow": + j = e[g]; + break; + case "long": + case "short": + i = e[g] + } + var k = a.node.getElementsByTagName("stroke")[0]; + k[f + "arrow"] = h, + k[f + "arrowlength"] = i, + k[f + "arrowwidth"] = j + }, + B = function (e, i) { + e.attrs = e.attrs || {}; + var l = e.node, + m = e.attrs, + p = l.style, + q = v[e.type] && (i.x != m.x || i.y != m.y || i.width != m.width || i.height != m.height || i.cx != m.cx || i.cy != m.cy || i.rx != m.rx || i.ry != m.ry || i.r != m.r), + r = w[e.type] && (m.cx != i.cx || m.cy != i.cy || m.r != i.r || m.rx != i.rx || m.ry != i.ry), + s = e; + for (var t in i) + i[b](t) && (m[t] = i[t]); + if (q && (m.path = a._getPath[e.type](e), e._.dirty = 1), i.href && (l.href = i.href), i.title && (l.title = i.title), i.target && (l.target = i.target), i.cursor && (p.cursor = i.cursor), "blur" in i && e.blur(i.blur), (i.path && "path" == e.type || q) && (l.path = x(~c(m.path).toLowerCase().indexOf("r") ? a._pathToAbsolute(m.path) : m.path), e._.dirty = 1, "image" == e.type && (e._.fillpos = [m.x, m.y], e._.fillsize = [m.width, m.height], z(e, 1, 1, 0, 0, 0))), "transform" in i && e.transform(i.transform), r) { + var y = +m.cx, + B = +m.cy, + D = +m.rx || +m.r || 0, + E = +m.ry || +m.r || 0; + l.path = a.format("ar{0},{1},{2},{3},{4},{1},{4},{1}x", f((y - D) * u), f((B - E) * u), f((y + D) * u), f((B + E) * u), f(y * u)), + e._.dirty = 1 + } + if ("clip-rect" in i) { + var G = c(i["clip-rect"]).split(k); + if (4 == G.length) { + G[2] = +G[2] + +G[0], + G[3] = +G[3] + +G[1]; + var H = l.clipRect || a._g.doc.createElement("div"), + I = H.style; + I.clip = a.format("rect({1}px {2}px {3}px {0}px)", G), + l.clipRect || (I.position = "absolute", I.top = 0, I.left = 0, I.width = e.paper.width + "px", I.height = e.paper.height + "px", l.parentNode.insertBefore(H, l), H.appendChild(l), l.clipRect = H) + } + i["clip-rect"] || l.clipRect && (l.clipRect.style.clip = "auto") + } + if (e.textpath) { + var J = e.textpath.style; + i.font && (J.font = i.font), + i["font-family"] && (J.fontFamily = '"' + i["font-family"].split(",")[0].replace(/^['"]+|['"]+$/g, o) + '"'), + i["font-size"] && (J.fontSize = i["font-size"]), + i["font-weight"] && (J.fontWeight = i["font-weight"]), + i["font-style"] && (J.fontStyle = i["font-style"]) + } + if ("arrow-start" in i && A(s, i["arrow-start"]), "arrow-end" in i && A(s, i["arrow-end"], 1), null != i.opacity || null != i["stroke-width"] || null != i.fill || null != i.src || null != i.stroke || null != i["stroke-width"] || null != i["stroke-opacity"] || null != i["fill-opacity"] || null != i["stroke-dasharray"] || null != i["stroke-miterlimit"] || null != i["stroke-linejoin"] || null != i["stroke-linecap"]) { + var K = l.getElementsByTagName(j), + L = !1; + if (K = K && K[0], !K && (L = K = F(j)), "image" == e.type && i.src && (K.src = i.src), i.fill && (K.on = !0), (null == K.on || "none" == i.fill || null === i.fill) && (K.on = !1), K.on && i.fill) { + var M = c(i.fill).match(a._ISURL); + if (M) { + K.parentNode == l && l.removeChild(K), + K.rotate = !0, + K.src = M[1], + K.type = "tile"; + var N = e.getBBox(1); + K.position = N.x + n + N.y, + e._.fillpos = [N.x, N.y], + a._preload(M[1], function () { + e._.fillsize = [this.offsetWidth, this.offsetHeight] + }) + } else + K.color = a.getRGB(i.fill).hex, K.src = o, K.type = "solid", a.getRGB(i.fill).error && (s.type in { + circle: 1, + ellipse: 1 + } + || "r" != c(i.fill).charAt()) && C(s, i.fill, K) && (m.fill = "none", m.gradient = i.fill, K.rotate = !1) + } + if ("fill-opacity" in i || "opacity" in i) { + var O = ((+m["fill-opacity"] + 1 || 2) - 1) * ((+m.opacity + 1 || 2) - 1) * ((+a.getRGB(i.fill).o + 1 || 2) - 1); + O = h(g(O, 0), 1), + K.opacity = O, + K.src && (K.color = "none") + } + l.appendChild(K); + var P = l.getElementsByTagName("stroke") && l.getElementsByTagName("stroke")[0], + Q = !1; + !P && (Q = P = F("stroke")), + (i.stroke && "none" != i.stroke || i["stroke-width"] || null != i["stroke-opacity"] || i["stroke-dasharray"] || i["stroke-miterlimit"] || i["stroke-linejoin"] || i["stroke-linecap"]) && (P.on = !0), + ("none" == i.stroke || null === i.stroke || null == P.on || 0 == i.stroke || 0 == i["stroke-width"]) && (P.on = !1); + var R = a.getRGB(i.stroke); + P.on && i.stroke && (P.color = R.hex), + O = ((+m["stroke-opacity"] + 1 || 2) - 1) * ((+m.opacity + 1 || 2) - 1) * ((+R.o + 1 || 2) - 1); + var S = .75 * (d(i["stroke-width"]) || 1); + if (O = h(g(O, 0), 1), null == i["stroke-width"] && (S = m["stroke-width"]), i["stroke-width"] && (P.weight = S), S && 1 > S && (O *= S) && (P.weight = 1), P.opacity = O, i["stroke-linejoin"] && (P.joinstyle = i["stroke-linejoin"] || "miter"), P.miterlimit = i["stroke-miterlimit"] || 8, i["stroke-linecap"] && (P.endcap = "butt" == i["stroke-linecap"] ? "flat" : "square" == i["stroke-linecap"] ? "square" : "round"), "stroke-dasharray" in i) { + var T = { + "-": "shortdash", + ".": "shortdot", + "-.": "shortdashdot", + "-..": "shortdashdotdot", + ". ": "dot", + "- ": "dash", + "--": "longdash", + "- .": "dashdot", + "--.": "longdashdot", + "--..": "longdashdotdot" + }; + P.dashstyle = T[b](i["stroke-dasharray"]) ? T[i["stroke-dasharray"]] : o + } + Q && l.appendChild(P) + } + if ("text" == s.type) { + s.paper.canvas.style.display = o; + var U = s.paper.span, + V = 100, + W = m.font && m.font.match(/\d+(?:\.\d*)?(?=px)/); + p = U.style, + m.font && (p.font = m.font), + m["font-family"] && (p.fontFamily = m["font-family"]), + m["font-weight"] && (p.fontWeight = m["font-weight"]), + m["font-style"] && (p.fontStyle = m["font-style"]), + W = d(m["font-size"] || W && W[0]) || 10, + p.fontSize = W * V + "px", + s.textpath.string && (U.innerHTML = c(s.textpath.string).replace(/")); + var X = U.getBoundingClientRect(); + s.W = m.w = (X.right - X.left) / V, + s.H = m.h = (X.bottom - X.top) / V, + s.X = m.x, + s.Y = m.y + s.H / 2, + ("x" in i || "y" in i) && (s.path.v = a.format("m{0},{1}l{2},{1}", f(m.x * u), f(m.y * u), f(m.x * u) + 1)); + for (var Y = ["x", "y", "text", "font", "font-family", "font-weight", "font-style", "font-size"], Z = 0, $ = Y.length; $ > Z; Z++) + if (Y[Z]in i) { + s._.dirty = 1; + break + } + switch (m["text-anchor"]) { + case "start": + s.textpath.style["v-text-align"] = "left", + s.bbx = s.W / 2; + break; + case "end": + s.textpath.style["v-text-align"] = "right", + s.bbx = -s.W / 2; + break; + default: + s.textpath.style["v-text-align"] = "center", + s.bbx = 0 + } + s.textpath.style["v-text-kern"] = !0 + } + }, + C = function (b, f, g) { + b.attrs = b.attrs || {}; + var h = (b.attrs, Math.pow), + i = "linear", + j = ".5 .5"; + if (b.attrs.gradient = f, f = c(f).replace(a._radial_gradient, function (a, b, c) { + return i = "radial", + b && c && (b = d(b), c = d(c), h(b - .5, 2) + h(c - .5, 2) > .25 && (c = e.sqrt(.25 - h(b - .5, 2)) * (2 * (c > .5) - 1) + .5), j = b + n + c), + o + }), f = f.split(/\s*\-\s*/), "linear" == i) { + var k = f.shift(); + if (k = -d(k), isNaN(k)) + return null + } + var l = a._parseDots(f); + if (!l) + return null; + if (b = b.shape || b.node, l.length) { + b.removeChild(g), + g.on = !0, + g.method = "none", + g.color = l[0].color, + g.color2 = l[l.length - 1].color; + for (var m = [], p = 0, q = l.length; q > p; p++) + l[p].offset && m.push(l[p].offset + n + l[p].color); + g.colors = m.length ? m.join() : "0% " + g.color, + "radial" == i ? (g.type = "gradientTitle", g.focus = "100%", g.focussize = "0 0", g.focusposition = j, g.angle = 0) : (g.type = "gradient", g.angle = (270 - k) % 360), + b.appendChild(g) + } + return 1 + }, + D = function (b, c) { + this[0] = this.node = b, + b.raphael = !0, + this.id = a._oid++, + b.raphaelid = this.id, + this.X = 0, + this.Y = 0, + this.attrs = {}, + this.paper = c, + this.matrix = a.matrix(), + this._ = { + transform: [], + sx: 1, + sy: 1, + dx: 0, + dy: 0, + deg: 0, + dirty: 1, + dirtyT: 1 + }, + !c.bottom && (c.bottom = this), + this.prev = c.top, + c.top && (c.top.next = this), + c.top = this, + this.next = null + }, + E = a.el; + D.prototype = E, + E.constructor = D, + E.transform = function (b) { + if (null == b) + return this._.transform; + var d, + e = this.paper._viewBoxShift, + f = e ? "s" + [e.scale, e.scale] + "-1-1t" + [e.dx, e.dy] : o; + e && (d = b = c(b).replace(/\.{3}|\u2026/g, this._.transform || o)), + a._extractTransform(this, f + b); + var g, + h = this.matrix.clone(), + i = this.skew, + j = this.node, + k = ~c(this.attrs.fill).indexOf("-"), + l = !c(this.attrs.fill).indexOf("url("); + if (h.translate(1, 1), l || k || "image" == this.type) + if (i.matrix = "1 0 0 1", i.offset = "0 0", g = h.split(), k && g.noRotation || !g.isSimple) { + j.style.filter = h.toFilter(); + var m = this.getBBox(), + p = this.getBBox(1), + q = m.x - p.x, + r = m.y - p.y; + j.coordorigin = q * -u + n + r * -u, + z(this, 1, 1, q, r, 0) + } else + j.style.filter = o, z(this, g.scalex, g.scaley, g.dx, g.dy, g.rotate); + else + j.style.filter = o, i.matrix = c(h), i.offset = h.offset(); + return null !== d && (this._.transform = d, a._extractTransform(this, d)), + this + }, + E.rotate = function (a, b, e) { + if (this.removed) + return this; + if (null != a) { + if (a = c(a).split(k), a.length - 1 && (b = d(a[1]), e = d(a[2])), a = d(a[0]), null == e && (b = e), null == b || null == e) { + var f = this.getBBox(1); + b = f.x + f.width / 2, + e = f.y + f.height / 2 + } + return this._.dirtyT = 1, + this.transform(this._.transform.concat([["r", a, b, e]])), + this + } + }, + E.translate = function (a, b) { + return this.removed ? this : (a = c(a).split(k), a.length - 1 && (b = d(a[1])), a = d(a[0]) || 0, b = +b || 0, this._.bbox && (this._.bbox.x += a, this._.bbox.y += b), this.transform(this._.transform.concat([["t", a, b]])), this) + }, + E.scale = function (a, b, e, f) { + if (this.removed) + return this; + if (a = c(a).split(k), a.length - 1 && (b = d(a[1]), e = d(a[2]), f = d(a[3]), isNaN(e) && (e = null), isNaN(f) && (f = null)), a = d(a[0]), null == b && (b = a), null == f && (e = f), null == e || null == f) + var g = this.getBBox(1); + return e = null == e ? g.x + g.width / 2 : e, + f = null == f ? g.y + g.height / 2 : f, + this.transform(this._.transform.concat([["s", a, b, e, f]])), + this._.dirtyT = 1, + this + }, + E.hide = function () { + return !this.removed && (this.node.style.display = "none"), + this + }, + E.show = function () { + return !this.removed && (this.node.style.display = o), + this + }, + E.auxGetBBox = a.el.getBBox, + E.getBBox = function () { + var a = this.auxGetBBox(); + if (this.paper && this.paper._viewBoxShift) { + var b = {}, + c = 1 / this.paper._viewBoxShift.scale; + return b.x = a.x - this.paper._viewBoxShift.dx, + b.x *= c, + b.y = a.y - this.paper._viewBoxShift.dy, + b.y *= c, + b.width = a.width * c, + b.height = a.height * c, + b.x2 = b.x + b.width, + b.y2 = b.y + b.height, + b + } + return a + }, + E._getBBox = function () { + return this.removed ? {} + : { + x: this.X + (this.bbx || 0) - this.W / 2, + y: this.Y - this.H, + width: this.W, + height: this.H + } + }, + E.remove = function () { + if (!this.removed && this.node.parentNode) { + this.paper.__set__ && this.paper.__set__.exclude(this), + a.eve.unbind("raphael.*.*." + this.id), + a._tear(this, this.paper), + this.node.parentNode.removeChild(this.node), + this.shape && this.shape.parentNode.removeChild(this.shape); + for (var b in this) + this[b] = "function" == typeof this[b] ? a._removedFactory(b) : null; + this.removed = !0 + } + }, + E.attr = function (c, d) { + if (this.removed) + return this; + if (null == c) { + var e = {}; + for (var f in this.attrs) + this.attrs[b](f) && (e[f] = this.attrs[f]); + return e.gradient && "none" == e.fill && (e.fill = e.gradient) && delete e.gradient, + e.transform = this._.transform, + e + } + if (null == d && a.is(c, "string")) { + if (c == j && "none" == this.attrs.fill && this.attrs.gradient) + return this.attrs.gradient; + for (var g = c.split(k), h = {}, i = 0, m = g.length; m > i; i++) + c = g[i], c in this.attrs ? h[c] = this.attrs[c] : a.is(this.paper.customAttributes[c], "function") ? h[c] = this.paper.customAttributes[c].def : h[c] = a._availableAttrs[c]; + return m - 1 ? h : h[g[0]] + } + if (this.attrs && null == d && a.is(c, "array")) { + for (h = {}, i = 0, m = c.length; m > i; i++) + h[c[i]] = this.attr(c[i]); + return h + } + var n; + null != d && (n = {}, n[c] = d), + null == d && a.is(c, "object") && (n = c); + for (var o in n) + l("raphael.attr." + o + "." + this.id, this, n[o]); + if (n) { + for (o in this.paper.customAttributes) + if (this.paper.customAttributes[b](o) && n[b](o) && a.is(this.paper.customAttributes[o], "function")) { + var p = this.paper.customAttributes[o].apply(this, [].concat(n[o])); + this.attrs[o] = n[o]; + for (var q in p) + p[b](q) && (n[q] = p[q]) + } + n.text && "text" == this.type && (this.textpath.string = n.text), + B(this, n) + } + return this + }, + E.toFront = function () { + return !this.removed && this.node.parentNode.appendChild(this.node), + this.paper && this.paper.top != this && a._tofront(this, this.paper), + this + }, + E.toBack = function () { + return this.removed ? this : (this.node.parentNode.firstChild != this.node && (this.node.parentNode.insertBefore(this.node, this.node.parentNode.firstChild), a._toback(this, this.paper)), this) + }, + E.insertAfter = function (b) { + return this.removed ? this : (b.constructor == a.st.constructor && (b = b[b.length - 1]), b.node.nextSibling ? b.node.parentNode.insertBefore(this.node, b.node.nextSibling) : b.node.parentNode.appendChild(this.node), a._insertafter(this, b, this.paper), this) + }, + E.insertBefore = function (b) { + return this.removed ? this : (b.constructor == a.st.constructor && (b = b[0]), b.node.parentNode.insertBefore(this.node, b.node), a._insertbefore(this, b, this.paper), this) + }, + E.blur = function (b) { + var c = this.node.runtimeStyle, + d = c.filter; + return d = d.replace(r, o), + 0 !== +b ? (this.attrs.blur = b, c.filter = d + n + m + ".Blur(pixelradius=" + (+b || 1.5) + ")", c.margin = a.format("-{0}px 0 0 -{0}px", f(+b || 1.5))) : (c.filter = d, c.margin = 0, delete this.attrs.blur), + this + }, + a._engine.path = function (a, b) { + var c = F("shape"); + c.style.cssText = t, + c.coordsize = u + n + u, + c.coordorigin = b.coordorigin; + var d = new D(c, b), + e = { + fill: "none", + stroke: "#000" + }; + a && (e.path = a), + d.type = "path", + d.path = [], + d.Path = o, + B(d, e), + b.canvas.appendChild(c); + var f = F("skew"); + return f.on = !0, + c.appendChild(f), + d.skew = f, + d.transform(o), + d + }, + a._engine.rect = function (b, c, d, e, f, g) { + var h = a._rectPath(c, d, e, f, g), + i = b.path(h), + j = i.attrs; + return i.X = j.x = c, + i.Y = j.y = d, + i.W = j.width = e, + i.H = j.height = f, + j.r = g, + j.path = h, + i.type = "rect", + i + }, + a._engine.ellipse = function (a, b, c, d, e) { { + var f = a.path(); + f.attrs + } + return f.X = b - d, + f.Y = c - e, + f.W = 2 * d, + f.H = 2 * e, + f.type = "ellipse", + B(f, { + cx: b, + cy: c, + rx: d, + ry: e + }), + f + }, + a._engine.circle = function (a, b, c, d) { { + var e = a.path(); + e.attrs + } + return e.X = b - d, + e.Y = c - d, + e.W = e.H = 2 * d, + e.type = "circle", + B(e, { + cx: b, + cy: c, + r: d + }), + e + }, + a._engine.image = function (b, c, d, e, f, g) { + var h = a._rectPath(d, e, f, g), + i = b.path(h).attr({ + stroke: "none" + }), + k = i.attrs, + l = i.node, + m = l.getElementsByTagName(j)[0]; + return k.src = c, + i.X = k.x = d, + i.Y = k.y = e, + i.W = k.width = f, + i.H = k.height = g, + k.path = h, + i.type = "image", + m.parentNode == l && l.removeChild(m), + m.rotate = !0, + m.src = c, + m.type = "tile", + i._.fillpos = [d, e], + i._.fillsize = [f, g], + l.appendChild(m), + z(i, 1, 1, 0, 0, 0), + i + }, + a._engine.text = function (b, d, e, g) { + var h = F("shape"), + i = F("path"), + j = F("textpath"); + d = d || 0, + e = e || 0, + g = g || "", + i.v = a.format("m{0},{1}l{2},{1}", f(d * u), f(e * u), f(d * u) + 1), + i.textpathok = !0, + j.string = c(g), + j.on = !0, + h.style.cssText = t, + h.coordsize = u + n + u, + h.coordorigin = "0 0"; + var k = new D(h, b), + l = { + fill: "#000", + stroke: "none", + font: a._availableAttrs.font, + text: g + }; + k.shape = h, + k.path = i, + k.textpath = j, + k.type = "text", + k.attrs.text = c(g), + k.attrs.x = d, + k.attrs.y = e, + k.attrs.w = 1, + k.attrs.h = 1, + B(k, l), + h.appendChild(j), + h.appendChild(i), + b.canvas.appendChild(h); + var m = F("skew"); + return m.on = !0, + h.appendChild(m), + k.skew = m, + k.transform(o), + k + }, + a._engine.setSize = function (b, c) { + var d = this.canvas.style; + return this.width = b, + this.height = c, + b == +b && (b += "px"), + c == +c && (c += "px"), + d.width = b, + d.height = c, + d.clip = "rect(0 " + b + " " + c + " 0)", + this._viewBox && a._engine.setViewBox.apply(this, this._viewBox), + this + }, + a._engine.setViewBox = function (b, c, d, e, f) { + a.eve("raphael.setViewBox", this, this._viewBox, [b, c, d, e, f]); + var g, + h, + i = this.getSize(), + j = i.width, + k = i.height; + return f && (g = k / e, h = j / d, j > d * g && (b -= (j - d * g) / 2 / g), k > e * h && (c -= (k - e * h) / 2 / h)), + this._viewBox = [b, c, d, e, !!f], + this._viewBoxShift = { + dx: -b, + dy: -c, + scale: i + }, + this.forEach(function (a) { + a.transform("...") + }), + this + }; + var F; + a._engine.initWin = function (a) { + var b = a.document; + b.styleSheets.length < 31 ? b.createStyleSheet().addRule(".rvml", "behavior:url(#default#VML)") : b.styleSheets[0].addRule(".rvml", "behavior:url(#default#VML)"); + try { + !b.namespaces.rvml && b.namespaces.add("rvml", "urn:schemas-microsoft-com:vml"), + F = function (a) { + return b.createElement("') + } + } catch (c) { + F = function (a) { + return b.createElement("<" + a + ' xmlns="urn:schemas-microsoft.com:vml" class="rvml">') + } + } + }, + a._engine.initWin(a._g.win), + a._engine.create = function () { + var b = a._getContainer.apply(0, arguments), + c = b.container, + d = b.height, + e = b.width, + f = b.x, + g = b.y; + if (!c) + throw new Error("VML container not found."); + var h = new a._Paper, + i = h.canvas = a._g.doc.createElement("div"), + j = i.style; + return f = f || 0, + g = g || 0, + e = e || 512, + d = d || 342, + h.width = e, + h.height = d, + e == +e && (e += "px"), + d == +d && (d += "px"), + h.coordsize = 1e3 * u + n + 1e3 * u, + h.coordorigin = "0 0", + h.span = a._g.doc.createElement("span"), + h.span.style.cssText = "position:absolute;left:-9999em;top:-9999em;padding:0;margin:0;line-height:1;", + i.appendChild(h.span), + j.cssText = a.format("top:0;left:0;width:{0};height:{1};display:inline-block;position:relative;clip:rect(0 {0} {1} 0);overflow:hidden", e, d), + 1 == c ? (a._g.doc.body.appendChild(i), j.left = f + "px", j.top = g + "px", j.position = "absolute") : c.firstChild ? c.insertBefore(i, c.firstChild) : c.appendChild(i), + h.renderfix = function () {}, + h + }, + a.prototype.clear = function () { + a.eve("raphael.clear", this), + this.canvas.innerHTML = o, + this.span = a._g.doc.createElement("span"), + this.span.style.cssText = "position:absolute;left:-9999em;top:-9999em;padding:0;margin:0;line-height:1;display:inline;", + this.canvas.appendChild(this.span), + this.bottom = this.top = null + }, + a.prototype.remove = function () { + a.eve("raphael.remove", this), + this.canvas.parentNode.removeChild(this.canvas); + for (var b in this) + this[b] = "function" == typeof this[b] ? a._removedFactory(b) : null; + return !0 + }; + var G = a.st; + for (var H in E) + E[b](H) && !G[b](H) && (G[H] = function (a) { + return function () { + var b = arguments; + return this.forEach(function (c) { + c[a].apply(c, b) + }) + } + } + (H)) + } +}); +JustGage = function (config) { + var obj = this; + if (config === null || config === undefined) { + console.log('* justgage: Make sure to pass options to the constructor!'); + return false; + } + var node; + if (config.id !== null && config.id !== undefined) { + node = document.getElementById(config.id); + if (!node) { + console.log('* justgage: No element with id : %s found', config.id); + return false; + } + } else if (config.parentNode !== null && config.parentNode !== undefined) { + node = config.parentNode; + } else { + console.log('* justgage: Make sure to pass the existing element id or parentNode to the constructor.'); + return false; + } + var dataset = node.dataset ? node.dataset : {}; + var defaults = (config.defaults !== null && config.defaults !== undefined) ? config.defaults : false; + if (defaults !== false) { + config = extend({}, config, defaults); + delete config.defaults; + } + obj.config = { + id: config.id, + value: kvLookup('value', config, dataset, 0, 'float'), + defaults: kvLookup('defaults', config, dataset, 0, false), + parentNode: kvLookup('parentNode', config, dataset, null), + width: kvLookup('width', config, dataset, null), + height: kvLookup('height', config, dataset, null), + title: kvLookup('title', config, dataset, ""), + titleFontColor: kvLookup('titleFontColor', config, dataset, "#999999"), + titleFontFamily: kvLookup('titleFontFamily', config, dataset, "sans-serif"), + titlePosition: kvLookup('titlePosition', config, dataset, "above"), + valueFontColor: kvLookup('valueFontColor', config, dataset, "#010101"), + valueFontFamily: kvLookup('valueFontFamily', config, dataset, "Arial"), + symbol: kvLookup('symbol', config, dataset, ''), + min: kvLookup('min', config, dataset, 0, 'float'), + max: kvLookup('max', config, dataset, 100, 'float'), + reverse: kvLookup('reverse', config, dataset, false), + humanFriendlyDecimal: kvLookup('humanFriendlyDecimal', config, dataset, 0), + textRenderer: kvLookup('textRenderer', config, dataset, null), + gaugeWidthScale: kvLookup('gaugeWidthScale', config, dataset, 1.0), + gaugeColor: kvLookup('gaugeColor', config, dataset, "#edebeb"), + label: kvLookup('label', config, dataset, ''), + labelFontColor: kvLookup('labelFontColor', config, dataset, "#b3b3b3"), + shadowOpacity: kvLookup('shadowOpacity', config, dataset, 0.2), + shadowSize: kvLookup('shadowSize', config, dataset, 5), + shadowVerticalOffset: kvLookup('shadowVerticalOffset', config, dataset, 3), + levelColors: kvLookup('levelColors', config, dataset, ["#a9d70b", "#f9c802", "#ff0000"], 'array', ','), + startAnimationTime: kvLookup('startAnimationTime', config, dataset, 700), + startAnimationType: kvLookup('startAnimationType', config, dataset, '>'), + refreshAnimationTime: kvLookup('refreshAnimationTime', config, dataset, 700), + refreshAnimationType: kvLookup('refreshAnimationType', config, dataset, '>'), + donutStartAngle: kvLookup('donutStartAngle', config, dataset, 90), + valueMinFontSize: kvLookup('valueMinFontSize', config, dataset, 16), + titleMinFontSize: kvLookup('titleMinFontSize', config, dataset, 10), + labelMinFontSize: kvLookup('labelMinFontSize', config, dataset, 10), + minLabelMinFontSize: kvLookup('minLabelMinFontSize', config, dataset, 10), + maxLabelMinFontSize: kvLookup('maxLabelMinFontSize', config, dataset, 10), + hideValue: kvLookup('hideValue', config, dataset, false), + hideMinMax: kvLookup('hideMinMax', config, dataset, false), + hideInnerShadow: kvLookup('hideInnerShadow', config, dataset, false), + humanFriendly: kvLookup('humanFriendly', config, dataset, false), + noGradient: kvLookup('noGradient', config, dataset, false), + donut: kvLookup('donut', config, dataset, false), + relativeGaugeSize: kvLookup('relativeGaugeSize', config, dataset, false), + counter: kvLookup('counter', config, dataset, false), + decimals: kvLookup('decimals', config, dataset, 0), + customSectors: kvLookup('customSectors', config, dataset, []), + formatNumber: kvLookup('formatNumber', config, dataset, false), + pointer: kvLookup('pointer', config, dataset, false), + pointerOptions: kvLookup('pointerOptions', config, dataset, []) + }; + var + canvasW, + canvasH, + widgetW, + widgetH, + aspect, + dx, + dy, + titleFontSize, + titleX, + titleY, + valueFontSize, + valueX, + valueY, + labelFontSize, + labelX, + labelY, + minFontSize, + minX, + minY, + maxFontSize, + maxX, + maxY; + if (obj.config.value > obj.config.max) + obj.config.value = obj.config.max; + if (obj.config.value < obj.config.min) + obj.config.value = obj.config.min; + obj.originalValue = kvLookup('value', config, dataset, -1, 'float'); + if (obj.config.id !== null && (document.getElementById(obj.config.id)) !== null) { + obj.canvas = Raphael(obj.config.id, "100%", "100%"); + } else if (obj.config.parentNode !== null) { + obj.canvas = Raphael(obj.config.parentNode, "100%", "100%"); + } + if (obj.config.relativeGaugeSize === true) { + obj.canvas.setViewBox(0, 0, 200, 150, true); + } + if (obj.config.relativeGaugeSize === true) { + canvasW = 200; + canvasH = 150; + } else if (obj.config.width !== null && obj.config.height !== null) { + canvasW = obj.config.width; + canvasH = obj.config.height; + } else if (obj.config.parentNode !== null) { + obj.canvas.setViewBox(0, 0, 200, 150, true); + canvasW = 200; + canvasH = 150; + } else { + canvasW = getStyle(document.getElementById(obj.config.id), "width").slice(0, -2) * 1; + canvasH = getStyle(document.getElementById(obj.config.id), "height").slice(0, -2) * 1; + } + if (obj.config.donut === true) { + if (canvasW > canvasH) { + widgetH = canvasH; + widgetW = widgetH; + } else if (canvasW < canvasH) { + widgetW = canvasW; + widgetH = widgetW; + if (widgetH > canvasH) { + aspect = widgetH / canvasH; + widgetH = widgetH / aspect; + widgetW = widgetH / aspect; + } + } else { + widgetW = canvasW; + widgetH = widgetW; + } + dx = (canvasW - widgetW) / 2; + dy = (canvasH - widgetH) / 2; + titleFontSize = ((widgetH / 8) > 10) ? (widgetH / 10) : 10; + titleX = dx + widgetW / 2; + titleY = dy + widgetH / 11; + valueFontSize = ((widgetH / 6.4) > 16) ? (widgetH / 5.4) : 18; + valueX = dx + widgetW / 2; + if (obj.config.label !== '') { + valueY = dy + widgetH / 1.85; + } else { + valueY = dy + widgetH / 1.7; + } + labelFontSize = ((widgetH / 16) > 10) ? (widgetH / 16) : 10; + labelX = dx + widgetW / 2; + labelY = valueY + labelFontSize; + minFontSize = ((widgetH / 16) > 10) ? (widgetH / 16) : 10; + minX = dx + (widgetW / 10) + (widgetW / 6.666666666666667 * obj.config.gaugeWidthScale) / 2; + minY = labelY; + maxFontSize = ((widgetH / 16) > 10) ? (widgetH / 16) : 10; + maxX = dx + widgetW - (widgetW / 10) - (widgetW / 6.666666666666667 * obj.config.gaugeWidthScale) / 2; + maxY = labelY; + } else { + if (canvasW > canvasH) { + widgetH = canvasH; + widgetW = widgetH * 1.25; + if (widgetW > canvasW) { + aspect = widgetW / canvasW; + widgetW = widgetW / aspect; + widgetH = widgetH / aspect; + } + } else if (canvasW < canvasH) { + widgetW = canvasW; + widgetH = widgetW / 1.25; + if (widgetH > canvasH) { + aspect = widgetH / canvasH; + widgetH = widgetH / aspect; + widgetW = widgetH / aspect; + } + } else { + widgetW = canvasW; + widgetH = widgetW * 0.75; + } + dx = (canvasW - widgetW) / 2; + dy = (canvasH - widgetH) / 2; + if (obj.config.titlePosition === 'below') { + dy -= (widgetH / 6.4); + } + titleFontSize = ((widgetH / 8) > obj.config.titleMinFontSize) ? (widgetH / 10) : obj.config.titleMinFontSize; + titleX = dx + widgetW / 2; + titleY = dy + (obj.config.titlePosition === 'below' ? (widgetH * 1.07) : (widgetH / 6.4)); + valueFontSize = ((widgetH / 6.5) > obj.config.valueMinFontSize) ? (widgetH / 6.5) : obj.config.valueMinFontSize; + valueX = dx + widgetW / 2; + valueY = dy + widgetH / 1.275; + labelFontSize = ((widgetH / 16) > obj.config.labelMinFontSize) ? (widgetH / 16) : obj.config.labelMinFontSize; + labelX = dx + widgetW / 2; + labelY = valueY + valueFontSize / 2 + 5; + minFontSize = ((widgetH / 16) > obj.config.minLabelMinFontSize) ? (widgetH / 16) : obj.config.minLabelMinFontSize; + minX = dx + (widgetW / 10) + (widgetW / 6.666666666666667 * obj.config.gaugeWidthScale) / 2; + minY = labelY; + maxFontSize = ((widgetH / 16) > obj.config.maxLabelMinFontSize) ? (widgetH / 16) : obj.config.maxLabelMinFontSize; + maxX = dx + widgetW - (widgetW / 10) - (widgetW / 6.666666666666667 * obj.config.gaugeWidthScale) / 2; + maxY = labelY; + } + obj.params = { + canvasW: canvasW, + canvasH: canvasH, + widgetW: widgetW, + widgetH: widgetH, + dx: dx, + dy: dy, + titleFontSize: titleFontSize, + titleX: titleX, + titleY: titleY, + valueFontSize: valueFontSize, + valueX: valueX, + valueY: valueY, + labelFontSize: labelFontSize, + labelX: labelX, + labelY: labelY, + minFontSize: minFontSize, + minX: minX, + minY: minY, + maxFontSize: maxFontSize, + maxX: maxX, + maxY: maxY + }; + canvasW, + canvasH, + widgetW, + widgetH, + aspect, + dx, + dy, + titleFontSize, + titleX, + titleY, + valueFontSize, + valueX, + valueY, + labelFontSize, + labelX, + labelY, + minFontSize, + minX, + minY, + maxFontSize, + maxX, + maxY = null; + obj.canvas.customAttributes.pki = function (value, min, max, w, h, dx, dy, gws, donut, reverse) { + var alpha, + Ro, + Ri, + Cx, + Cy, + Xo, + Yo, + Xi, + Yi, + path; + if (donut) { + alpha = (1 - 2 * (value - min) / (max - min)) * Math.PI; + Ro = w / 2 - w / 7; + Ri = Ro - w / 6.666666666666667 * gws; + Cx = w / 2 + dx; + Cy = h / 1.95 + dy; + Xo = w / 2 + dx + Ro * Math.cos(alpha); + Yo = h - (h - Cy) - Ro * Math.sin(alpha); + Xi = w / 2 + dx + Ri * Math.cos(alpha); + Yi = h - (h - Cy) - Ri * Math.sin(alpha); + path = "M" + (Cx - Ri) + "," + Cy + " "; + path += "L" + (Cx - Ro) + "," + Cy + " "; + if (value > ((max - min) / 2)) { + path += "A" + Ro + "," + Ro + " 0 0 1 " + (Cx + Ro) + "," + Cy + " "; + } + path += "A" + Ro + "," + Ro + " 0 0 1 " + Xo + "," + Yo + " "; + path += "L" + Xi + "," + Yi + " "; + if (value > ((max - min) / 2)) { + path += "A" + Ri + "," + Ri + " 0 0 0 " + (Cx + Ri) + "," + Cy + " "; + } + path += "A" + Ri + "," + Ri + " 0 0 0 " + (Cx - Ri) + "," + Cy + " "; + path += "Z "; + return { + path: path + }; + } else { + alpha = (1 - (value - min) / (max - min)) * Math.PI; + Ro = w / 2 - w / 10; + Ri = Ro - w / 6.666666666666667 * gws; + Cx = w / 2 + dx; + Cy = h / 1.25 + dy; + Xo = w / 2 + dx + Ro * Math.cos(alpha); + Yo = h - (h - Cy) - Ro * Math.sin(alpha); + Xi = w / 2 + dx + Ri * Math.cos(alpha); + Yi = h - (h - Cy) - Ri * Math.sin(alpha); + path = "M" + (Cx - Ri) + "," + Cy + " "; + path += "L" + (Cx - Ro) + "," + Cy + " "; + path += "A" + Ro + "," + Ro + " 0 0 1 " + Xo + "," + Yo + " "; + path += "L" + Xi + "," + Yi + " "; + path += "A" + Ri + "," + Ri + " 0 0 0 " + (Cx - Ri) + "," + Cy + " "; + path += "Z "; + return { + path: path + }; + } + alpha, + Ro, + Ri, + Cx, + Cy, + Xo, + Yo, + Xi, + Yi, + path = null; + }; + obj.canvas.customAttributes.ndl = function (value, min, max, w, h, dx, dy, gws, donut) { + var dlt = w * 3.5 / 100; + var dlb = w / 15; + var dw = w / 100; + if (obj.config.pointerOptions.toplength != null && obj.config.pointerOptions.toplength != undefined) + dlt = obj.config.pointerOptions.toplength; + if (obj.config.pointerOptions.bottomlength != null && obj.config.pointerOptions.bottomlength != undefined) + dlb = obj.config.pointerOptions.bottomlength; + if (obj.config.pointerOptions.bottomwidth != null && obj.config.pointerOptions.bottomwidth != undefined) + dw = obj.config.pointerOptions.bottomwidth; + var alpha, + Ro, + Ri, + Cx, + Cy, + Xo, + Yo, + Xi, + Yi, + Xc, + Yc, + Xz, + Yz, + Xa, + Ya, + Xb, + Yb, + path; + if (donut) { + alpha = (1 - 2 * (value - min) / (max - min)) * Math.PI; + Ro = w / 2 - w / 7; + Ri = Ro - w / 6.666666666666667 * gws; + Cx = w / 2 + dx; + Cy = h / 1.95 + dy; + Xo = w / 2 + dx + Ro * Math.cos(alpha); + Yo = h - (h - Cy) - Ro * Math.sin(alpha); + Xi = w / 2 + dx + Ri * Math.cos(alpha); + Yi = h - (h - Cy) - Ri * Math.sin(alpha); + Xc = Xo + dlt * Math.cos(alpha); + Yc = Yo - dlt * Math.sin(alpha); + Xz = Xi - dlb * Math.cos(alpha); + Yz = Yi + dlb * Math.sin(alpha); + Xa = Xz + dw * Math.sin(alpha); + Ya = Yz + dw * Math.cos(alpha); + Xb = Xz - dw * Math.sin(alpha); + Yb = Yz - dw * Math.cos(alpha); + path = 'M' + Xa + ',' + Ya + ' '; + path += 'L' + Xb + ',' + Yb + ' '; + path += 'L' + Xc + ',' + Yc + ' '; + path += 'Z '; + return { + path: path + }; + } else { + alpha = (1 - (value - min) / (max - min)) * Math.PI; + Ro = w / 2 - w / 10; + Ri = Ro - w / 6.666666666666667 * gws; + Cx = w / 2 + dx; + Cy = h / 1.25 + dy; + Xo = w / 2 + dx + Ro * Math.cos(alpha); + Yo = h - (h - Cy) - Ro * Math.sin(alpha); + Xi = w / 2 + dx + Ri * Math.cos(alpha); + Yi = h - (h - Cy) - Ri * Math.sin(alpha); + Xc = Xo + dlt * Math.cos(alpha); + Yc = Yo - dlt * Math.sin(alpha); + Xz = Xi - dlb * Math.cos(alpha); + Yz = Yi + dlb * Math.sin(alpha); + Xa = Xz + dw * Math.sin(alpha); + Ya = Yz + dw * Math.cos(alpha); + Xb = Xz - dw * Math.sin(alpha); + Yb = Yz - dw * Math.cos(alpha); + path = 'M' + Xa + ',' + Ya + ' '; + path += 'L' + Xb + ',' + Yb + ' '; + path += 'L' + Xc + ',' + Yc + ' '; + path += 'Z '; + return { + path: path + }; + } + alpha, + Ro, + Ri, + Cx, + Cy, + Xo, + Yo, + Xi, + Yi, + Xc, + Yc, + Xz, + Yz, + Xa, + Ya, + Xb, + Yb, + path = null; + }; + obj.gauge = obj.canvas.path().attr({ + "stroke": "none", + "fill": obj.config.gaugeColor, + pki: [obj.config.max, obj.config.min, obj.config.max, obj.params.widgetW, obj.params.widgetH, obj.params.dx, obj.params.dy, obj.config.gaugeWidthScale, obj.config.donut, obj.config.reverse] + }); + obj.level = obj.canvas.path().attr({ + "stroke": "none", + "fill": getColor(obj.config.value, (obj.config.value - obj.config.min) / (obj.config.max - obj.config.min), obj.config.levelColors, obj.config.noGradient, obj.config.customSectors), + pki: [obj.config.min, obj.config.min, obj.config.max, obj.params.widgetW, obj.params.widgetH, obj.params.dx, obj.params.dy, obj.config.gaugeWidthScale, obj.config.donut, obj.config.reverse] + }); + if (obj.config.donut) { + obj.level.transform("r" + obj.config.donutStartAngle + ", " + (obj.params.widgetW / 2 + obj.params.dx) + ", " + (obj.params.widgetH / 1.95 + obj.params.dy)); + } + if (obj.config.pointer) { + obj.needle = obj.canvas.path().attr({ + "stroke": (obj.config.pointerOptions.stroke !== null && obj.config.pointerOptions.stroke !== undefined) ? obj.config.pointerOptions.stroke : "none", + "stroke-width": (obj.config.pointerOptions.stroke_width !== null && obj.config.pointerOptions.stroke_width !== undefined) ? obj.config.pointerOptions.stroke_width : 0, + "stroke-linecap": (obj.config.pointerOptions.stroke_linecap !== null && obj.config.pointerOptions.stroke_linecap !== undefined) ? obj.config.pointerOptions.stroke_linecap : "square", + "fill": (obj.config.pointerOptions.color !== null && obj.config.pointerOptions.color !== undefined) ? obj.config.pointerOptions.color : "#000000", + ndl: [obj.config.min, obj.config.min, obj.config.max, obj.params.widgetW, obj.params.widgetH, obj.params.dx, obj.params.dy, obj.config.gaugeWidthScale, obj.config.donut] + }); + if (obj.config.donut) { + obj.needle.transform("r" + obj.config.donutStartAngle + ", " + (obj.params.widgetW / 2 + obj.params.dx) + ", " + (obj.params.widgetH / 1.95 + obj.params.dy)); + } + } + obj.txtTitle = obj.canvas.text(obj.params.titleX, obj.params.titleY, obj.config.title); + obj.txtTitle.attr({ + "font-size": obj.params.titleFontSize, + "font-weight": "bold", + "font-family": obj.config.titleFontFamily, + "fill": obj.config.titleFontColor, + "fill-opacity": "1" + }); + setDy(obj.txtTitle, obj.params.titleFontSize, obj.params.titleY); + obj.txtValue = obj.canvas.text(obj.params.valueX, obj.params.valueY, 0); + obj.txtValue.attr({ + "font-size": obj.params.valueFontSize, + "font-weight": "bold", + "font-family": obj.config.valueFontFamily, + "fill": obj.config.valueFontColor, + "fill-opacity": "0" + }); + setDy(obj.txtValue, obj.params.valueFontSize, obj.params.valueY); + obj.txtLabel = obj.canvas.text(obj.params.labelX, obj.params.labelY, obj.config.label); + obj.txtLabel.attr({ + "font-size": obj.params.labelFontSize, + "font-weight": "normal", + "font-family": "Arial", + "fill": obj.config.labelFontColor, + "fill-opacity": "0" + }); + setDy(obj.txtLabel, obj.params.labelFontSize, obj.params.labelY); + var min = obj.config.min; + if (obj.config.reverse) { + min = obj.config.max; + } + obj.txtMinimum = min; + if (obj.config.humanFriendly) { + obj.txtMinimum = humanFriendlyNumber(min, obj.config.humanFriendlyDecimal); + } else if (obj.config.formatNumber) { + obj.txtMinimum = formatNumber(min); + } + obj.txtMin = obj.canvas.text(obj.params.minX, obj.params.minY, obj.txtMinimum); + obj.txtMin.attr({ + "font-size": obj.params.minFontSize, + "font-weight": "normal", + "font-family": "Arial", + "fill": obj.config.labelFontColor, + "fill-opacity": (obj.config.hideMinMax || obj.config.donut) ? "0" : "1" + }); + setDy(obj.txtMin, obj.params.minFontSize, obj.params.minY); + var max = obj.config.max; + if (obj.config.reverse) { + max = obj.config.min; + } + obj.txtMaximum = max; + if (obj.config.humanFriendly) { + obj.txtMaximum = humanFriendlyNumber(max, obj.config.humanFriendlyDecimal); + } else if (obj.config.formatNumber) { + obj.txtMaximum = formatNumber(max); + } + obj.txtMax = obj.canvas.text(obj.params.maxX, obj.params.maxY, obj.txtMaximum); + obj.txtMax.attr({ + "font-size": obj.params.maxFontSize, + "font-weight": "normal", + "font-family": "Arial", + "fill": obj.config.labelFontColor, + "fill-opacity": (obj.config.hideMinMax || obj.config.donut) ? "0" : "1" + }); + setDy(obj.txtMax, obj.params.maxFontSize, obj.params.maxY); + var defs = obj.canvas.canvas.childNodes[1]; + var svg = "http://www.w3.org/2000/svg"; + if (ie !== 'undefined' && ie < 9) {} + else if (ie !== 'undefined') { + onCreateElementNsReady(function () { + obj.generateShadow(svg, defs); + }); + } else { + obj.generateShadow(svg, defs); + } + defs, + svg = null; + if (obj.config.textRenderer) { + obj.originalValue = obj.config.textRenderer(obj.originalValue); + } else if (obj.config.humanFriendly) { + obj.originalValue = humanFriendlyNumber(obj.originalValue, obj.config.humanFriendlyDecimal) + obj.config.symbol; + } else if (obj.config.formatNumber) { + obj.originalValue = formatNumber(obj.originalValue) + obj.config.symbol; + } else { + obj.originalValue = (obj.originalValue * 1).toFixed(obj.config.decimals) + obj.config.symbol; + } + if (obj.config.counter === true) { + eve.on("raphael.anim.frame." + (obj.level.id), function () { + var currentValue = obj.level.attr("pki")[0]; + if (obj.config.reverse) { + currentValue = (obj.config.max * 1) + (obj.config.min * 1) - (obj.level.attr("pki")[0] * 1); + } + if (obj.config.textRenderer) { + obj.txtValue.attr("text", obj.config.textRenderer(Math.floor(currentValue))); + } else if (obj.config.humanFriendly) { + obj.txtValue.attr("text", humanFriendlyNumber(Math.floor(currentValue), obj.config.humanFriendlyDecimal) + obj.config.symbol); + } else if (obj.config.formatNumber) { + obj.txtValue.attr("text", formatNumber(Math.floor(currentValue)) + obj.config.symbol); + } else { + obj.txtValue.attr("text", (currentValue * 1).toFixed(obj.config.decimals) + obj.config.symbol); + } + setDy(obj.txtValue, obj.params.valueFontSize, obj.params.valueY); + currentValue = null; + }); + eve.on("raphael.anim.finish." + (obj.level.id), function () { + obj.txtValue.attr({ + "text": obj.originalValue + }); + setDy(obj.txtValue, obj.params.valueFontSize, obj.params.valueY); + }); + } else { + eve.on("raphael.anim.start." + (obj.level.id), function () { + obj.txtValue.attr({ + "text": obj.originalValue + }); + setDy(obj.txtValue, obj.params.valueFontSize, obj.params.valueY); + }); + } + var rvl = obj.config.value; + if (obj.config.reverse) { + rvl = (obj.config.max * 1) + (obj.config.min * 1) - (obj.config.value * 1); + } + obj.level.animate({ + pki: [rvl, obj.config.min, obj.config.max, obj.params.widgetW, obj.params.widgetH, obj.params.dx, obj.params.dy, obj.config.gaugeWidthScale, obj.config.donut, obj.config.reverse] + }, obj.config.startAnimationTime, obj.config.startAnimationType); + if (obj.config.pointer) { + obj.needle.animate({ + ndl: [rvl, obj.config.min, obj.config.max, obj.params.widgetW, obj.params.widgetH, obj.params.dx, obj.params.dy, obj.config.gaugeWidthScale, obj.config.donut] + }, obj.config.startAnimationTime, obj.config.startAnimationType); + } + obj.txtValue.animate({ + "fill-opacity": (obj.config.hideValue) ? "0" : "1" + }, obj.config.startAnimationTime, obj.config.startAnimationType); + obj.txtLabel.animate({ + "fill-opacity": "1" + }, obj.config.startAnimationTime, obj.config.startAnimationType); +}; +JustGage.prototype.refresh = function (val, max) { + var obj = this; + var displayVal, + color, + max = max || null; + if (max !== null) { + obj.config.max = max; + obj.txtMaximum = obj.config.max; + if (obj.config.humanFriendly) { + obj.txtMaximum = humanFriendlyNumber(obj.config.max, obj.config.humanFriendlyDecimal); + } else if (obj.config.formatNumber) { + obj.txtMaximum = formatNumber(obj.config.max); + } + if (!obj.config.reverse) { + obj.txtMax.attr({ + "text": obj.txtMaximum + }); + setDy(obj.txtMax, obj.params.maxFontSize, obj.params.maxY); + } else { + obj.txtMin.attr({ + "text": obj.txtMaximum + }); + setDy(obj.txtMin, obj.params.minFontSize, obj.params.minY); + } + } + displayVal = val; + if ((val * 1) > (obj.config.max * 1)) { + val = (obj.config.max * 1); + } + if ((val * 1) < (obj.config.min * 1)) { + val = (obj.config.min * 1); + } + color = getColor(val, (val - obj.config.min) / (obj.config.max - obj.config.min), obj.config.levelColors, obj.config.noGradient, obj.config.customSectors); + if (obj.config.textRenderer) { + displayVal = obj.config.textRenderer(displayVal); + } else if (obj.config.humanFriendly) { + displayVal = humanFriendlyNumber(displayVal, obj.config.humanFriendlyDecimal) + obj.config.symbol; + } else if (obj.config.formatNumber) { + displayVal = formatNumber((displayVal * 1).toFixed(obj.config.decimals)) + obj.config.symbol; + } else { + displayVal = (displayVal * 1).toFixed(obj.config.decimals) + obj.config.symbol; + } + obj.originalValue = displayVal; + obj.config.value = val * 1; + if (!obj.config.counter) { + obj.txtValue.attr({ + "text": displayVal + }); + setDy(obj.txtValue, obj.params.valueFontSize, obj.params.valueY); + } + var rvl = obj.config.value; + if (obj.config.reverse) { + rvl = (obj.config.max * 1) + (obj.config.min * 1) - (obj.config.value * 1); + } + obj.level.animate({ + pki: [rvl, obj.config.min, obj.config.max, obj.params.widgetW, obj.params.widgetH, obj.params.dx, obj.params.dy, obj.config.gaugeWidthScale, obj.config.donut, obj.config.reverse], + "fill": color + }, obj.config.refreshAnimationTime, obj.config.refreshAnimationType); + if (obj.config.pointer) { + obj.needle.animate({ + ndl: [rvl, obj.config.min, obj.config.max, obj.params.widgetW, obj.params.widgetH, obj.params.dx, obj.params.dy, obj.config.gaugeWidthScale, obj.config.donut] + }, obj.config.refreshAnimationTime, obj.config.refreshAnimationType); + } + obj, + displayVal, + color, + max = null; +}; +JustGage.prototype.generateShadow = function (svg, defs) { + var obj = this; + var sid = "inner-shadow-" + obj.config.id; + var gaussFilter, + feOffset, + feGaussianBlur, + feComposite1, + feFlood, + feComposite2, + feComposite3; + gaussFilter = document.createElementNS(svg, "filter"); + gaussFilter.setAttribute("id", sid); + defs.appendChild(gaussFilter); + feOffset = document.createElementNS(svg, "feOffset"); + feOffset.setAttribute("dx", 0); + feOffset.setAttribute("dy", obj.config.shadowVerticalOffset); + gaussFilter.appendChild(feOffset); + feGaussianBlur = document.createElementNS(svg, "feGaussianBlur"); + feGaussianBlur.setAttribute("result", "offset-blur"); + feGaussianBlur.setAttribute("stdDeviation", obj.config.shadowSize); + gaussFilter.appendChild(feGaussianBlur); + feComposite1 = document.createElementNS(svg, "feComposite"); + feComposite1.setAttribute("operator", "out"); + feComposite1.setAttribute("in", "SourceGraphic"); + feComposite1.setAttribute("in2", "offset-blur"); + feComposite1.setAttribute("result", "inverse"); + gaussFilter.appendChild(feComposite1); + feFlood = document.createElementNS(svg, "feFlood"); + feFlood.setAttribute("flood-color", "black"); + feFlood.setAttribute("flood-opacity", obj.config.shadowOpacity); + feFlood.setAttribute("result", "color"); + gaussFilter.appendChild(feFlood); + feComposite2 = document.createElementNS(svg, "feComposite"); + feComposite2.setAttribute("operator", "in"); + feComposite2.setAttribute("in", "color"); + feComposite2.setAttribute("in2", "inverse"); + feComposite2.setAttribute("result", "shadow"); + gaussFilter.appendChild(feComposite2); + feComposite3 = document.createElementNS(svg, "feComposite"); + feComposite3.setAttribute("operator", "over"); + feComposite3.setAttribute("in", "shadow"); + feComposite3.setAttribute("in2", "SourceGraphic"); + gaussFilter.appendChild(feComposite3); + if (!obj.config.hideInnerShadow) { + obj.canvas.canvas.childNodes[2].setAttribute("filter", "url(#" + sid + ")"); + obj.canvas.canvas.childNodes[3].setAttribute("filter", "url(#" + sid + ")"); + } + gaussFilter, + feOffset, + feGaussianBlur, + feComposite1, + feFlood, + feComposite2, + feComposite3 = null; +}; +function kvLookup(key, tablea, tableb, defval, datatype, delimiter) { + var val = defval; + var canConvert = false; + if (!(key === null || key === undefined)) { + if (tableb !== null && tableb !== undefined && typeof tableb === "object" && key in tableb) { + val = tableb[key]; + canConvert = true; + } else if (tablea !== null && tablea !== undefined && typeof tablea === "object" && key in tablea) { + val = tablea[key]; + canConvert = true; + } else { + val = defval; + } + if (canConvert === true) { + if (datatype !== null && datatype !== undefined) { + switch (datatype) { + case 'int': + val = parseInt(val, 10); + break; + case 'float': + val = parseFloat(val); + break; + default: + break; + } + } + } + } + return val; +}; +function getColor(val, pct, col, noGradient, custSec) { + var no, + inc, + colors, + percentage, + rval, + gval, + bval, + lower, + upper, + range, + rangePct, + pctLower, + pctUpper, + color; + var noGradient = noGradient || custSec.length > 0; + if (custSec.length > 0) { + for (var i = 0; i < custSec.length; i++) { + if (val > custSec[i].lo && val <= custSec[i].hi) { + return custSec[i].color; + } + } + } + no = col.length; + if (no === 1) + return col[0]; + inc = (noGradient) ? (1 / no) : (1 / (no - 1)); + colors = []; + for (i = 0; i < col.length; i++) { + percentage = (noGradient) ? (inc * (i + 1)) : (inc * i); + rval = parseInt((cutHex(col[i])).substring(0, 2), 16); + gval = parseInt((cutHex(col[i])).substring(2, 4), 16); + bval = parseInt((cutHex(col[i])).substring(4, 6), 16); + colors[i] = { + pct: percentage, + color: { + r: rval, + g: gval, + b: bval + } + }; + } + if (pct === 0) { + return 'rgb(' + [colors[0].color.r, colors[0].color.g, colors[0].color.b].join(',') + ')'; + } + for (var j = 0; j < colors.length; j++) { + if (pct <= colors[j].pct) { + if (noGradient) { + return 'rgb(' + [colors[j].color.r, colors[j].color.g, colors[j].color.b].join(',') + ')'; + } else { + lower = colors[j - 1]; + upper = colors[j]; + range = upper.pct - lower.pct; + rangePct = (pct - lower.pct) / range; + pctLower = 1 - rangePct; + pctUpper = rangePct; + color = { + r: Math.floor(lower.color.r * pctLower + upper.color.r * pctUpper), + g: Math.floor(lower.color.g * pctLower + upper.color.g * pctUpper), + b: Math.floor(lower.color.b * pctLower + upper.color.b * pctUpper) + }; + return 'rgb(' + [color.r, color.g, color.b].join(',') + ')'; + } + } + } +} +function setDy(elem, fontSize, txtYpos) { + if ((!ie || ie > 9) && elem.node.firstChild.attributes.dy) { + elem.node.firstChild.attributes.dy.value = 0; + } +} +function getRandomInt(min, max) { + return Math.floor(Math.random() * (max - min + 1)) + min; +} +function cutHex(str) { + return (str.charAt(0) == "#") ? str.substring(1, 7) : str; +} +function humanFriendlyNumber(n, d) { + var p, + d2, + i, + s; + p = Math.pow; + d2 = p(10, d); + i = 7; + while (i) { + s = p(10, i-- * 3); + if (s <= n) { + n = Math.round(n * d2 / s) / d2 + "KMGTPE"[i]; + } + } + return n; +} +function formatNumber(x) { + var parts = x.toString().split("."); + parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ","); + return parts.join("."); +} +function getStyle(oElm, strCssRule) { + var strValue = ""; + if (document.defaultView && document.defaultView.getComputedStyle) { + strValue = document.defaultView.getComputedStyle(oElm, "").getPropertyValue(strCssRule); + } else if (oElm.currentStyle) { + strCssRule = strCssRule.replace(/\-(\w)/g, function (strMatch, p1) { + return p1.toUpperCase(); + }); + strValue = oElm.currentStyle[strCssRule]; + } + return strValue; +} +function onCreateElementNsReady(func) { + if (document.createElementNS !== undefined) { + func(); + } else { + setTimeout(function () { + onCreateElementNsReady(func); + }, 100); + } +} +var ie = (function () { + var undef, + v = 3, + div = document.createElement('div'), + all = div.getElementsByTagName('i'); + while (div.innerHTML = '', all[0]); + return v > 4 ? v : undef; +} + ()); +function extend(out) { + out = out || {}; + for (var i = 1; i < arguments.length; i++) { + if (!arguments[i]) + continue; + for (var key in arguments[i]) { + if (arguments[i].hasOwnProperty(key)) + out[key] = arguments[i][key]; + } + } + return out; +}; diff --git a/examples/SmartSwitch/data_src/js_css_src/desktop.ini b/examples/SmartSwitch/data_src/js_css_src/desktop.ini new file mode 100644 index 000000000..00f30c4a3 --- /dev/null +++ b/examples/SmartSwitch/data_src/js_css_src/desktop.ini @@ -0,0 +1,2 @@ +[LocalizedFileNames] +Command Prompt.lnk=@%SystemRoot%\system32\shell32.dll,-22022 diff --git a/examples/SmartSwitch/data_src/js_css_src/ext-searchbox.js b/examples/SmartSwitch/data_src/js_css_src/ext-searchbox.js new file mode 100644 index 000000000..b38b622ce --- /dev/null +++ b/examples/SmartSwitch/data_src/js_css_src/ext-searchbox.js @@ -0,0 +1,5 @@ +define("ace/ext/searchbox",["require","exports","module","ace/lib/dom","ace/lib/lang","ace/lib/event","ace/keyboard/hash_handler","ace/lib/keys"],function(e,t,n){"use strict";var r=e("../lib/dom"),i=e("../lib/lang"),s=e("../lib/event"),o=".ace_search {background-color: #ddd;border: 1px solid #cbcbcb;border-top: 0 none;max-width: 325px;overflow: hidden;margin: 0;padding: 4px;padding-right: 6px;padding-bottom: 0;position: absolute;top: 0px;z-index: 99;white-space: normal;}.ace_search.left {border-left: 0 none;border-radius: 0px 0px 5px 0px;left: 0;}.ace_search.right {border-radius: 0px 0px 0px 5px;border-right: 0 none;right: 0;}.ace_search_form, .ace_replace_form {border-radius: 3px;border: 1px solid #cbcbcb;float: left;margin-bottom: 4px;overflow: hidden;}.ace_search_form.ace_nomatch {outline: 1px solid red;}.ace_search_field {background-color: white;color: black;border-right: 1px solid #cbcbcb;border: 0 none;-webkit-box-sizing: border-box;-moz-box-sizing: border-box;box-sizing: border-box;float: left;height: 22px;outline: 0;padding: 0 7px;width: 214px;margin: 0;}.ace_searchbtn,.ace_replacebtn {background: #fff;border: 0 none;border-left: 1px solid #dcdcdc;cursor: pointer;float: left;height: 22px;margin: 0;position: relative;}.ace_searchbtn:last-child,.ace_replacebtn:last-child {border-top-right-radius: 3px;border-bottom-right-radius: 3px;}.ace_searchbtn:disabled {background: none;cursor: default;}.ace_searchbtn {background-position: 50% 50%;background-repeat: no-repeat;width: 27px;}.ace_searchbtn.prev {background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAFCAYAAAB4ka1VAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAADFJREFUeNpiSU1NZUAC/6E0I0yACYskCpsJiySKIiY0SUZk40FyTEgCjGgKwTRAgAEAQJUIPCE+qfkAAAAASUVORK5CYII=); }.ace_searchbtn.next {background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAFCAYAAAB4ka1VAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAADRJREFUeNpiTE1NZQCC/0DMyIAKwGJMUAYDEo3M/s+EpvM/mkKwCQxYjIeLMaELoLMBAgwAU7UJObTKsvAAAAAASUVORK5CYII=); }.ace_searchbtn_close {background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAcCAYAAABRVo5BAAAAZ0lEQVR42u2SUQrAMAhDvazn8OjZBilCkYVVxiis8H4CT0VrAJb4WHT3C5xU2a2IQZXJjiQIRMdkEoJ5Q2yMqpfDIo+XY4k6h+YXOyKqTIj5REaxloNAd0xiKmAtsTHqW8sR2W5f7gCu5nWFUpVjZwAAAABJRU5ErkJggg==) no-repeat 50% 0;border-radius: 50%;border: 0 none;color: #656565;cursor: pointer;float: right;font: 16px/16px Arial;height: 14px;margin: 5px 1px 9px 5px;padding: 0;text-align: center;width: 14px;}.ace_searchbtn_close:hover {background-color: #656565;background-position: 50% 100%;color: white;}.ace_replacebtn.prev {width: 54px}.ace_replacebtn.next {width: 27px}.ace_button {margin-left: 2px;cursor: pointer;-webkit-user-select: none;-moz-user-select: none;-o-user-select: none;-ms-user-select: none;user-select: none;overflow: hidden;opacity: 0.7;border: 1px solid rgba(100,100,100,0.23);padding: 1px;-moz-box-sizing: border-box;box-sizing: border-box;color: black;}.ace_button:hover {background-color: #eee;opacity:1;}.ace_button:active {background-color: #ddd;}.ace_button.checked {border-color: #3399ff;opacity:1;}.ace_search_options{margin-bottom: 3px;text-align: right;-webkit-user-select: none;-moz-user-select: none;-o-user-select: none;-ms-user-select: none;user-select: none;}",u=e("../keyboard/hash_handler").HashHandler,a=e("../lib/keys");r.importCssString(o,"ace_searchbox");var f=''.replace(/>\s+/g,">"),l=function(e,t,n){var i=r.createElement("div");i.innerHTML=f,this.element=i.firstChild,this.$init(),this.setEditor(e)};(function(){this.setEditor=function(e){e.searchBox=this,e.container.appendChild(this.element),this.editor=e},this.$initElements=function(e){this.searchBox=e.querySelector(".ace_search_form"),this.replaceBox=e.querySelector(".ace_replace_form"),this.searchOptions=e.querySelector(".ace_search_options"),this.regExpOption=e.querySelector("[action=toggleRegexpMode]"),this.caseSensitiveOption=e.querySelector("[action=toggleCaseSensitive]"),this.wholeWordOption=e.querySelector("[action=toggleWholeWords]"),this.searchInput=this.searchBox.querySelector(".ace_search_field"),this.replaceInput=this.replaceBox.querySelector(".ace_search_field")},this.$init=function(){var e=this.element;this.$initElements(e);var t=this;s.addListener(e,"mousedown",function(e){setTimeout(function(){t.activeInput.focus()},0),s.stopPropagation(e)}),s.addListener(e,"click",function(e){var n=e.target||e.srcElement,r=n.getAttribute("action");r&&t[r]?t[r]():t.$searchBarKb.commands[r]&&t.$searchBarKb.commands[r].exec(t),s.stopPropagation(e)}),s.addCommandKeyListener(e,function(e,n,r){var i=a.keyCodeToString(r),o=t.$searchBarKb.findKeyCommand(n,i);o&&o.exec&&(o.exec(t),s.stopEvent(e))}),this.$onChange=i.delayedCall(function(){t.find(!1,!1)}),s.addListener(this.searchInput,"input",function(){t.$onChange.schedule(20)}),s.addListener(this.searchInput,"focus",function(){t.activeInput=t.searchInput,t.searchInput.value&&t.highlight()}),s.addListener(this.replaceInput,"focus",function(){t.activeInput=t.replaceInput,t.searchInput.value&&t.highlight()})},this.$closeSearchBarKb=new u([{bindKey:"Esc",name:"closeSearchBar",exec:function(e){e.searchBox.hide()}}]),this.$searchBarKb=new u,this.$searchBarKb.bindKeys({"Ctrl-f|Command-f":function(e){var t=e.isReplace=!e.isReplace;e.replaceBox.style.display=t?"":"none",e.searchInput.focus()},"Ctrl-H|Command-Option-F":function(e){e.replaceBox.style.display="",e.replaceInput.focus()},"Ctrl-G|Command-G":function(e){e.findNext()},"Ctrl-Shift-G|Command-Shift-G":function(e){e.findPrev()},esc:function(e){setTimeout(function(){e.hide()})},Return:function(e){e.activeInput==e.replaceInput&&e.replace(),e.findNext()},"Shift-Return":function(e){e.activeInput==e.replaceInput&&e.replace(),e.findPrev()},"Alt-Return":function(e){e.activeInput==e.replaceInput&&e.replaceAll(),e.findAll()},Tab:function(e){(e.activeInput==e.replaceInput?e.searchInput:e.replaceInput).focus()}}),this.$searchBarKb.addCommands([{name:"toggleRegexpMode",bindKey:{win:"Alt-R|Alt-/",mac:"Ctrl-Alt-R|Ctrl-Alt-/"},exec:function(e){e.regExpOption.checked=!e.regExpOption.checked,e.$syncOptions()}},{name:"toggleCaseSensitive",bindKey:{win:"Alt-C|Alt-I",mac:"Ctrl-Alt-R|Ctrl-Alt-I"},exec:function(e){e.caseSensitiveOption.checked=!e.caseSensitiveOption.checked,e.$syncOptions()}},{name:"toggleWholeWords",bindKey:{win:"Alt-B|Alt-W",mac:"Ctrl-Alt-B|Ctrl-Alt-W"},exec:function(e){e.wholeWordOption.checked=!e.wholeWordOption.checked,e.$syncOptions()}}]),this.$syncOptions=function(){r.setCssClass(this.regExpOption,"checked",this.regExpOption.checked),r.setCssClass(this.wholeWordOption,"checked",this.wholeWordOption.checked),r.setCssClass(this.caseSensitiveOption,"checked",this.caseSensitiveOption.checked),this.find(!1,!1)},this.highlight=function(e){this.editor.session.highlight(e||this.editor.$search.$options.re),this.editor.renderer.updateBackMarkers()},this.find=function(e,t,n){var i=this.editor.find(this.searchInput.value,{skipCurrent:e,backwards:t,wrap:!0,regExp:this.regExpOption.checked,caseSensitive:this.caseSensitiveOption.checked,wholeWord:this.wholeWordOption.checked,preventScroll:n}),s=!i&&this.searchInput.value;r.setCssClass(this.searchBox,"ace_nomatch",s),this.editor._emit("findSearchBox",{match:!s}),this.highlight()},this.findNext=function(){this.find(!0,!1)},this.findPrev=function(){this.find(!0,!0)},this.findAll=function(){var e=this.editor.findAll(this.searchInput.value,{regExp:this.regExpOption.checked,caseSensitive:this.caseSensitiveOption.checked,wholeWord:this.wholeWordOption.checked}),t=!e&&this.searchInput.value;r.setCssClass(this.searchBox,"ace_nomatch",t),this.editor._emit("findSearchBox",{match:!t}),this.highlight(),this.hide()},this.replace=function(){this.editor.getReadOnly()||this.editor.replace(this.replaceInput.value)},this.replaceAndFindNext=function(){this.editor.getReadOnly()||(this.editor.replace(this.replaceInput.value),this.findNext())},this.replaceAll=function(){this.editor.getReadOnly()||this.editor.replaceAll(this.replaceInput.value)},this.hide=function(){this.element.style.display="none",this.editor.keyBinding.removeKeyboardHandler(this.$closeSearchBarKb),this.editor.focus()},this.show=function(e,t){this.element.style.display="",this.replaceBox.style.display=t?"":"none",this.isReplace=t,e&&(this.searchInput.value=e),this.find(!1,!1,!0),this.searchInput.focus(),this.searchInput.select(),this.editor.keyBinding.addKeyboardHandler(this.$closeSearchBarKb)},this.isFocused=function(){var e=document.activeElement;return e==this.searchInput||e==this.replaceInput}}).call(l.prototype),t.SearchBox=l,t.Search=function(e,t){var n=e.searchBox||new l(e);n.show(e.session.getTextRange(),t)}}); + (function() { + window.require(["ace/ext/searchbox"], function() {}); + })(); + \ No newline at end of file diff --git a/examples/SmartSwitch/data_src/js_css_src/js-time-picker/1-inline.html b/examples/SmartSwitch/data_src/js_css_src/js-time-picker/1-inline.html new file mode 100644 index 000000000..22160e924 --- /dev/null +++ b/examples/SmartSwitch/data_src/js_css_src/js-time-picker/1-inline.html @@ -0,0 +1,30 @@ + + + + Inline Timepicker Example + + + + + + +

Inline Time Picker

+ +
TIME ON
+
+
TIME OFF
+ + + + + \ No newline at end of file diff --git a/examples/SmartSwitch/data_src/js_css_src/js-time-picker/2-popup.html b/examples/SmartSwitch/data_src/js_css_src/js-time-picker/2-popup.html new file mode 100644 index 000000000..162339a50 --- /dev/null +++ b/examples/SmartSwitch/data_src/js_css_src/js-time-picker/2-popup.html @@ -0,0 +1,27 @@ + + + + Popup Timeicker Example + + + + + + +

Popup Time Picker

+ + + ON/OFF +

Line

+ + + + + \ No newline at end of file diff --git a/examples/SmartSwitch/data_src/js_css_src/js-time-picker/README.txt b/examples/SmartSwitch/data_src/js_css_src/js-time-picker/README.txt new file mode 100644 index 000000000..b09dd21f3 --- /dev/null +++ b/examples/SmartSwitch/data_src/js_css_src/js-time-picker/README.txt @@ -0,0 +1,29 @@ +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +LICENSE +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +Copyright 2018 by Code Boxx + +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: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +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. + + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +MORE +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +Please visit https://code-boxx.com/ for more! \ No newline at end of file diff --git a/examples/SmartSwitch/data_src/js_css_src/js-time-picker/tpick-light-pop.css b/examples/SmartSwitch/data_src/js_css_src/js-time-picker/tpick-light-pop.css new file mode 100644 index 000000000..cacbdb365 --- /dev/null +++ b/examples/SmartSwitch/data_src/js_css_src/js-time-picker/tpick-light-pop.css @@ -0,0 +1,65 @@ +/* [CONTAINER] */ +.tpop { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100vh; + background: rgba(0, 0, 0, 0.7); + transition: all 0.5s; + visibility: hidden; + opacity: 0; +} +.tpop.show { + visibility: visible; + opacity: 1; +} +.tpicker { + background: #f2f2f2; + padding: 10px; + width: 100%; + max-width: 320px; + white-space: nowrap; + font-size: 32px; + font-weight: bold; + text-align: center; +} +.tpop .tpicker { + margin: 20px auto 0 auto; +} + +/* [HR + MIN + AM/PM] */ +.tpicker-h, .tpicker-m, .tpicker-ap { + display: inline-block; + width: 30%; +} +.tpicker input[type=text] { + box-sizing: border-box; + width: 70%; + padding: 10px; + margin: 5px 0; + border: 0; + background: #fff; + color: #888; + text-align: center; + font-size: 28px; +} +.tpicker-up, .tpicker-down { + text-align: center; + color: #ff853f; + cursor: pointer; +} + +/* [CANCEL + OK BUTTON] */ +.tpicker-btn { + margin-top: 10px; +} +.tpicker-btn input[type=button] { + width: 50%; + padding: 10px 0; + border: 0; + background: #a83a0b; + color: #fff; + font-size: 20px; + cursor: pointer; +} \ No newline at end of file diff --git a/examples/SmartSwitch/data_src/js_css_src/js-time-picker/tpick-light.css b/examples/SmartSwitch/data_src/js_css_src/js-time-picker/tpick-light.css new file mode 100644 index 000000000..58676b4ff --- /dev/null +++ b/examples/SmartSwitch/data_src/js_css_src/js-time-picker/tpick-light.css @@ -0,0 +1,47 @@ +/* [CONTAINER] */ +.tpicker { + background: #f2f2f2; + padding: 10px; + width: 100%; + max-width: 320px; + white-space: nowrap; + font-size: 32px; + font-weight: bold; + text-align: center; +} + +/* [HR + MIN + AM/PM] */ +.tpicker-h, .tpicker-m, .tpicker-ap { + display: inline-block; + width: 30%; +} +.tpicker input[type=text] { + box-sizing: border-box; + width: 70%; + padding: 10px; + margin: 5px 0; + border: 0; + background: #fff; + color: #888; + text-align: center; + font-size: 28px; +} +.tpicker-up, .tpicker-down { + text-align: center; + color: #ff853f; + cursor: pointer; +} + +/* [CANCEL + OK BUTTON] */ +.tpicker-btn { + margin-top: 10px; +} +.tpicker-btn input[type=button] { + width: 50%; + padding: 10px 0; + border: 0; + background: #a83a0b; + color: #fff; + font-size: 20px; + cursor: pointer; +} \ No newline at end of file diff --git a/examples/SmartSwitch/data_src/js_css_src/js-time-picker/tpick-pop.js b/examples/SmartSwitch/data_src/js_css_src/js-time-picker/tpick-pop.js new file mode 100644 index 000000000..c52a2da5b --- /dev/null +++ b/examples/SmartSwitch/data_src/js_css_src/js-time-picker/tpick-pop.js @@ -0,0 +1,136 @@ +var tpick = { + attach : function (target) { + // attach() : attach time picker to target + + // Generate a unique random ID for the time picker + var uniqueID = 0; + while (document.getElementById("tpick-" + uniqueID) != null) { + uniqueID = Math.floor(Math.random() * (100 - 2)) + 1; + } + + // Create wrapper + var tw = document.createElement("div"); + tw.id = "tpick-" + uniqueID; + tw.classList.add("tpop"); + tw.dataset.target = target; + tw.addEventListener("click", function (evt) { + if (evt.target.classList.contains("tpop")) { + this.classList.remove("show"); + } + }); + + // Create new time picker + var tp = document.createElement("div"); + tp.classList.add("tpicker"); + + // Create hour picker + tp.appendChild(this.draw("h")); + tp.appendChild(this.draw("m")); + tp.appendChild(this.draw("ap")); + + // OK button + var bottom = document.createElement("div"), + ok = document.createElement("input"); + ok.setAttribute("type", "button"); + ok.value = "OK"; + ok.addEventListener("click", function(){ tpick.set(this); }); + bottom.classList.add("tpicker-btn"); + bottom.appendChild(ok); + tp.appendChild(bottom); + + // Attach time picker to body + tw.appendChild(tp); + document.body.appendChild(tw); + + // Attach on focus event + var target = document.getElementById(target); + target.dataset.dp = uniqueID; + target.onfocus = function () { + document.getElementById("tpick-" + this.dataset.dp).classList.add("show"); + }; + }, + + draw : function (type) { + // draw() : support function to create the hr, min, am/pm selector + + // Create the controls + var docket = document.createElement("div"), + up = document.createElement("div"), + down = document.createElement("div"), + text = document.createElement("input"); + docket.classList.add("tpicker-" + type); + up.classList.add("tpicker-up"); + down.classList.add("tpicker-down"); + up.innerHTML = "︿"; + down.innerHTML = "﹀"; + text.readOnly = true; + text.setAttribute("type", "text"); + + // Default values + click event + // You can do your own modifications here + if (type=="h") { + text.value = "12"; + up.addEventListener("click", function(){ tpick.spin("h", 1, this); }); + down.addEventListener("click", function(){ tpick.spin("h", 0, this); }); + } else if (type=="m") { + text.value = "10"; + up.addEventListener("click", function(){ tpick.spin("m", 1, this); }); + down.addEventListener("click", function(){ tpick.spin("m", 0, this); }); + } else { + text.value = "AM"; + up.addEventListener("click", function(){ tpick.spin("ap", 1, this); }); + down.addEventListener("click", function(){ tpick.spin("ap", 0, this); }); + } + + // Complete + return the docket + docket.appendChild(up); + docket.appendChild(text); + docket.appendChild(down); + return docket; + }, + + spin : function (type, direction, el) { + // spin() : when the up/down button is pressed + + // Get current field + value + var parent = el.parentElement, + field = parent.getElementsByTagName("input")[0], + value = field.value; + + // Spin it + if (type=="h") { + value = parseInt(value); + if (direction) { value++; } else { value--; } + if (value==0) { value = 12; } + else if (value>12) { value = 1; } + } else if (type=="m") { + value = parseInt(value); + if (direction) { value+=5; } else { value-=5; } + if (value<0) { value = 55; } + else if (value>60) { value = 0; } + if (value<10) { value = "0" + value; } + } + else { + value = value=="PM" ? "AM" : "PM"; + } + field.value = value; + }, + + set : function (el) { + // set() : set the selected time on the target + + // Get the parent container + var parent = el.parentElement; + while (parent.classList.contains("tpop") == false) { + parent = parent.parentElement; + } + + // Formulate + set selected time + var input = parent.querySelectorAll("input[type=text]"); + var time = input[0].value + ":" + input[1].value + " " + input[2].value; + document.getElementById(parent.dataset.target).value = time; + + // Close popup + parent.classList.remove("show"); + } +}; \ No newline at end of file diff --git a/examples/SmartSwitch/data_src/js_css_src/js-time-picker/tpick.js b/examples/SmartSwitch/data_src/js_css_src/js-time-picker/tpick.js new file mode 100644 index 000000000..799142c30 --- /dev/null +++ b/examples/SmartSwitch/data_src/js_css_src/js-time-picker/tpick.js @@ -0,0 +1,116 @@ +var tpick = { + attach : function (container, target) { + // attach() : attach time picker to target + + // Generate a unique random ID for the time picker + var uniqueID = 0; + while (document.getElementById("tpick-" + uniqueID) != null) { + uniqueID = Math.floor(Math.random() * (100 - 2)) + 1; + } + + // Create new time picker + var tp = document.createElement("div"); + tp.id = "tpick-" + uniqueID; + tp.dataset.target = target; + tp.classList.add("tpicker"); + + // Create hour picker + tp.appendChild(this.draw("h")); + tp.appendChild(this.draw("m")); + tp.appendChild(this.draw("ap")); + + // OK button + var bottom = document.createElement("div"), + ok = document.createElement("input"); + ok.setAttribute("type", "button"); + ok.value = "OK"; + ok.addEventListener("click", function(){ tpick.set(this); }); + bottom.classList.add("tpicker-btn"); + bottom.appendChild(ok); + tp.appendChild(bottom); + + // Attach time picker to target container + document.getElementById(container).appendChild(tp); + }, + + draw : function (type) { + // draw() : support function to create the hr, min, am/pm selector + + // Create the controls + var docket = document.createElement("div"), + up = document.createElement("div"), + down = document.createElement("div"), + text = document.createElement("input"); + docket.classList.add("tpicker-" + type); + up.classList.add("tpicker-up"); + down.classList.add("tpicker-down"); + up.innerHTML = "︿"; + down.innerHTML = "﹀"; + text.readOnly = true; + text.setAttribute("type", "text"); + + // Default values + click event + // You can do your own modifications here + if (type=="h") { + text.value = "12"; + up.addEventListener("click", function(){ tpick.spin("h", 1, this); }); + down.addEventListener("click", function(){ tpick.spin("h", 0, this); }); + } else if (type=="m") { + text.value = "10"; + up.addEventListener("click", function(){ tpick.spin("m", 1, this); }); + down.addEventListener("click", function(){ tpick.spin("m", 0, this); }); + } else { + text.value = "AM"; + up.addEventListener("click", function(){ tpick.spin("ap", 1, this); }); + down.addEventListener("click", function(){ tpick.spin("ap", 0, this); }); + } + + // Complete + return the docket + docket.appendChild(up); + docket.appendChild(text); + docket.appendChild(down); + return docket; + }, + + spin : function (type, direction, el) { + // spin() : when the up/down button is pressed + + // Get current field + value + var parent = el.parentElement, + field = parent.getElementsByTagName("input")[0], + value = field.value; + + // Spin it + if (type=="h") { + value = parseInt(value); + if (direction) { value++; } else { value--; } + if (value==0) { value = 12; } + else if (value>12) { value = 1; } + } else if (type=="m") { + value = parseInt(value); + if (direction) { value+=5; } else { value-=5; } + if (value<0) { value = 55; } + else if (value>60) { value = 0; } + if (value<10) { value = "0" + value; } + } + else { + value = value=="PM" ? "AM" : "PM"; + } + field.value = value; + }, + + set : function (el) { + // set() : set the selected time on the target + + // Get the parent container + var parent = el.parentElement; + while (parent.classList.contains("tpicker") == false) { + parent = parent.parentElement; + } + + // Formulate + set selected time + var input = parent.querySelectorAll("input[type=text]"); + var time = input[0].value + ":" + input[1].value + " " + input[2].value; + document.getElementById(parent.dataset.target).value = time; + } +}; \ No newline at end of file diff --git a/examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/auto-adjust.htm b/examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/auto-adjust.htm new file mode 100644 index 000000000..28903cfaa --- /dev/null +++ b/examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/auto-adjust.htm @@ -0,0 +1,94 @@ + + + + + Auto-adjust + + + + + + +
+
+
+
+

+ JustGage auto-adjusts to the size of containing element. And to the screen zoom level. And screen density. Nice. This means you’ll get clean, sharp and nice looking gauge at all times. Try zooming the page to see the results. +

+ + + + + + diff --git a/examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/counter.html b/examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/counter.html new file mode 100644 index 000000000..406959395 --- /dev/null +++ b/examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/counter.html @@ -0,0 +1,58 @@ + + + + + + Counter + + + + + +
+ + + + + + diff --git a/examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/custom-interval.htm b/examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/custom-interval.htm new file mode 100644 index 000000000..6c58bda33 --- /dev/null +++ b/examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/custom-interval.htm @@ -0,0 +1,82 @@ + + + + + Custom interval + + + + + +
+
+
+

+ You need to measure, say, between 350 and 980? No problem, just tell it to justGage. Displayed value and color are calculated as a percentage in defined range, with optional min and max labels shown. +

+

+ Also, if displayed value is out of range, relax and kick your feet up - justGage will take care of it for you. +

+ + + + + + diff --git a/examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/custom-node.html b/examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/custom-node.html new file mode 100644 index 000000000..98964e13d --- /dev/null +++ b/examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/custom-node.html @@ -0,0 +1,130 @@ + + + + + Custom Node + + + + + + +
+
+
+
+
+ + +
+
+ + + + +
+ + + + + + diff --git a/examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/custom-sectors.html b/examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/custom-sectors.html new file mode 100644 index 000000000..a868de6d3 --- /dev/null +++ b/examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/custom-sectors.html @@ -0,0 +1,88 @@ + + + + + + Custom Sectors + + + + + + + + + +
+
+

0-50 is green, 51-100 is red

+ Random Refresh + Update Sectors +
+ + + + + + \ No newline at end of file diff --git a/examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/custom-value-renderer.html b/examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/custom-value-renderer.html new file mode 100644 index 000000000..2e5b0f395 --- /dev/null +++ b/examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/custom-value-renderer.html @@ -0,0 +1,116 @@ + + + + + + Custom Render Function + + + + +
+ Random Refresh + + + + + + diff --git a/examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/customize-style.htm b/examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/customize-style.htm new file mode 100644 index 000000000..9be11d1eb --- /dev/null +++ b/examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/customize-style.htm @@ -0,0 +1,137 @@ + + + + + Customize style + + + + + + +
+
+
+
+
+
+

+ Not digging default style? Then mock your own, Picasso! JustGage features bunch of styling options including gauge width, gauge color and shadow, gauge level colors, colors for title, value, min & max etc. +

+

+ Check non-minified version of justgage.js for list of all setup parameters. +

+ + + + + + diff --git a/examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/defaults.html b/examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/defaults.html new file mode 100644 index 000000000..99f8827bd --- /dev/null +++ b/examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/defaults.html @@ -0,0 +1,60 @@ + + + + + + Defaults + + + + + +
+
+
+
+ + + + + + diff --git a/examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/font-options.html b/examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/font-options.html new file mode 100644 index 000000000..11063c73c --- /dev/null +++ b/examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/font-options.html @@ -0,0 +1,62 @@ + + + + + + Counter + + + + + + + + + + + + diff --git a/examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/format-number.html b/examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/format-number.html new file mode 100644 index 000000000..4bf2c366b --- /dev/null +++ b/examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/format-number.html @@ -0,0 +1,56 @@ + + + + + + Counter + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/html5-data-attribute-config.html b/examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/html5-data-attribute-config.html new file mode 100644 index 000000000..3c2ab0b58 --- /dev/null +++ b/examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/html5-data-attribute-config.html @@ -0,0 +1,54 @@ + + + + + + html5 data-attribute setup + + + + + + + + + +
+
+ +
+ + + + + + \ No newline at end of file diff --git a/examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/human-friendly-numbers.html b/examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/human-friendly-numbers.html new file mode 100644 index 000000000..f0e7ddc8d --- /dev/null +++ b/examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/human-friendly-numbers.html @@ -0,0 +1,109 @@ + + + + + + Guage + + + + +
+ Random Refresh + + + + + + diff --git a/examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/pointer.html b/examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/pointer.html new file mode 100644 index 000000000..b20ae5f4c --- /dev/null +++ b/examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/pointer.html @@ -0,0 +1,168 @@ + + + + + + Pointer + + + + + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+ + + + + + diff --git a/examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/refresh-maximum.html b/examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/refresh-maximum.html new file mode 100644 index 000000000..e1502a100 --- /dev/null +++ b/examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/refresh-maximum.html @@ -0,0 +1,91 @@ + + + + + + Donuts, baby! + + + + + + + + + + + + diff --git a/examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/responsive-gauges.htm b/examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/responsive-gauges.htm new file mode 100644 index 000000000..68680c6e3 --- /dev/null +++ b/examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/responsive-gauges.htm @@ -0,0 +1,71 @@ + + + + + Dynamic Resize + + + + + +
+
+
+
+
+ + + + + + diff --git a/examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/reverse.html b/examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/reverse.html new file mode 100644 index 000000000..e17b6750a --- /dev/null +++ b/examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/reverse.html @@ -0,0 +1,144 @@ + + + + + + Reverse + + + + + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+ + + + + + diff --git a/examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/justgage.js b/examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/justgage.js new file mode 100644 index 000000000..c852491ba --- /dev/null +++ b/examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/justgage.js @@ -0,0 +1,1220 @@ +/** + * JustGage - animated gauges using RaphaelJS + * Check http://www.justgage.com for official releases + * Licensed under MIT. + * @author Bojan Djuricic (@Toorshia) + **/ + +JustGage = function(config) { + + var obj = this; + + // Helps in case developer wants to debug it. unobtrusive + if (config === null || config === undefined) { + console.log('* justgage: Make sure to pass options to the constructor!'); + return false; + } + + var node; + + if (config.id !== null && config.id !== undefined) { + node = document.getElementById(config.id); + if (!node) { + console.log('* justgage: No element with id : %s found', config.id); + return false; + } + } else if (config.parentNode !== null && config.parentNode !== undefined) { + node = config.parentNode; + } else { + console.log('* justgage: Make sure to pass the existing element id or parentNode to the constructor.'); + return false; + } + + var dataset = node.dataset ? node.dataset : {}; + + // check for defaults + var defaults = (config.defaults !== null && config.defaults !== undefined) ? config.defaults : false; + if (defaults !== false) { + config = extend({}, config, defaults); + delete config.defaults; + } + + // configurable parameters + obj.config = { + // id : string + // this is container element id + id: config.id, + + // value : float + // value gauge is showing + value: kvLookup('value', config, dataset, 0, 'float'), + + // defaults : bool + // defaults parameter to use + defaults: kvLookup('defaults', config, dataset, 0, false), + + // parentNode : node object + // this is container element + parentNode: kvLookup('parentNode', config, dataset, null), + + // width : int + // gauge width + width: kvLookup('width', config, dataset, null), + + // height : int + // gauge height + height: kvLookup('height', config, dataset, null), + + // title : string + // gauge title + title: kvLookup('title', config, dataset, ""), + + // titleFontColor : string + // color of gauge title + titleFontColor: kvLookup('titleFontColor', config, dataset, "#999999"), + + // titleFontFamily : string + // color of gauge title + titleFontFamily: kvLookup('titleFontFamily', config, dataset, "sans-serif"), + + // titlePosition : string + // 'above' or 'below' + titlePosition: kvLookup('titlePosition', config, dataset, "above"), + + // valueFontColor : string + // color of label showing current value + valueFontColor: kvLookup('valueFontColor', config, dataset, "#010101"), + + // valueFontFamily : string + // color of label showing current value + valueFontFamily: kvLookup('valueFontFamily', config, dataset, "Arial"), + + // symbol : string + // special symbol to show next to value + symbol: kvLookup('symbol', config, dataset, ''), + + // min : float + // min value + min: kvLookup('min', config, dataset, 0, 'float'), + + // max : float + // max value + max: kvLookup('max', config, dataset, 100, 'float'), + + // reverse : bool + // reverse min and max + reverse: kvLookup('reverse', config, dataset, false), + + // humanFriendlyDecimal : int + // number of decimal places for our human friendly number to contain + humanFriendlyDecimal: kvLookup('humanFriendlyDecimal', config, dataset, 0), + + + // textRenderer: func + // function applied before rendering text + textRenderer: kvLookup('textRenderer', config, dataset, null), + + // gaugeWidthScale : float + // width of the gauge element + gaugeWidthScale: kvLookup('gaugeWidthScale', config, dataset, 1.0), + + // gaugeColor : string + // background color of gauge element + gaugeColor: kvLookup('gaugeColor', config, dataset, "#edebeb"), + + // label : string + // text to show below value + label: kvLookup('label', config, dataset, ''), + + // labelFontColor : string + // color of label showing label under value + labelFontColor: kvLookup('labelFontColor', config, dataset, "#b3b3b3"), + + // shadowOpacity : int + // 0 ~ 1 + shadowOpacity: kvLookup('shadowOpacity', config, dataset, 0.2), + + // shadowSize: int + // inner shadow size + shadowSize: kvLookup('shadowSize', config, dataset, 5), + + // shadowVerticalOffset : int + // how much shadow is offset from top + shadowVerticalOffset: kvLookup('shadowVerticalOffset', config, dataset, 3), + + // levelColors : string[] + // colors of indicator, from lower to upper, in RGB format + levelColors: kvLookup('levelColors', config, dataset, ["#a9d70b", "#f9c802", "#ff0000"], 'array', ','), + + // startAnimationTime : int + // length of initial animation + startAnimationTime: kvLookup('startAnimationTime', config, dataset, 700), + + // startAnimationType : string + // type of initial animation (linear, >, <, <>, bounce) + startAnimationType: kvLookup('startAnimationType', config, dataset, '>'), + + // refreshAnimationTime : int + // length of refresh animation + refreshAnimationTime: kvLookup('refreshAnimationTime', config, dataset, 700), + + // refreshAnimationType : string + // type of refresh animation (linear, >, <, <>, bounce) + refreshAnimationType: kvLookup('refreshAnimationType', config, dataset, '>'), + + // donutStartAngle : int + // angle to start from when in donut mode + donutStartAngle: kvLookup('donutStartAngle', config, dataset, 90), + + // valueMinFontSize : int + // absolute minimum font size for the value + valueMinFontSize: kvLookup('valueMinFontSize', config, dataset, 16), + + // titleMinFontSize + // absolute minimum font size for the title + titleMinFontSize: kvLookup('titleMinFontSize', config, dataset, 10), + + // labelMinFontSize + // absolute minimum font size for the label + labelMinFontSize: kvLookup('labelMinFontSize', config, dataset, 10), + + // minLabelMinFontSize + // absolute minimum font size for the minimum label + minLabelMinFontSize: kvLookup('minLabelMinFontSize', config, dataset, 10), + + // maxLabelMinFontSize + // absolute minimum font size for the maximum label + maxLabelMinFontSize: kvLookup('maxLabelMinFontSize', config, dataset, 10), + + // hideValue : bool + // hide value text + hideValue: kvLookup('hideValue', config, dataset, false), + + // hideMinMax : bool + // hide min and max values + hideMinMax: kvLookup('hideMinMax', config, dataset, false), + + // hideInnerShadow : bool + // hide inner shadow + hideInnerShadow: kvLookup('hideInnerShadow', config, dataset, false), + + // humanFriendly : bool + // convert large numbers for min, max, value to human friendly (e.g. 1234567 -> 1.23M) + humanFriendly: kvLookup('humanFriendly', config, dataset, false), + + // noGradient : bool + // whether to use gradual color change for value, or sector-based + noGradient: kvLookup('noGradient', config, dataset, false), + + // donut : bool + // show full donut gauge + donut: kvLookup('donut', config, dataset, false), + + // relativeGaugeSize : bool + // whether gauge size should follow changes in container element size + relativeGaugeSize: kvLookup('relativeGaugeSize', config, dataset, false), + + // counter : bool + // animate level number change + counter: kvLookup('counter', config, dataset, false), + + // decimals : int + // number of digits after floating point + decimals: kvLookup('decimals', config, dataset, 0), + + // customSectors : [] of objects + // number of digits after floating point + customSectors: kvLookup('customSectors', config, dataset, []), + + // formatNumber: boolean + // formats numbers with commas where appropriate + formatNumber: kvLookup('formatNumber', config, dataset, false), + + // pointer : bool + // show value pointer + pointer: kvLookup('pointer', config, dataset, false), + + // pointerOptions : object + // define pointer look + pointerOptions: kvLookup('pointerOptions', config, dataset, []) + }; + + // variables + var + canvasW, + canvasH, + widgetW, + widgetH, + aspect, + dx, + dy, + titleFontSize, + titleX, + titleY, + valueFontSize, + valueX, + valueY, + labelFontSize, + labelX, + labelY, + minFontSize, + minX, + minY, + maxFontSize, + maxX, + maxY; + + // overflow values + if (obj.config.value > obj.config.max) obj.config.value = obj.config.max; + if (obj.config.value < obj.config.min) obj.config.value = obj.config.min; + obj.originalValue = kvLookup('value', config, dataset, -1, 'float'); + + // create canvas + if (obj.config.id !== null && (document.getElementById(obj.config.id)) !== null) { + obj.canvas = Raphael(obj.config.id, "100%", "100%"); + } else if (obj.config.parentNode !== null) { + obj.canvas = Raphael(obj.config.parentNode, "100%", "100%"); + } + + if (obj.config.relativeGaugeSize === true) { + obj.canvas.setViewBox(0, 0, 200, 150, true); + } + + // canvas dimensions + if (obj.config.relativeGaugeSize === true) { + canvasW = 200; + canvasH = 150; + } else if (obj.config.width !== null && obj.config.height !== null) { + canvasW = obj.config.width; + canvasH = obj.config.height; + } else if (obj.config.parentNode !== null) { + obj.canvas.setViewBox(0, 0, 200, 150, true); + canvasW = 200; + canvasH = 150; + } else { + canvasW = getStyle(document.getElementById(obj.config.id), "width").slice(0, -2) * 1; + canvasH = getStyle(document.getElementById(obj.config.id), "height").slice(0, -2) * 1; + } + + // widget dimensions + if (obj.config.donut === true) { + + // DONUT ******************************* + + // width more than height + if (canvasW > canvasH) { + widgetH = canvasH; + widgetW = widgetH; + // width less than height + } else if (canvasW < canvasH) { + widgetW = canvasW; + widgetH = widgetW; + // if height don't fit, rescale both + if (widgetH > canvasH) { + aspect = widgetH / canvasH; + widgetH = widgetH / aspect; + widgetW = widgetH / aspect; + } + // equal + } else { + widgetW = canvasW; + widgetH = widgetW; + } + + // delta + dx = (canvasW - widgetW) / 2; + dy = (canvasH - widgetH) / 2; + + // title + titleFontSize = ((widgetH / 8) > 10) ? (widgetH / 10) : 10; + titleX = dx + widgetW / 2; + titleY = dy + widgetH / 11; + + // value + valueFontSize = ((widgetH / 6.4) > 16) ? (widgetH / 5.4) : 18; + valueX = dx + widgetW / 2; + if (obj.config.label !== '') { + valueY = dy + widgetH / 1.85; + } else { + valueY = dy + widgetH / 1.7; + } + + // label + labelFontSize = ((widgetH / 16) > 10) ? (widgetH / 16) : 10; + labelX = dx + widgetW / 2; + labelY = valueY + labelFontSize; + + // min + minFontSize = ((widgetH / 16) > 10) ? (widgetH / 16) : 10; + minX = dx + (widgetW / 10) + (widgetW / 6.666666666666667 * obj.config.gaugeWidthScale) / 2; + minY = labelY; + + // max + maxFontSize = ((widgetH / 16) > 10) ? (widgetH / 16) : 10; + maxX = dx + widgetW - (widgetW / 10) - (widgetW / 6.666666666666667 * obj.config.gaugeWidthScale) / 2; + maxY = labelY; + + } else { + // HALF ******************************* + + // width more than height + if (canvasW > canvasH) { + widgetH = canvasH; + widgetW = widgetH * 1.25; + //if width doesn't fit, rescale both + if (widgetW > canvasW) { + aspect = widgetW / canvasW; + widgetW = widgetW / aspect; + widgetH = widgetH / aspect; + } + // width less than height + } else if (canvasW < canvasH) { + widgetW = canvasW; + widgetH = widgetW / 1.25; + // if height don't fit, rescale both + if (widgetH > canvasH) { + aspect = widgetH / canvasH; + widgetH = widgetH / aspect; + widgetW = widgetH / aspect; + } + // equal + } else { + widgetW = canvasW; + widgetH = widgetW * 0.75; + } + + // delta + dx = (canvasW - widgetW) / 2; + dy = (canvasH - widgetH) / 2; + if (obj.config.titlePosition === 'below') { + // shift whole thing down + dy -= (widgetH / 6.4); + } + + // title + titleFontSize = ((widgetH / 8) > obj.config.titleMinFontSize) ? (widgetH / 10) : obj.config.titleMinFontSize; + titleX = dx + widgetW / 2; + titleY = dy + (obj.config.titlePosition === 'below' ? (widgetH * 1.07) : (widgetH / 6.4)); + + // value + valueFontSize = ((widgetH / 6.5) > obj.config.valueMinFontSize) ? (widgetH / 6.5) : obj.config.valueMinFontSize; + valueX = dx + widgetW / 2; + valueY = dy + widgetH / 1.275; + + // label + labelFontSize = ((widgetH / 16) > obj.config.labelMinFontSize) ? (widgetH / 16) : obj.config.labelMinFontSize; + labelX = dx + widgetW / 2; + labelY = valueY + valueFontSize / 2 + 5; + + // min + minFontSize = ((widgetH / 16) > obj.config.minLabelMinFontSize) ? (widgetH / 16) : obj.config.minLabelMinFontSize; + minX = dx + (widgetW / 10) + (widgetW / 6.666666666666667 * obj.config.gaugeWidthScale) / 2; + minY = labelY; + + // max + maxFontSize = ((widgetH / 16) > obj.config.maxLabelMinFontSize) ? (widgetH / 16) : obj.config.maxLabelMinFontSize; + maxX = dx + widgetW - (widgetW / 10) - (widgetW / 6.666666666666667 * obj.config.gaugeWidthScale) / 2; + maxY = labelY; + } + + // parameters + obj.params = { + canvasW: canvasW, + canvasH: canvasH, + widgetW: widgetW, + widgetH: widgetH, + dx: dx, + dy: dy, + titleFontSize: titleFontSize, + titleX: titleX, + titleY: titleY, + valueFontSize: valueFontSize, + valueX: valueX, + valueY: valueY, + labelFontSize: labelFontSize, + labelX: labelX, + labelY: labelY, + minFontSize: minFontSize, + minX: minX, + minY: minY, + maxFontSize: maxFontSize, + maxX: maxX, + maxY: maxY + }; + + // var clear + canvasW, canvasH, widgetW, widgetH, aspect, dx, dy, titleFontSize, titleX, titleY, valueFontSize, valueX, valueY, labelFontSize, labelX, labelY, minFontSize, minX, minY, maxFontSize, maxX, maxY = null; + + // pki - custom attribute for generating gauge paths + obj.canvas.customAttributes.pki = function(value, min, max, w, h, dx, dy, gws, donut, reverse) { + + var alpha, Ro, Ri, Cx, Cy, Xo, Yo, Xi, Yi, path; + + if (donut) { + alpha = (1 - 2 * (value - min) / (max - min)) * Math.PI; + Ro = w / 2 - w / 7; + Ri = Ro - w / 6.666666666666667 * gws; + + Cx = w / 2 + dx; + Cy = h / 1.95 + dy; + + Xo = w / 2 + dx + Ro * Math.cos(alpha); + Yo = h - (h - Cy) - Ro * Math.sin(alpha); + Xi = w / 2 + dx + Ri * Math.cos(alpha); + Yi = h - (h - Cy) - Ri * Math.sin(alpha); + + path = "M" + (Cx - Ri) + "," + Cy + " "; + path += "L" + (Cx - Ro) + "," + Cy + " "; + if (value > ((max - min) / 2)) { + path += "A" + Ro + "," + Ro + " 0 0 1 " + (Cx + Ro) + "," + Cy + " "; + } + path += "A" + Ro + "," + Ro + " 0 0 1 " + Xo + "," + Yo + " "; + path += "L" + Xi + "," + Yi + " "; + if (value > ((max - min) / 2)) { + path += "A" + Ri + "," + Ri + " 0 0 0 " + (Cx + Ri) + "," + Cy + " "; + } + path += "A" + Ri + "," + Ri + " 0 0 0 " + (Cx - Ri) + "," + Cy + " "; + path += "Z "; + + return { + path: path + }; + + } else { + alpha = (1 - (value - min) / (max - min)) * Math.PI; + Ro = w / 2 - w / 10; + Ri = Ro - w / 6.666666666666667 * gws; + + Cx = w / 2 + dx; + Cy = h / 1.25 + dy; + + Xo = w / 2 + dx + Ro * Math.cos(alpha); + Yo = h - (h - Cy) - Ro * Math.sin(alpha); + Xi = w / 2 + dx + Ri * Math.cos(alpha); + Yi = h - (h - Cy) - Ri * Math.sin(alpha); + + path = "M" + (Cx - Ri) + "," + Cy + " "; + path += "L" + (Cx - Ro) + "," + Cy + " "; + path += "A" + Ro + "," + Ro + " 0 0 1 " + Xo + "," + Yo + " "; + path += "L" + Xi + "," + Yi + " "; + path += "A" + Ri + "," + Ri + " 0 0 0 " + (Cx - Ri) + "," + Cy + " "; + path += "Z "; + + return { + path: path + }; + } + + // var clear + alpha, Ro, Ri, Cx, Cy, Xo, Yo, Xi, Yi, path = null; + }; + + // ndl - custom attribute for generating needle path + obj.canvas.customAttributes.ndl = function(value, min, max, w, h, dx, dy, gws, donut) { + + var dlt = w * 3.5 / 100; + var dlb = w / 15; + var dw = w / 100; + + if (obj.config.pointerOptions.toplength != null && obj.config.pointerOptions.toplength != undefined) dlt = obj.config.pointerOptions.toplength; + if (obj.config.pointerOptions.bottomlength != null && obj.config.pointerOptions.bottomlength != undefined) dlb = obj.config.pointerOptions.bottomlength; + if (obj.config.pointerOptions.bottomwidth != null && obj.config.pointerOptions.bottomwidth != undefined) dw = obj.config.pointerOptions.bottomwidth; + + var alpha, Ro, Ri, Cx, Cy, Xo, Yo, Xi, Yi, Xc, Yc, Xz, Yz, Xa, Ya, Xb, Yb, path; + + if (donut) { + + alpha = (1 - 2 * (value - min) / (max - min)) * Math.PI; + Ro = w / 2 - w / 7; + Ri = Ro - w / 6.666666666666667 * gws; + + Cx = w / 2 + dx; + Cy = h / 1.95 + dy; + + Xo = w / 2 + dx + Ro * Math.cos(alpha); + Yo = h - (h - Cy) - Ro * Math.sin(alpha); + Xi = w / 2 + dx + Ri * Math.cos(alpha); + Yi = h - (h - Cy) - Ri * Math.sin(alpha); + + Xc = Xo + dlt * Math.cos(alpha); + Yc = Yo - dlt * Math.sin(alpha); + Xz = Xi - dlb * Math.cos(alpha); + Yz = Yi + dlb * Math.sin(alpha); + + Xa = Xz + dw * Math.sin(alpha); + Ya = Yz + dw * Math.cos(alpha); + Xb = Xz - dw * Math.sin(alpha); + Yb = Yz - dw * Math.cos(alpha); + + path = 'M' + Xa + ',' + Ya + ' '; + path += 'L' + Xb + ',' + Yb + ' '; + path += 'L' + Xc + ',' + Yc + ' '; + path += 'Z '; + + return { + path: path + }; + + } else { + alpha = (1 - (value - min) / (max - min)) * Math.PI; + Ro = w / 2 - w / 10; + Ri = Ro - w / 6.666666666666667 * gws; + + Cx = w / 2 + dx; + Cy = h / 1.25 + dy; + + Xo = w / 2 + dx + Ro * Math.cos(alpha); + Yo = h - (h - Cy) - Ro * Math.sin(alpha); + Xi = w / 2 + dx + Ri * Math.cos(alpha); + Yi = h - (h - Cy) - Ri * Math.sin(alpha); + + Xc = Xo + dlt * Math.cos(alpha); + Yc = Yo - dlt * Math.sin(alpha); + Xz = Xi - dlb * Math.cos(alpha); + Yz = Yi + dlb * Math.sin(alpha); + + Xa = Xz + dw * Math.sin(alpha); + Ya = Yz + dw * Math.cos(alpha); + Xb = Xz - dw * Math.sin(alpha); + Yb = Yz - dw * Math.cos(alpha); + + path = 'M' + Xa + ',' + Ya + ' '; + path += 'L' + Xb + ',' + Yb + ' '; + path += 'L' + Xc + ',' + Yc + ' '; + path += 'Z '; + + return { + path: path + }; + } + + // var clear + alpha, Ro, Ri, Cx, Cy, Xo, Yo, Xi, Yi, Xc, Yc, Xz, Yz, Xa, Ya, Xb, Yb, path = null; + }; + + // gauge + obj.gauge = obj.canvas.path().attr({ + "stroke": "none", + "fill": obj.config.gaugeColor, + pki: [ + obj.config.max, + obj.config.min, + obj.config.max, + obj.params.widgetW, + obj.params.widgetH, + obj.params.dx, + obj.params.dy, + obj.config.gaugeWidthScale, + obj.config.donut, + obj.config.reverse + ] + }); + + // level + obj.level = obj.canvas.path().attr({ + "stroke": "none", + "fill": getColor(obj.config.value, (obj.config.value - obj.config.min) / (obj.config.max - obj.config.min), obj.config.levelColors, obj.config.noGradient, obj.config.customSectors), + pki: [ + obj.config.min, + obj.config.min, + obj.config.max, + obj.params.widgetW, + obj.params.widgetH, + obj.params.dx, + obj.params.dy, + obj.config.gaugeWidthScale, + obj.config.donut, + obj.config.reverse + ] + }); + if (obj.config.donut) { + obj.level.transform("r" + obj.config.donutStartAngle + ", " + (obj.params.widgetW / 2 + obj.params.dx) + ", " + (obj.params.widgetH / 1.95 + obj.params.dy)); + } + + if (obj.config.pointer) { + // needle + obj.needle = obj.canvas.path().attr({ + "stroke": (obj.config.pointerOptions.stroke !== null && obj.config.pointerOptions.stroke !== undefined) ? obj.config.pointerOptions.stroke : "none", + "stroke-width": (obj.config.pointerOptions.stroke_width !== null && obj.config.pointerOptions.stroke_width !== undefined) ? obj.config.pointerOptions.stroke_width : 0, + "stroke-linecap": (obj.config.pointerOptions.stroke_linecap !== null && obj.config.pointerOptions.stroke_linecap !== undefined) ? obj.config.pointerOptions.stroke_linecap : "square", + "fill": (obj.config.pointerOptions.color !== null && obj.config.pointerOptions.color !== undefined) ? obj.config.pointerOptions.color : "#000000", + ndl: [ + obj.config.min, + obj.config.min, + obj.config.max, + obj.params.widgetW, + obj.params.widgetH, + obj.params.dx, + obj.params.dy, + obj.config.gaugeWidthScale, + obj.config.donut + ] + }); + + if (obj.config.donut) { + obj.needle.transform("r" + obj.config.donutStartAngle + ", " + (obj.params.widgetW / 2 + obj.params.dx) + ", " + (obj.params.widgetH / 1.95 + obj.params.dy)); + } + + } + + // title + obj.txtTitle = obj.canvas.text(obj.params.titleX, obj.params.titleY, obj.config.title); + obj.txtTitle.attr({ + "font-size": obj.params.titleFontSize, + "font-weight": "bold", + "font-family": obj.config.titleFontFamily, + "fill": obj.config.titleFontColor, + "fill-opacity": "1" + }); + setDy(obj.txtTitle, obj.params.titleFontSize, obj.params.titleY); + + // value + obj.txtValue = obj.canvas.text(obj.params.valueX, obj.params.valueY, 0); + obj.txtValue.attr({ + "font-size": obj.params.valueFontSize, + "font-weight": "bold", + "font-family": obj.config.valueFontFamily, + "fill": obj.config.valueFontColor, + "fill-opacity": "0" + }); + setDy(obj.txtValue, obj.params.valueFontSize, obj.params.valueY); + + // label + obj.txtLabel = obj.canvas.text(obj.params.labelX, obj.params.labelY, obj.config.label); + obj.txtLabel.attr({ + "font-size": obj.params.labelFontSize, + "font-weight": "normal", + "font-family": "Arial", + "fill": obj.config.labelFontColor, + "fill-opacity": "0" + }); + setDy(obj.txtLabel, obj.params.labelFontSize, obj.params.labelY); + + // min + var min = obj.config.min; + if (obj.config.reverse) { + min = obj.config.max; + } + + obj.txtMinimum = min; + if (obj.config.humanFriendly) { + obj.txtMinimum = humanFriendlyNumber(min, obj.config.humanFriendlyDecimal); + } else if (obj.config.formatNumber) { + obj.txtMinimum = formatNumber(min); + } + obj.txtMin = obj.canvas.text(obj.params.minX, obj.params.minY, obj.txtMinimum); + obj.txtMin.attr({ + "font-size": obj.params.minFontSize, + "font-weight": "normal", + "font-family": "Arial", + "fill": obj.config.labelFontColor, + "fill-opacity": (obj.config.hideMinMax || obj.config.donut) ? "0" : "1" + }); + setDy(obj.txtMin, obj.params.minFontSize, obj.params.minY); + + // max + var max = obj.config.max; + if (obj.config.reverse) { + max = obj.config.min; + } + obj.txtMaximum = max; + if (obj.config.humanFriendly) { + obj.txtMaximum = humanFriendlyNumber(max, obj.config.humanFriendlyDecimal); + } else if (obj.config.formatNumber) { + obj.txtMaximum = formatNumber(max); + } + obj.txtMax = obj.canvas.text(obj.params.maxX, obj.params.maxY, obj.txtMaximum); + obj.txtMax.attr({ + "font-size": obj.params.maxFontSize, + "font-weight": "normal", + "font-family": "Arial", + "fill": obj.config.labelFontColor, + "fill-opacity": (obj.config.hideMinMax || obj.config.donut) ? "0" : "1" + }); + setDy(obj.txtMax, obj.params.maxFontSize, obj.params.maxY); + + var defs = obj.canvas.canvas.childNodes[1]; + var svg = "http://www.w3.org/2000/svg"; + + if (ie !== 'undefined' && ie < 9) { + // VML mode - no SVG & SVG filter support + } else if (ie !== 'undefined') { + onCreateElementNsReady(function() { + obj.generateShadow(svg, defs); + }); + } else { + obj.generateShadow(svg, defs); + } + + // var clear + defs, svg = null; + + // set value to display + if (obj.config.textRenderer) { + obj.originalValue = obj.config.textRenderer(obj.originalValue); + } else if (obj.config.humanFriendly) { + obj.originalValue = humanFriendlyNumber(obj.originalValue, obj.config.humanFriendlyDecimal) + obj.config.symbol; + } else if (obj.config.formatNumber) { + obj.originalValue = formatNumber(obj.originalValue) + obj.config.symbol; + } else { + obj.originalValue = (obj.originalValue * 1).toFixed(obj.config.decimals) + obj.config.symbol; + } + + if (obj.config.counter === true) { + //on each animation frame + eve.on("raphael.anim.frame." + (obj.level.id), function() { + var currentValue = obj.level.attr("pki")[0]; + if (obj.config.reverse) { + currentValue = (obj.config.max * 1) + (obj.config.min * 1) - (obj.level.attr("pki")[0] * 1); + } + if (obj.config.textRenderer) { + obj.txtValue.attr("text", obj.config.textRenderer(Math.floor(currentValue))); + } else if (obj.config.humanFriendly) { + obj.txtValue.attr("text", humanFriendlyNumber(Math.floor(currentValue), obj.config.humanFriendlyDecimal) + obj.config.symbol); + } else if (obj.config.formatNumber) { + obj.txtValue.attr("text", formatNumber(Math.floor(currentValue)) + obj.config.symbol); + } else { + obj.txtValue.attr("text", (currentValue * 1).toFixed(obj.config.decimals) + obj.config.symbol); + } + setDy(obj.txtValue, obj.params.valueFontSize, obj.params.valueY); + currentValue = null; + }); + //on animation end + eve.on("raphael.anim.finish." + (obj.level.id), function() { + obj.txtValue.attr({ + "text": obj.originalValue + }); + setDy(obj.txtValue, obj.params.valueFontSize, obj.params.valueY); + }); + } else { + //on animation start + eve.on("raphael.anim.start." + (obj.level.id), function() { + obj.txtValue.attr({ + "text": obj.originalValue + }); + setDy(obj.txtValue, obj.params.valueFontSize, obj.params.valueY); + }); + } + + // animate gauge level, value & label + var rvl = obj.config.value; + if (obj.config.reverse) { + rvl = (obj.config.max * 1) + (obj.config.min * 1) - (obj.config.value * 1); + } + obj.level.animate({ + pki: [ + rvl, + obj.config.min, + obj.config.max, + obj.params.widgetW, + obj.params.widgetH, + obj.params.dx, + obj.params.dy, + obj.config.gaugeWidthScale, + obj.config.donut, + obj.config.reverse + ] + }, obj.config.startAnimationTime, obj.config.startAnimationType); + + if (obj.config.pointer) { + obj.needle.animate({ + ndl: [ + rvl, + obj.config.min, + obj.config.max, + obj.params.widgetW, + obj.params.widgetH, + obj.params.dx, + obj.params.dy, + obj.config.gaugeWidthScale, + obj.config.donut + ] + }, obj.config.startAnimationTime, obj.config.startAnimationType); + } + + obj.txtValue.animate({ + "fill-opacity": (obj.config.hideValue) ? "0" : "1" + }, obj.config.startAnimationTime, obj.config.startAnimationType); + obj.txtLabel.animate({ + "fill-opacity": "1" + }, obj.config.startAnimationTime, obj.config.startAnimationType); +}; + +/** Refresh gauge level */ +JustGage.prototype.refresh = function(val, max) { + + var obj = this; + var displayVal, color, max = max || null; + + // set new max + if (max !== null) { + obj.config.max = max; + // TODO: update customSectors + + obj.txtMaximum = obj.config.max; + if (obj.config.humanFriendly) { + obj.txtMaximum = humanFriendlyNumber(obj.config.max, obj.config.humanFriendlyDecimal); + } else if (obj.config.formatNumber) { + obj.txtMaximum = formatNumber(obj.config.max); + } + if (!obj.config.reverse) { + obj.txtMax.attr({ + "text": obj.txtMaximum + }); + setDy(obj.txtMax, obj.params.maxFontSize, obj.params.maxY); + } else { + obj.txtMin.attr({ + "text": obj.txtMaximum + }); + setDy(obj.txtMin, obj.params.minFontSize, obj.params.minY); + } + } + + // overflow values + displayVal = val; + if ((val * 1) > (obj.config.max * 1)) { + val = (obj.config.max * 1); + } + if ((val * 1) < (obj.config.min * 1)) { + val = (obj.config.min * 1); + } + + color = getColor(val, (val - obj.config.min) / (obj.config.max - obj.config.min), obj.config.levelColors, obj.config.noGradient, obj.config.customSectors); + + if (obj.config.textRenderer) { + displayVal = obj.config.textRenderer(displayVal); + } else if (obj.config.humanFriendly) { + displayVal = humanFriendlyNumber(displayVal, obj.config.humanFriendlyDecimal) + obj.config.symbol; + } else if (obj.config.formatNumber) { + displayVal = formatNumber((displayVal * 1).toFixed(obj.config.decimals)) + obj.config.symbol; + } else { + displayVal = (displayVal * 1).toFixed(obj.config.decimals) + obj.config.symbol; + } + obj.originalValue = displayVal; + obj.config.value = val * 1; + + if (!obj.config.counter) { + obj.txtValue.attr({ + "text": displayVal + }); + setDy(obj.txtValue, obj.params.valueFontSize, obj.params.valueY); + } + + var rvl = obj.config.value; + if (obj.config.reverse) { + rvl = (obj.config.max * 1) + (obj.config.min * 1) - (obj.config.value * 1); + } + obj.level.animate({ + pki: [ + rvl, + obj.config.min, + obj.config.max, + obj.params.widgetW, + obj.params.widgetH, + obj.params.dx, + obj.params.dy, + obj.config.gaugeWidthScale, + obj.config.donut, + obj.config.reverse + ], + "fill": color + }, obj.config.refreshAnimationTime, obj.config.refreshAnimationType); + + if (obj.config.pointer) { + obj.needle.animate({ + ndl: [ + rvl, + obj.config.min, + obj.config.max, + obj.params.widgetW, + obj.params.widgetH, + obj.params.dx, + obj.params.dy, + obj.config.gaugeWidthScale, + obj.config.donut + ] + }, obj.config.refreshAnimationTime, obj.config.refreshAnimationType); + } + + // var clear + obj, displayVal, color, max = null; +}; + +/** Generate shadow */ +JustGage.prototype.generateShadow = function(svg, defs) { + + var obj = this; + var sid = "inner-shadow-" + obj.config.id; + var gaussFilter, feOffset, feGaussianBlur, feComposite1, feFlood, feComposite2, feComposite3; + + // FILTER + gaussFilter = document.createElementNS(svg, "filter"); + gaussFilter.setAttribute("id", sid); + defs.appendChild(gaussFilter); + + // offset + feOffset = document.createElementNS(svg, "feOffset"); + feOffset.setAttribute("dx", 0); + feOffset.setAttribute("dy", obj.config.shadowVerticalOffset); + gaussFilter.appendChild(feOffset); + + // blur + feGaussianBlur = document.createElementNS(svg, "feGaussianBlur"); + feGaussianBlur.setAttribute("result", "offset-blur"); + feGaussianBlur.setAttribute("stdDeviation", obj.config.shadowSize); + gaussFilter.appendChild(feGaussianBlur); + + // composite 1 + feComposite1 = document.createElementNS(svg, "feComposite"); + feComposite1.setAttribute("operator", "out"); + feComposite1.setAttribute("in", "SourceGraphic"); + feComposite1.setAttribute("in2", "offset-blur"); + feComposite1.setAttribute("result", "inverse"); + gaussFilter.appendChild(feComposite1); + + // flood + feFlood = document.createElementNS(svg, "feFlood"); + feFlood.setAttribute("flood-color", "black"); + feFlood.setAttribute("flood-opacity", obj.config.shadowOpacity); + feFlood.setAttribute("result", "color"); + gaussFilter.appendChild(feFlood); + + // composite 2 + feComposite2 = document.createElementNS(svg, "feComposite"); + feComposite2.setAttribute("operator", "in"); + feComposite2.setAttribute("in", "color"); + feComposite2.setAttribute("in2", "inverse"); + feComposite2.setAttribute("result", "shadow"); + gaussFilter.appendChild(feComposite2); + + // composite 3 + feComposite3 = document.createElementNS(svg, "feComposite"); + feComposite3.setAttribute("operator", "over"); + feComposite3.setAttribute("in", "shadow"); + feComposite3.setAttribute("in2", "SourceGraphic"); + gaussFilter.appendChild(feComposite3); + + // set shadow + if (!obj.config.hideInnerShadow) { + obj.canvas.canvas.childNodes[2].setAttribute("filter", "url(#" + sid + ")"); + obj.canvas.canvas.childNodes[3].setAttribute("filter", "url(#" + sid + ")"); + } + + // var clear + gaussFilter, feOffset, feGaussianBlur, feComposite1, feFlood, feComposite2, feComposite3 = null; +}; + +// +// tiny helper function to lookup value of a key from two hash tables +// if none found, return defaultvalue +// +// key: string +// tablea: object +// tableb: DOMStringMap|object +// defval: string|integer|float|null +// datatype: return datatype +// delimiter: delimiter to be used in conjunction with datatype formatting +// +function kvLookup(key, tablea, tableb, defval, datatype, delimiter) { + var val = defval; + var canConvert = false; + if (!(key === null || key === undefined)) { + if (tableb !== null && tableb !== undefined && typeof tableb === "object" && key in tableb) { + val = tableb[key]; + canConvert = true; + } else if (tablea !== null && tablea !== undefined && typeof tablea === "object" && key in tablea) { + val = tablea[key]; + canConvert = true; + } else { + val = defval; + } + if (canConvert === true) { + if (datatype !== null && datatype !== undefined) { + switch (datatype) { + case 'int': + val = parseInt(val, 10); + break; + case 'float': + val = parseFloat(val); + break; + default: + break; + } + } + } + } + return val; +}; + +/** Get color for value */ +function getColor(val, pct, col, noGradient, custSec) { + + var no, inc, colors, percentage, rval, gval, bval, lower, upper, range, rangePct, pctLower, pctUpper, color; + var noGradient = noGradient || custSec.length > 0; + + if (custSec.length > 0) { + for (var i = 0; i < custSec.length; i++) { + if (val > custSec[i].lo && val <= custSec[i].hi) { + return custSec[i].color; + } + } + } + + no = col.length; + if (no === 1) return col[0]; + inc = (noGradient) ? (1 / no) : (1 / (no - 1)); + colors = []; + for (i = 0; i < col.length; i++) { + percentage = (noGradient) ? (inc * (i + 1)) : (inc * i); + rval = parseInt((cutHex(col[i])).substring(0, 2), 16); + gval = parseInt((cutHex(col[i])).substring(2, 4), 16); + bval = parseInt((cutHex(col[i])).substring(4, 6), 16); + colors[i] = { + pct: percentage, + color: { + r: rval, + g: gval, + b: bval + } + }; + } + + if (pct === 0) { + return 'rgb(' + [colors[0].color.r, colors[0].color.g, colors[0].color.b].join(',') + ')'; + } + + for (var j = 0; j < colors.length; j++) { + if (pct <= colors[j].pct) { + if (noGradient) { + return 'rgb(' + [colors[j].color.r, colors[j].color.g, colors[j].color.b].join(',') + ')'; + } else { + lower = colors[j - 1]; + upper = colors[j]; + range = upper.pct - lower.pct; + rangePct = (pct - lower.pct) / range; + pctLower = 1 - rangePct; + pctUpper = rangePct; + color = { + r: Math.floor(lower.color.r * pctLower + upper.color.r * pctUpper), + g: Math.floor(lower.color.g * pctLower + upper.color.g * pctUpper), + b: Math.floor(lower.color.b * pctLower + upper.color.b * pctUpper) + }; + return 'rgb(' + [color.r, color.g, color.b].join(',') + ')'; + } + } + } + +} + +/** Fix Raphael display:none tspan dy attribute bug */ +function setDy(elem, fontSize, txtYpos) { + if ((!ie || ie > 9) && elem.node.firstChild.attributes.dy) { + elem.node.firstChild.attributes.dy.value = 0; + } +} + +/** Random integer */ +function getRandomInt(min, max) { + return Math.floor(Math.random() * (max - min + 1)) + min; +} + +/** Cut hex */ +function cutHex(str) { + return (str.charAt(0) == "#") ? str.substring(1, 7) : str; +} + +/** Human friendly number suffix - From: http://stackoverflow.com/questions/2692323/code-golf-friendly-number-abbreviator */ +function humanFriendlyNumber(n, d) { + var p, d2, i, s; + + p = Math.pow; + d2 = p(10, d); + i = 7; + while (i) { + s = p(10, i-- * 3); + if (s <= n) { + n = Math.round(n * d2 / s) / d2 + "KMGTPE" [i]; + } + } + return n; +} + +/** Format numbers with commas - From: http://stackoverflow.com/questions/2901102/how-to-print-a-number-with-commas-as-thousands-separators-in-javascript */ +function formatNumber(x) { + var parts = x.toString().split("."); + parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ","); + return parts.join("."); +} + +/** Get style */ +function getStyle(oElm, strCssRule) { + var strValue = ""; + if (document.defaultView && document.defaultView.getComputedStyle) { + strValue = document.defaultView.getComputedStyle(oElm, "").getPropertyValue(strCssRule); + } else if (oElm.currentStyle) { + strCssRule = strCssRule.replace(/\-(\w)/g, function(strMatch, p1) { + return p1.toUpperCase(); + }); + strValue = oElm.currentStyle[strCssRule]; + } + return strValue; +} + +/** Create Element NS Ready */ +function onCreateElementNsReady(func) { + if (document.createElementNS !== undefined) { + func(); + } else { + setTimeout(function() { + onCreateElementNsReady(func); + }, 100); + } +} + +/** Get IE version */ +// ---------------------------------------------------------- +// A short snippet for detecting versions of IE in JavaScript +// without resorting to user-agent sniffing +// ---------------------------------------------------------- +// If you're not in IE (or IE version is less than 5) then: +// ie === undefined +// If you're in IE (>=5) then you can determine which version: +// ie === 7; // IE7 +// Thus, to detect IE: +// if (ie) {} +// And to detect the version: +// ie === 6 // IE6 +// ie > 7 // IE8, IE9 ... +// ie < 9 // Anything less than IE9 +// ---------------------------------------------------------- +// UPDATE: Now using Live NodeList idea from @jdalton +var ie = (function() { + + var undef, + v = 3, + div = document.createElement('div'), + all = div.getElementsByTagName('i'); + + while ( + div.innerHTML = '', + all[0] + ); + return v > 4 ? v : undef; +}()); + +// extend target object with second object +function extend(out) { + out = out || {}; + + for (var i = 1; i < arguments.length; i++) { + if (!arguments[i]) + continue; + + for (var key in arguments[i]) { + if (arguments[i].hasOwnProperty(key)) + out[key] = arguments[i][key]; + } + } + + return out; +}; diff --git a/examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/raphael-2.1.4.min.js b/examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/raphael-2.1.4.min.js new file mode 100644 index 000000000..b907338b7 --- /dev/null +++ b/examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/raphael-2.1.4.min.js @@ -0,0 +1,12 @@ +// ┌────────────────────────────────────────────────────────────────────┐ \\ +// │ Raphaël 2.1.4 - JavaScript Vector Library │ \\ +// ├────────────────────────────────────────────────────────────────────┤ \\ +// │ Copyright © 2008-2012 Dmitry Baranovskiy (http://raphaeljs.com) │ \\ +// │ Copyright © 2008-2012 Sencha Labs (http://sencha.com) │ \\ +// ├────────────────────────────────────────────────────────────────────┤ \\ +// │ Licensed under the MIT (http://raphaeljs.com/license.html) license.│ \\ +// └────────────────────────────────────────────────────────────────────┘ \\ +!function(a,b){"function"==typeof define&&define.amd?define("eve",function(){return b()}):"object"==typeof exports?module.exports=b():a.eve=b()}(this,function(){var a,b,c="0.4.2",d="hasOwnProperty",e=/[\.\/]/,f="*",g=function(){},h=function(a,b){return a-b},i={n:{}},j=function(c,d){c=String(c);var e,f=b,g=Array.prototype.slice.call(arguments,2),i=j.listeners(c),k=0,l=[],m={},n=[],o=a;a=c,b=0;for(var p=0,q=i.length;q>p;p++)"zIndex"in i[p]&&(l.push(i[p].zIndex),i[p].zIndex<0&&(m[i[p].zIndex]=i[p]));for(l.sort(h);l[k]<0;)if(e=m[l[k++]],n.push(e.apply(d,g)),b)return b=f,n;for(p=0;q>p;p++)if(e=i[p],"zIndex"in e)if(e.zIndex==l[k]){if(n.push(e.apply(d,g)),b)break;do if(k++,e=m[l[k]],e&&n.push(e.apply(d,g)),b)break;while(e)}else m[e.zIndex]=e;else if(n.push(e.apply(d,g)),b)break;return b=f,a=o,n.length?n:null};return j._events=i,j.listeners=function(a){var b,c,d,g,h,j,k,l,m=a.split(e),n=i,o=[n],p=[];for(g=0,h=m.length;h>g;g++){for(l=[],j=0,k=o.length;k>j;j++)for(n=o[j].n,c=[n[m[g]],n[f]],d=2;d--;)b=c[d],b&&(l.push(b),p=p.concat(b.f||[]));o=l}return p},j.on=function(a,b){if(a=String(a),"function"!=typeof b)return function(){};for(var c=a.split(e),d=i,f=0,h=c.length;h>f;f++)d=d.n,d=d.hasOwnProperty(c[f])&&d[c[f]]||(d[c[f]]={n:{}});for(d.f=d.f||[],f=0,h=d.f.length;h>f;f++)if(d.f[f]==b)return g;return d.f.push(b),function(a){+a==+a&&(b.zIndex=+a)}},j.f=function(a){var b=[].slice.call(arguments,1);return function(){j.apply(null,[a,null].concat(b).concat([].slice.call(arguments,0)))}},j.stop=function(){b=1},j.nt=function(b){return b?new RegExp("(?:\\.|\\/|^)"+b+"(?:\\.|\\/|$)").test(a):a},j.nts=function(){return a.split(e)},j.off=j.unbind=function(a,b){if(!a)return void(j._events=i={n:{}});var c,g,h,k,l,m,n,o=a.split(e),p=[i];for(k=0,l=o.length;l>k;k++)for(m=0;mk;k++)for(c=p[k];c.n;){if(b){if(c.f){for(m=0,n=c.f.length;n>m;m++)if(c.f[m]==b){c.f.splice(m,1);break}!c.f.length&&delete c.f}for(g in c.n)if(c.n[d](g)&&c.n[g].f){var q=c.n[g].f;for(m=0,n=q.length;n>m;m++)if(q[m]==b){q.splice(m,1);break}!q.length&&delete c.n[g].f}}else{delete c.f;for(g in c.n)c.n[d](g)&&c.n[g].f&&delete c.n[g].f}c=c.n}},j.once=function(a,b){var c=function(){return j.unbind(a,c),b.apply(this,arguments)};return j.on(a,c)},j.version=c,j.toString=function(){return"You are running Eve "+c},j}),function(a,b){"function"==typeof define&&define.amd?define("raphael.core",["eve"],function(a){return b(a)}):"object"==typeof exports?module.exports=b(require("eve")):a.Raphael=b(a.eve)}(this,function(a){function b(c){if(b.is(c,"function"))return t?c():a.on("raphael.DOMload",c);if(b.is(c,U))return b._engine.create[C](b,c.splice(0,3+b.is(c[0],S))).add(c);var d=Array.prototype.slice.call(arguments,0);if(b.is(d[d.length-1],"function")){var e=d.pop();return t?e.call(b._engine.create[C](b,d)):a.on("raphael.DOMload",function(){e.call(b._engine.create[C](b,d))})}return b._engine.create[C](b,arguments)}function c(a){if("function"==typeof a||Object(a)!==a)return a;var b=new a.constructor;for(var d in a)a[y](d)&&(b[d]=c(a[d]));return b}function d(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c]===b)return a.push(a.splice(c,1)[0])}function e(a,b,c){function e(){var f=Array.prototype.slice.call(arguments,0),g=f.join("␀"),h=e.cache=e.cache||{},i=e.count=e.count||[];return h[y](g)?(d(i,g),c?c(h[g]):h[g]):(i.length>=1e3&&delete h[i.shift()],i.push(g),h[g]=a[C](b,f),c?c(h[g]):h[g])}return e}function f(){return this.hex}function g(a,b){for(var c=[],d=0,e=a.length;e-2*!b>d;d+=2){var f=[{x:+a[d-2],y:+a[d-1]},{x:+a[d],y:+a[d+1]},{x:+a[d+2],y:+a[d+3]},{x:+a[d+4],y:+a[d+5]}];b?d?e-4==d?f[3]={x:+a[0],y:+a[1]}:e-2==d&&(f[2]={x:+a[0],y:+a[1]},f[3]={x:+a[2],y:+a[3]}):f[0]={x:+a[e-2],y:+a[e-1]}:e-4==d?f[3]=f[2]:d||(f[0]={x:+a[d],y:+a[d+1]}),c.push(["C",(-f[0].x+6*f[1].x+f[2].x)/6,(-f[0].y+6*f[1].y+f[2].y)/6,(f[1].x+6*f[2].x-f[3].x)/6,(f[1].y+6*f[2].y-f[3].y)/6,f[2].x,f[2].y])}return c}function h(a,b,c,d,e){var f=-3*b+9*c-9*d+3*e,g=a*f+6*b-12*c+6*d;return a*g-3*b+3*c}function i(a,b,c,d,e,f,g,i,j){null==j&&(j=1),j=j>1?1:0>j?0:j;for(var k=j/2,l=12,m=[-.1252,.1252,-.3678,.3678,-.5873,.5873,-.7699,.7699,-.9041,.9041,-.9816,.9816],n=[.2491,.2491,.2335,.2335,.2032,.2032,.1601,.1601,.1069,.1069,.0472,.0472],o=0,p=0;l>p;p++){var q=k*m[p]+k,r=h(q,a,c,e,g),s=h(q,b,d,f,i),t=r*r+s*s;o+=n[p]*M.sqrt(t)}return k*o}function j(a,b,c,d,e,f,g,h,j){if(!(0>j||i(a,b,c,d,e,f,g,h)o;)m/=2,n+=(j>k?1:-1)*m,k=i(a,b,c,d,e,f,g,h,n);return n}}function k(a,b,c,d,e,f,g,h){if(!(N(a,c)N(e,g)||N(b,d)N(f,h))){var i=(a*d-b*c)*(e-g)-(a-c)*(e*h-f*g),j=(a*d-b*c)*(f-h)-(b-d)*(e*h-f*g),k=(a-c)*(f-h)-(b-d)*(e-g);if(k){var l=i/k,m=j/k,n=+l.toFixed(2),o=+m.toFixed(2);if(!(n<+O(a,c).toFixed(2)||n>+N(a,c).toFixed(2)||n<+O(e,g).toFixed(2)||n>+N(e,g).toFixed(2)||o<+O(b,d).toFixed(2)||o>+N(b,d).toFixed(2)||o<+O(f,h).toFixed(2)||o>+N(f,h).toFixed(2)))return{x:l,y:m}}}}function l(a,c,d){var e=b.bezierBBox(a),f=b.bezierBBox(c);if(!b.isBBoxIntersect(e,f))return d?0:[];for(var g=i.apply(0,a),h=i.apply(0,c),j=N(~~(g/5),1),l=N(~~(h/5),1),m=[],n=[],o={},p=d?0:[],q=0;j+1>q;q++){var r=b.findDotsAtSegment.apply(b,a.concat(q/j));m.push({x:r.x,y:r.y,t:q/j})}for(q=0;l+1>q;q++)r=b.findDotsAtSegment.apply(b,c.concat(q/l)),n.push({x:r.x,y:r.y,t:q/l});for(q=0;j>q;q++)for(var s=0;l>s;s++){var t=m[q],u=m[q+1],v=n[s],w=n[s+1],x=P(u.x-t.x)<.001?"y":"x",y=P(w.x-v.x)<.001?"y":"x",z=k(t.x,t.y,u.x,u.y,v.x,v.y,w.x,w.y);if(z){if(o[z.x.toFixed(4)]==z.y.toFixed(4))continue;o[z.x.toFixed(4)]=z.y.toFixed(4);var A=t.t+P((z[x]-t[x])/(u[x]-t[x]))*(u.t-t.t),B=v.t+P((z[y]-v[y])/(w[y]-v[y]))*(w.t-v.t);A>=0&&1.001>=A&&B>=0&&1.001>=B&&(d?p++:p.push({x:z.x,y:z.y,t1:O(A,1),t2:O(B,1)}))}}return p}function m(a,c,d){a=b._path2curve(a),c=b._path2curve(c);for(var e,f,g,h,i,j,k,m,n,o,p=d?0:[],q=0,r=a.length;r>q;q++){var s=a[q];if("M"==s[0])e=i=s[1],f=j=s[2];else{"C"==s[0]?(n=[e,f].concat(s.slice(1)),e=n[6],f=n[7]):(n=[e,f,e,f,i,j,i,j],e=i,f=j);for(var t=0,u=c.length;u>t;t++){var v=c[t];if("M"==v[0])g=k=v[1],h=m=v[2];else{"C"==v[0]?(o=[g,h].concat(v.slice(1)),g=o[6],h=o[7]):(o=[g,h,g,h,k,m,k,m],g=k,h=m);var w=l(n,o,d);if(d)p+=w;else{for(var x=0,y=w.length;y>x;x++)w[x].segment1=q,w[x].segment2=t,w[x].bez1=n,w[x].bez2=o;p=p.concat(w)}}}}}return p}function n(a,b,c,d,e,f){null!=a?(this.a=+a,this.b=+b,this.c=+c,this.d=+d,this.e=+e,this.f=+f):(this.a=1,this.b=0,this.c=0,this.d=1,this.e=0,this.f=0)}function o(){return this.x+G+this.y+G+this.width+" × "+this.height}function p(a,b,c,d,e,f){function g(a){return((l*a+k)*a+j)*a}function h(a,b){var c=i(a,b);return((o*c+n)*c+m)*c}function i(a,b){var c,d,e,f,h,i;for(e=a,i=0;8>i;i++){if(f=g(e)-a,P(f)e)return c;if(e>d)return d;for(;d>c;){if(f=g(e),P(f-a)f?c=e:d=e,e=(d-c)/2+c}return e}var j=3*b,k=3*(d-b)-j,l=1-j-k,m=3*c,n=3*(e-c)-m,o=1-m-n;return h(a,1/(200*f))}function q(a,b){var c=[],d={};if(this.ms=b,this.times=1,a){for(var e in a)a[y](e)&&(d[$(e)]=a[e],c.push($(e)));c.sort(ka)}this.anim=d,this.top=c[c.length-1],this.percents=c}function r(c,d,e,f,g,h){e=$(e);var i,j,k,l,m,o,q=c.ms,r={},s={},t={};if(f)for(w=0,x=fb.length;x>w;w++){var u=fb[w];if(u.el.id==d.id&&u.anim==c){u.percent!=e?(fb.splice(w,1),k=1):j=u,d.attr(u.totalOrigin);break}}else f=+s;for(var w=0,x=c.percents.length;x>w;w++){if(c.percents[w]==e||c.percents[w]>f*c.top){e=c.percents[w],m=c.percents[w-1]||0,q=q/c.top*(e-m),l=c.percents[w+1],i=c.anim[e];break}f&&d.attr(c.anim[c.percents[w]])}if(i){if(j)j.initstatus=f,j.start=new Date-j.ms*f;else{for(var z in i)if(i[y](z)&&(ca[y](z)||d.paper.customAttributes[y](z)))switch(r[z]=d.attr(z),null==r[z]&&(r[z]=ba[z]),s[z]=i[z],ca[z]){case S:t[z]=(s[z]-r[z])/q;break;case"colour":r[z]=b.getRGB(r[z]);var A=b.getRGB(s[z]);t[z]={r:(A.r-r[z].r)/q,g:(A.g-r[z].g)/q,b:(A.b-r[z].b)/q};break;case"path":var B=Ia(r[z],s[z]),C=B[1];for(r[z]=B[0],t[z]=[],w=0,x=r[z].length;x>w;w++){t[z][w]=[0];for(var E=1,F=r[z][w].length;F>E;E++)t[z][w][E]=(C[w][E]-r[z][w][E])/q}break;case"transform":var G=d._,J=Na(G[z],s[z]);if(J)for(r[z]=J.from,s[z]=J.to,t[z]=[],t[z].real=!0,w=0,x=r[z].length;x>w;w++)for(t[z][w]=[r[z][w][0]],E=1,F=r[z][w].length;F>E;E++)t[z][w][E]=(s[z][w][E]-r[z][w][E])/q;else{var K=d.matrix||new n,L={_:{transform:G.transform},getBBox:function(){return d.getBBox(1)}};r[z]=[K.a,K.b,K.c,K.d,K.e,K.f],La(L,s[z]),s[z]=L._.transform,t[z]=[(L.matrix.a-K.a)/q,(L.matrix.b-K.b)/q,(L.matrix.c-K.c)/q,(L.matrix.d-K.d)/q,(L.matrix.e-K.e)/q,(L.matrix.f-K.f)/q]}break;case"csv":var M=H(i[z])[I](v),N=H(r[z])[I](v);if("clip-rect"==z)for(r[z]=N,t[z]=[],w=N.length;w--;)t[z][w]=(M[w]-r[z][w])/q;s[z]=M;break;default:for(M=[][D](i[z]),N=[][D](r[z]),t[z]=[],w=d.paper.customAttributes[z].length;w--;)t[z][w]=((M[w]||0)-(N[w]||0))/q}var O=i.easing,P=b.easing_formulas[O];if(!P)if(P=H(O).match(Y),P&&5==P.length){var Q=P;P=function(a){return p(a,+Q[1],+Q[2],+Q[3],+Q[4],q)}}else P=la;if(o=i.start||c.start||+new Date,u={anim:c,percent:e,timestamp:o,start:o+(c.del||0),status:0,initstatus:f||0,stop:!1,ms:q,easing:P,from:r,diff:t,to:s,el:d,callback:i.callback,prev:m,next:l,repeat:h||c.times,origin:d.attr(),totalOrigin:g},fb.push(u),f&&!j&&!k&&(u.stop=!0,u.start=new Date-q*f,1==fb.length))return hb();k&&(u.start=new Date-u.ms*f),1==fb.length&&gb(hb)}a("raphael.anim.start."+d.id,d,c)}}function s(a){for(var b=0;be;e++)for(i=a[e],f=1,h=i.length;h>f;f+=2)c=b.x(i[f],i[f+1]),d=b.y(i[f],i[f+1]),i[f]=c,i[f+1]=d;return a};if(b._g=z,b.type=z.win.SVGAngle||z.doc.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure","1.1")?"SVG":"VML","VML"==b.type){var qa,ra=z.doc.createElement("div");if(ra.innerHTML='',qa=ra.firstChild,qa.style.behavior="url(#default#VML)",!qa||"object"!=typeof qa.adj)return b.type=F;ra=null}b.svg=!(b.vml="VML"==b.type),b._Paper=B,b.fn=u=B.prototype=b.prototype,b._id=0,b._oid=0,b.is=function(a,b){return b=L.call(b),"finite"==b?!X[y](+a):"array"==b?a instanceof Array:"null"==b&&null===a||b==typeof a&&null!==a||"object"==b&&a===Object(a)||"array"==b&&Array.isArray&&Array.isArray(a)||V.call(a).slice(8,-1).toLowerCase()==b},b.angle=function(a,c,d,e,f,g){if(null==f){var h=a-d,i=c-e;return h||i?(180+180*M.atan2(-i,-h)/R+360)%360:0}return b.angle(a,c,f,g)-b.angle(d,e,f,g)},b.rad=function(a){return a%360*R/180},b.deg=function(a){return Math.round(180*a/R%360*1e3)/1e3},b.snapTo=function(a,c,d){if(d=b.is(d,"finite")?d:10,b.is(a,U)){for(var e=a.length;e--;)if(P(a[e]-c)<=d)return a[e]}else{a=+a;var f=c%a;if(d>f)return c-f;if(f>a-d)return c-f+a}return c};b.createUUID=function(a,b){return function(){return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(a,b).toUpperCase()}}(/[xy]/g,function(a){var b=16*M.random()|0,c="x"==a?b:3&b|8;return c.toString(16)});b.setWindow=function(c){a("raphael.setWindow",b,z.win,c),z.win=c,z.doc=z.win.document,b._engine.initWin&&b._engine.initWin(z.win)};var sa=function(a){if(b.vml){var c,d=/^\s+|\s+$/g;try{var f=new ActiveXObject("htmlfile");f.write(""),f.close(),c=f.body}catch(g){c=createPopup().document.body}var h=c.createTextRange();sa=e(function(a){try{c.style.color=H(a).replace(d,F);var b=h.queryCommandValue("ForeColor");return b=(255&b)<<16|65280&b|(16711680&b)>>>16,"#"+("000000"+b.toString(16)).slice(-6)}catch(e){return"none"}})}else{var i=z.doc.createElement("i");i.title="Raphaël Colour Picker",i.style.display="none",z.doc.body.appendChild(i),sa=e(function(a){return i.style.color=a,z.doc.defaultView.getComputedStyle(i,F).getPropertyValue("color")})}return sa(a)},ta=function(){return"hsb("+[this.h,this.s,this.b]+")"},ua=function(){return"hsl("+[this.h,this.s,this.l]+")"},va=function(){return this.hex},wa=function(a,c,d){if(null==c&&b.is(a,"object")&&"r"in a&&"g"in a&&"b"in a&&(d=a.b,c=a.g,a=a.r),null==c&&b.is(a,T)){var e=b.getRGB(a);a=e.r,c=e.g,d=e.b}return(a>1||c>1||d>1)&&(a/=255,c/=255,d/=255),[a,c,d]},xa=function(a,c,d,e){a*=255,c*=255,d*=255;var f={r:a,g:c,b:d,hex:b.rgb(a,c,d),toString:va};return b.is(e,"finite")&&(f.opacity=e),f};b.color=function(a){var c;return b.is(a,"object")&&"h"in a&&"s"in a&&"b"in a?(c=b.hsb2rgb(a),a.r=c.r,a.g=c.g,a.b=c.b,a.hex=c.hex):b.is(a,"object")&&"h"in a&&"s"in a&&"l"in a?(c=b.hsl2rgb(a),a.r=c.r,a.g=c.g,a.b=c.b,a.hex=c.hex):(b.is(a,"string")&&(a=b.getRGB(a)),b.is(a,"object")&&"r"in a&&"g"in a&&"b"in a?(c=b.rgb2hsl(a),a.h=c.h,a.s=c.s,a.l=c.l,c=b.rgb2hsb(a),a.v=c.b):(a={hex:"none"},a.r=a.g=a.b=a.h=a.s=a.v=a.l=-1)),a.toString=va,a},b.hsb2rgb=function(a,b,c,d){this.is(a,"object")&&"h"in a&&"s"in a&&"b"in a&&(c=a.b,b=a.s,d=a.o,a=a.h),a*=360;var e,f,g,h,i;return a=a%360/60,i=c*b,h=i*(1-P(a%2-1)),e=f=g=c-i,a=~~a,e+=[i,h,0,0,h,i][a],f+=[h,i,i,h,0,0][a],g+=[0,0,h,i,i,h][a],xa(e,f,g,d)},b.hsl2rgb=function(a,b,c,d){this.is(a,"object")&&"h"in a&&"s"in a&&"l"in a&&(c=a.l,b=a.s,a=a.h),(a>1||b>1||c>1)&&(a/=360,b/=100,c/=100),a*=360;var e,f,g,h,i;return a=a%360/60,i=2*b*(.5>c?c:1-c),h=i*(1-P(a%2-1)),e=f=g=c-i/2,a=~~a,e+=[i,h,0,0,h,i][a],f+=[h,i,i,h,0,0][a],g+=[0,0,h,i,i,h][a],xa(e,f,g,d)},b.rgb2hsb=function(a,b,c){c=wa(a,b,c),a=c[0],b=c[1],c=c[2];var d,e,f,g;return f=N(a,b,c),g=f-O(a,b,c),d=0==g?null:f==a?(b-c)/g:f==b?(c-a)/g+2:(a-b)/g+4,d=(d+360)%6*60/360,e=0==g?0:g/f,{h:d,s:e,b:f,toString:ta}},b.rgb2hsl=function(a,b,c){c=wa(a,b,c),a=c[0],b=c[1],c=c[2];var d,e,f,g,h,i;return g=N(a,b,c),h=O(a,b,c),i=g-h,d=0==i?null:g==a?(b-c)/i:g==b?(c-a)/i+2:(a-b)/i+4,d=(d+360)%6*60/360,f=(g+h)/2,e=0==i?0:.5>f?i/(2*f):i/(2-2*f),{h:d,s:e,l:f,toString:ua}},b._path2string=function(){return this.join(",").replace(fa,"$1")};b._preload=function(a,b){var c=z.doc.createElement("img");c.style.cssText="position:absolute;left:-9999em;top:-9999em",c.onload=function(){b.call(this),this.onload=null,z.doc.body.removeChild(this)},c.onerror=function(){z.doc.body.removeChild(this)},z.doc.body.appendChild(c),c.src=a};b.getRGB=e(function(a){if(!a||(a=H(a)).indexOf("-")+1)return{r:-1,g:-1,b:-1,hex:"none",error:1,toString:f};if("none"==a)return{r:-1,g:-1,b:-1,hex:"none",toString:f};!(ea[y](a.toLowerCase().substring(0,2))||"#"==a.charAt())&&(a=sa(a));var c,d,e,g,h,i,j=a.match(W);return j?(j[2]&&(e=_(j[2].substring(5),16),d=_(j[2].substring(3,5),16),c=_(j[2].substring(1,3),16)),j[3]&&(e=_((h=j[3].charAt(3))+h,16),d=_((h=j[3].charAt(2))+h,16),c=_((h=j[3].charAt(1))+h,16)),j[4]&&(i=j[4][I](da),c=$(i[0]),"%"==i[0].slice(-1)&&(c*=2.55),d=$(i[1]),"%"==i[1].slice(-1)&&(d*=2.55),e=$(i[2]),"%"==i[2].slice(-1)&&(e*=2.55),"rgba"==j[1].toLowerCase().slice(0,4)&&(g=$(i[3])),i[3]&&"%"==i[3].slice(-1)&&(g/=100)),j[5]?(i=j[5][I](da),c=$(i[0]),"%"==i[0].slice(-1)&&(c*=2.55),d=$(i[1]),"%"==i[1].slice(-1)&&(d*=2.55),e=$(i[2]),"%"==i[2].slice(-1)&&(e*=2.55),("deg"==i[0].slice(-3)||"°"==i[0].slice(-1))&&(c/=360),"hsba"==j[1].toLowerCase().slice(0,4)&&(g=$(i[3])),i[3]&&"%"==i[3].slice(-1)&&(g/=100),b.hsb2rgb(c,d,e,g)):j[6]?(i=j[6][I](da),c=$(i[0]),"%"==i[0].slice(-1)&&(c*=2.55),d=$(i[1]),"%"==i[1].slice(-1)&&(d*=2.55),e=$(i[2]),"%"==i[2].slice(-1)&&(e*=2.55),("deg"==i[0].slice(-3)||"°"==i[0].slice(-1))&&(c/=360),"hsla"==j[1].toLowerCase().slice(0,4)&&(g=$(i[3])),i[3]&&"%"==i[3].slice(-1)&&(g/=100),b.hsl2rgb(c,d,e,g)):(j={r:c,g:d,b:e,toString:f},j.hex="#"+(16777216|e|d<<8|c<<16).toString(16).slice(1),b.is(g,"finite")&&(j.opacity=g),j)):{r:-1,g:-1,b:-1,hex:"none",error:1,toString:f}},b),b.hsb=e(function(a,c,d){return b.hsb2rgb(a,c,d).hex}),b.hsl=e(function(a,c,d){return b.hsl2rgb(a,c,d).hex}),b.rgb=e(function(a,b,c){function d(a){return a+.5|0}return"#"+(16777216|d(c)|d(b)<<8|d(a)<<16).toString(16).slice(1)}),b.getColor=function(a){var b=this.getColor.start=this.getColor.start||{h:0,s:1,b:a||.75},c=this.hsb2rgb(b.h,b.s,b.b);return b.h+=.075,b.h>1&&(b.h=0,b.s-=.2,b.s<=0&&(this.getColor.start={h:0,s:1,b:b.b})),c.hex},b.getColor.reset=function(){delete this.start},b.parsePathString=function(a){if(!a)return null;var c=ya(a);if(c.arr)return Aa(c.arr);var d={a:7,c:6,h:1,l:2,m:2,r:4,q:4,s:4,t:2,v:1,z:0},e=[];return b.is(a,U)&&b.is(a[0],U)&&(e=Aa(a)),e.length||H(a).replace(ga,function(a,b,c){var f=[],g=b.toLowerCase();if(c.replace(ia,function(a,b){b&&f.push(+b)}),"m"==g&&f.length>2&&(e.push([b][D](f.splice(0,2))),g="l",b="m"==b?"l":"L"),"r"==g)e.push([b][D](f));else for(;f.length>=d[g]&&(e.push([b][D](f.splice(0,d[g]))),d[g]););}),e.toString=b._path2string,c.arr=Aa(e),e},b.parseTransformString=e(function(a){if(!a)return null;var c=[];return b.is(a,U)&&b.is(a[0],U)&&(c=Aa(a)),c.length||H(a).replace(ha,function(a,b,d){{var e=[];L.call(b)}d.replace(ia,function(a,b){b&&e.push(+b)}),c.push([b][D](e))}),c.toString=b._path2string,c});var ya=function(a){var b=ya.ps=ya.ps||{};return b[a]?b[a].sleep=100:b[a]={sleep:100},setTimeout(function(){for(var c in b)b[y](c)&&c!=a&&(b[c].sleep--,!b[c].sleep&&delete b[c])}),b[a]};b.findDotsAtSegment=function(a,b,c,d,e,f,g,h,i){var j=1-i,k=Q(j,3),l=Q(j,2),m=i*i,n=m*i,o=k*a+3*l*i*c+3*j*i*i*e+n*g,p=k*b+3*l*i*d+3*j*i*i*f+n*h,q=a+2*i*(c-a)+m*(e-2*c+a),r=b+2*i*(d-b)+m*(f-2*d+b),s=c+2*i*(e-c)+m*(g-2*e+c),t=d+2*i*(f-d)+m*(h-2*f+d),u=j*a+i*c,v=j*b+i*d,w=j*e+i*g,x=j*f+i*h,y=90-180*M.atan2(q-s,r-t)/R;return(q>s||t>r)&&(y+=180),{x:o,y:p,m:{x:q,y:r},n:{x:s,y:t},start:{x:u,y:v},end:{x:w,y:x},alpha:y}},b.bezierBBox=function(a,c,d,e,f,g,h,i){b.is(a,"array")||(a=[a,c,d,e,f,g,h,i]);var j=Ha.apply(null,a);return{x:j.min.x,y:j.min.y,x2:j.max.x,y2:j.max.y,width:j.max.x-j.min.x,height:j.max.y-j.min.y}},b.isPointInsideBBox=function(a,b,c){return b>=a.x&&b<=a.x2&&c>=a.y&&c<=a.y2},b.isBBoxIntersect=function(a,c){var d=b.isPointInsideBBox;return d(c,a.x,a.y)||d(c,a.x2,a.y)||d(c,a.x,a.y2)||d(c,a.x2,a.y2)||d(a,c.x,c.y)||d(a,c.x2,c.y)||d(a,c.x,c.y2)||d(a,c.x2,c.y2)||(a.xc.x||c.xa.x)&&(a.yc.y||c.ya.y)},b.pathIntersection=function(a,b){return m(a,b)},b.pathIntersectionNumber=function(a,b){return m(a,b,1)},b.isPointInsidePath=function(a,c,d){var e=b.pathBBox(a);return b.isPointInsideBBox(e,c,d)&&m(a,[["M",c,d],["H",e.x2+10]],1)%2==1},b._removedFactory=function(b){return function(){a("raphael.log",null,"Raphaël: you are calling to method “"+b+"” of removed object",b)}};var za=b.pathBBox=function(a){var b=ya(a);if(b.bbox)return c(b.bbox);if(!a)return{x:0,y:0,width:0,height:0,x2:0,y2:0};a=Ia(a);for(var d,e=0,f=0,g=[],h=[],i=0,j=a.length;j>i;i++)if(d=a[i],"M"==d[0])e=d[1],f=d[2],g.push(e),h.push(f);else{var k=Ha(e,f,d[1],d[2],d[3],d[4],d[5],d[6]);g=g[D](k.min.x,k.max.x),h=h[D](k.min.y,k.max.y),e=d[5],f=d[6]}var l=O[C](0,g),m=O[C](0,h),n=N[C](0,g),o=N[C](0,h),p=n-l,q=o-m,r={x:l,y:m,x2:n,y2:o,width:p,height:q,cx:l+p/2,cy:m+q/2};return b.bbox=c(r),r},Aa=function(a){var d=c(a);return d.toString=b._path2string,d},Ba=b._pathToRelative=function(a){var c=ya(a);if(c.rel)return Aa(c.rel);b.is(a,U)&&b.is(a&&a[0],U)||(a=b.parsePathString(a));var d=[],e=0,f=0,g=0,h=0,i=0;"M"==a[0][0]&&(e=a[0][1],f=a[0][2],g=e,h=f,i++,d.push(["M",e,f]));for(var j=i,k=a.length;k>j;j++){var l=d[j]=[],m=a[j];if(m[0]!=L.call(m[0]))switch(l[0]=L.call(m[0]),l[0]){case"a":l[1]=m[1],l[2]=m[2],l[3]=m[3],l[4]=m[4],l[5]=m[5],l[6]=+(m[6]-e).toFixed(3),l[7]=+(m[7]-f).toFixed(3);break;case"v":l[1]=+(m[1]-f).toFixed(3);break;case"m":g=m[1],h=m[2];default:for(var n=1,o=m.length;o>n;n++)l[n]=+(m[n]-(n%2?e:f)).toFixed(3)}else{l=d[j]=[],"m"==m[0]&&(g=m[1]+e,h=m[2]+f);for(var p=0,q=m.length;q>p;p++)d[j][p]=m[p]}var r=d[j].length;switch(d[j][0]){case"z":e=g,f=h;break;case"h":e+=+d[j][r-1];break;case"v":f+=+d[j][r-1];break;default:e+=+d[j][r-2],f+=+d[j][r-1]}}return d.toString=b._path2string,c.rel=Aa(d),d},Ca=b._pathToAbsolute=function(a){var c=ya(a);if(c.abs)return Aa(c.abs);if(b.is(a,U)&&b.is(a&&a[0],U)||(a=b.parsePathString(a)),!a||!a.length)return[["M",0,0]];var d=[],e=0,f=0,h=0,i=0,j=0;"M"==a[0][0]&&(e=+a[0][1],f=+a[0][2],h=e,i=f,j++,d[0]=["M",e,f]);for(var k,l,m=3==a.length&&"M"==a[0][0]&&"R"==a[1][0].toUpperCase()&&"Z"==a[2][0].toUpperCase(),n=j,o=a.length;o>n;n++){if(d.push(k=[]),l=a[n],l[0]!=aa.call(l[0]))switch(k[0]=aa.call(l[0]),k[0]){case"A":k[1]=l[1],k[2]=l[2],k[3]=l[3],k[4]=l[4],k[5]=l[5],k[6]=+(l[6]+e),k[7]=+(l[7]+f);break;case"V":k[1]=+l[1]+f;break;case"H":k[1]=+l[1]+e;break;case"R":for(var p=[e,f][D](l.slice(1)),q=2,r=p.length;r>q;q++)p[q]=+p[q]+e,p[++q]=+p[q]+f;d.pop(),d=d[D](g(p,m));break;case"M":h=+l[1]+e,i=+l[2]+f;default:for(q=1,r=l.length;r>q;q++)k[q]=+l[q]+(q%2?e:f)}else if("R"==l[0])p=[e,f][D](l.slice(1)),d.pop(),d=d[D](g(p,m)),k=["R"][D](l.slice(-2));else for(var s=0,t=l.length;t>s;s++)k[s]=l[s];switch(k[0]){case"Z":e=h,f=i;break;case"H":e=k[1];break;case"V":f=k[1];break;case"M":h=k[k.length-2],i=k[k.length-1];default:e=k[k.length-2],f=k[k.length-1]}}return d.toString=b._path2string,c.abs=Aa(d),d},Da=function(a,b,c,d){return[a,b,c,d,c,d]},Ea=function(a,b,c,d,e,f){var g=1/3,h=2/3;return[g*a+h*c,g*b+h*d,g*e+h*c,g*f+h*d,e,f]},Fa=function(a,b,c,d,f,g,h,i,j,k){var l,m=120*R/180,n=R/180*(+f||0),o=[],p=e(function(a,b,c){var d=a*M.cos(c)-b*M.sin(c),e=a*M.sin(c)+b*M.cos(c);return{x:d,y:e}});if(k)y=k[0],z=k[1],w=k[2],x=k[3];else{l=p(a,b,-n),a=l.x,b=l.y,l=p(i,j,-n),i=l.x,j=l.y;var q=(M.cos(R/180*f),M.sin(R/180*f),(a-i)/2),r=(b-j)/2,s=q*q/(c*c)+r*r/(d*d);s>1&&(s=M.sqrt(s),c=s*c,d=s*d);var t=c*c,u=d*d,v=(g==h?-1:1)*M.sqrt(P((t*u-t*r*r-u*q*q)/(t*r*r+u*q*q))),w=v*c*r/d+(a+i)/2,x=v*-d*q/c+(b+j)/2,y=M.asin(((b-x)/d).toFixed(9)),z=M.asin(((j-x)/d).toFixed(9));y=w>a?R-y:y,z=w>i?R-z:z,0>y&&(y=2*R+y),0>z&&(z=2*R+z),h&&y>z&&(y-=2*R),!h&&z>y&&(z-=2*R)}var A=z-y;if(P(A)>m){var B=z,C=i,E=j;z=y+m*(h&&z>y?1:-1),i=w+c*M.cos(z),j=x+d*M.sin(z),o=Fa(i,j,c,d,f,0,h,C,E,[z,B,w,x])}A=z-y;var F=M.cos(y),G=M.sin(y),H=M.cos(z),J=M.sin(z),K=M.tan(A/4),L=4/3*c*K,N=4/3*d*K,O=[a,b],Q=[a+L*G,b-N*F],S=[i+L*J,j-N*H],T=[i,j];if(Q[0]=2*O[0]-Q[0],Q[1]=2*O[1]-Q[1],k)return[Q,S,T][D](o);o=[Q,S,T][D](o).join()[I](",");for(var U=[],V=0,W=o.length;W>V;V++)U[V]=V%2?p(o[V-1],o[V],n).y:p(o[V],o[V+1],n).x;return U},Ga=function(a,b,c,d,e,f,g,h,i){var j=1-i;return{x:Q(j,3)*a+3*Q(j,2)*i*c+3*j*i*i*e+Q(i,3)*g,y:Q(j,3)*b+3*Q(j,2)*i*d+3*j*i*i*f+Q(i,3)*h}},Ha=e(function(a,b,c,d,e,f,g,h){var i,j=e-2*c+a-(g-2*e+c),k=2*(c-a)-2*(e-c),l=a-c,m=(-k+M.sqrt(k*k-4*j*l))/2/j,n=(-k-M.sqrt(k*k-4*j*l))/2/j,o=[b,h],p=[a,g];return P(m)>"1e12"&&(m=.5),P(n)>"1e12"&&(n=.5),m>0&&1>m&&(i=Ga(a,b,c,d,e,f,g,h,m),p.push(i.x),o.push(i.y)),n>0&&1>n&&(i=Ga(a,b,c,d,e,f,g,h,n),p.push(i.x),o.push(i.y)),j=f-2*d+b-(h-2*f+d),k=2*(d-b)-2*(f-d),l=b-d,m=(-k+M.sqrt(k*k-4*j*l))/2/j,n=(-k-M.sqrt(k*k-4*j*l))/2/j,P(m)>"1e12"&&(m=.5),P(n)>"1e12"&&(n=.5),m>0&&1>m&&(i=Ga(a,b,c,d,e,f,g,h,m),p.push(i.x),o.push(i.y)),n>0&&1>n&&(i=Ga(a,b,c,d,e,f,g,h,n),p.push(i.x),o.push(i.y)),{min:{x:O[C](0,p),y:O[C](0,o)},max:{x:N[C](0,p),y:N[C](0,o)}}}),Ia=b._path2curve=e(function(a,b){var c=!b&&ya(a);if(!b&&c.curve)return Aa(c.curve);for(var d=Ca(a),e=b&&Ca(b),f={x:0,y:0,bx:0,by:0,X:0,Y:0,qx:null,qy:null},g={x:0,y:0,bx:0,by:0,X:0,Y:0,qx:null,qy:null},h=(function(a,b,c){var d,e,f={T:1,Q:1};if(!a)return["C",b.x,b.y,b.x,b.y,b.x,b.y];switch(!(a[0]in f)&&(b.qx=b.qy=null),a[0]){case"M":b.X=a[1],b.Y=a[2];break;case"A":a=["C"][D](Fa[C](0,[b.x,b.y][D](a.slice(1))));break;case"S":"C"==c||"S"==c?(d=2*b.x-b.bx,e=2*b.y-b.by):(d=b.x,e=b.y),a=["C",d,e][D](a.slice(1));break;case"T":"Q"==c||"T"==c?(b.qx=2*b.x-b.qx,b.qy=2*b.y-b.qy):(b.qx=b.x,b.qy=b.y),a=["C"][D](Ea(b.x,b.y,b.qx,b.qy,a[1],a[2]));break;case"Q":b.qx=a[1],b.qy=a[2],a=["C"][D](Ea(b.x,b.y,a[1],a[2],a[3],a[4]));break;case"L":a=["C"][D](Da(b.x,b.y,a[1],a[2]));break;case"H":a=["C"][D](Da(b.x,b.y,a[1],b.y));break;case"V":a=["C"][D](Da(b.x,b.y,b.x,a[1]));break;case"Z":a=["C"][D](Da(b.x,b.y,b.X,b.Y))}return a}),i=function(a,b){if(a[b].length>7){a[b].shift();for(var c=a[b];c.length;)k[b]="A",e&&(l[b]="A"),a.splice(b++,0,["C"][D](c.splice(0,6)));a.splice(b,1),p=N(d.length,e&&e.length||0)}},j=function(a,b,c,f,g){a&&b&&"M"==a[g][0]&&"M"!=b[g][0]&&(b.splice(g,0,["M",f.x,f.y]),c.bx=0,c.by=0,c.x=a[g][1],c.y=a[g][2],p=N(d.length,e&&e.length||0))},k=[],l=[],m="",n="",o=0,p=N(d.length,e&&e.length||0);p>o;o++){d[o]&&(m=d[o][0]),"C"!=m&&(k[o]=m,o&&(n=k[o-1])),d[o]=h(d[o],f,n),"A"!=k[o]&&"C"==m&&(k[o]="C"),i(d,o),e&&(e[o]&&(m=e[o][0]),"C"!=m&&(l[o]=m,o&&(n=l[o-1])),e[o]=h(e[o],g,n),"A"!=l[o]&&"C"==m&&(l[o]="C"),i(e,o)),j(d,e,f,g,o),j(e,d,g,f,o);var q=d[o],r=e&&e[o],s=q.length,t=e&&r.length;f.x=q[s-2],f.y=q[s-1],f.bx=$(q[s-4])||f.x,f.by=$(q[s-3])||f.y,g.bx=e&&($(r[t-4])||g.x),g.by=e&&($(r[t-3])||g.y),g.x=e&&r[t-2],g.y=e&&r[t-1]}return e||(c.curve=Aa(d)),e?[d,e]:d},null,Aa),Ja=(b._parseDots=e(function(a){for(var c=[],d=0,e=a.length;e>d;d++){var f={},g=a[d].match(/^([^:]*):?([\d\.]*)/);if(f.color=b.getRGB(g[1]),f.color.error)return null;f.opacity=f.color.opacity,f.color=f.color.hex,g[2]&&(f.offset=g[2]+"%"),c.push(f)}for(d=1,e=c.length-1;e>d;d++)if(!c[d].offset){for(var h=$(c[d-1].offset||0),i=0,j=d+1;e>j;j++)if(c[j].offset){i=c[j].offset;break}i||(i=100,j=e),i=$(i);for(var k=(i-h)/(j-d+1);j>d;d++)h+=k,c[d].offset=h+"%"}return c}),b._tear=function(a,b){a==b.top&&(b.top=a.prev),a==b.bottom&&(b.bottom=a.next),a.next&&(a.next.prev=a.prev),a.prev&&(a.prev.next=a.next)}),Ka=(b._tofront=function(a,b){b.top!==a&&(Ja(a,b),a.next=null,a.prev=b.top,b.top.next=a,b.top=a)},b._toback=function(a,b){b.bottom!==a&&(Ja(a,b),a.next=b.bottom,a.prev=null,b.bottom.prev=a,b.bottom=a)},b._insertafter=function(a,b,c){Ja(a,c),b==c.top&&(c.top=a),b.next&&(b.next.prev=a),a.next=b.next,a.prev=b,b.next=a},b._insertbefore=function(a,b,c){Ja(a,c),b==c.bottom&&(c.bottom=a),b.prev&&(b.prev.next=a),a.prev=b.prev,b.prev=a,a.next=b},b.toMatrix=function(a,b){var c=za(a),d={_:{transform:F},getBBox:function(){return c}};return La(d,b),d.matrix}),La=(b.transformPath=function(a,b){return pa(a,Ka(a,b))},b._extractTransform=function(a,c){if(null==c)return a._.transform;c=H(c).replace(/\.{3}|\u2026/g,a._.transform||F);var d=b.parseTransformString(c),e=0,f=0,g=0,h=1,i=1,j=a._,k=new n;if(j.transform=d||[],d)for(var l=0,m=d.length;m>l;l++){var o,p,q,r,s,t=d[l],u=t.length,v=H(t[0]).toLowerCase(),w=t[0]!=v,x=w?k.invert():0;"t"==v&&3==u?w?(o=x.x(0,0),p=x.y(0,0),q=x.x(t[1],t[2]),r=x.y(t[1],t[2]),k.translate(q-o,r-p)):k.translate(t[1],t[2]):"r"==v?2==u?(s=s||a.getBBox(1),k.rotate(t[1],s.x+s.width/2,s.y+s.height/2),e+=t[1]):4==u&&(w?(q=x.x(t[2],t[3]),r=x.y(t[2],t[3]),k.rotate(t[1],q,r)):k.rotate(t[1],t[2],t[3]),e+=t[1]):"s"==v?2==u||3==u?(s=s||a.getBBox(1),k.scale(t[1],t[u-1],s.x+s.width/2,s.y+s.height/2),h*=t[1],i*=t[u-1]):5==u&&(w?(q=x.x(t[3],t[4]),r=x.y(t[3],t[4]),k.scale(t[1],t[2],q,r)):k.scale(t[1],t[2],t[3],t[4]),h*=t[1],i*=t[2]):"m"==v&&7==u&&k.add(t[1],t[2],t[3],t[4],t[5],t[6]),j.dirtyT=1,a.matrix=k}a.matrix=k,j.sx=h,j.sy=i,j.deg=e,j.dx=f=k.e,j.dy=g=k.f,1==h&&1==i&&!e&&j.bbox?(j.bbox.x+=+f,j.bbox.y+=+g):j.dirtyT=1}),Ma=function(a){var b=a[0];switch(b.toLowerCase()){case"t":return[b,0,0];case"m":return[b,1,0,0,1,0,0];case"r":return 4==a.length?[b,0,a[2],a[3]]:[b,0];case"s":return 5==a.length?[b,1,1,a[3],a[4]]:3==a.length?[b,1,1]:[b,1]}},Na=b._equaliseTransform=function(a,c){ +c=H(c).replace(/\.{3}|\u2026/g,a),a=b.parseTransformString(a)||[],c=b.parseTransformString(c)||[];for(var d,e,f,g,h=N(a.length,c.length),i=[],j=[],k=0;h>k;k++){if(f=a[k]||Ma(c[k]),g=c[k]||Ma(f),f[0]!=g[0]||"r"==f[0].toLowerCase()&&(f[2]!=g[2]||f[3]!=g[3])||"s"==f[0].toLowerCase()&&(f[3]!=g[3]||f[4]!=g[4]))return;for(i[k]=[],j[k]=[],d=0,e=N(f.length,g.length);e>d;d++)d in f&&(i[k][d]=f[d]),d in g&&(j[k][d]=g[d])}return{from:i,to:j}};b._getContainer=function(a,c,d,e){var f;return f=null!=e||b.is(a,"object")?a:z.doc.getElementById(a),null!=f?f.tagName?null==c?{container:f,width:f.style.pixelWidth||f.offsetWidth,height:f.style.pixelHeight||f.offsetHeight}:{container:f,width:c,height:d}:{container:1,x:a,y:c,width:d,height:e}:void 0},b.pathToRelative=Ba,b._engine={},b.path2curve=Ia,b.matrix=function(a,b,c,d,e,f){return new n(a,b,c,d,e,f)},function(a){function c(a){return a[0]*a[0]+a[1]*a[1]}function d(a){var b=M.sqrt(c(a));a[0]&&(a[0]/=b),a[1]&&(a[1]/=b)}a.add=function(a,b,c,d,e,f){var g,h,i,j,k=[[],[],[]],l=[[this.a,this.c,this.e],[this.b,this.d,this.f],[0,0,1]],m=[[a,c,e],[b,d,f],[0,0,1]];for(a&&a instanceof n&&(m=[[a.a,a.c,a.e],[a.b,a.d,a.f],[0,0,1]]),g=0;3>g;g++)for(h=0;3>h;h++){for(j=0,i=0;3>i;i++)j+=l[g][i]*m[i][h];k[g][h]=j}this.a=k[0][0],this.b=k[1][0],this.c=k[0][1],this.d=k[1][1],this.e=k[0][2],this.f=k[1][2]},a.invert=function(){var a=this,b=a.a*a.d-a.b*a.c;return new n(a.d/b,-a.b/b,-a.c/b,a.a/b,(a.c*a.f-a.d*a.e)/b,(a.b*a.e-a.a*a.f)/b)},a.clone=function(){return new n(this.a,this.b,this.c,this.d,this.e,this.f)},a.translate=function(a,b){this.add(1,0,0,1,a,b)},a.scale=function(a,b,c,d){null==b&&(b=a),(c||d)&&this.add(1,0,0,1,c,d),this.add(a,0,0,b,0,0),(c||d)&&this.add(1,0,0,1,-c,-d)},a.rotate=function(a,c,d){a=b.rad(a),c=c||0,d=d||0;var e=+M.cos(a).toFixed(9),f=+M.sin(a).toFixed(9);this.add(e,f,-f,e,c,d),this.add(1,0,0,1,-c,-d)},a.x=function(a,b){return a*this.a+b*this.c+this.e},a.y=function(a,b){return a*this.b+b*this.d+this.f},a.get=function(a){return+this[H.fromCharCode(97+a)].toFixed(4)},a.toString=function(){return b.svg?"matrix("+[this.get(0),this.get(1),this.get(2),this.get(3),this.get(4),this.get(5)].join()+")":[this.get(0),this.get(2),this.get(1),this.get(3),0,0].join()},a.toFilter=function(){return"progid:DXImageTransform.Microsoft.Matrix(M11="+this.get(0)+", M12="+this.get(2)+", M21="+this.get(1)+", M22="+this.get(3)+", Dx="+this.get(4)+", Dy="+this.get(5)+", sizingmethod='auto expand')"},a.offset=function(){return[this.e.toFixed(4),this.f.toFixed(4)]},a.split=function(){var a={};a.dx=this.e,a.dy=this.f;var e=[[this.a,this.c],[this.b,this.d]];a.scalex=M.sqrt(c(e[0])),d(e[0]),a.shear=e[0][0]*e[1][0]+e[0][1]*e[1][1],e[1]=[e[1][0]-e[0][0]*a.shear,e[1][1]-e[0][1]*a.shear],a.scaley=M.sqrt(c(e[1])),d(e[1]),a.shear/=a.scaley;var f=-e[0][1],g=e[1][1];return 0>g?(a.rotate=b.deg(M.acos(g)),0>f&&(a.rotate=360-a.rotate)):a.rotate=b.deg(M.asin(f)),a.isSimple=!(+a.shear.toFixed(9)||a.scalex.toFixed(9)!=a.scaley.toFixed(9)&&a.rotate),a.isSuperSimple=!+a.shear.toFixed(9)&&a.scalex.toFixed(9)==a.scaley.toFixed(9)&&!a.rotate,a.noRotation=!+a.shear.toFixed(9)&&!a.rotate,a},a.toTransformString=function(a){var b=a||this[I]();return b.isSimple?(b.scalex=+b.scalex.toFixed(4),b.scaley=+b.scaley.toFixed(4),b.rotate=+b.rotate.toFixed(4),(b.dx||b.dy?"t"+[b.dx,b.dy]:F)+(1!=b.scalex||1!=b.scaley?"s"+[b.scalex,b.scaley,0,0]:F)+(b.rotate?"r"+[b.rotate,0,0]:F)):"m"+[this.get(0),this.get(1),this.get(2),this.get(3),this.get(4),this.get(5)]}}(n.prototype);for(var Oa=function(){this.returnValue=!1},Pa=function(){return this.originalEvent.preventDefault()},Qa=function(){this.cancelBubble=!0},Ra=function(){return this.originalEvent.stopPropagation()},Sa=function(a){var b=z.doc.documentElement.scrollTop||z.doc.body.scrollTop,c=z.doc.documentElement.scrollLeft||z.doc.body.scrollLeft;return{x:a.clientX+c,y:a.clientY+b}},Ta=function(){return z.doc.addEventListener?function(a,b,c,d){var e=function(a){var b=Sa(a);return c.call(d,a,b.x,b.y)};if(a.addEventListener(b,e,!1),E&&K[b]){var f=function(b){for(var e=Sa(b),f=b,g=0,h=b.targetTouches&&b.targetTouches.length;h>g;g++)if(b.targetTouches[g].target==a){b=b.targetTouches[g],b.originalEvent=f,b.preventDefault=Pa,b.stopPropagation=Ra;break}return c.call(d,b,e.x,e.y)};a.addEventListener(K[b],f,!1)}return function(){return a.removeEventListener(b,e,!1),E&&K[b]&&a.removeEventListener(K[b],f,!1),!0}}:z.doc.attachEvent?function(a,b,c,d){var e=function(a){a=a||z.win.event;var b=z.doc.documentElement.scrollTop||z.doc.body.scrollTop,e=z.doc.documentElement.scrollLeft||z.doc.body.scrollLeft,f=a.clientX+e,g=a.clientY+b;return a.preventDefault=a.preventDefault||Oa,a.stopPropagation=a.stopPropagation||Qa,c.call(d,a,f,g)};a.attachEvent("on"+b,e);var f=function(){return a.detachEvent("on"+b,e),!0};return f}:void 0}(),Ua=[],Va=function(b){for(var c,d=b.clientX,e=b.clientY,f=z.doc.documentElement.scrollTop||z.doc.body.scrollTop,g=z.doc.documentElement.scrollLeft||z.doc.body.scrollLeft,h=Ua.length;h--;){if(c=Ua[h],E&&b.touches){for(var i,j=b.touches.length;j--;)if(i=b.touches[j],i.identifier==c.el._drag.id){d=i.clientX,e=i.clientY,(b.originalEvent?b.originalEvent:b).preventDefault();break}}else b.preventDefault();var k,l=c.el.node,m=l.nextSibling,n=l.parentNode,o=l.style.display;z.win.opera&&n.removeChild(l),l.style.display="none",k=c.el.paper.getElementByPoint(d,e),l.style.display=o,z.win.opera&&(m?n.insertBefore(l,m):n.appendChild(l)),k&&a("raphael.drag.over."+c.el.id,c.el,k),d+=g,e+=f,a("raphael.drag.move."+c.el.id,c.move_scope||c.el,d-c.el._drag.x,e-c.el._drag.y,d,e,b)}},Wa=function(c){b.unmousemove(Va).unmouseup(Wa);for(var d,e=Ua.length;e--;)d=Ua[e],d.el._drag={},a("raphael.drag.end."+d.el.id,d.end_scope||d.start_scope||d.move_scope||d.el,c);Ua=[]},Xa=b.el={},Ya=J.length;Ya--;)!function(a){b[a]=Xa[a]=function(c,d){return b.is(c,"function")&&(this.events=this.events||[],this.events.push({name:a,f:c,unbind:Ta(this.shape||this.node||z.doc,a,c,d||this)})),this},b["un"+a]=Xa["un"+a]=function(c){for(var d=this.events||[],e=d.length;e--;)d[e].name!=a||!b.is(c,"undefined")&&d[e].f!=c||(d[e].unbind(),d.splice(e,1),!d.length&&delete this.events);return this}}(J[Ya]);Xa.data=function(c,d){var e=ja[this.id]=ja[this.id]||{};if(0==arguments.length)return e;if(1==arguments.length){if(b.is(c,"object")){for(var f in c)c[y](f)&&this.data(f,c[f]);return this}return a("raphael.data.get."+this.id,this,e[c],c),e[c]}return e[c]=d,a("raphael.data.set."+this.id,this,d,c),this},Xa.removeData=function(a){return null==a?ja[this.id]={}:ja[this.id]&&delete ja[this.id][a],this},Xa.getData=function(){return c(ja[this.id]||{})},Xa.hover=function(a,b,c,d){return this.mouseover(a,c).mouseout(b,d||c)},Xa.unhover=function(a,b){return this.unmouseover(a).unmouseout(b)};var Za=[];Xa.drag=function(c,d,e,f,g,h){function i(i){(i.originalEvent||i).preventDefault();var j=i.clientX,k=i.clientY,l=z.doc.documentElement.scrollTop||z.doc.body.scrollTop,m=z.doc.documentElement.scrollLeft||z.doc.body.scrollLeft;if(this._drag.id=i.identifier,E&&i.touches)for(var n,o=i.touches.length;o--;)if(n=i.touches[o],this._drag.id=n.identifier,n.identifier==this._drag.id){j=n.clientX,k=n.clientY;break}this._drag.x=j+m,this._drag.y=k+l,!Ua.length&&b.mousemove(Va).mouseup(Wa),Ua.push({el:this,move_scope:f,start_scope:g,end_scope:h}),d&&a.on("raphael.drag.start."+this.id,d),c&&a.on("raphael.drag.move."+this.id,c),e&&a.on("raphael.drag.end."+this.id,e),a("raphael.drag.start."+this.id,g||f||this,i.clientX+m,i.clientY+l,i)}return this._drag={},Za.push({el:this,start:i}),this.mousedown(i),this},Xa.onDragOver=function(b){b?a.on("raphael.drag.over."+this.id,b):a.unbind("raphael.drag.over."+this.id)},Xa.undrag=function(){for(var c=Za.length;c--;)Za[c].el==this&&(this.unmousedown(Za[c].start),Za.splice(c,1),a.unbind("raphael.drag.*."+this.id));!Za.length&&b.unmousemove(Va).unmouseup(Wa),Ua=[]},u.circle=function(a,c,d){var e=b._engine.circle(this,a||0,c||0,d||0);return this.__set__&&this.__set__.push(e),e},u.rect=function(a,c,d,e,f){var g=b._engine.rect(this,a||0,c||0,d||0,e||0,f||0);return this.__set__&&this.__set__.push(g),g},u.ellipse=function(a,c,d,e){var f=b._engine.ellipse(this,a||0,c||0,d||0,e||0);return this.__set__&&this.__set__.push(f),f},u.path=function(a){a&&!b.is(a,T)&&!b.is(a[0],U)&&(a+=F);var c=b._engine.path(b.format[C](b,arguments),this);return this.__set__&&this.__set__.push(c),c},u.image=function(a,c,d,e,f){var g=b._engine.image(this,a||"about:blank",c||0,d||0,e||0,f||0);return this.__set__&&this.__set__.push(g),g},u.text=function(a,c,d){var e=b._engine.text(this,a||0,c||0,H(d));return this.__set__&&this.__set__.push(e),e},u.set=function(a){!b.is(a,"array")&&(a=Array.prototype.splice.call(arguments,0,arguments.length));var c=new jb(a);return this.__set__&&this.__set__.push(c),c.paper=this,c.type="set",c},u.setStart=function(a){this.__set__=a||this.set()},u.setFinish=function(a){var b=this.__set__;return delete this.__set__,b},u.getSize=function(){var a=this.canvas.parentNode;return{width:a.offsetWidth,height:a.offsetHeight}},u.setSize=function(a,c){return b._engine.setSize.call(this,a,c)},u.setViewBox=function(a,c,d,e,f){return b._engine.setViewBox.call(this,a,c,d,e,f)},u.top=u.bottom=null,u.raphael=b;var $a=function(a){var b=a.getBoundingClientRect(),c=a.ownerDocument,d=c.body,e=c.documentElement,f=e.clientTop||d.clientTop||0,g=e.clientLeft||d.clientLeft||0,h=b.top+(z.win.pageYOffset||e.scrollTop||d.scrollTop)-f,i=b.left+(z.win.pageXOffset||e.scrollLeft||d.scrollLeft)-g;return{y:h,x:i}};u.getElementByPoint=function(a,b){var c=this,d=c.canvas,e=z.doc.elementFromPoint(a,b);if(z.win.opera&&"svg"==e.tagName){var f=$a(d),g=d.createSVGRect();g.x=a-f.x,g.y=b-f.y,g.width=g.height=1;var h=d.getIntersectionList(g,null);h.length&&(e=h[h.length-1])}if(!e)return null;for(;e.parentNode&&e!=d.parentNode&&!e.raphael;)e=e.parentNode;return e==c.canvas.parentNode&&(e=d),e=e&&e.raphael?c.getById(e.raphaelid):null},u.getElementsByBBox=function(a){var c=this.set();return this.forEach(function(d){b.isBBoxIntersect(d.getBBox(),a)&&c.push(d)}),c},u.getById=function(a){for(var b=this.bottom;b;){if(b.id==a)return b;b=b.next}return null},u.forEach=function(a,b){for(var c=this.bottom;c;){if(a.call(b,c)===!1)return this;c=c.next}return this},u.getElementsByPoint=function(a,b){var c=this.set();return this.forEach(function(d){d.isPointInside(a,b)&&c.push(d)}),c},Xa.isPointInside=function(a,c){var d=this.realPath=oa[this.type](this);return this.attr("transform")&&this.attr("transform").length&&(d=b.transformPath(d,this.attr("transform"))),b.isPointInsidePath(d,a,c)},Xa.getBBox=function(a){if(this.removed)return{};var b=this._;return a?((b.dirty||!b.bboxwt)&&(this.realPath=oa[this.type](this),b.bboxwt=za(this.realPath),b.bboxwt.toString=o,b.dirty=0),b.bboxwt):((b.dirty||b.dirtyT||!b.bbox)&&((b.dirty||!this.realPath)&&(b.bboxwt=0,this.realPath=oa[this.type](this)),b.bbox=za(pa(this.realPath,this.matrix)),b.bbox.toString=o,b.dirty=b.dirtyT=0),b.bbox)},Xa.clone=function(){if(this.removed)return null;var a=this.paper[this.type]().attr(this.attr());return this.__set__&&this.__set__.push(a),a},Xa.glow=function(a){if("text"==this.type)return null;a=a||{};var b={width:(a.width||10)+(+this.attr("stroke-width")||1),fill:a.fill||!1,opacity:null==a.opacity?.5:a.opacity,offsetx:a.offsetx||0,offsety:a.offsety||0,color:a.color||"#000"},c=b.width/2,d=this.paper,e=d.set(),f=this.realPath||oa[this.type](this);f=this.matrix?pa(f,this.matrix):f;for(var g=1;c+1>g;g++)e.push(d.path(f).attr({stroke:b.color,fill:b.fill?b.color:"none","stroke-linejoin":"round","stroke-linecap":"round","stroke-width":+(b.width/c*g).toFixed(3),opacity:+(b.opacity/c).toFixed(3)}));return e.insertBefore(this).translate(b.offsetx,b.offsety)};var _a=function(a,c,d,e,f,g,h,k,l){return null==l?i(a,c,d,e,f,g,h,k):b.findDotsAtSegment(a,c,d,e,f,g,h,k,j(a,c,d,e,f,g,h,k,l))},ab=function(a,c){return function(d,e,f){d=Ia(d);for(var g,h,i,j,k,l="",m={},n=0,o=0,p=d.length;p>o;o++){if(i=d[o],"M"==i[0])g=+i[1],h=+i[2];else{if(j=_a(g,h,i[1],i[2],i[3],i[4],i[5],i[6]),n+j>e){if(c&&!m.start){if(k=_a(g,h,i[1],i[2],i[3],i[4],i[5],i[6],e-n),l+=["C"+k.start.x,k.start.y,k.m.x,k.m.y,k.x,k.y],f)return l;m.start=l,l=["M"+k.x,k.y+"C"+k.n.x,k.n.y,k.end.x,k.end.y,i[5],i[6]].join(),n+=j,g=+i[5],h=+i[6];continue}if(!a&&!c)return k=_a(g,h,i[1],i[2],i[3],i[4],i[5],i[6],e-n),{x:k.x,y:k.y,alpha:k.alpha}}n+=j,g=+i[5],h=+i[6]}l+=i.shift()+i}return m.end=l,k=a?n:c?m:b.findDotsAtSegment(g,h,i[0],i[1],i[2],i[3],i[4],i[5],1),k.alpha&&(k={x:k.x,y:k.y,alpha:k.alpha}),k}},bb=ab(1),cb=ab(),db=ab(0,1);b.getTotalLength=bb,b.getPointAtLength=cb,b.getSubpath=function(a,b,c){if(this.getTotalLength(a)-c<1e-6)return db(a,b).end;var d=db(a,c,1);return b?db(d,b).end:d},Xa.getTotalLength=function(){var a=this.getPath();if(a)return this.node.getTotalLength?this.node.getTotalLength():bb(a)},Xa.getPointAtLength=function(a){var b=this.getPath();if(b)return cb(b,a)},Xa.getPath=function(){var a,c=b._getPath[this.type];if("text"!=this.type&&"set"!=this.type)return c&&(a=c(this)),a},Xa.getSubpath=function(a,c){var d=this.getPath();if(d)return b.getSubpath(d,a,c)};var eb=b.easing_formulas={linear:function(a){return a},"<":function(a){return Q(a,1.7)},">":function(a){return Q(a,.48)},"<>":function(a){var b=.48-a/1.04,c=M.sqrt(.1734+b*b),d=c-b,e=Q(P(d),1/3)*(0>d?-1:1),f=-c-b,g=Q(P(f),1/3)*(0>f?-1:1),h=e+g+.5;return 3*(1-h)*h*h+h*h*h},backIn:function(a){var b=1.70158;return a*a*((b+1)*a-b)},backOut:function(a){a-=1;var b=1.70158;return a*a*((b+1)*a+b)+1},elastic:function(a){return a==!!a?a:Q(2,-10*a)*M.sin(2*(a-.075)*R/.3)+1},bounce:function(a){var b,c=7.5625,d=2.75;return 1/d>a?b=c*a*a:2/d>a?(a-=1.5/d,b=c*a*a+.75):2.5/d>a?(a-=2.25/d,b=c*a*a+.9375):(a-=2.625/d,b=c*a*a+.984375),b}};eb.easeIn=eb["ease-in"]=eb["<"],eb.easeOut=eb["ease-out"]=eb[">"],eb.easeInOut=eb["ease-in-out"]=eb["<>"],eb["back-in"]=eb.backIn,eb["back-out"]=eb.backOut;var fb=[],gb=window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(a){setTimeout(a,16)},hb=function(){for(var c=+new Date,d=0;dh))if(i>h){var q=j(h/i);for(var s in k)if(k[y](s)){switch(ca[s]){case S:f=+k[s]+q*i*l[s];break;case"colour":f="rgb("+[ib(Z(k[s].r+q*i*l[s].r)),ib(Z(k[s].g+q*i*l[s].g)),ib(Z(k[s].b+q*i*l[s].b))].join(",")+")";break;case"path":f=[];for(var t=0,u=k[s].length;u>t;t++){f[t]=[k[s][t][0]];for(var v=1,w=k[s][t].length;w>v;v++)f[t][v]=+k[s][t][v]+q*i*l[s][t][v];f[t]=f[t].join(G)}f=f.join(G);break;case"transform":if(l[s].real)for(f=[],t=0,u=k[s].length;u>t;t++)for(f[t]=[k[s][t][0]],v=1,w=k[s][t].length;w>v;v++)f[t][v]=k[s][t][v]+q*i*l[s][t][v];else{var x=function(a){return+k[s][a]+q*i*l[s][a]};f=[["m",x(0),x(1),x(2),x(3),x(4),x(5)]]}break;case"csv":if("clip-rect"==s)for(f=[],t=4;t--;)f[t]=+k[s][t]+q*i*l[s][t];break;default:var z=[][D](k[s]);for(f=[],t=n.paper.customAttributes[s].length;t--;)f[t]=+z[t]+q*i*l[s][t]}o[s]=f}n.attr(o),function(b,c,d){setTimeout(function(){a("raphael.anim.frame."+b,c,d)})}(n.id,n,e.anim)}else{if(function(c,d,e){setTimeout(function(){a("raphael.anim.frame."+d.id,d,e),a("raphael.anim.finish."+d.id,d,e),b.is(c,"function")&&c.call(d)})}(e.callback,n,e.anim),n.attr(m),fb.splice(d--,1),e.repeat>1&&!e.next){for(g in m)m[y](g)&&(p[g]=e.totalOrigin[g]);e.el.attr(p),r(e.anim,e.el,e.anim.percents[0],null,e.totalOrigin,e.repeat-1)}e.next&&!e.stop&&r(e.anim,e.el,e.next,null,e.totalOrigin,e.repeat)}}}fb.length&&gb(hb)},ib=function(a){return a>255?255:0>a?0:a};Xa.animateWith=function(a,c,d,e,f,g){var h=this;if(h.removed)return g&&g.call(h),h;var i=d instanceof q?d:b.animation(d,e,f,g);r(i,h,i.percents[0],null,h.attr());for(var j=0,k=fb.length;k>j;j++)if(fb[j].anim==c&&fb[j].el==a){fb[k-1].start=fb[j].start;break}return h},Xa.onAnimation=function(b){return b?a.on("raphael.anim.frame."+this.id,b):a.unbind("raphael.anim.frame."+this.id),this},q.prototype.delay=function(a){var b=new q(this.anim,this.ms);return b.times=this.times,b.del=+a||0,b},q.prototype.repeat=function(a){var b=new q(this.anim,this.ms);return b.del=this.del,b.times=M.floor(N(a,0))||1,b},b.animation=function(a,c,d,e){if(a instanceof q)return a;(b.is(d,"function")||!d)&&(e=e||d||null,d=null),a=Object(a),c=+c||0;var f,g,h={};for(g in a)a[y](g)&&$(g)!=g&&$(g)+"%"!=g&&(f=!0,h[g]=a[g]);if(f)return d&&(h.easing=d),e&&(h.callback=e),new q({100:h},c);if(e){var i=0;for(var j in a){var k=_(j);a[y](j)&&k>i&&(i=k)}i+="%",!a[i].callback&&(a[i].callback=e)}return new q(a,c)},Xa.animate=function(a,c,d,e){var f=this;if(f.removed)return e&&e.call(f),f;var g=a instanceof q?a:b.animation(a,c,d,e);return r(g,f,g.percents[0],null,f.attr()),f},Xa.setTime=function(a,b){return a&&null!=b&&this.status(a,O(b,a.ms)/a.ms),this},Xa.status=function(a,b){var c,d,e=[],f=0;if(null!=b)return r(a,this,-1,O(b,1)),this;for(c=fb.length;c>f;f++)if(d=fb[f],d.el.id==this.id&&(!a||d.anim==a)){if(a)return d.status;e.push({anim:d.anim,status:d.status})}return a?0:e},Xa.pause=function(b){for(var c=0;cb;b++)!a[b]||a[b].constructor!=Xa.constructor&&a[b].constructor!=jb||(this[this.items.length]=this.items[this.items.length]=a[b],this.length++)},kb=jb.prototype;kb.push=function(){for(var a,b,c=0,d=arguments.length;d>c;c++)a=arguments[c],!a||a.constructor!=Xa.constructor&&a.constructor!=jb||(b=this.items.length,this[b]=this.items[b]=a,this.length++);return this},kb.pop=function(){return this.length&&delete this[this.length--],this.items.pop()},kb.forEach=function(a,b){for(var c=0,d=this.items.length;d>c;c++)if(a.call(b,this.items[c],c)===!1)return this;return this};for(var lb in Xa)Xa[y](lb)&&(kb[lb]=function(a){return function(){var b=arguments;return this.forEach(function(c){c[a][C](c,b)})}}(lb));return kb.attr=function(a,c){if(a&&b.is(a,U)&&b.is(a[0],"object"))for(var d=0,e=a.length;e>d;d++)this.items[d].attr(a[d]);else for(var f=0,g=this.items.length;g>f;f++)this.items[f].attr(a,c);return this},kb.clear=function(){for(;this.length;)this.pop()},kb.splice=function(a,b,c){a=0>a?N(this.length+a,0):a,b=N(0,O(this.length-a,b));var d,e=[],f=[],g=[];for(d=2;dd;d++)f.push(this[a+d]);for(;dd?g[d]:e[d-h];for(d=this.items.length=this.length-=b-h;this[d];)delete this[d++];return new jb(f)},kb.exclude=function(a){for(var b=0,c=this.length;c>b;b++)if(this[b]==a)return this.splice(b,1),!0},kb.animate=function(a,c,d,e){(b.is(d,"function")||!d)&&(e=d||null);var f,g,h=this.items.length,i=h,j=this;if(!h)return this;e&&(g=function(){!--h&&e.call(j)}),d=b.is(d,T)?d:g;var k=b.animation(a,c,d,g);for(f=this.items[--i].animate(k);i--;)this.items[i]&&!this.items[i].removed&&this.items[i].animateWith(f,k,k),this.items[i]&&!this.items[i].removed||h--;return this},kb.insertAfter=function(a){for(var b=this.items.length;b--;)this.items[b].insertAfter(a);return this},kb.getBBox=function(){for(var a=[],b=[],c=[],d=[],e=this.items.length;e--;)if(!this.items[e].removed){var f=this.items[e].getBBox();a.push(f.x),b.push(f.y),c.push(f.x+f.width),d.push(f.y+f.height)}return a=O[C](0,a),b=O[C](0,b),c=N[C](0,c),d=N[C](0,d),{x:a,y:b,x2:c,y2:d,width:c-a,height:d-b}},kb.clone=function(a){a=this.paper.set();for(var b=0,c=this.items.length;c>b;b++)a.push(this.items[b].clone());return a},kb.toString=function(){return"Raphaël‘s set"},kb.glow=function(a){var b=this.paper.set();return this.forEach(function(c,d){var e=c.glow(a);null!=e&&e.forEach(function(a,c){b.push(a)})}),b},kb.isPointInside=function(a,b){var c=!1;return this.forEach(function(d){return d.isPointInside(a,b)?(c=!0,!1):void 0}),c},b.registerFont=function(a){if(!a.face)return a;this.fonts=this.fonts||{};var b={w:a.w,face:{},glyphs:{}},c=a.face["font-family"];for(var d in a.face)a.face[y](d)&&(b.face[d]=a.face[d]);if(this.fonts[c]?this.fonts[c].push(b):this.fonts[c]=[b],!a.svg){b.face["units-per-em"]=_(a.face["units-per-em"],10);for(var e in a.glyphs)if(a.glyphs[y](e)){var f=a.glyphs[e];if(b.glyphs[e]={w:f.w,k:{},d:f.d&&"M"+f.d.replace(/[mlcxtrv]/g,function(a){return{l:"L",c:"C",x:"z",t:"m",r:"l",v:"c"}[a]||"M"})+"z"},f.k)for(var g in f.k)f[y](g)&&(b.glyphs[e].k[g]=f.k[g])}}return a},u.getFont=function(a,c,d,e){if(e=e||"normal",d=d||"normal",c=+c||{normal:400,bold:700,lighter:300,bolder:800}[c]||400,b.fonts){var f=b.fonts[a];if(!f){var g=new RegExp("(^|\\s)"+a.replace(/[^\w\d\s+!~.:_-]/g,F)+"(\\s|$)","i");for(var h in b.fonts)if(b.fonts[y](h)&&g.test(h)){f=b.fonts[h];break}}var i;if(f)for(var j=0,k=f.length;k>j&&(i=f[j],i.face["font-weight"]!=c||i.face["font-style"]!=d&&i.face["font-style"]||i.face["font-stretch"]!=e);j++);return i}},u.print=function(a,c,d,e,f,g,h,i){g=g||"middle",h=N(O(h||0,1),-1),i=N(O(i||1,3),1);var j,k=H(d)[I](F),l=0,m=0,n=F;if(b.is(e,"string")&&(e=this.getFont(e)),e){j=(f||16)/e.face["units-per-em"];for(var o=e.face.bbox[I](v),p=+o[0],q=o[3]-o[1],r=0,s=+o[1]+("baseline"==g?q+ +e.face.descent:q/2),t=0,u=k.length;u>t;t++){if("\n"==k[t])l=0,x=0,m=0,r+=q*i;else{var w=m&&e.glyphs[k[t-1]]||{},x=e.glyphs[k[t]];l+=m?(w.w||e.w)+(w.k&&w.k[k[t]]||0)+e.w*h:0,m=1}x&&x.d&&(n+=b.transformPath(x.d,["t",l*j,r*j,"s",j,j,p,s,"t",(a-p)/j,(c-s)/j]))}}return this.path(n).attr({fill:"#000",stroke:"none"})},u.add=function(a){if(b.is(a,"array"))for(var c,d=this.set(),e=0,f=a.length;f>e;e++)c=a[e]||{},w[y](c.type)&&d.push(this[c.type]().attr(c));return d},b.format=function(a,c){var d=b.is(c,U)?[0][D](c):arguments;return a&&b.is(a,T)&&d.length-1&&(a=a.replace(x,function(a,b){return null==d[++b]?F:d[b]})),a||F},b.fullfill=function(){var a=/\{([^\}]+)\}/g,b=/(?:(?:^|\.)(.+?)(?=\[|\.|$|\()|\[('|")(.+?)\2\])(\(\))?/g,c=function(a,c,d){var e=d;return c.replace(b,function(a,b,c,d,f){b=b||d,e&&(b in e&&(e=e[b]),"function"==typeof e&&f&&(e=e()))}),e=(null==e||e==d?a:e)+""};return function(b,d){return String(b).replace(a,function(a,b){return c(a,b,d)})}}(),b.ninja=function(){return A.was?z.win.Raphael=A.is:delete Raphael,b},b.st=kb,a.on("raphael.DOMload",function(){t=!0}),function(a,c,d){function e(){/in/.test(a.readyState)?setTimeout(e,9):b.eve("raphael.DOMload")}null==a.readyState&&a.addEventListener&&(a.addEventListener(c,d=function(){a.removeEventListener(c,d,!1),a.readyState="complete"},!1),a.readyState="loading"),e()}(document,"DOMContentLoaded"),b}),function(a,b){"function"==typeof define&&define.amd?define("raphael.svg",["raphael.core"],function(a){return b(a)}):b("object"==typeof exports?require("./raphael.core"):a.Raphael)}(this,function(a){if(!a||a.svg){var b="hasOwnProperty",c=String,d=parseFloat,e=parseInt,f=Math,g=f.max,h=f.abs,i=f.pow,j=/[, ]+/,k=a.eve,l="",m=" ",n="http://www.w3.org/1999/xlink",o={block:"M5,0 0,2.5 5,5z",classic:"M5,0 0,2.5 5,5 3.5,3 3.5,2z",diamond:"M2.5,0 5,2.5 2.5,5 0,2.5z",open:"M6,1 1,3.5 6,6",oval:"M2.5,0A2.5,2.5,0,0,1,2.5,5 2.5,2.5,0,0,1,2.5,0z"},p={};a.toString=function(){return"Your browser supports SVG.\nYou are running Raphaël "+this.version};var q=function(d,e){if(e){"string"==typeof d&&(d=q(d));for(var f in e)e[b](f)&&("xlink:"==f.substring(0,6)?d.setAttributeNS(n,f.substring(6),c(e[f])):d.setAttribute(f,c(e[f])))}else d=a._g.doc.createElementNS("http://www.w3.org/2000/svg",d),d.style&&(d.style.webkitTapHighlightColor="rgba(0,0,0,0)");return d},r=function(b,e){var j="linear",k=b.id+e,m=.5,n=.5,o=b.node,p=b.paper,r=o.style,s=a._g.doc.getElementById(k);if(!s){if(e=c(e).replace(a._radial_gradient,function(a,b,c){if(j="radial",b&&c){m=d(b),n=d(c);var e=2*(n>.5)-1;i(m-.5,2)+i(n-.5,2)>.25&&(n=f.sqrt(.25-i(m-.5,2))*e+.5)&&.5!=n&&(n=n.toFixed(5)-1e-5*e)}return l}),e=e.split(/\s*\-\s*/),"linear"==j){var t=e.shift();if(t=-d(t),isNaN(t))return null;var u=[0,0,f.cos(a.rad(t)),f.sin(a.rad(t))],v=1/(g(h(u[2]),h(u[3]))||1);u[2]*=v,u[3]*=v,u[2]<0&&(u[0]=-u[2],u[2]=0),u[3]<0&&(u[1]=-u[3],u[3]=0)}var w=a._parseDots(e);if(!w)return null;if(k=k.replace(/[\(\)\s,\xb0#]/g,"_"),b.gradient&&k!=b.gradient.id&&(p.defs.removeChild(b.gradient),delete b.gradient),!b.gradient){s=q(j+"Gradient",{id:k}),b.gradient=s,q(s,"radial"==j?{fx:m,fy:n}:{x1:u[0],y1:u[1],x2:u[2],y2:u[3],gradientTransform:b.matrix.invert()}),p.defs.appendChild(s);for(var x=0,y=w.length;y>x;x++)s.appendChild(q("stop",{offset:w[x].offset?w[x].offset:x?"100%":"0%","stop-color":w[x].color||"#fff","stop-opacity":isFinite(w[x].opacity)?w[x].opacity:1}))}}return q(o,{fill:"url('"+document.location.origin+document.location.pathname+"#"+k+"')",opacity:1,"fill-opacity":1}),r.fill=l,r.opacity=1,r.fillOpacity=1,1},s=function(a){var b=a.getBBox(1);q(a.pattern,{patternTransform:a.matrix.invert()+" translate("+b.x+","+b.y+")"})},t=function(d,e,f){if("path"==d.type){for(var g,h,i,j,k,m=c(e).toLowerCase().split("-"),n=d.paper,r=f?"end":"start",s=d.node,t=d.attrs,u=t["stroke-width"],v=m.length,w="classic",x=3,y=3,z=5;v--;)switch(m[v]){case"block":case"classic":case"oval":case"diamond":case"open":case"none":w=m[v];break;case"wide":y=5;break;case"narrow":y=2;break;case"long":x=5;break;case"short":x=2}if("open"==w?(x+=2,y+=2,z+=2,i=1,j=f?4:1,k={fill:"none",stroke:t.stroke}):(j=i=x/2,k={fill:t.stroke,stroke:"none"}),d._.arrows?f?(d._.arrows.endPath&&p[d._.arrows.endPath]--,d._.arrows.endMarker&&p[d._.arrows.endMarker]--):(d._.arrows.startPath&&p[d._.arrows.startPath]--,d._.arrows.startMarker&&p[d._.arrows.startMarker]--):d._.arrows={},"none"!=w){var A="raphael-marker-"+w,B="raphael-marker-"+r+w+x+y+"-obj"+d.id;a._g.doc.getElementById(A)?p[A]++:(n.defs.appendChild(q(q("path"),{"stroke-linecap":"round",d:o[w],id:A})),p[A]=1);var C,D=a._g.doc.getElementById(B);D?(p[B]++,C=D.getElementsByTagName("use")[0]):(D=q(q("marker"),{id:B,markerHeight:y,markerWidth:x,orient:"auto",refX:j,refY:y/2}),C=q(q("use"),{"xlink:href":"#"+A,transform:(f?"rotate(180 "+x/2+" "+y/2+") ":l)+"scale("+x/z+","+y/z+")","stroke-width":(1/((x/z+y/z)/2)).toFixed(4)}),D.appendChild(C),n.defs.appendChild(D),p[B]=1),q(C,k);var E=i*("diamond"!=w&&"oval"!=w);f?(g=d._.arrows.startdx*u||0,h=a.getTotalLength(t.path)-E*u):(g=E*u,h=a.getTotalLength(t.path)-(d._.arrows.enddx*u||0)),k={},k["marker-"+r]="url(#"+B+")",(h||g)&&(k.d=a.getSubpath(t.path,g,h)),q(s,k),d._.arrows[r+"Path"]=A,d._.arrows[r+"Marker"]=B,d._.arrows[r+"dx"]=E,d._.arrows[r+"Type"]=w,d._.arrows[r+"String"]=e}else f?(g=d._.arrows.startdx*u||0,h=a.getTotalLength(t.path)-g):(g=0,h=a.getTotalLength(t.path)-(d._.arrows.enddx*u||0)),d._.arrows[r+"Path"]&&q(s,{d:a.getSubpath(t.path,g,h)}),delete d._.arrows[r+"Path"],delete d._.arrows[r+"Marker"],delete d._.arrows[r+"dx"],delete d._.arrows[r+"Type"],delete d._.arrows[r+"String"];for(k in p)if(p[b](k)&&!p[k]){var F=a._g.doc.getElementById(k);F&&F.parentNode.removeChild(F)}}},u={"-":[3,1],".":[1,1],"-.":[3,1,1,1],"-..":[3,1,1,1,1,1],". ":[1,3],"- ":[4,3],"--":[8,3],"- .":[4,3,1,3],"--.":[8,3,1,3],"--..":[8,3,1,3,1,3]},v=function(a,b,d){if(b=u[c(b).toLowerCase()]){for(var e=a.attrs["stroke-width"]||"1",f={round:e,square:e,butt:0}[a.attrs["stroke-linecap"]||d["stroke-linecap"]]||0,g=[],h=b.length;h--;)g[h]=b[h]*e+(h%2?1:-1)*f;q(a.node,{"stroke-dasharray":g.join(",")})}else q(a.node,{"stroke-dasharray":"none"})},w=function(d,f){var i=d.node,k=d.attrs,m=i.style.visibility;i.style.visibility="hidden";for(var o in f)if(f[b](o)){if(!a._availableAttrs[b](o))continue;var p=f[o];switch(k[o]=p,o){case"blur":d.blur(p);break;case"title":var u=i.getElementsByTagName("title");if(u.length&&(u=u[0]))u.firstChild.nodeValue=p;else{u=q("title");var w=a._g.doc.createTextNode(p);u.appendChild(w),i.appendChild(u)}break;case"href":case"target":var x=i.parentNode;if("a"!=x.tagName.toLowerCase()){var z=q("a");x.insertBefore(z,i),z.appendChild(i),x=z}"target"==o?x.setAttributeNS(n,"show","blank"==p?"new":p):x.setAttributeNS(n,o,p);break;case"cursor":i.style.cursor=p;break;case"transform":d.transform(p);break;case"arrow-start":t(d,p);break;case"arrow-end":t(d,p,1);break;case"clip-rect":var A=c(p).split(j);if(4==A.length){d.clip&&d.clip.parentNode.parentNode.removeChild(d.clip.parentNode);var B=q("clipPath"),C=q("rect");B.id=a.createUUID(),q(C,{x:A[0],y:A[1],width:A[2],height:A[3]}),B.appendChild(C),d.paper.defs.appendChild(B),q(i,{"clip-path":"url(#"+B.id+")"}),d.clip=C}if(!p){var D=i.getAttribute("clip-path");if(D){var E=a._g.doc.getElementById(D.replace(/(^url\(#|\)$)/g,l));E&&E.parentNode.removeChild(E),q(i,{"clip-path":l}),delete d.clip}}break;case"path":"path"==d.type&&(q(i,{d:p?k.path=a._pathToAbsolute(p):"M0,0"}),d._.dirty=1,d._.arrows&&("startString"in d._.arrows&&t(d,d._.arrows.startString),"endString"in d._.arrows&&t(d,d._.arrows.endString,1)));break;case"width":if(i.setAttribute(o,p),d._.dirty=1,!k.fx)break;o="x",p=k.x;case"x":k.fx&&(p=-k.x-(k.width||0));case"rx":if("rx"==o&&"rect"==d.type)break;case"cx":i.setAttribute(o,p),d.pattern&&s(d),d._.dirty=1;break;case"height":if(i.setAttribute(o,p),d._.dirty=1,!k.fy)break;o="y",p=k.y;case"y":k.fy&&(p=-k.y-(k.height||0));case"ry":if("ry"==o&&"rect"==d.type)break;case"cy":i.setAttribute(o,p),d.pattern&&s(d),d._.dirty=1;break;case"r":"rect"==d.type?q(i,{rx:p,ry:p}):i.setAttribute(o,p),d._.dirty=1;break;case"src":"image"==d.type&&i.setAttributeNS(n,"href",p);break;case"stroke-width":(1!=d._.sx||1!=d._.sy)&&(p/=g(h(d._.sx),h(d._.sy))||1),i.setAttribute(o,p),k["stroke-dasharray"]&&v(d,k["stroke-dasharray"],f),d._.arrows&&("startString"in d._.arrows&&t(d,d._.arrows.startString),"endString"in d._.arrows&&t(d,d._.arrows.endString,1));break;case"stroke-dasharray":v(d,p,f);break;case"fill":var F=c(p).match(a._ISURL);if(F){B=q("pattern");var G=q("image");B.id=a.createUUID(),q(B,{x:0,y:0,patternUnits:"userSpaceOnUse",height:1,width:1}),q(G,{x:0,y:0,"xlink:href":F[1]}),B.appendChild(G),function(b){a._preload(F[1],function(){var a=this.offsetWidth,c=this.offsetHeight;q(b,{width:a,height:c}),q(G,{width:a,height:c})})}(B),d.paper.defs.appendChild(B),q(i,{fill:"url(#"+B.id+")"}),d.pattern=B,d.pattern&&s(d);break}var H=a.getRGB(p);if(H.error){if(("circle"==d.type||"ellipse"==d.type||"r"!=c(p).charAt())&&r(d,p)){if("opacity"in k||"fill-opacity"in k){var I=a._g.doc.getElementById(i.getAttribute("fill").replace(/^url\(#|\)$/g,l));if(I){var J=I.getElementsByTagName("stop");q(J[J.length-1],{"stop-opacity":("opacity"in k?k.opacity:1)*("fill-opacity"in k?k["fill-opacity"]:1)})}}k.gradient=p,k.fill="none";break}}else delete f.gradient,delete k.gradient,!a.is(k.opacity,"undefined")&&a.is(f.opacity,"undefined")&&q(i,{opacity:k.opacity}),!a.is(k["fill-opacity"],"undefined")&&a.is(f["fill-opacity"],"undefined")&&q(i,{"fill-opacity":k["fill-opacity"]});H[b]("opacity")&&q(i,{"fill-opacity":H.opacity>1?H.opacity/100:H.opacity});case"stroke":H=a.getRGB(p),i.setAttribute(o,H.hex),"stroke"==o&&H[b]("opacity")&&q(i,{"stroke-opacity":H.opacity>1?H.opacity/100:H.opacity}),"stroke"==o&&d._.arrows&&("startString"in d._.arrows&&t(d,d._.arrows.startString),"endString"in d._.arrows&&t(d,d._.arrows.endString,1));break;case"gradient":("circle"==d.type||"ellipse"==d.type||"r"!=c(p).charAt())&&r(d,p); + +break;case"opacity":k.gradient&&!k[b]("stroke-opacity")&&q(i,{"stroke-opacity":p>1?p/100:p});case"fill-opacity":if(k.gradient){I=a._g.doc.getElementById(i.getAttribute("fill").replace(/^url\(#|\)$/g,l)),I&&(J=I.getElementsByTagName("stop"),q(J[J.length-1],{"stop-opacity":p}));break}default:"font-size"==o&&(p=e(p,10)+"px");var K=o.replace(/(\-.)/g,function(a){return a.substring(1).toUpperCase()});i.style[K]=p,d._.dirty=1,i.setAttribute(o,p)}}y(d,f),i.style.visibility=m},x=1.2,y=function(d,f){if("text"==d.type&&(f[b]("text")||f[b]("font")||f[b]("font-size")||f[b]("x")||f[b]("y"))){var g=d.attrs,h=d.node,i=h.firstChild?e(a._g.doc.defaultView.getComputedStyle(h.firstChild,l).getPropertyValue("font-size"),10):10;if(f[b]("text")){for(g.text=f.text;h.firstChild;)h.removeChild(h.firstChild);for(var j,k=c(f.text).split("\n"),m=[],n=0,o=k.length;o>n;n++)j=q("tspan"),n&&q(j,{dy:i*x,x:g.x}),j.appendChild(a._g.doc.createTextNode(k[n])),h.appendChild(j),m[n]=j}else for(m=h.getElementsByTagName("tspan"),n=0,o=m.length;o>n;n++)n?q(m[n],{dy:i*x,x:g.x}):q(m[0],{dy:0});q(h,{x:g.x,y:g.y}),d._.dirty=1;var p=d._getBBox(),r=g.y-(p.y+p.height/2);r&&a.is(r,"finite")&&q(m[0],{dy:r})}},z=function(a){return a.parentNode&&"a"===a.parentNode.tagName.toLowerCase()?a.parentNode:a},A=function(b,c){this[0]=this.node=b,b.raphael=!0,this.id=a._oid++,b.raphaelid=this.id,this.matrix=a.matrix(),this.realPath=null,this.paper=c,this.attrs=this.attrs||{},this._={transform:[],sx:1,sy:1,deg:0,dx:0,dy:0,dirty:1},!c.bottom&&(c.bottom=this),this.prev=c.top,c.top&&(c.top.next=this),c.top=this,this.next=null},B=a.el;A.prototype=B,B.constructor=A,a._engine.path=function(a,b){var c=q("path");b.canvas&&b.canvas.appendChild(c);var d=new A(c,b);return d.type="path",w(d,{fill:"none",stroke:"#000",path:a}),d},B.rotate=function(a,b,e){if(this.removed)return this;if(a=c(a).split(j),a.length-1&&(b=d(a[1]),e=d(a[2])),a=d(a[0]),null==e&&(b=e),null==b||null==e){var f=this.getBBox(1);b=f.x+f.width/2,e=f.y+f.height/2}return this.transform(this._.transform.concat([["r",a,b,e]])),this},B.scale=function(a,b,e,f){if(this.removed)return this;if(a=c(a).split(j),a.length-1&&(b=d(a[1]),e=d(a[2]),f=d(a[3])),a=d(a[0]),null==b&&(b=a),null==f&&(e=f),null==e||null==f)var g=this.getBBox(1);return e=null==e?g.x+g.width/2:e,f=null==f?g.y+g.height/2:f,this.transform(this._.transform.concat([["s",a,b,e,f]])),this},B.translate=function(a,b){return this.removed?this:(a=c(a).split(j),a.length-1&&(b=d(a[1])),a=d(a[0])||0,b=+b||0,this.transform(this._.transform.concat([["t",a,b]])),this)},B.transform=function(c){var d=this._;if(null==c)return d.transform;if(a._extractTransform(this,c),this.clip&&q(this.clip,{transform:this.matrix.invert()}),this.pattern&&s(this),this.node&&q(this.node,{transform:this.matrix}),1!=d.sx||1!=d.sy){var e=this.attrs[b]("stroke-width")?this.attrs["stroke-width"]:1;this.attr({"stroke-width":e})}return this},B.hide=function(){return this.removed||(this.node.style.display="none"),this},B.show=function(){return this.removed||(this.node.style.display=""),this},B.remove=function(){var b=z(this.node);if(!this.removed&&b.parentNode){var c=this.paper;c.__set__&&c.__set__.exclude(this),k.unbind("raphael.*.*."+this.id),this.gradient&&c.defs.removeChild(this.gradient),a._tear(this,c),b.parentNode.removeChild(b),this.removeData();for(var d in this)this[d]="function"==typeof this[d]?a._removedFactory(d):null;this.removed=!0}},B._getBBox=function(){if("none"==this.node.style.display){this.show();var a=!0}var b,c=!1;this.paper.canvas.parentElement?b=this.paper.canvas.parentElement.style:this.paper.canvas.parentNode&&(b=this.paper.canvas.parentNode.style),b&&"none"==b.display&&(c=!0,b.display="");var d={};try{d=this.node.getBBox()}catch(e){d={x:this.node.clientLeft,y:this.node.clientTop,width:this.node.clientWidth,height:this.node.clientHeight}}finally{d=d||{},c&&(b.display="none")}return a&&this.hide(),d},B.attr=function(c,d){if(this.removed)return this;if(null==c){var e={};for(var f in this.attrs)this.attrs[b](f)&&(e[f]=this.attrs[f]);return e.gradient&&"none"==e.fill&&(e.fill=e.gradient)&&delete e.gradient,e.transform=this._.transform,e}if(null==d&&a.is(c,"string")){if("fill"==c&&"none"==this.attrs.fill&&this.attrs.gradient)return this.attrs.gradient;if("transform"==c)return this._.transform;for(var g=c.split(j),h={},i=0,l=g.length;l>i;i++)c=g[i],c in this.attrs?h[c]=this.attrs[c]:a.is(this.paper.customAttributes[c],"function")?h[c]=this.paper.customAttributes[c].def:h[c]=a._availableAttrs[c];return l-1?h:h[g[0]]}if(null==d&&a.is(c,"array")){for(h={},i=0,l=c.length;l>i;i++)h[c[i]]=this.attr(c[i]);return h}if(null!=d){var m={};m[c]=d}else null!=c&&a.is(c,"object")&&(m=c);for(var n in m)k("raphael.attr."+n+"."+this.id,this,m[n]);for(n in this.paper.customAttributes)if(this.paper.customAttributes[b](n)&&m[b](n)&&a.is(this.paper.customAttributes[n],"function")){var o=this.paper.customAttributes[n].apply(this,[].concat(m[n]));this.attrs[n]=m[n];for(var p in o)o[b](p)&&(m[p]=o[p])}return w(this,m),this},B.toFront=function(){if(this.removed)return this;var b=z(this.node);b.parentNode.appendChild(b);var c=this.paper;return c.top!=this&&a._tofront(this,c),this},B.toBack=function(){if(this.removed)return this;var b=z(this.node),c=b.parentNode;c.insertBefore(b,c.firstChild),a._toback(this,this.paper);this.paper;return this},B.insertAfter=function(b){if(this.removed||!b)return this;var c=z(this.node),d=z(b.node||b[b.length-1].node);return d.nextSibling?d.parentNode.insertBefore(c,d.nextSibling):d.parentNode.appendChild(c),a._insertafter(this,b,this.paper),this},B.insertBefore=function(b){if(this.removed||!b)return this;var c=z(this.node),d=z(b.node||b[0].node);return d.parentNode.insertBefore(c,d),a._insertbefore(this,b,this.paper),this},B.blur=function(b){var c=this;if(0!==+b){var d=q("filter"),e=q("feGaussianBlur");c.attrs.blur=b,d.id=a.createUUID(),q(e,{stdDeviation:+b||1.5}),d.appendChild(e),c.paper.defs.appendChild(d),c._blur=d,q(c.node,{filter:"url(#"+d.id+")"})}else c._blur&&(c._blur.parentNode.removeChild(c._blur),delete c._blur,delete c.attrs.blur),c.node.removeAttribute("filter");return c},a._engine.circle=function(a,b,c,d){var e=q("circle");a.canvas&&a.canvas.appendChild(e);var f=new A(e,a);return f.attrs={cx:b,cy:c,r:d,fill:"none",stroke:"#000"},f.type="circle",q(e,f.attrs),f},a._engine.rect=function(a,b,c,d,e,f){var g=q("rect");a.canvas&&a.canvas.appendChild(g);var h=new A(g,a);return h.attrs={x:b,y:c,width:d,height:e,rx:f||0,ry:f||0,fill:"none",stroke:"#000"},h.type="rect",q(g,h.attrs),h},a._engine.ellipse=function(a,b,c,d,e){var f=q("ellipse");a.canvas&&a.canvas.appendChild(f);var g=new A(f,a);return g.attrs={cx:b,cy:c,rx:d,ry:e,fill:"none",stroke:"#000"},g.type="ellipse",q(f,g.attrs),g},a._engine.image=function(a,b,c,d,e,f){var g=q("image");q(g,{x:c,y:d,width:e,height:f,preserveAspectRatio:"none"}),g.setAttributeNS(n,"href",b),a.canvas&&a.canvas.appendChild(g);var h=new A(g,a);return h.attrs={x:c,y:d,width:e,height:f,src:b},h.type="image",h},a._engine.text=function(b,c,d,e){var f=q("text");b.canvas&&b.canvas.appendChild(f);var g=new A(f,b);return g.attrs={x:c,y:d,"text-anchor":"middle",text:e,"font-family":a._availableAttrs["font-family"],"font-size":a._availableAttrs["font-size"],stroke:"none",fill:"#000"},g.type="text",w(g,g.attrs),g},a._engine.setSize=function(a,b){return this.width=a||this.width,this.height=b||this.height,this.canvas.setAttribute("width",this.width),this.canvas.setAttribute("height",this.height),this._viewBox&&this.setViewBox.apply(this,this._viewBox),this},a._engine.create=function(){var b=a._getContainer.apply(0,arguments),c=b&&b.container,d=b.x,e=b.y,f=b.width,g=b.height;if(!c)throw new Error("SVG container not found.");var h,i=q("svg"),j="overflow:hidden;";return d=d||0,e=e||0,f=f||512,g=g||342,q(i,{height:g,version:1.1,width:f,xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink"}),1==c?(i.style.cssText=j+"position:absolute;left:"+d+"px;top:"+e+"px",a._g.doc.body.appendChild(i),h=1):(i.style.cssText=j+"position:relative",c.firstChild?c.insertBefore(i,c.firstChild):c.appendChild(i)),c=new a._Paper,c.width=f,c.height=g,c.canvas=i,c.clear(),c._left=c._top=0,h&&(c.renderfix=function(){}),c.renderfix(),c},a._engine.setViewBox=function(a,b,c,d,e){k("raphael.setViewBox",this,this._viewBox,[a,b,c,d,e]);var f,h,i=this.getSize(),j=g(c/i.width,d/i.height),l=this.top,n=e?"xMidYMid meet":"xMinYMin";for(null==a?(this._vbSize&&(j=1),delete this._vbSize,f="0 0 "+this.width+m+this.height):(this._vbSize=j,f=a+m+b+m+c+m+d),q(this.canvas,{viewBox:f,preserveAspectRatio:n});j&&l;)h="stroke-width"in l.attrs?l.attrs["stroke-width"]:1,l.attr({"stroke-width":h}),l._.dirty=1,l._.dirtyT=1,l=l.prev;return this._viewBox=[a,b,c,d,!!e],this},a.prototype.renderfix=function(){var a,b=this.canvas,c=b.style;try{a=b.getScreenCTM()||b.createSVGMatrix()}catch(d){a=b.createSVGMatrix()}var e=-a.e%1,f=-a.f%1;(e||f)&&(e&&(this._left=(this._left+e)%1,c.left=this._left+"px"),f&&(this._top=(this._top+f)%1,c.top=this._top+"px"))},a.prototype.clear=function(){a.eve("raphael.clear",this);for(var b=this.canvas;b.firstChild;)b.removeChild(b.firstChild);this.bottom=this.top=null,(this.desc=q("desc")).appendChild(a._g.doc.createTextNode("Created with Raphaël "+a.version)),b.appendChild(this.desc),b.appendChild(this.defs=q("defs"))},a.prototype.remove=function(){k("raphael.remove",this),this.canvas.parentNode&&this.canvas.parentNode.removeChild(this.canvas);for(var b in this)this[b]="function"==typeof this[b]?a._removedFactory(b):null};var C=a.st;for(var D in B)B[b](D)&&!C[b](D)&&(C[D]=function(a){return function(){var b=arguments;return this.forEach(function(c){c[a].apply(c,b)})}}(D))}}),function(a,b){"function"==typeof define&&define.amd?define("raphael.vml",["raphael.core"],function(a){return b(a)}):b("object"==typeof exports?require("./raphael.core"):a.Raphael)}(this,function(a){if(!a||a.vml){var b="hasOwnProperty",c=String,d=parseFloat,e=Math,f=e.round,g=e.max,h=e.min,i=e.abs,j="fill",k=/[, ]+/,l=a.eve,m=" progid:DXImageTransform.Microsoft",n=" ",o="",p={M:"m",L:"l",C:"c",Z:"x",m:"t",l:"r",c:"v",z:"x"},q=/([clmz]),?([^clmz]*)/gi,r=/ progid:\S+Blur\([^\)]+\)/g,s=/-?[^,\s-]+/g,t="position:absolute;left:0;top:0;width:1px;height:1px;behavior:url(#default#VML)",u=21600,v={path:1,rect:1,image:1},w={circle:1,ellipse:1},x=function(b){var d=/[ahqstv]/gi,e=a._pathToAbsolute;if(c(b).match(d)&&(e=a._path2curve),d=/[clmz]/g,e==a._pathToAbsolute&&!c(b).match(d)){var g=c(b).replace(q,function(a,b,c){var d=[],e="m"==b.toLowerCase(),g=p[b];return c.replace(s,function(a){e&&2==d.length&&(g+=d+p["m"==b?"l":"L"],d=[]),d.push(f(a*u))}),g+d});return g}var h,i,j=e(b);g=[];for(var k=0,l=j.length;l>k;k++){h=j[k],i=j[k][0].toLowerCase(),"z"==i&&(i="x");for(var m=1,r=h.length;r>m;m++)i+=f(h[m]*u)+(m!=r-1?",":o);g.push(i)}return g.join(n)},y=function(b,c,d){var e=a.matrix();return e.rotate(-b,.5,.5),{dx:e.x(c,d),dy:e.y(c,d)}},z=function(a,b,c,d,e,f){var g=a._,h=a.matrix,k=g.fillpos,l=a.node,m=l.style,o=1,p="",q=u/b,r=u/c;if(m.visibility="hidden",b&&c){if(l.coordsize=i(q)+n+i(r),m.rotation=f*(0>b*c?-1:1),f){var s=y(f,d,e);d=s.dx,e=s.dy}if(0>b&&(p+="x"),0>c&&(p+=" y")&&(o=-1),m.flip=p,l.coordorigin=d*-q+n+e*-r,k||g.fillsize){var t=l.getElementsByTagName(j);t=t&&t[0],l.removeChild(t),k&&(s=y(f,h.x(k[0],k[1]),h.y(k[0],k[1])),t.position=s.dx*o+n+s.dy*o),g.fillsize&&(t.size=g.fillsize[0]*i(b)+n+g.fillsize[1]*i(c)),l.appendChild(t)}m.visibility="visible"}};a.toString=function(){return"Your browser doesn’t support SVG. Falling down to VML.\nYou are running Raphaël "+this.version};var A=function(a,b,d){for(var e=c(b).toLowerCase().split("-"),f=d?"end":"start",g=e.length,h="classic",i="medium",j="medium";g--;)switch(e[g]){case"block":case"classic":case"oval":case"diamond":case"open":case"none":h=e[g];break;case"wide":case"narrow":j=e[g];break;case"long":case"short":i=e[g]}var k=a.node.getElementsByTagName("stroke")[0];k[f+"arrow"]=h,k[f+"arrowlength"]=i,k[f+"arrowwidth"]=j},B=function(e,i){e.attrs=e.attrs||{};var l=e.node,m=e.attrs,p=l.style,q=v[e.type]&&(i.x!=m.x||i.y!=m.y||i.width!=m.width||i.height!=m.height||i.cx!=m.cx||i.cy!=m.cy||i.rx!=m.rx||i.ry!=m.ry||i.r!=m.r),r=w[e.type]&&(m.cx!=i.cx||m.cy!=i.cy||m.r!=i.r||m.rx!=i.rx||m.ry!=i.ry),s=e;for(var t in i)i[b](t)&&(m[t]=i[t]);if(q&&(m.path=a._getPath[e.type](e),e._.dirty=1),i.href&&(l.href=i.href),i.title&&(l.title=i.title),i.target&&(l.target=i.target),i.cursor&&(p.cursor=i.cursor),"blur"in i&&e.blur(i.blur),(i.path&&"path"==e.type||q)&&(l.path=x(~c(m.path).toLowerCase().indexOf("r")?a._pathToAbsolute(m.path):m.path),e._.dirty=1,"image"==e.type&&(e._.fillpos=[m.x,m.y],e._.fillsize=[m.width,m.height],z(e,1,1,0,0,0))),"transform"in i&&e.transform(i.transform),r){var y=+m.cx,B=+m.cy,D=+m.rx||+m.r||0,E=+m.ry||+m.r||0;l.path=a.format("ar{0},{1},{2},{3},{4},{1},{4},{1}x",f((y-D)*u),f((B-E)*u),f((y+D)*u),f((B+E)*u),f(y*u)),e._.dirty=1}if("clip-rect"in i){var G=c(i["clip-rect"]).split(k);if(4==G.length){G[2]=+G[2]+ +G[0],G[3]=+G[3]+ +G[1];var H=l.clipRect||a._g.doc.createElement("div"),I=H.style;I.clip=a.format("rect({1}px {2}px {3}px {0}px)",G),l.clipRect||(I.position="absolute",I.top=0,I.left=0,I.width=e.paper.width+"px",I.height=e.paper.height+"px",l.parentNode.insertBefore(H,l),H.appendChild(l),l.clipRect=H)}i["clip-rect"]||l.clipRect&&(l.clipRect.style.clip="auto")}if(e.textpath){var J=e.textpath.style;i.font&&(J.font=i.font),i["font-family"]&&(J.fontFamily='"'+i["font-family"].split(",")[0].replace(/^['"]+|['"]+$/g,o)+'"'),i["font-size"]&&(J.fontSize=i["font-size"]),i["font-weight"]&&(J.fontWeight=i["font-weight"]),i["font-style"]&&(J.fontStyle=i["font-style"])}if("arrow-start"in i&&A(s,i["arrow-start"]),"arrow-end"in i&&A(s,i["arrow-end"],1),null!=i.opacity||null!=i["stroke-width"]||null!=i.fill||null!=i.src||null!=i.stroke||null!=i["stroke-width"]||null!=i["stroke-opacity"]||null!=i["fill-opacity"]||null!=i["stroke-dasharray"]||null!=i["stroke-miterlimit"]||null!=i["stroke-linejoin"]||null!=i["stroke-linecap"]){var K=l.getElementsByTagName(j),L=!1;if(K=K&&K[0],!K&&(L=K=F(j)),"image"==e.type&&i.src&&(K.src=i.src),i.fill&&(K.on=!0),(null==K.on||"none"==i.fill||null===i.fill)&&(K.on=!1),K.on&&i.fill){var M=c(i.fill).match(a._ISURL);if(M){K.parentNode==l&&l.removeChild(K),K.rotate=!0,K.src=M[1],K.type="tile";var N=e.getBBox(1);K.position=N.x+n+N.y,e._.fillpos=[N.x,N.y],a._preload(M[1],function(){e._.fillsize=[this.offsetWidth,this.offsetHeight]})}else K.color=a.getRGB(i.fill).hex,K.src=o,K.type="solid",a.getRGB(i.fill).error&&(s.type in{circle:1,ellipse:1}||"r"!=c(i.fill).charAt())&&C(s,i.fill,K)&&(m.fill="none",m.gradient=i.fill,K.rotate=!1)}if("fill-opacity"in i||"opacity"in i){var O=((+m["fill-opacity"]+1||2)-1)*((+m.opacity+1||2)-1)*((+a.getRGB(i.fill).o+1||2)-1);O=h(g(O,0),1),K.opacity=O,K.src&&(K.color="none")}l.appendChild(K);var P=l.getElementsByTagName("stroke")&&l.getElementsByTagName("stroke")[0],Q=!1;!P&&(Q=P=F("stroke")),(i.stroke&&"none"!=i.stroke||i["stroke-width"]||null!=i["stroke-opacity"]||i["stroke-dasharray"]||i["stroke-miterlimit"]||i["stroke-linejoin"]||i["stroke-linecap"])&&(P.on=!0),("none"==i.stroke||null===i.stroke||null==P.on||0==i.stroke||0==i["stroke-width"])&&(P.on=!1);var R=a.getRGB(i.stroke);P.on&&i.stroke&&(P.color=R.hex),O=((+m["stroke-opacity"]+1||2)-1)*((+m.opacity+1||2)-1)*((+R.o+1||2)-1);var S=.75*(d(i["stroke-width"])||1);if(O=h(g(O,0),1),null==i["stroke-width"]&&(S=m["stroke-width"]),i["stroke-width"]&&(P.weight=S),S&&1>S&&(O*=S)&&(P.weight=1),P.opacity=O,i["stroke-linejoin"]&&(P.joinstyle=i["stroke-linejoin"]||"miter"),P.miterlimit=i["stroke-miterlimit"]||8,i["stroke-linecap"]&&(P.endcap="butt"==i["stroke-linecap"]?"flat":"square"==i["stroke-linecap"]?"square":"round"),"stroke-dasharray"in i){var T={"-":"shortdash",".":"shortdot","-.":"shortdashdot","-..":"shortdashdotdot",". ":"dot","- ":"dash","--":"longdash","- .":"dashdot","--.":"longdashdot","--..":"longdashdotdot"};P.dashstyle=T[b](i["stroke-dasharray"])?T[i["stroke-dasharray"]]:o}Q&&l.appendChild(P)}if("text"==s.type){s.paper.canvas.style.display=o;var U=s.paper.span,V=100,W=m.font&&m.font.match(/\d+(?:\.\d*)?(?=px)/);p=U.style,m.font&&(p.font=m.font),m["font-family"]&&(p.fontFamily=m["font-family"]),m["font-weight"]&&(p.fontWeight=m["font-weight"]),m["font-style"]&&(p.fontStyle=m["font-style"]),W=d(m["font-size"]||W&&W[0])||10,p.fontSize=W*V+"px",s.textpath.string&&(U.innerHTML=c(s.textpath.string).replace(/"));var X=U.getBoundingClientRect();s.W=m.w=(X.right-X.left)/V,s.H=m.h=(X.bottom-X.top)/V,s.X=m.x,s.Y=m.y+s.H/2,("x"in i||"y"in i)&&(s.path.v=a.format("m{0},{1}l{2},{1}",f(m.x*u),f(m.y*u),f(m.x*u)+1));for(var Y=["x","y","text","font","font-family","font-weight","font-style","font-size"],Z=0,$=Y.length;$>Z;Z++)if(Y[Z]in i){s._.dirty=1;break}switch(m["text-anchor"]){case"start":s.textpath.style["v-text-align"]="left",s.bbx=s.W/2;break;case"end":s.textpath.style["v-text-align"]="right",s.bbx=-s.W/2;break;default:s.textpath.style["v-text-align"]="center",s.bbx=0}s.textpath.style["v-text-kern"]=!0}},C=function(b,f,g){b.attrs=b.attrs||{};var h=(b.attrs,Math.pow),i="linear",j=".5 .5";if(b.attrs.gradient=f,f=c(f).replace(a._radial_gradient,function(a,b,c){return i="radial",b&&c&&(b=d(b),c=d(c),h(b-.5,2)+h(c-.5,2)>.25&&(c=e.sqrt(.25-h(b-.5,2))*(2*(c>.5)-1)+.5),j=b+n+c),o}),f=f.split(/\s*\-\s*/),"linear"==i){var k=f.shift();if(k=-d(k),isNaN(k))return null}var l=a._parseDots(f);if(!l)return null;if(b=b.shape||b.node,l.length){b.removeChild(g),g.on=!0,g.method="none",g.color=l[0].color,g.color2=l[l.length-1].color;for(var m=[],p=0,q=l.length;q>p;p++)l[p].offset&&m.push(l[p].offset+n+l[p].color);g.colors=m.length?m.join():"0% "+g.color,"radial"==i?(g.type="gradientTitle",g.focus="100%",g.focussize="0 0",g.focusposition=j,g.angle=0):(g.type="gradient",g.angle=(270-k)%360),b.appendChild(g)}return 1},D=function(b,c){this[0]=this.node=b,b.raphael=!0,this.id=a._oid++,b.raphaelid=this.id,this.X=0,this.Y=0,this.attrs={},this.paper=c,this.matrix=a.matrix(),this._={transform:[],sx:1,sy:1,dx:0,dy:0,deg:0,dirty:1,dirtyT:1},!c.bottom&&(c.bottom=this),this.prev=c.top,c.top&&(c.top.next=this),c.top=this,this.next=null},E=a.el;D.prototype=E,E.constructor=D,E.transform=function(b){if(null==b)return this._.transform;var d,e=this.paper._viewBoxShift,f=e?"s"+[e.scale,e.scale]+"-1-1t"+[e.dx,e.dy]:o;e&&(d=b=c(b).replace(/\.{3}|\u2026/g,this._.transform||o)),a._extractTransform(this,f+b);var g,h=this.matrix.clone(),i=this.skew,j=this.node,k=~c(this.attrs.fill).indexOf("-"),l=!c(this.attrs.fill).indexOf("url(");if(h.translate(1,1),l||k||"image"==this.type)if(i.matrix="1 0 0 1",i.offset="0 0",g=h.split(),k&&g.noRotation||!g.isSimple){j.style.filter=h.toFilter();var m=this.getBBox(),p=this.getBBox(1),q=m.x-p.x,r=m.y-p.y;j.coordorigin=q*-u+n+r*-u,z(this,1,1,q,r,0)}else j.style.filter=o,z(this,g.scalex,g.scaley,g.dx,g.dy,g.rotate);else j.style.filter=o,i.matrix=c(h),i.offset=h.offset();return null!==d&&(this._.transform=d,a._extractTransform(this,d)),this},E.rotate=function(a,b,e){if(this.removed)return this;if(null!=a){if(a=c(a).split(k),a.length-1&&(b=d(a[1]),e=d(a[2])),a=d(a[0]),null==e&&(b=e),null==b||null==e){var f=this.getBBox(1);b=f.x+f.width/2,e=f.y+f.height/2}return this._.dirtyT=1,this.transform(this._.transform.concat([["r",a,b,e]])),this}},E.translate=function(a,b){return this.removed?this:(a=c(a).split(k),a.length-1&&(b=d(a[1])),a=d(a[0])||0,b=+b||0,this._.bbox&&(this._.bbox.x+=a,this._.bbox.y+=b),this.transform(this._.transform.concat([["t",a,b]])),this)},E.scale=function(a,b,e,f){if(this.removed)return this;if(a=c(a).split(k),a.length-1&&(b=d(a[1]),e=d(a[2]),f=d(a[3]),isNaN(e)&&(e=null),isNaN(f)&&(f=null)),a=d(a[0]),null==b&&(b=a),null==f&&(e=f),null==e||null==f)var g=this.getBBox(1);return e=null==e?g.x+g.width/2:e,f=null==f?g.y+g.height/2:f,this.transform(this._.transform.concat([["s",a,b,e,f]])),this._.dirtyT=1,this},E.hide=function(){return!this.removed&&(this.node.style.display="none"),this},E.show=function(){return!this.removed&&(this.node.style.display=o),this},E.auxGetBBox=a.el.getBBox,E.getBBox=function(){var a=this.auxGetBBox();if(this.paper&&this.paper._viewBoxShift){var b={},c=1/this.paper._viewBoxShift.scale;return b.x=a.x-this.paper._viewBoxShift.dx,b.x*=c,b.y=a.y-this.paper._viewBoxShift.dy,b.y*=c,b.width=a.width*c,b.height=a.height*c,b.x2=b.x+b.width,b.y2=b.y+b.height,b}return a},E._getBBox=function(){return this.removed?{}:{x:this.X+(this.bbx||0)-this.W/2,y:this.Y-this.H,width:this.W,height:this.H}},E.remove=function(){if(!this.removed&&this.node.parentNode){this.paper.__set__&&this.paper.__set__.exclude(this),a.eve.unbind("raphael.*.*."+this.id),a._tear(this,this.paper),this.node.parentNode.removeChild(this.node),this.shape&&this.shape.parentNode.removeChild(this.shape);for(var b in this)this[b]="function"==typeof this[b]?a._removedFactory(b):null;this.removed=!0}},E.attr=function(c,d){if(this.removed)return this;if(null==c){var e={};for(var f in this.attrs)this.attrs[b](f)&&(e[f]=this.attrs[f]);return e.gradient&&"none"==e.fill&&(e.fill=e.gradient)&&delete e.gradient,e.transform=this._.transform,e}if(null==d&&a.is(c,"string")){if(c==j&&"none"==this.attrs.fill&&this.attrs.gradient)return this.attrs.gradient;for(var g=c.split(k),h={},i=0,m=g.length;m>i;i++)c=g[i],c in this.attrs?h[c]=this.attrs[c]:a.is(this.paper.customAttributes[c],"function")?h[c]=this.paper.customAttributes[c].def:h[c]=a._availableAttrs[c];return m-1?h:h[g[0]]}if(this.attrs&&null==d&&a.is(c,"array")){for(h={},i=0,m=c.length;m>i;i++)h[c[i]]=this.attr(c[i]);return h}var n;null!=d&&(n={},n[c]=d),null==d&&a.is(c,"object")&&(n=c);for(var o in n)l("raphael.attr."+o+"."+this.id,this,n[o]);if(n){for(o in this.paper.customAttributes)if(this.paper.customAttributes[b](o)&&n[b](o)&&a.is(this.paper.customAttributes[o],"function")){var p=this.paper.customAttributes[o].apply(this,[].concat(n[o]));this.attrs[o]=n[o];for(var q in p)p[b](q)&&(n[q]=p[q])}n.text&&"text"==this.type&&(this.textpath.string=n.text),B(this,n)}return this},E.toFront=function(){return!this.removed&&this.node.parentNode.appendChild(this.node),this.paper&&this.paper.top!=this&&a._tofront(this,this.paper),this},E.toBack=function(){return this.removed?this:(this.node.parentNode.firstChild!=this.node&&(this.node.parentNode.insertBefore(this.node,this.node.parentNode.firstChild),a._toback(this,this.paper)),this)},E.insertAfter=function(b){return this.removed?this:(b.constructor==a.st.constructor&&(b=b[b.length-1]),b.node.nextSibling?b.node.parentNode.insertBefore(this.node,b.node.nextSibling):b.node.parentNode.appendChild(this.node),a._insertafter(this,b,this.paper),this)},E.insertBefore=function(b){return this.removed?this:(b.constructor==a.st.constructor&&(b=b[0]),b.node.parentNode.insertBefore(this.node,b.node),a._insertbefore(this,b,this.paper),this)},E.blur=function(b){var c=this.node.runtimeStyle,d=c.filter;return d=d.replace(r,o),0!==+b?(this.attrs.blur=b,c.filter=d+n+m+".Blur(pixelradius="+(+b||1.5)+")",c.margin=a.format("-{0}px 0 0 -{0}px",f(+b||1.5))):(c.filter=d,c.margin=0,delete this.attrs.blur),this},a._engine.path=function(a,b){var c=F("shape");c.style.cssText=t,c.coordsize=u+n+u,c.coordorigin=b.coordorigin;var d=new D(c,b),e={fill:"none",stroke:"#000"};a&&(e.path=a),d.type="path",d.path=[],d.Path=o,B(d,e),b.canvas.appendChild(c);var f=F("skew");return f.on=!0,c.appendChild(f),d.skew=f,d.transform(o),d},a._engine.rect=function(b,c,d,e,f,g){var h=a._rectPath(c,d,e,f,g),i=b.path(h),j=i.attrs;return i.X=j.x=c,i.Y=j.y=d,i.W=j.width=e,i.H=j.height=f,j.r=g,j.path=h,i.type="rect",i},a._engine.ellipse=function(a,b,c,d,e){{var f=a.path();f.attrs}return f.X=b-d,f.Y=c-e,f.W=2*d,f.H=2*e,f.type="ellipse",B(f,{cx:b,cy:c,rx:d,ry:e}),f},a._engine.circle=function(a,b,c,d){{var e=a.path();e.attrs}return e.X=b-d,e.Y=c-d,e.W=e.H=2*d,e.type="circle",B(e,{cx:b,cy:c,r:d}),e},a._engine.image=function(b,c,d,e,f,g){var h=a._rectPath(d,e,f,g),i=b.path(h).attr({stroke:"none"}),k=i.attrs,l=i.node,m=l.getElementsByTagName(j)[0];return k.src=c,i.X=k.x=d,i.Y=k.y=e,i.W=k.width=f,i.H=k.height=g,k.path=h,i.type="image",m.parentNode==l&&l.removeChild(m),m.rotate=!0,m.src=c,m.type="tile",i._.fillpos=[d,e],i._.fillsize=[f,g],l.appendChild(m),z(i,1,1,0,0,0),i},a._engine.text=function(b,d,e,g){var h=F("shape"),i=F("path"),j=F("textpath");d=d||0,e=e||0,g=g||"",i.v=a.format("m{0},{1}l{2},{1}",f(d*u),f(e*u),f(d*u)+1),i.textpathok=!0,j.string=c(g),j.on=!0,h.style.cssText=t,h.coordsize=u+n+u,h.coordorigin="0 0";var k=new D(h,b),l={fill:"#000",stroke:"none",font:a._availableAttrs.font,text:g};k.shape=h,k.path=i,k.textpath=j,k.type="text",k.attrs.text=c(g),k.attrs.x=d,k.attrs.y=e,k.attrs.w=1,k.attrs.h=1,B(k,l),h.appendChild(j),h.appendChild(i),b.canvas.appendChild(h);var m=F("skew");return m.on=!0,h.appendChild(m),k.skew=m,k.transform(o),k},a._engine.setSize=function(b,c){var d=this.canvas.style;return this.width=b,this.height=c,b==+b&&(b+="px"),c==+c&&(c+="px"),d.width=b,d.height=c,d.clip="rect(0 "+b+" "+c+" 0)",this._viewBox&&a._engine.setViewBox.apply(this,this._viewBox),this},a._engine.setViewBox=function(b,c,d,e,f){a.eve("raphael.setViewBox",this,this._viewBox,[b,c,d,e,f]);var g,h,i=this.getSize(),j=i.width,k=i.height;return f&&(g=k/e,h=j/d,j>d*g&&(b-=(j-d*g)/2/g),k>e*h&&(c-=(k-e*h)/2/h)),this._viewBox=[b,c,d,e,!!f],this._viewBoxShift={dx:-b,dy:-c,scale:i},this.forEach(function(a){a.transform("...")}),this};var F;a._engine.initWin=function(a){var b=a.document;b.styleSheets.length<31?b.createStyleSheet().addRule(".rvml","behavior:url(#default#VML)"):b.styleSheets[0].addRule(".rvml","behavior:url(#default#VML)");try{!b.namespaces.rvml&&b.namespaces.add("rvml","urn:schemas-microsoft-com:vml"),F=function(a){return b.createElement("')}}catch(c){F=function(a){return b.createElement("<"+a+' xmlns="urn:schemas-microsoft.com:vml" class="rvml">')}}},a._engine.initWin(a._g.win),a._engine.create=function(){var b=a._getContainer.apply(0,arguments),c=b.container,d=b.height,e=b.width,f=b.x,g=b.y;if(!c)throw new Error("VML container not found.");var h=new a._Paper,i=h.canvas=a._g.doc.createElement("div"),j=i.style;return f=f||0,g=g||0,e=e||512,d=d||342,h.width=e,h.height=d,e==+e&&(e+="px"),d==+d&&(d+="px"),h.coordsize=1e3*u+n+1e3*u,h.coordorigin="0 0",h.span=a._g.doc.createElement("span"),h.span.style.cssText="position:absolute;left:-9999em;top:-9999em;padding:0;margin:0;line-height:1;",i.appendChild(h.span),j.cssText=a.format("top:0;left:0;width:{0};height:{1};display:inline-block;position:relative;clip:rect(0 {0} {1} 0);overflow:hidden",e,d),1==c?(a._g.doc.body.appendChild(i),j.left=f+"px",j.top=g+"px",j.position="absolute"):c.firstChild?c.insertBefore(i,c.firstChild):c.appendChild(i),h.renderfix=function(){},h},a.prototype.clear=function(){a.eve("raphael.clear",this),this.canvas.innerHTML=o,this.span=a._g.doc.createElement("span"),this.span.style.cssText="position:absolute;left:-9999em;top:-9999em;padding:0;margin:0;line-height:1;display:inline;",this.canvas.appendChild(this.span),this.bottom=this.top=null},a.prototype.remove=function(){a.eve("raphael.remove",this),this.canvas.parentNode.removeChild(this.canvas);for(var b in this)this[b]="function"==typeof this[b]?a._removedFactory(b):null;return!0};var G=a.st;for(var H in E)E[b](H)&&!G[b](H)&&(G[H]=function(a){return function(){var b=arguments;return this.forEach(function(c){c[a].apply(c,b)})}}(H))}}); \ No newline at end of file diff --git a/examples/SmartSwitch/data_src/js_css_src/mode-css.js b/examples/SmartSwitch/data_src/js_css_src/mode-css.js new file mode 100644 index 000000000..b41ecdc82 --- /dev/null +++ b/examples/SmartSwitch/data_src/js_css_src/mode-css.js @@ -0,0 +1 @@ +define("ace/mode/css_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./text_highlight_rules").TextHighlightRules,o=t.supportType="align-content|align-items|align-self|all|animation|animation-delay|animation-direction|animation-duration|animation-fill-mode|animation-iteration-count|animation-name|animation-play-state|animation-timing-function|backface-visibility|background|background-attachment|background-blend-mode|background-clip|background-color|background-image|background-origin|background-position|background-repeat|background-size|border|border-bottom|border-bottom-color|border-bottom-left-radius|border-bottom-right-radius|border-bottom-style|border-bottom-width|border-collapse|border-color|border-image|border-image-outset|border-image-repeat|border-image-slice|border-image-source|border-image-width|border-left|border-left-color|border-left-style|border-left-width|border-radius|border-right|border-right-color|border-right-style|border-right-width|border-spacing|border-style|border-top|border-top-color|border-top-left-radius|border-top-right-radius|border-top-style|border-top-width|border-width|bottom|box-shadow|box-sizing|caption-side|clear|clip|color|column-count|column-fill|column-gap|column-rule|column-rule-color|column-rule-style|column-rule-width|column-span|column-width|columns|content|counter-increment|counter-reset|cursor|direction|display|empty-cells|filter|flex|flex-basis|flex-direction|flex-flow|flex-grow|flex-shrink|flex-wrap|float|font|font-family|font-size|font-size-adjust|font-stretch|font-style|font-variant|font-weight|hanging-punctuation|height|justify-content|left|letter-spacing|line-height|list-style|list-style-image|list-style-position|list-style-type|margin|margin-bottom|margin-left|margin-right|margin-top|max-height|max-width|min-height|min-width|nav-down|nav-index|nav-left|nav-right|nav-up|opacity|order|outline|outline-color|outline-offset|outline-style|outline-width|overflow|overflow-x|overflow-y|padding|padding-bottom|padding-left|padding-right|padding-top|page-break-after|page-break-before|page-break-inside|perspective|perspective-origin|position|quotes|resize|right|tab-size|table-layout|text-align|text-align-last|text-decoration|text-decoration-color|text-decoration-line|text-decoration-style|text-indent|text-justify|text-overflow|text-shadow|text-transform|top|transform|transform-origin|transform-style|transition|transition-delay|transition-duration|transition-property|transition-timing-function|unicode-bidi|vertical-align|visibility|white-space|width|word-break|word-spacing|word-wrap|z-index",u=t.supportFunction="rgb|rgba|url|attr|counter|counters",a=t.supportConstant="absolute|after-edge|after|all-scroll|all|alphabetic|always|antialiased|armenian|auto|avoid-column|avoid-page|avoid|balance|baseline|before-edge|before|below|bidi-override|block-line-height|block|bold|bolder|border-box|both|bottom|box|break-all|break-word|capitalize|caps-height|caption|center|central|char|circle|cjk-ideographic|clone|close-quote|col-resize|collapse|column|consider-shifts|contain|content-box|cover|crosshair|cubic-bezier|dashed|decimal-leading-zero|decimal|default|disabled|disc|disregard-shifts|distribute-all-lines|distribute-letter|distribute-space|distribute|dotted|double|e-resize|ease-in|ease-in-out|ease-out|ease|ellipsis|end|exclude-ruby|fill|fixed|georgian|glyphs|grid-height|groove|hand|hanging|hebrew|help|hidden|hiragana-iroha|hiragana|horizontal|icon|ideograph-alpha|ideograph-numeric|ideograph-parenthesis|ideograph-space|ideographic|inactive|include-ruby|inherit|initial|inline-block|inline-box|inline-line-height|inline-table|inline|inset|inside|inter-ideograph|inter-word|invert|italic|justify|katakana-iroha|katakana|keep-all|last|left|lighter|line-edge|line-through|line|linear|list-item|local|loose|lower-alpha|lower-greek|lower-latin|lower-roman|lowercase|lr-tb|ltr|mathematical|max-height|max-size|medium|menu|message-box|middle|move|n-resize|ne-resize|newspaper|no-change|no-close-quote|no-drop|no-open-quote|no-repeat|none|normal|not-allowed|nowrap|nw-resize|oblique|open-quote|outset|outside|overline|padding-box|page|pointer|pre-line|pre-wrap|pre|preserve-3d|progress|relative|repeat-x|repeat-y|repeat|replaced|reset-size|ridge|right|round|row-resize|rtl|s-resize|scroll|se-resize|separate|slice|small-caps|small-caption|solid|space|square|start|static|status-bar|step-end|step-start|steps|stretch|strict|sub|super|sw-resize|table-caption|table-cell|table-column-group|table-column|table-footer-group|table-header-group|table-row-group|table-row|table|tb-rl|text-after-edge|text-before-edge|text-bottom|text-size|text-top|text|thick|thin|transparent|underline|upper-alpha|upper-latin|upper-roman|uppercase|use-script|vertical-ideographic|vertical-text|visible|w-resize|wait|whitespace|z-index|zero",f=t.supportConstantColor="aqua|black|blue|fuchsia|gray|green|lime|maroon|navy|olive|orange|purple|red|silver|teal|white|yellow",l=t.supportConstantFonts="arial|century|comic|courier|cursive|fantasy|garamond|georgia|helvetica|impact|lucida|symbol|system|tahoma|times|trebuchet|utopia|verdana|webdings|sans-serif|serif|monospace",c=t.numRe="\\-?(?:(?:[0-9]+)|(?:[0-9]*\\.[0-9]+))",h=t.pseudoElements="(\\:+)\\b(after|before|first-letter|first-line|moz-selection|selection)\\b",p=t.pseudoClasses="(:)\\b(active|checked|disabled|empty|enabled|first-child|first-of-type|focus|hover|indeterminate|invalid|last-child|last-of-type|link|not|nth-child|nth-last-child|nth-last-of-type|nth-of-type|only-child|only-of-type|required|root|target|valid|visited)\\b",d=function(){var e=this.createKeywordMapper({"support.function":u,"support.constant":a,"support.type":o,"support.constant.color":f,"support.constant.fonts":l},"text",!0);this.$rules={start:[{token:"comment",regex:"\\/\\*",push:"comment"},{token:"paren.lparen",regex:"\\{",push:"ruleset"},{token:"string",regex:"@.*?{",push:"media"},{token:"keyword",regex:"#[a-z0-9-_]+"},{token:"variable",regex:"\\.[a-z0-9-_]+"},{token:"string",regex:":[a-z0-9-_]+"},{token:"constant",regex:"[a-z0-9-_]+"},{caseInsensitive:!0}],media:[{token:"comment",regex:"\\/\\*",push:"comment"},{token:"paren.lparen",regex:"\\{",push:"ruleset"},{token:"string",regex:"\\}",next:"pop"},{token:"keyword",regex:"#[a-z0-9-_]+"},{token:"variable",regex:"\\.[a-z0-9-_]+"},{token:"string",regex:":[a-z0-9-_]+"},{token:"constant",regex:"[a-z0-9-_]+"},{caseInsensitive:!0}],comment:[{token:"comment",regex:"\\*\\/",next:"pop"},{defaultToken:"comment"}],ruleset:[{token:"paren.rparen",regex:"\\}",next:"pop"},{token:"comment",regex:"\\/\\*",push:"comment"},{token:"string",regex:'["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]'},{token:"string",regex:"['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']"},{token:["constant.numeric","keyword"],regex:"("+c+")(ch|cm|deg|em|ex|fr|gd|grad|Hz|in|kHz|mm|ms|pc|pt|px|rad|rem|s|turn|vh|vm|vw|%)"},{token:"constant.numeric",regex:c},{token:"constant.numeric",regex:"#[a-f0-9]{6}"},{token:"constant.numeric",regex:"#[a-f0-9]{3}"},{token:["punctuation","entity.other.attribute-name.pseudo-element.css"],regex:h},{token:["punctuation","entity.other.attribute-name.pseudo-class.css"],regex:p},{token:["support.function","string","support.function"],regex:"(url\\()(.*)(\\))"},{token:e,regex:"\\-?[a-zA-Z_][a-zA-Z0-9_\\-]*"},{caseInsensitive:!0}]},this.normalizeRules()};r.inherits(d,s),t.CssHighlightRules=d}),define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],function(e,t,n){"use strict";var r=e("../range").Range,i=function(){};(function(){this.checkOutdent=function(e,t){return/^\s+$/.test(e)?/^\s*\}/.test(t):!1},this.autoOutdent=function(e,t){var n=e.getLine(t),i=n.match(/^(\s*\})/);if(!i)return 0;var s=i[1].length,o=e.findMatchingBracket({row:t,column:s});if(!o||o.row==t)return 0;var u=this.$getIndent(e.getLine(o.row));e.replace(new r(t,0,t,s-1),u)},this.$getIndent=function(e){return e.match(/^\s*/)[0]}}).call(i.prototype),t.MatchingBraceOutdent=i}),define("ace/mode/css_completions",["require","exports","module"],function(e,t,n){"use strict";var r={background:{"#$0":1},"background-color":{"#$0":1,transparent:1,fixed:1},"background-image":{"url('/$0')":1},"background-repeat":{repeat:1,"repeat-x":1,"repeat-y":1,"no-repeat":1,inherit:1},"background-position":{bottom:2,center:2,left:2,right:2,top:2,inherit:2},"background-attachment":{scroll:1,fixed:1},"background-size":{cover:1,contain:1},"background-clip":{"border-box":1,"padding-box":1,"content-box":1},"background-origin":{"border-box":1,"padding-box":1,"content-box":1},border:{"solid $0":1,"dashed $0":1,"dotted $0":1,"#$0":1},"border-color":{"#$0":1},"border-style":{solid:2,dashed:2,dotted:2,"double":2,groove:2,hidden:2,inherit:2,inset:2,none:2,outset:2,ridged:2},"border-collapse":{collapse:1,separate:1},bottom:{px:1,em:1,"%":1},clear:{left:1,right:1,both:1,none:1},color:{"#$0":1,"rgb(#$00,0,0)":1},cursor:{"default":1,pointer:1,move:1,text:1,wait:1,help:1,progress:1,"n-resize":1,"ne-resize":1,"e-resize":1,"se-resize":1,"s-resize":1,"sw-resize":1,"w-resize":1,"nw-resize":1},display:{none:1,block:1,inline:1,"inline-block":1,"table-cell":1},"empty-cells":{show:1,hide:1},"float":{left:1,right:1,none:1},"font-family":{Arial:2,"Comic Sans MS":2,Consolas:2,"Courier New":2,Courier:2,Georgia:2,Monospace:2,"Sans-Serif":2,"Segoe UI":2,Tahoma:2,"Times New Roman":2,"Trebuchet MS":2,Verdana:1},"font-size":{px:1,em:1,"%":1},"font-weight":{bold:1,normal:1},"font-style":{italic:1,normal:1},"font-variant":{normal:1,"small-caps":1},height:{px:1,em:1,"%":1},left:{px:1,em:1,"%":1},"letter-spacing":{normal:1},"line-height":{normal:1},"list-style-type":{none:1,disc:1,circle:1,square:1,decimal:1,"decimal-leading-zero":1,"lower-roman":1,"upper-roman":1,"lower-greek":1,"lower-latin":1,"upper-latin":1,georgian:1,"lower-alpha":1,"upper-alpha":1},margin:{px:1,em:1,"%":1},"margin-right":{px:1,em:1,"%":1},"margin-left":{px:1,em:1,"%":1},"margin-top":{px:1,em:1,"%":1},"margin-bottom":{px:1,em:1,"%":1},"max-height":{px:1,em:1,"%":1},"max-width":{px:1,em:1,"%":1},"min-height":{px:1,em:1,"%":1},"min-width":{px:1,em:1,"%":1},overflow:{hidden:1,visible:1,auto:1,scroll:1},"overflow-x":{hidden:1,visible:1,auto:1,scroll:1},"overflow-y":{hidden:1,visible:1,auto:1,scroll:1},padding:{px:1,em:1,"%":1},"padding-top":{px:1,em:1,"%":1},"padding-right":{px:1,em:1,"%":1},"padding-bottom":{px:1,em:1,"%":1},"padding-left":{px:1,em:1,"%":1},"page-break-after":{auto:1,always:1,avoid:1,left:1,right:1},"page-break-before":{auto:1,always:1,avoid:1,left:1,right:1},position:{absolute:1,relative:1,fixed:1,"static":1},right:{px:1,em:1,"%":1},"table-layout":{fixed:1,auto:1},"text-decoration":{none:1,underline:1,"line-through":1,blink:1},"text-align":{left:1,right:1,center:1,justify:1},"text-transform":{capitalize:1,uppercase:1,lowercase:1,none:1},top:{px:1,em:1,"%":1},"vertical-align":{top:1,bottom:1},visibility:{hidden:1,visible:1},"white-space":{nowrap:1,normal:1,pre:1,"pre-line":1,"pre-wrap":1},width:{px:1,em:1,"%":1},"word-spacing":{normal:1},filter:{"alpha(opacity=$0100)":1},"text-shadow":{"$02px 2px 2px #777":1},"text-overflow":{"ellipsis-word":1,clip:1,ellipsis:1},"-moz-border-radius":1,"-moz-border-radius-topright":1,"-moz-border-radius-bottomright":1,"-moz-border-radius-topleft":1,"-moz-border-radius-bottomleft":1,"-webkit-border-radius":1,"-webkit-border-top-right-radius":1,"-webkit-border-top-left-radius":1,"-webkit-border-bottom-right-radius":1,"-webkit-border-bottom-left-radius":1,"-moz-box-shadow":1,"-webkit-box-shadow":1,transform:{"rotate($00deg)":1,"skew($00deg)":1},"-moz-transform":{"rotate($00deg)":1,"skew($00deg)":1},"-webkit-transform":{"rotate($00deg)":1,"skew($00deg)":1}},i=function(){};(function(){this.completionsDefined=!1,this.defineCompletions=function(){if(document){var e=document.createElement("c").style;for(var t in e){if(typeof e[t]!="string")continue;var n=t.replace(/[A-Z]/g,function(e){return"-"+e.toLowerCase()});r.hasOwnProperty(n)||(r[n]=1)}}this.completionsDefined=!0},this.getCompletions=function(e,t,n,r){this.completionsDefined||this.defineCompletions();var i=t.getTokenAt(n.row,n.column);if(!i)return[];if(e==="ruleset"){var s=t.getLine(n.row).substr(0,n.column);return/:[^;]+$/.test(s)?(/([\w\-]+):[^:]*$/.test(s),this.getPropertyValueCompletions(e,t,n,r)):this.getPropertyCompletions(e,t,n,r)}return[]},this.getPropertyCompletions=function(e,t,n,i){var s=Object.keys(r);return s.map(function(e){return{caption:e,snippet:e+": $0",meta:"property",score:Number.MAX_VALUE}})},this.getPropertyValueCompletions=function(e,t,n,i){var s=t.getLine(n.row).substr(0,n.column),o=(/([\w\-]+):[^:]*$/.exec(s)||{})[1];if(!o)return[];var u=[];return o in r&&typeof r[o]=="object"&&(u=Object.keys(r[o])),u.map(function(e){return{caption:e,snippet:e,meta:"property value",score:Number.MAX_VALUE}})}}).call(i.prototype),t.CssCompletions=i}),define("ace/mode/behaviour/css",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/mode/behaviour/cstyle","ace/token_iterator"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("./cstyle").CstyleBehaviour,o=e("../../token_iterator").TokenIterator,u=function(){this.inherit(s),this.add("colon","insertion",function(e,t,n,r,i){if(i===":"){var s=n.getCursorPosition(),u=new o(r,s.row,s.column),a=u.getCurrentToken();a&&a.value.match(/\s+/)&&(a=u.stepBackward());if(a&&a.type==="support.type"){var f=r.doc.getLine(s.row),l=f.substring(s.column,s.column+1);if(l===":")return{text:"",selection:[1,1]};if(!f.substring(s.column).match(/^\s*;/))return{text:":;",selection:[1,1]}}}}),this.add("colon","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s===":"){var u=n.getCursorPosition(),a=new o(r,u.row,u.column),f=a.getCurrentToken();f&&f.value.match(/\s+/)&&(f=a.stepBackward());if(f&&f.type==="support.type"){var l=r.doc.getLine(i.start.row),c=l.substring(i.end.column,i.end.column+1);if(c===";")return i.end.column++,i}}}),this.add("semicolon","insertion",function(e,t,n,r,i){if(i===";"){var s=n.getCursorPosition(),o=r.doc.getLine(s.row),u=o.substring(s.column,s.column+1);if(u===";")return{text:"",selection:[1,1]}}})};r.inherits(u,s),t.CssBehaviour=u}),define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../../range").Range,s=e("./fold_mode").FoldMode,o=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end)))};r.inherits(o,s),function(){this.foldingStartMarker=/(\{|\[)[^\}\]]*$|^\s*(\/\*)/,this.foldingStopMarker=/^[^\[\{]*(\}|\])|^[\s\*]*(\*\/)/,this.singleLineBlockCommentRe=/^\s*(\/\*).*\*\/\s*$/,this.tripleStarBlockCommentRe=/^\s*(\/\*\*\*).*\*\/\s*$/,this.startRegionRe=/^\s*(\/\*|\/\/)#?region\b/,this._getFoldWidgetBase=this.getFoldWidget,this.getFoldWidget=function(e,t,n){var r=e.getLine(n);if(this.singleLineBlockCommentRe.test(r)&&!this.startRegionRe.test(r)&&!this.tripleStarBlockCommentRe.test(r))return"";var i=this._getFoldWidgetBase(e,t,n);return!i&&this.startRegionRe.test(r)?"start":i},this.getFoldWidgetRange=function(e,t,n,r){var i=e.getLine(n);if(this.startRegionRe.test(i))return this.getCommentRegionBlock(e,i,n);var s=i.match(this.foldingStartMarker);if(s){var o=s.index;if(s[1])return this.openingBracketBlock(e,s[1],n,o);var u=e.getCommentFoldRange(n,o+s[0].length,1);return u&&!u.isMultiLine()&&(r?u=this.getSectionRange(e,n):t!="all"&&(u=null)),u}if(t==="markbegin")return;var s=i.match(this.foldingStopMarker);if(s){var o=s.index+s[0].length;return s[1]?this.closingBracketBlock(e,s[1],n,o):e.getCommentFoldRange(n,o,-1)}},this.getSectionRange=function(e,t){var n=e.getLine(t),r=n.search(/\S/),s=t,o=n.length;t+=1;var u=t,a=e.getLength();while(++tf)break;var l=this.getFoldWidgetRange(e,"all",t);if(l){if(l.start.row<=s)break;if(l.isMultiLine())t=l.end.row;else if(r==f)break}u=t}return new i(s,o,u,e.getLine(u).length)},this.getCommentRegionBlock=function(e,t,n){var r=t.search(/\s*$/),s=e.getLength(),o=n,u=/^\s*(?:\/\*|\/\/|--)#?(end)?region\b/,a=1;while(++no)return new i(o,r,l,t.length)}}.call(o.prototype)}),define("ace/mode/css",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/css_highlight_rules","ace/mode/matching_brace_outdent","ace/worker/worker_client","ace/mode/css_completions","ace/mode/behaviour/css","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./css_highlight_rules").CssHighlightRules,o=e("./matching_brace_outdent").MatchingBraceOutdent,u=e("../worker/worker_client").WorkerClient,a=e("./css_completions").CssCompletions,f=e("./behaviour/css").CssBehaviour,l=e("./folding/cstyle").FoldMode,c=function(){this.HighlightRules=s,this.$outdent=new o,this.$behaviour=new f,this.$completer=new a,this.foldingRules=new l};r.inherits(c,i),function(){this.foldingRules="cStyle",this.blockComment={start:"/*",end:"*/"},this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),i=this.getTokenizer().getLineTokens(t,e).tokens;if(i.length&&i[i.length-1].type=="comment")return r;var s=t.match(/^.*\{\s*$/);return s&&(r+=n),r},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.getCompletions=function(e,t,n,r){return this.$completer.getCompletions(e,t,n,r)},this.createWorker=function(e){var t=new u(["ace"],"ace/mode/css_worker","Worker");return t.attachToDocument(e.getDocument()),t.on("annotate",function(t){e.setAnnotations(t.data)}),t.on("terminate",function(){e.clearAnnotations()}),t},this.$id="ace/mode/css"}.call(c.prototype),t.Mode=c}) \ No newline at end of file diff --git a/examples/SmartSwitch/data_src/js_css_src/mode-html.js b/examples/SmartSwitch/data_src/js_css_src/mode-html.js new file mode 100644 index 000000000..faee4472e --- /dev/null +++ b/examples/SmartSwitch/data_src/js_css_src/mode-html.js @@ -0,0 +1 @@ +define("ace/mode/doc_comment_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){this.$rules={start:[{token:"comment.doc.tag",regex:"@[\\w\\d_]+"},s.getTagRule(),{defaultToken:"comment.doc",caseInsensitive:!0}]}};r.inherits(s,i),s.getTagRule=function(e){return{token:"comment.doc.tag.storage.type",regex:"\\b(?:TODO|FIXME|XXX|HACK)\\b"}},s.getStartRule=function(e){return{token:"comment.doc",regex:"\\/\\*(?=\\*)",next:e}},s.getEndRule=function(e){return{token:"comment.doc",regex:"\\*\\/",next:e}},t.DocCommentHighlightRules=s}),define("ace/mode/javascript_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/doc_comment_highlight_rules","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";function a(){var e=o.replace("\\d","\\d\\-"),t={onMatch:function(e,t,n){var r=e.charAt(1)=="/"?2:1;if(r==1)t!=this.nextState?n.unshift(this.next,this.nextState,0):n.unshift(this.next),n[2]++;else if(r==2&&t==this.nextState){n[1]--;if(!n[1]||n[1]<0)n.shift(),n.shift()}return[{type:"meta.tag.punctuation."+(r==1?"":"end-")+"tag-open.xml",value:e.slice(0,r)},{type:"meta.tag.tag-name.xml",value:e.substr(r)}]},regex:"",onMatch:function(e,t,n){return t==n[0]&&n.shift(),e.length==2&&(n[0]==this.nextState&&n[1]--,(!n[1]||n[1]<0)&&n.splice(0,2)),this.next=n[0]||"start",[{type:this.token,value:e}]},nextState:"jsx"},n,f("jsxAttributes"),{token:"entity.other.attribute-name.xml",regex:e},{token:"keyword.operator.attribute-equals.xml",regex:"="},{token:"text.tag-whitespace.xml",regex:"\\s+"},{token:"string.attribute-value.xml",regex:"'",stateName:"jsx_attr_q",push:[{token:"string.attribute-value.xml",regex:"'",next:"pop"},{include:"reference"},{defaultToken:"string.attribute-value.xml"}]},{token:"string.attribute-value.xml",regex:'"',stateName:"jsx_attr_qq",push:[{token:"string.attribute-value.xml",regex:'"',next:"pop"},{include:"reference"},{defaultToken:"string.attribute-value.xml"}]},t],this.$rules.reference=[{token:"constant.language.escape.reference.xml",regex:"(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)"}]}function f(e){return[{token:"comment",regex:/\/\*/,next:[i.getTagRule(),{token:"comment",regex:"\\*\\/",next:e||"pop"},{defaultToken:"comment",caseInsensitive:!0}]},{token:"comment",regex:"\\/\\/",next:[i.getTagRule(),{token:"comment",regex:"$|^",next:e||"pop"},{defaultToken:"comment",caseInsensitive:!0}]}]}var r=e("../lib/oop"),i=e("./doc_comment_highlight_rules").DocCommentHighlightRules,s=e("./text_highlight_rules").TextHighlightRules,o="[a-zA-Z\\$_\u00a1-\uffff][a-zA-Z\\d\\$_\u00a1-\uffff]*",u=function(e){var t=this.createKeywordMapper({"variable.language":"Array|Boolean|Date|Function|Iterator|Number|Object|RegExp|String|Proxy|Namespace|QName|XML|XMLList|ArrayBuffer|Float32Array|Float64Array|Int16Array|Int32Array|Int8Array|Uint16Array|Uint32Array|Uint8Array|Uint8ClampedArray|Error|EvalError|InternalError|RangeError|ReferenceError|StopIteration|SyntaxError|TypeError|URIError|decodeURI|decodeURIComponent|encodeURI|encodeURIComponent|eval|isFinite|isNaN|parseFloat|parseInt|JSON|Math|this|arguments|prototype|window|document",keyword:"const|yield|import|get|set|async|await|break|case|catch|continue|default|delete|do|else|finally|for|function|if|in|of|instanceof|new|return|switch|throw|try|typeof|let|var|while|with|debugger|__parent__|__count__|escape|unescape|with|__proto__|class|enum|extends|super|export|implements|private|public|interface|package|protected|static","storage.type":"const|let|var|function","constant.language":"null|Infinity|NaN|undefined","support.function":"alert","constant.language.boolean":"true|false"},"identifier"),n="case|do|else|finally|in|instanceof|return|throw|try|typeof|yield|void",r="\\\\(?:x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|u{[0-9a-fA-F]{1,6}}|[0-2][0-7]{0,2}|3[0-7][0-7]?|[4-7][0-7]?|.)";this.$rules={no_regex:[i.getStartRule("doc-start"),f("no_regex"),{token:"string",regex:"'(?=.)",next:"qstring"},{token:"string",regex:'"(?=.)',next:"qqstring"},{token:"constant.numeric",regex:/0(?:[xX][0-9a-fA-F]+|[bB][01]+)\b/},{token:"constant.numeric",regex:/[+-]?\d[\d_]*(?:(?:\.\d*)?(?:[eE][+-]?\d+)?)?\b/},{token:["storage.type","punctuation.operator","support.function","punctuation.operator","entity.name.function","text","keyword.operator"],regex:"("+o+")(\\.)(prototype)(\\.)("+o+")(\\s*)(=)",next:"function_arguments"},{token:["storage.type","punctuation.operator","entity.name.function","text","keyword.operator","text","storage.type","text","paren.lparen"],regex:"("+o+")(\\.)("+o+")(\\s*)(=)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["entity.name.function","text","keyword.operator","text","storage.type","text","paren.lparen"],regex:"("+o+")(\\s*)(=)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["storage.type","punctuation.operator","entity.name.function","text","keyword.operator","text","storage.type","text","entity.name.function","text","paren.lparen"],regex:"("+o+")(\\.)("+o+")(\\s*)(=)(\\s*)(function)(\\s+)(\\w+)(\\s*)(\\()",next:"function_arguments"},{token:["storage.type","text","entity.name.function","text","paren.lparen"],regex:"(function)(\\s+)("+o+")(\\s*)(\\()",next:"function_arguments"},{token:["entity.name.function","text","punctuation.operator","text","storage.type","text","paren.lparen"],regex:"("+o+")(\\s*)(:)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["text","text","storage.type","text","paren.lparen"],regex:"(:)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:"keyword",regex:"(?:"+n+")\\b",next:"start"},{token:["support.constant"],regex:/that\b/},{token:["storage.type","punctuation.operator","support.function.firebug"],regex:/(console)(\.)(warn|info|log|error|time|trace|timeEnd|assert)\b/},{token:t,regex:o},{token:"punctuation.operator",regex:/[.](?![.])/,next:"property"},{token:"keyword.operator",regex:/--|\+\+|\.{3}|===|==|=|!=|!==|<+=?|>+=?|!|&&|\|\||\?:|[!$%&*+\-~\/^]=?/,next:"start"},{token:"punctuation.operator",regex:/[?:,;.]/,next:"start"},{token:"paren.lparen",regex:/[\[({]/,next:"start"},{token:"paren.rparen",regex:/[\])}]/},{token:"comment",regex:/^#!.*$/}],property:[{token:"text",regex:"\\s+"},{token:["storage.type","punctuation.operator","entity.name.function","text","keyword.operator","text","storage.type","text","entity.name.function","text","paren.lparen"],regex:"("+o+")(\\.)("+o+")(\\s*)(=)(\\s*)(function)(?:(\\s+)(\\w+))?(\\s*)(\\()",next:"function_arguments"},{token:"punctuation.operator",regex:/[.](?![.])/},{token:"support.function",regex:/(s(?:h(?:ift|ow(?:Mod(?:elessDialog|alDialog)|Help))|croll(?:X|By(?:Pages|Lines)?|Y|To)?|t(?:op|rike)|i(?:n|zeToContent|debar|gnText)|ort|u(?:p|b(?:str(?:ing)?)?)|pli(?:ce|t)|e(?:nd|t(?:Re(?:sizable|questHeader)|M(?:i(?:nutes|lliseconds)|onth)|Seconds|Ho(?:tKeys|urs)|Year|Cursor|Time(?:out)?|Interval|ZOptions|Date|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Date|FullYear)|FullYear|Active)|arch)|qrt|lice|avePreferences|mall)|h(?:ome|andleEvent)|navigate|c(?:har(?:CodeAt|At)|o(?:s|n(?:cat|textual|firm)|mpile)|eil|lear(?:Timeout|Interval)?|a(?:ptureEvents|ll)|reate(?:StyleSheet|Popup|EventObject))|t(?:o(?:GMTString|S(?:tring|ource)|U(?:TCString|pperCase)|Lo(?:caleString|werCase))|est|a(?:n|int(?:Enabled)?))|i(?:s(?:NaN|Finite)|ndexOf|talics)|d(?:isableExternalCapture|ump|etachEvent)|u(?:n(?:shift|taint|escape|watch)|pdateCommands)|j(?:oin|avaEnabled)|p(?:o(?:p|w)|ush|lugins.refresh|a(?:ddings|rse(?:Int|Float)?)|r(?:int|ompt|eference))|e(?:scape|nableExternalCapture|val|lementFromPoint|x(?:p|ec(?:Script|Command)?))|valueOf|UTC|queryCommand(?:State|Indeterm|Enabled|Value)|f(?:i(?:nd|le(?:ModifiedDate|Size|CreatedDate|UpdatedDate)|xed)|o(?:nt(?:size|color)|rward)|loor|romCharCode)|watch|l(?:ink|o(?:ad|g)|astIndexOf)|a(?:sin|nchor|cos|t(?:tachEvent|ob|an(?:2)?)|pply|lert|b(?:s|ort))|r(?:ou(?:nd|teEvents)|e(?:size(?:By|To)|calc|turnValue|place|verse|l(?:oad|ease(?:Capture|Events)))|andom)|g(?:o|et(?:ResponseHeader|M(?:i(?:nutes|lliseconds)|onth)|Se(?:conds|lection)|Hours|Year|Time(?:zoneOffset)?|Da(?:y|te)|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Da(?:y|te)|FullYear)|FullYear|A(?:ttention|llResponseHeaders)))|m(?:in|ove(?:B(?:y|elow)|To(?:Absolute)?|Above)|ergeAttributes|a(?:tch|rgins|x))|b(?:toa|ig|o(?:ld|rderWidths)|link|ack))\b(?=\()/},{token:"support.function.dom",regex:/(s(?:ub(?:stringData|mit)|plitText|e(?:t(?:NamedItem|Attribute(?:Node)?)|lect))|has(?:ChildNodes|Feature)|namedItem|c(?:l(?:ick|o(?:se|neNode))|reate(?:C(?:omment|DATASection|aption)|T(?:Head|extNode|Foot)|DocumentFragment|ProcessingInstruction|E(?:ntityReference|lement)|Attribute))|tabIndex|i(?:nsert(?:Row|Before|Cell|Data)|tem)|open|delete(?:Row|C(?:ell|aption)|T(?:Head|Foot)|Data)|focus|write(?:ln)?|a(?:dd|ppend(?:Child|Data))|re(?:set|place(?:Child|Data)|move(?:NamedItem|Child|Attribute(?:Node)?)?)|get(?:NamedItem|Element(?:sBy(?:Name|TagName|ClassName)|ById)|Attribute(?:Node)?)|blur)\b(?=\()/},{token:"support.constant",regex:/(s(?:ystemLanguage|cr(?:ipts|ollbars|een(?:X|Y|Top|Left))|t(?:yle(?:Sheets)?|atus(?:Text|bar)?)|ibling(?:Below|Above)|ource|uffixes|e(?:curity(?:Policy)?|l(?:ection|f)))|h(?:istory|ost(?:name)?|as(?:h|Focus))|y|X(?:MLDocument|SLDocument)|n(?:ext|ame(?:space(?:s|URI)|Prop))|M(?:IN_VALUE|AX_VALUE)|c(?:haracterSet|o(?:n(?:structor|trollers)|okieEnabled|lorDepth|mp(?:onents|lete))|urrent|puClass|l(?:i(?:p(?:boardData)?|entInformation)|osed|asses)|alle(?:e|r)|rypto)|t(?:o(?:olbar|p)|ext(?:Transform|Indent|Decoration|Align)|ags)|SQRT(?:1_2|2)|i(?:n(?:ner(?:Height|Width)|put)|ds|gnoreCase)|zIndex|o(?:scpu|n(?:readystatechange|Line)|uter(?:Height|Width)|p(?:sProfile|ener)|ffscreenBuffering)|NEGATIVE_INFINITY|d(?:i(?:splay|alog(?:Height|Top|Width|Left|Arguments)|rectories)|e(?:scription|fault(?:Status|Ch(?:ecked|arset)|View)))|u(?:ser(?:Profile|Language|Agent)|n(?:iqueID|defined)|pdateInterval)|_content|p(?:ixelDepth|ort|ersonalbar|kcs11|l(?:ugins|atform)|a(?:thname|dding(?:Right|Bottom|Top|Left)|rent(?:Window|Layer)?|ge(?:X(?:Offset)?|Y(?:Offset)?))|r(?:o(?:to(?:col|type)|duct(?:Sub)?|mpter)|e(?:vious|fix)))|e(?:n(?:coding|abledPlugin)|x(?:ternal|pando)|mbeds)|v(?:isibility|endor(?:Sub)?|Linkcolor)|URLUnencoded|P(?:I|OSITIVE_INFINITY)|f(?:ilename|o(?:nt(?:Size|Family|Weight)|rmName)|rame(?:s|Element)|gColor)|E|whiteSpace|l(?:i(?:stStyleType|n(?:eHeight|kColor))|o(?:ca(?:tion(?:bar)?|lName)|wsrc)|e(?:ngth|ft(?:Context)?)|a(?:st(?:M(?:odified|atch)|Index|Paren)|yer(?:s|X)|nguage))|a(?:pp(?:MinorVersion|Name|Co(?:deName|re)|Version)|vail(?:Height|Top|Width|Left)|ll|r(?:ity|guments)|Linkcolor|bove)|r(?:ight(?:Context)?|e(?:sponse(?:XML|Text)|adyState))|global|x|m(?:imeTypes|ultiline|enubar|argin(?:Right|Bottom|Top|Left))|L(?:N(?:10|2)|OG(?:10E|2E))|b(?:o(?:ttom|rder(?:Width|RightWidth|BottomWidth|Style|Color|TopWidth|LeftWidth))|ufferDepth|elow|ackground(?:Color|Image)))\b/},{token:"identifier",regex:o},{regex:"",token:"empty",next:"no_regex"}],start:[i.getStartRule("doc-start"),f("start"),{token:"string.regexp",regex:"\\/",next:"regex"},{token:"text",regex:"\\s+|^$",next:"start"},{token:"empty",regex:"",next:"no_regex"}],regex:[{token:"regexp.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"string.regexp",regex:"/[sxngimy]*",next:"no_regex"},{token:"invalid",regex:/\{\d+\b,?\d*\}[+*]|[+*$^?][+*]|[$^][?]|\?{3,}/},{token:"constant.language.escape",regex:/\(\?[:=!]|\)|\{\d+\b,?\d*\}|[+*]\?|[()$^+*?.]/},{token:"constant.language.delimiter",regex:/\|/},{token:"constant.language.escape",regex:/\[\^?/,next:"regex_character_class"},{token:"empty",regex:"$",next:"no_regex"},{defaultToken:"string.regexp"}],regex_character_class:[{token:"regexp.charclass.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"constant.language.escape",regex:"]",next:"regex"},{token:"constant.language.escape",regex:"-"},{token:"empty",regex:"$",next:"no_regex"},{defaultToken:"string.regexp.charachterclass"}],function_arguments:[{token:"variable.parameter",regex:o},{token:"punctuation.operator",regex:"[, ]+"},{token:"punctuation.operator",regex:"$"},{token:"empty",regex:"",next:"no_regex"}],qqstring:[{token:"constant.language.escape",regex:r},{token:"string",regex:"\\\\$",next:"qqstring"},{token:"string",regex:'"|$',next:"no_regex"},{defaultToken:"string"}],qstring:[{token:"constant.language.escape",regex:r},{token:"string",regex:"\\\\$",next:"qstring"},{token:"string",regex:"'|$",next:"no_regex"},{defaultToken:"string"}]};if(!e||!e.noES6)this.$rules.no_regex.unshift({regex:"[{}]",onMatch:function(e,t,n){this.next=e=="{"?this.nextState:"";if(e=="{"&&n.length)n.unshift("start",t);else if(e=="}"&&n.length){n.shift(),this.next=n.shift();if(this.next.indexOf("string")!=-1||this.next.indexOf("jsx")!=-1)return"paren.quasi.end"}return e=="{"?"paren.lparen":"paren.rparen"},nextState:"start"},{token:"string.quasi.start",regex:/`/,push:[{token:"constant.language.escape",regex:r},{token:"paren.quasi.start",regex:/\${/,push:"start"},{token:"string.quasi.end",regex:/`/,next:"pop"},{defaultToken:"string.quasi"}]}),(!e||e.jsx!=0)&&a.call(this);this.embedRules(i,"doc-",[i.getEndRule("no_regex")]),this.normalizeRules()};r.inherits(u,s),t.JavaScriptHighlightRules=u}),define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],function(e,t,n){"use strict";var r=e("../range").Range,i=function(){};(function(){this.checkOutdent=function(e,t){return/^\s+$/.test(e)?/^\s*\}/.test(t):!1},this.autoOutdent=function(e,t){var n=e.getLine(t),i=n.match(/^(\s*\})/);if(!i)return 0;var s=i[1].length,o=e.findMatchingBracket({row:t,column:s});if(!o||o.row==t)return 0;var u=this.$getIndent(e.getLine(o.row));e.replace(new r(t,0,t,s-1),u)},this.$getIndent=function(e){return e.match(/^\s*/)[0]}}).call(i.prototype),t.MatchingBraceOutdent=i}),define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../../range").Range,s=e("./fold_mode").FoldMode,o=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end)))};r.inherits(o,s),function(){this.foldingStartMarker=/(\{|\[)[^\}\]]*$|^\s*(\/\*)/,this.foldingStopMarker=/^[^\[\{]*(\}|\])|^[\s\*]*(\*\/)/,this.singleLineBlockCommentRe=/^\s*(\/\*).*\*\/\s*$/,this.tripleStarBlockCommentRe=/^\s*(\/\*\*\*).*\*\/\s*$/,this.startRegionRe=/^\s*(\/\*|\/\/)#?region\b/,this._getFoldWidgetBase=this.getFoldWidget,this.getFoldWidget=function(e,t,n){var r=e.getLine(n);if(this.singleLineBlockCommentRe.test(r)&&!this.startRegionRe.test(r)&&!this.tripleStarBlockCommentRe.test(r))return"";var i=this._getFoldWidgetBase(e,t,n);return!i&&this.startRegionRe.test(r)?"start":i},this.getFoldWidgetRange=function(e,t,n,r){var i=e.getLine(n);if(this.startRegionRe.test(i))return this.getCommentRegionBlock(e,i,n);var s=i.match(this.foldingStartMarker);if(s){var o=s.index;if(s[1])return this.openingBracketBlock(e,s[1],n,o);var u=e.getCommentFoldRange(n,o+s[0].length,1);return u&&!u.isMultiLine()&&(r?u=this.getSectionRange(e,n):t!="all"&&(u=null)),u}if(t==="markbegin")return;var s=i.match(this.foldingStopMarker);if(s){var o=s.index+s[0].length;return s[1]?this.closingBracketBlock(e,s[1],n,o):e.getCommentFoldRange(n,o,-1)}},this.getSectionRange=function(e,t){var n=e.getLine(t),r=n.search(/\S/),s=t,o=n.length;t+=1;var u=t,a=e.getLength();while(++tf)break;var l=this.getFoldWidgetRange(e,"all",t);if(l){if(l.start.row<=s)break;if(l.isMultiLine())t=l.end.row;else if(r==f)break}u=t}return new i(s,o,u,e.getLine(u).length)},this.getCommentRegionBlock=function(e,t,n){var r=t.search(/\s*$/),s=e.getLength(),o=n,u=/^\s*(?:\/\*|\/\/|--)#?(end)?region\b/,a=1;while(++no)return new i(o,r,l,t.length)}}.call(o.prototype)}),define("ace/mode/javascript",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/javascript_highlight_rules","ace/mode/matching_brace_outdent","ace/worker/worker_client","ace/mode/behaviour/cstyle","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./javascript_highlight_rules").JavaScriptHighlightRules,o=e("./matching_brace_outdent").MatchingBraceOutdent,u=e("../worker/worker_client").WorkerClient,a=e("./behaviour/cstyle").CstyleBehaviour,f=e("./folding/cstyle").FoldMode,l=function(){this.HighlightRules=s,this.$outdent=new o,this.$behaviour=new a,this.foldingRules=new f};r.inherits(l,i),function(){this.lineCommentStart="//",this.blockComment={start:"/*",end:"*/"},this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),i=this.getTokenizer().getLineTokens(t,e),s=i.tokens,o=i.state;if(s.length&&s[s.length-1].type=="comment")return r;if(e=="start"||e=="no_regex"){var u=t.match(/^.*(?:\bcase\b.*:|[\{\(\[])\s*$/);u&&(r+=n)}else if(e=="doc-start"){if(o=="start"||o=="no_regex")return"";var u=t.match(/^\s*(\/?)\*/);u&&(u[1]&&(r+=" "),r+="* ")}return r},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.createWorker=function(e){var t=new u(["ace"],"ace/mode/javascript_worker","JavaScriptWorker");return t.attachToDocument(e.getDocument()),t.on("annotate",function(t){e.setAnnotations(t.data)}),t.on("terminate",function(){e.clearAnnotations()}),t},this.$id="ace/mode/javascript"}.call(l.prototype),t.Mode=l}),define("ace/mode/css_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./text_highlight_rules").TextHighlightRules,o=t.supportType="align-content|align-items|align-self|all|animation|animation-delay|animation-direction|animation-duration|animation-fill-mode|animation-iteration-count|animation-name|animation-play-state|animation-timing-function|backface-visibility|background|background-attachment|background-blend-mode|background-clip|background-color|background-image|background-origin|background-position|background-repeat|background-size|border|border-bottom|border-bottom-color|border-bottom-left-radius|border-bottom-right-radius|border-bottom-style|border-bottom-width|border-collapse|border-color|border-image|border-image-outset|border-image-repeat|border-image-slice|border-image-source|border-image-width|border-left|border-left-color|border-left-style|border-left-width|border-radius|border-right|border-right-color|border-right-style|border-right-width|border-spacing|border-style|border-top|border-top-color|border-top-left-radius|border-top-right-radius|border-top-style|border-top-width|border-width|bottom|box-shadow|box-sizing|caption-side|clear|clip|color|column-count|column-fill|column-gap|column-rule|column-rule-color|column-rule-style|column-rule-width|column-span|column-width|columns|content|counter-increment|counter-reset|cursor|direction|display|empty-cells|filter|flex|flex-basis|flex-direction|flex-flow|flex-grow|flex-shrink|flex-wrap|float|font|font-family|font-size|font-size-adjust|font-stretch|font-style|font-variant|font-weight|hanging-punctuation|height|justify-content|left|letter-spacing|line-height|list-style|list-style-image|list-style-position|list-style-type|margin|margin-bottom|margin-left|margin-right|margin-top|max-height|max-width|min-height|min-width|nav-down|nav-index|nav-left|nav-right|nav-up|opacity|order|outline|outline-color|outline-offset|outline-style|outline-width|overflow|overflow-x|overflow-y|padding|padding-bottom|padding-left|padding-right|padding-top|page-break-after|page-break-before|page-break-inside|perspective|perspective-origin|position|quotes|resize|right|tab-size|table-layout|text-align|text-align-last|text-decoration|text-decoration-color|text-decoration-line|text-decoration-style|text-indent|text-justify|text-overflow|text-shadow|text-transform|top|transform|transform-origin|transform-style|transition|transition-delay|transition-duration|transition-property|transition-timing-function|unicode-bidi|vertical-align|visibility|white-space|width|word-break|word-spacing|word-wrap|z-index",u=t.supportFunction="rgb|rgba|url|attr|counter|counters",a=t.supportConstant="absolute|after-edge|after|all-scroll|all|alphabetic|always|antialiased|armenian|auto|avoid-column|avoid-page|avoid|balance|baseline|before-edge|before|below|bidi-override|block-line-height|block|bold|bolder|border-box|both|bottom|box|break-all|break-word|capitalize|caps-height|caption|center|central|char|circle|cjk-ideographic|clone|close-quote|col-resize|collapse|column|consider-shifts|contain|content-box|cover|crosshair|cubic-bezier|dashed|decimal-leading-zero|decimal|default|disabled|disc|disregard-shifts|distribute-all-lines|distribute-letter|distribute-space|distribute|dotted|double|e-resize|ease-in|ease-in-out|ease-out|ease|ellipsis|end|exclude-ruby|fill|fixed|georgian|glyphs|grid-height|groove|hand|hanging|hebrew|help|hidden|hiragana-iroha|hiragana|horizontal|icon|ideograph-alpha|ideograph-numeric|ideograph-parenthesis|ideograph-space|ideographic|inactive|include-ruby|inherit|initial|inline-block|inline-box|inline-line-height|inline-table|inline|inset|inside|inter-ideograph|inter-word|invert|italic|justify|katakana-iroha|katakana|keep-all|last|left|lighter|line-edge|line-through|line|linear|list-item|local|loose|lower-alpha|lower-greek|lower-latin|lower-roman|lowercase|lr-tb|ltr|mathematical|max-height|max-size|medium|menu|message-box|middle|move|n-resize|ne-resize|newspaper|no-change|no-close-quote|no-drop|no-open-quote|no-repeat|none|normal|not-allowed|nowrap|nw-resize|oblique|open-quote|outset|outside|overline|padding-box|page|pointer|pre-line|pre-wrap|pre|preserve-3d|progress|relative|repeat-x|repeat-y|repeat|replaced|reset-size|ridge|right|round|row-resize|rtl|s-resize|scroll|se-resize|separate|slice|small-caps|small-caption|solid|space|square|start|static|status-bar|step-end|step-start|steps|stretch|strict|sub|super|sw-resize|table-caption|table-cell|table-column-group|table-column|table-footer-group|table-header-group|table-row-group|table-row|table|tb-rl|text-after-edge|text-before-edge|text-bottom|text-size|text-top|text|thick|thin|transparent|underline|upper-alpha|upper-latin|upper-roman|uppercase|use-script|vertical-ideographic|vertical-text|visible|w-resize|wait|whitespace|z-index|zero",f=t.supportConstantColor="aqua|black|blue|fuchsia|gray|green|lime|maroon|navy|olive|orange|purple|red|silver|teal|white|yellow",l=t.supportConstantFonts="arial|century|comic|courier|cursive|fantasy|garamond|georgia|helvetica|impact|lucida|symbol|system|tahoma|times|trebuchet|utopia|verdana|webdings|sans-serif|serif|monospace",c=t.numRe="\\-?(?:(?:[0-9]+)|(?:[0-9]*\\.[0-9]+))",h=t.pseudoElements="(\\:+)\\b(after|before|first-letter|first-line|moz-selection|selection)\\b",p=t.pseudoClasses="(:)\\b(active|checked|disabled|empty|enabled|first-child|first-of-type|focus|hover|indeterminate|invalid|last-child|last-of-type|link|not|nth-child|nth-last-child|nth-last-of-type|nth-of-type|only-child|only-of-type|required|root|target|valid|visited)\\b",d=function(){var e=this.createKeywordMapper({"support.function":u,"support.constant":a,"support.type":o,"support.constant.color":f,"support.constant.fonts":l},"text",!0);this.$rules={start:[{token:"comment",regex:"\\/\\*",push:"comment"},{token:"paren.lparen",regex:"\\{",push:"ruleset"},{token:"string",regex:"@.*?{",push:"media"},{token:"keyword",regex:"#[a-z0-9-_]+"},{token:"variable",regex:"\\.[a-z0-9-_]+"},{token:"string",regex:":[a-z0-9-_]+"},{token:"constant",regex:"[a-z0-9-_]+"},{caseInsensitive:!0}],media:[{token:"comment",regex:"\\/\\*",push:"comment"},{token:"paren.lparen",regex:"\\{",push:"ruleset"},{token:"string",regex:"\\}",next:"pop"},{token:"keyword",regex:"#[a-z0-9-_]+"},{token:"variable",regex:"\\.[a-z0-9-_]+"},{token:"string",regex:":[a-z0-9-_]+"},{token:"constant",regex:"[a-z0-9-_]+"},{caseInsensitive:!0}],comment:[{token:"comment",regex:"\\*\\/",next:"pop"},{defaultToken:"comment"}],ruleset:[{token:"paren.rparen",regex:"\\}",next:"pop"},{token:"comment",regex:"\\/\\*",push:"comment"},{token:"string",regex:'["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]'},{token:"string",regex:"['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']"},{token:["constant.numeric","keyword"],regex:"("+c+")(ch|cm|deg|em|ex|fr|gd|grad|Hz|in|kHz|mm|ms|pc|pt|px|rad|rem|s|turn|vh|vm|vw|%)"},{token:"constant.numeric",regex:c},{token:"constant.numeric",regex:"#[a-f0-9]{6}"},{token:"constant.numeric",regex:"#[a-f0-9]{3}"},{token:["punctuation","entity.other.attribute-name.pseudo-element.css"],regex:h},{token:["punctuation","entity.other.attribute-name.pseudo-class.css"],regex:p},{token:["support.function","string","support.function"],regex:"(url\\()(.*)(\\))"},{token:e,regex:"\\-?[a-zA-Z_][a-zA-Z0-9_\\-]*"},{caseInsensitive:!0}]},this.normalizeRules()};r.inherits(d,s),t.CssHighlightRules=d}),define("ace/mode/css_completions",["require","exports","module"],function(e,t,n){"use strict";var r={background:{"#$0":1},"background-color":{"#$0":1,transparent:1,fixed:1},"background-image":{"url('/$0')":1},"background-repeat":{repeat:1,"repeat-x":1,"repeat-y":1,"no-repeat":1,inherit:1},"background-position":{bottom:2,center:2,left:2,right:2,top:2,inherit:2},"background-attachment":{scroll:1,fixed:1},"background-size":{cover:1,contain:1},"background-clip":{"border-box":1,"padding-box":1,"content-box":1},"background-origin":{"border-box":1,"padding-box":1,"content-box":1},border:{"solid $0":1,"dashed $0":1,"dotted $0":1,"#$0":1},"border-color":{"#$0":1},"border-style":{solid:2,dashed:2,dotted:2,"double":2,groove:2,hidden:2,inherit:2,inset:2,none:2,outset:2,ridged:2},"border-collapse":{collapse:1,separate:1},bottom:{px:1,em:1,"%":1},clear:{left:1,right:1,both:1,none:1},color:{"#$0":1,"rgb(#$00,0,0)":1},cursor:{"default":1,pointer:1,move:1,text:1,wait:1,help:1,progress:1,"n-resize":1,"ne-resize":1,"e-resize":1,"se-resize":1,"s-resize":1,"sw-resize":1,"w-resize":1,"nw-resize":1},display:{none:1,block:1,inline:1,"inline-block":1,"table-cell":1},"empty-cells":{show:1,hide:1},"float":{left:1,right:1,none:1},"font-family":{Arial:2,"Comic Sans MS":2,Consolas:2,"Courier New":2,Courier:2,Georgia:2,Monospace:2,"Sans-Serif":2,"Segoe UI":2,Tahoma:2,"Times New Roman":2,"Trebuchet MS":2,Verdana:1},"font-size":{px:1,em:1,"%":1},"font-weight":{bold:1,normal:1},"font-style":{italic:1,normal:1},"font-variant":{normal:1,"small-caps":1},height:{px:1,em:1,"%":1},left:{px:1,em:1,"%":1},"letter-spacing":{normal:1},"line-height":{normal:1},"list-style-type":{none:1,disc:1,circle:1,square:1,decimal:1,"decimal-leading-zero":1,"lower-roman":1,"upper-roman":1,"lower-greek":1,"lower-latin":1,"upper-latin":1,georgian:1,"lower-alpha":1,"upper-alpha":1},margin:{px:1,em:1,"%":1},"margin-right":{px:1,em:1,"%":1},"margin-left":{px:1,em:1,"%":1},"margin-top":{px:1,em:1,"%":1},"margin-bottom":{px:1,em:1,"%":1},"max-height":{px:1,em:1,"%":1},"max-width":{px:1,em:1,"%":1},"min-height":{px:1,em:1,"%":1},"min-width":{px:1,em:1,"%":1},overflow:{hidden:1,visible:1,auto:1,scroll:1},"overflow-x":{hidden:1,visible:1,auto:1,scroll:1},"overflow-y":{hidden:1,visible:1,auto:1,scroll:1},padding:{px:1,em:1,"%":1},"padding-top":{px:1,em:1,"%":1},"padding-right":{px:1,em:1,"%":1},"padding-bottom":{px:1,em:1,"%":1},"padding-left":{px:1,em:1,"%":1},"page-break-after":{auto:1,always:1,avoid:1,left:1,right:1},"page-break-before":{auto:1,always:1,avoid:1,left:1,right:1},position:{absolute:1,relative:1,fixed:1,"static":1},right:{px:1,em:1,"%":1},"table-layout":{fixed:1,auto:1},"text-decoration":{none:1,underline:1,"line-through":1,blink:1},"text-align":{left:1,right:1,center:1,justify:1},"text-transform":{capitalize:1,uppercase:1,lowercase:1,none:1},top:{px:1,em:1,"%":1},"vertical-align":{top:1,bottom:1},visibility:{hidden:1,visible:1},"white-space":{nowrap:1,normal:1,pre:1,"pre-line":1,"pre-wrap":1},width:{px:1,em:1,"%":1},"word-spacing":{normal:1},filter:{"alpha(opacity=$0100)":1},"text-shadow":{"$02px 2px 2px #777":1},"text-overflow":{"ellipsis-word":1,clip:1,ellipsis:1},"-moz-border-radius":1,"-moz-border-radius-topright":1,"-moz-border-radius-bottomright":1,"-moz-border-radius-topleft":1,"-moz-border-radius-bottomleft":1,"-webkit-border-radius":1,"-webkit-border-top-right-radius":1,"-webkit-border-top-left-radius":1,"-webkit-border-bottom-right-radius":1,"-webkit-border-bottom-left-radius":1,"-moz-box-shadow":1,"-webkit-box-shadow":1,transform:{"rotate($00deg)":1,"skew($00deg)":1},"-moz-transform":{"rotate($00deg)":1,"skew($00deg)":1},"-webkit-transform":{"rotate($00deg)":1,"skew($00deg)":1}},i=function(){};(function(){this.completionsDefined=!1,this.defineCompletions=function(){if(document){var e=document.createElement("c").style;for(var t in e){if(typeof e[t]!="string")continue;var n=t.replace(/[A-Z]/g,function(e){return"-"+e.toLowerCase()});r.hasOwnProperty(n)||(r[n]=1)}}this.completionsDefined=!0},this.getCompletions=function(e,t,n,r){this.completionsDefined||this.defineCompletions();var i=t.getTokenAt(n.row,n.column);if(!i)return[];if(e==="ruleset"){var s=t.getLine(n.row).substr(0,n.column);return/:[^;]+$/.test(s)?(/([\w\-]+):[^:]*$/.test(s),this.getPropertyValueCompletions(e,t,n,r)):this.getPropertyCompletions(e,t,n,r)}return[]},this.getPropertyCompletions=function(e,t,n,i){var s=Object.keys(r);return s.map(function(e){return{caption:e,snippet:e+": $0",meta:"property",score:Number.MAX_VALUE}})},this.getPropertyValueCompletions=function(e,t,n,i){var s=t.getLine(n.row).substr(0,n.column),o=(/([\w\-]+):[^:]*$/.exec(s)||{})[1];if(!o)return[];var u=[];return o in r&&typeof r[o]=="object"&&(u=Object.keys(r[o])),u.map(function(e){return{caption:e,snippet:e,meta:"property value",score:Number.MAX_VALUE}})}}).call(i.prototype),t.CssCompletions=i}),define("ace/mode/behaviour/css",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/mode/behaviour/cstyle","ace/token_iterator"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("./cstyle").CstyleBehaviour,o=e("../../token_iterator").TokenIterator,u=function(){this.inherit(s),this.add("colon","insertion",function(e,t,n,r,i){if(i===":"){var s=n.getCursorPosition(),u=new o(r,s.row,s.column),a=u.getCurrentToken();a&&a.value.match(/\s+/)&&(a=u.stepBackward());if(a&&a.type==="support.type"){var f=r.doc.getLine(s.row),l=f.substring(s.column,s.column+1);if(l===":")return{text:"",selection:[1,1]};if(!f.substring(s.column).match(/^\s*;/))return{text:":;",selection:[1,1]}}}}),this.add("colon","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s===":"){var u=n.getCursorPosition(),a=new o(r,u.row,u.column),f=a.getCurrentToken();f&&f.value.match(/\s+/)&&(f=a.stepBackward());if(f&&f.type==="support.type"){var l=r.doc.getLine(i.start.row),c=l.substring(i.end.column,i.end.column+1);if(c===";")return i.end.column++,i}}}),this.add("semicolon","insertion",function(e,t,n,r,i){if(i===";"){var s=n.getCursorPosition(),o=r.doc.getLine(s.row),u=o.substring(s.column,s.column+1);if(u===";")return{text:"",selection:[1,1]}}})};r.inherits(u,s),t.CssBehaviour=u}),define("ace/mode/css",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/css_highlight_rules","ace/mode/matching_brace_outdent","ace/worker/worker_client","ace/mode/css_completions","ace/mode/behaviour/css","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./css_highlight_rules").CssHighlightRules,o=e("./matching_brace_outdent").MatchingBraceOutdent,u=e("../worker/worker_client").WorkerClient,a=e("./css_completions").CssCompletions,f=e("./behaviour/css").CssBehaviour,l=e("./folding/cstyle").FoldMode,c=function(){this.HighlightRules=s,this.$outdent=new o,this.$behaviour=new f,this.$completer=new a,this.foldingRules=new l};r.inherits(c,i),function(){this.foldingRules="cStyle",this.blockComment={start:"/*",end:"*/"},this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),i=this.getTokenizer().getLineTokens(t,e).tokens;if(i.length&&i[i.length-1].type=="comment")return r;var s=t.match(/^.*\{\s*$/);return s&&(r+=n),r},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.getCompletions=function(e,t,n,r){return this.$completer.getCompletions(e,t,n,r)},this.createWorker=function(e){var t=new u(["ace"],"ace/mode/css_worker","Worker");return t.attachToDocument(e.getDocument()),t.on("annotate",function(t){e.setAnnotations(t.data)}),t.on("terminate",function(){e.clearAnnotations()}),t},this.$id="ace/mode/css"}.call(c.prototype),t.Mode=c}),define("ace/mode/xml_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(e){var t="[_:a-zA-Z\u00c0-\uffff][-_:.a-zA-Z0-9\u00c0-\uffff]*";this.$rules={start:[{token:"string.cdata.xml",regex:"<\\!\\[CDATA\\[",next:"cdata"},{token:["punctuation.xml-decl.xml","keyword.xml-decl.xml"],regex:"(<\\?)(xml)(?=[\\s])",next:"xml_decl",caseInsensitive:!0},{token:["punctuation.instruction.xml","keyword.instruction.xml"],regex:"(<\\?)("+t+")",next:"processing_instruction"},{token:"comment.xml",regex:"<\\!--",next:"comment"},{token:["xml-pe.doctype.xml","xml-pe.doctype.xml"],regex:"(<\\!)(DOCTYPE)(?=[\\s])",next:"doctype",caseInsensitive:!0},{include:"tag"},{token:"text.end-tag-open.xml",regex:"",next:"start"}],processing_instruction:[{token:"punctuation.instruction.xml",regex:"\\?>",next:"start"},{defaultToken:"instruction.xml"}],doctype:[{include:"whitespace"},{include:"string"},{token:"xml-pe.doctype.xml",regex:">",next:"start"},{token:"xml-pe.xml",regex:"[-_a-zA-Z0-9:]+"},{token:"punctuation.int-subset",regex:"\\[",push:"int_subset"}],int_subset:[{token:"text.xml",regex:"\\s+"},{token:"punctuation.int-subset.xml",regex:"]",next:"pop"},{token:["punctuation.markup-decl.xml","keyword.markup-decl.xml"],regex:"(<\\!)("+t+")",push:[{token:"text",regex:"\\s+"},{token:"punctuation.markup-decl.xml",regex:">",next:"pop"},{include:"string"}]}],cdata:[{token:"string.cdata.xml",regex:"\\]\\]>",next:"start"},{token:"text.xml",regex:"\\s+"},{token:"text.xml",regex:"(?:[^\\]]|\\](?!\\]>))+"}],comment:[{token:"comment.xml",regex:"-->",next:"start"},{defaultToken:"comment.xml"}],reference:[{token:"constant.language.escape.reference.xml",regex:"(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)"}],attr_reference:[{token:"constant.language.escape.reference.attribute-value.xml",regex:"(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)"}],tag:[{token:["meta.tag.punctuation.tag-open.xml","meta.tag.punctuation.end-tag-open.xml","meta.tag.tag-name.xml"],regex:"(?:(<)|(",next:"start"}]}],tag_whitespace:[{token:"text.tag-whitespace.xml",regex:"\\s+"}],whitespace:[{token:"text.whitespace.xml",regex:"\\s+"}],string:[{token:"string.xml",regex:"'",push:[{token:"string.xml",regex:"'",next:"pop"},{defaultToken:"string.xml"}]},{token:"string.xml",regex:'"',push:[{token:"string.xml",regex:'"',next:"pop"},{defaultToken:"string.xml"}]}],attributes:[{token:"entity.other.attribute-name.xml",regex:"(?:"+t+":)?"+t+""},{token:"keyword.operator.attribute-equals.xml",regex:"="},{include:"tag_whitespace"},{include:"attribute_value"}],attribute_value:[{token:"string.attribute-value.xml",regex:"'",push:[{token:"string.attribute-value.xml",regex:"'",next:"pop"},{include:"attr_reference"},{defaultToken:"string.attribute-value.xml"}]},{token:"string.attribute-value.xml",regex:'"',push:[{token:"string.attribute-value.xml",regex:'"',next:"pop"},{include:"attr_reference"},{defaultToken:"string.attribute-value.xml"}]}]},this.constructor===s&&this.normalizeRules()};(function(){this.embedTagRules=function(e,t,n){this.$rules.tag.unshift({token:["meta.tag.punctuation.tag-open.xml","meta.tag."+n+".tag-name.xml"],regex:"(<)("+n+"(?=\\s|>|$))",next:[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:t+"start"}]}),this.$rules[n+"-end"]=[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:"start",onMatch:function(e,t,n){return n.splice(0),this.token}}],this.embedRules(e,t,[{token:["meta.tag.punctuation.end-tag-open.xml","meta.tag."+n+".tag-name.xml"],regex:"(|$))",next:n+"-end"},{token:"string.cdata.xml",regex:"<\\!\\[CDATA\\["},{token:"string.cdata.xml",regex:"\\]\\]>"}])}}).call(i.prototype),r.inherits(s,i),t.XmlHighlightRules=s}),define("ace/mode/html_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/css_highlight_rules","ace/mode/javascript_highlight_rules","ace/mode/xml_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./css_highlight_rules").CssHighlightRules,o=e("./javascript_highlight_rules").JavaScriptHighlightRules,u=e("./xml_highlight_rules").XmlHighlightRules,a=i.createMap({a:"anchor",button:"form",form:"form",img:"image",input:"form",label:"form",option:"form",script:"script",select:"form",textarea:"form",style:"style",table:"table",tbody:"table",td:"table",tfoot:"table",th:"table",tr:"table"}),f=function(){u.call(this),this.addRules({attributes:[{include:"tag_whitespace"},{token:"entity.other.attribute-name.xml",regex:"[-_a-zA-Z0-9:.]+"},{token:"keyword.operator.attribute-equals.xml",regex:"=",push:[{include:"tag_whitespace"},{token:"string.unquoted.attribute-value.html",regex:"[^<>='\"`\\s]+",next:"pop"},{token:"empty",regex:"",next:"pop"}]},{include:"attribute_value"}],tag:[{token:function(e,t){var n=a[t];return["meta.tag.punctuation."+(e=="<"?"":"end-")+"tag-open.xml","meta.tag"+(n?"."+n:"")+".tag-name.xml"]},regex:"(",next:"start"}]}),this.embedTagRules(s,"css-","style"),this.embedTagRules((new o({jsx:!1})).getRules(),"js-","script"),this.constructor===f&&this.normalizeRules()};r.inherits(f,u),t.HtmlHighlightRules=f}),define("ace/mode/behaviour/xml",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator","ace/lib/lang"],function(e,t,n){"use strict";function u(e,t){return e.type.lastIndexOf(t+".xml")>-1}var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("../../token_iterator").TokenIterator,o=e("../../lib/lang"),a=function(){this.add("string_dquotes","insertion",function(e,t,n,r,i){if(i=='"'||i=="'"){var o=i,a=r.doc.getTextRange(n.getSelectionRange());if(a!==""&&a!=="'"&&a!='"'&&n.getWrapBehavioursEnabled())return{text:o+a+o,selection:!1};var f=n.getCursorPosition(),l=r.doc.getLine(f.row),c=l.substring(f.column,f.column+1),h=new s(r,f.row,f.column),p=h.getCurrentToken();if(c==o&&(u(p,"attribute-value")||u(p,"string")))return{text:"",selection:[1,1]};p||(p=h.stepBackward());if(!p)return;while(u(p,"tag-whitespace")||u(p,"whitespace"))p=h.stepBackward();var d=!c||c.match(/\s/);if(u(p,"attribute-equals")&&(d||c==">")||u(p,"decl-attribute-equals")&&(d||c=="?"))return{text:o+o,selection:[1,1]}}}),this.add("string_dquotes","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&(s=='"'||s=="'")){var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==s)return i.end.column++,i}}),this.add("autoclosing","insertion",function(e,t,n,r,i){if(i==">"){var o=n.getSelectionRange().start,a=new s(r,o.row,o.column),f=a.getCurrentToken()||a.stepBackward();if(!f||!(u(f,"tag-name")||u(f,"tag-whitespace")||u(f,"attribute-name")||u(f,"attribute-equals")||u(f,"attribute-value")))return;if(u(f,"reference.attribute-value"))return;if(u(f,"attribute-value")){var l=f.value.charAt(0);if(l=='"'||l=="'"){var c=f.value.charAt(f.value.length-1),h=a.getCurrentTokenColumn()+f.value.length;if(h>o.column||h==o.column&&l!=c)return}}while(!u(f,"tag-name")){f=a.stepBackward();if(f.value=="<"){f=a.stepForward();break}}var p=a.getCurrentTokenRow(),d=a.getCurrentTokenColumn();if(u(a.stepBackward(),"end-tag-open"))return;var v=f.value;p==o.row&&(v=v.substring(0,o.column-d));if(this.voidElements.hasOwnProperty(v.toLowerCase()))return;return{text:">",selection:[1,1]}}}),this.add("autoindent","insertion",function(e,t,n,r,i){if(i=="\n"){var o=n.getCursorPosition(),u=r.getLine(o.row),a=new s(r,o.row,o.column),f=a.getCurrentToken();if(f&&f.type.indexOf("tag-close")!==-1){if(f.value=="/>")return;while(f&&f.type.indexOf("tag-name")===-1)f=a.stepBackward();if(!f)return;var l=f.value,c=a.getCurrentTokenRow();f=a.stepBackward();if(!f||f.type.indexOf("end-tag")!==-1)return;if(this.voidElements&&!this.voidElements[l]){var h=r.getTokenAt(o.row,o.column+1),u=r.getLine(c),p=this.$getIndent(u),d=p+r.getTabString();return h&&h.value==="-1}var r=e("../../lib/oop"),i=e("../../lib/lang"),s=e("../../range").Range,o=e("./fold_mode").FoldMode,u=e("../../token_iterator").TokenIterator,a=t.FoldMode=function(e,t){o.call(this),this.voidElements=e||{},this.optionalEndTags=r.mixin({},this.voidElements),t&&r.mixin(this.optionalEndTags,t)};r.inherits(a,o);var f=function(){this.tagName="",this.closing=!1,this.selfClosing=!1,this.start={row:0,column:0},this.end={row:0,column:0}};(function(){this.getFoldWidget=function(e,t,n){var r=this._getFirstTagInLine(e,n);return r?r.closing||!r.tagName&&r.selfClosing?t=="markbeginend"?"end":"":!r.tagName||r.selfClosing||this.voidElements.hasOwnProperty(r.tagName.toLowerCase())?"":this._findEndTagInLine(e,n,r.tagName,r.end.column)?"":"start":""},this._getFirstTagInLine=function(e,t){var n=e.getTokens(t),r=new f;for(var i=0;i";break}}return r}if(l(s,"tag-close"))return r.selfClosing=s.value=="/>",r;r.start.column+=s.value.length}return null},this._findEndTagInLine=function(e,t,n,r){var i=e.getTokens(t),s=0;for(var o=0;o",n.end.row=e.getCurrentTokenRow(),n.end.column=e.getCurrentTokenColumn()+t.value.length,e.stepForward(),n;while(t=e.stepForward());return null},this._readTagBackward=function(e){var t=e.getCurrentToken();if(!t)return null;var n=new f;do{if(l(t,"tag-open"))return n.closing=l(t,"end-tag-open"),n.start.row=e.getCurrentTokenRow(),n.start.column=e.getCurrentTokenColumn(),e.stepBackward(),n;l(t,"tag-name")?n.tagName=t.value:l(t,"tag-close")&&(n.selfClosing=t.value=="/>",n.end.row=e.getCurrentTokenRow(),n.end.column=e.getCurrentTokenColumn()+t.value.length)}while(t=e.stepBackward());return null},this._pop=function(e,t){while(e.length){var n=e[e.length-1];if(!t||n.tagName==t.tagName)return e.pop();if(this.optionalEndTags.hasOwnProperty(n.tagName)){e.pop();continue}return null}},this.getFoldWidgetRange=function(e,t,n){var r=this._getFirstTagInLine(e,n);if(!r)return null;var i=r.closing||r.selfClosing,o=[],a;if(!i){var f=new u(e,n,r.start.column),l={row:n,column:r.start.column+r.tagName.length+2};r.start.row==r.end.row&&(l.column=r.end.column);while(a=this._readTagForward(f)){if(a.selfClosing){if(!o.length)return a.start.column+=a.tagName.length+2,a.end.column-=2,s.fromPoints(a.start,a.end);continue}if(a.closing){this._pop(o,a);if(o.length==0)return s.fromPoints(l,a.start)}else o.push(a)}}else{var f=new u(e,n,r.end.column),c={row:n,column:r.start.column};while(a=this._readTagBackward(f)){if(a.selfClosing){if(!o.length)return a.start.column+=a.tagName.length+2,a.end.column-=2,s.fromPoints(a.start,a.end);continue}if(!a.closing){this._pop(o,a);if(o.length==0)return a.start.column+=a.tagName.length+2,a.start.row==a.end.row&&a.start.column-1}function l(e,t){var n=new r(e,t.row,t.column),i=n.getCurrentToken();while(i&&!f(i,"tag-name"))i=n.stepBackward();if(i)return i.value}function c(e,t){var n=new r(e,t.row,t.column),i=n.getCurrentToken();while(i&&!f(i,"attribute-name"))i=n.stepBackward();if(i)return i.value}var r=e("../token_iterator").TokenIterator,i=["accesskey","class","contenteditable","contextmenu","dir","draggable","dropzone","hidden","id","inert","itemid","itemprop","itemref","itemscope","itemtype","lang","spellcheck","style","tabindex","title","translate"],s=["onabort","onblur","oncancel","oncanplay","oncanplaythrough","onchange","onclick","onclose","oncontextmenu","oncuechange","ondblclick","ondrag","ondragend","ondragenter","ondragleave","ondragover","ondragstart","ondrop","ondurationchange","onemptied","onended","onerror","onfocus","oninput","oninvalid","onkeydown","onkeypress","onkeyup","onload","onloadeddata","onloadedmetadata","onloadstart","onmousedown","onmousemove","onmouseout","onmouseover","onmouseup","onmousewheel","onpause","onplay","onplaying","onprogress","onratechange","onreset","onscroll","onseeked","onseeking","onselect","onshow","onstalled","onsubmit","onsuspend","ontimeupdate","onvolumechange","onwaiting"],o=i.concat(s),u={html:{manifest:1},head:{},title:{},base:{href:1,target:1},link:{href:1,hreflang:1,rel:{stylesheet:1,icon:1},media:{all:1,screen:1,print:1},type:{"text/css":1,"image/png":1,"image/jpeg":1,"image/gif":1},sizes:1},meta:{"http-equiv":{"content-type":1},name:{description:1,keywords:1},content:{"text/html; charset=UTF-8":1},charset:1},style:{type:1,media:{all:1,screen:1,print:1},scoped:1},script:{charset:1,type:{"text/javascript":1},src:1,defer:1,async:1},noscript:{href:1},body:{onafterprint:1,onbeforeprint:1,onbeforeunload:1,onhashchange:1,onmessage:1,onoffline:1,onpopstate:1,onredo:1,onresize:1,onstorage:1,onundo:1,onunload:1},section:{},nav:{},article:{pubdate:1},aside:{},h1:{},h2:{},h3:{},h4:{},h5:{},h6:{},header:{},footer:{},address:{},main:{},p:{},hr:{},pre:{},blockquote:{cite:1},ol:{start:1,reversed:1},ul:{},li:{value:1},dl:{},dt:{},dd:{},figure:{},figcaption:{},div:{},a:{href:1,target:{_blank:1,top:1},ping:1,rel:{nofollow:1,alternate:1,author:1,bookmark:1,help:1,license:1,next:1,noreferrer:1,prefetch:1,prev:1,search:1,tag:1},media:1,hreflang:1,type:1},em:{},strong:{},small:{},s:{},cite:{},q:{cite:1},dfn:{},abbr:{},data:{},time:{datetime:1},code:{},"var":{},samp:{},kbd:{},sub:{},sup:{},i:{},b:{},u:{},mark:{},ruby:{},rt:{},rp:{},bdi:{},bdo:{},span:{},br:{},wbr:{},ins:{cite:1,datetime:1},del:{cite:1,datetime:1},img:{alt:1,src:1,height:1,width:1,usemap:1,ismap:1},iframe:{name:1,src:1,height:1,width:1,sandbox:{"allow-same-origin":1,"allow-top-navigation":1,"allow-forms":1,"allow-scripts":1},seamless:{seamless:1}},embed:{src:1,height:1,width:1,type:1},object:{param:1,data:1,type:1,height:1,width:1,usemap:1,name:1,form:1,classid:1},param:{name:1,value:1},video:{src:1,autobuffer:1,autoplay:{autoplay:1},loop:{loop:1},controls:{controls:1},width:1,height:1,poster:1,muted:{muted:1},preload:{auto:1,metadata:1,none:1}},audio:{src:1,autobuffer:1,autoplay:{autoplay:1},loop:{loop:1},controls:{controls:1},muted:{muted:1},preload:{auto:1,metadata:1,none:1}},source:{src:1,type:1,media:1},track:{kind:1,src:1,srclang:1,label:1,"default":1},canvas:{width:1,height:1},map:{name:1},area:{shape:1,coords:1,href:1,hreflang:1,alt:1,target:1,media:1,rel:1,ping:1,type:1},svg:{},math:{},table:{summary:1},caption:{},colgroup:{span:1},col:{span:1},tbody:{},thead:{},tfoot:{},tr:{},td:{headers:1,rowspan:1,colspan:1},th:{headers:1,rowspan:1,colspan:1,scope:1},form:{"accept-charset":1,action:1,autocomplete:1,enctype:{"multipart/form-data":1,"application/x-www-form-urlencoded":1},method:{get:1,post:1},name:1,novalidate:1,target:{_blank:1,top:1}},fieldset:{disabled:1,form:1,name:1},legend:{},label:{form:1,"for":1},input:{type:{text:1,password:1,hidden:1,checkbox:1,submit:1,radio:1,file:1,button:1,reset:1,image:31,color:1,date:1,datetime:1,"datetime-local":1,email:1,month:1,number:1,range:1,search:1,tel:1,time:1,url:1,week:1},accept:1,alt:1,autocomplete:{on:1,off:1},autofocus:{autofocus:1},checked:{checked:1},disabled:{disabled:1},form:1,formaction:1,formenctype:{"application/x-www-form-urlencoded":1,"multipart/form-data":1,"text/plain":1},formmethod:{get:1,post:1},formnovalidate:{formnovalidate:1},formtarget:{_blank:1,_self:1,_parent:1,_top:1},height:1,list:1,max:1,maxlength:1,min:1,multiple:{multiple:1},name:1,pattern:1,placeholder:1,readonly:{readonly:1},required:{required:1},size:1,src:1,step:1,width:1,files:1,value:1},button:{autofocus:1,disabled:{disabled:1},form:1,formaction:1,formenctype:1,formmethod:1,formnovalidate:1,formtarget:1,name:1,value:1,type:{button:1,submit:1}},select:{autofocus:1,disabled:1,form:1,multiple:{multiple:1},name:1,size:1,readonly:{readonly:1}},datalist:{},optgroup:{disabled:1,label:1},option:{disabled:1,selected:1,label:1,value:1},textarea:{autofocus:{autofocus:1},disabled:{disabled:1},form:1,maxlength:1,name:1,placeholder:1,readonly:{readonly:1},required:{required:1},rows:1,cols:1,wrap:{on:1,off:1,hard:1,soft:1}},keygen:{autofocus:1,challenge:{challenge:1},disabled:{disabled:1},form:1,keytype:{rsa:1,dsa:1,ec:1},name:1},output:{"for":1,form:1,name:1},progress:{value:1,max:1},meter:{value:1,min:1,max:1,low:1,high:1,optimum:1},details:{open:1},summary:{},command:{type:1,label:1,icon:1,disabled:1,checked:1,radiogroup:1,command:1},menu:{type:1,label:1},dialog:{open:1}},a=Object.keys(u),h=function(){};(function(){this.getCompletions=function(e,t,n,r){var i=t.getTokenAt(n.row,n.column);if(!i)return[];if(f(i,"tag-name")||f(i,"tag-open")||f(i,"end-tag-open"))return this.getTagCompletions(e,t,n,r);if(f(i,"tag-whitespace")||f(i,"attribute-name"))return this.getAttributeCompletions(e,t,n,r);if(f(i,"attribute-value"))return this.getAttributeValueCompletions(e,t,n,r);var s=t.getLine(n.row).substr(0,n.column);return/&[a-z]*$/i.test(s)?this.getHTMLEntityCompletions(e,t,n,r):[]},this.getTagCompletions=function(e,t,n,r){return a.map(function(e){return{value:e,meta:"tag",score:Number.MAX_VALUE}})},this.getAttributeCompletions=function(e,t,n,r){var i=l(t,n);if(!i)return[];var s=o;return i in u&&(s=s.concat(Object.keys(u[i]))),s.map(function(e){return{caption:e,snippet:e+'="$0"',meta:"attribute",score:Number.MAX_VALUE}})},this.getAttributeValueCompletions=function(e,t,n,r){var i=l(t,n),s=c(t,n);if(!i)return[];var o=[];return i in u&&s in u[i]&&typeof u[i][s]=="object"&&(o=Object.keys(u[i][s])),o.map(function(e){return{caption:e,snippet:e,meta:"attribute value",score:Number.MAX_VALUE}})},this.getHTMLEntityCompletions=function(e,t,n,r){var i=["Aacute;","aacute;","Acirc;","acirc;","acute;","AElig;","aelig;","Agrave;","agrave;","alefsym;","Alpha;","alpha;","amp;","and;","ang;","Aring;","aring;","asymp;","Atilde;","atilde;","Auml;","auml;","bdquo;","Beta;","beta;","brvbar;","bull;","cap;","Ccedil;","ccedil;","cedil;","cent;","Chi;","chi;","circ;","clubs;","cong;","copy;","crarr;","cup;","curren;","Dagger;","dagger;","dArr;","darr;","deg;","Delta;","delta;","diams;","divide;","Eacute;","eacute;","Ecirc;","ecirc;","Egrave;","egrave;","empty;","emsp;","ensp;","Epsilon;","epsilon;","equiv;","Eta;","eta;","ETH;","eth;","Euml;","euml;","euro;","exist;","fnof;","forall;","frac12;","frac14;","frac34;","frasl;","Gamma;","gamma;","ge;","gt;","hArr;","harr;","hearts;","hellip;","Iacute;","iacute;","Icirc;","icirc;","iexcl;","Igrave;","igrave;","image;","infin;","int;","Iota;","iota;","iquest;","isin;","Iuml;","iuml;","Kappa;","kappa;","Lambda;","lambda;","lang;","laquo;","lArr;","larr;","lceil;","ldquo;","le;","lfloor;","lowast;","loz;","lrm;","lsaquo;","lsquo;","lt;","macr;","mdash;","micro;","middot;","minus;","Mu;","mu;","nabla;","nbsp;","ndash;","ne;","ni;","not;","notin;","nsub;","Ntilde;","ntilde;","Nu;","nu;","Oacute;","oacute;","Ocirc;","ocirc;","OElig;","oelig;","Ograve;","ograve;","oline;","Omega;","omega;","Omicron;","omicron;","oplus;","or;","ordf;","ordm;","Oslash;","oslash;","Otilde;","otilde;","otimes;","Ouml;","ouml;","para;","part;","permil;","perp;","Phi;","phi;","Pi;","pi;","piv;","plusmn;","pound;","Prime;","prime;","prod;","prop;","Psi;","psi;","quot;","radic;","rang;","raquo;","rArr;","rarr;","rceil;","rdquo;","real;","reg;","rfloor;","Rho;","rho;","rlm;","rsaquo;","rsquo;","sbquo;","Scaron;","scaron;","sdot;","sect;","shy;","Sigma;","sigma;","sigmaf;","sim;","spades;","sub;","sube;","sum;","sup;","sup1;","sup2;","sup3;","supe;","szlig;","Tau;","tau;","there4;","Theta;","theta;","thetasym;","thinsp;","THORN;","thorn;","tilde;","times;","trade;","Uacute;","uacute;","uArr;","uarr;","Ucirc;","ucirc;","Ugrave;","ugrave;","uml;","upsih;","Upsilon;","upsilon;","Uuml;","uuml;","weierp;","Xi;","xi;","Yacute;","yacute;","yen;","Yuml;","yuml;","Zeta;","zeta;","zwj;","zwnj;"];return i.map(function(e){return{caption:e,snippet:e,meta:"html entity",score:Number.MAX_VALUE}})}}).call(h.prototype),t.HtmlCompletions=h}),define("ace/mode/html",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/text","ace/mode/javascript","ace/mode/css","ace/mode/html_highlight_rules","ace/mode/behaviour/xml","ace/mode/folding/html","ace/mode/html_completions","ace/worker/worker_client"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./text").Mode,o=e("./javascript").Mode,u=e("./css").Mode,a=e("./html_highlight_rules").HtmlHighlightRules,f=e("./behaviour/xml").XmlBehaviour,l=e("./folding/html").FoldMode,c=e("./html_completions").HtmlCompletions,h=e("../worker/worker_client").WorkerClient,p=["area","base","br","col","embed","hr","img","input","keygen","link","meta","menuitem","param","source","track","wbr"],d=["li","dt","dd","p","rt","rp","optgroup","option","colgroup","td","th"],v=function(e){this.fragmentContext=e&&e.fragmentContext,this.HighlightRules=a,this.$behaviour=new f,this.$completer=new c,this.createModeDelegates({"js-":o,"css-":u}),this.foldingRules=new l(this.voidElements,i.arrayToMap(d))};r.inherits(v,s),function(){this.blockComment={start:""},this.voidElements=i.arrayToMap(p),this.getNextLineIndent=function(e,t,n){return this.$getIndent(t)},this.checkOutdent=function(e,t,n){return!1},this.getCompletions=function(e,t,n,r){return this.$completer.getCompletions(e,t,n,r)},this.createWorker=function(e){if(this.constructor!=v)return;var t=new h(["ace"],"ace/mode/html_worker","Worker");return t.attachToDocument(e.getDocument()),this.fragmentContext&&t.call("setOptions",[{context:this.fragmentContext}]),t.on("error",function(t){e.setAnnotations(t.data)}),t.on("terminate",function(){e.clearAnnotations()}),t},this.$id="ace/mode/html"}.call(v.prototype),t.Mode=v}) \ No newline at end of file diff --git a/examples/SmartSwitch/data_src/js_css_src/mode-javascript.js b/examples/SmartSwitch/data_src/js_css_src/mode-javascript.js new file mode 100644 index 000000000..6bad9f609 --- /dev/null +++ b/examples/SmartSwitch/data_src/js_css_src/mode-javascript.js @@ -0,0 +1 @@ +ace.define("ace/mode/doc_comment_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){this.$rules={start:[{token:"comment.doc.tag",regex:"@[\\w\\d_]+"},s.getTagRule(),{defaultToken:"comment.doc",caseInsensitive:!0}]}};r.inherits(s,i),s.getTagRule=function(e){return{token:"comment.doc.tag.storage.type",regex:"\\b(?:TODO|FIXME|XXX|HACK)\\b"}},s.getStartRule=function(e){return{token:"comment.doc",regex:"\\/\\*(?=\\*)",next:e}},s.getEndRule=function(e){return{token:"comment.doc",regex:"\\*\\/",next:e}},t.DocCommentHighlightRules=s}),ace.define("ace/mode/javascript_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/doc_comment_highlight_rules","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";function a(){var e=o.replace("\\d","\\d\\-"),t={onMatch:function(e,t,n){var r=e.charAt(1)=="/"?2:1;if(r==1)t!=this.nextState?n.unshift(this.next,this.nextState,0):n.unshift(this.next),n[2]++;else if(r==2&&t==this.nextState){n[1]--;if(!n[1]||n[1]<0)n.shift(),n.shift()}return[{type:"meta.tag.punctuation."+(r==1?"":"end-")+"tag-open.xml",value:e.slice(0,r)},{type:"meta.tag.tag-name.xml",value:e.substr(r)}]},regex:"",onMatch:function(e,t,n){return t==n[0]&&n.shift(),e.length==2&&(n[0]==this.nextState&&n[1]--,(!n[1]||n[1]<0)&&n.splice(0,2)),this.next=n[0]||"start",[{type:this.token,value:e}]},nextState:"jsx"},n,f("jsxAttributes"),{token:"entity.other.attribute-name.xml",regex:e},{token:"keyword.operator.attribute-equals.xml",regex:"="},{token:"text.tag-whitespace.xml",regex:"\\s+"},{token:"string.attribute-value.xml",regex:"'",stateName:"jsx_attr_q",push:[{token:"string.attribute-value.xml",regex:"'",next:"pop"},{include:"reference"},{defaultToken:"string.attribute-value.xml"}]},{token:"string.attribute-value.xml",regex:'"',stateName:"jsx_attr_qq",push:[{token:"string.attribute-value.xml",regex:'"',next:"pop"},{include:"reference"},{defaultToken:"string.attribute-value.xml"}]},t],this.$rules.reference=[{token:"constant.language.escape.reference.xml",regex:"(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)"}]}function f(e){return[{token:"comment",regex:/\/\*/,next:[i.getTagRule(),{token:"comment",regex:"\\*\\/",next:e||"pop"},{defaultToken:"comment",caseInsensitive:!0}]},{token:"comment",regex:"\\/\\/",next:[i.getTagRule(),{token:"comment",regex:"$|^",next:e||"pop"},{defaultToken:"comment",caseInsensitive:!0}]}]}var r=e("../lib/oop"),i=e("./doc_comment_highlight_rules").DocCommentHighlightRules,s=e("./text_highlight_rules").TextHighlightRules,o="[a-zA-Z\\$_\u00a1-\uffff][a-zA-Z\\d\\$_\u00a1-\uffff]*",u=function(e){var t=this.createKeywordMapper({"variable.language":"Array|Boolean|Date|Function|Iterator|Number|Object|RegExp|String|Proxy|Namespace|QName|XML|XMLList|ArrayBuffer|Float32Array|Float64Array|Int16Array|Int32Array|Int8Array|Uint16Array|Uint32Array|Uint8Array|Uint8ClampedArray|Error|EvalError|InternalError|RangeError|ReferenceError|StopIteration|SyntaxError|TypeError|URIError|decodeURI|decodeURIComponent|encodeURI|encodeURIComponent|eval|isFinite|isNaN|parseFloat|parseInt|JSON|Math|this|arguments|prototype|window|document",keyword:"const|yield|import|get|set|async|await|break|case|catch|continue|default|delete|do|else|finally|for|function|if|in|of|instanceof|new|return|switch|throw|try|typeof|let|var|while|with|debugger|__parent__|__count__|escape|unescape|with|__proto__|class|enum|extends|super|export|implements|private|public|interface|package|protected|static","storage.type":"const|let|var|function","constant.language":"null|Infinity|NaN|undefined","support.function":"alert","constant.language.boolean":"true|false"},"identifier"),n="case|do|else|finally|in|instanceof|return|throw|try|typeof|yield|void",r="\\\\(?:x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|u{[0-9a-fA-F]{1,6}}|[0-2][0-7]{0,2}|3[0-7][0-7]?|[4-7][0-7]?|.)";this.$rules={no_regex:[i.getStartRule("doc-start"),f("no_regex"),{token:"string",regex:"'(?=.)",next:"qstring"},{token:"string",regex:'"(?=.)',next:"qqstring"},{token:"constant.numeric",regex:/0(?:[xX][0-9a-fA-F]+|[bB][01]+)\b/},{token:"constant.numeric",regex:/[+-]?\d[\d_]*(?:(?:\.\d*)?(?:[eE][+-]?\d+)?)?\b/},{token:["storage.type","punctuation.operator","support.function","punctuation.operator","entity.name.function","text","keyword.operator"],regex:"("+o+")(\\.)(prototype)(\\.)("+o+")(\\s*)(=)",next:"function_arguments"},{token:["storage.type","punctuation.operator","entity.name.function","text","keyword.operator","text","storage.type","text","paren.lparen"],regex:"("+o+")(\\.)("+o+")(\\s*)(=)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["entity.name.function","text","keyword.operator","text","storage.type","text","paren.lparen"],regex:"("+o+")(\\s*)(=)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["storage.type","punctuation.operator","entity.name.function","text","keyword.operator","text","storage.type","text","entity.name.function","text","paren.lparen"],regex:"("+o+")(\\.)("+o+")(\\s*)(=)(\\s*)(function)(\\s+)(\\w+)(\\s*)(\\()",next:"function_arguments"},{token:["storage.type","text","entity.name.function","text","paren.lparen"],regex:"(function)(\\s+)("+o+")(\\s*)(\\()",next:"function_arguments"},{token:["entity.name.function","text","punctuation.operator","text","storage.type","text","paren.lparen"],regex:"("+o+")(\\s*)(:)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["text","text","storage.type","text","paren.lparen"],regex:"(:)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:"keyword",regex:"(?:"+n+")\\b",next:"start"},{token:["support.constant"],regex:/that\b/},{token:["storage.type","punctuation.operator","support.function.firebug"],regex:/(console)(\.)(warn|info|log|error|time|trace|timeEnd|assert)\b/},{token:t,regex:o},{token:"punctuation.operator",regex:/[.](?![.])/,next:"property"},{token:"keyword.operator",regex:/--|\+\+|\.{3}|===|==|=|!=|!==|<+=?|>+=?|!|&&|\|\||\?:|[!$%&*+\-~\/^]=?/,next:"start"},{token:"punctuation.operator",regex:/[?:,;.]/,next:"start"},{token:"paren.lparen",regex:/[\[({]/,next:"start"},{token:"paren.rparen",regex:/[\])}]/},{token:"comment",regex:/^#!.*$/}],property:[{token:"text",regex:"\\s+"},{token:["storage.type","punctuation.operator","entity.name.function","text","keyword.operator","text","storage.type","text","entity.name.function","text","paren.lparen"],regex:"("+o+")(\\.)("+o+")(\\s*)(=)(\\s*)(function)(?:(\\s+)(\\w+))?(\\s*)(\\()",next:"function_arguments"},{token:"punctuation.operator",regex:/[.](?![.])/},{token:"support.function",regex:/(s(?:h(?:ift|ow(?:Mod(?:elessDialog|alDialog)|Help))|croll(?:X|By(?:Pages|Lines)?|Y|To)?|t(?:op|rike)|i(?:n|zeToContent|debar|gnText)|ort|u(?:p|b(?:str(?:ing)?)?)|pli(?:ce|t)|e(?:nd|t(?:Re(?:sizable|questHeader)|M(?:i(?:nutes|lliseconds)|onth)|Seconds|Ho(?:tKeys|urs)|Year|Cursor|Time(?:out)?|Interval|ZOptions|Date|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Date|FullYear)|FullYear|Active)|arch)|qrt|lice|avePreferences|mall)|h(?:ome|andleEvent)|navigate|c(?:har(?:CodeAt|At)|o(?:s|n(?:cat|textual|firm)|mpile)|eil|lear(?:Timeout|Interval)?|a(?:ptureEvents|ll)|reate(?:StyleSheet|Popup|EventObject))|t(?:o(?:GMTString|S(?:tring|ource)|U(?:TCString|pperCase)|Lo(?:caleString|werCase))|est|a(?:n|int(?:Enabled)?))|i(?:s(?:NaN|Finite)|ndexOf|talics)|d(?:isableExternalCapture|ump|etachEvent)|u(?:n(?:shift|taint|escape|watch)|pdateCommands)|j(?:oin|avaEnabled)|p(?:o(?:p|w)|ush|lugins.refresh|a(?:ddings|rse(?:Int|Float)?)|r(?:int|ompt|eference))|e(?:scape|nableExternalCapture|val|lementFromPoint|x(?:p|ec(?:Script|Command)?))|valueOf|UTC|queryCommand(?:State|Indeterm|Enabled|Value)|f(?:i(?:nd|le(?:ModifiedDate|Size|CreatedDate|UpdatedDate)|xed)|o(?:nt(?:size|color)|rward)|loor|romCharCode)|watch|l(?:ink|o(?:ad|g)|astIndexOf)|a(?:sin|nchor|cos|t(?:tachEvent|ob|an(?:2)?)|pply|lert|b(?:s|ort))|r(?:ou(?:nd|teEvents)|e(?:size(?:By|To)|calc|turnValue|place|verse|l(?:oad|ease(?:Capture|Events)))|andom)|g(?:o|et(?:ResponseHeader|M(?:i(?:nutes|lliseconds)|onth)|Se(?:conds|lection)|Hours|Year|Time(?:zoneOffset)?|Da(?:y|te)|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Da(?:y|te)|FullYear)|FullYear|A(?:ttention|llResponseHeaders)))|m(?:in|ove(?:B(?:y|elow)|To(?:Absolute)?|Above)|ergeAttributes|a(?:tch|rgins|x))|b(?:toa|ig|o(?:ld|rderWidths)|link|ack))\b(?=\()/},{token:"support.function.dom",regex:/(s(?:ub(?:stringData|mit)|plitText|e(?:t(?:NamedItem|Attribute(?:Node)?)|lect))|has(?:ChildNodes|Feature)|namedItem|c(?:l(?:ick|o(?:se|neNode))|reate(?:C(?:omment|DATASection|aption)|T(?:Head|extNode|Foot)|DocumentFragment|ProcessingInstruction|E(?:ntityReference|lement)|Attribute))|tabIndex|i(?:nsert(?:Row|Before|Cell|Data)|tem)|open|delete(?:Row|C(?:ell|aption)|T(?:Head|Foot)|Data)|focus|write(?:ln)?|a(?:dd|ppend(?:Child|Data))|re(?:set|place(?:Child|Data)|move(?:NamedItem|Child|Attribute(?:Node)?)?)|get(?:NamedItem|Element(?:sBy(?:Name|TagName|ClassName)|ById)|Attribute(?:Node)?)|blur)\b(?=\()/},{token:"support.constant",regex:/(s(?:ystemLanguage|cr(?:ipts|ollbars|een(?:X|Y|Top|Left))|t(?:yle(?:Sheets)?|atus(?:Text|bar)?)|ibling(?:Below|Above)|ource|uffixes|e(?:curity(?:Policy)?|l(?:ection|f)))|h(?:istory|ost(?:name)?|as(?:h|Focus))|y|X(?:MLDocument|SLDocument)|n(?:ext|ame(?:space(?:s|URI)|Prop))|M(?:IN_VALUE|AX_VALUE)|c(?:haracterSet|o(?:n(?:structor|trollers)|okieEnabled|lorDepth|mp(?:onents|lete))|urrent|puClass|l(?:i(?:p(?:boardData)?|entInformation)|osed|asses)|alle(?:e|r)|rypto)|t(?:o(?:olbar|p)|ext(?:Transform|Indent|Decoration|Align)|ags)|SQRT(?:1_2|2)|i(?:n(?:ner(?:Height|Width)|put)|ds|gnoreCase)|zIndex|o(?:scpu|n(?:readystatechange|Line)|uter(?:Height|Width)|p(?:sProfile|ener)|ffscreenBuffering)|NEGATIVE_INFINITY|d(?:i(?:splay|alog(?:Height|Top|Width|Left|Arguments)|rectories)|e(?:scription|fault(?:Status|Ch(?:ecked|arset)|View)))|u(?:ser(?:Profile|Language|Agent)|n(?:iqueID|defined)|pdateInterval)|_content|p(?:ixelDepth|ort|ersonalbar|kcs11|l(?:ugins|atform)|a(?:thname|dding(?:Right|Bottom|Top|Left)|rent(?:Window|Layer)?|ge(?:X(?:Offset)?|Y(?:Offset)?))|r(?:o(?:to(?:col|type)|duct(?:Sub)?|mpter)|e(?:vious|fix)))|e(?:n(?:coding|abledPlugin)|x(?:ternal|pando)|mbeds)|v(?:isibility|endor(?:Sub)?|Linkcolor)|URLUnencoded|P(?:I|OSITIVE_INFINITY)|f(?:ilename|o(?:nt(?:Size|Family|Weight)|rmName)|rame(?:s|Element)|gColor)|E|whiteSpace|l(?:i(?:stStyleType|n(?:eHeight|kColor))|o(?:ca(?:tion(?:bar)?|lName)|wsrc)|e(?:ngth|ft(?:Context)?)|a(?:st(?:M(?:odified|atch)|Index|Paren)|yer(?:s|X)|nguage))|a(?:pp(?:MinorVersion|Name|Co(?:deName|re)|Version)|vail(?:Height|Top|Width|Left)|ll|r(?:ity|guments)|Linkcolor|bove)|r(?:ight(?:Context)?|e(?:sponse(?:XML|Text)|adyState))|global|x|m(?:imeTypes|ultiline|enubar|argin(?:Right|Bottom|Top|Left))|L(?:N(?:10|2)|OG(?:10E|2E))|b(?:o(?:ttom|rder(?:Width|RightWidth|BottomWidth|Style|Color|TopWidth|LeftWidth))|ufferDepth|elow|ackground(?:Color|Image)))\b/},{token:"identifier",regex:o},{regex:"",token:"empty",next:"no_regex"}],start:[i.getStartRule("doc-start"),f("start"),{token:"string.regexp",regex:"\\/",next:"regex"},{token:"text",regex:"\\s+|^$",next:"start"},{token:"empty",regex:"",next:"no_regex"}],regex:[{token:"regexp.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"string.regexp",regex:"/[sxngimy]*",next:"no_regex"},{token:"invalid",regex:/\{\d+\b,?\d*\}[+*]|[+*$^?][+*]|[$^][?]|\?{3,}/},{token:"constant.language.escape",regex:/\(\?[:=!]|\)|\{\d+\b,?\d*\}|[+*]\?|[()$^+*?.]/},{token:"constant.language.delimiter",regex:/\|/},{token:"constant.language.escape",regex:/\[\^?/,next:"regex_character_class"},{token:"empty",regex:"$",next:"no_regex"},{defaultToken:"string.regexp"}],regex_character_class:[{token:"regexp.charclass.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"constant.language.escape",regex:"]",next:"regex"},{token:"constant.language.escape",regex:"-"},{token:"empty",regex:"$",next:"no_regex"},{defaultToken:"string.regexp.charachterclass"}],function_arguments:[{token:"variable.parameter",regex:o},{token:"punctuation.operator",regex:"[, ]+"},{token:"punctuation.operator",regex:"$"},{token:"empty",regex:"",next:"no_regex"}],qqstring:[{token:"constant.language.escape",regex:r},{token:"string",regex:"\\\\$",next:"qqstring"},{token:"string",regex:'"|$',next:"no_regex"},{defaultToken:"string"}],qstring:[{token:"constant.language.escape",regex:r},{token:"string",regex:"\\\\$",next:"qstring"},{token:"string",regex:"'|$",next:"no_regex"},{defaultToken:"string"}]};if(!e||!e.noES6)this.$rules.no_regex.unshift({regex:"[{}]",onMatch:function(e,t,n){this.next=e=="{"?this.nextState:"";if(e=="{"&&n.length)n.unshift("start",t);else if(e=="}"&&n.length){n.shift(),this.next=n.shift();if(this.next.indexOf("string")!=-1||this.next.indexOf("jsx")!=-1)return"paren.quasi.end"}return e=="{"?"paren.lparen":"paren.rparen"},nextState:"start"},{token:"string.quasi.start",regex:/`/,push:[{token:"constant.language.escape",regex:r},{token:"paren.quasi.start",regex:/\${/,push:"start"},{token:"string.quasi.end",regex:/`/,next:"pop"},{defaultToken:"string.quasi"}]}),(!e||e.jsx!=0)&&a.call(this);this.embedRules(i,"doc-",[i.getEndRule("no_regex")]),this.normalizeRules()};r.inherits(u,s),t.JavaScriptHighlightRules=u}),ace.define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],function(e,t,n){"use strict";var r=e("../range").Range,i=function(){};(function(){this.checkOutdent=function(e,t){return/^\s+$/.test(e)?/^\s*\}/.test(t):!1},this.autoOutdent=function(e,t){var n=e.getLine(t),i=n.match(/^(\s*\})/);if(!i)return 0;var s=i[1].length,o=e.findMatchingBracket({row:t,column:s});if(!o||o.row==t)return 0;var u=this.$getIndent(e.getLine(o.row));e.replace(new r(t,0,t,s-1),u)},this.$getIndent=function(e){return e.match(/^\s*/)[0]}}).call(i.prototype),t.MatchingBraceOutdent=i}),ace.define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../../range").Range,s=e("./fold_mode").FoldMode,o=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end)))};r.inherits(o,s),function(){this.foldingStartMarker=/(\{|\[)[^\}\]]*$|^\s*(\/\*)/,this.foldingStopMarker=/^[^\[\{]*(\}|\])|^[\s\*]*(\*\/)/,this.singleLineBlockCommentRe=/^\s*(\/\*).*\*\/\s*$/,this.tripleStarBlockCommentRe=/^\s*(\/\*\*\*).*\*\/\s*$/,this.startRegionRe=/^\s*(\/\*|\/\/)#?region\b/,this._getFoldWidgetBase=this.getFoldWidget,this.getFoldWidget=function(e,t,n){var r=e.getLine(n);if(this.singleLineBlockCommentRe.test(r)&&!this.startRegionRe.test(r)&&!this.tripleStarBlockCommentRe.test(r))return"";var i=this._getFoldWidgetBase(e,t,n);return!i&&this.startRegionRe.test(r)?"start":i},this.getFoldWidgetRange=function(e,t,n,r){var i=e.getLine(n);if(this.startRegionRe.test(i))return this.getCommentRegionBlock(e,i,n);var s=i.match(this.foldingStartMarker);if(s){var o=s.index;if(s[1])return this.openingBracketBlock(e,s[1],n,o);var u=e.getCommentFoldRange(n,o+s[0].length,1);return u&&!u.isMultiLine()&&(r?u=this.getSectionRange(e,n):t!="all"&&(u=null)),u}if(t==="markbegin")return;var s=i.match(this.foldingStopMarker);if(s){var o=s.index+s[0].length;return s[1]?this.closingBracketBlock(e,s[1],n,o):e.getCommentFoldRange(n,o,-1)}},this.getSectionRange=function(e,t){var n=e.getLine(t),r=n.search(/\S/),s=t,o=n.length;t+=1;var u=t,a=e.getLength();while(++tf)break;var l=this.getFoldWidgetRange(e,"all",t);if(l){if(l.start.row<=s)break;if(l.isMultiLine())t=l.end.row;else if(r==f)break}u=t}return new i(s,o,u,e.getLine(u).length)},this.getCommentRegionBlock=function(e,t,n){var r=t.search(/\s*$/),s=e.getLength(),o=n,u=/^\s*(?:\/\*|\/\/|--)#?(end)?region\b/,a=1;while(++no)return new i(o,r,l,t.length)}}.call(o.prototype)}),ace.define("ace/mode/javascript",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/javascript_highlight_rules","ace/mode/matching_brace_outdent","ace/worker/worker_client","ace/mode/behaviour/cstyle","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./javascript_highlight_rules").JavaScriptHighlightRules,o=e("./matching_brace_outdent").MatchingBraceOutdent,u=e("../worker/worker_client").WorkerClient,a=e("./behaviour/cstyle").CstyleBehaviour,f=e("./folding/cstyle").FoldMode,l=function(){this.HighlightRules=s,this.$outdent=new o,this.$behaviour=new a,this.foldingRules=new f};r.inherits(l,i),function(){this.lineCommentStart="//",this.blockComment={start:"/*",end:"*/"},this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),i=this.getTokenizer().getLineTokens(t,e),s=i.tokens,o=i.state;if(s.length&&s[s.length-1].type=="comment")return r;if(e=="start"||e=="no_regex"){var u=t.match(/^.*(?:\bcase\b.*:|[\{\(\[])\s*$/);u&&(r+=n)}else if(e=="doc-start"){if(o=="start"||o=="no_regex")return"";var u=t.match(/^\s*(\/?)\*/);u&&(u[1]&&(r+=" "),r+="* ")}return r},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.createWorker=function(e){var t=new u(["ace"],"ace/mode/javascript_worker","JavaScriptWorker");return t.attachToDocument(e.getDocument()),t.on("annotate",function(t){e.setAnnotations(t.data)}),t.on("terminate",function(){e.clearAnnotations()}),t},this.$id="ace/mode/javascript"}.call(l.prototype),t.Mode=l}) \ No newline at end of file diff --git a/examples/SmartSwitch/data_src/js_css_src/styled-notifications/.babelrc b/examples/SmartSwitch/data_src/js_css_src/styled-notifications/.babelrc new file mode 100644 index 000000000..377ca7046 --- /dev/null +++ b/examples/SmartSwitch/data_src/js_css_src/styled-notifications/.babelrc @@ -0,0 +1,3 @@ +{ + "presets": ["es2015"] +} \ No newline at end of file diff --git a/examples/SmartSwitch/data_src/js_css_src/styled-notifications/.eslintrc.js b/examples/SmartSwitch/data_src/js_css_src/styled-notifications/.eslintrc.js new file mode 100644 index 000000000..5bebe588f --- /dev/null +++ b/examples/SmartSwitch/data_src/js_css_src/styled-notifications/.eslintrc.js @@ -0,0 +1,31 @@ +module.exports = { + "env": { + "browser": true, + "commonjs": true, + "es6": true + }, + "extends": "eslint:recommended", + "parserOptions": { + "sourceType": "module" + }, + "rules": { + "indent": [ + "error", + "tab" + ], + "linebreak-style": [ + "error", + "windows" + ], + "quotes": [ + "error", + "single" + ], + "semi": [ + "error", + "always" + ], + "no-console": 0, + "no-undef": 0 + } +}; \ No newline at end of file diff --git a/examples/SmartSwitch/data_src/js_css_src/styled-notifications/.gitignore b/examples/SmartSwitch/data_src/js_css_src/styled-notifications/.gitignore new file mode 100644 index 000000000..f949f35de --- /dev/null +++ b/examples/SmartSwitch/data_src/js_css_src/styled-notifications/.gitignore @@ -0,0 +1,30 @@ +# IDE files +.idea/ +.DS_Store + +# Build directories +build/ + +# Dependency directories +node_modules/ +jspm_packages/ + +# Lock files +yarn.lock +package-lock.json + +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Yarn Integrity file +.yarn-integrity diff --git a/examples/SmartSwitch/data_src/js_css_src/styled-notifications/.travis.yml b/examples/SmartSwitch/data_src/js_css_src/styled-notifications/.travis.yml new file mode 100644 index 000000000..0fe294a6f --- /dev/null +++ b/examples/SmartSwitch/data_src/js_css_src/styled-notifications/.travis.yml @@ -0,0 +1,3 @@ +language: node_js +node_js: + - "7" diff --git a/examples/SmartSwitch/data_src/js_css_src/styled-notifications/LICENSE.md b/examples/SmartSwitch/data_src/js_css_src/styled-notifications/LICENSE.md new file mode 100644 index 000000000..5506c2df6 --- /dev/null +++ b/examples/SmartSwitch/data_src/js_css_src/styled-notifications/LICENSE.md @@ -0,0 +1,7 @@ +# Notifications license + +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: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +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. \ No newline at end of file diff --git a/examples/SmartSwitch/data_src/js_css_src/styled-notifications/__tests__/helpers.test.js b/examples/SmartSwitch/data_src/js_css_src/styled-notifications/__tests__/helpers.test.js new file mode 100644 index 000000000..b97ad7557 --- /dev/null +++ b/examples/SmartSwitch/data_src/js_css_src/styled-notifications/__tests__/helpers.test.js @@ -0,0 +1,104 @@ +const { partial, append, isString, createElement, createParagraph } = require('../src/helpers'); + +const addNumbers = (x, y) => x + y; + +const sum = (...numbers) => numbers.reduce((total, current) => total + current, 0); + +describe('Helpers', () => { + beforeEach(() => { + document.body.innerHTML = ''; + }); + + describe('Partial', () => { + it('should return a partially applied function', () => { + expect(typeof partial(addNumbers, 10)).toEqual('function'); + }); + + it('should execute function when partially applied function is called', () => { + expect(partial(addNumbers, 20)(10)).toEqual(30); + }); + + it('should gather argument', () => { + expect(partial(sum, 5, 10)(15, 20, 25)).toEqual(75); + }); + }); + + describe('Append', () => { + const container = document.createElement('div'); + document.body.appendChild(container); + + const elementToAppend = document.createElement('h1'); + elementToAppend.classList.add('heading'); + elementToAppend.innerText = 'working'; + + append(container, elementToAppend); + + const element = document.querySelector('.heading'); + expect(element); + + expect(element.innerText).toEqual('working'); + }); + + describe('Is string', () => { + expect(isString(1)).toEqual(false); + expect(isString(null)).toEqual(false); + expect(isString(undefined)).toEqual(false); + expect(isString({})).toEqual(false); + + expect(isString('')).toEqual(true); + expect(isString('a')).toEqual(true); + expect(isString('1')).toEqual(true); + expect(isString('some string')).toEqual(true); + }); + + describe('Create element', () => { + it('should create an element', () => { + expect(createElement('p')).toEqual(document.createElement('p')); + expect(createElement('h1')).toEqual(document.createElement('h1')); + expect(createElement('ul')).toEqual(document.createElement('ul')); + expect(createElement('li')).toEqual(document.createElement('li')); + expect(createElement('div')).toEqual(document.createElement('div')); + expect(createElement('span')).toEqual(document.createElement('span')); + }); + + it('should add class names', () => { + expect(createElement('div', 'someclass1', 'someclass2').classList.contains('someclass2')); + expect(createElement('p', 'para', 'test').classList.contains('para')); + + const mockUl = document.createElement('ul'); + mockUl.classList.add('nav'); + mockUl.classList.add('foo'); + + expect(createElement('ul', 'nav', 'foo').classList).toEqual(mockUl.classList); + }); + }); + + describe('Create paragraph', () => { + it('should create a paragraph', () => { + const p = document.createElement('p'); + p.innerText = 'Some text'; + expect(createParagraph()('Some text')).toEqual(p); + }); + + it('should add class names', () => { + const p = document.createElement('p'); + p.classList.add('body-text'); + p.classList.add('para'); + + expect(createParagraph('body-text', 'para')('')).toEqual(p); + }); + + it('should set inner text', () => { + const p = document.createElement('p'); + p.innerText = 'Hello world!'; + p.classList.add('text'); + + expect(createParagraph('text')('Hello world!')).toEqual(p); + }); + + it('should append to DOM', () => { + append(document.body, createParagraph('text')('hello')); + expect(document.querySelector('.text').innerText).toEqual('hello'); + }); + }); +}); diff --git a/examples/SmartSwitch/data_src/js_css_src/styled-notifications/__tests__/index.tests.js b/examples/SmartSwitch/data_src/js_css_src/styled-notifications/__tests__/index.tests.js new file mode 100644 index 000000000..9a69d1630 --- /dev/null +++ b/examples/SmartSwitch/data_src/js_css_src/styled-notifications/__tests__/index.tests.js @@ -0,0 +1,144 @@ +require('../src/index'); + +describe('Notifications', () => { + beforeEach(() => { + document.body.innerHTML = ''; + }); + + it('should display a console warning if no title or message is passed', () => { + jest.spyOn(global.console, 'warn'); + window.createNotification()(); + expect(console.warn).toBeCalled(); + }); + + it('should render a default notification', () => { + const notification = window.createNotification(); + + const title = 'I am a title'; + + // Should initially not contain any notifications + expect(document.querySelectorAll('.ncf').length).toEqual(0); + + // Create a notification instance with a title + notification({ title }); + + // Should be one notification with the title passed in + expect(document.querySelectorAll('.ncf').length).toEqual(1); + expect(document.querySelector('.ncf-title').innerText).toEqual(title); + + // Create a second instance so there should now be two instances + notification({ title }); + expect(document.querySelectorAll('.ncf').length).toEqual(2); + }); + + it('should close on click if the option is enabled', () => { + const notification = window.createNotification({ + closeOnClick: true + }); + + // Create a notification with a generic body + notification({ message: 'some text' }); + + // Should be one notification instance + expect(document.querySelectorAll('.ncf').length).toEqual(1); + + // Click the notification + document.querySelector('.ncf').click(); + + expect(document.querySelectorAll('.ncf').length).toEqual(0); + }); + + it('should not close on click if the option is disabled', () => { + const notification = window.createNotification({ + closeOnClick: false + }); + + // Create a notification with a generic body + notification({ message: 'some text' }); + + // Should be one notification instance + expect(document.querySelectorAll('.ncf').length).toEqual(1); + + // Click the notification + document.querySelector('.ncf').click(); + + expect(document.querySelectorAll('.ncf').length).toEqual(1); + }); + + it('should set position class if valid', () => { + const validPositions = [ + 'nfc-top-left', + 'nfc-top-right', + 'nfc-bottom-left', + 'nfc-bottom-right' + ]; + + validPositions.forEach(position => { + const notification = window.createNotification({ + positionClass: position + }); + + notification({ title: 'title here' }); + + const className = `.${position}`; + + expect(document.querySelectorAll(className).length).toEqual(1); + + const container = document.querySelector(className); + expect(container.querySelectorAll('.ncf').length).toEqual(1); + }); + }); + + it('should revert to default to default position and warn if class is invalid', () => { + const notification = window.createNotification({ + positionClass: 'invalid-name' + }); + + jest.spyOn(global.console, 'warn'); + + notification({ message: 'test' }); + + expect(console.warn).toBeCalled(); + + expect(document.querySelectorAll('.nfc-top-right').length).toEqual(1); + }); + + it('should allow a custom onclick callback', () => { + let a = 'not clicked'; + + const notification = window.createNotification({ + onclick: () => { + a = 'clicked'; + } + }); + + notification({ message: 'click test' }); + + expect(a).toEqual('not clicked'); + + // Click the notification + document.querySelector('.ncf').click(); + + expect(a).toEqual('clicked'); + }); + + it('should show for correct duration', () => { + const notification = window.createNotification({ + showDuration: 500 + }); + + notification({ message: 'test' }); + + expect(document.querySelectorAll('.ncf').length).toEqual(1); + + // Should exist after 400ms + setTimeout(() => { + expect(document.querySelectorAll('.ncf').length).toEqual(1); + }, 400); + + // Should delete after 500ms + setTimeout(() => { + expect(document.querySelectorAll('.ncf').length).toEqual(0); + }); + }, 501); +}); diff --git a/examples/SmartSwitch/data_src/js_css_src/styled-notifications/demo/demo.js b/examples/SmartSwitch/data_src/js_css_src/styled-notifications/demo/demo.js new file mode 100644 index 000000000..d2f0fad2b --- /dev/null +++ b/examples/SmartSwitch/data_src/js_css_src/styled-notifications/demo/demo.js @@ -0,0 +1,34 @@ +'use strict'; + +// Written using ES5 JS for browser support +window.addEventListener('DOMContentLoaded', function () { + var form = document.querySelector('form'); + + form.addEventListener('submit', function (e) { + e.preventDefault(); + + // Form elements + var title = form.querySelector('#title').value; + var message = form.querySelector('#message').value; + var position = form.querySelector('#position').value; + var duration = form.querySelector('#duration').value; + var theme = form.querySelector('#theme').value; + var closeOnClick = form.querySelector('#close').checked; + var displayClose = form.querySelector('#closeButton').checked; + + if(!message) { + message = 'You did not enter a message...'; + } + + window.createNotification({ + closeOnClick: closeOnClick, + displayCloseButton: displayClose, + positionClass: position, + showDuration: duration, + theme: theme + })({ + title: title, + message: message + }); + }); +}); \ No newline at end of file diff --git a/examples/SmartSwitch/data_src/js_css_src/styled-notifications/demo/index.html b/examples/SmartSwitch/data_src/js_css_src/styled-notifications/demo/index.html new file mode 100644 index 000000000..d5dd6a6fd --- /dev/null +++ b/examples/SmartSwitch/data_src/js_css_src/styled-notifications/demo/index.html @@ -0,0 +1,101 @@ + + + + +Notifications + + + + + + + + + +

Notifications

+
+ +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + + + +
+ + + + + +
+ + + + + \ No newline at end of file diff --git a/examples/SmartSwitch/data_src/js_css_src/styled-notifications/demo/index_my.html b/examples/SmartSwitch/data_src/js_css_src/styled-notifications/demo/index_my.html new file mode 100644 index 000000000..412e25d4b --- /dev/null +++ b/examples/SmartSwitch/data_src/js_css_src/styled-notifications/demo/index_my.html @@ -0,0 +1,37 @@ + + + + +Notifications + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/SmartSwitch/data_src/js_css_src/styled-notifications/dist/notifications.css b/examples/SmartSwitch/data_src/js_css_src/styled-notifications/dist/notifications.css new file mode 100644 index 000000000..90d9e61dd --- /dev/null +++ b/examples/SmartSwitch/data_src/js_css_src/styled-notifications/dist/notifications.css @@ -0,0 +1 @@ +.ncf-container{font-size:14px;box-sizing:border-box;position:fixed;z-index:999999}.ncf-container.nfc-top-left{top:12px;left:12px}.ncf-container.nfc-top-right{top:12px;right:12px}.ncf-container.nfc-bottom-right{bottom:12px;right:12px}.ncf-container.nfc-bottom-left{bottom:12px;left:12px}@media (max-width:767px){.ncf-container{left:0;right:0}}.ncf-container .ncf{background:#fff;transition:.3s ease;position:relative;pointer-events:auto;overflow:hidden;margin:0 0 6px;padding:30px;width:300px;border-radius:3px 3px 3px 3px;box-shadow:0 0 12px #999;color:#000;opacity:.9;-ms-filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=90);filter:alpha(opacity=90);background-position:15px!important;background-repeat:no-repeat!important;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.ncf-container .ncf:hover{box-shadow:0 0 12px #000;opacity:1;cursor:pointer}.ncf-container .ncf .ncf-title{font-weight:700;font-size:16px;text-align:left;margin-top:0;margin-bottom:6px;word-wrap:break-word}.ncf-container .ncf .nfc-message{margin:0;text-align:left;word-wrap:break-word}.ncf-container .success{background:#51a351;color:#fff;padding:15px 15px 15px 50px;background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAADsSURBVEhLY2AYBfQMgf///3P8+/evAIgvA/FsIF+BavYDDWMBGroaSMMBiE8VC7AZDrIFaMFnii3AZTjUgsUUWUDA8OdAH6iQbQEhw4HyGsPEcKBXBIC4ARhex4G4BsjmweU1soIFaGg/WtoFZRIZdEvIMhxkCCjXIVsATV6gFGACs4Rsw0EGgIIH3QJYJgHSARQZDrWAB+jawzgs+Q2UO49D7jnRSRGoEFRILcdmEMWGI0cm0JJ2QpYA1RDvcmzJEWhABhD/pqrL0S0CWuABKgnRki9lLseS7g2AlqwHWQSKH4oKLrILpRGhEQCw2LiRUIa4lwAAAABJRU5ErkJggg==")}.ncf-container .info{background:#2f96b4;color:#fff;padding:15px 15px 15px 50px;background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGwSURBVEhLtZa9SgNBEMc9sUxxRcoUKSzSWIhXpFMhhYWFhaBg4yPYiWCXZxBLERsLRS3EQkEfwCKdjWJAwSKCgoKCcudv4O5YLrt7EzgXhiU3/4+b2ckmwVjJSpKkQ6wAi4gwhT+z3wRBcEz0yjSseUTrcRyfsHsXmD0AmbHOC9Ii8VImnuXBPglHpQ5wwSVM7sNnTG7Za4JwDdCjxyAiH3nyA2mtaTJufiDZ5dCaqlItILh1NHatfN5skvjx9Z38m69CgzuXmZgVrPIGE763Jx9qKsRozWYw6xOHdER+nn2KkO+Bb+UV5CBN6WC6QtBgbRVozrahAbmm6HtUsgtPC19tFdxXZYBOfkbmFJ1VaHA1VAHjd0pp70oTZzvR+EVrx2Ygfdsq6eu55BHYR8hlcki+n+kERUFG8BrA0BwjeAv2M8WLQBtcy+SD6fNsmnB3AlBLrgTtVW1c2QN4bVWLATaIS60J2Du5y1TiJgjSBvFVZgTmwCU+dAZFoPxGEEs8nyHC9Bwe2GvEJv2WXZb0vjdyFT4Cxk3e/kIqlOGoVLwwPevpYHT+00T+hWwXDf4AJAOUqWcDhbwAAAAASUVORK5CYII=")}.ncf-container .warning{background:#f87400;color:#fff;padding:15px 15px 15px 50px;background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGYSURBVEhL5ZSvTsNQFMbXZGICMYGYmJhAQIJAICYQPAACiSDB8AiICQQJT4CqQEwgJvYASAQCiZiYmJhAIBATCARJy+9rTsldd8sKu1M0+dLb057v6/lbq/2rK0mS/TRNj9cWNAKPYIJII7gIxCcQ51cvqID+GIEX8ASG4B1bK5gIZFeQfoJdEXOfgX4QAQg7kH2A65yQ87lyxb27sggkAzAuFhbbg1K2kgCkB1bVwyIR9m2L7PRPIhDUIXgGtyKw575yz3lTNs6X4JXnjV+LKM/m3MydnTbtOKIjtz6VhCBq4vSm3ncdrD2lk0VgUXSVKjVDJXJzijW1RQdsU7F77He8u68koNZTz8Oz5yGa6J3H3lZ0xYgXBK2QymlWWA+RWnYhskLBv2vmE+hBMCtbA7KX5drWyRT/2JsqZ2IvfB9Y4bWDNMFbJRFmC9E74SoS0CqulwjkC0+5bpcV1CZ8NMej4pjy0U+doDQsGyo1hzVJttIjhQ7GnBtRFN1UarUlH8F3xict+HY07rEzoUGPlWcjRFRr4/gChZgc3ZL2d8oAAAAASUVORK5CYII=")}.ncf-container .error{background:#bd362f;color:#fff;padding:15px 15px 15px 50px;background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAHOSURBVEhLrZa/SgNBEMZzh0WKCClSCKaIYOED+AAKeQQLG8HWztLCImBrYadgIdY+gIKNYkBFSwu7CAoqCgkkoGBI/E28PdbLZmeDLgzZzcx83/zZ2SSXC1j9fr+I1Hq93g2yxH4iwM1vkoBWAdxCmpzTxfkN2RcyZNaHFIkSo10+8kgxkXIURV5HGxTmFuc75B2RfQkpxHG8aAgaAFa0tAHqYFfQ7Iwe2yhODk8+J4C7yAoRTWI3w/4klGRgR4lO7Rpn9+gvMyWp+uxFh8+H+ARlgN1nJuJuQAYvNkEnwGFck18Er4q3egEc/oO+mhLdKgRyhdNFiacC0rlOCbhNVz4H9FnAYgDBvU3QIioZlJFLJtsoHYRDfiZoUyIxqCtRpVlANq0EU4dApjrtgezPFad5S19Wgjkc0hNVnuF4HjVA6C7QrSIbylB+oZe3aHgBsqlNqKYH48jXyJKMuAbiyVJ8KzaB3eRc0pg9VwQ4niFryI68qiOi3AbjwdsfnAtk0bCjTLJKr6mrD9g8iq/S/B81hguOMlQTnVyG40wAcjnmgsCNESDrjme7wfftP4P7SP4N3CJZdvzoNyGq2c/HWOXJGsvVg+RA/k2MC/wN6I2YA2Pt8GkAAAAASUVORK5CYII=")!important}.ncf-container button{position:relative;right:-.3em;top:-.3em;float:right;font-weight:700;color:#fff;text-shadow:0 1px 0 #fff;opacity:.8;line-height:1;font-size:16px;padding:0;cursor:pointer;background:transparent;border:0}.ncf-container button:hover{opacity:1} \ No newline at end of file diff --git a/examples/SmartSwitch/data_src/js_css_src/styled-notifications/dist/notifications.css.gz b/examples/SmartSwitch/data_src/js_css_src/styled-notifications/dist/notifications.css.gz new file mode 100644 index 0000000000000000000000000000000000000000..b1e1ecb19e475a9932e331065120ac6a1bdbbc3c GIT binary patch literal 2487 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 B-pc?0 literal 0 HcmV?d00001 diff --git a/examples/SmartSwitch/data_src/js_css_src/styled-notifications/dist/notifications.js b/examples/SmartSwitch/data_src/js_css_src/styled-notifications/dist/notifications.js new file mode 100644 index 000000000..34b339e61 --- /dev/null +++ b/examples/SmartSwitch/data_src/js_css_src/styled-notifications/dist/notifications.js @@ -0,0 +1 @@ +!function(t){function n(i){if(e[i])return e[i].exports;var o=e[i]={i:i,l:!1,exports:{}};return t[i].call(o.exports,o,o.exports,n),o.l=!0,o.exports}var e={};n.m=t,n.c=e,n.d=function(t,e,i){n.o(t,e)||Object.defineProperty(t,e,{configurable:!1,enumerable:!0,get:i})},n.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return n.d(e,"a",e),e},n.o=function(t,n){return Object.prototype.hasOwnProperty.call(t,n)},n.p="",n(n.s=0)}([function(t,n,e){e(1),t.exports=e(4)},function(t,n,e){"use strict";var i=Object.assign||function(t){for(var n=1;n-1}(t.positionClass)||(console.warn("An invalid notification position class has been specified."),t.positionClass=c.positionClass),t.onclick&&"function"!=typeof t.onclick&&(console.warn("Notification on click must be a function."),t.onclick=c.onclick),"number"!=typeof t.showDuration&&(t.showDuration=c.showDuration),(0,o.isString)(t.theme)&&0!==t.theme.length||(console.warn("Notification theme must be a string with length"),t.theme=c.theme),t}function e(t){return t=n(t),function(){var n=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},e=n.title,i=n.message,c=r(t.positionClass);if(!e&&!i)return console.warn("Notification must contain a title or a message!");var a=(0,o.createElement)("div","ncf",t.theme);if(!0===t.closeOnClick&&a.addEventListener("click",function(){return c.removeChild(a)}),t.onclick&&a.addEventListener("click",function(n){return t.onclick(n)}),t.displayCloseButton){var s=(0,o.createElement)("button");s.innerText="X",!1===t.closeOnClick&&s.addEventListener("click",function(){return c.removeChild(a)}),(0,o.append)(a,s)}if((0,o.isString)(e)&&e.length&&(0,o.append)(a,(0,o.createParagraph)("ncf-title")(e)),(0,o.isString)(i)&&i.length&&(0,o.append)(a,(0,o.createParagraph)("nfc-message")(i)),(0,o.append)(c,a),t.showDuration&&t.showDuration>0){var l=setTimeout(function(){c.removeChild(a),0===c.querySelectorAll(".ncf").length&&document.body.removeChild(c)},t.showDuration);(t.closeOnClick||t.displayCloseButton)&&a.addEventListener("click",function(){return clearTimeout(l)})}}}function r(t){var n=document.querySelector("."+t);return n||(n=(0,o.createElement)("div","ncf-container",t),(0,o.append)(document.body,n)),n}var c={closeOnClick:!0,displayCloseButton:!1,positionClass:"nfc-top-right",onclick:!1,showDuration:3500,theme:"success"};t.createNotification?console.warn("Window already contains a create notification function. Have you included the script twice?"):t.createNotification=e}(window)},function(t,n,e){"use strict";!function(){function t(t){this.el=t;for(var n=t.className.replace(/^\s+|\s+$/g,"").split(/\s+/),i=0;i1?n-1:0),i=1;i1?n-1:0),i=1;i1?n-1:0),i=1;i1?n-1:0),c=1;cLmfM||m-$;8>RU#q-s5XUMp@m@G?VkH3orlN<+fg?Z@TR&u{)6)+hLAf}EjW+Nsw+G1G zdDwPT)@<~)%;kp+0!UNtp_wiD7Tj7_tU~=p3|&!!aEpbD-@k|Au}#YiZgo4@u`w_l zD$C4O>zR+89}qqTP9#CN9Q<*1XpZSb8cPnjb=I99Al}L1=~vU*6nyCg0_1}rgd1w& zLM&NDUk^3nK}Vn~#$D@J0rVP*O*fIUfT(b}R*r~^8R-YCN(ppT;g!i}IM1!vrR8NLb@F(nw_GRG^MI@tE zS4;+H2-S`lCzxU%ARnGp?CjTjWgc|mf#U_CMpMSAF9*7Kj-)hOhP&Mk_JCwqo(a*+ z8pfSYzd|2&4xkr7WAs(KT~y1X4UIyf>i@VI*iWCUSir(FhI<7f{>A-BMl$bX3 zewi>h+K56YYMP+wkSd*eu3b{h6#5FbyE77fSk$S03YQIJ@ z!;R^ATcHZ9OSS0e66~*;=%M@q(YY-njflz=QeW4jLgo74BKK7*xJB4{4uF7)ehsJo zuJP#`h(Z70d_dh!7cpeQC4KMX;&3xRk$XTMqGuJ*%kSP47f<+m;qsOfq%C?}J9-&c zE;FvhGSN3o+b3!4lb~tlP(L@Jzwt$u)>nrRq6Qu}q&S^OIMb7qXcKk8ZwD=TS_bQ0wMksRQ5-QJx@NZXKpQPwK-vzmBP|;r^2d&Y9n#F4pWR4j`?&i zqG$+o@9Ey#Fn)zs3K}~Zt{C@)>Mz!~)+R?eztbtMA&4z{db=Q@MABj%tzMP2e!GHqeJMll7 z` + +2. Link to notifications.js `` + +## Usage +### Custom options +- closeOnClick - Close the notification dialog when a click is invoked. +- displayCloseButton - Display a close button in the top right hand corner of the notification. +- positionClass - Set the position of the notification dialog. Accepted positions: ('nfc-top-right', 'nfc-bottom-right', 'nfc-bottom-left', 'nfc-top-left'). +- onClick - Call a callback function when a click is invoked on a notification. +- showDuration - Milliseconds the notification should be visible (0 for a notification that will remain open until clicked) +- theme - Set the position of the notification dialog. Accepted positions: ('success', 'info', 'warning', 'error', 'A custom clasName'). +``` +const defaultOptions = { + closeOnClick: true, + displayCloseButton: false, + positionClass: 'nfc-top-right', + onclick: false, + showDuration: 3500, + theme: 'success' +}; +``` + +## Example + +### Success notification +``` +// Create a success notification instance +const successNotification = window.createNotification({ + theme: 'success', + showDuration: 5000 +}); + +// Invoke success notification +successNotification({ + message: 'Simple success notification' +}); + +// Use the same instance but pass a title +successNotification({ + title: 'Working', + message: 'Simple success notification' +}); +``` + +### Information notification +``` +// Only running it once? Invoke immediately like this +window.createNotification({ + theme: 'success', + showDuration: 5000 +})({ + message: 'I have some information for you...' +}); +``` + +### Todo +~~1. Add to NPM~~ +2. Improve documentation +3. Further device testing +4. Add contributor instructions \ No newline at end of file diff --git a/examples/SmartSwitch/data_src/js_css_src/styled-notifications/src/helpers.js b/examples/SmartSwitch/data_src/js_css_src/styled-notifications/src/helpers.js new file mode 100644 index 000000000..5a7de2b95 --- /dev/null +++ b/examples/SmartSwitch/data_src/js_css_src/styled-notifications/src/helpers.js @@ -0,0 +1,24 @@ +export const partial = (fn, ...presetArgs) => (...laterArgs) => fn(...presetArgs, ...laterArgs); + +export const append = (el, ...children) => children.forEach(child => el.appendChild(child)); + +export const isString = input => typeof input === 'string'; + +export const createElement = (elementType, ...classNames) => { + const element = document.createElement(elementType); + + if(classNames.length) { + classNames.forEach(currentClass => element.classList.add(currentClass)); + } + + return element; +}; + +const setInnerText = (element, text) => { + element.innerText = text; + return element; +}; + +const createTextElement = (elementType, ...classNames) => partial(setInnerText, createElement(elementType, ...classNames)); + +export const createParagraph = (...classNames) => createTextElement('p', ...classNames); \ No newline at end of file diff --git a/examples/SmartSwitch/data_src/js_css_src/styled-notifications/src/index.js b/examples/SmartSwitch/data_src/js_css_src/styled-notifications/src/index.js new file mode 100644 index 000000000..51512babe --- /dev/null +++ b/examples/SmartSwitch/data_src/js_css_src/styled-notifications/src/index.js @@ -0,0 +1,148 @@ +'use strict'; + +// Polyfills +import './polyfills/classList'; + +import { + append, + createElement, + createParagraph, + isString +} from './helpers'; + +(function Notifications(window) { + // Default notification options + const defaultOptions = { + closeOnClick: true, + displayCloseButton: false, + positionClass: 'nfc-top-right', + onclick: false, + showDuration: 3500, + theme: 'success' + }; + + function configureOptions(options) { + // Create a copy of options and merge with defaults + options = Object.assign({}, defaultOptions, options); + + // Validate position class + function validatePositionClass(className) { + const validPositions = [ + 'nfc-top-left', + 'nfc-top-right', + 'nfc-bottom-left', + 'nfc-bottom-right' + ]; + + return validPositions.indexOf(className) > -1; + } + + // Verify position, if invalid reset to default + if (!validatePositionClass(options.positionClass)) { + console.warn('An invalid notification position class has been specified.'); + options.positionClass = defaultOptions.positionClass; + } + + // Verify onClick is a function + if (options.onclick && typeof options.onclick !== 'function') { + console.warn('Notification on click must be a function.'); + options.onclick = defaultOptions.onclick; + } + + // Verify show duration + if(typeof options.showDuration !== 'number') { + options.showDuration = defaultOptions.showDuration; + } + + // Verify theme + if(!isString(options.theme) || options.theme.length === 0) { + console.warn('Notification theme must be a string with length'); + options.theme = defaultOptions.theme; + } + + return options; + } + + // Create a new notification instance + function createNotification(options) { + // Validate options and set defaults + options = configureOptions(options); + + // Return a notification function + return function notification({ title, message } = {}) { + const container = createNotificationContainer(options.positionClass); + + if(!title && !message) { + return console.warn('Notification must contain a title or a message!'); + } + + // Create the notification wrapper + const notificationEl = createElement('div', 'ncf', options.theme); + + // Close on click + if(options.closeOnClick === true) { + notificationEl.addEventListener('click', () => container.removeChild(notificationEl)); + } + + // Custom click callback + if(options.onclick) { + notificationEl.addEventListener('click', (e) => options.onclick(e)); + } + + // Display close button + if(options.displayCloseButton) { + const closeButton = createElement('button'); + closeButton.innerText = 'X'; + + // Use the wrappers close on click to avoid useless event listeners + if(options.closeOnClick === false){ + closeButton.addEventListener('click', () =>container.removeChild(notificationEl)); + } + + append(notificationEl, closeButton); + } + + // Append title and message + isString(title) && title.length && append(notificationEl, createParagraph('ncf-title')(title)); + isString(message) && message.length && append(notificationEl, createParagraph('nfc-message')(message)); + + // Append to container + append(container, notificationEl); + + // Remove element after duration + if(options.showDuration && options.showDuration > 0) { + const timeout = setTimeout(() => { + container.removeChild(notificationEl); + + // Remove container if empty + if(container.querySelectorAll('.ncf').length === 0) { + document.body.removeChild(container); + } + }, options.showDuration); + + // If close on click is enabled and the user clicks, cancel timeout + if(options.closeOnClick || options.displayCloseButton) { + notificationEl.addEventListener('click', () => clearTimeout(timeout)); + } + } + }; + } + + function createNotificationContainer(position) { + let container = document.querySelector(`.${position}`); + + if(!container) { + container = createElement('div', 'ncf-container', position); + append(document.body, container); + } + + return container; + } + + // Add Notifications to window to make globally accessible + if (window.createNotification) { + console.warn('Window already contains a create notification function. Have you included the script twice?'); + } else { + window.createNotification = createNotification; + } +})(window); diff --git a/examples/SmartSwitch/data_src/js_css_src/styled-notifications/src/polyfills/classList.js b/examples/SmartSwitch/data_src/js_css_src/styled-notifications/src/polyfills/classList.js new file mode 100644 index 000000000..e040d70d9 --- /dev/null +++ b/examples/SmartSwitch/data_src/js_css_src/styled-notifications/src/polyfills/classList.js @@ -0,0 +1,68 @@ +(function () { + if (typeof window.Element === 'undefined' || 'classList' in document.documentElement) return; + + var prototype = Array.prototype, + push = prototype.push, + splice = prototype.splice, + join = prototype.join; + + function DOMTokenList(el) { + this.el = el; + // The className needs to be trimmed and split on whitespace + // to retrieve a list of classes. + var classes = el.className.replace(/^\s+|\s+$/g,'').split(/\s+/); + for (var i = 0; i < classes.length; i++) { + push.call(this, classes[i]); + } + } + + DOMTokenList.prototype = { + add: function(token) { + if(this.contains(token)) return; + push.call(this, token); + this.el.className = this.toString(); + }, + contains: function(token) { + return this.el.className.indexOf(token) != -1; + }, + item: function(index) { + return this[index] || null; + }, + remove: function(token) { + if (!this.contains(token)) return; + for (var i = 0; i < this.length; i++) { + if (this[i] == token) break; + } + splice.call(this, i, 1); + this.el.className = this.toString(); + }, + toString: function() { + return join.call(this, ' '); + }, + toggle: function(token) { + if (!this.contains(token)) { + this.add(token); + } else { + this.remove(token); + } + + return this.contains(token); + } + }; + + window.DOMTokenList = DOMTokenList; + + function defineElementGetter (obj, prop, getter) { + if (Object.defineProperty) { + Object.defineProperty(obj, prop,{ + get : getter + }); + } else { + obj.__defineGetter__(prop, getter); + } + } + + defineElementGetter(Element.prototype, 'classList', function () { + return new DOMTokenList(this); + }); +})(); \ No newline at end of file diff --git a/examples/SmartSwitch/data_src/js_css_src/styled-notifications/src/style.scss b/examples/SmartSwitch/data_src/js_css_src/styled-notifications/src/style.scss new file mode 100644 index 000000000..733bfd590 --- /dev/null +++ b/examples/SmartSwitch/data_src/js_css_src/styled-notifications/src/style.scss @@ -0,0 +1,134 @@ +// Base colors +$success: #51A351; +$info: #2F96B4; +$warning: #f87400; +$error: #BD362F; +$grey: #999999; + +.ncf-container { + font-size: 14px; + box-sizing: border-box; + position: fixed; + z-index: 999999; + + &.nfc-top-left { + top: 12px; + left: 12px; + } + + &.nfc-top-right { + top: 12px; + right: 12px; + } + + &.nfc-bottom-right { + bottom: 12px; + right: 12px; + } + + &.nfc-bottom-left { + bottom: 12px; + left: 12px; + } + + @media (max-width: 767px) { + left: 0; + right: 0; + } + + .ncf { + background: #ffffff; + transition: .3s ease; + position: relative; + pointer-events: auto; + overflow: hidden; + margin: 0 0 6px; + padding: 30px; + width: 300px; + border-radius: 3px 3px 3px 3px; + box-shadow: 0 0 12px $grey; + color: #000000; + opacity: 0.9; + -ms-filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=90); + filter: alpha(opacity=90); + background-position: 15px center !important; + background-repeat: no-repeat !important; + + // Prevent annoying text selection + -webkit-user-select: none; /* Chrome all / Safari all */ + -moz-user-select: none; /* Firefox all */ + -ms-user-select: none; /* IE 10+ */ + user-select: none; /* Likely future */ + + &:hover { + box-shadow: 0 0 12px #000000; + opacity: 1; + cursor: pointer; + } + + .ncf-title { + font-weight: bold; + font-size: 16px; + text-align: left; + margin-top: 0; + margin-bottom: 6px; + word-wrap: break-word; + } + + .nfc-message { + margin: 0; + text-align: left; + word-wrap: break-word; + } + } + + // Themes + .success { + background: $success; + color: #ffffff; + padding: 15px 15px 15px 50px; + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAADsSURBVEhLY2AYBfQMgf///3P8+/evAIgvA/FsIF+BavYDDWMBGroaSMMBiE8VC7AZDrIFaMFnii3AZTjUgsUUWUDA8OdAH6iQbQEhw4HyGsPEcKBXBIC4ARhex4G4BsjmweU1soIFaGg/WtoFZRIZdEvIMhxkCCjXIVsATV6gFGACs4Rsw0EGgIIH3QJYJgHSARQZDrWAB+jawzgs+Q2UO49D7jnRSRGoEFRILcdmEMWGI0cm0JJ2QpYA1RDvcmzJEWhABhD/pqrL0S0CWuABKgnRki9lLseS7g2AlqwHWQSKH4oKLrILpRGhEQCw2LiRUIa4lwAAAABJRU5ErkJggg=="); + } + + .info { + background: $info; + color: #ffffff; + padding: 15px 15px 15px 50px; + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGwSURBVEhLtZa9SgNBEMc9sUxxRcoUKSzSWIhXpFMhhYWFhaBg4yPYiWCXZxBLERsLRS3EQkEfwCKdjWJAwSKCgoKCcudv4O5YLrt7EzgXhiU3/4+b2ckmwVjJSpKkQ6wAi4gwhT+z3wRBcEz0yjSseUTrcRyfsHsXmD0AmbHOC9Ii8VImnuXBPglHpQ5wwSVM7sNnTG7Za4JwDdCjxyAiH3nyA2mtaTJufiDZ5dCaqlItILh1NHatfN5skvjx9Z38m69CgzuXmZgVrPIGE763Jx9qKsRozWYw6xOHdER+nn2KkO+Bb+UV5CBN6WC6QtBgbRVozrahAbmm6HtUsgtPC19tFdxXZYBOfkbmFJ1VaHA1VAHjd0pp70oTZzvR+EVrx2Ygfdsq6eu55BHYR8hlcki+n+kERUFG8BrA0BwjeAv2M8WLQBtcy+SD6fNsmnB3AlBLrgTtVW1c2QN4bVWLATaIS60J2Du5y1TiJgjSBvFVZgTmwCU+dAZFoPxGEEs8nyHC9Bwe2GvEJv2WXZb0vjdyFT4Cxk3e/kIqlOGoVLwwPevpYHT+00T+hWwXDf4AJAOUqWcDhbwAAAAASUVORK5CYII="); + } + + .warning { + background: $warning; + color: #ffffff; + padding: 15px 15px 15px 50px; + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGYSURBVEhL5ZSvTsNQFMbXZGICMYGYmJhAQIJAICYQPAACiSDB8AiICQQJT4CqQEwgJvYASAQCiZiYmJhAIBATCARJy+9rTsldd8sKu1M0+dLb057v6/lbq/2rK0mS/TRNj9cWNAKPYIJII7gIxCcQ51cvqID+GIEX8ASG4B1bK5gIZFeQfoJdEXOfgX4QAQg7kH2A65yQ87lyxb27sggkAzAuFhbbg1K2kgCkB1bVwyIR9m2L7PRPIhDUIXgGtyKw575yz3lTNs6X4JXnjV+LKM/m3MydnTbtOKIjtz6VhCBq4vSm3ncdrD2lk0VgUXSVKjVDJXJzijW1RQdsU7F77He8u68koNZTz8Oz5yGa6J3H3lZ0xYgXBK2QymlWWA+RWnYhskLBv2vmE+hBMCtbA7KX5drWyRT/2JsqZ2IvfB9Y4bWDNMFbJRFmC9E74SoS0CqulwjkC0+5bpcV1CZ8NMej4pjy0U+doDQsGyo1hzVJttIjhQ7GnBtRFN1UarUlH8F3xict+HY07rEzoUGPlWcjRFRr4/gChZgc3ZL2d8oAAAAASUVORK5CYII="); + } + + .error { + background: $error; + color: #ffffff; + padding: 15px 15px 15px 50px; + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAHOSURBVEhLrZa/SgNBEMZzh0WKCClSCKaIYOED+AAKeQQLG8HWztLCImBrYadgIdY+gIKNYkBFSwu7CAoqCgkkoGBI/E28PdbLZmeDLgzZzcx83/zZ2SSXC1j9fr+I1Hq93g2yxH4iwM1vkoBWAdxCmpzTxfkN2RcyZNaHFIkSo10+8kgxkXIURV5HGxTmFuc75B2RfQkpxHG8aAgaAFa0tAHqYFfQ7Iwe2yhODk8+J4C7yAoRTWI3w/4klGRgR4lO7Rpn9+gvMyWp+uxFh8+H+ARlgN1nJuJuQAYvNkEnwGFck18Er4q3egEc/oO+mhLdKgRyhdNFiacC0rlOCbhNVz4H9FnAYgDBvU3QIioZlJFLJtsoHYRDfiZoUyIxqCtRpVlANq0EU4dApjrtgezPFad5S19Wgjkc0hNVnuF4HjVA6C7QrSIbylB+oZe3aHgBsqlNqKYH48jXyJKMuAbiyVJ8KzaB3eRc0pg9VwQ4niFryI68qiOi3AbjwdsfnAtk0bCjTLJKr6mrD9g8iq/S/B81hguOMlQTnVyG40wAcjnmgsCNESDrjme7wfftP4P7SP4N3CJZdvzoNyGq2c/HWOXJGsvVg+RA/k2MC/wN6I2YA2Pt8GkAAAAASUVORK5CYII=") !important; + } + + button { + position: relative; + right: -0.3em; + top: -0.3em; + float: right; + font-weight: bold; + color: #FFFFFF; + text-shadow: 0 1px 0 #ffffff; + opacity: 0.8; + line-height: 1; + font-size: 16px; + padding: 0; + cursor: pointer; + background: transparent; + border: 0; + + &:hover { + opacity: 1; + } + } +} diff --git a/examples/SmartSwitch/data_src/js_css_src/styled-notifications/webpack.config.js b/examples/SmartSwitch/data_src/js_css_src/styled-notifications/webpack.config.js new file mode 100644 index 000000000..36a4ca3d1 --- /dev/null +++ b/examples/SmartSwitch/data_src/js_css_src/styled-notifications/webpack.config.js @@ -0,0 +1,41 @@ +const webpack = require('webpack'); +const ExtractTextPlugin = require('extract-text-webpack-plugin'); + +const extractSass = new ExtractTextPlugin({ + filename: 'notifications.css', + disable: process.env.NODE_ENV === 'development' +}); + +module.exports = { + entry: ['./src/index.js', './src/style.scss'], + output: { + path: __dirname + '/dist', + filename: 'notifications.js' + }, + module: { + rules: [ + { + test: /\.js$/, + loader: 'babel-loader', + query: { + presets: ['babel-preset-es2015', 'es2015-ie'] + } + }, + { + test: /\.scss$/, + use: extractSass.extract({ + use: [{ + loader: 'css-loader' + }, { + loader: 'sass-loader' + }], + // use style-loader in development + fallback: 'style-loader' + }) + } + ], + }, + plugins: [ + extractSass + ] +}; \ No newline at end of file diff --git a/examples/SmartSwitch/data_src/js_css_src/worker-html.js b/examples/SmartSwitch/data_src/js_css_src/worker-html.js new file mode 100644 index 000000000..58a39b130 --- /dev/null +++ b/examples/SmartSwitch/data_src/js_css_src/worker-html.js @@ -0,0 +1 @@ +"no use strict";(function(e){function t(e,t){var n=e,r="";while(n){var i=t[n];if(typeof i=="string")return i+r;if(i)return i.location.replace(/\/*$/,"/")+(r||i.main||i.name);if(i===!1)return"";var s=n.lastIndexOf("/");if(s===-1)break;r=n.substr(s)+r,n=n.slice(0,s)}return e}if(typeof e.window!="undefined"&&e.document)return;if(e.require&&e.define)return;e.console||(e.console=function(){var e=Array.prototype.slice.call(arguments,0);postMessage({type:"log",data:e})},e.console.error=e.console.warn=e.console.log=e.console.trace=e.console),e.window=e,e.ace=e,e.onerror=function(e,t,n,r,i){postMessage({type:"error",data:{message:e,data:i.data,file:t,line:n,col:r,stack:i.stack}})},e.normalizeModule=function(t,n){if(n.indexOf("!")!==-1){var r=n.split("!");return e.normalizeModule(t,r[0])+"!"+e.normalizeModule(t,r[1])}if(n.charAt(0)=="."){var i=t.split("/").slice(0,-1).join("/");n=(i?i+"/":"")+n;while(n.indexOf(".")!==-1&&s!=n){var s=n;n=n.replace(/^\.\//,"").replace(/\/\.\//,"/").replace(/[^\/]+\/\.\.\//,"")}}return n},e.require=function(r,i){i||(i=r,r=null);if(!i.charAt)throw new Error("worker.js require() accepts only (parentId, id) as arguments");i=e.normalizeModule(r,i);var s=e.require.modules[i];if(s)return s.initialized||(s.initialized=!0,s.exports=s.factory().exports),s.exports;if(!e.require.tlns)return console.log("unable to load "+i);var o=t(i,e.require.tlns);return o.slice(-3)!=".js"&&(o+=".js"),e.require.id=i,e.require.modules[i]={},importScripts(o),e.require(r,i)},e.require.modules={},e.require.tlns={},e.define=function(t,n,r){arguments.length==2?(r=n,typeof t!="string"&&(n=t,t=e.require.id)):arguments.length==1&&(r=t,n=[],t=e.require.id);if(typeof r!="function"){e.require.modules[t]={exports:r,initialized:!0};return}n.length||(n=["require","exports","module"]);var i=function(n){return e.require(t,n)};e.require.modules[t]={exports:{},factory:function(){var e=this,t=r.apply(this,n.map(function(t){switch(t){case"require":return i;case"exports":return e.exports;case"module":return e;default:return i(t)}}));return t&&(e.exports=t),e}}},e.define.amd={},require.tlns={},e.initBaseUrls=function(t){for(var n in t)require.tlns[n]=t[n]},e.initSender=function(){var n=e.require("ace/lib/event_emitter").EventEmitter,r=e.require("ace/lib/oop"),i=function(){};return function(){r.implement(this,n),this.callback=function(e,t){postMessage({type:"call",id:t,data:e})},this.emit=function(e,t){postMessage({type:"event",name:e,data:t})}}.call(i.prototype),new i};var n=e.main=null,r=e.sender=null;e.onmessage=function(t){var i=t.data;if(i.event&&r)r._signal(i.event,i.data);else if(i.command)if(n[i.command])n[i.command].apply(n,i.args);else{if(!e[i.command])throw new Error("Unknown command:"+i.command);e[i.command].apply(e,i.args)}else if(i.init){e.initBaseUrls(i.tlns),require("ace/lib/es5-shim"),r=e.sender=e.initSender();var s=require(i.module)[i.classname];n=e.main=new s(r)}}})(this),define("ace/lib/oop",["require","exports","module"],function(e,t,n){"use strict";t.inherits=function(e,t){e.super_=t,e.prototype=Object.create(t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}})},t.mixin=function(e,t){for(var n in t)e[n]=t[n];return e},t.implement=function(e,n){t.mixin(e,n)}}),define("ace/lib/lang",["require","exports","module"],function(e,t,n){"use strict";t.last=function(e){return e[e.length-1]},t.stringReverse=function(e){return e.split("").reverse().join("")},t.stringRepeat=function(e,t){var n="";while(t>0){t&1&&(n+=e);if(t>>=1)e+=e}return n};var r=/^\s\s*/,i=/\s\s*$/;t.stringTrimLeft=function(e){return e.replace(r,"")},t.stringTrimRight=function(e){return e.replace(i,"")},t.copyObject=function(e){var t={};for(var n in e)t[n]=e[n];return t},t.copyArray=function(e){var t=[];for(var n=0,r=e.length;n ["+this.end.row+"/"+this.end.column+"]"},this.contains=function(e,t){return this.compare(e,t)==0},this.compareRange=function(e){var t,n=e.end,r=e.start;return t=this.compare(n.row,n.column),t==1?(t=this.compare(r.row,r.column),t==1?2:t==0?1:0):t==-1?-2:(t=this.compare(r.row,r.column),t==-1?-1:t==1?42:0)},this.comparePoint=function(e){return this.compare(e.row,e.column)},this.containsRange=function(e){return this.comparePoint(e.start)==0&&this.comparePoint(e.end)==0},this.intersects=function(e){var t=this.compareRange(e);return t==-1||t==0||t==1},this.isEnd=function(e,t){return this.end.row==e&&this.end.column==t},this.isStart=function(e,t){return this.start.row==e&&this.start.column==t},this.setStart=function(e,t){typeof e=="object"?(this.start.column=e.column,this.start.row=e.row):(this.start.row=e,this.start.column=t)},this.setEnd=function(e,t){typeof e=="object"?(this.end.column=e.column,this.end.row=e.row):(this.end.row=e,this.end.column=t)},this.inside=function(e,t){return this.compare(e,t)==0?this.isEnd(e,t)||this.isStart(e,t)?!1:!0:!1},this.insideStart=function(e,t){return this.compare(e,t)==0?this.isEnd(e,t)?!1:!0:!1},this.insideEnd=function(e,t){return this.compare(e,t)==0?this.isStart(e,t)?!1:!0:!1},this.compare=function(e,t){return!this.isMultiLine()&&e===this.start.row?tthis.end.column?1:0:ethis.end.row?1:this.start.row===e?t>=this.start.column?0:-1:this.end.row===e?t<=this.end.column?0:1:0},this.compareStart=function(e,t){return this.start.row==e&&this.start.column==t?-1:this.compare(e,t)},this.compareEnd=function(e,t){return this.end.row==e&&this.end.column==t?1:this.compare(e,t)},this.compareInside=function(e,t){return this.end.row==e&&this.end.column==t?1:this.start.row==e&&this.start.column==t?-1:this.compare(e,t)},this.clipRows=function(e,t){if(this.end.row>t)var n={row:t+1,column:0};else if(this.end.rowt)var r={row:t+1,column:0};else if(this.start.row=0&&t.row=0&&t.column<=e[t.row].length}function s(e,t){t.action!="insert"&&t.action!="remove"&&r(t,"delta.action must be 'insert' or 'remove'"),t.lines instanceof Array||r(t,"delta.lines must be an Array"),(!t.start||!t.end)&&r(t,"delta.start/end must be an present");var n=t.start;i(e,t.start)||r(t,"delta.start must be contained in document");var s=t.end;t.action=="remove"&&!i(e,s)&&r(t,"delta.end must contained in document for 'remove' actions");var o=s.row-n.row,u=s.column-(o==0?n.column:0);(o!=t.lines.length-1||t.lines[o].length!=u)&&r(t,"delta.range must match delta lines")}t.applyDelta=function(e,t,n){var r=t.start.row,i=t.start.column,s=e[r]||"";switch(t.action){case"insert":var o=t.lines;if(o.length===1)e[r]=s.substring(0,i)+t.lines[0]+s.substring(i);else{var u=[r,1].concat(t.lines);e.splice.apply(e,u),e[r]=s.substring(0,i)+e[r],e[r+t.lines.length-1]+=s.substring(i)}break;case"remove":var a=t.end.column,f=t.end.row;r===f?e[r]=s.substring(0,i)+s.substring(a):e.splice(r,f-r+1,s.substring(0,i)+e[f].substring(a))}}}),define("ace/lib/event_emitter",["require","exports","module"],function(e,t,n){"use strict";var r={},i=function(){this.propagationStopped=!0},s=function(){this.defaultPrevented=!0};r._emit=r._dispatchEvent=function(e,t){this._eventRegistry||(this._eventRegistry={}),this._defaultHandlers||(this._defaultHandlers={});var n=this._eventRegistry[e]||[],r=this._defaultHandlers[e];if(!n.length&&!r)return;if(typeof t!="object"||!t)t={};t.type||(t.type=e),t.stopPropagation||(t.stopPropagation=i),t.preventDefault||(t.preventDefault=s),n=n.slice();for(var o=0;othis.row)return;var n=t(e,{row:this.row,column:this.column},this.$insertRight);this.setPosition(n.row,n.column,!0)},this.setPosition=function(e,t,n){var r;n?r={row:e,column:t}:r=this.$clipPositionToDocument(e,t);if(this.row==r.row&&this.column==r.column)return;var i={row:this.row,column:this.column};this.row=r.row,this.column=r.column,this._signal("change",{old:i,value:r})},this.detach=function(){this.document.removeEventListener("change",this.$onChange)},this.attach=function(e){this.document=e||this.document,this.document.on("change",this.$onChange)},this.$clipPositionToDocument=function(e,t){var n={};return e>=this.document.getLength()?(n.row=Math.max(0,this.document.getLength()-1),n.column=this.document.getLine(n.row).length):e<0?(n.row=0,n.column=0):(n.row=e,n.column=Math.min(this.document.getLine(n.row).length,Math.max(0,t))),t<0&&(n.column=0),n}}).call(s.prototype)}),define("ace/document",["require","exports","module","ace/lib/oop","ace/apply_delta","ace/lib/event_emitter","ace/range","ace/anchor"],function(e,t,n){"use strict";var r=e("./lib/oop"),i=e("./apply_delta").applyDelta,s=e("./lib/event_emitter").EventEmitter,o=e("./range").Range,u=e("./anchor").Anchor,a=function(e){this.$lines=[""],e.length===0?this.$lines=[""]:Array.isArray(e)?this.insertMergedLines({row:0,column:0},e):this.insert({row:0,column:0},e)};(function(){r.implement(this,s),this.setValue=function(e){var t=this.getLength()-1;this.remove(new o(0,0,t,this.getLine(t).length)),this.insert({row:0,column:0},e)},this.getValue=function(){return this.getAllLines().join(this.getNewLineCharacter())},this.createAnchor=function(e,t){return new u(this,e,t)},"aaa".split(/a/).length===0?this.$split=function(e){return e.replace(/\r\n|\r/g,"\n").split("\n")}:this.$split=function(e){return e.split(/\r\n|\r|\n/)},this.$detectNewLine=function(e){var t=e.match(/^.*?(\r\n|\r|\n)/m);this.$autoNewLine=t?t[1]:"\n",this._signal("changeNewLineMode")},this.getNewLineCharacter=function(){switch(this.$newLineMode){case"windows":return"\r\n";case"unix":return"\n";default:return this.$autoNewLine||"\n"}},this.$autoNewLine="",this.$newLineMode="auto",this.setNewLineMode=function(e){if(this.$newLineMode===e)return;this.$newLineMode=e,this._signal("changeNewLineMode")},this.getNewLineMode=function(){return this.$newLineMode},this.isNewLine=function(e){return e=="\r\n"||e=="\r"||e=="\n"},this.getLine=function(e){return this.$lines[e]||""},this.getLines=function(e,t){return this.$lines.slice(e,t+1)},this.getAllLines=function(){return this.getLines(0,this.getLength())},this.getLength=function(){return this.$lines.length},this.getTextRange=function(e){return this.getLinesForRange(e).join(this.getNewLineCharacter())},this.getLinesForRange=function(e){var t;if(e.start.row===e.end.row)t=[this.getLine(e.start.row).substring(e.start.column,e.end.column)];else{t=this.getLines(e.start.row,e.end.row),t[0]=(t[0]||"").substring(e.start.column);var n=t.length-1;e.end.row-e.start.row==n&&(t[n]=t[n].substring(0,e.end.column))}return t},this.insertLines=function(e,t){return console.warn("Use of document.insertLines is deprecated. Use the insertFullLines method instead."),this.insertFullLines(e,t)},this.removeLines=function(e,t){return console.warn("Use of document.removeLines is deprecated. Use the removeFullLines method instead."),this.removeFullLines(e,t)},this.insertNewLine=function(e){return console.warn("Use of document.insertNewLine is deprecated. Use insertMergedLines(position, ['', '']) instead."),this.insertMergedLines(e,["",""])},this.insert=function(e,t){return this.getLength()<=1&&this.$detectNewLine(t),this.insertMergedLines(e,this.$split(t))},this.insertInLine=function(e,t){var n=this.clippedPos(e.row,e.column),r=this.pos(e.row,e.column+t.length);return this.applyDelta({start:n,end:r,action:"insert",lines:[t]},!0),this.clonePos(r)},this.clippedPos=function(e,t){var n=this.getLength();e===undefined?e=n:e<0?e=0:e>=n&&(e=n-1,t=undefined);var r=this.getLine(e);return t==undefined&&(t=r.length),t=Math.min(Math.max(t,0),r.length),{row:e,column:t}},this.clonePos=function(e){return{row:e.row,column:e.column}},this.pos=function(e,t){return{row:e,column:t}},this.$clipPosition=function(e){var t=this.getLength();return e.row>=t?(e.row=Math.max(0,t-1),e.column=this.getLine(t-1).length):(e.row=Math.max(0,e.row),e.column=Math.min(Math.max(e.column,0),this.getLine(e.row).length)),e},this.insertFullLines=function(e,t){e=Math.min(Math.max(e,0),this.getLength());var n=0;e0,r=t=0&&this.applyDelta({start:this.pos(e,this.getLine(e).length),end:this.pos(e+1,0),action:"remove",lines:["",""]})},this.replace=function(e,t){e instanceof o||(e=o.fromPoints(e.start,e.end));if(t.length===0&&e.isEmpty())return e.start;if(t==this.getTextRange(e))return e.end;this.remove(e);var n;return t?n=this.insert(e.start,t):n=e.start,n},this.applyDeltas=function(e){for(var t=0;t=0;t--)this.revertDelta(e[t])},this.applyDelta=function(e,t){var n=e.action=="insert";if(n?e.lines.length<=1&&!e.lines[0]:!o.comparePoints(e.start,e.end))return;n&&e.lines.length>2e4&&this.$splitAndapplyLargeDelta(e,2e4),i(this.$lines,e,t),this._signal("change",e)},this.$splitAndapplyLargeDelta=function(e,t){var n=e.lines,r=n.length,i=e.start.row,s=e.start.column,o=0,u=0;do{o=u,u+=t-1;var a=n.slice(o,u);if(u>r){e.lines=a,e.start.row=i+o,e.start.column=s;break}a.push(""),this.applyDelta({start:this.pos(i+o,s),end:this.pos(i+u,s=0),action:e.action,lines:a},!0)}while(!0)},this.revertDelta=function(e){this.applyDelta({start:this.clonePos(e.start),end:this.clonePos(e.end),action:e.action=="insert"?"remove":"insert",lines:e.lines.slice()})},this.indexToPosition=function(e,t){var n=this.$lines||this.getAllLines(),r=this.getNewLineCharacter().length;for(var i=t||0,s=n.length;i=0;n--){var r=this.elements[n];if(r.localName===e)return!0;if(t(r))return!1}},l.prototype.push=function(e){this.elements.push(e)},l.prototype.pushHtmlElement=function(e){this.rootNode=e.node,this.push(e)},l.prototype.pushHeadElement=function(e){this.headElement=e.node,this.push(e)},l.prototype.pushBodyElement=function(e){this.bodyElement=e.node,this.push(e)},l.prototype.pop=function(){return this.elements.pop()},l.prototype.remove=function(e){this.elements.splice(this.elements.indexOf(e),1)},l.prototype.popUntilPopped=function(e){var t;do t=this.pop();while(t.localName!=e)},l.prototype.popUntilTableScopeMarker=function(){while(!s(this.top))this.pop()},l.prototype.popUntilTableBodyScopeMarker=function(){while(!o(this.top))this.pop()},l.prototype.popUntilTableRowScopeMarker=function(){while(!u(this.top))this.pop()},l.prototype.item=function(e){return this.elements[e]},l.prototype.contains=function(e){return this.elements.indexOf(e)!==-1},l.prototype.inScope=function(e){return this._inScope(e,r)},l.prototype.inListItemScope=function(e){return this._inScope(e,i)},l.prototype.inTableScope=function(e){return this._inScope(e,s)},l.prototype.inButtonScope=function(e){return this._inScope(e,a)},l.prototype.inSelectScope=function(e){return this._inScope(e,f)},l.prototype.hasNumberedHeaderElementInScope=function(){for(var e=this.elements.length-1;e>=0;e--){var t=this.elements[e];if(t.isNumberedHeader())return!0;if(r(t))return!1}},l.prototype.furthestBlockForFormattingElement=function(e){var t=null;for(var n=this.elements.length-1;n>=0;n--){var r=this.elements[n];if(r.node===e)break;r.isSpecial()&&(t=r)}return t},l.prototype.findIndex=function(e){for(var t=this.elements.length-1;t>=0;t--)if(this.elements[t].localName==e)return t;return-1},l.prototype.remove_openElements_until=function(e){var t=!1,n;while(!t)n=this.elements.pop(),t=e(n);return n},Object.defineProperty(l.prototype,"top",{get:function(){return this.elements[this.elements.length-1]}}),Object.defineProperty(l.prototype,"length",{get:function(){return this.elements.length}}),n.ElementStack=l},{}],2:[function(e,t,n){function o(e){return e>="0"&&e<="9"||e>="a"&&e<="z"||e>="A"&&e<="Z"}function u(e){return e>="0"&&e<="9"||e>="a"&&e<="f"||e>="A"&&e<="F"}function a(e){return e>="0"&&e<="9"}var r=e("html5-entities"),i=e("./InputStream").InputStream,s={};Object.keys(r).forEach(function(e){for(var t=0;t65535&&d<=1114111){d-=65536;var m=((1047552&d)>>10)+55296,g=(1023&d)+56320;f=String.fromCharCode(m,g)}else f=String.fromCharCode(d);return c!==";"&&(t._parseError("numeric-entity-without-semicolon"),e.unget(c)),f}return e.unget(l),t._parseError("expected-numeric-entity"),!1}if(c>="a"&&c<="z"||c>="A"&&c<="Z"){var y="";while(s[l]){r[l]&&(y=l);if(c==";")break;c=e.char();if(c===i.EOF)break;l+=c}return y?(f=r[y],c===";"||!n||!o(c)&&c!=="="?(l.length>y.length&&e.unget(l.substring(y.length)),c!==";"&&t._parseError("named-entity-without-semicolon"),f):(e.unget(l),!1)):(t._parseError("expected-named-entity"),e.unget(l),!1)}},f.replaceEntityNumbers=function(e){switch(e){case 0:return 65533;case 19:return 16;case 128:return 8364;case 129:return 129;case 130:return 8218;case 131:return 402;case 132:return 8222;case 133:return 8230;case 134:return 8224;case 135:return 8225;case 136:return 710;case 137:return 8240;case 138:return 352;case 139:return 8249;case 140:return 338;case 141:return 141;case 142:return 381;case 143:return 143;case 144:return 144;case 145:return 8216;case 146:return 8217;case 147:return 8220;case 148:return 8221;case 149:return 8226;case 150:return 8211;case 151:return 8212;case 152:return 732;case 153:return 8482;case 154:return 353;case 155:return 8250;case 156:return 339;case 157:return 157;case 158:return 382;case 159:return 376;default:if(e>=55296&&e<=57343||e>1114111)return 65533;if(e>=1&&e<=8||e>=14&&e<=31||e>=127&&e<=159||e>=64976&&e<=65007||e==11||e==65534||e==131070||e==3145726||e==196607||e==262142||e==262143||e==327678||e==327679||e==393214||e==393215||e==458750||e==458751||e==524286||e==524287||e==589822||e==589823||e==655358||e==655359||e==720894||e==720895||e==786430||e==786431||e==851966||e==851967||e==917502||e==917503||e==983038||e==983039||e==1048574||e==1048575||e==1114110||e==1114111)return e}},n.EntityParser=f},{"./InputStream":3,"html5-entities":12}],3:[function(e,t,n){function r(){this.data="",this.start=0,this.committed=0,this.eof=!1,this.lastLocation={line:0,column:0}}r.EOF=-1,r.DRAIN=-2,r.prototype={slice:function(){if(this.start>=this.data.length){if(!this.eof)throw r.DRAIN;return r.EOF}return this.data.slice(this.start,this.data.length)},"char":function(){if(!this.eof&&this.start>=this.data.length-1)throw r.DRAIN;if(this.start>=this.data.length)return r.EOF;var e=this.data[this.start++];return e==="\r"&&(e="\n"),e},advance:function(e){this.start+=e;if(this.start>=this.data.length){if(!this.eof)throw r.DRAIN;return r.EOF}this.committed>this.data.length/2&&(this.lastLocation=this.location(),this.data=this.data.slice(this.committed),this.start=this.start-this.committed,this.committed=0)},matchWhile:function(e){if(this.eof&&this.start>=this.data.length)return"";var t=new RegExp("^"+e+"+"),n=t.exec(this.slice());if(n){if(!this.eof&&n[0].length==this.data.length-this.start)throw r.DRAIN;return this.advance(n[0].length),n[0]}return""},matchUntil:function(e){var t,n;n=this.slice();if(n===r.EOF)return"";if(t=(new RegExp(e+(this.eof?"|$":""))).exec(n)){var i=this.data.slice(this.start,this.start+t.index);return this.advance(t.index),i.replace(/\r/g,"\n").replace(/\n{2,}/g,"\n")}throw r.DRAIN},append:function(e){this.data+=e},shift:function(e){if(!this.eof&&this.start+e>=this.data.length)throw r.DRAIN;if(this.eof&&this.start>=this.data.length)return r.EOF;var t=this.data.slice(this.start,this.start+e).toString();return this.advance(Math.min(e,this.data.length-this.start)),t},peek:function(e){if(!this.eof&&this.start+e>=this.data.length)throw r.DRAIN;return this.eof&&this.start>=this.data.length?r.EOF:this.data.slice(this.start,Math.min(this.start+e,this.data.length)).toString()},length:function(){return this.data.length-this.start-1},unget:function(e){if(e===r.EOF)return;this.start-=e.length},undo:function(){this.start=this.committed},commit:function(){this.committed=this.start},location:function(){var e=this.lastLocation.line,t=this.lastLocation.column,n=this.data.slice(0,this.committed),r=n.match(/\n/g),i=r?e+r.length:e,s=r?n.length-n.lastIndexOf("\n")-1:t+n.length;return{line:i,column:s}}},n.InputStream=r},{}],4:[function(e,t,n){function i(e,t,n,r){this.localName=t,this.namespaceURI=e,this.attributes=n,this.node=r}function s(e,t){for(var n=0;n-1},i.prototype.isFosterParenting=function(){return this.namespaceURI==="http://www.w3.org/1999/xhtml"?this.localName==="table"||this.localName==="tbody"||this.localName==="tfoot"||this.localName==="thead"||this.localName==="tr":!1},i.prototype.isNumberedHeader=function(){return this.namespaceURI==="http://www.w3.org/1999/xhtml"?this.localName==="h1"||this.localName==="h2"||this.localName==="h3"||this.localName==="h4"||this.localName==="h5"||this.localName==="h6":!1},i.prototype.isForeign=function(){return this.namespaceURI!="http://www.w3.org/1999/xhtml"},i.prototype.isHtmlIntegrationPoint=function(){if(this.namespaceURI==="http://www.w3.org/1998/Math/MathML"){if(this.localName!=="annotation-xml")return!1;var e=s(this,"encoding");return e?(e=e.toLowerCase(),e==="text/html"||e==="application/xhtml+xml"):!1}return this.namespaceURI==="http://www.w3.org/2000/svg"?this.localName==="foreignObject"||this.localName==="desc"||this.localName==="title":!1},i.prototype.isMathMLTextIntegrationPoint=function(){return this.namespaceURI==="http://www.w3.org/1998/Math/MathML"?this.localName==="mi"||this.localName==="mo"||this.localName==="mn"||this.localName==="ms"||this.localName==="mtext":!1},n.StackItem=i},{}],5:[function(e,t,n){function s(e){return e===" "||e==="\n"||e===" "||e==="\r"||e==="\f"}function o(e){return e>="A"&&e<="Z"||e>="a"&&e<="z"}function u(e){this._tokenHandler=e,this._state=u.DATA,this._inputStream=new r,this._currentToken=null,this._temporaryBuffer="",this._additionalAllowedCharacter=""}var r=e("./InputStream").InputStream,i=e("./EntityParser").EntityParser;u.prototype._parseError=function(e,t){this._tokenHandler.parseError(e,t)},u.prototype._emitToken=function(e){if(e.type==="StartTag")for(var t=1;t"&&r?(t._currentToken={type:"EndTag",name:this._temporaryBuffer,data:[],selfClosing:!1},t._emitCurrentToken(),t.setState(n)):o(i)?(this._temporaryBuffer+=i,e.commit()):(t._emitToken({type:"Characters",data:""&&r?(t._currentToken={type:"EndTag",name:this._temporaryBuffer,data:[],selfClosing:!1},t._emitCurrentToken(),t.setState(n)):o(i)?(this._temporaryBuffer+=i,e.commit()):(t._emitToken({type:"Characters",data:""&&n?(t._currentToken={type:"EndTag",name:"script",data:[],selfClosing:!1},t._emitCurrentToken()):o(r)?(this._temporaryBuffer+=r,e.commit()):(t._emitToken({type:"Characters",data:""?(t._emitToken({type:"Characters",data:">"}),t.setState(p)):i==="\0"?(t._parseError("invalid-codepoint"),t._emitToken({type:"Characters",data:"\ufffd"}),t.setState(N)):(t._emitToken({type:"Characters",data:i}),t.setState(N)),!0}function L(e){var n=e.char();return n==="/"?(this._temporaryBuffer="",t.setState(A)):o(n)?(t._emitToken({type:"Characters",data:"<"+n}),this._temporaryBuffer=n,t.setState(M)):(t._emitToken({type:"Characters",data:"<"}),e.unget(n),t.setState(N)),!0}function A(e){var n=e.char();return o(n)?(this._temporaryBuffer=n,t.setState(O)):(t._emitToken({type:"Characters",data:""&&r?(t._currentToken={type:"EndTag",name:"script",data:[],selfClosing:!1},t.setState(n),t._emitCurrentToken()):o(i)?(this._temporaryBuffer+=i,e.commit()):(t._emitToken({type:"Characters",data:""?(t._emitToken({type:"Characters",data:n}),this._temporaryBuffer.toLowerCase()==="script"?t.setState(_):t.setState(N)):o(n)?(t._emitToken({type:"Characters",data:n}),this._temporaryBuffer+=n,e.commit()):(e.unget(n),t.setState(N)),!0}function _(e){var i=e.char();return i===r.EOF?(t._parseError("eof-in-script"),e.unget(i),t.setState(n)):i==="-"?(t._emitToken({type:"Characters",data:"-"}),t.setState(D)):i==="<"?(t._emitToken({type:"Characters",data:"<"}),t.setState(H)):i==="\0"?(t._parseError("invalid-codepoint"),t._emitToken({type:"Characters",data:"\ufffd"}),e.commit()):(t._emitToken({type:"Characters",data:i}),e.commit()),!0}function D(e){var i=e.char();return i===r.EOF?(t._parseError("eof-in-script"),e.unget(i),t.setState(n)):i==="-"?(t._emitToken({type:"Characters",data:"-"}),t.setState(P)):i==="<"?(t._emitToken({type:"Characters",data:"<"}),t.setState(H)):i==="\0"?(t._parseError("invalid-codepoint"),t._emitToken({type:"Characters",data:"\ufffd"}),t.setState(_)):(t._emitToken({type:"Characters",data:i}),t.setState(_)),!0}function P(e){var i=e.char();return i===r.EOF?(t._parseError("eof-in-script"),e.unget(i),t.setState(n)):i==="-"?(t._emitToken({type:"Characters",data:"-"}),e.commit()):i==="<"?(t._emitToken({type:"Characters",data:"<"}),t.setState(H)):i===">"?(t._emitToken({type:"Characters",data:">"}),t.setState(p)):i==="\0"?(t._parseError("invalid-codepoint"),t._emitToken({type:"Characters",data:"\ufffd"}),t.setState(_)):(t._emitToken({type:"Characters",data:i}),t.setState(_)),!0}function H(e){var n=e.char();return n==="/"?(t._emitToken({type:"Characters",data:"/"}),this._temporaryBuffer="",t.setState(B)):(e.unget(n),t.setState(_)),!0}function B(e){var n=e.char();return s(n)||n==="/"||n===">"?(t._emitToken({type:"Characters",data:n}),this._temporaryBuffer.toLowerCase()==="script"?t.setState(N):t.setState(_)):o(n)?(t._emitToken({type:"Characters",data:n}),this._temporaryBuffer+=n,e.commit()):(e.unget(n),t.setState(_)),!0}function j(e){var i=e.char();return i===r.EOF?(t._parseError("bare-less-than-sign-at-eof"),t._emitToken({type:"Characters",data:"<"}),e.unget(i),t.setState(n)):o(i)?(t._currentToken={type:"StartTag",name:i.toLowerCase(),data:[]},t.setState(I)):i==="!"?t.setState(G):i==="/"?t.setState(F):i===">"?(t._parseError("expected-tag-name-but-got-right-bracket"),t._emitToken({type:"Characters",data:"<>"}),t.setState(n)):i==="?"?(t._parseError("expected-tag-name-but-got-question-mark"),e.unget(i),t.setState(Q)):(t._parseError("expected-tag-name"),t._emitToken({type:"Characters",data:"<"}),e.unget(i),t.setState(n)),!0}function F(e){var i=e.char();return i===r.EOF?(t._parseError("expected-closing-tag-but-got-eof"),t._emitToken({type:"Characters",data:""?(t._parseError("expected-closing-tag-but-got-right-bracket"),t.setState(n)):(t._parseError("expected-closing-tag-but-got-char",{data:i}),e.unget(i),t.setState(Q)),!0}function I(e){var i=e.char();return i===r.EOF?(t._parseError("eof-in-tag-name"),e.unget(i),t.setState(n)):s(i)?t.setState(q):o(i)?t._currentToken.name+=i.toLowerCase():i===">"?t._emitCurrentToken():i==="/"?t.setState(K):i==="\0"?(t._parseError("invalid-codepoint"),t._currentToken.name+="\ufffd"):t._currentToken.name+=i,e.commit(),!0}function q(e){var i=e.char();if(i===r.EOF)t._parseError("expected-attribute-name-but-got-eof"),e.unget(i),t.setState(n);else{if(s(i))return!0;o(i)?(t._currentToken.data.push({nodeName:i.toLowerCase(),nodeValue:""}),t.setState(R)):i===">"?t._emitCurrentToken():i==="/"?t.setState(K):i==="'"||i==='"'||i==="="||i==="<"?(t._parseError("invalid-character-in-attribute-name"),t._currentToken.data.push({nodeName:i,nodeValue:""}),t.setState(R)):i==="\0"?(t._parseError("invalid-codepoint"),t._currentToken.data.push({nodeName:"\ufffd",nodeValue:""})):(t._currentToken.data.push({nodeName:i,nodeValue:""}),t.setState(R))}return!0}function R(e){var i=e.char(),u=!0,a=!1;i===r.EOF?(t._parseError("eof-in-attribute-name"),e.unget(i),t.setState(n),a=!0):i==="="?t.setState(z):o(i)?(t._currentAttribute().nodeName+=i.toLowerCase(),u=!1):i===">"?a=!0:s(i)?t.setState(U):i==="/"?t.setState(K):i==="'"||i==='"'?(t._parseError("invalid-character-in-attribute-name"),t._currentAttribute().nodeName+=i,u=!1):i==="\0"?(t._parseError("invalid-codepoint"),t._currentAttribute().nodeName+="\ufffd"):(t._currentAttribute().nodeName+=i,u=!1);if(u){var f=t._currentToken.data,l=f[f.length-1];for(var c=f.length-2;c>=0;c--)if(l.nodeName===f[c].nodeName){t._parseError("duplicate-attribute",{name:l.nodeName}),l.nodeName=null;break}a&&t._emitCurrentToken()}else e.commit();return!0}function U(e){var i=e.char();if(i===r.EOF)t._parseError("expected-end-of-tag-but-got-eof"),e.unget(i),t.setState(n);else{if(s(i))return!0;i==="="?t.setState(z):i===">"?t._emitCurrentToken():o(i)?(t._currentToken.data.push({nodeName:i,nodeValue:""}),t.setState(R)):i==="/"?t.setState(K):i==="'"||i==='"'||i==="<"?(t._parseError("invalid-character-after-attribute-name"),t._currentToken.data.push({nodeName:i,nodeValue:""}),t.setState(R)):i==="\0"?(t._parseError("invalid-codepoint"),t._currentToken.data.push({nodeName:"\ufffd",nodeValue:""})):(t._currentToken.data.push({nodeName:i,nodeValue:""}),t.setState(R))}return!0}function z(e){var i=e.char();if(i===r.EOF)t._parseError("expected-attribute-value-but-got-eof"),e.unget(i),t.setState(n);else{if(s(i))return!0;i==='"'?t.setState(W):i==="&"?(t.setState(V),e.unget(i)):i==="'"?t.setState(X):i===">"?(t._parseError("expected-attribute-value-but-got-right-bracket"),t._emitCurrentToken()):i==="="||i==="<"||i==="`"?(t._parseError("unexpected-character-in-unquoted-attribute-value"),t._currentAttribute().nodeValue+=i,t.setState(V)):i==="\0"?(t._parseError("invalid-codepoint"),t._currentAttribute().nodeValue+="\ufffd"):(t._currentAttribute().nodeValue+=i,t.setState(V))}return!0}function W(e){var i=e.char();if(i===r.EOF)t._parseError("eof-in-attribute-value-double-quote"),e.unget(i),t.setState(n);else if(i==='"')t.setState(J);else if(i==="&")this._additionalAllowedCharacter='"',t.setState($);else if(i==="\0")t._parseError("invalid-codepoint"),t._currentAttribute().nodeValue+="\ufffd";else{var s=e.matchUntil('[\0"&]');i+=s,t._currentAttribute().nodeValue+=i}return!0}function X(e){var i=e.char();return i===r.EOF?(t._parseError("eof-in-attribute-value-single-quote"),e.unget(i),t.setState(n)):i==="'"?t.setState(J):i==="&"?(this._additionalAllowedCharacter="'",t.setState($)):i==="\0"?(t._parseError("invalid-codepoint"),t._currentAttribute().nodeValue+="\ufffd"):t._currentAttribute().nodeValue+=i+e.matchUntil("\0|['&]"),!0}function V(e){var i=e.char();if(i===r.EOF)t._parseError("eof-after-attribute-value"),e.unget(i),t.setState(n);else if(s(i))t.setState(q);else if(i==="&")this._additionalAllowedCharacter=">",t.setState($);else if(i===">")t._emitCurrentToken();else if(i==='"'||i==="'"||i==="="||i==="`"||i==="<")t._parseError("unexpected-character-in-unquoted-attribute-value"),t._currentAttribute().nodeValue+=i,e.commit();else if(i==="\0")t._parseError("invalid-codepoint"),t._currentAttribute().nodeValue+="\ufffd";else{var o=e.matchUntil("\0|[ \n \f \r&<>\"'=`]");o===r.EOF&&(t._parseError("eof-in-attribute-value-no-quotes"),t._emitCurrentToken()),e.commit(),t._currentAttribute().nodeValue+=i+o}return!0}function $(e){var n=i.consumeEntity(e,t,this._additionalAllowedCharacter);return this._currentAttribute().nodeValue+=n||"&",this._additionalAllowedCharacter==='"'?t.setState(W):this._additionalAllowedCharacter==="'"?t.setState(X):this._additionalAllowedCharacter===">"&&t.setState(V),!0}function J(e){var i=e.char();return i===r.EOF?(t._parseError("eof-after-attribute-value"),e.unget(i),t.setState(n)):s(i)?t.setState(q):i===">"?(t.setState(n),t._emitCurrentToken()):i==="/"?t.setState(K):(t._parseError("unexpected-character-after-attribute-value"),e.unget(i),t.setState(q)),!0}function K(e){var i=e.char();return i===r.EOF?(t._parseError("unexpected-eof-after-solidus-in-tag"),e.unget(i),t.setState(n)):i===">"?(t._currentToken.selfClosing=!0,t.setState(n),t._emitCurrentToken()):(t._parseError("unexpected-character-after-solidus-in-tag"),e.unget(i),t.setState(q)),!0}function Q(e){var r=e.matchUntil(">");return r=r.replace(/\u0000/g,"\ufffd"),e.char(),t._emitToken({type:"Comment",data:r}),t.setState(n),!0}function G(e){var n=e.shift(2);if(n==="--")t._currentToken={type:"Comment",data:""},t.setState(Z);else{var i=e.shift(5);if(i===r.EOF||n===r.EOF)return t._parseError("expected-dashes-or-doctype"),t.setState(Q),e.unget(n),!0;n+=i,n.toUpperCase()==="DOCTYPE"?(t._currentToken={type:"Doctype",name:"",publicId:null,systemId:null,forceQuirks:!1},t.setState(st)):t._tokenHandler.isCdataSectionAllowed()&&n==="[CDATA["?t.setState(Y):(t._parseError("expected-dashes-or-doctype"),e.unget(n),t.setState(Q))}return!0}function Y(e){var r=e.matchUntil("]]>");return e.shift(3),r&&t._emitToken({type:"Characters",data:r}),t.setState(n),!0}function Z(e){var i=e.char();return i===r.EOF?(t._parseError("eof-in-comment"),t._emitToken(t._currentToken),e.unget(i),t.setState(n)):i==="-"?t.setState(et):i===">"?(t._parseError("incorrect-comment"),t._emitToken(t._currentToken),t.setState(n)):i==="\0"?(t._parseError("invalid-codepoint"),t._currentToken.data+="\ufffd"):(t._currentToken.data+=i,t.setState(tt)),!0}function et(e){var i=e.char();return i===r.EOF?(t._parseError("eof-in-comment"),t._emitToken(t._currentToken),e.unget(i),t.setState(n)):i==="-"?t.setState(rt):i===">"?(t._parseError("incorrect-comment"),t._emitToken(t._currentToken),t.setState(n)):i==="\0"?(t._parseError("invalid-codepoint"),t._currentToken.data+="\ufffd"):(t._currentToken.data+="-"+i,t.setState(tt)),!0}function tt(e){var i=e.char();return i===r.EOF?(t._parseError("eof-in-comment"),t._emitToken(t._currentToken),e.unget(i),t.setState(n)):i==="-"?t.setState(nt):i==="\0"?(t._parseError("invalid-codepoint"),t._currentToken.data+="\ufffd"):(t._currentToken.data+=i,e.commit()),!0}function nt(e){var i=e.char();return i===r.EOF?(t._parseError("eof-in-comment-end-dash"),t._emitToken(t._currentToken),e.unget(i),t.setState(n)):i==="-"?t.setState(rt):i==="\0"?(t._parseError("invalid-codepoint"),t._currentToken.data+="-\ufffd",t.setState(tt)):(t._currentToken.data+="-"+i+e.matchUntil("\0|-"),e.char()),!0}function rt(e){var i=e.char();return i===r.EOF?(t._parseError("eof-in-comment-double-dash"),t._emitToken(t._currentToken),e.unget(i),t.setState(n)):i===">"?(t._emitToken(t._currentToken),t.setState(n)):i==="!"?(t._parseError("unexpected-bang-after-double-dash-in-comment"),t.setState(it)):i==="-"?(t._parseError("unexpected-dash-after-double-dash-in-comment"),t._currentToken.data+=i):i==="\0"?(t._parseError("invalid-codepoint"),t._currentToken.data+="--\ufffd",t.setState(tt)):(t._parseError("unexpected-char-in-comment"),t._currentToken.data+="--"+i,t.setState(tt)),!0}function it(e){var i=e.char();return i===r.EOF?(t._parseError("eof-in-comment-end-bang-state"),t._emitToken(t._currentToken),e.unget(i),t.setState(n)):i===">"?(t._emitToken(t._currentToken),t.setState(n)):i==="-"?(t._currentToken.data+="--!",t.setState(nt)):(t._currentToken.data+="--!"+i,t.setState(tt)),!0}function st(e){var i=e.char();return i===r.EOF?(t._parseError("expected-doctype-name-but-got-eof"),t._currentToken.forceQuirks=!0,e.unget(i),t.setState(n),t._emitCurrentToken()):s(i)?t.setState(ot):(t._parseError("need-space-after-doctype"),e.unget(i),t.setState(ot)),!0}function ot(e){var i=e.char();return i===r.EOF?(t._parseError("expected-doctype-name-but-got-eof"),t._currentToken.forceQuirks=!0,e.unget(i),t.setState(n),t._emitCurrentToken()):s(i)||(i===">"?(t._parseError("expected-doctype-name-but-got-right-bracket"),t._currentToken.forceQuirks=!0,t.setState(n),t._emitCurrentToken()):(o(i)&&(i=i.toLowerCase()),t._currentToken.name=i,t.setState(ut))),!0}function ut(e){var i=e.char();return i===r.EOF?(t._currentToken.forceQuirks=!0,e.unget(i),t._parseError("eof-in-doctype-name"),t.setState(n),t._emitCurrentToken()):s(i)?t.setState(at):i===">"?(t.setState(n),t._emitCurrentToken()):(o(i)&&(i=i.toLowerCase()),t._currentToken.name+=i,e.commit()),!0}function at(e){var i=e.char();if(i===r.EOF)t._currentToken.forceQuirks=!0,e.unget(i),t._parseError("eof-in-doctype"),t.setState(n),t._emitCurrentToken();else if(!s(i))if(i===">")t.setState(n),t._emitCurrentToken();else{if(["p","P"].indexOf(i)>-1){var o=[["u","U"],["b","B"],["l","L"],["i","I"],["c","C"]],u=o.every(function(t){return i=e.char(),t.indexOf(i)>-1});if(u)return t.setState(ft),!0}else if(["s","S"].indexOf(i)>-1){var o=[["y","Y"],["s","S"],["t","T"],["e","E"],["m","M"]],u=o.every(function(t){return i=e.char(),t.indexOf(i)>-1});if(u)return t.setState(vt),!0}e.unget(i),t._currentToken.forceQuirks=!0,i===r.EOF?(t._parseError("eof-in-doctype"),e.unget(i),t.setState(n),t._emitCurrentToken()):(t._parseError("expected-space-or-right-bracket-in-doctype",{data:i}),t.setState(wt))}return!0}function ft(e){var i=e.char();return i===r.EOF?(t._parseError("eof-in-doctype"),t._currentToken.forceQuirks=!0,e.unget(i),t.setState(n),t._emitCurrentToken()):s(i)?t.setState(lt):i==="'"||i==='"'?(t._parseError("unexpected-char-in-doctype"),e.unget(i),t.setState(lt)):(e.unget(i),t.setState(lt)),!0}function lt(e){var i=e.char();return i===r.EOF?(t._parseError("eof-in-doctype"),t._currentToken.forceQuirks=!0,e.unget(i),t.setState(n),t._emitCurrentToken()):s(i)||(i==='"'?(t._currentToken.publicId="",t.setState(ct)):i==="'"?(t._currentToken.publicId="",t.setState(ht)):i===">"?(t._parseError("unexpected-end-of-doctype"),t._currentToken.forceQuirks=!0,t.setState(n),t._emitCurrentToken()):(t._parseError("unexpected-char-in-doctype"),t._currentToken.forceQuirks=!0,t.setState(wt))),!0}function ct(e){var i=e.char();return i===r.EOF?(t._parseError("eof-in-doctype"),t._currentToken.forceQuirks=!0,e.unget(i),t.setState(n),t._emitCurrentToken()):i==='"'?t.setState(pt):i===">"?(t._parseError("unexpected-end-of-doctype"),t._currentToken.forceQuirks=!0,t.setState(n),t._emitCurrentToken()):t._currentToken.publicId+=i,!0}function ht(e){var i=e.char();return i===r.EOF?(t._parseError("eof-in-doctype"),t._currentToken.forceQuirks=!0,e.unget(i),t.setState(n),t._emitCurrentToken()):i==="'"?t.setState(pt):i===">"?(t._parseError("unexpected-end-of-doctype"),t._currentToken.forceQuirks=!0,t.setState(n),t._emitCurrentToken()):t._currentToken.publicId+=i,!0}function pt(e){var i=e.char();return i===r.EOF?(t._parseError("eof-in-doctype"),t._currentToken.forceQuirks=!0,t._emitCurrentToken(),e.unget(i),t.setState(n)):s(i)?t.setState(dt):i===">"?(t.setState(n),t._emitCurrentToken()):i==='"'?(t._parseError("unexpected-char-in-doctype"),t._currentToken.systemId="",t.setState(gt)):i==="'"?(t._parseError("unexpected-char-in-doctype"),t._currentToken.systemId="",t.setState(yt)):(t._parseError("unexpected-char-in-doctype"),t._currentToken.forceQuirks=!0,t.setState(wt)),!0}function dt(e){var i=e.char();return i===r.EOF?(t._parseError("eof-in-doctype"),t._currentToken.forceQuirks=!0,t._emitCurrentToken(),e.unget(i),t.setState(n)):s(i)||(i===">"?(t._emitCurrentToken(),t.setState(n)):i==='"'?(t._currentToken.systemId="",t.setState(gt)):i==="'"?(t._currentToken.systemId="",t.setState(yt)):(t._parseError("unexpected-char-in-doctype"),t._currentToken.forceQuirks=!0,t.setState(wt))),!0}function vt(e){var i=e.char();return i===r.EOF?(t._parseError("eof-in-doctype"),t._currentToken.forceQuirks=!0,t._emitCurrentToken(),e.unget(i),t.setState(n)):s(i)?t.setState(mt):i==="'"||i==='"'?(t._parseError("unexpected-char-in-doctype"),e.unget(i),t.setState(mt)):(e.unget(i),t.setState(mt)),!0}function mt(e){var i=e.char();return i===r.EOF?(t._parseError("eof-in-doctype"),t._currentToken.forceQuirks=!0,t._emitCurrentToken(),e.unget(i),t.setState(n)):s(i)||(i==='"'?(t._currentToken.systemId="",t.setState(gt)):i==="'"?(t._currentToken.systemId="",t.setState(yt)):i===">"?(t._parseError("unexpected-end-of-doctype"),t._currentToken.forceQuirks=!0,t._emitCurrentToken(),t.setState(n)):(t._parseError("unexpected-char-in-doctype"),t._currentToken.forceQuirks=!0,t.setState(wt))),!0}function gt(e){var i=e.char();return i===r.EOF?(t._parseError("eof-in-doctype"),t._currentToken.forceQuirks=!0,t._emitCurrentToken(),e.unget(i),t.setState(n)):i==='"'?t.setState(bt):i===">"?(t._parseError("unexpected-end-of-doctype"),t._currentToken.forceQuirks=!0,t._emitCurrentToken(),t.setState(n)):t._currentToken.systemId+=i,!0}function yt(e){var i=e.char();return i===r.EOF?(t._parseError("eof-in-doctype"),t._currentToken.forceQuirks=!0,t._emitCurrentToken(),e.unget(i),t.setState(n)):i==="'"?t.setState(bt):i===">"?(t._parseError("unexpected-end-of-doctype"),t._currentToken.forceQuirks=!0,t._emitCurrentToken(),t.setState(n)):t._currentToken.systemId+=i,!0}function bt(e){var i=e.char();return i===r.EOF?(t._parseError("eof-in-doctype"),t._currentToken.forceQuirks=!0,t._emitCurrentToken(),e.unget(i),t.setState(n)):s(i)||(i===">"?(t._emitCurrentToken(),t.setState(n)):(t._parseError("unexpected-char-in-doctype"),t.setState(wt))),!0}function wt(e){var i=e.char();return i===r.EOF?(e.unget(i),t._emitCurrentToken(),t.setState(n)):i===">"&&(t._emitCurrentToken(),t.setState(n)),!0}u.DATA=n,u.RCDATA=f,u.RAWTEXT=c,u.SCRIPT_DATA=p,u.PLAINTEXT=h,this._state=u.DATA,this._inputStream.append(e),this._tokenHandler.startTokenization(this),this._inputStream.eof=!0;var t=this;while(this._state.call(this,this._inputStream));},Object.defineProperty(u.prototype,"lineNumber",{get:function(){return this._inputStream.location().line}}),Object.defineProperty(u.prototype,"columnNumber",{get:function(){return this._inputStream.location().column}}),n.Tokenizer=u},{"./EntityParser":2,"./InputStream":3}],6:[function(e,t,n){function c(e){return e===" "||e==="\n"||e===" "||e==="\r"||e==="\f"}function h(e){return c(e)||e==="\ufffd"}function p(e){for(var t=0;t2?e.parseError("expected-closing-tag-but-got-eof"):e.openElements.length==2&&e.openElements.item(1).localName!="body"?e.parseError("expected-closing-tag-but-got-eof"):e.context&&e.openElements.length>1},processComment:function(t){e.insertComment(t,e.currentStackItem().node)},processDoctype:function(t,n,r,i){e.parseError("unexpected-doctype")},processStartTag:function(e,t,n){if(this[this.start_tag_handlers[e]])this[this.start_tag_handlers[e]](e,t,n);else{if(!this[this.start_tag_handlers["-default"]])throw new Error("No handler found for "+e);this[this.start_tag_handlers["-default"]](e,t,n)}},processEndTag:function(e){if(this[this.end_tag_handlers[e]])this[this.end_tag_handlers[e]](e);else{if(!this[this.end_tag_handlers["-default"]])throw new Error("No handler found for "+e);this[this.end_tag_handlers["-default"]](e)}},startTagHtml:function(e,n){t.inBody.startTagHtml(e,n)}},t.initial=Object.create(t.base),t.initial.processEOF=function(){e.parseError("expected-doctype-but-got-eof"),this.anythingElse(),e.insertionMode.processEOF()},t.initial.processComment=function(t){e.insertComment(t,e.document)},t.initial.processDoctype=function(t,n,r,i){function s(e){return n.toLowerCase().indexOf(e)===0}e.insertDoctype(t||"",n||"",r||""),i||t!="html"||n!=null&&(["+//silmaril//dtd html pro v0r11 19970101//","-//advasoft ltd//dtd html 3.0 aswedit + extensions//","-//as//dtd html 3.0 aswedit + extensions//","-//ietf//dtd html 2.0 level 1//","-//ietf//dtd html 2.0 level 2//","-//ietf//dtd html 2.0 strict level 1//","-//ietf//dtd html 2.0 strict level 2//","-//ietf//dtd html 2.0 strict//","-//ietf//dtd html 2.0//","-//ietf//dtd html 2.1e//","-//ietf//dtd html 3.0//","-//ietf//dtd html 3.0//","-//ietf//dtd html 3.2 final//","-//ietf//dtd html 3.2//","-//ietf//dtd html 3//","-//ietf//dtd html level 0//","-//ietf//dtd html level 0//","-//ietf//dtd html level 1//","-//ietf//dtd html level 1//","-//ietf//dtd html level 2//","-//ietf//dtd html level 2//","-//ietf//dtd html level 3//","-//ietf//dtd html level 3//","-//ietf//dtd html strict level 0//","-//ietf//dtd html strict level 0//","-//ietf//dtd html strict level 1//","-//ietf//dtd html strict level 1//","-//ietf//dtd html strict level 2//","-//ietf//dtd html strict level 2//","-//ietf//dtd html strict level 3//","-//ietf//dtd html strict level 3//","-//ietf//dtd html strict//","-//ietf//dtd html strict//","-//ietf//dtd html strict//","-//ietf//dtd html//","-//ietf//dtd html//","-//ietf//dtd html//","-//metrius//dtd metrius presentational//","-//microsoft//dtd internet explorer 2.0 html strict//","-//microsoft//dtd internet explorer 2.0 html//","-//microsoft//dtd internet explorer 2.0 tables//","-//microsoft//dtd internet explorer 3.0 html strict//","-//microsoft//dtd internet explorer 3.0 html//","-//microsoft//dtd internet explorer 3.0 tables//","-//netscape comm. corp.//dtd html//","-//netscape comm. corp.//dtd strict html//","-//o'reilly and associates//dtd html 2.0//","-//o'reilly and associates//dtd html extended 1.0//","-//spyglass//dtd html 2.0 extended//","-//sq//dtd html 2.0 hotmetal + extensions//","-//sun microsystems corp.//dtd hotjava html//","-//sun microsystems corp.//dtd hotjava strict html//","-//w3c//dtd html 3 1995-03-24//","-//w3c//dtd html 3.2 draft//","-//w3c//dtd html 3.2 final//","-//w3c//dtd html 3.2//","-//w3c//dtd html 3.2s draft//","-//w3c//dtd html 4.0 frameset//","-//w3c//dtd html 4.0 transitional//","-//w3c//dtd html experimental 19960712//","-//w3c//dtd html experimental 970421//","-//w3c//dtd w3 html//","-//w3o//dtd w3 html 3.0//","-//webtechs//dtd mozilla html 2.0//","-//webtechs//dtd mozilla html//","html"].some(s)||["-//w3o//dtd w3 html strict 3.0//en//","-/w3c/dtd html 4.0 transitional/en","html"].indexOf(n.toLowerCase())>-1||r==null&&["-//w3c//dtd html 4.01 transitional//","-//w3c//dtd html 4.01 frameset//"].some(s))||r!=null&&r.toLowerCase()=="http://www.ibm.com/data/dtd/v11/ibmxhtml1-transitional.dtd"?(e.compatMode="quirks",e.parseError("quirky-doctype")):n!=null&&(["-//w3c//dtd xhtml 1.0 transitional//","-//w3c//dtd xhtml 1.0 frameset//"].some(s)||r!=null&&["-//w3c//dtd html 4.01 transitional//","-//w3c//dtd html 4.01 frameset//"].indexOf(n.toLowerCase())>-1)?(e.compatMode="limited quirks",e.parseError("almost-standards-doctype")):n=="-//W3C//DTD HTML 4.0//EN"&&(r==null||r=="http://www.w3.org/TR/REC-html40/strict.dtd")||n=="-//W3C//DTD HTML 4.01//EN"&&(r==null||r=="http://www.w3.org/TR/html4/strict.dtd")||n=="-//W3C//DTD XHTML 1.0 Strict//EN"&&r=="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"||n=="-//W3C//DTD XHTML 1.1//EN"&&r=="http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"||(r!=null&&r!="about:legacy-compat"||n!=null)&&e.parseError("unknown-doctype"),e.setInsertionMode("beforeHTML")},t.initial.processCharacters=function(t){t.skipLeadingWhitespace();if(!t.length)return;e.parseError("expected-doctype-but-got-chars"),this.anythingElse(),e.insertionMode.processCharacters(t)},t.initial.processStartTag=function(t,n,r){e.parseError("expected-doctype-but-got-start-tag",{name:t}),this.anythingElse(),e.insertionMode.processStartTag(t,n,r)},t.initial.processEndTag=function(t){e.parseError("expected-doctype-but-got-end-tag",{name:t}),this.anythingElse(),e.insertionMode.processEndTag(t)},t.initial.anythingElse=function(){e.compatMode="quirks",e.setInsertionMode("beforeHTML")},t.beforeHTML=Object.create(t.base),t.beforeHTML.start_tag_handlers={html:"startTagHtml","-default":"startTagOther"},t.beforeHTML.processEOF=function(){this.anythingElse(),e.insertionMode.processEOF()},t.beforeHTML.processComment=function(t){e.insertComment(t,e.document)},t.beforeHTML.processCharacters=function(t){t.skipLeadingWhitespace();if(!t.length)return;this.anythingElse(),e.insertionMode.processCharacters(t)},t.beforeHTML.startTagHtml=function(t,n,r){e.insertHtmlElement(n),e.setInsertionMode("beforeHead")},t.beforeHTML.startTagOther=function(t,n,r){this.anythingElse(),e.insertionMode.processStartTag(t,n,r)},t.beforeHTML.processEndTag=function(t){this.anythingElse(),e.insertionMode.processEndTag(t)},t.beforeHTML.anythingElse=function(){e.insertHtmlElement(),e.setInsertionMode("beforeHead")},t.afterAfterBody=Object.create(t.base),t.afterAfterBody.start_tag_handlers={html:"startTagHtml","-default":"startTagOther"},t.afterAfterBody.processComment=function(t){e.insertComment(t,e.document)},t.afterAfterBody.processDoctype=function(e){t.inBody.processDoctype(e)},t.afterAfterBody.startTagHtml=function(e,n){t.inBody.startTagHtml(e,n)},t.afterAfterBody.startTagOther=function(t,n,r){e.parseError("unexpected-start-tag",{name:t}),e.setInsertionMode("inBody"),e.insertionMode.processStartTag(t,n,r)},t.afterAfterBody.endTagOther=function(t){e.parseError("unexpected-end-tag",{name:t}),e.setInsertionMode("inBody"),e.insertionMode.processEndTag(t)},t.afterAfterBody.processCharacters=function(n){if(!p(n.characters))return e.parseError("unexpected-char-after-body"),e.setInsertionMode("inBody"),e.insertionMode.processCharacters(n);t.inBody.processCharacters(n)},t.afterBody=Object.create(t.base),t.afterBody.end_tag_handlers={html:"endTagHtml","-default":"endTagOther"},t.afterBody.processComment=function(t){e.insertComment(t,e.openElements.rootNode)},t.afterBody.processCharacters=function(n){if(!p(n.characters))return e.parseError("unexpected-char-after-body"),e.setInsertionMode("inBody"),e.insertionMode.processCharacters(n);t.inBody.processCharacters(n)},t.afterBody.processStartTag=function(t,n,r){e.parseError("unexpected-start-tag-after-body",{name:t}),e.setInsertionMode("inBody"),e.insertionMode.processStartTag(t,n,r)},t.afterBody.endTagHtml=function(t){e.context?e.parseError("end-html-in-innerhtml"):e.setInsertionMode("afterAfterBody")},t.afterBody.endTagOther=function(t){e.parseError("unexpected-end-tag-after-body",{name:t}),e.setInsertionMode("inBody"),e.insertionMode.processEndTag(t)},t.afterFrameset=Object.create(t.base),t.afterFrameset.start_tag_handlers={html:"startTagHtml",noframes:"startTagNoframes","-default":"startTagOther"},t.afterFrameset.end_tag_handlers={html:"endTagHtml","-default":"endTagOther"},t.afterFrameset.processCharacters=function(t){var n=t.takeRemaining(),r="";for(var i=0;i1)e.openElements.pop();e.insertElement(t,n),e.setInsertionMode("inFrameset")}},t.inBody.startTagCloseP=function(t,n){e.openElements.inButtonScope("p")&&this.endTagP("p"),e.insertElement(t,n)},t.inBody.startTagPreListing=function(t,n){e.openElements.inButtonScope("p")&&this.endTagP("p"),e.insertElement(t,n),e.framesetOk=!1,e.shouldSkipLeadingNewline=!0},t.inBody.startTagForm=function(t,n){e.form?e.parseError("unexpected-start-tag",{name:t}):(e.openElements.inButtonScope("p")&&this.endTagP("p"),e.insertElement(t,n),e.form=e.currentStackItem())},t.inBody.startTagRpRt=function(t,n){e.openElements.inScope("ruby")&&(e.generateImpliedEndTags(),e.currentStackItem().localName!="ruby"&&e.parseError("unexpected-start-tag",{name:t})),e.insertElement(t,n)},t.inBody.startTagListItem=function(t,n){var r={li:["li"],dd:["dd","dt"],dt:["dd","dt"]},i=r[t],s=e.openElements;for(var o=s.length-1;o>=0;o--){var u=s.item(o);if(i.indexOf(u.localName)!=-1){e.insertionMode.processEndTag(u.localName);break}if(u.isSpecial()&&u.localName!=="p"&&u.localName!=="address"&&u.localName!=="div")break}e.openElements.inButtonScope("p")&&this.endTagP("p"),e.insertElement(t,n),e.framesetOk=!1},t.inBody.startTagPlaintext=function(t,n){e.openElements.inButtonScope("p")&&this.endTagP("p"),e.insertElement(t,n),e.tokenizer.setState(u.PLAINTEXT)},t.inBody.startTagHeading=function(t,n){e.openElements.inButtonScope("p")&&this.endTagP("p"),e.currentStackItem().isNumberedHeader()&&(e.parseError("unexpected-start-tag",{name:t}),e.popElement()),e.insertElement(t,n)},t.inBody.startTagA=function(t,n){var r=e.elementInActiveFormattingElements("a");r&&(e.parseError("unexpected-start-tag-implies-end-tag",{startName:"a",endName:"a"}),e.adoptionAgencyEndTag("a"),e.openElements.contains(r)&&e.openElements.remove(r),e.removeElementFromActiveFormattingElements(r)),e.reconstructActiveFormattingElements(),e.insertFormattingElement(t,n)},t.inBody.startTagFormatting=function(t,n){e.reconstructActiveFormattingElements(),e.insertFormattingElement(t,n)},t.inBody.startTagNobr=function(t,n){e.reconstructActiveFormattingElements(),e.openElements.inScope("nobr")&&(e.parseError("unexpected-start-tag-implies-end-tag",{startName:"nobr",endName:"nobr"}),this.processEndTag("nobr"),e.reconstructActiveFormattingElements()),e.insertFormattingElement(t,n)},t.inBody.startTagButton=function(t,n){e.openElements.inScope("button")?(e.parseError("unexpected-start-tag-implies-end-tag",{startName:"button",endName:"button"}),this.processEndTag("button"),e.insertionMode.processStartTag(t,n)):(e.framesetOk=!1,e.reconstructActiveFormattingElements(),e.insertElement(t,n))},t.inBody.startTagAppletMarqueeObject=function(t,n){e.reconstructActiveFormattingElements(),e.insertElement(t,n),e.activeFormattingElements.push(l),e.framesetOk=!1},t.inBody.endTagAppletMarqueeObject=function(t){e.openElements.inScope(t)?(e.generateImpliedEndTags(),e.currentStackItem().localName!=t&&e.parseError("end-tag-too-early",{name:t}),e.openElements.popUntilPopped(t),e.clearActiveFormattingElements()):e.parseError("unexpected-end-tag",{name:t})},t.inBody.startTagXmp=function(t,n){e.openElements.inButtonScope("p")&&this.processEndTag("p"),e.reconstructActiveFormattingElements(),e.processGenericRawTextStartTag(t,n),e.framesetOk=!1},t.inBody.startTagTable=function(t,n){e.compatMode!=="quirks"&&e.openElements.inButtonScope("p")&&this.processEndTag("p"),e.insertElement(t,n),e.setInsertionMode("inTable"),e.framesetOk=!1},t.inBody.startTagVoidFormatting=function(t,n){e.reconstructActiveFormattingElements(),e.insertSelfClosingElement(t,n),e.framesetOk=!1},t.inBody.startTagParamSourceTrack=function(t,n){e.insertSelfClosingElement(t,n)},t.inBody.startTagHr=function(t,n){e.openElements.inButtonScope("p")&&this.endTagP("p"),e.insertSelfClosingElement(t,n),e.framesetOk=!1},t.inBody.startTagImage=function(t,n){e.parseError("unexpected-start-tag-treated-as",{originalName:"image",newName:"img"}),this.processStartTag("img",n)},t.inBody.startTagInput=function(t,n){var r=e.framesetOk;this.startTagVoidFormatting(t,n);for(var i in n)if(n[i].nodeName=="type"){n[i].nodeValue.toLowerCase()=="hidden"&&(e.framesetOk=r);break}},t.inBody.startTagIsindex=function(t,n){e.parseError("deprecated-tag",{name:"isindex"}),e.selfClosingFlagAcknowledged=!0;if(e.form)return;var r=[],i=[],s="This is a searchable index. Enter search keywords: ";for(var o in n)switch(n[o].nodeName){case"action":r.push({nodeName:"action",nodeValue:n[o].nodeValue});break;case"prompt":s=n[o].nodeValue;break;case"name":break;default:i.push({nodeName:n[o].nodeName,nodeValue:n[o].nodeValue})}i.push({nodeName:"name",nodeValue:"isindex"}),this.processStartTag("form",r),this.processStartTag("hr"),this.processStartTag("label"),this.processCharacters(new m(s)),this.processStartTag("input",i),this.processEndTag("label"),this.processStartTag("hr"),this.processEndTag("form")},t.inBody.startTagTextarea=function(t,n){e.insertElement(t,n),e.tokenizer.setState(u.RCDATA),e.originalInsertionMode=e.insertionModeName,e.shouldSkipLeadingNewline=!0,e.framesetOk=!1,e.setInsertionMode("text")},t.inBody.startTagIFrame=function(t,n){e.framesetOk=!1,this.startTagRawText(t,n)},t.inBody.startTagRawText=function(t,n){e.processGenericRawTextStartTag(t,n)},t.inBody.startTagSelect=function(t,n){e.reconstructActiveFormattingElements(),e.insertElement(t,n),e.framesetOk=!1;var r=e.insertionModeName;r=="inTable"||r=="inCaption"||r=="inColumnGroup"||r=="inTableBody"||r=="inRow"||r=="inCell"?e.setInsertionMode("inSelectInTable"):e.setInsertionMode("inSelect")},t.inBody.startTagMisplaced=function(t,n){e.parseError("unexpected-start-tag-ignored",{name:t})},t.inBody.endTagMisplaced=function(t){e.parseError("unexpected-end-tag",{name:t})},t.inBody.endTagBr=function(t){e.parseError("unexpected-end-tag-treated-as",{originalName:"br",newName:"br element"}),e.reconstructActiveFormattingElements(),e.insertElement(t,[]),e.popElement()},t.inBody.startTagOptionOptgroup=function(t,n){e.currentStackItem().localName=="option"&&e.popElement(),e.reconstructActiveFormattingElements(),e.insertElement(t,n)},t.inBody.startTagOther=function(t,n){e.reconstructActiveFormattingElements(),e.insertElement(t,n)},t.inBody.endTagOther=function(t){var n;for(var r=e.openElements.length-1;r>0;r--){n=e.openElements.item(r);if(n.localName==t){e.generateImpliedEndTags(t),e.currentStackItem().localName!=t&&e.parseError("unexpected-end-tag",{name:t}),e.openElements.remove_openElements_until(function(e){return e===n});break}if(n.isSpecial()){e.parseError("unexpected-end-tag",{name:t});break}}},t.inBody.startTagMath=function(t,n,r){e.reconstructActiveFormattingElements(),n=e.adjustMathMLAttributes(n),n=e.adjustForeignAttributes(n),e.insertForeignElement(t,n,"http://www.w3.org/1998/Math/MathML",r)},t.inBody.startTagSVG=function(t,n,r){e.reconstructActiveFormattingElements(),n=e.adjustSVGAttributes(n),n=e.adjustForeignAttributes(n),e.insertForeignElement(t,n,"http://www.w3.org/2000/svg",r)},t.inBody.endTagP=function(t){e.openElements.inButtonScope("p")?(e.generateImpliedEndTags("p"),e.currentStackItem().localName!="p"&&e.parseError("unexpected-implied-end-tag",{name:"p"}),e.openElements.popUntilPopped(t)):(e.parseError("unexpected-end-tag",{name:"p"}),this.startTagCloseP("p",[]),this.endTagP("p"))},t.inBody.endTagBody=function(t){if(!e.openElements.inScope("body")){e.parseError("unexpected-end-tag",{name:t});return}e.currentStackItem().localName!="body"&&e.parseError("expected-one-end-tag-but-got-another",{expectedName:e.currentStackItem().localName,gotName:t}),e.setInsertionMode("afterBody")},t.inBody.endTagHtml=function(t){if(!e.openElements.inScope("body")){e.parseError("unexpected-end-tag",{name:t});return}e.currentStackItem().localName!="body"&&e.parseError("expected-one-end-tag-but-got-another",{expectedName:e.currentStackItem().localName,gotName:t}),e.setInsertionMode("afterBody"),e.insertionMode.processEndTag(t)},t.inBody.endTagBlock=function(t){e.openElements.inScope(t)?(e.generateImpliedEndTags(),e.currentStackItem().localName!=t&&e.parseError("end-tag-too-early",{name:t}),e.openElements.popUntilPopped(t)):e.parseError("unexpected-end-tag",{name:t})},t.inBody.endTagForm=function(t){var n=e.form;e.form=null,!n||!e.openElements.inScope(t)?e.parseError("unexpected-end-tag",{name:t}):(e.generateImpliedEndTags(),e.currentStackItem()!=n&&e.parseError("end-tag-too-early-ignored",{name:"form"}),e.openElements.remove(n))},t.inBody.endTagListItem=function(t){e.openElements.inListItemScope(t)?(e.generateImpliedEndTags(t),e.currentStackItem().localName!=t&&e.parseError("end-tag-too-early",{name:t}),e.openElements.popUntilPopped(t)):e.parseError("unexpected-end-tag",{name:t})},t.inBody.endTagHeading=function(t){if(!e.openElements.hasNumberedHeaderElementInScope()){e.parseError("unexpected-end-tag",{name:t});return}e.generateImpliedEndTags(),e.currentStackItem().localName!=t&&e.parseError("end-tag-too-early",{name:t}),e.openElements.remove_openElements_until(function(e){return e.isNumberedHeader()})},t.inBody.endTagFormatting=function(t,n){e.adoptionAgencyEndTag(t)||this.endTagOther(t,n)},t.inCaption=Object.create(t.base),t.inCaption.start_tag_handlers={html:"startTagHtml",caption:"startTagTableElement",col:"startTagTableElement",colgroup:"startTagTableElement",tbody:"startTagTableElement",td:"startTagTableElement",tfoot:"startTagTableElement",thead:"startTagTableElement",tr:"startTagTableElement","-default":"startTagOther"},t.inCaption.end_tag_handlers={caption:"endTagCaption",table:"endTagTable",body:"endTagIgnore",col:"endTagIgnore",colgroup:"endTagIgnore",html:"endTagIgnore",tbody:"endTagIgnore",td:"endTagIgnore",tfood:"endTagIgnore",thead:"endTagIgnore",tr:"endTagIgnore","-default":"endTagOther"},t.inCaption.processCharacters=function(e){t.inBody.processCharacters(e)},t.inCaption.startTagTableElement=function(t,n){e.parseError("unexpected-end-tag",{name:t});var r=!e.openElements.inTableScope("caption");e.insertionMode.processEndTag("caption"),r||e.insertionMode.processStartTag(t,n)},t.inCaption.startTagOther=function(e,n,r){t.inBody.processStartTag(e,n,r)},t.inCaption.endTagCaption=function(t){e.openElements.inTableScope("caption")?(e.generateImpliedEndTags(),e.currentStackItem().localName!="caption"&&e.parseError("expected-one-end-tag-but-got-another",{gotName:"caption",expectedName:e.currentStackItem().localName}),e.openElements.popUntilPopped("caption"),e.clearActiveFormattingElements(),e.setInsertionMode("inTable")):(r.ok(e.context),e.parseError("unexpected-end-tag",{name:t}))},t.inCaption.endTagTable=function(t){e.parseError("unexpected-end-table-in-caption");var n=!e.openElements.inTableScope("caption");e.insertionMode.processEndTag("caption"),n||e.insertionMode.processEndTag(t)},t.inCaption.endTagIgnore=function(t){e.parseError("unexpected-end-tag",{name:t})},t.inCaption.endTagOther=function(e){t.inBody.processEndTag(e)},t.inCell=Object.create(t.base),t.inCell.start_tag_handlers={html:"startTagHtml",caption:"startTagTableOther",col:"startTagTableOther",colgroup:"startTagTableOther",tbody:"startTagTableOther",td:"startTagTableOther",tfoot:"startTagTableOther",th:"startTagTableOther",thead:"startTagTableOther",tr:"startTagTableOther","-default":"startTagOther"},t.inCell.end_tag_handlers={td:"endTagTableCell",th:"endTagTableCell",body:"endTagIgnore",caption:"endTagIgnore",col:"endTagIgnore",colgroup:"endTagIgnore",html:"endTagIgnore",table:"endTagImply",tbody:"endTagImply",tfoot:"endTagImply",thead:"endTagImply",tr:"endTagImply","-default":"endTagOther"},t.inCell.processCharacters=function(e){t.inBody.processCharacters(e)},t.inCell.startTagTableOther=function(t,n,r){e.openElements.inTableScope("td")||e.openElements.inTableScope("th")?(this.closeCell(),e.insertionMode.processStartTag(t,n,r)):e.parseError("unexpected-start-tag",{name:t})},t.inCell.startTagOther=function(e,n,r){t.inBody.processStartTag(e,n,r)},t.inCell.endTagTableCell=function(t){e.openElements.inTableScope(t)?(e.generateImpliedEndTags(t),e.currentStackItem().localName!=t.toLowerCase()?(e.parseError("unexpected-cell-end-tag",{name:t}),e.openElements.popUntilPopped(t)):e.popElement(),e.clearActiveFormattingElements(),e.setInsertionMode("inRow")):e.parseError("unexpected-end-tag",{name:t})},t.inCell.endTagIgnore=function(t){e.parseError("unexpected-end-tag",{name:t})},t.inCell.endTagImply=function(t){e.openElements.inTableScope(t)?(this.closeCell(),e.insertionMode.processEndTag(t)):e.parseError("unexpected-end-tag",{name:t})},t.inCell.endTagOther=function(e){t.inBody.processEndTag(e)},t.inCell.closeCell=function(){e.openElements.inTableScope("td")?this.endTagTableCell("td"):e.openElements.inTableScope("th")&&this.endTagTableCell("th")},t.inColumnGroup=Object.create(t.base),t.inColumnGroup.start_tag_handlers={html:"startTagHtml",col:"startTagCol","-default":"startTagOther"},t.inColumnGroup.end_tag_handlers={colgroup:"endTagColgroup",col:"endTagCol","-default":"endTagOther"},t.inColumnGroup.ignoreEndTagColgroup=function(){return e.currentStackItem().localName=="html"},t.inColumnGroup.processCharacters=function(t){var n=t.takeLeadingWhitespace();n&&e.insertText(n);if(!t.length)return;var r=this.ignoreEndTagColgroup();this.endTagColgroup("colgroup"),r||e.insertionMode.processCharacters(t)},t.inColumnGroup.startTagCol=function(t,n){e.insertSelfClosingElement(t,n)},t.inColumnGroup.startTagOther=function(t,n,r){var i=this.ignoreEndTagColgroup();this.endTagColgroup("colgroup"),i||e.insertionMode.processStartTag(t,n,r)},t.inColumnGroup.endTagColgroup=function(t){this.ignoreEndTagColgroup()?(r.ok(e.context),e.parseError("unexpected-end-tag",{name:t})):(e.popElement(),e.setInsertionMode("inTable"))},t.inColumnGroup.endTagCol=function(t){e.parseError("no-end-tag",{name:"col"})},t.inColumnGroup.endTagOther=function(t){var n=this.ignoreEndTagColgroup();this.endTagColgroup("colgroup"),n||e.insertionMode.processEndTag(t)},t.inForeignContent=Object.create(t.base),t.inForeignContent.processStartTag=function(t,n,r){if(["b","big","blockquote","body","br","center","code","dd","div","dl","dt","em","embed","h1","h2","h3","h4","h5","h6","head","hr","i","img","li","listing","menu","meta","nobr","ol","p","pre","ruby","s","small","span","strong","strike","sub","sup","table","tt","u","ul","var"].indexOf(t)!=-1||t=="font"&&n.some(function(e){return["color","face","size"].indexOf(e.nodeName)>=0})){e.parseError("unexpected-html-element-in-foreign-content",{name:t});while(e.currentStackItem().isForeign()&&!e.currentStackItem().isHtmlIntegrationPoint()&&!e.currentStackItem().isMathMLTextIntegrationPoint())e.openElements.pop();e.insertionMode.processStartTag(t,n,r);return}e.currentStackItem().namespaceURI=="http://www.w3.org/1998/Math/MathML"&&(n=e.adjustMathMLAttributes(n)),e.currentStackItem().namespaceURI=="http://www.w3.org/2000/svg"&&(t=e.adjustSVGTagNameCase(t),n=e.adjustSVGAttributes(n)),n=e.adjustForeignAttributes(n),e.insertForeignElement(t,n,e.currentStackItem().namespaceURI,r)},t.inForeignContent.processEndTag=function(t){var n=e.currentStackItem(),r=e.openElements.length-1;n.localName.toLowerCase()!=t&&e.parseError("unexpected-end-tag",{name:t});for(;;){if(r===0)break;if(n.localName.toLowerCase()==t){while(e.openElements.pop()!=n);break}r-=1,n=e.openElements.item(r);if(n.isForeign())continue;e.insertionMode.processEndTag(t);break}},t.inForeignContent.processCharacters=function(t){var n=t.takeRemaining();n=n.replace(/\u0000/g,function(t,n){return e.parseError("invalid-codepoint"),"\ufffd"}),e.framesetOk&&!d(n)&&(e.framesetOk=!1),e.insertText(n)},t.inHeadNoscript=Object.create(t.base),t.inHeadNoscript.start_tag_handlers={html:"startTagHtml",basefont:"startTagBasefontBgsoundLinkMetaNoframesStyle",bgsound:"startTagBasefontBgsoundLinkMetaNoframesStyle",link:"startTagBasefontBgsoundLinkMetaNoframesStyle",meta:"startTagBasefontBgsoundLinkMetaNoframesStyle",noframes:"startTagBasefontBgsoundLinkMetaNoframesStyle",style:"startTagBasefontBgsoundLinkMetaNoframesStyle",head:"startTagHeadNoscript",noscript:"startTagHeadNoscript","-default":"startTagOther"},t.inHeadNoscript.end_tag_handlers={noscript:"endTagNoscript",br:"endTagBr","-default":"endTagOther"},t.inHeadNoscript.processCharacters=function(t){var n=t.takeLeadingWhitespace();n&&e.insertText(n);if(!t.length)return;e.parseError("unexpected-char-in-frameset"),this.anythingElse(),e.insertionMode.processCharacters(t)},t.inHeadNoscript.processComment=function(e){t.inHead.processComment(e)},t.inHeadNoscript.startTagBasefontBgsoundLinkMetaNoframesStyle=function(e,n){t.inHead.processStartTag(e,n)},t.inHeadNoscript.startTagHeadNoscript=function(t,n){e.parseError("unexpected-start-tag-in-frameset",{name:t})},t.inHeadNoscript.startTagOther=function(t,n){e.parseError("unexpected-start-tag-in-frameset",{name:t}),this.anythingElse(),e.insertionMode.processStartTag(t,n)},t.inHeadNoscript.endTagBr=function(t,n){e.parseError("unexpected-end-tag-in-frameset",{name:t}),this.anythingElse(),e.insertionMode.processEndTag(t,n)},t.inHeadNoscript.endTagNoscript=function(t,n){e.popElement(),e.setInsertionMode("inHead")},t.inHeadNoscript.endTagOther=function(t,n){e.parseError("unexpected-end-tag-in-frameset",{name:t})},t.inHeadNoscript.anythingElse=function(){e.popElement(),e.setInsertionMode("inHead")},t.inFrameset=Object.create(t.base),t.inFrameset.start_tag_handlers={html:"startTagHtml",frameset:"startTagFrameset",frame:"startTagFrame",noframes:"startTagNoframes","-default":"startTagOther"},t.inFrameset.end_tag_handlers={frameset:"endTagFrameset",noframes:"endTagNoframes","-default":"endTagOther"},t.inFrameset.processCharacters=function(t){e.parseError("unexpected-char-in-frameset")},t.inFrameset.startTagFrameset=function(t,n){e.insertElement(t,n)},t.inFrameset.startTagFrame=function(t,n){e.insertSelfClosingElement(t,n)},t.inFrameset.startTagNoframes=function(e,n){t.inBody.processStartTag(e,n)},t.inFrameset.startTagOther=function(t,n){e.parseError("unexpected-start-tag-in-frameset",{name:t})},t.inFrameset.endTagFrameset=function(t,n){e.currentStackItem().localName=="html"?e.parseError("unexpected-frameset-in-frameset-innerhtml"):e.popElement(),!e.context&&e.currentStackItem().localName!="frameset"&&e.setInsertionMode("afterFrameset")},t.inFrameset.endTagNoframes=function(e){t.inBody.processEndTag(e)},t.inFrameset.endTagOther=function(t){e.parseError("unexpected-end-tag-in-frameset",{name:t})},t.inTable=Object.create(t.base),t.inTable.start_tag_handlers={html:"startTagHtml",caption:"startTagCaption",colgroup:"startTagColgroup",col:"startTagCol",table:"startTagTable",tbody:"startTagRowGroup",tfoot:"startTagRowGroup",thead:"startTagRowGroup",td:"startTagImplyTbody",th:"startTagImplyTbody",tr:"startTagImplyTbody",style:"startTagStyleScript",script:"startTagStyleScript",input:"startTagInput",form:"startTagForm","-default":"startTagOther"},t.inTable.end_tag_handlers={table:"endTagTable",body:"endTagIgnore",caption:"endTagIgnore",col:"endTagIgnore",colgroup:"endTagIgnore",html:"endTagIgnore",tbody:"endTagIgnore",td:"endTagIgnore",tfoot:"endTagIgnore",th:"endTagIgnore",thead:"endTagIgnore",tr:"endTagIgnore","-default":"endTagOther"},t.inTable.processCharacters=function(n){if(e.currentStackItem().isFosterParenting()){var r=e.insertionModeName;e.setInsertionMode("inTableText"),e.originalInsertionMode=r,e.insertionMode.processCharacters(n)}else e.redirectAttachToFosterParent=!0,t.inBody.processCharacters(n),e.redirectAttachToFosterParent=!1},t.inTable.startTagCaption=function(t,n){e.openElements.popUntilTableScopeMarker(),e.activeFormattingElements.push(l),e.insertElement(t,n),e.setInsertionMode("inCaption")},t.inTable.startTagColgroup=function(t,n){e.openElements.popUntilTableScopeMarker(),e.insertElement(t,n),e.setInsertionMode("inColumnGroup")},t.inTable.startTagCol=function(t,n){this.startTagColgroup("colgroup",[]),e.insertionMode.processStartTag(t,n)},t.inTable.startTagRowGroup=function(t,n){e.openElements.popUntilTableScopeMarker(),e.insertElement(t,n),e.setInsertionMode("inTableBody")},t.inTable.startTagImplyTbody=function(t,n){this.startTagRowGroup("tbody",[]),e.insertionMode.processStartTag(t,n)},t.inTable.startTagTable=function(t,n){e.parseError("unexpected-start-tag-implies-end-tag",{startName:"table",endName:"table"}),e.insertionMode.processEndTag("table"),e.context||e.insertionMode.processStartTag(t,n)},t.inTable.startTagStyleScript=function(e,n){t.inHead.processStartTag(e,n)},t.inTable.startTagInput=function(t,n){for(var r in n)if(n[r].nodeName.toLowerCase()=="type"){if(n[r].nodeValue.toLowerCase()=="hidden"){e.parseError("unexpected-hidden-input-in-table"),e.insertElement(t,n),e.openElements.pop();return}break}this.startTagOther(t,n)},t.inTable.startTagForm=function(t,n){e.parseError("unexpected-form-in-table"),e.form||(e.insertElement(t,n),e.form=e.currentStackItem(),e.openElements.pop())},t.inTable.startTagOther=function(n,r,i){e.parseError("unexpected-start-tag-implies-table-voodoo",{name:n}),e.redirectAttachToFosterParent=!0,t.inBody.processStartTag(n,r,i),e.redirectAttachToFosterParent=!1},t.inTable.endTagTable=function(t){e.openElements.inTableScope(t)?(e.generateImpliedEndTags(),e.currentStackItem().localName!=t&&e.parseError("end-tag-too-early-named",{gotName:"table",expectedName:e.currentStackItem().localName}),e.openElements.popUntilPopped("table"),e.resetInsertionMode()):(r.ok(e.context),e.parseError("unexpected-end-tag",{name:t}))},t.inTable.endTagIgnore=function(t){e.parseError("unexpected-end-tag",{name:t})},t.inTable.endTagOther=function(n){e.parseError("unexpected-end-tag-implies-table-voodoo",{name:n}),e.redirectAttachToFosterParent=!0,t.inBody.processEndTag(n),e.redirectAttachToFosterParent=!1},t.inTableText=Object.create(t.base),t.inTableText.flushCharacters=function(){var t=e.pendingTableCharacters.join("");p(t)?e.insertText(t):(e.redirectAttachToFosterParent=!0,e.reconstructActiveFormattingElements(),e.insertText(t),e.framesetOk=!1,e.redirectAttachToFosterParent=!1),e.pendingTableCharacters=[]},t.inTableText.processComment=function(t){this.flushCharacters(),e.setInsertionMode(e.originalInsertionMode),e.insertionMode.processComment(t)},t.inTableText.processEOF=function(t){this.flushCharacters(),e.setInsertionMode(e.originalInsertionMode),e.insertionMode.processEOF()},t.inTableText.processCharacters=function(t){var n=t.takeRemaining();n=n.replace(/\u0000/g,function(t,n){return e.parseError("invalid-codepoint"),""});if(!n)return;e.pendingTableCharacters.push(n)},t.inTableText.processStartTag=function(t,n,r){this.flushCharacters(),e.setInsertionMode(e.originalInsertionMode),e.insertionMode.processStartTag(t,n,r)},t.inTableText.processEndTag=function(t,n){this.flushCharacters(),e.setInsertionMode(e.originalInsertionMode),e.insertionMode.processEndTag(t,n)},t.inTableBody=Object.create(t.base),t.inTableBody.start_tag_handlers={html:"startTagHtml",tr:"startTagTr",td:"startTagTableCell",th:"startTagTableCell",caption:"startTagTableOther",col:"startTagTableOther",colgroup:"startTagTableOther",tbody:"startTagTableOther",tfoot:"startTagTableOther",thead:"startTagTableOther","-default":"startTagOther"},t.inTableBody.end_tag_handlers={table:"endTagTable",tbody:"endTagTableRowGroup",tfoot:"endTagTableRowGroup",thead:"endTagTableRowGroup",body:"endTagIgnore",caption:"endTagIgnore",col:"endTagIgnore",colgroup:"endTagIgnore",html:"endTagIgnore",td:"endTagIgnore",th:"endTagIgnore",tr:"endTagIgnore","-default":"endTagOther"},t.inTableBody.processCharacters=function(e){t.inTable.processCharacters(e)},t.inTableBody.startTagTr=function(t,n){e.openElements.popUntilTableBodyScopeMarker(),e.insertElement(t,n),e.setInsertionMode("inRow")},t.inTableBody.startTagTableCell=function(t,n){e.parseError("unexpected-cell-in-table-body",{name:t}),this.startTagTr("tr",[]),e.insertionMode.processStartTag(t,n)},t.inTableBody.startTagTableOther=function(t,n){e.openElements.inTableScope("tbody")||e.openElements.inTableScope("thead")||e.openElements.inTableScope("tfoot")?(e.openElements.popUntilTableBodyScopeMarker(),this.endTagTableRowGroup(e.currentStackItem().localName),e.insertionMode.processStartTag(t,n)):e.parseError("unexpected-start-tag",{name:t})},t.inTableBody.startTagOther=function(e,n){t.inTable.processStartTag(e,n)},t.inTableBody.endTagTableRowGroup=function(t){e.openElements.inTableScope(t)?(e.openElements.popUntilTableBodyScopeMarker(),e.popElement(),e.setInsertionMode("inTable")):e.parseError("unexpected-end-tag-in-table-body",{name:t})},t.inTableBody.endTagTable=function(t){e.openElements.inTableScope("tbody")||e.openElements.inTableScope("thead")||e.openElements.inTableScope("tfoot")?(e.openElements.popUntilTableBodyScopeMarker(),this.endTagTableRowGroup(e.currentStackItem().localName),e.insertionMode.processEndTag(t)):e.parseError("unexpected-end-tag",{name:t})},t.inTableBody.endTagIgnore=function(t){e.parseError("unexpected-end-tag-in-table-body",{name:t})},t.inTableBody.endTagOther=function(e){t.inTable.processEndTag(e)},t.inSelect=Object.create(t.base),t.inSelect.start_tag_handlers={html:"startTagHtml",option:"startTagOption",optgroup:"startTagOptgroup",select:"startTagSelect",input:"startTagInput",keygen:"startTagInput",textarea:"startTagInput",script:"startTagScript","-default":"startTagOther"},t.inSelect.end_tag_handlers={option:"endTagOption",optgroup:"endTagOptgroup",select:"endTagSelect",caption:"endTagTableElements",table:"endTagTableElements",tbody:"endTagTableElements",tfoot:"endTagTableElements",thead:"endTagTableElements",tr:"endTagTableElements",td:"endTagTableElements",th:"endTagTableElements","-default":"endTagOther"},t.inSelect.processCharacters=function(t){var n=t.takeRemaining();n=n.replace(/\u0000/g,function(t,n){return e.parseError("invalid-codepoint"),""});if(!n)return;e.insertText(n)},t.inSelect.startTagOption=function(t,n){e.currentStackItem().localName=="option"&&e.popElement(),e.insertElement(t,n)},t.inSelect.startTagOptgroup=function(t,n){e.currentStackItem().localName=="option"&&e.popElement(),e.currentStackItem().localName=="optgroup"&&e.popElement(),e.insertElement(t,n)},t.inSelect.endTagOption=function(t){if(e.currentStackItem().localName!=="option"){e.parseError("unexpected-end-tag-in-select",{name:t});return}e.popElement()},t.inSelect.endTagOptgroup=function(t){e.currentStackItem().localName=="option"&&e.openElements.item(e.openElements.length-2).localName=="optgroup"&&e.popElement(),e.currentStackItem().localName=="optgroup"?e.popElement():e.parseError("unexpected-end-tag-in-select",{name:"optgroup"})},t.inSelect.startTagSelect=function(t){e.parseError("unexpected-select-in-select"),this.endTagSelect("select")},t.inSelect.endTagSelect=function(t){e.openElements.inTableScope("select")?(e.openElements.popUntilPopped("select"),e.resetInsertionMode()):e.parseError("unexpected-end-tag",{name:t})},t.inSelect.startTagInput=function(t,n){e.parseError("unexpected-input-in-select"),e.openElements.inSelectScope("select")&&(this.endTagSelect("select"),e.insertionMode.processStartTag(t,n))},t.inSelect.startTagScript=function(e,n){t.inHead.processStartTag(e,n)},t.inSelect.endTagTableElements=function(t){e.parseError("unexpected-end-tag-in-select",{name:t}),e.openElements.inTableScope(t)&&(this.endTagSelect("select"),e.insertionMode.processEndTag(t))},t.inSelect.startTagOther=function(t,n){e.parseError("unexpected-start-tag-in-select",{name:t})},t.inSelect.endTagOther=function(t){e.parseError("unexpected-end-tag-in-select",{name:t})},t.inSelectInTable=Object.create(t.base),t.inSelectInTable.start_tag_handlers={caption:"startTagTable",table:"startTagTable",tbody:"startTagTable",tfoot:"startTagTable",thead:"startTagTable",tr:"startTagTable",td:"startTagTable",th:"startTagTable","-default":"startTagOther"},t.inSelectInTable.end_tag_handlers={caption:"endTagTable",table:"endTagTable",tbody:"endTagTable",tfoot:"endTagTable",thead:"endTagTable",tr:"endTagTable",td:"endTagTable",th:"endTagTable","-default":"endTagOther"},t.inSelectInTable.processCharacters=function(e){t.inSelect.processCharacters(e)},t.inSelectInTable.startTagTable=function(t,n){e.parseError("unexpected-table-element-start-tag-in-select-in-table",{name:t}),this.endTagOther("select"),e.insertionMode.processStartTag(t,n)},t.inSelectInTable.startTagOther=function(e,n,r){t.inSelect.processStartTag(e,n,r)},t.inSelectInTable.endTagTable=function(t){e.parseError("unexpected-table-element-end-tag-in-select-in-table",{name:t}),e.openElements.inTableScope(t)&&(this.endTagOther("select"),e.insertionMode.processEndTag(t))},t.inSelectInTable.endTagOther=function(e){t.inSelect.processEndTag(e)},t.inRow=Object.create(t.base),t.inRow.start_tag_handlers={html:"startTagHtml",td:"startTagTableCell",th:"startTagTableCell",caption:"startTagTableOther",col:"startTagTableOther",colgroup:"startTagTableOther",tbody:"startTagTableOther",tfoot:"startTagTableOther",thead:"startTagTableOther",tr:"startTagTableOther","-default":"startTagOther"},t.inRow.end_tag_handlers={tr:"endTagTr",table:"endTagTable",tbody:"endTagTableRowGroup",tfoot:"endTagTableRowGroup",thead:"endTagTableRowGroup",body:"endTagIgnore",caption:"endTagIgnore",col:"endTagIgnore",colgroup:"endTagIgnore",html:"endTagIgnore",td:"endTagIgnore",th:"endTagIgnore","-default":"endTagOther"},t.inRow.processCharacters=function(e){t.inTable.processCharacters(e)},t.inRow.startTagTableCell=function(t,n){e.openElements.popUntilTableRowScopeMarker(),e.insertElement(t,n),e.setInsertionMode("inCell"),e.activeFormattingElements.push(l)},t.inRow.startTagTableOther=function(t,n){var r=this.ignoreEndTagTr();this.endTagTr("tr"),r||e.insertionMode.processStartTag(t,n)},t.inRow.startTagOther=function(e,n,r){t.inTable.processStartTag(e,n,r)},t.inRow.endTagTr=function(t){this.ignoreEndTagTr()?(r.ok(e.context),e.parseError("unexpected-end-tag",{name:t})):(e.openElements.popUntilTableRowScopeMarker(),e.popElement(),e.setInsertionMode("inTableBody"))},t.inRow.endTagTable=function(t){var n=this.ignoreEndTagTr();this.endTagTr("tr"),n||e.insertionMode.processEndTag(t)},t.inRow.endTagTableRowGroup=function(t){e.openElements.inTableScope(t)?(this.endTagTr("tr"),e.insertionMode.processEndTag(t)):e.parseError("unexpected-end-tag",{name:t})},t.inRow.endTagIgnore=function(t){e.parseError("unexpected-end-tag-in-table-row",{name:t})},t.inRow.endTagOther=function(e){t.inTable.processEndTag(e)},t.inRow.ignoreEndTagTr=function(){return!e.openElements.inTableScope("tr")},t.afterAfterFrameset=Object.create(t.base),t.afterAfterFrameset.start_tag_handlers={html:"startTagHtml",noframes:"startTagNoFrames","-default":"startTagOther"},t.afterAfterFrameset.processEOF=function(){},t.afterAfterFrameset.processComment=function(t){e.insertComment(t,e.document)},t.afterAfterFrameset.processCharacters=function(t){var n=t.takeRemaining(),r="";for(var i=0;i0&&this.currentStackItem().isForeign()},g.prototype.isSelfClosingFlagAcknowledged=function(){return this.selfClosingFlagAcknowledged},g.prototype.createElement=function(e,t,n){throw new Error("Not implemented")},g.prototype.attachNode=function(e,t){throw new Error("Not implemented")},g.prototype.attachNodeToFosterParent=function(e,t,n){throw new Error("Not implemented")},g.prototype.detachFromParent=function(e){throw new Error("Not implemented")},g.prototype.addAttributesToElement=function(e,t){throw new Error("Not implemented")},g.prototype.insertHtmlElement=function(e){var t=this.createElement("http://www.w3.org/1999/xhtml","html",e);return this.attachNode(t,this.document),this.openElements.pushHtmlElement(new f("http://www.w3.org/1999/xhtml","html",e,t)),t},g.prototype.insertHeadElement=function(e){var t=this.createElement("http://www.w3.org/1999/xhtml","head",e);return this.head=new f("http://www.w3.org/1999/xhtml","head",e,t),this.attachNode(t,this.openElements.top.node),this.openElements.pushHeadElement(this.head),t},g.prototype.insertBodyElement=function(e){var t=this.createElement("http://www.w3.org/1999/xhtml","body",e);return this.attachNode(t,this.openElements.top.node),this.openElements.pushBodyElement(new f("http://www.w3.org/1999/xhtml","body",e,t)),t},g.prototype.insertIntoFosterParent=function(e){var t=this.openElements.findIndex("table"),n=this.openElements.item(t).node;if(t===0)return this.attachNode(e,n);this.attachNodeToFosterParent(e,n,this.openElements.item(t-1).node)},g.prototype.insertElement=function(e,t,n,r){n||(n="http://www.w3.org/1999/xhtml");var i=this.createElement(n,e,t);this.shouldFosterParent()?this.insertIntoFosterParent(i):this.attachNode(i,this.openElements.top.node),r||this.openElements.push(new f(n,e,t,i))},g.prototype.insertFormattingElement=function(e,t){this.insertElement(e,t,"http://www.w3.org/1999/xhtml"),this.appendElementToActiveFormattingElements(this.currentStackItem())},g.prototype.insertSelfClosingElement=function(e,t){this.selfClosingFlagAcknowledged=!0,this.insertElement(e,t,"http://www.w3.org/1999/xhtml",!0)},g.prototype.insertForeignElement=function(e,t,n,r){r&&(this.selfClosingFlagAcknowledged=!0),this.insertElement(e,t,n,r)},g.prototype.insertComment=function(e,t){throw new Error("Not implemented")},g.prototype.insertDoctype=function(e,t,n){throw new Error("Not implemented")},g.prototype.insertText=function(e){throw new Error("Not implemented")},g.prototype.currentStackItem=function(){return this.openElements.top},g.prototype.popElement=function(){return this.openElements.pop()},g.prototype.shouldFosterParent=function(){return this.redirectAttachToFosterParent&&this.currentStackItem().isFosterParenting()},g.prototype.generateImpliedEndTags=function(e){var t=this.openElements.top.localName;["dd","dt","li","option","optgroup","p","rp","rt"].indexOf(t)!=-1&&t!=e&&(this.popElement(),this.generateImpliedEndTags(e))},g.prototype.reconstructActiveFormattingElements=function(){if(this.activeFormattingElements.length===0)return;var e=this.activeFormattingElements.length-1,t=this.activeFormattingElements[e];if(t==l||this.openElements.contains(t))return;while(t!=l&&!this.openElements.contains(t)){e-=1,t=this.activeFormattingElements[e];if(!t)break}for(;;){e+=1,t=this.activeFormattingElements[e],this.insertElement(t.localName,t.attributes);var n=this.currentStackItem();this.activeFormattingElements[e]=n;if(n==this.activeFormattingElements[this.activeFormattingElements.length-1])break}},g.prototype.ensureNoahsArkCondition=function(e){var t=3;if(this.activeFormattingElements.length=0;i--){var s=this.activeFormattingElements[i];if(s===l)break;if(e.localName!==s.localName||e.namespaceURI!==s.namespaceURI)continue;if(s.attributes.length!=r)continue;n.push(s)}if(n.length=0&&this.activeFormattingElements.splice(t,1)},g.prototype.elementInActiveFormattingElements=function(e){var t=this.activeFormattingElements;for(var n=t.length-1;n>=0;n--){if(t[n]==l)break;if(t[n].localName==e)return t[n]}return!1},g.prototype.clearActiveFormattingElements=function(){while(this.activeFormattingElements.length!==0&&this.activeFormattingElements.pop()!=l);},g.prototype.reparentChildren=function(e,t){throw new Error("Not implemented")},g.prototype.setFragmentContext=function(e){this.context=e},g.prototype.parseError=function(e,t){if(!this.errorHandler)return;var n=y(i[e],t);this.errorHandler.error(n,this.tokenizer._inputStream.location(),e)},g.prototype.resetInsertionMode=function(){var e=!1,t=null;for(var n=this.openElements.length-1;n>=0;n--){t=this.openElements.item(n),n===0&&(r.ok(this.context),e=!0,t=new f("http://www.w3.org/1999/xhtml",this.context,[],null));if(t.namespaceURI==="http://www.w3.org/1999/xhtml"){if(t.localName==="select")return this.setInsertionMode("inSelect");if(t.localName==="td"||t.localName==="th")return this.setInsertionMode("inCell");if(t.localName==="tr")return this.setInsertionMode("inRow");if(t.localName==="tbody"||t.localName==="thead"||t.localName==="tfoot")return this.setInsertionMode("inTableBody");if(t.localName==="caption")return this.setInsertionMode("inCaption");if(t.localName==="colgroup")return this.setInsertionMode("inColumnGroup");if(t.localName==="table")return this.setInsertionMode("inTable");if(t.localName==="head"&&!e)return this.setInsertionMode("inHead");if(t.localName==="body")return this.setInsertionMode("inBody");if(t.localName==="frameset")return this.setInsertionMode("inFrameset");if(t.localName==="html")return this.openElements.headElement?this.setInsertionMode("afterHead"):this.setInsertionMode("beforeHead")}if(e)return this.setInsertionMode("inBody")}},g.prototype.processGenericRCDATAStartTag=function(e,t){this.insertElement(e,t),this.tokenizer.setState(u.RCDATA),this.originalInsertionMode=this.insertionModeName,this.setInsertionMode("text")},g.prototype.processGenericRawTextStartTag=function(e,t){this.insertElement(e,t),this.tokenizer.setState(u.RAWTEXT),this.originalInsertionMode=this.insertionModeName,this.setInsertionMode("text")},g.prototype.adjustMathMLAttributes=function(e){return e.forEach(function(e){e.namespaceURI="http://www.w3.org/1998/Math/MathML",s.MATHMLAttributeMap[e.nodeName]&&(e.nodeName=s.MATHMLAttributeMap[e.nodeName])}),e},g.prototype.adjustSVGTagNameCase=function(e){return s.SVGTagMap[e]||e},g.prototype.adjustSVGAttributes=function(e){return e.forEach(function(e){e.namespaceURI="http://www.w3.org/2000/svg",s.SVGAttributeMap[e.nodeName]&&(e.nodeName=s.SVGAttributeMap[e.nodeName])}),e},g.prototype.adjustForeignAttributes=function(e){for(var t=0;t' instead.","expected-tag-name-but-got-question-mark":"Expected tag name. Got '?' instead. (HTML doesn't support processing instructions.)","expected-tag-name":"Expected tag name. Got something else instead.","expected-closing-tag-but-got-right-bracket":"Expected closing tag. Got '>' instead. Ignoring ''.","expected-closing-tag-but-got-eof":"Expected closing tag. Unexpected end of file.","expected-closing-tag-but-got-char":"Expected closing tag. Unexpected character '{data}' found.","eof-in-tag-name":"Unexpected end of file in the tag name.","expected-attribute-name-but-got-eof":"Unexpected end of file. Expected attribute name instead.","eof-in-attribute-name":"Unexpected end of file in attribute name.","invalid-character-in-attribute-name":"Invalid character in attribute name.","duplicate-attribute":"Dropped duplicate attribute '{name}' on tag.","expected-end-of-tag-but-got-eof":"Unexpected end of file. Expected = or end of tag.","expected-attribute-value-but-got-eof":"Unexpected end of file. Expected attribute value.","expected-attribute-value-but-got-right-bracket":"Expected attribute value. Got '>' instead.","unexpected-character-in-unquoted-attribute-value":"Unexpected character in unquoted attribute","invalid-character-after-attribute-name":"Unexpected character after attribute name.","unexpected-character-after-attribute-value":"Unexpected character after attribute value.","eof-in-attribute-value-double-quote":'Unexpected end of file in attribute value (").',"eof-in-attribute-value-single-quote":"Unexpected end of file in attribute value (').","eof-in-attribute-value-no-quotes":"Unexpected end of file in attribute value.","eof-after-attribute-value":"Unexpected end of file after attribute value.","unexpected-eof-after-solidus-in-tag":"Unexpected end of file in tag. Expected >.","unexpected-character-after-solidus-in-tag":"Unexpected character after / in tag. Expected >.","expected-dashes-or-doctype":"Expected '--' or 'DOCTYPE'. Not found.","unexpected-bang-after-double-dash-in-comment":"Unexpected ! after -- in comment.","incorrect-comment":"Incorrect comment.","eof-in-comment":"Unexpected end of file in comment.","eof-in-comment-end-dash":"Unexpected end of file in comment (-).","unexpected-dash-after-double-dash-in-comment":"Unexpected '-' after '--' found in comment.","eof-in-comment-double-dash":"Unexpected end of file in comment (--).","eof-in-comment-end-bang-state":"Unexpected end of file in comment.","unexpected-char-in-comment":"Unexpected character in comment found.","need-space-after-doctype":"No space after literal string 'DOCTYPE'.","expected-doctype-name-but-got-right-bracket":"Unexpected > character. Expected DOCTYPE name.","expected-doctype-name-but-got-eof":"Unexpected end of file. Expected DOCTYPE name.","eof-in-doctype-name":"Unexpected end of file in DOCTYPE name.","eof-in-doctype":"Unexpected end of file in DOCTYPE.","expected-space-or-right-bracket-in-doctype":"Expected space or '>'. Got '{data}'.","unexpected-end-of-doctype":"Unexpected end of DOCTYPE.","unexpected-char-in-doctype":"Unexpected character in DOCTYPE.","eof-in-bogus-doctype":"Unexpected end of file in bogus doctype.","eof-in-innerhtml":"Unexpected EOF in inner html mode.","unexpected-doctype":"Unexpected DOCTYPE. Ignored.","non-html-root":"html needs to be the first start tag.","expected-doctype-but-got-eof":"Unexpected End of file. Expected DOCTYPE.","unknown-doctype":"Erroneous DOCTYPE. Expected .","quirky-doctype":"Quirky doctype. Expected .","almost-standards-doctype":"Almost standards mode doctype. Expected .","obsolete-doctype":"Obsolete doctype. Expected .","expected-doctype-but-got-chars":"Non-space characters found without seeing a doctype first. Expected e.g. .","expected-doctype-but-got-start-tag":"Start tag seen without seeing a doctype first. Expected e.g. .","expected-doctype-but-got-end-tag":"End tag seen without seeing a doctype first. Expected e.g. .","end-tag-after-implied-root":"Unexpected end tag ({name}) after the (implied) root element.","expected-named-closing-tag-but-got-eof":"Unexpected end of file. Expected end tag ({name}).","two-heads-are-not-better-than-one":"Unexpected start tag head in existing head. Ignored.","unexpected-end-tag":"Unexpected end tag ({name}). Ignored.","unexpected-implied-end-tag":"End tag {name} implied, but there were open elements.","unexpected-start-tag-out-of-my-head":"Unexpected start tag ({name}) that can be in head. Moved.","unexpected-start-tag":"Unexpected start tag ({name}).","missing-end-tag":"Missing end tag ({name}).","missing-end-tags":"Missing end tags ({name}).","unexpected-start-tag-implies-end-tag":"Unexpected start tag ({startName}) implies end tag ({endName}).","unexpected-start-tag-treated-as":"Unexpected start tag ({originalName}). Treated as {newName}.","deprecated-tag":"Unexpected start tag {name}. Don't use it!","unexpected-start-tag-ignored":"Unexpected start tag {name}. Ignored.","expected-one-end-tag-but-got-another":"Unexpected end tag ({gotName}). Missing end tag ({expectedName}).","end-tag-too-early":"End tag ({name}) seen too early. Expected other end tag.","end-tag-too-early-named":"Unexpected end tag ({gotName}). Expected end tag ({expectedName}.","end-tag-too-early-ignored":"End tag ({name}) seen too early. Ignored.","adoption-agency-1.1":"End tag ({name}) violates step 1, paragraph 1 of the adoption agency algorithm.","adoption-agency-1.2":"End tag ({name}) violates step 1, paragraph 2 of the adoption agency algorithm.","adoption-agency-1.3":"End tag ({name}) violates step 1, paragraph 3 of the adoption agency algorithm.","adoption-agency-4.4":"End tag ({name}) violates step 4, paragraph 4 of the adoption agency algorithm.","unexpected-end-tag-treated-as":"Unexpected end tag ({originalName}). Treated as {newName}.","no-end-tag":"This element ({name}) has no end tag.","unexpected-implied-end-tag-in-table":"Unexpected implied end tag ({name}) in the table phase.","unexpected-implied-end-tag-in-table-body":"Unexpected implied end tag ({name}) in the table body phase.","unexpected-char-implies-table-voodoo":"Unexpected non-space characters in table context caused voodoo mode.","unexpected-hidden-input-in-table":"Unexpected input with type hidden in table context.","unexpected-form-in-table":"Unexpected form in table context.","unexpected-start-tag-implies-table-voodoo":"Unexpected start tag ({name}) in table context caused voodoo mode.","unexpected-end-tag-implies-table-voodoo":"Unexpected end tag ({name}) in table context caused voodoo mode.","unexpected-cell-in-table-body":"Unexpected table cell start tag ({name}) in the table body phase.","unexpected-cell-end-tag":"Got table cell end tag ({name}) while required end tags are missing.","unexpected-end-tag-in-table-body":"Unexpected end tag ({name}) in the table body phase. Ignored.","unexpected-implied-end-tag-in-table-row":"Unexpected implied end tag ({name}) in the table row phase.","unexpected-end-tag-in-table-row":"Unexpected end tag ({name}) in the table row phase. Ignored.","unexpected-select-in-select":"Unexpected select start tag in the select phase treated as select end tag.","unexpected-input-in-select":"Unexpected input start tag in the select phase.","unexpected-start-tag-in-select":"Unexpected start tag token ({name}) in the select phase. Ignored.","unexpected-end-tag-in-select":"Unexpected end tag ({name}) in the select phase. Ignored.","unexpected-table-element-start-tag-in-select-in-table":"Unexpected table element start tag ({name}) in the select in table phase.","unexpected-table-element-end-tag-in-select-in-table":"Unexpected table element end tag ({name}) in the select in table phase.","unexpected-char-after-body":"Unexpected non-space characters in the after body phase.","unexpected-start-tag-after-body":"Unexpected start tag token ({name}) in the after body phase.","unexpected-end-tag-after-body":"Unexpected end tag token ({name}) in the after body phase.","unexpected-char-in-frameset":"Unepxected characters in the frameset phase. Characters ignored.","unexpected-start-tag-in-frameset":"Unexpected start tag token ({name}) in the frameset phase. Ignored.","unexpected-frameset-in-frameset-innerhtml":"Unexpected end tag token (frameset in the frameset phase (innerHTML).","unexpected-end-tag-in-frameset":"Unexpected end tag token ({name}) in the frameset phase. Ignored.","unexpected-char-after-frameset":"Unexpected non-space characters in the after frameset phase. Ignored.","unexpected-start-tag-after-frameset":"Unexpected start tag ({name}) in the after frameset phase. Ignored.","unexpected-end-tag-after-frameset":"Unexpected end tag ({name}) in the after frameset phase. Ignored.","expected-eof-but-got-char":"Unexpected non-space characters. Expected end of file.","expected-eof-but-got-start-tag":"Unexpected start tag ({name}). Expected end of file.","expected-eof-but-got-end-tag":"Unexpected end tag ({name}). Expected end of file.","unexpected-end-table-in-caption":"Unexpected end table tag in caption. Generates implied end caption.","end-html-in-innerhtml":"Unexpected html end tag in inner html mode.","eof-in-table":"Unexpected end of file. Expected table content.","eof-in-script":"Unexpected end of file. Expected script content.","non-void-element-with-trailing-solidus":"Trailing solidus not allowed on element {name}.","unexpected-html-element-in-foreign-content":'HTML start tag "{name}" in a foreign namespace context.',"unexpected-start-tag-in-table":"Unexpected {name}. Expected table content."}},{}],9:[function(e,t,n){function o(){this.contentHandler=null,this._errorHandler=null,this._treeBuilder=new r,this._tokenizer=new i(this._treeBuilder),this._scriptingEnabled=!1}var r=e("./SAXTreeBuilder").SAXTreeBuilder,i=e("../Tokenizer").Tokenizer,s=e("./TreeParser").TreeParser;o.prototype.parse=function(e){this._tokenizer.tokenize(e);var t=this._treeBuilder.document;t&&(new s(this.contentHandler)).parse(t)},o.prototype.parseFragment=function(e,t){this._treeBuilder.setFragmentContext(t),this._tokenizer.tokenize(e);var n=this._treeBuilder.getFragment();n&&(new s(this.contentHandler)).parse(n)},Object.defineProperty(o.prototype,"scriptingEnabled",{get:function(){return this._scriptingEnabled},set:function(e){this._scriptingEnabled=e,this._treeBuilder.scriptingEnabled=e}}),Object.defineProperty(o.prototype,"errorHandler",{get:function(){return this._errorHandler},set:function(e){this._errorHandler=e,this._treeBuilder.errorHandler=e}}),n.SAXParser=o},{"../Tokenizer":5,"./SAXTreeBuilder":10,"./TreeParser":11}],10:[function(e,t,n){function s(){i.call(this)}function o(e,t){for(var n=0;n",gt:">","GT;":">",GT:">","Gt;":"\u226b","gtdot;":"\u22d7","gtlPar;":"\u2995","gtquest;":"\u2a7c","gtrapprox;":"\u2a86","gtrarr;":"\u2978","gtrdot;":"\u22d7","gtreqless;":"\u22db","gtreqqless;":"\u2a8c","gtrless;":"\u2277","gtrsim;":"\u2273","gvertneqq;":"\u2269\ufe00","gvnE;":"\u2269\ufe00","Hacek;":"\u02c7","hairsp;":"\u200a","half;":"\u00bd","hamilt;":"\u210b","HARDcy;":"\u042a","hardcy;":"\u044a","harrcir;":"\u2948","harr;":"\u2194","hArr;":"\u21d4","harrw;":"\u21ad","Hat;":"^","hbar;":"\u210f","Hcirc;":"\u0124","hcirc;":"\u0125","hearts;":"\u2665","heartsuit;":"\u2665","hellip;":"\u2026","hercon;":"\u22b9","hfr;":"\ud835\udd25","Hfr;":"\u210c","HilbertSpace;":"\u210b","hksearow;":"\u2925","hkswarow;":"\u2926","hoarr;":"\u21ff","homtht;":"\u223b","hookleftarrow;":"\u21a9","hookrightarrow;":"\u21aa","hopf;":"\ud835\udd59","Hopf;":"\u210d","horbar;":"\u2015","HorizontalLine;":"\u2500","hscr;":"\ud835\udcbd","Hscr;":"\u210b","hslash;":"\u210f","Hstrok;":"\u0126","hstrok;":"\u0127","HumpDownHump;":"\u224e","HumpEqual;":"\u224f","hybull;":"\u2043","hyphen;":"\u2010","Iacute;":"\u00cd",Iacute:"\u00cd","iacute;":"\u00ed",iacute:"\u00ed","ic;":"\u2063","Icirc;":"\u00ce",Icirc:"\u00ce","icirc;":"\u00ee",icirc:"\u00ee","Icy;":"\u0418","icy;":"\u0438","Idot;":"\u0130","IEcy;":"\u0415","iecy;":"\u0435","iexcl;":"\u00a1",iexcl:"\u00a1","iff;":"\u21d4","ifr;":"\ud835\udd26","Ifr;":"\u2111","Igrave;":"\u00cc",Igrave:"\u00cc","igrave;":"\u00ec",igrave:"\u00ec","ii;":"\u2148","iiiint;":"\u2a0c","iiint;":"\u222d","iinfin;":"\u29dc","iiota;":"\u2129","IJlig;":"\u0132","ijlig;":"\u0133","Imacr;":"\u012a","imacr;":"\u012b","image;":"\u2111","ImaginaryI;":"\u2148","imagline;":"\u2110","imagpart;":"\u2111","imath;":"\u0131","Im;":"\u2111","imof;":"\u22b7","imped;":"\u01b5","Implies;":"\u21d2","incare;":"\u2105","in;":"\u2208","infin;":"\u221e","infintie;":"\u29dd","inodot;":"\u0131","intcal;":"\u22ba","int;":"\u222b","Int;":"\u222c","integers;":"\u2124","Integral;":"\u222b","intercal;":"\u22ba","Intersection;":"\u22c2","intlarhk;":"\u2a17","intprod;":"\u2a3c","InvisibleComma;":"\u2063","InvisibleTimes;":"\u2062","IOcy;":"\u0401","iocy;":"\u0451","Iogon;":"\u012e","iogon;":"\u012f","Iopf;":"\ud835\udd40","iopf;":"\ud835\udd5a","Iota;":"\u0399","iota;":"\u03b9","iprod;":"\u2a3c","iquest;":"\u00bf",iquest:"\u00bf","iscr;":"\ud835\udcbe","Iscr;":"\u2110","isin;":"\u2208","isindot;":"\u22f5","isinE;":"\u22f9","isins;":"\u22f4","isinsv;":"\u22f3","isinv;":"\u2208","it;":"\u2062","Itilde;":"\u0128","itilde;":"\u0129","Iukcy;":"\u0406","iukcy;":"\u0456","Iuml;":"\u00cf",Iuml:"\u00cf","iuml;":"\u00ef",iuml:"\u00ef","Jcirc;":"\u0134","jcirc;":"\u0135","Jcy;":"\u0419","jcy;":"\u0439","Jfr;":"\ud835\udd0d","jfr;":"\ud835\udd27","jmath;":"\u0237","Jopf;":"\ud835\udd41","jopf;":"\ud835\udd5b","Jscr;":"\ud835\udca5","jscr;":"\ud835\udcbf","Jsercy;":"\u0408","jsercy;":"\u0458","Jukcy;":"\u0404","jukcy;":"\u0454","Kappa;":"\u039a","kappa;":"\u03ba","kappav;":"\u03f0","Kcedil;":"\u0136","kcedil;":"\u0137","Kcy;":"\u041a","kcy;":"\u043a","Kfr;":"\ud835\udd0e","kfr;":"\ud835\udd28","kgreen;":"\u0138","KHcy;":"\u0425","khcy;":"\u0445","KJcy;":"\u040c","kjcy;":"\u045c","Kopf;":"\ud835\udd42","kopf;":"\ud835\udd5c","Kscr;":"\ud835\udca6","kscr;":"\ud835\udcc0","lAarr;":"\u21da","Lacute;":"\u0139","lacute;":"\u013a","laemptyv;":"\u29b4","lagran;":"\u2112","Lambda;":"\u039b","lambda;":"\u03bb","lang;":"\u27e8","Lang;":"\u27ea","langd;":"\u2991","langle;":"\u27e8","lap;":"\u2a85","Laplacetrf;":"\u2112","laquo;":"\u00ab",laquo:"\u00ab","larrb;":"\u21e4","larrbfs;":"\u291f","larr;":"\u2190","Larr;":"\u219e","lArr;":"\u21d0","larrfs;":"\u291d","larrhk;":"\u21a9","larrlp;":"\u21ab","larrpl;":"\u2939","larrsim;":"\u2973","larrtl;":"\u21a2","latail;":"\u2919","lAtail;":"\u291b","lat;":"\u2aab","late;":"\u2aad","lates;":"\u2aad\ufe00","lbarr;":"\u290c","lBarr;":"\u290e","lbbrk;":"\u2772","lbrace;":"{","lbrack;":"[","lbrke;":"\u298b","lbrksld;":"\u298f","lbrkslu;":"\u298d","Lcaron;":"\u013d","lcaron;":"\u013e","Lcedil;":"\u013b","lcedil;":"\u013c","lceil;":"\u2308","lcub;":"{","Lcy;":"\u041b","lcy;":"\u043b","ldca;":"\u2936","ldquo;":"\u201c","ldquor;":"\u201e","ldrdhar;":"\u2967","ldrushar;":"\u294b","ldsh;":"\u21b2","le;":"\u2264","lE;":"\u2266","LeftAngleBracket;":"\u27e8","LeftArrowBar;":"\u21e4","leftarrow;":"\u2190","LeftArrow;":"\u2190","Leftarrow;":"\u21d0","LeftArrowRightArrow;":"\u21c6","leftarrowtail;":"\u21a2","LeftCeiling;":"\u2308","LeftDoubleBracket;":"\u27e6","LeftDownTeeVector;":"\u2961","LeftDownVectorBar;":"\u2959","LeftDownVector;":"\u21c3","LeftFloor;":"\u230a","leftharpoondown;":"\u21bd","leftharpoonup;":"\u21bc","leftleftarrows;":"\u21c7","leftrightarrow;":"\u2194","LeftRightArrow;":"\u2194","Leftrightarrow;":"\u21d4","leftrightarrows;":"\u21c6","leftrightharpoons;":"\u21cb","leftrightsquigarrow;":"\u21ad","LeftRightVector;":"\u294e","LeftTeeArrow;":"\u21a4","LeftTee;":"\u22a3","LeftTeeVector;":"\u295a","leftthreetimes;":"\u22cb","LeftTriangleBar;":"\u29cf","LeftTriangle;":"\u22b2","LeftTriangleEqual;":"\u22b4","LeftUpDownVector;":"\u2951","LeftUpTeeVector;":"\u2960","LeftUpVectorBar;":"\u2958","LeftUpVector;":"\u21bf","LeftVectorBar;":"\u2952","LeftVector;":"\u21bc","lEg;":"\u2a8b","leg;":"\u22da","leq;":"\u2264","leqq;":"\u2266","leqslant;":"\u2a7d","lescc;":"\u2aa8","les;":"\u2a7d","lesdot;":"\u2a7f","lesdoto;":"\u2a81","lesdotor;":"\u2a83","lesg;":"\u22da\ufe00","lesges;":"\u2a93","lessapprox;":"\u2a85","lessdot;":"\u22d6","lesseqgtr;":"\u22da","lesseqqgtr;":"\u2a8b","LessEqualGreater;":"\u22da","LessFullEqual;":"\u2266","LessGreater;":"\u2276","lessgtr;":"\u2276","LessLess;":"\u2aa1","lesssim;":"\u2272","LessSlantEqual;":"\u2a7d","LessTilde;":"\u2272","lfisht;":"\u297c","lfloor;":"\u230a","Lfr;":"\ud835\udd0f","lfr;":"\ud835\udd29","lg;":"\u2276","lgE;":"\u2a91","lHar;":"\u2962","lhard;":"\u21bd","lharu;":"\u21bc","lharul;":"\u296a","lhblk;":"\u2584","LJcy;":"\u0409","ljcy;":"\u0459","llarr;":"\u21c7","ll;":"\u226a","Ll;":"\u22d8","llcorner;":"\u231e","Lleftarrow;":"\u21da","llhard;":"\u296b","lltri;":"\u25fa","Lmidot;":"\u013f","lmidot;":"\u0140","lmoustache;":"\u23b0","lmoust;":"\u23b0","lnap;":"\u2a89","lnapprox;":"\u2a89","lne;":"\u2a87","lnE;":"\u2268","lneq;":"\u2a87","lneqq;":"\u2268","lnsim;":"\u22e6","loang;":"\u27ec","loarr;":"\u21fd","lobrk;":"\u27e6","longleftarrow;":"\u27f5","LongLeftArrow;":"\u27f5","Longleftarrow;":"\u27f8","longleftrightarrow;":"\u27f7","LongLeftRightArrow;":"\u27f7","Longleftrightarrow;":"\u27fa","longmapsto;":"\u27fc","longrightarrow;":"\u27f6","LongRightArrow;":"\u27f6","Longrightarrow;":"\u27f9","looparrowleft;":"\u21ab","looparrowright;":"\u21ac","lopar;":"\u2985","Lopf;":"\ud835\udd43","lopf;":"\ud835\udd5d","loplus;":"\u2a2d","lotimes;":"\u2a34","lowast;":"\u2217","lowbar;":"_","LowerLeftArrow;":"\u2199","LowerRightArrow;":"\u2198","loz;":"\u25ca","lozenge;":"\u25ca","lozf;":"\u29eb","lpar;":"(","lparlt;":"\u2993","lrarr;":"\u21c6","lrcorner;":"\u231f","lrhar;":"\u21cb","lrhard;":"\u296d","lrm;":"\u200e","lrtri;":"\u22bf","lsaquo;":"\u2039","lscr;":"\ud835\udcc1","Lscr;":"\u2112","lsh;":"\u21b0","Lsh;":"\u21b0","lsim;":"\u2272","lsime;":"\u2a8d","lsimg;":"\u2a8f","lsqb;":"[","lsquo;":"\u2018","lsquor;":"\u201a","Lstrok;":"\u0141","lstrok;":"\u0142","ltcc;":"\u2aa6","ltcir;":"\u2a79","lt;":"<",lt:"<","LT;":"<",LT:"<","Lt;":"\u226a","ltdot;":"\u22d6","lthree;":"\u22cb","ltimes;":"\u22c9","ltlarr;":"\u2976","ltquest;":"\u2a7b","ltri;":"\u25c3","ltrie;":"\u22b4","ltrif;":"\u25c2","ltrPar;":"\u2996","lurdshar;":"\u294a","luruhar;":"\u2966","lvertneqq;":"\u2268\ufe00","lvnE;":"\u2268\ufe00","macr;":"\u00af",macr:"\u00af","male;":"\u2642","malt;":"\u2720","maltese;":"\u2720","Map;":"\u2905","map;":"\u21a6","mapsto;":"\u21a6","mapstodown;":"\u21a7","mapstoleft;":"\u21a4","mapstoup;":"\u21a5","marker;":"\u25ae","mcomma;":"\u2a29","Mcy;":"\u041c","mcy;":"\u043c","mdash;":"\u2014","mDDot;":"\u223a","measuredangle;":"\u2221","MediumSpace;":"\u205f","Mellintrf;":"\u2133","Mfr;":"\ud835\udd10","mfr;":"\ud835\udd2a","mho;":"\u2127","micro;":"\u00b5",micro:"\u00b5","midast;":"*","midcir;":"\u2af0","mid;":"\u2223","middot;":"\u00b7",middot:"\u00b7","minusb;":"\u229f","minus;":"\u2212","minusd;":"\u2238","minusdu;":"\u2a2a","MinusPlus;":"\u2213","mlcp;":"\u2adb","mldr;":"\u2026","mnplus;":"\u2213","models;":"\u22a7","Mopf;":"\ud835\udd44","mopf;":"\ud835\udd5e","mp;":"\u2213","mscr;":"\ud835\udcc2","Mscr;":"\u2133","mstpos;":"\u223e","Mu;":"\u039c","mu;":"\u03bc","multimap;":"\u22b8","mumap;":"\u22b8","nabla;":"\u2207","Nacute;":"\u0143","nacute;":"\u0144","nang;":"\u2220\u20d2","nap;":"\u2249","napE;":"\u2a70\u0338","napid;":"\u224b\u0338","napos;":"\u0149","napprox;":"\u2249","natural;":"\u266e","naturals;":"\u2115","natur;":"\u266e","nbsp;":"\u00a0",nbsp:"\u00a0","nbump;":"\u224e\u0338","nbumpe;":"\u224f\u0338","ncap;":"\u2a43","Ncaron;":"\u0147","ncaron;":"\u0148","Ncedil;":"\u0145","ncedil;":"\u0146","ncong;":"\u2247","ncongdot;":"\u2a6d\u0338","ncup;":"\u2a42","Ncy;":"\u041d","ncy;":"\u043d","ndash;":"\u2013","nearhk;":"\u2924","nearr;":"\u2197","neArr;":"\u21d7","nearrow;":"\u2197","ne;":"\u2260","nedot;":"\u2250\u0338","NegativeMediumSpace;":"\u200b","NegativeThickSpace;":"\u200b","NegativeThinSpace;":"\u200b","NegativeVeryThinSpace;":"\u200b","nequiv;":"\u2262","nesear;":"\u2928","nesim;":"\u2242\u0338","NestedGreaterGreater;":"\u226b","NestedLessLess;":"\u226a","NewLine;":"\n","nexist;":"\u2204","nexists;":"\u2204","Nfr;":"\ud835\udd11","nfr;":"\ud835\udd2b","ngE;":"\u2267\u0338","nge;":"\u2271","ngeq;":"\u2271","ngeqq;":"\u2267\u0338","ngeqslant;":"\u2a7e\u0338","nges;":"\u2a7e\u0338","nGg;":"\u22d9\u0338","ngsim;":"\u2275","nGt;":"\u226b\u20d2","ngt;":"\u226f","ngtr;":"\u226f","nGtv;":"\u226b\u0338","nharr;":"\u21ae","nhArr;":"\u21ce","nhpar;":"\u2af2","ni;":"\u220b","nis;":"\u22fc","nisd;":"\u22fa","niv;":"\u220b","NJcy;":"\u040a","njcy;":"\u045a","nlarr;":"\u219a","nlArr;":"\u21cd","nldr;":"\u2025","nlE;":"\u2266\u0338","nle;":"\u2270","nleftarrow;":"\u219a","nLeftarrow;":"\u21cd","nleftrightarrow;":"\u21ae","nLeftrightarrow;":"\u21ce","nleq;":"\u2270","nleqq;":"\u2266\u0338","nleqslant;":"\u2a7d\u0338","nles;":"\u2a7d\u0338","nless;":"\u226e","nLl;":"\u22d8\u0338","nlsim;":"\u2274","nLt;":"\u226a\u20d2","nlt;":"\u226e","nltri;":"\u22ea","nltrie;":"\u22ec","nLtv;":"\u226a\u0338","nmid;":"\u2224","NoBreak;":"\u2060","NonBreakingSpace;":"\u00a0","nopf;":"\ud835\udd5f","Nopf;":"\u2115","Not;":"\u2aec","not;":"\u00ac",not:"\u00ac","NotCongruent;":"\u2262","NotCupCap;":"\u226d","NotDoubleVerticalBar;":"\u2226","NotElement;":"\u2209","NotEqual;":"\u2260","NotEqualTilde;":"\u2242\u0338","NotExists;":"\u2204","NotGreater;":"\u226f","NotGreaterEqual;":"\u2271","NotGreaterFullEqual;":"\u2267\u0338","NotGreaterGreater;":"\u226b\u0338","NotGreaterLess;":"\u2279","NotGreaterSlantEqual;":"\u2a7e\u0338","NotGreaterTilde;":"\u2275","NotHumpDownHump;":"\u224e\u0338","NotHumpEqual;":"\u224f\u0338","notin;":"\u2209","notindot;":"\u22f5\u0338","notinE;":"\u22f9\u0338","notinva;":"\u2209","notinvb;":"\u22f7","notinvc;":"\u22f6","NotLeftTriangleBar;":"\u29cf\u0338","NotLeftTriangle;":"\u22ea","NotLeftTriangleEqual;":"\u22ec","NotLess;":"\u226e","NotLessEqual;":"\u2270","NotLessGreater;":"\u2278","NotLessLess;":"\u226a\u0338","NotLessSlantEqual;":"\u2a7d\u0338","NotLessTilde;":"\u2274","NotNestedGreaterGreater;":"\u2aa2\u0338","NotNestedLessLess;":"\u2aa1\u0338","notni;":"\u220c","notniva;":"\u220c","notnivb;":"\u22fe","notnivc;":"\u22fd","NotPrecedes;":"\u2280","NotPrecedesEqual;":"\u2aaf\u0338","NotPrecedesSlantEqual;":"\u22e0","NotReverseElement;":"\u220c","NotRightTriangleBar;":"\u29d0\u0338","NotRightTriangle;":"\u22eb","NotRightTriangleEqual;":"\u22ed","NotSquareSubset;":"\u228f\u0338","NotSquareSubsetEqual;":"\u22e2","NotSquareSuperset;":"\u2290\u0338","NotSquareSupersetEqual;":"\u22e3","NotSubset;":"\u2282\u20d2","NotSubsetEqual;":"\u2288","NotSucceeds;":"\u2281","NotSucceedsEqual;":"\u2ab0\u0338","NotSucceedsSlantEqual;":"\u22e1","NotSucceedsTilde;":"\u227f\u0338","NotSuperset;":"\u2283\u20d2","NotSupersetEqual;":"\u2289","NotTilde;":"\u2241","NotTildeEqual;":"\u2244","NotTildeFullEqual;":"\u2247","NotTildeTilde;":"\u2249","NotVerticalBar;":"\u2224","nparallel;":"\u2226","npar;":"\u2226","nparsl;":"\u2afd\u20e5","npart;":"\u2202\u0338","npolint;":"\u2a14","npr;":"\u2280","nprcue;":"\u22e0","nprec;":"\u2280","npreceq;":"\u2aaf\u0338","npre;":"\u2aaf\u0338","nrarrc;":"\u2933\u0338","nrarr;":"\u219b","nrArr;":"\u21cf","nrarrw;":"\u219d\u0338","nrightarrow;":"\u219b","nRightarrow;":"\u21cf","nrtri;":"\u22eb","nrtrie;":"\u22ed","nsc;":"\u2281","nsccue;":"\u22e1","nsce;":"\u2ab0\u0338","Nscr;":"\ud835\udca9","nscr;":"\ud835\udcc3","nshortmid;":"\u2224","nshortparallel;":"\u2226","nsim;":"\u2241","nsime;":"\u2244","nsimeq;":"\u2244","nsmid;":"\u2224","nspar;":"\u2226","nsqsube;":"\u22e2","nsqsupe;":"\u22e3","nsub;":"\u2284","nsubE;":"\u2ac5\u0338","nsube;":"\u2288","nsubset;":"\u2282\u20d2","nsubseteq;":"\u2288","nsubseteqq;":"\u2ac5\u0338","nsucc;":"\u2281","nsucceq;":"\u2ab0\u0338","nsup;":"\u2285","nsupE;":"\u2ac6\u0338","nsupe;":"\u2289","nsupset;":"\u2283\u20d2","nsupseteq;":"\u2289","nsupseteqq;":"\u2ac6\u0338","ntgl;":"\u2279","Ntilde;":"\u00d1",Ntilde:"\u00d1","ntilde;":"\u00f1",ntilde:"\u00f1","ntlg;":"\u2278","ntriangleleft;":"\u22ea","ntrianglelefteq;":"\u22ec","ntriangleright;":"\u22eb","ntrianglerighteq;":"\u22ed","Nu;":"\u039d","nu;":"\u03bd","num;":"#","numero;":"\u2116","numsp;":"\u2007","nvap;":"\u224d\u20d2","nvdash;":"\u22ac","nvDash;":"\u22ad","nVdash;":"\u22ae","nVDash;":"\u22af","nvge;":"\u2265\u20d2","nvgt;":">\u20d2","nvHarr;":"\u2904","nvinfin;":"\u29de","nvlArr;":"\u2902","nvle;":"\u2264\u20d2","nvlt;":"<\u20d2","nvltrie;":"\u22b4\u20d2","nvrArr;":"\u2903","nvrtrie;":"\u22b5\u20d2","nvsim;":"\u223c\u20d2","nwarhk;":"\u2923","nwarr;":"\u2196","nwArr;":"\u21d6","nwarrow;":"\u2196","nwnear;":"\u2927","Oacute;":"\u00d3",Oacute:"\u00d3","oacute;":"\u00f3",oacute:"\u00f3","oast;":"\u229b","Ocirc;":"\u00d4",Ocirc:"\u00d4","ocirc;":"\u00f4",ocirc:"\u00f4","ocir;":"\u229a","Ocy;":"\u041e","ocy;":"\u043e","odash;":"\u229d","Odblac;":"\u0150","odblac;":"\u0151","odiv;":"\u2a38","odot;":"\u2299","odsold;":"\u29bc","OElig;":"\u0152","oelig;":"\u0153","ofcir;":"\u29bf","Ofr;":"\ud835\udd12","ofr;":"\ud835\udd2c","ogon;":"\u02db","Ograve;":"\u00d2",Ograve:"\u00d2","ograve;":"\u00f2",ograve:"\u00f2","ogt;":"\u29c1","ohbar;":"\u29b5","ohm;":"\u03a9","oint;":"\u222e","olarr;":"\u21ba","olcir;":"\u29be","olcross;":"\u29bb","oline;":"\u203e","olt;":"\u29c0","Omacr;":"\u014c","omacr;":"\u014d","Omega;":"\u03a9","omega;":"\u03c9","Omicron;":"\u039f","omicron;":"\u03bf","omid;":"\u29b6","ominus;":"\u2296","Oopf;":"\ud835\udd46","oopf;":"\ud835\udd60","opar;":"\u29b7","OpenCurlyDoubleQuote;":"\u201c","OpenCurlyQuote;":"\u2018","operp;":"\u29b9","oplus;":"\u2295","orarr;":"\u21bb","Or;":"\u2a54","or;":"\u2228","ord;":"\u2a5d","order;":"\u2134","orderof;":"\u2134","ordf;":"\u00aa",ordf:"\u00aa","ordm;":"\u00ba",ordm:"\u00ba","origof;":"\u22b6","oror;":"\u2a56","orslope;":"\u2a57","orv;":"\u2a5b","oS;":"\u24c8","Oscr;":"\ud835\udcaa","oscr;":"\u2134","Oslash;":"\u00d8",Oslash:"\u00d8","oslash;":"\u00f8",oslash:"\u00f8","osol;":"\u2298","Otilde;":"\u00d5",Otilde:"\u00d5","otilde;":"\u00f5",otilde:"\u00f5","otimesas;":"\u2a36","Otimes;":"\u2a37","otimes;":"\u2297","Ouml;":"\u00d6",Ouml:"\u00d6","ouml;":"\u00f6",ouml:"\u00f6","ovbar;":"\u233d","OverBar;":"\u203e","OverBrace;":"\u23de","OverBracket;":"\u23b4","OverParenthesis;":"\u23dc","para;":"\u00b6",para:"\u00b6","parallel;":"\u2225","par;":"\u2225","parsim;":"\u2af3","parsl;":"\u2afd","part;":"\u2202","PartialD;":"\u2202","Pcy;":"\u041f","pcy;":"\u043f","percnt;":"%","period;":".","permil;":"\u2030","perp;":"\u22a5","pertenk;":"\u2031","Pfr;":"\ud835\udd13","pfr;":"\ud835\udd2d","Phi;":"\u03a6","phi;":"\u03c6","phiv;":"\u03d5","phmmat;":"\u2133","phone;":"\u260e","Pi;":"\u03a0","pi;":"\u03c0","pitchfork;":"\u22d4","piv;":"\u03d6","planck;":"\u210f","planckh;":"\u210e","plankv;":"\u210f","plusacir;":"\u2a23","plusb;":"\u229e","pluscir;":"\u2a22","plus;":"+","plusdo;":"\u2214","plusdu;":"\u2a25","pluse;":"\u2a72","PlusMinus;":"\u00b1","plusmn;":"\u00b1",plusmn:"\u00b1","plussim;":"\u2a26","plustwo;":"\u2a27","pm;":"\u00b1","Poincareplane;":"\u210c","pointint;":"\u2a15","popf;":"\ud835\udd61","Popf;":"\u2119","pound;":"\u00a3",pound:"\u00a3","prap;":"\u2ab7","Pr;":"\u2abb","pr;":"\u227a","prcue;":"\u227c","precapprox;":"\u2ab7","prec;":"\u227a","preccurlyeq;":"\u227c","Precedes;":"\u227a","PrecedesEqual;":"\u2aaf","PrecedesSlantEqual;":"\u227c","PrecedesTilde;":"\u227e","preceq;":"\u2aaf","precnapprox;":"\u2ab9","precneqq;":"\u2ab5","precnsim;":"\u22e8","pre;":"\u2aaf","prE;":"\u2ab3","precsim;":"\u227e","prime;":"\u2032","Prime;":"\u2033","primes;":"\u2119","prnap;":"\u2ab9","prnE;":"\u2ab5","prnsim;":"\u22e8","prod;":"\u220f","Product;":"\u220f","profalar;":"\u232e","profline;":"\u2312","profsurf;":"\u2313","prop;":"\u221d","Proportional;":"\u221d","Proportion;":"\u2237","propto;":"\u221d","prsim;":"\u227e","prurel;":"\u22b0","Pscr;":"\ud835\udcab","pscr;":"\ud835\udcc5","Psi;":"\u03a8","psi;":"\u03c8","puncsp;":"\u2008","Qfr;":"\ud835\udd14","qfr;":"\ud835\udd2e","qint;":"\u2a0c","qopf;":"\ud835\udd62","Qopf;":"\u211a","qprime;":"\u2057","Qscr;":"\ud835\udcac","qscr;":"\ud835\udcc6","quaternions;":"\u210d","quatint;":"\u2a16","quest;":"?","questeq;":"\u225f","quot;":'"',quot:'"',"QUOT;":'"',QUOT:'"',"rAarr;":"\u21db","race;":"\u223d\u0331","Racute;":"\u0154","racute;":"\u0155","radic;":"\u221a","raemptyv;":"\u29b3","rang;":"\u27e9","Rang;":"\u27eb","rangd;":"\u2992","range;":"\u29a5","rangle;":"\u27e9","raquo;":"\u00bb",raquo:"\u00bb","rarrap;":"\u2975","rarrb;":"\u21e5","rarrbfs;":"\u2920","rarrc;":"\u2933","rarr;":"\u2192","Rarr;":"\u21a0","rArr;":"\u21d2","rarrfs;":"\u291e","rarrhk;":"\u21aa","rarrlp;":"\u21ac","rarrpl;":"\u2945","rarrsim;":"\u2974","Rarrtl;":"\u2916","rarrtl;":"\u21a3","rarrw;":"\u219d","ratail;":"\u291a","rAtail;":"\u291c","ratio;":"\u2236","rationals;":"\u211a","rbarr;":"\u290d","rBarr;":"\u290f","RBarr;":"\u2910","rbbrk;":"\u2773","rbrace;":"}","rbrack;":"]","rbrke;":"\u298c","rbrksld;":"\u298e","rbrkslu;":"\u2990","Rcaron;":"\u0158","rcaron;":"\u0159","Rcedil;":"\u0156","rcedil;":"\u0157","rceil;":"\u2309","rcub;":"}","Rcy;":"\u0420","rcy;":"\u0440","rdca;":"\u2937","rdldhar;":"\u2969","rdquo;":"\u201d","rdquor;":"\u201d","rdsh;":"\u21b3","real;":"\u211c","realine;":"\u211b","realpart;":"\u211c","reals;":"\u211d","Re;":"\u211c","rect;":"\u25ad","reg;":"\u00ae",reg:"\u00ae","REG;":"\u00ae",REG:"\u00ae","ReverseElement;":"\u220b","ReverseEquilibrium;":"\u21cb","ReverseUpEquilibrium;":"\u296f","rfisht;":"\u297d","rfloor;":"\u230b","rfr;":"\ud835\udd2f","Rfr;":"\u211c","rHar;":"\u2964","rhard;":"\u21c1","rharu;":"\u21c0","rharul;":"\u296c","Rho;":"\u03a1","rho;":"\u03c1","rhov;":"\u03f1","RightAngleBracket;":"\u27e9","RightArrowBar;":"\u21e5","rightarrow;":"\u2192","RightArrow;":"\u2192","Rightarrow;":"\u21d2","RightArrowLeftArrow;":"\u21c4","rightarrowtail;":"\u21a3","RightCeiling;":"\u2309","RightDoubleBracket;":"\u27e7","RightDownTeeVector;":"\u295d","RightDownVectorBar;":"\u2955","RightDownVector;":"\u21c2","RightFloor;":"\u230b","rightharpoondown;":"\u21c1","rightharpoonup;":"\u21c0","rightleftarrows;":"\u21c4","rightleftharpoons;":"\u21cc","rightrightarrows;":"\u21c9","rightsquigarrow;":"\u219d","RightTeeArrow;":"\u21a6","RightTee;":"\u22a2","RightTeeVector;":"\u295b","rightthreetimes;":"\u22cc","RightTriangleBar;":"\u29d0","RightTriangle;":"\u22b3","RightTriangleEqual;":"\u22b5","RightUpDownVector;":"\u294f","RightUpTeeVector;":"\u295c","RightUpVectorBar;":"\u2954","RightUpVector;":"\u21be","RightVectorBar;":"\u2953","RightVector;":"\u21c0","ring;":"\u02da","risingdotseq;":"\u2253","rlarr;":"\u21c4","rlhar;":"\u21cc","rlm;":"\u200f","rmoustache;":"\u23b1","rmoust;":"\u23b1","rnmid;":"\u2aee","roang;":"\u27ed","roarr;":"\u21fe","robrk;":"\u27e7","ropar;":"\u2986","ropf;":"\ud835\udd63","Ropf;":"\u211d","roplus;":"\u2a2e","rotimes;":"\u2a35","RoundImplies;":"\u2970","rpar;":")","rpargt;":"\u2994","rppolint;":"\u2a12","rrarr;":"\u21c9","Rrightarrow;":"\u21db","rsaquo;":"\u203a","rscr;":"\ud835\udcc7","Rscr;":"\u211b","rsh;":"\u21b1","Rsh;":"\u21b1","rsqb;":"]","rsquo;":"\u2019","rsquor;":"\u2019","rthree;":"\u22cc","rtimes;":"\u22ca","rtri;":"\u25b9","rtrie;":"\u22b5","rtrif;":"\u25b8","rtriltri;":"\u29ce","RuleDelayed;":"\u29f4","ruluhar;":"\u2968","rx;":"\u211e","Sacute;":"\u015a","sacute;":"\u015b","sbquo;":"\u201a","scap;":"\u2ab8","Scaron;":"\u0160","scaron;":"\u0161","Sc;":"\u2abc","sc;":"\u227b","sccue;":"\u227d","sce;":"\u2ab0","scE;":"\u2ab4","Scedil;":"\u015e","scedil;":"\u015f","Scirc;":"\u015c","scirc;":"\u015d","scnap;":"\u2aba","scnE;":"\u2ab6","scnsim;":"\u22e9","scpolint;":"\u2a13","scsim;":"\u227f","Scy;":"\u0421","scy;":"\u0441","sdotb;":"\u22a1","sdot;":"\u22c5","sdote;":"\u2a66","searhk;":"\u2925","searr;":"\u2198","seArr;":"\u21d8","searrow;":"\u2198","sect;":"\u00a7",sect:"\u00a7","semi;":";","seswar;":"\u2929","setminus;":"\u2216","setmn;":"\u2216","sext;":"\u2736","Sfr;":"\ud835\udd16","sfr;":"\ud835\udd30","sfrown;":"\u2322","sharp;":"\u266f","SHCHcy;":"\u0429","shchcy;":"\u0449","SHcy;":"\u0428","shcy;":"\u0448","ShortDownArrow;":"\u2193","ShortLeftArrow;":"\u2190","shortmid;":"\u2223","shortparallel;":"\u2225","ShortRightArrow;":"\u2192","ShortUpArrow;":"\u2191","shy;":"\u00ad",shy:"\u00ad","Sigma;":"\u03a3","sigma;":"\u03c3","sigmaf;":"\u03c2","sigmav;":"\u03c2","sim;":"\u223c","simdot;":"\u2a6a","sime;":"\u2243","simeq;":"\u2243","simg;":"\u2a9e","simgE;":"\u2aa0","siml;":"\u2a9d","simlE;":"\u2a9f","simne;":"\u2246","simplus;":"\u2a24","simrarr;":"\u2972","slarr;":"\u2190","SmallCircle;":"\u2218","smallsetminus;":"\u2216","smashp;":"\u2a33","smeparsl;":"\u29e4","smid;":"\u2223","smile;":"\u2323","smt;":"\u2aaa","smte;":"\u2aac","smtes;":"\u2aac\ufe00","SOFTcy;":"\u042c","softcy;":"\u044c","solbar;":"\u233f","solb;":"\u29c4","sol;":"/","Sopf;":"\ud835\udd4a","sopf;":"\ud835\udd64","spades;":"\u2660","spadesuit;":"\u2660","spar;":"\u2225","sqcap;":"\u2293","sqcaps;":"\u2293\ufe00","sqcup;":"\u2294","sqcups;":"\u2294\ufe00","Sqrt;":"\u221a","sqsub;":"\u228f","sqsube;":"\u2291","sqsubset;":"\u228f","sqsubseteq;":"\u2291","sqsup;":"\u2290","sqsupe;":"\u2292","sqsupset;":"\u2290","sqsupseteq;":"\u2292","square;":"\u25a1","Square;":"\u25a1","SquareIntersection;":"\u2293","SquareSubset;":"\u228f","SquareSubsetEqual;":"\u2291","SquareSuperset;":"\u2290","SquareSupersetEqual;":"\u2292","SquareUnion;":"\u2294","squarf;":"\u25aa","squ;":"\u25a1","squf;":"\u25aa","srarr;":"\u2192","Sscr;":"\ud835\udcae","sscr;":"\ud835\udcc8","ssetmn;":"\u2216","ssmile;":"\u2323","sstarf;":"\u22c6","Star;":"\u22c6","star;":"\u2606","starf;":"\u2605","straightepsilon;":"\u03f5","straightphi;":"\u03d5","strns;":"\u00af","sub;":"\u2282","Sub;":"\u22d0","subdot;":"\u2abd","subE;":"\u2ac5","sube;":"\u2286","subedot;":"\u2ac3","submult;":"\u2ac1","subnE;":"\u2acb","subne;":"\u228a","subplus;":"\u2abf","subrarr;":"\u2979","subset;":"\u2282","Subset;":"\u22d0","subseteq;":"\u2286","subseteqq;":"\u2ac5","SubsetEqual;":"\u2286","subsetneq;":"\u228a","subsetneqq;":"\u2acb","subsim;":"\u2ac7","subsub;":"\u2ad5","subsup;":"\u2ad3","succapprox;":"\u2ab8","succ;":"\u227b","succcurlyeq;":"\u227d","Succeeds;":"\u227b","SucceedsEqual;":"\u2ab0","SucceedsSlantEqual;":"\u227d","SucceedsTilde;":"\u227f","succeq;":"\u2ab0","succnapprox;":"\u2aba","succneqq;":"\u2ab6","succnsim;":"\u22e9","succsim;":"\u227f","SuchThat;":"\u220b","sum;":"\u2211","Sum;":"\u2211","sung;":"\u266a","sup1;":"\u00b9",sup1:"\u00b9","sup2;":"\u00b2",sup2:"\u00b2","sup3;":"\u00b3",sup3:"\u00b3","sup;":"\u2283","Sup;":"\u22d1","supdot;":"\u2abe","supdsub;":"\u2ad8","supE;":"\u2ac6","supe;":"\u2287","supedot;":"\u2ac4","Superset;":"\u2283","SupersetEqual;":"\u2287","suphsol;":"\u27c9","suphsub;":"\u2ad7","suplarr;":"\u297b","supmult;":"\u2ac2","supnE;":"\u2acc","supne;":"\u228b","supplus;":"\u2ac0","supset;":"\u2283","Supset;":"\u22d1","supseteq;":"\u2287","supseteqq;":"\u2ac6","supsetneq;":"\u228b","supsetneqq;":"\u2acc","supsim;":"\u2ac8","supsub;":"\u2ad4","supsup;":"\u2ad6","swarhk;":"\u2926","swarr;":"\u2199","swArr;":"\u21d9","swarrow;":"\u2199","swnwar;":"\u292a","szlig;":"\u00df",szlig:"\u00df","Tab;":" ","target;":"\u2316","Tau;":"\u03a4","tau;":"\u03c4","tbrk;":"\u23b4","Tcaron;":"\u0164","tcaron;":"\u0165","Tcedil;":"\u0162","tcedil;":"\u0163","Tcy;":"\u0422","tcy;":"\u0442","tdot;":"\u20db","telrec;":"\u2315","Tfr;":"\ud835\udd17","tfr;":"\ud835\udd31","there4;":"\u2234","therefore;":"\u2234","Therefore;":"\u2234","Theta;":"\u0398","theta;":"\u03b8","thetasym;":"\u03d1","thetav;":"\u03d1","thickapprox;":"\u2248","thicksim;":"\u223c","ThickSpace;":"\u205f\u200a","ThinSpace;":"\u2009","thinsp;":"\u2009","thkap;":"\u2248","thksim;":"\u223c","THORN;":"\u00de",THORN:"\u00de","thorn;":"\u00fe",thorn:"\u00fe","tilde;":"\u02dc","Tilde;":"\u223c","TildeEqual;":"\u2243","TildeFullEqual;":"\u2245","TildeTilde;":"\u2248","timesbar;":"\u2a31","timesb;":"\u22a0","times;":"\u00d7",times:"\u00d7","timesd;":"\u2a30","tint;":"\u222d","toea;":"\u2928","topbot;":"\u2336","topcir;":"\u2af1","top;":"\u22a4","Topf;":"\ud835\udd4b","topf;":"\ud835\udd65","topfork;":"\u2ada","tosa;":"\u2929","tprime;":"\u2034","trade;":"\u2122","TRADE;":"\u2122","triangle;":"\u25b5","triangledown;":"\u25bf","triangleleft;":"\u25c3","trianglelefteq;":"\u22b4","triangleq;":"\u225c","triangleright;":"\u25b9","trianglerighteq;":"\u22b5","tridot;":"\u25ec","trie;":"\u225c","triminus;":"\u2a3a","TripleDot;":"\u20db","triplus;":"\u2a39","trisb;":"\u29cd","tritime;":"\u2a3b","trpezium;":"\u23e2","Tscr;":"\ud835\udcaf","tscr;":"\ud835\udcc9","TScy;":"\u0426","tscy;":"\u0446","TSHcy;":"\u040b","tshcy;":"\u045b","Tstrok;":"\u0166","tstrok;":"\u0167","twixt;":"\u226c","twoheadleftarrow;":"\u219e","twoheadrightarrow;":"\u21a0","Uacute;":"\u00da",Uacute:"\u00da","uacute;":"\u00fa",uacute:"\u00fa","uarr;":"\u2191","Uarr;":"\u219f","uArr;":"\u21d1","Uarrocir;":"\u2949","Ubrcy;":"\u040e","ubrcy;":"\u045e","Ubreve;":"\u016c","ubreve;":"\u016d","Ucirc;":"\u00db",Ucirc:"\u00db","ucirc;":"\u00fb",ucirc:"\u00fb","Ucy;":"\u0423","ucy;":"\u0443","udarr;":"\u21c5","Udblac;":"\u0170","udblac;":"\u0171","udhar;":"\u296e","ufisht;":"\u297e","Ufr;":"\ud835\udd18","ufr;":"\ud835\udd32","Ugrave;":"\u00d9",Ugrave:"\u00d9","ugrave;":"\u00f9",ugrave:"\u00f9","uHar;":"\u2963","uharl;":"\u21bf","uharr;":"\u21be","uhblk;":"\u2580","ulcorn;":"\u231c","ulcorner;":"\u231c","ulcrop;":"\u230f","ultri;":"\u25f8","Umacr;":"\u016a","umacr;":"\u016b","uml;":"\u00a8",uml:"\u00a8","UnderBar;":"_","UnderBrace;":"\u23df","UnderBracket;":"\u23b5","UnderParenthesis;":"\u23dd","Union;":"\u22c3","UnionPlus;":"\u228e","Uogon;":"\u0172","uogon;":"\u0173","Uopf;":"\ud835\udd4c","uopf;":"\ud835\udd66","UpArrowBar;":"\u2912","uparrow;":"\u2191","UpArrow;":"\u2191","Uparrow;":"\u21d1","UpArrowDownArrow;":"\u21c5","updownarrow;":"\u2195","UpDownArrow;":"\u2195","Updownarrow;":"\u21d5","UpEquilibrium;":"\u296e","upharpoonleft;":"\u21bf","upharpoonright;":"\u21be","uplus;":"\u228e","UpperLeftArrow;":"\u2196","UpperRightArrow;":"\u2197","upsi;":"\u03c5","Upsi;":"\u03d2","upsih;":"\u03d2","Upsilon;":"\u03a5","upsilon;":"\u03c5","UpTeeArrow;":"\u21a5","UpTee;":"\u22a5","upuparrows;":"\u21c8","urcorn;":"\u231d","urcorner;":"\u231d","urcrop;":"\u230e","Uring;":"\u016e","uring;":"\u016f","urtri;":"\u25f9","Uscr;":"\ud835\udcb0","uscr;":"\ud835\udcca","utdot;":"\u22f0","Utilde;":"\u0168","utilde;":"\u0169","utri;":"\u25b5","utrif;":"\u25b4","uuarr;":"\u21c8","Uuml;":"\u00dc",Uuml:"\u00dc","uuml;":"\u00fc",uuml:"\u00fc","uwangle;":"\u29a7","vangrt;":"\u299c","varepsilon;":"\u03f5","varkappa;":"\u03f0","varnothing;":"\u2205","varphi;":"\u03d5","varpi;":"\u03d6","varpropto;":"\u221d","varr;":"\u2195","vArr;":"\u21d5","varrho;":"\u03f1","varsigma;":"\u03c2","varsubsetneq;":"\u228a\ufe00","varsubsetneqq;":"\u2acb\ufe00","varsupsetneq;":"\u228b\ufe00","varsupsetneqq;":"\u2acc\ufe00","vartheta;":"\u03d1","vartriangleleft;":"\u22b2","vartriangleright;":"\u22b3","vBar;":"\u2ae8","Vbar;":"\u2aeb","vBarv;":"\u2ae9","Vcy;":"\u0412","vcy;":"\u0432","vdash;":"\u22a2","vDash;":"\u22a8","Vdash;":"\u22a9","VDash;":"\u22ab","Vdashl;":"\u2ae6","veebar;":"\u22bb","vee;":"\u2228","Vee;":"\u22c1","veeeq;":"\u225a","vellip;":"\u22ee","verbar;":"|","Verbar;":"\u2016","vert;":"|","Vert;":"\u2016","VerticalBar;":"\u2223","VerticalLine;":"|","VerticalSeparator;":"\u2758","VerticalTilde;":"\u2240","VeryThinSpace;":"\u200a","Vfr;":"\ud835\udd19","vfr;":"\ud835\udd33","vltri;":"\u22b2","vnsub;":"\u2282\u20d2","vnsup;":"\u2283\u20d2","Vopf;":"\ud835\udd4d","vopf;":"\ud835\udd67","vprop;":"\u221d","vrtri;":"\u22b3","Vscr;":"\ud835\udcb1","vscr;":"\ud835\udccb","vsubnE;":"\u2acb\ufe00","vsubne;":"\u228a\ufe00","vsupnE;":"\u2acc\ufe00","vsupne;":"\u228b\ufe00","Vvdash;":"\u22aa","vzigzag;":"\u299a","Wcirc;":"\u0174","wcirc;":"\u0175","wedbar;":"\u2a5f","wedge;":"\u2227","Wedge;":"\u22c0","wedgeq;":"\u2259","weierp;":"\u2118","Wfr;":"\ud835\udd1a","wfr;":"\ud835\udd34","Wopf;":"\ud835\udd4e","wopf;":"\ud835\udd68","wp;":"\u2118","wr;":"\u2240","wreath;":"\u2240","Wscr;":"\ud835\udcb2","wscr;":"\ud835\udccc","xcap;":"\u22c2","xcirc;":"\u25ef","xcup;":"\u22c3","xdtri;":"\u25bd","Xfr;":"\ud835\udd1b","xfr;":"\ud835\udd35","xharr;":"\u27f7","xhArr;":"\u27fa","Xi;":"\u039e","xi;":"\u03be","xlarr;":"\u27f5","xlArr;":"\u27f8","xmap;":"\u27fc","xnis;":"\u22fb","xodot;":"\u2a00","Xopf;":"\ud835\udd4f","xopf;":"\ud835\udd69","xoplus;":"\u2a01","xotime;":"\u2a02","xrarr;":"\u27f6","xrArr;":"\u27f9","Xscr;":"\ud835\udcb3","xscr;":"\ud835\udccd","xsqcup;":"\u2a06","xuplus;":"\u2a04","xutri;":"\u25b3","xvee;":"\u22c1","xwedge;":"\u22c0","Yacute;":"\u00dd",Yacute:"\u00dd","yacute;":"\u00fd",yacute:"\u00fd","YAcy;":"\u042f","yacy;":"\u044f","Ycirc;":"\u0176","ycirc;":"\u0177","Ycy;":"\u042b","ycy;":"\u044b","yen;":"\u00a5",yen:"\u00a5","Yfr;":"\ud835\udd1c","yfr;":"\ud835\udd36","YIcy;":"\u0407","yicy;":"\u0457","Yopf;":"\ud835\udd50","yopf;":"\ud835\udd6a","Yscr;":"\ud835\udcb4","yscr;":"\ud835\udcce","YUcy;":"\u042e","yucy;":"\u044e","yuml;":"\u00ff",yuml:"\u00ff","Yuml;":"\u0178","Zacute;":"\u0179","zacute;":"\u017a","Zcaron;":"\u017d","zcaron;":"\u017e","Zcy;":"\u0417","zcy;":"\u0437","Zdot;":"\u017b","zdot;":"\u017c","zeetrf;":"\u2128","ZeroWidthSpace;":"\u200b","Zeta;":"\u0396","zeta;":"\u03b6","zfr;":"\ud835\udd37","Zfr;":"\u2128","ZHcy;":"\u0416","zhcy;":"\u0436","zigrarr;":"\u21dd","zopf;":"\ud835\udd6b","Zopf;":"\u2124","Zscr;":"\ud835\udcb5","zscr;":"\ud835\udccf","zwj;":"\u200d","zwnj;":"\u200c"}},{}],13:[function(e,t,n){function u(e,t){return r.isUndefined(t)?""+t:r.isNumber(t)&&(isNaN(t)||!isFinite(t))?t.toString():r.isFunction(t)||r.isRegExp(t)?t.toString():t}function a(e,t){return r.isString(e)?e.length=0;u--)if(n[u]!=s[u])return!1;for(u=n.length-1;u>=0;u--){o=n[u];if(!h(e[o],t[o]))return!1}return!0}function v(e,t){return!e||!t?!1:Object.prototype.toString.call(t)=="[object RegExp]"?t.test(e):e instanceof t?!0:t.call({},e)===!0?!0:!1}function m(e,t,n,i){var s;r.isString(n)&&(i=n,n=null);try{t()}catch(o){s=o}i=(n&&n.name?" ("+n.name+").":".")+(i?" "+i:"."),e&&!s&&l(s,n,"Missing expected exception"+i),!e&&v(s,n)&&l(s,n,"Got unwanted exception"+i);if(e&&s&&n&&!v(s,n)||!e&&s)throw s}var r=e("util/"),i=Array.prototype.slice,s=Object.prototype.hasOwnProperty,o=t.exports=c;o.AssertionError=function(t){this.name="AssertionError",this.actual=t.actual,this.expected=t.expected,this.operator=t.operator,t.message?(this.message=t.message,this.generatedMessage=!1):(this.message=f(this),this.generatedMessage=!0);var n=t.stackStartFunction||l;if(Error.captureStackTrace)Error.captureStackTrace(this,n);else{var r=new Error;if(r.stack){var i=r.stack,s=n.name,o=i.indexOf("\n"+s);if(o>=0){var u=i.indexOf("\n",o+1);i=i.substring(u+1)}this.stack=i}}},r.inherits(o.AssertionError,Error),o.fail=l,o.ok=c,o.equal=function(t,n,r){t!=n&&l(t,n,r,"==",o.equal)},o.notEqual=function(t,n,r){t==n&&l(t,n,r,"!=",o.notEqual)},o.deepEqual=function(t,n,r){h(t,n)||l(t,n,r,"deepEqual",o.deepEqual)},o.notDeepEqual=function(t,n,r){h(t,n)&&l(t,n,r,"notDeepEqual",o.notDeepEqual)},o.strictEqual=function(t,n,r){t!==n&&l(t,n,r,"===",o.strictEqual)},o.notStrictEqual=function(t,n,r){t===n&&l(t,n,r,"!==",o.notStrictEqual)},o.throws=function(e,t,n){m.apply(this,[!0].concat(i.call(arguments)))},o.doesNotThrow=function(e,t){m.apply(this,[!1].concat(i.call(arguments)))},o.ifError=function(e){if(e)throw e};var g=Object.keys||function(e){var t=[];for(var n in e)s.call(e,n)&&t.push(n);return t}},{"util/":15}],14:[function(e,t,n){t.exports=function(t){return t&&typeof t=="object"&&typeof t.copy=="function"&&typeof t.fill=="function"&&typeof t.readUInt8=="function"}},{}],15:[function(e,t,n){(function(t,r){function u(e,t){var r={seen:[],stylize:f};return arguments.length>=3&&(r.depth=arguments[2]),arguments.length>=4&&(r.colors=arguments[3]),y(t)?r.showHidden=t:t&&n._extend(r,t),T(r.showHidden)&&(r.showHidden=!1),T(r.depth)&&(r.depth=2),T(r.colors)&&(r.colors=!1),T(r.customInspect)&&(r.customInspect=!0),r.colors&&(r.stylize=a),c(r,e,r.depth)}function a(e,t){var n=u.styles[t];return n?"["+u.colors[n][0]+"m"+e+"["+u.colors[n][1]+"m":e}function f(e,t){return e}function l(e){var t={};return e.forEach(function(e,n){t[e]=!0}),t}function c(e,t,r){if(e.customInspect&&t&&A(t.inspect)&&t.inspect!==n.inspect&&(!t.constructor||t.constructor.prototype!==t)){var i=t.inspect(r,e);return S(i)||(i=c(e,i,r)),i}var s=h(e,t);if(s)return s;var o=Object.keys(t),u=l(o);e.showHidden&&(o=Object.getOwnPropertyNames(t));if(L(t)&&(o.indexOf("message")>=0||o.indexOf("description")>=0))return p(t);if(o.length===0){if(A(t)){var a=t.name?": "+t.name:"";return e.stylize("[Function"+a+"]","special")}if(N(t))return e.stylize(RegExp.prototype.toString.call(t),"regexp");if(k(t))return e.stylize(Date.prototype.toString.call(t),"date");if(L(t))return p(t)}var f="",y=!1,b=["{","}"];g(t)&&(y=!0,b=["[","]"]);if(A(t)){var w=t.name?": "+t.name:"";f=" [Function"+w+"]"}N(t)&&(f=" "+RegExp.prototype.toString.call(t)),k(t)&&(f=" "+Date.prototype.toUTCString.call(t)),L(t)&&(f=" "+p(t));if(o.length!==0||!!y&&t.length!=0){if(r<0)return N(t)?e.stylize(RegExp.prototype.toString.call(t),"regexp"):e.stylize("[Object]","special");e.seen.push(t);var E;return y?E=d(e,t,r,u,o):E=o.map(function(n){return v(e,t,r,u,n,y)}),e.seen.pop(),m(E,f,b)}return b[0]+f+b[1]}function h(e,t){if(T(t))return e.stylize("undefined","undefined");if(S(t)){var n="'"+JSON.stringify(t).replace(/^"|"$/g,"").replace(/'/g,"\\'").replace(/\\"/g,'"')+"'";return e.stylize(n,"string")}if(E(t))return e.stylize(""+t,"number");if(y(t))return e.stylize(""+t,"boolean");if(b(t))return e.stylize("null","null")}function p(e){return"["+Error.prototype.toString.call(e)+"]"}function d(e,t,n,r,i){var s=[];for(var o=0,u=t.length;o-1&&(s?u=u.split("\n").map(function(e){return" "+e}).join("\n").substr(2):u="\n"+u.split("\n").map(function(e){return" "+e}).join("\n"))):u=e.stylize("[Circular]","special"));if(T(o)){if(s&&i.match(/^\d+$/))return u;o=JSON.stringify(""+i),o.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)?(o=o.substr(1,o.length-2),o=e.stylize(o,"name")):(o=o.replace(/'/g,"\\'").replace(/\\"/g,'"').replace(/(^"|"$)/g,"'"),o=e.stylize(o,"string"))}return o+": "+u}function m(e,t,n){var r=0,i=e.reduce(function(e,t){return r++,t.indexOf("\n")>=0&&r++,e+t.replace(/\u001b\[\d\d?m/g,"").length+1},0);return i>60?n[0]+(t===""?"":t+"\n ")+" "+e.join(",\n ")+" "+n[1]:n[0]+t+" "+e.join(", ")+" "+n[1]}function g(e){return Array.isArray(e)}function y(e){return typeof e=="boolean"}function b(e){return e===null}function w(e){return e==null}function E(e){return typeof e=="number"}function S(e){return typeof e=="string"}function x(e){return typeof e=="symbol"}function T(e){return e===void 0}function N(e){return C(e)&&M(e)==="[object RegExp]"}function C(e){return typeof e=="object"&&e!==null}function k(e){return C(e)&&M(e)==="[object Date]"}function L(e){return C(e)&&(M(e)==="[object Error]"||e instanceof Error)}function A(e){return typeof e=="function"}function O(e){return e===null||typeof e=="boolean"||typeof e=="number"||typeof e=="string"||typeof e=="symbol"||typeof e=="undefined"}function M(e){return Object.prototype.toString.call(e)}function _(e){return e<10?"0"+e.toString(10):e.toString(10)}function P(){var e=new Date,t=[_(e.getHours()),_(e.getMinutes()),_(e.getSeconds())].join(":");return[e.getDate(),D[e.getMonth()],t].join(" ")}function H(e,t){return Object.prototype.hasOwnProperty.call(e,t)}var i=/%[sdj%]/g;n.format=function(e){if(!S(e)){var t=[];for(var n=0;n=s)return e;switch(e){case"%s":return String(r[n++]);case"%d":return Number(r[n++]);case"%j":try{return JSON.stringify(r[n++])}catch(t){return"[Circular]"};default:return e}});for(var a=r[n];n0&&this._events[e].length>n&&(this._events[e].warned=!0,console.error("(node) warning: possible EventEmitter memory leak detected. %d listeners added. Use emitter.setMaxListeners() to increase limit.",this._events[e].length),console.trace())}return this},r.prototype.on=r.prototype.addListener,r.prototype.once=function(e,t){function r(){this.removeListener(e,r),n||(n=!0,t.apply(this,arguments))}if(!i(t))throw TypeError("listener must be a function");var n=!1;return r.listener=t,this.on(e,r),this},r.prototype.removeListener=function(e,t){var n,r,s,u;if(!i(t))throw TypeError("listener must be a function");if(!this._events||!this._events[e])return this;n=this._events[e],s=n.length,r=-1;if(n===t||i(n.listener)&&n.listener===t)delete this._events[e],this._events.removeListener&&this.emit("removeListener",e,t);else if(o(n)){for(u=s;u-->0;)if(n[u]===t||n[u].listener&&n[u].listener===t){r=u;break}if(r<0)return this;n.length===1?(n.length=0,delete this._events[e]):n.splice(r,1),this._events.removeListener&&this.emit("removeListener",e,t)}return this},r.prototype.removeAllListeners=function(e){var t,n;if(!this._events)return this;if(!this._events.removeListener)return arguments.length===0?this._events={}:this._events[e]&&delete this._events[e],this;if(arguments.length===0){for(t in this._events){if(t==="removeListener")continue;this.removeAllListeners(t)}return this.removeAllListeners("removeListener"),this._events={},this}n=this._events[e];if(i(n))this.removeListener(e,n);else while(n.length)this.removeListener(e,n[n.length-1]);return delete this._events[e],this},r.prototype.listeners=function(e){var t;return!this._events||!this._events[e]?t=[]:i(this._events[e])?t=[this._events[e]]:t=this._events[e].slice(),t},r.listenerCount=function(e,t){var n;return!e._events||!e._events[t]?n=0:i(e._events[t])?n=1:n=e._events[t].length,n}},{}],17:[function(e,t,n){typeof Object.create=="function"?t.exports=function(t,n){t.super_=n,t.prototype=Object.create(n.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}})}:t.exports=function(t,n){t.super_=n;var r=function(){};r.prototype=n.prototype,t.prototype=new r,t.prototype.constructor=t}},{}],18:[function(e,t,n){function i(){}var r=t.exports={};r.nextTick=function(){var e=typeof window!="undefined"&&window.setImmediate,t=typeof window!="undefined"&&window.postMessage&&window.addEventListener;if(e)return function(e){return window.setImmediate(e)};if(t){var n=[];return window.addEventListener("message",function(e){var t=e.source;if((t===window||t===null)&&e.data==="process-tick"){e.stopPropagation();if(n.length>0){var r=n.shift();r()}}},!0),function(t){n.push(t),window.postMessage("process-tick","*")}}return function(t){setTimeout(t,0)}}(),r.title="browser",r.browser=!0,r.env={},r.argv=[],r.on=i,r.once=i,r.off=i,r.emit=i,r.binding=function(e){throw new Error("process.binding is not supported")},r.cwd=function(){return"/"},r.chdir=function(e){throw new Error("process.chdir is not supported")}},{}],19:[function(e,t,n){t.exports=e(14)},{}],20:[function(e,t,n){t.exports=e(15)},{"./support/isBuffer":19,"/usr/local/lib/node_modules/browserify/node_modules/insert-module-globals/node_modules/process/browser.js":18,inherits:17}]},{},[9])(9)}),define("ace/mode/html_worker",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/worker/mirror","ace/mode/html/saxparser"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("../worker/mirror").Mirror,o=e("./html/saxparser").SAXParser,u={"expected-doctype-but-got-start-tag":"info","expected-doctype-but-got-chars":"info","non-html-root":"info"},a=t.Worker=function(e){s.call(this,e),this.setTimeout(400),this.context=null};r.inherits(a,s),function(){this.setOptions=function(e){this.context=e.context},this.onUpdate=function(){var e=this.doc.getValue();if(!e)return;var t=new o,n=[],r=function(){};t.contentHandler={startDocument:r,endDocument:r,startElement:r,endElement:r,characters:r},t.errorHandler={error:function(e,t,r){n.push({row:t.line,column:t.column,text:e,type:u[r]||"error"})}},this.context?t.parseFragment(e,this.context):t.parse(e),this.sender.emit("error",n)}}.call(a.prototype)}),define("ace/lib/es5-shim",["require","exports","module"],function(e,t,n){function r(){}function w(e){try{return Object.defineProperty(e,"sentinel",{}),"sentinel"in e}catch(t){}}function H(e){return e=+e,e!==e?e=0:e!==0&&e!==1/0&&e!==-1/0&&(e=(e>0||-1)*Math.floor(Math.abs(e))),e}function B(e){var t=typeof e;return e===null||t==="undefined"||t==="boolean"||t==="number"||t==="string"}function j(e){var t,n,r;if(B(e))return e;n=e.valueOf;if(typeof n=="function"){t=n.call(e);if(B(t))return t}r=e.toString;if(typeof r=="function"){t=r.call(e);if(B(t))return t}throw new TypeError}Function.prototype.bind||(Function.prototype.bind=function(t){var n=this;if(typeof n!="function")throw new TypeError("Function.prototype.bind called on incompatible "+n);var i=u.call(arguments,1),s=function(){if(this instanceof s){var e=n.apply(this,i.concat(u.call(arguments)));return Object(e)===e?e:this}return n.apply(t,i.concat(u.call(arguments)))};return n.prototype&&(r.prototype=n.prototype,s.prototype=new r,r.prototype=null),s});var i=Function.prototype.call,s=Array.prototype,o=Object.prototype,u=s.slice,a=i.bind(o.toString),f=i.bind(o.hasOwnProperty),l,c,h,p,d;if(d=f(o,"__defineGetter__"))l=i.bind(o.__defineGetter__),c=i.bind(o.__defineSetter__),h=i.bind(o.__lookupGetter__),p=i.bind(o.__lookupSetter__);if([1,2].splice(0).length!=2)if(!function(){function e(e){var t=new Array(e+2);return t[0]=t[1]=0,t}var t=[],n;t.splice.apply(t,e(20)),t.splice.apply(t,e(26)),n=t.length,t.splice(5,0,"XXX"),n+1==t.length;if(n+1==t.length)return!0}())Array.prototype.splice=function(e,t){var n=this.length;e>0?e>n&&(e=n):e==void 0?e=0:e<0&&(e=Math.max(n+e,0)),e+ta)for(h=l;h--;)this[f+h]=this[a+h];if(s&&e===c)this.length=c,this.push.apply(this,i);else{this.length=c+s;for(h=0;h>>0;if(a(t)!="[object Function]")throw new TypeError;while(++s>>0,s=Array(i),o=arguments[1];if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");for(var u=0;u>>0,s=[],o,u=arguments[1];if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");for(var f=0;f>>0,s=arguments[1];if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");for(var o=0;o>>0,s=arguments[1];if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");for(var o=0;o>>0;if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");if(!i&&arguments.length==1)throw new TypeError("reduce of empty array with no initial value");var s=0,o;if(arguments.length>=2)o=arguments[1];else do{if(s in r){o=r[s++];break}if(++s>=i)throw new TypeError("reduce of empty array with no initial value")}while(!0);for(;s>>0;if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");if(!i&&arguments.length==1)throw new TypeError("reduceRight of empty array with no initial value");var s,o=i-1;if(arguments.length>=2)s=arguments[1];else do{if(o in r){s=r[o--];break}if(--o<0)throw new TypeError("reduceRight of empty array with no initial value")}while(!0);do o in this&&(s=t.call(void 0,s,r[o],o,n));while(o--);return s});if(!Array.prototype.indexOf||[0,1].indexOf(1,2)!=-1)Array.prototype.indexOf=function(t){var n=g&&a(this)=="[object String]"?this.split(""):F(this),r=n.length>>>0;if(!r)return-1;var i=0;arguments.length>1&&(i=H(arguments[1])),i=i>=0?i:Math.max(0,r+i);for(;i>>0;if(!r)return-1;var i=r-1;arguments.length>1&&(i=Math.min(i,H(arguments[1]))),i=i>=0?i:r-Math.abs(i);for(;i>=0;i--)if(i in n&&t===n[i])return i;return-1};Object.getPrototypeOf||(Object.getPrototypeOf=function(t){return t.__proto__||(t.constructor?t.constructor.prototype:o)});if(!Object.getOwnPropertyDescriptor){var y="Object.getOwnPropertyDescriptor called on a non-object: ";Object.getOwnPropertyDescriptor=function(t,n){if(typeof t!="object"&&typeof t!="function"||t===null)throw new TypeError(y+t);if(!f(t,n))return;var r,i,s;r={enumerable:!0,configurable:!0};if(d){var u=t.__proto__;t.__proto__=o;var i=h(t,n),s=p(t,n);t.__proto__=u;if(i||s)return i&&(r.get=i),s&&(r.set=s),r}return r.value=t[n],r}}Object.getOwnPropertyNames||(Object.getOwnPropertyNames=function(t){return Object.keys(t)});if(!Object.create){var b;Object.prototype.__proto__===null?b=function(){return{__proto__:null}}:b=function(){var e={};for(var t in e)e[t]=null;return e.constructor=e.hasOwnProperty=e.propertyIsEnumerable=e.isPrototypeOf=e.toLocaleString=e.toString=e.valueOf=e.__proto__=null,e},Object.create=function(t,n){var r;if(t===null)r=b();else{if(typeof t!="object")throw new TypeError("typeof prototype["+typeof t+"] != 'object'");var i=function(){};i.prototype=t,r=new i,r.__proto__=t}return n!==void 0&&Object.defineProperties(r,n),r}}if(Object.defineProperty){var E=w({}),S=typeof document=="undefined"||w(document.createElement("div"));if(!E||!S)var x=Object.defineProperty}if(!Object.defineProperty||x){var T="Property description must be an object: ",N="Object.defineProperty called on non-object: ",C="getters & setters can not be defined on this javascript engine";Object.defineProperty=function(t,n,r){if(typeof t!="object"&&typeof t!="function"||t===null)throw new TypeError(N+t);if(typeof r!="object"&&typeof r!="function"||r===null)throw new TypeError(T+r);if(x)try{return x.call(Object,t,n,r)}catch(i){}if(f(r,"value"))if(d&&(h(t,n)||p(t,n))){var s=t.__proto__;t.__proto__=o,delete t[n],t[n]=r.value,t.__proto__=s}else t[n]=r.value;else{if(!d)throw new TypeError(C);f(r,"get")&&l(t,n,r.get),f(r,"set")&&c(t,n,r.set)}return t}}Object.defineProperties||(Object.defineProperties=function(t,n){for(var r in n)f(n,r)&&Object.defineProperty(t,r,n[r]);return t}),Object.seal||(Object.seal=function(t){return t}),Object.freeze||(Object.freeze=function(t){return t});try{Object.freeze(function(){})}catch(k){Object.freeze=function(t){return function(n){return typeof n=="function"?n:t(n)}}(Object.freeze)}Object.preventExtensions||(Object.preventExtensions=function(t){return t}),Object.isSealed||(Object.isSealed=function(t){return!1}),Object.isFrozen||(Object.isFrozen=function(t){return!1}),Object.isExtensible||(Object.isExtensible=function(t){if(Object(t)===t)throw new TypeError;var n="";while(f(t,n))n+="?";t[n]=!0;var r=f(t,n);return delete t[n],r});if(!Object.keys){var L=!0,A=["toString","toLocaleString","valueOf","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","constructor"],O=A.length;for(var M in{toString:null})L=!1;Object.keys=function I(e){if(typeof e!="object"&&typeof e!="function"||e===null)throw new TypeError("Object.keys called on a non-object");var I=[];for(var t in e)f(e,t)&&I.push(t);if(L)for(var n=0,r=O;n_addClient(this); _server->_handleEvent(this, WS_EVT_CONNECT, request, NULL, 0); delete request; + memset(&_pinfo,0,sizeof(_pinfo)); // } AsyncWebSocketClient::~AsyncWebSocketClient(){ diff --git a/src/SPIFFSEditor.cpp b/src/SPIFFSEditor.cpp index a84fa87dd..169d70f54 100644 --- a/src/SPIFFSEditor.cpp +++ b/src/SPIFFSEditor.cpp @@ -2,268 +2,269 @@ #include //File: edit.htm.gz, Size: 4151 -#define edit_htm_gz_len 4151 +#define edit_htm_gz_len 4169 const uint8_t edit_htm_gz[] PROGMEM = { - 0x1F, 0x8B, 0x08, 0x08, 0xB8, 0x94, 0xB1, 0x59, 0x00, 0x03, 0x65, 0x64, 0x69, 0x74, 0x2E, 0x68, - 0x74, 0x6D, 0x00, 0xB5, 0x3A, 0x0B, 0x7B, 0xDA, 0xB8, 0xB2, 0x7F, 0xC5, 0x71, 0xCF, 0x66, 0xED, - 0x83, 0x31, 0x90, 0xA4, 0xD9, 0xD6, 0xC4, 0xC9, 0x42, 0x92, 0x36, 0x6D, 0xF3, 0x6A, 0x80, 0xB6, - 0x69, 0x4F, 0xEE, 0x7E, 0xC2, 0x16, 0xA0, 0xC6, 0x96, 0x5D, 0x5B, 0x0E, 0x49, 0x59, 0xFE, 0xFB, - 0x9D, 0x91, 0x6C, 0xB0, 0x09, 0x69, 0x77, 0xCF, 0xBD, 0xBB, 0xDD, 0x2D, 0x92, 0x46, 0x33, 0x9A, - 0x19, 0xCD, 0x53, 0xDE, 0xBD, 0x8D, 0xA3, 0x8B, 0xC3, 0xFE, 0xF5, 0xE5, 0xB1, 0x36, 0x11, 0x61, - 0xB0, 0xBF, 0x87, 0x7F, 0x6B, 0x01, 0xE1, 0x63, 0x97, 0xF2, 0xFD, 0x3D, 0xC1, 0x44, 0x40, 0xF7, - 0x8F, 0x7B, 0x97, 0xDA, 0xB1, 0xCF, 0x44, 0x94, 0xEC, 0x35, 0xD4, 0xCA, 0x5E, 0x2A, 0x1E, 0x02, - 0xAA, 0x85, 0xD4, 0x67, 0xC4, 0x4D, 0xBD, 0x84, 0xC2, 0x66, 0xDB, 0x0B, 0x67, 0xDF, 0xEB, 0x8C, - 0xFB, 0xF4, 0xDE, 0xD9, 0x6E, 0x36, 0xDB, 0x71, 0x94, 0x32, 0xC1, 0x22, 0xEE, 0x90, 0x61, 0x1A, - 0x05, 0x99, 0xA0, 0xED, 0x80, 0x8E, 0x84, 0xF3, 0x3C, 0xBE, 0x6F, 0x0F, 0xA3, 0xC4, 0xA7, 0x89, - 0xD3, 0x8A, 0xEF, 0x35, 0x00, 0x31, 0x5F, 0x7B, 0xB6, 0xB3, 0xB3, 0xD3, 0x1E, 0x12, 0xEF, 0x76, - 0x9C, 0x44, 0x19, 0xF7, 0xEB, 0x5E, 0x14, 0x44, 0x89, 0xF3, 0x6C, 0xF4, 0x1C, 0xFF, 0xB4, 0x7D, - 0x96, 0xC6, 0x01, 0x79, 0x70, 0x78, 0xC4, 0x29, 0xE0, 0xDE, 0xD7, 0xD3, 0x09, 0xF1, 0xA3, 0xA9, - 0xD3, 0xD4, 0x9A, 0x5A, 0xAB, 0x09, 0x44, 0x92, 0xF1, 0x90, 0x18, 0x4D, 0x0B, 0xFF, 0xD8, 0x3B, - 0x66, 0x7B, 0x14, 0x71, 0x51, 0x4F, 0xD9, 0x77, 0xEA, 0xB4, 0xB6, 0xE0, 0x34, 0x39, 0x1D, 0x91, - 0x90, 0x05, 0x0F, 0x4E, 0x4A, 0x78, 0x5A, 0x4F, 0x69, 0xC2, 0x46, 0x6A, 0x79, 0x4A, 0xD9, 0x78, - 0x22, 0x9C, 0xDF, 0x9A, 0xCD, 0x39, 0xF0, 0xAF, 0x65, 0xC1, 0x2C, 0x60, 0x29, 0x20, 0xA3, 0x78, - 0xEA, 0x3C, 0x11, 0xC5, 0x4E, 0x53, 0xB1, 0xDE, 0x6C, 0x87, 0x24, 0x19, 0x33, 0x0E, 0x83, 0x98, - 0xF8, 0x3E, 0xE3, 0x63, 0x47, 0xA1, 0x05, 0x6C, 0xB6, 0x90, 0x36, 0xA1, 0x01, 0x11, 0xEC, 0x8E, - 0xB6, 0x43, 0xC6, 0xEB, 0x53, 0xE6, 0x8B, 0x89, 0xB3, 0x0B, 0x3C, 0xB6, 0xBD, 0x2C, 0x49, 0x41, - 0xA6, 0x38, 0x62, 0x5C, 0xD0, 0x44, 0xA2, 0xA5, 0x31, 0xE1, 0xB3, 0x5C, 0x54, 0x54, 0x40, 0x21, - 0x27, 0xE3, 0x01, 0xE3, 0xB4, 0x3E, 0x0C, 0x22, 0xEF, 0x76, 0x71, 0xD2, 0x6E, 0x7C, 0x9F, 0x9F, - 0xE5, 0x4C, 0xA2, 0x3B, 0x9A, 0xCC, 0x96, 0xEA, 0x92, 0xD8, 0x15, 0x60, 0x85, 0x34, 0xA5, 0x74, - 0x6E, 0x8B, 0xBB, 0x0C, 0xA0, 0x96, 0xFC, 0x05, 0x29, 0x17, 0xFC, 0x2F, 0x45, 0x5A, 0x11, 0x5C, - 0xA1, 0x30, 0x1E, 0x67, 0x62, 0xF6, 0xF8, 0x2A, 0xA3, 0x98, 0x78, 0x4C, 0x3C, 0xA0, 0xFC, 0xB0, - 0x6D, 0x86, 0xBA, 0x04, 0xAC, 0x24, 0x24, 0x81, 0x86, 0x3A, 0xD7, 0x3E, 0xD0, 0xC4, 0x27, 0x9C, - 0x58, 0x9D, 0x84, 0x91, 0xC0, 0xEA, 0x2D, 0xB5, 0x5E, 0x0F, 0xA3, 0xEF, 0xF5, 0x0C, 0xC6, 0x30, - 0x0F, 0xA8, 0x27, 0x94, 0x92, 0xE1, 0x1E, 0x86, 0xB7, 0x4C, 0x3C, 0x06, 0x3C, 0x5A, 0x28, 0xA9, - 0x4B, 0x2A, 0x69, 0xA2, 0x2E, 0xB0, 0x25, 0xD5, 0x83, 0x1C, 0x4B, 0xC9, 0x95, 0x50, 0xF5, 0x61, - 0x24, 0x44, 0x14, 0x4A, 0x93, 0x5B, 0x08, 0xAC, 0x49, 0xAB, 0x79, 0xF1, 0xE8, 0x46, 0xD6, 0x6B, - 0xBF, 0x44, 0xBE, 0x0D, 0x7A, 0x15, 0xCC, 0x23, 0x41, 0x9D, 0x04, 0x6C, 0xCC, 0x9D, 0x90, 0xF9, - 0x7E, 0x40, 0x4B, 0x56, 0xEB, 0x64, 0x49, 0x60, 0xF8, 0x44, 0x10, 0x87, 0x85, 0x64, 0x4C, 0x1B, - 0x31, 0x1F, 0x03, 0x34, 0xA5, 0xBB, 0x3B, 0x16, 0xFB, 0xD0, 0xBD, 0xB8, 0x9A, 0x36, 0xDF, 0xBD, - 0x1E, 0x47, 0x1D, 0xF8, 0xE7, 0xBC, 0x37, 0x98, 0x1C, 0x0F, 0xC6, 0x30, 0xEA, 0xE2, 0xB4, 0xF3, - 0xFE, 0xB0, 0xF3, 0x1E, 0x7E, 0x0E, 0x5B, 0xB5, 0xAF, 0xA3, 0x6F, 0xB8, 0xD0, 0x7D, 0xED, 0x77, - 0xFB, 0x83, 0xE3, 0x4E, 0xE7, 0x5D, 0xE3, 0xCD, 0xF9, 0xF4, 0xE3, 0xBB, 0x5D, 0x04, 0x77, 0x83, - 0xE6, 0xD5, 0x87, 0x49, 0x73, 0xB0, 0xF5, 0x32, 0xF4, 0x4F, 0xFC, 0x89, 0x17, 0x0E, 0x3A, 0xEF, - 0x3F, 0x5E, 0xDD, 0x5D, 0x87, 0x83, 0x71, 0xEF, 0x63, 0x6B, 0xF2, 0x79, 0xEB, 0x43, 0xEF, 0xF3, - 0xC7, 0x57, 0xB7, 0xF4, 0xD3, 0xC9, 0xDB, 0xCF, 0xFD, 0x29, 0x20, 0x1C, 0x45, 0xBD, 0xC1, 0x55, - 0xF7, 0x43, 0x77, 0xFC, 0xB9, 0xEB, 0x1D, 0xDF, 0x0F, 0x83, 0xF3, 0xEE, 0xEB, 0xCE, 0xB0, 0xB3, - 0xE5, 0x51, 0x3A, 0xEE, 0x5F, 0x75, 0xB3, 0x37, 0xEF, 0x2E, 0xC6, 0x8C, 0x4D, 0x7A, 0x9F, 0xCF, - 0xFB, 0xDE, 0xE1, 0xF3, 0xD3, 0xC1, 0x49, 0x87, 0x4D, 0xCE, 0xDF, 0x5E, 0x35, 0x6F, 0x5F, 0xBF, - 0x3B, 0x3C, 0xF2, 0xAE, 0xDF, 0x5E, 0xEF, 0x1E, 0x6D, 0x37, 0x7E, 0xFB, 0xED, 0xCC, 0xBF, 0x60, - 0xBC, 0x7F, 0xF7, 0xBD, 0x33, 0x3E, 0x9C, 0xBE, 0x78, 0x48, 0xFB, 0x93, 0x37, 0x77, 0xBC, 0xF1, - 0x21, 0xFA, 0xFA, 0xE6, 0xE1, 0x0C, 0xFE, 0xBB, 0xBC, 0xAC, 0x0D, 0x7B, 0xAD, 0x74, 0xF0, 0xFE, - 0xCD, 0x87, 0xAD, 0xF4, 0xE5, 0xF3, 0xB8, 0x7B, 0x74, 0x74, 0x17, 0x0E, 0x2F, 0x1B, 0xA1, 0x7F, - 0x3B, 0x12, 0x2F, 0xB6, 0x45, 0x7C, 0x3D, 0xCE, 0x3E, 0x7F, 0x7B, 0xFE, 0x76, 0xD2, 0xB8, 0xA0, - 0xE4, 0x7A, 0x52, 0x7B, 0xF8, 0xFE, 0xF0, 0x62, 0xD2, 0x3F, 0xB9, 0x3B, 0x0F, 0xC8, 0xFD, 0xF9, - 0xB9, 0xF7, 0x3D, 0xAC, 0x05, 0xE4, 0xE5, 0x45, 0x3F, 0x20, 0x49, 0x6B, 0xE0, 0x77, 0x1A, 0xB5, - 0xC3, 0xAD, 0xCE, 0x8E, 0x48, 0xAE, 0x0E, 0xF9, 0xD1, 0xF6, 0xD7, 0xDE, 0x8B, 0x6E, 0xB7, 0x15, - 0x0D, 0xBF, 0x6D, 0xBD, 0xBE, 0xDD, 0x7D, 0x3D, 0xD8, 0x7D, 0x3F, 0x7C, 0xDF, 0xE9, 0xED, 0x74, - 0x07, 0xE4, 0xBA, 0xF7, 0xBE, 0x33, 0xDA, 0x19, 0x4E, 0x26, 0xEF, 0xDE, 0xF5, 0x5F, 0xF9, 0x9D, - 0xEF, 0x49, 0xE7, 0x62, 0xDA, 0xB9, 0x3F, 0x1E, 0x74, 0x4E, 0x6A, 0xEF, 0x8E, 0xCF, 0x9A, 0xAD, - 0xDE, 0xF5, 0xF6, 0xF8, 0x6C, 0x77, 0xDA, 0x4D, 0x8F, 0x3B, 0xEF, 0xBB, 0xCD, 0xF1, 0xDB, 0x5A, - 0x48, 0x3E, 0x47, 0x87, 0xDB, 0xE3, 0x37, 0xBB, 0xEC, 0xF2, 0x9A, 0x74, 0xDE, 0x74, 0xDF, 0xA6, - 0xEC, 0x2A, 0x3C, 0x19, 0x34, 0x3B, 0x9D, 0xD3, 0x0B, 0xFA, 0xEA, 0x70, 0x9B, 0xBC, 0xDB, 0xF2, - 0x3E, 0x82, 0xFE, 0x07, 0x9F, 0xE8, 0x6F, 0xB5, 0xCE, 0xF4, 0xA2, 0x19, 0x78, 0x2F, 0x69, 0xFF, - 0xE4, 0xBA, 0x2F, 0x6F, 0xE7, 0x38, 0x78, 0xD5, 0xBF, 0xED, 0x65, 0xEF, 0xC3, 0xC3, 0x43, 0x53, - 0xE3, 0x51, 0x3D, 0xA1, 0x31, 0x25, 0xA2, 0x1C, 0xAE, 0x16, 0xFE, 0x01, 0xB6, 0xB5, 0xB4, 0xC2, - 0xDC, 0x4F, 0x05, 0xBD, 0x17, 0x75, 0x9F, 0x7A, 0x51, 0x42, 0xE4, 0x1E, 0x40, 0xA0, 0x09, 0x9A, - 0xD8, 0xFC, 0x77, 0x19, 0x3F, 0x35, 0x15, 0x3F, 0x35, 0xC2, 0x7D, 0xCD, 0x28, 0x1C, 0x01, 0x83, - 0x87, 0x4F, 0xEF, 0x98, 0x47, 0xEB, 0x31, 0xBB, 0xA7, 0x41, 0x5D, 0x22, 0x3B, 0x4D, 0x73, 0x26, - 0xFD, 0xAD, 0xD8, 0x46, 0x38, 0x98, 0x9A, 0xA4, 0x5A, 0x2C, 0xF8, 0x5F, 0x89, 0x47, 0x21, 0xB0, - 0x81, 0xCB, 0x84, 0xF8, 0xAB, 0x7C, 0x27, 0x4A, 0xEA, 0xC3, 0x6C, 0x3C, 0x62, 0xF7, 0xE0, 0xD0, - 0x23, 0xC6, 0x99, 0xA0, 0x5A, 0x2B, 0x9D, 0xFF, 0x5E, 0x90, 0xB9, 0xA5, 0x0F, 0xA3, 0x84, 0x84, - 0x34, 0xD5, 0xFE, 0x22, 0x99, 0xD9, 0x28, 0x89, 0xC2, 0x65, 0x10, 0x99, 0x8B, 0xA8, 0x34, 0x99, - 0xCF, 0x9F, 0x65, 0x71, 0x10, 0x11, 0x10, 0x73, 0x4D, 0xE4, 0x50, 0xF1, 0x34, 0x91, 0x6E, 0xB5, - 0x88, 0xAB, 0xB9, 0x9B, 0x6D, 0xA1, 0x5B, 0x96, 0xDD, 0x7A, 0x6B, 0x67, 0xE9, 0xBA, 0x75, 0xB9, - 0x17, 0xE3, 0xFD, 0x9A, 0x4C, 0x81, 0xF1, 0xA0, 0x14, 0xEE, 0x9E, 0x09, 0x50, 0xE9, 0x13, 0x87, - 0xCB, 0x43, 0xF2, 0xC8, 0xB0, 0x60, 0x40, 0x05, 0xEA, 0x96, 0x8C, 0xD4, 0x85, 0x24, 0xB0, 0x6F, - 0xFE, 0x8C, 0xCA, 0xBC, 0x67, 0x3D, 0x8B, 0x13, 0xB8, 0x0D, 0x3A, 0xFD, 0x11, 0xCD, 0x42, 0xA6, - 0x2A, 0x6D, 0x45, 0x53, 0x65, 0xBC, 0x5C, 0x84, 0x65, 0xDA, 0x93, 0xBC, 0x16, 0xA4, 0x1F, 0x4B, - 0x05, 0xE0, 0x05, 0x37, 0xCF, 0x91, 0x9B, 0x1F, 0x6A, 0x75, 0x7B, 0xF7, 0x97, 0x9C, 0x87, 0x9D, - 0xE6, 0x2F, 0x73, 0x3B, 0xDF, 0x5B, 0xA4, 0xE4, 0x56, 0x13, 0xFE, 0x29, 0x32, 0xEF, 0x8B, 0x25, - 0x0B, 0xC3, 0xE7, 0xF8, 0xA7, 0x60, 0x10, 0xE9, 0x94, 0x80, 0xDB, 0x3B, 0x2F, 0x5F, 0xF8, 0xC3, - 0x02, 0x98, 0x0B, 0xF6, 0x24, 0x3C, 0x21, 0x3E, 0xCB, 0x52, 0xE7, 0x79, 0xF3, 0x97, 0x5C, 0x9F, - 0x5B, 0x3B, 0x28, 0xFB, 0xE2, 0x2E, 0x71, 0xB2, 0xB4, 0xD8, 0x34, 0x66, 0x5C, 0xDB, 0x4A, 0x35, - 0xBC, 0x6F, 0x92, 0x2C, 0x0C, 0xB3, 0x92, 0xED, 0xE7, 0xBF, 0x2F, 0x4D, 0x13, 0xF7, 0xCF, 0x9A, - 0xBF, 0xCC, 0x44, 0x02, 0xD9, 0x64, 0x04, 0xB9, 0xC6, 0x49, 0x22, 0x41, 0x04, 0x35, 0x9A, 0xE6, - 0x1C, 0x84, 0x5B, 0x03, 0xD8, 0xDE, 0x6D, 0xFA, 0x74, 0x6C, 0xCE, 0xE7, 0x7B, 0x0D, 0x99, 0xD7, - 0xA0, 0x6C, 0xF1, 0x12, 0x16, 0x8B, 0xFD, 0x51, 0xC6, 0x3D, 0xE4, 0x41, 0x1B, 0x53, 0x83, 0x9A, - 0xB3, 0x84, 0x8A, 0x2C, 0xE1, 0x9A, 0x1F, 0x79, 0x19, 0x1A, 0xBB, 0x3D, 0xA6, 0xE2, 0x58, 0xD9, - 0x7D, 0xF7, 0xE1, 0x8D, 0x0F, 0x3B, 0xE6, 0x0B, 0x04, 0x6F, 0x2D, 0x02, 0x38, 0x30, 0x9C, 0x97, - 0xE3, 0x54, 0xF6, 0x43, 0x82, 0x01, 0x22, 0xEF, 0xE8, 0x83, 0x41, 0x2D, 0xB1, 0x40, 0xA4, 0x36, - 0xAE, 0x1B, 0xC5, 0x2E, 0x80, 0x71, 0x73, 0x76, 0x07, 0x4A, 0x20, 0x2E, 0xFD, 0x22, 0x6E, 0x2C, - 0xE6, 0x72, 0xF8, 0x69, 0xE7, 0xBB, 0xC9, 0x1E, 0x3B, 0xA8, 0xB7, 0x1C, 0xB2, 0xCF, 0x0E, 0x5A, - 0xE0, 0x5E, 0x65, 0x6E, 0xE4, 0xB9, 0xAF, 0x58, 0x40, 0x07, 0xB9, 0xC3, 0xE1, 0x31, 0x48, 0x6C, - 0xB1, 0x85, 0x28, 0xE2, 0x5B, 0xCD, 0xE6, 0x86, 0x4B, 0x0F, 0x48, 0x00, 0x39, 0xCC, 0xD0, 0x8F, - 0xAF, 0xAE, 0x2E, 0xAE, 0xBE, 0xE8, 0x35, 0x5A, 0xD3, 0x6F, 0x1C, 0x4D, 0xAF, 0x71, 0xD3, 0x11, - 0x76, 0x42, 0x47, 0x09, 0x4D, 0x27, 0x97, 0x44, 0x4C, 0x8C, 0xD4, 0xBE, 0x23, 0x41, 0x56, 0x16, - 0x84, 0xA1, 0xDC, 0xC8, 0xA2, 0x70, 0x39, 0x9D, 0x6A, 0xAF, 0x40, 0xCD, 0x47, 0x90, 0xEA, 0xDA, - 0xC2, 0x26, 0x71, 0x4C, 0xB9, 0x6F, 0xE8, 0x31, 0x20, 0xEA, 0x16, 0x35, 0xAD, 0x84, 0x7E, 0xCB, - 0x68, 0x2A, 0x52, 0x1B, 0x2C, 0xD7, 0xD0, 0x2F, 0x07, 0x7D, 0xDD, 0xD2, 0x1B, 0xE8, 0x47, 0x3A, - 0xF0, 0x46, 0xCC, 0x39, 0x52, 0x89, 0x5C, 0xD0, 0xA4, 0x3E, 0xCC, 0xC0, 0xA0, 0xB8, 0x6E, 0xB6, - 0x23, 0x9B, 0x71, 0x4E, 0x93, 0x93, 0xFE, 0xD9, 0xA9, 0xAB, 0x5F, 0x29, 0x46, 0xB4, 0x53, 0x28, - 0x48, 0x74, 0x4B, 0x5E, 0x51, 0x7E, 0xC8, 0xE1, 0x84, 0x05, 0xBE, 0x11, 0x99, 0x6D, 0x24, 0xE1, - 0x49, 0x12, 0xB2, 0x40, 0x01, 0x0A, 0x9E, 0x2D, 0x1E, 0x62, 0xEA, 0xEA, 0x23, 0x50, 0x86, 0x6E, - 0x79, 0x76, 0x98, 0x05, 0x82, 0xC5, 0x01, 0x75, 0x37, 0x5A, 0x30, 0xE3, 0x60, 0x41, 0xAE, 0x8E, - 0xB9, 0x19, 0x61, 0xCC, 0x77, 0x75, 0x15, 0xA1, 0xF2, 0xB8, 0xB6, 0xEE, 0x14, 0x4F, 0x9D, 0x92, - 0x56, 0x4E, 0x49, 0xCB, 0xB8, 0x4A, 0xE0, 0x34, 0x3F, 0x18, 0xC3, 0x3C, 0xCE, 0xD4, 0x51, 0x05, - 0xCC, 0xA7, 0x23, 0x02, 0x9C, 0x7C, 0x40, 0x6D, 0xBA, 0x7A, 0x63, 0xDD, 0x41, 0xA9, 0x3A, 0xC8, - 0xAF, 0x6A, 0xC4, 0x2F, 0x6B, 0x44, 0xDD, 0xEE, 0x3A, 0x64, 0x5F, 0x21, 0x07, 0x55, 0xE4, 0xA0, - 0x8C, 0x7C, 0x28, 0x8D, 0x64, 0x1D, 0x72, 0xA0, 0x90, 0x93, 0x8A, 0x88, 0x89, 0x14, 0x51, 0x85, - 0xBD, 0x3A, 0x6A, 0x13, 0x05, 0xD2, 0xAD, 0xA4, 0x22, 0x66, 0x62, 0x83, 0x97, 0x92, 0x61, 0x40, - 0x7D, 0x77, 0xA3, 0x09, 0x33, 0x2C, 0xB6, 0xDD, 0xAD, 0xE6, 0x9A, 0x33, 0x12, 0x75, 0x46, 0x56, - 0x65, 0x30, 0x2B, 0x33, 0xA8, 0xF5, 0xC8, 0x1D, 0xD5, 0xD6, 0x31, 0x98, 0x99, 0x56, 0x60, 0x47, - 0xDC, 0x0B, 0x98, 0x77, 0xEB, 0x2E, 0xBD, 0xC5, 0x9C, 0xB1, 0x85, 0x85, 0x5A, 0x5C, 0x06, 0xBA, - 0x01, 0x94, 0x5E, 0x8B, 0xA5, 0x7C, 0x80, 0xFA, 0x9E, 0x5B, 0xD9, 0x5A, 0x02, 0xDC, 0xA6, 0xF7, - 0xD4, 0x3B, 0x8C, 0xC2, 0x90, 0xA0, 0xED, 0xA6, 0xC0, 0x41, 0x3E, 0xD1, 0xCD, 0xB9, 0x15, 0xAD, - 0xC5, 0x79, 0xC2, 0x45, 0x2C, 0x7F, 0x3D, 0x8B, 0x23, 0x03, 0x5C, 0xCE, 0xF5, 0x6C, 0xD4, 0x61, - 0x6A, 0x83, 0x1E, 0xC7, 0x62, 0xF2, 0x13, 0x17, 0x2A, 0x0C, 0x54, 0xA2, 0x7C, 0x69, 0xDE, 0x58, - 0x0B, 0x91, 0x56, 0x7C, 0xEA, 0xA2, 0xB7, 0xE2, 0x54, 0xA8, 0xBC, 0x8A, 0x5D, 0x9A, 0x4B, 0x1D, - 0x94, 0x61, 0xB9, 0xBD, 0x2F, 0xA0, 0xFA, 0x7C, 0x0E, 0xE7, 0x01, 0xFF, 0x13, 0x68, 0xF9, 0xE8, - 0x5F, 0x17, 0x60, 0xC9, 0xA3, 0x34, 0x78, 0x8B, 0xBB, 0x0D, 0xE3, 0xC0, 0xF9, 0x8F, 0x6D, 0x7C, - 0xF9, 0x1F, 0xFB, 0xA6, 0x66, 0x9A, 0x07, 0xFF, 0x6A, 0x48, 0x0D, 0x1B, 0xC2, 0xFC, 0xD2, 0xBA, - 0xB1, 0x08, 0x80, 0xED, 0x7F, 0x9B, 0xFF, 0xB1, 0x25, 0xB8, 0x02, 0x6B, 0xDF, 0x45, 0x90, 0x49, - 0xF0, 0x24, 0x34, 0xB0, 0x68, 0xA4, 0x91, 0xCD, 0x4D, 0x43, 0xB8, 0xA4, 0x72, 0x8D, 0x35, 0x51, - 0xD3, 0x6D, 0x88, 0x53, 0x50, 0x5B, 0xAC, 0x04, 0xBF, 0x3E, 0x24, 0x7A, 0x15, 0x5B, 0x17, 0x00, - 0xC9, 0x3D, 0xCA, 0x0C, 0x3D, 0x22, 0x97, 0x52, 0xCB, 0x0C, 0x02, 0x42, 0xA7, 0x89, 0xE7, 0x2A, - 0xAD, 0x1D, 0x14, 0x30, 0x17, 0xA2, 0xE0, 0xBC, 0x1C, 0x2D, 0x15, 0xEA, 0xAA, 0xFD, 0x17, 0x0A, - 0xA3, 0xD6, 0x12, 0x8A, 0x04, 0x31, 0xAD, 0xD8, 0x79, 0xC6, 0x72, 0x75, 0x4C, 0x59, 0xBA, 0x35, - 0x59, 0x5D, 0x96, 0xAD, 0x04, 0xAE, 0x2F, 0x8D, 0xFE, 0xD7, 0x3D, 0x16, 0x8E, 0xB5, 0x12, 0x3F, - 0xF8, 0x97, 0xFB, 0x2B, 0x46, 0xE4, 0xCD, 0x3F, 0xBC, 0x21, 0x70, 0x05, 0xA6, 0x41, 0x6D, 0x1E, - 0x4D, 0x0D, 0xB3, 0xF6, 0xAB, 0xAE, 0x49, 0x8A, 0xAE, 0x1E, 0x92, 0xFB, 0xBC, 0xA7, 0xC4, 0x8C, - 0xD7, 0xD6, 0x70, 0x5E, 0xB4, 0x28, 0xF9, 0x82, 0xEC, 0xE6, 0x48, 0x26, 0xA2, 0xB6, 0x56, 0x64, - 0x52, 0xD5, 0xCA, 0xE8, 0x5A, 0x63, 0xFF, 0xD7, 0x4A, 0x40, 0xB7, 0x98, 0xBA, 0x4E, 0x15, 0x8C, - 0xB3, 0x00, 0x1C, 0x93, 0x3E, 0x1D, 0x69, 0x03, 0x26, 0x03, 0x75, 0x35, 0x46, 0x5A, 0x81, 0xC1, - 0xCC, 0x03, 0xC3, 0x2B, 0xFB, 0xF3, 0x1E, 0x16, 0xBF, 0xFB, 0x97, 0xAA, 0xAA, 0x81, 0xD4, 0x8B, - 0x33, 0x5D, 0x59, 0x59, 0xD5, 0x4B, 0xE0, 0xD2, 0x08, 0xA0, 0x5B, 0x8B, 0x3C, 0x3A, 0x8C, 0xFC, - 0x87, 0x52, 0xF6, 0x4D, 0xBB, 0x0F, 0x87, 0x01, 0x49, 0xD3, 0x73, 0xB8, 0x01, 0x43, 0xF7, 0x42, - 0x50, 0xB8, 0xB2, 0xC2, 0xFD, 0xE6, 0xE6, 0x66, 0x15, 0x29, 0xA1, 0x21, 0x14, 0xDB, 0x8A, 0x2B, - 0xF0, 0x49, 0xD3, 0xF1, 0x81, 0x30, 0x18, 0xD2, 0x1A, 0xC6, 0xF0, 0x25, 0xE3, 0x47, 0x5C, 0x71, - 0xF4, 0xF4, 0x22, 0xA6, 0xFC, 0x33, 0xDC, 0x95, 0x32, 0xCB, 0x1A, 0xAD, 0xA6, 0x68, 0xFA, 0x8F, - 0xD8, 0x3E, 0xCA, 0x0D, 0x76, 0xC1, 0x7A, 0xBA, 0x56, 0xA1, 0xFC, 0x9F, 0x61, 0xB9, 0x94, 0x28, - 0xD6, 0x70, 0x9C, 0x40, 0x80, 0x5A, 0xC3, 0x31, 0xC4, 0x1A, 0x41, 0x17, 0xFC, 0x26, 0x6B, 0xF9, - 0xCD, 0xFE, 0x19, 0x7E, 0x97, 0x76, 0x1E, 0x15, 0x25, 0x91, 0xAA, 0xAF, 0x50, 0x02, 0x9F, 0xDD, - 0xE9, 0xA6, 0x15, 0xB9, 0x55, 0x0A, 0x50, 0x1B, 0x46, 0x41, 0xD0, 0x8F, 0xE2, 0x83, 0x27, 0xD6, - 0x9D, 0xC5, 0x7A, 0x31, 0xC8, 0xD9, 0x5C, 0x6E, 0xB1, 0xBC, 0xB5, 0x44, 0x4F, 0xA1, 0xEC, 0x5F, - 0x4B, 0x15, 0x01, 0x3F, 0x23, 0x8B, 0x7B, 0xAC, 0xD4, 0xA5, 0x36, 0x28, 0x0F, 0x56, 0x3F, 0xD5, - 0x3C, 0xCB, 0x5F, 0xCC, 0xAE, 0x6B, 0x51, 0x9B, 0xC0, 0x38, 0x57, 0x92, 0x8B, 0x4A, 0xB2, 0xC8, - 0x13, 0x01, 0xA8, 0x58, 0xC7, 0x2E, 0xC4, 0x4D, 0x6B, 0x7A, 0x7C, 0xBF, 0x5C, 0x83, 0xC2, 0xDF, - 0xF5, 0xD5, 0x12, 0x33, 0x08, 0xC4, 0xD3, 0x95, 0x4B, 0x29, 0x5F, 0x37, 0x29, 0x8A, 0x0E, 0x62, - 0x47, 0xA3, 0x51, 0x4A, 0xC5, 0x47, 0x0C, 0x49, 0x56, 0xB2, 0x98, 0x9F, 0xC8, 0x90, 0x04, 0x8C, - 0x45, 0x3C, 0x8C, 0xB2, 0x94, 0x46, 0x99, 0xA8, 0xA4, 0x16, 0x63, 0x21, 0xCC, 0x5E, 0xFA, 0xE7, - 0x9F, 0x8B, 0xC9, 0x7E, 0x5A, 0x0B, 0x96, 0xD3, 0xEB, 0x3D, 0xBF, 0x34, 0xD9, 0xF7, 0x6B, 0x89, - 0xB9, 0x7A, 0xE9, 0xFF, 0x67, 0x4B, 0x21, 0x65, 0x4B, 0xF1, 0xB0, 0x54, 0x2E, 0x62, 0x62, 0x29, - 0xE6, 0xC9, 0x82, 0x91, 0x97, 0x7C, 0x16, 0x0D, 0x1A, 0x2B, 0x25, 0x55, 0x9E, 0x97, 0x7D, 0x95, - 0x43, 0x40, 0x59, 0x71, 0xE5, 0x35, 0x11, 0x06, 0x34, 0xE0, 0x63, 0x64, 0xF2, 0x41, 0xEB, 0xA7, - 0xD1, 0x94, 0x26, 0x87, 0x24, 0xA5, 0x06, 0x24, 0xCD, 0x65, 0xDC, 0x41, 0xA8, 0xE9, 0x04, 0xEB, - 0x76, 0x6D, 0x6E, 0x12, 0x05, 0xCE, 0x33, 0x77, 0xC4, 0xB1, 0x26, 0x03, 0xF9, 0xB2, 0xCA, 0x09, - 0xD4, 0xC6, 0xBE, 0x12, 0xA4, 0x3E, 0x52, 0x25, 0xA8, 0x61, 0x5A, 0xD0, 0x76, 0xC0, 0x35, 0x5F, - 0x26, 0x51, 0x4C, 0xC6, 0xB2, 0x07, 0x83, 0x35, 0x74, 0x0F, 0xA4, 0x66, 0x6D, 0x34, 0x91, 0x60, - 0xA9, 0x73, 0x29, 0xFC, 0x66, 0xD9, 0xC2, 0x70, 0x4B, 0x57, 0xC9, 0xB0, 0xBD, 0xF4, 0xA5, 0x35, - 0x59, 0x83, 0xE0, 0x0B, 0x6C, 0x62, 0xE0, 0x1E, 0x68, 0x64, 0xF2, 0x7B, 0x00, 0x77, 0x6B, 0xB6, - 0xA3, 0x3D, 0xD6, 0x8E, 0x6A, 0x35, 0x53, 0x55, 0xE9, 0xAE, 0x0B, 0x6D, 0x4E, 0x74, 0x23, 0x0B, - 0x4B, 0x10, 0xAA, 0x9A, 0x59, 0x0C, 0x38, 0x1B, 0x81, 0xAA, 0xBA, 0xC0, 0x11, 0xD6, 0x98, 0x66, - 0xA9, 0x23, 0xF1, 0x97, 0x1D, 0xC9, 0x13, 0xB5, 0x07, 0x95, 0xF5, 0x05, 0xD4, 0x31, 0xAB, 0x25, - 0x86, 0x30, 0xD3, 0x29, 0x13, 0xDE, 0x04, 0x03, 0x90, 0x07, 0x5A, 0xD5, 0x05, 0x14, 0xB5, 0x8E, - 0x1C, 0x4D, 0x44, 0xB8, 0x1C, 0x05, 0xF9, 0xF0, 0x6B, 0x9A, 0x0F, 0xBC, 0xB4, 0x18, 0xDD, 0x97, - 0x80, 0x50, 0xD2, 0xE6, 0xE0, 0x88, 0x8F, 0xF2, 0x21, 0xF4, 0xB2, 0x05, 0x9D, 0x02, 0x58, 0xFC, - 0xC6, 0x71, 0x3E, 0x8A, 0x27, 0xC5, 0x68, 0x42, 0xEF, 0x17, 0x78, 0x51, 0x01, 0xF5, 0xA9, 0xEE, - 0x28, 0x1B, 0xDB, 0x68, 0xCE, 0xF3, 0x41, 0x6B, 0x29, 0x7F, 0xF0, 0xFF, 0x28, 0x7F, 0xCC, 0xC7, - 0x85, 0x34, 0x71, 0x31, 0x1A, 0xB3, 0x42, 0x96, 0x61, 0x18, 0xFF, 0x90, 0x93, 0xA4, 0xD4, 0x13, - 0x97, 0x7A, 0x5A, 0xF1, 0xB3, 0xB6, 0x53, 0x98, 0x8E, 0x31, 0xAA, 0xF8, 0xE3, 0xC8, 0xF6, 0xF0, - 0xF7, 0x3C, 0xF2, 0x65, 0x6D, 0x69, 0x5A, 0xA1, 0x31, 0x82, 0x3A, 0x57, 0x37, 0xCB, 0x7E, 0x9A, - 0xFD, 0xB7, 0xAD, 0xE8, 0xD1, 0xF1, 0xE9, 0x71, 0xFF, 0xB8, 0x5C, 0x38, 0x23, 0xE7, 0x25, 0x93, - 0x8A, 0x2B, 0x5D, 0xFA, 0xB2, 0x22, 0x80, 0x02, 0x1B, 0x45, 0x01, 0x7B, 0xDD, 0xDC, 0x54, 0x7E, - 0xF1, 0xB6, 0x77, 0x71, 0x6E, 0xC7, 0x24, 0x01, 0x8F, 0x24, 0x15, 0xE6, 0xC2, 0x82, 0x44, 0xF9, - 0xE0, 0xD7, 0xC7, 0xA5, 0x72, 0x5D, 0x7E, 0x61, 0x70, 0xC4, 0xDC, 0x52, 0xA7, 0xA9, 0x7E, 0x78, - 0xE2, 0x62, 0x5D, 0x99, 0xBF, 0x04, 0x41, 0x72, 0x1A, 0x2D, 0x13, 0x55, 0x11, 0x67, 0x46, 0xE5, - 0x30, 0x2F, 0xEE, 0xB2, 0x75, 0x0D, 0xD3, 0xC8, 0xB4, 0xC4, 0x84, 0xA5, 0xE5, 0x46, 0xA5, 0x12, - 0x14, 0xFE, 0xA2, 0xB6, 0xE7, 0x8B, 0x91, 0x24, 0xB7, 0x5A, 0x73, 0xAB, 0x6F, 0x41, 0x2A, 0x3E, - 0x58, 0x04, 0x23, 0x66, 0x39, 0xDB, 0x16, 0x77, 0xA3, 0x43, 0xEE, 0x61, 0x5C, 0x7F, 0xBA, 0x35, - 0x78, 0xD2, 0x3C, 0x79, 0x61, 0x9E, 0xFC, 0xB1, 0x7B, 0x2E, 0x1C, 0x45, 0xF9, 0xDA, 0xE2, 0x98, - 0xF6, 0x10, 0x58, 0xBB, 0x6D, 0x2F, 0x7D, 0x18, 0x20, 0xD2, 0x83, 0xCB, 0x00, 0xF4, 0x63, 0x58, - 0xFF, 0x4A, 0xEE, 0x88, 0x7A, 0x09, 0xAA, 0xA2, 0xAD, 0x73, 0x54, 0xD8, 0xEE, 0xFD, 0x81, 0xA3, - 0xF2, 0xCE, 0x65, 0x18, 0x48, 0x97, 0xC3, 0x92, 0x37, 0x8B, 0x75, 0xC1, 0x61, 0x19, 0x31, 0x64, - 0x6C, 0x00, 0xE3, 0xCD, 0x5D, 0x49, 0x13, 0xD5, 0x1C, 0xB4, 0xF0, 0x1B, 0x08, 0x8A, 0x4F, 0x39, - 0xCE, 0x9A, 0x38, 0xAD, 0x62, 0x72, 0xC5, 0x23, 0xC8, 0x4A, 0x67, 0x89, 0xC0, 0x6E, 0x10, 0x0D, - 0x0D, 0x7C, 0x64, 0x9A, 0xA1, 0xB6, 0x1D, 0x3E, 0x37, 0xD7, 0xBC, 0xD9, 0x54, 0xFA, 0x4B, 0x62, - 0x79, 0xD5, 0xB0, 0x8B, 0x1C, 0x56, 0xCC, 0x75, 0x7D, 0x1F, 0xF4, 0xA3, 0x4E, 0x29, 0xAF, 0x48, - 0xA4, 0x53, 0xD1, 0x83, 0xC4, 0x86, 0xA2, 0x41, 0xBE, 0x91, 0x40, 0x44, 0x72, 0x4A, 0x33, 0x5D, - 0xC7, 0xCA, 0xD2, 0x0B, 0x28, 0x49, 0x7A, 0xB2, 0x73, 0x95, 0x49, 0x6B, 0x25, 0x06, 0xFE, 0xC8, - 0xD7, 0xF0, 0xC7, 0xA1, 0xD0, 0xA3, 0x83, 0x9B, 0x49, 0x2B, 0x83, 0xA4, 0x23, 0x64, 0x83, 0xA9, - 0x37, 0xE4, 0xBB, 0xA8, 0x2D, 0x2F, 0xCB, 0xB4, 0x16, 0x50, 0x70, 0x71, 0x83, 0xBB, 0x11, 0x30, - 0x52, 0x5A, 0xC4, 0x9E, 0x94, 0xA8, 0xC7, 0x8F, 0x10, 0x1F, 0x53, 0x4A, 0x20, 0x06, 0x20, 0xA6, - 0x40, 0xD0, 0xA7, 0x42, 0x8A, 0x54, 0xE6, 0x92, 0x53, 0x2A, 0x20, 0xCA, 0x48, 0xCD, 0xE2, 0xC1, - 0x85, 0x78, 0xD4, 0x46, 0xD6, 0x80, 0xFD, 0xDC, 0xBD, 0x73, 0x33, 0xDE, 0x90, 0x68, 0x09, 0x56, - 0x36, 0x3D, 0x9A, 0xA6, 0x52, 0x5C, 0x54, 0xC7, 0x19, 0xF8, 0xA8, 0xA1, 0x03, 0x5A, 0x23, 0x84, - 0x11, 0x1E, 0x84, 0x8A, 0x01, 0x40, 0x7F, 0x42, 0xC3, 0x1C, 0x22, 0x70, 0x08, 0x20, 0x82, 0xA0, - 0x7F, 0x49, 0x0D, 0xF7, 0x64, 0x05, 0xC9, 0xF8, 0xD8, 0x6D, 0x35, 0xF0, 0x9D, 0x66, 0x95, 0xEC, - 0x20, 0xA5, 0xBD, 0x68, 0x24, 0xFA, 0x64, 0x98, 0x1A, 0x50, 0x00, 0xAC, 0xD9, 0x01, 0xA0, 0x1E, - 0x24, 0x5E, 0x63, 0x2B, 0x3F, 0xEF, 0x04, 0x2A, 0xBB, 0x00, 0xAB, 0xBB, 0x8E, 0x87, 0x5F, 0x39, - 0x4F, 0x19, 0xA7, 0x39, 0x26, 0x00, 0x7B, 0x93, 0x68, 0x7A, 0x99, 0x30, 0x2E, 0xCE, 0x64, 0x1B, - 0x6A, 0x6C, 0xB4, 0xE4, 0xF5, 0xA9, 0x87, 0x15, 0x79, 0x3F, 0xC5, 0x8B, 0xCB, 0x0C, 0xF3, 0xBA, - 0x53, 0x79, 0x77, 0xB1, 0x86, 0x70, 0x21, 0x50, 0x66, 0x38, 0xB3, 0x29, 0x74, 0xB0, 0xFA, 0xA1, - 0x48, 0x82, 0x7A, 0x4F, 0xB7, 0x42, 0xE2, 0xC1, 0x44, 0xED, 0x81, 0xF9, 0xDC, 0xC2, 0xD8, 0xE1, - 0x94, 0x83, 0x5A, 0x0A, 0xB5, 0x02, 0x45, 0xC6, 0x95, 0xCD, 0x98, 0x35, 0x1D, 0x6A, 0x58, 0x88, - 0x61, 0xE0, 0xAF, 0xFE, 0x05, 0x0F, 0x1E, 0x1C, 0xC8, 0x55, 0x3F, 0xE1, 0x23, 0xE3, 0x7E, 0xF4, - 0x23, 0x3E, 0x3E, 0xAF, 0xF0, 0xF1, 0x79, 0x1D, 0x1F, 0xB4, 0xAA, 0x3C, 0x98, 0x0C, 0x80, 0xEC, - 0x19, 0xE1, 0x64, 0x4C, 0x13, 0x58, 0xC0, 0x43, 0x50, 0x25, 0x7F, 0x8B, 0xB3, 0x84, 0xFE, 0x98, - 0xB3, 0xDE, 0x84, 0x8D, 0xC4, 0x23, 0xFE, 0x8A, 0xD5, 0xFF, 0x82, 0x4B, 0x3C, 0x70, 0x3D, 0x97, - 0x79, 0x6D, 0x5A, 0x49, 0x28, 0x3F, 0x7E, 0x2B, 0x91, 0x7E, 0xE4, 0x42, 0x78, 0xA9, 0x38, 0xC8, - 0xDF, 0xB7, 0xF4, 0x00, 0xBC, 0x11, 0xF8, 0x29, 0x35, 0x75, 0xBC, 0x0B, 0xA5, 0xFC, 0x29, 0x30, - 0x64, 0xA8, 0xC0, 0x47, 0xDD, 0xD9, 0xDC, 0x12, 0xAE, 0x01, 0x8A, 0xF1, 0xA3, 0x29, 0xB0, 0xEA, - 0xC9, 0x02, 0xD7, 0x9E, 0x40, 0x26, 0x04, 0x91, 0xE0, 0x48, 0xC8, 0xA7, 0x8D, 0x2F, 0x07, 0x9B, - 0x37, 0x35, 0xC8, 0x43, 0x2E, 0xFC, 0x98, 0x2E, 0x0C, 0x36, 0x6F, 0xFE, 0x6D, 0x36, 0xC6, 0xCC, - 0x5A, 0x76, 0xA4, 0x96, 0x4C, 0xF6, 0xF4, 0x0B, 0xBF, 0x71, 0x09, 0x48, 0x5D, 0x49, 0x78, 0x45, - 0x34, 0x03, 0x6B, 0x43, 0x61, 0xE1, 0x07, 0xFF, 0x47, 0x09, 0xF8, 0x91, 0x9E, 0x07, 0xCE, 0xBD, - 0xE6, 0x3D, 0x5E, 0x2F, 0x3E, 0x85, 0xE9, 0x56, 0xE9, 0xC1, 0x4A, 0xC7, 0xEF, 0x53, 0x3A, 0x76, - 0x59, 0xA2, 0x14, 0x4A, 0x14, 0x59, 0x88, 0x1A, 0x6A, 0x50, 0x0E, 0x51, 0x98, 0x89, 0x17, 0xCD, - 0x81, 0x02, 0x9B, 0x73, 0x34, 0x5B, 0x3A, 0x02, 0x0F, 0xF4, 0xF5, 0x45, 0xEE, 0xFC, 0x74, 0x76, - 0x7A, 0x22, 0x44, 0x7C, 0xA5, 0x62, 0x22, 0xD0, 0xAA, 0x2E, 0x2C, 0x2F, 0xCF, 0x9C, 0x89, 0xE4, - 0xA1, 0x28, 0x75, 0x30, 0x31, 0x28, 0x87, 0xFE, 0x74, 0x31, 0xFC, 0x0A, 0x71, 0xD6, 0xD0, 0xCF, - 0x52, 0x48, 0x58, 0x5B, 0x36, 0xA2, 0xF7, 0xFB, 0x97, 0xF6, 0xAE, 0xDD, 0x84, 0xBA, 0x00, 0xB4, - 0x0A, 0x69, 0x19, 0xEE, 0x7D, 0xFE, 0xB7, 0x90, 0xB7, 0xFF, 0x1E, 0x32, 0x83, 0xA8, 0x95, 0x42, - 0x58, 0x2A, 0xF0, 0xAB, 0xB8, 0x93, 0x24, 0x9A, 0x4A, 0xB4, 0xE3, 0x24, 0xC1, 0x4B, 0xE9, 0x43, - 0x85, 0xA2, 0x0D, 0x61, 0x31, 0xA5, 0x89, 0xE6, 0x47, 0x34, 0xD5, 0x78, 0x24, 0xB4, 0x34, 0x8B, - 0x63, 0x68, 0x5C, 0x56, 0xF4, 0x61, 0xEB, 0xC5, 0xEB, 0xCB, 0xFB, 0x8C, 0x66, 0xD4, 0xCF, 0x97, - 0x69, 0x52, 0xD1, 0x0B, 0x56, 0x50, 0xDF, 0x10, 0xEE, 0x7E, 0xB9, 0xC9, 0xEB, 0xA9, 0x8C, 0x73, - 0x8C, 0xA2, 0x1B, 0x2D, 0x35, 0x07, 0xE9, 0x26, 0x40, 0xD5, 0xE5, 0x59, 0x10, 0xCC, 0xDB, 0x2B, - 0xB4, 0xA0, 0xF1, 0x8A, 0x44, 0x24, 0x9F, 0xCB, 0x67, 0x7F, 0xE4, 0xC9, 0xA9, 0xE2, 0x82, 0x50, - 0xF2, 0x54, 0xA9, 0x36, 0xAD, 0x0D, 0x63, 0x83, 0x6A, 0x8C, 0xA7, 0x82, 0x70, 0x0F, 0xAF, 0x51, - 0xE9, 0xC2, 0x2C, 0x6A, 0x29, 0xDC, 0xDE, 0x46, 0x5F, 0xCB, 0x6D, 0xE9, 0x89, 0x7C, 0x2A, 0x25, - 0xE3, 0xAE, 0xAE, 0x63, 0x55, 0x45, 0xB1, 0x3E, 0x25, 0x61, 0x5A, 0x26, 0x5B, 0x54, 0x06, 0x26, - 0x77, 0x0B, 0x70, 0x9B, 0x06, 0x29, 0x1C, 0xBD, 0x7E, 0x7F, 0xCE, 0x46, 0xD1, 0xCE, 0x11, 0x80, - 0x69, 0xC5, 0x3E, 0x93, 0xD7, 0xE0, 0x24, 0xCC, 0x73, 0x07, 0x32, 0xE9, 0x4A, 0x03, 0x0E, 0xA9, - 0x98, 0x44, 0xFE, 0x81, 0x7E, 0xA0, 0x3B, 0x3A, 0xFC, 0xBB, 0x09, 0x35, 0x47, 0xCD, 0xA5, 0xD0, - 0xA4, 0xFA, 0x74, 0x70, 0xF5, 0x06, 0xC2, 0x53, 0x0C, 0xA5, 0x01, 0x17, 0x50, 0x34, 0xD7, 0x74, - 0x7C, 0x7A, 0x7D, 0x0C, 0x29, 0xC8, 0x7F, 0x21, 0x37, 0x66, 0xBB, 0xAA, 0x6C, 0xB8, 0xF3, 0xEA, - 0x75, 0x56, 0x2E, 0x03, 0x7A, 0x61, 0x8C, 0x58, 0x0F, 0x29, 0x7E, 0xFB, 0x7B, 0xF4, 0x9E, 0x8D, - 0x15, 0xD2, 0x6A, 0x5D, 0x6F, 0xCE, 0x76, 0x90, 0x67, 0x89, 0xD5, 0x43, 0x2C, 0x70, 0x97, 0x1F, - 0x29, 0x59, 0x95, 0x35, 0xDC, 0xF6, 0x48, 0x10, 0xE0, 0xC7, 0x5A, 0x03, 0x1B, 0x6A, 0x22, 0xB2, - 0xD4, 0x42, 0x22, 0x29, 0x08, 0x90, 0xD2, 0x3E, 0x84, 0x39, 0xD3, 0x92, 0x65, 0x86, 0xB2, 0xA1, - 0xBC, 0xFF, 0xC5, 0x9A, 0xA3, 0x64, 0x46, 0xE8, 0xCE, 0xF9, 0x6C, 0x73, 0x53, 0xD8, 0x85, 0x99, - 0x18, 0x05, 0x52, 0x8A, 0x01, 0x1C, 0x9A, 0x7D, 0x68, 0x2D, 0x8C, 0xB2, 0x90, 0x58, 0xAB, 0x3D, - 0xD2, 0xB6, 0x51, 0x55, 0x03, 0x54, 0x7C, 0x46, 0x01, 0x03, 0xCE, 0xB2, 0x24, 0x80, 0xA8, 0x8B, - 0x39, 0xBA, 0xB2, 0x2D, 0xC5, 0xBA, 0xD0, 0x84, 0x0E, 0xEC, 0x67, 0xC8, 0x12, 0x95, 0x97, 0xAD, - 0xA2, 0x27, 0x12, 0xC5, 0x77, 0x95, 0x9E, 0xC8, 0x6F, 0xE5, 0x84, 0xAA, 0xC8, 0x77, 0x88, 0x2F, - 0x13, 0x5C, 0xD4, 0xD1, 0x13, 0xA0, 0x24, 0x83, 0x52, 0x34, 0x60, 0x2A, 0x2C, 0x37, 0xEE, 0xEB, - 0xD3, 0xE9, 0xB4, 0x8E, 0xDF, 0x6A, 0xEB, 0x70, 0x82, 0xB2, 0x02, 0x5F, 0x5F, 0xC7, 0x21, 0x47, - 0x15, 0x58, 0xF8, 0x6E, 0xE1, 0xAC, 0xBA, 0xE8, 0x42, 0x7F, 0x2B, 0xDE, 0xD4, 0xAA, 0xD2, 0x59, - 0xE1, 0x73, 0x79, 0xDB, 0x7B, 0x3B, 0x2B, 0x20, 0x32, 0xC4, 0xAF, 0xB2, 0x90, 0x69, 0x20, 0x0D, - 0x3B, 0xE5, 0x46, 0x56, 0x25, 0x85, 0x65, 0x5C, 0xB0, 0xE3, 0x2C, 0x9D, 0x18, 0x33, 0x60, 0xDD, - 0x11, 0x96, 0xD2, 0x95, 0x43, 0x2D, 0x65, 0xB7, 0x0E, 0xB7, 0x0A, 0xFB, 0x70, 0x30, 0x83, 0x94, - 0x79, 0xFB, 0xF3, 0x4F, 0x39, 0x5B, 0xDE, 0xF6, 0x92, 0x62, 0x71, 0xE1, 0xF3, 0xFC, 0xA9, 0x35, - 0xAF, 0x69, 0xA5, 0xD1, 0xAF, 0xC4, 0x97, 0xBD, 0x46, 0xFE, 0x19, 0x3B, 0xFF, 0x9C, 0xAD, 0x81, - 0xB1, 0x43, 0x23, 0x2A, 0xDC, 0x4C, 0x8C, 0xEA, 0x2F, 0x34, 0xE6, 0x63, 0x79, 0x29, 0xBF, 0x2D, - 0xA0, 0x54, 0xA9, 0xD3, 0x68, 0x78, 0x3E, 0xFF, 0x9A, 0x42, 0x19, 0x1D, 0x65, 0xFE, 0x28, 0x20, - 0x09, 0xC5, 0x82, 0xA3, 0x41, 0xBE, 0x92, 0xFB, 0x46, 0xC0, 0x86, 0x69, 0x03, 0x93, 0x6D, 0xCB, - 0xDE, 0xB2, 0x77, 0x71, 0x64, 0x7F, 0x4D, 0xF7, 0x57, 0x4F, 0xD8, 0x5F, 0x34, 0x69, 0x58, 0x0B, - 0xE7, 0xB5, 0xAB, 0x8A, 0x4D, 0x6A, 0x83, 0xFB, 0xC4, 0xA7, 0x70, 0x3D, 0x6F, 0xB3, 0xCC, 0xB6, - 0x1A, 0xE4, 0x5F, 0x60, 0xD4, 0x31, 0xBA, 0x95, 0x2F, 0x92, 0xF4, 0x81, 0x7B, 0x18, 0x5B, 0x17, - 0x54, 0x26, 0x70, 0x49, 0xD5, 0x87, 0x34, 0xB9, 0xD3, 0x9C, 0x2F, 0x39, 0xC3, 0xB7, 0x3C, 0xA8, - 0x03, 0xE4, 0x37, 0x9C, 0x72, 0x39, 0xB0, 0xBF, 0x07, 0x5D, 0x33, 0x2A, 0x41, 0x79, 0xB1, 0x26, - 0x9B, 0xE6, 0x7C, 0x02, 0x82, 0x01, 0x70, 0xB1, 0xA3, 0x48, 0xCD, 0x2B, 0xCB, 0x98, 0x9B, 0x57, - 0x96, 0x54, 0xE2, 0x5F, 0x59, 0xCC, 0xDB, 0x9F, 0xFC, 0xDB, 0x4C, 0xF9, 0x7F, 0x5B, 0x28, 0x36, - 0x32, 0xF9, 0xE1, 0x09, 0xF7, 0x56, 0x3F, 0x45, 0xAD, 0x47, 0x51, 0xBB, 0xF7, 0xFF, 0x17, 0x53, - 0xE8, 0x9D, 0x36, 0x92, 0x29, 0x00, 0x00 +0x1F, 0x8B, 0x08, 0x08, 0x5A, 0x38, 0x57, 0x5E, 0x02, 0x00, 0x65, 0x64, 0x69, 0x74, 0x2E, 0x68, +0x74, 0x6D, 0x00, 0xB5, 0x1A, 0x0B, 0x5B, 0xDB, 0x36, 0xF0, 0xAF, 0x18, 0x6F, 0x63, 0xF6, 0xE2, +0x38, 0x0E, 0x50, 0xD6, 0x39, 0x18, 0x16, 0x1E, 0x1B, 0x5D, 0x5B, 0xA0, 0x24, 0xB4, 0xA3, 0x1D, +0xDB, 0xA7, 0xD8, 0x4A, 0xA2, 0x62, 0x4B, 0x9E, 0x2D, 0x13, 0x68, 0x96, 0xFF, 0xBE, 0x93, 0xE4, +0x67, 0x30, 0xDD, 0xE3, 0xDB, 0x4A, 0x21, 0x92, 0x4E, 0x77, 0xBA, 0x3B, 0xDD, 0xD3, 0xCE, 0xDE, +0xC6, 0xF1, 0xF9, 0xD1, 0xF8, 0xFA, 0xE2, 0x44, 0x9B, 0xF3, 0x28, 0xDC, 0xDF, 0x13, 0x7F, 0xB5, +0x10, 0xD1, 0x99, 0xA7, 0x63, 0xAA, 0xC3, 0x1C, 0xA3, 0x60, 0x7F, 0x2F, 0xC2, 0x1C, 0xC1, 0x06, +0x1E, 0x77, 0xF1, 0xEF, 0x19, 0xB9, 0xF3, 0xF4, 0x23, 0x46, 0x39, 0xA6, 0xBC, 0xCB, 0x1F, 0x62, +0xAC, 0x6B, 0xBE, 0x9A, 0x79, 0x3A, 0xC7, 0xF7, 0xBC, 0x27, 0x48, 0x0C, 0x34, 0x7F, 0x8E, 0x92, +0x14, 0x73, 0x2F, 0xE3, 0xD3, 0xEE, 0x73, 0x20, 0xC4, 0x09, 0x0F, 0xF1, 0xFE, 0xC9, 0xE8, 0x42, +0x3B, 0x09, 0x08, 0x67, 0xC9, 0x5E, 0x4F, 0xAD, 0xEC, 0xA5, 0xFC, 0x21, 0xC4, 0x9A, 0x20, 0x94, +0xE3, 0xFB, 0x69, 0xAA, 0x6B, 0x11, 0x0E, 0x08, 0xF2, 0xF4, 0xD4, 0x4F, 0xB0, 0xE0, 0xC3, 0xF6, +0xA3, 0xE5, 0xA7, 0x2E, 0xA1, 0x01, 0xBE, 0x77, 0xB7, 0x1D, 0x67, 0x10, 0xB3, 0x94, 0x70, 0xC2, +0xA8, 0x8B, 0x26, 0x29, 0x0B, 0x33, 0x8E, 0x07, 0x21, 0x9E, 0x72, 0xF7, 0x59, 0x7C, 0x3F, 0x98, +0xB0, 0x24, 0xC0, 0x89, 0xDB, 0x8F, 0xEF, 0x35, 0x00, 0x91, 0x40, 0xFB, 0x62, 0x67, 0x67, 0x67, +0x30, 0x41, 0xFE, 0xED, 0x2C, 0x61, 0x19, 0x0D, 0xBA, 0x3E, 0x0B, 0x59, 0xE2, 0x7E, 0xF1, 0xC3, +0x33, 0xF1, 0x33, 0x08, 0x48, 0x1A, 0x87, 0xE8, 0xC1, 0xA5, 0x8C, 0x62, 0xC0, 0xBD, 0xEF, 0xA6, +0x73, 0x14, 0xB0, 0x85, 0xEB, 0x68, 0x8E, 0xD6, 0x77, 0x80, 0x48, 0x32, 0x9B, 0x20, 0xC3, 0xB1, +0xC4, 0x8F, 0xBD, 0x63, 0x0E, 0xA6, 0x0C, 0xC4, 0x4E, 0xC9, 0x27, 0xEC, 0xF6, 0xB7, 0xE2, 0x7B, +0x35, 0x9D, 0xA2, 0x88, 0x84, 0x0F, 0x6E, 0x8A, 0x68, 0xDA, 0x4D, 0x71, 0x42, 0xA6, 0x6A, 0x79, +0x81, 0xC9, 0x6C, 0xCE, 0xDD, 0x6F, 0x1D, 0x67, 0x05, 0xFC, 0x6B, 0x59, 0xB8, 0x0C, 0x49, 0xCA, +0xBB, 0x52, 0x60, 0x75, 0x1E, 0x67, 0xB1, 0xEB, 0x48, 0xD6, 0xE1, 0x23, 0x42, 0xC9, 0x8C, 0x50, +0x18, 0xC4, 0x28, 0x08, 0x08, 0x9D, 0xB9, 0x0A, 0x2D, 0x24, 0xCB, 0x52, 0xDA, 0x04, 0x87, 0x88, +0x93, 0x3B, 0x3C, 0x88, 0x08, 0xED, 0x2E, 0x48, 0xC0, 0xE7, 0xEE, 0xAE, 0x03, 0x5C, 0xF8, 0x59, +0x92, 0x82, 0x4C, 0x31, 0x23, 0x94, 0xE3, 0x44, 0xA2, 0xA5, 0x31, 0xA2, 0x4B, 0x25, 0xAA, 0x50, +0x40, 0x29, 0x27, 0xA1, 0x21, 0xA1, 0xB8, 0x3B, 0x09, 0x99, 0x7F, 0x5B, 0x9E, 0xB4, 0x1B, 0xDF, +0xE7, 0x67, 0xB9, 0x73, 0x76, 0x87, 0x93, 0x65, 0xA5, 0x2E, 0x89, 0xDD, 0x00, 0x36, 0x48, 0x9F, +0x9C, 0x9C, 0xAC, 0x6C, 0x7E, 0x97, 0x01, 0xD4, 0x92, 0x9F, 0x20, 0x65, 0x4E, 0xB5, 0x2E, 0xD2, +0x9A, 0xE0, 0x0A, 0x85, 0xD0, 0x38, 0xE3, 0xCB, 0xC7, 0x57, 0xC9, 0x62, 0xE4, 0x13, 0xFE, 0xE0, +0x3A, 0x72, 0xDB, 0x52, 0xE8, 0xD2, 0xDD, 0x71, 0x1C, 0x4D, 0x28, 0x5C, 0x7B, 0x8B, 0x93, 0x00, +0x51, 0x64, 0x0D, 0x13, 0x82, 0x42, 0x6B, 0x54, 0xA9, 0xBC, 0x1B, 0xB1, 0x4F, 0xDD, 0x0C, 0xC6, +0x30, 0x0F, 0xB1, 0xCF, 0x95, 0x86, 0xE1, 0x12, 0x26, 0xB7, 0x84, 0x3F, 0x06, 0x3C, 0x5A, 0xA8, +0xE9, 0x4A, 0x6A, 0x68, 0xAE, 0x6E, 0xAF, 0x0F, 0xBA, 0x91, 0x7C, 0x28, 0xB1, 0x95, 0x44, 0xDD, +0x09, 0xE3, 0x9C, 0x45, 0xD2, 0xDE, 0x4A, 0x69, 0x35, 0x69, 0x32, 0xCF, 0x1F, 0x5D, 0x47, 0xBB, +0xEA, 0x6B, 0xE4, 0x07, 0xA0, 0x54, 0x4E, 0x7C, 0x14, 0x76, 0x51, 0x48, 0x66, 0xD4, 0x8D, 0x48, +0x10, 0x84, 0xB8, 0x66, 0xB2, 0x6E, 0x96, 0x84, 0x46, 0x80, 0x38, 0x72, 0x49, 0x84, 0x66, 0xB8, +0x17, 0xD3, 0x19, 0x40, 0x53, 0xBC, 0xBB, 0x63, 0x91, 0xB7, 0x87, 0xE7, 0x97, 0x0B, 0xE7, 0xE5, +0x8F, 0x33, 0x36, 0x84, 0x7F, 0x67, 0xA3, 0xAB, 0xF9, 0xC9, 0xD5, 0x0C, 0x46, 0x87, 0x62, 0x3A, +0x7C, 0x73, 0x34, 0x7C, 0x03, 0x1F, 0x47, 0xFD, 0xCE, 0xC7, 0xE9, 0xEF, 0x43, 0xB1, 0xFC, 0x63, +0x70, 0x38, 0xBE, 0x3A, 0x19, 0x0E, 0x5F, 0xF6, 0x5E, 0x9C, 0x2D, 0xDE, 0xBD, 0xDC, 0x15, 0xE0, +0xC3, 0xD0, 0xB9, 0x7C, 0x3B, 0x77, 0xAE, 0xB6, 0xBE, 0x8B, 0x82, 0xD3, 0x60, 0xEE, 0x47, 0x57, +0xC3, 0x37, 0xEF, 0x2E, 0xEF, 0xAE, 0xA3, 0xAB, 0xD9, 0xE8, 0x5D, 0x7F, 0xFE, 0x7E, 0xEB, 0xED, +0xE8, 0xFD, 0xBB, 0x1F, 0x6E, 0xF1, 0xCF, 0xA7, 0x3F, 0xBD, 0x1F, 0x2F, 0x00, 0xE1, 0x98, 0x8D, +0xAE, 0x2E, 0x0F, 0xDF, 0x1E, 0xCE, 0xDE, 0x1F, 0xFA, 0x27, 0xF7, 0x93, 0xF0, 0xEC, 0xF0, 0xC7, +0xE1, 0x64, 0xB8, 0xE5, 0x63, 0x3C, 0x1B, 0x5F, 0x1E, 0x66, 0x2F, 0x5E, 0x9E, 0xCF, 0x08, 0x99, +0x8F, 0xDE, 0x9F, 0x8D, 0xFD, 0xA3, 0x67, 0xAF, 0xAE, 0x4E, 0x87, 0x64, 0x7E, 0xF6, 0xD3, 0xA5, +0x73, 0xFB, 0xE3, 0xCB, 0xA3, 0x63, 0xFF, 0xFA, 0xA7, 0xEB, 0xDD, 0xE3, 0xED, 0xDE, 0xB7, 0xDF, +0xBE, 0x0E, 0xCE, 0x09, 0x1D, 0xDF, 0x7D, 0x1A, 0xCE, 0x8E, 0x16, 0xCF, 0x1F, 0xD2, 0xF1, 0xFC, +0xC5, 0x1D, 0xED, 0xBD, 0x65, 0x1F, 0x5F, 0x3C, 0xBC, 0x86, 0xDF, 0x8B, 0x8B, 0xCE, 0x64, 0xD4, +0x4F, 0xAF, 0xDE, 0xBC, 0x78, 0xBB, 0x95, 0x7E, 0xF7, 0x2C, 0x3E, 0x3C, 0x3E, 0xBE, 0x8B, 0x26, +0x17, 0xBD, 0x28, 0xB8, 0x9D, 0xF2, 0xE7, 0xDB, 0x3C, 0xBE, 0x9E, 0x65, 0xEF, 0x7F, 0x7F, 0xF6, +0xD3, 0xBC, 0x77, 0x8E, 0xD1, 0xF5, 0xBC, 0xF3, 0xF0, 0xE9, 0xE1, 0xF9, 0x7C, 0x7C, 0x7A, 0x77, +0x16, 0xA2, 0xFB, 0xB3, 0x33, 0xFF, 0x53, 0xD4, 0x09, 0xD1, 0x77, 0xE7, 0xE3, 0x10, 0x25, 0xFD, +0xAB, 0x60, 0xD8, 0xEB, 0x1C, 0x6D, 0x0D, 0x77, 0x78, 0x72, 0x79, 0x44, 0x8F, 0xB7, 0x3F, 0x8E, +0x9E, 0x1F, 0x1E, 0xF6, 0xD9, 0xE4, 0xF7, 0xAD, 0x1F, 0x6F, 0x77, 0x7F, 0xBC, 0xDA, 0x7D, 0x33, +0x79, 0x33, 0x1C, 0xED, 0x1C, 0x5E, 0xA1, 0xEB, 0xD1, 0x9B, 0xE1, 0x74, 0x67, 0x32, 0x9F, 0xBF, +0x7C, 0x39, 0xFE, 0x21, 0x18, 0x7E, 0x4A, 0x86, 0xE7, 0x8B, 0xE1, 0xFD, 0xC9, 0xD5, 0xF0, 0xB4, +0xF3, 0xF2, 0xE4, 0xB5, 0xD3, 0x1F, 0x5D, 0x6F, 0xCF, 0x5E, 0xEF, 0x2E, 0x0E, 0xD3, 0x93, 0xE1, +0x9B, 0x43, 0x67, 0xF6, 0x53, 0x27, 0x42, 0xEF, 0xD9, 0xD1, 0xF6, 0xEC, 0xC5, 0x2E, 0xB9, 0xB8, +0x46, 0xC3, 0x17, 0x87, 0x3F, 0xA5, 0xE4, 0x32, 0x3A, 0xBD, 0x72, 0x86, 0xC3, 0x57, 0xE7, 0xF8, +0x87, 0xA3, 0x6D, 0xF4, 0x72, 0xCB, 0x7F, 0x07, 0xFA, 0xBF, 0xFA, 0x19, 0x7F, 0xDB, 0x19, 0x2E, +0xCE, 0x9D, 0xD0, 0xFF, 0x0E, 0x8F, 0x4F, 0xAF, 0xC7, 0xF2, 0x76, 0x4E, 0xC2, 0x1F, 0xC6, 0xB7, +0xA3, 0xEC, 0x4D, 0x74, 0x74, 0x64, 0x6A, 0x94, 0x75, 0x13, 0x1C, 0x63, 0xC4, 0xEB, 0xB1, 0xAA, +0x74, 0x0E, 0xB0, 0xAD, 0xCA, 0x0A, 0x73, 0x27, 0x15, 0xD1, 0xB2, 0x1B, 0x60, 0x9F, 0x25, 0x48, +0xEE, 0x01, 0x04, 0x9C, 0x08, 0x13, 0x5B, 0x7D, 0x2F, 0xC3, 0xA7, 0xA6, 0xA2, 0xA7, 0x86, 0x68, +0xA0, 0x19, 0x85, 0x23, 0x44, 0x84, 0x02, 0xCE, 0x1D, 0xF1, 0x71, 0x37, 0x26, 0xF7, 0x38, 0xEC, +0x4A, 0x64, 0xD7, 0x31, 0x97, 0xD2, 0xD9, 0x8A, 0x6D, 0x88, 0x92, 0x48, 0x51, 0x2D, 0x16, 0x82, +0x8F, 0xC8, 0x17, 0x21, 0x1F, 0x5C, 0x26, 0x82, 0xCF, 0xDC, 0x77, 0x58, 0xD2, 0x9D, 0x64, 0xB3, +0x29, 0xB9, 0x07, 0x6F, 0x9E, 0x12, 0x4A, 0x38, 0xD6, 0xFA, 0xE9, 0xEA, 0xFB, 0x82, 0xCC, 0x2D, +0x7E, 0x98, 0x26, 0x28, 0xC2, 0xA9, 0xF6, 0x37, 0xC9, 0x2C, 0xA7, 0x09, 0x8B, 0x96, 0x55, 0x04, +0xE4, 0xAC, 0x36, 0x59, 0xAD, 0xBE, 0xC8, 0xE2, 0x90, 0x21, 0x10, 0xB3, 0x25, 0x6C, 0xA8, 0x60, +0x9A, 0x08, 0xB7, 0x2A, 0x83, 0x6A, 0xE1, 0x66, 0x5B, 0xE0, 0x96, 0x0D, 0xB7, 0xDE, 0xDA, 0xA9, +0x5C, 0xB7, 0x2B, 0xF7, 0x8A, 0x60, 0x5F, 0x57, 0x7D, 0x2D, 0x1E, 0xD4, 0x62, 0xDD, 0x17, 0x1C, +0x54, 0xDA, 0x7E, 0xB8, 0x3A, 0x44, 0x45, 0x86, 0x8A, 0x01, 0x15, 0xA5, 0xFB, 0xBB, 0x4E, 0x2D, +0x54, 0xC0, 0xBE, 0xD5, 0x17, 0x58, 0xA6, 0x41, 0xEB, 0x8B, 0x38, 0x81, 0xDB, 0xC0, 0x8B, 0xCF, +0xD0, 0x2C, 0x65, 0x6A, 0xD2, 0x06, 0x9A, 0x65, 0xBA, 0x53, 0x22, 0x54, 0x39, 0x4F, 0xF2, 0x5A, +0x92, 0x7E, 0x2C, 0x15, 0x80, 0x4B, 0x6E, 0x9E, 0x09, 0x6E, 0x3E, 0xAB, 0xD5, 0xED, 0xDD, 0xAF, +0x72, 0x1E, 0x76, 0x9C, 0xAF, 0x56, 0xB6, 0xDA, 0x5B, 0xE6, 0xE3, 0xBE, 0x03, 0xFF, 0x8A, 0xB4, +0xFB, 0xBC, 0x62, 0x61, 0xF2, 0x4C, 0xFC, 0x14, 0x0C, 0x02, 0x9D, 0x3A, 0x70, 0x7B, 0xE7, 0xBB, +0xE7, 0xC1, 0xA4, 0x00, 0x2A, 0xC1, 0x9E, 0x86, 0x27, 0x28, 0x20, 0x59, 0xEA, 0x3E, 0x73, 0xBE, +0x52, 0xFA, 0x84, 0xEB, 0x03, 0xD9, 0x8B, 0xCB, 0x55, 0x93, 0xCA, 0x62, 0xD3, 0x98, 0x50, 0x6D, +0x2B, 0xD5, 0xC4, 0x7D, 0xA3, 0xA4, 0x34, 0xCC, 0x7A, 0xAA, 0x07, 0x17, 0xA9, 0x4C, 0x53, 0xEC, +0x5F, 0x3A, 0x5F, 0x2D, 0x79, 0x82, 0x68, 0x3A, 0x65, 0x49, 0xE4, 0x26, 0x8C, 0x23, 0x8E, 0x0D, +0xC7, 0x5C, 0xF5, 0x9D, 0x36, 0xC0, 0xF6, 0xAE, 0x13, 0xE0, 0x99, 0xB9, 0x5A, 0xED, 0xF5, 0x20, +0xA9, 0xC9, 0x2A, 0xC6, 0x4F, 0x48, 0xCC, 0xF7, 0xA7, 0x19, 0xF5, 0x05, 0x0F, 0xDA, 0x0C, 0x1B, +0xD8, 0x5C, 0x26, 0x98, 0x67, 0x09, 0xD5, 0x02, 0xE6, 0x67, 0xC2, 0xD8, 0xED, 0x19, 0xE6, 0x27, +0xCA, 0xEE, 0x0F, 0x1F, 0x5E, 0x04, 0xB0, 0x63, 0x55, 0x22, 0xF8, 0xAD, 0x08, 0xE0, 0xC0, 0x70, +0x5E, 0x8E, 0xD3, 0xD8, 0x0F, 0x09, 0x06, 0x88, 0xBC, 0xC4, 0x0F, 0x06, 0xB6, 0x78, 0x89, 0x88, +0x6D, 0xB1, 0x6E, 0x14, 0xBB, 0x00, 0x46, 0xCD, 0xE5, 0x1D, 0x28, 0x01, 0x79, 0xF8, 0x03, 0xBF, +0xB1, 0x88, 0x47, 0xE1, 0x63, 0x90, 0xEF, 0x26, 0xFB, 0xE8, 0xA0, 0xDB, 0x77, 0xD1, 0x3E, 0x39, +0xE8, 0x83, 0x7B, 0xD5, 0xA8, 0xAB, 0x73, 0x7F, 0x20, 0x21, 0xBE, 0xCA, 0x1D, 0x4E, 0x1C, 0x23, +0x88, 0x95, 0x5B, 0x90, 0x22, 0xBE, 0xE5, 0x38, 0x1B, 0x1E, 0x3E, 0x40, 0x21, 0x86, 0x73, 0xF5, +0x93, 0xCB, 0xCB, 0xF3, 0xCB, 0x0F, 0x7A, 0x07, 0x77, 0xF4, 0x1B, 0x57, 0xD3, 0x3B, 0xD4, 0x74, +0xB9, 0x9D, 0xE0, 0x69, 0x82, 0xD3, 0xF9, 0x05, 0xE2, 0x73, 0x23, 0xB0, 0xEF, 0x50, 0x98, 0xD5, +0x05, 0x21, 0x06, 0x56, 0x2C, 0x72, 0x8F, 0xE2, 0x85, 0xF6, 0x03, 0xA8, 0xF9, 0x18, 0x71, 0x34, +0xE0, 0x36, 0x8A, 0x63, 0x4C, 0x03, 0x43, 0x8F, 0x01, 0x51, 0xB7, 0xB0, 0x69, 0x25, 0x50, 0x7D, +0xE2, 0x94, 0xA7, 0x36, 0x0A, 0x60, 0xF9, 0xE2, 0x6A, 0xAC, 0x5B, 0x7A, 0x4F, 0xF8, 0x91, 0x0E, +0xBC, 0x21, 0x73, 0x25, 0xA8, 0x30, 0x0F, 0x34, 0xA9, 0x4F, 0x32, 0xCE, 0x19, 0xD5, 0xCD, 0x01, +0xB3, 0x09, 0xA5, 0x38, 0x39, 0x1D, 0xBF, 0x7E, 0xE5, 0xE9, 0x97, 0x8A, 0x11, 0xED, 0x15, 0x49, +0x01, 0x45, 0x5E, 0x51, 0x7E, 0xC8, 0xD1, 0x9C, 0x84, 0x81, 0xC1, 0xCC, 0x81, 0x20, 0xE1, 0x4B, +0x12, 0xB2, 0x3A, 0x01, 0x0A, 0xBE, 0xAD, 0x6A, 0xD3, 0x29, 0x28, 0x43, 0xB7, 0x7C, 0x3B, 0xCA, +0x42, 0x4E, 0xE2, 0x10, 0x7B, 0x1B, 0x7D, 0x98, 0x51, 0x14, 0x01, 0x4C, 0xE4, 0x66, 0x01, 0x23, +0x81, 0xA7, 0xAB, 0x08, 0xA5, 0xE2, 0x5A, 0xEB, 0x29, 0xBE, 0x3A, 0x25, 0x68, 0x9C, 0x12, 0xD4, +0x71, 0x95, 0xC0, 0x81, 0x5D, 0x15, 0xC5, 0x30, 0xCB, 0x8F, 0x2A, 0x60, 0x01, 0x9E, 0x22, 0xE0, +0xE4, 0x2D, 0x68, 0x13, 0x56, 0x7B, 0x6D, 0x07, 0x05, 0xEA, 0xA0, 0xB4, 0xA9, 0x91, 0xB4, 0xAE, +0x11, 0x75, 0xBB, 0x6D, 0xC8, 0xA9, 0x42, 0x4E, 0x9A, 0xC8, 0x49, 0x1D, 0xF9, 0x48, 0x1A, 0x49, +0x1B, 0x72, 0xA2, 0x90, 0xC3, 0x86, 0x88, 0xA1, 0x14, 0x51, 0x85, 0xBD, 0xAE, 0xD0, 0x26, 0x08, +0x04, 0xD8, 0x61, 0x5D, 0x4C, 0x98, 0x81, 0x97, 0xA2, 0x49, 0x88, 0x03, 0x6F, 0xC3, 0x81, 0x99, +0xA8, 0xB4, 0xBD, 0x2D, 0xA7, 0xE5, 0x8C, 0x50, 0x9D, 0x91, 0x35, 0x19, 0xCC, 0xEA, 0x0C, 0x6A, +0x23, 0x74, 0x87, 0xB5, 0x36, 0x06, 0x33, 0x30, 0x26, 0x9B, 0x51, 0x3F, 0x24, 0xFE, 0xAD, 0x57, +0x79, 0x8B, 0xB9, 0x24, 0xA5, 0x85, 0x5A, 0x54, 0x06, 0xBA, 0xAB, 0x24, 0xAC, 0x96, 0x60, 0x50, +0xE8, 0x7B, 0x65, 0x65, 0xAD, 0x04, 0xA8, 0x8D, 0xEF, 0xB1, 0x7F, 0xC4, 0xA2, 0x08, 0x09, 0xDB, +0x4D, 0x81, 0x83, 0x7C, 0xA2, 0x9B, 0x2B, 0x8B, 0xB5, 0xE2, 0x3C, 0xE1, 0x22, 0x56, 0xDA, 0xCE, +0xE2, 0xD4, 0x00, 0x97, 0xF3, 0x7C, 0x5B, 0xE8, 0x30, 0xB5, 0x41, 0x8F, 0x33, 0x3E, 0xFF, 0xBC, +0x0B, 0x15, 0x06, 0xAA, 0x50, 0x3E, 0x38, 0x37, 0xB9, 0x24, 0x8F, 0x7D, 0xEA, 0x7C, 0xD4, 0x74, +0x2A, 0xA5, 0x64, 0xEA, 0x81, 0x0A, 0x1B, 0xD6, 0x69, 0x0E, 0x68, 0xA5, 0x0B, 0xB9, 0x87, 0x88, +0x3D, 0x4D, 0xEB, 0x87, 0x5D, 0xA4, 0xD8, 0xA5, 0xAF, 0x56, 0x96, 0x2F, 0xE4, 0x99, 0x23, 0x3A, +0xC3, 0x7F, 0x5F, 0xA0, 0x8A, 0x67, 0xE9, 0x00, 0x16, 0xF5, 0x7A, 0xC6, 0x81, 0xFB, 0x8B, 0x6D, +0x7C, 0xF8, 0xD5, 0xBE, 0xE9, 0x98, 0xE6, 0xC1, 0x97, 0x3D, 0xA9, 0x71, 0x83, 0x9B, 0x1F, 0xFA, +0x37, 0x16, 0x02, 0xB0, 0xFD, 0x8D, 0xF9, 0x8B, 0x2D, 0xC1, 0x0D, 0xD8, 0xE0, 0x8E, 0x41, 0x66, +0x11, 0x27, 0x09, 0x83, 0x63, 0x53, 0x0D, 0x6D, 0x6E, 0x1A, 0xDC, 0x43, 0x8D, 0x6B, 0xED, 0xF0, +0x8E, 0x6E, 0x43, 0xDC, 0x5A, 0xAD, 0xD6, 0x83, 0xE1, 0x38, 0xC1, 0x58, 0xC5, 0xDA, 0x12, 0x20, +0xB9, 0x17, 0x52, 0x43, 0xC3, 0x48, 0xA5, 0xDC, 0x32, 0xA3, 0xE8, 0xA6, 0x9D, 0x26, 0xBE, 0xA7, +0xB4, 0x78, 0x50, 0xC0, 0x3C, 0x88, 0x8A, 0x15, 0x4D, 0x54, 0x45, 0x3D, 0x20, 0xF0, 0xC8, 0x2B, +0xCC, 0x01, 0xCF, 0x79, 0xC2, 0x56, 0x05, 0x07, 0xC2, 0x32, 0xDD, 0xD8, 0x79, 0x26, 0xF3, 0x74, +0x91, 0xCA, 0x74, 0x6B, 0xBE, 0xBE, 0x2C, 0x5B, 0x0C, 0x58, 0xAF, 0x39, 0xC3, 0xD7, 0x7B, 0x24, +0x9A, 0x69, 0x35, 0xBE, 0xC4, 0x1F, 0xEF, 0x6B, 0x11, 0xA9, 0x37, 0x7F, 0xF3, 0x27, 0xC0, 0x1D, +0x98, 0x0C, 0xB6, 0x29, 0x5B, 0x18, 0x66, 0xE7, 0x6B, 0x5D, 0x93, 0x14, 0x3D, 0x3D, 0x42, 0xF7, +0x79, 0xA3, 0x29, 0x32, 0xE1, 0x40, 0x13, 0x73, 0x95, 0x76, 0x8B, 0x05, 0xD5, 0xE2, 0xA1, 0x8C, +0xB3, 0x81, 0x56, 0x64, 0x58, 0xD5, 0xE2, 0xE8, 0x5A, 0x6F, 0xFF, 0xEB, 0x46, 0xA0, 0xB7, 0x88, +0xB9, 0xAC, 0x82, 0x74, 0x16, 0x82, 0x9C, 0xF8, 0xE9, 0x08, 0x1C, 0x12, 0x80, 0xB3, 0xB5, 0xD8, +0x69, 0x25, 0x06, 0x31, 0x0F, 0x0C, 0xBF, 0xEE, 0xE7, 0x7B, 0xA2, 0x28, 0xDE, 0xBF, 0x50, 0xD5, +0xCE, 0x5E, 0x4F, 0xCE, 0xC0, 0xDA, 0x1F, 0x7B, 0x0F, 0x5C, 0x1E, 0x02, 0x74, 0xAB, 0xCC, 0xAF, +0x13, 0x16, 0x3C, 0xD4, 0xB2, 0x72, 0x7A, 0xF8, 0x70, 0x14, 0xA2, 0x34, 0x3D, 0x43, 0x11, 0x9C, +0xEF, 0x47, 0xBA, 0x99, 0x5B, 0xE3, 0xBE, 0xB3, 0xB9, 0xD9, 0x44, 0x4A, 0x70, 0x04, 0x45, 0xB8, +0xE2, 0x0A, 0x7C, 0xD5, 0x74, 0x53, 0x20, 0xBC, 0xB9, 0xD9, 0xC6, 0x98, 0x78, 0xE0, 0xF1, 0x39, +0xAE, 0x28, 0x44, 0x80, 0x22, 0xD6, 0xFC, 0x4F, 0xDC, 0xA9, 0x8C, 0xF3, 0x94, 0x56, 0x03, 0x38, +0xF3, 0x31, 0xDB, 0xC7, 0xB9, 0xE1, 0x96, 0xAC, 0x07, 0xAD, 0x0A, 0xA5, 0xFF, 0x0F, 0xCB, 0x2A, +0x81, 0x3C, 0xC5, 0x71, 0x68, 0x5A, 0x61, 0x0B, 0xC7, 0x38, 0xC4, 0x1C, 0x97, 0xFC, 0x86, 0xAD, +0xFC, 0x66, 0xFF, 0x0F, 0xBF, 0x95, 0x9D, 0x33, 0x11, 0x25, 0xCA, 0xBA, 0x4B, 0x4A, 0x10, 0x90, +0x3B, 0xDD, 0xB4, 0x98, 0xD7, 0xA4, 0x00, 0x35, 0x23, 0x0B, 0xC3, 0x31, 0x8B, 0x0F, 0x9E, 0x58, +0x77, 0xCB, 0xF5, 0x7C, 0x50, 0xB0, 0x59, 0x6D, 0xB1, 0xFC, 0x56, 0xA2, 0xAF, 0xF0, 0x94, 0x1F, +0x3C, 0x05, 0x78, 0x9A, 0x6C, 0xB5, 0xC7, 0x0A, 0x3C, 0x6C, 0x83, 0xF2, 0x60, 0xF5, 0xE7, 0x8E, +0x6F, 0xA5, 0xE5, 0xEC, 0xBA, 0xC3, 0x06, 0x08, 0xC6, 0xB9, 0x92, 0x3C, 0xA1, 0x24, 0x0B, 0xB5, +0x06, 0xA0, 0x6A, 0x5D, 0x74, 0x27, 0x5E, 0xD0, 0xD1, 0xE3, 0xFB, 0x6A, 0x8D, 0xB3, 0xD8, 0x4B, +0xD5, 0x12, 0x31, 0x90, 0xC5, 0xD7, 0x2E, 0xA5, 0x71, 0xDD, 0xA8, 0x28, 0x46, 0x90, 0xCD, 0xA6, +0xD3, 0x14, 0xF3, 0x77, 0x22, 0x24, 0x59, 0x61, 0x39, 0x3F, 0x95, 0x21, 0x69, 0x00, 0x53, 0x1A, +0xB1, 0x2C, 0xC5, 0x2C, 0xE3, 0x8D, 0x14, 0x63, 0x94, 0xC2, 0xEC, 0x05, 0x7F, 0xFC, 0x51, 0x4E, +0xF6, 0x83, 0x4E, 0x52, 0x4D, 0xAF, 0xF7, 0xD2, 0xDA, 0x64, 0x3F, 0xED, 0x84, 0xE0, 0xD0, 0xFF, +0xB1, 0xA5, 0xA0, 0xBA, 0xA5, 0xF8, 0xA2, 0x84, 0x96, 0x31, 0xB1, 0x19, 0xF3, 0x64, 0x21, 0x49, +0x6B, 0x3E, 0x2B, 0x0C, 0x5A, 0x37, 0x8B, 0xB2, 0xBD, 0xEE, 0xAB, 0xD4, 0xF2, 0xD7, 0x5D, 0xD9, +0x6F, 0xAD, 0x1A, 0x52, 0x43, 0x50, 0x05, 0xAD, 0xBF, 0x62, 0x0B, 0x9C, 0x1C, 0xA1, 0x14, 0x1B, +0x90, 0x3C, 0xCB, 0xB8, 0x23, 0xA1, 0xA6, 0x9B, 0xB4, 0xEC, 0x02, 0x25, 0x20, 0x05, 0xCE, 0x33, +0x38, 0xA3, 0xA2, 0x56, 0x03, 0xF9, 0xB2, 0xC6, 0x09, 0xD8, 0x16, 0xFD, 0x26, 0x48, 0x7D, 0xAC, +0x4A, 0x53, 0xC3, 0xB4, 0x30, 0xDC, 0x35, 0x8B, 0x2F, 0x12, 0x16, 0xA3, 0x99, 0xEC, 0xCD, 0x60, +0x4D, 0xB8, 0x87, 0xA0, 0x66, 0x6D, 0x38, 0x82, 0x60, 0xA5, 0x8D, 0xA0, 0xF0, 0x9B, 0xAA, 0xB5, +0xA1, 0x96, 0x9E, 0xA7, 0x43, 0xE9, 0x4B, 0x4F, 0x65, 0x0D, 0x24, 0x1E, 0xCB, 0x26, 0x86, 0xAA, +0x42, 0x68, 0x7E, 0x0F, 0xE0, 0x6E, 0xCE, 0x80, 0xEC, 0xB3, 0x01, 0xEB, 0x74, 0x4C, 0x55, 0xBD, +0x7B, 0x1E, 0xB4, 0x3F, 0xEC, 0x46, 0x16, 0x9C, 0x20, 0x54, 0x33, 0xB3, 0x18, 0xDC, 0x92, 0x40, +0x71, 0xA0, 0x1C, 0xC9, 0xDA, 0xD3, 0xAC, 0xB7, 0x5C, 0x65, 0xCE, 0x7E, 0xAA, 0x06, 0xC1, 0xB2, +0xCE, 0x80, 0x7A, 0x66, 0xBD, 0xD4, 0xE0, 0x66, 0xBA, 0x20, 0xDC, 0x9F, 0x8B, 0x00, 0xE4, 0x83, +0x56, 0x75, 0x0E, 0xC5, 0xAE, 0x2B, 0x47, 0x73, 0x1E, 0x55, 0xA3, 0x30, 0x1F, 0x7E, 0x4C, 0xF3, +0x81, 0x9F, 0x16, 0xA3, 0xFB, 0x1A, 0x90, 0xD1, 0x02, 0xCC, 0xE8, 0x34, 0x1F, 0x12, 0x4A, 0x0A, +0x3A, 0x05, 0xB0, 0xF8, 0x8C, 0xE3, 0x7C, 0x14, 0xCF, 0x8B, 0xD1, 0x1C, 0xDF, 0x97, 0x78, 0xAC, +0x80, 0x06, 0x58, 0x77, 0x95, 0x8D, 0x6D, 0x38, 0xAB, 0x7C, 0xD0, 0xAF, 0xE4, 0x4F, 0xFE, 0x43, +0xF9, 0x63, 0x3A, 0x2B, 0xA4, 0x89, 0x8B, 0xD1, 0x8C, 0x14, 0xB2, 0x4C, 0xA2, 0xF8, 0xB3, 0x9C, +0x84, 0xB5, 0x5E, 0xB9, 0xD6, 0xEB, 0xF2, 0xBF, 0x6A, 0x47, 0xB9, 0xE9, 0x1A, 0xD3, 0xBA, 0x3F, +0xC2, 0xCC, 0x17, 0x9F, 0x67, 0x2C, 0x90, 0x35, 0xA6, 0x69, 0x45, 0xC6, 0xD4, 0x82, 0x3A, 0xD0, +0xAC, 0xFB, 0x69, 0xF6, 0x6F, 0x5B, 0xD4, 0xE3, 0x93, 0x57, 0x27, 0xE3, 0x93, 0x7A, 0x41, 0x1D, +0x1A, 0x0D, 0x93, 0x8A, 0x15, 0xD7, 0xEB, 0xA2, 0x50, 0x0B, 0x49, 0x51, 0xC0, 0x5E, 0x37, 0x37, +0x95, 0x5F, 0xFC, 0x34, 0x3A, 0x3F, 0xB3, 0x63, 0x94, 0x80, 0x47, 0xA2, 0x06, 0x73, 0x91, 0x22, +0xD1, 0x3C, 0xF8, 0xC7, 0x93, 0x5A, 0x19, 0x2F, 0x5F, 0x3B, 0xB8, 0x7C, 0x65, 0xA9, 0xD3, 0x54, +0x9F, 0x3C, 0x97, 0x75, 0x67, 0xFE, 0x84, 0x08, 0x92, 0xD3, 0xB4, 0x4A, 0x54, 0x83, 0x82, 0x9D, +0x7A, 0x98, 0xE7, 0x77, 0x59, 0x5B, 0x23, 0x35, 0x35, 0x2D, 0x3E, 0x27, 0x69, 0xBD, 0x81, 0x69, +0x04, 0x85, 0xBF, 0xA9, 0xED, 0x55, 0x31, 0x52, 0xE4, 0xD6, 0x6B, 0x6F, 0xF5, 0xCA, 0x48, 0xC5, +0x07, 0x0B, 0x89, 0x88, 0x59, 0x65, 0xDB, 0xEA, 0x6E, 0x74, 0xC8, 0x3D, 0x84, 0xEA, 0x16, 0xFD, +0xC7, 0xE6, 0x49, 0x0B, 0xF3, 0xA4, 0x75, 0xF7, 0x2C, 0x29, 0x0E, 0x26, 0xC0, 0xC5, 0xED, 0xA0, +0x74, 0x9C, 0x76, 0x88, 0xF2, 0xC5, 0x76, 0x24, 0x1E, 0x09, 0x88, 0xF4, 0xF0, 0x06, 0xE0, 0x63, +0x2A, 0xD7, 0x3F, 0xA2, 0x3B, 0xA4, 0x9E, 0x20, 0x35, 0xD1, 0x24, 0xD0, 0xFF, 0x0D, 0x1C, 0xB8, +0x79, 0xD2, 0x53, 0xEB, 0x30, 0x6F, 0x87, 0x54, 0x61, 0x24, 0x85, 0xE1, 0xE3, 0x68, 0xC0, 0x1B, +0xC1, 0xA5, 0x8A, 0x38, 0xF5, 0xD8, 0x02, 0xC6, 0x9F, 0xBB, 0xA2, 0xC6, 0x6B, 0x17, 0x54, 0xF7, +0xBB, 0xCD, 0xCD, 0x27, 0x1D, 0xAF, 0x19, 0xE7, 0xAB, 0xFA, 0xA8, 0xE9, 0x51, 0x68, 0xAD, 0x63, +0x15, 0xC0, 0xC3, 0x90, 0x4D, 0x0C, 0xF1, 0xF0, 0x6A, 0x29, 0x6E, 0xCB, 0xA5, 0x2B, 0xD3, 0xFA, +0x8B, 0xBE, 0x15, 0x59, 0x7E, 0x3D, 0x6C, 0x2B, 0x0E, 0xEB, 0xE6, 0xDE, 0xDE, 0x47, 0x35, 0x3B, +0xAD, 0xF6, 0x8A, 0x46, 0x3A, 0x25, 0x3E, 0x08, 0xED, 0x14, 0xAB, 0x67, 0x2F, 0x06, 0xC4, 0x94, +0xDA, 0x4C, 0xD7, 0x45, 0x65, 0xEA, 0x87, 0x18, 0x25, 0x23, 0xD1, 0x03, 0xAB, 0xA4, 0xD7, 0x88, +0xA1, 0x9F, 0xF7, 0x55, 0xF1, 0xE1, 0x62, 0xE8, 0xFD, 0xCD, 0x95, 0x2E, 0x1E, 0xE8, 0x4F, 0x09, +0xC5, 0x81, 0x5E, 0x05, 0x52, 0xD9, 0xB3, 0xEA, 0x3D, 0xF9, 0xE8, 0xD5, 0x96, 0xF7, 0x66, 0x5A, +0x6D, 0x1B, 0x29, 0x6C, 0xA4, 0x1E, 0x03, 0xF6, 0xDA, 0xE1, 0x08, 0xE0, 0x08, 0xFA, 0x3B, 0x46, +0xD9, 0x2D, 0x22, 0x4F, 0x10, 0x21, 0xB0, 0x89, 0xE4, 0xAF, 0x65, 0xA1, 0x29, 0xB6, 0x94, 0x65, +0xC9, 0x3C, 0x5A, 0x83, 0x28, 0x7B, 0x37, 0x8B, 0x67, 0x3E, 0xC8, 0xC7, 0xB6, 0x90, 0xC2, 0xC0, +0x45, 0x24, 0xC9, 0x3D, 0x62, 0x43, 0xA2, 0x85, 0xA2, 0x88, 0x1A, 0xE1, 0x34, 0x95, 0x9A, 0x11, +0x9A, 0x7B, 0xCD, 0x02, 0x50, 0x1C, 0xA0, 0xF5, 0x22, 0x18, 0x89, 0x83, 0x40, 0x87, 0x02, 0x30, +0x9E, 0xE3, 0x28, 0x87, 0x70, 0x18, 0x0A, 0x10, 0x12, 0xA0, 0x2F, 0xE5, 0x65, 0x8C, 0x64, 0xB1, +0x4A, 0xE8, 0xCC, 0xEB, 0xF7, 0x1C, 0xEB, 0x31, 0xD9, 0xAB, 0x14, 0x8F, 0xD8, 0x94, 0x8F, 0xD1, +0x24, 0x35, 0xA0, 0xD6, 0x68, 0xD9, 0x01, 0xA0, 0x11, 0xE4, 0x78, 0x63, 0xCB, 0x6C, 0x47, 0x7F, +0xC7, 0x92, 0x5B, 0x9C, 0x18, 0x1B, 0xFD, 0x9C, 0x9F, 0x53, 0x28, 0x32, 0x43, 0xF8, 0xE5, 0x43, +0x5F, 0xBC, 0x85, 0x7D, 0x05, 0xCA, 0xCA, 0x29, 0xA7, 0x80, 0x3C, 0x67, 0x8B, 0x8B, 0x84, 0x50, +0xFE, 0x5A, 0x76, 0xC4, 0x39, 0x96, 0xAF, 0x9E, 0xFD, 0xC8, 0xAB, 0x2E, 0x1E, 0x0A, 0x2D, 0x45, +0x89, 0xE1, 0x36, 0x1E, 0x0D, 0x59, 0x13, 0xB8, 0x50, 0xA8, 0x78, 0xDC, 0xE5, 0x82, 0x50, 0x57, +0x3F, 0xE2, 0x49, 0xD8, 0x1D, 0xE9, 0x56, 0x84, 0x7C, 0x98, 0xA8, 0x3D, 0x30, 0x5F, 0x59, 0x22, +0x8C, 0xB9, 0xF5, 0xF8, 0x1A, 0x18, 0xDC, 0xC2, 0xF6, 0xAC, 0x30, 0x3F, 0xB3, 0xA3, 0xEB, 0x16, +0x81, 0x70, 0x0A, 0xAE, 0x1F, 0x9C, 0xD3, 0xF0, 0xC1, 0x85, 0xB4, 0xF9, 0x79, 0x3E, 0xC4, 0xBD, +0xB3, 0xCF, 0xF1, 0xF1, 0x7E, 0x8D, 0x8F, 0xF7, 0x6D, 0x7C, 0xE0, 0xA6, 0xFE, 0x60, 0x72, 0x05, +0x64, 0x5F, 0x23, 0x8A, 0x66, 0x38, 0x81, 0x05, 0x71, 0x08, 0xA8, 0xE4, 0x9F, 0x71, 0x96, 0xE0, +0xCF, 0x73, 0x36, 0x9A, 0x93, 0x29, 0x5F, 0xE7, 0x4F, 0xAD, 0xFE, 0x3B, 0x2E, 0x13, 0xFC, 0x04, +0x97, 0x45, 0x99, 0xDC, 0xC8, 0x6D, 0x2A, 0x7E, 0xB5, 0x3F, 0xBE, 0x41, 0xE5, 0xE3, 0x1B, 0x0E, +0xBF, 0xCA, 0x11, 0xAD, 0xBA, 0x2B, 0xFD, 0x0B, 0x9F, 0x48, 0x0C, 0x0E, 0x9C, 0x85, 0xB5, 0x4E, +0x93, 0x1E, 0x42, 0x7F, 0xF1, 0x0A, 0x58, 0x33, 0x14, 0x37, 0xD8, 0x5B, 0xAE, 0xE0, 0x40, 0x63, +0x41, 0x40, 0xAC, 0x05, 0x30, 0xED, 0xCB, 0xAA, 0xDB, 0x9E, 0x27, 0x58, 0x24, 0x62, 0x38, 0x12, +0x92, 0x7C, 0xEF, 0xC3, 0xC1, 0xE6, 0x4D, 0x07, 0x92, 0xA3, 0x07, 0x1F, 0xA6, 0x07, 0x83, 0xCD, +0x9B, 0x6F, 0xCC, 0xDE, 0x8C, 0x58, 0xA5, 0x70, 0x32, 0xCD, 0x82, 0xBA, 0x3E, 0xD0, 0x1B, 0x0F, +0x81, 0xFC, 0xF5, 0x2C, 0x5C, 0x86, 0x48, 0xB0, 0x3B, 0x21, 0x30, 0x7C, 0x84, 0x88, 0xCE, 0xE0, +0x43, 0xFA, 0xA8, 0x69, 0x82, 0xB4, 0xB5, 0x27, 0x66, 0x3A, 0x87, 0xBF, 0x3A, 0x04, 0xE0, 0x41, +0xCB, 0x3B, 0x05, 0x3D, 0xCB, 0x47, 0x3A, 0x1C, 0xC8, 0xDB, 0x63, 0x90, 0x3A, 0x05, 0xC2, 0x8D, +0x1A, 0xD4, 0x63, 0x1F, 0x44, 0xAD, 0xAA, 0x81, 0x51, 0xE0, 0xF6, 0xA8, 0xF9, 0xF3, 0xEB, 0x57, +0xA7, 0x9C, 0xC7, 0x97, 0x2A, 0xEE, 0x02, 0xAD, 0xE6, 0x42, 0x75, 0xAB, 0xE6, 0x92, 0x27, 0x0F, +0x45, 0x39, 0x26, 0x92, 0x8F, 0xF2, 0xF4, 0x9F, 0xCF, 0x27, 0x1F, 0xB1, 0x0F, 0x79, 0xED, 0x75, +0x0A, 0x49, 0x71, 0xCB, 0x16, 0xE8, 0xE3, 0xF1, 0x85, 0xBD, 0x6B, 0x3B, 0x50, 0xBB, 0x80, 0x92, +0xFD, 0xB9, 0x30, 0x88, 0xD5, 0x3F, 0x42, 0xDE, 0xFE, 0x67, 0xC8, 0x04, 0xC2, 0x5D, 0x0A, 0xF1, +0xAC, 0xC0, 0x6F, 0xE2, 0xCE, 0x13, 0xB6, 0x90, 0x68, 0x27, 0x49, 0x22, 0xEE, 0x68, 0x0C, 0x55, +0x94, 0x36, 0x81, 0xC5, 0x14, 0x43, 0x13, 0xC9, 0x70, 0xAA, 0x51, 0xC6, 0xB5, 0x34, 0x8B, 0x63, +0x96, 0xF0, 0x35, 0x7D, 0xD8, 0x7A, 0xF1, 0x84, 0xE8, 0x4D, 0x86, 0x33, 0x1C, 0xE4, 0xCB, 0x38, +0xA9, 0xEB, 0x45, 0x56, 0x79, 0xB0, 0x0E, 0x36, 0xFD, 0xE1, 0x26, 0xAF, 0xF9, 0x32, 0x4A, 0x45, +0xF8, 0xDD, 0xE8, 0xAB, 0x39, 0x48, 0x37, 0x07, 0xAA, 0x1E, 0xCD, 0xC2, 0x70, 0x35, 0x58, 0xA3, +0x05, 0xCD, 0x21, 0xE3, 0x4C, 0x3E, 0xEA, 0x5F, 0xFE, 0x96, 0x27, 0xC0, 0x86, 0x6F, 0x96, 0x56, +0xCD, 0xDB, 0x6B, 0x62, 0x73, 0xB9, 0x03, 0x99, 0xD7, 0x16, 0x8E, 0xF9, 0x30, 0xE2, 0x88, 0x0B, +0x93, 0x10, 0xBE, 0xA7, 0x0C, 0xE8, 0xA9, 0x94, 0xCE, 0x6D, 0x1F, 0x85, 0xA1, 0x78, 0x01, 0x0A, +0x06, 0x92, 0x02, 0x5A, 0x96, 0x5A, 0x82, 0x48, 0x1A, 0x33, 0x9A, 0xE2, 0x31, 0x78, 0xA3, 0x69, +0x39, 0x22, 0x9F, 0x29, 0xD9, 0xF2, 0xDE, 0x51, 0xE4, 0xCE, 0x9A, 0x78, 0xA6, 0x55, 0xCE, 0x36, +0x37, 0xA9, 0x5D, 0xB0, 0x6F, 0x14, 0x48, 0xA9, 0x88, 0x38, 0x86, 0x29, 0xCA, 0x72, 0x28, 0x2E, +0x9B, 0xBA, 0x71, 0xAC, 0x0D, 0x63, 0x03, 0x6B, 0x84, 0xC2, 0xE1, 0xD4, 0x17, 0xC6, 0xA8, 0x6E, +0xD4, 0x54, 0x1E, 0x4B, 0x3D, 0xB1, 0x7D, 0x50, 0x0A, 0xF2, 0x64, 0xE5, 0x91, 0x77, 0xC0, 0xBA, +0x2E, 0xEA, 0x57, 0x2C, 0x3A, 0x01, 0x14, 0xA5, 0x35, 0xB2, 0x65, 0x0D, 0x65, 0x22, 0xAF, 0x00, +0x0F, 0x70, 0x98, 0x62, 0xAD, 0xB9, 0x7F, 0x9D, 0x8D, 0xB2, 0x71, 0x06, 0x98, 0x56, 0xEC, 0x33, +0x51, 0x07, 0x4E, 0x02, 0xB5, 0xA0, 0x03, 0x59, 0x9E, 0x78, 0x42, 0xF3, 0x11, 0xE6, 0x73, 0x16, +0x1C, 0xE8, 0x07, 0xBA, 0xAB, 0xC3, 0xFF, 0x4D, 0xDD, 0x82, 0x5D, 0x98, 0xFA, 0x2C, 0xC0, 0x57, +0x97, 0x2F, 0x20, 0xFA, 0x82, 0x4A, 0x31, 0xE5, 0x06, 0x81, 0x24, 0xE4, 0xE9, 0x9D, 0x16, 0x48, +0x41, 0xFE, 0x03, 0xB9, 0x31, 0x07, 0x4D, 0x93, 0xC1, 0x8B, 0x35, 0xA3, 0x6C, 0x98, 0x94, 0xCD, +0xA8, 0xBC, 0x77, 0x71, 0x81, 0x38, 0x7F, 0x83, 0xC0, 0x8D, 0xFA, 0x0E, 0x51, 0x12, 0x3E, 0x62, +0xD5, 0x68, 0xD2, 0x88, 0x31, 0x35, 0x0A, 0x18, 0x18, 0x41, 0x96, 0x84, 0x1D, 0x24, 0x9E, 0x42, +0x34, 0x8F, 0x4A, 0x45, 0xF9, 0x69, 0x9A, 0xEE, 0x5F, 0x22, 0x4B, 0x54, 0x54, 0x57, 0xE9, 0x88, +0x27, 0xD2, 0x44, 0xD6, 0xE8, 0xF1, 0x5C, 0xA4, 0x53, 0x2C, 0x83, 0x5E, 0xF3, 0xCB, 0x73, 0x96, +0x8E, 0xE2, 0x38, 0x24, 0x2A, 0x50, 0xF7, 0xE0, 0x61, 0xFB, 0x62, 0xD1, 0x15, 0xAF, 0x9A, 0xBB, +0x70, 0x82, 0x52, 0x61, 0xA0, 0xB7, 0x70, 0xA8, 0x9A, 0x40, 0x2B, 0x15, 0xAF, 0xD5, 0xD7, 0xBC, +0xB4, 0x32, 0x55, 0x63, 0xCD, 0x4D, 0x9B, 0x74, 0x9A, 0x7C, 0xD6, 0x1C, 0x6B, 0x6F, 0x67, 0x0D, +0x84, 0x26, 0xE2, 0xA5, 0x32, 0xE4, 0x1E, 0x48, 0xD1, 0xE5, 0x69, 0x45, 0x37, 0x56, 0x0F, 0x0D, +0x76, 0x9C, 0xA5, 0x73, 0x63, 0x09, 0xAC, 0xBB, 0xDC, 0x52, 0xBA, 0x72, 0xB1, 0xA5, 0x2E, 0xDD, +0xA5, 0x56, 0xE1, 0x8A, 0xAE, 0xC8, 0x29, 0x75, 0xDE, 0xFE, 0xF8, 0x43, 0xCC, 0x2A, 0xC7, 0x92, +0xB3, 0xA6, 0x6F, 0xAD, 0xD4, 0x13, 0xE1, 0xA2, 0x74, 0x16, 0x16, 0xB3, 0x1E, 0xAE, 0x06, 0x7B, +0x3D, 0xD5, 0x44, 0x15, 0xAF, 0xE3, 0x35, 0x12, 0x78, 0x22, 0x87, 0xEA, 0xF9, 0x7B, 0x0F, 0x18, +0x4E, 0x21, 0x36, 0xD9, 0xD0, 0x75, 0xD5, 0xBF, 0x70, 0x58, 0xEB, 0xBE, 0xCA, 0xAF, 0x2D, 0xEA, +0xF9, 0xF7, 0x16, 0xD7, 0x49, 0xEE, 0x83, 0x37, 0xB5, 0x65, 0x98, 0xA2, 0xE8, 0x55, 0x5E, 0xAD, +0xF6, 0x7A, 0x4F, 0xBC, 0xC6, 0xD7, 0xF3, 0xC3, 0xCC, 0x81, 0x1A, 0xD8, 0x25, 0x77, 0x82, 0x33, +0x2B, 0x5F, 0x44, 0xE9, 0x03, 0xF5, 0x45, 0x6C, 0x2D, 0xA9, 0xCC, 0xE1, 0x86, 0x1A, 0xCD, 0xB7, +0xDA, 0x69, 0xAE, 0x2A, 0x26, 0x7B, 0xEA, 0xFB, 0x9A, 0xE2, 0xB1, 0xA3, 0xC6, 0xF2, 0xD7, 0x4E, +0xF5, 0x2A, 0x01, 0x04, 0x82, 0x16, 0x5F, 0xE8, 0xA5, 0x08, 0x37, 0x9A, 0xEC, 0xF1, 0xCB, 0x29, +0x90, 0x80, 0x0D, 0xD5, 0xAE, 0x2C, 0x6E, 0x07, 0xA8, 0xB4, 0xBE, 0xBE, 0xA8, 0x2A, 0x83, 0xF5, +0xE5, 0xA2, 0xED, 0x2A, 0x5F, 0x2A, 0xD5, 0xBE, 0x88, 0x51, 0xD1, 0x20, 0xF2, 0xDD, 0x99, 0xDC, +0xDF, 0x7C, 0x9D, 0xF6, 0x24, 0x9A, 0xC2, 0x80, 0x81, 0x10, 0x17, 0x3E, 0xE4, 0x37, 0x58, 0xFF, +0x04, 0x63, 0x8F, 0x76, 0xB0, 0xD1, 0x2A, 0x00, 0x00 }; #define SPIFFS_MAXLENGTH_FILEPATH 32 @@ -442,7 +443,7 @@ void SPIFFSEditor::handleRequest(AsyncWebServerRequest *request){ #ifdef ESP32 File dir = _fs.open(path); #else - Dir dir = _fs.openDir(path); + fs::Dir dir = _fs.openDir(path); #endif path = String(); String output = "["; diff --git a/src/WebRequest.cpp b/src/WebRequest.cpp index bbce5ca4c..822a6a7f5 100644 --- a/src/WebRequest.cpp +++ b/src/WebRequest.cpp @@ -96,6 +96,10 @@ AsyncWebServerRequest::~AsyncWebServerRequest(){ if(_tempFile){ _tempFile.close(); } + + if(_itemBuffer){ + free(_itemBuffer); + } } void AsyncWebServerRequest::_onData(void *buf, size_t len){ diff --git a/src/edit.htm b/src/edit.htm index 43d498455..49d9c00cf 100644 --- a/src/edit.htm +++ b/src/edit.htm @@ -1,627 +1 @@ - - - - -ESP Editor - - - - - - -
-
-
-
- - - - +ESP Editor
\ No newline at end of file From 37273f97403fb9599e72b4e7aed72a79944493d6 Mon Sep 17 00:00:00 2001 From: lorol Date: Wed, 11 Mar 2020 23:45:04 -0400 Subject: [PATCH 035/551] Added example info --- examples/SmartSwitch/README.md | 13 +++++++++++++ examples/SmartSwitch/SCREENSHOT.PNG | Bin 0 -> 123256 bytes 2 files changed, 13 insertions(+) create mode 100644 examples/SmartSwitch/README.md create mode 100644 examples/SmartSwitch/SCREENSHOT.PNG diff --git a/examples/SmartSwitch/README.md b/examples/SmartSwitch/README.md new file mode 100644 index 000000000..1801e990b --- /dev/null +++ b/examples/SmartSwitch/README.md @@ -0,0 +1,13 @@ +![](SCREENSHOT.PNG) + +SmartSwitch application +Based on ESP_AsyncFSBrowser +Temperature Control for heater with schedule for car block heater or battery charger +Wide browser compatibility, no extra server-side needed. +HTTP server and WebSocket, single port +Standalone, no JS dependencies for the browser from Internet (I hope) +Based on ESP_AsyncFSBrowser +Real Time (NTP) w/ Time Zones +Memorized settings to EEPROM +Multiple clients can be connected at same time, they see each other requests +Use latest ESP8266 core lib (from github) \ No newline at end of file diff --git a/examples/SmartSwitch/SCREENSHOT.PNG b/examples/SmartSwitch/SCREENSHOT.PNG new file mode 100644 index 0000000000000000000000000000000000000000..e9d0ddd5c4016011fb795078b89cfbdc9db75407 GIT binary patch literal 123256 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

N9==Z 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 literal 0 HcmV?d00001 From ab9267b0715f6af95515d1b65a3e955759a27631 Mon Sep 17 00:00:00 2001 From: lorol Date: Wed, 11 Mar 2020 23:49:21 -0400 Subject: [PATCH 036/551] Update README.md --- examples/SmartSwitch/README.md | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/examples/SmartSwitch/README.md b/examples/SmartSwitch/README.md index 1801e990b..371de48ba 100644 --- a/examples/SmartSwitch/README.md +++ b/examples/SmartSwitch/README.md @@ -1,13 +1,13 @@ ![](SCREENSHOT.PNG) -SmartSwitch application -Based on ESP_AsyncFSBrowser -Temperature Control for heater with schedule for car block heater or battery charger -Wide browser compatibility, no extra server-side needed. -HTTP server and WebSocket, single port -Standalone, no JS dependencies for the browser from Internet (I hope) -Based on ESP_AsyncFSBrowser -Real Time (NTP) w/ Time Zones -Memorized settings to EEPROM -Multiple clients can be connected at same time, they see each other requests -Use latest ESP8266 core lib (from github) \ No newline at end of file +* SmartSwitch application +* Based on ESP_AsyncFSBrowser +* Temperature Control for heater with schedule for car block heater or battery charger +* Wide browser compatibility, no extra server-side needed. +* HTTP server and WebSocket, single port +* Standalone, no JS dependencies for the browser from Internet (I hope) +* Based on ESP_AsyncFSBrowser +* Real Time (NTP) w/ Time Zones +* Memorized settings to EEPROM +* Multiple clients can be connected at same time, they see each other requests +* Use latest ESP8266 core lib (from github) From 3860983960af2577c739070c8f7ef8357c2a4071 Mon Sep 17 00:00:00 2001 From: lorol Date: Wed, 11 Mar 2020 23:50:27 -0400 Subject: [PATCH 037/551] --- examples/SmartSwitch/SCREENSHOT.PNG | Bin 123256 -> 51029 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/examples/SmartSwitch/SCREENSHOT.PNG b/examples/SmartSwitch/SCREENSHOT.PNG index e9d0ddd5c4016011fb795078b89cfbdc9db75407..9f18ba0887315e5448fc5b8f916a800bdd2c5ad2 100644 GIT binary patch literal 51029 zcmeFZbyQnT_dgn-6o;p1fg(i;#fy7NTl~RYQ%Z4nCqQv6P@s4rxE6P4aV^D*6WmGA z03qD;dG+`Gt@~T|y?@-b?pp5&lgv4pnauv2Ju{!#dmrw9-LC=uP?A%W17Kia0N$cs zfO{w)Ro2_a5&%$90dN2S09*hj1}Ojwox?!C01-BT2Y=-OfM@7W008?V7623dNsdm| zN#Ot-^d~7g`G3LqSFJCY|EPs|`~~YD`3E)VasYllem-$N0r3}nj4y=6`Gv)WL;*5d zuN4*1-)WhDS^kcW>6 zT^&!-^}VII<{P=c*G8X7G5x)tUS3{2UIIK$u2#G+#KgpS`S^MH`MJ?0xZQjl-OaqY z9o?A!YU6K>ys>aIceQbLw{dc0{N1S8J0}l!DJJyK|J5&NGzd;;B%J@*{{Mo*KfnG9 z4JO8ao{PURbGLZyYJq-7WAPhoZax9-7kt|P0Go;TFFAPsF34|8c>f6s`i$}agX6zH z@*jcxU%37Y*MEe-e^mIt+Vx+!{v!nbqr(5yuK$0)^)EhU;rL#P&5I2veSZYtQvU}H zVHDuu1Bkv-RC&Pqo5cbCn5K)JPXN?D*bBn@e291zc)tjEjpmLRzyJPzU}0nZJ{~@J zfQ60o5C`XX!o?%N!^OqN#lgWR!pA2dL?1YK#3V$7#J}^u8~I)RcP;cEAubN??-Kvn zasLhQ2p7`;!wU<834r+s1M3mSeJ_9k&1kXFy!SWt{riD|iS+>cA-YTW1n2?{f1taM zg@uXkEcOF5>BR^@e-C)@2%Gfj3z>&x8fG|5F68{diFvrpuWG(iXimUb1m3xZ;NeqJ zJ*K8%ea6QAoI_AZSVUAz{Pi1IIe7&|B`s|oT|IpRL-Y3*mR8m_wr=hoo?hNQz8^xv z!XqN1qLY$8rKF~PPS41P6ciQ}mz0*(*3~yOHZ`}jcK7u5^$!dV4Np!@&&1k6AzyM)A&d0-usa5XuVwE!tm_{XY{d_zm9fJpjR-b`MD6%*ziF zJNX|M+5fj{tu*XdIse<$|2Fn7ApeWmfA#GDZa7tiM+4aN|3@k_Wt^)(a_5`w8-|Sv z`vzuWEt?oCEt)q)k=M1+50jIseG$6$xmCLdeAjFDf&29(?}14itJ>M1MQMZe!aqNh z?fZ!8S~7kfc|sA-SRoKHmPJwqbtD-T*sl#IVttI%OicuRaOfQJooC?elQat&w2|{} zYf*;AdL$z&(!5UFfZFWU{S9}JF6)FKny{+UGVc%Tsj)n{f7}DQRfwij=h#Yhl>6A{ zsc#|7B?E?cnCLkK9Jngn)o}U2r)Yn+u~jdwUO#j$wQ=(<=MwYPUH%`vU)6g#pK__! zB76C&&7&kmM)|YY<~BrU^P4`=T?gpd?YXaJC(wo?6-LhN^`=?zG%7A*XR7DqR~F_A zx7_wP*z>!jfUoh{^Mml&%fyfCGq{VkX$t}$NvR?50Uff=SEf%p+XBX1nEd2CgRjAc znJRFLna~fTZY~TS=HqL=D0hr`4UPHbfdKntxy2-zkG4vGhd#&}kRQzs$S*sfsrQvi zPeEDkMgt@70XY{#rrxPH7gs)GG?)56egdm^Uea|?^zETI+P{8uOe|L2-vL$|9@O6= zE;!$02%LUBnPzzXl1$^JeU{hnZbAeB8nWd7PZGu%2uYFK+mu6h7bPi6mnnV^ur-nFyfc-($DWkEOIs|58Q#g{*DAY4;nE-myA zZAH^~>_i-`Z(BiiTQ=u?D%QY`Q+c5X;HUiG9#R3Rg?O$;RW04Jx1 zi+fi@UbMDphT8F6p2rWPtw)|X%M-8_sngHwGd#Hmtku!;Akx=p$EbP&sq10JH=!!n z{ROQM)1?7gLXpJVl2BDSxwGaHF=IYLVRZ3?+*&1M60k_KygEg*FQcH3|*$q z?Uv<$N3)6V>kU-eRhbFMH92wmH#;{NY0kk|{x0``u$YZi{DGot;4f)bSiuc!sU=5@ z(oS2Ogo(%3z)wS#aUR(O-FB}4?$+B*0YF09;@ zA9fEvck-ak+-_)kz`#T%nXo0Nps6YK<)` zzF|rLb3IlD&rc3Ot!0jSUA$s}(xe;bi6|C;7R^s?hS{P555A!}HsYyViU#8`AdP?n6s7^#G zZF&s6$!wXs_y})GEKy{D}(HCKJ^0qygP zYN4HUk^3vAnNOZq+5Ft2a_M0npf&8St#IKe$ByL~W5mYH;@b%hB9`dOr9SjGfL$3( zg=emF`i-0rk9b-*&>ZgVb&mX4;FYYwdMmubaDv(8{jNE8ejHkv7SYZOz4HkqLx{X? zt^KKayb5aa^Wj-}ZTs-FoV1z$p~FC6;5$6AYH#UBQ{$ocfUn38cWIYuUw!D!!KL$c zj)%v$?N(wZSyT0^1p2!us-_7C=!?C^#&QdCX>;LUI+)l?svD=V@3U^VgCw1x198aL z>y>Iyp2~F#*z(0(Or_OylqUj%0;%O)TlC;@Vpt zpYsYv8aezgbs_+aBo$9nnu$fFsm7rM;ny7lSKe#jTtmQhU3cKadW4n@lupYCwvy{Y zvrqX97`Z~-CEq@4=#wP6)kVsl0%_qd8>H9)t!z?Y82GM|qJDNVPPTh6%sW;H5phdu zIY6%+D(g8L8={{(G1tFai1`$`#N5J_Sk6)VIbMNZ&m#{t+DQOAuD0{AD>7lxr2^X5 zeGO3ESK%MFPbGbAIZ5k1ufOFfC;WtB!Kc_ba1=${Hbb+oB7JucSbr}Rd2|nGs6vf6 z`LdDS<+Dq!a)=Rrsd=xidW|ud*aL6@;RLcT`AefG|7URW97Z@sD_pgjkYQe$zN5=p zGP78YWHTzdbmLv)5=On_V#YT_1Z+s?9zf|mVw~KaA<{=Ay?+ETc{QRQ5BvjRk{8CD zv@osEMgj4#p&H3}w)%89^*VF8oeg%S2$Rk$M^9QyMx8D0b4}Kc+ewt^wFZ;I?-Em4 zQct^&C9`tua^ZT1P$=)?gSmyc<(xdio38{Vh4GbM<`0W7j~J|@sWrvom!9(!q+qDN z#0(Mxk@$Nzcfn3#9P7(VE{Hf^!A!HO_o%#F80t-^kB&D<)rLPbzoury{?2{S?^y$n z7!YrUlV?b+M%XjM#=`{f0e_^lP8BqZ)Q!`P)C0MOYJune?=8Zi@exw@farUG6$l40 zdG@1oa!cKwOgV{G`5;EZF7wT5EuLBUn|S>>zau?eg67~L73)RhQ`kklZ+_ti?AiK3 zcfaxTbhT_d{Ncobt4?FCNurT(i58aNAR-W+T`nvcVWcwM8>lc{`L6ZR@$%Nm%U|RE zR@9aFm5@E*n}^AE=5`Eec2@W@_>SB)Fby$xo*AP3`9c*!bZ)V;UKg-TOb&XVKj z>1YE0j{#aGRk4m1vHgl_)Vew}^TVoYaQmHaTg{SBjQQLlDpJ$$^1B{{M6*{hH~)iL zLp-3167wR8j$sL!Et+7Ci~+@_sk+VX#G3t=*9jZ56&f$G$^S>vYX8Y~vQ+<-^TocL zcJ6SM#!CwOdOH)Trq}oo_vM)`fic7XN!Cz77)o;kxco=E~|i7R2lPu zW^KL@PKGp3zMd?PCwhqp-gRK_k@}U z-p~9~Y~xGLsAfazk92mxWc_23wOL z#$F&c0uEJ+5;-;8y(wvKj$b{Bd6Ig%SbuqqH6E!@zTKAu8BK8AO3RUR6+BrOhptq7 z?C6TBSdoZvYA_l$OEGUVem+n3iGZue_X9o|qj`Oaq#nT<5P#p48&L|q)7(%)eA$)D^a08Z^ zeCvLD+FSZPypNvJeqY9~BEOKlz6XRS!(Jg?t(qqHQvTfY(i<;gNtR_%ZL*F(a)j4L zD0=pP1CZTi*vc8?i}|Z{Ho~WV)qQoK8afAeQXM2&@ewP zGgD^(BC*KU6c27|OGQJpe6!;JHbSGeK|O}`ocR^rwrq14SM`%H8D?%u(J|k&??)o) zaFV`z0JZmU0R64Zlu)J=P^C8H<^|Er&V1a6RBz&`I+^pM*JhECNdV55ltR^!InU}4 z<8~0Ez2Nh7)@VLp9S@7hAN8t}#xZ?Pb-m2aWJ4Z2i{8v*@wMlxk?1?uRA!e(Pl&dj z=qdknH@ZGAarDTvIe9iy9Neh1Tcb?VgZq*H;WIghu*Trnn;GxipoTHKOBWNn92VVw@#55I6ToH1BKYBg_qy(S|kqu7d2>#hKlZgTt zs-{(;>d;Vwqks1>EOB5Z?(*bykW%d?R-y^E8yN3cQYBz*(9z$>$=tlsM44;M!gg`C z`&nYFxR;;!tI*cs@17e~lJ%#4)!om_(tIHdmo(rl~shCW}es!N>jRtkX*0 zQkB$mnE~tk097GY@dHgQ>Q2`ishCWu*0&_`Fr`1fhV|7Hp1M7W*rt}n3gpLw!0Nu= zRK?}{8^#}~HHWC!^=5?4M7M4nX-E~eGFO*yRp2xWeYh3!7oC;l-T)CU+xn`EWz75Y zO$d6WYGVzz#w*7Dw5sDBRJc*c$@liUjDT6i`0H5Z?`2$6UR*+G6|J_IKl5UKNlbm- zc&#a(w=`H`@RB9?gKFK~mv#p52KLXq*}MRms*FC86voEXEw|QX9^q?l{-d|%dOY|a z@0kzPJf0=O(_GoIG}=9uEOPB)8f3Z$7#bhi6LtUs$lx*S#z0&Y zJ?Nm;P^CoK(L7{!n390?XmpZGy&DheHMrZBfRD!(WETRr>IFuDagaQy=kPc5L^Jht zl6Vb%bo2zDs|64I<4*gy;zwMzo^uVGN7k0V{Sf5awZH~FhQOJj1*xr^i$yI(D+{(a z*3B%hS^Fw`-3lD#pBfiU`ZB#CH*0@M5DU8@O5L8W)<%p1%TdFGlDD&ix0K0y7r*ORmRS3L>dGc5? z+m^u2;YGTP2z;PG78f5JL;BFvZ@YtJttibS&z}~S5_iaNv|_N^=xi*@c%7g4R@Op# zErcDb_^lHF5k@&yyHOa_*}VaZAU1=$5+LYZlD_gaD7FA-=mlGrR!Y_%HO4N=S~DWv`j;0 zZ&gy5+GB=NP<0WBi!OhB*#c#VH>H5@L^+I!uap>^jQ+A*l9*p0qkh%f zmd3F1tO(Hni_nL63`Dqh2+vncssRob$c$@K!n@bkB_4!CE%Gg~7u+=wH=97oaGmi&^5!k9|=vB2WPQ_Zy_X3?{I04ZwWre05)HCM%fgHyu6arNb-!?8P&oZ{>D z#@#Ee;X>^&(m!Qe^9P+jzf+~Hf^Sz>1y0&Q5U%6hrpz!@bZcP_q;mDZnYBcrvRFB+ zDGaMlk$H%eXHA%6^Oy~=v5FL(+x&SkIH%ZQ!xPB4chhT2l~$|VM&&aAbmnqYJlA?j zzXw&$j9DezJ2O>ra`O_ZcM|++BvtR)qOQ!PItnk94723Id62~U>Tg>7H;WcJUvkVt zxga%mCI4l7Z|Rn}fmK*v*J5F$`8`ALlZ0t?EQc){$kIf;@rK=_J3I-((&M`t({2YB=mQa6jMtlt6zYFH>kW+(sI?)%6rX2Nh&TfNgK$&W z42V_|?EFqe z*uX$nRF33bBZ~HQmGwL(8Itu540Yzrr_WLqbaizthGLIF<{`jD!F>RG z^(VB^tbl<5#p=xl)r)nIB*|OdHFOLs9&jo1?p`;;m0{+HpL&EyzErR<}=*&h8XI=N3LEshnoH3o4H?%Hqe9;g2=7%maXDR z)`zVmwa&ooto|6V_vK5bHRzhh5h^lITzB@+q2{r1EtNL$(V83|lVVW55EwZ-6y`~; zq#B{Oq8KX{FkJQ#Dm!qDaFF$PTMJ-YPaC)g%(otF2sQO~k$HRdE`(AU{s@L1Xg7(| zRo4HxO<(|hk(yob=DLszm!FX2Q~0i=&8_CaJ%9#9gCv=hWGLYc^Ein^udUNeahA#Q z4ULUwC%qWoL3|9$5I)fdSr5O{&4`+ol^*74^1FP3NSOX~iTPArR4T{s6?ZaxG>H^M zl*JSuS*dDl$68<)ZWppXUNoWolwZkdln$!wEGju>-P!3>f>;{BV+ZNoF{I_g(#-&}@9bYo)H*ILnVdyHTywOl-J4Pt!skx}B%^h@rrpl_P7npW*d58tEF#d%>Xm`(zLBE{m=vLlG1LT=R?co!^rYCD`otF ziqeg0BclSqa#eDhDGxT*XZaQNaV^=4%099@M^$Nd2fm!!2@jDPh`8H#s8KMXM*{A0 z50nyaT#>^)^JV_Bl84icMJq;OlTc(tP*x|>oaU=2(3|ahE`?n#VVC_ub+|A}c(#+t z+j65vrP6q)T!muh9uVP}>Jg`L%q%;sRLmrT9Sn#i+^IDN>T*HlJ#Lo?;MTvkW6sSfpSvYYWlty6lr;So0jq-lyAy>Gm|?11e=NMgga zw5CuKJ^`?@h1VrUV^}>;(&)7$H8>N)iNEn|4N_N=!BdmrT5CIpLpJa-P*fnxY`dPB zg+sNSDP5}ql}u|xviX=5IVb(@pDvvb@E@7SQvWM zF|~a+N^b~rZIi?vl(+b3^5cp<%vK3!4PlLwn~|x<_@x)_*HiMp?C?vxV{{xy6f%w+ zs(7V;JV+qNeV_R8QJZbNLC9tpwIwrv^ktq&+fyY)&f2>Na~WMnQLvnci!N}1Z=Ps+As$i{ZUtt+BS3wF37_EVAqW~JC7oDn;Dz_(zVBka!X zu7L^7tC6CSIa3lfC9vP^vX%n%NMj?WZiT%MlshNP5N^=6BfTEW%YN%cwVGR#kBv>V zKR+qVD&SN8nCZu(sA9bPsPl5*a53yLmbeJT)PleDT{f3AeN*ULxYKuie~$fKck2t2 z7w)H3+j8_T!MxZ*<^x=c2V()1f9i<46@C5eTb8ArzqaAPhJ!b}Coxv+*WegEp~yg{ zhND?vt4w8@T*^lMywqfcEEY;D!TMmPBKxMTaef4;2ggq610&egzGsWbv^UH!d}|b+ zZKarT!dZ?`*cU&2?S)+^0*rq0JeD$~5@V!EpuO^q!E ztTlP;@nuGpJJ`4I*gmxuJe z56)WCO^CP$SdRyFlFwY2yjF(qbkm_7NX99SLY$cg7F?K5C|aHzd!bssQ-|HT>y zB6aL@?#l=1KpB&?5B_>oaqj4qSKpDjCVPC|)H{Q+IRWb`^T|UUHqWKtk66UGY(teF zsukUIK183X1X|U|Q@<+TDimVdoI=J$v*)+`2tx0#0Qq(PI%r2x_Y25S;Ov~9y5YyO z!g>|K5e7KF+?TqeeI1#1SPq20w0fG35@1Qfi)?))5no#`;z5rV@D!sQY)rGnaXFPs|XGT~${bC$6mh+*ntG?@77X!lcKz=Te z5y?7RpSgwSW)V|O~Tp#2ffXy+HsR`=}w!f%Gyi8r$pPkdsK6*O|Y=E3u#*H#&hB;Dl zVKZm<6b2ZqA34dxC%t373%AaqgLm)<7yiugh-}tvX^ejVqM-V*L zv$x9xI5wuyWY}f6uBhQ>RXFk79R|gQv0+vVlp0ZUxak|nOoc>m#Wo~)&0bA`1te?Z zo;=~u@-CUydA507NL$k2!0q69DhatXzspAo!8TBM^_5k&sWhggYbx|7vNQFI>9Z2$ zM!SSH1fH?kE9PHK%44(Fn^%bt;v1I^F!YG^TIZzz_ZBO|Mh(N0E0kR&8>Xyg?CWqp zLFzvhT8@^97nxi%Hu}?K7e6eXB z!dV2DKazn-^xt65CRh5uL1>iQcnxhW8JgN%l6@E7e8MjnrvDymuv+g{&beG{qDQ;I zKvjp#$gSJiB|e)%v3}*o#Cq{`BemZ>5C2z&|Fk*ol+DSIsEU}~%v7|ELuF1W56OC0 zBv&9OI#As}A)C!K`|8uN+yj1<@R@>Fn2g%q?R|Mp6v1K9A?O@BE*AKKih36?F2< zsRg^J!@*6m__p+kju1675HLfdS691K10t=Yv8B?tyrP-uz)e}}spqL^JDxXu zpq_VRJ6B2UTf6OIg8Hs2VOtfhR%m z{JSn^eac&E#qWSvotx{~3{R^GImPlX=#l+cL)Hwj+TYkka=tY!M3FAoyy!4C>LM62 zN}r@aPRc|_ee+Dlp54+g*0^wl&Ojg|)Tc0CZkuz91i`k`H%{dL;4XFtb`{+)22`Ap zCSTdl@a%AM;U5qrOiLb){UhtEyT>oN*Ev+rI?}uB6GAz9!QImcr;pBV>vlZAQ&t!H z7x1RTF0{=ShWKDQ*NJ^#xYfCwcGa4iE;TR`*W&4_x1 zdddc!6Y=}hvRPZ#IY?byL+QV~P zWOK`j8UkVqf@$?ZHZJ}zn>&9L+?v-;7PMsewRs=Yededul-2pR7S3IdY0E&20Csnw zLu8y1B2csl$)EZ*H!Eo+V;ccf$}Ix=G7jX-hhF?e2Jb$NE@BaqHDd+!Hr0ApU#26d zHpWSe_r!O4c|#Xw)4bapxlS66q}NwmvY?5Z97{ny6v?ou^{c}z*t>o|CtO6^+CX?- z>)W%c%nF;?RcmHZ9-Z&+_?=Zu((Opxi?eLpc>~?$C#?H}GXf7RE@A(Z?7_@7q8`P)~fs3!E z+!uXPmD@6}Cq-3i`-wN0UO0@z#)ZyRdi!0*Aqb#SM%vSYUG)A>r<@vw!uku{>?-$u zj+H1q#2Ou58~jF!@lIjP?MD9h04G79)F^%(tYRJ_RXFP_%U+k-M0s@7wOoY{S`Lj6 ztGU``@|0e9cT@0P&=d=4iaT-2XYfzGS<=a9QQYU)-~Q`ft_&AbN?_k((hS6iD-4mN%xY7Tx)HeS{%+;rv6G8O#Ob~ zN?&*9TY%==dehN0T&u5D5)QH!CyppW7#)2TNq2Jdq&|N3#^tmo#+CCeOdo#_#e#IX z%R%w&DiHH256@RvMWR6_noqsEVI?1>#OtOSkcB?vq<|JelB< zCXVCySyVoC$yc(^>*HopeB9w+@mvh#mEU-Di%qeE<}wYdJw&QH5r4w3LN5;XaP=$P z12pNBPSa9T$0yXFCYPC#O_Y4?69GAvvNp_1v?K4tjN^$(s3}f`zRr}O-LpK> zrPZUiG@@lfU16-ea=DxO`O%zY&VMcSe=|m56tS8Qmm=9u$!=q=wMz02b98<=eau|~ z4JSMWHg~01AY%F#ctigLFD!JX6<)9Iqvkz7I^8%j3uWE|2%5gi4S%Y*&_eeiW?Bt=1+YOcnuCiGawtBdjOR@l4tcH_~$AVjHHo4tM0^+ z`BHVsESf$$9b2hvvRzS~LI%~2dAIZzNP0meh^mvr8`Cz3tyalU{OqMz7Kt$@nURN* z-miXlW4dBmprGKZ4+yH$Vhvf$TBCn@3~(o(2)Ao)J0fU3?fw5t^V zZ^3o>LA3vdjB0*N@^Bl`U$;)_+@&h!_lHGqU+tHX*99%&%js-1lLfq8B=zi>= z`@xICLA%ZRG)O|wjQq95tGA0N0y6mQ?Ijp(viC;5nsF~rZJ4>R^RDL<(@uFW;#xpj z`*q9YtxdYVE49qy1JIAi#}wDq^l&17ULG96YvYv7*~^Y3wZg-bQ(%*Hlr+hf&wh2E z*fOgwxz*v`D<$|2I+#7lS7}&7Lrr;kVb8F?t=t3w(aBYxLHoWrZ;N<^#+E7tr(WzE z{7N-HR?)td1fPuoPcr6U+BDpA(TC=6irG^0y!J1qOE!%)%O-scVlVnw5+RK)J>m(z zH_RLIhflxQNHb5JlSD|fz^NiHN+l)CH|Uf$dOZ!jBF+Pt6a{bQqHAR|o3>FY5cIR0bRD zavKQ}>Wu%%^PKH-|&+Y*}L^L? zw%%uEpSHH+Z9?Q@)%?NXe_f`Fw!vbK5kNB zgc;JmyT7kg`;~ERPC_qu)Fs^^(3jsO$+ucH?g>)kyT3%gkJ?NfhkCVKffHW2@TZjN zy)pYsn_|nRRtJWeod|zf^Ys&wU;C{lTb+4Dww@Eq^UI5aEaCgq>z(Tw z#K#NZsZr30B?V^B4dreCpE!4z(vHJ@C~VxsDOd^a0sLyqDXngDKbCpWaUWg`9Dj@c zFx9)YN9wmCp5AgG7JC~7ggW!Aia&D|X`RWqNL03~O3fVeHA1Lq(!RrUwl*&dt{YC!Xpd$*EBIF=aM^9Mh5nuqssOk>tNN! z65Du2qZXl66yM%|*8kZp<7Tvy(y=F9*)?R}%Fx@c*r$&?q2Q9^ah$s{2YYhnE1&sw z7J$qmoNhkf15Of^QXh>lm3^yZ{-dm%-XLlXfWwm9&!IKhS&ts@5=ep?MBeSIeN)!y zwfOzHZ=Q+9i@j?URCRR~qd>=89Za@kIEv}(EyKbEQE~C- zwv?w*mq~}>d|DqR63D^dDLhUvdt0k}RwIw-TddB$rBPNFxACElMtKYc?g0R?3yK?R zSup3izwSE6%reOK6X@4wOkA67CRhY4a04NNsu53qDHT^4xxU^k47?Fc8`4JrFVUe! zAwk|f(7C=Dgd%*HHpaw!T$z*Ga8Ji7+VWexL^vo(e{&E|e1|2j?*kR6ofB;+L2zAt z^JAbyV%NbB)#d4Hpb{kxR@rhicAQZUObw(|=U1K?-z`s?pJZH(|H@n+o9joL#Pz<@ zvvj6Z2@#Bm%J>N|WcWqWRc?K}txpsP6dLb)Z2U}s2huA_W1B0PE&ef~yNuPZ&s{UV zac`$w1nO_fi~V^PdgvjqmBdjf))h77IGen`e%=LYzEEP%?|g9g&zSig6q~=&L??+i zmM&Z*l9#kce!^j4d*5<1NE9DZF7X1tOw97_Lq&>fwp#=6cLij?t@44MZlht?Nhp$` zxv(?YTr65~s-`7Hb?;^E!-Jq)*4+mRWAint;>_I2R5Fz3uc*-w^TxsZ7;jt zXH1oM^b1vJ3U9{?OBcE+Ua|vsVnJ8ms)eFDK$67!Ke0uM6JB|iXJG)Un(rFRTnS4-Ox>6EoZkR*O@e~ZBmvf-Yf4izn$9kS`Rl0hJZrdIHI%mwJ$$qWq-38$0gn zbK)FwOafEq*zEza!QT~y#vdY;Tjt1QbZVxN1jXK@H?!k$2dCDE{j<*T~_GTCSJ>vxX6%F2n z&q^wcj;cLY2NWT3@9NtHApU>MwsUWAV=mlGDI#1^BvV|06D|yw2P5ma4OHA*%BTb; z=HbDC=dBcj4vQos(|Ya#NZT}ll&fV<+mst0-nQv$d->3I0nKQL>W5;hhgnuatcOcW z_Se~6Q9>S-1&31_cCB|1l$deg1enrEQbjn${L5lPWl^?S;rtNG$Gut4)QN?~Zu(ay z!+oTVo?@0<&KLmadcBD*m|8XBSuvWKI8`$k4HV8VTd&|WWD$XSr@qNHv|^nNU`VRC z#AEWjN+L*kKsF#3&c@e!I;Ew*zKdt4GHaM!xSMW#k_C~bH`}GN3VAPxt zEE%dB0h55{g#8Xlnja|Mm8PwY@9tlEau`PisPnKgKNCQ&o$nM`=9EDbEvh*C=zn`* zw3@WMksvhHG=A> z+!}B%5zh~ij4duI4TWio0^vG&j|O?yH=7T;_GhIr(AKu6{ zTUUM@VvCrMH)N9;|0p)k_*mn#laCsu8L#6`Sn-%X^vQNt3%}$QP9~H&_PcThug5HJ znH>ZK(@nL4&H5y6@Mjr+_5O7_WPhXRrB()>g=7{6&Z}e4{t1LzuVF-}q>MS*-som?lancKykOkD_&(%~ zm@dvV!?$xWiUjiaF(ShU7GsOq*0+LFF@btYC^_Vd>~@GCJ5`-T%SK9M1V>n(IPAn|a^&%_}>*+{*>h?;C8*CTlrz6W`}O%Cz@q2jIz zB1v1Bjb^VNCz-(ft&QkJ@&iqHc+!G+0_R~TeH#5^7L6wg&B+X0uGz`2x^#7NQFn7Y z2uZ!;rXy+?ncQ6=isXQvWDZN-u2hatg#F8ixp?-3YVHx|+YJa|DKxUWKX(CmX$ns` ztl3Z$1XJ47z9twPu_)~>tnd(`qj@gwIPgp$!gS*?8x#?NB|7UJS?vk>@CyZo^F|y@ z3`hiAn0WTi0i}SvB1nJdyvM=ckZI?z%6$b|PFV8oOE_{U-7_@F5^hz= z5}~BWuYp-~4CENSTd>8vk;pG})^EnwDiRyF-S>Aws|MDrq|Lh8(X*eMG2vEQlKo`SLhlk&?v{=pmKY;^Dh@OEeX zS?X78bCpP*X_&6My9|-6Y;C07#v1(wAZJPczPA6)mcxAxNg^Pb#@f5>T>^EUX!Gk# zG%-Ro%-aT>-9Gh~YDMVW@_OU+T*2GL!!z?1DmPVTsTcT8i;>v#5m3`aS&Ex5(Gpo% z_n)Zxo{2ab4G3L+5{UI}el$m1$lsOeFQv-ldZo?r-9Z0s2tRJI#!Gq}I0*_b;8xmS zVOxEi?L;EBzf14hO-9>(sL_w)43zJ+a)ujN z602os=dU94t{JrCCV`6DPDVT7j)90R2G~(<@anmmVD9Zbzy%E>=aO~R zJ>Vh+E%uj;T*Q;EQS{`c=bC$iU5ti99+^Ol);D`3$vq(7uizfAdYga}GwQ^?i$swk zg{Nn4StNw*Pe9*eLDcN;GX;PHBgW^{D=v4tiNS+BOuxmz+Q-Tm}QZPq7f zL{Y|m9yvO!1ue6w#=$>rhQA}RtPn9hhF&q}HuXn_-6Psl$8z(Pj%x;apM3fG7*S01 z?2v$=PueMkHS31eNV43u@Jin+QltnB>GX8S$RlY5_?_881A&kBr4r8|(1y=9Ckkj| zVGO#*rU!DIx%=+G#DKxGt{T^!@;nkGCUDbR4=JIyW_3r_!F&(E0l|l>1r>2G*mWBWiMK4eaB4wa~pF_QSZPH`^ z+3|%&{9KdnN=#AwT|$|p5qe64AWAFtxo%WbpmdaTUPEMtBOZ+Ou}4hd(onrU0|pqP zD~{o8t{aGW?u3#63GGT#P9wFO(92_^h!^_ZQ`1%?=Z&RWosoP3ztzASlO8T_YKlU( zZXo%a*{AIi74mnbMZyg>tutvy!W>}>d!pNnK{bJ&x4Q!G0h->13CCM#g*v`ixHGw& zo6>?YTueoC2A+y$#NRcpEK@X1&Ar~`MfijI6Rr=S3`lbHFVjI#3{-Fk$`>Jz?mstr z2-tl?>cN!zO|f8=sV!CBdcES(F{Kogb4{M4uOIZKxdx5CNL5$Bp~hks8VPAec@z@k zL!&2lAmPQV4YOqj9`08H)%{s2a>gk&I`6LP93;GE7!0gIFoWutR)^CeAFH)xRg(3n z^XqqmC*cOJB%LHb=jL*2u8`!5-M|LoQsQ8+6I&<}#CJCq*V}Cr@G>}gQzf`1i2C#w zr+LvD9z&9t?i20QCO7?MS*i9Zqa~x(5%LK!#it%mQ)VJKz6GJJc$`DylAMDzzq|;g zSmlZp-FW%lWtf{u!8V#bNf*>FuUAlsRfOI4((nOk+&?6u< z0@6WB1f(|s0R;gOkWQo{EkNii!a|O_0G!Qm%IFg>OxBiGR2eT`fFz4?{qiH6B zos~c}0^9XS>HYwGc>LS;BwrQ+*)E-ct&ymaxeG7s9;p9~KkLOe{-s80V!vm?nTB`&g6K~WG=6g^GIw*@(@7;=T+ZH!$>%g(UJ3rp zPj4DtNMyH^e$CI%?oKY0E9%!Q5b)ltm_!ds?|jl%_1s$3NmCX~yz&R24P9l@yc0$G zU2+^4qI}&5KNsEW<$E5;3p5xM$}c5Z^&j^6DgdA7XW%@bW8MUOQ<--&2c*ansFAiE0L#4EFWMrygsc_wS zCFZ0^y;|}>gE?Ggl{0B!lRqU;2&{0OaCL1{owNE8+rOaH|9dlCAPU%!0TDa8(YZ0wnTSmGSLR<(<)CC`hnjCRLfj+6PW`w=)L?}$?*B91OEg) z#VR=n<)msbFYyK5x+0JT5A<9>JJVcj%bXZK73%nCfFn%$y0_=8Q=7u3*Xe${Q64)p zv>6X%)@lrAFRV@&q4Ugejo{Bj*M3;feW0><>k%4G(3IID8H~4lo*?&eiH;G4uyfC~ zgO479QEyMnH$zH?c`nH9yNMRmJ9zlbmThm5`p<@Ap*83*pb0o^)py1l=3eR-|gTyDZa!(A*NfTr$eW$2Y#9Y&I ziKuymJlGC)OLeywp$JX8{LvupOV+|+*$ZQU34EqS=t2JlakcW`g}Q<-p=;^r{SY0q z8|0s*j#VT?2g_NSZ?;Hn%qter;@|O~zNRS#?Uh}zz5{y6!TtuHzVd`Oqooe?D}S#B44Nw6_WPY$-u9-^q+TVsd*tf@n4> zpZWdPGOIhc*qKqZw!FO2Ep63U&QO0oh3pQs4C@$gw^lM_o*t1_3>>; zd@5d(;2KX~bQT^c)l?(9YFnPYCIJLuC`Y>&05PtrE#L&vqkQDU3{e}&U_~?WvDQU| zASnjyU_?p>I|Q+GR6UT~nT9QxIg@vpX zVxH*?H<}3@*ADONTptkL_#?=E6}lE@gtkA0Z3F}Yxi2D9`O`n0mm-}?cZDHEJP%8jYs2$|3%jhT6(RzDgO5mO4j)H|O)U#o9C9JDoKNEb;|4+>%<=^BW1>F4b`p^>5*M+^M3XL%wswZyum;$x~VM0ENr zBt{wRSKW5j!6|r7=*Z^$IaMw;b%*cg@pIX+g6=7kMa6(9KBp)3X>U5Y#hF+-6KU~b zsO%d+2V>KzCEe3zyhDlek)!BZW{VGIzCG;Hx(jbvQpb$nhW3U455)`F0|K=U=5l1d zADB!}&}PxB9SKaUClAI9J*bhW^A-Add9XYsDURdIlx|2XrJu-3T4s?c-nS!|bJWG# zdnSmf;Jv%(>dSXkAZ0s>PnYCD3=&}$l5K-6c6rFvxgdqbx$?#wef8M;6U#rH6uY{I zOZDRAx(|K}aj6R&^bhF_$u#}hGN`VfI3O}EmouZg76n~o+l|kE%>rVUM&-{i&dxIC zgMeC3PmzNJLqqnl2N%OF%B_hE*w%7vVH=S21uCwJGdhnuatY*gUBK<2jZ+1ua&(*h z%3LzA*R*&)Jx_kc_`vu+bL#sn zi)eJkoZQpwhCv{B*5w6w`;lKTp`(?%apZebGHH+hM|?SXbAK1W{;p5hwOjUg_Vs9 z)L(ItB(ybJ6_!~!#$xS=5{#C9q2`K7FTJANzKsLQ%3GQboX=?Wp#uG@w^48ScD1Qj zz~Myk%duRUD+|mW;Ok|j1)?oq+~eh*NrIGbw4JFM8 z`hK|gX`!Z)_2N5OHXNKf@D?ULgvjZ=vcQK@V9xrw!%m*Gz7z*@^KJ1#e)@zuu%K*` zr=*IB1$Jdy&L!fVhT~?b6)4@d)Taza(fGJG8oj^D`c2g|1a2Ru%gM5DL9V_zrEgJb_fCf1BqT5BI-HhIcP)x{Q(vQkPNuQL|(Z1*2Isq&Czh1Zr} z2c1N;tNs=5>7I>g<*yS&%G}*_oG)ZnEXCiu&~~p{*MTG1Y%OV{lGP%>Cfx!f7`qzu zWa{w6=t;TSPEV$PMLA!Fmgg5@TwCha_)UuA#YzO;_A$P6ZTOZ&Px17;7G_I#>Z`>4 zNE3>5J%&CuiMG$S3Ac5|ih8g1$md~xsV^VSYOM^G$8oWbnp;-3u%tCYqU!ceKNQe@nB!wFyef*qkHvyhV70ke~6h$QiGi_-|ZV3w>j8K zzXd9dC`ndUWae(4zePz|sEL;4MGkx{ezN9x%O<~=FZn9xbx>exE>RFO53dqJi8Jmb z)o$jN!Puy9*||af{GZ<~eq$2IbXKdB&;fOXEM@EfW)!&knA5?BZf-o)4fx_b)4!lR zOC@cb&)B^)wTgVn(z|>cw~3u`T(IAF19=LDSC;ntA1pjP$qE&(l&)eA3j5G%CA0k2 zCRK^ApgY)7R@dTrIv;bdgz)XBDTRwhMtTd6^r$YpQ+C0Jzg)Unp)9%`%+WC61*e-c z^Yb`g6_H;T(hl7`SQSHDc9`GrcuU_@I+~{6@gYTC_t$r=M>YCB$unCAnz{`=r{B;xT1j?R9fsH(l zkfP}U7hyV2)(^61>XWh@yoYS3_&Iws%OAi=4%Qbr1W%CU1ZI^gXy2&x+SV zNv5P%!p1!Qf~1ax$QI)t-p%T4i~8rcNBrrIBs zwJQ8)EI=9aB(GFTg5uGsU_2aJjj4stKjWy^jZ>- zGtbbrLeB_HB9p6{j`7*jYp=!Wtn*&v`|s!wD_amQb3qIzO>f1@gQNZG$=5z(R65MU z%)Fr7c1`!DG60u112(xF6EZp>K@fUcf! zP9ZUx-hV-zkoDFbS%5F z5scDm3p>u9R75l)2>YEs1pFIbNS9S0XB7;S>77c{6iO2wy^*SWBzyN^yPYzZ|8fGS z_54xB7%tXvXi%&Fw+PrAp*`%$hi#(YpOA9a$GH&o8ev0&O$Y&p-AY1;swbF=EbIhk zC$nz10$b6krp05%^`#idZ`)n1g;{9fm@lW_`^;MEU+FMxa9|I4vS76>%Q47VTBWkI^k4${9m{RMex2fV4g z%3d)+mF{MD5iLc4kVj`7_NpPMkvx7AJVL8o zaYcIseQR#4ueT3&>&fQTTOnIKyc6*32=WZ4Z@IBMDoUt87AvF^nM#*~bNoidqoqX( zpnsfbV}0~USL3+HO8=kN)y@45B-HBaE9mhNf_#aa{D>HYpUJK-P=MlTkbk63^T=Gs z7%(}k5ly}-hQ!B!R}R6He?i-d?TW)VZ(8;aP^7)*;x0X{GeIm&#)re{pC4G=~cGdfW7W=)V z-rUj2dXc-V7wOxF%i-YlyG*CtM8;Cw*(BHj&i;Fm3E=Uh(Ww0wcJ(5PY2@~#A!f%u z!jA*KUpns?)-D3BjRIX(G(FeD(?o=d?>3Y+JR7X3-*6HQ%s}V0Mxx&!;>J2{^1_Gi zb_?tDyEkgK{7iAveQ>f<7F;>{NFH$00SEr~<)91@JfT1Qy4O13l|s>cwY~}3&a30v z4hC^*$GIPZSm{3ysVh}WbERTN8%EYUk`##2U@>x^@{Lh%M8bVXw)6;Z>V2+V-I|e_SSL5; zHPoSUp^ICz*;D!-B0Nu2`r@`0TXhnQBaG}6O*LM+k0hjy?JThd8dN~>**m*tKhw6l z!`aPKUOA&T1WZ3Nq(`0XeDoNmz69=-4SVx zgYpM{hZSNxlfh$5K3yI*3ykJps-A7{Xc`MS*Hgj?#zX+HQ!m&#Q@+!bsW%2lK^#)c zmr<;1^uO#ZGwq%Du9b~N*n=+Ui1?zQbv+464_B6MbkBaQH=C+ye15}O_a-}#dUNfM z(cSK}P13UDY>MpLs89eD)!(UN)^xa$aarFAV1jc+nNE!^A_il)V13s?!bj}9xNr)o z^IOHdn@_UgtY(2?)37C4*I%Rn75ED8;EjO-O)-H&LGITl(UFJw)&8ruG&^!q+aAi^ zrQ%plmUOomT1qR2HEtZnNH+~?={Ev5t_k~q%+k+anp67Ms}&h1()e@Ajf6H3O5 zjvdmoAIB^PMFjUtwZ6IKV(`T;Ql0ukYsB`l%SE=!DvS~0E;6?&|PDB&Sw1z-V1)`u(p zbJIvD^Wy)4bn(#TxqVMVr%PEe7hVV~+&lQiESF~`t8vgDBPsdoQXpyNkR7%}R|}7C z<(;S%2|zHaEDwl!yCi#O%;|pSo8)w{-s@w?cOFd4s+Xq>rW(x_z|>`~iSlZLA>(`A zTCC5i=d2!8KUwDpH434+ctIq56l@2k+76b*(w5Rjf9rxFoId=9TZieyT&#U0#%vS! z?uNZ-D)d%ww1@6XTFIVvWB7&BoN%+cOz$8Zg24)IhY$5XSWhRs)GV}^ul+@s4&xnk zt>6x2%2K1}>i1@plz~uLmd2?4Cl?Ku;lD<8rRC>9uiux&RvaVSg z+}BFoh#iioE#;>3^VQ?g7PyvcL}*@?EO} z{)a1qrTeW|Y007!+I~}&a8rh*3dQtQ&*zUQ2fO7J)Mtxq4PNfq>#hL*7nQ@vpQwrs zG?hs#Fjp^Fazcw=^HW%Fv#g>NVU--6XRbGWb;sygNR4a}3|>u>(L7t1*2>=)+5VPX z*af?oR&GC!>lfky0Pd*8ngJ^crKo6S-E%+ubYuq z)#^*J4Ku4&VqFmt2jSJVMoy+@ITh8aW4b3-i8tu&~;RQQG~SLksbhKd78EEHaWl1#{#?XVYiwqCUukVO7i;CTp&UiwPaAjM`uZpj8_j z@`kMq(N{MrU#nwnS|4HHok0OBr0?}^-*(d3UMusDua9{@h`P&?RuzQLyp3_6c)6VP zg)u9O1s8>_kM!ogW@U;`#<3?-&JDx9w)QR&B=4ps8$IfMOjGuF{%SX<`?Bm&&0MJ{Z^o!AvQk5B`y2AO4B&X-1NbttqNGjOoDnR z`b==;wNanOXx)tFy}EZydWKJr`ysB%WO<55Mv^qRXJ783H{x7y^I3lmPH|5C*jb#` zO8u-eEACmA=0xt`UFaTvd7oXOqJH%v+AZKjKX_F6=4c=l_PBeNJ2Jl^MRnABV1OF> zP^RxjjJ*o?l1KY3Nh;BFLz*XP!g4*T$&zJK4KHJ6u!o7#Zqa0k38lvsi*QF6TYji{ zQ;wiq;MO%3cauqooPIK>uTP#oMMZN=TV!Q|YNH=>gllWuRAH@Y#!aVS z7!pt&u~`N_CZ)7;?Vzia(CKVURTj^-L?0x5jsHTZe6bY&HrxYDL1sg=BSRM%F<+DA zGf|C3wePFG{;^M%o3sQ}l-g-TSOsF4*k7RVslPf8Bd>{2TR>70nnVhXvuRTS(`L3f zgHuf?76|+eL(Bgn2LHoU3WNYiPj0+`=wWQ2ev#k!ikHm3XHhR&Aw62U-*y>*0;hR$9L%nE)+OiO$?7bQ53< zAQk99!tWr^JZlv^YU3TM$h)<851{gmDGV|375BU~b{q;%lq4p$f${3Kbmvq%+;~8@ zwW3bsn~fwWF5F~5+2nx z;r-KF-$@ND?F-i`Sa_iB0^|I0_ojZnUU#lOy-&%VTOist!;kvVgq+IP{}Utk-ygTb z_jIs1Boal7wi_qEC`6=`%(av+)a2b&a=qUVr=0Lmh@*$5=hV6p8DhJas7{;8Roa=; zvmapc{JJLDSy{)<-NGZfntPH(QK;i$l+fRXVtH(_Qb1tJH{GFn!Df zCDZS#kVDQR$&_F`7RBkv%&KPsVQ_jwfB!6 zV|)*da__fRNQ{!nuj4?)_Ax+2YxZpLr>2jG&*-V9$lgL$V(AL}>d~*l8Bm0Z_H=k7>Tr<$H>qQ5`dl=Iw{{jt~4 zs)&U|ohC+^?PU~3Nn2`}O?;ORC?%vfd`2!m*CZ-HhHV;R;y8;c9G2|JuZhEQSd~kW zuGyEx@(yd@gQS58k}EzOV4kD#Jj?!OBHA!x?1R2`Hk~gA@Bf03f}LPJ4TRVfu!~!` z80)jrwebO~u!bJBhL+IzoOa*8AO+&I7KpA~&a{Zkgy1c_v08wc2}BNUb*w7s3<-l5 z8c<`h#Dn12cHlKIqceX&L6`wk)l+RNL2yzWTw#w0z%iG4@sM)K@0H*115fPR#HNxg zI+1Z6%>Rf}j+XXf6LJb9%Fx_C)rmK3ruMmIJLKcxeQu2SJiQtW`CZi-%o&2FpPfykD!Erxiu}fx9g1`h zW^t+tyo8YnUxCsNO8LP%&b{jr3+Lu5Q(S7BwP+q?|D29ZmKc^kWz|vsE|&Ra4Hhi4 z+sx8wQnqzn;q-S=QB4Y@+NWuB-$kKi*z?=ZoNIx4l~~I1X4D=ezD*r0l7llp=in~) zn%w1n_1}Zgzkb)7wCQW%#V?H23UQDNUJ{Bb)(kg6XuPpmT1%8 z(e^9s5})HmsibL%Q@3Tbj1kLy1y#!&NMAgKRzeP79nB7FOZ0)7pYx}@wMvVQlRz#X zghns3VELr+=`8sD59`Ni+*Et zmOKK8Lhvc8!?bk>Sb+DpF56<>S=ld@vkUh|)yg1vB0;1|{ZSLGf7{eg{LIV9Ga29N zfDa|$tU#s}BmjqW6p-qJ8RwsmqVfZuh8bfxr?#$?2TtvlIt|SzrLx)QUZ5aCwk9Am z?!TYq9iSKA&@uf5mH7+Yo9R+B@X)!tl-jLrMvex5UfVK-PDmu9tbUsfw~RSF4VL{1 zKDw5}eL4*f*QV+wNWz1x{kaJR=I1e+@al8|vOxNztLGVkuYW_`zcBE{s5b-4KHR~^ zJ$j^Ycl@-R5b)_>l|hwPlill;OB-2wEqS|S38g<%uo({iZ09ar?fr)xL{eA5kBAw} z79qfxv+k?6MQ9OpoXVpN01%`_Qs1zgj3+9jmT0^2d#c>-Z{!Gj%s=rz8Y)AI&R%%jAc?JB6kRK}N5@7-rx)ssK6?dA8j7ycTTX0dA=en%n2M`NSMwrF`< zi!mzjM@$nO4H@;70-6TE_&dQN1P(_&-P#0B-yXB~0(&*(e?d*P25s5v3C2n%`p5FO zZn4@CQ}92rzFpikECAxBxpv)V%VbhaS#K<`a_+kaUo_PK8*M+*AX!sBSP&~#jHT{+ z8_|M*S~zEPmn&KRe!=UHFr!lORDYkhqfkM4N%pF2xUyk=(RVydutSqn_ zqY;{vz2p1*4eqB`Xq5|@_PGG{WGFPy3;UY-LGYCn-S|ehBXn-Aezo9?uD`Azq8x&E zcN^u3pcCp|O~p(UfHmq`30(AzpG96m#uOrn3@U52ahK9j8QP<}Ro88ne921vV6!9c z_@!#yPVt#>lv!Hsn%iZ3*wc}d04F!`T1IDw+PY8yasK#w0Us_I*(R%BsL7_H=Z>K} za4>S^{I$Icp_ATaA*&AK1!Ymk*fa9A#N6)D2eWi-3m4Y9&SUo=?|0C>=fK>St<Yw~%^TxCAu!<^58+$at|*xK-iFU(j_s5zzrBYlQ+|vQQ}zP6OTKFK(7_Z? z0H?SI_&@N$r6ql~OC26y3rTi%HjLxll6_U{vYmX;bE|GIrd13ZoU`mkH}7m#&_6pf zCuW*i%GIA&Y&$~HhxizLpXfK)DrqI%_$R|Bw4Bf+?UoVf<)lIAA>}ka9F~Tz33Uw& z$1C5FlKp%+(XrEHHXB8LD@P^-hlR{%2QNr!YFHOQSTLY#2AKoJu@dpE)ZL8d|~_ zgq8Y1aZk}o?ki1xg;@0tOO@yN$h<#aN(S?-Q2spNy-dG@8#vULb$4j4)kW-LEY_f{ zkvpat>{Z{&jaAEZDfDlMPUg8!+@E#Y6%5+GkUI3Gimp-kA&Y4%#$_dKwEk(2IF^Y9 z*P#lSc4K;C$^(rG|KQdmtOTN4Pt-?%xBqq=!BN%Rh^Z^8Pm8ZbM;M&hS?$1wnRZ&a z&|k5FshpEP|3HC9^IUg=dj5i}LfOOt1>lwc&VF?PqJTm16?n+08$B#t(=Ol9C)sM@ z*V56D+(h+DU!|86eR7m3&J``pF5EGgXYd4=r+)Iv`*;%B+U9F*BM)BmO7hp3rxA>)Ig~#q8zaZ(TuYkfbN{M()>+ z_DA2IIUHJWuPm@VSc@Ix8CiX zePZApR^_b}bHLu?+%VZ#eP`soHJ6Eq!04r5fR=5a$f*^pUE!WS1lDmiP!TrIB}OgP zY(?!8MXg<^6*O=n50w3kts+bds_TX4m3$e!+YuAaf9i2zKzuhQijuy=UE$&I8kQIq zs|GBxLylN3I3uo(v+O9&T5)oj(LLnN@RV$R9cLwnVlleLs-7Q6LrQN}#8BaaF}kQ0 z8cnXuWy{M0kE?PVO$8EWFNRyTEmyyu?>sV%9@24~s!>GH>ejh8%E)N~-8=P_IK;Ce z#OrSpE>^60rhFf)Kc0Q{RqEq@L$>)ckhJIQc4OPa&-TU9r|NdW=aO7&BS0rW%aiz| zy#>d6!xLpsdp$&I@TRM26DPPI4K8ToM=t!w{6Q4w36Yr73VX++@5QFh;wxD`i+?<$ z%(p1PtWgGKC4zMD`PczML!bbeeqv06_BR}&Jm!2#x8EA(5utE!F{ic zEmc2a?=?%R1%0$mBs}#JvD&~Yc2^P=Fk*$}8ceMy3dfO?WR;_CWNa#Te4r&wiZhF+ zrKQIBKZmx6chYq7ub@7D^l|zaV|-!y#z-%ws`lB=aUI~RR8ML>IeB5J+q$fjWg|hy zY83EejtIrDtd5EnAk(sh+y1CI>TB|?BBNg&49|#K^QT;BN_?LK^45*v5f`u@_j(QF z>L@X*HS~bhTHRU?y1!5VbK` zGtyY2Ffx33hZDp^y1PObS~*y(t}tw1$n~SJI_E6^Om8o(YDpDF_U*EGiK+5?&eAhw z*_@uUv0E>-3=Jc5<9!(b*M{F%>hN2z;>gd60K1l``?U>+=!fHl3gh_zMdR`o_iX8M zJSr#=1<2pad9VjjXc`r(ohJgVpRKLb=;oxK^n?a?$}QXCE;svjA%6&UKskc}00K`c z^?SxX9IJeDEFv}^_8qsu){Q0!3I8YyWwsI9da)NC(<=4u65Q7Ak1GqMs`U@UH63cZ zo5_TvKM!B4nvHvlX!f<1FJyPA-h?`uEDY0%T)sw|!dvs@yd$Mmc`cJ`%TQgs(*eMUXkP}&< zkI1GeTvcqxj_Hmi3KrT-W!BO5*JK$yG)vb)Vu*FM>M!y#cMjm3o40uMYk|JE6CJy5LPW9M;w-utXcr*cPf?HTN&L2m zh*+NtgFAfBe+jS3jQ?7nEO<1qe{p|^0?`c4>uSZXEVoFlPA0x{Z8l%YgmXF@QyJA@ z)-&=&N-a$zyk)OCn-4mMsjd0F_^HOaJPD40)f2ig^fe_XQPfrnK92ugE)F!d@k0r19>r!Pc}-)VbzTeul~5+ zJK-OI!g_q4&z_K5keW*IFhmL6iNv@rbuP`E0r&e#pzEQWe1Rx4Nxq&X-X&ES2hjD- z5C}R$rh5G`WAd4#QiKfP8?D2~{_Vp}2(8E#7%w~==5;s+CeywkeGCQ>pH?S!=3ISE zWP-2GCDIKYa@Ou2tCw*eh4cN=n{_Gd_mGLciP^hCwVNK&9FR-Y#bl+mth6|2Vre6b zd6LKV$Hmr~Y8v&Pr6rj3sk2^u#n>xd4ow1MT)VzNs}qSgwQ$>{9O6TPbueup;~I64 zIZ8n@E5Ck}*~xV+O>V$0!PflgfCRr;F#uhk?>}NC-x)!7vMGIdBfzbsO+s^mQQNS= zeSW#ww$i(^kN4D_Ph*bZtS0eNU1!(woGmB-*to3$jK>IueuL~F4<;WzyN<23h(_w` z&5LdS1zo$Q2#sL-JfXyQP2yMDYnQogB!I$jidbHMvvfr)uxaqw5?({|CVc4;;E-55 zKcX@Z=uT$A*YDr!tUp*rjg96>x&;Z_Rz_p8}L7pZj;q#i}dX!td;^( zTAzuh#Ii`){;x(kG=9!&-DKhMlK?Bh2|@aZ?x(QHPk%v;xtW-fs(L)6jNIMIYN^td z(Ot>AZt|#ZBw22OMyowc0d*R2HvbSe)u!s`O+ z{!K(m>c-6rnjj-+WDY$MjP-1P3y)S3sc<9Pd_mxP6g+>NaW2p_t@qIac_uq=q`gEluZ1V{MEuK9)m(+tp^z_>U7Z&i}6031M*Rp_D~w15pFHjh>O z!#<_$@Y`UdqUMV}T$p2LZ7*HA5zGgWeX`+V-iJ)EM%joO5#G=>{Yf{Qs+xMST{fyT zHABmxojiWKPZWI@kN{Y>jHY`J;Re=@D*}IqDioolUW)G^bdW_yy>?pyj6BX}C$RId zQqlR&YDRvJltP6l!Q}Otp@<)ofYVoZNJyq~x1L z8vj2@bj)cCk@X*8*Tn=9V29!Ch8JrsUf~8(N!r(eLKt7%bMpWMtJUl-OXK@&QS7}6 zwk2IrcTb)KcK_QSAx0dSNeqL1N1-7%ev_{+D5W%zSQ z0Yn0;(=#;6+eo=t`|%Y}4=>#%`H&5-bJRG1RrKf8f4bxKT?r|t#R7kj!qoSOl1TCp z*3&%aXArC2LrV|T$%0j)m8JuDT1nMfPVuSl)toa;5E-yL9C;43NqqhAp9B#CfaycS zhu!J+G_evcwi!-^Bb)Vx(bS63_uqr$l_U@jc^t;xJi}D9J3Y!$bo<*n@%z6rkg!q< za^QX-Px(b|tiTii|5!-^@mMB$AfQltaX6|v3Dl<2!w&O5MgWw&m=S8=JV z_gx=vzb(TbYeR;?jSthH`9&<;DnaVu0~GvXD4 zI{$0dSAdr`U+9%B-U5XAz5Xe>j4`Biqq*%~gYJ9lq>|=Z`9FW&n$6cA2Xz4AM?C`N z@m3G~$8gtmH!`gv2HHb#qwNvui0593%jRsH(#d;W&UyUsH$AndP&OQ`etZQ-T=0{t zCpa&V7vR-P`z=C=t=F6ssCt${7jKVVN+BvtNQ;6|XUZ%SOnlIqE?-{0LG}kvbTdrp z&Q&{Zjof>Y*t+u_QDL^NuP!k0jp;M7mY*>tbRiNXT*;3C@h@Kk5t~U7e?iuCv$5o> zXu_qy0DS6KN9C*7oc$o|aMurf>lVsm{@b>UJ?uovTq-k4ulddV4kNQ^$AQGR&ocHZ zIO0F&J88S&3Q3>fuMrW!*D#3KVEI5<%$K)x34xT#)tuqw!#OT*#F&Tt`Hw0&G9tca zW*CEaSf4hTaF6>bdFRjXB4;WW`K(wR-_6c(sb0#skDsCWVIb8{=p5WON*N6Es$qgH}!gG-TKP5I4XDB~n8PyRRlJEo?eE55j>Cp~@B zrj;(na>51lFjg?GHowm3dLI+lwQ46|nEjrc^a<^&3QD{azvM`o&pB()PtBi&`-+n= zurX-_lLW)#!gdK==!EDEUfF2CkM0x#fxuU^YRd`E#*k%%lb_gY+;DG!~dVPKYniQxvwmo zji@a&bHEW)Q)JC}<4H-;{=Ny!<&8S=?E-u$4Y;Eb(p>|LgPT_46;W1@xr)5{<0^=c zpMLz1`~osUBU9@ltu6#X&_+%_eA$xdn-ls^=Ir5`IZl z*)Y9p#=H`%gs}iD1rlL7gp;Ke=+oeCV^J6e{US|cR$fe69W0s3f8`q`;`P=s;$_z@ zL_QFD+ZB`~GRnr}3XO{T@5aI5&}Qyt1=OCu@37? z`v3uYxt=J6PhB}ogx&}QZXWRv@Xb~p!Iss4hqU61GiFX~74=?Xt~_-~Y%^3dv#a`C z{2y&(c=9=FgD8No2OOc!JAg@$?zDmSNb`$Do?7fy42QFoz!>5b7W8CXqtSA-%s3u2 zU3sfRf?{dY_SlEpL;n$XHWH)ZHf_Edxd+G}FVT=1n!VQ$v^{xv^EIKkvRe3+#qW7A zZ&I-f=TODLrd+-g50C3tMLR>G;LC5O_ZSRf*Bt}ewP*~^t>{rEbRnJ_x>tB`uU zT|nMEf4Uj&gP7Q)Lld>P%nZ$4`)QG@zYs?>H(Iw~YnEcTb1jpD(F(qtz3%(v4aniP zwN2I-J&oSWLacwx*=i^-+(dR1fq`g9ibvYHMX`W6YD~OxV!0VxZ|_)%P4%|awx(Gt z8Lwz*yB_geR?X@-0Bq?taUH1I!b z*4bvvmSh2}V#Kp4ZvvQ3g(e++f3~0#JKOo{wSRJNJ3UpY)C~}m4xDQnhxXOe45INc zn0nAxE4OOmP2KV^?}NM}v&``$GV@~m zQO;{F1vFh=px~sExL-Q+d3bC7RAVw!g%f@79H16F%zMW)qI5qE@_5XdyIZ}nNZS6W zcNrQQ`0y|2N@Cbame3%;tk}({IBi~<+w^y2^igzR?Qx#?-+FRk#Y{QGg=pJ^$Lx`M zJM1vp$6U*2#dp5a8lbW{rkcTT)0}6m$83>5TcncrJ%xWAX>RPz)tbIaC)wlfF&>1j zBOw20o;5{ppcY1SD^^T2ze?uAFjMmsc2Vi5OF4UJ^nTj?&k()=DqC9tLs!rbF`(^8 z{DB+2y1TnTQQf#rbA9!VYN_YxELSBYFMy06Gl*ZRXXr_|$^7 z*?rS~>58oy`_rmWL|by);n;Nl3ljZ=_Wv($C2Qxw0tQ#f)Ll7gxm0Q(JXmUnJ#&XZ8fekRKRVH*(-TD6Z0KY3AF2$Qd6@?v2J0R0(U%rqH)IRShvwwy}G|Q zwPdDauVCQ$NF}kwFWrU8d3a{ETy~^< z40mz6Hn6gA`CL@Ci-i#%iaXQ}(~Zt9Af>GvE?aPYX_zZz{kyghH$#%%Vb18|SulIpw+t2tETmV)bg@__kL_R?# z1nedKXD%har)#ET=8n-Pe)vHe_)k!-B(%NTwG2F z+7J4Im?pn3$;@i_x|({lfg}}^SvJeBo8ziRYQP-k+h=dVG3EOQ(k5OKC4Ggj$Gi5v zxSG<`j^3-9Nh<3*jrwlpI=v0H@_ve-duNsf{icm z+x-$*W!%f=q&ezNaHUw~DqU3l?EK>Gk%Q08Ms(3G6$dqaf)iu>sTL;wn-=P>?_Bg^ zhi-nMsCnm1lp$54jq9*C$-E=pqB0`ftcBsPl``GaBvVbMEXO#WMG9&+gZkpu*GjNG z`%Wuvk@ct+E(0Cu zPL0pGph@4&RGqkb(*)+&F5P-cVd#El2vPuD0y&QUPy4+8JaT`pkp(3l)mH>FQ$@zt zJcPce9u>X*CEPBCWsY`PvP|a|gNXxY=}rtb({0A)h%N+4-^@p0|_*`j0 z%MLAe_&nS^1{pyK@674Sh)mBj+dU>FwA(RH85CRJi}a)ZLD9gt6yL@mp=3$m^@};! zva+P>dh43ww0cNAhxawn%95zy7reqHkj%iZmzx^(vi-+ZzArX&9)X!dtY$ zS%_#eS2<3N^egG|{L8xs@ zHGhdEic#S+-$DXMw~l(NNT5Ec@*Y4BFW8{9YNwV^In#*t4Ml)ZR-c8vD!w+yXXi^Dc6+A=N zDY1yp4Fs>2%j#BQH$zP;!7>z8(i?(cjTD{RPdgS&b;s z7d!X#O-fU9Q#iHqDZKq(?R{rdQ`_2Z1OWjtBE3eXOB1C@iE}! z=XqVK9ipZuvFl~&cFo8AUYnR}dyPrg^dQ{~k7&w4%NA;N(QjR}c#OI1E_l*OB)j@D zDzMFa9?81r*)G|o^ab&)c`1Oy>RnwO0aE9& z61(b7@`GmBaS9R{uS( z1E>}HC($_$fN1N@kdtLNP~32ZLE_XX&BJ0OT_EP@wLM#sqa|S4-Kq8D~4VWDc_9QHdn-Rnk!Y)(9x&=70&epq`yZ za0AR5+(Wh?(fCPAv&mwyO!(b!<>M}9MYj&?iNtmJ!S*hulUQ)#v@gKPXNnG-V5_+_ zy>=8c(XwR?4}Q>|>Ui}%D)eZ_R~wtgUi~RD1^ums#$s0nR5`nu zE=aXv0>Y7QkZ#)vG>!}IrQi^YN{Z?>o6No! zRXEq$3G@9|GvmMd$whrfAR9#wC(~G_C~Y&12)<3g)`2`yHgE`4?emh%lb^1CY1;u<=JTMDDu5KK{R2i_W1N*LmfB8{;|7rCC97p zUcbyUdp@uF)x@@nq&Qsg;ym>zWBWVlNF5U2)>W|&+ft+Y@5BD6P}&VYkBCB&@2@qp zU28&d;W!|Xo}tVk7m3i!va$6syV14*i(64m*y?g7TCx)EC04Op3#2mFtCMaM4pFs$ z(`sCRj1Pv+-b(VWT`hlmAxG!o>Gt-siV=BE3EB@)ObIcOI3&J4fOevF5=oVg4#A!u z@SMPZ5=nPfp$va%x>sP=+E>!>~heFf`>S}j4G+iyZYD*6j7Br z)gaWOns(w`VSiyzPz^$(UDW66yNcP$sI%pK1{GW0FvM#VCuvF#Je&!Q9+Ny(PH2R) zVMtd7-aI4Pd>Y=%8k>s=bN(J>e(Khtc2VaGP9h~tN*TK>xcYH8*eU*yY`?~d$<#}Y zNl)YRU5N!9!~K1h9I_1!hh@uJIB!Vlip&UI&|F>*p|K#r6B-Tzs#AN;kQtTw2?0zT zNaK>aFF06uwy>`9wTJiR>M#r)v*UQZ?Lmw4zCw#NISYdjd)L-Z%^nGP>)U4Z(H;60 zVXhiAiO|Ce1)k&jB^fO~Z)+rzRIZ*sa5-Gkgp&m}jhxIQkgcRifSeXogQeb{n5rd3 zCN}b`FJ*r>W>>aSRHF~Im26y3JMAXcYt!T>lu$hI z1g&bF9C{2bqt!oAiBoa6olzB%CV*meLXgZ}rc%D90SF4gA&D8bOUA&{W$QY8*Z1lL zcK0UEVo|A^Mw*7cY5e4|=)f9Hhs;GEpI^AdtP!0%cicRls20A7yeR6N@hI;#jOn~2 z{m*S0^G`51Hz+zkUhVoWBYA7wW{laWi{-4ES24l@e1&Vr`{g}Ed_Odl5*3t&IjWJQ z4RO+C$tLU!kUIQe9$sK1Xv|~e{9OaSKs)jNpZ_ckslW7C}4(ManRQ<`NChhCPwe0~h0t=tWk7?ungDXs*biLj1 z!S;O7_AUrpL-BrZ?&ounpMy1ejEnY$h|K^cfc~L36HS#`Tk-VX)y3XCW=qxYz0RLr zLv{~utR$a43g8eRul7R4diV9zHf&bNyq2f&F!EU?e}7H`;iv(~Us{E(2q$|D+aA*` zDcHU!e)`Sr9Wy@Vh%`noXL`yd8guz{fbHV$Uj5AOPtYpLhJti5a;>cyY!1Ep)7vg z2jIg=XzbwJ{10>B+?vN)Py=VGBatBbh!dpB8;0>D|KJbK+WTHLS!@>4{!k=BoK-PS zO2jW%d$faa6S}+)3v{kKNDZm?0%-N?l)kvY3_eTT$~RNB~Ts5AEwd>?p92 zV-RFht2#!^_|FcqPYLl-x|=eqRBSVIQB8?U{_v_uJN*0k9$}TsKZO2>5$_t;{}X>t zK~tp=P)6m<{9YUZ^s@MFnsg31*>AkVi_^jnRsy%~hO9M78}y%vUyquICTtmDFYUv! z+ryw)@Iqz)KJGx>0iOAB@GxJ?U157c#HaYl0tET`E=V6VZiF9R03*k?0^O@S-Xqa} zcpVd5R_fsxce^uv*nMa@CBlz?H;Kd!Zm@*kk^f!W@5eO|*X;oZa!IcTZX~B(Yb@=7 z>+b#34}5^Z6*&p~_LYYx$i~q_Z|Y9iP_2=?x>bcmul5My*$?JU-fX}polIO^Su9Q2 z4I zv`+I8)75UeG6I^|PJhj}TAop|BQ>cL_Z)rBH5;pgt-}DuJsCRpd-SOn2WFbCj=7GD z4X{t>kyn#UiRkk)onDPHrx_K&J%#BB&3&+?8Z?n<~LR0^Ev_QujMw{ zSBg%^io6oTGiB|>wCgtU7xuc(d}b=*mVIze3MU82RPw?N2S;s^jI<4*KoZ6<}_7Gx-4eL*dofcDLWzFulWl6DyDNp&xpaH$gz7m~F7LuOO+3|r%lLTMn|TrqO# zl`R7*-tO!1^YH#?s^r*MWFo||JA+M%x!?r+qrw&MJdS(FI-bdk-U>g;6wv6H1Z{)G zXQAl7P!=6!9h7!w%f0cJP=N#!n!t~$d9Qi4!ukG0PWeOlN+ej;ycmO%3^& zdx`CmZPK0onoD@bwNu-suT1nEM-Qxbi$sZvN=dOK9C-E`j!!3@!B4&i3a6QT_(XAZ z3xaV0c?4Z%V5nmKRkY6|VOQU#*(G5r4%SWW}Xf`Q+&OiOs%;slsb3wD;z6U_av=!<{_Hv;o;n8&D3rIsc^D@GopVQ`@uB{@`Z;;>+7^J|5B-h$&*A0)M zd9W%2%0q_uce)z{4lAbHfgP{tS=AS|RS(n;+uNmIA3f{8-H4{DIU4q3`3LIgsMp?B zh7*roLGP91wuq(H+!<%A`pd}(gFGgt=^FWM*R-# zsHLQ!S4|LkG9Zoj@kw6&e2+u*j!}}0gd(%wqUXT$1o&>umNKh?d3ZA$$sJa_jzz^I`rxpvyYyd4JZkTvGJ7Fa2Abd&~D zrX4k;Q5fc*@4s@gO+mh5jw+ZBUuy|sYtv5-@HP#7D-BxN?i zffBWtQO<*w^(eAeMI|E$mLFUxsfe#=&BL@9RXoB!9FTqmlF{l;-ltl&A>PSDf|2>S zFQ|hXgagoJD&BKC)#j5$Zq|tFy`@jhOPDvNf-c^NOG=LAy|s9*Y#R~JBuYkBt~IVj zf#h<+&`%U~WxDGy{!Twi4LA`TZAdpfl4-P{fu?@0|yojK0YFj9u4R z6Q)HKNMLs#Ci#X6_65psf|iEP2f;TQGk%v9qqCL2SGI`^Byp6Zk795JLMoT&24Ge!7g`XM^6#rd%}(7Ia1pJP-c^L z@FVG$AWa%S=|cegCf@B3uy+Fekxqmsp5OFl;1Twx$ziTN<+X8c!XiB~46|V>oDuDJ ztG~&M%IR`-K);XuoU#!FW2Tl8)!0wN+~ctX?Q{Q3RNM50`Wta@<)aUGm|qYLTM9A4 z)!A5}B?X4yU1brb?u^EVuqt1-hcEfDfA7I6Ij?3<4cuXom(LsybY&QI3}rtitqR+F zy%(W%2xGH#Z|@}}F-bhQoTw#6E($@PTpUi>HW}0N6^zr9TRX#b{TpM|Ph2Q(x^Fc1Yy}id2U@>v?g3>IZ3O`~n6Jn*Wld3klHx|3w;c`xzyJ`XITZ$IB{pMVJO% zAD!C!_d0gJYueG@4wgINJbNYf+yM&@sSKbok)q(=U&DW_>wWFO2_dr1X^_4xi1I-!3?H>B;Jo{&G$KG$qK zb)J1}NtzM(Se0j**gxUc2M`Cc*~sk!Sp+OP#;(F%5uSb6EV1+|0OvAP?bYgBIVS&p{cIh>m-Q6nK*`2K zhX=$?p8S#9T|PRal6h55Ey=*@&@e^az&`W(O(ytX{VCn77@-efa|WqCwAXu*^m7v< z6=c%K6&!L+iAan8@3;@k>OwYtzn_AqVOwvs{<4MwS-lY_+w-Gn#eIY7*w34tDzuvGc1Jn0z9Qz}eO;n_=la}* zgHH}fghj|Pv4)Ocm4f-9#Vy>+p#-#a0~8@4My?jz~PQ@hoaz5)S ztU5+RrfT8^X~-Qjj3IQOHkWyy7mcp&798=6@=T!^OhvPyFujcyYDTX-2CbiFovBA3 zazZI|T}U`_epB=j6QCC@(6m(THT8`zD9o=LSi?Ov=Fq!nE|@5T_6^{wB)NHi(1~`n zHTzYU^uW%-Upc95u5iL7wr5VxA?}e^?1@t|X?ePNttX48N;eATd6-oVw99V4_@2Y1 zTAh=(;aH+Am4EX6)Z^EmU(ejjmGqHpQq<2Ry!0F#jy~tPofuWK@tWyogo%Kn3G7OM zJ5YPbRSHet$@z>Pwd zu0i8fc+VqHR<4RP8{vju8^JG{DN#=EmTz^f^dP4@+z9{jl{|UypD$^)e_7J6I{maW zZ6>!H4sCR8;*L{-^fW0nbpya96A+Oz@38kZ<3j=B$xqDf!D+2z&lzU9#0zC;ty`6k zI(pwt7WiM-&D_*_6ty{mX|3a@&NmGX_ismQ=!ng2G~aH1;**p9xO(;NNBXap^Hy5y zGJu40>4F(LUdl+pRe3whMX3s#KVYvjG0)pR{U#*W$Row_tY=VW=GtoWqGr-}T#Q{O z5iv?d=~2g~jp-K)-P|TgN5%4NS_RW?DXXMiJYyvARkx#%)~@oJ$U#Ab$U$O6dzYjj zS+u`{^d-eRR4XI+lzkzEZhNYwk;pmf#-A8j9=f{9#T8unw2?hBkJG`tSe2equr`cn z56ct`pSp7ASdZT z+DWV|g{j$Hr$MbN_(65#9o-LK%T_dRRW@A8G(dYi?>xBH1B;c`T2#)p9A###dFFS` zn#+C2^ygs&z7YEb6_ur*vT*bG9P>KKM_-OoTke^VRGse=0MG6?t(4anjMeD7bHr)w zN~^U+U6`qFm7)5!opAu!zJMl>{3&74Hxu(}lMq_zcRQoN)~W?FTw4hlSX}ujZs90c z=NNlGu21+OK6v#3f!iRbGE}CFtE3z2znADFVAX&|b5+~eDq8e#u~yM5nlPT>R+Z6H ze@P&8=$rT07_GN8Sy3ppS78rC{?7H&@18K)N3mn6BH zmnGrWBh!kk^A+RDK0N4YuL!BZ#3B*MPhG40uAu20EtWUgv0a=q(Hl9fNZS zY%yKb@6MMy^m#+6$tE1!DtJN(7VZyAqduXptp zTr{7pN^3Wp{l3PXS+F9;Q`>j4OwVS7cKX}m9Z+=x&FfO9(7ne0YtDLgMyL13re0yA zOVF+iF!~Z~-DAj%+vcLMjN`68ztHvW^2T3rjR`nWiuRivOLnF@{lGeQ=EnjaS66vC)d_9KGU?c|KdkPwMS!Z3ps@HZ(g;cu*c>9c&WZeUN zebkGgv#r{xr{X=*M+?zjw9P{95es+CmF%`(0fsY3hIcOfO?8FYV-Kt3!ydf-0jRqM zstofk4;CIK-Hc?_9SBl%tI~10;Yd5#{GJqw;_zl;s;8almyv;xZUIvh{A}`iF^V>T zCdQRAUVZsd%M<2`aIs2-ot>Q#Exs+x&uzk~z3=I{c|No6dJ|uX`P8mj;-D_0y~Gvv^dYM6%tXYG zyY5rvCFKJ}v4?J&lzgglbTB(Y7xm}}?4zKiaII86fBK4Pun;WAvSp@(rA|Bx(-N<5 zI8r|1vx9JY+)%~q_drbU4sRB2OAl2vg|ficYmsKJ^dWyJNYFwni7%FyCa4l^^B=21 z_MVFF!@9XQe}z0DtzXlDIG~svLIi2uupPPwb(LZj{`J7n2?n~_7>+P?1@DOXoZbHq zFna(A{g3`O8OZo~0^Nv<$Gxr%@3^#f9wAK|t6+vRC-TglNWGasD5kcORg0xq$tp^IF8yU|D zsdfJR(UYbkKj&%IXE%4pTS{w0N&e$rdjsOAS3$IFZeYi`7pXd8&SO^1(skR>)7ZyN zg7`SpbrpzX{=&6=7-IY+V3Z*POhTS9)psCpABOzfH+V`O)I~c^;K0iu$x1YxMFfTK zJ$fexurVWlYMFr2AgY}KD1hbo^%XzA+lbnx!D&i5koxk4eHdYl9X~-uQu`5U!a8T2)sBJlX-y$e(-D z^1uVb^rt;0vRYuwt4~G@aK+p8U@x|2M}aCh=YYd}Ys# z_PENJcGw97RsE3vI3e`*)2&WO72Kx29o;$j7^=}6^&ehO=QtJGMJ_~;BXsuq-{SwV zv%kzPGii!9dN&`i-?4+NG*`rb+%fR$iqMvTE_0|6KV}`WiwBhDuRY>`q0Wcj5sv=H z#;{}>JMb`9mEk`rAhs>u{NtT7{?ho7ILOz&iCq1E`mtFRFgVpN7UZdF#xx*akGM(v zWfcB8gyWaLNf!KNQY7h`C7XcnH0<=LB4U0+hSjTV*@&RarXS`UyUlzZX_y?B*ipmV zk=~s5z6{CoD^CV$9Ns?es5*1*H7johICUBS)?5L^R&PcCC@pUWm!(D8^l*1(d9a7* zMdr|op5;*~+IBYRDJey*Hp$kej+z|x@|2FbNQuy)f7;81#q-P{=W%nFg|Zezs)Rq* zIt$tN)gUqr-)45Z(^~uG+#{^f&-P(HJ$hTr(HwWpZwqOB>(2`BcxKh?Q9|LFW@;{{ zGzVrvid6J8oOx(TC5^Yr4&R*UgU(GqS&(jk*?84$+8E^6aW`VVr}Q|vIjaz)VZ1@- zV1Dxj^egTXSnX{Vt?P2c5>oFdayMU&mFoH8!^V;R^7G^SWdUE}H+XI9f~5MRWbJKp zn|q_HA6~Ir+8i{OGk06|Nx}K^y|j$iH$Jp-*YU_5;rJ!`EX?}| zjfM6EpW$DM{e&cU;c)~zOZWHS4WE9+)ta<7VG38co)!OX1~OHfWFKy?n9kT;o0|VY znJ%=sQmuw7WXQYZ=2Max>HJgw`A%LD3%BvyV!2TXu?_{X=iN){}IoO>qH)rt8ph!Tq+?m zmQO8*>p?{LWyM`KBk`(dVoyM+r3-3m>T>hO3e2NX5%lmknRc=7fXoUl(l8QEacM5( zJEv_4Y_xu2sq1jQ`gWC_|7mJiZ0;$gn=jJiy2lh(6BgBXiAp}*KgS|xd+egZ#|1Zi z#Vm_VmrD;76Z1zte<^qF$vIW7Xlh8hlFu{k+k!s?@z?db*BBJ&WZN#Ycgd!p?j${w z(Ea101uMV8@KelV3Hmegh4)e9VbWpz!fjAZvkvIVN?(@zjGM#P!qw!%2_KP%Ij((G zOx3yagp(Qv`kh|0v77h!eB?F0@OV9cm3HC8taF<2t9=;*d&&~M_`A_h zlZuFrj__x_E7tL&+{*3Z1m9!r8tVlLIv=K4SU)dhh~6sZTKwpVLPGk~TyILw)+I9P z8BvkCk(_GTOgrjQkY4Tfeq~I?Z?-|#(GA?nR@nEj-AunSl>7dAcV7NFHQV_Ou8|I|2(0x z6#@l76CfSzXM5XPDJ==_uQ8LuRdcGSFtedx=;dv;$`jpvE0~uLoHSqh^_G1rI$jzn zmkId1pT=-F<1nf}belb!??*|}HT}idI8XqNJCSI}pe`v9qAafO!$wd!9_6|DHlub! zWj>|hE`pDoMn1&&$M3`3zNRs#8}>T%-0c}3Q@)(GBbt_(HoL8O;KqaWKdWQ@jRg1g zMtWe+BaO-})G|ey*0N#)EdGJP#~KW8G58r&qpaWD4SqaGFQYYD7=D?!Q{g;2N^1DY z9&KvxL>`>UP9$4464(_9N1c(!VwaYit)IT3|As{lmK(T*Kg1Ts>Sz|G#Hghps^+u2 z@#JAGcnkEnP7XhnM==H|F3aOh4xYFHkN9({onjA?d&m5cX34W4 z@3y1jWbmCJUNZ^|vkz*UrzoH(7qXK2Vb{uTImsw`#=ua#t3JaxcG-rUo%^P_H+dg+ zTAScr8PegN0=@dU9JWR2d4Hc*|5%WCL7#c=n9zs2Gpb)aeT}>ZR{`Hj&Cl*XSyw>) zD@U3kx{0tlj9%ILGh(C!{3Hmz3-oCxz8CP5_Y;v z#NFbA3AgIUgM&Vnv>hGD6zZ-|8k@`)gJPjqOFRe)MPhe;XD}X;L{j4LJo~U!hJ9G3 z@gE`0B%ZqCJfv<&Y)YPKG1h724aE=|Rx)9<$$>+=+QqJbk+P8t0>n;}viT zKz>&CCewV6x?2Y+`K|OCEIU=}?O;X+5-Z-UcFp)~ixEF)mO(37jrWQ?slrJneV-kIoZp3?svm?5ejv0qWnIcXfKXw*%!4l_f9~bw= zu%cf-)>lv7Ki`j1oE8`M(41PzVEo v+#_XwPjz_{NPs4WXRuq74}@R*R;|F$|J%=REe$x#d4OQ!{4<|qf9QV!pDyBi literal 123256 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

N9==Z zwbs^((Y#t-T3O^15A{`!W{!(qTG=#@7wZHs1y7gxt^d4B+7Xt`jEl8 zNmoS&KI0vq8DFcoqvANZeunf-V<|3eYd=kU=yWCFfFr%I z!rNIKc`yRNBNRw{~H{g0COP+yrIP2%;7TQmKAM=f^e@~LRA zUVqIU_pFFY24{;C1Cj_1MUOQNSG)yIZL#{zbF4@1+)C*}z^eL&?a;%^dQGq%STFcT zN^8c9!h@JbuycLJyPOA@67!7*pVR8Q0gZ}bo?x$C$jhnS8H$L?!dz3%L*)fl1iXKo zxP)5zH5k^eCind}$x_CV&;h~}ld-Y`#i495W>^{&nT`&4B_cvh)aw3%XOBRwr$Xg- z8m2?Y1ASFkyxQAa-N~utN8rLA_kw7}1l8#-QI;fVO4I>xrTN!4f6`aTRtaFcSO8mC znk9;3f#jWh7iG2iY?O(}M9(DP+FJM3u6m3Y>iuE`_h=v@JcejaaXs&<+6Cjv=!Diy{psF zu5kU4sSf#G{+De)KgW#=4S+xCwjiht&rv~`6F^gnq=nm`YsWO}-g(8XkzGtR@Cm%& ze}BoCjpP*x^A5Gai*uzLyn7xY@}aFPu6C!0S7?clN`i+@2Z@R&#T9wbS(v}oeiA0m z_oWZ{^zJ#s4t?(BB2&@Od82Qkv>dry!6(HeTd9}trMN!YjZgiNb9>hL4iL&Fc~II| zcAjSPPPy_qruNi_@(xqvLj}=ZmTgdpf@b@-4u8QTDU2^-7nig!JJ?8vx=}>d_)Fax zn`eDNok0;R`)*4e@`@Z)HGdhOr{KQJ@uQ^Kb$sp?Wc|+}HQ^?fWqT zvE8J`YMMgB)c9xE3A7px*vMn;CpGQHN-9`Bs$*>_4jBkrJ8;t3<|aZpQMmeRo(if) zHIZqFRA$?-uZ_MJgr|L<@l1gOkFBVg6~PA(GSij%*<&qPl84TWN`wc43J=)=9ytFd zY1})FBv>s&$c3fh)shTnxjBj{rpNduZIelCr>i;}84I)IJ{!v`T3XX{KlALD#Q3*= z<&fN*ACIa%kKw<&W;tX1@O6`9gry*gnPmMyX`;yU*HL0 zC6~nnrQx)*C5_I?4m$@yX7!1Xg$%W&Z{n_9SHoSu$VRj(8P*{6;T}ra1Wd_{2Hvm( z#P*|3+uxE8lZ2$aI6s$2Q}2V&gYCHQjM$FD_$-5ptdS0HS0(obCy-Y}b{8nxh}@{A ztZ8h(PZ5oewhRTJ&pR#w!0v6^D2>t!ms7t|VE0s`_4F&^Uclf2Qis(Jegn z7wT#%A(n7r0onj67!+Q3AvDF_3Q%DT9)>$*{M9gRjb_bptpczTi4NY2`!>F^Q? zK*si+fLt<-NY!3S9ORf7N-F|7+sJ>kvfr~G^~pM`?%2w}Ua%HX+%Fm!T8t)bTlFlQaY#Q{sLx~*|;9H4LAZmBL-+3)4n$xUf* z1JGY57Rk{D{`rqAA}LuVp@|YWYoy9#vuk5b&y75k-#Y=o6v?*XIc!Lx_cmxjiI`nN z-fM~bE6Q2E=iBgxMh|~&{*&kbywZOj;eSU_5W(&N%UmgO^avV6$U9UN$+CRi3_@uJ zi4WiE(|nar5V!ex#g3Eope%F|nFpGSSQ{k{E>(b{ly6vQ@sB6W&uljyxw|3#sCb&q zZah@FI)$2zkr~+cc-6Tu{f{8BSKuNM^2t9Y&9hBTPU#f(6+E;K=L@=3J2?7Hoj>a| z0||aam^k)>3z%2OIj>KKNNhR_STBTGJXl2XG!3ovCGuRpeCtJy5ScVryH#0B(ZTex z;pehJKL|C972CaL+5yDK@Zge|$-?5FKRS?YnMXgj%K1VD0!hy&M^mX-ohQxy4YD-qMF(|-D7Y~t{a)x0m!8y4y0danFy>Ro4ZNJcThT)ZYz7nfj z&mEe!@W_R@6u*gc^G<+cVhNl4=Y#umgaUZSB{{+e#Xwvjtb<3Mkf6-%KMe&pqjSHT zc4^We|`wR>o6`x0$f*qZq*$G0d^JwB>=t?A(!zcgvz zVrzZF;oE>?r;EyTo?7<>EBmz}CuUDD1HL%9KALw*ZcGpGu?cea?WKt@Jjj=(D$a1# zH=9+@YvbSP8m(++kj^S6v>q`2l!+xvCWxR;uKH}^iTkP?r* zd1jP~Py4k-PY6u95t^e}PsR3!1zu#68hNu2V+d5RC~s_X`D*O-d?>f4dH)I_EjZ=St_t3lL7WGMF5UW{kK&jQZ z=q3Ww_f@V<_^OGv9h|36=MTeJxC43#_=r3q7|#hDWe72fIyew^>S;>*2bbgRGfC&+ z`!!N#{Wh=ZCb6r2F;9Eq8->K$di3O4&mDzhwu@;9M771776=nH(hY*bcw}G z#lC1^*Uv-xP7dSi$c@>#2jrSn(XL`m<5G0%Oc}HC|3m*USui>!)OIpU_QIdaH}n@* z00^#P%^WA7J3K&L&UIVys%nsvwH}(jZPDAYgCl@=B>DLxobfkF;En?Bi4&E#;vh)T zD06wUe1DTxMAd>X^r0_FOxrh`_^2d$XBS!ylEL)bYAz|rnx8He@m^0;;_bXM>0Pn< ztJfyHnR4f=9m=lX+pz_E6S={p*7*NqgO zss0rX2mc+Li|7Vku19iMA9uj65;7`#k$#ReyM8_Nmo>E?yri!$>Vw77!7k0_vC5n} z?r))WhcXyj9xm(<2ZqCoGDHfWB}o;2q2oNX!`9iTIi>u> z90b_MD{36;@^(Hy^govC#!H@=F1g_QDI0^FhuPQ)K6s@jHUECuBn%U1GdCCHKePhHlo3RkYKdxP)_75L%k^kbi;g z+~3Fo?h*S8E6BHH;W+M%?yqnl|La${N%2|1u}t`GA@P`+xZ&L-p*JGk@5-qe=DP37 zr(qL$nT0>*VNt;z2?;epw*7m&Zg!WExwO-uf-!Ol5NEd8%UHM1ba(puN@f9idem3yb~cwLWX96US(qGQGJlw;9d@^ zM=M?bC3S(Mqb-$&DgG*wpnX-3B?e_)fA9*po#3~c(V?(0CQVQ0bY@X z<-y9r@%&K7|={bN%Iy=#any4W^X#0Eux_0x#64{+pz)kA!fLg#>{e^{^6gct#6M z1$HcxI0ULV?5xGBtbv&N1vnhirLEkihXnK$51M@@-ag6Wk4cl@i@kl17c?yoU{px{ z-z2VaSaCR>iGoN)SgRv45l1o@S8C8fl}@6wJV{P|g^Ldb*!96Pd;Y5u_OM^uRT)=lsy551*#g3i)N00&;3!$u4z<= zf5Bz-`Dmi?Gh4}}d+gr}_w&XiHpWVo@#02Az}Iy3B~h9)#nf>+~P+`s;M z-}^z;%WveBOVI~A6R~wD2g&JDXnk4j$ks^CJr~n? z21J2e6WE8dXHA?RGrsE+uAc<-GVe|e2sATiHCZE2+J|?=Y&)HKTZ)GB`zT5*5a`kG zr9-s2O&F!`@SSeNp4tymsBK9Oa#lOUk#l)G6j@^r)s-N~?bUD!(*oW?~jZ?y;Nh4WBW4?iLE<7Hgv0mnLU9sfdl z2hsT=e zU9nr#Il=U$e+J=lIviy%G~-324niT#u}Ivl#U0jq@i#@>Jo~4dvgIGFL>Vlv7OW>j z#O=1renBu)5f>_mU5Afd{npS}2FsG##VBO$EO&x>g<8AD^i+>H(@I$-+(Un&RgoyVqJ zoPESs>t19X4~S_KZqV<+)`_`(D`?~;Q6kyw;J|ukBf6KL)j>&{DM9m0rjYIXoGQ1A zzVbd?TyqEhLB>9)|K{z=9SW^mTsrY}`^ExpdEf7?rw)DnQTg;&KGOwots!hswpcO# zE>Pu_+^csiwNeG6)4%c4DE0CT3{no^1WZrZAwc-hdXLDN4}e9}?JWV<->WNO(q%NU ztr7*2b(~FY8pS6hrgO#wq4uXN5iMi+8-6>d;0YuZ_O<;Ng|}_9LrI#yNusQeaR~Ph zKx6SiM%E?h8yu84t$dB}25d*qMVwlc9u==5D74HfOB^ig*Q)_m$u3QeZ!vRzr~LpKLLc5I2fG2E(X9VXGNznjJp&*Q26#!VJIael z320?6t=xE%?{C{a3yG{``+hPgJS(E0!8GJmEqC20=JM+mb(vK-%AOUU9kJ?2_+#rM zwe3xM0i2nF9q$S}Y9?S7+hbP{bAuZTyY-KiIo~{JO~kn!a8i8?65C9Q!wI`!b%Cb^ zRHR$40IW6a&BMK+)wo$HObxcg5A}0Q4}A}{7|T~TR$|+jz^NVh`RDGb!VGMJF*rS6 zaS8+UZBg7Hwt=eE@yr$&?qRrN#`Km>+4$iq+PJ!+SmkvPOJu_6=;V&vYD`|oOY_(9 zJr0&Hxu%YAI2m|rGO{YaV<=Q?^>Eg7HTg4Ys53#d#Brte<>lJ4tFJ;1FpC&ATZ#Aa zZZ)Jvp|wA5l7M0GXJD*MH0A*z0`43~Mx24uz;62IcLYSd6-qwpo85ETcl5wSJGnMH zhFp5y;2=ul}V4rMC#Z}gYwkf)!e zoxGMBv)?v5=Zv|0U$Jbn(Np23p7KoWi8%i)V!k&iiUQA~j`=YTw*hP?;hjUXDG%&* zEZUkuUn}!oeUC0&D4&^@Dt^^hW7uJ)w@3oiO1$C!jk)&>YpU(mMT4Ly2uPP2s;D#t z1f>NFO+=)ll!!DDX;RgYP^5Ph5Kw{wqEaH#i$uDJR4Gyuy7WXK1XA3O-&*Ue^}XM_ z_CEVu=g0ctB~F<$Gfx@MJ;u1lJqVtgR4$VlD3woW4%hA-2d@qxVM>Eh&8ashr`iwB zHT%B5H$FM4AXVGYdi86ur*cYt25pOjVhasI@)KNHF+<)bl=Z&NZXbyMwFbF9t_r7)jIqF4Q9)*l-YuZKC!hOnDz zWfXez4mU>Rw<|I0K`q5b_d-z3i{U>|%{H1E^B}WIwieXSqVJND-T|j_9kcCCi*ReI zqeW{Uom@c?w`9T^)d!c*FP5tpuy*~-!$ZKo|AQ@qq3t3nH&<`0q$bFJb;M3zhowT( zeFHaB9Y%@TU+l<^Wjc%Fx~R`Di}psJjCFm^8&|x1S2$rfsd(r8+u(K^z2nV!ula!0 zok;&udU@n+uQt38;+L^&{N`TucpP#5Dj;znQasin7X^5U*YjTbjWm5CEc8ui!d(2X zUrW*JT(NN5$?JVp0Rrr<{{XxH{$hWAMpRI4uVM7x+Cp^4^e~CbK@6|4P2QKf0hDk>527=US$V zL`Pxk;wB$IOyY+{dF-B;KJ0nh$Rps0@I77&9|$9aBM-A86-^q)?CX2cemetQ|!6Ww#9eU;9#R7^chP=OMz0>#|G4OLmxWdL##3%zCNA!FVr#UTFdS_# zVcX_eqnc5@?!7!LQ?t~E7b+~KI!Sy6)Y_K!uk%dd8_F{rdpz6N{p|>_P)kwiK~xa{ z98V>Wpw=w|*PE(c@yn()ybgthVJ3{|Y#;(2eiPXOtANI% z?xB-l0*J?+dBNAa$^=!^Z)9)GBz1de_;{ZAZg;Jl=Qe@WCFX_!^*tCX+dmVhEk>*Q z4e{uPPT00DuIiIL2-XfChvnwYvjXHF^N~rhxD~l?#inFhn%*=l1SeRsfb@CoZO{>dN=hxa||HhUqE$Qy(-w2&;e;#dFIb`9~oA7G?Ro}0BtPw+V zj)>5EvxJt9>p2pY7r*ozD(F4`e&c+PjU3C6{MT$qTjRwDTO8{q8#*Bacb@-jWAH9x zFitr7nu^7dEFf7xF`bXJ$*rW}gU z#MryfLz=oyULh^*zN)bETX4*|J>b+@H zgM-Uzsmt{`+HV@QrOkp_-k;v+TxybSDXH}nU^(k`olPozqA3U374mAfGBxUq$Ilql z9n5(91?>aFzag7_zab77%$hC58dw1dQIN1iV)u8bzkW4dr}xnMsL5NRc9PlPE1ol< z9)QmyCXXkbV&#S#ar~$tVPIRJE#>a&pLL14(>GolK;Zkg2W+EU@1T|@n-<;ZMSluP zVgI=I>)P2cOD3i1DP0#YWvSk``9tNOX&x&_V0SjhvByOZ3@6jde?wMBFB5i23bc2U zOWf{&_5(sX?i zX2$ry_m*7#?+AHEdcJX0)Cg=>Tqk~?1@}6Ro@*%Wj4I>7=kp$419|*6Hh(N6wH4Jo zh5Z#Z@2==fBUH; z>|7;(xUH(9V03+TeX^s>;vor>JF?+mr#YaS_ zX*_EbZmo`2y&e3 z*-J!+)RKEom({0w>v-47m$x*Hq~kp+b2-vHpBD4`s4?AmFuZ^!T!WG?n2;oB?_kcX z-m&Ov>ozzG;tVNLHP80Y8ua&a83vrgHDIWgg#F3P|5I;62|;@N0S&&9c6%a;o4zjB_Q%P zG23^%XO<%>SDOf$Jxyedn-|8GU}nOO&+B^2k!F30`vnTJh{LgY91F0PAbuR-CYF5u z7e@?~!GCW;hv?R(VSnFH;(0EVK$ibP; z7||q2cLo%sN6!@)RKYn{l}e{e9}9|fb6?{ZGPq&$0D;`Ct7Uck^`_h8%s+2?W*E7@_s%dF3Mb~dG6%CRQQ8>7l zHNF+xharnY+n}8EZ={;~$f7n5mY1m3j2czC{d(KJ);PQw5_z*+WpM1F0i$q+06v?p zfx-`>$fuUpx+zBy#^efuIq3t@xG20bS#-iZ2sF2Pr>yImS#N9CDc|@JUt+9ceKEaY z99<{d;CB-C^Cd-u-VNoz-Z2^b)9mnLQA=@;{td!z_tVLiK8NE~e$t;ec3AT3|l_|oL*jWEkFMIB0QK6=!QwQwt zf6kqkJY7Fg*tXR~f;==_6h1Xab7^G8uS?D>g>8F7f?8()BoXV^F zNByPwEDVp^{J~8>;xwC+90z4yt5W0(UJOp)Bqz81vYoOY>sYa}C^rxbmvt1AwogA= z^5j*@tJ5g&yZ>Qv8PP=h+Iqq;RmyFbU4K|le?@k|n)*Pb-4(9POoZg-Eqghrf%95P>f`@ZEeF3g@{wuCUI@2etuK{&)m3WEZ zFr4LyKOHRiFPVFh8?r;ut1`iYGu#Os5g;D6txeWCG@zo~%4C2OAyD@kqaIm9M& z3p(~aL|p_&qnrZ_OZe5?BYj)!u%5FjXDr?L&Gp{(ym@vfJ=^LrbV^jv?YN)-pWusC zUC_Th&9<7d_u|(F9@?t?J*pfz8@6~P2%Hf;0F1C;W>GW-1#pPqz##(aL?aR4>ZN@g z`80|eyW1W6;5P(}AP4mbDyxHEAoJ`Y>j|Rk;?Mc)i@uG7+oGlRbnevBYiKx4_e!dD;1dqEUurdZ8&Le zr1!Ks38%cr(P`J4D|0@&Jo}jwQ)Q5KBU%UO$50BWHh*$*;N$V7XoANkmB)kxh&JI# z2qRiq6AL-#b3H1$(LTg2ps4fxy;}+V1M!cAJe(G#1n++-UA)vD_;vF3yeRXG8apGd= z5lF5q%|~_?OFpT%CQV4Dv*=UgSJ5B!J4N)Z2OHHeeJ;Mfey@zZ5B{o3{1#*yGhbIz zA9H{hIu`q}4ifPN@*AQGC#$j2k7!VC(MPZ%2sVm8RdRG&9`+f{qAlqzkGToQ**Ayy zsO(l@(QAau9&$<>ku8`km528u!g^4}0Z3O=vjP^M4y_oaa+%{vAVolWFoMu6b$5^) zv9+tqY|G@!R6F7`LYUx9ELoT9*Z;_S-r051q$h!4-%SU)0Dw6&z(-%5cF+`F6-64a zH0piw6WF{tSgEUn95lWvvMex^LI7HVsE1=8`4ng|>_;)DJ|e=CDwB^*xs$RzCVujd zJM-OP~0`4@%2-i9<|Z+;%$<3S)=4 zZ<5c0aOeU>lKx{ndF?FGlX_JXG|pSDN3?WbyIDeAx0;?_#NF?3kw!E;-xX;TPV$A< zr&G7UP!T*$))Xl&$jL|ObqZ0VJy+ucF{u<)cu)D}a?rT*tvlTXwzjuEzvCIV+j`<$ zby-X~&8FNeFBFzndbOLPZ(RHR%AoBYQ4@Lp$`S4dsdYz=G9I0G=FIH~g>^&eN6yOk zQF%J)>;Wd@%pIojJ(|H4ZK4;P{TeSHdS20#_TI$QTkXfN$!o?D?64q~5rxl&5xg?j zK%RsNLwoH7SS_KVCx~S=n8}}`>M~DfHKx>O2gK?#1RQjYj8z9Oo;-8-h|yxInxOVTtYU2arP1 zYrI?1q#C8PDS9&w=eQ+lN8N06Vhasag=jg%5jVN0H-=`27So3ahZ4p~@7%bI9%hXI zymwXkc!t%{pxV9g)8!L=SHF`(h+K2+ySJjkX4#aC`ELzo9qh^ZQo)v1_H!Z5lEGO| zKmc;=A`?4a^yS}F$1&*g;Hk@-~;scqK$ zDD`_OdJu*+iDUwrrJL&qC@cP5JMqB%%aFk~k#G^Vs74rseT}rg<@F*bHKEK+{g;rpc4( z%{BD+^aE5MT+C$NDJaEx4!QnguX;9AJL2_!r;6QpxgCDojj$Ahk#ihu@69Ucaq)gT zwMTJ|GFmhh{eq}iJRN;$zCJ}L)W_q~2cqM!rboz(?P0a%Hy4HMCO2lhPVA*YYUg9< zffw*fK0!VVV*vC2jd)RTQw0&*s*Y+aRh&U)l%hf&Yc%^wIqz9T-g$VbVg0nTXQSR> zG3OVz4=}9rSf>Z)&#D$W&idi8hnCq&S8hzOHay!JoIZcY^>kQ)&)CDmp6{72rs*tx z?CaEcr!JmFE@s|U;w~8%j!56oEsrn9Go-#q2z_kKyGUmyQt2|o z=b%SD#vi+@ccd?}v$;H_=`upMLNRv0f8nsX#jhnlhoQVyNSvpoHjpRs6G2>fpH*ro?Fi4 zC+EBl?rz_&iKMD0`>`jKAHk#)+h!GXoylk1QdeMgdgJ5sXd8^5_mf5!uZ&#z@A3iX z=cHawT}q3Td1sHuqwibN_%97;UMPC=bY}IuoTpRo56?N9e1X--8_ck)km0}C1qYJe zNwmMQ`?{#ZCnMFSeBuDQ_Coig$D_?P*=nJUyoAx#Tvf76DWH3wn|fLG?7>u*qrCOJl5p>yo3{G)UQ{R)Ax}R6YezP2SwCR^5O0B%?lQ`rPvjN?Wb{*!^FA zeUBhScyu;B8lUqU5>uTkQ=2qyWPc~*s&0DtQx9KnR=qhbi*=Xd8)ruv;A5+XLzO1s zNWt#`{&zRHx&%_A1THTOasG%D;~a13@%T(w~zddw#H&3kFiAf_e6-F3|I=3GB$4A^#9% ztH*9buWlw5bo;VzT)LVU>7%71Bl_~uh$;pTXZG0d!NgR3QW{^`?-srCtD|JOa>I_B zHnNwg#UYsuS^4=l6*#h=wNKjG+9LGGC{pkUOxe0Fa2zt((R;tV)9i8f?*6NwLieCu z)!odI0poM|Sz-@4Z@zv|Xe2Iq`fA#dSI`qkZvtz?d$9eHCEIP6bTUHS2) z`EvXH6G?X5onP9xmtW+{wrWas7p;nNlVjhWiPvu=S~bWiVZVlJT|8mr*7ftF619L3 z#9<1*7aZR_%|(2085+0UU~K3)fw;87^IS4Wwo%wkc&^l;slU?L#L$z`tRj3Cbl>(Y zNW3KxpP#+DGsbV_8!qHimu0a$Fmk&BR0O?mWRg{kb`d7o>{_tHb0yLzx3VO z-S6yg)XEEno7l^=2HtQdy?-E4lX&M^ZqdC^CEu=9+kY|Z4F6p%;@`3D{wH4h`?8Y% ztjD5~$P)lQA0?@R3#sKcLUp0rL!wf<-VV7$K= zWP5NwP#sv)Mjd7n+b-=fh^gmgQxk!MVi4+&6Ir4^TE_0P^+1q$R46&Ui0Vl8ETCQ; zEG?+08Gh|WJ;Zz5eD+N`k+ey2B@dL|3eK9h_Jmnh2c#$$T)G{8 z#ga?1%{HhAQu zs-A(nQeOG|Y2jm!2Fa(0exwm{{2a$I`ZqpN$?9b5!4uCXSJm!HWsJ*SK*Xl0a?-cH zr9Smg&tR0|{J}`tkE52*5}MQyUdeMyu_)KgM8P7`e7%KVV~}xFK*sbHJr;^(_66Qu zwpK~THwG9U&{5fl^p%Vw!aJ}>fa?59dB^I;tn7V);y!Psa@X-Bk@E7X6Bhox+))n3 z5G2kNo`$Wc>BJy#i?_GJUZb_HX-yV^mY{A0DVXhRvQ! zPR0sh-LVPNVgyVpTIeR3vDE?UX5gB8C2WJGPFHSz(>3MY{R6zm9vq>3hE}RrFLJDT zQm!Gcj%drR!Yh(HLat8O4yo*97>SrorDvd|%H}x)-+xJn{-!T>1`^fv87hkqCO1%g z=>2L)F|r?F4!(zfc>---?;OAOA3SLm)fp)O@V5H)(s?!&Q*!V5;;~D*7AC;g(39Z}Vxs-&^Si>HVlW=*f34Exq<>&%3D+?*T?Qurw)IM-hx zgMKZCB}QNkXLXuYocuN9fz9~(?#$jO}!0H2|oIOoZmo)c-4lvz9jYZ zrm9(c)Q#{7g9KO(Z?U0JW6pq?%8j^$OK&Wy`>)F`c{sIa= ztU0BJdyb~*^L%Ttn24M}KR;r5KIz%}yv z6+gX>3pcpKbpq~l58WOu>;F3`jsMd%<}Nxvt)x-;52e7A_M&vV_$_98QzKwP>9}o| z&Jv5Z*TvZe*to_VDVB0Rm<1}jO5$EQWBgDgC2lI+P9;_{s@peIQj&=2L?1&~j3U`V z_bJ59ITSk?iQ=|v*J``eF_k6qBvnlQS(16=3KHICfv#p=htJ^>ajc$H@mcTa%xT`5 zc+uD<3}Rvz4E7*XM^-@Gip;yRr`SHHt&ik-1Hg z;qJ6XRoJ@I$o;%eHg@3yvHj<*B*XQ5JhI7CM7R+dO2Ar>^Gn9NAA1(=Y0Nx%8@Tl* zi8FlC$C+vA1Lg@*ojw8@;ptOO1hd)?DlkpU5|KGxxcgbW)t)tp8!{7#Z;S`UZs_5j zzwnLNvR-GzZ%){L##L0mDn{56kBW-*pIfN1zcldUQ+q_#Z1xGJj!?$|r`shKe4ou* zAshpWob(?}!hoqFFGEU9zS2Xqeia4<(K>)zoicAafTa0j$J?7j`X(&oml%?u;dd(5t^n1is@4$tlAr> zx>#XjOXPM$i>E*1f5`@7MXI{J$313( z)|B(9di_)vxirwK!@;(&(X?o6J173`oKfIck;M~td+D`oPaUd=8l;j@IUqIMBRRVf zf%K&6mg;*J6}Ci9*1TQtdU1;Bz!jyGvmLq+WafYaFGWRv?mI!FwLZFSVlP1C0euMU zoijID*O|VgrsOevRJD{G65PG@zbWVbH)!#9H8}qj9(^G)Q$xM6tJ82A)95@%yX(_0 zHfj8Zl+}CFBmCgy7B`r;Hs`z0+VTr=0!R}{f?G85Dpz?9)>*z z5H|y%B+?z2o_*vt&kBF~FI={Apqi4}1;#Ni##hwnD z#6IfxuUl(8J2QVgW5x&N$0}v;t)S?|FYRBUFW+*=2xzmq;gg?0D^MMM+`*Sg<%GoP z(t>FN=Rrl!Z?6KGU61CtJTWLsdPR3VxmqKf279&YVe4^{Z>0BJl+N<2&)ovj=xem{LOXD(3vy+4qNZci56(6IzujVt9ngq8?CmH zwJeyq^;fV_E5E!a?M0^V9-FVw!*bSef#<1m6X`bPa*%!NZRUqX?)y>AC?>zX`y!g{ zY*o>hl-N0Hi=Q!&UlA!CBTz8c`21Tz?VBRDc8LO>yu&lbJrbXuWIV}}zBnPi7xjR7 z#tL=+rMVf|mU0uQ(x=yb-%w~&_bi!L(resEEZCChYKhgXvAWTAsLz2Nc2}mlrrtzh z@m%VonNZ1{!i>WT;vNqN98`~={(MaT6*EW>grGd&$s@Q*wKg~d8Pj@8i;kY5ctnNw zF4E5>Oc^g-^3wc}fG=_C7MOe}69(6#kKv&cH8aOxTR1>C`JQjRO7$%;kc_?bJ^^wF zB097WAuG~ZqzR~Y7$5SWzD)SK1E}G@)MPa0eN0~J!@~#qVu=vx=iXMGW;}B;2e2yl z0XlBK{P~erRuNV9(=g)xDqH1<>*C6J=UO2vJ!`|M-mSE^61_+>W^)>+72=UzI`7uK z)LU&e3TM7EnTm@>mOtI=XHKK{Y4b)jKKkw$voo1Q)GdLW2Gvh8 z5}%T?2r@C$n_$z@$)2Ubk4B8D2ITK6C}fH{3`suN8SnEH%VmRVpzv3pK zltb>YecOYsVN8n z0R%WPITQRW;y|H5Q|oPPisGhKk3?WX_ybt13G?}%9z@Vw7apnUO=O(a zkA^v6xx^{#v9m_q@k2|II`I#hn$3==imsp9;iVm=8f$9|Hi@oOP@xso=r)NnBR+jq zcOJ4T1TCb5Ozt@LAp9ue$R0R%BQH^?4J+EDnd3L>8T?V7=O}2~Y^Par6%kr)VZm~p z=a`8K!#-b3YF^SAUW?ldpCRV|FBah6))xKOBkX_r&wpi)|4)D4zrNpJNlt(L|NrU# z{%>c%q%9nN#)z5v$!*_!3j1X%A)`NA&f`Uk$u8CEG+Zt2l-fU+jlpihh!1>jVUo$ zeKQqcmT(sOB($n;orB`-5X?Fk-6rqWE~pfIhrWJ)bK_|Fk-6MqGo6Bv1@_NSKlr!4 zc3eD`ldg#{7;aKP*bWzsP%oEV_fk|;I4rlO2Z1=6a_U&B9IrNy@K zXg>Q}O=IF8vrv9To5JsE%@?mRFn|5gSWu0oYR%u;#fw_DyRdXzQ8NDFv zw3ymtxuL(yM!5hUco>Dx#T{ro>+Lv;VFiBH;7r*$*f9;GPsA@q7A`eOnoBIE6T-?( zz$fa&MWFB%D1x~O(>+cc2x0J@)990%Z-3kB@mMHnCS#T#Pr04cCP?d}MFPk%-)+L> zF#==9dfD?$7#d}8%EYPor`YCm9mwgHTvU2TKjnCbp>rdAA$p~A9ngxHw7_=^LrbB{-N?N}kxRAcar#8o=M4nB?|6*>{7;oe=4wnLP8D^ph6fbOPCot>num$jllQ z;$yisjfY<88F;U`Na?G~I=}n+(I87h%Id~9$Q=fH-XlHGHaEhsYP3@5Ip)6i9i#Zi zF(S@!HU&4jq`V4>B~Kl+;W~VQHy_@Gq6)cF0zBvv(Kl&P+7i=MgYFrF9-_z7+@$lv z?5#H1{e~@SbAcwX0O|>loMZWaT!)^KfKq5{w$^A2;$i?>Vq}7%ub-dKs_>0=u8fCL zf#R0D7v2fn2 z*H4p{a+Z9>MDC;tdjoKAh{!>eK7(vVu?8HGm-DqM3L0+AUwt)sFrYs^n|@4tDH0U$D8u#DDvN zCGV7u)@~fj zut};7aM2p-XWkm7oJKW&LkVi0EpC2=9L+smLDWlGu-wt&Jecw77+vPBKw>5R3)T%} zyw5`>5{=*`zUUN%5a%>-@)y#2dB|KpP$uy`qh%}4cYUPcwcw$YQ852 z&=6=AL*ZYEO46cW?xm_Yhao9=bgq0|TxXkAf*;SlC1>juSd@{g=Qo{h-A`u>?I5W9 zM4r%aC3V4D5Nba7*f!)O9Yza7x#U3OP%M%ka@rnMH+U3`zj?)Nd{{s3;i8|Q=6#6VrF%-(o!Fi}g6P>YYM@>6>^R$JM9M4-t;4&euL@lAfPn{HJxi5 zqFf-&671dNF=c#b zsHP!BgZz4~Wp})~%GWbUzW&mpP1>i5D;qn{u zWrsFFpTrSNuwgi`;ST>qvXU19if@evBYzo9I2H8q0C6^$T(nZ_8QGdVh~G5!9Bft) zMV9HK9c%<^HA2XQehH92`{+7!kY9OTd^CRrYtIQ5DFq z*^%pwBc1Dy(n||+1~qJc%wBk2ChYj(q3|(|4ihp0N99?i$1N5CU1<`WnygRN2IYsaK|#lbs-BS3n_wgW{zTM2&gG=v7s zO1L?~o}5ga1J%rgrP;pr9xG$-wp;C0bJGsr-eP3+QGQ%pl9r}VbRBs7cQF0+gygYI zQV>CA?G-^;hlWN97zL?D&eSf%4R6lh^g5jVP(kRMzroPUU#e#!5<*NG{y&9=|08t# zzg1)YulSBG0Y>2sm`n%QxOW?tv+*WH9oY+}oMl(HKR~uebk)4(>9=8w;GkRBl+0(o zn0BSt;)}_9D@s<_14vdXEAaBH5I5pycAKZTenZ-GrHAI-oo&Jb_i~nUXWhgljXM?P z%HAJY_~@~pKq#UL70&e~qAP0>wUy}K=_jLG>HH&&M((*k zC0`@S_$zio_*hZVb}2;_`4w8Rv=)!IBtN8Rk?(wOt!Aq#3J!amQ)C(@-P4+p;kFvS z7MR4(2)zCSFnl45U>u9Zzo7Gw;rZmETY`PS@pFGWwJNI9p58D~Ro{8AS|{kpqUy4c zQ14+~M)Z3y3=eE=>(wI_aW+v9JN9rmg^ zamjB%?iXLuF;oMWXJQDiF6tEkpqFQ@si*tMCo>59i9tnEr;` zUwjY}hS_SPz0ekEC!$DE1Zd0SuzDCbIo@c{j$>omzMT=7tOLb?)=Rb|`R^#F-;f^_ zR~m=qTgWw?{mqzFv-Gyur4GTt{-qT8SGQTVxf%<6hWFQPM8%2xk&Ub~-Ds}hGWw|g zpvuq2?)c(5v+41}ndE}BOK;<}3?bHYH66)h#U(0t1fE`_7QGD`x~^y|*VX_TjSDWM z7)Fj6+xY03D3jg%Ksf0wBkA=Y`Br=tm=kCWu&roF@M%PiE^zLG!!+M_ zjD)Ctb!8N?a< zJju8RCNw+{*r&r_IMHJqq)GyOU3?ZmN%FPv;J`(z`pWMcif^)QALl&ue3OXiK5y=8 zcwOm7?*+`NcHBuu);9V{LSHyS<1x5LU`4fF@9CSCUH+h&3h7Uu8qX#)rge*3Trur( z6=N70{RSftU_X@U@!p{*LIGe`?wzPpB%kV}<^wrsu-q{8r&XxuArMq4I)dtk2jn=!s=9C~@X(iecRP#|${Y*O|`zt@_^TV=?*IT9_nvn*Vz@Gnj5CsG$y=t1} zS!X(_+~b|Ik&P$M!D7@)cWB>!&}O2(K9m!SL2tYY*Ee0272Tmk%tD#TM(rcNA^(%&`>LJum+} zpY|vlG6{}4#(D3Fxf$zd?Q`^YEH_=4{F*0wdbjn_lk!YR%!cPHk9c>z;6tb8^qGe} zsI{^*DJ;GmTSe~;?R~n1*)ipGxi-k)GxJ#vmzka)MGlp?G6gKpj#7}H0BFd2D$;NY^9$4l6 zhFB7!5`6ow{_Mm=P0 z@UGBJo)e$4Lt%YIbawtf-5^<6=`1E?!GRYvzaT{Nm$Q{_&mR~N+GYH?d!M6LvI<#; zYA!>uU@MTER5S8~FI2sw)a7-{yuToV&G#hSRV^01t6zvxK-I{!bCB&})v$JsxU*f0 z%_YG(=GkKv=xs-zWiMsivG*J;*isBx2DTnX0nn>i8H)!eGzX3pPL#6(6>%0pP2z&* zvV}^oE_iJ?Q#48&5wAaeyuxRg;G1@sqaA{}I%NIJkH}4DPbUPtDU_~hK|SHGk3ms>A0Sl;wsx2WEjZZ|kc17X8bjx7Jdp}i$szw7$+jAGy<%Q!#FXb!O$BsMFcen& zNOmrHOqR4qOUHVCVyH?U11G^5kbOHr`E+`Y1~sb^U{o5f!&S(L-tkJvWz43C{&Sd; z8V9!HChF^{rqifNj^7ZI>=0!A=)5(R|1sUvm}pMNqxKQse=<^+WN99n;P91D1)$1- z54V5HgZgasuh;G}mi$?0LTyM%!fpf=_IS3B4>z&=$SR8|(>gOVt$>e2xKcQuant#9 zOiW&d@-Yb0)407Lx+pW{5Ng1az(ME91~np5BcQCvmVS+64o-{N2jRw?Ma-{Xc^o@^ zA3s$LmCOwJFQ?5;&+r)(CPw7vClt#b4KEN5KQB=-nvDR_zBG*)7=_UWwXAMk*w5g= zMpOjs^5;#gs3;z@nN(4@X?2meZJa-ebTifh)Q_wp)Uy2!1a%+I3cK4kwl(*%XCbp0CPIGP!R`JvIY2ZP5JuS!d@;~_ zW@{v_({5n)qnBOX`r|0E96%%hTe^(N%^+FzNd{C=*^QD+bPitj_4Ri5+O@u3uFI7f z^nlmW!a2|cx=Fq$&ohFOu}#upzw`w zf|0%J+E`6nW`*a3Wto4XCFiGIRy_#nQ#Cf)dkjrKGDC4ij*j5Q(U3-FREfLeH#hUl z?urkS+5~=U6Q1kc)T;^K&d;TyKOh_dKnF#e;V*;rbwj*hj1%{|xx9n@X=Yz-%wnm)|((`VblWjRemICs({j-y=Qx z4LM2Eupm(vFe=>66zQ*n^La=T1c2K(`g`lQ1 zfa(T}6s$1_ZxV^EMz;dq5I4sBdcWp{GTW8RQKbVd=S#X?q~!6reuccxt5Ah7rNVzG zQiUr#ePLAYC4&sEORaOp7v^`(-4NJ)ZWcN_pof^#Sxx~TD6INg z+}0%aDQP6oN}$`e<3z56MoD=-$5k50OokssHJ{TI0rP~;p$sY+=-%*3IF<7;orRyGLiU>LXp$vZlNMuL zqm1IG4)_l-omQ_*IiX<5^Pq2j&9wVWJA$8}JU80jH-?$LjwX8JGwS^EJjOkul4hqq zh&*7`JuO^Nu6>4Bd$KiLmge9=&IiaS3Lv8wx$IfZ& z=j-~2y&$WZSSRoEX4X>Ae7+cYvg3+|>7D>>n2ZP6&@!>!SjJUTyFGPS97d8bQkLK= zG`?acWw5zC-?w0#J8}4@F{+>x;tS`bi;$IPaiLYHC>W=lwRwNls^NX_b%B?B9uJ?D z#N1M~W(e!B4BI}p2X+g)A$TWy)PM|lx6d>aU_MuOuE#;PaFI|JB$UcQ4l1C^kZ%?# zq|U6fLo0ra<#$Q6iq1}4zS_H#X7a6V^wqy>4e&N2ZjfK$Il^%qJKk|9o+=v^6ONyO z>wb?PKbUZeJGbv#aaP=vhc8gvf=^5|Xb#hfd4jDlX%#V=WA5m=$HuHP_}#yTJNIT% zU^~~*#*cN!4f^?<`mOiC3D6ACH@^5cga-s!kms~T2cJxflHCjJ_y@P`ahe--mJLm( z0~_bLs~Aol*08AHPyKuzO+Fn2PLXzidvVF7v(LHgVa?hiTb`O1-h4qihdqCoX&!1o z(e1KyV-)8#J9B-oXBS5m+5(fbIZW3;_|?!b+S2Z1f=QTy+H&qAYR&$);IsFc5Cdar z(yq&kF+*Ohkz`>0g1{Y>e;~-gqvWKT-8-HfGaZTQiEg$N5#q<4++1os(-wvja?N;elbdas^lKnvn+AHzTgQ zjQy*vplTCO0g=b$`}Uooz3cfLI^k;7r1q_f4*5;v=k zmo>`H!TH_$AI1$fYgSvIz5&hRj4ZiUCw#yNzZEfv&BH~aShb;4F7m?y#3{0EVQc=|4yxb;F>vmh5*a-^o$U6o@{X*%((I!A zRA=^<&X3(+z&$4Gld8ZQA4X0>D>$MRs39{y<(kBUkzKcLF7{tbe8_ZC$vNYz#m&Qv zPv-@ylWZBKP_Nj448b)lEBzGW3i;IBl=5tJOX8iSi^N08XL1Kg10*A%B#sK%1C|3} z)@GJrW*7e)rDQ2Il_&oS_^3$g(KK(a!zD=ZV9Pr-#Dg!K?myTIjlp=1(jS_X*C^V| zAH@basciv+%gl*v7UiX(o8&>}uu84vG1K>LD75cfQ>h0_WE9(-b6bcu)6mx&TD=yi zZi9L6xdTm%;1iUQ1N%j5Q(z4pA&3@ay5bCp_Tyv^i)%Ad5#}y&^7L>G^a(rC*iSG> z1waV*KYKVLby3Yh*aaROFKmPPH>9XX8*A_JOP0?137m{?$RM8J1EXoXZ!^&S(&<&X z2f&FUqzg*ZS-ojIRrIR?f4x@8F!HDTn^^QW01UGO&aCiwR96_)0~}OPfYiPthUpF# z4D@m=z=rclWE1-55$OK)^yPp>^k1&{L#zqDV1(pA<=aL7WD2*+CQY^pvnl#FU@HX7 zz~4b9ctz)~frA#oZn zuS?yLMB6kZ7-ld=Q_eNKezk&;dfj9TzK0B|`Mf`RqGoPtGfw;T=U)gd!kMTg^BAtz z^c6GXPf7TThnqzfPX{sGK%YuEL;XQ3p-Zno1z`7}F({rL)hUHfv+`HBkItVq@)J*F zps$=57X56!4W7*844(c9*#iAAx|Zroz|9>hM!C$sw6$v(+RT`^o;wq$q|3zEqboLh zKJ2q5pH^2M#~Q4aF4~Wfesz-!ZyCAaUhjowu^k^D?qfs@u&kbaJdDO)0iAWE*X^~+I zrj)OFwG}Uca`*HD)s(ScKVtb)E~8$`JZZF^^L~QV{y@x(R45u~ygV~8R9F2{S$JgB zs#m~7GfLm#;=Uk#A2urvdS$!Ojy~$7vnXK6*>n-?eQ$oM5;>Y;Nxe*tAh_yhwv5xU zA@7z8XYU@r{80Hie>XzOQ^A6lqiR6JL3&UM2Lafg(t zj%#W@;SVKbW9D@pNA^A1cfh{HkyW40p2(lY{IIqo=)I<7w$M*EgioLwyaT+w{c4~) zV+*iE)D??=DR%h_f@AnU@yGuuO85UiT5IzrpEqgYZvyT>xGVXoWrgwF#o@}AmmKEB z>uk;R`zMc5T(N!O*r6KI0$KVoMUUQza6vRW1UjYz!5rjv6)E}v_pZ7Je}E%s!TpeX1zi{hQ7@ZypHyCyI)RgKFTR~ zm;cA9}$JPv+$0R5k8VyzjA<~{0^(zSF~9}=HywC)tx{r7YdJ0PPk># zsz^Su8$*@$Rg(V=N!;9~iS{ZXUB`SfpPq3jIPCeHyPr?w3lJZpR?1)ByfP}c^Ae^V zQb6nxRo_gEP=Im5S5e$q64qkxZnJZk=5}Dec9RUqw#C%@w6{no;?#hA&$s;ztmC~e z>W8!al{HWwQx64dJ>!P2jjM7mmiVoSoF zkGLdD-62EUBgZ9Wq%B|38bFm-UnKg2$!DX@L>QN0eXT1+A+@lh*=@)>%SfMvi+u>f zmvQOv6{eY-do_D)$YER+s>6Fic~0~dv0^T;z&k*;_2d6)?@hp={`bD|DV4NI5+PF| zvS!~+8|Nr&>T~~AU^_`jTeAf5py}aJ9_t>anWu?{oq$3qYw=i;Igi9$-;v;2c z3XnDYFac<%R1oamPF1E4kSmDaR^27Mb7oY#h&Ox5UO&R)Rhsu&-q)cp)q0v0{~gh)BJ zdnwk;6^wbq`c}xu+oyB+u>!5#}MvzEnyr$tuAkI}ok^ zz-DmJ`qhVtGlah9(SJJ6--)f4|2n7O6YI=FNwoK@9N10y!E`-(Cqt_uY{VGboHw^) zb71kz(JEZl`2_u`-Oq@-Yu0w}Jh^V2^3y77veyQ}f$Wyy?enecEJw z`uEB;iD@E}-du;OeNdA7FqpxYU}9j+UP}&#bog)|je%GLBo>SdHcn=7oAlww(^H2c zW-R2MlVzp8kG!3{&?(00mAyQLZdPHQMDDM{_p+4(fmFRHRPv&Kb>o;wsqAM*gYVnX z4j76rx;+%yj3`5d!<^HN9%$lXRNlSm+^OOCuJ@(CcoZcnE0C5n;IJh_7%dM4Ue<6p zUIgz2i$L%5xEW-h)N&|wzRV<5G6A@{8Ru6*C&-|Y|!Ue#vJ{U3#Wo&1< zRX%Ve+(({0y(XP+;=Kvq@cqKM*~UC{lqpPk4qe>=;14~1SR*VC>v=^jC;-+899?w= zE{)``+A4Y1bM{3zmPI#0FS`%FhG54B*!!#!pzK}Tc~V&xjWu^*h>9`Hq&uSnyV3-H za+7J?+aL-Qc_SvmIk!V1yjeB)?&EqBgXeo|Iu+yn(wz07V-^5*O{BP+GM^G-p|ssS z=vDtt^sRRFiDI-6^tby<|9;;Q=yV3wBWjgHoudu8zTUz;GWo2xEo$?KLUb8m)3l%s z09P#63PY0Wk!E$!#(EWAD^a)~%IaKPq*2u!vzLF|&|>i32-tXf^35#&x*X~PMo z#Pf^oxq)#kk9B|dYfi4kzy`19$U&*FfUBXg0#m*td4l+D0u(~=zXQ^CxAr^vg~QZn zsC;(9!K{sH#>EW3rfC3rYbMa6q}jV*KOwqfLg1TNP;m%^v^v00#Dh>O4p@*BphOK7 zGH76}-oyN-KaFkKi)QcJ1D+E^w;0^W-Qmn49!jP6Bl++2q>vl|Ks!ETk z@{{j|e(9y#JOYGI^NN{EnrXYQ*z@(uy zohj14t8RYDQ!6LJapp9Zgr@;=l5iB>4Y>QJuT@d`7nVHKTDf=DD(TV0IN+6b*%D=( zO2T(Uh$u3bLi-bG>LEZYN6)4Nv=E#N8s7xMuT|VENzA3GnZ2Fc=@FM3e3^4I1sTlB zZPeZu7=&D?*sIwgqvR`lWcJTyk0$rr%hWklwtOQyC< z`WK(zD#vc6J33ZU*qI6<_SbfFE_$@N3En7CYd`1I;`GF%GTG3=Mn=&Dp*^Z44xoMxvFpVO69z@3_cJac$ zo(hak@VQOaUUF4XRlg$iAZE(~hT<`>Ac397?8m}9e?pGf1Zk>1=Icr(y*thvP%D#9 z_V;@L2+Gxu%R@wuWf?%i4|6i)OVmiy&4g`835tFyWti0P+$+b$S{7Kf*Q`rEWJh!E z%2^Yed?%J@c%oJcLWK^&C(c95@)rQXJ~W=+I>fD;ZeUo`XZ_J}e>r(bNg_o|inQB7 zs4^p1knM^lpCs%=cOR+)eOW*=!x4B;Sr)pRp58`$o8OAvNmnwd>09$KY8pze&r5zP z@9pia{N&UHa?Gi&AMN+va7nztu7DU@6pB5DUOitI3ZSV z8?qe<49sm42xy!R`%s{K`=;ghsG`|TShBzU>oejNpShf zPM}M}7e`A_qp*s*AXQp(Ef18saY{F$bk-yuXUKR()eirJ=*W#Cn_4^vr?N@g0ng%a z{5Odvmv20Li@>=0;>j z8G&;Ucp}2Cp}Wslfsv2{!u^9kQw`mWM|;6GkK5^j5_IlYejywF?nfYK9~kid$kWAB zSqF^(srwut{fjbS!alLN90AJWzyuiM8vIYlu>r~`aL%z1n-e-P) zZqpH5C@H$oM0~R`FL}LLtNFEy$gv8e;oT`Q7cRZMpjhOPY_3Phk<{%Y6LFji?YZo4 z_)>f<5bY)x7N@A&qYuFq_Y~K!?kTgr=-t)#oEJ5A(eucBEa;{i-L%zi8!HUZXlS)< zI*vUqoEVclOICV($O}6sa zzj#iSHdH*bC#M~fnhW7ccw(^U)S06(>`wG}9EM_zk3ebB?O&okqbpw3as&RL7mY_E zpBK$3K3rHca=CZmkb9JtL#^Hxq0dK+?={B8S~c{6X61m9Kf(rbsqyqed`mo+tpUk2 zy3&e$Nigg45b-7VXyfbSd#Ald4SN;!^S9r!yaH{FUpxjzw~K`X(0C6})tH>$yl7S= zyR2XQ>g;A@+KeV_sJQv%E#FGpI8IBTUSwF|tZ@C^W7jT}os)_(+#hLW@!@D}*v=U} zq&&k3{IUT^-2LX;q-NdTO5m~SED^hXn+bC`Zd@>WVTa{;DZ^;)Ag4irH3?wura8p} zvO=}U)&4K5d(q}^%Wg;Fa5ZU?T_zVKWBIWa!4ggKgE_Q#R!#+Rfe@~{r=JNAQ1T3t zDL(O>-azzd_&m=%M%Q*ZA>K7+s>Pf|An+Csq<#ZB#4z>TF$ZBemQWJrZSQGwp0D z_bBe|efhA8^P}ziJrS@t-oHX{K0Y!WsJX-FA+mJ}R-SL} z@I>0jgDmqH{Em4yW?ohDWte!__MH#6zIpu~)Ij5Sad3rf-fYJo1n!D7 z*nv7uO8a>{Riqltil=#K8C9k%|L~H&_AbR#Zl~pBXhM#bhXtsaa1Xe`(*4oJ&iC+> z`rYXHCLk2_WYN#Om|E*J;Kh9@KC#3+QDF-3N~?5=WgRVRZ;z~J!pjsbX+OU^=cIRj z-G63sf8fzCoW|f(=j5k~zTZT&5Tk&a*X(gSxsUj9;W^P>JWWsv{(f=o<>{;5>6d0>hDqZ8sI#9J$&TGz$Rf}<(G~CJi}op^cYTo zVP1fO+N-LfNB3CW#k9=iVSz;z|A?*U$)~xK{9eC2)e__b$?n*H{a&C1lZS)7Yn@_? z+UbG^@xw)>l15TyK+}v&xsHYTQv+A@E!$YtMXj6aPPlF7ABjrU*{deL2ON%g(kV(R zO`a)+8A`znj-vXe+b2O%d*?9P`X@vd8V4(dFDe1jWNa?L*Q%D0QuU?E?5wLQpTxbA zPTs*~Q0Lh^RwsY4r=mD`QMq{EP{_v-=G*s=MU#3XE*mmmb1;CM3VVod^!*8O!Vd;C zZpMc9wIM9mHBZAQlw}UZx^NAluNj_)SqZF2{5UvrD~O8*WGz{D zGA${9(%Z;+fPj9}JVhjkp!aAywGj6VjL8q!@RrELoq@dLrj1_T z@T8J@EIp)26IHgY`CPADg@oaWkP|CdvC8P5kkC6FKdw>hBHzD%5BUVtAZzqwKJo_0 zx3Nq53CSsOXGmfvSJ->&SeY;v*nRwdwv-+7Hpsp~Ligq5ySlocz~zn3&TAQ{H2Oar zX%+CvzJH^-O+R>GE$TG%Lljdunz7w|U??k-5r|ZIyRzs|`N)WRvk9+_vbkN>a7VMi z>d>+pWicxDfWb;TgA+9jJpiJ^*dcBcI*GD|8iZK57P@*)9sepLcJw31+r1U{FH=8; zm+DzWUI*v6sXPxo;4~F=KZIn;H+ZJNHSOsE>(Qa>ZKciHiUo$EiE7)g9WmUK3;aOX ziC*?DUf@Wb4kQ{5RLIAm-})uE1#7qFdvT2!PmK=qeiBdqTwDsAhqc0=6D7yBBk#d- z5rbd>iZV{3hVA$&`WyBHW__D0)qgd8w%#AtCwog&CjNG3b@vDp@uisOh?GQyj}41c7DaS0!H_T z8NR3-QJxuhfz{qt z9RWn?EyVstvgwg|9wU3-LRakfYco{!L78YDyx4%A;nfG1nofMG-EsLb(~Q3ReU<_} zXTn3CG;mLOqr$`2rY5edqi0KvVgB>5my)v|wG&TsB%aZWc@cu`XFzDYa7WCI<)IYkGO38lZT2oPW z&8?C;0?hMZjmw&t*EjTRU*1#l>lC`seUu^h*nMvnnd1a`Yy~mzsir>e@~xV!Cy98-45_x)cNA$ijvGihrEXUsCs^+KnqB|E0C zTS|Oyb@)UU=UnnVE%L%&{<=BZmD_8D4o}4J%CDDg_M%A=rb}o{*F7Cy#)S|xrU~eG zi){3+Wf=XUD0_W_33TNLFJXUt2weFpU;&0ciy7^%06??kaZk2dUtoT|7pF#{Pjg%@e@6?x;HbM)Y0RMU9ZI}K-|32u#@=0>9?13rndmYdQaZ3hSaoX6-6?<>?( zbwM4~{10=uC6y4#)((>)+d(bq!iLwIKOyF<7Y%&UrRXNJ+(}^`+Bc=2kn90bU&a}x z(#PFo+fyugV2F|DDQ+= zn$I31fv?QL=q^y;J6%<9#nbt?e?s^Xkyij5z&nFpOC#A zlwo$HEclJB+29dCC`8`>1+P4J2)ud!@=plWpYEs!rNV;ntlhJ~2r=iTC&=Wp!{^ZB z3NT+Z=>B`0;0)j+7Jmwo7D7## zJ0yO1F_pQSy*35PiOgM5KOv8D*n*rS9BYrY7km3TfYlrzB_Bk$u)c#H$>)RCT!4|! zmtr=#fu?t_g$4Tbw@vj!H=kyzg5i2(4B$Gi(exUo;>&nCrjE#tSOpf_Nlxa46fk;c z)?gF?Of~*LHa7m(=n?ZQWFAW&>_M>1V4|Jesbo1F9yz6Rz)7b968_Ri0 zM+}UNT0w8}_k!l+LaE2EnX)*)g6o?o(5b&|E9`H^5_QVyG5wGbUb$7>;e?o+j z5~-Zd=t0!Lkp5+h*kWg=$)diog4VUZYqKFDBxm(5?sGO~S$*xUy zH4oBA+^9C=r$A!Cz$E`-&(so9Ba3(&M9TP>#MNq$M;P)9JtEK2xx{|B3AX=7^u3>u zD*UEXHU;>a5ab~C=k0%Gl>9%vhMqxvQVfEL_#M{SOJFA%A?n8XYGmFhA@2W#lu3Kg zN!hq;-~#S(bziq>T+V!Lj4puNVf7VRuTlmUjI+r;~xY%kvfRih#hQQ z18UE@HQj=G)?Q4r3)MmB(RqH98_Tz`PE~qegK5SdwhKgDIUCQBsH2(%hem|r9|>zc z?KrqHcI44j>#X@lW4v)GXtGt}T4?+uO4&oD3mvZvTMjgw5LtG2ZL)>a5j8BH_n^is z{W;^*Z!jaoRVEiJeHC+re$I^EN_7U#w+GIRnwP>3%Y}JW)jXS6SN#~C^kMtkk&Nx? zHyiRv#OU7#|4DQIihRLjQ7&VI{!cBgFj#=2gxK`SAmL4vM8-EBtqB~O_J<*N(zp3rc(A*iuG!_oGFXw}S}Gko9I zHfRp1@J6!4gVr-`xk9l?qsj}tE0-7}wWqQlH8=A`CO$p!^ksjiir>H+VAWT}y?wfYbusTtuQvQHA@r#qWW;in4_Y&USQg_nG#TqT~WijVb)Chy!$}L6BH^ z_nJ|yr1ecf{Wz{P6}c;tGG}9-KnV7B6QqTUpRC;T%Y11e^PgYl;oNlye9rWMXLVSF zOE#f0qr^mOz2@6Wha@%+`0~BN?4a~1>b?~{YQ$>4plbZ9>u$Ino9!#Hs#6Dx9K$7V zUKdW*=4f-hGtEu*z3wklyCbQ|?zwp`3(QISeL0e|xXnpGQ z6+OOrm_Ui{u93hrUWydaGTiVgB$Z+NQc0OKEUx|X^x1TUq|Cty0qlvAO9PO%Rnerr z3xwq1G&w3Nu48`E-|^XWbaPYfgY3`PPvWlfmI2NyV6f^|>i(IuTsIvoWE(j}ulA|IvH@7X^*^ zxr0d^Z(9_*PIHX(UfevU=5cKnv9m$M4R(O(f}{QC_lFBvRZtCwfaS*)b_tG49Gfa-As6m7d29=K63+W^v}GNe-j% zA>r&*4+}ak0^M5OWn>hiaP0)2zPj*vduRYDc7xXfK}rf(uF>5cp&0ueyVt%f!&LcQ zxwu-%a=cOlmIN*Hqi&HqWfL`V5u@HU0)mgq0mW3wujw zk`*<$e%00puwlUOdFtL&)XMlMA<=_Z?|UwwDa`Xhv?6pJgb5^?2*4oRGEBQpA1LJJ z)`=KKxCqugs@ZwVr!_l0A>xFAhWM38m}2tvAqsIJoYLMn^x005PM~TvbCW(<@oHOJ zl4@#d^^R`13Rv3LW}p1d^DO|{%|tW_G)NXc=u`|k)8psT1TWb6MlpY9(?vIP6NS2< zq>8ivcrcWpE#CUfPB8D$Cnc9oOUpN1st+dT+H$AVtJGiRNgE{>j;c6277*Aif?0V0 zSy1!ElZo~|Q7zML7Y)7a>qDsQxmg>V7u`7NoEH+%h#lH(Ooc6Oab@TZ2Ez5C-m48* zxJKXb;F)siwslA|9F|)-z@a3(rat|>2pUaFW+ng)t@%Ogus8UG7iIfj}~7o*^*N*)%Nx*^Y=%9>(bi-%QrujO4w zNkbp_O$qPSILlR8@U`LCkZP%KR87)FYD4<`8axuEYmL-lg&uIw~CgcE<-XXgcAcA2;12oQ%f-A3q3yH+j+Ul|cnGG+0`$L0JLmnOSy( zbkyC&X?1LlM}r1alY(1(J~4~b3rx-0PtApE>hw)zJd$zc>uB5FRO-2}Ff6y^j=&Qx z0UZrB-W$}US1ZwtO>ru1X^HVNM@hPt?$^vMVuh@x41>xr>ZCfmeSC+^xC;6j3yfPo zrTJP!Db@d&tI`-GKF7^^U}Um*5d$|-)!5Z9bEj} zxVwDeyvY(XsJm2nt2;Iv29gsV*LgYT4bClzR1}`0g{;bRt;pRHiUC~j)mR_8G=-al zX+%7>mTxhA2tA;!67+J=PAo0(UEMW_s)V?2c2{6BJo*=cY%|_04ku*{5H{PxkwVl$ zS_u`EiY9kzHE$aKD1KwBS9txSkaf+*kM2cZF_)&(D03)hrF$pg9nxg^`VkrbD^#Mj zCx51z$`3iX1jQ2mqDHzFHi~Fd}C4WCW#MSku0?Rlrl2%W}P@z zz1)x!=)d=D2u&}RAbP#iH4Rv5$_k26kQ8qe%&lVJOj#Q4t{jlI$gH zO3u7Ea4Bx7Ni(8+Z-C-i@#kX)-W~H%(}LW|5gQ-(Mx+J`WmqdU7> z>Wf35ujm6$&D$s?$5YFud*q}B7)Flui@r1Rg9BvMqzUc_G{3GA)4W@G)Oy<3R_ePJ zy3AnDURnI}Nx2q?lyWrm87J{Dr$$M@xaC(&CB9vO>=h%pBdb4)w|lC_17;MyFpHMb zJr;A;Hd?HTLl(D_UqBXfl+H`W@1BL0=C=~}%?%|Nmt+^5cqX&x^!$K(yc}G9O20*E zkyEx@IH1Ifrb+)uLOj6mEEOYB%jZbIAv9YytJd3GRbSH?Rt9CxI?tD3Yt`GW3tzGo8+Pj?F4ql*xiw{lKI$kigg?mH zrCm1=s}sQ|Zg`@?{kfd2jiH2J@jCVaiB+V1ZNkQDH(^D@JzyXz-}#aTx7juA9t-uNf|p)N(U6gS6zK>gjR+`C=TkK zlyDW=u@7Z+`+(|{slp3Dgb4k@yxeetexDkzS4FWcYH+VlDG(*vp3T=aAI_F3J@x)Z zQLFEA)Ruhy%(E(Z%L~LFNpb; z^CGUvpg86S(VHKQS3+E?Ix5^O#l4*6EPwQxT?xgOxpr1b>t3y@hRVEECl)yTg!BzP zO74kC%+W7aCk`1rXY>hYdO3EbMZEe^o%i`=sPp&{A=(T2V=}#t2h{0Pd7IvtmZN;2 zNVW3I5uNKt5^X;6KIeCE(2xOHy6!7US6Imn@?(K3En~d&ke8$Lm19S~PWO(H`RtID zTD!OE?>-^K(cchH!M``%6R39G>k!k4j?1;9oAe^XbVMx^Lx%ex3m3?y&kfZ_%ijsd zVNTI|+5DVw+6pCerAX<4icC(UhT6oy@kn;yNVb^4w6Z712VTg#`BiKfRpRiy6yDt; z$MfLnS-~}5-@qrQtn3z*lXX4pKNE*04Ye@7q%qzj!d6n(VOFW~V#-(CnxbGzwd-$G z=X_>$uQU*}yw1%LzpaxbV(PdU2)b|MPYB&LkD*zvc4opmIH>&VWLC=qfM z<}s}NZt4W^UPP#Pkvf$wQk)*YIc`%CQN{kk5HBnDh|Z*?CZhmS@ampQrA*Ur)8x*n zfkpU>z~KpKbk_OG%G!Ixd9~b!Uxqv1?HS;XF#mD4WL!;6I15-Wgonr@FOVTUb*2*+ z`sdGA^qZ3>w;zx`TjnW?dosuQ8J_vxp+3-zETydOus3x|B{Wltp4Od&kxqO?iZaT~ ztskx&Ey}FT8BXQyFK&4ji*h#_vdoFhlYH$fS(C9gJZX#%{wN+&fg&KjJchLa6ZLyp zp&s`_J*7=YsL?GUFSCO7d~4{dqdTn0LEpT_2E|kCGOuPNrBXkUa3JxU;mcIDRl0!d zwP@iqY{0*ZxIA3^In_(J(Ne!N|3;U(ghV}z7D0(Cpc;^mfUFpQMC_(i;DNQ4?(;S2 zb#I4nI0=-~?-QkBnK>!i@Ah2C1N6^;HWkmfj66)84)_0bQd!8zL+<2}lH+@wQr7i4 zMjsQa91VoR7u&eAvBSQ7+as|CP_s{iWJz_+q`Xg`7KI(9lwaTjE_R0IA4)?wmQgbv zcakNo-ZvTy+0Pd&pDo^~PxF54R)(%C@MCu*x;7N-qYf+{<7_q^id-V8-9sw89H!ry zzd39kXLCNqeW2=@P)d-H_-SYR1M$favoQ4{bR1e3q(gz;)TB1U!gLS!$SMz?bg25O z+wCclviPIhQ$${+Yld__!Cd*$_D1b#zGXrycE5{e>LU6LJ>8@MSJiuqdNfmRB3W?9 zBZ9?ut}T)l!auqc#)?tHS;v8$_Xy_3eUKjBG|<198PRMV1XnH1{n9Y3&R6;2K|%A@ zecao4zQU)4&B%8hOyxd%tGmr!$&WS5?RiWxeA8u?@A#v!>MXNH7tjUHAXP|}2#Zti z?WxK_`4&5;EY+kha?h) z?~i{Gz)TdtFm__t>AC1+w2A44G;ng!xS=eKE1PO(X7Hx-cG1r47x2s(9sXICd$-I_ z$k$!$Z?IUxe+4-GkL39Qo zXukTa?GjTBz6b^JlZT*!V-q?8N*P6zqggvde?mZ23%*Uefb=`M_HhNz$ld~}=3dVm zE`|WLC`2x5T0;)rR<&o3B2#CN;sbuE^*In?y63r>HOkPlMOx7(vS&8+u;E>4ejjLu zE*)WRNxHv?5HnzCFmFZopYIU|ke$$W(k}?o-adu_h{xQ7F(??4!QZsUtA%-{F{n-P zDzlk4I@#bBu`IXJ%KD^u=_yiCc&uWq@Ew6Yx+2Pb3-x&hwY7b%^@D2wFbdF^0~4kT zEbnoG&{bv4wg=D4pI6IpeL{ud#nv86EuHU^=<#}z`&Pqh8vsIO!25SI0#H3Mu?h1o z*^&E>onc9T=ROozXiddE^hBDG4{yVzI$nx9C@FsB=(u;cUZAe5H+~2Ov&p+ym>t=Swh? zpP?C?@$8H@p?rVsBq8`6yH_z|m2q}E`Zl!9`M(Ra`DfeiuiuNbPn%G&JfSL5F=X@w zF8{jy$*0pId&#eTigYVBwlD(E->jnyt}(p8b{iz{4DnmEq5#Oa@ysHM;7_t(E#XiY z=YO#gyQCyv;#*c&&;At-=fCp4&I%227Qp6}#f2w9iruVo1*4uM?UU_J!P88l2&@;{ zF#duX;L5sIxIWNqwVf{zyOuKp&R4NW33ihNs4YJWokH{`u`hmxvBKMbLQE`m-1W}x zcP^1`sQd}Jf`9BIcwKKl+<9jcB=k?7tDgU}P?fkd$(=We21yv}Q5~tL?>1uKfO$r- zU&bhs+@Q$H#XEOuO&}t9FC}`tBVMac>7Vc%FKXTsSAE!ELVa>Sw|XPv`*QCcsirE{ zxeMH&RutJzsL@$qSGALau}QL?t3)5N!dS<`I{%GMgD_df$s#WAx#P-Yq4AikA6iGy zT|euw3*r4d_L~-&RhB?wiQm&k(e9w-kH4E@MYCmE?hK^ax90-um>R?CtEbF7VGVu% zp)C~~WX*O#pKaLj6N2%FQ5;}71HBTD@zYZ<=Arl&CB|Xq72!}Uh#BLP(9|?jx`Sy9 zeq}8mP5g+bccS`m58ySZWPawc2}U`de6dQ19SVZDjj=GYPv9^cWdW{TezA{7D$@&r z&&N7|#RM_qSP&83<4T3IQRPdF4G>^Ij2-f#pKD)t0d8+?^xb%RV#%Ky#7)o00 zQxK%Kh8;qa9_vbhM5zAEpAhs3kQt$jZWcsZf)5mHvDu)VZSJ&m_I@gB2u9+Dj^?n% z3h(2mM@^Xm&1{LkbgUKgA3Fl2v|;$r)AJ^O>L=^fpBwUTjf$2U_u5zoz1acI-sq1L zUK<-g6l~9-IY=9n4{xrX_;0=B?4OX-dbK|bjMU!*MlfB^KnQ&i_K)_dT|7;ij+Gd#?S(BZ5Scg2 z$5|0gO;LGC6R>YGdnkcF#AVxV;np9h;}xeWKxH8CC^u3 z{ZBtW$mJ>2@j$)#l+&)yEsm%e2=9P4>d8!v_vsx{MtgZIgyGK4w~k|HNsRI> z@6k80FPIU~Z-q0kW3~YC3vPyjcTWp*(xf)IKbZaTjsJU?dadaR6O|1M}v+5So4bp3YbdC7y19*@>UA1iA!e2N4jN zE(KGigyWc1K~MfPXE-& zC7niv$17?ZqslJ%>LDeKw%(_lW zj5J3JpeMzLE8_-`_663ns%9A~t&<V!pkk6%8zNrl>|y;bpI@U^ zyf1wf9uw$Jd&Mv9z#8-L zMX_GyZQmQdGP)25LZb=K(QCg66}Ui`=7fc-#x0L20FDC#_E3`2Dw!4`XEsV>TL(#^m&|VH5__+qQ}G=ei!b-@_C6@ z0o6P5(c>>+tM0^&;8`fsEuQX5q)W!L1lQSiH9(0J!~*;8p+W|luprMqG>+eRL4}c} z95E~NJizbs49hl0JvBq50mZWS7m3EE$`Z5QFP^Ppa33&yA%-N_f)ekE5Vr0w(&z`= zY+k}5>@5-9WZ?P+{Xwp~(c?WgLAFK++p^8dL%enOsyjne%={=W)aADtDVqpZ9II za8C>mt5ZV#SY?lz?v=Ml=wr)7B}ZhtT}{ z>O^(w`;+~t?oEn=#!eq-%QiLFl}&f+UsS&R;Gopq@1tFTX5;b zn9!)c59R4CDT)NpoJ!$tj{_X0v zIR3J!M~S929?~UmX6UB8zPsqxAMx7kRXaQ=)<6IJ_2^w!9jHNp^Ls$C2xff6ZTAFm z$a4;G8^nGWDp8R|8HC)r>ElrO&T9Gi187Ywlp~wt{@j=%_-rt{r9q>csMm)&>~iQ~ z^Hy8cZsm=yG-;I=F{cd}eKcb}b%H?PtA=AY?d+`-7W4(-ZFBBn{1*!et7dYV2rIUGu8UIM{Tp@vhSe3Xi-uE>06LR9aP`R0ELByzr}|>UIFygl&gPna5%|Lh{Rod!`2;FUkCLNvE9(;C z67rUsg>0mi?Rm~K@-kGH)gW9NQK0l+&eb_QCA;C<{dMGZ%4qe6pO6&a(44@{BQNo$ z?rSI+DwHpZw6Mc9Mf}|17+OrdHELmcVKPTZeK_g4R^KG9Jhfg6lW~W*l{7yc_!%!U zdRq=U$Plzx&)FAPeQ}nENiMYbjxUQ#ct<6Ipfo6)^iDpuJf+*;D}pT&c0wrN+n|BN zsZC>-<4>TWeaq2bbj8q(+PZRqyPF$?se0=%x(5OQwjD=lauxg>NnX*%H(03_JNu#T z;+)P3N{|kU6b(nsC!@e#ZM=a09)=!tpy1e}@cSfZL8s~x2jOrPtQ6g?!|n3xksf5C z+vV@I4|)v?^a)0)y{-(q<9A-!rrvPOnEL8qz+>20a7I$Knw;VI$Ul@ zBG3cbXqe0I9@}K?P^uaU-;^l=;{k$pUplE?*EMBKtJvy?kh-0dmH*>gncYUo`Zr!o zMo0+ks10VefMt{AQUi-tM&D;2q4MRbZH9uZM8aO1>%-UeOPiGyi+c=(6RN;Ay;%D8 zXxJG6ERHe}>Ef)>w+F{3Az)lvHAFM>>Dfe>3o)3LV~3%`?nP11g4%Y}~(Y zV%S1zG#$Xlf*oICih%S=CaOW7^`JqL-AOFtTqqzR?l2hXf*-J#C~2=N6z{q`g?@FX5r@T8mZbO-rw>+EQQa6CmX|5r?m z(II@M@$2$X^%Xmb!LON`@fYFW^92*)>Wi%cZ2cCH{kOwmZLSTxlc=XKEKrKK3 zVU7L?5y<)bcGa2E8}W0}fYM(C$8;pFasPxQbK6q5TZoZFzVaaLbClW^O|NJ_x|6%B zoL^y;*D=Fn%OTZ7PXB#;eKAQ-1cYzIGLJAo7^~wv+Hr}IiC^vJa{`SxwQ36r48q#E zxdZR^2<_EvCQnCu6c-ogT+NOYNa+)eQ~$F4yxtbeE8qm!W0krH8hMfjFvtJ63&0rX zEopx;3@a{#}Ys#R5eoueiLSo;$ItY;!Pwx4pu*hp)RVDY%QYnl^K5 zgk98cN=ui-kNdxPazNg|UzC<*>_K|e<$e_}`dOs<-HS}qlj=hXiJYj+3!A$ZnOdY# zSaWdTyLX2rQhnDm>rGdW6!Nx??HBxJYhmOiY8L)%QrNTowCS==!&Bl;de!{)^2fHw z$NKw@>}+HDA4MzB<1`@we*Xy?j9|1A=@dBK=8^7`MZkpOAtl;}l`m zUNLo+LE_^STtw9KQ2Bimx##e@4f(i!98;QP1KTs0eD3?m$Iqo%MWLJ(5dSOxq7lC~ zd=~&t{D?#UXhh`kZD4;wG{S#EYBT_~%68OK_`HZT`ZJE*=!#x!pB4d}g`d%^2UmVV zhD|%s^ppI|FQyC`)FJTq8i_MtL?Xw0ARdeD=h z{S#8{M=T3L#@DD4KIe0YBqMaPsIq&kjPHFa$S0f|@>O%!4LT|99*V0$C=GWg3VuTl z9F9xBUJ;sE98z+%d?~M9hWKFvOX~#rbh>oV+M9Q4K`ee_h82sSBs3gEf6L59&o=CW z-6n1*EdfzUlW@mxdS%6b`^3J)AQ`Zthxpm)03M_;3vc=dJ`m-!6&C@NWZq;cRZ6ffbC9XrN9mXW~gFl z`4ThNfMy3)0~jV_9y1`2M!|%v10a2TD~#c8@VDEag#c5TbpILpn;ei$mTRWdd(@Z- zf%1%<&FDD~rBz@yV5c}XwSRR5fX@E1(WN7)0S|Um@?Ys0{_yq2cMVRVcVBp!@m_fW z%9lC$#+P_U+`WzL-<-E^C~x|ldjon_N2h(N-K0N_@7y8C)?kdaKjhaQ{bw(}Y1ApI zNZyg5K%3@=)|(_BM7c}I^Z*gpUw3?q9BIEZc=$Ir!~ry3CwpoCjK`_)whQwZb;VGMsl zc!bz56rgl@HrHzYV)`%LmWlwnEm#l6E8UF4=#LnrBw*jy0OFnrl{W4|j{;OHIqK%TWyh>)#oeSM%ZxqgcxR_!o=5SO*x}SU-zc=Mht`D)e zr_joBW6|V#e|*_gZMTg@=LdxfD$_tFpzn>vtJlk8-cxneOOAyz!BfE2eTXUgW$SML z+t=^xQ=~D&4@E%p!CXwY1YYD08%jxk6`0gGCew>Fb3Rcdu8KX8Rkj_zoIotfeuw)$ zj1$#>z6#WOZvQsJC;}V%x}a&<#C*_K-^_SWN3L&Gm$P-xK2hE$A5=ekN}(spJusJBC;uI)dSAIC|ZFy3fDw!0_o& zWUcg}&->3u{XphDUCui*q`RSMl``booi-%uWYKZzHbUM>0q3N;*e=i}-BV~9=Ci&Q z9Md3Y6x8IM&CT#ONxt^+?$i48&>L~Pe90qjv@d>lx@WoCEP+zurT#TfpkYpX)-MSr zhxWvZ(51=F5kDc$SV5*vp9i2)T?aW3X}fDRtXwjx#}_0Nolf6(5)H&ls=qfuE; z(au;NbdwNOt@X>9;&Eq_vY3$hybm7^=(!8OQZzVfh!agnW2OS3cn{Tt7i@qc&ronN zF#AWlU;Bl+xAbe)_dm8j#L$tqD;=v$OEaiQ9NS@d{nDM|=8tN_?xVpe=tvwiAYm73 z#~-dD_MXNKvA(VNXWpF(AiBYQkUgK2J5z_c46lrwjkidF6?sR(8=u)7?x6a%n(}Zi z21z!yWm*R1%X>%&Cggu$^|=@gG0mn7zB3h`QLQ9kpHF>hZhJ6LHeIN4viI&Iqd~ok z`;edDK?Z}1a!%f`-N0Rhe;41j*AZ02gB}??S5Ujn#@O&gucI?44?KA%%3<*GJC!LS z#aw>l1%`ID4xB4EOB$?|ILH{sv={TOa>wcl^fJ$Qc34`^@hKT(Q72JT z9@g&dl}VZAX?)x1`aRHXrKuw^-EUsS%+SZsn$NXKWNj=VQ!>BDV-V&W=R&TQ>n1T+2k@QDq`p1q^5V3y5gUzg(buMQKnqPpB1IUpPdt774E2ZkFX5ZL` zHm3NVYPJtd-HqTkJInP^!{|JgOFUp`5z0Z1+|?j@ti`*$NmH0RKlp3O_(-0i^?|7ytepGPIPi zK%zL)FcfsVJcQ}fjmIgc!ydCwd_5Mv$bV?q(;-eEd41T3H$$vMHATA1`^nDDX%Z)s z_YqBzzMINxLVriWG~x&Cj`q|om5!oa=9D&2NcnA;+N`+?!+t)R%n#lfvHN$z>_NFm z0n}FduPg&fU5TGNW`AIBn`UZ^6T2xSsw|$NuNB&zKjiSs@97nxMM?LWoQ8VAdjs>x zC0@bK#hoftxoFs=fT>A)WZnm?uxSE4h}3^|c|lH1@%_1Zg}#e^<8yii t)dpj(<^7MZ&Cq~Vhu;Eo{$S7XNR*2Z+`Fzuo@9{{`&%qj>-T From 7d648b45a2a3c3bf347320065fa39f0acd7a1d44 Mon Sep 17 00:00:00 2001 From: lorol Date: Thu, 12 Mar 2020 07:46:16 -0400 Subject: [PATCH 038/551] Added notes and screenshots to README.md ESPAsyncWiFiManager (alanswx port) tested Tested choices of ESPAsyncDNSServer and standard DNSServer --- examples/SmartSwitch/AWIFIMAN.JPG | Bin 0 -> 30179 bytes examples/SmartSwitch/README.md | 6 +++--- examples/SmartSwitch/SCREENSHOT.PNG | Bin 51029 -> 51457 bytes examples/SmartSwitch/SmartSwitch.ino | 6 +++++- 4 files changed, 8 insertions(+), 4 deletions(-) create mode 100644 examples/SmartSwitch/AWIFIMAN.JPG diff --git a/examples/SmartSwitch/AWIFIMAN.JPG b/examples/SmartSwitch/AWIFIMAN.JPG new file mode 100644 index 0000000000000000000000000000000000000000..46f38f49869d5ab39ef65b205dbd77549718cfbd GIT binary patch literal 30179 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%0Dcy=X$HSW~V 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 Z{P*vFo^A4Po%~xT|Hi;445-d^{wE6!KrH|O literal 0 HcmV?d00001 diff --git a/examples/SmartSwitch/README.md b/examples/SmartSwitch/README.md index 371de48ba..fc0bdfa70 100644 --- a/examples/SmartSwitch/README.md +++ b/examples/SmartSwitch/README.md @@ -1,12 +1,12 @@ -![](SCREENSHOT.PNG) +![](SCREENSHOT.PNG) ![](AWIFIMAN.JPG) -* SmartSwitch application +## SmartSwitch * Based on ESP_AsyncFSBrowser * Temperature Control for heater with schedule for car block heater or battery charger * Wide browser compatibility, no extra server-side needed. * HTTP server and WebSocket, single port * Standalone, no JS dependencies for the browser from Internet (I hope) -* Based on ESP_AsyncFSBrowser +* Added ESPAsyncWiFiManager * Real Time (NTP) w/ Time Zones * Memorized settings to EEPROM * Multiple clients can be connected at same time, they see each other requests diff --git a/examples/SmartSwitch/SCREENSHOT.PNG b/examples/SmartSwitch/SCREENSHOT.PNG index 9f18ba0887315e5448fc5b8f916a800bdd2c5ad2..001cc568454f148bac0d25ceb524507ba645fd60 100644 GIT binary patch literal 51457 zcmeFZcT`i|7B3n^L3)=a1nEfch(JW7i4;+K6R9x*(nF1c^d=x6AOxg?fYi_g=^dm? zuhL6G2?0WQ@jKr+=id9r8~5Bl?ilZlvy;i*$)0QNHGgYnt=R@wzpj=5)Q{CP)c^zp z1b`R#7vO3ckgN&?+XDdF+JL(N0N^Iz8UZbU5PwC0e*wb4fa`x<0|31EGXQYo10moV z{!EW2$AnM-G5$=8C;u#hf49oI_Rm(=_Ol58d40VC&j*kYlMs^^lav=1;}DmTmynT{ zmIEk1Q_;p70@Dsmc0Yl~^WQL%FbYxug^J@eIhZsQBFxo67> zQlcPLfXYLi-ZRldx{pV{@PL97=JRpjk#@c!uDlTqz9MU3E zB4V8Q<|GPkw)XP+kJSEdjsK*``S&=zy}d=eB}H7^97M(M-Mc3$CLt;zA&ln`cK31i zu!agdyL0{3$3HrGWan<<27coKc5&wT)2a1K7f%mGPWpjZKSJO?V*amo{THtP2!a2I`M=ur{|&hQZBN-b+bZ&T^MRDE_5eb9 z|1?85Bt^skat}4Nuk-w|;sDg+Y|+zkfXeGzZ%IDwVjc!w%>q>Lwj;rx_umKM4Z=SM z(e>+uH;9RdiT}_|5;BsTH%V_26O&Sql9G|*4`LEZDhhJSKi7Xc`P2MQEBu@MCh^Tb z9RJyI^#ee2^O^~PBOw7N;2I49Aq~M*2LOn-Xm8-{-an@A-v_}p!s|DP@IxXc!!y)S zKdAlpFKA)G%_|ZwXwCccW?y1a`*7`@`n2O z2EPvp4GWKmOi28gl$`P@HSJ4IZeD&tVNr2qRdr1*qOQK7t-YhOtGlPSZ***YVsh%& z^vv?g>e}!1jm@oX)Zx+b3HlUscK$~$yxsi|vHm65{~{L+Uao8SIk-;zM=pYE-gqLU zxqjo0I1#P#Q(|jZI!=jqH|Zb7XIHe6a7pST8D6@Lklx~!TINCh5$!L@{`Uk6`ahEF zUxNKxt{DJ1Apw5!2x$Nyz~%9Tvwiiq1P$T!h9uWoxkwjhb?x1fgI+d8=vNnvMvcok zUwh($Nw+%BXZL*>sloLzv%k>AgP-` zf`6%%0`Au$@~I0Mu2)|q5pANNwbHvv+nqQ2m{WuL82r2SaH9SP=`QrX7q-1oxL@2P z^p5p6J@@p@mJ*)%?^GbkL9zM(;)pKohh!z#rp4rq5oV?8#`^LB!YjayQp`u`misuG z#Tyi|-ZH;M6!z+`0GZ9sAhyqeNhgS1S3D0rvSkm<1qRurw<`%F!UuVi-1(Cnlw$_3 zXAy8PGv6=>;{%(EpFde_#~ul{UqTqv=eEam7HYBRBP9nu6dCux&ZQZJ(V`!3DNJkY zaPFL+oj+G4DX%<6=@Z98M;GDNm9Ydn57-nLD3W%4LmK+&oYjg70be5d|4nJ#>=Pj+(0M02$Gz1fW*u4a zHXM63L5r#zdO_(E=pZ{HQSo^a*HKxp?s(4l-un-=MsnS*Cs}0lPgMc`yW{|cn})Tg zQJ}Nm7%SVj@N~SVj4U?B1+}oWIFyIYgzZgVn3|dG%)FmGgy!!Dm>D;O?3?78>j+mG$^EGtxJ+GFm|~xHNAI)SPGO} zDNW`gFkkSD`pnX3Mrjb25u18pbbh(G=Q4j_ z^$AwZ*gmL^roSw8cB-a$=(CP2ontAB^Sm?59WN2~D3PhR3j=4O%t8`60kep4q^C%8 z==}?o3oUcp&qKr&!1fAYGmQSScr@&_$mM-mGkahKZx)@vs^hhY{IYaL%TL^?5ZZQl zANnHvtYXX1G22_xo2KjQ?i|tUJ;J*+yHKC7p>HP@29kMl%V#`;d!qKov*`h%UWki0 zx{ljAn&Ek&p<2B{>Iyyq8D%LMO?$S(le!UC06Gy4j74t$@6(RwxC;HJ7{i@z`q+T+g0gO+1D!H+4x)3phi2(RL~;9~hEnVfl*1D%>MLn3E?UI2e+zf-KY1s1 zo9>jrx4Y#s{bbN`%Ce~eWf7fuXHwcp)Fg7*!`@8L`Ebd6ah zbhx3k_wicUSAaHEmn*QOsZw8&;85EEM zmI9oh?0a9vxx+Fld3Swj;C{;DVk!~t>1$YHbu&_6Z z9dMROoDt5Li0EI7us$MA?HcWy)qJ2q1Zs7ek+rD%=^4?a>{19Z?J8e!g=B5X{A?wk zL?3M>&qRCecYJwAE>Z8peXs9>EN!vxGz{G6X~y~pxe?Aibs+8I!8ZzfQ#EVR{mL2L zSREu0Lo`iTLTwPnTA7_TynE)&7g<9^4NlvY@mO2#ur_&Pd2eMw`8T> zfBKb}+ymHZX7ztwjfu$8^g;V&@UDy=2FUOCo#fD&nLoT>BT=)p{u!#q5&Ep_je_&= zO2$Tb6Ktgvq>ss1xdKqmnP7qfWV-sbe}3KPh^6K_yaGVcl5Cxy*Q$=Y9_&~q<_8Wg zux6YPqi!W;Val{(ULF}%2dHR9+7w)7$EV3*2QgOw!&JN3M#rTWhKubkVd~4r&73xV z=;6If`v9v;-IO(-5~f2OYCZ<;7rl`OaLtsz{L)k+%49YJUf`{&K}NR?otoEb3DDk; zHf!j-?bf4J#l7ujGefXVDLBP=-)F}XT!sZCnj*bpkF&oDX|GzCcq$82iwM1qoB@fl zcBfte*w2QH4pwj5p1(ZKA}?pMlunMF)nTzGf$QYrf*HCC`V=Ln78*ee#xgm%4TVA@ z@f_@RJLe9^Wl}QR0P(a5r01-1Nx1vrP_7MI_dRT=pde_d2Fq%VPG8SRIeilxygd&} zb|f4K6!O=eRJe~KwhA*t#nvD%v=N74Vf(8i)^#K0dTr683l^H>=}bDdD!^1C8v5wu zd5f+pREj>bC9HZfrTvuUWC#58mF%ghIZ7q3OM}_COvF<9LlqH!4xi%IEC zg{JVPXK%_h0}*j%BPq}8Dq?A`09&`pMmbenIh&cIb#glyduwE}q%pAYQjE`!h$6oF8occwdciqyxx{SHT^ALG<(|oyh|Ty4PM6W7*Xx(B z>5C~&yb%#UK|~1f%HlEX%Dd1snVp-RHQ8+F$_wx-x4?MK%n;rLiwNf=sJ|RoHdL&r z=)DJEmwfB?~Zoi*7IR)4Jh2k8QVVK=uENnIfISJr$1|Z>jKpcLjj3NibnG z9i*F!9P@;w&2G_Hnq6~8xZbdk$5sl8;>Cwd6_wTRS;#3kbCH<56dQB>=mnn6No0H1 zzRKUE#7nB@mtPh)d~^l4E)fl3y#g%T>t4beKgGURz`~|Z-v}8s!w-K_Dp?x-YnCU zM>)fNssH#2a6gmsS!=3@nbi)HJgMYC31oC{c8xUH<*`MRex%@fToE+~eWNP99)Re^ zb!Ymg517v3!FvZhU@rT2pVs!6pJATg%DfQ*^cYjfxhQT_#?`buV9L6=gwTQ}(L5|h z0*bCJ1%CAS^7dMNEZO{TVHn(w`0X9Jd_Q~ewE45INrpS3tgY>7@NHUfGu8mCqRG zq-$gOgvnHYfBEq?r(?Dc+cEVN<=0v(drrJZvf|S`dOjTDqBNE>h)!j^xC^b0Voo-G zAQ!9V)cA?~n;r>QB;Y(}U`TPx`{HC%a2*(vNm_w1S)pPy*@S@+7LaB87QaIKt@#ty zPb||mb)Tx(#t0O020-EqZW;hG93ZT1#-T&^{V6-~c=Cn8ly#;qwHC!ln$zPR6OBRF zfL^7S^Ov8A64#B~f&t$E?87Lom0TcY@;s}~gfyhFFu&f+jE3sdhqmmzkEymXGG%K_ zNA?U9z}9ksBM`@m=W?t zZYdZoY14Jj_CLp}a{95j!PUe+cP6p`ry}0mxyHL7klr zBd>GMg2*OCJ4nu=MGq(9$SJ=byr)tD(D28sk!o-|bIH91crB9SB!2m8f1h}5Q#F1Z z08w$A(i^RjOBO7#=6#~$CCR0>YzE1Z$cUEwpy~x!Goo7pMWq2d;($AozT}W1mF&*z zvc7{A>QxE$62MBK;y~}1Hv>cueX?ko;w`=eEaGYa^8fS|vm5FlP#({iJn^Cz;Ytoa zhKSxs1b)fSivCF)2cKDWiO3m&Et_LCaFfXci+KgpLQP!=qnmhBJ?^WGJ3;hDe5Ws8 zaFZ2Z)SU*fRH=<7#N_>b>6^EB)5X>Ac+3ni6Q@?)yFk@#5-2dB8PO|a4_4W4Gz{a& zg-iOHGz&x{u+~2LbLN)9rKeriPGX_nA-Un3cP$nBlu6s&K2Y5WKX?E%IN;DLGtT_% zH`SXdjnU2eg)u_Ey-;lW*}Wu}xzqlp+w-n^*6?NAjg9ozgn?TF-LBKIpEfm$nmLCS z#4)|AJSY{+LoFvhoyxk=?r=|^<5e4bbol7J$(iGG*%|WI{D<7nSOhq(XHk_PXytGQ z>$0F4hK$aktaDI^KX}E7Pb*Uk5@YuGTdbLtgp2@xxKtGP1+$4}2si7;cM0NVRyTpq zCj+lRJr-WI%*dAxMctH7NfhGU8c?D87;mU5+)mwhlN%{GdP6=E`ySHVVf8^u7r@v`*r@d_MIE(5f5*A&($c{17ovilj@uU!a z9^x!q#(B?#CRCX)Nbx2Iwet0Alv3UsJByKLvdhD7jXIkJF%Ax8#`C6|3wL0*c3d~d zBp>Dv`StrOg*vwWcIE8-ohk8vi({$`*C!LdIRlE3f_Nof$UZ<>?1jR~G=_vZX6eFH zymThOK*B6yHb54Y@w0eU!aRDwQ`NtS0KVe%N|(yf$b011!nQ7i?y>Oe2~)pl^1TNG zC3Wb2f_=e(WBAOE9ZTM(ktK{Dihf((<%0{SjF(Rho%7*z%cw7Ptea#^!K_lPk@VUk zSy1_&4a#Pw`yuFza{H|!Yg;Cl3%z4MbW%Pv%@mwXZS{yN{nV}68XcrIHTzx1NA20W z&lGfg__;|%_O~0tsXgH#zLsTU7F!59%t%@3lOfLUG~2y3Jb)NfaOlkR^OnwY1{%$)c<|vq$kUB|@cS zR6@>OvbKdo;&l%61d$-fcm7QW%PYWphpzTk%n@jrQ~qT@SZ`P0*zYqq_)tvNCsSv> zz{~5%f-f8=YrGjKIpT5OjP03O-K4OYo+NnX7NWA+=#i{MV^3DW0l_uJ{f7zkr|Wd+ zFBo6=4Yi`ng8a***UbY`4|mY`9n^mK+hw|vLk4{Q3_9dzlXj>Zwn$KYDciBYID$3E znVx@D3nDWp*Y_arbtP+O3G%B39};d>6CAs=iAK6&Um~5Fze93&SPbF*x6C99bNNqy z$_wUhR`jf?wbm`x)PeY!_=;7MPEJqCr7z<=$k-UsmPj&_nO2v}>?~u;IUkj4;M|(< zM!3E%_f+0b0{m|M7ioLX1Qd-=>8VQ*-1Y_wm9q4davt`_$7AdhEMyi|4p~!$m;J&S z5(G>Lpc55!gyV$Owv=`3A9wCsJH0MCjg0%WdceMcx+g9A7%-U9X8I(PL))bKyW)w) z$1j%Y9hUnexzS2 z+s#O9tWMLM4KOo2u^47IS*LmKvB6vOYEP=1epYkOBk>}2r-iPW-OOJNsZ^iSGcq$+ zx@Bal@tuY^dFI|Kf2Xg*XSRAk5_^(M8#~DumigtE$)O>^f=K@TvX=;r-;K6<*`H&L zFEzV-r-u2^2uwC|N*j3vh{ADVfbD6zZxz(tU0fu==bx)yS+X#a-(nVN@2Y5Uwlg~H zxoh^;7nr~N#^%}Ob~i)HWP9!gtSc ziE8L>J|f!~ldh96{IsfOT$sBHBVui0^ZIsl$u%nJql3Mu3m6z))!C6o6_y>=ktrDp zdFtmFIcm1~L7V#(Poo{)TQt|mrv5Nst8%IX*{n13P>F3CEqzz67A?+TkaK@_XtELE zWYCxtHt_9aXS{th>9@|@f>Cp3!+rFf(drTl%C`Gj_aT1wjfuD-Z+5t5?X<3DDThg}}Z`~t>b{mKFfSf(Qrlk1|r|I<#Ak3w|u}p4AFadLPp@MNh zdmuY}Q^L#HxW6avo_oQaXwohW>$rXgE%2P>#zzp|Ciq-I$XfxkX^Arp+v7vBYNG;+ z3e2`-eM9DVd53P<8`HAZTdVTa3)e8Z{%DKvsQME$;;A9q5mK6X2|CAPLqADH?Qap~PlmfVx#*VDf5zIa*$^ zbPo6UmRi6*ZK^otXXuyBd3cdT#HAf^u z1ReBH$f3>3bFvbN*g5c*cPZC3n7@r07K?QjG1N*otUe7CRLp3=4!=&(L8PHsBkn}( z3%3jDS6)Mfb}f~TI}pn4ywgThAjbSRLYZD1K_l@xqtb|tJ` zTecl1f{9pyQ99xPD2BoB)q@4wZi7WoNAt?B5*A@GHXd_*WqLt*4eViCh42B@*C(5h z+lE#~l!+N%_sh~=?Ra`l1QzX%)KW?0M6N&IPpgfQ+C_T>0I?Kp3tN2JBMm(T*@hHp zpF9d}YK-@7VP~5}MswcSZy?f79%Yh0|8hqj{>m$K5yp*?Xm@(Qxb4ln7Rbeg$|6>m zAF7WDwi(Ti(ypy-Oxt?#PDJEdM85G4pNAWcHsh;&%v*`iIPa2+&<6;11PbGRE{HW@ zruf?7p{BQ@iXk)hpVP{!3U|ESlnb_8dpfPdXaqHmG;3y=^ca+TduN-0Wcp2?tw$^n zU$h!wZYN{ziHy;Cp^-^CWxc{?0SU*ASY6v%Bs#+u*(4+LrUsGvn?B@u=eo?6%m=x- zxmx*5ZHnccTL>scOhG*Nq9YWW^lS9sNTE$UXcp%*@9jR>1ZoA2@|6KNId(L#c0 zd|Epuvz7L_YFi1IytV?Yj^KJ8uR>jB!v(%aP!T*+X>KGLk~F1N>e13z)?iZN;yJgJ zLj7Vix@`BvS5X@AJwI(8QUkZyj9Mhw^3AMrDl!NA26W}w%d~p)G)N&S>x{VEVs%v( zstJe@lf}&yE;r`94$U7T=mb2%>uBZJG}yHLPhl52{!cIkt3XC|WO*CjwydVQwk-jc zHIkpq6aG3gxOSHuXUhDP-?TEV0R&W`?5{h=9ctTTdIwyK>H! zezoU3-t(J{?5Fquu5;WKfP@O&g4RjDEQ-lL-7P`~iAVcLkgA7iC1m_Xu+?fDB*@lkRl2iOa>vzVlh^g(UpKn`D@&NG7kpSf@XIxpB*VzH}Ke zvdbCD9XdHVagCFMrkj@k2Y~Y0TQOq5%K{UF2@{jY2##1~dbP%s%o?_uFEiEYfd*c4 z^yD{AutU1zQ)zzJr@y=#{gY|JQ61Rgtn|vu+dm{10t0-)Pt5QxSjCX z+4OCR{Y(BTzEpPI3$4I$Ll|NHShb?)lRA`9T$9EVU%s&2@T0Og6``-t(Ccf})GO1L7Zh4sAapp9-$rVNS7-djAZD9t@c^bPf_mYgWp|eu1?<|U!>GQ@b8>Wrz zZ&0iVsZ>E&(v0iJiHuo&-6X}22F*?u$6Bl6^?{;nhF`_0t4%+?*#BCVwhr-HT*_$t ztd3>4yS=D?`BuTUVy{7Vr=a_FQK+QGR4vYOBvX@{ChiHk{L7vePp);ka5Z6g` zxUB3)tPEo`u$uN#W+tVuimWEGJj=7UaS~83?0)^3*_$q6(<7AUn*%CxVF7pkKDX~J zsj56zfP`)IRMFN8@QO`%rpVWO<{$4sO24elwH!L#I`>cr!;ylser>@k z9I-u+bZd2c>Ovw~|3pU{XPaH*nikz3x3W@_VMsroJT|CXt;zbh;&diY8T8~^x%_bU z_7UfA`f#_PD7~=4YJwNMU_EQOWWSn+|&6e5G%4<*?J-OqcudsB)7vTAbP92f#Ht zw&t*97mVUvT{^|mIqT9+Z=T{fnns;#Qk{->`1=RF1;+Ocr~xFc_RJi&MRX{|0xOcR zJ=5NzTnwGK;YGsZ^69DNkn#|z^udScU6U*8zj>N%!KnqAnsc<_QEx}7#d6+CCME>D z=9SM-;NBcJYFgTxSI^wORO0IBT5>RACLNzKd_U&v_`Bc1xwZlcjKT42o`Zq{*)6QL zaB|J4@24FZT%AgHC(0E>{a#5k=ZHMHg?nk2%soplCOTjsXP#XCeZPrh*=mMS8)+3; zqs_hzu1<+E8wuIg2D@5IX5F>qd|vYQ&C}M_y)>(sML;zyj%3+$LZo~TwoHejfJX=i zc8!#0C|2FlSX+qs)N4~GGPxDX09g@j%fp1N0Liw=R;XwlbJ`iN04^6wslFV+&sN#B zN0XFn)yqa={if`#)ATyJ((^xa*Owgxu=jE&rRZu?$qM(Pm^3HQWzrmHuS=Z__vXL* zo>ld<*aTm~FVt~AYmGp>*}#asGB&dVA6gSNYnM|EV&LPmRdifsx(Vja#S05Cs%Zv> z<&l5x(0`G)H`80z;7xW~vSSqmtW=DPYvyi=_5jgC;XeYo8>%fpdW}EVLyVrkBl*P} z>$s-oLEdT$kPnXj0APhtg6yqsVr4MG-b-43_dMAc4Yl5tC}oRhZW#GRpB>I=w)$}Q z_PfU7OQeVcfeP6VE4$PV6VaMovwpI-PL6($P4!!{oUwD!XfEY`d>)Xa-;CYX1pgi^ zFL*WxS}KxkgW?Ow0WdCRmW#ujW@ z68>2c2-SZ|!zjv%R&`l11?|lgbz0x4lqXzX`mr+GTmke4^m!7j1mlD>*7$$4mIp>4 z?~5Yxpr6ji4Oy5>Mbne@llEL9RLz<{H=Jkgo2XTF3^Q0Nls%1h^1w0j1xQ_(`qIUH z(qD}%pe!MuiJq+JDOGF&bBEuX0ls;L*?UzRCb(m%R^q;(vl9F9sj7I4P2ARl4f_2P zBZKjkk=?brx_E2EduJck{jTrRadvE)3IqvnZm>Q0rqgOAgBvQIgdz1{Gvd4!?+cG9nF6!}*egrO*IqWIud45sSfjL77~-O(T4*qFt$`wyRr0PAQYK$0 zykD8O#7ntzb!~n%Nx4f}(IdTOR~PBAY8Yc=r>}sR()E?N0?axUxOWXYP84oVX4Plh zb2r_xaO;zYEg4N!thbOfxqk7NzpRFV<7gpiNwHDOmx>Cq3=7%bciWv4E)$ePKYX_J zi7%h{v18nV)H@*Bfl+cIFr5J_qL{}DqDxMe{m-n37TdlVcOP{E5(GGB2IU)5=?B;O zh2GQ==vG6C(GQU>K{!fCCRttRQO7N%y9tmOw}a<(l9mvDS3SQ)(M+&Q_r{6k^Rv&naM|{II{N1QU{wpS zgIBHMvu7CfIl}!Gw*9A?}*Uvnu;cgo>CY3oDJ=FL7z7;ALA`$@d=7iyIKt2 zO4L2CD}dwHg5>1hK?+D>NaRz-!o}l@rKxWa7-@Ks+`;lg` zfzKie^M!#$IbkGofKH!{IM7Q9P=}@L)JZuNW~ys}(28-nW>%4OpK0%eL}pKtfLq5p z_2b>@cn0C2BaOQLV07P=6n*3G@I>! zel^E6jRD>LFp?kd{qIcXazMQ5S(cVPOQI|DF7h060;Fmc9h!I|{TLzZ6FsIE;o-Otx9bwx63m@|djr)ahNIP3IE3 zE)aM)02FT8aJ8SWlO)VQmY~(EkfI%*{H@EOC7tXFD4v)c<1K{g+Rw@@y?XW+p>jDf z40CtG+{nb3dag&FxH1p1)L4C;FJSk`aT>3$w?HqLo`VB3m4IBGBRMB#y!l%QL9B>O zLoI%U^Cy$tm8z%2XM^(DM{>KmExxg1&qL3(LPAwP%z~15K_RuF-D~Yf<#FQ|{iRXQ z_2i#EX!{ekPU|T@4F!+u5yPSBXj^1?q;yFXnw@)$ugP6#RUIXgm)j{7bDHb8=Mcj@ z>@8S#%3BC)=Y$&Jf?zZ)$R)@kHq|m))#;?T*F^JjL+G2F*ZxxTYCk?n74LtS3j4m9 z3%2}Ys^v@~4Q6XaN_7_DuXY7!e^(AWwDa{7H{3bb<5|4|lEYdPkrkM?9$l%}ZMDUvyu> z!*Hsn>@PvKx}-E$fII)<%#WL9ZOg&EgyFyad&r;d)~*2I1?2HN_$RkyT(01T+hLp+ zapJ&AzL1+&fDb7hE?7AhyvfdMWU)jQA`fim7h%*y)E||Trbm_ZPnVbNdj&BLWIFhm z^K%0R90|LWVsT zr(N1i*NYTq@P!>u^J+R`q&{r13ydE(+Q-LQVACPttK@^p_GHQ2i3ytJkMb+mCfahB zk@uMmvUT#4XafsA;W4~}(ZvN>{c{pDV74$4_*n$@-|z-{{WK%0IiGM@hxvq|16j`) z=X}Dj60+~F0Gm80d>)aK==&9*_alBjG0)(b)c;{-e47nZJVi^5aNeh3<8KywnpX!v z%kc^V@H3KsaFtyF4(;w-#{2VK0hIp*bh)l@XwJYD;AHH4BH#?Z0Mu)D`qNf@H)`4H zoaEnQyL0&gEBIH-ZqSL|KW6h;QeNIk@!|ju=@SUVkM$)6xQvcR?xy79l-Gv2|bW{END+v<=4Xt!}iHNvu=o_a3#Y1VFG_JhqE zY9Lz>Y0>|z1%)GKm#=E)h7aTx2+8N?@L2j>#w+|0UpIX23NZ2DkCG?im>JvP$F%>@ zTZ=z>dyIa~KIb>)KX6)bQatP4(xj9f+VTSr3cf;US#KIQ`akdz??x=^f!6+>oJRcQ zByBZ@rOMafq7xoN}MuOYAAF=Utre4i#QwnP(%HB@-ecih_UKM zjn}VBm1$I&+R8M!FA_Al@s37e2o3 zC|3j_4S_Rqut5uy`sIFCG_dv;?A*3#5Nj z_m!Ome*brv0_PkY(rc+ZQR@juqD5!!<020tVS+H6tU6XP3LSd|_)@n%W zmqIun+c?hKTGZ?3(lj!iZg8>J1H*;Q<*e>%53GyHuyuw?)SWQj_PZ2Jxv-MlF@<61 z6gM&6tt@7u`0(OV18gmT$^k!HuP<|joD&>zBG3<&?APPXOYHyFhIXVxP5Bmy7*$A$-4iXD(7#P*m@*RGBY+hh$#+ELy$QC6?f4 z@mRp=d&byy>ZK8sY~@xWN~JZ;C0qeiII}$?QsJCp=$*XJ9l63wkdzemlIl#lHYT$r zCJo<{4e)P||c@a~xpiqZ<*=z`0yP2v|k7&_v^e<=nB?&Q@BZITW8(t3&#NT24mZeb|7**#LySkM~cpg69SA z6eRnRzwSbt`qGLFU!jwWWhZzT^DYqOHfPUb{T~mAL#LN3&to(A@AI+UE^TyzIQJhY zzJ;|uP?7?k6`mhl9ueSUCLXZ%AAwRfxW_Wz7cm@L$A@R-cNo4StCknCQGP3y!OHHYT%mQ*aRk88EujY&PAVntv(h&6TZYux(vb*eP?_vzwBQ9G45bUv4S| zUb*Y8IW6MQc$PVWEJr6_<~7S;rn&_+;(aXMu58k^+rQ6_!ZotT?PWN zu?_YJBZAb65o!wpWHo-Rp?=|=E3Z5B=<@ZivmLjkP@>y%q<52x1e9f_(hadP`@>s8 z1?_WB-t?|kOk}9l{7%;dsr%sy+83)tu?%h}{%)BhnEssd5YMEKX84MYPwbOSwsJEf z)`_1~Y-u=nD3>%;&r0^`olv2x@t-5ls&J&b7o1xy)#|NI>Lyhc2B^4@J=?}HXD;P+ z3$?e6GqPSr1hsL?ABwi>WOT8#_t8O3nDz^q4B+!RNU2t5E5PgWSlYlLSe18_f`xNM4LaSCvw~70f7`+Mh0y)N z1XXTdLaXqG&}`SQuNWCqQs@>eEgv75o9q1kT^IkWs|e{M<=D@ z`hTx<94_~OhrzU7e9dCm7Xb;tj#l|(2t&$|wn z+MMj_d%3493|Z|pO*rlhAEcaR&f|-GTQzWU&_JXvutWIqYW&BB>e@^hG)MP&5Jf=9 z1tb2xg|Lz!G;+ADg+^G&A5?0k@y&QUxuY~>Ei5Ef_2mBy~`t9~4J zJ6cz$i~JzZ`)PSR;1kGdI$1L#q_Hlr>)FUQP!)JaS4I7B05ntw>7 zx(qcv?0+@cu0p466<>YHR)eM59nKzRU2J$6Z|t6e&9 zHu&N?EuEWNRu;f`;ez!ZQR2s_w8^uTM@g3hcT6dBzFL|?Of%Ca^-X5x`e_hj&n3k@ z!}{XGfeq1pv=T-ILv_UGFW>cE0TjlQ(Uq2So#f)Z(jEI;k^EEcJ!?yM3)d>R0mR%N z1UFE>`abpTmzXvRiV7?0PSzQPi8aY4b&KZ6Y_+G>Kkhft?A=Vzv}oi`(6|W0QEdEl zK7nEQ&AnwVlG#MtjizKDdDx0xe*jx_6X>o9M3s?FwJjo5t^gQ5d=)CYKh3zp)0J6C z@M;`;cz)WD>g9T(1CtFo#g>4`0S8m7oxUWy?mWrZ<>IT$+4q&_pA>4TOL8-2Ey}O( z|GWdh9~ghzCV0hCreoFZOh7*c$`JLA_C%>#v53l1H1-->r}2LR{(_W-T~j9ffT-wn#ODa5|0V;L^L(MBbCV~Vrsql zn&y_8ZPK^K=dpSTf!{BqTI|C?c5!bTtU|q&U5hnLPYvtC*-~WPYy#!&p5KUZBkpHe zBTPFl{$#Q?ci)UE%DkpRheCNjn>f(E!D2IU>iA6FxX{5|U5h68v~c-(IZxHciTYm~f%s_|LHu8Cr;wJ|VGza?xCjLSVHyn89@{^K) z71XRluO*elp|WYZmQ8Uv_u8&@QjmUm>Kr-N3VgBi&fZCRRx>~DrxFtiv`2<&@9^?A63&P2 zw4JgT#&MbUlqD2uygQCnPxNHy?R5LT#PCX4>+B#|Q} z*N+$sa)Tr_UKTa6z^g)9LXXk0BiUnJNg@$EF{_>2_+1PHW<>2}2piNcw^ys#+07o^ z`EmB1++%fXCK?vv4TBif)=uO2YD6TuHKnC8#>~7CshhAGhc1)m`&cj3t)_;I$%5Qo zpSxgo-^!ap{mH7vJ*)&n8b9uFXS!Q@84*s`b&9IsP{WVsFkocAC8m3I5Y%qTJhnD| z^8G1V`P#9b(s3*-Nc#FMn;+N*A@kI|OPrbZ92>mqgYA274Car`&6gM4z-X~BZ zu{HjYyMWlf7UB^I#p27lg57ac*hiE5qD_2Xp@~0S?#-jMd<+l!Bz!+41ak~4kX(!X zK~Atih@*%c(ZHt=5heIWS+`+Wua@U??&_pUNlTNw_ zmX!ZoanR3q+AE8JC$*r+WumSCsxF3j%ZMA_I1Uras)~1!5hbvt1Q71NRWYO|uhRin z^c!@v9B_agTEu*cqXBI?fUrbB?7K5-d>DnO6XWATw+Ff<-D^#}p-~;4CMl(DRrG183zE}Ekv{;De_=4bMg^>^pZ&E6=B^BY8R1*xq)SfeGQv3mCH z`tcyUCEnNl=C7Dyoj0r&sr~x&q6})TyvoSD0d)u-s3J|wKaG4PaHjOUtSO_blXPz@ z?$rl!eU7%#sp>$7=Inn~>nWR$r~(WoJfgI{b?T~`5TVvvF z;vm5_e4$wjQe8CE^8R>1(@*CbIMJXuUr$AnUDf;^{o5qqZccG*TXP*>+Rc^kPs$a# ze^;SDu~gZ<#k*6g^VHrzOHz zz_8<|o;sjyMj$>!^2`yARG}g_dqsm^p<<V^IbfEYF6tqI(qp|#O|RYlubBb2i=?>P|XsucZjb?A400~ zE3W`>(^NG{^GYK%gTl6IHu(stQ{CtO_gASfcQ%5h*_88tV(nI(*co}6qCRCeJx4#Q zVU0sa0e!oH$cNwgaFI%Q|K@KPH$~*G0Gu(oMsOiG37_|M{{ajicY0%13vdKZ2y2f# zEOgB&5uj}m%`1Qs7B8))`21owPE1Rn}{eouVK;`vloag>x zRrlTjauJ>SU5ky_7-Hcx{%y2|AJ^~k!|gF)QX+uvqV_eVcA)s~j~#uJ`N0B96<6}g z**UYGDpe_crnQjP>+;`z8`HE?DtG!!rvx*rn*Kj@eRoh(-`aH)5tXJ$lNJ>O1py09 zT0oQ{Vi2U4NG}l(5C{+w1ObsIT|tOSuc3DmdJ*YOdhacv1`^_Te)qli{qD>+-yfNC zCd`~O;q1N7de&Oc+KjK4gxyysYL2r`BzzvZgpYM|jkabF1t$*lOlzSkA?WzsK+19| z_Y(FCWEPMfDsHW8Jt7otXcEtLiH9Ktt%46tX~{@tjPPusj8%Dj!-AXhtPIWC?k2<=H6@n5NwQ|t=uK( z47$Kq2U?zkPxO4d@&IJFr5`_hMyBV1>%otDF`3rR@moFa%CjE1H7Kl0Zu9c^WTOY4 z`V@VLj+(g|+oM=TOv>%DgXcP7FMj(hMwZRJOrMBUSbw_KYyA3#O!~PbZ1#+b1x=Sk zaWl(;dq?9d&qd5$w;|ozpR1CS4_g@~?0Lk5>zC8m5)+rZd3^ue+~!}l>SIPbXGUoo z_=svg{^Tfi&@KBvtwnb-iqI#+zW^NEcpoO2hv;g`b1T$t@-UQdXqe408|y)|7l1rI z*!tgBFQ|6cRH6l0rX|>Xr2Ni{eIGk?2#!#AVUPsUd8j(>fMgNQ-59YwnI7Frz&qB3 zt^|N3k(~=#KT-_xZcl&ZzwQEi`I+9|GTb(r+il?gTD$-K(l{?2br4#oFq>jarJa$C z2p??AB7M~^0)N3aUf|uf&=81Tj2?O@$5VQLUE@IV6g1sbsolwa+dBGLN%Uvsc|0TD ze&_uWrZlRp0Nr?0^gAqLQu

t7I9|BXg~wvW`}Z0h^rc0EaQ`}?Y2_pzUvH8LLE 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 wOkDS^kcW>6 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 diff --git a/examples/SmartSwitch/SmartSwitch.ino b/examples/SmartSwitch/SmartSwitch.ino index 22d9998ee..e7927a183 100644 --- a/examples/SmartSwitch/SmartSwitch.ino +++ b/examples/SmartSwitch/SmartSwitch.ino @@ -60,7 +60,11 @@ AsyncWebServer server(80); //single port - easy for forwarding AsyncWebSocket ws("/ws"); #ifdef USE_WFM - DNSServer dns; + #ifdef USE_EADNS + AsyncDNSServer dns; + #else + DNSServer dns; + #endif #else const char* ssid = "MYSSD"; const char* password = "MYPASSWD"; From cda9ae65c8ed6bf97ef7d4a1705b047dc6702c8f Mon Sep 17 00:00:00 2001 From: lorol Date: Thu, 12 Mar 2020 10:32:06 -0400 Subject: [PATCH 039/551] Added an authentication define to SmartSwitch.ino to be able to activate on all static pages. Same credentials as the /edit --- examples/SmartSwitch/README.md | 8 ++++---- examples/SmartSwitch/SmartSwitch.ino | 10 +++++++--- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/examples/SmartSwitch/README.md b/examples/SmartSwitch/README.md index fc0bdfa70..1a9c83ef6 100644 --- a/examples/SmartSwitch/README.md +++ b/examples/SmartSwitch/README.md @@ -1,11 +1,11 @@ -![](SCREENSHOT.PNG) ![](AWIFIMAN.JPG) +![](AWIFIMAN.JPG) ![](SCREENSHOT.PNG) ## SmartSwitch -* Based on ESP_AsyncFSBrowser -* Temperature Control for heater with schedule for car block heater or battery charger +* Remote Temperature Control application with schedule (example car block heater or battery charger) +* Based on the ESP_AsyncFSBrowser example * Wide browser compatibility, no extra server-side needed. * HTTP server and WebSocket, single port -* Standalone, no JS dependencies for the browser from Internet (I hope) +* Standalone, no JS dependencies for the browser from Internet (I hope), ace editor included * Added ESPAsyncWiFiManager * Real Time (NTP) w/ Time Zones * Memorized settings to EEPROM diff --git a/examples/SmartSwitch/SmartSwitch.ino b/examples/SmartSwitch/SmartSwitch.ino index e7927a183..a1d2c959a 100644 --- a/examples/SmartSwitch/SmartSwitch.ino +++ b/examples/SmartSwitch/SmartSwitch.ino @@ -13,7 +13,8 @@ Multiple clients can be connected at same time, they see each other requests Use latest ESP core lib (from github) */ -#define USE_WFM // to use ESPAsyncWiFiManager +#define USE_WFM // to use ESPAsyncWiFiManager +#define USE_AUTH // .setAuthentication for all static #include #ifdef ESP32 @@ -449,8 +450,11 @@ void setup(){ request->send(200, "text/plain","Erasing WiFi data ..."); }); - server.serveStatic("/", SPIFFS, "/").setDefaultFile("index.htm"); //.setAuthentication(http_username,http_password); //append or remove auth part - +#ifdef USE_AUTH + server.serveStatic("/", SPIFFS, "/").setDefaultFile("index.htm").setAuthentication(http_username,http_password); +#else + server.serveStatic("/", SPIFFS, "/").setDefaultFile("index.htm"); +#endif server.onNotFound([](AsyncWebServerRequest *request){ // nothing known Serial.print(F("NOT_FOUND: ")); From add0f3077395f16d28406aafdfb1cc4096ecec0d Mon Sep 17 00:00:00 2001 From: lorol Date: Thu, 12 Mar 2020 10:48:38 -0400 Subject: [PATCH 040/551] remove file (not needed) --- examples/SmartSwitch/desktop.ini | 2 -- 1 file changed, 2 deletions(-) delete mode 100644 examples/SmartSwitch/desktop.ini diff --git a/examples/SmartSwitch/desktop.ini b/examples/SmartSwitch/desktop.ini deleted file mode 100644 index 00f30c4a3..000000000 --- a/examples/SmartSwitch/desktop.ini +++ /dev/null @@ -1,2 +0,0 @@ -[LocalizedFileNames] -Command Prompt.lnk=@%SystemRoot%\system32\shell32.dll,-22022 From b541718588b1baf93d94be36d10e0442a52b12c6 Mon Sep 17 00:00:00 2001 From: lorol Date: Thu, 12 Mar 2020 13:04:59 -0400 Subject: [PATCH 041/551] Bugfix --- examples/SmartSwitch/README.md | 7 ++++--- examples/SmartSwitch/SmartSwitch.ino | 16 +++++++++++----- .../SmartSwitch/data/{index2.htm => index.htm} | 10 ++++++---- examples/SmartSwitch/data/index.htm.gz | Bin 3834 -> 0 bytes examples/SmartSwitch/data_src/index.htm | 10 ++++++---- 5 files changed, 27 insertions(+), 16 deletions(-) rename examples/SmartSwitch/data/{index2.htm => index.htm} (98%) delete mode 100644 examples/SmartSwitch/data/index.htm.gz diff --git a/examples/SmartSwitch/README.md b/examples/SmartSwitch/README.md index 1a9c83ef6..ac614818d 100644 --- a/examples/SmartSwitch/README.md +++ b/examples/SmartSwitch/README.md @@ -2,12 +2,13 @@ ## SmartSwitch * Remote Temperature Control application with schedule (example car block heater or battery charger) -* Based on the ESP_AsyncFSBrowser example +* Based on ESP_AsyncFSBrowser example * Wide browser compatibility, no extra server-side needed. * HTTP server and WebSocket, single port * Standalone, no JS dependencies for the browser from Internet (I hope), ace editor included * Added ESPAsyncWiFiManager * Real Time (NTP) w/ Time Zones * Memorized settings to EEPROM -* Multiple clients can be connected at same time, they see each other requests -* Use latest ESP8266 core lib (from github) +* Multiple clients can be connected at same time, they see each other' requests +* Default credentials smart:switch +* Use latest ESP8266 core lib (from Github) diff --git a/examples/SmartSwitch/SmartSwitch.ino b/examples/SmartSwitch/SmartSwitch.ino index a1d2c959a..11d17e70e 100644 --- a/examples/SmartSwitch/SmartSwitch.ino +++ b/examples/SmartSwitch/SmartSwitch.ino @@ -14,6 +14,9 @@ Use latest ESP core lib (from github) */ #define USE_WFM // to use ESPAsyncWiFiManager +//#define DEL_WFM // delete Wifi credentials stored + //(use once then comment and flash again), also HTTP /erase-wifi can do the same live + #define USE_AUTH // .setAuthentication for all static #include @@ -44,7 +47,7 @@ Use latest ESP core lib (from github) #define EECH 104 // fixed eeprom address to keep selected active channel, only for reference here #define EEBEGIN EECH + 1 #define EEMARK 0x5A -#define MEMMAX 1 // 0,1,2... last max index (only 2 channels) +#define MEMMAX 2 // 0,1,2... last max index (only 3 channels) #define EEALL 512 #define HYST 0.5 // C +/- hysteresis @@ -140,8 +143,9 @@ void showTime() Serial.printf("RTC: %02d:%02d\n", tm->tm_hour, tm->tm_min); if (sched == 0) { // automatic - if ((tm->tm_wday > 0)&&(tm->tm_wday < 6)) tmpch = 0; //weekdays - else tmpch = 0; //weekend + if ((tm->tm_wday > 0)&&(tm->tm_wday < 6)) tmpch = 0; //Mon - Fri + else if (tm->tm_wday == 6) tmpch = 1; //Sat + else if (tm->tm_wday == 0) tmpch = 2; //Sun } else { // manual tmpch = sched - 1; //and stays } @@ -372,8 +376,10 @@ void setup(){ //Wifi #ifdef USE_WFM AsyncWiFiManager wifiManager(&server,&dns); - //wifiManager.resetSettings(); - wifiManager.autoConnect("SmartSW"); + #ifdef DEL_WFM + wifiManager.resetSettings(); + #endif + wifiManager.autoConnect(hostName); #else //WiFi.mode(WIFI_AP_STA); // Core SVN 5179 use STA as default interface in mDNS (#7042) //WiFi.softAP(hostName); // Core SVN 5179 use STA as default interface in mDNS (#7042) diff --git a/examples/SmartSwitch/data/index2.htm b/examples/SmartSwitch/data/index.htm similarity index 98% rename from examples/SmartSwitch/data/index2.htm rename to examples/SmartSwitch/data/index.htm index 44c86bfc0..7c28036b0 100644 --- a/examples/SmartSwitch/data/index2.htm +++ b/examples/SmartSwitch/data/index.htm @@ -251,12 +251,14 @@
-
"); + return 1; + } + + inputFile = fopen(argv[1], "r"); + + if (inputFile == NULL) + { + printf("%s %s\n", "Unable to open input header:", argv[1]); + return 1; + } + + outputFile = fopen(argv[2], "wb"); + + if (outputFile == NULL) + { + printf("%s %s\n", "Unable to open output file:", argv[2]); + return 1; + } + + // Skip the first 2 lines. + for (i = 0; i < 2; i++) + { + fgets(sBuffer, BUFFER_SIZE, inputFile); + } + + // Get the contents of each line of the array. + while (fgets(sBuffer, BUFFER_SIZE, inputFile)) + { + // Get rid of the new line character. + newline = strchr(sBuffer, '\n'); + if (newline) + { + *newline = 0; + } + + // Skip this line if its the closing "};". + endBracket = strchr(sBuffer, '}'); + if (endBracket) + { + continue; + } + + // Write out each character. + pch = strtok(sBuffer, ","); + while (pch != NULL) + { + // Use atoi() to convert from decimal to a char. + //fprintf(outputFile, "%c", atoi(pch)); // decimal + fprintf(outputFile, "%c", strtol(pch, NULL, 16)); // hex + //printf("%s\n", pch); + pch = strtok(NULL, ","); + } + } + + return 0; +} diff --git a/extras/rehg.exe b/extras/rehg.exe new file mode 100644 index 0000000000000000000000000000000000000000..06cfe4a03486b1d7662578683f05d88c3f6c7a1a GIT binary patch literal 2560 zcmeHJL1-Lh6n>j*WSVZ8s1XDaC%DllF(|!AsU={hC?q(s4Twgjlif*naWk{dPSOY# z8n!`)VKI2hp%pPUrF^xoBHc zwmvOqbknpPdBTwG8B@-i^3W@%kqJDBCQDO#<_zF-+=A6?;Uwp zq;S8NJmr!ga1Q<|fZmta$n0nDuE(&TJa`nY#v*}whrYm|l8nc!?Wm&L>!1DQ( z!9(C3aW&``w3O<<%_lJ)H8>Q8e1{_;HMogEl-JST^7iHW6I_WUu2)IC2Wj|=6(vxE z3BgN7Gusl6L=C>(i?#~I1m1uzLq)G`17*C9?|FadN9?Xrt0-Hl*VgDk{Z~glrKScI z!S22td(&%Cy#!j{^dOu4tJ%ckQ-e%c^LkZu$lsR5==6x>N?w~NIFfQD^t#{Gqj&DA z5!Y#Ookl~{!32oj>ranW3hCsiTc5Ah?Ah3(G-4#X3@-cd|O3mIC%ov)zpG9~%!YdK_5nhdOEyDE(zl-pv z2sb0FMYt7VAdt)czy5m@=q<_O(@tY0eabjS$8(0BHS81eacjmY&NwH?rkG*s69q$d zEZHg={ELpX9MX@`*@-*QLK%57Ux0c)^=7c`uRr8{|M?yw{@uLYdJ(x{*lE}}%z&A& zv#@#Chp>-eE3hwMS795lA7H=1>M&mSN@uz>o3WjNY@q1MWI*hi5f`WsZ72=f2{ literal 0 HcmV?d00001 diff --git a/extras/undo.bat b/extras/undo.bat new file mode 100644 index 000000000..3c36e3574 --- /dev/null +++ b/extras/undo.bat @@ -0,0 +1,4 @@ +copy ..\src\edit.htm.gz.h edit.htm.gz.h +rehg edit.htm.gz.h edit.htm.gz +"C:\Program Files\7-Zip\7z.exe" e -tgzip edit.htm.gz +pause diff --git a/src/SPIFFSEditor.cpp b/src/SPIFFSEditor.cpp index 35ac233de..84ce2d0b5 100644 --- a/src/SPIFFSEditor.cpp +++ b/src/SPIFFSEditor.cpp @@ -1,376 +1,7 @@ #include "SPIFFSEditor.h" #include -#define edit_htm_gz_len 4398 -const uint8_t edit_htm_gz[] PROGMEM = { -0x1F, 0x8B, 0x08, 0x08, 0xE8, 0xAE, 0x7B, 0x5E, 0x02, 0x00, 0x65, 0x64, -0x69, 0x74, 0x2E, 0x68, 0x74, 0x6D, 0x00, 0xB5, 0x1A, 0x8B, 0x5F, 0x9B, -0x46, 0xF8, 0x5F, 0xA1, 0x6C, 0x73, 0xB0, 0x10, 0x42, 0xAC, 0x75, 0x1D, -0x11, 0x5D, 0xB4, 0xAE, 0xF6, 0xE9, 0x23, 0xB1, 0x9D, 0x75, 0x6E, 0xBF, -0x0B, 0x5C, 0xC2, 0x55, 0xB8, 0x63, 0x70, 0x18, 0x6D, 0x96, 0xFF, 0x7D, -0xDF, 0xDD, 0x01, 0x81, 0x88, 0xEE, 0xF1, 0xDB, 0x6A, 0x95, 0x7B, 0x7E, -0xAF, 0xFB, 0x9E, 0x07, 0x3B, 0x4F, 0x5E, 0x1C, 0x1F, 0x8C, 0x2F, 0x4E, -0x0E, 0xB5, 0x90, 0xC7, 0xD1, 0xEE, 0x8E, 0xF8, 0xAB, 0x45, 0x88, 0xCE, -0x3C, 0x1D, 0x53, 0x1D, 0xFA, 0x18, 0x05, 0xBB, 0x3B, 0x31, 0xE6, 0x08, -0x16, 0xF0, 0xA4, 0x8B, 0x7F, 0xCF, 0xC9, 0x8D, 0xA7, 0x1F, 0x30, 0xCA, -0x31, 0xE5, 0x5D, 0x7E, 0x97, 0x60, 0x5D, 0xF3, 0x55, 0xCF, 0xD3, 0x39, -0xBE, 0xE5, 0x3D, 0x01, 0x62, 0xA0, 0xF9, 0x21, 0x4A, 0x33, 0xCC, 0xBD, -0x9C, 0x4F, 0xBB, 0xCF, 0x01, 0x10, 0x27, 0x3C, 0xC2, 0xBB, 0x87, 0xA3, -0x13, 0xED, 0x30, 0x20, 0x9C, 0xA5, 0x3B, 0x3D, 0x35, 0xB2, 0x93, 0xF1, -0xBB, 0x08, 0x6B, 0x02, 0x50, 0xB1, 0xDF, 0xCF, 0x32, 0x5D, 0x8B, 0x71, -0x40, 0x90, 0xA7, 0x67, 0x7E, 0x8A, 0x05, 0x1D, 0x11, 0x9A, 0xE0, 0x68, -0x31, 0x65, 0x80, 0x32, 0x23, 0x5F, 0xB0, 0xDB, 0xDF, 0x4C, 0x6E, 0x07, -0xB2, 0x3B, 0x45, 0x31, 0x89, 0xEE, 0xDC, 0x0C, 0xD1, 0xAC, 0x9B, 0xE1, -0x94, 0x4C, 0x97, 0xB6, 0x1F, 0x2F, 0xBE, 0x74, 0x09, 0x0D, 0xF0, 0xAD, -0xFB, 0xD4, 0x71, 0x06, 0x09, 0xCB, 0x08, 0x27, 0x8C, 0xBA, 0x68, 0x92, -0xB1, 0x28, 0xE7, 0x78, 0x10, 0xE1, 0x29, 0x77, 0x9F, 0x01, 0x84, 0x09, -0x4B, 0x03, 0x9C, 0xBA, 0xFD, 0xE4, 0x56, 0x83, 0x29, 0x12, 0x68, 0x5F, -0x6D, 0x6D, 0x6D, 0x0D, 0x26, 0xC8, 0xBF, 0x9E, 0xA5, 0x2C, 0xA7, 0x41, -0xD7, 0x67, 0x11, 0x4B, 0xDD, 0xAF, 0x7E, 0x7A, 0x26, 0x7E, 0x06, 0x01, -0xC9, 0x92, 0x08, 0xDD, 0xB9, 0x94, 0x51, 0x0C, 0x7B, 0x6F, 0xBB, 0x59, -0x88, 0x02, 0x36, 0x77, 0x1D, 0xCD, 0xD1, 0xFA, 0x0E, 0x00, 0x49, 0x67, -0x13, 0x64, 0x38, 0x96, 0xF8, 0xB1, 0xB7, 0xCC, 0xC1, 0xDF, 0xA2, 0x57, -0x0D, 0xCF, 0x31, 0x99, 0x85, 0xDC, 0xFD, 0xDE, 0x71, 0x04, 0xFD, 0x5A, -0x1E, 0x2D, 0x22, 0x92, 0xF1, 0xAE, 0x14, 0x8E, 0xC2, 0xC7, 0x59, 0xE2, -0x3A, 0x92, 0x74, 0x78, 0xC4, 0x28, 0x9D, 0x11, 0x0A, 0x8D, 0x04, 0x05, -0x01, 0xA1, 0x33, 0x57, 0x6D, 0x8B, 0xC8, 0xA2, 0xE2, 0x36, 0xC5, 0x11, -0xE2, 0xE4, 0x06, 0x0F, 0x62, 0x42, 0xBB, 0x73, 0x12, 0xF0, 0xD0, 0xDD, -0x76, 0x80, 0x0A, 0x3F, 0x4F, 0x33, 0xE0, 0x29, 0x61, 0x84, 0x72, 0x9C, -0xCA, 0x6D, 0x59, 0x82, 0xE8, 0x42, 0xB1, 0x2A, 0x04, 0x50, 0xF1, 0x49, -0x68, 0x44, 0x28, 0xEE, 0x4E, 0x22, 0xE6, 0x5F, 0x57, 0x98, 0xB6, 0x93, -0xDB, 0x02, 0x97, 0x1B, 0xB2, 0x1B, 0x9C, 0x2E, 0x56, 0xE2, 0x92, 0xBB, -0x1B, 0x93, 0x0D, 0xD0, 0x87, 0x87, 0x87, 0x4B, 0x9B, 0xDF, 0xE4, 0x30, -0x6B, 0xC9, 0x27, 0x70, 0x59, 0x40, 0xAD, 0xB3, 0xB4, 0xC6, 0xB8, 0xDA, -0x42, 0x68, 0x92, 0xF3, 0xC5, 0xFD, 0xA3, 0x64, 0x09, 0xF2, 0x09, 0xBF, -0x73, 0x1D, 0xB9, 0x4C, 0x6A, 0x88, 0xBB, 0xE5, 0x38, 0x9A, 0x10, 0xB8, -0xF6, 0x01, 0xA7, 0x01, 0xA2, 0xC8, 0x1A, 0xA6, 0x04, 0x45, 0xD6, 0x68, -0x25, 0xF2, 0x6E, 0xCC, 0xBE, 0x74, 0x73, 0x68, 0x43, 0x3F, 0xC2, 0x3E, -0x57, 0x12, 0x86, 0x43, 0x98, 0x5C, 0x13, 0x7E, 0x7F, 0xE2, 0xDE, 0x40, -0x4D, 0x56, 0x52, 0x42, 0xA1, 0x3A, 0xBD, 0x3E, 0xC8, 0x46, 0xD2, 0xA1, -0xD8, 0x56, 0x1C, 0x75, 0x27, 0x8C, 0x73, 0x16, 0x4B, 0x7D, 0xAB, 0xB8, -0xD5, 0xA4, 0xCA, 0x3C, 0xBF, 0x77, 0x1C, 0xED, 0xA2, 0xAF, 0x81, 0x1F, -0x80, 0x50, 0x39, 0xF1, 0x51, 0xD4, 0x45, 0x11, 0x99, 0x51, 0x37, 0x26, -0x41, 0x10, 0xE1, 0x9A, 0xCA, 0xBA, 0x79, 0x1A, 0x19, 0x01, 0xE2, 0xC8, -0x25, 0x31, 0x9A, 0xE1, 0x5E, 0x42, 0x67, 0x30, 0x9B, 0xE1, 0xED, 0x2D, -0x8B, 0x7C, 0xD8, 0x3F, 0x3E, 0x9B, 0x3B, 0x6F, 0x5E, 0xCE, 0xD8, 0x10, -0xFE, 0xBD, 0x1F, 0x9D, 0x87, 0x87, 0xE7, 0x33, 0x68, 0xED, 0x8B, 0xEE, -0xF0, 0xF4, 0x60, 0x78, 0x0A, 0x8F, 0x83, 0x7E, 0xE7, 0xF3, 0xF4, 0xF7, -0xA1, 0x18, 0x7E, 0x19, 0xEC, 0x8F, 0xCF, 0x0F, 0x87, 0xC3, 0x37, 0xBD, -0x57, 0xEF, 0xE7, 0x1F, 0xDF, 0x6C, 0x9F, 0x8A, 0xC1, 0xC8, 0x39, 0xFB, -0x10, 0x3A, 0xE7, 0x9B, 0x3F, 0xC4, 0xC1, 0x51, 0x10, 0xFA, 0xF1, 0xF9, -0xF0, 0xF4, 0xE3, 0xD9, 0xCD, 0x45, 0x7C, 0x3E, 0x1B, 0x7D, 0xEC, 0x87, -0x9F, 0x36, 0x3F, 0x8C, 0x3E, 0x7D, 0xFC, 0xE9, 0x1A, 0xFF, 0x7C, 0xF4, -0xFA, 0xD3, 0x78, 0x0E, 0x1B, 0x5E, 0xB0, 0xD1, 0xF9, 0xD9, 0xFE, 0x87, -0xFD, 0xD9, 0xA7, 0x7D, 0xFF, 0xF0, 0x76, 0x12, 0xBD, 0xDF, 0x7F, 0x39, -0x9C, 0x0C, 0x37, 0x7D, 0x8C, 0x67, 0xE3, 0xB3, 0xFD, 0xFC, 0xD5, 0x9B, -0xE3, 0x19, 0x21, 0xE1, 0xE8, 0xD3, 0xFB, 0xB1, 0x7F, 0xF0, 0xEC, 0xED, -0xF9, 0xD1, 0x90, 0x84, 0xEF, 0x5F, 0x9F, 0x39, 0xD7, 0x2F, 0xDF, 0x1C, -0xBC, 0xF0, 0x2F, 0x5E, 0x5F, 0x6C, 0xBF, 0x78, 0xDA, 0xFB, 0xFE, 0xFB, -0x77, 0xC1, 0x31, 0xA1, 0xE3, 0x9B, 0x2F, 0xC3, 0xD9, 0xC1, 0xFC, 0xF9, -0x5D, 0x36, 0x0E, 0x5F, 0xDD, 0xD0, 0xDE, 0x07, 0xF6, 0xF9, 0xD5, 0xDD, -0x3B, 0xF8, 0x3D, 0x39, 0xE9, 0x4C, 0x46, 0xFD, 0xEC, 0xFC, 0xF4, 0xD5, -0x87, 0xCD, 0xEC, 0x87, 0x67, 0xC9, 0xFE, 0x8B, 0x17, 0x37, 0xF1, 0xE4, -0xA4, 0x17, 0x07, 0xD7, 0x53, 0xFE, 0xFC, 0x29, 0x4F, 0x2E, 0x66, 0xF9, -0xA7, 0xDF, 0x9F, 0xBD, 0x0E, 0x7B, 0xC7, 0x18, 0x5D, 0x84, 0x9D, 0xBB, -0x2F, 0x77, 0xCF, 0xC3, 0xF1, 0xD1, 0xCD, 0xFB, 0x08, 0xDD, 0xBE, 0x7F, -0xEF, 0x7F, 0x89, 0x3B, 0x11, 0xFA, 0xE1, 0x78, 0x1C, 0xA1, 0xB4, 0x7F, -0x1E, 0x0C, 0x7B, 0x9D, 0x83, 0xCD, 0xE1, 0x16, 0x4F, 0xCF, 0x0E, 0xE8, -0x8B, 0xA7, 0x9F, 0x47, 0xCF, 0xF7, 0xF7, 0xFB, 0x6C, 0xF2, 0xFB, 0xE6, -0xCB, 0xEB, 0xED, 0x97, 0xE7, 0xDB, 0xA7, 0x93, 0xD3, 0xE1, 0x68, 0x6B, -0xFF, 0x1C, 0x5D, 0x8C, 0x4E, 0x87, 0xD3, 0xAD, 0x49, 0x18, 0xBE, 0x79, -0x33, 0xFE, 0x29, 0x18, 0x7E, 0x49, 0x87, 0xC7, 0xF3, 0xE1, 0xED, 0xE1, -0xF9, 0xF0, 0xA8, 0xF3, 0xE6, 0xF0, 0x9D, 0xD3, 0x1F, 0x5D, 0x3C, 0x9D, -0xBD, 0xDB, 0x9E, 0xEF, 0x67, 0x87, 0xC3, 0xD3, 0x7D, 0x67, 0xF6, 0xBA, -0x13, 0xA3, 0x4F, 0xEC, 0xE0, 0xE9, 0xEC, 0xD5, 0x36, 0x39, 0xB9, 0x40, -0xC3, 0x57, 0xFB, 0xAF, 0x33, 0x72, 0x16, 0x1F, 0x9D, 0x3B, 0xC3, 0xE1, -0xDB, 0x63, 0xFC, 0xD3, 0xC1, 0x53, 0xF4, 0x66, 0xD3, 0xFF, 0x08, 0xF2, -0x3F, 0xFF, 0x19, 0x7F, 0xDF, 0x19, 0xCE, 0x8F, 0x9D, 0xC8, 0xFF, 0x01, -0x8F, 0x8F, 0x2E, 0xC6, 0xF2, 0x74, 0x0E, 0xA3, 0x9F, 0xC6, 0xD7, 0xA3, -0xFC, 0x34, 0x3E, 0x38, 0x30, 0x35, 0xCA, 0xBA, 0x29, 0x4E, 0x30, 0xE2, -0x75, 0x5F, 0x55, 0x19, 0x07, 0xE8, 0xD6, 0x4A, 0x0B, 0x0B, 0x23, 0x15, -0x9E, 0xB5, 0x1B, 0x60, 0x9F, 0xA5, 0x48, 0xAE, 0x81, 0x0D, 0x38, 0x15, -0x2A, 0xB6, 0xFC, 0x51, 0xBA, 0x5A, 0x4D, 0x79, 0x5A, 0x0D, 0xD1, 0x40, -0x33, 0x4A, 0x43, 0x88, 0x09, 0x85, 0x3D, 0x37, 0xC4, 0xC7, 0xDD, 0x84, -0xDC, 0xE2, 0xA8, 0x2B, 0x37, 0xBB, 0x8E, 0xB9, 0x90, 0xC6, 0x56, 0x2E, -0x43, 0x94, 0xC4, 0x0A, 0x6A, 0x39, 0x10, 0x7C, 0x46, 0xBE, 0x08, 0x0F, -0x60, 0x32, 0x31, 0x3C, 0x0B, 0xDB, 0x61, 0x69, 0x77, 0x92, 0xCF, 0xA6, -0xE4, 0x16, 0xAC, 0x79, 0x4A, 0x28, 0xE1, 0x58, 0xEB, 0x67, 0xCB, 0x1F, -0x4B, 0x30, 0xD7, 0xF8, 0x6E, 0x9A, 0xA2, 0x18, 0x67, 0xDA, 0xDF, 0x04, -0xB3, 0x98, 0xA6, 0x2C, 0x5E, 0xAC, 0x3C, 0x20, 0x67, 0xB5, 0xCE, 0x72, -0xF9, 0x55, 0x9E, 0x44, 0x0C, 0x01, 0x9B, 0x2D, 0x6E, 0x43, 0x39, 0xD3, -0x54, 0x98, 0x55, 0xE5, 0x54, 0x4B, 0x33, 0xDB, 0x04, 0xB3, 0x6C, 0x98, -0xF5, 0xE6, 0xD6, 0xCA, 0x74, 0xBB, 0x72, 0xAD, 0x70, 0xF6, 0x75, 0xD1, -0xD7, 0xFC, 0x41, 0xCD, 0xD7, 0x7D, 0xC5, 0x41, 0xA4, 0xED, 0xC8, 0x15, -0x12, 0xE5, 0x19, 0x56, 0x04, 0x28, 0x2F, 0xDD, 0xDF, 0x76, 0x6A, 0xAE, -0x02, 0xD6, 0x2D, 0xBF, 0xC2, 0x32, 0x64, 0x5A, 0x5F, 0x25, 0x29, 0x9C, -0x06, 0x9E, 0x3F, 0x02, 0xB3, 0xE2, 0xA9, 0x09, 0x1B, 0x60, 0x56, 0xE1, -0x4E, 0xB2, 0x50, 0x8B, 0x79, 0x92, 0xD6, 0x0A, 0xF4, 0x7D, 0xAE, 0x60, -0xBA, 0xA2, 0xE6, 0x99, 0xA0, 0xE6, 0x51, 0xA9, 0x3E, 0xDD, 0xFE, 0xA6, -0xA0, 0x61, 0xCB, 0xF9, 0x66, 0x69, 0xAB, 0xB5, 0x55, 0x3C, 0xEE, 0x3B, -0xF0, 0xAF, 0x0C, 0xBB, 0xCF, 0x57, 0x24, 0x4C, 0x9E, 0x89, 0x9F, 0x92, -0x40, 0x80, 0x53, 0x9F, 0x7C, 0xBA, 0xF5, 0xC3, 0xF3, 0x60, 0x52, 0x4E, -0x2A, 0xC6, 0x1E, 0x9E, 0x4F, 0x51, 0x40, 0xF2, 0xCC, 0x7D, 0xE6, 0x7C, -0xA3, 0xE4, 0x09, 0xC7, 0x07, 0xBC, 0x97, 0x87, 0xAB, 0x3A, 0x2B, 0x8D, -0xCD, 0x12, 0x42, 0xB5, 0xCD, 0x4C, 0x13, 0xE7, 0x8D, 0xD2, 0x4A, 0x31, -0xEB, 0xA1, 0x1E, 0x4C, 0x64, 0xA5, 0x9A, 0x62, 0xFD, 0xC2, 0xF9, 0x66, -0xC1, 0x53, 0x44, 0xB3, 0x29, 0x4B, 0x63, 0x37, 0x65, 0x1C, 0x71, 0x6C, -0x38, 0xE6, 0xB2, 0xEF, 0xB4, 0x4D, 0x3C, 0xDD, 0x76, 0x02, 0x3C, 0x33, -0x97, 0xCB, 0x9D, 0x1E, 0x04, 0x35, 0x99, 0xF1, 0xF8, 0x29, 0x49, 0xF8, -0xEE, 0x34, 0xA7, 0xBE, 0xA0, 0x41, 0x9B, 0x61, 0x03, 0x9B, 0x8B, 0x14, -0xF3, 0x3C, 0xA5, 0x5A, 0xC0, 0xFC, 0x5C, 0x28, 0xBB, 0x3D, 0xC3, 0xFC, -0x50, 0xE9, 0xFD, 0xFE, 0xDD, 0xAB, 0x00, 0x56, 0x2C, 0xAB, 0x0D, 0x7E, -0xEB, 0x06, 0x30, 0x60, 0xC0, 0x57, 0xEC, 0x69, 0xAC, 0x87, 0x00, 0x03, -0x40, 0xDE, 0xE0, 0x3B, 0x03, 0x5B, 0xBC, 0xDA, 0x88, 0x6D, 0x31, 0x6E, -0x94, 0xAB, 0x60, 0x8E, 0x9A, 0x8B, 0x1B, 0x10, 0x02, 0xF2, 0xF0, 0x25, -0xBF, 0xB2, 0x88, 0x47, 0xE1, 0x31, 0x28, 0x56, 0x93, 0x5D, 0xB4, 0xD7, -0xED, 0xBB, 0x68, 0x97, 0xEC, 0xF5, 0xC1, 0xBC, 0x6A, 0xD0, 0x15, 0xDE, -0x9F, 0x48, 0x84, 0xCF, 0x0B, 0x83, 0x13, 0x68, 0x04, 0xB0, 0x6A, 0x09, -0x52, 0xC0, 0x37, 0x1D, 0xE7, 0x89, 0x87, 0xF7, 0x50, 0x84, 0x01, 0xAF, -0x7E, 0x78, 0x76, 0x76, 0x7C, 0x76, 0xA9, 0x77, 0x70, 0x47, 0xBF, 0x72, -0x35, 0xBD, 0x43, 0x4D, 0x97, 0xDB, 0x29, 0x9E, 0xA6, 0x38, 0x0B, 0x4F, -0x10, 0x0F, 0x8D, 0xD4, 0xBE, 0x41, 0x51, 0x5E, 0x67, 0x84, 0x18, 0x58, -0x91, 0xC8, 0x3D, 0x8A, 0xE7, 0xDA, 0x4F, 0x20, 0xE6, 0x17, 0x88, 0xA3, -0x01, 0xB7, 0x51, 0x92, 0x60, 0x1A, 0x18, 0x7A, 0x02, 0x1B, 0x75, 0x0B, -0x9B, 0x56, 0x0A, 0x99, 0x2A, 0xCE, 0x78, 0x66, 0xA3, 0x00, 0x86, 0x4F, -0xCE, 0xC7, 0xBA, 0xA5, 0xF7, 0x84, 0x1D, 0xE9, 0x40, 0x1B, 0x32, 0x97, -0x02, 0x0A, 0xF3, 0x7A, 0x06, 0x39, 0x09, 0x19, 0xC5, 0xE6, 0x77, 0xC6, -0xF1, 0x48, 0x33, 0x2E, 0xBF, 0xEF, 0xFE, 0x70, 0xF5, 0x47, 0xFF, 0xD2, -0xE9, 0xF6, 0xAF, 0xCC, 0xDF, 0xCC, 0x1E, 0xB1, 0x39, 0xC0, 0x30, 0x28, -0xBA, 0x21, 0x33, 0x04, 0x16, 0x68, 0x8B, 0x4C, 0x60, 0x38, 0x03, 0xF9, -0x9A, 0x96, 0xEF, 0xC1, 0x31, 0xE8, 0x93, 0x9C, 0x73, 0x46, 0x75, 0x73, -0xE0, 0xDB, 0x84, 0x52, 0x9C, 0x1E, 0x8D, 0xDF, 0xBD, 0xF5, 0xF4, 0x33, -0xC5, 0x85, 0xF6, 0x96, 0x64, 0x80, 0x4F, 0x9E, 0x6F, 0x41, 0xE1, 0x41, -0x48, 0xA2, 0xC0, 0xF0, 0xCD, 0x81, 0xC0, 0x1F, 0x48, 0x10, 0x32, 0xB5, -0x01, 0x08, 0x81, 0xAD, 0x92, 0xE0, 0x29, 0x48, 0x52, 0xB7, 0x02, 0x3B, -0xCE, 0x23, 0x4E, 0x92, 0x08, 0x7B, 0x4F, 0xFA, 0xD0, 0xA3, 0x28, 0x86, -0x39, 0x11, 0xD8, 0xC5, 0x1C, 0x09, 0x3C, 0x5D, 0xB9, 0x37, 0xE5, 0x14, -0x5B, 0xB1, 0x04, 0x0A, 0x4B, 0xDA, 0xC0, 0x92, 0xD6, 0xF7, 0x2A, 0x69, -0xA5, 0xF6, 0x2A, 0xFB, 0x86, 0x5E, 0x81, 0xAA, 0x9C, 0x0B, 0xF0, 0x14, -0x01, 0x25, 0x1F, 0xE0, 0x28, 0x60, 0xB4, 0xD7, 0x86, 0x28, 0x55, 0x88, -0xB2, 0xA6, 0x44, 0xB2, 0xBA, 0x44, 0x94, 0x6A, 0xB4, 0x6D, 0xCE, 0xD4, -0xE6, 0xA8, 0xB9, 0x39, 0xAA, 0x6F, 0x3E, 0x90, 0x1A, 0xD6, 0xB6, 0x39, -0x52, 0x9B, 0xF3, 0x06, 0x8B, 0xB9, 0x64, 0x51, 0xF9, 0xCC, 0xAE, 0x90, -0x26, 0x30, 0x04, 0xBB, 0xF3, 0x3A, 0x9B, 0xD0, 0x03, 0x13, 0x47, 0x93, -0x08, 0x07, 0xDE, 0x13, 0x07, 0x7A, 0x22, 0x4D, 0xF7, 0x36, 0x9D, 0x16, -0x1C, 0xB9, 0xC2, 0x91, 0x34, 0x70, 0x24, 0x12, 0x07, 0x49, 0x40, 0x88, -0x10, 0x89, 0x74, 0x2B, 0x91, 0x52, 0x6B, 0x8E, 0x28, 0x74, 0x7E, 0x88, -0xFD, 0x6B, 0x28, 0x16, 0xDA, 0xC8, 0x4F, 0x4C, 0x8B, 0xED, 0x25, 0xB6, -0x5C, 0x22, 0x09, 0x71, 0x6B, 0x9D, 0xBE, 0x44, 0x1B, 0x4B, 0xB4, 0xB2, -0xFE, 0x01, 0xB4, 0xF1, 0xA5, 0x0E, 0xBE, 0x45, 0xBF, 0xF2, 0x04, 0x7E, -0x2B, 0xAE, 0x0B, 0xE9, 0x38, 0x0A, 0x34, 0x02, 0x4A, 0xDC, 0x86, 0x27, -0x56, 0x2C, 0x84, 0x4D, 0x19, 0x87, 0xF5, 0xED, 0xDA, 0x08, 0xDD, 0xE0, -0xD6, 0xCD, 0xA1, 0x69, 0x45, 0x36, 0xA3, 0x7E, 0x44, 0xFC, 0x6B, 0x6F, -0xE5, 0x2D, 0xCC, 0x05, 0xA9, 0x2C, 0xD4, 0xA2, 0xD2, 0xD1, 0x9F, 0xA7, -0xD1, 0x6A, 0x08, 0x1A, 0xA5, 0xCA, 0x2C, 0xAD, 0xB0, 0x1D, 0xC0, 0xD4, -0xA8, 0xF8, 0x2D, 0xED, 0x1A, 0xF9, 0xD8, 0x16, 0x47, 0x67, 0x14, 0x07, -0xA8, 0x9B, 0xE0, 0x88, 0x84, 0x37, 0x54, 0x1A, 0x68, 0x80, 0xC4, 0x9A, -0xB6, 0xCF, 0x2A, 0xDB, 0x4F, 0xD1, 0xBC, 0x38, 0x69, 0x85, 0x5A, 0x31, -0xED, 0x7B, 0x0E, 0x04, 0x65, 0x9A, 0x71, 0x30, 0xB7, 0x2D, 0xE7, 0x87, -0xED, 0x01, 0x08, 0xD0, 0x50, 0x76, 0x01, 0x19, 0xC0, 0x0E, 0xB1, 0x41, -0x3F, 0x66, 0x3C, 0x1C, 0xA4, 0x1D, 0xAF, 0x20, 0x22, 0xF3, 0x88, 0x9D, -0xE5, 0x93, 0x8C, 0xA7, 0x10, 0xF2, 0x8C, 0xD4, 0x4A, 0x3B, 0x81, 0xD9, -0x44, 0xA3, 0x77, 0x7C, 0x2B, 0x03, 0x17, 0xD0, 0xE9, 0x2C, 0xD7, 0xFC, -0xCC, 0xF1, 0xA8, 0xE6, 0x68, 0x98, 0x70, 0x34, 0x38, 0xCA, 0xB0, 0x46, -0x6D, 0x7C, 0x8B, 0xFD, 0x03, 0x16, 0xC7, 0x48, 0x80, 0xC8, 0x40, 0xD6, -0x45, 0x47, 0x37, 0x97, 0x96, 0xDF, 0x2A, 0x9D, 0x07, 0x9C, 0xA1, 0x95, -0x3D, 0x24, 0x4B, 0x70, 0xAE, 0x5E, 0x60, 0x0B, 0x85, 0xCF, 0x0A, 0xA6, -0x1E, 0x77, 0x96, 0xA5, 0x37, 0x51, 0x5B, 0x2E, 0x9D, 0x2B, 0xAB, 0x3A, -0xBC, 0xC7, 0xB8, 0xE2, 0x16, 0x52, 0x92, 0xA5, 0x1E, 0x28, 0x4B, 0xC3, -0x95, 0x98, 0x03, 0xBA, 0x3A, 0x75, 0xB9, 0x86, 0x88, 0x35, 0x4D, 0x57, -0x05, 0xAB, 0x48, 0xB9, 0x4A, 0x5F, 0x2E, 0xAD, 0x40, 0xF0, 0x13, 0x22, -0x3A, 0xC3, 0x7F, 0x9F, 0xA1, 0x15, 0xCD, 0xD2, 0xEE, 0x2C, 0x0A, 0x9E, -0x7C, 0xCF, 0xFD, 0xC5, 0x36, 0x2E, 0x7F, 0xB5, 0xAF, 0x3A, 0xA6, 0xB9, -0xF7, 0x75, 0x4F, 0x4A, 0xDC, 0xE0, 0xE6, 0x65, 0xFF, 0xCA, 0x42, 0x30, -0x6D, 0x7F, 0x67, 0xFE, 0x62, 0xCB, 0xE9, 0xC6, 0xDC, 0xE0, 0x86, 0x91, -0x40, 0x13, 0x98, 0x84, 0xB9, 0xB2, 0xA9, 0x86, 0x36, 0x36, 0x0C, 0x50, -0xC3, 0x86, 0x02, 0x77, 0x78, 0x47, 0xB7, 0x21, 0x42, 0x2D, 0x97, 0xEB, -0x61, 0x6F, 0x9C, 0x62, 0xAC, 0xA2, 0x6A, 0x35, 0x21, 0xA9, 0x17, 0x5C, -0x07, 0x6C, 0x4E, 0x25, 0xDF, 0x32, 0x77, 0xD0, 0x4D, 0x3B, 0x4B, 0x7D, -0x4F, 0x49, 0x71, 0xAF, 0x9C, 0xF3, 0x20, 0xFE, 0xAD, 0x60, 0xA2, 0x55, -0x7C, 0x03, 0x00, 0xF7, 0x5C, 0x98, 0x39, 0xE0, 0x05, 0x4D, 0xD8, 0x5A, -0xCD, 0x03, 0x60, 0x99, 0x58, 0xD8, 0x45, 0xCE, 0xE2, 0xE9, 0x94, 0x51, -0xB0, 0x82, 0x70, 0x7D, 0x58, 0x16, 0x93, 0xBA, 0x55, 0x37, 0xFB, 0x6F, -0x77, 0x48, 0x3C, 0xD3, 0x6A, 0x74, 0x89, 0x3F, 0xDE, 0xB7, 0x22, 0x26, -0x6F, 0xFC, 0xE6, 0x4F, 0x80, 0x3A, 0x50, 0x19, 0x6C, 0x53, 0x36, 0x37, -0xCC, 0xCE, 0xB7, 0xBA, 0x26, 0x21, 0x7A, 0x7A, 0x8C, 0x6E, 0x8B, 0x2B, -0x05, 0x91, 0xF3, 0x0C, 0x34, 0xE8, 0x57, 0x35, 0xB0, 0x1A, 0x50, 0xC5, -0x3C, 0xCA, 0x39, 0x1B, 0x68, 0x65, 0x2E, 0xA5, 0x8A, 0x59, 0x5D, 0xEB, -0xED, 0x7E, 0xDB, 0x08, 0xE9, 0x16, 0x51, 0x4C, 0x33, 0xE9, 0x9E, 0x72, -0xE1, 0xE7, 0x70, 0xC3, 0x03, 0xB1, 0xC2, 0x92, 0x95, 0x2B, 0x24, 0x30, -0xCF, 0xD6, 0xC2, 0xA9, 0x95, 0x19, 0xC4, 0xDC, 0x33, 0x1A, 0x41, 0x78, -0x47, 0x94, 0x3F, 0xBB, 0x27, 0x2A, 0xAF, 0xDD, 0xE9, 0xC9, 0x9E, 0xDE, -0x66, 0x6B, 0x70, 0x78, 0x08, 0xB6, 0x5B, 0x55, 0x26, 0x35, 0x61, 0xC1, -0x5D, 0x2D, 0xFF, 0xCA, 0xF6, 0xEF, 0x0E, 0x22, 0x94, 0x65, 0xEF, 0x51, -0x0C, 0xF8, 0xFD, 0x58, 0x37, 0x0B, 0x6D, 0xDC, 0x75, 0x36, 0x36, 0x9A, -0x9B, 0x52, 0x1C, 0x43, 0xB9, 0xA5, 0xA8, 0x02, 0x5B, 0x35, 0xDD, 0x14, -0x00, 0x6F, 0x6C, 0xB4, 0x11, 0x26, 0xAE, 0xC1, 0x1E, 0xA3, 0x8A, 0x82, -0x07, 0x28, 0xBD, 0xEA, 0xFF, 0x44, 0x9D, 0x4A, 0x42, 0x1E, 0x92, 0x6A, -0x00, 0x38, 0xEF, 0x93, 0xFD, 0xA2, 0x50, 0xDC, 0x8A, 0xF4, 0xA0, 0x55, -0xA0, 0xF4, 0xFF, 0x21, 0x59, 0xA5, 0x0A, 0x0F, 0x51, 0x1C, 0x41, 0xA4, -0x6A, 0xA1, 0x18, 0x47, 0x98, 0xE3, 0x8A, 0xDE, 0xA8, 0x95, 0xDE, 0xFC, -0xFF, 0xA1, 0x77, 0xA5, 0xE7, 0x4C, 0x78, 0x89, 0x2A, 0xC3, 0x96, 0x1C, -0x04, 0xE4, 0x46, 0x17, 0xE1, 0xAC, 0x09, 0x01, 0xAA, 0x03, 0x16, 0x45, -0x63, 0x96, 0xEC, 0x3D, 0x30, 0xEE, 0x56, 0xE3, 0x45, 0xA3, 0x24, 0x73, -0xB5, 0xC4, 0xF2, 0x5B, 0x81, 0xBE, 0xC5, 0x53, 0xBE, 0xF7, 0xD0, 0xC4, -0xE3, 0x60, 0xD5, 0x1A, 0x2B, 0xF0, 0xB0, 0x0D, 0xC2, 0x83, 0xD1, 0x9F, -0x21, 0x04, 0xA6, 0x55, 0xEF, 0xA2, 0xC3, 0x06, 0x08, 0xDA, 0x85, 0x90, -0x3C, 0x21, 0x24, 0x0B, 0xB5, 0x3B, 0xA0, 0x6A, 0x5C, 0xD4, 0xA1, 0x5E, -0xD0, 0xD1, 0x93, 0xDB, 0xD5, 0x18, 0x67, 0x89, 0x97, 0xAA, 0x21, 0x62, -0x20, 0x8B, 0xAF, 0x1D, 0x4A, 0xE3, 0xB8, 0x51, 0x99, 0x76, 0x22, 0x9B, -0x4D, 0xA7, 0x19, 0xE6, 0x1F, 0x85, 0x4B, 0xB2, 0xA2, 0xAA, 0x7F, 0x24, -0x5D, 0xD2, 0x00, 0xBA, 0x34, 0x66, 0x79, 0x86, 0x59, 0xCE, 0x1B, 0x21, -0xC6, 0xA8, 0x98, 0xD9, 0x09, 0xFE, 0xF8, 0xA3, 0xEA, 0xEC, 0x06, 0x9D, -0x6C, 0xD5, 0xBD, 0xD8, 0x49, 0x6B, 0x9D, 0xDD, 0xB4, 0x13, 0x81, 0x41, -0xFF, 0xC7, 0x9A, 0x82, 0xEA, 0x9A, 0xE2, 0x8B, 0x62, 0x49, 0xFA, 0xC4, -0xA6, 0xCF, 0xF3, 0x45, 0xCA, 0x49, 0x6B, 0x36, 0x2B, 0x14, 0x5A, 0x37, -0xCB, 0x02, 0xAD, 0x6E, 0xAB, 0xD4, 0xF2, 0xD7, 0x4D, 0xB9, 0x3D, 0xC7, -0x48, 0x0D, 0x01, 0x15, 0xA4, 0xFE, 0x96, 0xCD, 0x71, 0x7A, 0x80, 0x32, -0x6C, 0x40, 0xF0, 0xAC, 0xFC, 0x8E, 0x9C, 0x35, 0xDD, 0xAC, 0x65, 0x15, -0x08, 0x01, 0xC9, 0xE1, 0x32, 0x7F, 0x61, 0x54, 0x24, 0xD6, 0xC0, 0x5F, -0xDE, 0xC0, 0x80, 0x6D, 0x71, 0xB3, 0x00, 0x5C, 0xBF, 0x50, 0x75, 0x04, -0x24, 0x70, 0x18, 0xCE, 0x9A, 0x25, 0x27, 0x29, 0x4B, 0xD0, 0x4C, 0x56, -0xE1, 0x30, 0x26, 0xCC, 0x43, 0x40, 0xB3, 0x9E, 0x38, 0x02, 0xE0, 0x4A, -0x1A, 0x41, 0x69, 0x37, 0xAB, 0x22, 0x96, 0x5A, 0x7A, 0x11, 0x0E, 0xA5, -0x2D, 0x3D, 0x14, 0x35, 0x90, 0x59, 0xA5, 0x7A, 0xC4, 0xA3, 0xC5, 0x39, -0x58, 0x0C, 0xB2, 0x3E, 0xB2, 0xCB, 0x06, 0xAC, 0xD3, 0x31, 0x55, 0xA9, -0xE5, 0x79, 0x50, 0xE8, 0xB2, 0x2B, 0x99, 0xAE, 0x03, 0x53, 0xCD, 0xC8, -0x62, 0x70, 0x4B, 0x4E, 0x0A, 0x84, 0xB2, 0x25, 0x0B, 0x05, 0xB3, 0x56, -0x93, 0xA6, 0x55, 0xCC, 0x96, 0x39, 0xC8, 0xFD, 0x14, 0x04, 0xCB, 0x34, -0x03, 0xD2, 0x99, 0xF5, 0x4C, 0x83, 0x9B, 0xD9, 0x9C, 0x70, 0x3F, 0x14, -0xFE, 0xC7, 0x07, 0xA1, 0xEA, 0x1C, 0x0A, 0x13, 0x57, 0xB6, 0x42, 0x1E, -0xAF, 0x5A, 0x51, 0xD1, 0xFC, 0x9C, 0x15, 0x0D, 0x3F, 0x2B, 0x5B, 0xB7, -0xB5, 0x49, 0x46, 0xCB, 0x69, 0x46, 0xA7, 0x45, 0x93, 0x50, 0x52, 0xC2, -0x29, 0x27, 0xCB, 0x67, 0x92, 0x14, 0xAD, 0x24, 0x2C, 0x5B, 0x21, 0xBE, -0xAD, 0xF6, 0xB1, 0x72, 0x36, 0xC0, 0xBA, 0xAB, 0x54, 0xEC, 0x89, 0xB3, -0x2C, 0x1A, 0xFD, 0xDA, 0xDD, 0xC2, 0x7F, 0xC7, 0x7E, 0x42, 0x67, 0x25, -0x33, 0x49, 0xD9, 0x9A, 0x91, 0x92, 0x95, 0x49, 0x9C, 0x3C, 0x4A, 0x48, -0x54, 0xBB, 0x13, 0xA9, 0xDD, 0x69, 0xF0, 0xBF, 0xBA, 0x76, 0xE0, 0xA6, -0x6B, 0x4C, 0xEB, 0xD6, 0x08, 0x3D, 0x5F, 0x3C, 0xDF, 0xB3, 0x40, 0x66, -0x98, 0xA6, 0x15, 0x1B, 0x53, 0x0B, 0xB2, 0x40, 0xB3, 0x6E, 0xA5, 0xF9, -0xBF, 0xBD, 0x8A, 0x78, 0x71, 0xF8, 0xF6, 0x70, 0x7C, 0x58, 0x4F, 0xA7, -0x23, 0xA3, 0xA1, 0x50, 0x89, 0xA2, 0x7A, 0x9D, 0x15, 0x6A, 0x21, 0xC9, -0x0A, 0x68, 0xEB, 0xC6, 0x86, 0xB2, 0x8A, 0xD7, 0xA3, 0xE3, 0xF7, 0x76, -0x82, 0x52, 0xB0, 0x47, 0xD4, 0x20, 0x2E, 0x56, 0x20, 0x9A, 0x88, 0x5F, -0x1E, 0xD6, 0x92, 0x78, 0xF9, 0x7A, 0xC9, 0xE5, 0x4B, 0x4B, 0x61, 0x53, -0xF7, 0x21, 0xA1, 0xCC, 0x3A, 0x8B, 0x9B, 0x40, 0x08, 0x4D, 0xD3, 0x55, -0x98, 0x1A, 0x94, 0xE4, 0xD4, 0x9D, 0x3C, 0xBF, 0xC9, 0xDB, 0x0A, 0xC6, -0xA9, 0x69, 0xF1, 0x90, 0x64, 0xF5, 0xF2, 0xA5, 0xE1, 0x12, 0xFE, 0xA6, -0xB4, 0x97, 0x65, 0x4B, 0x81, 0x5B, 0xCF, 0xBC, 0xD5, 0x6B, 0x44, 0xE5, -0x1D, 0x2C, 0x64, 0x91, 0x5A, 0x06, 0xCE, 0x56, 0x67, 0xA3, 0x43, 0xE4, -0x21, 0x54, 0xB7, 0xE8, 0x3F, 0xD5, 0x4E, 0x5A, 0x6A, 0x27, 0xAD, 0x1B, -0x67, 0x05, 0x70, 0x30, 0x01, 0x22, 0xAE, 0x07, 0x95, 0xD9, 0xB4, 0xCF, -0x28, 0x4B, 0x6C, 0xDF, 0xC4, 0x63, 0x31, 0x23, 0xED, 0xBB, 0x31, 0xF1, -0x39, 0x93, 0xE3, 0x9F, 0xD1, 0x0D, 0x52, 0x17, 0x85, 0xCD, 0x6D, 0x72, -0xD2, 0xFF, 0x0D, 0xCC, 0xB7, 0x89, 0xE9, 0x81, 0x71, 0xE8, 0xB7, 0xCC, -0x34, 0x9D, 0x48, 0x06, 0xCD, 0xFB, 0xBE, 0x80, 0x37, 0x5D, 0x4B, 0xE5, -0x6F, 0xEA, 0x9E, 0x05, 0x74, 0xBF, 0xB0, 0x44, 0x8D, 0xD7, 0xCE, 0xA7, -0x6E, 0x76, 0x1B, 0x1B, 0x0F, 0xDA, 0x5D, 0x8B, 0x93, 0x97, 0x0E, 0xBD, -0x69, 0x50, 0x68, 0xAD, 0x5C, 0x15, 0x93, 0xFB, 0x11, 0x9B, 0x18, 0xE2, -0x8E, 0x72, 0x21, 0x4E, 0xCB, 0xA5, 0x4B, 0xD3, 0xFA, 0x8B, 0xA2, 0x15, -0x59, 0x7E, 0xDD, 0x67, 0x2B, 0x0A, 0xEB, 0xDA, 0xDE, 0x5E, 0x44, 0x35, -0xCB, 0xAC, 0xF6, 0x74, 0x46, 0xDA, 0x24, 0xDE, 0x8B, 0xEC, 0xAC, 0xBC, -0xA3, 0x00, 0x97, 0x52, 0xEB, 0xE9, 0xBA, 0x48, 0x4B, 0xFD, 0x08, 0xA3, -0x74, 0x24, 0x0A, 0x60, 0x15, 0xF1, 0x1A, 0x1E, 0xF4, 0x71, 0x53, 0x15, -0x0F, 0x17, 0x2F, 0xAD, 0xD4, 0x5C, 0xEA, 0xE2, 0xBD, 0xCD, 0x94, 0x50, -0x1C, 0xE8, 0x2B, 0x3F, 0x2A, 0x0B, 0x56, 0xBD, 0x27, 0x6F, 0xD8, 0x6D, -0x79, 0x6E, 0xA6, 0xD5, 0xB6, 0x90, 0xC2, 0x42, 0xEA, 0x31, 0x20, 0xAF, -0x7D, 0x1E, 0xC1, 0x3C, 0x82, 0xE2, 0x8E, 0x51, 0x76, 0x8D, 0xC8, 0x03, -0x40, 0x08, 0x2C, 0x22, 0xC5, 0x9B, 0x7A, 0xA8, 0x88, 0x2D, 0xA5, 0x59, -0x32, 0x88, 0xD6, 0x66, 0x94, 0xBE, 0x9B, 0xE5, 0xD5, 0x5E, 0x75, 0xA9, -0x83, 0x4B, 0x47, 0x52, 0x58, 0xC4, 0x13, 0xB9, 0x2D, 0x12, 0x19, 0xD4, -0x08, 0x67, 0x99, 0x94, 0x8C, 0x90, 0xDC, 0x3B, 0x16, 0x80, 0xE0, 0x60, -0x5B, 0x2F, 0x86, 0x96, 0x40, 0x64, 0x5A, 0x52, 0xA4, 0xE3, 0x10, 0xC7, -0xC5, 0x0C, 0x87, 0xA6, 0x98, 0x42, 0x62, 0xEA, 0x6B, 0x79, 0x18, 0x23, -0x99, 0xA9, 0x12, 0x3A, 0xF3, 0xFA, 0x3D, 0xC7, 0xBA, 0x0F, 0xF6, 0x3C, -0xC3, 0x23, 0x36, 0xE5, 0x63, 0x34, 0xC9, 0x0C, 0x48, 0x34, 0x5A, 0x56, -0xC0, 0xD4, 0x08, 0x02, 0xBC, 0xB1, 0x69, 0xB6, 0x6F, 0xFF, 0xC8, 0xD2, -0x6B, 0x9C, 0x1A, 0x4F, 0xFA, 0x05, 0x3D, 0x47, 0x90, 0x61, 0x46, 0xF0, -0xCB, 0x87, 0xBE, 0x78, 0xD9, 0xFE, 0x16, 0x84, 0x55, 0x40, 0xCE, 0x60, -0x73, 0xC8, 0xE6, 0x27, 0x29, 0xA1, 0xFC, 0x9D, 0x2C, 0x87, 0x8B, 0x5D, -0xBE, 0xBA, 0xF8, 0x91, 0x47, 0x5D, 0xDE, 0x08, 0x2D, 0x44, 0x7E, 0xE1, -0x36, 0xEE, 0x85, 0xAC, 0x09, 0x1C, 0x28, 0xA4, 0x3B, 0xEE, 0x62, 0x4E, -0xA8, 0xAB, 0x1F, 0xF0, 0x34, 0xEA, 0x8E, 0x74, 0x2B, 0x46, 0x3E, 0x74, -0xD4, 0x1A, 0xE8, 0x2F, 0x2D, 0xE1, 0xC6, 0xDC, 0xBA, 0x7B, 0x0D, 0x0C, -0x6E, 0xE1, 0xDA, 0x85, 0x59, 0x47, 0xD7, 0xC1, 0x3B, 0x82, 0xFA, 0x60, -0x14, 0x1C, 0xD3, 0xE8, 0xCE, 0x85, 0xA8, 0xF9, 0x38, 0x1D, 0xE2, 0xDC, -0xD9, 0x63, 0x74, 0x7C, 0x5A, 0xA3, 0xE3, 0x53, 0x1B, 0x1D, 0xB8, 0x29, -0x3F, 0xE8, 0x9C, 0x03, 0xD8, 0x77, 0x88, 0xA2, 0x19, 0x4E, 0x61, 0x40, -0x20, 0x01, 0x91, 0xFC, 0x33, 0xCA, 0x52, 0xFC, 0x38, 0x65, 0xA3, 0x90, -0x4C, 0xF9, 0x3A, 0x7D, 0x6A, 0xF4, 0xDF, 0x51, 0x99, 0xE2, 0x07, 0xA8, -0x2C, 0x73, 0xE4, 0x46, 0x68, 0x53, 0xFE, 0xAB, 0xFD, 0xEE, 0x06, 0x55, -0x77, 0x37, 0x1C, 0x7E, 0x95, 0x21, 0x5A, 0x75, 0x53, 0xFA, 0x17, 0x36, -0x91, 0x19, 0x1C, 0x28, 0x8B, 0x6A, 0x65, 0x26, 0xDD, 0x87, 0xE2, 0xE2, -0x2D, 0x90, 0x66, 0x28, 0x6A, 0xB0, 0xB7, 0x58, 0x02, 0x42, 0x63, 0x4E, -0x80, 0xAD, 0x39, 0x10, 0xED, 0xCB, 0x94, 0xDB, 0x0E, 0x53, 0x2C, 0xE2, -0x30, 0xA0, 0x84, 0x18, 0xDF, 0xBB, 0xDC, 0xDB, 0xB8, 0xEA, 0x40, 0x70, -0xF4, 0xE0, 0x61, 0x7A, 0xD0, 0xD8, 0xB8, 0xFA, 0xCE, 0xEC, 0xCD, 0x88, -0x55, 0x31, 0x27, 0xA3, 0x2C, 0x88, 0xEB, 0x92, 0x5E, 0x79, 0x08, 0xF8, -0xAF, 0x07, 0xE1, 0xCA, 0x45, 0x82, 0xDE, 0x09, 0x86, 0xE1, 0x21, 0x3E, -0x21, 0x82, 0x87, 0xB4, 0x51, 0xD3, 0x04, 0x6E, 0x6B, 0xD7, 0x65, 0x3A, -0x87, 0xBF, 0x3A, 0x38, 0xE0, 0x41, 0xCB, 0xAB, 0x23, 0x3D, 0x2F, 0x5A, -0x3A, 0x20, 0xE4, 0xED, 0x3E, 0x48, 0x61, 0x01, 0x77, 0xA3, 0x1A, 0x75, -0xDF, 0x07, 0x5E, 0xAB, 0xAA, 0x5E, 0x8A, 0xE9, 0x76, 0xAF, 0xF9, 0xF3, -0xBB, 0xB7, 0x47, 0x9C, 0x27, 0x67, 0xCA, 0xEF, 0x02, 0xAC, 0xE6, 0xC0, -0xEA, 0x54, 0xCD, 0x05, 0x4F, 0xEF, 0xCA, 0x6C, 0x4C, 0x04, 0x1F, 0x65, -0xE9, 0x3F, 0x1F, 0x4F, 0x3E, 0x63, 0x1F, 0xE2, 0xDA, 0xBB, 0x0C, 0x82, -0xE2, 0xA6, 0x2D, 0xB6, 0x8F, 0xC7, 0x27, 0xF6, 0xB6, 0xED, 0x40, 0xEA, -0x02, 0x42, 0xF6, 0x43, 0xA1, 0x10, 0xCB, 0x7F, 0xB4, 0xF9, 0xE9, 0x3F, -0xDB, 0x4C, 0xC0, 0xDD, 0x65, 0xE0, 0xCF, 0xCA, 0xFD, 0xCD, 0xBD, 0x61, -0xCA, 0xE6, 0x72, 0xDB, 0x61, 0x9A, 0x8A, 0x33, 0x1A, 0x87, 0x24, 0xD3, -0x26, 0x30, 0x98, 0x61, 0xA8, 0x20, 0x19, 0xCE, 0x34, 0xCA, 0xB8, 0x96, -0xE5, 0x49, 0xC2, 0x52, 0xBE, 0x26, 0x0F, 0x5B, 0x2F, 0xAF, 0x87, 0x4E, -0x73, 0x9C, 0xE3, 0xA0, 0x18, 0xC6, 0x69, 0x5D, 0x2E, 0x32, 0xC9, 0x83, -0x71, 0xD0, 0xE9, 0xCB, 0xAB, 0x22, 0xE5, 0xCB, 0x29, 0x15, 0xEE, 0xF7, -0x49, 0x5F, 0xF5, 0x81, 0xBB, 0x10, 0xA0, 0x7A, 0x34, 0x8F, 0xA2, 0xE5, -0x60, 0x0D, 0x16, 0x54, 0x86, 0x8C, 0x33, 0xF9, 0x96, 0x64, 0xF1, 0x5B, -0x11, 0x00, 0x1B, 0xB6, 0x59, 0x69, 0x35, 0x6F, 0x4F, 0x89, 0xCD, 0xC5, -0x16, 0x44, 0x5E, 0x5B, 0x18, 0xE6, 0xDD, 0x88, 0x23, 0x2E, 0x54, 0x42, -0xD8, 0x9E, 0x52, 0xA0, 0x87, 0x42, 0x3A, 0xB7, 0x7D, 0x14, 0x45, 0xE2, -0x3D, 0xB7, 0x81, 0x61, 0x05, 0xE2, 0x79, 0x66, 0x09, 0x20, 0x59, 0xC2, -0x68, 0x86, 0xC7, 0x60, 0x8D, 0xA6, 0xE5, 0x88, 0x78, 0xA6, 0x78, 0x2B, -0x0A, 0x47, 0x11, 0x3B, 0x6B, 0xEC, 0x99, 0x56, 0xD5, 0xDB, 0xD8, 0xA0, -0x76, 0x49, 0xBE, 0x51, 0x6E, 0xCA, 0x84, 0xC7, 0x31, 0x4C, 0x91, 0x95, -0x43, 0x72, 0xD9, 0x94, 0x8D, 0x63, 0x3D, 0x31, 0x9E, 0x60, 0x8D, 0x50, -0x40, 0x4E, 0x7D, 0xA1, 0x8C, 0xEA, 0x44, 0x4D, 0x65, 0xB1, 0xD4, 0x13, -0xCB, 0x07, 0x15, 0x23, 0x0F, 0x66, 0x1E, 0x45, 0xF9, 0xAB, 0xEB, 0x22, -0x7F, 0xC5, 0xA2, 0x10, 0x40, 0x71, 0x56, 0x03, 0x5B, 0xE5, 0x50, 0x26, -0xF2, 0xCA, 0xE9, 0x81, 0x7C, 0x1D, 0xD1, 0x5C, 0xBF, 0x4E, 0x46, 0x55, -0x35, 0xC3, 0x9C, 0x56, 0xAE, 0x33, 0x51, 0x07, 0x30, 0x81, 0x58, 0xD0, -0x9E, 0x4C, 0x4F, 0x3C, 0x21, 0xF9, 0x18, 0xF3, 0x90, 0x05, 0x7B, 0xFA, -0x9E, 0xEE, 0xEA, 0xF0, 0x7F, 0x43, 0xB7, 0x60, 0x15, 0xA6, 0x3E, 0x0B, -0xF0, 0xF9, 0xD9, 0x2B, 0xF0, 0xBE, 0x20, 0x52, 0x4C, 0xB9, 0x41, 0x20, -0x08, 0x79, 0x7A, 0xA7, 0x65, 0xA6, 0x04, 0x7F, 0x49, 0xAE, 0xCC, 0x41, -0x53, 0x65, 0xF0, 0x7C, 0x4D, 0x29, 0x1B, 0x2A, 0x65, 0x33, 0x2A, 0xCF, -0x5D, 0x1C, 0x20, 0x2E, 0x5E, 0x1F, 0x70, 0xA3, 0xBE, 0x42, 0xA4, 0x84, -0xF7, 0x48, 0x35, 0x9A, 0x30, 0x12, 0x4C, 0x8D, 0x72, 0x0E, 0x94, 0x20, -0x4F, 0xA3, 0x0E, 0x12, 0x57, 0x10, 0x4D, 0x54, 0x99, 0x48, 0x3F, 0x4D, -0xD3, 0xFD, 0xCB, 0xCD, 0x72, 0x2B, 0xAA, 0x8B, 0x74, 0xC4, 0x53, 0xA9, -0x22, 0x6B, 0xF0, 0x78, 0xC1, 0xD2, 0x11, 0x96, 0x4E, 0xAF, 0xF9, 0x3D, -0xA5, 0xA5, 0xA3, 0x24, 0x89, 0x88, 0x72, 0xD4, 0x3D, 0xB8, 0x69, 0x9F, -0xCF, 0xBB, 0x70, 0x26, 0x71, 0x17, 0x30, 0x28, 0x11, 0x06, 0x7A, 0x0B, -0x85, 0xAA, 0x06, 0xB4, 0xC4, 0xDD, 0x8A, 0xBB, 0x6E, 0xA5, 0x95, 0xAA, -0x1A, 0x6B, 0x66, 0xDA, 0x84, 0xD3, 0xA4, 0xB3, 0x66, 0x58, 0x3B, 0x5B, -0x6B, 0x53, 0x68, 0xC2, 0x52, 0x6E, 0x40, 0xEC, 0x81, 0x10, 0x5D, 0x61, -0x2B, 0x8B, 0xB1, 0xBA, 0x6B, 0xB0, 0x93, 0x3C, 0x0B, 0x8D, 0x05, 0x90, -0xEE, 0x72, 0x4B, 0xC9, 0xCA, 0xC5, 0x96, 0x3A, 0x74, 0x97, 0x5A, 0xA5, -0x29, 0xBA, 0x22, 0xA6, 0xD4, 0x69, 0xFB, 0xE3, 0x0F, 0xD9, 0xAB, 0x0C, -0x4B, 0xF6, 0x9A, 0xB6, 0xB5, 0x54, 0xD7, 0xC1, 0x65, 0xEA, 0x2C, 0x34, -0x66, 0xDD, 0x5D, 0x0D, 0x76, 0x7A, 0xAA, 0x88, 0x2A, 0xBF, 0xBA, 0xD0, -0x48, 0xE0, 0x89, 0x18, 0xAA, 0x17, 0x2F, 0x3D, 0xA0, 0x39, 0x05, 0xDF, -0x64, 0x43, 0xD5, 0x55, 0xFF, 0x06, 0xB5, 0x56, 0x7D, 0x55, 0x5F, 0xB2, -0xEA, 0xC5, 0xA7, 0xAC, 0xEB, 0x20, 0x77, 0xC1, 0x9A, 0xDA, 0x22, 0x4C, -0x99, 0xF4, 0x2A, 0xAB, 0x56, 0x6B, 0xBD, 0x07, 0xBE, 0xD6, 0xD0, 0x0B, -0x64, 0xE6, 0x40, 0x35, 0xEC, 0x8A, 0x3A, 0x41, 0x99, 0x55, 0x0C, 0xA2, -0xEC, 0x8E, 0xFA, 0xC2, 0xB7, 0x56, 0x50, 0x42, 0x38, 0xA1, 0x46, 0xED, -0xAD, 0x56, 0x9A, 0xCB, 0x15, 0x91, 0x3D, 0xF5, 0x09, 0xAF, 0xB8, 0x73, -0xD4, 0x58, 0xF1, 0xCE, 0xA9, 0x9E, 0x25, 0x00, 0x43, 0x50, 0xE1, 0x0B, -0xB9, 0x94, 0xEE, 0x46, 0x93, 0x25, 0x7E, 0xD5, 0x05, 0x10, 0xB0, 0x60, -0xB5, 0x2A, 0x4F, 0xDA, 0x27, 0x54, 0x58, 0x5F, 0x1F, 0x54, 0x99, 0xC1, -0xFA, 0x70, 0x59, 0x76, 0x55, 0x6F, 0x94, 0xEA, 0xDF, 0xDB, 0x54, 0x8B, -0x89, 0x7C, 0x71, 0x26, 0xD7, 0x37, 0xDF, 0xA5, 0x3D, 0xB8, 0x4D, 0xED, -0x80, 0x86, 0x60, 0x17, 0x1E, 0xF2, 0xA3, 0xE6, 0x3F, 0x01, 0x05, 0x45, -0x3B, 0x0D, 0xE4, 0x2C, 0x00, 0x00 -}; +#include "edit.htm.gz.h" #define SPIFFS_MAXLENGTH_FILEPATH 32 const char *excludeListFile = "/.exclude.files"; diff --git a/src/edit.htm.gz.h b/src/edit.htm.gz.h new file mode 100644 index 000000000..398e37f23 --- /dev/null +++ b/src/edit.htm.gz.h @@ -0,0 +1,219 @@ +#define edit_htm_gz_len 4314 +const uint8_t edit_htm_gz[] PROGMEM = { +0x1F,0x8B,0x08,0x08,0x4B,0x0B,0x84,0x5E,0x02,0x00,0x65,0x64,0x69,0x74,0x2E,0x68,0x74,0x6D,0x00,0xB5, +0x1A,0x0B,0x5B,0xDB,0x36,0xF0,0xAF,0x18,0x6F,0x63,0xF6,0xE2,0x38,0x0E,0x50,0xD6,0x39,0x18,0x16,0x1E, +0x2B,0x7D,0x01,0x25,0x49,0x3B,0xCA,0xD8,0x3E,0xC5,0x56,0x12,0x15,0x5B,0xF6,0x2C,0x99,0x40,0xB3,0xFC, +0xF7,0x9D,0x24,0x3F,0x43,0xE8,0x1E,0xDF,0xD6,0x07,0x91,0x74,0xBA,0xD3,0xDD,0xE9,0x9E,0x0A,0x7B,0x1B, +0xC7,0xE7,0x47,0xC3,0xAB,0x8B,0x13,0x6D,0xC6,0xA3,0x70,0x7F,0x4F,0xFC,0xD4,0x42,0x44,0xA7,0x9E,0x8E, +0xA9,0xBE,0xBF,0x17,0x61,0x8E,0x00,0xC4,0x93,0x36,0xFE,0x3D,0x23,0x77,0x9E,0x7E,0x14,0x53,0x8E,0x29, +0x6F,0xF3,0x87,0x04,0xEB,0xBE,0x9A,0x78,0x3A,0xC7,0xF7,0xBC,0x23,0x70,0x7B,0x9A,0x3F,0x43,0x29,0xC3, +0xDC,0xCB,0xF8,0xA4,0xFD,0x1C,0x28,0x70,0xC2,0x43,0xBC,0x7F,0x32,0xB8,0xD0,0x4E,0x02,0xC2,0xE3,0x74, +0xAF,0xA3,0x56,0xF6,0x18,0x7F,0x08,0xB1,0x26,0xE8,0xE4,0xF8,0x3E,0x63,0x7A,0x84,0x03,0x82,0x3C,0x9D, +0xF9,0x29,0x16,0xE7,0x87,0x68,0x8C,0xC3,0xC5,0x24,0x86,0x03,0x19,0xF9,0x8C,0xDD,0xEE,0x56,0x72,0xDF, +0x93,0xD3,0x09,0x8A,0x48,0xF8,0xE0,0x32,0x44,0x59,0x9B,0xE1,0x94,0x4C,0x96,0xB6,0x1F,0x2D,0x3E,0xB7, +0x09,0x0D,0xF0,0xBD,0xBB,0xED,0x38,0xBD,0x24,0x66,0x84,0x93,0x98,0xBA,0x68,0xCC,0xE2,0x30,0xE3,0xB8, +0x17,0xE2,0x09,0x77,0x9F,0x01,0x85,0x71,0x9C,0x06,0x38,0x75,0xBB,0xC9,0xBD,0x06,0x20,0x12,0x68,0x5F, +0xED,0xEC,0xEC,0xF4,0xC6,0xC8,0xBF,0x9D,0xA6,0x71,0x46,0x83,0xB6,0x1F,0x87,0x71,0xEA,0x7E,0x35,0x79, +0x26,0xFE,0xF6,0x02,0xC2,0x92,0x10,0x3D,0xB8,0x34,0xA6,0x18,0x70,0xEF,0xDB,0x6C,0x86,0x82,0x78,0xEE, +0x3A,0x9A,0xA3,0x75,0x1D,0x20,0x92,0x4E,0xC7,0xC8,0x70,0x2C,0xF1,0xD7,0xDE,0x31,0x7B,0x7F,0x8B,0x5F, +0xB5,0x3C,0xC7,0x64,0x3A,0xE3,0xEE,0xF7,0x8E,0x23,0xF8,0xD7,0xB2,0x70,0x11,0x12,0xC6,0xDB,0x52,0x37, +0xEA,0x3C,0x1E,0x27,0xAE,0x23,0x59,0x87,0x8F,0x08,0xA5,0x53,0x42,0x61,0x90,0xA0,0x20,0x20,0x74,0xEA, +0x2A,0xB4,0x90,0x2C,0x4A,0x69,0x53,0x1C,0x22,0x4E,0xEE,0x70,0x2F,0x22,0xB4,0x3D,0x27,0x01,0x9F,0xB9, +0xBB,0x0E,0x70,0xE1,0x67,0x29,0x03,0x99,0x92,0x98,0x50,0x8E,0x53,0x89,0xC6,0x12,0x44,0x17,0x4A,0x54, +0xA1,0x80,0x52,0x4E,0x42,0x43,0x42,0x71,0x7B,0x1C,0xC6,0xFE,0x6D,0x79,0xD2,0x6E,0x72,0x9F,0x9F,0xE5, +0xCE,0xE2,0x3B,0x9C,0x2E,0x2A,0x75,0x49,0xEC,0x06,0xB0,0x41,0x1A,0x63,0xBC,0xB4,0xF9,0x5D,0x06,0x50, +0x4B,0x7E,0x82,0x94,0x39,0xD5,0xBA,0x48,0x4D,0xC1,0x73,0x14,0x42,0x93,0x8C,0x2F,0x1E,0x5F,0x65,0x9C, +0x20,0x9F,0xF0,0x07,0xD7,0x91,0xDB,0xA4,0x85,0xB8,0x3B,0x8E,0xA3,0x09,0x85,0x6B,0xEF,0x71,0x1A,0x20, +0x8A,0xAC,0x7E,0x4A,0x50,0x68,0x0D,0x2A,0x95,0xB7,0xA3,0xF8,0x73,0x3B,0x83,0x31,0xCC,0x43,0xEC,0x73, +0xA5,0x61,0xB8,0x84,0xF1,0x2D,0xE1,0x8F,0x01,0x8F,0x16,0x6A,0xBA,0x92,0x1A,0x9A,0xA9,0xDB,0xEB,0x82, +0x6E,0x24,0x1F,0x4A,0x6C,0x25,0x51,0x7B,0x1C,0x73,0x1E,0x47,0xD2,0xDE,0x4A,0x69,0x35,0x69,0x32,0xCF, +0x1F,0x5D,0xC7,0x7A,0xD5,0xD7,0xC8,0xF7,0x40,0xA9,0x9C,0xF8,0x28,0x6C,0xA3,0x90,0x4C,0xA9,0x1B,0x91, +0x20,0x08,0x71,0xCD,0x64,0xDD,0x2C,0x0D,0x8D,0x00,0x71,0xE4,0x92,0x08,0x4D,0x71,0x27,0xA1,0x53,0x80, +0x32,0xBC,0xBB,0x63,0x91,0xF7,0x87,0xE7,0x97,0x73,0xE7,0xF5,0x8B,0x69,0xDC,0x87,0x3F,0x67,0x83,0xD1, +0xEC,0x64,0x34,0x85,0xD1,0xA1,0x98,0xF6,0xDF,0x1D,0xF5,0xDF,0xC1,0xC7,0x51,0xB7,0xF5,0x69,0xF2,0x7B, +0x5F,0x2C,0xBF,0x08,0x0E,0x87,0xA3,0x93,0x7E,0xFF,0x75,0xE7,0xE5,0xD9,0xFC,0xC3,0xEB,0x5D,0x01,0x3E, +0x0C,0x9D,0xCB,0xF7,0x33,0x67,0xB4,0xF5,0x43,0x14,0x9C,0x06,0x33,0x3F,0x1A,0xF5,0xDF,0x7D,0xB8,0xBC, +0xBB,0x8A,0x46,0xD3,0xC1,0x87,0xEE,0xEC,0xE3,0xD6,0xFB,0xC1,0xC7,0x0F,0x3F,0xDD,0xE2,0x9F,0x4F,0x5F, +0x7D,0x1C,0xCE,0x01,0xE1,0x38,0x1E,0x8C,0x2E,0x0F,0xDF,0x1F,0x4E,0x3F,0x1E,0xFA,0x27,0xF7,0xE3,0xF0, +0xEC,0xF0,0x45,0x7F,0xDC,0xDF,0xF2,0x31,0x9E,0x0E,0x2F,0x0F,0xB3,0x97,0xAF,0xCF,0xA7,0x84,0xCC,0x06, +0x1F,0xCF,0x86,0xFE,0xD1,0xB3,0x37,0xA3,0xD3,0x3E,0x99,0x9D,0xBD,0xBA,0x74,0x6E,0x5F,0xBC,0x3E,0x3A, +0xF6,0xAF,0x5E,0x5D,0xED,0x1E,0x6F,0x77,0xBE,0xFF,0xFE,0x6D,0x70,0x4E,0xE8,0xF0,0xEE,0x73,0x7F,0x7A, +0x34,0x7F,0xFE,0xC0,0x86,0xB3,0x97,0x77,0xB4,0xF3,0x3E,0xFE,0xF4,0xF2,0xE1,0x2D,0xFC,0xBF,0xB8,0x68, +0x8D,0x07,0x5D,0x36,0x7A,0xF7,0xF2,0xFD,0x16,0xFB,0xE1,0x59,0x72,0x78,0x7C,0x7C,0x17,0x8D,0x2F,0x3A, +0x51,0x70,0x3B,0xE1,0xCF,0xB7,0x79,0x72,0x35,0xCD,0x3E,0xFE,0xFE,0xEC,0xD5,0xAC,0x73,0x8E,0xD1,0xD5, +0xAC,0xF5,0xF0,0xF9,0xE1,0xF9,0x6C,0x78,0x7A,0x77,0x16,0xA2,0xFB,0xB3,0x33,0xFF,0x73,0xD4,0x0A,0xD1, +0x0F,0xE7,0xC3,0x10,0xA5,0xDD,0x51,0xD0,0xEF,0xB4,0x8E,0xB6,0xFA,0x3B,0x3C,0xBD,0x3C,0xA2,0xC7,0xDB, +0x9F,0x06,0xCF,0x0F,0x0F,0xBB,0xF1,0xF8,0xF7,0xAD,0x17,0xB7,0xBB,0x2F,0x46,0xBB,0xEF,0xC6,0xEF,0xFA, +0x83,0x9D,0xC3,0x11,0xBA,0x1A,0xBC,0xEB,0x4F,0x76,0xC6,0xB3,0xD9,0xEB,0xD7,0xC3,0x9F,0x82,0xFE,0xE7, +0xB4,0x7F,0x3E,0xEF,0xDF,0x9F,0x8C,0xFA,0xA7,0xAD,0xD7,0x27,0x6F,0x9D,0xEE,0xE0,0x6A,0x7B,0xFA,0x76, +0x77,0x7E,0xC8,0x4E,0xFA,0xEF,0x0E,0x9D,0xE9,0xAB,0x56,0x84,0x3E,0xC6,0x47,0xDB,0xD3,0x97,0xBB,0xE4, +0xE2,0x0A,0xF5,0x5F,0x1E,0xBE,0x62,0xE4,0x32,0x3A,0x1D,0x39,0xFD,0xFE,0x9B,0x73,0xFC,0xD3,0xD1,0x36, +0x7A,0xBD,0xE5,0x7F,0x00,0xFD,0x8F,0x7E,0xC6,0xDF,0xB7,0xFA,0xF3,0x73,0x27,0xF4,0x7F,0xC0,0xC3,0xD3, +0xAB,0xA1,0xBC,0x9D,0x93,0xF0,0xA7,0xE1,0xED,0x20,0x7B,0x17,0x1D,0x1D,0x99,0x1A,0x8D,0xDB,0x29,0x4E, +0x30,0xE2,0xF5,0x58,0x55,0x3A,0x07,0xD8,0x56,0x65,0x85,0xB9,0x93,0x8A,0xC0,0xDA,0x0E,0xB0,0x1F,0xA7, +0x48,0xEE,0x01,0x04,0x9C,0x0A,0x13,0x5B,0xFE,0x28,0x43,0xAD,0xA6,0x22,0xAD,0x86,0x68,0xA0,0x19,0x85, +0x23,0x44,0x84,0x02,0xCE,0x1D,0xF1,0x71,0x3B,0x21,0xF7,0x38,0x6C,0x4B,0x64,0xD7,0x31,0x17,0xD2,0xD9, +0x8A,0x6D,0x88,0x92,0x48,0x51,0x2D,0x16,0x82,0x4F,0xC8,0x17,0xC9,0x01,0x5C,0x26,0x82,0xCF,0xDC,0x77, +0xE2,0xB4,0x3D,0xCE,0xA6,0x13,0x72,0x0F,0xDE,0x3C,0x21,0x94,0x70,0xAC,0x75,0xD9,0xF2,0xC7,0x82,0xCC, +0x2D,0x7E,0x98,0xA4,0x28,0xC2,0x4C,0xFB,0x9B,0x64,0x16,0x93,0x34,0x8E,0x16,0x55,0x04,0xE4,0x71,0x6D, +0xB2,0x5C,0x7E,0x95,0x25,0x61,0x8C,0x40,0xCC,0x35,0x61,0x43,0x05,0xD3,0x54,0xB8,0x55,0x19,0x54,0x0B, +0x37,0xDB,0x02,0xB7,0x6C,0xB8,0xF5,0xD6,0x4E,0xE5,0xBA,0x6D,0xB9,0x57,0x04,0xFB,0xBA,0xEA,0x6B,0xF1, +0xA0,0x16,0xEB,0xBE,0xE2,0xA0,0xD2,0xF5,0x87,0xAB,0x43,0x54,0x64,0xA8,0x18,0x50,0x51,0xBA,0xBB,0xEB, +0xD4,0x42,0x05,0xEC,0x5B,0x7E,0x85,0x65,0xC6,0xB4,0xBE,0x4A,0x52,0xB8,0x0D,0x3C,0xFF,0x02,0xCD,0x52, +0xA6,0x26,0x6D,0xA0,0x59,0xA6,0x3B,0x25,0x42,0x95,0xF3,0x24,0xAF,0x25,0xE9,0xC7,0x52,0x01,0xB8,0xE4, +0xE6,0x99,0xE0,0xE6,0x8B,0x5A,0xDD,0xDE,0xFD,0x26,0xE7,0x61,0xC7,0xF9,0x66,0x69,0xAB,0xBD,0x65,0x3E, +0xEE,0x3A,0xF0,0xA7,0x48,0xBB,0xCF,0x2B,0x16,0xC6,0xCF,0xC4,0xDF,0x82,0x41,0xA0,0x53,0x07,0x6E,0xEF, +0xFC,0xF0,0x3C,0x18,0x17,0x40,0x25,0xD8,0xD3,0xF0,0x14,0x05,0x24,0x63,0xEE,0x33,0xE7,0x1B,0xA5,0x4F, +0xB8,0x3E,0x90,0xBD,0xB8,0x5C,0x35,0xA9,0x2C,0x96,0x25,0x84,0x6A,0x5B,0x4C,0x13,0xF7,0x8D,0xD2,0xD2, +0x30,0xEB,0xA9,0x1E,0x5C,0xA4,0x32,0x4D,0xB1,0x7F,0xE1,0x7C,0xB3,0xE0,0x29,0xA2,0x6C,0x12,0xA7,0x91, +0x9B,0xC6,0x1C,0x71,0x6C,0x38,0xE6,0xB2,0xEB,0xAC,0x03,0x6C,0xEF,0x3A,0x01,0x9E,0x9A,0xCB,0xE5,0x5E, +0x07,0x92,0x9A,0x2C,0x78,0xFC,0x94,0x24,0x7C,0x7F,0x92,0x51,0x5F,0xF0,0xA0,0x4D,0xB1,0x81,0xCD,0x45, +0x8A,0x79,0x96,0x52,0x2D,0x88,0xFD,0x4C,0x18,0xBB,0x3D,0xC5,0xFC,0x44,0xD9,0xFD,0xE1,0xC3,0xCB,0x00, +0x76,0x2C,0x4B,0x04,0x7F,0x2D,0x02,0x38,0x30,0x9C,0x97,0xE3,0x34,0xF6,0x43,0x82,0x01,0x22,0xAF,0xF1, +0x83,0x81,0x2D,0x5E,0x22,0x62,0x5B,0xAC,0x1B,0x46,0xB1,0x0D,0x80,0xD4,0x5C,0xDC,0x81,0x16,0x90,0x87, +0xAF,0xF9,0x8D,0x45,0x3C,0x0A,0x1F,0xBD,0x7C,0x3B,0xD9,0x47,0x07,0xED,0xAE,0x8B,0xF6,0xC9,0x41,0x17, +0xFC,0xCB,0xAC,0xD1,0x57,0x27,0xFF,0x44,0x42,0x3C,0xCA,0x5D,0x4E,0x1C,0x54,0x51,0xEB,0x18,0xE4,0x62, +0x06,0x8A,0x34,0xBF,0x33,0xCE,0x07,0x9A,0x71,0xFD,0x7D,0xFB,0x87,0x9B,0x3F,0xBA,0xD7,0x4E,0xBB,0x7B, +0x63,0xFE,0x66,0x76,0x88,0xCD,0x31,0xE3,0x06,0x45,0x77,0x64,0x8A,0xC0,0xCE,0x6D,0x91,0x6F,0xFB,0x53, +0x90,0xC2,0xEC,0x95,0x67,0x10,0xC5,0xDE,0x96,0xE3,0x6C,0x78,0xF8,0x00,0x85,0x18,0x58,0xD7,0x4F,0x2E, +0x2F,0xCF,0x2F,0xAF,0xF5,0x16,0x6E,0xE9,0x37,0xAE,0xA6,0xB7,0xA8,0xE9,0x72,0x3B,0xC5,0x93,0x14,0xB3, +0xD9,0x05,0xE2,0x33,0x23,0xB0,0xEF,0x50,0x98,0x81,0x2E,0x04,0x23,0xB1,0x07,0x8A,0xD3,0xC7,0x19,0xD8, +0x0F,0xD5,0xCD,0x5E,0x6C,0x13,0x4A,0x71,0x7A,0x3A,0x7C,0xFB,0xC6,0xD3,0x2F,0x15,0x92,0xF6,0x86,0x30, +0xAE,0x5B,0xF2,0x46,0x6C,0x94,0x24,0x98,0x06,0x47,0x33,0x12,0x06,0x46,0x6C,0xF6,0x04,0x09,0x5F,0x92, +0x90,0xC5,0x08,0x50,0xF0,0x6D,0x55,0xB5,0x4E,0x40,0x72,0xDD,0xF2,0xED,0x28,0x0B,0x39,0x49,0x42,0xEC, +0x6D,0x74,0x61,0x46,0x51,0x04,0x30,0x91,0x8A,0x05,0x8C,0x04,0x9E,0xAE,0x02,0x92,0x0A,0x63,0x6B,0x4F, +0xF1,0xD5,0x29,0x41,0xE3,0x94,0xA0,0x8E,0x9B,0x80,0x54,0xBA,0x15,0xD8,0x55,0xB9,0x0C,0xB3,0xFC,0xA8, +0x02,0x16,0xE0,0x09,0x02,0x4E,0xDE,0x83,0xE4,0xB0,0xDA,0x59,0x77,0x50,0xA0,0x0E,0x62,0x4D,0x8D,0xB0, +0xBA,0x46,0xD4,0x55,0xAE,0x43,0x66,0x0A,0x39,0x6D,0x22,0xA7,0x75,0xE4,0x23,0x69,0x11,0xEB,0x90,0x53, +0x85,0x1C,0x36,0x44,0x0C,0xA5,0x88,0x2A,0xCA,0xB5,0x85,0x36,0x41,0x20,0xC0,0x0E,0xEB,0x62,0xC2,0x0C, +0x9C,0x12,0x8D,0x43,0x1C,0x78,0x1B,0x0E,0xCC,0x44,0x61,0xED,0x6D,0x39,0x6B,0xCE,0x08,0xD5,0x19,0x59, +0xE3,0x8C,0x4C,0x9E,0x41,0x12,0x50,0x22,0xE4,0x0E,0xDD,0xCA,0xA4,0xD6,0x9A,0x2B,0xEA,0x38,0x7F,0x86, +0xFD,0x5B,0x28,0xEF,0xD7,0xB1,0x9F,0x99,0xB0,0x4D,0x6E,0x10,0x6C,0x6C,0x20,0x79,0x50,0x22,0x0F,0x92, +0x3D,0x0A,0x1C,0x94,0xD8,0xE0,0xFE,0x9E,0x38,0xCE,0x4A,0xEA,0x3A,0x39,0x0F,0x03,0x8D,0x80,0xFD,0xAF, +0x23,0x9B,0x28,0x8E,0xA3,0xA6,0x4A,0xA3,0x3A,0xBA,0x36,0x40,0x77,0x78,0x2D,0x72,0x64,0x5A,0xA9,0x1D, +0x53,0x3F,0x24,0xFE,0xAD,0x57,0x79,0xB3,0xB9,0x30,0xEA,0x13,0x41,0x9F,0x7B,0x14,0xCF,0xB5,0x9F,0x20, +0x3A,0x1D,0x23,0x8E,0x7A,0x3C,0x27,0x63,0xE4,0xA6,0x83,0x81,0x10,0xB4,0x77,0x98,0x71,0x66,0xA3,0x00, +0x96,0x2F,0x46,0x43,0xDD,0xD2,0x3B,0xE2,0x62,0x74,0x70,0x68,0x62,0x2E,0xCD,0xD2,0xA5,0x2C,0x2A,0x83, +0xFB,0x28,0x0D,0xAB,0x25,0x18,0x14,0x46,0xB7,0xB4,0xA2,0xB5,0x3C,0x91,0x89,0x51,0x2A,0xB0,0x60,0x0A, +0xF9,0xD8,0x16,0x67,0x18,0xB9,0x09,0xE8,0x26,0x44,0x3F,0x65,0xBF,0x86,0x69,0xA1,0x26,0xD3,0xA8,0x64, +0x3A,0x45,0xF3,0xC2,0x4E,0xD4,0xF9,0x3D,0xE5,0xE5,0x0E,0x24,0x61,0xCA,0xB8,0x86,0xBD,0x1D,0xE7,0x87, +0xDD,0x1E,0xDC,0x86,0xA1,0x7C,0x17,0x00,0x7B,0xDC,0x06,0xEB,0x9A,0xF2,0x59,0xCF,0x6F,0x79,0xB9,0x56, +0x02,0x8F,0xDB,0x2C,0x1B,0x33,0x9E,0x42,0x8A,0x33,0x7C,0xCB,0x6F,0x61,0xB3,0x79,0x8C,0xDE,0x8A,0xAD, +0xC0,0xB4,0xE2,0x56,0x6B,0xB9,0xA2,0xA0,0xF3,0x41,0x4D,0x43,0x48,0x68,0x08,0x87,0x0C,0x6B,0xD4,0xC6, +0xF7,0xD8,0x3F,0x8A,0xA3,0x08,0x09,0x12,0x0C,0xAE,0x2E,0x9F,0xE8,0xE6,0xD2,0x8A,0xD7,0x6A,0xE6,0x89, +0xC8,0x65,0xB1,0xA7,0xF4,0x08,0x91,0xD0,0xF3,0x6D,0xE1,0x2E,0x2C,0x17,0xEA,0xCB,0xB7,0x5C,0xC4,0x22, +0x85,0x72,0xED,0xDC,0x58,0xE5,0xC5,0xAD,0x97,0xAA,0xBA,0x77,0x61,0x75,0x8D,0x10,0x64,0x56,0x37,0x2D, +0x60,0xCD,0xD0,0x56,0x41,0xF5,0xE5,0xD2,0xF2,0x05,0xFF,0x33,0x44,0xA7,0xF8,0xEF,0x0B,0x50,0xF1,0x28, +0xBD,0xD4,0xA2,0x90,0x43,0x0E,0xDC,0x5F,0x6C,0xE3,0xFA,0x57,0xFB,0xA6,0x65,0x9A,0x07,0x5F,0x77,0xA4, +0x86,0x0D,0x6E,0x5E,0x77,0x6F,0x2C,0x04,0x60,0xFB,0x3B,0xF3,0x17,0x5B,0x82,0x1B,0xB0,0xDE,0x5D,0x4C, +0x02,0x4D,0x9C,0x24,0x9C,0x3B,0x9E,0x68,0x68,0x73,0xD3,0x00,0x93,0x6B,0x18,0x6B,0x8B,0xB7,0x74,0x1B, +0xD2,0xC7,0x72,0xB9,0x9A,0xD4,0x86,0x29,0xC6,0x2A,0x6B,0x96,0x00,0xC9,0x3D,0xC8,0xBC,0x1A,0xAF,0x4A, +0xA9,0xB1,0x55,0x41,0x61,0x51,0x66,0x7D,0x3B,0x2F,0x28,0x3C,0x5D,0x54,0x14,0x10,0x6B,0x56,0x97,0x65, +0xA7,0x07,0xEB,0x35,0x97,0xFF,0x76,0x8F,0x44,0x53,0x8D,0xA5,0xBE,0xA7,0xAE,0xE2,0x40,0xFC,0xF0,0xBE, +0x15,0xD9,0x6E,0xF3,0x37,0x7F,0xEC,0xE9,0x2D,0xB8,0x5F,0x6C,0xD3,0x78,0x6E,0x98,0xAD,0x6F,0x75,0x4D, +0x52,0xF4,0xF4,0x08,0xDD,0xE7,0xFD,0xBE,0x28,0x48,0x7A,0x1A,0xCC,0xCB,0x06,0x55,0x2D,0xA8,0x4E,0x1B, +0x65,0x3C,0xEE,0x69,0x45,0xA1,0xA3,0x3A,0x4D,0x5D,0xEB,0xEC,0x7F,0x5B,0xE9,0x00,0x81,0xE8,0x48,0xDD, +0x09,0x91,0xA1,0x29,0x13,0x01,0x0E,0x37,0xA2,0x0F,0xC9,0xDD,0x4E,0xC5,0x40,0x02,0x70,0xB2,0x92,0x39, +0xAD,0xC0,0x40,0xE6,0x81,0xD1,0xC8,0xB7,0x7B,0xA2,0x37,0xD9,0xBF,0x50,0x45,0xE7,0x5E,0x47,0xCE,0xF4, +0x75,0x8E,0x01,0x9A,0xA7,0x80,0x6E,0x95,0x65,0xCE,0x38,0x0E,0x1E,0x6A,0xC5,0x11,0x3B,0x7C,0x38,0x0A, +0x11,0x63,0x67,0x28,0x82,0xF3,0xFD,0x48,0x37,0x73,0x53,0xDA,0x77,0x36,0x37,0x9B,0x48,0x29,0x8E,0xA0, +0x17,0x52,0x5C,0x61,0x08,0x65,0xAE,0x0F,0x84,0x37,0x37,0xD7,0x31,0x26,0x9E,0xA8,0xBE,0xC4,0x15,0x05, +0x77,0x2D,0xC2,0xDF,0xFF,0xC4,0x9D,0xCA,0xB1,0x4F,0x69,0x35,0x05,0x9F,0x7D,0xCC,0xF6,0x71,0x3C,0xA7, +0x82,0xAB,0x92,0xF5,0x74,0x8D,0x42,0xAB,0xBC,0x50,0x5A,0x72,0x90,0xE3,0xB5,0x27,0xA9,0x32,0xE4,0x9A, +0xD1,0x15,0x30,0x30,0x37,0xBC,0x34,0xFF,0x1F,0x61,0x55,0x49,0xF0,0x94,0xAC,0xA1,0x69,0x85,0x6B,0x64, +0xC5,0x21,0xE6,0xB8,0x94,0x34,0x5C,0x2B,0x29,0xFB,0x7F,0xF8,0xAD,0x3C,0x84,0xA8,0x4A,0xB7,0xEE,0x23, +0x01,0xB9,0xD3,0x21,0x57,0x78,0x4D,0x0A,0xCC,0x4F,0xE3,0x30,0x1C,0xC6,0xC9,0xC1,0x13,0xEB,0x6E,0xB9, +0x9E,0x0F,0x0A,0x36,0xAB,0x2D,0x96,0xBF,0x96,0xE8,0x1B,0x3C,0xE1,0x07,0x4F,0x01,0x9E,0x26,0x5B,0xED, +0xB1,0x02,0x0F,0xDB,0xA0,0x3C,0x58,0xFD,0xB9,0xE5,0x5B,0xAC,0x9C,0x5D,0xB5,0x62,0xB8,0x0B,0xBF,0x50, +0x92,0x27,0x94,0x64,0x91,0xB5,0xA1,0xAB,0x5A,0x17,0xED,0xA5,0x17,0xB4,0xF4,0xE4,0xBE,0x5A,0xE3,0x71, +0xE2,0x31,0xB5,0x84,0x0C,0x62,0xF1,0x95,0x4B,0x59,0x17,0x50,0x52,0x8F,0xD8,0xF1,0x64,0xC2,0x30,0xFF, +0x20,0x82,0x99,0x15,0x96,0xF3,0x53,0x19,0xCC,0x7A,0x30,0xA5,0x51,0x9C,0x31,0x1C,0x67,0xBC,0x59,0xF6, +0x94,0xC2,0xEC,0x05,0x7F,0xFC,0x51,0x4E,0xF6,0x83,0x56,0x5A,0x4D,0xAF,0xF6,0x58,0x6D,0xB2,0xCF,0x5A, +0x21,0x84,0x82,0xFF,0xD8,0x52,0x48,0xDD,0x52,0x62,0x11,0x4B,0xAD,0x58,0x59,0x0A,0xAB,0x6C,0x9D,0x89, +0xBA,0x14,0xD5,0xBC,0x5D,0x18,0xB4,0x6E,0x16,0x6D,0x57,0xDD,0xCB,0x91,0xC5,0x56,0x83,0xC0,0xFA,0xE2, +0xC0,0x37,0x04,0x55,0xD0,0xFA,0x9B,0x78,0x8E,0xD3,0x23,0xC4,0xB0,0x01,0x39,0xB3,0x8C,0x58,0x12,0x6A, +0xBA,0xC1,0x9A,0x5D,0xA0,0x04,0xAA,0xC0,0x79,0xE1,0x11,0x53,0x51,0x7D,0x83,0x7C,0x59,0xE3,0x04,0x6C, +0x8B,0x07,0x03,0x90,0xFA,0x58,0x35,0x1B,0x50,0xA7,0x61,0x9B,0xC1,0x35,0x5F,0xA4,0x71,0x82,0xA6,0xB2, +0xB9,0x86,0x35,0xE1,0x1E,0x05,0xB5,0x5A,0x6A,0x2D,0xEB,0x51,0x99,0xD6,0x1F,0x67,0x75,0x2C,0x33,0x37, +0x54,0x08,0xAB,0xC9,0x9B,0x9B,0x6C,0x4E,0xB8,0x3F,0x13,0xBE,0xED,0x03,0xC3,0x3A,0x87,0xCE,0xC0,0x95, +0xA3,0x19,0x8F,0xAA,0x51,0x98,0x0F,0x3F,0xB1,0x7C,0xE0,0xB3,0x62,0x74,0x5F,0x03,0xC6,0xB4,0x00,0xC7, +0x74,0x92,0x0F,0x09,0x25,0x05,0x9D,0x02,0x58,0x7C,0x26,0x49,0x3E,0x4A,0x66,0xC5,0x68,0x86,0xEF,0x4B, +0xBC,0xB8,0x80,0x06,0x58,0x77,0xD5,0xF5,0x6D,0x38,0xCB,0x7C,0xD0,0xAD,0xC4,0x0F,0xFE,0x3B,0xF1,0x13, +0x3A,0x2D,0x84,0x49,0x8A,0xD1,0x94,0x14,0xA2,0x8C,0xA3,0xE4,0x8B,0x8C,0xB0,0x7F,0xDB,0x17,0x1C,0x9F, +0xBC,0x39,0x19,0x9E,0xD4,0x4B,0xC4,0xFA,0x2B,0x02,0xFF,0xAB,0x36,0x9D,0x9B,0xAE,0x91,0xD4,0x3D,0x05, +0x66,0xBE,0xF8,0x3C,0x8B,0x03,0x59,0xF4,0x41,0xC0,0x37,0x12,0xA0,0xAE,0x9B,0x66,0xE3,0xA1,0x21,0x6D, +0x3C,0x60,0x54,0x81,0x3E,0x7F,0x19,0x00,0x3D,0x6D,0x6E,0xD6,0x18,0x91,0xEB,0xD5,0xE3,0x07,0xB5,0x74, +0x55,0xA7,0x49,0x67,0x43,0x4F,0x15,0x34,0xC8,0x2C,0x5B,0x06,0xE2,0xD1,0xDC,0xD1,0x2D,0xD1,0x3D,0x90, +0x7D,0x1F,0xDA,0x86,0x96,0xA9,0x1A,0x7E,0xCF,0xF3,0xE8,0xB5,0x7F,0x23,0x9B,0xC6,0xCD,0x4D,0xD4,0x2C, +0x7A,0x0C,0xC7,0x92,0x40,0x71,0xA0,0x1C,0xC9,0x76,0x15,0x64,0x01,0xB6,0x1C,0xEB,0xD5,0xE0,0xFC,0xCC, +0x4E,0x50,0x0A,0x1E,0x47,0xCD,0x7A,0x90,0x08,0x95,0x80,0x4D,0x6D,0xBF,0x38,0xA9,0x55,0xE3,0xF2,0x7B, +0x21,0x97,0x2F,0xAD,0xD4,0x10,0xE4,0x54,0x9F,0x2B,0x72,0x78,0xFE,0x80,0x07,0xA9,0x27,0x29,0xD2,0x50, +0x15,0x45,0x92,0x7A,0x10,0xE7,0x77,0xD9,0xFA,0x1E,0xD4,0xE2,0x33,0xC2,0xEA,0x5D,0x48,0xC3,0xE5,0xFF, +0xE6,0x8D,0x2D,0x8B,0x91,0x22,0xB7,0x5A,0x50,0xAB,0x2F,0xFF,0xD4,0xE5,0xC8,0x86,0x69,0x51,0x45,0xC8, +0xCA,0x1C,0x75,0xC8,0x2C,0x84,0xEA,0x16,0xFD,0xA7,0x1E,0x42,0x0B,0x0F,0xA1,0x8F,0x03,0x04,0xBE,0x6F, +0x78,0x7B,0x79,0x4A,0x6F,0x0C,0x9C,0xDD,0xF6,0xCA,0x28,0x02,0x10,0x19,0x43,0x1A,0x80,0x4F,0x4C,0xAE, +0x7F,0x42,0x77,0x48,0xBD,0xDF,0x55,0xD0,0xF5,0xA1,0x42,0x6E,0xF7,0x7F,0x83,0x51,0xB9,0xB3,0x19,0x88, +0x18,0x0C,0x1F,0xC7,0x13,0xDE,0x08,0x4F,0x55,0xCC,0xAA,0x47,0x27,0x70,0xD7,0xDC,0x9B,0x35,0x5E,0xD3, +0x6F,0xCD,0xF5,0xC0,0x20,0x9F,0xF4,0xBD,0x5A,0x20,0x52,0x18,0x75,0xEB,0x59,0xDF,0xAE,0x34,0x1B,0x9A, +0xF5,0xE9,0x5F,0xFA,0x1F,0x3E,0x60,0x36,0x2B,0x5A,0x77,0x70,0xF3,0xDA,0x4C,0xD7,0x45,0xB6,0xF2,0x43, +0x8C,0xD2,0x81,0xE8,0x12,0x55,0x86,0x58,0xAA,0x0B,0xF4,0xA4,0xEB,0x1A,0xA0,0xB1,0x8E,0x7C,0x28,0xB6, +0x85,0x1E,0x00,0xA1,0x84,0x52,0x80,0x52,0x2F,0x06,0x9A,0xB5,0x45,0x04,0x8B,0x08,0x1A,0x9E,0x98,0xC6, +0xB7,0x88,0xD4,0xB7,0x13,0x80,0x90,0xFC,0xEB,0x64,0xE8,0xEB,0xAC,0xFC,0x22,0x24,0xA1,0x0A,0xA2,0xAE, +0xDF,0xCC,0xDF,0xC2,0xAA,0x67,0x08,0x5C,0xF8,0x4D,0x6E,0x20,0x1B,0x12,0x8D,0x89,0x82,0x60,0x80,0x19, +0x93,0x8C,0x0B,0xC1,0xDE,0xC6,0x01,0xC8,0x05,0x68,0x9D,0x08,0x46,0xE2,0x20,0x10,0x51,0x00,0x86,0x33, +0x1C,0xE5,0x10,0x0E,0x43,0x01,0x42,0x02,0xF4,0xB5,0xD4,0xD5,0x40,0x16,0x5E,0x84,0x4E,0xBD,0x6E,0xC7, +0xB1,0x1E,0x93,0x1D,0x31,0x3C,0x88,0x27,0x7C,0x88,0xC6,0xCC,0xD8,0x70,0xCC,0x35,0x3B,0x00,0x34,0x80, +0x70,0x62,0x6C,0x99,0xEB,0xD1,0x3F,0xC4,0xE9,0x2D,0x4E,0x8D,0x8D,0x6E,0xCE,0xCF,0x29,0x14,0x4C,0x21, +0xFC,0xE7,0x7D,0x50,0xFB,0x1D,0x7E,0x43,0x28,0xCE,0x29,0x33,0x40,0x9E,0xC5,0xF3,0x8B,0x94,0x50,0xFE, +0x56,0xF6,0x85,0x39,0x96,0xAF,0x9E,0x2B,0x64,0x08,0x2A,0xDE,0x31,0x16,0x22,0x9A,0xB9,0x8D,0xD7,0x0C, +0x6B,0x0C,0xF7,0x05,0xC1,0xD5,0x5D,0xCC,0x09,0x75,0xF5,0x23,0x9E,0x86,0xED,0x81,0x6E,0x45,0xC8,0x87, +0x89,0xDA,0x03,0xF3,0xA5,0x25,0xBC,0xD6,0xAD,0x47,0x93,0x8D,0x6A,0x52,0x15,0xD0,0x6B,0x9F,0x7A,0xAA, +0x97,0x0B,0x01,0x3C,0x0C,0xE3,0xB1,0x21,0x5E,0xA7,0x17,0xC2,0xE3,0x5D,0xBA,0x34,0x45,0x7A,0xFA,0xF2, +0xAB,0x8C,0x0F,0x61,0x97,0x5B,0xB8,0xF6,0xA8,0xD4,0xD2,0x75,0xF1,0x56,0x03,0x78,0x28,0x38,0xA7,0xE1, +0x83,0x0B,0x69,0xF1,0x2F,0xA4,0xCE,0x68,0x10,0x7F,0x49,0xEA,0x8F,0x2B,0x52,0x7F,0x5C,0x27,0x35,0x6E, +0xDE,0x16,0x4C,0x46,0x40,0xF6,0x2D,0xA2,0x68,0x8A,0x53,0x58,0x10,0x87,0xC0,0x05,0xFC,0x33,0xCE,0x52, +0xFC,0x65,0xCE,0x06,0x33,0x32,0xE1,0xAB,0xFC,0xA9,0xD5,0x7F,0xC7,0x65,0x8A,0x9F,0xE0,0xB2,0x28,0x30, +0xCB,0xBC,0xF1,0xD7,0x4F,0x25,0xD2,0xA9,0x3D,0xB8,0xC2,0xBA,0xBB,0xFE,0x0B,0xBF,0xAB,0x4E,0xFC,0x72, +0xFA,0x14,0x1F,0x2E,0x5E,0x5A,0x81,0xB0,0x89,0x66,0x59,0x1A,0xD3,0x43,0xA8,0xE0,0xDF,0x80,0x08,0x86, +0x32,0x47,0xEC,0x2D,0x96,0x16,0xF7,0x0C,0x50,0x25,0x74,0xC1,0x20,0x9C,0x2F,0xEB,0x5A,0x7B,0x06,0x29, +0x12,0x94,0x00,0x4C,0x42,0xA2,0xED,0x5C,0x1F,0x6C,0xDE,0xB4,0x20,0x43,0x79,0xF0,0x61,0x7A,0x30,0xD8, +0xBC,0xF9,0xCE,0xEC,0x4C,0x49,0xAD,0x26,0x92,0xB9,0x0E,0xF4,0x7A,0x4D,0x6F,0x3C,0xB4,0x84,0x10,0x56, +0xCF,0x85,0x65,0x64,0xB5,0xB0,0x7C,0xF5,0x82,0x8F,0x10,0xD1,0x29,0x7C,0xC8,0xD8,0x01,0xE1,0x69,0xCD, +0xF7,0x2B,0x7A,0xA6,0x46,0x80,0x55,0x7B,0xA8,0xD2,0x39,0xFC,0xD4,0x45,0x7B,0xC5,0x6B,0xC1,0x50,0x91, +0x85,0xB8,0xA7,0x06,0xF5,0x18,0x2B,0x92,0x74,0x71,0x69,0x39,0xD8,0x5C,0x0A,0x53,0xC7,0x13,0x42,0x71, +0xA0,0x97,0x79,0xF5,0xE7,0xB7,0x6F,0x4E,0x39,0x4F,0x2E,0x95,0x66,0x81,0x56,0x73,0xA1,0xBA,0x70,0x73, +0xC1,0xD3,0x87,0xA2,0x42,0x13,0x0E,0xAB,0x42,0xCE,0xCF,0xE7,0xE3,0x4F,0xD8,0x87,0x7C,0xF4,0x96,0x41, +0x32,0xDB,0xB2,0x05,0xFA,0x70,0x78,0x61,0xEF,0xDA,0x0E,0x94,0x0C,0x3E,0x82,0x94,0x2D,0x6E,0x6E,0xF9, +0x8F,0x90,0xB7,0xFF,0x19,0x32,0x81,0xB8,0xCB,0x20,0xB0,0x16,0xF8,0x4D,0xDC,0x59,0x1A,0xCF,0x25,0xDA, +0x49,0x9A,0x8A,0x4B,0x19,0xCE,0x08,0xD3,0xC6,0xB0,0xC8,0x70,0xAA,0x05,0x31,0x66,0x1A,0x8D,0xB9,0xC6, +0xB2,0x24,0x89,0x53,0xBE,0xA2,0x0F,0x5B,0x2F,0x1E,0x6C,0xDE,0x65,0x38,0xC3,0x41,0xBE,0x8C,0xD3,0xBA, +0x5E,0x64,0x71,0x05,0xEB,0x60,0xF6,0xD7,0x37,0x79,0xA9,0x95,0x51,0x2A,0xF2,0xC0,0x46,0x57,0xCD,0x41, +0xBA,0x19,0x50,0xF5,0x68,0x16,0x86,0xCB,0xDE,0x0A,0x2D,0xE8,0xB8,0x62,0x1E,0xCB,0xAF,0x28,0x16,0xBF, +0xE5,0x26,0xEE,0xAE,0xBC,0xA8,0x36,0xA9,0x3A,0xD6,0x86,0xB1,0x81,0x35,0x42,0x19,0x47,0xD4,0x17,0xD7, +0xA8,0x74,0x61,0x16,0x65,0x96,0xD8,0xDE,0x13,0xFE,0x29,0x6D,0xE9,0xC9,0xDC,0x2E,0x25,0xA3,0x9E,0xAE, +0x8B,0x8A,0x0B,0x8B,0xC2,0x15,0x45,0xAC,0x46,0xB6,0x8C,0xD8,0x26,0xF5,0x0A,0x70,0x4F,0xBE,0x83,0x37, +0xF7,0xAF,0xB2,0x51,0x94,0xD9,0x08,0x60,0x5A,0xB1,0xCF,0xA4,0x2D,0x4F,0x97,0x99,0xFA,0x40,0xBA,0xAE, +0x34,0xE0,0x08,0xF3,0x59,0x1C,0x1C,0xE8,0x07,0xBA,0xAB,0xC3,0xBF,0x4D,0xDD,0x82,0x5D,0x98,0xFA,0xE0, +0xFE,0xA3,0xCB,0x97,0x10,0xD2,0x92,0x98,0x62,0xCA,0x0D,0x04,0x91,0xDD,0xD3,0x5B,0x6B,0x20,0x05,0xF9, +0x6B,0x74,0x63,0xF6,0x9A,0xCA,0xC6,0xF3,0x95,0xEB,0x6C,0x5C,0x86,0x1D,0x53,0x11,0xE5,0x1E,0x80,0x79, +0x8E,0x1F,0xBD,0x63,0x5B,0xF4,0x71,0x3B,0x62,0x2E,0x76,0x04,0xCF,0x12,0x6B,0x00,0x58,0xC2,0xF5,0x2A, +0x25,0x3F,0x55,0x62,0x51,0xDB,0x47,0x61,0x28,0xBE,0x7E,0x07,0x5E,0xC5,0x61,0x19,0xB3,0x04,0x11,0x06, +0x02,0x30,0x3C,0xC4,0xF7,0xE0,0xD2,0xB2,0x4E,0x52,0x36,0x94,0xF7,0x25,0x40,0x9A,0xD7,0xCC,0xC8,0xB4, +0xCA,0xD9,0xE6,0x26,0xB7,0x0B,0x33,0x31,0x0A,0x24,0x26,0x82,0xBE,0x61,0x8A,0x9E,0xC3,0xA8,0x0B,0x29, +0x72,0xE8,0x23,0x6D,0x1B,0x4D,0x35,0x24,0x98,0x1A,0x05,0x0C,0x38,0xCB,0xD2,0x10,0x22,0xB5,0xA8,0x22, +0x1A,0xDB,0x18,0xA6,0x01,0x1C,0xE0,0xFE,0x25,0xB2,0x44,0xA5,0x75,0xAB,0x18,0xF0,0x54,0xF1,0xDD,0xA4, +0xC7,0xF3,0x5B,0x39,0xC5,0x32,0xF2,0x35,0x7F,0xF3,0xD0,0xD2,0x51,0x92,0x84,0x44,0x05,0xE6,0x0E,0x3C, +0x7C,0xCF,0xE7,0x6D,0x30,0xAB,0xA8,0x0D,0x27,0x28,0x2B,0x08,0xF4,0x35,0x1C,0xAA,0xB6,0xCB,0x12,0x0F, +0x16,0xEE,0x8A,0x8B,0x56,0xFA,0x33,0x56,0x7C,0xB4,0x49,0xA7,0xC9,0x67,0xED,0xB6,0xF7,0x76,0x56,0x40, +0x68,0x2C,0xBE,0x67,0x87,0x5C,0x03,0xE9,0xA8,0x3C,0xAD,0xE8,0x80,0xEA,0x71,0xC1,0x4E,0x32,0x36,0x33, +0x16,0xC0,0xBA,0xCB,0x2D,0xA5,0x2B,0x17,0x5B,0xCA,0x6E,0x5D,0x6A,0x15,0xF6,0xE1,0x42,0x0A,0x69,0xC4, +0x8F,0x3F,0xFE,0x90,0xB3,0xEA,0xB6,0x61,0xB6,0x72,0xE1,0x4B,0xF5,0xC6,0x5A,0x64,0x46,0x61,0xF4,0xAB, +0xB1,0x6A,0xAF,0xA3,0x1A,0x9B,0xE2,0x17,0x14,0x34,0x12,0x78,0x22,0xC9,0xEA,0xEA,0x31,0x18,0x46,0x13, +0x08,0x4B,0x36,0x34,0x42,0xC5,0xAF,0x76,0xEA,0xF9,0xEF,0x76,0xAE,0x62,0xEE,0x97,0x8D,0x99,0xE7,0x95, +0x55,0xB5,0x8A,0x39,0x6A,0x83,0xF7,0xC4,0x2F,0x2D,0xE8,0x0A,0x0C,0x7D,0xAB,0x1A,0xD8,0xE5,0xD1,0xE2, +0x58,0x2B,0x5F,0x44,0xEC,0x81,0xFA,0x22,0x66,0x96,0x54,0x66,0xA0,0xFC,0x46,0x2F,0xAB,0x76,0x9A,0xCB, +0x8A,0x33,0xF1,0x38,0xA7,0xC5,0xF9,0x4B,0x76,0x3D,0xD3,0x03,0xFB,0xD0,0x2A,0x0B,0x61,0x0B,0x07,0x95, +0xAD,0x72,0x39,0x03,0xE9,0x00,0x5E,0x6D,0xCA,0x92,0xF5,0x00,0x95,0x7B,0x57,0x17,0x55,0x6A,0x5F,0x5D, +0x2E,0xDB,0xAD,0xFC,0x2B,0x9B,0xDA,0x6F,0x9B,0x54,0x24,0x88,0x7C,0x8C,0x97,0xDB,0x9B,0xEF,0xF3,0x4F, +0x61,0x29,0x84,0xFD,0x3F,0x01,0xA4,0x40,0xDC,0x9E,0xCB,0x2B,0x00,0x00 +}; From 525a0f1e50380b2f7599893c210c4b0997535547 Mon Sep 17 00:00:00 2001 From: lorol Date: Wed, 1 Apr 2020 12:33:56 -0400 Subject: [PATCH 050/551] Added tool to help embedding htm file to code with one click See in /extras + improvement of rehg.c / exe and typo corrections in Readme --- extras/Readme | 6 +++--- extras/rehg.c | 9 +++------ extras/rehg.exe | Bin 2560 -> 2560 bytes src/edit.htm.gz.h | 2 +- 4 files changed, 7 insertions(+), 10 deletions(-) diff --git a/extras/Readme b/extras/Readme index 7c3ebfd6e..80ae78470 100644 --- a/extras/Readme +++ b/extras/Readme @@ -1,8 +1,8 @@ ehg.c (ehg.exe): Tool to generate C-code array from file' bytes -Based on https://github.com/TheLivingOne/bin2array/ and compiled on TynyCC +Based on https://github.com/TheLivingOne/bin2array/ and compiled with TynyCC -rehg.c (rehg.exe): Tool to generate C-code array from file' bytes -Based on https://github.com/birkett/cbintools/tree/master/bin2c and compiled on TynyCC +rehg.c (rehg.exe): Tool to reverse C-code array generated by ehg.exe back to a file +Based on https://github.com/birkett/cbintools/tree/master/c2bin and compiled with TynyCC Tools used (on Win 10): diff --git a/extras/rehg.c b/extras/rehg.c index c72af5171..8886b51ab 100644 --- a/extras/rehg.c +++ b/extras/rehg.c @@ -24,7 +24,7 @@ /* * rehg.c (rehg.exe): Tool to reverse C-code array to file converted by ehg.exe - * Based on https://github.com/birkett/cbintools/tree/master/bin2c + * Based on https://github.com/birkett/cbintools/tree/master/c2bin * and compiled with TynyCC https://bellard.org/tcc/ */ @@ -32,7 +32,7 @@ #include #include -#define BUFFER_SIZE 80 +#define BUFFER_SIZE 500 int main(int argc, char *argv[]) { @@ -92,10 +92,7 @@ int main(int argc, char *argv[]) pch = strtok(sBuffer, ","); while (pch != NULL) { - // Use atoi() to convert from decimal to a char. - //fprintf(outputFile, "%c", atoi(pch)); // decimal - fprintf(outputFile, "%c", strtol(pch, NULL, 16)); // hex - //printf("%s\n", pch); + fprintf(outputFile, "%c", strtol(pch, NULL, 0)); // autodetect pch = strtok(NULL, ","); } } diff --git a/extras/rehg.exe b/extras/rehg.exe index 06cfe4a03486b1d7662578683f05d88c3f6c7a1a..6e8e6f69b12b14702af34a64bb2ba956bda086f1 100644 GIT binary patch delta 536 zcmZn=X%LyPg3)2(N`0nZaT9MXV@#Ob$k@Wf!!((l$wFx@GXq2O5rG|y3=9k}UjxZ* zSDxkrEIXAI92f$-IRalynViU^t&{*(#sg6{52lP`rzcFA`{Z>@+V#T7$^wDPb^wiK z=xqJ+_y7NHFxmWriNDtnWSJn4fQWS-bbu&%eY@NBPr!~ZK#c*ttt|ik{||U^feGY5 zp4V3}rM5z(ntw3xx7-Jswxga4NWyi_2TOBww*CRz4kE!ydBGNgxI2L?h7OJ$waD5s zVA_6wwSh>mHddgbmlgm2|KE|X;DE5j5vH8s-~W1`CxH}1y%$hD*!uwx5+W7wLK3Wj zCtyb*$e3=|9|14;AVNDzKq3&;FJ1uyq4@~V^&kUZFMs(TNP(qJ9tIj5+WEBcjS7%4 zq1W|Az>6fXVwTBrELDs;lV`G|Gai}D$ePbuC+xs5d2%VMGUo;$tJ9Td$CAwpS=E^q HaWDY@ctG2= delta 461 zcmZn=X%LyPf{|n5N`0mniHWzCF=|Y1WNcx|V3^F#WT8~b%)romL|_La0|Ud$tw6Hd zm8bat%T8ql2Zq3Ij=&c&lM|V=l{CQ0cp%C$V9Gdldcu_PPhQ8QU4NSiWExbNG*Hz$H82DRu16A+ff@`S(OL278yDsQw@Ak_57M0x5{X2ChE> zUT{Lhc9ejGAZlMc1qMa)5spsRC9gNUR0CNBG>GBk;mP(a6B$z`Ut~#V{4?2-HJ{Z@ i*nuH>@>*79&I%x_)0JmO&gPq}>P(Xr7%diYFaZGbNSIjw diff --git a/src/edit.htm.gz.h b/src/edit.htm.gz.h index 398e37f23..f482f1e82 100644 --- a/src/edit.htm.gz.h +++ b/src/edit.htm.gz.h @@ -1,6 +1,6 @@ #define edit_htm_gz_len 4314 const uint8_t edit_htm_gz[] PROGMEM = { -0x1F,0x8B,0x08,0x08,0x4B,0x0B,0x84,0x5E,0x02,0x00,0x65,0x64,0x69,0x74,0x2E,0x68,0x74,0x6D,0x00,0xB5, +0x1F,0x8B,0x08,0x08,0x30,0xC1,0x84,0x5E,0x02,0x00,0x65,0x64,0x69,0x74,0x2E,0x68,0x74,0x6D,0x00,0xB5, 0x1A,0x0B,0x5B,0xDB,0x36,0xF0,0xAF,0x18,0x6F,0x63,0xF6,0xE2,0x38,0x0E,0x50,0xD6,0x39,0x18,0x16,0x1E, 0x2B,0x7D,0x01,0x25,0x49,0x3B,0xCA,0xD8,0x3E,0xC5,0x56,0x12,0x15,0x5B,0xF6,0x2C,0x99,0x40,0xB3,0xFC, 0xF7,0x9D,0x24,0x3F,0x43,0xE8,0x1E,0xDF,0xD6,0x07,0x91,0x74,0xBA,0xD3,0xDD,0xE9,0x9E,0x0A,0x7B,0x1B, From da8e271b869a9efd4b1c5d73f78d5f76387abc4e Mon Sep 17 00:00:00 2001 From: lorol Date: Fri, 3 Apr 2020 16:29:02 -0400 Subject: [PATCH 051/551] Added another tool to update acefull.js.gz from sources in addition to tools for embedding of edit.htm file Changed flags in do.bat to less aggressive edit.htm minifying w/o "Remove space between attributes" See: extras/update_ace.bat Updated examples/SmartSwitch/data/acefull.js.gz Updated Readme --- examples/SmartSwitch/data/acefull.js.gz | Bin 116297 -> 116605 bytes extras/Readme | 20 +- extras/do.bat | 2 +- extras/tmp1/placeholder | 0 extras/update_ace.bat | 14 + src/edit.htm.gz.h | 424 ++++++++++++------------ 6 files changed, 235 insertions(+), 225 deletions(-) create mode 100644 extras/tmp1/placeholder create mode 100644 extras/update_ace.bat diff --git a/examples/SmartSwitch/data/acefull.js.gz b/examples/SmartSwitch/data/acefull.js.gz index 57ab200896332c7dfdd0dc4c25eb9d06a86034ae..55e603987c85f75e218196817a418dc810c959d9 100644 GIT binary patch literal 116605 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�&kX!N9J;Ig+OBjb~3_ti{IdtIQ2KT`FazfT}(62 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%0A7tM~l_j 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 O`sg3$aU+O`!3F?xKx||H literal 116297 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
-
- +
+
-
- -
- + + -
+ -
- -
+ @@ -319,15 +327,14 @@
-
- -
+
+
- - - - - -
-
-
-
- - - - + + + + + + ESP Editor + + + + + + + + + + +
+
+
+
+ + + + \ No newline at end of file diff --git a/src/edit.htm.gz.h b/src/edit.htm.gz.h index 21057eefb..cbcacd57d 100644 --- a/src/edit.htm.gz.h +++ b/src/edit.htm.gz.h @@ -1,219 +1,224 @@ -#define edit_htm_gz_len 4316 + +//File: edit.htm.gz, Size: 4365 +#define edit_htm_gz_len 4365 const uint8_t edit_htm_gz[] PROGMEM = { -0x1F,0x8B,0x08,0x08,0x33,0x95,0x87,0x5E,0x02,0x00,0x65,0x64,0x69,0x74,0x2E,0x68,0x74,0x6D,0x00,0xB5, -0x1A,0x0B,0x5B,0xDB,0x36,0xF0,0xAF,0x18,0x6F,0x63,0xF6,0xE2,0x38,0x0E,0x50,0xD6,0x39,0x18,0x16,0x1E, -0x2B,0x7D,0x01,0x25,0x49,0x3B,0xCA,0xD8,0x3E,0xC5,0x56,0x12,0x15,0x5B,0xF6,0x2C,0x99,0x40,0xB3,0xFC, -0xF7,0x9D,0x24,0x3F,0x43,0xE8,0x1E,0xDF,0xD6,0x07,0x91,0x74,0xBA,0xD3,0xDD,0xE9,0x9E,0x0A,0x7B,0x1B, -0xC7,0xE7,0x47,0xC3,0xAB,0x8B,0x13,0x6D,0xC6,0xA3,0x70,0x7F,0x4F,0xFC,0xD4,0x42,0x44,0xA7,0x9E,0x8E, -0xA9,0xBE,0xBF,0x17,0x61,0x8E,0x00,0xC4,0x93,0x36,0xFE,0x3D,0x23,0x77,0x9E,0x7E,0x14,0x53,0x8E,0x29, -0x6F,0xF3,0x87,0x04,0xEB,0x9A,0xAF,0x66,0x9E,0xCE,0xF1,0x3D,0xEF,0x08,0xE4,0x9E,0xE6,0xCF,0x50,0xCA, -0x30,0xF7,0x32,0x3E,0x69,0x3F,0x07,0x12,0x9C,0xF0,0x10,0xEF,0x9F,0x0C,0x2E,0xB4,0x93,0x80,0xF0,0x38, -0xDD,0xEB,0xA8,0x95,0x3D,0xC6,0x1F,0x42,0xAC,0x09,0x42,0x39,0xBE,0xCF,0x98,0xAE,0x45,0x38,0x20,0xC8, -0xD3,0x99,0x9F,0x62,0xC1,0x41,0x88,0xC6,0x38,0x5C,0x4C,0x62,0x38,0x92,0x91,0xCF,0xD8,0xED,0x6E,0x25, -0xF7,0x3D,0x39,0x9D,0xA0,0x88,0x84,0x0F,0x2E,0x43,0x94,0xB5,0x19,0x4E,0xC9,0x64,0x69,0xFB,0xD1,0xE2, -0x73,0x9B,0xD0,0x00,0xDF,0xBB,0xDB,0x8E,0xD3,0x4B,0x62,0x46,0x38,0x89,0xA9,0x8B,0xC6,0x2C,0x0E,0x33, -0x8E,0x7B,0x21,0x9E,0x70,0xF7,0x19,0x50,0x18,0xC7,0x69,0x80,0x53,0xB7,0x9B,0xDC,0x6B,0x00,0x22,0x81, -0xF6,0xD5,0xCE,0xCE,0x4E,0x6F,0x8C,0xFC,0xDB,0x69,0x1A,0x67,0x34,0x68,0xFB,0x71,0x18,0xA7,0xEE,0x57, -0x93,0x67,0xE2,0x6F,0x2F,0x20,0x2C,0x09,0xD1,0x83,0x4B,0x63,0x8A,0x01,0xF7,0xBE,0xCD,0x66,0x28,0x88, -0xE7,0xAE,0xA3,0x39,0x5A,0xD7,0x01,0x22,0xE9,0x74,0x8C,0x0C,0xC7,0x12,0x7F,0xED,0x1D,0xB3,0xF7,0xB7, -0xF8,0x55,0xCB,0x73,0x4C,0xA6,0x33,0xEE,0x7E,0xEF,0x38,0x82,0x7F,0x2D,0x0B,0x17,0x21,0x61,0xBC,0x2D, -0x95,0xA3,0xCE,0xE3,0x71,0xE2,0x3A,0x92,0x75,0xF8,0x88,0x50,0x3A,0x25,0x14,0x06,0x09,0x0A,0x02,0x42, -0xA7,0xAE,0x42,0x0B,0xC9,0xA2,0x94,0x36,0xC5,0x21,0xE2,0xE4,0x0E,0xF7,0x22,0x42,0xDB,0x73,0x12,0xF0, -0x99,0xBB,0xEB,0x00,0x17,0x7E,0x96,0x32,0x90,0x29,0x89,0x09,0xE5,0x38,0x95,0x68,0x2C,0x41,0x74,0xA1, -0x44,0x15,0x0A,0x28,0xE5,0x24,0x34,0x24,0x14,0xB7,0xC7,0x61,0xEC,0xDF,0x96,0x27,0xED,0x26,0xF7,0xF9, -0x59,0xEE,0x2C,0xBE,0xC3,0xE9,0xA2,0x52,0x97,0xC4,0x6E,0x00,0x1B,0xA4,0x31,0xC6,0x4B,0x9B,0xDF,0x65, -0x00,0xB5,0xE4,0x27,0x48,0x99,0x53,0xAD,0x8B,0xD4,0x14,0x3C,0x47,0x21,0x34,0xC9,0xF8,0xE2,0xF1,0x55, -0xC6,0x09,0xF2,0x09,0x7F,0x70,0x1D,0xB9,0x4D,0x5A,0x88,0xBB,0xE3,0x38,0x9A,0x50,0xB8,0xF6,0x1E,0xA7, -0x01,0xA2,0xC8,0xEA,0xA7,0x04,0x85,0xD6,0xA0,0x52,0x79,0x3B,0x8A,0x3F,0xB7,0x33,0x18,0xC3,0x3C,0xC4, -0x3E,0x57,0x1A,0x86,0x4B,0x18,0xDF,0x12,0xFE,0x18,0xF0,0x68,0xA1,0xA6,0x2B,0xA9,0xA1,0x99,0xBA,0xBD, -0x2E,0xE8,0x46,0xF2,0xA1,0xC4,0x56,0x12,0xB5,0xC7,0x31,0xE7,0x71,0x24,0xED,0xAD,0x94,0x56,0x93,0x26, -0xF3,0xFC,0xD1,0x75,0xAC,0x57,0x7D,0x8D,0x7C,0x0F,0x94,0xCA,0x89,0x8F,0xC2,0x36,0x0A,0xC9,0x94,0xBA, -0x11,0x09,0x82,0x10,0xD7,0x4C,0xD6,0xCD,0xD2,0xD0,0x08,0x10,0x47,0x2E,0x89,0xD0,0x14,0x77,0x12,0x3A, -0x05,0x28,0xC3,0xBB,0x3B,0x16,0x79,0x7F,0x78,0x7E,0x39,0x77,0x5E,0xBF,0x98,0xC6,0x7D,0xF8,0x73,0x36, -0x18,0xCD,0x4E,0x46,0x53,0x18,0x1D,0x8A,0x69,0xFF,0xDD,0x51,0xFF,0x1D,0x7C,0x1C,0x75,0x5B,0x9F,0x26, -0xBF,0xF7,0xC5,0xF2,0x8B,0xE0,0x70,0x38,0x3A,0xE9,0xF7,0x5F,0x77,0x5E,0x9E,0xCD,0x3F,0xBC,0xDE,0x15, -0xE0,0xC3,0xD0,0xB9,0x7C,0x3F,0x73,0x46,0x5B,0x3F,0x44,0xC1,0x69,0x30,0xF3,0xA3,0x51,0xFF,0xDD,0x87, -0xCB,0xBB,0xAB,0x68,0x34,0x1D,0x7C,0xE8,0xCE,0x3E,0x6E,0xBD,0x1F,0x7C,0xFC,0xF0,0xD3,0x2D,0xFE,0xF9, -0xF4,0xD5,0xC7,0xE1,0x1C,0x10,0x8E,0xE3,0xC1,0xE8,0xF2,0xF0,0xFD,0xE1,0xF4,0xE3,0xA1,0x7F,0x72,0x3F, -0x0E,0xCF,0x0E,0x5F,0xF4,0xC7,0xFD,0x2D,0x1F,0xE3,0xE9,0xF0,0xF2,0x30,0x7B,0xF9,0xFA,0x7C,0x4A,0xC8, -0x6C,0xF0,0xF1,0x6C,0xE8,0x1F,0x3D,0x7B,0x33,0x3A,0xED,0x93,0xD9,0xD9,0xAB,0x4B,0xE7,0xF6,0xC5,0xEB, -0xA3,0x63,0xFF,0xEA,0xD5,0xD5,0xEE,0xF1,0x76,0xE7,0xFB,0xEF,0xDF,0x06,0xE7,0x84,0x0E,0xEF,0x3E,0xF7, -0xA7,0x47,0xF3,0xE7,0x0F,0x6C,0x38,0x7B,0x79,0x47,0x3B,0xEF,0xE3,0x4F,0x2F,0x1F,0xDE,0xC2,0xFF,0x8B, -0x8B,0xD6,0x78,0xD0,0x65,0xA3,0x77,0x2F,0xDF,0x6F,0xB1,0x1F,0x9E,0x25,0x87,0xC7,0xC7,0x77,0xD1,0xF8, -0xA2,0x13,0x05,0xB7,0x13,0xFE,0x7C,0x9B,0x27,0x57,0xD3,0xEC,0xE3,0xEF,0xCF,0x5E,0xCD,0x3A,0xE7,0x18, -0x5D,0xCD,0x5A,0x0F,0x9F,0x1F,0x9E,0xCF,0x86,0xA7,0x77,0x67,0x21,0xBA,0x3F,0x3B,0xF3,0x3F,0x47,0xAD, -0x10,0xFD,0x70,0x3E,0x0C,0x51,0xDA,0x1D,0x05,0xFD,0x4E,0xEB,0x68,0xAB,0xBF,0xC3,0xD3,0xCB,0x23,0x7A, -0xBC,0xFD,0x69,0xF0,0xFC,0xF0,0xB0,0x1B,0x8F,0x7F,0xDF,0x7A,0x71,0xBB,0xFB,0x62,0xB4,0xFB,0x6E,0xFC, -0xAE,0x3F,0xD8,0x39,0x1C,0xA1,0xAB,0xC1,0xBB,0xFE,0x64,0x67,0x3C,0x9B,0xBD,0x7E,0x3D,0xFC,0x29,0xE8, -0x7F,0x4E,0xFB,0xE7,0xF3,0xFE,0xFD,0xC9,0xA8,0x7F,0xDA,0x7A,0x7D,0xF2,0xD6,0xE9,0x0E,0xAE,0xB6,0xA7, -0x6F,0x77,0xE7,0x87,0xEC,0xA4,0xFF,0xEE,0xD0,0x99,0xBE,0x6A,0x45,0xE8,0x63,0x7C,0xB4,0x3D,0x7D,0xB9, -0x4B,0x2E,0xAE,0x50,0xFF,0xE5,0xE1,0x2B,0x46,0x2E,0xA3,0xD3,0x91,0xD3,0xEF,0xBF,0x39,0xC7,0x3F,0x1D, -0x6D,0xA3,0xD7,0x5B,0xFE,0x07,0xD0,0xFF,0xE8,0x67,0xFC,0x7D,0xAB,0x3F,0x3F,0x77,0x42,0xFF,0x07,0x3C, -0x3C,0xBD,0x1A,0xCA,0xDB,0x39,0x09,0x7F,0x1A,0xDE,0x0E,0xB2,0x77,0xD1,0xD1,0x91,0xA9,0xD1,0xB8,0x9D, -0xE2,0x04,0x23,0x5E,0x8F,0x55,0xA5,0x73,0x80,0x6D,0x55,0x56,0x98,0x3B,0xA9,0x88,0xAC,0xED,0x00,0xFB, -0x71,0x8A,0xE4,0x1E,0x40,0xC0,0xA9,0x30,0xB1,0xE5,0x8F,0x32,0xD4,0x6A,0x2A,0xD2,0x6A,0x88,0x06,0x9A, -0x51,0x38,0x42,0x44,0x28,0xE0,0xDC,0x11,0x1F,0xB7,0x13,0x72,0x8F,0xC3,0xB6,0x44,0x76,0x1D,0x73,0x21, -0x9D,0xAD,0xD8,0x86,0x28,0x89,0x14,0xD5,0x62,0x21,0xF8,0x84,0x7C,0x91,0x1E,0xC0,0x65,0x22,0xF8,0xCC, -0x7D,0x27,0x4E,0xDB,0xE3,0x6C,0x3A,0x21,0xF7,0xE0,0xCD,0x13,0x42,0x09,0xC7,0x5A,0x97,0x2D,0x7F,0x2C, -0xC8,0xDC,0xE2,0x87,0x49,0x8A,0x22,0xCC,0xB4,0xBF,0x49,0x66,0x31,0x49,0xE3,0x68,0x51,0x45,0x40,0x1E, -0xD7,0x26,0xCB,0xE5,0x57,0x59,0x12,0xC6,0x08,0xC4,0x5C,0x13,0x36,0x54,0x30,0x4D,0x85,0x5B,0x95,0x41, -0xB5,0x70,0xB3,0x2D,0x70,0xCB,0x86,0x5B,0x6F,0xED,0x54,0xAE,0xDB,0x96,0x7B,0x45,0xB0,0xAF,0xAB,0xBE, -0x16,0x0F,0x6A,0xB1,0xEE,0x2B,0x0E,0x2A,0x5D,0x7F,0xB8,0x3A,0x44,0x45,0x86,0x8A,0x01,0x15,0xA5,0xBB, -0xBB,0x4E,0x2D,0x54,0xC0,0xBE,0xE5,0x57,0x58,0xA6,0x4C,0xEB,0xAB,0x24,0x85,0xDB,0xC0,0xF3,0x2F,0xD0, -0x2C,0x65,0x6A,0xD2,0x06,0x9A,0x65,0xBA,0x53,0x22,0x54,0x39,0x4F,0xF2,0x5A,0x92,0x7E,0x2C,0x15,0x80, -0x4B,0x6E,0x9E,0x09,0x6E,0xBE,0xA8,0xD5,0xED,0xDD,0x6F,0x72,0x1E,0x76,0x9C,0x6F,0x96,0xB6,0xDA,0x5B, -0xE6,0xE3,0xAE,0x03,0x7F,0x8A,0xB4,0xFB,0xBC,0x62,0x61,0xFC,0x4C,0xFC,0x2D,0x18,0x04,0x3A,0x75,0xE0, -0xF6,0xCE,0x0F,0xCF,0x83,0x71,0x01,0x54,0x82,0x3D,0x0D,0x4F,0x51,0x40,0x32,0xE6,0x3E,0x73,0xBE,0x51, -0xFA,0x84,0xEB,0x03,0xD9,0x8B,0xCB,0x55,0x93,0xCA,0x62,0x59,0x42,0xA8,0xB6,0xC5,0x34,0x71,0xDF,0x28, -0x2D,0x0D,0xB3,0x9E,0xEA,0xC1,0x45,0x2A,0xD3,0x14,0xFB,0x17,0xCE,0x37,0x0B,0x9E,0x22,0xCA,0x26,0x71, -0x1A,0xB9,0x69,0xCC,0x11,0xC7,0x86,0x63,0x2E,0xBB,0xCE,0x3A,0xC0,0xF6,0xAE,0x13,0xE0,0xA9,0xB9,0x5C, -0xEE,0x75,0x20,0xA9,0xC9,0x8A,0xC7,0x4F,0x49,0xC2,0xF7,0x27,0x19,0xF5,0x05,0x0F,0xDA,0x14,0x1B,0xD8, -0x5C,0xA4,0x98,0x67,0x29,0xD5,0x82,0xD8,0xCF,0x84,0xB1,0xDB,0x53,0xCC,0x4F,0x94,0xDD,0x1F,0x3E,0xBC, -0x0C,0x60,0xC7,0xB2,0x44,0xF0,0xD7,0x22,0x80,0x03,0xC3,0x79,0x39,0x4E,0x63,0x3F,0x24,0x18,0x20,0xF2, -0x1A,0x3F,0x18,0xD8,0xE2,0x25,0x22,0xB6,0xC5,0xBA,0x61,0x14,0xDB,0x00,0x48,0xCD,0xC5,0x1D,0x68,0x01, -0x79,0xF8,0x9A,0xDF,0x58,0xC4,0xA3,0xF0,0xD1,0xCB,0xB7,0x93,0x7D,0x74,0xD0,0xEE,0xBA,0x68,0x9F,0x1C, -0x74,0xC1,0xBF,0xCC,0x1A,0x7D,0x75,0xF2,0x4F,0x24,0xC4,0xA3,0xDC,0xE5,0xC4,0x41,0x15,0xB5,0x8E,0x41, -0x2E,0x66,0xA0,0x48,0xF3,0x3B,0xE3,0x7C,0xA0,0x19,0xD7,0xDF,0xB7,0x7F,0xB8,0xF9,0xA3,0x7B,0xED,0xB4, -0xBB,0x37,0xE6,0x6F,0x66,0x87,0xD8,0x1C,0x33,0x6E,0x50,0x74,0x47,0xA6,0x08,0xEC,0xDC,0x16,0xF9,0xB6, -0x3F,0x05,0x29,0xCC,0x5E,0x79,0x06,0x51,0xEC,0x6D,0x39,0xCE,0x86,0x87,0x0F,0x50,0x88,0x81,0x75,0xFD, -0xE4,0xF2,0xF2,0xFC,0xF2,0x5A,0x6F,0xE1,0x96,0x7E,0xE3,0x6A,0x7A,0x8B,0x9A,0x2E,0xB7,0x53,0x3C,0x49, -0x31,0x9B,0x5D,0x20,0x3E,0x33,0x02,0xFB,0x0E,0x85,0x19,0xE8,0x42,0x30,0x12,0x7B,0xA0,0x38,0x7D,0x9C, -0x81,0xFD,0x50,0xDD,0xEC,0xC5,0x36,0xA1,0x14,0xA7,0xA7,0xC3,0xB7,0x6F,0x3C,0xFD,0x52,0x21,0x69,0x6F, -0x08,0xE3,0xBA,0x25,0x6F,0xC4,0x46,0x49,0x82,0x69,0x70,0x34,0x23,0x61,0x60,0xC4,0x66,0x4F,0x90,0xF0, -0x25,0x09,0x59,0x8C,0x00,0x05,0xDF,0x56,0x65,0xEB,0x04,0x24,0xD7,0x2D,0xDF,0x8E,0xB2,0x90,0x93,0x24, -0xC4,0xDE,0x46,0x17,0x66,0x14,0x45,0x00,0x13,0xA9,0x58,0xC0,0x48,0xE0,0xE9,0x2A,0x20,0xA9,0x30,0xB6, -0xF6,0x14,0x5F,0x9D,0x12,0x34,0x4E,0x09,0xEA,0xB8,0x09,0x48,0xA5,0x5B,0x81,0x5D,0xD5,0xCB,0x30,0xCB, -0x8F,0x2A,0x60,0x01,0x9E,0x20,0xE0,0xE4,0x3D,0x48,0x0E,0xAB,0x9D,0x75,0x07,0x05,0xEA,0x20,0xD6,0xD4, -0x08,0xAB,0x6B,0x44,0x5D,0xE5,0x3A,0x64,0xA6,0x90,0xD3,0x26,0x72,0x5A,0x47,0x3E,0x92,0x16,0xB1,0x0E, -0x39,0x55,0xC8,0x61,0x43,0xC4,0x50,0x8A,0xA8,0xA2,0x5C,0x5B,0x68,0x13,0x04,0x02,0xEC,0xB0,0x2E,0x26, -0xCC,0xC0,0x29,0xD1,0x38,0xC4,0x81,0xB7,0xE1,0xC0,0x4C,0x14,0xD6,0xDE,0x96,0xB3,0xE6,0x8C,0x50,0x9D, -0x91,0x35,0xCE,0xC8,0xE4,0x19,0x24,0x01,0x25,0x42,0xEE,0xD0,0xAD,0x4C,0x6A,0xAD,0xB9,0xA2,0x8E,0xF3, -0x67,0xD8,0xBF,0x85,0xF2,0x7E,0x1D,0xFB,0x99,0x09,0xDB,0xE4,0x06,0xC1,0xC6,0x06,0x92,0x07,0x25,0xF2, -0x20,0xD9,0xA3,0xC0,0x41,0x89,0x0D,0xEE,0xEF,0x89,0xE3,0xAC,0xA4,0xAE,0x93,0xF3,0x30,0xD0,0x08,0xD8, -0xFF,0x3A,0xB2,0x89,0xE2,0x38,0x6A,0xAA,0x34,0xAA,0xA3,0x6B,0x03,0x74,0x87,0xD7,0x22,0x47,0xA6,0x95, -0xDA,0x31,0xF5,0x43,0xE2,0xDF,0x7A,0x95,0x37,0x9B,0x0B,0xA3,0x3E,0x11,0xF4,0xB9,0x47,0xF1,0x5C,0xFB, -0x09,0xA2,0xD3,0x31,0xE2,0xA8,0xC7,0x73,0x32,0x46,0x6E,0x3A,0x18,0x08,0x41,0x83,0x87,0x19,0x67,0x36, -0x0A,0x60,0xF9,0x62,0x34,0xD4,0x2D,0xBD,0x23,0x2E,0x46,0x07,0x87,0x26,0xE6,0xD2,0x2C,0x5D,0xCA,0xA2, -0x32,0xB8,0x8F,0xD2,0xB0,0x5A,0x82,0x41,0x61,0x74,0x4B,0x2B,0x5A,0xCB,0x13,0x99,0x18,0xA5,0x02,0x0B, -0xA6,0x90,0x8F,0x6D,0x71,0x86,0x91,0x9B,0x80,0x6E,0x42,0xF4,0x53,0xF6,0x6B,0x98,0x16,0x6A,0x32,0x8D, -0x4A,0xA6,0x53,0x34,0x2F,0xEC,0x44,0x9D,0xDF,0x53,0x5E,0xEE,0x40,0x12,0xA6,0x8C,0x6B,0xD8,0xDB,0x71, -0x7E,0xD8,0xED,0xC1,0x6D,0x18,0xCA,0x77,0x01,0xB0,0xC7,0x6D,0xB0,0xAE,0x29,0x9F,0xF5,0xFC,0x96,0x97, -0x6B,0x25,0xF0,0xB8,0xCD,0xB2,0x31,0xE3,0x29,0xA4,0x38,0xC3,0xB7,0xFC,0x16,0x36,0x9B,0xC7,0xE8,0xAD, -0xD8,0x0A,0x4C,0x2B,0x6E,0xB5,0x96,0x2B,0x0A,0x3A,0x1F,0xD4,0x34,0x84,0x84,0x86,0x70,0xC8,0xB0,0x46, -0x6D,0x7C,0x8F,0xFD,0xA3,0x38,0x8A,0x90,0x20,0xC1,0xE0,0xEA,0xF2,0x89,0x6E,0x2E,0xAD,0x78,0xAD,0x66, -0x9E,0x88,0x5C,0x16,0x7B,0x4A,0x8F,0x10,0x09,0x3D,0xDF,0x16,0xEE,0xC2,0x72,0xA1,0xBE,0x7C,0xCB,0x45, -0x2C,0x52,0x28,0xD7,0xCE,0x8D,0x55,0x5E,0xDC,0x7A,0xA9,0xAA,0x7B,0x17,0x56,0xD7,0x08,0x41,0x66,0x75, -0xD3,0x02,0xD6,0x0C,0x6D,0x15,0x54,0x5F,0x2E,0x2D,0x5F,0xF0,0x3F,0x43,0x74,0x8A,0xFF,0xBE,0x00,0x15, -0x8F,0xD2,0x4B,0x2D,0x0A,0x39,0xE4,0xC0,0xFD,0xC5,0x36,0xAE,0x7F,0xB5,0x6F,0x5A,0xA6,0x79,0xF0,0x75, -0x47,0x6A,0xD8,0xE0,0xE6,0x75,0xF7,0xC6,0x42,0x00,0xB6,0xBF,0x33,0x7F,0xB1,0x25,0xB8,0x01,0xEB,0xDD, -0xC5,0x24,0xD0,0xC4,0x49,0xC2,0xB9,0xE3,0x89,0x86,0x36,0x37,0x0D,0x30,0xB9,0x86,0xB1,0xB6,0x78,0x4B, -0xB7,0x21,0x7D,0x2C,0x97,0xAB,0x49,0x6D,0x98,0x62,0xAC,0xB2,0x66,0x09,0x90,0xDC,0x83,0xCC,0xAB,0xF1, -0xAA,0x94,0x1A,0x5B,0x15,0x14,0x16,0x65,0xD6,0xB7,0xF3,0x82,0xC2,0xD3,0x45,0x45,0x01,0xB1,0x66,0x75, -0x59,0x76,0x7A,0xB0,0x5E,0x73,0xF9,0x6F,0xF7,0x48,0x34,0xD5,0x58,0xEA,0x7B,0xEA,0x2A,0x0E,0xC4,0x0F, -0xEF,0x5B,0x91,0xED,0x36,0x7F,0xF3,0xC7,0x9E,0xDE,0x82,0xFB,0xC5,0x36,0x8D,0xE7,0x86,0xD9,0xFA,0x56, -0xD7,0x24,0x45,0x4F,0x8F,0xD0,0x7D,0xDE,0xEF,0x8B,0x82,0xA4,0xA7,0xC1,0xBC,0x6C,0x50,0xD5,0x82,0xEA, -0xB4,0x51,0xC6,0xE3,0x9E,0x56,0x14,0x3A,0xAA,0xD3,0xD4,0xB5,0xCE,0xFE,0xB7,0x95,0x0E,0x10,0x88,0x8E, -0xD4,0x9D,0x10,0x19,0x9A,0x32,0x11,0xE0,0x70,0x23,0xFA,0x90,0xDC,0xED,0x54,0x0C,0x24,0x00,0x27,0x2B, -0x99,0xD3,0x0A,0x0C,0x64,0x1E,0x18,0x8D,0x7C,0xBB,0x27,0x7A,0x93,0xFD,0x0B,0x55,0x74,0xEE,0x75,0xE4, -0x4C,0x5F,0xE7,0x18,0xA0,0x79,0x0A,0xE8,0x56,0x59,0xE6,0x8C,0xE3,0xE0,0xA1,0x56,0x1C,0xB1,0xC3,0x87, -0xA3,0x10,0x31,0x76,0x86,0x22,0x38,0xDF,0x8F,0x74,0x33,0x37,0xA5,0x7D,0x67,0x73,0xB3,0x89,0x94,0xE2, -0x08,0x7A,0x21,0xC5,0x15,0x86,0x50,0xE6,0xFA,0x40,0x78,0x73,0x73,0x1D,0x63,0xE2,0x8D,0xEA,0x4B,0x5C, -0x51,0x70,0xD7,0x22,0xFC,0xFD,0x4F,0xDC,0xA9,0x1C,0xFB,0x94,0x56,0x53,0xF0,0xD9,0xC7,0x6C,0x1F,0xC7, -0x73,0x2A,0xB8,0x2A,0x59,0x4F,0xD7,0x28,0xB4,0xCA,0x0B,0xA5,0x25,0x07,0x39,0x5E,0x7B,0x92,0x2A,0x43, -0xAE,0x19,0x5D,0x01,0x03,0x73,0xC3,0x4B,0xF3,0xFF,0x11,0x56,0x95,0x04,0x4F,0xC9,0x1A,0x9A,0x56,0xB8, -0x46,0x56,0x1C,0x62,0x8E,0x4B,0x49,0xC3,0xB5,0x92,0xB2,0xFF,0x87,0xDF,0xCA,0x43,0x88,0xAA,0x74,0xEB, -0x3E,0x12,0x90,0x3B,0x1D,0x72,0x85,0xD7,0xA4,0xC0,0xFC,0x34,0x0E,0xC3,0x61,0x9C,0x1C,0x3C,0xB1,0xEE, -0x96,0xEB,0xF9,0xA0,0x60,0xB3,0xDA,0x62,0xF9,0x6B,0x89,0xBE,0xC1,0x13,0x7E,0xF0,0x14,0xE0,0x69,0xB2, -0xD5,0x1E,0x2B,0xF0,0xB0,0x0D,0xCA,0x83,0xD5,0x9F,0x5B,0xBE,0xC5,0xCA,0xD9,0x55,0x2B,0x86,0xBB,0xF0, -0x0B,0x25,0x79,0x42,0x49,0x16,0x59,0x1B,0xBA,0xAA,0x75,0xD1,0x5E,0x7A,0x41,0x4B,0x4F,0xEE,0xAB,0x35, -0x1E,0x27,0x1E,0x53,0x4B,0xC8,0x20,0x16,0x5F,0xB9,0x94,0x75,0x01,0x25,0xF5,0x88,0x1D,0x4F,0x26,0x0C, -0xF3,0x0F,0x22,0x98,0x59,0x61,0x39,0x3F,0x95,0xC1,0xAC,0x07,0x53,0x1A,0xC5,0x19,0xC3,0x71,0xC6,0x9B, -0x65,0x4F,0x29,0xCC,0x5E,0xF0,0xC7,0x1F,0xE5,0x64,0x3F,0x68,0xA5,0xD5,0xF4,0x6A,0x8F,0xD5,0x26,0xFB, -0xAC,0x15,0x42,0x28,0xF8,0x8F,0x2D,0x85,0xD4,0x2D,0x25,0x16,0xB1,0xD4,0x8A,0x95,0xA5,0xB0,0xCA,0xD6, -0x99,0xA8,0x4B,0x51,0xCD,0xDB,0x85,0x41,0xEB,0x66,0xD1,0x76,0xD5,0xBD,0x1C,0x59,0x6C,0x35,0x08,0xAC, -0x2F,0x0E,0x7C,0x43,0x50,0x05,0xAD,0xBF,0x89,0xE7,0x38,0x3D,0x42,0x0C,0x1B,0x90,0x33,0xCB,0x88,0x25, -0xA1,0xA6,0x1B,0xAC,0xD9,0x05,0x4A,0xA0,0x0A,0x9C,0x17,0x1E,0x31,0x15,0xD5,0x37,0xC8,0x97,0x35,0x4E, -0xC0,0xB6,0x78,0x30,0x00,0xA9,0x8F,0x55,0xB3,0x01,0x75,0x1A,0xB6,0x19,0x5C,0xF3,0x45,0x1A,0x27,0x68, -0x2A,0x9B,0x6B,0x58,0x13,0xEE,0x51,0x50,0xAB,0xA5,0xD6,0xB2,0x1E,0x95,0x69,0xFD,0x71,0x56,0xC7,0x32, -0x73,0x43,0x85,0xB0,0x9A,0xBC,0xB9,0xC9,0xE6,0x84,0xFB,0x33,0xE1,0xDB,0x3E,0x30,0xAC,0x73,0xE8,0x0C, -0x5C,0x39,0x9A,0xF1,0xA8,0x1A,0x85,0xF9,0xF0,0x13,0xCB,0x07,0x3E,0x2B,0x46,0xF7,0x35,0x60,0x4C,0x0B, -0x70,0x4C,0x27,0xF9,0x90,0x50,0x52,0xD0,0x29,0x80,0xC5,0x67,0x92,0xE4,0xA3,0x64,0x56,0x8C,0x66,0xF8, -0xBE,0xC4,0x8B,0x0B,0x68,0x80,0x75,0x57,0x5D,0xDF,0x86,0xB3,0xCC,0x07,0xDD,0x4A,0xFC,0xE0,0xBF,0x13, -0x3F,0xA1,0xD3,0x42,0x98,0xA4,0x18,0x4D,0x49,0x21,0xCA,0x38,0x4A,0xBE,0xC8,0x08,0xFB,0xB7,0x7D,0xC1, -0xF1,0xC9,0x9B,0x93,0xE1,0x49,0xBD,0x44,0xAC,0xBF,0x22,0xF0,0xBF,0x6A,0xD3,0xB9,0xE9,0x1A,0x49,0xDD, -0x53,0x60,0xE6,0x8B,0xCF,0xB3,0x38,0x90,0x45,0x1F,0x04,0x7C,0x23,0x01,0xEA,0xBA,0x69,0x36,0x1E,0x1A, -0xD2,0xC6,0x03,0x46,0x15,0xE8,0xF3,0x97,0x01,0xD0,0xD3,0xE6,0x66,0x8D,0x11,0xB9,0x5E,0x3D,0x7E,0x50, -0x4B,0x57,0x75,0x9A,0x74,0x36,0xF4,0x54,0x41,0x83,0xCC,0xB2,0x65,0x20,0x1E,0xCD,0x1D,0xDD,0x12,0xDD, -0x03,0xD9,0xF7,0xA1,0x6D,0x68,0x99,0xAA,0xE1,0xF7,0x3C,0x8F,0x5E,0xFB,0x37,0xB2,0x69,0xDC,0xDC,0x44, -0xCD,0xA2,0xC7,0x70,0x2C,0x09,0x14,0x07,0xCA,0x91,0x6C,0x57,0x41,0x16,0x60,0xCB,0xB1,0x5E,0x0D,0xCE, -0xCF,0xEC,0x04,0xA5,0xE0,0x71,0xD4,0xAC,0x07,0x89,0x50,0x09,0xD8,0xD4,0xF6,0x8B,0x93,0x5A,0x35,0x2E, -0xBF,0x17,0x72,0xF9,0xD2,0x4A,0x0D,0x41,0x4E,0xF5,0xB9,0x22,0x87,0xE7,0x0F,0x78,0x90,0x7A,0x92,0x22, -0x0D,0x55,0x51,0x24,0xA9,0x07,0x71,0x7E,0x97,0xAD,0xEF,0x41,0x2D,0x3E,0x23,0xAC,0xDE,0x85,0x34,0x5C, -0xFE,0x6F,0xDE,0xD8,0xB2,0x18,0x29,0x72,0xAB,0x05,0xB5,0xFA,0xF6,0x4F,0x5D,0x8E,0x6C,0x98,0x16,0x55, -0x84,0xAC,0xCC,0x51,0x87,0xCC,0x42,0xA8,0x6E,0xD1,0x7F,0xEA,0x21,0xB4,0xF0,0x10,0xFA,0x38,0x40,0xE0, -0xFB,0x86,0xB7,0x97,0xA7,0xF4,0xC6,0xC0,0xD9,0x6D,0xAF,0x8C,0x22,0x00,0x91,0x31,0xA4,0x01,0xF8,0xC4, -0xE4,0xFA,0x27,0x74,0x87,0xD4,0xFB,0x5D,0x05,0x5D,0x1F,0x2A,0xE4,0x76,0xFF,0x37,0x18,0x95,0x3B,0x9B, -0x81,0x88,0xC1,0xF0,0x71,0x3C,0xE1,0x8D,0xF0,0x54,0xC5,0xAC,0x7A,0x74,0x02,0x77,0xCD,0xBD,0x59,0xE3, -0x35,0xFD,0xD6,0x5C,0x0F,0x0C,0xF2,0x49,0xDF,0xAB,0x05,0x22,0x85,0x51,0xB7,0x9E,0xF5,0xED,0x4A,0xB3, -0xA1,0x59,0x9F,0xFE,0xA5,0xFF,0xE1,0x03,0x66,0xB3,0xA2,0x75,0x07,0x37,0xAF,0xCD,0x74,0x5D,0x64,0x2B, -0x3F,0xC4,0x28,0x1D,0x88,0x2E,0x51,0x65,0x88,0xA5,0xBA,0x40,0x4F,0xBA,0xAE,0x01,0x1A,0xEB,0xC8,0x87, -0x62,0x5B,0xE8,0x01,0x10,0x4A,0x28,0x05,0x28,0xF5,0x62,0xA0,0x59,0x5B,0x44,0xB0,0x88,0xA0,0xE1,0x89, -0x69,0x7C,0x8B,0x48,0x7D,0x3B,0x01,0x08,0xC9,0xBF,0x4F,0x86,0xBE,0xCE,0xCA,0x2F,0x42,0x12,0xAA,0x20, -0xEA,0xFA,0xCD,0xFC,0x2D,0xAC,0x7A,0x86,0xC0,0x85,0xDF,0xE4,0x06,0xB2,0x21,0xD1,0x98,0x28,0x08,0x06, -0x98,0x31,0xC9,0xB8,0x10,0xEC,0x6D,0x1C,0x80,0x5C,0x80,0xD6,0x89,0x60,0x24,0x0E,0x02,0x11,0x05,0x60, -0x38,0xC3,0x51,0x0E,0xE1,0x30,0x14,0x20,0x24,0x40,0x5F,0x4B,0x5D,0x0D,0x64,0xE1,0x45,0xE8,0xD4,0xEB, -0x76,0x1C,0xEB,0x31,0xD9,0x11,0xC3,0x83,0x78,0xC2,0x87,0x68,0xCC,0x8C,0x0D,0xC7,0x5C,0xB3,0x03,0x40, -0x03,0x08,0x27,0xC6,0x96,0xB9,0x1E,0xFD,0x43,0x9C,0xDE,0xE2,0xD4,0xD8,0xE8,0xE6,0xFC,0x9C,0x42,0xC1, -0x14,0xC2,0x7F,0xDE,0x07,0xB5,0xDF,0xE1,0x37,0x84,0xE2,0x9C,0x32,0x03,0xE4,0x59,0x3C,0xBF,0x48,0x09, -0xE5,0x6F,0x65,0x5F,0x98,0x63,0xF9,0xEA,0xB9,0x42,0x86,0xA0,0xE2,0x1D,0x63,0x21,0xA2,0x99,0xDB,0x78, -0xCD,0xB0,0xC6,0x70,0x5F,0x10,0x5C,0xDD,0xC5,0x9C,0x50,0x57,0x3F,0xE2,0x69,0xD8,0x1E,0xE8,0x56,0x84, -0x7C,0x98,0xA8,0x3D,0x30,0x5F,0x5A,0xC2,0x6B,0xDD,0x7A,0x34,0xD9,0xA8,0x26,0x55,0x01,0xBD,0xF6,0xA9, -0xA7,0x7A,0xB9,0x10,0xC0,0xC3,0x30,0x1E,0x1B,0xE2,0x75,0x7A,0x21,0x3C,0xDE,0xA5,0x4B,0x53,0xA4,0xA7, -0x2F,0xBF,0xCA,0xF8,0x10,0x76,0xB9,0x85,0x6B,0x8F,0x4A,0x2D,0x5D,0x17,0x6F,0x35,0x80,0x87,0x82,0x73, -0x1A,0x3E,0xB8,0x90,0x16,0xFF,0x42,0xEA,0x8C,0x06,0xF1,0x97,0xA4,0xFE,0xB8,0x22,0xF5,0xC7,0x75,0x52, -0xE3,0xE6,0x6D,0xC1,0x64,0x04,0x64,0xDF,0x22,0x8A,0xA6,0x38,0x85,0x05,0x71,0x08,0x5C,0xC0,0x3F,0xE3, -0x2C,0xC5,0x5F,0xE6,0x6C,0x30,0x23,0x13,0xBE,0xCA,0x9F,0x5A,0xFD,0x77,0x5C,0xA6,0xF8,0x09,0x2E,0x8B, -0x02,0xB3,0xCC,0x1B,0x7F,0xFD,0x54,0x22,0x9D,0xDA,0x83,0x2B,0xAC,0xBB,0xEB,0xBF,0xF0,0xBB,0xEA,0xC4, -0x2F,0xA7,0x4F,0xF1,0xE1,0xE2,0xA5,0x15,0x08,0x9B,0x68,0x96,0xA5,0x31,0x3D,0x84,0x0A,0xFE,0x0D,0x88, -0x60,0x28,0x73,0xC4,0xDE,0x62,0x69,0x71,0xCF,0x00,0x55,0x42,0x17,0x0C,0xC2,0xF9,0xB2,0xAE,0xB5,0x67, -0x90,0x22,0x41,0x09,0xC0,0x24,0x24,0xDA,0xCE,0xF5,0xC1,0xE6,0x4D,0x0B,0x32,0x94,0x07,0x1F,0xA6,0x07, -0x83,0xCD,0x9B,0xEF,0xCC,0xCE,0x94,0xD4,0x6A,0x22,0x99,0xEB,0x40,0xAF,0xD7,0xF4,0xC6,0x43,0x4B,0x08, -0x61,0xF5,0x5C,0x58,0x46,0x56,0x0B,0xCB,0x57,0x2F,0xF8,0x08,0x11,0x9D,0xC2,0x87,0x8C,0x1D,0x10,0x9E, -0xD6,0x7C,0xBF,0xA2,0x67,0x6A,0x04,0x58,0xB5,0x87,0x2A,0x9D,0xC3,0x4F,0x5D,0xB4,0x57,0xBC,0x16,0x0C, -0x15,0x59,0x88,0x7B,0x6A,0x50,0x8F,0xB1,0x22,0x49,0x17,0x97,0x96,0x83,0xCD,0xA5,0x30,0x75,0x3C,0x21, -0x14,0x07,0x7A,0x99,0x57,0x7F,0x7E,0xFB,0xE6,0x94,0xF3,0xE4,0x52,0x69,0x16,0x68,0x35,0x17,0xAA,0x0B, -0x37,0x17,0x3C,0x7D,0x28,0x2A,0x34,0xE1,0xB0,0x2A,0xE4,0xFC,0x7C,0x3E,0xFE,0x84,0x7D,0xC8,0x47,0x6F, -0x19,0x24,0xB3,0x2D,0x5B,0xA0,0x0F,0x87,0x17,0xF6,0xAE,0xED,0x40,0xC9,0xE0,0x23,0x48,0xD9,0xE2,0xE6, -0x96,0xFF,0x08,0x79,0xFB,0x9F,0x21,0x13,0x88,0xBB,0x0C,0x02,0x6B,0x81,0xDF,0xC4,0x9D,0xA5,0xF1,0x5C, -0xA2,0x9D,0xA4,0xA9,0xB8,0x94,0xE1,0x8C,0x30,0x6D,0x0C,0x8B,0x0C,0xA7,0x5A,0x10,0x63,0xA6,0xD1,0x98, -0x6B,0x2C,0x4B,0x92,0x38,0xE5,0x2B,0xFA,0xB0,0xF5,0xE2,0xC1,0xE6,0x5D,0x86,0x33,0x1C,0xE4,0xCB,0x38, -0xAD,0xEB,0x45,0x16,0x57,0xB0,0x0E,0x66,0x7F,0x7D,0x93,0x97,0x5A,0x19,0xA5,0x22,0x0F,0x6C,0x74,0xD5, -0x1C,0xA4,0x9B,0x01,0x55,0x8F,0x66,0x61,0xB8,0xEC,0xAD,0xD0,0x82,0x8E,0x2B,0xE6,0xB1,0xFC,0x8A,0x62, -0xF1,0x5B,0x6E,0xE2,0xEE,0xCA,0x8B,0x6A,0x93,0xAA,0x63,0x6D,0x18,0x1B,0x58,0x23,0x94,0x71,0x44,0x7D, -0x71,0x8D,0x4A,0x17,0x66,0x51,0x66,0x89,0xED,0x3D,0xE1,0x9F,0xD2,0x96,0x9E,0xCC,0xED,0x52,0x32,0xEA, -0xE9,0xBA,0xA8,0xB8,0xB0,0x28,0x5C,0x51,0xC4,0x6A,0x64,0xCB,0x88,0x6D,0x52,0xAF,0x00,0xF7,0xE4,0x3B, -0x78,0x73,0xFF,0x2A,0x1B,0x45,0x99,0x8D,0x00,0xA6,0x15,0xFB,0x4C,0xDA,0xF2,0x74,0x99,0xA9,0x0F,0xA4, -0xEB,0x4A,0x03,0x8E,0x30,0x9F,0xC5,0xC1,0x81,0x7E,0xA0,0xBB,0x3A,0xFC,0xDB,0xD4,0x2D,0xD8,0x85,0xA9, -0x0F,0xEE,0x3F,0xBA,0x7C,0x09,0x21,0x2D,0x89,0x29,0xA6,0xDC,0x40,0x10,0xD9,0x3D,0xBD,0xB5,0x06,0x52, -0x90,0xBF,0x46,0x37,0x66,0xAF,0xA9,0x6C,0x3C,0x5F,0xB9,0xCE,0xC6,0x65,0xD8,0x31,0x15,0x51,0xEE,0x01, -0x98,0xE7,0xF8,0xD1,0x3B,0xB6,0x45,0x1F,0xB7,0x23,0xE6,0x62,0x47,0xF0,0x2C,0xB1,0x06,0x80,0x25,0x5C, -0xAF,0x52,0xF2,0x53,0x25,0x16,0xB5,0x7D,0x14,0x86,0xE2,0xEB,0x77,0xE0,0x55,0x1C,0x96,0x31,0x4B,0x10, -0x61,0x20,0x00,0xC3,0x43,0x7C,0x0F,0x2E,0x2D,0xEB,0x24,0x65,0x43,0x79,0x5F,0x02,0xA4,0x79,0xCD,0x8C, -0x4C,0xAB,0x9C,0x6D,0x6E,0x72,0xBB,0x30,0x13,0xA3,0x40,0x62,0x22,0xE8,0x1B,0xA6,0xE8,0x39,0x8C,0xBA, -0x90,0x22,0x87,0x3E,0xD2,0xB6,0xD1,0x54,0x43,0x82,0xA9,0x51,0xC0,0x80,0xB3,0x2C,0x0D,0x21,0x52,0x8B, -0x2A,0xA2,0xB1,0x8D,0x61,0x1A,0xC0,0x01,0xEE,0x5F,0x22,0x4B,0x54,0x5A,0xB7,0x8A,0x01,0x4F,0x15,0xDF, -0x4D,0x7A,0x3C,0xBF,0x95,0x53,0x2C,0x23,0x5F,0xF3,0x77,0x0F,0x2D,0x1D,0x25,0x49,0x48,0x54,0x60,0xEE, -0xC0,0xC3,0xF7,0x7C,0xDE,0x06,0xB3,0x8A,0xDA,0x70,0x82,0xB2,0x82,0x40,0x5F,0xC3,0xA1,0x6A,0xBB,0x2C, -0xF1,0x60,0xE1,0xAE,0xB8,0x68,0xA5,0x3F,0x63,0xC5,0x47,0x9B,0x74,0x9A,0x7C,0xD6,0x6E,0x7B,0x6F,0x67, -0x05,0x84,0xC6,0xE2,0x7B,0x76,0xC8,0x35,0x90,0x8E,0xCA,0xD3,0x8A,0x0E,0xA8,0x1E,0x17,0xEC,0x24,0x63, -0x33,0x63,0x01,0xAC,0xBB,0xDC,0x52,0xBA,0x72,0xB1,0xA5,0xEC,0xD6,0xA5,0x56,0x61,0x1F,0x2E,0xA4,0x90, -0x46,0xFC,0xF8,0xE3,0x0F,0x39,0xAB,0x6E,0x1B,0x66,0x2B,0x17,0xBE,0x54,0x6F,0xAC,0x45,0x66,0x14,0x46, -0xBF,0x1A,0xAB,0xF6,0x3A,0xAA,0xB1,0x29,0x7E,0x41,0x41,0x23,0x81,0x27,0x92,0xAC,0x9E,0x7F,0x05,0x01, -0xC3,0x09,0xC4,0x25,0x1B,0x3A,0xA1,0xF2,0xB7,0x3B,0xF5,0xFC,0xD7,0x3B,0x57,0x71,0xF7,0xCB,0xD6,0xCC, -0xF3,0xCA,0xBA,0x5A,0x45,0x1D,0xB5,0xC1,0x7B,0xE2,0xD7,0x16,0x74,0x05,0x86,0xCE,0x55,0x0D,0xEC,0xF2, -0x6C,0x71,0xAE,0x95,0x2F,0x22,0xF6,0x40,0x7D,0x11,0x35,0x4B,0x2A,0x33,0x50,0x7F,0xA3,0x9B,0x55,0x3B, -0xCD,0x65,0xC5,0x99,0x78,0x9E,0xD3,0xE2,0xFC,0x2D,0xBB,0x9E,0xEB,0x81,0x7D,0x68,0x96,0x85,0xB8,0x85, -0x8B,0x6A,0xB2,0x5B,0x2E,0xA7,0x20,0x1E,0x6C,0xA8,0x76,0x65,0xC9,0x7A,0x80,0x4A,0xBF,0xAB,0x8B,0x2A, -0xBB,0xAF,0x2E,0x17,0x1D,0x57,0xF9,0xB5,0x4D,0xED,0x37,0x4E,0x2A,0x1A,0x44,0x3E,0xC8,0xCB,0xFD,0xCD, -0x37,0xFA,0x27,0xD1,0x14,0xC6,0xFE,0x9F,0xFB,0x0C,0xD2,0xB3,0xD2,0x2B,0x00,0x00 +0x1F,0x8B,0x08,0x08,0xC6,0xC7,0xA5,0x5E,0x02,0x00,0x65,0x64,0x69,0x74,0x2E,0x68,0x74,0x6D,0x00,0xB5, +0x1A,0x0B,0x5B,0xDB,0x36,0xF0,0xAF,0x18,0x6F,0x63,0xF6,0xE2,0x38,0x0E,0xA5,0xAC,0x73,0x30,0x2C,0x50, +0x56,0xFA,0x02,0x4A,0x42,0x3B,0xCA,0xD8,0x3E,0xC5,0x56,0x62,0x15,0x5B,0xF2,0x6C,0x99,0x40,0xB3,0xFC, +0xF7,0x9D,0x24,0x3F,0x43,0xE8,0x1E,0xDF,0xB6,0xAE,0x8D,0xA4,0xD3,0x9D,0xEE,0xA1,0x7B,0x29,0xD9,0xDD, +0x78,0x7E,0x7A,0x38,0xBE,0x3C,0x3B,0xD2,0x42,0x1E,0x47,0x7B,0xBB,0xE2,0x5F,0x2D,0x42,0x74,0xE6,0xE9, +0x98,0xEA,0x7B,0xBB,0x31,0xE6,0x08,0x40,0x3C,0xE9,0xE2,0xDF,0x73,0x72,0xEB,0xE9,0x87,0x8C,0x72,0x4C, +0x79,0x97,0xDF,0x27,0x58,0xD7,0x7C,0x35,0xF3,0x74,0x8E,0xEF,0x78,0x4F,0x20,0x0F,0x34,0x3F,0x44,0x69, +0x86,0xB9,0x97,0xF3,0x69,0xF7,0x19,0x90,0xE0,0x84,0x47,0x78,0xEF,0x68,0x74,0xA6,0x1D,0x05,0x84,0xB3, +0x74,0xB7,0xA7,0x56,0x76,0x23,0x42,0x6F,0xB4,0x14,0x47,0x9E,0x8E,0x92,0x24,0xC2,0x5D,0xCE,0x72,0x3F, +0xEC,0x12,0xA0,0xA9,0x6B,0x61,0x8A,0xA7,0x9E,0xDE,0x43,0x3E,0xB6,0x61,0x41,0xD7,0xC4,0x71,0x9E,0x4E, +0x62,0x34,0xC3,0xBD,0x3B,0xB5,0xA7,0x49,0x20,0x0B,0x59,0xCA,0xFD,0x9C,0x6B,0xFF,0x0A,0xFB,0x1F,0x20, +0x65,0xFC,0x3E,0xC2,0x0A,0xA4,0x64,0xF6,0xB3,0x4C,0xD7,0x62,0x1C,0x10,0x04,0x5C,0xF8,0x29,0x16,0x5A, +0x8B,0xD0,0x04,0x47,0x8B,0x29,0x03,0x35,0x65,0xE4,0x33,0x76,0xFB,0x5B,0xC9,0xDD,0x40,0x4E,0xA7,0x28, +0x26,0xD1,0xBD,0x9B,0x21,0x9A,0x75,0x33,0x9C,0x92,0xE9,0xD2,0xF6,0xE3,0xC5,0xE7,0x2E,0xA1,0x01,0xBE, +0x73,0x9F,0x38,0xCE,0x20,0x61,0x19,0xE1,0x84,0x51,0x17,0x4D,0x32,0x16,0xE5,0x1C,0x0F,0x22,0x3C,0xE5, +0xEE,0x53,0xA0,0x30,0x61,0x69,0x80,0x53,0xB7,0x9F,0xDC,0x69,0x00,0x22,0x81,0xF6,0xD5,0xF6,0xF6,0xF6, +0x60,0x82,0xFC,0x9B,0x59,0xCA,0x72,0x1A,0x74,0x7D,0x16,0xB1,0xD4,0xFD,0x6A,0xFA,0x54,0xFC,0x19,0x04, +0x24,0x4B,0x22,0x74,0xEF,0x52,0x46,0x31,0xE0,0xDE,0x75,0xB3,0x10,0x05,0x6C,0xEE,0x3A,0x9A,0xA3,0xF5, +0x1D,0x20,0x92,0xCE,0x26,0xC8,0x70,0x2C,0xF1,0xC7,0xDE,0x36,0x07,0x7F,0x8B,0x5F,0xB5,0x3C,0xC7,0x64, +0x16,0x72,0xF7,0x7B,0xC7,0x11,0xFC,0x6B,0x79,0xB4,0x88,0x48,0xC6,0xBB,0x52,0x39,0xEA,0x3C,0xCE,0x12, +0xD7,0x91,0xAC,0xC3,0x47,0x8C,0xD2,0x19,0xA1,0x30,0x48,0x50,0x10,0x10,0x3A,0x73,0x15,0x5A,0x44,0x16, +0x95,0xB4,0x60,0x07,0xC4,0xC9,0x2D,0x1E,0xC4,0x84,0x76,0xE7,0x24,0xE0,0xA1,0xBB,0xE3,0x00,0x17,0x7E, +0x9E,0x66,0x20,0x53,0xC2,0x08,0xE5,0x38,0x95,0x68,0x59,0x82,0xE8,0x42,0x89,0x2A,0x14,0x50,0xC9,0x49, +0x28,0x58,0x14,0x77,0x27,0x11,0xF3,0x6F,0xAA,0x93,0x76,0x92,0xBB,0xE2,0x2C,0x37,0x64,0xB7,0x38,0x5D, +0xD4,0xEA,0x92,0xD8,0x2D,0x60,0x8B,0x34,0xC6,0x78,0x69,0xF3,0xDB,0x1C,0xA0,0x96,0xFC,0x04,0x29,0x0B, +0xAA,0x4D,0x91,0xDA,0x82,0x17,0x28,0x84,0x26,0x39,0x5F,0x3C,0x34,0x25,0x4B,0x90,0x4F,0xF8,0xBD,0xEB, +0xC8,0x6D,0xF2,0x86,0xB8,0xDB,0x8E,0xA3,0x09,0x85,0x6B,0xEF,0x71,0x1A,0x20,0x8A,0xAC,0x61,0x4A,0x50, +0x64,0x8D,0x6A,0x95,0x77,0x63,0xF6,0xB9,0x9B,0xC3,0x18,0xE6,0x11,0xF6,0xB9,0xD2,0x30,0x18,0x61,0x72, +0x43,0xF8,0x43,0xC0,0x83,0x85,0x86,0xAE,0xA4,0x86,0x42,0x65,0xBD,0x3E,0xE8,0x46,0xF2,0xA1,0xC4,0x56, +0x12,0x75,0x27,0x8C,0x73,0x16,0xCB,0xFB,0x56,0x49,0xAB,0xC9,0x2B,0xF3,0xEC,0x81,0x39,0xD6,0xAB,0xBE, +0x41,0x7E,0x00,0x4A,0xE5,0xC4,0x47,0x51,0x17,0x45,0x64,0x46,0xDD,0x98,0x04,0x41,0x84,0x07,0x0D,0x1B, +0xE4,0x69,0x64,0x04,0x88,0x23,0x57,0xF9,0x59,0x42,0x67,0x00,0xCD,0xF0,0xCE,0xB6,0x45,0xDE,0x1F,0x9C, +0x9E,0xCF,0x9D,0xD7,0x2F,0x66,0x6C,0x08,0xFF,0x9D,0x8C,0x2E,0xC2,0xA3,0x8B,0x19,0x8C,0x0E,0xC4,0x74, +0xF8,0xEE,0x70,0xF8,0x0E,0x3E,0x0E,0xFB,0x9D,0x4F,0xD3,0xDF,0x87,0x62,0xF9,0x45,0x70,0x30,0xBE,0x38, +0x1A,0x0E,0x5F,0xF7,0x5E,0x9E,0xCC,0x3F,0xBC,0xDE,0x11,0xE0,0x83,0xC8,0x39,0x7F,0x1F,0x3A,0x17,0x5B, +0x3F,0xC4,0xC1,0x71,0x10,0xFA,0xF1,0xC5,0xF0,0xDD,0x87,0xF3,0xDB,0xCB,0xF8,0x62,0x36,0xFA,0xD0,0x0F, +0x3F,0x6E,0xBD,0x1F,0x7D,0xFC,0xF0,0xD3,0x0D,0xFE,0xF9,0xF8,0xD5,0xC7,0xF1,0x1C,0x10,0x9E,0xB3,0xD1, +0xC5,0xF9,0xC1,0xFB,0x83,0xD9,0xC7,0x03,0xFF,0xE8,0x6E,0x12,0x9D,0x1C,0xBC,0x18,0x4E,0x86,0x5B,0x3E, +0xC6,0xB3,0xF1,0xF9,0x41,0xFE,0xF2,0xF5,0xE9,0x8C,0x90,0x70,0xF4,0xF1,0x64,0xEC,0x1F,0x3E,0x7D,0x73, +0x71,0x3C,0x24,0xE1,0xC9,0xAB,0x73,0xE7,0xE6,0xC5,0xEB,0xC3,0xE7,0xFE,0xE5,0xAB,0xCB,0x9D,0xE7,0x4F, +0x7A,0xDF,0x7F,0xFF,0x36,0x38,0x25,0x74,0x7C,0xFB,0x79,0x38,0x3B,0x9C,0x3F,0xBB,0xCF,0xC6,0xE1,0xCB, +0x5B,0xDA,0x7B,0xCF,0x3E,0xBD,0xBC,0x7F,0x0B,0x7F,0xCF,0xCE,0x3A,0x93,0x51,0x3F,0xBB,0x78,0xF7,0xF2, +0xFD,0x56,0xF6,0xC3,0xD3,0xE4,0xE0,0xF9,0xF3,0xDB,0x78,0x72,0xD6,0x8B,0x83,0x9B,0x29,0x7F,0xF6,0x84, +0x27,0x97,0xB3,0xFC,0xE3,0xEF,0x4F,0x5F,0x85,0xBD,0x53,0x8C,0x2E,0xC3,0xCE,0xFD,0xE7,0xFB,0x67,0xE1, +0xF8,0xF8,0xF6,0x24,0x42,0x77,0x27,0x27,0xFE,0xE7,0xB8,0x13,0xA1,0x1F,0x4E,0xC7,0x11,0x4A,0xFB,0x17, +0xC1,0xB0,0xD7,0x39,0xDC,0x1A,0x6E,0xF3,0xF4,0xFC,0x90,0x3E,0x7F,0xF2,0x69,0xF4,0xEC,0xE0,0xA0,0xCF, +0x26,0xBF,0x6F,0xBD,0xB8,0xD9,0x79,0x71,0xB1,0xF3,0x6E,0xF2,0x6E,0x38,0xDA,0x3E,0xB8,0x40,0x97,0xA3, +0x77,0xC3,0xE9,0xF6,0x24,0x0C,0x5F,0xBF,0x1E,0xFF,0x14,0x0C,0x3F,0xA7,0xC3,0xD3,0xF9,0xF0,0xEE,0xE8, +0x62,0x78,0xDC,0x79,0x7D,0xF4,0xD6,0xE9,0x8F,0x2E,0x9F,0xCC,0xDE,0xEE,0xCC,0x0F,0xB2,0xA3,0xE1,0xBB, +0x03,0x67,0xF6,0xAA,0x13,0xA3,0x8F,0xEC,0xF0,0xC9,0xEC,0xE5,0x0E,0x39,0xBB,0x44,0xC3,0x97,0x07,0xAF, +0x32,0x72,0x1E,0x1F,0x5F,0x38,0xC3,0xE1,0x9B,0x53,0xFC,0xD3,0xE1,0x13,0xF4,0x7A,0xCB,0xFF,0x00,0xFA, +0xBF,0xF8,0x19,0x7F,0xDF,0x19,0xCE,0x4F,0x9D,0xC8,0xFF,0x01,0x8F,0x8F,0x2F,0xC7,0xD2,0x3A,0x47,0xD1, +0x4F,0xE3,0x9B,0x51,0xFE,0x2E,0x3E,0x3C,0x34,0x35,0xCA,0xBA,0x29,0x4E,0x30,0xE2,0xCD,0x58,0x55,0x39, +0x07,0xDC,0xAD,0xFA,0x16,0x16,0x4E,0x2A,0x22,0x6B,0x37,0xC0,0x3E,0x4B,0x91,0xDC,0x03,0x08,0x38,0x15, +0x57,0x6C,0xF9,0xA3,0x0C,0xB5,0x9A,0x8A,0xB4,0x1A,0xA2,0x81,0x66,0x94,0x8E,0x10,0x13,0x0A,0x38,0xB7, +0xC4,0xC7,0xDD,0x84,0xDC,0xE1,0xA8,0x2B,0x91,0x5D,0xC7,0x5C,0x48,0x67,0x2B,0xB7,0x21,0x4A,0x62,0x45, +0xB5,0x5C,0x08,0x3E,0x21,0x5F,0xA4,0x34,0x70,0x99,0x18,0x3E,0x0B,0xDF,0x61,0x69,0x77,0x92,0xCF,0xA6, +0xE4,0x0E,0xBC,0x79,0x4A,0x28,0xE1,0x58,0xEB,0x67,0xCB,0x1F,0x4B,0x32,0x37,0xF8,0x7E,0x9A,0xA2,0x18, +0x67,0xDA,0xDF,0x24,0xB3,0x98,0xA6,0x2C,0x5E,0xD4,0x11,0x90,0xB3,0xC6,0x64,0xB9,0xFC,0x2A,0x4F,0x22, +0x86,0x40,0xCC,0x35,0x61,0x43,0x05,0xD3,0x54,0xB8,0x55,0x15,0x54,0x4B,0x37,0xDB,0x02,0xB7,0x6C,0xB9, +0xF5,0xD6,0x76,0xED,0xBA,0x5D,0xB9,0x57,0x04,0xFB,0xA6,0xEA,0x1B,0xF1,0xA0,0x11,0xEB,0xBE,0xE2,0xA0, +0xD2,0xF5,0x87,0xAB,0x43,0x54,0x64,0xA8,0x19,0x50,0x51,0xBA,0xBF,0xE3,0x34,0x42,0x05,0xEC,0x5B,0x7E, +0x85,0x65,0x9A,0xB7,0xBE,0x4A,0x52,0xB0,0x06,0x9E,0x7F,0x81,0x66,0x25,0x53,0x9B,0x36,0xD0,0xAC,0xD2, +0x9D,0x12,0xA1,0xCE,0x79,0x92,0xD7,0x8A,0xF4,0x43,0xA9,0x00,0x5C,0x71,0xF3,0x54,0x70,0xF3,0x45,0xAD, +0x3E,0xD9,0xF9,0xA6,0xE0,0x61,0xDB,0xF9,0x66,0x69,0xAB,0xBD,0x55,0x3E,0xEE,0x3B,0xF0,0x5F,0x99,0x76, +0x9F,0xD5,0x2C,0x4C,0x9E,0x8A,0x3F,0x25,0x83,0x40,0xA7,0x09,0x7C,0xB2,0xFD,0xC3,0xB3,0x60,0x52,0x02, +0x95,0x60,0x8F,0xC3,0x53,0x14,0x90,0x3C,0x73,0x9F,0x3A,0xDF,0x28,0x7D,0x82,0xF9,0x40,0xF6,0xD2,0xB8, +0x6A,0x52,0xDF,0xD8,0x2C,0x21,0x54,0xDB,0xCA,0x34,0x61,0x6F,0x94,0x56,0x17,0xB3,0x99,0xEA,0xC1,0x45, +0xEA,0xAB,0x29,0xF6,0x2F,0x9C,0x6F,0x16,0x3C,0x45,0x34,0x9B,0xB2,0x34,0x76,0x53,0xC6,0x11,0xC7,0x86, +0x63,0x2E,0xFB,0xCE,0x3A,0xC0,0x93,0x1D,0x27,0xC0,0x33,0x73,0xB9,0xDC,0xED,0xC9,0xA4,0x06,0x15,0x8F, +0x9F,0x92,0x84,0xEF,0x4D,0x73,0xEA,0x0B,0x1E,0xB4,0x19,0x36,0xB0,0xB9,0x48,0x31,0xCF,0x53,0xAA,0x05, +0xCC,0xCF,0xC5,0x65,0xB7,0x67,0x98,0x1F,0xA9,0x7B,0x7F,0x70,0xFF,0x32,0x80,0x1D,0xCB,0x0A,0xC1,0x5F, +0x8B,0x00,0x0E,0x0C,0xE7,0x15,0x38,0xAD,0xFD,0x90,0x60,0x80,0xC8,0x6B,0x7C,0x6F,0x60,0x8B,0x57,0x88, +0xD8,0x16,0xEB,0x86,0x51,0x6E,0x03,0x20,0x35,0x17,0xB7,0xA0,0x05,0xE4,0xE1,0x2B,0x7E,0x6D,0x11,0x8F, +0xC2,0xC7,0xA0,0xD8,0x4E,0xF6,0xD0,0x7E,0xB7,0xEF,0xA2,0x3D,0xB2,0xDF,0x07,0xFF,0x32,0x1B,0xF4,0xD5, +0xC9,0x3F,0x91,0x08,0x5F,0x14,0x2E,0x27,0x0E,0xAA,0xA9,0xF5,0x0C,0x72,0x16,0x82,0x22,0xCD,0xEF,0x8C, +0xD3,0x91,0x66,0x5C,0x7D,0xDF,0xFD,0xE1,0xFA,0x8F,0xFE,0x95,0xD3,0xED,0x5F,0x9B,0xBF,0x99,0x3D,0x62, +0x73,0x9C,0x71,0x83,0xA2,0x5B,0x32,0x43,0x9C,0xA5,0xB6,0xC8,0xB7,0xC3,0x19,0x48,0x61,0x0E,0xAA,0x33, +0x88,0x62,0x6F,0xCB,0x71,0x36,0x3C,0xBC,0x8F,0x22,0x0C,0xAC,0xEB,0x47,0xE7,0xE7,0xA7,0xE7,0x57,0x7A, +0x07,0x77,0xF4,0x6B,0x57,0xD3,0x3B,0xD4,0x74,0xB9,0x0D,0x45,0x67,0x8A,0xB3,0xF0,0x0C,0xF1,0xD0,0x08, +0xEC,0x5B,0x14,0xE5,0xA0,0x0B,0xC1,0x08,0xF3,0x40,0x71,0xFA,0x24,0xE7,0x9C,0x51,0xDD,0x1C,0x30,0x9B, +0x50,0x8A,0xD3,0xE3,0xF1,0xDB,0x37,0x9E,0x7E,0xAE,0x90,0xB4,0x37,0x24,0xE3,0xBA,0x25,0x2D,0x62,0xA3, +0x24,0xC1,0x34,0x38,0x0C,0x49,0x14,0x18,0xCC,0x1C,0x08,0x12,0xBE,0x24,0x21,0x8B,0x11,0xA0,0xE0,0xDB, +0xAA,0x6C,0x9D,0x82,0xE4,0xBA,0xE5,0xDB,0x71,0x1E,0x71,0x92,0x44,0xD8,0xDB,0xE8,0xC3,0x8C,0xA2,0x18, +0x60,0x22,0x15,0x0B,0x18,0x09,0x3C,0x5D,0x05,0x24,0x15,0xC6,0xD6,0x9E,0xE2,0xAB,0x53,0x82,0xD6,0x29, +0x41,0x13,0x37,0x01,0xA9,0x74,0x2B,0xB0,0xEB,0x7A,0x19,0x66,0xC5,0x51,0x25,0x2C,0xC0,0x53,0x04,0x9C, +0xBC,0x17,0x92,0x43,0xF9,0xBD,0xEE,0xA0,0x40,0x1D,0x94,0xB5,0x35,0x92,0x35,0x35,0xA2,0x4C,0xB9,0x0E, +0x39,0x53,0xC8,0x69,0x1B,0x39,0x6D,0x22,0x1F,0xCA,0x1B,0xB1,0x0E,0x39,0x55,0xC8,0x51,0x4B,0xC4,0x48, +0x8A,0xA8,0xA2,0x5C,0x57,0x68,0x13,0x04,0x02,0xEC,0xA8,0x29,0x26,0xCC,0xC0,0x29,0xD1,0x24,0xC2,0x81, +0xB7,0xE1,0xC0,0x4C,0x14,0xD6,0xDE,0x96,0xB3,0xE6,0x8C,0x48,0x9D,0x91,0xB7,0xCE,0xC8,0xE5,0x19,0x24, +0x01,0x25,0x42,0xEE,0xD0,0xAD,0x5C,0x6A,0xAD,0xBD,0xA2,0x8E,0xF3,0x43,0xEC,0xDF,0x4C,0x98,0x5C,0x91, +0x63,0x71,0xE2,0x06,0x92,0x34,0x13,0x49,0x53,0xB6,0x23,0x40,0x33,0xB1,0xC1,0xD3,0x3D,0x41,0xD9,0x4A, +0x9A,0xE2,0x6B,0xC3,0x88,0xDB,0xBA,0x44,0x88,0xDB,0x5A,0x8A,0x5B,0xDB,0x46,0xE8,0x16,0x6B,0xEB,0xB4, +0x14,0x9B,0x6B,0x16,0x93,0x75,0x8B,0xB9,0x69,0xA5,0x36,0xA3,0x7E,0x44,0xFC,0x1B,0xAF,0x76,0x65,0x73, +0x61,0x34,0x27,0x82,0x13,0xEE,0x51,0x3C,0xD7,0x7E,0x82,0xD0,0xF4,0x1C,0x71,0x34,0xE0,0x05,0x19,0xA3, +0xB8,0x37,0x18,0x08,0x41,0x47,0x0A,0x9E,0x98,0xD9,0x28,0x80,0xE5,0xB3,0x8B,0xB1,0x6E,0xE9,0x3D,0x61, +0x15,0x1D,0xBC,0x99,0x98,0x4B,0xB3,0xF2,0x27,0x8B,0xCA,0xC8,0x7E,0x91,0x46,0xF5,0x12,0x0C,0xCA,0x1B, +0xB7,0xB4,0xE2,0xB5,0x3C,0x91,0xA9,0x51,0xA9,0xB4,0x64,0x4A,0x74,0x87,0xE2,0x0C,0xA3,0xB0,0xBF,0x6E, +0x42,0xE8,0x53,0x97,0xD7,0x30,0x2D,0xD4,0x66,0x1A,0x55,0x4C,0xA7,0x68,0x5E,0x5E,0x12,0x75,0xFE,0x40, +0xB9,0xB8,0x03,0x19,0x98,0x66,0x5C,0xC3,0xDE,0xB6,0xF3,0xC3,0xCE,0x00,0xEC,0x63,0x28,0xC7,0x05,0xC0, +0x2E,0xB7,0x23,0x4C,0x67,0x3C,0x1C,0xF8,0x1D,0xAF,0xD0,0x4A,0xE0,0x71,0x3B,0xCB,0x27,0x19,0x4F,0x21, +0xBF,0x19,0xBE,0xE5,0x77,0xB0,0xD9,0x3E,0x46,0xEF,0x30,0x2B,0x30,0x2D,0xD6,0xE9,0x2C,0x57,0x14,0x74, +0x3A,0x6A,0x68,0x08,0x09,0x0D,0xE1,0x28,0xC3,0x1A,0xB5,0xF1,0x1D,0xF6,0x0F,0x59,0x1C,0x23,0x41,0x22, +0x03,0x23,0x17,0x13,0xDD,0x5C,0x5A,0x6C,0xAD,0x66,0x1E,0x09,0x5B,0x56,0xF6,0x98,0x1E,0x21,0x0C,0x7A, +0xBE,0x2D,0x7C,0x25,0x2B,0x84,0xFA,0xB2,0x95,0xCB,0x40,0xA4,0x50,0xAE,0x9C,0x6B,0xAB,0x32,0xDC,0x5A, +0xA9,0x6A,0xBB,0xCB,0x5B,0xD7,0x8A,0x3F,0x66,0x6D,0x69,0x01,0x6B,0xC7,0xB5,0x1A,0xAA,0x2F,0x97,0x96, +0x2F,0xF8,0x0F,0x11,0x9D,0xE1,0xBF,0x2F,0x40,0xCD,0xA3,0x74,0x51,0x8B,0x42,0x02,0xD9,0x77,0x7F,0xB1, +0x8D,0xAB,0x5F,0xED,0xEB,0x8E,0x69,0xEE,0x7F,0xDD,0x93,0x1A,0x36,0xB8,0x79,0xD5,0xBF,0xB6,0x10,0x80, +0xED,0xEF,0xCC,0x5F,0x6C,0x09,0x6E,0xC1,0x06,0xB7,0x8C,0x04,0x9A,0x38,0x49,0x78,0x36,0x9B,0x6A,0x68, +0x73,0xD3,0xE0,0x1E,0x6A,0x5D,0xD6,0x0E,0xEF,0xE8,0x36,0xE4,0x8E,0xE5,0x72,0x35,0xA3,0x8D,0x53,0x8C, +0x55,0xCA,0xAC,0x00,0x92,0x7B,0x90,0x79,0x35,0x58,0x55,0x52,0x63,0xAB,0x86,0xC2,0xA2,0x4C,0xF9,0x76, +0x51,0x4D,0x78,0xBA,0x28,0x27,0x20,0xAC,0xAC,0x2E,0xCB,0x36,0x0F,0xD6,0x1B,0xC1,0xE1,0xDB,0x5D,0x12, +0xCF,0xB4,0x2C,0xF5,0x3D,0x65,0x8A,0x7D,0xF1,0x8F,0xF7,0xAD,0x48,0x75,0x9B,0xBF,0xF9,0x13,0x4F,0xEF, +0x80,0x7D,0xB1,0x4D,0xD9,0xDC,0x30,0x3B,0xDF,0xEA,0x9A,0xA4,0xE8,0xE9,0x31,0xBA,0x2B,0x9A,0x7D,0x51, +0x8D,0x0C,0x34,0x98,0x57,0xDD,0xA9,0x5A,0x50,0x6D,0x36,0xCA,0x39,0x1B,0x68,0x65,0x95,0xA3,0xDA,0x4C, +0x5D,0xEB,0xED,0x7D,0x5B,0xEB,0x00,0x81,0xE8,0x48,0xD9,0x84,0xC8,0x20,0x96,0x8B,0x90,0x87,0x5B,0xD1, +0x87,0x14,0x6E,0xA7,0xA2,0x22,0x01,0x38,0x59,0x49,0x9B,0x56,0x60,0x20,0x73,0xDF,0x68,0x25,0xDB,0x5D, +0xD1,0x98,0xEC,0x9D,0xA9,0x8A,0x73,0xB7,0x27,0x67,0xFA,0x3A,0xC7,0x00,0xCD,0x53,0x40,0xB7,0xAA,0x1A, +0x67,0xC2,0x82,0xFB,0x46,0x65,0x94,0x1D,0xDC,0x1F,0x46,0x28,0xCB,0x4E,0x50,0x0C,0xE7,0xFB,0xB1,0x6E, +0x16,0x57,0x69,0xCF,0xD9,0xDC,0x6C,0x23,0xA5,0x38,0x86,0x46,0x48,0x71,0x85,0x21,0x94,0xB9,0x3E,0x10, +0xDE,0xDC,0x5C,0xC7,0x98,0x78,0x54,0xFB,0x12,0x57,0x14,0xDC,0xB5,0x0C,0x7F,0xFF,0x13,0x77,0x2A,0xC1, +0x3E,0xA6,0xD5,0x14,0x7C,0xF6,0x21,0xDB,0xCF,0xD9,0x9C,0x0A,0xAE,0x2A,0xD6,0xD3,0x35,0x0A,0xAD,0xF3, +0x42,0x75,0x93,0x83,0x02,0xAF,0x3B,0x4D,0xD5,0x45,0x6E,0x5C,0xBA,0x12,0x06,0xD7,0x0D,0x2F,0xCD,0xFF, +0x47,0x58,0x55,0x0F,0x3C,0x26,0x6B,0x64,0x5A,0xD1,0x1A,0x59,0x71,0x84,0x39,0xAE,0x24,0x8D,0xD6,0x4A, +0x9A,0xFD,0x3F,0xFC,0xD6,0x1E,0x42,0x54,0x99,0xDB,0xF4,0x91,0x80,0xDC,0xEA,0x90,0x2B,0xBC,0x36,0x05, +0xA8,0xF8,0x59,0x14,0x8D,0x59,0xB2,0xFF,0xC8,0xBA,0x5B,0xAD,0x17,0x83,0x92,0xCD,0x7A,0x8B,0xE5,0xAF, +0x25,0xFA,0x06,0x4F,0xF9,0xFE,0x63,0x80,0xC7,0xC9,0xD6,0x7B,0xAC,0xC0,0xC3,0x36,0x28,0x0F,0x56,0x7F, +0xEE,0xF8,0x56,0x56,0xCD,0x2E,0x3B,0x0C,0x6C,0xE1,0x97,0x4A,0xF2,0x84,0x92,0x2C,0xB2,0x36,0x74,0xD5, +0xEB,0xA2,0xB7,0xF4,0x82,0x8E,0x9E,0xDC,0xD5,0x6B,0x9C,0x25,0x5E,0xA6,0x96,0x90,0x41,0x2C,0xBE,0x62, +0x94,0x75,0x01,0x25,0xF5,0x88,0xCD,0xA6,0xD3,0x0C,0xF3,0x0F,0x22,0x98,0x59,0x51,0x35,0x3F,0x96,0xC1, +0x6C,0x00,0x53,0x1A,0xB3,0x3C,0xC3,0x2C,0xE7,0xED,0xB2,0xA7,0x12,0x66,0x37,0xF8,0xE3,0x8F,0x6A,0xB2, +0x17,0x74,0xD2,0x7A,0x7A,0xB9,0x9B,0x35,0x26,0x7B,0x59,0x27,0x82,0x50,0xF0,0x1F,0xDF,0x14,0xD2,0xBC, +0x29,0x4C,0xC4,0x52,0x8B,0xA9,0x9B,0x92,0xD5,0x77,0x3D,0x13,0x45,0x29,0x6A,0x78,0xBB,0xB8,0xD0,0xBA, +0x59,0xF6,0x5C,0x4D,0x2F,0x47,0x56,0xB6,0x1A,0x04,0xD6,0x17,0x07,0xBE,0x21,0xA8,0x82,0xD6,0xDF,0xB0, +0x39,0x4E,0x0F,0x51,0x86,0x0D,0xC8,0x99,0x55,0xC4,0x92,0x50,0xD3,0x0D,0xD6,0xEC,0x02,0x25,0x50,0x05, +0x2E,0x0A,0x0F,0x46,0x45,0xE9,0x0D,0xF2,0xE5,0xAD,0x13,0xB0,0x2D,0x5E,0x0B,0x40,0xEA,0xE7,0xAA,0xD3, +0x80,0x3A,0x0D,0x83,0xAD,0x59,0x72,0x96,0xB2,0x04,0xCD,0x64,0x67,0x0D,0x6B,0xC2,0x3D,0x4A,0x6A,0x8D, +0xD4,0x5A,0xD5,0xA3,0x32,0xAD,0x3F,0xCC,0xEA,0x58,0x66,0x6E,0xA8,0x10,0x56,0x93,0x37,0x37,0xB3,0x39, +0xE1,0x7E,0x28,0x7C,0xDB,0x07,0x86,0x75,0x0E,0x6D,0x81,0x2B,0x47,0x21,0x8F,0xEB,0x51,0x54,0x0C,0x3F, +0x65,0xC5,0xC0,0xCF,0xCA,0xD1,0x5D,0x03,0xC8,0x68,0x09,0x66,0x74,0x5A,0x0C,0x09,0x25,0x25,0x9D,0x12, +0x58,0x7E,0x26,0x49,0x31,0x4A,0xC2,0x72,0x14,0xE2,0xBB,0x0A,0x8F,0x95,0xD0,0x00,0xEB,0xAE,0x32,0xDF, +0x86,0xB3,0x2C,0x06,0xFD,0x5A,0xFC,0xE0,0xBF,0x13,0x3F,0xA1,0xB3,0x52,0x98,0xA4,0x1C,0xCD,0x48,0x29, +0xCA,0x24,0x4E,0xBE,0xC8,0x48,0xF6,0x6F,0xFB,0x82,0xE7,0x47,0x6F,0x8E,0xC6,0x47,0xCD,0x12,0xB1,0xF9, +0x84,0xC0,0xFF,0xAA,0x47,0xE7,0xA6,0x6B,0x24,0x4D,0x4F,0x81,0x99,0x2F,0x3E,0x4F,0x58,0x20,0x8B,0x3E, +0x08,0xF8,0x46,0x02,0xD4,0x75,0xD3,0x6C,0xBD,0x32,0xA4,0xAD,0xD7,0x8B,0x3A,0xD0,0x17,0xCF,0x02,0xA0, +0xA7,0xCD,0xCD,0x06,0x23,0x72,0xBD,0x7E,0xF9,0xA0,0x96,0xAE,0xEA,0x34,0xE9,0x6C,0xE8,0xB1,0x82,0x06, +0x99,0x55,0xCB,0x40,0x3C,0x5A,0x38,0xBA,0x25,0xBA,0x07,0xB2,0xE7,0x43,0xDB,0xD0,0x31,0x55,0xB7,0xEF, +0x79,0x1E,0xBD,0xF2,0xAF,0x65,0xC7,0xB8,0xB9,0x89,0xDA,0x45,0x8F,0xE1,0x58,0x12,0x28,0x0E,0x94,0x23, +0xD9,0xAB,0x82,0x2C,0xC0,0x96,0x63,0xBD,0x1A,0x9D,0x9E,0xD8,0x09,0x4A,0xC1,0xE3,0xA8,0xD9,0x0C,0x12, +0x91,0x12,0xB0,0xAD,0xED,0x17,0x47,0x8D,0x6A,0x5C,0x7E,0x29,0xE4,0xF2,0xA5,0x95,0x1A,0x82,0x9C,0x6A, +0x72,0x45,0x0E,0x2F,0x5E,0xEF,0x20,0xF5,0x24,0x65,0x1A,0xAA,0xA3,0x48,0xD2,0x0C,0xE2,0xFC,0x36,0xD7, +0xD7,0xF7,0x96,0x3C,0x24,0x59,0xB3,0x0B,0x69,0xB9,0xFC,0xDF,0xB4,0xD8,0xB2,0x1C,0x29,0x72,0xAB,0x05, +0xB5,0xFA,0xBA,0x52,0x19,0x47,0x36,0x4C,0x75,0x61,0xCD,0xEA,0xEB,0xA8,0x43,0x66,0x21,0x54,0xB7,0xE8, +0x3F,0xF5,0x10,0x5A,0x7A,0x08,0x7D,0x18,0x20,0xF0,0x5D,0xCB,0xDB,0xAB,0x53,0x06,0x13,0xE0,0xEC,0x66, +0x50,0x45,0x11,0x80,0xC8,0x18,0xD2,0x02,0x7C,0xCA,0xE4,0xFA,0x27,0x74,0x8B,0xD4,0xE3,0x5D,0x0D,0x5D, +0x1F,0x2A,0xE4,0x76,0xFF,0x37,0x18,0x55,0x3B,0xDB,0x81,0x28,0x83,0xE1,0xC3,0x78,0xC2,0x5B,0xE1,0xA9, +0x8E,0x59,0xCD,0xE8,0x04,0xEE,0xBA,0x2C,0x0C,0xCB,0x1B,0xFA,0x6D,0xBA,0xDE,0xE6,0xE6,0xA3,0xBE,0xD7, +0x08,0x44,0x0A,0xA3,0x79,0x7B,0xD6,0xB7,0x2B,0xED,0x86,0x66,0x7D,0xFA,0x97,0xFE,0x87,0xF7,0x33,0x3B, +0x2B,0x5B,0x77,0x70,0xF3,0xC6,0x4C,0xD7,0x45,0xB6,0xF2,0x23,0x8C,0xD2,0x91,0xE8,0x12,0x55,0x86,0x58, +0x2A,0x03,0x7A,0xD2,0x75,0x0D,0xD0,0x58,0x4F,0xBE,0x12,0xDB,0x42,0x0F,0x80,0x50,0x41,0x29,0x40,0xA9, +0xC7,0x80,0x66,0x63,0x11,0xC1,0x22,0x82,0x86,0x87,0x51,0x76,0x83,0x48,0x73,0x3B,0x01,0x08,0x29,0xBE, +0x4C,0x86,0xBE,0xCE,0x2A,0x0C,0x21,0x09,0xD5,0x10,0x65,0x7E,0xB3,0x78,0x08,0xAB,0x9F,0x21,0x70,0xE9, +0x37,0xC5,0x05,0xD9,0x90,0x68,0x99,0x28,0x08,0x46,0x38,0xCB,0x24,0xE3,0x42,0xB0,0xB7,0x2C,0x00,0xB9, +0x00,0xAD,0x17,0xC3,0x48,0x1C,0x04,0x22,0x0A,0xC0,0x38,0xC4,0x71,0x01,0xE1,0x30,0x14,0x20,0x24,0x40, +0x5F,0x4B,0x5D,0x8D,0x64,0xE1,0x45,0xE8,0xCC,0xEB,0xF7,0x1C,0xEB,0x21,0xD9,0x8B,0x0C,0x8F,0xD8,0x94, +0x8F,0xD1,0x24,0x33,0x36,0x1C,0x73,0xCD,0x0E,0x00,0x8D,0x20,0x9C,0x18,0x5B,0xE6,0x7A,0xF4,0x0F,0x2C, +0xBD,0xC1,0xA9,0xB1,0xD1,0x2F,0xF8,0x39,0x86,0x82,0x29,0x82,0xBF,0x7C,0x08,0x6A,0xBF,0xC5,0x6F,0x08, +0xC5,0x05,0xE5,0x0C,0x90,0x43,0x36,0x3F,0x4B,0x09,0xE5,0x6F,0x65,0x5F,0x58,0x60,0xF9,0xEA,0xB9,0x42, +0x86,0xA0,0xF2,0x1D,0x63,0x21,0xA2,0x99,0xDB,0x7A,0xCD,0xB0,0x26,0x60,0x2F,0x08,0xAE,0xEE,0x62,0x4E, +0xA8,0xAB,0x1F,0xF2,0x34,0xEA,0x8E,0x74,0x2B,0x46,0x3E,0x4C,0xD4,0x1E,0x98,0x2F,0x2D,0xE1,0xB5,0x6E, +0x33,0x9A,0x6C,0xD4,0x93,0xBA,0x80,0x5E,0xFB,0xD4,0x53,0xBF,0x5C,0x08,0xE0,0x41,0xC4,0x26,0x86,0x78, +0x9A,0x5E,0x08,0x8F,0x77,0xE9,0xD2,0x14,0xE9,0xE9,0xCB,0xAF,0x32,0x3E,0x84,0x5D,0x6E,0xE1,0xC6,0xA3, +0x52,0x47,0xD7,0xC5,0x5B,0x0D,0xE0,0xA1,0xE0,0x94,0x46,0xF7,0x2E,0xA4,0xC5,0xBF,0x90,0x3A,0xA7,0x01, +0xFB,0x92,0xD4,0x1F,0x57,0xA4,0xFE,0xB8,0x4E,0x6A,0xDC,0xB6,0x16,0x4C,0x2E,0x80,0xEC,0x5B,0x44,0xD1, +0x0C,0xA7,0xB0,0x20,0x0E,0x01,0x03,0xFC,0x33,0xCE,0x52,0xFC,0x65,0xCE,0x46,0x21,0x99,0xF2,0x55,0xFE, +0xD4,0xEA,0xBF,0xE3,0x32,0xC5,0x8F,0x70,0x59,0x16,0x98,0x55,0xDE,0xF8,0xEB,0xA7,0x12,0xE9,0xD4,0x1E, +0x98,0xB0,0xE9,0xAE,0xFF,0xC2,0xEF,0xEA,0x13,0xBF,0x9C,0x3E,0xC5,0x87,0x8B,0x97,0x56,0x20,0xEE,0x44, +0xBB,0x2C,0x65,0xF4,0x00,0x2A,0xF8,0x37,0x20,0x82,0xA1,0xAE,0x23,0xF6,0x16,0x4B,0x8B,0x7B,0x06,0xA8, +0x12,0xBA,0x60,0x10,0xCE,0x97,0x75,0xAD,0x1D,0x42,0x8A,0x04,0x25,0x00,0x93,0x90,0x68,0x7B,0x57,0xFB, +0x9B,0xD7,0x1D,0xC8,0x50,0x1E,0x7C,0x98,0x1E,0x0C,0x36,0xAF,0xBF,0x33,0x7B,0x33,0xD2,0xA8,0x89,0x64, +0xAE,0x03,0xBD,0x5E,0xD1,0x6B,0x0F,0x2D,0x21,0x84,0x35,0x73,0x61,0x15,0x59,0x2D,0x2C,0x5F,0xBD,0xE0, +0x23,0x42,0x74,0x06,0x1F,0x32,0x76,0x40,0x78,0x5A,0xF3,0xE5,0x8A,0x9E,0xAB,0x11,0x60,0x35,0x1E,0xAA, +0x74,0x0E,0xFF,0xEA,0xA2,0xBD,0xE2,0x8D,0x60,0xA8,0xC8,0x42,0xDC,0x53,0x83,0x66,0x8C,0x15,0x49,0xBA, +0x34,0x5A,0x01,0x36,0x97,0x7A,0x0E,0xE0,0x29,0xA1,0x38,0xD0,0xAB,0xBC,0xFA,0xF3,0xDB,0x37,0xC7,0x9C, +0x27,0xE7,0x4A,0xB3,0x40,0xAB,0xBD,0x50,0x1B,0xDC,0x5C,0xF0,0xF4,0xBE,0xAC,0xD0,0x84,0xC3,0xAA,0x90, +0xF3,0xF3,0xE9,0xE4,0x13,0xF6,0x21,0x1F,0xBD,0xCD,0x20,0x99,0x6D,0xD9,0x02,0x7D,0x3C,0x3E,0xB3,0x77, +0x6C,0x07,0x4A,0x06,0xD0,0xAB,0x1F,0x0A,0xCB,0x2D,0xFF,0x11,0xF2,0x93,0x7F,0x86,0x4C,0x20,0xEE,0x66, +0x10,0x58,0x4B,0xFC,0x36,0x6E,0x98,0xB2,0xB9,0x44,0x3B,0x4A,0x53,0x61,0x94,0x71,0x48,0x32,0x6D,0x02, +0x8B,0x19,0x4E,0xB5,0x80,0xE1,0x4C,0xA3,0x8C,0x6B,0x59,0x9E,0x24,0x2C,0xE5,0x2B,0xFA,0xB0,0xF5,0xF2, +0xC1,0xE6,0x5D,0x8E,0x73,0x1C,0x14,0xCB,0x38,0x6D,0xEA,0x45,0x16,0x57,0xBF,0x0B,0xB8,0x77,0x75,0x5D, +0x94,0x5A,0x39,0xA5,0x22,0x0F,0x6C,0xF4,0xD5,0x1C,0xA4,0x0B,0x81,0xAA,0x47,0xF3,0x28,0x5A,0x0E,0x56, +0x68,0x41,0xC7,0xC5,0x38,0x13,0xF6,0xF0,0x16,0xBF,0x15,0x57,0xDC,0x5D,0x79,0x51,0x6D,0x53,0x75,0xAC, +0x0D,0x63,0x03,0x6B,0x84,0x66,0x1C,0x51,0x5F,0x98,0x51,0xE9,0xC2,0x2C,0xCB,0x2C,0xB1,0x7D,0x20,0xFC, +0x53,0xDE,0xA5,0x47,0x73,0xBB,0x94,0x8C,0x7A,0xBA,0x2E,0x2A,0x2E,0x2C,0x0A,0x57,0x14,0x67,0x0D,0xB2, +0x55,0xC4,0x36,0xA9,0x57,0x82,0x07,0xF2,0x1D,0xBC,0xBD,0x7F,0x95,0x8D,0xB2,0xCC,0x46,0x00,0xD3,0xCA, +0x7D,0x26,0xED,0x78,0xBA,0xCC,0xD4,0xFB,0xD2,0x75,0xE5,0x05,0x8E,0x31,0x0F,0x59,0xB0,0xAF,0xEF,0xEB, +0xAE,0x0E,0xFF,0x6F,0xEA,0x16,0xEC,0xC2,0xD4,0x07,0xF7,0xBF,0x38,0x7F,0x09,0x21,0x2D,0x61,0x14,0x53, +0x6E,0x20,0x88,0xEC,0x9E,0xDE,0x59,0x03,0x29,0xC9,0x5F,0xA1,0x6B,0x73,0xD0,0x56,0x36,0x9E,0xAF,0x98, +0xB3,0x65,0x0C,0x9B,0x51,0x11,0xE5,0xEE,0x81,0x79,0x8E,0x1F,0xBC,0x63,0x5B,0xF4,0x61,0x3B,0x62,0x2E, +0xB6,0x05,0xCF,0x12,0x6B,0x04,0x58,0xC2,0xF5,0x6A,0x25,0x3F,0x56,0x62,0x51,0xDB,0x47,0x51,0x24,0xBE, +0x7B,0x07,0x5E,0xC5,0x61,0x79,0x66,0x09,0x22,0x19,0x08,0x90,0xE1,0x31,0xBE,0x03,0x97,0x96,0x75,0x92, +0xBA,0x43,0x45,0x5F,0x02,0xA4,0x79,0xE3,0x1A,0x99,0x56,0x35,0xDB,0xDC,0xE4,0x76,0x79,0x4D,0x8C,0x12, +0x29,0x13,0x41,0xDF,0x30,0x45,0xCF,0x61,0x34,0x85,0x14,0x39,0xF4,0x81,0xB6,0x8D,0xB6,0x1A,0x12,0x4C, +0x8D,0x12,0x06,0x9C,0xE5,0x69,0x04,0x91,0x5A,0x54,0x11,0xAD,0x6D,0x19,0xA6,0x01,0x1C,0xE0,0xFE,0x25, +0xB2,0x44,0xA5,0xCD,0x5B,0x31,0xE2,0xA9,0xE2,0xBB,0x4D,0x8F,0x17,0x56,0x39,0xC6,0x32,0xF2,0xB5,0x7F, +0x2C,0x69,0xC9,0x9F,0x39,0x12,0x15,0x98,0x7B,0xF0,0xF0,0x3D,0x9F,0x77,0xC5,0x57,0xEF,0x5D,0x38,0x41, +0xDD,0x82,0x40,0x5F,0xC3,0xA1,0x6A,0xBB,0x2C,0xF1,0x60,0xE1,0xAE,0xB8,0x68,0xAD,0x3F,0x63,0xC5,0x47, +0xDB,0x74,0xDA,0x7C,0x36,0xAC,0xBD,0xBB,0xBD,0x02,0x42,0x13,0x96,0x72,0x03,0x72,0x0D,0xA4,0xA3,0xEA, +0xB4,0xB2,0x03,0x6A,0xC6,0x05,0x3B,0xC9,0xB3,0xD0,0x58,0x00,0xEB,0x2E,0xB7,0x94,0xAE,0x5C,0x6C,0xA9, +0x7B,0xEB,0x52,0xAB,0xBC,0x1F,0x2E,0xA4,0x90,0x56,0xFC,0xF8,0xE3,0x0F,0x39,0xAB,0xAD,0x0D,0xB3,0x15, +0x83,0x2F,0xD5,0x1B,0x6B,0x99,0x19,0xC5,0xA5,0x5F,0x8D,0x55,0xBB,0x3D,0xD5,0xD8,0x94,0xBF,0x4E,0xD0, +0x48,0xE0,0x89,0x24,0xAB,0x17,0x5F,0x41,0xC0,0x70,0x0A,0x71,0xC9,0x86,0x4E,0xA8,0xFA,0x39,0xAA,0x5E, +0xFC,0x1E,0x75,0x15,0x77,0xAF,0x6A,0xCD,0x3C,0xAF,0xAA,0xAB,0x55,0xD4,0x51,0x1B,0xBC,0x47,0x7E,0xB3, +0xA0,0x2B,0x30,0x74,0xAE,0x6A,0x60,0x57,0x67,0x8B,0x73,0xAD,0x62,0x11,0x65,0xF7,0xD4,0x17,0x51,0xB3, +0xA2,0x12,0x82,0xFA,0x5B,0xDD,0xAC,0xDA,0x69,0x2E,0x6B,0xCE,0xC4,0xF3,0x9C,0xC6,0x8A,0xB7,0xEC,0x66, +0xAE,0x07,0xF6,0xA1,0x59,0x16,0xE2,0x96,0x2E,0xAA,0xC9,0x6E,0xB9,0x9A,0x82,0x78,0xB0,0xA1,0xDE,0x95, +0x27,0xEB,0x01,0x2A,0xFD,0xAE,0x2E,0xAA,0xEC,0xBE,0xBA,0x5C,0x76,0x5C,0xD5,0xD7,0x36,0x8D,0x9F,0x9B, +0xD4,0x34,0x88,0x7C,0x90,0x97,0xFB,0xDB,0x6F,0xF4,0x8F,0xA2,0x29,0x8C,0xBD,0x3F,0x01,0x2C,0xED,0xAE, +0xEF,0x83,0x2C,0x00,0x00 }; From 7dbe1150dc2895eb48a634e1422d4c1c59579016 Mon Sep 17 00:00:00 2001 From: lorol Date: Mon, 4 May 2020 13:04:18 -0400 Subject: [PATCH 053/551] Added ext-searchbox (Ctrl+F) search/replace functionality and -workers (live syntax checkers) to the ace editor - a standalone hack. if you don't need worker(s), modify line #446 of edit.htm .setUseWorker(!0) to (!1) (true to false) repack by do.bat and modify update_ace.bat Changes of src/WebAuthentication.cpp and minor updates of my SmartSwitch example --- examples/SmartSwitch/SmartSwitch.ino | 1057 ++++++++--------- examples/SmartSwitch/data/acefull.js.gz | Bin 116948 -> 119986 bytes examples/SmartSwitch/data/worker-css.js.gz | Bin 0 -> 35483 bytes examples/SmartSwitch/data/worker-html.js.gz | Bin 0 -> 47406 bytes .../SmartSwitch/data/worker-javascript.js.gz | Bin 0 -> 47729 bytes extras/update_ace.bat | 19 +- src/WebAuthentication.cpp | 6 + src/edit.htm | 10 +- src/edit.htm.gz.h | 442 +++---- 9 files changed, 781 insertions(+), 753 deletions(-) create mode 100644 examples/SmartSwitch/data/worker-css.js.gz create mode 100644 examples/SmartSwitch/data/worker-html.js.gz create mode 100644 examples/SmartSwitch/data/worker-javascript.js.gz diff --git a/examples/SmartSwitch/SmartSwitch.ino b/examples/SmartSwitch/SmartSwitch.ino index 3dbc61b8e..0307cd29a 100644 --- a/examples/SmartSwitch/SmartSwitch.ino +++ b/examples/SmartSwitch/SmartSwitch.ino @@ -1,529 +1,528 @@ -/* -SmartSwitch application -Based on ESP_AsyncFSBrowser -Temperature Control for heater with schedule -Main purpose - for winter outside car block heater or battery charger -Wide browser compatibility, no other server-side needed. -HTTP server and WebSocket, single port -Standalone, no JS dependencies for the browser from Internet (I hope) -Based on ESP_AsyncFSBrowser -Real Time (NTP) w/ Time Zones -Memorized settings to EEPROM -Multiple clients can be connected at same time, they see each other requests -Use latest ESP core lib (from Github) -*/ - -#define USE_WFM // to use ESPAsyncWiFiManager -//#define DEL_WFM // delete Wifi credentials stored - //(use once then comment and flash again), also HTTP /erase-wifi can do the same live - -#define USE_AUTH // .setAuthentication for all static - -#include -#ifdef ESP32 - #include - #include - #include - #include - #include -#elif defined(ESP8266) - #include - #include - #include -#endif -#include -#ifdef USE_WFM - #include "ESPAsyncWiFiManager.h" -#endif -#include -#include -#include -#include - -#define RTC_UTC_TEST 1577836800 // Some Date -#ifdef ESP32 - #define MYTZ -5*3600,3600 -#elif defined(ESP8266) - #include - #define MYTZ TZ_America_Toronto -#endif - -#define EESC 100 // fixed eeprom address for sched choice -#define EECH 104 // fixed eeprom address to keep selected active channel, only for reference here -#define EEBEGIN EECH + 1 -#define EEMARK 0x5A -#define MEMMAX 2 // 0,1,2... last max index (only 3 channels) -#define EEALL 512 - -#define HYST 0.5 // C +/- hysteresis - -// DHT -#define DHTTYPE DHT22 // DHT 11 // DHT 22, AM2302, AM2321 // DHT 21, AM2301 -#define DHTPIN 4 //D2 - -DHT dht(DHTPIN, DHTTYPE); - -// SKETCH BEGIN MAIN DECLARATIONS -Ticker tim; -AsyncWebServer server(80); //single port - easy for forwarding -AsyncWebSocket ws("/ws"); - -#ifdef USE_WFM - #ifdef USE_EADNS - AsyncDNSServer dns; - #else - DNSServer dns; - #endif - -//Fallback timeout in seconds allowed to config or it creates an own AP, then serves 192.168.4.1 - #define FBTO 120 - const char* fbssid = "FBSSW"; - const char* fbpassword = "FBpassword4"; - -#else - const char* ssid = "MYROUTERSSD"; - const char* password = "MYROUTERPASSWD"; -#endif -const char* hostName = "smartsw"; -const char* http_username = "smart"; // for SPIFFSEditor (and static html) -const char* http_password = "switch"; - -// RTC -static timeval tv; -static time_t now; - -// HW I/O -const int btnPin = 0; //D3 -const int ledPin = 2; //D4 -int btnState = HIGH; - -// Globals -uint8_t count = 0; -uint8_t sched = 0; // automatic schedule -byte memch = 0; // select memory "channel" to work with -float t = 0; -float h = 0; -bool udht = false; -bool heat_enabled_prev = false; -int ledState; - -struct EE_bl { - byte memid; //here goes the EEMARK stamp - uint8_t hstart; - uint8_t mstart; - uint8_t hstop; - uint8_t mstop; - float tempe; -}; - -EE_bl ee = {0,0,0,0,0,0.1}; //populate as initial - -// SUBS -void writeEE() { - ee.memid = EEMARK; - //EEPROM.put(EESC, sched); // only separately when needed with commit() - //EEPROM.put(EECH, memch); // not need to store and retrieve memch - EEPROM.put(EEBEGIN + memch*sizeof(ee), ee); - EEPROM.commit(); //needed for ESP8266? -} - -void readEE() { - byte ChkEE; - if (memch > MEMMAX) memch = 0; - EEPROM.get(EEBEGIN + memch*sizeof(ee), ChkEE); - if (ChkEE == EEMARK){ //otherwise stays with defaults - EEPROM.get(EEBEGIN + memch*sizeof(ee), ee); - EEPROM.get(EESC, sched); - if (sched > MEMMAX + 1) sched = 0; - } -} - -void showTime() -{ - byte tmpch = 0; - bool heat_enabled = false; - - gettimeofday(&tv, nullptr); - now = time(nullptr); - const tm* tm = localtime(&now); - ws.printfAll("Now,Clock,%02d:%02d,%d", tm->tm_hour, tm->tm_min, tm->tm_wday); - if ((2==tm->tm_hour )&&(2==tm->tm_min)) { - configTime(MYTZ, "pool.ntp.org"); - Serial.print(F("Sync Clock at 02:02\n")); - } - Serial.printf("RTC: %02d:%02d\n", tm->tm_hour, tm->tm_min); - - if (sched == 0) { // automatic - if ((tm->tm_wday > 0)&&(tm->tm_wday < 6)) tmpch = 0; //Mon - Fri - else if (tm->tm_wday == 6) tmpch = 1; //Sat - else if (tm->tm_wday == 0) tmpch = 2; //Sun - } else { // manual - tmpch = sched - 1; //and stays - } - - if (tmpch != memch) { // update if different - memch = tmpch; - readEE(); - ws.printfAll("Now,Setting,%02d:%02d,%02d:%02d,%+2.1f", ee.hstart, ee.mstart, ee.hstop, ee.mstop, ee.tempe); - } - - // process smart switch by time and temperature - uint16_t xmi = (uint16_t)(60*tm->tm_hour) + tm->tm_min; // max 24h = 1440min, current time - uint16_t bmi = (uint16_t)(60*ee.hstart) + ee.mstart; // begin in minutes - uint16_t emi = (uint16_t)(60*ee.hstop) + ee.mstop; // end in minutes - - if (bmi == emi) heat_enabled = false; - else { //enable smart if different - - if (((bmi < emi)&&(bmi <= xmi)&&(xmi < emi))|| - ((emi < bmi)&&((bmi <= xmi)||(xmi < emi)))) { - heat_enabled = true; - } else heat_enabled = false; - } - - if (heat_enabled_prev) { // smart control (delayed one cycle) - if (((t - HYST) < ee.tempe)&&(ledState == HIGH)) { // OFF->ON once - ledState = LOW; - digitalWrite(ledPin, ledState); // apply change - ws.textAll("led,ledon"); - } - if ((((t + HYST) > ee.tempe)&&(ledState == LOW))||(!heat_enabled)) { // ON->OFF once, also turn off at end of period. - ledState = HIGH; - digitalWrite(ledPin, ledState); // apply change - ws.textAll("led,ledoff"); - } - Serial.printf(ledState ? "LED OFF" : "LED ON"); - Serial.print(F(", Smart enabled\n")); - } - heat_enabled_prev = heat_enabled; //update -} - -void updateDHT(){ - h = dht.readHumidity(); - t = dht.readTemperature(); //Celsius or dht.readTemperature(true) for Fahrenheit - if (isnan(h) || isnan(t)) { - Serial.print(F("Failed to read from DHT sensor!")); - h = 0; // debug w/o sensor - t = 0; - } -} - -void analogSample() -{ - ws.printfAll("wpMeter,Arduino,%+2.1f,%2.1f,%d", t, h, heat_enabled_prev); - Serial.printf("T/H.: %+2.1f°C/%2.1f%%,%d\n", t, h, heat_enabled_prev); -} - -void checkPhysicalButton() -{ - if (digitalRead(btnPin) == LOW) { - if (btnState != LOW) { // btnState is used to avoid sequential toggles - ledState = !ledState; - digitalWrite(ledPin, ledState); - if (ledState) ws.textAll("led,ledoff"); - else ws.textAll("led,ledon"); - } - btnState = LOW; - } else { - btnState = HIGH; - } -} - -void mytimer() { - ++count; //200ms increments - checkPhysicalButton(); - if ((count % 25) == 1) { // update temp every 5 seconds - analogSample(); - udht = true; - } - if ((count % 50) == 0) { // update temp every 10 seconds - ws.cleanupClients(); - } - if (count >= 150) { // cycle every 30 sec - showTime(); - count = 0; - } -} - -// server -void onWsEvent(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventType type, void * arg, uint8_t *data, size_t len){ - if(type == WS_EVT_CONNECT){ - Serial.printf("ws[%s][%u] connect\n", server->url(), client->id()); - //client->printf("Hello Client %u :)", client->id()); - //client->ping(); - - IPAddress ip = client->remoteIP(); - Serial.printf("[%u] Connected from %d.%d.%d.%d\n", client->id(), ip[0], ip[1], ip[2], ip[3]); - showTime(); - analogSample(); - if (ledState) ws.textAll("led,ledoff"); - else ws.textAll("led,ledon"); - - ws.printfAll("Now,Setting,%02d:%02d,%02d:%02d,%+2.1f", ee.hstart, ee.mstart, ee.hstop, ee.mstop, ee.tempe); - ws.printfAll("Now,sched,%d", sched); - - } else if(type == WS_EVT_DISCONNECT){ - Serial.printf("ws[%s][%u] disconnect\n", server->url(), client->id()); - ws.textAll("Now,remoff"); - - } else if(type == WS_EVT_ERROR){ - Serial.printf("ws[%s][%u] error(%u): %s\n", server->url(), client->id(), *((uint16_t*)arg), (char*)data); - } else if(type == WS_EVT_PONG){ - Serial.printf("ws[%s][%u] pong[%u]: %s\n", server->url(), client->id(), len, (len)?(char*)data:""); - } else if(type == WS_EVT_DATA){ - AwsFrameInfo * info = (AwsFrameInfo*)arg; - String msg = ""; - if(info->final && info->index == 0 && info->len == len){ - //the whole message is in a single frame and we got all of it's data - Serial.printf("ws[%s][%u] %s-message[%llu]: ", server->url(), client->id(), (info->opcode == WS_TEXT)?"text":"binary", info->len); - - if(info->opcode == WS_TEXT){ - for(size_t i=0; i < info->len; i++) { //debug - msg += (char) data[i]; - } - if(data[0] == 'L') { // LED - if(data[1] == '1') { - ledState = LOW; - ws.textAll("led,ledon"); // for others - } - else if(data[1] == '0') { - ledState = HIGH; - ws.textAll("led,ledoff"); - } - digitalWrite(ledPin, ledState); // apply change - - - } else if(data[0] == 'T') { // timeset - if (len > 11) { - data[3] = data[6] = data[9] = data[12] = 0; // cut strings - ee.hstart = (uint8_t) atoi((const char *) &data[1]); - ee.mstart = (uint8_t) atoi((const char *) &data[4]); - ee.hstop = (uint8_t) atoi((const char *) &data[7]); - ee.mstop = (uint8_t) atoi((const char *) &data[10]); - Serial.printf("[%u] Timer set %02d:%02d - %02d:%02d\n", client->id(), ee.hstart, ee.mstart, ee.hstop, ee.mstop); - writeEE(); - memch = 255; // to force showTime()to send Setting - showTime(); - } - } else if(data[0] == 'W') { // temperatureset - if (len > 3) { - if (ee.tempe != (float) atof((const char *) &data[1])){ - ee.tempe = (float) atof((const char *) &data[1]); - Serial.printf("[%u] Temp set %+2.1f\n", client->id(), ee.tempe); - writeEE(); - memch = 255; // to force showTime()to send Setting - showTime(); - } - } - } else if ((data[0] == 'Z')&&(len > 2)) { // sched - data[2] = 0; - if (sched != (uint8_t) atoi((const char *) &data[1])){ - sched = (uint8_t) atoi((const char *) &data[1]); - EEPROM.put(EESC, sched); //separately - EEPROM.commit(); //needed for ESP8266? - ws.printfAll("Now,sched,%d", sched); - showTime(); - } - } - - } else { - char buff[3]; - for(size_t i=0; i < info->len; i++) { - sprintf(buff, "%02x ", (uint8_t) data[i]); - msg += buff ; - } - } - Serial.printf("%s\n",msg.c_str()); - - if(info->opcode == WS_TEXT) - client->text("I got your text message"); - else - client->binary("I got your binary message"); - - } else { - //message is comprised of multiple frames or the frame is split into multiple packets - if(info->index == 0){ - if(info->num == 0) - Serial.printf("ws[%s][%u] %s-message start\n", server->url(), client->id(), (info->message_opcode == WS_TEXT)?"text":"binary"); - Serial.printf("ws[%s][%u] frame[%u] start[%llu]\n", server->url(), client->id(), info->num, info->len); - } - - Serial.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 < len; i++) { - msg += (char) data[i]; - } - } else { - char buff[3]; - for(size_t i=0; i < len; i++) { - sprintf(buff, "%02x ", (uint8_t) data[i]); - msg += buff ; - } - } - Serial.printf("%s\n",msg.c_str()); - - if((info->index + len) == info->len){ - Serial.printf("ws[%s][%u] frame[%u] end[%llu]\n", server->url(), client->id(), info->num, info->len); - if(info->final){ - Serial.printf("ws[%s][%u] %s-message end\n", server->url(), client->id(), (info->message_opcode == WS_TEXT)?"text":"binary"); - if(info->message_opcode == WS_TEXT) - client->text("I got your text message"); - else - client->binary("I got your binary message"); - } - } - } - } -} - - -// setup ----------------------------------- - -void setup(){ - Serial.begin(115200); - Serial.setDebugOutput(true); - -//Wifi -#ifdef USE_WFM - AsyncWiFiManager wifiManager(&server,&dns); - #ifdef DEL_WFM - wifiManager.resetSettings(); - #endif - wifiManager.setTimeout(FBTO); // seconds to config or it creates an own AP, then browse 192.168.4.1 - if (!wifiManager.autoConnect(hostName)){ - Serial.print(F("*FALLBACK AP*\n")); - WiFi.mode(WIFI_AP); - WiFi.softAP(fbssid, fbpassword); - // MDNS.begin(fbssid); - // MDNS.addService("http","tcp",80); // Core SVN 5179 use STA as default interface in mDNS (#7042) - } - -#else -// Manual simple STA mode to connect to known router - //WiFi.mode(WIFI_AP_STA); // Core SVN 5179 use STA as default interface in mDNS (#7042) - //WiFi.softAP(hostName); // Core SVN 5179 use STA as default interface in mDNS (#7042) - WiFi.mode(WIFI_STA); // Core SVN 5179 use STA as default interface in mDNS (#7042) - WiFi.begin(ssid, password); - if (WiFi.waitForConnectResult() != WL_CONNECTED) { - Serial.print(F("STA: Failed!\n")); - WiFi.disconnect(false); - delay(1000); - WiFi.begin(ssid, password); - } -#endif - - Serial.print(F("*CONNECTED*\n")); - -//DHT - dht.begin(); - updateDHT(); //first reading takes time, hold here than the loop; - -//Real Time - time_t rtc = RTC_UTC_TEST; - timeval tv = { rtc, 0 }; - //timezone tz = { 0, 0 }; //(insert) <#5194 - settimeofday(&tv, nullptr); //settimeofday(&tv, &tz); // <#5194 - configTime(MYTZ, "pool.ntp.org"); - -//MDNS (not needed) - // MDNS.begin(hostName); - // MDNS.addService("http","tcp",80); // Core SVN 5179 use STA as default interface in mDNS (#7042) - -//I/O & DHT - pinMode(ledPin, OUTPUT); - pinMode(btnPin, INPUT_PULLUP); - -//EE - EEPROM.begin(EEALL); - //EEPROM.get(EECH, memch); //current channel, no need - readEE(); // populate structure if healthy - digitalWrite(ledPin, ledState); - Serial.printf("Timer set %02d:%02d - %02d:%02d\n", ee.hstart, ee.mstart, ee.hstop, ee.mstop); - Serial.printf("Temp set %+2.1f\n", ee.tempe); - -//SPIFFS - SPIFFS.begin(); - - ws.onEvent(onWsEvent); - server.addHandler(&ws); - -#ifdef ESP32 - server.addHandler(new SPIFFSEditor(SPIFFS, http_username,http_password)); -#elif defined(ESP8266) - server.addHandler(new SPIFFSEditor(http_username,http_password)); -#endif - - server.on("/free-ram", HTTP_GET, [](AsyncWebServerRequest *request){ // direct request->answer - request->send(200, "text/plain", String(ESP.getFreeHeap())); - }); - - - server.on("/get-time", HTTP_GET, [](AsyncWebServerRequest *request){ - if(request->hasParam("btime")){ - time_t rtc = (request->getParam("btime")->value()).toInt(); - timeval tv = { rtc, 0 }; - settimeofday(&tv, nullptr); - } - request->send(200, "text/plain","Got browser time ..."); - }); - - - server.on("/hw-reset", HTTP_GET, [](AsyncWebServerRequest *request){ - request->onDisconnect([]() { -#ifdef ESP32 - ESP.restart(); -#elif defined(ESP8266) - ESP.reset(); -#endif - }); - request->send(200, "text/plain","Restarting ..."); - }); - - server.on("/erase-wifi", HTTP_GET, [](AsyncWebServerRequest *request){ - request->onDisconnect([]() { - WiFi.disconnect(true); -#ifdef ESP32 - ESP.restart(); -#elif defined(ESP8266) - ESP.reset(); -#endif - }); - request->send(200, "text/plain","Erasing WiFi data ..."); - }); - -#ifdef USE_AUTH - server.serveStatic("/", SPIFFS, "/").setDefaultFile("index.htm").setAuthentication(http_username,http_password); -#else - server.serveStatic("/", SPIFFS, "/").setDefaultFile("index.htm"); -#endif - - server.onNotFound([](AsyncWebServerRequest *request){ // nothing known - Serial.print(F("NOT_FOUND: ")); - if (request->method() == HTTP_OPTIONS) request->send(200); //CORS - else request->send(404); - }); - - DefaultHeaders::Instance().addHeader("Access-Control-Allow-Origin", "*");//CORS - server.begin(); - - //Timer tick - tim.attach(0.2, mytimer); //every 0.2s - - //OTA - ArduinoOTA.setHostname(hostName); - ArduinoOTA.onStart([]() { - Serial.print(F("OTA Started ...\n")); - ws.textAll("Now,OTA"); // for all clients - }); - ArduinoOTA.begin(); -} // setup end - -// loop ----------------------------------- -void loop(){ - if (udht){ // 5sec - updateDHT(); - udht = false; - } - ArduinoOTA.handle(); -} +/* +SmartSwitch application +Based on ESP_AsyncFSBrowser +Temperature Control for heater with schedule +Main purpose - for winter outside car block heater or battery charger +Wide browser compatibility, no other server-side needed. +HTTP server and WebSocket, single port +Standalone, no JS dependencies for the browser from Internet (I hope) +Based on ESP_AsyncFSBrowser +Real Time (NTP) w/ Time Zones +Memorized settings to EEPROM +Multiple clients can be connected at same time, they see each other requests +Use latest ESP core lib (from Github) +*/ + +#define USE_WFM // to use ESPAsyncWiFiManager +//#define DEL_WFM // delete Wifi credentials stored + //(use once then comment and flash again), also HTTP /erase-wifi can do the same live + +#define USE_AUTH_STAT // .setAuthentication also for static (editor always requires auth) +//#define USE_AUTH_WS // .setAuthentication also for ws, broken for Safari iOS + +#include +#ifdef ESP32 + #include + #include + #include + #include + #include +#elif defined(ESP8266) + #include + #include + #include +#endif +#include +#ifdef USE_WFM + #include "ESPAsyncWiFiManager.h" +#endif +#include +#include +#include +#include + +#define RTC_UTC_TEST 1577836800 // Some Date +#define MYTZ PSTR("EST5EDT,M3.2.0,M11.1.0") + +#define EESC 100 // fixed eeprom address for sched choice +#define EECH 104 // fixed eeprom address to keep selected active channel, only for reference here +#define EEBEGIN EECH + 1 +#define EEMARK 0x5A +#define MEMMAX 2 // 0,1,2... last max index (only 3 channels) +#define EEALL 512 + +#define HYST 0.5 // C +/- hysteresis + +// DHT +#define DHTTYPE DHT22 // DHT 11 // DHT 22, AM2302, AM2321 // DHT 21, AM2301 +#define DHTPIN 4 //D2 + +DHT dht(DHTPIN, DHTTYPE); + +// SKETCH BEGIN MAIN DECLARATIONS +Ticker tim; +AsyncWebServer server(80); //single port - easy for forwarding +AsyncWebSocket ws("/ws"); + +#ifdef USE_WFM + #ifdef USE_EADNS + AsyncDNSServer dns; + #else + DNSServer dns; + #endif + +//Fallback timeout in seconds allowed to config or it creates an own AP, then serves 192.168.4.1 + #define FBTO 120 + const char* fbssid = "FBSSW"; + const char* fbpassword = "FBpassword4"; + +#else + const char* ssid = "MYROUTERSSD"; + const char* password = "MYROUTERPASSWD"; +#endif +const char* hostName = "smartsw"; +const char* http_username = "smart"; +const char* http_password = "switch"; + +// RTC +static timeval tv; +static time_t now; + +// HW I/O +const int btnPin = 0; //D3 +const int ledPin = 2; //D4 +int btnState = HIGH; + +// Globals +uint8_t count = 0; +uint8_t sched = 0; // automatic schedule +byte memch = 0; // select memory "channel" to work with +float t = 0; +float h = 0; +bool udht = false; +bool heat_enabled_prev = false; +int ledState; + +struct EE_bl { + byte memid; //here goes the EEMARK stamp + uint8_t hstart; + uint8_t mstart; + uint8_t hstop; + uint8_t mstop; + float tempe; +}; + +EE_bl ee = {0,0,0,0,0,0.1}; //populate as initial + +// SUBS +void writeEE() { + ee.memid = EEMARK; + //EEPROM.put(EESC, sched); // only separately when needed with commit() + //EEPROM.put(EECH, memch); // not need to store and retrieve memch + EEPROM.put(EEBEGIN + memch*sizeof(ee), ee); + EEPROM.commit(); //needed for ESP8266? +} + +void readEE() { + byte ChkEE; + if (memch > MEMMAX) memch = 0; + EEPROM.get(EEBEGIN + memch*sizeof(ee), ChkEE); + if (ChkEE == EEMARK){ //otherwise stays with defaults + EEPROM.get(EEBEGIN + memch*sizeof(ee), ee); + EEPROM.get(EESC, sched); + if (sched > MEMMAX + 1) sched = 0; + } +} + +void showTime() +{ + byte tmpch = 0; + bool heat_enabled = false; + + gettimeofday(&tv, nullptr); + now = time(nullptr); + const tm* tm = localtime(&now); + ws.printfAll("Now,Clock,%02d:%02d,%d", tm->tm_hour, tm->tm_min, tm->tm_wday); + if ((2==tm->tm_hour )&&(2==tm->tm_min)) { + configTzTime(MYTZ, "pool.ntp.org"); + Serial.print(F("Sync Clock at 02:02\n")); + } + Serial.printf("RTC: %02d:%02d\n", tm->tm_hour, tm->tm_min); + + if (sched == 0) { // automatic + if ((tm->tm_wday > 0)&&(tm->tm_wday < 6)) tmpch = 0; //Mon - Fri + else if (tm->tm_wday == 6) tmpch = 1; //Sat + else if (tm->tm_wday == 0) tmpch = 2; //Sun + } else { // manual + tmpch = sched - 1; //and stays + } + + if (tmpch != memch) { // update if different + memch = tmpch; + readEE(); + ws.printfAll("Now,Setting,%02d:%02d,%02d:%02d,%+2.1f", ee.hstart, ee.mstart, ee.hstop, ee.mstop, ee.tempe); + } + + // process smart switch by time and temperature + uint16_t xmi = (uint16_t)(60*tm->tm_hour) + tm->tm_min; // max 24h = 1440min, current time + uint16_t bmi = (uint16_t)(60*ee.hstart) + ee.mstart; // begin in minutes + uint16_t emi = (uint16_t)(60*ee.hstop) + ee.mstop; // end in minutes + + if (bmi == emi) heat_enabled = false; + else { //enable smart if different + + if (((bmi < emi)&&(bmi <= xmi)&&(xmi < emi))|| + ((emi < bmi)&&((bmi <= xmi)||(xmi < emi)))) { + heat_enabled = true; + } else heat_enabled = false; + } + + if (heat_enabled_prev) { // smart control (delayed one cycle) + if (((t - HYST) < ee.tempe)&&(ledState == HIGH)) { // OFF->ON once + ledState = LOW; + digitalWrite(ledPin, ledState); // apply change + ws.textAll("led,ledon"); + } + if ((((t + HYST) > ee.tempe)&&(ledState == LOW))||(!heat_enabled)) { // ON->OFF once, also turn off at end of period. + ledState = HIGH; + digitalWrite(ledPin, ledState); // apply change + ws.textAll("led,ledoff"); + } + Serial.printf(ledState ? "LED OFF" : "LED ON"); + Serial.print(F(", Smart enabled\n")); + } + heat_enabled_prev = heat_enabled; //update +} + +void updateDHT(){ + h = dht.readHumidity(); + t = dht.readTemperature(); //Celsius or dht.readTemperature(true) for Fahrenheit + if (isnan(h) || isnan(t)) { + Serial.print(F("Failed to read from DHT sensor!")); + h = 0; // debug w/o sensor + t = 0; + } +} + +void analogSample() +{ + ws.printfAll("wpMeter,Arduino,%+2.1f,%2.1f,%d", t, h, heat_enabled_prev); + Serial.printf("T/H.: %+2.1f°C/%2.1f%%,%d\n", t, h, heat_enabled_prev); +} + +void checkPhysicalButton() +{ + if (digitalRead(btnPin) == LOW) { + if (btnState != LOW) { // btnState is used to avoid sequential toggles + ledState = !ledState; + digitalWrite(ledPin, ledState); + if (ledState) ws.textAll("led,ledoff"); + else ws.textAll("led,ledon"); + } + btnState = LOW; + } else { + btnState = HIGH; + } +} + +void mytimer() { + ++count; //200ms increments + checkPhysicalButton(); + if ((count % 25) == 1) { // update temp every 5 seconds + analogSample(); + udht = true; + } + if ((count % 50) == 0) { // update temp every 10 seconds + ws.cleanupClients(); + } + if (count >= 150) { // cycle every 30 sec + showTime(); + count = 0; + } +} + +// server +void onWsEvent(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventType type, void * arg, uint8_t *data, size_t len){ + if(type == WS_EVT_CONNECT){ + Serial.printf("ws[%s][%u] connect\n", server->url(), client->id()); + //client->printf("Hello Client %u :)", client->id()); + //client->ping(); + + IPAddress ip = client->remoteIP(); + Serial.printf("[%u] Connected from %d.%d.%d.%d\n", client->id(), ip[0], ip[1], ip[2], ip[3]); + showTime(); + analogSample(); + if (ledState) ws.textAll("led,ledoff"); + else ws.textAll("led,ledon"); + + ws.printfAll("Now,Setting,%02d:%02d,%02d:%02d,%+2.1f", ee.hstart, ee.mstart, ee.hstop, ee.mstop, ee.tempe); + ws.printfAll("Now,sched,%d", sched); + + } else if(type == WS_EVT_DISCONNECT){ + Serial.printf("ws[%s][%u] disconnect\n", server->url(), client->id()); + ws.textAll("Now,remoff"); + + } else if(type == WS_EVT_ERROR){ + Serial.printf("ws[%s][%u] error(%u): %s\n", server->url(), client->id(), *((uint16_t*)arg), (char*)data); + } else if(type == WS_EVT_PONG){ + Serial.printf("ws[%s][%u] pong[%u]: %s\n", server->url(), client->id(), len, (len)?(char*)data:""); + } else if(type == WS_EVT_DATA){ + AwsFrameInfo * info = (AwsFrameInfo*)arg; + String msg = ""; + if(info->final && info->index == 0 && info->len == len){ + //the whole message is in a single frame and we got all of it's data + Serial.printf("ws[%s][%u] %s-message[%llu]: ", server->url(), client->id(), (info->opcode == WS_TEXT)?"text":"binary", info->len); + + if(info->opcode == WS_TEXT){ + for(size_t i=0; i < info->len; i++) { //debug + msg += (char) data[i]; + } + if(data[0] == 'L') { // LED + if(data[1] == '1') { + ledState = LOW; + ws.textAll("led,ledon"); // for others + } + else if(data[1] == '0') { + ledState = HIGH; + ws.textAll("led,ledoff"); + } + digitalWrite(ledPin, ledState); // apply change + + + } else if(data[0] == 'T') { // timeset + if (len > 11) { + data[3] = data[6] = data[9] = data[12] = 0; // cut strings + ee.hstart = (uint8_t) atoi((const char *) &data[1]); + ee.mstart = (uint8_t) atoi((const char *) &data[4]); + ee.hstop = (uint8_t) atoi((const char *) &data[7]); + ee.mstop = (uint8_t) atoi((const char *) &data[10]); + Serial.printf("[%u] Timer set %02d:%02d - %02d:%02d\n", client->id(), ee.hstart, ee.mstart, ee.hstop, ee.mstop); + writeEE(); + memch = 255; // to force showTime()to send Setting + showTime(); + } + } else if(data[0] == 'W') { // temperatureset + if (len > 3) { + if (ee.tempe != (float) atof((const char *) &data[1])){ + ee.tempe = (float) atof((const char *) &data[1]); + Serial.printf("[%u] Temp set %+2.1f\n", client->id(), ee.tempe); + writeEE(); + memch = 255; // to force showTime()to send Setting + showTime(); + } + } + } else if ((data[0] == 'Z')&&(len > 2)) { // sched + data[2] = 0; + if (sched != (uint8_t) atoi((const char *) &data[1])){ + sched = (uint8_t) atoi((const char *) &data[1]); + EEPROM.put(EESC, sched); //separately + EEPROM.commit(); //needed for ESP8266? + ws.printfAll("Now,sched,%d", sched); + showTime(); + } + } + + } else { + char buff[3]; + for(size_t i=0; i < info->len; i++) { + sprintf(buff, "%02x ", (uint8_t) data[i]); + msg += buff ; + } + } + Serial.printf("%s\n",msg.c_str()); + + if(info->opcode == WS_TEXT) + client->text("I got your text message"); + else + client->binary("I got your binary message"); + + } else { + //message is comprised of multiple frames or the frame is split into multiple packets + if(info->index == 0){ + if(info->num == 0) + Serial.printf("ws[%s][%u] %s-message start\n", server->url(), client->id(), (info->message_opcode == WS_TEXT)?"text":"binary"); + Serial.printf("ws[%s][%u] frame[%u] start[%llu]\n", server->url(), client->id(), info->num, info->len); + } + + Serial.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 < len; i++) { + msg += (char) data[i]; + } + } else { + char buff[3]; + for(size_t i=0; i < len; i++) { + sprintf(buff, "%02x ", (uint8_t) data[i]); + msg += buff ; + } + } + Serial.printf("%s\n",msg.c_str()); + + if((info->index + len) == info->len){ + Serial.printf("ws[%s][%u] frame[%u] end[%llu]\n", server->url(), client->id(), info->num, info->len); + if(info->final){ + Serial.printf("ws[%s][%u] %s-message end\n", server->url(), client->id(), (info->message_opcode == WS_TEXT)?"text":"binary"); + if(info->message_opcode == WS_TEXT) + client->text("I got your text message"); + else + client->binary("I got your binary message"); + } + } + } + } +} + + +// setup ----------------------------------- + +void setup(){ + Serial.begin(115200); + Serial.setDebugOutput(true); + +//Wifi +#ifdef USE_WFM + AsyncWiFiManager wifiManager(&server,&dns); + #ifdef DEL_WFM + wifiManager.resetSettings(); + #endif + wifiManager.setTimeout(FBTO); // seconds to config or it creates an own AP, then browse 192.168.4.1 + if (!wifiManager.autoConnect(hostName)){ + Serial.print(F("*FALLBACK AP*\n")); + WiFi.mode(WIFI_AP); + WiFi.softAP(fbssid, fbpassword); + // MDNS.begin(fbssid); + // MDNS.addService("http","tcp",80); // Core SVN 5179 use STA as default interface in mDNS (#7042) + } + +#else +// Manual simple STA mode to connect to known router + //WiFi.mode(WIFI_AP_STA); // Core SVN 5179 use STA as default interface in mDNS (#7042) + //WiFi.softAP(hostName); // Core SVN 5179 use STA as default interface in mDNS (#7042) + WiFi.mode(WIFI_STA); // Core SVN 5179 use STA as default interface in mDNS (#7042) + WiFi.begin(ssid, password); + if (WiFi.waitForConnectResult() != WL_CONNECTED) { + Serial.print(F("STA: Failed!\n")); + WiFi.disconnect(false); + delay(1000); + WiFi.begin(ssid, password); + } +#endif + + Serial.print(F("*CONNECTED*\n")); + +//DHT + dht.begin(); + updateDHT(); //first reading takes time, hold here than the loop; + +//Real Time + time_t rtc = RTC_UTC_TEST; + timeval tv = { rtc, 0 }; + //timezone tz = { 0, 0 }; //(insert) <#5194 + settimeofday(&tv, nullptr); //settimeofday(&tv, &tz); // <#5194 + configTzTime(MYTZ, "pool.ntp.org"); + +//MDNS (not needed) + // MDNS.begin(hostName); + // MDNS.addService("http","tcp",80); // Core SVN 5179 use STA as default interface in mDNS (#7042) + +//I/O & DHT + pinMode(ledPin, OUTPUT); + pinMode(btnPin, INPUT_PULLUP); + +//EE + EEPROM.begin(EEALL); + //EEPROM.get(EECH, memch); //current channel, no need + readEE(); // populate structure if healthy + digitalWrite(ledPin, ledState); + Serial.printf("Timer set %02d:%02d - %02d:%02d\n", ee.hstart, ee.mstart, ee.hstop, ee.mstop); + Serial.printf("Temp set %+2.1f\n", ee.tempe); + +//SPIFFS + SPIFFS.begin(); + +#ifdef USE_AUTH_WS + ws.setAuthentication(http_username,http_password); +#endif + ws.onEvent(onWsEvent); + server.addHandler(&ws); + +#ifdef ESP32 + server.addHandler(new SPIFFSEditor(SPIFFS, http_username,http_password)); +#elif defined(ESP8266) + server.addHandler(new SPIFFSEditor(http_username,http_password)); +#endif + + server.on("/free-ram", HTTP_GET, [](AsyncWebServerRequest *request){ // direct request->answer + request->send(200, "text/plain", String(ESP.getFreeHeap())); + }); + + + server.on("/get-time", HTTP_GET, [](AsyncWebServerRequest *request){ + if(request->hasParam("btime")){ + time_t rtc = (request->getParam("btime")->value()).toInt(); + timeval tv = { rtc, 0 }; + settimeofday(&tv, nullptr); + } + request->send(200, "text/plain","Got browser time ..."); + }); + + + server.on("/hw-reset", HTTP_GET, [](AsyncWebServerRequest *request){ + request->onDisconnect([]() { +#ifdef ESP32 + ESP.restart(); +#elif defined(ESP8266) + ESP.reset(); +#endif + }); + request->send(200, "text/plain","Restarting ..."); + }); + + server.on("/erase-wifi", HTTP_GET, [](AsyncWebServerRequest *request){ + request->onDisconnect([]() { + WiFi.disconnect(true); +#ifdef ESP32 + ESP.restart(); +#elif defined(ESP8266) + ESP.reset(); +#endif + }); + request->send(200, "text/plain","Erasing WiFi data ..."); + }); + +#ifdef USE_AUTH_STAT + server.serveStatic("/", SPIFFS, "/").setDefaultFile("index.htm").setAuthentication(http_username,http_password); +#else + server.serveStatic("/", SPIFFS, "/").setDefaultFile("index.htm"); +#endif + + server.onNotFound([](AsyncWebServerRequest *request){ // nothing known + Serial.print(F("NOT_FOUND: ")); + if (request->method() == HTTP_OPTIONS) request->send(200); //CORS + else request->send(404); + }); + + DefaultHeaders::Instance().addHeader("Access-Control-Allow-Origin", "*");//CORS + server.begin(); + + //Timer tick + tim.attach(0.2, mytimer); //every 0.2s + + //OTA + ArduinoOTA.setHostname(hostName); + ArduinoOTA.onStart([]() { + Serial.print(F("OTA Started ...\n")); + ws.textAll("Now,OTA"); // for all clients + }); + ArduinoOTA.begin(); +} // setup end + +// loop ----------------------------------- +void loop(){ + if (udht){ // 5sec + updateDHT(); + udht = false; + } + ArduinoOTA.handle(); +} diff --git a/examples/SmartSwitch/data/acefull.js.gz b/examples/SmartSwitch/data/acefull.js.gz index 0ff2a5f9fb7afff20fbb37242a7841c1b63312e8..e08df275219565d93939df9642c0198e32044e3b 100644 GIT binary patch delta 7760 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 diff --git a/examples/SmartSwitch/data/worker-css.js.gz b/examples/SmartSwitch/data/worker-css.js.gz new file mode 100644 index 0000000000000000000000000000000000000000..6e826b6cc0669fdfe8c91ea7135fe25431513434 GIT binary patch literal 35483 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 literal 0 HcmV?d00001 diff --git a/examples/SmartSwitch/data/worker-html.js.gz b/examples/SmartSwitch/data/worker-html.js.gz new file mode 100644 index 0000000000000000000000000000000000000000..5245c5e855964f046498a7f78b944848302bd519 GIT binary patch literal 47406 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 Ct+cfO literal 0 HcmV?d00001 diff --git a/examples/SmartSwitch/data/worker-javascript.js.gz b/examples/SmartSwitch/data/worker-javascript.js.gz new file mode 100644 index 0000000000000000000000000000000000000000..a5fce7e0e123c1db9d80632e017df836a341b711 GIT binary patch literal 47729 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%0Dq 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 acefull.js +type ace.js mode-html.js theme-monokai.js ext-searchbox.js > acefull.js "C:\Program Files\7-Zip\7z.exe" a -tgzip -mx9 acefull.js.gz acefull.js +REM +"C:\Program Files\7-Zip\7z.exe" a -tgzip -mx9 worker-html.js.gz worker-html.js +"C:\Program Files\7-Zip\7z.exe" a -tgzip -mx9 worker-javascript.js.gz worker-javascript.js +"C:\Program Files\7-Zip\7z.exe" a -tgzip -mx9 worker-css.js.gz worker-css.js + REM update: pause copy acefull.js.gz ..\..\examples\SmartSwitch\data\acefull.js.gz +REM +copy worker-html.js.gz ..\..\examples\SmartSwitch\data\worker-html.js.gz +copy worker-javascript.js.gz ..\..\examples\SmartSwitch\data\worker-javascript.js.gz +copy worker-css.js.gz ..\..\examples\SmartSwitch\data\worker-css.js.gz del *.js *.gz - diff --git a/src/WebAuthentication.cpp b/src/WebAuthentication.cpp index a88dde133..2d72de9d4 100644 --- a/src/WebAuthentication.cpp +++ b/src/WebAuthentication.cpp @@ -36,6 +36,12 @@ bool checkBasicAuthentication(const char * hash, const char * username, const ch size_t toencodeLen = strlen(username)+strlen(password)+1; size_t encodedLen = base64_encode_expected_len(toencodeLen); if(strlen(hash) != encodedLen) +// Fix from https://github.com/me-no-dev/ESPAsyncWebServer/issues/667 +#ifdef ARDUINO_ARCH_ESP32 + if(strlen(hash) != encodedLen) +#else + if (strlen(hash) != encodedLen - 1) +#endif return false; char *toencode = new char[toencodeLen+1]; diff --git a/src/edit.htm b/src/edit.htm index 3f8baaeb8..584b5bbbf 100644 --- a/src/edit.htm +++ b/src/edit.htm @@ -441,9 +441,9 @@ edit: e }, s) } - "undefined" == typeof t && (t = "/index.html"), "undefined" == typeof n && (n = o(t)), "undefined" == typeof a && (a = "monokai"), "undefined" == typeof i && (i = "text/" + n, "c_cpp" === n && (i = "text/plain")); + "undefined" == typeof t && (t = "/index.htm"), "undefined" == typeof n && (n = o(t)), "undefined" == typeof a && (a = "monokai"), "undefined" == typeof i && (i = "text/" + n, "c_cpp" === n && (i = "text/plain")); var l = ace.edit(e); - return "plain" !== n && l.getSession().setMode("ace/mode/" + n), l.setTheme("ace/theme/" + a), l.$blockScrolling = 1 / 0, l.getSession().setUseSoftTabs(!0), l.getSession().setTabSize(2), l.getSession().setUseWorker(!1), l.setHighlightActiveLine(!0), l.setShowPrintMargin(!1), l.commands.addCommand({ + return "plain" !== n && l.getSession().setMode("ace/mode/" + n), l.setTheme("ace/theme/" + a), l.$blockScrolling = 1 / 0, l.getSession().setUseSoftTabs(!0), l.getSession().setTabSize(2), l.getSession().setUseWorker(!0), l.setHighlightActiveLine(!0), l.setShowPrintMargin(!1), l.commands.addCommand({ name: "saveCommand", bindKey: { win: "Ctrl-S", @@ -485,6 +485,12 @@ e[n] = a }), createEditor("editor", e.file, e.lang, e.theme)), n = createTree("tree", t); + + window.define = ace.define; + window.require = ace.require; + ace.config.set('basePath', '/'); + ace.config.set("workerPath", '/'); + createFileUploader("uploader", n, t), "undefined" == typeof e.file && (e.file = "/index.htm"), t.loadUrl(e.file) } "undefined" == typeof XMLHttpRequest && (XMLHttpRequest = function() { diff --git a/src/edit.htm.gz.h b/src/edit.htm.gz.h index cbcacd57d..c2d7f53fc 100644 --- a/src/edit.htm.gz.h +++ b/src/edit.htm.gz.h @@ -1,224 +1,226 @@ -//File: edit.htm.gz, Size: 4365 -#define edit_htm_gz_len 4365 +//File: edit.htm.gz, Size: 4408 +#define edit_htm_gz_len 4408 const uint8_t edit_htm_gz[] PROGMEM = { -0x1F,0x8B,0x08,0x08,0xC6,0xC7,0xA5,0x5E,0x02,0x00,0x65,0x64,0x69,0x74,0x2E,0x68,0x74,0x6D,0x00,0xB5, +0x1F,0x8B,0x08,0x08,0x52,0x4A,0xB0,0x5E,0x02,0x00,0x65,0x64,0x69,0x74,0x2E,0x68,0x74,0x6D,0x00,0xB5, 0x1A,0x0B,0x5B,0xDB,0x36,0xF0,0xAF,0x18,0x6F,0x63,0xF6,0xE2,0x38,0x0E,0xA5,0xAC,0x73,0x30,0x2C,0x50, -0x56,0xFA,0x02,0x4A,0x42,0x3B,0xCA,0xD8,0x3E,0xC5,0x56,0x62,0x15,0x5B,0xF2,0x6C,0x99,0x40,0xB3,0xFC, -0xF7,0x9D,0x24,0x3F,0x43,0xE8,0x1E,0xDF,0xB6,0xAE,0x8D,0xA4,0xD3,0x9D,0xEE,0xA1,0x7B,0x29,0xD9,0xDD, -0x78,0x7E,0x7A,0x38,0xBE,0x3C,0x3B,0xD2,0x42,0x1E,0x47,0x7B,0xBB,0xE2,0x5F,0x2D,0x42,0x74,0xE6,0xE9, -0x98,0xEA,0x7B,0xBB,0x31,0xE6,0x08,0x40,0x3C,0xE9,0xE2,0xDF,0x73,0x72,0xEB,0xE9,0x87,0x8C,0x72,0x4C, -0x79,0x97,0xDF,0x27,0x58,0xD7,0x7C,0x35,0xF3,0x74,0x8E,0xEF,0x78,0x4F,0x20,0x0F,0x34,0x3F,0x44,0x69, -0x86,0xB9,0x97,0xF3,0x69,0xF7,0x19,0x90,0xE0,0x84,0x47,0x78,0xEF,0x68,0x74,0xA6,0x1D,0x05,0x84,0xB3, -0x74,0xB7,0xA7,0x56,0x76,0x23,0x42,0x6F,0xB4,0x14,0x47,0x9E,0x8E,0x92,0x24,0xC2,0x5D,0xCE,0x72,0x3F, -0xEC,0x12,0xA0,0xA9,0x6B,0x61,0x8A,0xA7,0x9E,0xDE,0x43,0x3E,0xB6,0x61,0x41,0xD7,0xC4,0x71,0x9E,0x4E, -0x62,0x34,0xC3,0xBD,0x3B,0xB5,0xA7,0x49,0x20,0x0B,0x59,0xCA,0xFD,0x9C,0x6B,0xFF,0x0A,0xFB,0x1F,0x20, -0x65,0xFC,0x3E,0xC2,0x0A,0xA4,0x64,0xF6,0xB3,0x4C,0xD7,0x62,0x1C,0x10,0x04,0x5C,0xF8,0x29,0x16,0x5A, -0x8B,0xD0,0x04,0x47,0x8B,0x29,0x03,0x35,0x65,0xE4,0x33,0x76,0xFB,0x5B,0xC9,0xDD,0x40,0x4E,0xA7,0x28, -0x26,0xD1,0xBD,0x9B,0x21,0x9A,0x75,0x33,0x9C,0x92,0xE9,0xD2,0xF6,0xE3,0xC5,0xE7,0x2E,0xA1,0x01,0xBE, -0x73,0x9F,0x38,0xCE,0x20,0x61,0x19,0xE1,0x84,0x51,0x17,0x4D,0x32,0x16,0xE5,0x1C,0x0F,0x22,0x3C,0xE5, -0xEE,0x53,0xA0,0x30,0x61,0x69,0x80,0x53,0xB7,0x9F,0xDC,0x69,0x00,0x22,0x81,0xF6,0xD5,0xF6,0xF6,0xF6, -0x60,0x82,0xFC,0x9B,0x59,0xCA,0x72,0x1A,0x74,0x7D,0x16,0xB1,0xD4,0xFD,0x6A,0xFA,0x54,0xFC,0x19,0x04, -0x24,0x4B,0x22,0x74,0xEF,0x52,0x46,0x31,0xE0,0xDE,0x75,0xB3,0x10,0x05,0x6C,0xEE,0x3A,0x9A,0xA3,0xF5, -0x1D,0x20,0x92,0xCE,0x26,0xC8,0x70,0x2C,0xF1,0xC7,0xDE,0x36,0x07,0x7F,0x8B,0x5F,0xB5,0x3C,0xC7,0x64, -0x16,0x72,0xF7,0x7B,0xC7,0x11,0xFC,0x6B,0x79,0xB4,0x88,0x48,0xC6,0xBB,0x52,0x39,0xEA,0x3C,0xCE,0x12, -0xD7,0x91,0xAC,0xC3,0x47,0x8C,0xD2,0x19,0xA1,0x30,0x48,0x50,0x10,0x10,0x3A,0x73,0x15,0x5A,0x44,0x16, -0x95,0xB4,0x60,0x07,0xC4,0xC9,0x2D,0x1E,0xC4,0x84,0x76,0xE7,0x24,0xE0,0xA1,0xBB,0xE3,0x00,0x17,0x7E, -0x9E,0x66,0x20,0x53,0xC2,0x08,0xE5,0x38,0x95,0x68,0x59,0x82,0xE8,0x42,0x89,0x2A,0x14,0x50,0xC9,0x49, -0x28,0x58,0x14,0x77,0x27,0x11,0xF3,0x6F,0xAA,0x93,0x76,0x92,0xBB,0xE2,0x2C,0x37,0x64,0xB7,0x38,0x5D, -0xD4,0xEA,0x92,0xD8,0x2D,0x60,0x8B,0x34,0xC6,0x78,0x69,0xF3,0xDB,0x1C,0xA0,0x96,0xFC,0x04,0x29,0x0B, -0xAA,0x4D,0x91,0xDA,0x82,0x17,0x28,0x84,0x26,0x39,0x5F,0x3C,0x34,0x25,0x4B,0x90,0x4F,0xF8,0xBD,0xEB, -0xC8,0x6D,0xF2,0x86,0xB8,0xDB,0x8E,0xA3,0x09,0x85,0x6B,0xEF,0x71,0x1A,0x20,0x8A,0xAC,0x61,0x4A,0x50, -0x64,0x8D,0x6A,0x95,0x77,0x63,0xF6,0xB9,0x9B,0xC3,0x18,0xE6,0x11,0xF6,0xB9,0xD2,0x30,0x18,0x61,0x72, -0x43,0xF8,0x43,0xC0,0x83,0x85,0x86,0xAE,0xA4,0x86,0x42,0x65,0xBD,0x3E,0xE8,0x46,0xF2,0xA1,0xC4,0x56, -0x12,0x75,0x27,0x8C,0x73,0x16,0xCB,0xFB,0x56,0x49,0xAB,0xC9,0x2B,0xF3,0xEC,0x81,0x39,0xD6,0xAB,0xBE, -0x41,0x7E,0x00,0x4A,0xE5,0xC4,0x47,0x51,0x17,0x45,0x64,0x46,0xDD,0x98,0x04,0x41,0x84,0x07,0x0D,0x1B, -0xE4,0x69,0x64,0x04,0x88,0x23,0x57,0xF9,0x59,0x42,0x67,0x00,0xCD,0xF0,0xCE,0xB6,0x45,0xDE,0x1F,0x9C, -0x9E,0xCF,0x9D,0xD7,0x2F,0x66,0x6C,0x08,0xFF,0x9D,0x8C,0x2E,0xC2,0xA3,0x8B,0x19,0x8C,0x0E,0xC4,0x74, -0xF8,0xEE,0x70,0xF8,0x0E,0x3E,0x0E,0xFB,0x9D,0x4F,0xD3,0xDF,0x87,0x62,0xF9,0x45,0x70,0x30,0xBE,0x38, -0x1A,0x0E,0x5F,0xF7,0x5E,0x9E,0xCC,0x3F,0xBC,0xDE,0x11,0xE0,0x83,0xC8,0x39,0x7F,0x1F,0x3A,0x17,0x5B, -0x3F,0xC4,0xC1,0x71,0x10,0xFA,0xF1,0xC5,0xF0,0xDD,0x87,0xF3,0xDB,0xCB,0xF8,0x62,0x36,0xFA,0xD0,0x0F, -0x3F,0x6E,0xBD,0x1F,0x7D,0xFC,0xF0,0xD3,0x0D,0xFE,0xF9,0xF8,0xD5,0xC7,0xF1,0x1C,0x10,0x9E,0xB3,0xD1, -0xC5,0xF9,0xC1,0xFB,0x83,0xD9,0xC7,0x03,0xFF,0xE8,0x6E,0x12,0x9D,0x1C,0xBC,0x18,0x4E,0x86,0x5B,0x3E, -0xC6,0xB3,0xF1,0xF9,0x41,0xFE,0xF2,0xF5,0xE9,0x8C,0x90,0x70,0xF4,0xF1,0x64,0xEC,0x1F,0x3E,0x7D,0x73, -0x71,0x3C,0x24,0xE1,0xC9,0xAB,0x73,0xE7,0xE6,0xC5,0xEB,0xC3,0xE7,0xFE,0xE5,0xAB,0xCB,0x9D,0xE7,0x4F, -0x7A,0xDF,0x7F,0xFF,0x36,0x38,0x25,0x74,0x7C,0xFB,0x79,0x38,0x3B,0x9C,0x3F,0xBB,0xCF,0xC6,0xE1,0xCB, -0x5B,0xDA,0x7B,0xCF,0x3E,0xBD,0xBC,0x7F,0x0B,0x7F,0xCF,0xCE,0x3A,0x93,0x51,0x3F,0xBB,0x78,0xF7,0xF2, -0xFD,0x56,0xF6,0xC3,0xD3,0xE4,0xE0,0xF9,0xF3,0xDB,0x78,0x72,0xD6,0x8B,0x83,0x9B,0x29,0x7F,0xF6,0x84, -0x27,0x97,0xB3,0xFC,0xE3,0xEF,0x4F,0x5F,0x85,0xBD,0x53,0x8C,0x2E,0xC3,0xCE,0xFD,0xE7,0xFB,0x67,0xE1, -0xF8,0xF8,0xF6,0x24,0x42,0x77,0x27,0x27,0xFE,0xE7,0xB8,0x13,0xA1,0x1F,0x4E,0xC7,0x11,0x4A,0xFB,0x17, -0xC1,0xB0,0xD7,0x39,0xDC,0x1A,0x6E,0xF3,0xF4,0xFC,0x90,0x3E,0x7F,0xF2,0x69,0xF4,0xEC,0xE0,0xA0,0xCF, -0x26,0xBF,0x6F,0xBD,0xB8,0xD9,0x79,0x71,0xB1,0xF3,0x6E,0xF2,0x6E,0x38,0xDA,0x3E,0xB8,0x40,0x97,0xA3, -0x77,0xC3,0xE9,0xF6,0x24,0x0C,0x5F,0xBF,0x1E,0xFF,0x14,0x0C,0x3F,0xA7,0xC3,0xD3,0xF9,0xF0,0xEE,0xE8, -0x62,0x78,0xDC,0x79,0x7D,0xF4,0xD6,0xE9,0x8F,0x2E,0x9F,0xCC,0xDE,0xEE,0xCC,0x0F,0xB2,0xA3,0xE1,0xBB, -0x03,0x67,0xF6,0xAA,0x13,0xA3,0x8F,0xEC,0xF0,0xC9,0xEC,0xE5,0x0E,0x39,0xBB,0x44,0xC3,0x97,0x07,0xAF, -0x32,0x72,0x1E,0x1F,0x5F,0x38,0xC3,0xE1,0x9B,0x53,0xFC,0xD3,0xE1,0x13,0xF4,0x7A,0xCB,0xFF,0x00,0xFA, -0xBF,0xF8,0x19,0x7F,0xDF,0x19,0xCE,0x4F,0x9D,0xC8,0xFF,0x01,0x8F,0x8F,0x2F,0xC7,0xD2,0x3A,0x47,0xD1, -0x4F,0xE3,0x9B,0x51,0xFE,0x2E,0x3E,0x3C,0x34,0x35,0xCA,0xBA,0x29,0x4E,0x30,0xE2,0xCD,0x58,0x55,0x39, -0x07,0xDC,0xAD,0xFA,0x16,0x16,0x4E,0x2A,0x22,0x6B,0x37,0xC0,0x3E,0x4B,0x91,0xDC,0x03,0x08,0x38,0x15, -0x57,0x6C,0xF9,0xA3,0x0C,0xB5,0x9A,0x8A,0xB4,0x1A,0xA2,0x81,0x66,0x94,0x8E,0x10,0x13,0x0A,0x38,0xB7, -0xC4,0xC7,0xDD,0x84,0xDC,0xE1,0xA8,0x2B,0x91,0x5D,0xC7,0x5C,0x48,0x67,0x2B,0xB7,0x21,0x4A,0x62,0x45, -0xB5,0x5C,0x08,0x3E,0x21,0x5F,0xA4,0x34,0x70,0x99,0x18,0x3E,0x0B,0xDF,0x61,0x69,0x77,0x92,0xCF,0xA6, -0xE4,0x0E,0xBC,0x79,0x4A,0x28,0xE1,0x58,0xEB,0x67,0xCB,0x1F,0x4B,0x32,0x37,0xF8,0x7E,0x9A,0xA2,0x18, -0x67,0xDA,0xDF,0x24,0xB3,0x98,0xA6,0x2C,0x5E,0xD4,0x11,0x90,0xB3,0xC6,0x64,0xB9,0xFC,0x2A,0x4F,0x22, -0x86,0x40,0xCC,0x35,0x61,0x43,0x05,0xD3,0x54,0xB8,0x55,0x15,0x54,0x4B,0x37,0xDB,0x02,0xB7,0x6C,0xB9, -0xF5,0xD6,0x76,0xED,0xBA,0x5D,0xB9,0x57,0x04,0xFB,0xA6,0xEA,0x1B,0xF1,0xA0,0x11,0xEB,0xBE,0xE2,0xA0, -0xD2,0xF5,0x87,0xAB,0x43,0x54,0x64,0xA8,0x19,0x50,0x51,0xBA,0xBF,0xE3,0x34,0x42,0x05,0xEC,0x5B,0x7E, -0x85,0x65,0x9A,0xB7,0xBE,0x4A,0x52,0xB0,0x06,0x9E,0x7F,0x81,0x66,0x25,0x53,0x9B,0x36,0xD0,0xAC,0xD2, -0x9D,0x12,0xA1,0xCE,0x79,0x92,0xD7,0x8A,0xF4,0x43,0xA9,0x00,0x5C,0x71,0xF3,0x54,0x70,0xF3,0x45,0xAD, -0x3E,0xD9,0xF9,0xA6,0xE0,0x61,0xDB,0xF9,0x66,0x69,0xAB,0xBD,0x55,0x3E,0xEE,0x3B,0xF0,0x5F,0x99,0x76, -0x9F,0xD5,0x2C,0x4C,0x9E,0x8A,0x3F,0x25,0x83,0x40,0xA7,0x09,0x7C,0xB2,0xFD,0xC3,0xB3,0x60,0x52,0x02, -0x95,0x60,0x8F,0xC3,0x53,0x14,0x90,0x3C,0x73,0x9F,0x3A,0xDF,0x28,0x7D,0x82,0xF9,0x40,0xF6,0xD2,0xB8, -0x6A,0x52,0xDF,0xD8,0x2C,0x21,0x54,0xDB,0xCA,0x34,0x61,0x6F,0x94,0x56,0x17,0xB3,0x99,0xEA,0xC1,0x45, -0xEA,0xAB,0x29,0xF6,0x2F,0x9C,0x6F,0x16,0x3C,0x45,0x34,0x9B,0xB2,0x34,0x76,0x53,0xC6,0x11,0xC7,0x86, -0x63,0x2E,0xFB,0xCE,0x3A,0xC0,0x93,0x1D,0x27,0xC0,0x33,0x73,0xB9,0xDC,0xED,0xC9,0xA4,0x06,0x15,0x8F, -0x9F,0x92,0x84,0xEF,0x4D,0x73,0xEA,0x0B,0x1E,0xB4,0x19,0x36,0xB0,0xB9,0x48,0x31,0xCF,0x53,0xAA,0x05, -0xCC,0xCF,0xC5,0x65,0xB7,0x67,0x98,0x1F,0xA9,0x7B,0x7F,0x70,0xFF,0x32,0x80,0x1D,0xCB,0x0A,0xC1,0x5F, -0x8B,0x00,0x0E,0x0C,0xE7,0x15,0x38,0xAD,0xFD,0x90,0x60,0x80,0xC8,0x6B,0x7C,0x6F,0x60,0x8B,0x57,0x88, -0xD8,0x16,0xEB,0x86,0x51,0x6E,0x03,0x20,0x35,0x17,0xB7,0xA0,0x05,0xE4,0xE1,0x2B,0x7E,0x6D,0x11,0x8F, -0xC2,0xC7,0xA0,0xD8,0x4E,0xF6,0xD0,0x7E,0xB7,0xEF,0xA2,0x3D,0xB2,0xDF,0x07,0xFF,0x32,0x1B,0xF4,0xD5, -0xC9,0x3F,0x91,0x08,0x5F,0x14,0x2E,0x27,0x0E,0xAA,0xA9,0xF5,0x0C,0x72,0x16,0x82,0x22,0xCD,0xEF,0x8C, -0xD3,0x91,0x66,0x5C,0x7D,0xDF,0xFD,0xE1,0xFA,0x8F,0xFE,0x95,0xD3,0xED,0x5F,0x9B,0xBF,0x99,0x3D,0x62, -0x73,0x9C,0x71,0x83,0xA2,0x5B,0x32,0x43,0x9C,0xA5,0xB6,0xC8,0xB7,0xC3,0x19,0x48,0x61,0x0E,0xAA,0x33, -0x88,0x62,0x6F,0xCB,0x71,0x36,0x3C,0xBC,0x8F,0x22,0x0C,0xAC,0xEB,0x47,0xE7,0xE7,0xA7,0xE7,0x57,0x7A, -0x07,0x77,0xF4,0x6B,0x57,0xD3,0x3B,0xD4,0x74,0xB9,0x0D,0x45,0x67,0x8A,0xB3,0xF0,0x0C,0xF1,0xD0,0x08, -0xEC,0x5B,0x14,0xE5,0xA0,0x0B,0xC1,0x08,0xF3,0x40,0x71,0xFA,0x24,0xE7,0x9C,0x51,0xDD,0x1C,0x30,0x9B, -0x50,0x8A,0xD3,0xE3,0xF1,0xDB,0x37,0x9E,0x7E,0xAE,0x90,0xB4,0x37,0x24,0xE3,0xBA,0x25,0x2D,0x62,0xA3, -0x24,0xC1,0x34,0x38,0x0C,0x49,0x14,0x18,0xCC,0x1C,0x08,0x12,0xBE,0x24,0x21,0x8B,0x11,0xA0,0xE0,0xDB, -0xAA,0x6C,0x9D,0x82,0xE4,0xBA,0xE5,0xDB,0x71,0x1E,0x71,0x92,0x44,0xD8,0xDB,0xE8,0xC3,0x8C,0xA2,0x18, -0x60,0x22,0x15,0x0B,0x18,0x09,0x3C,0x5D,0x05,0x24,0x15,0xC6,0xD6,0x9E,0xE2,0xAB,0x53,0x82,0xD6,0x29, -0x41,0x13,0x37,0x01,0xA9,0x74,0x2B,0xB0,0xEB,0x7A,0x19,0x66,0xC5,0x51,0x25,0x2C,0xC0,0x53,0x04,0x9C, -0xBC,0x17,0x92,0x43,0xF9,0xBD,0xEE,0xA0,0x40,0x1D,0x94,0xB5,0x35,0x92,0x35,0x35,0xA2,0x4C,0xB9,0x0E, -0x39,0x53,0xC8,0x69,0x1B,0x39,0x6D,0x22,0x1F,0xCA,0x1B,0xB1,0x0E,0x39,0x55,0xC8,0x51,0x4B,0xC4,0x48, -0x8A,0xA8,0xA2,0x5C,0x57,0x68,0x13,0x04,0x02,0xEC,0xA8,0x29,0x26,0xCC,0xC0,0x29,0xD1,0x24,0xC2,0x81, -0xB7,0xE1,0xC0,0x4C,0x14,0xD6,0xDE,0x96,0xB3,0xE6,0x8C,0x48,0x9D,0x91,0xB7,0xCE,0xC8,0xE5,0x19,0x24, -0x01,0x25,0x42,0xEE,0xD0,0xAD,0x5C,0x6A,0xAD,0xBD,0xA2,0x8E,0xF3,0x43,0xEC,0xDF,0x4C,0x98,0x5C,0x91, -0x63,0x71,0xE2,0x06,0x92,0x34,0x13,0x49,0x53,0xB6,0x23,0x40,0x33,0xB1,0xC1,0xD3,0x3D,0x41,0xD9,0x4A, -0x9A,0xE2,0x6B,0xC3,0x88,0xDB,0xBA,0x44,0x88,0xDB,0x5A,0x8A,0x5B,0xDB,0x46,0xE8,0x16,0x6B,0xEB,0xB4, -0x14,0x9B,0x6B,0x16,0x93,0x75,0x8B,0xB9,0x69,0xA5,0x36,0xA3,0x7E,0x44,0xFC,0x1B,0xAF,0x76,0x65,0x73, -0x61,0x34,0x27,0x82,0x13,0xEE,0x51,0x3C,0xD7,0x7E,0x82,0xD0,0xF4,0x1C,0x71,0x34,0xE0,0x05,0x19,0xA3, -0xB8,0x37,0x18,0x08,0x41,0x47,0x0A,0x9E,0x98,0xD9,0x28,0x80,0xE5,0xB3,0x8B,0xB1,0x6E,0xE9,0x3D,0x61, -0x15,0x1D,0xBC,0x99,0x98,0x4B,0xB3,0xF2,0x27,0x8B,0xCA,0xC8,0x7E,0x91,0x46,0xF5,0x12,0x0C,0xCA,0x1B, -0xB7,0xB4,0xE2,0xB5,0x3C,0x91,0xA9,0x51,0xA9,0xB4,0x64,0x4A,0x74,0x87,0xE2,0x0C,0xA3,0xB0,0xBF,0x6E, -0x42,0xE8,0x53,0x97,0xD7,0x30,0x2D,0xD4,0x66,0x1A,0x55,0x4C,0xA7,0x68,0x5E,0x5E,0x12,0x75,0xFE,0x40, -0xB9,0xB8,0x03,0x19,0x98,0x66,0x5C,0xC3,0xDE,0xB6,0xF3,0xC3,0xCE,0x00,0xEC,0x63,0x28,0xC7,0x05,0xC0, -0x2E,0xB7,0x23,0x4C,0x67,0x3C,0x1C,0xF8,0x1D,0xAF,0xD0,0x4A,0xE0,0x71,0x3B,0xCB,0x27,0x19,0x4F,0x21, -0xBF,0x19,0xBE,0xE5,0x77,0xB0,0xD9,0x3E,0x46,0xEF,0x30,0x2B,0x30,0x2D,0xD6,0xE9,0x2C,0x57,0x14,0x74, -0x3A,0x6A,0x68,0x08,0x09,0x0D,0xE1,0x28,0xC3,0x1A,0xB5,0xF1,0x1D,0xF6,0x0F,0x59,0x1C,0x23,0x41,0x22, -0x03,0x23,0x17,0x13,0xDD,0x5C,0x5A,0x6C,0xAD,0x66,0x1E,0x09,0x5B,0x56,0xF6,0x98,0x1E,0x21,0x0C,0x7A, -0xBE,0x2D,0x7C,0x25,0x2B,0x84,0xFA,0xB2,0x95,0xCB,0x40,0xA4,0x50,0xAE,0x9C,0x6B,0xAB,0x32,0xDC,0x5A, -0xA9,0x6A,0xBB,0xCB,0x5B,0xD7,0x8A,0x3F,0x66,0x6D,0x69,0x01,0x6B,0xC7,0xB5,0x1A,0xAA,0x2F,0x97,0x96, -0x2F,0xF8,0x0F,0x11,0x9D,0xE1,0xBF,0x2F,0x40,0xCD,0xA3,0x74,0x51,0x8B,0x42,0x02,0xD9,0x77,0x7F,0xB1, -0x8D,0xAB,0x5F,0xED,0xEB,0x8E,0x69,0xEE,0x7F,0xDD,0x93,0x1A,0x36,0xB8,0x79,0xD5,0xBF,0xB6,0x10,0x80, -0xED,0xEF,0xCC,0x5F,0x6C,0x09,0x6E,0xC1,0x06,0xB7,0x8C,0x04,0x9A,0x38,0x49,0x78,0x36,0x9B,0x6A,0x68, -0x73,0xD3,0xE0,0x1E,0x6A,0x5D,0xD6,0x0E,0xEF,0xE8,0x36,0xE4,0x8E,0xE5,0x72,0x35,0xA3,0x8D,0x53,0x8C, -0x55,0xCA,0xAC,0x00,0x92,0x7B,0x90,0x79,0x35,0x58,0x55,0x52,0x63,0xAB,0x86,0xC2,0xA2,0x4C,0xF9,0x76, -0x51,0x4D,0x78,0xBA,0x28,0x27,0x20,0xAC,0xAC,0x2E,0xCB,0x36,0x0F,0xD6,0x1B,0xC1,0xE1,0xDB,0x5D,0x12, -0xCF,0xB4,0x2C,0xF5,0x3D,0x65,0x8A,0x7D,0xF1,0x8F,0xF7,0xAD,0x48,0x75,0x9B,0xBF,0xF9,0x13,0x4F,0xEF, -0x80,0x7D,0xB1,0x4D,0xD9,0xDC,0x30,0x3B,0xDF,0xEA,0x9A,0xA4,0xE8,0xE9,0x31,0xBA,0x2B,0x9A,0x7D,0x51, -0x8D,0x0C,0x34,0x98,0x57,0xDD,0xA9,0x5A,0x50,0x6D,0x36,0xCA,0x39,0x1B,0x68,0x65,0x95,0xA3,0xDA,0x4C, -0x5D,0xEB,0xED,0x7D,0x5B,0xEB,0x00,0x81,0xE8,0x48,0xD9,0x84,0xC8,0x20,0x96,0x8B,0x90,0x87,0x5B,0xD1, -0x87,0x14,0x6E,0xA7,0xA2,0x22,0x01,0x38,0x59,0x49,0x9B,0x56,0x60,0x20,0x73,0xDF,0x68,0x25,0xDB,0x5D, -0xD1,0x98,0xEC,0x9D,0xA9,0x8A,0x73,0xB7,0x27,0x67,0xFA,0x3A,0xC7,0x00,0xCD,0x53,0x40,0xB7,0xAA,0x1A, -0x67,0xC2,0x82,0xFB,0x46,0x65,0x94,0x1D,0xDC,0x1F,0x46,0x28,0xCB,0x4E,0x50,0x0C,0xE7,0xFB,0xB1,0x6E, -0x16,0x57,0x69,0xCF,0xD9,0xDC,0x6C,0x23,0xA5,0x38,0x86,0x46,0x48,0x71,0x85,0x21,0x94,0xB9,0x3E,0x10, -0xDE,0xDC,0x5C,0xC7,0x98,0x78,0x54,0xFB,0x12,0x57,0x14,0xDC,0xB5,0x0C,0x7F,0xFF,0x13,0x77,0x2A,0xC1, -0x3E,0xA6,0xD5,0x14,0x7C,0xF6,0x21,0xDB,0xCF,0xD9,0x9C,0x0A,0xAE,0x2A,0xD6,0xD3,0x35,0x0A,0xAD,0xF3, -0x42,0x75,0x93,0x83,0x02,0xAF,0x3B,0x4D,0xD5,0x45,0x6E,0x5C,0xBA,0x12,0x06,0xD7,0x0D,0x2F,0xCD,0xFF, -0x47,0x58,0x55,0x0F,0x3C,0x26,0x6B,0x64,0x5A,0xD1,0x1A,0x59,0x71,0x84,0x39,0xAE,0x24,0x8D,0xD6,0x4A, -0x9A,0xFD,0x3F,0xFC,0xD6,0x1E,0x42,0x54,0x99,0xDB,0xF4,0x91,0x80,0xDC,0xEA,0x90,0x2B,0xBC,0x36,0x05, -0xA8,0xF8,0x59,0x14,0x8D,0x59,0xB2,0xFF,0xC8,0xBA,0x5B,0xAD,0x17,0x83,0x92,0xCD,0x7A,0x8B,0xE5,0xAF, -0x25,0xFA,0x06,0x4F,0xF9,0xFE,0x63,0x80,0xC7,0xC9,0xD6,0x7B,0xAC,0xC0,0xC3,0x36,0x28,0x0F,0x56,0x7F, -0xEE,0xF8,0x56,0x56,0xCD,0x2E,0x3B,0x0C,0x6C,0xE1,0x97,0x4A,0xF2,0x84,0x92,0x2C,0xB2,0x36,0x74,0xD5, -0xEB,0xA2,0xB7,0xF4,0x82,0x8E,0x9E,0xDC,0xD5,0x6B,0x9C,0x25,0x5E,0xA6,0x96,0x90,0x41,0x2C,0xBE,0x62, -0x94,0x75,0x01,0x25,0xF5,0x88,0xCD,0xA6,0xD3,0x0C,0xF3,0x0F,0x22,0x98,0x59,0x51,0x35,0x3F,0x96,0xC1, -0x6C,0x00,0x53,0x1A,0xB3,0x3C,0xC3,0x2C,0xE7,0xED,0xB2,0xA7,0x12,0x66,0x37,0xF8,0xE3,0x8F,0x6A,0xB2, -0x17,0x74,0xD2,0x7A,0x7A,0xB9,0x9B,0x35,0x26,0x7B,0x59,0x27,0x82,0x50,0xF0,0x1F,0xDF,0x14,0xD2,0xBC, -0x29,0x4C,0xC4,0x52,0x8B,0xA9,0x9B,0x92,0xD5,0x77,0x3D,0x13,0x45,0x29,0x6A,0x78,0xBB,0xB8,0xD0,0xBA, -0x59,0xF6,0x5C,0x4D,0x2F,0x47,0x56,0xB6,0x1A,0x04,0xD6,0x17,0x07,0xBE,0x21,0xA8,0x82,0xD6,0xDF,0xB0, -0x39,0x4E,0x0F,0x51,0x86,0x0D,0xC8,0x99,0x55,0xC4,0x92,0x50,0xD3,0x0D,0xD6,0xEC,0x02,0x25,0x50,0x05, -0x2E,0x0A,0x0F,0x46,0x45,0xE9,0x0D,0xF2,0xE5,0xAD,0x13,0xB0,0x2D,0x5E,0x0B,0x40,0xEA,0xE7,0xAA,0xD3, -0x80,0x3A,0x0D,0x83,0xAD,0x59,0x72,0x96,0xB2,0x04,0xCD,0x64,0x67,0x0D,0x6B,0xC2,0x3D,0x4A,0x6A,0x8D, -0xD4,0x5A,0xD5,0xA3,0x32,0xAD,0x3F,0xCC,0xEA,0x58,0x66,0x6E,0xA8,0x10,0x56,0x93,0x37,0x37,0xB3,0x39, -0xE1,0x7E,0x28,0x7C,0xDB,0x07,0x86,0x75,0x0E,0x6D,0x81,0x2B,0x47,0x21,0x8F,0xEB,0x51,0x54,0x0C,0x3F, -0x65,0xC5,0xC0,0xCF,0xCA,0xD1,0x5D,0x03,0xC8,0x68,0x09,0x66,0x74,0x5A,0x0C,0x09,0x25,0x25,0x9D,0x12, -0x58,0x7E,0x26,0x49,0x31,0x4A,0xC2,0x72,0x14,0xE2,0xBB,0x0A,0x8F,0x95,0xD0,0x00,0xEB,0xAE,0x32,0xDF, -0x86,0xB3,0x2C,0x06,0xFD,0x5A,0xFC,0xE0,0xBF,0x13,0x3F,0xA1,0xB3,0x52,0x98,0xA4,0x1C,0xCD,0x48,0x29, -0xCA,0x24,0x4E,0xBE,0xC8,0x48,0xF6,0x6F,0xFB,0x82,0xE7,0x47,0x6F,0x8E,0xC6,0x47,0xCD,0x12,0xB1,0xF9, -0x84,0xC0,0xFF,0xAA,0x47,0xE7,0xA6,0x6B,0x24,0x4D,0x4F,0x81,0x99,0x2F,0x3E,0x4F,0x58,0x20,0x8B,0x3E, -0x08,0xF8,0x46,0x02,0xD4,0x75,0xD3,0x6C,0xBD,0x32,0xA4,0xAD,0xD7,0x8B,0x3A,0xD0,0x17,0xCF,0x02,0xA0, -0xA7,0xCD,0xCD,0x06,0x23,0x72,0xBD,0x7E,0xF9,0xA0,0x96,0xAE,0xEA,0x34,0xE9,0x6C,0xE8,0xB1,0x82,0x06, -0x99,0x55,0xCB,0x40,0x3C,0x5A,0x38,0xBA,0x25,0xBA,0x07,0xB2,0xE7,0x43,0xDB,0xD0,0x31,0x55,0xB7,0xEF, -0x79,0x1E,0xBD,0xF2,0xAF,0x65,0xC7,0xB8,0xB9,0x89,0xDA,0x45,0x8F,0xE1,0x58,0x12,0x28,0x0E,0x94,0x23, -0xD9,0xAB,0x82,0x2C,0xC0,0x96,0x63,0xBD,0x1A,0x9D,0x9E,0xD8,0x09,0x4A,0xC1,0xE3,0xA8,0xD9,0x0C,0x12, -0x91,0x12,0xB0,0xAD,0xED,0x17,0x47,0x8D,0x6A,0x5C,0x7E,0x29,0xE4,0xF2,0xA5,0x95,0x1A,0x82,0x9C,0x6A, -0x72,0x45,0x0E,0x2F,0x5E,0xEF,0x20,0xF5,0x24,0x65,0x1A,0xAA,0xA3,0x48,0xD2,0x0C,0xE2,0xFC,0x36,0xD7, -0xD7,0xF7,0x96,0x3C,0x24,0x59,0xB3,0x0B,0x69,0xB9,0xFC,0xDF,0xB4,0xD8,0xB2,0x1C,0x29,0x72,0xAB,0x05, -0xB5,0xFA,0xBA,0x52,0x19,0x47,0x36,0x4C,0x75,0x61,0xCD,0xEA,0xEB,0xA8,0x43,0x66,0x21,0x54,0xB7,0xE8, -0x3F,0xF5,0x10,0x5A,0x7A,0x08,0x7D,0x18,0x20,0xF0,0x5D,0xCB,0xDB,0xAB,0x53,0x06,0x13,0xE0,0xEC,0x66, -0x50,0x45,0x11,0x80,0xC8,0x18,0xD2,0x02,0x7C,0xCA,0xE4,0xFA,0x27,0x74,0x8B,0xD4,0xE3,0x5D,0x0D,0x5D, -0x1F,0x2A,0xE4,0x76,0xFF,0x37,0x18,0x55,0x3B,0xDB,0x81,0x28,0x83,0xE1,0xC3,0x78,0xC2,0x5B,0xE1,0xA9, -0x8E,0x59,0xCD,0xE8,0x04,0xEE,0xBA,0x2C,0x0C,0xCB,0x1B,0xFA,0x6D,0xBA,0xDE,0xE6,0xE6,0xA3,0xBE,0xD7, -0x08,0x44,0x0A,0xA3,0x79,0x7B,0xD6,0xB7,0x2B,0xED,0x86,0x66,0x7D,0xFA,0x97,0xFE,0x87,0xF7,0x33,0x3B, -0x2B,0x5B,0x77,0x70,0xF3,0xC6,0x4C,0xD7,0x45,0xB6,0xF2,0x23,0x8C,0xD2,0x91,0xE8,0x12,0x55,0x86,0x58, -0x2A,0x03,0x7A,0xD2,0x75,0x0D,0xD0,0x58,0x4F,0xBE,0x12,0xDB,0x42,0x0F,0x80,0x50,0x41,0x29,0x40,0xA9, -0xC7,0x80,0x66,0x63,0x11,0xC1,0x22,0x82,0x86,0x87,0x51,0x76,0x83,0x48,0x73,0x3B,0x01,0x08,0x29,0xBE, -0x4C,0x86,0xBE,0xCE,0x2A,0x0C,0x21,0x09,0xD5,0x10,0x65,0x7E,0xB3,0x78,0x08,0xAB,0x9F,0x21,0x70,0xE9, -0x37,0xC5,0x05,0xD9,0x90,0x68,0x99,0x28,0x08,0x46,0x38,0xCB,0x24,0xE3,0x42,0xB0,0xB7,0x2C,0x00,0xB9, -0x00,0xAD,0x17,0xC3,0x48,0x1C,0x04,0x22,0x0A,0xC0,0x38,0xC4,0x71,0x01,0xE1,0x30,0x14,0x20,0x24,0x40, -0x5F,0x4B,0x5D,0x8D,0x64,0xE1,0x45,0xE8,0xCC,0xEB,0xF7,0x1C,0xEB,0x21,0xD9,0x8B,0x0C,0x8F,0xD8,0x94, -0x8F,0xD1,0x24,0x33,0x36,0x1C,0x73,0xCD,0x0E,0x00,0x8D,0x20,0x9C,0x18,0x5B,0xE6,0x7A,0xF4,0x0F,0x2C, -0xBD,0xC1,0xA9,0xB1,0xD1,0x2F,0xF8,0x39,0x86,0x82,0x29,0x82,0xBF,0x7C,0x08,0x6A,0xBF,0xC5,0x6F,0x08, -0xC5,0x05,0xE5,0x0C,0x90,0x43,0x36,0x3F,0x4B,0x09,0xE5,0x6F,0x65,0x5F,0x58,0x60,0xF9,0xEA,0xB9,0x42, -0x86,0xA0,0xF2,0x1D,0x63,0x21,0xA2,0x99,0xDB,0x7A,0xCD,0xB0,0x26,0x60,0x2F,0x08,0xAE,0xEE,0x62,0x4E, -0xA8,0xAB,0x1F,0xF2,0x34,0xEA,0x8E,0x74,0x2B,0x46,0x3E,0x4C,0xD4,0x1E,0x98,0x2F,0x2D,0xE1,0xB5,0x6E, -0x33,0x9A,0x6C,0xD4,0x93,0xBA,0x80,0x5E,0xFB,0xD4,0x53,0xBF,0x5C,0x08,0xE0,0x41,0xC4,0x26,0x86,0x78, -0x9A,0x5E,0x08,0x8F,0x77,0xE9,0xD2,0x14,0xE9,0xE9,0xCB,0xAF,0x32,0x3E,0x84,0x5D,0x6E,0xE1,0xC6,0xA3, -0x52,0x47,0xD7,0xC5,0x5B,0x0D,0xE0,0xA1,0xE0,0x94,0x46,0xF7,0x2E,0xA4,0xC5,0xBF,0x90,0x3A,0xA7,0x01, -0xFB,0x92,0xD4,0x1F,0x57,0xA4,0xFE,0xB8,0x4E,0x6A,0xDC,0xB6,0x16,0x4C,0x2E,0x80,0xEC,0x5B,0x44,0xD1, -0x0C,0xA7,0xB0,0x20,0x0E,0x01,0x03,0xFC,0x33,0xCE,0x52,0xFC,0x65,0xCE,0x46,0x21,0x99,0xF2,0x55,0xFE, -0xD4,0xEA,0xBF,0xE3,0x32,0xC5,0x8F,0x70,0x59,0x16,0x98,0x55,0xDE,0xF8,0xEB,0xA7,0x12,0xE9,0xD4,0x1E, -0x98,0xB0,0xE9,0xAE,0xFF,0xC2,0xEF,0xEA,0x13,0xBF,0x9C,0x3E,0xC5,0x87,0x8B,0x97,0x56,0x20,0xEE,0x44, -0xBB,0x2C,0x65,0xF4,0x00,0x2A,0xF8,0x37,0x20,0x82,0xA1,0xAE,0x23,0xF6,0x16,0x4B,0x8B,0x7B,0x06,0xA8, -0x12,0xBA,0x60,0x10,0xCE,0x97,0x75,0xAD,0x1D,0x42,0x8A,0x04,0x25,0x00,0x93,0x90,0x68,0x7B,0x57,0xFB, -0x9B,0xD7,0x1D,0xC8,0x50,0x1E,0x7C,0x98,0x1E,0x0C,0x36,0xAF,0xBF,0x33,0x7B,0x33,0xD2,0xA8,0x89,0x64, -0xAE,0x03,0xBD,0x5E,0xD1,0x6B,0x0F,0x2D,0x21,0x84,0x35,0x73,0x61,0x15,0x59,0x2D,0x2C,0x5F,0xBD,0xE0, -0x23,0x42,0x74,0x06,0x1F,0x32,0x76,0x40,0x78,0x5A,0xF3,0xE5,0x8A,0x9E,0xAB,0x11,0x60,0x35,0x1E,0xAA, -0x74,0x0E,0xFF,0xEA,0xA2,0xBD,0xE2,0x8D,0x60,0xA8,0xC8,0x42,0xDC,0x53,0x83,0x66,0x8C,0x15,0x49,0xBA, -0x34,0x5A,0x01,0x36,0x97,0x7A,0x0E,0xE0,0x29,0xA1,0x38,0xD0,0xAB,0xBC,0xFA,0xF3,0xDB,0x37,0xC7,0x9C, -0x27,0xE7,0x4A,0xB3,0x40,0xAB,0xBD,0x50,0x1B,0xDC,0x5C,0xF0,0xF4,0xBE,0xAC,0xD0,0x84,0xC3,0xAA,0x90, -0xF3,0xF3,0xE9,0xE4,0x13,0xF6,0x21,0x1F,0xBD,0xCD,0x20,0x99,0x6D,0xD9,0x02,0x7D,0x3C,0x3E,0xB3,0x77, -0x6C,0x07,0x4A,0x06,0xD0,0xAB,0x1F,0x0A,0xCB,0x2D,0xFF,0x11,0xF2,0x93,0x7F,0x86,0x4C,0x20,0xEE,0x66, -0x10,0x58,0x4B,0xFC,0x36,0x6E,0x98,0xB2,0xB9,0x44,0x3B,0x4A,0x53,0x61,0x94,0x71,0x48,0x32,0x6D,0x02, -0x8B,0x19,0x4E,0xB5,0x80,0xE1,0x4C,0xA3,0x8C,0x6B,0x59,0x9E,0x24,0x2C,0xE5,0x2B,0xFA,0xB0,0xF5,0xF2, -0xC1,0xE6,0x5D,0x8E,0x73,0x1C,0x14,0xCB,0x38,0x6D,0xEA,0x45,0x16,0x57,0xBF,0x0B,0xB8,0x77,0x75,0x5D, -0x94,0x5A,0x39,0xA5,0x22,0x0F,0x6C,0xF4,0xD5,0x1C,0xA4,0x0B,0x81,0xAA,0x47,0xF3,0x28,0x5A,0x0E,0x56, -0x68,0x41,0xC7,0xC5,0x38,0x13,0xF6,0xF0,0x16,0xBF,0x15,0x57,0xDC,0x5D,0x79,0x51,0x6D,0x53,0x75,0xAC, -0x0D,0x63,0x03,0x6B,0x84,0x66,0x1C,0x51,0x5F,0x98,0x51,0xE9,0xC2,0x2C,0xCB,0x2C,0xB1,0x7D,0x20,0xFC, -0x53,0xDE,0xA5,0x47,0x73,0xBB,0x94,0x8C,0x7A,0xBA,0x2E,0x2A,0x2E,0x2C,0x0A,0x57,0x14,0x67,0x0D,0xB2, -0x55,0xC4,0x36,0xA9,0x57,0x82,0x07,0xF2,0x1D,0xBC,0xBD,0x7F,0x95,0x8D,0xB2,0xCC,0x46,0x00,0xD3,0xCA, -0x7D,0x26,0xED,0x78,0xBA,0xCC,0xD4,0xFB,0xD2,0x75,0xE5,0x05,0x8E,0x31,0x0F,0x59,0xB0,0xAF,0xEF,0xEB, -0xAE,0x0E,0xFF,0x6F,0xEA,0x16,0xEC,0xC2,0xD4,0x07,0xF7,0xBF,0x38,0x7F,0x09,0x21,0x2D,0x61,0x14,0x53, -0x6E,0x20,0x88,0xEC,0x9E,0xDE,0x59,0x03,0x29,0xC9,0x5F,0xA1,0x6B,0x73,0xD0,0x56,0x36,0x9E,0xAF,0x98, -0xB3,0x65,0x0C,0x9B,0x51,0x11,0xE5,0xEE,0x81,0x79,0x8E,0x1F,0xBC,0x63,0x5B,0xF4,0x61,0x3B,0x62,0x2E, -0xB6,0x05,0xCF,0x12,0x6B,0x04,0x58,0xC2,0xF5,0x6A,0x25,0x3F,0x56,0x62,0x51,0xDB,0x47,0x51,0x24,0xBE, -0x7B,0x07,0x5E,0xC5,0x61,0x79,0x66,0x09,0x22,0x19,0x08,0x90,0xE1,0x31,0xBE,0x03,0x97,0x96,0x75,0x92, -0xBA,0x43,0x45,0x5F,0x02,0xA4,0x79,0xE3,0x1A,0x99,0x56,0x35,0xDB,0xDC,0xE4,0x76,0x79,0x4D,0x8C,0x12, -0x29,0x13,0x41,0xDF,0x30,0x45,0xCF,0x61,0x34,0x85,0x14,0x39,0xF4,0x81,0xB6,0x8D,0xB6,0x1A,0x12,0x4C, -0x8D,0x12,0x06,0x9C,0xE5,0x69,0x04,0x91,0x5A,0x54,0x11,0xAD,0x6D,0x19,0xA6,0x01,0x1C,0xE0,0xFE,0x25, -0xB2,0x44,0xA5,0xCD,0x5B,0x31,0xE2,0xA9,0xE2,0xBB,0x4D,0x8F,0x17,0x56,0x39,0xC6,0x32,0xF2,0xB5,0x7F, -0x2C,0x69,0xC9,0x9F,0x39,0x12,0x15,0x98,0x7B,0xF0,0xF0,0x3D,0x9F,0x77,0xC5,0x57,0xEF,0x5D,0x38,0x41, -0xDD,0x82,0x40,0x5F,0xC3,0xA1,0x6A,0xBB,0x2C,0xF1,0x60,0xE1,0xAE,0xB8,0x68,0xAD,0x3F,0x63,0xC5,0x47, -0xDB,0x74,0xDA,0x7C,0x36,0xAC,0xBD,0xBB,0xBD,0x02,0x42,0x13,0x96,0x72,0x03,0x72,0x0D,0xA4,0xA3,0xEA, -0xB4,0xB2,0x03,0x6A,0xC6,0x05,0x3B,0xC9,0xB3,0xD0,0x58,0x00,0xEB,0x2E,0xB7,0x94,0xAE,0x5C,0x6C,0xA9, -0x7B,0xEB,0x52,0xAB,0xBC,0x1F,0x2E,0xA4,0x90,0x56,0xFC,0xF8,0xE3,0x0F,0x39,0xAB,0xAD,0x0D,0xB3,0x15, -0x83,0x2F,0xD5,0x1B,0x6B,0x99,0x19,0xC5,0xA5,0x5F,0x8D,0x55,0xBB,0x3D,0xD5,0xD8,0x94,0xBF,0x4E,0xD0, -0x48,0xE0,0x89,0x24,0xAB,0x17,0x5F,0x41,0xC0,0x70,0x0A,0x71,0xC9,0x86,0x4E,0xA8,0xFA,0x39,0xAA,0x5E, -0xFC,0x1E,0x75,0x15,0x77,0xAF,0x6A,0xCD,0x3C,0xAF,0xAA,0xAB,0x55,0xD4,0x51,0x1B,0xBC,0x47,0x7E,0xB3, -0xA0,0x2B,0x30,0x74,0xAE,0x6A,0x60,0x57,0x67,0x8B,0x73,0xAD,0x62,0x11,0x65,0xF7,0xD4,0x17,0x51,0xB3, -0xA2,0x12,0x82,0xFA,0x5B,0xDD,0xAC,0xDA,0x69,0x2E,0x6B,0xCE,0xC4,0xF3,0x9C,0xC6,0x8A,0xB7,0xEC,0x66, -0xAE,0x07,0xF6,0xA1,0x59,0x16,0xE2,0x96,0x2E,0xAA,0xC9,0x6E,0xB9,0x9A,0x82,0x78,0xB0,0xA1,0xDE,0x95, -0x27,0xEB,0x01,0x2A,0xFD,0xAE,0x2E,0xAA,0xEC,0xBE,0xBA,0x5C,0x76,0x5C,0xD5,0xD7,0x36,0x8D,0x9F,0x9B, -0xD4,0x34,0x88,0x7C,0x90,0x97,0xFB,0xDB,0x6F,0xF4,0x8F,0xA2,0x29,0x8C,0xBD,0x3F,0x01,0x2C,0xED,0xAE, -0xEF,0x83,0x2C,0x00,0x00 +0x56,0xFA,0x02,0x4A,0x42,0x3B,0xCA,0xD8,0x3E,0xC5,0x56,0x62,0x15,0x5B,0xF6,0x2C,0x99,0x40,0xB3,0xFC, +0xF7,0x9D,0x24,0x3F,0x43,0xE8,0x1E,0xDF,0xD6,0x6E,0x8D,0xA4,0xD3,0x9D,0xEE,0x4E,0xF7,0x54,0xB2,0xBB, +0xF1,0xFC,0xF4,0x70,0x7C,0x79,0x76,0xA4,0x85,0x3C,0x8E,0xF6,0x76,0xC5,0xBF,0x5A,0x84,0xE8,0xCC,0xD3, +0x31,0xD5,0xF7,0x76,0x63,0xCC,0x11,0x80,0x78,0xDA,0xC5,0xBF,0xE7,0xE4,0xD6,0xD3,0x0F,0x13,0xCA,0x31, +0xE5,0x5D,0x7E,0x9F,0x62,0x5D,0xF3,0xD5,0xCC,0xD3,0x39,0xBE,0xE3,0x3D,0x81,0x3C,0xD0,0xFC,0x10,0x65, +0x0C,0x73,0x2F,0xE7,0xD3,0xEE,0x33,0x20,0xC1,0x09,0x8F,0xF0,0xDE,0xD1,0xE8,0x4C,0x3B,0x0A,0x08,0x4F, +0xB2,0xDD,0x9E,0x5A,0xD9,0x8D,0x08,0xBD,0xD1,0x32,0x1C,0x79,0x3A,0x4A,0xD3,0x08,0x77,0x79,0x92,0xFB, +0x61,0x97,0x00,0x4D,0x5D,0x0B,0x33,0x3C,0xF5,0xF4,0x1E,0xF2,0xB1,0x0D,0x0B,0xBA,0x26,0x8E,0xF3,0x74, +0x12,0xA3,0x19,0xEE,0xDD,0xA9,0x3D,0x4D,0x02,0x2C,0x4C,0x32,0xEE,0xE7,0x5C,0xFB,0x57,0xD8,0xFF,0x00, +0x89,0xF1,0xFB,0x08,0x2B,0x90,0x92,0xD9,0x67,0x4C,0xD7,0x62,0x1C,0x10,0x04,0x5C,0xF8,0x19,0x16,0x5A, +0x8B,0xD0,0x04,0x47,0x8B,0x69,0x02,0x6A,0x62,0xE4,0x33,0x76,0xFB,0x5B,0xE9,0xDD,0x40,0x4E,0xA7,0x28, +0x26,0xD1,0xBD,0xCB,0x10,0x65,0x5D,0x86,0x33,0x32,0x5D,0xDA,0x7E,0xBC,0xF8,0xDC,0x25,0x34,0xC0,0x77, +0xEE,0x13,0xC7,0x19,0xA4,0x09,0x23,0x9C,0x24,0xD4,0x45,0x13,0x96,0x44,0x39,0xC7,0x83,0x08,0x4F,0xB9, +0xFB,0x14,0x28,0x4C,0x92,0x2C,0xC0,0x99,0xDB,0x4F,0xEF,0x34,0x00,0x91,0x40,0xFB,0x6A,0x7B,0x7B,0x7B, +0x30,0x41,0xFE,0xCD,0x2C,0x4B,0x72,0x1A,0x74,0xFD,0x24,0x4A,0x32,0xF7,0xAB,0xE9,0x53,0xF1,0x77,0x10, +0x10,0x96,0x46,0xE8,0xDE,0xA5,0x09,0xC5,0x80,0x7B,0xD7,0x65,0x21,0x0A,0x92,0xB9,0xEB,0x68,0x8E,0xD6, +0x77,0x80,0x48,0x36,0x9B,0x20,0xC3,0xB1,0xC4,0x5F,0x7B,0xDB,0x1C,0xFC,0x2D,0x7E,0xD5,0xF2,0x1C,0x93, +0x59,0xC8,0xDD,0xEF,0x1D,0x47,0xF0,0xAF,0xE5,0xD1,0x22,0x22,0x8C,0x77,0xA5,0x72,0xD4,0x79,0x3C,0x49, +0x5D,0x47,0xB2,0x0E,0x1F,0x31,0xCA,0x66,0x84,0xC2,0x20,0x45,0x41,0x40,0xE8,0xCC,0x55,0x68,0x11,0x59, +0x54,0xD2,0xC2,0x3D,0x20,0x4E,0x6E,0xF1,0x20,0x26,0xB4,0x3B,0x27,0x01,0x0F,0xDD,0x1D,0x07,0xB8,0xF0, +0xF3,0x8C,0x81,0x4C,0x69,0x42,0x28,0xC7,0x99,0x44,0x63,0x29,0xA2,0x0B,0x25,0xAA,0x50,0x40,0x25,0x27, +0xA1,0x70,0xA3,0xB8,0x3B,0x89,0x12,0xFF,0xA6,0x3A,0x69,0x27,0xBD,0x2B,0xCE,0x72,0xC3,0xE4,0x16,0x67, +0x8B,0x5A,0x5D,0x12,0xBB,0x05,0x6C,0x91,0xC6,0x18,0x2F,0x6D,0x7E,0x9B,0x03,0xD4,0x92,0x9F,0x20,0x65, +0x41,0xB5,0x29,0x52,0x5B,0xF0,0x02,0x85,0xD0,0x34,0xE7,0x8B,0x87,0x57,0x99,0xA4,0xC8,0x27,0xFC,0xDE, +0x75,0xE4,0x36,0x69,0x21,0xEE,0xB6,0xE3,0x68,0x42,0xE1,0xDA,0x7B,0x9C,0x05,0x88,0x22,0x6B,0x98,0x11, +0x14,0x59,0xA3,0x5A,0xE5,0xDD,0x38,0xF9,0xDC,0xCD,0x61,0x0C,0xF3,0x08,0xFB,0x5C,0x69,0x18,0x2E,0x61, +0x72,0x43,0xF8,0x43,0xC0,0x83,0x85,0x86,0xAE,0xA4,0x86,0x42,0x75,0x7B,0x7D,0xD0,0x8D,0xE4,0x43,0x89, +0xAD,0x24,0xEA,0x4E,0x12,0xCE,0x93,0x58,0xDA,0x5B,0x25,0xAD,0x26,0x4D,0xE6,0xD9,0x83,0xEB,0x58,0xAF, +0xFA,0x06,0xF9,0x01,0x28,0x95,0x13,0x1F,0x45,0x5D,0x14,0x91,0x19,0x75,0x63,0x12,0x04,0x11,0x6E,0x98, +0xAC,0x9B,0x67,0x91,0x11,0x20,0x8E,0x5C,0xE5,0x67,0x29,0x9D,0x01,0x94,0xE1,0x9D,0x6D,0x8B,0xBC,0x3F, +0x38,0x3D,0x9F,0x3B,0xAF,0x5F,0xCC,0x92,0x21,0xFC,0x39,0x19,0x5D,0x84,0x47,0x17,0x33,0x18,0x1D,0x88, +0xE9,0xF0,0xDD,0xE1,0xF0,0x1D,0x7C,0x1C,0xF6,0x3B,0x9F,0xA6,0xBF,0x0F,0xC5,0xF2,0x8B,0xE0,0x60,0x7C, +0x71,0x34,0x1C,0xBE,0xEE,0xBD,0x3C,0x99,0x7F,0x78,0xBD,0x23,0xC0,0x07,0x91,0x73,0xFE,0x3E,0x74,0x2E, +0xB6,0x7E,0x88,0x83,0xE3,0x20,0xF4,0xE3,0x8B,0xE1,0xBB,0x0F,0xE7,0xB7,0x97,0xF1,0xC5,0x6C,0xF4,0xA1, +0x1F,0x7E,0xDC,0x7A,0x3F,0xFA,0xF8,0xE1,0xA7,0x1B,0xFC,0xF3,0xF1,0xAB,0x8F,0xE3,0x39,0x20,0x3C,0x4F, +0x46,0x17,0xE7,0x07,0xEF,0x0F,0x66,0x1F,0x0F,0xFC,0xA3,0xBB,0x49,0x74,0x72,0xF0,0x62,0x38,0x19,0x6E, +0xF9,0x18,0xCF,0xC6,0xE7,0x07,0xF9,0xCB,0xD7,0xA7,0x33,0x42,0xC2,0xD1,0xC7,0x93,0xB1,0x7F,0xF8,0xF4, +0xCD,0xC5,0xF1,0x90,0x84,0x27,0xAF,0xCE,0x9D,0x9B,0x17,0xAF,0x0F,0x9F,0xFB,0x97,0xAF,0x2E,0x77,0x9E, +0x3F,0xE9,0x7D,0xFF,0xFD,0xDB,0xE0,0x94,0xD0,0xF1,0xED,0xE7,0xE1,0xEC,0x70,0xFE,0xEC,0x9E,0x8D,0xC3, +0x97,0xB7,0xB4,0xF7,0x3E,0xF9,0xF4,0xF2,0xFE,0x2D,0xFC,0x7F,0x76,0xD6,0x99,0x8C,0xFA,0xEC,0xE2,0xDD, +0xCB,0xF7,0x5B,0xEC,0x87,0xA7,0xE9,0xC1,0xF3,0xE7,0xB7,0xF1,0xE4,0xAC,0x17,0x07,0x37,0x53,0xFE,0xEC, +0x09,0x4F,0x2F,0x67,0xF9,0xC7,0xDF,0x9F,0xBE,0x0A,0x7B,0xA7,0x18,0x5D,0x86,0x9D,0xFB,0xCF,0xF7,0xCF, +0xC2,0xF1,0xF1,0xED,0x49,0x84,0xEE,0x4E,0x4E,0xFC,0xCF,0x71,0x27,0x42,0x3F,0x9C,0x8E,0x23,0x94,0xF5, +0x2F,0x82,0x61,0xAF,0x73,0xB8,0x35,0xDC,0xE6,0xD9,0xF9,0x21,0x7D,0xFE,0xE4,0xD3,0xE8,0xD9,0xC1,0x41, +0x3F,0x99,0xFC,0xBE,0xF5,0xE2,0x66,0xE7,0xC5,0xC5,0xCE,0xBB,0xC9,0xBB,0xE1,0x68,0xFB,0xE0,0x02,0x5D, +0x8E,0xDE,0x0D,0xA7,0xDB,0x93,0x30,0x7C,0xFD,0x7A,0xFC,0x53,0x30,0xFC,0x9C,0x0D,0x4F,0xE7,0xC3,0xBB, +0xA3,0x8B,0xE1,0x71,0xE7,0xF5,0xD1,0x5B,0xA7,0x3F,0xBA,0x7C,0x32,0x7B,0xBB,0x33,0x3F,0x60,0x47,0xC3, +0x77,0x07,0xCE,0xEC,0x55,0x27,0x46,0x1F,0x93,0xC3,0x27,0xB3,0x97,0x3B,0xE4,0xEC,0x12,0x0D,0x5F,0x1E, +0xBC,0x62,0xE4,0x3C,0x3E,0xBE,0x70,0x86,0xC3,0x37,0xA7,0xF8,0xA7,0xC3,0x27,0xE8,0xF5,0x96,0xFF,0x01, +0xF4,0x7F,0xF1,0x33,0xFE,0xBE,0x33,0x9C,0x9F,0x3A,0x91,0xFF,0x03,0x1E,0x1F,0x5F,0x8E,0xE5,0xED,0x1C, +0x45,0x3F,0x8D,0x6F,0x46,0xF9,0xBB,0xF8,0xF0,0xD0,0xD4,0x68,0xD2,0xCD,0x70,0x8A,0x11,0x6F,0xC6,0xAA, +0xCA,0x39,0xC0,0xB6,0x6A,0x2B,0x2C,0x9C,0x54,0x44,0xD6,0x6E,0x80,0xFD,0x24,0x43,0x72,0x0F,0x20,0xE0, +0x4C,0x98,0xD8,0xF2,0x47,0x19,0x6A,0x35,0x15,0x69,0x35,0x44,0x03,0xCD,0x28,0x1D,0x21,0x26,0x14,0x70, +0x6E,0x89,0x8F,0xBB,0x29,0xB9,0xC3,0x51,0x57,0x22,0xBB,0x8E,0xB9,0x90,0xCE,0x56,0x6E,0x43,0x94,0xC4, +0x8A,0x6A,0xB9,0x10,0x7C,0x42,0xBE,0x48,0x69,0xE0,0x32,0x31,0x7C,0x16,0xBE,0x93,0x64,0xDD,0x49,0x3E, +0x9B,0x92,0x3B,0xF0,0xE6,0x29,0xA1,0x84,0x63,0xAD,0xCF,0x96,0x3F,0x96,0x64,0x6E,0xF0,0xFD,0x34,0x43, +0x31,0x66,0xDA,0xDF,0x24,0xB3,0x98,0x66,0x49,0xBC,0xA8,0x23,0x20,0x4F,0x1A,0x93,0xE5,0xF2,0xAB,0x3C, +0x8D,0x12,0x04,0x62,0xAE,0x09,0x1B,0x2A,0x98,0x66,0xC2,0xAD,0xAA,0xA0,0x5A,0xBA,0xD9,0x16,0xB8,0x65, +0xCB,0xAD,0xB7,0xB6,0x6B,0xD7,0xED,0xCA,0xBD,0x22,0xD8,0x37,0x55,0xDF,0x88,0x07,0x8D,0x58,0xF7,0x15, +0x07,0x95,0xAE,0x3F,0x5C,0x1D,0xA2,0x22,0x43,0xCD,0x80,0x8A,0xD2,0xFD,0x1D,0xA7,0x11,0x2A,0x60,0xDF, +0xF2,0x2B,0x2C,0xD3,0xBC,0xF5,0x55,0x9A,0xC1,0x6D,0xE0,0xF9,0x17,0x68,0x56,0x32,0xB5,0x69,0x03,0xCD, +0x2A,0xDD,0x29,0x11,0xEA,0x9C,0x27,0x79,0xAD,0x48,0x3F,0x94,0x0A,0xC0,0x15,0x37,0x4F,0x05,0x37,0x5F, +0xD4,0xEA,0x93,0x9D,0x6F,0x0A,0x1E,0xB6,0x9D,0x6F,0x96,0xB6,0xDA,0x5B,0xE5,0xE3,0xBE,0x03,0x7F,0xCA, +0xB4,0xFB,0xAC,0x66,0x61,0xF2,0x54,0xFC,0x2D,0x19,0x04,0x3A,0x4D,0xE0,0x93,0xED,0x1F,0x9E,0x05,0x93, +0x12,0xA8,0x04,0x7B,0x1C,0x9E,0xA1,0x80,0xE4,0xCC,0x7D,0xEA,0x7C,0xA3,0xF4,0x09,0xD7,0x07,0xB2,0x97, +0x97,0xAB,0x26,0xB5,0xC5,0xB2,0x94,0x50,0x6D,0x8B,0x69,0xE2,0xBE,0x51,0x56,0x19,0x66,0x33,0xD5,0x83, +0x8B,0xD4,0xA6,0x29,0xF6,0x2F,0x9C,0x6F,0x16,0x3C,0x43,0x94,0x4D,0x93,0x2C,0x76,0xB3,0x84,0x23,0x8E, +0x0D,0xC7,0x5C,0xF6,0x9D,0x75,0x80,0x27,0x3B,0x4E,0x80,0x67,0xE6,0x72,0xB9,0xDB,0x93,0x49,0x0D,0x2A, +0x1E,0x3F,0x23,0x29,0xDF,0x9B,0xE6,0xD4,0x17,0x3C,0x68,0x33,0x6C,0x60,0x73,0x91,0x61,0x9E,0x67,0x54, +0x0B,0x12,0x3F,0x17,0xC6,0x6E,0xCF,0x30,0x3F,0x52,0x76,0x7F,0x70,0xFF,0x32,0x80,0x1D,0xCB,0x0A,0xC1, +0x5F,0x8B,0x00,0x0E,0x0C,0xE7,0x15,0x38,0xAD,0xFD,0x90,0x60,0x80,0xC8,0x6B,0x7C,0x6F,0x60,0x8B,0x57, +0x88,0xD8,0x16,0xEB,0x86,0x51,0x6E,0x03,0x20,0x35,0x17,0xB7,0xA0,0x05,0xE4,0xE1,0x2B,0x7E,0x6D,0x11, +0x8F,0xC2,0xC7,0xA0,0xD8,0x4E,0xF6,0xD0,0x7E,0xB7,0xEF,0xA2,0x3D,0xB2,0xDF,0x07,0xFF,0x32,0x1B,0xF4, +0xD5,0xC9,0x3F,0x91,0x08,0x5F,0x14,0x2E,0x27,0x0E,0xAA,0xA9,0xF5,0x0C,0x72,0x16,0x82,0x22,0xCD,0xEF, +0x8C,0xD3,0x91,0x66,0x5C,0x7D,0xDF,0xFD,0xE1,0xFA,0x8F,0xFE,0x95,0xD3,0xED,0x5F,0x9B,0xBF,0x99,0x3D, +0x62,0x73,0xCC,0xB8,0x41,0xD1,0x2D,0x99,0x21,0xB0,0x73,0x5B,0xE4,0xDB,0xE1,0x0C,0xA4,0x30,0x07,0xD5, +0x19,0x44,0xB1,0xB7,0xE5,0x38,0x1B,0x1E,0xDE,0x47,0x11,0x06,0xD6,0xF5,0xA3,0xF3,0xF3,0xD3,0xF3,0x2B, +0xBD,0x83,0x3B,0xFA,0xB5,0xAB,0xE9,0x1D,0x6A,0xBA,0xDC,0x86,0xA2,0x33,0xC3,0x2C,0x3C,0x43,0x3C,0x34, +0x02,0xFB,0x16,0x45,0x39,0xE8,0x42,0x30,0x92,0x78,0xA0,0x38,0x7D,0x92,0x83,0xFD,0x50,0xDD,0x1C,0x24, +0x36,0xA1,0x14,0x67,0xC7,0xE3,0xB7,0x6F,0x3C,0xFD,0x5C,0x21,0x69,0x6F,0x08,0xE3,0xBA,0x25,0x6F,0xC4, +0x46,0x69,0x8A,0x69,0x70,0x18,0x92,0x28,0x30,0x12,0x73,0x20,0x48,0xF8,0x92,0x84,0x2C,0x46,0x80,0x82, +0x6F,0xAB,0xB2,0x75,0x0A,0x92,0xEB,0x96,0x6F,0xC7,0x79,0xC4,0x49,0x1A,0x61,0x6F,0xA3,0x0F,0x33,0x8A, +0x62,0x80,0x89,0x54,0x2C,0x60,0x24,0xF0,0x74,0x15,0x90,0x54,0x18,0x5B,0x7B,0x8A,0xAF,0x4E,0x09,0x5A, +0xA7,0x04,0x4D,0xDC,0x14,0xA4,0xD2,0xAD,0xC0,0xAE,0xEB,0x65,0x98,0x15,0x47,0x95,0xB0,0x00,0x4F,0x11, +0x70,0xF2,0x5E,0x48,0x0E,0xE5,0xF7,0xBA,0x83,0x02,0x75,0x10,0x6B,0x6B,0x84,0x35,0x35,0xA2,0xAE,0x72, +0x1D,0x32,0x53,0xC8,0x59,0x1B,0x39,0x6B,0x22,0x1F,0x4A,0x8B,0x58,0x87,0x9C,0x29,0xE4,0xA8,0x25,0x62, +0x24,0x45,0x54,0x51,0xAE,0x2B,0xB4,0x09,0x02,0x01,0x76,0xD4,0x14,0x13,0x66,0xE0,0x94,0x68,0x12,0xE1, +0xC0,0xDB,0x70,0x60,0x26,0x0A,0x6B,0x6F,0xCB,0x59,0x73,0x46,0xA4,0xCE,0xC8,0x5B,0x67,0xE4,0xF2,0x0C, +0x92,0x82,0x12,0x21,0x77,0xE8,0x56,0x2E,0xB5,0xD6,0x5E,0x51,0xC7,0xF9,0x21,0xF6,0x6F,0x26,0x89,0x5C, +0x91,0x63,0x71,0xE2,0x06,0x92,0x34,0x53,0x49,0x53,0xB6,0x23,0x40,0x33,0xB5,0xC1,0xD3,0x3D,0x41,0xD9, +0x4A,0x9B,0xE2,0x6B,0xC3,0x88,0xDB,0xBA,0x44,0x88,0xDB,0x5A,0x8A,0x5B,0xDB,0x46,0xE8,0x16,0x6B,0xEB, +0xB4,0x14,0x9B,0x6B,0x16,0xD3,0x75,0x8B,0xB9,0x69,0x65,0x76,0x42,0xFD,0x88,0xF8,0x37,0x5E,0xED,0xCA, +0xE6,0xC2,0x68,0x4E,0x04,0x27,0xDC,0xA3,0x78,0xAE,0xFD,0x04,0xA1,0xE9,0x39,0xE2,0x68,0xC0,0x0B,0x32, +0x46,0x61,0x37,0x18,0x08,0x41,0x47,0x8A,0x19,0x67,0x36,0x0A,0x60,0xF9,0xEC,0x62,0xAC,0x5B,0x7A,0x4F, +0xDC,0x8A,0x0E,0xDE,0x4C,0xCC,0xA5,0x59,0xF9,0x93,0x45,0x65,0x64,0xBF,0xC8,0xA2,0x7A,0x09,0x06,0xA5, +0xC5,0x2D,0xAD,0x78,0x2D,0x4F,0x64,0x6A,0x54,0x2A,0x2D,0x99,0x12,0xDD,0xA1,0x38,0xC3,0x28,0xEE,0x5F, +0x37,0x21,0xF4,0x29,0xE3,0x35,0x4C,0x0B,0xB5,0x99,0x46,0x15,0xD3,0x19,0x9A,0x97,0x46,0xA2,0xCE,0x1F, +0x28,0x17,0x77,0x20,0x03,0x53,0xC6,0x35,0xEC,0x6D,0x3B,0x3F,0xEC,0x0C,0xE0,0x7E,0x0C,0xE5,0xB8,0x00, +0xD8,0xE5,0x36,0x98,0xD6,0x8C,0x87,0x03,0xBF,0xE3,0x15,0x5A,0x09,0x3C,0x6E,0xB3,0x7C,0xC2,0x78,0x06, +0xF9,0xCD,0xF0,0x2D,0xBF,0x83,0xCD,0xF6,0x31,0x7A,0x27,0xB1,0x02,0xD3,0x4A,0x3A,0x9D,0xE5,0x8A,0x82, +0x4E,0x47,0x0D,0x0D,0x21,0xA1,0x21,0x1C,0x31,0xAC,0x51,0x1B,0xDF,0x61,0xFF,0x30,0x89,0x63,0x24,0x48, +0x30,0xB8,0xE4,0x62,0xA2,0x9B,0x4B,0x2B,0x59,0xAB,0x99,0x47,0xC2,0x96,0xC5,0x1E,0xD3,0x23,0x84,0x41, +0xCF,0xB7,0x85,0xAF,0xB0,0x42,0xA8,0x2F,0xDF,0x72,0x19,0x88,0x14,0xCA,0x95,0x73,0x6D,0x55,0x17,0xB7, +0x56,0xAA,0xFA,0xDE,0xA5,0xD5,0xB5,0xE2,0x8F,0x59,0xDF,0xB4,0x80,0xB5,0xE3,0x5A,0x0D,0xD5,0x97,0x4B, +0xCB,0x17,0xFC,0x87,0x88,0xCE,0xF0,0xDF,0x17,0xA0,0xE6,0x51,0xBA,0xA8,0x45,0x21,0x81,0xEC,0xBB,0xBF, +0xD8,0xC6,0xD5,0xAF,0xF6,0x75,0xC7,0x34,0xF7,0xBF,0xEE,0x49,0x0D,0x1B,0xDC,0xBC,0xEA,0x5F,0x5B,0x08, +0xC0,0xF6,0x77,0xE6,0x2F,0xB6,0x04,0xB7,0x60,0x83,0xDB,0x84,0x04,0x9A,0x38,0x49,0x78,0x76,0x32,0xD5, +0xD0,0xE6,0xA6,0x01,0x26,0xD7,0x32,0xD6,0x0E,0xEF,0xE8,0x36,0xE4,0x8E,0xE5,0x72,0x35,0xA3,0x8D,0x33, +0x8C,0x55,0xCA,0xAC,0x00,0x92,0x7B,0x90,0x79,0x35,0x58,0x55,0x52,0x63,0xAB,0x86,0xC2,0xA2,0x4C,0xF9, +0x76,0x51,0x4D,0x78,0xBA,0x28,0x27,0x20,0xAC,0xAC,0x2E,0xCB,0x36,0x0F,0xD6,0x1B,0xC1,0xE1,0xDB,0x5D, +0x12,0xCF,0x34,0x96,0xF9,0x9E,0xBA,0x8A,0x7D,0xF1,0x8F,0xF7,0xAD,0x48,0x75,0x9B,0xBF,0xF9,0x13,0x4F, +0xEF,0xC0,0xFD,0x62,0x9B,0x26,0x73,0xC3,0xEC,0x7C,0xAB,0x6B,0x92,0xA2,0xA7,0xC7,0xE8,0xAE,0x68,0xF6, +0x45,0x35,0x32,0xD0,0x60,0x5E,0x75,0xA7,0x6A,0x41,0xB5,0xD9,0x28,0xE7,0xC9,0x40,0x2B,0xAB,0x1C,0xD5, +0x66,0xEA,0x5A,0x6F,0xEF,0xDB,0x5A,0x07,0x08,0x44,0x47,0xEA,0x4E,0x88,0x0C,0x62,0xB9,0x08,0x79,0xB8, +0x15,0x7D,0x48,0xE1,0x76,0x2A,0x2A,0x12,0x80,0x93,0x95,0xB4,0x69,0x05,0x06,0x32,0xF7,0x8D,0x56,0xB2, +0xDD,0x15,0x8D,0xC9,0xDE,0x99,0xAA,0x38,0x77,0x7B,0x72,0xA6,0xAF,0x73,0x0C,0xD0,0x3C,0x05,0x74,0xAB, +0xAA,0x71,0x26,0x49,0x70,0xDF,0xA8,0x8C,0xD8,0xC1,0xFD,0x61,0x84,0x18,0x3B,0x41,0x31,0x9C,0xEF,0xC7, +0xBA,0x59,0x98,0xD2,0x9E,0xB3,0xB9,0xD9,0x46,0xCA,0x70,0x0C,0x8D,0x90,0xE2,0x0A,0x43,0x28,0x73,0x7D, +0x20,0xBC,0xB9,0xB9,0x8E,0x31,0xF1,0xA8,0xF6,0x25,0xAE,0x28,0xB8,0x6B,0x19,0xFE,0xFE,0x27,0xEE,0x54, +0x82,0x7D,0x4C,0xAB,0x19,0xF8,0xEC,0x43,0xB6,0x9F,0x27,0x73,0x2A,0xB8,0xAA,0x58,0xCF,0xD6,0x28,0xB4, +0xCE,0x0B,0x95,0x25,0x07,0x05,0x5E,0x77,0x9A,0x29,0x43,0x6E,0x18,0x5D,0x09,0x03,0x73,0xC3,0x4B,0xF3, +0xFF,0x11,0x56,0xD5,0x03,0x8F,0xC9,0x1A,0x99,0x56,0xB4,0x46,0x56,0x1C,0x61,0x8E,0x2B,0x49,0xA3,0xB5, +0x92,0xB2,0xFF,0x87,0xDF,0xDA,0x43,0x88,0x2A,0x73,0x9B,0x3E,0x12,0x90,0x5B,0x1D,0x72,0x85,0xD7,0xA6, +0xC0,0xFC,0x2C,0x89,0xA2,0x71,0x92,0xEE,0x3F,0xB2,0xEE,0x56,0xEB,0xC5,0xA0,0x64,0xB3,0xDE,0x62,0xF9, +0x6B,0x89,0xBE,0xC1,0x53,0xBE,0xFF,0x18,0xE0,0x71,0xB2,0xF5,0x1E,0x2B,0xF0,0xB0,0x0D,0xCA,0x83,0xD5, +0x9F,0x3B,0xBE,0xC5,0xAA,0xD9,0x65,0x27,0x81,0xBB,0xF0,0x4B,0x25,0x79,0x42,0x49,0x16,0x59,0x1B,0xBA, +0xEA,0x75,0xD1,0x5B,0x7A,0x41,0x47,0x4F,0xEF,0xEA,0x35,0x9E,0xA4,0x1E,0x53,0x4B,0xC8,0x20,0x16,0x5F, +0xB9,0x94,0x75,0x01,0x25,0xF3,0x88,0x9D,0x4C,0xA7,0x0C,0xF3,0x0F,0x22,0x98,0x59,0x51,0x35,0x3F,0x96, +0xC1,0x6C,0x00,0x53,0x1A,0x27,0x39,0xC3,0x49,0xCE,0xDB,0x65,0x4F,0x25,0xCC,0x6E,0xF0,0xC7,0x1F,0xD5, +0x64,0x2F,0xE8,0x64,0xF5,0xF4,0x72,0x97,0x35,0x26,0x7B,0xAC,0x13,0x41,0x28,0xF8,0x8F,0x2D,0x85,0x34, +0x2D,0x25,0x11,0xB1,0xD4,0x4A,0x94,0xA5,0xB0,0xDA,0xD6,0x99,0x28,0x4A,0x51,0xC3,0xDB,0x85,0x41,0xEB, +0x66,0xD9,0x73,0x35,0xBD,0x1C,0x59,0x6C,0x35,0x08,0xAC,0x2F,0x0E,0x7C,0x43,0x50,0x05,0xAD,0xBF,0x49, +0xE6,0x38,0x3B,0x44,0x0C,0x1B,0x90,0x33,0xAB,0x88,0x25,0xA1,0xA6,0x1B,0xAC,0xD9,0x05,0x4A,0xA0,0x0A, +0x5C,0x14,0x1E,0x09,0x15,0xA5,0x37,0xC8,0x97,0xB7,0x4E,0xC0,0xB6,0x78,0x2D,0x00,0xA9,0x9F,0xAB,0x4E, +0x03,0xEA,0x34,0x6C,0x33,0xB8,0xE6,0xB3,0x2C,0x49,0xD1,0x4C,0x76,0xD6,0xB0,0x26,0xDC,0xA3,0xA4,0xD6, +0x48,0xAD,0x55,0x3D,0x2A,0xD3,0xFA,0xC3,0xAC,0x8E,0x65,0xE6,0x86,0x0A,0x61,0x35,0x79,0x73,0x93,0xCD, +0x09,0xF7,0x43,0xE1,0xDB,0x3E,0x30,0xAC,0x73,0x68,0x0B,0x5C,0x39,0x0A,0x79,0x5C,0x8F,0xA2,0x62,0xF8, +0x89,0x15,0x03,0x9F,0x95,0xA3,0xBB,0x06,0x30,0xA1,0x25,0x38,0xA1,0xD3,0x62,0x48,0x28,0x29,0xE9,0x94, +0xC0,0xF2,0x33,0x4D,0x8B,0x51,0x1A,0x96,0xA3,0x10,0xDF,0x55,0x78,0x49,0x09,0x0D,0xB0,0xEE,0xAA,0xEB, +0xDB,0x70,0x96,0xC5,0xA0,0x5F,0x8B,0x1F,0xFC,0x77,0xE2,0xA7,0x74,0x56,0x0A,0x93,0x96,0xA3,0x19,0x29, +0x45,0x99,0xC4,0xE9,0x17,0x19,0x61,0xFF,0xB6,0x2F,0x78,0x7E,0xF4,0xE6,0x68,0x7C,0xD4,0x2C,0x11,0x9B, +0x4F,0x08,0xFC,0xAF,0x7A,0x74,0x6E,0xBA,0x46,0xDA,0xF4,0x14,0x98,0xF9,0xE2,0xF3,0x24,0x09,0x64,0xD1, +0x07,0x01,0xDF,0x48,0x81,0xBA,0x6E,0x9A,0xAD,0x57,0x86,0xAC,0xF5,0x7A,0x51,0x07,0xFA,0xE2,0x59,0x00, +0xF4,0xB4,0xB9,0xD9,0x60,0x44,0xAE,0xD7,0x2F,0x1F,0xD4,0xD2,0x55,0x9D,0x26,0x9D,0x0D,0x3D,0x56,0xD0, +0x20,0xB3,0x6A,0x19,0x88,0x47,0x0B,0x47,0xB7,0x44,0xF7,0x40,0xF6,0x7C,0x68,0x1B,0x3A,0xA6,0xEA,0xF6, +0x3D,0xCF,0xA3,0x57,0xFE,0xB5,0xEC,0x18,0x37,0x37,0x51,0xBB,0xE8,0x31,0x1C,0x4B,0x02,0xC5,0x81,0x72, +0x24,0x7B,0x55,0x90,0x05,0xD8,0x72,0xAC,0x57,0xA3,0xD3,0x13,0x3B,0x45,0x19,0x78,0x1C,0x35,0x9B,0x41, +0x22,0x52,0x02,0xB6,0xB5,0xFD,0xE2,0xA8,0x51,0x8D,0xCB,0x2F,0x85,0x5C,0xBE,0xB4,0x32,0x43,0x90,0x53, +0x4D,0xAE,0xC8,0xE1,0xC5,0xEB,0x1D,0xA4,0x9E,0xB4,0x4C,0x43,0x75,0x14,0x49,0x9B,0x41,0x9C,0xDF,0xE6, +0xFA,0xFA,0xDE,0x92,0x87,0x84,0x35,0xBB,0x90,0x96,0xCB,0xFF,0xCD,0x1B,0x5B,0x96,0x23,0x45,0x6E,0xB5, +0xA0,0x56,0x5F,0x57,0xAA,0xCB,0x91,0x0D,0xD3,0xA2,0x8E,0x90,0xB5,0x39,0xEA,0x90,0x59,0x08,0xD5,0x2D, +0xFA,0x4F,0x3D,0x84,0x96,0x1E,0x42,0x1F,0x06,0x08,0x7C,0xD7,0xF2,0xF6,0xEA,0x94,0xC1,0x04,0x38,0xBB, +0x19,0x54,0x51,0x04,0x20,0x32,0x86,0xB4,0x00,0x9F,0x98,0x5C,0xFF,0x84,0x6E,0x91,0x7A,0xBC,0xAB,0xA1, +0xEB,0x43,0x85,0xDC,0xEE,0xFF,0x06,0xA3,0x6A,0x67,0x3B,0x10,0x31,0x18,0x3E,0x8C,0x27,0xBC,0x15,0x9E, +0xEA,0x98,0xD5,0x8C,0x4E,0xE0,0xAE,0x85,0x37,0x6B,0xBC,0xA1,0xDF,0x86,0xEB,0x81,0x41,0x3E,0xEA,0x7B, +0x8D,0x40,0xA4,0x30,0x9A,0xD6,0xB3,0xBE,0x5D,0x69,0x37,0x34,0xEB,0xD3,0xBF,0xF4,0x3F,0xBC,0xCF,0x6C, +0x56,0xB6,0xEE,0xE0,0xE6,0x8D,0x99,0xAE,0x8B,0x6C,0xE5,0x47,0x18,0x65,0x23,0xD1,0x25,0xAA,0x0C,0xB1, +0x54,0x17,0xE8,0x49,0xD7,0x35,0x40,0x63,0x3D,0xF9,0x4A,0x6C,0x83,0x1E,0x60,0x7F,0x05,0xA4,0x00,0xA4, +0x5E,0x02,0x24,0x1B,0x8B,0x08,0x16,0x11,0xF4,0x3B,0x09,0x4D,0x6E,0x10,0x69,0x6E,0x27,0x00,0x21,0xC5, +0x77,0xC9,0xD0,0xD6,0x59,0xC5,0x3D,0x48,0x42,0x35,0x44,0xDD,0xBE,0x59,0xBC,0x83,0xD5,0xAF,0x10,0xB8, +0x74,0x9B,0xC2,0x3E,0x36,0x24,0x1A,0x13,0xF5,0xC0,0x08,0x33,0x26,0xF9,0x16,0x72,0xBD,0x4D,0x02,0x10, +0x0B,0xD0,0x7A,0x31,0x8C,0xC4,0x41,0x20,0xA1,0x00,0x8C,0x43,0x1C,0x17,0x10,0x0E,0x43,0x01,0x42,0x02, +0xF4,0xB5,0x54,0xD5,0x48,0xD6,0x5D,0x84,0xCE,0xBC,0x7E,0xCF,0xB1,0x1E,0x92,0xBD,0x60,0x78,0x94,0x4C, +0xF9,0x18,0x4D,0x98,0xB1,0xE1,0x98,0x6B,0x76,0x00,0x68,0x04,0xD1,0xC4,0xD8,0x32,0xD7,0xA3,0x7F,0x48, +0xB2,0x1B,0x9C,0x15,0xC8,0xA2,0x60,0x82,0x7A,0x29,0x12,0x35,0xD3,0x10,0xB4,0x7E,0x8B,0xDF,0x10,0x8A, +0x6B,0xE0,0x28,0x4C,0xE6,0x67,0x19,0xA1,0xFC,0xAD,0x6C,0x0B,0x8D,0x8D,0xBE,0xBC,0x27,0xF5,0x5A,0x21, +0x23,0x50,0xF9,0x8C,0xB1,0x10,0xC1,0xCC,0x6D,0x3D,0x66,0x58,0x13,0xB8,0x2E,0x88,0xAD,0xEE,0x62,0x4E, +0xA8,0xAB,0x1F,0xF2,0x2C,0xEA,0x8E,0x74,0x2B,0x46,0x3E,0x4C,0xD4,0x1E,0x98,0x2F,0x2D,0xE1,0xB4,0x6E, +0x33,0x98,0x6C,0xD4,0x93,0xBA,0x7E,0x5E,0xFB,0xD2,0x53,0x3F,0x5C,0x08,0xE0,0x41,0x94,0x4C,0x0C,0xF1, +0x32,0xBD,0x10,0x0E,0xEF,0xD2,0xA5,0x29,0xB2,0xD3,0x97,0x1F,0x65,0x7C,0x88,0xBA,0xDC,0xC2,0x8D,0x37, +0xA5,0x8E,0xAE,0x8B,0xA7,0x1A,0xC0,0x43,0xC1,0x29,0x8D,0xEE,0x5D,0xC8,0x8A,0x7F,0x21,0x75,0x4E,0x83, +0xE4,0x4B,0x52,0x7F,0x5C,0x91,0xFA,0xE3,0x3A,0xA9,0x71,0xFB,0xB6,0x60,0x72,0x01,0x64,0xDF,0x22,0x8A, +0x66,0x38,0x83,0x05,0x71,0x08,0x5C,0xC0,0x3F,0xE3,0x2C,0xC3,0x5F,0xE6,0x6C,0x14,0x92,0x29,0x5F,0xE5, +0x4F,0xAD,0xFE,0x3B,0x2E,0x33,0xFC,0x08,0x97,0x65,0x7D,0x59,0xA5,0x8D,0xBF,0x7E,0x29,0x91,0x4E,0xED, +0xC1,0x15,0x36,0xDD,0xF5,0x5F,0xF8,0x5D,0x7D,0xE2,0x97,0xB3,0xA7,0xF8,0x70,0xF1,0xD2,0x0A,0x84,0x4D, +0xB4,0xAB,0xD2,0x84,0x1E,0x40,0x01,0xFF,0x06,0x44,0x30,0x94,0x39,0x62,0x6F,0xB1,0xB4,0xB8,0x67,0x80, +0x2A,0xA1,0x09,0x06,0xE1,0x7C,0x59,0xD6,0xDA,0x21,0x64,0x48,0x50,0x02,0x30,0x09,0x79,0xB6,0x77,0xB5, +0xBF,0x79,0xDD,0x81,0x04,0xE5,0xC1,0x87,0xE9,0xC1,0x60,0xF3,0xFA,0x3B,0xB3,0x37,0x23,0x8D,0x92,0x48, +0xA6,0x3A,0xD0,0xEB,0x15,0xBD,0xF6,0xD0,0x12,0x42,0x58,0x33,0x15,0x56,0x81,0xD5,0xC2,0xF2,0xD1,0x0B, +0x3E,0x22,0x44,0x67,0xF0,0x21,0x63,0x07,0xEC,0xA6,0x5E,0xE3,0x2D,0x4A,0xE7,0xF0,0xAF,0x0E,0x61,0x7B, +0x50,0xB0,0x15,0xE0,0x29,0xA1,0x58,0x46,0x2F,0x35,0xB4,0x0A,0x80,0x50,0x03,0xC9,0x24,0xA4,0x1C,0x5B, +0x62,0x2C,0xB2,0x1F,0x99,0x09,0x45,0x1A,0xFA,0x04,0x31,0x2C,0x12,0xBD,0xAE,0x12,0xF6,0x2A,0x78,0x2E, +0x03,0x49,0x63,0xC3,0x9A,0xAF,0x79,0xF4,0xBC,0x18,0xE9,0x20,0x25,0x6F,0x04,0x61,0x25,0x0E,0xC4,0x5B, +0x35,0x58,0x09,0xED,0x75,0x33,0xA2,0xC0,0xE6,0x12,0x5C,0x4C,0x09,0x10,0xE8,0x55,0x3A,0xFF,0xF9,0xED, +0x9B,0x63,0xCE,0xD3,0x73,0x75,0xA3,0x40,0xAB,0xBD,0x50,0x1B,0x9A,0xB9,0xE0,0xD9,0x7D,0x59,0x18,0x8A, +0x40,0xA1,0x42,0xDD,0xCF,0xA7,0x93,0x4F,0xD8,0x07,0x49,0xDE,0x32,0xC8,0xA1,0x5B,0xB6,0x40,0x1F,0x8F, +0xCF,0xEC,0x1D,0xDB,0x81,0x4A,0x05,0xEE,0xD3,0x0F,0x85,0xC5,0x2C,0xFF,0x11,0xF2,0x93,0x7F,0x86,0x4C, +0x20,0xDE,0x33,0x08,0xE8,0x25,0x7E,0x1B,0x37,0xCC,0x92,0xB9,0x44,0x3B,0xCA,0x32,0x61,0x0C,0xE3,0x90, +0x30,0x6D,0x02,0x8B,0x0C,0x67,0x5A,0x90,0x60,0xA6,0xD1,0x84,0x6B,0x2C,0x4F,0xD3,0x24,0xE3,0x2B,0xFA, +0xB0,0xF5,0xF2,0x9D,0xE8,0x5D,0x8E,0x73,0x1C,0x14,0xCB,0x38,0x6B,0xEA,0x45,0xD6,0x74,0xB0,0x0E,0xEE, +0x76,0x75,0x5D,0x54,0x78,0x39,0xA5,0x22,0xFF,0x6C,0xF4,0xD5,0x1C,0xA4,0x0B,0x81,0xAA,0x47,0xF3,0x28, +0x5A,0x0E,0x56,0x68,0x41,0xA3,0x97,0xF0,0x44,0x7E,0x2D,0xB2,0xF8,0xAD,0x70,0x2D,0x77,0xE5,0x21,0xB7, +0x4D,0xD5,0xB1,0x36,0x8C,0x0D,0xAC,0x11,0xCA,0x38,0xA2,0xBE,0xB8,0x46,0xA5,0x0B,0xB3,0xAC,0xEE,0xC4, +0xF6,0x81,0x88,0x0B,0xD2,0x70,0x1E,0x2D,0x29,0xA4,0x64,0xD4,0xD3,0x75,0x51,0xE8,0x61,0x51,0x2F,0xA3, +0x98,0x35,0xC8,0x56,0x99,0xC2,0xA4,0x5E,0x09,0x1E,0xC8,0xE7,0xF7,0xF6,0xFE,0x55,0x36,0xCA,0xEA,0x1E, +0x01,0x4C,0x2B,0xF7,0x99,0xB4,0xE3,0xE9,0xB2,0x42,0xD8,0x97,0x21,0x43,0x1A,0x70,0x8C,0x79,0x98,0x04, +0xFB,0xFA,0xBE,0xEE,0xEA,0xF0,0xDF,0xA6,0x6E,0xC1,0x2E,0x4C,0x7D,0x08,0x3B,0x17,0xE7,0x2F,0x21,0x94, +0xA6,0x09,0xC5,0x94,0x1B,0x08,0x32,0x8A,0xA7,0x77,0xD6,0x40,0x4A,0xF2,0x57,0xE8,0xDA,0x1C,0xB4,0x95, +0x8D,0xE7,0x2B,0xD7,0xD9,0xBA,0x0C,0x3B,0xA1,0x22,0xBA,0xDE,0x03,0xF3,0x1C,0x3F,0x78,0x3E,0xB7,0xE8, +0xC3,0x2E,0xC8,0x5C,0x6C,0x0B,0x9E,0x25,0xD6,0x08,0xB0,0x84,0xEB,0xD5,0x4A,0x7E,0xAC,0xB2,0xA3,0xB6, +0x8F,0xA2,0x48,0x7C,0xE5,0x0F,0xBC,0x8A,0xC3,0x72,0x66,0x09,0x22,0x0C,0x04,0x60,0x78,0x8C,0xEF,0xC0, +0xA5,0x65,0x79,0xA6,0x6C,0xA8,0x68,0x87,0x80,0x34,0x6F,0x98,0x91,0x69,0x55,0xB3,0xCD,0x4D,0x6E,0x97, +0x66,0x62,0x94,0x48,0x4C,0x24,0x1B,0xC3,0x14,0xAD,0x8E,0xD1,0x14,0x52,0xE4,0xEE,0x07,0xDA,0x36,0xDA, +0x6A,0x48,0x31,0x35,0x4A,0x18,0x70,0x96,0x67,0x11,0x64,0x08,0x51,0xBD,0xB4,0xB6,0x31,0x4C,0x03,0x38, +0xC0,0xFD,0x4B,0x64,0x89,0x4A,0x9B,0x56,0x31,0xE2,0x99,0xE2,0xBB,0x4D,0x8F,0x17,0xB7,0x72,0x8C,0x65, +0x98,0x6B,0xFF,0x46,0xD3,0x92,0xBF,0xAE,0x24,0x2A,0x21,0xF4,0xE0,0xBD,0x7D,0x3E,0xEF,0x82,0x59,0xC5, +0x5D,0x38,0x41,0x59,0x41,0xA0,0xAF,0xE1,0x50,0x75,0x7B,0x96,0x78,0x27,0x71,0x57,0x5C,0xB4,0xD6,0x9F, +0xB1,0xE2,0xA3,0x6D,0x3A,0x6D,0x3E,0x1B,0xB7,0xBD,0xBB,0xBD,0x02,0x42,0x13,0xF1,0xDD,0x3E,0xE4,0x38, +0x48,0x83,0xD5,0x69,0x65,0xE3,0xD5,0x8C,0x0B,0x76,0x9A,0xB3,0xD0,0x58,0x00,0xEB,0x2E,0xB7,0x94,0xAE, +0x5C,0x6C,0x29,0xBB,0x75,0xA9,0x55,0xDA,0x87,0x0B,0xA9,0xAB,0x15,0x3F,0xFE,0xF8,0x43,0xCE,0xEA,0xDB, +0x86,0xD9,0xCA,0x85,0x2F,0xD5,0xD3,0x6E,0x99,0x91,0x85,0xD1,0xAF,0xC6,0xAA,0xDD,0x9E,0xEA,0xA7,0xCA, +0x1F,0x45,0x68,0x24,0xF0,0x44,0x72,0xD7,0x8B,0x6F,0x3E,0x60,0x38,0x85,0xB8,0x64,0x43,0x03,0x56,0xFD, +0x0A,0x56,0x2F,0x7E,0x06,0xBB,0x8A,0xBB,0x57,0x75,0x84,0x9E,0x57,0xD5,0xF3,0x2A,0xEA,0xA8,0x0D,0xDE, +0x23,0x3F,0x95,0xD0,0x15,0x18,0x1A,0x66,0x35,0xB0,0xAB,0xB3,0xC5,0xB9,0x56,0xB1,0x88,0xD8,0x3D,0xF5, +0x45,0xD4,0xAC,0xA8,0x84,0xA0,0xFE,0x56,0x13,0xAD,0x76,0x9A,0xCB,0x9A,0x33,0xF1,0x2A,0xA8,0x25,0xC5, +0x13,0x7A,0xB3,0xC6,0x00,0xF6,0xA1,0x47,0x17,0xE2,0x96,0x2E,0xAA,0xC9,0x26,0xBD,0x9A,0x82,0x78,0xB0, +0xA1,0xDE,0x95,0xA7,0xEB,0x01,0xAA,0x24,0x58,0x5D,0x54,0x55,0xC5,0xEA,0x72,0xD9,0xE8,0x55,0xDF,0x16, +0x35,0x7E,0xE5,0x52,0xD3,0x20,0xF2,0x7B,0x00,0xB9,0xBF,0xFD,0xD5,0xC0,0xA3,0x68,0x0A,0x63,0xEF,0x4F, +0x7E,0xDB,0x4D,0x59,0xFA,0x2C,0x00,0x00 }; From 2aa029bc408ac4179c2d02c02f0b116373716b73 Mon Sep 17 00:00:00 2001 From: lorol Date: Sat, 9 May 2020 16:55:57 -0400 Subject: [PATCH 054/551] Cookie Authentication including WS part taken from ayushsharma82 ideas https://github.com/me-no-dev/ESPAsyncWebServer/pull/684 For Websocket added: void handleHandshake(AwsHandshakeHandler handler) For EventSource added: void authorizeConnect(ArAuthorizeConnectHandler cb); Auth example and modifications. Tested on ESP8266 and ESP32 platforms See SmartSwitch.ino --- examples/SmartSwitch/README.md | 8 +- examples/SmartSwitch/SmartSwitch.ino | 155 ++++++++++++++---- examples/SmartSwitch/data/acefull.js.gz | Bin 119986 -> 119986 bytes .../SmartSwitch/data/login/favicon.ico.gz | Bin 0 -> 5806 bytes examples/SmartSwitch/data/login/index.htm | 20 +++ examples/SmartSwitch/data/worker-css.js.gz | Bin 35483 -> 35483 bytes examples/SmartSwitch/data/worker-html.js.gz | Bin 47406 -> 47406 bytes .../SmartSwitch/data/worker-javascript.js.gz | Bin 47729 -> 47729 bytes src/AsyncEventSource.cpp | 10 ++ src/AsyncEventSource.h | 3 + src/AsyncWebSocket.cpp | 11 ++ src/AsyncWebSocket.h | 7 + src/edit.htm.gz.h | 2 +- 13 files changed, 182 insertions(+), 34 deletions(-) create mode 100644 examples/SmartSwitch/data/login/favicon.ico.gz create mode 100644 examples/SmartSwitch/data/login/index.htm diff --git a/examples/SmartSwitch/README.md b/examples/SmartSwitch/README.md index fd8cd4061..4ce4e9ab3 100644 --- a/examples/SmartSwitch/README.md +++ b/examples/SmartSwitch/README.md @@ -4,14 +4,16 @@ ## SmartSwitch * Remote Temperature Control application with schedule (example car block heater or battery charger) -* Based on ESP_AsyncFSBrowser example +* Based on ESP_AsyncFSBrowser example with ACE editor * Wide browser compatibility, no extra server-side needed * HTTP server and WebSocket, single port * Standalone, no JS dependencies for the browser from Internet (I hope), ace editor included * Added ESPAsyncWiFiManager -* Fallback to an own WIFI_AP, no Internet to sync but by a browser the clock can be set once * Real Time (NTP) w/ Time Zones * Memorized settings to EEPROM * Multiple clients can be connected at same time, they see each other' requests +* Base Authentication of the editor, static content, WS +* Or Cookie Authentication including WS part, need lib src changes taken from https://github.com/me-no-dev/ESPAsyncWebServer/pull/684 * Default credentials smart:switch -* Use latest ESP8266 or ESP32 core(from GitHub) +* Use latest ESP8266 ESP32 cores from GitHub + diff --git a/examples/SmartSwitch/SmartSwitch.ino b/examples/SmartSwitch/SmartSwitch.ino index 0307cd29a..9609e9d06 100644 --- a/examples/SmartSwitch/SmartSwitch.ino +++ b/examples/SmartSwitch/SmartSwitch.ino @@ -16,9 +16,21 @@ Use latest ESP core lib (from Github) #define USE_WFM // to use ESPAsyncWiFiManager //#define DEL_WFM // delete Wifi credentials stored //(use once then comment and flash again), also HTTP /erase-wifi can do the same live - -#define USE_AUTH_STAT // .setAuthentication also for static (editor always requires auth) -//#define USE_AUTH_WS // .setAuthentication also for ws, broken for Safari iOS + +// AUTH COOKIE uses only the password, Base uses both +#define http_username "smart" +#define http_password "switch" + +//See https://github.com/me-no-dev/ESPAsyncWebServer/pull/684 +#define USE_AUTH_COOKIE +#define MY_COOKIE_FULL "LLKQ=7;max-age=31536000;" +#define MY_COOKIE_DEL "LLKQ=" +#define MY_COOKIE "LLKQ=7" + +#ifndef USE_AUTH_COOKIE + #define USE_AUTH_STAT //Base Auth for stat, /commands and SPIFFSEditor + //#define USE_AUTH_WS //Base Auth also for WS, not very supported +#endif #include #ifdef ESP32 @@ -55,7 +67,10 @@ Use latest ESP core lib (from Github) // DHT #define DHTTYPE DHT22 // DHT 11 // DHT 22, AM2302, AM2321 // DHT 21, AM2301 -#define DHTPIN 4 //D2 +#define DHTPIN 4 //D2 + +#define DHT_T_CORR -0.5 //Temperature offset compensation of the sensor (can be -) +#define DHT_H_CORR 1.5 //Humidity offset compensation of the sensor DHT dht(DHTPIN, DHTTYPE); @@ -80,9 +95,7 @@ AsyncWebSocket ws("/ws"); const char* ssid = "MYROUTERSSD"; const char* password = "MYROUTERPASSWD"; #endif -const char* hostName = "smartsw"; -const char* http_username = "smart"; -const char* http_password = "switch"; + const char* hostName = "smartsw32"; // RTC static timeval tv; @@ -91,6 +104,15 @@ static time_t now; // HW I/O const int btnPin = 0; //D3 const int ledPin = 2; //D4 + +#ifdef ESP32 + #define LED_ON 0x1 + #define LED_OFF 0x0 +#elif defined(ESP8266) + #define LED_ON 0x0 + #define LED_OFF 0x1 +#endif + int btnState = HIGH; // Globals @@ -101,7 +123,7 @@ float t = 0; float h = 0; bool udht = false; bool heat_enabled_prev = false; -int ledState; +int ledState = LED_OFF; struct EE_bl { byte memid; //here goes the EEMARK stamp @@ -178,30 +200,32 @@ void showTime() } if (heat_enabled_prev) { // smart control (delayed one cycle) - if (((t - HYST) < ee.tempe)&&(ledState == HIGH)) { // OFF->ON once - ledState = LOW; + if (((t - HYST) < ee.tempe)&&(ledState == LED_OFF)) { // OFF->ON once + ledState = LED_ON; digitalWrite(ledPin, ledState); // apply change ws.textAll("led,ledon"); } - if ((((t + HYST) > ee.tempe)&&(ledState == LOW))||(!heat_enabled)) { // ON->OFF once, also turn off at end of period. - ledState = HIGH; + if ((((t + HYST) > ee.tempe)&&(ledState == LED_ON))||(!heat_enabled)) { // ON->OFF once, also turn off at end of period. + ledState = LED_OFF; digitalWrite(ledPin, ledState); // apply change ws.textAll("led,ledoff"); } - Serial.printf(ledState ? "LED OFF" : "LED ON"); + + Serial.printf(ledState == LED_ON ? "LED ON" : "LED OFF"); Serial.print(F(", Smart enabled\n")); } heat_enabled_prev = heat_enabled; //update } void updateDHT(){ - h = dht.readHumidity(); - t = dht.readTemperature(); //Celsius or dht.readTemperature(true) for Fahrenheit - if (isnan(h) || isnan(t)) { + float h1 = dht.readHumidity(); + float t1 = dht.readTemperature(); //Celsius or dht.readTemperature(true) for Fahrenheit + if (isnan(h1) || isnan(t1)) { Serial.print(F("Failed to read from DHT sensor!")); - h = 0; // debug w/o sensor - t = 0; - } + } else { + h = h1 + DHT_H_CORR; + t = t1 + DHT_T_CORR; + } } void analogSample() @@ -216,7 +240,7 @@ void checkPhysicalButton() if (btnState != LOW) { // btnState is used to avoid sequential toggles ledState = !ledState; digitalWrite(ledPin, ledState); - if (ledState) ws.textAll("led,ledoff"); + if (ledState == LED_OFF) ws.textAll("led,ledoff"); else ws.textAll("led,ledon"); } btnState = LOW; @@ -241,6 +265,16 @@ void mytimer() { } } +#ifdef USE_AUTH_COOKIE +bool myHandshake(AsyncWebServerRequest *request){ // false will 401 + if (request->hasHeader("Cookie")){ + String cookie = request->header("Cookie"); + if (cookie.indexOf(MY_COOKIE) != -1) return true; + else return false; + } else return false; +} +#endif + // server void onWsEvent(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventType type, void * arg, uint8_t *data, size_t len){ if(type == WS_EVT_CONNECT){ @@ -252,7 +286,7 @@ void onWsEvent(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventT Serial.printf("[%u] Connected from %d.%d.%d.%d\n", client->id(), ip[0], ip[1], ip[2], ip[3]); showTime(); analogSample(); - if (ledState) ws.textAll("led,ledoff"); + if (ledState == LED_OFF) ws.textAll("led,ledoff"); else ws.textAll("led,ledon"); ws.printfAll("Now,Setting,%02d:%02d,%02d:%02d,%+2.1f", ee.hstart, ee.mstart, ee.hstop, ee.mstop, ee.tempe); @@ -279,11 +313,11 @@ void onWsEvent(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventT } if(data[0] == 'L') { // LED if(data[1] == '1') { - ledState = LOW; + ledState = LED_ON; ws.textAll("led,ledon"); // for others } else if(data[1] == '0') { - ledState = HIGH; + ledState = LED_OFF; ws.textAll("led,ledoff"); } digitalWrite(ledPin, ledState); // apply change @@ -444,31 +478,74 @@ void setup(){ #ifdef USE_AUTH_WS ws.setAuthentication(http_username,http_password); #endif + +#ifdef USE_AUTH_COOKIE + ws.handleHandshake(myHandshake); +#endif + ws.onEvent(onWsEvent); server.addHandler(&ws); #ifdef ESP32 + #ifdef USE_AUTH_STAT server.addHandler(new SPIFFSEditor(SPIFFS, http_username,http_password)); + #elif defined(USE_AUTH_COOKIE) + server.addHandler(new SPIFFSEditor(SPIFFS)).setFilter(myHandshake); + #endif #elif defined(ESP8266) + #ifdef USE_AUTH_STAT server.addHandler(new SPIFFSEditor(http_username,http_password)); + #elif defined(USE_AUTH_COOKIE) + server.addHandler(new SPIFFSEditor()).setFilter(myHandshake); + #endif #endif - + +#ifdef USE_AUTH_COOKIE + server.on("/lg2n", HTTP_POST, [](AsyncWebServerRequest *request){ // cookie test + if((request->hasParam("pa2w",true) && (String(request->getParam("pa2w",true)->value().c_str()) == String(http_password)))||(request->hasParam("lg0f",true))){ + AsyncWebServerResponse *response = request->beginResponse(301); + response->addHeader("Location", "/"); + response->addHeader("Cache-Control", "no-cache"); + if(request->hasParam("lg0f",true)) response->addHeader("Set-Cookie", MY_COOKIE_DEL); + else response->addHeader("Set-Cookie", MY_COOKIE_FULL); + request->send(response); + } else request->send(200, "text/plain","Wrong Password!"); + }); +#endif + +// below paths need individual auth //////////////////////////////////////////////// + server.on("/free-ram", HTTP_GET, [](AsyncWebServerRequest *request){ // direct request->answer +#ifdef USE_AUTH_STAT + if(!request->authenticate(http_username, http_password)) return request->requestAuthentication(); +#endif request->send(200, "text/plain", String(ESP.getFreeHeap())); +#ifdef USE_AUTH COOKIE + }).setFilter(myHandshake); +#else }); +#endif - - server.on("/get-time", HTTP_GET, [](AsyncWebServerRequest *request){ + server.on("/get-time", HTTP_GET, [](AsyncWebServerRequest *request){ +#ifdef USE_AUTH_STAT + if(!request->authenticate(http_username, http_password)) return request->requestAuthentication(); +#endif if(request->hasParam("btime")){ time_t rtc = (request->getParam("btime")->value()).toInt(); timeval tv = { rtc, 0 }; settimeofday(&tv, nullptr); } request->send(200, "text/plain","Got browser time ..."); +#ifdef USE_AUTH COOKIE + }).setFilter(myHandshake); +#else }); - +#endif server.on("/hw-reset", HTTP_GET, [](AsyncWebServerRequest *request){ +#ifdef USE_AUTH_STAT + if(!request->authenticate(http_username, http_password)) return request->requestAuthentication(); +#endif request->onDisconnect([]() { #ifdef ESP32 ESP.restart(); @@ -477,9 +554,16 @@ void setup(){ #endif }); request->send(200, "text/plain","Restarting ..."); +#ifdef USE_AUTH COOKIE + }).setFilter(myHandshake); +#else }); +#endif server.on("/erase-wifi", HTTP_GET, [](AsyncWebServerRequest *request){ +#ifdef USE_AUTH_STAT + if(!request->authenticate(http_username, http_password)) return request->requestAuthentication(); +#endif request->onDisconnect([]() { WiFi.disconnect(true); #ifdef ESP32 @@ -489,12 +573,23 @@ void setup(){ #endif }); request->send(200, "text/plain","Erasing WiFi data ..."); +#ifdef USE_AUTH COOKIE + }).setFilter(myHandshake); +#else }); +#endif + +// above paths need individual auth //////////////////////////////////////////////// -#ifdef USE_AUTH_STAT - server.serveStatic("/", SPIFFS, "/").setDefaultFile("index.htm").setAuthentication(http_username,http_password); +#ifdef USE_AUTH_COOKIE + server.serveStatic("/", SPIFFS, "/").setDefaultFile("index.htm").setFilter(myHandshake); + server.serveStatic("/", SPIFFS, "/login/").setDefaultFile("index.htm").setFilter(!myHandshake); #else - server.serveStatic("/", SPIFFS, "/").setDefaultFile("index.htm"); + #ifdef USE_AUTH_STAT + server.serveStatic("/", SPIFFS, "/").setDefaultFile("index.htm").setAuthentication(http_username,http_password); + #else + server.serveStatic("/", SPIFFS, "/").setDefaultFile("index.htm"); + #endif #endif server.onNotFound([](AsyncWebServerRequest *request){ // nothing known diff --git a/examples/SmartSwitch/data/acefull.js.gz b/examples/SmartSwitch/data/acefull.js.gz index e08df275219565d93939df9642c0198e32044e3b..00cdd5f934f68062b7484b87eedd6b1d99bf0815 100644 GIT binary patch delta 21 dcmdnAl6})kc6Rx04vsA0?TzeP*%?<~0RU2g2Yvtm delta 21 dcmdnAl6})kc6Rx04i0ax4UOzu*%?<~0RU412af;% diff --git a/examples/SmartSwitch/data/login/favicon.ico.gz b/examples/SmartSwitch/data/login/favicon.ico.gz new file mode 100644 index 0000000000000000000000000000000000000000..9e605465c6e22500502ba34a11be2488bc508355 GIT binary patch literal 5806 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 literal 0 HcmV?d00001 diff --git a/examples/SmartSwitch/data/login/index.htm b/examples/SmartSwitch/data/login/index.htm new file mode 100644 index 000000000..c522ea4f1 --- /dev/null +++ b/examples/SmartSwitch/data/login/index.htm @@ -0,0 +1,20 @@ + + + + + Login + + + + + +

+

+

Password

+ + +

+ +
+ + \ No newline at end of file diff --git a/examples/SmartSwitch/data/worker-css.js.gz b/examples/SmartSwitch/data/worker-css.js.gz index 6e826b6cc0669fdfe8c91ea7135fe25431513434..36849854f5e68ac7c3f494cc8f1af284f760dc17 100644 GIT binary patch delta 18 acmbO|m1*`=CU*I54vtLW?Hk#rbO8W4UaddInterestingHeader(F("Last-Event-ID")); + request->addInterestingHeader("Cookie"); return true; } @@ -340,6 +345,11 @@ void AsyncEventSource::handleRequest(AsyncWebServerRequest *request){ if((_username.length() && _password.length()) && !request->authenticate(_username.c_str(), _password.c_str())) { return request->requestAuthentication(); } + if(_authorizeConnectHandler != NULL){ + if(!_authorizeConnectHandler(request)){ + return request->send(401); + } + } request->send(new AsyncEventSourceResponse(this)); } diff --git a/src/AsyncEventSource.h b/src/AsyncEventSource.h index b097fa623..a350e7ff9 100644 --- a/src/AsyncEventSource.h +++ b/src/AsyncEventSource.h @@ -49,6 +49,7 @@ class AsyncEventSource; class AsyncEventSourceResponse; class AsyncEventSourceClient; typedef std::function ArEventHandlerFunction; +typedef std::function ArAuthorizeConnectHandler; class AsyncEventSourceMessage { private: @@ -100,6 +101,7 @@ class AsyncEventSource: public AsyncWebHandler { String _url; LinkedList _clients; ArEventHandlerFunction _connectcb; + ArAuthorizeConnectHandler _authorizeConnectHandler; public: AsyncEventSource(const String& url); ~AsyncEventSource(); @@ -107,6 +109,7 @@ class AsyncEventSource: public AsyncWebHandler { const char * url() const { return _url.c_str(); } void close(); void onConnect(ArEventHandlerFunction cb); + void authorizeConnect(ArAuthorizeConnectHandler cb); void send(const char *message, const char *event=NULL, uint32_t id=0, uint32_t reconnect=0); size_t count() const; //number clinets connected size_t avgPacketsWaiting() const; diff --git a/src/AsyncWebSocket.cpp b/src/AsyncWebSocket.cpp index 04e1a6f59..9ce9385fe 100644 --- a/src/AsyncWebSocket.cpp +++ b/src/AsyncWebSocket.cpp @@ -1146,6 +1146,7 @@ void AsyncWebSocket::binaryAll(const __FlashStringHelper *message, size_t len){ const char __WS_STR_CONNECTION[] PROGMEM = { "Connection" }; const char __WS_STR_UPGRADE[] PROGMEM = { "Upgrade" }; const char __WS_STR_ORIGIN[] PROGMEM = { "Origin" }; +const char __WS_STR_COOKIE[] PROGMEM = { "Cookie" }; const char __WS_STR_VERSION[] PROGMEM = { "Sec-WebSocket-Version" }; const char __WS_STR_KEY[] PROGMEM = { "Sec-WebSocket-Key" }; const char __WS_STR_PROTOCOL[] PROGMEM = { "Sec-WebSocket-Protocol" }; @@ -1155,6 +1156,7 @@ const char __WS_STR_UUID[] PROGMEM = { "258EAFA5-E914-47DA-95CA-C5AB0DC85B11" }; #define WS_STR_CONNECTION FPSTR(__WS_STR_CONNECTION) #define WS_STR_UPGRADE FPSTR(__WS_STR_UPGRADE) #define WS_STR_ORIGIN FPSTR(__WS_STR_ORIGIN) +#define WS_STR_COOKIE FPSTR(__WS_STR_COOKIE) #define WS_STR_VERSION FPSTR(__WS_STR_VERSION) #define WS_STR_KEY FPSTR(__WS_STR_KEY) #define WS_STR_PROTOCOL FPSTR(__WS_STR_PROTOCOL) @@ -1171,6 +1173,7 @@ bool AsyncWebSocket::canHandle(AsyncWebServerRequest *request){ request->addInterestingHeader(WS_STR_CONNECTION); request->addInterestingHeader(WS_STR_UPGRADE); request->addInterestingHeader(WS_STR_ORIGIN); + request->addInterestingHeader(WS_STR_COOKIE); request->addInterestingHeader(WS_STR_VERSION); request->addInterestingHeader(WS_STR_KEY); request->addInterestingHeader(WS_STR_PROTOCOL); @@ -1185,6 +1188,14 @@ void AsyncWebSocket::handleRequest(AsyncWebServerRequest *request){ if((_username.length() && _password.length()) && !request->authenticate(_username.c_str(), _password.c_str())){ return request->requestAuthentication(); } +////////////////////////////////////////// + if(_handshakeHandler != nullptr){ + if(!_handshakeHandler(request)){ + request->send(401); + return; + } + } +////////////////////////////////////////// AsyncWebHeader* version = request->getHeader(WS_STR_VERSION); if(version->value().toInt() != 13){ AsyncWebServerResponse *response = request->beginResponse(400); diff --git a/src/AsyncWebSocket.h b/src/AsyncWebSocket.h index 5b03aceb9..f06af2cf8 100644 --- a/src/AsyncWebSocket.h +++ b/src/AsyncWebSocket.h @@ -237,6 +237,7 @@ class AsyncWebSocketClient { void _onData(void *pbuf, size_t plen); }; +typedef std::function AwsHandshakeHandler; typedef std::function AwsEventHandler; //WebServer Handler implementation that plays the role of a socket server @@ -248,6 +249,7 @@ class AsyncWebSocket: public AsyncWebHandler { AsyncWebSocketClientLinkedList _clients; uint32_t _cNextId; AwsEventHandler _eventHandler; + AwsHandshakeHandler _handshakeHandler; bool _enabled; AsyncWebLock _lock; @@ -316,6 +318,11 @@ class AsyncWebSocket: public AsyncWebHandler { _eventHandler = handler; } + // Handshake Handler + void handleHandshake(AwsHandshakeHandler handler){ + _handshakeHandler = handler; + } + //system callbacks (do not call) uint32_t _getNextId(){ return _cNextId++; } void _addClient(AsyncWebSocketClient * client); diff --git a/src/edit.htm.gz.h b/src/edit.htm.gz.h index c2d7f53fc..3f352e00a 100644 --- a/src/edit.htm.gz.h +++ b/src/edit.htm.gz.h @@ -2,7 +2,7 @@ //File: edit.htm.gz, Size: 4408 #define edit_htm_gz_len 4408 const uint8_t edit_htm_gz[] PROGMEM = { -0x1F,0x8B,0x08,0x08,0x52,0x4A,0xB0,0x5E,0x02,0x00,0x65,0x64,0x69,0x74,0x2E,0x68,0x74,0x6D,0x00,0xB5, +0x1F,0x8B,0x08,0x08,0x42,0x13,0xB7,0x5E,0x02,0x00,0x65,0x64,0x69,0x74,0x2E,0x68,0x74,0x6D,0x00,0xB5, 0x1A,0x0B,0x5B,0xDB,0x36,0xF0,0xAF,0x18,0x6F,0x63,0xF6,0xE2,0x38,0x0E,0xA5,0xAC,0x73,0x30,0x2C,0x50, 0x56,0xFA,0x02,0x4A,0x42,0x3B,0xCA,0xD8,0x3E,0xC5,0x56,0x62,0x15,0x5B,0xF6,0x2C,0x99,0x40,0xB3,0xFC, 0xF7,0x9D,0x24,0x3F,0x43,0xE8,0x1E,0xDF,0xD6,0x6E,0x8D,0xA4,0xD3,0x9D,0xEE,0x4E,0xF7,0x54,0xB2,0xBB, From 44b27dc61f4f25e3e053d8f27957d43d4aaece53 Mon Sep 17 00:00:00 2001 From: lorol Date: Sat, 9 May 2020 20:05:23 -0400 Subject: [PATCH 055/551] Logoff Cookie Authentication in the example --- examples/SmartSwitch/SmartSwitch.ino | 7 ++++--- examples/SmartSwitch/data/index.htm | 1 + examples/SmartSwitch/data/login/index.htm | 2 +- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/examples/SmartSwitch/SmartSwitch.ino b/examples/SmartSwitch/SmartSwitch.ino index 9609e9d06..2c31bf707 100644 --- a/examples/SmartSwitch/SmartSwitch.ino +++ b/examples/SmartSwitch/SmartSwitch.ino @@ -23,9 +23,10 @@ Use latest ESP core lib (from Github) //See https://github.com/me-no-dev/ESPAsyncWebServer/pull/684 #define USE_AUTH_COOKIE -#define MY_COOKIE_FULL "LLKQ=7;max-age=31536000;" -#define MY_COOKIE_DEL "LLKQ=" -#define MY_COOKIE "LLKQ=7" +// 1 year age, path helps Safari to unset +#define MY_COOKIE_FULL "LLKQ=3; Max-Age=31536000; Path=/;" +#define MY_COOKIE_DEL "LLKQ=; Max-Age=-1; Path=/;" +#define MY_COOKIE "LLKQ=3" #ifndef USE_AUTH_COOKIE #define USE_AUTH_STAT //Base Auth for stat, /commands and SPIFFSEditor diff --git a/examples/SmartSwitch/data/index.htm b/examples/SmartSwitch/data/index.htm index 9f7da5b6e..68aaefa90 100644 --- a/examples/SmartSwitch/data/index.htm +++ b/examples/SmartSwitch/data/index.htm @@ -329,6 +329,7 @@
+

Logoff

diff --git a/examples/SmartSwitch/data/login/index.htm b/examples/SmartSwitch/data/login/index.htm index c522ea4f1..5e39f6f00 100644 --- a/examples/SmartSwitch/data/login/index.htm +++ b/examples/SmartSwitch/data/login/index.htm @@ -12,7 +12,7 @@

Password

- +



From 10a23dfcc78fa7957bb1a0ab0c166157190f2895 Mon Sep 17 00:00:00 2001 From: lorol Date: Wed, 27 May 2020 11:51:06 -0400 Subject: [PATCH 056/551] Updated the Readme.md files in this fork (used Mark Text editor) Cookie auth with Xtea encrypting, see SmartSwitch.ino example Tested on ESP8266 and ESP32 with better built-in LED handling Minor updates and improvements of js / html packed files. --- README.md | 116 ++++++++++++++-- examples/SmartSwitch/PinOut_Notes.txt | 14 +- examples/SmartSwitch/README.md | 42 ++++-- examples/SmartSwitch/SmartSwitch.ino | 125 ++++++++++++++---- examples/SmartSwitch/Xtea.cpp | 48 +++++++ examples/SmartSwitch/Xtea.h | 20 +++ examples/SmartSwitch/data/acefull.js.gz | Bin 119986 -> 119986 bytes examples/SmartSwitch/data/index.htm | 39 +++--- examples/SmartSwitch/data/index.min.htm.gz | Bin 4193 -> 3328 bytes examples/SmartSwitch/data/login/index.htm | 26 +++- examples/SmartSwitch/data/worker-css.js.gz | Bin 35483 -> 35483 bytes examples/SmartSwitch/data/worker-html.js.gz | Bin 47406 -> 47406 bytes .../SmartSwitch/data/worker-javascript.js.gz | Bin 47729 -> 47729 bytes extras/README.md | 28 ++++ extras/Readme | 27 ---- src/edit.htm.gz.h | 2 +- 16 files changed, 378 insertions(+), 109 deletions(-) create mode 100644 examples/SmartSwitch/Xtea.cpp create mode 100644 examples/SmartSwitch/Xtea.h create mode 100644 extras/README.md delete mode 100644 extras/Readme diff --git a/README.md b/README.md index 5cc2fc0c2..3b4bae6f9 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,20 @@ -# ESPAsyncWebServer +# In this fork + +SPIFFSEditor improvements + +Added [extras](https://github.com/lorol/ESPAsyncWebServer/tree/master/extras) folder with (Win) tools for re-packing, allow editing, updating and compressing html to binary arrays, embedded to source + +Added a [SmartSwitch](https://github.com/lorol/ESPAsyncWebServer/tree/master/examples/SmartSwitch) example to test code features + +Applied the memory optimizations from [sascha432](https://github.com/sascha432/ESPAsyncWebServer) fork + +Cookie Authentication including on Websocket part, based on [ayushsharma82](https://github.com/me-no-dev/ESPAsyncWebServer/pull/684) PR, new functions added: + +- For Websocket: ```void handleHandshake(AwsHandshakeHandler handler) ``` +- For EventSource: ```void authorizeConnect(ArAuthorizeConnectHandler cb)``` + +# ESPAsyncWebServer + [![Build Status](https://travis-ci.org/me-no-dev/ESPAsyncWebServer.svg?branch=master)](https://travis-ci.org/me-no-dev/ESPAsyncWebServer) ![](https://github.com/me-no-dev/ESPAsyncWebServer/workflows/ESP%20Async%20Web%20Server%20CI/badge.svg) [![Codacy Badge](https://api.codacy.com/project/badge/Grade/395dd42cfc674e6ca2e326af3af80ffc)](https://www.codacy.com/manual/me-no-dev/ESPAsyncWebServer?utm_source=github.com&utm_medium=referral&utm_content=me-no-dev/ESPAsyncWebServer&utm_campaign=Badge_Grade) For help and support [![Join the chat at https://gitter.im/me-no-dev/ESPAsyncWebServer](https://badges.gitter.im/me-no-dev/ESPAsyncWebServer.svg)](https://gitter.im/me-no-dev/ESPAsyncWebServer?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) @@ -12,6 +28,7 @@ For ESP32 it requires [AsyncTCP](https://github.com/me-no-dev/AsyncTCP) to work To use this library you might need to have the latest git versions of [ESP32](https://github.com/espressif/arduino-esp32) Arduino Core ## Table of contents + - [ESPAsyncWebServer](#espasyncwebserver) - [Table of contents](#table-of-contents) - [Installation](#installation) @@ -102,7 +119,7 @@ To use this library you might need to have the latest git versions of [ESP32](ht 3. Update dev/platform to staging version: - [Instruction for Espressif 8266](http://docs.platformio.org/en/latest/platforms/espressif8266.html#using-arduino-framework-with-staging-version) - [Instruction for Espressif 32](http://docs.platformio.org/en/latest/platforms/espressif32.html#using-arduino-framework-with-staging-version) - 4. Add "ESP Async WebServer" to project using [Project Configuration File `platformio.ini`](http://docs.platformio.org/page/projectconf.html) and [lib_deps](http://docs.platformio.org/page/projectconf/section_env_library.html#lib-deps) option: + 4. Add "ESP Async WebServer" to project using [Project Configuration File `platformio.ini`](http://docs.platformio.org/page/projectconf.html) and [lib_deps](http://docs.platformio.org/page/projectconf/section_env_library.html#lib-deps) option: ```ini [env:myboard] @@ -116,9 +133,11 @@ lib_deps = ESP Async WebServer # or using GIT Url (the latest development version) lib_deps = https://github.com/me-no-dev/ESPAsyncWebServer.git ``` - 5. Happy coding with PlatformIO! + +5. Happy coding with PlatformIO! ## Why should you care + - Using asynchronous network means that you can handle more than one connection at the same time - You are called once the request is ready and parsed - When you send the response, you are immediately ready to handle other connections @@ -134,6 +153,7 @@ lib_deps = https://github.com/me-no-dev/ESPAsyncWebServer.git - Simple template processing engine to handle templates ## Important things to remember + - This is fully asynchronous server and as such does not run on the loop thread. - You can not use yield or delay or any function that uses them inside the callbacks - The server is smart enough to know when to close the connection and free resources @@ -142,6 +162,7 @@ lib_deps = https://github.com/me-no-dev/ESPAsyncWebServer.git ## Principles of operation ### The Async Web server + - Listens for connections - Wraps the new clients into ```Request``` - Keeps track of clients and cleans memory @@ -149,6 +170,7 @@ lib_deps = https://github.com/me-no-dev/ESPAsyncWebServer.git - Manages ```Handlers``` and attaches them to Requests ### Request Life Cycle + - TCP connection is received by the server - The connection is wrapped inside ```Request``` object - When the request head is received (type, url, get params, http version and host), @@ -161,6 +183,7 @@ lib_deps = https://github.com/me-no-dev/ESPAsyncWebServer.git - When the ```Response``` is sent, the client is closed and freed from the memory ### Rewrites and how do they work + - The ```Rewrites``` are used to rewrite the request url and/or inject get parameters for a specific request url path. - All ```Rewrites``` are evaluated on the request in the order they have been added to the server. - The ```Rewrite``` will change the request url only if the request url (excluding get parameters) is fully match @@ -172,6 +195,7 @@ lib_deps = https://github.com/me-no-dev/ESPAsyncWebServer.git - The ```Rewrite``` can specify a target url with optional get parameters, e.g. ```/to-url?with=params``` ### Handlers and how do they work + - The ```Handlers``` are used for executing specific actions to particular requests - One ```Handler``` instance can be attached to any request and lives together with the server - Setting a ```Filter``` to the ```Handler``` enables to control when to apply the handler, decision can be based on @@ -189,6 +213,7 @@ lib_deps = https://github.com/me-no-dev/ESPAsyncWebServer.git - The first ```Handler``` that can handle the request is selected, not further ```Filter``` and ```canHandle``` are called. ### Responses and how do they work + - The ```Response``` objects are used to send the response data back to the client - The ```Response``` object lives with the ```Request``` and is freed on end or disconnect - Different techniques are used depending on the response type to send the data in packets @@ -198,6 +223,7 @@ lib_deps = https://github.com/me-no-dev/ESPAsyncWebServer.git - Many different options exist for the user to make responding a background task ### Template processing + - ESPAsyncWebserver contains simple template processing engine. - Template processing can be added to most response types. - Currently it supports only replacing template placeholders with actual values. No conditional processing, cycles, etc. @@ -207,6 +233,7 @@ lib_deps = https://github.com/me-no-dev/ESPAsyncWebServer.git - Since it's impossible to know the actual response size after template processing step in advance (and, therefore, to include it in response headers), the response becomes [chunked](#chunked-response). ## Libraries and projects that use AsyncWebServer + - [WebSocketToSerial](https://github.com/hallard/WebSocketToSerial) - Debug serial devices through the web browser - [Sattrack](https://github.com/Hopperpop/Sattrack) - Track the ISS with ESP8266 - [ESP Radio](https://github.com/Edzelf/Esp-radio) - Icecast radio based on ESP8266 and VS1053 @@ -218,6 +245,7 @@ lib_deps = https://github.com/me-no-dev/ESPAsyncWebServer.git ## Request Variables ### Common Variables + ```cpp request->version(); // uint8_t: 0 = HTTP/1.0, 1 = HTTP/1.1 request->method(); // enum: HTTP_GET, HTTP_POST, HTTP_DELETE, HTTP_PUT, HTTP_PATCH, HTTP_HEAD, HTTP_OPTIONS @@ -229,6 +257,7 @@ request->multipart(); // bool: True if the request has content type "mult ``` ### Headers + ```cpp //List all collected headers int headers = request->headers(); @@ -258,6 +287,7 @@ if(request->hasHeader("MyHeader")){ ``` ### GET, POST and FILE parameters + ```cpp //List all parameters int params = request->params(); @@ -296,6 +326,7 @@ if(request->hasArg("download")) ``` ### FILE Upload handling + ```cpp void handleUpload(AsyncWebServerRequest *request, String filename, size_t index, uint8_t *data, size_t len, bool final){ if(!index){ @@ -311,6 +342,7 @@ void handleUpload(AsyncWebServerRequest *request, String filename, size_t index, ``` ### Body data handling + ```cpp void handleBody(AsyncWebServerRequest *request, uint8_t *data, size_t len, size_t index, size_t total){ if(!index){ @@ -324,10 +356,13 @@ void handleBody(AsyncWebServerRequest *request, uint8_t *data, size_t len, size_ } } ``` + If needed, the `_tempObject` field on the request can be used to store a pointer to temporary data (e.g. from the body) associated with the request. If assigned, the pointer will automatically be freed along with the request. ### JSON body handling with ArduinoJson + Endpoints which consume JSON can use a special handler to get ready to use JSON data in the request callback: + ```cpp #include "AsyncJson.h" #include "ArduinoJson.h" @@ -340,7 +375,9 @@ server.addHandler(handler); ``` ## Responses + ### Redirect to another URL + ```cpp //to local url request->redirect("/login"); @@ -350,11 +387,13 @@ request->redirect("http://esp8266.com"); ``` ### Basic response with HTTP Code + ```cpp request->send(404); //Sends 404 File Not Found ``` ### Basic response with HTTP Code and extra headers + ```cpp AsyncWebServerResponse *response = request->beginResponse(404); //Sends 404 File Not Found response->addHeader("Server","ESP Async Web Server"); @@ -362,11 +401,13 @@ request->send(response); ``` ### Basic response with string content + ```cpp request->send(200, "text/plain", "Hello World!"); ``` ### Basic response with string content and extra headers + ```cpp AsyncWebServerResponse *response = request->beginResponse(200, "text/plain", "Hello World!"); response->addHeader("Server","ESP Async Web Server"); @@ -374,12 +415,14 @@ 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); @@ -388,6 +431,7 @@ request->send(response); ``` ### Send large webpage from PROGMEM containing templates + ```cpp String processor(const String& var) { @@ -403,6 +447,7 @@ request->send_P(200, "text/html", index_html, processor); ``` ### Send large webpage from PROGMEM containing templates and extra headers + ```cpp String processor(const String& var) { @@ -420,8 +465,8 @@ request->send(response); ``` ### Send binary content from PROGMEM -```cpp +```cpp //File: favicon.ico.gz, Size: 726 #define favicon_ico_gz_len 726 const uint8_t favicon_ico_gz[] PROGMEM = { @@ -479,12 +524,14 @@ request->send(response); ``` ### Respond with content coming from a Stream + ```cpp //read 12 bytes from Serial and send them as Content Type text/plain request->send(Serial, "text/plain", 12); ``` ### Respond with content coming from a Stream and extra headers + ```cpp //read 12 bytes from Serial and send them as Content Type text/plain AsyncWebServerResponse *response = request->beginResponse(Serial, "text/plain", 12); @@ -493,6 +540,7 @@ request->send(response); ``` ### Respond with content coming from a Stream containing templates + ```cpp String processor(const String& var) { @@ -508,6 +556,7 @@ request->send(Serial, "text/plain", 12, processor); ``` ### Respond with content coming from a Stream containing templates and extra headers + ```cpp String processor(const String& var) { @@ -525,6 +574,7 @@ request->send(response); ``` ### Respond with content coming from a File + ```cpp //Send index.htm with default content type request->send(SPIFFS, "/index.htm"); @@ -537,6 +587,7 @@ request->send(SPIFFS, "/index.htm", String(), true); ``` ### Respond with content coming from a File and extra headers + ```cpp //Send index.htm with default content type AsyncWebServerResponse *response = request->beginResponse(SPIFFS, "/index.htm"); @@ -552,14 +603,17 @@ request->send(response); ``` ### Respond with content coming from a File containing templates + Internally uses [Chunked Response](#chunked-response). Index.htm contents: + ``` %HELLO_FROM_TEMPLATE% ``` Somewhere in source files: + ```cpp String processor(const String& var) { @@ -575,6 +629,7 @@ request->send(SPIFFS, "/index.htm", String(), false, processor); ``` ### Respond with content using a callback + ```cpp //send 128 bytes as plain text request->send("text/plain", 128, [](uint8_t *buffer, size_t maxLen, size_t index) -> size_t { @@ -588,6 +643,7 @@ request->send("text/plain", 128, [](uint8_t *buffer, size_t maxLen, size_t index ``` ### Respond with content using a callback and extra headers + ```cpp //send 128 bytes as plain text AsyncWebServerResponse *response = request->beginResponse("text/plain", 128, [](uint8_t *buffer, size_t maxLen, size_t index) -> size_t { @@ -603,6 +659,7 @@ request->send(response); ``` ### Respond with content using a callback containing templates + ```cpp String processor(const String& var) { @@ -625,6 +682,7 @@ request->send("text/plain", 128, [](uint8_t *buffer, size_t maxLen, size_t index ``` ### Respond with content using a callback containing templates and extra headers + ```cpp String processor(const String& var) { @@ -649,7 +707,9 @@ request->send(response); ``` ### Chunked Response + Used when content length is unknown. Works best if the client supports HTTP/1.1 + ```cpp AsyncWebServerResponse *response = request->beginChunkedResponse("text/plain", [](uint8_t *buffer, size_t maxLen, size_t index) -> size_t { //Write up to "maxLen" bytes into "buffer" and return the amount written. @@ -663,7 +723,9 @@ request->send(response); ``` ### Chunked Response containing templates + Used when content length is unknown. Works best if the client supports HTTP/1.1 + ```cpp String processor(const String& var) { @@ -686,6 +748,7 @@ request->send(response); ``` ### Print to response + ```cpp AsyncResponseStream *response = request->beginResponseStream("text/html"); response->addHeader("Server","ESP Async Web Server"); @@ -736,7 +799,9 @@ request->send(response); ``` ### ArduinoJson Basic Response + This way of sending Json is great for when the result is below 4KB + ```cpp #include "AsyncJson.h" #include "ArduinoJson.h" @@ -752,11 +817,13 @@ request->send(response); ``` ### ArduinoJson Advanced Response + This response can handle really large Json objects (tested to 40KB) There isn't any noticeable speed decrease for small results with the method above Since ArduinoJson does not allow reading parts of the string, the whole Json has to be passed every time a chunks needs to be sent, which shows speed decrease proportional to the resulting json packets + ```cpp #include "AsyncJson.h" #include "ArduinoJson.h" @@ -772,6 +839,7 @@ request->send(response); ``` ## Serving static files + In addition to serving files from SPIFFS as described above, the server provide a dedicated handler that optimize the performance of serving files from SPIFFS - ```AsyncStaticWebHandler```. Use ```server.serveStatic()``` function to initialize and add a new instance of ```AsyncStaticWebHandler``` to the server. @@ -780,13 +848,16 @@ handler that can handle the request. Notice that you can chain setter functions to setup the handler, or keep a pointer to change it at a later time. ### Serving specific file by name + ```cpp // Serve the file "/www/page.htm" when request url is "/page.htm" server.serveStatic("/page.htm", SPIFFS, "/www/page.htm"); ``` ### Serving files in directory + To serve files in a directory, the path to the files should specify a directory in SPIFFS and ends with "/". + ```cpp // Serve files in directory "/www/" when request url starts with "/" // Request to the root or none existing files will try to server the defualt @@ -807,8 +878,10 @@ server ``` ### Specifying Cache-Control header + It is possible to specify Cache-Control header value to reduce the number of calls to the server once the client loaded the files. For more information on Cache-Control values see [Cache-Control](https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9) + ```cpp // Cache responses for 10 minutes (600 seconds) server.serveStatic("/", SPIFFS, "/www/").setCacheControl("max-age=600"); @@ -823,8 +896,10 @@ handler->setCacheControl("max-age=30"); ``` ### Specifying Date-Modified header + It is possible to specify Date-Modified header to enable the server to return Not-Modified (304) response for requests with "If-Modified-Since" header with the same value, instead of responding with the actual file content. + ```cpp // Update the date modified string every time files are updated server.serveStatic("/", SPIFFS, "/www/").setLastModified("Mon, 20 Jun 2016 14:00:00 GMT"); @@ -843,8 +918,10 @@ handler->setLastModified(date_modified); ``` ### Specifying Template Processor callback + It is possible to specify template processor for static files. For information on template processor see [Respond with content coming from a File containing templates](#respond-with-content-coming-from-a-file-containing-templates). + ```cpp String processor(const String& var) { @@ -859,6 +936,7 @@ server.serveStatic("/", SPIFFS, "/www/").setTemplateProcessor(processor); ``` ## Param Rewrite With Matching + It is possible to rewrite the request url with parameter matchg. Here is an example with one parameter: Rewrite for example "/radio/{frequence}" -> "/radio?f={frequence}" @@ -911,20 +989,24 @@ Usage: ``` ## Using filters + Filters can be set to `Rewrite` or `Handler` in order to control when to apply the rewrite and consider the handler. A filter is a callback function that evaluates the request and return a boolean `true` to include the item or `false` to exclude it. Two filter callback are provided for convince: + * `ON_STA_FILTER` - return true when requests are made to the STA (station mode) interface. * `ON_AP_FILTER` - return true when requests are made to the AP (access point) interface. ### Serve different site files in AP mode + ```cpp server.serveStatic("/", SPIFFS, "/www/").setFilter(ON_STA_FILTER); server.serveStatic("/", SPIFFS, "/ap/").setFilter(ON_AP_FILTER); ``` ### Rewrite to different index on AP + ```cpp // Serve the file "/www/index-ap.htm" in AP, and the file "/www/index.htm" on STA server.rewrite("/", "index.htm"); @@ -933,6 +1015,7 @@ server.serveStatic("/", SPIFFS, "/www/"); ``` ### Serving different hosts + ```cpp // Filter callback using request host bool filterOnHost1(AsyncWebServerRequest *request) { return request->host() == "host1"; } @@ -943,6 +1026,7 @@ server.serveStatic("/", SPIFFS, "/www/"); ``` ### Determine interface inside callbacks + ```cpp String RedirectUrl = "http://"; if (ON_STA_FILTER(request)) { @@ -955,11 +1039,13 @@ server.serveStatic("/", SPIFFS, "/www/"); ``` ## Bad Responses + Some responses are implemented, but you should not use them, because they do not conform to HTTP. The following example will lead to unclean close of the connection and more time wasted than providing the length of the content ### Respond with content using a callback without content length to HTTP/1.0 clients + ```cpp //This is used as fallback for chunked responses to HTTP/1.0 Clients request->send("text/plain", 0, [](uint8_t *buffer, size_t maxLen, size_t index) -> size_t { @@ -971,12 +1057,13 @@ request->send("text/plain", 0, [](uint8_t *buffer, size_t maxLen, size_t index) ``` ## Async WebSocket Plugin + The server includes a web socket plugin which lets you define different WebSocket locations to connect to without starting another listening service or using different port ### Async WebSocket Event -```cpp +```cpp void onEvent(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventType type, void * arg, uint8_t *data, size_t len){ if(type == WS_EVT_CONNECT){ //client connected @@ -1046,10 +1133,8 @@ void onEvent(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventTyp ``` ### Methods for sending data to a socket client -```cpp - - +```cpp //Server methods AsyncWebSocket ws("/ws"); //printf to a client @@ -1104,6 +1189,7 @@ client->binary(flash_binary, 4); ``` ### Direct access to web socket message buffer + When sending a web socket message using the above methods a buffer is created. Under certain circumstances you might want to manipulate or populate this buffer directly from your application, for example to prevent unnecessary duplications of the data. This example below shows how to create a buffer and print data to it from an ArduinoJson object then send it. ```cpp @@ -1130,6 +1216,7 @@ void sendDataWs(AsyncWebSocketClient * client) ``` ### Limiting the number of web socket clients + Browsers sometimes do not correctly close the websocket connection, even when the close() function is called in javascript. This will eventually exhaust the web server's resources and will cause the server to crash. Periodically calling the cleanClients() function from the main loop() function limits the number of clients by closing the oldest client when the maximum number of clients has been exceeded. This can called be every cycle, however, if you wish to use less power, then calling as infrequently as once per second is sufficient. ```cpp @@ -1138,12 +1225,13 @@ void loop(){ } ``` - ## Async Event Source Plugin + The server includes EventSource (Server-Sent Events) plugin which can be used to send short text events to the browser. Difference between EventSource and WebSockets is that EventSource is single direction, text-only protocol. ### Setup Event Source on the server + ```cpp AsyncWebServer server(80); AsyncEventSource events("/events"); @@ -1173,6 +1261,7 @@ void loop(){ ``` ### Setup Event Source in the browser + ```javascript if (!!window.EventSource) { var source = new EventSource('/events'); @@ -1198,6 +1287,7 @@ if (!!window.EventSource) { ``` ## Scanning for available WiFi Networks + ```cpp //First request will return 0 results unless you start scan from somewhere else (loop/setup) //Do not request more often than 3-5 seconds @@ -1233,6 +1323,7 @@ server.on("/scan", HTTP_GET, [](AsyncWebServerRequest *request){ Server goes through handlers in same order as they were added. You can't simple add handler with same path to override them. To remove handler: + ```arduino // save callback for particular URL path auto handler = server.on("/some/path", [](AsyncWebServerRequest *request){ @@ -1256,6 +1347,7 @@ server.reset(); ``` ## Setting up the server + ```cpp #include "ESPAsyncTCP.h" #include "ESPAsyncWebServer.h" @@ -1456,7 +1548,6 @@ Example of OTA code ws.closeAll(); }); - ``` ### Adding Default Headers @@ -1496,11 +1587,11 @@ For example we want a `sensorId` parameter in a route rule to match only a integ String sensorId = request->pathArg(0); }); ``` + *NOTE*: All regex patterns starts with `^` and ends with `$` To enable the `Path variable` support, you have to define the buildflag `-DASYNCWEBSERVER_REGEX`. - For Arduino IDE create/update `platform.local.txt`: `Windows`: C:\Users\(username)\AppData\Local\Arduino15\packages\\`{espxxxx}`\hardware\\`espxxxx`\\`{version}`\platform.local.txt @@ -1508,14 +1599,17 @@ For Arduino IDE create/update `platform.local.txt`: `Linux`: ~/.arduino15/packages/`{espxxxx}`/hardware/`{espxxxx}`/`{version}`/platform.local.txt Add/Update the following line: + ``` compiler.cpp.extra_flags=-DASYNCWEBSERVER_REGEX ``` For platformio modify `platformio.ini`: + ```ini [env:myboard] build_flags = -DASYNCWEBSERVER_REGEX ``` + *NOTE*: By enabling `ASYNCWEBSERVER_REGEX`, `` will be included. This will add an 100k to your binary. diff --git a/examples/SmartSwitch/PinOut_Notes.txt b/examples/SmartSwitch/PinOut_Notes.txt index 2634a19d6..a55977a82 100644 --- a/examples/SmartSwitch/PinOut_Notes.txt +++ b/examples/SmartSwitch/PinOut_Notes.txt @@ -1,12 +1,12 @@ This application: D2 = 4; // DHT DATA I/O -D3 = 0; // BUTTON - most modules have it populated on PCB -D4 = 2; // LED (RELAY) - most modules have it populated on PCB +D3 = 0; // BUTTON - most modules have it populated on PCB +D4 = 2; // LED (RELAY) - most modules have it populated, on ESP32 is with reversed logic levels Pinout ESP12 (8266) -D GPIO In Out Notes +D GPIO In Out Notes D0 16 no interrupt no PWM or I2C support HIGH at boot used to wake up from deep sleep D1 5 OK OK often used as SCL (I2C) @@ -23,16 +23,16 @@ A0 ADC0 Analog Input Pinout ESP32 -IO In Out Notes +IO In Out Notes 0 PU OK pulled-up input, outputs PWM signal at boot -1 TX OK debug output at boot +1 TX OK debug output at boot 2 OK OK connected to on-board LED -3 OK RX pin HIGH at boot +3 OK RX HIGH at boot 4 OK OK 5 OK OK outputs PWM signal at boot -6-11 x x connected to the integrated SPI flash +6-11 x x connected to the integrated SPI flash 12 OK OK boot fail if pulled high 13 OK OK diff --git a/examples/SmartSwitch/README.md b/examples/SmartSwitch/README.md index 4ce4e9ab3..723f3c789 100644 --- a/examples/SmartSwitch/README.md +++ b/examples/SmartSwitch/README.md @@ -1,19 +1,35 @@ -![](1.PNG) ![](2.PNG) -## -![](3.PNG) ![](4.PNG) + ## SmartSwitch -* Remote Temperature Control application with schedule (example car block heater or battery charger) -* Based on ESP_AsyncFSBrowser example with ACE editor + +* Remote Temperature Control application with schedule + + (example: car block heater or car battery charger for winter) + +* Based on [ESP_AsyncFSBrowser](https://github.com/lorol/ESPAsyncWebServer/tree/master/examples/ESP_AsyncFSBrowser) example that uses embedded ACE editor + * Wide browser compatibility, no extra server-side needed -* HTTP server and WebSocket, single port -* Standalone, no JS dependencies for the browser from Internet (I hope), ace editor included -* Added ESPAsyncWiFiManager -* Real Time (NTP) w/ Time Zones + +* HTTP server and WebSocket on same port + +* Standalone, no JS dependencies for the browser from Internet + +* [Ace Editor](https://github.com/ajaxorg/ace) embedded to source but also - editable, upgradeable see [extras folder](https://github.com/lorol/ESPAsyncWebServer/tree/master/extras) + +* Added [ESPAsyncWiFiManager](https://github.com/alanswx/ESPAsyncWiFiManager) and fallback AP mode after timeout + +* Real Time (NTP) w/ Time Zones. Sync from browser time if in AP mode + * Memorized settings to EEPROM + * Multiple clients can be connected at same time, they see each other' requests -* Base Authentication of the editor, static content, WS -* Or Cookie Authentication including WS part, need lib src changes taken from https://github.com/me-no-dev/ESPAsyncWebServer/pull/684 -* Default credentials smart:switch -* Use latest ESP8266 ESP32 cores from GitHub +* Authentication variants including [Cookie-based](https://github.com/me-no-dev/ESPAsyncWebServer/pull/684) idea + +* Used [this Xtea implementation](https://github.com/franksmicro/Arduino/tree/master/libraries/Xtea) for getting a fancier Cookie token + +* Default credentials **smart : switch** or only **switch** as password + +* OTA included + +* Use the latest ESP8266 ESP32 cores from GitHub diff --git a/examples/SmartSwitch/SmartSwitch.ino b/examples/SmartSwitch/SmartSwitch.ino index 2c31bf707..f99a2e26f 100644 --- a/examples/SmartSwitch/SmartSwitch.ino +++ b/examples/SmartSwitch/SmartSwitch.ino @@ -17,20 +17,23 @@ Use latest ESP core lib (from Github) //#define DEL_WFM // delete Wifi credentials stored //(use once then comment and flash again), also HTTP /erase-wifi can do the same live -// AUTH COOKIE uses only the password, Base uses both +// AUTH COOKIE uses only the password and unsigned long MY_SECRET_NUMBER + #define http_username "smart" #define http_password "switch" +#define MY_SECRET_NUMBER 0xA217B02F + //See https://github.com/me-no-dev/ESPAsyncWebServer/pull/684 +//SSWI or other 4 chars #define USE_AUTH_COOKIE -// 1 year age, path helps Safari to unset -#define MY_COOKIE_FULL "LLKQ=3; Max-Age=31536000; Path=/;" -#define MY_COOKIE_DEL "LLKQ=; Max-Age=-1; Path=/;" -#define MY_COOKIE "LLKQ=3" +#define MY_COOKIE_DEL "SSWI=;Max-Age=-1;Path=/;" +#define MY_COOKIE_PREF "SSWI=" +#define MY_COOKIE_SUFF ";Max-Age=31536000;Path=/;" #ifndef USE_AUTH_COOKIE #define USE_AUTH_STAT //Base Auth for stat, /commands and SPIFFSEditor - //#define USE_AUTH_WS //Base Auth also for WS, not very supported + //#define USE_AUTH_WS //Base Auth also for WS, not very supported #endif #include @@ -54,6 +57,11 @@ Use latest ESP core lib (from Github) #include #include +#ifdef USE_AUTH_COOKIE + #include + #include "Xtea.h" +#endif + #define RTC_UTC_TEST 1577836800 // Some Date #define MYTZ PSTR("EST5EDT,M3.2.0,M11.1.0") @@ -70,12 +78,13 @@ Use latest ESP core lib (from Github) #define DHTTYPE DHT22 // DHT 11 // DHT 22, AM2302, AM2321 // DHT 21, AM2301 #define DHTPIN 4 //D2 -#define DHT_T_CORR -0.5 //Temperature offset compensation of the sensor (can be -) -#define DHT_H_CORR 1.5 //Humidity offset compensation of the sensor +#define DHT_T_CORR -0.3 //Temperature offset compensation of the sensor (can be -) +#define DHT_H_CORR -2.2 //Humidity offset compensation of the sensor + +// SKETCH BEGIN MAIN DECLARATIONS DHT dht(DHTPIN, DHTTYPE); -// SKETCH BEGIN MAIN DECLARATIONS Ticker tim; AsyncWebServer server(80); //single port - easy for forwarding AsyncWebSocket ws("/ws"); @@ -86,7 +95,7 @@ AsyncWebSocket ws("/ws"); #else DNSServer dns; #endif - + //Fallback timeout in seconds allowed to config or it creates an own AP, then serves 192.168.4.1 #define FBTO 120 const char* fbssid = "FBSSW"; @@ -96,7 +105,8 @@ AsyncWebSocket ws("/ws"); const char* ssid = "MYROUTERSSD"; const char* password = "MYROUTERPASSWD"; #endif - const char* hostName = "smartsw32"; + +const char* hostName = "smartsw"; // RTC static timeval tv; @@ -222,7 +232,7 @@ void updateDHT(){ float h1 = dht.readHumidity(); float t1 = dht.readTemperature(); //Celsius or dht.readTemperature(true) for Fahrenheit if (isnan(h1) || isnan(t1)) { - Serial.print(F("Failed to read from DHT sensor!")); + Serial.println(F("Failed to read from DHT sensor!")); } else { h = h1 + DHT_H_CORR; t = t1 + DHT_T_CORR; @@ -241,8 +251,13 @@ void checkPhysicalButton() if (btnState != LOW) { // btnState is used to avoid sequential toggles ledState = !ledState; digitalWrite(ledPin, ledState); - if (ledState == LED_OFF) ws.textAll("led,ledoff"); - else ws.textAll("led,ledon"); + if (ledState == LED_OFF) { + ws.textAll("led,ledoff"); + Serial.println(F("LED-OFF")); + } else { + ws.textAll("led,ledon"); + Serial.println(F("LED-ON")); + } } btnState = LOW; } else { @@ -267,12 +282,41 @@ void mytimer() { } #ifdef USE_AUTH_COOKIE + unsigned long key[4] = {0x01F20304,0x05060708,0x090a0b0c,0x0d0e0f00}; + Xtea x(key); + +void encip(String &mtk, unsigned long token){ + unsigned long res[2] = {random(0xFFFFFFFF),token}; + x.encrypt(res); + char buf1[18]; + sprintf(buf1, "%08X_%08X",res[0],res[1]); //8 bytes for encryping the IP cookie + mtk = (String)buf1; +} + +unsigned long decip(const char *pch){ + unsigned long res[2] = {0,0}; + res[0] = strtoul(pch, NULL, 16); + res[1] = strtoul(&pch[9], NULL, 16); + x.decrypt(res); + return res[1]; +} + bool myHandshake(AsyncWebServerRequest *request){ // false will 401 + bool rslt = false; if (request->hasHeader("Cookie")){ String cookie = request->header("Cookie"); - if (cookie.indexOf(MY_COOKIE) != -1) return true; - else return false; - } else return false; + Serial.println(cookie); + + uint8_t pos = cookie.indexOf(MY_COOKIE_PREF); + if (pos != -1){ + unsigned long ix = decip(cookie.substring(pos+5, pos+22).c_str()); + Serial.printf("Ask:%08X Got:%08X\n", MY_SECRET_NUMBER, ix); + if (MY_SECRET_NUMBER == ix) + rslt=true; + } else rslt=false; + } else rslt=false; + Serial.printf(rslt ? "C-YES\n" : "C-NO\n"); + return rslt; } #endif @@ -322,8 +366,7 @@ void onWsEvent(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventT ws.textAll("led,ledoff"); } digitalWrite(ledPin, ledState); // apply change - - + } else if(data[0] == 'T') { // timeset if (len > 11) { data[3] = data[6] = data[9] = data[12] = 0; // cut strings @@ -444,7 +487,8 @@ void setup(){ } #endif - Serial.print(F("*CONNECTED*\n")); + Serial.print(F("*CONNECTED* OWN IP:")); + Serial.println(WiFi.localIP()); //DHT dht.begin(); @@ -492,25 +536,41 @@ void setup(){ server.addHandler(new SPIFFSEditor(SPIFFS, http_username,http_password)); #elif defined(USE_AUTH_COOKIE) server.addHandler(new SPIFFSEditor(SPIFFS)).setFilter(myHandshake); + #else + server.addHandler(new SPIFFSEditor(SPIFFS)); #endif #elif defined(ESP8266) #ifdef USE_AUTH_STAT server.addHandler(new SPIFFSEditor(http_username,http_password)); #elif defined(USE_AUTH_COOKIE) server.addHandler(new SPIFFSEditor()).setFilter(myHandshake); + #else + server.addHandler(new SPIFFSEditor()); #endif #endif #ifdef USE_AUTH_COOKIE - server.on("/lg2n", HTTP_POST, [](AsyncWebServerRequest *request){ // cookie test - if((request->hasParam("pa2w",true) && (String(request->getParam("pa2w",true)->value().c_str()) == String(http_password)))||(request->hasParam("lg0f",true))){ - AsyncWebServerResponse *response = request->beginResponse(301); + server.on("/lg2n", HTTP_POST, [](AsyncWebServerRequest *request){ + + String ckx; + encip(ckx, MY_SECRET_NUMBER); + + AsyncWebServerResponse *response; + + if(request->hasParam("lg0f",true)){ + response = request->beginResponse(200, "text/html;charset=utf-8", "

Logged Out! Back

"); + response->addHeader("Cache-Control", "no-cache"); + response->addHeader("Set-Cookie", MY_COOKIE_DEL); + + } else if(request->hasParam("pa2w",true) && (String(request->getParam("pa2w",true)->value().c_str()) == String(http_password))){ + response = request->beginResponse(301); response->addHeader("Location", "/"); response->addHeader("Cache-Control", "no-cache"); - if(request->hasParam("lg0f",true)) response->addHeader("Set-Cookie", MY_COOKIE_DEL); - else response->addHeader("Set-Cookie", MY_COOKIE_FULL); - request->send(response); - } else request->send(200, "text/plain","Wrong Password!"); + response->addHeader("Set-Cookie", MY_COOKIE_PREF + ckx + MY_COOKIE_SUFF); + + } else response = request->beginResponse(200, "text/html;charset=utf-8", "

Wrong password! Back

"); + + request->send(response); }); #endif @@ -520,7 +580,14 @@ void setup(){ #ifdef USE_AUTH_STAT if(!request->authenticate(http_username, http_password)) return request->requestAuthentication(); #endif - request->send(200, "text/plain", String(ESP.getFreeHeap())); + +#ifdef ESP32 + request->send(200, "text/plain", String(ESP.getMinFreeHeap()) + ':' + String(ESP.getFreeHeap()) + ':'+ String(ESP.getHeapSize())); +#else + request->send(200, "text/plain", String(ESP.getFreeHeap())); +#endif + + #ifdef USE_AUTH COOKIE }).setFilter(myHandshake); #else @@ -584,7 +651,7 @@ void setup(){ #ifdef USE_AUTH_COOKIE server.serveStatic("/", SPIFFS, "/").setDefaultFile("index.htm").setFilter(myHandshake); - server.serveStatic("/", SPIFFS, "/login/").setDefaultFile("index.htm").setFilter(!myHandshake); + server.serveStatic("/", SPIFFS, "/login/").setDefaultFile("index.htm"); #else #ifdef USE_AUTH_STAT server.serveStatic("/", SPIFFS, "/").setDefaultFile("index.htm").setAuthentication(http_username,http_password); diff --git a/examples/SmartSwitch/Xtea.cpp b/examples/SmartSwitch/Xtea.cpp new file mode 100644 index 000000000..97d99b0ab --- /dev/null +++ b/examples/SmartSwitch/Xtea.cpp @@ -0,0 +1,48 @@ +/* + Xtea.cpp - Xtea encryption/decryption + Written by Frank Kienast in November, 2010 + https://github.com/franksmicro/Arduino/tree/master/libraries/Xtea +*/ +#include +#include "Xtea.h" + +#define NUM_ROUNDS 32 + +Xtea::Xtea(unsigned long key[4]) +{ + _key[0] = key[0]; + _key[1] = key[1]; + _key[2] = key[2]; + _key[3] = key[3]; +} + +void Xtea::encrypt(unsigned long v[2]) +{ + unsigned int i; + unsigned long v0=v[0], v1=v[1], sum=0, delta=0x9E3779B9; + + for (i=0; i < NUM_ROUNDS; i++) + { + v0 += (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + _key[sum & 3]); + sum += delta; + v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + _key[(sum>>11) & 3]); + } + + v[0]=v0; v[1]=v1; +} + +void Xtea::decrypt(unsigned long v[2]) +{ + unsigned int i; + uint32_t v0=v[0], v1=v[1], delta=0x9E3779B9, sum=delta*NUM_ROUNDS; + + for (i=0; i < NUM_ROUNDS; i++) + { + v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + _key[(sum>>11) & 3]); + sum -= delta; + v0 -= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + _key[sum & 3]); + } + + v[0]=v0; v[1]=v1; +} + diff --git a/examples/SmartSwitch/Xtea.h b/examples/SmartSwitch/Xtea.h new file mode 100644 index 000000000..fc8fa43cc --- /dev/null +++ b/examples/SmartSwitch/Xtea.h @@ -0,0 +1,20 @@ +/* + Xtea.h - Crypto library + Written by Frank Kienast in November, 2010 + https://github.com/franksmicro/Arduino/tree/master/libraries/Xtea +*/ +#ifndef Xtea_h +#define Xtea_h + + +class Xtea +{ + public: + Xtea(unsigned long key[4]); + void encrypt(unsigned long data[2]); + void decrypt(unsigned long data[2]); + private: + unsigned long _key[4]; +}; + +#endif diff --git a/examples/SmartSwitch/data/acefull.js.gz b/examples/SmartSwitch/data/acefull.js.gz index 00cdd5f934f68062b7484b87eedd6b1d99bf0815..11645575f7869e10ce99a2c4199995a224fd0142 100644 GIT binary patch delta 21 dcmdnAl6})kc6Rx04i1gZbB*j<*%?<~0RU9X2gv{c delta 21 dcmdnAl6})kc6Rx04vsA0?TzeP*%?<~0RU2g2Yvtm diff --git a/examples/SmartSwitch/data/index.htm b/examples/SmartSwitch/data/index.htm index 68aaefa90..c9c24fa16 100644 --- a/examples/SmartSwitch/data/index.htm +++ b/examples/SmartSwitch/data/index.htm @@ -1,5 +1,4 @@ - @@ -115,13 +114,13 @@ } .clk { - font-size: 54px; + font-size: 52px; color: #444; cursor: pointer } .clk2 { - font-size: 32px; + font-size: 24px; color: #444 } @@ -329,7 +328,7 @@
-

Logoff

+ @@ -378,10 +377,10 @@ }, { color: "#32a852", lo: 0, - hi: 25 + hi: 35 }, { color: "#ff4d4d", - lo: 25, + lo: 35, hi: 50 }], formatNumber: true @@ -531,7 +530,7 @@ message: 'Timer REQ' }); } - }; + } function button2Click(e) { if (connection.readyState === WebSocket.OPEN) { @@ -540,32 +539,40 @@ message: 'Temp. REQ' }); } - }; + } function buttonEClick() { var murl = '/edit'; if (document.location.host.length < 5) murl = 'http://' + MYCORS + '/edit'; //CORS - successNotification({ - message: 'Editor' - }); + successNotification({message: 'Editor'}); window.open(murl, '_blank'); - }; - + } + + function buttonOClick() { + // If base auth + var murl = document.location.href.replace("http://", "http://" + new Date().getTime() + "@"); + // If cookie auth + murl += 'login'; + if (document.location.host.length < 5) murl = 'http://' + MYCORS + '/login'; //CORS + warningNotification({ message: 'Logout'}); + window.open(murl, '_self'); + } + function checkboxClick(e) { if (connection.readyState === WebSocket.OPEN) { if (e.checked) connection.send('L1'); else connection.send('L0'); } - }; + } function ent1Click() { document.getElementById("input-temperature").className = "blinking"; - }; + } function ent2Click() { document.getElementById("input-popup-stop").className = "blinking"; document.getElementById("input-popup-start").className = "blinking"; - }; + } function handleClick(e) { if (e.value == 'Z0' ) auto = true; diff --git a/examples/SmartSwitch/data/index.min.htm.gz b/examples/SmartSwitch/data/index.min.htm.gz index a898dd0ce3cc8537526e7b69deb9d311e464eff4..c5bc134d8203c6eaff5e6cd7f4b641fd489fe8b2 100644 GIT binary patch literal 3328 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 K7~@siD*yoDr+1bB literal 4193 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 diff --git a/examples/SmartSwitch/data/login/index.htm b/examples/SmartSwitch/data/login/index.htm index 5e39f6f00..d17ef7f49 100644 --- a/examples/SmartSwitch/data/login/index.htm +++ b/examples/SmartSwitch/data/login/index.htm @@ -8,13 +8,29 @@ -
+ +


-

Password

+

Login - Logout

-

-

+

+

-
+ +
Back +
+ + + \ No newline at end of file diff --git a/examples/SmartSwitch/data/worker-css.js.gz b/examples/SmartSwitch/data/worker-css.js.gz index 36849854f5e68ac7c3f494cc8f1af284f760dc17..61fdcd34d54c969b12c55d75d0ed73e69b636123 100644 GIT binary patch delta 18 acmbO|m1*`=CU*I54i5Fsa~s*GbO8W5$p(4= delta 18 acmbO|m1*`=CU*I54vtLW?Hk#rbO8W4U Date: Fri, 5 Jun 2020 07:40:37 -0400 Subject: [PATCH 057/551] LittleFS can be used (a choice for ESP8266 for now) - To make and upload FS https://github.com/earlephilhower/arduino-esp8266littlefs-plugin - Simply redefine SPIFFS to LittleFS Changes are in src/SPIFFSEditor.cpp including the src/edit.htm See ESP_AsyncFSBrowser and SmartSwitch examples --- README.md | 215 +++++---- .../ESP_AsyncFSBrowser/ESP_AsyncFSBrowser.ino | 7 + examples/ESP_AsyncFSBrowser/data/ace.js.gz | Bin 98943 -> 0 bytes .../ESP_AsyncFSBrowser/data/acefull.js.gz | Bin 0 -> 119986 bytes .../data/ext-searchbox.js.gz | Bin 3131 -> 0 bytes .../ESP_AsyncFSBrowser/data/folder/image.jpg | Bin 0 -> 6071 bytes .../ESP_AsyncFSBrowser/data/folder/test.txt | 1 + .../ESP_AsyncFSBrowser/data/mode-css.js.gz | Bin 6102 -> 0 bytes .../ESP_AsyncFSBrowser/data/mode-html.js.gz | Bin 17037 -> 0 bytes .../data/mode-javascript.js.gz | Bin 6315 -> 0 bytes .../ESP_AsyncFSBrowser/data/worker-css.js.gz | Bin 0 -> 35483 bytes .../ESP_AsyncFSBrowser/data/worker-html.js.gz | Bin 50024 -> 47406 bytes .../data/worker-javascript.js.gz | Bin 0 -> 47729 bytes examples/SmartSwitch/README.md | 48 +- examples/SmartSwitch/SmartSwitch.ino | 20 +- examples/SmartSwitch/data/acefull.js.gz | Bin 119986 -> 119986 bytes examples/SmartSwitch/data/index.htm | 7 +- examples/SmartSwitch/data/index.min.htm.gz | Bin 3328 -> 0 bytes examples/SmartSwitch/data/worker-css.js.gz | Bin 35483 -> 35483 bytes examples/SmartSwitch/data/worker-html.js.gz | Bin 47406 -> 47406 bytes .../SmartSwitch/data/worker-javascript.js.gz | Bin 47729 -> 47729 bytes extras/README.md | 22 +- extras/update_ace.bat | 14 +- src/SPIFFSEditor.cpp | 13 +- src/edit.htm | 19 +- src/edit.htm.gz.h | 449 +++++++++--------- 26 files changed, 424 insertions(+), 391 deletions(-) delete mode 100644 examples/ESP_AsyncFSBrowser/data/ace.js.gz create mode 100644 examples/ESP_AsyncFSBrowser/data/acefull.js.gz delete mode 100644 examples/ESP_AsyncFSBrowser/data/ext-searchbox.js.gz create mode 100644 examples/ESP_AsyncFSBrowser/data/folder/image.jpg create mode 100644 examples/ESP_AsyncFSBrowser/data/folder/test.txt delete mode 100644 examples/ESP_AsyncFSBrowser/data/mode-css.js.gz delete mode 100644 examples/ESP_AsyncFSBrowser/data/mode-html.js.gz delete mode 100644 examples/ESP_AsyncFSBrowser/data/mode-javascript.js.gz create mode 100644 examples/ESP_AsyncFSBrowser/data/worker-css.js.gz create mode 100644 examples/ESP_AsyncFSBrowser/data/worker-javascript.js.gz delete mode 100644 examples/SmartSwitch/data/index.min.htm.gz diff --git a/README.md b/README.md index 3b4bae6f9..7563bfb6a 100644 --- a/README.md +++ b/README.md @@ -1,20 +1,17 @@ # In this fork - -SPIFFSEditor improvements - -Added [extras](https://github.com/lorol/ESPAsyncWebServer/tree/master/extras) folder with (Win) tools for re-packing, allow editing, updating and compressing html to binary arrays, embedded to source - -Added a [SmartSwitch](https://github.com/lorol/ESPAsyncWebServer/tree/master/examples/SmartSwitch) example to test code features - -Applied the memory optimizations from [sascha432](https://github.com/sascha432/ESPAsyncWebServer) fork - -Cookie Authentication including on Websocket part, based on [ayushsharma82](https://github.com/me-no-dev/ESPAsyncWebServer/pull/684) PR, new functions added: - -- For Websocket: ```void handleHandshake(AwsHandshakeHandler handler) ``` -- For EventSource: ```void authorizeConnect(ArAuthorizeConnectHandler cb)``` - -# ESPAsyncWebServer - +- SPIFFSEditor improvements +- Added [extras](https://github.com/lorol/ESPAsyncWebServer/tree/master/extras) folder with (Win) tools for re-packing, allow editing, updating and compressing html to binary arrays, embedded to source +- Added a [SmartSwitch](https://github.com/lorol/ESPAsyncWebServer/tree/master/examples/SmartSwitch) example to test code features +- Applied the memory optimizations from [sascha432](https://github.com/sascha432/ESPAsyncWebServer) fork +- Cookie Authentication including on Websocket part, based on [ayushsharma82](https://github.com/me-no-dev/ESPAsyncWebServer/pull/684) PR, new functions added: + - For Websocket: ```void handleHandshake(AwsHandshakeHandler handler) ``` + - For EventSource: ```void authorizeConnect(ArAuthorizeConnectHandler cb)``` +- [Additions to this README.md from jendakol' PR](https://github.com/me-no-dev/ESPAsyncWebServer/pull/770) + - [Respond with file content using a callback and extra headers](#respond-with-file-content-using-a-callback-and-extra-headers) + - [Serving static files by custom handling](#serving-static-files-by-custom-handling) +------------------------------------------------------------------------------------------ + +# ESPAsyncWebServer [![Build Status](https://travis-ci.org/me-no-dev/ESPAsyncWebServer.svg?branch=master)](https://travis-ci.org/me-no-dev/ESPAsyncWebServer) ![](https://github.com/me-no-dev/ESPAsyncWebServer/workflows/ESP%20Async%20Web%20Server%20CI/badge.svg) [![Codacy Badge](https://api.codacy.com/project/badge/Grade/395dd42cfc674e6ca2e326af3af80ffc)](https://www.codacy.com/manual/me-no-dev/ESPAsyncWebServer?utm_source=github.com&utm_medium=referral&utm_content=me-no-dev/ESPAsyncWebServer&utm_campaign=Badge_Grade) For help and support [![Join the chat at https://gitter.im/me-no-dev/ESPAsyncWebServer](https://badges.gitter.im/me-no-dev/ESPAsyncWebServer.svg)](https://gitter.im/me-no-dev/ESPAsyncWebServer?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) @@ -28,7 +25,6 @@ For ESP32 it requires [AsyncTCP](https://github.com/me-no-dev/AsyncTCP) to work To use this library you might need to have the latest git versions of [ESP32](https://github.com/espressif/arduino-esp32) Arduino Core ## Table of contents - - [ESPAsyncWebServer](#espasyncwebserver) - [Table of contents](#table-of-contents) - [Installation](#installation) @@ -70,6 +66,7 @@ To use this library you might need to have the latest git versions of [ESP32](ht - [Respond with content coming from a File containing templates](#respond-with-content-coming-from-a-file-containing-templates) - [Respond with content using a callback](#respond-with-content-using-a-callback) - [Respond with content using a callback and extra headers](#respond-with-content-using-a-callback-and-extra-headers) + - [Respond with file content using a callback and extra headers](#respond-with-file-content-using-a-callback-and-extra-headers) - [Respond with content using a callback containing templates](#respond-with-content-using-a-callback-containing-templates) - [Respond with content using a callback containing templates and extra headers](#respond-with-content-using-a-callback-containing-templates-and-extra-headers) - [Chunked Response](#chunked-response) @@ -84,6 +81,7 @@ To use this library you might need to have the latest git versions of [ESP32](ht - [Specifying Cache-Control header](#specifying-cache-control-header) - [Specifying Date-Modified header](#specifying-date-modified-header) - [Specifying Template Processor callback](#specifying-template-processor-callback) + - [Serving static files by custom handling](#serving-static-files-by-custom-handling) - [Param Rewrite With Matching](#param-rewrite-with-matching) - [Using filters](#using-filters) - [Serve different site files in AP mode](#serve-different-site-files-in-ap-mode) @@ -119,7 +117,7 @@ To use this library you might need to have the latest git versions of [ESP32](ht 3. Update dev/platform to staging version: - [Instruction for Espressif 8266](http://docs.platformio.org/en/latest/platforms/espressif8266.html#using-arduino-framework-with-staging-version) - [Instruction for Espressif 32](http://docs.platformio.org/en/latest/platforms/espressif32.html#using-arduino-framework-with-staging-version) - 4. Add "ESP Async WebServer" to project using [Project Configuration File `platformio.ini`](http://docs.platformio.org/page/projectconf.html) and [lib_deps](http://docs.platformio.org/page/projectconf/section_env_library.html#lib-deps) option: + 4. Add "ESP Async WebServer" to project using [Project Configuration File `platformio.ini`](http://docs.platformio.org/page/projectconf.html) and [lib_deps](http://docs.platformio.org/page/projectconf/section_env_library.html#lib-deps) option: ```ini [env:myboard] @@ -133,11 +131,9 @@ lib_deps = ESP Async WebServer # or using GIT Url (the latest development version) lib_deps = https://github.com/me-no-dev/ESPAsyncWebServer.git ``` - -5. Happy coding with PlatformIO! + 5. Happy coding with PlatformIO! ## Why should you care - - Using asynchronous network means that you can handle more than one connection at the same time - You are called once the request is ready and parsed - When you send the response, you are immediately ready to handle other connections @@ -153,7 +149,6 @@ lib_deps = https://github.com/me-no-dev/ESPAsyncWebServer.git - Simple template processing engine to handle templates ## Important things to remember - - This is fully asynchronous server and as such does not run on the loop thread. - You can not use yield or delay or any function that uses them inside the callbacks - The server is smart enough to know when to close the connection and free resources @@ -162,7 +157,6 @@ lib_deps = https://github.com/me-no-dev/ESPAsyncWebServer.git ## Principles of operation ### The Async Web server - - Listens for connections - Wraps the new clients into ```Request``` - Keeps track of clients and cleans memory @@ -170,7 +164,6 @@ lib_deps = https://github.com/me-no-dev/ESPAsyncWebServer.git - Manages ```Handlers``` and attaches them to Requests ### Request Life Cycle - - TCP connection is received by the server - The connection is wrapped inside ```Request``` object - When the request head is received (type, url, get params, http version and host), @@ -183,7 +176,6 @@ lib_deps = https://github.com/me-no-dev/ESPAsyncWebServer.git - When the ```Response``` is sent, the client is closed and freed from the memory ### Rewrites and how do they work - - The ```Rewrites``` are used to rewrite the request url and/or inject get parameters for a specific request url path. - All ```Rewrites``` are evaluated on the request in the order they have been added to the server. - The ```Rewrite``` will change the request url only if the request url (excluding get parameters) is fully match @@ -195,7 +187,6 @@ lib_deps = https://github.com/me-no-dev/ESPAsyncWebServer.git - The ```Rewrite``` can specify a target url with optional get parameters, e.g. ```/to-url?with=params``` ### Handlers and how do they work - - The ```Handlers``` are used for executing specific actions to particular requests - One ```Handler``` instance can be attached to any request and lives together with the server - Setting a ```Filter``` to the ```Handler``` enables to control when to apply the handler, decision can be based on @@ -213,7 +204,6 @@ lib_deps = https://github.com/me-no-dev/ESPAsyncWebServer.git - The first ```Handler``` that can handle the request is selected, not further ```Filter``` and ```canHandle``` are called. ### Responses and how do they work - - The ```Response``` objects are used to send the response data back to the client - The ```Response``` object lives with the ```Request``` and is freed on end or disconnect - Different techniques are used depending on the response type to send the data in packets @@ -223,7 +213,6 @@ lib_deps = https://github.com/me-no-dev/ESPAsyncWebServer.git - Many different options exist for the user to make responding a background task ### Template processing - - ESPAsyncWebserver contains simple template processing engine. - Template processing can be added to most response types. - Currently it supports only replacing template placeholders with actual values. No conditional processing, cycles, etc. @@ -233,7 +222,6 @@ lib_deps = https://github.com/me-no-dev/ESPAsyncWebServer.git - Since it's impossible to know the actual response size after template processing step in advance (and, therefore, to include it in response headers), the response becomes [chunked](#chunked-response). ## Libraries and projects that use AsyncWebServer - - [WebSocketToSerial](https://github.com/hallard/WebSocketToSerial) - Debug serial devices through the web browser - [Sattrack](https://github.com/Hopperpop/Sattrack) - Track the ISS with ESP8266 - [ESP Radio](https://github.com/Edzelf/Esp-radio) - Icecast radio based on ESP8266 and VS1053 @@ -245,7 +233,6 @@ lib_deps = https://github.com/me-no-dev/ESPAsyncWebServer.git ## Request Variables ### Common Variables - ```cpp request->version(); // uint8_t: 0 = HTTP/1.0, 1 = HTTP/1.1 request->method(); // enum: HTTP_GET, HTTP_POST, HTTP_DELETE, HTTP_PUT, HTTP_PATCH, HTTP_HEAD, HTTP_OPTIONS @@ -257,7 +244,6 @@ request->multipart(); // bool: True if the request has content type "mult ``` ### Headers - ```cpp //List all collected headers int headers = request->headers(); @@ -287,7 +273,6 @@ if(request->hasHeader("MyHeader")){ ``` ### GET, POST and FILE parameters - ```cpp //List all parameters int params = request->params(); @@ -326,7 +311,6 @@ if(request->hasArg("download")) ``` ### FILE Upload handling - ```cpp void handleUpload(AsyncWebServerRequest *request, String filename, size_t index, uint8_t *data, size_t len, bool final){ if(!index){ @@ -342,7 +326,6 @@ void handleUpload(AsyncWebServerRequest *request, String filename, size_t index, ``` ### Body data handling - ```cpp void handleBody(AsyncWebServerRequest *request, uint8_t *data, size_t len, size_t index, size_t total){ if(!index){ @@ -356,13 +339,10 @@ void handleBody(AsyncWebServerRequest *request, uint8_t *data, size_t len, size_ } } ``` - If needed, the `_tempObject` field on the request can be used to store a pointer to temporary data (e.g. from the body) associated with the request. If assigned, the pointer will automatically be freed along with the request. ### JSON body handling with ArduinoJson - Endpoints which consume JSON can use a special handler to get ready to use JSON data in the request callback: - ```cpp #include "AsyncJson.h" #include "ArduinoJson.h" @@ -375,9 +355,7 @@ server.addHandler(handler); ``` ## Responses - ### Redirect to another URL - ```cpp //to local url request->redirect("/login"); @@ -387,13 +365,11 @@ request->redirect("http://esp8266.com"); ``` ### Basic response with HTTP Code - ```cpp request->send(404); //Sends 404 File Not Found ``` ### Basic response with HTTP Code and extra headers - ```cpp AsyncWebServerResponse *response = request->beginResponse(404); //Sends 404 File Not Found response->addHeader("Server","ESP Async Web Server"); @@ -401,13 +377,11 @@ request->send(response); ``` ### Basic response with string content - ```cpp request->send(200, "text/plain", "Hello World!"); ``` ### Basic response with string content and extra headers - ```cpp AsyncWebServerResponse *response = request->beginResponse(200, "text/plain", "Hello World!"); response->addHeader("Server","ESP Async Web Server"); @@ -415,14 +389,12 @@ 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); @@ -431,7 +403,6 @@ request->send(response); ``` ### Send large webpage from PROGMEM containing templates - ```cpp String processor(const String& var) { @@ -447,7 +418,6 @@ request->send_P(200, "text/html", index_html, processor); ``` ### Send large webpage from PROGMEM containing templates and extra headers - ```cpp String processor(const String& var) { @@ -465,8 +435,8 @@ 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 = { @@ -524,14 +494,12 @@ request->send(response); ``` ### Respond with content coming from a Stream - ```cpp //read 12 bytes from Serial and send them as Content Type text/plain request->send(Serial, "text/plain", 12); ``` ### Respond with content coming from a Stream and extra headers - ```cpp //read 12 bytes from Serial and send them as Content Type text/plain AsyncWebServerResponse *response = request->beginResponse(Serial, "text/plain", 12); @@ -540,7 +508,6 @@ request->send(response); ``` ### Respond with content coming from a Stream containing templates - ```cpp String processor(const String& var) { @@ -556,7 +523,6 @@ request->send(Serial, "text/plain", 12, processor); ``` ### Respond with content coming from a Stream containing templates and extra headers - ```cpp String processor(const String& var) { @@ -574,7 +540,6 @@ request->send(response); ``` ### Respond with content coming from a File - ```cpp //Send index.htm with default content type request->send(SPIFFS, "/index.htm"); @@ -587,7 +552,6 @@ request->send(SPIFFS, "/index.htm", String(), true); ``` ### Respond with content coming from a File and extra headers - ```cpp //Send index.htm with default content type AsyncWebServerResponse *response = request->beginResponse(SPIFFS, "/index.htm"); @@ -603,17 +567,14 @@ request->send(response); ``` ### Respond with content coming from a File containing templates - Internally uses [Chunked Response](#chunked-response). Index.htm contents: - ``` %HELLO_FROM_TEMPLATE% ``` Somewhere in source files: - ```cpp String processor(const String& var) { @@ -629,7 +590,6 @@ request->send(SPIFFS, "/index.htm", String(), false, processor); ``` ### Respond with content using a callback - ```cpp //send 128 bytes as plain text request->send("text/plain", 128, [](uint8_t *buffer, size_t maxLen, size_t index) -> size_t { @@ -643,7 +603,6 @@ request->send("text/plain", 128, [](uint8_t *buffer, size_t maxLen, size_t index ``` ### Respond with content using a callback and extra headers - ```cpp //send 128 bytes as plain text AsyncWebServerResponse *response = request->beginResponse("text/plain", 128, [](uint8_t *buffer, size_t maxLen, size_t index) -> size_t { @@ -658,8 +617,44 @@ response->addHeader("Server","ESP Async Web Server"); request->send(response); ``` -### Respond with content using a callback containing templates +### Respond with file content using a callback and extra headers +With this code your ESP is able to serve even large (large in terms of ESP, e.g. 100kB) files +without memory problems. + +You need to create a file handler in outer function (to have a single one for request) but use +it in a lambda. The catch is that the lambda has it's own lifecycle which may/will cause it's +called after the original function is over thus the original file handle is destroyed. Using the +captured `&file` in the lambda then causes segfault (Hello, Exception 9!) and the whole ESP crashes. +By using this code, you tell the compiler to move the handle into the lambda so it won't be +destroyed when outer function (that one where you call `request->send(response)`) ends. + +```cpp +const File file = ... // e.g. SPIFFS.open(path, "r"); + +const contentType = "application/javascript"; + +AsyncWebServerResponse *response = request->beginResponse( + contentType, + file.size(), + [file](uint8_t *buffer, size_t maxLen, size_t total) mutable -> size_t { + int bytes = file.read(buffer, maxLen); + + // close file at the end + if (bytes + total == file.size()) file.close(); + + return max(0, bytes); // return 0 even when no bytes were loaded + } +); + +if (gzipped) { + response->addHeader(F("Content-Encoding"), F("gzip")); +} + +request->send(response); +``` + +### Respond with content using a callback containing templates ```cpp String processor(const String& var) { @@ -682,7 +677,6 @@ request->send("text/plain", 128, [](uint8_t *buffer, size_t maxLen, size_t index ``` ### Respond with content using a callback containing templates and extra headers - ```cpp String processor(const String& var) { @@ -707,9 +701,7 @@ request->send(response); ``` ### Chunked Response - Used when content length is unknown. Works best if the client supports HTTP/1.1 - ```cpp AsyncWebServerResponse *response = request->beginChunkedResponse("text/plain", [](uint8_t *buffer, size_t maxLen, size_t index) -> size_t { //Write up to "maxLen" bytes into "buffer" and return the amount written. @@ -723,9 +715,7 @@ request->send(response); ``` ### Chunked Response containing templates - Used when content length is unknown. Works best if the client supports HTTP/1.1 - ```cpp String processor(const String& var) { @@ -748,7 +738,6 @@ request->send(response); ``` ### Print to response - ```cpp AsyncResponseStream *response = request->beginResponseStream("text/html"); response->addHeader("Server","ESP Async Web Server"); @@ -799,9 +788,7 @@ request->send(response); ``` ### ArduinoJson Basic Response - This way of sending Json is great for when the result is below 4KB - ```cpp #include "AsyncJson.h" #include "ArduinoJson.h" @@ -817,13 +804,11 @@ request->send(response); ``` ### ArduinoJson Advanced Response - This response can handle really large Json objects (tested to 40KB) There isn't any noticeable speed decrease for small results with the method above Since ArduinoJson does not allow reading parts of the string, the whole Json has to be passed every time a chunks needs to be sent, which shows speed decrease proportional to the resulting json packets - ```cpp #include "AsyncJson.h" #include "ArduinoJson.h" @@ -839,7 +824,6 @@ request->send(response); ``` ## Serving static files - In addition to serving files from SPIFFS as described above, the server provide a dedicated handler that optimize the performance of serving files from SPIFFS - ```AsyncStaticWebHandler```. Use ```server.serveStatic()``` function to initialize and add a new instance of ```AsyncStaticWebHandler``` to the server. @@ -848,16 +832,13 @@ handler that can handle the request. Notice that you can chain setter functions to setup the handler, or keep a pointer to change it at a later time. ### Serving specific file by name - ```cpp // Serve the file "/www/page.htm" when request url is "/page.htm" server.serveStatic("/page.htm", SPIFFS, "/www/page.htm"); ``` ### Serving files in directory - To serve files in a directory, the path to the files should specify a directory in SPIFFS and ends with "/". - ```cpp // Serve files in directory "/www/" when request url starts with "/" // Request to the root or none existing files will try to server the defualt @@ -878,10 +859,8 @@ server ``` ### Specifying Cache-Control header - It is possible to specify Cache-Control header value to reduce the number of calls to the server once the client loaded the files. For more information on Cache-Control values see [Cache-Control](https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9) - ```cpp // Cache responses for 10 minutes (600 seconds) server.serveStatic("/", SPIFFS, "/www/").setCacheControl("max-age=600"); @@ -896,10 +875,8 @@ handler->setCacheControl("max-age=30"); ``` ### Specifying Date-Modified header - It is possible to specify Date-Modified header to enable the server to return Not-Modified (304) response for requests with "If-Modified-Since" header with the same value, instead of responding with the actual file content. - ```cpp // Update the date modified string every time files are updated server.serveStatic("/", SPIFFS, "/www/").setLastModified("Mon, 20 Jun 2016 14:00:00 GMT"); @@ -918,10 +895,8 @@ handler->setLastModified(date_modified); ``` ### Specifying Template Processor callback - It is possible to specify template processor for static files. For information on template processor see [Respond with content coming from a File containing templates](#respond-with-content-coming-from-a-file-containing-templates). - ```cpp String processor(const String& var) { @@ -935,8 +910,54 @@ String processor(const String& var) server.serveStatic("/", SPIFFS, "/www/").setTemplateProcessor(processor); ``` -## Param Rewrite With Matching +### Serving static files by custom handling + +It may happen your static files are too big and the ESP will crash the request before it sends the whole file. +In that case, you can handle static files with custom file serving through not found handler. + +This code below is more-or-less equivalent to this: +```cpp +webServer.serveStatic("/", SPIFFS, STATIC_FILES_PREFIX).setDefaultFile("index.html") +``` + +First, declare the handling function: +```cpp +bool handleStaticFile(AsyncWebServerRequest *request) { + String path = STATIC_FILES_PREFIX + request->url(); + + if (path.endsWith("/")) path += F("index.html"); + + String contentType = getContentType(path); + String pathWithGz = path + ".gz"; + + if (SPIFFS.exists(pathWithGz) || SPIFFS.exists(path)) { + bool gzipped = false; + if (SPIFFS.exists(pathWithGz)) { + gzipped = true; + path += ".gz"; + } + + // TODO serve the file + + return true; + } + + return false; +} +``` +And then configure your webserver: +```cpp +webServer.onNotFound([](AsyncWebServerRequest *request) { + if (handleStaticFile(request)) return; + + request->send(404); +}); +``` + +You may want to try [Respond with file content using a callback and extra headers](#respond-with-file-content-using-a-callback-and-extra-headers) +For actual serving the file. +## Param Rewrite With Matching It is possible to rewrite the request url with parameter matchg. Here is an example with one parameter: Rewrite for example "/radio/{frequence}" -> "/radio?f={frequence}" @@ -989,24 +1010,20 @@ Usage: ``` ## Using filters - Filters can be set to `Rewrite` or `Handler` in order to control when to apply the rewrite and consider the handler. A filter is a callback function that evaluates the request and return a boolean `true` to include the item or `false` to exclude it. Two filter callback are provided for convince: - * `ON_STA_FILTER` - return true when requests are made to the STA (station mode) interface. * `ON_AP_FILTER` - return true when requests are made to the AP (access point) interface. ### Serve different site files in AP mode - ```cpp server.serveStatic("/", SPIFFS, "/www/").setFilter(ON_STA_FILTER); server.serveStatic("/", SPIFFS, "/ap/").setFilter(ON_AP_FILTER); ``` ### Rewrite to different index on AP - ```cpp // Serve the file "/www/index-ap.htm" in AP, and the file "/www/index.htm" on STA server.rewrite("/", "index.htm"); @@ -1015,7 +1032,6 @@ server.serveStatic("/", SPIFFS, "/www/"); ``` ### Serving different hosts - ```cpp // Filter callback using request host bool filterOnHost1(AsyncWebServerRequest *request) { return request->host() == "host1"; } @@ -1026,7 +1042,6 @@ server.serveStatic("/", SPIFFS, "/www/"); ``` ### Determine interface inside callbacks - ```cpp String RedirectUrl = "http://"; if (ON_STA_FILTER(request)) { @@ -1039,13 +1054,11 @@ server.serveStatic("/", SPIFFS, "/www/"); ``` ## Bad Responses - Some responses are implemented, but you should not use them, because they do not conform to HTTP. The following example will lead to unclean close of the connection and more time wasted than providing the length of the content ### Respond with content using a callback without content length to HTTP/1.0 clients - ```cpp //This is used as fallback for chunked responses to HTTP/1.0 Clients request->send("text/plain", 0, [](uint8_t *buffer, size_t maxLen, size_t index) -> size_t { @@ -1057,13 +1070,12 @@ request->send("text/plain", 0, [](uint8_t *buffer, size_t maxLen, size_t index) ``` ## Async WebSocket Plugin - The server includes a web socket plugin which lets you define different WebSocket locations to connect to without starting another listening service or using different port ### Async WebSocket Event - ```cpp + void onEvent(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventType type, void * arg, uint8_t *data, size_t len){ if(type == WS_EVT_CONNECT){ //client connected @@ -1133,8 +1145,10 @@ void onEvent(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventTyp ``` ### Methods for sending data to a socket client - ```cpp + + + //Server methods AsyncWebSocket ws("/ws"); //printf to a client @@ -1189,7 +1203,6 @@ client->binary(flash_binary, 4); ``` ### Direct access to web socket message buffer - When sending a web socket message using the above methods a buffer is created. Under certain circumstances you might want to manipulate or populate this buffer directly from your application, for example to prevent unnecessary duplications of the data. This example below shows how to create a buffer and print data to it from an ArduinoJson object then send it. ```cpp @@ -1216,7 +1229,6 @@ void sendDataWs(AsyncWebSocketClient * client) ``` ### Limiting the number of web socket clients - Browsers sometimes do not correctly close the websocket connection, even when the close() function is called in javascript. This will eventually exhaust the web server's resources and will cause the server to crash. Periodically calling the cleanClients() function from the main loop() function limits the number of clients by closing the oldest client when the maximum number of clients has been exceeded. This can called be every cycle, however, if you wish to use less power, then calling as infrequently as once per second is sufficient. ```cpp @@ -1225,13 +1237,12 @@ void loop(){ } ``` -## Async Event Source Plugin +## Async Event Source Plugin The server includes EventSource (Server-Sent Events) plugin which can be used to send short text events to the browser. Difference between EventSource and WebSockets is that EventSource is single direction, text-only protocol. ### Setup Event Source on the server - ```cpp AsyncWebServer server(80); AsyncEventSource events("/events"); @@ -1261,7 +1272,6 @@ void loop(){ ``` ### Setup Event Source in the browser - ```javascript if (!!window.EventSource) { var source = new EventSource('/events'); @@ -1287,7 +1297,6 @@ if (!!window.EventSource) { ``` ## Scanning for available WiFi Networks - ```cpp //First request will return 0 results unless you start scan from somewhere else (loop/setup) //Do not request more often than 3-5 seconds @@ -1323,7 +1332,6 @@ server.on("/scan", HTTP_GET, [](AsyncWebServerRequest *request){ Server goes through handlers in same order as they were added. You can't simple add handler with same path to override them. To remove handler: - ```arduino // save callback for particular URL path auto handler = server.on("/some/path", [](AsyncWebServerRequest *request){ @@ -1347,7 +1355,6 @@ server.reset(); ``` ## Setting up the server - ```cpp #include "ESPAsyncTCP.h" #include "ESPAsyncWebServer.h" @@ -1548,6 +1555,7 @@ Example of OTA code ws.closeAll(); }); + ``` ### Adding Default Headers @@ -1587,11 +1595,11 @@ For example we want a `sensorId` parameter in a route rule to match only a integ String sensorId = request->pathArg(0); }); ``` - *NOTE*: All regex patterns starts with `^` and ends with `$` To enable the `Path variable` support, you have to define the buildflag `-DASYNCWEBSERVER_REGEX`. + For Arduino IDE create/update `platform.local.txt`: `Windows`: C:\Users\(username)\AppData\Local\Arduino15\packages\\`{espxxxx}`\hardware\\`espxxxx`\\`{version}`\platform.local.txt @@ -1599,17 +1607,14 @@ For Arduino IDE create/update `platform.local.txt`: `Linux`: ~/.arduino15/packages/`{espxxxx}`/hardware/`{espxxxx}`/`{version}`/platform.local.txt Add/Update the following line: - ``` - compiler.cpp.extra_flags=-DASYNCWEBSERVER_REGEX + compiler.cpp.extra_flags=-DDASYNCWEBSERVER_REGEX ``` For platformio modify `platformio.ini`: - ```ini [env:myboard] build_flags = -DASYNCWEBSERVER_REGEX ``` - *NOTE*: By enabling `ASYNCWEBSERVER_REGEX`, `` will be included. This will add an 100k to your binary. diff --git a/examples/ESP_AsyncFSBrowser/ESP_AsyncFSBrowser.ino b/examples/ESP_AsyncFSBrowser/ESP_AsyncFSBrowser.ino index bf42d0038..205643333 100644 --- a/examples/ESP_AsyncFSBrowser/ESP_AsyncFSBrowser.ino +++ b/examples/ESP_AsyncFSBrowser/ESP_AsyncFSBrowser.ino @@ -1,3 +1,5 @@ +#define USE_LittleFS // possible only for ESP8266 for now + #include #ifdef ESP32 #include @@ -6,6 +8,11 @@ #include #include #elif defined(ESP8266) + #ifdef USE_LittleFS + #include + #define SPIFFS LittleFS + #include + #endif #include #include #include diff --git a/examples/ESP_AsyncFSBrowser/data/ace.js.gz b/examples/ESP_AsyncFSBrowser/data/ace.js.gz deleted file mode 100644 index 7b175c1c92c541999766de1f36c1e7141f0f7236..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 98943 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 diff --git a/examples/ESP_AsyncFSBrowser/data/acefull.js.gz b/examples/ESP_AsyncFSBrowser/data/acefull.js.gz new file mode 100644 index 0000000000000000000000000000000000000000..373060858ebd1d1e27f5489917f59a039dda37d1 GIT binary patch literal 119986 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 VGMhX(j|D9=`)`h{Z=Vz=005Io7cT$+ diff --git a/examples/ESP_AsyncFSBrowser/data/folder/image.jpg b/examples/ESP_AsyncFSBrowser/data/folder/image.jpg new file mode 100644 index 0000000000000000000000000000000000000000..3224d5aa7952d8825f61de9ac1d8834792b15d4d GIT binary patch literal 6071 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 diff --git a/examples/ESP_AsyncFSBrowser/data/mode-javascript.js.gz b/examples/ESP_AsyncFSBrowser/data/mode-javascript.js.gz deleted file mode 100644 index c0451c1c5dbe7eb3d41d2a4e0e7946b38e26b47d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6315 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 literal 0 HcmV?d00001 diff --git a/examples/ESP_AsyncFSBrowser/data/worker-html.js.gz b/examples/ESP_AsyncFSBrowser/data/worker-html.js.gz index ec8aa87a9524a68c1f6b2b53f12589ee0a14f43a..f93dbff3e22b5e0e7f7155eddca11283dab689fa 100644 GIT binary patch literal 47406 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 CdbSY& literal 50024 zcmV(*K;FL}iwFoR!jM=13wLjFYh`jRXmo9CE^2cCv^;B*+cuJaMdG=}WQ5^J-rUt4 zIkYO9cxzK-Us8^9Uo?t~mY^9V5~u~CjJ+fM_v^+RBsJr;@4k3M5a@1nH~NL96W)vt zEgiK|u$4^8baUV<$r_&0?7{vX$&?bAJ^WdV5w9o_Rg#qVcWg^ju18rV7kpW=O)5X_ zX|sWWDnXe1Hpv8)2f;^dB5(q8&-u1l)d)Wqbib`vG`+gH`sUdcNv@J?l8WPz<-3}3 z{LAYd&D8R$s>U+|1IR$^ZN>9#-O3;NntuFglj3@u+rr$-S@uED`j1k;r1tOuh)UaR zA_&LlEd#7m(q<<^6g~Mp(EOh9b#p(ik^?~AFizLW#RbjR&FZkDTpB766@@+gQDJzG_pbbnznpZZ?|bJZWX?kOtW&|wDJvY z+xnKK4>+?(w#{uq*0rn)ddg13A<3x_ji~(deJyzK2b(C`u!)*Y1JZt|NeI4OW9I6P+XDjZ$>c5}6ysCRbB$!a@Cz8b~#{8X}JpslPD zaMt-@yH&?&%*?hkc_*6t5vTW~S18{!xo^ZDROG+6BLgkXM)hh%_p%)|eEVsX?rQ-W z{NtL8*c#roBd64OR;xa{kqUFV9gX=;y=xat*_zgxk`}nfBvZ@RKzQ_Ajp2aj^y9t} zvaQ;DQ?FzrKBbu*%lvD#O^;4)xx*10niT9o{b5T-vKeigdOb=ehSsK%DI*;KR^b|> z5|@7g0VlvLFeYg;(Lb|b6RB)Rn&OAm{%I2!9pZwhDK# z0dt_@gb@SiS-27+1QjOO^}kRsd7|qHxmS)f0Sk7uWgo8SpP)_e>5fTB1z5LN`20#g z5;3%*Y4&iYSP0$f$0!&RIh?00MP)T|$q4>cj`ssNpUBY-x;UJf5Vi&%=6$e&f%HDT zUhOR*7~xpYC;`Mt`+nv_f{dWWWv9}z34d zxDc7h-?!|R*IPSCw13V@x`hByO-db zws6=}@gB@9^;%Q?^x=29lKBdvU3d_7Qd-lhUyQ)E<2od*MQN^1{WiTLV%(0FE99w>7w)uVf*n z3ssowSi%<6IFHNO5{cBF?k$`M(bB;cHs(`7mztK^fG^2H5PJ|nhfn$>yKG9noWk}m z&{^_Hr4t_c@?|y4C_MV8t<+I1M1k#1`^^=YxhwVS*;Q%Ly%TKrnr?7qkHA{ueg zTXuW*#42W2t(yHOtzOXrq)vjLC?hqX8EQa912vEqh)RA2U@Vp%Mm1H(R7Hd3|>L`K3OjT}S5sV%5<8f?LJaDs$ zTojj1<5;Wy!eWqTXBR-a-v#VIkuIY@1Kz55d8>lS0i?_Uz%5X2-?N5;CfrWp;H-lAD`n zvm^lb_jhkzKLP9l*IoSEU;eWUQ?3X*jb7`~|Cp8<^(~ceYKR|y+H6|d za}Am`3vYiNAW1?>dA>iicj-f;p!hg`(T(UYUo46KRajnwH-HF5AEOQA{dE03sOf$jpp^;e=Roh;;%~p0DUOh3KpT%HFXZZ4MITNRP)U_-_~6iM(CiQB@#-$WWb> z5R=s=9pV{~fEOSTi)3K_YD;TjkxC>&hh4acwLe3!0LO9&&k5%sN4E8+9z(ojOb{0U z-~mfm#1dYqS1R`kSRs%VGRqt%n8q5fy|{?B0@3ae5J2hK$l#&N#vcDpYEqYbgXoZW zocmB+Jp|OE=q4>gRgQFf%dOA>xz}S9i@> zbc&lD)|S+Zs+zimYE+TfH$jB!t?IZRiF9tJihy#Y5ps1+7@qrTHcvZ~gqkGcNiPcc zGo8O>CUZfKva?EWq{^oS^fvcdAbZv{^bJzo;X6 z9!zk)=-|<@pukcN!Lq?&5PGJ4C{`Y%gHuT>E7I;T>4T7&C#27rvt$HZiHWfMi%4*T zq`TOm2Q6ajZV2|sp`3eZsv!_^AQ?3@AI~7Agp4yn@s#AAz%vZ=ah*B?@;s$x!63-7 zS^eg)mFzXTvJ9e7u(YwT=kmHIY-I*sc0_>oq@dTG)i9I33}pw?`i^5RUsioA)8f)h z4*UqvQ*|*<3&0(3`RmWs+#(OT9wYf03ow5Y`j1a(^5-G=%AIc6{%v#L^>UbY1|++BxcA;x|y?0Mj-1aF3BeUDfPv>%r@Z^O; z8IH_4iseu^v+*RFag4?(Rx`LZ+G?=R?k0hpZM|=4tepJ=VmC6Ks|s~TSICq=YI>LN z>W|$wA0>RQ52;ofP!Xk)HSAtT0CeEw;UHv;V^XH~zx*F~t75TV2#Kfs$h9+-^WxJ6Y9;szXc9Qy%OX*_O)pqUTWMCeddoqW) z1)USi<1tA}d#!A^W^R{_o)xBPLDP#~v~gGVc*V$Qj$WolNy1XF-@cX)@43?so&d^PEEcR8tItS8;yWiHK?La1%kT3;+n zHs%rdRSMYMWebA{LVP8D1*Q+hPR-g(~Bh$)!<@ytr~c^Gst5R^ymfsEB+2g zX6k-J=J*z=Qa>u1DRb5AfA$PjZ#!cZ!-;#%#UC^|YF<24wOP<`=x;lkYFakemfo_N zOtJ?KW+T<^Uta(Y2vzqq;w6!QP0F4$ZEP$oAS_gy`~ATvdq{f6BM8Is)G~5t8v?c= z{5Aw^gTvtpk%J-VrdeLhr8IGIyXd{v5HlT zB?fQm0!CPu$6Q|^BtGp}wFNS3l3KjQLKIk_5{5Njyw6C=wr#RQx85D(8n%@LA4_4g znl6`7GWovQrEFP&yxdh@7M>WZEGLh**Uv8EZ#r@!Ze+7@9<`s zSF7)~TT5YF-5o%8aWQ004C^oh2-~+R(M<&S>aKapLz1|k=8Tv9EI$fp^QdLa4LsU) zhT-UUiqv6keAe*q?^LFv9_>^90eEg&gS5$$vWEB!9gg--7})xL^SM1)J|B$}wW2>k zwJV0VOwNYVIELhN>XH--uy8|mqzp5=YnR!n;)c115Wa+|g-#JH!6_#PAZ4!a;1u7?CT$FVDri~* zz2j)sr0vd|=&PWrs#Sfp!JC;vEjWZ=4;JjH*I3Amyl=gv&XrW2VL{MNde{75QWkxv zT-hY9GyqsT?;Kd0`j{2Zv^;db&v-^6HI0tA`o1A7ar$Z&4NFj#zUaG%pvc&HZOj#@ zq%J$!-Py{V-{b(rS=rP3xCBGS)8MwG&+_mflziT=85YI?oRfyFMOwP6N(2=?TM~1Z zd%>nz_2h<22UT<>?m(Kz+H`Fut2=!`{?KgK1tYqhPq=2(HAOqq&jZYM1_LVxGqz|J zq&8iBZ(w0o)YMJw0Etn;k|!{n;r(D#Why9CLy(12A1S{iv1rR0pYF~*apSG zj%#%lm4Ds2M&-G4Np0At5&H74@WUbAEU1cLiQ}{Ubff2Ksxn=C1h=7qYw|MV$VuJT zQk%;H=tagUe28;HIz=bGx8LXZe@pv*bBjX6-y#3OrNYB z|8IJa<6r^=1P$1J?JgoztKdMm71gv4njQLPEvf4|F}=B0^;OoFoqG2~qu!0U;l~@H z+Wa_v)TMiU@%O2C5{$uafE;i5l{0K$j_Jzoc<|;z)dkb5-|}zfsfUnV?TqVtRv%F%kl7_0#^~$tgORXZv@wMN);bq_gI+E-Jmu6n5b4WEO1Hp4Uf?v_8*M(zP=I z6g_m7Q(=|YFM3Bm%Eud)Eb_lK!nPHCu2tzS?H|Lk8~Xa#H<@%V^bOqW%P|DtTqx)n)YihPRqIiSIMMVRGMS0W)+7K3_p23M33eny}h6|W#KoNK{H`5)$aG|KZ_ z_=_L!+vKjlQuj^zwS5M<_KImnI^H5o9Pzu`L5tS?#BT^i1l#)E(tZtNx&@;YSgLBD zx|+q*1@ERXN0lm(ahJA0)a4~H9C2}l*Oy1q8z(m`-NdIinEQoCIH=Qk7iSTs(gpgn z@TPtu7k;wq#Q3ViE>CCAx#)hQ6n8;~y9-@?T-zMth3$Zf{PPpLkZKp)?ZRA=+g%I> zQSnmsX-~Y>j-MT{$w8|^cN-vW>{;jyKe-j5=wV;76|)rUVUHN-jo^RBr7XOOKHmGmgNF+l+Qs1;`Zn>`& z2F`+W{~dGeOtB)_Pn*opybcp@f})dG9#u8yDoxma)!=^uR5fA$CAF+lEmr2r-xn*e z#%`KT!L0kzf^MsVxn5^nvV`BA`u`sSd!~X~4>j86Bse#Q#*}s}Ju)k}{XB-)61?YV z?CotQfCP^t{r8~~KfmlqfN=f@aT7N`cEx79BT!r+pqDS`w>JD$;p}&Ottfn5gC8{16PN@RF%1rz zs$!j~@cZ)k8Hi^#t^wn{uQ~55{G1Fcs&TH`RA@P-<+^!jsslMpDu{hM z^tbi?Iw(+_e!ce$1N&`A26-y$9K)(-BlDW zX_YaTEm47$_)MT*2eGHr9yV~v$K#Z=PC-g`-IffSlIUf{7tF>@`hRkRR3r;xb><@c zNi@~|Z&PYg>mxP3XoE=1X9MQ0NBw7R|6f}M&BuK@2Tje@q0Iq(e-?72Y=8}uNt3Zj z#s9axckON)$rVLE?{$8{{UY=3ok+*DBgt>MmE3gVbY~{7Nt~XC+dGGnD4QLLR7lE> zJNAFS0P2M*7A4tn&z`;4nKkW*s22)_LZMJ7lyT|=D(KL5W>+ImVIuC5U2f`=tH?Q$ z5s|YVO%o9)ZH03ge!gN3bnNIDD<8PH2P27u8sA%ux;$~&G_Bw{eYyEMaRS0A4|f?) z<&bHQz4vQZWH3^FKewU2N_6bjNQml7QTP?vS-`qWd5FU`}RL*jdpIt>^ zg_K^w3X!%di*R&7;-V-+PpZv-FU7@bwb-Zn);3Q(%ryZ?xKuA7tE~NCpF$WwW;)Ed%O+GR^|1_Nj87!Ku!7_RTsgV>8ct<0B(NP2Kfc|_dWRP z{LPl0?OFYqE6m;a(Rn$YJSw8Epg$CM@cvD8gf8X{iEcIt^X(~`sIpU}rSxQeDt?vp z3%PCFXZJ%@Aq;0po?+302V=!Wu$Uu@kvF)4WfE2i+w?3-)2wVje@6|0f8$}WK3@+W z2CW-xchW~}c%U@kXMo^jB-%|>=PHvIlt()@GKUJ?b1B96b7pY+)j{P(0Mh8z_rqaK^{zqU^wj(Ts4fBuu0H%RG*& z3EJ7&fm2*34|wE(od<`j_iXp`2I@f z6NY199cX`F#fIU&uO5OL6tnw8agdF!?g7PeoMq*G)N>w3qx&b>{60yR-#>oQz0Zun zyevU#nkL4k2}dHVEvwv`*qA$;m1lW2p9L)nr}^ELp?q%{R3}PLi-p%uK|xe$D+^rq z2K^7{)&qf%VUA>6Jp)Cy=Fpo7i!1giNk0s;S$#|`t8rtG!F!H}>Bfd-=T+HcJn-Ba z2IYFO)+Wp+S zS*ePXd8OKZWFt_ijStWA+Ok=ls%q$imoDsLo-+x%jP(1rf$D|;DDRyr9v{;(nY{qTL zsZ?PGdX@4;rTmX1*H^9}s#Nd+=rk->u3+p`a2^$J=F>q8`$Lo$aW1FvOBW|2Pvbgy ziYFI`v681{-(>)CG>|wA>QezBRCDx~s1d5;c@7FiQT_-s@bil-e}OUA%M$joKFMUF z^&Q^RQjjVKJozL8#?_g{!z7wuTpaX9;I2j%=D@_RMUbBo)S#tL40LQ1g;IIS7bYFa zQw0KZr-=}rpI}5&Nvh)09L0c#Vr!jHh4o)6TQ12+0AL98raA3QZ$cRpQ&@f992Zvw*};cc%KkIrDyTV8p1@Op|jwZ#$M zm?E>%gB|l}e1y2!u}0Jp{21M6C-`TG5x~wPjBE{4VhEEl**tptLJN$;$$Eb%lY)N( znhk~bsrd1~Pl0WklU4|oiKsmNVQnfF{(pnkH$;nWPBuGU#2V%1 zC$gPMt5f_H#6}s9HYiqgG86-IwE)U9fkI-Fe zecEp}JMHbgot^H3QS0&JPP?@ZzYli9vpytrw*b1nv%A%8ACCJnk};lx12FsSy&>BnVKo@X!uMLbQ0*#x&$dJKT3;rOP?nX3(KfFp>5H|}p$tegM_zTEi^(TtCpf_?=tec`Dm3T%Xef6X{?&l|0ry=Ho z8m_O`Qur@}z5xPAqkixNgu6V7zS40Kba$C}QK>){O_P2Jo70~4C9!S`h zu5iEG*;l}h0&cgv3f46lyBfGdW>% z1M0R}XS%A+9X>WH=T3(K6)kpjclNe4%#6+Uz6Nd^LaILQu>R~QEO&MdAr*0Vba&vV zf|-#qjp)v7?d|HDF=&>4+$U*Cy2sAm*7g=^EK1Z`j4g6^DCa)uHJxqx*y@O{?jC(Y zWAwedeXu9$-Q8)o_vlVZr$hf>h1&wK)oJgw>E{*<<6d`HfDd+eWs&Y~7kI<`+!C3) zd%Ju4=I4RyUxDiGg6YGmOn3QP9hhSvoCW<>Ws<(o=g2EW6SinMF_f3ed0D0ixqnqRL z7ptgkbR2Y+b%mpQ$oBS_=fsp;UpJBW`{G^~`R>y_LUjF(Mi=NH*sB=lMDc#S6qA*S zYBR)Rx1vW~6}`ja3jvW|&6Xj2-#a?G{ubv(^K-+_RpC+?N4oy_SJas-s_2dUvaz(E zh%CwNL_GA+4E{4%kJp2B;exUme~pKdxWWNTgz<41C&d$M<(FCE9D|CV_`-0&fskalJ+Uw9|^ zdhB5h|0G|PrPy>YSEO0o(t-4we!>}7w2DyUyhY)JW^w%azB+Fib(Rs}3H7|UpwD(x z1BpacOmlMFsE0)A+;6;;Km#4^7hFQb&U83rWwbLfmK|lhMORE|VRRFUpOwr;T$!@a z7bzqCuK-#?mApQ~(vzTK%2v3`UC&$O%`0z;|C&BJL%US|Bwkl{w&-F&{zQ2;Za5F+ z;^f1?)axd8oAA{nH9&iG7B{56Fjb|W3-jLg0>vb8Udk}`RyjAU6Wv(H6v>mpyo`&! z3~)k5l0Sr(%7Y{S;&P<8))&!REAw#e4N`m38K*` zj|+6@l0H1}187G7l*v#ya$?wV_;-N!<;6eajQltUXGI3giNDZF|7D()lmq<|;2(^# zA|^o#ivki_v6E-|6>I|zfbr5{mr(nCggdDe~5VGh$y?}I8S-&)SgmMm+ci53O6W)@9E89!cX4R(NEo3 zHkS?TIck~kR0)Nk2Ihs6iL>qH+@}x-bB2S9+ z7xJV?4chq z$xE2!XE{v)=j|P{6}gK~q%Lf^{y6i^oXQ9dLU=rYv`&W^Iv}&R%%3#Tsin+bWtVaO zEGo$PnV1A-@+0MFr2I+~p=XGGuTxV<+S@URp7gNY$@@ z)1X}c8rL~aTIZ|o`Kxo@Dx4z9>~ox|II}u(PKjRj^Udc^kDp3V!qi6GljagWoaZ?` zxB%5KSG7+-fmxQr`uO8~Jcg>3N$V3RR&+TinmnCMfYC=LZc)IFY8M^K%2Qizh{J$k z?DKHWJ>$&5g*PrMC&4B=5j28wo2c16VoK%d;V9%|s&fHuI2$!cB6l*F5!rUSYDl z0KA_L@nPvnJUWX<=w?zyGliaAWXWhldNt6|)&?k6$pkxJWRqkx2fgTLo9uyuL**B`cFK=r9W7))4{K>mW)Tif7NhK41HG| z&hd&pOMSyR{DX$m9bOnKvRB#~ z3ppcMDoiRiQC@7Ft#DH5Dc<^i@F0KEbZYG@-W8g1NGhMV3DLWg(~zm8;#E-7y)Qte zM2z?!-`Jm3V~_v1#wu!V(;ChcP{@F?wLFxtId~feTKCq+*eY4bR%iD#A+PRbLJl45 zuI^((4(?|{y0{Jg?}Yrn6Y~2fq{~*9_cS4oS{S7Y3akZBRz-ddxu4bX^swbI+vCVN$27vA#Y-TX7!eY99Xq_5WGb|M*_(_smwDpLsny zO1< zHG@+H)n`sc_QvUzllo8GI2DzR)5a~fPRV-V-8wz`+bZd$^673 zb5D`?N!=Bi@1ZYi>dng2JgF44829r^lyom=WMeedOG#F@nx~7Y^mt|RKXy7lYyCGQ z^s9T)WuDSnK&rut%E)@E-&b|3w$zB%_oCsr{eF5U4adgp?fob?E^2T8C3h{iRd8;* zQMs*xbKAYiZR$6t5mj~PzkWO7^2_UbRxY3`*Vl3)%O5KXxZ3$?GZxkTNUqkZWL&LkbQT=%p4R0kpNrzcQ8T_$cGP~IQ_%FG5y|EUr zPygJ-%O%locbS%hD33QLaZzlP=MhZLZRSDgz}X*x~SB_ zET!wEnp|tvQ2eA-Ne+Es&t>lw{W3bEYx+8jMUHRpZVb@pJYIcv{@_XhEz6$VrtvTH zxFF})X_SAim6Ly26mvk;c~2u~G1-ed$$o{IaIq8@9xPrkN&%=rxN(HgV6q%q@HzDTLxTE?=Y!Zjl5>l$1`x=?yb_HyK;)JLB%&t zyJ9APFS;K4@cSyeh4cPeJB<41U9@ZhSBP52Xjorc(yMO`@$Xexs(o^sE$xt9nc0YD z$FLOEUlA1_S7oa2W}zCCIg+<$6Mv;fv@9o?XrCUG(P8U7d=yUlber+mLnE%-o{sgi;u$|r5e!dR6SH_{bf zAEZ=y`{P|jDSFlee^*t9TZ&OXw=Wigw-CLn$fi}r=}J;G8q?qZD@Z+p^!M*yw=b}{ z@8>uaXDshuC2=1RZ8i88UbkioUhr=#sHAns*X(Ot+qJur%OC%z+TuJlsw)@C^OSCM zS1?&9M`>J9I$HF&H!&@%UrA2apyFY$zuuO?+!b1k&?uV^Ch>;22fu{B)G;`46h9>Y zlXFOpmlBp;D1$0^1OI;KbN1C}UVE(m@C2HAaQYBvx85&S;1SPA{Ovn-JnnGdCTxY_ z@J`S_@tM8!M&HB09)LfN-Io(}-F2(KK6&`yG_ZFNrT1>_SVl`Q5I2>U z-{tjb1S=G(Y6GhjdQ4GHxt77n^QXH?&fCswuhocYGb@~{`_<=_^pe|Q`^7P+{rN6L zVt5#O$(y#)(zbkgk(!>R9W$Q*aG9R3F43gsZ4;hc^l&^ zV1P8aOoiIs;WY?@AfSgJ#T`%A+-@QB6F)E#L9V;{R#&hgTorw0V!IKHR>vCohjXb) zRJ>!af#M9xy*cJp)kjfr9v2%~4l3Xf+qbR7f3bXlU@MX03XpD=*~i(8pG`e~`|SAd z?~bahqI&gQRxh1gf^Y^JXEJ;_qHAkmaaEM@RDF%Jd>H>_p5&hk*X5-sTck@k*U_IL zu|9~XKvDwXHFTo&$uqnReqv49zb~+Y`)J}n0sD(rC;xjL8=jsrMpR?B)e3WM%~*1& zcp=06<2w}4q2xJ-?VYh)<t$tkW_UW8|^_FT!oL zU1dg>0{|oEB-rnRVe52r7zcYG<|_}x%2f5udQKkKKW9}=jLO>@FK$VzMLI|1qmyfg zy$=$tMjdU5TqBdMWn5jYFrJ#7Q25z*feCk-V1(0_G(w)71Q_V{V{jUt1Oxc>BmKgV zu&?MB26=r+zc3){GuZEi^M1A&U&Q&9d5x^pk;IsHMQJyABTwf&5sOM12-V+{07J=s zSb#DHy!|^NC3C_r3>$k)zc9k>5&go5yRZKclrJR8)`&0Sjirm`GWoi?5lRazA--YH zZwV>h81sQ+O<4X`)=TB#SQ#j zg_FerqkmZra5h`Z0}<7(SgQ`?zrx@+vGo3BM~BbP=^vy_O&2IrQ;aR$J@IxoV~UAVwlEem@Q8oA1djqCdu;Pyc#+^ta>w5PpAn_WtF&<4=?} zgYS2*p1yoTspl)bKCvm@6~xyCJP!vHbl(;s$?xKsOU%^rR70<)w%G%K@@;R1!{#uW zOvH07mGZ6D;Y}!>M%f(2<0OsW<=HIG%c~}fs!#7*#o{%eApB;%bms*8=eU_SI_Y`2 zo14}uO^J8jzNax!12&g#N+QO2e=gp*J>t)8^txf?+1s1baCgCDC&PPq?Btx)f%U08 zGH`$$@Y=k;(Wdt|*wY)zaq6TzMXTZ(J)o%`>ZywbeT(|em(+K0o9FMeuaEV<9k!G6 z`%wBJyj;BjL;<_)sLbN!LGAdXUVM?FP`@mk%J&dWPW9#@i^eN!D>b8-=U-wJXzEoN z0~QemlJx8-#pks~`uSoIb8|eVWO?z$EcS^{)v-_D|MW;a^ij}zG?9FH5RkiwUqEIc z7B-~voScdbNeb+X9e9l|5}FDvI8ju+Sd-<+S&~MRmsUxYnxtaUAfW2bFq_VzQshgs z#uv&V3#do--hQTa20?i|O3-!YX<0_Y^W%&^ai;4m>K{a5?b3U88aWh{kpCEoZM?lS zEsFDOJ{f)ZoXlPUu_5D|_!8w!Uq4nQWM98Zp`!oo=CItvClCAIpp{Q$boS|740zG| z7Hr5j(Su$P)3x-sg zg4Srx8CWBK6-m!YRuMk;875d=olAz&N^~V3m$z?y`J$*Q?xE?ZI;*9Alp;=i%$SSzmx0h zk{(5**8$TtTGK#dKMB?!Jt~sPG|H37qer81)WAFqz_W4D&O4n(=ip$k-D!6oJqp5L zkW`iaauq(3SF$YMdl*oaw$3?*g61P~lt(75M>D3v}kRjKm!< zoi!Qe8Hy~C8DDeG)3^k=Gn-^Nta><;JxH!x?p6ip$>3t;B3pOFZR@tUZB=lC?}QMHi9P&sFk!$aA?hvK^KQl?Hfi)ghjtYprZr9g&U+Qru-XZ9$Fb0&34W{l7bSPJ9 zVkHbDe_uHnOwp9_2>sHq-bWXm&LaTQi_@JAj>0A+2WVjCrVnNJu=RL?UYR{)tH+gA z-VJI8CBWj|nryz_vd-QoEfCo*zGN{CxcS6(aNK(a{?;%S$#Pe(}7Fef<8>`=e(Y*oE!(Bf+mUQX-zHx9ZO7 zbyK}ds{I?)i-Yq)E^}0SZJmO*u&DgG!RoKCzO!1ryyA|mvS}s*?4zPVHZOaV_$(S; zZHPfM+o~3tWo(-WTH)+7cHj`pRM-p#F+Qb^m;!*z8hwuU59GCsBP@mkTzn;i|OpeN)Rb@YUIM z*Ezx}ub(DW3av&Ux;pg~|DeILcBm3|L*`>U#$9b;yjwez4&x2B&Jwp?c8 zt*^(=d$lJD-bKJSssfeZHZ1F4$j+k{ED4Ug%ROLbae56yc;u8gLs^@FrfE)N)!}lZ z7HM)I5w`^g3a#7Y%mi7AZ-UtjWu@v~EuUR#7`)R;3{Q1Z*~f^yrd!S?>sT$%vhs~M z4)ay{KV>{_sjK-WCP)4cnxkxbI;*2lkLYC7JyeCsiHw8JQc0S|Iqk0TB(;i{J?R2( z!?%|U_ehwkhsw?X)rmwPLFi!Q3s(%VDno_E?j}YHE zwQ7(y3f{7P4-$FRseyh+42J6CYI`AUWbu4JUzICSqiCf9Mj_$@=N{mqdBsp#us!3Q zYzF64>&fZL`!rVj{cW&riBsK9OOLp$sxn{XE&`I4?6bri4eBaiu*bS(SL!!glC${m zSGQZY9Zb)@%e1p>s@n525k6QOs7yI?R8Vh$|HpUF%`zz`u>l_AXAlZcLj(RGA3ZF} zE1vsJCS=qH1mm*kmV1+_lD;L=DvW(Hi9f;@{x=4#<;SxEy>DJ6>1UA*fvaQ{A1maX zz~2?J;W3!W_8PvH$u>Da9=XN@m=tNw%8#nfkGU<=EO_pNE|O~Ya_LAk;hF38chin} zhbKWP_#-I9ps7c%j6uI_t@SrLpd{2R{K(z)E_{{(ILl_*L~&OKr4^(sSB!kJHg)uz z^#1Kzd>$_`BGf56ZWTVE%?G5s%r=k-iw%6?D+T%w;u571z4Mi&ap0?##6z`Sfzwau zQ<@CL#RV>oeKje`;8X^bjVpf6Y#+BKYo#Nih}$XnOzUhOa*PF^n!a7XCvd5sLL!TW=8uI63v)Qdv%yDRx4 z46{a3S7#66San(UdKhnTM`k=sL)res$qIt4iCgT|3}&K^nk_MD5JtnYd!g5bd$BHC zb$^%rkJVOZr&hkTwnk?5Mhn#D|Am=}3A74_K4g@N1J zgn_#{6iczSFO%RXaVB8}V?>RD!qpD!J26vkt0^3A)DaF{YP?vs$GYW$U#at7cg=U0 z^p4AZwHC4;yAqb)n(1g1G3(Opn`7&<+S2B=m6kJK?H;p-(}G}SW0KDqMEt$+=zZ>=#;?t&3)2#aehY!w>mxz2dx13W|9@a+i^Jf`%_s zxh7S1zitM1&+DYyi;m-EVGo=O5Z{FbviS^zfEU=8*W0Fi3C4k0CP5^u+$~f=#1rhiJt() zE4~bhpHL&<1KTc!(6NL7o#F}b7c;%kH`G+n7Ms;20MM`5Y{FHNr}X_g%D>FxSggny(M%A8qmdU{`k>Khl*90vB-H!kcaQ*camb0S6N+Ty0S`de z{!A~#RMUnrx^h?HBjEC6;%R)8_;M!~9^j-38z=E(WT}QGbW?x}bJ90C%Y%Ypcn zfI+Ky>`xfjVnEzn25@rbPr#Vf{*-v?hub2TrzC!GQ3IYvlSxfdnJ1rX(1Nrqt?5iz zgV@{;PO|~yo;UD?la5QGU$SImkuk4Ni>HHlRG*wo&*~FD$5&@@TAzNos9{hMA~sg< z@bg19&xi3bMg|3v(Z`}3CH}K0Lqh8vleeU+A_<*tOUsYX{;iYFJNEXHdU4+M0k?d> zZ69#Q2i)}lE8>Ug8$&+BZMY*-SfWE3H>GBWT-xh6D^>b+p%TTQKjpjzT&Gr*xfh%{ zgn3Kf@R#~d=?)d#9Ke$t7x)71yI_p};g_F+Fy~A$dk@6OXD(#fQ9_O1&rEHt-`R%+ zLQSeV6zIiQX2T_vt-Ll=EV~wrueo-D)Tk_=T7@m3UV?3CQptyluML?v0JH2mV6*1B z3AEtaK)KplK(*A`K*$zhR9V z)nVFCJrCE}b}_G$qwggZe7%|sj;XnyVp$_C`^19>Ya@UW4J<=n>n8L%A1^!@OtVyY z1d=-fwgd}?e$BEt&Xf(M#uZc_*;vh58~WQiayfN*Eu5Qstr)Zr|Dc@uNobKyK9yk>cMO^KN=V-|l zF_{+hz9pl`)kN=U`3}-q@r6*NQXZsdp;Go3SYNGObnSf(V~`T?tR= zqgk*+C`x-nOKSugeL7OVZ-mYyEDKLTjts9P$76%8-hrzpFig?RTa}=7@@z2|+A02) zNw}8Qb}L_9o7FU~B-T;eWUR2#AJih+DDT{sU(Dm)DOim`7Y{sDWX7I8)g5PB*vU3m z9hf`NNle`p7dm082`JRU_mM!>WQZUEHDpi?uW};Y@@mw#V>3=Puk@%|DZZ1j9Z_8u zQB^n{Oct#uwRV(+u4!_JOB&ldYcXZz=8kk(FSBeTj`E3fS<6++=~35r*=!b%02OR* z0;Lu({L1cd+JDR%$G=TycU;>X2A!=wNyAlKKv&Qh=s>xGy$NT4%8U$XPz|1Xt8T5l zPZDR`s~~Tm%zWqEsc`{aMeA~oZ|>q_YAa0DMdv&8x4UR}^E8!5gGiB}C-WbQzO zhWVz!zeJOHTn)UGj7D)9xK^-S?Jay=5FQi@sXK~iz{5mKZcUNi7|JboL2T)^u(sfq zRT=XHnNCh&8+L-5u;3Vo)PVm-jRK_P@Em7fgBsXu9O3zigf~9NSC?5nDtZlbXEPIo zD=w3Acn-wN4DnjuhCrSmqTU6)Tr4`@RB}(Hgqo~9U7kK~B=rud9^j7YtPFa18P?t1`2Jys6<(I_c%f=J~ zg4N9(;p~(6H6dT+3$Rkfs5id(s62?i<7$DpxpC`T1@-nMpY>_s9Rz!NlC^G$FRLYA zZ-Lv-6$p{imo*a84Y2n&WVWwLg@YY*l_ z(t9EQUYe-$F{VR2y@2NZnyWmA`Q!Fsj)u?F%|aH?oGhRzCtA7SafR{@+pcACbUgN= zPaO7XjvF!aRJ8quOnSpCuPL{@-fHqF4a+y}qw?J2`o7xeBGseOZ}XzWYF@uGCuw*D zYEq$a3_`+AW(E{YWE>KDLL7Du4)z~mE007|fxZ@I3;kbyx`*CCEq`EFx_IZwuy!A+tp%A?o70d*N;7IiIcA6v#NV;tjf))(-8XKI{ZZ(#p=w zvmn@~&LWIat$mFSNN+cZ#Js#&N>Zx3Hn2*T#(GUsH>;yGBS(wyo61IO(c+duDEVel zG#(xLC#Vvu68z-<5=#?n#mknQ_0Vzazn#(Vt|mR>M&!A&CpOZDF?-NzExo?3<1HY_ zEs*HlmUwIZbScSP^;PWP>K5;2>JdGjLthUIs9YDoC~hR$s8-+imN!P(|%L- z-|_HS;4KqTM}0K>MTbU2+*twv_f_%VD3T|`-m#aEN~O`1a4&}yV&O3P2T{m zYM}6l46&Q6E=E+n)OO?;2F7pAuLqcn_*B&@$EE(RIlJFjUJ_n#v0U#P7$X{PTf7K) zd-`2UiLU03TAb3%bUooM^tz=>8ylsiXPk@A+Ccko94f*9lL#MS2?I^)^e}s_uJ`n zIhEutRSND|;#AUk9lW~msU&yVlklaB9#XEl;+fS&yuykmYC@|5^saaIdU;>VAYW}M zq@cSrN|+$54XZ@1v{pd@Sh5HrrM`a!)SPM!l*hWYVCsuEOBQE2NBJ+F*F~EPw!3mb ziUr#Sp9`UNsi=fw({cl-P!QiE`toRn9>|tH5@EOE**rNS{+ax?)`Lnr9{I~!5w@Kpt3EzDdV9X)sEwkoSF8W0 z1hEpE7V$>8r#nsY+VQ4MG|=W0`4;U@JdrLdtRQN=i^G<$D*q}bVw-gWdn`bDfmBYj%1H}QEV!wyuI426y9Q?Ey@WhHdxqpp z>t6(LGcJAm0p`?6FaW7BNY3!Dz8;SsbO)b200MCn9)AFicoT=N<0KdOcOq`)gaKZ3 z4k*3^zI52ZKVAH@g@3m3&kp|C#Xlm#-#J#9;D6|+2GP9Nuq+U3@B@7OYw^PjFZ>L~slO44X-Qk6B%@@oRhBZ{I93=h6jM>1TmE+OZhY zjiDG*ZnIGr4!xIJBrD);mbIEJxLCb}TF-KNUH2Vc;a!wpoG+t5u9jMSzj3kLS$HId zy`^R0+Up(i-Br08phO*MnN!iEVc!YYY zEcVrN8~(U`kP2^8mJqnT>uXx~dQVMrcYNK*-_Bj1k@X?y@v2?rbnPB6Q>)G*yy{12 z`5wxRzV1|gs}Wh;Yfl^XL2qw~`O=rtOqP`wsYS8ioCtC{w%%PIR%7T@#jQa^`ax(k zOoNIMe9cuw?~0GE-9ld8cxZgQAn;3_vQ^AOvTw@L2n6}Cn5!g(&OmT;?> z;_AJ|RP!7a=jB9e=B;T14z93Ej=FWHZ;~tW-1Y3(_2@FaH634{kGQFR6uSK zBa3#m=0a`t3fKaBE=8QJzr~lYpoN3nrf6Pxw_%jzFms=l7{u#1<4EESzXeClskkb% zsC?(f6#>USM`DgTdTrKFr%2(l)d}(=6ts3=ji|gu$unT>4$T)b| zS01X?^Htwd^fsqN-9Mx6=Hj9k6(cVf5kMi_3`!wdzo+;9pbg&_OGO&gV--q8eBUhF z*~olkkrk@OZTto8Zm|{Q_8VYlP&@$w^p!hy**`Z|!7G>g<<)&gz$#Yt5Yu_uZf6J1z z83e7vnYhlxth6HL?6RKT_A<4s+7rBC30;Vf@ZFHh|08qOqbI<4zOt;570M^mpWPIZjkLtL#X{xJjX z+Ml&DyG(H0>OnEf@!IF^ZG5La;D5F+`XZn6THo@O>=ZSxWcX|qmIZ-e6@!mIjoS*G zw11-g!*j>#UJMw^BJoRuVvVswTNND^CbqoAUJ*;)dA~?L$+c*Bytx-D<>X?ml=2O+ zcXW=TOcy~L%kQ+ctm5c5k}q=E6<6t(y5!Tj&$3)&ivRz_<0GH2c3h;1r-Tszcr?onG%RR^K82=WooJ$?kYdLvACs)7p_dk#YzsKp{rRE*B zPPZH{|J?$MwVmT18Of|(84(#))i&G2FM~YM<4V36*n_6}@<5 z$E(^zW-aK|4r;j5JpospbMyj!3AylH>Sk#b&4r~^G#8du(Og(sUYAf?;=Cqdv63OF z`Y*cI@i_8v{@25Of6>(HPV%eG-g6kYz)0PD(L$p&7C}I7S{Z7sb7ti&#S!ojXo>- z#we)AlH)hxcwz&1tW+Kg)v9`$>Z<4Jr$^E9N6o1!Rz8Kwr$|*4sEXoLQJ7X!lwQ_Z zS}IC@onqx^`W8!gc6bYUU+hHG)hf?SFsGNUjf8dZma=OR_VqXXZE|oSrftI&#;Mux zu0)K=)b*0$Ho|R1TKQ$0-7EjL&?b?yFNA&b0`UT=tJ|jk=h>p~8s`Mb=CMv2(UGqz znEt2Psu#;bq}%t~q&3qnGy~Tgo1pyN{kM?0SMg4(LDi?C)ZE=a&h3lS(kgw+NMam= zdMR6LG}S^@viz}g0N}a(j(C6nz4u!U->Q~X;e1x@QDw2HxzS!bBrD%vcN)Eu-Pwo0 zA7J$~sD78dGtVv;RDF9xCziFxq#CPZajY{W7}iCe_)obze(g$G&ARfk>AMZ{Vx`+K zo<@BR4y|vCGy9w~6uW3w3Sgj7Hk{)}4Q=jb>I?IJU|zXN`t8Hyhg6zW4wLnDQ4rsv zNlp)k%>s3&e7#?^Zp538cW`>arxSD8gl?-g?qHmab-Y2m&r`=5o9^h{cDucx%DSLk zOA)R+FI&JlKDUV#TJj5ta*^W{CVFSdVy>rRRprXQYU{K8yXr={+!yB$e2c#JjrnDk z>axy}sdk*mJ8@$uZh%<+yPkF2~}9qet(b{uLj}ZA>u|3+Eh{eI&lQ zQMEO$K(3VRkVKuP;B!{*7u6B?!9eGuzBL8In8Yr^8rR6!Y2b+Bduzs3kivQ8TWY&hrB)SK;SIv_pL%t zf}mHAU>x$i8#uM)DhJCAFweUjCURb0H5uw*AT$kh6OYSY4LxWbWp&?xc|2| zMB;wLO0I&6llU~Of=RB$H&$c5aPd}yTHGYgn?w1H@OR!1)BaYNgAi!T7)-_b`VT0W zB=4x;{k6(lELOx^#;C7(AP+0knw48mGR#L8HN z#4YOX^13PiZQlM4*V>1xbyt#Y5i;AG+Z>sE&6)^I9Z-+XF6`JAtBZ7;tY5`+JkMeA zD@uCv1bSF~|2n5@Kw|7Oi>@oapOD;=eveioj?f3sB@9=5`fo=zi}PN1RBFox5x4xJg%aW!m)tsmM_lK9amW~2+u!cOZ@ z#e%|@#fC8JWn8NBem?^Rc~t@oTk9RcD;JXWXse)DVQ9zh8nOp@hMSQN3f2mzebjEo zs}=|^q^+h7!IM?dKkZM$dWxN_G^SX`P}MVv@#+O~tGIU2JQveJMns{D8E;S%6maO4 zNIvfmZx&Y&`K};8VavhGw6tz~sFJ;!rXx8~YlqJthwk9fR|=&NGGPV3`EZ`e;mn=b zZ8Zh-aDu8!m_LIFGJ+q?OkjFZCErDual+n8RxD-?IZH66-sUt(o0BE^Wdx?M9iFv3 zyd>WZ%6)0>%v^!pGMI7H)Qz-Ixzy?^=c_)`T%6~|1L6(2~!6pf}MsTQn^2y8?XBH|)k-o1MI@(mTeVZsS5 zrpAyj=WNyAM}##H$a+luf`M8#`$~HPF>sZ07e4+i9`P+bt8bajuCM9+vh;ARyuMy5 zc_>BD&6b1;B`Xu62YXCqFod1v8b(P49%v-#x9QpBYIfdhhtp^RwN9h_bFY0vPS>Jf zKQP9vfZDuEoY2y;ene@Sm4xWVR}kW8Jgs6Wa70_l#aSTwS{FuD6vytU^3WlJHgw4J zCpdchB6yN|b~Zg95I^nUlZSFXiwfmTW;E&v(}sBXJKh{cWz;(KJV(^bEw+}X@}QSG zhIL&B%dE*{avOs%(Jd6ELhIpqs}8XrV>PIQ5GrqFeVz^JlD)|*A*Qj}d;qJ*%Mmts z1eR((QTb4M zL-x9jepoP3YZ_lLx9!?3y@s3j<=sM9A{)pxa&LsIWx|$A2UnwpSXF&bMb2H_@5Rtn zBCF=u+h92wnE<}WnU9LMue7o%SST{7d@GeyL`0{bgsEXs#vRkCOQZ->wCNgp;K}8o z1GGgDd5F}tve6Okc;~cV%HpwSdVSqYYqS{Tk#Qe&!mhqWysjhv@5yzVcH9cQ&0-I^uXi*Gf~qz~bR zs&qTNQ>VhUb{z#-aCi?h<;oRvF;=ZQw1odtwc%&J?fEoV1^)Pz2Y-D$jnGYzNlQk$~SHJd@u^&*CJPUTN_8$HP3AzWiTAjOm-rT=MSV34)=FXbzERIK#Oo`S^$8WW&qhBT zV-7uJE{9caU1G?NPx~po%D-$eSrQuO0yueMp5BP9`;3M8 zLR$s5u}~@pm^U=A)@paw`nk!H3Voqy-H7KtJcP-RFmsDAj!WIV;!+p&=h!WkZ4BAQ z#`A8>J@3Y+;jn+vETpZU&J_=b4;~Cns6L=fWWF9e$T-qj1?jY(g^2VG8#f#j+x733 zHhFXrbT^%=X*pGUUkxue<7IY#>b9%WuH1*Z#bfCi6bwiS94%L~Wv3El*l{pidJcbE z%rs-6i<@~72WMT1vknEoNqTBcCB0jBFxLdrLE zCaptvr0uh(?^FPb7}zB`!^CIe;GxQ@@GeYiV>zWU6l4#pQ=#62MLF-F_hcWf=A4OY%!C$G`BW|1Yo@r{ zrC}BK4y>b`Fs6OSY6cHpG6boMXtuwW=sb zWNNoz=gX@U_f~ur=F1CHASPc~vSoPiL8DO>ECRtSYm8mg@HDBPA79#G{h+z068-St z(pq@9W*-HFt!1S?c`G1N;X89n>k#jJc&ZSwdX^QhrKowlVp$dD(E?vbi0NxLc<09O z_oSu)a#|O??A2r$#P|lFeDMTTv=zJUXtMHH<0srUB|~v&TMcx$zy{ND#bfmhc+nwu z^%P6&2mGC&qg4NCrs_d-iQE4B>w-Mh{bT#!f0fW$0JVEF4Equ6?XCAFZ6$oAbI!2X zeEszJXV%{9Xm(Xk52&3O`3<-}_ zsj(nyEh#FGJK7GWQUNGoi7$VM)$X8F+mo~(pOm;MEH>SW5P{SnaEPWp^WEoeM0k)H zkCU$e6h8oBk;ryIQeHC+=uo z7SK)l#E|pv1=D<`# z0o7mhbPkGkXnU+;0&;BAp8Kg*+0660H);`=B09fbHJnwWI) zZPIb=6TFYVi1$&hRF{_iH@aOwmWX*i=>_KVM=Tti04Q1_{$t!yL$nCzEGbc6@>YiD2pHO#0N$fm<*@H6Zq>jF@&1nbHKMSv-~4| zVw3^$%n_bt0v8Dq7qtXFDi?ap*_jX`^2n*F#3|570G>%e5aOARzz%;2?11iZ4k`@n zPP2IqniF<2$zu#?Ad}v!r1vrjSS6W2T8>wD#n1P6XIK1`{S+Uvmp zU>MP$AVxMQNc>f(3?|Q!gkYW=_LtMRJjZoee7&YGe8vrSSZZ~n54FG*k8UE=ElenA>}=}llt&1sz$->>Aij4yM6 z=J-OsM?$uFia84FG;)#n@izszQjoukMM-fx{#M+6k;IpS49enc?HAN7a@?(Q@{hgux~G#K>PEa~G$XTmDS2tNe|!B( zm@9NfRXs|81=UmXcT_Jv>gyNjcWVIZ0*S7wCO>&rGo>!CnQRr5_mRXI>J$TDVU2b1 z+Qk6hs`eY$-ovJQzq;uzH*v|xON?HD{n*gghJ#-41^^8Wzz79&Skfryv?OfEyZNKW zWm29uKCZub@#6Vr5PE_c_kx!K*3dAlPEU#-W}vI@{#6Yz*^_R9uJOKp&X$iZGC=jc4y0GPNO6-LAZPLDfwru-BYyTqfx# zyDT<3-JPzf?udRgKt-2@WcCK=UIU<3lNW>fVFQmFwHDSqghhJ;H|%jT$I}NI~5RbgxE~ z>Tc;KHXEQ*z``bwD9_`@vkoFwg6u6Cpb?(M*sRkWk|>*(8$~=#&=`_d+Z`p;%{Y|= zeR%i~D>C6g>>7D2kV;*u&}QSOOjMbT8@S5@b^&!G8ZD@~zP1Lm*+@a3YK%eqqdG*4 zl0}`w3@dk$)#jG9yM$O^QR6v*k*QQP8)VNB1s74iK@Ahis=@p=pa%3H)InCpljv+C zTeTuyw1Gvjz5%GA8=wUi8?duVHwsX6HX=1lM{FeMT%_@XMF0%)f<(}xo8wk$V*rf) zIYv2hq}oQDFsC5L!^aQ3BU`EO3uuyb{|9$n3+j7f>T5KAK7ReGG0Nfs2d|jVP-3b; zF4*-%I-j9ZzuEG&U*A%Zp-PUm(B&^*CwvibYU!ee17%``G!2S)hRF|qc=Y(;(pKc4 zdF%dY_<+r?rBzZasuk)q((U0lypVJA&`dfE;6!oQG;#gN(Aoe3N>iL8r)Po9Afn4P zoogIb=1@akXfwkmkh7~_h@xGWwSp=lcx%*aDqo_jm5t`;Jp=m%Qv(!!o>L6+hE8QA zA5tU)pm?U&Rx1u3^sve$OG(ymWVuRmYc+kNo!{L@gNmgTD8$DGvFN^Mw5y~P3# z1*vA{$4kb2QN`}CKdPx-S3Zi0b5KOG9L8N<+%(hb;l{>8lmHK(zkPQ6_jgARHyh|h zriD5~asW!C#7{C1){Hm~)n!$V=bFTCV*?SCS)2`lE@!p@ETiNHZ|x3wYfF)2L_Ak1 z-e_*LoK900SMT&gpr+_H5thif7(Z6)iYRWhYPv}SRFu(@*~f5kSg^KRmS|L%7;QVo zogr>}HKi1vy~!GsAc-Z*p}t$xK7tx~BN z1YYGr(l0K*N>QsTg61%>E$Y}cYTU&*;8X_{Q>>m+g>&Vb&?Ocj#gOr^khi48LcBAA z1cU4hjQv^qMmiyXONDB2l7OW0?6s%+; zNAJQO`JpwC{|nr94`Nbm$4Oq4CX}R?`)V2QXc6NHwDB^THN<%i`_2rgqEXfbe^^sI zhp5uRKygv7Sb4gUf2B#fuy8b)W(9?UO-E5a;zRb7k{UXR2)$aZ*#K6&xQtnCZzX88 z3To+#Y*&yVO2u?Bj95tVEbRlZZ;nwYMXE(Hj;!5y6BgOqG;RXs_C$;Z+Vem==^xl= z)kttp4a!j4Ld1*5)JJL_IMWqdZHnzmONxG+7)@EK)xcs6c}>7$YpLJ$E)~&k^H_U% znQfp;Xt9A-kQ6E##CQ}cY#}gr?21hgSS*CnBmSBcc*INqOCWe6n=hnBU13Gf>gb7r z4VfV%YZu0PjT@Kv2mM|ZB@3rg^VAC3zd%e*uZRwH-PJ<|bOB8)N>QRg_eHN?XBQQ; zIfpN-63a~!GR&|(z7`PgpgFmVYWBj)?|*EGs8;yLhGR*;MQmb8>VjbfzuqivsHAJ* zu){3s+fc5pvZ}_hDAR}v807epz+@UgQ|~a6ma4k?MAtVP&oi`t&CyC#uGP{(Fx|4c z7;oxIGBVeXthpG$96G1d2rsKc7S+e<2&?>tpsMyV%QoUDpIkBS*DOgw401Fm2b=JO ziK^dQoe(N3AnOq#7PkJ{4Q-bq&FJe35bCMnBFQGe2^g6=o;5mQV+O0&Ssu;K8yzy) zfLK*kHAGd7XmSRuR-RA&?R0P1PWO)OY~8Y*tvj`Y@kW=nv(4MtUa1|=BNKIV+;GdP zGd#_hL^?iC3MIi!2hO2PnsL6aUoFg|Q5Ie@S9L|!23RQ4m_bXfK3rG7cux2ZjbJ%% zOJdI;rL<_{BFjcuX19|1)HkwwVD0h-6|7iv@Fyzp>G|i$XcVXBNkt#g=rEPefk-_P zMJjDM6{EXVO@)}Wtax?7swahKxxPIi^uR7{&O5HRYit-#CW}}|RtLH2I=2EJVH;*n z;r5nQTj>Pd-)tziE~8L@e%O$TM;*oL`?2yASWO4CAGNu|q{G{xK3XlWf7N&oaZQ-wlS-HSI0bxqU}f0e3l z@zkPc3aUk@eilj`v<&dkaOD>c7htf21`FG#B}ME~t8=t=Avsqz%32X)s99I}GUiy) zfW5=6moIm!Tp8!|1x%`X_SLb@X=12+ir=2G9R5kqnayrxRrM`wEgqZII>s2+-^g<2U9BOPlb4N_pVd}t%Vz4u#JhDnrWN;H zt)+Bxc6&ZY3IE$y%M2a2t9M1CQC*!CLZj%#Qyh68-BT@!O}QA#T$_!bWJssN(kxW6 z-1U;(yWY@Frf`M1-{P)4L@LtXZ_8tPrge6v0!S~fLFD9BATL~G$w)6ysOrPkE=ne7 zZ88py#}d?#AmE}BwulsY7F{sZQYCFC&PD@irCLCtA$-d>BqBlYA$c#c=cYt8^x{<1 zkl7pBpH%M~9@fiT4_TF6r;ei11@)lnf~wzQ$(lSeNLtFs9TZVR+`sMb{Ce2E2c@_MV8ymd8)-f+dZ9e+&^l$9CEWXWT0pt@>b6hnukAx%IGA*e0$rWF_u= zKgP$ARzR9_`x1nC);eUZ$>T%R&VWd!$moJi`x)I4uigN6=0>m64sB-dbviKfJM9Hi zzrd(`n?sO!G}x^hCKQP6OhBFXVfuqFl3J>+*4u&BPErbimYWOo{k{t4)yPfgFZKjo zM6m{*D7M2uDR0Q9yB}Mhf`aHqu9MA2tLG_?u>qYj_~4F+en|0`D6F;-Y$-;+NCvn# zFesg)QKTjU8q6_p$hXMQF;ro{CJ`^7glRf@g#nMU+^J?l5ez)lAhqziYJa}@{Oz-k zuaDjwn^ME3T?pr{tiQharx)*^{$$s4t^$;XNm%&tnCD4f1~oRZT4ZRaFCt2Uj_RzU zGst+i;$p??Xf^|y7X6}v+0m;b8=slrKp$DrsX-yas(AME)AvuG9Ur~_U}_oNx|Wwe zy?Oio>5s3DKK=FQm&ZpR-aUPGWa_)PJyvgD+Z~&(Fw7M5#S}Snil_oe^0-RMH^(oJ z|8BkQXkom#^oKvceE06?`6suQL8a#^1EtQl2lE%CyQS(Fj$=X zuqg2*^OI8@BHi1=n&8LR*UhpneyLJsu;GhJ!>vQROR3W(l~#Sjms&Pe&)llZ)?vJ` z>YAX*Dt_q-p@l1fe?5VP?<;P52t&6hcDqBTCec>J-}I6v#^+mewx&|R($+T>+3Cl) zyo}?tnS>NM=OW4GgQ$}WXz1<80L-+TN< z3v{m&8l9up4dqhb+X|JQ)!Pm$Di^5luw?aiL#gug_Cm4N_Vz=c^3gj8-@SkP?C8UX zmv4Uh^zzMzr8`V10>%CEh@hWSc z;qbLSsk=JrxK5DaZUsLx^}x~0Yd4$`-@7>zrn-HToJi_;-^IkR^`VN*EhRVGy~Kwx zY9}y#**4(@w{2sCiSvp*!_ms7r##w&e1TWJ@>op#Lo=Pjm{SY$>WJBF(*j+Ht*uR2 z+1EhdCPn;>Sqe;In7a^OnGBYWufeub*azeo1dS!9R?GN;6#vdyh%_I0NFr9ms4SB{ zX)Yp#(-bI>Pf8n^9;ZO4->!7T?AW70UVRG zyE&^6+gL&Q;cB=I7vgpkp08HT`NC=xv)lHTmX3>wrw>k=l=e3Cq&z*8qeHb-sGC+iDNWkCL`BiBxF;d@EWF4*6>S#%;9#e{=+X`(?inPJi}hNoqmq;HfdvAV*|H~l-WoA7eA@w;4Q{9rfe zkf&k}^&3M~hb~tcXl$i*BaW7M4B|qaFY&{q-4G3_y>1&%kU9%akaBiBX&)6zSsZ^& zKpNXHF$_uv=(cq6amoG@F5ZdBQot zjzbw7-o`>Htqzoqs*T|q*0gUo`SLSjyG?CV<#tzjU>t|3-d2`^9fT|qPc4<)s`3q# z!bA0@&y6W1hu4%V&ATV68m>iCJ>vDH(lR(y=p`p?!Q!7Fw% zOp~gT(rqF3w!oFKYVGxJ_uZlsOtq-#gtgfF&g$KU%DRSZwIOzz@+`F9*EQeD?dzjg zu6o`S^fa7$8}wQSs-vi9oZlGWM=+?5gS&4jOoI%W)$nue14hN{mMs#f!N0 zyGX&bSMN-)$Z>~Z)Ow6>9GQ}Ocj|CWH?Fk>vu4A98xa;8F&q@0_<)v8qPNkhcP6rs zFgA{RK!I6L1OmyT`G`h^WZ``BbxY|s{hhT^l^-HPdR zq`$}XePq(1(AE|fdOA$h@N?C}$txRS}+oi-KF z-&^?o^k|ZtX%uz=1q7JSAc|Rr7$5{NpFuR1J!|h0xyHHp9_?@Kz~51On=(1j4pQmq zSsq=O0Rnsk#C!*ll_dsH#InScWfG5ztEt4Iv$Z2&vvUhVvCCyWTL(1u95Nu>r_nIi z!%B5qkdA;%Bt5#37~AO#zaIc<(;596JbnF6g5Z|`Vd#uhF-5dPD6#J?kwq~{cTaqq z3_}4ZCLnAya9;o~G$10tnXaZSzEz2XXj=d#v72RDjG{v#dbCLqujan_Rt+qSBhKpylP+SEnTe#b2!IpJG@iP8b4k zI`IrKKq8YNCV~`0TLugdh$AZC!7k;-K&A?X9ip)qng2~cuci)p5W;ZA@qJpNRYM~U zQ%pe2cMw@w;w^mY#AJy{NYAGeT?gQS-{vcbSaOU4SSQDndXtk`Ue`20s3w5xMzp(FAQ2Ki?N7$`u=fmF0Ygdf=gMwDU; z7=4ev%riv@T2%%y-domm*wLWag8k@$4dUsnyi#O17_3Qo25ga5`D1mlLuFx5UF--M zT^ckN@m*$92Xt8`W(*18?CU_UR0l&*|JTt(^@1PeuRkb|V5ZQ;H4Mg_g zTuGpvEm`Vk4cV2wI{&C4l7v4Sh@{{&NsY8T7z-eqX)rAWj8A!(e*!o+^p`En4Q&Sk z^3l*=_V}a8Gm@n=Z9B3zb3D+Edz*z!fzJozkKSSpFQG?}DH^3nL3W06HvZ9R?21lWZ zU?f1jzaTXdAq4nUew-I`m19rH0etXVwnI8Q0^-sEG4(K(0Ifeq3Su;9#P`R!r9tXU zU#wiu_?Ejvi`>u#?Gb3kc6-~~0yN0k`nY`{fM&IhNN;DWclUrA)Ze47EW&D$t+9oB zyDds3Wi-L(CS!6Rhu>oU+8p5)tX}R4I5Uqc9hkI1_)g-<$nhuWS zkkuEF_Wg_(?2uF)+8~iD9wkPP5EpKSAg$xi@Ou*REKtZ+HfeCWV4j&sv`o95y(fZ!wH!K)PgELV%fEJ1Wm4hV6EC$uyw9;0L9gk!%v>Ut25cu7?gjy4-7sl22ok4om7J6Ks~$XI9JY3_ zI}*Ue^DYq!VELR?xGO5;5~>@Ej2tu;Am1=i_F+}y-lif7tdX4MnYI@Zw>%@zd{|mg z$f(3Y8x4T?ZN7qMZ{Pi$C*wCu#@vM#I2|#FbCgy~nU44&H+Ps50VWI4vos^z6*Fx<0_0VH4#@Z?V0!kE znl_xrGX?36VgV_%xEhJNCY%tv8Z^^Y(HcBQ4TGr@qD@P~AZaw8F{NT#7S((di7Xm} zEm;dwIwApLecqR~WZH-+cz@2cjL2vib8BSxG-#?jG!(GORs02GraBZNcrhQkbOJax z2W$f?h5%~v0)bZ9m_ zhvhzx^sfA%BPz+tLN6lG9**lM*7j{Q48o`R2%g7UbkPO?zM1KdaOIGJfY=HkH9SrV z%})n=M1+dYgX^M5AGL zM+a^aDh0f>9A=Z{Cv}kbe{A?Mv%q&pIPFJCq&JRaV@E({4#$QPuL?}&v-FBx2`?Oo z?j@ad`S(d8=UF6`2OK!+)hHc+gHJS{wTp_hZhHwDonG)JtwA~tIunVEl|97mlYPK6triv1=L%BC@auI3X%U+ACNm?6kI(_8u1tJHxh>;aIO6LcGcp&=%dQ z_s08`^h))6IsSslUWI34kB9$byllR9VI( z9MBFEP3sY_Oe|w=6B-(MMoH#%a2~66xruB`tONkn4QoxG))fSUFr8&t$`yp+mYrs4 z2twdOq8_hbVtl_^b#$lA(t+MiYRpna5+l;iZY5PKCL@`o#?h&F%#*7X?^Tm^hdMG1 zDz#`D?U@A4H8fvyTSFktVw79rYb-!qe4#vfURCWWXH~T)w*J6`=8ni`gr)#wT0^I! zz2`-lXP=c0A~3T-#1mZG9}7sXjGsG$u>_1YgrxDDt-Hi>)=F) zZP0*nan~lubi`bnL>cbd1dy1yHmMAHLD(e#w+PVq9Wmq8h_V>l6@5Q9E0R#+j+p6= zj=f_J*rPJe>ZIAXL-w$E%roG0KB_2a`;^aB&@gYTeTT>pb!2-$LAfLD0Y&xL9#8;^ zxd)WUqIbY#Zh~)Sa5$hW6a9(fdgPchM3w}1=BlbKvaH71*xn%-98XMBJK~!+MI`1v zQyuEG1)*wC^VO~IC`b{P7VrpxAEwb{^1(Wg9S>BAi)wyYSA1n6QKp!6wv>)SXUGKF z)}S2;(f~yF=*>?GecJoR+SR2)Hv2eb1&AfMKM>iFVhciJP}RPMl(C|H(U{K6GD(Xl z0tzj?$W1YZ^3NY0$0UOT!wKvB;TBl0lx#wR7NbD6;Z% zZUxcX#AuHO?8}8sVL||3K%l>c$=L%z;hc*D8U=ndMtCp)9XrGY*MQrUMH4OB6O}kr zJYw5PnwV@eNwe4Z=75olWg>^(`1@}erJ zsIID@qCv=DH)V_=ZK@!D>VP1ZIzH;s9tZ*2v_$*K7qB}^V2_Y%(>2+|#xN^OcGN-p z+HoEYm0L`^joPk&m~W9qiT)1FR03`5QbSp4+kA^GJG#`40_|$hfdcJo&_IH^rnzke zGIi}r(3Zg<78q=8n{ScDl-g4u)11O{+vM7ppdEu}q(G*iBFmlu$riQPYm4cT8?UA< z(qqO|l^c8gf{QvFtuyOvoEDOwxIKk7YnFwDyuB#TNP)1kxtyeWd13mR~;E zK+bFsisPU7X>Esk^AkTUCO3>T3o@cS#uiCPGg~B~%oIs7%bsxn(L%3SWSTqER|3dg z=j=$Ydi#Wdu_%rP^!>#y9)I~_S0GnZy^c`-VKq{Vc0^|~XU1<&qz%vml?S8gL1iApE$%zmGA-LsNwtr1-=06p1ZrdH*5IF`VXQ1B!hU@oB{|z7 zMFg5CHA5`W=g~BoXhRwK)%^VQJv##GiefoC1=^ONoH;enu_r&|AOUpF54W~u4r8nu z5!%%He`2C`i|dM$sGs?IKvL@5g5YSL$Do;*a|Q$A=Me%5YM7=*cb7o<(Cnnhe05$C zj#&0*lV^5pj{EkPtDT968_+ViUJLBq#o z0inzHVC=(=lPT@*FU>%gb1*tAh`sdUvZzr?JWY$&b1T2I6Hl58{`1v zm)szSJxFYW9DovTkfSV0P_@Zp=A~t30~B8}Gh0mgxtR?h2{W_BRD)4#_NjnTYw-Ie z(_&~__L3RhXrvNmb=wjExdo(?6VQAJU_OIntcRbbVp8FB9GI7e)5+@k(zcZW^S|V_ zGMo&FZ7Ty%!fj=gMcHXPBqtL1AKOca9NgoEh@PZlec*R65}7i!0f${aGWE+pnTwJg zI?qpj;}9AyZU`fBmROL1fM`Wgb{rr{8s%3nZPWogF>^y$s}YDBB&z}dY6E~!%U@2N z3~I{53c{h^F)WGaD9^M+t|}?)@dVoI(Fz8p|0` zgIms!T*h*S$$#Ps1i7>PWjrz+1N zyZu(>8JskKs;c0K;&0V4r`{DX!wdoUDJKWf2IWr{m5Bxxl@ao1P=^h(BKLmgkb#C6 zdo}XdpRH{^-L3mL^j}>L^jyD`2`9H+jlbzY%u$m1VFYCY#uxh(M0- z(l!A>&}thlo&3Ctrh}0gyaDCnpn(8sm)Si!(0auIk<4K(Z+9d_TWm$C3EP$LP%Se+ zJ!S?(!f6ue8>66)K>GwRp8{+?kE~b zKw%(yr#Bg}T`93Ix^ox^k%3+P-PDws#91 z@u}3RbIU;`Rin8jlU__R4c#K^1tKr~d)SR%;b+6rw9j;hP7^RiciT7*L+tz7O1{13$?OmDT zl-N^kvzGT%US{BqB1w*d+fchQqsQVsl1a9?nPl;Vwp{FgC0siw8v`JT8! zePW#~jwHk^)dHU{v}-sKzu6{WUqQ?!fJBjX8bRimi4CHr`GMuG0I&l~>NX9-53su} z>7U@$u>`z2mH=~LNdsF}mRr)mEahur>tmuJCcY2E;^G`@ijqd?l3tAfqoi$1i1wKt zihkz&$du}y=Ob%J6bYc^OHCOo=a&0M4dLgO2Fz^nZHzaE-{vc@T*SHpptm61wgkjF zrj&ra)@#85S;(i6+1u}mZzIe&i0>=tR9b*7d9g2(m*r)~7>em5xX$ zc+EDlL&{<{vh;1;0Hns4M|GD>LDM)Y=6O7_qY5J9zJ_h}e9BKI+vJz|8jn9y?$?F< z@VXMtiYQu9W~j|`O)xTTPLpA-O*(j7K>+g!8AdF89DK3qLe@faQNBx_dGPIoSr8EO z9nkG09cGX&B3KueNU9LT!~)&dpt&9h>=1&RqyT;;pz=+^u|L*&}H^O>NLNfp{EDq!^u9rR?VOf%s;D6%n~D(W(_sk;7Fd zp&eO)6+%(K%DFjn+NFCF5~jD>baqNWJKI3{Nr2P=&ctu?1gONV;ZAl**=9rzs z9nkq6f{fXfP>8wRbx-ACx{iS91%T)pTQ1oe={FdFIk|{EvW$ETRQmCGGW@(SIjv7c zhhBdUCng&)aEyK(ng;s<#J$BC@OfeAB9uzZ|(Xqs?E+c3|hv}PbwHKO& z*^l`2iyA1BaBs4dfJu7BG-J7hezZkqLGPw8F4kXwz?lcZ>~-Z zd-7OLvj?SLa zfa&XIV>$k{#(&-m-zfmiC@0P8X*^UJoM|p$_Q_^H%a!QYNO~k2)lXgag;2& zU|EkMi^aX`dlYr}aIke{s32^B49pBrtYKz=?Iu06HG?|!dIkYIHGiQ}b`K{4t zJo;6IQBIj(CMZv44$iU(58Wr)%B>j$-@|!q&4-kS#oE^pb7sJ17pC~YXq(kfIc#m& z30hMlbu;Ih;8^7`>KxOQJjd8n#rvw(CMx2Z&p<&;Z%HLIA<>9q;hPggf?^-zRvn@a zL~hrtK|9RiJj+X0pAu02`17q-M*?Dt7gH+)zXVmAs4!CTg@vLM;)7sjpC1d9bp*Ta z{O#Br1%{VX#7bi2Xq_^4H<~-f?j}BoVgFz8GuGF)MLY}uv5PvSie2zvfri=_JbWrC z{OQGW4x+|>v2u~-@Qam;M8E~V8_AlG*RB}kXYO7`+t@BzU5H_I}|n{vq2pKX}d>6Q=GkNA;S4)81+XVERreuEqev4L#{Yk%ppXS zF}q_%hmCJ5wk|4Jv2|e!%wJzz%6n^FRYBHx%dV;rt7KLdGy-KT%UER5r>%6VnX!v& z2Xyk0oln*5r*$uLBg|%2Y|)4yyr&`$54?InPP-Yqd(sv|W{!Tzx%e%=+d|Q`GYdk4 zI*rdF8$k}C6UMi6nqy*?j477|8%UTL)?EQ`BQd|N9)(cO3Ye@2{5YS^eBRFDv^EOz zkY})yh!H`x)klGJ$0D1#5ur0HE-LYf-rA8fd}ee6s#BkkN8~^N-+C`7?i3It8@n)l z^%C#t;kWt1WW_V>fk>X3FGx<#*mWTyUvAvLb_BqFsBDj5=AANPAUk&U+p3;Mt?_fF zZOUhE^}$4eq5@*Rp$yN0J}DW?G8S3%RrW6VKD@OTei)3meBr0Tu@`;-Wqje6S*CFj z8F!6cQ8oAA*wgtm0>oPEwg`&+xB9jSEdUuyMr%l>lgT!cnTH&@TXcHz7WT?!3nOMI z!E$rRur=aP<4`N&lOp^bJsf==7uwt`qA{Q@ta$_wz;E*vR8-|10d&7v*c)1ToV}BP zuuT&H-eLF;6QxrE*=mBKV8&Jx`i}FVkbD0jz7lb{X;XYnwF7dS?l`iUD&C{P2R>u{ z5>K0MsJ*L*f9gR+{9`ZPvEcYb9~K;6e(T#S#A~y26{P%Eb-+41H=)jV$^Ye@sg$rb zb&Ah&cwULKGGh%<%dnZ(@%_amSphN^XJZM|@mW;1dBI<;BV7i8=1e@65T2_mVF*~4 zzeh?36%joNWDdx8BuI-Ba=*dTau#VH7_TGqO;ZjM5GM=cyY8-pm6zJDm2|1u)T;Si zCayaoCCr^inhUt5@*O-OTwPH_EzF{RK>6k>iY5l##Wq@~%mbGS}GiSW4AOWYuPyh+^43w_Zq)<2p$T zC&Af{jx-$ta(~Eu0d#8AyUf9sEW{6N1S0$`9pW_$vZeAA_DJT;?Ng$e9yus_5HxZ4 z+k$>p6n-()Ut z$qLHM$~nucWSi$k;*-zZyXu-wEL*j`>`-na&xkbUn>2*kJRP#VDT4k|k-;cGzEor| z;`hb9=>4TSMUjMm;ZqcO{fosAq|5xJ+A*rJ+A)+aFbT>yPZM_0g6?S|oXZW7S9;Dp zQ6DUn*_dFopLrNO4Dl!Z2>$Z%?Xd*nPXWxW%Y8_Aw)Dd~PF4^UO7AW28PYRz8?-~9 zk&ZslCBo$HEx;`TG6&=Xs+|D_GKaa$*Od@`=_}fi5O%%qfI#ft9*Vx)+}j(7dUGQy z5B7E>$Xw;q5OWEST=X0>sD!9ugyDOBWKU)I4!tXju*-e11hLC~kp!{JeM1Q{m;1IA zlKgVtw!}bR?mHk}$?f}o3UOwXC5Uz1kC3o$016~v(reb(RgjcBEKyPG!XMRdUHC%| zea|7}#g|)G00~ch1@K0FQHE3T#jXGjC4^rAj5SPO0i=s)?=43rx`vb6AYw?%k%{&z zxeeMAAa(_i7*JjTyrDYGydgZ(7p&*K z@<@fXOBB-IvXabPPbZm6F8ID{nFl)6y_ZR%p?bK|wF*?h_N^E@cjb}*J)~e7vF>JW zsiN-XOpUVtcIKW*_FT^-!-Y<+-i+I+CTnDMXI@mtpWScduGC^USfcTq7K4jPo=ckB zJgstXa;Q>$S1u1!V)a7hf$n_e*5ocrQS&G2GN407-D%Io$)PUhJ0EuwwGOxCrr38U z^~m@xPf}Us;W|x zIN{fKL{YO!l6-Z(b9oczRQzV^?ty~jHpssHLIZD4DngG3{y&fab{-@l<|%-E31RMj z2jsl?em;qx$CKzvKNWRACnvDdSa(~fg0H&oSoDLftRr594MGYP1Kw-O#C*dEu@9EA zL?-aU26ZTxE;OVZs=IX2$2yp&#o0QSr*E?>-lqC2`GwjK)&jAowf-d zDm!q>=0eG=T2$i*<5ey-V!Nc>efZgWlaz2fw_YVZpj<4^zQ|*85HF+4hW~LGO7e%Y zsJMS@DWKP+O*Pf%UX0K)xjJdKKTEf;8mUre3%6R7>lz)ut1$d-hdNI8-CHU`F_1Q<`t zp}t%A;q8lK#$V}u7jv{D)}t@nm1(RXdYHxR`QkV& zjTz7|ug+_bX)B1Su&Y3pCnf{33PoNk;y$g0bs%3nK_Py;KBP{9rD-2@SgPwcT1m2t zc6Iv4lw-23x}$Xy!O&mkR$t)T$xyM4eW)5kNl;WZH=3rNMa47EK%v%{iT9#El!hw_ zP#C~&TLH!zLX2DH5jjZNPn?W-8as;{NqDLcmFUobb0u}yeADI$(wSr>Co9_pPXLS` z+pYw#QbMrL2Y4$|!#VQi9x*tw_Q7$=0p{R!H-5{B%hVS&wz&!t#` zI5&tf=I){bVCKZ01n~K_EgEy2&l%9>Vp+wx@e|n_9w-003 zLJZon9G}WV!7MWm(tO%>bS^gK_89PsODt!44mk9SizA<&lKPwm+X`f+C$(a`Ix3J^ zJcyo_tK)&n<3uefE>pf?Auj#hc<8n9`DX%{&)_&B4F3&&!n$x~oLgwkIgYefEJaZ$ z%{Q@1X>2aS8|K*F2vZ&#v_rZ0#+A+!OB=LBxr`<#vKTdxz76BH$uLsJ6LVa@MGgkX zm5mpUcUjqZA#0T9aUO50!6r8<0*y2CYAQjG>!2)L@V+R`;st9+aiyINM;!&ca6rlM zvvXyBU%}liOZ8Uu&iGgLfI#)e^ns{{KgK3NpP2`~spq4hzIvo*v(Q5yHmrx_l>N>^TH=W#TuUPg~iqUYW@PKuAVXFZVjBloOFa?fqgdH~J2XT8Y6mcI^F z%K%8XIbRM{j*LHVf@J(S;K8*K`#Fb@4fUh-^cD4gZi8@~KU%K+K-`bawI69cw_N)H zGH0&+1FFG{=oS?)14`c`ZvIDx{%E=F)49Uj26YI;&EC{U`{0*4Sy=`5DWkgzBBy?| zUG9O7AGymt(sgdT+yiLNUG6ChKQX5M0h;=Zlmy0{2Y4VAc5a15qz>EfwGTCj1xAxV z{t7ZxZv`;K{(j_s^`yhkEeMUH@gGL-D(yZ@u2vt@k@gn;q`xgs;V}nuSK%F%;PVwG z7UOmY5}X9#;f~0o<0F66fQ)~03qmEUYY0)Px`v=okk(iJkT_L4iz-H0pP}}noo~eQ zRSe6-*tmCb-zX>YR3Ac@@JjxXfctzOh>>QV7smzDsT3=Q;3jk?r?E!`Jxs#y)d*82?9 zR{*9Ns^`k!9#g_8>Mg;UnVyl_Y(y}%m>{4}L2fmL&rwo>zC zX1B7_E8A&rGTT@4bZav;l6d+qj1IbXnsqIdtSc8r)J5c8{0rM7kn<(x(D!i2kn{_? zJ3$SwyA$+n-QXmMb%B$bvGP!@R-S>%qb+I_clIKV4Srp6;=C}kowgdkurv6MNM}lQ zL=g6xT9>>kE@Jhb*fmvQy)Gsi7R)S@ODoYA0AP#3Ra~rV2K#`=Ns;k8+1uG?srLS@ zEmAxozpy*MR5ThS=S4-Mq2cC1g9LY2x53SQ?hEV2wYf9>OLaY^*;QRnNeWav$uF!B ztVE@%Sfp{QibWc3$GmOkg=6LB36>SjPGH6~o$!mz!NfDaCuhG$N*Eo`jnuz#cLH*` zy|f@GQ!e8Xn^5GJ03dUDnJ$j}l|#sYM|lj_9uO!omyE;{@qew1Jfd}38F@tQuhnrw z#=oqN8`gYjH*}d>ym*NrWX>(nU#o+N+;UkRL|h5JveQ8lsbASs@jLX`(N}gVNGjmh z5ntGlmHt-gJ~GJHO80RbzA_D4gpK~nLa2#I(SOs+2yO4a>QB;%zD{@zROf`(fOPt5 zVo{1H(_eYiHNuYFE{=%V{#G3r>VI`$4g{EO#p(60uNmKW)9tpeImdOEARJe$>2K8$ zBQjSjyV2$Sz-3S+dE}w?(cl3jLl!!J7oY}@trbe z`TJA0tsILoW?zYbzgx2tyKrSe_9&03WI#Dg9rUf=Yigrz37_U8_D&0px%{H z`G}S#xkCXf{$cr#(c$6mHVCo&hh+e#Q?TD{P)xaug0V+gjDmsR|6q~!>Fnfp4nUg! z9`je6NH6$DoM(ScM&)@mXy!k-wR)F|Gh;OYDq~1^7~gQw1T#dDV(>e&L(!=Jj?YUn zwUY=?9Z*7wd18{Y%Rj0kj7;}?b%b$%e!u)p_mNt;ObuWd+}woUZcf9_R_|myPs!z= z8HZ(h+Qv*5XhQD89bNw%4HhVbJdf zVYZolX4%d~wgkx0@Au1=pvYSL5Fkj^ALrvSjAsnv$v$BesfZ->TECRPRQb-~71gwz32A(=9e?E8sbxpECG!YfiPXtnYX}lOiaQ%fzlc*?P0`q^RB>ja+$yu7^ z@w2E9#mr}K4N-YJ_zgyqFyr5d8f5Q{Xe`Xw%ovM`tec=hmsxo=i}keFgdGBmFc2a* z$tY9fX?`}xdo#spU@9BwffmzrGI^VuDICj*=fYv2_3+SuYXorg%$Jo5@s@xF5gvFe zQFw->`dzj{!F{bBlq>VAZ-QTN4u=K&0~xY#elv{9;dwJsq*&|RKpUxMy`sW;DGY92 zHlY&vgP3vNS7kOjhx5n4mh+7baV1-@l{EP(x71N2X_)3Ag;hE6w{ zjWz8rxUgD-DY;fYS?lzcjA_ZoRB-WWfC4ctkcWD4BS}FDq{BEHH=x3HuM`Ep-Gs;w z{k1j%0V9pbREi-GLP+c4kO|I|M0P(7(|!tE(4r9m;z{~vt#3s?yGi=Z^udF4GmWP4 zlc3QI*2VAjptTubNQBmUGkJpYF`=&zrp#LL;K8I>K)b=~q`B}8m-gT2iAag&T=j{u#d54vx3 z#fVPJ1MpjAG|r>q?PZFWnn6Neg&FWWpbZRF^oNJ8j++=?e7zuE$Y6?!GIJ+Gn5}mp3qa8rC)j-spd0Em)!t8T zKn;TFkeFFl8P7_Ja^!frs|NY!@4f5 z^&MJJr&tk%(T7E~^j*p*(tL0#qRC(MU0rs%8O>&sE5UvzYwgp`VU~h$Ys&Q~Qp;wm zCFq>R1;+Zs+N{bdRdtqCm5d!B5exlE%BlEeZ9^O>iFAL9p8vGF2ht6P%Q{UTw#FTVlfH~4EjC0 zf&^8PCykTIq$VkkqtVBgX}QnS)iz|Oiei&7LtfpL2pRINh+zkQatf;P)g<{n?u~C0 zA@q321^sb<3l_T^ro^l~@9Wf)?rAHm=G~^e!)%h}1Q;E%6769ISJP1vRcsLPui#J!4$Sg z>y?xar8qk;wsniGO_JjDZ+htBO2s9AJ6v(wF@hSA~239U-(}NsBx~fG9;JybB zo;E=#*TmAlQ9h~PK%_NfYf!E7Io<`mzP3JX4Y;KiDP0%RR8PPU%>=|TXjO<<0*HYE zLOMy&7pgC=TZPh<3z7mEmjb8*&-)Y5z7Au?GJvGc2AdzIro4d#5=&9duf#q)GmD{I z^@A3ymDkrSVH6j`JQ2DTCRz$St*&x9fD~>MeV;Z}?<45F&!CJ zxE}=J70kPE&_AJfoNt2D!!to(fVT;bFSVTpr&Nuh&t(mLpw0%P$R$$b=8dQl(}MM- zU2lb-dHzZ-KOR4G3%ue5W{OoZy`MtHSX;Zo>7hVk!1Ev4iY#yBcKY@s)Z^SBIM`wX zWOESXVkIku@_D2<>FUW*esEV^0>>*+!1NJQd8cG0Ruinz^}hPLihump3z!${Vlz;0zaZwftrf~%CIlu^ezJZWq@v=_!|aFo z;re>k`WdtXxtYycttW+Gq6=M>P77gGZ1rS1kX?~7sjfB9d;%<7`b2BHjVCBK_OmM(paRPvxS!ykbHVN_8 z5A7$wGHDC&#pO?eLozP(9M}fvGjnUt)_T0r0mKR@4JycNl9U2$&v(OO4YbhSv^Ias zl2qmto4sZiTcdsAiWOCAYPqDu3#9W&`65e34Q2s-!_uFT0sJ-Dtg8l2Q|6h!ZM_FY z1>Ela=cTQng2dZ+RVmSQi_pS#8eCsn_EupHG8H}bBWpIdI_F!@=)xYO$`BS%j-UmT zqh-Uy$XGC=niwoz-{x$=6#K-H|Dn@<60~u4=rg)b8#O%sY0AE93PBK)wGT%kEc+)= zBQ9+}XY;&h!ZIVjF*s`(bI6Anc3~rgoXXkQ(<}E0<)GuCR`^_ez0T6|yxBSpOO?OD z)svqs!L!8ptE?;z%MbJ}wThTy%0+_>&MHf{s1~_+GaOl ziiQvjcU#8X+?OzWQ`QtiThKqHurxlGr65Dg9PNtp+@y5~xzOs(ay>zF0?cud0C{=} z5X(X^l;#*T=Eg>2S-c@_gH-Av?CQ04p;6b&%{oT?sj2Ufx|C)NQ#wR4%peqTeNqcV zlb~-mVRnek4CZH(?97@9s1cF9qTGzri_JH0pC5gCe)QwVpRTV1JRj=QJ{A4O@u0Lx zTGU!`5})GPToXwtPjEqH8IXwy{|$o#R1a|$mbH|I0TU=09b(}=BZHWNYM#p8r>yIT zHvNIi8~-utHGtXCK8CaY2G1%QZpGS2g$c+&(gxI@hsp%j{|4fC)H~^f-R^0al+h#^ z_D;6K?$&9DayiFS<=)A5*xiQYl!6!bPWHm?-f4Jwo|N#hwHIz3oQ7w4eAPQSXwwJY zcliuS>T8bqw&`Pd6{Ya8s|uk_bgN5W)94KP8^QMueS<0nzdQ8%DxOTTOZeQv&zn%$ z{rcaeg4+wQ<{%U+Q7;e$0<%YCAhY810>oQw4|@SpBM8N$r?eQVMB7U*kl0b6$oT85 z7v#8NAytJk)jy-(KZ@r1SM-Gk*8PG0$KA1^66F8Q|+<7x4Fa zJPbevZd%h2q_^a7026<25O>3p94?p_Ey2^`L=16PzXL2LP2A4W2+rP;BrY=+$TLL8 zu$k)v_CsLxN!-jgHd^sXdXk@>qH75Ld&mU6v?ih00$d)=i~P|f1K6WUGI*3`qxjP_ z8_j`d9}VyT2rwOA*>ISju$*s*&kf=2QP^3eI8{|_{)U~E%2W|g#%o-kdV-LiOufYS zEHCYJ0qcFcY2itXXXtyK?eL%2m0o8*RD;;-?BQ|C?gFo`yeSW}KgAcw5q9NYgLD$!sBt`*CR@Rt{6*o26tv3vF|F*@Ph~;6vd4#<^g4tZc1V(_- z5*1l=_v}=QEIg0YVqWv~PTMM6#CEc)T^8iC6aUb@z7~FVplk~5;~0ty?IVCK_`E0^ zgSZhjW?4Z3siAFuid5Ah6z&5z7D6#lz`}x-RWfja8WD~UZQf{Fd;=5UP-&dB$ObJE z6fBQee6O#wW)+GKQ&p&P{1M$Q+0k4FwEoI&?Mc})q=EK%uYOy>l^Vp4fGqwGq5(G$9+12cY=G^G?QX{`whXZYZe&;ayAwP^@A5xq|8=X@|&j?o(rZs}LND2`i z9AMYK-B&APSQ3Q4CN2+SwLFNTZC!K>c^!PT*OkSz(P*T&+F7S)MIv1@!Ii2qbtbYH zn?YJMwU+UEXfZ3$K_T(rf$;U2q7{ADnj%wd)$_EVhzc| zcs%;_3LfC~rVVhWmMpTm?GN|giMp2x>eY=`6q92cq5 z+H5`XIROgiKn#VKf9j_pGmrPJieON6O8AZWO7+wcb{NxR!4a&zy|qqw3ENNco0jZx zayFM~ZP@0+3|flJp|JPawm60#$B5&NDrwFk+_kG;Dhlo|*b^t%m@+piJgNCK{#qU< z!_ThmG49t}2p&8TK-4E*PN(rG5$7T+lmKm}lz!S82I>LnHfl=IrmJEZHk)2g<9Oaf zreNj1a-xkeHH{dzvamAk`s&gRR!O2uRC0Y?%CoN)UYr?4WrSi)nk+U-AY;(_h6m2s z3{PRAvq(_%kX`i3XJv z;+|19FM%K1kOy}un`Kf?;(j2lECE2|Pt>Y%G;Otui-~qLF50Lz~>q5ujvQ6exTvnX}q=h;pyMr(eH5H z{}!lgD;uM1i1KS=FfTXGvT_4ME0-H(bQbi2BpqjhDE_>|bEwedOS5zXo88E>tW@Be z5M56HO1N6=TW}Mx)L+=7-EOxf5Y;7+*1{Zk$gX`vVZj84+&4iLZ^<>ba3%|@DOSI3 z)ZXUfY-AlJ>cs$)q1$*!{R^&-^2|%g=|g#5h4(|llq80|(3PU8wEQ_rN0S&m-;u!2 zvmxn`y&RU?5&NQ4`IeSQG#^OrXo#`KdpTe(cFww9`s!IMmTOu14JJzu%@k=2tN3I- zP4NO6{Roi|y_oFgz4=LgdVMV|Yd0t{IN?C^Aa;6@M`wsrGq#djJ(=D#!>{6 zq^HfA^fMZu&A8PHnall;W}#LV^FwA2m%b@|%ZWq+n43!9a!~2}9EpCjEXK(1KeAh* z@gb_Tq%6K2lky>uNx6=SSAbIGk|Js_M@;2S-ZzdXtcu*NBCoH)tbW>#aHG!kn97I? z?)7!ECdIl%Bk#`1ou2B|8b`^~Xfvp(yMd_3qXw#>=`fqlKq*3dR#(5Rmf`J0*MFjyoE&~_GTg_Cd?o`lq&*B5T5C?STeF$OBca_fv42EWFp_vFI5+-Z)5pR`ex3MPajVrkfi76S!N4xox9|34WCsDDe5ZjFZ&N9raC3FPrXZ{^b}cNFMh~cxQI2-bSx+iJLi)Enn8826}tVKMl(;Z0eZhZ z=Dkzv40`ls7AF zcj2MaIGMm&;bRa=_(Q1$Yeoj^?jK93F;Hp@lp5nfvZ55Q<;nOol(d=y8e_UsEwB1y zi)n_B4qtglM({tBVt*{DG9Xn3q{>9po=j3}O_HeqmdbF*xI2VigsWsKvT5w05`zEd z5viU=ZAGJwheqOhjE71h;g6%!{Sk)FWC4}RxmL%&*%3W!;O28WE3aThhMqSrlkyzu zZeZN7B$_m6cPNjQ3(zw&-`Uw?&|)1)OS;S`qdQqNG#J7M7K-)tQ*+P>>&fGOau4X; zi1i8MrXYVD7Qh$A_r2h>4kd( z%xr%8M3nsW2{+LEJoZUV;Ei6^lKj5pBDENStA4N~A2X{(4LorWgVbvThf7L22h_&K zSFU-Y<#4+nI{@`bldE+Rc4KW!HS?nZx=?XVdWtwtK|Axd(0$cp97Ng@urf9Dgz(LwI*~Ui8u=I2+*7QSS1#(xQRZ7u`dzW zj3E3GM5hObu0@aaNl^aDpn5d=O=s%S;m}QQP(8x=cB8ewQUqd(Ps&rO(}ZQ`BR!4)#;YS{!k|g}6&`oS^6HAQaT|kqpZ5%L2;-a3cJ;8?l(^_nx)Ko! z=KVoa+GV^v>|gO@K26}0U|khm4^A6v{l-I4{$ZdjverRX!c4biD5AjO@we$ssg22N z%I@;uf$xwdiHl~AEDX#BJ@B5xh>joiFPnG<^Ff_>jO0m~bI5VoR0)!Z^3bdqjFJm^ z+kfro`g-j{3#0$BZ}3~HAh#)5P#@LO~d2^<=*pg@wAfp&wH_-ywl``$>| zr%rG@)#Y||`J(EM*K?}wYl|J!eHH4J=$eSrp>Ccgz?x|L1bzynqK2#C2n3x9uqUKs zONAz>m9E+^62&0?=}W;F@@$20rswH;Dz1&ZeR>AVHR1_pwzu$WSvnyNqc1zPor)8S~q$vBDcLGyg65( zLxJf@C20vIlHvo9D;}8|6vR`IObt5Qi#+>1PI*BASz1sc2P+jXY@k*JS`3pB8`N;0 zIafwV3go6nYCGwAKX?)x(u`PZD`!8Unm9h8Lcy@K08|ac)O>|5SWo*Wfm$>Jd;?g73IGagg8gf$r|gGJBClj-&KC;GPuYs4ptm-GqaCCPif{8IaWViF|& z@1PaF<0%6A?=Upp7OK=z5gBL$siQtTx8jPu!>=1Up?y(_M!JZHKx24VHh|Ib@uLP^ Z!^aCRntfbVRb0jOG8-swqRa>qImimbGV#CDYTdTOEX&JIEcM;3R;#5gWHULne9~$q zHo90&cPF{gqLC#hkN)>Wmz-+y_-Cyql5wh7Q7j+s#h#bajtZu4<$5W0rG9nf%?<`w zVQ9*`f+(&}N>0Q~82}N!=lf<;8~Ss_kNbMV%j*}{@4R(Qi|c~SN_9Sq`Jool{FU{A z6GUf>O>Z0x5W{e9nVj$IR(~nC{I73!CEz1$3$Rx=E?@I+h?dc^5RkmcNs5IYu z0bCcfC7lzBcTopEe-LupJWN?}0?Iof`L=lbZ9d;No6~_y?W8cQIOy=lNhpr<27aAv)&ea2oKuFy#)?@}yv+>!RHR+Jk=Dt=R z>2g6J&gVr~1eOg3U+V62WO@&jN z=zG;XOeBApd}jPx77va3ovZn8?Zi}N?Nd<&;rr7Ab9r8rm(>0{I6r9bj#ZLuHNWIy()v6m9)n}%doJ(vJ!9{# zO2s5~X;Du@Y6tlx(^Rumc0#Hl35aH(0UX%vx(}ah8wzN9d0m+mIpm5zkx1s*eg{9x!nj(J5A&465L*& z_Bv1j`jBBmlxpx)Ai*@Dyz64L%i>@djr(N&G%WM88m-<(J5L$Bu`R+6G{h9rwY7C=kjs>A2rQUg^ zlQA`i6}IOle4VEVHGgp{ehJ%Aw)Kr}dIqwfVq59BD_a^y-ly?Vw}L{=6ZT3CBsyCS zh*%^LYI3mXmd;FAE@8q(6SQbf{9c-!+wH%JcjCrnxL|!XH{2lz6jAeETX84ry&t3k z!N`*Dp=3nhO>;QZa!cSt-iFULNk3fJOF)Oj&|36I%(MyAa8vn7{w|vbIdKqGF$>T@ zW5|Ge23?d-NC8Ub(OC+cm+3I5+7GVUdvPd8YQHo#OTQ<1T;Z|-G4enW+8VE|m(dxZ zPg^SRUWegCXua`^DUVGGnK7@b$YYV#<{IR<=St|d7eXNE>B!ZuOj90%gMIt*H@?yH zjpDWDrH(W7(QIZ~olL%}AO!X&6KGsQ(pF|;tEM;f0T|ie3ku*nad%SgyTf>%AH-im zrlJfNJNGL*6kUKA7g&l6+B%Z>(RD*hsaoFgr|o1*z7!CMBHHvgW_rqtb^4idiY zkB*8I&FzP{a9dp~%^m>{3}vA!?H9G&+8OC*RM#zICU+!6``I6-dY^CzVg(i`8Dosc zueaa!Ou`)g#+is`IpcIX5V2E;_~}&8%@4SvN8!9|#rMYO)#SFAtN$Rge)9)2rpd=*^c|nfgDT)i4%-1I+~86hzYXIYT!PrDplSnVUJ@OQE6nP z(g{YWhI(aH_J9-usT}CtN`o}3n`%KSZHo5Q)w|Wxm{_x?;4SNF!%dTH~NyAzTL2Xv4(lFve92nWY_?oDJLpQ{L*R_xWrrhX3Al)GrLV z9rt}6`g|msbs+MCQQ|Tgt7IS)hX$ltuE%Kkt^i|2gPFBhl|w4tAGF64y+x|BKTL-t zG>L+sWu6uzS|u04Ph=wGg8^p19->HW`RgyrRrDqfozJOfaA-BXf&Bxvmy89@zd4_A zqA>fPNsddJB8-xpI_$5ZtQKFH?TSDfh%uHsd!?TboQ-MV!=4LFKB@Tg9NR$h2nizq zHrzN?`a?G4vZw&NzmI@C%#TGt;GL`d|JM~N*|&PmiI1$yOA4cH?V`Md!-y9R4{^;dug$fI-AaT0Kb`F%sfxNIdj#cd9wy zKGB+nZA7OMzfjI_`uR)qfuF7P1EU%7C9F)6xXF!O-Hb}5ofcT159gkixXmQ?N#=0W zucFA8OE!;sxiaeoR!943<4HEtoJ|O}E;PB)5kd7;i@u_OPZgZ!>(1;RuQgvuuXk#ne4 ztb|Shzn|unqL=T`{K-Fl)r;$1wLG@d&scPZ0}9^}r0dAY!9R6wk8`F#UL{hePgFo; z#a_!)f8@;$QhIKkB}R^Mcv}B;%lEo|`Y`7wC(4@@Smw>xFD0B{#dh+kp;#3ZtkWBV z2CeP_C6Q@jQzMqXHs!f?9DF-%U^0F@XZ#ic*A6byZJmVk8o#Hk5VGY;7l0kd6gS}l zW2)4&Kr6V($>G%M$xA+YX7Qd)8Z~)l;hz-*Y-;XE+6m0+T5e1gh?hp^b0lR!0;O77 z5Wp^{+6LeGJk=QKnFu&_4Z|t!QSsKaqKIoSISNa(pj%cMcN_{7+*yQgO)~&jUL@8s z6k_Qu!xGC(4gEHk&r3E=bh1lKHL(<1$Ejg02CH4WC)WCCEgQ^bbHA&RW!X%bv$FFp z9$4(iZR1@&Wv5&?Y)n}34mGrFCpbJow1RZnHmEQbdkqGEL8X&4DBM@bIxWPUTA$BF zv2-nAZ#CN)_HkCBx=sV!Et}AQXE($UVJ%*Q;$gpBP(fy1yTy8z&I#M5L-9`RR?(X^ zh$A<(E*%B{;C0uAhyL4%&~YYa)J)C#)?Lq7&b70*wWyZ$r&X)A@#0OgW7=oUr2_4C zt8vEZKuszyajEF;NkS7NoL27$=yP zn&WrTpfEcaW5NI)trb7D;vif;#9ER(6Cg|9+-%rl**y31E}PkmJW5CprQOa6iap{~ zg0bDftO6zVz?;6-Ri02sLl1tmYA#283eE^N^@bc%LxCD9s-Zv)35zIY4hx=Ntk;*w z9mkVh8cZ>7b~_kUU}TpX@Jb@w3X+bXbebfk3b^MWT3)8*oo2j4Ia-cBiBU5q)OdI; zC0+wwh+DH_OjmpRE8O5&u_PGJr)Be-3b0*-L(>Au-WU^bvuVn*6cp1HqK{Jz{?JI28B_KY&Lta04@*c?j|?|GEJCsL_8 z!m6XZI>M-9qXq!$?H04pR}ht4ay8ia#xl=^cy{WH=N4bED{#ss81zjlJhP(T%2jca z?Y-FPqAHB*iZ#qq^an&S^Iq{~fc>u_J}t+&8bi2LsYPy%NTOr*D-_ z$@&p88jt0-8u`gRo_g@pf6ZTl$52yehg$0zYB)~(iweoo7iKHJF5}rWKeSat0FWWS zaS92U=XIuB@o(Y*aQ1(v z)S(lQ)Vzc?eGn&#g9^&i6LTZ9W@2@!5I6{2N_qlOR`xy)?dFt}{%l(DvIcpl8Pu%p z!_7)*6|S+@+L&9K3K32z*^?*R4IT~%=kL4dsY~sZw@h=;1O3>13dfp2C$vz)p*@iG za2LpiZimBo%lhMcad)p7T=8aMnk5K)(HOjw-8u5K9p&ZoIV#8dus7|K9fTwr5~mYe zCQ6P-OqPSV&)YF{iXEdK(D;FCDObb(VWrr=c_Z{Cz1)l`Ym-E97<0c;r3HIZ;bowz z`W_D?aWK5fC^qQ0f<89;Z6&C^$5-L8$(EZulg36C6j-GN8hHluBx;?L;5`})c9Lv> z_E^X#I9#&zXx$Uv>+la*&IlI6S6IfDWaSoa=teH+MOa8TA$&$C3dt=o;@@b&wamgZ zSVYtXsoWqBgH8Y;%hw=GQ)vkyR6k$9{+KYJGBg6)q!Bo>8G26tYdg%kbR=nD(DpUA z%f`Yf^ggluKzhPKzh4u#pVE35VsBxifZZ0wn)2AjSgiW9m3=uaTKo(67Q$wZuerM8 zTVwCG#3i_hml%|jDghmv&o|XUhHptoH$R)jci}=jk2qZDu0ku#$)^FIgV&K%hz=b> zj?kxs446@fd^7O#P!L*ExEINO{2TsY#$jcudIP>Ii6iPB4_Pl=ZZn^(IqYRuQP*|h z9ztK&*JS8BoEv+az>~+!>V-VNP}g^~cp(eo=;80KdXfxI1tRAc@;c-j$clX9G#IfuFLN?_QJHe zp_=bMPV~M1<6vs$7YkXYYQ%c8e8hEANeT<2QnW_iRp>2X`l@dAx-;j$!-Lvu6uMat365*4k`In$=J@5s$_)oo@ys>E z#DR!AVn9D-?3lYGJI?`)ZY-nqO~c1nMA}hpzXvRq{CR&4-xT{>RC9D8)E*r*Ghcp2 zgHTsjFqPL8PUMSgH}{+DFx!p8zTpy1+GTNz^9)NJ|Fc(msXo*H&~~NmjnhE*uO#KN ziAoc0oT_=a&*fasP3K(qtfQ}jkR%5{4W8-}I5wXs*xt_UB zhu>JGL+Lstm$i6GEKKFB3)bl!Z&vW>F`gx!=0yV7IY74MCJ<1umUXPm*^VDr9o#oi zTaslGA3Wpl-x{*5mbYCpBx6pJI34E}B}$Fc6{i25IrgTQNDg4L1xad?|B`v=DZ0oDxI6iZWOFQhg|+A%(~^etwXS!4;D+A@Q{QxiS-C8ZGHq- zl1KL0)1&f2a`yr|-s5Pj8{xo}!i=MQ^4d~iGrvC)0!~uk*fpBG6Q2mH7i6C5yH38J%S#q)8z=~a0_1b$Fr z8nnbSz+n2VvY>1xigh5+E}TOQoaI)$8ah0jaE6QPWhO?F-9(gbt?=p-yOEJHWLXN& zRX$WW0U8hY`|#+P-ZxyjaaS{K=HiL6?VT=*Gh$drSuxGB=3Rc%%{W{*lK0Z5p46<% zm!-*&z&e`UXDX^$&Dzv1psWKK!7?}&S<6t;B(t}@2`%R=UVm%EX-{}Nphf^wsxHH! zPGuqOMmo{i=BPJ=Pbl*p8jktO2}|D(vb}VPJ>DErhQPx*IP1glj>Yr#b{HRq92^eg zSOM{)UvbFlTu+4VOLdBT6rC0&j=5Y{&h0Zdz+fenM@x;$FHmL)=zbpowa1GX46gyu zFKGNO5?uuIe{~x=fxdbl!}`gt>rs{%ab;P96|-5LS2J*;jyU13#j!4S*xxDRL~r$s z-xDhjBqHu$o&L)4;a%B|$II6uc<6hyXrfV{YN2n%T@iM=f5d>fJp~lSD6T{~x|tWQ z5K?DzDAJQK`tsllI&8=@SgY2|Yc2vUJToY^q;A5Zin9 z78*u0#+7J;`R-bktF@`G9+{)n1FKI-iOCUYkyDsYL`R^NLqhviBRJOQ0SDI(sGrp( z%&UZ2X>>6B_9P%)qQijH9tm+EG}AD7F;2>b5Ld4Ql!rui8^d=EB&nCeJ2*=psqOE; z=jc zUX70A-Slg8=X?<(w7X^F_|nt(bg9n0q7tb5lxBdQBBk{4lt9k85fh*DEZKqtShSn+ zN+46~&EK!?*@es2&pbU_efRjyKFe>{-=5NM~+LZhD@x@Vu?wyAZJ{Um;b1)Nm zK=`Dt`{ZNKy}Ue%N{?*m^GWGbw)B;x^wgBTIA5CPVX7bK4ZDxF+g7OY&<132&^N_m zYNhc?Zfe33F0fhqCubp_J!j^raQvo4x-_b^6-^^9UWcfThyZ25COJU1Oi$jd85@fR zVlOvhm+56KD0^7_BI-_IEU|Z|LxlUKhio^Of^NoYSVP)!V9O_<6q&}rY$Idvo1G{d z*Qm;wC73Ez?Z@ zjlRXXlFk=fiX@AuuT|(zxVr}HMeAm(c){!rvrL@9Y+*3l)5_V)cE+F0Z~F5X(6uvM z_?8=I?xr7$G+sV{&aFFc;Qc97s+7hrl1kv7uM(4+)wJ*cIn6VVD-xiPDDR~+{O#5MIjp*??7^be3-T}E?@rMC7(v+t7r`b znnZ$Poid;9)VC3O1ALZym%P3^$0VL*-m~!O8J2VEa~soiVjWS3#+26 z-8$=7Ng_Fw>+ak{^1)~lI}IW z4F|o+wP+A-lt42LBR8)515K8k02k*`PJfN~kSz2dZ&;|=FvBmuHb6c1k*H`7^2b>K z9jxer1?b>0A^NHr?3*TYlJB#dqZ5ffe{VR_p8Nnlzyeg;M`<}F!?_=QrC+h`k9{=a z$ti)B$1nO^05b&$U55<*K@lMRo?>#m)rt#fbG#^hhv@!ElzhisUGv|&2_Pv z8d05{trlrexbgEoS!ao`f)9=e69y+;%8sIP#O#^A#lf|juflVoa@G^VRh{)pP$4Za z3q_R|y>h@;uVq)p&6DW@(i0=y@uRw z2|j0|G|>II$%WF{QKl!pe4@X@O)9hrY%6^sZe-Fi!0>sSN0S}2W7i$C5&JwmbJqw z><&wS#dVL;uk@BdQH{*MgP9fcYM&F{xltg?6Z3lAjUOd*B#A&zct%PCrq(%ViHmZS z!Pn$*nKMH=r}Ach&eD~ljRKtL@YD$+166fgU7)7+h?`?wI=)Jz;9b0bQt>%_ zOna)0z6id8BtG{dEZ!M^@daEdaLQkq;|-;+yg;R|yhNpoXP-4U5gf+XYJ3_g)qDPB zs`tW6%dl9xA>!Zlw9}1%59u=ChV{OE>_4@4GG$j^l1Cl!+Mo%?Ap7KhBty#Hh z3d{*sKoi}2OaQ6XkW(enN6gUnL1%-ju` z4;f~_TQ1yxwg67Fo^AVKcfJk;PN%pZaTqBGu&*nOW_bNTMY@S8J>K)Ai&?l`?&P^= zv;>L64YPpr)x$Ug4lftL!6f9u{O>X}3p<=5;QZ(?PFCr6QnMI4f!2mbmDSV+JneQ3 z9-s5t&kSv7mEW5UQh4Nar3x!5@exne&^6u8S(&|=N2ev9pCZK`*i;_M|C z@U?V`WmYn!A3Nqwa%Wq*J8BErE{l@mFJeFX7rmZlo!OSnb$!0w59Q%CPpe+{FZH**=$rBbJi(#;8(js6Z%tL;K8I#YW_7odB`ir&lTZ_4ay1t+oJ<~u6e>V1R`L)g(pF(sZ#{X}G6^DZ67Ya~JfL$|($i5K2M z#j6{e&IAbrP?@J~&a&O=RaN|V$d@XbD6P2pbj&H~5G6KzBr`I4aO9-r zsWFy)1rbxb!K){rHn*lz8zOKh>VjSK zOa1eUe!J9q@(Xlpi+@*+rx(V;Y>XCJd-fxT4oXKBJNo|n-x`=~Ts!qW7Bi3db@-~% zuY~5u+uKJDzs!C_O7OMW-zx-rv{L>}c`i|CQXZn}srOg_`_{+FJJ5GW3gbmVh1jpnNKeWu#d&lyby zls1yH@KYW(;8^fLf0kLW@?&{RR`;fhLRSIRt#-9c|0-{Zu&GO9U|lJhv(7zwHyA?F z63da}#cIkQW1apX8kUD?@Fom{POV|!b=vbja{FUbZuPw49~vVG{3=JEwFkfS{dzz^ zzPXw#U2VD>q`>$*Eu;Z0*T%nrUjiNV&PaeGFe9SoR`;k z55*`3tl?{1HTA6@df8VTh(XQBW{LS?jjgN1@v7Cu$5f^cd zB#K%uc^!@rX=$|rTpBA^uS*OMdP_N?9p0==?H%b7q+4y@GC5BAmSHTm=~!%OEbx6Bf4I zwLdRrlt6Fp{K5K6owX=zXNuCsIH{IISzFAc29yLSXS~(6LY+xKOVm0$0}}j2d?z+> zt+Q*!uc~1jwNag^F`r7sak4wzOgCY3WlPvp?(t_T12!oKOGNb-7PHRwjx1!GUYu+W zJYwazS~T&Uu_2iOu9&t{6x;e8^q2;t^;k2jz&I=@X+5??B&0s&s;Ey@zG^tKw2F$i zdryv=_5Y;pTA14=g79C#8Xgik(zu}o6ojYH6v88grcfXWjACCBwYKC+a+@^xzw_ayL%pnpL;t8kFvOCz* z47P)DgVO_d?h-RtGI1cTj|V)f%=I!p#S*8cMm|9Z!vmCT&eR4|teDKHHuKNho%0Dq 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 ## SmartSwitch - -* Remote Temperature Control application with schedule - - (example: car block heater or car battery charger for winter) - -* Based on [ESP_AsyncFSBrowser](https://github.com/lorol/ESPAsyncWebServer/tree/master/examples/ESP_AsyncFSBrowser) example that uses embedded ACE editor - -* Wide browser compatibility, no extra server-side needed - -* HTTP server and WebSocket on same port - -* Standalone, no JS dependencies for the browser from Internet - -* [Ace Editor](https://github.com/ajaxorg/ace) embedded to source but also - editable, upgradeable see [extras folder](https://github.com/lorol/ESPAsyncWebServer/tree/master/extras) - -* Added [ESPAsyncWiFiManager](https://github.com/alanswx/ESPAsyncWiFiManager) and fallback AP mode after timeout - -* Real Time (NTP) w/ Time Zones. Sync from browser time if in AP mode - -* Memorized settings to EEPROM - -* Multiple clients can be connected at same time, they see each other' requests - -* Authentication variants including [Cookie-based](https://github.com/me-no-dev/ESPAsyncWebServer/pull/684) idea - -* Used [this Xtea implementation](https://github.com/franksmicro/Arduino/tree/master/libraries/Xtea) for getting a fancier Cookie token - -* Default credentials **smart : switch** or only **switch** as password - -* OTA included - -* Use the latest ESP8266 ESP32 cores from GitHub +- Remote Temperature Control application with schedule + (example: car block heater or car battery charger for winter) +- Based on [ESP_AsyncFSBrowser](https://github.com/lorol/ESPAsyncWebServer/tree/master/examples/ESP_AsyncFSBrowser) example that uses embedded ACE editor +- Wide browser compatibility, no extra server-side needed +- HTTP server and WebSocket on same port +- Standalone, no JS dependencies for the browser from Internet +- [Ace Editor](https://github.com/ajaxorg/ace) embedded to source but also - editable, upgradeable see [extras folder](https://github.com/lorol/ESPAsyncWebServer/tree/master/extras) +- Added [ESPAsyncWiFiManager](https://github.com/alanswx/ESPAsyncWiFiManager) and fallback AP mode after timeout +- Real Time (NTP) w/ Time Zones. Sync from browser time if in AP mode +- Memorized settings to EEPROM +- Multiple clients can be connected at same time, they see each other' requests +- Authentication variants including [Cookie-based](https://github.com/me-no-dev/ESPAsyncWebServer/pull/684) idea +- Used [this Xtea implementation](https://github.com/franksmicro/Arduino/tree/master/libraries/Xtea) for getting a fancier Cookie token +- Default credentials **smart : switch** or only **switch** as password +- OTA included +- Use the latest ESP8266 ESP32 cores from GitHub \ No newline at end of file diff --git a/examples/SmartSwitch/SmartSwitch.ino b/examples/SmartSwitch/SmartSwitch.ino index f99a2e26f..4244e29dc 100644 --- a/examples/SmartSwitch/SmartSwitch.ino +++ b/examples/SmartSwitch/SmartSwitch.ino @@ -13,6 +13,8 @@ Multiple clients can be connected at same time, they see each other requests Use latest ESP core lib (from Github) */ +#define USE_LittleFS // possible only for ESP8266 for now + #define USE_WFM // to use ESPAsyncWiFiManager //#define DEL_WFM // delete Wifi credentials stored //(use once then comment and flash again), also HTTP /erase-wifi can do the same live @@ -44,10 +46,16 @@ Use latest ESP core lib (from Github) #include #include #elif defined(ESP8266) + #ifdef USE_LittleFS + #include + #define SPIFFS LittleFS + #include + #endif #include #include #include #endif + #include #ifdef USE_WFM #include "ESPAsyncWiFiManager.h" @@ -62,6 +70,7 @@ Use latest ESP core lib (from Github) #include "Xtea.h" #endif + #define RTC_UTC_TEST 1577836800 // Some Date #define MYTZ PSTR("EST5EDT,M3.2.0,M11.1.0") @@ -517,8 +526,12 @@ void setup(){ Serial.printf("Timer set %02d:%02d - %02d:%02d\n", ee.hstart, ee.mstart, ee.hstop, ee.mstop); Serial.printf("Temp set %+2.1f\n", ee.tempe); -//SPIFFS - SPIFFS.begin(); +//FS + if (SPIFFS.begin()) { + Serial.print(F("FS mounted\n")); + } else { + Serial.print(F("FS mount failed\n")); + } #ifdef USE_AUTH_WS ws.setAuthentication(http_username,http_password); @@ -676,7 +689,10 @@ void setup(){ ArduinoOTA.setHostname(hostName); ArduinoOTA.onStart([]() { Serial.print(F("OTA Started ...\n")); + SPIFFS.end(); // Clean FS ws.textAll("Now,OTA"); // for all clients + ws.enable(false); + ws.closeAll(); }); ArduinoOTA.begin(); } // setup end diff --git a/examples/SmartSwitch/data/acefull.js.gz b/examples/SmartSwitch/data/acefull.js.gz index 11645575f7869e10ce99a2c4199995a224fd0142..373060858ebd1d1e27f5489917f59a039dda37d1 100644 GIT binary patch delta 21 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 K7~@siD*yoDr+1bB diff --git a/examples/SmartSwitch/data/worker-css.js.gz b/examples/SmartSwitch/data/worker-css.js.gz index 61fdcd34d54c969b12c55d75d0ed73e69b636123..dfb3f20900e5b7a945e150a0715be080957f02b7 100644 GIT binary patch delta 18 acmbO|m1*`=CU*I54vw?GZfshasParam("edit") || request->hasParam("download")){ - request->send(request->_tempFile, request->_tempFile.name(), String(), request->hasParam("download")); + request->send(request->_tempFile, request->_tempFile.fullName(), String(), request->hasParam("download")); } else { const char * buildTime = __DATE__ " " __TIME__ " GMT"; diff --git a/src/edit.htm b/src/edit.htm index 584b5bbbf..c1ca544c8 100644 --- a/src/edit.htm +++ b/src/edit.htm @@ -1,6 +1,5 @@ - ESP Editor @@ -196,7 +195,7 @@ t.append("path", e), requests.add("PUT", "/edit", t, a) } var o = ce("button"); - o.innerHTML = "Refresh List", ge(e).appendChild(o); + o.innerHTML = "Root Dir", ge(e).appendChild(o); var c = ce("input"); c.type = "file", c.multiple = !1, c.name = "data", c.id = "upload-select", ge(e).appendChild(c); var d = ce("input"); @@ -255,6 +254,7 @@ } function createTree(e, t) { + function n(e) { ge("download-frame").src = "/edit?download=" + e } @@ -274,10 +274,12 @@ t.loadUrl(i), document.body.getElementsByClassName("cm").length > 0 && document.body.removeChild(e) }); var d = ce("li"); - o.appendChild(d), d.innerHTML = "Download", d.onclick = function(t) { + o.appendChild(d), s(i) || r(i) ? (d.innerHTML = "Download", d.onclick = function(t) { n(i), document.body.getElementsByClassName("cm").length > 0 && document.body.removeChild(e) - }; - var l = ce("li"); + }) : z(i) ? (o.appendChild(d), d.innerHTML = "ChDir", d.onclick = function(t) { + f.removeChild(f.childNodes[0]), m(f, i), document.body.getElementsByClassName("cm").length > 0 && document.body.removeChild(e) + }) : (); + var l = ce("li"); o.appendChild(l), l.innerHTML = "Delete", l.onclick = function(t) { u(i), document.body.getElementsByClassName("cm").length > 0 && document.body.removeChild(e) } @@ -302,7 +304,7 @@ c.id = n; var d = ce("span"); return d.innerHTML = n, c.appendChild(d), c.onclick = function(e) { - s(c.id.toLowerCase()) ? t.loadUrl(c.id) : r(c.id.toLowerCase()) && a(c.id) + s(c.id.toLowerCase()) ? t.loadUrl(c.id) : r(c.id.toLowerCase()) ? a(c.id) : z(c.id) ? f.removeChild(f.childNodes[0]) && m(f, c.id.toLowerCase()) : () }, c.oncontextmenu = function(e) { e.preventDefault(), e.stopPropagation(), o(e, c.id, !0) }, c @@ -314,6 +316,11 @@ e.appendChild(a); for (var i = n.length, o = 0; i > o; o++) "file" === n[o].type && a.appendChild(c(t, n[o].name, n[o].size)) } + + function z(e) { + if (e.indexOf('.') == -1) return !0 + else return !1 + } function s(e) { var t = /(?:.([^.]+))?$/.exec(e)[1]; diff --git a/src/edit.htm.gz.h b/src/edit.htm.gz.h index 863993877..634c6824d 100644 --- a/src/edit.htm.gz.h +++ b/src/edit.htm.gz.h @@ -1,226 +1,229 @@ -//File: edit.htm.gz, Size: 4408 -#define edit_htm_gz_len 4408 +//File: edit.htm.gz, Size: 4469 +#define edit_htm_gz_len 4469 const uint8_t edit_htm_gz[] PROGMEM = { -0x1F,0x8B,0x08,0x08,0x1B,0x89,0xCE,0x5E,0x02,0x00,0x65,0x64,0x69,0x74,0x2E,0x68,0x74,0x6D,0x00,0xB5, -0x1A,0x0B,0x5B,0xDB,0x36,0xF0,0xAF,0x18,0x6F,0x63,0xF6,0xE2,0x38,0x0E,0xA5,0xAC,0x73,0x30,0x2C,0x50, -0x56,0xFA,0x02,0x4A,0x42,0x3B,0xCA,0xD8,0x3E,0xC5,0x56,0x62,0x15,0x5B,0xF6,0x2C,0x99,0x40,0xB3,0xFC, -0xF7,0x9D,0x24,0x3F,0x43,0xE8,0x1E,0xDF,0xD6,0x6E,0x8D,0xA4,0xD3,0x9D,0xEE,0x4E,0xF7,0x54,0xB2,0xBB, -0xF1,0xFC,0xF4,0x70,0x7C,0x79,0x76,0xA4,0x85,0x3C,0x8E,0xF6,0x76,0xC5,0xBF,0x5A,0x84,0xE8,0xCC,0xD3, -0x31,0xD5,0xF7,0x76,0x63,0xCC,0x11,0x80,0x78,0xDA,0xC5,0xBF,0xE7,0xE4,0xD6,0xD3,0x0F,0x13,0xCA,0x31, -0xE5,0x5D,0x7E,0x9F,0x62,0x5D,0xF3,0xD5,0xCC,0xD3,0x39,0xBE,0xE3,0x3D,0x81,0x3C,0xD0,0xFC,0x10,0x65, -0x0C,0x73,0x2F,0xE7,0xD3,0xEE,0x33,0x20,0xC1,0x09,0x8F,0xF0,0xDE,0xD1,0xE8,0x4C,0x3B,0x0A,0x08,0x4F, -0xB2,0xDD,0x9E,0x5A,0xD9,0x8D,0x08,0xBD,0xD1,0x32,0x1C,0x79,0x3A,0x4A,0xD3,0x08,0x77,0x79,0x92,0xFB, -0x61,0x97,0x00,0x4D,0x5D,0x0B,0x33,0x3C,0xF5,0xF4,0x1E,0xF2,0xB1,0x0D,0x0B,0xBA,0x26,0x8E,0xF3,0x74, -0x12,0xA3,0x19,0xEE,0xDD,0xA9,0x3D,0x4D,0x02,0x2C,0x4C,0x32,0xEE,0xE7,0x5C,0xFB,0x57,0xD8,0xFF,0x00, -0x89,0xF1,0xFB,0x08,0x2B,0x90,0x92,0xD9,0x67,0x4C,0xD7,0x62,0x1C,0x10,0x04,0x5C,0xF8,0x19,0x16,0x5A, -0x8B,0xD0,0x04,0x47,0x8B,0x69,0x02,0x6A,0x62,0xE4,0x33,0x76,0xFB,0x5B,0xE9,0xDD,0x40,0x4E,0xA7,0x28, -0x26,0xD1,0xBD,0xCB,0x10,0x65,0x5D,0x86,0x33,0x32,0x5D,0xDA,0x7E,0xBC,0xF8,0xDC,0x25,0x34,0xC0,0x77, -0xEE,0x13,0xC7,0x19,0xA4,0x09,0x23,0x9C,0x24,0xD4,0x45,0x13,0x96,0x44,0x39,0xC7,0x83,0x08,0x4F,0xB9, -0xFB,0x14,0x28,0x4C,0x92,0x2C,0xC0,0x99,0xDB,0x4F,0xEF,0x34,0x00,0x91,0x40,0xFB,0x6A,0x7B,0x7B,0x7B, -0x30,0x41,0xFE,0xCD,0x2C,0x4B,0x72,0x1A,0x74,0xFD,0x24,0x4A,0x32,0xF7,0xAB,0xE9,0x53,0xF1,0x77,0x10, -0x10,0x96,0x46,0xE8,0xDE,0xA5,0x09,0xC5,0x80,0x7B,0xD7,0x65,0x21,0x0A,0x92,0xB9,0xEB,0x68,0x8E,0xD6, -0x77,0x80,0x48,0x36,0x9B,0x20,0xC3,0xB1,0xC4,0x5F,0x7B,0xDB,0x1C,0xFC,0x2D,0x7E,0xD5,0xF2,0x1C,0x93, -0x59,0xC8,0xDD,0xEF,0x1D,0x47,0xF0,0xAF,0xE5,0xD1,0x22,0x22,0x8C,0x77,0xA5,0x72,0xD4,0x79,0x3C,0x49, -0x5D,0x47,0xB2,0x0E,0x1F,0x31,0xCA,0x66,0x84,0xC2,0x20,0x45,0x41,0x40,0xE8,0xCC,0x55,0x68,0x11,0x59, -0x54,0xD2,0xC2,0x3D,0x20,0x4E,0x6E,0xF1,0x20,0x26,0xB4,0x3B,0x27,0x01,0x0F,0xDD,0x1D,0x07,0xB8,0xF0, -0xF3,0x8C,0x81,0x4C,0x69,0x42,0x28,0xC7,0x99,0x44,0x63,0x29,0xA2,0x0B,0x25,0xAA,0x50,0x40,0x25,0x27, -0xA1,0x70,0xA3,0xB8,0x3B,0x89,0x12,0xFF,0xA6,0x3A,0x69,0x27,0xBD,0x2B,0xCE,0x72,0xC3,0xE4,0x16,0x67, -0x8B,0x5A,0x5D,0x12,0xBB,0x05,0x6C,0x91,0xC6,0x18,0x2F,0x6D,0x7E,0x9B,0x03,0xD4,0x92,0x9F,0x20,0x65, -0x41,0xB5,0x29,0x52,0x5B,0xF0,0x02,0x85,0xD0,0x34,0xE7,0x8B,0x87,0x57,0x99,0xA4,0xC8,0x27,0xFC,0xDE, -0x75,0xE4,0x36,0x69,0x21,0xEE,0xB6,0xE3,0x68,0x42,0xE1,0xDA,0x7B,0x9C,0x05,0x88,0x22,0x6B,0x98,0x11, -0x14,0x59,0xA3,0x5A,0xE5,0xDD,0x38,0xF9,0xDC,0xCD,0x61,0x0C,0xF3,0x08,0xFB,0x5C,0x69,0x18,0x2E,0x61, -0x72,0x43,0xF8,0x43,0xC0,0x83,0x85,0x86,0xAE,0xA4,0x86,0x42,0x75,0x7B,0x7D,0xD0,0x8D,0xE4,0x43,0x89, -0xAD,0x24,0xEA,0x4E,0x12,0xCE,0x93,0x58,0xDA,0x5B,0x25,0xAD,0x26,0x4D,0xE6,0xD9,0x83,0xEB,0x58,0xAF, -0xFA,0x06,0xF9,0x01,0x28,0x95,0x13,0x1F,0x45,0x5D,0x14,0x91,0x19,0x75,0x63,0x12,0x04,0x11,0x6E,0x98, -0xAC,0x9B,0x67,0x91,0x11,0x20,0x8E,0x5C,0xE5,0x67,0x29,0x9D,0x01,0x94,0xE1,0x9D,0x6D,0x8B,0xBC,0x3F, -0x38,0x3D,0x9F,0x3B,0xAF,0x5F,0xCC,0x92,0x21,0xFC,0x39,0x19,0x5D,0x84,0x47,0x17,0x33,0x18,0x1D,0x88, -0xE9,0xF0,0xDD,0xE1,0xF0,0x1D,0x7C,0x1C,0xF6,0x3B,0x9F,0xA6,0xBF,0x0F,0xC5,0xF2,0x8B,0xE0,0x60,0x7C, -0x71,0x34,0x1C,0xBE,0xEE,0xBD,0x3C,0x99,0x7F,0x78,0xBD,0x23,0xC0,0x07,0x91,0x73,0xFE,0x3E,0x74,0x2E, -0xB6,0x7E,0x88,0x83,0xE3,0x20,0xF4,0xE3,0x8B,0xE1,0xBB,0x0F,0xE7,0xB7,0x97,0xF1,0xC5,0x6C,0xF4,0xA1, -0x1F,0x7E,0xDC,0x7A,0x3F,0xFA,0xF8,0xE1,0xA7,0x1B,0xFC,0xF3,0xF1,0xAB,0x8F,0xE3,0x39,0x20,0x3C,0x4F, -0x46,0x17,0xE7,0x07,0xEF,0x0F,0x66,0x1F,0x0F,0xFC,0xA3,0xBB,0x49,0x74,0x72,0xF0,0x62,0x38,0x19,0x6E, -0xF9,0x18,0xCF,0xC6,0xE7,0x07,0xF9,0xCB,0xD7,0xA7,0x33,0x42,0xC2,0xD1,0xC7,0x93,0xB1,0x7F,0xF8,0xF4, -0xCD,0xC5,0xF1,0x90,0x84,0x27,0xAF,0xCE,0x9D,0x9B,0x17,0xAF,0x0F,0x9F,0xFB,0x97,0xAF,0x2E,0x77,0x9E, -0x3F,0xE9,0x7D,0xFF,0xFD,0xDB,0xE0,0x94,0xD0,0xF1,0xED,0xE7,0xE1,0xEC,0x70,0xFE,0xEC,0x9E,0x8D,0xC3, -0x97,0xB7,0xB4,0xF7,0x3E,0xF9,0xF4,0xF2,0xFE,0x2D,0xFC,0x7F,0x76,0xD6,0x99,0x8C,0xFA,0xEC,0xE2,0xDD, -0xCB,0xF7,0x5B,0xEC,0x87,0xA7,0xE9,0xC1,0xF3,0xE7,0xB7,0xF1,0xE4,0xAC,0x17,0x07,0x37,0x53,0xFE,0xEC, -0x09,0x4F,0x2F,0x67,0xF9,0xC7,0xDF,0x9F,0xBE,0x0A,0x7B,0xA7,0x18,0x5D,0x86,0x9D,0xFB,0xCF,0xF7,0xCF, -0xC2,0xF1,0xF1,0xED,0x49,0x84,0xEE,0x4E,0x4E,0xFC,0xCF,0x71,0x27,0x42,0x3F,0x9C,0x8E,0x23,0x94,0xF5, -0x2F,0x82,0x61,0xAF,0x73,0xB8,0x35,0xDC,0xE6,0xD9,0xF9,0x21,0x7D,0xFE,0xE4,0xD3,0xE8,0xD9,0xC1,0x41, -0x3F,0x99,0xFC,0xBE,0xF5,0xE2,0x66,0xE7,0xC5,0xC5,0xCE,0xBB,0xC9,0xBB,0xE1,0x68,0xFB,0xE0,0x02,0x5D, -0x8E,0xDE,0x0D,0xA7,0xDB,0x93,0x30,0x7C,0xFD,0x7A,0xFC,0x53,0x30,0xFC,0x9C,0x0D,0x4F,0xE7,0xC3,0xBB, -0xA3,0x8B,0xE1,0x71,0xE7,0xF5,0xD1,0x5B,0xA7,0x3F,0xBA,0x7C,0x32,0x7B,0xBB,0x33,0x3F,0x60,0x47,0xC3, -0x77,0x07,0xCE,0xEC,0x55,0x27,0x46,0x1F,0x93,0xC3,0x27,0xB3,0x97,0x3B,0xE4,0xEC,0x12,0x0D,0x5F,0x1E, -0xBC,0x62,0xE4,0x3C,0x3E,0xBE,0x70,0x86,0xC3,0x37,0xA7,0xF8,0xA7,0xC3,0x27,0xE8,0xF5,0x96,0xFF,0x01, -0xF4,0x7F,0xF1,0x33,0xFE,0xBE,0x33,0x9C,0x9F,0x3A,0x91,0xFF,0x03,0x1E,0x1F,0x5F,0x8E,0xE5,0xED,0x1C, -0x45,0x3F,0x8D,0x6F,0x46,0xF9,0xBB,0xF8,0xF0,0xD0,0xD4,0x68,0xD2,0xCD,0x70,0x8A,0x11,0x6F,0xC6,0xAA, -0xCA,0x39,0xC0,0xB6,0x6A,0x2B,0x2C,0x9C,0x54,0x44,0xD6,0x6E,0x80,0xFD,0x24,0x43,0x72,0x0F,0x20,0xE0, -0x4C,0x98,0xD8,0xF2,0x47,0x19,0x6A,0x35,0x15,0x69,0x35,0x44,0x03,0xCD,0x28,0x1D,0x21,0x26,0x14,0x70, -0x6E,0x89,0x8F,0xBB,0x29,0xB9,0xC3,0x51,0x57,0x22,0xBB,0x8E,0xB9,0x90,0xCE,0x56,0x6E,0x43,0x94,0xC4, -0x8A,0x6A,0xB9,0x10,0x7C,0x42,0xBE,0x48,0x69,0xE0,0x32,0x31,0x7C,0x16,0xBE,0x93,0x64,0xDD,0x49,0x3E, -0x9B,0x92,0x3B,0xF0,0xE6,0x29,0xA1,0x84,0x63,0xAD,0xCF,0x96,0x3F,0x96,0x64,0x6E,0xF0,0xFD,0x34,0x43, -0x31,0x66,0xDA,0xDF,0x24,0xB3,0x98,0x66,0x49,0xBC,0xA8,0x23,0x20,0x4F,0x1A,0x93,0xE5,0xF2,0xAB,0x3C, -0x8D,0x12,0x04,0x62,0xAE,0x09,0x1B,0x2A,0x98,0x66,0xC2,0xAD,0xAA,0xA0,0x5A,0xBA,0xD9,0x16,0xB8,0x65, -0xCB,0xAD,0xB7,0xB6,0x6B,0xD7,0xED,0xCA,0xBD,0x22,0xD8,0x37,0x55,0xDF,0x88,0x07,0x8D,0x58,0xF7,0x15, -0x07,0x95,0xAE,0x3F,0x5C,0x1D,0xA2,0x22,0x43,0xCD,0x80,0x8A,0xD2,0xFD,0x1D,0xA7,0x11,0x2A,0x60,0xDF, -0xF2,0x2B,0x2C,0xD3,0xBC,0xF5,0x55,0x9A,0xC1,0x6D,0xE0,0xF9,0x17,0x68,0x56,0x32,0xB5,0x69,0x03,0xCD, -0x2A,0xDD,0x29,0x11,0xEA,0x9C,0x27,0x79,0xAD,0x48,0x3F,0x94,0x0A,0xC0,0x15,0x37,0x4F,0x05,0x37,0x5F, -0xD4,0xEA,0x93,0x9D,0x6F,0x0A,0x1E,0xB6,0x9D,0x6F,0x96,0xB6,0xDA,0x5B,0xE5,0xE3,0xBE,0x03,0x7F,0xCA, -0xB4,0xFB,0xAC,0x66,0x61,0xF2,0x54,0xFC,0x2D,0x19,0x04,0x3A,0x4D,0xE0,0x93,0xED,0x1F,0x9E,0x05,0x93, -0x12,0xA8,0x04,0x7B,0x1C,0x9E,0xA1,0x80,0xE4,0xCC,0x7D,0xEA,0x7C,0xA3,0xF4,0x09,0xD7,0x07,0xB2,0x97, -0x97,0xAB,0x26,0xB5,0xC5,0xB2,0x94,0x50,0x6D,0x8B,0x69,0xE2,0xBE,0x51,0x56,0x19,0x66,0x33,0xD5,0x83, -0x8B,0xD4,0xA6,0x29,0xF6,0x2F,0x9C,0x6F,0x16,0x3C,0x43,0x94,0x4D,0x93,0x2C,0x76,0xB3,0x84,0x23,0x8E, -0x0D,0xC7,0x5C,0xF6,0x9D,0x75,0x80,0x27,0x3B,0x4E,0x80,0x67,0xE6,0x72,0xB9,0xDB,0x93,0x49,0x0D,0x2A, -0x1E,0x3F,0x23,0x29,0xDF,0x9B,0xE6,0xD4,0x17,0x3C,0x68,0x33,0x6C,0x60,0x73,0x91,0x61,0x9E,0x67,0x54, -0x0B,0x12,0x3F,0x17,0xC6,0x6E,0xCF,0x30,0x3F,0x52,0x76,0x7F,0x70,0xFF,0x32,0x80,0x1D,0xCB,0x0A,0xC1, -0x5F,0x8B,0x00,0x0E,0x0C,0xE7,0x15,0x38,0xAD,0xFD,0x90,0x60,0x80,0xC8,0x6B,0x7C,0x6F,0x60,0x8B,0x57, -0x88,0xD8,0x16,0xEB,0x86,0x51,0x6E,0x03,0x20,0x35,0x17,0xB7,0xA0,0x05,0xE4,0xE1,0x2B,0x7E,0x6D,0x11, -0x8F,0xC2,0xC7,0xA0,0xD8,0x4E,0xF6,0xD0,0x7E,0xB7,0xEF,0xA2,0x3D,0xB2,0xDF,0x07,0xFF,0x32,0x1B,0xF4, -0xD5,0xC9,0x3F,0x91,0x08,0x5F,0x14,0x2E,0x27,0x0E,0xAA,0xA9,0xF5,0x0C,0x72,0x16,0x82,0x22,0xCD,0xEF, -0x8C,0xD3,0x91,0x66,0x5C,0x7D,0xDF,0xFD,0xE1,0xFA,0x8F,0xFE,0x95,0xD3,0xED,0x5F,0x9B,0xBF,0x99,0x3D, -0x62,0x73,0xCC,0xB8,0x41,0xD1,0x2D,0x99,0x21,0xB0,0x73,0x5B,0xE4,0xDB,0xE1,0x0C,0xA4,0x30,0x07,0xD5, -0x19,0x44,0xB1,0xB7,0xE5,0x38,0x1B,0x1E,0xDE,0x47,0x11,0x06,0xD6,0xF5,0xA3,0xF3,0xF3,0xD3,0xF3,0x2B, -0xBD,0x83,0x3B,0xFA,0xB5,0xAB,0xE9,0x1D,0x6A,0xBA,0xDC,0x86,0xA2,0x33,0xC3,0x2C,0x3C,0x43,0x3C,0x34, -0x02,0xFB,0x16,0x45,0x39,0xE8,0x42,0x30,0x92,0x78,0xA0,0x38,0x7D,0x92,0x83,0xFD,0x50,0xDD,0x1C,0x24, -0x36,0xA1,0x14,0x67,0xC7,0xE3,0xB7,0x6F,0x3C,0xFD,0x5C,0x21,0x69,0x6F,0x08,0xE3,0xBA,0x25,0x6F,0xC4, -0x46,0x69,0x8A,0x69,0x70,0x18,0x92,0x28,0x30,0x12,0x73,0x20,0x48,0xF8,0x92,0x84,0x2C,0x46,0x80,0x82, -0x6F,0xAB,0xB2,0x75,0x0A,0x92,0xEB,0x96,0x6F,0xC7,0x79,0xC4,0x49,0x1A,0x61,0x6F,0xA3,0x0F,0x33,0x8A, -0x62,0x80,0x89,0x54,0x2C,0x60,0x24,0xF0,0x74,0x15,0x90,0x54,0x18,0x5B,0x7B,0x8A,0xAF,0x4E,0x09,0x5A, -0xA7,0x04,0x4D,0xDC,0x14,0xA4,0xD2,0xAD,0xC0,0xAE,0xEB,0x65,0x98,0x15,0x47,0x95,0xB0,0x00,0x4F,0x11, -0x70,0xF2,0x5E,0x48,0x0E,0xE5,0xF7,0xBA,0x83,0x02,0x75,0x10,0x6B,0x6B,0x84,0x35,0x35,0xA2,0xAE,0x72, -0x1D,0x32,0x53,0xC8,0x59,0x1B,0x39,0x6B,0x22,0x1F,0x4A,0x8B,0x58,0x87,0x9C,0x29,0xE4,0xA8,0x25,0x62, -0x24,0x45,0x54,0x51,0xAE,0x2B,0xB4,0x09,0x02,0x01,0x76,0xD4,0x14,0x13,0x66,0xE0,0x94,0x68,0x12,0xE1, -0xC0,0xDB,0x70,0x60,0x26,0x0A,0x6B,0x6F,0xCB,0x59,0x73,0x46,0xA4,0xCE,0xC8,0x5B,0x67,0xE4,0xF2,0x0C, -0x92,0x82,0x12,0x21,0x77,0xE8,0x56,0x2E,0xB5,0xD6,0x5E,0x51,0xC7,0xF9,0x21,0xF6,0x6F,0x26,0x89,0x5C, -0x91,0x63,0x71,0xE2,0x06,0x92,0x34,0x53,0x49,0x53,0xB6,0x23,0x40,0x33,0xB5,0xC1,0xD3,0x3D,0x41,0xD9, -0x4A,0x9B,0xE2,0x6B,0xC3,0x88,0xDB,0xBA,0x44,0x88,0xDB,0x5A,0x8A,0x5B,0xDB,0x46,0xE8,0x16,0x6B,0xEB, -0xB4,0x14,0x9B,0x6B,0x16,0xD3,0x75,0x8B,0xB9,0x69,0x65,0x76,0x42,0xFD,0x88,0xF8,0x37,0x5E,0xED,0xCA, -0xE6,0xC2,0x68,0x4E,0x04,0x27,0xDC,0xA3,0x78,0xAE,0xFD,0x04,0xA1,0xE9,0x39,0xE2,0x68,0xC0,0x0B,0x32, -0x46,0x61,0x37,0x18,0x08,0x41,0x47,0x8A,0x19,0x67,0x36,0x0A,0x60,0xF9,0xEC,0x62,0xAC,0x5B,0x7A,0x4F, -0xDC,0x8A,0x0E,0xDE,0x4C,0xCC,0xA5,0x59,0xF9,0x93,0x45,0x65,0x64,0xBF,0xC8,0xA2,0x7A,0x09,0x06,0xA5, -0xC5,0x2D,0xAD,0x78,0x2D,0x4F,0x64,0x6A,0x54,0x2A,0x2D,0x99,0x12,0xDD,0xA1,0x38,0xC3,0x28,0xEE,0x5F, -0x37,0x21,0xF4,0x29,0xE3,0x35,0x4C,0x0B,0xB5,0x99,0x46,0x15,0xD3,0x19,0x9A,0x97,0x46,0xA2,0xCE,0x1F, -0x28,0x17,0x77,0x20,0x03,0x53,0xC6,0x35,0xEC,0x6D,0x3B,0x3F,0xEC,0x0C,0xE0,0x7E,0x0C,0xE5,0xB8,0x00, -0xD8,0xE5,0x36,0x98,0xD6,0x8C,0x87,0x03,0xBF,0xE3,0x15,0x5A,0x09,0x3C,0x6E,0xB3,0x7C,0xC2,0x78,0x06, -0xF9,0xCD,0xF0,0x2D,0xBF,0x83,0xCD,0xF6,0x31,0x7A,0x27,0xB1,0x02,0xD3,0x4A,0x3A,0x9D,0xE5,0x8A,0x82, -0x4E,0x47,0x0D,0x0D,0x21,0xA1,0x21,0x1C,0x31,0xAC,0x51,0x1B,0xDF,0x61,0xFF,0x30,0x89,0x63,0x24,0x48, -0x30,0xB8,0xE4,0x62,0xA2,0x9B,0x4B,0x2B,0x59,0xAB,0x99,0x47,0xC2,0x96,0xC5,0x1E,0xD3,0x23,0x84,0x41, -0xCF,0xB7,0x85,0xAF,0xB0,0x42,0xA8,0x2F,0xDF,0x72,0x19,0x88,0x14,0xCA,0x95,0x73,0x6D,0x55,0x17,0xB7, -0x56,0xAA,0xFA,0xDE,0xA5,0xD5,0xB5,0xE2,0x8F,0x59,0xDF,0xB4,0x80,0xB5,0xE3,0x5A,0x0D,0xD5,0x97,0x4B, -0xCB,0x17,0xFC,0x87,0x88,0xCE,0xF0,0xDF,0x17,0xA0,0xE6,0x51,0xBA,0xA8,0x45,0x21,0x81,0xEC,0xBB,0xBF, -0xD8,0xC6,0xD5,0xAF,0xF6,0x75,0xC7,0x34,0xF7,0xBF,0xEE,0x49,0x0D,0x1B,0xDC,0xBC,0xEA,0x5F,0x5B,0x08, -0xC0,0xF6,0x77,0xE6,0x2F,0xB6,0x04,0xB7,0x60,0x83,0xDB,0x84,0x04,0x9A,0x38,0x49,0x78,0x76,0x32,0xD5, -0xD0,0xE6,0xA6,0x01,0x26,0xD7,0x32,0xD6,0x0E,0xEF,0xE8,0x36,0xE4,0x8E,0xE5,0x72,0x35,0xA3,0x8D,0x33, -0x8C,0x55,0xCA,0xAC,0x00,0x92,0x7B,0x90,0x79,0x35,0x58,0x55,0x52,0x63,0xAB,0x86,0xC2,0xA2,0x4C,0xF9, -0x76,0x51,0x4D,0x78,0xBA,0x28,0x27,0x20,0xAC,0xAC,0x2E,0xCB,0x36,0x0F,0xD6,0x1B,0xC1,0xE1,0xDB,0x5D, -0x12,0xCF,0x34,0x96,0xF9,0x9E,0xBA,0x8A,0x7D,0xF1,0x8F,0xF7,0xAD,0x48,0x75,0x9B,0xBF,0xF9,0x13,0x4F, -0xEF,0xC0,0xFD,0x62,0x9B,0x26,0x73,0xC3,0xEC,0x7C,0xAB,0x6B,0x92,0xA2,0xA7,0xC7,0xE8,0xAE,0x68,0xF6, -0x45,0x35,0x32,0xD0,0x60,0x5E,0x75,0xA7,0x6A,0x41,0xB5,0xD9,0x28,0xE7,0xC9,0x40,0x2B,0xAB,0x1C,0xD5, -0x66,0xEA,0x5A,0x6F,0xEF,0xDB,0x5A,0x07,0x08,0x44,0x47,0xEA,0x4E,0x88,0x0C,0x62,0xB9,0x08,0x79,0xB8, -0x15,0x7D,0x48,0xE1,0x76,0x2A,0x2A,0x12,0x80,0x93,0x95,0xB4,0x69,0x05,0x06,0x32,0xF7,0x8D,0x56,0xB2, -0xDD,0x15,0x8D,0xC9,0xDE,0x99,0xAA,0x38,0x77,0x7B,0x72,0xA6,0xAF,0x73,0x0C,0xD0,0x3C,0x05,0x74,0xAB, -0xAA,0x71,0x26,0x49,0x70,0xDF,0xA8,0x8C,0xD8,0xC1,0xFD,0x61,0x84,0x18,0x3B,0x41,0x31,0x9C,0xEF,0xC7, -0xBA,0x59,0x98,0xD2,0x9E,0xB3,0xB9,0xD9,0x46,0xCA,0x70,0x0C,0x8D,0x90,0xE2,0x0A,0x43,0x28,0x73,0x7D, -0x20,0xBC,0xB9,0xB9,0x8E,0x31,0xF1,0xA8,0xF6,0x25,0xAE,0x28,0xB8,0x6B,0x19,0xFE,0xFE,0x27,0xEE,0x54, -0x82,0x7D,0x4C,0xAB,0x19,0xF8,0xEC,0x43,0xB6,0x9F,0x27,0x73,0x2A,0xB8,0xAA,0x58,0xCF,0xD6,0x28,0xB4, -0xCE,0x0B,0x95,0x25,0x07,0x05,0x5E,0x77,0x9A,0x29,0x43,0x6E,0x18,0x5D,0x09,0x03,0x73,0xC3,0x4B,0xF3, -0xFF,0x11,0x56,0xD5,0x03,0x8F,0xC9,0x1A,0x99,0x56,0xB4,0x46,0x56,0x1C,0x61,0x8E,0x2B,0x49,0xA3,0xB5, -0x92,0xB2,0xFF,0x87,0xDF,0xDA,0x43,0x88,0x2A,0x73,0x9B,0x3E,0x12,0x90,0x5B,0x1D,0x72,0x85,0xD7,0xA6, -0xC0,0xFC,0x2C,0x89,0xA2,0x71,0x92,0xEE,0x3F,0xB2,0xEE,0x56,0xEB,0xC5,0xA0,0x64,0xB3,0xDE,0x62,0xF9, -0x6B,0x89,0xBE,0xC1,0x53,0xBE,0xFF,0x18,0xE0,0x71,0xB2,0xF5,0x1E,0x2B,0xF0,0xB0,0x0D,0xCA,0x83,0xD5, -0x9F,0x3B,0xBE,0xC5,0xAA,0xD9,0x65,0x27,0x81,0xBB,0xF0,0x4B,0x25,0x79,0x42,0x49,0x16,0x59,0x1B,0xBA, -0xEA,0x75,0xD1,0x5B,0x7A,0x41,0x47,0x4F,0xEF,0xEA,0x35,0x9E,0xA4,0x1E,0x53,0x4B,0xC8,0x20,0x16,0x5F, -0xB9,0x94,0x75,0x01,0x25,0xF3,0x88,0x9D,0x4C,0xA7,0x0C,0xF3,0x0F,0x22,0x98,0x59,0x51,0x35,0x3F,0x96, -0xC1,0x6C,0x00,0x53,0x1A,0x27,0x39,0xC3,0x49,0xCE,0xDB,0x65,0x4F,0x25,0xCC,0x6E,0xF0,0xC7,0x1F,0xD5, -0x64,0x2F,0xE8,0x64,0xF5,0xF4,0x72,0x97,0x35,0x26,0x7B,0xAC,0x13,0x41,0x28,0xF8,0x8F,0x2D,0x85,0x34, -0x2D,0x25,0x11,0xB1,0xD4,0x4A,0x94,0xA5,0xB0,0xDA,0xD6,0x99,0x28,0x4A,0x51,0xC3,0xDB,0x85,0x41,0xEB, -0x66,0xD9,0x73,0x35,0xBD,0x1C,0x59,0x6C,0x35,0x08,0xAC,0x2F,0x0E,0x7C,0x43,0x50,0x05,0xAD,0xBF,0x49, -0xE6,0x38,0x3B,0x44,0x0C,0x1B,0x90,0x33,0xAB,0x88,0x25,0xA1,0xA6,0x1B,0xAC,0xD9,0x05,0x4A,0xA0,0x0A, -0x5C,0x14,0x1E,0x09,0x15,0xA5,0x37,0xC8,0x97,0xB7,0x4E,0xC0,0xB6,0x78,0x2D,0x00,0xA9,0x9F,0xAB,0x4E, -0x03,0xEA,0x34,0x6C,0x33,0xB8,0xE6,0xB3,0x2C,0x49,0xD1,0x4C,0x76,0xD6,0xB0,0x26,0xDC,0xA3,0xA4,0xD6, -0x48,0xAD,0x55,0x3D,0x2A,0xD3,0xFA,0xC3,0xAC,0x8E,0x65,0xE6,0x86,0x0A,0x61,0x35,0x79,0x73,0x93,0xCD, -0x09,0xF7,0x43,0xE1,0xDB,0x3E,0x30,0xAC,0x73,0x68,0x0B,0x5C,0x39,0x0A,0x79,0x5C,0x8F,0xA2,0x62,0xF8, -0x89,0x15,0x03,0x9F,0x95,0xA3,0xBB,0x06,0x30,0xA1,0x25,0x38,0xA1,0xD3,0x62,0x48,0x28,0x29,0xE9,0x94, -0xC0,0xF2,0x33,0x4D,0x8B,0x51,0x1A,0x96,0xA3,0x10,0xDF,0x55,0x78,0x49,0x09,0x0D,0xB0,0xEE,0xAA,0xEB, -0xDB,0x70,0x96,0xC5,0xA0,0x5F,0x8B,0x1F,0xFC,0x77,0xE2,0xA7,0x74,0x56,0x0A,0x93,0x96,0xA3,0x19,0x29, -0x45,0x99,0xC4,0xE9,0x17,0x19,0x61,0xFF,0xB6,0x2F,0x78,0x7E,0xF4,0xE6,0x68,0x7C,0xD4,0x2C,0x11,0x9B, -0x4F,0x08,0xFC,0xAF,0x7A,0x74,0x6E,0xBA,0x46,0xDA,0xF4,0x14,0x98,0xF9,0xE2,0xF3,0x24,0x09,0x64,0xD1, -0x07,0x01,0xDF,0x48,0x81,0xBA,0x6E,0x9A,0xAD,0x57,0x86,0xAC,0xF5,0x7A,0x51,0x07,0xFA,0xE2,0x59,0x00, -0xF4,0xB4,0xB9,0xD9,0x60,0x44,0xAE,0xD7,0x2F,0x1F,0xD4,0xD2,0x55,0x9D,0x26,0x9D,0x0D,0x3D,0x56,0xD0, -0x20,0xB3,0x6A,0x19,0x88,0x47,0x0B,0x47,0xB7,0x44,0xF7,0x40,0xF6,0x7C,0x68,0x1B,0x3A,0xA6,0xEA,0xF6, -0x3D,0xCF,0xA3,0x57,0xFE,0xB5,0xEC,0x18,0x37,0x37,0x51,0xBB,0xE8,0x31,0x1C,0x4B,0x02,0xC5,0x81,0x72, -0x24,0x7B,0x55,0x90,0x05,0xD8,0x72,0xAC,0x57,0xA3,0xD3,0x13,0x3B,0x45,0x19,0x78,0x1C,0x35,0x9B,0x41, -0x22,0x52,0x02,0xB6,0xB5,0xFD,0xE2,0xA8,0x51,0x8D,0xCB,0x2F,0x85,0x5C,0xBE,0xB4,0x32,0x43,0x90,0x53, -0x4D,0xAE,0xC8,0xE1,0xC5,0xEB,0x1D,0xA4,0x9E,0xB4,0x4C,0x43,0x75,0x14,0x49,0x9B,0x41,0x9C,0xDF,0xE6, -0xFA,0xFA,0xDE,0x92,0x87,0x84,0x35,0xBB,0x90,0x96,0xCB,0xFF,0xCD,0x1B,0x5B,0x96,0x23,0x45,0x6E,0xB5, -0xA0,0x56,0x5F,0x57,0xAA,0xCB,0x91,0x0D,0xD3,0xA2,0x8E,0x90,0xB5,0x39,0xEA,0x90,0x59,0x08,0xD5,0x2D, -0xFA,0x4F,0x3D,0x84,0x96,0x1E,0x42,0x1F,0x06,0x08,0x7C,0xD7,0xF2,0xF6,0xEA,0x94,0xC1,0x04,0x38,0xBB, -0x19,0x54,0x51,0x04,0x20,0x32,0x86,0xB4,0x00,0x9F,0x98,0x5C,0xFF,0x84,0x6E,0x91,0x7A,0xBC,0xAB,0xA1, -0xEB,0x43,0x85,0xDC,0xEE,0xFF,0x06,0xA3,0x6A,0x67,0x3B,0x10,0x31,0x18,0x3E,0x8C,0x27,0xBC,0x15,0x9E, -0xEA,0x98,0xD5,0x8C,0x4E,0xE0,0xAE,0x85,0x37,0x6B,0xBC,0xA1,0xDF,0x86,0xEB,0x81,0x41,0x3E,0xEA,0x7B, -0x8D,0x40,0xA4,0x30,0x9A,0xD6,0xB3,0xBE,0x5D,0x69,0x37,0x34,0xEB,0xD3,0xBF,0xF4,0x3F,0xBC,0xCF,0x6C, -0x56,0xB6,0xEE,0xE0,0xE6,0x8D,0x99,0xAE,0x8B,0x6C,0xE5,0x47,0x18,0x65,0x23,0xD1,0x25,0xAA,0x0C,0xB1, -0x54,0x17,0xE8,0x49,0xD7,0x35,0x40,0x63,0x3D,0xF9,0x4A,0x6C,0x83,0x1E,0x60,0x7F,0x05,0xA4,0x00,0xA4, -0x5E,0x02,0x24,0x1B,0x8B,0x08,0x16,0x11,0xF4,0x3B,0x09,0x4D,0x6E,0x10,0x69,0x6E,0x27,0x00,0x21,0xC5, -0x77,0xC9,0xD0,0xD6,0x59,0xC5,0x3D,0x48,0x42,0x35,0x44,0xDD,0xBE,0x59,0xBC,0x83,0xD5,0xAF,0x10,0xB8, -0x74,0x9B,0xC2,0x3E,0x36,0x24,0x1A,0x13,0xF5,0xC0,0x08,0x33,0x26,0xF9,0x16,0x72,0xBD,0x4D,0x02,0x10, -0x0B,0xD0,0x7A,0x31,0x8C,0xC4,0x41,0x20,0xA1,0x00,0x8C,0x43,0x1C,0x17,0x10,0x0E,0x43,0x01,0x42,0x02, -0xF4,0xB5,0x54,0xD5,0x48,0xD6,0x5D,0x84,0xCE,0xBC,0x7E,0xCF,0xB1,0x1E,0x92,0xBD,0x60,0x78,0x94,0x4C, -0xF9,0x18,0x4D,0x98,0xB1,0xE1,0x98,0x6B,0x76,0x00,0x68,0x04,0xD1,0xC4,0xD8,0x32,0xD7,0xA3,0x7F,0x48, -0xB2,0x1B,0x9C,0x15,0xC8,0xA2,0x60,0x82,0x7A,0x29,0x12,0x35,0xD3,0x10,0xB4,0x7E,0x8B,0xDF,0x10,0x8A, -0x6B,0xE0,0x28,0x4C,0xE6,0x67,0x19,0xA1,0xFC,0xAD,0x6C,0x0B,0x8D,0x8D,0xBE,0xBC,0x27,0xF5,0x5A,0x21, -0x23,0x50,0xF9,0x8C,0xB1,0x10,0xC1,0xCC,0x6D,0x3D,0x66,0x58,0x13,0xB8,0x2E,0x88,0xAD,0xEE,0x62,0x4E, -0xA8,0xAB,0x1F,0xF2,0x2C,0xEA,0x8E,0x74,0x2B,0x46,0x3E,0x4C,0xD4,0x1E,0x98,0x2F,0x2D,0xE1,0xB4,0x6E, -0x33,0x98,0x6C,0xD4,0x93,0xBA,0x7E,0x5E,0xFB,0xD2,0x53,0x3F,0x5C,0x08,0xE0,0x41,0x94,0x4C,0x0C,0xF1, -0x32,0xBD,0x10,0x0E,0xEF,0xD2,0xA5,0x29,0xB2,0xD3,0x97,0x1F,0x65,0x7C,0x88,0xBA,0xDC,0xC2,0x8D,0x37, -0xA5,0x8E,0xAE,0x8B,0xA7,0x1A,0xC0,0x43,0xC1,0x29,0x8D,0xEE,0x5D,0xC8,0x8A,0x7F,0x21,0x75,0x4E,0x83, -0xE4,0x4B,0x52,0x7F,0x5C,0x91,0xFA,0xE3,0x3A,0xA9,0x71,0xFB,0xB6,0x60,0x72,0x01,0x64,0xDF,0x22,0x8A, -0x66,0x38,0x83,0x05,0x71,0x08,0x5C,0xC0,0x3F,0xE3,0x2C,0xC3,0x5F,0xE6,0x6C,0x14,0x92,0x29,0x5F,0xE5, -0x4F,0xAD,0xFE,0x3B,0x2E,0x33,0xFC,0x08,0x97,0x65,0x7D,0x59,0xA5,0x8D,0xBF,0x7E,0x29,0x91,0x4E,0xED, -0xC1,0x15,0x36,0xDD,0xF5,0x5F,0xF8,0x5D,0x7D,0xE2,0x97,0xB3,0xA7,0xF8,0x70,0xF1,0xD2,0x0A,0x84,0x4D, -0xB4,0xAB,0xD2,0x84,0x1E,0x40,0x01,0xFF,0x06,0x44,0x30,0x94,0x39,0x62,0x6F,0xB1,0xB4,0xB8,0x67,0x80, -0x2A,0xA1,0x09,0x06,0xE1,0x7C,0x59,0xD6,0xDA,0x21,0x64,0x48,0x50,0x02,0x30,0x09,0x79,0xB6,0x77,0xB5, -0xBF,0x79,0xDD,0x81,0x04,0xE5,0xC1,0x87,0xE9,0xC1,0x60,0xF3,0xFA,0x3B,0xB3,0x37,0x23,0x8D,0x92,0x48, -0xA6,0x3A,0xD0,0xEB,0x15,0xBD,0xF6,0xD0,0x12,0x42,0x58,0x33,0x15,0x56,0x81,0xD5,0xC2,0xF2,0xD1,0x0B, -0x3E,0x22,0x44,0x67,0xF0,0x21,0x63,0x07,0xEC,0xA6,0x5E,0xE3,0x2D,0x4A,0xE7,0xF0,0xAF,0x0E,0x61,0x7B, -0x50,0xB0,0x15,0xE0,0x29,0xA1,0x58,0x46,0x2F,0x35,0xB4,0x0A,0x80,0x50,0x03,0xC9,0x24,0xA4,0x1C,0x5B, -0x62,0x2C,0xB2,0x1F,0x99,0x09,0x45,0x1A,0xFA,0x04,0x31,0x2C,0x12,0xBD,0xAE,0x12,0xF6,0x2A,0x78,0x2E, -0x03,0x49,0x63,0xC3,0x9A,0xAF,0x79,0xF4,0xBC,0x18,0xE9,0x20,0x25,0x6F,0x04,0x61,0x25,0x0E,0xC4,0x5B, -0x35,0x58,0x09,0xED,0x75,0x33,0xA2,0xC0,0xE6,0x12,0x5C,0x4C,0x09,0x10,0xE8,0x55,0x3A,0xFF,0xF9,0xED, -0x9B,0x63,0xCE,0xD3,0x73,0x75,0xA3,0x40,0xAB,0xBD,0x50,0x1B,0x9A,0xB9,0xE0,0xD9,0x7D,0x59,0x18,0x8A, -0x40,0xA1,0x42,0xDD,0xCF,0xA7,0x93,0x4F,0xD8,0x07,0x49,0xDE,0x32,0xC8,0xA1,0x5B,0xB6,0x40,0x1F,0x8F, -0xCF,0xEC,0x1D,0xDB,0x81,0x4A,0x05,0xEE,0xD3,0x0F,0x85,0xC5,0x2C,0xFF,0x11,0xF2,0x93,0x7F,0x86,0x4C, -0x20,0xDE,0x33,0x08,0xE8,0x25,0x7E,0x1B,0x37,0xCC,0x92,0xB9,0x44,0x3B,0xCA,0x32,0x61,0x0C,0xE3,0x90, -0x30,0x6D,0x02,0x8B,0x0C,0x67,0x5A,0x90,0x60,0xA6,0xD1,0x84,0x6B,0x2C,0x4F,0xD3,0x24,0xE3,0x2B,0xFA, -0xB0,0xF5,0xF2,0x9D,0xE8,0x5D,0x8E,0x73,0x1C,0x14,0xCB,0x38,0x6B,0xEA,0x45,0xD6,0x74,0xB0,0x0E,0xEE, -0x76,0x75,0x5D,0x54,0x78,0x39,0xA5,0x22,0xFF,0x6C,0xF4,0xD5,0x1C,0xA4,0x0B,0x81,0xAA,0x47,0xF3,0x28, -0x5A,0x0E,0x56,0x68,0x41,0xA3,0x97,0xF0,0x44,0x7E,0x2D,0xB2,0xF8,0xAD,0x70,0x2D,0x77,0xE5,0x21,0xB7, -0x4D,0xD5,0xB1,0x36,0x8C,0x0D,0xAC,0x11,0xCA,0x38,0xA2,0xBE,0xB8,0x46,0xA5,0x0B,0xB3,0xAC,0xEE,0xC4, -0xF6,0x81,0x88,0x0B,0xD2,0x70,0x1E,0x2D,0x29,0xA4,0x64,0xD4,0xD3,0x75,0x51,0xE8,0x61,0x51,0x2F,0xA3, -0x98,0x35,0xC8,0x56,0x99,0xC2,0xA4,0x5E,0x09,0x1E,0xC8,0xE7,0xF7,0xF6,0xFE,0x55,0x36,0xCA,0xEA,0x1E, -0x01,0x4C,0x2B,0xF7,0x99,0xB4,0xE3,0xE9,0xB2,0x42,0xD8,0x97,0x21,0x43,0x1A,0x70,0x8C,0x79,0x98,0x04, -0xFB,0xFA,0xBE,0xEE,0xEA,0xF0,0xDF,0xA6,0x6E,0xC1,0x2E,0x4C,0x7D,0x08,0x3B,0x17,0xE7,0x2F,0x21,0x94, -0xA6,0x09,0xC5,0x94,0x1B,0x08,0x32,0x8A,0xA7,0x77,0xD6,0x40,0x4A,0xF2,0x57,0xE8,0xDA,0x1C,0xB4,0x95, -0x8D,0xE7,0x2B,0xD7,0xD9,0xBA,0x0C,0x3B,0xA1,0x22,0xBA,0xDE,0x03,0xF3,0x1C,0x3F,0x78,0x3E,0xB7,0xE8, -0xC3,0x2E,0xC8,0x5C,0x6C,0x0B,0x9E,0x25,0xD6,0x08,0xB0,0x84,0xEB,0xD5,0x4A,0x7E,0xAC,0xB2,0xA3,0xB6, -0x8F,0xA2,0x48,0x7C,0xE5,0x0F,0xBC,0x8A,0xC3,0x72,0x66,0x09,0x22,0x0C,0x04,0x60,0x78,0x8C,0xEF,0xC0, -0xA5,0x65,0x79,0xA6,0x6C,0xA8,0x68,0x87,0x80,0x34,0x6F,0x98,0x91,0x69,0x55,0xB3,0xCD,0x4D,0x6E,0x97, -0x66,0x62,0x94,0x48,0x4C,0x24,0x1B,0xC3,0x14,0xAD,0x8E,0xD1,0x14,0x52,0xE4,0xEE,0x07,0xDA,0x36,0xDA, -0x6A,0x48,0x31,0x35,0x4A,0x18,0x70,0x96,0x67,0x11,0x64,0x08,0x51,0xBD,0xB4,0xB6,0x31,0x4C,0x03,0x38, -0xC0,0xFD,0x4B,0x64,0x89,0x4A,0x9B,0x56,0x31,0xE2,0x99,0xE2,0xBB,0x4D,0x8F,0x17,0xB7,0x72,0x8C,0x65, -0x98,0x6B,0xFF,0x46,0xD3,0x92,0xBF,0xAE,0x24,0x2A,0x21,0xF4,0xE0,0xBD,0x7D,0x3E,0xEF,0x82,0x59,0xC5, -0x5D,0x38,0x41,0x59,0x41,0xA0,0xAF,0xE1,0x50,0x75,0x7B,0x96,0x78,0x27,0x71,0x57,0x5C,0xB4,0xD6,0x9F, -0xB1,0xE2,0xA3,0x6D,0x3A,0x6D,0x3E,0x1B,0xB7,0xBD,0xBB,0xBD,0x02,0x42,0x13,0xF1,0xDD,0x3E,0xE4,0x38, -0x48,0x83,0xD5,0x69,0x65,0xE3,0xD5,0x8C,0x0B,0x76,0x9A,0xB3,0xD0,0x58,0x00,0xEB,0x2E,0xB7,0x94,0xAE, -0x5C,0x6C,0x29,0xBB,0x75,0xA9,0x55,0xDA,0x87,0x0B,0xA9,0xAB,0x15,0x3F,0xFE,0xF8,0x43,0xCE,0xEA,0xDB, -0x86,0xD9,0xCA,0x85,0x2F,0xD5,0xD3,0x6E,0x99,0x91,0x85,0xD1,0xAF,0xC6,0xAA,0xDD,0x9E,0xEA,0xA7,0xCA, -0x1F,0x45,0x68,0x24,0xF0,0x44,0x72,0xD7,0x8B,0x6F,0x3E,0x60,0x38,0x85,0xB8,0x64,0x43,0x03,0x56,0xFD, -0x0A,0x56,0x2F,0x7E,0x06,0xBB,0x8A,0xBB,0x57,0x75,0x84,0x9E,0x57,0xD5,0xF3,0x2A,0xEA,0xA8,0x0D,0xDE, -0x23,0x3F,0x95,0xD0,0x15,0x18,0x1A,0x66,0x35,0xB0,0xAB,0xB3,0xC5,0xB9,0x56,0xB1,0x88,0xD8,0x3D,0xF5, -0x45,0xD4,0xAC,0xA8,0x84,0xA0,0xFE,0x56,0x13,0xAD,0x76,0x9A,0xCB,0x9A,0x33,0xF1,0x2A,0xA8,0x25,0xC5, -0x13,0x7A,0xB3,0xC6,0x00,0xF6,0xA1,0x47,0x17,0xE2,0x96,0x2E,0xAA,0xC9,0x26,0xBD,0x9A,0x82,0x78,0xB0, -0xA1,0xDE,0x95,0xA7,0xEB,0x01,0xAA,0x24,0x58,0x5D,0x54,0x55,0xC5,0xEA,0x72,0xD9,0xE8,0x55,0xDF,0x16, -0x35,0x7E,0xE5,0x52,0xD3,0x20,0xF2,0x7B,0x00,0xB9,0xBF,0xFD,0xD5,0xC0,0xA3,0x68,0x0A,0x63,0xEF,0x4F, -0x7E,0xDB,0x4D,0x59,0xFA,0x2C,0x00,0x00 +0x1F,0x8B,0x08,0x08,0xC2,0xFA,0xD8,0x5E,0x02,0x00,0x65,0x64,0x69,0x74,0x2E,0x68,0x74,0x6D,0x00,0xB5, +0x1A,0x09,0x5B,0xDB,0x36,0xF4,0xAF,0x18,0x6F,0x63,0xF6,0xE2,0x38,0x0E,0x50,0xD6,0x39,0x18,0x16,0x8E, +0x8D,0x5E,0x40,0x49,0x68,0x47,0x19,0xDB,0xA7,0xD8,0x4A,0xAC,0x62,0x4B,0x9E,0x2D,0x13,0x68,0x9A,0xFF, +0xBE,0x27,0xC9,0x27,0x84,0xEE,0xF8,0xB6,0x76,0x6B,0x24,0x3D,0x3D,0xE9,0xDD,0x87,0x92,0x9D,0xB5,0xC3, +0xD3,0x83,0xF1,0xE5,0xD9,0x91,0x16,0xF2,0x38,0xDA,0xDD,0x11,0xFF,0x6A,0x11,0xA2,0x33,0x4F,0xC7,0x54, +0xDF,0xDD,0x89,0x31,0x47,0x00,0xE2,0x49,0x17,0xFF,0x91,0x93,0x5B,0x4F,0x3F,0x60,0x94,0x63,0xCA,0xBB, +0xFC,0x3E,0xC1,0xBA,0xE6,0xAB,0x99,0xA7,0x73,0x7C,0xC7,0x7B,0x02,0x79,0xA0,0xF9,0x21,0x4A,0x33,0xCC, +0xBD,0x9C,0x4F,0xBB,0xCF,0xE1,0x08,0x4E,0x78,0x84,0x77,0x8F,0x46,0x67,0xDA,0x51,0x40,0x38,0x4B,0x77, +0x7A,0x6A,0x65,0x27,0x22,0xF4,0x46,0x4B,0x71,0xE4,0xE9,0x28,0x49,0x22,0xDC,0xE5,0x2C,0xF7,0xC3,0x2E, +0x81,0x33,0x75,0x2D,0x4C,0xF1,0xD4,0xD3,0x7B,0xC8,0xC7,0x36,0x2C,0xE8,0x9A,0xB8,0xCE,0xD3,0x49,0x8C, +0x66,0xB8,0x77,0xA7,0xF6,0x34,0x0F,0xC8,0x42,0x96,0x72,0x3F,0xE7,0xDA,0xBF,0xC2,0xFE,0x07,0x48,0x19, +0xBF,0x8F,0xB0,0x02,0x29,0x9E,0xFD,0x2C,0xD3,0xB5,0x18,0x07,0x04,0x01,0x15,0x7E,0x8A,0x85,0xD4,0x22, +0x34,0xC1,0xD1,0x62,0xCA,0x40,0x4C,0x19,0xF9,0x84,0xDD,0xFE,0x46,0x72,0x37,0x90,0xD3,0x29,0x8A,0x49, +0x74,0xEF,0x66,0x88,0x66,0xDD,0x0C,0xA7,0x64,0xBA,0xB4,0xFD,0x78,0xF1,0xA9,0x4B,0x68,0x80,0xEF,0xDC, +0x4D,0xC7,0x19,0x24,0x2C,0x23,0x9C,0x30,0xEA,0xA2,0x49,0xC6,0xA2,0x9C,0xE3,0x41,0x84,0xA7,0xDC,0x7D, +0x06,0x27,0x4C,0x58,0x1A,0xE0,0xD4,0xED,0x27,0x77,0x1A,0x80,0x48,0xA0,0x7D,0xB5,0xB5,0xB5,0x35,0x98, +0x20,0xFF,0x66,0x96,0xB2,0x9C,0x06,0x5D,0x9F,0x45,0x2C,0x75,0xBF,0x9A,0x3E,0x13,0x7F,0x07,0x01,0xC9, +0x92,0x08,0xDD,0xBB,0x94,0x51,0x0C,0xB8,0x77,0xDD,0x2C,0x44,0x01,0x9B,0xBB,0x8E,0xE6,0x68,0x7D,0x07, +0x0E,0x49,0x67,0x13,0x64,0x38,0x96,0xF8,0x6B,0x6F,0x99,0x83,0xBF,0x45,0xAF,0x5A,0x9E,0x63,0x32,0x0B, +0xB9,0xFB,0xBD,0xE3,0x08,0xFA,0xB5,0x3C,0x5A,0x44,0x24,0xE3,0x5D,0x29,0x1C,0x75,0x1F,0x67,0x89,0xEB, +0x48,0xD2,0xE1,0x23,0x46,0xE9,0x8C,0x50,0x18,0x24,0x28,0x08,0x08,0x9D,0xB9,0x0A,0x2D,0x22,0x8B,0x8A, +0x5B,0xD0,0x03,0xE2,0xE4,0x16,0x0F,0x62,0x42,0xBB,0x73,0x12,0xF0,0xD0,0xDD,0x76,0x80,0x0A,0x3F,0x4F, +0x33,0xE0,0x29,0x61,0x84,0x72,0x9C,0x4A,0xB4,0x2C,0x41,0x74,0xA1,0x58,0x15,0x02,0xA8,0xF8,0x24,0x14, +0x34,0x8A,0xBB,0x93,0x88,0xF9,0x37,0xD5,0x4D,0xDB,0xC9,0x5D,0x71,0x97,0x1B,0xB2,0x5B,0x9C,0x2E,0x6A, +0x71,0x49,0xEC,0x16,0xB0,0x75,0x34,0xC6,0x78,0x69,0xF3,0xDB,0x1C,0xA0,0x96,0xFC,0x04,0x2E,0x2B,0xFA, +0x6B,0x96,0xDA,0x8C,0x17,0x28,0x84,0x26,0x39,0x5F,0x3C,0x56,0x25,0x4B,0x90,0x4F,0xF8,0xBD,0xEB,0xC8, +0x6D,0xD2,0x42,0xDC,0x2D,0xC7,0xD1,0x84,0xC0,0xB5,0x77,0x38,0x0D,0x10,0x45,0xD6,0x30,0x25,0x28,0xB2, +0x46,0xB5,0xC8,0xBB,0x31,0xFB,0xD4,0xCD,0x61,0x0C,0xF3,0x08,0xFB,0x5C,0x49,0x18,0x94,0x30,0xB9,0x21, +0xFC,0x31,0xE0,0xD1,0x42,0x43,0x56,0x52,0x42,0xA1,0xD2,0x5E,0x1F,0x64,0x23,0xE9,0x50,0x6C,0x2B,0x8E, +0xBA,0x13,0xC6,0x39,0x8B,0xA5,0xBD,0x55,0xDC,0x6A,0xD2,0x64,0x9E,0x3F,0x52,0xC7,0x6A,0xD1,0x37,0x8E, +0x1F,0x80,0x50,0x39,0xF1,0x51,0xD4,0x45,0x11,0x99,0x51,0x37,0x26,0x41,0x10,0xE1,0x41,0x43,0x07,0x79, +0x1A,0x19,0x01,0xE2,0xC8,0x55,0x7E,0x96,0xD0,0x19,0x40,0x33,0xBC,0xBD,0x65,0x91,0x77,0xFB,0xA7,0xE7, +0x73,0xE7,0xD5,0xCF,0x33,0x36,0x84,0x3F,0x27,0xA3,0x8B,0xF0,0xE8,0x62,0x06,0xA3,0x7D,0x31,0x1D,0xBE, +0x3D,0x18,0xBE,0x85,0x8F,0x83,0x7E,0xE7,0xE3,0xF4,0x8F,0xA1,0x58,0xFE,0x39,0xD8,0x1F,0x5F,0x1C,0x0D, +0x87,0xAF,0x7A,0x2F,0x4E,0xE6,0xEF,0x5F,0x6D,0x0B,0xF0,0x7E,0xE4,0x9C,0xBF,0x0B,0x9D,0x8B,0x8D,0x1F, +0xE2,0xE0,0x38,0x08,0xFD,0xF8,0x62,0xF8,0xF6,0xFD,0xF9,0xED,0x65,0x7C,0x31,0x1B,0xBD,0xEF,0x87,0x1F, +0x36,0xDE,0x8D,0x3E,0xBC,0xFF,0xE9,0x06,0xFF,0x72,0xFC,0xF2,0xC3,0x78,0x0E,0x08,0x87,0x6C,0x74,0x71, +0xBE,0xFF,0x6E,0x7F,0xF6,0x61,0xDF,0x3F,0xBA,0x9B,0x44,0x27,0xFB,0x3F,0x0F,0x27,0xC3,0x0D,0x1F,0xE3, +0xD9,0xF8,0x7C,0x3F,0x7F,0xF1,0xEA,0x74,0x46,0x48,0x38,0xFA,0x70,0x32,0xF6,0x0F,0x9E,0xBD,0xBE,0x38, +0x1E,0x92,0xF0,0xE4,0xE5,0xB9,0x73,0xF3,0xF3,0xAB,0x83,0x43,0xFF,0xF2,0xE5,0xE5,0xF6,0xE1,0x66,0xEF, +0xFB,0xEF,0xDF,0x04,0xA7,0x84,0x8E,0x6F,0x3F,0x0D,0x67,0x07,0xF3,0xE7,0xF7,0xD9,0x38,0x7C,0x71,0x4B, +0x7B,0xEF,0xD8,0xC7,0x17,0xF7,0x6F,0xE0,0xFF,0xB3,0xB3,0xCE,0x64,0xD4,0xCF,0x2E,0xDE,0xBE,0x78,0xB7, +0x91,0xFD,0xF0,0x2C,0xD9,0x3F,0x3C,0xBC,0x8D,0x27,0x67,0xBD,0x38,0xB8,0x99,0xF2,0xE7,0x9B,0x3C,0xB9, +0x9C,0xE5,0x1F,0xFE,0x78,0xF6,0x32,0xEC,0x9D,0x62,0x74,0x19,0x76,0xEE,0x3F,0xDD,0x3F,0x0F,0xC7,0xC7, +0xB7,0x27,0x11,0xBA,0x3B,0x39,0xF1,0x3F,0xC5,0x9D,0x08,0xFD,0x70,0x3A,0x8E,0x50,0xDA,0xBF,0x08,0x86, +0xBD,0xCE,0xC1,0xC6,0x70,0x8B,0xA7,0xE7,0x07,0xF4,0x70,0xF3,0xE3,0xE8,0xF9,0xFE,0x7E,0x9F,0x4D,0xFE, +0xD8,0xF8,0xF9,0x66,0xFB,0xE7,0x8B,0xED,0xB7,0x93,0xB7,0xC3,0xD1,0xD6,0xFE,0x05,0xBA,0x1C,0xBD,0x1D, +0x4E,0xB7,0x26,0x61,0xF8,0xEA,0xD5,0xF8,0xA7,0x60,0xF8,0x29,0x1D,0x9E,0xCE,0x87,0x77,0x47,0x17,0xC3, +0xE3,0xCE,0xAB,0xA3,0x37,0x4E,0x7F,0x74,0xB9,0x39,0x7B,0xB3,0x3D,0xDF,0xCF,0x8E,0x86,0x6F,0xF7,0x9D, +0xD9,0xCB,0x4E,0x8C,0x3E,0xB0,0x83,0xCD,0xD9,0x8B,0x6D,0x72,0x76,0x89,0x86,0x2F,0xF6,0x5F,0x66,0xE4, +0x3C,0x3E,0xBE,0x70,0x86,0xC3,0xD7,0xA7,0xF8,0xA7,0x83,0x4D,0xF4,0x6A,0xC3,0x7F,0x0F,0xF2,0xBF,0xF8, +0x05,0x7F,0xDF,0x19,0xCE,0x4F,0x9D,0xC8,0xFF,0x01,0x8F,0x8F,0x2F,0xC7,0x52,0x3B,0x47,0xD1,0x4F,0xE3, +0x9B,0x51,0xFE,0x36,0x3E,0x38,0x30,0x35,0xCA,0xBA,0x29,0x4E,0x30,0xE2,0xCD,0x58,0x55,0x39,0x07,0xD8, +0x56,0x6D,0x85,0x85,0x93,0x8A,0xC8,0xDA,0x0D,0xB0,0xCF,0x52,0x24,0xF7,0x00,0x02,0x4E,0x85,0x89,0x2D, +0x7F,0x94,0xA1,0x56,0x53,0x91,0x56,0x43,0x34,0xD0,0x8C,0xD2,0x11,0x62,0x42,0x01,0xE7,0x96,0xF8,0xB8, +0x9B,0x90,0x3B,0x1C,0x75,0x25,0xB2,0xEB,0x98,0x0B,0xE9,0x6C,0xE5,0x36,0x44,0x49,0xAC,0x4E,0x2D,0x17, +0x82,0x8F,0xC8,0x17,0x29,0x0D,0x5C,0x26,0x86,0xCF,0xC2,0x77,0x58,0xDA,0x9D,0xE4,0xB3,0x29,0xB9,0x03, +0x6F,0x9E,0x12,0x4A,0x38,0xD6,0xFA,0xD9,0xF2,0xC7,0xF2,0x98,0x1B,0x7C,0x3F,0x4D,0x51,0x8C,0x33,0xED, +0x6F,0x1E,0xB3,0x98,0xA6,0x2C,0x5E,0xD4,0x11,0x90,0xB3,0xC6,0x64,0xB9,0xFC,0x2A,0x4F,0x22,0x86,0x80, +0xCD,0x15,0x61,0x43,0x05,0xD3,0x54,0xB8,0x55,0x15,0x54,0x4B,0x37,0xDB,0x00,0xB7,0x6C,0xB9,0xF5,0xC6, +0x56,0xED,0xBA,0x5D,0xB9,0x57,0x04,0xFB,0xA6,0xE8,0x1B,0xF1,0xA0,0x11,0xEB,0xBE,0xE2,0x20,0xD2,0xD5, +0x97,0xAB,0x4B,0x54,0x64,0xA8,0x09,0x50,0x51,0xBA,0xBF,0xED,0x34,0x42,0x05,0xEC,0x5B,0x7E,0x85,0x65, +0x9A,0xB7,0xBE,0x4A,0x52,0xD0,0x06,0x9E,0x7F,0xE1,0xCC,0x8A,0xA7,0xF6,0xD9,0x70,0x66,0x95,0xEE,0x14, +0x0B,0x75,0xCE,0x93,0xB4,0x56,0x47,0x3F,0xE6,0x0A,0xC0,0x15,0x35,0xCF,0x04,0x35,0x5F,0x94,0xEA,0xE6, +0xF6,0x37,0x05,0x0D,0x5B,0xCE,0x37,0x4B,0x5B,0xED,0xAD,0xF2,0x71,0xDF,0x81,0x3F,0x65,0xDA,0x7D,0x5E, +0x93,0x30,0x79,0x26,0xFE,0x96,0x04,0xC2,0x39,0x4D,0xE0,0xE6,0xD6,0x0F,0xCF,0x83,0x49,0x09,0x54,0x8C, +0x3D,0x0D,0x4F,0x51,0x40,0xF2,0xCC,0x7D,0xE6,0x7C,0xA3,0xE4,0x09,0xEA,0x03,0xDE,0x4B,0xE5,0xAA,0x49, +0x6D,0xB1,0x59,0x42,0xA8,0xB6,0x91,0x69,0x42,0xDF,0x28,0xAD,0x0C,0xB3,0x99,0xEA,0xC1,0x45,0x6A,0xD3, +0x14,0xFB,0x17,0xCE,0x37,0x0B,0x9E,0x22,0x9A,0x4D,0x59,0x1A,0xBB,0x29,0xE3,0x88,0x63,0xC3,0x31,0x97, +0x7D,0x67,0x15,0x60,0x73,0xDB,0x09,0xF0,0xCC,0x5C,0x2E,0x77,0x7A,0x32,0xA9,0x41,0xC5,0xE3,0xA7,0x24, +0xE1,0xBB,0xD3,0x9C,0xFA,0x82,0x06,0x6D,0x86,0x0D,0x6C,0x2E,0x52,0xCC,0xF3,0x94,0x6A,0x01,0xF3,0x73, +0x61,0xEC,0xF6,0x0C,0xF3,0x23,0x65,0xF7,0xFB,0xF7,0x2F,0x02,0xD8,0xB1,0xAC,0x10,0xFC,0x95,0x08,0xE0, +0xC0,0x70,0x5F,0x81,0xD3,0xDA,0x0F,0x09,0x06,0x0E,0x79,0x85,0xEF,0x0D,0x6C,0xF1,0x0A,0x11,0xDB,0x62, +0xDD,0x30,0xCA,0x6D,0x00,0xA4,0xE6,0xE2,0x16,0xA4,0x80,0x3C,0x7C,0xC5,0xAF,0x2D,0xE2,0x51,0xF8,0x18, +0x14,0xDB,0xC9,0x2E,0xDA,0xEB,0xF6,0x5D,0xB4,0x4B,0xF6,0xFA,0xE0,0x5F,0x66,0xE3,0x7C,0x75,0xF3,0x4F, +0x24,0xC2,0x17,0x85,0xCB,0x89,0x8B,0xEA,0xD3,0x7A,0x06,0x39,0x0B,0x41,0x90,0xE6,0x77,0xC6,0xE9,0x48, +0x33,0xAE,0xBE,0xEF,0xFE,0x70,0xFD,0xB9,0x7F,0xE5,0x74,0xFB,0xD7,0xE6,0xEF,0x66,0x8F,0xD8,0x1C,0x67, +0xDC,0xA0,0xE8,0x96,0xCC,0x10,0xD8,0xB9,0x2D,0xF2,0xED,0x70,0x06,0x5C,0x98,0x83,0xEA,0x0E,0xA2,0xC8, +0xDB,0x70,0x9C,0x35,0x0F,0xEF,0xA1,0x08,0x03,0xE9,0xFA,0xD1,0xF9,0xF9,0xE9,0xF9,0x95,0xDE,0xC1,0x1D, +0xFD,0xDA,0xD5,0xF4,0x0E,0x35,0x5D,0x6E,0x43,0xD1,0x99,0xE2,0x2C,0x3C,0x43,0x3C,0x34,0x02,0xFB,0x16, +0x45,0x39,0xC8,0x42,0x10,0xC2,0x3C,0x10,0x9C,0x3E,0xC9,0x39,0x67,0x54,0x37,0x07,0xCC,0x26,0x94,0xE2, +0xF4,0x78,0xFC,0xE6,0xB5,0xA7,0x9F,0x33,0xC6,0xB5,0x43,0x92,0xEA,0x96,0xD4,0x86,0x8D,0x92,0x04,0xD3, +0xE0,0x20,0x24,0x51,0x60,0x30,0x73,0x20,0xD0,0x7D,0x89,0x2E,0x0B,0x11,0xC0,0xF6,0x6D,0x55,0xB2,0x4E, +0x81,0x6B,0xDD,0xF2,0xED,0x38,0x8F,0x38,0x49,0x22,0xEC,0xAD,0xF5,0x61,0x46,0x51,0x0C,0x30,0x91,0x86, +0x05,0x8C,0x04,0x9E,0xAE,0x82,0x51,0x11,0xC2,0x56,0xDD,0xE2,0xAB,0x5B,0x82,0xD6,0x2D,0x41,0x13,0x37, +0x01,0x8E,0x74,0x2B,0xB0,0xEB,0x5A,0x19,0x66,0xC5,0x55,0x25,0x2C,0xC0,0x53,0x04,0x94,0xBC,0x13,0x5C, +0x43,0xE9,0xBD,0xEA,0xA2,0x40,0x5D,0x94,0xB5,0xA5,0x91,0x35,0xA5,0xA1,0xD4,0xB8,0x0A,0x39,0x53,0xC8, +0x69,0x1B,0x39,0x6D,0x22,0x1F,0x48,0x6B,0x58,0x85,0x9C,0x2A,0xE4,0xA8,0xC5,0x62,0x24,0x59,0x54,0x11, +0xAE,0x2B,0xA4,0x09,0x0C,0x01,0x76,0xD4,0x64,0x13,0x66,0xE0,0x90,0x68,0x12,0xE1,0xC0,0x5B,0x73,0x60, +0x26,0x8A,0x6A,0x6F,0xC3,0x59,0x71,0x47,0xA4,0xEE,0xC8,0x5B,0x77,0xE4,0xF2,0x0E,0x92,0x80,0x10,0x21, +0x6F,0xE8,0x56,0x2E,0xA5,0xD6,0x5E,0x51,0xD7,0xF9,0x21,0xF6,0x6F,0x26,0x4C,0xAE,0xC8,0xB1,0xB8,0x71, +0x0D,0xC9,0x33,0x13,0x79,0xA6,0x6C,0x45,0xE0,0xCC,0xC4,0x06,0x2F,0xF7,0xC4,0xC9,0x56,0xD2,0x64,0x5F, +0x1B,0x46,0xDC,0xD6,0x25,0x42,0xDC,0x96,0x52,0xDC,0xDA,0x36,0x42,0xB7,0x58,0x5B,0x25,0xA5,0xD8,0x5C, +0xB1,0x98,0xAC,0x5A,0xCC,0x4D,0x2B,0xB5,0x19,0xF5,0x23,0xE2,0xDF,0x78,0xB5,0x1B,0x9B,0x0B,0xA3,0x39, +0x11,0x94,0x70,0x8F,0xE2,0xB9,0xF6,0x13,0x84,0xA5,0x43,0xC4,0xD1,0x80,0x17,0xC7,0x18,0x85,0xDD,0x60, +0x38,0x08,0xBA,0x51,0xF0,0xC2,0xCC,0x46,0x01,0x2C,0x9F,0x5D,0x8C,0x75,0x4B,0xEF,0x09,0xAD,0xE8,0xE0, +0xC9,0xC4,0x5C,0x9A,0x95,0x2F,0x59,0x54,0x46,0xF5,0x8B,0x34,0xAA,0x97,0x60,0x50,0x5A,0xDC,0xD2,0x8A, +0x57,0xD2,0x44,0xA6,0x46,0x25,0xD2,0x92,0x28,0xD1,0x19,0x8A,0x3B,0x8C,0x42,0xFF,0xBA,0x09,0x61,0x4F, +0x19,0xAF,0x61,0x5A,0xA8,0x4D,0x34,0xAA,0x88,0x4E,0xD1,0xBC,0x34,0x12,0x75,0xFF,0x40,0xB9,0xB7,0x03, +0xD9,0x97,0x66,0x5C,0xC3,0xDE,0x96,0xF3,0xC3,0xF6,0x00,0xF4,0x63,0x28,0xC7,0x05,0xC0,0x0E,0xB7,0xC1, +0xB4,0x66,0x3C,0x1C,0xF8,0x1D,0xAF,0x90,0x4A,0xE0,0x71,0x3B,0xCB,0x27,0x19,0x4F,0x21,0xB7,0x19,0xBE, +0xE5,0x77,0xB0,0xD9,0xBE,0x46,0xEF,0x30,0x2B,0x30,0x2D,0xD6,0xE9,0x2C,0x1F,0x08,0xE8,0x74,0xD4,0x90, +0x10,0x12,0x12,0xC2,0x51,0x86,0x35,0x6A,0xE3,0x3B,0xEC,0x1F,0xB0,0x38,0x46,0xE2,0x88,0x0C,0x94,0x5C, +0x4C,0x74,0x73,0x69,0xB1,0x95,0x92,0x79,0x22,0x64,0x59,0xD9,0x53,0x72,0x84,0x10,0xE8,0xF9,0xB6,0xF0, +0x95,0xAC,0x60,0xEA,0xCB,0x5A,0x2E,0x03,0x91,0x42,0xB9,0x72,0xAE,0xAD,0x4A,0x71,0x2B,0xB9,0xAA,0xF5, +0x2E,0xAD,0xAE,0x15,0x7F,0xCC,0x5A,0xD3,0x02,0xD6,0x8E,0x6B,0x35,0x54,0x5F,0x2E,0x2D,0x5F,0xD0,0x1F, +0x22,0x3A,0xC3,0x7F,0x9F,0x81,0x9A,0x46,0xE9,0xA2,0x16,0x85,0xE4,0xB1,0xE7,0xFE,0x6A,0x1B,0x57,0xBF, +0xD9,0xD7,0x1D,0xD3,0xDC,0xFB,0xBA,0x27,0x25,0x6C,0x70,0xF3,0xAA,0x7F,0x6D,0x21,0x00,0xDB,0xDF,0x99, +0xBF,0xDA,0x12,0xDC,0x82,0x0D,0x6E,0x19,0x09,0x34,0x71,0x93,0xF0,0x6C,0x36,0xD5,0xD0,0xFA,0xBA,0x01, +0x26,0xD7,0x32,0xD6,0x0E,0xEF,0xE8,0x36,0xE4,0x8D,0xE5,0xF2,0x61,0x36,0x1B,0xA7,0x18,0xAB,0x74,0x59, +0x01,0x24,0xF5,0xC0,0xF3,0xC3,0x60,0x55,0x71,0x8D,0xAD,0x1A,0x0A,0x8B,0x32,0xDD,0xDB,0x45,0x25,0xE1, +0xE9,0x94,0x51,0x30,0xD9,0xE4,0xE1,0xB2,0x6C,0xF1,0xF4,0x56,0x0C,0xF9,0x76,0x87,0xC4,0x33,0x2D,0x4B, +0x7D,0x4F,0xA9,0x62,0x4F,0xFC,0xE3,0x7D,0x2B,0xD2,0xDC,0xFA,0xEF,0xFE,0xC4,0xD3,0x3B,0xA0,0x5F,0x6C, +0x53,0x36,0x37,0xCC,0xCE,0xB7,0xBA,0x26,0x4F,0xF4,0xF4,0x18,0xDD,0x15,0x8D,0xBE,0xA8,0x44,0x06,0x1A, +0xCC,0xAB,0xCE,0x54,0x2D,0xA8,0x16,0x1B,0xE5,0x9C,0x0D,0xB4,0xB2,0xC2,0x51,0x2D,0xA6,0xAE,0xF5,0x76, +0xBF,0xAD,0x65,0x80,0x80,0x75,0xA4,0x74,0x42,0x64,0x10,0xCB,0x45,0xC8,0xC3,0xAD,0xE8,0x43,0x0A,0xB7, +0x53,0x51,0x91,0x00,0x9C,0x3C,0x48,0x9B,0x56,0x66,0x20,0x73,0xCF,0x68,0x25,0xDA,0x1D,0xD1,0x94,0xEC, +0x9E,0xA9,0x6A,0x73,0xA7,0x27,0x67,0xFA,0x2A,0xC7,0x00,0xC9,0x53,0x40,0xB7,0xAA,0xFA,0x66,0xC2,0x82, +0xFB,0x46,0x55,0x94,0xED,0xDF,0x1F,0x44,0x28,0xCB,0x4E,0x50,0x0C,0xF7,0xFB,0xB1,0x6E,0x16,0xA6,0xB4, +0xEB,0xAC,0xAF,0xB7,0x91,0x52,0x1C,0x43,0x13,0xA4,0xA8,0xC2,0x10,0xCA,0xDC,0x00,0x0E,0x5E,0x5F,0x5F, +0x45,0x98,0x78,0x50,0xFB,0x12,0x55,0x14,0xDC,0xB5,0x0C,0x7F,0xFF,0x13,0x75,0x2A,0x47,0x3E,0x25,0xD5, +0xC8,0xB4,0x04,0xF5,0x9F,0x3F,0x2B,0xD9,0x46,0x8F,0x59,0x38,0x64,0x73,0x2A,0x28,0xAC,0xD8,0x88,0x56, +0x08,0xB7,0xCE,0x11,0x95,0x55,0x07,0x05,0x5E,0x77,0x9A,0x2A,0xA3,0x6E,0x18,0x60,0x09,0x03,0xD3,0xC3, +0x4B,0xF3,0xFF,0x52,0x8B,0xAF,0xD4,0xF2,0x88,0xE1,0x15,0x4C,0x1E,0x84,0x50,0xAC,0xFD,0x05,0x87,0x71, +0xEB,0x86,0xD8,0xF6,0xC5,0xE7,0x09,0x0B,0x64,0x78,0x31,0xAD,0xDC,0x88,0xAD,0xFF,0x51,0x83,0x49,0x4B, +0x83,0xED,0x54,0x9E,0xAC,0xD0,0x1A,0x8E,0x30,0xC7,0x15,0x47,0xC9,0x4A,0x8E,0xD2,0xFF,0x47,0xF2,0xB5, +0xDF,0x13,0x55,0xB8,0x37,0x3D,0x3F,0x20,0xB7,0x3A,0x64,0x40,0xAF,0x7D,0x02,0xF4,0x30,0x2C,0x8A,0xC6, +0x2C,0xD9,0x7B,0x62,0xDD,0xAD,0xD6,0x8B,0x41,0x49,0x66,0xBD,0xC5,0xF2,0x57,0x1E,0xFA,0x1A,0x4F,0xF9, +0xDE,0x53,0x80,0xA7,0x8F,0xAD,0xF7,0x58,0x81,0x87,0x6D,0x10,0x1E,0xAC,0xFE,0xD2,0xF1,0xAD,0xAC,0x9A, +0x5D,0x76,0x18,0xE8,0xC2,0x2F,0x85,0xE4,0x09,0x21,0x59,0x64,0x65,0x40,0xAE,0xD7,0x45,0xB7,0xEC,0x05, +0x1D,0x3D,0xB9,0xAB,0xD7,0x38,0x4B,0xBC,0x4C,0x2D,0x21,0x83,0x58,0xFC,0x81,0x52,0x56,0x85,0xC9,0xD4, +0x23,0x36,0x9B,0x4E,0x33,0xCC,0xDF,0x8B,0x10,0x6D,0x45,0xD5,0xFC,0x58,0x86,0xE8,0x01,0x4C,0x69,0xCC, +0xF2,0x0C,0xB3,0x9C,0xB7,0x8B,0xB9,0x8A,0x99,0x9D,0xE0,0xF3,0xE7,0x6A,0xB2,0x1B,0x74,0xD2,0x7A,0x7A, +0xB9,0x93,0x35,0x26,0xBB,0x59,0x27,0x02,0x4F,0xFA,0x8F,0x2D,0x85,0x34,0x2D,0x85,0x89,0x0C,0x61,0x31, +0x65,0x29,0x69,0x6D,0xEB,0xA9,0x28,0xB5,0x51,0x23,0x86,0x09,0x83,0xD6,0xCD,0xB2,0x8B,0x6C,0xBA,0x32, +0xB2,0xD2,0xB6,0xA7,0x3F,0x55,0xCE,0x06,0x86,0x38,0x15,0xA4,0xFE,0x9A,0xCD,0x71,0x7A,0x80,0x32,0x6C, +0x40,0x25,0x50,0xC5,0x61,0x09,0x35,0xDD,0x6C,0xE5,0x2E,0x5A,0x40,0x7D,0xF5,0x09,0xE1,0xE5,0x8B,0x61, +0x01,0x36,0x88,0xB8,0xB0,0xE2,0x24,0x73,0xA9,0xA8,0x63,0x54,0xB4,0x24,0x20,0xA1,0xBC,0x45,0x23,0xB6, +0xC5,0x0B,0x0A,0xC8,0xED,0x50,0x75,0x60,0x50,0xBF,0x62,0xB0,0x16,0x96,0x9C,0xA5,0x2C,0x41,0x33,0x24, +0xF6,0xC1,0x1A,0x38,0x98,0x3C,0x5C,0x9C,0xD6,0x28,0x39,0xEA,0x7E,0xBE,0xDB,0xF7,0xC0,0x5E,0xE5,0x6B, +0xC9,0xE9,0xD4,0x80,0xE2,0xA4,0xD1,0x67,0x07,0x55,0x39,0x2F,0xAB,0xA2,0xC7,0x45,0x11,0x96,0x85,0x0F, +0x14,0x58,0x0F,0x6B,0x1F,0x6E,0x66,0x73,0xC2,0xFD,0x50,0x04,0x11,0x1F,0xF8,0xD1,0x39,0x74,0x55,0xAE, +0x1C,0x85,0x3C,0xAE,0x47,0x51,0x31,0xFC,0x98,0x15,0x03,0x3F,0x2B,0x47,0x77,0x0D,0x20,0xA3,0x25,0x98, +0xD1,0x69,0x31,0x24,0x94,0x94,0xE7,0x94,0xC0,0xF2,0x33,0x49,0x8A,0x51,0x12,0x96,0xA3,0x10,0xDF,0x55, +0x78,0xAC,0x84,0x06,0x58,0x77,0x95,0x14,0xD6,0x9C,0x65,0x31,0xE8,0xD7,0xEC,0x67,0xFF,0x1D,0xFB,0x09, +0x9D,0x95,0xCC,0x24,0xE5,0x68,0x46,0x4A,0x56,0x26,0x71,0xF2,0x45,0x42,0xD2,0x7F,0xDB,0x56,0x1D,0x1E, +0xBD,0x3E,0x1A,0x1F,0x35,0x2B,0xEC,0xE6,0xEB,0x0B,0xFF,0xAB,0xE7,0x0D,0x6E,0xBA,0xC6,0xDF,0x48,0x6A, +0x50,0xD7,0x9A,0x66,0xEB,0x81,0x26,0x6A,0x3D,0xFC,0xD4,0x19,0xA5,0x78,0x51,0x01,0x39,0xAD,0xAF,0x37, +0x08,0x91,0xEB,0xF5,0xA3,0x11,0xB5,0x74,0x55,0xE6,0x4A,0xAF,0x46,0x4F,0xD5,0x83,0xC8,0xAC,0x3A,0x2E, +0xE2,0xD1,0x22,0xA2,0x58,0xA2,0xF9,0x22,0xBB,0x3E,0x74,0x5D,0x1D,0x53,0x3D,0x96,0x78,0x9E,0x47,0xAF, +0xFC,0x6B,0xD9,0x70,0xAF,0xAF,0xA3,0x76,0xCD,0x68,0x38,0x96,0x04,0x8A,0x0B,0xE5,0x48,0xB6,0xFA,0xC0, +0x0B,0x90,0xE5,0x58,0x2F,0x47,0xA7,0x27,0x76,0x82,0x52,0x70,0x48,0x6A,0x36,0xA3,0x51,0xAE,0x18,0x6C, +0x4B,0xFB,0xE7,0xA3,0x46,0x33,0x23,0xBF,0x4F,0x73,0xF9,0xD2,0x8A,0x0C,0x71,0x9C,0xCA,0xD0,0xA2,0xEC, +0x29,0x1E,0x3E,0x21,0xC7,0xC5,0x65,0xBE,0xAB,0xC3,0x55,0xDC,0xCC,0x16,0xFC,0x36,0x7F,0xA2,0x5F,0xE7, +0x21,0xC9,0x9A,0x4D,0x5C,0x2B,0x32,0xFC,0x4D,0x8D,0x2D,0xCB,0x91,0x3A,0xEE,0x61,0x3F,0xA2,0xBE,0xE9, +0x55,0xCA,0x91,0xFD,0x66,0xDD,0x97,0xB0,0xDA,0x1C,0x75,0x48,0x61,0x84,0xEA,0x16,0xFD,0xA7,0x1E,0x42, +0x4B,0x0F,0xA1,0x8F,0x03,0x04,0xBE,0x6B,0x79,0x7B,0x75,0xCB,0x60,0x02,0x94,0xDD,0x0C,0xAA,0x28,0x02, +0x10,0x19,0x43,0x5A,0x80,0x8F,0x99,0x5C,0xFF,0x88,0x6E,0x91,0x7A,0xF7,0xAC,0xA1,0xAB,0x43,0x85,0xDC, +0xEE,0xFF,0x0E,0xA3,0x6A,0x67,0x3B,0x10,0x65,0x30,0x7C,0x1C,0x4F,0x78,0x2B,0x3C,0xD5,0x31,0xAB,0x19, +0x9D,0xC0,0x5D,0x97,0x85,0x62,0x79,0x43,0xBE,0x0D,0xD7,0x03,0x83,0x7C,0xCA,0xF7,0x9A,0x71,0x58,0x61, +0x34,0xAD,0x67,0x75,0xB7,0xD7,0xEE,0x07,0x57,0xD7,0x19,0xD2,0xFF,0xF0,0x5E,0x66,0x67,0xE5,0xCB,0x07, +0xB8,0x79,0x63,0xA6,0x83,0x41,0x64,0x60,0x86,0x18,0xA5,0x23,0xD1,0x64,0xAB,0x44,0xB2,0x54,0x0A,0xF4, +0xA4,0xEB,0x1A,0x20,0xB1,0x9E,0x4C,0x19,0x36,0xC8,0x01,0xF6,0x57,0x40,0x0A,0x40,0xEA,0x31,0x38,0xB2, +0xB1,0x88,0x60,0x11,0x41,0xBB,0xC8,0x28,0xBB,0x41,0xA4,0xB9,0x9D,0x00,0x84,0x14,0x5F,0xC3,0x43,0x57, +0x6C,0x15,0x7A,0x90,0x07,0xD5,0x10,0xA5,0x7D,0xB3,0x78,0x46,0xAC,0x1F,0x71,0x70,0xE9,0x36,0x85,0x7D, +0xAC,0x49,0xB4,0x4C,0x14,0x1E,0x23,0x9C,0x65,0x92,0x6E,0xC1,0xD7,0x1B,0x16,0x00,0x5B,0x80,0xD6,0x8B, +0x61,0x24,0x2E,0x02,0x0E,0x05,0x60,0x1C,0xE2,0xB8,0x80,0x70,0x18,0x0A,0x10,0x12,0xA0,0xAF,0xA5,0xA8, +0x46,0xB2,0xC0,0x23,0x74,0xE6,0xF5,0x7B,0x8E,0xF5,0xF8,0xD8,0x8B,0x0C,0x8F,0xD8,0x94,0x8F,0xD1,0x24, +0x33,0xD6,0x1C,0x73,0xC5,0x0E,0x00,0x8D,0x20,0x9A,0x18,0x1B,0xE6,0x6A,0xF4,0xF7,0x2C,0xBD,0xC1,0x69, +0x81,0x2C,0x2A,0x33,0x28,0xCC,0x22,0x51,0x9C,0x0D,0x41,0xEA,0xB7,0xF8,0x35,0xA1,0xB8,0x06,0x8E,0x42, +0x36,0x3F,0x4B,0x09,0xE5,0x6F,0x64,0x57,0x6D,0xAC,0xF5,0xA5,0x9E,0xD4,0x63,0x8F,0x8C,0x40,0xE5,0x2B, +0xD0,0x42,0x04,0x33,0xB7,0xF5,0x16,0x64,0x4D,0x40,0x5D,0x10,0x5B,0xDD,0xC5,0x9C,0x50,0x57,0x3F,0xE0, +0x69,0xD4,0x1D,0xE9,0x56,0x8C,0x7C,0x98,0xA8,0x3D,0x30,0x5F,0x5A,0xC2,0x69,0xDD,0x66,0x30,0x59,0xAB, +0x27,0x75,0xA1,0xBE,0xF2,0xA1,0xAC,0x7E,0xF7,0x11,0xC0,0xFD,0x88,0x4D,0x0C,0xF1,0xA8,0xBF,0x10,0x0E, +0xEF,0xD2,0xA5,0x29,0xB2,0xD3,0x97,0xDF,0xB4,0x7C,0x88,0xBA,0xDC,0xC2,0x8D,0x27,0xB9,0x8E,0xAE,0x8B, +0x97,0x2E,0xC0,0x43,0xC1,0x29,0x8D,0xEE,0x5D,0xC8,0x8A,0x7F,0xC1,0x75,0x4E,0x03,0xF6,0x25,0xAE,0x3F, +0x3C,0xE0,0xFA,0xC3,0x2A,0xAE,0x71,0x5B,0x5B,0x30,0xB9,0x80,0x63,0xDF,0x20,0x8A,0x66,0x38,0x85,0x05, +0x71,0x09,0x28,0xE0,0x9F,0x51,0x96,0xE2,0x2F,0x53,0x36,0x0A,0xC9,0x94,0x3F,0xA4,0x4F,0xAD,0xFE,0x3B, +0x2A,0x53,0xFC,0x04,0x95,0x65,0x21,0x5B,0xA5,0x8D,0xBF,0x7E,0x68,0x92,0x4E,0xED,0x81,0x0A,0x9B,0xEE, +0xFA,0x2F,0xFC,0xAE,0xBE,0xF1,0xCB,0xD9,0x53,0x7C,0xB8,0x78,0x69,0x05,0xC2,0x26,0x80,0x83,0x46,0x7E, +0x62,0x74,0x1F,0x3A,0x85,0xD7,0xC0,0x82,0xA1,0xCC,0x11,0x7B,0x8B,0xA5,0xC5,0x3D,0x63,0x4E,0x80,0xFD, +0x39,0x30,0xE7,0xCB,0xEA,0xD7,0x0E,0x21,0x43,0x82,0x10,0x80,0x48,0xC8,0xB3,0xBD,0xAB,0xBD,0xF5,0xEB, +0x0E,0x24,0x28,0x0F,0x3E,0x4C,0x0F,0x06,0xEB,0xD7,0xDF,0x99,0xBD,0x19,0x69,0x94,0x44,0x32,0xD5,0x81, +0x5C,0xAF,0xE8,0xB5,0x87,0x96,0x10,0xC2,0x9A,0xA9,0xB0,0x0A,0xAC,0x16,0x96,0x6F,0x86,0xF0,0x11,0x21, +0x3A,0x83,0x0F,0x19,0x3B,0x60,0x37,0xF5,0x1A,0x4F,0x79,0x3A,0x87,0x7F,0x75,0x08,0xDB,0x83,0x82,0xAC, +0x00,0x4F,0x09,0xC5,0x32,0x7A,0xA9,0xA1,0x55,0x00,0x84,0x18,0x48,0x2A,0x21,0xE5,0xD8,0x12,0x63,0x91, +0xFD,0xC8,0x4C,0x08,0xD2,0xD0,0x27,0x28,0xC3,0x22,0xD1,0xEB,0x32,0x61,0x3F,0x02,0xCF,0x65,0x20,0x69, +0x6C,0x58,0xF1,0x0D,0x99,0x9E,0x17,0x23,0x1D,0xB8,0xE4,0x8D,0x20,0xAC,0xD8,0x81,0x78,0xAB,0x06,0x0F, +0x42,0x7B,0xDD,0xF5,0x28,0xB0,0xB9,0x04,0x17,0x53,0x0C,0x04,0x7A,0x95,0xCE,0x7F,0x79,0xF3,0xFA,0x98, +0xF3,0xE4,0x5C,0x69,0x14,0xCE,0x6A,0x2F,0xD4,0x86,0x66,0x2E,0x78,0x7A,0x5F,0x16,0x86,0x22,0x50,0xA8, +0x50,0xF7,0xCB,0xE9,0xE4,0x23,0xF6,0x81,0x93,0x37,0x19,0xE4,0xD0,0x0D,0x5B,0xA0,0x8F,0xC7,0x67,0xF6, +0xB6,0xED,0x40,0xA5,0x02,0xFA,0xF4,0x43,0x61,0x31,0xCB,0x7F,0x84,0xBC,0xF9,0xCF,0x90,0x09,0xC4,0xFB, +0x0C,0x02,0x7A,0x89,0xDF,0xC6,0x0D,0x53,0x36,0x97,0x68,0x47,0x69,0x2A,0x8C,0x61,0x1C,0x92,0x4C,0x9B, +0xC0,0x62,0x86,0x53,0x2D,0x60,0x38,0xD3,0x28,0xE3,0x5A,0x96,0x27,0x09,0x4B,0xF9,0x03,0x79,0xD8,0x7A, +0xF9,0x48,0xF3,0x36,0xC7,0x39,0x0E,0x8A,0x65,0x9C,0x36,0xE5,0x22,0x6B,0x3A,0x58,0x07,0x77,0xBB,0xBA, +0x2E,0x2A,0xBC,0x9C,0x52,0x91,0x7F,0xD6,0xFA,0x6A,0x0E,0xDC,0x85,0x70,0xAA,0x47,0xF3,0x28,0x5A,0x0E, +0x1E,0x9C,0x05,0xFD,0x20,0xE3,0x4C,0xE8,0xC3,0x5B,0xFC,0x5E,0xB8,0x96,0xFB,0xE0,0x1D,0xBC,0x7D,0xAA, +0x63,0xAD,0x19,0x6B,0x58,0x23,0x34,0xE3,0x88,0xFA,0x42,0x8D,0x4A,0x16,0x66,0x59,0xDD,0x89,0xED,0x03, +0x11,0x17,0xA4,0xE1,0x3C,0x59,0x52,0x48,0xCE,0xA8,0xA7,0xEB,0xA2,0xD0,0xC3,0xA2,0x5E,0x46,0x71,0xD6, +0x38,0xB6,0xCA,0x14,0x26,0xF5,0x4A,0xF0,0x40,0x7E,0x7B,0xB1,0x6A,0x7F,0x4D,0x46,0x59,0xDD,0x23,0x80, +0x69,0xE5,0x3E,0x93,0x76,0x3C,0x5D,0x56,0x08,0x7B,0x32,0x64,0x48,0x03,0x8E,0x31,0x0F,0x59,0xB0,0xA7, +0xEF,0xE9,0xAE,0x0E,0xFF,0xAD,0xEB,0x16,0xEC,0xC2,0xD4,0x67,0x01,0xBE,0x38,0x7F,0x01,0xA1,0x34,0x61, +0x14,0x53,0x6E,0x20,0xC8,0x28,0x9E,0xDE,0x79,0x0C,0xA9,0xC8,0xB8,0x42,0xD7,0xE6,0xA0,0x2D,0x6C,0x3C, +0x7F,0xA0,0xCE,0x96,0x32,0x6C,0x46,0x45,0x74,0xBD,0x07,0xE2,0x39,0x7E,0xF4,0xED,0x83,0x45,0x1F,0x77, +0x41,0xE6,0x62,0x4B,0xD0,0x2C,0xB1,0x46,0x80,0x25,0x5C,0xAF,0x16,0xF2,0x53,0x95,0x1D,0xB5,0x7D,0x14, +0x45,0xE2,0xD7,0x12,0x40,0xAB,0xB8,0x2C,0xCF,0x2C,0x71,0x48,0x06,0x0C,0x64,0x78,0x8C,0xEF,0xC0,0xA5, +0x65,0x79,0xA6,0x6C,0xA8,0x68,0x87,0x44,0xAD,0xD6,0x30,0x23,0xD3,0xAA,0x66,0xEB,0xEB,0xDC,0x2E,0xCD, +0xC4,0x28,0x91,0x32,0x91,0x6C,0xE4,0xDB,0xC3,0xD2,0x68,0x32,0x29,0x72,0xF7,0x23,0x69,0x1B,0x6D,0x31, +0x24,0x98,0x1A,0x25,0x0C,0x28,0xCB,0xD3,0x08,0x32,0x84,0xA8,0x5E,0x5A,0xDB,0x32,0x4C,0x03,0xB8,0xC0, +0xFD,0x4B,0x64,0x89,0x4A,0x9B,0x56,0x31,0xE2,0xA9,0xA2,0xBB,0x7D,0x1E,0x2F,0xB4,0x72,0x8C,0x65,0x98, +0x6B,0xFF,0xBC,0xD5,0x92,0x3F,0x4C,0x25,0x2A,0x21,0xF4,0xE0,0xEB,0x8A,0xF9,0xBC,0x0B,0x66,0x15,0x77, +0xE1,0x06,0x65,0x05,0x81,0xBE,0x82,0x42,0xD5,0xED,0x59,0xE2,0x39,0xC5,0x7D,0xE0,0xA2,0xB5,0xFC,0x8C, +0x07,0x3E,0xDA,0x3E,0xA7,0x4D,0x67,0x43,0xDB,0x3B,0x5B,0x0F,0x40,0x68,0xC2,0x52,0x6E,0x40,0x8E,0x83, +0x34,0x58,0xDD,0x56,0x36,0x5E,0xCD,0xB8,0x60,0x27,0x79,0x16,0x1A,0x0B,0x20,0xDD,0xE5,0x96,0x92,0x95, +0x8B,0x2D,0x65,0xB7,0x2E,0xB5,0x4A,0xFB,0x70,0x21,0x75,0xB5,0xE2,0xC7,0xE7,0xCF,0x72,0x56,0x6B,0x1B, +0x66,0x6D,0x85,0x03,0xB3,0xD2,0x89,0xCB,0x8C,0x2C,0x8C,0xFE,0x61,0xAC,0xDA,0xE9,0xA9,0x7E,0xAA,0xFC, +0x3D,0x89,0x46,0x02,0x4F,0x24,0x77,0xBD,0xF8,0xE2,0x08,0x86,0x53,0x88,0x4B,0x36,0x34,0x60,0xD5,0x0F, +0x88,0xF5,0xE2,0x17,0xC4,0x0F,0x71,0x77,0xAB,0x8E,0xD0,0xF3,0xAA,0x7A,0x5E,0x45,0x1D,0xB5,0xC1,0x7B, +0xE2,0x57,0x26,0xBA,0x02,0x43,0xC3,0xAC,0x06,0x76,0x75,0xB7,0xB8,0xD7,0x2A,0x16,0x51,0x76,0x4F,0x7D, +0x11,0x35,0xAB,0x53,0x42,0x10,0x7F,0xAB,0x89,0x56,0x3B,0xCD,0x65,0x4D,0x99,0x78,0x7E,0xD4,0x58,0xF1, +0xAD,0x43,0xB3,0xC6,0x00,0xF2,0xA1,0x47,0x17,0xEC,0x96,0x2E,0xAA,0xC9,0x26,0xBD,0x9A,0x02,0x7B,0xB0, +0xA1,0xDE,0x95,0x27,0xAB,0x01,0xB2,0x24,0x78,0xB4,0xA8,0xAA,0x8A,0x87,0xCB,0x65,0xA3,0x57,0x7D,0xD9, +0xD6,0xFC,0x81,0x50,0xB5,0x99,0xC8,0xAF,0x4E,0xE4,0xFE,0xF6,0xB7,0x29,0x4F,0xA2,0x29,0x8C,0xDD,0x3F, +0x01,0x4B,0x0A,0x87,0xFB,0x35,0x2E,0x00,0x00 }; From abb9d79045461dc8fa750fe6c9f4b8a5c338a224 Mon Sep 17 00:00:00 2001 From: lorol Date: Wed, 17 Jun 2020 13:12:16 -0400 Subject: [PATCH 058/551] LittleFS, on ESP32, too. see my library and tool plus the core conversation: https://github.com/lorol/arduino-esp32littlefs-plugin https://github.com/lorol/LITTLEFS https://github.com/espressif/arduino-esp32/issues/3765 #include #define SPIFFS LITTLEFS #include --- .../ESP_AsyncFSBrowser/ESP_AsyncFSBrowser.ino | 16 +++++++++++----- examples/SmartSwitch/SmartSwitch.ino | 9 +++++++-- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/examples/ESP_AsyncFSBrowser/ESP_AsyncFSBrowser.ino b/examples/ESP_AsyncFSBrowser/ESP_AsyncFSBrowser.ino index 205643333..b12106b76 100644 --- a/examples/ESP_AsyncFSBrowser/ESP_AsyncFSBrowser.ino +++ b/examples/ESP_AsyncFSBrowser/ESP_AsyncFSBrowser.ino @@ -1,12 +1,18 @@ #define USE_LittleFS // possible only for ESP8266 for now #include + #ifdef ESP32 -#include -#include -#include -#include -#include + #include + #ifdef USE_LittleFS + #define SPIFFS LITTLEFS + #include + #else + #include + #endif + #include + #include + #include #elif defined(ESP8266) #ifdef USE_LittleFS #include diff --git a/examples/SmartSwitch/SmartSwitch.ino b/examples/SmartSwitch/SmartSwitch.ino index 4244e29dc..a5e448c4b 100644 --- a/examples/SmartSwitch/SmartSwitch.ino +++ b/examples/SmartSwitch/SmartSwitch.ino @@ -13,7 +13,7 @@ Multiple clients can be connected at same time, they see each other requests Use latest ESP core lib (from Github) */ -#define USE_LittleFS // possible only for ESP8266 for now +#define USE_LittleFS #define USE_WFM // to use ESPAsyncWiFiManager //#define DEL_WFM // delete Wifi credentials stored @@ -41,7 +41,12 @@ Use latest ESP core lib (from Github) #include #ifdef ESP32 #include - #include + #ifdef USE_LittleFS + #define SPIFFS LITTLEFS + #include + #else + #include + #endif #include #include #include From 0de5612160d3bc15073acfe8bb78a0567f7288f0 Mon Sep 17 00:00:00 2001 From: lorol Date: Thu, 18 Jun 2020 13:31:25 -0400 Subject: [PATCH 059/551] Minor modification of edit.htm, which is embedded in SPIFFSEditor - allow to "download" with more file types by right-click on file tree. Tested LITTLEFS compatibility --- .../ESP_AsyncFSBrowser/data/acefull.js.gz | Bin 119986 -> 119986 bytes .../ESP_AsyncFSBrowser/data/worker-css.js.gz | Bin 35483 -> 35483 bytes .../ESP_AsyncFSBrowser/data/worker-html.js.gz | Bin 47406 -> 47406 bytes .../data/worker-javascript.js.gz | Bin 47729 -> 47729 bytes examples/SmartSwitch/data/acefull.js.gz | Bin 119986 -> 119986 bytes examples/SmartSwitch/data/worker-css.js.gz | Bin 35483 -> 35483 bytes examples/SmartSwitch/data/worker-html.js.gz | Bin 47406 -> 47406 bytes .../SmartSwitch/data/worker-javascript.js.gz | Bin 47729 -> 47729 bytes examples/SmartSwitch/data_src/.exclude.files | 2 + src/edit.htm | 16 +- src/edit.htm.gz.h | 454 +++++++++--------- 11 files changed, 245 insertions(+), 227 deletions(-) create mode 100644 examples/SmartSwitch/data_src/.exclude.files diff --git a/examples/ESP_AsyncFSBrowser/data/acefull.js.gz b/examples/ESP_AsyncFSBrowser/data/acefull.js.gz index 373060858ebd1d1e27f5489917f59a039dda37d1..1c60522393af9280fd007d1cbd4b180ac3f4943c 100644 GIT binary patch delta 21 dcmdnAl6})kc6Rx04vtR?UpKOEWoKM{1pr=e2*>~c delta 21 dcmdnAl6})kc6Rx04vurbZZxuQWoKM{1pr@=2Imup delta 18 acmezPh3VrLCU*I54vurbZfs=F+64eur3nlG diff --git a/examples/SmartSwitch/data/acefull.js.gz b/examples/SmartSwitch/data/acefull.js.gz index 373060858ebd1d1e27f5489917f59a039dda37d1..1c60522393af9280fd007d1cbd4b180ac3f4943c 100644 GIT binary patch delta 21 dcmdnAl6})kc6Rx04vtR?UpKOEWoKM{1pr=e2*>~c delta 21 dcmdnAl6})kc6Rx04vurbZZxuQWoKM{1pr@=2Imup delta 18 acmezPh3VrLCU*I54vurbZfs=F+64eur3nlG diff --git a/examples/SmartSwitch/data_src/.exclude.files b/examples/SmartSwitch/data_src/.exclude.files new file mode 100644 index 000000000..1d600fd29 --- /dev/null +++ b/examples/SmartSwitch/data_src/.exclude.files @@ -0,0 +1,2 @@ +*.gz +.exclude.files diff --git a/src/edit.htm b/src/edit.htm index c1ca544c8..4943b8ba1 100644 --- a/src/edit.htm +++ b/src/edit.htm @@ -274,7 +274,7 @@ t.loadUrl(i), document.body.getElementsByClassName("cm").length > 0 && document.body.removeChild(e) }); var d = ce("li"); - o.appendChild(d), s(i) || r(i) ? (d.innerHTML = "Download", d.onclick = function(t) { + o.appendChild(d), s(i) || r(i) || k(i) ? (d.innerHTML = "Download", d.onclick = function(t) { n(i), document.body.getElementsByClassName("cm").length > 0 && document.body.removeChild(e) }) : z(i) ? (o.appendChild(d), d.innerHTML = "ChDir", d.onclick = function(t) { f.removeChild(f.childNodes[0]), m(f, i), document.body.getElementsByClassName("cm").length > 0 && document.body.removeChild(e) @@ -357,6 +357,20 @@ } return !1 } + + function k(e) { // other types may be there and good for download + var t = /(?:.([^.]+))?$/.exec(e)[1]; + if (void 0 !== typeof t) switch (t) { + case "ico": + case "gz": + case "zip": + case "wav": + case "mp3": + case "pdf": + return !0 + } + return !1 + } function l(e) { return function(e, t) { diff --git a/src/edit.htm.gz.h b/src/edit.htm.gz.h index 634c6824d..c890b787e 100644 --- a/src/edit.htm.gz.h +++ b/src/edit.htm.gz.h @@ -1,229 +1,231 @@ -//File: edit.htm.gz, Size: 4469 -#define edit_htm_gz_len 4469 +//File: edit.htm.gz, Size: 4503 +#define edit_htm_gz_len 4503 const uint8_t edit_htm_gz[] PROGMEM = { -0x1F,0x8B,0x08,0x08,0xC2,0xFA,0xD8,0x5E,0x02,0x00,0x65,0x64,0x69,0x74,0x2E,0x68,0x74,0x6D,0x00,0xB5, -0x1A,0x09,0x5B,0xDB,0x36,0xF4,0xAF,0x18,0x6F,0x63,0xF6,0xE2,0x38,0x0E,0x50,0xD6,0x39,0x18,0x16,0x8E, -0x8D,0x5E,0x40,0x49,0x68,0x47,0x19,0xDB,0xA7,0xD8,0x4A,0xAC,0x62,0x4B,0x9E,0x2D,0x13,0x68,0x9A,0xFF, -0xBE,0x27,0xC9,0x27,0x84,0xEE,0xF8,0xB6,0x76,0x6B,0x24,0x3D,0x3D,0xE9,0xDD,0x87,0x92,0x9D,0xB5,0xC3, -0xD3,0x83,0xF1,0xE5,0xD9,0x91,0x16,0xF2,0x38,0xDA,0xDD,0x11,0xFF,0x6A,0x11,0xA2,0x33,0x4F,0xC7,0x54, -0xDF,0xDD,0x89,0x31,0x47,0x00,0xE2,0x49,0x17,0xFF,0x91,0x93,0x5B,0x4F,0x3F,0x60,0x94,0x63,0xCA,0xBB, -0xFC,0x3E,0xC1,0xBA,0xE6,0xAB,0x99,0xA7,0x73,0x7C,0xC7,0x7B,0x02,0x79,0xA0,0xF9,0x21,0x4A,0x33,0xCC, -0xBD,0x9C,0x4F,0xBB,0xCF,0xE1,0x08,0x4E,0x78,0x84,0x77,0x8F,0x46,0x67,0xDA,0x51,0x40,0x38,0x4B,0x77, -0x7A,0x6A,0x65,0x27,0x22,0xF4,0x46,0x4B,0x71,0xE4,0xE9,0x28,0x49,0x22,0xDC,0xE5,0x2C,0xF7,0xC3,0x2E, -0x81,0x33,0x75,0x2D,0x4C,0xF1,0xD4,0xD3,0x7B,0xC8,0xC7,0x36,0x2C,0xE8,0x9A,0xB8,0xCE,0xD3,0x49,0x8C, -0x66,0xB8,0x77,0xA7,0xF6,0x34,0x0F,0xC8,0x42,0x96,0x72,0x3F,0xE7,0xDA,0xBF,0xC2,0xFE,0x07,0x48,0x19, -0xBF,0x8F,0xB0,0x02,0x29,0x9E,0xFD,0x2C,0xD3,0xB5,0x18,0x07,0x04,0x01,0x15,0x7E,0x8A,0x85,0xD4,0x22, -0x34,0xC1,0xD1,0x62,0xCA,0x40,0x4C,0x19,0xF9,0x84,0xDD,0xFE,0x46,0x72,0x37,0x90,0xD3,0x29,0x8A,0x49, -0x74,0xEF,0x66,0x88,0x66,0xDD,0x0C,0xA7,0x64,0xBA,0xB4,0xFD,0x78,0xF1,0xA9,0x4B,0x68,0x80,0xEF,0xDC, -0x4D,0xC7,0x19,0x24,0x2C,0x23,0x9C,0x30,0xEA,0xA2,0x49,0xC6,0xA2,0x9C,0xE3,0x41,0x84,0xA7,0xDC,0x7D, -0x06,0x27,0x4C,0x58,0x1A,0xE0,0xD4,0xED,0x27,0x77,0x1A,0x80,0x48,0xA0,0x7D,0xB5,0xB5,0xB5,0x35,0x98, -0x20,0xFF,0x66,0x96,0xB2,0x9C,0x06,0x5D,0x9F,0x45,0x2C,0x75,0xBF,0x9A,0x3E,0x13,0x7F,0x07,0x01,0xC9, -0x92,0x08,0xDD,0xBB,0x94,0x51,0x0C,0xB8,0x77,0xDD,0x2C,0x44,0x01,0x9B,0xBB,0x8E,0xE6,0x68,0x7D,0x07, -0x0E,0x49,0x67,0x13,0x64,0x38,0x96,0xF8,0x6B,0x6F,0x99,0x83,0xBF,0x45,0xAF,0x5A,0x9E,0x63,0x32,0x0B, -0xB9,0xFB,0xBD,0xE3,0x08,0xFA,0xB5,0x3C,0x5A,0x44,0x24,0xE3,0x5D,0x29,0x1C,0x75,0x1F,0x67,0x89,0xEB, -0x48,0xD2,0xE1,0x23,0x46,0xE9,0x8C,0x50,0x18,0x24,0x28,0x08,0x08,0x9D,0xB9,0x0A,0x2D,0x22,0x8B,0x8A, -0x5B,0xD0,0x03,0xE2,0xE4,0x16,0x0F,0x62,0x42,0xBB,0x73,0x12,0xF0,0xD0,0xDD,0x76,0x80,0x0A,0x3F,0x4F, -0x33,0xE0,0x29,0x61,0x84,0x72,0x9C,0x4A,0xB4,0x2C,0x41,0x74,0xA1,0x58,0x15,0x02,0xA8,0xF8,0x24,0x14, -0x34,0x8A,0xBB,0x93,0x88,0xF9,0x37,0xD5,0x4D,0xDB,0xC9,0x5D,0x71,0x97,0x1B,0xB2,0x5B,0x9C,0x2E,0x6A, -0x71,0x49,0xEC,0x16,0xB0,0x75,0x34,0xC6,0x78,0x69,0xF3,0xDB,0x1C,0xA0,0x96,0xFC,0x04,0x2E,0x2B,0xFA, -0x6B,0x96,0xDA,0x8C,0x17,0x28,0x84,0x26,0x39,0x5F,0x3C,0x56,0x25,0x4B,0x90,0x4F,0xF8,0xBD,0xEB,0xC8, -0x6D,0xD2,0x42,0xDC,0x2D,0xC7,0xD1,0x84,0xC0,0xB5,0x77,0x38,0x0D,0x10,0x45,0xD6,0x30,0x25,0x28,0xB2, -0x46,0xB5,0xC8,0xBB,0x31,0xFB,0xD4,0xCD,0x61,0x0C,0xF3,0x08,0xFB,0x5C,0x49,0x18,0x94,0x30,0xB9,0x21, -0xFC,0x31,0xE0,0xD1,0x42,0x43,0x56,0x52,0x42,0xA1,0xD2,0x5E,0x1F,0x64,0x23,0xE9,0x50,0x6C,0x2B,0x8E, -0xBA,0x13,0xC6,0x39,0x8B,0xA5,0xBD,0x55,0xDC,0x6A,0xD2,0x64,0x9E,0x3F,0x52,0xC7,0x6A,0xD1,0x37,0x8E, -0x1F,0x80,0x50,0x39,0xF1,0x51,0xD4,0x45,0x11,0x99,0x51,0x37,0x26,0x41,0x10,0xE1,0x41,0x43,0x07,0x79, -0x1A,0x19,0x01,0xE2,0xC8,0x55,0x7E,0x96,0xD0,0x19,0x40,0x33,0xBC,0xBD,0x65,0x91,0x77,0xFB,0xA7,0xE7, -0x73,0xE7,0xD5,0xCF,0x33,0x36,0x84,0x3F,0x27,0xA3,0x8B,0xF0,0xE8,0x62,0x06,0xA3,0x7D,0x31,0x1D,0xBE, -0x3D,0x18,0xBE,0x85,0x8F,0x83,0x7E,0xE7,0xE3,0xF4,0x8F,0xA1,0x58,0xFE,0x39,0xD8,0x1F,0x5F,0x1C,0x0D, -0x87,0xAF,0x7A,0x2F,0x4E,0xE6,0xEF,0x5F,0x6D,0x0B,0xF0,0x7E,0xE4,0x9C,0xBF,0x0B,0x9D,0x8B,0x8D,0x1F, -0xE2,0xE0,0x38,0x08,0xFD,0xF8,0x62,0xF8,0xF6,0xFD,0xF9,0xED,0x65,0x7C,0x31,0x1B,0xBD,0xEF,0x87,0x1F, -0x36,0xDE,0x8D,0x3E,0xBC,0xFF,0xE9,0x06,0xFF,0x72,0xFC,0xF2,0xC3,0x78,0x0E,0x08,0x87,0x6C,0x74,0x71, -0xBE,0xFF,0x6E,0x7F,0xF6,0x61,0xDF,0x3F,0xBA,0x9B,0x44,0x27,0xFB,0x3F,0x0F,0x27,0xC3,0x0D,0x1F,0xE3, -0xD9,0xF8,0x7C,0x3F,0x7F,0xF1,0xEA,0x74,0x46,0x48,0x38,0xFA,0x70,0x32,0xF6,0x0F,0x9E,0xBD,0xBE,0x38, -0x1E,0x92,0xF0,0xE4,0xE5,0xB9,0x73,0xF3,0xF3,0xAB,0x83,0x43,0xFF,0xF2,0xE5,0xE5,0xF6,0xE1,0x66,0xEF, -0xFB,0xEF,0xDF,0x04,0xA7,0x84,0x8E,0x6F,0x3F,0x0D,0x67,0x07,0xF3,0xE7,0xF7,0xD9,0x38,0x7C,0x71,0x4B, -0x7B,0xEF,0xD8,0xC7,0x17,0xF7,0x6F,0xE0,0xFF,0xB3,0xB3,0xCE,0x64,0xD4,0xCF,0x2E,0xDE,0xBE,0x78,0xB7, -0x91,0xFD,0xF0,0x2C,0xD9,0x3F,0x3C,0xBC,0x8D,0x27,0x67,0xBD,0x38,0xB8,0x99,0xF2,0xE7,0x9B,0x3C,0xB9, -0x9C,0xE5,0x1F,0xFE,0x78,0xF6,0x32,0xEC,0x9D,0x62,0x74,0x19,0x76,0xEE,0x3F,0xDD,0x3F,0x0F,0xC7,0xC7, -0xB7,0x27,0x11,0xBA,0x3B,0x39,0xF1,0x3F,0xC5,0x9D,0x08,0xFD,0x70,0x3A,0x8E,0x50,0xDA,0xBF,0x08,0x86, -0xBD,0xCE,0xC1,0xC6,0x70,0x8B,0xA7,0xE7,0x07,0xF4,0x70,0xF3,0xE3,0xE8,0xF9,0xFE,0x7E,0x9F,0x4D,0xFE, -0xD8,0xF8,0xF9,0x66,0xFB,0xE7,0x8B,0xED,0xB7,0x93,0xB7,0xC3,0xD1,0xD6,0xFE,0x05,0xBA,0x1C,0xBD,0x1D, -0x4E,0xB7,0x26,0x61,0xF8,0xEA,0xD5,0xF8,0xA7,0x60,0xF8,0x29,0x1D,0x9E,0xCE,0x87,0x77,0x47,0x17,0xC3, -0xE3,0xCE,0xAB,0xA3,0x37,0x4E,0x7F,0x74,0xB9,0x39,0x7B,0xB3,0x3D,0xDF,0xCF,0x8E,0x86,0x6F,0xF7,0x9D, -0xD9,0xCB,0x4E,0x8C,0x3E,0xB0,0x83,0xCD,0xD9,0x8B,0x6D,0x72,0x76,0x89,0x86,0x2F,0xF6,0x5F,0x66,0xE4, -0x3C,0x3E,0xBE,0x70,0x86,0xC3,0xD7,0xA7,0xF8,0xA7,0x83,0x4D,0xF4,0x6A,0xC3,0x7F,0x0F,0xF2,0xBF,0xF8, -0x05,0x7F,0xDF,0x19,0xCE,0x4F,0x9D,0xC8,0xFF,0x01,0x8F,0x8F,0x2F,0xC7,0x52,0x3B,0x47,0xD1,0x4F,0xE3, -0x9B,0x51,0xFE,0x36,0x3E,0x38,0x30,0x35,0xCA,0xBA,0x29,0x4E,0x30,0xE2,0xCD,0x58,0x55,0x39,0x07,0xD8, -0x56,0x6D,0x85,0x85,0x93,0x8A,0xC8,0xDA,0x0D,0xB0,0xCF,0x52,0x24,0xF7,0x00,0x02,0x4E,0x85,0x89,0x2D, -0x7F,0x94,0xA1,0x56,0x53,0x91,0x56,0x43,0x34,0xD0,0x8C,0xD2,0x11,0x62,0x42,0x01,0xE7,0x96,0xF8,0xB8, -0x9B,0x90,0x3B,0x1C,0x75,0x25,0xB2,0xEB,0x98,0x0B,0xE9,0x6C,0xE5,0x36,0x44,0x49,0xAC,0x4E,0x2D,0x17, -0x82,0x8F,0xC8,0x17,0x29,0x0D,0x5C,0x26,0x86,0xCF,0xC2,0x77,0x58,0xDA,0x9D,0xE4,0xB3,0x29,0xB9,0x03, -0x6F,0x9E,0x12,0x4A,0x38,0xD6,0xFA,0xD9,0xF2,0xC7,0xF2,0x98,0x1B,0x7C,0x3F,0x4D,0x51,0x8C,0x33,0xED, -0x6F,0x1E,0xB3,0x98,0xA6,0x2C,0x5E,0xD4,0x11,0x90,0xB3,0xC6,0x64,0xB9,0xFC,0x2A,0x4F,0x22,0x86,0x80, -0xCD,0x15,0x61,0x43,0x05,0xD3,0x54,0xB8,0x55,0x15,0x54,0x4B,0x37,0xDB,0x00,0xB7,0x6C,0xB9,0xF5,0xC6, -0x56,0xED,0xBA,0x5D,0xB9,0x57,0x04,0xFB,0xA6,0xE8,0x1B,0xF1,0xA0,0x11,0xEB,0xBE,0xE2,0x20,0xD2,0xD5, -0x97,0xAB,0x4B,0x54,0x64,0xA8,0x09,0x50,0x51,0xBA,0xBF,0xED,0x34,0x42,0x05,0xEC,0x5B,0x7E,0x85,0x65, -0x9A,0xB7,0xBE,0x4A,0x52,0xD0,0x06,0x9E,0x7F,0xE1,0xCC,0x8A,0xA7,0xF6,0xD9,0x70,0x66,0x95,0xEE,0x14, -0x0B,0x75,0xCE,0x93,0xB4,0x56,0x47,0x3F,0xE6,0x0A,0xC0,0x15,0x35,0xCF,0x04,0x35,0x5F,0x94,0xEA,0xE6, -0xF6,0x37,0x05,0x0D,0x5B,0xCE,0x37,0x4B,0x5B,0xED,0xAD,0xF2,0x71,0xDF,0x81,0x3F,0x65,0xDA,0x7D,0x5E, -0x93,0x30,0x79,0x26,0xFE,0x96,0x04,0xC2,0x39,0x4D,0xE0,0xE6,0xD6,0x0F,0xCF,0x83,0x49,0x09,0x54,0x8C, -0x3D,0x0D,0x4F,0x51,0x40,0xF2,0xCC,0x7D,0xE6,0x7C,0xA3,0xE4,0x09,0xEA,0x03,0xDE,0x4B,0xE5,0xAA,0x49, -0x6D,0xB1,0x59,0x42,0xA8,0xB6,0x91,0x69,0x42,0xDF,0x28,0xAD,0x0C,0xB3,0x99,0xEA,0xC1,0x45,0x6A,0xD3, -0x14,0xFB,0x17,0xCE,0x37,0x0B,0x9E,0x22,0x9A,0x4D,0x59,0x1A,0xBB,0x29,0xE3,0x88,0x63,0xC3,0x31,0x97, -0x7D,0x67,0x15,0x60,0x73,0xDB,0x09,0xF0,0xCC,0x5C,0x2E,0x77,0x7A,0x32,0xA9,0x41,0xC5,0xE3,0xA7,0x24, -0xE1,0xBB,0xD3,0x9C,0xFA,0x82,0x06,0x6D,0x86,0x0D,0x6C,0x2E,0x52,0xCC,0xF3,0x94,0x6A,0x01,0xF3,0x73, -0x61,0xEC,0xF6,0x0C,0xF3,0x23,0x65,0xF7,0xFB,0xF7,0x2F,0x02,0xD8,0xB1,0xAC,0x10,0xFC,0x95,0x08,0xE0, -0xC0,0x70,0x5F,0x81,0xD3,0xDA,0x0F,0x09,0x06,0x0E,0x79,0x85,0xEF,0x0D,0x6C,0xF1,0x0A,0x11,0xDB,0x62, -0xDD,0x30,0xCA,0x6D,0x00,0xA4,0xE6,0xE2,0x16,0xA4,0x80,0x3C,0x7C,0xC5,0xAF,0x2D,0xE2,0x51,0xF8,0x18, -0x14,0xDB,0xC9,0x2E,0xDA,0xEB,0xF6,0x5D,0xB4,0x4B,0xF6,0xFA,0xE0,0x5F,0x66,0xE3,0x7C,0x75,0xF3,0x4F, -0x24,0xC2,0x17,0x85,0xCB,0x89,0x8B,0xEA,0xD3,0x7A,0x06,0x39,0x0B,0x41,0x90,0xE6,0x77,0xC6,0xE9,0x48, -0x33,0xAE,0xBE,0xEF,0xFE,0x70,0xFD,0xB9,0x7F,0xE5,0x74,0xFB,0xD7,0xE6,0xEF,0x66,0x8F,0xD8,0x1C,0x67, -0xDC,0xA0,0xE8,0x96,0xCC,0x10,0xD8,0xB9,0x2D,0xF2,0xED,0x70,0x06,0x5C,0x98,0x83,0xEA,0x0E,0xA2,0xC8, -0xDB,0x70,0x9C,0x35,0x0F,0xEF,0xA1,0x08,0x03,0xE9,0xFA,0xD1,0xF9,0xF9,0xE9,0xF9,0x95,0xDE,0xC1,0x1D, -0xFD,0xDA,0xD5,0xF4,0x0E,0x35,0x5D,0x6E,0x43,0xD1,0x99,0xE2,0x2C,0x3C,0x43,0x3C,0x34,0x02,0xFB,0x16, -0x45,0x39,0xC8,0x42,0x10,0xC2,0x3C,0x10,0x9C,0x3E,0xC9,0x39,0x67,0x54,0x37,0x07,0xCC,0x26,0x94,0xE2, -0xF4,0x78,0xFC,0xE6,0xB5,0xA7,0x9F,0x33,0xC6,0xB5,0x43,0x92,0xEA,0x96,0xD4,0x86,0x8D,0x92,0x04,0xD3, -0xE0,0x20,0x24,0x51,0x60,0x30,0x73,0x20,0xD0,0x7D,0x89,0x2E,0x0B,0x11,0xC0,0xF6,0x6D,0x55,0xB2,0x4E, -0x81,0x6B,0xDD,0xF2,0xED,0x38,0x8F,0x38,0x49,0x22,0xEC,0xAD,0xF5,0x61,0x46,0x51,0x0C,0x30,0x91,0x86, -0x05,0x8C,0x04,0x9E,0xAE,0x82,0x51,0x11,0xC2,0x56,0xDD,0xE2,0xAB,0x5B,0x82,0xD6,0x2D,0x41,0x13,0x37, -0x01,0x8E,0x74,0x2B,0xB0,0xEB,0x5A,0x19,0x66,0xC5,0x55,0x25,0x2C,0xC0,0x53,0x04,0x94,0xBC,0x13,0x5C, -0x43,0xE9,0xBD,0xEA,0xA2,0x40,0x5D,0x94,0xB5,0xA5,0x91,0x35,0xA5,0xA1,0xD4,0xB8,0x0A,0x39,0x53,0xC8, -0x69,0x1B,0x39,0x6D,0x22,0x1F,0x48,0x6B,0x58,0x85,0x9C,0x2A,0xE4,0xA8,0xC5,0x62,0x24,0x59,0x54,0x11, -0xAE,0x2B,0xA4,0x09,0x0C,0x01,0x76,0xD4,0x64,0x13,0x66,0xE0,0x90,0x68,0x12,0xE1,0xC0,0x5B,0x73,0x60, -0x26,0x8A,0x6A,0x6F,0xC3,0x59,0x71,0x47,0xA4,0xEE,0xC8,0x5B,0x77,0xE4,0xF2,0x0E,0x92,0x80,0x10,0x21, -0x6F,0xE8,0x56,0x2E,0xA5,0xD6,0x5E,0x51,0xD7,0xF9,0x21,0xF6,0x6F,0x26,0x4C,0xAE,0xC8,0xB1,0xB8,0x71, -0x0D,0xC9,0x33,0x13,0x79,0xA6,0x6C,0x45,0xE0,0xCC,0xC4,0x06,0x2F,0xF7,0xC4,0xC9,0x56,0xD2,0x64,0x5F, -0x1B,0x46,0xDC,0xD6,0x25,0x42,0xDC,0x96,0x52,0xDC,0xDA,0x36,0x42,0xB7,0x58,0x5B,0x25,0xA5,0xD8,0x5C, -0xB1,0x98,0xAC,0x5A,0xCC,0x4D,0x2B,0xB5,0x19,0xF5,0x23,0xE2,0xDF,0x78,0xB5,0x1B,0x9B,0x0B,0xA3,0x39, -0x11,0x94,0x70,0x8F,0xE2,0xB9,0xF6,0x13,0x84,0xA5,0x43,0xC4,0xD1,0x80,0x17,0xC7,0x18,0x85,0xDD,0x60, -0x38,0x08,0xBA,0x51,0xF0,0xC2,0xCC,0x46,0x01,0x2C,0x9F,0x5D,0x8C,0x75,0x4B,0xEF,0x09,0xAD,0xE8,0xE0, -0xC9,0xC4,0x5C,0x9A,0x95,0x2F,0x59,0x54,0x46,0xF5,0x8B,0x34,0xAA,0x97,0x60,0x50,0x5A,0xDC,0xD2,0x8A, -0x57,0xD2,0x44,0xA6,0x46,0x25,0xD2,0x92,0x28,0xD1,0x19,0x8A,0x3B,0x8C,0x42,0xFF,0xBA,0x09,0x61,0x4F, -0x19,0xAF,0x61,0x5A,0xA8,0x4D,0x34,0xAA,0x88,0x4E,0xD1,0xBC,0x34,0x12,0x75,0xFF,0x40,0xB9,0xB7,0x03, -0xD9,0x97,0x66,0x5C,0xC3,0xDE,0x96,0xF3,0xC3,0xF6,0x00,0xF4,0x63,0x28,0xC7,0x05,0xC0,0x0E,0xB7,0xC1, -0xB4,0x66,0x3C,0x1C,0xF8,0x1D,0xAF,0x90,0x4A,0xE0,0x71,0x3B,0xCB,0x27,0x19,0x4F,0x21,0xB7,0x19,0xBE, -0xE5,0x77,0xB0,0xD9,0xBE,0x46,0xEF,0x30,0x2B,0x30,0x2D,0xD6,0xE9,0x2C,0x1F,0x08,0xE8,0x74,0xD4,0x90, -0x10,0x12,0x12,0xC2,0x51,0x86,0x35,0x6A,0xE3,0x3B,0xEC,0x1F,0xB0,0x38,0x46,0xE2,0x88,0x0C,0x94,0x5C, -0x4C,0x74,0x73,0x69,0xB1,0x95,0x92,0x79,0x22,0x64,0x59,0xD9,0x53,0x72,0x84,0x10,0xE8,0xF9,0xB6,0xF0, -0x95,0xAC,0x60,0xEA,0xCB,0x5A,0x2E,0x03,0x91,0x42,0xB9,0x72,0xAE,0xAD,0x4A,0x71,0x2B,0xB9,0xAA,0xF5, -0x2E,0xAD,0xAE,0x15,0x7F,0xCC,0x5A,0xD3,0x02,0xD6,0x8E,0x6B,0x35,0x54,0x5F,0x2E,0x2D,0x5F,0xD0,0x1F, -0x22,0x3A,0xC3,0x7F,0x9F,0x81,0x9A,0x46,0xE9,0xA2,0x16,0x85,0xE4,0xB1,0xE7,0xFE,0x6A,0x1B,0x57,0xBF, -0xD9,0xD7,0x1D,0xD3,0xDC,0xFB,0xBA,0x27,0x25,0x6C,0x70,0xF3,0xAA,0x7F,0x6D,0x21,0x00,0xDB,0xDF,0x99, -0xBF,0xDA,0x12,0xDC,0x82,0x0D,0x6E,0x19,0x09,0x34,0x71,0x93,0xF0,0x6C,0x36,0xD5,0xD0,0xFA,0xBA,0x01, -0x26,0xD7,0x32,0xD6,0x0E,0xEF,0xE8,0x36,0xE4,0x8D,0xE5,0xF2,0x61,0x36,0x1B,0xA7,0x18,0xAB,0x74,0x59, -0x01,0x24,0xF5,0xC0,0xF3,0xC3,0x60,0x55,0x71,0x8D,0xAD,0x1A,0x0A,0x8B,0x32,0xDD,0xDB,0x45,0x25,0xE1, -0xE9,0x94,0x51,0x30,0xD9,0xE4,0xE1,0xB2,0x6C,0xF1,0xF4,0x56,0x0C,0xF9,0x76,0x87,0xC4,0x33,0x2D,0x4B, -0x7D,0x4F,0xA9,0x62,0x4F,0xFC,0xE3,0x7D,0x2B,0xD2,0xDC,0xFA,0xEF,0xFE,0xC4,0xD3,0x3B,0xA0,0x5F,0x6C, -0x53,0x36,0x37,0xCC,0xCE,0xB7,0xBA,0x26,0x4F,0xF4,0xF4,0x18,0xDD,0x15,0x8D,0xBE,0xA8,0x44,0x06,0x1A, -0xCC,0xAB,0xCE,0x54,0x2D,0xA8,0x16,0x1B,0xE5,0x9C,0x0D,0xB4,0xB2,0xC2,0x51,0x2D,0xA6,0xAE,0xF5,0x76, -0xBF,0xAD,0x65,0x80,0x80,0x75,0xA4,0x74,0x42,0x64,0x10,0xCB,0x45,0xC8,0xC3,0xAD,0xE8,0x43,0x0A,0xB7, -0x53,0x51,0x91,0x00,0x9C,0x3C,0x48,0x9B,0x56,0x66,0x20,0x73,0xCF,0x68,0x25,0xDA,0x1D,0xD1,0x94,0xEC, -0x9E,0xA9,0x6A,0x73,0xA7,0x27,0x67,0xFA,0x2A,0xC7,0x00,0xC9,0x53,0x40,0xB7,0xAA,0xFA,0x66,0xC2,0x82, -0xFB,0x46,0x55,0x94,0xED,0xDF,0x1F,0x44,0x28,0xCB,0x4E,0x50,0x0C,0xF7,0xFB,0xB1,0x6E,0x16,0xA6,0xB4, -0xEB,0xAC,0xAF,0xB7,0x91,0x52,0x1C,0x43,0x13,0xA4,0xA8,0xC2,0x10,0xCA,0xDC,0x00,0x0E,0x5E,0x5F,0x5F, -0x45,0x98,0x78,0x50,0xFB,0x12,0x55,0x14,0xDC,0xB5,0x0C,0x7F,0xFF,0x13,0x75,0x2A,0x47,0x3E,0x25,0xD5, -0xC8,0xB4,0x04,0xF5,0x9F,0x3F,0x2B,0xD9,0x46,0x8F,0x59,0x38,0x64,0x73,0x2A,0x28,0xAC,0xD8,0x88,0x56, -0x08,0xB7,0xCE,0x11,0x95,0x55,0x07,0x05,0x5E,0x77,0x9A,0x2A,0xA3,0x6E,0x18,0x60,0x09,0x03,0xD3,0xC3, -0x4B,0xF3,0xFF,0x52,0x8B,0xAF,0xD4,0xF2,0x88,0xE1,0x15,0x4C,0x1E,0x84,0x50,0xAC,0xFD,0x05,0x87,0x71, -0xEB,0x86,0xD8,0xF6,0xC5,0xE7,0x09,0x0B,0x64,0x78,0x31,0xAD,0xDC,0x88,0xAD,0xFF,0x51,0x83,0x49,0x4B, -0x83,0xED,0x54,0x9E,0xAC,0xD0,0x1A,0x8E,0x30,0xC7,0x15,0x47,0xC9,0x4A,0x8E,0xD2,0xFF,0x47,0xF2,0xB5, -0xDF,0x13,0x55,0xB8,0x37,0x3D,0x3F,0x20,0xB7,0x3A,0x64,0x40,0xAF,0x7D,0x02,0xF4,0x30,0x2C,0x8A,0xC6, -0x2C,0xD9,0x7B,0x62,0xDD,0xAD,0xD6,0x8B,0x41,0x49,0x66,0xBD,0xC5,0xF2,0x57,0x1E,0xFA,0x1A,0x4F,0xF9, -0xDE,0x53,0x80,0xA7,0x8F,0xAD,0xF7,0x58,0x81,0x87,0x6D,0x10,0x1E,0xAC,0xFE,0xD2,0xF1,0xAD,0xAC,0x9A, -0x5D,0x76,0x18,0xE8,0xC2,0x2F,0x85,0xE4,0x09,0x21,0x59,0x64,0x65,0x40,0xAE,0xD7,0x45,0xB7,0xEC,0x05, -0x1D,0x3D,0xB9,0xAB,0xD7,0x38,0x4B,0xBC,0x4C,0x2D,0x21,0x83,0x58,0xFC,0x81,0x52,0x56,0x85,0xC9,0xD4, -0x23,0x36,0x9B,0x4E,0x33,0xCC,0xDF,0x8B,0x10,0x6D,0x45,0xD5,0xFC,0x58,0x86,0xE8,0x01,0x4C,0x69,0xCC, -0xF2,0x0C,0xB3,0x9C,0xB7,0x8B,0xB9,0x8A,0x99,0x9D,0xE0,0xF3,0xE7,0x6A,0xB2,0x1B,0x74,0xD2,0x7A,0x7A, -0xB9,0x93,0x35,0x26,0xBB,0x59,0x27,0x02,0x4F,0xFA,0x8F,0x2D,0x85,0x34,0x2D,0x85,0x89,0x0C,0x61,0x31, -0x65,0x29,0x69,0x6D,0xEB,0xA9,0x28,0xB5,0x51,0x23,0x86,0x09,0x83,0xD6,0xCD,0xB2,0x8B,0x6C,0xBA,0x32, -0xB2,0xD2,0xB6,0xA7,0x3F,0x55,0xCE,0x06,0x86,0x38,0x15,0xA4,0xFE,0x9A,0xCD,0x71,0x7A,0x80,0x32,0x6C, -0x40,0x25,0x50,0xC5,0x61,0x09,0x35,0xDD,0x6C,0xE5,0x2E,0x5A,0x40,0x7D,0xF5,0x09,0xE1,0xE5,0x8B,0x61, -0x01,0x36,0x88,0xB8,0xB0,0xE2,0x24,0x73,0xA9,0xA8,0x63,0x54,0xB4,0x24,0x20,0xA1,0xBC,0x45,0x23,0xB6, -0xC5,0x0B,0x0A,0xC8,0xED,0x50,0x75,0x60,0x50,0xBF,0x62,0xB0,0x16,0x96,0x9C,0xA5,0x2C,0x41,0x33,0x24, -0xF6,0xC1,0x1A,0x38,0x98,0x3C,0x5C,0x9C,0xD6,0x28,0x39,0xEA,0x7E,0xBE,0xDB,0xF7,0xC0,0x5E,0xE5,0x6B, -0xC9,0xE9,0xD4,0x80,0xE2,0xA4,0xD1,0x67,0x07,0x55,0x39,0x2F,0xAB,0xA2,0xC7,0x45,0x11,0x96,0x85,0x0F, -0x14,0x58,0x0F,0x6B,0x1F,0x6E,0x66,0x73,0xC2,0xFD,0x50,0x04,0x11,0x1F,0xF8,0xD1,0x39,0x74,0x55,0xAE, -0x1C,0x85,0x3C,0xAE,0x47,0x51,0x31,0xFC,0x98,0x15,0x03,0x3F,0x2B,0x47,0x77,0x0D,0x20,0xA3,0x25,0x98, -0xD1,0x69,0x31,0x24,0x94,0x94,0xE7,0x94,0xC0,0xF2,0x33,0x49,0x8A,0x51,0x12,0x96,0xA3,0x10,0xDF,0x55, -0x78,0xAC,0x84,0x06,0x58,0x77,0x95,0x14,0xD6,0x9C,0x65,0x31,0xE8,0xD7,0xEC,0x67,0xFF,0x1D,0xFB,0x09, -0x9D,0x95,0xCC,0x24,0xE5,0x68,0x46,0x4A,0x56,0x26,0x71,0xF2,0x45,0x42,0xD2,0x7F,0xDB,0x56,0x1D,0x1E, -0xBD,0x3E,0x1A,0x1F,0x35,0x2B,0xEC,0xE6,0xEB,0x0B,0xFF,0xAB,0xE7,0x0D,0x6E,0xBA,0xC6,0xDF,0x48,0x6A, -0x50,0xD7,0x9A,0x66,0xEB,0x81,0x26,0x6A,0x3D,0xFC,0xD4,0x19,0xA5,0x78,0x51,0x01,0x39,0xAD,0xAF,0x37, -0x08,0x91,0xEB,0xF5,0xA3,0x11,0xB5,0x74,0x55,0xE6,0x4A,0xAF,0x46,0x4F,0xD5,0x83,0xC8,0xAC,0x3A,0x2E, -0xE2,0xD1,0x22,0xA2,0x58,0xA2,0xF9,0x22,0xBB,0x3E,0x74,0x5D,0x1D,0x53,0x3D,0x96,0x78,0x9E,0x47,0xAF, -0xFC,0x6B,0xD9,0x70,0xAF,0xAF,0xA3,0x76,0xCD,0x68,0x38,0x96,0x04,0x8A,0x0B,0xE5,0x48,0xB6,0xFA,0xC0, -0x0B,0x90,0xE5,0x58,0x2F,0x47,0xA7,0x27,0x76,0x82,0x52,0x70,0x48,0x6A,0x36,0xA3,0x51,0xAE,0x18,0x6C, -0x4B,0xFB,0xE7,0xA3,0x46,0x33,0x23,0xBF,0x4F,0x73,0xF9,0xD2,0x8A,0x0C,0x71,0x9C,0xCA,0xD0,0xA2,0xEC, -0x29,0x1E,0x3E,0x21,0xC7,0xC5,0x65,0xBE,0xAB,0xC3,0x55,0xDC,0xCC,0x16,0xFC,0x36,0x7F,0xA2,0x5F,0xE7, -0x21,0xC9,0x9A,0x4D,0x5C,0x2B,0x32,0xFC,0x4D,0x8D,0x2D,0xCB,0x91,0x3A,0xEE,0x61,0x3F,0xA2,0xBE,0xE9, -0x55,0xCA,0x91,0xFD,0x66,0xDD,0x97,0xB0,0xDA,0x1C,0x75,0x48,0x61,0x84,0xEA,0x16,0xFD,0xA7,0x1E,0x42, -0x4B,0x0F,0xA1,0x8F,0x03,0x04,0xBE,0x6B,0x79,0x7B,0x75,0xCB,0x60,0x02,0x94,0xDD,0x0C,0xAA,0x28,0x02, -0x10,0x19,0x43,0x5A,0x80,0x8F,0x99,0x5C,0xFF,0x88,0x6E,0x91,0x7A,0xF7,0xAC,0xA1,0xAB,0x43,0x85,0xDC, -0xEE,0xFF,0x0E,0xA3,0x6A,0x67,0x3B,0x10,0x65,0x30,0x7C,0x1C,0x4F,0x78,0x2B,0x3C,0xD5,0x31,0xAB,0x19, -0x9D,0xC0,0x5D,0x97,0x85,0x62,0x79,0x43,0xBE,0x0D,0xD7,0x03,0x83,0x7C,0xCA,0xF7,0x9A,0x71,0x58,0x61, -0x34,0xAD,0x67,0x75,0xB7,0xD7,0xEE,0x07,0x57,0xD7,0x19,0xD2,0xFF,0xF0,0x5E,0x66,0x67,0xE5,0xCB,0x07, -0xB8,0x79,0x63,0xA6,0x83,0x41,0x64,0x60,0x86,0x18,0xA5,0x23,0xD1,0x64,0xAB,0x44,0xB2,0x54,0x0A,0xF4, -0xA4,0xEB,0x1A,0x20,0xB1,0x9E,0x4C,0x19,0x36,0xC8,0x01,0xF6,0x57,0x40,0x0A,0x40,0xEA,0x31,0x38,0xB2, -0xB1,0x88,0x60,0x11,0x41,0xBB,0xC8,0x28,0xBB,0x41,0xA4,0xB9,0x9D,0x00,0x84,0x14,0x5F,0xC3,0x43,0x57, -0x6C,0x15,0x7A,0x90,0x07,0xD5,0x10,0xA5,0x7D,0xB3,0x78,0x46,0xAC,0x1F,0x71,0x70,0xE9,0x36,0x85,0x7D, -0xAC,0x49,0xB4,0x4C,0x14,0x1E,0x23,0x9C,0x65,0x92,0x6E,0xC1,0xD7,0x1B,0x16,0x00,0x5B,0x80,0xD6,0x8B, -0x61,0x24,0x2E,0x02,0x0E,0x05,0x60,0x1C,0xE2,0xB8,0x80,0x70,0x18,0x0A,0x10,0x12,0xA0,0xAF,0xA5,0xA8, -0x46,0xB2,0xC0,0x23,0x74,0xE6,0xF5,0x7B,0x8E,0xF5,0xF8,0xD8,0x8B,0x0C,0x8F,0xD8,0x94,0x8F,0xD1,0x24, -0x33,0xD6,0x1C,0x73,0xC5,0x0E,0x00,0x8D,0x20,0x9A,0x18,0x1B,0xE6,0x6A,0xF4,0xF7,0x2C,0xBD,0xC1,0x69, -0x81,0x2C,0x2A,0x33,0x28,0xCC,0x22,0x51,0x9C,0x0D,0x41,0xEA,0xB7,0xF8,0x35,0xA1,0xB8,0x06,0x8E,0x42, -0x36,0x3F,0x4B,0x09,0xE5,0x6F,0x64,0x57,0x6D,0xAC,0xF5,0xA5,0x9E,0xD4,0x63,0x8F,0x8C,0x40,0xE5,0x2B, -0xD0,0x42,0x04,0x33,0xB7,0xF5,0x16,0x64,0x4D,0x40,0x5D,0x10,0x5B,0xDD,0xC5,0x9C,0x50,0x57,0x3F,0xE0, -0x69,0xD4,0x1D,0xE9,0x56,0x8C,0x7C,0x98,0xA8,0x3D,0x30,0x5F,0x5A,0xC2,0x69,0xDD,0x66,0x30,0x59,0xAB, -0x27,0x75,0xA1,0xBE,0xF2,0xA1,0xAC,0x7E,0xF7,0x11,0xC0,0xFD,0x88,0x4D,0x0C,0xF1,0xA8,0xBF,0x10,0x0E, -0xEF,0xD2,0xA5,0x29,0xB2,0xD3,0x97,0xDF,0xB4,0x7C,0x88,0xBA,0xDC,0xC2,0x8D,0x27,0xB9,0x8E,0xAE,0x8B, -0x97,0x2E,0xC0,0x43,0xC1,0x29,0x8D,0xEE,0x5D,0xC8,0x8A,0x7F,0xC1,0x75,0x4E,0x03,0xF6,0x25,0xAE,0x3F, -0x3C,0xE0,0xFA,0xC3,0x2A,0xAE,0x71,0x5B,0x5B,0x30,0xB9,0x80,0x63,0xDF,0x20,0x8A,0x66,0x38,0x85,0x05, -0x71,0x09,0x28,0xE0,0x9F,0x51,0x96,0xE2,0x2F,0x53,0x36,0x0A,0xC9,0x94,0x3F,0xA4,0x4F,0xAD,0xFE,0x3B, -0x2A,0x53,0xFC,0x04,0x95,0x65,0x21,0x5B,0xA5,0x8D,0xBF,0x7E,0x68,0x92,0x4E,0xED,0x81,0x0A,0x9B,0xEE, -0xFA,0x2F,0xFC,0xAE,0xBE,0xF1,0xCB,0xD9,0x53,0x7C,0xB8,0x78,0x69,0x05,0xC2,0x26,0x80,0x83,0x46,0x7E, -0x62,0x74,0x1F,0x3A,0x85,0xD7,0xC0,0x82,0xA1,0xCC,0x11,0x7B,0x8B,0xA5,0xC5,0x3D,0x63,0x4E,0x80,0xFD, -0x39,0x30,0xE7,0xCB,0xEA,0xD7,0x0E,0x21,0x43,0x82,0x10,0x80,0x48,0xC8,0xB3,0xBD,0xAB,0xBD,0xF5,0xEB, -0x0E,0x24,0x28,0x0F,0x3E,0x4C,0x0F,0x06,0xEB,0xD7,0xDF,0x99,0xBD,0x19,0x69,0x94,0x44,0x32,0xD5,0x81, -0x5C,0xAF,0xE8,0xB5,0x87,0x96,0x10,0xC2,0x9A,0xA9,0xB0,0x0A,0xAC,0x16,0x96,0x6F,0x86,0xF0,0x11,0x21, -0x3A,0x83,0x0F,0x19,0x3B,0x60,0x37,0xF5,0x1A,0x4F,0x79,0x3A,0x87,0x7F,0x75,0x08,0xDB,0x83,0x82,0xAC, -0x00,0x4F,0x09,0xC5,0x32,0x7A,0xA9,0xA1,0x55,0x00,0x84,0x18,0x48,0x2A,0x21,0xE5,0xD8,0x12,0x63,0x91, -0xFD,0xC8,0x4C,0x08,0xD2,0xD0,0x27,0x28,0xC3,0x22,0xD1,0xEB,0x32,0x61,0x3F,0x02,0xCF,0x65,0x20,0x69, -0x6C,0x58,0xF1,0x0D,0x99,0x9E,0x17,0x23,0x1D,0xB8,0xE4,0x8D,0x20,0xAC,0xD8,0x81,0x78,0xAB,0x06,0x0F, -0x42,0x7B,0xDD,0xF5,0x28,0xB0,0xB9,0x04,0x17,0x53,0x0C,0x04,0x7A,0x95,0xCE,0x7F,0x79,0xF3,0xFA,0x98, -0xF3,0xE4,0x5C,0x69,0x14,0xCE,0x6A,0x2F,0xD4,0x86,0x66,0x2E,0x78,0x7A,0x5F,0x16,0x86,0x22,0x50,0xA8, -0x50,0xF7,0xCB,0xE9,0xE4,0x23,0xF6,0x81,0x93,0x37,0x19,0xE4,0xD0,0x0D,0x5B,0xA0,0x8F,0xC7,0x67,0xF6, -0xB6,0xED,0x40,0xA5,0x02,0xFA,0xF4,0x43,0x61,0x31,0xCB,0x7F,0x84,0xBC,0xF9,0xCF,0x90,0x09,0xC4,0xFB, -0x0C,0x02,0x7A,0x89,0xDF,0xC6,0x0D,0x53,0x36,0x97,0x68,0x47,0x69,0x2A,0x8C,0x61,0x1C,0x92,0x4C,0x9B, -0xC0,0x62,0x86,0x53,0x2D,0x60,0x38,0xD3,0x28,0xE3,0x5A,0x96,0x27,0x09,0x4B,0xF9,0x03,0x79,0xD8,0x7A, -0xF9,0x48,0xF3,0x36,0xC7,0x39,0x0E,0x8A,0x65,0x9C,0x36,0xE5,0x22,0x6B,0x3A,0x58,0x07,0x77,0xBB,0xBA, -0x2E,0x2A,0xBC,0x9C,0x52,0x91,0x7F,0xD6,0xFA,0x6A,0x0E,0xDC,0x85,0x70,0xAA,0x47,0xF3,0x28,0x5A,0x0E, -0x1E,0x9C,0x05,0xFD,0x20,0xE3,0x4C,0xE8,0xC3,0x5B,0xFC,0x5E,0xB8,0x96,0xFB,0xE0,0x1D,0xBC,0x7D,0xAA, -0x63,0xAD,0x19,0x6B,0x58,0x23,0x34,0xE3,0x88,0xFA,0x42,0x8D,0x4A,0x16,0x66,0x59,0xDD,0x89,0xED,0x03, -0x11,0x17,0xA4,0xE1,0x3C,0x59,0x52,0x48,0xCE,0xA8,0xA7,0xEB,0xA2,0xD0,0xC3,0xA2,0x5E,0x46,0x71,0xD6, -0x38,0xB6,0xCA,0x14,0x26,0xF5,0x4A,0xF0,0x40,0x7E,0x7B,0xB1,0x6A,0x7F,0x4D,0x46,0x59,0xDD,0x23,0x80, -0x69,0xE5,0x3E,0x93,0x76,0x3C,0x5D,0x56,0x08,0x7B,0x32,0x64,0x48,0x03,0x8E,0x31,0x0F,0x59,0xB0,0xA7, -0xEF,0xE9,0xAE,0x0E,0xFF,0xAD,0xEB,0x16,0xEC,0xC2,0xD4,0x67,0x01,0xBE,0x38,0x7F,0x01,0xA1,0x34,0x61, -0x14,0x53,0x6E,0x20,0xC8,0x28,0x9E,0xDE,0x79,0x0C,0xA9,0xC8,0xB8,0x42,0xD7,0xE6,0xA0,0x2D,0x6C,0x3C, -0x7F,0xA0,0xCE,0x96,0x32,0x6C,0x46,0x45,0x74,0xBD,0x07,0xE2,0x39,0x7E,0xF4,0xED,0x83,0x45,0x1F,0x77, -0x41,0xE6,0x62,0x4B,0xD0,0x2C,0xB1,0x46,0x80,0x25,0x5C,0xAF,0x16,0xF2,0x53,0x95,0x1D,0xB5,0x7D,0x14, -0x45,0xE2,0xD7,0x12,0x40,0xAB,0xB8,0x2C,0xCF,0x2C,0x71,0x48,0x06,0x0C,0x64,0x78,0x8C,0xEF,0xC0,0xA5, -0x65,0x79,0xA6,0x6C,0xA8,0x68,0x87,0x44,0xAD,0xD6,0x30,0x23,0xD3,0xAA,0x66,0xEB,0xEB,0xDC,0x2E,0xCD, -0xC4,0x28,0x91,0x32,0x91,0x6C,0xE4,0xDB,0xC3,0xD2,0x68,0x32,0x29,0x72,0xF7,0x23,0x69,0x1B,0x6D,0x31, -0x24,0x98,0x1A,0x25,0x0C,0x28,0xCB,0xD3,0x08,0x32,0x84,0xA8,0x5E,0x5A,0xDB,0x32,0x4C,0x03,0xB8,0xC0, -0xFD,0x4B,0x64,0x89,0x4A,0x9B,0x56,0x31,0xE2,0xA9,0xA2,0xBB,0x7D,0x1E,0x2F,0xB4,0x72,0x8C,0x65,0x98, -0x6B,0xFF,0xBC,0xD5,0x92,0x3F,0x4C,0x25,0x2A,0x21,0xF4,0xE0,0xEB,0x8A,0xF9,0xBC,0x0B,0x66,0x15,0x77, -0xE1,0x06,0x65,0x05,0x81,0xBE,0x82,0x42,0xD5,0xED,0x59,0xE2,0x39,0xC5,0x7D,0xE0,0xA2,0xB5,0xFC,0x8C, -0x07,0x3E,0xDA,0x3E,0xA7,0x4D,0x67,0x43,0xDB,0x3B,0x5B,0x0F,0x40,0x68,0xC2,0x52,0x6E,0x40,0x8E,0x83, -0x34,0x58,0xDD,0x56,0x36,0x5E,0xCD,0xB8,0x60,0x27,0x79,0x16,0x1A,0x0B,0x20,0xDD,0xE5,0x96,0x92,0x95, -0x8B,0x2D,0x65,0xB7,0x2E,0xB5,0x4A,0xFB,0x70,0x21,0x75,0xB5,0xE2,0xC7,0xE7,0xCF,0x72,0x56,0x6B,0x1B, -0x66,0x6D,0x85,0x03,0xB3,0xD2,0x89,0xCB,0x8C,0x2C,0x8C,0xFE,0x61,0xAC,0xDA,0xE9,0xA9,0x7E,0xAA,0xFC, -0x3D,0x89,0x46,0x02,0x4F,0x24,0x77,0xBD,0xF8,0xE2,0x08,0x86,0x53,0x88,0x4B,0x36,0x34,0x60,0xD5,0x0F, -0x88,0xF5,0xE2,0x17,0xC4,0x0F,0x71,0x77,0xAB,0x8E,0xD0,0xF3,0xAA,0x7A,0x5E,0x45,0x1D,0xB5,0xC1,0x7B, -0xE2,0x57,0x26,0xBA,0x02,0x43,0xC3,0xAC,0x06,0x76,0x75,0xB7,0xB8,0xD7,0x2A,0x16,0x51,0x76,0x4F,0x7D, -0x11,0x35,0xAB,0x53,0x42,0x10,0x7F,0xAB,0x89,0x56,0x3B,0xCD,0x65,0x4D,0x99,0x78,0x7E,0xD4,0x58,0xF1, -0xAD,0x43,0xB3,0xC6,0x00,0xF2,0xA1,0x47,0x17,0xEC,0x96,0x2E,0xAA,0xC9,0x26,0xBD,0x9A,0x02,0x7B,0xB0, -0xA1,0xDE,0x95,0x27,0xAB,0x01,0xB2,0x24,0x78,0xB4,0xA8,0xAA,0x8A,0x87,0xCB,0x65,0xA3,0x57,0x7D,0xD9, -0xD6,0xFC,0x81,0x50,0xB5,0x99,0xC8,0xAF,0x4E,0xE4,0xFE,0xF6,0xB7,0x29,0x4F,0xA2,0x29,0x8C,0xDD,0x3F, -0x01,0x4B,0x0A,0x87,0xFB,0x35,0x2E,0x00,0x00 +0x1F,0x8B,0x08,0x08,0xE1,0xA1,0xEB,0x5E,0x02,0x00,0x65,0x64,0x69,0x74,0x2E,0x68,0x74,0x6D,0x00,0xB5, +0x1A,0x0B,0x5B,0xDB,0x36,0xF0,0xAF,0x18,0x6F,0x63,0xF6,0xE2,0x38,0x0E,0x50,0xD6,0x3A,0x18,0x16,0x1E, +0xEB,0xBB,0x50,0x12,0xDA,0xD1,0x8E,0xED,0x53,0x6C,0x25,0x56,0xB1,0x25,0xCF,0x96,0x09,0x34,0xCD,0x7F, +0xDF,0x49,0xF2,0x93,0x84,0xEE,0xF1,0x6D,0xA5,0x60,0x49,0xA7,0x3B,0xDD,0x9D,0xEE,0x25,0xD9,0x7B,0x1B, +0xC7,0xA7,0x47,0xE3,0xCB,0xB3,0x13,0x2D,0xE4,0x71,0xB4,0xBF,0x27,0xFE,0x6A,0x11,0xA2,0x33,0x4F,0xC7, +0x54,0xDF,0xDF,0x8B,0x31,0x47,0x00,0xE2,0x49,0x17,0xFF,0x91,0x93,0x1B,0x4F,0x3F,0x62,0x94,0x63,0xCA, +0xBB,0xFC,0x2E,0xC1,0xBA,0xE6,0xAB,0x9E,0xA7,0x73,0x7C,0xCB,0x7B,0x02,0x79,0xA0,0xF9,0x21,0x4A,0x33, +0xCC,0xBD,0x9C,0x4F,0xBB,0x8F,0x81,0x04,0x27,0x3C,0xC2,0xFB,0x27,0xA3,0x33,0xED,0x24,0x20,0x9C,0xA5, +0x7B,0x3D,0x35,0xB2,0x17,0x11,0x7A,0xAD,0xA5,0x38,0xF2,0x74,0x94,0x24,0x11,0xEE,0x72,0x96,0xFB,0x61, +0x97,0x00,0x4D,0x5D,0x0B,0x53,0x3C,0xF5,0xF4,0x1E,0xF2,0xB1,0x0D,0x03,0xBA,0x26,0x96,0xF3,0x74,0x12, +0xA3,0x19,0xEE,0xDD,0xAA,0x39,0x4D,0x02,0x59,0xC8,0x52,0xEE,0xE7,0x5C,0xFB,0x57,0xD8,0xFF,0x00,0x29, +0xE3,0x77,0x11,0x56,0x20,0x25,0xB3,0x9F,0x65,0xBA,0x16,0xE3,0x80,0x20,0xE0,0xC2,0x4F,0xB1,0xD0,0x5A, +0x84,0x26,0x38,0x5A,0x4C,0x19,0xA8,0x29,0x23,0x9F,0xB1,0xDB,0xDF,0x4A,0x6E,0x07,0xB2,0x3B,0x45,0x31, +0x89,0xEE,0xDC,0x0C,0xD1,0xAC,0x9B,0xE1,0x94,0x4C,0x97,0xB6,0x1F,0x2F,0x3E,0x77,0x09,0x0D,0xF0,0xAD, +0xBB,0xED,0x38,0x83,0x84,0x65,0x84,0x13,0x46,0x5D,0x34,0xC9,0x58,0x94,0x73,0x3C,0x88,0xF0,0x94,0xBB, +0x8F,0x80,0xC2,0x84,0xA5,0x01,0x4E,0xDD,0x7E,0x72,0xAB,0x01,0x88,0x04,0xDA,0x37,0x3B,0x3B,0x3B,0x83, +0x09,0xF2,0xAF,0x67,0x29,0xCB,0x69,0xD0,0xF5,0x59,0xC4,0x52,0xF7,0x9B,0xE9,0x23,0xF1,0x33,0x08,0x48, +0x96,0x44,0xE8,0xCE,0xA5,0x8C,0x62,0xC0,0xBD,0xED,0x66,0x21,0x0A,0xD8,0xDC,0x75,0x34,0x47,0xEB,0x3B, +0x40,0x24,0x9D,0x4D,0x90,0xE1,0x58,0xE2,0xC7,0xDE,0x31,0x07,0x7F,0x8B,0x5F,0x35,0x3C,0xC7,0x64,0x16, +0x72,0xF7,0x47,0xC7,0x11,0xFC,0x6B,0x79,0xB4,0x88,0x48,0xC6,0xBB,0x52,0x39,0x6A,0x3D,0xCE,0x12,0xD7, +0x91,0xAC,0xC3,0x23,0x46,0xE9,0x8C,0x50,0x68,0x24,0x28,0x08,0x08,0x9D,0xB9,0x0A,0x2D,0x22,0x8B,0x4A, +0x5A,0xD8,0x07,0xC4,0xC9,0x0D,0x1E,0xC4,0x84,0x76,0xE7,0x24,0xE0,0xA1,0xBB,0xEB,0x00,0x17,0x7E,0x9E, +0x66,0x20,0x53,0xC2,0x08,0xE5,0x38,0x95,0x68,0x59,0x82,0xE8,0x42,0x89,0x2A,0x14,0x50,0xC9,0x49,0x28, +0xEC,0x28,0xEE,0x4E,0x22,0xE6,0x5F,0x57,0x2B,0xED,0x26,0xB7,0xC5,0x5A,0x6E,0xC8,0x6E,0x70,0xBA,0xA8, +0xD5,0x25,0xB1,0x5B,0xC0,0x16,0x69,0x8C,0xF1,0xD2,0xE6,0x37,0x39,0x40,0x2D,0xF9,0x04,0x29,0x0B,0xAA, +0x4D,0x91,0xDA,0x82,0x17,0x28,0x84,0x26,0x39,0x5F,0xAC,0x6E,0x25,0x4B,0x90,0x4F,0xF8,0x9D,0xEB,0xC8, +0x69,0xD2,0x42,0xDC,0x1D,0xC7,0xD1,0x84,0xC2,0xB5,0x77,0x38,0x0D,0x10,0x45,0xD6,0x30,0x25,0x28,0xB2, +0x46,0xB5,0xCA,0xBB,0x31,0xFB,0xDC,0xCD,0xA1,0x0D,0xFD,0x08,0xFB,0x5C,0x69,0x18,0x36,0x61,0x72,0x4D, +0xF8,0x2A,0x60,0x65,0xA0,0xA1,0x2B,0xA9,0xA1,0x50,0xED,0x5E,0x1F,0x74,0x23,0xF9,0x50,0x62,0x2B,0x89, +0xBA,0x13,0xC6,0x39,0x8B,0xA5,0xBD,0x55,0xD2,0x6A,0xD2,0x64,0x1E,0xAF,0x6C,0xC7,0x7A,0xD5,0x37,0xC8, +0x0F,0x40,0xA9,0x9C,0xF8,0x28,0xEA,0xA2,0x88,0xCC,0xA8,0x1B,0x93,0x20,0x88,0x70,0xC3,0x64,0xDD,0x3C, +0x8D,0x8C,0x00,0x71,0xE4,0x2A,0x3F,0x4B,0xE8,0x0C,0xA0,0x19,0xDE,0xDD,0xB1,0xC8,0xBB,0xC3,0xD3,0xF3, +0xB9,0xF3,0xF2,0xE9,0x8C,0x0D,0xE1,0xDF,0x9B,0xD1,0x45,0x78,0x72,0x31,0x83,0xD6,0xA1,0xE8,0x0E,0xDF, +0x1E,0x0D,0xDF,0xC2,0xE3,0xA8,0xDF,0xF9,0x34,0xFD,0x63,0x28,0x86,0x9F,0x06,0x87,0xE3,0x8B,0x93,0xE1, +0xF0,0x65,0xEF,0xF9,0x9B,0xF9,0xFB,0x97,0xBB,0x02,0x7C,0x18,0x39,0xE7,0xEF,0x42,0xE7,0x62,0xEB,0x49, +0x1C,0x3C,0x0B,0x42,0x3F,0xBE,0x18,0xBE,0x7D,0x7F,0x7E,0x73,0x19,0x5F,0xCC,0x46,0xEF,0xFB,0xE1,0x87, +0xAD,0x77,0xA3,0x0F,0xEF,0x7F,0xBE,0xC6,0xBF,0x3C,0x7B,0xF1,0x61,0x3C,0x07,0x84,0x63,0x36,0xBA,0x38, +0x3F,0x7C,0x77,0x38,0xFB,0x70,0xE8,0x9F,0xDC,0x4E,0xA2,0x37,0x87,0x4F,0x87,0x93,0xE1,0x96,0x8F,0xF1, +0x6C,0x7C,0x7E,0x98,0x3F,0x7F,0x79,0x3A,0x23,0x24,0x1C,0x7D,0x78,0x33,0xF6,0x8F,0x1E,0xBD,0xBA,0x78, +0x36,0x24,0xE1,0x9B,0x17,0xE7,0xCE,0xF5,0xD3,0x97,0x47,0xC7,0xFE,0xE5,0x8B,0xCB,0xDD,0xE3,0xED,0xDE, +0x8F,0x3F,0xBE,0x0E,0x4E,0x09,0x1D,0xDF,0x7C,0x1E,0xCE,0x8E,0xE6,0x8F,0xEF,0xB2,0x71,0xF8,0xFC,0x86, +0xF6,0xDE,0xB1,0x4F,0xCF,0xEF,0x5E,0xC3,0xEF,0xD9,0x59,0x67,0x32,0xEA,0x67,0x17,0x6F,0x9F,0xBF,0xDB, +0xCA,0x9E,0x3C,0x4A,0x0E,0x8F,0x8F,0x6F,0xE2,0xC9,0x59,0x2F,0x0E,0xAE,0xA7,0xFC,0xF1,0x36,0x4F,0x2E, +0x67,0xF9,0x87,0x3F,0x1E,0xBD,0x08,0x7B,0xA7,0x18,0x5D,0x86,0x9D,0xBB,0xCF,0x77,0x8F,0xC3,0xF1,0xB3, +0x9B,0x37,0x11,0xBA,0x7D,0xF3,0xC6,0xFF,0x1C,0x77,0x22,0xF4,0xE4,0x74,0x1C,0xA1,0xB4,0x7F,0x11,0x0C, +0x7B,0x9D,0xA3,0xAD,0xE1,0x0E,0x4F,0xCF,0x8F,0xE8,0xF1,0xF6,0xA7,0xD1,0xE3,0xC3,0xC3,0x3E,0x9B,0xFC, +0xB1,0xF5,0xF4,0x7A,0xF7,0xE9,0xC5,0xEE,0xDB,0xC9,0xDB,0xE1,0x68,0xE7,0xF0,0x02,0x5D,0x8E,0xDE,0x0E, +0xA7,0x3B,0x93,0x30,0x7C,0xF9,0x72,0xFC,0x73,0x30,0xFC,0x9C,0x0E,0x4F,0xE7,0xC3,0xDB,0x93,0x8B,0xE1, +0xB3,0xCE,0xCB,0x93,0xD7,0x4E,0x7F,0x74,0xB9,0x3D,0x7B,0xBD,0x3B,0x3F,0xCC,0x4E,0x86,0x6F,0x0F,0x9D, +0xD9,0x8B,0x4E,0x8C,0x3E,0xB0,0xA3,0xED,0xD9,0xF3,0x5D,0x72,0x76,0x89,0x86,0xCF,0x0F,0x5F,0x64,0xE4, +0x3C,0x7E,0x76,0xE1,0x0C,0x87,0xAF,0x4E,0xF1,0xCF,0x47,0xDB,0xE8,0xE5,0x96,0xFF,0x1E,0xF4,0x7F,0xF1, +0x0B,0xFE,0xB1,0x33,0x9C,0x9F,0x3A,0x91,0xFF,0x04,0x8F,0x9F,0x5D,0x8E,0xE5,0xEE,0x9C,0x44,0x3F,0x8F, +0xAF,0x47,0xF9,0xDB,0xF8,0xE8,0xC8,0xD4,0x28,0xEB,0xA6,0x38,0xC1,0x88,0x37,0x63,0x55,0xE5,0x1C,0x60, +0x5B,0xB5,0x15,0x16,0x4E,0x2A,0x22,0x6B,0x37,0xC0,0x3E,0x4B,0x91,0x9C,0x03,0x08,0x38,0x15,0x26,0xB6, +0xFC,0x49,0x86,0x5A,0x4D,0x45,0x5A,0x0D,0xD1,0x40,0x33,0x4A,0x47,0x88,0x09,0x05,0x9C,0x1B,0xE2,0xE3, +0x6E,0x42,0x6E,0x71,0xD4,0x95,0xC8,0xAE,0x63,0x2E,0xA4,0xB3,0x95,0xD3,0x10,0x25,0xB1,0xA2,0x5A,0x0E, +0x04,0x9F,0x90,0x2F,0x52,0x1A,0xB8,0x4C,0x0C,0xCF,0xC2,0x77,0x58,0xDA,0x9D,0xE4,0xB3,0x29,0xB9,0x05, +0x6F,0x9E,0x12,0x4A,0x38,0xD6,0xFA,0xD9,0xF2,0xA7,0x92,0xCC,0x35,0xBE,0x9B,0xA6,0x28,0xC6,0x99,0xF6, +0x37,0xC9,0x2C,0xA6,0x29,0x8B,0x17,0x75,0x04,0xE4,0xAC,0xD1,0x59,0x2E,0xBF,0xC9,0x93,0x88,0x21,0x10, +0x73,0x25,0x6C,0x94,0xC1,0x34,0x15,0x6E,0x55,0x05,0xD5,0xD2,0xCD,0xB6,0xC0,0x2D,0x5B,0x6E,0xBD,0xB5, +0x53,0xBB,0x6E,0x57,0xCE,0x15,0xC1,0xBE,0xA9,0xFA,0x46,0x3C,0x68,0xC4,0xBA,0x6F,0x38,0xA8,0x74,0xFD, +0xE2,0x6A,0x11,0x15,0x19,0x6A,0x06,0x54,0x94,0xEE,0xEF,0x3A,0x8D,0x50,0x01,0xF3,0x96,0xDF,0x60,0x99, +0xE6,0xAD,0x6F,0x92,0x14,0x76,0x03,0xCF,0xBF,0x42,0xB3,0x92,0xA9,0x4D,0x1B,0x68,0x56,0xE9,0x4E,0x89, +0x50,0xE7,0x3C,0xC9,0x6B,0x45,0x7A,0x55,0x2A,0x00,0x57,0xDC,0x3C,0x12,0xDC,0x7C,0x55,0xAB,0xDB,0xBB, +0xDF,0x15,0x3C,0xEC,0x38,0xDF,0x2D,0x6D,0x35,0xB7,0xCA,0xC7,0x7D,0x07,0xFE,0x95,0x69,0xF7,0x71,0xCD, +0xC2,0xE4,0x91,0xF8,0x29,0x19,0x04,0x3A,0x4D,0xE0,0xF6,0xCE,0x93,0xC7,0xC1,0xA4,0x04,0x2A,0xC1,0x1E, +0x86,0xA7,0x28,0x20,0x79,0xE6,0x3E,0x72,0xBE,0x53,0xFA,0x84,0xED,0x03,0xD9,0xCB,0xCD,0x55,0x9D,0xDA, +0x62,0xB3,0x84,0x50,0x6D,0x2B,0xD3,0xC4,0x7E,0xA3,0xB4,0x32,0xCC,0x66,0xAA,0x07,0x17,0xA9,0x4D,0x53, +0xCC,0x5F,0x38,0xDF,0x2D,0x78,0x8A,0x68,0x36,0x65,0x69,0xEC,0xA6,0x8C,0x23,0x8E,0x0D,0xC7,0x5C,0xF6, +0x9D,0x75,0x80,0xED,0x5D,0x27,0xC0,0x33,0x73,0xB9,0xDC,0xEB,0xC9,0xA4,0x06,0x15,0x8F,0x9F,0x92,0x84, +0xEF,0x4F,0x73,0xEA,0x0B,0x1E,0xB4,0x19,0x36,0xB0,0xB9,0x48,0x31,0xCF,0x53,0xAA,0x05,0xCC,0xCF,0x85, +0xB1,0xDB,0x33,0xCC,0x4F,0x94,0xDD,0x1F,0xDE,0x3D,0x0F,0x60,0xC6,0xB2,0x42,0xF0,0xD7,0x22,0x80,0x03, +0xC3,0x7A,0x05,0x4E,0x6B,0x3E,0x24,0x18,0x20,0xF2,0x12,0xDF,0x19,0xD8,0xE2,0x15,0x22,0xB6,0xC5,0xB8, +0x61,0x94,0xD3,0x00,0x48,0xCD,0xC5,0x0D,0x68,0x01,0x79,0xF8,0x23,0xBF,0xB2,0x88,0x47,0xE1,0x31,0x28, +0xA6,0x93,0x7D,0x74,0xD0,0xED,0xBB,0x68,0x9F,0x1C,0xF4,0xC1,0xBF,0xCC,0x06,0x7D,0xB5,0xF2,0xCF,0x24, +0xC2,0x17,0x85,0xCB,0x89,0x85,0x6A,0x6A,0x3D,0x83,0x9C,0x85,0xA0,0x48,0xF3,0x07,0xE3,0x74,0xA4,0x19, +0x1F,0x7F,0xEC,0x3E,0xB9,0xFA,0xD2,0xFF,0xE8,0x74,0xFB,0x57,0xE6,0xEF,0x66,0x8F,0xD8,0x1C,0x67,0xDC, +0xA0,0xE8,0x86,0xCC,0x10,0xD8,0xB9,0x2D,0xF2,0xED,0x70,0x06,0x52,0x98,0x83,0x6A,0x0D,0xA2,0xD8,0xDB, +0x72,0x9C,0x0D,0x0F,0x1F,0xA0,0x08,0x03,0xEB,0xFA,0xC9,0xF9,0xF9,0xE9,0xF9,0x47,0xBD,0x83,0x3B,0xFA, +0x95,0xAB,0xE9,0x1D,0x6A,0xBA,0xDC,0x86,0xA2,0x33,0xC5,0x59,0x78,0x86,0x78,0x68,0x04,0xF6,0x0D,0x8A, +0x72,0xD0,0x85,0x60,0x84,0x79,0xA0,0x38,0x7D,0x92,0x73,0xCE,0xA8,0x6E,0x0E,0x98,0x4D,0x28,0xC5,0xE9, +0xB3,0xF1,0xEB,0x57,0x9E,0x7E,0xCE,0x18,0xD7,0x8E,0x49,0xAA,0x5B,0x72,0x37,0x6C,0x94,0x24,0x98,0x06, +0x47,0x21,0x89,0x02,0x83,0x99,0x03,0x81,0xEE,0x4B,0x74,0x59,0x88,0x00,0xB6,0x6F,0xAB,0x92,0x75,0x0A, +0x52,0xEB,0x96,0x6F,0xC7,0x79,0xC4,0x49,0x12,0x61,0x6F,0xA3,0x0F,0x3D,0x8A,0x62,0x80,0x89,0x34,0x2C, +0x60,0x24,0xF0,0x74,0x15,0x8C,0x8A,0x10,0xB6,0x6E,0x15,0x5F,0xAD,0x12,0xB4,0x56,0x09,0x9A,0xB8,0x09, +0x48,0xA4,0x5B,0x81,0x5D,0xD7,0xCA,0xD0,0x2B,0x96,0x2A,0x61,0x01,0x9E,0x22,0xE0,0xE4,0x9D,0x90,0x1A, +0x4A,0xEF,0x75,0x0B,0x05,0x6A,0xA1,0xAC,0xAD,0x8D,0xAC,0xA9,0x0D,0xB5,0x8D,0xEB,0x90,0x33,0x85,0x9C, +0xB6,0x91,0xD3,0x26,0xF2,0x91,0xB4,0x86,0x75,0xC8,0xA9,0x42,0x8E,0x5A,0x22,0x46,0x52,0x44,0x15,0xE1, +0xBA,0x42,0x9B,0x20,0x10,0x60,0x47,0x4D,0x31,0xA1,0x07,0x0E,0x89,0x26,0x11,0x0E,0xBC,0x0D,0x07,0x7A, +0xA2,0xA8,0xF6,0xB6,0x9C,0x35,0x6B,0x44,0x6A,0x8D,0xBC,0xB5,0x46,0x2E,0xD7,0x20,0x09,0x28,0x11,0xF2, +0x86,0x6E,0xE5,0x52,0x6B,0xED,0x11,0xB5,0x9C,0x1F,0x62,0xFF,0x7A,0xC2,0xE4,0x88,0x6C,0x8B,0x15,0x37, +0x90,0xA4,0x99,0x48,0x9A,0xF2,0x28,0x02,0x34,0x13,0x1B,0xBC,0xDC,0x13,0x94,0xAD,0xA4,0x29,0xBE,0x36, +0x8C,0xB8,0xAD,0x4B,0x84,0xB8,0xAD,0xA5,0xB8,0x35,0x6D,0x84,0x6E,0xB0,0xB6,0x4E,0x4B,0xB1,0xB9,0x66, +0x30,0x59,0x37,0x98,0x9B,0x56,0x6A,0x33,0xEA,0x47,0xC4,0xBF,0xF6,0x6A,0x37,0x36,0x17,0x46,0xB3,0x23, +0x38,0xE1,0x1E,0xC5,0x73,0xED,0x67,0x08,0x4B,0xC7,0x88,0xA3,0x01,0x2F,0xC8,0x18,0x85,0xDD,0x60,0x20, +0x04,0xA7,0x51,0xF0,0xC2,0xCC,0x46,0x01,0x0C,0x9F,0x5D,0x8C,0x75,0x4B,0xEF,0x89,0x5D,0xD1,0xC1,0x93, +0x89,0xB9,0x34,0x2B,0x5F,0xB2,0xA8,0x8C,0xEA,0x17,0x69,0x54,0x0F,0x41,0xA3,0xB4,0xB8,0xA5,0x15,0xAF, +0xE5,0x89,0x4C,0x8D,0x4A,0xA5,0x25,0x53,0xE2,0x64,0x28,0xD6,0x30,0x8A,0xFD,0xD7,0x4D,0x08,0x7B,0xCA, +0x78,0x0D,0xD3,0x42,0x6D,0xA6,0x51,0xC5,0x74,0x8A,0xE6,0xA5,0x91,0xA8,0xF5,0x07,0xCA,0xBD,0x1D,0xC8, +0xBE,0x34,0xE3,0x1A,0xF6,0x76,0x9C,0x27,0xBB,0x03,0xD8,0x1F,0x43,0x39,0x2E,0x00,0xF6,0xB8,0x0D,0xA6, +0x35,0xE3,0xE1,0xC0,0xEF,0x78,0x85,0x56,0x02,0x8F,0xDB,0x59,0x3E,0xC9,0x78,0x0A,0xB9,0xCD,0xF0,0x2D, +0xBF,0x83,0xCD,0xF6,0x32,0x7A,0x87,0x59,0x81,0x69,0xB1,0x4E,0x67,0x79,0x4F,0x41,0xA7,0xA3,0x86,0x86, +0x90,0xD0,0x10,0x8E,0x32,0xAC,0x51,0x1B,0xDF,0x62,0xFF,0x88,0xC5,0x31,0x12,0x24,0x32,0xD8,0xE4,0xA2, +0xA3,0x9B,0x4B,0x8B,0xAD,0xD5,0xCC,0x03,0x21,0xCB,0xCA,0x1E,0xD2,0x23,0x84,0x40,0xCF,0xB7,0x85,0xAF, +0x64,0x85,0x50,0x5F,0xDF,0xE5,0x32,0x10,0x29,0x94,0x8F,0xCE,0x95,0x55,0x6D,0xDC,0x8A,0x54,0xED,0x7D, +0x97,0x56,0xD7,0x8A,0x3F,0x66,0xBD,0xD3,0x02,0xD6,0x8E,0x6B,0x35,0x54,0x5F,0x2E,0x2D,0x5F,0xF0,0x1F, +0x22,0x3A,0xC3,0x7F,0x5F,0x80,0x9A,0x47,0xE9,0xA2,0x16,0x85,0xE4,0x71,0xE0,0xFE,0x6A,0x1B,0x1F,0x7F, +0xB3,0xAF,0x3A,0xA6,0x79,0xF0,0x6D,0x4F,0x6A,0xD8,0xE0,0xE6,0xC7,0xFE,0x95,0x85,0x00,0x6C,0xFF,0x60, +0xFE,0x6A,0x4B,0x70,0x0B,0x36,0xB8,0x61,0x24,0xD0,0xC4,0x4A,0xC2,0xB3,0xD9,0x54,0x43,0x9B,0x9B,0x06, +0x98,0x5C,0xCB,0x58,0x3B,0xBC,0xA3,0xDB,0x90,0x37,0x96,0xCB,0xFB,0xD9,0x6C,0x9C,0x62,0xAC,0xD2,0x65, +0x05,0x90,0xDC,0x83,0xCC,0x2B,0xC1,0xAA,0x94,0x1A,0x5B,0x35,0x14,0x06,0x65,0xBA,0xB7,0x8B,0x4A,0xC2, +0xD3,0x29,0xA3,0x60,0xB2,0xC9,0xFD,0x61,0x79,0xC4,0xD3,0x5B,0x31,0xE4,0xFB,0x3D,0x12,0xCF,0xB4,0x2C, +0xF5,0x3D,0xB5,0x15,0x07,0xE2,0x8F,0xF7,0xBD,0x48,0x73,0x9B,0xBF,0xFB,0x13,0x4F,0xEF,0xC0,0xFE,0x62, +0x9B,0xB2,0xB9,0x61,0x76,0xBE,0xD7,0x35,0x49,0xD1,0xD3,0x63,0x74,0x5B,0x1C,0xF4,0x45,0x25,0x32,0xD0, +0xA0,0x5F,0x96,0xB0,0x6A,0xA0,0x38,0x62,0xA3,0x9C,0xB3,0x81,0x56,0x56,0x38,0xEA,0x88,0xA9,0x6B,0xBD, +0xFD,0xEF,0x6B,0x1D,0x20,0x10,0x1D,0xA9,0x3D,0x21,0x32,0x88,0xE5,0x22,0xE4,0xE1,0x56,0xF4,0x21,0x85, +0xDB,0xA9,0xA8,0x48,0x00,0x4E,0xEE,0xA5,0x4D,0x2B,0x33,0x90,0x79,0x60,0xB4,0x12,0xED,0x9E,0x38,0x94, +0xEC,0x9F,0xA9,0x6A,0x73,0xAF,0x27,0x7B,0xFA,0x3A,0xC7,0x00,0xCD,0x53,0x40,0xB7,0xAA,0xFA,0x66,0xC2, +0x82,0xBB,0x46,0x55,0x94,0x1D,0xDE,0x1D,0x45,0x28,0xCB,0xDE,0xA0,0x18,0xD6,0xF7,0x63,0xDD,0x2C,0x4C, +0x69,0xDF,0xD9,0xDC,0x6C,0x23,0xA5,0x38,0x66,0x37,0x58,0x71,0x85,0x21,0x94,0xB9,0x01,0x10,0xDE,0xDC, +0x5C,0xC7,0x98,0xB8,0x50,0xFB,0x1A,0x57,0x14,0xDC,0xB5,0x0C,0x7F,0xFF,0x13,0x77,0x2A,0x47,0x3E,0xA4, +0xD5,0xC8,0xB4,0x04,0xF7,0x5F,0xBE,0x64,0xF2,0xEF,0x4A,0xA0,0x97,0xFE,0xB2,0xEA,0x2E,0x58,0xBA,0x04, +0xB8,0xDE,0x7D,0xAF,0xE0,0x66,0x36,0x27,0xDC,0x0F,0x85,0xBE,0x7D,0x94,0x61,0x5D,0xDC,0xD4,0xB9,0xB2, +0x35,0xFB,0x5C,0x34,0x3E,0x93,0xA4,0x68,0xCD,0xD1,0x4D,0xD1,0x8A,0x93,0xED,0xA2,0x95,0x04,0x53,0xDD, +0x55,0x45,0xE2,0x86,0xB3,0x2C,0x1A,0xFD,0xA5,0xDC,0xFA,0x68,0x55,0xC3,0xC7,0x6C,0x4E,0x85,0x02,0x2B, +0x2D,0x47,0x6B,0xF6,0xBE,0x4E,0x61,0x95,0xD3,0x05,0x05,0x5E,0x77,0x9A,0x2A,0x9F,0x6B,0xF8,0x47,0x09, +0x03,0xCF,0xC0,0x4B,0xF3,0xFF,0xB2,0x1A,0x5F,0x59,0xCD,0xCA,0x7E,0xAC,0x11,0xF2,0x28,0x84,0x5A,0xF2, +0x2F,0x24,0x8C,0x5B,0x2B,0xC4,0xB6,0x2F,0x9E,0x6F,0x58,0x20,0xA3,0x9F,0x69,0xE5,0x46,0x6C,0xFD,0x8F, +0x06,0x96,0xB4,0x0C,0xAC,0x5D,0x69,0x24,0x6B,0x76,0x0D,0x47,0x98,0xE3,0x4A,0xA2,0x64,0xAD,0x44,0xE9, +0xFF,0xA3,0xF9,0x3A,0x2C,0x11,0x75,0xAE,0x68,0x06,0xA6,0x80,0xDC,0xE8,0x90,0xA0,0xBD,0x36,0x85,0xCC, +0x4F,0x59,0x14,0x8D,0x59,0x72,0xF0,0xC0,0xB8,0x5B,0x8D,0x17,0x8D,0x92,0xCD,0x7A,0x8A,0xE5,0xAF,0x25, +0xFA,0x0A,0x4F,0xF9,0xC1,0x43,0x80,0x87,0xC9,0xD6,0x73,0xAC,0xC0,0xC3,0x36,0x28,0x0F,0x46,0x7F,0xE9, +0xF8,0x56,0x56,0xF5,0x2E,0x3B,0x0C,0xF6,0xC2,0x2F,0x95,0xE4,0x09,0x25,0x59,0x64,0x6D,0xBE,0xA8,0xC7, +0x23,0xA0,0xE8,0x05,0x1D,0x3D,0xB9,0xAD,0xC7,0x38,0x4B,0xBC,0x4C,0x0D,0x21,0x83,0x58,0xFC,0xDE,0xA6, +0xAC,0x8B,0xE2,0xA9,0x47,0x6C,0x36,0x9D,0x66,0x98,0xBF,0x17,0x19,0xC4,0x8A,0xAA,0xFE,0x33,0x99,0x41, +0x06,0xD0,0xA5,0x31,0xCB,0x33,0xCC,0x72,0xDE,0xAE,0x35,0x2B,0x61,0xF6,0x82,0x2F,0x5F,0xAA,0xCE,0x7E, +0xD0,0x49,0xEB,0xEE,0xE5,0x5E,0xD6,0xE8,0xEC,0x67,0x9D,0x08,0x3C,0xE9,0x3F,0xB6,0x14,0xD2,0xB4,0x14, +0x26,0x12,0x98,0xC5,0x94,0xA5,0xA4,0xB5,0xAD,0xA7,0xE2,0x24,0x80,0x1A,0x21,0x56,0x18,0xB4,0x6E,0x96, +0x87,0xDC,0xA6,0x2B,0x23,0x2B,0x6D,0x7B,0xFA,0x43,0xD5,0x76,0x60,0x08,0xAA,0xA0,0xF5,0x57,0x6C,0x8E, +0xD3,0x23,0x94,0x61,0x03,0x22,0x6F,0x95,0x26,0x24,0xD4,0x74,0xB3,0xB5,0xB3,0x68,0x01,0xF5,0xD5,0x13, +0xC2,0xCB,0x57,0xC3,0x02,0x4C,0x10,0x71,0x61,0x0D,0x25,0x73,0xA9,0xB8,0x63,0x54,0x9C,0x98,0x40,0x43, +0x79,0x8B,0x47,0x6C,0x8B,0x0B,0x1E,0xD0,0xDB,0xB1,0x3A,0x20,0x42,0x79,0x8D,0xC1,0x5A,0x58,0x72,0x96, +0xB2,0x04,0xCD,0x90,0x98,0x07,0x63,0xE0,0x60,0x92,0xB8,0xA0,0xD6,0xA8,0x88,0xEA,0xEB,0x86,0x6E,0xDF, +0x03,0x7B,0x95,0x97,0x39,0xA7,0x53,0x03,0x6A,0x27,0xB3,0x9E,0x16,0xFC,0x77,0x49,0x88,0xDF,0xF2,0x22, +0xBB,0x84,0x3C,0xAE,0x5B,0x51,0xD1,0xFC,0x94,0x15,0x0D,0x3F,0x2B,0x5B,0xB7,0x0D,0x20,0xA3,0x25,0x98, +0xD1,0x69,0xD1,0x24,0x94,0x94,0x74,0x4A,0x60,0xF9,0x4C,0x92,0x32,0x93,0x85,0x65,0x2B,0xC4,0xB7,0x15, +0x1E,0xAB,0xF2,0x1C,0x5E,0x97,0xE7,0xEA,0x5B,0x96,0xFF,0x4E,0xFC,0x84,0xCE,0x4A,0x61,0x92,0xB2,0x35, +0x23,0xA5,0x28,0x93,0x38,0xF9,0x2A,0x23,0xE9,0xBF,0x3D,0xF5,0x1D,0x9F,0xBC,0x3A,0x19,0x9F,0x34,0x0F, +0x00,0xCD,0xCB,0x21,0xFE,0x57,0xB7,0x2F,0xDC,0x74,0x8D,0xBF,0x91,0xD4,0xA0,0xEC,0x36,0xCD,0xD6,0xFD, +0x51,0xD4,0xBA,0x97,0xAA,0x33,0x4A,0x71,0xE1,0x03,0x7A,0xDA,0xDC,0x6C,0x30,0x22,0xC7,0xEB,0x3B,0x2D, +0x6A,0xE9,0xAA,0x0A,0x97,0x5E,0x8D,0x1E,0x2A,0x57,0x91,0x59,0x1D,0x08,0x89,0x47,0x8B,0x88,0x62,0x89, +0xB3,0x21,0xD9,0xF7,0xE1,0x50,0xD8,0x31,0xD5,0x5D,0x8E,0xE7,0xC1,0xB5,0x97,0x7F,0x25,0xEF,0x03,0x36, +0x37,0x51,0xBB,0xA4,0x35,0x1C,0x4B,0x02,0xC5,0x82,0xB2,0x25,0x6F,0x22,0x40,0x16,0x60,0xCB,0xB1,0x5E, +0x8C,0x4E,0xDF,0xD8,0x09,0x4A,0xC1,0x21,0xA9,0xD9,0x8C,0x46,0xB9,0x12,0xB0,0xAD,0xED,0xA7,0x27,0x8D, +0xB3,0x96,0x7C,0xDD,0xE7,0xF2,0xA5,0x15,0x19,0x82,0x9C,0xCA,0xD0,0xA2,0xEC,0x29,0xEE,0x65,0x21,0xC7, +0xC5,0x65,0xBE,0xAB,0xC3,0x55,0xDC,0xCC,0x16,0xFC,0x26,0x7F,0xE0,0x3A,0x81,0x87,0x24,0x6B,0x9E,0x31, +0x5B,0x91,0xE1,0x6F,0xEE,0xD8,0xB2,0x6C,0x29,0x72,0xF7,0x8F,0x4B,0xEA,0x45,0xB4,0xDA,0x1C,0x79,0x1C, +0x5E,0xD4,0xA1,0xB8,0x36,0x47,0x1D,0x52,0x18,0xA1,0xBA,0x45,0xFF,0xA9,0x87,0xD0,0xD2,0x43,0xE8,0x6A, +0x80,0xC0,0xB7,0x2D,0x6F,0xAF,0x56,0x19,0x4C,0x80,0xB3,0xEB,0x41,0x1D,0x45,0x00,0x02,0xCF,0xA8,0x05, +0xF8,0x94,0xC9,0xF1,0x4F,0xE8,0x06,0xA9,0x6B,0xD9,0x1A,0xBA,0x3E,0x54,0xC8,0xE9,0xFE,0xEF,0xD0,0xAA, +0x66,0xB6,0x03,0x51,0x06,0xCD,0xD5,0x78,0xC2,0x5B,0xE1,0xA9,0x8E,0x59,0xCD,0xE8,0x04,0xEE,0x5A,0x78, +0xB3,0xC6,0x1B,0xFA,0x6D,0xB8,0x1E,0x18,0xE4,0x43,0xBE,0xD7,0x8C,0xC3,0x0A,0xA3,0x69,0x3D,0xEB,0x0F, +0xA3,0xED,0xE3,0xEA,0xFA,0x3A,0x43,0xFA,0x1F,0x3E,0xC8,0xEC,0xAC,0xBC,0x98,0x01,0x37,0x6F,0xF4,0x74, +0x30,0x88,0x0C,0xCC,0x10,0xA3,0x74,0x24,0xEE,0x00,0x54,0x22,0x59,0xAA,0x0D,0xF4,0xA4,0xEB,0x1A,0xA0, +0xB1,0x9E,0x4C,0x19,0x36,0xE8,0x01,0xE6,0x57,0x40,0x0A,0x40,0xEA,0x31,0x20,0xD9,0x18,0x44,0x30,0x88, +0x3C,0x3D,0x66,0x94,0x5D,0x23,0xD2,0x9C,0x4E,0x00,0x42,0x8A,0xAF,0x04,0xF4,0x0E,0xB5,0x8A,0x7D,0x90, +0x84,0x6A,0x88,0xDA,0x7D,0xB3,0xB8,0xE5,0xAC,0xEF,0x98,0x70,0xE9,0x36,0x85,0x7D,0x6C,0x48,0xB4,0x4C, +0x14,0x1E,0x23,0x9C,0x65,0x92,0x6F,0x21,0xD7,0x6B,0x16,0x80,0x58,0x80,0xD6,0x8B,0xA1,0x25,0x16,0x02, +0x09,0x05,0x60,0x1C,0xE2,0xB8,0x80,0x70,0x68,0x0A,0x10,0x12,0xA0,0x6F,0xA5,0xAA,0x46,0xB2,0xC0,0x23, +0x74,0xE6,0xF5,0x7B,0x8E,0xB5,0x4A,0xF6,0x22,0xC3,0x23,0x36,0xE5,0x63,0x34,0xC9,0x8C,0x0D,0xC7,0x5C, +0x9D,0x21,0x40,0x23,0x88,0x26,0xC6,0x96,0xB9,0x1E,0xFD,0x3D,0x4B,0xAF,0x71,0x5A,0x20,0x8B,0xCA,0x0C, +0x0A,0xB3,0x08,0x7E,0xF9,0xD0,0x17,0x2F,0xFA,0x5F,0x11,0x8A,0x6B,0xE0,0x28,0x64,0xF3,0xB3,0x94,0x50, +0xFE,0x5A,0x1E,0xFA,0x8D,0x8D,0xBE,0xDC,0x27,0x75,0x17,0x25,0x23,0x50,0x79,0x49,0xB5,0x10,0xC1,0xCC, +0x6D,0x5D,0x55,0x59,0x13,0xD8,0x2E,0x88,0xAD,0xEE,0x62,0x4E,0xA8,0xAB,0x1F,0xF1,0x34,0xEA,0x8E,0x74, +0x2B,0x46,0x3E,0x74,0xD4,0x1C,0xE8,0x2F,0x2D,0xE1,0xB4,0x6E,0x33,0x98,0x6C,0xD4,0x9D,0xBA,0x50,0x5F, +0xB9,0xC7,0x6B,0x5F,0x4B,0x09,0xE0,0x61,0xC4,0x26,0x86,0x78,0xE7,0xB0,0x10,0x0E,0xEF,0xD2,0xA5,0x29, +0xB2,0xD3,0xD7,0xAF,0xDC,0x7C,0x88,0xBA,0xDC,0xC2,0x8D,0x1B,0xC3,0x8E,0xAE,0x8B,0x8B,0x38,0xC0,0x43, +0xC1,0x29,0x8D,0xEE,0x5C,0xC8,0x8A,0x7F,0x21,0x75,0x4E,0x03,0xF6,0x35,0xA9,0x3F,0xDC,0x93,0xFA,0xC3, +0x3A,0xA9,0x71,0x7B,0xB7,0xA0,0x73,0x01,0x64,0x5F,0x23,0x8A,0x66,0x38,0x85,0x01,0xB1,0x08,0x6C,0xC0, +0x3F,0xE3,0x2C,0xC5,0x5F,0xE7,0x6C,0x14,0x92,0x29,0x5F,0xE1,0x4F,0x8E,0xFE,0x3B,0x2E,0x53,0xFC,0x00, +0x97,0x65,0x21,0x5B,0xA5,0x8D,0xBF,0xBE,0x07,0x93,0x4E,0xED,0xC1,0x16,0x36,0xDD,0xF5,0x5F,0xF8,0x5D, +0xBD,0xE2,0xD7,0xB3,0xA7,0x78,0xB8,0x78,0x69,0x05,0xC2,0x26,0x40,0x82,0x46,0x7E,0x62,0xF4,0x10,0x4E, +0x0A,0xAF,0x40,0x04,0x43,0x99,0x23,0xF6,0x16,0x4B,0x8B,0x7B,0xC6,0x9C,0x80,0xF8,0x73,0x10,0xCE,0x97, +0xD5,0xAF,0x2D,0xBE,0x56,0x02,0x25,0x00,0x93,0x90,0x67,0x7B,0x1F,0x0F,0x36,0xAF,0x3A,0x90,0xA0,0x3C, +0x78,0x98,0x1E,0x34,0x36,0xAF,0x7E,0x30,0x7B,0x33,0xD2,0x28,0x89,0x64,0xAA,0x03,0xBD,0x7E,0xA4,0x57, +0x1E,0x5A,0x42,0x08,0x6B,0xA6,0xC2,0x2A,0xB0,0x5A,0x58,0x5E,0x69,0xC2,0x43,0x7C,0x04,0x06,0x0F,0x19, +0x3B,0x60,0x36,0xF5,0x1A,0x37,0x8D,0x3A,0x87,0xBF,0x3A,0x84,0xED,0x41,0xC1,0x56,0x80,0xA7,0x84,0x62, +0x19,0xBD,0x54,0xD3,0x2A,0x00,0x42,0x0D,0x24,0x95,0x90,0xB2,0x6D,0x89,0xB6,0xC8,0x7E,0x64,0x26,0x14, +0x69,0xE8,0xE2,0x83,0x0F,0x91,0xE8,0x75,0x99,0xB0,0x57,0xC0,0x73,0x19,0x48,0x1A,0x13,0xD6,0xBC,0xC0, +0xD3,0xF3,0xA2,0xA5,0x83,0x94,0xBC,0x11,0x84,0x95,0x38,0x10,0x6F,0x55,0xE3,0x5E,0x68,0xAF,0x4F,0x3D, +0x0A,0x6C,0x2E,0xC1,0xC5,0x94,0x00,0x81,0x5E,0xA5,0xF3,0x5F,0x5E,0xBF,0x7A,0xC6,0x79,0x72,0xAE,0x76, +0x14,0x68,0xB5,0x07,0x6A,0x43,0x33,0x17,0x3C,0xBD,0x2B,0x0B,0x43,0x11,0x28,0x54,0xA8,0xFB,0xE5,0x74, +0xF2,0x09,0xFB,0x20,0xC9,0xEB,0x0C,0x72,0xE8,0x96,0x2D,0xD0,0xC7,0xE3,0x33,0x7B,0xD7,0x76,0xA0,0x52, +0x81,0xFD,0xF4,0x43,0x61,0x31,0xCB,0x7F,0x84,0xBC,0xFD,0xCF,0x90,0x09,0xC4,0xFB,0x0C,0x02,0x7A,0x89, +0xDF,0xC6,0x0D,0x53,0x36,0x97,0x68,0x27,0x69,0x2A,0x8C,0x61,0x1C,0x92,0x4C,0x9B,0xC0,0x60,0x86,0x53, +0x2D,0x60,0x38,0xD3,0x28,0xE3,0x5A,0x96,0x27,0x09,0x4B,0xF9,0x3D,0x7D,0xD8,0x7A,0x79,0x49,0xF3,0x36, +0xC7,0x39,0x0E,0x8A,0x61,0x9C,0x36,0xF5,0x22,0x6B,0x3A,0x18,0x07,0x77,0xFB,0x78,0x55,0x54,0x78,0x39, +0xA5,0x22,0xFF,0x6C,0xF4,0x55,0x1F,0xA4,0x0B,0x81,0xAA,0x47,0xF3,0x28,0x5A,0x0E,0xEE,0xD1,0xB2,0x93, +0x94,0x71,0x26,0x5F,0x7A,0x2D,0x7E,0x2F,0x5C,0xCB,0xBD,0x77,0x4D,0xDF,0xA6,0xEA,0x58,0x1B,0xC6,0x06, +0xD6,0x08,0xCD,0x38,0xA2,0xBE,0xD8,0x46,0xA5,0x0B,0xB3,0xAC,0xEE,0xC4,0xF4,0x81,0x88,0x0B,0xD2,0x70, +0x1E,0x2C,0x29,0xA4,0x64,0xD4,0xD3,0x75,0x51,0xE8,0x61,0x51,0x2F,0xA3,0x38,0x6B,0x90,0xAD,0x32,0x85, +0x49,0xBD,0x12,0x3C,0x90,0x2F,0x57,0x9A,0xF3,0x57,0xD9,0x28,0xAB,0x7B,0x04,0x30,0xAD,0x9C,0x67,0xD2, +0x8E,0xA7,0xCB,0x0A,0xE1,0x40,0x86,0x0C,0x69,0xC0,0x31,0xE6,0x21,0x0B,0x0E,0xF4,0x03,0xDD,0xD5,0xE1, +0xFF,0xA6,0x6E,0xC1,0x2C,0x4C,0x7D,0x16,0xE0,0x8B,0xF3,0xE7,0x10,0x4A,0x13,0x46,0x31,0xE5,0x06,0x82, +0x8C,0xE2,0xE9,0x9D,0x55,0x48,0xC5,0xC6,0x47,0x74,0x65,0x0E,0xDA,0xCA,0xC6,0xF3,0x7B,0xDB,0xD9,0xDA, +0x0C,0x9B,0x51,0x11,0x5D,0xEF,0x80,0x79,0x8E,0x57,0x5E,0x8E,0x58,0x74,0xF5,0x14,0x64,0x2E,0x76,0x04, +0xCF,0x12,0x6B,0x04,0x58,0xC2,0xF5,0x6A,0x25,0x3F,0x54,0xD9,0x51,0xDB,0x47,0x51,0x24,0x3E,0xE6,0x00, +0x5E,0xC5,0x62,0x79,0x66,0x09,0x22,0x19,0x08,0x90,0xE1,0x31,0xBE,0x05,0x97,0x96,0xE5,0x99,0xB2,0xA1, +0xE2,0x38,0x04,0xA4,0x79,0xC3,0x8C,0x4C,0xAB,0xEA,0x6D,0x6E,0x72,0xBB,0x34,0x13,0xA3,0x44,0xCA,0x44, +0xB2,0x91,0x77,0x0F,0x4B,0xA3,0x29,0xA4,0xC8,0xDD,0x2B,0xDA,0x36,0xDA,0x6A,0x48,0x30,0x35,0x4A,0x18, +0x70,0x96,0xA7,0x11,0x64,0x08,0x51,0xBD,0xB4,0xA6,0x65,0x98,0x06,0xB0,0x80,0xFB,0x97,0xC8,0x12,0x95, +0x36,0xAD,0x62,0xC4,0x53,0xC5,0x77,0x9B,0x1E,0x2F,0x76,0xE5,0x19,0x96,0x61,0xAE,0xFD,0xF5,0xAD,0x25, +0xBF,0x9B,0x25,0x2A,0x21,0xF4,0xE0,0x6D,0xCA,0x7C,0xDE,0x05,0xB3,0x8A,0xBB,0xB0,0x82,0xB2,0x82,0x40, +0x5F,0xC3,0xA1,0x3A,0xED,0x59,0xE2,0x3A,0xC5,0xBD,0xE7,0xA2,0xB5,0xFE,0x8C,0x7B,0x3E,0xDA,0xA6,0xD3, +0xE6,0xB3,0xB1,0xDB,0x7B,0x3B,0xF7,0x40,0x68,0xC2,0x52,0x6E,0x40,0x8E,0x83,0x34,0x58,0xAD,0x56,0x1E, +0xBC,0x9A,0x71,0xC1,0x4E,0xF2,0x2C,0x34,0x16,0xC0,0xBA,0xCB,0x2D,0xA5,0x2B,0x17,0x5B,0xCA,0x6E,0x5D, +0x6A,0x95,0xF6,0xE1,0x42,0xEA,0x6A,0xC5,0x8F,0x2F,0x5F,0x64,0xAF,0xDE,0x6D,0xE8,0xB5,0x37,0x1C,0x84, +0x95,0x4E,0x5C,0x66,0x64,0x61,0xF4,0xF7,0x63,0xD5,0x5E,0x4F,0x9D,0xA7,0xCA,0xCF,0x5D,0x34,0x12,0x78, +0x22,0xB9,0xEB,0xC5,0x7B,0x2D,0x68,0x4E,0x21,0x2E,0xD9,0x70,0x00,0xAB,0xBE,0x6F,0xD6,0x8B,0x0F,0x9C, +0xEF,0xE3,0xEE,0x57,0x27,0x42,0xCF,0xAB,0xEA,0x79,0x15,0x75,0xD4,0x04,0xEF,0x81,0x8F,0x60,0x74,0x05, +0x86,0x03,0xB3,0x6A,0xD8,0xD5,0xDA,0x62,0x5D,0xAB,0x18,0x44,0xD9,0x1D,0xF5,0x45,0xD4,0xAC,0xA8,0x84, +0xA0,0xFE,0xD6,0x21,0x5A,0xCD,0x34,0x97,0x35,0x67,0xE2,0xFA,0x51,0x63,0xC5,0x5B,0x87,0x66,0x8D,0x01, +0xEC,0xC3,0x19,0x5D,0x88,0x5B,0xBA,0xA8,0x26,0x0F,0xE9,0x55,0x17,0xC4,0x83,0x09,0xF5,0xAC,0x3C,0x59, +0x0F,0x90,0x25,0xC1,0xCA,0xA0,0xAA,0x2A,0x56,0x86,0x8B,0x83,0x5E,0xF5,0x2E,0xB0,0xF1,0xFD,0x52,0x4D, +0x83,0xC8,0x57,0x27,0x72,0x7E,0xFB,0x6D,0xCA,0x83,0x68,0x0A,0x63,0xFF,0x4F,0x51,0x09,0xC4,0x79,0xD4, +0x2E,0x00,0x00 }; From efe7618b5bcd6aca32c0c148ad07f433b6210864 Mon Sep 17 00:00:00 2001 From: lorol Date: Fri, 19 Jun 2020 20:03:02 -0400 Subject: [PATCH 060/551] Fixes --- examples/SmartSwitch/SmartSwitch.ino | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/examples/SmartSwitch/SmartSwitch.ino b/examples/SmartSwitch/SmartSwitch.ino index a5e448c4b..19affa4fe 100644 --- a/examples/SmartSwitch/SmartSwitch.ino +++ b/examples/SmartSwitch/SmartSwitch.ino @@ -300,7 +300,7 @@ void mytimer() { Xtea x(key); void encip(String &mtk, unsigned long token){ - unsigned long res[2] = {random(0xFFFFFFFF),token}; + unsigned long res[2] = {(unsigned long)random(0xFFFFFFFF),token}; x.encrypt(res); char buf1[18]; sprintf(buf1, "%08X_%08X",res[0],res[1]); //8 bytes for encryping the IP cookie @@ -606,7 +606,7 @@ void setup(){ #endif -#ifdef USE_AUTH COOKIE +#ifdef USE_AUTH_COOKIE }).setFilter(myHandshake); #else }); @@ -622,7 +622,7 @@ void setup(){ settimeofday(&tv, nullptr); } request->send(200, "text/plain","Got browser time ..."); -#ifdef USE_AUTH COOKIE +#ifdef USE_AUTH_COOKIE }).setFilter(myHandshake); #else }); @@ -640,7 +640,7 @@ void setup(){ #endif }); request->send(200, "text/plain","Restarting ..."); -#ifdef USE_AUTH COOKIE +#ifdef USE_AUTH_COOKIE }).setFilter(myHandshake); #else }); @@ -659,7 +659,7 @@ void setup(){ #endif }); request->send(200, "text/plain","Erasing WiFi data ..."); -#ifdef USE_AUTH COOKIE +#ifdef USE_AUTH_COOKIE }).setFilter(myHandshake); #else }); From a67ba33153b44ffeb641ddb3753b73250704ce6b Mon Sep 17 00:00:00 2001 From: lorol Date: Mon, 22 Jun 2020 15:09:21 -0400 Subject: [PATCH 061/551] Minor modification of app index.htm for better outlook on Chrome browser. Tested with LITTLEFS. Refreshed & checked if everything else still works. --- .../ESP_AsyncFSBrowser/data/acefull.js.gz | Bin 119986 -> 119986 bytes .../ESP_AsyncFSBrowser/data/worker-css.js.gz | Bin 35483 -> 35483 bytes .../ESP_AsyncFSBrowser/data/worker-html.js.gz | Bin 47406 -> 47406 bytes .../data/worker-javascript.js.gz | Bin 47729 -> 47729 bytes examples/SmartSwitch/data/acefull.js.gz | Bin 119986 -> 119986 bytes examples/SmartSwitch/data/index.htm | 2 +- examples/SmartSwitch/data/worker-css.js.gz | Bin 35483 -> 35483 bytes examples/SmartSwitch/data/worker-html.js.gz | Bin 47406 -> 47406 bytes .../SmartSwitch/data/worker-javascript.js.gz | Bin 47729 -> 47729 bytes src/edit.htm.gz.h | 2 +- 10 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/ESP_AsyncFSBrowser/data/acefull.js.gz b/examples/ESP_AsyncFSBrowser/data/acefull.js.gz index 1c60522393af9280fd007d1cbd4b180ac3f4943c..9ce2845d6af3d0227403882a26b74b1064e181a6 100644 GIT binary patch delta 21 dcmdnAl6})kc6Rx04vx~c diff --git a/examples/ESP_AsyncFSBrowser/data/worker-css.js.gz b/examples/ESP_AsyncFSBrowser/data/worker-css.js.gz index 2dd76b9b1dff40f199896e8d16a724312dffc73f..30355a778582facac1906df6d65b79d52180c07a 100644 GIT binary patch delta 18 acmbO|m1*`=CU*I54vtR@A2+g3=>h;f&j#NB delta 18 acmbO|m1*`=CU*I54vvotUvFfe(ggrPa0ht+ diff --git a/examples/ESP_AsyncFSBrowser/data/worker-html.js.gz b/examples/ESP_AsyncFSBrowser/data/worker-html.js.gz index 0bf3cb8f6d4dfbc0f608f8eff90efa5ab4c3b1a6..47c560cdc44198d33201ee9363ac704458b77c30 100644 GIT binary patch delta 18 acmZ4YiD}&@CU*I54vvouA2+hA?*sr!(+7Y6 delta 18 acmZ4YiD}&@CU*I54vr5CUvFer-w6OtbO;&% diff --git a/examples/ESP_AsyncFSBrowser/data/worker-javascript.js.gz b/examples/ESP_AsyncFSBrowser/data/worker-javascript.js.gz index eef3ab50d21864679d896df4589d8e42bc51f2e1..c8abaa30d17fc7cdc79778537c3bf45277d27745 100644 GIT binary patch delta 18 acmezPh3VrLCU*I54vxImup diff --git a/examples/SmartSwitch/data/acefull.js.gz b/examples/SmartSwitch/data/acefull.js.gz index 1c60522393af9280fd007d1cbd4b180ac3f4943c..9ce2845d6af3d0227403882a26b74b1064e181a6 100644 GIT binary patch delta 21 dcmdnAl6})kc6Rx04vx~c diff --git a/examples/SmartSwitch/data/index.htm b/examples/SmartSwitch/data/index.htm index ea10e567c..6775d9e2a 100644 --- a/examples/SmartSwitch/data/index.htm +++ b/examples/SmartSwitch/data/index.htm @@ -249,7 +249,7 @@ border-radius: 50%; background: white } - + *:focus {outline:none !important} diff --git a/examples/SmartSwitch/data/worker-css.js.gz b/examples/SmartSwitch/data/worker-css.js.gz index 2dd76b9b1dff40f199896e8d16a724312dffc73f..30355a778582facac1906df6d65b79d52180c07a 100644 GIT binary patch delta 18 acmbO|m1*`=CU*I54vtR@A2+g3=>h;f&j#NB delta 18 acmbO|m1*`=CU*I54vvotUvFfe(ggrPa0ht+ diff --git a/examples/SmartSwitch/data/worker-html.js.gz b/examples/SmartSwitch/data/worker-html.js.gz index 0bf3cb8f6d4dfbc0f608f8eff90efa5ab4c3b1a6..47c560cdc44198d33201ee9363ac704458b77c30 100644 GIT binary patch delta 18 acmZ4YiD}&@CU*I54vvouA2+hA?*sr!(+7Y6 delta 18 acmZ4YiD}&@CU*I54vr5CUvFer-w6OtbO;&% diff --git a/examples/SmartSwitch/data/worker-javascript.js.gz b/examples/SmartSwitch/data/worker-javascript.js.gz index eef3ab50d21864679d896df4589d8e42bc51f2e1..c8abaa30d17fc7cdc79778537c3bf45277d27745 100644 GIT binary patch delta 18 acmezPh3VrLCU*I54vxImup diff --git a/src/edit.htm.gz.h b/src/edit.htm.gz.h index c890b787e..8ba8275d9 100644 --- a/src/edit.htm.gz.h +++ b/src/edit.htm.gz.h @@ -2,7 +2,7 @@ //File: edit.htm.gz, Size: 4503 #define edit_htm_gz_len 4503 const uint8_t edit_htm_gz[] PROGMEM = { -0x1F,0x8B,0x08,0x08,0xE1,0xA1,0xEB,0x5E,0x02,0x00,0x65,0x64,0x69,0x74,0x2E,0x68,0x74,0x6D,0x00,0xB5, +0x1F,0x8B,0x08,0x08,0xD4,0x00,0xF1,0x5E,0x02,0x00,0x65,0x64,0x69,0x74,0x2E,0x68,0x74,0x6D,0x00,0xB5, 0x1A,0x0B,0x5B,0xDB,0x36,0xF0,0xAF,0x18,0x6F,0x63,0xF6,0xE2,0x38,0x0E,0x50,0xD6,0x3A,0x18,0x16,0x1E, 0xEB,0xBB,0x50,0x12,0xDA,0xD1,0x8E,0xED,0x53,0x6C,0x25,0x56,0xB1,0x25,0xCF,0x96,0x09,0x34,0xCD,0x7F, 0xDF,0x49,0xF2,0x93,0x84,0xEE,0xF1,0x6D,0xA5,0x60,0x49,0xA7,0x3B,0xDD,0x9D,0xEE,0x25,0xD9,0x7B,0x1B, From 0b6b4ca3ddeea3d53b0fdef9a6fa22cf2b8f8580 Mon Sep 17 00:00:00 2001 From: lorol Date: Mon, 29 Jun 2020 10:31:31 -0400 Subject: [PATCH 062/551] --- .../ESP_AsyncFSBrowser/data/acefull.js.gz | Bin 119986 -> 119986 bytes .../ESP_AsyncFSBrowser/data/worker-css.js.gz | Bin 35483 -> 35483 bytes .../ESP_AsyncFSBrowser/data/worker-html.js.gz | Bin 47406 -> 47406 bytes .../data/worker-javascript.js.gz | Bin 47729 -> 47729 bytes examples/SmartSwitch/data/acefull.js.gz | Bin 119986 -> 119986 bytes examples/SmartSwitch/data/index.htm | 7 +++---- examples/SmartSwitch/data/worker-css.js.gz | Bin 35483 -> 35483 bytes examples/SmartSwitch/data/worker-html.js.gz | Bin 47406 -> 47406 bytes .../SmartSwitch/data/worker-javascript.js.gz | Bin 47729 -> 47729 bytes src/edit.htm.gz.h | 2 +- 10 files changed, 4 insertions(+), 5 deletions(-) diff --git a/examples/ESP_AsyncFSBrowser/data/acefull.js.gz b/examples/ESP_AsyncFSBrowser/data/acefull.js.gz index 9ce2845d6af3d0227403882a26b74b1064e181a6..5a816d7e0a68a9cdfd2d6572c9bebda9e18c3619 100644 GIT binary patch delta 21 dcmdnAl6})kc6Rx04vy4cKO5P%vNNu}0svfo2%-Q0 delta 21 dcmdnAl6})kc6Rx04vxZ=>h;h_y<$~ delta 18 acmbO|m1*`=CU*I54vtR@A2+g3=>h;f&j#NB diff --git a/examples/ESP_AsyncFSBrowser/data/worker-html.js.gz b/examples/ESP_AsyncFSBrowser/data/worker-html.js.gz index 47c560cdc44198d33201ee9363ac704458b77c30..f5b19901bf118d8b8d181e352b2842e8e84ff98f 100644 GIT binary patch delta 18 acmZ4YiD}&@CU*I54vv&xKR2?g?*sr${0H>_ delta 18 acmZ4YiD}&@CU*I54vvouA2+hA?*sr!(+7Y6 diff --git a/examples/ESP_AsyncFSBrowser/data/worker-javascript.js.gz b/examples/ESP_AsyncFSBrowser/data/worker-javascript.js.gz index c8abaa30d17fc7cdc79778537c3bf45277d27745..f3d1c7d7da726ccd3c42bf8fa060ba985e4665ba 100644 GIT binary patch delta 18 acmezPh3VrLCU*I54vy4cKR2>x?E(N+YY4;u delta 18 acmezPh3VrLCU*I54vx - + - + - + diff --git a/examples/SmartSwitch/data/worker-css.js.gz b/examples/SmartSwitch/data/worker-css.js.gz index 30355a778582facac1906df6d65b79d52180c07a..4aab43d890fb796e449a27829286064ef766b241 100644 GIT binary patch delta 18 acmbO|m1*`=CU*I54vy4cKR2>Z=>h;h_y<$~ delta 18 acmbO|m1*`=CU*I54vtR@A2+g3=>h;f&j#NB diff --git a/examples/SmartSwitch/data/worker-html.js.gz b/examples/SmartSwitch/data/worker-html.js.gz index 47c560cdc44198d33201ee9363ac704458b77c30..f5b19901bf118d8b8d181e352b2842e8e84ff98f 100644 GIT binary patch delta 18 acmZ4YiD}&@CU*I54vv&xKR2?g?*sr${0H>_ delta 18 acmZ4YiD}&@CU*I54vvouA2+hA?*sr!(+7Y6 diff --git a/examples/SmartSwitch/data/worker-javascript.js.gz b/examples/SmartSwitch/data/worker-javascript.js.gz index c8abaa30d17fc7cdc79778537c3bf45277d27745..f3d1c7d7da726ccd3c42bf8fa060ba985e4665ba 100644 GIT binary patch delta 18 acmezPh3VrLCU*I54vy4cKR2>x?E(N+YY4;u delta 18 acmezPh3VrLCU*I54vx Date: Fri, 3 Jul 2020 16:47:21 -0400 Subject: [PATCH 063/551] In src/SPIFFSEditor.cpp: using Arduino esp32 FS' LITTLEFS.mkdir(path) and LITTLEFS.rmdir(path) to get web file management working w/ LITTLEFS on ESP32. It is slightly different than with esp8266 LittleFS.h library. - On ESP32 w/ LITTLEFS, a new file can be created same way as with SPIFFS, /folder/folder/file.txt - folders are created silently, idea taken from: https://github.com/esp8266/Arduino/blob/master/libraries/LittleFS/src/LittleFS.cpp#L55 - On ESP32 w/ LITTLEFS file remove - first delete the file, then folders if empty - For a compatibility, a folder alone cannot be purposely created. A file will be created instead. - Note, a confuse may occur: /mystuff could be a folder or a file, both will look same way on SPIFFSEditor web file tree. --- .../ESP_AsyncFSBrowser/data/acefull.js.gz | Bin 119986 -> 119986 bytes .../ESP_AsyncFSBrowser/data/worker-css.js.gz | Bin 35483 -> 35483 bytes .../ESP_AsyncFSBrowser/data/worker-html.js.gz | Bin 47406 -> 47406 bytes .../data/worker-javascript.js.gz | Bin 47729 -> 47729 bytes examples/SmartSwitch/data/acefull.js.gz | Bin 119986 -> 119986 bytes examples/SmartSwitch/data/worker-css.js.gz | Bin 35483 -> 35483 bytes examples/SmartSwitch/data/worker-html.js.gz | Bin 47406 -> 47406 bytes .../SmartSwitch/data/worker-javascript.js.gz | Bin 47729 -> 47729 bytes src/SPIFFSEditor.cpp | 25 +++++++++++++++++- src/edit.htm.gz.h | 2 +- 10 files changed, 25 insertions(+), 2 deletions(-) diff --git a/examples/ESP_AsyncFSBrowser/data/acefull.js.gz b/examples/ESP_AsyncFSBrowser/data/acefull.js.gz index 5a816d7e0a68a9cdfd2d6572c9bebda9e18c3619..f795265513b69a806659da016f00ad4d78ec4b24 100644 GIT binary patch delta 21 dcmdnAl6})kc6Rx04i4$6|BdWh*%?<~0RUA>2i^bx delta 21 dcmdnAl6})kc6Rx04vy4cKO5P%vNNu}0svfo2%-Q0 diff --git a/examples/ESP_AsyncFSBrowser/data/worker-css.js.gz b/examples/ESP_AsyncFSBrowser/data/worker-css.js.gz index 4aab43d890fb796e449a27829286064ef766b241..0ba451b948d8798fe8b21a6e20d779c64ccdd0fb 100644 GIT binary patch delta 18 acmbO|m1*`=CU*I54i2fR{~Ot-bO8W62?mb< delta 18 acmbO|m1*`=CU*I54vy4cKR2>Z=>h;h_y<$~ diff --git a/examples/ESP_AsyncFSBrowser/data/worker-html.js.gz b/examples/ESP_AsyncFSBrowser/data/worker-html.js.gz index f5b19901bf118d8b8d181e352b2842e8e84ff98f..496312885798882fc08b5cc91d5fbc1d686cf414 100644 GIT binary patch delta 18 acmZ4YiD}&@CU*I54i3qx{~OuWcLD%N4F@m) delta 18 acmZ4YiD}&@CU*I54vv&xKR2?g?*sr${0H>_ diff --git a/examples/ESP_AsyncFSBrowser/data/worker-javascript.js.gz b/examples/ESP_AsyncFSBrowser/data/worker-javascript.js.gz index f3d1c7d7da726ccd3c42bf8fa060ba985e4665ba..9909a164a99e567cff41557c05ac26b9db42d6cc 100644 GIT binary patch delta 18 acmezPh3VrLCU*I54i4$6{~Ot}b^!oUg9rcs delta 18 acmezPh3VrLCU*I54vy4cKR2>x?E(N+YY4;u diff --git a/examples/SmartSwitch/data/acefull.js.gz b/examples/SmartSwitch/data/acefull.js.gz index 5a816d7e0a68a9cdfd2d6572c9bebda9e18c3619..f795265513b69a806659da016f00ad4d78ec4b24 100644 GIT binary patch delta 21 dcmdnAl6})kc6Rx04i4$6|BdWh*%?<~0RUA>2i^bx delta 21 dcmdnAl6})kc6Rx04vy4cKO5P%vNNu}0svfo2%-Q0 diff --git a/examples/SmartSwitch/data/worker-css.js.gz b/examples/SmartSwitch/data/worker-css.js.gz index 4aab43d890fb796e449a27829286064ef766b241..0ba451b948d8798fe8b21a6e20d779c64ccdd0fb 100644 GIT binary patch delta 18 acmbO|m1*`=CU*I54i2fR{~Ot-bO8W62?mb< delta 18 acmbO|m1*`=CU*I54vy4cKR2>Z=>h;h_y<$~ diff --git a/examples/SmartSwitch/data/worker-html.js.gz b/examples/SmartSwitch/data/worker-html.js.gz index f5b19901bf118d8b8d181e352b2842e8e84ff98f..496312885798882fc08b5cc91d5fbc1d686cf414 100644 GIT binary patch delta 18 acmZ4YiD}&@CU*I54i3qx{~OuWcLD%N4F@m) delta 18 acmZ4YiD}&@CU*I54vv&xKR2?g?*sr${0H>_ diff --git a/examples/SmartSwitch/data/worker-javascript.js.gz b/examples/SmartSwitch/data/worker-javascript.js.gz index f3d1c7d7da726ccd3c42bf8fa060ba985e4665ba..9909a164a99e567cff41557c05ac26b9db42d6cc 100644 GIT binary patch delta 18 acmezPh3VrLCU*I54i4$6{~Ot}b^!oUg9rcs delta 18 acmezPh3VrLCU*I54vy4cKR2>x?E(N+YY4;u diff --git a/src/SPIFFSEditor.cpp b/src/SPIFFSEditor.cpp index 2a2598b27..e0885706b 100644 --- a/src/SPIFFSEditor.cpp +++ b/src/SPIFFSEditor.cpp @@ -240,6 +240,9 @@ void SPIFFSEditor::handleRequest(AsyncWebServerRequest *request){ } } else if(request->method() == HTTP_DELETE){ if(request->hasParam("path", true)){ +#ifdef ESP32 + _fs.rmdir(request->getParam("path", true)->value()); // try rmdir for littlefs +#endif _fs.remove(request->getParam("path", true)->value()); request->send(200, "", "DELETE: "+request->getParam("path", true)->value()); } else @@ -275,7 +278,27 @@ void SPIFFSEditor::handleRequest(AsyncWebServerRequest *request){ String filename = request->getParam("path", true)->value(); if(_fs.exists(filename)){ request->send(200); - } else { + } else { +/*******************************************************/ +#ifdef ESP32 + if (strchr(filename.c_str(), '/')) { + // For file creation, silently make subdirs as needed. If any fail, + // it will be caught by the real file open later on + char *pathStr = strdup(filename.c_str()); + if (pathStr) { + // Make dirs up to the final fnamepart + char *ptr = strchr(pathStr, '/'); + while (ptr) { + *ptr = 0; + _fs.mkdir(pathStr); + *ptr = '/'; + ptr = strchr(ptr+1, '/'); + } + } + free(pathStr); + } +#endif +/*******************************************************/ fs::File f = _fs.open(filename, "w"); if(f){ f.write((uint8_t)0x00); diff --git a/src/edit.htm.gz.h b/src/edit.htm.gz.h index 542f9d8d4..0f937aa73 100644 --- a/src/edit.htm.gz.h +++ b/src/edit.htm.gz.h @@ -2,7 +2,7 @@ //File: edit.htm.gz, Size: 4503 #define edit_htm_gz_len 4503 const uint8_t edit_htm_gz[] PROGMEM = { -0x1F,0x8B,0x08,0x08,0x59,0xFA,0xF9,0x5E,0x02,0x00,0x65,0x64,0x69,0x74,0x2E,0x68,0x74,0x6D,0x00,0xB5, +0x1F,0x8B,0x08,0x08,0x0F,0x7A,0xFF,0x5E,0x02,0x00,0x65,0x64,0x69,0x74,0x2E,0x68,0x74,0x6D,0x00,0xB5, 0x1A,0x0B,0x5B,0xDB,0x36,0xF0,0xAF,0x18,0x6F,0x63,0xF6,0xE2,0x38,0x0E,0x50,0xD6,0x3A,0x18,0x16,0x1E, 0xEB,0xBB,0x50,0x12,0xDA,0xD1,0x8E,0xED,0x53,0x6C,0x25,0x56,0xB1,0x25,0xCF,0x96,0x09,0x34,0xCD,0x7F, 0xDF,0x49,0xF2,0x93,0x84,0xEE,0xF1,0x6D,0xA5,0x60,0x49,0xA7,0x3B,0xDD,0x9D,0xEE,0x25,0xD9,0x7B,0x1B, From 0823e9d9406de9365f9104d4239bf221e1156387 Mon Sep 17 00:00:00 2001 From: lorol Date: Fri, 3 Jul 2020 18:29:55 -0400 Subject: [PATCH 064/551] Minor corrections --- README.md | 3 ++- src/SPIFFSEditor.cpp | 7 +++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 7563bfb6a..ec14bdafb 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # In this fork - SPIFFSEditor improvements -- Added [extras](https://github.com/lorol/ESPAsyncWebServer/tree/master/extras) folder with (Win) tools for re-packing, allow editing, updating and compressing html to binary arrays, embedded to source +- Added [extras](https://github.com/lorol/ESPAsyncWebServer/tree/master/extras) folder with (Win) tools for re-packing, editing, updating and compressing html to binary arrays embedded to source - Added a [SmartSwitch](https://github.com/lorol/ESPAsyncWebServer/tree/master/examples/SmartSwitch) example to test code features - Applied the memory optimizations from [sascha432](https://github.com/sascha432/ESPAsyncWebServer) fork - Cookie Authentication including on Websocket part, based on [ayushsharma82](https://github.com/me-no-dev/ESPAsyncWebServer/pull/684) PR, new functions added: @@ -9,6 +9,7 @@ - [Additions to this README.md from jendakol' PR](https://github.com/me-no-dev/ESPAsyncWebServer/pull/770) - [Respond with file content using a callback and extra headers](#respond-with-file-content-using-a-callback-and-extra-headers) - [Serving static files by custom handling](#serving-static-files-by-custom-handling) + - Added LittleFS choice for both [esp8266](https://github.com/esp8266/Arduino/tree/master/libraries/LittleFS) / [esp32](https://github.com/lorol/LITTLEFS) , see [SmartSwitch](https://github.com/lorol/ESPAsyncWebServer/blob/master/examples/SmartSwitch/SmartSwitch.ino#L16 ) ------------------------------------------------------------------------------------------ # ESPAsyncWebServer diff --git a/src/SPIFFSEditor.cpp b/src/SPIFFSEditor.cpp index e0885706b..e7a592e9e 100644 --- a/src/SPIFFSEditor.cpp +++ b/src/SPIFFSEditor.cpp @@ -240,10 +240,13 @@ void SPIFFSEditor::handleRequest(AsyncWebServerRequest *request){ } } else if(request->method() == HTTP_DELETE){ if(request->hasParam("path", true)){ + + if(!(_fs.remove(request->getParam("path", true)->value()))){ #ifdef ESP32 - _fs.rmdir(request->getParam("path", true)->value()); // try rmdir for littlefs + _fs.rmdir(request->getParam("path", true)->value()); // try rmdir for littlefs #endif - _fs.remove(request->getParam("path", true)->value()); + } + request->send(200, "", "DELETE: "+request->getParam("path", true)->value()); } else request->send(404); From 1f3541b1dd4e981daef465d97bc3c57920bf1699 Mon Sep 17 00:00:00 2001 From: lorol Date: Fri, 10 Jul 2020 07:53:21 -0400 Subject: [PATCH 065/551] Updates to test ffat partition alternative on esp32, see https://github.com/lorol/arduino-esp32fatfs-plugin examples/ESP_AsyncFSBrowser examples/SmartSwitch updated ACE editor js. css. gz components in example's /data folder (they are used by SPIFFSEditor) --- README.md | 4 +- .../ESP_AsyncFSBrowser/ESP_AsyncFSBrowser.ino | 482 +++++++++--------- .../ESP_AsyncFSBrowser/data/acefull.js.gz | Bin 119986 -> 117524 bytes .../ESP_AsyncFSBrowser/data/worker-css.js.gz | Bin 35483 -> 32927 bytes .../ESP_AsyncFSBrowser/data/worker-html.js.gz | Bin 47406 -> 45019 bytes .../data/worker-javascript.js.gz | Bin 47729 -> 112558 bytes examples/SmartSwitch/SmartSwitch.ino | 50 +- examples/SmartSwitch/data/acefull.js.gz | Bin 119986 -> 117524 bytes examples/SmartSwitch/data/worker-css.js.gz | Bin 35483 -> 32927 bytes examples/SmartSwitch/data/worker-html.js.gz | Bin 47406 -> 45019 bytes .../SmartSwitch/data/worker-javascript.js.gz | Bin 47729 -> 112558 bytes src/edit.htm.gz.h | 2 +- 12 files changed, 285 insertions(+), 253 deletions(-) diff --git a/README.md b/README.md index ec14bdafb..d3d3cf91b 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # In this fork -- SPIFFSEditor improvements +- SPIFFSEditor modifications - Added [extras](https://github.com/lorol/ESPAsyncWebServer/tree/master/extras) folder with (Win) tools for re-packing, editing, updating and compressing html to binary arrays embedded to source - Added a [SmartSwitch](https://github.com/lorol/ESPAsyncWebServer/tree/master/examples/SmartSwitch) example to test code features - Applied the memory optimizations from [sascha432](https://github.com/sascha432/ESPAsyncWebServer) fork @@ -9,7 +9,7 @@ - [Additions to this README.md from jendakol' PR](https://github.com/me-no-dev/ESPAsyncWebServer/pull/770) - [Respond with file content using a callback and extra headers](#respond-with-file-content-using-a-callback-and-extra-headers) - [Serving static files by custom handling](#serving-static-files-by-custom-handling) - - Added LittleFS choice for both [esp8266](https://github.com/esp8266/Arduino/tree/master/libraries/LittleFS) / [esp32](https://github.com/lorol/LITTLEFS) , see [SmartSwitch](https://github.com/lorol/ESPAsyncWebServer/blob/master/examples/SmartSwitch/SmartSwitch.ino#L16 ) + - Added LittleFS choice for both [esp8266](https://github.com/esp8266/Arduino/tree/master/libraries/LittleFS) / [esp32](https://github.com/lorol/LITTLEFS) , and FatFS tests for esp32 see [SmartSwitch](https://github.com/lorol/ESPAsyncWebServer/blob/master/examples/SmartSwitch/SmartSwitch.ino#L16 ) ------------------------------------------------------------------------------------------ # ESPAsyncWebServer diff --git a/examples/ESP_AsyncFSBrowser/ESP_AsyncFSBrowser.ino b/examples/ESP_AsyncFSBrowser/ESP_AsyncFSBrowser.ino index b12106b76..dab2f069c 100644 --- a/examples/ESP_AsyncFSBrowser/ESP_AsyncFSBrowser.ino +++ b/examples/ESP_AsyncFSBrowser/ESP_AsyncFSBrowser.ino @@ -1,234 +1,248 @@ -#define USE_LittleFS // possible only for ESP8266 for now - -#include - -#ifdef ESP32 - #include - #ifdef USE_LittleFS - #define SPIFFS LITTLEFS - #include - #else - #include - #endif - #include - #include - #include -#elif defined(ESP8266) - #ifdef USE_LittleFS - #include - #define SPIFFS LittleFS - #include - #endif -#include -#include -#include -#endif -#include -#include - -// SKETCH BEGIN -AsyncWebServer server(80); -AsyncWebSocket ws("/ws"); -AsyncEventSource events("/events"); - -void onWsEvent(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventType type, void * arg, uint8_t *data, size_t len){ - if(type == WS_EVT_CONNECT){ - Serial.printf("ws[%s][%u] connect\n", server->url(), client->id()); - client->printf("Hello Client %u :)", client->id()); - client->ping(); - } else if(type == WS_EVT_DISCONNECT){ - Serial.printf("ws[%s][%u] disconnect\n", server->url(), client->id()); - } else if(type == WS_EVT_ERROR){ - Serial.printf("ws[%s][%u] error(%u): %s\n", server->url(), client->id(), *((uint16_t*)arg), (char*)data); - } else if(type == WS_EVT_PONG){ - Serial.printf("ws[%s][%u] pong[%u]: %s\n", server->url(), client->id(), len, (len)?(char*)data:""); - } else if(type == WS_EVT_DATA){ - AwsFrameInfo * info = (AwsFrameInfo*)arg; - String msg = ""; - if(info->final && info->index == 0 && info->len == len){ - //the whole message is in a single frame and we got all of it's data - Serial.printf("ws[%s][%u] %s-message[%llu]: ", server->url(), client->id(), (info->opcode == WS_TEXT)?"text":"binary", info->len); - - if(info->opcode == WS_TEXT){ - for(size_t i=0; i < info->len; i++) { - msg += (char) data[i]; - } - } else { - char buff[3]; - for(size_t i=0; i < info->len; i++) { - sprintf(buff, "%02x ", (uint8_t) data[i]); - msg += buff ; - } - } - Serial.printf("%s\n",msg.c_str()); - - if(info->opcode == WS_TEXT) - client->text("I got your text message"); - else - client->binary("I got your binary message"); - } else { - //message is comprised of multiple frames or the frame is split into multiple packets - if(info->index == 0){ - if(info->num == 0) - Serial.printf("ws[%s][%u] %s-message start\n", server->url(), client->id(), (info->message_opcode == WS_TEXT)?"text":"binary"); - Serial.printf("ws[%s][%u] frame[%u] start[%llu]\n", server->url(), client->id(), info->num, info->len); - } - - Serial.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 < len; i++) { - msg += (char) data[i]; - } - } else { - char buff[3]; - for(size_t i=0; i < len; i++) { - sprintf(buff, "%02x ", (uint8_t) data[i]); - msg += buff ; - } - } - Serial.printf("%s\n",msg.c_str()); - - if((info->index + len) == info->len){ - Serial.printf("ws[%s][%u] frame[%u] end[%llu]\n", server->url(), client->id(), info->num, info->len); - if(info->final){ - Serial.printf("ws[%s][%u] %s-message end\n", server->url(), client->id(), (info->message_opcode == WS_TEXT)?"text":"binary"); - if(info->message_opcode == WS_TEXT) - client->text("I got your text message"); - else - client->binary("I got your binary message"); - } - } - } - } -} - - -const char* ssid = "*******"; -const char* password = "*******"; -const char * hostName = "esp-async"; -const char* http_username = "admin"; -const char* http_password = "admin"; - -void setup(){ - Serial.begin(115200); - Serial.setDebugOutput(true); - WiFi.mode(WIFI_AP_STA); - WiFi.softAP(hostName); - WiFi.begin(ssid, password); - if (WiFi.waitForConnectResult() != WL_CONNECTED) { - Serial.printf("STA: Failed!\n"); - WiFi.disconnect(false); - delay(1000); - WiFi.begin(ssid, password); - } - - //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.setHostname(hostName); - ArduinoOTA.begin(); - - MDNS.addService("http","tcp",80); - - SPIFFS.begin(); - - ws.onEvent(onWsEvent); - server.addHandler(&ws); - - events.onConnect([](AsyncEventSourceClient *client){ - client->send("hello!",NULL,millis(),1000); - }); - server.addHandler(&events); - -#ifdef ESP32 - server.addHandler(new SPIFFSEditor(SPIFFS, http_username,http_password)); -#elif defined(ESP8266) - server.addHandler(new SPIFFSEditor(http_username,http_password)); -#endif - - server.on("/heap", HTTP_GET, [](AsyncWebServerRequest *request){ - request->send(200, "text/plain", String(ESP.getFreeHeap())); - }); - - server.serveStatic("/", SPIFFS, "/").setDefaultFile("index.htm"); - - server.onNotFound([](AsyncWebServerRequest *request){ - Serial.printf("NOT_FOUND: "); - if(request->method() == HTTP_GET) - Serial.printf("GET"); - else if(request->method() == HTTP_POST) - Serial.printf("POST"); - else if(request->method() == HTTP_DELETE) - Serial.printf("DELETE"); - else if(request->method() == HTTP_PUT) - Serial.printf("PUT"); - else if(request->method() == HTTP_PATCH) - Serial.printf("PATCH"); - else if(request->method() == HTTP_HEAD) - Serial.printf("HEAD"); - else if(request->method() == HTTP_OPTIONS) - Serial.printf("OPTIONS"); - else - Serial.printf("UNKNOWN"); - Serial.printf(" http://%s%s\n", request->host().c_str(), request->url().c_str()); - - if(request->contentLength()){ - Serial.printf("_CONTENT_TYPE: %s\n", request->contentType().c_str()); - Serial.printf("_CONTENT_LENGTH: %u\n", request->contentLength()); - } - - int headers = request->headers(); - int i; - for(i=0;igetHeader(i); - Serial.printf("_HEADER[%s]: %s\n", h->name().c_str(), h->value().c_str()); - } - - int params = request->params(); - for(i=0;igetParam(i); - if(p->isFile()){ - Serial.printf("_FILE[%s]: %s, size: %u\n", p->name().c_str(), p->value().c_str(), p->size()); - } else if(p->isPost()){ - Serial.printf("_POST[%s]: %s\n", p->name().c_str(), p->value().c_str()); - } else { - Serial.printf("_GET[%s]: %s\n", p->name().c_str(), p->value().c_str()); - } - } - - request->send(404); - }); - server.onFileUpload([](AsyncWebServerRequest *request, const String& filename, size_t index, uint8_t *data, size_t len, bool final){ - if(!index) - Serial.printf("UploadStart: %s\n", filename.c_str()); - Serial.printf("%s", (const char*)data); - if(final) - Serial.printf("UploadEnd: %s (%u)\n", filename.c_str(), index+len); - }); - server.onRequestBody([](AsyncWebServerRequest *request, uint8_t *data, size_t len, size_t index, size_t total){ - if(!index) - Serial.printf("BodyStart: %u\n", total); - Serial.printf("%s", (const char*)data); - if(index + len == total) - Serial.printf("BodyEnd: %u\n", total); - }); - server.begin(); -} - -void loop(){ - ArduinoOTA.handle(); - ws.cleanupClients(); -} +// Defaulut is SPIFFS, FatFS: only on ESP32, also choose partition scheme w/ ffat. +// Comment 2 lines below or uncomment only one of them + +//#define USE_LittleFS +//#define USE_FatFS // Only ESP32 + +#include +#ifdef ESP32 + #include + #ifdef USE_LittleFS + #define MYFS LITTLEFS + #include "LITTLEFS.h" + #elif defined(USE_FatFS) + #define MYFS FFat + #include "FFat.h" + #else + #define MYFS SPIFFS + #include + #endif + #include + #include + #include +#elif defined(ESP8266) + #ifdef USE_LittleFS + #include + #define MYFS LittleFS + #include + #elif defined(USE_FatFS) + #error "FatFS only on ESP32 for now!" + #else + #define MYFS SPIFFS + #endif + #include + #include + #include +#endif +#include +#include + + +// SKETCH BEGIN +AsyncWebServer server(80); +AsyncWebSocket ws("/ws"); +AsyncEventSource events("/events"); + +void onWsEvent(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventType type, void * arg, uint8_t *data, size_t len){ + if(type == WS_EVT_CONNECT){ + Serial.printf("ws[%s][%u] connect\n", server->url(), client->id()); + client->printf("Hello Client %u :)", client->id()); + client->ping(); + } else if(type == WS_EVT_DISCONNECT){ + Serial.printf("ws[%s][%u] disconnect\n", server->url(), client->id()); + } else if(type == WS_EVT_ERROR){ + Serial.printf("ws[%s][%u] error(%u): %s\n", server->url(), client->id(), *((uint16_t*)arg), (char*)data); + } else if(type == WS_EVT_PONG){ + Serial.printf("ws[%s][%u] pong[%u]: %s\n", server->url(), client->id(), len, (len)?(char*)data:""); + } else if(type == WS_EVT_DATA){ + AwsFrameInfo * info = (AwsFrameInfo*)arg; + String msg = ""; + if(info->final && info->index == 0 && info->len == len){ + //the whole message is in a single frame and we got all of it's data + Serial.printf("ws[%s][%u] %s-message[%llu]: ", server->url(), client->id(), (info->opcode == WS_TEXT)?"text":"binary", info->len); + + if(info->opcode == WS_TEXT){ + for(size_t i=0; i < info->len; i++) { + msg += (char) data[i]; + } + } else { + char buff[3]; + for(size_t i=0; i < info->len; i++) { + sprintf(buff, "%02x ", (uint8_t) data[i]); + msg += buff ; + } + } + Serial.printf("%s\n",msg.c_str()); + + if(info->opcode == WS_TEXT) + client->text("I got your text message"); + else + client->binary("I got your binary message"); + } else { + //message is comprised of multiple frames or the frame is split into multiple packets + if(info->index == 0){ + if(info->num == 0) + Serial.printf("ws[%s][%u] %s-message start\n", server->url(), client->id(), (info->message_opcode == WS_TEXT)?"text":"binary"); + Serial.printf("ws[%s][%u] frame[%u] start[%llu]\n", server->url(), client->id(), info->num, info->len); + } + + Serial.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 < len; i++) { + msg += (char) data[i]; + } + } else { + char buff[3]; + for(size_t i=0; i < len; i++) { + sprintf(buff, "%02x ", (uint8_t) data[i]); + msg += buff ; + } + } + Serial.printf("%s\n",msg.c_str()); + + if((info->index + len) == info->len){ + Serial.printf("ws[%s][%u] frame[%u] end[%llu]\n", server->url(), client->id(), info->num, info->len); + if(info->final){ + Serial.printf("ws[%s][%u] %s-message end\n", server->url(), client->id(), (info->message_opcode == WS_TEXT)?"text":"binary"); + if(info->message_opcode == WS_TEXT) + client->text("I got your text message"); + else + client->binary("I got your binary message"); + } + } + } + } +} + +const char* ssid = "*****"; +const char* password = "*****"; +const char* hostName = "esp-async"; +const char* http_username = "admin"; +const char* http_password = "admin"; + +void setup(){ + Serial.begin(115200); + Serial.setDebugOutput(true); + WiFi.mode(WIFI_AP_STA); + WiFi.softAP(hostName); + WiFi.begin(ssid, password); + if (WiFi.waitForConnectResult() != WL_CONNECTED) { + Serial.printf("STA: Failed!\n"); + WiFi.disconnect(false); + delay(1000); + WiFi.begin(ssid, password); + } + + Serial.print(F("*CONNECTED* IP:")); + Serial.println(WiFi.localIP()); + + //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.setHostname(hostName); + ArduinoOTA.begin(); + + MDNS.addService("http","tcp",80); + + MYFS.begin(); + + ws.onEvent(onWsEvent); + server.addHandler(&ws); + + events.onConnect([](AsyncEventSourceClient *client){ + client->send("hello!",NULL,millis(),1000); + }); + server.addHandler(&events); + +#ifdef ESP32 + server.addHandler(new SPIFFSEditor(MYFS, http_username,http_password)); +#elif defined(ESP8266) + server.addHandler(new SPIFFSEditor(http_username,http_password, MYFS)); +#endif + + server.on("/heap", HTTP_GET, [](AsyncWebServerRequest *request){ + request->send(200, "text/plain", String(ESP.getFreeHeap())); + }); + + server.serveStatic("/", MYFS, "/").setDefaultFile("index.htm"); + + server.onNotFound([](AsyncWebServerRequest *request){ + Serial.printf("NOT_FOUND: "); + if(request->method() == HTTP_GET) + Serial.printf("GET"); + else if(request->method() == HTTP_POST) + Serial.printf("POST"); + else if(request->method() == HTTP_DELETE) + Serial.printf("DELETE"); + else if(request->method() == HTTP_PUT) + Serial.printf("PUT"); + else if(request->method() == HTTP_PATCH) + Serial.printf("PATCH"); + else if(request->method() == HTTP_HEAD) + Serial.printf("HEAD"); + else if(request->method() == HTTP_OPTIONS) + Serial.printf("OPTIONS"); + else + Serial.printf("UNKNOWN"); + Serial.printf(" http://%s%s\n", request->host().c_str(), request->url().c_str()); + + if(request->contentLength()){ + Serial.printf("_CONTENT_TYPE: %s\n", request->contentType().c_str()); + Serial.printf("_CONTENT_LENGTH: %u\n", request->contentLength()); + } + + int headers = request->headers(); + int i; + for(i=0;igetHeader(i); + Serial.printf("_HEADER[%s]: %s\n", h->name().c_str(), h->value().c_str()); + } + + int params = request->params(); + for(i=0;igetParam(i); + if(p->isFile()){ + Serial.printf("_FILE[%s]: %s, size: %u\n", p->name().c_str(), p->value().c_str(), p->size()); + } else if(p->isPost()){ + Serial.printf("_POST[%s]: %s\n", p->name().c_str(), p->value().c_str()); + } else { + Serial.printf("_GET[%s]: %s\n", p->name().c_str(), p->value().c_str()); + } + } + + request->send(404); + }); + server.onFileUpload([](AsyncWebServerRequest *request, const String& filename, size_t index, uint8_t *data, size_t len, bool final){ + if(!index) + Serial.printf("UploadStart: %s\n", filename.c_str()); + Serial.printf("%s", (const char*)data); + if(final) + Serial.printf("UploadEnd: %s (%u)\n", filename.c_str(), index+len); + }); + server.onRequestBody([](AsyncWebServerRequest *request, uint8_t *data, size_t len, size_t index, size_t total){ + if(!index) + Serial.printf("BodyStart: %u\n", total); + Serial.printf("%s", (const char*)data); + if(index + len == total) + Serial.printf("BodyEnd: %u\n", total); + }); + server.begin(); +} + +void loop(){ + ArduinoOTA.handle(); + ws.cleanupClients(); +} diff --git a/examples/ESP_AsyncFSBrowser/data/acefull.js.gz b/examples/ESP_AsyncFSBrowser/data/acefull.js.gz index f795265513b69a806659da016f00ad4d78ec4b24..e88a884655abb64466041d0be61874b93598a18c 100644 GIT binary patch literal 117524 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 literal 119986 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 diff --git a/examples/ESP_AsyncFSBrowser/data/worker-css.js.gz b/examples/ESP_AsyncFSBrowser/data/worker-css.js.gz index 0ba451b948d8798fe8b21a6e20d779c64ccdd0fb..658f04aff7224a0bb99abbdd273f99d8ced0b420 100644 GIT binary patch delta 7007 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 delta 9568 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 Ks4O;XCISFtYmQ<7 diff --git a/examples/ESP_AsyncFSBrowser/data/worker-html.js.gz b/examples/ESP_AsyncFSBrowser/data/worker-html.js.gz index 496312885798882fc08b5cc91d5fbc1d686cf414..1556f5a8dfa9319797730cd5ec88e48ac19f36da 100644 GIT binary patch literal 45019 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 H;4A|G@j#CV literal 47406 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 CEVTpx diff --git a/examples/ESP_AsyncFSBrowser/data/worker-javascript.js.gz b/examples/ESP_AsyncFSBrowser/data/worker-javascript.js.gz index 9909a164a99e567cff41557c05ac26b9db42d6cc..2b45889847baf8b0729068fe6bc8691913e6dfc6 100644 GIT binary patch literal 112558 zcmeFaby!x-x;U(&bcnQ+A_6MiQYsb_QU)T8LAQhmh?LTZ0+IrP0wN*Zh=52VDAFO) zEhY7>C)VKJ=iP4KSl@N7^Yb5F%sn%A$IO~p53>(GK6@&j_Kt0K=2phnt+yv6OSx)fX#M%x^N^dVm-JHR7ff6pUgg?*#bR#6fUPXzl-1NQ}Fqcj7#it z#;cs7JZH=G9`R3tr42PjO2e-7LdK;>EgFN?uXU+FJBn2h{ zcq1FPH9wPWT5Y$Klf*01667+agi|*>b4_nm`oG-|)9eveuu|~Y5x$Ii`VPQZfBrNRwX43{cG`PH z&(zj>@C_?eGNn!4GB}4GJ(Zs|&Jp6&f6Zm7+qUYs08Rg0I<80B+MHS%+N%4=d6-1( z83TIOz7Kr2^|#)hFyG8AK87Qb`Fu9vt^t+2a(Z{tt9q+&g6G1`OUVxJSY6&po!z8f zIT^pvXEf^=anxv6P4Z+2^Q{P>Oy?-7YFW#q(vD{N37uE<(n^Es*OT&<33ChFe0|)W z7@ND-2&F0>Lo^-~rzS$$rHu9)t zA|rm_?!%3|i#vR;3Q9%`T?u8`@ll4A!P3wu&;JEWKsldJc&)foWBY1^G~YQ*^;UtH z4rS*W!8Xp2s6hUM89S7AJ$=~S<=-El8GAP;6z|eSBODT8i;}}senlD$AyEQ0?2K3M z@9YZ|-+Q#4k!>yW+uYT0VRGNQyXy0g@QM&5UfnF@)lsHVyZ*3aq1fPrVfG9E>hHI7 zrB(;xBeQmTcW2-k=HnF5dCJ)3PmcydmHcrN%ri&!UprsRiWSoD zUT1SvswL}1}Tf=IifA3>BMd>HCe9d*gVhTbUE56l~T~=QElumIu8&^iXG&&|@ zTFGXtl`A1o*7?=q#TS1aU7qcXdrlfRGb<$eJ#C4bd%bp2n2g_g_jM_< zrsD^$mr1&Dzw=VwB}*Frdbco7wXpYK+RUwLuRx0<(fb+;jIMsGn-rsExNb(Yi)l>$ z-EMW$?t65V%pMaWT}OkeC3;+p0|%pz#C9r&-F^1_z~xdt1qbGB6NRCr^Ql@URB3`d zHpfmfXXqH-dJ}o!Uc@*BE=6cy7!`GzRZbjP*}Dxbm2JH~g~3+6Q4c;>o+#SGPkm6c zsVi+DJwy6!`hAvbtsfs|F>8jZ%U+!GKW55anCf$4pr~6y!*FfsPSvD|lbFnM&M~pW zdV-hdn~d{5UkI1n!9@FBI<$jFBmcEPOXG`ISC>9_1nr(2c8N|F8`%Apkkj{?FJF&K z@#?Fa1H&`9F$DG@ug{X;NZRfscM_wrnU7EED7MhbS;G^&{iOTLeC(qh`-Y zPSGXV+#^q>yK3r99>{;(2>+XN(uwf;WQ{#*x3W7linXOYMz>u~*gxC9dRL-#c=ZhN z$Esbbw3%JOjGtRRvnB-b9*(qZdbOK-RIr1WU(DCCP5OqRYVhl~T)b2-{cp!K8t~0e zC&xSMzU$7K_KIy}kGq1$ax88S!IPSW%E5%-K%@NVxFN+2-yy%6mn(@fN%k&HggNB#{{oXo^>1kZbgX$1irsp@FHlM$Z@$M7D7 zZYL7h++2~T@c6tbZ>8QstNZXvovw>@a`y7xS}NB|Wcnr}6MoLoqMgrN1I}=l-BFnv zK563qW&579+c>!x=-0{R@;T+om_CsQdU<4Q!!PnWT)JK$-As`}_M}Jww_W1g`Vk6p z^Xk4yq14J*udliqLvNka_Z@3_I}tPCFWq?ASutbc%||g$mj-=%rV|HrcJr~MM(<+$5G5@UhTpqXDKJ}JOq;T{#0s2e=*EZI?2gyOv2M#Jn7Kr6^ z?Yt?=c7?3g@8}hOJrC|tk;f%os*NeL@|*&q0o><~D(G$_&{?0dNf8aDS#)?gU9kCO zU#YpeD=#^o^ic3!14?F&OVZEpraiBSiVK}?TB|(fAn85cZ03;M(s*T>n2fRnN9I$| zg9@jKF7jbD*JkdZ+fMg(yh#%~D|_(3=J>t@nvYlX254`d|57?>pPKTV%-We>wdZA- zRlCKy>>Gkh6Pb;HdQVi-8w`lU(+h|my**A5vDb2ZTqW8#zdZK?E_+3_b(J}BU#i>q zXwLaJr>~dXAe{b4Ud@Ds(XGXYHyb&7UcXfSEI_o$$*!YX zgl8xa*7mq-fV)Y9II2O_oQtCccUot(?jIL=43VeMzQRIV1En@Y-KD4pjkR#GiUTv0?D(kv{KqOsO zq)mr#tUPC?Wmcz3V!R+n*X4I&TyG-_BxC09Om>v?80D;v555!}yG@d=E*x9aaB1g* z^pBc0gbtTEllEDsbq# zGj5p=o4m_@Et2^nga|+7()Gd0h--~mjp4?-IwnOv_zt>yKhheIZeD+UkFm-9*=px@ z($R;PS}#PbD0HgW%T=67-Cs9eJ@)ENEb}dEiEy7J{~Us+mOp01UhGJ2&>6yuL`Muz-QF+FJp(MM&I zJ#>lnZQ;ZZ>=NTT=Ph1SHWY@H-N%g%l(3+FmU)bposCPVdfL(LjR}9%&K*ptRL5Qq zZ0oYWpUrxk@c74){Lkq_1rAd~nj-T@9UcWT5ngS0K<@Y^X)*f*-fO}~tq(-jwJtkI zGmFf~C(9+`^8+ z-oB6q?}O#`Qe1=Phs$gwBl)-j8T|OR=Z5BSiAQ&=O0Tf6zv(V!8@IjjYRW@VnoBe2 zJWJ-8gQf+mrMF4fP2VbhvF+f)4avRvs5NsWuQKB(^|R7iz3)N>x zwp}WWs*%<{dBLjYqRMh2f1`)J?U?*v%lBdS51w@sSp$E+h9`1Es ztMd8%{rd(9LUi8+yc|^Rv37a?+K<%kP(neO^Z}Q>R;SvVz2?bGXLUai-VXdyEbVpv zc-HX2taHa-a*!V8P*kk*Yw~_jpCnjzqEEVo;(lhvl4X_I`E#RUUyab#V<9sHG|vw*PK2%j;S~fF`AIxei{?r*r!G@;!Z6qnuV9i zG_~V%)1(FMw3^G>zNsmph*Sgo56{x>rBORh6HhTXbotNCtuP3^T{RG#3}$qH#>aZT zI>+}>WMJ6K;5_CW{SjjEGx|?QaXzV=wQT4nwU;^^_;#?k%lD9Ru#5$*b*Wy$E=QIA zTThd#n8;Y`b?hC2%>4$fzPGm)swg=Iq`h%_$XG2A9KAnMOs)6!-U{Nc=Pulqxffu- z`-0VNyO`eom_Cb|kHM?a8w#YG_ep5`^_DwK^ocSpi9~D;gnnb;d={}=ih|PPO9<`k zbb6oqjZr#I$JT>~y7!T}o!_?KM`WM8z9GT>3&*sjoqTDP==Qprw&F)}ct(Hdd|Z(y zcQy_e*R(fXLzwzJ-84lf*)w*5k#Ql*g-4eR?-%Ru-8I41XnttAleV_rJ|`R{dF|@P-NAHzs#dc*LtpL}RG<7P z7us3JZcOU<`SIn8j|;0CKD7y*bMmqdo~F0|rgNn@aF}N7yZ=|7Yv&mx=L?U-u;|C) z1kDpUFwT)&J6&>Xuc9_v7&VhbyjD@}q1%LCz90V>a_Ux#ANy00y;{zp9PQU^b1arE zo(z|(CROS`&u5AmI_P-k)5L4C>57O3hSPPX6%(wLDZHfdgG-SQmWKuI-C|UrsIi^#qJE( zSwD=wKPy_pD0}aQqkyP*HBOg(@p(hK4_-U@8w8%wlW1mL=n9++avn&tvFa7BS@SuQ zA1Y-Yc2T9(hVG1b&FpKDxX%jm2R#ockB5*&jLfEpSQ$rjhLgN~aHu(&xvh!e=B^E& zlH$4p-;SSjbYy&?L6Q|@zqnw2V37Kol6;GUo1HTGa&DOSrU+TlLl5=di3+ZBzR?ea zJ7?nuI%Vg(SxzcBH3|^TRo0x=vhDj`^0`0#Ynxe6p^@MYqG<-{>#M!|xZi5|)dShD zXXzyQo>&uPE_&j7^4p<9AL^@{O)U*==O^guqa_OuJ}5gx{XD%QHob<9P|Ea^C82%8 zQz1d+Z-nbSYjG`v7AJGG&$)jOU82t}6Be2HS{*>)G`$%nU%#%me_Y1Tp!AAF_$^gg zLZbK!t->_#o38SXrW7^jGDdI4(U5a^?$~uEPQm+_aCf-C$EByjk>_5|4x12|r`L^n z#HLWSN$w_4crPlnpnm$B#jL>4LSn(OL*IBfI7V9Bd=-lt$0#q&f<;@S@MLKX_q9UG zMHlY=7n&bKMH|y+PWq+}$SvfTjJg)@>AuQk+kJ5Sj@q4;8To7?n3K<`_-0Rt|y$knV$f6F8`&}*J{qAooq5_+G zY)>XnX($`M{Lrz#sk=lx=R;n@!|p!UTp>A4c3Xzcm4hGnCN+lpT`o{YZa-l)PwnDB zooM@U*WkCP&kaq_&pL!G8?W_@=LJtFUN>QR+Hkc_JJhg*|7@I_>b+#O(A4i2o~3NE zW_o`!9eTj}m9^aAP7W;x)v$5<23cK3n4aF1TeWQ0vOE+74CpGy>D;S?s%&0eCzjB*{;5fTsSVqipjpJzf?n)cgIA`0CWIL+*yOkpw zJ5FfcA8!_z*>_?hOKRu#gT*fG_)L6k!rMgy^8{l@duxho-_?!!WlD-_CX(~5_$%{u#_<(?vkj%Q=~wHObBz|n-+e^ZC$LOZ z?AZ0gV=rs2<`5N_dYKT1lq)Ek)5-Q+TUeUTQ2XzM)vN-JCDX?81V7aL=4k9Zt^G*^DKWFr14nox^s0i@9x+sQ{4!G zfbRzn^Tybx*qUpKMD#8i+|pT~do;r6>iOuyou~fC?fmgSrLYK6*SdP{$Gc#=AQb*d zi2DeOmuGL>*^v{BxX-3D_8d7wF&11B@Y)I|edWHUA8w{KX|Ge6o7O#1QIBgzWJfGU zC;K@9Z_(}YyL-iuOB+W-<~_dz=eDEaCZV`Z>muJuReibmjT%%0T3YWEKtQ$9b2ySYwV23K;li7_o#6-;&bZ<+)hU zwT&fPYP}=!#hZgZ!;P7rbE|V#S&Oe~aLpz^O}YO5bbd;8a1hIqgR=wqo&(l_C&YH& zk)D=v_%>$Br;-|9vXK4hdzQJ=aCUU(N0GsM#}pI4KP0r(PEPjV4)55fNnG`DD7-U! zLDq~ukzYgQb)a^Gbcx1SC!67~5pLhIHD#$xaxLb`FABx&@V&Rdd)$eh)xE=~W=9Y+ zW!cL;gvLRy9oBKeHN7(5b}%O3FL``3Nh`(ab}dpS>@QcmTBvENPY zWX%*M5`4dLjhD|BD$nG5v556tT$bQEMpD8fY?c#Y6>rL4>mkW2#1!_Oe8M3KZ&Wjj zY>F>zeEY+K(^XG8nX6g+LIeD${lv{W#?F%95XRH_Nsjq=^X=kjfz*FOqr8>X>X*3`}i9{IBEeX!|bu;EuNxg7jM$F`Rpc0VR( zBq6NuRnA6M_Vo4>iKmjkF1%SgGQ!-s$#x5W|I6JT1hf*-3#;_T;`A4TbyvRFE6^=u z$uT-7Jb%d{E1!ZRTd038-Y2E!DbqJza?5L0yml2-C#9=C41eydwc=k_D>;8Nc$f)y zcT(v^@A(C_Cej1pBBm-IN8cNd2(zcFBJSLPW=NF9OY^b)UN^;_%BOSdNA{HyaQ9gv1=PAULnC@Cskf@?J z;}~X#JEF->XR&u?`D}IfxEcwLE^P@NA>kR{Nnic>ln0YCHk23A?{egAcYa27-;sTu zg$w_LWi(H(D7$Q&>G_QF`Lh)(suLqLt4~61n_7OKFw7p`JQFQ3c{|&?D~3jC*J05 zdgf!DG1Dx{NTa;HRcy)ksHA$iG+FFU*j~UHeMfM9uOnjh<(!9>p8WKD{plL_>mI@g`jRXAUNu=!N?v#>>G);&P79{1$#I8-Hnilw0~DSP^kfV6IQSeTpd%`+K_oOiVTX18C-@#IUp z*U&x)mY{9xoAND&aJdK-->tXq_8t^4C3HIx{K!z1wl4gOtaw!GNPixGxPIL!AH8Oh z%l0!54U{d+{B?tQnnAJ;0c>b2a_bW@6TP%EoI_@Qk+SZ3t=03f=j8pNHf{lb9 z?;!7c&jsGw9u<6x`Ioeri+H7Vvd*w;&d3vo&kG*rPxU@Qb6{r}L;RWc9s2zK0~f^7 zy8ZCD_g9S2CY8m#Aj)|gw*8egqyIelUU_dy0~L8S!6XmTb{k^`QOWwOriNL;JO+{` zHayRA4N^W4w(pwPZk-aPN@=PoQ(Ux>n()=(JxmyX_@(x9efi5z1BkVgnk%lxHkaS` z5Uz})XFDtDC)oVP>pUqZ3+LWC|7Ow&*Nnpw;gJsAk28$pJS;yh>4BY-+06rRS!dS9#;+1QQjNa~s~utFSX<8qv7n28r6sU#96Q z$!H}Gn5zjMiZb&&9Zu!LRAu%}U;Hi}x1o~0JQ)oe^ZHBXi4H1B+X7m{ikIgaviM}5 zown?Ie(am$8J`(E({0rH2h|PZRozHP+ycz-S-5=Tsa#!V?$tE5(=?qHi3!<}n$?`- zT0SxAMUPuN9Dk!-BL4KU{wETj3`nx)pAQr}y>$zf@fpxy@42MGyONROT`BY6QpZSZ znGQGQV8AOO7A|j`6fdqa?Sj##-c$z4f?|}o_05F2OqF(y{oPduTc)+ccva#~H;*XM z);*zK-mo1imxE~3ArjmOE3VahdCDiQIhNPpNr+vjAj32YRsF8LrA|&2G7qRv$Dh>Y zy?j5H07b%`ym%xP2(<&6r?4SC;j@Zrj1t6gDX$6 zzUWq$c7d4qhN5QF=Z{|^c_x}0K20=>F}l>8pA>KuJfqnvm8~kikz!{Q>zv1_`f{g& zE~D8}|5xAK+q|??N1gMIs&bwstN1QXl%=Ml!s>PvKzngI296 zw|hImE)pCfyosu^6EuUQ*uNCrT~8jDJ^@X=oyM?lcc4-eZ@NXsvfS9CA#BdN z85T3AP?J$+aj2n?pg|2Nigk5dy9F%pn;NY9j|UsjZt?RG1MR;%O9v3m0?uuMZeS_V zgJc1TA{sp}MikhIp`ijzd7S%D;v*12i!X>^7njy?6!We<#sV@NYNGaU_LDH6h1vcX zBGp@pk97NYlQ;WNvOFcWQ;_&22Mq;ANHb`8@a982m2`_WW0=MvQuK8_DZRarUS|nV z_iZE}Bjh*R2N^~CK0ypZxOA2nc6^(BeV0TQS4Ckdl72h>g1Ny{{O0OBCWtaL`#9nq7|CS2R+Lld z!vZJCijc>E8KiAcc2vk`fsZy#og!$Ol_CF=C<&KSjPD-6j4#F->0|@3hWrU1609LF z5^EH><0?e&dNzVKVmFN8VT@P^np5Wvuv!TmFHE1M$4@Y_g%H!2ZJ8r5JemHLQ(Gnj z)U-8s-vc5U4z#u)>TIYnhE(>JgdyxLO7gIy>1Y6%Xk@vbyvwb{!yv(zj%{3Bc=J_Z@c zmVadcLJDZb?cb1K-Tyo%4K(>vpO^#Uxw^F8uKPLyaeAJ8H?MOMcDS3$ShXW-2S0NMDvV>jBVn&i58&fpV5-l2-M{(dFkJj(fmdkm^ zFJnVeNpCpaa>WWAEG7;dJlhCNj2S|^fq|&b5>`D$wOZJq)EkdxN{jpwDjLm5cA=af zEk72BA`X~}9AXC2q~#(zouRwB%1 zDAl`;=em#ezWIYO&A5x~QSVa)+6;@InI`0jjU_*q>M%=Ai5=^)6l%R7XL_skqM}pQ zrwf-)DqLKOUNmn_&`&JbYm|)bEB4qZNxei_(aEO1^@7iKEP zWbBG251q~6{n%sYZ>+4uDB6$sCb=BzF3(-Eo)Q1P?_x>fc&J)>iAJr&ER#?YRRZFAM6g_{yU6X=xX*wGguZ&K0Cy7U1{&T?h6Yf z-uUu0CM?m9n}L+!>{rjNx~V(ihvy&asqX9_+WmfbPW|CI>W62^t-4HtDq^dSi~8YN zGi<9}GyI3=AL>5MANqIy(7*eK{@p+H?-l?BUS&lDnxFyY`mJJcQCHUPs8QRYb?wA& zg_DH`P!;3e>|QjvW7Ah&K&4^#QWxmox~la9Qq2Om1|3b52leRatF78})a-|Lvme^0 zerTWCqW5-81W2Um7TCHC$G-vu=hNt#4pjrDZv|6oQ#j+5>4AW$wv}vrFlhh^tU7Qd zLQR@w0a}}+@4*GC4==h3LUr9LP&nUj;fJDddKfmT<`@IK16z2Zx&aI4db8D<2WO4# zzk&jr9Jf*f^?yUv@>5iOqHqc)ReQ8W2}nXZeAw*SHHj*tKm}1Y0Muci43cyiwjfaJ z+FsoVi{`kGFkqY-T_vF^PWLc3sB(l;YbBU1-5yjJ>b_g87SuxNKhz=Ve?kBse=2}K zRHy5pA#KJkE;F6}oy@Zn?x6gUAP2;8wrmk!wq<*wTde*dfSX&xw#tdqp!`Xf*&4OA zs)@sDMvb^S4PAfGI0D1e>ED|14Vn7*=ZEr2w>TVhh=yjA$0QvZGH()i63ZO~ z!8g~AK-tO7$15!g|I1k|3DFl|5=I$HZl=idsBzpA!swJmLpCLj#Vo;Lwoe&KP~1$u z+D|PkX8T&1Z3U!^((~+>o$AWUqXS-x=Gmtgx>ma0hz7NxB$H=9Ln^T20hAhNbwUBY!h8*0guL31p2>-)!(c4EF0mva&)~%j4%p9 z#>TD$CFb+yPkEs=k8AnBoi%ulnTO&#R+Q&0d6*(gPy%Ampxwm6co*~O0FC^C&}J?k z4O!Ke1{5F(+Rsc$?SQz&drl`q39*e=NC+#T8H{B^AxDj+mq8T_gM;5hM3kT2{VS+zC@K6 z)#HV3z-%si`=Muqlq!IlkZ2G?=ba+RKHbJ$U|R1~J^+{@j?m`o76;FQvR+!+MzIP&_0AuF2D>gz0q>}krYcZdeV z?*SZ?30TbPXux=3bH~mC0b}zZiE-QaN616}mwcuKJt0kC1af*8)-axq9G9Mb-q+(t z@2$&0DE#H_+W@6azZKI=0qW@!Uz#qlL6w(V9F_S@`pjo04Pqv0Etdyg3(v2*;T`LN ziY$AzHK~Cl5H#@gf2ps?DjaV(<1kR1_KPD4-2RSw+HlobO@ zmSo&0+03LXy)8eDGDaq9Z;3o~saGMbj2W&*y98iIVc0AwJa7U4d*LT-H;KMTA*SY z8PVXss}{11?=Wwbe>C?#$ZDwBw!}VQ2W0#&(__eE0TO5hTuDJ(QDR8rTs!a%Ye1{_ zQATHR@IMSd8K*QK5JL}`4Or7Gth<3DQ@|)KQQ=3225a=9kHG|JIie(Rni;mZFd!Y2 zM__z|2?j31wl_;<`BxbJQ}oXP!9x)P>#t~cMiUHZdI1P_0!9UBD*`~^4Fj<4RbFo0 zk`NI1fA;tPY7{_Tu;hHwMz-7*5PTod6H2MYW{~OJZ<-w*z)3{e-QvC!~cQu-tc@a zSSuv+={*bL$~!>wA1ABh7)EEJ79OMZ*n9R5!=!WuPH^u)MAxs;5l2e-dge16rltQV z#h#9Y2y?!mKO=QpR{}`pKSg`Uz|2EYQQ$=YJtp7aK#A?=nTHS>b9oq(L~TX-g;4(b zh8qOIe@#<=Dr$cR(#^wLnvQW3uTt6P>B?arOL9#vQ*x=aT}Ae=&Uboywy)J^;+mj^ zgVIFV8|>3H9o+-U2GCM~<8XR<5QiXCWKuG!wL`2xrJ^?lc%lbSG~kH`JA!g*?G%{i z66#5*2u5Jh1NSG4Svm8sz0hcFK^s3HfC``>(U_08b>~i3mIaBz7AtV45S~ zNgO=UfvE}M!Kd-4g&`A$YWIPi;0YHz?E+6&bVMHFn|~FFD;9;@ycytI3p|y;Qd{28 z!bnu2Jr!yjK&@v`RQeGGYhZO#^~XX&>&;dK@C)mRiBcPjhNG*`8^)vb67yuw+vDot zcdDElhln06iTJ}x1`J^~s3Ga%C{Qf4#OU*bh#o9=qrs3+YI$aJWN`e3lAjZdL!?@LJa*toa{(hTlh3e(4QY`yU|uS)W(nts5| zqCxs&uV?{eE$?5Z5U3KG;;Y{4C^5*`yPTo-8J zw7~kn16|r}_YMWw=dZBaKDX^SuKQGFXPuoroji3!#Zder{51IK%2RyRsGj_ub7aA26RZkz^h)N<<~NfYDgKa&hUqE3VYR_on+9$4X*rZvGSt3 zqE;ufoq?MmV2@w7Rsx&9XG1Oz(^{TB->#(+`LlfU7iRM~`3N!tkZ;#QeLb6FF<*7JH zT%)%cVTqB};Iu$!0NX8lltdQA(Q+|s01}dfCA3Nki*EydTI&#lsW+MiBShg55m=zn z5!9sIOP~i(Ng){C3xMEByK@*8!z7@B9*mgB0Od>>A)%Trg7N=ta}R1n2>6wm@Aa00>-@)S(dw5tzi^bstplEroG) z3&+5Z*}x=Bf%g9ahuG*81t#>9;Pp2gVlCGJ=nxr)ST-LAB0W_uSAc8I~!C}4Dp zf7c<_a*z2BwI6>-yK|e`NoE~i*U{39(u;BOl5%!#UNyA?`qp_irG2_{nafZ*cd=u! z4=du7684f?+DR51T3P+oV)Vugufvr)P`;WXVPfO)38?RHNreY=(@4l`Q8PzWBy^Tn ze7Qag)e8j_a8n^@(uSufEhLAbj`v{n0stp2jPnvaV2TLFISFtQz)jtti3dAHZSOk5 z9Jnl<29k*e_=#bXiUH45Fr%x0QE`}2JJ2KoH!Z=8&eLann0JP!*qHJ`7=hVYfF2lhJ-`X1dKIRq0Jd?tT;RCuu=V`*WmNe3v(d;U z_W-aDggk*AX#{k@K7cWZ0Q)e9P0S4T&CwEIVx+(3X!J-U`0dG13I@viQ=YumT>~ZP ze$#_teqvO4rf&L*>9cs>dMWP5@X%eydc!i=W%}Je1d;1ks zY$t%5xG9b_G{f)S}8~Tfo## zxXBDO(O}6Qnm!MpH(;n4m?IkCq=)%j1yU1-aoT~VEizz1&e@3or~o`57c?otIHyQp zrkns%j4)1d(6mJcOyf$SHo_cCo1KEGG=p|pFw(sQH%$TiCE_1`X6Y{EzI^4rx1GJq?>IGM=_MMT4{*)gv9SFM)V~P{3A18iDy=L$J9DW$$0i z2|OUfAe3|%L6n7dkTLbdRnP>2{SwF*B_MW_!ig>lG=bc=4wJps{Qy9r*GHI|Bo#D) zVDAX>1qk+LcyNw74?EKoAj27^abxNX4E?8FZMjgJr!)qT_y_r@x77PS-~}1>%n)M_ zQx>}9vcL%%p`7iAI0D3@Ino?-A|1@5kPhZ%e=QV3YnETEzDp72ptt_FC!^jyz)9c_ zq8+q=|68HLPVpGFG{dY`|7el*7gOr5+Y!=>EIV;H_1Pelu_@rxSAbB)_Cq+OP0=9C zK_S(jil+^wF@Ju$;RezH?+DU%#Evuq#5YX-j~B=DF(<`@16gsm?+a_9-*?<#PH|%C z{h_pCQZ_Q^^x4pya%cG$-Hf9}&>;u*FbU|4Rw#7Bj06T20-!dpgPI8`4|Fz-2h&Y1 zHBD=0uvg{R8LO2S^*VFu?F?GbNi;Bt=`I*J34j#xOwb9UTIe7gE)47jK>=iHio4P{F_)06Y(r2`IM( zz!ESL*15X&MIaHRG|dS35_qw2@g~M16#<=uutok2b7cdXy8-3}7MTNpwg5-~BZU^0 zSe=^zAl67BTPDJEQyEX8-(mu24oq?t0L1|ih_x61w{(u37dmK$wW_3rwle@fF(3|5 zehC19cZ-90%>fX2H?(_=Wy=}c&B$qi1ttzDYyFNe24)x2vp}v0nCtv>V=WY#=zwGe zV2Mrsv$}o&91)?&l#H+@vP;JBVJnRQ;`;5>=)C*esj(HqR>1p7l4Ew6JcXoFSNwMA zU(&blw1=$k&Fr%NZfQJ#!oJ*a{uj!EUS}vjG%Px_BD#@Qv7ldcHRX zy@?2IpZs1@qt~9l%Wv#n_W#@aWRuYOFGS;py7qO%!v^#Q3gN2H8|kVq8SxYp{+HHS z*(Kpuq>O%XL{oqdp*De>Azi>k5PwamG-Y6T2M`rg#T^nqaA$Cye_ulufgbn2PzPnwHc_2ED*Ge$304nj6TpN))jLow|VpAvOwB`EhnSNCTu99CXHw~5*r zn7DbEv!Odx5fv3fL-Ei-Kj@raUeTRa=;ALH2;I2F0HFhn(8)*CNa%)c#!(3kE$Aar z*lyXjx1clb!d_mr(6_8Wzke1(Hgq@{LkSeKuw+8Fa7{?bLZKs?(5`3T77M4Ni;uN}@dSLo={x_ySR66ksxR>IJAI1CUv(}@K_ccrl=1dAVa8UpGz+}k*m@bMMo@>oSdmmINL zgs#0~wAcv-Z_Nzd!o~oh3mDj$p(02f^j6pXsu#92nMIT&5cT37n@dy3TADKfr7Zf ziA4`x5=4v8XmSj34A8qMSo**?{@J(z?b0EP0Xjg6GzREiG?JQ@+JJsy9%&{XBOd&c zk&H}UwQ{MNw}3Cz1Mh}DD1r$QIUu`0H*c}(0`bEZ0HMz~VB-fm;-PXTbp9Vb2Ne0B z)iBl#|7_$lzWf><`g0VhPkvxR8B$C@dt85!iC+!hQ1y>62I!Uy!Wd9@>JZe!(4cl9 zIf(d3WjSA9&HpXStxpf5%f~;Rg`h**2*+2bc*goLQne-YItsa>2_2eHca- z9W%ml1A3>1Fot5pF`zyVh2-u-fXk#0;!HqCQ;-RMbuP!y8vebmhAS253tUkGZ}309JceGSRF~$k{H?UM zxsEv$@sr2_rJet<>#e#T)O!S0a0!eu1QC(Y`w__uR(vprd%r5|K>MQzxomf zy2yfA8yeyNopXum1+~J@l)I3M`k3O+ zccEVtqu$zy6hRY0$6&-Zu`lP77CaGorz1BRieBN#4V#YsN*e5#P8)+h%ZV+Fo^T37 zM`Riv@u1lC90cffnp5-f+=y>oN3tJc5zlIYyz!m6a$Jft$z zL69MZXvl!p1yDzqmR`e5eS7;K%m}k9+*Se&ZGM7&eOqc|?EozZUIKArPg5n>dP62+ z_op^JHj?R~-wQx-^Q3a+^Trb$E7V~un+?bw6K#DIHoGu3hiN22pYB*1CaPKzK*R$dX7s@{>U&!llV3JQeK8in_efBLwuK_}_s_@TG5e|XZ1DC4 z^f4(c=3fgS<8r^(NWYS-kYB+dj{*4=%)en+S;BrsGL|E(iEhWv7xRh}H{{M-xvjR@ z2>pa{gctNN)=bn7WsdWPacZG|r5N=?zoDq#H|_+$VE|-;oUIo16UI&eSXu#nG4?Y9 zced?9gD&rtBJ}Sdi^7xq!x*Bl$e6P&Y2~STP`}MAOa^^D{yOSsm_GvajxaC>0JmrZ z46c&GBb{MxHaesLv!)C%v-JS$EqLNZAc;u;w1$DU0BZ>V_F{=sFZ2fegaH9x0qJ6} z&kyu-fZ5LhZ1n)36AZKkz$w5Mc3$X{jN%vup*Ju~h+}X9lvDvqBwztw z1+tk2Kq(j~4uDHQa9GMwzb=fCFH~P21^ou$ex|@~Qh{v1B&N);YPRegnDQdf+d7tT z=n-R1Cjyhpqyro_w}KxP;&J0W;&G!5@whRC zIEL?t#|>-5+1{%Ry@Sj*mfH1UG4O~RL z8Yn;4-6zBd59^!!I&+5ElDT}+kn(`!(j=6F7S@`9}vhe(-Cs z^Y_ml5s?Dsj8wgW_^zlC;;V??2g|U#{{I^emW?;kaxJ|ahaASuZJXRQt{R)6$FzKCukYSjRNkGUt zBbMHk-mgbNM}$yhFEPNvs3*t}f!D)*_Ni_Qkrb1qFcHd`Oq7FeC zTje4R-EhHhnZK4S`UAfxeWQrcfzG5BFaW?jEHP79PDzu1VxV+eK=B5wh_wz0Fv)+A zX11h;dIL}whF-|hR>iT3n=>BY5*L^Zm_&yttl$U$90%kw!-9?iqe z05tj)XWlf8dcEe<1IrQm;E;9Rw-_&s$tREfStXVHV4a@v@)x@(+b7~Djo?=l_AJd^G*L)?E<`kCa^{)q#3?#&!} zqwmg+uSg!fU*hcjEOtqECwIl&Qm5^GXLj}VL-6J~egJv&K8e%z zo-+*lTcQ_sGaZmPVegHe@2!N()?6$bmw%jR|J++*SCY0^zTjwewhUXwvEAn6T-}Cj zRbuBoYHNzWhy}-G`#u}EEL|A6=y**Iw_}hwG^y3Q^6KqUMwQ`=;U~RO;nmW|s7Kv< zxm(VKSS;8_5L(r-NcO}kbu{S7#_pPs8#gR> zD|Y9w-6l=U*{Pk)ogkkuuJN4fvEOhi>)zS7=0`Qp<9f={nw`CU*QlUqJWQzh7WMlK z_m^E7xHqY4w=bQ_>Z^0$is!TASfbWQGN{@g{ow*Pi>BIvOx6tIxF^-h2d54(`t@E_ z;r2U}&(h-Kp+1-4ne=M@dHUmgK7*>d_cN{ZXU`2>k~WAT*5h%S&RP8yC>$O*`7uzo zN|XJA<-qQ}5th#=L-%eRnm6BL=*-$ewWj!4MCFXJ`61P)v4uTZiUWMlcOS7WWej^_ z)3L|&>$SiuAJk?Zd>F+~lPTV(-`36(csbB*)X0k^ChJ`|g)?pouZ1eLC&k#^*OB{4 zjw!KIe`qD9Y30km<|#1tG_BrVfsv6XkIsLtKOrp4<;b$ve)rjfx7hgNdYf8kD*Crc zjO=|vFi!H&Cn?l|@5B6wmdUT=w66`rh({y+DtZFB`#&&~W?CHWGSQgVwa!c>67GB` zp>><-h`OkL$g_A3L(v28hGp#zMaxHw-}p+=KsB6=`SCb+u8Qk@7Ly#N<7dc zHns7*K=#4Kr9DO}qj&KI{L1#}rhV6YwaWP3Otytf{FyP~JYCZs^Qr}7{50cL4d;?` zY@@6y*5;AV?zvoX{1U=uUT@X*DpoAdHoFFwB>y-^TJ2Id=?%drc?GVsY}M~NKafA- z9o)|Iuwk0y(!6NDS?&>TR#)MtnoQpNsUA^OsTC@od3bgjZmf5||%2@m%#0 z-IC4i`0JcEl#C8OIhm!=i*v5iWM5Nqbr4fy{Zu~JmofFX)7kjxGLNVo4sR4LZWmEl z<=??}Y0))iSDrH26^=v9W(3(93uh}Dyk%Px3#(3EyBchhCT-7Pg5LiwTG6l zR62QAk0fjQHJ8+&oO(5`H(xbgf7iMyWF7Wo+xb4>cZN4+iS)Ep-L&TmzL!?4d~y~& zd4x2L$%^R3Lqfr>Q>Qe($(ZeJeOdmBzEioEFpxMaS3Z<`mge#J&Pj@nsWyI>)uOtG z2j6A0n1x?!&&}HGJb!$jsny_@@pxyywZ;B)Wy76Ba_KwE-(0<6H060*h_wVifxN-? z!1C0le_zBpe$UCMdZ#XbA&+rix`NQ#uk%~n4^Ko@CRYvzO}?DAy6IXO8%&cT;C|hB z_~?BNhu4y?5JYsXYfyy~t>Oi5hph0g2Nj&xhr1IpeP!a`gItr19(mHng{*W4ldCBnQ{m(cl7WkfbhqM`Lxhiv=*Jvu3NQgWv z-B;G)FG9ad{LXp2PY)Lb`VSwj*Hd;FYjQmuYn7#ZVkBJsF7E#aAwb^0b=z0Ml~lk; z*ew{uxH?yg7)oYwPHnSyPix}nh=7zUfk#0+brMo)SEy-sn@luMMV-z^)7oADAdTH5 z66G0>##GTPmmisPof|O~NS7B2J`4%AXZb;tR>?f!?vV!#wh?Q+^F9Sq0pO zdu7Ca7Va{*-}<{cyf)mxZ4tPq(8R3Y!L@IX$F0FlXe6kHR+*VQAm;aTP0-{C%dk{) z8IwxkL005^lnb8{gS}uPxHg9Q5T1Guc;hZM8&0b;SxmvI1%ySh*c|6W1*N8p!iq+) zTtrb(Fasr$DmB{|ENCwJ<#Y-% zsI77E$-A@DPPP-!N|oc;ore?B(G*2$7YN?)0) zJ>&J*_QmLcnp~H9;>cF?-6s`Y*|~qKgCfOlt14(#*yVp5hh#SfH)8ibU2h~B+LSJC zfRd2LGk`YtYYyN*!haO?D}VqVg28jsz5y^*Qhds& zuSo+1c?`2zJLW9x41HnV^=sDe8?5suijwUdtOd4*u8A+L#IH^|f;H2i=A`Ra z3pf(g>UBDGhjZ|u%Q0sj;o+F^{7cRMWo9Jdx6z7zw!K#hvDIMp>j=opyKpdt%~kKE z{jJ!2M`~~ys8wuUQ@~y0Nb%NZPqV7OTz+h>&WvQ*49X~; zZ$?rM@jF(`h)^iUmK~IS!no40K$C3h{EEj+PhGB=f!eaDLV;`0JFvDuD$6G3S4#P)Oatz zoTbgKyl3TP{$nK#cLL1YXV~P7c-@QWZedmzyPO_9FlS&xGgbIe%z(msdqp3u!%e?g zrcZb8dL6u6dVx&JlHu?j@7LKtzc0L`fZPX-0Nj@KG0LCZ)e)BeA{rVLu+4Vp1b#pQZF(r23uD3!(H`838dn{K@Z@xMjHlw{IX&DpfwLrPiJ&<|!XjXeLQ*Navy}ab zLGF!R>mHoKQNzKw^8rdd=wowO0i1atIadIgJBaav0(9mGyed1LzT>$-GR}yYE;!f4x%j{(H7$&zHc} z|DgrHY=NWqE&MAEX9Mhd_;)$$=U@fCH%~9GvU6Mflo#`HPIv(y=o7g;IX?bnW9#if z5`>fE>2LST>Gp;AMs6S9yuGn4K9}3S9NV^AgJjQh>EkKNKSp_w#KYwz+WcsGeExO_ z;0yBbzJPcqUrZMCct(#~dZhH2(c_37U(;ic9xv(f6+N!#aZZnGdR)-sjvlA`Zmw?W&{<# z%1>b*T`ukU2>Q%w*AIhG9NNAM-f;moTx^jW^9ZH*7T?K3$Cwnas!&z2s!F_)-+@Cr z7patoLa9|ZzbKTnSTSg&nh7viuH>&1u&1-K$~IrrC-w8R(tK$uY9%debCDF=lV7%` zgN<#YrscpdS6eT$yV|{MJ=s6`=J4R?V7ct~y>6WJ%}EXF>MT5owh+q^B zJahuWYo*B4d2myJRa|A2x)UjYtjeE;qncb7qICYz%<0c=x;=*(MLqbMn4pDC0`}KZW%`6<$ZAm zI&PUMis$t1PqDaC^5?)%o@_|pSmGbdgn@?Q+%3&nm4RoAYdzzu2HPj~KJHAgbHHoeWl-?;cZvH-Qw*) zza8Q2sgh?Z;TxGv>qNVFg}*DFg8|EXm}^yeh36C2k~;MmyAiFfdxC^S`I&Zl`N7MWHsCetjT#TNMzN`O@?;q214S!X;3JOx+ltTKDc#ogT=_wg z+ki~zr{r+A3S?Yyi%V?Y4+==ac;zWt z2^doYPn%(U5SRsOnHMX7F-2ilnmmcjkox)>`fZmY{dG%^K58k1N1g@j;WfGFR*)B3 zPfeLY^UvzXIWu+s6YBBHKcO9e)qyOx7@;pv#!X$ynQy!6!(Z6~43i9-A(KxVw;I8! z<&u6jD`zS~;KXJWM~;qf*Y~WCjQU{aR!^1Ph7G?Nu_YkqK%zE_Sn*a*4SF3%&7n*9 z5d|!uBmk|!>LOUNgHt?l&;VWm%y^H?&MZa%dQ_n3g zaBc>8Of4+A4y-Hd9Z(~AC;l*u&s=GVjvGrwv<*wex-FuX(H3$#kwzRLB?KAYNXyFT z-;R`Wh!%@ZGeY{f8DZ9;zt2hStOrZ{Z9wWi!{=mkFdg1bhMOOyo3kmvxp)rn@N_ba z%;yz-mZpiYdC2VU)Wyieo!nIE6>J|eV;)L&!O`iy zF7xv@hHe1shbWqh>o;^)>=sIF*G~%Uq+H!`U+K!2 z*IT)w!=BN#dYbr8-Cb-^WG0+K8Ch{(EkeFOX-?TatLLs&Z=Q-N$90s=Q4`A3VnaWsjKRJpJU3g;v012hf>4EoXGn&OK|C*~t6r&+SmW zg2_wimYdw7`SrD{YYu6wD1NskLkYDmcBMWBi_1;i>E0~93k|72vI^^64F-n$m~rhq z&G2-cP83A*sdGo;nl)ui=JDdhOLoIr{>)`H1vLQAvD{-~k3AqtUTA(|#BPy0X@YPD zzFZf9&Y)4p1r7AT7%;92qpGD24;}e-byvHZCMM{K)=pevVvTmef9u-?VijB6@PFVujkWYRYJf9l!!s!ZgLz-u{Y@NWu*)lGC-O1aVWp49B4wzomO zLs6`itW7-UBl{adRw-5UN?4aW;1H#hem>au{4=a%hUu2~T`5UFw&}yj^M9hw_^(rE z+)$@YoY$hw_dF6c$hsuO4NE>wpu#eZ#Fj8CQoo`yam$E^%`OL>XV zyySF^)Qp-?=;puIJQYrOX` zIOyQMjSQyk0&ym^2{Xq1EzT+uoAWfb{P`aC*BW{sQyh7Wo2^f|f$oFW6r4ta717&H z1#++HN0G_IL0Pq0wi($;H=$*l%KYMn=xdz&JZGajk*#%As$?=jj_z~{`>xwWAQ4p& zyQs?~fZQ=*`XFAO1vQ9V(gjtorNcQVqfu!}XMNk(-^lXT(LFzhvED(n8lM(s54CNC zs@0vdHc~5ZzSK8K^WmFTs#^hDE^Whcl(Z#a3?2K!kPuUdbLz%zeZI}|)dB1@#Zb8I zKlE(_)^!xCkaPR`A3)ZhPY8SHuM-KyM=c+mK^s-pWPv8Fo2`j*VO3J)Z{3Q_hZDmt zAW3!H@}e|?d_6AxWxvp&_eLgPP~a8z(E=Rllzu{;uWLodp_s`SzhA!oJ;TdBpwb(P0MN$N*7JuS&q$qwN34&g!^KIk|6l=1DQk+hF z$3^l4=XFLn)uv8WCSmi5w<%!iXw+n8)74nGG=e(pND{tQt@uWgs9st= zv0M&auC5AKG*zWhE`X~fVXx{+Qo3m68iIp9GI@mnXPP;*FFa%OF&W}pzeLlH{_j+$ z?r!#%-9MUcG#DiXHmaAsSx2>2v5XKcGa@G1PioMRB{tPQv58rMXm0JHL}UjmXfSqg z&6&gTwMSR8o!Ptu4naLA!|iv%QK7ZYaGWQ#TnwVPl#34S^I0?Q`n($}ofo|zW^ft4 zW)1=(!$Q*RlRCCM5SXNtV3nEzE0q8oVdKXr9Ylr|5S?_wed=f=3v(%w{y{0q=yx-+ z>R|4xslYH$)Lx)h@d;!NgU4VIH_Kv{X%VORwkwpn6|y5dx;$SiuUT1+f*np@3UYL7+CXa2rUXQSQc$QKFNkY6(+X$U)uT3KEL6Pq`Uk*UI3<7zY; z`H=CFye`g#Wh;@K$Lu1l)9$yW&*3~na({+%(eDoel_+NTW9H%5vyvm7Y=)IGMD4C0 z3MzHdSu+Z_jVO3JKbLp)Nufj!EM7a6B;{^{h0fP9^qm%u}s`0cgRx-NLtE$uT6lJ0{xY-wQ68lAQEu-Tu2rNa_x?Z zwq@98o|Qb&wL}B>t&%b3JMak5sOuMxNXu%68J`h&%!%szE4IcyZEK z$!S?)AP`fOV9JyfO%f~4UyYxxmdv7~x_lxNEiXD>!TjOe(<~(Xim)TM^g9Ld&nCh% zJIMnhJ~+VZcD%tPPh;owUJ>REbKR3qi95t-*Wzc|VcYpab(>Z7I9#z2H8}sHegU$q zz~25xK7lX)?qu{_gqc$3oW5lv(A{Q+S&^uVHMa`HXp+$(M&qX|t@1P5Z|7p(m_+}s z{i2L{hyN3b2adjF_v^}#(#N*RRxOOhxf;I%mAdWyDj4A+5UwJ^t+_LZf~ACoFq2{k=U&f7N(6-!|tNs(5^VwRLy5+r0jc9oXpZDscan z%1$72Acf0d7A0 zPp-gV*E5^2mU1nVP4kYj6@=Gg@r&y#-Hv2US451NRQ%iii<22dg5Y=NuD(5P8is$B zHM}gLUe|7Hj2z*fZ44L;1}o#O9dNx%+iX{-B)-0^EuWpAWIK_QTwCBD9$3$I{36S? zEK9NsLOcN#p2%UIz~ofNB+1&9$&?WABt*&kNv2&mI@2V9R8kT-&vbYIomM;pyLGY<;s#9kqpb%xo&^ zXX@kPXlg#x#u+)#oLk!e0|@v&4w<&meQI>S(`dU1ShrrPa=((+9EK!vYNOI&$AFlA zh2`{CddvExC-!HDep>N8Eek2a=L8|d>)sd5{q-weN74bu<;E@zJ&=V4udd^P+=|K|9k?&q!z&g<4a3vAXJ3hOO~M%S?da=Q!owqS2sX{?J1LAUda zttjj2dZKWj;#Te zb)>oEHaM`LE%%}Zs+nsBNuK@!FD#x>mr5ZprOpmYZFKqfyyf3bTnuX9L!uDKBCQ}Y zUlp=o4ptLAE8)=k0}?&LqE4zT#ljotA7e)8EP^?4v})$1>sbWT?RlSozm4kDWw z`ml;%yWKlqORV~VilUS@c~v#W*sXbY!Gj}^`%8md9zXW`0tl0i>qMr)m0usn)+9oUDiJjwSE3XST_rj-BhuG5-?3C_&OQaP2Kf?ky&1~C|+ItRm0r9y$_nNn$!s0 zVC6eVcV09PD-dh4k|&{2M?lj7uw(Mg+!(M*wd=e`{ZdgjV|z;5K?Fy(27E3 z+0C2ydELE{%qUfdU~vO$a&8^jyROi0-b_XpBiD>WCGt{=)7_E(j*=}?o9ovSX4)n( zaO7UWd;P$mSO@b9H_lnD78jwUS~~v};<;QMu^777f}hS4S7p0hV;FW^xd`) z3*$(fGjYtA?oSGhZB~kRCRJz}>vD~ch&$t8oXEAbTZw)=j3JhgG`u-m9)W;ZXNO1a zKq1<{^}Q9?-?vuBPDYpu0U?4GXWD%{V&{99Tt|#+bJ=zKHJg~VSMSfy2k-K)*_(#M zJR^3=6?~enO84%^R|6N}Jz#vY>0E5IX>IP5CF^x&8Fht;=soLaReMc+f=K5g`)=pH zL5E>`|-((&8N@drD9`kV}0#TG-_?{ zvmIVCkF7@Tusn|MsC#!4+<$zNoy6W-W}<$_HLMLN5%F^izkf;%L8xi)1x)*4p7y9^Vmc+D z9;%9R&X(3@GGsL_t0Lo^euXT6&+QN#P)$cBA-@BshUVHa1$efdm~0bC_@wCe{|_9+ z6g@`dnS?-IXytn?;?)p3q`8+v9u<0a<6r?FR6F?%cAYf4L6o#%$s)%+$f~_jo>Tc& zUVX)nU|&2cAh0m z&FK#&__!gqY(SJ!x;u{-pLE5-NonUsSSA?-{p4PHP2Gj)-ze-xcEmV)-tV-Z3LE&p zcOYXM!;SvyE;|^bhx2(eOox-Y#xOP87`@a|M?%-*2#|f+ASZK~XYP(f&O6NS0sxT_ zkrRl4H7RQ02Ly4S6TzXXkQ{C$T;y4axt+U$uhg$5gW}*v@&~Lb^fN-0UNS|oa}X-m z#fexb39z;*x_#~MHCT1_UR>F?F^IIYIx9($thEYefXZ8Gw4KrYIgj&4&F7EMtz^#j zxAB6F&CsSsT-eBI;!>CO$nf>6QE>W+HT-iRpgKL_Uht*z=dpy`;*xYuq6Hn0GtIXo z+*J??m)fG8>ENEuz_ma+6!DUdK<;$LQNIL{bZnD6+k%uQHl>*@n>KF6y@;RKILT`f z`@zQe}#K{hgCLA5r8F8@azeiZ0YwI)jGtT@9v1XJ2a$eZirx5c*YP8JQ~U zpNF$Ef0|8ifAU_uwOwy-zFHk8?|lmXL7ai4F4-tbf9M>(XN2;rvouA$$u;ve>tgup`EFRxVJZ;M8y z@)U$<);I5vhoDi%@wnV&2d!_xLmhNU^nd{nwOK{ZK!rgC7yTk|gCNsP`PC*)DZOk#LBA6YG-p4AU?&$= z$wHG82e!##Zld%^xf4-(p!`87-BDFun}!ajPgD;3w)CN*$8tEtPhUJ&(-OpMY7naO z*g)6=+MCW7vs?r@bX2~{(?8YWd@+5KzEH>e zd6lOxx%rI!%98^*-Do&GYm}Rf9qy@UEie@#r-DO6^tU;t-+l?G+S+ zz5oCVO<#Xeret!P=0?#AL#Z(e>I75JxTM;k#i}-G1-%c<@aWe}02zJ@jXZD$R2Vg% zAWLl+`)Ns8iaGtxz{=nktsNXrfRhEP1A#KRPIrwWkrUXpbZ*o_7k{Qx`@6_p2<`71 zOV?^(l;Ve|vmn1uxyGQ)DBIiOFg-Ggeh!SXTSmHP7*p&>Jl(O8X8_VB92-VX?!G@U z7BO%nc4GVT)J1l=- zm=x$Gm3v_n$rPaKq8auz1;L^4YO8Vcg=YG5i;b@cSPWzOHT4v;(xl(Fm+tHI3j!Ns zG2>uRv0Il5etkY5}E8<8OTJhs; zDZRXaZtiMT)R0tQHO?vcfvF=YOY#hE5*XebWwo}oglDVU0~cZ$S3Em#pASsFOezo;=uVo zaWqy}Qx^=~xr7R?(5njiW1k_UbonfylQa~Ro*%gbKuxi=+xSqU2_%#@!97Rn5*Idc zo}X}h?OA>Tq)%*WmG9YHyEa}MAl>HUpql&i)45GoQ=3vAQfFKn`!3fMbLQ5;M5Fb} zemS&XFq>w#K+PrxuEdPe`>)gD%aPo&qXq1M$(s>)^pWt~AaGcyy5Xb7agjw45Hlr~ zpqPD2r~f2HDsgUx&cHY9XCJjW6dCWJ6=?YsTn4S)diB%x?CkCZoCtZv8kq*vYmSIp zeKon&(rcI@?AiP^_$tjhbr#sh)3pk8`Uor$3df)0V70!!5h=~KWpqqTrM1Fiak#Jq zXn>g!y7HdMkGN_O3i`(|SGEg(x5!~n;Ot=indRc_9?htocxD0UGR^_w# zLFY_%iaghITsdyCaxtE#J_DzKx^g5=sQ(7YA$(4bCk2mQoWFm#HmOhbG^oHjY?38T zi+nz7N^mS0i|WGxei)8Q>r!_6EZ+JJ^y7nM`vRvHDKQ9SRpH6Ak`DM?n)JI@LGznP zR~_8C&=bTa>A&x2WukWe9aF>3);x!SYNGkf}4>X_neu4%5_y95DsLeCFkSad}l( zG*O*J0hBgf!0Qqa{J_gwuQHoAQuh;40rnrbBU@ar2A8>01&$fheUB85h>w4Q(J=la zM`YvJoJ;?aBNBuA`F#Gm24wu*#}ma-w&#*i&=Q>ax;P>}9`1wDDi7ReAC(zAsYio0 zlS~pBsab#|U{JD2k#hz%VeTvAi2PW-_8sT2_~iCt--wSdZKvJ4FD>FCBD<_aTV`}N zsXPv4lF0aaQXgOyyG%YRGk~qEPThAG3npx7KqWkuo4CkwTvl)L%4Kjd`MLI!je_FC z>7wu-5DeM`2kSp^L>k9+pTH5;N02t7bGLW-$17t#*jQgD)~~dW$=9HT7~XmcKJSc_ z9clE{=9h&wR*b8tXlg4WM!LcgIj@kg3y<5%F^VZ{3vR&HpjeIGy8&ihYmC=g1g`!# zg+3XxEQNMH)oLe&Gb3;RfTLGkLP-_VBY?vdETnTG+d(F$d%A?=;~Dj8#QTjqm$mm< zMn|rDS%rpJ3*b}Ku%Q)qG1!$JIn>H~xN4&2YD$gX{>`&^p2Ooktbq=A^{`BVYt}$PriGfpR!hy>IpA6Xjq$@|RfcoY>54?};Hq65lM{S$ThNDhBW0j_7G|4r z3{~j|oX7Ue&TU2APxVEUM_5{hGa#H0!tioQBcETZkw2aG$XbZ$$=r3_4u?;~h~$tr zU?K51rpAtn^)D~DLGXg~WI(*V4Sw*>_O`Z<2W)H7g7o}3xicX+pV=up^EWYe>xAAM z8&b@>GY)Fvi&m_&WAe;4!eF!N8??F?d;2gtA}{2y_@&ezY$A9rH*qgyNzWaiOwng4 z<&%0I#FWpf^sKN0hz--Js#~N*@mGbM*BJ=7`H}6$1jMgPd#1WWjFyM1T%-959qW2x zs~e-<(wUP$Gbfl@(g~KziOx3>OVXOsDxu@UqsI}Q==wi%P7 zQ8_}R++xYPUCrslFpMU5>iYMc-(BPCwxXC9Y!cxT>1_7IwHvcOx`pQ;r;|cW2|jB#XvvF#=4zjDaf#OSNCmPxuIGaXt%wb zMwu6lRH7oMZ#;4Al_xAp0C`qttA+GCA$`ZKc&TDc%GjE(vbQV<5>XLIC(pLKG}}}m z<{J}n_Bm49L%U3>fHIHn@rRHy2;#xtSVY4{b_{bneJw%3{0$7X?2P|7a!w81dc^#d zos|XT5@|M^rqQfumUI^|Qm-CNsyBekUB4>a^()SvQqVP+HWm9qvR>=y>8xhfZcPy_ucPD?)QQF{n-6(tP9u=%D3pO zYT`{hpwkisch)yhzYpGTgCDiQ2W{}Vtb@Y zAU3yedsY6*VSB79x9+?G=`m6G`kA67zfpe(W?B1w`i-}=WsW0M2`M2o513Hv*Z#5artV|gJ<@Lbm8 z*J|oERtJEgoOR_;gE?uf5>RIYJ_N{?@D6#(*EW zx6RRgU769W1Ym#>Mt81hd0Hi6l0-xAqyHq0?84@ARwB&oD=M)W>)`l1W?W%*E5irl z#7@>b>!eG`IZ3(0u(qcuD12JAOx)@|63i&wXg}ysZfjz#Oj|l><&KB22nvthDu{(0 zu`bL;$ytz!;bS8nl594kqdJFvd;A3;LG?U{GN(i}^=9asmjHMUG0X$i?eqlvA zsI_|YFrOCS#a@J8x^Ob{HvsHPI4_v!Tu6tw@^H##AjEH1WDsNBNbd5lRJb4>sBEMQ z+0b0KYsc)J&V&QnnT?6^)2|@=KT_@Jve2ad^B+cl!G|wIIE`E`y<40h!PwCGc~@fu z&Dzf4Cz}3_SH9x2U!a70SF9CP5g{+=Pn{7o&L&2cSU1^UO&lXaba2z)c*_Ea&Lr!~ zlq?0h-<@&lCzOMDRB+>*meL$o=Qt1xXR-zzlKUk8TNGpY=VF!4goB`PMei(~!* z@`c6h{M?5~2$$%v6y=V+^ZM|MUd+Zi>!mUBQhQmLo2hEOwfMd4I5cTUGXv(KH))E0S=GjRuPWWGYM%E;8EK>+^`m_E%2D>) znph;xWq|JZU>5XcYrR^h4Bu>2k*RB@{5*L2(~PxJ1Y;hvw(+b4QiFJLSAw(fgSc2ezwJE^QpB} zNR&%uU$CMVey<$dq5OVJi#%`cG@PFcCBA>5Ff7V-Iu4sr=$Kpn=QkddnPqLq?rNZZQB2@M)8G%#rtki?l*~27LEZ|B9bxli z!RX%s-FF7`OUMzz;=)W$$O4&dMH;IHE!?$;T$yHtN3KArQ==;W>-?Z!3^?HYwOuRJ z@VdA!3mI^6(77&~8wnj1Zt4^>JkyPh43*ckS!G7j6cf~AYZX=P%**K;6qQA^bODUU zTEQ!`|DS^KiTI6}=q)x0ia&JmU!x?K(B%@kQU7jzC4pnKY}{)Rqxs57S>c_ic^J zm&qcrOddhv*Ww|;iXKNXp89b&E{j!#_UrRHy!vo7J z0zs+^y?(H7az%}Jx(wj20ER8N!oDp`M;Fa_(Q-b})1{8RMJ1$^5Z8$1n`E#v`#KKx zr0zZ+=a$EIcN-+d#fItU!%D*`;08#o5Kq+bT%_jhpr<^+`0S9?;T$Z`9h(Wt4(a_p zBn}_mX;I#G*M!}byuuZIZQ(Hzo|lAhe!4G>CKc@>iflb$bDYxcU^{8$mHhs4T^G}~ zg;aMT#hK{ZAZqUpL?SM1>J7OlfdO)q(1V?o3ycyeXH!Z-a4NLZ!tLXlz9S$;~kw*nGT5vh>-C4W&&f=2HUOaik**a zOPQlzhC<-8wKr&@C&u&oe#$?0mDsMuN=Ng8p|@2MNNr|o?FV^C-samW_N*XGccoEl z_LDQF`tU;*;5{n#o+7*Q<(wI6wdOB~#6`nprolr2hr!fqjW1jH2=&|ve{3Y~3@iYh z9Nmq26ogNhW!;ZWXyoJo5jJeL0@Jrt5?QTLHi(Ky^H&7lW4!}lxWm_eyG?Zdtdp> zwzavFb2gd1M9{@AoTpKLn2p54=ZLw>1qeOHbtYmgBk`a=2XpsB_ZUAfs{_7j#@0vl zi$;8yorm4M!wvZ8{STX{!xe)5=^qZ7x&7I=&pA1QT14bQ6E=C}K;-KfZNS6T9Lb{> zbmzuH_9C~}eMAD?+dyE`l!sic1FgAUy~(?^&rePReE4M{fkh0^%GiS-@_3HBRQaq) zd-2rP^NN(j&NF1u`1V6kc$w?%*X;R%x%SU;>soL@;EvdzpczRM-Q6nB-!{H8W`?{2 zI!0@Q1fqs4WWvMT3ZnHlU>m%}_TZ#rjuyOzy~`6jqNWV@#0vn{{91y&gA?-cuONYq z@Gj~YZ6^*&G8WQFAoi+r6Yg^45m2^!7PZ2-t;iZ&6hyPvW)5Kw8SF$Ba3GE!v8;iQ z#p$)7mB0$7!hwL?UHFZqDg-$l^g2Ue&GQGwA~_ox3s4G-KhYRJ5Q#NKndUqV{1yrU zgBu~yryL<<2yidXehwANTk`jD;SjuXjT!`!q^L$B#-e1XxOAu(>{HCqUUhT{Wyad` zY0c_7>o2GjfFw!>+!1Xl>W*Z`VDM90Zp^NQ&LLng^u6C>w%K)k%hQq2>*{luWJ+5T z-NGCfb$;nFO0uV-U)u9j)sk0U05$cx=`5o>#O-we(n>QZ9_vf6D_<8DJbU-#dI_g~ zt;3}Nh2sH=`h5AZkq%{+Ny9w%08;#ub7s(yEDuYPeWz&YSIO9j3ohd#jqUpV@Jb1& zDw4DapUbiEPIX7M6RoYSMdF@~x6B9M|?S3~-&5r`rH5HA*ssfZ;`%?+1h)s=n( z`&w8X*7YOWDji&n?r>HD_LoHM4Aik+yGvCFJHD9m$@nRoKs@NIFjfO}k{a9Tq_xDD z)L<~s0vZx1u1%dE6w~wb*T5ze82_kpHnjs_7vqvFZGi( znJj2K8DMH^;s}s!DepO%;U4}@K99YU^30lC2k6B9-J#TTDuaEaGmToM+*!jdJ?PR7 z*U}&j=?+99@QymY>!QBC6`xrg4}gaCi)l1^*7#YozK2u^#0~Q03+)i+2iVg?-eGBj zC3TII8VX|xNhy#`SXW4m0~U^DpPE2e8z&7_+2ffZ4TTcg~%gj|s zmyF-z&YOge#)s3v$Z~_ThwV4fzM)K8$mZ@5LQp(ysa>b?=EV6&bSM zdDFgV6g2Fh?*Su4R=&4yomtY490%wycY*Ar}p{U8d* zJLE+;{bONV#-^f@@qK3c_nPSGv;#HC_ULvKJn$a?qtnhfQNEcVGY2`fM=+0O$Wde0 zXNKf6GNlLWp=N7Gd{OV4$;r2!&)?-$<1KZmkKC+F#DmQ;S~ebyKW1h2Be?i z+*z4#iP^>}qDo2QF3OB41;(Md`S6%r>Z~?z>8QP1-TqqMfau`W@Fyb-&qbuBi4q0m zAhEIh#JK5A>Yq6>3T$Qc9NndaZ!eoznD}x_Vu$0BZCwK+g~f{grUb>nV&XGLmjP2z zvm}UL1TS)fb^!3zNU9^=2e0nZihJGr$R9LEVr#Hekj%_5wvAf==o$ky=BV9~Icwx) zKH!><{?#Oj`zdh+sx6wGNn`I=b=FDoEISoiIv#!>@qHk~&riKjYvcZPTVWKR z4)Zw0E*OU)>mfGW2+bFJrzfJI{Y9_JY>PLtS6Ctak6Y`&G5v+qZ#ti_aF@9s*r-r4 z+VAowjMWbxL|j<8O!U{3FAs6J;OY(6CFqLu(gdq6P-x=3I{3|>dpzcZbzWbiA;-xJtW}VAdx#Rc(tT4 z+*35hPPMOv4yZ1O*7}XDl&If>7QRV2w$$WfwrBtWs_Pqkci!aH4eKN=YFbG}HB!+C z=tV7VcHFq4vZQ%UEU*I`MX5gzsG8@myoDkmPs?#!Wv^KnztH@~c1>r`5_cGQ^&w%A zBtRMTEbq7TYdnCzbTXWp@%CQ=3}30#@mOCh7~KHIttiDQTgOJi(Y?*&0B4R+dW1>N z`fvy=TokxxLe?#^w^cR-QyOEms%wvvAD*g<%%B$+7tEz43a*m1T{VxX_#@o;2Kl&j zhY_A_gtD-b?pBsBK410&E6^pxEhA`gsmwej+9p8sG(+&eZ>LFI3COtQq z$asy8m|yH-lN8nR{MNMy8Ac`>+dAtDN;cP|hsTU?duLiL& z#>7l5UFpggu7kJa(GkvG4XV zzP6yHz9=Q1{q9`6S?_pV6BasSotZSICFoR5q@$(Ija^>d))jFwb z+I+W+FRy<8we<-|TVZ;c^o=Eg0|TonRzwaLmTmS+hwb}{Sd`X%V8GuQ*@yxe=;sd8 zO~Q<*&#(gvKB+rH!hR0AL21XUfHalZd;AcGPkZB>{!F2i+t1h<(V17O!^~POK)|{$ z&ho7D@@l6`fQk1V3ilIr#x{lNhO+J`(k=H520TtSNY(`9Xs73%dui{T zP8lXv8FEYr#|;HLYJ7&wh9Ob}5o)z=@HU2ORjBog_)J{Ta7HPY%^W|kB~C<>E5gIz zGM3P{^*41_!r!)S#lMQJb(=WDwv@A_%;?u;?ba>bm1LKrc8X0qTxH4?DJPk%efItF z2ObH6proY9j;*mk+;{*U9vC+9q#*D}lus}9=K!BG*e;eYm(>~fU`rd;h;feAyfp~5;)@UAhH%4I z{jMre!Wyq5Dw0m3gm>pe5KG8s<6M#`s(+^Ebp(aJ>rdWx>raA9IZGuoGh9Ebmx^{A<5>;)Y>!o* z)_g0+@|Ayb%*FVqyR5~2wEuRht;YLtrl&MsR4X|JUb_5BC7zXfaZaVRyfDQ^6lBD^ zBp%kaj|iziEzD;=f2yq~smy%R-jOO?c`#v*k!Mj_^?!>?0i$R?JQ%+>toczkHm|}l zdTje|?3qcisK>jI7c;$#3uhxgcj+mY`(~c0D$cCBsjUL4t0Z+e2cwcot0iySdcgH# zh??VzH)+V~E`Dxg9l=to1niw#nwmP%qHBRDxwnBxC~Xg(0HNr|tw>S7n%dts2=zW( zy+N6(t1%@hxMO1`ny^}$1a9?Mt5q`5e4|F6)yMJs%u0!lR0S13hs0NuZ~~+WL6ZPi z!aK-TO>9;)P?@dFK}}OtQ_8W6q^{PQ;FAKrB-^<;;%)MV2f&KUK+8kc%=u-a4+TA* zc{IAj*4iNI(Z5vlvEici;;J_9AHol;ZaK$)m`UTNM$nFCD$)k-ktGDVU)ZgqcFL$9dDx zje~|=IE_%Xs3s}vp5o$C4ILwyZddoILb%ubm%S2Ny`J+<$ z0{lWhvaYlH5;ceLgtTdEI{GAe_j;8@!X&oc*Dg%Jw7(QLp1F8rxC08JIcJO2&8fE_sd3(ZJp|J85U0OMWT@5UzD}9%#k=^v7C+2o!ZmP zq3SR=6WQ3jkUaFB&^28g#XJPuS{#V|+9jjO$g&zGdhbgY9AeeyW(?YLZ{yy%tI)Dn z*Vl`^B&$SZkKf<0FRu9$pT;K_&h&C_*jm3Qk4w${t}8H^#;f`}p0CZ_cbXLAMu+3( zEX{nsdc5ug7)F|9w9*WtRi3b;OT*+^B;f3xG3D#SUL@a`8@HBylAx2s?+RMhv_(4 zjQcwXC0Oq{y3C$fs4;>G0hx|Am)?Ri26J4-ENUgSUWDe%+l*=-v(g3~Ml$Z#BSLm9 z(P4~P_~hvJX`>ilaAgWJ(N}uWGyO_k+j*Uuxm*Et+xcu)HmNIn=u^yA#B_fsVw!>C zf?jXjDbtJn2FU!pv-|yy{wp*$0CaCcB@>pEc)_<;hiGipXl!}3uaah_>uO%XqP%Ww zu4{Q1bG?BHIXdV8ps!^9!vG|BF|0MaAV@`~U{z1SDmVq}4O1YH50=7#ua{yMpgt-j zu*5ohMQAWbI0HGpA_gJCYnfv}t9d>ei&bo}B8(PCaNdYq)U(C`&0p=>IgcTS9c{9E zt_A*b{0t|g=*G7GB#-fFKBz?GjN8V_uh{K!Eq8e=?%bLgR0V^^Ry%SQu&*aEjI_uCe4~xBw1YHNGk8hz)vTYvKlwMj@bI#BtXzMTYpVK zmYJ?J#^FLcxX<1*H1hgW0O*f`qCU4M1%8Fl-p{*hR^i*dy8UjMAe&*H0zi2%C_-IM7zRqL~ z$A~|P8zE7I^=2cY?kAyyP98AyuZ%ue_D^FehzGmWwvb)Rj)GVo&~!XdNUTOb2)b3yiWODoZ^XGa=DE_fZ;Wod*=Zd9P; zB=L2y2rw{tI}y(eGFRfpSY~b{J5KNjJvn21omvyBX9a*cuaEU39cNTt3@hyU3Zo!- zN#@l|izNyq$)4g+?o@knoSAM(u1S=pUbdcI`g=!iG%9T7i8iLgG$GQM z?nrNFldE1~m%%-0$C!Ruma#6*_Q>x>b?jG@Th%nqy3CvUH@Q!F=k7wsrDufbjFP${ z{?|J&Vu^-C;j6~7nXrJ5{l$P0$02q&XuvOMiW76WMYpr7$~ zq70h3?{CbdDlOfi`w$YA9w7l(4CCW4-xouvgFCqJVFww7@ZV`{XZly42poWLw0ufR(^L#D5{w>pfjYnSOwFq@uE z;VyIp0Z(1!^q{UYQus<6QnXq$mDAA$(<#|I1S(n$1J!mXStztUdp{0I@`P z6GCFF(2Ir@!~}8Mr8+g=Y6+xM-Fo&kh^;UKmn@~Nej?0-VQp4{wnRC0 zsDsiqFjZG{wo^r}Q7ESuuN-oX3TY*}UjDk6=i~l<1rl0LDqzRM+IYbU5~i5CStEv& zqE;3t7vJEkMVtRXyI;eCmHs+MZ=7kxr}J=~RtlBcq@Sm)N9uo*cASu48!d!KMzXmj zUrAvBQT_?nKqUpP^v`?u-TyT1zwu})6|(WI;fDh67E>XFnOX2CxmNkD?LzOIM=StfG(Y0 zVxG=gC-1iU9{OWVcUXOs_gj5{dB^fwzZ;x*F%MbLtr_Pl$RqWAHH5N`3Hu9TSRV#9 zDBLailnoJkY8Zz)27fv4RiUuQmb?($hlqy_3ZJCh{wR{VHI8AK4%Kd0>7H&Ck!w&$0RWvHn@BTtVzaU8=Y0rFyNt zP*2qx&BcC}K;?fgJNiO9T>s)K)0B%kqj>yTiSb-c&)$MWdvi7GsY=>xqKutKB-FPR zRjIovk<(G)zFE~m3&NJHD=|Mp_*bn)CjEhz-Yec-y`0Zn1CLqhtQI9LZKl|dDyiN3 zJ;(mhnzhLa4c2C|bsDox%$>CvO9RdWRY&QWfz{i%&5J?xqH>idp`Jq=z%`e|zK`vl zUFRE>Dr>@m3b-FEH)9&tcq^(JN{SK?kg~U*acon6H z9l%Pw25Tk8x6-g2-oM|L%_2nqSfYpgvEpQ!22;N)BNeE4?_*f&+3&-V(Qw)cTxGLS~ul3Db|_w=Sk|F^ztWl6cK*SZo&X{I0(dK<(4cu7|PN#uCV`e^V9YQ=c>*Kcn_jteaYy*CgH>h!f(;^GzRYyky(K(8sw+AM#C@|s>Tx00TTIH+U5CA5); zbtHC&jr>_1dBxdd>~S4?p562!+CBI2*zg`GB4+=wQ_1{XYDU%FhW}_$rEx9IRZsK3 za*gZAV|MMwX%jzUiE*P%z(~Owp%zOpfm;cDBY~3>2|apLhZtNUs5<-XNRUz3-Ch@I z_{`}Xcxq#>Td{oWWs5$lA(?AzZ`{!yg+ZKZr3&vRE;N4)0Cm?Iu=u)6?hQt00}Jxq z8&O}Ex;Flx4iEr(igQpd_jS)XzaMsbjqZz<;h1S*^h(8=MbTJCKj}1yU4_9%_Y^>p ziB3y~_h1r2gMnla8+bdZXh$wQ)Z&aUAPsx<~Mq1X=(qX&4KA|0QBSjuCV8w z5r4JetPecw{}_Nzdi=$8$$lpip#zu1ofss2*XfPeQ+VJ(0uiVraAUeDUeYqxr$l$`aa})zr(9)8n;I8FzlA0iL=>zYvLOA1FGd3W=$7D#s7yPnXAypO+Ry0b z+lh;i*Yhmkw6Su+r@H*YbhC~X+Op2*5~(Z!#fnJO%my@n=h^QRfdDPPlH&wg*U&u( z1GQxyvJ;+Jt)g7=C8H&`gV?sxsas6?TNRi?c;`jZR=sPmlgFy_uSb z=YMq#;m4WPBvxc0yk*3TEf?B?J`^-HHK zWvDA|IoXn&s>7Y8s%xU^X(BYloqiQQth?~Qg@yx+!;b|F_M{B;q!Sq0>;!34g%jOG z9U}?^Y8?Xx4juQ}7}$g+q}74}q~UQngY_GiP(b`dj2o~7x`Pr7m=fn{qXgpX63mD< zm{j{c*zEpD9#eed)MEl=-!fVlCT@^bJ+zKYx$1w~$BfeGM zZ}OaZar#=ScHi7d>zpO&6Znjwokv;aUJ1RVv~1iL!>Tl%m>ViRlCss~UaBgM4Do!a zoe%CeZm*P`a$m(osvv1TjIUGM`rQYcT94M|fi@B#vM0F(?tOp&$t2cVme+K=14!{{ zm%H|h#MuWK=;EP+AL72metkVH#cAKKpZ@N*z1ZxxyMEt&TA9@v&T8yDC+=Rlc5V{a zBwGtkpUa~iqnRE7N%MP0=CCE@7Rjm- z7-OqUm8PCHN;!U8vPp%}`zPhbx&1$w&i9^&ZgBZi^g~w6pk6U*%PUJB1ty9UbTiM+ zd-a@=;OHWsHBdAQu4&B&35k7#13*5fbW!^PxMbfGM0*MYu zDXzh_4G+H`Y>tkB*cw+FCNqk(0+T4Y8eUmvN-2p_si-d zeA9)s71ZrISpXl=7xae+12*4;-1z-pZ}fjCMB`RJD&n|hpcS1c5x&izACv_($#VS7 z>F0-koAmYH!Qp4$elq#l>GbfQ6a9@}8x@T|IYwuU7q&e^*z6gSX3r8cdzw7hGs0zi zbQZQ}i4$=Q=lXg&q|5ty?T`i<8xY>*!f4S7Ch?w5>=c-YY7r2v$58;JQ~eTUAQ;Piqaaa5$7efuv_Fh8+DC&)sCzi`;xYt zw1Y*1F+|8aU=h@mR-t8*ePTjgQ;e=>P`u^}hzVO8%9Dmdie_9RVu=c?@RcA!X%jIE{V!o{vbtzBY<@%;0i4WNr6&4Zj&g*5 zh=VH)gc=K?77?{324%sUyj3lTSysuYa;7zKTEk~L-qui%=Uju6PNln<0@zUS_?s8! z2cI01Q!Cd;wAUO&)gj-x%Bp^tnPOaj>1QaLVIW0>&uLOV%Cw9#um)`bposm(sF0)3 zPk$%Pz9Sh>wC94Bft{Nd<7r8|A%-3~?R;`jg^-K?4KhP5{I_2cqHTA;fKHoAYaJ&N zvkS%cc_|gR1R&T8;L1B_mJ?m&q?M-Xvb?BlAdZWKPAju0E)uazEB(TNLZq=Oq&qF9 zmNX}pKvhn-*y#5q(?fK>OSmq)h2lz^i(k`1+iW1&W-*mBD}`>l>C>XiqAUf`G^K*! zzCtv)VCq+5MzJZv9ywe|&x0u~I;xecfzO+lqis*ztc!{b-_7pTMr=h?0C^t_cwT6` zWdX1+54>!_vYyrapwFXKAcu>EFWk)l;tsziwkFx4l|cv~`LxMpt9-h#-jR4;SR3K; zfe{f__~{Z~7P_`U9oG;vI(lLgvYR?~ZbzjhW34obLxTQ;-bM!R;zLfT-S;88C)hb2 zH~|yCd7qxf6bX0Cz*sA;pOPPD>tU?fH zA7$U_NigHKOr_Blx%{;(%Vo%>?`V_z(%W0$Em@aX0rJI4QP6edcYC`Op9&x{?5%>i z-0cwUZl=K$@eMVY?PK)_Lc63xu8Z(34#@aGtj4kMz z^ydv{-ZJ~Y)_2mTNM7Zfa~UbYk?4<+1iy!TVR()$JY%}o5Q8DE@|vmPe$QC>fYv3D zp7IFCwil9|S2SlZL>{=TxTgMarL1-<>J|=;)uaO9T=1f;8HLPQNX|T984$a@(r$mK zi^@w+aCXAG{S{dFdr;w{;2`HnRt(6o@S>@)fhJ%7Cr?x*=*vt(hxS~@X&Q&oIo62N z?Qq#zj<5R&Uds^->s-@F`3K9;>Nh}wJs=r;_d%;ginyf11%j?M3bD_dv)WnORVmZlD%0E}Csb+3L#@Q_p31i6VW%pKuE*M>XZ6+X zB^q@X&!{0nNIlzF6;6iKok(Lq!K2A1WAgam7R^O z(C_Jfz*g_=Z6LCG4RR}NybML}WVc04J;w90df{2>zJ*Pp=|wp6_w9D$C($8dG;=E z`~Pa1j;C>S7`JTt-t|N`gpy($94Wbl!LT8K%&GPGPT zKC46}ed=JbWiw#?=S{=?o0fY1gO+-}b*Xb?olCvMfaDz?D>moVkB!B_)vGdhan$T) zvl`04wa{_a(d16k?s(5pc3LPK7b)V3?uC$r7eeMOvU*u8WG;!xvWxAq-G44C8r2ce z1g!Fwcy-pE*!_?p+S}aZ+g_ts z&gfrcutdIR`bNpTf_;2J1GDGon!GaRr<#4b`mdD_j=}bCQ*`^*2 zdX*mtBdoaT22J>xgP@DYDT?e|>GB~>RG2}iN6-@;j@K=qg6qxQZJf8A)o)~Qt~)I4 z6kGXJxWw0}ow(awRFtN1kbnwSei*Er@j^1prZ3YOj4255tWnv{BXUWju~9e=Fu~-I z(N*i4vly9giCD>4IneMpUFZ`dZttuR`uLOS9oRJun;`91iGL~kjS*mp|L!rT4R3ve6G>K%0lu_RH?t`>7Ng)C~i=bQ8L?H+kd zSycNaHf-?>jV&)<$tr32a_0#6n9ESTUNS(IdxrQ))b88v^i8o*do=G4(=Z^zuw(PP z0**uW0jGU!Zv-A|3Ik7uO8CjgR)|SP7ijBVj8)vtoZi9_-3et$2P(#c#XRhRl`n`5 z5~og&Z-!d33*_2cjxu5Xej}{v{ibXicwC6w4ggv)kqfO0hOBzsX-%b^L1IVEZ<3a= zaDa86Ohp<#n51Sqi>89sYZ}wo-*tQD*4}}TQg8C*^71ll`=lz)OtND|3&>Z|@ccid z39Fws5%_x@k}j{wJuLn#M|3pWaEf)}{r5gqM`;s`0)n;fYDuToK{XX$y<4v>zG%$N zeJyXhzDA0AU-#GVrq05XtUrDe`0UrRODa^0BY4TV2ymP6!r#BS`a(rX> z3NyyJTw|NE(Om`~$~ta#vy>pcYD|FsvUace%5vqrvP9^(Uy(Wfx+#(mImWPCfRT0! z@JheVaL>J;A#bF0R2{gn3OvSr+*L2t%9FPVItU=9;2S||-w5DMW2=9KSrc}kI4&tT zfCr`X#C|BvDmm})J@U%5iMJZGbS|~el5-^~s4UbCCEY-Pg2&UulVBMcXT0!=9UO3b zMbH+8So9U7tsO9_wDx+i^l(uD_N6ybdZ$vbe@T`?hbw$r3TwlL5>tMRx3D{dpx>jV z!BWUX79e1jK$uEgMB|{JO0C+Ez#_#v090(|dAj%ITzrb^Npnif>Jl|a8jPc24=ugS z&M{Xgac%$!fEsTuaFwl5jSPW==9%LqSw`{-pobP&kx(6nwapRaMnCbTqd4g=eM+0-Py-ix3pI?KQP76R)UW{AxcEEYt z7u6kLKmG0Cj|(j%|5o;y%N2C08zM`H`4ZJ}xSc}v`k zOJ}6d8|{!l04=8j7M_oG9Tyol>V_0f4UI@*g8P26I&Qtwqpqb9ZEK2tASHcIP2Fe$Y_?}6AOTNscL~1JvAsO+^Gm1z7USf)`_TFl zs?yB2s;06|;irh0Rug5cY{3`E!cND!&!wiD_Z4OxK-+QmwZPsF8lpEUYn{viKi1-h zTc4iV3r(4(bn9~Gehn0Y!19jW0wkq{VH1hUjWs9C#*F@$K|d`2!Q@@ZaPs_l?XuNH z?t$30p(RS)%|~|!MsuU2-o~UdfG9Eu+x^^18%FvgTC(K;(qk~dIMaP7FFJ??^) z`_O~%GF4=QYtR_)q0#8!h6xf48;l zzA_a?JNVs_#(|0gchk07cjP=MNSql|yRd_(SG9?zT?~6kZjrl`UV5UI9geKKJuE7> z|N6lieGiOevkooxA$KE-P7C~Q5RLv1j@xRuSr1*pOb7!*9BJ_tQ&fbE$MWz3kk?UA zfAxoQ-d7!;(p?WLwC^P_vzfO-BFi z9d3Aq_q>Bv<~r3D!S#j8BN4~!o_!!7;-N~2{dBU~19-P~_m{hiNmBcH&S!%r*|H-_ z`e2>t@QyD2)ny?P({%QYyJg(3_f6JZ(an8C7ya`fmwfY#3Y(mYh-z*h7Yz5ZpN$Pm z$0~r;2qhEARFgjR(q)C%fp$Djb94;&&O~Lwc0DDtAOgD=lotpVWpMYx9|~Xi_5P>P zhu{7W#3s9+js9_G5OltUPbJ%g&Rh+D@JPRegTq~WT^4*L)G&<)lJ`N^t+=4G04-Ry zGuu0VH5TWA`1V$Fv~15ubIstJSdr2!}b@@;W=As$xqj8ouPbWt&0VtR5Enxs?l_v{oLwbro zSfG9acT4=dztChEeh!AlxTWIGscRqWx?>wTLFC#td6*blE;H64T~@B^+L$t3MtCKs zakXewxCW-^YfW4n;4!|htEwR=Vl*MeRSp#xg@Dm$(7;tc z*hESj+i~lc{=?h=A76F290c&fw@>b-dJ$xpOn!b_(H+J10w$=9`^k5p!M zpQsdAkiYD_l^IGKwtiEwEC&DK1sN%6Mg5mX9m~j!UaRlalTnsHf*!{;&>mI1IO5wQ{t-kJ`!VCueNZ|5fEK(Gc z2CoIPQGeIQZbw=g$+!v{(`-mVWH5}};hyG`B$t=Lr}(19B-*k^uVJe-wRbdZHVmcF+0ReuaD5#~qcS@Au1l-y#!|@)Z*U5) z+S8M3LHyH$g9wm1{^sz{FV0tY*Pk3;8bg}br&FBNPfqo3HFVuHxs3$UuM(X&`tI~s zlO)5R^;#BH@|~&{Rq{l6qWFpTeS3Sa&T=(m1wEF=rM3)8~EZHISUzwkGPe-g;joY~@Om8Sn*e zJm);7KT8k6l+}CdS5(l(9SH0pJV~X=3JVwFquM8ps}J!HkWpV_MThO?jPB;@9a>g6Mztg|HLTIs3wGW?@CKZ=$G#KBuNL8VNPn)?-`JnAu9 zd%dt|^|K?Jb$z5c)VwyMrnPzoEOj-%Nk5;>o&X={bF9F`_21myo=yUFp)o3`G>tBK z^6Sm}aBar6a?(5@rnWom7wIg6Gk7$NT z2qd+fYO~}DSxj1V&^vwcqImJ*>EvhQ-T@L!R&_?=(6|=T=9{xiGMdZkv^`Us591>o zyqG#7P~nwy>89>Oh18nY88|B;8wAB}ye1;y|)^+%wc-}e6qy2_)p%;8*@ zpfIT>DWzx?QP(l_>wwVO>KAzun_3ZP>^WwZ;i7h_#Y==bDOT!Jc)08ksJDF*3oSRLr zQJcH}+-$<aI1=+ z>${cGD;hyAY(NVq0=`T@VVUbR{R88y{8iPOM?w`wDz%2!m9ZnC7?X--gqA|ycgReY z>3(XtbLpzXv0lr)=rY%Dh&ZH{v$R3LzcB;TH!L?#e}>LqW(69FkihNO=1#68riel8 z&aX{S&bhU!tpAQsMWb_?UKg^tN{du|mg)@rz><|WlfZoA0R76CPcw_Hz~Y{}>IJEo zS1S^LsOYHUx%Pyx_yzBCbxo>h)Fec5V(q>yKy@un&MQuV=2PX#`RQV!NbQ&AnLDq| z!61rKR-RQ)b1E}Z2N+c^3dUDoHvhCJ8LtC%R9!~WymFRkN>-Ynnx$_t*tqm;gFdcO z9?zF~so2d_A8~QWifCnbe@Fn)`!tdcJI&DQD4F3FM`%;57w&QMng zFAGayXLsdBlH}r499~UxbZ^m>-_OL7ocN9sk|;Uf&N_24QF3CTbPiF{6rZv12yyrl zNF7(??BZ>!Kn~>c?G=$+aoo;-Oet&DmfmnxvwWiz6XeG_z+5-`89&^E#R~LdaX`SuqgOlt8_t+q0uD^n&}sM49wrzFeGvKWe|y z@=2D1!CJC7DJ*Pg)XPtE%9t>Z7puBXl0(8-e!VQw0r}D@!e}+wx9QfWEauXDi~sYd z`XW<^-BxmnFkSh{+_Sup>r--m1QPZj!OdiC43nk(UcH?8vX2Wg;j@2kX_+XOT)4_nRf zMrYbN+nV_rc@O7!WHSX`fitzLn~jI+_m!Y%d`IDKkz&U_q4xYNzN^gLM85ASJ6Z94 z^_%qVYpoOUK$+WP{F!=YXX;ll&>s&6)%Vv>gq@}Fa9G7WgC*>Ei1y}B^@6t1$Z~fL z#>(pFnok_p+2cFw(OaxFJi1a!Y4xpMXe0@-e$09aF*w}y93-iWL8_pzhtv0BFS%GS z%xO~C1KLzcU30S(e=YmLjaOs@)yvj&)97J{&V*Y(Wk%fY^KyfyIkURlx$BFvm@OLW zb#XS$oz304TCu#IrG8{uk~_Qj(mv|NAbHI(J(2UdE;WoQHYRO2Ag`M!&H(GUJ2uXi zGP~vasOqD*a*x%Ux{>%Q3d-0amQno~vgu6nWT@ULE zL`ad^TFJUuNtXLn2s|qE(BGlfAMHGds(CVhr7O-<^D)((618wX??#G@0Qy9fKrVrW z5f~VEPu!zNk08(+SLy|&1oEv#kwHrCzgx+Dmh9^HmhMW)6DfJJQ=2Cz;WoFI^dYpZ zlj%WevX^j3d2o30=qI;7tG&BIEi)O6MQ>$W^Q`S4U&k9;!{{C*`v-?V`|(e1zd82X zDtBmNQv+)nd?9uc%CCrnmPMyc$IYibbL;3S8>sk{jG37va}O`75CWE`QiTwZXFAQy zH+GQFYY=TcP#am^tDgFkoSZL^mc`fF{H3vv+@Bu++{YfH{FoFyjv2d$j`f6q@^#Fo zSqw_~ACSztK_>5&CLKi=?K8?4$H;`OkFcr#SWh?>zraPlJm5&V>bTA2{-SHy(`&H4 zRk&%nbTd6jatu|n)fM2)DnoIpcu?2qw{Io(4Re8v2Y!=Mk60QmtA&}9r>(oP zzzTI*UmSR2HEXFzoDnY~eTH83BZsFsDx@=^E-Y}kvONn~IW}{1Y|6rmr-`ga*S?)y zgiMx|>2bdeE3y>ACGJIdiM{S`euw$yMR9PfdhT@+F`qEXXlFQb#&^Ur-5hs8+immQ z)QhW>p``G>(TkUSk>YiLtYNaZ3qXl`$Q>e>>fPCg%)VYvlYG6d4?l|w)S3BxremiT zY0TA2xSoki1+$>n=~;%GNQUs&(-}4k+`Y#6k@IzXtE=Z-yg}pS&0}!k5Rfv*cl5om zy2t`8RJ5mBGE5?;fo+c~rHckVCQno=a_#ZB0F!BkOP@K6`8fcc*?TyKL}T8IL}2mx?oR zR~J!Wv3q-Lz?^k*U2c)#ps(Tc9iHFe^PQo}C;ah|_Rs3fWTZv?XuX|=uxR9vvivk` zg}-3p;4h7JQ&b;e6vhuNgNv0%h|p$`?X@;}t&Fr79Tw9uVyjqGFU2R5s8Jiybo>^} zYaX)(P6!z87Xn5q1_80CE27u624t<)R@qfnwJ5gZWxz4ZQkjk<7=WDeGqlHXGx=g_ z2CKISevJISSd*B@e5N=jYSIR1kkpM}BRg9{v>@4~TO9t0%VCu8-qJzQGnalk9M&Ae zb0^c1(tT%LSzm@x{)-pOzQaOY-CIY;mtkWFhK)lu++*yV$JkJPaZ%qd;oMd~gcE1x z*sH*e1A5fFav$XAyT7rs7u@g5CQ|Y)mlTaYa6j)fKkqg_??qxO!!V1r@?+K0RQFU} zoR$!8!9^E|=+u4H10;F}X~Zcqf8DzH z;d==hN6l-Me8{uBav6{i>~~p@`bn}dY)4D_7Lh$JT#iR2BqEredX*N_Gq?AgT_4K2 z)fmD7d8P~QeM+rMEfL)|Dyva(O>NXW*lzJck?ocn<<=)WF=HY5EDHCSqrpqdh5x=W z2|aAgyj%~1xz3uohQUm)9NfTr!6!J98Ti%)usd`J_s%Kkh!i*1f7Xm7Nd+&fSxt$h>s4LRBm-o(E3)?nJ!ar9 zy{Jg8bkh$^VZA~}l5H;8ey6j|knK}vy?&g<_q($aJ_t04i#qpaW^u?uOv4K?(Dj$n z^`GmmpP}n_K6=+-({j3a`~H2O^)r2!6-d*YR+Wm&p-I0mx$1IyBgKTDdz0@vs%}b%2xP7stlnC$$cQX4|@?Zx6sR|U9OFyeptsp7Svr( z!;)2&BVRw48^ss+bDcg-zh9=Hfa9%%;*G%;akh;E$m(Yr@eSLMDs2i11Hc= zJ2u1Kyq0Z_Tpq$pu(A^reA#njFKp~ZBR03Oc_VgVV;7Cs(#DpJ*ny25^a!F%NY3Va z2Ym|f2A=!7fF}%*j7+TTBzXw!a>o-&6Fx)xz;Va^-nGB??C*X1`@sG_v?J^tEYwFI zLU*^9y_hVx0P|(2K>IIi$QK~?v0__9W1zD%qq+NX#ATtFtThWLbT3+JR?&U8(>EV! zQ{3#bDU_bJH-qLrcw@jgt)Ufy=beZk{3v~YbGW_pogkiS5Z`qMgbMBYM8JvvY44|q z{wX4V>gGOfI6mpcx%)jgAbyOP;oeG zK&OF+R_TQ`tR%cbfUTVeAoSRg>n1CL!)nN&tOHz3PRzc-AdM;P^{W>)acgmH3VaG<&FKmAU<_iPnHuZyv&;;29VdeDj z;z%O^%j8{{xyD@tSr?6^7&&j{N#gB>@%51}r-TfSB$L0Y!zw><%&;4mQTIx`33;{B*e(1!MN8Ge6&-(g*R zC+cT#@9uk#ZNIv6(q&>%V)O3U=$#J(&_D;G1_cv5Xm)En3SvR;w%S;Vf#tq%mV4$Q ztnZiel4mpz08ThX_!|#2Q`~EoCwx!d?G(NHE~n^;mZZGK5XdojwBh8WXN%oY)KW0i zG%=Wo>LM<2vR>-lXmQliK`hf6M>*?X{cwm61>zQsSZPile~>vC;0rbmOzc%qMS25I zwfOFZ4$btRGrjR%=|A-FOC8xuD$43VFLjpJNx%_UE!Dj2@l8a1p`M~AZ`3pOTc5L@ ztNDnWf`xw%r!A5kjxXlF0B5E&T+{{5?m7CKySWdBf>T08a*!Oto3t&V(E~kb{U?osGPsDt`6>u=E%0{HQKn44&R`A5jvBr3v|uP zL$0bNky<+@@Y4F=UG~dYITl=YzW3bn;ZrXBy~3`1vwvPk6|1XKpSmN54!Vt=X(-NB zrvE_m_FxDI+4P0k>wT=F!H&4}eGeyjDp(k4u<^UJ`7X5jV$$7s%*F>4AcFJt>}oo5 zR$+6IfJ^$(Ce*gwHKAmGIZJ=hc=>u9c=?j|1^mexjJdSlc%dPKi5? zAJwBi#h_nt@iq!cG7J-5F|~Edjx_|`Xanm6U~0$i)4bUw;mt{q`lDWSIo1ioY8n4w zIThctu-InlEHAgZR>qTk^RbFj8H0XrA3wjX6Ke=#p%8^@c<&o(iF zv--kS@WN#V^ou1X1OkE0WdT$&)5lqTOIvI$qArA5G$G=V<~1)dnyb6L&p&*Bj)`zd z?1V4Z#;l2B4`-=nV&&s=*k4ILKeD>?Ld85A_dhhP^lYN(|BLoK?8}jYSrv+?38fH# zcDx4Fj07`u!$I(*tj|OaYM%dGV@|a6Z{n`BH+mul|CIqgq=izt-QDg11#wCs4vA9; zkeYV05D}8nB;5RW9zPx@PMR)#IT3oBov}SL9*^zuTp!`q*~w#t?$~j8UEjXqm#4Dy z4jg^q=*#x(?A5d57ml|wu`j32S5me2@xRVF$6v5O3Ljfl97^jD#m@O)p^Jn1<0l;V znmP`nx-7q7WSM<%|CMHYE$I{5vpn43#(C#xgfH-EaxSdPW>Ufe&D zYiF}VTpQQ+K_33zecCfB;~2@;dK}l^U|Py%Y|U?9Z0z1D)IlF7_7_ejPx5FYwhnajPTHTKB3$5&ay%JlxyB}zd z2#UOu%FR{x9zNHnw~%bd4q{xEb<%G=s9-q{X zWsE*?Yg}_0Tg67P!<6tH*Q$^2Rl#B>zy0=b$qfoQY5mKD_qm6BUT>g(P<;2|c!@8O zE4TdCx_hGB)`#9Q^J`Ef;tIl??nda#`cyB5?jE+SCG^m(P7HoPn!CbDrOUZ=P)fq? zIuJPfzU)#X4A)Ny!LQ4h5_9{d5CL&NFMZyzT>9vn7=i7A*~?s*&U7~jo zk|EW;qca@cDO)Z(<=+E4eBDzqCx*-0DG`u}jT~H4x_Q2ftO^4t?4*;>g=!*WPLJjstGu=hdM<_WY-@ zfV0K&NtCx%jf(r9-#>abwSCkYCEMS@f!PJ71#U0tf4glN?6iuk<=c)xjOt<6@jkKW zjf@Jn{A-DWn9HDxZRDUtFFsL9EOz6iO(RAVpmvWJA2I2U)!R0ne7D7gpb7%yQB`>s z|5W~*z+_8?JGAf4=sUuX=#p_fe>jhDjdC*?*RbF5ALi!oWp$B*{aU&Uzox%yY-1aeU$1{ppxBXlu9=z>D8rgD-^z=he19vXK^_9| zxr;4U7vMsNybfiC1N_+?pw!O{WrZJQ;4=oH+Q;NtF_#V#7Pt9XlP|Vd^2w|~gl3DM z111iFj*H8_#-*+bx7sG}<#jE^cm{;-3f|L1z}DNRRfC2f@~TLsaf-j$KK+5VHR0lj z4D=)*nw2!+I_s8#)1a541YY|})Y;kg=|t`-NZ9BAH$ce0stMdMr|`8FhK`QFGXR6* zNx*C!fY2ekpHV|VJIO%)RKsNU9`C}XygS0gyFI>iQ z(Q!5nouHyH=tW(0dKhHo$V7du8EeV7239#t-$?p*viboGHj(M)XC|PQEW99`%6Aa; z9YoECUvGYgKuSl|4LTy!>5qWf8Kv2n(gg6e0i(m-6`C{)(gU2E`ih~0OhjGk!V9?1 zSUT`+5-JfsT1SWp`ayv%9MG_(zMUYd;426Il?VS~5`2wrD+>4(1zDeJ>c;hy4q>Lx zJ>wxVy)GWJ&9!nKm5@Hg-gWN$+|vp*HahiZn1!pnL?bywcs{I+ILcy@522tdzRsXx zvnF65hBrT2hCQNJE#y=IT$k8ulR>Pc=3clG!Pz>?LfY$}aly#rb5n}D;?jqFt-CMq z`7PD$rW~lRYE}+<2GoA2Zg^-oe0G=K254K1@~X&!*@OrZKLel8*S0LAw^DRHm3P2H zh;6ZhQu-kac~gh#$5Mr@NUyU(F=o>5c=15=ij*1;@2H?F$hoN3>h{)TVu4=xxDqKV ze^$6y`odbdSoW%6kM7B&PDNGSDjazFxx`7Gx~M@7=A$g|&kZId)JJGsd?*Ywto5<1 zRaX||8NKb9Nj~a34xp!$T)!+fq8ouDN>D(rGj{mSjr`>qq@wyIFNze(?fVwQYIeoX zql!Z)fUli^{F<5^1~OAJGppwE+zqhti7ADhyM}nFAXm)%qz$Wq{s;wpl0s~zdK}Jr zEg|&WWMC4VXJBw!v#Ges{+nu7pN3uy9wp(rZ5|jw%O$!SMKUG&4vupiSbH=hP#kc1 zP}@+DWOAeg(BIKorMmwLcn}K_N+y|+Jn79@9yJueqJr-qp(D*zFJWj<+6~<;>v`ID z1t7NrqZ4rnzlASUm_QI+MNw5Q?N z!{(+cJ2i$G$Wd#RR44tKfRdZ_t-7u1oUA4bD0YdLyCbppP{$Z5cPR%as5v>TkCi0k z?!yc{-#vH`c2yQ#nozg5awk%V6CSO;;>|JYThz4UY&Sx!SvIm%paSM*5Hm$y7_u3r9>|K^6{qcOYr#h<e} zPr+(7hH}PgUT1Xge!P>Le5u>telx5gg6bo~=qmR7@OUzgDe%I8^UgIL0xZD*$V7vN ziH;FLN`p@Kr@h3~wrE2}F(#DC1vCz!1pm9d1bD4EE1z>)v~`!WmXZt92suNV4;EZC zTV}qUa-2Q0R_-h{kYyXv&N!ox|4^apI>a(4(h8 z%1WTk6Z(8b)`-h$HXva2N|-1LGi}Hz#A(W}*$wo^->5j8wJ2b+-kB}2_rqTitdHQ5 zKba#Nj?!T7Q3i>p9+RMR;5nRu81@tXoC0%(RA$b3F`w)@qk0+|^lHyfC_0CtlvZ@p z#E+sPVijq2qj^-QHKr@#+L^5`h2y=qN}#bv@B6GTm5O`JnW2a(wVCw@1uMZuwuBao zsyf^6QBJLpbb!k22H22mXN;Na=24@Z#WwMH-TPcYyrrj46M z^yKiDtlqth`#x&+`atf2k+{RP!Lz3xoQGSM8yS&RL`wA1l&vaR;8E3p88$cw*f0v78*H{a;? z+t9^&!QZLq1W`90RhuUy3{^{cm;fgU@4!3wi0{0HPdHr`Da;v=W>Ki;q5vqg-(uMA-HqPlcVE=!+;T%iDqt0$h-Y= zr{Ia?(E;C8H%vVh$0>_)Gtqdu*Yd+a(9z%RTjtSEmiabq0|HXJJZ=7D$_<@O?O9WU zN9!)x8kTKRS~40k0yyiQ*Ab;|3#yc~E9!(=x2%ZcD$vwfvDd1Ku1p)+RKPi0&0h4Z zCF|+TXXPP2UpU)#m+pWuFs5{se=f9Aq!69dW0u6yXeoUm9j5`!y)nnYZv5-jrbR5W`GKzD42&d=t07q1~7_=B2 z%EVzH&MwRF@P`LojL0XLg#L_h!*^)wP3Ygn3%Qp1P5$*a9)G!YyXTSW+=|t}l3G>0 zew6ov0X~$&)oK{-L&y5*83XBpmyYoyoUc8X+gwJqznI^znWKOk@i_^=nex!BU5i0( z5*;GF5o;OD!6HpH4Xqmxe)vP};tgTC+|KQ2sz-Q& z>$#sBYkm3|H7BKka~GVM<%lemiaIU3E{r0sHSIFWQyXi(S6V`1ycn)!Eur@kbK035 zS)LZIS%h7B>(3RG$k2;{G$b5jiEF)|Dk;VaEv@dpt~huTyMWo@yh1RU-GG?HW^5fN z0jWM>bQ(S~r<*z92sxBHy!jH#iW5m$UykayQVBIojk2(VX(IN+j@##jFu5&%OiQ%T z#oZW!XK!|I^03IwS?_&PhNeBxO(%#O@d{uBf38}@Oj6E$?3lmr5vO^be{byC43{QU z>oH^LI>hv-AL#|ZK2cMmtbzd`GxG`;4RJ1 zhtVVKNrVc4fkIdx|6 z%jQvvbKZxZb>F&9K^24$^M@meAs?6-r6`>{v4EpGRi|pHXwycTR5xJG{pA&ofaQ%PDd@~Vo!94p`$PqY2wkBnSNE5&pyaRf z9h95a{R$JxE76cwoP%81NL4cP!Q$cb;1B&8NXfo=9>Kuf^D^n+7*T}9Xn|@vc+csN zE#kcS`g^Y`H-!w>s+87}i*U4N>e$&Di5MSAEA3U?kd;5=cNI-*WUVc9*;<>A4!V&s zUzwonGM$07su$tIjpsE~WIA63&&6wuTw25V)v!e04c;de3C*;#YpO(p;SNlSqycO`Tbb!Ja2-=i+>T*)4kM0Wg%J;fgDL+(Xs;i&u&|_kJtt>b)`! z;_t+zb72M5i!tn+wzcyXeb@Tyoy-a?y zsR)ufL2j&_DtA)Le#&s^wl+@cCDRNfw%MCXa|IE-OlN%Ul)yfO`Sf+Ji@KZ3?pJPt z2AwR{k`e8v*_$47$z`{(`5ip8vpCx)gLbFd=Xh$_Np{XIWEbZ%xjIcJ;k77w!V@!F ziM!?8?V$=m!Ch?f`HuQiD&iSdZ{zASX6qhHFT;)Qd>Sv43@BBwd2e~1&fla3-DXW@ zN%9v%6n=p6^kaehq7q2{lz%0p?9!{efDf#MNyTIRIbgE929^LdyAlA$nduua`GS@d zx_^dp5CaVmH))W)XOP^ZhEPZYI%`C?65%X6NRUb;38?J!op6|iSU(ik{`2d(1hwmO zNkG2rEW|aww?cKmlN_0|B9*%A&_=>kib&u*FA8?}bvnf_Q4kpp`B1HhjyXqRu3W2v zuiUgK_{1lA?L^9oIgT|T>k+bnQ#{_N6jwWvNl2Z>@dO*khEd)`Z|xY z!?l89&f`CRfaya&7?vfh6AFUNY8*3-;41PtvEK4J2k7~f4PWF7o#H>viff=S24PTc z=B9I;sQJ&#%^lXT_WD&ao&LcpN@Sp)w~JJJ0e*l1VrX`r{f#F zU^*cfW4Xx1K>i0?m)6E?8$8E6zh)=%^CFkSquvrrPxpc?wlXw6BMf|%fC-3~`T|{6 zmO84J5aK}nBm}g;1-fTT#4K}OpUti$%q8T?RBCM(!56JAOjgJeDs40Ccy%_;-!N3J zz(poZrOx==U{Gg}Rp=?E_*&K~>#c<21L>VHN%4|?Po!3*`^beFW5Xlf_P2c=E_EA2 z+pj)mQJAfEuIV4;1%TVJRBje__%fVU^;)4VzlH;AC{F*zmK4Fo{ei6q0gW+VD4QIpo@HIzy z7lV2D`7TG1LxwmVO#c0%8qov%eT+;TP)=;kXtDSf-J=USB$z!@OW3u9HG5~W9De_B zINbU8lK~9*3`fh=9qSHE8ZsyHEG;p#xhCn8Y&L(*41v)#rjDN$CvSf9lAq=PuJild z>F>kgsM{IhpYF%Qoktt@EXm?SoRmSLpS|ycEg1JGaNe3o{4^KJ&2OYIe=70%>I~dC z#o9cycbA7w02e@49lJsYX1{K)gK|{VhO!xOZ%*dn)8=HoVvOVkK7><2FhNk!DLyFf z7+e}_mhx!V%tZ}ON6x*evr@hAJPf{8*?GK^fCE^2a+^3iHgkR2s{`qqQ`+yYyvnZs z&B`u0&ZpHVj!u&ijH856G85npX%n-H1v0`A&D;&iDuzuL{PG)l(-ET`sMAJx)G(&7 zwc067+^SrP0^anGXaGb~c!HF46KEl-Dn&{xFHS;ibg9alA^pLFbJzi5tOFF0>igFN z6)-H>1RJ+SFmmQT6gsoBulZ@1SwfB4X^mo)`T(P|CjZ4{m3RWlRiIRXB;Lu7`0iP_3hc3##F z4}5G$9FCjTR;>A*kJ5PiQWhT@vvRfO=vMxvb+n&<@`*D?j~?cuzBt`S;FGFQM6z7-w7;q)<5^VVkVWU6R$9Z zEMgTKb;3%W$+i^6!_uyTwz~_^W|#!^l)RvmgZ`vrL)(qG?PiJF2Qt2MPR2Bb`CUkbo@1a(OtJ4yxbp5SJt}vfYLTorZtq2N_J?WyCPKn0I^Sr! zbzb_sQkw-i0%p_+WQ3T(xszY02+%tvQW`~mD=yM@`^ZTML3FLiXw{#=;u1`U>)+A< zU#8~vI3sc~!3-~?YCoV@ff7fZnVRxq{g}NQ=e&y6J(6`F@`dPskK!dH+PcCxF;lcq z!|h;C9E(=D$|8i!Wkn4%7-Ey(TQ?&}yHB(tmH?(1LuYU;9xj?FL0wczHhAG!^o6^K zTH-fn+dc*nA~3@Nu_)yz}xU6+tgwK6vo9GL%}znh9AXa@zeA zBDNbKwVN;B8dAG4r1o?C_Vi{1$0Elt!;1BAf*(Q5N1A*UA60$oU&dExMjw#_tH_7B zwPzW2D|w+WrCv-_68S4Clr9^1%bZV9XL}b_GR{;=_d2%{oD8| zK+jhj(eqUUdZu6CTTL_Vy+UeiTnK9|Erd2mB$zv@=#u9%cXz-o5@<(ZPVG>1Rku>_ zxQTD{Ji!gJtdkD2OaKdF%%{7CvuK>JHWYnwhyf`;-xPe13;wu} z#DX58Hcj(?wuX0Y4evIuVP}WjZ_9=)Xopky+{a9;p#NOR;U&~2zX;=j#ptmdwXT55WT_>4CD_v3|)`U8SeHZI#yc!v(oBQO%l0m1;)cC2zfJIJ_k|G zPm@wcQbVYKD#QON{-0>ip4O<#iBBJ%uF;2|;-^9%o`Ep@q*B#03=8iV6OF5+_H2__ zrV3lo^7BeK9k?7n0)k)sE8v%KI5lo2|(mN!I8RI?9oW! zIw@$bNujY?Mh>-4We} zLj5ov|0EnluWtQTTx)|9cZ{Ms_-Pp0BKCUiqhT0Q6JwvDlwGY^Iel_lW_Mr2QLc40 zmfp8X8Ylb>{PYYl;f37&+pfbFyFqwy-TD%Cd`9@Sf__32x%hqG34-P53 zMJYC_9y_8poYBIYQWKK>L5);kHI3E?EM`T&0PG2$l(Q;ATX@O(Y~3^+Gr!j+64xTv zF-EQ+E#g@)*pP7--n?My;WbGt*@|2^V4wHECoFuW2K*4MiRhS66Cyud%dYz>57$)Q zxTgHFlsa(NL+0hh?5WZh)#(@OmZg16cTt+Izo^)0w1;hyY-6dDb(T6x2m_xZZE1a` zR~U+pSfU5*v-V$A?Q>%__zNk$UNPa< zMCo}))JPa$50f+qWG8hu0H=wk)}zowtakiXFD^DzpnPDcf^z1jBS2tG1*&%1FiW0G zGMWrod1fmWRcQ>~zS7~OM$QT}o$8)x6&28`fvR9A0^B9SYb%H(2mvMRE`v<#aGJ(+ zl_4$WDPfV!8^$U!YsLDg7&WNS9hDD=>Ql2=YnkG312~@5FUPrZzFa;JX;lu?QoRmz zh5$Drgk5e`%#!U|}h)mij0p+0t6vj4`ie4!U7V(}972Q^6pBgL<{ka;06QTH5$UwYlI^<-7b20@u!b))!gxEo-%oMYSB!QikG5wZF+eZiU^59%`Pq ze4LH0G;^(Cmka{GOWmkhtxdH`swC)Wnisf&#$|XR>{21z2h<)=WWYx;BQ0{?b?LeV1 zuj#5BZ!%oaA~mb{WZ^9Kuw4M;{RIxA+2{@ZsN28;~mik+}+jH z2GokkzRi5)fl%e>QhaCzSbCcZYLCrjfwFYkR0XHAl995m9s4(sBj^s&2BE)|hP(uI zu)av-aagO!6f(htW}XTs_J#_dk(ahtPjilxs4BZ9>wAlznE`S|qgXDnF31c;+mzq;<0AJ*g~$~T-o}B!O!`K(%ye)O_`Tf-{oe` zPVi=e_LS8YW)D|yjLqEiz@fBCbm~_RuFYIW2|F$tDUGrD)ZW$OSeA^dV=aJ%<(8v+ zRka|kR9TZSWKtX5GyW-Ab; zUGrnyW$JolbrW0UI=t`whiY+qT{0e@?CoyKnH0b3P35oRyu2}K`k7`uY*0DKac?Ux@W_i|CHp1-*L*^H> zyWiNo_2|cgByQuU-K)nRX#7DKpQ+y_Bx<-#5iK#UGwC_G>J$*r%&u0_Io7B3|O~=d~W7OKlnwS07G4P z4>W?!aCZ1@tbp80tYg5&%O%WWZZ&{(D))>9jt%t-5a8{UhA*HgO{{Kfi(VefNZ#sC zC-i%z#>=c;s_ae#lk+yqEDDh@GOpzPAgM&0(pf|JW^U`Nx^0B#c6uMe!@H+x0U};| znFdOq)xFD4 zdZTxP$etE817)f257#|mYSn-$Uyp@QRc<7IfBDJXOI(w_6xU^*F53Lyy8JY(j@+m2 z7WfF4vAead9KJ_a%%Pay4Pz2(9kHi5!ky@`!{4M`$JMnldkLLEGwxSSHU)s8HhC*XpIedoC{S@Dge~RzV4eI|+DBO|#eL5XDcP-y84SI*Do%;R$`kV~q{_jqdj$T{e zC_WlaE^DzrGXE${ET1Ie@=hZNYhJzmeZhV^SUqpyF!?}5&Cjjozr|m7%b%G0ZhvsS z?(K#m_shFt) z)rMa7GyTXq1+HVa2FL=q>^rPLaMGWt)TlsVVKk}mso{yCB7;UfU%&mGZ<7IiBUkXf zf&G@`x>awC{=zi!bM*=|CjQ2?iKo2ZESbwU3a$*eQphaT+};G8$*;#;IGgKZt<&SU zfA1`^ZKedkA%%i1lYlN+6MI_sPvBdvJ|XQyQUWOTO)7PytZV|(qjrukMKw^HpVlFF zzb}TZacG0IOrj?~evnQPbS}DIX zeF?CK&4TAch&Y>6U@z6KWCh9fk=ZpHT@PlbGbPNbCBOctHNtJEhx;X!$fGM};Kb~; z8?u56dLp(=wzLn-sPV1eb3OGcYxv$=>1PR4_>TZa{u$pe+(4>^ooN5+K!?fY1d5c25N@AZ!T3nh*ju z@g>wrV2IK60!-~)g3elvVR=Nj7K9Q*Tx}B8d~0Tqs8QDKB#8Bs^T!JRERjY+lBEe? zE3ij=6qQCL3A?_A{9Zs9HCk95A;0tnMB{-(I|;Lx{ZK(s)sXfQb26`K@|R$v@sKfxA-jf6 z)kXN5%+9OB#|FNam|@RWTA~fa?Ys^_z^@uzJNfLApym!LLF+2W4SpkI#9$?`6W$BC zuTcJ`NL$;)T@!9$o%_;)*Lu@Pbi6RPg1^Sb@X3RI1;siWUTtL4ecfmsZ_HM^0{dtJ z4^vE{BQk+$G^D)0cn|yAXB-nxS}}og8)erN0YZYGrfjUP(JPn(!TFh(PH&v&*$4ox zOQe&%eXnhSV2&&Jm(C~F4Ph3tXM%gjkvehE7^0E|=(Dl(+-;}lBlvn9Iph#DuOxC| z5c0Fxspz2S`sChr=&e)R^hFbP8Yu0(%OoaNkcFnlwNi;LVmN3{2v44VaGPu9Q}$8^ z2IkGqfJ)zNL1_;^W@H_L^(NsoQVn`#Hr_=QK8-5`=y*-S5Nlg9xq7I~)Gp~Wi87$d zNBYDim2hx<%6Zs$t@}(lYiA1KGM&PO|S3ck6U0T!N+O{!KnV89lVrbCYRt!`(J=G@znz74%SgIWY4w>4LwcoS_uf351ug$I(YXFEuYr!1V zfI2zLjax-Oqfee{FUFhY{rlyx)@WPL$f8*DZqLYBmGXGHlrLy)mW$+mRn zSM{K~QfvoEEPN6O27-~%QSolOP)Yw}G^+5Y>8+a9UMe$bR@nox*1Mm%h2JdRhYIVo z{TaK@n^jB;c%T_Ey8FX>BjOQ4MEEP=ntkhi6yaMczlw$Y_-wt3A`dNvKgLk!rLES^ z54WJ`5W0q+IB&kOn{oR`g*FK_VPA3OfQv_y#Xn zErP&DsKD^e;AiZl8ZA#~eCq|ILktuBHDW(q)DHwTfU>sWp6eRZok$86(1 z#a}&qkXH6&@3rlE+rzx5dDb77)i)P51W^iXqi=0i~LJkzEnAZoh7qAm!zRzY{J zJ9?~^aG)5ZLF8%`eZzL5NSQ7<47NEwmd{$-X*)i~Nit)iEtfENA3VM>dyvp-w}W=c zwmv>d?PZeELquOeyWTB4U+?{r?zaCV82Fp*P}-3Eto0;@Gd_iJdQL zp$uWH%n_lo^ZvmS$Ljf#|2}KdKVFi!|2!tL|ImodR1F4QU8%gX^E#8UZN92v;BL_- zr?C1hF`X2B{zkW4eXz6DJ-3I8&sDw8ZCP%)y}ZFBa@?5T<3qiJ>@O*F=n(Akd?Wu_ z(Vw+BiQq@-WPViB>?<03zPZ5O^HiANVmR)>?E?R2O{4Ahh7PMjLJ6eGjo8t+{h$PH zJ1vx|`SeR4vZoC4@7NU8b@;lmb71VEcxrm__23t# ztXBu9Z&j=RGydP<|2_Uc<3F(hNErYY8FpoS0k;CENBZ;Phi?YfiI8+(gTB^yD1ro5 z*j8Iw5olbtw$;8D)nHFB_`=K#rGJ~3dTVLe#~5kLqA*lXhuSnvF6rvy$CXm5PMvja zrP%o)NcLtW(z!XCNXynfx+pr=jEsj^Ooclw$Txxb=WOgx9Mf`V$&b0l)&iby);}MYelf+_ zo=$R^NP{*R=@ip!wTcl18c6#3v_z88Ra zc;MW3F6_7_d(9)+9+cPX>E)|O_4RUk^=Oi?T^onHQXX=h01IZtTZ;lfODN$HE~Y!K z22_eNCNT^v4o^Z!8RdNX*wktezm$~^2%Cl(72+~2C1eh@`3$s! z++ize^He^91eUkK1Y?~{pIm7rvPRRaNiT!*?P=y zO)yaA_N4g$;*wjRkcHGDn@r_2J37cl?NOG6WM*$IfNWHbviDgJP@KLb?dQCosqGdp zn!=5emqr-^Dh}F>2TJBDUHXoha20RD90KhKx!>a z7(ZK#N43Jj&gFY69#CI;wDJ=zahO|5+=B_C&+;7bFo)F_4{B}+b7O*sU{Hu!v0_%S zjUezycc}(BjZbgJINvZ#(69NSywWDlUe=TBeBH4=0M$bCZ6(pxgS{$+N{W!TFv*@c z<;Kzf$`I=46gfBrL$;fXhOar6h7|)t>2!@&ZzL28+P-U>T(xUqxPV~}9xWa#FnD7{ zW~)p4kDs2C{|;i9jfUdtMDUYxARTYC%>cJPHX6{s4D}0_hu#~#(jmpau<{wVMxzSDkYH%u55)Zp4>-YC zm54E6utw_60-2)d&`axfh<5_P1;lCIB`}y%0fRXO7z`m%Pv1*8c%(4)zp+{6ctf$u zkkGd)*s0==b+-cuGjV|Zwnoz24JH_GY*5a^9+}(n%Emw3Ao<)DO}svE&~BCIUm9QQ z8=sDD?<1m4OS3HLh`6ALP0#my#AEq5EMPh3$IT%^ncEWY~r}zrwkc=Co*cG`yG*iX)46xyCDa7ZGmkBC;MvbwY6%cjilm2?*91NZSc%Ui5_I;(r5NGesy*n+ z?~Ae@8T+ROP$CR_m0^a0T&61cvS%X4EFOU}w0T`tSQq5H5@Cng?+TbM-)W-Tc5KKG z$6x1x>o4^BT`U79`4z2*&#Ef>HIz#X5@^W@pyRHc_vR+!P9U{ zJXaXy#<=#1pVc!sTWpl7)PI8uMkTo6oW@7izNbFLm@I`K!zwE|Y7ZcSXAgiNmY&@T z>t7>kO?XJzNk&Gki2sJqdmN63e)mTF8-fF+qj7S_tY~tMKditoy)O$67ML89NrF7) z6*OGqixe6C`I1gPEK>@tSxI}+pZAtO(8K5!Eueu8Y*s1A?i$;R8~erCoyIH1H1Fwd zG)+5ghQJnJOZ4#lfap@g{axVo0TZ*_#8pe}?-0L7v`hR(i&`l0<=HN1@8Mfajj>on4++cr9@RjBzb>Z;!Q=)Vq| z+7$^6PuLHHvD6D*Zqs7yto0_9i#Ms-v2bYtroO>yQCt{cyXT9H2h6j+>?u zr&0^ja(B}yMpNakLpNRG;(PX|?d?xJMyxsj#t@a;#Nut@ux=ay^N%qFvOAY9Sk1?o z(+>9w*<7PL230yToOTOrvP#B%cF}tV&c^J;zGap+CAw$hv8$Tp)c5>yA2NWnBR{_d z!ty%Q1I%91tQ*AE~I$DU){i z0_}B!)OQ|l~J1No3M`=_6;fNN&|cZ;5#~6te~haZl7h# zWeQFvu80*sgL(j>?BNRdMX!by1j|n+47Ld%icM$`JEVB6IkZ@4mN)!b`+E`W0m6@B zvyhsLlO1uAMHsySc4?&bwtV%%8hfodM_Q6$$42ZBd@>70wJR3>?_i#L6kJ2{H`+)! z;1nyXyy!?gO~O^Xd}F3*dXMi49_G#*Hh4=bf=1CQtLRVyoq~T~Ly(d+#L{ox%k`V= z%2sB=LU?3@X8t2r6)GFqltnbvT?NvUj0}Hf2_crTZNqFW=c#v01r{WRDm3Q>r?6Wa z8}x)&tN=f2h76D_jQGQxSor>$x-cNg1c9~;tK-XICn$mc6O$mS7(Rz_VyH;nIH^hD zrUS{Jn7*K;YyBdr_&g$FWchAo$%9nK+|Y`Z7bI4W0-{+)2CvsB@&y&SkxN7aejg=v)~?>ugSrc5E$`ej-MfZ&JG_f zeQvkV2W1WnMQ&Np{z8gG8en%eJ&Z0b{6;HZzk1?l_{nCV_G$O3;A)Hm_osK59vbC3 ze04llvJjHfztuyr9St&q?J(eBj%8e>raU7~bR^wPPm-lf@u(&r5+_Lk4a<$u?it;L z!sXE&TN;vr#YxNc@Fcp3&KpVWIjvw9qw|hx=3OJ)deu9o3|AMKZ>HxjP4DMq)oMg$ zW%lKG$OdRbW6Ue~JrGk~CUTD=PEYr2-05k6SlGUTnq{wNdgYOdW_UK8^dpTCh$9g{ z@eow+w!^90CILL}2P9Ec5Xm32i`=wg=m2|y9M`uCqPtqArPT__f;pR8kDF25s$q-c z8miVJdd?@3p8ljn186?9xGYC1tj`*P!~Wv7>gngv~W9=o=+xTp|Wp z**3wZmePm!yz@9REcDg)WPOoM0bYvLeg3P#`(qDZ(p60Z=i@S|r z8U%4QLeYajwbjzm5u!AXRP-_Ds=6>1pkF60^5U#?3caqTyHC%rORP~)8$i{#8NIYk z^%GBe>(J%i^ZvZ`&Vf}9^~3R-A_MozL-~D?EeF1SMGbhfO8Yr}lO6?-(XjN?Z4a%g zfHn$&owX2yWb628BgfFs!W-8-@N~}{YdZJqeq=S>RQb|Cw))hb0ilt$2Q|+27UKM# zv2jNDWUzSt_wM+dS>%ro#?xRNjLfB%gK-#lf+p|JtX^!=YBcZR&k9{e_B!|l>CzY&+no1|=u$57o zc1TGFQ2jNqP+_cGX;`aW52WpSo<$ypte|@EKy|Lc19lq-L)c|&VY=iOg_MCU(msH6 z#-+ImRx@CZ6OSY>n`C)J>?Qve#H3zzAl@D*psILn`o`|I>xnZ#7b}7g{(di8UfsJ!(m!jfT}G`-yiVm~MKTS$q-!xmPs}cd@CM zG!5hSY$OfE*hxMXRqEx|FIa_CoUo1>8B$V5wMy#l zu^i*B(Lr>0IFBHahWa?39Yu#nbMYl1&RZWxhmVn*)B6_$zlaXMnA1CyDh2Qt(b1Q4 zdYy6?&%PXU;2bmh5=k1W3GOim-rOy61U}bHDTNL>L@xsKYJu=)90n_f?*sn6OUY>h zf=39VF)H^%*kDl?V5|5`9xJi4(ZM}IOeLZZIveh7E{#=LDr+)XX*RiKJiTq`UPEx#|=gkoNIKMeJ&bhyGb zrgWCiR`YpM$=^oG(bdlZmor)TfXn};t?TQ%_}|gvMB1F5@?6TJa|5nD5&uI?p6Ua4 zJJ0d8GMn3?IM_IoEEod2nJVqhz-7XcZp%nk>W{%hJ}K(F0uLo|*NYGO=(tQaqJTxy zm;D#j(=NQdyf`iP9k=n^K*U}SBQ8|Bu)F(In%B9A(mo={k`I7hS?71~dw0Bo9IFg7 zIK9){Ya>uofl{{yM3_3VwvLkP$U-YNgRCrLSy>6Uy>0$=ujI|I2T`V`vaPA$n##7O z8a37Y0HO|ySv|KUthb8D{Mry{>MPp%YOb#^oFD3292cl>5!SQCyi%-*{3C7%Ubzvr>yjYoqEjO(rV!+#ARV3T5h1-Mk(Y@L2(^7J zf7*V=c^H}ENcB`e@5l0^bYoJc-i#E^tqvszJ_}BkD^isCD_X)gFBki+ z;3UO2UplDp@rFA>(bR3xZT(hs;-Z)|-4HPc!ubj!_~Uej7~bnmo$Z}n`eFBiI)uOF z$@ab&htQVrYR~w}l70)*yx(HbX>RT&J#+d;WI2Kk#8uXfGi?ebXHG%Q_M_-MLm4p#1Wv6EHJ zqQ?Wk$|$X9_x?i7AWE0U%`O^A_BiF?7*|od*sQS)mO_WSXl1l83X)(|bz>ySqRh%b zZSC#a)bTO{nTxyPY3?p$Q#UKJ?mM~Ztf>|n{|rkI{^!$IbUObqMCD3UTrly(twLcU zl|`fVmW#8YUHWak${-&QK&~O>igmh;z2_L}NR~?{E_!qTN;ciQ!tRuhNH&BY;-}|H z3RZfOite*}^Iy?4bs-gdj_{Ru+j)6F4n80#;&CM zm3^;vWuMw8aUhvbeC(A^!WqM{I`5#Om-il_yewBn=B7#T7!(6_6fX_bR`$bYc^tpr zoy7)@G=IaylxD-o9y)LEMRLGrtYS2xGuFcc%c>Of$#q+688%Pax?>AWxQ<8fg0H~i zh{grD=K|f#5aVqr%Yxx6g}s8mP|w(}2Sd!u_1_#4?R4gv&Ks=4&`fBrWiNrBw(kGN z)2HrEq`k97vgyRSSyuj|qj>2pP^>93O~NEDb=GGlfk88@ba?Y*xL<_BhYvSpU)U(8 zePXhBxJ=0y%YZ70N{=4mJ=aMCB*_W{Ec*-cHmj(z%N;V^7s*3;i&`gH`xdpPx2Uze zUdkj3_a(;1E!=WLo!dP8SYc=wQ}aQEzcgITXbB_5a1#;p z@@-gxS>t{eF<9NQ@&)y3jn$b8K`x)tp;|-YlV%TDhYQmS{SX^vMjuNdSuS#&fBmO1 zQ>|Hb@^&)hp|m}3$9zF!zQCB@k{J{UCtC-X&Vb&>8n?RKZR{JX1qt(Z=hU4|s}W*o zhF;4f9;`hidugaIJ~1~V42FIwC!I9z7`mw5$0%;}-B;tObA-4L`$s>L?#RN>f!sVb z+5LEGw^L4|*GT`&>_P8t5x66Z)H#4V!@S^~0)!$i5j@);#a-LZ(=ZHvl@g?_g=!mT z7*q%(BtRT4INWRlm91rkt{uw?2-v&x*-n>I67UBQA?`y%@RPf*_B0teF|H4{KR1(i@-VQqrIXWQ0t1( z*}q?yh_T8{y;epGI?55u7IEz`+^Y;<$-+8M{nSa}M<$p7sZ0(miSLZb3tz^oCKoPV zx_ss8wd*%Jy)2x=2q6xlzFimZ-j|!I-hSBWy|RX%D(Z13!5E{#B*RYBKcQ@qnxY02 zQRH{0wL&z|qi7u$zjR2~rzN)L-2?3c$a#tY%%0mVRNU6rseee* zA7+-h%O(d4{Hd8zj*)Ov04zjc9oVC z#^P3L+gXz6Zvmu;YauWw1u*g(9Tn1z;Q+rrJN@-RX4iyAxuClN1|yKqIjaKu>H1%4 zUwsa<`@0ZQo{l07x`wTk;BwG)IdI{UHH9+)g-&Y}9+bFS-Lu6iILFyu`LARc_%8ic zp>_f0%3Q$L6XymWjb1uJxc>Qh<`jp^Ho!;&qrN)21u5=;@Ua48>&Hp^IGtjoeT-W8 ztU?pL2>n~zaA3=XLhhQWd%H~5wABa95JJ`#l5$*{cZ0!4Ujh43fGsT?;o@nyiU{Py zFyOLnB!OP8lQJ%$$TT_U&u?$-BLH8|wu{lOsbECK&APgWb;7uEPiag#N22D?2APRD znn~H@X73$oqO*pFIp#uKG1fO7GZiX}FyW?aTaNJO9XTTIp z&cUFELllZl4N*yuUdKcd`0rNPXEcte45v=x{bwm6=<(D%RUk!fZM^V9v(8!7R$)NB zZ9+w%MKb_VT(&keXO@FO8h(UWwebbNrgHsugC+`Pna*zXP#3qG)7=V*GW<^=$0RYq z@BouM3?dTf-A51$DHDS^QOZ4NDTLg&`0;fscxE+*B=VepMGW@K^hooREh<1Hy1RYJ zb6N;Lzej3z!ULp1!m;2mlHU6s#%$IGTR13$H5)4(=F0%J{Ioh1Q`K1UyEQ^P|5hVX z^ao8e8$`tIk%cEc%bGJM`YT_3HyJN4X8*v3h+KesEXZ8{|Jbel?>pSz$Y1rD|NYAj zI*9$f`Kj62|1mN9^XYe35KUvD3jW?fl~e7U=M8$dqRcu7~r!p1*sR` zxYu$|hKj+cj`TMHy6xQnv2^K2dpZup59`j%cWtp2#;-!>>+_9VeIjFOU)S5jv=b^| zP!?~-$Wu}LxS;R6^-?-H-tZgjIHX8i0#UD=hnArNiavaH|G|^zbXf;U@z&r2)~Jcs z@0q%rt^zDPBxj>{1(gkk;pluc9I1F{<9Yc67%n1-Nq++CMP&m*saV}J$pC4@aLyYB z6mH8#f7?KLqa#JGV_(zx{17yBw*+!issN+irX>00c&Cbr0b4Gk4>--vZT8^}%0v8< z8|qceD8c^O+!})niv{1t5^(%rFW1JZ3evp-YDJaT9mE_iX%)!M$7@Qi5}}NM&Ul_a zLcXH}_bY8>Nk6San-5UqKXiWfKR(?})ss&5I1Ku9*g*Ia>dw z{z5-|s}3a$8=)jI9QrNO&pbXR&5C15>%E3Ru{8G-ruV8v%!dHnf zR1Su!_na1MVfke6d=Nsc>Lu;hU($JX7>PESxD+5|s~6i9Io)f_Y+^ehKu4zDa!n!F z`|u}XZi>%fGd?9S9Dmnfp*a@+!)LBB;36V9s8NPW#FNQQb)H^`(CjI>CN8d`)ms?Q zbtUaO$kv&wr^h$5B=h{+&z>2bn^)tQ{W)0+o<+X4PxC!gMnBK`GBiXy-o_~gx37{m zh7?~~eKPiNQ+q;8EEemrPt?}K$P92~v{O`mBy2G*uuJHg;~r01A;lXb)ZI+W0Z#1{ z+M*q=Ni7?v$+25htVt5b$!KoYC4JliEk~V3qdhpF;PI3fK#S@Xe;0dgMhW2l2Nw5(Bj~ j#wbpk14U~2$?RmOAmOB4X6UwSkZ8UG8qf%^3cLpZy;~>Q literal 47729 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%0Dq zw5U$ycC;t70vz~TKqrd}&A^=+M;D!Qdo%KmfNO<)X*KjZW$2Pc!xW<{JEdy=Q0kj zx^)r;kAjrWJfQgEF6oyFGF7fj2=6Prk5$U}ct`hY6NnM8;NdH@>%Rx47>3jtRusmVm+ zc|Gyk4zYTR!p;$6-x6MxK}U)T7-6f<{!hYI&bZ6AK6ww_2T zf{h%0P@JaHcJQHPIn3suyH1_Ra_$z9DHP~h1T`l%7cBq$i&MKdGEF-rp+f%oX`-b{ zl3H__wZsxl>Cy}4bec&KF9r5v36wwQVu=@KLzo-lZKEnb%jO#H42;$l!I=>w1%8P( zOG~WQRNPjAVdySX20qv4T^kX)$H>eqIqs0wJmsHLO~W>1mTk0(uFX?-&vm{)Ld(B& z9z@>*iYW7{iY!yNi`kIi=>aU2q-Zq~l+^pcEA{O&TL|z-@6ea(z8daSy(a`0?)nu` zEw67nN_Xv)Bz)mc2b)x}^!L3>)4Q`QKU^M*SLn_et8r5&dr-Fxzfu_&nWTO@q%66_$ zxWu6L62(c@`e8!$a+ICC|9$|1w(9+;7L8;U>&tKsUiwCRmsU4(66QMbbDbnNZS5Bw zF6^t;+G#_8ZnRxUs7a_^Po9$>2t+&U&D6fik$F{78PyOwsp)EmKnHb8W)^Q!X z*;K1~D#bTYSj#EvBpN>Jx~DqJy$@*HE;{!bf$#~pGuvlREMKs9i}%LLDa7YqA3W84 zVC5KP5>lz!iI|D0a2t|DH4-x{q9JJqiD`gME6iyX@C$ZC>XD%=E3Fipi2*9Lj@>5iLH879X&7wJ)iuok%&nxf%Eqn zsP;`J=qS`_`)uE9{TE!?uRlBH(hJrXTd9^Td5UJ=E{P~jvs#jk12c@jagCjDeMB0j zks|~l73ZCLNW6z<^e7JJbP~3kF+tE;na<^a8TmRYlmx(GQg~H*;L(|)BV-jd`6_eT zW3R@dq16oSUn_|Y*S***t8y2O|DZktBlV11Pbg`%ui37QmN;h-^G@9G(9OYO`e^0} zU~73!Zn^rEr%(4gkoyYCI&)+>@l@iR&knor0J5hI`ziL$n*QLoWvMk|3YmIR*la(F zh)%Mm5UjA8to8KUA%zXL?mS}Z#F#;NQU`y^VD*99xJ&5vHcGzs&PuPGid%KHk#j46 zam!LwdN!%Dyx={HYC~(HLPtP7<+&RP0jkd545TX9`uS_-H#bz#PGZ;_+I6xVd9%}! zKb{PbOMy!k(nOLF(9@Nd9Rq|Iv(;U;2Kxjye7Hopgaui(mC6U!2{mY5##w)BSr**4 zOV}d}f(@9QT+-)VotWM#mq0vcoFxz5Cvm^BAPihz1(xl@Z08oLb6GUkH_ZVJ`Be$` zf5Q)oeqNyBhR5M8J&0Ut*&qax)Ti1nJAK5^CXd_nrFWtAf>ERWTOCl5aNnoH{=WK2 zD5TWTA7bHy7Ps5QtP}`tWeV(-N|rY{WSk*N$Hd@ghI*}ZNt+ax(l;w^5?5O^y0&<* zHj7$@y5&h{%|d6zFhYw>P~3UBp(2eQYeguZXdsxNMRub;?lM$cZhPepk2IP=84o3r zWW?sUdtDAZ#*{74QL*1I!rjBJO)7<5?WDLgH5ws(bMngHUBB@rhU0*}zC5X_xy(y{ zYJ&(tp*Fm<#aLfxxe=5n!JC;kVKyyOLk?qF;#(1Tbb(f2UzF=6D>*uHD>JwoPlFBs zz6pZkQxs61`2i@m;Qgk4p6L+J(svQiw$spVjM{X>`_$fbkKa1Pd&W6!Xve4Q;f4(1 zzPm<&>DP5SDO$x?wKg_M6|!F%j?2@p-ON*&YWiPTdODNxCOgBy(r2FH#4oLK5{u__ zN2Ag6Ls!;Y9%OAxYP+hU4tck-wlqTysXoihaUOPuH!AVXeckDB3`lQ6X1=dVnX(~^ zM3UBkik7sUtbDQhTpxC@&to+ENP#Kg0m5sHWoZ&MCIcl9nkXEUFWLb%4CzGQR82#^ z(@?eH$yZtpSBSuUwpRGK08CB5@(t@~47xxUJQuWo7PEEgLp#lD@0<9iLA?9GzKj34@ZfyaiT`SzFJR_ml3#?$?mORy z3GPD=;NxoZucO0wk{ASIC4BPyb#%0ud^kyt#z)6@ z#AEW3^%|bB#1Gk>!#_5;qyiIvG&!1W;N@r&zsV#q05!zBU5JPQ$TRULAoZL9amvF? zb#wfumc%6D#|&xl(NQu%`ZowLGG7u}rlOl0ldl~8I66l9b8@=${P6X0_WW>{9tZTe zpvO~s?9<~bdc2^=_s4X2?)hOwffYSY=#kUolpb?>OzCk>k0m{3^ms*&1wGE_aS1?b z4S7TuJR*pX01=N9dgSytrN?V}?9$_a9vAd@N{=NyX7qSPk28Ag)8i|8yud@F`v_Pe zFr~*iJr;O)80=+Nj(VpkpqdMBYwvzI1u@A8izhBaiwrF?v|ff* z{G7df|NSR;8#u+!+c7nX@h09lSdE;Y0v!FQr^&_v@yz8^catEmdNIE`zX^(8vnN2q zo-fG=tC!-J>}RlIqfA|Es*k0q5(!qpzy5loT=t3I)e`0wHX)6a)QfA|%uurdcVdDr zuWC2X^XBpElCFl8b$cmligbC3)(q|Fk7xs{QQdl;s7$uMtbR73D`O_v5ypP<7kQh( zDCY>{HS66mazx2S^lp@hrp>_q;rYv^N7-o6Y(>Rscs6J?z9k3?9*pkPIVa?)TCviO zj!)+mU7^G!a@!DRvh`|qaJe|C<_!wwFl6Gar+(HSO#?kXMV`}E%-igDUc1GVbKB;X ze8l&nm1Tn(H`#Rw05fgHIXCE1W3kr|S0igWA0(CxcS+TEL=>f#(9*Pl&!zg3*=$Mq zC9*rB&IQobO2}{8X}pzylN(dgdYWr}nbVcVQ0Dj_(7>;t#a;sxjZ=KcwocxV8(8AM zb_kO;W=>8-7gdz>z>g%hZ^%j?S#SmM4BQF<(4rM*oOWhE@1= z&DzPV-Td;mr@IG#{Af%i^oFy)%m8) zUV&d9yr;w3h^N@+w8~mh@GEOSm6zc?G;JBbLGVeN%~83X3h?4p2~%ObjF#;LOe(Xl zX}?#LZsmKU0zljMTgzk`BSXpB*!`X zj1g-@RgonXsT1J}AVwl4NkpN~#axydc;HBlizq?Wv%H-Qn9=5KtZj8u)RJs4|17g< zNk+ord6_|c^koTYLYcuZ;X#YWO2n_QVQ?*e^FB1(zpmEe-7@`|@@Ao%kC5{DLa5CP;Sl2yUlp`bUp{fe-859|6J}Uh(T3@|UF3DN(VOKU$`& z!&u`-v~`x3argA3EoTo?rQhiNO@a}YopsU0b3je$9TB@lV;O8PQS%{*9=AV)Nvy3% zm8ky=Sh0*aeNc*q>+%!E;#Y>`W^FAzy>gawkWtL(ST6@bICklZ%10$aOh&W1Hm`eS zR&ZcJcVA=;-rZu9O*vRgcIEoARDq_&3D$gpA%?J8ZL@Fqy{&$n=S8Vqze+B=D&G{# z>`PAP9&NIU6DayQM@xsDq{VTjt5vjE2U{t1wb&bU_6GSn4mwwyOg_23w<^s)k&Stm ztmIU6tQb|At6({uuV%nyuM|$3o;_5d#_l7tXC{U{(f&#ys!I+1ENwaZTB8I!L_fOkwalqO_ahA65HTpwdtHH7_sq8y&a@ zRIZ+@tq%RN`{ZEn@qSha;&dm!PGZMreg*FBPdw9?>gN~!Stp+VAU|Ma`DgR$B%hCh zJDOEo>M_V+I>n>`QyiwNIM_cYHyx60>ZyJmJ}B+EdDI80&HbI~h&n?0woc@12u5PA z<E$MJEWl*l`QvcoqvK~sv#ag(yLZm4WN5UNPH9RO zGhYAABw!i}aT$><>K^hY{Jfc?g-KIe)0~Q@+Bw2Z08acej&`@U#*t_d6eH5jY~0W4hfvQ04OJ!z!1VM1jIlh&=EbhD-Y2ySp)n2nzN9~PbOA4 zHM5Z}pXlt*s(OZ{2Mx7*a4$|2G@?cKEFdnssru$|IlrW%VVkOtbu7nVhI1fJf|3#m zW;=3|Y0(eV4ue;MUd4xhV6uFe9IdgLa+ASL1u`1%tX8!zyf$%891i1u>8ryYs;_%& zIo4#e%DA;wS$wGRvfMlYf-lJFgedKW6w+Mp=R^N7=5n^xWC_SqiQ(bAIkTO_bdyvu zIvuztrU-eF3a%0xO~HpcIPCT$_H)z0Dg(RqVApbP41VC5JNIPX{7lrEEtmjAvhvTg+V!tZoCXd|`&A`hm*SS|DaY&HMz9PnLDpNf^*dHgZ z4%Qu>dmX+K%nzr_P5u=*h5&4J#T30fOPjTzbvkbt z-1yEfkOX4^Vr4(xj?hi3M9e*dDelYOxhL-9D?Lc54bpOL^LX}2;YbJuhHq$e%|~9o z)kl6FIF(rH?kGw$Wtq>>BXTYmsT9O21Kt{qViI*@m4Wj9jh#2)D$NqKYIbSvf{#Bs zYM?BGYOE3IF{{s-59!}eINl(27nXi_{VpIbRZOpzi$t1=MUayYu#=+Zn-9#jI%#Ci zD#fL_cG~QCDvBEiacmS!ANh#%@MZ)k7L|N{)<|=gaGHsyb~bk-=P+p9Y|_wtK&l1> zZUVUGf~hfmdo&gvzf1mW8smcS0HGu;D6XQ?5G2WHtroPx@t_Uyphcp1XLK{mzNiqS zTCTa&o?Xr`KZn~(dq@BGbv@l=aEDRMQ!j~*$;Icc{w@XzPaF4GZ* z*MI=lHKZtANIJw|`l0Uu$L|Nx2kbi}BUkHe#4Po#;1DU>LU*0=>4T%A=mUXbSnPM1 z%O9_`bxD;SMws!uHD@tTBq+Qjv6gT_G4^gWDngM&)(t8l6?TSp5qr6++C^T!i0o;zLfJg3>?ytK54tUxDdfX-KDMJ-wK|!bvJF=H`EcQm zk8Q6G>kgL9c@6>EAdWt0l@0u|k4?40lF-kj<84k?O@1%Ra;TJ!e|yYVB_v$4TQOJJ zfO#LEex|XXiDZ2mXT=Qn3jC9Xo`Z}a+pYNOe1i!0bA=d}6%GD@Y$oOH(N+9qA6rl- z;1P1ihf=Y%z?nFxxBiH3)?1rIWgBXdex|TNRCDmFA_ry+f>;-F)+_!t9ZHxR=>wLS zH?5&LAcCCz-o5LD71rb46(l(6wt!GDy@w}dO7E|CtSGDzWpZ1qKqf?7#DFxX0paX5 zRag=#&_OZK+xML<)$hK0QEH?~qb)4M5aH}?ZEZ)1LT6id!u_|Z%tql?&!2Kta#gzU&X zd!2O)Z;vCG#Cb*%b!>kDxWwXK+Io{^m4hUvXnY`#sgHzFD2nupjJ!aSq&8Fr(73mu zhlVaK@&QD#yddlDqTT1jBq9P}8_RF-M0^wbrs^Jl$8K1%OMB3YnT^k_L#s=OOpP-s zx~8|zE`gq?F@Du+cA~m1CTrpidyn7<+cdvJ!@cSxNb=9|{AxEcTcX{WRX`Eg!n?0V z!iPgNFY&G^@l5GylVztxuqj4)JxgN6NF`A^gy?3(^XA#s7KUa3!M}6^Ln@8C#mxq0 zF#e+`F@Wz!0jP~(P>3G}wXxwqeG*~M(Qk3(yf1DiH*^J$lksPy7owCz&D6VF-3ci< zStx-*kfv3}Nr=AFOT|w8lXUB1l|fS1Wjwy${qpeF5*y1lTcPM9?6GiD%p16!o#ZNr z#T3A1;It)?w;j@=BXm)MhjC{>aEmbQxwe^yyU+??%#I+;Gd-8n7wFV}WIXh>=74Ug z0mt3%1x?uI%{wH*!>u;aB&-1qz(9UaXS)??EKUAo+zQ`R_{2KYw(Xgj$M);I3I?rqDI!DYA=k;Y2xVm^ypNN46%l3w>2cHu5AMog@+wu+kZr`_2@W#7R{QOkx_Q&yc5 zqc|WoXb2l1@=MGgSQ1hZ zYc&CLZy1(Gz&pebICS$JB43Pry@gvq_ot;$lt0x3_MqlUY=8lX=*U^Aosp z873pKnY8GA%v;RUq!?%b&dbIyk!Y?MuzE4%-enmnb||_o zYbU4{b1Kg>&;l7k3YlnzCaSZGPVbn}9SyTKiRBnR>yCKQ{7X>dtsbbd3u-R=!vJw{ zX~x0!ZR5bX!369+Sy+{ZFa$)4-NTlFdwxgs)%B&{v+hCBQ{TZplSP>!EkvxZ=nElhzE- zSZ%?^Af_ggPnufPrA6I8H`cZm`>QpOSxWh00t^Cz*BKybj0{0kNTZo_gKqX&h+uh+ zN77mtV(qrp3HBPhft5-#*4#^ak4X>viemcR+%=Zs$M^>^8$nO%pD-+JjuUBx^LQ4`mTRLdYVhD zwHNv#pHXS;lS=1XJn?d6O5r61)|s@`N-h}B_b(5qJqM=z(Ji~(<2$*F1>Za73KRim zT-<{7#&=d)^D+WZ(juF+J~e9sKpLzAbuzD}FHqDkQhCS{cj;6oyx@P4MLB7KKF^{z zSiC6wK!<;i66s?nee4GA?^p%Mal?%7xu&VqMcu>H@a_ zD?rr0U*fDPAaeyM(rrD}5hia}>x^OMtA_q3in!fZ;P}D&O9z~&j0*);f{$aHz^3Fu zwh=Gs1CfVz-TXv-HSwwv=5KzGZEno?CTgJ^t3n})g9r|;lRPHK=nBRz4t+h77; z>e?SW`Ay@NiG(yA>K8i=iYXw&10F*)81p`qc^?W@oIZzTbNE}t4LidMPQ&XPxV|1nHyiZFZV31mALnh?tqRYe(w{#C*gv&#CCmz9sGMUT}IKC{FCBgywfa)_YwfMciP)Ywjv3Fn~F?s}jN_Od9`VanoiM1kg;&R`+gvxI#~Q6`HM zl)DI)mWMI!Y=Af8&cZu@Y~MQTJ~i0MAe@`ErMDOp)7YU-7G%PGKjoioVHu}TxQL!| zl~W)QH_!@`ktZN1ESnEukB9Z89hu=Rqz)c+5`EOJ1q2h!6A1WePysx7PHsszVs)1}|<_P5E#P?|cbH=#zfDdcPQD)rCPVj&+@HEgC3!6uIMi;tLh-%o=H-v8JJbqnBi zuf$vcXT`7W96!!40|x-b3w&zdTUl!q`CO8FF?dIdu_y`U)=x zZM9^u8Z~urgI<^|H~FofD!hBn9XQ0;x{yQHcM@Uap6n?&WJG3e$SUkTf_U{jo(A-R zo&A++FY{2Ub9^g8c87Tlx#OQaIIX38Bh5m7((;G2D&g*!NUgi_ttWsExxgEkx>~BE zd}jCwkFsw5^@zkiCyB ze{XVxBY{pGP2z!S&hryFCvs)!j0;{%++q+f9bVfwQAF# ziQld%@A^(JpE~~BZs>1k(BFE~4FVPJuazq<>FuWF^_ysU%YIp+^gr1hJ2D#dQ-5=? z-}-)uuaj099tDD@Ut)7}Wheq2)KQq`eT;!PX}v>(lY**Lg#0WbV>MsjLRmzfp*{D& z0Vk;|H5zMw1%?~$3uK)FV-qTjD|0Gqv}M(OpY_yz4Hk@ic85-Yzf&zO8*!i2dHls? z8HZ&Qcv!q!xnMt8>x!-|4A|=%`-q|U+m6dS6CeJu4YqcQtlK4(LptgmjAdZvxmxz7 z*_PlYA1=pBZ24uKPvu-T&6hNKbx&CXf?0*$d`7M=+KtTK)yyEA60|hB9?}Y+HIhhm zJMk3La}APX`g-*%9i4e}5wTtKLRKZ3#ROBo)OICn74r#Vv=GK>G)#_laCtF*aJW5& zlA51O9QSYJ%nV^O`(#h60u=kZx`i)!^Q({>_8TY8^wzvP$2iSTVjX=%iU*K$Q8P157Wnrai+F81O=B6eP zZcgaCSK^X6TO}nkzth>>q95;Ar*E+txR&DM zEW(#G)V?QHDmKILiklz}S`yNskbEfiYc5ftVWXkw%5q>my9e{7VOr7uOr{HTJ4nq| z%h4L|GJPumB(t6c$PTN!(`X0Yq0x-=H>SU)OZSLVpmb$vFbZYjrrrTDKsIY>6>5<% zkQM)DUP5RbH3+iDgm;Z}opeGm=xl!`v{D2U%grjXJK>5j4hS_$yw)>L@MmXPLA}pj z-xx>!b^3B!6>S!&M*wppVC{&CCE_fTqP|6$-FjXJ+!V!`Cv%HWb+WT6q*U?^k9c;wUJAW!UCV!Jb+acJLs!=$QAzl8QIhJ&-p$J>$)|9M@jj{$lyVo5zYCy$z5 zEP}}nrf%;rJTMuMBKyavK$ho+{+K)-mX@$FaFr2FLxm4Zb2E)e&u5n( zoK)zDjr(N!BarFJa}&h-;a#hfp)EPND==k zwkTA(Y!WAZ-N{k>JIVnE_xjNu2e`gNb(BWn$ib3(EvfnJ{Aczpt!$@U0qDijYIpWE zJ3Bi&k7qK_U zqSp~#;Vk3EzDclnx!vGRX~36-NntH^ykIS9)?U9!=?I4t$D0ug>m+l2HVJk+&`E~K z+XP;9=GE>0uzN{}uH(j+LBU&p<3ak=Z}Jjj?q!E9|D~SW5eZximK< zb}>0tjIDHN;kVOdS2!r5)y@w%ZVCbAbO!3Dxj>DakgvT2=xpDWjoc?#H&O!-m3*z1 z&&XwuSjks*vLhAy6Gf3Q4#_as;7*NP`g}EkTsuk8Ce=dH|95T4_%zW<$w_0>F%7re zi1ofD*jJl5{fW7C95*gFu$v4U&VdolauYS)m~Db?)asWwGE$U`WoGsC%$kbC+9qp- z)*MN)mM=g&NUmkY0Xh=Gd{q#msgo078rI5T(hcL8fqsEmbJa=83VK~_gJf~*laSJ* z9}1X54c0AUvD^@sqVu(E$VA2I_WNtOS*h185;`M=k$z|r73Lg0s>cwZZ@VdquS7jj z3~g%Qw2wx^lYMGej-nF98~nr7slRcxePl+WHaAD|S%hSs%0}Ww{syyH@#i;YXY>T0 zNxB8{NUVXe;Y)sh03;p`%+ipmMT0myPt-9L=AG6SjPYiSKwi;xIGTHeud<^eq^j_9a^Bbw&l^9*K zk00XV*%WVmX)ze0w)hCKdxf16nd?L_{v!AGxps|?T%V4nQXMPFZ^d~yujTbrT`s#)C2^UinE61Et%InjXr+mPL(!W*ZmxjhT#qn;1g zqdG7SPILn?_skFmi=w%qMHg-;@4{YHb5lgK5iK+slb!Z?quatZuh15Cy+$;E9HIto zPzSDH@pmp;z#6!Rehg=cTM}n@RX9mn5p$zV33dxW}J3_T~~FPC+#m+8aEJ)ltxFtr$YijDx$hs2* zjM(*n*nk8Fw>USECIA{)TW6*#LL+kT)Zmg@CfFT|51wo`fm~+6&mym5)YxkLgDJY6}totu)};C9OliIVeTK@4S~(${xSMsg8&Tb zZ4eIx=Lly|im=Frw@udv!CyS(ZRNc~%0rBC9L32(E-yeLg$b+DDWt^P{3~;){EVV4 zGJ`Zx@Utq#t9qgMsLrUURP}3Ip14j*DqsFt$?(}2;5VX{Z)GJtQ)6>69;U>ao>e?- z&`PNsG~T^)7IGV0_WG}iqshLms#q4FZUcAe0g-jh)=PZlgX&@Dc6B|8o^mhK=nHmr zrN@0bGwR*uP9b!m5WYN(bG}m$M1_(RZ&RXtL`8$dZ>DGpskdyA;`8oxa=P8>fLmZU z^b6Y1^CWLYhK(<19bRNPg8cUD?3VR!STahK^4atPO`(g%p*cuEAaNlp7xXdVzrfNR za}kH{l34vVCJ=({#?4Nl>e!fz5|zM;M|Dt=1a?+?K3BQ5TCXk(ViCUjF!YJ1<0qt1 z43Ah8r>Z_P2`yaN&*Wha_NAO4cS;PwVv>WJC_J81eD)hLPb_MyUqa@2j*tDZsEw^Ljz@WhPTLM@X!@tQ=nzcBs4nwaEOG+W$+$a~KEdtZfm`m40J! z;8g*c1jIvH)xiTt^QU+L880GRQ_X_+#CBe1Dv_%#l5YvO=>UN41yk3CSmoJh9M;|( z9~|U#T50L_(^dA0{*)QPVvT0Uexj{RJ=O|Z8=dPT8lsi#H(oIC0j+;WxwxUIt@2{i zo?L!ScVDWuN2hzN*pO2_YNOLYyoj|j3GtE8nP!r7mGdYGTs)&Me$TikXsO>lza>sb z*ID?3s0d_xBEoqmaj5t*!y+sFIal{P11XdmK+JcwgeQ2FT6?Ku$-c37;)QUb z>obk5+d8DcSUKe+U=2|?*^=?++`-ns%Dc$b#9jibi}d!5VOm%sKatOz5it*p|FffNTeggHO_z#abK zhiD?1w~njznr-q?B1olKO87Fb%Q*;u^Va;m%3L2(wujcrAaf?&kwIdzYv&F0E{ewG zB(7;aA7pw6K$Y=U97GO6Bq=iUxcS^~KA#tLy<9z)uCm%#3`qoqu$;vBtJ)9JgXigz z1izIxP(Yuaky_JgLb32jDR`M0RtYo0dNn?)13C8^tm{B~UK~(2nE6pcRo=g? zVYre36^?VO$`3ml_Aoecjx>$y{>B2j*#nU8PRMoYWJFn6j>mC9E`EMjFRMvBG~+;J z%Nl+Nlm`k7dzc0670W8F@au-fRc%k9iY@&cs{In)b?EIHjd7MGULEa@!qHIfIGUF1 z(H1ikeQMn520W2U`yGvBsdA%*qG1Rd&Dea>9w2SZ8!9EFhxe|5WS8F^`hKEhU61zJ z?l#3Vkj!VsQ6JUeRUCwt2ANxbfe!uHo8S=o%9P5LPOF$sp2%)K-lv;sxSNDnR(47_ zw)ym;UW?E7{kY!b~E9B!uVyP%Aq z`~FIT@~iV`LOIhu(+3V5!I2Mo#eSIYxaHlzxRP8HUel~+@!gxlhB=pSfDzq3p9rn- zM~FIhhES)|02<}e+m4zbkJ)z(+Q&aicab<5@eNq}0Kma@2?0?EZXl1~2Ws42ph-P5 z4A{>h=w}DeYB{Ls+u%POiIJ|1YEa0$DqcbSzYUpJ$YxEx)jNkVP;Yuqk#_Oe11Zr) zH1U%+?F0>ECVvqCvX$X}yTn+PNZTKNM!YqCY4=i(OrUKxm4>ZDeOJ`EmBlz2hhPR9hhCDf3M>T$mbV@GY~2I$EAK+;5wozh-r?WmPd6eW&QQDT zkhC`Z%zCIkkNyH-OrST~xbWe~c1P}_{OJ1o6rbUp_HN0bM{sZ@(++GRWV1H?(53^^ zZTd$x{TkC`KOEZ+7v*bCXP?Mz!gNCFGhE{54ydK7`VG>dm?IzF>4)$2!`YdBIzP8h z{CI^&VW-6n<=aSoq6}t_Zq#xP1)zocPqYa#UVMx3zBo;xvVcS7a5$I@%#j?1x*Gwf|Ml`Czgk^%U^NFGjq+hh+% zW57of?pVQZ8-_$bC=afYrmez+Jwg@F2qJL@B`ahAJn zbQa0q^GLmCI)NUZF~!9|ar8B!3z5KuCO$CP)gOpX_+R`_>xxKxaY0!WjVoo`XPe^s zUKj3*&2bPW?rK~*bgR+^*1#>GO2@husa^9^HAV-Sami+J2x;coQP8jFtCCc?fyepL z-}2YFO!)Q>U%>9BZZt@}S3lyt8viJAJhyMnedAMAq}~n=LfoGTCn)v^3t^`DsspeH zLkxT5q$Y9-w^o8XL~DsDFzx4*s(2Ntx5LB!_CLOB`#S)OFvR`a{}Ea%nU|A?D(M(W zU|Vboj^`YjR;4`WQ8e?zR~1EB%_H|%fb^Mhp75O8ZAL_vxG205NVg?8qx62^jb1>s zjH~vo-a#Los3B3>1%+ri)%6)x00V#X3NBQ>)eefBU>lpnYvI3~#_jF-6{YSr>!^uz z^g?w7jc~Z!RtKBIeN_n9VVh4WhCTYaG4tSeafI3J(1zIp+`Jpy&A3;+Ls}QLU#n!rzjqeLh--@zAylqO4G(sKq!B7LE5Y zj3vH85J5cBW$iVNwYyVS#T*cA=pDV}Sz&7I_h$MmkomSjn?lw8;PJNFlZ|vzY~1E^ zOB$sCEq$RXUwghkK&1PgTv0vXa=2m51bgABw9opKUbLfme$ig|)!UbObEO`C_w4Jh zqEu3r2d!=dm{Ne1LcG+uPTIe;_0gYN{_b_TkON7V{9bO34Z!Wx{`C1pp3+la;@cTN z@+4sVRIo&66^{f=7+Y@KDBoH1DS6GK(>R^(1CqM3{$^FEBX``i_Wh2>7UeZ>;6+U` zl-xeYhN^d?bus|UimXBM&|p1M+DCL)Hff;`I}mh@AMc~rD8iJW5gpkpAh-6r*UJ*p z36pe1WIudrc&aQU6W`MbzGO-cjh_69qic0}K|y-80iPeeO0k*e4rExE_#H#fCqD3j z66O$16$OgeH)wDSJ@mykjep%BAdG_?DFo!c07Uz;sEqr<$HX>zemK#HiJYWQq`6k= zZ|eV0g04jP?NHUR*h|+&A=;lY+e#I3Y?Vt>GYtUos*kORB98ieu$R}+x!|r23-i+U zlB^-0DvDcWkQS0MFN*bqV=+Sqdp4qJ$KOvsJ^aforoW@ZPky*J`)HaU{&Pm}_*F^C zp z!LS%*Q!FL7sXn$%VufRTC|XTNkc8q-_pJ79T<~XY?~@Mc?cF<0Yh90fYqc&K3K_Fp zQ{Vh_^tV`1nwNv(Tdv> zJ`dRE?A&>Y?K7V23tH>EOc-Gt)tF&n#nXm7&?b|(GUxFD|IM=OA z+~qZfU}SV4)hhK+Xl&wFSwF)e1$Lj`DE)3rBB>)!n-=nfX>PC+w9WI*M3QRl$6-3# zgT!1(Ni|cK-M9Sx0(0fshscc%M$z5}u7I-gZ+9fZ+(?1bQfy5P5@0+-+spAfSfPacw6Ehd>2I4E-&Fc^b{y=lgWQ1Cfc8I!@b zkH3F$ad7Wgilm#DmrIU4MKZ76b-xlRmtzm!iIQam#JHO zzWA657-KW`^B-_++jUEg;eK`CXA752dbQ8(4szS? zE?#h`4;RH3C5@m=bpnCk%GCz$pSD6}Ww{luwQ`U;fg`EeCGgX)b;dh{GiZ0(Sm>tJ z#>6%oS#NE?FTaD_%CNqhW`$`Mx(eLoRd&G91#37S6pG&od2gb#d(gD}jN;TV*)yht&$2z8BvzCr7e5DjUTj_1w zsWKQxu<^$lDA_fRG9liLXhbO-Y&8MiZS4mgJqY)ezQ69a;ZEz0RR&q^X{xC8a*Bkexg_-aeYPIBUVtjww2h=SU2koWUFbTPYoA zFeW9Rut<`^S!$hyw{3kY2d`qy@#r%;iYaVGR;xAtPSwlPl`916vHxSt#9iJj{DzHYkb^+ zzlm238vrPefOjS`#aPVcnyxOxNZ@FQk`1u`;;!9~1zm!Jt==Ofw``hbpxJ=i?oDe^-(du&ObN1Q$2k&b1FdZ)p`$Se(Yv8su=C| zB>cm!h?S%KP^43ie!=;1%+%KHAGbh>ZJNVeTIUB%-fHZBWsUtAe-$FA(i?UqQSCJF z_iGe$$r@hmVdx*+`z)2$egGQAy1cW8P958?Ov?6FBBdv&hiBbzL3N?S~A;PjQYC&aX3u zXrWL2IF|bsE-qF~mR@|f9Iiz&s4^UTpZ%V$`6IdC!u~*`!D-N0(JK4ObCK4+U{-py z*lvbhO_B3Ke%UK5^6Q5EBrR!0`bl z7$Q=$WuLg}19q~z;)Gpu>vK@MXVLQ906kLMzc+1Wm>M}QMSw-+wkt#}FL#Nl$M=}? zrrqnJq->~J`NJ`H_Gk(`A2#}Oi>k3=R8aYn$tORQmu&k{6}UI1jUbeaVZ*xcztq## zyCa(HIo)`+;KOKAaW-VCV35OcmZH?8-7M=;rYWarqG#GEV2!H?lwdCYC7v-O|yFI zp^axU_(x^lu-k2t%BX!K@AMO>qPa49Hw$9<&Nr191WHM^tr$YC9r&@?)x4J}lK-O2&;j?i8_;4)6=7HOKEZYC5( zzf{zgliG+S+^7y@Q>A|f%$&Vfw7i+ zG&ttX8w9tnn$62^ zq3U=zvJfSvMk%jV_{9j?qo1~kg)Xi`>~?Bo8+7ad{lvX4g0$U0RtPBpbj7~-#?9Sy zr$+BB0TNrXHv7xzpB={&PFVu{N4?o4<1M>F z4@G_NEoxkNBWMCKZen$eUaqY-9zH@TX*!4LIEp)aKN1)OGvbkXi=Ur1WGnNa+J+oDYM#j zvBq@R)v{NBI_7KYzSWg%SzPJ{5vBVU7E1H)ofnLSu5XF3SIH>5yCuO3Z2Er*2;kAv zUc?IkWIAeg$v%LAu5-aYz6MJb-*@U%-@V704D>I$_dkqotdMMLyrCY3iYw{z06|@g zHlLN(P&WLF^kv&SOGEzyyWl`mJF?%btI-m?y5a=7!1^V%{0r(1`?-ff_Vrb1#>8_*u{_P2`A&kxLg8!{a1!4X0v$}m=c_iE;BIr4ZruWACoUj%6l>BOKFi5}RnQ zn7EE_95C;}(Az$cMDN-i(S&Mgl6G}=!dcaAQ@F7<{GPl4+I7vZTh!DF<`ijSE~ zgHW*-wOy*vhv|MI)EtvP$9|8!9PUa`D%k%=%VF$@*26pihMRHp`~jW#bVMhuLa!{- z)EsMkc{GyMtDBG@tsQ%UkAx`|3)Dh{N|o`4@^rMF?v>Yc_v?Y%eLt#80bK*kPFG*v zhIY1TvNfH;zLoL&JNlQW!SEINR^Lf(V@Vo~h6b9wU1u3fju##m&1?K_QRnzjom4uW zQq1lt)P{-1Mqcl1w768=Lj|YSh*>9bVPAwRe@#-|p>TCMhbYkFBlB+W{eM2Scj~^D zQ|`WY)Fl*BY_=j$a1~0ml#nXJh}6N|_&agWnp7}!lnl}b+a2A70ZMB0paoFE=o?Rk z<)){M?AtorOC>DE>{3Uz*k!^CwwDzP&0GU8NC4zHT#n_ z;{RdMDqINHBhh*ihY?%`zbk_wzIGr&q5VH4T0!VNMLV}zwTl_f6%uMt?L+DG3QdX?p*9zR<0SnyP&AT%GQpt zAlIbiL?oYM%;{BoP1bL3n?gMj7fX*;o$|J*A8Aj+b+wV-E|%+;3tgswJ*Ua1GRTqj zQ%!gwKUt}WMCy65%ylbY!B4w-BzZZj6FM!DN|s+&3$`B6`9k%URTG(~Vs)9%i|t?# z3jLKTQL!{vz1-w;NKRJhE!P_Te7Rb3Wl>|QSyd1J31^Qy-djqK&i40V%3@2kq+EF4`iy7q(IGNCKC zDqFE?aVu&qNS*%RA$2*m=KHqw%M z%$JG;mcw+nA?lmPlCD4s&%o0Vj~Y?Et1P59SX%XHwyG#|(17|#YOvXDtZDVMNQ^T? zzILLE;9`@g+Y>{x$gzPF^6fqA!i1@6Osy)azj87bn|E-lp?1*Z$+L_d1V#C;DJDpS z!tx|;+XY^0BiJ~%QgCirWS%+@Dt3C0C89m@Zp6Ck`CPIsgjp zILHhS6A?@~zT{m!5o9sx)~0&{`y>`D{{$7Dmq9R@E;l~tL#WVp&xjI3eFX9w7Q2yJvNAmFh4@r_Exx3XJ>Sp{Rc63j zZ1^CHV9wAJ;5MCfh)3tancT?VOueV^%@I4Tr*$uG4k>hH2CsBX98MCqj}#BA5z<%a;2GYMG&W6wX{%#AhfR;& zTP#x6uwXaazaiE2NqcXI5bj=!|ez&E?*B*|PQp`0+D9QQR z*LokA9~{ty`SJIM-@UlFeXzNA{7Smf_24_%%JoyL&->c^zNPd^hhO2ZGq1z^h+WL41JdFx@<8v2>cSO7F|LM%H}K1 zfaS}(`$kKJvoFP^vdX;3z7Z|`xXgdYhVjs5xz67JxikMAhxA7y@hX$%72jnzwTfrr zZ)9cs-4W&?`Y~UTnZ9pI_3NYj=4SDhu}w@1><$-ZlbLBt%i`!FZ}Nm@T7u%G36~lf0Di?OL#2Rf;i}!qWQEXOsME}HdS@a#B*Bm zZ!)gsM_TWn$>(cgc-|@}NW(8;y1r}?wZ{1L{{x-&=)Q+yJfDmaSPTmX%2nj-(u(eF zh_a2Kg~c=FZ^iyKJJyI?I-LJ0Xkro0KBrH}jUB#|k7={bk~JGa)85MPxj$Dz-<0qL ziJ7cMPnKA=0Tj%7VCDu0fO6(D5g3p1KMC7eLFVasLVgrTmLyGw#kgQ3bopPMedf$1{GtW`jgzv0u~~WnoYZD zp#9y%;NbAyNoqH%hOd^0x!1bG*{dp6-;#r9`r<|X;>EMsN0aCPA7obXDYL24XK8#P zqVg5%MmJ`M|5R*e0FG$0AF#;|_TZNcZXGvx>?ahThu1d{$Mba_TIw(RXvQD@Q<#@{ zUHCAy2Vo0`9SnDTcUDq_Fc?8;YeI6Hr{(0Q(7Ys>y8Y0JK1 z89^Bqym^L4mVddXG+Ug76fNjIJ0q(0RNe zq-PDelR$IvQTeX^okT)|%J^WO@s)9N!@C~eJZkncGYlxYl$F#t#t#aqou4@@tmcSv z64ER(=gTw)(No|SM+GEvVC&|*Oh;hieJl4C?i zLN^a8Sb^l$bjOYlyk0vZsLY%u>J*_u?E(z_NnoqQDFYtX$R(%WD>8Zs~O0eIN9SJsu)mH|h=Hl;{&oDV2=ffMP0lPp?ux_MLi^Sa@5day};8BX!bDb6mt zC9ZE#yeZ*@hO(-38tkX$%hTn$Y6Lg4puM-9lfB|wqxa5t^MwJC9~pzDgzWZ++BfGc zB_KS?y=m6MtX$4=P4xZ8#5!C0aa!ZtpkpI~xk9(;G5c}s1$!!JsR6UEu*QM9xa>Unm9C3=gH2*-=%MP9>@Ejq5SOn$iL1zR6Wfa)v2M>OU_6{=lrFXrdf02n296y!X% zz}v;n0?1uE)D6F}i2DGXSV-IA{`zMoy~dTD&DV;!?yki|QfjeQV2H;! z&g*$u9@=Z7LrRt9^K5;@pDk<89eYkvVR700`i=Rx$Zl?Eaags{X{%hQ}A0vrGZZ# z^ZuobTzYb1Ql3*B&=WLAh6Yv1$npToF1zJRrqpInPr>KP_}Z+lbNd5f5Hn&x42cLK zxr2)+&i3XePXl=lPmI3~>|aC=LUp(WT|*|^{h-kDrc)-|EaZ$)psYVgKV%o^NPJ}QxH@m?Y&mv)AwO9JbUjD{^_zZCx}k%OBqSomYtglwktN2Mcn zxbQ!vi+Ed!x>5(LE>YK=yEsuZuZo6RUC;B%5|*A&(KJhOB5TqodmWhPC`wrxK1J|~ znRd@@OPwS}bjhZ@$m@R8@d<3&sY+9&ukO4JkUNesB4VuY|Nrw=^eNry*sOwLU{grf(X_^F}1_ zu#gY(q+6ROJSd@vdBTIf93(kDF|F$i{RLkafukv_$Y>p86-mkj_|p1I@{1&W&Bf~j zXf_|WWaP*4I50r692>H*0o&|2C{cuzHIl$@Q-%C_(8%v7y6SFK(k8mp5`8>N_{S>B zlO6?~!ECRUKIKsM0pXlId$`{!-5!cIiazOV7C<6~C5mgnBLlHh*TG4*wv(RPFzCp5 z5Udh#WB?7_Z@ouVa*xu}o93CGbJtyso@#tH^WTz4OB|9qFDhXCb$%0Xzv%e>MSXBA zBKO3HlzT|hf%8^YB6g}hvydY>)ogi)iBj|BM1NtieUvWwoI`xSf6^H-rn+5(kh?$o z31{DI@~qly>`tSWmzc}n=aibOmADo!mlto-M!><;O))QVekg^5_^G!HaM5%^U-JbJ z77$nAnky1%g{u3R8=EAu8bEY;6toW0tsGO_{vum%;m?)o`V2BGGW28HtcrnITGS36}} zZ=B(2b3Ua(Zwx`TwzgL8H3rHiZmJ35tDTM+6Ci7!XHBz=+dg5HwjCd;j$OKOr{qV- zo{g=C^~Q1>pne{^qUJ%79s2BY0FHd5S0PnbbAI~hv7%cPFi$bu$65)sBJI#5{>o>%$TJ*0}c+tp4Vs0TPMtD$3t!?I*q z_Q~mF9RuhY!pcnYX*J`jprR$_{kd26|QJ~S)j`~5IC8~kskW&5r4HyapN9CE46ZI zp$HaQ6;kc>3*O{XEnQb+*B5IB7xiU(c?K8eyp`)oFxQoz>md76}LUxun>GI47tGE-M{? zZir`J24la1bohV@AY%)-;W*D*l(DVOV3|FVx2MzS>p3)X2E^L}++ZP*h%H!Wntq^@!z~qqkXb$dZ{ZWmfY+TW}O-IQ(=cGM6Qi5+IF5 z+ptEGA{hjOtJ&Z~ODqYf5DhN_qhTQx8fQK;Aj4~hGacyMhf#veowYXZmg}z9 z|E%F3X4L(mF6&>H74pT6=AS>qpPS-Y@sD)@elP8)jI-lk^vGr1>4Vcst3|d_d)NI) zE-F_P9$c0W@31UEkndyti6Y{F#3GYAaAZFb z#6j9F)WjN&%lfPQt9T7kwu9ut!_-~o7VKp`;}{kpK6_0J+#|Q)uRjomz1|1I1kLiB zk&jewQT%OveFJurBZ$H3;S27eqDK1uS@V?v3l@MRwLeFiR6Ek7br#S~ zQ2Qa%UduN4w7V-=`73q;@XPKUyXXSfYM`x&QoXf{G}+oTD;XgI(Y>-Vtx(Qgs3!`& z0(rm>`O>6~f4-z{`Kkh&pb+Y>CR%9hk$Ww8s`>>_a=P+Bm$f6$eI!$sh~#bj&v{sl z6tq#>UL{!M%1BkpXF~C`#y=5 z<2G_-dhge$lW?PaRRT23@GMw@a+ojWFn70e;vdkyOCBqyg_lRP2$hU(C8rw9DYC9S zOiY|h$1H0thRNcntxbXqj=qVH)P0!nlMa?YgG^E+vFjx$E?zScz-WNPDY@`{Z{h4m zwnrbo|E|4s6qHpHFy?J<@m0-+LGwSS2fGm6Rl;#(JC9~^oYwnOueBy#c_xXLsPW+P4jWLd zwL@xhL$qw#PcfD!b}X5$C?z}x<%}>WAP1_v0f$E?qfhCFdjo z9y;O0Muw5t#cw~{kL)Di^H?)tf53N&3u@8z0RfKCvg~2Hp3M z;j050HT+=|!e@OCC$>AFBmW8eKuGY+X(n321@QFyD_h?LL9BZBioW z>dS*=%yR-2G>ME-A+ei zyn0#ROx)vTk+0CbbUpkqcYQCGpy6neNSMX^5YbXdK(u%GO~(tNZRK$9ws z6=X}-4P0OE(k9!hXOre%bb86Yh%N^4nZ&kt)sb`40s<+`?~HmurEc6dLbDc~UB~nD zdoDYp)r8|jLy|oPk+sv_&N?+vX2LvTF8WLdc zbqyI@<1s!%O1GQoI^9Nvivx5bs7dXru{F5XX4?zXB%e6!-`<+#r=USjO>m9(%R!$*!+#QuRG+UKC-e^A-K18KtG>X73ST6F|J zB?b_eJ+hwVfa*)%WE&~2@YpNam^a&N$pT-o4tnXk2dc$d35CXuw&#|Hp_m5Oz&m!h zMeT{U>9_$;Zq=PbY4zLrH)-jN|E#4`esG{34iBT$ugbqI_dcR;dCT?AQag|+p)6ru z(2dnf`iEzSZ=DddQt^|L<*0#C{P}17VpRSr}OtsK}*dkNm-wD01cGtrSwI=g2g2$3WOJTDfI6_(|lR zr@u9gg7KLKLoMk#ZEd2KBg>IF;dw8^%vMfN?3c{u(jb(eiSp^^%%rM3ER^CL{FJE_ z_0=9HIg5SG+;0iZj^9PjtX(c;H4Qr3N@j)p6}fZd@_c>|yVO+8Y>OOC%GgW@#aR_5_7jPjRt06D1j1zlS@ZB9Wu0cAQ#-^Wce(v=cu2ZM@;707W>O?W z`kny`+MNuScLoF=lS3DVsK3j*xebHlZU(F=J+3W zq(Sw4-RN8ZgnQy=`X9_nwH&Z?WUw2_97WXt1+ZW5)(IT;1-xb0g-yGaOyJ#0Sn8fG zTk%(=R!raGHx1W%(ERG@0P3Wc8L`$Ah`s&V4otWmcBp){6N|*I#lTJm8zJxRK;>1_ zh{At>3-nR%{W&^C$~5F=_%T>&_cHy1>v6d3H-=L;Vd54Sl7b;xiOmHW5AIyW6_#zB|>k;DpwNu zJy5nUNAx3T%g3{0B;(k`IDq$vIA2s!TJ?EoA(6^FU{E4Vt6`JSZrzbxyTs&P9% zFg}fr?o+mp(@0XB!RwMe#V;#a{*yHNTK4rmx>H`z3b;Rj9O-^Dcv%eAHEJ&_^hH|d z4cJ=_7d;uJ(S5RuxzC+mHUqxGllf~|875F=#)$JM4{+Q?#uXUSx2T|i+I9i+7`Q@} z`A$_xAf6M3Yyueraw^?`?EZ8 zz$ii{KYUCdUZPaxr+-4}*L3%R5*Bk$M;bwOGK~f2!|O}D5?vb*{TtlQH$X_5C>;2J z?REYm@?2<0Cv8Z9%rA9jOxPC$lSw4a03Z6?hGBvfin^%}T?BVOJaV$9_XkTtKHg7& zCYT4A>9Lc^@2T5Q0F~LFIN4|aX6{ORqo;xJUkOEGw;Vn8-iitkmq1+N6yil{y6b&6 zkWEUQw7eYuooD9pmF>0#z5od7#51-tx5r*P1^?k7_yTMzOZeeZNuTrWGT{_eSl^FR z!b4=Dao#6e@|9y}fq1!GVD5O-voaP=Iqs7 z3O6Q0ZZX@KToR9#00~QOTuhrusLR@!?~w{>jmh$8fA%{@ogQXR+_^4;NNEvDpz{Z` z>)tr1y|Owu*cr5TTd!pI!AbUAliy^pw$O4!!kPC64#X8Ry*ZHIG7)a&t1XRpX18@$ zu3?mJO;)rvtM4ibo8AXSjC0|8V^(5Uq}Pn8G736DMq*y;n;S0^6L8_{TBNLcK{(g@ z#DC>v8cl=0EtyWiGR0*?s;)8 zj136Lz;EldJ;|aC91gPUu6;m#rc>~G>%9#FhlE0^RT~U9Q(3^TRJ&HCNM;gj0L*r- zD!1x!fd`ooiIi8tL%tq;S>enRz?^jtw;iy}c@!^MQV4p>VCN(Ol3(m0eR^igHcy^|-&XwRnsp&zt%mVyu==WI{}3Ebzq zMM}qg6h=GNs0q>EDbUb41HvQW4atZ~LD4|yOC#N2`HOGPz(Vh*lVj} zX_XrAlwg4t>#j{u*wUQ-77kGal|!TnrKuwnY}q$pfohwqh{(dWr_Jd zd8@=*v9M}*;=b3dxWiJmmpz+(s`ECA{-T;$*^W`UeeJ-Az0Y=bk z7vS*diZ$Uz_h)si7^k|UL1Z3gb%#YLs>=36HdHci^ z33{nU($Y{%SVej3DilCVb$+O$B~Rn|!a5Y&m1;Sne|lYwYgH2`4xqKB+;FI35_9l~ zrX|5;^(2s%q}M>E_!aKkRFBblmbkDcUjw7>e`jF5I}DyQ%@B)-Id1?+v^bRD9_mfV z?XeZcHT!OOwjll0RLQRSk3Ra~eYTdQnQTJ+!lu@VjX+XCP!(fOrdJHF0 zx`!hsT>O@s%^SGOmHW+XlC(X_^e>B+v52)#h=3Dbl@#m zLW>if%)IX~In(I@+iZsrtk0 z%I!X);Za&-7*7X$i?MgFyZq;9A8bf-XkLV%lCzCLT%rD9t)$A!WH<^tO}#cV)of(e zn4~zE>J%=76K}Q4G$=%1S7=^CJ$@hmm4@U}p z5bL)lN-t+}iwIRj5;R4|S4`bd^(5Sfcae#?JeF}WqbI9gnI1T%-h=SF`nO}YKJ9T6 z{h(!lF(_Y&5miypTpiV#cU|jVDgrGJ0MSlIpmRx5 z7QdRcLs!uvP^M6pV555pf4(0>%?}0Tgt?G!C*Z_IdGQU1#Dj8z_lFyNWbuqxv%j|> zL*RK|nZ3NSG7)6WkM!gq@Hx%^4)NPfwT{{1@^Fh!OBV4ZTl2k`5jbykI;G1q<-usu zr87A!C|sXv4P((@%0zQ{A2^d>eojT4QOt*OCoUHN2%-?2_#yAM6l zWg=ugu2>hyp)}|ru%1&nnUts+K}Z;>pn2OlH65Qt)^dbC;SPh}`d0)!kDxJXi@@tYRa#<5?)l3$6XywVxSmDf!+Gwv<*yaD=XL<3RZv~O&o%5TV& zL$!hkllv6n!Ijl^?)s!gcQ5VK@FDPrn`BxXLrKFXl;{le=<+((X0ZU~efyb6P3At=e? zTj0GzmkDBmp>;$4>aLGd-#mnZs^K0q#3e$T9yqtG$7@4O9~0a%&EYdG4>#bBAk_W# z2Imy|`&8U{vd0hOj^YWgZw;$UV!kfF(vG{zc_?|@=*Q={b2NG9RpYIrVVq;(M>#`t zlCQ+w)QxPu)0>z2uU^x0*4x+orT51dXhJN-G4#51mp|Lf1_Jwt5C(VmHzcsa*1#Iq z_Za9#vyyo1_v@m)E36)AylIU2O-mYZBHrXfhy7JjFu%yZQli7!*0wE5g{f)=4hm++ z{4-V18Wbf?wGykS@S1YdLQ9`2W!@Rh=8*bhL5&rQN*gKCt+NCq6yi1b3{^iA_ip77 z1IUqWcdZop)v`8=Cy1YcEmRuhwh&aG9+$FCW2JCiTdSXQTa@ybQ&$pHo@I3t|0#@$ zvlMtoIOwJi-8KI}r`>4Lv4%3P9KJE^GLr|f*E)2R5n1wcHDDq$L|fT_ZFQ+cAK*Jd zX)TL5k`oANv>6wZp!nzOsYAQ?eOF`Xb!nC1b+_6|;iug0V2-qiBPtq4{I%gp8&#o= zHV{O9_12W-PufIKY(Bo|NZ=Y%0x3|4^&{<8|J2RTrg0qARBGPnXR7;UP23|%2Hl!c z3-wRhyY!|gH;5YAdZ!;*U)x$Hk{7>2P`p5MOKvEMp%-9yFeoClgTJ2?iQ!FNQsQOe zQsN!$D0xxvM`i5t=4UBW$cYnkgYE@S@nKmVxvz*RJ8ff|uj@N0MM>j@iR5_e$H1fb zS?XW1Ebrp1VoLvvN1$G&T2BRy>X*uNN-U~a&kn@Fk#-Q?&tN%h@3MNWIQEwnr!}-j zCteSa9|NN9J_Y63{U}f>_;NZ31^_oMRMF2m;^!Sf|0?hRTXpX&ysj;=h3Un`ku#ZUQ8FyPSL~X~41_6@NVxNoB*RO^-B35; za!p5&c6E6AFq_{X@TJ-XC+*o z{(#dL@Xs6a=X@jopKtVGsSo)Y|DT~=|4i`z`57wC=hqYc|MXcmIy+mvp?@~=|ItDp zM)Cj@eVE~4V>a^t%?7XJ&*sNdA(b&}9H6s5j#u71dWLh(|EuBfTHF7{p#Gxm%663q zg6OXZF^180-@%dS)dv%!CRgJFqPYrQM{yu5ZpgoTs!s0=xF;@5cTZJyPjzk6Q*~@= z{ZQy|0tr{1e{uT7c_B2|FsK>O*;O>4I4NV_!=oZYAkrkm``ys={k{Ev{N|%;`t;iV zm>|}`p9MImE8LTmkpVEYYfJydV#!9d2-^G$b|S_ftl|0Z_~-QZ7pIF8{h~j3d18pl zCEOCfSjO~EPsiu=7}w%_rC`i7&j-FL*X@pmi5IX5lkbXYZksj&Kp<;(w^|Ah_k-Y3 zL3FQhA({|B$0n2~W~C!X8e47NZx(2^( z{&i<**h*s2$O0Y_xuC;l{9DC!s_h5Lq|jzour(r$%T-hJ&MGB+P{VO5zjkZ|XipJ8 zk-&hE_sPFqYexm2s(22?>rQQ|gnlKlZFYlaUT~KUQq117yvHH&Gl>e~9(KlYUEL$^ zLH3qN|Is^p7EH)hIO2l(`RZ)IG(K@x1og{)sLQiwBdCOwuwsCkx4Sj8r4lwS=S0B$ z6c3-}w8k!Z1y_J#*hltyM|M&`Iol(G4mDi?D< zaTeZ=J_d{86-`Xxpa?5>kK-{BZYX*@uyLI1*teF#8hvogjY-qle z$AiP6d0KwOe2)5M9Bf#PpgWwnt z6xlw*h?=Y?rVUu-E5f$P#*hZV0VJt(eG~;@iPc$HIo`Z4$1I1_+a@1H+~!e~=7h4} znGGm(eKg}s7H*4z*_+hx@jS>yEAoc&i>U!EZ^os(V0wn-MQ#UoK8WCHm*`{vQ06!G zKBNm*X4fuGkv|>tA?BYlTxIvLk$2<^RVFPtw$Q=5_e}BP##vtW^>C^SIa4WH!;A|s zf_Z%7#1!r3jdW_k!{*xn|1bFDlk&-hW#WyMSkuASy94BXP*vk^B}JDwvpb2n{Td6*J6i(tad`&3 z(HlYY9`A*kQE61I_}Hw`Jz0&$2h8-Y)eX7lf?i=S zlAk37G#v%q>=T% zwbB%}-@jYyNWG&nSvM~HqKp<#Co8xlmmdu4MZVI36(tVx{X5OtOX5-~3o}U-?3rRi z10_)*Xz#BwTm9UKXGEF#s@r*LsW$qZgDw$iO8!s3ljCHp3rXjn0@ z`#sxW?PEx&3esN=#zBbE09Wa8-&Xl<06_mDa7@@nQv>Wy2Lmu8C%$_r-9VVzj5^GR zH7cpy89e^VX@dn2SLF8AB9P2@MWA63lLmy)1W6Oor@EwAXG3xdU1V)jqp#GLAvkl; zutvt^;Nyp2fS_%Je#R74HgoX?KGIvxCmx09R1GQ{;E4E z8YPHx2W#N(i3B||Qx$nu70=3Cn)X^Vc*YE*taj22M0lejQGK)IA0SlO)1oXs?;tYR}&h)8zWomgD`OWljK__&{|-a?|53m3JVVuvqu zhflNZ2%=jxnE$66*@ZXrkzpxpWNF?9E}ZA-P6Z#*hVG9wq-6oaZxzUQ8AgnE_aDV+ zLpU-G)-owqy`R85N$|y7SD59NwopmsAHEKusOoM9BIg0(m_m0F z8)tJ#%cbMHs60+h+@SbY&E~EFl*Gd2s?IY5X%11CNvZ9Y6ax)puwAyf6MpBb_wC&d z?<|9!>yv^Wz}UKMqjTb_!6-<4I(1RSL#boWP92Nm&XN%7EQm8Pxp+++O&+(ChwNO| zCf%h0fv?(N@>f~8w@Z+s;doaD4{yjCVKC+pL--GjcOm68MUd^)oN;W4fL`?2!yO

qntWI*D)^W~P0~MeeL_Gf}Sh&*}O_npz1_{-|V|AFky7`>Q3i|uw} z0T!nDHXyPi9I}fj%#X?VC9L)^f?qEt^UWW-EfJ(c?<_kP3T9^xPe)Qq{R*RnjLP<> zt0QJFy@Swz;mY;j!*KrPg$rj~B`-D?3A}5+1@Gq!^>+vKdij3$r`W^Rnm5jdyJPR_ z2>Cxfxr#~r(pL<=L=4idK!f;GVdCQaAng2_(}rOH{++hl9(K0}prhkfHkPpN*(3sd zb!^Udy0U)xMUqKCc5hFSep2E;aUv&RWyo|jZ1AtN*y!;#f`0Emz0Pp09=fF`FBI=o z1l+cOe?9wEt!|Ws>rT#sO)CfzWu@dopZy{8&_x7>?FcXLR8YQ69f#!dwR)C^mY{&C zKXA*J1xoxf7Nzv*?MYr5r%0s#&U zbQ!n9Exr)NN$~?lR|}rliQkWFXX&OyEVBR3^q#iSDcm;7HehB}cjUkHsw4k}vcpAl zk7-cA#))iHjNt7ADzGhJho!XD@9xM}*K~9P%C83Q`P?(u>JD5VS$6?Op+zaB0VlB! z(RI{58kaxT8|4ExGOaSIql$eXYs!K{#!;U5(6qyaeK8lGN4QbAI!}X%bWhg0-fW1i40U}-ueT25gxe~Ik+x5d(0aj|YjkSJu(LVxokZA~C6*r$ zKU`8k+8!jWB#506Xhnrc*r|hLl#pApK);#_N{`YRJA;=D4q#geR}yIZB+y!&BmvuJ zC@P7ZERAoe5*E(w5F2T2S&nr!*zo1l!K>4;z&pu22=cQq?s*ZjgkbWz)8!}F7FR|u z6jilo0%MBY6>*7G?oSEV(3A>I8EZ5A5@#Ni#5!hW{wkcIN8N(EVn-eDN=A`}GYK{t z-120PB-bcY502!)`sI#54+d*Y5k~Qtlk6{!%33g2gm0pgzHy#a*N4f7ONQp>i?ns* z(MKxm$Bw2o9+^#%>AP#k?UJ(BTr_Mu%Q(ZCs%zD=KB&lX+gVQ7(_78JJmSEV*l8Psgy~sg7BJ~Yg$)oM z)xZVfIkSLcSIQdYoj=SMtKPsx)4nkvJd8eJGX%x+el2gj+v{oH+;UaS_?W^K1y2tn zdEI&+ zAWDkYZn;PBGe(#|W$J8ccjX*&OqUoqW7&o)uFIC%H)X>wucg6*K3FjeCX*N~9Jz8-$tZVu zmcFH5zk#>6Xth{e-_{Ca>p`V2NGJU!bYvmpL0hpu66MPkdcb)ePEnJ-&TqPFh2dVZ z@FWP`2rddlg|F{~3nyDGbm2{S%fi}5>CsbGk4X)OTW#i>*)C+P0&~k2#sxrG;NCw& zbc=qc#c_l&9k6VyF{#8+>|b(u>nJ~a)p`|09ZC-WJwjfWvRk=6ID(?1y>tB4dHvVf zsLX#I-Z=0-#;&xtX&{LH6%--S3dA8H#20@^#VwAKl#07biB;Stc8Q%9WccsAd2cUo z6NFURGqaoZp0m3%+qYZ9hvf=cVzS$VHzwLw^rlyE& znf-*}}0KR9C!xu=RYttUJ6qC)jLxRbn%}V?Q>{a$L{%wGFY-`S&9l?pL0D zTt~KA#%(y7TW0N-vOga`eL1Gj`#E;PLA19v(7nJqn=cdbLK)|dhY|O63tiyVQ?p39 zDLDjSmx+Lk#rXL~@E)xNLMRGpSWJOOb+etk{X+6745_le3)O_;K*bI1`$x?Zv&}?X zaZ1cu*qsk0({d$5W&Mc#%{)S|Iz&l;Z-^4%W2GYE#c*y9lBuol7Z*v|6N1w^w+?}S z;PhFPGOyT$0o7{hNc@sXJtBS+2!b}s;DEKfPegb_MPDuLJdZSlfQy>8bM_l!4TK%< z#0m~4$v2PH5}}HUp4SQR)9X6W7K>;~MekrCov{MDj=3|KPt*nmgCK*0LWs>zV!f0> zip6mUkc^ZA%@ysUnsbCHU-Po)kB)5r=gmk*M>y5tnWrz`?2TVW2%}+YNltzLzZ-!XF|;iRwF^mfBjn|1Q&(g6KmIL8|B@lvGFo zB*xP|`p1@PQ4&PQLNB!|au3|VF%*UDys&>0GWy-FK_^k?UMU`zm_<4`={$9`$u19a_SDrKYQ-g67QKrE)Ky7?dl6SOZc|%L_iw z&{xw6hN4#Xq!Csnf5OX`j6iIrXs0vvo#vcx;8-aWniao&NB;>5QOd%5Z|!b4ew8I6 zQd%Kjc%0!9)+SpMnGMa;=2=GlFjn9n+z&iP^SuWN$GDMu7?^jJVn$X`Bl~d3p(`wr zVG6zaZlO^%U%%(3l}g5&AZ5~iT6QtWtpV#3blRNXTUU$uq1rqTdo??4R@=g=dJuNF z$1GAqOrPx$l&0omx?bizM{X*(eu_A7vf?3T-bF! z$8D>AyC(%|B-|HOO~MZ}Zo)-0XH_YRpB(s_Q4X63@j-g1Q*U*Y!-ZzgHYqbVwfRKl@aI${7^j5F!sZ#UD4Aqm8y@ zky5iAJl{=ofEsgWN6@1fDhEbO66(M&Fq2i#lwJh4X~+44Ge^vw2r7;j0+9jIbnWDq zFb!%odfxg|7965@E5BGnC(ARnYs6CwO{?da&nJ97<8#6%&oYzp|0Pd`LmB(P&cHE9 zpU!>`x`76f>O8h!+G=!fli>b9t)+%Q=kg0ajlJO9*@yCN=C)mZ%v&B+8-7bd+85Cn z`83s<-c3llIXPK~l1p#A?ixWSx+FQ8MTP?o>X9cbRLZpC0PGjI$GoX5ZNZfG4m!!! zQt=w(GZ-P8wO@h(@UrMXykkRtum|WPDP|XgSeQl6mzzP6&M`mtGi9odBE1CeAxT2Z z$7d9wqNB+E(KLuX(_;24(-{crVSO&aY=ur&hgegFc<#Uls|XGrwCEl2zs1;|IpyU^ z#Vt+i*8(Zup8tANC(9@nR7^g_X0M%gqytm=ju5XEu_BVEJ-`q85 z@{Jd_-}thtHBFvY0@^>i6|aK;9k0*aF+|hfyry&)0iQqjv(KOZTwB{N1kzcz@v3sf z4A)$c=3xLb`3>Zd3@^HZz?XtsT;aG!X>$K`XAm5QSe_MZ(+!RBQ`%>mz}@x-d46fk zK%{&?wEf<%e_hYYYWv&Wb@ea}1L0@>1q}#dnnKtkn2J5b5<@})gbJiIj07buJO7>U z?z|FQh8PdLw28;rKA+EL$No+nZasSRb1t{Gc}=ADdM5|60iliX?;l2tPSJ}X?kB&L zd~Yr*mD~vME70_4p8G&Em#3;P$W>BRuS!(6OUI>{QJ}K%RSQq!TX6HnMBrY_XTe$a zaLs~IJVG%h9WsJ__HfW4nsbOJd(h*_dMx6Dxj;OJ(A5!yYI~`pc}8b@*#&WmgS!$) zdv*ALdjBnE zna98W*Jw?-1;o?BDmOK7bKW zCrVJ~Re0a1>fW>s5|icQNbWa{8$zv*Bh z+-gd1JS$`s?!p8Yd-I|@-P#NMoxQ-{=+<2CoixgthvqtNLl|(`Lc3~FvW?a;r>sJ4 zi9983Kh@9NVftpj!(UUyQZMbf{UzA6Xz7;4qq_%`0zzg0Oj!Eb4%lt z@HU7^!R8#r0b_(%6Za@I512^Fe(WR*_a-iv24ofh$W5(z82d*wc2-Q*s zvKcv1uNR<^bm&k7y-r|xso<3`Q_X;1gRrN3CA_<*r)5SLU&?u@^HcPM+b;BX@PK)k z@e|ZVTAs39Bqzp_;GM;R4?f0hIzg zHkN%A#}f9flN%krpqI8FzI#h!kcw8etfJP&X~eB%;bFPz5Qzoji9{ptom=0@oho6&yFQx5NaPm(pTUl3}YRVU;3yQX04Weyxj8Uey?IcqO*u{!%JfhU6%-3U#`EXe)W;=Bk7jw6 zJb3URLG<*Xb}6VWg8*+PrAm!D*bocBV+X_2(uDS$muG5LrL`iIarQ-)i{d>kI+oQb zj8+t1X4IT=x;|Y)C4fJ((wH$qR$#tMN};mI=sZNDvkF?oYFBk)Uh^Qy5lxJAs4ms}nF?5`pJm@|!XW9iVXC47%! zB`@%-b@EVL9Lm6ZoEY`?MpPErKZyby?Hde2%q$Dc!ILznrRy6t=7hy+qr&4ck?HFa zvx2VKz5pgRzl60Ch4?sOhFAzQ+mf+M9oLYiYOUo%*LM|U?hF2R@V+lq9lTubK&G&gmYaSZV(eS^?vA@hJ!N{)| z93R9R!>x&7QwNc1sLN{QP@)Pq36I$%V20pQEcpLp(smx@g=JQRM{NmD*2JY~#9!po zpJNON5i;+1V#R7TzSxnL(N1dV{m+Vb&)Rvr7Z1LmZZ?84HfqLYoPiZP)U;yDJa1^- zBlCs&%=<;t>El8?QXmHN$r)Y!f$H@#KTUFx4{TReyie76MPmd*tca{}la^O8%~rX% zL+AdjaKvN(UkTyn{gRkq)~#j-w+TwORZtouD4oXOoy`J4na!Hh`EOM+E-cTRom?n& z0ZrT^DG9ZRF@aF8U``UAj>STtVF2p=FwYKpw-i_aq7$)4v?YB+gnmhIyu8(+_=FfR z=oML_=fyW&bCB^?uB2h_C|W&LfH<62r`+-@&)R8a23mExEh^E#6)_S^xEiRgTI;pl z;He5*b|2-|YX-{>ITi+?wAo={TQuXpXI+b@IP?6n$Z+{U0|BVvkbHVgSk zYaZfdjE}Mep|1??xC3!7jfO|v!FZfvT0qkxN}NhJ?R@a&`F*NUM&5lX!T!qyg96hS z80wEY`9Zp1TW!HUvaL(`r1(KjJ%sx6dwgpsNuh#Wa2Gc8+G93YquS)-bS+I>GUb8) zqpZrhqQwc_;ABf~PRVWTJB#>p;lM@*TrPrV-560?aVapB-txmB&4wre+r4xB&--&= ziLQ`^Upl;y)Vfu=Z071Ud~6}KkFt@EN~6=aN5%vuMDAWYK?wa4Nu!?@;~hQUCd2u8 z;7rKU|LhV8;9P$yNF<^H6qmIocycz+3Zpweu&G7>+#{FubKLN4!K~ z1bf_m!(0a~<2n%B_kbfhf=Eexb0XO4r>X4A#AP@>2ug9<*>eGv0Xn#O>z?!$Wp(M0kkxZsQ6u`W> z6Ids!j3YXUcxEE-s(SaGtB;N#(Z%tYkpi*GuVo8CEmLA&d|=Y%J_aV7Kd8c0Kw0%f zN7+$o@D@?|VFq#OE?NBhmP`e8_#j~#>L1(Tuhi!sQgcDI3yOWCoWsK>lJxzseyVqK z5d%`u#s9iP24Q(T>Ia+vs4du4(wE3lNF?LrV3_ez+k7f(WE_S3Fr%p)W-4TkgboNe zHH;TB!()PM{Bu<$kZ-M#Z_ zT88ShjOf2|sQ=3E>Axf>WQ(P1rsu2JfE^n)OZr%Xv3=E`X)~v*%~>SO$SoPSU7?@9h$cz@JK@q5@% zJ9L77Pl{{mge6XTG%zvo{ziR9?O+Q%fe|Di)fdRL@#k3)MUndwmE8_wBy=}=BTDyM z2AO4~tQp #ifdef USE_LittleFS - #define SPIFFS LITTLEFS - #include + #define HSTNM "ssw32-littlefs" + #define MYFS LITTLEFS + #include "LITTLEFS.h" + #elif defined(USE_FatFS) + #define HSTNM "ssw32-ffat" + #define MYFS FFat + #include "FFat.h" #else + #define MYFS SPIFFS #include + #define HSTNM "ssw32-spiffs" #endif #include #include @@ -53,8 +65,14 @@ Use latest ESP core lib (from Github) #elif defined(ESP8266) #ifdef USE_LittleFS #include - #define SPIFFS LittleFS + #define HSTNM "ssw8266-littlefs" + #define MYFS LittleFS #include + #elif defined(USE_FatFS) + #error "FatFS only on ESP32 for now!" + #else + #define HSTNM "ssw8266-spiffs" + #define MYFS SPIFFS #endif #include #include @@ -120,7 +138,7 @@ AsyncWebSocket ws("/ws"); const char* password = "MYROUTERPASSWD"; #endif -const char* hostName = "smartsw"; +const char* hostName = HSTNM; // RTC static timeval tv; @@ -532,7 +550,7 @@ void setup(){ Serial.printf("Temp set %+2.1f\n", ee.tempe); //FS - if (SPIFFS.begin()) { + if (MYFS.begin()) { Serial.print(F("FS mounted\n")); } else { Serial.print(F("FS mount failed\n")); @@ -551,19 +569,19 @@ void setup(){ #ifdef ESP32 #ifdef USE_AUTH_STAT - server.addHandler(new SPIFFSEditor(SPIFFS, http_username,http_password)); + server.addHandler(new SPIFFSEditor(MYFS, http_username,http_password)); #elif defined(USE_AUTH_COOKIE) - server.addHandler(new SPIFFSEditor(SPIFFS)).setFilter(myHandshake); + server.addHandler(new SPIFFSEditor(MYFS)).setFilter(myHandshake); #else - server.addHandler(new SPIFFSEditor(SPIFFS)); + server.addHandler(new SPIFFSEditor(MYFS)); #endif #elif defined(ESP8266) #ifdef USE_AUTH_STAT - server.addHandler(new SPIFFSEditor(http_username,http_password)); + server.addHandler(new SPIFFSEditor(http_username,http_password,MYFS)); #elif defined(USE_AUTH_COOKIE) - server.addHandler(new SPIFFSEditor()).setFilter(myHandshake); + server.addHandler(new SPIFFSEditor("","",MYFS)).setFilter(myHandshake); #else - server.addHandler(new SPIFFSEditor()); + server.addHandler(new SPIFFSEditor("","",MYFS)); #endif #endif @@ -668,13 +686,13 @@ void setup(){ // above paths need individual auth //////////////////////////////////////////////// #ifdef USE_AUTH_COOKIE - server.serveStatic("/", SPIFFS, "/").setDefaultFile("index.htm").setFilter(myHandshake); - server.serveStatic("/", SPIFFS, "/login/").setDefaultFile("index.htm"); + server.serveStatic("/", MYFS, "/").setDefaultFile("index.htm").setFilter(myHandshake); + server.serveStatic("/", MYFS, "/login/").setDefaultFile("index.htm"); #else #ifdef USE_AUTH_STAT - server.serveStatic("/", SPIFFS, "/").setDefaultFile("index.htm").setAuthentication(http_username,http_password); + server.serveStatic("/", MYFS, "/").setDefaultFile("index.htm").setAuthentication(http_username,http_password); #else - server.serveStatic("/", SPIFFS, "/").setDefaultFile("index.htm"); + server.serveStatic("/", MYFS, "/").setDefaultFile("index.htm"); #endif #endif @@ -694,7 +712,7 @@ void setup(){ ArduinoOTA.setHostname(hostName); ArduinoOTA.onStart([]() { Serial.print(F("OTA Started ...\n")); - SPIFFS.end(); // Clean FS + MYFS.end(); // Clean FS ws.textAll("Now,OTA"); // for all clients ws.enable(false); ws.closeAll(); diff --git a/examples/SmartSwitch/data/acefull.js.gz b/examples/SmartSwitch/data/acefull.js.gz index f795265513b69a806659da016f00ad4d78ec4b24..e88a884655abb64466041d0be61874b93598a18c 100644 GIT binary patch literal 117524 zcmV(xKri%LE{5s$wkyuli^W10{C?>%z)|&v@xJ?d8kzMt&RgKG4y+L_NQ#yEd`2N+w@!{EP z)H=N5gk#|_!E1VuLKQOYsA-%pU2nK0wzt*YTx65ZO`JyA%@%ix)Ce9qq#bVHMjs6Z ztC6KRf8>q9o?$g4!Bi!JU@4Q{J*btV1xDpc#_5&g-B&stRaHNn&yzcsWM-kfDrO>8 zxfi(OEX}h-_(IA|x=tjs`5a_Avn(nS(YX}ku*gNn2-LX=^YlyA2|I?F?|94-P!fuA zJ#T14UapwTv1$NX zS~qE3H;Sco-6+1&jWybwu=HxgTYRN$uUuCcG*+3#OOasaKsvenLyW;xW-241zRJ$b z{KsLExXR;Tah_?c&ViKS-9^bNg7;a-RjH3*@l81Fb_;_zF*2POX46b~ zCD!(KWzE(eGJjs=Q+MJmYciKhOd4aEw^+cSmrOP^V-=9Pj>FKls|C;lUPwl#hy(1yno?!0qvUB;KEyKO5QtmMLy={cUCCozn#&%nk1Ba2fF9V#xnsC3ovW*R4=E|gyiwY`lESE?oF3PTh; z!#p8d?!D{1^WXJ)jEGgx^WWa}F1plL_B!6uE`wUKysiuhXTf7#85$Oqamx$s4s!1v zP;1c|T-k1pDO+;Zq-X~e{63BX$qE?7N3Q!b+NYMN=EG^BdZHp z#tLtk@yTLQ_$4J)7n5f!5{Xcv(-3o+^Cs3}ky}0F%VFj=9G$oHu&1EF(xbZ$>b)es z>`mg^EQu~u4wFIz zwc~?!5ELmv`c)QzdlO)#dIp<~^mc=NdCSepD{=^Ng@ON5Z~n;{zkhl3>ZiAXqYH-} zA3O^j{5b6AqgT&Qem)DFvf_{nz7h&!Hk^unoF9kd5s~zX1_55iX>n^nhKa707NB1Jc}LfgO|q0{`|ZoC#_VN$8*Bl*bSPd>mFzO9Q|h z06Q%W(sCH!(IL+OIgZCN%d?5<9HmOgRH)A3?L5gOWLhk;$`u`-9n9xHWVv#@Z+U+N zJIKWgY%=A#xjzflc-}TP>J5MjV=kI)74*jp>b>O*8sMjMs zKml;2!9#TaGetewlO)1?&9q_2y8Py;?)qMgKV)3%E&D4@l8~?1c61+HXw>bMbmp*Q zYXKQGR;!Pl`-ubCL|48Z=GBg3P4vR7%Fp8R$5`>27IJ%ln692fv%>UNE<=xdHkH{- zY#i4yeGd#gjIJIShMtE89UPtVyfTf0D7zGZY0EGODI&BuY9JYq#jzq|b5=-@Ri2!6 zDx4#9_u|)Kw1{6%vs9qSqMolr4oN-u%2KDtXHc{VXLb-mIJ*VGd=`d{Ms10i8xcG=0UG_b93Y0>>-@F>J6SgecHR7s#!ui z{jz|geV)yDb-!7UBE>3-ggpuyghbi6&_~1=N>bvDxYZuq6|2ZbVONl65ou%`y7ZV_ z(!s9-Md(VG7-7Rt0s8e3Akd-#WG03++2G--3jhK?0@zTm7J%lwKg_=oHUQ1LU4v9` zO!z#%&~qLZ+uN}TFN;-p87~PhY|pnmAYIK5(S(3avxE znuJMP!cw%5r7N8#xJ#^@!Uu7egOU#thasFxWh7>DicfHl7z&Ef$4Qvy&M5SCg`7Qa zN~FAzDg#JtmOuryJA@?+1q(Fwv5q>;9nH@{7JRr0G$$!0IJGdn^jux=5Tv&BRc3oT z^mCyO6xQmpP=XAN&i1t>4zYF0WA=He^dCeR@%r?v!O+cnwKOmde+o=UMuW>G%D=mN z6JF7bU59!dIu!|}9A@#BthKhAL&(i`@ak;zP=||SHfF*L9ua@wl~U4U;e%&Kt3-kMUnzH=+uFW^P24q7%PM&c8cEfI@giMg7= zG|Zpn`7<)Zjgq^fve7PX80PT6l_c->uDnWm>)@5S&JgJ^iZ+pkH*2ufpv9uWh{Ni; zX>BP!Dr0SAOFY`n!=ZJObt%bfNqrl>`5#j(Mx2^u9U|Ib3myEBo%O=j`{ffA00JDjebXYRx4H?s7!9*sCpyWI;P z!3F1{JdC#bBtbl*<9UM+m<@~VeZWla5Gv{sZjj=$bs4N#!eJ5a%!Yu%p z#4=Z!y4Tb<1jwgCsMbcVVixzDt{xv82G5)XMq)j}VN;wzfmmLwA0i~Nwo%+rlH@X! zKgW@pu6en1T_e!ld+mpzmDJbV{2M*k8T9*KILrcPacYP<{rPPLo{IQts<^Y;Z-Ap1 zdo8@<&SjE~KiF7qBloOOLh86qn!!T^D_I_s;M@r>k&6U|!(v$W1e|st7cnCUc9)za z*$qO%IEq9Hn3aCl;BaEL$L4!bwJv6IHo!fj=Cay?=Ig_Wt12(ec5X zqmx%~&^7Rz(}P!MFHTO6&r0~w`{%EZxHNb8(Z_Q0rL>W_hO2)a--_fkggoE!f&VBl zZw)P_H3(SW_drzRMDaCtij@e-#?s)G4AYzv63b0Obz#YB~(;QD@IEyAs5 z5$};A1l3}!6Iv!eDA+&FC{i|%614GcoVG-<_bA-h5P^F7Jx<}rx(iVrFYB>AW@|{A z#zR`9+txq6yF=yw;?_>sUi~e>Y%am?k58T-y*N5NegEU(FK5C1;OoFSo5mC6u)*WN zd8TB7+LORJNC4X1-ACF|sL)|g2d4HCmV(x}KZfdYr2zH!Usgur}3Dv&_0_FWlQq*4+ zvw0Zx(Rged12mr4#x5F9ZDY@2ICyPqpIQUkdPJ>V+xnVXd$#qMTKl&3gj$bm>#4(V zobNfdeMos#U<^R(#egb%sO(Z@AC*0-JVJ%Ilg+#!#$+)sh$k7$3t~qae?gpf`=~sn z%76&=sisK}sJ2HnBEE0LGl&0xG6bfXbgJKt-Ye zl^g}AC={Slpa7L?6rgg00#t5MfXW@L162N^6-8&4N`QB00RZ<=(%2!D=;tVDG^4V_ zds^brw(e00Iey1Bp#?lgN$dCS9aVsEK_w8rBnIVxJ{Ww31A_dJz7A?PDg4GJ^%QSG z&eQh$0fiYT zw{trD~(iJo#kr0A;`6Gn$!Q;IPPAk#!(2AcsaC}%R@|!5&H}RWm7hPo^Q*&6) zvm1ApDSPo8raL=BPx#jP>JtkWq67j~xxCur<#vS&oh{4vUWny&@w0?3YY2S^?9>4} z13=;wap?}=z#dvXDHeN7rxTxLk$97>UAXOJ<8!e(Pi=az%Dz(2#m!iMf;{}QX()*x z#)Eug)gL@$#r3Bj^jPCa{x1o0+t~@Rjs+s;p^|s^twiMu}1jG=H6%}4$C!$|W z1)>-Z0M&KGrA(dPgf4N)^0XQmnUOZ%J$IG;I7vTdATkG0y0jc;Q9Ox-JX4rG7IPiw zIwxmzliAdR>jttb7*;I!6U`y_u^YZOAM3b#+l9yZp8blW?Bo3VuAz7WW4%q;_?(>5zbwB8z4;i)*Q7vG*UQLc(C2z@{wNPO1s& z*ZHtW)N85t$Lf2XC223Ny?bF!+fVH1PYlLu2j6+RG>xsTVzDq2Yr0GeZ8_PIWdYl+ zOzj%RoVTKX^A%GS?3zuBXt(`fWv^x|<9${PliHhSB(QU{yLx;)bypjq+6K){;IV42 zR6C`CQf)Z%5wd;0RJ-mAsAuAuOqldPSJ`tTuF00B;>K=XN_|Rh(k2}$2f@}}M%~3yC0mtStGo#DQVqqN{_|U2RqqxKK zo1iUht8_k7W3&qzmzpU_fFJOhBs-%FwEvx{{8jA}_y>QFTy(*fA~v z5ez+7p;Q2^b_AqsXL;MtDdTkp<2Hlw8Uq%WFCxc;_VZMT_WaU=FR4cLA3y^ZGf!qfhuCe2 z9~9Q#do;{%VtoMn5s||Ah2Am35m?vrljHZ#4`04Hc>nt7?cvK{B}j?<_N#QUsD!fM zUo?1V-cHs?;d`IMV4cCi_lFgI*D?Sd@2f`@2iLMN9n00M^*ljNudBX)wI&Qxzm0Pk zmM%GD{o&;F=+_gt@0afn-X5Ke+$MV!#z~uffAeaz2UM$JtquD*CeifWe3Qk|%Sq0% z+P0dL)HMfyCXA^+DtJGz?7kh0+@jlM#kc!9={xYe0KdcX06aQ03!Rxr8_952lxg9& zJE8aOqs3yaD(!z=YT5utp8ARsH0n|LhYxlp!UJAo3DNMz}GfzW!f z_`2Um#AX7IkgvG2312a!XTJB^edWAh5|8_?*<+E;MhJaiV}>4PZle{n2ljDCkC@_1 zS)eXg-_^1SOK`5-?*^53WVoR!86(?Ow)b&=EyBpOmc#ZJ82TL@(Y?pS#?J}J=<1@* zv4Bg@9Gde@4!aM6*8PqKLEocxm>92Xnw1;gF9DQPqV^NCm&0b1xqc_HN~x|mWJnkG zA=qT5KyI@Unz%GJA9CrBvT$KecJaAfz#Bsf(9! zVXst6aAOt|XJ4KJb$uq03-1WU61x5Z+l1_&Vw9h+7+r9;-l9F)9h9HY8|tf0d&vfU zu@)jS^(m1N<5mm2SlG2i%`PkIs}=QtT?<=4fSGA|4L-&E;hAZ4jh(|-uU#5t7KAwy zoS2aB+Cz9=d$%y%^{;RYgkH_mF{XsT6DwWXfOR1=K7i?^h$r4)ue1`yDTl*1RLTUd z^Oum>jxzpXXJ)AGINe#dThHj`n2jHWD&$;38S6n>PEkV2oRWe*!iA3a#%*v~pMWbF zGCP>K@;{HGM0`idI1!oWpe#KCs5u8~Z5zB=N5Zc)>5OVtUZ-}o7HBIyrzLA6N?38hOA~qUr735;X(5#4NCt(M&#L|6CUS>BtihjvejI*SerD&VVlEv%SFO&VyF)qKyxIi$29jIk_+e;(U zliD5$pU|)ppwWvWj>BZrc~Y?;$vEetYHe>@CbrMk(Nm2xoT{DpcoX_hlZr-yut3s0%mTXIxRwwH;+KgPI9IaQF%X&BIu%>jtgv{Z+@(t!e=`F8K2JL%jM3Nta%-QM2n9(#NHs&35}(Wi8j zLHH!cWPh?p%l+15GaEQ)Oabwef!z076Qs0|R06Q}!7*AMr0rgM1GH|QBcLa>Wfl;9 z`=9*r`-(_!jk@2-$8dnrjo6>?iukw=KK@JR+2R;sckS>^mxP05!rCJxQ7k)sBUAJ? z`g-oe?@Je6I?w=gskW%g8&Pu$2YJ~-ZX-$A>c;0p6_@LE-CX2&({!2VRFW2F08N8z;+AA!$Qo-!^aQKBE+=oBH7?DVJON=TjKPBh zSS_8xvLo{?a-QS-d7>eoX&+UmheYHz0-|Rtttblh2blBJmlO?sq$7WD)mYaJX*qP# zchY(?JRrQ+Ah;!|z`LwAPbI>g+(ysd2l!H=@V^HikeOYlQI*Y-|8$W;4{EZqEk^e_ zYCqON5PthXDOtWUAx%({5-G}A;8^}ea%-rCjc(`2a|VmGs{@K$6bl#_gA6Q+OxXKD zj|?__|R=-wv_C%KM@zd?Sq3I66qL<`R79`n*$d`g? zbQ_V=*$u5S(`s5Qu9W#Su(Ocx!E)g%RGAlw&gpo!d*;>XG2hM5e}Pv~B!eFvd2 zrw8$cEbcci6-(tY+Z7ud$)_*%3B>uSmWecxLb>SE0@j{X$MPHj-|t`Zd-1E?JDt&Q zx3A%fw0`yLYs5tV`a0P=7w}}e-H#k}6!{iF26oVqNsaJRYWwLYpMN!soYF{_-t$U7 z)1_Z~rTeP%i{6mCXZr*B>>P3QK{)gZYq9lhOHYff!=|na#xk%8L|)k^!y)g!7V2qW z#+$PrHWxu| zhs4(|QVmzJ8;_^)mXJe}#F1FJSHEpTo1G^jgalpI!Z z_eQw!m#oBBW8gJPYtT*To8D;K-5&Xcu+!tsPKCY;VkpmuAI9I1pZu|Gcqx8(Fu<-u z1SCtR%y*UIazhMC3SD9ef{9HPIYeQg(%N5azyB4i)5?4<=1#@I7oUr1dau_L7d2Mn zxV1!2tw1|U=LA;;u7U1KZ0n+ZdzgB7fj__GVkQD8m(Y_!UNm# z@Pu;5v+Oo)G;0imzuuP=j!N+(hEwk6P|?jLgR_e`1 z-#{>;rr+Sm{$@E|l~sWq;6l)uY#>ew1wkyK=g|F~>)Kf==9ZB=Yu@%!3)_y%1~VyX z$x-Mlg-QjmgsimXmXRV#Hf%B^bS5~^0BAYTI^9lC`j@oni_+YRU<7@~5EpzIQb8ajAW=pgN0Qec&@7FHF5vObqxV0+lo>R|lo zrzddANGaAfVgO8F-D>}k>dS7QAZ{@L2XCRP#jc93ae>!s^n)hj9s0#{Wm`1*v}wO8 z6Cck6=)G`om)p^Fw`lcfDRDOm5(8+CN*;T}*e1hr2k*++cfkgKr6ekh$19nhYY&W= z@^*=WL3Spz&ZnvlR&n5LdY;FC)ZVxj5PtEDN+XRK-3+KW|B)$0R=7imDC4xkF6ZoI zL$kmFYuT=W>4h?MRtek8<48N4dJf(OQNTMhj0>`x5=5$IY$P2@6BJP>u@gzpQNC2y z)hAZ&C(MZcE+^P~5d_I7X;n^E%VJuTCCGR`%w&Q1x_S0aZUw6rIHn=0kmJx!Ke55e z1tPIBXy7QENBXhcxsYxwH_zWWalI@0Ii;V!@xzRAcnQ92aL!;Odk$g{W{eO<)sTZ( z-_p+sz`?hBVvN5xX^$QC3FK)S<{T+Fhjz6829EZn>&^=zBRXdy(O^Pv4a1<>e*g%S zi>J)KAeXjq@Da5g2^umV$#mRmLNwFLw-h6K|66s;={8Pi0Fl6zM1w)$dSM(TgCq8s z)&9-5nH=Q^2$EGHl{vhY34F9(!_TeVCXI9kI(yeOr|`A*(^Y^Jf2rn2rg7t7D72d8z%2O?&e^K`Y?_ZqtQ`D?%AHPFBL12$INy) z^^ax6x-1!6yGWJI5)E!_jnvPED65X_;uE??D2&*NKhf3Y5#5Xk+Gx6SDs$$uK_LNg)8? z7^duGIa|aHu(IlBq9WloqjPUF@HhRbLp*;IKIoY#09)?q4Gmo&{xWsDS!qck1P!wVb>o=E zP(<+nqU@v-J*u5Px|(!IEb7$xY?&0VhgqnH4tfCH)((h*(M%&Al+;b;c9W@YW~!S@ zMByAz*ie?L-U+@hB!2LnMnszeKXeq-d?!8e7TTO|I&%|eD4wDAuq_6U8)7g|0+tyJaaeL#>3;Q2I_8rsv;r~mv;rk? zmYQ>4;4GtKe=}s>QA)Q}dL*zA>!VKXj32`qL!a!FJ!7Ot+Ch4vKNdB57*ZOPlO`m@ z*6~LC-n@mJnjLXIBB5pQBeW_byDKSw5c7&;fVpjsBa6p;B0p4~y2f4P2?=rfvf_34 zFqN94p8HS%zWPwvCZ5sB{rA!223} z!r%tc#lc~>Pt9$K!ee{V2q!=|@20RQi7EfjxS?A(I6W`+dmJdxT|i@jW4)%JCl=}^ zQi2!G@HfZb3V##)P4zI63CVCry1iQkpiS|J<7!4}nQzgNI>VI;q3(dBt{i-G!ns~Q zAJKf^KCk8*7nMPyKwK+}JlU8AE1_Q4b~Km>?4D(zy*~zX^NN`oOd$^Ztt4fM9av!p z77&!D;%r1LWH8%^2isQrt#>K|6`#R;<$%DXK%DoKat2Xf^X%wLx53mf3+aVZHuKcOBqoET4Azf`S@^?Krq88a}$QAD#94fyu92StCDD}mO0)u^OhPgrmwb5=TVl5+Rl zlsN&w)JtxL;}52jV@t)iF7cT?eF+KK(TD<*HOw?G+o63!LRo=>QDU7Vl6%k7YKzo( zuC+9fhB98HW7MnFNj-v@1UkSGg?2rmXA8&;0|ET@e!xSw^|GPh$S2-P{Wg|7D&o&} zaUaFUPO%v&e7Fjt+4VKf_NFy-(u-?}auioCyR3u+kvgrfd+*vd5{^)L#UaAOG8}*s z=fc;EC{OKW61-)q@r=ap!CI{$co3|dQq_}i6-GM}e+KJ#$Rcq}l`#TfikuL^d`Q_6 z`JGyO1>8iHVE_3T!|^J-_-%;hjtvn3LK{zF=E?@_v4Y5k>ml98pFre>-64U-akJ>F z!4niw&I=`8ylC-3^rd9ApUmTE+UPM-iYG4`>=$##!0vAeTo6yKpIqs9?Ub%_Q0WWe zr*H=<-^h|Nq$S=PlGULIjRuYj5%|QBd!4d68r}|<)puI1(OHIgkn{yM4b;| z8=beBfCap3s5o{4Q~F|od6JQRfY9mY2<4;*TfGhv5xE489E;^U|Kp{I$&@ z>H|8ie@+Y6l8dc!zn54;sp62VomXxR0fuIK)3MJlYUUP(Tk!-&;#~;PSU7G6D=kC& z`KC@V3s5o`EuE8(IBc0Umj-<}kloaqi07%q7BORvp{|=8>p~wMS_KDQCKjFriI>^( zg4GO`uXwFBaFIJ{!aRUybow8~%+%y1nIG~AX<^++d~uEWz;_Rp0wzknR8<2Pl!F%yxXPn$|%yH1_m(Vjyl`r(p?tMzQH;hdBR1@g|$gopYyb;a}r`1*OAk6Kq^PlEO+CkQ9LEDhzl)lsZ0zzsk6roTX>&Mv?rQY*Gwg@ zgeal2F?hoyF2oN>Xl;(?1=hN6zY;-5?`C?Xx z%|pP)2+wX|XLw&BBKg@lu1D!ZYn3bOZGpP=l6T60Lg-}Wbzd_YSlHHU3lC;G5$ zhuTNYUM3(wg8@Ysaf%Wx`GE`OGY^ z`V+FS&EuALrMR1P?0eZ=;@!bAu@NOs{HPN!sv|}2-Z2tc*TC6VE6CM$`7kchn(g?_ zQQ#uby;Kx{N_zTGV!%VZ37BiGBjJQ!Qg_(Zw|$W<(y`Y%N(0{IP-xu=>frYrVW-{@7Rg;`HTis*ksTOPtJies!(Otal$ttRX7Ym zNr2{j*CL=L-#Fz5V01%=h2d1JhsdN>LB13bNHNuF+{|T6CJ$#Rc!#u<`AI>?>$m{R z$Z~v=4&!;N@Lm~S>tJ9#U0^zlXcVa8)ur=izyesS<;|0`fF$&1&`WMzVLV{^ldN(s zZ_6HhC*Xm`o$USfgurAl*OqDBJ3AcuQ*I6&JM{e8N^&fg-Uh@7{_By)I0sgy)%=F) z{IKfW`PVsQ5Z?3a0^n9SUSPFO05-@VZ3129X{IfwLgGP3206i$n2qCdq$RgwM%P48J#1P}cw3nG%_6Y5Iq@D^Y6P2%^6NDvC(U*udtt z5fn+tQ8`GmgU}cfTFpTAy?AoDtB&LBzHFP#j+Eya43fSa{&}j%& zUNkG0H7P#1YEylRwW)3&d~68!5?BvKw*d7E3a?Hhg(hwhKp zB9!_d8s~8CQUh^znB$)4bx{t7ZCU`NP3tZWR1Xtl$ujWH3Q>3A>TNWn6*z!iBm<^` zZ%?hELYk>Zac=1|qPTogyC>WeytC7Jld)=s3)Ai!q5=G&Ml6V;EfIvkTzD7u(tT9^ z%cUB&2V_r&QE4i|;)bS6h01t0Y0mp7h*G>|b02Q8Bfm&Q7vfz}-Mpw6nGc@Vx$V|p zbNd(%uei6auA)eI3Sl8m7(&nrXr}h7zR8&9JwLvJfRl+uE0?k~BtyIQ-3UTmdvwGR z&|g!X?fQNk2Ik1Kg08aCV+1$0nUubn4-oYCHT`+OAF%V`@p}vx1(rDWYvAx&`rUe7 zrgIFIB`K!lM|z;U`2gaT*J5GQevxSp!~CFTch7OTLuHcPmna4`F3Q9Y+5O1+hAej% zV7Zc7#|Xy2p5aBV)M62F1a{@=t&-210&~(wN`Mn4f0EIj`;(mqGV=}Nm_Lf-fv=Y=>S_-O@ zE_jSuJk}y318dWsu8{76a+|nBIjiZyfb@F>=oZs>&YC*I@a%2 z_5)cMb?U85$!;utuw|oGrOa&E43_i##L{@;l9gv6cLhHO&b0qWPto zLB|TnsiM|=ykK2k{YIzDuxzV)DvytL+OZ>&qE~~5-u!k^mRKY#`(?(Bt@$}3*{-Q+ zqi5QB=8p830D;eO>C;>gx~s>J zeVtJ>N?3}38W0YI1B-V|rxonYJr`D9ckB7`@lMb7cDU^@0NNv$Sg>MoRS2ru4U=`X zu3#HrdDt`Rb9q_4?R9=NZoq1LN6nt6P)<1By)9%hX6<9lGkLJndacOj20YBH(vq9? z=+h$1Ffz5au`XJEGICuI!G@7BID^KKyJxH z^cB=oD%|Jf#%JUS?uWWwNJu9uhs4E|Qmt_r@UZ@LMGr87@|92-vf)~T>+8t9;Hyu@ zz*@+vBe#5=Rx1vcJulA7h);|EdPqvcwux)8r$C3w8Msjn+9Ar&Fz-BvLh7Svr2RbV zdY{!M0CCp+aut~`DX2odE)}K_3vvC#U1Q|z?3(qE);u+jk4{ouU8xhoE9!-wE(DWj zv}?V4-nPiW6>QQPKDpc59C>+>a-*f*>axT5TAMWUqtDm7IKr+B2rog?iml0l$_W14C@PeWg|f- z=Bu0gi;WGzxlC=ikIcLX@up|iZ~QCVva@V#s8QdOKWDVvUv~%n0fF4ijJ+u*-6PPh zN`1uZx9#V(nhwtZ4VzJ?Yo?-^YGLtj=tk^(vtlcb%(p>o_vhI{Vh;jLFc7=rdUWn? z`-;siXxNkvi}cme%9m!H9-|!K8f5KK^OifFw3-44DT>kZ@WM(K?W%LjC2qQF>>9b* zDW-&i`(x;&7If;$mWByb_o|q16}qbBsiw+I;b=`0+Js>_SW{5jHw52y-S0VIrZFJ= zpS|S%J^r+@3cVNH847C=yOk!f{}`|pGAXx|n_kN#Bev8)z_bH2l_7nqlR2v|Nco?y z#PBMu;0@x<>%mMs48}_fjAc5BUxSQ)4FT6oK#*G=j*edO!5CD%SBD%Reyspp$Qp_B zJo%<`Zcb|xdK7%j0jm4t>q=e9bypc*hZvMxYh)|chcW**^voK}dQt^gRBRo%=<{c9 zw#4eZ0X7_rQ2?JpKD`D;4S2j<;z4Efc}M-%vK@SpZ6spiWMS7O=%yCF!hJJ7$=qm!emcXF8G!MP3?V0?X&R`^E{Vd3FpBXzwQ-aJJ?g`iQK z#W#Z7PVt9r>`yc{^bnV0p3%mM!sJB0gp|0E(H!kHt#}LmtR|fcKKn zq^lRa?$lX`udooU_U*hYuA-*SX2VPYISa>bcm1WCwr09{PqW=(19Z9DYMI1THh9Ay zJOR1y3L%JG4dLlCI>n5RjVr<9j+fA}X3xT09c!?p^>Z5e+7;{4)ld($Yx~DXc7y7Y z=;bt1w7Cdb&!?$tuZjbL1h!*cIz9gGIEYmig8U&T7@>9iT@=K%&)IX(7j6eloc|{_gmrWBTvo&)@y%_~gsu7skOWd{2&Q@Q1fiN9*=qyf9=8PaXBHzWj&4{bH`a{rz8-}&I}_uhGb zXiQ~>k#@;--mUY^V*F2#q;kkG=|N^GIW}j)dG8Yy!Yy}my=K3P-|Ab701b;fF%>s_ zx-Z4OI1#VJ>!E6ehQp?BP0_mJij&H~sPL*!GrA$kuB%q4;VOL4D^EWr5tYxTV&6MK zUDat=Ux4S>JPpI#KMz#Z8ihfLRDm~td<}s1;l^1oSMJAdMb#Y%3#4>UGN^fbznF61 zH2-&8h&{~4ZQE&DVN%m{E-xrHj8`r5cZr*X$IPcBwE*nvV6UMz!LY^}6Lwbtb>5yj z+h<&n`K>Ss$OLI){S= zcmMN9V>Q%79B(=oHbcR`AO2U_=*}1UKJ_D;RlVRq=E(HnW2eL}|Qv8&+9$%cjK&^+y4o%ZbI zH_ZIo=U-^fHngGbpe(uNUwqDhf^VSz_PX&_NDt6o#}1F@l!dhkvn`#aoV!a21-qv` zV^OYaY6^YU((w2wQtanwAkpP8>zr>}!`JLWQ-9N&xOr@ap@ppx*i_wu;2h63r*%z| zO#X!m_^>#98y)a+5+;y(3T}s~A@BdI4)=)O{Ljt;d8=4yBWTR8w#JN$(Wmtj-E9!q zut#bc8CIT&AS1MQi$S{?_1LVZ zi#WYD6Gx7@^4_&7s_ZBGjOL^1hPump|E0e5v;?~t-Q|$Nkth3RiuJN4DmwOg^Xe>` zPR^Q+Ldp5u*P{ZIK@}&YQb7p-f(I3KMZGQI#CCztPs(Xr9l`E>HYy^q37NP4{w88g z*=WG`z?35t^e*`&3-DwRV9g zoa=RbDM|}h#%8dPh!61PyM9J7jm~O*y;m6pp{n%b41ijRJk|x&awZvj)saBjpWkMM z=fBzaZOHm6iS??Vype73zLJr+<|Afg(g5WX`HE^Bg=C-@&wk^o>afvevUJxZtZ>U` z5O(dMmEPVqFR$hBA$1PaIV+xrw@^AIDGNr0@^$CO*NJ3_EFiECI8L!nTkK$T>mbLx zwx8H!8E4!EYn~0tr2@(4!X|^sQUGiA0g1x7&K!pNeT)}Bf>x+oIP;`EOsD#KhCJJV zGHTP>S5!}_M0~hD79;yvp0$Zn9xLcY4s zOy}PFdq=UV%NgV#PW@&fAQJZXP#@-Welp5=^{Sm*waxwExHsWB66>LznaJ8>;)%0O zC(M}vnez~=sMJb>RbOF;C;V9UeHcvwJMMbRuIy_DQbOL{nQQ!h@C6I|7RBcy&LD|b?2bPs($p8;Ai>eQKzORPbRV4oR%Rb+Q}e}b7tr@R_k(E zGU%F@(DSl$I>Vf9chdLZOUjc<>H?JA>oMCc_JxgCkZvl5pRty@OAh*bB$mEQ_nhRZ zPM%Wo?ZL}EF4F(-#hv*%rJqy1R^Bqa(rk3>OvsRGfA7Vez@I4)SK3(>ecYn^B}(eZ zB9Uw&5~S5S64wG7D^Q38ANY$&2#lD-A48uPlr_9btzj-Y=-AW$9-4Sftj^i$!`=pd z7g~-X@j2_)b_BC_0)oFvP^;Qy$W6LBG?0FL)KAdfxOzevxYM(? zicsf&;MOnG{Cw{MqJ>Mtb3QTOe;Ha6zTSPZW9{{NC&?ihFVf6dKULRG@5RFMtkVGV_~zql0(%0G@hn`9ZpQn~ZmM0+%F`v+va`1Nl-RlG8%rDFbYG0MsrpEN{UyDk`_f?1QF36uUnPu9_Yy8) zQxBZdv>Q|ck%r_=KH8n(ro7sn8IPvEG0`{?yB@6kIjZkJ2{I)rXm-XMMbP~W@StJ5gOYKm73h zS8drw=fo-Kov{RbRTd3(vtW>gJgg+rNbyN; zNYX*;v>svREF1D+SPwuUfmDn!5i))3yGTI!U^;4OSyrGuxY~MrJSXkDU}a>p>Pun5 z=omKG&<1Otd%@c02?sKt_bC^nl3!9{oi`aW$Ze&iISMwg4$3u?(wf5?tI#brta%Bd zv^>z`9hN&gIMwInMJ$bQq>v)8sR`>ZERkE0Kf~5;8s?vFXelafd>TCVad1zu8D>rO zLWZVMVH%a4MulkWttOWfx--*ULA5AO)F(5 zJz+wu*q&)#XFfwS&6XHPz)~_as4#d92?CH8hFdx@ESmd$@MbB8MXuqrnjL*-zj3x4 zFD;sEq@@%eFcB)+UzKP|$*6CFs;D>FF|8$=Ie)I5~?so(BSt-8`q!Fo8R(|EB$J&-09?UI+dPIPScT4lUA*er!7|!AHZRJJZs+0Zp27&~azgIt%@ja1tJMDes4Dzl3PGwQiz9uX z&^`@%QdQ)P6NEhL-KBHkcb=N7()N{6oyO0&2nS3e2nH38&=9U3mG4-{U#!I2A_2sT zc27C1bM47XPI+7uQ>Vtypei=QgszShLAu$=QeR3p;f9&;Q(=v&cS^4g=}0wN)R z*Oj8Ei`VU=}bLLcm;BaCKX=O z)tX311D9C~EOMwnvS+Y`n56fBKXmpC)q~19R#|0Zl>uMl{bCk!K!~{FV7VBB{6c%2 z*=^!P?0h96WmxkgLKLxr4+qcX zx`ne$H1Ft64-vqcd5B0yT_T#aK|Jx8TbreD5fR+k23iblRDwdGbig=mRA%~ zNNZnV>yDDxrH&kazg1|7w%9pNp-H+0c$NdIsDg179V^q+S0p=u2)c?mp3Nk)JskyziDwcK6YwWOG=*hW1xS?VkQWo}v1fso z??QX!Fz6q1gP;?l@G(Wt&CD-wZ=LT8HO1|1{6+zh9>uZQ&Re0ni_ zV5DSdZMK~2VHpJ|^&xLx?RAuvbKYyGN-)=+xGAnyeST0Z0-I1T)Uo;3| zjwch}3(9gx+$+~?)UIbQ?kBr9A}H_z%cuNdHq*A39;s^1rKVTgu6fkyw0?P-2Q;x* z0z{2E|LL3w@KWiMhFvZ^KC1akMa0Gm$i$^ItJj-2fLO_H(SX?{v?cZz?|}WOw|jsi zTQ9C*Q8|bJK#|yz`00mgQV(#ZiJ|%vH~cC1D<4hD%KPnR2=w#*EO7QWIM@8Q-b-B2QKVTNM0OQ9;2W3D5y}suUIbWn%I`CYPX#69M6B$M zVn+86Yl8Rq$?I7h{TA&&jp_W?Uwgk_JjxGF*~0B~L&!7D&9SQqcP-=19EY8r86eh; zNRT7TdxO@x-lKCgM<5v)+Psv;ZAZxL8-S%T?qaMMd6l9gLAQtEO+pJ{Q{|RB_(HiD zB{Z>i^ph!$B)CV30;;b&cBf+}(m8K0oeR*ka)arIY{s@x2+i~o<qIoh2E#@9HPhFG%^SMY28EEnDQcpENv}VD;8HwOh2QhQ`t-!5|E-N{9BJHVeb9|! z@JJm|SL~cUY)A=|nTTuPdT9>sPHxje7zIDK_Z|PFW^A58rTFC%q8_LuMj8?OJQLs- zVyJG+OWbwW8K@JqM89x!HpnN$hNNpYK$VC{un34KOo@*8`g=xhB1?EUn0DPqD`3d zODiRJ7AR3813HoYcl!G;qt#y1jG4i|_nRhG#`#<8QMTKZVWsn;Zo3JG^8e3$x^a4Y zmPykCxuQh6rkwaL?!;n^(Zz`K+pCZ?txLo;muxIa(zeDB6E#ImBZ;dH%d(;Cn=TV{ z71ffj!rx2h`-s15`CBl}SaggYt{asCdh zZ{Nnhm+#`XmD6)qE;19eu`0~u9NW#VIF;O@t8K$8cI{QoBy0lqTkc64TRd^%v##Fe zrhDGdhEFWOtZ#`+hFhT!qfc)Lg}dAGL2!LzrgRXXz11oL-L(tk$~d(HXk)*DFbpd% z=j(b8LUU(j%#StwL#}(76UbT!IvD&|TQ8C>L&!u_Uoz{xeHE~BEo6AJOe=4P)&Fa! zx#6Z4ln6hHIv;23pP(5R?Wk^A9~(pEWKahke}LTU45t~?O|iFyqDkeQu>jZA$%EN# z3-N^|RBto`ms%?f)l9b&5C+9j74 zqZWfAbM%CAV*spT4dquL-b)?ajN8=@4L=n(b&1(ncP%9*WF5As_X|>|27J}FWujEG zpzN)wf=Q*mb?uF}kmfv>8Qw@4yc4jWqPcWB-E?(#n}|t_CeKT`Cp!@;MBvUhQ)pZ& zg_*a_$(Zj0YgW#hU}{l)L z3PR72?GH|2IVEiui3f~Xt5l16KW4?nF)pPi?4!4hP4EOVC8g3%;8B4a?Xtd6LmSAq zyxakVK;w6NT_JpSxm2PXMPVgJYv@>3>>+txZpsjv@ch0i%qpp@i2}(a}?PSeMpfVMxs+ zCx+FPE6JMp!eTd5M6MMBxH|S00a&<_*1^lAF!V?xOFJRne|K*HjArPRRvU!x+!&3G zY~%*Q3bfk*gew2%TL0~;lOsW444%P|cz#5#TpIYIn5M(qkJGS!5RVuWwG3Q>nU9a> z4Oi3xUS?Sl%6GnT^fz@^-rY8C#Q*NMh}Et$1KuQcgv(&IhH&7*C~ zVJnL+N#$sy@7~`GZUXetyPLI0;us7Dz+f;K42=6v$~0^;Gz2Pzy6SJy>buR1_O)+> z@KSUJ6>E4CM5Ua$mMc10_Ff+|&U#X{)dd_rz5i6_SCnR0dYj?{4i!6G!{0&B!6#Iy z>|?ID$@y`%)l#!t!=$NPq%TGB?j&iI4NK=v66-Co|27i8rC<;5a-&s(&*K_=+a?9p z-`hC8rg2ycGJXgzRWbSk*I?UDoiR=QcdP9>=x=fq$K8}y4D2?o<|7T21V2I;Z9S?J z&zyqFuApg`mAge#?TiIIz83t&mv`1iuSy+%9d`3Ij%4$hCjR0>?xMQ68?jeti-GeE zJ>H^&IkKl+f{_BAiZkq{Ot2d$huM1wzm$BE@7DYVS(->6dN=(d!|3x}77OwBt zvW4JR6$oX%4mCk_;=&n1i)wu4mcd}lHp_F*?sew#E>c#Dw|?mohcxGTn+ z&0$f;;iu~+79=m$*X&n07M0x)7tRgzELjpPPp$$3E1hZ;lmYRf6F>&I8SPAOv#xel zUm|yJkQuf@B5H>O9TP^ouiA);7NcwFQ`4{1EP)=T+ zm>KXn?W2?}T(mcUVN_hki4RELX=`_E1Q1?8EQH4xMrpXRgRsBjpy!pWTXpx4n_Yuo zwBHN}ejAG3OD&Q5J2k7zrsrtEX?b3*+j4pRw14Y`#rNSzC}lH0pI&K)Am*xpkLm$i zHFrq>KTaj8^GUrQsmEJ+tn9t(jK<9;(*Y(lShm%$wvxXc7IO-d9g#WQnY?X9?-h{@!n&2`S>wk z@BJ%R&c%QMkI2>p6kaF@Q`>GH-1x`ndQ%g8aW>gzxUr%qdFABgD2Jj_2)qVa{ z9=X#qCX$WL#gFq&a{G5Gd7>@V6ke`6ki$kP- zvAdgn<)kkl0KC#>xh=lXX}rr@e&Lz^RtLU*vXIOGq`bt`yimu0Y4^PtnxUWtRHJeh zr5v+o75G)rVo7;W6J*q?JUNtn4PH5#=*aa!O_Iu*W7eY)S0k4t-6V=?3)c zem_z{pQd_{mMZwve6Q!9rl%_GtqmjRsyY39Q8BMf%#r$jF{PF`fPaE|G&z(;xY}&k zDyJqPYe&L_vf7cK5O_vNk4)eh0y7KG6iH?t2*((d)%>qqSg+hD+yTQgRPZr-KzsG=L%V0W>=#Ta(Q9> zB|o1!P=aB{0H1pRjWdLT+W8~7U79@J+s9ryZr6Dg5C zOY& zdOlSko&W?rzUALj^>OABVi>hxFld?iOPyt*vMj#!Qk_oU5@L_`(DVoL+1|6K^FJTA zKi=El=Q{1}KSn*}ll{q~C-b+{qv?^O*6(~1-9tH0bs0b|IZz+_`vc9vj`@3UG7u`& zgxo*s&_}rm%@Nvw#Z~xA%tzvkem>C8l{`L%6@VCv3I6c!MA+{={PVt_;u8-Yu#bO_ z#l$Aqo6!G{qZ9-J_T?ysb5jnT%YE&4!3cepbLI9Ehh;n;15f^xV!Sht^VX}UN znfkGKBlpE;`2^GTQ}IeZ6EEbqa7#29iaCSCccx$KNsD9pT!&ey~6L$`~M;KjZSxje=qspk^T1<@q+&F?==30&?E2P#ohn? ztMZ36!r$Hhy|A@^=`d2T4Q05_N4C^cAO92aXL_vn>8#pCs>_rH~o@bdhXd`yw=e=hg&{7ych zua`&iDLE#7{g#LO`1I*Okf!-N$i}}dV2=>$C|G15u}9B62j+%medf8e#?Wj7%p0o8 zytdRiGOjK^YL&-^4hl9m79|hD(V&@t z11DYj-gxhHz=;sT&D={uDrAi^Q7}={n0bF)Ru?4}R&>DN_hkdWEYnKRis>cfTbx2z zZ?}T&^r)x2F!vBPNo$CmNyj@y;d`fm48hA7o~%i+oMr4@c}Ni~f2fzY=H(Mn3sA?I zoyxcB+B!y*QGThg|Hb*|4n_u%6%biL*o&%ZP+O^0L?XrU%BdDnwn1W?@-{;hyW?(_ zTbG8X(QdC`4xyl5M8{_usl}YJ7IUaaj^jDsGgYX)Q)@6|39jOWL(%M}Knc3JpWbhBoKn^v~_=dsjylD;iI-(Xt&nwLTk@rPTE$ zk3P`1??7+M3S&+#rB;1`ry0_4<2G7Z`40P>#1#UV)J;-gqnn#KDptcHxAeO?+iU?g z62E}Lm^aGIBFwP5Fg;2ziK*v(9=2VCpomxZ{}r9AuyQt8`DCn-(LD_^&9e;lUxK=* z?~c4)basMw3#f>`-kBE2w>wcgpXjEwR>ss4xuw}TaH|tZS@`lM(3t>m#agt5b2`X<-&PyXxsmBTuZ*^7fWROidl8MP@ z-b`x}!LDX0~ci#e{%>xmt4%c9Q#*o(8v?F?H{4R0H@$&`= z+Q2R?H6I2wGRW!yn!d&~NFycr+OT2NbBI*Vy1GkdcPUZ~tOt}>QN(4DH|v^FRQ-8C z!t42C*n6b-ii`t~UL`_#1&44E#~?Tkd=4P1I592R5b=`-kM|Ri-=!ddho8u_km8wj z2OK3KLWS|g4d9NdB@r-!!%}zQ(!KCTN{~1jN66*+B#*fMjXX{=$JT4H<69S`XGS;a zxjAnd^nQn~`YyQCLPevxbD!IrwHvjKwG*5 z_i2pk%}c7u+(kjyQ}z!KjT8`4P-fE`3)s1?0A%({Fn3{oHI`I@Osqh{eh8kV44ToJ zC3HBq+nwLNf!!~*%qJ)t4RY8<4Nuop@})H}mMo@_2d8w)RNc3>AFhJM2d!&+79)bZ zd+uCQ9BaHm?*^N2KiUIbNuQ&)+j#Ou{`EmQTchEtQ8bpD7?HeL|Ol7V=vE&knLLOO<)I zQyr1(`22G+-rqF<_5U@*aBgYD6@XqH)JEZRg_gxGeL~-JbwZtx9&j^$DA%}d_aGMw z?D#I{XR?~^;1yOD+AQiTUw(cj)NSe2F4;QAO^gPnLlQG&y^>NIEUtq>;(j>yo4U|_ z3g-vbisl?OX^ziN*k6CDt?eD-W_`|~I2lqcBUbNsoMJcCarB@ci^6YD-fshs!C%=s zDw~)rQ1P9_ZH=Pu+}37!S{$xM&BHw`Nk@{c1Zxo7DNkW<1oA1noD@Ez5im0A@0#_z zw6$ru1itiGhJxh)ipzR;SF~Z3<33em1rq?14j2QTw{kKf+~+q!n%MX|xuAK-fWiEKphqhQD zXy9!&+EI$ht7Jovbq8tmDO#|2n*n_-%wQ?NdDQW{pB4@J%=rrzv0iJnCkbM(M%RZ! zc4VR4hv{!HH)KBdGio(uK&NyqxssG1sN~&ifWmHYWZ7tJG~8YrSRD`YI^0QQmab>e zCvb7`ni5_T9by+2?C5~zoVZ-(QC@vJccuq+A>f;ad`C91BE&0Qw61-v z-j-VAu%%y|tI_>L^$#;X5bJjad-nZKWyR#G9*|p~-(dToZAcfLO}mvDX5B=vcn?Cj z{Zc&9$E`CghQYVlqv#!%w$pJCe1FHF{r*UNQ@mPVo?-#_>*s%b|NG}Je|HoGSfGZK zQNQNkwCs;{E8Uk_sIxhuMu>i&a?C8os(U;xbVUGc;w(Yg*6zTY5CTWZr3|R5<;wU% z?3oY1(7roMa9GGxZyLmI2JA!<;-b^y6`6})<#l2Dl>_XEa~8&c=JT6@`0;rus;qv358G2RHFXwTHY z4oMB*E>P2W9`L(^cHM&uu<E-VqAt3Bf>Lbyq0J(gjkk*ni4hA=!K}IGpsqGce8-g8IH({sW+pD-DW~ zy*se5lI~{Jf20jgSF1bTY#bLWvxeoK3y7 zBNze4BlPwy!^vICMBGvK&k?w#cUPAlGsNrjdD%Wy>*YCF6w%4)H`SuW=56x4RxM2f zi_*T1T5CdgK&oh$Xt(u}Wg$t+hIWYQ1a<)-!K~li#tk=)cK(WX&WuSYjucvjlVq2z zG53x8a?j#Jw5$(JcB1EPr%wy0`LcLUZM}}A-*pCeF3Er(?Ni23NtG4D;wUs|k{pOI zRacPJK#7nyJMY=7w{g*?TpcXzySZQGAIl40#Hu$N!IbV$-K^n2{x{+L5 zSl9dSnxDYMeglJN-PBmofS{3m)X`;r*057MO9Ntjh9OE1!gYdk9rNu-wu>m5n1&5C zUgizk$1xVBlxSv7_k0tb=!|YO5F`b_WVB}z?F})=mDfbgcg^TNsL5J;mjQL&Mil8T z*R~=S64PW!4?fT+W}#;I&U)8HVR%xYjq^fTl4!B2EjT2biN1D%yRw#qYGFAD~ve?pNvG&+%AAWoiy=G(Ek-V`I z;uh76XrsF6q1QiC&2D3plNGVv+p>4t+QW41+rFyzx6O@B*R#Y=cSpAZx_fVAgWBu5 z2qyd#fmfbvv~1rQ93SX15s#s^1^rCE4M}Swdjuj!tYkz54C%(s7Od&0YF_1LYpCWHB3X zmV~l!OsZaq`RAc1llaU^zepljZ@u_plN&0fgg9j|Nf~=+-e5WINy36 z;!1aAlqM-O%+7Jm0_*@%ti>9E9KiJ(ONsaOxw{%{h5|y`J8O;{?51Yv?3c#*9e6?PL6+zbzW8 zElM`YZlXz&gCbliC~c6LeVh4pQX+O)uN``{Rhs6{|2zT!(pSEV-il~pm{8nZzp!(w zlCZ~i`zsj4Oxx<Z@c7YElT0-2xl|hS9I5DD20rS zMjE?#jrn9e`Wc95tg=%u@OU)zY^KEk!}WLyP+IqT!vx8;m9qA=k>)GZ!1mi1$({6S z(D7wD@%z&kI7)=a_uqeS{D+kG_zj()bYHAu42QauFl9>UA4Zcoq(|6lkK`nCBRJY6 zzqt+*v9cBtu|-r&Z^N3>RKI0sM3&TS9x9uxr+w`%Fyh-(V;wgP4YypNL&r&0-ti1J zEqPs+K(2`Psd{%J3Q-u_JE;vZk{k(<{x=AnNTd;Is~C-VSKqsa!rJr9hZ+aV{(?_Y zxK1v8^*fu6xIFGd$8dVL^8>NTRXaA^2`y5Dt9dU=7DdOr==B0hT6Mc=T>WT+jjxI; zf;*4GB#uNKn<9I+94uVYDX@aVb|g$7zFcEwfJCSJd;c3h@-8{Qx?EPQ%<`2xxVyblxPb@}m;IYji!*jjwALyK=`n6ysVd$T&A{M)U3bKLzN zIg^1F$a}>j(WLKYacA~wzSgs`{xf)M0|xO|=m8Y!D96{1I{>Du+90MGdy8a$gN=;g zA%Xm=y&bbIYC53Px$JLr04w%2GJF17$8a^cvTj<J}-z8#b>25bWU7#FzVj4bl*g^&=;X1x5=WP4_f1r)a*k~ zXpyY1{4%M;nH>7psSfAU;b62J4YCccD9&Jfsr|0zZsU3{yfzdCw_K;We$nZqgoC^@ z{F-p7pBU)Vv)###4Aakt-D}Q=+H`_$iaaC7{rav*#{BBu1y(j!&As!gXjb2}_qb_s zA4E-;doBdW@|dN<(DP#~vZ=wHD`H|yN~S$NaOn$yHb#+@lpC?hrrOHGWC-0<+nnTs z@o+MaAYEN86{M+)GQ@OZrY?a8R`TIs>NcZ1Oo zCYRLdAluRnAER=FjZskHOwu7U&j&SMq(YtNXG~*TbS6+MHf8uNeS<*<1lW-SrL;ix z*Xj`00(t19m&`>ul4qh;!OP4M7UHgb*FtXXJYUlCQjSeN-0KT~>*zjKK8xvL#+A{> zDcFreThtr@gALvDjZP%^LrvvPAxM{+U~qJ6|~M z$YL|zif;4w30JN`CU%+p{iQ?8i zr&H|Ga=P-MnU(CMsyw01i(}I`CsG4Lgoa0HwpLK8w;~!dy;ofUforSI6Rw$m6`xj8 zCQvtOI5(C%m8lbzfn!tla<=MJrw*!vR9oN4R{tPLv|`~8&tqy#y_6Qos-S*-LU^k_&G7=!L)FwK-Jyb#beVxci}$($w5X=yv>X`7VJE#q}kO& zcnCx@!U`n=N1&L^={v*E@w;Q7-$hq6q9VV(7VUao%Qbky$zZz1D|s6yTQ*j0LP`Vm zS=}vj7?bEQ!b_~+$#=>kBsAKM6~%}jnq(_cYVkJ*KLA|>gW6&K!CKeMYF(|z3{H|| ztZ4|Gpcr7;sFT(S%PT?$qWFiBw4n&L@7j%v9!!QI5ROcg zfoKA$s)mz7)>ZdJ+l$j& z*M>zXB3#KTkhR3Q@jIRqJuanJ9x;{6-H&F8v{Vo-g5I$dE=4x`ps!)OntxD7*hcbV zI^dR=vO`9Ko0l)G65joNCTsH7d_=ViL zn#pp0CGGq0qo~=Z{1kzT5hCG=FFr8Sf%-2Ynwpm(U}RB)3bc1ZIOBLLeifg~ z2A!eK#5Fxb^!19Ryo`H>@O#E(hWdaS4K!EU%m_7GB3$nulE3E6&3#wi+_$rXw73Yq zs4oh#m4#rcT5N|J@)oW45mJ(E?~m35?<)Hm31y!}eQL-G#{qZ;xT=@a!$9jPa(NJ^OABer^)-sGW25;tLl7ESVktZ~~ zJy@?4zhY*_9qlVur-88Fa5d~oVl}Oy3hEL@*8W$|r3r5hg_3tB(0%m}N%naE0h?M& z{I&0Cz0uri^?Y|Xmcd!)GPeHbvZZRuDP%jfh%M-F(R(y03T9b%I{4FltZI{M-IGX+ z)k+!$9beAlI}oLARb(D2{x5*&u-^4#3t6+_)Am_}PPK&5X#)0M2mITT5|yW5=ZaQXy0 z5y+zeryJN;ApOe5U!f2`y~u;5#%7}?RgrhKyP0XDFavZ*ZV~Qrz}f55KSOCxB{kR; zv+Ax=*dxGc?0W7bE2RRcvkYmBcP^^Zm7;wYT6_5j6b^yzU7ihF>xoKgmCdjQ4K{gb~U|+-MHM6K-#Ts(RfYcB?)?QYhiuy&)w?&JR?)7Q6MsKIDUtY}HNm-Et{ALL@rD&y9enICj}5O`aAXaKNQn->?C5E15AC5G`~_ zi9Ldz?84QTAK5jiz67ZYaGEG#mP`o(PZME;Q6iW%uXatG-b*@o8v8qTJG*?Ds~T5Mk7O2tm7l?hekbH1}b3V-8@wYLTU6=n?iCk-C*!-Nu4N!fpivVz|mWSeb|_ z*MVX6rA8aji9hZFz$mj+_`a%dA_9!DltkY{io+g+JOTlPC?NS2I%&cadKOUdP!=%> z;l}e{N5t`6sO2nh>SCp!`xN`& zVwhIyp+mG4-utKsh>`WmGF+_Yy0;Kx9-cLHvh>dG17mS0!S(+MMcRYdk>CTbw9L&u zqOn=J#b+ToMCDRCMIG6V=ykw=d>p~jmmm1FFZN03uXA>}TwUo>u=x7tARw4-($!b8 zizS)UoXM}>48ED-PYk{pO!2oB9};_(yA$jJUOJyqG_MDqp-Uc$OV223M+P}u3}r^) z?t9voaI3iJ5@Xbi{t`MRxWK~=*d^Sc@|V9_?yvG9YzjxcEkL3*bE8hCM; ze>p8;2rk@#2*d0lX$vKWjsbqvyY{l?o4cOrr@3T`nt2Mt>`^T&ji<+B5!#T_4ryQ@ zIvSSq@pO`%pyczQ8Li+uI7KB%HLY)sLA>WSkuh`{#J{#Yw%v-LbJ;?*-r(zY;5XhxOh}VqbN-t8jGy(Zmo?6*)k2!YTc5<(!}RuCOg+Tf z_7Wz?N1cswT!Q%b7Z|g+YH5W`y5kR#Ko~dZE<5`}=O*4Vq{|(1Xq8CpC;*e;Wz{ea zA{UKqn)3%xWTleX`o`7Wa&^Dz>b_e+y~-~&UcIVcprgzP3#Mj_2J0vr@)B$tzye!cyUU^Ml`u6zz z5q5z!_W;v&L4uJeXFYvzcQ>p#PwElJj;oFWOB6WtE7QnTlKoaG5;cr;rP=T5R$Q0N zdr+hpWPMy0*xB?k+oWh@cD!$x#oWN~KCWNp*KaLXJu_6Dn4!etRwH+zOVRUJnpI}E zVU^2UvC8tFWR-Dm`8SP|;XgV~BC#b5*t4T0>m4mIH$XGoepDR)=SRgckURNjM#YI6 z6~`wxjEa;0$f!8EX;hs2kB$o6U;a(w;`rY_E>3PaE)?MR=YL&SZ7k*YSNA@xvme}7 z*SfI(8&YMF^!PVJfpSvZ01Ugt2HZ$>Hn_+eM&a4eT#`Jp&{ex}ry%X+4Ll_!Yo6TGN z0+KH7Z5Cz*1;$%nX#O;>Mpc@D^$%>r#_m3@MRh0MMpyN{{g(k;qy*2x9pNiHo74R$`IIX&R~Gp2##HeV5FhyLY+V5kX7aE0AsG_Em6rK+6P ziAr1Nv9Prstz7z$Mlpp<$|Q->E!ub0cbeAZxuejoG@=HD41wUj-T_(1;9D4c`;r6O z9rs(ar zscuV7d_`^SF`D7IC}}(E1@BHdOM~;ohSqvjo?$NiR~Y0RKYk{@70<-pzStLIu}3cm z8jHyUKNR#t>>*STX4&**FN2*n`V zBjg4UfP9MgF~A^VG8T^?n=JIl@5uWE2yp30@l-rPI70XFMQ;E=X@CJkngBbzArkMX z&?8j=pe^=*G>}IeA+b*{6O)NHfV$eIFcCiv!S-3NoG(+X8s! za6BiJ#3lj)D3Iyv5HRS`4}ep06Ub;x6qya$_&=QsX@gwc!}@apiJ+j#nEH%KKjCKP zqMs7_k2HnH2z|nBfF|Q_Kvm!;Xd`q6JQ=0OsHV=qPhEKcvK?mZ#ZL?#rX%k&BHRW% zxE?bRP!OVRUeJ*;ardD&dU?trTp#MuPah%VDU%O~qG9$-&)j>a=>vQ$tsd(aM8~nJ zZu?J6%o83Xk7!U5ot^qQajN6^L^X=Xt^ zFoLT8Jz<)G*o+!bRs7WsM;;Ae=8MvoCd4|L&Q2k8M%-m`BRrlaTV=k6k zjam4$e~%`L=RbZrrY1v|AlL*FZ_fahLKTMst_mGO_*=zJL4&8vZ>i_(KLgp3fBY@l z5}06S03Ug^6N0P$C)fa|JH>?BTQxF|YJ^RAcAz4V9^iZ+Zfd%u3Kc+=F!rl=pPPpqM=ZnaBIcjVXtQ1|x>z zfG*M~I@#ghnZuCsDf&NXidSUd4ud=sZYMqF7|cZB@(7XKruZF4GxG#3K(#~Z_HR%7 z5AhGl&`rvfJF`@ch!!uZ(!3I5{{+RKC6=TP-fv#O`MY{bsQ>6ppRmGh-294+*PL=p||`bBTp8i{DIOl>$tOQ z#2drsL55Vy50sMNkXMC|v6=k^ziGs|!VPrW@7@@-U52BLyio$3F%wi7a~hKjV-5-1 zxJ+D|at)I@tS~QAddV4ivDVjeu)~Q`A34yFT47y9tlV82HZT)j{;OpE)$zn;^FRQh zK;5unnp~N>hZ@ORww}fDD!cATE}+nHTJC$)l`S@Ta)|bO4CiZ zgWsBs^xAW_a|$T6AouhXeB9vnaFG8Voppx$>8M{&(yjO+&qhcSjgQoDpaRxVCeLr` z?O(F#Z3aY-y36!Ir0BVv%NcF&?m`FVe6n(Vvs$~5|Iq?|fgNKCv)WwPNbvF*mD}Oo zobxYsCsVvgiEhiAPL^@bJ`I!2XRn0;>9QHwo$pR?{Q6)GwbWWdi%At zdUR+;G{TOgGqtA8VOu0aI1&x=2+k<5TfXLMauhpphARaO&h^7Z_LBv+qB>XR`?|D>Tz>aGhZa{5G2d!BY zCPG2yYwh3>f9% z2BpOOn-dV1fLcWQqq&i?Xx-S%e&6I5wg z!`_z^Nx~vz;v{Sl-Xw;B9~?A>Fa5t1bt)q*RD+~sM*UMz=mPIekfY)5?# z0kMOH7b9)c4H`58#W-r<#VQ)0s){`$_AkEylJ$U_gd@9ftL!A|KgRb zh-ljBN^wkIC%x;kbJb>m4~AV|u#@mc)MTG)FP{z*_RQrZk69lUo=3vkb6FM(i}mr| zNoJ-h`Z%T^drI)cIFxdY4G`AfE}g>Fnv+H#=j6ot3^+bvzi8$fZ86EnwVSMcEVrR{ z$L|nM(KAv)l#hj<5SpJ8>$1yOPUw^IopeeNT=O)$2Cf(yc$f65XWQ!vnWgI7YIg#; z?7DFXxDbfSJc+KU4~xS(<*YcwNCR_ zW~@eDAvPO0kC{fnh81Zq7%n2g-O}o$NM8jhC@MxK^2YdSWI|TmFNMcd?5T@8%vtvM zP5HWlbDC*k9J-1IHYEieYb)A(I?!d{e41t5<+<$Wkj=@@v+(36P2%z_p?&7D`W{n2 zoBwlrcHq`yM%+WB`#8WX$qCJz7`w+^gz)->CH8knWVV5RLEIo9D#M#(`2vETnv;k|6hRN2}t<6Fm#S0SX-T z5W#-ltGZ}N^tXb3Z=pca;c(mBXNpjj@bd4$*{-;?BkHIk8-8OlhHGCKsn3Gp+S zrGegCc%-_gAU3+BN;Z73QrXmDIx&`-ScA*4y@6;7_fKTkuc>S$ip@rc99Qnn+;xZ? z>*^JH%=_+f@IA@~EViwhy0|a)2}9m$rR?4YLLPK#_8B$Pj#muTl;0K8&!${mQv+Tq zTcd3`$q0ySLZ`ObNT-HiG4kU|?}7>(R<1qoN;(G;gzl0GsE9*u zRo*PQTB0qa)R61LhS0<6WFN)#VJLPVt~xEF6rGgBcKc8-gf0FeJ>(g8U`bWaegR+f_(Qt zb3JfbkAIne##Gds7VO4$p9rFV%)n?!r?{@r6fkyK$JtZ|7B)~LfPJ)E02V&BydQo* zyAiGc;JHn?P)2Z^=` z(zuJbevgsfcSBy-y=R{Py&)T{po5LIXCi0hVEcC_ZbH)LWF*ov563@WE)^;CZnD$R zf1+?QYk{CZN`TP6W0OjjKA+RvQ5A zyoI`wy+I_W0-cT&3BX+RQQRS7olmN=RxZC@41I#^iaS>aQ&n5#C1l1?u+RGJ!V#(s zq;$}|2>s25l0m5$#gGM0gn?v5{lIp5SGh=5iStV96>b(s7I!8d2d6rF1l(SNr}HJd zjB&TJ*{E0jf)H13UuKUZu_M)i%agEqN@Y{3d5Wd$s6=c29c)(uz1IhGFHE3%Di@2eY84sGzNXke+tOl_(N(wA5*jrs&_OMUewTE!!oPuNUdR=# zGVr8p(0TMCXcxK-7g3>Hp;7J~yJ5Sn zw#@C)Y5&0??CIv*6lV$?w$6cyzv(b)k6mKBsq{|`_I8^b=Z@#c-7~6PIMs*x%$OE- z8V~2^8*0&VEmpP`3OQ4Yv=9|$-DXi$JM*mL$+1Q)t_E6Ll!@RQt5P#Q<(;eIvTn18 zLB|bum*F=y*UNOZM{P23n@VgYHYwvsC{_>oQi_8(PL!m#-<{BIGu{FYQyT6vrSk~& z95OxHGsoL_8YEnsgkm9;BA^rvUmq!!vS)R0Q$sCOUnZL49lv*KvIX_GWzZxkA*nb> zQ;Ro}(|Eb*zr&6#D`u2kve5+WwFh}E6dARu(He9+jlYvzu>qZ8p&?x1 z8^U$+u^FMG*hdt3Exf|5V%kH3jw?z1ybflBV%q*c+Jqu1ViW~irYyAX6n4{gx>K>$ zOkNksW-}@U$Ydd)!@c6MuWx$3I%fo5=9mUG@&aiv{gy*F*pwElN2^~Lffz9JMe#gU z;n2*=$7lxBV`BhsB06aCNwrcRn@vozFuiQEc)*cDu)p5@t)psR%av*Oc0_E>pC}s{ zPL=*?P_b4gLT8m+XJ6MN*`niUQ#{SUDzP@VIt}T5sGC?tIjTex@&$ygfrjG@hD4e( zqPx3}LtH=9^LjDFCs#xecb9hO30OTS>Te9IgTFsTadbnpUlMwUlKk|c z(^j8KSt(p;D#W~Nd_DT&5i`e?S4Eu@rt8_)m9xgBV<;{6!r6Is55VFQ$cUAVf`7EH zq!fegZgIFb1~gkr1Hq)cEUI;j{F(v+NzC=LLEU7FQc*p+-d+NQ=0IIJyFe%U-PJkZ za|;gH6h7J(OIukq$#c+Po89)hxxp3p9QxJ-W>_S*!fy$)x*BSTK}CCayOF4AA@eVD zJlgFn6cg5*9h?7n?@fu5Q{QLiT-RZO`H!T zQ}3yM<_|XUbnKc7=RJt`ya_20j(kYyw}tEEFh%p%+JqsN!vgtb<=sP}ZqK11#8Ryt zVC<{cTAarcTb7`@ASaKMFQjf9?Q9NfskW-l-57z#^ z*51COxzXZ2`q~k9S&%z3*LE(d({s$ZEq4aHcelyyuF+@6G5sxYz9lpTB_e~w6&ER3 zj<8&yI~*gT)IDN<;FAylS26%er+8`^@<5YZQGu=ZobEV8Xfzn?$Xb2leLf7MO_cD- zHkzn@9X0qNqQLSa;vhK7rb(Km6Wihp5-rzc+jGbGcUEk<{2uY!ScWT&0L#Dgpv04)P%E>UqAoj``E`nymuaR-QI9X^+a`0zqk8miS8r{ULWF{}WhG+#Io*gkP#2O#V zoZsE8+OnGE2XZ~j&2`HQ=?Xv2am2{@Ngpnh8)&{h~KYBodXWj4=*kAzs56@Q0L z3}~TOM`O{61zSUG-%Y&AQEiS@V#VbP_d43VPeBFKxtZNf*GvX-S=b zdIJu)EZ9gPr+E!zUK}s!>fd3%&8p6r#U)X$1g@Uw+R{vc}jYpn2EI%AM79K-V0=um|pX? zyf?+uXSngdvby_~ue@Hd<#p(p+#dyauP@+k5vJ}4Ud9wm1C%ly|NeNU9-DNNZI=C{JQ7fnUx*$ zfGP@Jtevx`XQrp8r;m82GbhkLT^zLh{vrztqx&9)jpm|P+pD_ET&!7wKB0G<-_Uv2 z*FrvVP$BpJo{@xKrv^5v!xl}vq24wPcEtFHdG(#{0DU3SKEZp?)qKPq7|b2yc>3=S zuJNa;=_$S{bgdeb~C)Fc{F;#*Sx_g77@WX#5n>g;eUcmg_DYoa1d>3(^NYOJMm4L$j{$ZSj!| z0gu)_L;rMqL6*4I z>yn|@TSc2`wf%kSw4uX3A-FvWkgVJJlyCk%DnSXw^6jVQfGLB6(L5sJeY#f z7FYl$$d5JG7*x^ht)+~g@9zPC^>?!b0$M|lL?ivd?m`el7ZgmF-_@ymy=Z!VpB&bG z2T*sFHyw~vlB_%;5!NDsr71?vNmUk=__23+Fe%Twvq6B;LqHru0ycl%^E!1?JnC zt};ZWGv6))`xPud51-bQ(FIXi(!5)07dj}>3%iDRwdb0E&FMwiFRw#B@WSzoV*;-x z72lP^Bx`Zck146uGlXjH5gdKh!)+8^1IvhUAbfmaQwH3V*m}5Wz}jJ)TVjX;!kiBh zX3lX2msU8j71mgBn=v?R?I5rgt-XQPrg&{(V77)HX~i0xv_{fR(WHeiYEZq9>RlL8 z-7z4n8>tnlLNqKJYvE`i0ezo4KTyh-XdF@a%$>8g)C8XN76)fz>r3JR9;(o9R|jNp z?X^M-gULG|<2Nh9vbMT?lezR?WMT}>`nYkBI3$_P?K0V;$)Rk5<$l;Do>_DeUn4B6 zH7$1Bluw>@-(hnHx*m?9#;3ksXLj|u-fWudZYbWe;RBPQmU#woZ)v;#O8omKe0>&y zF1A}zo+FvYcuqJfdRl6ogTmGclJgvtr(xC>)*4aqUjb=*@tETw&ND(xPN$HB7UfX>D= z4r?%2F!&n26djZf`+6PhtU?s7(H>ib1&!6#1*;9m7R@JCn-Ks_8lIiX^DR1S>@z0o-Dvv z_h1*rdpAbX3~R07X{Ft3c6^zx)wx=HE#P{kJS z{WOggB9TQ^G(&xaLvXhf0RG@xoOy>6jWixXD*oFBt1nb8a%}#|mS>jR%$eP%g=$&f zQ`uzdg&V1{HjR-zmxttw{Lpegm9Nt@+=<%?x|h(IBHql^w{xyzenoB;rI+PchZBjz zHgd?g5xFnFTW6UYv+EdNQMcKhDY&;=pH2^z-cV#FVCHb%>nwye%#^ZakN>?Q0Z4~( zV;oMp0rR&Wu8xqdr>;3HF?E*P{odj;artjZ%R&N<)i%in*JD^M zTSpstqiZE5Hh;(Z>%-qaRY(CBxZrWGycxBKZ5CZ z#s^4ENm86*76B5O420+@9Mr=PR(@NgPh?EDYO@7-#7+Y>Gn?fg;wm(?QPc=$x8sx#(SSZ=Hj{)UK&NX|*e0Nk&fL-H)*sDA)Jt%t->KjV< zI6?BVhVaA;k88Tu4L_wn%v?5Vn0b1bd1{#XBZgTr(Lr@39SvJ>{?>BvlLZ;>Q2Eu` zUXd2&r-k%F*2{~N&GG^e75?DYXBY0061^q6?cu}lZcJa~jn8O4c z{0oF_Vp!K;Ff$o2>Cwl~)=;x6g|au@-dB-;tgx8AiG=dzb;K9Ck;JWxC2ra^EXJ-x z9CoGi!N7Z<;;8a9Hnw>pg4m-@iaogSp)So2aeK>axCsQ`IWRBIpH;to{6&m!0`|3` zr2DkvhUTKONBKO!$gm7D+*xMVYa!5aUn+EXthSr+7>x#c_|MT>ezMiQ`D#R4(jKbi zI^AQhgCPK3*nCCi!Od9-ksG_HJe-tieD|b_v6FA4c_POmed;(%;Zz?JYl@`b^Hp={ zqVBK@T#Im_v=Fhk9QM82c*hJ*81`qe?jJ8&_U1Cr8jsM0SXBJPn^gRcMj}|&mu%rX zGPb$1qN5$Xp)Wm0(QpdggwSqjRn=zilV4}8yEgpLo2%#XHZ)+b(@shJ2S-u&yoXq+ z1Gpp!oFw>37#Ti} z>-2)LQ_%Y7Wu*c7c)F z*e6K#a%<%BAApeA@cc$fs9$=A{I7%~aau@W^6=A!<%~n8raQ+vX#gIDM~+Lh4D5;9 zRV|Cfq}Df#j(ER1aT$n`GS8g`(`V0{rKU2OJ_NmOEpqeaJOtNvwl?aw$-0msGlWO} zoSs0g`{`@35r=c8VuYM{5tW6L4q*68=r-M`lc9P6a;et&`hQ2^fR4vPdDHG_KknpU!#b6^PAjQ z^DW!i`Xqph)9rr4VewH$TW+FMJbLTAc2OU}X8*CtZ^?by$}_a#L@GP+dK7-|3%@i5 zr;JE`NE*_EbzG2{a$OdeKv2^Dnt(UPRkigDfKiRHt?O`GhlV6+7RxVhZAkE^x5Nh3 zS=eBv3S65v&TY3S`(y-%wq|MRR_wf`WTm-9mfm3^=3d+je=`j!hSF1)GR`vj5H@lwDEu{blUp<=mzfA3_el2sE?w@yj|{ zU3x3IKEmA;4?+V32|`}E6L`2GQS28J7J(21DI(M)vyc?gDM1H{6|CSw@ zR6U&gfB}KgupUi;xJsG`ZL9SFiz3Qpp_G8(`dC{+%tY)4l3i3eZDHUaW?kCHJsKES zTf|dp#w*iCfi?y`v@FJ?V_kBn8rcM{R7Al}OF;C7Zp3WKGJAdoF6yiO6-lw66ZPO7nkl?I41b)jnAiQIkw0pVla^J=d%&{i713 zE&oiFlCh~8JHd@C{ByOm8Kvwk1kb%?Ws@s8;Dgu;$HlhqwH%M_{hf8#Cq2NnN~V2c zuI1WePQ%I7NofV!&aGRCO1omDR&_lEdyRhrXxz1QE7<8i{uQ-DR)nZH@X(+Lu+(=U zt0a;%<@B${4V!A;-#c9pU3FmYFhB!~^Ql)?*aeC~NQq)Bl6%ZVXt!q8m|-x6tlI3; z#m+4}W(2{#F#~Z7xLjv{x$cZO#e0Xl0p<2HYZM zHJkbpocMV57ah&^UIC>e&~15qTjPm5EW=Sr#ny{JPC}Qd9N&Xh9nwUY7*x3z!y9dC zFLMp=PkP_FgO3qF8iePyp>_dXuAos6)2#MF+pc|=O6iEY>yU*m2gBngUfBCEq5UUUjSetzDdX2Qjg{W+Xlr|sxyXD-=`aWeICR?gfHDhYQ`;* zWk-Db(S!mIBdJxQ{R&rjvG`g0y>L1HX^x1}yusd>K6fu;A zBo`&E--!RqmcUZEVzfe%MCY$ubJ=>unvr1q^4JjOJnAdF(6!g`%(OH)O>8H2us z1Of?GwM%yRa%)wIDO+g^qy%?Wc#U8}L;?~Y;qU5S!p+epI3xYpuzLyaT%mvOvGmGL z4S~+X>C@DvO)EDn{i3P`_fO0V6wa##5`A@m2W8Uij6f<^1Vp6Xx6^N$;FxL&MlX`$wi?YAqq!G(am_69=M9BAzR4>nIV|Sl2KMhCimS5nf78>=JgO$gw!qjaoS57w z6lz$TT~ow1rzOWy)Yhggm7{=)aG7v6o_@vAMUN0evYqrB%e0k`K#2V*+5G@{{X$XD z1D8_>!m&aEuMz!OgwbPBt;hCw^F}W zSm-atObn1DStJtowlsuO$>~vYs1zP!Hf|!yA8xCz9zE67Q)YVSVzA|n&s@1nP<(Zc z&nXD`LDws6X=CQLGlpE`rA?FG2F4KP2EqicwFeX@B#)?uk0=zd=hNN(Bd9@nuob1O zxgsA&?qSb}(jCdG&rQ24>;Mb~WbMbSPfEG}iV<%bO@LyO#eLq&I14@6x6UH^PRWUPBJ1%Vl4 zQHyPJ@m4v2Tb4L4pvm)Bnytf6RM{N~@L|%nzlKZ~r?dYF-t~a$XhJ-uLpBXZ4+R8J zJSAahyEvcj@sXc?Vm~G38?!cEL2GL++Ww8FKpB2QpDh~e3o;AhuLIBa1&Xk`=}Ws% zG!%Aml4$p{IP8nmtgKPpzY0Z=)`LQ9F;@U%(HSj6t)S-=@?wxhyW^Jtvtmr-@;&=l zi&eI|ZFL<{U!jzBZBosK3E7-ntcAklym+ygX>Qx$d4*@WdS!RpBH~v=0WUfX+shU} z>4a18H^B&^SeE7mEqiYyP|<3ANO+1a3&GOQ_vlDkaMt2b5u-Q95 z9WSX$>PtE_`i~qH;wT9>DjMXehNwLOu`x0RpiZ;Z|GuG@!{R6i)G++SH>@+ei+u{F*mTl6Fgb^4`&fZVnpS{03&+hRvdw>3Z zcb+|SCey11G3)fxBmw`!P2GC3P0FPQ9arG1+oB2z9CLwCK}qKh>6|9UCn|c?O zp^BR2We*LCJo_gaAW6k=5F7|;AJsgAsIWe&1C%4B2A<4OIEc)ek*QkP1}!wQ4BybU z=#50JzUkIf^n5!UW=OfW{#rI*xGaq!{#HX#EB4PY ze!(Z7Tc(=Wo*RB!(@_X##u?nrPe2zZ_?zMHIsTsE?-~A{kb`dPHX}HKR4PU;-ayj!C zl;dX~W<^DrVtc`$@)FeN+=F(xUmBJn_GJ8_yezLFHrUvh-;lzu%c}&`JV6+1Fo6(7>_-~vOhiAgvF8d#~h$3JNf~>eyYCo&BI^~JN}UYD{?O9 z5Q+TXncrf~nGUPSB+{8Bk0zj@6w!rQ8RQPQV<)s{( zeKI|mPA^ffyzG@uTPr)MRqS@Hu6#X7=fuP&dD8E!@4zG|>F~q+tDc6-X1I7>LW}fjIwzTeO_p>f9QK1KRrPmg<>A(*v!#NryuA8O5Sh zs}(L4TII~Q1Gg928(&rEYdowOW zKUA65v)P-n)xJAUy}ryYOaroDP@(q6sN zY0qEID2;zT*J&@FztU+hUYI^!zTmq2>$ORH_1dJpHg&)E>U*4qU$&3$Kj%L9*Y`}? z_va?!RP z^Za|<9{qa7-;_hsIt|V2qNp<4>~W!AAmY-$ z23;A2`#cj~)R+Pr{(*uYt}F#cU%eC$JZrh>5)6&uP0YI9EqPApmrIj32GLMiZUHSR>Yh;%ERb>(_iKDweBqR6HcHV~KTIMey%>#_i% zQ~_Wo-D&cn5W*xcZlMXDbRrw8<1lSbPv^uaz~W6gOKY=AmVnlHs~$mXwauI@VI$#X z%=zKP?`RJF`ATc;BY2Hg{&&;R1WNx%PfhJ)_Lx=Y!Xw2e+_3OC)tzU!(QnLeC>~~f zaM_9|pB$Pe$+sF0?!6h)4Au*$7-8)z*VJ-kS(2OIgS7xQESvGGyvnZ#L6Z*2dLiH| zD#6Yh?*eNHMi%&S)}UQ5NUONdwwDod} zXcJkoFtoca$f|e4s-&S*dZ`?=C@wnS(A&?|#n1W;1qZ>tjzkx4{`qbQa9KjA04svx z@`vQUWe))Qef*IinwLkqvQd$r;C>m0^-8w`WDaLyui4w=I^S-B*}J33TKHgyrs$_2 z_y_95iNB3XGJOb>FlAAK-SS}$FF(ZkVUVKP zZrkE_^_q%;d0asqnJfIZxGnMyzRAZyW1t2&G8W@+jLlXG8i==&ylkUCW+1jkiOgQ6>0<1s29#IGy%!ET;yz7;e^ zdIk>kU*{joE3)t`ky1Shxm8pp!gJj0ew3%1G&>Q;bn~f!h?Be-SZGY*URZ5aAH2A7 z43ViA8Wtt%MG#F!VH>^!@1JZ*EcYWTsp=hyksyoX_)SvD^pY-88Bj_iFaJrl=?7MB z2Fu%?jqMXalan;SWB-|efkDcn0pclg8R=ycN&($wOjj(@g2UyWAoNlBGYT0Gw3EW0 zOCB#DKP-+enS?J5-s3P94?NPh3@s_TXbhN}RbsqQF=_E^tsA!%8LYMw75kp zt_7N>5vH8MEF`d%z#lbaIU0e?Bu81D%i?LHjH{+cSp>vOr6(i?F>FksqHdAOFQa`W zTr<{H+|VLwWU1G36|G&@P67{$cz}))n%cfV;meCgAPeztmC+89 z4RygRpd(#3v7I8AYbh%Ofv2Ki!YAhm%^xYeZLf^4ZCHx#!=5fD+mX(IgX{G+Q$WQ}| zAS{|Js13N)0`YUK_HAHLR_Oq(=vQEI5y0#(>uTJgNsU7h)E1pbLYk!G74*RwgWkzNQm37Ks ztXB*)L1YuNaLx|icjr(?^E06-VL`P!%dA2?5T@mOVVO{H71vFR*}@jG;JS%nWB2dB zY?@NhRZ}GoZd_Z@h^w(WHg)cv$%h5tX)(G{g$`Nm*wTsNbQjxJ*7}E+$nrMt`)8M& z5XGdGY>ad|HqJ%w@bznrq_mjP zZO4$U9tLbt(B+?U$mcwdQ+-Yff1YL@p^M+OC--BQ`BLF)O<3`jTK%uERa+RhONx zK~^sENG^$ui~0cjidaSP*b38faES-Bk`F%F zb1nwO6E6>(xUTP=dp(EM+B--zXZB$EolT1BHl&MS^NYQNehsyB@4Zo`JSq!G+9v zB$0_WxmsD5Se84qnZL^a8B}XsciEz!vJ-<1^y7l{Vc;?&wL2W_aS^7V1>}C|LTR6U zbPoD(o~jczNXvE+Vieq1_AwTt6%wc?+}|fO7D#P5cG&0!8=_J=n)k~Rw94u$IQI9A zy4AKE=Q5?@AvhEV{%d>QytMb_RqOeHGuLUcl}3@F?+RbXv{=Iwphl1z=e`-*ESxI0 zTK75ba5^3Ca#x+@&W{UyIK?0JI^`|$Nr(K5{6q;VdD~_sn zip3X$_1d1#KQ$41t}w0;-CiQ^Qu|;H3Qj0qrE+I>H$jPDY7qLZ`T2n49Fn@kkQ&DakLKwGSO(@3NF`R~5^bzCxA z^oq7-#_i4_G}uRIWzi3&u8$_CUH0`LJND-qAbRpROlMB15~p6iF5Zwav&Q#h@cD*f z-VdQOD)v_re*I9NP~0Tcatu9lT1 zZZQBV5jDf9gN@+RYa$ahDtI2)TtgwCQ(3$2@R9BKOL|A9DK478MX-slSm@lfH05f! zW?bePk86Xm++Zs_CCWkXsnSK33u5u*dLTuNJ053Pij#se;rKbcYCp-26*W)^VRx$I%#(a$zez~%0!Q0Nl5ldK|%WM>2 zmRLU)%>@6CWZ#jVk{79@^TUq-MC%=9IyIhpL)m$mEi2z2rKp_KML(1<0&+HJq|WH! zzzO?Dr0$`)Wt6~jb$L=keQGrcy`0Kg^mvki?mA^ zk{$GOh^T6}nI|(ttlCv(HO(ZuGL4+3IOxN9+;Yb)n<0Hu z$02`L2c}VjnVorc~@BQT?fU zd;_-r<(6zU@=oPFz5$k8rzbjfyRj0HnNUAV?jpVJf~J*S@w*yb3_y1>gGVphs%bOU zg%(}V@Neq2q{b}ZvBHppS|9oa_FEzGC1=i=P$g62Si&Z%TG6`$J&ei-EF?R}{GEIx z{A$c$B>rxB|flP;7VeOevE+k*g;t)Exi1f=bn&AVr)M`*zC4Gf=TR*bzDn_#32QuPr zi#Ys7+C(E(d=HjlXu+g?Uv-&C1~)+$L|zi2RtuQ(@OL#ZPP;p!K{*8dF~DVfOHN^& zw#bO3#mQXE0&=@-c(MwfDad;tVF1N?^>5lAl@0m9kCz3g`aUE%oxHzoTRYmc0Z0nq zWkusTnUM@n0pDrh&10OAqgHL#cgt^ibnFo_jc+6pny{oS?Ca5*?|nIMEB%k!aO57~&{i z#v!RqFLD6sq@n%HxKp0=p>4oxVQ3d%e?DZ27c>1aQ4*Cj!Vl5dyIHBD&bG2qPKjh` z?zo4o$d#+UFt(BonzkL`TwxDrPBx`*bq19{OQE0&*b}{v&us`Pu~o}|-4Ak_4_@J; zkTtn#ViQLb;gMwGLNdHCwb~HZ_FJwCyftl4x*-~K9W^PL*eK_%bnqN%V6Wqz@ca$F z@EY`rr1aN1KHLV?arR_va4n5 zyp7%Ja{v(DS`Ub=m??m9XJ3WK#v=73vb+r4BVLNz^z4WPu3Lv^6RU3%#A(I4ZA&Oo zsAbkTzJmDn$wqFt^RAyS2%+B4!H7q*Sc{pR!$VsW60MI~Tou)5lQl%p&%ZryZ7^q; zGBsa1$_`l!?GYPg!rxaI!x!xcY+tillXJBMR%4`CtP23^Xm7Z5^w38sRuH0TqU!Yq zBT@d`d-(@Aj1T%v9bD%hp`%eBd>~DY;(#K}jmDV>sSfjP=@4$MsP~0%<9w0t#Bh=5 z8sIqwECB>(y$8vD3ov=}## z-(>4}O>D$E6YJH4ZQ|F7FjA$cwSUDWbG_Pn)d1omJ{enAVdfXB@oWa{Sjo?t;+DJU z;cIN7?b-TV6SRZDCL18x3mQ|4GIO2a$jD8U?rosgCD!)F(45)d=epvQoLeH54MEV2w_v#1yg%dVEEkBLq zn%r{Wwbzw$VfjCuuKSH~&r4m~t&vaDscB&(TdxIa(WMi^=4dc)9X>uCP8$6G^z=Bx zbXbA~K;Ek1om3fsrIzu)kk0F+N|{r#qAL9w7p65N(MYG$Xskjtf+G+`1)#?q?3|zR z^saZ?&>3pc;%S#0GJh7zznuYpZPxTwD!q4FOeFF)?(<%gbNNuS$s7=+p=D&lq1NU&_Z;4UBifKlW_6yf!GVi1 z_N7M2&|y8r)g644GjO|>ql={ytHk0@FyhV{>z|&mDFb(Yxw=f~a2hu5L>8nP8XXTh z!t!>SpOWhIsl3$;({?IzfzwQsryn_R@TI+Y48tKVhat(tb4u#kS9HsP1+Y18*dLntGxBl9=HESc#CAhWjkCv`0gK=fS#jNBFR?e05 znCOBeAj8MU=l)RuA9SCAoLYW9yE+$FWR3aRc`dtiBeo;%=E+s5zvioSFoKyc{9;Y_o)Lnc>cM`V6U2z z_`@!{87#YXjOi;324=Y9BrIbIwl9(3>VVt)%8BIq}Z%2(Ve?m zUWc0N^=YB0(LfKixE}69T{CLAMPto0LHf4r>Rnt6lcnuGveaOcDG~R0Od@z1#AjZw3vpq!RCMGH@aZ$Nf_C|kcLIKGe5Sy$4iNAtf z^QFA>I=<0VW+qH=BJ3bcs~g9U?uM=r@oiyyo=hYZv~NB@42(Iz9PKTViBJjc<8%-C zxg=ABA)>L5AxTz9GbBR{rZ??|6}PT3a@w&S>n zqBwL~cZZ%jo_hf*Wl~JftW`sh_N`7DWpx6P`Y>r|Pf9J5=&$P*BnS$VtF5`rag;vt zKy#`NmCjL-FYG(pv!*A7cithjH$`NbSp@M`;X|Y#zxC~ahmfMmKWvIWo>H@YA>Em0h$>evhjEZDYUs%&@(c)aWu zjoNpmRt2m=kwqg~w;Kx(nfkN8reja0lYM5fHsEboL~?R$m>fJ);kCm!f^H{$C#HZ6 z=CIE0r))_TPoe*2$Cj_4pSMlj)f`?zkl+1usDsQzEgP&g90ef@0!kzrsC94&?f>1+ z6wcTC9c`J#UEmfGE0BWcvOj_Kdb}c?qy>GgF~9sdgz0%AP=~~r zxfMLGw#Cnw1)9$wQ`S+k+@6hM3Ui{eS}3xFmeYiqu*9X4wqxUx1^_LX_6;aUbaZMa z8=jHE(G~D9#C)3NQ#w2UdnvK9(5NAL?rf} z9WbI0*Z*eEQO7_a$INBcNr__OKKDC4>o*C>pmksn&q&Y1LD~&Mk#c;H0^Rd3xwwmR zwX`M%!ryf0jc$v9d}pL$=0v(zgZ{>Y+5_g%n)HvOIe5`u(UJSfRLVieLH ziP6@v9wFoUi4iz=lQicMFqLy!6E`>PA15X!`~Bg>qre31LBNCEIDa1fmUrY`_$^Ku z?b|_K#({}AX3T@3GUFgbE<(|hLS}Ah2^OuuEco3kns4soWyRwl4|NDj(~sSWjScU_<8Ug zr``_vA|q{>+s|LI$DgnjE4ocoFZwVWh7|Li^8X)#SLtu&K}^W2N#X3&^yAB1OEvfi zHq#N?_ZOm4iW|C!4q#)`(H{wcG#hSy_@93-Z*^p_5xMbdY@}*k2o{P83bOj76%TgT z8!$M%hsLaKPe)ZzVBfe`cU2~D+u{Zsx(?;$f-fuGGLq@63TN%%Ssgi>BWRT;)NJ&N zKFTs11P|d}ByVHEwsr6QrCHv&KRQ;Xn=T~9^+iQkd$(q?VMA3BjLC@DNV1C zX&7N^V`Gqh#n@_rimP+d{|qtp+0?x@bw9|@K$8JVfpjH4XsiqObNa!ENdOjI%#6ZB zXb2|W_7kpHk)!U%D!Dp=K&b|lLFtoEK_Vm5TXq@79MlKwKAPXUBvscf(`)D>)Uwt- z_^t#l)e1Wyd_b_mYzW2Fhe9Ba`-pO^{=#0vT;60o($vW0maLSKTeyA9$ruD@HKu2X zw_i{+F3v3R4B*!3$f}G40bM)k!ZtRd(>>mj26_YS#k?h=D?6=0Iv%@4)jDlB)3UH# zEL&haFzv1>7Jpa&vi?*w)a)c1$$HfxOVU5c`u**#$y(U-u*wdg=;&u-r$@OHDfA`$ z&1p(_P*#|<>VmFas;of?;X;~XiXPfe#;N%TD&WW{^g+(z2~0zKk>9#$BqO^|*Y$?j z>Pxm$*eb1hJ#Pi>z~GgOilk*9i`Dq*X1u^Z<#<^HvoFa7!LzgX)%)gLu@QQa1jRz= zLfmi}2!1SZ0wN7^{N(HmU5@ebgj0?KH~7usoZs7Wa@iN2*>3Z`x_{r?zpr4vJO1YT z>M!F=uQHBoCmP@7wo*f>d^HpTx-pc?K@GVu`ZJKXR;Oa_+s(&}KnmRSt{mbQx}y&| zC~Pa`T$HkZ#EaIRt+g@y<*?rDpysSujX_l~@0>9{UleK2D#jH6Kd9Ab*v$zSjr9jy6~!4S z(ZeigM&@FxJA8a|JM(Vybof~zsXCE4>t^b*vqwR^6}f?Uxc)A|3@J5ov#!O3F9j_{ zYba>5>JB#$1T)pI?YqC8XUnBwqXLkv;eklgMlDuI9P<;L2f38eSSIGn(lcw97ESMI)>^yaTT@ ztfnAOQ9xqecKjUZ)H`LRj>I;zA%H#T2v;RlU?i=zlPTE-x|Ko09HJMcbiFCGM^!1! zM41e+&UOa98=wCn-HGMqP#&9b!!_eftm%hRx5aQT1pWi^9da~w9*-EY4FGS3Fp>ut zsSQR9B(=bQ)7(MAsLHcDzwuhD^3@*hEZGIR*8@Kl(~vdvPsrf^`%LNRr#h@(BAmzgUfL z@(YmQPi1B7E1*Vx12E}o9VGms`22&iBH6jkfw{;Jb!itxu0@GWq0=SSKwrL4d%h}> zFi>yqM}T(7$ZWLd5Fr`ctNr5bpa1%+uYUBq<7AShes(1hHdZa>x0h;2n&fZQ~j_l zH}w6}T?y`7N~pEy66#RHWC9V~Y+-Ff@h$H2O`v zr8f!PE~Qz*%9dXdoAbpgCD|JT-VP z+F^PO_jy0g65<|XtT7%lzilx_{!|EKMjzcY1IO;uXEf<0hILEEN3PMd)P|+r0FFsO z1@v}DMC*Qbc|PrquxCljV*+09fCPovw9;~HH_CUlULUy0kx;m-s5N6?oe9)OW$hI{ z?sAJRYujbbUGC{(x~2Iwjqiq`iC%UYQ3Fd`w2Hen>$g1X-1;5S*ZqBh%w?1#EA_4x zE_2GsR@fBu!%iD6WdK1yzQ1anBh@pSg`kaFI-`Hjgeqk8asNAz^sJI`VhDhXAKZnU-W{;FsDvUPi^I9P?f9ogN2ZE$ z%x1gepjIgS@!HVdk9^CX&a$dj!nE}mmb31xKIh?WbrjH$A<;&(BVTJWGOaBu1nDd< z5A@?=gP>&8>~xId7QaC&aqDmI<#v}CyHn;|tBH=72G7Y}i*+=u%rirpBtlC`H>kK? zQ~E(XX3E5fE%+33s1cZ1Ltnr$f2U+i2X64^Ih@=M8rdDB+DA#EGqC5w~4!v z;Tz45zv7?#>f!5A{Lq=cW_cyyfwt<{jXkK%L${~!;=$dxd&fXmSu|wPstR%cDEyYb z->Oeh_hr7mGk;+N+kgIbe$!*d?W3c;}{B1KhAT`hAzB88{A!F>YiGl;E3 zk(pq4Ofi73i>B;aHmdgTO;PCoRsqNjMr?G%z87HMJr9RgwUNl8)=<)*fq-xu?hbD+ z=L1?#y~|RM`PM$gvERs5O@8@RwZZKPvT^efl+%jk*Tu!(H6`Sz(fsCF&}cs9<%U!R z(M0f#V>gtsmhw&^8H~KyfrTJ+gB@|u^ z3-?Kk6bXFJ=8gx&VE|GWcRV*I6dJuzI8G6>AxDvhKA^`@Kq8PJ=^rKA5Cvc%2@a>> zbC(UAZ+gB=Jn4GhX{IAc|J5WsMU4lX-MYMbk`_rEmp!g(w$l* zoSqiWvU8%rvpbeUfGLJ4Wzls&Z~LpF+K#QHqDEYmuGt(4j6ow0zcazNuwXU25KM0?e1dLfRo+lcqCsGP1F!jIy=~I~ z{|>hi1-AP2p922y3DB$OzZ@K|xGYe!WOaeXSovx{Kt{Yw-gwL8O=>9SRq+k>=D-wR zkd|v>A0KYlp$?V(jJFWC9%i~iEl0xYV@Hpj+U6hczT6xD*`yVDJ^&8uf)z?Er)a7drpz1J(8U6p+8_a05&MTO%Vrl4e*1 zPeiA1X=-avdP*cH#XJbc@r47~R_S%|d!#G8C&@^1IGm9lR5XAu#Wz5xa6I?XjpPGL zj}MJsc<}us4H7j9p6BbN2@L41W=&GSn!Ffb#$Et6r|bjX@IYVZ0Mxqrs`;@-PMS%n zp>vVMJr)R$frpd^-7Q^GjlQ`h_rfbbm49)tVWGoIv{>+{-7E`2)gjbc$YTbWczD!J6wckgc(Zvvp?#Me&e=3)_8EEccD zVzJmYuTw0IqhHG)L6JUFJDe#rJfdCAR&Md3guKYPsdeA%`SJJg$Xe3X&yHqQ*1Fh5;k_SFN1@{j8WGtEuY)=lC-%BLDo8w?Yr_nW~DP^8C* z7M(jJptL*c%G;uSG=l94gVktqeIYNkx)4AmSX@Z!tt|@5@xavuB>&B|g(e0=mTJ1+ zXt%lC(B10_CH}jsY5}t1qsuwr%Hnni=fhoHzkk3`QrX8}Uqp3$g@p}LO|gym{jPOJ zpx@g{LyTlxJS`KO8Rb4fc5*k9@qI^1&bDd$4+#q*ROE4orK@er!gVyzFuzIsHN1ih z{g2NDd2$WQ8a&AuBq1{rX#q>5M0W{2f53P_AH_TIBM(@*u^6%8hH`6s;lifLWxSRlRU{!rI`l4+|Ba<`}l*HUS^Rw=nvbct*Y;3MWt6$*a%HN|5cYS zySN>}et+z4joa?Dl#SfJWU9LU6>?ZYO)Hi(NJ>YNsQQ(y)7O$4)}s-}M_%?pSa~>d zntWIJRP zK}*8^1?`@0Iq2;@+jemBn5~0#oHUD!x9%lp@6)=kN5cEuvn}Fro3oy`Eof`;sEi!u z2G{AYkpG0NDeQ@aLDi<~7e|UN9X|Pa zN)?iSIleA591!M7k;_DW+~Zy->Sy4}VMM}@#LU<{sWgaTgRbyqJ5& zTPZF(H1h7Cc11XlNQ;Z=Pvsi{1{rtB%54Rb^oSkVYtG>PD6;X}6^!4B&EJIi{O^Jm9}y<6A#^fRZti;NBo zL!>9p8QzT=$afQVH{kGdTOb`Wg$$BYBQ^tpl>4Z5B`h{%TgU2bQ3nQRNDAosn?u*% z;{8UrFkhXP2e@A&DK$cWlTzMaZAB(SfB!YLTX4mmIKk|2vyMm=l2i8Pxi_zaAxO@3 zs)<<-j_!Nxm$a$H3Hus3X~LMK9i$NM-K2zlM2jZbOW~687f{$!oI2cB1hQ{$SrWtk zN|R`a+esAF@gSn$HlZ&&up2g9yNn>I8aZ)&Todc=l62^DWf`i{qrjItXxY@gG2w}O>c zk3AR&PqElzK%Nj>d}p(RqbFVJV465ccAgX0{6qw2$L?`QZg-mjG}vMuu}^L;uiGw#^>3-MkbzxG;()~e>wnnQa?sy*rZak~gX`tFtY*_Y$iuzAxh z!eiDSRBFh^5foq~?C&^@d^{r@k9U+Rs|cCDt^z70eM!my_;@sNGvgijf)A)FFC6WQ zkx)N&civiIwq!ec`8Ycmc*=Sr^Ac(`S^TpZl|)0a zTH-WN&M*bdk)#uc&tlGZ@hC#RQiQsezrR1tK9frJpA^vuavWRUJQAn-Z@d%a%OA5tWmtfa=tyBkT93;$VtDG zxvGz8#D9Zytr1U;)^MW{*jD=+kKX~A)%rV7hI^n?_VeoMrfz_v1dd%m)8R@)of`>Q zM+RZ;$f09(ykW5kq2M@6jX`{5*|W9dKE8U}{`gqHJ()qe9ISd~-7!}x1nUYxmi5oc zL_1{GyU-grOks)FO^~8wyq;B-WwR^ed@MiVU>=}wa+QhYB){6K+RlRV)(tz#0Mr8b zF_ug;!f_V6juT!v-B~KI2e(?B2uZ{j;sivYQxWsj>v8s<$W!`Ft;$q7Ik~>umqmFpfBa$Afly1~Lid+S{}TF2nTri7L_Z&dk%sTgL1f zhC(*VU#%!9?m?q~&)C~;ei2_2mv&ayaFSS`>0+~*f|%sF{yt6u zL}Hb}BdQY)#w#Rx@Y1Q6Ks`Ao5i*^aDK!6O1s+4DXUVNY6-KS z3VsiSvjX0f%I<4BuQ(W4WL@=pxpaHk9U1tek|R^1I^IbJA8J*#dmV|wG*O-}>BaT% zJK}KNhgQVGh}8(E@mV@ROWTVAC5i_UH`8kd^Hwfw9TgaP{gsb3&jW^q)K{(aTO=4T zXFlsbg8b}*{<^4?6!L1miYRdZ0DvdTRtkoct3Z#-zEa|zPy&xK3QwE#C_};TxFvxJ z3A>PcvckWcIeq|;z2c-f*)SzkJ|x42VA;UO|K{xHvkfM_^=pf*ZU!A&ScK9E8<*MBB}5kSEyn%>_xFprEWZN<%ATkV9A@gTMSUB1 z9}8m*^gV3S>9(xa8=Y}m162O2y( z*%3*ozoy?}&QQ?-gZonY)~-vJ3>g_f6+l_Ttr#vgo&a>bqhB$cKf0M41ykHGgdXfn z-K>jsEF9#56L|`H=P8`iWaEFfcv{E>VXe=+kNn-AFz9|t(BYcIJBG3| z2n9a`K2ufT*ZLPKB=?01tDrWcy6WcO49!dBgf*LSfh(P!H-ZwBNw*D$TQ2gEVkDC% zlgS4}%q(pjydT$La1e2uX}9t^TD}_@L9)3{Pc_Daa3A`F^c)OM(QP7sXFio& zcn-MSM@1-1OLYh=XRdNp^RdK8zn7ki&VQOo$bga`Ydmtc)lOFWi!aGh zWiqC+;?Z}yCA99?8q@u91GT4fj#~J^U2L@LjHoNrN_&SLiJt4apallq_$Q~CB~SB$ zF+_ZjS!qh}h4Hzf*m;?_#)Pp!R`sxJ(rrcsP}>)J|77s(Oium$WYDegVt9CRr|i(6 zv-obyyL08>B%CjvV_(k1`WP;ac#N;9Pu@V+-1KJ000tn44PMZ!P4fqe4;Z!uAi{!J ziCBu;YNb%LCCGsuBp8U40y#X8-==^fBa(lgq=k@a0=Eu4yXu$Uc#AJILF64=`mL5e zk(D_6re05dR&LU_yGFq#Lf`zGZ~pLmFqd%Jr@PPRS)57!ssnG>aFOf+8eho%NY1D@ z2Ym=fBbFvZgybXMk4y*=pAEm`#=dk~Gm>t}Ejm?DojAj4M3uAGa{u%|NYLW;Ly6Z5 z^ovyf>O^s9TA%8A_ZOt%k`Ma(l$gS&uAwsVf}Y zbi0(SINesc?eczYDqTL{gG}PgWV>iG89pSnK4!5c#p;*56&`0xVX*Rm>SwY|RWk56 zBXy9~gMjD7`A?qb?H0R!2>){1u(_wmmC|*l$>2PB2>licoY!Jp$M(;*q zM-*rw%}#yxvgg=eqzjy9k{q{$wd9CcUDc_czF1s!cr%RH;$0=pf21+zI>q{TAbaL2;9_ zvo!6;>$Hcgc_ zOw8Z<-5U=NsU$nq3=h=cu+Sz+71(-=pb*9RIKD(Bf&EnX2v#6>&xLNKJgZzlUa-t{ ztu`f9W13MUxPU?JCx`g=XDe~8(G!vVTw9$5k@fD$l2ZIe)*2)St=pf0CD>C~QEZg< zXLcbw(>2(X1okvTO!GR0Jj}3l^w)RwaBdoMN?UiBK3w(wj5x_;WyN9oaK-!c@Fahh z6^H4=74OgfqfAj&>Zc7N$kdlX}>r+4&? z79cge0cWx3yo2tO5A2~|=V>R8<3X+>cj}Cnis@lnU@1z|Z{WP9Grpn5YXB22uSI8i zr_jD!^qN7CV|(n)O>yh@Sg)7?;yg(md;JJyBL7Nf~fv0 z@BqkhNm8%%#o2hYRG=ehm`c*f;MT5KNR<9Pb9SU*b+c?mA&G6I3IQ68>hJnyh5x%3 zto-X*i@_=qEYz!ll@hM}g%QF&Xl(%g z6PJgYsL|Odr2WQ6JIO@fc)QFSRg&V6G4ipTh$SjKe*12GKJDh$hhzYGPd`|Dto7ta z9KkbKS{OWlnt{tiFF{@hO8U3uQsFVG>XEK+B-PXy3^u?o)?d{Py=~AGsxDABI_1%O z+TlcPer;fcFjqxM9J6KT5+aA1`V4yMMg3%+mm;V}l$f#sb*dK>b?0MSVGD#cig@VH zVH`PiQ;wk%-y9x74pZ=@%{+dlGG`xdN^A-xzMkbLQcDdw(G~MVo64+Q?jklrjhfoM z>722K9LPO7)z!=reZ0!&irf`1oYf!^;8ZJvsLk$Bg}mk4Qc-VUIC-`Tnk$x*$yVE- zUcvtQ>TEf?f(>eK{I*+3)*KBvLod$y`8^THP(G#2K`N{y z`fx7eeJ{NIOEcljWx-467Cp}EaMcv!EZeWBRIy;Mbk>|rA{!gCr!a%lZTW=AW(!(S zQ~2F#)41jQ0-SAN>xxUqBTO6Anw9sGv32-|G7cdtnS5}-dtbJj`3f5Y7e=-l<(ymZ z2!yZ_0hPfO@V;c7_UgVV7sW2JsKOpq)KjjMdgUD2y$%jfvZlI}fQy`POSY*JiJr9l z9^ieUU+hMe$J$Ng_)x|Y=jPY+*VU3t-#*SFty4|}9UP((UHlME z9T@hXZAYjwk3C&N#(aR1PMUa#jtxM7I#j3(4_d1L|2poUN(~CSY7X@=`y&2JfY{=2 zF@KqwV_^^a{T(W%fON-X3b|TO>p*qPtfU!WaJhv!jPq#`SL*y~)|y_~C!qX#NlxZW z&eE80*c%jJBM zIT-f~mK7I#cB*mn-tCIe$X9zA5tbF+_LhKz)pjQ0S-jsF$>$(dQzu8ZQhT{vtol8f zke_;~;|>rN=7qCCR&s-!^MD`nhzfE|UKHHkQJOkswt(J0TCp@AhAs8IJ}q_fVMZ>E?1!3;q%5vCcV!{jv8W0$s#YwU`3mmji1IsqGwtn-+( zv8E=&JJ3v;Jo!vP5l}41c@27mGhMm})$a)Kb#aZ?OF-kTF@tAZ?#I}M(Z^YvIc9cY zzo{-|cIP@3?tG5rA8Y-W`=asQ?$eVV`;^vB_)O4Yu-&|q7D!{1<7!*|#Q3MhPv~%a z@%F>p#icsSwqDJ3?!I9-dOC00;uc13Xgu5&;2pzFy<#^)^n?>em*~B!EolfTp(+Yk z@JvZBz40l*6UJt8Dvz(VtaxK8Rsv|fP2Mr=kcwPT5_ZE2iM`M;WPl~SfE>o+KoXYJ zMMoM7gntXx2K&342W}JG2DywTP9VLV@kCP348aPf;k|rFb9l`XEA5k&)Sj~)d~jhN z6dd9qVu&t(Z59jah#eOQzBh){;&yP8KTawTGKyI3L@;OU_HiI8?Ebufl(>@ejGo;A z@?>VspHorK?Nja&s)W)$m@l;hh&FF7%1cyA`WXDgyK+~)Zynx43jDI#6tiODHOMe3 z7kJWbx02o5(E)N=Y&8?`IJELLUuWVSM-Aa=RGrsHTxf(G{$=M3z|${i==F?7Nja`? z-0dv3>H4L}^?Lt)hq9{c6=WlHWd0`)% z6CfEc=eg}m(Rf2;Wrniqc>=hLd5Sl{QA`aGN^MatGQEhhV)kj_bJWW>i%tW|F$}&Ep$iyq-XW6 z6b?!#@UgF!Q0YsBq;Y$qci#K^+CB~mr-JXZj37X)eQR#e%t&P@C)qr2FE*F6xhqjL z+RfrT6Q)Dv>XxAdc(zsc^jxntM)stIqSKAxO41D%dg%7KtXv*_u`fb(EM+0ptH{)gjFv-7%LbZ2sky?( zz`TZ%Z`jWKG-VopN*-xc9od!^?GJdp2Aq*B;iQO^WqXM1^?-Qk;np*umW&~cRiT$# zpCDs6L>+Eb+3aM3bl8dxKK6MRTBRtnS?x%vlU%EGMVzv&d>2Ki@9+6XL$%z=Id3-( z9#6Tj6zXT2BPpO_?S6Cr^f=RNVxweE1DW*zXS~5G8h%|_{6d#7KPGc5muTnBr2gNO zSmojD3mYKFn-Z)stc%8#*wB=$^inPHB``sq34lrCd|9@0-kT?FFe7+?RNIyl2Nujq z#FD|hvgt$6_L2I?LDWUARFF1JE4gQXfy3^z#2qt&!wCI++AdFu!V{%@?qwJXJQFpI(jRpIf{c(FHzG{ zO?<9)Wv-7-#EsBdnJ|vNR~bq=B?@nhZ=BKH0J8JOwiSiAu_B)FauL4y!DbYH(&82y zV|mBk5t~=AF{h>5t!Gw0U$0jmv9qkPQTECG73~-YpqBTC??F{xKO@{Sy(oGOt%;$0v%E? zio+}H!}%6<@+I#Ynyo?Wv)00mgl$29AZaHTqH(DB1$^@Sf*ddm(y-7_9tE~=y8aM_ zt-Y@T9_|JY)ThHolO!gE%%vz){S1?J6TrxmXO461@ z=Ti06d{OL6)e^8tsw|>ms?z9y%#p2qO4245&>hL(PJvd0e@RoAX*5qoLs4q-^kI5f zHJMO*TCI?OOIx}M(Lj^gurrgwQ(ShE0!OSTSFc(d+P|b?;P#?5{*EuDmQBLfRx_nA zvU=_K?{C}5Q*|j^qg(yzYK08Pgp%^|GTX+~dR=W*wmo@aCp(m`aVth* zHGT*MlQo&d`=c0axDA-HPm^&S@d#b6duG@?&i5^i6wejCf!5qVh@|4SXYg7>ZVWqU zBE6~VbmoJ^{M?dNT-8%ZcH4+@)}3kP`T3X_GwdCj=XCElvA;=SSt{is7Zpen>KAlG z*%U=xaIf$eVc{=y;mn^LCKf>{8b2p+0B-t#wYR3XZ4ec=qjyaCPvBtVT^pnDx<1^9 zqRs9^aKeSJJUGc&HsDb(S%QEyNW~hc_wIG)McOm9kewPx#jjNJl$aUN8Hw*0{D;vguV<2x z5(oG$SC)hc5lg?J(hd+zu>;FK~2Pspi) z7np?8NLgb&*lsmnW9Ok-a$S_mkFqb4M)-OJ>_E!7CaM7dW1g*FK?rbYzWowqS~gJq zaR6I}`R~Vgr`Q%>t!nH9CEXU{xfwm0DDb8Gqd%Nf52I-HiN570l#aR1(I~^~*>iRA zJc;Ea*c4v?W9#dIX}v*>P0%4vfGs?62yzl`y z=MY_!P2)M(ZDB1W=Eps}GqoRL;(t|s2TcpATA999REticNeEmkv5cHxP@Jp6!S?QWhf$!xUm^k5M z(c-(R`Qt;m=x*?NQ$VYs3UFYRcXij*x16BD0JFA>6F8m;oaXVzcliC0e_a;@)fN&6 zjl>t867d&24wwHXZyPHlQsA%h3O|v4u}o-n6%`f*lC-mN1qfkl-b$~&{8N$BbueV$RQ`c92txS2 zzvth1j^B76c6lj!!<69J=|$h|Ui7nF2Zt(U@ZE&SxtwDDo>)g`N*m{Id@(=#_vPgN z;`!mpB_nzwp)qwI*M(4 zff4)rJ<4Pu#@mZi#yEb;0Kj=oIIk&uqMZsZz8FbNi3s<)^~L*3y;t@^$3o9_j%n{F zP7AHzILQKVn+4)fRNG#X_&K4PQe`Iwl`+-RHds(sklRewE_M8QcOkx8*HKTST8L z@F^Sr(8|{x+KNugAJ(Sn)EE)vt>7YgEsB`Ir)Z2gZ-(I)*aO06IVO92N)_}A{c$~1 zrG)mgsE>WeGCAK)uyM$Svnp)7Q7wy`lS)!5;Ll?iwJ=G{Zb?-aZv+Ch25 zcU6&-EoJId%#zn?zHSSprMctYoAwV{ujNg*yxb~Wb>C{92B%vibDiTFLs~;v#^})< zdMPpB3=qR&y-}piOB`_GYza)kRaxMh#39DLr>AcFlQbbh>vtNbghgCzznebxt;!ka?!r$pz{lZA;*IBmVU=OqBB0I^u*qzry{o&d1?dYu1v0wB z1PGjoaQ@^}S16bMtNC^OouY?FH0gLa^y2)-d|+O#YB1jBNS;!U8-7dpEB=7YmFM8t zeJc#6!pc=ni+jg%FsV{tU(KeBh*+ABDufk2K;pKu%_|!SXQqDx#fd0?>@`7j2kbrp zdW_-dMWPDB?qDl)>7i~91qpvxSds{fL1q~!y2l--KBraHodlG=|X622hYVDK0@9MpXW=NvhcO#rOwy-d!l+RJpMZ@D`sCA4u15O0{XMkPT=ZZ!$uVV*Tbo5QbW%$a5DxgQZ5dR058fQQRm<2+OvT7IE+H_8w^b_~VH zSpB`k-wXV`P=D|6_YQxz{C7Je=aEaTy*8?@yX`o8d-3-2^7uN-=rA!`p7}~&y!zS9 zmUOHjIX>l*1@cAdIn}gz@UB_*yldJ_&}Tm^l|+D|Fq>^~U@7xfw1Jz_CF)hKE?XKdxP7%%cPgf$r5|#rxYUJnKyF26Ad`5EmUa# zO4^|D4ncMWW-l;n@9c|gN5d9+z*U!UKg$W;-ruKZ0gsH^t?%`n)9h1w2Mxx4 z@g?(~7YqJSGf_;g4&yMF=l`}Hst|?D-%SFdudv*5v<} z7NfzD_WFkJXz#FFl3^Q3wUG@rfz`)FPShw~R>1jol5lB#9`(%8ZwkE+c*M4V|2=9; zh`fE95;gfxVs?%D_r;FQZg1Rx-4io{x$KP@un)w%e~%dG{jdj5REDu@=!am(Jl-EU zfOp{5$BjN;2RpJJ9a*XwciKR~%UMET=xO$G1*Dl!r9&%r&BxdJ5?T})Ulg70VZ;n{ z`^CscVe7;IG-T7pZy`?SpVdf|58EkYkZ5xs)#zrn!^cW|*YxZ!+gxLX9Y*^MH60$d zS=g5s?Im|7Y%_JA@9fhOq;EwJS6tPbwni)LM&tKYV}@DkMOiU=F4a&TJ`KtBp%GI8 z^e+g$VU+UOU*ch)tr%q#q@LV7Zh@S}UihIZ$VBKJ@BSWVoT}}xu_8y=N}P8`(nV=r zOr0Y2yMLfpN95<{w*0OHE7y+m$^jo72A5J8kBf9Cb7XDbvuZ6{sE~+)&bSsqU>4;1 z@+p1YpBSz<6T#ZJla<16U@VtLTh;)YgQChHbE`D#yLbqnVL5hsQK@SRy}DXy!syNb z0-LYY#j-%tT6FU}Ej^v9hD%pQQ~ozsX-UT>r8|Yl5m9e>m^?J?pXFK|>ByU{sdtK7 zOaWjQ(<^1MmcoY50esRMq3E|cKo*`eioM>8%p&(Y&JDQHf&8!M)%=?Ln=*8dF$aVuFJx?QKA=iKKSGs@0z9V<9go6F?H4i& z%%PVObz)g)R5p-@Ex}wyr`}@b6)Ijjh9gKbh`jdL^uWizN*{?Z*rxBZKEUu44uqw% ztCzII0Ub#OuOddgvh-l9q>Y@c3W};|JQoq<15VB+3VLWeK9J-KS0mLaBM;G#{ztJT z#`2sGS75MVVyyooD_*V&`a*}4??;*51j2IsRN~_bHgIjrhDsxS(LRL|1$>#j zulj-QlsVQ5wwfK6{am(X_!5VPh09svkwKlAhQ^Yfp$-BykClDyYfkdZu)SVope+@w zFRVB0)alDrNv~>9=QyMJxCyI}mcKy_JUBEjQBUQ^tf`bg#uxQ>xMH;*E|fZm6%K`> z%?ll+;&=0p6d7R+gYXp&Uub&aURAR>I}E1}YYHZg*)-$NXQVQN(JK8uJ2|Iro3{K> z%e!n4%ij`YQaiW8&pwnDte!D|=pva!2u`Qc)xKyBvC6FD-+U(x69kQ?rvV7zyC?w)p5(;>ggc| zeZ_Rt*|~}iq@+zNW>QqET#p>-+)yKF`1 zRm)JYzaMxXH%nYmFH>RL;$fHLDD|WWvG~EUTo*pbP0aYP3do&tAMg8A_+?mg!>77P(zzXZpeDz`eu|?sa&jWuz z)4Kr1dg2*|>-(IIfXoxjG3=&Y>=ZCycJP|`uEr@qNor{{zx4rm+^zweIy@6%>5lQ& z3ruz{)qYdZ(L)WCt}E??k(<4%CL2<@R}EI!0=>u;Dx}FOZIJEZ$`qcVnr>?L2rOU6 zwTT+--f+!c@OW=vI{f0iI{gAL##x&<+G9WS%U?bJ{V!jB`^!JRdGqo$N8{FuWi@AJ zWHFz=bj@e8=}XrdI?7x^9I3V0>jUgjJ8Ihs*4W(ONEyySpS`}afDoY*Im6F-AsO{I zXlt2zf8U!`tTPBgayj(=p6uawNgoM9Gf}G3huOD%L0oR$H}lphG|I#vF$&{&2UtI} z7B0sI;lns7`?nEq_a4$f?dzh9o`YsM9ucPB;}$vR;)YTtgZG^;Q2~l5Da`?Zls4MY zF((RdJpyn8v=F>8=LjAnO3vaR*MoC$M8D{0eB4@j2E0S^UhQx?8> zEXBK?y40PHG?^puem6+y=F`ibd%i5)oYr$G>E-zT65XtI&s$-b8J6+Ay#+NTvKE0q z$)Kccv74%c!S~a?n%|bIk8Y|C&F7_+Rgk7FSzEFS@zCNRN_2NOAsHM;&`rRy!?Jv% zUB0zFN?y^SR-OUfoK4FQoaR`XUqPPu`lXv`T?T_JR||wZkE5ol__IM~ zSJ$}eUSqIUc!lvb=bfoqHocFYkWhbqY9{q8~aZ@R*XicHG+%)S|#Yr`n zY9$s~6#?j^Qx}`U@}cu7y_FOTD*IO|=cBiqlaqHp8%@D(@D_B$0us-#Y2rPcdCN}93+=mKzt2^^8D3Lp zgDjH&MfPJD4(LErT+dcWPStBlmzIiBBGFbzF~k!uii9}!R3}SCUJ=)RF)NkyW$uU6 z%aS~~C_bS|t`i%?PDrJRElBA26!Ny%PUXoU{{X!j_5yV#AJf))Olt63si7XxlmFsh zo06Z|Bl=+7bS-|}k~#oM4Bw!BI%V~z#%M!!ofvCeZOwG%lTwbPzMX{1bXJ+5LQP&= zR2=S$Vu?27U;`)lx2$way2fJnRD z8an1~6y73KUnv6$$&;OdO+{v;6hgDHwn6O4w* zQ-^c1#y#R_!JFtr$KQ}?QBwN?%Y{_%hsXTT7M%Aw+ z3-2zP%gpk4jY6k1Fk)Me2}lq)>_u{o$>Hx8AmmcJUvh*TdEu3JL5c(O9H&|!?I-Y# z*=z9o&zZ@!xzz4-f1jM|QJL!ToVhd8E2O98xfzvd1ZD2v91~>g1WF4g24N8zKAZV7 zHdqn{H`g7`QB9kwyYuP}Naea2-mm*nmZXvs#76VDSnt!NSzd@D2jex#nE)u^(>+dL z8wTM709@M&EqUCW4QMX`ub6$lk$*KLzMT^Ik}j}{j3ye0y~IuIiUO{_sB4JlxJcQt z0&lgzb=_~CBo#2^MXmuo?WVP$s{PzLiTM!**?+=l~7YKqR2!bGZ<*q4aN(cb4MUJQ7&m%Fuhpm`U zecZQqqpTTFBB-EFrA-BXy*l28Q-{c61gwc7$HLgn<+AgtqM)m^D_YKTVeRGcP0Xpm zy+$P=*-O04|z;jsX5P8Pe`gX+~m?}l1Vh@ zBH8M@>=L%UV1H#b*p-RVG?4mPF1mPb-t)2$>!cM1hoDBKR~SGvxZC9f3VhPk2~MU4 zJ~6RMw}u&4YtZX#2}@dSl-ZYk6OJQ7-6?qpVOZ5vW=BBq+C0C4aU}%Eu^;R-?Xq&jh)N6EI?X;d8r*w zf~&7gdsv|mit4%E+tMw_F5Ek=9>+~<9XYqaOrr(uJI;)-hbU1ZZl*p$QEy4mTX5*?OMO}Ptg*sPcTYdS9LBraa*Xp zpga8Ov|T%**|HhDH0TrWTNqo<<_RAZ-4s(Uo%)4a5e*MQyWUJ^cQ%G03woN?8Fccl zba<(A49=zy`!E4GQNlR#XkrH7s$BIGp>a26?fUUfL|+lC?pI>X@KTJSGV%4>Vh(7c z%W}Q~)Xe^JBN;^(U3fE)t`TB6TA6tm&VWcc5e)w~?OY<-JFdQVhHhIl!^Y~!5G!1R`DE~_9JwV&j<)Pp$HxJdaRHGQL^{rYTNv3#XI(**JT@@y zNWqt7`HIjEhLn^|p)|#G<<^@4UPCkM?dWv#m z4z`F!KEZ4X5y7X3LGcWCSd!uEnqxCKn&^&PK||JW>2$KwkJEGxp`&@f)kUCmy8xMg z2wJ?sygmCt_Dz({T;S8C{_=s4TZiFpzAB~Dvg<=JF=|c{g#3%`1S^w<-91nI2<*G&VKswPpNjJF@?hnN^{_&KGOGOP=HKK7*`%TS(`%-i&ae->M+x zw8dzN53uVxHF@VsQvvmyw+B;X=KQ46#y&H!1;8#0=1(#SbqblUQwS_`NQdl-Ss=`S zM=Q!(2m;a~S|&5GPE03S-h&Lb%zsM>cfVum$A`B<)*@0SIl7aqyun0SUf1d6ujw3u z*2ar$%3fwy=&qd+9A&U=CeYNIBPiB^QmXAYIE|}tF-9Z`^jM`y!d(>6LKiVHXD0~VqDV`QR*n({N%wohR;<{G?Y;j zB2k?rQm)C=-5(i5{@`Keltk(s{7-f9kRo~_XmQAtVvow2OKxGT&JNIxiI3e8rA1M$ zQ?um>3>8nkq)0rohWwD|L_VP!hOtTSl>5e^+z0x(o0Td`a75|a9ML96?kxI-I=xr} zHE^qqMq6&*04ZM3DO{BS;InLAR%wU2P+udPL!ojB;PpQb;8JiAhVVirY;fjiu(^X1 zO{3LSi5Xh)EL45?*5*HsDXWJg%X4vjskc31w|bn9U%OVXC8#CbTD=|&?8(*u1< z1~j>3P)I)u>Z$G|`Hq-7Cc}^E&CZ#N=<}HTLe)#H3SQNk)|MmK2Ne0k4F9nJ{knA?l_U(jIWJoaFhUb3 zba-#;DF>EHNQ7iqS*)ytC*UFmO^c2!*?SwIiMaKi)2&pQQA63o5N>ZMDyghEb0}*K zHZ#q#zaefZ)^1bNPljVHVgj50QstMG2rBhiZn%dA{QNG|u4ZuaX3l@9E_9eML-;6( z6y(Np>basg`W)&h^7UI$DivKLhv>euplLXPV}kUgMq@N-ACrSl>4Ke#JPw_twDhDh z1}R>ve1e=b(4~GFNqG9yp_Hvs;MgBuu9}u4m8D1hFo%;T0k_s$af@IrGjmr(8aq)c zSwhKNr08mYaO>ZV3@>toUGb?~q@8%n(}JPaIk?t1cx)|M_sKv5 zv7bzN)B`Q!Iu*S$gola%;W|TGYI?jPm%+##RKu}x%snkIMYVPc^$v2HwrMTGw<;ETzaGd^-MWU3CcQ=t?4&IXA?G6pr!{&sVzN>lN^j)Gm84m% z3VTDj{5(MdP3(D=FB#-StIGJbS--3Cx^;5fJzv>N%an;<2C*9}em$$()3fW?xvfh| zvN18B+R2m{@I%t(7+n5dR8_TDBgdnS`&otuf9)7$XJc#Q1sIGD`Tg!J&JnOD;HPv~ zd5AM=2liXW*Tg!Qe6)pTc&YQD?JPc!5JaOB*&AELS z0t4%E7Rzq@lP{j=8f+c)Y_akOoe>HFqLM8!fQbbKbrGoYt79i|M9_ttFrK!^U==Q-l@R^K z(>x*Tii@@1h(r`86@m$+giaV0%Be{bWt;s({8`a~RTnu3fPFuZQq%!CnT(dB(xjf& z9TJ+A_wtjHPONJu@7)Pj)N#Pn<@rgWxd&~JVscu}<+KSC$r{L1qp(@29%;xL$C zkY*dziB>}?%AkSj5D+ysC?TLtqe#P;G2SpKx#+dTNNVUx9VgB);?nMmYjG{hyM(%x z?9>3k^HmQPE+{TZ^l}7OC_MP;^ye2poqqY_xp*CLV_b@MdXwmqO`YCeW5C}JtOv)f zScp22aDv^6K9+?UGbn?-9>iAz#`$+8BJdwC;CwyGAaV&dm8v=TUn1rrhx67rmq{lmHq4KwQ;W4FGUU;mBGTh zP-*qlZ+9iwm7|v%Xq);+z76oRtfSowkF)UuQFIz6O0{L!3~pVnI4pM@90F3e-sM|R zr;GMZ4$XyPa~>@xMaX<)uV=M(pYZ~L5Ecik@ZfGOHq^%*dGNYiDfAQY&fclzhg)EV zqx+dB_Ig&lyyBH|Se-3F0Gvm=26DB2XbCi}n1ctq7}-e+V{(|OE8cKpt;MtZjay+WU=FM)mKFRa*ex-&H&#T9m%?l=@aZCMt zm(E>6qB_}};z3v{rs_X%udgb)B2&^O1t zl?CrEJw9e^ti})!_Z(eWUkrNF~Qq&^Tl3_&$ za8mXb`pxj38V;9L`evr1a5(Cs753xrzoYWnmaM5^t+J}M@zQztmdMmXLlMn`gX5!5lAk{MK&NxtFyAt(v;AJ&_1pI||3T{Fr-pNdU%qN$gF{G7A{A4Yba6Ux? zh@$=XQ`^Rjj#&-c){LPEBEaCpbD(HvFKSV$f!2gO`qY1nT`b&ARV-yH=D_^Wo?;~% z5`d_7t$NeXLM;<#;#xCrW>^JeKMq>q}Rgyfk&mrML`A%B7U)G=z54 zXoE;Rdr>}f;11K`IkqRfv0!;_W3x)bOZjl&o{#){Y&XK#L5WlhK#L@6uZ(zOZM z%G&GeDnaGVU>&lOs?ADreBRIoB+4b zQaJpJ`%y?~C5V52PM@JLXq^w({ye*}}YUqtMVAH{K$8<&SSdNTn5uXQxv1#2L zUm(rnr-Q@WTYmEf%#nxkB1bywqK3nFG2i z7{uAxuuepr60WUv(ALpJPh>t*oe2DQx9{&k)2bKhP`#irt)uD%6wfy+7q}(1Q!g;P zY-WEQv((;RFX4=#nNA{R9?h+un=NgoyUe4ZCYg&s-(lkairNDyf49;jJSIIamuJ8j zWk=j5d**VJ9;IrVD>oXz`8Tr{;1lsXsoXj~?wRN>Df-2iGnJCg+bL(?*|dkPG}(rs zl7BdTYU|n`jZLZVzdb!W_mTJn6S($`;~XR zF{}=H)y*uk4D}NUC=_sP;R+-Iaw|uS0qj0{jo& zM@7|jZN?1i4z_VcKzCTdC zI60UfLc?b+chGnS3kbmCJZtzfzoMS-K`~o4o;?e^C|kuf*y>=qx#n(f_FQN4SF^Hm zX&&wzbyt7`qTLl8{VoZXz~Lvm!7xtE zGzY4@eav#Lg4SN0*FSph*&dGZKI8zt%Aug&8CK;SuJZhHS9@*G&FI<*LN5S`o~QyB z?NAw^1utI$=zg#Uk}D7G7DFpBbkHFb-b`yj>+Qfg6pA6FrigZ?;YGQN`!17v7xl&W z?{_ZN?=RLn?=R{P_q2gMHCE*vUSZ~*C}nGS)3!NI5}G-vSrZK_$!HS@0>ba@(Dl(@oZj%?VmVd9@72cY+mZ956MoImtb1#W{F21k~xIZSJ;0{;@}u6_CV? zHT!eXKtttnn!+1RiC6%tbMJw<4fZ`v%MwzX`Vd0bGV>iMv>J;Ys%?uKRcbO1{C(_7 zbV9YjH8M<)*U4=IeS|Ku^=VLf>~IV(gsZW#k}O@(YGuaXcFkR3Cv-OXFIs~CV;0|T zu8Rt{Iwk}@%l`pWZGva(*b1)2@BeHHZku$1=-#tZU4-Vm1@upuiW|og8%@SD+Z>Az zHzD5$d+plfprQ6HS}1A|jthY(H}k?8Uj;3vK+POzek1E!9z1B381 zW)NPtd4gET)UcLGj1?~ukvrSU#r;e)>rOVrAZ}x&8H2?aiiN15yJRyhVWBYTO-+Ev zTW1ZX1Pi7^gVYySnA|(+OzasO`7{wVvyqS9c#U5-<=0`o$q@2H57IQk5~bYhU##I6Y-a$UUoL(d zjfNM$jTaZcJ;8s{5&T_VG~>rlM(}+yI!FB+Dg|Q+4HU=>G1KHtwdN8D)Pw+cCrN9iq9qa=L{5gg1Ibel9hlliiN`ct{ zd}j)&*|SIZovFa=Db+Y0;?Kc3ejlp9;bZz9QUL2Y7>^!dV7&hfzXxLqJUPej;fMlH zPw{)E0_O+#ol#(ae2(9J6?pgwejlm83{wsWw};Q3&ft4afzyXi&hUGv0%womd-#|F zho4}|8D)F+$>{-ppQ-?4!|ziHVB=>KpNG%ICHy>6re3+XLj*?-&KOG>{4aK8s$3LIEA5?i zA#_ZFmwgu|eUO48z!({T4S(aS-lIG0*B!g*rMaV!8$RcZQH*k8Jupa2!iw@>3wHBd znF3HnY#(TtC-CuUpz6N5YcqJ|v&XwP)&-o*pphDxynQqG+eQN^Vs1MwaRnIVY^^*oPpAb`NSiKe8gfM#zYU!Zib#7SY_F@p>Hab0#L&DsRzy2o%o6?0LlDeuV= z)zB8ju}}?6=(tQ8$s}ul(uk#)C!!kIg0zBZcP|dWiQEVwd{tx!vJs%}$6}nQWVwmD zqD@_q`Vm{79?-e{s0Y@*Y7)0j66o5oXmqFN@DfP-2JXbPdY2w_^N1rhQ4!cUFkI(& z@ucfyA3NRw_~vz1E#NuNuR#6+4HtnTlgD1qoI<(G-=m!ak*xEM#RxZVIEaDa=)o2n zV|ZscHnK92BZ(kO(b3jS+X*Ee7aLD%H}Y#7`G`pEAwv4HL9X+3(#7)BICX60lTDbR z;xP`R)8+}i)^T{0Zr0mwGmRlGyF`S$mdu)qd87q+*{s)PK`SpjBmbtXE|qOfd36P{ z55AV#6Ll!?Onb-I&`~EK6CKY1xmP>ua;MI+otv`C9z1w((l*Dbxf+TyLwtFvP~*Lb zA0%ioqey%|`d$ViU5z&VS`wyw44%&BUOb}pHPBGktk8ET<}LH}vvi$8Q7i%j+3B?- zY#;qRh}zcVE;lHfVuL`Z>IUb@*8B=4MP$0Fhc=Yl@^{ojZTAn{;TAZJ;{MuQkkH1k zcMZ&P+xxzHj z5rTinc`o6*5-YtXx?dlSG_KV|Qe<1YFu_~0%?cW^JXSadBbSFwgMhYMTPBL4MT)ij1f$iyUD z69U*_dx~U6wSgT>RED9Q1dv^CFz~Fupavd!XC>bU6Oq-z=PFjiW1$`z*Bg3E6>yy; zvd(FV>WT=?AsgVcpxUUF$l8q0u z8`D2mRkiABao@lzWi0vLOp;SQu%f-Y%8@XW_OI5;BYAIkjGf7RnWdE(`+CCZ(C3$l zpk%|&D0Qs@kQiY}eM;byAllOSfKLSJ;+%%p@d9`;lh0j<3@NNA&T+Kk=e85o`?7G3 zJ?G$RtM>9)=4tbSVX~YFSPR0Azi%d;JE&E#^V0U!O_;DQyjGg zsjJILx1=>T*zB|4Gcma~n;P3c%3zP^$qqleZrG%B2n%Z1Q4P%QxoETjIkE1D`rWkk zoHn__?pD&nhZc8C+HcfpfIUhuhAm?&FQdyI0Q0g3;l;ynaxdwg43%W}Mwv@`Y zScV{Qb9Y5aw$CH7Y|L^75O=i9@0#_CEU*;_BYqL=yQpo>^JTG?kb^X-pSZBDJ|qL8 zj?A8{Hz*u!SYfBNSDUwB=wtRR~!v;k>=ww^&InQ!er)OIahc^BR@fFWtFyl$9DK<8$ZC_@8IuX0st;Sj2tqb zm>3O;L4d>=m(ZQP?B1Ridf*PYfoK}QzFR`IClYkoDqSdN2WIVZaTm$f&sN_Dh>c8~ zvJ1`|Mz2do8^rd+ZQ)j)e2^CKk0N0PES|K!#2@dbJ6kfl?|lUx_3{H%OKK(iLgBZL zdFe~c%7=+FxML2x))R+I-PHBWc*Obxy?5PS2Q`(+c|0yFb5O>01jq{2VA6D#MXKcj zD|7jznR@&Z&3#A{O*Updg|n_3LrhS6>6;nm#t4B|2IrZxe$*at+1an@3 z^6wcXJ=LZddd|2~gt2U`yTl*HZtAdU{k&3k`-Ab&&mR*L&LADrc2;-Cgu#t?1 z5HZPTF}AQ$UOY>%XH$<&S*t7Tgodk}=phub&gul-d$CoJX5woQ!k#dy3cum#R0BBt zKhU1|3JIhcZuI}#s_DkaJ$$q@l*Y*c1`P%DS%}@ehj}Ro?csx56@TQrW2g!izCt91 z{v`hibG_XQHX_UD0*Ti7P8bwmO&d z`n9@rR=F(Mdd!g!ea|b4Ea*B&@4J?td`WB+JB}J7E{rAW=G>CvzrjMzba{$qUkq!d zf9WJAM}eqEGJhE$St%7&YJ@OdTP9e^VU_@}Zfv5_WTtFO!~YA|@v6e5Bka~f@UZga2my%E?C_}4@8f-eMT|I-Ml z)HqHRj2XT$8_$~MJ&i-!0{QQ-bS_BKrIPr~`jG8!VnuNJfZ{0VS;#W31`g#{TUkpvc4Ym_+O_n? z2?OE3;#R5xS;&Sw`T%iiuf4TBG>Ix;-3gpui~&0kfwYaHwLKn>?XfXq z&oGY1y9?sWH`huG^yD%A^lY&oTud}OO-GZNC`;l_CkAv^6c{EIW3Vv?>ZZr^-$HC+ zr-u;tibnI(mVk(Xg*gaZjE=3kMSJF;aHHu15Mu{|D*0pcUL0ukCuU zLXK)Xuatb{J*yW(_`ZE9hpc@mM~yE}Zu*jzD)Ij1<|Wb$s3EtdJ8{YIDbmk z3mFBJ%2W!$jrWRWvTgfUAu7z=MDjPSf2&v0I=;X?rf(m7jvvH=c6MGlzNE|&@C7gs zL(*MVp0nUO1Eq|No0s0k*y0Z-Od{b?K}FWUtp~V^4tMbiSJ=463K4;gwd2h1NjIG(&&C-a+!U>ioIRw-&IK`cqM_Ty^Rj$*PLBnwrWL3KMV! zz^w^52VfglPVU^2Buqg;0S>(>QX`$XuIsI+iHj}qCP!8R&|ZTA0u=x?mhkO&%+g!O zgnzuj&oU!KiU$-AyvMk9ghN>#G<}E>nSK9(8*;&t^)mAwU659m&uNS~fP{Ci8oWX= z)u7a+7VlLuXp(71NML^7_v*r1W1~E>Gv4Qw+$F^yeIv%wG>#53lTEKF1HQ?DC)?Ik+`OWB4kUqGHdz)LQW(p?hMZ_WUPg&FN31jT}RE8qu;D zvfym{uq+|$Bn7)Z`Yy^O6W2!`#d%ri=+AUl${jCXkz%{&&&i z-eiTN&qGOl*k|yc`r9y3#ggo9tt{Nydi0T5)OB6RIt1&G0w_wh&EqMPVqhtCN*7)4Nt_PKz6E2R;@> z&B{4t1H;GLdO!TEEl;_uT1Snf2|%uH*J!>m&}~Cji<9EBVVFQd@PwmU+nMfTK(C9L z?x%=WpMb$&-4MGxb!?Gd^gL8eu;mIsqj8Vr3JV(1FW%BrN3#n%_T-8r*Ix2b4s!{o zU0uDUSu;;vpweU{R;?_I_)(Thp)o|I@t(ip)wtv#xZ=C^T0MN6(~YJ!$F&DP;#M&! zfKg8pizBBZ{gzl&E2m6BimrD~xyt%+mu1g4kkuNM>-|j@ZxxNNVh1;}uXMG+cl_zp zl`70G(gJK45LsN`SC#1tDXP*`sbi;{vS;*qa!Y&E%T79{oIvcF%;OBtg&A-$5-C!^ z2g0dS+&)${JrpVaija63Z*yQLQ-`APMJ!+lTPEwt33paLUdglB+J!h`BOssAz+tno z$c`gvg5a_MQE_Ks_ykT0)^Ehs8h3a^E+#(V6d5QcvpSz>7+^OOfX}A;0>vEx!E;x^ zq$Y3aNIk|f^-{JHu`A6`>5Xu*%mdi5*&Ol<+Pku8=7s(>3eZJr3-ikgJr_F{Ad@L8 zC&6ig%$wQeY=D`uTP{K`k}cg*NJX}qQ4}ErECZMnhYiV_&5>AM8Ks0-l?YO?l*U95 zI_ipwMJUV{oMv!xWR>(RhLIEMSN~j=E~WWlC9P_ILl_&Q-cYX1j}DA1_z>agprN?6 zppB^Px|x&h1~V5@16NU%3HBA0oWmL}nJKp9)X0&I{bfq2e6Xy@-F2QFk4IX8CWpqd zN-_(^^sMqk;d2`tyaK^yv%pmmQ50ETQaX*%OVuE_G+06i+Z)Qye&`9lBz|^5XzRQV zPIn&r9ZykOY3#@F-}(wF+I;jC(@yV0-Oo|h8XFK<4+A?CzyxbR9tH!Qof7AdFvU<% z1_j@MG+>>SxB0ZSvU8v;7|I20aYl=*=bvyaxaftK#zv3V0t@2Pp@Z`RO+nlMkmx6H z9+7y$yPy$z{eok$|?;b62<1WShw_3&V|f z!OA5UpeI9Xb{J!DY-`&1WHdRR)B_>vlu{)tn4h<5xg`yna5V&3Z>E$jnJ~_n34P|M zZ`tu5nyMeW$zQkAzL3#dX4V1xPMvQBRku-dbVTR1snE2^&wNv(m-coZo1100->Ssn z5QcK!bvZHuLT?$O!E}UoEpo3rWj{jKa6yw(C6}1=hI%KCc7#N&W zzs=Zg-+cP!6o$LEeFix6>62Ag`%<@C zZnxBwK5_3A+)I4l{2*C+NV#w6pTv3jfxT<*Q4g{88c4p_XzeNBM1oLxtI<+UHWlwhXYoYP`_h-J!poiqV>gA z60|I(6B{Ny6Ofhgnz2`0WOxiesS;w_r3;H49flz{Fuo^0aSOB_^vL2%&Z*@Va)gw84V9FSJY38zMZbnVK8f(;H9&7>==M2^hZwmCc#Uv(*D}|q-`!r= zjrz^*#eMm5n(HPcL*J83?;O~l=TFTww;hWkKR^N#U~Y0jx5fe{>LNX1>|BZ9%+&3N z*xu1Cma;Q)kEPHXtljdtYHzLs{EnQF<29)}S#a>NHXCgXW`PIE!T?z^Y^(*SARGY@ z@sHSPg%A7CQy8VD{tKDcA=}SFYz4pbeg3l{1Le>~QG>g~HsJ@-!UX{}*N4K8% zHi1GafyoX=*T0ivU#D~@fbqA8q?$SRNUjv%#iV7aV=>r$8oT-Lh)aiT1_u2$5h2YT ze~!XPNONvmKq{qiau|tn1ds-mg=X_m0KRl@PBrTkXx8AyEWONZvmdm}uHa3zghuco z-(5GRjR)Zux6Wx7ZN6x~c+vJ+mVt&hqnpmkLjA72l1n%1r8mlXnyXk#)fpja??`WT zBu}e-b*>&7D)NpV8rJ|TQa(xb)m#y^Mpv>#t5XzPs=1Qh-l&zzu2$vy+m$vkZzQz! z?z9;?j&D1@x_iL`7&5GBR_Um!?M<`aGj4Oenda5`UcnG+?OfyTwz&{L<*SOVR;$Zx zbBBaMOE`{r!#XsTdM~fk<~5Lj>duTCbNI>Fj1q8?%tIuNu%xeuq?=6>6&@sM={Az| zGm!M$H+slx%c3v)GG8opy2EE9y>gJ>Hl$!CwX0flJv6;}o|(z_kl+j#erEkdV2C6< zy3(cYrr6=((cQXWz#Da$Eh&h-nJokhW!D1QN<&8)DY{5xxlvr zJZ1z78~-@V=E8uNiJL`+IS+>$7tRe2HIaagaXdXHlg%Y=ECIhl6ezhd~km37imK*nu~!bdg6l zv-Duoh=%}XqT)0xf%pb!3TdcShzuj90{!limURdfsRti^y}8{s4kCd(X1>T z9$gPSQR=o01r6=`YTLE<#ZB|-(C|7%XMB}!9vx-Xw`K9pSI|!!F|y%=UgvmGvKA3H zA|_xYYnoMHaw^7g9HVUfzrKM8^M^EZRrS;rXl5bvqodoIF5W7&qKnLxK3MI1uRE=X z{AN+mi%PFOFxTUiDeOn{{$%*9(X<5TFdpj5yH+mw@HcsSQ_FVsUpK=rM8XX5XQ8X& zg4P|G;c}>iGc;sR@wSRAR6I3*?RHzM{$Od;YE^V>o06ez&F$v4I^HNXNvw3L&D=|& zRhYc|G^u|?{Z9Rv#g7IX#&Zu*@=U|DfV*cFRFczVojtjrtB~Q&Z-6*FWgRj8OKx6F z;w#+BT*8=;z!=krFZ>u!rKfa8MRWI?mwh!n=d2C#Z2`{nU!bFXQ&EfdjilA_Q-)zk$3lKocsuO{NFMX$N6p{3j~BmwzLsjrCUt_FSi)iJ-b z7QU0x{TJ+uvfvw z7$bImZtSEtjW7|@h2()~BK;g857X3lArOU+1ZMiwK7pfA9ceqkdsQl*4T?zZ#>Vwj zOE&W*djCS()%G?G1L5D&f&%@*=)Wr48F)Yf;jH2JL_6d_LEC za!Kis5E5F>=a*d0_MOu_&y;LE6b%WNy^Iy)G_D<9j@C~b-ZsPqmYsn;mUiQB*jH(r z{#&W_N8y-mLJ$&Z`!XG0RUOG;#?ZZ|P7EoB`ENfghB?F;4s5h;F0V@-cABNv6`|{` z(a`CtmPO;eaO zs%~73b>-1WW(WQ>pnwrV-jUJU?&3SJoRX@v)w%aLiPH9jlDc#GDnlozh1W4RGKiZ5RuiP8vIc)a*8s4Bj)GtfpQvJ| z8gNIdV`FY4TT?PBISV}m_psXmU#8Ik;J~`kfl?hp>?#8cnn~2G#lA(Ia-Sk@;>dK5 zqK76q7+eeN$pj6jwFu)Q0I$3xsfU1w2!>wfQBwe4);Hvr_~$e&xwk7ElYFNeX=&rQ z2B;~nJ)j67w^@MJgHCoc(uH2|&i$ekd-zhRbw;!Nm%uVMx+45h666cSJ-mF+4G+t6 zgDq03xyPy(tEj#wGe=BEM7I-A%LO6AY&H(S-vHi8K(#KeZ;z$f*StV6$oX6i?ce%C z6vdhj-P#E~0u--C@AMDNL6ZN@X#eOK&kPVjsJ_IHnc1S>!J_QZ=v|CkwHs@-R6AG& zrvPFPp>YK7A5>b2fC%R9qS2wN(>RNaGbm%4z?Gmo(e+7A=X!&Sn%>ihJ(O1>b(yd% z?3D!{MDzCOJflsk5$wsYH@7`Mfi%}OvbU3ZAXnf&k!QhN3_?*vxu**R$R`24+?T?x zVa5dc+p`Jq=tbf!b?D^+Q3~#40|iFLHG~So$m`*b`Qchy_{!x!)VcjFO~1P@`L}3& z-VzQC+u%+6@K|)*=lASjixfY{OZap!U0AYXUW1o=YvG)F_9s8hH(f7&ot?gH~yY{H6 zZ1?E!O`p*c%VxCqyV%2C7-6@w)-wtxZ&Yu0MDoQ&1QF00vg@Ig;o-E{E^mv66L}<> zF%_f$r>eaq!P&0)Rk%kb!%=8ps1~$aCS2kAaIM=rSd_Mq#p|v6)wiGZRB|5g7Q-JQ zy^C3%1W1Z`V`Wk{rvF8z97lW-mgG0-Pd8@A{J4mTw#y}nL6$coh*4@Yc3d*2#cexz z$^V1l+iRsdB*S7IOkueW4OKZjPAp}1sx)BZuCltJ(N@~FF^mB~W{jv} z=)oK&wGYnL6~Lliqaz-So-@9g;{cP8lje$>StG3N`=9AuFFb;q9dY%|mX<9zlb(@Z zE-SbElvT0p{7D>9tlCIP;6B_aC24irv>fxv+q+kv` zYa7+oTjtwpqf6%XKBx8&)fViJdg95Fxih(N%QLtk@^A4R4Ql090v&UCsQtlb*y>gs z=1lL&YUJfUTIl~S4!dc$*upMNc7;c&A~v-YxnqJSE3H}B8!b+Mi3(~UMa3{>Ty)>8 zQ{Bq1$HN+12&6aPnPe0`%(smW-$hJFs3#C80{nxr- z5_Rmz?i&$W74D+5Axk9ggpuvlL*7=qRX&5qTIW?|y~My6xPKUvIxtv$=bM`fV^ups z))vE(?`DHwEdNNIi%x8`sksW-<3w^>N$Ms6))$RVaui^qO2u$ZP^x4FI^GP;HEfoU zBwX6eyL|ZCi>jB3ni)(T@NbFMN8rtOX8BdDtpb^2`Hr#{nyP zOz6*5Hz^8sY^IhUaRgnx?dVqhf!$`&g@wq^n>u(C6~(|G0&ctqyiwD1*>%%Ml)WTS zM{P;a!x>SiUV82}Q1y7`{C3&qWKPLL+QkOXU>tDgFpTO!2&`p&U#zyVx`i^ImJI5x zb8}7aUrn>b!Ptv1u~|xEFU5n=*Q*k+qw7F8S@I>v< zf7mK9yip%D@#YA#wJ|Pz^yAqrYfrb=P;{vA=4@B?9rEml%OhqNGQY7nZ1E=Tq3V5c zpHb?{8*C`uNuI)QPX(bC(P^wW&w*p_ zS>)gvIwz=P>l-_`O>ipbI_k_+2fyiI*1q6RAt)V9VjPGSyFtm>aylZUYUFWK^&O7` zi+-R#0FW$F)o`Pxrn)lIo$uT07d&W!s{Nr97jD7$D0z+G{iXtxu%#k;!`@(Aj0{?l zJhGZ`4{`%QirsA8nQ^cq zZP_fNv2|kHaUN2n0Q%8-567cldJ{s+sy0A6OQ~P)KI3h{G_1nrH;J4|4<47f+9%+6#tCb1T2S8 zjGVgeP2Z_r33ka;?k5k4oqp@i%e}1^&FHSYxP4L(&Zu zC5EyR$;FMYYYK(;z43#;a}kV9q}>}1d%XLMbn~AZV^sa(DH-?C#`ps@3&TXtI9uOk z_bN_tRL;K%mp7P;Hy9TkB8|G@!|y*4(%YvX{rzV^dfN}FnKcuO`00&utnIl-L!&n= zGs$v6VZ2&ZIv`Q%H?Up3DKL)Wh$hXbbNZ&w0);!~gr{uO@cPtE9yX-^GQ`*7cZ0Df zZ0Orw+{UZnD(yfKG~S3I{g-}haGlkOdhMTrxQvF+pE)~up#K}+bi%de>@Yii6S(O0 z7*t z7bK65HcU{I2{ECgcV>#^g~mNKuen=v>k#*L_7Gs}kU#Xk&jm7ZRqn$5zX%WHsUu5qov5D~ExaSNxp&O;hyNPqAHQ%rD$G+r1Bs91H~9n0!(6m3Cli4MDY3QR<2-=P&@ zq02?`sc1-d{%l503?RfX@`12|yIm5HRg~AiQCH*|6>?pwd;cQ5&8*<;+|oXmZ?b#=!Q}bEg~{vD8hP7bwgQmME@IUVjXn3Hc@%5Y zPL7;Q>>`X*fY3Lqj`SMG|J2R%d;TAtAs^xMa9a6CtL<9Dl zW@#D{UxrD@t}C5|jG~HRzZH~*9d*_s9oV7MaC%bEP=-=v7bo<&H;9}b0?D(}2HCMg zs)9i06^uL7D7Qu3*<|l zQkr~WYfWkb6zUI-79Fxx^f|yV`4N7vpLiXap6fv+*r8dfo*;Xe#>%Tyn|Q=;OD@RZ za}X$8Qf`x(^eS#();oIZdemVAPmWX4Qje?;DJ^F$wD0B6(ie=)beD3vGnZy&o_50> z=II2IoIN8E?X0L7fn-y=7+TYPbSLwq)6jle6fmjEhjfjwECM>vxE@mPLZbyqJDQM0&Tu}PoZ0aSX!?I14N`Gu&O$(UqkD| zE7C>!=>FLqj_91i!dOMrYljrh+BQ9>A-RuNYabuC>G>o56iv8PfU6C*%Yx_-D!m_im zUIH)O2f%l8i=++tC(EJ2lefF1M|WvzUKB?)(mV25DzI7@SE!>ssa@;Il$`H~Cop)1 zJ)RunnKHzlB9Vs1-#5)70#cto?zB*~hZD<+s5voeC_9-_^VIC&lf;s!l%_>KNvPp+ zQd}im-%C(`?34T6oVb`fcWJm*l%U{siJ&z$z+5yR(up@BWKlc7zdQRQ%8}o`ee?A% zKK#;LQN+s(UmT}~$&X#pcNraf$7jz%HoNXaB@~`SD0_!KLzlLyT;gKWq=VKvd|w-r zGQN|tO zqOT>-O41v=uTXF-t&6h3PTYok(A>gMhV0*&0o=3h3WDsZ8FVXPC>LnM*FczZ2~^c9 ze4nbOoT-XS?_32-_^N11?z6#vm}?4)7F5ZEK{knJ^V&N;AGId|h!EKRN~6FqhW*2c1L=Vni zNVC;xK2P!!=g2^*sn;b00Gpx=v2;`@$Jc8Sl#qS}^lHi7owMGE}?u-VO4FuTy!tT?G=!(ox;<851mppz6w zR^!mvh#BEB@60GN7i26$>(6A z05?V~0rnjU=7lDr+cS!Mfrn=P8I2MdrG+JN1&>&T$zbM~M~lLyz%UQh9borBb1-l2 zG{4&k&2?oF7V;^xV7nCKT}@$}<+LE!$+X@PG!Xzkg;ijIEx~Q_4R^y4_-R=UyQW(Ykyh!7=`|7^iZlAer&v8D4ZdotS(07s#HFon_r1Q8F9&o6N0sgkn zh@4Kstgl=ZheDNk+TThKM;kZ!JQ+>A+eIZIIK49*Llhl2hzOtQwu7VSLu*uD64vDg zM}U_Freirz_@qZEu3rNa1k5CC=E1Yr?A$k5{kpC{D38K*`T!fL@INS=67J;w@0rn! z8&%2bEV+PAF4GyK)y3p;)YT)8yeA|Lt<=L7_hb^s?yIsz&oQs@y7C*g031q>Eo|6X z%OlaGtMTLqbLfdUDXGIQ4m+B5q)?AJG?#VgNnS8?bE}~`om#R$tr!sG7fQu1w4?^< ze_D@Pa8Wavj+CRxKTdOb6RIy0xKYCY=km$9{Ip3S?dQyWkTLddeKd>M8XalLZ-H{P zpK`_OUdwb}9FnU4{f`C-b<;U@h3q7LnUL47;EUg5Rs4#Kuyh_PjKD!heD0vMAaon; zIx(#Kg{j3py7H4+Kilk@{c&2zmmHpfBG3NQ6z6SNkKE~0OA1uyZMKGu_ve5gN0Ixq z7x5LZGDy2Ey;`@G(~#7U?$?%4`kCjS0UhVU%4LLcx9faY0M}Fcci?fU&PxgNpD4QS z`9cLm-(Gr3A{q0+pR7iBC)QzP0Tp2rT=`pHM&`Jn?XD6i;K0(<%6hN(Ld68Yt+96$y zu^(9in?9kfD7Eh7j*@m%rDUO#>vg_h3Gf~%x#=XX(^)yLxA;3F6Cy^n8uNeT&=xyV zhth9A6^7v!ce`EJ5ouE3HAQfSeQC|D%FuGs2@}z&qP`BwL^vTVKrZIxzFHnqreu5} z3eQmf=ia8q3rX{7a|0xHz@2ixsVbNPSnKV2S^Tg$SeM!IU{i9*^I$M!!@)rbq|qEK zbIe|35XVt$*I*|PGI$OP(dwOIQcC=Q9hF)c#K1uc%N0F*@J2vR^p>bqOqDWYk<>Vl zT*M$R4yt)ImY-8AJ&|=EA0Kw<{L5*fS&vy^>AdShYJV2?W7|3 zarI;(SZbi6)eH#ddVU7KQsw#{FzvX+r^lr5++HRry2j_LKWi2@=$|4PAb4+KZovwM zJmA-~+NDxkvg<@iG1JLnZ3&Ya-4@#kIs@EVTI3q1exRQ3FlBpM3LoooCb@}3o~?h6 zUJ2?kr@(hefXRjE3s7-M%2aUkrQ-n#7e`pBZ$`0mU4VD>20SCiCP4|*cj}wjBGAf{ z+?KPR#mN|Iqu+_0*y&y8J?P^@H2Ckel{F1mT>+bp(T=_;OXs>}pYS`x9kOb8$$$vT zd%HF3*<+G=fhu&BAamvBNvxmoCmMCb3N&lz0D>pCG(_TO;VvEXO)R+|Z>zE?Ikj>( z|6)&*&j0O9VmbbQaJACY2b*-K`~jwG8Z&+1rdjsHI0h{d|7Nfx_jBFr_wIVlk=+~2 z$2iwI8Q=>O*!ThE6e*oUbQ?PW*Qn+Ly5 z-z^A~&WlKC_odXy%O5@e>6btK>B|>iKA*gpOhDD+7C`^nfezd^OHTsjAquG4d4A!y zz~~U@;@Ie%o$^$RL9H!xb!fNKWYx6r-JVe-BiL;Yu|;xBgoMD zUAPeinL6$IxnjwT<5y>t5Q-6#kN5`48J5hj269zR5+C+Q-&dXj_yjX!IA%bE8dI^$OUj`|7i0HARMrdoJXzU zmyllvc(h?qNkFajRj|hT!qB_lvQ5q>NTx6F-fM74x+WommU}(pd}=e8X(_xlI<|q} zlwq67w{X(^a4^ir|KKXx)&1|jc?;!+gCC}|!K|t7<*c9>{%T!bB^S-5R5J{+E!Rlk zwf529vfHf2_6ECjx8RakqFo}~VgP1y6&K z&dg*;xD$|J{6r>%n+q*uvK1 zqc)2dgD|Lgzh27wT0T|xA{-ZRuXqDvf=-GRq<6p?X8LDr-DJOQS<7fB(T~xF!oQNa zXdo>R0Z0yjI-g$KD4g*?wV-^MxGA7<+&N=_RyM&#-Pmkih%)S|7lQ`>s30Xdsrft< z*@k^6e^;$x|6=1t{7U36YUQUEy>0>Y3|}8TKB`)2PIDfuKx|ZykQ8Jf1~qUrqykP6 zni@{}-(;Zr#Ja8OHn2O6{|1{N>WBy54wRiMAaB+HD^a}xLEoT%mlRZm@CGB|lZ=k1=H0A8JRCDMU7h429d1gSuGj2xaFJxsCv}h8$+wC!(pR zcYaS-q@VWbBA|*`?x>YC(TQF+2<>*MsU~B@Xgc@w`Y{rR zyPQo1JT2qfb3JWfA(^c%@PNS__nj?rIGlB8s=DMxfq2=%4=@dz{Vs+dLtR*b9T8Lk zxWIq;v;qyA5Bji?2ewHY%Op}a(7T<131m?&o#Om^*SGj_F#=w2;W^9CW_?`BD@14M z&e3HWI|zpaJ9F++2u>_B(~%5-u|@_KxJ`T;iyujP$*;4^qMulHp;R9rL&PXxIVotH z47`25VP)GSp#z#6ryQ6J8>Mt0TzwDbot6YuD6hy&Ta3JT1DoGd)vH>}HMxNdXONJ@Cq?dc{fUFF>9uw~UmcFNHEbOKTZ9TP>7V?P>)QVHRO(iOU2VlE~x~$g4YT;yky=V3AH22_MC5 z4eJ|O$#XmC8FJ#32{WsOKU0}9Ykeh5mghPmBsCi0@I{aDlH)xG!q;ek_v+ zlgEkTp<8=RI}okSA)T11Ag$iO0$ZrNL7;dfj$e{5rwy@M!MWbA1$pWd7Y|NRo~bF zt#r1yjl=6vXM?oXu9aGj-5NkTdb0(prG@lCkE8t^uw(DC0;sr3Qn==T&vSnAJwC>= zYmxmRunFd!JH)P4_h)PiXl^CG^~GYl1(Y&lv0`CDfIA2dxDyq-?n+*HYV{C4K1f3q z`a9ml5p)BRh-5)+vzn&-)%p9c0dhMrFW$B5CO^jn@hIJ`a}F1pYld{K=!m0Ut<1Ax z0qXEX&k0)R=r3udqpU|&Z7`qtLY%_i;5$>0XL4B7fN^y1V~oIT%P-WzBsq4F%Z7>j zIkXl>m*$1s26xpq>BG6?P^vEh8s5?!aDg2cdVrNTqRNbj$?i1ciE|)mQeZv-z$`<< z_q@0mch~8I1^pQ$-)aUT>U3%5RiVmrNYAJXGYia{1$Xqs{Tw!C3SN^N(L`HIF&=62#44h!q8Qjs#m(ZZ3K#5Bj~-xkc0!kjSlM3vV5KyezdnNSJu?x9f!=%cmhlbZR%r5pICuk&_mY-Aib7U7KIdyYS z4J4QVlDu2s#1!xs<#0l3+U?FQJ`19bX#t9R1E)Q2?z19A5b+l1Eqrp+gAoJ?<=x!EjdMWWEwInoU3@(}8B zj=I9x*YZn`@l)9Hd9(N~_xR{6I)lEr9W`gcl-2VLH#O>RYOs&Qx0t;)mw6I8KaEFo zDeEE-ZweWJE}bUcQ53E9mSwjLYYC*u6W*q+`1ztBhtbGi7SZ&=AQf+MW;={>U8kQd zb?bY4$+4SlYxNdcv0!U|W%(R5k2V(PQ#|&ZG&Er@3vY4ksoD)gUFjtuo}M?e0uFsP z=7kbxMZ>^?EHg|`7@PcHK?XWh%Vq)TIH#Asf*O2DRuf{aG<|$g|%*29h#6ncY^^hQcnM=&lxiu&^D9@rp&urcN zn%(m!UZ_05kCwO4RBQe_6JpxgV!`+~%<@X4ylR_ z7S@y@fn`PM^YlTLK$FI=if!BQJ*_PG=Q~!kiGkO4-+c(ZV$}8wup@lH#QU=H*vGu- zoHbQ-$%3v80g)TJ_In~*fgJC-T1u95Veh8omNKZ1RYi%%#|5DA&1TyG zmce2>*%H`dHc;#%xrV>@+u&z-|Fev7p&lqlYiB2wxED!s}yh#VK6fIJ3ptTu>yo+b1;QTfd(*14DJoq z<|g&$R2EHje7B5GWBPDTu`=og!4XTTTohoj{aQS?$WW6n)N}_UcR!oJkWkO5fFOO4 zAlxbA}izeCfnt373 zL`?m1iGp4Uqx&HAvmaF>H9Y@(eEdk(@`&;~O(Cy@0VV?+bh{l8PazQ+!v|O*F7bVk z?|BH5KhpVPT(?(sQ)LS|1f4ZaNLsU0}d$`S(sUo>I zl##V{hT$u;Qa9VA#K0H!Czi%&q)uL^#Ratzv9RPknU3At$)~A)Y8M~ zF|U;-lTP3Rh|(sVgeTA^+JMcfME9iRwN_(<))83)I6@@wM*>Xt4L|_J%2#j( zuzVe&b`o5%Ujs1Z{ElA5ANa~?nl8FCvW4AKh;XBcl;7Z&xTkpQY}$WM(vHiN_x*FF za1D28K&;+q@XGG%*!sd@kq&ww$(G)ZXU)lLEw=&NWv##0Ah-2xQ zy;~q}maMHuB=_X4P_Vp@d3rhHlHqgXH;DnKhP)G;L>ZjEknLG7VZO0n>hM=wlHntO zl%JJ%MUcUhS4OqVQgmmPcS$c%#`vpSf$GV;sqA**d*=;8!?!o{DvS zc2#l-X35Y#jaQxy&X&sqvB4f>BAb0=i>Yg5RZGsKlCSX4`4+zvfU|K5wh++HYd9%K zXX|G4J2)&h*}_dx7OQG!nd)aY6)c7K#rhsiC%XW@V(aoQ4)7Ib?*niTynOBq#3t=? zVMZjM|2^NrXT|BHAKwQ_4P_w-3#WUc9|V~Ah|YllH}l}8|J$?SjVwAbpEI(324*JA z&H1cpGXMxtt}`aF108H22L^=&`iIfGG`JH41G!22Y?#k@NRb|pGm+m9aSyiSoOLmA7AFM_*b3T$=b#;!eh#Sz86=0mkyUyi z`E?hPU+hVgpo_MU>oYAia+-P)yK{%R2er=D@C~3?Xe?os&0esQygs|la&)aW4cKg= zV#w3s>~@zki=mA0aq0M%@G03|U?^27nL@?IK@e4`&u=&nz30TNj=zU6E z8COWIp+WiC&kgHNvubf8Ke)>5Td9Pyl1lF}N>tT()A3lkFi-67s%*=3Bvw+v7z~Ft zb{e<6x`QdHX+bF$%y3!2{2RUK?Puy!H}Zl76x@gsfsyycIgVIfbSZHj3YEo~l&Prm zHNFxM5lsCCB{*5kB={w5lBL}Qx1?Bbs;Eiv%f<%+2q@hYyB>z4eP=4mI? ziYhY)y|r{5B={xrn7F##iUffXrE- zX9YA8H9BqguFcBeD&aTMnn={0wH!!gR+}_r09%U~ih1CmyxZWu^P0=zbn+9>g(O<@ z`S_?6`uKapnhbt|<~6KJ&F7%f?Hd|ww{?A!<&_xYamqEl=nM(49)g)GAFE*I)w-=j zo+Y_kJDRe{<8??LGS#aw(d=`Op-&w7^r&ysOKtg|v{>Fz9Aubew!xIFL`wfoh^htk zK|T6{tYVQh$trXzNJCxhM(w3AD*Qnfc%H1u7PH;m6|58CQ!WF?R82V)>FSke)Mr4a zpuQg4+Sg;<9&l=`Se!=VZPK(($#-ySjH#9JQ0N8+(>1S(K@J=*e!foI1%(5EVQ9Qm zX_M?`h+pcC`j9?XCPHp8aEFzueo|q~E;*L) z=rrhVi|EN*j!+`lJ#&&OB`)4ElwEX=68B|`A#%Q?!j|$?n^}F!pGdP$Za}4WwWLiZOSunKS=I%i33xxf497%T1A%;I2ss^>~F)Z zn%>{CY7J)afD9~C`*$C1x1t)F)W?U6qp~U1M{{@m_ANJS*3ml=8uc?TEGu?{4s* z8|&L!ORb!~RRnkt7hQsU9gNk0G9MDWOph+{*fO5Dv*UGYyAUb)O2Wk>(=))rV+lHV+8U`!qR97CYPp`uSti|A%n+rN^MR?0#a zZ#*fbWvbrssVhMFG*~8cgyu<2D#zNC)TC>9gbrrvRGHqX2P?y2eWLroIhLgrdmTPt8ZRry=k?TBiPsm4sT##A#+NYMuMD<_TG z57yZKLL`$LiW#y8%xGi=!;F##5lBkzoM(YQ7x>JtM@I%gxy9_XFcBt@|=p2 zmDs5^>23|uw%K-2R+4jkO)I@_q41)1MeD|`!*o1T+lCTHPn-?g>OnNZYiJFF`wAd54NSN?F2IM<#F|f)-Bd4 zrTN-;Lz>ZMjyK;vbZ~l8BT~#z+-h2vG`NaGqxo5slMm?#SnU1^itZXR`Oa|BhY9yN z#6ClsMY(yyEs2-V3RB!BCNEmngH=^lKg`pJgQQ#{PT?lkB0xWG)bRVox5$d&3PYiH z{SKC7zuXp|90f%Eok3xXH=R`w5rEW^=+|->54O1UwI17uNT4@;m177Bj_qH&mrBX1 zd(9+j8TEF}lv$LjGT=9AgV4arIo7m(6@ zLDy3E-3-ZSYh*XFqDeJxr&+3`xHZz#N{Qu)6+(Q>#XkrzX>hz#W`9Y)9xbebTMWN* z4SiJivu*-?*kREd)W6h8DTKkewYNTvw^V^P+u~^q(B`S&g10=l*y>_?X*3v=!Z!$` z`kgPYbQ4f1@oFi#5$7@85*KN-w0_@6UU*-e90KFNJai+@*1~frL1e0iT4&sXl!e_>dJ70b zPSW(^2lo_(QzBo-g_g7}dBm@%9v}Buh*-qgBwhW*j<`|18r!p}m?O_}e zeMoqacnX=q*85c;ELJC4msNp8U7$4LMLFaEEA3WwnJQk@F6MeU;a^{~JHGwAR$;5S zs+<<66NB}s9V$_p6k60xpXK^WBH<{J2Zu}aMqWiPlW}N0aZa6DMxYb36SHgZZ#F-F zeu~Ka)G~~#mupGo4fQHZ{gZnf#LLYKtt>0VW(X;;f~N9os`6)*@NRA`Tzmm$v`3mKS>Jqsh_J<%DS&O4Oi;Pzpx+R;y}`v6=-tQfSuJVluCK$>^{co zwMQ#6uovm-Uvu2ujV}b%)~w`*EeepTV0j5Fmf?5c9aQY0oV*GE%C;J)cx{rq!mDeP z9uN6v@aq!~si>iTr24%zy{caKg)(??V|8A!f}}JU0beaZ8_0Tfy42IxP4;J&}^u z>QZyoXg9+(X(2NupM|tt5n!bYifH3&6!t0UA4%B;HcMp_CN$fP6;y$>X<+gU3+Yq2wD+iD9Q4<>2TI1DSWM!x1ev#WK}w-!Q> ztxO>8irQH_c~IzgrnP3a4X>>>i70nMT8F4t)*4^ameLho_=#o~&IoO9s08lnN)YRV zm;Ebs$A5G|rTHKptLbv2gbz~E4cxQ<%j&&uubX_|DpWCl|22+OXHjWuL)nO>0j#M5gB|jIp9%- zVWg($6>nw0k4@HPpl?l;a+_92sNYc`l;R&S9A}7kUri(u%VVpKCZL4(e zjY{Zd#JF7rEsVoN0|bqKjf>`dW<%{*48q!S+MrfZpTnTghf`epeFT<7LM}oqScTA> z#+FZlCV??GiDlmXcK?Xa=15t9zYOk!+Z=R=*Mqt z6{H)&l7Wde)CqjLv;&{2SBMY7sg)UHAfDSsy3S^E{1JMMhUt9|(y)a0CQUmq1VaAY zHnFPP=#Jd#_=z|^+d?xI#m#>WMw!*nF8Ev(rtFA|QZO(0@3%Z<|A(vl`)D5@jeS4u z&6r2t?B31nd{Z(B;yLHB-eo3Aikn$(y*%JuO>obkOzm*E`dE(iDnyPdoez-R8%!HY z2OG$`V%N|>v4o(EVVGj+rbS+RiUILGz+E$%&VyRZC1j5AL-E=zZc3U{&ZU#u8h4YT z(nB)wxrh+e^%~jI!U&aUSZYgrE837XZM6AzbCO9Z(dozSV}X4riz!Swp{1yILzxcP zf7T=oITivgNVYc^BI(cy;w>WGL;pK2o}R8m6I-k6wK6fcgQ!kuR z6TBhpx=_xgi3CfgDSU=W{;4htFY z0j(}FTvVv>YG=tqQY!IlZk9E-FA{_nRU)aJnhf75bNORqCeXKE8;P2&P_lptH34YFQVWvVfIPG@YJ)Ob&ho z{Y=tGas0SybG|h@Re$mma`5BlT+;j9>bq6 zQy-h4b#$lHRLqj+FJF>_WAVQ+j9BHdWf#ZomM;MOtw`O4;TQ(b0RbSQbQB2BK5o{dE%VWhe|*SbSfGCtaAg}7rorzW!+*}6 zcdFj73|46u3ouI|9HJKjRTNA9FV&pn{4)m zG|r^W*a*+N0R90C`R8RC8T|8OT-sR3nh5gw`|IW8=x#DO!uqd%_08{IzN!BHtLy7)N(bpd#ht4i zRH%*~-OqMEBn_zSmNdZBIWnf^-grbH5!dx~U7zDRO*BhpF>E2Gkx$>ZcY+=NE?Gvs z!R08kd!fVh=U8+u{qa-C@}JFqQ{D;D3$vY+&f6o%5(0y;46$lO^6c;(@0AYLPjiEk znX3sY$WTAYtFU2N-B!%hFll}jcUa#FU5k{3>_}1)I`Jrth7x0qy81JJz|qoNDC^YV zNx||4j6o1$+m((XXGbIA&A6{2chnd_&(P;EXLHd8NE-AX{_j`Yx;e~Eq^8%i)-G^*wm;CM9vQ9YIn zy*&-7$>Qst?Sd2FAk&K3s$(FePAFHWI69(pRM+O2`UG*tzEO?$Cef)-Eq;}!j2#bhXjoihNPXuw&m z_8Ng(<>?{F`x|?)+JwgMa?GW)H{EP4{*Jd9G~0Y#F2!WPA*+n)xRSsvqVAtx-+<7W z@H~uI?(ZRC+eZgHwEBRhsKQw}*1;=Q_+jj9iBl`>U?F-57@aSN z%Jkiw89d-b4SrOhAtS~Lu>yjbcwkCns$XLk!wIS2F-LPzz)hr$h}u2l=*@%GJh#jK^$(CcdVGlxcHq1ySoO;f@7_{TH6^lUg)SwfSb*(_XZ>dUuT`)E z)mF_Pua39UVj4Ejs~Q#j6}1i-x()FAB4LU(Vf6%BD;n9)LFGyuxnYeT&P%Q=!%$ zgncPqTVTJt-7c{0g~XdgFemz2Sds{Kflg6fj|`Dj;&Ta3pf?iXE}r5goRD2s(5xi` zS+u-Qo9h0dn+Tix0!@~H%h*Bn*aT@Fq<@pZ$>z-K6Xl$}n%EzBO!}y`i%64xaV&@< zqp-4h_YY2jU3n(%3<1;5Y4P1sj=9X0!#-;u;}e(}QlPmJh)|^Bmhx(>mGpd-5_bU3 z!($(PPR~68wdkq3F$zRqE&&aR_aTy5NJGZDGAXVr{r4N_x$ zq6*Jy|C%bJ_It#@*FIPu?m0M;xtW7)5LC$n&v>$D#NYvVU2|?7A@@8fZ)Q5*0WMA ztCm(5rC3%iEUUJ=tXg?Krw^@RVw!SGN0Z~@5o8;7gDacBc7FSDFjFn;T6@U=xwrc+ zAp|6qRu=BCIO+a|_p0B!A@P*PnxDT*U?s};EIg8m)5RJR=n9)APz{J3Yk_fyy(Pfnvg&Md zkqU!D>w@9)X9aK=OMcacEv3YUU~W}KUA>0pRff35Qi+(!saF_`oPrh{Fq3aB$te#g z=Rtjc#Hy;S& zqfQ*yrp(S!SiWpp6{I?SSeBw7EIq{l!BJugi24d|pyxtOjZma#oM~z(7M?*v*#*Ed zA4uH?*xPYFXK=|Mi^cnBQf-f=?c6gvSe;8@sZGTs?_Ny_r}tfJ$XSD-v;W1~l{PI6 z1L5!fiW(iI67U!uwOH{U9nW!e#t|H+Vi7!AwBQB&cc0yE(l(@s2Qx1(O*Wfjx5*~i z<2HC(0#JKbn@aQDxhBG-;G{_C5{QUShCR@h$r0_TBHG#skyQfAQ1r2bz?ElVO5w9z zvo;d+a>ubstG=miNFET9VN&fsq8yW&nG8Fb&e7}A56#qQ5>Ba*HM;IhB%n9Y=hI+f zPrwwE9p0dlAp>A$icDUJ^+gv<)rlCjr8UQVi@&fyrzrD zXrvzG`G+ESm*;PfVj^MPl}8*$hxJiDV8%;b>qSNy>a;yVsGLpDO3k{G8r3XJk#TBk z20f-9qq+a|g9a&Tl0Yxw8K&mOn&~ec>bD1j4&L@{?}g^_X1q@D@GVf?j}?Ttkf{-2 z|1w>KyuP85+G6*$Ta~Y`n!O9) zdVKN)teL*Gk#2tPdhOHBw6c4mJqycNxx0SQv~AxGNKtqJY$W9Nvh|!TviAGn`^2TQ z-?lCLP17>lveuH#4F5GhHL)>t%(XybEdy9lc(N+0xI2fLHftyWA&~p0Xy$Gt>Beck zqbH#PeEPn3Bv=RXsjH04vl%qYmIIR~N>FaHsHtRmmeS*Prxw9(L3@yuBhhF%2PGdT zS32bZFgijPNJYq|iZmNR;RxyH@ny4E8LC$-FjYqZqSE%LzXN|OS$~ETG%|K(w<_D| zjn%20PA?=El0C@bpqzB2+tCX^TLpK{-nw-5;+_iTSbn_NZEhQCw0wWt^ABFclGlzl z@uRf}D&8>1?NMNk+g%P5jsW!sy9{OOWN#hi5$aKX0Z38Oh3DPMACR)Og9vd0#AL$zv{{9`KKX9FY&qso~Z*0SXPfJJ7cOy_0 zzOYxh*MqiR{Vpn$#IvfC0sznPB&&#ow{j@MP~xQQsibh%{Gl#PNMjuDTsRAow6ZKR zd-!yK(sJfhi}iNn$Gx{5*;UhB2l#^xi+CHyZ!p&sOp@&6G9XKs0Ph{1kMMHWM0|M$gXd%bYM#*T+H*CPXm9Z#cdi!cL$y2msJ`L+JR+82;!hx zasA-i*5({#MquG4Y^}+{a9#c?rg-J~Y#mcB-hB|S>~0@3@8fUTlP_e?0_RQ04iBkm z1i)8R9sfX``=OPDH&iH7OCPj$T&77DK+vr?Q2CqpH0uW^P6U!Ea*C5HW%kffAo^0i z-lBsEv<2mx&z)L|*9IE1jxo4-J%iZykwm}OU(k}nb-?p{QAsJhuI=JF++NzCv|@!H zVb~{?_PZwaDJAONAREUSI+mNV(RxW{wUIJ5M(94R6-u)qOQf!i#^Z0}@!Qw0x)e^D z4RMoqgq%(rgkPTR;81#!6zRRJNV8&2wh$a>dW#9VFWbSQQ|Nivz!>kI8MZX9FLr@^ zplI7V9>3`fqi2tAJ>J~8_u}F0&5IW=Hg~VzydNS*ZKe5a#C>>mHSDLy<5QhsjPFqC zj86MfgYrA4I!wVR>O1AS=Qr(8}x7~clQ`vqWLl% zW>(YDX6Pn}hL3m;6qZo(6x0>RkzBz!>zCISCnXd3%jxx43Z$Q#4SnM-Co_%*wf!a6 zIiq!XAWK$f%-Rd;>MG$=VAbWm43&z=D*y(is{qp@Ij3%XY7bBG* z>$+wM@!W+1ueOFEubdvLZrWAClInf&{rVE5d$U>+?QKUnM{Nhyj3WL3?bunZu(hCG zD=lvV%anaY_$%gRA*Jc=B~tw0U`0LgCg^K9~Q^)`*b($f?eATMm)8AxPxgtT{X zRK190%JYvnj}_Uv%V0_4PYHWOkdx?zK(RkeNQ3e|1bx!9>HKwl9 zSi(=8E{9|^Z^|-m5&s&!*~n1(MV}V2XAknz2KnJF`o-OqC^roQ(QhGK72$>fhAUG_ z3*jh70|PXn<0J|gT-(GkZQ#MT^LBNF&~P&h10}X>NvqXfTCHUJ0G|IAI{f>VclpiX z-+a|UIa>X!Z(3Ywc&2u{2e!KP$&<;cW8Hehf4!J7+?#iVyIH=nanetnZ#%nmSJx_* z-Z#Qi>`@{)oa#<|Tq}yqCONLN7S=pWv?tDfdK%2NmqzPgzE0W2X(|XHYoIC3-xJq;CTu8D=OkQxQM`$&b0Jp9zATk z#Ly1t2l8^3qG*&wPT_#fLnc#uGKm<{YE5S7mWlOb9drvStCVp`qKsP`_tqiX-XPos zmvb~CR3UB^f}0dVgGDOxeo*pu2-DPNL%6Uzs9&h~OR8x;K(dph6X@<=h@wFEJtOQl zgV!mZGdtmB0rCGZN=e9UiV;Z=#1QESX^w)&7_kGxFK`A4)lMp)H7*G5x`vw^gMdNl zgl;qe3%z7({rZLM~WDQ8Mi=bCU;n630+wk}S?a@zx_aC8|fRCP&U z&ifZSWHyj6eJfI5)_wXJNJT$|)4>+S~J+!cSc9uSF8kgp#=y|c_O#Ws%H*sBRP}+|<2hfN|7Yg!f-Z_}LG@Q2* zzV`;+1V4FkarzBf{BS6~w|wM@f15}gVNa4uo4ZeXpO4_!EbeJ1CE35mY4f^KqU{3vzB6X~(YiHk-$KEnau~rZt1NIVY)D!{dghXgMTvLmFtebzO13!-RKg^p&(Ec>%nsVG}{suvQALV(3JlcO$uI4%R zM`i2cZ_Adp_G_s8e(OOf<9H&k;o}$~P?ip(+c4%Eg=wlA&78zw7}m8GV?D8Z(G-V~ zAfnI3;bhY7|F&`02Oh+?nn7NY#)^#QSoA=4(?B-8AS+(Ls*5{Gw=Lv7`c{(+^MVc* z{gS!iYvKVG@y=qLLc5#CdrPf-Jem_>e(qOxW)zw0WUP7R>WPH}j6~nt*s){iHoHv@ zoA1wj05=dq{$n5iGjX|jrG=|<*oQ-h(B&Vxt&7;)ci`ZmBhBuykKGf`dskZX&HiXV zTNjUBI^O$A-Faz^b-J5N@4r)J{AHCMgP3H;*QWi?_wPG??xRGKTvu zf&o!O%`zqWJkrE?F@$KBya8g7__Uf&H0mou&ba|)NMek zvbo71Pu`|41olAqnFs+_IOktx3`FQFq(UxaOx)g-n!TYl-Zt1S(~J$!qV$~| zkKHB(5@8PKX|A~nf`$fqcwavpz46l83GNqVT|&#ah>bB$5cs=sx8vhB8@zHUl4QWP zA4#JtK35_}D@n!McM3%~vp#3XXBd##ijs^L0^h%6o6_QBO@vzJw=TS4;6CY&NkXEM zF+*WlB~?~;T~uZz(cYonE}?JF@no%~5&m>Nf%VxO!n|KX6$b9RApRrQ2Ct;IX->u^ z0V$N80ws0~7(hl=b5pEFZpW6F(i7bfTVY%YMM-!Up%U?Tx-bDlHxmR=FisU5Ci$YC zh`72y!&-P@FLo6PI}oPndL=yKN;r)&lS&k8(Wmj$XDW+DwAv&i8`*~M86HawgHh0c zAzO47L_z>VmGuqo#lecmiofxw9EP;Pt{pn*R5n&pR<~@j+jIt)mlae-c0fL3DgtdB z-H|C(UTfWC2->EknzS9CnO0yq^j-XfSg907zM|+O5w@OI`%-38NTkCVA2CM8k-ezB zx$$Ce;BAhau1&?zf$}+kL@<;X&~;SEh8(Ln7DUb_%GJOb56c));DQ?XLdwB9qgIu) zFV>l|AFyQ1)H?{@$nbWCMkN}tcSTOVjw&m*?7Glq3KIX<>{qP5(25C_Y2O7Cf|~D* zc6nR*hT^S~P+{4upk8!@lgoY|G4WjPvy6d!uWq(hri>N#k41s7OMrd3QzS@Vs4Qed zjEDZ26LujJ8DTWd&|4I5dFfk&;&F0geqgKxx(mHfUK8-4XC069(`hOU!ZZmx4;i!F zM#NO^inO+ff-{3J69K4u_avvnnoUF;4DwiA6jKFz-~_v}$gRSeSzBS5bFOfGxwE|C z*p8%h-0v`3$PFSWHL+F{#5p{pyGD0M&JsK4fKstz?VKH~9h6npR_7-MrM(R?v#yCr zPx`8AZd|7`uA*D);F`V>3@bLvAOtgDw+v*l+{bWzLFokx?L}MB^>y_T3+#+jt(N7c z<-3I5vD=YY#ZdR_@nBN@mR zRI^YB`dK~xh6u(v*Sz>mE4F^e$6PVck)WJZp!Y@Zse-k+cwy>tmEhCIVZ5EH9o8{f zTrvupfK#DmML{U-XXL%;pr~KaHXV;qkL1C&3Tj+xl3$&?f@9~Dz(hd3(2Yc+)p-<0 zdWxcw#zmf`QS~gbCQM|pDV~V2xf3K28!>6rGZExilPOuv(X%Xc7!lRdIIpg~zV&$d z&ZAWIUmIAmcu+p6j>OT+A!XVtD^MK#USsF)D=}& zMe((eeJrCJJ`s1NJxjzu_^&9ENO=)F5ayE&I-O42nPW$0=OWjTcANzfo&Qfv4+NBdMkKHvI zoh?ltGDxO2{)UzNY3+wsP`LO}2blBT1Os2aAc?9evOr}-VWi@xVgZt2VjH8|C}xwU zSx$+2)JhGNM5jvH52BzLiyK%`2R?D47t;dkA69LAT84_iJ8zxhhBZSVT$wuIqD=SJWipmT;}{hSNkFk^=dQBP!e7oyEpiF&7QtS?M;~&d8oMI*>#Sk@llI(&m30EQIt9&A^3z6 zMI5PU=gJnmBT=%;cJm#FA~`>-UtGqcL~l744CiJNxL1#8;+-E(wRlSQ(_2D)+_ptx zDIe-4DZUCVzmq*Gv*TvwJXhQ56MwJKe2C|8t{L6jF{ZzPtp>0Osol7K;qQ1O+cnyV zd=Gnr^2__z#k;Sg_D;KEUJb7iO^4RJW$g5E2|3&h4%#D&f12a|$UQg5qd|X!v(xpN z&L#|P-Wn7si$5?JLyR&Q{T(iUA|^ zqUHlrH%A)zv6X%5916C}Xc9l5sza#uTR61lx$w5M zD|Z7{{v=8zqpjX$d$!|lJNE01p*}Tx>YZ!)@*4}jzCfttqo+Kwa($j(H57nfv8gIaXH6a=i?7>}5_P&ll#&?*KKaij4G?k0q*7!dQe=;4vAxz{xQ3?N8kxa(xEYRyX4Gz4 zVWyV22bf;2-Muj~ATzSITLaB%?07INhi$xqqd?E+X4q%0_6(J&7W4OKC?r(WZA%XP zY-%QO0jzVSvDr-WXE!4W4w9nhNotFKdgfSv$xp+nCV!TM54}7o6{P>0crvA?&oLzGo3t-2bEMYoxPdJ zO~EoKVLA2ekKq%bC{al&`RYfVGufSqqBrIGY`&|2Dz;M&ajE;5zpwD8qCD-;1<9`P z;j(`4a8D_f5^Zq4g9Nb+Frdn}Hs7K0=)2GWzMUi*lFLo>oRuuvCDI)ScTs#9V$NgRx@;Lg*ZHax{ALj-g>$+FE8vmWnOuSbI4}TXV_YbOzYXT8 z0jO9{Q&jb^R-WS~daVmV*!OfPuBPJMG@N$Zhn7m|a4<4X(4DJf^#y>jLNsaV@j8Gq zd{L`#kyIG9sT2SF4hYLMRp3Z#AA$z8@24^1gdPXz5Bb|>hN9b=3(HZ~1 zFlQEjTRHPibzuuftd$u#Y|qF!mvEK= z)d`_kQpdZp zt`HVjMKp;j3Ci)tr1h?r?LLMdJ(an6CB$+q?e<%^e`w{SFM8}>3S}j(-*i2X-X}<1ND;rhv ziZ_z&tdv$lK2<qIXKk~<`(=P} zZ0;`1=pr|}d?XomOeRcR)E8~KIz*x>;vo_la=7QBZnA2mbT?re!z5^LzEXPfnWP@U z)od{M;KK4Q+ljqEKSKsif)$l>dD-?<`sb z_}Sc2#`O+OGl|PfVV4~Yxy)&@k)#w;G2=>zJ`+mt<;^Dk9amCgipuleim?-I5aCic zq6`4ezNgWukps8pXKuz==?mb=31%H{-YXK(iXU`WKK2!uwBYI<^PLshaTg8T-)ca( zcqjhsJx1ni!-CFPA(T5GHY?j?CmDkDc$1F87CaT1V8<~XCoUyOSu^cckH`A+YbhBW zkT4z`(DBaQ!909*V9zG45Icq$Y`BNLF*Gh;Z48y!bHkK3xn==(vWa#van^eaLzm-= za46psvv`%xQN`^HKuB524+rj(t+tx4^+0RuUP40R2D0_u?c#>*CNE?#^A|#dcel)N zgP)Jdiw$uR-CF!@UsGP74cbw_0b&wQIahZH7l{u3jGf&lZ#`XU zeHGdJ>>&HxI&`AC540xz7&s;K&1zBo&Q;lris3dxLk%#rPk)2L-pMG!o{CM4R)Sif zaMXHb(UdEJoj5f06wH&;m9x;)cR;a9nL2-$s}25OuI57*kCFh^?i?}Rq#9#L6>P+Q z(-BJ~$!U&dCBcn}j3GFc%xIMH*oI`W{cK|qui_%GD|FU#xmP>N2OuwysM_@_L3knsh0 z0VA+W^B#+45J>p|B$ADY3?9$GVF4-OfH%~_QqSp21vdp*A7#$~$!ZLXk+#$rf)i70 zTMOdV=Tr&x6v;M*-3?qT04I0}0`ZgB*bZr8`2mbvhE2jUA2fhJ`DsQc?v8|LJpw`< z#ZnOPEW(s)RL$Q{z&ze*PN~#t%i+@Qs+9F!VV&8amHUaM#3cks{B(SU(fxr1>HJ6& z;r8#Q=rzpho|d$_zs^vnMa;SrA^stdC1tP?*lv0FY)3}#sJ_6*w;@KX!-|;0idcu$ zfj%ogoVAE$bZni;n=^_*dzxICpsc6JtZ_=FE0Q<}zyJLlcyOUPq7TuHcOJt4JQ)sB z5D4f2H<(Dc4fNN8F@amKb9LQ3N1lMCKT-ZYs#ygQ=DvfLov zezsRRPEQVWyMi*#Jzbc_Elxe3}lSZ{l zT#pFDv8&oFiNu=FH zto@}_6*7t5Un6NNd9~K}lUqeTT5f8g8@8%f*vAky^@x2;DFbCySX4}j{fN7-M{0GI z>N6H}3h z^Q^kBQo;bRsCA>nOQsu*575n&9!o}IkHS@DNC;c?Je4s)TCKQJXSdB@=VcyHm81*5 zYlup5Lu@w+2}60Y;ns# zmvs-{cVSk)S5~qpPS5b@5`QJ%F90&u6fCc{ooFPZS#jx}>@f$vcgMyfPtB7D_a)Uo zU45O?@?+LIovH*!V)#0>uWIIoN-C^rsvr;yIlhFCnAiu=$&wM_BoM z)>cLj%0_f2sZd!HMje=87Lm;Tp{OS4|5IY!pR;xz4}X5E{E2By%^VtjJ`2Eyc<;&O z7l$sQ_xGOoZ<+>4KFR&`S6{Pe39jGj+ID%Q_?^1zU~ZiV!heN`W?`8m^l>n~&d`R= z7aW63l-|DA8Y>yplKLTIm8*URqSUfbKn3I)IV(jB*h`xQ`uNVn$w1q&~t z`lnou>m>S|<29&5`UMYzrAMhLSU7jSM`PNfqW>7fU_`SU(PWP^E`0mrwd!fFlz0Qj zeW~IaIj7wuwy0J~eafdZcKzNlMf@LtryzYCCTE>=an*M0&`#5AZ50u76%67rs)v_W zQFJT=cb~lTKrQpNq~B@Ev6nLbt;U=xJhXoH8oRN)miOVPi0TBK)#9CGDr+!(x_GT) zpWT_uku(8v4Cp&{VOmyDj4Jwrl&0@hQI1+suO4V9(7d4=U~c)T#Hm9qEPPj`qa^d6 zp&t64ZG3id2eP;wb)NSO7DFk4j<%`jWfKk4SJ(jju){nn_hnE-#n|NyvKUG6Qd4xK3`B z{#h^mxsR44+hl^V=>pyfh7W zOh=I1-NVC(feCEz{Kttg;~45iTbX?2R00imTgOg$=iKyrw_z4qpt=6nE`^Enz| zR*U~m1XnJIV95X{3#9|)(UGVtvII_ba|MUGqH@rut1jd#mkIdDg#i6Lj-L@dp;VUC zYMf}YIeTY+73#OE-w;t;NrxV1t10y}-jWbbNeJ?lTT^^cGjp@Aj@0Fzc>woGhQEr0 zWjD_xnx9BAeLn%0+_c~$>mht_RxBU6nZw82O-Q-sGA5y?@O^=&4t;^=SKk+Smd3{x zYw4izR&_Gtog2RDDoxV+mvJn>T^A^XdxAxR@5|~}qyi!f#!@sW2|??@H1Xtxkm_|g zDiPXvQ%*@9`3%hDkqhR=|kBVOzrMz&xs}4=z`p_I`NO~z|^qCxV zB=q7ata#*$_r>!$4^AXh)F0L;5|14bvP>9ePEvFuzElS(uHl4Z4?QKG=n`4ZVunb? z@NK*uBkBgSo4~B~k;KGgiMu>vP3pF8VC|5M&+|6nj(Gr15EWLn!q~VkU z5I=9N7{QBowz%(No|NQWZPJgmQ{eZmMCo_eqBgznH+SPq>TXuOr1TREN-C=lKECi) zvL^xHyEh)Q$i8UBiXth@C2lmDf-=3aPKqoR9nWkekH%ZYhY_Q%xZo0D7JSr{$FiI> zSaRDOzaN-GPhfpL(NTo+zW6vILwU7*N#e+EORpi3?t~Hyf`fuS`1%}>c{_q`x5#YP zGsvNZmJn<1wcUawOVrIV8_Udno$v+W&<5r;*kF7p#pXu8y=IldeA$PDQwfenncoT2 zbtVG62!lh*Uob-`?S@QFGzlr~buHXhBEp+fKoNbt3`NjTDAFNXVP8@>p|mb>vII|5 z4cV0xgXP+s#0dx^iI5nNq+=U6^7`6F(Y8L8ERwohp^c}Zf6vRY?$75+wawJLY-9S7U3+q74$)5)~!(dDIz|oqojRsg`;s7dT zruwJiR~z7P!CwH&Y+4G4{U5lwwB#>nsq%pOzX$7*3X9-n`Ec41ZElrTdfnmK;O zG21Xj-1y=t7iW8E07Px)UW08<({Vd#PbzDA`Qo}$@*X&rs+aXd85a4P|* zuh$^I?RARBol4Kkin)Y(_JA4yl3aZ-@{TH8U3qDfm|(MVeUbA&Di*Z@yZn$ zwg+i>Y-x<3W}EiQadW6RsP)LiqIQsgu6QzEQYCvS?lvRJO0v^Z7|WQt;OvDw6i2)* z`~E>{Xn0As#siQ~^x|{?+EMS)2k4+sHhv8~=aUU{DE-;&0{B=iI?PBk<`pv(Zyk$z z5=k!tj&I=HORPN%QgS_JP!F{y;jOi5*nF}U8~%2Hu^Fj6uh)Z2v@M%f+2##TS@=Tr zJk|8x@EkhHEELA)r`aiW`Y8ooLt&CTdDWe2X4qFtnuZ0A&$>n8Pam>oNEXKx5#joa z7q40;NU4>IwROJKx_`{MiJ&mIDBKW*8;ipEB=14t{D~*#{U}8GJ`^&;9uzKGDAbDf z6e6dSg$H74(=*7VCq(E}syMSR`GXY0tZYHOF0RU34wJLH4U?*$N;i}004m+E;v1}OYBA*UD1O(&Z@mniq6 zfQ3cfx8{}jT~B0s{Kqu1^!7Ftp#M8MSUM0&Tk8v>fh7c28jwl0xJgUP^!~K8%yp=4 zbg^G|%OW80X-juYH%~I9F7yL+xBP=jS+qhH;RdBu!&07?hp1s8(+L!8k-k>yIS0X zN|gK7fpS}gCv^`&BxwV=A}~$+q80I&qiJQ!AXT?~|7j@8^NzfbjGRq4#}#fwu*X`o_A#92cHY zT5Q~lO3}@Vun)(55Yru1cHFZ=2N@2I)f*xrB1jiVi;Wm26}Rx^5A475z+t|`Va5a3de*fj(xAK0$a6BIZxy~R5J$Lc`P0N zJ4SiowR`X~+V=8snhxOMI2fm|`tzXAoeT_o8OmsT`S3f0({Yyxs_s8@d@me-EXYN6 zNgVm3d2h(qHUXmiOd64xjik9*N>>j6#Ky`Ag^w=kAu?#B0$;c}QnxEfg6fbm!)W32C9!CB$o%FLRfV`pjR zb@UvK7>RKD#pG|~qH!}nM%VPy^-5F)3{G_GSm!lHT+84K^VyjwKFizf0qK)I~?WS zT^IL;nR~mFcJYN%-BO=y;W6uAn`7M3TzisX=rtASg%T{8{2Dj(GmI0yHh_BxL$@Yk zkwc}H@l?FSHa>O)3Hi0x3p$pf+c{cc{5%gvVturle=k0K==&bZ5u9)4oT5I(`7WJv zZJZ#^xqq^}v1Xmz6|NrR+hAD`pQ;a7F~s+hPh&HA_ay}9#CYSnV}7%w4xm|QZo6#! z7JmEkE0ZT5B;U!&$uOAw<7Vz$nv1>5mv9;1XCNX!Z;V()gtsO`>hXRVR?89r{A`q9 zOBUg_NW6SC5uS^7rX9X}?J-^)ZMCsuI4?n4H#ntZ7mVlcUiGJ0cgX#_AO{|cYO0(s(H4NS>U~$!inOdC(TJ-0BqB#LLu#P#6ipWPq$n@StZw9p{ z>RJ)Cq3XD(ODGLuqAbm1t$=5YY)BoGb_qKymz3JN(qV&=7%Y z1&Dytwv-SdIET$t(8N4T%*?3JKkui#xko!;>MoryqBCgRD3SV^B6@z9bdq)wXj!Ii zkKZIP2I){sP3fC&Dak@r6C(Q@{z+1&nJDD)ZOID2x&TvS9X>-Yh8As^=b9%08B6rMumZP z#aZI-bS)G#|Itl4yPQneRbd>HnK#%@EYXfusWTQQk8_Nwqqa==EEF5JH3p3L72L`V zXG096C_8eaQ)!GocyK;gn$a1R&1_@%mP0j^-g8EM?ZOeJeQC#R8=(F8l_a2?ND-Qh zCM*Hf_c8?^j|+pxY#O1Pvsf{^U8@0xTyzg~HNA+3F}+UM`Qk#s{*o|OO?bT-gisxx zhDex#usgCeSh~(8tD!0;|Nb*YkXAGU(lVC@vJ<)FeN~ed&=1PuXB86H%vc0;&Wr1@ zpAE#c%IJavQrLocku!i$ z-6MoWM0O0in)fO0aS9j?iihFDG8OWyFPaCIb^FWz3tL5XZDz(~vG zfbn5IDe8$QOoG1LS<`0Zm9c)=W>%Q*KEj-fO>*WNTeXk(#QfEp?J$}Jq~-AwV|m=X zbHg0ki3x9-4mMisOa+VHM)d3bC8x{+N$gm8b#0o=p{Bb7@c1o%wejuMqKViX$}hOt z*k%GUTqc%x<9g3#ZLRy{@K3c~Otu3lLE|%<4KBAmV=iObIJBf1un+RNSbW5ky_Vuo zi+rC^H7WL`$1fj^Y?QN9YYi=v=|`{;H>7I>e$z|~JKJfloSdAMFE8z;XE?Nv3C>Ht zXIscgqPKG2`hc3O!(DG3?4h!?rD2v5?g28XV>nc`9M!2eWu95IOjL;>dWMs*9`*)J z@AO3VVsGA{i(ECckHKK8{k5~+AUUIreFd1vcrn@fOv5hHuDK30H}U>?cVRQznjjEZp#9O>Jj7y+h5b$rG~~4xQ}+7 znhpV!(i^?|>=BPG`gc7?O+YRrbxql`>JhfE38;4IQDW1f#HBmuVU3-wi%nwazKHFA zt>I?W6KuzqmZTd689!w&^(+JGX#(ou)$zXeGQo|l9X8>BEyBZq%xn>xNh>A|R=6QH zxx2eRbZ)!oG^zhFtZKlpX9hAY1i#ur@Hj*)4@CcYoTk?y3fYG^4skixnnzT2Q=FYw z&I|WOMB#9^b0C;B#+llMB#I`wd)G;wH~lt$x;0r13kq0cbfa;Xr3^O;rp0?Fejqbu z?A|wYZlHFi__Cc4TML}5!YlDCXZ@vlIm@>qT&09FgZygs4y27KWgL1&|*1`J|6e59TS)lybid3^}TFl?H}+YmUo1P0Mnx-qGZl3{R(^ zgX$B}+g1;BewE0h0MV`_-I;cgW<`3fd7OLsBI z`PwyNdS8uj*H5=>ilx7sk6g-$yk?a5M-WT`&ZtK^vC2-1SxKQP6Y^UlmeAmXpLZIrMvh?d)w zb5Tm=bXBzq^Fc!YrtosizF)XZ0x9bNi}c(;h4n28*ch_D>K8AH%v1XSJ344`G-#&C zY?Xy79@QAvdR?iKXsd%R3iZ*Yt#r^0DiA}t#w`}$YUA0cS{GG5GY(Y1=ZDTK!cakw zYxh-!vCh)1Pqex^U$yZPvh&u5x~&^_Wid0mV8^IqCw4PSMb+91ZxaNxS*}s%*5gUK#YlpbXj#V5k~@k)iK5L6q2*lwGPs zKvO7?YGyW*Z4M=R7#E_@jMhuW+lOMI>?aARR@7mLoJwnoC2kR-rt=r-0nXR-gD*<$H0uDbG;)!% zB{Ei8Yicx6LI5R$Y*PtaWC;47T2N`P9_HPNFGgSdS2^~l8ecK}>UAGZ&RKMcI>Snpb7~7fStOaQ`iiDtx@Y_?7KRoiwh(^893Zq(s8dc# z7%*oiFjyAV4_Uj{8EaPqr-zoMgVyOY+e?N8JMJxMB>0epJ{%uP^53O zCj69xl8th>yIL%z4r@O-Eaji>Q1h&NbOMx{9+{sE0n49$Y@d-)H&z9DkqZ?+g6J z_RxHbHC^hrxdPmQ zejq4Z1i?`|zc$KQ6D;85R}1oG>q1v4?!N{5jkif=YievQYksfwvjC0(3P2FfSU!q; zJDh42XvP4#W5=Z#4OF#D-Nkm`a$3fhFAv7go@%}E901`s$P(io(JF94wXhf%R2IKv zo0l68n-StN>{mPTbE?iHF`?D$WhQ%f3M(aW*WAzQ8#)VK$W`?L`@8n3D#8=x% zgcM!(a@?Q3=NQKt_=lo3)q$feq)+I9b>4_@6r}LGu5+o1zs1yb{aQ~cTb&`nS1YDR z3)q+i_=#;ewMB2c3o0%Tl^rZBnj1YuxfR?NEmk_i3l3E-DkNHy9|>q$D`vtmdAwTw z;Q4-B6~6a}a-JBd*Q_QlIW-8&*qXj^Ey}>=l3#3~+H)xxc#bAqHqB}z2>m62&lut0 z_Rzu$k2}fZ^bpc-Y}f#u!SqGg^4TML8k&6Z`8%VRSd0$Q^%iRbThgheU$w@TCs+7X zsP1ZWr5eGRc3G)bXiOl2%0b~5D;h}2N#0JeaURQFx!IPR@^Z!kiBF7lA{SevnuH~d z;o8EHn-9v0kO|_{p2j8fhXM9sx>p9 z*jfnnO$)B79ELf{*bb~5nF`wpj7+#VDh<`&G#q&{LPTQ*W$ujv(Jw5EXEdmKbA_Qr zX2=J0i~_SzYZK`@4x!i*&Z~Mg>mKH9V>4QunT1T9Ap0xqnhn&g!-qQJy*W1nC6IWl zIT!c(IUq%QZs?{0A-ijqY~=1+pU?9ciBW6yn@_>0a1JojQwV>_Tivj6_G(CPQ?nX2 z*no4xACigKu1v)73%08Fy+v*BaX7!T%)4w}f0Yd$zImY6c!T#faTVr0y4m6)lfG~- zbvJvOvw4^1bTPx*I+xw;7~pP<84wXwx3__~$>~%7X3OushUhto?H2pGiQiLr_c=kl zn5fQgqqgsG-Q!fXBI>S7C74vFubS%K`~1TX-sY3mzN*Gl8SdbAkh;A*rtX?Owkoax z=C=OtI4I*JM8Sa$v1l0mN!*q6JPiZUJHMiEV38^$mJ`c?r2@oK#3HeXgPXXCA&!Hc z6bj=~D);L>E^4y%Sj9A+C?bU(|eUt%ynl~eNz zx6k#FtS(4I`2DbcIIok9h> zO+V%2*ykrKN@k&+-vBxNlsQ$V7H+$p@;a0LUa^g3)UvMD48 zWQo`YQ0EL>i#JSEB7Fr7vRYH+TrC)6ovk1dT+tFZB6oXTK@ibzR?35Q6^dpGwcg8g zZdfp|fz&Mul?IyvqKvHSRsqD-1!J=XdgVPx*8uRk^bYvd1n6;HyEV{xRaIbKWmm2yc0ICdkp&ccpsd9Ki$pY1R9lJ$OC_k4ZvzDy4HNNmr$Y-CxZoqvh!K3Ong&Hb zMe;=1RSs62V0FPLR$Wm;ArQ>8sX+2rLL*&Q&T$F%MTM5xH-NW*km?MPpqN#e2T}|~ z5R-YwB+p&TtnQ%RryVwt(i&t1vI-3_)=+Dt2B~WWSTXc1hwxdtq-!w9xL%~o)M+lU zW$ZN<$ui!RoEEZ7z2^p2nVKuGx=@frvP5fZmJPJ2x&Y!i&DVk!JB3PG>JnR~R=AVQ z>VRA^11Cs-?gU#Pd6=z)L7C4>gH49#ydmj^fKJiYU=(H(rF?%pNCx6^L9R7$6%6z> zgpkGxGbVMx*k^%|{XrlY?a$}2gjN+}0Z4}UqU3ym$^u}8%!GuMke8Vf^@o9p0S28h zmRl4xg;m%dku@_5XjIO+hrt0fqh)9Wt_WTgye6oD-^8w7sg9r(D7DwuAur|5*p5ip zTINRXvacR4Up!-x^JrT#6Icm|S1fs*Ouic!bp<4huj4h)5rHHbd^a##0h(Y+lo{^u z9aBhSF~Kj|h#9_tp?pR9Hl53MV7f+@?6?(tC%X6+@ykbsy2s&_>hv!|G`uupFEJBw zTgs8+WVqEh`9f4q&%XJ?)ko95_R~lTq$8KmzjN(0>GNZ1y4EkI6HPns|EoTl#vb_h z{4k}AF8Onc5(UX&O(M#xa>v!}zqKtj#GY`I2UxgY~qB0b9Vdo zERKuJ&Yz!2raW7Ba%CSJVEQMeE~h$X_U2^y9|v=K1)bTKUEGoGz9+P$wxpHXeNyJ= zcZHwq9bHq}K=7~Jw9{#w5*lIx!Au_lgjOB3AfWQ%1QSE#BN#+chX3B(y@U{QMxDNv z3~(QNdwZL`yG?HI)(Iwp`Sqdb&l`3)0>6uBwF=%}a1DxXv=rCCGdeibekyKdFpOM# z3tYTqtHjm*0sE{p_e)CEphbO%>dmUGo9k?0TKJH-w`Ufa?y%BqX{4}enpW0Isp8x9 zNpUqwMbQ;yQ)^R)OA*w{J}!ds8m2X3M3kV{{-`bdlX zY2@iRksVFZ6x9*H@}~m|;#vX)9&E3Wg^ZT51v#j9h4Zjynt88<=8qQNBr5d&Ffe(6p`WjgGxA%0V+b3S->DLw6mr2yR^9vaA;TUhS;?Bp?6s0uw%`=iQ;z^)P7RPrYtl;a}eyTumu; zG`3p3*5TyhPfKn#RyWlN*k`*&S5t9$*|M~NqBrNa#_L67-}J}P{7MN#)L z@#P59;~=m@=Led*UxT^3Gj_uS7V|%Nx;Isx_vWa$MFhI${7PMgw^2BzI*zk7c$GzJ z(#-%bBXOmVsvg>47`OxGc8t0oH>EXV)k`*Jw&UP-2&Mv}GJItW88d!99e~&aK#wm$ zIYQ$_qODQ~tXeh5zCq$%LKr{$*H~}0q=@eKV+BaU$c7}I7P;n!)JPxI_`easrm^w< zx)K#lipQ7{IH?X}8HCqpcT`}M5_zGgq(n89nSy9lM4#m%>Wb3P<)}-=Dj^r6l3pi( z;?sbRU1ck=jqke?$$LKeo9B|?Kinqd?6CwBmIqis>C${8- zv=pBP51_@o+DI{Rjz32;DNLYzdNYC;-+aY{`NRTja!AQ|4U`GaRY@e5&vZ-Y;>5;iwrsxoRif|Nj z-P_V_rU^yd8&+UDiMXGPtrFH_D~cc?qQVEXu}O%6XR%dmzRNy+iX}hdfP&A#x~>~s z451bcBrKK;ipAWEAeh4Y8vbuYCM7YneU!`^Ss2i%Mad2un^3p$^m=E*L@B0gV-c~NO+lp6TXw!>kchKbc75 zQM;>I;poWoyq`b!KprKozcEez!sMN41rwvBxLYP&Ny97C4PiXP?g8EW2mY|XP)*WInct)z_uz+Nv1>s!8lK1y%WynfISwfG`SJw%=!Lv%L0^P% z`iI025|ilh_;Y#mVbP3FYZy4abYb`$?D%h?71!k-4Qx!WE`j z0)0&F|4DY`>d;OIm1N2Q{uvs8RR2Ob(|l}%dZktA(7Vhl>D8i`rN+wY?FLOlt!Y{ z7Q%c6$39?^XB~DLT!;RgU9h1Y!=^ayQNrf~{guviS#O$SSmeFEy?~=ur3%sWzQa(5 zC>Fa)E-Vji{Fn`{1ka<919)@_>h(_bF?mHv>30*}Aa8-!Q=!hlJ;8(GP{`cG!YBr% zN?jGn|Mb#{1kLS4f=v6Tybw1F6+1Go4mD~}U!^|uL9XVrCABJ%#n^JsK&8eI9-zJj zT-58+E0f8Qih#f^z$ggRdD}tUS}tP{lsRAzhcBD)U8Fe#hZWw02GSelzdn-BHGskA zMe}~wu{4d|TAke6G9-YKZ9&BW^^8bg|D{w3QE5}XgQyV}3Em7zGC%4ssOZ2B32vXc zSC};G6XzSzg^FIk zV5)Ue4$~dvby{X3i+mo@!{fX3Wu_tAuD%d@0A-CaOxEQ((?L4m2b@oZH0o2* z?yc>+23wwq4vXU=x-lJW4r9@oe&fwCvmu|HgUzwlaM%+R5|&52%;2!?`YTNj4w%Zi z3c+A%ghRZJDZnaeI2t`!?UkmgLJ-xPPNUlZFrnfr6EAM9%lX?^KW?+!HYk#zJ)qB) z54Qv1Z0jJH0YY6;@c9!nA@mC$NejcL>;i=2G1byCLSovi^WHb&%;$F}qBYC_U3??ZJtfSL-(i_$L|WO?KYQ z>1_SzC^PXkYRH6g(L7iqFOQR^zXMZU{!#hWccs;Z_BECn-mjSg6TGO5s9fW+aR-6< zf}k0=$qEGdK0HQM5jJ>Pr-RmATz>|HhVF&cYBi;BFCg+yO5D;unZn^4HdoY20)fZR zU6xbPWeRuVk3n$FWHs1OxNM(Xnd}101f7bJPSLR9>`O;9!#Q&&E)&@#hh z)Nvl!{)c`7O`yqF-;eY}=IU;Jtn^)2#S5zxr!tRdy$oFrXbBE_S!L91MW$z_RXl$< zZPv^2d}AnSJXd)ri0`5{lD#4MkK(FA_Syl!)__F{XXVwdXLk zed|aFjpqZ0r>-!*$I-HcJ)+_Rb z5Am&LUqye*iq<2;ie-JAZ z{0>BNiX2e*jWFSX9tJAug>}G)E9aR*H^XNER%%J{8rW7ds`N_?V`1p1Rjxa{!M~SO z3b&GSO$|Dke(Jol0E;`*iPLE~T@Wu^!S*;xH%Fp5B{U!Qp!qO}CO6Rpwmf@hq^0vD zF}_V0zwBas+hhDPh_SZ?CAKoFA5-B=i{_#NM`UbmO8R|q%^+H9yDn)-PL5AV!qtHF zyfBqdd&+-nVNGWiFBt@WrkXbW`?P#Z1ZDvgxC|GSr?f}Ly%1jY zK#f(dMoOT;ygGqKP&|pgFqcfgk=gyAgpiTo`s7gCy$Ko*`*M_|u|t+lu5@#8vnW2` z5W&~mOa_cMz|+zYo3}4HTS@ZvC6jWqX%(=F4Xks*01;wqA$|=-$0Ehp!J6!m%ROq5 z#q~BM>H#K5V>$g^e^`7n;f(V#Ju(rB>%7rXT)-&P)RadlD`oSVZ=34WQB~eYWE8>_ zkUFFlqjX1hW^n+gN~XsAe`+`dTR%h{>8gOaC?@olgP&$T90#SPJpLlDkZgI01t_XT zfi4)5iqT86g50`H5%cdtZvSS^h^-N+&IOD1;4i;R-@uFW>q%}`w)*V z4{_|}vJMl`>ya8%^MM*+BM0*l$mHCsn|kM z=KeRVi>v|W&Y$4P=4W`aiSeX$(3oCea}ZNIOlI4f%!p`p%r+o5qIPU6`I*Kz@g>7< z>&xY@_K+&aJL!j1G@$K3|4tsaaM4`j^I6U3iP9mD&3eD;ZUFGjk&Y&}dfJ1;mAl)E z74Cc))AEto|R)!kc&4m z!w7VfBL@#{{M|<`z5%nS?;!@|i4m`fN6I%@>#3S2XQOM4t|!`q}TFL6_&P|I;(*KLFpYzHlMW1^`@24hR4M literal 119986 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 diff --git a/examples/SmartSwitch/data/worker-css.js.gz b/examples/SmartSwitch/data/worker-css.js.gz index 0ba451b948d8798fe8b21a6e20d779c64ccdd0fb..658f04aff7224a0bb99abbdd273f99d8ced0b420 100644 GIT binary patch delta 7007 zcmV-l8=&Nyl>(oE0)HQi2nZ&v2VVjJcW-iQWpXWJb8{|ga{#0p*>WQ_@K@}C3L~s_ zY@jF@uhzv?1yw9iTrY{CW^E-Aj5S7*2}|OCr(5?NCLAyEsMUA3T4xH`PL7&Sv{7Pf ziq-VyD7QwmvgG6;d{0ctsUZ))*J>ger-~KD>i$kNyp#?qm=d{?o0YgJ&FceiZvemw zEXb@>kB?%$uZ6^4S?@WqqBz*_+fgWv{SG(u^7*!ZmAY;C<6{}WS@g4WAZH&bRllAe zRBKw4Z*>Fox@pQ<-CB8?F39T8YV(q7UElKZ0WqthX>SXPt0djFO{J(d_4Zdlu)il~lx)?$Zp5GbWxG4(9yAoP5Mm(bA|$}HAXALJbFK~j zp%KP*tbC{k9D$L#T5QM+ux8`E%MCeMN!z54!!#6`f@YF zzDRNk*)C5sCT{YljirEW6--g^-LYxxaGDBlHZgaqy`M;aKlu#fTNd}N`jxBsFM8s+ zm1I(HxBOuAq?OIu(d{qQli0s zd%_4yz5~TOZ8n7gKIeZNT4glT^P75WTJ^dl0Y*}{H8Y7bjf^s~K~q9Ks9!aFV%ka5 z*1JhD^SZXol!A5{#Dr^oN<4cP0$hNzpqP~H%zcuKO6-`RV@9)w6BT>Z^t-JR;M}rJ zbk1d`At6xpR6>X^Q{8by6?uq(nKxX2-kLkc-dUH5N$Sg@nTFDi`b%c0VY%*vR6`a^ zKvjS$+0~|xpG_MIcn5u8R1JM#zz057m7-actLft89et8sEMx-6D?E>a7M>Em9KT}Y z!X}avV8HosMd7x46_Mi@i7SeK{cA?R@^{=KtF&e;7)Q%STop#L!keTLlIQ{xlytdiUMldWg}i) z^53~MKl8mXhAXIdpJDqm*Q9EHjG}E11)(D6ehNlsFg1q})^JQ;A1Old*G|Q+U^?nd zeWQ~eVir{FDwAeq#{>0!n%>%0P+9NeTxo#C$*l%NS|kvPHCUWh!A-bavIX0^Ks$G0 zdxbN%pMSIHq=^fq*!9&Mr9%=ZqUJwqaVzU40I9HOWW^iJCl-0z?)SBS+!1KVtJvI- zyy4Sc0yz{0?Z_W&rOmL0lgbbBSJ~dniN~mlS;Ph&LjgPpI3@jr6kudGJ4@l}a_*x% z|H?4$gcK5f#1oX+)LLU?Hmm4x)LEB`z(BDnLukGA1E!aM6sli$sP<Y)!fVHtJAnp8oUn$^rE7qUQBO6sy!|Jx zf>7k_Q{}$mzNS7~ZcrIFU408ltTZ2`2n#n{IXSe_t=bTjvpDd7I?2qoMQKZ9UM#@O z3!L%fjM-faz+SK=;m}M=ua#Sx!ctCO>$fkdV3+s>8=zGX_q`JPFZs>5k#UKqsMj$O zeJgJ7o}dzeYTF)O+ce4voK=QFiR^@%6NBOAS-4GLVs|hjJgzp02U}3ZLUdO0xmwBD z%%;%AMc8(s09LerR;6NX<>9Ex6fF^lRO71bI6r&>s8N%NMqRRf-86E4e4KI;XGW_o zhRf~6gtosxOdk4Hfa=i-w7{yOonA>BVC59f_I0NH&W6bqbB=5M;>xKrambq@sdP31 zNmjDFMs>e$U)G1Skvy+IvfHp_#xRtXQGUJ3V>by;rb^O(@>{-df9He3lIzF13NprA znz*sL1(|ed6PW95ec<2n+t2K-!Bp-u+-zWYEGx-|Il%^3V@E(B}^N{$l0C-*WS^hGpN^ zH#eFaJyvUfFc$~58JcS==ZB-dD<4|RB`wIW;#a7U?`)|1s)E0v@)IiEP`cqt@!cno zs>2j;3k{hss6339V2T=xg@Uw~Ti%p}8U~tuFZR4W8i*wvk1PmPr&Yw%+dFP|`idf1 zu0rI8g(0!zC32u%$Qb^%;k61v4WUk9MwhQNp+!YF4VF-zy5Kd~B_Tr*riX?P|35rZ^6jTh{*!Le&481ol4wVP=zxA60 zgt2K}!4%J*oa6lznWN;Ry1jp9@bBXzo?11>y@a;?K(T`(DsQbewSsa8bQPx#yE0*Y zE_befM}{7CI<3mS!-W3qw`1LmC3q5nnqkpOt&58wB=+HV>Ost4fhSFXM4e-#rZXYV zFT-FI-=fp2$yG7yYKf;&vw;G$Vl#R60zv+2di5?O<$y zgb8X@9F`g?ovBm>r^G3Rb(l)jkxH)^j&HUoT$ep0Wsy`D>7B}eHtS`zAo%rcxqkLe z^%SK?TvnFFd+z{o*Pd@$lgbD<4kmZ!W1mu=k7TonOuj>t5D6&(X_Gn$Jb%k$W5ky@ zT@hGuGRC^WUYqBGVB0eAq89?JCl!C*rAAC1F%bf2!-->UUa+B*MFrITc?9%f0hSO! zcGu+pKdw;qf!Di2{!ay1Kgs{=)`221R|Dp0m3gDuy`3jC-n}MrDxu}|j0c&27-)?y zfd@`Q^(BlNXCR;_HU$O<#^DDDnVx4HeY&(^ z96FeQmR6@*#koAQ&SU9v{djILZUbgy#Zl9?XDDqet0VJ@#|h* z_g2eeGyROEV0fh1PAISw8aczygWHpw8_-)NQg2T(K!j1}S*bqczip(<+yzUFY~$>~ z`_DVxnEL6>Te6Dx-jIn~mk0DpBkH7@z!_|n)+&sA_; zmjKRb4~lENRU-bb$a7es2mLq6r8`jM;P)bYhbMb>Hxybt2?xr%6l|kWKvFd2ZIkkCwEQ*!C-3?xIm%Jg*Dr;`A z0B6fK-lel8K_*Q5_e?_GmJ2G#ELgYL%eKum-Fh`&{E^7d>-tBA^ z`ci1aC0B!qZ>;j1$!BlQcx{PyKM<62I5sx9^317zCD+AK>N{~`imJfS6&vWK7!S;1 z7NQcYh=B99{aeeo6|k-n6%As|E?OD=V6!U4m$j$luG*^gYs#t5phKy_ditQ`{iW?d;hmf6HfxNH7}uUAH}QU zv7+(x$UKDBOstQUMUD!Wk{&^owY!hAe)C4kus5xES%bdQ4%STf@n)rT2G{trZt<3; zvINJR?J=-D4c-6>AMe`~sdL9GZ-3(9U_ko5{S>w}kxx8AiJSJwHsGCO8@5ND;!PJ1 z_s(a!q@6U4Jp8*Co}$yabIjmV7W4}>s!R8x*By!-q@;BucIUp#j2zLJtonK1ySSrM zJTdAcjc>SCay>jhtQ7mZXvA~Lpf_X6`6N>uVE!vNTCgV#UPZ2|AMwc20)OKJ%VKK- zSI~#H*;RtN=Xxr>8{KiNGkI=wk^<+q#G_lm0*l&oS@0eY1~W+qKzkzO6B5q(dUV~B zp5F2otRn~q!n33?@8m?s)LBJxBE=c8pJOaG} zLYDu4G0n9lgi!N*0rO)ffPcz(5U8_*z>&!?Ncw-%VSY+SvI7jN|KW7mIy_~gPuzJR zJz8LxuZf>eX+2D_H|;?IyDEwe<>?q>vF`U){fBoB!&Q!#T;1{=`dgQF2rkkk2IZv6 zP)GWElj@+tYZA-Nk2v_wT!?ow&JJ|HLMw6S(?ZN4>Xuc^4ii(3(0`|tjFd@<;begQ zxFAGVglDP&{uRGRIE+jMb2mO__DuatJr||($IM6P4tLpA)OB6>r?HpyB^k!f_C4|F z?pj^T$7^L@*~x-QJ{*&%61*4 z_#?sr+W)tWf%=b+lbI1P10NsVlgtq@0sE8w5upU_!ebbdqY`leppz97!~&P9liL$S z0dA8Z6ygE{>9YhCeE}d~Zg7$!-ch5l2b3%T-R(S}W_;v>!KVYX2O4{eBxAahp%x$& zggbXIBRX`O@8~TK?44NNbJ?SUXp`0!PXT;s2VX0LOq)yu@*i!y$0dSljR!Q0Z@~{8zBKu zlj9qG5Fpp?nV{BGS{HvgPmfgW;s&)cwU>q6rQDHf=CY$ZiH)4}TQ=LeJF zA$J1Lkh5AMwN-yfuM;s0{wpO1I;F#uN*qwPCj>$Q0T)&Y5Gs(uK$$>iidfqJ&Sz(D zx=}U>ad~gXah%j~oW$eU7sz67+({Y*HnSP+H&`&eqVd8X91UpiuSN@ZvLmS*FX;3J z@i%f`Zpb~#LXk-}HdR5tJ#s%g#9{y0z*#C&i*kV0a%g|)k^I44G(M3hjQ``N34*awyz&M zY1_yo&<8yA5?tMSYq z7}c=kF`R$lv{-2Te5&6xnS23@%NhRY4|l2_;RC0A4p)JD35VPK@wIK&aM)7p-Qtv~ zzRFZ*?y{}WFtQ9p5c@qgb%L&Ub_1jIT46C#z@owb(Z&+%0rCRb?8KX4`r`L|6AyL) zKKv&YY{A}|Y$u4TrX^`zV}D2+j>`_!Pn%B*Jq3Stm^JDYuBg)(qE6?9`WZIhdci?P zq)7A=s23?G4%MRe<7$VyWcqF!OnGs*F1K+MGd7|phOb`m4q!2%D9)mPNr|Kwo`8?V z7`&wYA!LiutNJRARXiW4q zilFLWeE)W0tpBN-=f^}#;9A#dngSY(cxEW8Jy47tY@%4n%(?*~!}6jrgML81DvMi4MS*ir;5hi$ewI zFE5KYonSetJK2IZ&fLA#3eVoi;`XZp?JngG?6$>Zr2RTD!~mm5dZpvX zT7Dt{9-G)MEqznR)UI^x9+%-ih;xUd@D@_L)loP)tqpsyVFLY|3A zHigMUT2Le-Dhg6L){q(@Is+kGI#)ZN$oDWawz>@-RP+KN1EI%>Ii$t5*Ppc5I~Lw_;vOecil zJ7r3@MnyprlQJXk7HST)@v?E!tY7n1`-4K0^J!VNkCSO3_DiVPDGxFaBtnJ~A;hp6 zSCmI_NTsQCaPm0vx47CMxNd(O=%g!6)ZKn35d_kWXH@|Mj%-NvG+i-h5rQ9_iW|3de%fMfo#p%u|0silQw#9&{cM zy=sKe5ku!q1e^e}Wkzn6?aQEi@UoX}i zHE3Dl-(ku2xTgyDH=Td57Qv&Y<(xA1Ut0g_6*5=9a0;D1St>UNww!wGPS<5(b-8VI z(NMYt+0Q!SKK6JVU6Xe+ZVE!Lx+Qed4#ZA$n|K*ku?$Z}=bl`YYOcE&f2LELr{#6?z6YA$OFoK z+U5!vL;4)-Z7zRdSR}}l5W5z!D{N^kaw-m5F?)ENj;3{U(_ZrK2}+RPSmCa1N{9sU z=~Ei2dcvg&rS;n+7c!j*}lfQEe0Q|bdPO95n#3+@2b2BZo1-j}=tcZxgwkSi{x zrtOvqVLrJ{PdmW&GJwc5Gq<83sgUYRDz_pO?=kl29_1TM)+VUO#eS}BQ97~*UTG~G xcqJ=D<2L{=scB~YnV=5ZJ$6pufhna0aLpIa^#oq}ERxV%-vL{_&?)x<0sz7Oj^F?Q delta 9568 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 Ks4O;XCISFtYmQ<7 diff --git a/examples/SmartSwitch/data/worker-html.js.gz b/examples/SmartSwitch/data/worker-html.js.gz index 496312885798882fc08b5cc91d5fbc1d686cf414..1556f5a8dfa9319797730cd5ec88e48ac19f36da 100644 GIT binary patch literal 45019 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 H;4A|G@j#CV literal 47406 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 CEVTpx diff --git a/examples/SmartSwitch/data/worker-javascript.js.gz b/examples/SmartSwitch/data/worker-javascript.js.gz index 9909a164a99e567cff41557c05ac26b9db42d6cc..2b45889847baf8b0729068fe6bc8691913e6dfc6 100644 GIT binary patch literal 112558 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 literal 47729 zcmV(?K-a$?iwFoCdjDPm0C#V4Yh`jRYGHO^b7OL8aC9zea{#0p*^=Wl@K+KS#acv@ z$#A?lD^i>VRb0jOG8-swqRa>qImimbGV#CDYTdTOEX&JIEcM;3R;#5gWHULne9~$q zHo90&cPF{gqLC#hkN)>Wmz-+y_-Cyql5wh7Q7j+s#h#bajtZu4<$5W0rG9nf%?<`w zVQ9*`f+(&}N>0Q~82}N!=lf<;8~Ss_kNbMV%j*}{@4R(Qi|c~SN_9Sq`Jool{FU{A z6GUf>O>Z0x5W{e9nVj$IR(~nC{I73!CEz1$3$Rx=E?@I+h?dc^5RkmcNs5IYu z0bCcfC7lzBcTopEe-LupJWN?}0?Iof`L=lbZ9d;No6~_y?W8cQIOy=lNhpr<27aAv)&ea2oKuFy#)?@}yv+>!RHR+Jk=Dt=R z>2g6J&gVr~1eOg3U+V62WO@&jN z=zG;XOeBApd}jPx77va3ovZn8?Zi}N?Nd<&;rr7Ab9r8rm(>0{I6r9bj#ZLuHNWIy()v6m9)n}%doJ(vJ!9{# zO2s5~X;Du@Y6tlx(^Rumc0#Hl35aH(0UX%vx(}ah8wzN9d0m+mIpm5zkx1s*eg{9x!nj(J5A&465L*& z_Bv1j`jBBmlxpx)Ai*@Dyz64L%i>@djr(N&G%WM88m-<(J5L$Bu`R+6G{h9rwY7C=kjs>A2rQUg^ zlQA`i6}IOle4VEVHGgp{ehJ%Aw)Kr}dIqwfVq59BD_a^y-ly?Vw}L{=6ZT3CBsyCS zh*%^LYI3mXmd;FAE@8q(6SQbf{9c-!+wH%JcjCrnxL|!XH{2lz6jAeETX84ry&t3k z!N`*Dp=3nhO>;QZa!cSt-iFULNk3fJOF)Oj&|36I%(MyAa8vn7{w|vbIdKqGF$>T@ zW5|Ge23?d-NC8Ub(OC+cm+3I5+7GVUdvPd8YQHo#OTQ<1T;Z|-G4enW+8VE|m(dxZ zPg^SRUWegCXua`^DUVGGnK7@b$YYV#<{IR<=St|d7eXNE>B!ZuOj90%gMIt*H@?yH zjpDWDrH(W7(QIZ~olL%}AO!X&6KGsQ(pF|;tEM;f0T|ie3ku*nad%SgyTf>%AH-im zrlJfNJNGL*6kUKA7g&l6+B%Z>(RD*hsaoFgr|o1*z7!CMBHHvgW_rqtb^4idiY zkB*8I&FzP{a9dp~%^m>{3}vA!?H9G&+8OC*RM#zICU+!6``I6-dY^CzVg(i`8Dosc zueaa!Ou`)g#+is`IpcIX5V2E;_~}&8%@4SvN8!9|#rMYO)#SFAtN$Rge)9)2rpd=*^c|nfgDT)i4%-1I+~86hzYXIYT!PrDplSnVUJ@OQE6nP z(g{YWhI(aH_J9-usT}CtN`o}3n`%KSZHo5Q)w|Wxm{_x?;4SNF!%dTH~NyAzTL2Xv4(lFve92nWY_?oDJLpQ{L*R_xWrrhX3Al)GrLV z9rt}6`g|msbs+MCQQ|Tgt7IS)hX$ltuE%Kkt^i|2gPFBhl|w4tAGF64y+x|BKTL-t zG>L+sWu6uzS|u04Ph=wGg8^p19->HW`RgyrRrDqfozJOfaA-BXf&Bxvmy89@zd4_A zqA>fPNsddJB8-xpI_$5ZtQKFH?TSDfh%uHsd!?TboQ-MV!=4LFKB@Tg9NR$h2nizq zHrzN?`a?G4vZw&NzmI@C%#TGt;GL`d|JM~N*|&PmiI1$yOA4cH?V`Md!-y9R4{^;dug$fI-AaT0Kb`F%sfxNIdj#cd9wy zKGB+nZA7OMzfjI_`uR)qfuF7P1EU%7C9F)6xXF!O-Hb}5ofcT159gkixXmQ?N#=0W zucFA8OE!;sxiaeoR!943<4HEtoJ|O}E;PB)5kd7;i@u_OPZgZ!>(1;RuQgvuuXk#ne4 ztb|Shzn|unqL=T`{K-Fl)r;$1wLG@d&scPZ0}9^}r0dAY!9R6wk8`F#UL{hePgFo; z#a_!)f8@;$QhIKkB}R^Mcv}B;%lEo|`Y`7wC(4@@Smw>xFD0B{#dh+kp;#3ZtkWBV z2CeP_C6Q@jQzMqXHs!f?9DF-%U^0F@XZ#ic*A6byZJmVk8o#Hk5VGY;7l0kd6gS}l zW2)4&Kr6V($>G%M$xA+YX7Qd)8Z~)l;hz-*Y-;XE+6m0+T5e1gh?hp^b0lR!0;O77 z5Wp^{+6LeGJk=QKnFu&_4Z|t!QSsKaqKIoSISNa(pj%cMcN_{7+*yQgO)~&jUL@8s z6k_Qu!xGC(4gEHk&r3E=bh1lKHL(<1$Ejg02CH4WC)WCCEgQ^bbHA&RW!X%bv$FFp z9$4(iZR1@&Wv5&?Y)n}34mGrFCpbJow1RZnHmEQbdkqGEL8X&4DBM@bIxWPUTA$BF zv2-nAZ#CN)_HkCBx=sV!Et}AQXE($UVJ%*Q;$gpBP(fy1yTy8z&I#M5L-9`RR?(X^ zh$A<(E*%B{;C0uAhyL4%&~YYa)J)C#)?Lq7&b70*wWyZ$r&X)A@#0OgW7=oUr2_4C zt8vEZKuszyajEF;NkS7NoL27$=yP zn&WrTpfEcaW5NI)trb7D;vif;#9ER(6Cg|9+-%rl**y31E}PkmJW5CprQOa6iap{~ zg0bDftO6zVz?;6-Ri02sLl1tmYA#283eE^N^@bc%LxCD9s-Zv)35zIY4hx=Ntk;*w z9mkVh8cZ>7b~_kUU}TpX@Jb@w3X+bXbebfk3b^MWT3)8*oo2j4Ia-cBiBU5q)OdI; zC0+wwh+DH_OjmpRE8O5&u_PGJr)Be-3b0*-L(>Au-WU^bvuVn*6cp1HqK{Jz{?JI28B_KY&Lta04@*c?j|?|GEJCsL_8 z!m6XZI>M-9qXq!$?H04pR}ht4ay8ia#xl=^cy{WH=N4bED{#ss81zjlJhP(T%2jca z?Y-FPqAHB*iZ#qq^an&S^Iq{~fc>u_J}t+&8bi2LsYPy%NTOr*D-_ z$@&p88jt0-8u`gRo_g@pf6ZTl$52yehg$0zYB)~(iweoo7iKHJF5}rWKeSat0FWWS zaS92U=XIuB@o(Y*aQ1(v z)S(lQ)Vzc?eGn&#g9^&i6LTZ9W@2@!5I6{2N_qlOR`xy)?dFt}{%l(DvIcpl8Pu%p z!_7)*6|S+@+L&9K3K32z*^?*R4IT~%=kL4dsY~sZw@h=;1O3>13dfp2C$vz)p*@iG za2LpiZimBo%lhMcad)p7T=8aMnk5K)(HOjw-8u5K9p&ZoIV#8dus7|K9fTwr5~mYe zCQ6P-OqPSV&)YF{iXEdK(D;FCDObb(VWrr=c_Z{Cz1)l`Ym-E97<0c;r3HIZ;bowz z`W_D?aWK5fC^qQ0f<89;Z6&C^$5-L8$(EZulg36C6j-GN8hHluBx;?L;5`})c9Lv> z_E^X#I9#&zXx$Uv>+la*&IlI6S6IfDWaSoa=teH+MOa8TA$&$C3dt=o;@@b&wamgZ zSVYtXsoWqBgH8Y;%hw=GQ)vkyR6k$9{+KYJGBg6)q!Bo>8G26tYdg%kbR=nD(DpUA z%f`Yf^ggluKzhPKzh4u#pVE35VsBxifZZ0wn)2AjSgiW9m3=uaTKo(67Q$wZuerM8 zTVwCG#3i_hml%|jDghmv&o|XUhHptoH$R)jci}=jk2qZDu0ku#$)^FIgV&K%hz=b> zj?kxs446@fd^7O#P!L*ExEINO{2TsY#$jcudIP>Ii6iPB4_Pl=ZZn^(IqYRuQP*|h z9ztK&*JS8BoEv+az>~+!>V-VNP}g^~cp(eo=;80KdXfxI1tRAc@;c-j$clX9G#IfuFLN?_QJHe zp_=bMPV~M1<6vs$7YkXYYQ%c8e8hEANeT<2QnW_iRp>2X`l@dAx-;j$!-Lvu6uMat365*4k`In$=J@5s$_)oo@ys>E z#DR!AVn9D-?3lYGJI?`)ZY-nqO~c1nMA}hpzXvRq{CR&4-xT{>RC9D8)E*r*Ghcp2 zgHTsjFqPL8PUMSgH}{+DFx!p8zTpy1+GTNz^9)NJ|Fc(msXo*H&~~NmjnhE*uO#KN ziAoc0oT_=a&*fasP3K(qtfQ}jkR%5{4W8-}I5wXs*xt_UB zhu>JGL+Lstm$i6GEKKFB3)bl!Z&vW>F`gx!=0yV7IY74MCJ<1umUXPm*^VDr9o#oi zTaslGA3Wpl-x{*5mbYCpBx6pJI34E}B}$Fc6{i25IrgTQNDg4L1xad?|B`v=DZ0oDxI6iZWOFQhg|+A%(~^etwXS!4;D+A@Q{QxiS-C8ZGHq- zl1KL0)1&f2a`yr|-s5Pj8{xo}!i=MQ^4d~iGrvC)0!~uk*fpBG6Q2mH7i6C5yH38J%S#q)8z=~a0_1b$Fr z8nnbSz+n2VvY>1xigh5+E}TOQoaI)$8ah0jaE6QPWhO?F-9(gbt?=p-yOEJHWLXN& zRX$WW0U8hY`|#+P-ZxyjaaS{K=HiL6?VT=*Gh$drSuxGB=3Rc%%{W{*lK0Z5p46<% zm!-*&z&e`UXDX^$&Dzv1psWKK!7?}&S<6t;B(t}@2`%R=UVm%EX-{}Nphf^wsxHH! zPGuqOMmo{i=BPJ=Pbl*p8jktO2}|D(vb}VPJ>DErhQPx*IP1glj>Yr#b{HRq92^eg zSOM{)UvbFlTu+4VOLdBT6rC0&j=5Y{&h0Zdz+fenM@x;$FHmL)=zbpowa1GX46gyu zFKGNO5?uuIe{~x=fxdbl!}`gt>rs{%ab;P96|-5LS2J*;jyU13#j!4S*xxDRL~r$s z-xDhjBqHu$o&L)4;a%B|$II6uc<6hyXrfV{YN2n%T@iM=f5d>fJp~lSD6T{~x|tWQ z5K?DzDAJQK`tsllI&8=@SgY2|Yc2vUJToY^q;A5Zin9 z78*u0#+7J;`R-bktF@`G9+{)n1FKI-iOCUYkyDsYL`R^NLqhviBRJOQ0SDI(sGrp( z%&UZ2X>>6B_9P%)qQijH9tm+EG}AD7F;2>b5Ld4Ql!rui8^d=EB&nCeJ2*=psqOE; z=jc zUX70A-Slg8=X?<(w7X^F_|nt(bg9n0q7tb5lxBdQBBk{4lt9k85fh*DEZKqtShSn+ zN+46~&EK!?*@es2&pbU_efRjyKFe>{-=5NM~+LZhD@x@Vu?wyAZJ{Um;b1)Nm zK=`Dt`{ZNKy}Ue%N{?*m^GWGbw)B;x^wgBTIA5CPVX7bK4ZDxF+g7OY&<132&^N_m zYNhc?Zfe33F0fhqCubp_J!j^raQvo4x-_b^6-^^9UWcfThyZ25COJU1Oi$jd85@fR zVlOvhm+56KD0^7_BI-_IEU|Z|LxlUKhio^Of^NoYSVP)!V9O_<6q&}rY$Idvo1G{d z*Qm;wC73Ez?Z@ zjlRXXlFk=fiX@AuuT|(zxVr}HMeAm(c){!rvrL@9Y+*3l)5_V)cE+F0Z~F5X(6uvM z_?8=I?xr7$G+sV{&aFFc;Qc97s+7hrl1kv7uM(4+)wJ*cIn6VVD-xiPDDR~+{O#5MIjp*??7^be3-T}E?@rMC7(v+t7r`b znnZ$Poid;9)VC3O1ALZym%P3^$0VL*-m~!O8J2VEa~soiVjWS3#+26 z-8$=7Ng_Fw>+ak{^1)~lI}IW z4F|o+wP+A-lt42LBR8)515K8k02k*`PJfN~kSz2dZ&;|=FvBmuHb6c1k*H`7^2b>K z9jxer1?b>0A^NHr?3*TYlJB#dqZ5ffe{VR_p8Nnlzyeg;M`<}F!?_=QrC+h`k9{=a z$ti)B$1nO^05b&$U55<*K@lMRo?>#m)rt#fbG#^hhv@!ElzhisUGv|&2_Pv z8d05{trlrexbgEoS!ao`f)9=e69y+;%8sIP#O#^A#lf|juflVoa@G^VRh{)pP$4Za z3q_R|y>h@;uVq)p&6DW@(i0=y@uRw z2|j0|G|>II$%WF{QKl!pe4@X@O)9hrY%6^sZe-Fi!0>sSN0S}2W7i$C5&JwmbJqw z><&wS#dVL;uk@BdQH{*MgP9fcYM&F{xltg?6Z3lAjUOd*B#A&zct%PCrq(%ViHmZS z!Pn$*nKMH=r}Ach&eD~ljRKtL@YD$+166fgU7)7+h?`?wI=)Jz;9b0bQt>%_ zOna)0z6id8BtG{dEZ!M^@daEdaLQkq;|-;+yg;R|yhNpoXP-4U5gf+XYJ3_g)qDPB zs`tW6%dl9xA>!Zlw9}1%59u=ChV{OE>_4@4GG$j^l1Cl!+Mo%?Ap7KhBty#Hh z3d{*sKoi}2OaQ6XkW(enN6gUnL1%-ju` z4;f~_TQ1yxwg67Fo^AVKcfJk;PN%pZaTqBGu&*nOW_bNTMY@S8J>K)Ai&?l`?&P^= zv;>L64YPpr)x$Ug4lftL!6f9u{O>X}3p<=5;QZ(?PFCr6QnMI4f!2mbmDSV+JneQ3 z9-s5t&kSv7mEW5UQh4Nar3x!5@exne&^6u8S(&|=N2ev9pCZK`*i;_M|C z@U?V`WmYn!A3Nqwa%Wq*J8BErE{l@mFJeFX7rmZlo!OSnb$!0w59Q%CPpe+{FZH**=$rBbJi(#;8(js6Z%tL;K8I#YW_7odB`ir&lTZ_4ay1t+oJ<~u6e>V1R`L)g(pF(sZ#{X}G6^DZ67Ya~JfL$|($i5K2M z#j6{e&IAbrP?@J~&a&O=RaN|V$d@XbD6P2pbj&H~5G6KzBr`I4aO9-r zsWFy)1rbxb!K){rHn*lz8zOKh>VjSK zOa1eUe!J9q@(Xlpi+@*+rx(V;Y>XCJd-fxT4oXKBJNo|n-x`=~Ts!qW7Bi3db@-~% zuY~5u+uKJDzs!C_O7OMW-zx-rv{L>}c`i|CQXZn}srOg_`_{+FJJ5GW3gbmVh1jpnNKeWu#d&lyby zls1yH@KYW(;8^fLf0kLW@?&{RR`;fhLRSIRt#-9c|0-{Zu&GO9U|lJhv(7zwHyA?F z63da}#cIkQW1apX8kUD?@Fom{POV|!b=vbja{FUbZuPw49~vVG{3=JEwFkfS{dzz^ zzPXw#U2VD>q`>$*Eu;Z0*T%nrUjiNV&PaeGFe9SoR`;k z55*`3tl?{1HTA6@df8VTh(XQBW{LS?jjgN1@v7Cu$5f^cd zB#K%uc^!@rX=$|rTpBA^uS*OMdP_N?9p0==?H%b7q+4y@GC5BAmSHTm=~!%OEbx6Bf4I zwLdRrlt6Fp{K5K6owX=zXNuCsIH{IISzFAc29yLSXS~(6LY+xKOVm0$0}}j2d?z+> zt+Q*!uc~1jwNag^F`r7sak4wzOgCY3WlPvp?(t_T12!oKOGNb-7PHRwjx1!GUYu+W zJYwazS~T&Uu_2iOu9&t{6x;e8^q2;t^;k2jz&I=@X+5??B&0s&s;Ey@zG^tKw2F$i zdryv=_5Y;pTA14=g79C#8Xgik(zu}o6ojYH6v88grcfXWjACCBwYKC+a+@^xzw_ayL%pnpL;t8kFvOCz* z47P)DgVO_d?h-RtGI1cTj|V)f%=I!p#S*8cMm|9Z!vmCT&eR4|teDKHHuKNho%0Dq zw5U$ycC;t70vz~TKqrd}&A^=+M;D!Qdo%KmfNO<)X*KjZW$2Pc!xW<{JEdy=Q0kj zx^)r;kAjrWJfQgEF6oyFGF7fj2=6Prk5$U}ct`hY6NnM8;NdH@>%Rx47>3jtRusmVm+ zc|Gyk4zYTR!p;$6-x6MxK}U)T7-6f<{!hYI&bZ6AK6ww_2T zf{h%0P@JaHcJQHPIn3suyH1_Ra_$z9DHP~h1T`l%7cBq$i&MKdGEF-rp+f%oX`-b{ zl3H__wZsxl>Cy}4bec&KF9r5v36wwQVu=@KLzo-lZKEnb%jO#H42;$l!I=>w1%8P( zOG~WQRNPjAVdySX20qv4T^kX)$H>eqIqs0wJmsHLO~W>1mTk0(uFX?-&vm{)Ld(B& z9z@>*iYW7{iY!yNi`kIi=>aU2q-Zq~l+^pcEA{O&TL|z-@6ea(z8daSy(a`0?)nu` zEw67nN_Xv)Bz)mc2b)x}^!L3>)4Q`QKU^M*SLn_et8r5&dr-Fxzfu_&nWTO@q%66_$ zxWu6L62(c@`e8!$a+ICC|9$|1w(9+;7L8;U>&tKsUiwCRmsU4(66QMbbDbnNZS5Bw zF6^t;+G#_8ZnRxUs7a_^Po9$>2t+&U&D6fik$F{78PyOwsp)EmKnHb8W)^Q!X z*;K1~D#bTYSj#EvBpN>Jx~DqJy$@*HE;{!bf$#~pGuvlREMKs9i}%LLDa7YqA3W84 zVC5KP5>lz!iI|D0a2t|DH4-x{q9JJqiD`gME6iyX@C$ZC>XD%=E3Fipi2*9Lj@>5iLH879X&7wJ)iuok%&nxf%Eqn zsP;`J=qS`_`)uE9{TE!?uRlBH(hJrXTd9^Td5UJ=E{P~jvs#jk12c@jagCjDeMB0j zks|~l73ZCLNW6z<^e7JJbP~3kF+tE;na<^a8TmRYlmx(GQg~H*;L(|)BV-jd`6_eT zW3R@dq16oSUn_|Y*S***t8y2O|DZktBlV11Pbg`%ui37QmN;h-^G@9G(9OYO`e^0} zU~73!Zn^rEr%(4gkoyYCI&)+>@l@iR&knor0J5hI`ziL$n*QLoWvMk|3YmIR*la(F zh)%Mm5UjA8to8KUA%zXL?mS}Z#F#;NQU`y^VD*99xJ&5vHcGzs&PuPGid%KHk#j46 zam!LwdN!%Dyx={HYC~(HLPtP7<+&RP0jkd545TX9`uS_-H#bz#PGZ;_+I6xVd9%}! zKb{PbOMy!k(nOLF(9@Nd9Rq|Iv(;U;2Kxjye7Hopgaui(mC6U!2{mY5##w)BSr**4 zOV}d}f(@9QT+-)VotWM#mq0vcoFxz5Cvm^BAPihz1(xl@Z08oLb6GUkH_ZVJ`Be$` zf5Q)oeqNyBhR5M8J&0Ut*&qax)Ti1nJAK5^CXd_nrFWtAf>ERWTOCl5aNnoH{=WK2 zD5TWTA7bHy7Ps5QtP}`tWeV(-N|rY{WSk*N$Hd@ghI*}ZNt+ax(l;w^5?5O^y0&<* zHj7$@y5&h{%|d6zFhYw>P~3UBp(2eQYeguZXdsxNMRub;?lM$cZhPepk2IP=84o3r zWW?sUdtDAZ#*{74QL*1I!rjBJO)7<5?WDLgH5ws(bMngHUBB@rhU0*}zC5X_xy(y{ zYJ&(tp*Fm<#aLfxxe=5n!JC;kVKyyOLk?qF;#(1Tbb(f2UzF=6D>*uHD>JwoPlFBs zz6pZkQxs61`2i@m;Qgk4p6L+J(svQiw$spVjM{X>`_$fbkKa1Pd&W6!Xve4Q;f4(1 zzPm<&>DP5SDO$x?wKg_M6|!F%j?2@p-ON*&YWiPTdODNxCOgBy(r2FH#4oLK5{u__ zN2Ag6Ls!;Y9%OAxYP+hU4tck-wlqTysXoihaUOPuH!AVXeckDB3`lQ6X1=dVnX(~^ zM3UBkik7sUtbDQhTpxC@&to+ENP#Kg0m5sHWoZ&MCIcl9nkXEUFWLb%4CzGQR82#^ z(@?eH$yZtpSBSuUwpRGK08CB5@(t@~47xxUJQuWo7PEEgLp#lD@0<9iLA?9GzKj34@ZfyaiT`SzFJR_ml3#?$?mORy z3GPD=;NxoZucO0wk{ASIC4BPyb#%0ud^kyt#z)6@ z#AEW3^%|bB#1Gk>!#_5;qyiIvG&!1W;N@r&zsV#q05!zBU5JPQ$TRULAoZL9amvF? zb#wfumc%6D#|&xl(NQu%`ZowLGG7u}rlOl0ldl~8I66l9b8@=${P6X0_WW>{9tZTe zpvO~s?9<~bdc2^=_s4X2?)hOwffYSY=#kUolpb?>OzCk>k0m{3^ms*&1wGE_aS1?b z4S7TuJR*pX01=N9dgSytrN?V}?9$_a9vAd@N{=NyX7qSPk28Ag)8i|8yud@F`v_Pe zFr~*iJr;O)80=+Nj(VpkpqdMBYwvzI1u@A8izhBaiwrF?v|ff* z{G7df|NSR;8#u+!+c7nX@h09lSdE;Y0v!FQr^&_v@yz8^catEmdNIE`zX^(8vnN2q zo-fG=tC!-J>}RlIqfA|Es*k0q5(!qpzy5loT=t3I)e`0wHX)6a)QfA|%uurdcVdDr zuWC2X^XBpElCFl8b$cmligbC3)(q|Fk7xs{QQdl;s7$uMtbR73D`O_v5ypP<7kQh( zDCY>{HS66mazx2S^lp@hrp>_q;rYv^N7-o6Y(>Rscs6J?z9k3?9*pkPIVa?)TCviO zj!)+mU7^G!a@!DRvh`|qaJe|C<_!wwFl6Gar+(HSO#?kXMV`}E%-igDUc1GVbKB;X ze8l&nm1Tn(H`#Rw05fgHIXCE1W3kr|S0igWA0(CxcS+TEL=>f#(9*Pl&!zg3*=$Mq zC9*rB&IQobO2}{8X}pzylN(dgdYWr}nbVcVQ0Dj_(7>;t#a;sxjZ=KcwocxV8(8AM zb_kO;W=>8-7gdz>z>g%hZ^%j?S#SmM4BQF<(4rM*oOWhE@1= z&DzPV-Td;mr@IG#{Af%i^oFy)%m8) zUV&d9yr;w3h^N@+w8~mh@GEOSm6zc?G;JBbLGVeN%~83X3h?4p2~%ObjF#;LOe(Xl zX}?#LZsmKU0zljMTgzk`BSXpB*!`X zj1g-@RgonXsT1J}AVwl4NkpN~#axydc;HBlizq?Wv%H-Qn9=5KtZj8u)RJs4|17g< zNk+ord6_|c^koTYLYcuZ;X#YWO2n_QVQ?*e^FB1(zpmEe-7@`|@@Ao%kC5{DLa5CP;Sl2yUlp`bUp{fe-859|6J}Uh(T3@|UF3DN(VOKU$`& z!&u`-v~`x3argA3EoTo?rQhiNO@a}YopsU0b3je$9TB@lV;O8PQS%{*9=AV)Nvy3% zm8ky=Sh0*aeNc*q>+%!E;#Y>`W^FAzy>gawkWtL(ST6@bICklZ%10$aOh&W1Hm`eS zR&ZcJcVA=;-rZu9O*vRgcIEoARDq_&3D$gpA%?J8ZL@Fqy{&$n=S8Vqze+B=D&G{# z>`PAP9&NIU6DayQM@xsDq{VTjt5vjE2U{t1wb&bU_6GSn4mwwyOg_23w<^s)k&Stm ztmIU6tQb|At6({uuV%nyuM|$3o;_5d#_l7tXC{U{(f&#ys!I+1ENwaZTB8I!L_fOkwalqO_ahA65HTpwdtHH7_sq8y&a@ zRIZ+@tq%RN`{ZEn@qSha;&dm!PGZMreg*FBPdw9?>gN~!Stp+VAU|Ma`DgR$B%hCh zJDOEo>M_V+I>n>`QyiwNIM_cYHyx60>ZyJmJ}B+EdDI80&HbI~h&n?0woc@12u5PA z<E$MJEWl*l`QvcoqvK~sv#ag(yLZm4WN5UNPH9RO zGhYAABw!i}aT$><>K^hY{Jfc?g-KIe)0~Q@+Bw2Z08acej&`@U#*t_d6eH5jY~0W4hfvQ04OJ!z!1VM1jIlh&=EbhD-Y2ySp)n2nzN9~PbOA4 zHM5Z}pXlt*s(OZ{2Mx7*a4$|2G@?cKEFdnssru$|IlrW%VVkOtbu7nVhI1fJf|3#m zW;=3|Y0(eV4ue;MUd4xhV6uFe9IdgLa+ASL1u`1%tX8!zyf$%891i1u>8ryYs;_%& zIo4#e%DA;wS$wGRvfMlYf-lJFgedKW6w+Mp=R^N7=5n^xWC_SqiQ(bAIkTO_bdyvu zIvuztrU-eF3a%0xO~HpcIPCT$_H)z0Dg(RqVApbP41VC5JNIPX{7lrEEtmjAvhvTg+V!tZoCXd|`&A`hm*SS|DaY&HMz9PnLDpNf^*dHgZ z4%Qu>dmX+K%nzr_P5u=*h5&4J#T30fOPjTzbvkbt z-1yEfkOX4^Vr4(xj?hi3M9e*dDelYOxhL-9D?Lc54bpOL^LX}2;YbJuhHq$e%|~9o z)kl6FIF(rH?kGw$Wtq>>BXTYmsT9O21Kt{qViI*@m4Wj9jh#2)D$NqKYIbSvf{#Bs zYM?BGYOE3IF{{s-59!}eINl(27nXi_{VpIbRZOpzi$t1=MUayYu#=+Zn-9#jI%#Ci zD#fL_cG~QCDvBEiacmS!ANh#%@MZ)k7L|N{)<|=gaGHsyb~bk-=P+p9Y|_wtK&l1> zZUVUGf~hfmdo&gvzf1mW8smcS0HGu;D6XQ?5G2WHtroPx@t_Uyphcp1XLK{mzNiqS zTCTa&o?Xr`KZn~(dq@BGbv@l=aEDRMQ!j~*$;Icc{w@XzPaF4GZ* z*MI=lHKZtANIJw|`l0Uu$L|Nx2kbi}BUkHe#4Po#;1DU>LU*0=>4T%A=mUXbSnPM1 z%O9_`bxD;SMws!uHD@tTBq+Qjv6gT_G4^gWDngM&)(t8l6?TSp5qr6++C^T!i0o;zLfJg3>?ytK54tUxDdfX-KDMJ-wK|!bvJF=H`EcQm zk8Q6G>kgL9c@6>EAdWt0l@0u|k4?40lF-kj<84k?O@1%Ra;TJ!e|yYVB_v$4TQOJJ zfO#LEex|XXiDZ2mXT=Qn3jC9Xo`Z}a+pYNOe1i!0bA=d}6%GD@Y$oOH(N+9qA6rl- z;1P1ihf=Y%z?nFxxBiH3)?1rIWgBXdex|TNRCDmFA_ry+f>;-F)+_!t9ZHxR=>wLS zH?5&LAcCCz-o5LD71rb46(l(6wt!GDy@w}dO7E|CtSGDzWpZ1qKqf?7#DFxX0paX5 zRag=#&_OZK+xML<)$hK0QEH?~qb)4M5aH}?ZEZ)1LT6id!u_|Z%tql?&!2Kta#gzU&X zd!2O)Z;vCG#Cb*%b!>kDxWwXK+Io{^m4hUvXnY`#sgHzFD2nupjJ!aSq&8Fr(73mu zhlVaK@&QD#yddlDqTT1jBq9P}8_RF-M0^wbrs^Jl$8K1%OMB3YnT^k_L#s=OOpP-s zx~8|zE`gq?F@Du+cA~m1CTrpidyn7<+cdvJ!@cSxNb=9|{AxEcTcX{WRX`Eg!n?0V z!iPgNFY&G^@l5GylVztxuqj4)JxgN6NF`A^gy?3(^XA#s7KUa3!M}6^Ln@8C#mxq0 zF#e+`F@Wz!0jP~(P>3G}wXxwqeG*~M(Qk3(yf1DiH*^J$lksPy7owCz&D6VF-3ci< zStx-*kfv3}Nr=AFOT|w8lXUB1l|fS1Wjwy${qpeF5*y1lTcPM9?6GiD%p16!o#ZNr z#T3A1;It)?w;j@=BXm)MhjC{>aEmbQxwe^yyU+??%#I+;Gd-8n7wFV}WIXh>=74Ug z0mt3%1x?uI%{wH*!>u;aB&-1qz(9UaXS)??EKUAo+zQ`R_{2KYw(Xgj$M);I3I?rqDI!DYA=k;Y2xVm^ypNN46%l3w>2cHu5AMog@+wu+kZr`_2@W#7R{QOkx_Q&yc5 zqc|WoXb2l1@=MGgSQ1hZ zYc&CLZy1(Gz&pebICS$JB43Pry@gvq_ot;$lt0x3_MqlUY=8lX=*U^Aosp z873pKnY8GA%v;RUq!?%b&dbIyk!Y?MuzE4%-enmnb||_o zYbU4{b1Kg>&;l7k3YlnzCaSZGPVbn}9SyTKiRBnR>yCKQ{7X>dtsbbd3u-R=!vJw{ zX~x0!ZR5bX!369+Sy+{ZFa$)4-NTlFdwxgs)%B&{v+hCBQ{TZplSP>!EkvxZ=nElhzE- zSZ%?^Af_ggPnufPrA6I8H`cZm`>QpOSxWh00t^Cz*BKybj0{0kNTZo_gKqX&h+uh+ zN77mtV(qrp3HBPhft5-#*4#^ak4X>viemcR+%=Zs$M^>^8$nO%pD-+JjuUBx^LQ4`mTRLdYVhD zwHNv#pHXS;lS=1XJn?d6O5r61)|s@`N-h}B_b(5qJqM=z(Ji~(<2$*F1>Za73KRim zT-<{7#&=d)^D+WZ(juF+J~e9sKpLzAbuzD}FHqDkQhCS{cj;6oyx@P4MLB7KKF^{z zSiC6wK!<;i66s?nee4GA?^p%Mal?%7xu&VqMcu>H@a_ zD?rr0U*fDPAaeyM(rrD}5hia}>x^OMtA_q3in!fZ;P}D&O9z~&j0*);f{$aHz^3Fu zwh=Gs1CfVz-TXv-HSwwv=5KzGZEno?CTgJ^t3n})g9r|;lRPHK=nBRz4t+h77; z>e?SW`Ay@NiG(yA>K8i=iYXw&10F*)81p`qc^?W@oIZzTbNE}t4LidMPQ&XPxV|1nHyiZFZV31mALnh?tqRYe(w{#C*gv&#CCmz9sGMUT}IKC{FCBgywfa)_YwfMciP)Ywjv3Fn~F?s}jN_Od9`VanoiM1kg;&R`+gvxI#~Q6`HM zl)DI)mWMI!Y=Af8&cZu@Y~MQTJ~i0MAe@`ErMDOp)7YU-7G%PGKjoioVHu}TxQL!| zl~W)QH_!@`ktZN1ESnEukB9Z89hu=Rqz)c+5`EOJ1q2h!6A1WePysx7PHsszVs)1}|<_P5E#P?|cbH=#zfDdcPQD)rCPVj&+@HEgC3!6uIMi;tLh-%o=H-v8JJbqnBi zuf$vcXT`7W96!!40|x-b3w&zdTUl!q`CO8FF?dIdu_y`U)=x zZM9^u8Z~urgI<^|H~FofD!hBn9XQ0;x{yQHcM@Uap6n?&WJG3e$SUkTf_U{jo(A-R zo&A++FY{2Ub9^g8c87Tlx#OQaIIX38Bh5m7((;G2D&g*!NUgi_ttWsExxgEkx>~BE zd}jCwkFsw5^@zkiCyB ze{XVxBY{pGP2z!S&hryFCvs)!j0;{%++q+f9bVfwQAF# ziQld%@A^(JpE~~BZs>1k(BFE~4FVPJuazq<>FuWF^_ysU%YIp+^gr1hJ2D#dQ-5=? z-}-)uuaj099tDD@Ut)7}Wheq2)KQq`eT;!PX}v>(lY**Lg#0WbV>MsjLRmzfp*{D& z0Vk;|H5zMw1%?~$3uK)FV-qTjD|0Gqv}M(OpY_yz4Hk@ic85-Yzf&zO8*!i2dHls? z8HZ&Qcv!q!xnMt8>x!-|4A|=%`-q|U+m6dS6CeJu4YqcQtlK4(LptgmjAdZvxmxz7 z*_PlYA1=pBZ24uKPvu-T&6hNKbx&CXf?0*$d`7M=+KtTK)yyEA60|hB9?}Y+HIhhm zJMk3La}APX`g-*%9i4e}5wTtKLRKZ3#ROBo)OICn74r#Vv=GK>G)#_laCtF*aJW5& zlA51O9QSYJ%nV^O`(#h60u=kZx`i)!^Q({>_8TY8^wzvP$2iSTVjX=%iU*K$Q8P157Wnrai+F81O=B6eP zZcgaCSK^X6TO}nkzth>>q95;Ar*E+txR&DM zEW(#G)V?QHDmKILiklz}S`yNskbEfiYc5ftVWXkw%5q>my9e{7VOr7uOr{HTJ4nq| z%h4L|GJPumB(t6c$PTN!(`X0Yq0x-=H>SU)OZSLVpmb$vFbZYjrrrTDKsIY>6>5<% zkQM)DUP5RbH3+iDgm;Z}opeGm=xl!`v{D2U%grjXJK>5j4hS_$yw)>L@MmXPLA}pj z-xx>!b^3B!6>S!&M*wppVC{&CCE_fTqP|6$-FjXJ+!V!`Cv%HWb+WT6q*U?^k9c;wUJAW!UCV!Jb+acJLs!=$QAzl8QIhJ&-p$J>$)|9M@jj{$lyVo5zYCy$z5 zEP}}nrf%;rJTMuMBKyavK$ho+{+K)-mX@$FaFr2FLxm4Zb2E)e&u5n( zoK)zDjr(N!BarFJa}&h-;a#hfp)EPND==k zwkTA(Y!WAZ-N{k>JIVnE_xjNu2e`gNb(BWn$ib3(EvfnJ{Aczpt!$@U0qDijYIpWE zJ3Bi&k7qK_U zqSp~#;Vk3EzDclnx!vGRX~36-NntH^ykIS9)?U9!=?I4t$D0ug>m+l2HVJk+&`E~K z+XP;9=GE>0uzN{}uH(j+LBU&p<3ak=Z}Jjj?q!E9|D~SW5eZximK< zb}>0tjIDHN;kVOdS2!r5)y@w%ZVCbAbO!3Dxj>DakgvT2=xpDWjoc?#H&O!-m3*z1 z&&XwuSjks*vLhAy6Gf3Q4#_as;7*NP`g}EkTsuk8Ce=dH|95T4_%zW<$w_0>F%7re zi1ofD*jJl5{fW7C95*gFu$v4U&VdolauYS)m~Db?)asWwGE$U`WoGsC%$kbC+9qp- z)*MN)mM=g&NUmkY0Xh=Gd{q#msgo078rI5T(hcL8fqsEmbJa=83VK~_gJf~*laSJ* z9}1X54c0AUvD^@sqVu(E$VA2I_WNtOS*h185;`M=k$z|r73Lg0s>cwZZ@VdquS7jj z3~g%Qw2wx^lYMGej-nF98~nr7slRcxePl+WHaAD|S%hSs%0}Ww{syyH@#i;YXY>T0 zNxB8{NUVXe;Y)sh03;p`%+ipmMT0myPt-9L=AG6SjPYiSKwi;xIGTHeud<^eq^j_9a^Bbw&l^9*K zk00XV*%WVmX)ze0w)hCKdxf16nd?L_{v!AGxps|?T%V4nQXMPFZ^d~yujTbrT`s#)C2^UinE61Et%InjXr+mPL(!W*ZmxjhT#qn;1g zqdG7SPILn?_skFmi=w%qMHg-;@4{YHb5lgK5iK+slb!Z?quatZuh15Cy+$;E9HIto zPzSDH@pmp;z#6!Rehg=cTM}n@RX9mn5p$zV33dxW}J3_T~~FPC+#m+8aEJ)ltxFtr$YijDx$hs2* zjM(*n*nk8Fw>USECIA{)TW6*#LL+kT)Zmg@CfFT|51wo`fm~+6&mym5)YxkLgDJY6}totu)};C9OliIVeTK@4S~(${xSMsg8&Tb zZ4eIx=Lly|im=Frw@udv!CyS(ZRNc~%0rBC9L32(E-yeLg$b+DDWt^P{3~;){EVV4 zGJ`Zx@Utq#t9qgMsLrUURP}3Ip14j*DqsFt$?(}2;5VX{Z)GJtQ)6>69;U>ao>e?- z&`PNsG~T^)7IGV0_WG}iqshLms#q4FZUcAe0g-jh)=PZlgX&@Dc6B|8o^mhK=nHmr zrN@0bGwR*uP9b!m5WYN(bG}m$M1_(RZ&RXtL`8$dZ>DGpskdyA;`8oxa=P8>fLmZU z^b6Y1^CWLYhK(<19bRNPg8cUD?3VR!STahK^4atPO`(g%p*cuEAaNlp7xXdVzrfNR za}kH{l34vVCJ=({#?4Nl>e!fz5|zM;M|Dt=1a?+?K3BQ5TCXk(ViCUjF!YJ1<0qt1 z43Ah8r>Z_P2`yaN&*Wha_NAO4cS;PwVv>WJC_J81eD)hLPb_MyUqa@2j*tDZsEw^Ljz@WhPTLM@X!@tQ=nzcBs4nwaEOG+W$+$a~KEdtZfm`m40J! z;8g*c1jIvH)xiTt^QU+L880GRQ_X_+#CBe1Dv_%#l5YvO=>UN41yk3CSmoJh9M;|( z9~|U#T50L_(^dA0{*)QPVvT0Uexj{RJ=O|Z8=dPT8lsi#H(oIC0j+;WxwxUIt@2{i zo?L!ScVDWuN2hzN*pO2_YNOLYyoj|j3GtE8nP!r7mGdYGTs)&Me$TikXsO>lza>sb z*ID?3s0d_xBEoqmaj5t*!y+sFIal{P11XdmK+JcwgeQ2FT6?Ku$-c37;)QUb z>obk5+d8DcSUKe+U=2|?*^=?++`-ns%Dc$b#9jibi}d!5VOm%sKatOz5it*p|FffNTeggHO_z#abK zhiD?1w~njznr-q?B1olKO87Fb%Q*;u^Va;m%3L2(wujcrAaf?&kwIdzYv&F0E{ewG zB(7;aA7pw6K$Y=U97GO6Bq=iUxcS^~KA#tLy<9z)uCm%#3`qoqu$;vBtJ)9JgXigz z1izIxP(Yuaky_JgLb32jDR`M0RtYo0dNn?)13C8^tm{B~UK~(2nE6pcRo=g? zVYre36^?VO$`3ml_Aoecjx>$y{>B2j*#nU8PRMoYWJFn6j>mC9E`EMjFRMvBG~+;J z%Nl+Nlm`k7dzc0670W8F@au-fRc%k9iY@&cs{In)b?EIHjd7MGULEa@!qHIfIGUF1 z(H1ikeQMn520W2U`yGvBsdA%*qG1Rd&Dea>9w2SZ8!9EFhxe|5WS8F^`hKEhU61zJ z?l#3Vkj!VsQ6JUeRUCwt2ANxbfe!uHo8S=o%9P5LPOF$sp2%)K-lv;sxSNDnR(47_ zw)ym;UW?E7{kY!b~E9B!uVyP%Aq z`~FIT@~iV`LOIhu(+3V5!I2Mo#eSIYxaHlzxRP8HUel~+@!gxlhB=pSfDzq3p9rn- zM~FIhhES)|02<}e+m4zbkJ)z(+Q&aicab<5@eNq}0Kma@2?0?EZXl1~2Ws42ph-P5 z4A{>h=w}DeYB{Ls+u%POiIJ|1YEa0$DqcbSzYUpJ$YxEx)jNkVP;Yuqk#_Oe11Zr) zH1U%+?F0>ECVvqCvX$X}yTn+PNZTKNM!YqCY4=i(OrUKxm4>ZDeOJ`EmBlz2hhPR9hhCDf3M>T$mbV@GY~2I$EAK+;5wozh-r?WmPd6eW&QQDT zkhC`Z%zCIkkNyH-OrST~xbWe~c1P}_{OJ1o6rbUp_HN0bM{sZ@(++GRWV1H?(53^^ zZTd$x{TkC`KOEZ+7v*bCXP?Mz!gNCFGhE{54ydK7`VG>dm?IzF>4)$2!`YdBIzP8h z{CI^&VW-6n<=aSoq6}t_Zq#xP1)zocPqYa#UVMx3zBo;xvVcS7a5$I@%#j?1x*Gwf|Ml`Czgk^%U^NFGjq+hh+% zW57of?pVQZ8-_$bC=afYrmez+Jwg@F2qJL@B`ahAJn zbQa0q^GLmCI)NUZF~!9|ar8B!3z5KuCO$CP)gOpX_+R`_>xxKxaY0!WjVoo`XPe^s zUKj3*&2bPW?rK~*bgR+^*1#>GO2@husa^9^HAV-Sami+J2x;coQP8jFtCCc?fyepL z-}2YFO!)Q>U%>9BZZt@}S3lyt8viJAJhyMnedAMAq}~n=LfoGTCn)v^3t^`DsspeH zLkxT5q$Y9-w^o8XL~DsDFzx4*s(2Ntx5LB!_CLOB`#S)OFvR`a{}Ea%nU|A?D(M(W zU|Vboj^`YjR;4`WQ8e?zR~1EB%_H|%fb^Mhp75O8ZAL_vxG205NVg?8qx62^jb1>s zjH~vo-a#Los3B3>1%+ri)%6)x00V#X3NBQ>)eefBU>lpnYvI3~#_jF-6{YSr>!^uz z^g?w7jc~Z!RtKBIeN_n9VVh4WhCTYaG4tSeafI3J(1zIp+`Jpy&A3;+Ls}QLU#n!rzjqeLh--@zAylqO4G(sKq!B7LE5Y zj3vH85J5cBW$iVNwYyVS#T*cA=pDV}Sz&7I_h$MmkomSjn?lw8;PJNFlZ|vzY~1E^ zOB$sCEq$RXUwghkK&1PgTv0vXa=2m51bgABw9opKUbLfme$ig|)!UbObEO`C_w4Jh zqEu3r2d!=dm{Ne1LcG+uPTIe;_0gYN{_b_TkON7V{9bO34Z!Wx{`C1pp3+la;@cTN z@+4sVRIo&66^{f=7+Y@KDBoH1DS6GK(>R^(1CqM3{$^FEBX``i_Wh2>7UeZ>;6+U` zl-xeYhN^d?bus|UimXBM&|p1M+DCL)Hff;`I}mh@AMc~rD8iJW5gpkpAh-6r*UJ*p z36pe1WIudrc&aQU6W`MbzGO-cjh_69qic0}K|y-80iPeeO0k*e4rExE_#H#fCqD3j z66O$16$OgeH)wDSJ@mykjep%BAdG_?DFo!c07Uz;sEqr<$HX>zemK#HiJYWQq`6k= zZ|eV0g04jP?NHUR*h|+&A=;lY+e#I3Y?Vt>GYtUos*kORB98ieu$R}+x!|r23-i+U zlB^-0DvDcWkQS0MFN*bqV=+Sqdp4qJ$KOvsJ^aforoW@ZPky*J`)HaU{&Pm}_*F^C zp z!LS%*Q!FL7sXn$%VufRTC|XTNkc8q-_pJ79T<~XY?~@Mc?cF<0Yh90fYqc&K3K_Fp zQ{Vh_^tV`1nwNv(Tdv> zJ`dRE?A&>Y?K7V23tH>EOc-Gt)tF&n#nXm7&?b|(GUxFD|IM=OA z+~qZfU}SV4)hhK+Xl&wFSwF)e1$Lj`DE)3rBB>)!n-=nfX>PC+w9WI*M3QRl$6-3# zgT!1(Ni|cK-M9Sx0(0fshscc%M$z5}u7I-gZ+9fZ+(?1bQfy5P5@0+-+spAfSfPacw6Ehd>2I4E-&Fc^b{y=lgWQ1Cfc8I!@b zkH3F$ad7Wgilm#DmrIU4MKZ76b-xlRmtzm!iIQam#JHO zzWA657-KW`^B-_++jUEg;eK`CXA752dbQ8(4szS? zE?#h`4;RH3C5@m=bpnCk%GCz$pSD6}Ww{luwQ`U;fg`EeCGgX)b;dh{GiZ0(Sm>tJ z#>6%oS#NE?FTaD_%CNqhW`$`Mx(eLoRd&G91#37S6pG&od2gb#d(gD}jN;TV*)yht&$2z8BvzCr7e5DjUTj_1w zsWKQxu<^$lDA_fRG9liLXhbO-Y&8MiZS4mgJqY)ezQ69a;ZEz0RR&q^X{xC8a*Bkexg_-aeYPIBUVtjww2h=SU2koWUFbTPYoA zFeW9Rut<`^S!$hyw{3kY2d`qy@#r%;iYaVGR;xAtPSwlPl`916vHxSt#9iJj{DzHYkb^+ zzlm238vrPefOjS`#aPVcnyxOxNZ@FQk`1u`;;!9~1zm!Jt==Ofw``hbpxJ=i?oDe^-(du&ObN1Q$2k&b1FdZ)p`$Se(Yv8su=C| zB>cm!h?S%KP^43ie!=;1%+%KHAGbh>ZJNVeTIUB%-fHZBWsUtAe-$FA(i?UqQSCJF z_iGe$$r@hmVdx*+`z)2$egGQAy1cW8P958?Ov?6FBBdv&hiBbzL3N?S~A;PjQYC&aX3u zXrWL2IF|bsE-qF~mR@|f9Iiz&s4^UTpZ%V$`6IdC!u~*`!D-N0(JK4ObCK4+U{-py z*lvbhO_B3Ke%UK5^6Q5EBrR!0`bl z7$Q=$WuLg}19q~z;)Gpu>vK@MXVLQ906kLMzc+1Wm>M}QMSw-+wkt#}FL#Nl$M=}? zrrqnJq->~J`NJ`H_Gk(`A2#}Oi>k3=R8aYn$tORQmu&k{6}UI1jUbeaVZ*xcztq## zyCa(HIo)`+;KOKAaW-VCV35OcmZH?8-7M=;rYWarqG#GEV2!H?lwdCYC7v-O|yFI zp^axU_(x^lu-k2t%BX!K@AMO>qPa49Hw$9<&Nr191WHM^tr$YC9r&@?)x4J}lK-O2&;j?i8_;4)6=7HOKEZYC5( zzf{zgliG+S+^7y@Q>A|f%$&Vfw7i+ zG&ttX8w9tnn$62^ zq3U=zvJfSvMk%jV_{9j?qo1~kg)Xi`>~?Bo8+7ad{lvX4g0$U0RtPBpbj7~-#?9Sy zr$+BB0TNrXHv7xzpB={&PFVu{N4?o4<1M>F z4@G_NEoxkNBWMCKZen$eUaqY-9zH@TX*!4LIEp)aKN1)OGvbkXi=Ur1WGnNa+J+oDYM#j zvBq@R)v{NBI_7KYzSWg%SzPJ{5vBVU7E1H)ofnLSu5XF3SIH>5yCuO3Z2Er*2;kAv zUc?IkWIAeg$v%LAu5-aYz6MJb-*@U%-@V704D>I$_dkqotdMMLyrCY3iYw{z06|@g zHlLN(P&WLF^kv&SOGEzyyWl`mJF?%btI-m?y5a=7!1^V%{0r(1`?-ff_Vrb1#>8_*u{_P2`A&kxLg8!{a1!4X0v$}m=c_iE;BIr4ZruWACoUj%6l>BOKFi5}RnQ zn7EE_95C;}(Az$cMDN-i(S&Mgl6G}=!dcaAQ@F7<{GPl4+I7vZTh!DF<`ijSE~ zgHW*-wOy*vhv|MI)EtvP$9|8!9PUa`D%k%=%VF$@*26pihMRHp`~jW#bVMhuLa!{- z)EsMkc{GyMtDBG@tsQ%UkAx`|3)Dh{N|o`4@^rMF?v>Yc_v?Y%eLt#80bK*kPFG*v zhIY1TvNfH;zLoL&JNlQW!SEINR^Lf(V@Vo~h6b9wU1u3fju##m&1?K_QRnzjom4uW zQq1lt)P{-1Mqcl1w768=Lj|YSh*>9bVPAwRe@#-|p>TCMhbYkFBlB+W{eM2Scj~^D zQ|`WY)Fl*BY_=j$a1~0ml#nXJh}6N|_&agWnp7}!lnl}b+a2A70ZMB0paoFE=o?Rk z<)){M?AtorOC>DE>{3Uz*k!^CwwDzP&0GU8NC4zHT#n_ z;{RdMDqINHBhh*ihY?%`zbk_wzIGr&q5VH4T0!VNMLV}zwTl_f6%uMt?L+DG3QdX?p*9zR<0SnyP&AT%GQpt zAlIbiL?oYM%;{BoP1bL3n?gMj7fX*;o$|J*A8Aj+b+wV-E|%+;3tgswJ*Ua1GRTqj zQ%!gwKUt}WMCy65%ylbY!B4w-BzZZj6FM!DN|s+&3$`B6`9k%URTG(~Vs)9%i|t?# z3jLKTQL!{vz1-w;NKRJhE!P_Te7Rb3Wl>|QSyd1J31^Qy-djqK&i40V%3@2kq+EF4`iy7q(IGNCKC zDqFE?aVu&qNS*%RA$2*m=KHqw%M z%$JG;mcw+nA?lmPlCD4s&%o0Vj~Y?Et1P59SX%XHwyG#|(17|#YOvXDtZDVMNQ^T? zzILLE;9`@g+Y>{x$gzPF^6fqA!i1@6Osy)azj87bn|E-lp?1*Z$+L_d1V#C;DJDpS z!tx|;+XY^0BiJ~%QgCirWS%+@Dt3C0C89m@Zp6Ck`CPIsgjp zILHhS6A?@~zT{m!5o9sx)~0&{`y>`D{{$7Dmq9R@E;l~tL#WVp&xjI3eFX9w7Q2yJvNAmFh4@r_Exx3XJ>Sp{Rc63j zZ1^CHV9wAJ;5MCfh)3tancT?VOueV^%@I4Tr*$uG4k>hH2CsBX98MCqj}#BA5z<%a;2GYMG&W6wX{%#AhfR;& zTP#x6uwXaazaiE2NqcXI5bj=!|ez&E?*B*|PQp`0+D9QQR z*LokA9~{ty`SJIM-@UlFeXzNA{7Smf_24_%%JoyL&->c^zNPd^hhO2ZGq1z^h+WL41JdFx@<8v2>cSO7F|LM%H}K1 zfaS}(`$kKJvoFP^vdX;3z7Z|`xXgdYhVjs5xz67JxikMAhxA7y@hX$%72jnzwTfrr zZ)9cs-4W&?`Y~UTnZ9pI_3NYj=4SDhu}w@1><$-ZlbLBt%i`!FZ}Nm@T7u%G36~lf0Di?OL#2Rf;i}!qWQEXOsME}HdS@a#B*Bm zZ!)gsM_TWn$>(cgc-|@}NW(8;y1r}?wZ{1L{{x-&=)Q+yJfDmaSPTmX%2nj-(u(eF zh_a2Kg~c=FZ^iyKJJyI?I-LJ0Xkro0KBrH}jUB#|k7={bk~JGa)85MPxj$Dz-<0qL ziJ7cMPnKA=0Tj%7VCDu0fO6(D5g3p1KMC7eLFVasLVgrTmLyGw#kgQ3bopPMedf$1{GtW`jgzv0u~~WnoYZD zp#9y%;NbAyNoqH%hOd^0x!1bG*{dp6-;#r9`r<|X;>EMsN0aCPA7obXDYL24XK8#P zqVg5%MmJ`M|5R*e0FG$0AF#;|_TZNcZXGvx>?ahThu1d{$Mba_TIw(RXvQD@Q<#@{ zUHCAy2Vo0`9SnDTcUDq_Fc?8;YeI6Hr{(0Q(7Ys>y8Y0JK1 z89^Bqym^L4mVddXG+Ug76fNjIJ0q(0RNe zq-PDelR$IvQTeX^okT)|%J^WO@s)9N!@C~eJZkncGYlxYl$F#t#t#aqou4@@tmcSv z64ER(=gTw)(No|SM+GEvVC&|*Oh;hieJl4C?i zLN^a8Sb^l$bjOYlyk0vZsLY%u>J*_u?E(z_NnoqQDFYtX$R(%WD>8Zs~O0eIN9SJsu)mH|h=Hl;{&oDV2=ffMP0lPp?ux_MLi^Sa@5day};8BX!bDb6mt zC9ZE#yeZ*@hO(-38tkX$%hTn$Y6Lg4puM-9lfB|wqxa5t^MwJC9~pzDgzWZ++BfGc zB_KS?y=m6MtX$4=P4xZ8#5!C0aa!ZtpkpI~xk9(;G5c}s1$!!JsR6UEu*QM9xa>Unm9C3=gH2*-=%MP9>@Ejq5SOn$iL1zR6Wfa)v2M>OU_6{=lrFXrdf02n296y!X% zz}v;n0?1uE)D6F}i2DGXSV-IA{`zMoy~dTD&DV;!?yki|QfjeQV2H;! z&g*$u9@=Z7LrRt9^K5;@pDk<89eYkvVR700`i=Rx$Zl?Eaags{X{%hQ}A0vrGZZ# z^ZuobTzYb1Ql3*B&=WLAh6Yv1$npToF1zJRrqpInPr>KP_}Z+lbNd5f5Hn&x42cLK zxr2)+&i3XePXl=lPmI3~>|aC=LUp(WT|*|^{h-kDrc)-|EaZ$)psYVgKV%o^NPJ}QxH@m?Y&mv)AwO9JbUjD{^_zZCx}k%OBqSomYtglwktN2Mcn zxbQ!vi+Ed!x>5(LE>YK=yEsuZuZo6RUC;B%5|*A&(KJhOB5TqodmWhPC`wrxK1J|~ znRd@@OPwS}bjhZ@$m@R8@d<3&sY+9&ukO4JkUNesB4VuY|Nrw=^eNry*sOwLU{grf(X_^F}1_ zu#gY(q+6ROJSd@vdBTIf93(kDF|F$i{RLkafukv_$Y>p86-mkj_|p1I@{1&W&Bf~j zXf_|WWaP*4I50r692>H*0o&|2C{cuzHIl$@Q-%C_(8%v7y6SFK(k8mp5`8>N_{S>B zlO6?~!ECRUKIKsM0pXlId$`{!-5!cIiazOV7C<6~C5mgnBLlHh*TG4*wv(RPFzCp5 z5Udh#WB?7_Z@ouVa*xu}o93CGbJtyso@#tH^WTz4OB|9qFDhXCb$%0Xzv%e>MSXBA zBKO3HlzT|hf%8^YB6g}hvydY>)ogi)iBj|BM1NtieUvWwoI`xSf6^H-rn+5(kh?$o z31{DI@~qly>`tSWmzc}n=aibOmADo!mlto-M!><;O))QVekg^5_^G!HaM5%^U-JbJ z77$nAnky1%g{u3R8=EAu8bEY;6toW0tsGO_{vum%;m?)o`V2BGGW28HtcrnITGS36}} zZ=B(2b3Ua(Zwx`TwzgL8H3rHiZmJ35tDTM+6Ci7!XHBz=+dg5HwjCd;j$OKOr{qV- zo{g=C^~Q1>pne{^qUJ%79s2BY0FHd5S0PnbbAI~hv7%cPFi$bu$65)sBJI#5{>o>%$TJ*0}c+tp4Vs0TPMtD$3t!?I*q z_Q~mF9RuhY!pcnYX*J`jprR$_{kd26|QJ~S)j`~5IC8~kskW&5r4HyapN9CE46ZI zp$HaQ6;kc>3*O{XEnQb+*B5IB7xiU(c?K8eyp`)oFxQoz>md76}LUxun>GI47tGE-M{? zZir`J24la1bohV@AY%)-;W*D*l(DVOV3|FVx2MzS>p3)X2E^L}++ZP*h%H!Wntq^@!z~qqkXb$dZ{ZWmfY+TW}O-IQ(=cGM6Qi5+IF5 z+ptEGA{hjOtJ&Z~ODqYf5DhN_qhTQx8fQK;Aj4~hGacyMhf#veowYXZmg}z9 z|E%F3X4L(mF6&>H74pT6=AS>qpPS-Y@sD)@elP8)jI-lk^vGr1>4Vcst3|d_d)NI) zE-F_P9$c0W@31UEkndyti6Y{F#3GYAaAZFb z#6j9F)WjN&%lfPQt9T7kwu9ut!_-~o7VKp`;}{kpK6_0J+#|Q)uRjomz1|1I1kLiB zk&jewQT%OveFJurBZ$H3;S27eqDK1uS@V?v3l@MRwLeFiR6Ek7br#S~ zQ2Qa%UduN4w7V-=`73q;@XPKUyXXSfYM`x&QoXf{G}+oTD;XgI(Y>-Vtx(Qgs3!`& z0(rm>`O>6~f4-z{`Kkh&pb+Y>CR%9hk$Ww8s`>>_a=P+Bm$f6$eI!$sh~#bj&v{sl z6tq#>UL{!M%1BkpXF~C`#y=5 z<2G_-dhge$lW?PaRRT23@GMw@a+ojWFn70e;vdkyOCBqyg_lRP2$hU(C8rw9DYC9S zOiY|h$1H0thRNcntxbXqj=qVH)P0!nlMa?YgG^E+vFjx$E?zScz-WNPDY@`{Z{h4m zwnrbo|E|4s6qHpHFy?J<@m0-+LGwSS2fGm6Rl;#(JC9~^oYwnOueBy#c_xXLsPW+P4jWLd zwL@xhL$qw#PcfD!b}X5$C?z}x<%}>WAP1_v0f$E?qfhCFdjo z9y;O0Muw5t#cw~{kL)Di^H?)tf53N&3u@8z0RfKCvg~2Hp3M z;j050HT+=|!e@OCC$>AFBmW8eKuGY+X(n321@QFyD_h?LL9BZBioW z>dS*=%yR-2G>ME-A+ei zyn0#ROx)vTk+0CbbUpkqcYQCGpy6neNSMX^5YbXdK(u%GO~(tNZRK$9ws z6=X}-4P0OE(k9!hXOre%bb86Yh%N^4nZ&kt)sb`40s<+`?~HmurEc6dLbDc~UB~nD zdoDYp)r8|jLy|oPk+sv_&N?+vX2LvTF8WLdc zbqyI@<1s!%O1GQoI^9Nvivx5bs7dXru{F5XX4?zXB%e6!-`<+#r=USjO>m9(%R!$*!+#QuRG+UKC-e^A-K18KtG>X73ST6F|J zB?b_eJ+hwVfa*)%WE&~2@YpNam^a&N$pT-o4tnXk2dc$d35CXuw&#|Hp_m5Oz&m!h zMeT{U>9_$;Zq=PbY4zLrH)-jN|E#4`esG{34iBT$ugbqI_dcR;dCT?AQag|+p)6ru z(2dnf`iEzSZ=DddQt^|L<*0#C{P}17VpRSr}OtsK}*dkNm-wD01cGtrSwI=g2g2$3WOJTDfI6_(|lR zr@u9gg7KLKLoMk#ZEd2KBg>IF;dw8^%vMfN?3c{u(jb(eiSp^^%%rM3ER^CL{FJE_ z_0=9HIg5SG+;0iZj^9PjtX(c;H4Qr3N@j)p6}fZd@_c>|yVO+8Y>OOC%GgW@#aR_5_7jPjRt06D1j1zlS@ZB9Wu0cAQ#-^Wce(v=cu2ZM@;707W>O?W z`kny`+MNuScLoF=lS3DVsK3j*xebHlZU(F=J+3W zq(Sw4-RN8ZgnQy=`X9_nwH&Z?WUw2_97WXt1+ZW5)(IT;1-xb0g-yGaOyJ#0Sn8fG zTk%(=R!raGHx1W%(ERG@0P3Wc8L`$Ah`s&V4otWmcBp){6N|*I#lTJm8zJxRK;>1_ zh{At>3-nR%{W&^C$~5F=_%T>&_cHy1>v6d3H-=L;Vd54Sl7b;xiOmHW5AIyW6_#zB|>k;DpwNu zJy5nUNAx3T%g3{0B;(k`IDq$vIA2s!TJ?EoA(6^FU{E4Vt6`JSZrzbxyTs&P9% zFg}fr?o+mp(@0XB!RwMe#V;#a{*yHNTK4rmx>H`z3b;Rj9O-^Dcv%eAHEJ&_^hH|d z4cJ=_7d;uJ(S5RuxzC+mHUqxGllf~|875F=#)$JM4{+Q?#uXUSx2T|i+I9i+7`Q@} z`A$_xAf6M3Yyueraw^?`?EZ8 zz$ii{KYUCdUZPaxr+-4}*L3%R5*Bk$M;bwOGK~f2!|O}D5?vb*{TtlQH$X_5C>;2J z?REYm@?2<0Cv8Z9%rA9jOxPC$lSw4a03Z6?hGBvfin^%}T?BVOJaV$9_XkTtKHg7& zCYT4A>9Lc^@2T5Q0F~LFIN4|aX6{ORqo;xJUkOEGw;Vn8-iitkmq1+N6yil{y6b&6 zkWEUQw7eYuooD9pmF>0#z5od7#51-tx5r*P1^?k7_yTMzOZeeZNuTrWGT{_eSl^FR z!b4=Dao#6e@|9y}fq1!GVD5O-voaP=Iqs7 z3O6Q0ZZX@KToR9#00~QOTuhrusLR@!?~w{>jmh$8fA%{@ogQXR+_^4;NNEvDpz{Z` z>)tr1y|Owu*cr5TTd!pI!AbUAliy^pw$O4!!kPC64#X8Ry*ZHIG7)a&t1XRpX18@$ zu3?mJO;)rvtM4ibo8AXSjC0|8V^(5Uq}Pn8G736DMq*y;n;S0^6L8_{TBNLcK{(g@ z#DC>v8cl=0EtyWiGR0*?s;)8 zj136Lz;EldJ;|aC91gPUu6;m#rc>~G>%9#FhlE0^RT~U9Q(3^TRJ&HCNM;gj0L*r- zD!1x!fd`ooiIi8tL%tq;S>enRz?^jtw;iy}c@!^MQV4p>VCN(Ol3(m0eR^igHcy^|-&XwRnsp&zt%mVyu==WI{}3Ebzq zMM}qg6h=GNs0q>EDbUb41HvQW4atZ~LD4|yOC#N2`HOGPz(Vh*lVj} zX_XrAlwg4t>#j{u*wUQ-77kGal|!TnrKuwnY}q$pfohwqh{(dWr_Jd zd8@=*v9M}*;=b3dxWiJmmpz+(s`ECA{-T;$*^W`UeeJ-Az0Y=bk z7vS*diZ$Uz_h)si7^k|UL1Z3gb%#YLs>=36HdHci^ z33{nU($Y{%SVej3DilCVb$+O$B~Rn|!a5Y&m1;Sne|lYwYgH2`4xqKB+;FI35_9l~ zrX|5;^(2s%q}M>E_!aKkRFBblmbkDcUjw7>e`jF5I}DyQ%@B)-Id1?+v^bRD9_mfV z?XeZcHT!OOwjll0RLQRSk3Ra~eYTdQnQTJ+!lu@VjX+XCP!(fOrdJHF0 zx`!hsT>O@s%^SGOmHW+XlC(X_^e>B+v52)#h=3Dbl@#m zLW>if%)IX~In(I@+iZsrtk0 z%I!X);Za&-7*7X$i?MgFyZq;9A8bf-XkLV%lCzCLT%rD9t)$A!WH<^tO}#cV)of(e zn4~zE>J%=76K}Q4G$=%1S7=^CJ$@hmm4@U}p z5bL)lN-t+}iwIRj5;R4|S4`bd^(5Sfcae#?JeF}WqbI9gnI1T%-h=SF`nO}YKJ9T6 z{h(!lF(_Y&5miypTpiV#cU|jVDgrGJ0MSlIpmRx5 z7QdRcLs!uvP^M6pV555pf4(0>%?}0Tgt?G!C*Z_IdGQU1#Dj8z_lFyNWbuqxv%j|> zL*RK|nZ3NSG7)6WkM!gq@Hx%^4)NPfwT{{1@^Fh!OBV4ZTl2k`5jbykI;G1q<-usu zr87A!C|sXv4P((@%0zQ{A2^d>eojT4QOt*OCoUHN2%-?2_#yAM6l zWg=ugu2>hyp)}|ru%1&nnUts+K}Z;>pn2OlH65Qt)^dbC;SPh}`d0)!kDxJXi@@tYRa#<5?)l3$6XywVxSmDf!+Gwv<*yaD=XL<3RZv~O&o%5TV& zL$!hkllv6n!Ijl^?)s!gcQ5VK@FDPrn`BxXLrKFXl;{le=<+((X0ZU~efyb6P3At=e? zTj0GzmkDBmp>;$4>aLGd-#mnZs^K0q#3e$T9yqtG$7@4O9~0a%&EYdG4>#bBAk_W# z2Imy|`&8U{vd0hOj^YWgZw;$UV!kfF(vG{zc_?|@=*Q={b2NG9RpYIrVVq;(M>#`t zlCQ+w)QxPu)0>z2uU^x0*4x+orT51dXhJN-G4#51mp|Lf1_Jwt5C(VmHzcsa*1#Iq z_Za9#vyyo1_v@m)E36)AylIU2O-mYZBHrXfhy7JjFu%yZQli7!*0wE5g{f)=4hm++ z{4-V18Wbf?wGykS@S1YdLQ9`2W!@Rh=8*bhL5&rQN*gKCt+NCq6yi1b3{^iA_ip77 z1IUqWcdZop)v`8=Cy1YcEmRuhwh&aG9+$FCW2JCiTdSXQTa@ybQ&$pHo@I3t|0#@$ zvlMtoIOwJi-8KI}r`>4Lv4%3P9KJE^GLr|f*E)2R5n1wcHDDq$L|fT_ZFQ+cAK*Jd zX)TL5k`oANv>6wZp!nzOsYAQ?eOF`Xb!nC1b+_6|;iug0V2-qiBPtq4{I%gp8&#o= zHV{O9_12W-PufIKY(Bo|NZ=Y%0x3|4^&{<8|J2RTrg0qARBGPnXR7;UP23|%2Hl!c z3-wRhyY!|gH;5YAdZ!;*U)x$Hk{7>2P`p5MOKvEMp%-9yFeoClgTJ2?iQ!FNQsQOe zQsN!$D0xxvM`i5t=4UBW$cYnkgYE@S@nKmVxvz*RJ8ff|uj@N0MM>j@iR5_e$H1fb zS?XW1Ebrp1VoLvvN1$G&T2BRy>X*uNN-U~a&kn@Fk#-Q?&tN%h@3MNWIQEwnr!}-j zCteSa9|NN9J_Y63{U}f>_;NZ31^_oMRMF2m;^!Sf|0?hRTXpX&ysj;=h3Un`ku#ZUQ8FyPSL~X~41_6@NVxNoB*RO^-B35; za!p5&c6E6AFq_{X@TJ-XC+*o z{(#dL@Xs6a=X@jopKtVGsSo)Y|DT~=|4i`z`57wC=hqYc|MXcmIy+mvp?@~=|ItDp zM)Cj@eVE~4V>a^t%?7XJ&*sNdA(b&}9H6s5j#u71dWLh(|EuBfTHF7{p#Gxm%663q zg6OXZF^180-@%dS)dv%!CRgJFqPYrQM{yu5ZpgoTs!s0=xF;@5cTZJyPjzk6Q*~@= z{ZQy|0tr{1e{uT7c_B2|FsK>O*;O>4I4NV_!=oZYAkrkm``ys={k{Ev{N|%;`t;iV zm>|}`p9MImE8LTmkpVEYYfJydV#!9d2-^G$b|S_ftl|0Z_~-QZ7pIF8{h~j3d18pl zCEOCfSjO~EPsiu=7}w%_rC`i7&j-FL*X@pmi5IX5lkbXYZksj&Kp<;(w^|Ah_k-Y3 zL3FQhA({|B$0n2~W~C!X8e47NZx(2^( z{&i<**h*s2$O0Y_xuC;l{9DC!s_h5Lq|jzour(r$%T-hJ&MGB+P{VO5zjkZ|XipJ8 zk-&hE_sPFqYexm2s(22?>rQQ|gnlKlZFYlaUT~KUQq117yvHH&Gl>e~9(KlYUEL$^ zLH3qN|Is^p7EH)hIO2l(`RZ)IG(K@x1og{)sLQiwBdCOwuwsCkx4Sj8r4lwS=S0B$ z6c3-}w8k!Z1y_J#*hltyM|M&`Iol(G4mDi?D< zaTeZ=J_d{86-`Xxpa?5>kK-{BZYX*@uyLI1*teF#8hvogjY-qle z$AiP6d0KwOe2)5M9Bf#PpgWwnt z6xlw*h?=Y?rVUu-E5f$P#*hZV0VJt(eG~;@iPc$HIo`Z4$1I1_+a@1H+~!e~=7h4} znGGm(eKg}s7H*4z*_+hx@jS>yEAoc&i>U!EZ^os(V0wn-MQ#UoK8WCHm*`{vQ06!G zKBNm*X4fuGkv|>tA?BYlTxIvLk$2<^RVFPtw$Q=5_e}BP##vtW^>C^SIa4WH!;A|s zf_Z%7#1!r3jdW_k!{*xn|1bFDlk&-hW#WyMSkuASy94BXP*vk^B}JDwvpb2n{Td6*J6i(tad`&3 z(HlYY9`A*kQE61I_}Hw`Jz0&$2h8-Y)eX7lf?i=S zlAk37G#v%q>=T% zwbB%}-@jYyNWG&nSvM~HqKp<#Co8xlmmdu4MZVI36(tVx{X5OtOX5-~3o}U-?3rRi z10_)*Xz#BwTm9UKXGEF#s@r*LsW$qZgDw$iO8!s3ljCHp3rXjn0@ z`#sxW?PEx&3esN=#zBbE09Wa8-&Xl<06_mDa7@@nQv>Wy2Lmu8C%$_r-9VVzj5^GR zH7cpy89e^VX@dn2SLF8AB9P2@MWA63lLmy)1W6Oor@EwAXG3xdU1V)jqp#GLAvkl; zutvt^;Nyp2fS_%Je#R74HgoX?KGIvxCmx09R1GQ{;E4E z8YPHx2W#N(i3B||Qx$nu70=3Cn)X^Vc*YE*taj22M0lejQGK)IA0SlO)1oXs?;tYR}&h)8zWomgD`OWljK__&{|-a?|53m3JVVuvqu zhflNZ2%=jxnE$66*@ZXrkzpxpWNF?9E}ZA-P6Z#*hVG9wq-6oaZxzUQ8AgnE_aDV+ zLpU-G)-owqy`R85N$|y7SD59NwopmsAHEKusOoM9BIg0(m_m0F z8)tJ#%cbMHs60+h+@SbY&E~EFl*Gd2s?IY5X%11CNvZ9Y6ax)puwAyf6MpBb_wC&d z?<|9!>yv^Wz}UKMqjTb_!6-<4I(1RSL#boWP92Nm&XN%7EQm8Pxp+++O&+(ChwNO| zCf%h0fv?(N@>f~8w@Z+s;doaD4{yjCVKC+pL--GjcOm68MUd^)oN;W4fL`?2!yO

qntWI*D)^W~P0~MeeL_Gf}Sh&*}O_npz1_{-|V|AFky7`>Q3i|uw} z0T!nDHXyPi9I}fj%#X?VC9L)^f?qEt^UWW-EfJ(c?<_kP3T9^xPe)Qq{R*RnjLP<> zt0QJFy@Swz;mY;j!*KrPg$rj~B`-D?3A}5+1@Gq!^>+vKdij3$r`W^Rnm5jdyJPR_ z2>Cxfxr#~r(pL<=L=4idK!f;GVdCQaAng2_(}rOH{++hl9(K0}prhkfHkPpN*(3sd zb!^Udy0U)xMUqKCc5hFSep2E;aUv&RWyo|jZ1AtN*y!;#f`0Emz0Pp09=fF`FBI=o z1l+cOe?9wEt!|Ws>rT#sO)CfzWu@dopZy{8&_x7>?FcXLR8YQ69f#!dwR)C^mY{&C zKXA*J1xoxf7Nzv*?MYr5r%0s#&U zbQ!n9Exr)NN$~?lR|}rliQkWFXX&OyEVBR3^q#iSDcm;7HehB}cjUkHsw4k}vcpAl zk7-cA#))iHjNt7ADzGhJho!XD@9xM}*K~9P%C83Q`P?(u>JD5VS$6?Op+zaB0VlB! z(RI{58kaxT8|4ExGOaSIql$eXYs!K{#!;U5(6qyaeK8lGN4QbAI!}X%bWhg0-fW1i40U}-ueT25gxe~Ik+x5d(0aj|YjkSJu(LVxokZA~C6*r$ zKU`8k+8!jWB#506Xhnrc*r|hLl#pApK);#_N{`YRJA;=D4q#geR}yIZB+y!&BmvuJ zC@P7ZERAoe5*E(w5F2T2S&nr!*zo1l!K>4;z&pu22=cQq?s*ZjgkbWz)8!}F7FR|u z6jilo0%MBY6>*7G?oSEV(3A>I8EZ5A5@#Ni#5!hW{wkcIN8N(EVn-eDN=A`}GYK{t z-120PB-bcY502!)`sI#54+d*Y5k~Qtlk6{!%33g2gm0pgzHy#a*N4f7ONQp>i?ns* z(MKxm$Bw2o9+^#%>AP#k?UJ(BTr_Mu%Q(ZCs%zD=KB&lX+gVQ7(_78JJmSEV*l8Psgy~sg7BJ~Yg$)oM z)xZVfIkSLcSIQdYoj=SMtKPsx)4nkvJd8eJGX%x+el2gj+v{oH+;UaS_?W^K1y2tn zdEI&+ zAWDkYZn;PBGe(#|W$J8ccjX*&OqUoqW7&o)uFIC%H)X>wucg6*K3FjeCX*N~9Jz8-$tZVu zmcFH5zk#>6Xth{e-_{Ca>p`V2NGJU!bYvmpL0hpu66MPkdcb)ePEnJ-&TqPFh2dVZ z@FWP`2rddlg|F{~3nyDGbm2{S%fi}5>CsbGk4X)OTW#i>*)C+P0&~k2#sxrG;NCw& zbc=qc#c_l&9k6VyF{#8+>|b(u>nJ~a)p`|09ZC-WJwjfWvRk=6ID(?1y>tB4dHvVf zsLX#I-Z=0-#;&xtX&{LH6%--S3dA8H#20@^#VwAKl#07biB;Stc8Q%9WccsAd2cUo z6NFURGqaoZp0m3%+qYZ9hvf=cVzS$VHzwLw^rlyE& znf-*}}0KR9C!xu=RYttUJ6qC)jLxRbn%}V?Q>{a$L{%wGFY-`S&9l?pL0D zTt~KA#%(y7TW0N-vOga`eL1Gj`#E;PLA19v(7nJqn=cdbLK)|dhY|O63tiyVQ?p39 zDLDjSmx+Lk#rXL~@E)xNLMRGpSWJOOb+etk{X+6745_le3)O_;K*bI1`$x?Zv&}?X zaZ1cu*qsk0({d$5W&Mc#%{)S|Iz&l;Z-^4%W2GYE#c*y9lBuol7Z*v|6N1w^w+?}S z;PhFPGOyT$0o7{hNc@sXJtBS+2!b}s;DEKfPegb_MPDuLJdZSlfQy>8bM_l!4TK%< z#0m~4$v2PH5}}HUp4SQR)9X6W7K>;~MekrCov{MDj=3|KPt*nmgCK*0LWs>zV!f0> zip6mUkc^ZA%@ysUnsbCHU-Po)kB)5r=gmk*M>y5tnWrz`?2TVW2%}+YNltzLzZ-!XF|;iRwF^mfBjn|1Q&(g6KmIL8|B@lvGFo zB*xP|`p1@PQ4&PQLNB!|au3|VF%*UDys&>0GWy-FK_^k?UMU`zm_<4`={$9`$u19a_SDrKYQ-g67QKrE)Ky7?dl6SOZc|%L_iw z&{xw6hN4#Xq!Csnf5OX`j6iIrXs0vvo#vcx;8-aWniao&NB;>5QOd%5Z|!b4ew8I6 zQd%Kjc%0!9)+SpMnGMa;=2=GlFjn9n+z&iP^SuWN$GDMu7?^jJVn$X`Bl~d3p(`wr zVG6zaZlO^%U%%(3l}g5&AZ5~iT6QtWtpV#3blRNXTUU$uq1rqTdo??4R@=g=dJuNF z$1GAqOrPx$l&0omx?bizM{X*(eu_A7vf?3T-bF! z$8D>AyC(%|B-|HOO~MZ}Zo)-0XH_YRpB(s_Q4X63@j-g1Q*U*Y!-ZzgHYqbVwfRKl@aI${7^j5F!sZ#UD4Aqm8y@ zky5iAJl{=ofEsgWN6@1fDhEbO66(M&Fq2i#lwJh4X~+44Ge^vw2r7;j0+9jIbnWDq zFb!%odfxg|7965@E5BGnC(ARnYs6CwO{?da&nJ97<8#6%&oYzp|0Pd`LmB(P&cHE9 zpU!>`x`76f>O8h!+G=!fli>b9t)+%Q=kg0ajlJO9*@yCN=C)mZ%v&B+8-7bd+85Cn z`83s<-c3llIXPK~l1p#A?ixWSx+FQ8MTP?o>X9cbRLZpC0PGjI$GoX5ZNZfG4m!!! zQt=w(GZ-P8wO@h(@UrMXykkRtum|WPDP|XgSeQl6mzzP6&M`mtGi9odBE1CeAxT2Z z$7d9wqNB+E(KLuX(_;24(-{crVSO&aY=ur&hgegFc<#Uls|XGrwCEl2zs1;|IpyU^ z#Vt+i*8(Zup8tANC(9@nR7^g_X0M%gqytm=ju5XEu_BVEJ-`q85 z@{Jd_-}thtHBFvY0@^>i6|aK;9k0*aF+|hfyry&)0iQqjv(KOZTwB{N1kzcz@v3sf z4A)$c=3xLb`3>Zd3@^HZz?XtsT;aG!X>$K`XAm5QSe_MZ(+!RBQ`%>mz}@x-d46fk zK%{&?wEf<%e_hYYYWv&Wb@ea}1L0@>1q}#dnnKtkn2J5b5<@})gbJiIj07buJO7>U z?z|FQh8PdLw28;rKA+EL$No+nZasSRb1t{Gc}=ADdM5|60iliX?;l2tPSJ}X?kB&L zd~Yr*mD~vME70_4p8G&Em#3;P$W>BRuS!(6OUI>{QJ}K%RSQq!TX6HnMBrY_XTe$a zaLs~IJVG%h9WsJ__HfW4nsbOJd(h*_dMx6Dxj;OJ(A5!yYI~`pc}8b@*#&WmgS!$) zdv*ALdjBnE zna98W*Jw?-1;o?BDmOK7bKW zCrVJ~Re0a1>fW>s5|icQNbWa{8$zv*Bh z+-gd1JS$`s?!p8Yd-I|@-P#NMoxQ-{=+<2CoixgthvqtNLl|(`Lc3~FvW?a;r>sJ4 zi9983Kh@9NVftpj!(UUyQZMbf{UzA6Xz7;4qq_%`0zzg0Oj!Eb4%lt z@HU7^!R8#r0b_(%6Za@I512^Fe(WR*_a-iv24ofh$W5(z82d*wc2-Q*s zvKcv1uNR<^bm&k7y-r|xso<3`Q_X;1gRrN3CA_<*r)5SLU&?u@^HcPM+b;BX@PK)k z@e|ZVTAs39Bqzp_;GM;R4?f0hIzg zHkN%A#}f9flN%krpqI8FzI#h!kcw8etfJP&X~eB%;bFPz5Qzoji9{ptom=0@oho6&yFQx5NaPm(pTUl3}YRVU;3yQX04Weyxj8Uey?IcqO*u{!%JfhU6%-3U#`EXe)W;=Bk7jw6 zJb3URLG<*Xb}6VWg8*+PrAm!D*bocBV+X_2(uDS$muG5LrL`iIarQ-)i{d>kI+oQb zj8+t1X4IT=x;|Y)C4fJ((wH$qR$#tMN};mI=sZNDvkF?oYFBk)Uh^Qy5lxJAs4ms}nF?5`pJm@|!XW9iVXC47%! zB`@%-b@EVL9Lm6ZoEY`?MpPErKZyby?Hde2%q$Dc!ILznrRy6t=7hy+qr&4ck?HFa zvx2VKz5pgRzl60Ch4?sOhFAzQ+mf+M9oLYiYOUo%*LM|U?hF2R@V+lq9lTubK&G&gmYaSZV(eS^?vA@hJ!N{)| z93R9R!>x&7QwNc1sLN{QP@)Pq36I$%V20pQEcpLp(smx@g=JQRM{NmD*2JY~#9!po zpJNON5i;+1V#R7TzSxnL(N1dV{m+Vb&)Rvr7Z1LmZZ?84HfqLYoPiZP)U;yDJa1^- zBlCs&%=<;t>El8?QXmHN$r)Y!f$H@#KTUFx4{TReyie76MPmd*tca{}la^O8%~rX% zL+AdjaKvN(UkTyn{gRkq)~#j-w+TwORZtouD4oXOoy`J4na!Hh`EOM+E-cTRom?n& z0ZrT^DG9ZRF@aF8U``UAj>STtVF2p=FwYKpw-i_aq7$)4v?YB+gnmhIyu8(+_=FfR z=oML_=fyW&bCB^?uB2h_C|W&LfH<62r`+-@&)R8a23mExEh^E#6)_S^xEiRgTI;pl z;He5*b|2-|YX-{>ITi+?wAo={TQuXpXI+b@IP?6n$Z+{U0|BVvkbHVgSk zYaZfdjE}Mep|1??xC3!7jfO|v!FZfvT0qkxN}NhJ?R@a&`F*NUM&5lX!T!qyg96hS z80wEY`9Zp1TW!HUvaL(`r1(KjJ%sx6dwgpsNuh#Wa2Gc8+G93YquS)-bS+I>GUb8) zqpZrhqQwc_;ABf~PRVWTJB#>p;lM@*TrPrV-560?aVapB-txmB&4wre+r4xB&--&= ziLQ`^Upl;y)Vfu=Z071Ud~6}KkFt@EN~6=aN5%vuMDAWYK?wa4Nu!?@;~hQUCd2u8 z;7rKU|LhV8;9P$yNF<^H6qmIocycz+3Zpweu&G7>+#{FubKLN4!K~ z1bf_m!(0a~<2n%B_kbfhf=Eexb0XO4r>X4A#AP@>2ug9<*>eGv0Xn#O>z?!$Wp(M0kkxZsQ6u`W> z6Ids!j3YXUcxEE-s(SaGtB;N#(Z%tYkpi*GuVo8CEmLA&d|=Y%J_aV7Kd8c0Kw0%f zN7+$o@D@?|VFq#OE?NBhmP`e8_#j~#>L1(Tuhi!sQgcDI3yOWCoWsK>lJxzseyVqK z5d%`u#s9iP24Q(T>Ia+vs4du4(wE3lNF?LrV3_ez+k7f(WE_S3Fr%p)W-4TkgboNe zHH;TB!()PM{Bu<$kZ-M#Z_ zT88ShjOf2|sQ=3E>Axf>WQ(P1rsu2JfE^n)OZr%Xv3=E`X)~v*%~>SO$SoPSU7?@9h$cz@JK@q5@% zJ9L77Pl{{mge6XTG%zvo{ziR9?O+Q%fe|Di)fdRL@#k3)MUndwmE8_wBy=}=BTDyM z2AO4~tQp Date: Sat, 11 Jul 2020 18:54:39 -0400 Subject: [PATCH 066/551] Limit the max open files on fat variant, takes a lot of RAM otherwise (10 are default) Added missing icon --- .../ESP_AsyncFSBrowser/ESP_AsyncFSBrowser.ino | 11 ++++++++++- examples/ESP_AsyncFSBrowser/data/ace.ico.gz | Bin 0 -> 6307 bytes examples/SmartSwitch/SmartSwitch.ino | 12 ++++++++---- 3 files changed, 18 insertions(+), 5 deletions(-) create mode 100644 examples/ESP_AsyncFSBrowser/data/ace.ico.gz diff --git a/examples/ESP_AsyncFSBrowser/ESP_AsyncFSBrowser.ino b/examples/ESP_AsyncFSBrowser/ESP_AsyncFSBrowser.ino index dab2f069c..3381b9feb 100644 --- a/examples/ESP_AsyncFSBrowser/ESP_AsyncFSBrowser.ino +++ b/examples/ESP_AsyncFSBrowser/ESP_AsyncFSBrowser.ino @@ -157,7 +157,16 @@ void setup(){ MDNS.addService("http","tcp",80); - MYFS.begin(); +//FS +#ifdef USE_FatFS + if (MYFS.begin(false,"/ffat",3)) { //limit the RAM usage, bottom line 8kb + 4kb takes per each file, default is 10 +#else + if (MYFS.begin()) { +#endif + Serial.print(F("FS mounted\n")); + } else { + Serial.print(F("FS mount failed\n")); + } ws.onEvent(onWsEvent); server.addHandler(&ws); diff --git a/examples/ESP_AsyncFSBrowser/data/ace.ico.gz b/examples/ESP_AsyncFSBrowser/data/ace.ico.gz new file mode 100644 index 0000000000000000000000000000000000000000..49e15bcebdeba0b55db396e5b6266b6e72730070 GIT binary patch literal 6307 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 #elif defined(ESP8266) #ifdef USE_LittleFS - #include + #include #define HSTNM "ssw8266-littlefs" - #define MYFS LittleFS - #include + #define MYFS LittleFS + #include #elif defined(USE_FatFS) #error "FatFS only on ESP32 for now!" #else @@ -550,10 +550,14 @@ void setup(){ Serial.printf("Temp set %+2.1f\n", ee.tempe); //FS +#ifdef USE_FatFS + if (MYFS.begin(false,"/ffat",3)) { //limit the RAM usage, bottom line 8kb + 4kb takes per each file, default is 10 +#else if (MYFS.begin()) { +#endif Serial.print(F("FS mounted\n")); } else { - Serial.print(F("FS mount failed\n")); + Serial.print(F("FS mount failed\n")); } #ifdef USE_AUTH_WS From c61f2d8d0266bfb37e4b37d9e44b1684e4f48363 Mon Sep 17 00:00:00 2001 From: lorol Date: Thu, 30 Jul 2020 09:24:21 -0400 Subject: [PATCH 067/551] Tests OK with esp32s2 Arduino core --- .../ESP_AsyncFSBrowser/data/acefull.js.gz | Bin 117524 -> 117524 bytes .../ESP_AsyncFSBrowser/data/worker-css.js.gz | Bin 32927 -> 32927 bytes .../ESP_AsyncFSBrowser/data/worker-html.js.gz | Bin 45019 -> 45019 bytes .../data/worker-javascript.js.gz | Bin 112558 -> 112558 bytes examples/SmartSwitch/ESPAsyncWiFiManager.h | 4 ++++ examples/SmartSwitch/data/acefull.js.gz | Bin 117524 -> 117524 bytes examples/SmartSwitch/data/worker-css.js.gz | Bin 32927 -> 32927 bytes examples/SmartSwitch/data/worker-html.js.gz | Bin 45019 -> 45019 bytes .../SmartSwitch/data/worker-javascript.js.gz | Bin 112558 -> 112558 bytes src/edit.htm.gz.h | 2 +- 10 files changed, 5 insertions(+), 1 deletion(-) diff --git a/examples/ESP_AsyncFSBrowser/data/acefull.js.gz b/examples/ESP_AsyncFSBrowser/data/acefull.js.gz index e88a884655abb64466041d0be61874b93598a18c..7e65c5f6d5ed9e3466cf5bb3a200e22d3db94a29 100644 GIT binary patch delta 21 dcmbO-jeW{Ac6Rx04vv*4lp5K$vNQ6Y1^`YL2Gjrm delta 21 dcmbO-jeW{Ac6Rx04i5FT?2YVO*%^6H0{}-i1{?qY diff --git a/examples/ESP_AsyncFSBrowser/data/worker-css.js.gz b/examples/ESP_AsyncFSBrowser/data/worker-css.js.gz index 658f04aff7224a0bb99abbdd273f99d8ced0b420..23cfa33a5a3c13868e41875c80ce8fc5ea3ae8d0 100644 GIT binary patch delta 18 ZcmbQ=$TYu^iCw;%gJby#rH$+}8UQ+d24?^O delta 18 ZcmbQ=$TYu^iCw;%gF|gC`$qN|4FEOG1+V}B diff --git a/examples/ESP_AsyncFSBrowser/data/worker-html.js.gz b/examples/ESP_AsyncFSBrowser/data/worker-html.js.gz index 1556f5a8dfa9319797730cd5ec88e48ac19f36da..69a5f29ca6063e498b83bf508c974fccdaaaeb02 100644 GIT binary patch delta 18 acmcb8pXv5}CU*I54vys~ls2+oSq}hCLI?%` delta 18 acmcb8pXv5}CU*I54i43|>>JsytOo!|iw8~s diff --git a/examples/ESP_AsyncFSBrowser/data/worker-javascript.js.gz b/examples/ESP_AsyncFSBrowser/data/worker-javascript.js.gz index 2b45889847baf8b0729068fe6bc8691913e6dfc6..9523daf4b0d7d24e64d4724c04d17d218d7ae976 100644 GIT binary patch delta 21 dcmZ4Yo^9QGHg@@L4vv*4lp5K$vNJB<4gg=~2tEJ+ delta 21 dcmZ4Yo^9QGHg@@L4i5FT?2YVO*%_B_2LM?I2ZjIu diff --git a/examples/SmartSwitch/ESPAsyncWiFiManager.h b/examples/SmartSwitch/ESPAsyncWiFiManager.h index f6e2e5b7e..deecf4f7f 100644 --- a/examples/SmartSwitch/ESPAsyncWiFiManager.h +++ b/examples/SmartSwitch/ESPAsyncWiFiManager.h @@ -44,8 +44,12 @@ extern "C" { #include "user_interface.h" } #else +#if __has_include() +#include +#else #include #endif +#endif const char WFM_HTTP_HEAD[] PROGMEM = "{v}"; const char HTTP_STYLE[] PROGMEM = ""; diff --git a/examples/SmartSwitch/data/acefull.js.gz b/examples/SmartSwitch/data/acefull.js.gz index e88a884655abb64466041d0be61874b93598a18c..7e65c5f6d5ed9e3466cf5bb3a200e22d3db94a29 100644 GIT binary patch delta 21 dcmbO-jeW{Ac6Rx04vv*4lp5K$vNQ6Y1^`YL2Gjrm delta 21 dcmbO-jeW{Ac6Rx04i5FT?2YVO*%^6H0{}-i1{?qY diff --git a/examples/SmartSwitch/data/worker-css.js.gz b/examples/SmartSwitch/data/worker-css.js.gz index 658f04aff7224a0bb99abbdd273f99d8ced0b420..23cfa33a5a3c13868e41875c80ce8fc5ea3ae8d0 100644 GIT binary patch delta 18 ZcmbQ=$TYu^iCw;%gJby#rH$+}8UQ+d24?^O delta 18 ZcmbQ=$TYu^iCw;%gF|gC`$qN|4FEOG1+V}B diff --git a/examples/SmartSwitch/data/worker-html.js.gz b/examples/SmartSwitch/data/worker-html.js.gz index 1556f5a8dfa9319797730cd5ec88e48ac19f36da..69a5f29ca6063e498b83bf508c974fccdaaaeb02 100644 GIT binary patch delta 18 acmcb8pXv5}CU*I54vys~ls2+oSq}hCLI?%` delta 18 acmcb8pXv5}CU*I54i43|>>JsytOo!|iw8~s diff --git a/examples/SmartSwitch/data/worker-javascript.js.gz b/examples/SmartSwitch/data/worker-javascript.js.gz index 2b45889847baf8b0729068fe6bc8691913e6dfc6..9523daf4b0d7d24e64d4724c04d17d218d7ae976 100644 GIT binary patch delta 21 dcmZ4Yo^9QGHg@@L4vv*4lp5K$vNJB<4gg=~2tEJ+ delta 21 dcmZ4Yo^9QGHg@@L4i5FT?2YVO*%_B_2LM?I2ZjIu diff --git a/src/edit.htm.gz.h b/src/edit.htm.gz.h index 9f101144e..b8b5c02b0 100644 --- a/src/edit.htm.gz.h +++ b/src/edit.htm.gz.h @@ -2,7 +2,7 @@ //File: edit.htm.gz, Size: 4503 #define edit_htm_gz_len 4503 const uint8_t edit_htm_gz[] PROGMEM = { -0x1F,0x8B,0x08,0x08,0x1C,0xAD,0x07,0x5F,0x02,0x00,0x65,0x64,0x69,0x74,0x2E,0x68,0x74,0x6D,0x00,0xB5, +0x1F,0x8B,0x08,0x08,0x9B,0xC8,0x22,0x5F,0x02,0x00,0x65,0x64,0x69,0x74,0x2E,0x68,0x74,0x6D,0x00,0xB5, 0x1A,0x0B,0x5B,0xDB,0x36,0xF0,0xAF,0x18,0x6F,0x63,0xF6,0xE2,0x38,0x0E,0x50,0xD6,0x3A,0x18,0x16,0x1E, 0xEB,0xBB,0x50,0x12,0xDA,0xD1,0x8E,0xED,0x53,0x6C,0x25,0x56,0xB1,0x25,0xCF,0x96,0x09,0x34,0xCD,0x7F, 0xDF,0x49,0xF2,0x93,0x84,0xEE,0xF1,0x6D,0xA5,0x60,0x49,0xA7,0x3B,0xDD,0x9D,0xEE,0x25,0xD9,0x7B,0x1B, From d803e1298036ef5df92a1b5d502e3310ad575fc7 Mon Sep 17 00:00:00 2001 From: lorol Date: Wed, 19 Aug 2020 14:22:06 -0400 Subject: [PATCH 068/551] In SPIFFSEditor.h Prevented a warning that SPIFFS has been deprecated on esp32 In WebHandlers.cpp A difference between SPIFFS and LITTLEFS of opendir() response in file.open() of FS vfs_api.cpp has been resolved. --- .github/scripts/on-push.sh | 6 +++++- .../ESP_AsyncFSBrowser/data/acefull.js.gz | Bin 117524 -> 117524 bytes .../ESP_AsyncFSBrowser/data/worker-css.js.gz | Bin 32927 -> 32927 bytes .../ESP_AsyncFSBrowser/data/worker-html.js.gz | Bin 45019 -> 45019 bytes .../data/worker-javascript.js.gz | Bin 112558 -> 112558 bytes examples/SmartSwitch/data/acefull.js.gz | Bin 117524 -> 117524 bytes examples/SmartSwitch/data/worker-css.js.gz | Bin 32927 -> 32927 bytes examples/SmartSwitch/data/worker-html.js.gz | Bin 45019 -> 45019 bytes .../SmartSwitch/data/worker-javascript.js.gz | Bin 112558 -> 112558 bytes src/SPIFFSEditor.h | 3 ++- src/WebHandlers.cpp | 16 ++++++++++++---- src/edit.htm.gz.h | 2 +- 12 files changed, 20 insertions(+), 7 deletions(-) diff --git a/.github/scripts/on-push.sh b/.github/scripts/on-push.sh index 96fff573e..1eedd0779 100755 --- a/.github/scripts/on-push.sh +++ b/.github/scripts/on-push.sh @@ -7,7 +7,7 @@ if [ ! -z "$TRAVIS_BUILD_DIR" ]; then export GITHUB_REPOSITORY="$TRAVIS_REPO_SLUG" elif [ -z "$GITHUB_WORKSPACE" ]; then export GITHUB_WORKSPACE="$PWD" - export GITHUB_REPOSITORY="me-no-dev/ESPAsyncWebServer" + export GITHUB_REPOSITORY="lorol/ESPAsyncWebServer" fi TARGET_PLATFORM="$1" @@ -34,8 +34,12 @@ if [ "$BUILD_PIO" -eq 0 ]; then cp -rf "$GITHUB_WORKSPACE" "$ARDUINO_USR_PATH/libraries/ESPAsyncWebServer" echo "Installing ArduinoJson ..." git clone https://github.com/bblanchon/ArduinoJson "$ARDUINO_USR_PATH/libraries/ArduinoJson" > /dev/null 2>&1 + echo "Installing DHT sensor library ..." + git clone https://github.com/adafruit/DHT-sensor-library "$ARDUINO_USR_PATH/libraries/DHT-sensor-library" > /dev/null 2>&1 if [[ "$TARGET_PLATFORM" == "esp32" ]]; then + echo "Installing LITTLEFS for ESP32 ..." + git clone https://github.com/lorol/LITTLEFS "$ARDUINO_USR_PATH/libraries/LITTLEFS" > /dev/null 2>&1 echo "Installing AsyncTCP ..." git clone https://github.com/me-no-dev/AsyncTCP "$ARDUINO_USR_PATH/libraries/AsyncTCP" > /dev/null 2>&1 FQBN="espressif:esp32:esp32:PSRAM=enabled,PartitionScheme=huge_app" diff --git a/examples/ESP_AsyncFSBrowser/data/acefull.js.gz b/examples/ESP_AsyncFSBrowser/data/acefull.js.gz index 7e65c5f6d5ed9e3466cf5bb3a200e22d3db94a29..4a0ae6120f768922447ecf68f82f4451857a4b89 100644 GIT binary patch delta 21 ccmbO-jeW{Ac6Rx04vwB|+eY@S?2Npp0ZNAkbpQYW delta 21 dcmbO-jeW{Ac6Rx04vv*4lp5K$vNQ6Y1^`YL2Gjrm diff --git a/examples/ESP_AsyncFSBrowser/data/worker-css.js.gz b/examples/ESP_AsyncFSBrowser/data/worker-css.js.gz index 23cfa33a5a3c13868e41875c80ce8fc5ea3ae8d0..dc267b31e163d3823d510176f61c26af9c3bed49 100644 GIT binary patch delta 18 ZcmbQ=$TYu^iCw;%gQGj!b|d?Y1^_q`1_=NF delta 18 ZcmbQ=$TYu^iCw;%gJby#rH$+}8UQ+d24?^O diff --git a/examples/ESP_AsyncFSBrowser/data/worker-html.js.gz b/examples/ESP_AsyncFSBrowser/data/worker-html.js.gz index 69a5f29ca6063e498b83bf508c974fccdaaaeb02..c551f7094c333e68b393be4d7be9024fe733c183 100644 GIT binary patch delta 18 acmcb8pXv5}CU*I54vwyD+l}m3)&l@b&_tempFile = _fs.open(gzip, fs::FileOpenMode::read); - gzipFound = FILE_IS_REAL(request->_tempFile); + if (_fs.exists(gzip)) { + request->_tempFile = _fs.open(gzip, fs::FileOpenMode::read); + gzipFound = FILE_IS_REAL(request->_tempFile); + } if (!gzipFound){ + if (_fs.exists(path)) { request->_tempFile = _fs.open(path, fs::FileOpenMode::read); fileFound = FILE_IS_REAL(request->_tempFile); + } } } else { - request->_tempFile = _fs.open(path, fs::FileOpenMode::read); - fileFound = FILE_IS_REAL(request->_tempFile); + if (_fs.exists(path)) { + request->_tempFile = _fs.open(path, fs::FileOpenMode::read); + fileFound = FILE_IS_REAL(request->_tempFile); + } if (!fileFound){ + if (_fs.exists(gzip)) { request->_tempFile = _fs.open(gzip, fs::FileOpenMode::read); gzipFound = FILE_IS_REAL(request->_tempFile); + } } } diff --git a/src/edit.htm.gz.h b/src/edit.htm.gz.h index b8b5c02b0..ae6dcea38 100644 --- a/src/edit.htm.gz.h +++ b/src/edit.htm.gz.h @@ -2,7 +2,7 @@ //File: edit.htm.gz, Size: 4503 #define edit_htm_gz_len 4503 const uint8_t edit_htm_gz[] PROGMEM = { -0x1F,0x8B,0x08,0x08,0x9B,0xC8,0x22,0x5F,0x02,0x00,0x65,0x64,0x69,0x74,0x2E,0x68,0x74,0x6D,0x00,0xB5, +0x1F,0x8B,0x08,0x08,0x66,0x6B,0x3D,0x5F,0x02,0x00,0x65,0x64,0x69,0x74,0x2E,0x68,0x74,0x6D,0x00,0xB5, 0x1A,0x0B,0x5B,0xDB,0x36,0xF0,0xAF,0x18,0x6F,0x63,0xF6,0xE2,0x38,0x0E,0x50,0xD6,0x3A,0x18,0x16,0x1E, 0xEB,0xBB,0x50,0x12,0xDA,0xD1,0x8E,0xED,0x53,0x6C,0x25,0x56,0xB1,0x25,0xCF,0x96,0x09,0x34,0xCD,0x7F, 0xDF,0x49,0xF2,0x93,0x84,0xEE,0xF1,0x6D,0xA5,0x60,0x49,0xA7,0x3B,0xDD,0x9D,0xEE,0x25,0xD9,0x7B,0x1B, From 3a406f804e09b1a8a7024018e33d5671d069182b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Villac=C3=ADs=20Lasso?= Date: Tue, 25 Aug 2020 11:48:00 -0500 Subject: [PATCH 069/551] Explicitly close socket after response has entered finished state In at least two places in the code, the response object is evaluated on whether it has finished sending data to the client. If the response has already finished, or enters the finished state after sending data, the underlying socket should not be left open. Failure to close the socket in these scenarios cause the remote client to timeout expecting more data unless it closes the connection on its own. Fixes: #802 --- src/WebRequest.cpp | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/WebRequest.cpp b/src/WebRequest.cpp index bbce5ca4c..35fd7dccd 100644 --- a/src/WebRequest.cpp +++ b/src/WebRequest.cpp @@ -189,8 +189,16 @@ void AsyncWebServerRequest::_removeNotInterestingHeaders(){ void AsyncWebServerRequest::_onPoll(){ //os_printf("p\n"); - if(_response != NULL && _client != NULL && _client->canSend() && !_response->_finished()){ - _response->_ack(this, 0, 0); + if(_response != NULL && _client != NULL && _client->canSend()){ + if(!_response->_finished()){ + _response->_ack(this, 0, 0); + } else { + AsyncWebServerResponse* r = _response; + _response = NULL; + delete r; + + _client->close(); + } } } @@ -199,10 +207,13 @@ void AsyncWebServerRequest::_onAck(size_t len, uint32_t time){ if(_response != NULL){ if(!_response->_finished()){ _response->_ack(this, len, time); - } else { + } + if(_response->_finished()){ AsyncWebServerResponse* r = _response; _response = NULL; delete r; + + _client->close(); } } } From 737a3567b760e8a38600b1e4ac4f5045ed37b5ae Mon Sep 17 00:00:00 2001 From: lorol Date: Thu, 3 Sep 2020 11:26:49 -0400 Subject: [PATCH 070/551] Manually merged changes from BlueAndy fork Minor updates of my custom stuff --- .../ESP_AsyncFSBrowser/data/acefull.js.gz | Bin 117524 -> 117524 bytes .../ESP_AsyncFSBrowser/data/worker-css.js.gz | Bin 32927 -> 32927 bytes .../ESP_AsyncFSBrowser/data/worker-html.js.gz | Bin 45019 -> 45019 bytes .../data/worker-javascript.js.gz | Bin 112558 -> 112558 bytes examples/SmartSwitch/SmartSwitch.ino | 16 ++++++++++++++-- examples/SmartSwitch/data/acefull.js.gz | Bin 117524 -> 117524 bytes examples/SmartSwitch/data/worker-css.js.gz | Bin 32927 -> 32927 bytes examples/SmartSwitch/data/worker-html.js.gz | Bin 45019 -> 45019 bytes .../SmartSwitch/data/worker-javascript.js.gz | Bin 112558 -> 112558 bytes src/AsyncWebSocket.cpp | 6 ++++-- src/WebRequest.cpp | 17 ++++++++++++++--- src/edit.htm.gz.h | 2 +- 12 files changed, 33 insertions(+), 8 deletions(-) diff --git a/examples/ESP_AsyncFSBrowser/data/acefull.js.gz b/examples/ESP_AsyncFSBrowser/data/acefull.js.gz index 4a0ae6120f768922447ecf68f82f4451857a4b89..4b10ee879cb1238a59fb0f23064da41ba4b6da28 100644 GIT binary patch delta 21 dcmbO-jeW{Ac6Rx04vwM;UXAQq*%^6H0{}}n28{p! delta 21 ccmbO-jeW{Ac6Rx04vwB|+eY@S?2Npp0ZNAkbpQYW diff --git a/examples/ESP_AsyncFSBrowser/data/worker-css.js.gz b/examples/ESP_AsyncFSBrowser/data/worker-css.js.gz index dc267b31e163d3823d510176f61c26af9c3bed49..97beeb133712d3e716a32b360301942afee6ae4a 100644 GIT binary patch delta 18 ZcmbQ=$TYu^iCw;%gQIYQ*GBdk4FEWM1|a|d delta 18 ZcmbQ=$TYu^iCw;%gQGj!b|d?Y1^_q`1_=NF diff --git a/examples/ESP_AsyncFSBrowser/data/worker-html.js.gz b/examples/ESP_AsyncFSBrowser/data/worker-html.js.gz index c551f7094c333e68b393be4d7be9024fe733c183..819a3b7842296f34a262479417b33cc94809069b 100644 GIT binary patch delta 18 acmcb8pXv5}CU*I54vvBeUK`o3tOo#0IS0Q0 delta 18 acmcb8pXv5}CU*I54vwyD+l}m3)&l@b&authenticate(http_username, http_password)) return request->requestAuthentication(); #endif - request->onDisconnect([]() { - WiFi.disconnect(true); + request->onDisconnect([]() { #ifdef ESP32 +/* + //https://github.com/espressif/arduino-esp32/issues/400#issuecomment-499631249 + //WiFi.disconnect(true); // doesn't work on esp32, below needs #include "esp_wifi.h" + wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); //load the flash-saved configs + esp_wifi_init(&cfg); //initiate and allocate wifi resources (does not matter if connection fails) + if(esp_wifi_restore()!=ESP_OK){ + Serial.print(F("WiFi is not initialized by esp_wifi_init ")); + } else { + Serial.print(F("WiFi Configurations Cleared!")); + } +*/ + WiFi.disconnect(true, true); // Works on esp32 ESP.restart(); #elif defined(ESP8266) + WiFi.disconnect(true); ESP.reset(); #endif }); diff --git a/examples/SmartSwitch/data/acefull.js.gz b/examples/SmartSwitch/data/acefull.js.gz index 4a0ae6120f768922447ecf68f82f4451857a4b89..4b10ee879cb1238a59fb0f23064da41ba4b6da28 100644 GIT binary patch delta 21 dcmbO-jeW{Ac6Rx04vwM;UXAQq*%^6H0{}}n28{p! delta 21 ccmbO-jeW{Ac6Rx04vwB|+eY@S?2Npp0ZNAkbpQYW diff --git a/examples/SmartSwitch/data/worker-css.js.gz b/examples/SmartSwitch/data/worker-css.js.gz index dc267b31e163d3823d510176f61c26af9c3bed49..97beeb133712d3e716a32b360301942afee6ae4a 100644 GIT binary patch delta 18 ZcmbQ=$TYu^iCw;%gQIYQ*GBdk4FEWM1|a|d delta 18 ZcmbQ=$TYu^iCw;%gQGj!b|d?Y1^_q`1_=NF diff --git a/examples/SmartSwitch/data/worker-html.js.gz b/examples/SmartSwitch/data/worker-html.js.gz index c551f7094c333e68b393be4d7be9024fe733c183..819a3b7842296f34a262479417b33cc94809069b 100644 GIT binary patch delta 18 acmcb8pXv5}CU*I54vvBeUK`o3tOo#0IS0Q0 delta 18 acmcb8pXv5}CU*I54vwyD+l}m3)&l@b&_handleEvent(this, WS_EVT_DATA, (void *)&_pinfo, (uint8_t*)data, datalen); + if (datalen > 0) _server->_handleEvent(this, WS_EVT_DATA, (void *)&_pinfo, (uint8_t*)data, datalen); _pinfo.index += datalen; } else if((datalen + _pinfo.index) == _pinfo.len){ @@ -694,6 +694,8 @@ void AsyncWebSocketClient::_onData(void *pbuf, size_t plen){ _server->_handleEvent(this, WS_EVT_PONG, NULL, data, datalen); } else if(_pinfo.opcode < 8){//continuation or text/binary frame _server->_handleEvent(this, WS_EVT_DATA, (void *)&_pinfo, data, datalen); + if (_pinfo.final) _pinfo.num = 0; + else _pinfo.num += 1; } } else { //os_printf("frame error: len: %u, index: %llu, total: %llu\n", datalen, _pinfo.index, _pinfo.len); diff --git a/src/WebRequest.cpp b/src/WebRequest.cpp index 5031f263e..6d79726e1 100644 --- a/src/WebRequest.cpp +++ b/src/WebRequest.cpp @@ -192,8 +192,16 @@ void AsyncWebServerRequest::_removeNotInterestingHeaders(){ void AsyncWebServerRequest::_onPoll(){ //os_printf("p\n"); - if(_response != NULL && _client != NULL && _client->canSend() && !_response->_finished()){ - _response->_ack(this, 0, 0); + if(_response != NULL && _client != NULL && _client->canSend()){ + if(!_response->_finished()){ + _response->_ack(this, 0, 0); + } else { + AsyncWebServerResponse* r = _response; + _response = NULL; + delete r; + + _client->close(); + } } } @@ -202,10 +210,13 @@ void AsyncWebServerRequest::_onAck(size_t len, uint32_t time){ if(_response != NULL){ if(!_response->_finished()){ _response->_ack(this, len, time); - } else { + } + if(_response->_finished()){ AsyncWebServerResponse* r = _response; _response = NULL; delete r; + + _client->close(); } } } diff --git a/src/edit.htm.gz.h b/src/edit.htm.gz.h index ae6dcea38..3b163a0fc 100644 --- a/src/edit.htm.gz.h +++ b/src/edit.htm.gz.h @@ -2,7 +2,7 @@ //File: edit.htm.gz, Size: 4503 #define edit_htm_gz_len 4503 const uint8_t edit_htm_gz[] PROGMEM = { -0x1F,0x8B,0x08,0x08,0x66,0x6B,0x3D,0x5F,0x02,0x00,0x65,0x64,0x69,0x74,0x2E,0x68,0x74,0x6D,0x00,0xB5, +0x1F,0x8B,0x08,0x08,0x54,0x90,0x4A,0x5F,0x02,0x00,0x65,0x64,0x69,0x74,0x2E,0x68,0x74,0x6D,0x00,0xB5, 0x1A,0x0B,0x5B,0xDB,0x36,0xF0,0xAF,0x18,0x6F,0x63,0xF6,0xE2,0x38,0x0E,0x50,0xD6,0x3A,0x18,0x16,0x1E, 0xEB,0xBB,0x50,0x12,0xDA,0xD1,0x8E,0xED,0x53,0x6C,0x25,0x56,0xB1,0x25,0xCF,0x96,0x09,0x34,0xCD,0x7F, 0xDF,0x49,0xF2,0x93,0x84,0xEE,0xF1,0x6D,0xA5,0x60,0x49,0xA7,0x3B,0xDD,0x9D,0xEE,0x25,0xD9,0x7B,0x1B, From 848a929e552d2b1becb3f377d5d7f503f5d9abdf Mon Sep 17 00:00:00 2001 From: Dmytro Korniienko Date: Sat, 12 Sep 2020 14:40:39 +0300 Subject: [PATCH 071/551] Manual merge from anton-zolotarev:master --- src/AsyncWebSocket.cpp | 132 +++++++++++++++++++++++++++++++++-------- src/AsyncWebSocket.h | 38 ++++++------ 2 files changed, 128 insertions(+), 42 deletions(-) diff --git a/src/AsyncWebSocket.cpp b/src/AsyncWebSocket.cpp index 6b2f9e9c4..9ebab12cd 100644 --- a/src/AsyncWebSocket.cpp +++ b/src/AsyncWebSocket.cpp @@ -52,11 +52,15 @@ size_t webSocketSendFrameWindow(AsyncClient *client){ } size_t webSocketSendFrame(AsyncClient *client, bool final, uint8_t opcode, bool mask, uint8_t *data, size_t len){ - if(!client->canSend()) + if(!client->canSend()) { + // Serial.println("SF 1"); return 0; + } size_t space = client->space(); - if(space < 2) + if(space < 2) { + // Serial.println("SF 2"); return 0; + } uint8_t mbuf[4] = {0,0,0,0}; uint8_t headLen = 2; if(len && mask){ @@ -68,8 +72,10 @@ size_t webSocketSendFrame(AsyncClient *client, bool final, uint8_t opcode, bool } if(len > 125) headLen += 2; - if(space < headLen) + if(space < headLen) { + // Serial.println("SF 2"); return 0; + } space -= headLen; if(len > space) len = space; @@ -77,6 +83,7 @@ size_t webSocketSendFrame(AsyncClient *client, bool final, uint8_t opcode, bool uint8_t *buf = (uint8_t*)malloc(headLen); if(buf == NULL){ //os_printf("could not malloc %u bytes for frame header\n", headLen); + // Serial.println("SF 3"); return 0; } @@ -97,6 +104,7 @@ size_t webSocketSendFrame(AsyncClient *client, bool final, uint8_t opcode, bool if(client->add((const char *)buf, headLen) != headLen){ //os_printf("error adding %lu header bytes\n", headLen); free(buf); + // Serial.println("SF 4"); return 0; } free(buf); @@ -109,13 +117,16 @@ size_t webSocketSendFrame(AsyncClient *client, bool final, uint8_t opcode, bool } if(client->add((const char *)data, len) != len){ //os_printf("error adding %lu data bytes\n", len); + // Serial.println("SF 5"); return 0; } } if(!client->send()){ //os_printf("error sending frame: %lu\n", headLen+len); + // Serial.println("SF 6"); return 0; } + // Serial.println("SF"); return len; } @@ -149,6 +160,7 @@ AsyncWebSocketMessageBuffer::AsyncWebSocketMessageBuffer(uint8_t * data, size_t _data = new uint8_t[_len + 1]; if (_data) { + // Serial.println("BUFF alloc"); memcpy(_data, data, _len); _data[_len] = 0; } @@ -164,6 +176,7 @@ AsyncWebSocketMessageBuffer::AsyncWebSocketMessageBuffer(size_t size) _data = new uint8_t[_len + 1]; if (_data) { + // Serial.println("BUFF alloc"); _data[_len] = 0; } @@ -185,6 +198,7 @@ AsyncWebSocketMessageBuffer::AsyncWebSocketMessageBuffer(const AsyncWebSocketMes } if (_data) { + // Serial.println("BUFF alloc"); memcpy(_data, copy._data, _len); _data[_len] = 0; } @@ -202,6 +216,7 @@ AsyncWebSocketMessageBuffer::AsyncWebSocketMessageBuffer(AsyncWebSocketMessageBu _count = 0; if (copy._data) { + // Serial.println("BUFF alloc"); _data = copy._data; copy._data = nullptr; } @@ -211,6 +226,7 @@ AsyncWebSocketMessageBuffer::AsyncWebSocketMessageBuffer(AsyncWebSocketMessageBu AsyncWebSocketMessageBuffer::~AsyncWebSocketMessageBuffer() { if (_data) { + // Serial.println("BUFF free"); delete[] _data; } } @@ -293,6 +309,7 @@ AsyncWebSocketBasicMessage::AsyncWebSocketBasicMessage(const char * data, size_t _opcode = opcode & 0x07; _mask = mask; _data = (uint8_t*)malloc(_len+1); + // Serial.println("MSG alloc"); if(_data == NULL){ _len = 0; _status = WS_MSG_ERROR; @@ -316,35 +333,43 @@ AsyncWebSocketBasicMessage::AsyncWebSocketBasicMessage(uint8_t opcode, bool mask AsyncWebSocketBasicMessage::~AsyncWebSocketBasicMessage() { - if(_data != NULL) + if(_data != NULL) { + // Serial.println("MSG free"); free(_data); + } } void AsyncWebSocketBasicMessage::ack(size_t len, uint32_t time) { (void)time; _acked += len; + // Serial.printf("ACK %u = %u | %u = %u\n", _sent, _len, _acked, _ack); if(_sent == _len && _acked == _ack){ + // Serial.println("ACK end"); _status = WS_MSG_SENT; } } size_t AsyncWebSocketBasicMessage::send(AsyncClient *client) { - if(_status != WS_MSG_SENDING) + if(_status != WS_MSG_SENDING){ + // Serial.println("MS 1"); return 0; + } if(_acked < _ack){ + // Serial.println("MS 2"); return 0; } if(_sent == _len){ - if(_acked == _ack) - _status = WS_MSG_SENT; + // Serial.println("MS 3"); + _status = WS_MSG_SENT; return 0; } if(_sent > _len){ + // Serial.println("MS 4"); _status = WS_MSG_ERROR; return 0; } - size_t toSend = _len - _sent; size_t window = webSocketSendFrameWindow(client); + // Serial.printf("Send %u %u %u\n", _len, _sent, toSend); if(window < toSend) { toSend = window; @@ -360,8 +385,14 @@ AsyncWebSocketBasicMessage::~AsyncWebSocketBasicMessage() { size_t sent = webSocketSendFrame(client, final, opCode, _mask, dPtr, toSend); _status = WS_MSG_SENDING; if(toSend && sent != toSend){ - _sent -= (toSend - sent); - _ack -= (toSend - sent); + size_t delta = (toSend - sent); + // Serial.printf("\ns:%u a:%u d:%u\n", _sent, _ack, delta); + _sent -= delta; + _ack -= delta + ((delta < 126)?2:4) + (_mask * 4); + // Serial.printf("s:%u a:%u\n", _sent, _ack); + if (!sent) { + _status = WS_MSG_ERROR; + } } return sent; } @@ -399,11 +430,13 @@ AsyncWebSocketMultiMessage::AsyncWebSocketMultiMessage(AsyncWebSocketMessageBuff if (buffer) { _WSbuffer = buffer; (*_WSbuffer)++; + // Serial.printf("INC WSbuffer == %u\n", _WSbuffer->count()); _data = buffer->get(); _len = buffer->length(); _status = WS_MSG_SENDING; //ets_printf("M: %u\n", _len); } else { + // Serial.println("BUFF ERROR"); _status = WS_MSG_ERROR; } @@ -413,40 +446,48 @@ AsyncWebSocketMultiMessage::AsyncWebSocketMultiMessage(AsyncWebSocketMessageBuff AsyncWebSocketMultiMessage::~AsyncWebSocketMultiMessage() { if (_WSbuffer) { (*_WSbuffer)--; // decreases the counter. + // Serial.printf("DEC WSbuffer == %u\n", _WSbuffer->count()); } } void AsyncWebSocketMultiMessage::ack(size_t len, uint32_t time) { (void)time; _acked += len; + // Serial.printf("ACK %u = %u | %u = %u\n", _sent, _len, _acked, _ack); if(_sent >= _len && _acked >= _ack){ + // Serial.println("ACK end"); _status = WS_MSG_SENT; } //ets_printf("A: %u\n", len); } size_t AsyncWebSocketMultiMessage::send(AsyncClient *client) { - if(_status != WS_MSG_SENDING) + if(_status != WS_MSG_SENDING) { + // Serial.println("MS 1"); return 0; + } if(_acked < _ack){ + // Serial.println("MS 2"); return 0; } if(_sent == _len){ + // Serial.println("MS 3"); _status = WS_MSG_SENT; return 0; } if(_sent > _len){ + // Serial.println("MS 4"); _status = WS_MSG_ERROR; //ets_printf("E: %u > %u\n", _sent, _len); return 0; } - size_t toSend = _len - _sent; size_t window = webSocketSendFrameWindow(client); + // Serial.printf("Send %u %u %u\n", _len, _sent, toSend); if(window < toSend) { toSend = window; } - + // Serial.printf("s:%u a:%u t:%u\n", _sent, _ack, toSend); _sent += toSend; _ack += toSend + ((toSend < 126)?2:4) + (_mask * 4); @@ -460,8 +501,14 @@ AsyncWebSocketMultiMessage::~AsyncWebSocketMultiMessage() { _status = WS_MSG_SENDING; if(toSend && sent != toSend){ //ets_printf("E: %u != %u\n", toSend, sent); - _sent -= (toSend - sent); - _ack -= (toSend - sent); + size_t delta = (toSend - sent); + // Serial.printf("\ns:%u a:%u d:%u\n", _sent, _ack, delta); + _sent -= delta; + _ack -= delta + ((delta < 126)?2:4) + (_mask * 4); + // Serial.printf("s:%u a:%u\n", _sent, _ack); + if (!sent) { + _status = WS_MSG_ERROR; + } } //ets_printf("S: %u %u\n", _sent, sent); return sent; @@ -496,16 +543,25 @@ AsyncWebSocketClient::AsyncWebSocketClient(AsyncWebServerRequest *request, Async _server->_addClient(this); _server->_handleEvent(this, WS_EVT_CONNECT, request, NULL, 0); delete request; - memset(&_pinfo,0,sizeof(_pinfo)); // + memset(&_pinfo,0,sizeof(_pinfo)); } AsyncWebSocketClient::~AsyncWebSocketClient(){ + // Serial.printf("%u FREE Q\n", id()); _messageQueue.free(); _controlQueue.free(); + _server->_cleanBuffers(); _server->_handleEvent(this, WS_EVT_DISCONNECT, NULL, NULL, 0); } +void AsyncWebSocketClient::_clearQueue(){ + while(!_messageQueue.isEmpty() && _messageQueue.front()->finished()){ + _messageQueue.remove(_messageQueue.front()); + } +} + void AsyncWebSocketClient::_onAck(size_t len, uint32_t time){ + // Serial.printf("%u onAck\n", id()); _lastMessageTime = millis(); if(!_controlQueue.isEmpty()){ auto head = _controlQueue.front(); @@ -520,15 +576,21 @@ void AsyncWebSocketClient::_onAck(size_t len, uint32_t time){ _controlQueue.remove(head); } } + if(len && !_messageQueue.isEmpty()){ _messageQueue.front()->ack(len, time); } + + _clearQueue(); + _server->_cleanBuffers(); + // Serial.println("RUN 1"); _runQueue(); } void AsyncWebSocketClient::_onPoll(){ if(_client->canSend() && (!_controlQueue.isEmpty() || !_messageQueue.isEmpty())){ + // Serial.println("RUN 2"); _runQueue(); } else if(_keepAlivePeriod > 0 && _controlQueue.isEmpty() && _messageQueue.isEmpty() && (millis() - _lastMessageTime) >= _keepAlivePeriod){ ping((uint8_t *)AWSC_PING_PAYLOAD, AWSC_PING_PAYLOAD_LEN); @@ -536,15 +598,20 @@ void AsyncWebSocketClient::_onPoll(){ } void AsyncWebSocketClient::_runQueue(){ - while(!_messageQueue.isEmpty() && _messageQueue.front()->finished()){ - _messageQueue.remove(_messageQueue.front()); - } + _clearQueue(); + //size_t m0 = _messageQueue.isEmpty()? 0 : _messageQueue.length(); + //size_t m1 = _messageQueue.isEmpty()? 0 : _messageQueue.front()->betweenFrames(); + // Serial.printf("%u R C = %u %u\n", _clientId, m0, m1); if(!_controlQueue.isEmpty() && (_messageQueue.isEmpty() || _messageQueue.front()->betweenFrames()) && webSocketSendFrameWindow(_client) > (size_t)(_controlQueue.front()->len() - 1)){ + // Serial.printf("%u R S C\n", _clientId); _controlQueue.front()->send(_client); } else if(!_messageQueue.isEmpty() && _messageQueue.front()->betweenFrames() && webSocketSendFrameWindow(_client)){ + // Serial.printf("%u R S M = ", _clientId); _messageQueue.front()->send(_client); } + + _clearQueue(); } bool AsyncWebSocketClient::queueIsFull(){ @@ -553,28 +620,38 @@ bool AsyncWebSocketClient::queueIsFull(){ } void AsyncWebSocketClient::_queueMessage(AsyncWebSocketMessage *dataMessage){ - if(dataMessage == NULL) + if(dataMessage == NULL){ + // Serial.printf("%u Q1\n", _clientId); return; + } if(_status != WS_CONNECTED){ + // Serial.printf("%u Q2\n", _clientId); delete dataMessage; return; } if(_messageQueue.length() >= WS_MAX_QUEUED_MESSAGES){ ets_printf(String(F("ERROR: Too many messages queued\n")).c_str()); + // Serial.printf("%u Q3\n", _clientId); delete dataMessage; } else { _messageQueue.add(dataMessage); + // Serial.printf("%u Q A %u\n", _clientId, _messageQueue.length()); } - if(_client->canSend()) + if(_client->canSend()) { + // Serial.printf("%u Q S\n", _clientId); + // Serial.println("RUN 3"); _runQueue(); + } } void AsyncWebSocketClient::_queueControl(AsyncWebSocketControl *controlMessage){ if(controlMessage == NULL) return; _controlQueue.add(controlMessage); - if(_client->canSend()) + if(_client->canSend()) { + // Serial.println("RUN 4"); _runQueue(); + } } void AsyncWebSocketClient::close(uint16_t code, const char * message){ @@ -607,19 +684,24 @@ void AsyncWebSocketClient::ping(uint8_t *data, size_t len){ _queueControl(new AsyncWebSocketControl(WS_PING, data, len)); } -void AsyncWebSocketClient::_onError(int8_t){} +void AsyncWebSocketClient::_onError(int8_t){ + //Serial.println("onErr"); +} void AsyncWebSocketClient::_onTimeout(uint32_t time){ + // Serial.println("onTime"); (void)time; _client->close(true); } void AsyncWebSocketClient::_onDisconnect(){ + // Serial.println("onDis"); _client = NULL; _server->_handleDisconnect(this); } void AsyncWebSocketClient::_onData(void *pbuf, size_t plen){ + // Serial.println("onData"); _lastMessageTime = millis(); uint8_t *data = (uint8_t*)pbuf; while(plen > 0){ @@ -959,6 +1041,7 @@ void AsyncWebSocket::textAll(AsyncWebSocketMessageBuffer * buffer){ void AsyncWebSocket::textAll(const char * message, size_t len){ + //if (_buffers.length()) return; AsyncWebSocketMessageBuffer * WSBuffer = makeBuffer((uint8_t *)message, len); textAll(WSBuffer); } @@ -1231,6 +1314,7 @@ AsyncWebSocketMessageBuffer * AsyncWebSocket::makeBuffer(uint8_t * data, size_t if (buffer) { AsyncWebLockGuard l(_lock); + // Serial.printf("Add to global buffers = %u\n", _buffers.length() + 1); _buffers.add(buffer); } @@ -1240,9 +1324,9 @@ AsyncWebSocketMessageBuffer * AsyncWebSocket::makeBuffer(uint8_t * data, size_t void AsyncWebSocket::_cleanBuffers() { AsyncWebLockGuard l(_lock); - for(AsyncWebSocketMessageBuffer * c: _buffers){ if(c && c->canDelete()){ + // Serial.printf("Remove from global buffers = %u\n", _buffers.length() - 1); _buffers.remove(c); } } diff --git a/src/AsyncWebSocket.h b/src/AsyncWebSocket.h index f06af2cf8..5ebf1cc64 100644 --- a/src/AsyncWebSocket.h +++ b/src/AsyncWebSocket.h @@ -84,16 +84,16 @@ class AsyncWebSocketMessageBuffer { private: uint8_t * _data; size_t _len; - bool _lock; - uint32_t _count; + bool _lock; + uint32_t _count; public: AsyncWebSocketMessageBuffer(); AsyncWebSocketMessageBuffer(size_t size); - AsyncWebSocketMessageBuffer(uint8_t * data, size_t size); - AsyncWebSocketMessageBuffer(const AsyncWebSocketMessageBuffer &); - AsyncWebSocketMessageBuffer(AsyncWebSocketMessageBuffer &&); - ~AsyncWebSocketMessageBuffer(); + AsyncWebSocketMessageBuffer(uint8_t * data, size_t size); + AsyncWebSocketMessageBuffer(const AsyncWebSocketMessageBuffer &); + AsyncWebSocketMessageBuffer(AsyncWebSocketMessageBuffer &&); + ~AsyncWebSocketMessageBuffer(); void operator ++(int i) { (void)i; _count++; } void operator --(int i) { (void)i; if (_count > 0) { _count--; } ; } bool reserve(size_t size); @@ -102,9 +102,9 @@ class AsyncWebSocketMessageBuffer { uint8_t * get() { return _data; } size_t length() { return _len; } uint32_t count() { return _count; } - bool canDelete() { return (!_count && !_lock); } + bool canDelete() { return (!_count && !_lock); } - friend AsyncWebSocket; + friend AsyncWebSocket; }; @@ -145,9 +145,9 @@ class AsyncWebSocketMultiMessage: public AsyncWebSocketMessage { size_t _sent; size_t _ack; size_t _acked; - AsyncWebSocketMessageBuffer * _WSbuffer; + AsyncWebSocketMessageBuffer * _WSbuffer; public: - AsyncWebSocketMultiMessage(AsyncWebSocketMessageBuffer * buffer, uint8_t opcode=WS_TEXT, bool mask=false); + AsyncWebSocketMultiMessage(AsyncWebSocketMessageBuffer * buffer, uint8_t opcode=WS_TEXT, bool mask=false); virtual ~AsyncWebSocketMultiMessage() override; virtual bool betweenFrames() const override { return _acked == _ack; } virtual void ack(size_t len, uint32_t time) override ; @@ -173,6 +173,7 @@ class AsyncWebSocketClient { void _queueMessage(AsyncWebSocketMessage *dataMessage); void _queueControl(AsyncWebSocketControl *controlMessage); void _runQueue(); + void _clearQueue(); public: void *_tempObject; @@ -205,6 +206,7 @@ class AsyncWebSocketClient { //data packets void message(AsyncWebSocketMessage *message){ _queueMessage(message); } bool queueIsFull(); + size_t queueLen() { return _messageQueue.length() + _controlQueue.length(); } size_t printf(const char *format, ...) __attribute__ ((format (printf, 2, 3))); #ifndef ESP32 @@ -216,7 +218,7 @@ class AsyncWebSocketClient { void text(char * message); void text(const String &message); void text(const __FlashStringHelper *data); - void text(AsyncWebSocketMessageBuffer *buffer); + void text(AsyncWebSocketMessageBuffer *buffer); void binary(const char * message, size_t len); void binary(const char * message); @@ -224,7 +226,7 @@ class AsyncWebSocketClient { void binary(char * message); void binary(const String &message); void binary(const __FlashStringHelper *data, size_t len); - void binary(AsyncWebSocketMessageBuffer *buffer); + void binary(AsyncWebSocketMessageBuffer *buffer); bool canSend() { return _messageQueue.length() < WS_MAX_QUEUED_MESSAGES; } @@ -286,7 +288,7 @@ class AsyncWebSocket: public AsyncWebHandler { void textAll(char * message); void textAll(const String &message); void textAll(const __FlashStringHelper *message); // need to convert - void textAll(AsyncWebSocketMessageBuffer * buffer); + void textAll(AsyncWebSocketMessageBuffer * buffer); void binary(uint32_t id, const char * message, size_t len); void binary(uint32_t id, const char * message); @@ -301,7 +303,7 @@ class AsyncWebSocket: public AsyncWebHandler { void binaryAll(char * message); void binaryAll(const String &message); void binaryAll(const __FlashStringHelper *message, size_t len); - void binaryAll(AsyncWebSocketMessageBuffer * buffer); + void binaryAll(AsyncWebSocketMessageBuffer * buffer); void message(uint32_t id, AsyncWebSocketMessage *message); void messageAll(AsyncWebSocketMultiMessage *message); @@ -332,11 +334,11 @@ class AsyncWebSocket: public AsyncWebHandler { virtual void handleRequest(AsyncWebServerRequest *request) override final; - // messagebuffer functions/objects. - AsyncWebSocketMessageBuffer * makeBuffer(size_t size = 0); - AsyncWebSocketMessageBuffer * makeBuffer(uint8_t * data, size_t size); + // messagebuffer functions/objects. + AsyncWebSocketMessageBuffer * makeBuffer(size_t size = 0); + AsyncWebSocketMessageBuffer * makeBuffer(uint8_t * data, size_t size); LinkedList _buffers; - void _cleanBuffers(); + void _cleanBuffers(); AsyncWebSocketClientLinkedList getClients() const; }; From 1ec044ba42bf86e84ae274fc7d9850232ab52549 Mon Sep 17 00:00:00 2001 From: Dmytro Korniienko Date: Sat, 12 Sep 2020 20:01:52 +0300 Subject: [PATCH 072/551] /edit moved to FS --- .../data/{ => extras}/ace.ico.gz | Bin .../data/{ => extras}/acefull.js.gz | Bin .../data/extras/edit.htm.gz | Bin 0 -> 4509 bytes .../data/extras/mode-json.js.gz | Bin 0 -> 2983 bytes .../data/{ => extras}/worker-css.js.gz | Bin .../data/{ => extras}/worker-html.js.gz | Bin .../data/{ => extras}/worker-javascript.js.gz | Bin .../data/extras/worker-json.js.gz | Bin 0 -> 8712 bytes .../SmartSwitch/data/{ => extras}/ace.ico.gz | Bin .../data/{ => extras}/acefull.js.gz | Bin examples/SmartSwitch/data/extras/edit.htm.gz | Bin 0 -> 4509 bytes .../SmartSwitch/data/extras/mode-json.js.gz | Bin 0 -> 2983 bytes .../data/{ => extras}/worker-css.js.gz | Bin .../data/{ => extras}/worker-html.js.gz | Bin .../data/{ => extras}/worker-javascript.js.gz | Bin .../SmartSwitch/data/extras/worker-json.js.gz | Bin 0 -> 8712 bytes src/SPIFFSEditor.cpp | 75 +-- src/edit.htm | 582 +----------------- src/edit.htm.gz.h | 454 +++++++------- 19 files changed, 266 insertions(+), 845 deletions(-) rename examples/ESP_AsyncFSBrowser/data/{ => extras}/ace.ico.gz (100%) rename examples/ESP_AsyncFSBrowser/data/{ => extras}/acefull.js.gz (100%) create mode 100644 examples/ESP_AsyncFSBrowser/data/extras/edit.htm.gz create mode 100644 examples/ESP_AsyncFSBrowser/data/extras/mode-json.js.gz rename examples/ESP_AsyncFSBrowser/data/{ => extras}/worker-css.js.gz (100%) rename examples/ESP_AsyncFSBrowser/data/{ => extras}/worker-html.js.gz (100%) rename examples/ESP_AsyncFSBrowser/data/{ => extras}/worker-javascript.js.gz (100%) create mode 100644 examples/ESP_AsyncFSBrowser/data/extras/worker-json.js.gz rename examples/SmartSwitch/data/{ => extras}/ace.ico.gz (100%) rename examples/SmartSwitch/data/{ => extras}/acefull.js.gz (100%) create mode 100644 examples/SmartSwitch/data/extras/edit.htm.gz create mode 100644 examples/SmartSwitch/data/extras/mode-json.js.gz rename examples/SmartSwitch/data/{ => extras}/worker-css.js.gz (100%) rename examples/SmartSwitch/data/{ => extras}/worker-html.js.gz (100%) rename examples/SmartSwitch/data/{ => extras}/worker-javascript.js.gz (100%) create mode 100644 examples/SmartSwitch/data/extras/worker-json.js.gz diff --git a/examples/ESP_AsyncFSBrowser/data/ace.ico.gz b/examples/ESP_AsyncFSBrowser/data/extras/ace.ico.gz similarity index 100% rename from examples/ESP_AsyncFSBrowser/data/ace.ico.gz rename to examples/ESP_AsyncFSBrowser/data/extras/ace.ico.gz diff --git a/examples/ESP_AsyncFSBrowser/data/acefull.js.gz b/examples/ESP_AsyncFSBrowser/data/extras/acefull.js.gz similarity index 100% rename from examples/ESP_AsyncFSBrowser/data/acefull.js.gz rename to examples/ESP_AsyncFSBrowser/data/extras/acefull.js.gz diff --git a/examples/ESP_AsyncFSBrowser/data/extras/edit.htm.gz b/examples/ESP_AsyncFSBrowser/data/extras/edit.htm.gz new file mode 100644 index 0000000000000000000000000000000000000000..3d4fa14a97812370a5a6b55d7ddad8b582ea444c GIT binary patch literal 4509 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 literal 0 HcmV?d00001 diff --git a/examples/ESP_AsyncFSBrowser/data/extras/mode-json.js.gz b/examples/ESP_AsyncFSBrowser/data/extras/mode-json.js.gz new file mode 100644 index 0000000000000000000000000000000000000000..a13781b95dc2cf63ba25697c8ca7724952155b07 GIT binary patch literal 2983 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 literal 0 HcmV?d00001 diff --git a/examples/ESP_AsyncFSBrowser/data/worker-css.js.gz b/examples/ESP_AsyncFSBrowser/data/extras/worker-css.js.gz similarity index 100% rename from examples/ESP_AsyncFSBrowser/data/worker-css.js.gz rename to examples/ESP_AsyncFSBrowser/data/extras/worker-css.js.gz diff --git a/examples/ESP_AsyncFSBrowser/data/worker-html.js.gz b/examples/ESP_AsyncFSBrowser/data/extras/worker-html.js.gz similarity index 100% rename from examples/ESP_AsyncFSBrowser/data/worker-html.js.gz rename to examples/ESP_AsyncFSBrowser/data/extras/worker-html.js.gz diff --git a/examples/ESP_AsyncFSBrowser/data/worker-javascript.js.gz b/examples/ESP_AsyncFSBrowser/data/extras/worker-javascript.js.gz similarity index 100% rename from examples/ESP_AsyncFSBrowser/data/worker-javascript.js.gz rename to examples/ESP_AsyncFSBrowser/data/extras/worker-javascript.js.gz diff --git a/examples/ESP_AsyncFSBrowser/data/extras/worker-json.js.gz b/examples/ESP_AsyncFSBrowser/data/extras/worker-json.js.gz new file mode 100644 index 0000000000000000000000000000000000000000..50719211195dba380260a94e1de2ecb4108be34e GIT binary patch literal 8712 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 literal 0 HcmV?d00001 diff --git a/examples/SmartSwitch/data/ace.ico.gz b/examples/SmartSwitch/data/extras/ace.ico.gz similarity index 100% rename from examples/SmartSwitch/data/ace.ico.gz rename to examples/SmartSwitch/data/extras/ace.ico.gz diff --git a/examples/SmartSwitch/data/acefull.js.gz b/examples/SmartSwitch/data/extras/acefull.js.gz similarity index 100% rename from examples/SmartSwitch/data/acefull.js.gz rename to examples/SmartSwitch/data/extras/acefull.js.gz diff --git a/examples/SmartSwitch/data/extras/edit.htm.gz b/examples/SmartSwitch/data/extras/edit.htm.gz new file mode 100644 index 0000000000000000000000000000000000000000..3d4fa14a97812370a5a6b55d7ddad8b582ea444c GIT binary patch literal 4509 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 literal 0 HcmV?d00001 diff --git a/examples/SmartSwitch/data/extras/mode-json.js.gz b/examples/SmartSwitch/data/extras/mode-json.js.gz new file mode 100644 index 0000000000000000000000000000000000000000..a13781b95dc2cf63ba25697c8ca7724952155b07 GIT binary patch literal 2983 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 literal 0 HcmV?d00001 diff --git a/examples/SmartSwitch/data/worker-css.js.gz b/examples/SmartSwitch/data/extras/worker-css.js.gz similarity index 100% rename from examples/SmartSwitch/data/worker-css.js.gz rename to examples/SmartSwitch/data/extras/worker-css.js.gz diff --git a/examples/SmartSwitch/data/worker-html.js.gz b/examples/SmartSwitch/data/extras/worker-html.js.gz similarity index 100% rename from examples/SmartSwitch/data/worker-html.js.gz rename to examples/SmartSwitch/data/extras/worker-html.js.gz diff --git a/examples/SmartSwitch/data/worker-javascript.js.gz b/examples/SmartSwitch/data/extras/worker-javascript.js.gz similarity index 100% rename from examples/SmartSwitch/data/worker-javascript.js.gz rename to examples/SmartSwitch/data/extras/worker-javascript.js.gz diff --git a/examples/SmartSwitch/data/extras/worker-json.js.gz b/examples/SmartSwitch/data/extras/worker-json.js.gz new file mode 100644 index 0000000000000000000000000000000000000000..50719211195dba380260a94e1de2ecb4108be34e GIT binary patch literal 8712 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 literal 0 HcmV?d00001 diff --git a/src/SPIFFSEditor.cpp b/src/SPIFFSEditor.cpp index e7a592e9e..36f2ee7f7 100644 --- a/src/SPIFFSEditor.cpp +++ b/src/SPIFFSEditor.cpp @@ -1,14 +1,14 @@ #include "SPIFFSEditor.h" #include -#include "edit.htm.gz.h" +//#include "edit.htm.gz.h" // moved to FS #ifdef ESP32 #define fullName(x) name(x) #endif #define SPIFFS_MAXLENGTH_FILEPATH 32 -const char *excludeListFile = "/.exclude.files"; +static const char excludeListFile[] PROGMEM = "/.exclude.files"; typedef struct ExcludeListS { char *item; @@ -103,7 +103,7 @@ static void loadExcludeList(fs::FS &_fs, const char *filename){ static bool isExcluded(fs::FS &_fs, const char *filename) { if(excludes == NULL){ - loadExcludeList(_fs, excludeListFile); + loadExcludeList(_fs, String(FPSTR(excludeListFile)).c_str()); } ExcludeList *e = excludes; while(e){ @@ -130,12 +130,12 @@ SPIFFSEditor::SPIFFSEditor(const String& username, const String& password, const {} bool SPIFFSEditor::canHandle(AsyncWebServerRequest *request){ - if(request->url().equalsIgnoreCase("/edit")){ + if(request->url().equalsIgnoreCase(F("/edit"))){ if(request->method() == HTTP_GET){ - if(request->hasParam("list")) + if(request->hasParam(F("list"))) return true; - if(request->hasParam("edit")){ - request->_tempFile = _fs.open(request->arg("edit"), "r"); + if(request->hasParam(F("edit"))){ + request->_tempFile = _fs.open(request->arg(F("edit")), "r"); if(!request->_tempFile){ return false; } @@ -147,7 +147,7 @@ bool SPIFFSEditor::canHandle(AsyncWebServerRequest *request){ #endif } if(request->hasParam("download")){ - request->_tempFile = _fs.open(request->arg("download"), "r"); + request->_tempFile = _fs.open(request->arg(F("download")), "r"); if(!request->_tempFile){ return false; } @@ -158,7 +158,7 @@ bool SPIFFSEditor::canHandle(AsyncWebServerRequest *request){ } #endif } - request->addInterestingHeader("If-Modified-Since"); + request->addInterestingHeader(F("If-Modified-Since")); return true; } else if(request->method() == HTTP_POST) @@ -178,8 +178,8 @@ void SPIFFSEditor::handleRequest(AsyncWebServerRequest *request){ return request->requestAuthentication(); if(request->method() == HTTP_GET){ - if(request->hasParam("list")){ - String path = request->getParam("list")->value(); + if(request->hasParam(F("list"))){ + String path = request->getParam(F("list"))->value(); #ifdef ESP32 File dir = _fs.open(path); #else @@ -204,11 +204,11 @@ void SPIFFSEditor::handleRequest(AsyncWebServerRequest *request){ continue; } if (output != "[") output += ','; - output += "{\"type\":\""; - output += "file"; - output += "\",\"name\":\""; + output += F("{\"type\":\""); + output += F("file"); + output += F("\",\"name\":\""); output += String(fname); - output += "\",\"size\":"; + output += F("\",\"size\":"); output += String(entry.size()); output += "}"; #ifdef ESP32 @@ -221,41 +221,42 @@ void SPIFFSEditor::handleRequest(AsyncWebServerRequest *request){ dir.close(); #endif output += "]"; - request->send(200, "application/json", output); + request->send(200, F("application/json"), output); output = String(); } - else if(request->hasParam("edit") || request->hasParam("download")){ - request->send(request->_tempFile, request->_tempFile.fullName(), String(), request->hasParam("download")); + else if(request->hasParam(F("edit")) || request->hasParam(F("download"))){ + request->send(request->_tempFile, request->_tempFile.fullName(), String(), request->hasParam(F("download"))); } else { const char * buildTime = __DATE__ " " __TIME__ " GMT"; - if (request->header("If-Modified-Since").equals(buildTime)) { + if (request->header(F("If-Modified-Since")).equals(buildTime)) { request->send(304); } else { - AsyncWebServerResponse *response = request->beginResponse_P(200, "text/html", edit_htm_gz, edit_htm_gz_len); - response->addHeader("Content-Encoding", "gzip"); - response->addHeader("Last-Modified", buildTime); - request->send(response); + request->send(_fs, F("/extras/edit.htm"), String(F("text/html")), false); + // AsyncWebServerResponse *response = request->beginResponse_P(200, "text/html", edit_htm_gz, edit_htm_gz_len); + // response->addHeader("Content-Encoding", "gzip"); + // response->addHeader("Last-Modified", buildTime); + // request->send(response); } } } else if(request->method() == HTTP_DELETE){ - if(request->hasParam("path", true)){ + if(request->hasParam(F("path"), true)){ - if(!(_fs.remove(request->getParam("path", true)->value()))){ + if(!(_fs.remove(request->getParam(F("path"), true)->value()))){ #ifdef ESP32 - _fs.rmdir(request->getParam("path", true)->value()); // try rmdir for littlefs + _fs.rmdir(request->getParam(F("path"), true)->value()); // try rmdir for littlefs #endif } - request->send(200, "", "DELETE: "+request->getParam("path", true)->value()); + request->send(200, "", String(F("DELETE: "))+request->getParam(F("path"), true)->value()); } else request->send(404); } else if(request->method() == HTTP_POST){ - if(request->hasParam("data", true, true) && _fs.exists(request->getParam("data", true, true)->value())) - request->send(200, "", "UPLOADED: "+request->getParam("data", true, true)->value()); + if(request->hasParam(F("data"), true, true) && _fs.exists(request->getParam(F("data"), true, true)->value())) + request->send(200, "", String(F("UPLOADED: "))+request->getParam(F("data"), true, true)->value()); - else if(request->hasParam("rawname", true) && request->hasParam("raw0", true)){ - String rawnam = request->getParam("rawname", true)->value(); + else if(request->hasParam(F("rawname"), true) && request->hasParam(F("raw0"), true)){ + String rawnam = request->getParam(F("rawname"), true)->value(); if (_fs.exists(rawnam)) _fs.remove(rawnam); // delete it to allow a mode @@ -263,22 +264,22 @@ void SPIFFSEditor::handleRequest(AsyncWebServerRequest *request){ uint16_t i = 0; fs::File f = _fs.open(rawnam, "a"); - while (request->hasParam("raw" + String(k), true)) { //raw0 .. raw1 + while (request->hasParam(String(F("raw")) + String(k), true)) { //raw0 .. raw1 if(f){ - i += f.print(request->getParam("raw" + String(k), true)->value()); + i += f.print(request->getParam(String(F("raw")) + String(k), true)->value()); } k++; } f.close(); - request->send(200, "", "IPADWRITE: " + rawnam + ":" + String(i)); + request->send(200, "", String(F("IPADWRITE: ")) + rawnam + ":" + String(i)); } else { request->send(500); } } else if(request->method() == HTTP_PUT){ - if(request->hasParam("path", true)){ - String filename = request->getParam("path", true)->value(); + if(request->hasParam(F("path"), true)){ + String filename = request->getParam(F("path"), true)->value(); if(_fs.exists(filename)){ request->send(200); } else { @@ -306,7 +307,7 @@ void SPIFFSEditor::handleRequest(AsyncWebServerRequest *request){ if(f){ f.write((uint8_t)0x00); f.close(); - request->send(200, "", "CREATE: "+filename); + request->send(200, "", String(F("CREATE: "))+filename); } else { request->send(500); } diff --git a/src/edit.htm b/src/edit.htm index 4943b8ba1..e3eeac354 100644 --- a/src/edit.htm +++ b/src/edit.htm @@ -1,581 +1 @@ - - - - - ESP Editor - - - - - - - - - - -

-
-
-
- - - - - \ No newline at end of file +ESP Editor
\ No newline at end of file diff --git a/src/edit.htm.gz.h b/src/edit.htm.gz.h index 3b163a0fc..49ab77ab4 100644 --- a/src/edit.htm.gz.h +++ b/src/edit.htm.gz.h @@ -1,231 +1,231 @@ -//File: edit.htm.gz, Size: 4503 -#define edit_htm_gz_len 4503 +//File: edit.htm.gz, Size: 4509 +#define edit_htm_gz_len 4509 const uint8_t edit_htm_gz[] PROGMEM = { -0x1F,0x8B,0x08,0x08,0x54,0x90,0x4A,0x5F,0x02,0x00,0x65,0x64,0x69,0x74,0x2E,0x68,0x74,0x6D,0x00,0xB5, -0x1A,0x0B,0x5B,0xDB,0x36,0xF0,0xAF,0x18,0x6F,0x63,0xF6,0xE2,0x38,0x0E,0x50,0xD6,0x3A,0x18,0x16,0x1E, +0x1F,0x8B,0x08,0x08,0x76,0xDF,0x5C,0x5F,0x02,0x00,0x65,0x64,0x69,0x74,0x2E,0x68,0x74,0x6D,0x00,0xB5, +0x1A,0x0B,0x5B,0xDB,0x36,0xF0,0xAF,0x18,0x6F,0x63,0xF6,0xE2,0x38,0x0E,0x50,0xD6,0x39,0x18,0x16,0x1E, 0xEB,0xBB,0x50,0x12,0xDA,0xD1,0x8E,0xED,0x53,0x6C,0x25,0x56,0xB1,0x25,0xCF,0x96,0x09,0x34,0xCD,0x7F, -0xDF,0x49,0xF2,0x93,0x84,0xEE,0xF1,0x6D,0xA5,0x60,0x49,0xA7,0x3B,0xDD,0x9D,0xEE,0x25,0xD9,0x7B,0x1B, -0xC7,0xA7,0x47,0xE3,0xCB,0xB3,0x13,0x2D,0xE4,0x71,0xB4,0xBF,0x27,0xFE,0x6A,0x11,0xA2,0x33,0x4F,0xC7, -0x54,0xDF,0xDF,0x8B,0x31,0x47,0x00,0xE2,0x49,0x17,0xFF,0x91,0x93,0x1B,0x4F,0x3F,0x62,0x94,0x63,0xCA, -0xBB,0xFC,0x2E,0xC1,0xBA,0xE6,0xAB,0x9E,0xA7,0x73,0x7C,0xCB,0x7B,0x02,0x79,0xA0,0xF9,0x21,0x4A,0x33, -0xCC,0xBD,0x9C,0x4F,0xBB,0x8F,0x81,0x04,0x27,0x3C,0xC2,0xFB,0x27,0xA3,0x33,0xED,0x24,0x20,0x9C,0xA5, -0x7B,0x3D,0x35,0xB2,0x17,0x11,0x7A,0xAD,0xA5,0x38,0xF2,0x74,0x94,0x24,0x11,0xEE,0x72,0x96,0xFB,0x61, -0x97,0x00,0x4D,0x5D,0x0B,0x53,0x3C,0xF5,0xF4,0x1E,0xF2,0xB1,0x0D,0x03,0xBA,0x26,0x96,0xF3,0x74,0x12, -0xA3,0x19,0xEE,0xDD,0xAA,0x39,0x4D,0x02,0x59,0xC8,0x52,0xEE,0xE7,0x5C,0xFB,0x57,0xD8,0xFF,0x00,0x29, -0xE3,0x77,0x11,0x56,0x20,0x25,0xB3,0x9F,0x65,0xBA,0x16,0xE3,0x80,0x20,0xE0,0xC2,0x4F,0xB1,0xD0,0x5A, -0x84,0x26,0x38,0x5A,0x4C,0x19,0xA8,0x29,0x23,0x9F,0xB1,0xDB,0xDF,0x4A,0x6E,0x07,0xB2,0x3B,0x45,0x31, -0x89,0xEE,0xDC,0x0C,0xD1,0xAC,0x9B,0xE1,0x94,0x4C,0x97,0xB6,0x1F,0x2F,0x3E,0x77,0x09,0x0D,0xF0,0xAD, -0xBB,0xED,0x38,0x83,0x84,0x65,0x84,0x13,0x46,0x5D,0x34,0xC9,0x58,0x94,0x73,0x3C,0x88,0xF0,0x94,0xBB, -0x8F,0x80,0xC2,0x84,0xA5,0x01,0x4E,0xDD,0x7E,0x72,0xAB,0x01,0x88,0x04,0xDA,0x37,0x3B,0x3B,0x3B,0x83, -0x09,0xF2,0xAF,0x67,0x29,0xCB,0x69,0xD0,0xF5,0x59,0xC4,0x52,0xF7,0x9B,0xE9,0x23,0xF1,0x33,0x08,0x48, -0x96,0x44,0xE8,0xCE,0xA5,0x8C,0x62,0xC0,0xBD,0xED,0x66,0x21,0x0A,0xD8,0xDC,0x75,0x34,0x47,0xEB,0x3B, -0x40,0x24,0x9D,0x4D,0x90,0xE1,0x58,0xE2,0xC7,0xDE,0x31,0x07,0x7F,0x8B,0x5F,0x35,0x3C,0xC7,0x64,0x16, -0x72,0xF7,0x47,0xC7,0x11,0xFC,0x6B,0x79,0xB4,0x88,0x48,0xC6,0xBB,0x52,0x39,0x6A,0x3D,0xCE,0x12,0xD7, -0x91,0xAC,0xC3,0x23,0x46,0xE9,0x8C,0x50,0x68,0x24,0x28,0x08,0x08,0x9D,0xB9,0x0A,0x2D,0x22,0x8B,0x4A, -0x5A,0xD8,0x07,0xC4,0xC9,0x0D,0x1E,0xC4,0x84,0x76,0xE7,0x24,0xE0,0xA1,0xBB,0xEB,0x00,0x17,0x7E,0x9E, -0x66,0x20,0x53,0xC2,0x08,0xE5,0x38,0x95,0x68,0x59,0x82,0xE8,0x42,0x89,0x2A,0x14,0x50,0xC9,0x49,0x28, -0xEC,0x28,0xEE,0x4E,0x22,0xE6,0x5F,0x57,0x2B,0xED,0x26,0xB7,0xC5,0x5A,0x6E,0xC8,0x6E,0x70,0xBA,0xA8, -0xD5,0x25,0xB1,0x5B,0xC0,0x16,0x69,0x8C,0xF1,0xD2,0xE6,0x37,0x39,0x40,0x2D,0xF9,0x04,0x29,0x0B,0xAA, -0x4D,0x91,0xDA,0x82,0x17,0x28,0x84,0x26,0x39,0x5F,0xAC,0x6E,0x25,0x4B,0x90,0x4F,0xF8,0x9D,0xEB,0xC8, -0x69,0xD2,0x42,0xDC,0x1D,0xC7,0xD1,0x84,0xC2,0xB5,0x77,0x38,0x0D,0x10,0x45,0xD6,0x30,0x25,0x28,0xB2, -0x46,0xB5,0xCA,0xBB,0x31,0xFB,0xDC,0xCD,0xA1,0x0D,0xFD,0x08,0xFB,0x5C,0x69,0x18,0x36,0x61,0x72,0x4D, -0xF8,0x2A,0x60,0x65,0xA0,0xA1,0x2B,0xA9,0xA1,0x50,0xED,0x5E,0x1F,0x74,0x23,0xF9,0x50,0x62,0x2B,0x89, -0xBA,0x13,0xC6,0x39,0x8B,0xA5,0xBD,0x55,0xD2,0x6A,0xD2,0x64,0x1E,0xAF,0x6C,0xC7,0x7A,0xD5,0x37,0xC8, -0x0F,0x40,0xA9,0x9C,0xF8,0x28,0xEA,0xA2,0x88,0xCC,0xA8,0x1B,0x93,0x20,0x88,0x70,0xC3,0x64,0xDD,0x3C, -0x8D,0x8C,0x00,0x71,0xE4,0x2A,0x3F,0x4B,0xE8,0x0C,0xA0,0x19,0xDE,0xDD,0xB1,0xC8,0xBB,0xC3,0xD3,0xF3, -0xB9,0xF3,0xF2,0xE9,0x8C,0x0D,0xE1,0xDF,0x9B,0xD1,0x45,0x78,0x72,0x31,0x83,0xD6,0xA1,0xE8,0x0E,0xDF, -0x1E,0x0D,0xDF,0xC2,0xE3,0xA8,0xDF,0xF9,0x34,0xFD,0x63,0x28,0x86,0x9F,0x06,0x87,0xE3,0x8B,0x93,0xE1, -0xF0,0x65,0xEF,0xF9,0x9B,0xF9,0xFB,0x97,0xBB,0x02,0x7C,0x18,0x39,0xE7,0xEF,0x42,0xE7,0x62,0xEB,0x49, -0x1C,0x3C,0x0B,0x42,0x3F,0xBE,0x18,0xBE,0x7D,0x7F,0x7E,0x73,0x19,0x5F,0xCC,0x46,0xEF,0xFB,0xE1,0x87, -0xAD,0x77,0xA3,0x0F,0xEF,0x7F,0xBE,0xC6,0xBF,0x3C,0x7B,0xF1,0x61,0x3C,0x07,0x84,0x63,0x36,0xBA,0x38, -0x3F,0x7C,0x77,0x38,0xFB,0x70,0xE8,0x9F,0xDC,0x4E,0xA2,0x37,0x87,0x4F,0x87,0x93,0xE1,0x96,0x8F,0xF1, -0x6C,0x7C,0x7E,0x98,0x3F,0x7F,0x79,0x3A,0x23,0x24,0x1C,0x7D,0x78,0x33,0xF6,0x8F,0x1E,0xBD,0xBA,0x78, -0x36,0x24,0xE1,0x9B,0x17,0xE7,0xCE,0xF5,0xD3,0x97,0x47,0xC7,0xFE,0xE5,0x8B,0xCB,0xDD,0xE3,0xED,0xDE, -0x8F,0x3F,0xBE,0x0E,0x4E,0x09,0x1D,0xDF,0x7C,0x1E,0xCE,0x8E,0xE6,0x8F,0xEF,0xB2,0x71,0xF8,0xFC,0x86, -0xF6,0xDE,0xB1,0x4F,0xCF,0xEF,0x5E,0xC3,0xEF,0xD9,0x59,0x67,0x32,0xEA,0x67,0x17,0x6F,0x9F,0xBF,0xDB, -0xCA,0x9E,0x3C,0x4A,0x0E,0x8F,0x8F,0x6F,0xE2,0xC9,0x59,0x2F,0x0E,0xAE,0xA7,0xFC,0xF1,0x36,0x4F,0x2E, -0x67,0xF9,0x87,0x3F,0x1E,0xBD,0x08,0x7B,0xA7,0x18,0x5D,0x86,0x9D,0xBB,0xCF,0x77,0x8F,0xC3,0xF1,0xB3, -0x9B,0x37,0x11,0xBA,0x7D,0xF3,0xC6,0xFF,0x1C,0x77,0x22,0xF4,0xE4,0x74,0x1C,0xA1,0xB4,0x7F,0x11,0x0C, -0x7B,0x9D,0xA3,0xAD,0xE1,0x0E,0x4F,0xCF,0x8F,0xE8,0xF1,0xF6,0xA7,0xD1,0xE3,0xC3,0xC3,0x3E,0x9B,0xFC, -0xB1,0xF5,0xF4,0x7A,0xF7,0xE9,0xC5,0xEE,0xDB,0xC9,0xDB,0xE1,0x68,0xE7,0xF0,0x02,0x5D,0x8E,0xDE,0x0E, -0xA7,0x3B,0x93,0x30,0x7C,0xF9,0x72,0xFC,0x73,0x30,0xFC,0x9C,0x0E,0x4F,0xE7,0xC3,0xDB,0x93,0x8B,0xE1, -0xB3,0xCE,0xCB,0x93,0xD7,0x4E,0x7F,0x74,0xB9,0x3D,0x7B,0xBD,0x3B,0x3F,0xCC,0x4E,0x86,0x6F,0x0F,0x9D, -0xD9,0x8B,0x4E,0x8C,0x3E,0xB0,0xA3,0xED,0xD9,0xF3,0x5D,0x72,0x76,0x89,0x86,0xCF,0x0F,0x5F,0x64,0xE4, -0x3C,0x7E,0x76,0xE1,0x0C,0x87,0xAF,0x4E,0xF1,0xCF,0x47,0xDB,0xE8,0xE5,0x96,0xFF,0x1E,0xF4,0x7F,0xF1, -0x0B,0xFE,0xB1,0x33,0x9C,0x9F,0x3A,0x91,0xFF,0x04,0x8F,0x9F,0x5D,0x8E,0xE5,0xEE,0x9C,0x44,0x3F,0x8F, -0xAF,0x47,0xF9,0xDB,0xF8,0xE8,0xC8,0xD4,0x28,0xEB,0xA6,0x38,0xC1,0x88,0x37,0x63,0x55,0xE5,0x1C,0x60, -0x5B,0xB5,0x15,0x16,0x4E,0x2A,0x22,0x6B,0x37,0xC0,0x3E,0x4B,0x91,0x9C,0x03,0x08,0x38,0x15,0x26,0xB6, -0xFC,0x49,0x86,0x5A,0x4D,0x45,0x5A,0x0D,0xD1,0x40,0x33,0x4A,0x47,0x88,0x09,0x05,0x9C,0x1B,0xE2,0xE3, -0x6E,0x42,0x6E,0x71,0xD4,0x95,0xC8,0xAE,0x63,0x2E,0xA4,0xB3,0x95,0xD3,0x10,0x25,0xB1,0xA2,0x5A,0x0E, -0x04,0x9F,0x90,0x2F,0x52,0x1A,0xB8,0x4C,0x0C,0xCF,0xC2,0x77,0x58,0xDA,0x9D,0xE4,0xB3,0x29,0xB9,0x05, -0x6F,0x9E,0x12,0x4A,0x38,0xD6,0xFA,0xD9,0xF2,0xA7,0x92,0xCC,0x35,0xBE,0x9B,0xA6,0x28,0xC6,0x99,0xF6, -0x37,0xC9,0x2C,0xA6,0x29,0x8B,0x17,0x75,0x04,0xE4,0xAC,0xD1,0x59,0x2E,0xBF,0xC9,0x93,0x88,0x21,0x10, -0x73,0x25,0x6C,0x94,0xC1,0x34,0x15,0x6E,0x55,0x05,0xD5,0xD2,0xCD,0xB6,0xC0,0x2D,0x5B,0x6E,0xBD,0xB5, -0x53,0xBB,0x6E,0x57,0xCE,0x15,0xC1,0xBE,0xA9,0xFA,0x46,0x3C,0x68,0xC4,0xBA,0x6F,0x38,0xA8,0x74,0xFD, -0xE2,0x6A,0x11,0x15,0x19,0x6A,0x06,0x54,0x94,0xEE,0xEF,0x3A,0x8D,0x50,0x01,0xF3,0x96,0xDF,0x60,0x99, -0xE6,0xAD,0x6F,0x92,0x14,0x76,0x03,0xCF,0xBF,0x42,0xB3,0x92,0xA9,0x4D,0x1B,0x68,0x56,0xE9,0x4E,0x89, -0x50,0xE7,0x3C,0xC9,0x6B,0x45,0x7A,0x55,0x2A,0x00,0x57,0xDC,0x3C,0x12,0xDC,0x7C,0x55,0xAB,0xDB,0xBB, -0xDF,0x15,0x3C,0xEC,0x38,0xDF,0x2D,0x6D,0x35,0xB7,0xCA,0xC7,0x7D,0x07,0xFE,0x95,0x69,0xF7,0x71,0xCD, -0xC2,0xE4,0x91,0xF8,0x29,0x19,0x04,0x3A,0x4D,0xE0,0xF6,0xCE,0x93,0xC7,0xC1,0xA4,0x04,0x2A,0xC1,0x1E, -0x86,0xA7,0x28,0x20,0x79,0xE6,0x3E,0x72,0xBE,0x53,0xFA,0x84,0xED,0x03,0xD9,0xCB,0xCD,0x55,0x9D,0xDA, -0x62,0xB3,0x84,0x50,0x6D,0x2B,0xD3,0xC4,0x7E,0xA3,0xB4,0x32,0xCC,0x66,0xAA,0x07,0x17,0xA9,0x4D,0x53, -0xCC,0x5F,0x38,0xDF,0x2D,0x78,0x8A,0x68,0x36,0x65,0x69,0xEC,0xA6,0x8C,0x23,0x8E,0x0D,0xC7,0x5C,0xF6, -0x9D,0x75,0x80,0xED,0x5D,0x27,0xC0,0x33,0x73,0xB9,0xDC,0xEB,0xC9,0xA4,0x06,0x15,0x8F,0x9F,0x92,0x84, -0xEF,0x4F,0x73,0xEA,0x0B,0x1E,0xB4,0x19,0x36,0xB0,0xB9,0x48,0x31,0xCF,0x53,0xAA,0x05,0xCC,0xCF,0x85, -0xB1,0xDB,0x33,0xCC,0x4F,0x94,0xDD,0x1F,0xDE,0x3D,0x0F,0x60,0xC6,0xB2,0x42,0xF0,0xD7,0x22,0x80,0x03, -0xC3,0x7A,0x05,0x4E,0x6B,0x3E,0x24,0x18,0x20,0xF2,0x12,0xDF,0x19,0xD8,0xE2,0x15,0x22,0xB6,0xC5,0xB8, -0x61,0x94,0xD3,0x00,0x48,0xCD,0xC5,0x0D,0x68,0x01,0x79,0xF8,0x23,0xBF,0xB2,0x88,0x47,0xE1,0x31,0x28, -0xA6,0x93,0x7D,0x74,0xD0,0xED,0xBB,0x68,0x9F,0x1C,0xF4,0xC1,0xBF,0xCC,0x06,0x7D,0xB5,0xF2,0xCF,0x24, -0xC2,0x17,0x85,0xCB,0x89,0x85,0x6A,0x6A,0x3D,0x83,0x9C,0x85,0xA0,0x48,0xF3,0x07,0xE3,0x74,0xA4,0x19, -0x1F,0x7F,0xEC,0x3E,0xB9,0xFA,0xD2,0xFF,0xE8,0x74,0xFB,0x57,0xE6,0xEF,0x66,0x8F,0xD8,0x1C,0x67,0xDC, -0xA0,0xE8,0x86,0xCC,0x10,0xD8,0xB9,0x2D,0xF2,0xED,0x70,0x06,0x52,0x98,0x83,0x6A,0x0D,0xA2,0xD8,0xDB, -0x72,0x9C,0x0D,0x0F,0x1F,0xA0,0x08,0x03,0xEB,0xFA,0xC9,0xF9,0xF9,0xE9,0xF9,0x47,0xBD,0x83,0x3B,0xFA, -0x95,0xAB,0xE9,0x1D,0x6A,0xBA,0xDC,0x86,0xA2,0x33,0xC5,0x59,0x78,0x86,0x78,0x68,0x04,0xF6,0x0D,0x8A, -0x72,0xD0,0x85,0x60,0x84,0x79,0xA0,0x38,0x7D,0x92,0x73,0xCE,0xA8,0x6E,0x0E,0x98,0x4D,0x28,0xC5,0xE9, -0xB3,0xF1,0xEB,0x57,0x9E,0x7E,0xCE,0x18,0xD7,0x8E,0x49,0xAA,0x5B,0x72,0x37,0x6C,0x94,0x24,0x98,0x06, -0x47,0x21,0x89,0x02,0x83,0x99,0x03,0x81,0xEE,0x4B,0x74,0x59,0x88,0x00,0xB6,0x6F,0xAB,0x92,0x75,0x0A, -0x52,0xEB,0x96,0x6F,0xC7,0x79,0xC4,0x49,0x12,0x61,0x6F,0xA3,0x0F,0x3D,0x8A,0x62,0x80,0x89,0x34,0x2C, -0x60,0x24,0xF0,0x74,0x15,0x8C,0x8A,0x10,0xB6,0x6E,0x15,0x5F,0xAD,0x12,0xB4,0x56,0x09,0x9A,0xB8,0x09, -0x48,0xA4,0x5B,0x81,0x5D,0xD7,0xCA,0xD0,0x2B,0x96,0x2A,0x61,0x01,0x9E,0x22,0xE0,0xE4,0x9D,0x90,0x1A, -0x4A,0xEF,0x75,0x0B,0x05,0x6A,0xA1,0xAC,0xAD,0x8D,0xAC,0xA9,0x0D,0xB5,0x8D,0xEB,0x90,0x33,0x85,0x9C, -0xB6,0x91,0xD3,0x26,0xF2,0x91,0xB4,0x86,0x75,0xC8,0xA9,0x42,0x8E,0x5A,0x22,0x46,0x52,0x44,0x15,0xE1, -0xBA,0x42,0x9B,0x20,0x10,0x60,0x47,0x4D,0x31,0xA1,0x07,0x0E,0x89,0x26,0x11,0x0E,0xBC,0x0D,0x07,0x7A, -0xA2,0xA8,0xF6,0xB6,0x9C,0x35,0x6B,0x44,0x6A,0x8D,0xBC,0xB5,0x46,0x2E,0xD7,0x20,0x09,0x28,0x11,0xF2, -0x86,0x6E,0xE5,0x52,0x6B,0xED,0x11,0xB5,0x9C,0x1F,0x62,0xFF,0x7A,0xC2,0xE4,0x88,0x6C,0x8B,0x15,0x37, -0x90,0xA4,0x99,0x48,0x9A,0xF2,0x28,0x02,0x34,0x13,0x1B,0xBC,0xDC,0x13,0x94,0xAD,0xA4,0x29,0xBE,0x36, -0x8C,0xB8,0xAD,0x4B,0x84,0xB8,0xAD,0xA5,0xB8,0x35,0x6D,0x84,0x6E,0xB0,0xB6,0x4E,0x4B,0xB1,0xB9,0x66, -0x30,0x59,0x37,0x98,0x9B,0x56,0x6A,0x33,0xEA,0x47,0xC4,0xBF,0xF6,0x6A,0x37,0x36,0x17,0x46,0xB3,0x23, -0x38,0xE1,0x1E,0xC5,0x73,0xED,0x67,0x08,0x4B,0xC7,0x88,0xA3,0x01,0x2F,0xC8,0x18,0x85,0xDD,0x60,0x20, -0x04,0xA7,0x51,0xF0,0xC2,0xCC,0x46,0x01,0x0C,0x9F,0x5D,0x8C,0x75,0x4B,0xEF,0x89,0x5D,0xD1,0xC1,0x93, -0x89,0xB9,0x34,0x2B,0x5F,0xB2,0xA8,0x8C,0xEA,0x17,0x69,0x54,0x0F,0x41,0xA3,0xB4,0xB8,0xA5,0x15,0xAF, -0xE5,0x89,0x4C,0x8D,0x4A,0xA5,0x25,0x53,0xE2,0x64,0x28,0xD6,0x30,0x8A,0xFD,0xD7,0x4D,0x08,0x7B,0xCA, -0x78,0x0D,0xD3,0x42,0x6D,0xA6,0x51,0xC5,0x74,0x8A,0xE6,0xA5,0x91,0xA8,0xF5,0x07,0xCA,0xBD,0x1D,0xC8, -0xBE,0x34,0xE3,0x1A,0xF6,0x76,0x9C,0x27,0xBB,0x03,0xD8,0x1F,0x43,0x39,0x2E,0x00,0xF6,0xB8,0x0D,0xA6, -0x35,0xE3,0xE1,0xC0,0xEF,0x78,0x85,0x56,0x02,0x8F,0xDB,0x59,0x3E,0xC9,0x78,0x0A,0xB9,0xCD,0xF0,0x2D, -0xBF,0x83,0xCD,0xF6,0x32,0x7A,0x87,0x59,0x81,0x69,0xB1,0x4E,0x67,0x79,0x4F,0x41,0xA7,0xA3,0x86,0x86, -0x90,0xD0,0x10,0x8E,0x32,0xAC,0x51,0x1B,0xDF,0x62,0xFF,0x88,0xC5,0x31,0x12,0x24,0x32,0xD8,0xE4,0xA2, -0xA3,0x9B,0x4B,0x8B,0xAD,0xD5,0xCC,0x03,0x21,0xCB,0xCA,0x1E,0xD2,0x23,0x84,0x40,0xCF,0xB7,0x85,0xAF, -0x64,0x85,0x50,0x5F,0xDF,0xE5,0x32,0x10,0x29,0x94,0x8F,0xCE,0x95,0x55,0x6D,0xDC,0x8A,0x54,0xED,0x7D, -0x97,0x56,0xD7,0x8A,0x3F,0x66,0xBD,0xD3,0x02,0xD6,0x8E,0x6B,0x35,0x54,0x5F,0x2E,0x2D,0x5F,0xF0,0x1F, -0x22,0x3A,0xC3,0x7F,0x5F,0x80,0x9A,0x47,0xE9,0xA2,0x16,0x85,0xE4,0x71,0xE0,0xFE,0x6A,0x1B,0x1F,0x7F, -0xB3,0xAF,0x3A,0xA6,0x79,0xF0,0x6D,0x4F,0x6A,0xD8,0xE0,0xE6,0xC7,0xFE,0x95,0x85,0x00,0x6C,0xFF,0x60, -0xFE,0x6A,0x4B,0x70,0x0B,0x36,0xB8,0x61,0x24,0xD0,0xC4,0x4A,0xC2,0xB3,0xD9,0x54,0x43,0x9B,0x9B,0x06, -0x98,0x5C,0xCB,0x58,0x3B,0xBC,0xA3,0xDB,0x90,0x37,0x96,0xCB,0xFB,0xD9,0x6C,0x9C,0x62,0xAC,0xD2,0x65, -0x05,0x90,0xDC,0x83,0xCC,0x2B,0xC1,0xAA,0x94,0x1A,0x5B,0x35,0x14,0x06,0x65,0xBA,0xB7,0x8B,0x4A,0xC2, -0xD3,0x29,0xA3,0x60,0xB2,0xC9,0xFD,0x61,0x79,0xC4,0xD3,0x5B,0x31,0xE4,0xFB,0x3D,0x12,0xCF,0xB4,0x2C, -0xF5,0x3D,0xB5,0x15,0x07,0xE2,0x8F,0xF7,0xBD,0x48,0x73,0x9B,0xBF,0xFB,0x13,0x4F,0xEF,0xC0,0xFE,0x62, -0x9B,0xB2,0xB9,0x61,0x76,0xBE,0xD7,0x35,0x49,0xD1,0xD3,0x63,0x74,0x5B,0x1C,0xF4,0x45,0x25,0x32,0xD0, -0xA0,0x5F,0x96,0xB0,0x6A,0xA0,0x38,0x62,0xA3,0x9C,0xB3,0x81,0x56,0x56,0x38,0xEA,0x88,0xA9,0x6B,0xBD, -0xFD,0xEF,0x6B,0x1D,0x20,0x10,0x1D,0xA9,0x3D,0x21,0x32,0x88,0xE5,0x22,0xE4,0xE1,0x56,0xF4,0x21,0x85, -0xDB,0xA9,0xA8,0x48,0x00,0x4E,0xEE,0xA5,0x4D,0x2B,0x33,0x90,0x79,0x60,0xB4,0x12,0xED,0x9E,0x38,0x94, -0xEC,0x9F,0xA9,0x6A,0x73,0xAF,0x27,0x7B,0xFA,0x3A,0xC7,0x00,0xCD,0x53,0x40,0xB7,0xAA,0xFA,0x66,0xC2, -0x82,0xBB,0x46,0x55,0x94,0x1D,0xDE,0x1D,0x45,0x28,0xCB,0xDE,0xA0,0x18,0xD6,0xF7,0x63,0xDD,0x2C,0x4C, -0x69,0xDF,0xD9,0xDC,0x6C,0x23,0xA5,0x38,0x66,0x37,0x58,0x71,0x85,0x21,0x94,0xB9,0x01,0x10,0xDE,0xDC, -0x5C,0xC7,0x98,0xB8,0x50,0xFB,0x1A,0x57,0x14,0xDC,0xB5,0x0C,0x7F,0xFF,0x13,0x77,0x2A,0x47,0x3E,0xA4, -0xD5,0xC8,0xB4,0x04,0xF7,0x5F,0xBE,0x64,0xF2,0xEF,0x4A,0xA0,0x97,0xFE,0xB2,0xEA,0x2E,0x58,0xBA,0x04, -0xB8,0xDE,0x7D,0xAF,0xE0,0x66,0x36,0x27,0xDC,0x0F,0x85,0xBE,0x7D,0x94,0x61,0x5D,0xDC,0xD4,0xB9,0xB2, -0x35,0xFB,0x5C,0x34,0x3E,0x93,0xA4,0x68,0xCD,0xD1,0x4D,0xD1,0x8A,0x93,0xED,0xA2,0x95,0x04,0x53,0xDD, -0x55,0x45,0xE2,0x86,0xB3,0x2C,0x1A,0xFD,0xA5,0xDC,0xFA,0x68,0x55,0xC3,0xC7,0x6C,0x4E,0x85,0x02,0x2B, -0x2D,0x47,0x6B,0xF6,0xBE,0x4E,0x61,0x95,0xD3,0x05,0x05,0x5E,0x77,0x9A,0x2A,0x9F,0x6B,0xF8,0x47,0x09, -0x03,0xCF,0xC0,0x4B,0xF3,0xFF,0xB2,0x1A,0x5F,0x59,0xCD,0xCA,0x7E,0xAC,0x11,0xF2,0x28,0x84,0x5A,0xF2, -0x2F,0x24,0x8C,0x5B,0x2B,0xC4,0xB6,0x2F,0x9E,0x6F,0x58,0x20,0xA3,0x9F,0x69,0xE5,0x46,0x6C,0xFD,0x8F, -0x06,0x96,0xB4,0x0C,0xAC,0x5D,0x69,0x24,0x6B,0x76,0x0D,0x47,0x98,0xE3,0x4A,0xA2,0x64,0xAD,0x44,0xE9, -0xFF,0xA3,0xF9,0x3A,0x2C,0x11,0x75,0xAE,0x68,0x06,0xA6,0x80,0xDC,0xE8,0x90,0xA0,0xBD,0x36,0x85,0xCC, -0x4F,0x59,0x14,0x8D,0x59,0x72,0xF0,0xC0,0xB8,0x5B,0x8D,0x17,0x8D,0x92,0xCD,0x7A,0x8A,0xE5,0xAF,0x25, -0xFA,0x0A,0x4F,0xF9,0xC1,0x43,0x80,0x87,0xC9,0xD6,0x73,0xAC,0xC0,0xC3,0x36,0x28,0x0F,0x46,0x7F,0xE9, -0xF8,0x56,0x56,0xF5,0x2E,0x3B,0x0C,0xF6,0xC2,0x2F,0x95,0xE4,0x09,0x25,0x59,0x64,0x6D,0xBE,0xA8,0xC7, -0x23,0xA0,0xE8,0x05,0x1D,0x3D,0xB9,0xAD,0xC7,0x38,0x4B,0xBC,0x4C,0x0D,0x21,0x83,0x58,0xFC,0xDE,0xA6, -0xAC,0x8B,0xE2,0xA9,0x47,0x6C,0x36,0x9D,0x66,0x98,0xBF,0x17,0x19,0xC4,0x8A,0xAA,0xFE,0x33,0x99,0x41, -0x06,0xD0,0xA5,0x31,0xCB,0x33,0xCC,0x72,0xDE,0xAE,0x35,0x2B,0x61,0xF6,0x82,0x2F,0x5F,0xAA,0xCE,0x7E, -0xD0,0x49,0xEB,0xEE,0xE5,0x5E,0xD6,0xE8,0xEC,0x67,0x9D,0x08,0x3C,0xE9,0x3F,0xB6,0x14,0xD2,0xB4,0x14, -0x26,0x12,0x98,0xC5,0x94,0xA5,0xA4,0xB5,0xAD,0xA7,0xE2,0x24,0x80,0x1A,0x21,0x56,0x18,0xB4,0x6E,0x96, -0x87,0xDC,0xA6,0x2B,0x23,0x2B,0x6D,0x7B,0xFA,0x43,0xD5,0x76,0x60,0x08,0xAA,0xA0,0xF5,0x57,0x6C,0x8E, -0xD3,0x23,0x94,0x61,0x03,0x22,0x6F,0x95,0x26,0x24,0xD4,0x74,0xB3,0xB5,0xB3,0x68,0x01,0xF5,0xD5,0x13, -0xC2,0xCB,0x57,0xC3,0x02,0x4C,0x10,0x71,0x61,0x0D,0x25,0x73,0xA9,0xB8,0x63,0x54,0x9C,0x98,0x40,0x43, -0x79,0x8B,0x47,0x6C,0x8B,0x0B,0x1E,0xD0,0xDB,0xB1,0x3A,0x20,0x42,0x79,0x8D,0xC1,0x5A,0x58,0x72,0x96, -0xB2,0x04,0xCD,0x90,0x98,0x07,0x63,0xE0,0x60,0x92,0xB8,0xA0,0xD6,0xA8,0x88,0xEA,0xEB,0x86,0x6E,0xDF, -0x03,0x7B,0x95,0x97,0x39,0xA7,0x53,0x03,0x6A,0x27,0xB3,0x9E,0x16,0xFC,0x77,0x49,0x88,0xDF,0xF2,0x22, -0xBB,0x84,0x3C,0xAE,0x5B,0x51,0xD1,0xFC,0x94,0x15,0x0D,0x3F,0x2B,0x5B,0xB7,0x0D,0x20,0xA3,0x25,0x98, -0xD1,0x69,0xD1,0x24,0x94,0x94,0x74,0x4A,0x60,0xF9,0x4C,0x92,0x32,0x93,0x85,0x65,0x2B,0xC4,0xB7,0x15, -0x1E,0xAB,0xF2,0x1C,0x5E,0x97,0xE7,0xEA,0x5B,0x96,0xFF,0x4E,0xFC,0x84,0xCE,0x4A,0x61,0x92,0xB2,0x35, -0x23,0xA5,0x28,0x93,0x38,0xF9,0x2A,0x23,0xE9,0xBF,0x3D,0xF5,0x1D,0x9F,0xBC,0x3A,0x19,0x9F,0x34,0x0F, -0x00,0xCD,0xCB,0x21,0xFE,0x57,0xB7,0x2F,0xDC,0x74,0x8D,0xBF,0x91,0xD4,0xA0,0xEC,0x36,0xCD,0xD6,0xFD, -0x51,0xD4,0xBA,0x97,0xAA,0x33,0x4A,0x71,0xE1,0x03,0x7A,0xDA,0xDC,0x6C,0x30,0x22,0xC7,0xEB,0x3B,0x2D, -0x6A,0xE9,0xAA,0x0A,0x97,0x5E,0x8D,0x1E,0x2A,0x57,0x91,0x59,0x1D,0x08,0x89,0x47,0x8B,0x88,0x62,0x89, -0xB3,0x21,0xD9,0xF7,0xE1,0x50,0xD8,0x31,0xD5,0x5D,0x8E,0xE7,0xC1,0xB5,0x97,0x7F,0x25,0xEF,0x03,0x36, -0x37,0x51,0xBB,0xA4,0x35,0x1C,0x4B,0x02,0xC5,0x82,0xB2,0x25,0x6F,0x22,0x40,0x16,0x60,0xCB,0xB1,0x5E, -0x8C,0x4E,0xDF,0xD8,0x09,0x4A,0xC1,0x21,0xA9,0xD9,0x8C,0x46,0xB9,0x12,0xB0,0xAD,0xED,0xA7,0x27,0x8D, -0xB3,0x96,0x7C,0xDD,0xE7,0xF2,0xA5,0x15,0x19,0x82,0x9C,0xCA,0xD0,0xA2,0xEC,0x29,0xEE,0x65,0x21,0xC7, -0xC5,0x65,0xBE,0xAB,0xC3,0x55,0xDC,0xCC,0x16,0xFC,0x26,0x7F,0xE0,0x3A,0x81,0x87,0x24,0x6B,0x9E,0x31, -0x5B,0x91,0xE1,0x6F,0xEE,0xD8,0xB2,0x6C,0x29,0x72,0xF7,0x8F,0x4B,0xEA,0x45,0xB4,0xDA,0x1C,0x79,0x1C, -0x5E,0xD4,0xA1,0xB8,0x36,0x47,0x1D,0x52,0x18,0xA1,0xBA,0x45,0xFF,0xA9,0x87,0xD0,0xD2,0x43,0xE8,0x6A, -0x80,0xC0,0xB7,0x2D,0x6F,0xAF,0x56,0x19,0x4C,0x80,0xB3,0xEB,0x41,0x1D,0x45,0x00,0x02,0xCF,0xA8,0x05, -0xF8,0x94,0xC9,0xF1,0x4F,0xE8,0x06,0xA9,0x6B,0xD9,0x1A,0xBA,0x3E,0x54,0xC8,0xE9,0xFE,0xEF,0xD0,0xAA, -0x66,0xB6,0x03,0x51,0x06,0xCD,0xD5,0x78,0xC2,0x5B,0xE1,0xA9,0x8E,0x59,0xCD,0xE8,0x04,0xEE,0x5A,0x78, -0xB3,0xC6,0x1B,0xFA,0x6D,0xB8,0x1E,0x18,0xE4,0x43,0xBE,0xD7,0x8C,0xC3,0x0A,0xA3,0x69,0x3D,0xEB,0x0F, -0xA3,0xED,0xE3,0xEA,0xFA,0x3A,0x43,0xFA,0x1F,0x3E,0xC8,0xEC,0xAC,0xBC,0x98,0x01,0x37,0x6F,0xF4,0x74, -0x30,0x88,0x0C,0xCC,0x10,0xA3,0x74,0x24,0xEE,0x00,0x54,0x22,0x59,0xAA,0x0D,0xF4,0xA4,0xEB,0x1A,0xA0, -0xB1,0x9E,0x4C,0x19,0x36,0xE8,0x01,0xE6,0x57,0x40,0x0A,0x40,0xEA,0x31,0x20,0xD9,0x18,0x44,0x30,0x88, -0x3C,0x3D,0x66,0x94,0x5D,0x23,0xD2,0x9C,0x4E,0x00,0x42,0x8A,0xAF,0x04,0xF4,0x0E,0xB5,0x8A,0x7D,0x90, -0x84,0x6A,0x88,0xDA,0x7D,0xB3,0xB8,0xE5,0xAC,0xEF,0x98,0x70,0xE9,0x36,0x85,0x7D,0x6C,0x48,0xB4,0x4C, -0x14,0x1E,0x23,0x9C,0x65,0x92,0x6F,0x21,0xD7,0x6B,0x16,0x80,0x58,0x80,0xD6,0x8B,0xA1,0x25,0x16,0x02, -0x09,0x05,0x60,0x1C,0xE2,0xB8,0x80,0x70,0x68,0x0A,0x10,0x12,0xA0,0x6F,0xA5,0xAA,0x46,0xB2,0xC0,0x23, -0x74,0xE6,0xF5,0x7B,0x8E,0xB5,0x4A,0xF6,0x22,0xC3,0x23,0x36,0xE5,0x63,0x34,0xC9,0x8C,0x0D,0xC7,0x5C, -0x9D,0x21,0x40,0x23,0x88,0x26,0xC6,0x96,0xB9,0x1E,0xFD,0x3D,0x4B,0xAF,0x71,0x5A,0x20,0x8B,0xCA,0x0C, -0x0A,0xB3,0x08,0x7E,0xF9,0xD0,0x17,0x2F,0xFA,0x5F,0x11,0x8A,0x6B,0xE0,0x28,0x64,0xF3,0xB3,0x94,0x50, -0xFE,0x5A,0x1E,0xFA,0x8D,0x8D,0xBE,0xDC,0x27,0x75,0x17,0x25,0x23,0x50,0x79,0x49,0xB5,0x10,0xC1,0xCC, -0x6D,0x5D,0x55,0x59,0x13,0xD8,0x2E,0x88,0xAD,0xEE,0x62,0x4E,0xA8,0xAB,0x1F,0xF1,0x34,0xEA,0x8E,0x74, -0x2B,0x46,0x3E,0x74,0xD4,0x1C,0xE8,0x2F,0x2D,0xE1,0xB4,0x6E,0x33,0x98,0x6C,0xD4,0x9D,0xBA,0x50,0x5F, -0xB9,0xC7,0x6B,0x5F,0x4B,0x09,0xE0,0x61,0xC4,0x26,0x86,0x78,0xE7,0xB0,0x10,0x0E,0xEF,0xD2,0xA5,0x29, -0xB2,0xD3,0xD7,0xAF,0xDC,0x7C,0x88,0xBA,0xDC,0xC2,0x8D,0x1B,0xC3,0x8E,0xAE,0x8B,0x8B,0x38,0xC0,0x43, -0xC1,0x29,0x8D,0xEE,0x5C,0xC8,0x8A,0x7F,0x21,0x75,0x4E,0x03,0xF6,0x35,0xA9,0x3F,0xDC,0x93,0xFA,0xC3, -0x3A,0xA9,0x71,0x7B,0xB7,0xA0,0x73,0x01,0x64,0x5F,0x23,0x8A,0x66,0x38,0x85,0x01,0xB1,0x08,0x6C,0xC0, -0x3F,0xE3,0x2C,0xC5,0x5F,0xE7,0x6C,0x14,0x92,0x29,0x5F,0xE1,0x4F,0x8E,0xFE,0x3B,0x2E,0x53,0xFC,0x00, -0x97,0x65,0x21,0x5B,0xA5,0x8D,0xBF,0xBE,0x07,0x93,0x4E,0xED,0xC1,0x16,0x36,0xDD,0xF5,0x5F,0xF8,0x5D, -0xBD,0xE2,0xD7,0xB3,0xA7,0x78,0xB8,0x78,0x69,0x05,0xC2,0x26,0x40,0x82,0x46,0x7E,0x62,0xF4,0x10,0x4E, -0x0A,0xAF,0x40,0x04,0x43,0x99,0x23,0xF6,0x16,0x4B,0x8B,0x7B,0xC6,0x9C,0x80,0xF8,0x73,0x10,0xCE,0x97, -0xD5,0xAF,0x2D,0xBE,0x56,0x02,0x25,0x00,0x93,0x90,0x67,0x7B,0x1F,0x0F,0x36,0xAF,0x3A,0x90,0xA0,0x3C, -0x78,0x98,0x1E,0x34,0x36,0xAF,0x7E,0x30,0x7B,0x33,0xD2,0x28,0x89,0x64,0xAA,0x03,0xBD,0x7E,0xA4,0x57, -0x1E,0x5A,0x42,0x08,0x6B,0xA6,0xC2,0x2A,0xB0,0x5A,0x58,0x5E,0x69,0xC2,0x43,0x7C,0x04,0x06,0x0F,0x19, -0x3B,0x60,0x36,0xF5,0x1A,0x37,0x8D,0x3A,0x87,0xBF,0x3A,0x84,0xED,0x41,0xC1,0x56,0x80,0xA7,0x84,0x62, -0x19,0xBD,0x54,0xD3,0x2A,0x00,0x42,0x0D,0x24,0x95,0x90,0xB2,0x6D,0x89,0xB6,0xC8,0x7E,0x64,0x26,0x14, -0x69,0xE8,0xE2,0x83,0x0F,0x91,0xE8,0x75,0x99,0xB0,0x57,0xC0,0x73,0x19,0x48,0x1A,0x13,0xD6,0xBC,0xC0, -0xD3,0xF3,0xA2,0xA5,0x83,0x94,0xBC,0x11,0x84,0x95,0x38,0x10,0x6F,0x55,0xE3,0x5E,0x68,0xAF,0x4F,0x3D, -0x0A,0x6C,0x2E,0xC1,0xC5,0x94,0x00,0x81,0x5E,0xA5,0xF3,0x5F,0x5E,0xBF,0x7A,0xC6,0x79,0x72,0xAE,0x76, -0x14,0x68,0xB5,0x07,0x6A,0x43,0x33,0x17,0x3C,0xBD,0x2B,0x0B,0x43,0x11,0x28,0x54,0xA8,0xFB,0xE5,0x74, -0xF2,0x09,0xFB,0x20,0xC9,0xEB,0x0C,0x72,0xE8,0x96,0x2D,0xD0,0xC7,0xE3,0x33,0x7B,0xD7,0x76,0xA0,0x52, -0x81,0xFD,0xF4,0x43,0x61,0x31,0xCB,0x7F,0x84,0xBC,0xFD,0xCF,0x90,0x09,0xC4,0xFB,0x0C,0x02,0x7A,0x89, -0xDF,0xC6,0x0D,0x53,0x36,0x97,0x68,0x27,0x69,0x2A,0x8C,0x61,0x1C,0x92,0x4C,0x9B,0xC0,0x60,0x86,0x53, -0x2D,0x60,0x38,0xD3,0x28,0xE3,0x5A,0x96,0x27,0x09,0x4B,0xF9,0x3D,0x7D,0xD8,0x7A,0x79,0x49,0xF3,0x36, -0xC7,0x39,0x0E,0x8A,0x61,0x9C,0x36,0xF5,0x22,0x6B,0x3A,0x18,0x07,0x77,0xFB,0x78,0x55,0x54,0x78,0x39, -0xA5,0x22,0xFF,0x6C,0xF4,0x55,0x1F,0xA4,0x0B,0x81,0xAA,0x47,0xF3,0x28,0x5A,0x0E,0xEE,0xD1,0xB2,0x93, -0x94,0x71,0x26,0x5F,0x7A,0x2D,0x7E,0x2F,0x5C,0xCB,0xBD,0x77,0x4D,0xDF,0xA6,0xEA,0x58,0x1B,0xC6,0x06, -0xD6,0x08,0xCD,0x38,0xA2,0xBE,0xD8,0x46,0xA5,0x0B,0xB3,0xAC,0xEE,0xC4,0xF4,0x81,0x88,0x0B,0xD2,0x70, -0x1E,0x2C,0x29,0xA4,0x64,0xD4,0xD3,0x75,0x51,0xE8,0x61,0x51,0x2F,0xA3,0x38,0x6B,0x90,0xAD,0x32,0x85, -0x49,0xBD,0x12,0x3C,0x90,0x2F,0x57,0x9A,0xF3,0x57,0xD9,0x28,0xAB,0x7B,0x04,0x30,0xAD,0x9C,0x67,0xD2, -0x8E,0xA7,0xCB,0x0A,0xE1,0x40,0x86,0x0C,0x69,0xC0,0x31,0xE6,0x21,0x0B,0x0E,0xF4,0x03,0xDD,0xD5,0xE1, -0xFF,0xA6,0x6E,0xC1,0x2C,0x4C,0x7D,0x16,0xE0,0x8B,0xF3,0xE7,0x10,0x4A,0x13,0x46,0x31,0xE5,0x06,0x82, -0x8C,0xE2,0xE9,0x9D,0x55,0x48,0xC5,0xC6,0x47,0x74,0x65,0x0E,0xDA,0xCA,0xC6,0xF3,0x7B,0xDB,0xD9,0xDA, -0x0C,0x9B,0x51,0x11,0x5D,0xEF,0x80,0x79,0x8E,0x57,0x5E,0x8E,0x58,0x74,0xF5,0x14,0x64,0x2E,0x76,0x04, -0xCF,0x12,0x6B,0x04,0x58,0xC2,0xF5,0x6A,0x25,0x3F,0x54,0xD9,0x51,0xDB,0x47,0x51,0x24,0x3E,0xE6,0x00, -0x5E,0xC5,0x62,0x79,0x66,0x09,0x22,0x19,0x08,0x90,0xE1,0x31,0xBE,0x05,0x97,0x96,0xE5,0x99,0xB2,0xA1, -0xE2,0x38,0x04,0xA4,0x79,0xC3,0x8C,0x4C,0xAB,0xEA,0x6D,0x6E,0x72,0xBB,0x34,0x13,0xA3,0x44,0xCA,0x44, -0xB2,0x91,0x77,0x0F,0x4B,0xA3,0x29,0xA4,0xC8,0xDD,0x2B,0xDA,0x36,0xDA,0x6A,0x48,0x30,0x35,0x4A,0x18, -0x70,0x96,0xA7,0x11,0x64,0x08,0x51,0xBD,0xB4,0xA6,0x65,0x98,0x06,0xB0,0x80,0xFB,0x97,0xC8,0x12,0x95, -0x36,0xAD,0x62,0xC4,0x53,0xC5,0x77,0x9B,0x1E,0x2F,0x76,0xE5,0x19,0x96,0x61,0xAE,0xFD,0xF5,0xAD,0x25, -0xBF,0x9B,0x25,0x2A,0x21,0xF4,0xE0,0x6D,0xCA,0x7C,0xDE,0x05,0xB3,0x8A,0xBB,0xB0,0x82,0xB2,0x82,0x40, -0x5F,0xC3,0xA1,0x3A,0xED,0x59,0xE2,0x3A,0xC5,0xBD,0xE7,0xA2,0xB5,0xFE,0x8C,0x7B,0x3E,0xDA,0xA6,0xD3, -0xE6,0xB3,0xB1,0xDB,0x7B,0x3B,0xF7,0x40,0x68,0xC2,0x52,0x6E,0x40,0x8E,0x83,0x34,0x58,0xAD,0x56,0x1E, -0xBC,0x9A,0x71,0xC1,0x4E,0xF2,0x2C,0x34,0x16,0xC0,0xBA,0xCB,0x2D,0xA5,0x2B,0x17,0x5B,0xCA,0x6E,0x5D, -0x6A,0x95,0xF6,0xE1,0x42,0xEA,0x6A,0xC5,0x8F,0x2F,0x5F,0x64,0xAF,0xDE,0x6D,0xE8,0xB5,0x37,0x1C,0x84, -0x95,0x4E,0x5C,0x66,0x64,0x61,0xF4,0xF7,0x63,0xD5,0x5E,0x4F,0x9D,0xA7,0xCA,0xCF,0x5D,0x34,0x12,0x78, -0x22,0xB9,0xEB,0xC5,0x7B,0x2D,0x68,0x4E,0x21,0x2E,0xD9,0x70,0x00,0xAB,0xBE,0x6F,0xD6,0x8B,0x0F,0x9C, -0xEF,0xE3,0xEE,0x57,0x27,0x42,0xCF,0xAB,0xEA,0x79,0x15,0x75,0xD4,0x04,0xEF,0x81,0x8F,0x60,0x74,0x05, -0x86,0x03,0xB3,0x6A,0xD8,0xD5,0xDA,0x62,0x5D,0xAB,0x18,0x44,0xD9,0x1D,0xF5,0x45,0xD4,0xAC,0xA8,0x84, -0xA0,0xFE,0xD6,0x21,0x5A,0xCD,0x34,0x97,0x35,0x67,0xE2,0xFA,0x51,0x63,0xC5,0x5B,0x87,0x66,0x8D,0x01, -0xEC,0xC3,0x19,0x5D,0x88,0x5B,0xBA,0xA8,0x26,0x0F,0xE9,0x55,0x17,0xC4,0x83,0x09,0xF5,0xAC,0x3C,0x59, -0x0F,0x90,0x25,0xC1,0xCA,0xA0,0xAA,0x2A,0x56,0x86,0x8B,0x83,0x5E,0xF5,0x2E,0xB0,0xF1,0xFD,0x52,0x4D, -0x83,0xC8,0x57,0x27,0x72,0x7E,0xFB,0x6D,0xCA,0x83,0x68,0x0A,0x63,0xFF,0x4F,0x51,0x09,0xC4,0x79,0xD4, -0x2E,0x00,0x00 +0xDF,0x49,0xF2,0x93,0x84,0xEE,0x5D,0x0A,0x96,0x74,0xBA,0xD3,0xDD,0xE9,0x5E,0x92,0xBD,0xB7,0x71,0x7C, +0x7A,0x34,0xBE,0x3C,0x3B,0xD1,0x42,0x1E,0x47,0xFB,0x7B,0xE2,0xAF,0x16,0x21,0x3A,0xF3,0x74,0x4C,0xF5, +0xFD,0xBD,0x18,0x73,0x04,0x20,0x9E,0x74,0xF1,0xEF,0x39,0xB9,0xF1,0xF4,0x23,0x46,0x39,0xA6,0xBC,0xCB, +0xEF,0x12,0xAC,0x6B,0xBE,0xEA,0x79,0x3A,0xC7,0xB7,0xBC,0x27,0x90,0x07,0x9A,0x1F,0xA2,0x34,0xC3,0xDC, +0xCB,0xF9,0xB4,0xFB,0x18,0x48,0x70,0xC2,0x23,0xBC,0x7F,0x32,0x3A,0xD3,0x4E,0x02,0xC2,0x59,0xBA,0xD7, +0x53,0x23,0x7B,0x11,0xA1,0xD7,0x5A,0x8A,0x23,0x4F,0x47,0x49,0x12,0xE1,0x2E,0x67,0xB9,0x1F,0x76,0x09, +0xD0,0xD4,0xB5,0x30,0xC5,0x53,0x4F,0x07,0xA2,0x29,0xCA,0x7A,0xC8,0xC7,0x36,0x0C,0xEB,0x9A,0x58,0xD4, +0xD3,0x49,0x8C,0x66,0xB8,0x77,0xAB,0x66,0x36,0xC9,0x64,0x21,0x4B,0xB9,0x9F,0x73,0xED,0x5F,0xD0,0xF8, +0xDB,0xA8,0x19,0xBF,0x8B,0xB0,0x02,0x29,0x2D,0xF8,0x59,0xA6,0x6B,0x31,0x0E,0x08,0x02,0x8E,0xFC,0x14, +0x0B,0x3D,0x46,0x68,0x82,0xA3,0xC5,0x94,0x81,0xE2,0x32,0xF2,0x09,0xBB,0xFD,0xAD,0xE4,0x76,0x20,0xBB, +0x53,0x14,0x93,0xE8,0xCE,0xCD,0x10,0xCD,0xBA,0x19,0x4E,0xC9,0x74,0x69,0xFB,0xF1,0xE2,0x53,0x97,0xD0, +0x00,0xDF,0xBA,0xDB,0x8E,0x33,0x48,0x58,0x46,0x38,0x61,0xD4,0x45,0x93,0x8C,0x45,0x39,0xC7,0x83,0x08, +0x4F,0xB9,0xFB,0x08,0x28,0x4C,0x58,0x1A,0xE0,0xD4,0xED,0x27,0xB7,0x1A,0x80,0x48,0xA0,0x7D,0xB5,0xB3, +0xB3,0x33,0x98,0x20,0xFF,0x7A,0x96,0xB2,0x9C,0x06,0x5D,0x9F,0x45,0x2C,0x75,0xBF,0x9A,0x3E,0x12,0x3F, +0x83,0x80,0x64,0x49,0x84,0xEE,0x5C,0xCA,0x28,0x06,0xDC,0xDB,0x6E,0x16,0xA2,0x80,0xCD,0x5D,0x47,0x73, +0xB4,0xBE,0x03,0x44,0xD2,0xD9,0x04,0x19,0x8E,0x25,0x7E,0xEC,0x1D,0x73,0xF0,0x97,0xF8,0x55,0xC3,0x73, +0x4C,0x66,0x21,0x77,0xBF,0x77,0x1C,0xC1,0xBF,0x96,0x47,0x8B,0x88,0x64,0xBC,0x2B,0x95,0xA3,0xD6,0xE3, +0x2C,0x71,0x1D,0xC9,0x3A,0x3C,0x62,0x94,0xCE,0x08,0x85,0x46,0x82,0x82,0x80,0xD0,0x99,0xAB,0xD0,0x22, +0xB2,0xA8,0xA4,0x85,0xDD,0x40,0x9C,0xDC,0xE0,0x41,0x4C,0x68,0x77,0x4E,0x02,0x1E,0xBA,0xBB,0x0E,0x70, +0xE1,0xE7,0x69,0x06,0x32,0x25,0x8C,0x50,0x8E,0x53,0x89,0x96,0x25,0x88,0x2E,0x94,0xA8,0x42,0x01,0x95, +0x9C,0x84,0xC2,0xBE,0xE2,0xEE,0x24,0x62,0xFE,0x75,0xB5,0xD2,0x6E,0x72,0x5B,0xAC,0xE5,0x86,0xEC,0x06, +0xA7,0x8B,0x5A,0x5D,0x12,0xBB,0x05,0x6C,0x91,0xC6,0x18,0x2F,0x6D,0x7E,0x93,0x03,0xD4,0x92,0x4F,0x90, +0xB2,0xA0,0xDA,0x14,0xA9,0x2D,0x78,0x81,0x42,0x68,0x92,0xF3,0xC5,0xEA,0x56,0xB2,0x04,0xF9,0x84,0xDF, +0xB9,0x8E,0x9C,0x26,0x2D,0xC4,0xDD,0x71,0x1C,0x4D,0x28,0x5C,0x7B,0x8B,0xD3,0x00,0x51,0x64,0x0D,0x53, +0x82,0x22,0x6B,0x54,0xAB,0xBC,0x1B,0xB3,0x4F,0xDD,0x1C,0xDA,0xD0,0x8F,0xB0,0xCF,0x95,0x86,0x61,0x13, +0x26,0xD7,0x84,0xAF,0x02,0x56,0x06,0x1A,0xBA,0x92,0x1A,0x0A,0xD5,0xEE,0xF5,0x41,0x37,0x92,0x0F,0x25, +0xB6,0x92,0xA8,0x3B,0x61,0x9C,0xB3,0x58,0xDA,0x5B,0x25,0xAD,0x26,0x4D,0xE6,0xF1,0xCA,0x76,0xAC,0x57, +0x7D,0x83,0xFC,0x00,0x94,0xCA,0x89,0x8F,0xA2,0x2E,0x8A,0xC8,0x8C,0xBA,0x31,0x09,0x82,0x08,0x37,0x4C, +0xD6,0xCD,0xD3,0xC8,0x08,0x10,0x47,0xAE,0xF2,0xB3,0x84,0xCE,0x00,0x9A,0xE1,0xDD,0x1D,0x8B,0xBC,0x3D, +0x3C,0x3D,0x9F,0x3B,0x2F,0x9E,0xCC,0xD8,0x10,0xFE,0xBD,0x1E,0x5D,0x84,0x27,0x17,0x33,0x68,0x1D,0x8A, +0xEE,0xF0,0xCD,0xD1,0xF0,0x0D,0x3C,0x8E,0xFA,0x9D,0x8F,0xD3,0xDF,0x87,0x62,0xF8,0x49,0x70,0x38,0xBE, +0x38,0x19,0x0E,0x5F,0xF4,0x9E,0xBD,0x9E,0xBF,0x7B,0xB1,0x2B,0xC0,0x87,0x91,0x73,0xFE,0x36,0x74,0x2E, +0xB6,0x7E,0x88,0x83,0xA7,0x41,0xE8,0xC7,0x17,0xC3,0x37,0xEF,0xCE,0x6F,0x2E,0xE3,0x8B,0xD9,0xE8,0x5D, +0x3F,0x7C,0xBF,0xF5,0x76,0xF4,0xFE,0xDD,0x4F,0xD7,0xF8,0xE7,0xA7,0xCF,0xDF,0x8F,0xE7,0x80,0x70,0xCC, +0x46,0x17,0xE7,0x87,0x6F,0x0F,0x67,0xEF,0x0F,0xFD,0x93,0xDB,0x49,0xF4,0xFA,0xF0,0xC9,0x70,0x32,0xDC, +0xF2,0x31,0x9E,0x8D,0xCF,0x0F,0xF3,0x67,0x2F,0x4E,0x67,0x84,0x84,0xA3,0xF7,0xAF,0xC7,0xFE,0xD1,0xA3, +0x97,0x17,0x4F,0x87,0x24,0x7C,0xFD,0xFC,0xDC,0xB9,0x7E,0xF2,0xE2,0xE8,0xD8,0xBF,0x7C,0x7E,0xB9,0x7B, +0xBC,0xDD,0xFB,0xFE,0xFB,0x57,0xC1,0x29,0xA1,0xE3,0x9B,0x4F,0xC3,0xD9,0xD1,0xFC,0xF1,0x5D,0x36,0x0E, +0x9F,0xDD,0xD0,0xDE,0x5B,0xF6,0xF1,0xD9,0xDD,0x2B,0xF8,0x3D,0x3B,0xEB,0x4C,0x46,0xFD,0xEC,0xE2,0xCD, +0xB3,0xB7,0x5B,0xD9,0x0F,0x8F,0x92,0xC3,0xE3,0xE3,0x9B,0x78,0x72,0xD6,0x8B,0x83,0xEB,0x29,0x7F,0xBC, +0xCD,0x93,0xCB,0x59,0xFE,0xFE,0xF7,0x47,0xCF,0xC3,0xDE,0x29,0x46,0x97,0x61,0xE7,0xEE,0xD3,0xDD,0xE3, +0x70,0xFC,0xF4,0xE6,0x75,0x84,0x6E,0x5F,0xBF,0xF6,0x3F,0xC5,0x9D,0x08,0xFD,0x70,0x3A,0x8E,0x50,0xDA, +0xBF,0x08,0x86,0xBD,0xCE,0xD1,0xD6,0x70,0x87,0xA7,0xE7,0x47,0xF4,0x78,0xFB,0xE3,0xE8,0xF1,0xE1,0x61, +0x9F,0x4D,0x7E,0xDF,0x7A,0x72,0xBD,0xFB,0xE4,0x62,0xF7,0xCD,0xE4,0xCD,0x70,0xB4,0x73,0x78,0x81,0x2E, +0x47,0x6F,0x86,0xD3,0x9D,0x49,0x18,0xBE,0x78,0x31,0xFE,0x29,0x18,0x7E,0x4A,0x87,0xA7,0xF3,0xE1,0xED, +0xC9,0xC5,0xF0,0x69,0xE7,0xC5,0xC9,0x2B,0xA7,0x3F,0xBA,0xDC,0x9E,0xBD,0xDA,0x9D,0x1F,0x66,0x27,0xC3, +0x37,0x87,0xCE,0xEC,0x79,0x27,0x46,0xEF,0xD9,0xD1,0xF6,0xEC,0xD9,0x2E,0x39,0xBB,0x44,0xC3,0x67,0x87, +0xCF,0x33,0x72,0x1E,0x3F,0xBD,0x70,0x86,0xC3,0x97,0xA7,0xF8,0xA7,0xA3,0x6D,0xF4,0x62,0xCB,0x7F,0x07, +0xFA,0xBF,0xF8,0x19,0x7F,0xDF,0x19,0xCE,0x4F,0x9D,0xC8,0xFF,0x01,0x8F,0x9F,0x5E,0x8E,0xE5,0xEE,0x9C, +0x44,0x3F,0x8D,0xAF,0x47,0xF9,0x9B,0xF8,0xE8,0xC8,0xD4,0x28,0xEB,0xA6,0x38,0xC1,0x88,0x37,0x63,0x55, +0xE5,0x1C,0x60,0x5B,0xB5,0x15,0x16,0x4E,0x2A,0x22,0x6B,0x37,0xC0,0x3E,0x4B,0x91,0x9C,0x03,0x08,0x38, +0x15,0x26,0xB6,0xFC,0x51,0x86,0x5A,0x4D,0x45,0x5A,0x0D,0xD1,0x40,0x33,0x4A,0x47,0x88,0x09,0x05,0x9C, +0x1B,0xE2,0xE3,0x6E,0x42,0x6E,0x71,0xD4,0x95,0xC8,0xAE,0x63,0x2E,0xA4,0xB3,0x95,0xD3,0x10,0x25,0xB1, +0xA2,0x5A,0x0E,0x04,0x1F,0x91,0x2F,0x92,0x1C,0xB8,0x4C,0x0C,0xCF,0xC2,0x77,0x58,0xDA,0x9D,0xE4,0xB3, +0x29,0xB9,0x05,0x6F,0x9E,0x12,0x4A,0x38,0xD6,0xFA,0xD9,0xF2,0xC7,0x92,0xCC,0x35,0xBE,0x9B,0xA6,0x28, +0xC6,0x99,0xF6,0x17,0xC9,0x2C,0xA6,0x29,0x8B,0x17,0x75,0x04,0xE4,0xAC,0xD1,0x59,0x2E,0xBF,0xCA,0x93, +0x88,0x21,0x10,0x73,0x25,0x6C,0x94,0xC1,0x34,0x15,0x6E,0x55,0x05,0xD5,0xD2,0xCD,0xB6,0xC0,0x2D,0x5B, +0x6E,0xBD,0xB5,0x53,0xBB,0x6E,0x57,0xCE,0x15,0xC1,0xBE,0xA9,0xFA,0x46,0x3C,0x68,0xC4,0xBA,0xAF,0x38, +0xA8,0x74,0xFD,0xE2,0x6A,0x11,0x15,0x19,0x6A,0x06,0x54,0x94,0xEE,0xEF,0x3A,0x8D,0x50,0x01,0xF3,0x96, +0x5F,0x61,0x99,0xF8,0xAD,0xAF,0x92,0x14,0x76,0x03,0xCF,0xBF,0x40,0xB3,0x92,0xA9,0x4D,0x1B,0x68,0x56, +0xE9,0x4E,0x89,0x50,0xE7,0x3C,0xC9,0x6B,0x45,0x7A,0x55,0x2A,0x00,0x57,0xDC,0x3C,0x12,0xDC,0x7C,0x51, +0xAB,0xDB,0xBB,0xDF,0x14,0x3C,0xEC,0x38,0xDF,0x2C,0x6D,0x35,0xB7,0xCA,0xC7,0x7D,0x07,0xFE,0x95,0x69, +0xF7,0x71,0xCD,0xC2,0xE4,0x91,0xF8,0x29,0x19,0x04,0x3A,0x4D,0xE0,0xF6,0xCE,0x0F,0x8F,0x83,0x49,0x09, +0x54,0x82,0x3D,0x0C,0x4F,0x51,0x40,0xF2,0xCC,0x7D,0xE4,0x7C,0xA3,0xF4,0x09,0xDB,0x07,0xB2,0x97,0x9B, +0xAB,0x3A,0xB5,0xC5,0x66,0x09,0xA1,0xDA,0x56,0xA6,0x89,0xFD,0x46,0x69,0x65,0x98,0xCD,0x54,0x0F,0x2E, +0x52,0x9B,0xA6,0x98,0xBF,0x70,0xBE,0x59,0xF0,0x14,0xD1,0x6C,0xCA,0xD2,0xD8,0x4D,0x19,0x47,0x1C,0x1B, +0x8E,0xB9,0xEC,0x3B,0xEB,0x00,0xDB,0xBB,0x4E,0x80,0x67,0xE6,0x72,0xB9,0xD7,0x93,0x49,0x0D,0x2A,0x1E, +0x3F,0x25,0x09,0xDF,0x9F,0xE6,0xD4,0x17,0x3C,0x68,0x33,0x6C,0x60,0x73,0x91,0x62,0x9E,0xA7,0x54,0x0B, +0x98,0x9F,0x0B,0x63,0xB7,0x67,0x98,0x9F,0x28,0xBB,0x3F,0xBC,0x7B,0x16,0xC0,0x8C,0x65,0x85,0xE0,0xAF, +0x45,0x00,0x07,0x86,0xF5,0x0A,0x9C,0xD6,0x7C,0x48,0x30,0x40,0xE4,0x05,0xBE,0x33,0xB0,0xC5,0x2B,0x44, +0x6C,0x8B,0x71,0xC3,0x28,0xA7,0x01,0x90,0x9A,0x8B,0x1B,0xD0,0x02,0xF2,0xF0,0x07,0x7E,0x65,0x11,0x8F, +0xC2,0x63,0x50,0x4C,0x27,0xFB,0xE8,0xA0,0xDB,0x77,0xD1,0x3E,0x39,0xE8,0x83,0x7F,0x99,0x0D,0xFA,0x6A, +0xE5,0x9F,0x48,0x84,0x2F,0x0A,0x97,0x13,0x0B,0xD5,0xD4,0x7A,0x06,0x39,0x0B,0x41,0x91,0xE6,0x77,0xC6, +0xE9,0x48,0x33,0x3E,0x7C,0xDF,0xFD,0xE1,0xEA,0x73,0xFF,0x83,0xD3,0xED,0x5F,0x99,0xBF,0x99,0x3D,0x62, +0x73,0x9C,0x71,0x83,0xA2,0x1B,0x32,0x43,0x60,0xE7,0xB6,0xC8,0xB7,0xC3,0x19,0x48,0x61,0x0E,0xAA,0x35, +0x88,0x62,0x6F,0xCB,0x71,0x36,0x3C,0x7C,0x80,0x22,0x0C,0xAC,0xEB,0x27,0xE7,0xE7,0xA7,0xE7,0x1F,0xF4, +0x0E,0xEE,0xE8,0x57,0xAE,0xA6,0x77,0xA8,0xE9,0x72,0x1B,0x4A,0xCF,0x14,0x67,0xE1,0x19,0xE2,0xA1,0x11, +0xD8,0x37,0x28,0xCA,0x41,0x17,0x82,0x11,0xE6,0x81,0xE2,0xF4,0x49,0xCE,0x39,0xA3,0xBA,0x39,0x60,0x36, +0xA1,0x14,0xA7,0x4F,0xC7,0xAF,0x5E,0x7A,0xFA,0x39,0x63,0x5C,0x3B,0x26,0xA9,0x6E,0xC9,0xDD,0xB0,0x51, +0x92,0x60,0x1A,0x1C,0x85,0x24,0x0A,0x0C,0x66,0x0E,0x04,0xBA,0x2F,0xD1,0x65,0x21,0x02,0xD8,0xBE,0xAD, +0x4A,0xD6,0x29,0x48,0xAD,0x5B,0xBE,0x1D,0xE7,0x11,0x27,0x49,0x84,0xBD,0x8D,0x3E,0xF4,0x28,0x8A,0x01, +0x26,0xD2,0xB0,0x80,0x91,0xC0,0xD3,0x55,0x30,0x2A,0x42,0xD8,0xBA,0x55,0x7C,0xB5,0x4A,0xD0,0x5A,0x25, +0x68,0xE2,0x26,0x20,0x91,0x6E,0x05,0x76,0x5D,0x2B,0x43,0xAF,0x58,0xAA,0x84,0x05,0x78,0x8A,0x80,0x93, +0xB7,0x20,0x35,0x8C,0xF6,0xD6,0x2D,0x14,0xA8,0x85,0xB2,0xB6,0x36,0xB2,0xA6,0x36,0xD4,0x36,0xAE,0x43, +0xCE,0x14,0x72,0xDA,0x46,0x4E,0x9B,0xC8,0x47,0xD2,0x1A,0xD6,0x21,0xA7,0x0A,0x39,0x6A,0x89,0x18,0x49, +0x11,0x55,0x84,0xEB,0x0A,0x6D,0x82,0x40,0x80,0x1D,0x35,0xC5,0x84,0x1E,0x38,0x24,0x9A,0x44,0x38,0xF0, +0x36,0x1C,0xE8,0x89,0xA2,0xDA,0xDB,0x72,0xD6,0xAC,0x11,0xA9,0x35,0xF2,0xD6,0x1A,0xB9,0x5C,0x83,0x24, +0xA0,0x44,0xC8,0x1B,0xBA,0x95,0x4B,0xAD,0xB5,0x47,0xD4,0x72,0x7E,0x88,0xFD,0xEB,0x09,0x93,0x23,0xB2, +0x2D,0x56,0xDC,0x40,0x92,0x66,0x22,0x69,0xCA,0xA3,0x08,0xD0,0x4C,0x6C,0xF0,0x72,0x4F,0x50,0xB6,0x92, +0xA6,0xF8,0xDA,0x30,0xE2,0xB6,0x2E,0x11,0xE2,0xB6,0x96,0xE2,0xD6,0xB4,0x11,0xBA,0xC1,0xDA,0x3A,0x2D, +0xC5,0xE6,0x9A,0xC1,0x64,0xDD,0x60,0x6E,0x5A,0xA9,0xCD,0xA8,0x1F,0x11,0xFF,0xDA,0xAB,0xDD,0xD8,0x5C, +0x18,0xCD,0x8E,0xE0,0x84,0x7B,0x14,0xCF,0xB5,0x9F,0x20,0x2C,0x1D,0x23,0x8E,0x06,0xBC,0x20,0x63,0x14, +0x76,0x83,0x81,0x10,0x9C,0x4F,0xC1,0x0B,0x33,0x1B,0x05,0x30,0x7C,0x76,0x31,0xD6,0x2D,0xBD,0x27,0x76, +0x45,0x07,0x4F,0x26,0xE6,0xD2,0xAC,0x7C,0xC9,0xA2,0x32,0xAA,0x5F,0xA4,0x51,0x3D,0x04,0x8D,0xD2,0xE2, +0x96,0x56,0xBC,0x96,0x27,0x32,0x35,0x2A,0x95,0x96,0x4C,0x89,0x93,0xA1,0x58,0xC3,0x28,0xF6,0x5F,0x37, +0x21,0xEC,0x29,0xE3,0x35,0x4C,0x0B,0xB5,0x99,0x46,0x15,0xD3,0x29,0x9A,0x97,0x46,0xA2,0xD6,0x1F,0x28, +0xF7,0x76,0x20,0xFB,0xD2,0x8C,0x6B,0xD8,0xDB,0x71,0x7E,0xD8,0x1D,0xC0,0xFE,0x18,0xCA,0x71,0x01,0xB0, +0xC7,0x6D,0x30,0xAD,0x19,0x0F,0x07,0x7E,0xC7,0x2B,0xB4,0x12,0x78,0xDC,0xCE,0xF2,0x49,0xC6,0x53,0xC8, +0x6D,0x86,0x6F,0xF9,0x1D,0x6C,0xB6,0x97,0xD1,0x3B,0xCC,0x0A,0x4C,0x8B,0x75,0x3A,0xCB,0x7B,0x0A,0x3A, +0x1D,0x35,0x34,0x84,0x84,0x86,0x70,0x94,0x61,0x8D,0xDA,0xF8,0x16,0xFB,0x47,0x2C,0x8E,0x91,0x20,0x91, +0xC1,0x26,0x17,0x1D,0xDD,0x5C,0x5A,0x6C,0xAD,0x66,0x1E,0x08,0x59,0x56,0xF6,0x90,0x1E,0x21,0x04,0x7A, +0xBE,0x2D,0x7C,0x25,0x2B,0x84,0xFA,0xF2,0x2E,0x97,0x81,0x48,0xA1,0x7C,0x70,0xAE,0xAC,0x6A,0xE3,0x56, +0xA4,0x6A,0xEF,0xBB,0xB4,0xBA,0x56,0xFC,0x31,0xEB,0x9D,0x16,0xB0,0x76,0x5C,0xAB,0xA1,0xFA,0x72,0x69, +0xF9,0x82,0xFF,0x10,0xD1,0x19,0xFE,0xEB,0x02,0xD4,0x3C,0x4A,0x17,0xB5,0x28,0x24,0x8F,0x03,0xF7,0x17, +0xDB,0xF8,0xF0,0xAB,0x7D,0xD5,0x31,0xCD,0x83,0xAF,0x7B,0x52,0xC3,0x06,0x37,0x3F,0xF4,0xAF,0x2C,0x04, +0x60,0xFB,0x3B,0xF3,0x17,0x5B,0x82,0x5B,0xB0,0xC1,0x0D,0x23,0x81,0x26,0x56,0x12,0x9E,0xCD,0xA6,0x1A, +0xDA,0xDC,0x34,0xC0,0xE4,0x5A,0xC6,0xDA,0xE1,0x1D,0xDD,0x86,0xBC,0xB1,0x5C,0xDE,0xCF,0x66,0xE3,0x14, +0x63,0x95,0x2E,0x2B,0x80,0xE4,0x1E,0x64,0x5E,0x09,0x56,0xA5,0xD4,0xD8,0xAA,0xA1,0x30,0x28,0xD3,0xBD, +0x5D,0x54,0x12,0x9E,0x4E,0x19,0x05,0x93,0x4D,0xEE,0x0F,0xCB,0x23,0x9E,0xDE,0x8A,0x21,0xDF,0xEE,0x91, +0x78,0xA6,0x65,0xA9,0xEF,0xA9,0xAD,0x38,0x10,0x7F,0xBC,0x6F,0x45,0x9A,0xDB,0xFC,0xCD,0x9F,0x78,0x7A, +0x07,0xF6,0x17,0xDB,0x94,0xCD,0x0D,0xB3,0xF3,0xAD,0xAE,0x49,0x8A,0x9E,0x1E,0xA3,0xDB,0xE2,0xA0,0x2F, +0x2A,0x91,0x81,0x06,0xFD,0xB2,0x84,0x55,0x03,0xC5,0x11,0x1B,0xE5,0x9C,0x0D,0xB4,0xB2,0xC2,0x51,0x47, +0x4C,0x5D,0xEB,0xED,0x7F,0x5B,0xEB,0x00,0x81,0xE8,0x48,0xED,0x09,0x91,0x41,0x2C,0x17,0x21,0x0F,0xB7, +0xA2,0x0F,0x29,0xDC,0x4E,0x45,0x45,0x02,0x70,0x72,0x2F,0x6D,0x5A,0x99,0x81,0xCC,0x03,0xA3,0x95,0x68, +0xF7,0xC4,0xA1,0x64,0xFF,0x4C,0x55,0x9B,0x7B,0x3D,0xD9,0xD3,0xD7,0x39,0x06,0x68,0x9E,0x02,0xBA,0x55, +0xD5,0x37,0x13,0x16,0xDC,0x35,0xAA,0xA2,0xEC,0xF0,0xEE,0x28,0x42,0x59,0xF6,0x1A,0xC5,0xB0,0xBE,0x1F, +0xEB,0x66,0x61,0x4A,0xFB,0xCE,0xE6,0x66,0x1B,0x29,0xC5,0x31,0xBB,0xC1,0x8A,0x2B,0x0C,0xA1,0xCC,0x0D, +0x80,0xF0,0xE6,0xE6,0x3A,0xC6,0xC4,0x15,0xDB,0x97,0xB8,0xA2,0xE0,0xAE,0x65,0xF8,0xFB,0x9F,0xB8,0x53, +0x39,0xF2,0x21,0xAD,0x46,0xA6,0x25,0xB8,0xFF,0xFC,0x39,0x93,0x7F,0x57,0x02,0xBD,0xF4,0x97,0x55,0x77, +0xC1,0xD2,0x25,0xC0,0xF5,0xEE,0x7B,0x05,0x37,0xB3,0x39,0xE1,0x7E,0x28,0xF4,0xED,0xA3,0x0C,0xEB,0xE2, +0xA6,0xCE,0x95,0xAD,0xD9,0xA7,0xA2,0xF1,0x89,0x24,0x45,0x6B,0x8E,0x6E,0x8A,0x56,0x9C,0x6C,0x17,0xAD, +0x24,0x98,0xEA,0xAE,0x2A,0x12,0x37,0x9C,0x65,0xD1,0xE8,0x2F,0xE5,0xD6,0x47,0xAB,0x1A,0x3E,0x66,0x73, +0x2A,0x14,0x58,0x69,0x39,0x5A,0xB3,0xF7,0x75,0x0A,0xAB,0x9C,0x2E,0x28,0xF0,0xBA,0xD3,0x54,0xF9,0x5C, +0xC3,0x3F,0x4A,0x18,0x78,0x06,0x5E,0x9A,0xFF,0x97,0xD5,0xF8,0xCA,0x6A,0x56,0xF6,0x63,0x8D,0x90,0x47, +0x21,0xD4,0x92,0x7F,0x22,0x61,0xDC,0x5A,0x21,0xB6,0x7D,0xF1,0x7C,0xCD,0x02,0x19,0xFD,0x4C,0x2B,0x37, +0x62,0xEB,0x7F,0x34,0xB0,0xA4,0x65,0x60,0xED,0x4A,0x23,0x59,0xB3,0x6B,0x38,0xC2,0x1C,0x57,0x12,0x25, +0x6B,0x25,0x4A,0xFF,0x1F,0xCD,0xD7,0x61,0x89,0xA8,0x73,0x45,0x33,0x30,0x05,0xE4,0x46,0x87,0x04,0xED, +0xB5,0x29,0x64,0x7E,0xCA,0xA2,0x68,0xCC,0x92,0x83,0x07,0xC6,0xDD,0x6A,0xBC,0x68,0x94,0x6C,0xD6,0x53, +0x2C,0x7F,0x2D,0xD1,0x97,0x78,0xCA,0x0F,0x1E,0x02,0x3C,0x4C,0xB6,0x9E,0x63,0x05,0x1E,0xB6,0x41,0x79, +0x30,0xFA,0x73,0xC7,0xB7,0xB2,0xAA,0x77,0xD9,0x61,0xB0,0x17,0x7E,0xA9,0x24,0x4F,0x28,0xC9,0x22,0x6B, +0xF3,0x45,0x3D,0x1E,0x01,0x45,0x2F,0xE8,0xE8,0xC9,0x6D,0x3D,0xC6,0x59,0xE2,0x65,0x6A,0x08,0x19,0xC4, +0xE2,0xF7,0x36,0x65,0x5D,0x14,0x4F,0x3D,0x62,0xB3,0xE9,0x34,0xC3,0xFC,0x9D,0xC8,0x20,0x56,0x54,0xF5, +0x9F,0xCA,0x0C,0x32,0x80,0x2E,0x8D,0x59,0x9E,0x61,0x96,0xF3,0x76,0xAD,0x59,0x09,0xB3,0x17,0x7C,0xFE, +0x5C,0x75,0xF6,0x83,0x4E,0x5A,0x77,0x2F,0xF7,0xB2,0x46,0x67,0x3F,0xEB,0x44,0xE0,0x49,0xFF,0xB1,0xA5, +0x90,0xA6,0xA5,0x30,0x91,0xC0,0x2C,0xA6,0x2C,0x25,0xAD,0x6D,0x3D,0x15,0x27,0x01,0xD4,0x08,0xB1,0xC2, +0xA0,0x75,0xB3,0x3C,0xE4,0x36,0x5D,0x19,0x59,0x69,0xDB,0xD3,0x1F,0xAA,0xB6,0x03,0x43,0x50,0x05,0xAD, +0xBF,0x64,0x73,0x9C,0x1E,0xA1,0x0C,0x1B,0x10,0x79,0xAB,0x34,0x21,0xA1,0xA6,0x9B,0xAD,0x9D,0x45,0x0B, +0xA8,0xAF,0x9E,0x10,0x5E,0xBE,0x18,0x16,0x60,0x82,0x88,0x0B,0x6B,0x28,0x99,0x4B,0xC5,0x1D,0xA3,0xE2, +0xC4,0x04,0x1A,0xCA,0x5B,0x3C,0x62,0x5B,0x5C,0xF0,0x80,0xDE,0x8E,0xD5,0x01,0x11,0xCA,0x6B,0x0C,0xD6, +0xC2,0x92,0xB3,0x94,0x25,0x68,0x86,0xC4,0x3C,0x18,0x03,0x07,0x93,0xC4,0x05,0xB5,0x46,0x45,0x54,0x5F, +0x37,0x74,0xFB,0x1E,0xD8,0xAB,0xBC,0xCC,0x39,0x9D,0x1A,0x50,0x3B,0x99,0xF5,0xB4,0xE0,0xBF,0x4B,0x42, +0xFC,0x96,0x17,0xD9,0x25,0xE4,0x71,0xDD,0x8A,0x8A,0xE6,0xC7,0xAC,0x68,0xF8,0x59,0xD9,0xBA,0x6D,0x00, +0x19,0x2D,0xC1,0x8C,0x4E,0x8B,0x26,0xA1,0xA4,0xA4,0x53,0x02,0xCB,0x67,0x92,0x94,0x99,0x2C,0x2C,0x5B, +0x21,0xBE,0xAD,0xF0,0x58,0x95,0xE7,0xF0,0xBA,0x3C,0x57,0xDF,0xB2,0xFC,0x77,0xE2,0x27,0x74,0x56,0x0A, +0x93,0x94,0xAD,0x19,0x29,0x45,0x99,0xC4,0xC9,0x17,0x19,0x49,0xFF,0xE9,0xA9,0xEF,0xF8,0xE4,0xE5,0xC9, +0xF8,0xA4,0x79,0x00,0x68,0x5E,0x0E,0xF1,0x3F,0xBB,0x7D,0xE1,0xA6,0x6B,0xFC,0x85,0xA4,0x06,0x65,0xB7, +0x69,0xB6,0xEE,0x8F,0xA2,0xD6,0xBD,0x54,0x9D,0x51,0x8A,0x0B,0x1F,0xD0,0xD3,0xE6,0x66,0x83,0x11,0x39, +0x5E,0xDF,0x69,0x51,0x4B,0x57,0x55,0xB8,0xF4,0x6A,0xF4,0x50,0xB9,0x8A,0xCC,0xEA,0x40,0x48,0x3C,0x5A, +0x44,0x14,0x4B,0x9C,0x0D,0xC9,0xBE,0x0F,0x87,0xC2,0x8E,0xA9,0xEE,0x72,0x3C,0x0F,0xAE,0xBD,0xFC,0x2B, +0x79,0x1F,0xB0,0xB9,0x89,0xDA,0x25,0xAD,0xE1,0x58,0x12,0x28,0x16,0x94,0x2D,0x79,0x13,0x01,0xB2,0x00, +0x5B,0x8E,0xF5,0x7C,0x74,0xFA,0xDA,0x4E,0x50,0x0A,0x0E,0x49,0xCD,0x66,0x34,0xCA,0x95,0x80,0x6D,0x6D, +0x3F,0x39,0x69,0x9C,0xB5,0xE4,0xEB,0x3E,0x97,0x2F,0xAD,0xC8,0x10,0xE4,0x54,0x86,0x16,0x65,0x4F,0x71, +0x2F,0x0B,0x39,0x2E,0x2E,0xF3,0x5D,0x1D,0xAE,0xE2,0x66,0xB6,0xE0,0x37,0xF9,0x03,0xD7,0x09,0x3C,0x24, +0x59,0xF3,0x8C,0xD9,0x8A,0x0C,0x7F,0x71,0xC7,0x96,0x65,0x4B,0x91,0xBB,0x7F,0x5C,0x52,0xAF,0xA6,0xD5, +0xE6,0xC8,0xE3,0xF0,0xA2,0x0E,0xC5,0xB5,0x39,0xEA,0x90,0xC2,0x08,0xD5,0x2D,0xFA,0x77,0x3D,0x84,0x96, +0x1E,0x42,0x57,0x03,0x04,0xBE,0x6D,0x79,0x7B,0xB5,0xCA,0x60,0x02,0x9C,0x5D,0x0F,0xEA,0x28,0x02,0x10, +0x78,0x46,0x2D,0xC0,0xC7,0x4C,0x8E,0x7F,0x44,0x37,0x48,0x5D,0xCB,0xD6,0xD0,0xF5,0xA1,0x42,0x4E,0xF7, +0x7F,0x83,0x56,0x35,0xB3,0x1D,0x88,0x32,0x68,0xAE,0xC6,0x13,0xDE,0x0A,0x4F,0x75,0xCC,0x6A,0x46,0x27, +0x70,0xD7,0xC2,0x9B,0x35,0xDE,0xD0,0x6F,0xC3,0xF5,0xC0,0x20,0x1F,0xF2,0xBD,0x66,0x1C,0x56,0x18,0x4D, +0xEB,0x59,0x7F,0x18,0x6D,0x1F,0x57,0xD7,0xD7,0x19,0xD2,0xFF,0xF0,0x41,0x66,0x67,0xE5,0xC5,0x0C,0xB8, +0x79,0xA3,0xA7,0x83,0x41,0x64,0x60,0x86,0x18,0xA5,0x23,0x71,0x07,0xA0,0x12,0xC9,0x52,0x6D,0xA0,0x27, +0x5D,0xD7,0x00,0x8D,0xF5,0x64,0xCA,0xB0,0x41,0x0F,0x30,0xBF,0x02,0x52,0x00,0x52,0x8F,0x01,0xC9,0xC6, +0x20,0x82,0x41,0xE4,0xE9,0x31,0xA3,0xEC,0x1A,0x91,0xE6,0x74,0x02,0x10,0x52,0x7C,0x25,0xA0,0x77,0xA8, +0x55,0xEC,0x83,0x24,0x54,0x43,0xD4,0xEE,0x9B,0xC5,0x2D,0x67,0x7D,0xC7,0x84,0x4B,0xB7,0x29,0xEC,0x63, +0x43,0xA2,0x65,0xA2,0xF0,0x18,0xE1,0x2C,0x93,0x7C,0x0B,0xB9,0x5E,0xB1,0x00,0xC4,0x02,0xB4,0x5E,0x0C, +0x2D,0xB1,0x10,0x48,0x28,0x00,0xE3,0x10,0xC7,0x05,0x84,0x43,0x53,0x80,0x90,0x00,0x7D,0x2D,0x55,0x35, +0x92,0x05,0x1E,0xA1,0x33,0xAF,0xDF,0x73,0xAC,0x55,0xB2,0x17,0x19,0x1E,0xB1,0x29,0x1F,0xA3,0x49,0x66, +0x6C,0x38,0xE6,0xEA,0x0C,0x01,0x1A,0x41,0x34,0x31,0xB6,0xCC,0xF5,0xE8,0xEF,0x58,0x7A,0x8D,0xD3,0x02, +0x59,0x54,0x66,0x50,0x98,0x45,0xF0,0xCB,0x87,0xBE,0x78,0xD1,0xFF,0x92,0x50,0x5C,0x03,0x47,0x21,0x9B, +0x9F,0xA5,0x84,0xF2,0x57,0xF2,0xD0,0x6F,0x6C,0xF4,0xE5,0x3E,0xA9,0xBB,0x28,0x19,0x81,0xCA,0x4B,0xAA, +0x85,0x08,0x66,0x6E,0xEB,0xAA,0xCA,0x9A,0xC0,0x76,0x41,0x6C,0x75,0x17,0x73,0x42,0x5D,0xFD,0x88,0xA7, +0x51,0x77,0xA4,0x5B,0x31,0xF2,0xA1,0xA3,0xE6,0x40,0x7F,0x69,0x09,0xA7,0x75,0x9B,0xC1,0x64,0xA3,0xEE, +0xD4,0x85,0xFA,0xCA,0x3D,0x5E,0xFB,0x5A,0x4A,0x00,0x0F,0x23,0x36,0x31,0xC4,0x3B,0x87,0x85,0x70,0x78, +0x97,0x2E,0x4D,0x91,0x9D,0xBE,0x7C,0xE5,0xE6,0x43,0xD4,0xE5,0x16,0x6E,0xDC,0x18,0x76,0x74,0x5D,0x5C, +0xC4,0x01,0x1E,0x0A,0x4E,0x69,0x74,0xE7,0x42,0x56,0xFC,0x13,0xA9,0x73,0x1A,0xB0,0x2F,0x49,0xFD,0xFE, +0x9E,0xD4,0xEF,0xD7,0x49,0x8D,0xDB,0xBB,0x05,0x9D,0x0B,0x20,0xFB,0x0A,0x51,0x34,0xC3,0x29,0x0C,0x88, +0x45,0x60,0x03,0xFE,0x1E,0x67,0x29,0xFE,0x32,0x67,0xA3,0x90,0x4C,0xF9,0x0A,0x7F,0x72,0xF4,0x9F,0x71, +0x99,0xE2,0x07,0xB8,0x2C,0x0B,0xD9,0x2A,0x6D,0xFC,0xF9,0x3D,0x98,0x74,0x6A,0x0F,0xB6,0xB0,0xE9,0xAE, +0xFF,0xC0,0xEF,0xEA,0x15,0xBF,0x9C,0x3D,0xC5,0xC3,0xC5,0x4B,0x2B,0x10,0x36,0x01,0x12,0x34,0xF2,0x13, +0xA3,0x87,0x70,0x52,0x78,0x09,0x22,0x18,0xCA,0x1C,0xB1,0xB7,0x58,0x5A,0xDC,0x33,0xE6,0x04,0xC4,0x9F, +0x83,0x70,0xBE,0xAC,0x7E,0x6D,0xF1,0xCD,0x12,0x28,0x01,0x98,0x84,0x3C,0xDB,0xFB,0x70,0xB0,0x79,0xD5, +0x81,0x04,0xE5,0xC1,0xC3,0xF4,0xA0,0xB1,0x79,0xF5,0x9D,0xD9,0x9B,0x91,0x46,0x49,0x24,0x53,0x1D,0xE8, +0xF5,0x03,0xBD,0xF2,0xD0,0x12,0x42,0x58,0x33,0x15,0x56,0x81,0xD5,0xC2,0xF2,0x4A,0x13,0x1E,0xE2,0xB3, +0x30,0x78,0xC8,0xD8,0x01,0xB3,0xA9,0xD7,0xB8,0x69,0xD4,0x39,0xFC,0xD5,0x21,0x6C,0x0F,0x0A,0xB6,0x02, +0x3C,0x25,0x14,0xCB,0xE8,0xA5,0x9A,0x56,0x01,0x10,0x6A,0x20,0xA9,0x84,0x94,0x6D,0x4B,0xB4,0x45,0xF6, +0x23,0x33,0xA1,0x48,0x43,0x17,0x1F,0x7C,0x88,0x44,0xAF,0xCB,0x84,0xBD,0x02,0x9E,0xCB,0x40,0xD2,0x98, +0xB0,0xE6,0x05,0x9E,0x9E,0x17,0x2D,0x1D,0xA4,0xE4,0x8D,0x20,0xAC,0xC4,0x81,0x78,0xAB,0x1A,0xF7,0x42, +0x7B,0x7D,0xEA,0x51,0x60,0x73,0x09,0x2E,0xA6,0x04,0x08,0xF4,0x2A,0x9D,0xFF,0xFC,0xEA,0xE5,0x53,0xCE, +0x93,0x73,0xB5,0xA3,0x40,0xAB,0x3D,0x50,0x1B,0x9A,0xB9,0xE0,0xE9,0x5D,0x59,0x18,0x8A,0x40,0xA1,0x42, +0xDD,0xCF,0xA7,0x93,0x8F,0xD8,0x07,0x49,0x5E,0x65,0x90,0x43,0xB7,0x6C,0x81,0x3E,0x1E,0x9F,0xD9,0xBB, +0xB6,0x03,0x95,0x0A,0xEC,0xA7,0x1F,0x0A,0x8B,0x59,0xFE,0x2D,0xE4,0xED,0xBF,0x87,0x4C,0x20,0xDE,0x67, +0x10,0xD0,0x4B,0xFC,0x36,0x6E,0x98,0xB2,0xB9,0x44,0x3B,0x49,0x53,0x61,0x0C,0xE3,0x90,0x64,0xDA,0x04, +0x06,0x33,0x9C,0x6A,0x01,0xC3,0x99,0x46,0x19,0xD7,0xB2,0x3C,0x49,0x58,0xCA,0xEF,0xE9,0xC3,0xD6,0xCB, +0x4B,0x9A,0x37,0x39,0xCE,0x71,0x50,0x0C,0xE3,0xB4,0xA9,0x17,0x59,0xD3,0xC1,0x38,0xB8,0xDB,0x87,0xAB, +0xA2,0xC2,0xCB,0x29,0x15,0xF9,0x67,0xA3,0xAF,0xFA,0x20,0x5D,0x08,0x54,0x3D,0x9A,0x47,0xD1,0x72,0x70, +0x8F,0x96,0x9D,0xA4,0x8C,0x33,0xF9,0xD2,0x6B,0xF1,0x5B,0xE1,0x5A,0xEE,0xBD,0x6B,0xFA,0x36,0x55,0xC7, +0xDA,0x30,0x36,0xB0,0x46,0x68,0xC6,0x11,0xF5,0xC5,0x36,0x2A,0x5D,0x98,0x65,0x75,0x27,0xA6,0x0F,0x44, +0x5C,0x90,0x86,0xF3,0x60,0x49,0x21,0x25,0xA3,0x9E,0xAE,0x8B,0x42,0x0F,0x8B,0x7A,0x19,0xC5,0x59,0x83, +0x6C,0x95,0x29,0x4C,0xEA,0x95,0xE0,0x81,0x7C,0xB9,0xD2,0x9C,0xBF,0xCA,0x46,0x59,0xDD,0x23,0x80,0x69, +0xE5,0x3C,0x93,0x76,0x3C,0x5D,0x56,0x08,0x07,0x32,0x64,0x48,0x03,0x8E,0x31,0x0F,0x59,0x70,0xA0,0x1F, +0xE8,0xAE,0x0E,0xFF,0x37,0x75,0x0B,0x66,0x61,0xEA,0xB3,0x00,0x5F,0x9C,0x3F,0x83,0x50,0x9A,0x30,0x8A, +0x29,0x37,0x10,0x64,0x14,0x4F,0xEF,0xAC,0x42,0x2A,0x36,0x3E,0xA0,0x2B,0x73,0xD0,0x56,0x36,0x9E,0xDF, +0xDB,0xCE,0xD6,0x66,0xD8,0x8C,0x8A,0xE8,0x7A,0x07,0xCC,0x73,0xBC,0xF2,0x72,0xC4,0xA2,0xAB,0xA7,0x20, +0x73,0xB1,0x23,0x78,0x96,0x58,0x23,0xC0,0x12,0xAE,0x57,0x2B,0xF9,0xA1,0xCA,0x8E,0xDA,0x3E,0x8A,0x22, +0xF1,0x31,0x07,0xF0,0x2A,0x16,0xCB,0x33,0x4B,0x10,0xC9,0x40,0x80,0x0C,0x8F,0xF1,0x2D,0xB8,0xB4,0x2C, +0xCF,0x94,0x0D,0x15,0xC7,0x21,0x20,0xCD,0x1B,0x66,0x64,0x5A,0x55,0x6F,0x73,0x93,0xDB,0xA5,0x99,0x18, +0x25,0x52,0x26,0x92,0x8D,0xBC,0x7B,0x58,0x1A,0x4D,0x21,0x45,0xEE,0x5E,0xD1,0xB6,0xD1,0x56,0x43,0x82, +0xA9,0x51,0xC2,0x80,0xB3,0x3C,0x8D,0x20,0x43,0x88,0xEA,0xA5,0x35,0x2D,0xC3,0x34,0x80,0x05,0xDC,0x3F, +0x45,0x96,0xA8,0xB4,0x69,0x15,0x23,0x9E,0x2A,0xBE,0xDB,0xF4,0x78,0xB1,0x2B,0x4F,0xB1,0x0C,0x73,0xED, +0xEF,0x71,0x2D,0xF9,0x25,0x2D,0x51,0x09,0xA1,0x07,0x6F,0x53,0xE6,0xF3,0x2E,0x98,0x55,0xDC,0x85,0x15, +0x94,0x15,0x04,0xFA,0x1A,0x0E,0xD5,0x69,0xCF,0x12,0xD7,0x29,0xEE,0x3D,0x17,0xAD,0xF5,0x67,0xDC,0xF3, +0xD1,0x36,0x9D,0x36,0x9F,0x8D,0xDD,0xDE,0xDB,0xB9,0x07,0x42,0x13,0x96,0x72,0x03,0x72,0x1C,0xA4,0xC1, +0x6A,0xB5,0xF2,0xE0,0xD5,0x8C,0x0B,0x76,0x92,0x67,0xA1,0xB1,0x00,0xD6,0x5D,0x6E,0x29,0x5D,0xB9,0xD8, +0x52,0x76,0xEB,0x52,0xAB,0xB4,0x0F,0x17,0x52,0x57,0x2B,0x7E,0x7C,0xFE,0x2C,0x7B,0xF5,0x6E,0x43,0xAF, +0xBD,0xE1,0x20,0xAC,0x74,0xE2,0x32,0x23,0x0B,0xA3,0xBF,0x1F,0xAB,0xF6,0x7A,0xEA,0x3C,0x55,0x7E,0xEE, +0xA2,0x91,0xC0,0x13,0xC9,0x5D,0x57,0xEF,0xB5,0xEA,0x4F,0x83,0xA7,0x10,0x9D,0x6C,0x38,0x86,0x55,0xDF, +0x3D,0xEB,0xC5,0x87,0xCF,0xF7,0x29,0xEC,0x57,0xE7,0x42,0xCF,0xAB,0xAA,0x7A,0x15,0x7B,0xD4,0x04,0xEF, +0x81,0x4F,0x61,0x74,0x05,0x86,0x63,0xB3,0x6A,0xD8,0xF7,0x38,0x10,0xAB,0x5B,0x05,0x08,0x65,0x77,0xD4, +0x17,0x11,0xB4,0xA2,0x15,0xC2,0x56,0xB4,0x0E,0xD4,0x6A,0xA6,0xB9,0xAC,0xF9,0x13,0x57,0x91,0x1A,0x2B, +0xDE,0x40,0x34,0xEB,0x0D,0x10,0x02,0xCE,0xEB,0x42,0xF4,0xD2,0x5D,0x35,0x79,0x60,0xAF,0xBA,0x20,0x24, +0x4C,0xA8,0x67,0xE5,0xC9,0x7A,0x80,0x2C,0x0F,0x56,0x06,0x55,0x85,0xB1,0x32,0x5C,0x1C,0xFA,0xAA,0xF7, +0x82,0x8D,0x6F,0x99,0x6A,0x1A,0x44,0xBE,0x46,0x91,0xF3,0xDB,0x6F,0x56,0x1E,0x44,0x53,0x18,0xFB,0x7F, +0x00,0x47,0x16,0x74,0xBA,0xF2,0x2E,0x00,0x00 }; From 96b25b3f20c2a09d9a8d399a323adef75a30cab9 Mon Sep 17 00:00:00 2001 From: Dmytro Korniienko Date: Sat, 12 Sep 2020 20:05:39 +0300 Subject: [PATCH 073/551] extra script :) --- extras/do2.bat | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 extras/do2.bat diff --git a/extras/do2.bat b/extras/do2.bat new file mode 100644 index 000000000..4e02f84ba --- /dev/null +++ b/extras/do2.bat @@ -0,0 +1,5 @@ +copy ..\src\edit.htm edit.htm +"C:\Program Files\7-Zip\7z.exe" a -tgzip -mx9 edit.htm.gz edit.htm +ehg edit.htm.gz PROGMEM +copy edit.htm.gz.h ..\src\edit.htm.gz.h +pause From fa232d50fe79a96c97ba515accae057c2c69800f Mon Sep 17 00:00:00 2001 From: Dmytro Korniienko Date: Sat, 12 Sep 2020 21:00:34 +0300 Subject: [PATCH 074/551] _onAck small fix --- src/WebRequest.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/WebRequest.cpp b/src/WebRequest.cpp index 6d79726e1..0200ce987 100644 --- a/src/WebRequest.cpp +++ b/src/WebRequest.cpp @@ -210,8 +210,7 @@ void AsyncWebServerRequest::_onAck(size_t len, uint32_t time){ if(_response != NULL){ if(!_response->_finished()){ _response->_ack(this, len, time); - } - if(_response->_finished()){ + } else if(_response->_finished()){ AsyncWebServerResponse* r = _response; _response = NULL; delete r; From 1ce5cabfeb686c63f0ddb10618f2d295c6a5b9b5 Mon Sep 17 00:00:00 2001 From: lorol Date: Wed, 23 Sep 2020 14:40:34 -0400 Subject: [PATCH 075/551] A logic bugfix of SmartSwitch.ino sketch. Reverting the PR idea of ACE editor' supporting fles to be moved to sf data/extras subfolder, moved back to root fs. (workers didn't work this way) edit.htm can be binary-embedded in a firmware or a in gzipped file on fs (saves 4k of program storage, RAM usage is identical) To embed: Comment #define EDFS in SPIFFSEditor.cpp and run do_emb.bat On fs: Enable #define EDFS in SPIFFSEditor.cpp and run do_ed_fs.bat --- .../ESP_AsyncFSBrowser/data/.exclude.files | 1 + .../data/{extras => }/ace.ico.gz | Bin .../data/{extras => }/acefull.js.gz | Bin 117524 -> 117524 bytes examples/ESP_AsyncFSBrowser/data/edit.htm | Bin 0 -> 4503 bytes .../data/extras/edit.htm.gz | Bin 4509 -> 0 bytes .../data/extras/mode-json.js.gz | Bin 2983 -> 0 bytes .../data/extras/worker-json.js.gz | Bin 8712 -> 0 bytes .../data}/worker-css.js.gz | Bin 32927 -> 32927 bytes .../data/{extras => }/worker-html.js.gz | Bin 45019 -> 45019 bytes .../data/{extras => }/worker-javascript.js.gz | Bin 112558 -> 112558 bytes examples/SmartSwitch/SmartSwitch.ino | 4 +- examples/SmartSwitch/data/.exclude.files | 1 + .../SmartSwitch/data/{extras => }/ace.ico.gz | Bin .../data/{extras => }/acefull.js.gz | Bin 117524 -> 117524 bytes examples/SmartSwitch/data/edit.htm | Bin 0 -> 4503 bytes examples/SmartSwitch/data/extras/edit.htm.gz | Bin 4509 -> 0 bytes .../SmartSwitch/data/extras/mode-json.js.gz | Bin 2983 -> 0 bytes .../SmartSwitch/data/extras/worker-json.js.gz | Bin 8712 -> 0 bytes .../data}/worker-css.js.gz | Bin 32927 -> 32927 bytes .../data/{extras => }/worker-html.js.gz | Bin 45019 -> 45019 bytes .../data/{extras => }/worker-javascript.js.gz | Bin 112558 -> 112558 bytes extras/do2.bat | 5 - extras/do_ed_fs.bat | 9 + extras/{do.bat => do_emb.bat} | 14 +- src/SPIFFSEditor.cpp | 20 +- src/edit.htm | 582 +++++++++++++++++- src/edit.htm.gz.h | 454 +++++++------- 27 files changed, 842 insertions(+), 248 deletions(-) rename examples/ESP_AsyncFSBrowser/data/{extras => }/ace.ico.gz (100%) rename examples/ESP_AsyncFSBrowser/data/{extras => }/acefull.js.gz (99%) create mode 100644 examples/ESP_AsyncFSBrowser/data/edit.htm delete mode 100644 examples/ESP_AsyncFSBrowser/data/extras/edit.htm.gz delete mode 100644 examples/ESP_AsyncFSBrowser/data/extras/mode-json.js.gz delete mode 100644 examples/ESP_AsyncFSBrowser/data/extras/worker-json.js.gz rename examples/{SmartSwitch/data/extras => ESP_AsyncFSBrowser/data}/worker-css.js.gz (99%) rename examples/ESP_AsyncFSBrowser/data/{extras => }/worker-html.js.gz (99%) rename examples/ESP_AsyncFSBrowser/data/{extras => }/worker-javascript.js.gz (99%) rename examples/SmartSwitch/data/{extras => }/ace.ico.gz (100%) rename examples/SmartSwitch/data/{extras => }/acefull.js.gz (99%) create mode 100644 examples/SmartSwitch/data/edit.htm delete mode 100644 examples/SmartSwitch/data/extras/edit.htm.gz delete mode 100644 examples/SmartSwitch/data/extras/mode-json.js.gz delete mode 100644 examples/SmartSwitch/data/extras/worker-json.js.gz rename examples/{ESP_AsyncFSBrowser/data/extras => SmartSwitch/data}/worker-css.js.gz (99%) rename examples/SmartSwitch/data/{extras => }/worker-html.js.gz (99%) rename examples/SmartSwitch/data/{extras => }/worker-javascript.js.gz (99%) delete mode 100644 extras/do2.bat create mode 100644 extras/do_ed_fs.bat rename extras/{do.bat => do_emb.bat} (82%) diff --git a/examples/ESP_AsyncFSBrowser/data/.exclude.files b/examples/ESP_AsyncFSBrowser/data/.exclude.files index 955397fa2..ba74486a2 100644 --- a/examples/ESP_AsyncFSBrowser/data/.exclude.files +++ b/examples/ESP_AsyncFSBrowser/data/.exclude.files @@ -1,2 +1,3 @@ /*.js.gz +/edit.htm /.exclude.files diff --git a/examples/ESP_AsyncFSBrowser/data/extras/ace.ico.gz b/examples/ESP_AsyncFSBrowser/data/ace.ico.gz similarity index 100% rename from examples/ESP_AsyncFSBrowser/data/extras/ace.ico.gz rename to examples/ESP_AsyncFSBrowser/data/ace.ico.gz diff --git a/examples/ESP_AsyncFSBrowser/data/extras/acefull.js.gz b/examples/ESP_AsyncFSBrowser/data/acefull.js.gz similarity index 99% rename from examples/ESP_AsyncFSBrowser/data/extras/acefull.js.gz rename to examples/ESP_AsyncFSBrowser/data/acefull.js.gz index 4b10ee879cb1238a59fb0f23064da41ba4b6da28..560a0fa10d7a284b356f160f982d03407cc61502 100644 GIT binary patch delta 21 dcmbO-jeW{Ac6Rx04i1Lt*^TU5*%^6H0{}=1215V< delta 21 dcmbO-jeW{Ac6Rx04vwM;UXAQq*%^6H0{}}n28{p! diff --git a/examples/ESP_AsyncFSBrowser/data/edit.htm b/examples/ESP_AsyncFSBrowser/data/edit.htm new file mode 100644 index 0000000000000000000000000000000000000000..95099096172853e05dce9881d28b499dd0ebddd4 GIT binary patch literal 4503 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 literal 0 HcmV?d00001 diff --git a/examples/ESP_AsyncFSBrowser/data/extras/edit.htm.gz b/examples/ESP_AsyncFSBrowser/data/extras/edit.htm.gz deleted file mode 100644 index 3d4fa14a97812370a5a6b55d7ddad8b582ea444c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4509 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 diff --git a/examples/ESP_AsyncFSBrowser/data/extras/mode-json.js.gz b/examples/ESP_AsyncFSBrowser/data/extras/mode-json.js.gz deleted file mode 100644 index a13781b95dc2cf63ba25697c8ca7724952155b07..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2983 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 diff --git a/examples/ESP_AsyncFSBrowser/data/extras/worker-json.js.gz b/examples/ESP_AsyncFSBrowser/data/extras/worker-json.js.gz deleted file mode 100644 index 50719211195dba380260a94e1de2ecb4108be34e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8712 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 diff --git a/examples/SmartSwitch/data/extras/worker-css.js.gz b/examples/ESP_AsyncFSBrowser/data/worker-css.js.gz similarity index 99% rename from examples/SmartSwitch/data/extras/worker-css.js.gz rename to examples/ESP_AsyncFSBrowser/data/worker-css.js.gz index 97beeb133712d3e716a32b360301942afee6ae4a..1d108b743445f6c759767729403589f3656a123f 100644 GIT binary patch delta 18 ZcmbQ=$TYu^iCw;%gX90S?2YU*8UQ^e2G#%o delta 18 ZcmbQ=$TYu^iCw;%gQIYQ*GBdk4FEWM1|a|d diff --git a/examples/ESP_AsyncFSBrowser/data/extras/worker-html.js.gz b/examples/ESP_AsyncFSBrowser/data/worker-html.js.gz similarity index 99% rename from examples/ESP_AsyncFSBrowser/data/extras/worker-html.js.gz rename to examples/ESP_AsyncFSBrowser/data/worker-html.js.gz index 819a3b7842296f34a262479417b33cc94809069b..8bacd4aaa83b52d87a0ee63ff1977aea05c24816 100644 GIT binary patch delta 18 acmcb8pXv5}CU*I54vv4*vNy6{Sq}hEON once + if (((t + HYST) < ee.tempe)&&(ledState == LED_OFF)) { // OFF->ON once ledState = LED_ON; digitalWrite(ledPin, ledState); // apply change ws.textAll("led,ledon"); } - if ((((t + HYST) > ee.tempe)&&(ledState == LED_ON))||(!heat_enabled)) { // ON->OFF once, also turn off at end of period. + if ((((t - HYST) > ee.tempe)&&(ledState == LED_ON))||(!heat_enabled)) { // ON->OFF once, also turn off at end of period. ledState = LED_OFF; digitalWrite(ledPin, ledState); // apply change ws.textAll("led,ledoff"); diff --git a/examples/SmartSwitch/data/.exclude.files b/examples/SmartSwitch/data/.exclude.files index 4aacf0d7a..664e3b71e 100644 --- a/examples/SmartSwitch/data/.exclude.files +++ b/examples/SmartSwitch/data/.exclude.files @@ -1,2 +1,3 @@ /*.gz +/edit.htm /.exclude.files diff --git a/examples/SmartSwitch/data/extras/ace.ico.gz b/examples/SmartSwitch/data/ace.ico.gz similarity index 100% rename from examples/SmartSwitch/data/extras/ace.ico.gz rename to examples/SmartSwitch/data/ace.ico.gz diff --git a/examples/SmartSwitch/data/extras/acefull.js.gz b/examples/SmartSwitch/data/acefull.js.gz similarity index 99% rename from examples/SmartSwitch/data/extras/acefull.js.gz rename to examples/SmartSwitch/data/acefull.js.gz index 4b10ee879cb1238a59fb0f23064da41ba4b6da28..560a0fa10d7a284b356f160f982d03407cc61502 100644 GIT binary patch delta 21 dcmbO-jeW{Ac6Rx04i1Lt*^TU5*%^6H0{}=1215V< delta 21 dcmbO-jeW{Ac6Rx04vwM;UXAQq*%^6H0{}}n28{p! diff --git a/examples/SmartSwitch/data/edit.htm b/examples/SmartSwitch/data/edit.htm new file mode 100644 index 0000000000000000000000000000000000000000..95099096172853e05dce9881d28b499dd0ebddd4 GIT binary patch literal 4503 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 literal 0 HcmV?d00001 diff --git a/examples/SmartSwitch/data/extras/edit.htm.gz b/examples/SmartSwitch/data/extras/edit.htm.gz deleted file mode 100644 index 3d4fa14a97812370a5a6b55d7ddad8b582ea444c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4509 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 diff --git a/examples/SmartSwitch/data/extras/mode-json.js.gz b/examples/SmartSwitch/data/extras/mode-json.js.gz deleted file mode 100644 index a13781b95dc2cf63ba25697c8ca7724952155b07..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2983 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 diff --git a/examples/SmartSwitch/data/extras/worker-json.js.gz b/examples/SmartSwitch/data/extras/worker-json.js.gz deleted file mode 100644 index 50719211195dba380260a94e1de2ecb4108be34e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8712 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 diff --git a/examples/ESP_AsyncFSBrowser/data/extras/worker-css.js.gz b/examples/SmartSwitch/data/worker-css.js.gz similarity index 99% rename from examples/ESP_AsyncFSBrowser/data/extras/worker-css.js.gz rename to examples/SmartSwitch/data/worker-css.js.gz index 97beeb133712d3e716a32b360301942afee6ae4a..1d108b743445f6c759767729403589f3656a123f 100644 GIT binary patch delta 18 ZcmbQ=$TYu^iCw;%gX90S?2YU*8UQ^e2G#%o delta 18 ZcmbQ=$TYu^iCw;%gQIYQ*GBdk4FEWM1|a|d diff --git a/examples/SmartSwitch/data/extras/worker-html.js.gz b/examples/SmartSwitch/data/worker-html.js.gz similarity index 99% rename from examples/SmartSwitch/data/extras/worker-html.js.gz rename to examples/SmartSwitch/data/worker-html.js.gz index 819a3b7842296f34a262479417b33cc94809069b..8bacd4aaa83b52d87a0ee63ff1977aea05c24816 100644 GIT binary patch delta 18 acmcb8pXv5}CU*I54vv4*vNy6{Sq}hE -//#include "edit.htm.gz.h" // moved to FS +#define EDFS + +#ifndef EDFS + #include "edit.htm.gz.h" +#endif #ifdef ESP32 #define fullName(x) name(x) @@ -232,16 +236,18 @@ void SPIFFSEditor::handleRequest(AsyncWebServerRequest *request){ if (request->header(F("If-Modified-Since")).equals(buildTime)) { request->send(304); } else { - request->send(_fs, F("/extras/edit.htm"), String(F("text/html")), false); - // AsyncWebServerResponse *response = request->beginResponse_P(200, "text/html", edit_htm_gz, edit_htm_gz_len); - // response->addHeader("Content-Encoding", "gzip"); - // response->addHeader("Last-Modified", buildTime); - // request->send(response); +#ifdef EDFS + AsyncWebServerResponse *response = request->beginResponse(_fs, F("/edit.htm"), F("text/html"), false); +#else + AsyncWebServerResponse *response = request->beginResponse_P(200, F("text/html"), edit_htm_gz, edit_htm_gz_len); +#endif + response->addHeader(F("Content-Encoding"), F("gzip")); + response->addHeader(F("Last-Modified"), buildTime); + request->send(response); } } } else if(request->method() == HTTP_DELETE){ if(request->hasParam(F("path"), true)){ - if(!(_fs.remove(request->getParam(F("path"), true)->value()))){ #ifdef ESP32 _fs.rmdir(request->getParam(F("path"), true)->value()); // try rmdir for littlefs diff --git a/src/edit.htm b/src/edit.htm index e3eeac354..5d497ea45 100644 --- a/src/edit.htm +++ b/src/edit.htm @@ -1 +1,581 @@ -ESP Editor
\ No newline at end of file + + + + + ESP Editor + + + + + + + + + + +
+
+
+
+ + + + \ No newline at end of file diff --git a/src/edit.htm.gz.h b/src/edit.htm.gz.h index 49ab77ab4..7b9c3b3ca 100644 --- a/src/edit.htm.gz.h +++ b/src/edit.htm.gz.h @@ -1,231 +1,231 @@ -//File: edit.htm.gz, Size: 4509 -#define edit_htm_gz_len 4509 +//File: edit.htm.gz, Size: 4503 +#define edit_htm_gz_len 4503 const uint8_t edit_htm_gz[] PROGMEM = { -0x1F,0x8B,0x08,0x08,0x76,0xDF,0x5C,0x5F,0x02,0x00,0x65,0x64,0x69,0x74,0x2E,0x68,0x74,0x6D,0x00,0xB5, -0x1A,0x0B,0x5B,0xDB,0x36,0xF0,0xAF,0x18,0x6F,0x63,0xF6,0xE2,0x38,0x0E,0x50,0xD6,0x39,0x18,0x16,0x1E, +0x1F,0x8B,0x08,0x08,0x2A,0x97,0x6B,0x5F,0x02,0x00,0x65,0x64,0x69,0x74,0x2E,0x68,0x74,0x6D,0x00,0xB5, +0x1A,0x0B,0x5B,0xDB,0x36,0xF0,0xAF,0x18,0x6F,0x63,0xF6,0xE2,0x38,0x0E,0x50,0xD6,0x3A,0x18,0x16,0x1E, 0xEB,0xBB,0x50,0x12,0xDA,0xD1,0x8E,0xED,0x53,0x6C,0x25,0x56,0xB1,0x25,0xCF,0x96,0x09,0x34,0xCD,0x7F, -0xDF,0x49,0xF2,0x93,0x84,0xEE,0x5D,0x0A,0x96,0x74,0xBA,0xD3,0xDD,0xE9,0x5E,0x92,0xBD,0xB7,0x71,0x7C, -0x7A,0x34,0xBE,0x3C,0x3B,0xD1,0x42,0x1E,0x47,0xFB,0x7B,0xE2,0xAF,0x16,0x21,0x3A,0xF3,0x74,0x4C,0xF5, -0xFD,0xBD,0x18,0x73,0x04,0x20,0x9E,0x74,0xF1,0xEF,0x39,0xB9,0xF1,0xF4,0x23,0x46,0x39,0xA6,0xBC,0xCB, -0xEF,0x12,0xAC,0x6B,0xBE,0xEA,0x79,0x3A,0xC7,0xB7,0xBC,0x27,0x90,0x07,0x9A,0x1F,0xA2,0x34,0xC3,0xDC, -0xCB,0xF9,0xB4,0xFB,0x18,0x48,0x70,0xC2,0x23,0xBC,0x7F,0x32,0x3A,0xD3,0x4E,0x02,0xC2,0x59,0xBA,0xD7, -0x53,0x23,0x7B,0x11,0xA1,0xD7,0x5A,0x8A,0x23,0x4F,0x47,0x49,0x12,0xE1,0x2E,0x67,0xB9,0x1F,0x76,0x09, -0xD0,0xD4,0xB5,0x30,0xC5,0x53,0x4F,0x07,0xA2,0x29,0xCA,0x7A,0xC8,0xC7,0x36,0x0C,0xEB,0x9A,0x58,0xD4, -0xD3,0x49,0x8C,0x66,0xB8,0x77,0xAB,0x66,0x36,0xC9,0x64,0x21,0x4B,0xB9,0x9F,0x73,0xED,0x5F,0xD0,0xF8, -0xDB,0xA8,0x19,0xBF,0x8B,0xB0,0x02,0x29,0x2D,0xF8,0x59,0xA6,0x6B,0x31,0x0E,0x08,0x02,0x8E,0xFC,0x14, -0x0B,0x3D,0x46,0x68,0x82,0xA3,0xC5,0x94,0x81,0xE2,0x32,0xF2,0x09,0xBB,0xFD,0xAD,0xE4,0x76,0x20,0xBB, -0x53,0x14,0x93,0xE8,0xCE,0xCD,0x10,0xCD,0xBA,0x19,0x4E,0xC9,0x74,0x69,0xFB,0xF1,0xE2,0x53,0x97,0xD0, -0x00,0xDF,0xBA,0xDB,0x8E,0x33,0x48,0x58,0x46,0x38,0x61,0xD4,0x45,0x93,0x8C,0x45,0x39,0xC7,0x83,0x08, -0x4F,0xB9,0xFB,0x08,0x28,0x4C,0x58,0x1A,0xE0,0xD4,0xED,0x27,0xB7,0x1A,0x80,0x48,0xA0,0x7D,0xB5,0xB3, -0xB3,0x33,0x98,0x20,0xFF,0x7A,0x96,0xB2,0x9C,0x06,0x5D,0x9F,0x45,0x2C,0x75,0xBF,0x9A,0x3E,0x12,0x3F, -0x83,0x80,0x64,0x49,0x84,0xEE,0x5C,0xCA,0x28,0x06,0xDC,0xDB,0x6E,0x16,0xA2,0x80,0xCD,0x5D,0x47,0x73, -0xB4,0xBE,0x03,0x44,0xD2,0xD9,0x04,0x19,0x8E,0x25,0x7E,0xEC,0x1D,0x73,0xF0,0x97,0xF8,0x55,0xC3,0x73, -0x4C,0x66,0x21,0x77,0xBF,0x77,0x1C,0xC1,0xBF,0x96,0x47,0x8B,0x88,0x64,0xBC,0x2B,0x95,0xA3,0xD6,0xE3, -0x2C,0x71,0x1D,0xC9,0x3A,0x3C,0x62,0x94,0xCE,0x08,0x85,0x46,0x82,0x82,0x80,0xD0,0x99,0xAB,0xD0,0x22, -0xB2,0xA8,0xA4,0x85,0xDD,0x40,0x9C,0xDC,0xE0,0x41,0x4C,0x68,0x77,0x4E,0x02,0x1E,0xBA,0xBB,0x0E,0x70, -0xE1,0xE7,0x69,0x06,0x32,0x25,0x8C,0x50,0x8E,0x53,0x89,0x96,0x25,0x88,0x2E,0x94,0xA8,0x42,0x01,0x95, -0x9C,0x84,0xC2,0xBE,0xE2,0xEE,0x24,0x62,0xFE,0x75,0xB5,0xD2,0x6E,0x72,0x5B,0xAC,0xE5,0x86,0xEC,0x06, -0xA7,0x8B,0x5A,0x5D,0x12,0xBB,0x05,0x6C,0x91,0xC6,0x18,0x2F,0x6D,0x7E,0x93,0x03,0xD4,0x92,0x4F,0x90, -0xB2,0xA0,0xDA,0x14,0xA9,0x2D,0x78,0x81,0x42,0x68,0x92,0xF3,0xC5,0xEA,0x56,0xB2,0x04,0xF9,0x84,0xDF, -0xB9,0x8E,0x9C,0x26,0x2D,0xC4,0xDD,0x71,0x1C,0x4D,0x28,0x5C,0x7B,0x8B,0xD3,0x00,0x51,0x64,0x0D,0x53, -0x82,0x22,0x6B,0x54,0xAB,0xBC,0x1B,0xB3,0x4F,0xDD,0x1C,0xDA,0xD0,0x8F,0xB0,0xCF,0x95,0x86,0x61,0x13, -0x26,0xD7,0x84,0xAF,0x02,0x56,0x06,0x1A,0xBA,0x92,0x1A,0x0A,0xD5,0xEE,0xF5,0x41,0x37,0x92,0x0F,0x25, -0xB6,0x92,0xA8,0x3B,0x61,0x9C,0xB3,0x58,0xDA,0x5B,0x25,0xAD,0x26,0x4D,0xE6,0xF1,0xCA,0x76,0xAC,0x57, -0x7D,0x83,0xFC,0x00,0x94,0xCA,0x89,0x8F,0xA2,0x2E,0x8A,0xC8,0x8C,0xBA,0x31,0x09,0x82,0x08,0x37,0x4C, -0xD6,0xCD,0xD3,0xC8,0x08,0x10,0x47,0xAE,0xF2,0xB3,0x84,0xCE,0x00,0x9A,0xE1,0xDD,0x1D,0x8B,0xBC,0x3D, -0x3C,0x3D,0x9F,0x3B,0x2F,0x9E,0xCC,0xD8,0x10,0xFE,0xBD,0x1E,0x5D,0x84,0x27,0x17,0x33,0x68,0x1D,0x8A, -0xEE,0xF0,0xCD,0xD1,0xF0,0x0D,0x3C,0x8E,0xFA,0x9D,0x8F,0xD3,0xDF,0x87,0x62,0xF8,0x49,0x70,0x38,0xBE, -0x38,0x19,0x0E,0x5F,0xF4,0x9E,0xBD,0x9E,0xBF,0x7B,0xB1,0x2B,0xC0,0x87,0x91,0x73,0xFE,0x36,0x74,0x2E, -0xB6,0x7E,0x88,0x83,0xA7,0x41,0xE8,0xC7,0x17,0xC3,0x37,0xEF,0xCE,0x6F,0x2E,0xE3,0x8B,0xD9,0xE8,0x5D, -0x3F,0x7C,0xBF,0xF5,0x76,0xF4,0xFE,0xDD,0x4F,0xD7,0xF8,0xE7,0xA7,0xCF,0xDF,0x8F,0xE7,0x80,0x70,0xCC, -0x46,0x17,0xE7,0x87,0x6F,0x0F,0x67,0xEF,0x0F,0xFD,0x93,0xDB,0x49,0xF4,0xFA,0xF0,0xC9,0x70,0x32,0xDC, -0xF2,0x31,0x9E,0x8D,0xCF,0x0F,0xF3,0x67,0x2F,0x4E,0x67,0x84,0x84,0xA3,0xF7,0xAF,0xC7,0xFE,0xD1,0xA3, -0x97,0x17,0x4F,0x87,0x24,0x7C,0xFD,0xFC,0xDC,0xB9,0x7E,0xF2,0xE2,0xE8,0xD8,0xBF,0x7C,0x7E,0xB9,0x7B, -0xBC,0xDD,0xFB,0xFE,0xFB,0x57,0xC1,0x29,0xA1,0xE3,0x9B,0x4F,0xC3,0xD9,0xD1,0xFC,0xF1,0x5D,0x36,0x0E, -0x9F,0xDD,0xD0,0xDE,0x5B,0xF6,0xF1,0xD9,0xDD,0x2B,0xF8,0x3D,0x3B,0xEB,0x4C,0x46,0xFD,0xEC,0xE2,0xCD, -0xB3,0xB7,0x5B,0xD9,0x0F,0x8F,0x92,0xC3,0xE3,0xE3,0x9B,0x78,0x72,0xD6,0x8B,0x83,0xEB,0x29,0x7F,0xBC, -0xCD,0x93,0xCB,0x59,0xFE,0xFE,0xF7,0x47,0xCF,0xC3,0xDE,0x29,0x46,0x97,0x61,0xE7,0xEE,0xD3,0xDD,0xE3, -0x70,0xFC,0xF4,0xE6,0x75,0x84,0x6E,0x5F,0xBF,0xF6,0x3F,0xC5,0x9D,0x08,0xFD,0x70,0x3A,0x8E,0x50,0xDA, -0xBF,0x08,0x86,0xBD,0xCE,0xD1,0xD6,0x70,0x87,0xA7,0xE7,0x47,0xF4,0x78,0xFB,0xE3,0xE8,0xF1,0xE1,0x61, -0x9F,0x4D,0x7E,0xDF,0x7A,0x72,0xBD,0xFB,0xE4,0x62,0xF7,0xCD,0xE4,0xCD,0x70,0xB4,0x73,0x78,0x81,0x2E, -0x47,0x6F,0x86,0xD3,0x9D,0x49,0x18,0xBE,0x78,0x31,0xFE,0x29,0x18,0x7E,0x4A,0x87,0xA7,0xF3,0xE1,0xED, -0xC9,0xC5,0xF0,0x69,0xE7,0xC5,0xC9,0x2B,0xA7,0x3F,0xBA,0xDC,0x9E,0xBD,0xDA,0x9D,0x1F,0x66,0x27,0xC3, -0x37,0x87,0xCE,0xEC,0x79,0x27,0x46,0xEF,0xD9,0xD1,0xF6,0xEC,0xD9,0x2E,0x39,0xBB,0x44,0xC3,0x67,0x87, -0xCF,0x33,0x72,0x1E,0x3F,0xBD,0x70,0x86,0xC3,0x97,0xA7,0xF8,0xA7,0xA3,0x6D,0xF4,0x62,0xCB,0x7F,0x07, -0xFA,0xBF,0xF8,0x19,0x7F,0xDF,0x19,0xCE,0x4F,0x9D,0xC8,0xFF,0x01,0x8F,0x9F,0x5E,0x8E,0xE5,0xEE,0x9C, -0x44,0x3F,0x8D,0xAF,0x47,0xF9,0x9B,0xF8,0xE8,0xC8,0xD4,0x28,0xEB,0xA6,0x38,0xC1,0x88,0x37,0x63,0x55, -0xE5,0x1C,0x60,0x5B,0xB5,0x15,0x16,0x4E,0x2A,0x22,0x6B,0x37,0xC0,0x3E,0x4B,0x91,0x9C,0x03,0x08,0x38, -0x15,0x26,0xB6,0xFC,0x51,0x86,0x5A,0x4D,0x45,0x5A,0x0D,0xD1,0x40,0x33,0x4A,0x47,0x88,0x09,0x05,0x9C, -0x1B,0xE2,0xE3,0x6E,0x42,0x6E,0x71,0xD4,0x95,0xC8,0xAE,0x63,0x2E,0xA4,0xB3,0x95,0xD3,0x10,0x25,0xB1, -0xA2,0x5A,0x0E,0x04,0x1F,0x91,0x2F,0x92,0x1C,0xB8,0x4C,0x0C,0xCF,0xC2,0x77,0x58,0xDA,0x9D,0xE4,0xB3, -0x29,0xB9,0x05,0x6F,0x9E,0x12,0x4A,0x38,0xD6,0xFA,0xD9,0xF2,0xC7,0x92,0xCC,0x35,0xBE,0x9B,0xA6,0x28, -0xC6,0x99,0xF6,0x17,0xC9,0x2C,0xA6,0x29,0x8B,0x17,0x75,0x04,0xE4,0xAC,0xD1,0x59,0x2E,0xBF,0xCA,0x93, -0x88,0x21,0x10,0x73,0x25,0x6C,0x94,0xC1,0x34,0x15,0x6E,0x55,0x05,0xD5,0xD2,0xCD,0xB6,0xC0,0x2D,0x5B, -0x6E,0xBD,0xB5,0x53,0xBB,0x6E,0x57,0xCE,0x15,0xC1,0xBE,0xA9,0xFA,0x46,0x3C,0x68,0xC4,0xBA,0xAF,0x38, -0xA8,0x74,0xFD,0xE2,0x6A,0x11,0x15,0x19,0x6A,0x06,0x54,0x94,0xEE,0xEF,0x3A,0x8D,0x50,0x01,0xF3,0x96, -0x5F,0x61,0x99,0xF8,0xAD,0xAF,0x92,0x14,0x76,0x03,0xCF,0xBF,0x40,0xB3,0x92,0xA9,0x4D,0x1B,0x68,0x56, -0xE9,0x4E,0x89,0x50,0xE7,0x3C,0xC9,0x6B,0x45,0x7A,0x55,0x2A,0x00,0x57,0xDC,0x3C,0x12,0xDC,0x7C,0x51, -0xAB,0xDB,0xBB,0xDF,0x14,0x3C,0xEC,0x38,0xDF,0x2C,0x6D,0x35,0xB7,0xCA,0xC7,0x7D,0x07,0xFE,0x95,0x69, -0xF7,0x71,0xCD,0xC2,0xE4,0x91,0xF8,0x29,0x19,0x04,0x3A,0x4D,0xE0,0xF6,0xCE,0x0F,0x8F,0x83,0x49,0x09, -0x54,0x82,0x3D,0x0C,0x4F,0x51,0x40,0xF2,0xCC,0x7D,0xE4,0x7C,0xA3,0xF4,0x09,0xDB,0x07,0xB2,0x97,0x9B, -0xAB,0x3A,0xB5,0xC5,0x66,0x09,0xA1,0xDA,0x56,0xA6,0x89,0xFD,0x46,0x69,0x65,0x98,0xCD,0x54,0x0F,0x2E, -0x52,0x9B,0xA6,0x98,0xBF,0x70,0xBE,0x59,0xF0,0x14,0xD1,0x6C,0xCA,0xD2,0xD8,0x4D,0x19,0x47,0x1C,0x1B, -0x8E,0xB9,0xEC,0x3B,0xEB,0x00,0xDB,0xBB,0x4E,0x80,0x67,0xE6,0x72,0xB9,0xD7,0x93,0x49,0x0D,0x2A,0x1E, -0x3F,0x25,0x09,0xDF,0x9F,0xE6,0xD4,0x17,0x3C,0x68,0x33,0x6C,0x60,0x73,0x91,0x62,0x9E,0xA7,0x54,0x0B, -0x98,0x9F,0x0B,0x63,0xB7,0x67,0x98,0x9F,0x28,0xBB,0x3F,0xBC,0x7B,0x16,0xC0,0x8C,0x65,0x85,0xE0,0xAF, -0x45,0x00,0x07,0x86,0xF5,0x0A,0x9C,0xD6,0x7C,0x48,0x30,0x40,0xE4,0x05,0xBE,0x33,0xB0,0xC5,0x2B,0x44, -0x6C,0x8B,0x71,0xC3,0x28,0xA7,0x01,0x90,0x9A,0x8B,0x1B,0xD0,0x02,0xF2,0xF0,0x07,0x7E,0x65,0x11,0x8F, -0xC2,0x63,0x50,0x4C,0x27,0xFB,0xE8,0xA0,0xDB,0x77,0xD1,0x3E,0x39,0xE8,0x83,0x7F,0x99,0x0D,0xFA,0x6A, -0xE5,0x9F,0x48,0x84,0x2F,0x0A,0x97,0x13,0x0B,0xD5,0xD4,0x7A,0x06,0x39,0x0B,0x41,0x91,0xE6,0x77,0xC6, -0xE9,0x48,0x33,0x3E,0x7C,0xDF,0xFD,0xE1,0xEA,0x73,0xFF,0x83,0xD3,0xED,0x5F,0x99,0xBF,0x99,0x3D,0x62, -0x73,0x9C,0x71,0x83,0xA2,0x1B,0x32,0x43,0x60,0xE7,0xB6,0xC8,0xB7,0xC3,0x19,0x48,0x61,0x0E,0xAA,0x35, -0x88,0x62,0x6F,0xCB,0x71,0x36,0x3C,0x7C,0x80,0x22,0x0C,0xAC,0xEB,0x27,0xE7,0xE7,0xA7,0xE7,0x1F,0xF4, -0x0E,0xEE,0xE8,0x57,0xAE,0xA6,0x77,0xA8,0xE9,0x72,0x1B,0x4A,0xCF,0x14,0x67,0xE1,0x19,0xE2,0xA1,0x11, -0xD8,0x37,0x28,0xCA,0x41,0x17,0x82,0x11,0xE6,0x81,0xE2,0xF4,0x49,0xCE,0x39,0xA3,0xBA,0x39,0x60,0x36, -0xA1,0x14,0xA7,0x4F,0xC7,0xAF,0x5E,0x7A,0xFA,0x39,0x63,0x5C,0x3B,0x26,0xA9,0x6E,0xC9,0xDD,0xB0,0x51, -0x92,0x60,0x1A,0x1C,0x85,0x24,0x0A,0x0C,0x66,0x0E,0x04,0xBA,0x2F,0xD1,0x65,0x21,0x02,0xD8,0xBE,0xAD, -0x4A,0xD6,0x29,0x48,0xAD,0x5B,0xBE,0x1D,0xE7,0x11,0x27,0x49,0x84,0xBD,0x8D,0x3E,0xF4,0x28,0x8A,0x01, -0x26,0xD2,0xB0,0x80,0x91,0xC0,0xD3,0x55,0x30,0x2A,0x42,0xD8,0xBA,0x55,0x7C,0xB5,0x4A,0xD0,0x5A,0x25, -0x68,0xE2,0x26,0x20,0x91,0x6E,0x05,0x76,0x5D,0x2B,0x43,0xAF,0x58,0xAA,0x84,0x05,0x78,0x8A,0x80,0x93, -0xB7,0x20,0x35,0x8C,0xF6,0xD6,0x2D,0x14,0xA8,0x85,0xB2,0xB6,0x36,0xB2,0xA6,0x36,0xD4,0x36,0xAE,0x43, -0xCE,0x14,0x72,0xDA,0x46,0x4E,0x9B,0xC8,0x47,0xD2,0x1A,0xD6,0x21,0xA7,0x0A,0x39,0x6A,0x89,0x18,0x49, -0x11,0x55,0x84,0xEB,0x0A,0x6D,0x82,0x40,0x80,0x1D,0x35,0xC5,0x84,0x1E,0x38,0x24,0x9A,0x44,0x38,0xF0, -0x36,0x1C,0xE8,0x89,0xA2,0xDA,0xDB,0x72,0xD6,0xAC,0x11,0xA9,0x35,0xF2,0xD6,0x1A,0xB9,0x5C,0x83,0x24, -0xA0,0x44,0xC8,0x1B,0xBA,0x95,0x4B,0xAD,0xB5,0x47,0xD4,0x72,0x7E,0x88,0xFD,0xEB,0x09,0x93,0x23,0xB2, -0x2D,0x56,0xDC,0x40,0x92,0x66,0x22,0x69,0xCA,0xA3,0x08,0xD0,0x4C,0x6C,0xF0,0x72,0x4F,0x50,0xB6,0x92, -0xA6,0xF8,0xDA,0x30,0xE2,0xB6,0x2E,0x11,0xE2,0xB6,0x96,0xE2,0xD6,0xB4,0x11,0xBA,0xC1,0xDA,0x3A,0x2D, -0xC5,0xE6,0x9A,0xC1,0x64,0xDD,0x60,0x6E,0x5A,0xA9,0xCD,0xA8,0x1F,0x11,0xFF,0xDA,0xAB,0xDD,0xD8,0x5C, -0x18,0xCD,0x8E,0xE0,0x84,0x7B,0x14,0xCF,0xB5,0x9F,0x20,0x2C,0x1D,0x23,0x8E,0x06,0xBC,0x20,0x63,0x14, -0x76,0x83,0x81,0x10,0x9C,0x4F,0xC1,0x0B,0x33,0x1B,0x05,0x30,0x7C,0x76,0x31,0xD6,0x2D,0xBD,0x27,0x76, -0x45,0x07,0x4F,0x26,0xE6,0xD2,0xAC,0x7C,0xC9,0xA2,0x32,0xAA,0x5F,0xA4,0x51,0x3D,0x04,0x8D,0xD2,0xE2, -0x96,0x56,0xBC,0x96,0x27,0x32,0x35,0x2A,0x95,0x96,0x4C,0x89,0x93,0xA1,0x58,0xC3,0x28,0xF6,0x5F,0x37, -0x21,0xEC,0x29,0xE3,0x35,0x4C,0x0B,0xB5,0x99,0x46,0x15,0xD3,0x29,0x9A,0x97,0x46,0xA2,0xD6,0x1F,0x28, -0xF7,0x76,0x20,0xFB,0xD2,0x8C,0x6B,0xD8,0xDB,0x71,0x7E,0xD8,0x1D,0xC0,0xFE,0x18,0xCA,0x71,0x01,0xB0, -0xC7,0x6D,0x30,0xAD,0x19,0x0F,0x07,0x7E,0xC7,0x2B,0xB4,0x12,0x78,0xDC,0xCE,0xF2,0x49,0xC6,0x53,0xC8, -0x6D,0x86,0x6F,0xF9,0x1D,0x6C,0xB6,0x97,0xD1,0x3B,0xCC,0x0A,0x4C,0x8B,0x75,0x3A,0xCB,0x7B,0x0A,0x3A, -0x1D,0x35,0x34,0x84,0x84,0x86,0x70,0x94,0x61,0x8D,0xDA,0xF8,0x16,0xFB,0x47,0x2C,0x8E,0x91,0x20,0x91, -0xC1,0x26,0x17,0x1D,0xDD,0x5C,0x5A,0x6C,0xAD,0x66,0x1E,0x08,0x59,0x56,0xF6,0x90,0x1E,0x21,0x04,0x7A, -0xBE,0x2D,0x7C,0x25,0x2B,0x84,0xFA,0xF2,0x2E,0x97,0x81,0x48,0xA1,0x7C,0x70,0xAE,0xAC,0x6A,0xE3,0x56, -0xA4,0x6A,0xEF,0xBB,0xB4,0xBA,0x56,0xFC,0x31,0xEB,0x9D,0x16,0xB0,0x76,0x5C,0xAB,0xA1,0xFA,0x72,0x69, -0xF9,0x82,0xFF,0x10,0xD1,0x19,0xFE,0xEB,0x02,0xD4,0x3C,0x4A,0x17,0xB5,0x28,0x24,0x8F,0x03,0xF7,0x17, -0xDB,0xF8,0xF0,0xAB,0x7D,0xD5,0x31,0xCD,0x83,0xAF,0x7B,0x52,0xC3,0x06,0x37,0x3F,0xF4,0xAF,0x2C,0x04, -0x60,0xFB,0x3B,0xF3,0x17,0x5B,0x82,0x5B,0xB0,0xC1,0x0D,0x23,0x81,0x26,0x56,0x12,0x9E,0xCD,0xA6,0x1A, -0xDA,0xDC,0x34,0xC0,0xE4,0x5A,0xC6,0xDA,0xE1,0x1D,0xDD,0x86,0xBC,0xB1,0x5C,0xDE,0xCF,0x66,0xE3,0x14, -0x63,0x95,0x2E,0x2B,0x80,0xE4,0x1E,0x64,0x5E,0x09,0x56,0xA5,0xD4,0xD8,0xAA,0xA1,0x30,0x28,0xD3,0xBD, -0x5D,0x54,0x12,0x9E,0x4E,0x19,0x05,0x93,0x4D,0xEE,0x0F,0xCB,0x23,0x9E,0xDE,0x8A,0x21,0xDF,0xEE,0x91, -0x78,0xA6,0x65,0xA9,0xEF,0xA9,0xAD,0x38,0x10,0x7F,0xBC,0x6F,0x45,0x9A,0xDB,0xFC,0xCD,0x9F,0x78,0x7A, -0x07,0xF6,0x17,0xDB,0x94,0xCD,0x0D,0xB3,0xF3,0xAD,0xAE,0x49,0x8A,0x9E,0x1E,0xA3,0xDB,0xE2,0xA0,0x2F, -0x2A,0x91,0x81,0x06,0xFD,0xB2,0x84,0x55,0x03,0xC5,0x11,0x1B,0xE5,0x9C,0x0D,0xB4,0xB2,0xC2,0x51,0x47, -0x4C,0x5D,0xEB,0xED,0x7F,0x5B,0xEB,0x00,0x81,0xE8,0x48,0xED,0x09,0x91,0x41,0x2C,0x17,0x21,0x0F,0xB7, -0xA2,0x0F,0x29,0xDC,0x4E,0x45,0x45,0x02,0x70,0x72,0x2F,0x6D,0x5A,0x99,0x81,0xCC,0x03,0xA3,0x95,0x68, -0xF7,0xC4,0xA1,0x64,0xFF,0x4C,0x55,0x9B,0x7B,0x3D,0xD9,0xD3,0xD7,0x39,0x06,0x68,0x9E,0x02,0xBA,0x55, -0xD5,0x37,0x13,0x16,0xDC,0x35,0xAA,0xA2,0xEC,0xF0,0xEE,0x28,0x42,0x59,0xF6,0x1A,0xC5,0xB0,0xBE,0x1F, -0xEB,0x66,0x61,0x4A,0xFB,0xCE,0xE6,0x66,0x1B,0x29,0xC5,0x31,0xBB,0xC1,0x8A,0x2B,0x0C,0xA1,0xCC,0x0D, -0x80,0xF0,0xE6,0xE6,0x3A,0xC6,0xC4,0x15,0xDB,0x97,0xB8,0xA2,0xE0,0xAE,0x65,0xF8,0xFB,0x9F,0xB8,0x53, -0x39,0xF2,0x21,0xAD,0x46,0xA6,0x25,0xB8,0xFF,0xFC,0x39,0x93,0x7F,0x57,0x02,0xBD,0xF4,0x97,0x55,0x77, -0xC1,0xD2,0x25,0xC0,0xF5,0xEE,0x7B,0x05,0x37,0xB3,0x39,0xE1,0x7E,0x28,0xF4,0xED,0xA3,0x0C,0xEB,0xE2, -0xA6,0xCE,0x95,0xAD,0xD9,0xA7,0xA2,0xF1,0x89,0x24,0x45,0x6B,0x8E,0x6E,0x8A,0x56,0x9C,0x6C,0x17,0xAD, -0x24,0x98,0xEA,0xAE,0x2A,0x12,0x37,0x9C,0x65,0xD1,0xE8,0x2F,0xE5,0xD6,0x47,0xAB,0x1A,0x3E,0x66,0x73, -0x2A,0x14,0x58,0x69,0x39,0x5A,0xB3,0xF7,0x75,0x0A,0xAB,0x9C,0x2E,0x28,0xF0,0xBA,0xD3,0x54,0xF9,0x5C, -0xC3,0x3F,0x4A,0x18,0x78,0x06,0x5E,0x9A,0xFF,0x97,0xD5,0xF8,0xCA,0x6A,0x56,0xF6,0x63,0x8D,0x90,0x47, -0x21,0xD4,0x92,0x7F,0x22,0x61,0xDC,0x5A,0x21,0xB6,0x7D,0xF1,0x7C,0xCD,0x02,0x19,0xFD,0x4C,0x2B,0x37, -0x62,0xEB,0x7F,0x34,0xB0,0xA4,0x65,0x60,0xED,0x4A,0x23,0x59,0xB3,0x6B,0x38,0xC2,0x1C,0x57,0x12,0x25, -0x6B,0x25,0x4A,0xFF,0x1F,0xCD,0xD7,0x61,0x89,0xA8,0x73,0x45,0x33,0x30,0x05,0xE4,0x46,0x87,0x04,0xED, -0xB5,0x29,0x64,0x7E,0xCA,0xA2,0x68,0xCC,0x92,0x83,0x07,0xC6,0xDD,0x6A,0xBC,0x68,0x94,0x6C,0xD6,0x53, -0x2C,0x7F,0x2D,0xD1,0x97,0x78,0xCA,0x0F,0x1E,0x02,0x3C,0x4C,0xB6,0x9E,0x63,0x05,0x1E,0xB6,0x41,0x79, -0x30,0xFA,0x73,0xC7,0xB7,0xB2,0xAA,0x77,0xD9,0x61,0xB0,0x17,0x7E,0xA9,0x24,0x4F,0x28,0xC9,0x22,0x6B, -0xF3,0x45,0x3D,0x1E,0x01,0x45,0x2F,0xE8,0xE8,0xC9,0x6D,0x3D,0xC6,0x59,0xE2,0x65,0x6A,0x08,0x19,0xC4, -0xE2,0xF7,0x36,0x65,0x5D,0x14,0x4F,0x3D,0x62,0xB3,0xE9,0x34,0xC3,0xFC,0x9D,0xC8,0x20,0x56,0x54,0xF5, -0x9F,0xCA,0x0C,0x32,0x80,0x2E,0x8D,0x59,0x9E,0x61,0x96,0xF3,0x76,0xAD,0x59,0x09,0xB3,0x17,0x7C,0xFE, -0x5C,0x75,0xF6,0x83,0x4E,0x5A,0x77,0x2F,0xF7,0xB2,0x46,0x67,0x3F,0xEB,0x44,0xE0,0x49,0xFF,0xB1,0xA5, -0x90,0xA6,0xA5,0x30,0x91,0xC0,0x2C,0xA6,0x2C,0x25,0xAD,0x6D,0x3D,0x15,0x27,0x01,0xD4,0x08,0xB1,0xC2, -0xA0,0x75,0xB3,0x3C,0xE4,0x36,0x5D,0x19,0x59,0x69,0xDB,0xD3,0x1F,0xAA,0xB6,0x03,0x43,0x50,0x05,0xAD, -0xBF,0x64,0x73,0x9C,0x1E,0xA1,0x0C,0x1B,0x10,0x79,0xAB,0x34,0x21,0xA1,0xA6,0x9B,0xAD,0x9D,0x45,0x0B, -0xA8,0xAF,0x9E,0x10,0x5E,0xBE,0x18,0x16,0x60,0x82,0x88,0x0B,0x6B,0x28,0x99,0x4B,0xC5,0x1D,0xA3,0xE2, -0xC4,0x04,0x1A,0xCA,0x5B,0x3C,0x62,0x5B,0x5C,0xF0,0x80,0xDE,0x8E,0xD5,0x01,0x11,0xCA,0x6B,0x0C,0xD6, -0xC2,0x92,0xB3,0x94,0x25,0x68,0x86,0xC4,0x3C,0x18,0x03,0x07,0x93,0xC4,0x05,0xB5,0x46,0x45,0x54,0x5F, -0x37,0x74,0xFB,0x1E,0xD8,0xAB,0xBC,0xCC,0x39,0x9D,0x1A,0x50,0x3B,0x99,0xF5,0xB4,0xE0,0xBF,0x4B,0x42, -0xFC,0x96,0x17,0xD9,0x25,0xE4,0x71,0xDD,0x8A,0x8A,0xE6,0xC7,0xAC,0x68,0xF8,0x59,0xD9,0xBA,0x6D,0x00, -0x19,0x2D,0xC1,0x8C,0x4E,0x8B,0x26,0xA1,0xA4,0xA4,0x53,0x02,0xCB,0x67,0x92,0x94,0x99,0x2C,0x2C,0x5B, -0x21,0xBE,0xAD,0xF0,0x58,0x95,0xE7,0xF0,0xBA,0x3C,0x57,0xDF,0xB2,0xFC,0x77,0xE2,0x27,0x74,0x56,0x0A, -0x93,0x94,0xAD,0x19,0x29,0x45,0x99,0xC4,0xC9,0x17,0x19,0x49,0xFF,0xE9,0xA9,0xEF,0xF8,0xE4,0xE5,0xC9, -0xF8,0xA4,0x79,0x00,0x68,0x5E,0x0E,0xF1,0x3F,0xBB,0x7D,0xE1,0xA6,0x6B,0xFC,0x85,0xA4,0x06,0x65,0xB7, -0x69,0xB6,0xEE,0x8F,0xA2,0xD6,0xBD,0x54,0x9D,0x51,0x8A,0x0B,0x1F,0xD0,0xD3,0xE6,0x66,0x83,0x11,0x39, -0x5E,0xDF,0x69,0x51,0x4B,0x57,0x55,0xB8,0xF4,0x6A,0xF4,0x50,0xB9,0x8A,0xCC,0xEA,0x40,0x48,0x3C,0x5A, -0x44,0x14,0x4B,0x9C,0x0D,0xC9,0xBE,0x0F,0x87,0xC2,0x8E,0xA9,0xEE,0x72,0x3C,0x0F,0xAE,0xBD,0xFC,0x2B, -0x79,0x1F,0xB0,0xB9,0x89,0xDA,0x25,0xAD,0xE1,0x58,0x12,0x28,0x16,0x94,0x2D,0x79,0x13,0x01,0xB2,0x00, -0x5B,0x8E,0xF5,0x7C,0x74,0xFA,0xDA,0x4E,0x50,0x0A,0x0E,0x49,0xCD,0x66,0x34,0xCA,0x95,0x80,0x6D,0x6D, -0x3F,0x39,0x69,0x9C,0xB5,0xE4,0xEB,0x3E,0x97,0x2F,0xAD,0xC8,0x10,0xE4,0x54,0x86,0x16,0x65,0x4F,0x71, -0x2F,0x0B,0x39,0x2E,0x2E,0xF3,0x5D,0x1D,0xAE,0xE2,0x66,0xB6,0xE0,0x37,0xF9,0x03,0xD7,0x09,0x3C,0x24, -0x59,0xF3,0x8C,0xD9,0x8A,0x0C,0x7F,0x71,0xC7,0x96,0x65,0x4B,0x91,0xBB,0x7F,0x5C,0x52,0xAF,0xA6,0xD5, -0xE6,0xC8,0xE3,0xF0,0xA2,0x0E,0xC5,0xB5,0x39,0xEA,0x90,0xC2,0x08,0xD5,0x2D,0xFA,0x77,0x3D,0x84,0x96, -0x1E,0x42,0x57,0x03,0x04,0xBE,0x6D,0x79,0x7B,0xB5,0xCA,0x60,0x02,0x9C,0x5D,0x0F,0xEA,0x28,0x02,0x10, -0x78,0x46,0x2D,0xC0,0xC7,0x4C,0x8E,0x7F,0x44,0x37,0x48,0x5D,0xCB,0xD6,0xD0,0xF5,0xA1,0x42,0x4E,0xF7, -0x7F,0x83,0x56,0x35,0xB3,0x1D,0x88,0x32,0x68,0xAE,0xC6,0x13,0xDE,0x0A,0x4F,0x75,0xCC,0x6A,0x46,0x27, -0x70,0xD7,0xC2,0x9B,0x35,0xDE,0xD0,0x6F,0xC3,0xF5,0xC0,0x20,0x1F,0xF2,0xBD,0x66,0x1C,0x56,0x18,0x4D, -0xEB,0x59,0x7F,0x18,0x6D,0x1F,0x57,0xD7,0xD7,0x19,0xD2,0xFF,0xF0,0x41,0x66,0x67,0xE5,0xC5,0x0C,0xB8, -0x79,0xA3,0xA7,0x83,0x41,0x64,0x60,0x86,0x18,0xA5,0x23,0x71,0x07,0xA0,0x12,0xC9,0x52,0x6D,0xA0,0x27, -0x5D,0xD7,0x00,0x8D,0xF5,0x64,0xCA,0xB0,0x41,0x0F,0x30,0xBF,0x02,0x52,0x00,0x52,0x8F,0x01,0xC9,0xC6, -0x20,0x82,0x41,0xE4,0xE9,0x31,0xA3,0xEC,0x1A,0x91,0xE6,0x74,0x02,0x10,0x52,0x7C,0x25,0xA0,0x77,0xA8, -0x55,0xEC,0x83,0x24,0x54,0x43,0xD4,0xEE,0x9B,0xC5,0x2D,0x67,0x7D,0xC7,0x84,0x4B,0xB7,0x29,0xEC,0x63, -0x43,0xA2,0x65,0xA2,0xF0,0x18,0xE1,0x2C,0x93,0x7C,0x0B,0xB9,0x5E,0xB1,0x00,0xC4,0x02,0xB4,0x5E,0x0C, -0x2D,0xB1,0x10,0x48,0x28,0x00,0xE3,0x10,0xC7,0x05,0x84,0x43,0x53,0x80,0x90,0x00,0x7D,0x2D,0x55,0x35, -0x92,0x05,0x1E,0xA1,0x33,0xAF,0xDF,0x73,0xAC,0x55,0xB2,0x17,0x19,0x1E,0xB1,0x29,0x1F,0xA3,0x49,0x66, -0x6C,0x38,0xE6,0xEA,0x0C,0x01,0x1A,0x41,0x34,0x31,0xB6,0xCC,0xF5,0xE8,0xEF,0x58,0x7A,0x8D,0xD3,0x02, -0x59,0x54,0x66,0x50,0x98,0x45,0xF0,0xCB,0x87,0xBE,0x78,0xD1,0xFF,0x92,0x50,0x5C,0x03,0x47,0x21,0x9B, -0x9F,0xA5,0x84,0xF2,0x57,0xF2,0xD0,0x6F,0x6C,0xF4,0xE5,0x3E,0xA9,0xBB,0x28,0x19,0x81,0xCA,0x4B,0xAA, -0x85,0x08,0x66,0x6E,0xEB,0xAA,0xCA,0x9A,0xC0,0x76,0x41,0x6C,0x75,0x17,0x73,0x42,0x5D,0xFD,0x88,0xA7, -0x51,0x77,0xA4,0x5B,0x31,0xF2,0xA1,0xA3,0xE6,0x40,0x7F,0x69,0x09,0xA7,0x75,0x9B,0xC1,0x64,0xA3,0xEE, -0xD4,0x85,0xFA,0xCA,0x3D,0x5E,0xFB,0x5A,0x4A,0x00,0x0F,0x23,0x36,0x31,0xC4,0x3B,0x87,0x85,0x70,0x78, -0x97,0x2E,0x4D,0x91,0x9D,0xBE,0x7C,0xE5,0xE6,0x43,0xD4,0xE5,0x16,0x6E,0xDC,0x18,0x76,0x74,0x5D,0x5C, -0xC4,0x01,0x1E,0x0A,0x4E,0x69,0x74,0xE7,0x42,0x56,0xFC,0x13,0xA9,0x73,0x1A,0xB0,0x2F,0x49,0xFD,0xFE, -0x9E,0xD4,0xEF,0xD7,0x49,0x8D,0xDB,0xBB,0x05,0x9D,0x0B,0x20,0xFB,0x0A,0x51,0x34,0xC3,0x29,0x0C,0x88, -0x45,0x60,0x03,0xFE,0x1E,0x67,0x29,0xFE,0x32,0x67,0xA3,0x90,0x4C,0xF9,0x0A,0x7F,0x72,0xF4,0x9F,0x71, -0x99,0xE2,0x07,0xB8,0x2C,0x0B,0xD9,0x2A,0x6D,0xFC,0xF9,0x3D,0x98,0x74,0x6A,0x0F,0xB6,0xB0,0xE9,0xAE, -0xFF,0xC0,0xEF,0xEA,0x15,0xBF,0x9C,0x3D,0xC5,0xC3,0xC5,0x4B,0x2B,0x10,0x36,0x01,0x12,0x34,0xF2,0x13, -0xA3,0x87,0x70,0x52,0x78,0x09,0x22,0x18,0xCA,0x1C,0xB1,0xB7,0x58,0x5A,0xDC,0x33,0xE6,0x04,0xC4,0x9F, -0x83,0x70,0xBE,0xAC,0x7E,0x6D,0xF1,0xCD,0x12,0x28,0x01,0x98,0x84,0x3C,0xDB,0xFB,0x70,0xB0,0x79,0xD5, -0x81,0x04,0xE5,0xC1,0xC3,0xF4,0xA0,0xB1,0x79,0xF5,0x9D,0xD9,0x9B,0x91,0x46,0x49,0x24,0x53,0x1D,0xE8, -0xF5,0x03,0xBD,0xF2,0xD0,0x12,0x42,0x58,0x33,0x15,0x56,0x81,0xD5,0xC2,0xF2,0x4A,0x13,0x1E,0xE2,0xB3, -0x30,0x78,0xC8,0xD8,0x01,0xB3,0xA9,0xD7,0xB8,0x69,0xD4,0x39,0xFC,0xD5,0x21,0x6C,0x0F,0x0A,0xB6,0x02, -0x3C,0x25,0x14,0xCB,0xE8,0xA5,0x9A,0x56,0x01,0x10,0x6A,0x20,0xA9,0x84,0x94,0x6D,0x4B,0xB4,0x45,0xF6, -0x23,0x33,0xA1,0x48,0x43,0x17,0x1F,0x7C,0x88,0x44,0xAF,0xCB,0x84,0xBD,0x02,0x9E,0xCB,0x40,0xD2,0x98, -0xB0,0xE6,0x05,0x9E,0x9E,0x17,0x2D,0x1D,0xA4,0xE4,0x8D,0x20,0xAC,0xC4,0x81,0x78,0xAB,0x1A,0xF7,0x42, -0x7B,0x7D,0xEA,0x51,0x60,0x73,0x09,0x2E,0xA6,0x04,0x08,0xF4,0x2A,0x9D,0xFF,0xFC,0xEA,0xE5,0x53,0xCE, -0x93,0x73,0xB5,0xA3,0x40,0xAB,0x3D,0x50,0x1B,0x9A,0xB9,0xE0,0xE9,0x5D,0x59,0x18,0x8A,0x40,0xA1,0x42, -0xDD,0xCF,0xA7,0x93,0x8F,0xD8,0x07,0x49,0x5E,0x65,0x90,0x43,0xB7,0x6C,0x81,0x3E,0x1E,0x9F,0xD9,0xBB, -0xB6,0x03,0x95,0x0A,0xEC,0xA7,0x1F,0x0A,0x8B,0x59,0xFE,0x2D,0xE4,0xED,0xBF,0x87,0x4C,0x20,0xDE,0x67, -0x10,0xD0,0x4B,0xFC,0x36,0x6E,0x98,0xB2,0xB9,0x44,0x3B,0x49,0x53,0x61,0x0C,0xE3,0x90,0x64,0xDA,0x04, -0x06,0x33,0x9C,0x6A,0x01,0xC3,0x99,0x46,0x19,0xD7,0xB2,0x3C,0x49,0x58,0xCA,0xEF,0xE9,0xC3,0xD6,0xCB, -0x4B,0x9A,0x37,0x39,0xCE,0x71,0x50,0x0C,0xE3,0xB4,0xA9,0x17,0x59,0xD3,0xC1,0x38,0xB8,0xDB,0x87,0xAB, -0xA2,0xC2,0xCB,0x29,0x15,0xF9,0x67,0xA3,0xAF,0xFA,0x20,0x5D,0x08,0x54,0x3D,0x9A,0x47,0xD1,0x72,0x70, -0x8F,0x96,0x9D,0xA4,0x8C,0x33,0xF9,0xD2,0x6B,0xF1,0x5B,0xE1,0x5A,0xEE,0xBD,0x6B,0xFA,0x36,0x55,0xC7, -0xDA,0x30,0x36,0xB0,0x46,0x68,0xC6,0x11,0xF5,0xC5,0x36,0x2A,0x5D,0x98,0x65,0x75,0x27,0xA6,0x0F,0x44, -0x5C,0x90,0x86,0xF3,0x60,0x49,0x21,0x25,0xA3,0x9E,0xAE,0x8B,0x42,0x0F,0x8B,0x7A,0x19,0xC5,0x59,0x83, -0x6C,0x95,0x29,0x4C,0xEA,0x95,0xE0,0x81,0x7C,0xB9,0xD2,0x9C,0xBF,0xCA,0x46,0x59,0xDD,0x23,0x80,0x69, -0xE5,0x3C,0x93,0x76,0x3C,0x5D,0x56,0x08,0x07,0x32,0x64,0x48,0x03,0x8E,0x31,0x0F,0x59,0x70,0xA0,0x1F, -0xE8,0xAE,0x0E,0xFF,0x37,0x75,0x0B,0x66,0x61,0xEA,0xB3,0x00,0x5F,0x9C,0x3F,0x83,0x50,0x9A,0x30,0x8A, -0x29,0x37,0x10,0x64,0x14,0x4F,0xEF,0xAC,0x42,0x2A,0x36,0x3E,0xA0,0x2B,0x73,0xD0,0x56,0x36,0x9E,0xDF, -0xDB,0xCE,0xD6,0x66,0xD8,0x8C,0x8A,0xE8,0x7A,0x07,0xCC,0x73,0xBC,0xF2,0x72,0xC4,0xA2,0xAB,0xA7,0x20, -0x73,0xB1,0x23,0x78,0x96,0x58,0x23,0xC0,0x12,0xAE,0x57,0x2B,0xF9,0xA1,0xCA,0x8E,0xDA,0x3E,0x8A,0x22, -0xF1,0x31,0x07,0xF0,0x2A,0x16,0xCB,0x33,0x4B,0x10,0xC9,0x40,0x80,0x0C,0x8F,0xF1,0x2D,0xB8,0xB4,0x2C, -0xCF,0x94,0x0D,0x15,0xC7,0x21,0x20,0xCD,0x1B,0x66,0x64,0x5A,0x55,0x6F,0x73,0x93,0xDB,0xA5,0x99,0x18, -0x25,0x52,0x26,0x92,0x8D,0xBC,0x7B,0x58,0x1A,0x4D,0x21,0x45,0xEE,0x5E,0xD1,0xB6,0xD1,0x56,0x43,0x82, -0xA9,0x51,0xC2,0x80,0xB3,0x3C,0x8D,0x20,0x43,0x88,0xEA,0xA5,0x35,0x2D,0xC3,0x34,0x80,0x05,0xDC,0x3F, -0x45,0x96,0xA8,0xB4,0x69,0x15,0x23,0x9E,0x2A,0xBE,0xDB,0xF4,0x78,0xB1,0x2B,0x4F,0xB1,0x0C,0x73,0xED, -0xEF,0x71,0x2D,0xF9,0x25,0x2D,0x51,0x09,0xA1,0x07,0x6F,0x53,0xE6,0xF3,0x2E,0x98,0x55,0xDC,0x85,0x15, -0x94,0x15,0x04,0xFA,0x1A,0x0E,0xD5,0x69,0xCF,0x12,0xD7,0x29,0xEE,0x3D,0x17,0xAD,0xF5,0x67,0xDC,0xF3, -0xD1,0x36,0x9D,0x36,0x9F,0x8D,0xDD,0xDE,0xDB,0xB9,0x07,0x42,0x13,0x96,0x72,0x03,0x72,0x1C,0xA4,0xC1, -0x6A,0xB5,0xF2,0xE0,0xD5,0x8C,0x0B,0x76,0x92,0x67,0xA1,0xB1,0x00,0xD6,0x5D,0x6E,0x29,0x5D,0xB9,0xD8, -0x52,0x76,0xEB,0x52,0xAB,0xB4,0x0F,0x17,0x52,0x57,0x2B,0x7E,0x7C,0xFE,0x2C,0x7B,0xF5,0x6E,0x43,0xAF, -0xBD,0xE1,0x20,0xAC,0x74,0xE2,0x32,0x23,0x0B,0xA3,0xBF,0x1F,0xAB,0xF6,0x7A,0xEA,0x3C,0x55,0x7E,0xEE, -0xA2,0x91,0xC0,0x13,0xC9,0x5D,0x57,0xEF,0xB5,0xEA,0x4F,0x83,0xA7,0x10,0x9D,0x6C,0x38,0x86,0x55,0xDF, -0x3D,0xEB,0xC5,0x87,0xCF,0xF7,0x29,0xEC,0x57,0xE7,0x42,0xCF,0xAB,0xAA,0x7A,0x15,0x7B,0xD4,0x04,0xEF, -0x81,0x4F,0x61,0x74,0x05,0x86,0x63,0xB3,0x6A,0xD8,0xF7,0x38,0x10,0xAB,0x5B,0x05,0x08,0x65,0x77,0xD4, -0x17,0x11,0xB4,0xA2,0x15,0xC2,0x56,0xB4,0x0E,0xD4,0x6A,0xA6,0xB9,0xAC,0xF9,0x13,0x57,0x91,0x1A,0x2B, -0xDE,0x40,0x34,0xEB,0x0D,0x10,0x02,0xCE,0xEB,0x42,0xF4,0xD2,0x5D,0x35,0x79,0x60,0xAF,0xBA,0x20,0x24, -0x4C,0xA8,0x67,0xE5,0xC9,0x7A,0x80,0x2C,0x0F,0x56,0x06,0x55,0x85,0xB1,0x32,0x5C,0x1C,0xFA,0xAA,0xF7, -0x82,0x8D,0x6F,0x99,0x6A,0x1A,0x44,0xBE,0x46,0x91,0xF3,0xDB,0x6F,0x56,0x1E,0x44,0x53,0x18,0xFB,0x7F, -0x00,0x47,0x16,0x74,0xBA,0xF2,0x2E,0x00,0x00 +0xDF,0x49,0xF2,0x93,0x84,0xEE,0xF1,0x6D,0xA5,0x60,0x49,0xA7,0x3B,0xDD,0x9D,0xEE,0x25,0xD9,0x7B,0x1B, +0xC7,0xA7,0x47,0xE3,0xCB,0xB3,0x13,0x2D,0xE4,0x71,0xB4,0xBF,0x27,0xFE,0x6A,0x11,0xA2,0x33,0x4F,0xC7, +0x54,0xDF,0xDF,0x8B,0x31,0x47,0x00,0xE2,0x49,0x17,0xFF,0x91,0x93,0x1B,0x4F,0x3F,0x62,0x94,0x63,0xCA, +0xBB,0xFC,0x2E,0xC1,0xBA,0xE6,0xAB,0x9E,0xA7,0x73,0x7C,0xCB,0x7B,0x02,0x79,0xA0,0xF9,0x21,0x4A,0x33, +0xCC,0xBD,0x9C,0x4F,0xBB,0x8F,0x81,0x04,0x27,0x3C,0xC2,0xFB,0x27,0xA3,0x33,0xED,0x24,0x20,0x9C,0xA5, +0x7B,0x3D,0x35,0xB2,0x17,0x11,0x7A,0xAD,0xA5,0x38,0xF2,0x74,0x94,0x24,0x11,0xEE,0x72,0x96,0xFB,0x61, +0x97,0x00,0x4D,0x5D,0x0B,0x53,0x3C,0xF5,0xF4,0x1E,0xF2,0xB1,0x0D,0x03,0xBA,0x26,0x96,0xF3,0x74,0x12, +0xA3,0x19,0xEE,0xDD,0xAA,0x39,0x4D,0x02,0x59,0xC8,0x52,0xEE,0xE7,0x5C,0xFB,0x57,0xD8,0xFF,0x00,0x29, +0xE3,0x77,0x11,0x56,0x20,0x25,0xB3,0x9F,0x65,0xBA,0x16,0xE3,0x80,0x20,0xE0,0xC2,0x4F,0xB1,0xD0,0x5A, +0x84,0x26,0x38,0x5A,0x4C,0x19,0xA8,0x29,0x23,0x9F,0xB1,0xDB,0xDF,0x4A,0x6E,0x07,0xB2,0x3B,0x45,0x31, +0x89,0xEE,0xDC,0x0C,0xD1,0xAC,0x9B,0xE1,0x94,0x4C,0x97,0xB6,0x1F,0x2F,0x3E,0x77,0x09,0x0D,0xF0,0xAD, +0xBB,0xED,0x38,0x83,0x84,0x65,0x84,0x13,0x46,0x5D,0x34,0xC9,0x58,0x94,0x73,0x3C,0x88,0xF0,0x94,0xBB, +0x8F,0x80,0xC2,0x84,0xA5,0x01,0x4E,0xDD,0x7E,0x72,0xAB,0x01,0x88,0x04,0xDA,0x37,0x3B,0x3B,0x3B,0x83, +0x09,0xF2,0xAF,0x67,0x29,0xCB,0x69,0xD0,0xF5,0x59,0xC4,0x52,0xF7,0x9B,0xE9,0x23,0xF1,0x33,0x08,0x48, +0x96,0x44,0xE8,0xCE,0xA5,0x8C,0x62,0xC0,0xBD,0xED,0x66,0x21,0x0A,0xD8,0xDC,0x75,0x34,0x47,0xEB,0x3B, +0x40,0x24,0x9D,0x4D,0x90,0xE1,0x58,0xE2,0xC7,0xDE,0x31,0x07,0x7F,0x8B,0x5F,0x35,0x3C,0xC7,0x64,0x16, +0x72,0xF7,0x47,0xC7,0x11,0xFC,0x6B,0x79,0xB4,0x88,0x48,0xC6,0xBB,0x52,0x39,0x6A,0x3D,0xCE,0x12,0xD7, +0x91,0xAC,0xC3,0x23,0x46,0xE9,0x8C,0x50,0x68,0x24,0x28,0x08,0x08,0x9D,0xB9,0x0A,0x2D,0x22,0x8B,0x4A, +0x5A,0xD8,0x07,0xC4,0xC9,0x0D,0x1E,0xC4,0x84,0x76,0xE7,0x24,0xE0,0xA1,0xBB,0xEB,0x00,0x17,0x7E,0x9E, +0x66,0x20,0x53,0xC2,0x08,0xE5,0x38,0x95,0x68,0x59,0x82,0xE8,0x42,0x89,0x2A,0x14,0x50,0xC9,0x49,0x28, +0xEC,0x28,0xEE,0x4E,0x22,0xE6,0x5F,0x57,0x2B,0xED,0x26,0xB7,0xC5,0x5A,0x6E,0xC8,0x6E,0x70,0xBA,0xA8, +0xD5,0x25,0xB1,0x5B,0xC0,0x16,0x69,0x8C,0xF1,0xD2,0xE6,0x37,0x39,0x40,0x2D,0xF9,0x04,0x29,0x0B,0xAA, +0x4D,0x91,0xDA,0x82,0x17,0x28,0x84,0x26,0x39,0x5F,0xAC,0x6E,0x25,0x4B,0x90,0x4F,0xF8,0x9D,0xEB,0xC8, +0x69,0xD2,0x42,0xDC,0x1D,0xC7,0xD1,0x84,0xC2,0xB5,0x77,0x38,0x0D,0x10,0x45,0xD6,0x30,0x25,0x28,0xB2, +0x46,0xB5,0xCA,0xBB,0x31,0xFB,0xDC,0xCD,0xA1,0x0D,0xFD,0x08,0xFB,0x5C,0x69,0x18,0x36,0x61,0x72,0x4D, +0xF8,0x2A,0x60,0x65,0xA0,0xA1,0x2B,0xA9,0xA1,0x50,0xED,0x5E,0x1F,0x74,0x23,0xF9,0x50,0x62,0x2B,0x89, +0xBA,0x13,0xC6,0x39,0x8B,0xA5,0xBD,0x55,0xD2,0x6A,0xD2,0x64,0x1E,0xAF,0x6C,0xC7,0x7A,0xD5,0x37,0xC8, +0x0F,0x40,0xA9,0x9C,0xF8,0x28,0xEA,0xA2,0x88,0xCC,0xA8,0x1B,0x93,0x20,0x88,0x70,0xC3,0x64,0xDD,0x3C, +0x8D,0x8C,0x00,0x71,0xE4,0x2A,0x3F,0x4B,0xE8,0x0C,0xA0,0x19,0xDE,0xDD,0xB1,0xC8,0xBB,0xC3,0xD3,0xF3, +0xB9,0xF3,0xF2,0xE9,0x8C,0x0D,0xE1,0xDF,0x9B,0xD1,0x45,0x78,0x72,0x31,0x83,0xD6,0xA1,0xE8,0x0E,0xDF, +0x1E,0x0D,0xDF,0xC2,0xE3,0xA8,0xDF,0xF9,0x34,0xFD,0x63,0x28,0x86,0x9F,0x06,0x87,0xE3,0x8B,0x93,0xE1, +0xF0,0x65,0xEF,0xF9,0x9B,0xF9,0xFB,0x97,0xBB,0x02,0x7C,0x18,0x39,0xE7,0xEF,0x42,0xE7,0x62,0xEB,0x49, +0x1C,0x3C,0x0B,0x42,0x3F,0xBE,0x18,0xBE,0x7D,0x7F,0x7E,0x73,0x19,0x5F,0xCC,0x46,0xEF,0xFB,0xE1,0x87, +0xAD,0x77,0xA3,0x0F,0xEF,0x7F,0xBE,0xC6,0xBF,0x3C,0x7B,0xF1,0x61,0x3C,0x07,0x84,0x63,0x36,0xBA,0x38, +0x3F,0x7C,0x77,0x38,0xFB,0x70,0xE8,0x9F,0xDC,0x4E,0xA2,0x37,0x87,0x4F,0x87,0x93,0xE1,0x96,0x8F,0xF1, +0x6C,0x7C,0x7E,0x98,0x3F,0x7F,0x79,0x3A,0x23,0x24,0x1C,0x7D,0x78,0x33,0xF6,0x8F,0x1E,0xBD,0xBA,0x78, +0x36,0x24,0xE1,0x9B,0x17,0xE7,0xCE,0xF5,0xD3,0x97,0x47,0xC7,0xFE,0xE5,0x8B,0xCB,0xDD,0xE3,0xED,0xDE, +0x8F,0x3F,0xBE,0x0E,0x4E,0x09,0x1D,0xDF,0x7C,0x1E,0xCE,0x8E,0xE6,0x8F,0xEF,0xB2,0x71,0xF8,0xFC,0x86, +0xF6,0xDE,0xB1,0x4F,0xCF,0xEF,0x5E,0xC3,0xEF,0xD9,0x59,0x67,0x32,0xEA,0x67,0x17,0x6F,0x9F,0xBF,0xDB, +0xCA,0x9E,0x3C,0x4A,0x0E,0x8F,0x8F,0x6F,0xE2,0xC9,0x59,0x2F,0x0E,0xAE,0xA7,0xFC,0xF1,0x36,0x4F,0x2E, +0x67,0xF9,0x87,0x3F,0x1E,0xBD,0x08,0x7B,0xA7,0x18,0x5D,0x86,0x9D,0xBB,0xCF,0x77,0x8F,0xC3,0xF1,0xB3, +0x9B,0x37,0x11,0xBA,0x7D,0xF3,0xC6,0xFF,0x1C,0x77,0x22,0xF4,0xE4,0x74,0x1C,0xA1,0xB4,0x7F,0x11,0x0C, +0x7B,0x9D,0xA3,0xAD,0xE1,0x0E,0x4F,0xCF,0x8F,0xE8,0xF1,0xF6,0xA7,0xD1,0xE3,0xC3,0xC3,0x3E,0x9B,0xFC, +0xB1,0xF5,0xF4,0x7A,0xF7,0xE9,0xC5,0xEE,0xDB,0xC9,0xDB,0xE1,0x68,0xE7,0xF0,0x02,0x5D,0x8E,0xDE,0x0E, +0xA7,0x3B,0x93,0x30,0x7C,0xF9,0x72,0xFC,0x73,0x30,0xFC,0x9C,0x0E,0x4F,0xE7,0xC3,0xDB,0x93,0x8B,0xE1, +0xB3,0xCE,0xCB,0x93,0xD7,0x4E,0x7F,0x74,0xB9,0x3D,0x7B,0xBD,0x3B,0x3F,0xCC,0x4E,0x86,0x6F,0x0F,0x9D, +0xD9,0x8B,0x4E,0x8C,0x3E,0xB0,0xA3,0xED,0xD9,0xF3,0x5D,0x72,0x76,0x89,0x86,0xCF,0x0F,0x5F,0x64,0xE4, +0x3C,0x7E,0x76,0xE1,0x0C,0x87,0xAF,0x4E,0xF1,0xCF,0x47,0xDB,0xE8,0xE5,0x96,0xFF,0x1E,0xF4,0x7F,0xF1, +0x0B,0xFE,0xB1,0x33,0x9C,0x9F,0x3A,0x91,0xFF,0x04,0x8F,0x9F,0x5D,0x8E,0xE5,0xEE,0x9C,0x44,0x3F,0x8F, +0xAF,0x47,0xF9,0xDB,0xF8,0xE8,0xC8,0xD4,0x28,0xEB,0xA6,0x38,0xC1,0x88,0x37,0x63,0x55,0xE5,0x1C,0x60, +0x5B,0xB5,0x15,0x16,0x4E,0x2A,0x22,0x6B,0x37,0xC0,0x3E,0x4B,0x91,0x9C,0x03,0x08,0x38,0x15,0x26,0xB6, +0xFC,0x49,0x86,0x5A,0x4D,0x45,0x5A,0x0D,0xD1,0x40,0x33,0x4A,0x47,0x88,0x09,0x05,0x9C,0x1B,0xE2,0xE3, +0x6E,0x42,0x6E,0x71,0xD4,0x95,0xC8,0xAE,0x63,0x2E,0xA4,0xB3,0x95,0xD3,0x10,0x25,0xB1,0xA2,0x5A,0x0E, +0x04,0x9F,0x90,0x2F,0x52,0x1A,0xB8,0x4C,0x0C,0xCF,0xC2,0x77,0x58,0xDA,0x9D,0xE4,0xB3,0x29,0xB9,0x05, +0x6F,0x9E,0x12,0x4A,0x38,0xD6,0xFA,0xD9,0xF2,0xA7,0x92,0xCC,0x35,0xBE,0x9B,0xA6,0x28,0xC6,0x99,0xF6, +0x37,0xC9,0x2C,0xA6,0x29,0x8B,0x17,0x75,0x04,0xE4,0xAC,0xD1,0x59,0x2E,0xBF,0xC9,0x93,0x88,0x21,0x10, +0x73,0x25,0x6C,0x94,0xC1,0x34,0x15,0x6E,0x55,0x05,0xD5,0xD2,0xCD,0xB6,0xC0,0x2D,0x5B,0x6E,0xBD,0xB5, +0x53,0xBB,0x6E,0x57,0xCE,0x15,0xC1,0xBE,0xA9,0xFA,0x46,0x3C,0x68,0xC4,0xBA,0x6F,0x38,0xA8,0x74,0xFD, +0xE2,0x6A,0x11,0x15,0x19,0x6A,0x06,0x54,0x94,0xEE,0xEF,0x3A,0x8D,0x50,0x01,0xF3,0x96,0xDF,0x60,0x99, +0xE6,0xAD,0x6F,0x92,0x14,0x76,0x03,0xCF,0xBF,0x42,0xB3,0x92,0xA9,0x4D,0x1B,0x68,0x56,0xE9,0x4E,0x89, +0x50,0xE7,0x3C,0xC9,0x6B,0x45,0x7A,0x55,0x2A,0x00,0x57,0xDC,0x3C,0x12,0xDC,0x7C,0x55,0xAB,0xDB,0xBB, +0xDF,0x15,0x3C,0xEC,0x38,0xDF,0x2D,0x6D,0x35,0xB7,0xCA,0xC7,0x7D,0x07,0xFE,0x95,0x69,0xF7,0x71,0xCD, +0xC2,0xE4,0x91,0xF8,0x29,0x19,0x04,0x3A,0x4D,0xE0,0xF6,0xCE,0x93,0xC7,0xC1,0xA4,0x04,0x2A,0xC1,0x1E, +0x86,0xA7,0x28,0x20,0x79,0xE6,0x3E,0x72,0xBE,0x53,0xFA,0x84,0xED,0x03,0xD9,0xCB,0xCD,0x55,0x9D,0xDA, +0x62,0xB3,0x84,0x50,0x6D,0x2B,0xD3,0xC4,0x7E,0xA3,0xB4,0x32,0xCC,0x66,0xAA,0x07,0x17,0xA9,0x4D,0x53, +0xCC,0x5F,0x38,0xDF,0x2D,0x78,0x8A,0x68,0x36,0x65,0x69,0xEC,0xA6,0x8C,0x23,0x8E,0x0D,0xC7,0x5C,0xF6, +0x9D,0x75,0x80,0xED,0x5D,0x27,0xC0,0x33,0x73,0xB9,0xDC,0xEB,0xC9,0xA4,0x06,0x15,0x8F,0x9F,0x92,0x84, +0xEF,0x4F,0x73,0xEA,0x0B,0x1E,0xB4,0x19,0x36,0xB0,0xB9,0x48,0x31,0xCF,0x53,0xAA,0x05,0xCC,0xCF,0x85, +0xB1,0xDB,0x33,0xCC,0x4F,0x94,0xDD,0x1F,0xDE,0x3D,0x0F,0x60,0xC6,0xB2,0x42,0xF0,0xD7,0x22,0x80,0x03, +0xC3,0x7A,0x05,0x4E,0x6B,0x3E,0x24,0x18,0x20,0xF2,0x12,0xDF,0x19,0xD8,0xE2,0x15,0x22,0xB6,0xC5,0xB8, +0x61,0x94,0xD3,0x00,0x48,0xCD,0xC5,0x0D,0x68,0x01,0x79,0xF8,0x23,0xBF,0xB2,0x88,0x47,0xE1,0x31,0x28, +0xA6,0x93,0x7D,0x74,0xD0,0xED,0xBB,0x68,0x9F,0x1C,0xF4,0xC1,0xBF,0xCC,0x06,0x7D,0xB5,0xF2,0xCF,0x24, +0xC2,0x17,0x85,0xCB,0x89,0x85,0x6A,0x6A,0x3D,0x83,0x9C,0x85,0xA0,0x48,0xF3,0x07,0xE3,0x74,0xA4,0x19, +0x1F,0x7F,0xEC,0x3E,0xB9,0xFA,0xD2,0xFF,0xE8,0x74,0xFB,0x57,0xE6,0xEF,0x66,0x8F,0xD8,0x1C,0x67,0xDC, +0xA0,0xE8,0x86,0xCC,0x10,0xD8,0xB9,0x2D,0xF2,0xED,0x70,0x06,0x52,0x98,0x83,0x6A,0x0D,0xA2,0xD8,0xDB, +0x72,0x9C,0x0D,0x0F,0x1F,0xA0,0x08,0x03,0xEB,0xFA,0xC9,0xF9,0xF9,0xE9,0xF9,0x47,0xBD,0x83,0x3B,0xFA, +0x95,0xAB,0xE9,0x1D,0x6A,0xBA,0xDC,0x86,0xA2,0x33,0xC5,0x59,0x78,0x86,0x78,0x68,0x04,0xF6,0x0D,0x8A, +0x72,0xD0,0x85,0x60,0x84,0x79,0xA0,0x38,0x7D,0x92,0x73,0xCE,0xA8,0x6E,0x0E,0x98,0x4D,0x28,0xC5,0xE9, +0xB3,0xF1,0xEB,0x57,0x9E,0x7E,0xCE,0x18,0xD7,0x8E,0x49,0xAA,0x5B,0x72,0x37,0x6C,0x94,0x24,0x98,0x06, +0x47,0x21,0x89,0x02,0x83,0x99,0x03,0x81,0xEE,0x4B,0x74,0x59,0x88,0x00,0xB6,0x6F,0xAB,0x92,0x75,0x0A, +0x52,0xEB,0x96,0x6F,0xC7,0x79,0xC4,0x49,0x12,0x61,0x6F,0xA3,0x0F,0x3D,0x8A,0x62,0x80,0x89,0x34,0x2C, +0x60,0x24,0xF0,0x74,0x15,0x8C,0x8A,0x10,0xB6,0x6E,0x15,0x5F,0xAD,0x12,0xB4,0x56,0x09,0x9A,0xB8,0x09, +0x48,0xA4,0x5B,0x81,0x5D,0xD7,0xCA,0xD0,0x2B,0x96,0x2A,0x61,0x01,0x9E,0x22,0xE0,0xE4,0x9D,0x90,0x1A, +0x4A,0xEF,0x75,0x0B,0x05,0x6A,0xA1,0xAC,0xAD,0x8D,0xAC,0xA9,0x0D,0xB5,0x8D,0xEB,0x90,0x33,0x85,0x9C, +0xB6,0x91,0xD3,0x26,0xF2,0x91,0xB4,0x86,0x75,0xC8,0xA9,0x42,0x8E,0x5A,0x22,0x46,0x52,0x44,0x15,0xE1, +0xBA,0x42,0x9B,0x20,0x10,0x60,0x47,0x4D,0x31,0xA1,0x07,0x0E,0x89,0x26,0x11,0x0E,0xBC,0x0D,0x07,0x7A, +0xA2,0xA8,0xF6,0xB6,0x9C,0x35,0x6B,0x44,0x6A,0x8D,0xBC,0xB5,0x46,0x2E,0xD7,0x20,0x09,0x28,0x11,0xF2, +0x86,0x6E,0xE5,0x52,0x6B,0xED,0x11,0xB5,0x9C,0x1F,0x62,0xFF,0x7A,0xC2,0xE4,0x88,0x6C,0x8B,0x15,0x37, +0x90,0xA4,0x99,0x48,0x9A,0xF2,0x28,0x02,0x34,0x13,0x1B,0xBC,0xDC,0x13,0x94,0xAD,0xA4,0x29,0xBE,0x36, +0x8C,0xB8,0xAD,0x4B,0x84,0xB8,0xAD,0xA5,0xB8,0x35,0x6D,0x84,0x6E,0xB0,0xB6,0x4E,0x4B,0xB1,0xB9,0x66, +0x30,0x59,0x37,0x98,0x9B,0x56,0x6A,0x33,0xEA,0x47,0xC4,0xBF,0xF6,0x6A,0x37,0x36,0x17,0x46,0xB3,0x23, +0x38,0xE1,0x1E,0xC5,0x73,0xED,0x67,0x08,0x4B,0xC7,0x88,0xA3,0x01,0x2F,0xC8,0x18,0x85,0xDD,0x60,0x20, +0x04,0xA7,0x51,0xF0,0xC2,0xCC,0x46,0x01,0x0C,0x9F,0x5D,0x8C,0x75,0x4B,0xEF,0x89,0x5D,0xD1,0xC1,0x93, +0x89,0xB9,0x34,0x2B,0x5F,0xB2,0xA8,0x8C,0xEA,0x17,0x69,0x54,0x0F,0x41,0xA3,0xB4,0xB8,0xA5,0x15,0xAF, +0xE5,0x89,0x4C,0x8D,0x4A,0xA5,0x25,0x53,0xE2,0x64,0x28,0xD6,0x30,0x8A,0xFD,0xD7,0x4D,0x08,0x7B,0xCA, +0x78,0x0D,0xD3,0x42,0x6D,0xA6,0x51,0xC5,0x74,0x8A,0xE6,0xA5,0x91,0xA8,0xF5,0x07,0xCA,0xBD,0x1D,0xC8, +0xBE,0x34,0xE3,0x1A,0xF6,0x76,0x9C,0x27,0xBB,0x03,0xD8,0x1F,0x43,0x39,0x2E,0x00,0xF6,0xB8,0x0D,0xA6, +0x35,0xE3,0xE1,0xC0,0xEF,0x78,0x85,0x56,0x02,0x8F,0xDB,0x59,0x3E,0xC9,0x78,0x0A,0xB9,0xCD,0xF0,0x2D, +0xBF,0x83,0xCD,0xF6,0x32,0x7A,0x87,0x59,0x81,0x69,0xB1,0x4E,0x67,0x79,0x4F,0x41,0xA7,0xA3,0x86,0x86, +0x90,0xD0,0x10,0x8E,0x32,0xAC,0x51,0x1B,0xDF,0x62,0xFF,0x88,0xC5,0x31,0x12,0x24,0x32,0xD8,0xE4,0xA2, +0xA3,0x9B,0x4B,0x8B,0xAD,0xD5,0xCC,0x03,0x21,0xCB,0xCA,0x1E,0xD2,0x23,0x84,0x40,0xCF,0xB7,0x85,0xAF, +0x64,0x85,0x50,0x5F,0xDF,0xE5,0x32,0x10,0x29,0x94,0x8F,0xCE,0x95,0x55,0x6D,0xDC,0x8A,0x54,0xED,0x7D, +0x97,0x56,0xD7,0x8A,0x3F,0x66,0xBD,0xD3,0x02,0xD6,0x8E,0x6B,0x35,0x54,0x5F,0x2E,0x2D,0x5F,0xF0,0x1F, +0x22,0x3A,0xC3,0x7F,0x5F,0x80,0x9A,0x47,0xE9,0xA2,0x16,0x85,0xE4,0x71,0xE0,0xFE,0x6A,0x1B,0x1F,0x7F, +0xB3,0xAF,0x3A,0xA6,0x79,0xF0,0x6D,0x4F,0x6A,0xD8,0xE0,0xE6,0xC7,0xFE,0x95,0x85,0x00,0x6C,0xFF,0x60, +0xFE,0x6A,0x4B,0x70,0x0B,0x36,0xB8,0x61,0x24,0xD0,0xC4,0x4A,0xC2,0xB3,0xD9,0x54,0x43,0x9B,0x9B,0x06, +0x98,0x5C,0xCB,0x58,0x3B,0xBC,0xA3,0xDB,0x90,0x37,0x96,0xCB,0xFB,0xD9,0x6C,0x9C,0x62,0xAC,0xD2,0x65, +0x05,0x90,0xDC,0x83,0xCC,0x2B,0xC1,0xAA,0x94,0x1A,0x5B,0x35,0x14,0x06,0x65,0xBA,0xB7,0x8B,0x4A,0xC2, +0xD3,0x29,0xA3,0x60,0xB2,0xC9,0xFD,0x61,0x79,0xC4,0xD3,0x5B,0x31,0xE4,0xFB,0x3D,0x12,0xCF,0xB4,0x2C, +0xF5,0x3D,0xB5,0x15,0x07,0xE2,0x8F,0xF7,0xBD,0x48,0x73,0x9B,0xBF,0xFB,0x13,0x4F,0xEF,0xC0,0xFE,0x62, +0x9B,0xB2,0xB9,0x61,0x76,0xBE,0xD7,0x35,0x49,0xD1,0xD3,0x63,0x74,0x5B,0x1C,0xF4,0x45,0x25,0x32,0xD0, +0xA0,0x5F,0x96,0xB0,0x6A,0xA0,0x38,0x62,0xA3,0x9C,0xB3,0x81,0x56,0x56,0x38,0xEA,0x88,0xA9,0x6B,0xBD, +0xFD,0xEF,0x6B,0x1D,0x20,0x10,0x1D,0xA9,0x3D,0x21,0x32,0x88,0xE5,0x22,0xE4,0xE1,0x56,0xF4,0x21,0x85, +0xDB,0xA9,0xA8,0x48,0x00,0x4E,0xEE,0xA5,0x4D,0x2B,0x33,0x90,0x79,0x60,0xB4,0x12,0xED,0x9E,0x38,0x94, +0xEC,0x9F,0xA9,0x6A,0x73,0xAF,0x27,0x7B,0xFA,0x3A,0xC7,0x00,0xCD,0x53,0x40,0xB7,0xAA,0xFA,0x66,0xC2, +0x82,0xBB,0x46,0x55,0x94,0x1D,0xDE,0x1D,0x45,0x28,0xCB,0xDE,0xA0,0x18,0xD6,0xF7,0x63,0xDD,0x2C,0x4C, +0x69,0xDF,0xD9,0xDC,0x6C,0x23,0xA5,0x38,0x66,0x37,0x58,0x71,0x85,0x21,0x94,0xB9,0x01,0x10,0xDE,0xDC, +0x5C,0xC7,0x98,0xB8,0x50,0xFB,0x1A,0x57,0x14,0xDC,0xB5,0x0C,0x7F,0xFF,0x13,0x77,0x2A,0x47,0x3E,0xA4, +0xD5,0xC8,0xB4,0x04,0xF7,0x5F,0xBE,0x64,0xF2,0xEF,0x4A,0xA0,0x97,0xFE,0xB2,0xEA,0x2E,0x58,0xBA,0x04, +0xB8,0xDE,0x7D,0xAF,0xE0,0x66,0x36,0x27,0xDC,0x0F,0x85,0xBE,0x7D,0x94,0x61,0x5D,0xDC,0xD4,0xB9,0xB2, +0x35,0xFB,0x5C,0x34,0x3E,0x93,0xA4,0x68,0xCD,0xD1,0x4D,0xD1,0x8A,0x93,0xED,0xA2,0x95,0x04,0x53,0xDD, +0x55,0x45,0xE2,0x86,0xB3,0x2C,0x1A,0xFD,0xA5,0xDC,0xFA,0x68,0x55,0xC3,0xC7,0x6C,0x4E,0x85,0x02,0x2B, +0x2D,0x47,0x6B,0xF6,0xBE,0x4E,0x61,0x95,0xD3,0x05,0x05,0x5E,0x77,0x9A,0x2A,0x9F,0x6B,0xF8,0x47,0x09, +0x03,0xCF,0xC0,0x4B,0xF3,0xFF,0xB2,0x1A,0x5F,0x59,0xCD,0xCA,0x7E,0xAC,0x11,0xF2,0x28,0x84,0x5A,0xF2, +0x2F,0x24,0x8C,0x5B,0x2B,0xC4,0xB6,0x2F,0x9E,0x6F,0x58,0x20,0xA3,0x9F,0x69,0xE5,0x46,0x6C,0xFD,0x8F, +0x06,0x96,0xB4,0x0C,0xAC,0x5D,0x69,0x24,0x6B,0x76,0x0D,0x47,0x98,0xE3,0x4A,0xA2,0x64,0xAD,0x44,0xE9, +0xFF,0xA3,0xF9,0x3A,0x2C,0x11,0x75,0xAE,0x68,0x06,0xA6,0x80,0xDC,0xE8,0x90,0xA0,0xBD,0x36,0x85,0xCC, +0x4F,0x59,0x14,0x8D,0x59,0x72,0xF0,0xC0,0xB8,0x5B,0x8D,0x17,0x8D,0x92,0xCD,0x7A,0x8A,0xE5,0xAF,0x25, +0xFA,0x0A,0x4F,0xF9,0xC1,0x43,0x80,0x87,0xC9,0xD6,0x73,0xAC,0xC0,0xC3,0x36,0x28,0x0F,0x46,0x7F,0xE9, +0xF8,0x56,0x56,0xF5,0x2E,0x3B,0x0C,0xF6,0xC2,0x2F,0x95,0xE4,0x09,0x25,0x59,0x64,0x6D,0xBE,0xA8,0xC7, +0x23,0xA0,0xE8,0x05,0x1D,0x3D,0xB9,0xAD,0xC7,0x38,0x4B,0xBC,0x4C,0x0D,0x21,0x83,0x58,0xFC,0xDE,0xA6, +0xAC,0x8B,0xE2,0xA9,0x47,0x6C,0x36,0x9D,0x66,0x98,0xBF,0x17,0x19,0xC4,0x8A,0xAA,0xFE,0x33,0x99,0x41, +0x06,0xD0,0xA5,0x31,0xCB,0x33,0xCC,0x72,0xDE,0xAE,0x35,0x2B,0x61,0xF6,0x82,0x2F,0x5F,0xAA,0xCE,0x7E, +0xD0,0x49,0xEB,0xEE,0xE5,0x5E,0xD6,0xE8,0xEC,0x67,0x9D,0x08,0x3C,0xE9,0x3F,0xB6,0x14,0xD2,0xB4,0x14, +0x26,0x12,0x98,0xC5,0x94,0xA5,0xA4,0xB5,0xAD,0xA7,0xE2,0x24,0x80,0x1A,0x21,0x56,0x18,0xB4,0x6E,0x96, +0x87,0xDC,0xA6,0x2B,0x23,0x2B,0x6D,0x7B,0xFA,0x43,0xD5,0x76,0x60,0x08,0xAA,0xA0,0xF5,0x57,0x6C,0x8E, +0xD3,0x23,0x94,0x61,0x03,0x22,0x6F,0x95,0x26,0x24,0xD4,0x74,0xB3,0xB5,0xB3,0x68,0x01,0xF5,0xD5,0x13, +0xC2,0xCB,0x57,0xC3,0x02,0x4C,0x10,0x71,0x61,0x0D,0x25,0x73,0xA9,0xB8,0x63,0x54,0x9C,0x98,0x40,0x43, +0x79,0x8B,0x47,0x6C,0x8B,0x0B,0x1E,0xD0,0xDB,0xB1,0x3A,0x20,0x42,0x79,0x8D,0xC1,0x5A,0x58,0x72,0x96, +0xB2,0x04,0xCD,0x90,0x98,0x07,0x63,0xE0,0x60,0x92,0xB8,0xA0,0xD6,0xA8,0x88,0xEA,0xEB,0x86,0x6E,0xDF, +0x03,0x7B,0x95,0x97,0x39,0xA7,0x53,0x03,0x6A,0x27,0xB3,0x9E,0x16,0xFC,0x77,0x49,0x88,0xDF,0xF2,0x22, +0xBB,0x84,0x3C,0xAE,0x5B,0x51,0xD1,0xFC,0x94,0x15,0x0D,0x3F,0x2B,0x5B,0xB7,0x0D,0x20,0xA3,0x25,0x98, +0xD1,0x69,0xD1,0x24,0x94,0x94,0x74,0x4A,0x60,0xF9,0x4C,0x92,0x32,0x93,0x85,0x65,0x2B,0xC4,0xB7,0x15, +0x1E,0xAB,0xF2,0x1C,0x5E,0x97,0xE7,0xEA,0x5B,0x96,0xFF,0x4E,0xFC,0x84,0xCE,0x4A,0x61,0x92,0xB2,0x35, +0x23,0xA5,0x28,0x93,0x38,0xF9,0x2A,0x23,0xE9,0xBF,0x3D,0xF5,0x1D,0x9F,0xBC,0x3A,0x19,0x9F,0x34,0x0F, +0x00,0xCD,0xCB,0x21,0xFE,0x57,0xB7,0x2F,0xDC,0x74,0x8D,0xBF,0x91,0xD4,0xA0,0xEC,0x36,0xCD,0xD6,0xFD, +0x51,0xD4,0xBA,0x97,0xAA,0x33,0x4A,0x71,0xE1,0x03,0x7A,0xDA,0xDC,0x6C,0x30,0x22,0xC7,0xEB,0x3B,0x2D, +0x6A,0xE9,0xAA,0x0A,0x97,0x5E,0x8D,0x1E,0x2A,0x57,0x91,0x59,0x1D,0x08,0x89,0x47,0x8B,0x88,0x62,0x89, +0xB3,0x21,0xD9,0xF7,0xE1,0x50,0xD8,0x31,0xD5,0x5D,0x8E,0xE7,0xC1,0xB5,0x97,0x7F,0x25,0xEF,0x03,0x36, +0x37,0x51,0xBB,0xA4,0x35,0x1C,0x4B,0x02,0xC5,0x82,0xB2,0x25,0x6F,0x22,0x40,0x16,0x60,0xCB,0xB1,0x5E, +0x8C,0x4E,0xDF,0xD8,0x09,0x4A,0xC1,0x21,0xA9,0xD9,0x8C,0x46,0xB9,0x12,0xB0,0xAD,0xED,0xA7,0x27,0x8D, +0xB3,0x96,0x7C,0xDD,0xE7,0xF2,0xA5,0x15,0x19,0x82,0x9C,0xCA,0xD0,0xA2,0xEC,0x29,0xEE,0x65,0x21,0xC7, +0xC5,0x65,0xBE,0xAB,0xC3,0x55,0xDC,0xCC,0x16,0xFC,0x26,0x7F,0xE0,0x3A,0x81,0x87,0x24,0x6B,0x9E,0x31, +0x5B,0x91,0xE1,0x6F,0xEE,0xD8,0xB2,0x6C,0x29,0x72,0xF7,0x8F,0x4B,0xEA,0x45,0xB4,0xDA,0x1C,0x79,0x1C, +0x5E,0xD4,0xA1,0xB8,0x36,0x47,0x1D,0x52,0x18,0xA1,0xBA,0x45,0xFF,0xA9,0x87,0xD0,0xD2,0x43,0xE8,0x6A, +0x80,0xC0,0xB7,0x2D,0x6F,0xAF,0x56,0x19,0x4C,0x80,0xB3,0xEB,0x41,0x1D,0x45,0x00,0x02,0xCF,0xA8,0x05, +0xF8,0x94,0xC9,0xF1,0x4F,0xE8,0x06,0xA9,0x6B,0xD9,0x1A,0xBA,0x3E,0x54,0xC8,0xE9,0xFE,0xEF,0xD0,0xAA, +0x66,0xB6,0x03,0x51,0x06,0xCD,0xD5,0x78,0xC2,0x5B,0xE1,0xA9,0x8E,0x59,0xCD,0xE8,0x04,0xEE,0x5A,0x78, +0xB3,0xC6,0x1B,0xFA,0x6D,0xB8,0x1E,0x18,0xE4,0x43,0xBE,0xD7,0x8C,0xC3,0x0A,0xA3,0x69,0x3D,0xEB,0x0F, +0xA3,0xED,0xE3,0xEA,0xFA,0x3A,0x43,0xFA,0x1F,0x3E,0xC8,0xEC,0xAC,0xBC,0x98,0x01,0x37,0x6F,0xF4,0x74, +0x30,0x88,0x0C,0xCC,0x10,0xA3,0x74,0x24,0xEE,0x00,0x54,0x22,0x59,0xAA,0x0D,0xF4,0xA4,0xEB,0x1A,0xA0, +0xB1,0x9E,0x4C,0x19,0x36,0xE8,0x01,0xE6,0x57,0x40,0x0A,0x40,0xEA,0x31,0x20,0xD9,0x18,0x44,0x30,0x88, +0x3C,0x3D,0x66,0x94,0x5D,0x23,0xD2,0x9C,0x4E,0x00,0x42,0x8A,0xAF,0x04,0xF4,0x0E,0xB5,0x8A,0x7D,0x90, +0x84,0x6A,0x88,0xDA,0x7D,0xB3,0xB8,0xE5,0xAC,0xEF,0x98,0x70,0xE9,0x36,0x85,0x7D,0x6C,0x48,0xB4,0x4C, +0x14,0x1E,0x23,0x9C,0x65,0x92,0x6F,0x21,0xD7,0x6B,0x16,0x80,0x58,0x80,0xD6,0x8B,0xA1,0x25,0x16,0x02, +0x09,0x05,0x60,0x1C,0xE2,0xB8,0x80,0x70,0x68,0x0A,0x10,0x12,0xA0,0x6F,0xA5,0xAA,0x46,0xB2,0xC0,0x23, +0x74,0xE6,0xF5,0x7B,0x8E,0xB5,0x4A,0xF6,0x22,0xC3,0x23,0x36,0xE5,0x63,0x34,0xC9,0x8C,0x0D,0xC7,0x5C, +0x9D,0x21,0x40,0x23,0x88,0x26,0xC6,0x96,0xB9,0x1E,0xFD,0x3D,0x4B,0xAF,0x71,0x5A,0x20,0x8B,0xCA,0x0C, +0x0A,0xB3,0x08,0x7E,0xF9,0xD0,0x17,0x2F,0xFA,0x5F,0x11,0x8A,0x6B,0xE0,0x28,0x64,0xF3,0xB3,0x94,0x50, +0xFE,0x5A,0x1E,0xFA,0x8D,0x8D,0xBE,0xDC,0x27,0x75,0x17,0x25,0x23,0x50,0x79,0x49,0xB5,0x10,0xC1,0xCC, +0x6D,0x5D,0x55,0x59,0x13,0xD8,0x2E,0x88,0xAD,0xEE,0x62,0x4E,0xA8,0xAB,0x1F,0xF1,0x34,0xEA,0x8E,0x74, +0x2B,0x46,0x3E,0x74,0xD4,0x1C,0xE8,0x2F,0x2D,0xE1,0xB4,0x6E,0x33,0x98,0x6C,0xD4,0x9D,0xBA,0x50,0x5F, +0xB9,0xC7,0x6B,0x5F,0x4B,0x09,0xE0,0x61,0xC4,0x26,0x86,0x78,0xE7,0xB0,0x10,0x0E,0xEF,0xD2,0xA5,0x29, +0xB2,0xD3,0xD7,0xAF,0xDC,0x7C,0x88,0xBA,0xDC,0xC2,0x8D,0x1B,0xC3,0x8E,0xAE,0x8B,0x8B,0x38,0xC0,0x43, +0xC1,0x29,0x8D,0xEE,0x5C,0xC8,0x8A,0x7F,0x21,0x75,0x4E,0x03,0xF6,0x35,0xA9,0x3F,0xDC,0x93,0xFA,0xC3, +0x3A,0xA9,0x71,0x7B,0xB7,0xA0,0x73,0x01,0x64,0x5F,0x23,0x8A,0x66,0x38,0x85,0x01,0xB1,0x08,0x6C,0xC0, +0x3F,0xE3,0x2C,0xC5,0x5F,0xE7,0x6C,0x14,0x92,0x29,0x5F,0xE1,0x4F,0x8E,0xFE,0x3B,0x2E,0x53,0xFC,0x00, +0x97,0x65,0x21,0x5B,0xA5,0x8D,0xBF,0xBE,0x07,0x93,0x4E,0xED,0xC1,0x16,0x36,0xDD,0xF5,0x5F,0xF8,0x5D, +0xBD,0xE2,0xD7,0xB3,0xA7,0x78,0xB8,0x78,0x69,0x05,0xC2,0x26,0x40,0x82,0x46,0x7E,0x62,0xF4,0x10,0x4E, +0x0A,0xAF,0x40,0x04,0x43,0x99,0x23,0xF6,0x16,0x4B,0x8B,0x7B,0xC6,0x9C,0x80,0xF8,0x73,0x10,0xCE,0x97, +0xD5,0xAF,0x2D,0xBE,0x56,0x02,0x25,0x00,0x93,0x90,0x67,0x7B,0x1F,0x0F,0x36,0xAF,0x3A,0x90,0xA0,0x3C, +0x78,0x98,0x1E,0x34,0x36,0xAF,0x7E,0x30,0x7B,0x33,0xD2,0x28,0x89,0x64,0xAA,0x03,0xBD,0x7E,0xA4,0x57, +0x1E,0x5A,0x42,0x08,0x6B,0xA6,0xC2,0x2A,0xB0,0x5A,0x58,0x5E,0x69,0xC2,0x43,0x7C,0x04,0x06,0x0F,0x19, +0x3B,0x60,0x36,0xF5,0x1A,0x37,0x8D,0x3A,0x87,0xBF,0x3A,0x84,0xED,0x41,0xC1,0x56,0x80,0xA7,0x84,0x62, +0x19,0xBD,0x54,0xD3,0x2A,0x00,0x42,0x0D,0x24,0x95,0x90,0xB2,0x6D,0x89,0xB6,0xC8,0x7E,0x64,0x26,0x14, +0x69,0xE8,0xE2,0x83,0x0F,0x91,0xE8,0x75,0x99,0xB0,0x57,0xC0,0x73,0x19,0x48,0x1A,0x13,0xD6,0xBC,0xC0, +0xD3,0xF3,0xA2,0xA5,0x83,0x94,0xBC,0x11,0x84,0x95,0x38,0x10,0x6F,0x55,0xE3,0x5E,0x68,0xAF,0x4F,0x3D, +0x0A,0x6C,0x2E,0xC1,0xC5,0x94,0x00,0x81,0x5E,0xA5,0xF3,0x5F,0x5E,0xBF,0x7A,0xC6,0x79,0x72,0xAE,0x76, +0x14,0x68,0xB5,0x07,0x6A,0x43,0x33,0x17,0x3C,0xBD,0x2B,0x0B,0x43,0x11,0x28,0x54,0xA8,0xFB,0xE5,0x74, +0xF2,0x09,0xFB,0x20,0xC9,0xEB,0x0C,0x72,0xE8,0x96,0x2D,0xD0,0xC7,0xE3,0x33,0x7B,0xD7,0x76,0xA0,0x52, +0x81,0xFD,0xF4,0x43,0x61,0x31,0xCB,0x7F,0x84,0xBC,0xFD,0xCF,0x90,0x09,0xC4,0xFB,0x0C,0x02,0x7A,0x89, +0xDF,0xC6,0x0D,0x53,0x36,0x97,0x68,0x27,0x69,0x2A,0x8C,0x61,0x1C,0x92,0x4C,0x9B,0xC0,0x60,0x86,0x53, +0x2D,0x60,0x38,0xD3,0x28,0xE3,0x5A,0x96,0x27,0x09,0x4B,0xF9,0x3D,0x7D,0xD8,0x7A,0x79,0x49,0xF3,0x36, +0xC7,0x39,0x0E,0x8A,0x61,0x9C,0x36,0xF5,0x22,0x6B,0x3A,0x18,0x07,0x77,0xFB,0x78,0x55,0x54,0x78,0x39, +0xA5,0x22,0xFF,0x6C,0xF4,0x55,0x1F,0xA4,0x0B,0x81,0xAA,0x47,0xF3,0x28,0x5A,0x0E,0xEE,0xD1,0xB2,0x93, +0x94,0x71,0x26,0x5F,0x7A,0x2D,0x7E,0x2F,0x5C,0xCB,0xBD,0x77,0x4D,0xDF,0xA6,0xEA,0x58,0x1B,0xC6,0x06, +0xD6,0x08,0xCD,0x38,0xA2,0xBE,0xD8,0x46,0xA5,0x0B,0xB3,0xAC,0xEE,0xC4,0xF4,0x81,0x88,0x0B,0xD2,0x70, +0x1E,0x2C,0x29,0xA4,0x64,0xD4,0xD3,0x75,0x51,0xE8,0x61,0x51,0x2F,0xA3,0x38,0x6B,0x90,0xAD,0x32,0x85, +0x49,0xBD,0x12,0x3C,0x90,0x2F,0x57,0x9A,0xF3,0x57,0xD9,0x28,0xAB,0x7B,0x04,0x30,0xAD,0x9C,0x67,0xD2, +0x8E,0xA7,0xCB,0x0A,0xE1,0x40,0x86,0x0C,0x69,0xC0,0x31,0xE6,0x21,0x0B,0x0E,0xF4,0x03,0xDD,0xD5,0xE1, +0xFF,0xA6,0x6E,0xC1,0x2C,0x4C,0x7D,0x16,0xE0,0x8B,0xF3,0xE7,0x10,0x4A,0x13,0x46,0x31,0xE5,0x06,0x82, +0x8C,0xE2,0xE9,0x9D,0x55,0x48,0xC5,0xC6,0x47,0x74,0x65,0x0E,0xDA,0xCA,0xC6,0xF3,0x7B,0xDB,0xD9,0xDA, +0x0C,0x9B,0x51,0x11,0x5D,0xEF,0x80,0x79,0x8E,0x57,0x5E,0x8E,0x58,0x74,0xF5,0x14,0x64,0x2E,0x76,0x04, +0xCF,0x12,0x6B,0x04,0x58,0xC2,0xF5,0x6A,0x25,0x3F,0x54,0xD9,0x51,0xDB,0x47,0x51,0x24,0x3E,0xE6,0x00, +0x5E,0xC5,0x62,0x79,0x66,0x09,0x22,0x19,0x08,0x90,0xE1,0x31,0xBE,0x05,0x97,0x96,0xE5,0x99,0xB2,0xA1, +0xE2,0x38,0x04,0xA4,0x79,0xC3,0x8C,0x4C,0xAB,0xEA,0x6D,0x6E,0x72,0xBB,0x34,0x13,0xA3,0x44,0xCA,0x44, +0xB2,0x91,0x77,0x0F,0x4B,0xA3,0x29,0xA4,0xC8,0xDD,0x2B,0xDA,0x36,0xDA,0x6A,0x48,0x30,0x35,0x4A,0x18, +0x70,0x96,0xA7,0x11,0x64,0x08,0x51,0xBD,0xB4,0xA6,0x65,0x98,0x06,0xB0,0x80,0xFB,0x97,0xC8,0x12,0x95, +0x36,0xAD,0x62,0xC4,0x53,0xC5,0x77,0x9B,0x1E,0x2F,0x76,0xE5,0x19,0x96,0x61,0xAE,0xFD,0xF5,0xAD,0x25, +0xBF,0x9B,0x25,0x2A,0x21,0xF4,0xE0,0x6D,0xCA,0x7C,0xDE,0x05,0xB3,0x8A,0xBB,0xB0,0x82,0xB2,0x82,0x40, +0x5F,0xC3,0xA1,0x3A,0xED,0x59,0xE2,0x3A,0xC5,0xBD,0xE7,0xA2,0xB5,0xFE,0x8C,0x7B,0x3E,0xDA,0xA6,0xD3, +0xE6,0xB3,0xB1,0xDB,0x7B,0x3B,0xF7,0x40,0x68,0xC2,0x52,0x6E,0x40,0x8E,0x83,0x34,0x58,0xAD,0x56,0x1E, +0xBC,0x9A,0x71,0xC1,0x4E,0xF2,0x2C,0x34,0x16,0xC0,0xBA,0xCB,0x2D,0xA5,0x2B,0x17,0x5B,0xCA,0x6E,0x5D, +0x6A,0x95,0xF6,0xE1,0x42,0xEA,0x6A,0xC5,0x8F,0x2F,0x5F,0x64,0xAF,0xDE,0x6D,0xE8,0xB5,0x37,0x1C,0x84, +0x95,0x4E,0x5C,0x66,0x64,0x61,0xF4,0xF7,0x63,0xD5,0x5E,0x4F,0x9D,0xA7,0xCA,0xCF,0x5D,0x34,0x12,0x78, +0x22,0xB9,0xEB,0xC5,0x7B,0x2D,0x68,0x4E,0x21,0x2E,0xD9,0x70,0x00,0xAB,0xBE,0x6F,0xD6,0x8B,0x0F,0x9C, +0xEF,0xE3,0xEE,0x57,0x27,0x42,0xCF,0xAB,0xEA,0x79,0x15,0x75,0xD4,0x04,0xEF,0x81,0x8F,0x60,0x74,0x05, +0x86,0x03,0xB3,0x6A,0xD8,0xD5,0xDA,0x62,0x5D,0xAB,0x18,0x44,0xD9,0x1D,0xF5,0x45,0xD4,0xAC,0xA8,0x84, +0xA0,0xFE,0xD6,0x21,0x5A,0xCD,0x34,0x97,0x35,0x67,0xE2,0xFA,0x51,0x63,0xC5,0x5B,0x87,0x66,0x8D,0x01, +0xEC,0xC3,0x19,0x5D,0x88,0x5B,0xBA,0xA8,0x26,0x0F,0xE9,0x55,0x17,0xC4,0x83,0x09,0xF5,0xAC,0x3C,0x59, +0x0F,0x90,0x25,0xC1,0xCA,0xA0,0xAA,0x2A,0x56,0x86,0x8B,0x83,0x5E,0xF5,0x2E,0xB0,0xF1,0xFD,0x52,0x4D, +0x83,0xC8,0x57,0x27,0x72,0x7E,0xFB,0x6D,0xCA,0x83,0x68,0x0A,0x63,0xFF,0x4F,0x51,0x09,0xC4,0x79,0xD4, +0x2E,0x00,0x00 }; From 00b4fba84963fd4407897a5cdb86dd5275562f30 Mon Sep 17 00:00:00 2001 From: lorol Date: Thu, 24 Sep 2020 15:19:15 -0400 Subject: [PATCH 076/551] Update README.md --- extras/README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/extras/README.md b/extras/README.md index 23c2032cf..ac2457282 100644 --- a/extras/README.md +++ b/extras/README.md @@ -17,6 +17,9 @@ until a } is found on separate new line. ``` npm install html-minifier-terser -g, npm install -g github-files-fetcher ``` ### Batch files provided -- **do.bat:** Generates **edit.htm.gz.h** file +- **do_emb.bat:** Generates **edit.htm.gz.h** file for embedding to **SPIFFSEditor.cpp** as binary C array - +You need to comment **#define EDFS** at **SPIFFSEditor.cpp** for this choice +- **do_ed_fs.bat:** Alternatively, makes a gzip-ed **edit.htm** file for fs - +uncomment **#define EDFS** for this choice. Saves about 4k of program flash storage. - **undo.bat:** Reverts **edit.htm** from C array header to file (still minified!) - **update_ace.bat:** Updates **acefull.js.gz** file from latest GitHub Ace sources From b16a9c29d993d9bd664b8d4bb6d94df5822868e3 Mon Sep 17 00:00:00 2001 From: lorol Date: Tue, 13 Oct 2020 10:34:29 -0400 Subject: [PATCH 077/551] Added json mode and worker to editor Example - updates --- .../ESP_AsyncFSBrowser/data/acefull.js.gz | Bin 117524 -> 118766 bytes examples/ESP_AsyncFSBrowser/data/edit.htm | Bin 4503 -> 4503 bytes .../ESP_AsyncFSBrowser/data/worker-css.js.gz | Bin 32927 -> 32927 bytes .../ESP_AsyncFSBrowser/data/worker-html.js.gz | Bin 45019 -> 45019 bytes .../data/worker-javascript.js.gz | Bin 112558 -> 112558 bytes .../ESP_AsyncFSBrowser/data/worker-json.js.gz | Bin 0 -> 6923 bytes examples/SmartSwitch/SmartSwitch.ino | 90 ++++++++++-------- examples/SmartSwitch/data/acefull.js.gz | Bin 117524 -> 118766 bytes examples/SmartSwitch/data/edit.htm | Bin 4503 -> 4503 bytes examples/SmartSwitch/data/worker-css.js.gz | Bin 32927 -> 32927 bytes examples/SmartSwitch/data/worker-html.js.gz | Bin 45019 -> 45019 bytes .../SmartSwitch/data/worker-javascript.js.gz | Bin 112558 -> 112558 bytes examples/SmartSwitch/data/worker-json.js.gz | Bin 0 -> 6923 bytes extras/update_ace.bat | 7 +- src/edit.htm.gz.h | 2 +- 15 files changed, 55 insertions(+), 44 deletions(-) create mode 100644 examples/ESP_AsyncFSBrowser/data/worker-json.js.gz create mode 100644 examples/SmartSwitch/data/worker-json.js.gz diff --git a/examples/ESP_AsyncFSBrowser/data/acefull.js.gz b/examples/ESP_AsyncFSBrowser/data/acefull.js.gz index 560a0fa10d7a284b356f160f982d03407cc61502..42cd5e87724f3765698a6aef40c852f786905e42 100644 GIT binary patch delta 6382 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 delta 5130 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 diff --git a/examples/ESP_AsyncFSBrowser/data/edit.htm b/examples/ESP_AsyncFSBrowser/data/edit.htm index 95099096172853e05dce9881d28b499dd0ebddd4..6620caab1b5d747bd72794f957a8d78c19ae9827 100644 GIT binary patch delta 16 XcmbQPJYAVxzMF%i^Ho4FEds2Aco? delta 18 ZcmbQ=$TYu^iCw;%gX90S?2YU*8UQ^e2G#%o diff --git a/examples/ESP_AsyncFSBrowser/data/worker-html.js.gz b/examples/ESP_AsyncFSBrowser/data/worker-html.js.gz index 8bacd4aaa83b52d87a0ee63ff1977aea05c24816..19b5d9e4e6d9b7d5ae8a330732372afda5406eee 100644 GIT binary patch delta 18 acmcb8pXv5}CU*I54i4wvZ5!FItOo#2tOz*( delta 18 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 MEMMAX) memch = 0; EEPROM.get(EEBEGIN + memch*sizeof(ee), ChkEE); @@ -199,6 +200,15 @@ void readEE() { } } +void doOut(){ + if (ledOut != ledState){ // only if changed + digitalWrite(ledPin, ledState); //consolidated here + ledOut = ledState; //update + if (ledState == LED_OFF) ws.textAll("led,ledoff"); + else ws.textAll("led,ledon"); + } +} + void showTime() { byte tmpch = 0; @@ -208,13 +218,13 @@ void showTime() now = time(nullptr); const tm* tm = localtime(&now); ws.printfAll("Now,Clock,%02d:%02d,%d", tm->tm_hour, tm->tm_min, tm->tm_wday); - if ((2==tm->tm_hour )&&(2==tm->tm_min)) { + if ((2==tm->tm_hour )&&(2==tm->tm_min)){ configTzTime(MYTZ, "pool.ntp.org"); Serial.print(F("Sync Clock at 02:02\n")); } Serial.printf("RTC: %02d:%02d\n", tm->tm_hour, tm->tm_min); - if (sched == 0) { // automatic + if (sched == 0){ // automatic if ((tm->tm_wday > 0)&&(tm->tm_wday < 6)) tmpch = 0; //Mon - Fri else if (tm->tm_wday == 6) tmpch = 1; //Sat else if (tm->tm_wday == 0) tmpch = 2; //Sun @@ -222,7 +232,7 @@ void showTime() tmpch = sched - 1; //and stays } - if (tmpch != memch) { // update if different + if (tmpch != memch){ // update if different memch = tmpch; readEE(); ws.printfAll("Now,Setting,%02d:%02d,%02d:%02d,%+2.1f", ee.hstart, ee.mstart, ee.hstop, ee.mstop, ee.tempe); @@ -237,20 +247,18 @@ void showTime() else { //enable smart if different if (((bmi < emi)&&(bmi <= xmi)&&(xmi < emi))|| - ((emi < bmi)&&((bmi <= xmi)||(xmi < emi)))) { + ((emi < bmi)&&((bmi <= xmi)||(xmi < emi)))){ heat_enabled = true; } else heat_enabled = false; } - if (heat_enabled_prev) { // smart control (delayed one cycle) - if (((t + HYST) < ee.tempe)&&(ledState == LED_OFF)) { // OFF->ON once + if (heat_enabled_prev){ // smart control (delayed one cycle) + if (((t + HYST) < ee.tempe)&&(ledState == LED_OFF)){ // OFF->ON once ledState = LED_ON; - digitalWrite(ledPin, ledState); // apply change ws.textAll("led,ledon"); } - if ((((t - HYST) > ee.tempe)&&(ledState == LED_ON))||(!heat_enabled)) { // ON->OFF once, also turn off at end of period. + if ((((t - HYST) > ee.tempe)&&(ledState == LED_ON))||(!heat_enabled)){ // ON->OFF once, also turn off at end of period. ledState = LED_OFF; - digitalWrite(ledPin, ledState); // apply change ws.textAll("led,ledoff"); } @@ -263,7 +271,7 @@ void showTime() void updateDHT(){ float h1 = dht.readHumidity(); float t1 = dht.readTemperature(); //Celsius or dht.readTemperature(true) for Fahrenheit - if (isnan(h1) || isnan(t1)) { + if (isnan(h1) || isnan(t1)){ Serial.println(F("Failed to read from DHT sensor!")); } else { h = h1 + DHT_H_CORR; @@ -279,11 +287,10 @@ void analogSample() void checkPhysicalButton() { - if (digitalRead(btnPin) == LOW) { - if (btnState != LOW) { // btnState is used to avoid sequential toggles + if (digitalRead(btnPin) == LOW){ + if (btnState != LOW){ // btnState is used to avoid sequential toggles ledState = !ledState; - digitalWrite(ledPin, ledState); - if (ledState == LED_OFF) { + if (ledState == LED_OFF){ ws.textAll("led,ledoff"); Serial.println(F("LED-OFF")); } else { @@ -297,17 +304,17 @@ void checkPhysicalButton() } } -void mytimer() { +void mytimer(){ ++count; //200ms increments checkPhysicalButton(); - if ((count % 25) == 1) { // update temp every 5 seconds + if ((count % 25) == 1){ // update temp every 5 seconds analogSample(); udht = true; } - if ((count % 50) == 0) { // update temp every 10 seconds + if ((count % 50) == 0){ // update temp every 10 seconds ws.cleanupClients(); } - if (count >= 150) { // cycle every 30 sec + if (count >= 150){ // cycle every 30 sec showTime(); count = 0; } @@ -385,22 +392,21 @@ void onWsEvent(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventT Serial.printf("ws[%s][%u] %s-message[%llu]: ", server->url(), client->id(), (info->opcode == WS_TEXT)?"text":"binary", info->len); if(info->opcode == WS_TEXT){ - for(size_t i=0; i < info->len; i++) { //debug + for(size_t i=0; i < info->len; i++){ //debug msg += (char) data[i]; } - if(data[0] == 'L') { // LED - if(data[1] == '1') { + if(data[0] == 'L'){ // LED + if(data[1] == '1'){ ledState = LED_ON; ws.textAll("led,ledon"); // for others } - else if(data[1] == '0') { + else if(data[1] == '0'){ ledState = LED_OFF; ws.textAll("led,ledoff"); } - digitalWrite(ledPin, ledState); // apply change - } else if(data[0] == 'T') { // timeset - if (len > 11) { + } else if(data[0] == 'T'){ // timeset + if (len > 11){ data[3] = data[6] = data[9] = data[12] = 0; // cut strings ee.hstart = (uint8_t) atoi((const char *) &data[1]); ee.mstart = (uint8_t) atoi((const char *) &data[4]); @@ -411,8 +417,8 @@ void onWsEvent(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventT memch = 255; // to force showTime()to send Setting showTime(); } - } else if(data[0] == 'W') { // temperatureset - if (len > 3) { + } else if(data[0] == 'W'){ // temperatureset + if (len > 3){ if (ee.tempe != (float) atof((const char *) &data[1])){ ee.tempe = (float) atof((const char *) &data[1]); Serial.printf("[%u] Temp set %+2.1f\n", client->id(), ee.tempe); @@ -421,7 +427,7 @@ void onWsEvent(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventT showTime(); } } - } else if ((data[0] == 'Z')&&(len > 2)) { // sched + } else if ((data[0] == 'Z')&&(len > 2)){ // sched data[2] = 0; if (sched != (uint8_t) atoi((const char *) &data[1])){ sched = (uint8_t) atoi((const char *) &data[1]); @@ -434,7 +440,7 @@ void onWsEvent(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventT } else { char buff[3]; - for(size_t i=0; i < info->len; i++) { + for(size_t i=0; i < info->len; i++){ sprintf(buff, "%02x ", (uint8_t) data[i]); msg += buff ; } @@ -457,12 +463,12 @@ void onWsEvent(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventT Serial.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 < len; i++) { + for(size_t i=0; i < len; i++){ msg += (char) data[i]; } } else { char buff[3]; - for(size_t i=0; i < len; i++) { + for(size_t i=0; i < len; i++){ sprintf(buff, "%02x ", (uint8_t) data[i]); msg += buff ; } @@ -488,7 +494,7 @@ void onWsEvent(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventT void setup(){ Serial.begin(115200); - Serial.setDebugOutput(true); + //Serial.setDebugOutput(true); //Wifi #ifdef USE_WFM @@ -511,7 +517,7 @@ void setup(){ //WiFi.softAP(hostName); // Core SVN 5179 use STA as default interface in mDNS (#7042) WiFi.mode(WIFI_STA); // Core SVN 5179 use STA as default interface in mDNS (#7042) WiFi.begin(ssid, password); - if (WiFi.waitForConnectResult() != WL_CONNECTED) { + if (WiFi.waitForConnectResult() != WL_CONNECTED){ Serial.print(F("STA: Failed!\n")); WiFi.disconnect(false); delay(1000); @@ -545,15 +551,14 @@ void setup(){ EEPROM.begin(EEALL); //EEPROM.get(EECH, memch); //current channel, no need readEE(); // populate structure if healthy - digitalWrite(ledPin, ledState); Serial.printf("Timer set %02d:%02d - %02d:%02d\n", ee.hstart, ee.mstart, ee.hstop, ee.mstop); Serial.printf("Temp set %+2.1f\n", ee.tempe); //FS #ifdef USE_FatFS - if (MYFS.begin(false,"/ffat",3)) { //limit the RAM usage, bottom line 8kb + 4kb takes per each file, default is 10 + if (MYFS.begin(false,"/ffat",3)){ //limit the RAM usage, bottom line 8kb + 4kb takes per each file, default is 10 #else - if (MYFS.begin()) { + if (MYFS.begin()){ #endif Serial.print(F("FS mounted\n")); } else { @@ -654,7 +659,7 @@ void setup(){ #ifdef USE_AUTH_STAT if(!request->authenticate(http_username, http_password)) return request->requestAuthentication(); #endif - request->onDisconnect([]() { + request->onDisconnect([](){ #ifdef ESP32 ESP.restart(); #elif defined(ESP8266) @@ -672,7 +677,7 @@ void setup(){ #ifdef USE_AUTH_STAT if(!request->authenticate(http_username, http_password)) return request->requestAuthentication(); #endif - request->onDisconnect([]() { + request->onDisconnect([](){ #ifdef ESP32 /* //https://github.com/espressif/arduino-esp32/issues/400#issuecomment-499631249 @@ -726,7 +731,7 @@ void setup(){ //OTA ArduinoOTA.setHostname(hostName); - ArduinoOTA.onStart([]() { + ArduinoOTA.onStart([](){ Serial.print(F("OTA Started ...\n")); MYFS.end(); // Clean FS ws.textAll("Now,OTA"); // for all clients @@ -742,5 +747,6 @@ void loop(){ updateDHT(); udht = false; } + doOut(); ArduinoOTA.handle(); } diff --git a/examples/SmartSwitch/data/acefull.js.gz b/examples/SmartSwitch/data/acefull.js.gz index 560a0fa10d7a284b356f160f982d03407cc61502..42cd5e87724f3765698a6aef40c852f786905e42 100644 GIT binary patch delta 6382 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 delta 5130 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 diff --git a/examples/SmartSwitch/data/edit.htm b/examples/SmartSwitch/data/edit.htm index 95099096172853e05dce9881d28b499dd0ebddd4..6620caab1b5d747bd72794f957a8d78c19ae9827 100644 GIT binary patch delta 16 XcmbQPJYAVxzMF%i^Ho4FEds2Aco? delta 18 ZcmbQ=$TYu^iCw;%gX90S?2YU*8UQ^e2G#%o diff --git a/examples/SmartSwitch/data/worker-html.js.gz b/examples/SmartSwitch/data/worker-html.js.gz index 8bacd4aaa83b52d87a0ee63ff1977aea05c24816..19b5d9e4e6d9b7d5ae8a330732372afda5406eee 100644 GIT binary patch delta 18 acmcb8pXv5}CU*I54i4wvZ5!FItOo#2tOz*( delta 18 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 acefull.js +type ace.js mode-html.js mode-json.js theme-monokai.js ext-searchbox.js > acefull.js "C:\Program Files\7-Zip\7z.exe" a -tgzip -mx9 acefull.js.gz acefull.js "C:\Program Files\7-Zip\7z.exe" a -tgzip -mx9 worker-html.js.gz worker-html.js "C:\Program Files\7-Zip\7z.exe" a -tgzip -mx9 worker-javascript.js.gz worker-javascript.js +"C:\Program Files\7-Zip\7z.exe" a -tgzip -mx9 worker-json.js.gz worker-json.js "C:\Program Files\7-Zip\7z.exe" a -tgzip -mx9 worker-css.js.gz worker-css.js REM update SmartSwitch /data: @@ -25,6 +28,7 @@ pause copy acefull.js.gz ..\..\examples\SmartSwitch\data\acefull.js.gz copy worker-html.js.gz ..\..\examples\SmartSwitch\data\worker-html.js.gz copy worker-javascript.js.gz ..\..\examples\SmartSwitch\data\worker-javascript.js.gz +copy worker-json.js.gz ..\..\examples\SmartSwitch\data\worker-json.js.gz copy worker-css.js.gz ..\..\examples\SmartSwitch\data\worker-css.js.gz REM update ESP_AsyncFSBrowser /data: @@ -32,6 +36,7 @@ pause copy acefull.js.gz ..\..\examples\ESP_AsyncFSBrowser\data\acefull.js.gz copy worker-html.js.gz ..\..\examples\ESP_AsyncFSBrowser\data\worker-html.js.gz copy worker-javascript.js.gz ..\..\examples\ESP_AsyncFSBrowser\data\worker-javascript.js.gz +copy worker-json.js.gz ..\..\examples\ESP_AsyncFSBrowser\data\worker-json.js.gz copy worker-css.js.gz ..\..\examples\ESP_AsyncFSBrowser\data\worker-css.js.gz REM delete temporary stuff diff --git a/src/edit.htm.gz.h b/src/edit.htm.gz.h index 7b9c3b3ca..5a0008992 100644 --- a/src/edit.htm.gz.h +++ b/src/edit.htm.gz.h @@ -2,7 +2,7 @@ //File: edit.htm.gz, Size: 4503 #define edit_htm_gz_len 4503 const uint8_t edit_htm_gz[] PROGMEM = { -0x1F,0x8B,0x08,0x08,0x2A,0x97,0x6B,0x5F,0x02,0x00,0x65,0x64,0x69,0x74,0x2E,0x68,0x74,0x6D,0x00,0xB5, +0x1F,0x8B,0x08,0x08,0x89,0xFA,0x86,0x5F,0x02,0x00,0x65,0x64,0x69,0x74,0x2E,0x68,0x74,0x6D,0x00,0xB5, 0x1A,0x0B,0x5B,0xDB,0x36,0xF0,0xAF,0x18,0x6F,0x63,0xF6,0xE2,0x38,0x0E,0x50,0xD6,0x3A,0x18,0x16,0x1E, 0xEB,0xBB,0x50,0x12,0xDA,0xD1,0x8E,0xED,0x53,0x6C,0x25,0x56,0xB1,0x25,0xCF,0x96,0x09,0x34,0xCD,0x7F, 0xDF,0x49,0xF2,0x93,0x84,0xEE,0xF1,0x6D,0xA5,0x60,0x49,0xA7,0x3B,0xDD,0x9D,0xEE,0x25,0xD9,0x7B,0x1B, From 35ef3ad84205635bcec9af5d073dfdaa3a740f6a Mon Sep 17 00:00:00 2001 From: lorol Date: Sun, 25 Oct 2020 22:11:22 -0400 Subject: [PATCH 078/551] Bugfix - my additions. --- .../ESP_AsyncFSBrowser/data/.exclude.files | 4 ++-- .../ESP_AsyncFSBrowser/data/acefull.js.gz | Bin 118766 -> 118766 bytes .../data/{edit.htm => edit_gz} | Bin 4503 -> 4503 bytes .../ESP_AsyncFSBrowser/data/worker-css.js.gz | Bin 32927 -> 32927 bytes .../ESP_AsyncFSBrowser/data/worker-html.js.gz | Bin 45019 -> 45019 bytes .../data/worker-javascript.js.gz | Bin 112558 -> 112558 bytes .../ESP_AsyncFSBrowser/data/worker-json.js.gz | Bin 6923 -> 6923 bytes examples/SmartSwitch/SmartSwitch.ino | 18 ++++++++---------- examples/SmartSwitch/data/.exclude.files | 2 +- examples/SmartSwitch/data/acefull.js.gz | Bin 118766 -> 118766 bytes .../SmartSwitch/data/{edit.htm => edit_gz} | Bin 4503 -> 4503 bytes examples/SmartSwitch/data/worker-css.js.gz | Bin 32927 -> 32927 bytes examples/SmartSwitch/data/worker-html.js.gz | Bin 45019 -> 45019 bytes .../SmartSwitch/data/worker-javascript.js.gz | Bin 112558 -> 112558 bytes examples/SmartSwitch/data/worker-json.js.gz | Bin 6923 -> 6923 bytes extras/do_ed_fs.bat | 4 ++-- src/SPIFFSEditor.cpp | 2 +- src/edit.htm.gz.h | 2 +- 18 files changed, 15 insertions(+), 17 deletions(-) rename examples/ESP_AsyncFSBrowser/data/{edit.htm => edit_gz} (98%) rename examples/SmartSwitch/data/{edit.htm => edit_gz} (98%) diff --git a/examples/ESP_AsyncFSBrowser/data/.exclude.files b/examples/ESP_AsyncFSBrowser/data/.exclude.files index ba74486a2..a1c42787a 100644 --- a/examples/ESP_AsyncFSBrowser/data/.exclude.files +++ b/examples/ESP_AsyncFSBrowser/data/.exclude.files @@ -1,3 +1,3 @@ -/*.js.gz -/edit.htm +/*.gz +/edit_gz /.exclude.files diff --git a/examples/ESP_AsyncFSBrowser/data/acefull.js.gz b/examples/ESP_AsyncFSBrowser/data/acefull.js.gz index 42cd5e87724f3765698a6aef40c852f786905e42..8ba7fd8a73c8744cd2a2edd3205bd2afcb36833a 100644 GIT binary patch delta 21 dcmaDipZ(o@c6Rx04vwTPQyba0vNJwE4**{82#^2( delta 21 dcmaDipZ(o@c6Rx04i4AfZH??(*%_ao2LNBx2&(`9 diff --git a/examples/ESP_AsyncFSBrowser/data/edit.htm b/examples/ESP_AsyncFSBrowser/data/edit_gz similarity index 98% rename from examples/ESP_AsyncFSBrowser/data/edit.htm rename to examples/ESP_AsyncFSBrowser/data/edit_gz index 6620caab1b5d747bd72794f957a8d78c19ae9827..323f93ec3763003d9a988e6119bb9cabbf93bbb1 100644 GIT binary patch delta 16 XcmbQPJYAVxzMF&NsNS@V>=Oh5Dx?J% delta 16 XcmbQPJYAVxzMF%i^Ho4FEds2Aco? diff --git a/examples/ESP_AsyncFSBrowser/data/worker-html.js.gz b/examples/ESP_AsyncFSBrowser/data/worker-html.js.gz index 19b5d9e4e6d9b7d5ae8a330732372afda5406eee..beef3c194fee47f2481918ca233af25fe0256cc2 100644 GIT binary patch delta 18 acmcb8pXv5}CU*I54vzROQ#Z0-Sq}hC5eOXs delta 18 acmcb8pXv5}CU*I54i4wvZ5!FItOo#2tOz*( diff --git a/examples/ESP_AsyncFSBrowser/data/worker-javascript.js.gz b/examples/ESP_AsyncFSBrowser/data/worker-javascript.js.gz index 5ad84ceaa2ed99fddf81ae1adad50c6aabda632e..02c0e6f39f64f7bb37c543d5000bd63c047f258d 100644 GIT binary patch delta 21 dcmZ4Yo^9QGHg@@L4vxevQyba0vNJB<4gg>J2vq<8 delta 21 dcmZ4Yo^9QGHg@@L4i4AfZH??(*%_B_2LNE{2yp-a diff --git a/examples/ESP_AsyncFSBrowser/data/worker-json.js.gz b/examples/ESP_AsyncFSBrowser/data/worker-json.js.gz index e1de25bd0450183027aa0b0a808cd43483163049..f917582a23fa4abb51e368fb4e3308d38c9cbcaa 100644 GIT binary patch delta 16 XcmeA+>o#MT@8;l0+A?(`JBu^`Dy#&? delta 16 XcmeA+>o#MT@8;le{oS^aokbb|D?kL{ diff --git a/examples/SmartSwitch/SmartSwitch.ino b/examples/SmartSwitch/SmartSwitch.ino index 796bb99a3..658942f34 100644 --- a/examples/SmartSwitch/SmartSwitch.ino +++ b/examples/SmartSwitch/SmartSwitch.ino @@ -204,8 +204,13 @@ void doOut(){ if (ledOut != ledState){ // only if changed digitalWrite(ledPin, ledState); //consolidated here ledOut = ledState; //update - if (ledState == LED_OFF) ws.textAll("led,ledoff"); - else ws.textAll("led,ledon"); + if (ledState == LED_OFF){ + ws.textAll("led,ledoff"); + Serial.println(F("LED-OFF")); + } else { + ws.textAll("led,ledon"); + Serial.println(F("LED-ON")); + } } } @@ -257,7 +262,7 @@ void showTime() ledState = LED_ON; ws.textAll("led,ledon"); } - if ((((t - HYST) > ee.tempe)&&(ledState == LED_ON))||(!heat_enabled)){ // ON->OFF once, also turn off at end of period. + if ((((t - HYST) > ee.tempe)&&(ledState == LED_ON))||(!heat_enabled)){ // ->OFF ledState = LED_OFF; ws.textAll("led,ledoff"); } @@ -290,13 +295,6 @@ void checkPhysicalButton() if (digitalRead(btnPin) == LOW){ if (btnState != LOW){ // btnState is used to avoid sequential toggles ledState = !ledState; - if (ledState == LED_OFF){ - ws.textAll("led,ledoff"); - Serial.println(F("LED-OFF")); - } else { - ws.textAll("led,ledon"); - Serial.println(F("LED-ON")); - } } btnState = LOW; } else { diff --git a/examples/SmartSwitch/data/.exclude.files b/examples/SmartSwitch/data/.exclude.files index 664e3b71e..a1c42787a 100644 --- a/examples/SmartSwitch/data/.exclude.files +++ b/examples/SmartSwitch/data/.exclude.files @@ -1,3 +1,3 @@ /*.gz -/edit.htm +/edit_gz /.exclude.files diff --git a/examples/SmartSwitch/data/acefull.js.gz b/examples/SmartSwitch/data/acefull.js.gz index 42cd5e87724f3765698a6aef40c852f786905e42..8ba7fd8a73c8744cd2a2edd3205bd2afcb36833a 100644 GIT binary patch delta 21 dcmaDipZ(o@c6Rx04vwTPQyba0vNJwE4**{82#^2( delta 21 dcmaDipZ(o@c6Rx04i4AfZH??(*%_ao2LNBx2&(`9 diff --git a/examples/SmartSwitch/data/edit.htm b/examples/SmartSwitch/data/edit_gz similarity index 98% rename from examples/SmartSwitch/data/edit.htm rename to examples/SmartSwitch/data/edit_gz index 6620caab1b5d747bd72794f957a8d78c19ae9827..323f93ec3763003d9a988e6119bb9cabbf93bbb1 100644 GIT binary patch delta 16 XcmbQPJYAVxzMF&NsNS@V>=Oh5Dx?J% delta 16 XcmbQPJYAVxzMF%i^Ho4FEds2Aco? diff --git a/examples/SmartSwitch/data/worker-html.js.gz b/examples/SmartSwitch/data/worker-html.js.gz index 19b5d9e4e6d9b7d5ae8a330732372afda5406eee..beef3c194fee47f2481918ca233af25fe0256cc2 100644 GIT binary patch delta 18 acmcb8pXv5}CU*I54vzROQ#Z0-Sq}hC5eOXs delta 18 acmcb8pXv5}CU*I54i4wvZ5!FItOo#2tOz*( diff --git a/examples/SmartSwitch/data/worker-javascript.js.gz b/examples/SmartSwitch/data/worker-javascript.js.gz index 5ad84ceaa2ed99fddf81ae1adad50c6aabda632e..02c0e6f39f64f7bb37c543d5000bd63c047f258d 100644 GIT binary patch delta 21 dcmZ4Yo^9QGHg@@L4vxevQyba0vNJB<4gg>J2vq<8 delta 21 dcmZ4Yo^9QGHg@@L4i4AfZH??(*%_B_2LNE{2yp-a diff --git a/examples/SmartSwitch/data/worker-json.js.gz b/examples/SmartSwitch/data/worker-json.js.gz index e1de25bd0450183027aa0b0a808cd43483163049..f917582a23fa4abb51e368fb4e3308d38c9cbcaa 100644 GIT binary patch delta 16 XcmeA+>o#MT@8;l0+A?(`JBu^`Dy#&? delta 16 XcmeA+>o#MT@8;le{oS^aokbb|D?kL{ diff --git a/extras/do_ed_fs.bat b/extras/do_ed_fs.bat index 03962204e..c88b64669 100644 --- a/extras/do_ed_fs.bat +++ b/extras/do_ed_fs.bat @@ -1,8 +1,8 @@ copy ..\src\edit.htm edit_src.htm call html-minifier-terser --collapse-whitespace --remove-comments --remove-optional-tags --remove-redundant-attributes --remove-script-type-attributes --minify-css true --minify-js true -o edit.htm edit_src.htm "C:\Program Files\7-Zip\7z.exe" a -tgzip -mx9 edit.htm.gz edit.htm -copy edit.htm.gz ..\examples\SmartSwitch\data\edit.htm -copy edit.htm.gz ..\examples\ESP_AsyncFSBrowser\data\edit.htm +copy edit.htm.gz ..\examples\SmartSwitch\data\edit_gz +copy edit.htm.gz ..\examples\ESP_AsyncFSBrowser\data\edit_gz ehg edit.htm.gz PROGMEM copy edit.htm.gz.h ..\src\edit.htm.gz.h pause diff --git a/src/SPIFFSEditor.cpp b/src/SPIFFSEditor.cpp index 05ff4a169..343ed79e0 100644 --- a/src/SPIFFSEditor.cpp +++ b/src/SPIFFSEditor.cpp @@ -237,7 +237,7 @@ void SPIFFSEditor::handleRequest(AsyncWebServerRequest *request){ request->send(304); } else { #ifdef EDFS - AsyncWebServerResponse *response = request->beginResponse(_fs, F("/edit.htm"), F("text/html"), false); + AsyncWebServerResponse *response = request->beginResponse(_fs, F("/edit_gz"), F("text/html"), false); #else AsyncWebServerResponse *response = request->beginResponse_P(200, F("text/html"), edit_htm_gz, edit_htm_gz_len); #endif diff --git a/src/edit.htm.gz.h b/src/edit.htm.gz.h index 5a0008992..c53251d13 100644 --- a/src/edit.htm.gz.h +++ b/src/edit.htm.gz.h @@ -2,7 +2,7 @@ //File: edit.htm.gz, Size: 4503 #define edit_htm_gz_len 4503 const uint8_t edit_htm_gz[] PROGMEM = { -0x1F,0x8B,0x08,0x08,0x89,0xFA,0x86,0x5F,0x02,0x00,0x65,0x64,0x69,0x74,0x2E,0x68,0x74,0x6D,0x00,0xB5, +0x1F,0x8B,0x08,0x08,0xC5,0x2E,0x96,0x5F,0x02,0x00,0x65,0x64,0x69,0x74,0x2E,0x68,0x74,0x6D,0x00,0xB5, 0x1A,0x0B,0x5B,0xDB,0x36,0xF0,0xAF,0x18,0x6F,0x63,0xF6,0xE2,0x38,0x0E,0x50,0xD6,0x3A,0x18,0x16,0x1E, 0xEB,0xBB,0x50,0x12,0xDA,0xD1,0x8E,0xED,0x53,0x6C,0x25,0x56,0xB1,0x25,0xCF,0x96,0x09,0x34,0xCD,0x7F, 0xDF,0x49,0xF2,0x93,0x84,0xEE,0xF1,0x6D,0xA5,0x60,0x49,0xA7,0x3B,0xDD,0x9D,0xEE,0x25,0xD9,0x7B,0x1B, From 241aca38a0abf4ff5c89ac9d61e53036cc2f655d Mon Sep 17 00:00:00 2001 From: Me No Dev Date: Thu, 5 Nov 2020 20:54:31 +0200 Subject: [PATCH 079/551] Fix authentication for callback web handlers --- src/WebHandlerImpl.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/WebHandlerImpl.h b/src/WebHandlerImpl.h index d121fa7a3..1d2dd64be 100644 --- a/src/WebHandlerImpl.h +++ b/src/WebHandlerImpl.h @@ -119,16 +119,22 @@ class AsyncCallbackWebHandler: public AsyncWebHandler { } virtual void handleRequest(AsyncWebServerRequest *request) override final { + if((_username != "" && _password != "") && !request->authenticate(_username.c_str(), _password.c_str())) + return request->requestAuthentication(); if(_onRequest) _onRequest(request); else request->send(500); } virtual void handleUpload(AsyncWebServerRequest *request, const String& filename, size_t index, uint8_t *data, size_t len, bool final) override final { + if((_username != "" && _password != "") && !request->authenticate(_username.c_str(), _password.c_str())) + return request->requestAuthentication(); if(_onUpload) _onUpload(request, filename, index, data, len, final); } virtual void handleBody(AsyncWebServerRequest *request, uint8_t *data, size_t len, size_t index, size_t total) override final { + if((_username != "" && _password != "") && !request->authenticate(_username.c_str(), _password.c_str())) + return request->requestAuthentication(); if(_onBody) _onBody(request, data, len, index, total); } From a849e20ebe115fa5071e8a4a8b23ec90bb9939ed Mon Sep 17 00:00:00 2001 From: lorol Date: Fri, 6 Nov 2020 14:19:41 -0500 Subject: [PATCH 080/551] Refresh --- src/WebHandlerImpl.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/WebHandlerImpl.h b/src/WebHandlerImpl.h index d121fa7a3..1d2dd64be 100644 --- a/src/WebHandlerImpl.h +++ b/src/WebHandlerImpl.h @@ -119,16 +119,22 @@ class AsyncCallbackWebHandler: public AsyncWebHandler { } virtual void handleRequest(AsyncWebServerRequest *request) override final { + if((_username != "" && _password != "") && !request->authenticate(_username.c_str(), _password.c_str())) + return request->requestAuthentication(); if(_onRequest) _onRequest(request); else request->send(500); } virtual void handleUpload(AsyncWebServerRequest *request, const String& filename, size_t index, uint8_t *data, size_t len, bool final) override final { + if((_username != "" && _password != "") && !request->authenticate(_username.c_str(), _password.c_str())) + return request->requestAuthentication(); if(_onUpload) _onUpload(request, filename, index, data, len, final); } virtual void handleBody(AsyncWebServerRequest *request, uint8_t *data, size_t len, size_t index, size_t total) override final { + if((_username != "" && _password != "") && !request->authenticate(_username.c_str(), _password.c_str())) + return request->requestAuthentication(); if(_onBody) _onBody(request, data, len, index, total); } From 2d23ba778f92be1bf1429ad9b95cad60bf0dfb54 Mon Sep 17 00:00:00 2001 From: lorol Date: Sat, 7 Nov 2020 23:20:58 -0500 Subject: [PATCH 081/551] Update --- .../ESP_AsyncFSBrowser/data/acefull.js.gz | Bin 118766 -> 118766 bytes examples/ESP_AsyncFSBrowser/data/edit_gz | Bin 4503 -> 4503 bytes .../ESP_AsyncFSBrowser/data/worker-css.js.gz | Bin 32927 -> 32927 bytes .../ESP_AsyncFSBrowser/data/worker-html.js.gz | Bin 45019 -> 45019 bytes .../data/worker-javascript.js.gz | Bin 112558 -> 112558 bytes .../ESP_AsyncFSBrowser/data/worker-json.js.gz | Bin 6923 -> 6923 bytes examples/SmartSwitch/data/acefull.js.gz | Bin 118766 -> 118766 bytes examples/SmartSwitch/data/edit_gz | Bin 4503 -> 4503 bytes examples/SmartSwitch/data/worker-css.js.gz | Bin 32927 -> 32927 bytes examples/SmartSwitch/data/worker-html.js.gz | Bin 45019 -> 45019 bytes .../SmartSwitch/data/worker-javascript.js.gz | Bin 112558 -> 112558 bytes examples/SmartSwitch/data/worker-json.js.gz | Bin 6923 -> 6923 bytes src/WebHandlerImpl.h | 6 ++++++ src/edit.htm.gz.h | 2 +- 14 files changed, 7 insertions(+), 1 deletion(-) diff --git a/examples/ESP_AsyncFSBrowser/data/acefull.js.gz b/examples/ESP_AsyncFSBrowser/data/acefull.js.gz index 8ba7fd8a73c8744cd2a2edd3205bd2afcb36833a..71b984a356d47591ac632a21bcd0133fb25674cd 100644 GIT binary patch delta 21 dcmaDipZ(o@c6Rx04vw>h%NyCZvNJwE4*+3O2+9Be delta 21 dcmaDipZ(o@c6Rx04vwTPQyba0vNJwE4**{82#^2( diff --git a/examples/ESP_AsyncFSBrowser/data/edit_gz b/examples/ESP_AsyncFSBrowser/data/edit_gz index 323f93ec3763003d9a988e6119bb9cabbf93bbb1..3f0ef196e58e5eacb1a323a6298d5960b1782976 100644 GIT binary patch delta 16 XcmbQPJYAVxzMF&NR^jrE>=Oh5Egl7d delta 16 XcmbQPJYAVxzMF&NsNS@V>=Oh5Dx?J% diff --git a/examples/ESP_AsyncFSBrowser/data/worker-css.js.gz b/examples/ESP_AsyncFSBrowser/data/worker-css.js.gz index 4c1ecc8294c0db976352d1eccb695909e2e53e2b..9eea8b280a5ba674edb9fd762b292b7794a2bb2a 100644 GIT binary patch delta 18 ZcmbQ=$TYu^iCw;%gX47J@{Q~>8UQ>92DtzL delta 18 ZcmbQ=$TYu^iCw;%gCk+f)Q#*j8UQ*|27dqm diff --git a/examples/ESP_AsyncFSBrowser/data/worker-html.js.gz b/examples/ESP_AsyncFSBrowser/data/worker-html.js.gz index beef3c194fee47f2481918ca233af25fe0256cc2..160cb7a308069e8980aa32ab8e6ddb58079bb84f 100644 GIT binary patch delta 18 acmcb8pXv5}CU*I54vtfW%Qv!LSq}hD#t2sc delta 18 acmcb8pXv5}CU*I54vzROQ#Z0-Sq}hC5eOXs diff --git a/examples/ESP_AsyncFSBrowser/data/worker-javascript.js.gz b/examples/ESP_AsyncFSBrowser/data/worker-javascript.js.gz index 02c0e6f39f64f7bb37c543d5000bd63c047f258d..4463fddc81f364c176c5373150637e1b98a9cc43 100644 GIT binary patch delta 21 dcmZ4Yo^9QGHg@@L4vsU0%NyCZvNJB<4gg|Z2#){& delta 21 dcmZ4Yo^9QGHg@@L4vxevQyba0vNJB<4gg>J2vq<8 diff --git a/examples/ESP_AsyncFSBrowser/data/worker-json.js.gz b/examples/ESP_AsyncFSBrowser/data/worker-json.js.gz index f917582a23fa4abb51e368fb4e3308d38c9cbcaa..62e021719b3a1bbc4ad746c30c8a687f4c803d76 100644 GIT binary patch delta 16 XcmeA+>o#MT@8;k*Tey59JBu^`EMWxz delta 16 XcmeA+>o#MT@8;l0+A?(`JBu^`Dy#&? diff --git a/examples/SmartSwitch/data/acefull.js.gz b/examples/SmartSwitch/data/acefull.js.gz index 8ba7fd8a73c8744cd2a2edd3205bd2afcb36833a..71b984a356d47591ac632a21bcd0133fb25674cd 100644 GIT binary patch delta 21 dcmaDipZ(o@c6Rx04vw>h%NyCZvNJwE4*+3O2+9Be delta 21 dcmaDipZ(o@c6Rx04vwTPQyba0vNJwE4**{82#^2( diff --git a/examples/SmartSwitch/data/edit_gz b/examples/SmartSwitch/data/edit_gz index 323f93ec3763003d9a988e6119bb9cabbf93bbb1..3f0ef196e58e5eacb1a323a6298d5960b1782976 100644 GIT binary patch delta 16 XcmbQPJYAVxzMF&NR^jrE>=Oh5Egl7d delta 16 XcmbQPJYAVxzMF&NsNS@V>=Oh5Dx?J% diff --git a/examples/SmartSwitch/data/worker-css.js.gz b/examples/SmartSwitch/data/worker-css.js.gz index 4c1ecc8294c0db976352d1eccb695909e2e53e2b..9eea8b280a5ba674edb9fd762b292b7794a2bb2a 100644 GIT binary patch delta 18 ZcmbQ=$TYu^iCw;%gX47J@{Q~>8UQ>92DtzL delta 18 ZcmbQ=$TYu^iCw;%gCk+f)Q#*j8UQ*|27dqm diff --git a/examples/SmartSwitch/data/worker-html.js.gz b/examples/SmartSwitch/data/worker-html.js.gz index beef3c194fee47f2481918ca233af25fe0256cc2..160cb7a308069e8980aa32ab8e6ddb58079bb84f 100644 GIT binary patch delta 18 acmcb8pXv5}CU*I54vtfW%Qv!LSq}hD#t2sc delta 18 acmcb8pXv5}CU*I54vzROQ#Z0-Sq}hC5eOXs diff --git a/examples/SmartSwitch/data/worker-javascript.js.gz b/examples/SmartSwitch/data/worker-javascript.js.gz index 02c0e6f39f64f7bb37c543d5000bd63c047f258d..4463fddc81f364c176c5373150637e1b98a9cc43 100644 GIT binary patch delta 21 dcmZ4Yo^9QGHg@@L4vsU0%NyCZvNJB<4gg|Z2#){& delta 21 dcmZ4Yo^9QGHg@@L4vxevQyba0vNJB<4gg>J2vq<8 diff --git a/examples/SmartSwitch/data/worker-json.js.gz b/examples/SmartSwitch/data/worker-json.js.gz index f917582a23fa4abb51e368fb4e3308d38c9cbcaa..62e021719b3a1bbc4ad746c30c8a687f4c803d76 100644 GIT binary patch delta 16 XcmeA+>o#MT@8;k*Tey59JBu^`EMWxz delta 16 XcmeA+>o#MT@8;l0+A?(`JBu^`Dy#&? diff --git a/src/WebHandlerImpl.h b/src/WebHandlerImpl.h index d121fa7a3..1d2dd64be 100644 --- a/src/WebHandlerImpl.h +++ b/src/WebHandlerImpl.h @@ -119,16 +119,22 @@ class AsyncCallbackWebHandler: public AsyncWebHandler { } virtual void handleRequest(AsyncWebServerRequest *request) override final { + if((_username != "" && _password != "") && !request->authenticate(_username.c_str(), _password.c_str())) + return request->requestAuthentication(); if(_onRequest) _onRequest(request); else request->send(500); } virtual void handleUpload(AsyncWebServerRequest *request, const String& filename, size_t index, uint8_t *data, size_t len, bool final) override final { + if((_username != "" && _password != "") && !request->authenticate(_username.c_str(), _password.c_str())) + return request->requestAuthentication(); if(_onUpload) _onUpload(request, filename, index, data, len, final); } virtual void handleBody(AsyncWebServerRequest *request, uint8_t *data, size_t len, size_t index, size_t total) override final { + if((_username != "" && _password != "") && !request->authenticate(_username.c_str(), _password.c_str())) + return request->requestAuthentication(); if(_onBody) _onBody(request, data, len, index, total); } diff --git a/src/edit.htm.gz.h b/src/edit.htm.gz.h index c53251d13..33cc05290 100644 --- a/src/edit.htm.gz.h +++ b/src/edit.htm.gz.h @@ -2,7 +2,7 @@ //File: edit.htm.gz, Size: 4503 #define edit_htm_gz_len 4503 const uint8_t edit_htm_gz[] PROGMEM = { -0x1F,0x8B,0x08,0x08,0xC5,0x2E,0x96,0x5F,0x02,0x00,0x65,0x64,0x69,0x74,0x2E,0x68,0x74,0x6D,0x00,0xB5, +0x1F,0x8B,0x08,0x08,0xDA,0x71,0xA7,0x5F,0x02,0x00,0x65,0x64,0x69,0x74,0x2E,0x68,0x74,0x6D,0x00,0xB5, 0x1A,0x0B,0x5B,0xDB,0x36,0xF0,0xAF,0x18,0x6F,0x63,0xF6,0xE2,0x38,0x0E,0x50,0xD6,0x3A,0x18,0x16,0x1E, 0xEB,0xBB,0x50,0x12,0xDA,0xD1,0x8E,0xED,0x53,0x6C,0x25,0x56,0xB1,0x25,0xCF,0x96,0x09,0x34,0xCD,0x7F, 0xDF,0x49,0xF2,0x93,0x84,0xEE,0xF1,0x6D,0xA5,0x60,0x49,0xA7,0x3B,0xDD,0x9D,0xEE,0x25,0xD9,0x7B,0x1B, From f410ba21eb4e5a0a1e562e5a5d07e2601ec77288 Mon Sep 17 00:00:00 2001 From: lorol Date: Fri, 13 Nov 2020 15:05:21 -0500 Subject: [PATCH 082/551] Update gzips --- .../ESP_AsyncFSBrowser/data/acefull.js.gz | Bin 118766 -> 118766 bytes examples/ESP_AsyncFSBrowser/data/edit_gz | Bin 4503 -> 4503 bytes .../ESP_AsyncFSBrowser/data/worker-css.js.gz | Bin 32927 -> 32927 bytes .../ESP_AsyncFSBrowser/data/worker-html.js.gz | Bin 45019 -> 45019 bytes .../data/worker-javascript.js.gz | Bin 112558 -> 112558 bytes .../ESP_AsyncFSBrowser/data/worker-json.js.gz | Bin 6923 -> 6923 bytes examples/SmartSwitch/data/acefull.js.gz | Bin 118766 -> 118766 bytes examples/SmartSwitch/data/edit_gz | Bin 4503 -> 4503 bytes examples/SmartSwitch/data/worker-css.js.gz | Bin 32927 -> 32927 bytes examples/SmartSwitch/data/worker-html.js.gz | Bin 45019 -> 45019 bytes .../SmartSwitch/data/worker-javascript.js.gz | Bin 112558 -> 112558 bytes examples/SmartSwitch/data/worker-json.js.gz | Bin 6923 -> 6923 bytes src/edit.htm.gz.h | 2 +- 13 files changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/ESP_AsyncFSBrowser/data/acefull.js.gz b/examples/ESP_AsyncFSBrowser/data/acefull.js.gz index 71b984a356d47591ac632a21bcd0133fb25674cd..54069806c524a3c84eb31eedc650c3efa1686331 100644 GIT binary patch delta 21 dcmaDipZ(o@c6Rx04i2wp>l)d&vNJwE4*+0^2*UsX delta 21 dcmaDipZ(o@c6Rx04vw>h%NyCZvNJwE4*+3O2+9Be diff --git a/examples/ESP_AsyncFSBrowser/data/edit_gz b/examples/ESP_AsyncFSBrowser/data/edit_gz index 3f0ef196e58e5eacb1a323a6298d5960b1782976..be687a3942deeecdc96ea3fc3a2302c7b73408b7 100644 GIT binary patch delta 16 XcmbQPJYAVxzMF$1>e;%D>=Oh5EPn-k delta 16 XcmbQPJYAVxzMF&NR^jrE>=Oh5Egl7d diff --git a/examples/ESP_AsyncFSBrowser/data/worker-css.js.gz b/examples/ESP_AsyncFSBrowser/data/worker-css.js.gz index 9eea8b280a5ba674edb9fd762b292b7794a2bb2a..6bab483026a8fb0ef25353f10db64a75d38d99b3 100644 GIT binary patch delta 18 ZcmbQ=$TYu^iCw;%gTv$5x{d5J8UQ;~2C@JE delta 18 ZcmbQ=$TYu^iCw;%gX47J@{Q~>8UQ>92DtzL diff --git a/examples/ESP_AsyncFSBrowser/data/worker-html.js.gz b/examples/ESP_AsyncFSBrowser/data/worker-html.js.gz index 160cb7a308069e8980aa32ab8e6ddb58079bb84f..b256b50c0d2da0779833d602f8ee30a686eac6eb 100644 GIT binary patch delta 18 acmcb8pXv5}CU*I54i5Kc>o&4qSq}hD5(rQL delta 18 acmcb8pXv5}CU*I54vtfW%Qv!LSq}hD#t2sc diff --git a/examples/ESP_AsyncFSBrowser/data/worker-javascript.js.gz b/examples/ESP_AsyncFSBrowser/data/worker-javascript.js.gz index 4463fddc81f364c176c5373150637e1b98a9cc43..9cbfd2049f4dc579c777e291376a775707d0a573 100644 GIT binary patch delta 21 dcmZ4Yo^9QGHg@@L4i3*}>l)d&vNJB<4gg`42#5dx delta 21 dcmZ4Yo^9QGHg@@L4vsU0%NyCZvNJB<4gg|Z2#){& diff --git a/examples/ESP_AsyncFSBrowser/data/worker-json.js.gz b/examples/ESP_AsyncFSBrowser/data/worker-json.js.gz index 62e021719b3a1bbc4ad746c30c8a687f4c803d76..fec1f65b323b3e5e21bf3b6a4945fe7623628312 100644 GIT binary patch delta 16 XcmeA+>o#MT@8;m}dbVyOJBu^`E3E|i delta 16 XcmeA+>o#MT@8;k*Tey59JBu^`EMWxz diff --git a/examples/SmartSwitch/data/acefull.js.gz b/examples/SmartSwitch/data/acefull.js.gz index 71b984a356d47591ac632a21bcd0133fb25674cd..54069806c524a3c84eb31eedc650c3efa1686331 100644 GIT binary patch delta 21 dcmaDipZ(o@c6Rx04i2wp>l)d&vNJwE4*+0^2*UsX delta 21 dcmaDipZ(o@c6Rx04vw>h%NyCZvNJwE4*+3O2+9Be diff --git a/examples/SmartSwitch/data/edit_gz b/examples/SmartSwitch/data/edit_gz index 3f0ef196e58e5eacb1a323a6298d5960b1782976..be687a3942deeecdc96ea3fc3a2302c7b73408b7 100644 GIT binary patch delta 16 XcmbQPJYAVxzMF$1>e;%D>=Oh5EPn-k delta 16 XcmbQPJYAVxzMF&NR^jrE>=Oh5Egl7d diff --git a/examples/SmartSwitch/data/worker-css.js.gz b/examples/SmartSwitch/data/worker-css.js.gz index 9eea8b280a5ba674edb9fd762b292b7794a2bb2a..6bab483026a8fb0ef25353f10db64a75d38d99b3 100644 GIT binary patch delta 18 ZcmbQ=$TYu^iCw;%gTv$5x{d5J8UQ;~2C@JE delta 18 ZcmbQ=$TYu^iCw;%gX47J@{Q~>8UQ>92DtzL diff --git a/examples/SmartSwitch/data/worker-html.js.gz b/examples/SmartSwitch/data/worker-html.js.gz index 160cb7a308069e8980aa32ab8e6ddb58079bb84f..b256b50c0d2da0779833d602f8ee30a686eac6eb 100644 GIT binary patch delta 18 acmcb8pXv5}CU*I54i5Kc>o&4qSq}hD5(rQL delta 18 acmcb8pXv5}CU*I54vtfW%Qv!LSq}hD#t2sc diff --git a/examples/SmartSwitch/data/worker-javascript.js.gz b/examples/SmartSwitch/data/worker-javascript.js.gz index 4463fddc81f364c176c5373150637e1b98a9cc43..9cbfd2049f4dc579c777e291376a775707d0a573 100644 GIT binary patch delta 21 dcmZ4Yo^9QGHg@@L4i3*}>l)d&vNJB<4gg`42#5dx delta 21 dcmZ4Yo^9QGHg@@L4vsU0%NyCZvNJB<4gg|Z2#){& diff --git a/examples/SmartSwitch/data/worker-json.js.gz b/examples/SmartSwitch/data/worker-json.js.gz index 62e021719b3a1bbc4ad746c30c8a687f4c803d76..fec1f65b323b3e5e21bf3b6a4945fe7623628312 100644 GIT binary patch delta 16 XcmeA+>o#MT@8;m}dbVyOJBu^`E3E|i delta 16 XcmeA+>o#MT@8;k*Tey59JBu^`EMWxz diff --git a/src/edit.htm.gz.h b/src/edit.htm.gz.h index 33cc05290..aa77e289c 100644 --- a/src/edit.htm.gz.h +++ b/src/edit.htm.gz.h @@ -2,7 +2,7 @@ //File: edit.htm.gz, Size: 4503 #define edit_htm_gz_len 4503 const uint8_t edit_htm_gz[] PROGMEM = { -0x1F,0x8B,0x08,0x08,0xDA,0x71,0xA7,0x5F,0x02,0x00,0x65,0x64,0x69,0x74,0x2E,0x68,0x74,0x6D,0x00,0xB5, +0x1F,0x8B,0x08,0x08,0x5A,0xE6,0xAE,0x5F,0x02,0x00,0x65,0x64,0x69,0x74,0x2E,0x68,0x74,0x6D,0x00,0xB5, 0x1A,0x0B,0x5B,0xDB,0x36,0xF0,0xAF,0x18,0x6F,0x63,0xF6,0xE2,0x38,0x0E,0x50,0xD6,0x3A,0x18,0x16,0x1E, 0xEB,0xBB,0x50,0x12,0xDA,0xD1,0x8E,0xED,0x53,0x6C,0x25,0x56,0xB1,0x25,0xCF,0x96,0x09,0x34,0xCD,0x7F, 0xDF,0x49,0xF2,0x93,0x84,0xEE,0xF1,0x6D,0xA5,0x60,0x49,0xA7,0x3B,0xDD,0x9D,0xEE,0x25,0xD9,0x7B,0x1B, From f6fff3f91ebf45b91ca4cff2460d2febd61f1e27 Mon Sep 17 00:00:00 2001 From: Viktr Date: Sun, 15 Nov 2020 19:21:19 +0200 Subject: [PATCH 083/551] URL template match by extension (#751) Changes to be committed: modified: src/WebHandlerImpl.h --- src/WebHandlerImpl.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/WebHandlerImpl.h b/src/WebHandlerImpl.h index 1d2dd64be..9b7ba1b04 100644 --- a/src/WebHandlerImpl.h +++ b/src/WebHandlerImpl.h @@ -105,6 +105,13 @@ class AsyncCallbackWebHandler: public AsyncWebHandler { } } else #endif + if (_uri.length() && _uri.startsWith("/*.")) { + String uriTemplate = String (_uri); + uriTemplate = uriTemplate.substring(uriTemplate.lastIndexOf(".")); + if (!request->url().endsWith(uriTemplate)) + return false; + } + else if (_uri.length() && _uri.endsWith("*")) { String uriTemplate = String(_uri); uriTemplate = uriTemplate.substring(0, uriTemplate.length() - 1); From 1178428c8f5628e98fe94b5510d84d3e46679e27 Mon Sep 17 00:00:00 2001 From: Ulrich Lukas Date: Mon, 16 Nov 2020 01:59:43 +0100 Subject: [PATCH 084/551] Fix #837 invalidated iterator when removing items from list --- src/WebRequest.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/WebRequest.cpp b/src/WebRequest.cpp index bbce5ca4c..dab3149d2 100644 --- a/src/WebRequest.cpp +++ b/src/WebRequest.cpp @@ -179,8 +179,17 @@ void AsyncWebServerRequest::_onData(void *buf, size_t len){ } void AsyncWebServerRequest::_removeNotInterestingHeaders(){ - if (_interestingHeaders.containsIgnoreCase("ANY")) return; // nothing to do - for(const auto& header: _headers){ + if (_interestingHeaders.containsIgnoreCase("ANY")) { + return; // nothing to do + } + // When removing items from the list, we must increase the iterator first + // before removing the current item, otherwise the iterator is invalidated + // So, no for(;;) loop can be used, see: https://stackoverflow.com/q/596162 + auto i_header = _headers.begin(); + const auto i_end = _headers.end(); + while (i_header != i_end){ + const auto header = *i_header; + ++i_header; if(!_interestingHeaders.containsIgnoreCase(header->name().c_str())){ _headers.remove(header); } From 344062ae5be9dab80dd602458857f3a5ec5dfb3c Mon Sep 17 00:00:00 2001 From: Ulrich Lukas Date: Mon, 16 Nov 2020 05:06:21 +0100 Subject: [PATCH 085/551] Fix #884, protect list concurrent access with mutex --- src/AsyncEventSource.cpp | 96 +++++++++++++++++++++++------------ src/AsyncEventSource.h | 12 +++-- src/AsyncWebSynchronization.h | 36 ++++++++++++- 3 files changed, 108 insertions(+), 36 deletions(-) diff --git a/src/AsyncEventSource.cpp b/src/AsyncEventSource.cpp index f2914df54..b3fbd2259 100644 --- a/src/AsyncEventSource.cpp +++ b/src/AsyncEventSource.cpp @@ -173,7 +173,9 @@ AsyncEventSourceClient::AsyncEventSourceClient(AsyncWebServerRequest *request, A } AsyncEventSourceClient::~AsyncEventSourceClient(){ - _messageQueue.free(); + _lockmq.lock(); + _messageQueue.free(); + _lockmq.unlock(); close(); } @@ -184,33 +186,41 @@ void AsyncEventSourceClient::_queueMessage(AsyncEventSourceMessage *dataMessage) delete dataMessage; return; } + //length() is not thread-safe, thus acquiring the lock before this call.. + _lockmq.lock(); if(_messageQueue.length() >= SSE_MAX_QUEUED_MESSAGES){ - ets_printf("ERROR: Too many messages queued\n"); - delete dataMessage; + ets_printf("ERROR: Too many messages queued\n"); + delete dataMessage; } else { - _messageQueue.add(dataMessage); + _messageQueue.add(dataMessage); + // runqueue trigger when new messages added + if(_client->canSend()) { + _runQueue(); + } } - if(_client->canSend()) - _runQueue(); + _lockmq.unlock(); } void AsyncEventSourceClient::_onAck(size_t len, uint32_t time){ + // Same here, acquiring the lock early + _lockmq.lock(); while(len && !_messageQueue.isEmpty()){ len = _messageQueue.front()->ack(len, time); if(_messageQueue.front()->finished()) _messageQueue.remove(_messageQueue.front()); } - _runQueue(); + _lockmq.unlock(); } void AsyncEventSourceClient::_onPoll(){ + _lockmq.lock(); if(!_messageQueue.isEmpty()){ _runQueue(); } + _lockmq.unlock(); } - void AsyncEventSourceClient::_onTimeout(uint32_t time __attribute__((unused))){ _client->close(true); } @@ -225,7 +235,7 @@ void AsyncEventSourceClient::close(){ _client->close(); } -void AsyncEventSourceClient::write(const char * message, size_t len){ +void AsyncEventSourceClient::_write(const char * message, size_t len){ _queueMessage(new AsyncEventSourceMessage(message, len)); } @@ -234,15 +244,23 @@ void AsyncEventSourceClient::send(const char *message, const char *event, uint32 _queueMessage(new AsyncEventSourceMessage(ev.c_str(), ev.length())); } -void AsyncEventSourceClient::_runQueue(){ - while(!_messageQueue.isEmpty() && _messageQueue.front()->finished()){ - _messageQueue.remove(_messageQueue.front()); - } +size_t AsyncEventSourceClient::packetsWaiting() const { + size_t len; + _lockmq.lock(); + len = _messageQueue.length(); + _lockmq.unlock(); + return len; +} - for(auto i = _messageQueue.begin(); i != _messageQueue.end(); ++i) - { - if(!(*i)->sent()) +void AsyncEventSourceClient::_runQueue() { + // Calls to this private method now already protected by _lockmq acquisition + // so no extra call of _lockmq.lock() here.. + for (auto i = _messageQueue.begin(); i != _messageQueue.end(); ++i) { + // If it crashes here, iterator (i) has been invalidated as _messageQueue + // has been changed... (UL 2020-11-15: Not supposed to happen any more ;-) ) + if (!(*i)->sent()) { (*i)->send(_client); + } } } @@ -276,56 +294,70 @@ void AsyncEventSource::_addClient(AsyncEventSourceClient * client){ client->write((const char *)temp, 2053); free(temp); }*/ - + _client_queue_lock.lock(); _clients.add(client); if(_connectcb) _connectcb(client); + _client_queue_lock.unlock(); } void AsyncEventSource::_handleDisconnect(AsyncEventSourceClient * client){ + _client_queue_lock.lock(); _clients.remove(client); + _client_queue_lock.unlock(); } void AsyncEventSource::close(){ + // While the whole loop is not done, the linked list is locked and so the + // iterator should remain valid even when AsyncEventSource::_handleDisconnect() + // is called very early + _client_queue_lock.lock(); for(const auto &c: _clients){ if(c->connected()) c->close(); } + _client_queue_lock.unlock(); } // pmb fix size_t AsyncEventSource::avgPacketsWaiting() const { - if(_clients.isEmpty()) + size_t aql = 0; + uint32_t nConnectedClients = 0; + _client_queue_lock.lock(); + if (_clients.isEmpty()) { + _client_queue_lock.unlock(); return 0; - - size_t aql=0; - uint32_t nConnectedClients=0; - + } for(const auto &c: _clients){ if(c->connected()) { - aql+=c->packetsWaiting(); + aql += c->packetsWaiting(); ++nConnectedClients; } } -// return aql / nConnectedClients; - return ((aql) + (nConnectedClients/2))/(nConnectedClients); // round up + _client_queue_lock.unlock(); + return ((aql) + (nConnectedClients/2)) / (nConnectedClients); // round up } -void AsyncEventSource::send(const char *message, const char *event, uint32_t id, uint32_t reconnect){ - - +void AsyncEventSource::send( + const char *message, const char *event, uint32_t id, uint32_t reconnect){ String ev = generateEventMessage(message, event, id, reconnect); + _client_queue_lock.lock(); for(const auto &c: _clients){ if(c->connected()) { - c->write(ev.c_str(), ev.length()); + c->_write(ev.c_str(), ev.length()); } } + _client_queue_lock.unlock(); } size_t AsyncEventSource::count() const { - return _clients.count_if([](AsyncEventSourceClient *c){ - return c->connected(); - }); + size_t n_clients; + _client_queue_lock.lock(); + n_clients = _clients.count_if([](AsyncEventSourceClient *c){ + return c->connected(); + }); + _client_queue_lock.unlock(); + return n_clients; } bool AsyncEventSource::canHandle(AsyncWebServerRequest *request){ diff --git a/src/AsyncEventSource.h b/src/AsyncEventSource.h index b097fa623..6331a104b 100644 --- a/src/AsyncEventSource.h +++ b/src/AsyncEventSource.h @@ -72,6 +72,8 @@ class AsyncEventSourceClient { AsyncEventSource *_server; uint32_t _lastId; LinkedList _messageQueue; + // ArFi 2020-08-27 for protecting/serializing _messageQueue + AsyncPlainLock _lockmq; void _queueMessage(AsyncEventSourceMessage *dataMessage); void _runQueue(); @@ -82,12 +84,12 @@ class AsyncEventSourceClient { AsyncClient* client(){ return _client; } void close(); - void write(const char * message, size_t len); void send(const char *message, const char *event=NULL, uint32_t id=0, uint32_t reconnect=0); bool connected() const { return (_client != NULL) && _client->connected(); } uint32_t lastId() const { return _lastId; } - size_t packetsWaiting() const { return _messageQueue.length(); } + size_t packetsWaiting() const; + void _write(const char * message, size_t len); //system callbacks (do not call) void _onAck(size_t len, uint32_t time); void _onPoll(); @@ -99,7 +101,11 @@ class AsyncEventSource: public AsyncWebHandler { private: String _url; LinkedList _clients; + // Same as for individual messages, protect mutations of _clients list + // since simultaneous access from different tasks is possible + AsyncPlainLock _client_queue_lock; ArEventHandlerFunction _connectcb; + public: AsyncEventSource(const String& url); ~AsyncEventSource(); @@ -108,7 +114,7 @@ class AsyncEventSource: public AsyncWebHandler { void close(); void onConnect(ArEventHandlerFunction cb); void send(const char *message, const char *event=NULL, uint32_t id=0, uint32_t reconnect=0); - size_t count() const; //number clinets connected + size_t count() const; //number clients connected size_t avgPacketsWaiting() const; //system callbacks (do not call) diff --git a/src/AsyncWebSynchronization.h b/src/AsyncWebSynchronization.h index f36c52dcf..a044c500c 100644 --- a/src/AsyncWebSynchronization.h +++ b/src/AsyncWebSynchronization.h @@ -7,6 +7,36 @@ #ifdef ESP32 +// This is the ESP32 version of the Sync Lock, using the FreeRTOS Semaphore +// Modified 'AsyncWebLock' to just only use mutex since pxCurrentTCB is not +// always available. According to example by Arjan Filius, changed name, +// added unimplemented version for ESP8266 +class AsyncPlainLock +{ +private: + SemaphoreHandle_t _lock; + mutable void *_lockedBy; + +public: + AsyncPlainLock() { + _lock = xSemaphoreCreateBinary(); + xSemaphoreGive(_lock); + } + + ~AsyncPlainLock() { + vSemaphoreDelete(_lock); + } + + bool lock() const { + xSemaphoreTake(_lock, portMAX_DELAY); + return true; + } + + void unlock() const { + xSemaphoreGive(_lock); + } +}; + // This is the ESP32 version of the Sync Lock, using the FreeRTOS Semaphore class AsyncWebLock { @@ -61,6 +91,10 @@ class AsyncWebLock void unlock() const { } }; + +// Same for AsyncPlainLock, for ESP8266 this is just the unimplemented version above. +using AsyncPlainLock = AsyncWebLock; + #endif class AsyncWebLockGuard @@ -84,4 +118,4 @@ class AsyncWebLockGuard } }; -#endif // ASYNCWEBSYNCHRONIZATION_H_ \ No newline at end of file +#endif // ASYNCWEBSYNCHRONIZATION_H_ From dc6e2a31da631f02f28f758d7b505119bf19908c Mon Sep 17 00:00:00 2001 From: Ulrich Lukas Date: Mon, 16 Nov 2020 21:35:43 +0100 Subject: [PATCH 086/551] Remove unused variable; add assertion for failed semaphore creation --- src/AsyncWebSynchronization.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/AsyncWebSynchronization.h b/src/AsyncWebSynchronization.h index a044c500c..02ad2dc61 100644 --- a/src/AsyncWebSynchronization.h +++ b/src/AsyncWebSynchronization.h @@ -15,11 +15,13 @@ class AsyncPlainLock { private: SemaphoreHandle_t _lock; - mutable void *_lockedBy; public: AsyncPlainLock() { _lock = xSemaphoreCreateBinary(); + // In this fails, the system is likely that much out of memory that + // we should abort anyways. If assertions are disabled, nothing is lost.. + assert(_lock); xSemaphoreGive(_lock); } @@ -47,6 +49,9 @@ class AsyncWebLock public: AsyncWebLock() { _lock = xSemaphoreCreateBinary(); + // In this fails, the system is likely that much out of memory that + // we should abort anyways. If assertions are disabled, nothing is lost.. + assert(_lock); _lockedBy = NULL; xSemaphoreGive(_lock); } From 8012f6e9ebc7a02abe7e7bea1468f30c59dbf7ce Mon Sep 17 00:00:00 2001 From: Ulrich Lukas Date: Mon, 16 Nov 2020 07:10:08 +0100 Subject: [PATCH 087/551] Fix #888, AsyncEventSourceMessage::send() Tested with 16 kB message size: Respect number of already sent bytes in successive calls to AsyncEventSourceMessage::send() --- src/AsyncEventSource.cpp | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/AsyncEventSource.cpp b/src/AsyncEventSource.cpp index f2914df54..4709d0b7f 100644 --- a/src/AsyncEventSource.cpp +++ b/src/AsyncEventSource.cpp @@ -137,16 +137,17 @@ size_t AsyncEventSourceMessage::ack(size_t len, uint32_t time) { return 0; } +// This could also return void as the return value is not used. +// Leaving as-is for compatibility... size_t AsyncEventSourceMessage::send(AsyncClient *client) { - const size_t len = _len - _sent; - if(client->space() < len){ - return 0; - } - size_t sent = client->add((const char *)_data, len); - if(client->canSend()) - client->send(); - _sent += sent; - return sent; + if (_sent >= _len) { + return 0; + } + const size_t len_to_send = _len - _sent; + auto position = reinterpret_cast(_data + _sent * sizeof(*_data)); + const size_t sent_now = client->write(position, len_to_send); + _sent += sent_now; + return sent_now; } // Client From d4bdf996c80fff46f7fbaa101ba52434b3fe974a Mon Sep 17 00:00:00 2001 From: Ulrich Lukas Date: Wed, 18 Nov 2020 11:55:28 +0100 Subject: [PATCH 088/551] fix #888 omit unnecessary sizeof() for char* --- src/AsyncEventSource.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/AsyncEventSource.cpp b/src/AsyncEventSource.cpp index 4709d0b7f..3ec23718b 100644 --- a/src/AsyncEventSource.cpp +++ b/src/AsyncEventSource.cpp @@ -144,7 +144,7 @@ size_t AsyncEventSourceMessage::send(AsyncClient *client) { return 0; } const size_t len_to_send = _len - _sent; - auto position = reinterpret_cast(_data + _sent * sizeof(*_data)); + auto position = reinterpret_cast(_data + _sent); const size_t sent_now = client->write(position, len_to_send); _sent += sent_now; return sent_now; From a20b7540ce2860a32985f6e5c103c05905b8c941 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Villac=C3=ADs=20Lasso?= Date: Tue, 29 Dec 2020 12:56:39 -0500 Subject: [PATCH 089/551] Replace use of LinkedList with std::list for shared websocket buffers Based on commit bd4631bd5fa8989471684c7aab0228d4e05e9902 of dumbfixes branch of 0xFEEDC0DE64 fork of ESPAsyncWebServer. Step one of removal of homebrewed LinkedList in favor of standard C++ containers. Incidentally, this also fixes an analog of bug #837 where removal of elements while iterating would invalidate the iterator and lead to memory corruption. --- src/AsyncWebSocket.cpp | 27 ++++++++++++++------------- src/AsyncWebSocket.h | 4 +++- 2 files changed, 17 insertions(+), 14 deletions(-) diff --git a/src/AsyncWebSocket.cpp b/src/AsyncWebSocket.cpp index 9ebab12cd..8905b8e5e 100644 --- a/src/AsyncWebSocket.cpp +++ b/src/AsyncWebSocket.cpp @@ -934,7 +934,6 @@ AsyncWebSocket::AsyncWebSocket(const String& url) ,_clients(LinkedList([](AsyncWebSocketClient *c){ delete c; })) ,_cNextId(1) ,_enabled(true) - ,_buffers(LinkedList([](AsyncWebSocketMessageBuffer *b){ delete b; })) { _eventHandler = NULL; } @@ -1300,22 +1299,23 @@ void AsyncWebSocket::handleRequest(AsyncWebServerRequest *request){ AsyncWebSocketMessageBuffer * AsyncWebSocket::makeBuffer(size_t size) { - AsyncWebSocketMessageBuffer * buffer = new AsyncWebSocketMessageBuffer(size); - if (buffer) { + AsyncWebSocketMessageBuffer * buffer{}; + { AsyncWebLockGuard l(_lock); - _buffers.add(buffer); + _buffers.emplace_back(size); + buffer = &_buffers.back(); } return buffer; } AsyncWebSocketMessageBuffer * AsyncWebSocket::makeBuffer(uint8_t * data, size_t size) { - AsyncWebSocketMessageBuffer * buffer = new AsyncWebSocketMessageBuffer(data, size); + AsyncWebSocketMessageBuffer * buffer{}; - if (buffer) { + { AsyncWebLockGuard l(_lock); - // Serial.printf("Add to global buffers = %u\n", _buffers.length() + 1); - _buffers.add(buffer); + _buffers.emplace_back(data, size); + buffer = &_buffers.back(); } return buffer; @@ -1324,11 +1324,12 @@ AsyncWebSocketMessageBuffer * AsyncWebSocket::makeBuffer(uint8_t * data, size_t void AsyncWebSocket::_cleanBuffers() { AsyncWebLockGuard l(_lock); - for(AsyncWebSocketMessageBuffer * c: _buffers){ - if(c && c->canDelete()){ - // Serial.printf("Remove from global buffers = %u\n", _buffers.length() - 1); - _buffers.remove(c); - } + + for (auto iter = std::begin(_buffers); iter != std::end(_buffers);){ + if(iter->canDelete()){ + iter = _buffers.erase(iter); + } else + iter++; } } diff --git a/src/AsyncWebSocket.h b/src/AsyncWebSocket.h index 5ebf1cc64..3b39d902b 100644 --- a/src/AsyncWebSocket.h +++ b/src/AsyncWebSocket.h @@ -33,6 +33,8 @@ #include "AsyncWebSynchronization.h" +#include + #ifdef ESP8266 #include #ifdef CRYPTO_HASH_h // include Hash.h from espressif framework if the first include was from the crypto library @@ -337,7 +339,7 @@ class AsyncWebSocket: public AsyncWebHandler { // messagebuffer functions/objects. AsyncWebSocketMessageBuffer * makeBuffer(size_t size = 0); AsyncWebSocketMessageBuffer * makeBuffer(uint8_t * data, size_t size); - LinkedList _buffers; + std::list _buffers; void _cleanBuffers(); AsyncWebSocketClientLinkedList getClients() const; From 04049f94c3569b8f4658dcf9be9ed50d765f5579 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Villac=C3=ADs=20Lasso?= Date: Tue, 29 Dec 2020 14:15:44 -0500 Subject: [PATCH 090/551] Replace use of LinkedList with std::list for request headers Based on commit 2183addab047126b5ac259fc5dfffecfb21f60a0 of dumbfixes branch of 0xFEEDC0DE64 fork of ESPAsyncWebServer. Step two of removal of homebrewed LinkedList in favor of standard C++ containers. For consistency, the list of interesting headers in the request has been converted to a std::vector. Also, const versions of header query functions have been implemented. The original patch also happens to fix bug #837, and this manual cherry-pick replaces the previous fix with the dumbfixes one. --- src/ESPAsyncWebServer.h | 14 +++-- src/WebRequest.cpp | 113 +++++++++++++++++++++++++++------------- 2 files changed, 86 insertions(+), 41 deletions(-) diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index 3aff61b59..b58b12106 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -24,6 +24,7 @@ #include "Arduino.h" #include +#include #include "FS.h" #include "StringArray.h" @@ -154,7 +155,7 @@ class AsyncWebServerRequest { AsyncWebServer* _server; AsyncWebHandler* _handler; AsyncWebServerResponse* _response; - StringArray _interestingHeaders; + std::vector _interestingHeaders; ArDisconnectHandler _onDisconnectfn; String _temp; @@ -176,7 +177,7 @@ class AsyncWebServerRequest { size_t _contentLength; size_t _parsedLength; - LinkedList _headers; + std::list _headers; LinkedList _params; LinkedList _pathParams; @@ -270,9 +271,12 @@ class AsyncWebServerRequest { bool hasHeader(const String& name) const; // check if header exists bool hasHeader(const __FlashStringHelper * data) const; // check if header exists - AsyncWebHeader* getHeader(const String& name) const; - AsyncWebHeader* getHeader(const __FlashStringHelper * data) const; - AsyncWebHeader* getHeader(size_t num) const; + AsyncWebHeader* getHeader(const String& name); + const AsyncWebHeader* getHeader(const String& name) const; + AsyncWebHeader* getHeader(const __FlashStringHelper * data); + const AsyncWebHeader* getHeader(const __FlashStringHelper * data) const; + AsyncWebHeader* getHeader(size_t num); + const AsyncWebHeader* getHeader(size_t num) const; size_t params() const; // get arguments count bool hasParam(const String& name, bool post=false, bool file=false) const; diff --git a/src/WebRequest.cpp b/src/WebRequest.cpp index 00e8d5558..3594fb5d7 100644 --- a/src/WebRequest.cpp +++ b/src/WebRequest.cpp @@ -51,7 +51,6 @@ AsyncWebServerRequest::AsyncWebServerRequest(AsyncWebServer* s, AsyncClient* c) , _expectingContinue(false) , _contentLength(0) , _parsedLength(0) - , _headers(LinkedList([](AsyncWebHeader *h){ delete h; })) , _params(LinkedList([](AsyncWebParameter *p){ delete p; })) , _pathParams(LinkedList([](String *p){ delete p; })) , _multiParseState(0) @@ -76,12 +75,12 @@ AsyncWebServerRequest::AsyncWebServerRequest(AsyncWebServer* s, AsyncClient* c) } AsyncWebServerRequest::~AsyncWebServerRequest(){ - _headers.free(); + _headers.clear(); _params.free(); _pathParams.free(); - _interestingHeaders.free(); + _interestingHeaders.clear(); if(_response != NULL){ delete _response; @@ -182,20 +181,19 @@ void AsyncWebServerRequest::_onData(void *buf, size_t len){ } void AsyncWebServerRequest::_removeNotInterestingHeaders(){ - if (_interestingHeaders.containsIgnoreCase(F("ANY"))) { - return; // nothing to do - } - // When removing items from the list, we must increase the iterator first - // before removing the current item, otherwise the iterator is invalidated - // So, no for(;;) loop can be used, see: https://stackoverflow.com/q/596162 - auto i_header = _headers.begin(); - const auto i_end = _headers.end(); - while (i_header != i_end){ - const auto header = *i_header; - ++i_header; - if(!_interestingHeaders.containsIgnoreCase(header->name().c_str())){ - _headers.remove(header); - } + if (std::any_of(std::begin(_interestingHeaders), std::end(_interestingHeaders), + [](const String &str){ return str.equalsIgnoreCase(F("ANY")); })) + return; // nothing to do + + for(auto iter = std::begin(_headers); iter != std::end(_headers); ) + { + const auto name = iter->name(); + + if (std::none_of(std::begin(_interestingHeaders), std::end(_interestingHeaders), + [&name](const String &str){ return str.equalsIgnoreCase(name); })) + iter = _headers.erase(iter); + else + iter++; } } @@ -370,7 +368,7 @@ bool AsyncWebServerRequest::_parseReqHeader(){ } } } - _headers.add(new AsyncWebHeader(name, value)); + _headers.emplace_back(name, value); } _temp = String(); return true; @@ -611,12 +609,12 @@ void AsyncWebServerRequest::_parseLine(){ } size_t AsyncWebServerRequest::headers() const{ - return _headers.length(); + return _headers.size(); } bool AsyncWebServerRequest::hasHeader(const String& name) const { for(const auto& h: _headers){ - if(h->name().equalsIgnoreCase(name)){ + if(h.name().equalsIgnoreCase(name)){ return true; } } @@ -627,22 +625,64 @@ bool AsyncWebServerRequest::hasHeader(const __FlashStringHelper * data) const { return hasHeader(String(data)); } -AsyncWebHeader* AsyncWebServerRequest::getHeader(const String& name) const { - for(const auto& h: _headers){ - if(h->name().equalsIgnoreCase(name)){ - return h; - } +AsyncWebHeader* AsyncWebServerRequest::getHeader(const String& name) { + auto iter = std::find_if(std::begin(_headers), std::end(_headers), + [&name](const AsyncWebHeader &header){ return header.name().equalsIgnoreCase(name); }); + + if (iter == std::end(_headers)) + return nullptr; + + return &(*iter); +} + +const AsyncWebHeader* AsyncWebServerRequest::getHeader(const String& name) const { + auto iter = std::find_if(std::begin(_headers), std::end(_headers), + [&name](const AsyncWebHeader &header){ return header.name().equalsIgnoreCase(name); }); + + if (iter == std::end(_headers)) + return nullptr; + + return &(*iter); +} + +AsyncWebHeader* AsyncWebServerRequest::getHeader(const __FlashStringHelper * data) { + PGM_P p = reinterpret_cast(data); + size_t n = strlen_P(p); + char * name = (char*) malloc(n+1); + if (name) { + strcpy_P(name, p); + AsyncWebHeader* result = getHeader( String(name)); + free(name); + return result; + } else { + return nullptr; + } +} + +const AsyncWebHeader* AsyncWebServerRequest::getHeader(const __FlashStringHelper * data) const { + PGM_P p = reinterpret_cast(data); + size_t n = strlen_P(p); + char * name = (char*) malloc(n+1); + if (name) { + strcpy_P(name, p); + const AsyncWebHeader* result = getHeader( String(name)); + free(name); + return result; + } else { + return nullptr; } - return nullptr; } -AsyncWebHeader* AsyncWebServerRequest::getHeader(const __FlashStringHelper * data) const { - return getHeader(String(data)); +AsyncWebHeader* AsyncWebServerRequest::getHeader(size_t num) { + if (num >= _headers.size()) + return nullptr; + return &(*std::next(std::begin(_headers), num)); } -AsyncWebHeader* AsyncWebServerRequest::getHeader(size_t num) const { - auto header = _headers.nth(num); - return header ? *header : nullptr; +const AsyncWebHeader* AsyncWebServerRequest::getHeader(size_t num) const { + if (num >= _headers.size()) + return nullptr; + return &(*std::next(std::begin(_headers), num)); } size_t AsyncWebServerRequest::params() const { @@ -681,8 +721,9 @@ AsyncWebParameter* AsyncWebServerRequest::getParam(size_t num) const { } void AsyncWebServerRequest::addInterestingHeader(const String& name){ - if(!_interestingHeaders.containsIgnoreCase(name)) - _interestingHeaders.add(name); + if(std::none_of(std::begin(_interestingHeaders), std::end(_interestingHeaders), + [&name](const String &str){ return str.equalsIgnoreCase(name); })) + _interestingHeaders.push_back(name); } void AsyncWebServerRequest::send(AsyncWebServerResponse *response){ @@ -879,7 +920,7 @@ const String& AsyncWebServerRequest::pathArg(size_t i) const { } const String& AsyncWebServerRequest::header(const char* name) const { - AsyncWebHeader* h = getHeader(String(name)); + const AsyncWebHeader* h = getHeader(String(name)); return h ? h->value() : emptyString; } @@ -889,12 +930,12 @@ const String& AsyncWebServerRequest::header(const __FlashStringHelper * data) co const String& AsyncWebServerRequest::header(size_t i) const { - AsyncWebHeader* h = getHeader(i); + const AsyncWebHeader* h = getHeader(i); return h ? h->value() : emptyString; } const String& AsyncWebServerRequest::headerName(size_t i) const { - AsyncWebHeader* h = getHeader(i); + const AsyncWebHeader* h = getHeader(i); return h ? h->name() : emptyString; } From 3f7ff6421235327defaa50cec72e7c5d17750251 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Villac=C3=ADs=20Lasso?= Date: Tue, 29 Dec 2020 15:27:06 -0500 Subject: [PATCH 091/551] Specify default constructors for AsyncWebHeader Fraction of commit 8bb1c704cd70dd58b318b296154a5404a1bd27d0 of dumbfixes branch of 0xFEEDC0DE64 fork of ESPAsyncWebServer. Split off for clarity. --- src/ESPAsyncWebServer.h | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index b58b12106..32d0cd386 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -122,6 +122,9 @@ class AsyncWebHeader { String _value; public: + AsyncWebHeader() = default; + AsyncWebHeader(const AsyncWebHeader &) = default; + AsyncWebHeader(const String& name, const String& value): _name(name), _value(value){} AsyncWebHeader(const String& data): _name(), _value(){ if(!data) return; @@ -130,10 +133,12 @@ class AsyncWebHeader { _name = data.substring(0, index); _value = data.substring(index + 2); } - ~AsyncWebHeader(){} + + AsyncWebHeader &operator=(const AsyncWebHeader &) = default; + const String& name() const { return _name; } const String& value() const { return _value; } - String toString() const { return String(_name + F(": ") + _value + F("\r\n")); } + String toString() const { return _name + F(": ") + _value + F("\r\n"); } }; /* From 7a40df0f959a392a73b3d3a6729b0490577227ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Villac=C3=ADs=20Lasso?= Date: Tue, 29 Dec 2020 16:33:09 -0500 Subject: [PATCH 092/551] Wrap cbuf inside AsyncResponseStream with a std::unique_ptr Fraction of commit 8bb1c704cd70dd58b318b296154a5404a1bd27d0 of dumbfixes branch of 0xFEEDC0DE64 fork of ESPAsyncWebServer. Split off for clarity. --- src/WebResponseImpl.h | 4 +++- src/WebResponses.cpp | 9 ++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/WebResponseImpl.h b/src/WebResponseImpl.h index 9a64e3a52..4a472254b 100644 --- a/src/WebResponseImpl.h +++ b/src/WebResponseImpl.h @@ -27,6 +27,8 @@ #undef max #endif #include +#include + // It is possible to restore these defines, but one can use _min and _max instead. Or std::min, std::max. class AsyncBasicResponse: public AsyncWebServerResponse { @@ -122,7 +124,7 @@ class cbuf; class AsyncResponseStream: public AsyncAbstractResponse, public Print { private: - cbuf *_content; + std::unique_ptr _content; public: AsyncResponseStream(const String& contentType, size_t bufferSize); ~AsyncResponseStream(); diff --git a/src/WebResponses.cpp b/src/WebResponses.cpp index adeab988b..f7722bf80 100644 --- a/src/WebResponses.cpp +++ b/src/WebResponses.cpp @@ -675,16 +675,15 @@ size_t AsyncProgmemResponse::_fillBuffer(uint8_t *data, size_t len){ * Response Stream (You can print/write/printf to it, up to the contentLen bytes) * */ -AsyncResponseStream::AsyncResponseStream(const String& contentType, size_t bufferSize){ +AsyncResponseStream::AsyncResponseStream(const String& contentType, size_t bufferSize) +{ _code = 200; _contentLength = 0; _contentType = contentType; - _content = new cbuf(bufferSize); + _content = std::unique_ptr(new cbuf(bufferSize)); //std::make_unique(bufferSize); } -AsyncResponseStream::~AsyncResponseStream(){ - delete _content; -} +AsyncResponseStream::~AsyncResponseStream() = default; size_t AsyncResponseStream::_fillBuffer(uint8_t *buf, size_t maxLen){ return _content->read((char*)buf, maxLen); From 7f172eabf6ad21eb9b4e72f309638ef22aa54b6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Villac=C3=ADs=20Lasso?= Date: Tue, 29 Dec 2020 16:49:19 -0500 Subject: [PATCH 093/551] Replace use of LinkedList with std::list for AsyncWebServerResponse headers Fraction of commit 8bb1c704cd70dd58b318b296154a5404a1bd27d0 of dumbfixes branch of 0xFEEDC0DE64 fork of ESPAsyncWebServer. This uses defaulted copy constructors for AsyncWebHeader from a previous commit. Step three of removal of homebrewed LinkedList in favor of standard C++ containers. Also removed from DefaultHeaders class. --- src/ESPAsyncWebServer.h | 14 +++++++------- src/WebResponses.cpp | 15 ++++++--------- 2 files changed, 13 insertions(+), 16 deletions(-) diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index 32d0cd386..042515992 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -380,7 +380,7 @@ typedef enum { class AsyncWebServerResponse { protected: int _code; - LinkedList _headers; + std::list _headers; String _contentType; size_t _contentLength; bool _sendContentLength; @@ -463,17 +463,16 @@ class AsyncWebServer { }; class DefaultHeaders { - using headers_t = LinkedList; + using headers_t = std::list; headers_t _headers; - DefaultHeaders() - :_headers(headers_t([](AsyncWebHeader *h){ delete h; })) - {} public: - using ConstIterator = headers_t::ConstIterator; + DefaultHeaders() = default; + + using ConstIterator = headers_t::const_iterator; void addHeader(const String& name, const String& value){ - _headers.add(new AsyncWebHeader(name, value)); + _headers.emplace_back(name, value); } ConstIterator begin() const { return _headers.begin(); } @@ -481,6 +480,7 @@ class DefaultHeaders { DefaultHeaders(DefaultHeaders const &) = delete; DefaultHeaders &operator=(DefaultHeaders const &) = delete; + static DefaultHeaders &Instance() { static DefaultHeaders instance; return instance; diff --git a/src/WebResponses.cpp b/src/WebResponses.cpp index f7722bf80..22a549f65 100644 --- a/src/WebResponses.cpp +++ b/src/WebResponses.cpp @@ -88,7 +88,6 @@ const __FlashStringHelper *AsyncWebServerResponse::responseCodeToString(int code AsyncWebServerResponse::AsyncWebServerResponse() : _code(0) - , _headers(LinkedList([](AsyncWebHeader *h){ delete h; })) , _contentType() , _contentLength(0) , _sendContentLength(true) @@ -99,14 +98,12 @@ AsyncWebServerResponse::AsyncWebServerResponse() , _writtenLength(0) , _state(RESPONSE_SETUP) { - for(auto header: DefaultHeaders::Instance()) { - _headers.add(new AsyncWebHeader(header->name(), header->value())); + for(const auto &header: DefaultHeaders::Instance()) { + _headers.emplace_back(header); } } -AsyncWebServerResponse::~AsyncWebServerResponse(){ - _headers.free(); -} +AsyncWebServerResponse::~AsyncWebServerResponse() = default; void AsyncWebServerResponse::setCode(int code){ if(_state == RESPONSE_SETUP) @@ -124,7 +121,7 @@ void AsyncWebServerResponse::setContentType(const String& type){ } void AsyncWebServerResponse::addHeader(const String& name, const String& value){ - _headers.add(new AsyncWebHeader(name, value)); + _headers.emplace_back(name, value); } String AsyncWebServerResponse::_assembleHead(uint8_t version){ @@ -150,10 +147,10 @@ String AsyncWebServerResponse::_assembleHead(uint8_t version){ } for(const auto& header: _headers){ - snprintf_P(buf, bufSize, PSTR("%s: %s\r\n"), header->name().c_str(), header->value().c_str()); + snprintf_P(buf, bufSize, PSTR("%s: %s\r\n"), header.name().c_str(), header.value().c_str()); out.concat(buf); } - _headers.free(); + _headers.clear(); out.concat(F("\r\n")); _headLength = out.length(); From 380ead2b8f62ae7b999ae887c11d18090a557018 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Villac=C3=ADs=20Lasso?= Date: Tue, 29 Dec 2020 17:28:42 -0500 Subject: [PATCH 094/551] Remove no-longer-used StringArray class Fraction of commit 8bb1c704cd70dd58b318b296154a5404a1bd27d0 of dumbfixes branch of 0xFEEDC0DE64 fork of ESPAsyncWebServer. Split off for clarity. --- src/StringArray.h | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/src/StringArray.h b/src/StringArray.h index 4c0aa7019..d5096e699 100644 --- a/src/StringArray.h +++ b/src/StringArray.h @@ -171,23 +171,4 @@ class LinkedList { } }; - -class StringArray : public LinkedList { -public: - - StringArray() : LinkedList(nullptr) {} - - bool containsIgnoreCase(const String& str){ - for (const auto& s : *this) { - if (str.equalsIgnoreCase(s)) { - return true; - } - } - return false; - } -}; - - - - #endif /* STRINGARRAY_H_ */ From c3e4ca1f922bd47d1b4572b44b3affc1543f9002 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Villac=C3=ADs=20Lasso?= Date: Tue, 29 Dec 2020 17:43:35 -0500 Subject: [PATCH 095/551] Replace use of LinkedList with std::list for AsyncWebServer clients Fraction of commit 8bb1c704cd70dd58b318b296154a5404a1bd27d0 of dumbfixes branch of 0xFEEDC0DE64 fork of ESPAsyncWebServer. Const-ify a few methods of AsyncWebServer. Instead of using the new operator to create the AsyncWebSocketClient and then discarding it while adding the pointer to the client list, just create the client inside the standard list container. Workarounds for lack of auto parameter support in lambdas used by original patch. --- src/AsyncWebSocket.cpp | 116 ++++++++++++++++++++--------------------- src/AsyncWebSocket.h | 20 +++---- 2 files changed, 68 insertions(+), 68 deletions(-) diff --git a/src/AsyncWebSocket.cpp b/src/AsyncWebSocket.cpp index 8905b8e5e..ff4db1d7e 100644 --- a/src/AsyncWebSocket.cpp +++ b/src/AsyncWebSocket.cpp @@ -540,7 +540,6 @@ AsyncWebSocketClient::AsyncWebSocketClient(AsyncWebServerRequest *request, Async _client->onTimeout([](void *r, AsyncClient* c, uint32_t time){ (void)c; ((AsyncWebSocketClient*)(r))->_onTimeout(time); }, this); _client->onData([](void *r, AsyncClient* c, void *buf, size_t len){ (void)c; ((AsyncWebSocketClient*)(r))->_onData(buf, len); }, this); _client->onPoll([](void *r, AsyncClient* c){ (void)c; ((AsyncWebSocketClient*)(r))->_onPoll(); }, this); - _server->_addClient(this); _server->_handleEvent(this, WS_EVT_CONNECT, request, NULL, 0); delete request; memset(&_pinfo,0,sizeof(_pinfo)); @@ -614,9 +613,8 @@ void AsyncWebSocketClient::_runQueue(){ _clearQueue(); } -bool AsyncWebSocketClient::queueIsFull(){ - if((_messageQueue.length() >= WS_MAX_QUEUED_MESSAGES) || (_status != WS_CONNECTED) ) return true; - return false; +bool AsyncWebSocketClient::queueIsFull() const { + return (_messageQueue.length() >= WS_MAX_QUEUED_MESSAGES) || (_status != WS_CONNECTED); } void AsyncWebSocketClient::_queueMessage(AsyncWebSocketMessage *dataMessage){ @@ -909,14 +907,14 @@ void AsyncWebSocketClient::binary(AsyncWebSocketMessageBuffer * buffer) _queueMessage(new AsyncWebSocketMultiMessage(buffer, WS_BINARY)); } -IPAddress AsyncWebSocketClient::remoteIP() { +IPAddress AsyncWebSocketClient::remoteIP() const { if(!_client) { return IPAddress(0U); } return _client->remoteIP(); } -uint16_t AsyncWebSocketClient::remotePort() { +uint16_t AsyncWebSocketClient::remotePort() const { if(!_client) { return 0; } @@ -931,7 +929,6 @@ uint16_t AsyncWebSocketClient::remotePort() { AsyncWebSocket::AsyncWebSocket(const String& url) :_url(url) - ,_clients(LinkedList([](AsyncWebSocketClient *c){ delete c; })) ,_cNextId(1) ,_enabled(true) { @@ -946,64 +943,65 @@ void AsyncWebSocket::_handleEvent(AsyncWebSocketClient * client, AwsEventType ty } } -void AsyncWebSocket::_addClient(AsyncWebSocketClient * client){ - _clients.add(client); +AsyncWebSocketClient *AsyncWebSocket::_newClient(AsyncWebServerRequest *request) +{ + _clients.emplace_back(request, this); + return &_clients.back(); } void AsyncWebSocket::_handleDisconnect(AsyncWebSocketClient * client){ - - _clients.remove_first([=](AsyncWebSocketClient * c){ - return c->id() == client->id(); - }); + const auto client_id = client->id(); + const auto iter = std::find_if(std::begin(_clients), std::end(_clients), + [client_id](const AsyncWebSocketClient &c){ return c.id() == client_id; }); + if (iter != std::end(_clients)) + _clients.erase(iter); } bool AsyncWebSocket::availableForWriteAll(){ - for(const auto& c: _clients){ - if(c->queueIsFull()) return false; - } - return true; + return std::none_of(std::begin(_clients), std::end(_clients), + [](const AsyncWebSocketClient &c){ return c.queueIsFull(); }); } bool AsyncWebSocket::availableForWrite(uint32_t id){ - for(const auto& c: _clients){ - if(c->queueIsFull() && (c->id() == id )) return false; - } - return true; + const auto iter = std::find_if(std::begin(_clients), std::end(_clients), + [id](const AsyncWebSocketClient &c){ return c.id() == id; }); + if (iter == std::end(_clients)) + return true; // don't know why me-no-dev decided like this? + return !iter->queueIsFull(); } size_t AsyncWebSocket::count() const { - return _clients.count_if([](AsyncWebSocketClient * c){ - return c->status() == WS_CONNECTED; - }); + return std::count_if(std::begin(_clients), std::end(_clients), + [](const AsyncWebSocketClient &c){ return c.status() == WS_CONNECTED; }); } AsyncWebSocketClient * AsyncWebSocket::client(uint32_t id){ - for(const auto &c: _clients){ - if(c->id() == id && c->status() == WS_CONNECTED){ - return c; - } - } - return nullptr; + const auto iter = std::find_if(std::begin(_clients), std::end(_clients), + [id](const AsyncWebSocketClient &c){ return c.id() == id && c.status() == WS_CONNECTED; }); + if (iter == std::end(_clients)) + return nullptr; + + return &(*iter); } void AsyncWebSocket::close(uint32_t id, uint16_t code, const char * message){ - AsyncWebSocketClient * c = client(id); - if(c) + AsyncWebSocketClient *c = client(id); + if (c) c->close(code, message); } void AsyncWebSocket::closeAll(uint16_t code, const char * message){ - for(const auto& c: _clients){ - if(c->status() == WS_CONNECTED) - c->close(code, message); + for(auto& c: _clients){ + if(c.status() == WS_CONNECTED) + c.close(code, message); } } void AsyncWebSocket::cleanupClients(uint16_t maxClients) { if (count() > maxClients){ - _clients.front()->close(); + _clients.front().close(); } } @@ -1014,14 +1012,14 @@ void AsyncWebSocket::ping(uint32_t id, uint8_t *data, size_t len){ } void AsyncWebSocket::pingAll(uint8_t *data, size_t len){ - for(const auto& c: _clients){ - if(c->status() == WS_CONNECTED) - c->ping(data, len); + for(auto& c: _clients){ + if(c.status() == WS_CONNECTED) + c.ping(data, len); } } void AsyncWebSocket::text(uint32_t id, const char * message, size_t len){ - AsyncWebSocketClient * c = client(id); + AsyncWebSocketClient *c = client(id); if(c) c->text(message, len); } @@ -1029,9 +1027,9 @@ void AsyncWebSocket::text(uint32_t id, const char * message, size_t len){ void AsyncWebSocket::textAll(AsyncWebSocketMessageBuffer * buffer){ if (!buffer) return; buffer->lock(); - for(const auto& c: _clients){ - if(c->status() == WS_CONNECTED){ - c->text(buffer); + for(auto& c: _clients){ + if(c.status() == WS_CONNECTED){ + c.text(buffer); } } buffer->unlock(); @@ -1060,24 +1058,24 @@ void AsyncWebSocket::binaryAll(AsyncWebSocketMessageBuffer * buffer) { if (!buffer) return; buffer->lock(); - for(const auto& c: _clients){ - if(c->status() == WS_CONNECTED) - c->binary(buffer); + for(auto& c: _clients){ + if(c.status() == WS_CONNECTED) + c.binary(buffer); } buffer->unlock(); _cleanBuffers(); } void AsyncWebSocket::message(uint32_t id, AsyncWebSocketMessage *message){ - AsyncWebSocketClient * c = client(id); - if(c) + AsyncWebSocketClient *c = client(id); + if (c) c->message(message); } void AsyncWebSocket::messageAll(AsyncWebSocketMultiMessage *message){ - for(const auto& c: _clients){ - if(c->status() == WS_CONNECTED) - c->message(message); + for(auto& c: _clients){ + if(c.status() == WS_CONNECTED) + c.message(message); } _cleanBuffers(); } @@ -1186,9 +1184,9 @@ void AsyncWebSocket::textAll(const String &message){ textAll(message.c_str(), message.length()); } void AsyncWebSocket::textAll(const __FlashStringHelper *message){ - for(const auto& c: _clients){ - if(c->status() == WS_CONNECTED) - c->text(message); + for(auto& c: _clients){ + if(c.status() == WS_CONNECTED) + c.text(message); } } void AsyncWebSocket::binary(uint32_t id, const char * message){ @@ -1221,9 +1219,9 @@ void AsyncWebSocket::binaryAll(const String &message){ binaryAll(message.c_str(), message.length()); } void AsyncWebSocket::binaryAll(const __FlashStringHelper *message, size_t len){ - for(const auto& c: _clients){ - if(c->status() == WS_CONNECTED) - c-> binary(message, len); + for(auto& c: _clients){ + if(c.status() == WS_CONNECTED) + c.binary(message, len); } } @@ -1333,7 +1331,7 @@ void AsyncWebSocket::_cleanBuffers() } } -AsyncWebSocket::AsyncWebSocketClientLinkedList AsyncWebSocket::getClients() const { +const AsyncWebSocket::AsyncWebSocketClientLinkedList &AsyncWebSocket::getClients() const { return _clients; } @@ -1391,7 +1389,7 @@ void AsyncWebSocketResponse::_respond(AsyncWebServerRequest *request){ size_t AsyncWebSocketResponse::_ack(AsyncWebServerRequest *request, size_t len, uint32_t time){ (void)time; if(len){ - new AsyncWebSocketClient(request, _server); + _server->_newClient(request); } return 0; } diff --git a/src/AsyncWebSocket.h b/src/AsyncWebSocket.h index 3b39d902b..481844758 100644 --- a/src/AsyncWebSocket.h +++ b/src/AsyncWebSocket.h @@ -184,14 +184,16 @@ class AsyncWebSocketClient { ~AsyncWebSocketClient(); //client id increments for the given server - uint32_t id(){ return _clientId; } - AwsClientStatus status(){ return _status; } - AsyncClient* client(){ return _client; } + uint32_t id() const { return _clientId; } + AwsClientStatus status() const { return _status; } + AsyncClient* client() { return _client; } + const AsyncClient* client() const { return _client; } AsyncWebSocket *server(){ return _server; } + const AsyncWebSocket *server() const { return _server; } AwsFrameInfo const &pinfo() const { return _pinfo; } - IPAddress remoteIP(); - uint16_t remotePort(); + IPAddress remoteIP() const; + uint16_t remotePort() const; //control frames void close(uint16_t code=0, const char * message=NULL); @@ -207,7 +209,7 @@ class AsyncWebSocketClient { //data packets void message(AsyncWebSocketMessage *message){ _queueMessage(message); } - bool queueIsFull(); + bool queueIsFull() const; size_t queueLen() { return _messageQueue.length() + _controlQueue.length(); } size_t printf(const char *format, ...) __attribute__ ((format (printf, 2, 3))); @@ -247,7 +249,7 @@ typedef std::function AsyncWebSocketClientLinkedList; + typedef std::list AsyncWebSocketClientLinkedList; private: String _url; AsyncWebSocketClientLinkedList _clients; @@ -329,7 +331,7 @@ class AsyncWebSocket: public AsyncWebHandler { //system callbacks (do not call) uint32_t _getNextId(){ return _cNextId++; } - void _addClient(AsyncWebSocketClient * client); + AsyncWebSocketClient *_newClient(AsyncWebServerRequest *request); void _handleDisconnect(AsyncWebSocketClient * client); void _handleEvent(AsyncWebSocketClient * client, AwsEventType type, void * arg, uint8_t *data, size_t len); virtual bool canHandle(AsyncWebServerRequest *request) override final; @@ -342,7 +344,7 @@ class AsyncWebSocket: public AsyncWebHandler { std::list _buffers; void _cleanBuffers(); - AsyncWebSocketClientLinkedList getClients() const; + const AsyncWebSocketClientLinkedList &getClients() const; }; //WebServer response to authenticate the socket and detach the tcp client from the web server request From bf72f5484c6e55fb941fffebfae73757ff8dd2b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Villac=C3=ADs=20Lasso?= Date: Tue, 29 Dec 2020 18:10:26 -0500 Subject: [PATCH 096/551] Remove unnecessary typedef for websocket client list Fraction of commit f5e439c8f86609c3be855b76844352322e366b80 of dumbfixes branch of 0xFEEDC0DE64 fork of ESPAsyncWebServer. Split off for clarity. --- src/AsyncWebSocket.cpp | 4 ---- src/AsyncWebSocket.h | 6 ++---- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/src/AsyncWebSocket.cpp b/src/AsyncWebSocket.cpp index ff4db1d7e..c1c79009c 100644 --- a/src/AsyncWebSocket.cpp +++ b/src/AsyncWebSocket.cpp @@ -1331,10 +1331,6 @@ void AsyncWebSocket::_cleanBuffers() } } -const AsyncWebSocket::AsyncWebSocketClientLinkedList &AsyncWebSocket::getClients() const { - return _clients; -} - /* * Response to Web Socket request - sends the authorization and detaches the TCP Client from the web server * Authentication code from https://github.com/Links2004/arduinoWebSockets/blob/master/src/WebSockets.cpp#L480 diff --git a/src/AsyncWebSocket.h b/src/AsyncWebSocket.h index 481844758..414c5ffeb 100644 --- a/src/AsyncWebSocket.h +++ b/src/AsyncWebSocket.h @@ -248,11 +248,9 @@ typedef std::function AsyncWebSocketClientLinkedList; private: String _url; - AsyncWebSocketClientLinkedList _clients; + std::list _clients; uint32_t _cNextId; AwsEventHandler _eventHandler; AwsHandshakeHandler _handshakeHandler; @@ -344,7 +342,7 @@ class AsyncWebSocket: public AsyncWebHandler { std::list _buffers; void _cleanBuffers(); - const AsyncWebSocketClientLinkedList &getClients() const; + const std::list &getClients() const { return _clients; } }; //WebServer response to authenticate the socket and detach the tcp client from the web server request From 8feb6730a80ca313986d50a82f1c79a70f0230bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Villac=C3=ADs=20Lasso?= Date: Tue, 29 Dec 2020 18:49:23 -0500 Subject: [PATCH 097/551] _controlQueue is now a std::deque Based on commit f5e439c8f86609c3be855b76844352322e366b80 of dumbfixes branch of 0xFEEDC0DE64 fork of ESPAsyncWebServer. Unlike the original patch, clearing the std::queue using assignment of {} is not supported in C++11, and no other method of clearing the queue is available, so this forces use of std::deque instead. This in turn forces all methods of std::queue to be replaced with their underlying equivalents in std::deque. Control messages are constructed directly inside the container using .emplace_back() (.emplace() in the original patch) instead of building the message and passing its pointer as a parameter. --- src/AsyncWebSocket.cpp | 50 +++++++++++++++++++++--------------------- src/AsyncWebSocket.h | 7 +++--- 2 files changed, 29 insertions(+), 28 deletions(-) diff --git a/src/AsyncWebSocket.cpp b/src/AsyncWebSocket.cpp index c1c79009c..35a400300 100644 --- a/src/AsyncWebSocket.cpp +++ b/src/AsyncWebSocket.cpp @@ -522,8 +522,7 @@ AsyncWebSocketMultiMessage::~AsyncWebSocketMultiMessage() { const size_t AWSC_PING_PAYLOAD_LEN = 22; AsyncWebSocketClient::AsyncWebSocketClient(AsyncWebServerRequest *request, AsyncWebSocket *server) - : _controlQueue(LinkedList([](AsyncWebSocketControl *c){ delete c; })) - , _messageQueue(LinkedList([](AsyncWebSocketMessage *m){ delete m; })) + : _messageQueue(LinkedList([](AsyncWebSocketMessage *m){ delete m; })) , _tempObject(NULL) { _client = request->client(); @@ -548,7 +547,7 @@ AsyncWebSocketClient::AsyncWebSocketClient(AsyncWebServerRequest *request, Async AsyncWebSocketClient::~AsyncWebSocketClient(){ // Serial.printf("%u FREE Q\n", id()); _messageQueue.free(); - _controlQueue.free(); + _controlQueue.clear(); _server->_cleanBuffers(); _server->_handleEvent(this, WS_EVT_DISCONNECT, NULL, NULL, 0); } @@ -562,17 +561,17 @@ void AsyncWebSocketClient::_clearQueue(){ void AsyncWebSocketClient::_onAck(size_t len, uint32_t time){ // Serial.printf("%u onAck\n", id()); _lastMessageTime = millis(); - if(!_controlQueue.isEmpty()){ - auto head = _controlQueue.front(); - if(head->finished()){ - len -= head->len(); - if(_status == WS_DISCONNECTING && head->opcode() == WS_DISCONNECT){ - _controlQueue.remove(head); + if(!_controlQueue.empty()){ + auto &head = _controlQueue.front(); + if(head.finished()){ + len -= head.len(); + if(_status == WS_DISCONNECTING && head.opcode() == WS_DISCONNECT){ + _controlQueue.pop_front(); _status = WS_DISCONNECTED; _client->close(true); return; } - _controlQueue.remove(head); + _controlQueue.pop_front(); } } @@ -588,10 +587,9 @@ void AsyncWebSocketClient::_onAck(size_t len, uint32_t time){ } void AsyncWebSocketClient::_onPoll(){ - if(_client->canSend() && (!_controlQueue.isEmpty() || !_messageQueue.isEmpty())){ - // Serial.println("RUN 2"); + if(_client->canSend() && (!_controlQueue.empty() || !_messageQueue.isEmpty())){ _runQueue(); - } else if(_keepAlivePeriod > 0 && _controlQueue.isEmpty() && _messageQueue.isEmpty() && (millis() - _lastMessageTime) >= _keepAlivePeriod){ + } else if(_keepAlivePeriod > 0 && _controlQueue.empty() && _messageQueue.isEmpty() && (millis() - _lastMessageTime) >= _keepAlivePeriod){ ping((uint8_t *)AWSC_PING_PAYLOAD, AWSC_PING_PAYLOAD_LEN); } } @@ -602,9 +600,9 @@ void AsyncWebSocketClient::_runQueue(){ //size_t m0 = _messageQueue.isEmpty()? 0 : _messageQueue.length(); //size_t m1 = _messageQueue.isEmpty()? 0 : _messageQueue.front()->betweenFrames(); // Serial.printf("%u R C = %u %u\n", _clientId, m0, m1); - if(!_controlQueue.isEmpty() && (_messageQueue.isEmpty() || _messageQueue.front()->betweenFrames()) && webSocketSendFrameWindow(_client) > (size_t)(_controlQueue.front()->len() - 1)){ + if(!_controlQueue.empty() && (_messageQueue.isEmpty() || _messageQueue.front()->betweenFrames()) && webSocketSendFrameWindow(_client) > (size_t)(_controlQueue.front().len() - 1)){ // Serial.printf("%u R S C\n", _clientId); - _controlQueue.front()->send(_client); + _controlQueue.front().send(_client); } else if(!_messageQueue.isEmpty() && _messageQueue.front()->betweenFrames() && webSocketSendFrameWindow(_client)){ // Serial.printf("%u R S M = ", _clientId); _messageQueue.front()->send(_client); @@ -617,6 +615,10 @@ bool AsyncWebSocketClient::queueIsFull() const { return (_messageQueue.length() >= WS_MAX_QUEUED_MESSAGES) || (_status != WS_CONNECTED); } +size_t AsyncWebSocketClient::queueLen() const { + return _messageQueue.length() + _controlQueue.size(); +} + void AsyncWebSocketClient::_queueMessage(AsyncWebSocketMessage *dataMessage){ if(dataMessage == NULL){ // Serial.printf("%u Q1\n", _clientId); @@ -642,11 +644,9 @@ void AsyncWebSocketClient::_queueMessage(AsyncWebSocketMessage *dataMessage){ } } -void AsyncWebSocketClient::_queueControl(AsyncWebSocketControl *controlMessage){ - if(controlMessage == NULL) - return; - _controlQueue.add(controlMessage); - if(_client->canSend()) { +void AsyncWebSocketClient::_queueControl(uint8_t opcode, uint8_t *data, size_t len, bool mask){ + _controlQueue.emplace_back(opcode, data, len, mask); + if (_client->canSend()) { // Serial.println("RUN 4"); _runQueue(); } @@ -669,17 +669,17 @@ void AsyncWebSocketClient::close(uint16_t code, const char * message){ if(message != NULL){ memcpy(buf+2, message, packetLen -2); } - _queueControl(new AsyncWebSocketControl(WS_DISCONNECT,(uint8_t*)buf,packetLen)); + _queueControl(WS_DISCONNECT, (uint8_t*)buf, packetLen); free(buf); return; } } - _queueControl(new AsyncWebSocketControl(WS_DISCONNECT)); + _queueControl(WS_DISCONNECT); } void AsyncWebSocketClient::ping(uint8_t *data, size_t len){ if(_status == WS_CONNECTED) - _queueControl(new AsyncWebSocketControl(WS_PING, data, len)); + _queueControl(WS_PING, data, len); } void AsyncWebSocketClient::_onError(int8_t){ @@ -765,10 +765,10 @@ void AsyncWebSocketClient::_onData(void *pbuf, size_t plen){ } else { _status = WS_DISCONNECTING; _client->ackLater(); - _queueControl(new AsyncWebSocketControl(WS_DISCONNECT, data, datalen)); + _queueControl(WS_DISCONNECT, data, datalen); } } else if(_pinfo.opcode == WS_PING){ - _queueControl(new AsyncWebSocketControl(WS_PONG, data, datalen)); + _queueControl(WS_PONG, data, datalen); } else if(_pinfo.opcode == WS_PONG){ if(datalen != AWSC_PING_PAYLOAD_LEN || memcmp(AWSC_PING_PAYLOAD, data, AWSC_PING_PAYLOAD_LEN) != 0) _server->_handleEvent(this, WS_EVT_PONG, NULL, data, datalen); diff --git a/src/AsyncWebSocket.h b/src/AsyncWebSocket.h index 414c5ffeb..d23b144de 100644 --- a/src/AsyncWebSocket.h +++ b/src/AsyncWebSocket.h @@ -34,6 +34,7 @@ #include "AsyncWebSynchronization.h" #include +#include #ifdef ESP8266 #include @@ -163,7 +164,7 @@ class AsyncWebSocketClient { uint32_t _clientId; AwsClientStatus _status; - LinkedList _controlQueue; + std::deque _controlQueue; LinkedList _messageQueue; uint8_t _pstate; @@ -173,7 +174,7 @@ class AsyncWebSocketClient { uint32_t _keepAlivePeriod; void _queueMessage(AsyncWebSocketMessage *dataMessage); - void _queueControl(AsyncWebSocketControl *controlMessage); + void _queueControl(uint8_t opcode, uint8_t *data=NULL, size_t len=0, bool mask=false); void _runQueue(); void _clearQueue(); @@ -210,7 +211,7 @@ class AsyncWebSocketClient { //data packets void message(AsyncWebSocketMessage *message){ _queueMessage(message); } bool queueIsFull() const; - size_t queueLen() { return _messageQueue.length() + _controlQueue.length(); } + size_t queueLen() const; size_t printf(const char *format, ...) __attribute__ ((format (printf, 2, 3))); #ifndef ESP32 From 12b5f4966b6a95fa02d19e2e6644abf9df24e597 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Villac=C3=ADs=20Lasso?= Date: Wed, 30 Dec 2020 16:02:46 -0500 Subject: [PATCH 098/551] Replace one use of LinkedList with std::vector for web request path params Fraction of commit 9b98550f64000b937db9567b69e1275feccf1f0f of dumbfixes branch of 0xFEEDC0DE64 fork of ESPAsyncWebServer. Split off for clarity. --- src/ESPAsyncWebServer.h | 2 +- src/WebRequest.cpp | 8 +++----- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index 042515992..4497c9a14 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -184,7 +184,7 @@ class AsyncWebServerRequest { std::list _headers; LinkedList _params; - LinkedList _pathParams; + std::vector _pathParams; uint8_t _multiParseState; uint8_t _boundaryPosition; diff --git a/src/WebRequest.cpp b/src/WebRequest.cpp index 3594fb5d7..31613dfda 100644 --- a/src/WebRequest.cpp +++ b/src/WebRequest.cpp @@ -52,7 +52,6 @@ AsyncWebServerRequest::AsyncWebServerRequest(AsyncWebServer* s, AsyncClient* c) , _contentLength(0) , _parsedLength(0) , _params(LinkedList([](AsyncWebParameter *p){ delete p; })) - , _pathParams(LinkedList([](String *p){ delete p; })) , _multiParseState(0) , _boundaryPosition(0) , _itemStartIndex(0) @@ -78,7 +77,7 @@ AsyncWebServerRequest::~AsyncWebServerRequest(){ _headers.clear(); _params.free(); - _pathParams.free(); + _pathParams.clear(); _interestingHeaders.clear(); @@ -254,7 +253,7 @@ void AsyncWebServerRequest::_addParam(AsyncWebParameter *p){ } void AsyncWebServerRequest::_addPathParam(const char *p){ - _pathParams.add(new String(p)); + _pathParams.emplace_back(p); } void AsyncWebServerRequest::_addGetParams(const String& params){ @@ -915,8 +914,7 @@ const String& AsyncWebServerRequest::argName(size_t i) const { } const String& AsyncWebServerRequest::pathArg(size_t i) const { - auto param = _pathParams.nth(i); - return param ? **param : emptyString; + return i < _pathParams.size() ? _pathParams[i] : emptyString; } const String& AsyncWebServerRequest::header(const char* name) const { From 36cc1ea7eaee4ff0a302ebb81d8bdd3ff7bd5fa5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Villac=C3=ADs=20Lasso?= Date: Wed, 30 Dec 2020 18:05:02 -0500 Subject: [PATCH 099/551] Add locking around _messageQueue and _controlQueue in AsyncWebSocketClient Based on a combination of commits 344d31c1ffbffd845823e1f8c369fcbf2439e47d and 9b98550f64000b937db9567b69e1275feccf1f0f of of dumbfixes branch of 0xFEEDC0DE64 fork of ESPAsyncWebServer. This patch additionally introduces a PolymorphMessageContainer class, containing either a AsyncWebSocketBasicMessage or an AsyncWebSocketMultiMessage, and intented to be contained inside a std::deque (instead of a std::queue as on the original commits, as done in a previous commit). This patch therefore eliminates one more use of a LinkedList. Some code formatting done on the side too. --- src/AsyncWebSocket.cpp | 388 ++++++++++++++++++++-------------- src/AsyncWebSocket.h | 80 ++++++- src/AsyncWebSynchronization.h | 7 + 3 files changed, 306 insertions(+), 169 deletions(-) diff --git a/src/AsyncWebSocket.cpp b/src/AsyncWebSocket.cpp index 35a400300..4b14c25a0 100644 --- a/src/AsyncWebSocket.cpp +++ b/src/AsyncWebSocket.cpp @@ -416,14 +416,13 @@ AsyncWebSocketBasicMessage::~AsyncWebSocketBasicMessage() { */ -AsyncWebSocketMultiMessage::AsyncWebSocketMultiMessage(AsyncWebSocketMessageBuffer * buffer, uint8_t opcode, bool mask) +AsyncWebSocketMultiMessage::AsyncWebSocketMultiMessage(AsyncWebSocketMessageBuffer *buffer, uint8_t opcode, bool mask) :_len(0) ,_sent(0) ,_ack(0) ,_acked(0) ,_WSbuffer(nullptr) { - _opcode = opcode & 0x07; _mask = mask; @@ -522,134 +521,185 @@ AsyncWebSocketMultiMessage::~AsyncWebSocketMultiMessage() { const size_t AWSC_PING_PAYLOAD_LEN = 22; AsyncWebSocketClient::AsyncWebSocketClient(AsyncWebServerRequest *request, AsyncWebSocket *server) - : _messageQueue(LinkedList([](AsyncWebSocketMessage *m){ delete m; })) - , _tempObject(NULL) + : _tempObject(NULL) { - _client = request->client(); - _server = server; - _clientId = _server->_getNextId(); - _status = WS_CONNECTED; - _pstate = 0; - _lastMessageTime = millis(); - _keepAlivePeriod = 0; - _client->setRxTimeout(0); - _client->onError([](void *r, AsyncClient* c, int8_t error){ (void)c; ((AsyncWebSocketClient*)(r))->_onError(error); }, this); - _client->onAck([](void *r, AsyncClient* c, size_t len, uint32_t time){ (void)c; ((AsyncWebSocketClient*)(r))->_onAck(len, time); }, this); - _client->onDisconnect([](void *r, AsyncClient* c){ ((AsyncWebSocketClient*)(r))->_onDisconnect(); delete c; }, this); - _client->onTimeout([](void *r, AsyncClient* c, uint32_t time){ (void)c; ((AsyncWebSocketClient*)(r))->_onTimeout(time); }, this); - _client->onData([](void *r, AsyncClient* c, void *buf, size_t len){ (void)c; ((AsyncWebSocketClient*)(r))->_onData(buf, len); }, this); - _client->onPoll([](void *r, AsyncClient* c){ (void)c; ((AsyncWebSocketClient*)(r))->_onPoll(); }, this); - _server->_handleEvent(this, WS_EVT_CONNECT, request, NULL, 0); - delete request; - memset(&_pinfo,0,sizeof(_pinfo)); -} - -AsyncWebSocketClient::~AsyncWebSocketClient(){ - // Serial.printf("%u FREE Q\n", id()); - _messageQueue.free(); - _controlQueue.clear(); - _server->_cleanBuffers(); - _server->_handleEvent(this, WS_EVT_DISCONNECT, NULL, NULL, 0); + _client = request->client(); + _server = server; + _clientId = _server->_getNextId(); + _status = WS_CONNECTED; + _pstate = 0; + _lastMessageTime = millis(); + _keepAlivePeriod = 0; + _client->setRxTimeout(0); + _client->onError([](void *r, AsyncClient* c, int8_t error){ (void)c; ((AsyncWebSocketClient*)(r))->_onError(error); }, this); + _client->onAck([](void *r, AsyncClient* c, size_t len, uint32_t time){ (void)c; ((AsyncWebSocketClient*)(r))->_onAck(len, time); }, this); + _client->onDisconnect([](void *r, AsyncClient* c){ ((AsyncWebSocketClient*)(r))->_onDisconnect(); delete c; }, this); + _client->onTimeout([](void *r, AsyncClient* c, uint32_t time){ (void)c; ((AsyncWebSocketClient*)(r))->_onTimeout(time); }, this); + _client->onData([](void *r, AsyncClient* c, void *buf, size_t len){ (void)c; ((AsyncWebSocketClient*)(r))->_onData(buf, len); }, this); + _client->onPoll([](void *r, AsyncClient* c){ (void)c; ((AsyncWebSocketClient*)(r))->_onPoll(); }, this); + _server->_handleEvent(this, WS_EVT_CONNECT, request, NULL, 0); + delete request; + memset(&_pinfo,0,sizeof(_pinfo)); +} + +AsyncWebSocketClient::~AsyncWebSocketClient() +{ + { + AsyncWebLockGuard l(_lock); + + _messageQueue.clear(); + _controlQueue.clear(); + } + _server->_cleanBuffers(); + _server->_handleEvent(this, WS_EVT_DISCONNECT, NULL, NULL, 0); } void AsyncWebSocketClient::_clearQueue(){ - while(!_messageQueue.isEmpty() && _messageQueue.front()->finished()){ - _messageQueue.remove(_messageQueue.front()); - } + while (!_messageQueue.empty() && _messageQueue.front().get().finished()){ + _messageQueue.pop_front(); + } } void AsyncWebSocketClient::_onAck(size_t len, uint32_t time){ - // Serial.printf("%u onAck\n", id()); - _lastMessageTime = millis(); - if(!_controlQueue.empty()){ - auto &head = _controlQueue.front(); - if(head.finished()){ - len -= head.len(); - if(_status == WS_DISCONNECTING && head.opcode() == WS_DISCONNECT){ - _controlQueue.pop_front(); - _status = WS_DISCONNECTED; - _client->close(true); - return; - } - _controlQueue.pop_front(); - } - } + _lastMessageTime = millis(); + + { + AsyncWebLockGuard l(_lock); + + if (!_controlQueue.empty()){ + auto &head = _controlQueue.front(); + if(head.finished()){ + len -= head.len(); + if(_status == WS_DISCONNECTING && head.opcode() == WS_DISCONNECT){ + _controlQueue.pop_front(); + _status = WS_DISCONNECTED; + _client->close(true); + return; + } + _controlQueue.pop_front(); + } + } - if(len && !_messageQueue.isEmpty()){ - _messageQueue.front()->ack(len, time); - } + if(len && !_messageQueue.empty()){ + _messageQueue.front().get().ack(len, time); + } - _clearQueue(); + _clearQueue(); + } - _server->_cleanBuffers(); - // Serial.println("RUN 1"); - _runQueue(); + _server->_cleanBuffers(); + _runQueue(); } void AsyncWebSocketClient::_onPoll(){ - if(_client->canSend() && (!_controlQueue.empty() || !_messageQueue.isEmpty())){ - _runQueue(); - } else if(_keepAlivePeriod > 0 && _controlQueue.empty() && _messageQueue.isEmpty() && (millis() - _lastMessageTime) >= _keepAlivePeriod){ - ping((uint8_t *)AWSC_PING_PAYLOAD, AWSC_PING_PAYLOAD_LEN); - } + if(_client->canSend() && [this](){ AsyncWebLockGuard l(_lock); return !_controlQueue.empty() || !_messageQueue.empty(); }()) + { + _runQueue(); + } else if(_keepAlivePeriod > 0 && (millis() - _lastMessageTime) >= _keepAlivePeriod && + [this](){ AsyncWebLockGuard l(_lock); return _controlQueue.empty() && _messageQueue.empty(); }()) + { + ping((uint8_t *)AWSC_PING_PAYLOAD, AWSC_PING_PAYLOAD_LEN); + } } -void AsyncWebSocketClient::_runQueue(){ - _clearQueue(); +void AsyncWebSocketClient::_runQueue() +{ + AsyncWebLockGuard l(_lock); - //size_t m0 = _messageQueue.isEmpty()? 0 : _messageQueue.length(); - //size_t m1 = _messageQueue.isEmpty()? 0 : _messageQueue.front()->betweenFrames(); - // Serial.printf("%u R C = %u %u\n", _clientId, m0, m1); - if(!_controlQueue.empty() && (_messageQueue.isEmpty() || _messageQueue.front()->betweenFrames()) && webSocketSendFrameWindow(_client) > (size_t)(_controlQueue.front().len() - 1)){ - // Serial.printf("%u R S C\n", _clientId); - _controlQueue.front().send(_client); - } else if(!_messageQueue.isEmpty() && _messageQueue.front()->betweenFrames() && webSocketSendFrameWindow(_client)){ - // Serial.printf("%u R S M = ", _clientId); - _messageQueue.front()->send(_client); - } + _clearQueue(); - _clearQueue(); + if(!_controlQueue.empty() && (_messageQueue.empty() || _messageQueue.front().get().betweenFrames()) && webSocketSendFrameWindow(_client) > (size_t)(_controlQueue.front().len() - 1)) + { + l.unlock(); + _controlQueue.front().send(_client); + } + else if (!_messageQueue.empty() && _messageQueue.front().get().betweenFrames() && webSocketSendFrameWindow(_client)) + { + l.unlock(); + _messageQueue.front().get().send(_client); + } } -bool AsyncWebSocketClient::queueIsFull() const { - return (_messageQueue.length() >= WS_MAX_QUEUED_MESSAGES) || (_status != WS_CONNECTED); +bool AsyncWebSocketClient::queueIsFull() const +{ + size_t size; + { + AsyncWebLockGuard l(_lock); + size = _messageQueue.size(); + } + return (size >= WS_MAX_QUEUED_MESSAGES) || (_status != WS_CONNECTED); } -size_t AsyncWebSocketClient::queueLen() const { - return _messageQueue.length() + _controlQueue.size(); +size_t AsyncWebSocketClient::queueLen() const +{ + AsyncWebLockGuard l(_lock); + + return _messageQueue.size() + _controlQueue.size(); } -void AsyncWebSocketClient::_queueMessage(AsyncWebSocketMessage *dataMessage){ - if(dataMessage == NULL){ - // Serial.printf("%u Q1\n", _clientId); - return; - } - if(_status != WS_CONNECTED){ - // Serial.printf("%u Q2\n", _clientId); - delete dataMessage; - return; - } - if(_messageQueue.length() >= WS_MAX_QUEUED_MESSAGES){ - ets_printf(String(F("ERROR: Too many messages queued\n")).c_str()); - // Serial.printf("%u Q3\n", _clientId); - delete dataMessage; - } else { - _messageQueue.add(dataMessage); - // Serial.printf("%u Q A %u\n", _clientId, _messageQueue.length()); - } - if(_client->canSend()) { - // Serial.printf("%u Q S\n", _clientId); - // Serial.println("RUN 3"); - _runQueue(); - } +bool AsyncWebSocketClient::canSend() const +{ + size_t size; + { + AsyncWebLockGuard l(_lock); + size = _messageQueue.size(); + } + return size < WS_MAX_QUEUED_MESSAGES; } -void AsyncWebSocketClient::_queueControl(uint8_t opcode, uint8_t *data, size_t len, bool mask){ - _controlQueue.emplace_back(opcode, data, len, mask); - if (_client->canSend()) { - // Serial.println("RUN 4"); - _runQueue(); - } +void AsyncWebSocketClient::_queueControl(uint8_t opcode, uint8_t *data, size_t len, bool mask) +{ + { + AsyncWebLockGuard l(_lock); + _controlQueue.emplace_back(opcode, data, len, mask); + } + + if (_client->canSend()) + _runQueue(); +} + +void AsyncWebSocketClient::_queueMessage(const char *data, size_t len, uint8_t opcode, bool mask) +{ + if(_status != WS_CONNECTED) + return; + + { + AsyncWebLockGuard l(_lock); + if (_messageQueue.size() >= WS_MAX_QUEUED_MESSAGES) + { + l.unlock(); + ets_printf("ERROR: Too many messages queued\n"); + } + else + { + _messageQueue.emplace_back(data, len, opcode, mask); + } + } + + if(_client->canSend()) + _runQueue(); +} + +void AsyncWebSocketClient::_queueMessage(AsyncWebSocketMessageBuffer *buffer, uint8_t opcode, bool mask) +{ + if(_status != WS_CONNECTED) + return; + + { + AsyncWebLockGuard l(_lock); + if (_messageQueue.size() >= WS_MAX_QUEUED_MESSAGES) + { + l.unlock(); + ets_printf("ERROR: Too many messages queued\n"); + } + else + { + _messageQueue.emplace_back(buffer, opcode, mask); + } + } + + if(_client->canSend()) + _runQueue(); } void AsyncWebSocketClient::close(uint16_t code, const char * message){ @@ -855,7 +905,7 @@ size_t AsyncWebSocketClient::printf_P(PGM_P formatP, ...) { #endif void AsyncWebSocketClient::text(const char * message, size_t len){ - _queueMessage(new AsyncWebSocketBasicMessage(message, len)); + _queueMessage(message, len); } void AsyncWebSocketClient::text(const char * message){ text(message, strlen(message)); @@ -874,11 +924,11 @@ void AsyncWebSocketClient::text(const __FlashStringHelper *data){ } void AsyncWebSocketClient::text(AsyncWebSocketMessageBuffer * buffer) { - _queueMessage(new AsyncWebSocketMultiMessage(buffer)); + _queueMessage(buffer); } void AsyncWebSocketClient::binary(const char * message, size_t len){ - _queueMessage(new AsyncWebSocketBasicMessage(message, len, WS_BINARY)); + _queueMessage(message, len, WS_BINARY); } void AsyncWebSocketClient::binary(const char * message){ binary(message, strlen(message)); @@ -904,7 +954,7 @@ void AsyncWebSocketClient::binary(const __FlashStringHelper *data, size_t len){ } void AsyncWebSocketClient::binary(AsyncWebSocketMessageBuffer * buffer) { - _queueMessage(new AsyncWebSocketMultiMessage(buffer, WS_BINARY)); + _queueMessage(buffer, WS_BINARY); } IPAddress AsyncWebSocketClient::remoteIP() const { @@ -1024,16 +1074,20 @@ void AsyncWebSocket::text(uint32_t id, const char * message, size_t len){ c->text(message, len); } -void AsyncWebSocket::textAll(AsyncWebSocketMessageBuffer * buffer){ - if (!buffer) return; - buffer->lock(); - for(auto& c: _clients){ - if(c.status() == WS_CONNECTED){ - c.text(buffer); - } - } - buffer->unlock(); - _cleanBuffers(); +void AsyncWebSocket::textAll(AsyncWebSocketMessageBuffer * buffer) +{ + if (!buffer) + return; + + buffer->lock(); + + for(auto &c : _clients) + if (c.status() == WS_CONNECTED) + c.text(buffer); + + buffer->unlock(); + + _cleanBuffers(); } @@ -1056,28 +1110,40 @@ void AsyncWebSocket::binaryAll(const char * message, size_t len){ void AsyncWebSocket::binaryAll(AsyncWebSocketMessageBuffer * buffer) { - if (!buffer) return; - buffer->lock(); - for(auto& c: _clients){ - if(c.status() == WS_CONNECTED) - c.binary(buffer); - } - buffer->unlock(); - _cleanBuffers(); + if (!buffer) + return; + + buffer->lock(); + + for (auto &c : _clients) + if (c.status() == WS_CONNECTED) + c.binary(buffer); + + buffer->unlock(); + + _cleanBuffers(); } -void AsyncWebSocket::message(uint32_t id, AsyncWebSocketMessage *message){ - AsyncWebSocketClient *c = client(id); - if (c) - c->message(message); +void AsyncWebSocket::message(uint32_t id, const char *data, size_t len, uint8_t opcode, bool mask) +{ + AsyncWebSocketClient *c = client(id); + if (c) + c->message(data, len, opcode, mask); } -void AsyncWebSocket::messageAll(AsyncWebSocketMultiMessage *message){ - for(auto& c: _clients){ - if(c.status() == WS_CONNECTED) - c.message(message); - } - _cleanBuffers(); +void AsyncWebSocket::message(uint32_t id, AsyncWebSocketMessageBuffer *buffer, uint8_t opcode, bool mask) +{ + AsyncWebSocketClient *c = client(id); + if (c) + c->message(buffer, opcode, mask); +} + +void AsyncWebSocket::messageAll(AsyncWebSocketMessageBuffer *buffer, uint8_t opcode, bool mask){ + for (auto &c : _clients){ + if (c.status() == WS_CONNECTED) + c.message(buffer, opcode, mask); + } + _cleanBuffers(); } size_t AsyncWebSocket::printf(uint32_t id, const char *format, ...){ @@ -1295,40 +1361,42 @@ void AsyncWebSocket::handleRequest(AsyncWebServerRequest *request){ request->send(response); } -AsyncWebSocketMessageBuffer * AsyncWebSocket::makeBuffer(size_t size) +AsyncWebSocketMessageBuffer *AsyncWebSocket::makeBuffer(size_t size) { - AsyncWebSocketMessageBuffer * buffer{}; - { - AsyncWebLockGuard l(_lock); - _buffers.emplace_back(size); - buffer = &_buffers.back(); - } - return buffer; + AsyncWebSocketMessageBuffer * buffer{}; + + { + AsyncWebLockGuard l(_lock); + _buffers.emplace_back(size); + buffer = &_buffers.back(); + } + + return buffer; } -AsyncWebSocketMessageBuffer * AsyncWebSocket::makeBuffer(uint8_t * data, size_t size) +AsyncWebSocketMessageBuffer *AsyncWebSocket::makeBuffer(uint8_t * data, size_t size) { - AsyncWebSocketMessageBuffer * buffer{}; + AsyncWebSocketMessageBuffer * buffer{}; - { - AsyncWebLockGuard l(_lock); - _buffers.emplace_back(data, size); - buffer = &_buffers.back(); - } + { + AsyncWebLockGuard l(_lock); + _buffers.emplace_back(data, size); + buffer = &_buffers.back(); + } - return buffer; + return buffer; } void AsyncWebSocket::_cleanBuffers() { - AsyncWebLockGuard l(_lock); + AsyncWebLockGuard l(_lock); - for (auto iter = std::begin(_buffers); iter != std::end(_buffers);){ - if(iter->canDelete()){ - iter = _buffers.erase(iter); - } else - iter++; - } + for (auto iter = std::begin(_buffers); iter != std::end(_buffers);){ + if(iter->canDelete()){ + iter = _buffers.erase(iter); + } else + iter++; + } } /* diff --git a/src/AsyncWebSocket.h b/src/AsyncWebSocket.h index d23b144de..30a8cf65a 100644 --- a/src/AsyncWebSocket.h +++ b/src/AsyncWebSocket.h @@ -148,7 +148,7 @@ class AsyncWebSocketMultiMessage: public AsyncWebSocketMessage { size_t _sent; size_t _ack; size_t _acked; - AsyncWebSocketMessageBuffer * _WSbuffer; + AsyncWebSocketMessageBuffer *_WSbuffer; public: AsyncWebSocketMultiMessage(AsyncWebSocketMessageBuffer * buffer, uint8_t opcode=WS_TEXT, bool mask=false); virtual ~AsyncWebSocketMultiMessage() override; @@ -157,6 +157,63 @@ class AsyncWebSocketMultiMessage: public AsyncWebSocketMessage { virtual size_t send(AsyncClient *client) override ; }; +class PolymorphMessageContainer +{ + union { + AsyncWebSocketBasicMessage basicMessage; + AsyncWebSocketMultiMessage multiMessage; + }; + + enum class Type : uint8_t { Basic, Multi }; + const Type type; + +public: + PolymorphMessageContainer() = delete; + PolymorphMessageContainer(const PolymorphMessageContainer &) = delete; + PolymorphMessageContainer &operator=(const PolymorphMessageContainer &) = delete; + + PolymorphMessageContainer(const char *data, size_t len, uint8_t opcode=WS_TEXT, bool mask=false) : + type{Type::Basic} + { + new (&basicMessage) AsyncWebSocketBasicMessage{data, len, opcode, mask}; + } + + PolymorphMessageContainer(AsyncWebSocketMessageBuffer *buffer, uint8_t opcode=WS_TEXT, bool mask=false) : + type{Type::Multi} + { + new (&multiMessage) AsyncWebSocketMultiMessage{buffer, opcode, mask}; + } + + ~PolymorphMessageContainer() + { + switch (type) + { + case Type::Basic: basicMessage.~AsyncWebSocketBasicMessage(); break; + case Type::Multi: multiMessage.~AsyncWebSocketMultiMessage(); break; + } + } + + AsyncWebSocketMessage &get() + { + switch (type) + { + case Type::Basic: return basicMessage; + case Type::Multi: return multiMessage; + } + __builtin_unreachable(); + } + + const AsyncWebSocketMessage &get() const + { + switch (type) + { + case Type::Basic: return basicMessage; + case Type::Multi: return multiMessage; + } + __builtin_unreachable(); + } +}; + class AsyncWebSocketClient { private: AsyncClient *_client; @@ -164,8 +221,10 @@ class AsyncWebSocketClient { uint32_t _clientId; AwsClientStatus _status; + AsyncWebLock _lock; + std::deque _controlQueue; - LinkedList _messageQueue; + std::deque _messageQueue; uint8_t _pstate; AwsFrameInfo _pinfo; @@ -173,8 +232,9 @@ class AsyncWebSocketClient { uint32_t _lastMessageTime; uint32_t _keepAlivePeriod; - void _queueMessage(AsyncWebSocketMessage *dataMessage); void _queueControl(uint8_t opcode, uint8_t *data=NULL, size_t len=0, bool mask=false); + void _queueMessage(const char *data, size_t len, uint8_t opcode=WS_TEXT, bool mask=false); + void _queueMessage(AsyncWebSocketMessageBuffer *buffer, uint8_t opcode=WS_TEXT, bool mask=false); void _runQueue(); void _clearQueue(); @@ -209,7 +269,8 @@ class AsyncWebSocketClient { } //data packets - void message(AsyncWebSocketMessage *message){ _queueMessage(message); } + void message(const char *data, size_t len, uint8_t opcode=WS_TEXT, bool mask=false) { _queueMessage(data, len, opcode, mask); } + void message(AsyncWebSocketMessageBuffer *buffer, uint8_t opcode=WS_TEXT, bool mask=false) { _queueMessage(buffer, opcode, mask); } bool queueIsFull() const; size_t queueLen() const; @@ -233,7 +294,7 @@ class AsyncWebSocketClient { void binary(const __FlashStringHelper *data, size_t len); void binary(AsyncWebSocketMessageBuffer *buffer); - bool canSend() { return _messageQueue.length() < WS_MAX_QUEUED_MESSAGES; } + bool canSend() const; //system callbacks (do not call) void _onAck(size_t len, uint32_t time); @@ -291,7 +352,7 @@ class AsyncWebSocket: public AsyncWebHandler { void textAll(char * message); void textAll(const String &message); void textAll(const __FlashStringHelper *message); // need to convert - void textAll(AsyncWebSocketMessageBuffer * buffer); + void textAll(AsyncWebSocketMessageBuffer *buffer); void binary(uint32_t id, const char * message, size_t len); void binary(uint32_t id, const char * message); @@ -306,10 +367,11 @@ class AsyncWebSocket: public AsyncWebHandler { void binaryAll(char * message); void binaryAll(const String &message); void binaryAll(const __FlashStringHelper *message, size_t len); - void binaryAll(AsyncWebSocketMessageBuffer * buffer); + void binaryAll(AsyncWebSocketMessageBuffer *buffer); - void message(uint32_t id, AsyncWebSocketMessage *message); - void messageAll(AsyncWebSocketMultiMessage *message); + void message(uint32_t id, const char *data, size_t len, uint8_t opcode=WS_TEXT, bool mask=false); + void message(uint32_t id, AsyncWebSocketMessageBuffer *buffer, uint8_t opcode=WS_TEXT, bool mask=false); + void messageAll(AsyncWebSocketMessageBuffer *buffer, uint8_t opcode=WS_TEXT, bool mask=false); size_t printf(uint32_t id, const char *format, ...) __attribute__ ((format (printf, 3, 4))); size_t printfAll(const char *format, ...) __attribute__ ((format (printf, 2, 3))); diff --git a/src/AsyncWebSynchronization.h b/src/AsyncWebSynchronization.h index 02ad2dc61..0f76815b4 100644 --- a/src/AsyncWebSynchronization.h +++ b/src/AsyncWebSynchronization.h @@ -121,6 +121,13 @@ class AsyncWebLockGuard _lock->unlock(); } } + + void unlock() { + if (_lock) { + _lock->unlock(); + _lock = NULL; + } + } }; #endif // ASYNCWEBSYNCHRONIZATION_H_ From a8840bc6526351bb11773475ba29b3748cd086af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Villac=C3=ADs=20Lasso?= Date: Wed, 30 Dec 2020 19:25:25 -0500 Subject: [PATCH 100/551] Replace homebrewed smart pointer with std::shared_ptr and std::weak_ptr Based on commit 84833546f04ec6fbaa9c4dcb90d8761475de7a6e of dumbfixes branch of 0xFEEDC0DE64 fork of ESPAsyncWebServer. Buffers to data that is sent to all clients at once are stored as a single copy of the data with multiple references to it. This usage is one for which std::shared_ptr should be used. Each client having an active std::shared_ptr to a master buffer keeps the buffer alive. Once all clients have finished using their reference, the std::weak_ptr ensures that the AsyncWebSocketMessageBuffer goes out of scope and gets invalidated. This invalidation is checked with the lock() method of the std::weak_ptr. Also some code formatting while at it. A future commit will introduce an unification between single-client buffers and multiple-client buffers in such a way that the master buffer list in the AsyncWebSocket class will be redundant and will be removed. Therefore this stage is only temporary. --- src/AsyncWebSocket.cpp | 506 ++++++++++++++++++----------------------- src/AsyncWebSocket.h | 50 ++-- 2 files changed, 241 insertions(+), 315 deletions(-) diff --git a/src/AsyncWebSocket.cpp b/src/AsyncWebSocket.cpp index 4b14c25a0..1d165c77f 100644 --- a/src/AsyncWebSocket.cpp +++ b/src/AsyncWebSocket.cpp @@ -140,8 +140,6 @@ size_t webSocketSendFrame(AsyncClient *client, bool final, uint8_t opcode, bool AsyncWebSocketMessageBuffer::AsyncWebSocketMessageBuffer() :_data(nullptr) ,_len(0) - ,_lock(false) - ,_count(0) { } @@ -149,106 +147,36 @@ AsyncWebSocketMessageBuffer::AsyncWebSocketMessageBuffer() AsyncWebSocketMessageBuffer::AsyncWebSocketMessageBuffer(uint8_t * data, size_t size) :_data(nullptr) ,_len(size) - ,_lock(false) - ,_count(0) { + if (!data) + return; - if (!data) { - return; - } - - _data = new uint8_t[_len + 1]; - - if (_data) { - // Serial.println("BUFF alloc"); - memcpy(_data, data, _len); + _data = std::unique_ptr(new uint8_t[_len + 1]); //std::make_unique(_len + 1); + memcpy(_data.get(), data, _len); _data[_len] = 0; - } } AsyncWebSocketMessageBuffer::AsyncWebSocketMessageBuffer(size_t size) :_data(nullptr) ,_len(size) - ,_lock(false) - ,_count(0) -{ - _data = new uint8_t[_len + 1]; - - if (_data) { - // Serial.println("BUFF alloc"); - _data[_len] = 0; - } - -} - -AsyncWebSocketMessageBuffer::AsyncWebSocketMessageBuffer(const AsyncWebSocketMessageBuffer & copy) - :_data(nullptr) - ,_len(0) - ,_lock(false) - ,_count(0) { - _len = copy._len; - _lock = copy._lock; - _count = 0; - - if (_len) { - _data = new uint8_t[_len + 1]; + _data = std::unique_ptr(new uint8_t[_len + 1]); //std::make_unique(_len + 1); _data[_len] = 0; - } - - if (_data) { - // Serial.println("BUFF alloc"); - memcpy(_data, copy._data, _len); - _data[_len] = 0; - } - -} - -AsyncWebSocketMessageBuffer::AsyncWebSocketMessageBuffer(AsyncWebSocketMessageBuffer && copy) - :_data(nullptr) - ,_len(0) - ,_lock(false) - ,_count(0) -{ - _len = copy._len; - _lock = copy._lock; - _count = 0; - - if (copy._data) { - // Serial.println("BUFF alloc"); - _data = copy._data; - copy._data = nullptr; - } - } AsyncWebSocketMessageBuffer::~AsyncWebSocketMessageBuffer() { - if (_data) { - // Serial.println("BUFF free"); - delete[] _data; - } } bool AsyncWebSocketMessageBuffer::reserve(size_t size) { _len = size; - if (_data) { - delete[] _data; - _data = nullptr; - } - - _data = new uint8_t[_len + 1]; - - if (_data) { - _data[_len] = 0; - return true; - } else { - return false; - } + _data = std::unique_ptr(new uint8_t[_len + 1]); //std::make_unique(_len + 1); + _data[_len] = 0; + return true; } @@ -416,7 +344,7 @@ AsyncWebSocketBasicMessage::~AsyncWebSocketBasicMessage() { */ -AsyncWebSocketMultiMessage::AsyncWebSocketMultiMessage(AsyncWebSocketMessageBuffer *buffer, uint8_t opcode, bool mask) +AsyncWebSocketMultiMessage::AsyncWebSocketMultiMessage(std::shared_ptr buffer, uint8_t opcode, bool mask) :_len(0) ,_sent(0) ,_ack(0) @@ -428,8 +356,6 @@ AsyncWebSocketMultiMessage::AsyncWebSocketMultiMessage(AsyncWebSocketMessageBuff if (buffer) { _WSbuffer = buffer; - (*_WSbuffer)++; - // Serial.printf("INC WSbuffer == %u\n", _WSbuffer->count()); _data = buffer->get(); _len = buffer->length(); _status = WS_MSG_SENDING; @@ -443,10 +369,6 @@ AsyncWebSocketMultiMessage::AsyncWebSocketMultiMessage(AsyncWebSocketMessageBuff AsyncWebSocketMultiMessage::~AsyncWebSocketMultiMessage() { - if (_WSbuffer) { - (*_WSbuffer)--; // decreases the counter. - // Serial.printf("DEC WSbuffer == %u\n", _WSbuffer->count()); - } } void AsyncWebSocketMultiMessage::ack(size_t len, uint32_t time) { @@ -680,7 +602,7 @@ void AsyncWebSocketClient::_queueMessage(const char *data, size_t len, uint8_t o _runQueue(); } -void AsyncWebSocketClient::_queueMessage(AsyncWebSocketMessageBuffer *buffer, uint8_t opcode, bool mask) +void AsyncWebSocketClient::_queueMessage(std::shared_ptr buffer, uint8_t opcode, bool mask) { if(_status != WS_CONNECTED) return; @@ -922,49 +844,56 @@ void AsyncWebSocketClient::text(const String &message){ void AsyncWebSocketClient::text(const __FlashStringHelper *data){ text(String(data)); } -void AsyncWebSocketClient::text(AsyncWebSocketMessageBuffer * buffer) +void AsyncWebSocketClient::text(std::shared_ptr buffer) { - _queueMessage(buffer); + _queueMessage(buffer); } -void AsyncWebSocketClient::binary(const char * message, size_t len){ - _queueMessage(message, len, WS_BINARY); +void AsyncWebSocketClient::binary(const char * message, size_t len) +{ + _queueMessage(message, len, WS_BINARY); } -void AsyncWebSocketClient::binary(const char * message){ - binary(message, strlen(message)); +void AsyncWebSocketClient::binary(const char * message) +{ + binary(message, strlen(message)); } -void AsyncWebSocketClient::binary(uint8_t * message, size_t len){ - binary((const char *)message, len); +void AsyncWebSocketClient::binary(uint8_t * message, size_t len) +{ + binary((const char *)message, len); } -void AsyncWebSocketClient::binary(char * message){ - binary(message, strlen(message)); +void AsyncWebSocketClient::binary(char * message) +{ + binary(message, strlen(message)); } -void AsyncWebSocketClient::binary(const String &message){ - binary(message.c_str(), message.length()); +void AsyncWebSocketClient::binary(const String &message) +{ + binary(message.c_str(), message.length()); } -void AsyncWebSocketClient::binary(const __FlashStringHelper *data, size_t len){ - PGM_P p = reinterpret_cast(data); - char * message = (char*) malloc(len); - if(message){ - memcpy_P(message, p, len); - binary(message, len); - free(message); - } - +void AsyncWebSocketClient::binary(const __FlashStringHelper *data, size_t len) +{ + PGM_P p = reinterpret_cast(data); + char * message = (char*) malloc(len); + if(message) { + memcpy_P(message, p, len); + binary(message, len); + free(message); + } } -void AsyncWebSocketClient::binary(AsyncWebSocketMessageBuffer * buffer) +void AsyncWebSocketClient::binary(std::shared_ptr buffer) { - _queueMessage(buffer, WS_BINARY); + _queueMessage(buffer, WS_BINARY); } -IPAddress AsyncWebSocketClient::remoteIP() const { - if(!_client) { +IPAddress AsyncWebSocketClient::remoteIP() const +{ + if (!_client) { return IPAddress(0U); } return _client->remoteIP(); } -uint16_t AsyncWebSocketClient::remotePort() const { +uint16_t AsyncWebSocketClient::remotePort() const +{ if(!_client) { return 0; } @@ -1041,8 +970,10 @@ void AsyncWebSocket::close(uint32_t id, uint16_t code, const char * message){ c->close(code, message); } -void AsyncWebSocket::closeAll(uint16_t code, const char * message){ - for(auto& c: _clients){ +void AsyncWebSocket::closeAll(uint16_t code, const char * message) +{ + for(auto& c: _clients) + { if(c.status() == WS_CONNECTED) c.close(code, message); } @@ -1055,72 +986,68 @@ void AsyncWebSocket::cleanupClients(uint16_t maxClients) } } -void AsyncWebSocket::ping(uint32_t id, uint8_t *data, size_t len){ +void AsyncWebSocket::ping(uint32_t id, uint8_t *data, size_t len) +{ AsyncWebSocketClient * c = client(id); if(c) c->ping(data, len); } -void AsyncWebSocket::pingAll(uint8_t *data, size_t len){ +void AsyncWebSocket::pingAll(uint8_t *data, size_t len) +{ for(auto& c: _clients){ if(c.status() == WS_CONNECTED) c.ping(data, len); } } -void AsyncWebSocket::text(uint32_t id, const char * message, size_t len){ +void AsyncWebSocket::text(uint32_t id, const char * message, size_t len) +{ AsyncWebSocketClient *c = client(id); if(c) c->text(message, len); } -void AsyncWebSocket::textAll(AsyncWebSocketMessageBuffer * buffer) +void AsyncWebSocket::textAll(std::shared_ptr buffer) { if (!buffer) return; - buffer->lock(); - for(auto &c : _clients) if (c.status() == WS_CONNECTED) c.text(buffer); - buffer->unlock(); - _cleanBuffers(); } -void AsyncWebSocket::textAll(const char * message, size_t len){ - //if (_buffers.length()) return; - AsyncWebSocketMessageBuffer * WSBuffer = makeBuffer((uint8_t *)message, len); +void AsyncWebSocket::textAll(const char * message, size_t len) +{ + std::shared_ptr WSBuffer = makeBuffer((uint8_t *)message, len); textAll(WSBuffer); } -void AsyncWebSocket::binary(uint32_t id, const char * message, size_t len){ - AsyncWebSocketClient * c = client(id); - if(c) - c->binary(message, len); +void AsyncWebSocket::binary(uint32_t id, const char * message, size_t len) +{ + AsyncWebSocketClient * c = client(id); + if(c) + c->binary(message, len); } void AsyncWebSocket::binaryAll(const char * message, size_t len){ - AsyncWebSocketMessageBuffer * buffer = makeBuffer((uint8_t *)message, len); + std::shared_ptr buffer = makeBuffer((uint8_t *)message, len); binaryAll(buffer); } -void AsyncWebSocket::binaryAll(AsyncWebSocketMessageBuffer * buffer) +void AsyncWebSocket::binaryAll(std::shared_ptr buffer) { if (!buffer) return; - buffer->lock(); - for (auto &c : _clients) if (c.status() == WS_CONNECTED) c.binary(buffer); - buffer->unlock(); - _cleanBuffers(); } @@ -1131,18 +1058,19 @@ void AsyncWebSocket::message(uint32_t id, const char *data, size_t len, uint8_t c->message(data, len, opcode, mask); } -void AsyncWebSocket::message(uint32_t id, AsyncWebSocketMessageBuffer *buffer, uint8_t opcode, bool mask) +void AsyncWebSocket::message(uint32_t id, std::shared_ptr buffer, uint8_t opcode, bool mask) { AsyncWebSocketClient *c = client(id); if (c) c->message(buffer, opcode, mask); } -void AsyncWebSocket::messageAll(AsyncWebSocketMessageBuffer *buffer, uint8_t opcode, bool mask){ - for (auto &c : _clients){ +void AsyncWebSocket::messageAll(std::shared_ptr buffer, uint8_t opcode, bool mask) +{ + for (auto &c : _clients) if (c.status() == WS_CONNECTED) c.message(buffer, opcode, mask); - } + _cleanBuffers(); } @@ -1158,28 +1086,26 @@ size_t AsyncWebSocket::printf(uint32_t id, const char *format, ...){ return 0; } -size_t AsyncWebSocket::printfAll(const char *format, ...) { - va_list arg; - char* temp = new char[MAX_PRINTF_LEN]; - if(!temp){ - return 0; - } - va_start(arg, format); - size_t len = vsnprintf(temp, MAX_PRINTF_LEN, format, arg); - va_end(arg); - delete[] temp; +size_t AsyncWebSocket::printfAll(const char *format, ...) +{ + va_list arg; + char* temp = new char[MAX_PRINTF_LEN]; + if(!temp){ + return 0; + } + va_start(arg, format); + size_t len = vsnprintf(temp, MAX_PRINTF_LEN, format, arg); + va_end(arg); + delete[] temp; - AsyncWebSocketMessageBuffer * buffer = makeBuffer(len); - if (!buffer) { - return 0; - } + std::shared_ptr buffer = makeBuffer(len); - va_start(arg, format); - vsnprintf( (char *)buffer->get(), len + 1, format, arg); - va_end(arg); + va_start(arg, format); + vsnprintf( (char *)buffer->get(), len + 1, format, arg); + va_end(arg); - textAll(buffer); - return len; + textAll(buffer); + return len; } #ifndef ESP32 @@ -1197,99 +1123,115 @@ size_t AsyncWebSocket::printf_P(uint32_t id, PGM_P formatP, ...){ #endif size_t AsyncWebSocket::printfAll_P(PGM_P formatP, ...) { - va_list arg; - char* temp = new char[MAX_PRINTF_LEN]; - if(!temp){ - return 0; - } - va_start(arg, formatP); - size_t len = vsnprintf_P(temp, MAX_PRINTF_LEN, formatP, arg); - va_end(arg); - delete[] temp; + va_list arg; + char* temp = new char[MAX_PRINTF_LEN]; + if(!temp){ + return 0; + } + va_start(arg, formatP); + size_t len = vsnprintf_P(temp, MAX_PRINTF_LEN, formatP, arg); + va_end(arg); + delete[] temp; - AsyncWebSocketMessageBuffer * buffer = makeBuffer(len + 1); - if (!buffer) { - return 0; - } + std::shared_ptr buffer = makeBuffer(len + 1); - va_start(arg, formatP); - vsnprintf_P((char *)buffer->get(), len + 1, formatP, arg); - va_end(arg); + va_start(arg, formatP); + vsnprintf_P((char *)buffer->get(), len + 1, formatP, arg); + va_end(arg); - textAll(buffer); - return len; + textAll(buffer); + return len; } -void AsyncWebSocket::text(uint32_t id, const char * message){ - text(id, message, strlen(message)); +void AsyncWebSocket::text(uint32_t id, const char * message) +{ + text(id, message, strlen(message)); } -void AsyncWebSocket::text(uint32_t id, uint8_t * message, size_t len){ - text(id, (const char *)message, len); +void AsyncWebSocket::text(uint32_t id, uint8_t * message, size_t len) +{ + text(id, (const char *)message, len); } -void AsyncWebSocket::text(uint32_t id, char * message){ - text(id, message, strlen(message)); +void AsyncWebSocket::text(uint32_t id, char * message) +{ + text(id, message, strlen(message)); } -void AsyncWebSocket::text(uint32_t id, const String &message){ - text(id, message.c_str(), message.length()); +void AsyncWebSocket::text(uint32_t id, const String &message) +{ + text(id, message.c_str(), message.length()); } -void AsyncWebSocket::text(uint32_t id, const __FlashStringHelper *message){ - AsyncWebSocketClient * c = client(id); - if(c != NULL) - c->text(message); +void AsyncWebSocket::text(uint32_t id, const __FlashStringHelper *message) +{ + AsyncWebSocketClient * c = client(id); + if(c != NULL) + c->text(message); } -void AsyncWebSocket::textAll(const char * message){ - textAll(message, strlen(message)); +void AsyncWebSocket::textAll(const char * message) +{ + textAll(message, strlen(message)); } -void AsyncWebSocket::textAll(uint8_t * message, size_t len){ - textAll((const char *)message, len); +void AsyncWebSocket::textAll(uint8_t * message, size_t len) +{ + textAll((const char *)message, len); } -void AsyncWebSocket::textAll(char * message){ - textAll(message, strlen(message)); +void AsyncWebSocket::textAll(char * message) +{ + textAll(message, strlen(message)); } -void AsyncWebSocket::textAll(const String &message){ - textAll(message.c_str(), message.length()); +void AsyncWebSocket::textAll(const String &message) +{ + textAll(message.c_str(), message.length()); } -void AsyncWebSocket::textAll(const __FlashStringHelper *message){ - for(auto& c: _clients){ - if(c.status() == WS_CONNECTED) - c.text(message); - } +void AsyncWebSocket::textAll(const __FlashStringHelper *message) +{ + for (auto& c : _clients) + if (c.status() == WS_CONNECTED) + c.text(message); } -void AsyncWebSocket::binary(uint32_t id, const char * message){ - binary(id, message, strlen(message)); +void AsyncWebSocket::binary(uint32_t id, const char * message) +{ + binary(id, message, strlen(message)); } -void AsyncWebSocket::binary(uint32_t id, uint8_t * message, size_t len){ - binary(id, (const char *)message, len); +void AsyncWebSocket::binary(uint32_t id, uint8_t * message, size_t len) +{ + binary(id, (const char *)message, len); } -void AsyncWebSocket::binary(uint32_t id, char * message){ - binary(id, message, strlen(message)); +void AsyncWebSocket::binary(uint32_t id, char * message) +{ + binary(id, message, strlen(message)); } -void AsyncWebSocket::binary(uint32_t id, const String &message){ - binary(id, message.c_str(), message.length()); +void AsyncWebSocket::binary(uint32_t id, const String &message) +{ + binary(id, message.c_str(), message.length()); } -void AsyncWebSocket::binary(uint32_t id, const __FlashStringHelper *message, size_t len){ - AsyncWebSocketClient * c = client(id); - if(c != NULL) - c-> binary(message, len); +void AsyncWebSocket::binary(uint32_t id, const __FlashStringHelper *message, size_t len) +{ + AsyncWebSocketClient * c = client(id); + if (c != NULL) + c-> binary(message, len); } -void AsyncWebSocket::binaryAll(const char * message){ - binaryAll(message, strlen(message)); +void AsyncWebSocket::binaryAll(const char * message) +{ + binaryAll(message, strlen(message)); } -void AsyncWebSocket::binaryAll(uint8_t * message, size_t len){ - binaryAll((const char *)message, len); +void AsyncWebSocket::binaryAll(uint8_t * message, size_t len) +{ + binaryAll((const char *)message, len); } -void AsyncWebSocket::binaryAll(char * message){ - binaryAll(message, strlen(message)); +void AsyncWebSocket::binaryAll(char * message) +{ + binaryAll(message, strlen(message)); } -void AsyncWebSocket::binaryAll(const String &message){ - binaryAll(message.c_str(), message.length()); +void AsyncWebSocket::binaryAll(const String &message) +{ + binaryAll(message.c_str(), message.length()); +} +void AsyncWebSocket::binaryAll(const __FlashStringHelper *message, size_t len) +{ + for (auto& c : _clients) { + if (c.status() == WS_CONNECTED) + c.binary(message, len); + } } -void AsyncWebSocket::binaryAll(const __FlashStringHelper *message, size_t len){ - for(auto& c: _clients){ - if(c.status() == WS_CONNECTED) - c.binary(message, len); - } - } const char __WS_STR_CONNECTION[] PROGMEM = { "Connection" }; const char __WS_STR_UPGRADE[] PROGMEM = { "Upgrade" }; @@ -1312,76 +1254,73 @@ const char __WS_STR_UUID[] PROGMEM = { "258EAFA5-E914-47DA-95CA-C5AB0DC85B11" }; #define WS_STR_UUID FPSTR(__WS_STR_UUID) bool AsyncWebSocket::canHandle(AsyncWebServerRequest *request){ - if(!_enabled) - return false; - - if(request->method() != HTTP_GET || !request->url().equals(_url) || !request->isExpectedRequestedConnType(RCT_WS)) - return false; - - request->addInterestingHeader(WS_STR_CONNECTION); - request->addInterestingHeader(WS_STR_UPGRADE); - request->addInterestingHeader(WS_STR_ORIGIN); - request->addInterestingHeader(WS_STR_COOKIE); - request->addInterestingHeader(WS_STR_VERSION); - request->addInterestingHeader(WS_STR_KEY); - request->addInterestingHeader(WS_STR_PROTOCOL); - return true; + if(!_enabled) + return false; + + if(request->method() != HTTP_GET || !request->url().equals(_url) || !request->isExpectedRequestedConnType(RCT_WS)) + return false; + + request->addInterestingHeader(WS_STR_CONNECTION); + request->addInterestingHeader(WS_STR_UPGRADE); + request->addInterestingHeader(WS_STR_ORIGIN); + request->addInterestingHeader(WS_STR_COOKIE); + request->addInterestingHeader(WS_STR_VERSION); + request->addInterestingHeader(WS_STR_KEY); + request->addInterestingHeader(WS_STR_PROTOCOL); + return true; } -void AsyncWebSocket::handleRequest(AsyncWebServerRequest *request){ - if(!request->hasHeader(WS_STR_VERSION) || !request->hasHeader(WS_STR_KEY)){ - request->send(400); - return; - } - if((_username.length() && _password.length()) && !request->authenticate(_username.c_str(), _password.c_str())){ - return request->requestAuthentication(); - } -////////////////////////////////////////// - if(_handshakeHandler != nullptr){ - if(!_handshakeHandler(request)){ - request->send(401); - return; +void AsyncWebSocket::handleRequest(AsyncWebServerRequest *request) +{ + if (!request->hasHeader(WS_STR_VERSION) || !request->hasHeader(WS_STR_KEY)){ + request->send(400); + return; + } + if ((_username.length() && _password.length()) && !request->authenticate(_username.c_str(), _password.c_str())){ + return request->requestAuthentication(); + } + if (_handshakeHandler != nullptr){ + if(!_handshakeHandler(request)){ + request->send(401); + return; + } + } + AsyncWebHeader* version = request->getHeader(WS_STR_VERSION); + if (version->value().toInt() != 13){ + AsyncWebServerResponse *response = request->beginResponse(400); + response->addHeader(WS_STR_VERSION, F("13")); + request->send(response); + return; + } + AsyncWebHeader* key = request->getHeader(WS_STR_KEY); + AsyncWebServerResponse *response = new AsyncWebSocketResponse(key->value(), this); + if (request->hasHeader(WS_STR_PROTOCOL)){ + AsyncWebHeader* protocol = request->getHeader(WS_STR_PROTOCOL); + //ToDo: check protocol + response->addHeader(WS_STR_PROTOCOL, protocol->value()); } - } -////////////////////////////////////////// - AsyncWebHeader* version = request->getHeader(WS_STR_VERSION); - if(version->value().toInt() != 13){ - AsyncWebServerResponse *response = request->beginResponse(400); - response->addHeader(WS_STR_VERSION, F("13")); request->send(response); - return; - } - AsyncWebHeader* key = request->getHeader(WS_STR_KEY); - AsyncWebServerResponse *response = new AsyncWebSocketResponse(key->value(), this); - if(request->hasHeader(WS_STR_PROTOCOL)){ - AsyncWebHeader* protocol = request->getHeader(WS_STR_PROTOCOL); - //ToDo: check protocol - response->addHeader(WS_STR_PROTOCOL, protocol->value()); - } - request->send(response); } -AsyncWebSocketMessageBuffer *AsyncWebSocket::makeBuffer(size_t size) +std::shared_ptr AsyncWebSocket::makeBuffer(size_t size) { - AsyncWebSocketMessageBuffer * buffer{}; + std::shared_ptr buffer = std::make_shared(size); { AsyncWebLockGuard l(_lock); - _buffers.emplace_back(size); - buffer = &_buffers.back(); + _buffers.emplace_back(buffer); } return buffer; } -AsyncWebSocketMessageBuffer *AsyncWebSocket::makeBuffer(uint8_t * data, size_t size) +std::shared_ptr AsyncWebSocket::makeBuffer(uint8_t * data, size_t size) { - AsyncWebSocketMessageBuffer * buffer{}; + std::shared_ptr buffer = std::make_shared(data, size); { AsyncWebLockGuard l(_lock); - _buffers.emplace_back(data, size); - buffer = &_buffers.back(); + _buffers.emplace_back(buffer); } return buffer; @@ -1390,12 +1329,11 @@ AsyncWebSocketMessageBuffer *AsyncWebSocket::makeBuffer(uint8_t * data, size_t s void AsyncWebSocket::_cleanBuffers() { AsyncWebLockGuard l(_lock); - for (auto iter = std::begin(_buffers); iter != std::end(_buffers);){ - if(iter->canDelete()){ - iter = _buffers.erase(iter); - } else + if(iter->lock()) iter++; + else + iter = _buffers.erase(iter); } } diff --git a/src/AsyncWebSocket.h b/src/AsyncWebSocket.h index 30a8cf65a..3d24e235c 100644 --- a/src/AsyncWebSocket.h +++ b/src/AsyncWebSocket.h @@ -35,6 +35,7 @@ #include #include +#include #ifdef ESP8266 #include @@ -85,30 +86,17 @@ typedef enum { WS_EVT_CONNECT, WS_EVT_DISCONNECT, WS_EVT_PONG, WS_EVT_ERROR, WS_ class AsyncWebSocketMessageBuffer { private: - uint8_t * _data; - size_t _len; - bool _lock; - uint32_t _count; + std::unique_ptr _data; + size_t _len{}; public: AsyncWebSocketMessageBuffer(); AsyncWebSocketMessageBuffer(size_t size); - AsyncWebSocketMessageBuffer(uint8_t * data, size_t size); - AsyncWebSocketMessageBuffer(const AsyncWebSocketMessageBuffer &); - AsyncWebSocketMessageBuffer(AsyncWebSocketMessageBuffer &&); + AsyncWebSocketMessageBuffer(uint8_t *data, size_t size); ~AsyncWebSocketMessageBuffer(); - void operator ++(int i) { (void)i; _count++; } - void operator --(int i) { (void)i; if (_count > 0) { _count--; } ; } bool reserve(size_t size); - void lock() { _lock = true; } - void unlock() { _lock = false; } - uint8_t * get() { return _data; } + uint8_t *get() { return _data.get(); } size_t length() { return _len; } - uint32_t count() { return _count; } - bool canDelete() { return (!_count && !_lock); } - - friend AsyncWebSocket; - }; class AsyncWebSocketMessage { @@ -148,9 +136,9 @@ class AsyncWebSocketMultiMessage: public AsyncWebSocketMessage { size_t _sent; size_t _ack; size_t _acked; - AsyncWebSocketMessageBuffer *_WSbuffer; + std::shared_ptr _WSbuffer; public: - AsyncWebSocketMultiMessage(AsyncWebSocketMessageBuffer * buffer, uint8_t opcode=WS_TEXT, bool mask=false); + AsyncWebSocketMultiMessage(std::shared_ptr buffer, uint8_t opcode=WS_TEXT, bool mask=false); virtual ~AsyncWebSocketMultiMessage() override; virtual bool betweenFrames() const override { return _acked == _ack; } virtual void ack(size_t len, uint32_t time) override ; @@ -178,7 +166,7 @@ class PolymorphMessageContainer new (&basicMessage) AsyncWebSocketBasicMessage{data, len, opcode, mask}; } - PolymorphMessageContainer(AsyncWebSocketMessageBuffer *buffer, uint8_t opcode=WS_TEXT, bool mask=false) : + PolymorphMessageContainer(std::shared_ptr buffer, uint8_t opcode=WS_TEXT, bool mask=false) : type{Type::Multi} { new (&multiMessage) AsyncWebSocketMultiMessage{buffer, opcode, mask}; @@ -234,7 +222,7 @@ class AsyncWebSocketClient { void _queueControl(uint8_t opcode, uint8_t *data=NULL, size_t len=0, bool mask=false); void _queueMessage(const char *data, size_t len, uint8_t opcode=WS_TEXT, bool mask=false); - void _queueMessage(AsyncWebSocketMessageBuffer *buffer, uint8_t opcode=WS_TEXT, bool mask=false); + void _queueMessage(std::shared_ptr buffer, uint8_t opcode=WS_TEXT, bool mask=false); void _runQueue(); void _clearQueue(); @@ -270,7 +258,7 @@ class AsyncWebSocketClient { //data packets void message(const char *data, size_t len, uint8_t opcode=WS_TEXT, bool mask=false) { _queueMessage(data, len, opcode, mask); } - void message(AsyncWebSocketMessageBuffer *buffer, uint8_t opcode=WS_TEXT, bool mask=false) { _queueMessage(buffer, opcode, mask); } + void message(std::shared_ptr buffer, uint8_t opcode=WS_TEXT, bool mask=false) { _queueMessage(buffer, opcode, mask); } bool queueIsFull() const; size_t queueLen() const; @@ -284,7 +272,7 @@ class AsyncWebSocketClient { void text(char * message); void text(const String &message); void text(const __FlashStringHelper *data); - void text(AsyncWebSocketMessageBuffer *buffer); + void text(std::shared_ptr buffer); void binary(const char * message, size_t len); void binary(const char * message); @@ -292,7 +280,7 @@ class AsyncWebSocketClient { void binary(char * message); void binary(const String &message); void binary(const __FlashStringHelper *data, size_t len); - void binary(AsyncWebSocketMessageBuffer *buffer); + void binary(std::shared_ptr buffer); bool canSend() const; @@ -352,7 +340,7 @@ class AsyncWebSocket: public AsyncWebHandler { void textAll(char * message); void textAll(const String &message); void textAll(const __FlashStringHelper *message); // need to convert - void textAll(AsyncWebSocketMessageBuffer *buffer); + void textAll(std::shared_ptr buffer); void binary(uint32_t id, const char * message, size_t len); void binary(uint32_t id, const char * message); @@ -367,11 +355,11 @@ class AsyncWebSocket: public AsyncWebHandler { void binaryAll(char * message); void binaryAll(const String &message); void binaryAll(const __FlashStringHelper *message, size_t len); - void binaryAll(AsyncWebSocketMessageBuffer *buffer); + void binaryAll(std::shared_ptr buffer); void message(uint32_t id, const char *data, size_t len, uint8_t opcode=WS_TEXT, bool mask=false); - void message(uint32_t id, AsyncWebSocketMessageBuffer *buffer, uint8_t opcode=WS_TEXT, bool mask=false); - void messageAll(AsyncWebSocketMessageBuffer *buffer, uint8_t opcode=WS_TEXT, bool mask=false); + void message(uint32_t id, std::shared_ptr buffer, uint8_t opcode=WS_TEXT, bool mask=false); + void messageAll(std::shared_ptr buffer, uint8_t opcode=WS_TEXT, bool mask=false); size_t printf(uint32_t id, const char *format, ...) __attribute__ ((format (printf, 3, 4))); size_t printfAll(const char *format, ...) __attribute__ ((format (printf, 2, 3))); @@ -400,9 +388,9 @@ class AsyncWebSocket: public AsyncWebHandler { // messagebuffer functions/objects. - AsyncWebSocketMessageBuffer * makeBuffer(size_t size = 0); - AsyncWebSocketMessageBuffer * makeBuffer(uint8_t * data, size_t size); - std::list _buffers; + std::shared_ptr makeBuffer(size_t size = 0); + std::shared_ptr makeBuffer(uint8_t * data, size_t size); + std::list> _buffers; void _cleanBuffers(); const std::list &getClients() const { return _clients; } From 9509bdcd66c59c7f715774a9434eb39c727039d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Villac=C3=ADs=20Lasso?= Date: Sat, 2 Jan 2021 17:43:33 -0500 Subject: [PATCH 101/551] Compare task handles instead of opaque undocumented symbols Based on commit 9b98550f64000b937db9567b69e1275feccf1f0f of dumbfixes branch of 0xFEEDC0DE64 fork of ESPAsyncWebServer. The AsyncWebLock class tries to prevent self-deadlock by comparing the current task with the task currently holding the lock (if any). Use documented task handle values and APIs instead of grabbing undocumented external symbols for this. --- src/AsyncWebSynchronization.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/AsyncWebSynchronization.h b/src/AsyncWebSynchronization.h index 0f76815b4..0591ea181 100644 --- a/src/AsyncWebSynchronization.h +++ b/src/AsyncWebSynchronization.h @@ -44,7 +44,7 @@ class AsyncWebLock { private: SemaphoreHandle_t _lock; - mutable void *_lockedBy; + mutable TaskHandle_t _lockedBy{}; public: AsyncWebLock() { @@ -61,10 +61,10 @@ class AsyncWebLock } bool lock() const { - extern void *pxCurrentTCB; - if (_lockedBy != pxCurrentTCB) { + const auto currentTask = xTaskGetCurrentTaskHandle(); + if (_lockedBy != currentTask) { xSemaphoreTake(_lock, portMAX_DELAY); - _lockedBy = pxCurrentTCB; + _lockedBy = currentTask; return true; } return false; From 1e8d96631df016113ade2dd446260d1f3df17ee7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Villac=C3=ADs=20Lasso?= Date: Sat, 2 Jan 2021 17:54:39 -0500 Subject: [PATCH 102/551] Unlock websocket client before closing on ACK Fraction of commit f7c5c452df5b0918357fc98003aafde9e18304f9 of dumbfixes branch of 0xFEEDC0DE64 fork of ESPAsyncWebServer. Split off for clarity. --- src/AsyncWebSocket.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/AsyncWebSocket.cpp b/src/AsyncWebSocket.cpp index 1d165c77f..6bee38bb2 100644 --- a/src/AsyncWebSocket.cpp +++ b/src/AsyncWebSocket.cpp @@ -495,6 +495,7 @@ void AsyncWebSocketClient::_onAck(size_t len, uint32_t time){ if(_status == WS_DISCONNECTING && head.opcode() == WS_DISCONNECT){ _controlQueue.pop_front(); _status = WS_DISCONNECTED; + l.unlock(); _client->close(true); return; } From 04672f45729599538c1ed10eb97edd12d55ee46e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Villac=C3=ADs=20Lasso?= Date: Sat, 2 Jan 2021 18:06:19 -0500 Subject: [PATCH 103/551] Code formatting plus queue unlocking change Based on commit f7c5c452df5b0918357fc98003aafde9e18304f9 of dumbfixes branch of 0xFEEDC0DE64 fork of ESPAsyncWebServer. In addition to indentation changes, now the queues are no longer unlocked before attempting to write the messages to the socket. --- src/AsyncWebSocket.cpp | 15 ++++++----- src/AsyncWebSynchronization.h | 51 ++++++++++++++++++----------------- 2 files changed, 35 insertions(+), 31 deletions(-) diff --git a/src/AsyncWebSocket.cpp b/src/AsyncWebSocket.cpp index 6bee38bb2..5a62b4861 100644 --- a/src/AsyncWebSocket.cpp +++ b/src/AsyncWebSocket.cpp @@ -514,13 +514,16 @@ void AsyncWebSocketClient::_onAck(size_t len, uint32_t time){ _runQueue(); } -void AsyncWebSocketClient::_onPoll(){ - if(_client->canSend() && [this](){ AsyncWebLockGuard l(_lock); return !_controlQueue.empty() || !_messageQueue.empty(); }()) +void AsyncWebSocketClient::_onPoll() +{ + AsyncWebLockGuard l(_lock); + if(_client->canSend() && (!_controlQueue.empty() || !_messageQueue.empty())) { + l.unlock(); _runQueue(); - } else if(_keepAlivePeriod > 0 && (millis() - _lastMessageTime) >= _keepAlivePeriod && - [this](){ AsyncWebLockGuard l(_lock); return _controlQueue.empty() && _messageQueue.empty(); }()) + } else if(_keepAlivePeriod > 0 && (millis() - _lastMessageTime) >= _keepAlivePeriod && (_controlQueue.empty() && _messageQueue.empty())) { + l.unlock(); ping((uint8_t *)AWSC_PING_PAYLOAD, AWSC_PING_PAYLOAD_LEN); } } @@ -533,12 +536,12 @@ void AsyncWebSocketClient::_runQueue() if(!_controlQueue.empty() && (_messageQueue.empty() || _messageQueue.front().get().betweenFrames()) && webSocketSendFrameWindow(_client) > (size_t)(_controlQueue.front().len() - 1)) { - l.unlock(); + //l.unlock(); _controlQueue.front().send(_client); } else if (!_messageQueue.empty() && _messageQueue.front().get().betweenFrames() && webSocketSendFrameWindow(_client)) { - l.unlock(); + //l.unlock(); _messageQueue.front().get().send(_client); } } diff --git a/src/AsyncWebSynchronization.h b/src/AsyncWebSynchronization.h index 0591ea181..0ff8ab63b 100644 --- a/src/AsyncWebSynchronization.h +++ b/src/AsyncWebSynchronization.h @@ -43,37 +43,38 @@ class AsyncPlainLock class AsyncWebLock { private: - SemaphoreHandle_t _lock; - mutable TaskHandle_t _lockedBy{}; + SemaphoreHandle_t _lock; + mutable TaskHandle_t _lockedBy{}; public: - AsyncWebLock() { - _lock = xSemaphoreCreateBinary(); - // In this fails, the system is likely that much out of memory that - // we should abort anyways. If assertions are disabled, nothing is lost.. - assert(_lock); - _lockedBy = NULL; - xSemaphoreGive(_lock); - } + AsyncWebLock() + { + _lock = xSemaphoreCreateBinary(); + // In this fails, the system is likely that much out of memory that + // we should abort anyways. If assertions are disabled, nothing is lost.. + assert(_lock); + _lockedBy = NULL; + xSemaphoreGive(_lock); + } - ~AsyncWebLock() { - vSemaphoreDelete(_lock); - } + ~AsyncWebLock() { + vSemaphoreDelete(_lock); + } - bool lock() const { - const auto currentTask = xTaskGetCurrentTaskHandle(); - if (_lockedBy != currentTask) { - xSemaphoreTake(_lock, portMAX_DELAY); - _lockedBy = currentTask; - return true; + bool lock() const { + const auto currentTask = xTaskGetCurrentTaskHandle(); + if (_lockedBy != currentTask) { + xSemaphoreTake(_lock, portMAX_DELAY); + _lockedBy = currentTask; + return true; + } + return false; } - return false; - } - void unlock() const { - _lockedBy = NULL; - xSemaphoreGive(_lock); - } + void unlock() const { + _lockedBy = NULL; + xSemaphoreGive(_lock); + } }; #else From 4963ce9da983e433d938e8b978327f0eac2ddd8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Villac=C3=ADs=20Lasso?= Date: Sat, 2 Jan 2021 20:07:28 -0500 Subject: [PATCH 104/551] Replace entire AsyncWebSocketBuffer infrastructure with std::shared_ptr Based on commit 9172736ac28e7c2f3edd0c56434bc27f578a89b1 of dumbfixes branch of 0xFEEDC0DE64 fork of ESPAsyncWebServer. The entire purpose of having an AsyncWebSocketMessageBuffer is to maintain a shared copy of a buffer sent to multiple clients until all of them finish sending it. This can be replaced with a single message object that contains a shared_ptr to the data being sent. For the single client case, this is equivalent to non-shared buffer. For multiple clients, the shared_ptr will maintain the buffer live until all messages referencing it are destroyed. This simplifies the websocket architecture. --- src/AsyncWebSocket.cpp | 867 ++++++++++++++++------------------------- src/AsyncWebSocket.h | 199 ++-------- 2 files changed, 368 insertions(+), 698 deletions(-) diff --git a/src/AsyncWebSocket.cpp b/src/AsyncWebSocket.cpp index 5a62b4861..58bc45755 100644 --- a/src/AsyncWebSocket.cpp +++ b/src/AsyncWebSocket.cpp @@ -21,6 +21,8 @@ #include "Arduino.h" #include "AsyncWebSocket.h" +#include + #include #ifndef ESP8266 @@ -131,308 +133,129 @@ size_t webSocketSendFrame(AsyncClient *client, bool final, uint8_t opcode, bool } -/* - * AsyncWebSocketMessageBuffer - */ - - - -AsyncWebSocketMessageBuffer::AsyncWebSocketMessageBuffer() - :_data(nullptr) - ,_len(0) -{ - -} - -AsyncWebSocketMessageBuffer::AsyncWebSocketMessageBuffer(uint8_t * data, size_t size) - :_data(nullptr) - ,_len(size) -{ - if (!data) - return; - - _data = std::unique_ptr(new uint8_t[_len + 1]); //std::make_unique(_len + 1); - memcpy(_data.get(), data, _len); - _data[_len] = 0; -} - - -AsyncWebSocketMessageBuffer::AsyncWebSocketMessageBuffer(size_t size) - :_data(nullptr) - ,_len(size) -{ - _data = std::unique_ptr(new uint8_t[_len + 1]); //std::make_unique(_len + 1); - _data[_len] = 0; -} - -AsyncWebSocketMessageBuffer::~AsyncWebSocketMessageBuffer() -{ -} - -bool AsyncWebSocketMessageBuffer::reserve(size_t size) -{ - _len = size; - - _data = std::unique_ptr(new uint8_t[_len + 1]); //std::make_unique(_len + 1); - _data[_len] = 0; - - return true; -} - - /* * Control Frame */ class AsyncWebSocketControl { - private: +private: uint8_t _opcode; uint8_t *_data; size_t _len; bool _mask; bool _finished; - public: - AsyncWebSocketControl(uint8_t opcode, uint8_t *data=NULL, size_t len=0, bool mask=false) + +public: + AsyncWebSocketControl(uint8_t opcode, const uint8_t *data=NULL, size_t len=0, bool mask=false) :_opcode(opcode) ,_len(len) ,_mask(len && mask) ,_finished(false) - { - if(data == NULL) - _len = 0; - if(_len){ - if(_len > 125) - _len = 125; - _data = (uint8_t*)malloc(_len); - if(_data == NULL) - _len = 0; - else memcpy(_data, data, len); - } else _data = NULL; + { + if (data == NULL) + _len = 0; + if (_len) + { + if (_len > 125) + _len = 125; + + _data = (uint8_t*)malloc(_len); + + if(_data == NULL) + _len = 0; + else + memcpy(_data, data, len); + } + else + _data = NULL; } - virtual ~AsyncWebSocketControl(){ - if(_data != NULL) - free(_data); + + virtual ~AsyncWebSocketControl() + { + if (_data != NULL) + free(_data); } + virtual bool finished() const { return _finished; } uint8_t opcode(){ return _opcode; } uint8_t len(){ return _len + 2; } size_t send(AsyncClient *client){ - _finished = true; - return webSocketSendFrame(client, true, _opcode & 0x0F, _mask, _data, _len); + _finished = true; + return webSocketSendFrame(client, true, _opcode & 0x0F, _mask, _data, _len); } }; + /* - * Basic Buffered Message + * AsyncWebSocketMessage Message */ -AsyncWebSocketBasicMessage::AsyncWebSocketBasicMessage(const char * data, size_t len, uint8_t opcode, bool mask) - :_len(len) - ,_sent(0) - ,_ack(0) - ,_acked(0) -{ - _opcode = opcode & 0x07; - _mask = mask; - _data = (uint8_t*)malloc(_len+1); - // Serial.println("MSG alloc"); - if(_data == NULL){ - _len = 0; - _status = WS_MSG_ERROR; - } else { - _status = WS_MSG_SENDING; - memcpy(_data, data, _len); - _data[_len] = 0; - } -} -AsyncWebSocketBasicMessage::AsyncWebSocketBasicMessage(uint8_t opcode, bool mask) - :_len(0) - ,_sent(0) - ,_ack(0) - ,_acked(0) - ,_data(NULL) +AsyncWebSocketMessage::AsyncWebSocketMessage(std::shared_ptr> buffer, uint8_t opcode, bool mask) : + _WSbuffer{buffer}, + _opcode(opcode & 0x07), + _mask{mask}, + _status{_WSbuffer?WS_MSG_SENDING:WS_MSG_ERROR} { - _opcode = opcode & 0x07; - _mask = mask; - -} +} - -AsyncWebSocketBasicMessage::~AsyncWebSocketBasicMessage() { - if(_data != NULL) { - // Serial.println("MSG free"); - free(_data); - } -} - - void AsyncWebSocketBasicMessage::ack(size_t len, uint32_t time) { - (void)time; - _acked += len; - // Serial.printf("ACK %u = %u | %u = %u\n", _sent, _len, _acked, _ack); - if(_sent == _len && _acked == _ack){ - // Serial.println("ACK end"); - _status = WS_MSG_SENT; - } +void AsyncWebSocketMessage::ack(size_t len, uint32_t time) +{ + (void)time; + _acked += len; + if (_sent >= _WSbuffer->size() && _acked >= _ack) + { + _status = WS_MSG_SENT; + } + //ets_printf("A: %u\n", len); } - size_t AsyncWebSocketBasicMessage::send(AsyncClient *client) { - if(_status != WS_MSG_SENDING){ - // Serial.println("MS 1"); - return 0; - } - if(_acked < _ack){ - // Serial.println("MS 2"); - return 0; - } - if(_sent == _len){ - // Serial.println("MS 3"); - _status = WS_MSG_SENT; - return 0; - } - if(_sent > _len){ - // Serial.println("MS 4"); - _status = WS_MSG_ERROR; - return 0; - } - size_t toSend = _len - _sent; - size_t window = webSocketSendFrameWindow(client); - // Serial.printf("Send %u %u %u\n", _len, _sent, toSend); - if(window < toSend) { - toSend = window; - } - - _sent += toSend; - _ack += toSend + ((toSend < 126)?2:4) + (_mask * 4); - - bool final = (_sent == _len); - uint8_t* dPtr = (uint8_t*)(_data + (_sent - toSend)); - uint8_t opCode = (toSend && _sent == toSend)?_opcode:(uint8_t)WS_CONTINUATION; - - size_t sent = webSocketSendFrame(client, final, opCode, _mask, dPtr, toSend); - _status = WS_MSG_SENDING; - if(toSend && sent != toSend){ - size_t delta = (toSend - sent); - // Serial.printf("\ns:%u a:%u d:%u\n", _sent, _ack, delta); - _sent -= delta; - _ack -= delta + ((delta < 126)?2:4) + (_mask * 4); - // Serial.printf("s:%u a:%u\n", _sent, _ack); - if (!sent) { +size_t AsyncWebSocketMessage::send(AsyncClient *client) +{ + if (_status != WS_MSG_SENDING) + return 0; + if (_acked < _ack){ + return 0; + } + if (_sent == _WSbuffer->size()) + { + if(_acked == _ack) + _status = WS_MSG_SENT; + return 0; + } + if (_sent > _WSbuffer->size()) + { _status = WS_MSG_ERROR; - } - } - return sent; -} + //ets_printf("E: %u > %u\n", _sent, _WSbuffer->length()); + return 0; + } -// bool AsyncWebSocketBasicMessage::reserve(size_t size) { -// if (size) { -// _data = (uint8_t*)malloc(size +1); -// if (_data) { -// memset(_data, 0, size); -// _len = size; -// _status = WS_MSG_SENDING; -// return true; -// } -// } -// return false; -// } + size_t toSend = _WSbuffer->size() - _sent; + size_t window = webSocketSendFrameWindow(client); + if (window < toSend) { + toSend = window; + } -/* - * AsyncWebSocketMultiMessage Message - */ + _sent += toSend; + _ack += toSend + ((toSend < 126)?2:4) + (_mask * 4); + //ets_printf("W: %u %u\n", _sent - toSend, toSend); -AsyncWebSocketMultiMessage::AsyncWebSocketMultiMessage(std::shared_ptr buffer, uint8_t opcode, bool mask) - :_len(0) - ,_sent(0) - ,_ack(0) - ,_acked(0) - ,_WSbuffer(nullptr) -{ - _opcode = opcode & 0x07; - _mask = mask; + bool final = (_sent == _WSbuffer->size()); + uint8_t* dPtr = (uint8_t*)(_WSbuffer->data() + (_sent - toSend)); + uint8_t opCode = (toSend && _sent == toSend)?_opcode:(uint8_t)WS_CONTINUATION; - if (buffer) { - _WSbuffer = buffer; - _data = buffer->get(); - _len = buffer->length(); + size_t sent = webSocketSendFrame(client, final, opCode, _mask, dPtr, toSend); _status = WS_MSG_SENDING; - //ets_printf("M: %u\n", _len); - } else { - // Serial.println("BUFF ERROR"); - _status = WS_MSG_ERROR; - } - -} - - -AsyncWebSocketMultiMessage::~AsyncWebSocketMultiMessage() { -} - - void AsyncWebSocketMultiMessage::ack(size_t len, uint32_t time) { - (void)time; - _acked += len; - // Serial.printf("ACK %u = %u | %u = %u\n", _sent, _len, _acked, _ack); - if(_sent >= _len && _acked >= _ack){ - // Serial.println("ACK end"); - _status = WS_MSG_SENT; - } - //ets_printf("A: %u\n", len); -} - size_t AsyncWebSocketMultiMessage::send(AsyncClient *client) { - if(_status != WS_MSG_SENDING) { - // Serial.println("MS 1"); - return 0; - } - if(_acked < _ack){ - // Serial.println("MS 2"); - return 0; - } - if(_sent == _len){ - // Serial.println("MS 3"); - _status = WS_MSG_SENT; - return 0; - } - if(_sent > _len){ - // Serial.println("MS 4"); - _status = WS_MSG_ERROR; - //ets_printf("E: %u > %u\n", _sent, _len); - return 0; - } - size_t toSend = _len - _sent; - size_t window = webSocketSendFrameWindow(client); - // Serial.printf("Send %u %u %u\n", _len, _sent, toSend); - - if(window < toSend) { - toSend = window; - } - // Serial.printf("s:%u a:%u t:%u\n", _sent, _ack, toSend); - _sent += toSend; - _ack += toSend + ((toSend < 126)?2:4) + (_mask * 4); - - //ets_printf("W: %u %u\n", _sent - toSend, toSend); - - bool final = (_sent == _len); - uint8_t* dPtr = (uint8_t*)(_data + (_sent - toSend)); - uint8_t opCode = (toSend && _sent == toSend)?_opcode:(uint8_t)WS_CONTINUATION; - - size_t sent = webSocketSendFrame(client, final, opCode, _mask, dPtr, toSend); - _status = WS_MSG_SENDING; - if(toSend && sent != toSend){ - //ets_printf("E: %u != %u\n", toSend, sent); - size_t delta = (toSend - sent); - // Serial.printf("\ns:%u a:%u d:%u\n", _sent, _ack, delta); - _sent -= delta; - _ack -= delta + ((delta < 126)?2:4) + (_mask * 4); - // Serial.printf("s:%u a:%u\n", _sent, _ack); - if (!sent) { - _status = WS_MSG_ERROR; - } - } - //ets_printf("S: %u %u\n", _sent, sent); - return sent; + if (toSend && sent != toSend){ + //ets_printf("E: %u != %u\n", toSend, sent); + _sent -= (toSend - sent); + _ack -= (toSend - sent); + } + //ets_printf("S: %u %u\n", _sent, sent); + return sent; } @@ -472,14 +295,13 @@ AsyncWebSocketClient::~AsyncWebSocketClient() _messageQueue.clear(); _controlQueue.clear(); } - _server->_cleanBuffers(); _server->_handleEvent(this, WS_EVT_DISCONNECT, NULL, NULL, 0); } -void AsyncWebSocketClient::_clearQueue(){ - while (!_messageQueue.empty() && _messageQueue.front().get().finished()){ +void AsyncWebSocketClient::_clearQueue() +{ + while (!_messageQueue.empty() && _messageQueue.front().finished()) _messageQueue.pop_front(); - } } void AsyncWebSocketClient::_onAck(size_t len, uint32_t time){ @@ -488,29 +310,28 @@ void AsyncWebSocketClient::_onAck(size_t len, uint32_t time){ { AsyncWebLockGuard l(_lock); - if (!_controlQueue.empty()){ + if (!_controlQueue.empty()) { auto &head = _controlQueue.front(); - if(head.finished()){ + if (head.finished()){ len -= head.len(); - if(_status == WS_DISCONNECTING && head.opcode() == WS_DISCONNECT){ - _controlQueue.pop_front(); - _status = WS_DISCONNECTED; - l.unlock(); - _client->close(true); - return; + if (_status == WS_DISCONNECTING && head.opcode() == WS_DISCONNECT){ + _controlQueue.pop_front(); + _status = WS_DISCONNECTED; + l.unlock(); + _client->close(true); + return; } _controlQueue.pop_front(); } } if(len && !_messageQueue.empty()){ - _messageQueue.front().get().ack(len, time); + _messageQueue.front().ack(len, time); } _clearQueue(); } - _server->_cleanBuffers(); _runQueue(); } @@ -521,7 +342,8 @@ void AsyncWebSocketClient::_onPoll() { l.unlock(); _runQueue(); - } else if(_keepAlivePeriod > 0 && (millis() - _lastMessageTime) >= _keepAlivePeriod && (_controlQueue.empty() && _messageQueue.empty())) + } + else if(_keepAlivePeriod > 0 && (millis() - _lastMessageTime) >= _keepAlivePeriod && (_controlQueue.empty() && _messageQueue.empty())) { l.unlock(); ping((uint8_t *)AWSC_PING_PAYLOAD, AWSC_PING_PAYLOAD_LEN); @@ -534,15 +356,15 @@ void AsyncWebSocketClient::_runQueue() _clearQueue(); - if(!_controlQueue.empty() && (_messageQueue.empty() || _messageQueue.front().get().betweenFrames()) && webSocketSendFrameWindow(_client) > (size_t)(_controlQueue.front().len() - 1)) + if (!_controlQueue.empty() && (_messageQueue.empty() || _messageQueue.front().betweenFrames()) && webSocketSendFrameWindow(_client) > (size_t)(_controlQueue.front().len() - 1)) { //l.unlock(); _controlQueue.front().send(_client); } - else if (!_messageQueue.empty() && _messageQueue.front().get().betweenFrames() && webSocketSendFrameWindow(_client)) + else if (!_messageQueue.empty() && _messageQueue.front().betweenFrames() && webSocketSendFrameWindow(_client)) { //l.unlock(); - _messageQueue.front().get().send(_client); + _messageQueue.front().send(_client); } } @@ -573,7 +395,7 @@ bool AsyncWebSocketClient::canSend() const return size < WS_MAX_QUEUED_MESSAGES; } -void AsyncWebSocketClient::_queueControl(uint8_t opcode, uint8_t *data, size_t len, bool mask) +void AsyncWebSocketClient::_queueControl(uint8_t opcode, const uint8_t *data, size_t len, bool mask) { { AsyncWebLockGuard l(_lock); @@ -584,29 +406,7 @@ void AsyncWebSocketClient::_queueControl(uint8_t opcode, uint8_t *data, size_t l _runQueue(); } -void AsyncWebSocketClient::_queueMessage(const char *data, size_t len, uint8_t opcode, bool mask) -{ - if(_status != WS_CONNECTED) - return; - - { - AsyncWebLockGuard l(_lock); - if (_messageQueue.size() >= WS_MAX_QUEUED_MESSAGES) - { - l.unlock(); - ets_printf("ERROR: Too many messages queued\n"); - } - else - { - _messageQueue.emplace_back(data, len, opcode, mask); - } - } - - if(_client->canSend()) - _runQueue(); -} - -void AsyncWebSocketClient::_queueMessage(std::shared_ptr buffer, uint8_t opcode, bool mask) +void AsyncWebSocketClient::_queueMessage(std::shared_ptr> buffer, uint8_t opcode, bool mask) { if(_status != WS_CONNECTED) return; @@ -653,28 +453,32 @@ void AsyncWebSocketClient::close(uint16_t code, const char * message){ _queueControl(WS_DISCONNECT); } -void AsyncWebSocketClient::ping(uint8_t *data, size_t len){ - if(_status == WS_CONNECTED) - _queueControl(WS_PING, data, len); +void AsyncWebSocketClient::ping(const uint8_t *data, size_t len) +{ + if (_status == WS_CONNECTED) + _queueControl(WS_PING, data, len); } void AsyncWebSocketClient::_onError(int8_t){ //Serial.println("onErr"); } -void AsyncWebSocketClient::_onTimeout(uint32_t time){ - // Serial.println("onTime"); - (void)time; - _client->close(true); +void AsyncWebSocketClient::_onTimeout(uint32_t time) +{ + // Serial.println("onTime"); + (void)time; + _client->close(true); } -void AsyncWebSocketClient::_onDisconnect(){ - // Serial.println("onDis"); - _client = NULL; - _server->_handleDisconnect(this); +void AsyncWebSocketClient::_onDisconnect() +{ + // Serial.println("onDis"); + _client = NULL; + _server->_handleDisconnect(this); } -void AsyncWebSocketClient::_onData(void *pbuf, size_t plen){ +void AsyncWebSocketClient::_onData(void *pbuf, size_t plen) +{ // Serial.println("onData"); _lastMessageTime = millis(); uint8_t *data = (uint8_t*)pbuf; @@ -768,7 +572,8 @@ void AsyncWebSocketClient::_onData(void *pbuf, size_t plen){ } } -size_t AsyncWebSocketClient::printf(const char *format, ...) { +size_t AsyncWebSocketClient::printf(const char *format, ...) +{ va_list arg; va_start(arg, format); char* temp = new char[MAX_PRINTF_LEN]; @@ -799,7 +604,8 @@ size_t AsyncWebSocketClient::printf(const char *format, ...) { } #ifndef ESP32 -size_t AsyncWebSocketClient::printf_P(PGM_P formatP, ...) { +size_t AsyncWebSocketClient::printf_P(PGM_P formatP, ...) +{ va_list arg; va_start(arg, formatP); char* temp = new char[MAX_PRINTF_LEN]; @@ -830,63 +636,96 @@ size_t AsyncWebSocketClient::printf_P(PGM_P formatP, ...) { } #endif -void AsyncWebSocketClient::text(const char * message, size_t len){ - _queueMessage(message, len); +namespace { +std::shared_ptr> makeBuffer(const uint8_t *message, size_t len) +{ + auto buffer = std::make_shared>(len); + std::memcpy(buffer->data(), message, len); + return buffer; } -void AsyncWebSocketClient::text(const char * message){ - text(message, strlen(message)); } -void AsyncWebSocketClient::text(uint8_t * message, size_t len){ - text((const char *)message, len); + +void AsyncWebSocketClient::text(std::shared_ptr> buffer) +{ + _queueMessage(buffer); } -void AsyncWebSocketClient::text(char * message){ - text(message, strlen(message)); + +void AsyncWebSocketClient::text(const uint8_t *message, size_t len) +{ + text(makeBuffer(message, len)); } -void AsyncWebSocketClient::text(const String &message){ - text(message.c_str(), message.length()); + +void AsyncWebSocketClient::text(const char *message, size_t len) +{ + text((const uint8_t *)message, len); } -void AsyncWebSocketClient::text(const __FlashStringHelper *data){ - text(String(data)); + +void AsyncWebSocketClient::text(const char *message) +{ + text(message, strlen(message)); } -void AsyncWebSocketClient::text(std::shared_ptr buffer) + +void AsyncWebSocketClient::text(const String &message) { - _queueMessage(buffer); + text(message.c_str(), message.length()); } -void AsyncWebSocketClient::binary(const char * message, size_t len) +void AsyncWebSocketClient::text(const __FlashStringHelper *data) { - _queueMessage(message, len, WS_BINARY); + PGM_P p = reinterpret_cast(data); + + size_t n = 0; + while (1) + { + if (pgm_read_byte(p+n) == 0) break; + n += 1; + } + + char * message = (char*) malloc(n+1); + if(message) + { + memcpy_P(message, p, n); + message[n] = 0; + text(message, n); + free(message); + } } -void AsyncWebSocketClient::binary(const char * message) + +void AsyncWebSocketClient::binary(std::shared_ptr> buffer) { - binary(message, strlen(message)); + _queueMessage(buffer, WS_BINARY); } -void AsyncWebSocketClient::binary(uint8_t * message, size_t len) + +void AsyncWebSocketClient::binary(const uint8_t *message, size_t len) { - binary((const char *)message, len); + binary(makeBuffer(message, len)); } -void AsyncWebSocketClient::binary(char * message) + +void AsyncWebSocketClient::binary(const char *message, size_t len) +{ + binary((const uint8_t *)message, len); +} + +void AsyncWebSocketClient::binary(const char *message) { binary(message, strlen(message)); } + void AsyncWebSocketClient::binary(const String &message) { binary(message.c_str(), message.length()); } + void AsyncWebSocketClient::binary(const __FlashStringHelper *data, size_t len) { PGM_P p = reinterpret_cast(data); - char * message = (char*) malloc(len); - if(message) { + char *message = (char*) malloc(len); + if (message) { memcpy_P(message, p, len); binary(message, len); free(message); } } -void AsyncWebSocketClient::binary(std::shared_ptr buffer) -{ - _queueMessage(buffer, WS_BINARY); -} IPAddress AsyncWebSocketClient::remoteIP() const { @@ -968,114 +807,184 @@ AsyncWebSocketClient * AsyncWebSocket::client(uint32_t id){ } -void AsyncWebSocket::close(uint32_t id, uint16_t code, const char * message){ - AsyncWebSocketClient *c = client(id); - if (c) - c->close(code, message); +void AsyncWebSocket::close(uint32_t id, uint16_t code, const char * message) +{ + if (AsyncWebSocketClient *c = client(id)) + c->close(code, message); } void AsyncWebSocket::closeAll(uint16_t code, const char * message) { - for(auto& c: _clients) - { - if(c.status() == WS_CONNECTED) - c.close(code, message); - } + for (auto &c : _clients) + { + if (c.status() == WS_CONNECTED) + c.close(code, message); + } } void AsyncWebSocket::cleanupClients(uint16_t maxClients) { - if (count() > maxClients){ - _clients.front().close(); - } + if (count() > maxClients) { + _clients.front().close(); + } } -void AsyncWebSocket::ping(uint32_t id, uint8_t *data, size_t len) +void AsyncWebSocket::ping(uint32_t id, const uint8_t *data, size_t len) { - AsyncWebSocketClient * c = client(id); - if(c) - c->ping(data, len); + if (AsyncWebSocketClient * c = client(id)) + c->ping(data, len); } -void AsyncWebSocket::pingAll(uint8_t *data, size_t len) +void AsyncWebSocket::pingAll(const uint8_t *data, size_t len) { - for(auto& c: _clients){ - if(c.status() == WS_CONNECTED) - c.ping(data, len); - } + for (auto &c : _clients) { + if (c.status() == WS_CONNECTED) + c.ping(data, len); + } } -void AsyncWebSocket::text(uint32_t id, const char * message, size_t len) +void AsyncWebSocket::text(uint32_t id, const uint8_t *message, size_t len) { - AsyncWebSocketClient *c = client(id); - if(c) - c->text(message, len); + if (AsyncWebSocketClient * c = client(id)) + c->text(makeBuffer(message, len)); } - -void AsyncWebSocket::textAll(std::shared_ptr buffer) +void AsyncWebSocket::text(uint32_t id, const char *message, size_t len) { - if (!buffer) - return; + text(id, (const uint8_t *)message, len); +} +void AsyncWebSocket::text(uint32_t id, const char * message) +{ + text(id, message, strlen(message)); +} +void AsyncWebSocket::text(uint32_t id, const String &message) +{ + text(id, message.c_str(), message.length()); +} +void AsyncWebSocket::text(uint32_t id, const __FlashStringHelper *data) +{ + PGM_P p = reinterpret_cast(data); - for(auto &c : _clients) - if (c.status() == WS_CONNECTED) - c.text(buffer); + size_t n = 0; + while (1) + { + if (pgm_read_byte(p+n) == 0) break; + n += 1; + } - _cleanBuffers(); + char * message = (char*) malloc(n+1); + if(message) + { + memcpy_P(message, p, n); + message[n] = 0; + text(id, message, n); + free(message); + } } - +void AsyncWebSocket::textAll(std::shared_ptr> buffer) +{ + for (auto &c : _clients) + if (c.status() == WS_CONNECTED) + c.text(buffer); +} +void AsyncWebSocket::textAll(const uint8_t *message, size_t len) +{ + textAll(makeBuffer(message, len)); +} void AsyncWebSocket::textAll(const char * message, size_t len) { - std::shared_ptr WSBuffer = makeBuffer((uint8_t *)message, len); - textAll(WSBuffer); + textAll((const uint8_t *)message, len); } - -void AsyncWebSocket::binary(uint32_t id, const char * message, size_t len) +void AsyncWebSocket::textAll(const char *message) { - AsyncWebSocketClient * c = client(id); - if(c) - c->binary(message, len); + textAll(message, strlen(message)); } +void AsyncWebSocket::textAll(const String &message) +{ + textAll(message.c_str(), message.length()); +} +void AsyncWebSocket::textAll(const __FlashStringHelper *data) +{ + PGM_P p = reinterpret_cast(data); -void AsyncWebSocket::binaryAll(const char * message, size_t len){ - std::shared_ptr buffer = makeBuffer((uint8_t *)message, len); - binaryAll(buffer); + size_t n = 0; + while (1) + { + if (pgm_read_byte(p+n) == 0) break; + n += 1; + } + + char *message = (char*)malloc(n+1); + if(message) + { + memcpy_P(message, p, n); + message[n] = 0; + textAll(message, n); + free(message); + } } -void AsyncWebSocket::binaryAll(std::shared_ptr buffer) +void AsyncWebSocket::binary(uint32_t id, const uint8_t *message, size_t len) { - if (!buffer) - return; + if (AsyncWebSocketClient * c = client(id)) + c->binary(makeBuffer(message, len)); +} +void AsyncWebSocket::binary(uint32_t id, const char * message, size_t len) +{ + binary(id, (const uint8_t *)message, len); +} +void AsyncWebSocket::binary(uint32_t id, const char * message) +{ + binary(id, message, strlen(message)); +} +void AsyncWebSocket::binary(uint32_t id, const String &message) +{ + binary(id, message.c_str(), message.length()); +} +void AsyncWebSocket::binary(uint32_t id, const __FlashStringHelper *data, size_t len) +{ + PGM_P p = reinterpret_cast(data); + char *message = (char*) malloc(len); + if (message) { + memcpy_P(message, p, len); + binary(id, message, len); + free(message); + } +} +void AsyncWebSocket::binaryAll(std::shared_ptr> buffer) +{ for (auto &c : _clients) if (c.status() == WS_CONNECTED) c.binary(buffer); - - _cleanBuffers(); } -void AsyncWebSocket::message(uint32_t id, const char *data, size_t len, uint8_t opcode, bool mask) +void AsyncWebSocket::binaryAll(const uint8_t *message, size_t len) { - AsyncWebSocketClient *c = client(id); - if (c) - c->message(data, len, opcode, mask); + binaryAll(makeBuffer(message, len)); } -void AsyncWebSocket::message(uint32_t id, std::shared_ptr buffer, uint8_t opcode, bool mask) +void AsyncWebSocket::binaryAll(const char *message, size_t len) { - AsyncWebSocketClient *c = client(id); - if (c) - c->message(buffer, opcode, mask); + binaryAll((const uint8_t *)message, len); } - -void AsyncWebSocket::messageAll(std::shared_ptr buffer, uint8_t opcode, bool mask) +void AsyncWebSocket::binaryAll(const char *message) { - for (auto &c : _clients) - if (c.status() == WS_CONNECTED) - c.message(buffer, opcode, mask); - - _cleanBuffers(); + binaryAll(message, strlen(message)); +} +void AsyncWebSocket::binaryAll(const String &message) +{ + binaryAll(message.c_str(), message.length()); +} +void AsyncWebSocket::binaryAll(const __FlashStringHelper *data, size_t len) +{ + PGM_P p = reinterpret_cast(data); + char * message = (char*) malloc(len); + if(message) { + memcpy_P(message, p, len); + binaryAll(message, len); + free(message); + } } size_t AsyncWebSocket::printf(uint32_t id, const char *format, ...){ @@ -1094,7 +1003,7 @@ size_t AsyncWebSocket::printfAll(const char *format, ...) { va_list arg; char* temp = new char[MAX_PRINTF_LEN]; - if(!temp){ + if (!temp) { return 0; } va_start(arg, format); @@ -1102,10 +1011,10 @@ size_t AsyncWebSocket::printfAll(const char *format, ...) va_end(arg); delete[] temp; - std::shared_ptr buffer = makeBuffer(len); + std::shared_ptr> buffer = std::make_shared>(len); va_start(arg, format); - vsnprintf( (char *)buffer->get(), len + 1, format, arg); + vsnprintf( (char *)buffer->data(), len + 1, format, arg); va_end(arg); textAll(buffer); @@ -1126,10 +1035,11 @@ size_t AsyncWebSocket::printf_P(uint32_t id, PGM_P formatP, ...){ } #endif -size_t AsyncWebSocket::printfAll_P(PGM_P formatP, ...) { +size_t AsyncWebSocket::printfAll_P(PGM_P formatP, ...) +{ va_list arg; char* temp = new char[MAX_PRINTF_LEN]; - if(!temp){ + if (!temp) { return 0; } va_start(arg, formatP); @@ -1137,106 +1047,16 @@ size_t AsyncWebSocket::printfAll_P(PGM_P formatP, ...) { va_end(arg); delete[] temp; - std::shared_ptr buffer = makeBuffer(len + 1); + std::shared_ptr> buffer = std::make_shared>(len + 1); va_start(arg, formatP); - vsnprintf_P((char *)buffer->get(), len + 1, formatP, arg); + vsnprintf_P((char *)buffer->data(), len + 1, formatP, arg); va_end(arg); textAll(buffer); return len; } -void AsyncWebSocket::text(uint32_t id, const char * message) -{ - text(id, message, strlen(message)); -} -void AsyncWebSocket::text(uint32_t id, uint8_t * message, size_t len) -{ - text(id, (const char *)message, len); -} -void AsyncWebSocket::text(uint32_t id, char * message) -{ - text(id, message, strlen(message)); -} -void AsyncWebSocket::text(uint32_t id, const String &message) -{ - text(id, message.c_str(), message.length()); -} -void AsyncWebSocket::text(uint32_t id, const __FlashStringHelper *message) -{ - AsyncWebSocketClient * c = client(id); - if(c != NULL) - c->text(message); -} -void AsyncWebSocket::textAll(const char * message) -{ - textAll(message, strlen(message)); -} -void AsyncWebSocket::textAll(uint8_t * message, size_t len) -{ - textAll((const char *)message, len); -} -void AsyncWebSocket::textAll(char * message) -{ - textAll(message, strlen(message)); -} -void AsyncWebSocket::textAll(const String &message) -{ - textAll(message.c_str(), message.length()); -} -void AsyncWebSocket::textAll(const __FlashStringHelper *message) -{ - for (auto& c : _clients) - if (c.status() == WS_CONNECTED) - c.text(message); -} -void AsyncWebSocket::binary(uint32_t id, const char * message) -{ - binary(id, message, strlen(message)); -} -void AsyncWebSocket::binary(uint32_t id, uint8_t * message, size_t len) -{ - binary(id, (const char *)message, len); -} -void AsyncWebSocket::binary(uint32_t id, char * message) -{ - binary(id, message, strlen(message)); -} -void AsyncWebSocket::binary(uint32_t id, const String &message) -{ - binary(id, message.c_str(), message.length()); -} -void AsyncWebSocket::binary(uint32_t id, const __FlashStringHelper *message, size_t len) -{ - AsyncWebSocketClient * c = client(id); - if (c != NULL) - c-> binary(message, len); -} -void AsyncWebSocket::binaryAll(const char * message) -{ - binaryAll(message, strlen(message)); -} -void AsyncWebSocket::binaryAll(uint8_t * message, size_t len) -{ - binaryAll((const char *)message, len); -} -void AsyncWebSocket::binaryAll(char * message) -{ - binaryAll(message, strlen(message)); -} -void AsyncWebSocket::binaryAll(const String &message) -{ - binaryAll(message.c_str(), message.length()); -} -void AsyncWebSocket::binaryAll(const __FlashStringHelper *message, size_t len) -{ - for (auto& c : _clients) { - if (c.status() == WS_CONNECTED) - c.binary(message, len); - } -} - const char __WS_STR_CONNECTION[] PROGMEM = { "Connection" }; const char __WS_STR_UPGRADE[] PROGMEM = { "Upgrade" }; const char __WS_STR_ORIGIN[] PROGMEM = { "Origin" }; @@ -1306,41 +1126,6 @@ void AsyncWebSocket::handleRequest(AsyncWebServerRequest *request) request->send(response); } -std::shared_ptr AsyncWebSocket::makeBuffer(size_t size) -{ - std::shared_ptr buffer = std::make_shared(size); - - { - AsyncWebLockGuard l(_lock); - _buffers.emplace_back(buffer); - } - - return buffer; -} - -std::shared_ptr AsyncWebSocket::makeBuffer(uint8_t * data, size_t size) -{ - std::shared_ptr buffer = std::make_shared(data, size); - - { - AsyncWebLockGuard l(_lock); - _buffers.emplace_back(buffer); - } - - return buffer; -} - -void AsyncWebSocket::_cleanBuffers() -{ - AsyncWebLockGuard l(_lock); - for (auto iter = std::begin(_buffers); iter != std::end(_buffers);){ - if(iter->lock()) - iter++; - else - iter = _buffers.erase(iter); - } -} - /* * Response to Web Socket request - sends the authorization and detaches the TCP Client from the web server * Authentication code from https://github.com/Links2004/arduinoWebSockets/blob/master/src/WebSockets.cpp#L480 diff --git a/src/AsyncWebSocket.h b/src/AsyncWebSocket.h index 3d24e235c..3b4e0f7a4 100644 --- a/src/AsyncWebSocket.h +++ b/src/AsyncWebSocket.h @@ -84,122 +84,25 @@ typedef enum { WS_CONTINUATION, WS_TEXT, WS_BINARY, WS_DISCONNECT = 0x08, WS_PIN typedef enum { WS_MSG_SENDING, WS_MSG_SENT, WS_MSG_ERROR } AwsMessageStatus; typedef enum { WS_EVT_CONNECT, WS_EVT_DISCONNECT, WS_EVT_PONG, WS_EVT_ERROR, WS_EVT_DATA } AwsEventType; -class AsyncWebSocketMessageBuffer { - private: - std::unique_ptr _data; - size_t _len{}; - - public: - AsyncWebSocketMessageBuffer(); - AsyncWebSocketMessageBuffer(size_t size); - AsyncWebSocketMessageBuffer(uint8_t *data, size_t size); - ~AsyncWebSocketMessageBuffer(); - bool reserve(size_t size); - uint8_t *get() { return _data.get(); } - size_t length() { return _len; } -}; - -class AsyncWebSocketMessage { - protected: - uint8_t _opcode; - bool _mask; - AwsMessageStatus _status; - public: - AsyncWebSocketMessage():_opcode(WS_TEXT),_mask(false),_status(WS_MSG_ERROR){} - virtual ~AsyncWebSocketMessage(){} - virtual void ack(size_t len __attribute__((unused)), uint32_t time __attribute__((unused))){} - virtual size_t send(AsyncClient *client __attribute__((unused))){ return 0; } - virtual bool finished(){ return _status != WS_MSG_SENDING; } - virtual bool betweenFrames() const { return false; } -}; - -class AsyncWebSocketBasicMessage: public AsyncWebSocketMessage { - private: - size_t _len; - size_t _sent; - size_t _ack; - size_t _acked; - uint8_t * _data; -public: - AsyncWebSocketBasicMessage(const char * data, size_t len, uint8_t opcode=WS_TEXT, bool mask=false); - AsyncWebSocketBasicMessage(uint8_t opcode=WS_TEXT, bool mask=false); - virtual ~AsyncWebSocketBasicMessage() override; - virtual bool betweenFrames() const override { return _acked == _ack; } - virtual void ack(size_t len, uint32_t time) override ; - virtual size_t send(AsyncClient *client) override ; -}; - -class AsyncWebSocketMultiMessage: public AsyncWebSocketMessage { - private: - uint8_t * _data; - size_t _len; - size_t _sent; - size_t _ack; - size_t _acked; - std::shared_ptr _WSbuffer; -public: - AsyncWebSocketMultiMessage(std::shared_ptr buffer, uint8_t opcode=WS_TEXT, bool mask=false); - virtual ~AsyncWebSocketMultiMessage() override; - virtual bool betweenFrames() const override { return _acked == _ack; } - virtual void ack(size_t len, uint32_t time) override ; - virtual size_t send(AsyncClient *client) override ; -}; - -class PolymorphMessageContainer +class AsyncWebSocketMessage { - union { - AsyncWebSocketBasicMessage basicMessage; - AsyncWebSocketMultiMessage multiMessage; - }; - - enum class Type : uint8_t { Basic, Multi }; - const Type type; +private: + std::shared_ptr> _WSbuffer; + uint8_t _opcode{WS_TEXT}; + bool _mask{false}; + AwsMessageStatus _status{WS_MSG_ERROR}; + size_t _sent{}; + size_t _ack{}; + size_t _acked{}; public: - PolymorphMessageContainer() = delete; - PolymorphMessageContainer(const PolymorphMessageContainer &) = delete; - PolymorphMessageContainer &operator=(const PolymorphMessageContainer &) = delete; - - PolymorphMessageContainer(const char *data, size_t len, uint8_t opcode=WS_TEXT, bool mask=false) : - type{Type::Basic} - { - new (&basicMessage) AsyncWebSocketBasicMessage{data, len, opcode, mask}; - } - - PolymorphMessageContainer(std::shared_ptr buffer, uint8_t opcode=WS_TEXT, bool mask=false) : - type{Type::Multi} - { - new (&multiMessage) AsyncWebSocketMultiMessage{buffer, opcode, mask}; - } - - ~PolymorphMessageContainer() - { - switch (type) - { - case Type::Basic: basicMessage.~AsyncWebSocketBasicMessage(); break; - case Type::Multi: multiMessage.~AsyncWebSocketMultiMessage(); break; - } - } + AsyncWebSocketMessage(std::shared_ptr> buffer, uint8_t opcode=WS_TEXT, bool mask=false); - AsyncWebSocketMessage &get() - { - switch (type) - { - case Type::Basic: return basicMessage; - case Type::Multi: return multiMessage; - } - __builtin_unreachable(); - } + bool finished() const { return _status != WS_MSG_SENDING; } + bool betweenFrames() const { return _acked == _ack; } - const AsyncWebSocketMessage &get() const - { - switch (type) - { - case Type::Basic: return basicMessage; - case Type::Multi: return multiMessage; - } - __builtin_unreachable(); - } + void ack(size_t len, uint32_t time); + size_t send(AsyncClient *client); }; class AsyncWebSocketClient { @@ -212,7 +115,7 @@ class AsyncWebSocketClient { AsyncWebLock _lock; std::deque _controlQueue; - std::deque _messageQueue; + std::deque _messageQueue; uint8_t _pstate; AwsFrameInfo _pinfo; @@ -220,9 +123,8 @@ class AsyncWebSocketClient { uint32_t _lastMessageTime; uint32_t _keepAlivePeriod; - void _queueControl(uint8_t opcode, uint8_t *data=NULL, size_t len=0, bool mask=false); - void _queueMessage(const char *data, size_t len, uint8_t opcode=WS_TEXT, bool mask=false); - void _queueMessage(std::shared_ptr buffer, uint8_t opcode=WS_TEXT, bool mask=false); + void _queueControl(uint8_t opcode, const uint8_t *data=NULL, size_t len=0, bool mask=false); + void _queueMessage(std::shared_ptr> buffer, uint8_t opcode=WS_TEXT, bool mask=false); void _runQueue(); void _clearQueue(); @@ -246,7 +148,7 @@ class AsyncWebSocketClient { //control frames void close(uint16_t code=0, const char * message=NULL); - void ping(uint8_t *data=NULL, size_t len=0); + void ping(const uint8_t *data=NULL, size_t len=0); //set auto-ping period in seconds. disabled if zero (default) void keepAlivePeriod(uint16_t seconds){ @@ -257,8 +159,7 @@ class AsyncWebSocketClient { } //data packets - void message(const char *data, size_t len, uint8_t opcode=WS_TEXT, bool mask=false) { _queueMessage(data, len, opcode, mask); } - void message(std::shared_ptr buffer, uint8_t opcode=WS_TEXT, bool mask=false) { _queueMessage(buffer, opcode, mask); } + void message(std::shared_ptr> buffer, uint8_t opcode=WS_TEXT, bool mask=false) { _queueMessage(buffer, opcode, mask); } bool queueIsFull() const; size_t queueLen() const; @@ -266,21 +167,20 @@ class AsyncWebSocketClient { #ifndef ESP32 size_t printf_P(PGM_P formatP, ...) __attribute__ ((format (printf, 2, 3))); #endif - void text(const char * message, size_t len); - void text(const char * message); - void text(uint8_t * message, size_t len); - void text(char * message); + + void text(std::shared_ptr> buffer); + void text(const uint8_t *message, size_t len); + void text(const char *message, size_t len); + void text(const char *message); void text(const String &message); - void text(const __FlashStringHelper *data); - void text(std::shared_ptr buffer); + void text(const __FlashStringHelper *message); + void binary(std::shared_ptr> buffer); + void binary(const uint8_t *message, size_t len); void binary(const char * message, size_t len); void binary(const char * message); - void binary(uint8_t * message, size_t len); - void binary(char * message); void binary(const String &message); - void binary(const __FlashStringHelper *data, size_t len); - void binary(std::shared_ptr buffer); + void binary(const __FlashStringHelper *message, size_t len); bool canSend() const; @@ -324,42 +224,34 @@ class AsyncWebSocket: public AsyncWebHandler { void closeAll(uint16_t code=0, const char * message=NULL); void cleanupClients(uint16_t maxClients = DEFAULT_MAX_WS_CLIENTS); - void ping(uint32_t id, uint8_t *data=NULL, size_t len=0); - void pingAll(uint8_t *data=NULL, size_t len=0); // done + void ping(uint32_t id, const uint8_t *data=NULL, size_t len=0); + void pingAll(const uint8_t *data=NULL, size_t len=0); // done - void text(uint32_t id, const char * message, size_t len); - void text(uint32_t id, const char * message); - void text(uint32_t id, uint8_t * message, size_t len); - void text(uint32_t id, char * message); + void text(uint32_t id, const uint8_t * message, size_t len); + void text(uint32_t id, const char *message, size_t len); + void text(uint32_t id, const char *message); void text(uint32_t id, const String &message); void text(uint32_t id, const __FlashStringHelper *message); + void textAll(std::shared_ptr> buffer); + void textAll(const uint8_t *message, size_t len); void textAll(const char * message, size_t len); void textAll(const char * message); - void textAll(uint8_t * message, size_t len); - void textAll(char * message); void textAll(const String &message); void textAll(const __FlashStringHelper *message); // need to convert - void textAll(std::shared_ptr buffer); - void binary(uint32_t id, const char * message, size_t len); - void binary(uint32_t id, const char * message); - void binary(uint32_t id, uint8_t * message, size_t len); - void binary(uint32_t id, char * message); + void binary(uint32_t id, const uint8_t *message, size_t len); + void binary(uint32_t id, const char *message, size_t len); + void binary(uint32_t id, const char *message); void binary(uint32_t id, const String &message); void binary(uint32_t id, const __FlashStringHelper *message, size_t len); - void binaryAll(const char * message, size_t len); - void binaryAll(const char * message); - void binaryAll(uint8_t * message, size_t len); - void binaryAll(char * message); + void binaryAll(std::shared_ptr> buffer); + void binaryAll(const uint8_t *message, size_t len); + void binaryAll(const char *message, size_t len); + void binaryAll(const char *message); void binaryAll(const String &message); void binaryAll(const __FlashStringHelper *message, size_t len); - void binaryAll(std::shared_ptr buffer); - - void message(uint32_t id, const char *data, size_t len, uint8_t opcode=WS_TEXT, bool mask=false); - void message(uint32_t id, std::shared_ptr buffer, uint8_t opcode=WS_TEXT, bool mask=false); - void messageAll(std::shared_ptr buffer, uint8_t opcode=WS_TEXT, bool mask=false); size_t printf(uint32_t id, const char *format, ...) __attribute__ ((format (printf, 3, 4))); size_t printfAll(const char *format, ...) __attribute__ ((format (printf, 2, 3))); @@ -386,13 +278,6 @@ class AsyncWebSocket: public AsyncWebHandler { virtual bool canHandle(AsyncWebServerRequest *request) override final; virtual void handleRequest(AsyncWebServerRequest *request) override final; - - // messagebuffer functions/objects. - std::shared_ptr makeBuffer(size_t size = 0); - std::shared_ptr makeBuffer(uint8_t * data, size_t size); - std::list> _buffers; - void _cleanBuffers(); - const std::list &getClients() const { return _clients; } }; From 7a0d05849a99b34080bddd34a4e8797bf04932b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Villac=C3=ADs=20Lasso?= Date: Sat, 2 Jan 2021 20:15:21 -0500 Subject: [PATCH 105/551] Some code formatting Fraction of commit 6ac642b019dda9bd703a5b9c35e6f1a5a7738aa9 of dumbfixes branch of 0xFEEDC0DE64 fork of ESPAsyncWebServer. Additionally, lock is no longer released between _clearQueue() and _runQueue() in _onAck(). --- src/AsyncWebSocket.cpp | 83 ++++++++++++++++++++++-------------------- 1 file changed, 43 insertions(+), 40 deletions(-) diff --git a/src/AsyncWebSocket.cpp b/src/AsyncWebSocket.cpp index 58bc45755..de81f3e06 100644 --- a/src/AsyncWebSocket.cpp +++ b/src/AsyncWebSocket.cpp @@ -307,31 +307,29 @@ void AsyncWebSocketClient::_clearQueue() void AsyncWebSocketClient::_onAck(size_t len, uint32_t time){ _lastMessageTime = millis(); - { - AsyncWebLockGuard l(_lock); + AsyncWebLockGuard l(_lock); - if (!_controlQueue.empty()) { - auto &head = _controlQueue.front(); - if (head.finished()){ - len -= head.len(); - if (_status == WS_DISCONNECTING && head.opcode() == WS_DISCONNECT){ - _controlQueue.pop_front(); - _status = WS_DISCONNECTED; - l.unlock(); - _client->close(true); - return; - } + if (!_controlQueue.empty()) { + auto &head = _controlQueue.front(); + if (head.finished()){ + len -= head.len(); + if (_status == WS_DISCONNECTING && head.opcode() == WS_DISCONNECT){ _controlQueue.pop_front(); + _status = WS_DISCONNECTED; + l.unlock(); + _client->close(true); + return; } + _controlQueue.pop_front(); } + } - if(len && !_messageQueue.empty()){ - _messageQueue.front().ack(len, time); - } - - _clearQueue(); + if(len && !_messageQueue.empty()){ + _messageQueue.front().ack(len, time); } + _clearQueue(); + _runQueue(); } @@ -428,29 +426,34 @@ void AsyncWebSocketClient::_queueMessage(std::shared_ptr> b _runQueue(); } -void AsyncWebSocketClient::close(uint16_t code, const char * message){ - if(_status != WS_CONNECTED) - return; - if(code){ - uint8_t packetLen = 2; - if(message != NULL){ - size_t mlen = strlen(message); - if(mlen > 123) mlen = 123; - packetLen += mlen; - } - char * buf = (char*)malloc(packetLen); - if(buf != NULL){ - buf[0] = (uint8_t)(code >> 8); - buf[1] = (uint8_t)(code & 0xFF); - if(message != NULL){ - memcpy(buf+2, message, packetLen -2); - } - _queueControl(WS_DISCONNECT, (uint8_t*)buf, packetLen); - free(buf); - return; +void AsyncWebSocketClient::close(uint16_t code, const char * message) +{ + if(_status != WS_CONNECTED) + return; + + if(code) + { + uint8_t packetLen = 2; + if (message != NULL) + { + size_t mlen = strlen(message); + if(mlen > 123) mlen = 123; + packetLen += mlen; + } + char * buf = (char*)malloc(packetLen); + if (buf != NULL) + { + buf[0] = (uint8_t)(code >> 8); + buf[1] = (uint8_t)(code & 0xFF); + if(message != NULL){ + memcpy(buf+2, message, packetLen -2); + } + _queueControl(WS_DISCONNECT, (uint8_t*)buf, packetLen); + free(buf); + return; + } } - } - _queueControl(WS_DISCONNECT); + _queueControl(WS_DISCONNECT); } void AsyncWebSocketClient::ping(const uint8_t *data, size_t len) From b949a6fcd0743a3f36344eb3c8666b63dbe53102 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Villac=C3=ADs=20Lasso?= Date: Sat, 2 Jan 2021 20:52:41 -0500 Subject: [PATCH 106/551] Guard websocket client against invalidation of TCP socket Based on commit c9e4d424d5d007d9901b83d2c7215be7e77c9837 of dumbfixes branch of 0xFEEDC0DE64 fork of ESPAsyncWebServer. When the socket gets disconnected, its corresponding AsyncClient is set to NULL. Several places in the code now have null pointer checks to prevent crashes. Message queue overflow is now an error that triggers socket disconnection. Limit of queued messages is now 16 for ESP32. Disconnected clients are no longer immediately removed from the client queue. Instead the cleanupClients() function prunes all of the disconnected clients. Some code formatting fixes. --- src/AsyncWebSocket.cpp | 260 +++++++++++++++++++++++------------------ src/AsyncWebSocket.h | 5 +- 2 files changed, 148 insertions(+), 117 deletions(-) diff --git a/src/AsyncWebSocket.cpp b/src/AsyncWebSocket.cpp index de81f3e06..ca76bfbcd 100644 --- a/src/AsyncWebSocket.cpp +++ b/src/AsyncWebSocket.cpp @@ -317,7 +317,7 @@ void AsyncWebSocketClient::_onAck(size_t len, uint32_t time){ _controlQueue.pop_front(); _status = WS_DISCONNECTED; l.unlock(); - _client->close(true); + if (_client) _client->close(true); return; } _controlQueue.pop_front(); @@ -335,13 +335,16 @@ void AsyncWebSocketClient::_onAck(size_t len, uint32_t time){ void AsyncWebSocketClient::_onPoll() { + if (!_client) + return; + AsyncWebLockGuard l(_lock); - if(_client->canSend() && (!_controlQueue.empty() || !_messageQueue.empty())) + if (_client->canSend() && (!_controlQueue.empty() || !_messageQueue.empty())) { l.unlock(); _runQueue(); } - else if(_keepAlivePeriod > 0 && (millis() - _lastMessageTime) >= _keepAlivePeriod && (_controlQueue.empty() && _messageQueue.empty())) + else if (_keepAlivePeriod > 0 && (millis() - _lastMessageTime) >= _keepAlivePeriod && (_controlQueue.empty() && _messageQueue.empty())) { l.unlock(); ping((uint8_t *)AWSC_PING_PAYLOAD, AWSC_PING_PAYLOAD_LEN); @@ -350,6 +353,9 @@ void AsyncWebSocketClient::_onPoll() void AsyncWebSocketClient::_runQueue() { + if (!_client) + return; + AsyncWebLockGuard l(_lock); _clearQueue(); @@ -395,12 +401,15 @@ bool AsyncWebSocketClient::canSend() const void AsyncWebSocketClient::_queueControl(uint8_t opcode, const uint8_t *data, size_t len, bool mask) { + if (!_client) + return; + { AsyncWebLockGuard l(_lock); _controlQueue.emplace_back(opcode, data, len, mask); } - if (_client->canSend()) + if (_client && _client->canSend()) _runQueue(); } @@ -409,12 +418,18 @@ void AsyncWebSocketClient::_queueMessage(std::shared_ptr> b if(_status != WS_CONNECTED) return; + if (!_client) + return; + { AsyncWebLockGuard l(_lock); if (_messageQueue.size() >= WS_MAX_QUEUED_MESSAGES) { l.unlock(); - ets_printf("ERROR: Too many messages queued\n"); + ets_printf("AsyncWebSocketClient::_queueMessage: Too many messages queued, closing connection\n"); + _status = WS_DISCONNECTED; + if (_client) _client->close(true); + return; } else { @@ -422,7 +437,7 @@ void AsyncWebSocketClient::_queueMessage(std::shared_ptr> b } } - if(_client->canSend()) + if (_client && _client->canSend()) _runQueue(); } @@ -462,8 +477,9 @@ void AsyncWebSocketClient::ping(const uint8_t *data, size_t len) _queueControl(WS_PING, data, len); } -void AsyncWebSocketClient::_onError(int8_t){ - //Serial.println("onErr"); +void AsyncWebSocketClient::_onError(int8_t) +{ + //Serial.println("onErr"); } void AsyncWebSocketClient::_onTimeout(uint32_t time) @@ -477,7 +493,6 @@ void AsyncWebSocketClient::_onDisconnect() { // Serial.println("onDis"); _client = NULL; - _server->_handleDisconnect(this); } void AsyncWebSocketClient::_onData(void *pbuf, size_t plen) @@ -732,17 +747,17 @@ void AsyncWebSocketClient::binary(const __FlashStringHelper *data, size_t len) IPAddress AsyncWebSocketClient::remoteIP() const { - if (!_client) { + if (!_client) return IPAddress(0U); - } + return _client->remoteIP(); } uint16_t AsyncWebSocketClient::remotePort() const { - if(!_client) { + if(!_client) return 0; - } + return _client->remotePort(); } @@ -774,39 +789,35 @@ AsyncWebSocketClient *AsyncWebSocket::_newClient(AsyncWebServerRequest *request) return &_clients.back(); } -void AsyncWebSocket::_handleDisconnect(AsyncWebSocketClient * client){ - const auto client_id = client->id(); - const auto iter = std::find_if(std::begin(_clients), std::end(_clients), - [client_id](const AsyncWebSocketClient &c){ return c.id() == client_id; }); - if (iter != std::end(_clients)) - _clients.erase(iter); -} - -bool AsyncWebSocket::availableForWriteAll(){ - return std::none_of(std::begin(_clients), std::end(_clients), +bool AsyncWebSocket::availableForWriteAll() +{ + return std::none_of(std::begin(_clients), std::end(_clients), [](const AsyncWebSocketClient &c){ return c.queueIsFull(); }); } -bool AsyncWebSocket::availableForWrite(uint32_t id){ - const auto iter = std::find_if(std::begin(_clients), std::end(_clients), - [id](const AsyncWebSocketClient &c){ return c.id() == id; }); - if (iter == std::end(_clients)) - return true; // don't know why me-no-dev decided like this? - return !iter->queueIsFull(); +bool AsyncWebSocket::availableForWrite(uint32_t id) +{ + const auto iter = std::find_if(std::begin(_clients), std::end(_clients), + [id](const AsyncWebSocketClient &c){ return c.id() == id; }); + if (iter == std::end(_clients)) + return true; + return !iter->queueIsFull(); } -size_t AsyncWebSocket::count() const { - return std::count_if(std::begin(_clients), std::end(_clients), - [](const AsyncWebSocketClient &c){ return c.status() == WS_CONNECTED; }); +size_t AsyncWebSocket::count() const +{ + return std::count_if(std::begin(_clients), std::end(_clients), + [](const AsyncWebSocketClient &c){ return c.status() == WS_CONNECTED; }); } -AsyncWebSocketClient * AsyncWebSocket::client(uint32_t id){ - const auto iter = std::find_if(std::begin(_clients), std::end(_clients), - [id](const AsyncWebSocketClient &c){ return c.id() == id && c.status() == WS_CONNECTED; }); - if (iter == std::end(_clients)) - return nullptr; +AsyncWebSocketClient * AsyncWebSocket::client(uint32_t id) +{ + const auto iter = std::find_if(std::begin(_clients), std::end(_clients), + [id](const AsyncWebSocketClient &c){ return c.id() == id && c.status() == WS_CONNECTED; }); + if (iter == std::end(_clients)) + return nullptr; - return &(*iter); + return &(*iter); } @@ -819,16 +830,21 @@ void AsyncWebSocket::close(uint32_t id, uint16_t code, const char * message) void AsyncWebSocket::closeAll(uint16_t code, const char * message) { for (auto &c : _clients) - { if (c.status() == WS_CONNECTED) c.close(code, message); - } } void AsyncWebSocket::cleanupClients(uint16_t maxClients) { - if (count() > maxClients) { + if (count() > maxClients) _clients.front().close(); + + for (auto iter = std::begin(_clients); iter != std::end(_clients);) + { + if (iter->shouldBeDeleted()) + iter = _clients.erase(iter); + else + iter++; } } @@ -840,10 +856,9 @@ void AsyncWebSocket::ping(uint32_t id, const uint8_t *data, size_t len) void AsyncWebSocket::pingAll(const uint8_t *data, size_t len) { - for (auto &c : _clients) { + for (auto &c : _clients) if (c.status() == WS_CONNECTED) c.ping(data, len); - } } void AsyncWebSocket::text(uint32_t id, const uint8_t *message, size_t len) @@ -868,14 +883,15 @@ void AsyncWebSocket::text(uint32_t id, const __FlashStringHelper *data) PGM_P p = reinterpret_cast(data); size_t n = 0; - while (1) + while (true) { - if (pgm_read_byte(p+n) == 0) break; - n += 1; + if (pgm_read_byte(p+n) == 0) + break; + n += 1; } char * message = (char*) malloc(n+1); - if(message) + if (message) { memcpy_P(message, p, n); message[n] = 0; @@ -929,7 +945,7 @@ void AsyncWebSocket::textAll(const __FlashStringHelper *data) void AsyncWebSocket::binary(uint32_t id, const uint8_t *message, size_t len) { - if (AsyncWebSocketClient * c = client(id)) + if (AsyncWebSocketClient *c = client(id)) c->binary(makeBuffer(message, len)); } void AsyncWebSocket::binary(uint32_t id, const char * message, size_t len) @@ -948,7 +964,8 @@ void AsyncWebSocket::binary(uint32_t id, const __FlashStringHelper *data, size_t { PGM_P p = reinterpret_cast(data); char *message = (char*) malloc(len); - if (message) { + if (message) + { memcpy_P(message, p, len); binary(id, message, len); free(message); @@ -983,7 +1000,8 @@ void AsyncWebSocket::binaryAll(const __FlashStringHelper *data, size_t len) { PGM_P p = reinterpret_cast(data); char * message = (char*) malloc(len); - if(message) { + if(message) + { memcpy_P(message, p, len); binaryAll(message, len); free(message); @@ -991,24 +1009,25 @@ void AsyncWebSocket::binaryAll(const __FlashStringHelper *data, size_t len) } size_t AsyncWebSocket::printf(uint32_t id, const char *format, ...){ - AsyncWebSocketClient * c = client(id); - if(c){ - va_list arg; - va_start(arg, format); - size_t len = c->printf(format, arg); - va_end(arg); - return len; - } - return 0; + AsyncWebSocketClient * c = client(id); + if (c) + { + va_list arg; + va_start(arg, format); + size_t len = c->printf(format, arg); + va_end(arg); + return len; + } + return 0; } size_t AsyncWebSocket::printfAll(const char *format, ...) { va_list arg; - char* temp = new char[MAX_PRINTF_LEN]; - if (!temp) { + char *temp = new char[MAX_PRINTF_LEN]; + if (!temp) return 0; - } + va_start(arg, format); size_t len = vsnprintf(temp, MAX_PRINTF_LEN, format, arg); va_end(arg); @@ -1041,10 +1060,10 @@ size_t AsyncWebSocket::printf_P(uint32_t id, PGM_P formatP, ...){ size_t AsyncWebSocket::printfAll_P(PGM_P formatP, ...) { va_list arg; - char* temp = new char[MAX_PRINTF_LEN]; - if (!temp) { + char *temp = new char[MAX_PRINTF_LEN]; + if (!temp) return 0; - } + va_start(arg, formatP); size_t len = vsnprintf_P(temp, MAX_PRINTF_LEN, formatP, arg); va_end(arg); @@ -1099,11 +1118,13 @@ bool AsyncWebSocket::canHandle(AsyncWebServerRequest *request){ void AsyncWebSocket::handleRequest(AsyncWebServerRequest *request) { - if (!request->hasHeader(WS_STR_VERSION) || !request->hasHeader(WS_STR_KEY)){ + if (!request->hasHeader(WS_STR_VERSION) || !request->hasHeader(WS_STR_KEY)) + { request->send(400); return; } - if ((_username.length() && _password.length()) && !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 (_handshakeHandler != nullptr){ @@ -1113,7 +1134,8 @@ void AsyncWebSocket::handleRequest(AsyncWebServerRequest *request) } } AsyncWebHeader* version = request->getHeader(WS_STR_VERSION); - if (version->value().toInt() != 13){ + if (version->value().toInt() != 13) + { AsyncWebServerResponse *response = request->beginResponse(400); response->addHeader(WS_STR_VERSION, F("13")); request->send(response); @@ -1121,7 +1143,8 @@ void AsyncWebSocket::handleRequest(AsyncWebServerRequest *request) } AsyncWebHeader* key = request->getHeader(WS_STR_KEY); AsyncWebServerResponse *response = new AsyncWebSocketResponse(key->value(), this); - if (request->hasHeader(WS_STR_PROTOCOL)){ + if (request->hasHeader(WS_STR_PROTOCOL)) + { AsyncWebHeader* protocol = request->getHeader(WS_STR_PROTOCOL); //ToDo: check protocol response->addHeader(WS_STR_PROTOCOL, protocol->value()); @@ -1134,56 +1157,63 @@ void AsyncWebSocket::handleRequest(AsyncWebServerRequest *request) * Authentication code from https://github.com/Links2004/arduinoWebSockets/blob/master/src/WebSockets.cpp#L480 */ -AsyncWebSocketResponse::AsyncWebSocketResponse(const String& key, AsyncWebSocket *server){ - _server = server; - _code = 101; - _sendContentLength = false; +AsyncWebSocketResponse::AsyncWebSocketResponse(const String& key, AsyncWebSocket *server) +{ + _server = server; + _code = 101; + _sendContentLength = false; - uint8_t * hash = (uint8_t*)malloc(20); - if(hash == NULL){ - _state = RESPONSE_FAILED; - return; - } - char * buffer = (char *) malloc(33); - if(buffer == NULL){ - free(hash); - _state = RESPONSE_FAILED; - return; - } + uint8_t * hash = (uint8_t*)malloc(20); + if(hash == NULL) + { + _state = RESPONSE_FAILED; + return; + } + char * buffer = (char *) malloc(33); + if(buffer == NULL) + { + free(hash); + _state = RESPONSE_FAILED; + return; + } #ifdef ESP8266 - sha1(key + WS_STR_UUID, hash); + sha1(key + WS_STR_UUID, hash); #else - (String&)key += WS_STR_UUID; - SHA1_CTX ctx; - SHA1Init(&ctx); - SHA1Update(&ctx, (const unsigned char*)key.c_str(), key.length()); - SHA1Final(hash, &ctx); + (String&)key += WS_STR_UUID; + SHA1_CTX ctx; + SHA1Init(&ctx); + SHA1Update(&ctx, (const unsigned char*)key.c_str(), key.length()); + SHA1Final(hash, &ctx); #endif - base64_encodestate _state; - base64_init_encodestate(&_state); - int len = base64_encode_block((const char *) hash, 20, buffer, &_state); - len = base64_encode_blockend((buffer + len), &_state); - addHeader(WS_STR_CONNECTION, WS_STR_UPGRADE); - addHeader(WS_STR_UPGRADE, F("websocket")); - addHeader(WS_STR_ACCEPT,buffer); - free(buffer); - free(hash); -} - -void AsyncWebSocketResponse::_respond(AsyncWebServerRequest *request){ - if(_state == RESPONSE_FAILED){ - request->client()->close(true); - return; - } - String out = _assembleHead(request->version()); - request->client()->write(out.c_str(), _headLength); - _state = RESPONSE_WAIT_ACK; + base64_encodestate _state; + base64_init_encodestate(&_state); + int len = base64_encode_block((const char *) hash, 20, buffer, &_state); + len = base64_encode_blockend((buffer + len), &_state); + addHeader(WS_STR_CONNECTION, WS_STR_UPGRADE); + addHeader(WS_STR_UPGRADE, F("websocket")); + addHeader(WS_STR_ACCEPT,buffer); + free(buffer); + free(hash); } -size_t AsyncWebSocketResponse::_ack(AsyncWebServerRequest *request, size_t len, uint32_t time){ - (void)time; - if(len){ - _server->_newClient(request); - } - return 0; +void AsyncWebSocketResponse::_respond(AsyncWebServerRequest *request) +{ + if(_state == RESPONSE_FAILED) + { + request->client()->close(true); + return; + } + String out = _assembleHead(request->version()); + request->client()->write(out.c_str(), _headLength); + _state = RESPONSE_WAIT_ACK; +} + +size_t AsyncWebSocketResponse::_ack(AsyncWebServerRequest *request, size_t len, uint32_t time) +{ + (void)time; + + if(len) + _server->_newClient(request); + + return 0; } diff --git a/src/AsyncWebSocket.h b/src/AsyncWebSocket.h index 3b4e0f7a4..9a0a3b45b 100644 --- a/src/AsyncWebSocket.h +++ b/src/AsyncWebSocket.h @@ -24,7 +24,7 @@ #include #ifdef ESP32 #include -#define WS_MAX_QUEUED_MESSAGES 32 +#define WS_MAX_QUEUED_MESSAGES 16 #else #include #define WS_MAX_QUEUED_MESSAGES 8 @@ -146,6 +146,8 @@ class AsyncWebSocketClient { IPAddress remoteIP() const; uint16_t remotePort() const; + bool shouldBeDeleted() const { return !_client; } + //control frames void close(uint16_t code=0, const char * message=NULL); void ping(const uint8_t *data=NULL, size_t len=0); @@ -273,7 +275,6 @@ class AsyncWebSocket: public AsyncWebHandler { //system callbacks (do not call) uint32_t _getNextId(){ return _cNextId++; } AsyncWebSocketClient *_newClient(AsyncWebServerRequest *request); - void _handleDisconnect(AsyncWebSocketClient * client); void _handleEvent(AsyncWebSocketClient * client, AwsEventType type, void * arg, uint8_t *data, size_t len); virtual bool canHandle(AsyncWebServerRequest *request) override final; virtual void handleRequest(AsyncWebServerRequest *request) override final; From 646eab7bd8761a7ff89c627e37c0f27c49cef32f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Villac=C3=ADs=20Lasso?= Date: Thu, 14 Jan 2021 15:13:17 -0500 Subject: [PATCH 107/551] Fix self-deadlock onConnect introduced by ul-gh/fix_#884 branch Commit 344062ae5be9dab80dd602458857f3a5ec5dfb3c intended to protect the client list for AsyncEventSource from concurrent access by wrapping accesses with locking. However, this introduces a self-deadlock scenario if application code in the onConnect callback (now called with the client list lock held) tries to broadcast a message to existing connections in the same AsyncEventSource (for example, to alert of a new incoming connection). The broadcast call tries to take the lock but blocks because the lock is already taken, by the same task, before calling the callback. Fixed by making use of the AsyncWebLockGuard class which is tailor-made to address this scenario. --- src/AsyncEventSource.cpp | 19 ++++++------------- src/AsyncEventSource.h | 2 +- 2 files changed, 7 insertions(+), 14 deletions(-) diff --git a/src/AsyncEventSource.cpp b/src/AsyncEventSource.cpp index c2f8187f4..90317afac 100644 --- a/src/AsyncEventSource.cpp +++ b/src/AsyncEventSource.cpp @@ -298,38 +298,34 @@ void AsyncEventSource::_addClient(AsyncEventSourceClient * client){ client->write((const char *)temp, 2053); free(temp); }*/ - _client_queue_lock.lock(); + AsyncWebLockGuard l(_client_queue_lock); _clients.add(client); if(_connectcb) _connectcb(client); - _client_queue_lock.unlock(); } void AsyncEventSource::_handleDisconnect(AsyncEventSourceClient * client){ - _client_queue_lock.lock(); + AsyncWebLockGuard l(_client_queue_lock); _clients.remove(client); - _client_queue_lock.unlock(); } void AsyncEventSource::close(){ // While the whole loop is not done, the linked list is locked and so the // iterator should remain valid even when AsyncEventSource::_handleDisconnect() // is called very early - _client_queue_lock.lock(); + AsyncWebLockGuard l(_client_queue_lock); for(const auto &c: _clients){ if(c->connected()) c->close(); } - _client_queue_lock.unlock(); } // pmb fix size_t AsyncEventSource::avgPacketsWaiting() const { size_t aql = 0; uint32_t nConnectedClients = 0; - _client_queue_lock.lock(); + AsyncWebLockGuard l(_client_queue_lock); if (_clients.isEmpty()) { - _client_queue_lock.unlock(); return 0; } for(const auto &c: _clients){ @@ -338,29 +334,26 @@ size_t AsyncEventSource::avgPacketsWaiting() const { ++nConnectedClients; } } - _client_queue_lock.unlock(); return ((aql) + (nConnectedClients/2)) / (nConnectedClients); // round up } void AsyncEventSource::send( const char *message, const char *event, uint32_t id, uint32_t reconnect){ String ev = generateEventMessage(message, event, id, reconnect); - _client_queue_lock.lock(); + AsyncWebLockGuard l(_client_queue_lock); for(const auto &c: _clients){ if(c->connected()) { c->_write(ev.c_str(), ev.length()); } } - _client_queue_lock.unlock(); } size_t AsyncEventSource::count() const { size_t n_clients; - _client_queue_lock.lock(); + AsyncWebLockGuard l(_client_queue_lock); n_clients = _clients.count_if([](AsyncEventSourceClient *c){ return c->connected(); }); - _client_queue_lock.unlock(); return n_clients; } diff --git a/src/AsyncEventSource.h b/src/AsyncEventSource.h index cd0afbcf0..abb1829c7 100644 --- a/src/AsyncEventSource.h +++ b/src/AsyncEventSource.h @@ -104,7 +104,7 @@ class AsyncEventSource: public AsyncWebHandler { LinkedList _clients; // Same as for individual messages, protect mutations of _clients list // since simultaneous access from different tasks is possible - AsyncPlainLock _client_queue_lock; + AsyncWebLock _client_queue_lock; ArEventHandlerFunction _connectcb; ArAuthorizeConnectHandler _authorizeConnectHandler; public: From 2f784268f0a358741ee6384480d48656e159d726 Mon Sep 17 00:00:00 2001 From: Pablo Clemente Maseda Date: Wed, 24 Feb 2021 23:03:28 +0100 Subject: [PATCH 108/551] Redefine DYNAMIC_JSON_DOCUMENT_SIZE if not defined (#922) --- src/AsyncJson.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/AsyncJson.h b/src/AsyncJson.h index 27b4a26f6..2fa6a2d26 100644 --- a/src/AsyncJson.h +++ b/src/AsyncJson.h @@ -41,7 +41,9 @@ #if ARDUINOJSON_VERSION_MAJOR == 5 #define ARDUINOJSON_5_COMPATIBILITY #else - #define DYNAMIC_JSON_DOCUMENT_SIZE 1024 + #ifndef DYNAMIC_JSON_DOCUMENT_SIZE + #define DYNAMIC_JSON_DOCUMENT_SIZE 1024 + #endif #endif constexpr const char* JSON_MIMETYPE = "application/json"; From c7b7fafa818df3c00404062c3aff548a01bfe8d7 Mon Sep 17 00:00:00 2001 From: Blackhack Date: Sat, 5 Jun 2021 18:28:56 -0500 Subject: [PATCH 109/551] Fix build when using latest arduino-esp32 master due to IDF update https://github.com/espressif/arduino-esp32/commit/a618fc1361b08aa968407dd81b7b065cca207f46 --- src/WebAuthentication.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/WebAuthentication.cpp b/src/WebAuthentication.cpp index 2feca5420..45246a196 100644 --- a/src/WebAuthentication.cpp +++ b/src/WebAuthentication.cpp @@ -71,9 +71,9 @@ static bool getMD5(uint8_t * data, uint16_t len, char * output){//33 bytes or mo memset(_buf, 0x00, 16); #ifdef ESP32 mbedtls_md5_init(&_ctx); - mbedtls_md5_starts(&_ctx); - mbedtls_md5_update(&_ctx, data, len); - mbedtls_md5_finish(&_ctx, _buf); + mbedtls_md5_starts_ret(&_ctx); + mbedtls_md5_update_ret(&_ctx, data, len); + mbedtls_md5_finish_ret(&_ctx, _buf); #else MD5Init(&_ctx); MD5Update(&_ctx, data, len); From 8a43124ee8dead6298821c0e0fe67ebc98cfae8d Mon Sep 17 00:00:00 2001 From: Blackhack Date: Sat, 5 Jun 2021 22:30:35 -0500 Subject: [PATCH 110/551] Fix build when using WebSockets --- src/AsyncWebSocket.cpp | 23 +++++++---------------- 1 file changed, 7 insertions(+), 16 deletions(-) diff --git a/src/AsyncWebSocket.cpp b/src/AsyncWebSocket.cpp index 52dcd75f0..f76f2fc96 100644 --- a/src/AsyncWebSocket.cpp +++ b/src/AsyncWebSocket.cpp @@ -24,18 +24,7 @@ #include #ifndef ESP8266 -extern "C" { -typedef struct { - uint32_t state[5]; - uint32_t count[2]; - unsigned char buffer[64]; -} SHA1_CTX; - -void SHA1Transform(uint32_t state[5], const unsigned char buffer[64]); -void SHA1Init(SHA1_CTX* context); -void SHA1Update(SHA1_CTX* context, const unsigned char* data, uint32_t len); -void SHA1Final(unsigned char digest[20], SHA1_CTX* context); -} +#include "mbedtls/sha1.h" #else #include #endif @@ -1268,10 +1257,12 @@ AsyncWebSocketResponse::AsyncWebSocketResponse(const String& key, AsyncWebSocket sha1(key + WS_STR_UUID, hash); #else (String&)key += WS_STR_UUID; - SHA1_CTX ctx; - SHA1Init(&ctx); - SHA1Update(&ctx, (const unsigned char*)key.c_str(), key.length()); - SHA1Final(hash, &ctx); + mbedtls_sha1_context ctx; + mbedtls_sha1_init(&ctx); + mbedtls_sha1_starts_ret(&ctx); + mbedtls_sha1_update_ret(&ctx, (const unsigned char*)key.c_str(), key.length()); + mbedtls_sha1_finish_ret(&ctx, hash); + mbedtls_sha1_free(&ctx); #endif base64_encodestate _state; base64_init_encodestate(&_state); From 2ab974a5b5d65fb69b3fe7e0d4114e97bf7c0703 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Villac=C3=ADs=20Lasso?= Date: Fri, 18 Jun 2021 16:32:30 -0500 Subject: [PATCH 111/551] Add missing #include to base ESPAsyncWebServer.h This fixes a compilation error with the gcc version on Arduino ESP32 2.0.0-dev --- src/ESPAsyncWebServer.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index 4497c9a14..1d3c4049c 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -25,6 +25,7 @@ #include #include +#include #include "FS.h" #include "StringArray.h" From 5613e66f6768b5a5f1629e0931992cd020856a0a Mon Sep 17 00:00:00 2001 From: JDavid Date: Mon, 26 Jul 2021 12:40:52 -0500 Subject: [PATCH 112/551] Fix build when using latest arduino-esp32 master due to IDF update (#999) * Fix build when using latest arduino-esp32 master due to IDF update https://github.com/espressif/arduino-esp32/commit/a618fc1361b08aa968407dd81b7b065cca207f46 * Fix build when using WebSockets --- src/AsyncWebSocket.cpp | 23 +++++++---------------- src/WebAuthentication.cpp | 6 +++--- 2 files changed, 10 insertions(+), 19 deletions(-) diff --git a/src/AsyncWebSocket.cpp b/src/AsyncWebSocket.cpp index 52dcd75f0..f76f2fc96 100644 --- a/src/AsyncWebSocket.cpp +++ b/src/AsyncWebSocket.cpp @@ -24,18 +24,7 @@ #include #ifndef ESP8266 -extern "C" { -typedef struct { - uint32_t state[5]; - uint32_t count[2]; - unsigned char buffer[64]; -} SHA1_CTX; - -void SHA1Transform(uint32_t state[5], const unsigned char buffer[64]); -void SHA1Init(SHA1_CTX* context); -void SHA1Update(SHA1_CTX* context, const unsigned char* data, uint32_t len); -void SHA1Final(unsigned char digest[20], SHA1_CTX* context); -} +#include "mbedtls/sha1.h" #else #include #endif @@ -1268,10 +1257,12 @@ AsyncWebSocketResponse::AsyncWebSocketResponse(const String& key, AsyncWebSocket sha1(key + WS_STR_UUID, hash); #else (String&)key += WS_STR_UUID; - SHA1_CTX ctx; - SHA1Init(&ctx); - SHA1Update(&ctx, (const unsigned char*)key.c_str(), key.length()); - SHA1Final(hash, &ctx); + mbedtls_sha1_context ctx; + mbedtls_sha1_init(&ctx); + mbedtls_sha1_starts_ret(&ctx); + mbedtls_sha1_update_ret(&ctx, (const unsigned char*)key.c_str(), key.length()); + mbedtls_sha1_finish_ret(&ctx, hash); + mbedtls_sha1_free(&ctx); #endif base64_encodestate _state; base64_init_encodestate(&_state); diff --git a/src/WebAuthentication.cpp b/src/WebAuthentication.cpp index 2feca5420..45246a196 100644 --- a/src/WebAuthentication.cpp +++ b/src/WebAuthentication.cpp @@ -71,9 +71,9 @@ static bool getMD5(uint8_t * data, uint16_t len, char * output){//33 bytes or mo memset(_buf, 0x00, 16); #ifdef ESP32 mbedtls_md5_init(&_ctx); - mbedtls_md5_starts(&_ctx); - mbedtls_md5_update(&_ctx, data, len); - mbedtls_md5_finish(&_ctx, _buf); + mbedtls_md5_starts_ret(&_ctx); + mbedtls_md5_update_ret(&_ctx, data, len); + mbedtls_md5_finish_ret(&_ctx, _buf); #else MD5Init(&_ctx); MD5Update(&_ctx, data, len); From 1d46269cedf477661ca8a29518414f4b74e957d4 Mon Sep 17 00:00:00 2001 From: Me No Dev Date: Mon, 26 Jul 2021 20:50:50 +0300 Subject: [PATCH 113/551] Stop PIO CI --- .github/workflows/push.yml | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml index abdea4627..231dc5292 100644 --- a/.github/workflows/push.yml +++ b/.github/workflows/push.yml @@ -21,14 +21,14 @@ jobs: - name: Build Tests run: bash ./.github/scripts/on-push.sh ${{ matrix.board }} 0 1 - build-pio: - name: PlatformIO for ${{ matrix.board }} on ${{ matrix.os }} - runs-on: ${{ matrix.os }} - strategy: - matrix: - os: [ubuntu-latest, windows-latest, macOS-latest] - board: [esp32, esp8266] - steps: - - uses: actions/checkout@v1 - - name: Build Tests - run: bash ./.github/scripts/on-push.sh ${{ matrix.board }} 1 1 +# build-pio: +# name: PlatformIO for ${{ matrix.board }} on ${{ matrix.os }} +# runs-on: ${{ matrix.os }} +# strategy: +# matrix: +# os: [ubuntu-latest, windows-latest, macOS-latest] +# board: [esp32, esp8266] +# steps: +# - uses: actions/checkout@v1 +# - name: Build Tests +# run: bash ./.github/scripts/on-push.sh ${{ matrix.board }} 1 1 From f71e3d427b5be9791a8a2c93cf8079792c3a9a26 Mon Sep 17 00:00:00 2001 From: Ivan Kravets Date: Sat, 26 Mar 2022 00:02:59 +0200 Subject: [PATCH 114/551] Avoid breaking changes with strict dependencies (#1133) --- library.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/library.json b/library.json index 556592793..750ca28d2 100644 --- a/library.json +++ b/library.json @@ -18,11 +18,15 @@ "platforms": ["espressif8266", "espressif32"], "dependencies": [ { + "owner": "me-no-dev", "name": "ESPAsyncTCP", + "version": "^1.2.2", "platforms": "espressif8266" }, { + "owner": "me-no-dev", "name": "AsyncTCP", + "version": "^1.1.1", "platforms": "espressif32" }, { From 1f1750477a92c53e63b31b956045981bfebd61ef Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Fri, 12 Jan 2024 18:46:56 +0100 Subject: [PATCH 115/551] Switched to 2.0.0 --- library.json | 35 ++++++++++++++++++----------------- library.properties | 4 ++-- 2 files changed, 20 insertions(+), 19 deletions(-) diff --git a/library.json b/library.json index 332c1c34b..c5cfbbdf6 100644 --- a/library.json +++ b/library.json @@ -1,32 +1,33 @@ { - "name":"ESP Async WebServer", - "description":"Asynchronous HTTP and WebSocket Server Library for ESP8266 and ESP32", - "keywords":"http,async,websocket,webserver", - "authors": - { + "name": "ESP Async WebServer", + "description": "Asynchronous HTTP and WebSocket Server Library for ESP8266 and ESP32", + "keywords": "http,async,websocket,webserver", + "authors": { "name": "Hristo Gochkov", "maintainer": true }, - "repository": - { + "repository": { "type": "git", - "url": "https://github.com/lorol/ESPAsyncWebServer.git" + "url": "https://github.com/mathieucarbou/ESPAsyncWebServer.git" }, - "version": "1.2.3", + "version": "2.0.0", "license": "LGPL-3.0", "frameworks": "arduino", - "platforms": ["espressif8266", "espressif32"], + "platforms": [ + "espressif8266", + "espressif32" + ], "dependencies": [ { - "owner": "me-no-dev", - "name": "ESPAsyncTCP", - "version": "^1.2.2", + "owner": "esphome", + "name": "ESPAsyncTCP-esphome", + "version": "2.0.0", "platforms": "espressif8266" }, { - "owner": "me-no-dev", - "name": "AsyncTCP", - "version": "^1.1.1", + "owner": "esphome", + "name": "AsyncTCP-esphome", + "version": "2.0.1", "platforms": "espressif32" }, { @@ -34,4 +35,4 @@ "platforms": "espressif8266" } ] -} +} \ No newline at end of file diff --git a/library.properties b/library.properties index 1039ed0a3..0d3959e84 100644 --- a/library.properties +++ b/library.properties @@ -1,9 +1,9 @@ name=ESP Async WebServer -version=1.2.3 +version=2.0.0 author=Me-No-Dev maintainer=lorol sentence=Async Web Server for ESP8266 and ESP31B paragraph=Async Web Server for ESP8266 and ESP31B category=Other -url=https://github.com/lorol/ESPAsyncWebServer +urlhttps://github.com/mathieucarbou/ESPAsyncWebServer architectures=* From 11249c3726c363d3e395eeb2b2cb19c448be5209 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Fri, 12 Jan 2024 19:02:14 +0100 Subject: [PATCH 116/551] ArduinoJson 7 support --- src/AsyncJson.h | 56 ++++++++++++++++++++++++++++++------------------- 1 file changed, 35 insertions(+), 21 deletions(-) diff --git a/src/AsyncJson.h b/src/AsyncJson.h index 2fa6a2d26..a6673a8aa 100644 --- a/src/AsyncJson.h +++ b/src/AsyncJson.h @@ -38,9 +38,7 @@ #include #include -#if ARDUINOJSON_VERSION_MAJOR == 5 - #define ARDUINOJSON_5_COMPATIBILITY -#else +#if ARDUINOJSON_VERSION_MAJOR == 6 #ifndef DYNAMIC_JSON_DOCUMENT_SIZE #define DYNAMIC_JSON_DOCUMENT_SIZE 1024 #endif @@ -82,10 +80,12 @@ class ChunkPrint : public Print { class AsyncJsonResponse: public AsyncAbstractResponse { protected: -#ifdef ARDUINOJSON_5_COMPATIBILITY +#if ARDUINOJSON_VERSION_MAJOR == 5 DynamicJsonBuffer _jsonBuffer; -#else +#elif ARDUINOJSON_VERSION_MAJOR == 6 DynamicJsonDocument _jsonBuffer; +#else + JsonDocument _jsonBuffer; #endif JsonVariant _root; @@ -93,7 +93,7 @@ class AsyncJsonResponse: public AsyncAbstractResponse { public: -#ifdef ARDUINOJSON_5_COMPATIBILITY +#if ARDUINOJSON_VERSION_MAJOR == 5 AsyncJsonResponse(bool isArray=false): _isValid{false} { _code = 200; _contentType = JSON_MIMETYPE; @@ -102,7 +102,7 @@ class AsyncJsonResponse: public AsyncAbstractResponse { else _root = _jsonBuffer.createObject(); } -#else +#elif ARDUINOJSON_VERSION_MAJOR == 6 AsyncJsonResponse(bool isArray=false, size_t maxJsonBufferSize = DYNAMIC_JSON_DOCUMENT_SIZE) : _jsonBuffer(maxJsonBufferSize), _isValid{false} { _code = 200; _contentType = JSON_MIMETYPE; @@ -111,6 +111,15 @@ class AsyncJsonResponse: public AsyncAbstractResponse { else _root = _jsonBuffer.createNestedObject(); } +#else + AsyncJsonResponse(bool isArray=false) : _isValid{false} { + _code = 200; + _contentType = JSON_MIMETYPE; + if(isArray) + _root = _jsonBuffer.add(); + else + _root = _jsonBuffer.add(); + } #endif ~AsyncJsonResponse() {} @@ -118,7 +127,7 @@ class AsyncJsonResponse: public AsyncAbstractResponse { bool _sourceValid() const { return _isValid; } size_t setLength() { -#ifdef ARDUINOJSON_5_COMPATIBILITY +#if ARDUINOJSON_VERSION_MAJOR == 5 _contentLength = _root.measureLength(); #else _contentLength = measureJson(_root); @@ -133,7 +142,7 @@ class AsyncJsonResponse: public AsyncAbstractResponse { size_t _fillBuffer(uint8_t *data, size_t len){ ChunkPrint dest(data, _sentLength, len); -#ifdef ARDUINOJSON_5_COMPATIBILITY +#if ARDUINOJSON_VERSION_MAJOR == 5 _root.printTo( dest ) ; #else serializeJson(_root, dest); @@ -144,13 +153,13 @@ class AsyncJsonResponse: public AsyncAbstractResponse { class PrettyAsyncJsonResponse: public AsyncJsonResponse { public: -#ifdef ARDUINOJSON_5_COMPATIBILITY - PrettyAsyncJsonResponse (bool isArray=false) : AsyncJsonResponse{isArray} {} +#if ARDUINOJSON_VERSION_MAJOR == 6 + PrettyAsyncJsonResponse (bool isArray=false, size_t maxJsonBufferSize = DYNAMIC_JSON_DOCUMENT_SIZE) : AsyncJsonResponse{isArray, maxJsonBufferSize} {} #else - PrettyAsyncJsonResponse (bool isArray=false, size_t maxJsonBufferSize = DYNAMIC_JSON_DOCUMENT_SIZE) : AsyncJsonResponse{isArray, maxJsonBufferSize} {} + PrettyAsyncJsonResponse (bool isArray=false) : AsyncJsonResponse{isArray} {} #endif size_t setLength () { -#ifdef ARDUINOJSON_5_COMPATIBILITY +#if ARDUINOJSON_VERSION_MAJOR == 5 _contentLength = _root.measurePrettyLength (); #else _contentLength = measureJsonPretty(_root); @@ -160,7 +169,7 @@ class PrettyAsyncJsonResponse: public AsyncJsonResponse { } size_t _fillBuffer (uint8_t *data, size_t len) { ChunkPrint dest (data, _sentLength, len); -#ifdef ARDUINOJSON_5_COMPATIBILITY +#if ARDUINOJSON_VERSION_MAJOR == 5 _root.prettyPrintTo (dest); #else serializeJsonPretty(_root, dest); @@ -178,17 +187,17 @@ class AsyncCallbackJsonWebHandler: public AsyncWebHandler { WebRequestMethodComposite _method; ArJsonRequestHandlerFunction _onRequest; size_t _contentLength; -#ifndef ARDUINOJSON_5_COMPATIBILITY +#if ARDUINOJSON_VERSION_MAJOR == 6 const size_t maxJsonBufferSize; #endif size_t _maxContentLength; public: -#ifdef ARDUINOJSON_5_COMPATIBILITY - AsyncCallbackJsonWebHandler(const String& uri, ArJsonRequestHandlerFunction onRequest) - : _uri(uri), _method(HTTP_POST|HTTP_PUT|HTTP_PATCH), _onRequest(onRequest), _maxContentLength(16384) {} -#else +#if ARDUINOJSON_VERSION_MAJOR == 6 AsyncCallbackJsonWebHandler(const String& uri, ArJsonRequestHandlerFunction onRequest, size_t maxJsonBufferSize=DYNAMIC_JSON_DOCUMENT_SIZE) : _uri(uri), _method(HTTP_POST|HTTP_PUT|HTTP_PATCH), _onRequest(onRequest), maxJsonBufferSize(maxJsonBufferSize), _maxContentLength(16384) {} +#else + AsyncCallbackJsonWebHandler(const String& uri, ArJsonRequestHandlerFunction onRequest) + : _uri(uri), _method(HTTP_POST|HTTP_PUT|HTTP_PATCH), _onRequest(onRequest), _maxContentLength(16384) {} #endif void setMethod(WebRequestMethodComposite method){ _method = method; } @@ -216,15 +225,20 @@ class AsyncCallbackJsonWebHandler: public AsyncWebHandler { if(_onRequest) { if (request->_tempObject != NULL) { -#ifdef ARDUINOJSON_5_COMPATIBILITY +#if ARDUINOJSON_VERSION_MAJOR == 5 DynamicJsonBuffer jsonBuffer; JsonVariant json = jsonBuffer.parse((uint8_t*)(request->_tempObject)); if (json.success()) { -#else +#elif ARDUINOJSON_VERSION_MAJOR == 6 DynamicJsonDocument jsonBuffer(this->maxJsonBufferSize); DeserializationError error = deserializeJson(jsonBuffer, (uint8_t*)(request->_tempObject)); if(!error) { JsonVariant json = jsonBuffer.as(); +#else + JsonDocument jsonBuffer; + DeserializationError error = deserializeJson(jsonBuffer, (uint8_t*)(request->_tempObject)); + if(!error) { + JsonVariant json = jsonBuffer.as(); #endif _onRequest(request, json); From 924deb219236ea1533f4216738cd6d1fb3fc275b Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Fri, 12 Jan 2024 19:02:29 +0100 Subject: [PATCH 117/551] User-defined WS_MAX_QUEUED_MESSAGES --- src/AsyncWebSocket.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/AsyncWebSocket.h b/src/AsyncWebSocket.h index 9a0a3b45b..46de34066 100644 --- a/src/AsyncWebSocket.h +++ b/src/AsyncWebSocket.h @@ -24,11 +24,15 @@ #include #ifdef ESP32 #include -#define WS_MAX_QUEUED_MESSAGES 16 +#ifndef WS_MAX_QUEUED_MESSAGES +#define WS_MAX_QUEUED_MESSAGES 32 +#endif #else #include +#ifndef WS_MAX_QUEUED_MESSAGES #define WS_MAX_QUEUED_MESSAGES 8 #endif +#endif #include #include "AsyncWebSynchronization.h" From b459827878802ac729e03424ddf1de32d912db22 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Fri, 12 Jan 2024 19:04:02 +0100 Subject: [PATCH 118/551] Remove DEBUGF --- src/ESPAsyncWebServer.h | 2 -- src/WebHandlers.cpp | 1 - 2 files changed, 3 deletions(-) diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index 1d3c4049c..3c9059ffe 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -46,8 +46,6 @@ #define ASYNCWEBSERVER_REGEX_ATTRIBUTE __attribute__((warning("ASYNCWEBSERVER_REGEX not defined"))) #endif -#define DEBUGF(...) //Serial.printf(__VA_ARGS__) - class AsyncWebServer; class AsyncWebServerRequest; class AsyncWebServerResponse; diff --git a/src/WebHandlers.cpp b/src/WebHandlers.cpp index 8e87ff1cf..c79cdbbb5 100644 --- a/src/WebHandlers.cpp +++ b/src/WebHandlers.cpp @@ -99,7 +99,6 @@ bool AsyncStaticWebHandler::canHandle(AsyncWebServerRequest *request){ if(_cache_control.length()) request->addInterestingHeader(F("If-None-Match")); - DEBUGF("[AsyncStaticWebHandler::canHandle] TRUE\n"); return true; } From ccfb1c16697d2802381a9d59059bf308b04646d3 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Fri, 12 Jan 2024 23:45:48 +0100 Subject: [PATCH 119/551] Added ASYNCWEBSERVER_F* defines for downstream projects --- src/ESPAsyncWebServer.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index 3c9059ffe..23b14c424 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -40,6 +40,12 @@ #error Platform not supported #endif +#define ASYNCWEBSERVER_VERSION "2.1.0" +#define ASYNCWEBSERVER_VERSION_MAJOR 2 +#define ASYNCWEBSERVER_VERSION_MINOR 1 +#define ASYNCWEBSERVER_VERSION_REVISION 0 +#define ASYNCWEBSERVER_FORK_mathieucarbou + #ifdef ASYNCWEBSERVER_REGEX #define ASYNCWEBSERVER_REGEX_ATTRIBUTE #else From 910074e079bce7093fc8c572ed7c29717283bbdb Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Fri, 12 Jan 2024 19:04:28 +0100 Subject: [PATCH 120/551] Preparing 2.1.0 --- .github/scripts/install-arduino-core-esp32.sh | 36 - .../scripts/install-arduino-core-esp8266.sh | 29 - .github/scripts/install-arduino-ide.sh | 228 - .github/scripts/install-platformio.sh | 140 - .github/scripts/on-push.sh | 75 - .github/stale.yml | 31 - .github/workflows/push.yml | 34 - README.md | 4 +- examples/CaptivePortal/CaptivePortal.ino | 47 - .../ESP_AsyncFSBrowser/ESP_AsyncFSBrowser.ino | 257 - .../ESP_AsyncFSBrowser/data/.exclude.files | 3 - examples/ESP_AsyncFSBrowser/data/ace.ico.gz | Bin 6307 -> 0 bytes .../ESP_AsyncFSBrowser/data/acefull.js.gz | Bin 118766 -> 0 bytes examples/ESP_AsyncFSBrowser/data/edit_gz | Bin 4503 -> 0 bytes examples/ESP_AsyncFSBrowser/data/favicon.ico | Bin 1150 -> 0 bytes .../ESP_AsyncFSBrowser/data/folder/image.jpg | Bin 6071 -> 0 bytes .../ESP_AsyncFSBrowser/data/folder/test.txt | 1 - examples/ESP_AsyncFSBrowser/data/index.htm | 131 - .../ESP_AsyncFSBrowser/data/worker-css.js.gz | Bin 32927 -> 0 bytes .../ESP_AsyncFSBrowser/data/worker-html.js.gz | Bin 45019 -> 0 bytes .../data/worker-javascript.js.gz | Bin 112558 -> 0 bytes .../ESP_AsyncFSBrowser/data/worker-json.js.gz | Bin 6923 -> 0 bytes examples/SmartSwitch/1.PNG | Bin 17650 -> 0 bytes examples/SmartSwitch/2.PNG | Bin 12835 -> 0 bytes examples/SmartSwitch/3.PNG | Bin 26824 -> 0 bytes examples/SmartSwitch/4.PNG | Bin 17958 -> 0 bytes examples/SmartSwitch/ESPAsyncWiFiManager.cpp | 1177 ---- examples/SmartSwitch/ESPAsyncWiFiManager.h | 283 - examples/SmartSwitch/PinOut_Notes.txt | 56 - examples/SmartSwitch/README.md | 19 - examples/SmartSwitch/SmartSwitch.ino | 750 --- examples/SmartSwitch/Xtea.cpp | 48 - examples/SmartSwitch/Xtea.h | 20 - examples/SmartSwitch/data/.exclude.files | 3 - examples/SmartSwitch/data/ace.ico.gz | Bin 6307 -> 0 bytes examples/SmartSwitch/data/acefull.js.gz | Bin 118766 -> 0 bytes examples/SmartSwitch/data/app.css.gz | Bin 2740 -> 0 bytes examples/SmartSwitch/data/app.min.js.gz | Bin 38439 -> 0 bytes examples/SmartSwitch/data/edit_gz | Bin 4503 -> 0 bytes examples/SmartSwitch/data/favicon.ico.gz | Bin 4314 -> 0 bytes examples/SmartSwitch/data/index.htm | 626 -- .../SmartSwitch/data/login/favicon.ico.gz | Bin 5806 -> 0 bytes examples/SmartSwitch/data/login/index.htm | 36 - examples/SmartSwitch/data/worker-css.js.gz | Bin 32927 -> 0 bytes examples/SmartSwitch/data/worker-html.js.gz | Bin 45019 -> 0 bytes .../SmartSwitch/data/worker-javascript.js.gz | Bin 112558 -> 0 bytes examples/SmartSwitch/data/worker-json.js.gz | Bin 6923 -> 0 bytes examples/SmartSwitch/data_src/.exclude.files | 2 - examples/SmartSwitch/data_src/acefull.js | 30 - examples/SmartSwitch/data_src/app.css | 1 - examples/SmartSwitch/data_src/app.min.js | 533 -- examples/SmartSwitch/data_src/favicon.ico | Bin 15406 -> 0 bytes examples/SmartSwitch/data_src/index.htm | 599 -- .../data_src/js_css_src/.exclude.files | 2 - .../data_src/js_css_src/ace-drafts/ace.js | 14 - .../js_css_src/ace-drafts/ext-searchbox.js | 5 - .../js_css_src/ace-drafts/mode-css.js | 1 - .../js_css_src/ace-drafts/mode-html.js | 1 - .../js_css_src/ace-drafts/mode-javascript.js | 1 - .../js_css_src/ace-drafts/worker-html.js | 1 - .../SmartSwitch/data_src/js_css_src/ace.js | 14 - .../SmartSwitch/data_src/js_css_src/app.js | 5787 ----------------- .../js_css_src/js-time-picker/1-inline.html | 30 - .../js_css_src/js-time-picker/2-popup.html | 27 - .../js_css_src/js-time-picker/README.txt | 29 - .../js-time-picker/tpick-light-pop.css | 65 - .../js_css_src/js-time-picker/tpick-light.css | 47 - .../js_css_src/js-time-picker/tpick-pop.js | 136 - .../js_css_src/js-time-picker/tpick.js | 116 - .../justgage-1.2.2/examples/auto-adjust.htm | 94 - .../justgage-1.2.2/examples/counter.html | 58 - .../examples/custom-interval.htm | 82 - .../justgage-1.2.2/examples/custom-node.html | 130 - .../examples/custom-sectors.html | 88 - .../examples/custom-value-renderer.html | 116 - .../examples/customize-style.htm | 137 - .../justgage-1.2.2/examples/defaults.html | 60 - .../justgage-1.2.2/examples/font-options.html | 62 - .../examples/format-number.html | 56 - .../examples/html5-data-attribute-config.html | 54 - .../examples/human-friendly-numbers.html | 109 - .../justgage-1.2.2/examples/pointer.html | 168 - .../examples/refresh-maximum.html | 91 - .../examples/responsive-gauges.htm | 71 - .../justgage-1.2.2/examples/reverse.html | 144 - .../js_css_src/justgage-1.2.2/justgage.js | 1220 ---- .../justgage-1.2.2/raphael-2.1.4.min.js | 12 - .../js_css_src/styled-notifications/.babelrc | 3 - .../styled-notifications/.eslintrc.js | 31 - .../styled-notifications/.gitignore | 30 - .../styled-notifications/.travis.yml | 3 - .../styled-notifications/LICENSE.md | 7 - .../__tests__/helpers.test.js | 104 - .../__tests__/index.tests.js | 144 - .../styled-notifications/demo/demo.js | 34 - .../styled-notifications/demo/index.html | 101 - .../styled-notifications/demo/index_my.html | 37 - .../dist/notifications.css | 1 - .../dist/notifications.css.gz | Bin 2487 -> 0 bytes .../dist/notifications.js | 1 - .../dist/notifications.js.gz | Bin 1723 -> 0 bytes .../styled-notifications/package.json | 58 - .../js_css_src/styled-notifications/readme.md | 82 - .../styled-notifications/src/helpers.js | 24 - .../styled-notifications/src/index.js | 148 - .../src/polyfills/classList.js | 68 - .../styled-notifications/src/style.scss | 134 - .../styled-notifications/webpack.config.js | 41 - examples/regex_patterns/.test.build_flags | 1 - examples/regex_patterns/regex_patterns.ino | 77 - examples/simple_server/simple_server.ino | 74 - extras/README.md | 25 - extras/do_ed_fs.bat | 9 - extras/do_emb.bat | 9 - extras/ehg.c | 124 - extras/ehg.exe | Bin 4096 -> 0 bytes extras/rehg.c | 101 - extras/rehg.exe | Bin 2560 -> 0 bytes extras/tmp1/placeholder | 0 extras/undo.bat | 4 - extras/update_ace.bat | 44 - library.json | 2 +- library.properties | 4 +- 123 files changed, 5 insertions(+), 15747 deletions(-) delete mode 100755 .github/scripts/install-arduino-core-esp32.sh delete mode 100644 .github/scripts/install-arduino-core-esp8266.sh delete mode 100755 .github/scripts/install-arduino-ide.sh delete mode 100644 .github/scripts/install-platformio.sh delete mode 100755 .github/scripts/on-push.sh delete mode 100644 .github/stale.yml delete mode 100644 .github/workflows/push.yml delete mode 100644 examples/CaptivePortal/CaptivePortal.ino delete mode 100644 examples/ESP_AsyncFSBrowser/ESP_AsyncFSBrowser.ino delete mode 100644 examples/ESP_AsyncFSBrowser/data/.exclude.files delete mode 100644 examples/ESP_AsyncFSBrowser/data/ace.ico.gz delete mode 100644 examples/ESP_AsyncFSBrowser/data/acefull.js.gz delete mode 100644 examples/ESP_AsyncFSBrowser/data/edit_gz delete mode 100644 examples/ESP_AsyncFSBrowser/data/favicon.ico delete mode 100644 examples/ESP_AsyncFSBrowser/data/folder/image.jpg delete mode 100644 examples/ESP_AsyncFSBrowser/data/folder/test.txt delete mode 100644 examples/ESP_AsyncFSBrowser/data/index.htm delete mode 100644 examples/ESP_AsyncFSBrowser/data/worker-css.js.gz delete mode 100644 examples/ESP_AsyncFSBrowser/data/worker-html.js.gz delete mode 100644 examples/ESP_AsyncFSBrowser/data/worker-javascript.js.gz delete mode 100644 examples/ESP_AsyncFSBrowser/data/worker-json.js.gz delete mode 100644 examples/SmartSwitch/1.PNG delete mode 100644 examples/SmartSwitch/2.PNG delete mode 100644 examples/SmartSwitch/3.PNG delete mode 100644 examples/SmartSwitch/4.PNG delete mode 100644 examples/SmartSwitch/ESPAsyncWiFiManager.cpp delete mode 100644 examples/SmartSwitch/ESPAsyncWiFiManager.h delete mode 100644 examples/SmartSwitch/PinOut_Notes.txt delete mode 100644 examples/SmartSwitch/README.md delete mode 100644 examples/SmartSwitch/SmartSwitch.ino delete mode 100644 examples/SmartSwitch/Xtea.cpp delete mode 100644 examples/SmartSwitch/Xtea.h delete mode 100644 examples/SmartSwitch/data/.exclude.files delete mode 100644 examples/SmartSwitch/data/ace.ico.gz delete mode 100644 examples/SmartSwitch/data/acefull.js.gz delete mode 100644 examples/SmartSwitch/data/app.css.gz delete mode 100644 examples/SmartSwitch/data/app.min.js.gz delete mode 100644 examples/SmartSwitch/data/edit_gz delete mode 100644 examples/SmartSwitch/data/favicon.ico.gz delete mode 100644 examples/SmartSwitch/data/index.htm delete mode 100644 examples/SmartSwitch/data/login/favicon.ico.gz delete mode 100644 examples/SmartSwitch/data/login/index.htm delete mode 100644 examples/SmartSwitch/data/worker-css.js.gz delete mode 100644 examples/SmartSwitch/data/worker-html.js.gz delete mode 100644 examples/SmartSwitch/data/worker-javascript.js.gz delete mode 100644 examples/SmartSwitch/data/worker-json.js.gz delete mode 100644 examples/SmartSwitch/data_src/.exclude.files delete mode 100644 examples/SmartSwitch/data_src/acefull.js delete mode 100644 examples/SmartSwitch/data_src/app.css delete mode 100644 examples/SmartSwitch/data_src/app.min.js delete mode 100644 examples/SmartSwitch/data_src/favicon.ico delete mode 100644 examples/SmartSwitch/data_src/index.htm delete mode 100644 examples/SmartSwitch/data_src/js_css_src/.exclude.files delete mode 100644 examples/SmartSwitch/data_src/js_css_src/ace-drafts/ace.js delete mode 100644 examples/SmartSwitch/data_src/js_css_src/ace-drafts/ext-searchbox.js delete mode 100644 examples/SmartSwitch/data_src/js_css_src/ace-drafts/mode-css.js delete mode 100644 examples/SmartSwitch/data_src/js_css_src/ace-drafts/mode-html.js delete mode 100644 examples/SmartSwitch/data_src/js_css_src/ace-drafts/mode-javascript.js delete mode 100644 examples/SmartSwitch/data_src/js_css_src/ace-drafts/worker-html.js delete mode 100644 examples/SmartSwitch/data_src/js_css_src/ace.js delete mode 100644 examples/SmartSwitch/data_src/js_css_src/app.js delete mode 100644 examples/SmartSwitch/data_src/js_css_src/js-time-picker/1-inline.html delete mode 100644 examples/SmartSwitch/data_src/js_css_src/js-time-picker/2-popup.html delete mode 100644 examples/SmartSwitch/data_src/js_css_src/js-time-picker/README.txt delete mode 100644 examples/SmartSwitch/data_src/js_css_src/js-time-picker/tpick-light-pop.css delete mode 100644 examples/SmartSwitch/data_src/js_css_src/js-time-picker/tpick-light.css delete mode 100644 examples/SmartSwitch/data_src/js_css_src/js-time-picker/tpick-pop.js delete mode 100644 examples/SmartSwitch/data_src/js_css_src/js-time-picker/tpick.js delete mode 100644 examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/auto-adjust.htm delete mode 100644 examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/counter.html delete mode 100644 examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/custom-interval.htm delete mode 100644 examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/custom-node.html delete mode 100644 examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/custom-sectors.html delete mode 100644 examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/custom-value-renderer.html delete mode 100644 examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/customize-style.htm delete mode 100644 examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/defaults.html delete mode 100644 examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/font-options.html delete mode 100644 examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/format-number.html delete mode 100644 examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/html5-data-attribute-config.html delete mode 100644 examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/human-friendly-numbers.html delete mode 100644 examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/pointer.html delete mode 100644 examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/refresh-maximum.html delete mode 100644 examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/responsive-gauges.htm delete mode 100644 examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/reverse.html delete mode 100644 examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/justgage.js delete mode 100644 examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/raphael-2.1.4.min.js delete mode 100644 examples/SmartSwitch/data_src/js_css_src/styled-notifications/.babelrc delete mode 100644 examples/SmartSwitch/data_src/js_css_src/styled-notifications/.eslintrc.js delete mode 100644 examples/SmartSwitch/data_src/js_css_src/styled-notifications/.gitignore delete mode 100644 examples/SmartSwitch/data_src/js_css_src/styled-notifications/.travis.yml delete mode 100644 examples/SmartSwitch/data_src/js_css_src/styled-notifications/LICENSE.md delete mode 100644 examples/SmartSwitch/data_src/js_css_src/styled-notifications/__tests__/helpers.test.js delete mode 100644 examples/SmartSwitch/data_src/js_css_src/styled-notifications/__tests__/index.tests.js delete mode 100644 examples/SmartSwitch/data_src/js_css_src/styled-notifications/demo/demo.js delete mode 100644 examples/SmartSwitch/data_src/js_css_src/styled-notifications/demo/index.html delete mode 100644 examples/SmartSwitch/data_src/js_css_src/styled-notifications/demo/index_my.html delete mode 100644 examples/SmartSwitch/data_src/js_css_src/styled-notifications/dist/notifications.css delete mode 100644 examples/SmartSwitch/data_src/js_css_src/styled-notifications/dist/notifications.css.gz delete mode 100644 examples/SmartSwitch/data_src/js_css_src/styled-notifications/dist/notifications.js delete mode 100644 examples/SmartSwitch/data_src/js_css_src/styled-notifications/dist/notifications.js.gz delete mode 100644 examples/SmartSwitch/data_src/js_css_src/styled-notifications/package.json delete mode 100644 examples/SmartSwitch/data_src/js_css_src/styled-notifications/readme.md delete mode 100644 examples/SmartSwitch/data_src/js_css_src/styled-notifications/src/helpers.js delete mode 100644 examples/SmartSwitch/data_src/js_css_src/styled-notifications/src/index.js delete mode 100644 examples/SmartSwitch/data_src/js_css_src/styled-notifications/src/polyfills/classList.js delete mode 100644 examples/SmartSwitch/data_src/js_css_src/styled-notifications/src/style.scss delete mode 100644 examples/SmartSwitch/data_src/js_css_src/styled-notifications/webpack.config.js delete mode 100644 examples/regex_patterns/.test.build_flags delete mode 100644 examples/regex_patterns/regex_patterns.ino delete mode 100644 examples/simple_server/simple_server.ino delete mode 100644 extras/README.md delete mode 100644 extras/do_ed_fs.bat delete mode 100644 extras/do_emb.bat delete mode 100644 extras/ehg.c delete mode 100644 extras/ehg.exe delete mode 100644 extras/rehg.c delete mode 100644 extras/rehg.exe delete mode 100644 extras/tmp1/placeholder delete mode 100644 extras/undo.bat delete mode 100644 extras/update_ace.bat diff --git a/.github/scripts/install-arduino-core-esp32.sh b/.github/scripts/install-arduino-core-esp32.sh deleted file mode 100755 index cf1026d6a..000000000 --- a/.github/scripts/install-arduino-core-esp32.sh +++ /dev/null @@ -1,36 +0,0 @@ -#!/bin/bash - -export ARDUINO_ESP32_PATH="$ARDUINO_USR_PATH/hardware/espressif/esp32" -if [ ! -d "$ARDUINO_ESP32_PATH" ]; then - echo "Installing ESP32 Arduino Core ..." - script_init_path="$PWD" - mkdir -p "$ARDUINO_USR_PATH/hardware/espressif" - cd "$ARDUINO_USR_PATH/hardware/espressif" - - echo "Installing Python Serial ..." - pip install pyserial > /dev/null - - if [ "$OS_IS_WINDOWS" == "1" ]; then - echo "Installing Python Requests ..." - pip install requests > /dev/null - fi - - if [ "$GITHUB_REPOSITORY" == "espressif/arduino-esp32" ]; then - echo "Linking Core..." - ln -s $GITHUB_WORKSPACE esp32 - else - echo "Cloning Core Repository..." - git clone https://github.com/espressif/arduino-esp32.git esp32 > /dev/null 2>&1 - fi - - echo "Updating Submodules ..." - cd esp32 - git submodule update --init --recursive > /dev/null 2>&1 - - echo "Installing Platform Tools ..." - cd tools && python get.py - cd $script_init_path - - echo "ESP32 Arduino has been installed in '$ARDUINO_ESP32_PATH'" - echo "" -fi diff --git a/.github/scripts/install-arduino-core-esp8266.sh b/.github/scripts/install-arduino-core-esp8266.sh deleted file mode 100644 index 048cd0246..000000000 --- a/.github/scripts/install-arduino-core-esp8266.sh +++ /dev/null @@ -1,29 +0,0 @@ -#!/bin/bash - -echo "Installing ESP8266 Arduino Core ..." -script_init_path="$PWD" -mkdir -p "$ARDUINO_USR_PATH/hardware/esp8266com" -cd "$ARDUINO_USR_PATH/hardware/esp8266com" - -echo "Installing Python Serial ..." -pip install pyserial > /dev/null - -if [ "$OS_IS_WINDOWS" == "1" ]; then - echo "Installing Python Requests ..." - pip install requests > /dev/null -fi - -echo "Cloning Core Repository ..." -git clone https://github.com/esp8266/Arduino.git esp8266 > /dev/null 2>&1 - -echo "Updating submodules ..." -cd esp8266 -git submodule update --init --recursive > /dev/null 2>&1 - -echo "Installing Platform Tools ..." -cd tools -python get.py > /dev/null -cd $script_init_path - -echo "ESP8266 Arduino has been installed in '$ARDUINO_USR_PATH/hardware/esp8266com'" -echo "" diff --git a/.github/scripts/install-arduino-ide.sh b/.github/scripts/install-arduino-ide.sh deleted file mode 100755 index ce60cb82f..000000000 --- a/.github/scripts/install-arduino-ide.sh +++ /dev/null @@ -1,228 +0,0 @@ -#!/bin/bash - -#OSTYPE: 'linux-gnu', ARCH: 'x86_64' => linux64 -#OSTYPE: 'msys', ARCH: 'x86_64' => win32 -#OSTYPE: 'darwin18', ARCH: 'i386' => macos - -OSBITS=`arch` -if [[ "$OSTYPE" == "linux"* ]]; then - export OS_IS_LINUX="1" - ARCHIVE_FORMAT="tar.xz" - if [[ "$OSBITS" == "i686" ]]; then - OS_NAME="linux32" - elif [[ "$OSBITS" == "x86_64" ]]; then - OS_NAME="linux64" - elif [[ "$OSBITS" == "armv7l" || "$OSBITS" == "aarch64" ]]; then - OS_NAME="linuxarm" - else - OS_NAME="$OSTYPE-$OSBITS" - echo "Unknown OS '$OS_NAME'" - exit 1 - fi -elif [[ "$OSTYPE" == "darwin"* ]]; then - export OS_IS_MACOS="1" - ARCHIVE_FORMAT="zip" - OS_NAME="macosx" -elif [[ "$OSTYPE" == "cygwin" ]] || [[ "$OSTYPE" == "msys" ]] || [[ "$OSTYPE" == "win32" ]]; then - export OS_IS_WINDOWS="1" - ARCHIVE_FORMAT="zip" - OS_NAME="windows" -else - OS_NAME="$OSTYPE-$OSBITS" - echo "Unknown OS '$OS_NAME'" - exit 1 -fi -export OS_NAME - -ARDUINO_BUILD_DIR="$HOME/.arduino/build.tmp" -ARDUINO_CACHE_DIR="$HOME/.arduino/cache.tmp" - -if [ "$OS_IS_MACOS" == "1" ]; then - export ARDUINO_IDE_PATH="/Applications/Arduino.app/Contents/Java" - export ARDUINO_USR_PATH="$HOME/Documents/Arduino" -elif [ "$OS_IS_WINDOWS" == "1" ]; then - export ARDUINO_IDE_PATH="$HOME/arduino_ide" - export ARDUINO_USR_PATH="$HOME/Documents/Arduino" -else - export ARDUINO_IDE_PATH="$HOME/arduino_ide" - export ARDUINO_USR_PATH="$HOME/Arduino" -fi - -if [ ! -d "$ARDUINO_IDE_PATH" ]; then - echo "Installing Arduino IDE on $OS_NAME ..." - echo "Downloading 'arduino-nightly-$OS_NAME.$ARCHIVE_FORMAT' to 'arduino.$ARCHIVE_FORMAT' ..." - if [ "$OS_IS_LINUX" == "1" ]; then - wget -O "arduino.$ARCHIVE_FORMAT" "https://www.arduino.cc/download.php?f=/arduino-nightly-$OS_NAME.$ARCHIVE_FORMAT" > /dev/null 2>&1 - echo "Extracting 'arduino.$ARCHIVE_FORMAT' ..." - tar xf "arduino.$ARCHIVE_FORMAT" > /dev/null - mv arduino-nightly "$ARDUINO_IDE_PATH" - else - curl -o "arduino.$ARCHIVE_FORMAT" -L "https://www.arduino.cc/download.php?f=/arduino-nightly-$OS_NAME.$ARCHIVE_FORMAT" > /dev/null 2>&1 - echo "Extracting 'arduino.$ARCHIVE_FORMAT' ..." - unzip "arduino.$ARCHIVE_FORMAT" > /dev/null - if [ "$OS_IS_MACOS" == "1" ]; then - mv "Arduino.app" "/Applications/Arduino.app" - else - mv arduino-nightly "$ARDUINO_IDE_PATH" - fi - fi - rm -rf "arduino.$ARCHIVE_FORMAT" - - mkdir -p "$ARDUINO_USR_PATH/libraries" - mkdir -p "$ARDUINO_USR_PATH/hardware" - - echo "Arduino IDE Installed in '$ARDUINO_IDE_PATH'" - echo "" -fi - -function build_sketch(){ # build_sketch [extra-options] - if [ "$#" -lt 2 ]; then - echo "ERROR: Illegal number of parameters" - echo "USAGE: build_sketch [extra-options]" - return 1 - fi - - local fqbn="$1" - local sketch="$2" - local build_flags="$3" - local xtra_opts="$4" - local win_opts="" - if [ "$OS_IS_WINDOWS" == "1" ]; then - local ctags_version=`ls "$ARDUINO_IDE_PATH/tools-builder/ctags/"` - local preprocessor_version=`ls "$ARDUINO_IDE_PATH/tools-builder/arduino-preprocessor/"` - win_opts="-prefs=runtime.tools.ctags.path=$ARDUINO_IDE_PATH/tools-builder/ctags/$ctags_version -prefs=runtime.tools.arduino-preprocessor.path=$ARDUINO_IDE_PATH/tools-builder/arduino-preprocessor/$preprocessor_version" - fi - - echo "" - echo "Compiling '"$(basename "$sketch")"' ..." - mkdir -p "$ARDUINO_BUILD_DIR" - mkdir -p "$ARDUINO_CACHE_DIR" - $ARDUINO_IDE_PATH/arduino-builder -compile -logger=human -core-api-version=10810 \ - -fqbn=$fqbn \ - -warnings="all" \ - -tools "$ARDUINO_IDE_PATH/tools-builder" \ - -tools "$ARDUINO_IDE_PATH/tools" \ - -built-in-libraries "$ARDUINO_IDE_PATH/libraries" \ - -hardware "$ARDUINO_IDE_PATH/hardware" \ - -hardware "$ARDUINO_USR_PATH/hardware" \ - -libraries "$ARDUINO_USR_PATH/libraries" \ - -build-cache "$ARDUINO_CACHE_DIR" \ - -build-path "$ARDUINO_BUILD_DIR" \ - -prefs=compiler.cpp.extra_flags="$build_flags" \ - $win_opts $xtra_opts "$sketch" -} - -function count_sketches() # count_sketches -{ - local examples="$1" - rm -rf sketches.txt - if [ ! -d "$examples" ]; then - touch sketches.txt - return 0 - fi - local sketches=$(find $examples -name *.ino) - local sketchnum=0 - for sketch in $sketches; do - local sketchdir=$(dirname $sketch) - local sketchdirname=$(basename $sketchdir) - local sketchname=$(basename $sketch) - if [[ "${sketchdirname}.ino" != "$sketchname" ]]; then - continue - fi; - if [[ -f "$sketchdir/.test.skip" ]]; then - continue - fi - echo $sketch >> sketches.txt - sketchnum=$(($sketchnum + 1)) - done - return $sketchnum -} - -function build_sketches() # build_sketches [extra-options] -{ - local fqbn=$1 - local examples=$2 - local chunk_idex=$3 - local chunks_num=$4 - local xtra_opts=$5 - - if [ "$#" -lt 2 ]; then - echo "ERROR: Illegal number of parameters" - echo "USAGE: build_sketches [ ] [extra-options]" - return 1 - fi - - if [ "$#" -lt 4 ]; then - chunk_idex="0" - chunks_num="1" - xtra_opts=$3 - fi - - if [ "$chunks_num" -le 0 ]; then - echo "ERROR: Chunks count must be positive number" - return 1 - fi - if [ "$chunk_idex" -ge "$chunks_num" ]; then - echo "ERROR: Chunk index must be less than chunks count" - return 1 - fi - - set +e - count_sketches "$examples" - local sketchcount=$? - set -e - local sketches=$(cat sketches.txt) - rm -rf sketches.txt - - local chunk_size=$(( $sketchcount / $chunks_num )) - local all_chunks=$(( $chunks_num * $chunk_size )) - if [ "$all_chunks" -lt "$sketchcount" ]; then - chunk_size=$(( $chunk_size + 1 )) - fi - - local start_index=$(( $chunk_idex * $chunk_size )) - if [ "$sketchcount" -le "$start_index" ]; then - echo "Skipping job" - return 0 - fi - - local end_index=$(( $(( $chunk_idex + 1 )) * $chunk_size )) - if [ "$end_index" -gt "$sketchcount" ]; then - end_index=$sketchcount - fi - - local start_num=$(( $start_index + 1 )) - echo "Found $sketchcount Sketches"; - echo "Chunk Count : $chunks_num" - echo "Chunk Size : $chunk_size" - echo "Start Sketch: $start_num" - echo "End Sketch : $end_index" - - local sketchnum=0 - for sketch in $sketches; do - local sketchdir=$(dirname $sketch) - local sketchdirname=$(basename $sketchdir) - local sketchname=$(basename $sketch) - if [ "${sketchdirname}.ino" != "$sketchname" ] \ - || [ -f "$sketchdir/.test.skip" ]; then - continue - fi - sketchnum=$(($sketchnum + 1)) - if [ "$sketchnum" -le "$start_index" ] \ - || [ "$sketchnum" -gt "$end_index" ]; then - continue - fi - local sketchBuildFlags="" - if [ -f "$sketchdir/.test.build_flags" ]; then - while read line; do - sketchBuildFlags="$sketchBuildFlags $line" - done < "$sketchdir/.test.build_flags" - fi - build_sketch "$fqbn" "$sketch" "$sketchBuildFlags" "$xtra_opts" - local result=$? - if [ $result -ne 0 ]; then - return $result - fi - done - return 0 -} diff --git a/.github/scripts/install-platformio.sh b/.github/scripts/install-platformio.sh deleted file mode 100644 index 594948ea4..000000000 --- a/.github/scripts/install-platformio.sh +++ /dev/null @@ -1,140 +0,0 @@ -#!/bin/bash - -echo "Installing Python Wheel ..." -pip install wheel > /dev/null 2>&1 - -echo "Installing PlatformIO ..." -pip install -U platformio > /dev/null 2>&1 - -echo "PlatformIO has been installed" -echo "" - - -function build_pio_sketch(){ # build_pio_sketch - if [ "$#" -lt 3 ]; then - echo "ERROR: Illegal number of parameters" - echo "USAGE: build_pio_sketch " - return 1 - fi - - local board="$1" - local sketch="$2" - local buildFlags="$3" - local sketch_dir=$(dirname "$sketch") - echo "" - echo "Compiling '"$(basename "$sketch")"' ..." - python -m platformio ci -l '.' --board "$board" "$sketch_dir" --project-option="board_build.partitions = huge_app.csv" --project-option="build_flags=$buildFlags" -} - -function count_sketches() # count_sketches -{ - local examples="$1" - rm -rf sketches.txt - if [ ! -d "$examples" ]; then - touch sketches.txt - return 0 - fi - local sketches=$(find $examples -name *.ino) - local sketchnum=0 - for sketch in $sketches; do - local sketchdir=$(dirname $sketch) - local sketchdirname=$(basename $sketchdir) - local sketchname=$(basename $sketch) - if [[ "${sketchdirname}.ino" != "$sketchname" ]]; then - continue - fi; - if [[ -f "$sketchdir/.test.skip" ]]; then - continue - fi - echo $sketch >> sketches.txt - sketchnum=$(($sketchnum + 1)) - done - return $sketchnum -} - -function build_pio_sketches() # build_pio_sketches -{ - if [ "$#" -lt 2 ]; then - echo "ERROR: Illegal number of parameters" - echo "USAGE: build_pio_sketches [ ]" - return 1 - fi - - local board=$1 - local examples=$2 - local chunk_idex=$3 - local chunks_num=$4 - - if [ "$#" -lt 4 ]; then - chunk_idex="0" - chunks_num="1" - fi - - if [ "$chunks_num" -le 0 ]; then - echo "ERROR: Chunks count must be positive number" - return 1 - fi - if [ "$chunk_idex" -ge "$chunks_num" ]; then - echo "ERROR: Chunk index must be less than chunks count" - return 1 - fi - - set +e - count_sketches "$examples" - local sketchcount=$? - set -e - local sketches=$(cat sketches.txt) - rm -rf sketches.txt - - local chunk_size=$(( $sketchcount / $chunks_num )) - local all_chunks=$(( $chunks_num * $chunk_size )) - if [ "$all_chunks" -lt "$sketchcount" ]; then - chunk_size=$(( $chunk_size + 1 )) - fi - - local start_index=$(( $chunk_idex * $chunk_size )) - if [ "$sketchcount" -le "$start_index" ]; then - echo "Skipping job" - return 0 - fi - - local end_index=$(( $(( $chunk_idex + 1 )) * $chunk_size )) - if [ "$end_index" -gt "$sketchcount" ]; then - end_index=$sketchcount - fi - - local start_num=$(( $start_index + 1 )) - echo "Found $sketchcount Sketches"; - echo "Chunk Count : $chunks_num" - echo "Chunk Size : $chunk_size" - echo "Start Sketch: $start_num" - echo "End Sketch : $end_index" - - local sketchnum=0 - for sketch in $sketches; do - local sketchdir=$(dirname $sketch) - local sketchdirname=$(basename $sketchdir) - local sketchname=$(basename $sketch) - if [ "${sketchdirname}.ino" != "$sketchname" ] \ - || [ -f "$sketchdir/.test.skip" ]; then - continue - fi - local sketchBuildFlags="" - if [ -f "$sketchdir/.test.build_flags" ]; then - while read line; do - sketchBuildFlags="$sketchBuildFlags $line" - done < "$sketchdir/.test.build_flags" - fi - sketchnum=$(($sketchnum + 1)) - if [ "$sketchnum" -le "$start_index" ] \ - || [ "$sketchnum" -gt "$end_index" ]; then - continue - fi - build_pio_sketch "$board" "$sketch" "$sketchBuildFlags" - local result=$? - if [ $result -ne 0 ]; then - return $result - fi - done - return 0 -} diff --git a/.github/scripts/on-push.sh b/.github/scripts/on-push.sh deleted file mode 100755 index 1eedd0779..000000000 --- a/.github/scripts/on-push.sh +++ /dev/null @@ -1,75 +0,0 @@ -#!/bin/bash - -set -e - -if [ ! -z "$TRAVIS_BUILD_DIR" ]; then - export GITHUB_WORKSPACE="$TRAVIS_BUILD_DIR" - export GITHUB_REPOSITORY="$TRAVIS_REPO_SLUG" -elif [ -z "$GITHUB_WORKSPACE" ]; then - export GITHUB_WORKSPACE="$PWD" - export GITHUB_REPOSITORY="lorol/ESPAsyncWebServer" -fi - -TARGET_PLATFORM="$1" -CHUNK_INDEX=$2 -CHUNKS_CNT=$3 -BUILD_PIO=0 -if [ "$#" -lt 1 ]; then - TARGET_PLATFORM="esp32" -fi -if [ "$#" -lt 3 ] || [ "$CHUNKS_CNT" -le 0 ]; then - CHUNK_INDEX=0 - CHUNKS_CNT=1 -elif [ "$CHUNK_INDEX" -gt "$CHUNKS_CNT" ]; then - CHUNK_INDEX=$CHUNKS_CNT -elif [ "$CHUNK_INDEX" -eq "$CHUNKS_CNT" ]; then - BUILD_PIO=1 -fi - -if [ "$BUILD_PIO" -eq 0 ]; then - # ArduinoIDE Test - source ./.github/scripts/install-arduino-ide.sh - - echo "Installing ESPAsyncWebServer ..." - cp -rf "$GITHUB_WORKSPACE" "$ARDUINO_USR_PATH/libraries/ESPAsyncWebServer" - echo "Installing ArduinoJson ..." - git clone https://github.com/bblanchon/ArduinoJson "$ARDUINO_USR_PATH/libraries/ArduinoJson" > /dev/null 2>&1 - echo "Installing DHT sensor library ..." - git clone https://github.com/adafruit/DHT-sensor-library "$ARDUINO_USR_PATH/libraries/DHT-sensor-library" > /dev/null 2>&1 - - if [[ "$TARGET_PLATFORM" == "esp32" ]]; then - echo "Installing LITTLEFS for ESP32 ..." - git clone https://github.com/lorol/LITTLEFS "$ARDUINO_USR_PATH/libraries/LITTLEFS" > /dev/null 2>&1 - echo "Installing AsyncTCP ..." - git clone https://github.com/me-no-dev/AsyncTCP "$ARDUINO_USR_PATH/libraries/AsyncTCP" > /dev/null 2>&1 - FQBN="espressif:esp32:esp32:PSRAM=enabled,PartitionScheme=huge_app" - source ./.github/scripts/install-arduino-core-esp32.sh - echo "BUILDING ESP32 EXAMPLES" - else - echo "Installing ESPAsyncTCP ..." - git clone https://github.com/me-no-dev/ESPAsyncTCP "$ARDUINO_USR_PATH/libraries/ESPAsyncTCP" > /dev/null 2>&1 - FQBN="esp8266com:esp8266:generic:eesz=4M1M,ip=lm2f" - source ./.github/scripts/install-arduino-core-esp8266.sh - echo "BUILDING ESP8266 EXAMPLES" - fi - build_sketches "$FQBN" "$GITHUB_WORKSPACE/examples" "$CHUNK_INDEX" "$CHUNKS_CNT" -else - # PlatformIO Test - source ./.github/scripts/install-platformio.sh - - python -m platformio lib --storage-dir "$GITHUB_WORKSPACE" install - echo "Installing ArduinoJson ..." - python -m platformio lib -g install https://github.com/bblanchon/ArduinoJson.git > /dev/null 2>&1 - if [[ "$TARGET_PLATFORM" == "esp32" ]]; then - BOARD="esp32dev" - echo "Installing AsyncTCP ..." - python -m platformio lib -g install https://github.com/me-no-dev/AsyncTCP.git > /dev/null 2>&1 - echo "BUILDING ESP32 EXAMPLES" - else - BOARD="esp12e" - echo "Installing ESPAsyncTCP ..." - python -m platformio lib -g install https://github.com/me-no-dev/ESPAsyncTCP.git > /dev/null 2>&1 - echo "BUILDING ESP8266 EXAMPLES" - fi - build_pio_sketches "$BOARD" "$GITHUB_WORKSPACE/examples" -fi diff --git a/.github/stale.yml b/.github/stale.yml deleted file mode 100644 index ce7a8e3f7..000000000 --- a/.github/stale.yml +++ /dev/null @@ -1,31 +0,0 @@ -# Configuration for probot-stale - https://github.com/probot/stale - -daysUntilStale: 60 -daysUntilClose: 14 -limitPerRun: 30 -staleLabel: stale -exemptLabels: - - pinned - - security - - "to be implemented" - - "for reference" - - "move to PR" - - "enhancement" - -only: issues -onlyLabels: [] -exemptProjects: false -exemptMilestones: false -exemptAssignees: false - -markComment: > - [STALE_SET] This issue has been automatically marked as stale because it has not had - recent activity. It will be closed in 14 days if no further activity occurs. Thank you - for your contributions. - -unmarkComment: > - [STALE_CLR] This issue has been removed from the stale queue. Please ensure activity to keep it openin the future. - -closeComment: > - [STALE_DEL] This stale issue has been automatically closed. Thank you for your contributions. - diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml deleted file mode 100644 index 231dc5292..000000000 --- a/.github/workflows/push.yml +++ /dev/null @@ -1,34 +0,0 @@ -name: ESP Async Web Server CI - -on: - push: - branches: - - master - - release/* - pull_request: - -jobs: - - build-arduino: - name: Arduino for ${{ matrix.board }} on ${{ matrix.os }} - runs-on: ${{ matrix.os }} - strategy: - matrix: - os: [ubuntu-latest, windows-latest, macOS-latest] - board: [esp32, esp8266] - steps: - - uses: actions/checkout@v1 - - name: Build Tests - run: bash ./.github/scripts/on-push.sh ${{ matrix.board }} 0 1 - -# build-pio: -# name: PlatformIO for ${{ matrix.board }} on ${{ matrix.os }} -# runs-on: ${{ matrix.os }} -# strategy: -# matrix: -# os: [ubuntu-latest, windows-latest, macOS-latest] -# board: [esp32, esp8266] -# steps: -# - uses: actions/checkout@v1 -# - name: Build Tests -# run: bash ./.github/scripts/on-push.sh ${{ matrix.board }} 1 1 diff --git a/README.md b/README.md index d3d3cf91b..fd2c61091 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # In this fork - SPIFFSEditor modifications -- Added [extras](https://github.com/lorol/ESPAsyncWebServer/tree/master/extras) folder with (Win) tools for re-packing, editing, updating and compressing html to binary arrays embedded to source -- Added a [SmartSwitch](https://github.com/lorol/ESPAsyncWebServer/tree/master/examples/SmartSwitch) example to test code features +- Added [extras](https://github.com/mathieucarbou/ESPAsyncWebServer/tree/master/extras) folder with (Win) tools for re-packing, editing, updating and compressing html to binary arrays embedded to source +- Added a [SmartSwitch](https://github.com/mathieucarbou/ESPAsyncWebServer/tree/master/examples/SmartSwitch) example to test code features - Applied the memory optimizations from [sascha432](https://github.com/sascha432/ESPAsyncWebServer) fork - Cookie Authentication including on Websocket part, based on [ayushsharma82](https://github.com/me-no-dev/ESPAsyncWebServer/pull/684) PR, new functions added: - For Websocket: ```void handleHandshake(AwsHandshakeHandler handler) ``` diff --git a/examples/CaptivePortal/CaptivePortal.ino b/examples/CaptivePortal/CaptivePortal.ino deleted file mode 100644 index f97f142a6..000000000 --- a/examples/CaptivePortal/CaptivePortal.ino +++ /dev/null @@ -1,47 +0,0 @@ -#include -#ifdef ESP32 -#include -#include -#elif defined(ESP8266) -#include -#include -#endif -#include "ESPAsyncWebServer.h" - -DNSServer dnsServer; -AsyncWebServer server(80); - -class CaptiveRequestHandler : public AsyncWebHandler { -public: - CaptiveRequestHandler() {} - virtual ~CaptiveRequestHandler() {} - - bool canHandle(AsyncWebServerRequest *request){ - //request->addInterestingHeader("ANY"); - return true; - } - - void handleRequest(AsyncWebServerRequest *request) { - AsyncResponseStream *response = request->beginResponseStream("text/html"); - response->print("Captive Portal"); - response->print("

This is out captive portal front page.

"); - response->printf("

You were trying to reach: http://%s%s

", request->host().c_str(), request->url().c_str()); - response->printf("
", WiFi.softAPIP().toString().c_str()); - response->print(""); - request->send(response); - } -}; - - -void setup(){ - //your other setup stuff... - WiFi.softAP("esp-captive"); - dnsServer.start(53, "*", WiFi.softAPIP()); - server.addHandler(new CaptiveRequestHandler()).setFilter(ON_AP_FILTER);//only when requested from AP - //more handlers... - server.begin(); -} - -void loop(){ - dnsServer.processNextRequest(); -} diff --git a/examples/ESP_AsyncFSBrowser/ESP_AsyncFSBrowser.ino b/examples/ESP_AsyncFSBrowser/ESP_AsyncFSBrowser.ino deleted file mode 100644 index 3381b9feb..000000000 --- a/examples/ESP_AsyncFSBrowser/ESP_AsyncFSBrowser.ino +++ /dev/null @@ -1,257 +0,0 @@ -// Defaulut is SPIFFS, FatFS: only on ESP32, also choose partition scheme w/ ffat. -// Comment 2 lines below or uncomment only one of them - -//#define USE_LittleFS -//#define USE_FatFS // Only ESP32 - -#include -#ifdef ESP32 - #include - #ifdef USE_LittleFS - #define MYFS LITTLEFS - #include "LITTLEFS.h" - #elif defined(USE_FatFS) - #define MYFS FFat - #include "FFat.h" - #else - #define MYFS SPIFFS - #include - #endif - #include - #include - #include -#elif defined(ESP8266) - #ifdef USE_LittleFS - #include - #define MYFS LittleFS - #include - #elif defined(USE_FatFS) - #error "FatFS only on ESP32 for now!" - #else - #define MYFS SPIFFS - #endif - #include - #include - #include -#endif -#include -#include - - -// SKETCH BEGIN -AsyncWebServer server(80); -AsyncWebSocket ws("/ws"); -AsyncEventSource events("/events"); - -void onWsEvent(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventType type, void * arg, uint8_t *data, size_t len){ - if(type == WS_EVT_CONNECT){ - Serial.printf("ws[%s][%u] connect\n", server->url(), client->id()); - client->printf("Hello Client %u :)", client->id()); - client->ping(); - } else if(type == WS_EVT_DISCONNECT){ - Serial.printf("ws[%s][%u] disconnect\n", server->url(), client->id()); - } else if(type == WS_EVT_ERROR){ - Serial.printf("ws[%s][%u] error(%u): %s\n", server->url(), client->id(), *((uint16_t*)arg), (char*)data); - } else if(type == WS_EVT_PONG){ - Serial.printf("ws[%s][%u] pong[%u]: %s\n", server->url(), client->id(), len, (len)?(char*)data:""); - } else if(type == WS_EVT_DATA){ - AwsFrameInfo * info = (AwsFrameInfo*)arg; - String msg = ""; - if(info->final && info->index == 0 && info->len == len){ - //the whole message is in a single frame and we got all of it's data - Serial.printf("ws[%s][%u] %s-message[%llu]: ", server->url(), client->id(), (info->opcode == WS_TEXT)?"text":"binary", info->len); - - if(info->opcode == WS_TEXT){ - for(size_t i=0; i < info->len; i++) { - msg += (char) data[i]; - } - } else { - char buff[3]; - for(size_t i=0; i < info->len; i++) { - sprintf(buff, "%02x ", (uint8_t) data[i]); - msg += buff ; - } - } - Serial.printf("%s\n",msg.c_str()); - - if(info->opcode == WS_TEXT) - client->text("I got your text message"); - else - client->binary("I got your binary message"); - } else { - //message is comprised of multiple frames or the frame is split into multiple packets - if(info->index == 0){ - if(info->num == 0) - Serial.printf("ws[%s][%u] %s-message start\n", server->url(), client->id(), (info->message_opcode == WS_TEXT)?"text":"binary"); - Serial.printf("ws[%s][%u] frame[%u] start[%llu]\n", server->url(), client->id(), info->num, info->len); - } - - Serial.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 < len; i++) { - msg += (char) data[i]; - } - } else { - char buff[3]; - for(size_t i=0; i < len; i++) { - sprintf(buff, "%02x ", (uint8_t) data[i]); - msg += buff ; - } - } - Serial.printf("%s\n",msg.c_str()); - - if((info->index + len) == info->len){ - Serial.printf("ws[%s][%u] frame[%u] end[%llu]\n", server->url(), client->id(), info->num, info->len); - if(info->final){ - Serial.printf("ws[%s][%u] %s-message end\n", server->url(), client->id(), (info->message_opcode == WS_TEXT)?"text":"binary"); - if(info->message_opcode == WS_TEXT) - client->text("I got your text message"); - else - client->binary("I got your binary message"); - } - } - } - } -} - -const char* ssid = "*****"; -const char* password = "*****"; -const char* hostName = "esp-async"; -const char* http_username = "admin"; -const char* http_password = "admin"; - -void setup(){ - Serial.begin(115200); - Serial.setDebugOutput(true); - WiFi.mode(WIFI_AP_STA); - WiFi.softAP(hostName); - WiFi.begin(ssid, password); - if (WiFi.waitForConnectResult() != WL_CONNECTED) { - Serial.printf("STA: Failed!\n"); - WiFi.disconnect(false); - delay(1000); - WiFi.begin(ssid, password); - } - - Serial.print(F("*CONNECTED* IP:")); - Serial.println(WiFi.localIP()); - - //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.setHostname(hostName); - ArduinoOTA.begin(); - - MDNS.addService("http","tcp",80); - -//FS -#ifdef USE_FatFS - if (MYFS.begin(false,"/ffat",3)) { //limit the RAM usage, bottom line 8kb + 4kb takes per each file, default is 10 -#else - if (MYFS.begin()) { -#endif - Serial.print(F("FS mounted\n")); - } else { - Serial.print(F("FS mount failed\n")); - } - - ws.onEvent(onWsEvent); - server.addHandler(&ws); - - events.onConnect([](AsyncEventSourceClient *client){ - client->send("hello!",NULL,millis(),1000); - }); - server.addHandler(&events); - -#ifdef ESP32 - server.addHandler(new SPIFFSEditor(MYFS, http_username,http_password)); -#elif defined(ESP8266) - server.addHandler(new SPIFFSEditor(http_username,http_password, MYFS)); -#endif - - server.on("/heap", HTTP_GET, [](AsyncWebServerRequest *request){ - request->send(200, "text/plain", String(ESP.getFreeHeap())); - }); - - server.serveStatic("/", MYFS, "/").setDefaultFile("index.htm"); - - server.onNotFound([](AsyncWebServerRequest *request){ - Serial.printf("NOT_FOUND: "); - if(request->method() == HTTP_GET) - Serial.printf("GET"); - else if(request->method() == HTTP_POST) - Serial.printf("POST"); - else if(request->method() == HTTP_DELETE) - Serial.printf("DELETE"); - else if(request->method() == HTTP_PUT) - Serial.printf("PUT"); - else if(request->method() == HTTP_PATCH) - Serial.printf("PATCH"); - else if(request->method() == HTTP_HEAD) - Serial.printf("HEAD"); - else if(request->method() == HTTP_OPTIONS) - Serial.printf("OPTIONS"); - else - Serial.printf("UNKNOWN"); - Serial.printf(" http://%s%s\n", request->host().c_str(), request->url().c_str()); - - if(request->contentLength()){ - Serial.printf("_CONTENT_TYPE: %s\n", request->contentType().c_str()); - Serial.printf("_CONTENT_LENGTH: %u\n", request->contentLength()); - } - - int headers = request->headers(); - int i; - for(i=0;igetHeader(i); - Serial.printf("_HEADER[%s]: %s\n", h->name().c_str(), h->value().c_str()); - } - - int params = request->params(); - for(i=0;igetParam(i); - if(p->isFile()){ - Serial.printf("_FILE[%s]: %s, size: %u\n", p->name().c_str(), p->value().c_str(), p->size()); - } else if(p->isPost()){ - Serial.printf("_POST[%s]: %s\n", p->name().c_str(), p->value().c_str()); - } else { - Serial.printf("_GET[%s]: %s\n", p->name().c_str(), p->value().c_str()); - } - } - - request->send(404); - }); - server.onFileUpload([](AsyncWebServerRequest *request, const String& filename, size_t index, uint8_t *data, size_t len, bool final){ - if(!index) - Serial.printf("UploadStart: %s\n", filename.c_str()); - Serial.printf("%s", (const char*)data); - if(final) - Serial.printf("UploadEnd: %s (%u)\n", filename.c_str(), index+len); - }); - server.onRequestBody([](AsyncWebServerRequest *request, uint8_t *data, size_t len, size_t index, size_t total){ - if(!index) - Serial.printf("BodyStart: %u\n", total); - Serial.printf("%s", (const char*)data); - if(index + len == total) - Serial.printf("BodyEnd: %u\n", total); - }); - server.begin(); -} - -void loop(){ - ArduinoOTA.handle(); - ws.cleanupClients(); -} diff --git a/examples/ESP_AsyncFSBrowser/data/.exclude.files b/examples/ESP_AsyncFSBrowser/data/.exclude.files deleted file mode 100644 index a1c42787a..000000000 --- a/examples/ESP_AsyncFSBrowser/data/.exclude.files +++ /dev/null @@ -1,3 +0,0 @@ -/*.gz -/edit_gz -/.exclude.files diff --git a/examples/ESP_AsyncFSBrowser/data/ace.ico.gz b/examples/ESP_AsyncFSBrowser/data/ace.ico.gz deleted file mode 100644 index 49e15bcebdeba0b55db396e5b6266b6e72730070..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6307 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 diff --git a/examples/ESP_AsyncFSBrowser/data/favicon.ico b/examples/ESP_AsyncFSBrowser/data/favicon.ico deleted file mode 100644 index 71b25fe6ee6012a4c26602977262d217af885520..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1150 zcmd5)T}YZ?6n@3p3@y{hrv0dyWg4`Ks8LiSs1Zp~iZo)Ag)vw}5=AXod1FBkBZ8nH zm^Z-|?V=!w1lNUBASeXo@J`0^VlWvo2dii2d%G#v{l>?6f6jZJbDr~@k1-K_xw(v1 z9ebI0x7Iqot*#Mb_8XCpMW( zReHVNRa#m)qtR%dYqeVa%E}7s=;*k^yt%pgaZOFlCyT}Mt)ikLSyomSAdHVNiTwQh zYlT9AoSdAi?Ck6_l}cqxrBb4{wllAZC#W|h5(!LCPa_ZrfO4a^w-*$T#l=O$<8hpvoWSq* zr+q%3e_~?7OnSW+IMa^f<71qjo??H0AF)^rR;v~3>+77){QNxD*47Y-M377-5sgNF zZ*FeBB8@*378YW1auP>JN7&xpMmQYC!NCEBhljDWw8S}YZEay}Y>emI+uIY~)4^cy z8F70`_|(9_00svKF*G!U(a}+OJRTk|_-LM-)6~=yc6N5SQH{@((@6bGii?Y1E0xNx zGMVg3&{-mpfX*l>DM4Lb9lE=_xgNW_yPVhI;UPky&|8{|m^5NE!wk}(ie_b}IlBq} zMVOVKdwqR9$B&PX3*3JY_m9Nk&GPc{gN==iJO5F2bv2uvofXmS?P|3;LfBta`3zy6F#O-#g&(F`<>gww4@PB>= d7!xdbpRqYH(Gg7acUp7g|4wmf`3*+E{Q*gMMA`rV diff --git a/examples/ESP_AsyncFSBrowser/data/folder/image.jpg b/examples/ESP_AsyncFSBrowser/data/folder/image.jpg deleted file mode 100644 index 3224d5aa7952d8825f61de9ac1d8834792b15d4d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6071 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 - - - - - WebSocketTester - - - - -

-    
- $ -
- - diff --git a/examples/ESP_AsyncFSBrowser/data/worker-css.js.gz b/examples/ESP_AsyncFSBrowser/data/worker-css.js.gz deleted file mode 100644 index 6bab483026a8fb0ef25353f10db64a75d38d99b3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 32927 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≥U|#lf@UA#CUp!mp<(1LEKhfB^fM~*fDD+;^3+k_t|j)| zZbHa%SKeIjtC4}rQ#ZG6)Js~;n_RFvq|^LRi_~4&d2IXEqOY})erribB{{Thql+!w zWZGKTE{GZprzW=Mc&+7Z7Q|R)oIdOZ;ar!ctwv{L9%z$vej1$CJ}vPr}^d&-aUkG{RMhJ3e#FJvd?C&34^t z3~>?V+~PW7S!wSKuLUXL$jxhADiV|4c0YIPmtoVfK>oA?+2A6NltY5P)WviRZXhl+2 zLo2S|VmsnS;%O0%=f6M<^ycp49+sch&ObQS%m72qh-l;~EW?JdE34OoG5fh< zw%2=p8?XC!;I*NW?>(YX;lTmfrpVgV3Hlw|AZnbiRX{PzuZgHg1mn=H3BgX*mJjC# z$tY-faWgJvN7mr0q+21bdr*_@mG<)^<=)Z<%*Xfl0JmGb2>5sgtvr+wA} zv-}RTRyJsNo~)dcrz>^?K5*$QF@j@S=}^8E+;d5fQMPH(t5#gA-)$0fyI64?#?aNN6+elDLFaVl`^PCO{pc=OFw`X?$F zT~S?l_{1*KDrj#CP!&Fj;I9(J+kZgu7k+&j!DXcy-(^oK{DNDLssWfEn>a!24`Z68 zpL&XgQLCGfPfe9Fwel(_zxI6~D-mA|rihv)KC|NX zfglrQuzG*sU237l1@nBQsphtVqmy6uj*kxX44)<=TbE4Yk!XOIZX5|P5bIyo2!5}-=z zsSulSYD{U5_odU3JQ`xk~~L7eT%Ft^VD>_FBSimLLJ zg@)~8;5a1=6Gx>EipvoW#HNLzo73)&b69g6>#B94D6>KGd9y)kSfBANPawvk=6J?l zO&>|EZG$fvFa^5Z9J6DMA)T*Zf}pMyGL>41lJhx(y9PMp z2X$lv`x1B=I7=gZLJO6$$ppp%gfuq!;c3l-flia+j!yQEUmpxms`|Uwzlo$B!0hqU z-mCo|Ok(9EzBn5k9{uJezeyZ6Umq?eKk<^kQ+qy-V#B52WC`;*UV>zjkr1Eb_z-7` z`c|EE9e%No^$6(Zz9j!NI5^t#(i!kh2o6tiN<7@#_Y2XV_g^|C(N^x|z-NX|O-1T( zb3%B|FBVHfni^Lj{N-ry>q6VkgKytw=?89J6nsl}Qf+u>Gdi|SDNUfHz2XGQ80DF- zdb~)!GUvxkCG1oyCu*-^bwrXdpMoSvCmspW*+xS4ydqI@GLblSY?LroMhO_(h{Sl? zUy0WHeW$A9*LH4nCHnib!QLxWr&FFw3gh;g_{eSI@xj2(GKt4o+aWrAaXdJDwSRhc zGC1=@!}=}7{qjkgH?k}x_Nb`GmK3V)xqFmnN8kV87ifKb>h?CYw4T^Uw|N=3wdgRP>ZhZFgX2MyP+bo8 zX%$0FTE&Xc63dP1iBYLv=!5}}R5);{g$19w$%EJda~BvCY8D=eR#3}<{rg!^8=|?>4kj`Q^+N6+2d|v`Lqm4% z~T< z1@&;J)7Vv?52KR)kmdh94c3E5$IK@DNq)yP?({II)uxvUPtY%b zY8Au0$)%-IuGyWJSTdczc`dy@dY%res<(|TqJ}ROx30qHsfd0Tp26Rg6@BWS5;8kzm+ZdG(0T}E%CchOb!KDuE~w*?>ECt^bC1+exfTcMyu z3+EOw`Y+t%pFA>Oo-ksx@<5v^545TBK+9c>E}}6ja0*n`X0k__$RyEUmj(Soc)+ec zeBRquHg0ygXj)3Pc5Q)I&WPQFXgiDx<&alp^?mc|FzD26oe`d}9aoig(i=N$nV|u< z1s#v-$gi;R$A2|`+Sk5@!KYhT*5iKZdfcDxPSEo$9{0;ARUY><^EVgx&*!in7O$ws zrM|6=P`@*?=eFn}{pqiCsLvv>8n}qtRW88+DDUF~d9}xW9`bvP8AXkj4cz051}|4o z2<^is1IGjDwwNHQtUKrl7gWmM*&<_j8rd$X*B$%O{~!C2>cx@j#gQI+D%oByr_y1k zPl(t41J?6kBGw{f(xDI9J9Xq~s1{>4!Ejg!BaAV)_{~bC>hxj-!JG3Z9Pw7I1uz;f z6+uYfXu0Y*9e+>Ehz1#n8FP9*8tM?eCffjI;rhB=s&0#DbWD;IRpkk74gwa#+{{=Q zPb9tH8UKIT8>`+OtKJ>oU+-k9piC8%-J*BKA`=hEHK5MDq8gX#IZpNkGK|SQD~=iH z@w#ny0CsQPA{f!a=TkwbF6Tm+c;lun2j_Nov|B)$ro2mc zWyMRFXBL3>^{u+cYGLMdY=DS(e@cOm?bMfwfXP{emop4ZR?1))Ui88~q80cW^oj|O2!QpXSCMWT!t}w;hPZ-cwLnCez#qW3G71u2yr#H2j$fGosYQLk-=3++7KC z<1`fhE5?CD5Id)^|>6V_J z-bq$AZb2>(Vb0c}8Umf6Q_L&OPhkUHPNJ_!f-Vjirb}~x<5EO{N4r6Fbv()`3_h>Fy!v@4oEjnXZ5_Jeh28SR@)uc zK&xio8GJIh*HNPM(J#JdKk|n69d+I36aj^`{2R=xwQ^51&*YMS$O^?dr%}ETKw~Qh z>~*fg43v_6rK=c}+^w#e{^1?txarx?Szh=tBK!m+VF@6~SDtR)l=G5Y$xbS?)`DV4 z3W{}77f9(8LsD4GOXWE-4pI)@DV*r<)4jG3nft3|HL8C??V?H@qGf*!I*C^{K3LODc=eF;m7G9 zkNec3^QC`yW5dqi$>>GXuhY9u_~#xqgQNtZP1-lTUR(0C<#;MiWZDWE6>C;fXiM7) zzA1d>&qhD^bzV0QJ1mB4K1 z^n=f35Cx1mALgj^kAXZ|ITx_;_=39GKk@qxq!TW_KZ>scGoHjv;A{4MW5Q&^eZV%v zF{)kUz<$(NC%OstSEhg7#^WFobx^LPHV7(dHQQgrU@|VLyT+=*o5Tc0?4O8JKUi@$ z0`^_+`tjv$V|9=Fmc_nk7&P}HdiNHvh#n=%2QQ9GAl~-;!=7_@b4d-T;oj2}rRBr) zd1@$qapSZTJ7H`8Of2YKC&8_DKLq+|uIX)k;iK6fRlV)iujiyWHknUc0oZJ=i{S!} zu5v}t&|o1)9F3>kr+uLr7noMGn(yIN5WM2nmqx~uiv5`BBR!{=kvCaUYaT9$Tj{qM zU3b{!+RqJhmK8I5t(e(sW@bAjb+ENpqzqRV`J>59f?53*ZE`tPen3Kp)o;yo z$oI^2ze`jk@NHi3Z@umllW9gQt4*0|ty|l=|_dmOlV2Mee0aRaKBe3@ib% zwb<6m!F5tas>;vB4L1H0sZ>=()xs)XeY{&_H*yPpjbnHD-V_xaE)t$RO5+>gb}@km z$*LA4F44(3C$rochsdNpM(P^pNB0yiXPTnb-H}R~=v7QP{_{BDzb5?Wr&faGcaknj zgL!m6={GOA?{LhStoxpm1mlLdxNn zXV+G!!PoH}n1U2`@A)KF@w2i*;`20l9!Y0NIVDM_Y>S+Xj3t3w6dV1W3{7+wrF8OB zC_RzbOJ@M;bzwd&jg4{%0sj0tU2g!&frSZJ`b$9Fq+GNWjeHoa z*MK7hogvasrEKjnWqQT;2FJ1L`r^Dt-@%5y$5ZTP>^#GSY#6rK|elS zpxYBX@KOmC)=Xe4q%^7lpXM|a094%j&jn#E^teGHhArsclIim-8kKZU)#JK5LlTwZ zWL^W8*gv5JmSg`W6%3u~+q=bt=LPL=W{hnL*o&*$NAbHE1&-&BB${PqS*?vXbTP%F zvzS1?U4jfw3PsNpM9(BxVP`gar$OYjGSHIMTPcD6PHHt9_}0HRNoHXO&l^b;n-yv4 z=$|-wPq}29dVDq&+{0r*gSM|n~CjnNoVpCo`x+7PPC@3w~Tl0*zruvCE|pm zd8{dB_Owhi;8Y~yXOdXWgc27Mki1+&PR-LX<%6;zQ_rj}`&zBJZzd7ID&de$QihrK z%bM{A8O7?pPh)BxxBGoZK_ke^MRm};QGq|xpjz~Ig7wYkRwvRG!3okP(d5JAd$T7~^TTF+#WW~53WmZtkVha&jh`Eq6KvdOkLXVI$RNACo#^vlfX-uWs1tioSp)8j@JOlDJ=xxWmR_f}h z`06RKu0WgkZ~N*(+ku^U7iLx86gZ)RG|#X;cq>MLh=@HJE-DLeqN-|PiY+G;NNhhtz-G=qZHa0mkrUXgD%!`T-fSjoISv{X$sQEY#Xd|3v z!W-+uzh+0H_aNnss9q7WiU!7Fm0 zILK>%6gGZ<*5-g53^0gm5(#FoV4Apdyn_6T7g4({oA8Xgae~76E5>;?JWlS!Uo_0k z#+~^D?>V)3=qaauDdR2o?IM%uq2X62MwLsjz(C<))yDkDOMz&ur)mT1k~Hu}D?bh( ztY(~S%OvAa*oO84zyx(TQ%PcbL5u-rUoUJ}k0fMCh>6K%o?ZI^eV$*g@dB<%x9_Qw z?@q72c+S|vYepY4da<4K#A5%c4BztPDWhpdz!G((cTDkkP185iKQ4_o4p%kRRc^*p zs4np){Y@i=lia;2kVktSnT}~aZuiz5clOA8!JRpqu2UYsuO>>cQB~apGl_?sn&fO- zmR{(-Y^-EomRsZ=fc6q+{b=6}Be=~Q$=KgP7{veOQh2G+%G&!xxuh#WHY+B+=7gGX zrAJvg$KS7Xulj@%;{+2gVNOiyy4hOCB8ji}Cj*AJY`tU4*1=+0G}klG+ug%-wn&W4 zhOS-k3&a{VSBqn36`p8oW3pjFA3UJQ*^Wn&{f?_u*%LTgS2`Nqi>EI>%dg|Apk7C# z<$ArEo}B#h%P$iuC0BGBN%Qsuac*x;P&Ea`I^NphV^#Y&xZH}$CTMuZm_&h*ly&COh8e%6nq0_6|q`ba#Au~ph^(YEBTz_0I7VAfixHMV|1t_RHL9Kz@GW}Q>Es1X5{(>?#nQ4 z7FCX?e$G?OZKCAORy@=|$qvFF3+scb7o2$jLvQ>X3(Nn{@;p&Aj;rfLzY6W{?`m&d|t0jqdW3g%;QEE2^zrR3=gba?5 z&DpkBgP7tb^B2rp5MJERv@fKvL6;S_*be7uP8m^hoOTS(M1%%T+-7grXJp zs|(R)lahqR8m`5P2MKN%#7>RjePs_8=Nb54mEsM@$FQb`h3FCefSZ4+A+3_x1lK@u zJ6ck(k3Bemp!i61IsE*UK8>itu_!_T_NS*?X{c=_QIJ?u_k2X3`|N4UBVHzJeyWfs z0#J2N6;>ajc*=S$KpF#?QapFXk@cbgV$sNYw+<$pG7!mz8|u@_g7|MTbmYLxsp7p@ zCaQc;olD}8HffHfQ!C!Xp(3gkOxPOBoot!Et#xxP69sBoNtORnKTA!Z&QCbQt6t}h@z2H%R51TO94l`y z8tN=9Ce(Y-goUb&pAa+SB5rAxz)kP0JH4xPb}4&i4QpeEGEYryDfzrxf|W6KDUfC@ zC&V@$#r$@K3Yz&&@R770!tV7OAFaUa%cVzX8z$iVNYx~lRfA{cBN63_FrP=6jD8VC z0TR3L=MX*O*Hn;d7=c4P>v=Ajz%*S`R0a-5=Kdt&U=3 zB3k983Q8wOu?}brnNxx#93{pX!ff~M40J}s!L)sM%7q^(-@UiBo+(O zz`_U^Qp_EDdPHi8kF#4lRqKk(arvbS-j22gJ66r&!FvNE`7C&OJD87Wv_N|>jy!Q`2@N2#GfY> za%Qc!Smq3!?8$B44AB+MFb}HP&9rWY8Q%i{$QrmanpJ_-U*ibkWqHFE59%o&%CjwO z9Dir@kN*|rjGb{vorUkH{OPa<~UxMQXy_ue_eqlVJT!1aUfL9%tUs!j`&K5kAhZt zqa&Uq*#~aTNBU75viHZEeYTsSCeI(7$$ z9v9d^gy3D9DILTHKci;EP@98(bCIE6f2QpGFyHkQ!&7< zIvz^)pcsRl=*SW^eZcZ@R;-p;jJF)}$!cTS2=jF@Iw3=h@%7R8YNRznC|&WZl*!KI znKSh6tJTWJlT0|ILOn!z>zif5y&#)BBxo^c+`3%eH3uXG{Jslsn{`!1kLgBH`5_jh$&&Cc$;1c)`DznP zp}9(!Lc9N^GrX$?-$2+4YKYhidQ$~ZP7?`0eHRnUIpk7^b?Y8mvwrf(Oe0$+JWS8{ zdUCqbV63(0lY9!+M_3?Ik$YA#t{&kYxz*Z~nAFF7#S|F;)|2S1s+1(i*7+Hn)#P(r zI&uxbyu@D_uJz%2z)Jkhay!jVw^R@sL;&=b+~mx2a8=0nl7m6Zy#5lkMQ(=fL0{~z z4szfE)em3lU5o8H5O#6)nNJo?4ILlAL=0mYk4rK8QS!7Y*DIuzV5(|&Wb!v08K>}q zqhg12|C8XV*yA+xjN6?KIQ@fYOc4U502E0=f{9Xgl}$}Y2H=8^Dph{)V(m*(-$8%}gGMFI!w(Q;-`L-BRfpUW%k2i5gW^{Y5w~ob7RXHa>*vXI+{J_4&74iw)n+ zu_Vw>e_`@6ZIF7RI^Y0QL(%AqY?0M@^wLohy#;%BxP}L~?TTOG6I`;LQZIH(dC-{I zEIK=zoKgEm9tIhliNyAzf4_f}OWIMve!|wZdrG|};8E5S$?zTT-aJ-%(n;G*`{(lz zIeqXpBW_cXJpo^s1VeflV>d`YP$)o0{{{;Vq79#@6~~`3;K=97dSjEZ6mE<8Mlkms zztR*^wQc$VchIH~FpVvkM76+b-d+UdhvaA~=uxmCbTFjA-os=h{PCb5R}Y5R_>-H# zwCJCCH($Elh}?nm3BmfItD=aY?Nfq+n#-O(?f)t^p^n4pc*e&l~fVwaR@=Pl}t>c2alJa=(?lEg81){6Wn z52K%ILsG;Xl~);(k6q$9@xW!kN;OL0%j{=GH|J~VE%)}N7KfonqZF*yQr<< zl9QnF3|Nq<2cFPOa`1H!@TT+7ESqWuXIoxFah5d@VSHCjuQh{HCr~4gSxd+#M?T^D z9LB54g7qOZSu@x78yBZ3tJSz_L!s0YI|Nh>Y9*+;txRLQ@HQnQeHL9sKj*T+-l5Qw zHyVXJ&gLR)Zroz|{=d;dpIyp%jm7t-9Tz`My*WiOa?8$Bo{k4JiMq+BY;9-v6q&OP z;S@P6-k1HNdAUohFL$d3$N~HT!OKtBK)hj(je1XrNqn%#fCZGUF{TDS0ky4UYM#ze z21}`m^0KG#V|;)4{qSojH!Skp9`nApkZiq$s#LbE*{dz@AUs@J@1SPScTlta9h9X_ z_Z_4sj6AL39ppcYJmm9^0wS8Qp{OdkY%fw0LCsq&3J1fn@=c)&(h7S)nC!DDu%jQ< z%<<>HKuL@f`k`G@n4V9wgyv-0Y)A|05c-();?8$jW|Ov_rAQQ@9S@$&G1Ng1x7Z|?R@+4;D}B=&IE)x%8PwtiULDOmh0APnSUSwYaS&hNk#a%DTN(gs@K7W-0kx14 z>!WA^iOM@F#{5DQ^M8O1i4VPuD-i^2CnAPv5{}KsP+o(jPH)E||MG{p#%xm9kA{q%7JM7Q=t)N_T&0C(i_i__#*Zs%^>FELBP>RHj+I`eKhe=hO|90j z&Mw9=22I1TE?n%zv=<3b4{V+#dbPyTbvep5BV;FoNwqzn4maZ1G;M6rO z!C~Yn&gThyn2UqyONPWnT&lG=r z@e#v05vH<9BDzg8G(p4NDh#oOQMd`cEnvX3wbMIoV{+-+i*(IN+V&?M>yvA1TXNYl z5(%tG+LkBo)6}!sW1e?Rv7O&^Pyt{UD{FC2E>kbp@VrvSA`Si;7Sk8QETLlHL}3ih zhHnY7FF?q4M`=1Vi%`fo_UNe4V5aHPWeBHyM%6~6H9Jn0WYTr=$~Zi2Pu}McSoG91 zA-U&T&V|h8-~su=v1;R86CC%w`z6ly@x<{h*IRD48;(R6c|hSDa&Dw@J*nLBYp<<- zJ=nfLJNk)D00!T>kh$3;afpj`-I}70w{+A>Az-%tBb$_}3Hfgf7&-9_lp^RMFVI1M$1~A3njVHbz zz!R>+PZC=wBej5Or@2UhKu8;I;d>_fxOWbWi!tmy801Tk8_Du{`r`%q<3;-8CHmv# z>FEIXeArgR(Z@SjIEiD@w5j0ZGv?WJ*>xkuuY;q(9UQyyonsD#3>{_=p?aUAvv6AM zD=C_J1!rR%JDtsjHw`%2z8)S#LH_5%vpv~^Y%84=H6UoMMX8rD|JlG5=@wUNk6TL>}+L?VorR$D6maFm19~jlJ`_!Pn%B*Jq2}`HR=?usM8ptPUnUC88+a0!9hl(Nc0n^7bzzW z)uQ&}YKOaI`feLcd2zTdw{a9RHlinnuU_yDU@@U6&Z2)wiKG~wfRDu(yrm>k98V+- z$C$u8!Q=2f@iZP}0`tU=!}r9~Adv~o6F(9^CLZG@B!37C9vc;qg0}>xcI8goqA;HR z#aG>f!312GN0ho}UwwDE+FkU%-d)CRrlBPhkn6#**y>0`^zLX(^fij0>R){Sc4Dmm zshj7=L`&kcbz{B78tW~_8&+RCPCt-iw>7|4?U#p10yj<$j})+Jf0(4Na-lBb=(@#s zlA&xtyQE{?xw99}-zE-3CE3Z^+>Q96>lp6_U5O6Bmx|wKS&Ksj=r1peIGtcQsyo?& zHqP9=)e6tv$l|j?&?$$Dn4*p{;!w$MP50O%o83cZOH0k1^SSez=carV7T(I5&_n!W zW5lrJV0aP>%9ad(=OpFP2y(NbQ`*vWCd5Gcs{>D-iu04vv)=27VR3-IwrCGDS#kd3 zQZ+-N1J|7w4m^GT!9qtKI(MiO4}1+E9RY2i(tj0Ha5GrQ^q1ej))Lo7gTbeN)HO zu5|4lm*GE%bBCkkkx@si@HZ~y8r$3QdYjOkgTYduuN?P6o{35}g~>x&P$VNN3Q{@N zkQyO610h^GS394`_b@ZIx(yyw^b^`~5LTC#Y>|hlNv$n!wX&o<JXHA1CDG+^)y{EXc326Hx^Q!6NBuK9H0Zz=B6yWVIJjEWzBXX>BMu=m%u|)u{`)Rc@ys{i1-6L$_piP2+(cU-IX3m7l z%OL-H&1Kp;thOv-Djw}Wkzn6?aQEi@UoX}iHE3Dl-(ku2xTgyDH=VE+ z!K0?-oHF)bTL0=5GFQKF3Y|V#DmMqVoO9$=X zD8;tzj{92tmsS0yoHbe7%bD*!gQ!=QaXb;1}pmZhl zGecPsiJJ1Awmtf>dAYgX{GP?;xRvJrGV_0#IeD4!&T1~qChd(|_W}948{=}8g}Yjp ziP>*%1+v>$W{MA5cNJ?2?Euc&sSra@jF9fLx39he-&oTbWY z|LErPPmjwk|5m8$+{u1MT_sr7fD~`hjl|`)#LL-WH+EN0+~$3I`;?x8cxmNh9f=~o zelO>Mf95*}h53bJ^B)LM5{32|$poHzs32)i{hYiGDSidi*QPuPayul>;n+7c!j*}l zfQEe0Q|bdPO95n#3+@2b2BZo1-j}=tcZxgwkSi{xrtOvqVLrJ{Pdm zW&GJwc5DXizy}YyRYs{KV+7Ruhh!|UV&`h%U~7MKsm$Am#-dtcr|T66BZ+quB;C} zueY;xyqTO*c9H=Z%6To1>bl8j38kf|cX}{7Tep7A6FS;HGpRGTq9Cc2qzw|gAjERg ztbd9Ns?vqy#H6`}?2y@F)vn*A_{Dz4)ClNf5&mJ`8PV>B{hN&N17x;2N%0)LWGtM6{LPG_Q-99uSNmE;?hEvLJq z*eKqJoRJ6rJyAKMiah*L$%!Z#m1UMK@9%ica$%voRM%p?#9{>h%Ni`n_UiigWCf4?JM$9vg)^`1X6o^38nIu%p?`MU2{lX(3YH> zQtT9MVDoz}w$1&t%#Pr^ec)p8`Ws}MmL~Wb)8r8*2rt=f-DbBtG;4wTivq!L1PwK-P~q$ zTdAsGCvu`e$ec;p$TGI?D=CsD=#rL_2tjNU>g_KXKGA3XH^MTFc|sKxR8meJMpQG% zPPvD@?JJmV^SS;mv+>@mH8~kco4ZPWr1Awpp3k!| z2)r01U`Q@#G5@vU!ltDtbH3s;d>0wAT=;Pmb)P%kFD}|?3CmoDgEAQ?Ki|x6E-xuq zq=Ux+FH`9C&o`IrneGcDC!g)&L_^|6f0|fwWGgQvh3}4aZHCj7JF|(plg<4^u=~kp zI=*>!-^kyXod4QR9JicIs?CNSR6A)z{c4gQDv1pKVoN7{i@tUel3I_|a^P;Gg&W;L z$NAp$wb$I#n%0++7T)8E8}cm_@3hM)2Kb!)d1$0+%XYr2HmZ@Ya^hhmb{jLJI8}=v zBN;R~>Ou9gW)sy+>ZaOGvYFGhDOJvCmqAFl#-+sD?;^k%oP}bNH#7T55-PqeIUO^) zd^l0Q*P4F6ksQv=n@DF}b{Z0bs;iQLxH8opM^uuB5SV$*#I3q3%Xd~e(tx_MsHUN` zLw`{!s>)P%LW&^^WHWd`LV3OJ<0sRG1aGeoM%B;<3O;bLLYYXSTuc`y=jfAgVvz}u zmpL98%^W4ZEWd1R!^Wc%FyLIcf^bt{PRoB*1|D^ZRSZhIy5lX3mhwB*tAzko~r`%88=maL`7-2Qj>FXjz zsQz!J;+L3?I#b{1q^B`6%D07zv$Ex(^?jP&*p^YOdBR+&z~W?A13WGg2-P*1pO(%| zX1QbvwsApg+-cfNJ#)MHH;GQ1xU>|rzM5<4NCHXZ{Fj#BimLWN$_*M>vKmW9gS=_> z`$}vH8sa)M*CcJYv=<;pVQ4M+gQ>I$)^Jk!QT!&FdoghsMK%lA;4u`yyns{G4_O5x zyV(h_smrO4()`Q)yyH`dyAe;cOe{289hvnqIvhH;xg;1UCS?e%Hg3T5@{gkWbyrU0 zAxqca3VPfz$yM7+6KHxoF!>8=D2oYDe)IBIwo&tqWR*gpiaqoJ6Bf80bxkS|=K83U zi3t>DsVA>udPVOc$bK&<(0BayC|&zxa(2Gwe{zwkG91v%kK(Yf0%06PDKV_IENufa zMm<$m;`Vi1g;1pIW97bPuBN_ywbshm>FPTqv258WgI!Y zJ~~VBTrS0IW>V(!>yqs2rh)t8 zJ_yCE30s_uT#zUCQP=NGctv(*H)d0 zMP6r7rLz%;vZCdcR`-YItLktzlIQi;?AGN~!qAtMQGUJ3V>Ss-rb^WEJGO8BV1vSv z>Q{CZ#9rQ}i5;sO$fQ>$fmyq$4(vO2``Mp|f6n>K{CfV@Z1wZAhf_`-uW#1a7Tv7L zf4piamb{-$P?^g~6R9htc7-A&c!FE0UD}I_jwyoBF(wch-N-2)xN+b=Pz<~`D$d#k z^ndi50K(WbFEPclC+B!KMW!g}sBZ4xR{HPbqdv8&k9&c({ealP5tXyHRh2|J1YNxpz$vLlUvNS$KD zrZpkVFT-GD-)W~8lk05O)l#2E%?1k0vi0Qc7XcfB9Bu?e%*;v$K&Xm~c06VdWv>r| zOh;KRK$t*{io;Svg*BB*@02j5lpUr*>qv!DOpovKYL)kpq(PEhq<0DhZB|#sg5V41 zZ>zW8DW0Nqh*yPS@!mTi?%MNh!#hjhGp;afnP=PcW%S87k0>a&&M|&Px{P$ghl$ex z(@WirYDcR3AS~#LUWeT%Fkof=UY)2P7-D-q_A&L@NH(j$CmgK`z4 zX+Q{a5*Y(pO|P&`#4fTU!u0=lIpa*x`>$D!Ynl>_vYa~Vua33iU+U?KV8w|_+YR=sQdE>^eH_oB0_f8IKY6l!)wEptRAoS>!n&smDk z5^Nww6%*F-3D%w>GM5A9ah17~&ECutt-gDWYK$VYKd59CeSXR2Nzbp$dWm(S{j%|-m}yr`NUWw$J2W-1 zvu`BSsjEZFVsZ{uh-&LC>BfO96Fdli>uR(WK5h{ z=aunt{RfBnZPRjt6D1HTo&GfS}2E!qR zc0|EWXygn(4Q@|zYCvz5NS!^=0PaVfV1hDq>ollibJ{(^vlj*4nw(An$l=dK5t8bNvyDM@W zmd1l_Sf$b}C~$Cl5w?ZO6EpH6v$ix!EWKyS#4}UPzwPShH5+F-*(I);SdOie)Re7B zRy%f&Xt`|78&k_%6T7fw-b_p9Wfxt&VR4Y_#)o`b9=pn!g9)qNULV6v40vM5GICP( zuF2$L+0S-6m8ql*a@Pt~r$x@m_2VOM3*7Cl_nN)r^?6npbDafdwrs*(I&Km)ld^U1 znXuW<7nGBkw{EeXrG4DpxM`Nh@>RHO*Uz>@CXmRJFeXu4Z>XvnE|6g7UE z{F=v7<}t?LEDd%2P~BD<^u1~h2lM{qMB4$PyN3T(8rc?YDd$Fs692cnJ?I297u#bK z(l3S($KD)jp>pISQ0Pdgg*$nlS7KW;*#dtQ4vJ7BhWxG>au?o_;x6z^K9l%Pi5f9djpIUW**9Vm?NnZTLn~DZk z4b5|}@3O&7!-GJ1$nA7ajM^hXwT}u<=#?;14WjASy3#W`(QutUx@yixV~St|pL$1* znIU0@jAlrfAuxzi;TZ7j?0S7^q#JlLOY3U{Tp$1_;bd1D%xSj2MF4B#B1AD+svtaj z-m*Mh-l>wEj2ruH{M45zTV!tvV`aD z9%blR9k}_SIpich*^vIphfK}k)*R{0;o2OVH9)MkTT_L;L{>7vIQSnv;zPP){l&!@mzk^h)?d!uE#WeYyJ`uGnP6(R7zD?!!hC? zM~X6iEWYyNGVD!zo3>(z03EtFPN5*P?mAPfSlGyThD88*$THpKJ@>mjd(h!7rDWXq zC@r6c8WC3XVgCcq!Qy79{%J%5lo(69Kxr_I0jMTZ~ zm1p{J&?EiOe2Q&N;1iBe!lpg2^?2vl`t6aUcxK~a-}&GrS0_ya5BKhc#prbI925Ao z^!oW4)unsU>-NPCDQO&OyQ41?BS$nQ%YNSXF7D_QA)s^-8`Xo^tF!z-j&C4eZUIwnRAMwD_0K)^zY-0kK(TAqq7M$AWdNRBl-7;Ng(%k4I zg`VFck8TC?EGpGy!FoJO%p@HE?THXiNI2)~(RELJddpsvT|pQOUz%lXPF8NP2Q1yI)`7sedMK}m- zlY_vK${~tN=Zifv9rdkx3Pl+^~Y%ZX#^ zUh3H>oj+ziT6fsXuB@u6%sq|0tS-qgcBb!%M|U^!Mm*j~^U6+S#PKuVr{XC#7CSI` zyb+h7-k>V7jk9?CGQk|-;n!00w^n)NKrZ)WX<1Z9)p!PKrSJoXzq;9$`X;@9roGZ*M*;MWLm{+X}XSr{~6$b_J6j~S0B||qhZrFG%U+#UjqO& zMi!Dj8aG%z3~9?U{JL@2$^L`$03J*B0rPOtHVk?of_m1GkB|1#eE<^Wo+C~wk~!qp99TrR#ibq>CGz+`N7roVpKLywP*kyP5@3$o$z+K zHch|Tvgr_ z?c>vJ%U!4);po=(kS@Vb@~E>c!{wJEt1dXmGHWikCI?t`T>+{rlw(~bwe=j}s9cNY znl9Sbgu!jtR&zi&rx(pU9#gDNQEzZm2V&{S2!5#?21NCGkX839B*}ZnZe4GArLCP? z_FoQRYrD)$ajHR&nS0yzp?a6yn8G?};++ONt6ImovH5QIbh)#q`oQZ);cDeD63^c~q=flm+m zOdu7`Y6W+yV6Y@&BOnXPU>78Qup)a_2hS;LDf%*(`4ao;Td8b`{cTlKNt=^IFWRN0 zFA%tNnd!e_jn@THEWPvbSjsUggBH&zc_Q&vK$Zz>YU0YL5+b{gJ_p z!_4(e28a1gO;B)>jKtnRlLzrpvx;Gth`rbI?Yai1Lt^XvLY;FVlp>6xT1XIgT3=Be zlr(!)Sn-Ii+H`;es>?=n8PkEi-}GUgast0dU>cOf2T%s4-^??EP3&Ur*=VQe5KElN zl746yb|)NnaXt5FORyWY!mSy6>cDP@NO45gC{LL04mhf5booA{9l`yU}mY zBl%6H+&=M`8?2;!YpIdx1xmM8w5qH^WiPUe!KW#x7c}}5iNERgU$G5i0(jLvhV+va z>vohFN@ZSvD7xLk&$=Lq!jgo3;ZC~P=6oly1HIXqJ`+n?4tvBSTIcI*yM4O=h~~*m zCZQ%yS2rA#BG0_D;RhII`Xz7F84&t;l(}UI0WA>`>79=9u=Q2(A2w;iC@Jlm(w;n> z=6QAyg;LU-){YmO78v+3@6*6UBF7)IXHpgAdZKhzf(GM@x#q;&C zm=*xBSQlA`@9w+wn)05n$7*r-EOuR_^!%Q!SLbE&08UJ~CsH`qk7rq-l#qk3>RA^I zaBc9!qrz@>w<5(LC3^glSa(BJCG;5PSS~p|U8>%)^mf>l5MC%)Az{voN*^bAUa%A3 zDLoNS8lAlEba&kj+)1dg-4#J<>{rdIIZ_3KPRMAbm~#ecPI$rS){5gR!6(dTsJ~TU zYHkA|jY^inCRHY zZ?6e7c+c2oc7FcnpMReH**`0`cjwV`Iz4|t)ti@D_~WIkub?j0!I4cdoVfvCBpYna z%~&VfKX#Nl88R^1h4XisTEJ-w?7lNUp0mk0PJjHLFTdEw-#Tkyp=g1%v0Apk7=37A zl6OxYX5D*Oua4#-4#V)gd~>&tdgwJ2-2bolh&H9=!iBPofxxY+M)oTvkcJ9x*L6-$ zo2p)Q-W|zqWzkq#G`<^R)8XC~4?t}ai;4q{y}} zPhaxlBjdLnV?}N?u{2FIEW)d2kkd&9awO`05b7ZsUdZx{4pxRi%NX) zR0aeV?5iTB{NWq{!VdGPC}%;jTieiTWxXHvYnFevC^q}w&Z;$THhyy4_{n=cy`gLu zlaF_AHFI{1$Ey(Yn78#6AgZdsrU|zJEP5IO;Mo9m>wFF}m5e&ojkrKZ@CQY62$hzk zi^>-Bao9dG8gQ|pdXC3dY}#E?BOff|)vGy&AC64rErA+P-zT7c5V>^xkh5&{jkuHM zMrovlSl>x<)MJKrcc*)BeveZH@04FAxP-MC7HD3Tf>Ks&d|x+m2pwwRFv{XBQR1ce z!x(o*V9Xd@TheRSD7e72TF$dbZcSH({6a__jUM{#ShQ{6H@2Ep@&3p)P=7Rv%t67$ zcy#^Jss9n$_2YR+e20CI(}Eq1VA()$pOjzi*1yp$P0?P^tsKVJO`427rTgqDMSDt> zJ!PcX0mKL<1pW@kI`H2*VGP!+lIlG#^37jpD#&G| zpZfg-d{bvb7g+)`oCtd`F-;B1p%XXv?W9CqQMDXRK=XBy*sVP=QC~GX7l~ffW;}ld zjpkBR<*z$51FppI?nFM9Z z%4W}4|C@Gc+*Xx;Ogp0dfu>yKh&ex#lKGC|lh&&$c&cuL*j+HUJMNdH6QbL8K{``# zitsy;-+#&P59RmIwkLZej%5SKXO6eohNIFuqUfs)dlXd8GFqBI`0ISL1CF6TuVGKr z`U*@(=FpW^MVBhTny(A(jE{Dk+Gyb9%g>Ls?Y#F?Pnt?8#o+hgll z{}SVMSNP9@Q2vVx9^c+s5JIxEPrv?58;tp?OBOP#^B%}-!NXit;vxJ^CQszw3;Fld zS}E^x=sDiX4*;Kdl!q+#=3?ddJN^?=#;;m>kwcq&isM(lMJ6|%V0Q;3OVb{IemYwS z-8}Zd(eK?AtVfF_Xvu0$F^2-VCs7z|NTLXMkX-x(gh1X1@^-=hMNtK~H{QY*x=PKn z&x=>G!P8TopF&|n`@_@I^nyfDG=Ts8r?f{9I^wObiRVS(U_2bgr>TE=8HIiq($i6JM<65a zpQZp9_2Y29B=XT>Jafl$l#h#)dh6g$zO~+-Z(iU*;dJI5m!Ae75H5dTfCfss&fp}a z$c+wAropmud**S9?Vtuxc?)T07SdKNq@7uCTP4)`Xw+KXtZu>Hz`sEJBU#DLh1|%A zanC4~x!7kE(T`W&l5B4tZ=qix27LY?hyM%U4G2IPk=USstvNREw)nEOBU?63--nR*A5KDbn*lpzf6igiQ~{%r zgv1jCn)F8l1ytoQDPjFk7mTBc0!9ir2xA3{O~F_L`v%w#6>wmc94O$>0uB{$q=4f{ z*B+aK0}a&d^oP3bsZ~(1GYECT{zSnPH<(ngSeKhz`@CQ`u20>%m$YeDuk%;;t?(ZGQbWM9E7eukj}j*K9u3Z~e> zq=FgEm`0`=HXi9)IJh%?Nw~G-?#FQ4AN0{_QKq)mu|?^Kmz+Q;NDuf&KN4T@n14cJ z{ChN*js@P)Fbu~4BVfb%A4E71fPNH?L!Rt|8prWSfTyF8tP+o6=o=>47lq^TXgo2= zsYp)yP{JgKJUJLn#>3Dg1r5V^5Kl%XITp#u6x3~!eNFFhVv?e@aU4#j1CtzzHfi!Cv~oxums&a>s9JdzjeuPUZx5F-iW^CjlX*Fh5Y3_ z@`T6I_9enmA~r%St?u81~)qhh+?NF@g%-ZO7@ zoE#3VC2r#O979UG@Oi#evuC051N^8Iv664T$vA6ywtSuwn^LvH;;J3zk2{L8ahTO=K_}HXE9! zHU2eiU5qf{D>Ey9{~+&Dw`;hA+^KowaA!x#jQaW=eXm_`CT1)+)VKKiLmNtee<9`- zEyoGqigP|Yz_Vtl=qF{J-qoDXeGJM~x6 z-QL~m_8ga{;vKRc^N!+22yjCN?&cEPqVnOn)a#-Gmj~(wsPM~VLfse5RcXg;h41?k z$0W!l%1}$LOgFNdxBFD6OiHF+2h7Jz2-Ck?s-f~6$r;qO@|5kLJXOtE;L zL?E14!iD-z<0!=%xJigVFjz}eOGrwK=L$T{4lm#1C*uj@vi%A2 z+5QBXZhr#PoRw@Rjs3v|^%0cZh7zc~{q}eE+uz%7Kepfg!Ped9Oypepxl+;1JZOw2 zIRGs`kEsf<)H~)pcb2e7^|BuQlh-%3F~d9v7W4qtI_yRmYpmrS-vPe|a{<1Lu1UPt zNobriB7>Uz4UaXFp``)yGg!aZX;VmA7XdL9-xLosLei{(ror}r84DYy8R_tQI)f=D z^JioX?~56$YPlWRZ-@5ViTyURhjljGpj)RHQPB>VbM@GCuI!V+%I7<;vnB(&&7Rb_2Z3ayGOhHR-oKQIt!2a{q8tMOMHZ2 zWV9N>C76;N#>c1Qejh-49)AFiRe(rz2Jl%92zpPQk>v5++NyoofK|{J;-H59=hj$B zo!YoCj<_;Ou%YVm^F%U`$S`1CHBVE-3dkIqPUoltdabsFAK|tzp987AVZv9Kls5|; zqxWPWSF6>0#6MwCEkG_Egiiw%!9D5k4Wa}L37hq0w`uTktIM9Z`h(7S3#<|ed#w}^ zY-Vr*+x5@}LwVJ$KzrHWvQaONx+F;`i7?>IAPb_M!+OPpgMNjo@*MEq?PA*J0qLES zUcY**0KV)aZQTu$uwRd7hADW2s_Z-Hd{K(h5I{e#bXea%v-FFNGLrnzi|$ZO;f znakm^#}by)8JG$xU_l3|M71HZh>NFBGEe`?Jw18o`L_0?K}kfj&?e#Y?FIuPKOs{q zbq#Oz_Q@>*-ExDv9%SH7L=0ChEQOi0ARFX?#zhYNS|3Bd>C`wJh7GiX_VwoacfzDW zDU*6OCfUOk!2cm59Qr-SPJ1UXmh^kxzs1ghq^~PG`;I*eZS3sU%uYMQ&X-TMZja*BOjMV2cJpK-zj=s8g#G&mIKmLzK& zu8OgX;MD@u*4v>DbT|cS-?-y8RKs4H^;p1h%egQin?zZ$%}s>^qo+wDz(h^Z+1x~g zbwhZ{P3rPln_#_zk8w1Y6lZdJ_dWrY0><&hH}*m_w!N^%OgFcYVP^;^M2(QSzT`*kSwyE>HG#Ox?8J9}P-xd1Va#puiPTP*K8*XBHv@j$t-H~`LkO(pppg>N5 z>;^AXGn#d%Jio(9OAIK9-K-tojKF(yu}DW*=rdSabA?MZSQJeMTjX%x^L$J_Y@ zgOhnDL*`9RUVvObeRT|8JF9tMyqFQ(O9x6Cogq;lm+HACD;mwiaw=`Rk{@bLa>{oP z3H`DrUuG8&qOO6nGqR4$(^k+~H{w+d9*)`X-6{{q0kb!CI5;M1ZPJCn_d< z_qoYp;D^4|-C2_9NM2rE6^n8LUAevGip&b`1`hSpL9hU(psj9CKl+L@GlOIY`dc}EJX>mh9Nq(d=$baGFYqzPmBZ!Z ziWHzaSaPpCyxO?>lY@unh9~u5T%5tDhGj0q?&(qvUa$R49p}3oyi5}PHH%uFbz;&Q zkR)lP7oD($C%(5j;v|O|yy?KYGF#+&v9KrQd<9vm3m+`wbR7ugTFJ2DN9juHcb_X= zF8oA4g|IJdT^?f*W4hhe8OEHG)SV1q1?;wLXPU+#sz0H@u@F3eS!gGJ0oau=YvEu{ z$ez0knTeSQwL=VZhlaR1!L!R6y7@Co+P3H3B~yS5ET@8nG=``=Zov!XA;+eJ*@tK) zK4p|nkka~8juYQD@mz0bsjaALn>|_e_{Ee1svQk6g8G{UXezUtCFiHA_0b}Z%HU9? zwO5cS&(WTUDV|H(Y37)zct0JIfhfQAc+!07gZ^+B5IWy zBfN*4UhNEvKTBI`#^g495s+})Y;x2bwEM?>6~8RcDD1Z7T{v(B4*=}40{{owcc1WXS4GbIUvhoyjoBA6MA1*g zek&*-tLhJSP9i;^X#$7o+pGmY*h!Uu7PV<>jo3xi3L9PomD7(8k zb+@9OK3xAdq*g=vdH!+x3Y(i-;*hC2&wt~@T}9fe+rR3trC8`M{%*LW&d8f?seSD_ zHR{d=r%DaH_pgcY8^B5sLf0xc#EBON5v{&zqt#TIYKKA^`i0F zfV7ZmNFggKLZoQp2$cTj# zzdOx%+}MGWuxfVL74&CKv#S_@?`9aVKyj}o>Uut`{`Pon_0-GGgnpet;MEAFh+Hk^ z!i?&Z%;{wuEoHHc<5S;e230LNB6D8nXF7i>L+Rg%d6eGOooQ>-HYMY$lMv6!J?TF< ziC3R&pLlESKS5TuA|VK?tB%SRMoiI?!VyWIl{<)WWU&rkmwuX5`RQ%uIHM{I*vCqh zFs)8OIojgCg8c%oCc3(JB4vo{+y4{0zaZMbtRhVUo^un1)c044# z#K*RLv8{w$iZ+IWtc4}u%76puoQY(j=uD$uWK2rVW^8+cSnw#;&PW?Sgnw{GnjEQ` zg1GiIVK4;HCGnYOZpA%|%#Tv(_Lq4ufnP zDt0+byVprBNYaX8@B+KozL#Cum856g+X`_I2w~af{b;0bPd$6Hcl6%;AG}xy)t7 zKF>>+eRJ(LNsFh8LD-D|a5r^sT5qq8)d6ERW>m;d!O}EmZAiLo1ds1K!J$9v~B%LReLpWyUzP8Cm&6mWfiXxoLti_x$MyV-QApw-=F=$*5 zl;3D?F3OW5x=-Y|y%noh?iiU{0Oh#3&nhGOeLy3~ZwA}LFtR?~IQ4Uk7`rjTovL=N z*U96}D2W~2+gk*!%6yJaTD25g4~g8UqZT7q=&G%@zUuliZk!#{6KD@Tb>eA&hn)I+ z9rF0t8^iPW-f8pLJA=|wS{gv$v^0d$tA(I^#ZZNXNYzdDT zrT-o`iX;Zd;><~EOG``;{QE}C(OnSJisUqVRXv@OQ_1#RD$Z8s4V!hY8M=iuaFZ_9 zIAtWDx3m(VPqtjnB2rABiIGdfoZNAGOUoTyKZgr)riLZX)G#l|!=)t^2=d*C=7OB5 zYUR62l{jBYK3klrv-IENhFxOJ@&9INi3x&#--vm(l*BZK(z>;|TwSlzX%Ag;K~Nnp z;?y6+h@Fk!4&ik9w|lhM$Kvj9NBh4YwYyM$xA*qo@aQ9bHiEwoUqTW)`t-sn0mTMO zErV-I$>ld}f(0v663sVF^?pYB>OTdT)gT5VA8E&>QCazP~kTvg{}uJ<<0 zA(u%$&U(B+?m%Z1;;~7!J%c}kbzT>e`5<* zbuovg%++H%4th#>7ZvcXrpSP&Vtw=!ceI^Y|0F7v$t@>(&O7~JW|8+$2L6boFWeN$ z4H$``FPh-?cS-miN@QK#oFNi#QZ!X&_oZK<#1u^Mj$Ze;4aTMuU z&LqsFI46qME=_4CkwZfX^^cI)GTKYgB7yAxgWkK#VDyr7u;OcSjrOK3^Hnk1*ET7X zw7*Q?m_W>W*!}{oe1tg4j~9&L$>tZY#nYmDn;xNGroTxqNDQ%t)IgWirq8wdJgE!} zU%D|P8|Ne>G1%yX;b;($9{c<~!7*Bw4I#GM-|mo&=|0-uv;u0kA-i(!2_`0NJo5EK zU@Y0=3~dS)LL=6GJdzaQVVs-#CJNz9;?EjslL*z8si}B4w=V(l$Vml=X8ddh2+r=E zNUuZz5l3BYX3f9MlExC)n9M&Wr>A~Z1qMs)qpg&_pri>vvsAfgAb2lcM-O<-2Yt-a z3D@|6w@&;mN1zg&i4xARm+iXhwlJq=r^_EVh|yhMwVuv8f@~1%rqIcM*gMkZ)@k5h zN&Nwmsna$*&IZG9!wfg&m?>`G?T6WL=lH4eXdLjRH^3E=Fk$0nb@8Ivs&-Vnq#X)VpH!9+@-N z+#1=RgX}qbVEJg)o8vi8jv5T3MMF@zG6rLGXK<#>7)?^5IUwb^(JdMu?sQj*9WFV) z7?3&}kow$!)F+3ewj2E7Xqje5%kDY;fKvxV9ZlqF?AE32Z%?k0dYO1ql zi>gGGB{FCDf_A|g&^znAtXPEul@b|VZoi87tHE_}ktc+<{mO+GAhbbpy-3$=guz#5 z@LR3VNJF@DNs3#U%V#T=<@w_X%m|nP>T;2#4XcUL49hHLjwM@;X1Y|pe!R=mx`T6< zb(ihOPKNuk!AHY$>x5KqiV>Hf@Hf^5n^^Gs^dS{|hUd45=cgwNQ#s?@`@;0%$@IDB zX%40MmlZ^Nl4LS3*pr~<^gOll+)T+m= zsGJo7HPY-67ArJ%W$JZIK#X{GE@{EibzX@MwJ;`|9)a&)<1#iYz>TaW48RZz+(93-v4reSM!b;w5wu2Yu2=kC1fw&I8xV=+Ldh zR?C#UFu7WW^<7`h7B!Ujc0TnIz}{d&oH493KI}NI`szrpu^HWR7kdC z3>SiQK<_4~Ty94ueX}$VBvCx1TL$@fDIRa%bMGkFCINe^3R0rrE=wsi_M_hZVqW zg9_nfNbNtGy4!+~ZU2F35`X+Lswvg&-)>2@Guqiyh3tHNgTYc+ zQLqX>_)aRNt3BxCtT0F~5WyTwT1QU8!IE9n^z7_0J#`D85=j7r1?t_YBfD+fuw z<(bLkIJ)Opub+ml)3DUB7g&Cp!dF^Yx`m327l93vde&KDj79{x*Ut5^53I z;pf1{?@dE!3?kIg1)a;AY-_!-3_(oloH;NJjm9x=Dp z%tA+ffnb~#RXLqOlq6FoEsQ+r#5ds!|Gx#R<;}Yqqi;UUiXR}G1cqc49|1XY_zlR0 z+h97|NAT6B+p@x;*R%pt4bh$X(bRdf(mIX6D+={%wXE=HG!dC=i+9t3dGqV25&a{o zMWd;Aue3wInVclk85jwUi645mJA|)o0ItjR&P8!RfRg4o+%U4~+M;9U6vy>%X*xrk z2zFzKqQDQYk<e<#?QBvYdg(4G+dt( zX&nH8JdW^cMgy{~GJq8!;oPSK9dv)8gR3PAlzpu<2O~MYW7gEv04FAbEo9jmVLUYh znUh2q60f(jqGB6QE<+t=0taYB=K_LHAe0L|FAViA6Wqi6e;S+9Ppx8W4U0_ixMSJB zs2^+@;l!(9-188trId!NMVc~TG`w6P9%WomI9d}FZrENl1=SEqP(~b02y#X^3>0m4 z2;O;Ts+5^R;Wrh5Qgg&!`?0pb6wZIfoX<%eJnd5~n4M@?^VH02M((u z4@{PJFo7R~_HrC}k3SEZwX{d`@JWQAA3Bd{gx;yd*4wY2_Ia4w2hGHc<=L81$p_9j zA7wSa^M2W#Mm`lX{D5~!vihYN)S8#3lgWrC>KTb9>IFQ_K;|u)tS2v;s%J2o>Y0km zYGq7$@D;@%!wh#hOez#8iVfc00GykqDGLKD|Bm9HS8EOYX0-;|(wmlx1V5nxE2Bwa zs>@dCossJU`~)Z-@in0M8O1;k09a}ul@O2<%h|$oz3^|qRP!aaflB~@uk|`-jlmrM z{wS^BxnL%`E3~cn?8#N)zkR6kOlSBos~dC^MDcQIg*G;5x?EP!ygCW(e)cIOz*t=5 z%#u)NOAGi0Z0#TT3o$fp!7!AY!k5s?v%Iz>WR(s0U;*Y7cAK$$3Hrj8atCqXsAQ~Z zn~GWBWoacI)rJ**SCyMJh2uVt1(+l{<~CZrIYDoUQKMi9fK%J65>UfAUqlPGK%G zdINrbQEsXQyTY46L1g^Hm!rXdd>JyF?@W!(ZB-Ouhi&QkG5p^&>3-H;UUDw(pR)m< z*nrR5fG^m9FIs?F{ZM;jQRXhV(kV1ih=!*4SICW=$7!i%X$PYkw5QxVz$|s3s;uC$ zBbZP4H~ezmAzl9E&ap~cw7?hizK1(w0{`m0D6Y&-vHrXP$hr;b-%4=A{jAl}8Wd=E z)lRn+^yI6u;S{Q8UK6UOT@z-^xgXGRNIDbh{QmTDiG>a zZ9pQ-Z$6Sd#CY_hSuRzwX(Ccso>AESOu|eBNK!b2Ao%};C`d; zK9*R7QoI4j1M23Jg0(Y>pKWOuD2;O^V3F9-JJ z_?RqV{nl6&B4lY?_lQ?fQEhG>k&vZX&7l@U>WaHx!ECyY z@+^7^h8Fy_#2vt8gP)E0xs9`=g1h$OI%!K{7YAG>dP93&z6Mdj<#Z~l*(6dYl;TC1 zUF6S3OM%A#ftbA;0%rdCO~uk5wi#l{>MuZ2S(@Vup&L`Q3G@j9lFJ#I0E>rcBJloU z!-=+#b~qn>Nc#gr^i80o-)Nh5I8BZLkk#ViOt!?DScPpj4juwD;46GYykQ**?2L(G z9~4ewE=uva*C0A&jAm_YLh-bZk$Aup16=*R6*iObEW81FWbr6_JR}mk182_^7#&w2 zG5g+P1%>3_G70BWCtFppHLGPz5?#_(8EIEKevR5kd0<^GHD93Hb20!nK*_(n;RPaW zd*f4{aqcKPkrv!A2gpeb-N1=XxN4%w>qAALFrg4kfI|!_HE2hALM`e*`Pr2Rk(%90 zF{EQtRh^O&X3#n)Z^Xm@$Rhn-Y zy?7~GE?E(Ey!}iBis8bXkc>=U0_{sZ!#dST99+^|_VOn{zzt3Um^9Z|kI;%glq~i7o{|x_d9P zZoMrcJ(X`sNr7J%(JkTZ!YKJDu3X9YRpd&_(;JqnR2s*LHwCZ8^~5=LM6gdrEg_BE zLlr5exuN4xM-UA-TJZT>d!H)s`;)r*&3OiaaHKcf{jsbs1bb*GsSo3uRWPc)3HPSbvn_m#q-O#(*5Uo- z`f0~wLWE9Y6^P`0O91E*C6>k+wN=jmqRBvV9>^bF1-X-gg#Yg*&?<2p<(XHnUCb+V zd=`mqSES+|(83g2<9S@630iiAcUng*`gbPmyA3YH#)|pQ8#2Y#@VpkL=XIaKqi_%t zOUA>H2=&m`MX9ID?>BXWXg>N-@1%_jGZhLmP!eXc?iw=D=pnJ?ibJ?$_2qM{!G6cp51HVal&su3lB2uM;u<5Te+}o@JqM8(m)ky(3f#_%Rmy@%LWV2L0-yLXNa%LZ2hArX+2TNe(kL-IBhC(4dMKxPDpvZBDM3-QN@N`|Q~&U$ex%?7D$M79PZLnBya zNRJJjj5vB}?Z`HS&;!36pfloARRPSzC-_-ouTB+3_M!#gmM7K7NM=i>=29 zCj4k6F~G$~FzUfUm4``?Rvaw%J;#U111CF9l2p|+!Bp5ZRjO!5($WssQyfjYcfnce z!dBVf-bqhOj?Q>Uw9%O{7blAX>D;6xeB@~mD{b8>sw z10ojMP{h0C9s1(U5`UI^)c@jnUG%wNy}=h!OfL5cAtam)oc$0_r<;XNe#4hvt^I9Z zoYn%!BHAu=Nv7TUhtFTQg%q~HqwO?Mu~T$<7=<@gZ~vsz)1mwhnRYaNx@5rkd>wh~ z_G6KB**kJEriGT~X^Jwv&FGsKb*}K~u{1z{z&nSKTIf{LRq=1hZ&8y568-C`Mfi5! zY2nkYqnGD>TW!ccMgONfG zYy2P0S#e+~j%xfL4+`VI>$JdsnyTbz#5rO7V{^lQu{5`X@n0l-ga2buXi;(I5CSj89OX+i46yvAlNk-*z@!7GCRB?A}JacyuSY3p(4iUX`N&H`7ox1vd>3(=-} zq^JXjjzcZ7E8uCC6Gs-DtUds&cU6k)e2PbSefh=yGAd+R%6q=iuXp@gV!*AK7QX!a zgCq&q|He2<@Ams74yeepJB<}I=8iaUf=$cq-Nv_DK481NpXRu-YKyi?v1l+G;@BNn zV#JKJ4gEbsKt%ZLe9pB{g>T-A6K^=tJL}+4Dze+t{)U@cDx#yBCbQTZ`(lof368F; z*sytzLRRRllJ?s?f6npyZ#TEMx65c7dd@!X*jdO}>w0O&bVITQ8^`n_K+A2-c-b;O zo?_mzFH-j{mIHX-GC1e#Tc(ho`nz%Og~tF|*;>r+@5mNrkT}6L>)AYvFpmhgPTi z;IMjzKO<`+Q1$6Och`nfhOL<#919pAyR`-rK$m|h^p1Vup`xGe_b?ELxA_kicg|~>V5sz?QE(cx40t< z6f(vux{rW){JH$bS@$WvD(H3GEx*kR&o(TxiowB#1~2itDorBsgrD~j-MFv(%#>Sa zL=(kr-OtoJR&Yha53Cx8UAho{6kh3<2_;o)m;tng6QbSePGUNA=pzqS?|JZhiljQF z>i#6&^})q9=Tu)>1V9KLM_hFb;NEd*!@#>#ltUfT%3>ffh#XU#6}j;ygy!sp)Gw+W?80}cdX}Cn zoiar|6xvg8dTvvPkl%hA?|BoRodrssBA&dj6W*6)+~7l5F3Zw{aKE(^K7Ejw z#{pqF#|!Wm?_HW*^*?vyL4^x|{$$bR4Gxh z512TM7TO&D?b*wc_iYucac|FE2~8tTB%67&a{dz>AR+{LB4W#C#-l{|R8h%w284ASih zHNFsQWt2~`g~?WwW)ZBhDtKw>r;$3z`{I3(w*HWO?7scEZ~$QJ{yvQ)rC}KvW510X zB(1~F15n}8Ljj~m)Ag;1$;M##nqzO7hKF*71me4TvX4oFx&K}l91!$Rr0HEc4R0^f zxrwqS+dt~oE{8FqGXz>9t~a%;Z)r)06nm4@Tal~%bDmQHN;1ZreZss3%(Iy8_^5!~+2 z$GT08S~ZSpkA00>e?eK{0W_QAqI+#ek5f%k9Htt@(6U|JVbV;DD-DPlko!-*J7#8C3G<@d<=3@b<{2oK%L=0a0Pt1Kfy@2wIaiNWB0y30zv|AfEJ z?>gg8Q92g9!NP#zeWD0gZd6v`x{Y#0#Y99z)`jRqbE_9j4O|iaD}B+2-gAOtqYBDU z9f0G%>8mEXkjQPgPa3h19vAMEM%f+gljfZ}AUchZ>hT6U&hB4T=D}&@l@7j1j8Ndy zvRdR+$!a``4&Ui_Odo#kJ+%3#XEh-BjB@ksnP@Td3O49yxiZQ4)6yc=>FhE_@f93<1$%--M( z)m?U>6wrZ|0>Wix+iuCh9$;CW-wU92Ad3Jg#3f2j}3p8JhYqXuJ)1;nk zEBNc6pqFX_waO}Xbvf@HWaX{8Z;+qoiCpY=TW{axHbvQU-AO;euKhAvmoIE0q$Y=w zXgq;am}nm*o?fqtQRAw8)Ry}Gc?v=Fm%T;rdSkxdQ{A`%nVju}EdnlaaRSV|KoeUK zTkOE-#3P4D>Hc8X`}a6gTvZucj+$~LOOJSg5im81PT6UMA;;o{qw~+-_!=L|9j%}; z-QZ^buqY^dOfcFiMaxGkPjc@g0mY=-Uo=$2+pWSjdIY`F=uHx}o5G*7`kdXp^D_j< z|9X8feI=d#GJSfwg`skn0Xvp!r<-daA+Bu;N`oDLrm``~`g#Etp)diy(u2PebW1+n!J^ZeQKCNb3s zZyIV2fQ$ned!lg(8>dVtrMH_3CcnDjZ=L{$gh}9`D3`MBOH;0)?l#u)s;GfE_vywIu*(8=Cj{J_saRt_uTza z8Ld;bn)6OJXVq#>Qh+okn7W+uw_t!Q;g4}CD1D&fdx%BaA-clTIrJ#OJN3?1SuxK2 z`PB_f@kM+$iCuaQtL-0|0o|>H5yz|AN`KgeIq}PFH$Bs<#n;DWGg_?$GPaB?Wu&d1 zVliTx==W$7X+Y`c&y%PqNAmr1p5{2$9)UI4WN9ulnP-*P>2Z0n1>CA& z5^3jFgmoTtPiWKfexyZFHk{Du&#N4gZB%j^5r!9mLcPvwR8?_gN0kSLG}*wA<|hJ& zQS^FYS=n6LfHk>%axTZSKqyACDWgl_+7J(agWEf8Qiw>k>^D}eZY^Eq(WTBRAPR?> zS+Qy4Rv_87u_)Dkc)o=L)?;l90MO-IS>G-f$g7c8LUd*8%?->RA1txL#~Q3g{wFx* z7wj{xmQ94%1`?Te;kCz8R=1C>_Z zH?~{Y+jfoV-f!YUPLU(*HF9l)vt?#XmmONQ8PY;E1d(}GcQ}QH5lIjpK;?3&FYvu8 zr4)y;PG*HRiCilmV3J1SA2v~*qpsQ5#0b$FV#M$eyZq*C#ZB43icu7R)5ZdAZq^@F78of*WHFE-B$D)jUMf6&fUeLe z^EQtQnEoH2^{?-dC|vG>X2MzGhA_Wv+93}X7h=ifR6&>}cGWVSiF&MK+OB1B+Y>@5 z#zo?nqF9b*woXu>Xa(7F|IQ@1XDyu3WpL*06w+-;`-SKXf|@v+SY@EsDh_R_DOKDd zHos`pI9&rpYN%b6&V{ah3bxa$=3XzsepC7)K8PuB+*v7-W`esjVGuz8RTBqUh{Rek zn0`l_-lVBEbUN2N$%7_x(i!Y#6&(>K7BeC%q&#Nt*m`8}Ix%@KH1Qaj)K6v-;JQ%A zu8pZU^m=N3Enf*~)XN^FJZh*)u%TE-MI7rS#IrKYpE@n*z*EICEx-p!##?aN4)Imjx9HMGCPuWXuxQgG4;zxP%> z)4)!H%G#7lV|X_k!@H^CMI60#-d9&rAf-jpLsVGHJeB;mdk-t>O~pPg)BF03>IYbC zFEi{YmI3i(9@uqWZOo2SpsTJ*m==r5X9SRiaWKzb!%(y7RK=J1#gg%Mt`q2L`soeU zI?q_^FZ5NIJ{C-E0rVRhh?TN)l2kfNA?yW+c*6#?3Z_KCY+8cpgw$}Ot`am-2?h7clb~IRCZ4q^B>V7# zDN`K_RhIE04vxBFIu&!rb@5aWCy{CZ&V9lVrq<5Hz&P!^#=^cq~?1tW@@6fP|Vqlo~z6hXftJ%kK#;2#roMaRq zux{zN?!V)QUcYFdEmyn^h1g><6o|W?2Jf8UwICo$Q z4rt`-jxdLZSuzH#i)2pto>AAYp7=3|Az*g*L>&Q>jp5$F_(JBJQxwe-Tblaqk|mZ?NWDZH|!7EqHSR^>5)<%EBf7ccjTE;X(@`g0!2#R<9Em7 zQ#3`%+X)EmP=wxJbw6quy1q*Ibjt~4`km@b!f$#_W_uAn=y%SsJGeZa{M4{_Dc66* zPg4E~6G+TGeMovAkIg5AO1^}+tw`>`%Mc5 z3xEoy`09JbPX}cNVL|>RDZsxw20e@5k>xJfMDbIBp$CKl*aqI^cfv)wp#${^*-=a*F=w+p#}p ze{}f8*dLrfI{fRJ}Zm$T2|mEre4Yl{G2P8 z6!9yDbM*`pNFno}Yl}Oill@D|dhTj%G(^YSQkGc>k_y%QFR_&fn2e_k3xF*wHr zQn11$Q6O>5lqpl5F=fG&=S;Coxkk!D*3K1DPs^GZ&qMwhj0vQyl=YNL zNJNS@d8A%JhB(Hqmry;6dtz;J$TRb~Q&id)ltS9t6pbjngj|e)TdP@JO4|(ht3cz3 zdpW}pC}1K&Rg~o71pcRdZKrjq^vqK^hde)w7&^`mOrL#$SwN!hVX@;->Kc0uzAYl{ z!pgi*8dQA#xzB?RCS)1;J|Fow_xZMuDQf#Lt|U_nc4vCKfOaBk3onw!?Ca|bRN@gh zYDmuc>!3JGV<2=*&ccA)JL)4VDnnFDMOkY`q*qOmp-g zjV+{YED&4vSTa^Mi^ZB|nKlgTQ_aW zbv7&OHTWcoK<215@JIz!Y`omkd$nj3{2l zDw(fTwZwVZ=PoG+Jbc39*^M$h!MQ5W)lDJ!&YS#{bI8N+V!?eiBt&lg|a$g)OM%KSSx-_4d%YgPJ9EnGC-op{QtKzTC0Ph{>BnSYE~Nu94H z#0}HOI)5oO&UV|D{P6bp9eu}I&Z=5gaOClwU(z3W`jas)`ypg3Gj6W#kGl5lNFVI7 z0Xws%>^HzNI~l;Kq8A+nc7uM<@!h?4OLN-`jRLztL(h1?ZIaj#{C@p0uvg{LRJsN- zl3KXH9sv91^1^RdYy=q|M}Qu9Wd9d<%Jkq9e@6p=rQHS^x6+%)#O+0ndle-68Tm|@ zz5*DUv6|>4@ksRd@OTdo-QT7U-PHk38MeaPE3h2d=CxtCc;X5Of(i6dH2SebIQq3@ zEW*3_xwtK=rFi}6`T6}g^{1FQf<8Z%?@s7raDdCbfi5U(AmzVa!t z_u0N^2nsKVIF(!+G*Pmd&9r|VK2sVxz&(1vTyb(O0#|tMhef$KC%Cdy3t48jh0e{b z%ML&P>hlP9MhQ_nRtn-m*Q+T+Ypi?~s1%e%5f8NwYTEb}}w;Y7jV9ImkF6H5V&Z+<|~K zh19usqFO3(a)^#q)|5_I=(Y;YeqatmWa=t&YE|H7h)(V11r<~25YW+gBLIrmfwU2u zcY&l>taKor8xLvb0-y3kphMH$CASL*0kcd}ViKv4Jc!F?q$;!Nxi_8oKYN`rUMZBrBDl3(9S+$fp zbHzeulB?;gQ4{pLi1@w{0J2Fz*wn7YN2zRTVHZ+W2oNO6CzSNz82vEfn(fDfT>wY# z|KL+s58jUvPwf3Pxx5g$Q4TB5)oUCv`63rAdf^YBA+9^v-)6ttk~6p@M-*I6riDmv z!0C@m5JoF$XawDOhV0SzpZzfEv%-C=6Z^Gh)n@;C2$Ck4A((M=8@zS?;$}0qw(h}$5(4?LA$ux}Wfr5Rl|fH_yVnM(_d)mf zpcHKT022qnb{*CF@7knR+x6eBFjk3nw>AJ8Eqhy4L?zjzB_v*_!0hi}WD<_8J_&Yi zYP>5EO9+^wA$@=p#U5OMH0p%K5hKDrc?9fezsFl`JfwRJCgb(RF$L;~WV@0gY*-D4 zQLooM;5T~44?Xps0{2(@XC3ex@Lam3a+$GN&M$7pZZ*oX5sm<((-$X`w=d5|2ja?9 zJgB#voJzg${&53BWb|>yFRM2F{3Q67W$0iKX+01`z4#cwf?R(Qy)V4oTA9*50z=fr zUbf#ZG^swK&?AT@NmF2b82kNW)Zs3Yk7+SO1vxxbF$8H#6Knu>wYjL@SZyoNr^nt9 zso2i0j37n`N?E{PSqgvgRcv(4_R88lE6%oaKScK$eIP&!MCpMaKBJ|eTnSCc-q82! z4^nLug=21PJ34Jd_C3^tu{de^*^`%W+!9)Ai9V;;nT{sJn%zx^^LFAfgni{ zBqIX+)5_wxu(me5O^#Z`709L=9NV66waZS1<+<`r-RKNKGHVPrLjuJ1@9?pEs%T+5 zFRZKLRgzm;Ur)n3>uz`)aD17pRmIjCtxWA$tfBb*CxJ#~r-^~?MY(V2|3U-~X}_{8 zSH{s*usWAEZ&ukcvBZW&fgXlxrp}bAQVp~ho-_cUFTT_!9SuaU3IWH7-BrVFccWSgC-vxf||!MeRWT9 z=qfHd3HY)SGpTVzD|9IJrMXdgmxYHQQEyc^s?}J=OHbh_^+~%_+(r2guR>TIg7kYy z=__CQpw#dRQdj+kaL*hm(skS5qpbl-OuUYe4k}sQ5*ZETxYauYR-ezHLh|C&;Qm*Q zyHwRDopJDut{eBzZK38Dg&Hl%r0-YqH}DAI344=?Sjy42sec(Wu+WcmRgI$u~Nb)+w!f@0X@7yC1#R-`11hU*7?gK&z1I{RO|>E@%-;Vv^?@EiLDQS z@win7AhHtm-U%xWMgQEoLm;5G2ATuOU5xdA3%_N8;XsNDw?jKZ8?jH}<86dZ3qkL1 z3O?2q7ZlPe5f&az14FvP@GdZ54VZk?W|vL}YH6$n;19q}3)1&#*EYDP#i|bAOebVf z#gQ}6<4D-|b=0&k_Z#Z!h+U8ojNWBxL@34Xc~D49q`@Byz1yc2w{=0U#}VuH0dmRY z(es7F9XtT7-R$#}LJytPM+Z(MOWvbIo&L6wfDdgP{RS{pz3{-_9h^7k_ytT4y}t9% zX)suh+uKP)f}37PcoHi^D0r@5zq`w_PGV^Hf~5_Y z6&~4m2N_CRGHVT5XbiWNHtO!+?PRC>yIK#&4WIVXjifHn;Ts)~#O>cS>c>n2O@ksf zQhsqgfh7r^41?6atX*wy(=ZVJE8`Q1WF`iPmxO2=wp{caq8fmyA$;t=R z|BmnC<9u<_dJ^9n+xO!0**?3;bN1f=2kBJ%kp)%LsTXF~mWy^MArmYw5-SOR;%qVn+ zjjFjd4@>AaT7}&T8*MgejMBch?@-up8Y&yM=~YxTKqU=0dh4de3cnHWd;uQLjqKo| z@|+z@4(!Z7c(`Ti*MQ2mKeuZh4tBcXMWJ;&2Gn_&o0ok^YKA_omq2UZ3__q)`~iJY zG=#2EG4$7lMa~dw;E>!7fKpEIo$f-5$JT=I8aY*a4{6pz|KLEIBZ1fEQD<_yB-MtE$818W9XaHfXIWKziQp z+du6-eH@)knQER$BAC05|1kN*oAaZ$lFyO=N>!=qem!ohvS{$9ht*=*f?xRH28aEi zD6z!hBz&|0Yu2W9Q3slhK8&P3H=s|iSrO>IXaW|;?~cxoj;EvZ33FN8nalX?$?5sg zs}G}#&+o?5(d6vtc*OkHch~ClqwLtvh+#&|7bdytkPrcwTnEHf+Iad^5 z;e0vk#P5zOs%?>1!-AAh$l)I1N|j(wqO%yV7Rx>@8pve+?fXB7bm(C$__4+9Zietn zDVPDl>p*at%Ptw&C92~bzEU!?zUi`V(p-nEcY`L|tuPK+I0XLf0~Y>Yxb4ag-7t20 zV5bCa3!=+@^JqxlTJfHWeC=jZ69m6*ers)#QXz8Ax?J7XZl6^ZImw2y0B(nY&sSm~ z%75hjst-64vQipGF)G)FkU2~yMs{e{G`^v#!%7$l+XhBz(#(V^#OC0j>I8}6Q7C##LXwq#mI#0v(P!qg6!hm_3rD?Ltw&tWMYFhw`M@(JUAsMa@~?LDeeVho&yv9Gy&}`Re=* z8a9E3O>p$(-}z#-*K`fyJf}0E(%f_p+=@6+f$TUhBXUgoW`a(;MZ!tCUEpL1Qh}7G zOA|~N6ER)PJy4}Ewy_b_!WMT|u3^l<;D$pFEu@$JLdr*nT~}b#aQFg@Pa%K!3MTWf zZ4}?vV2%HXOY8N}(&}qX&4%_qcd~o!jy>+qi--odJ3P$^BJW^j>F05}&9~~dQOh_s z%K>$j#)f#VC`lDQeX2_Pvo$8tFfc4#8+9&? zyep&bg^}ZmB0V2Wn9wf5uI#pD`;3M*Rsfj`2{YkZZ=IkLzpP!&Zrd;new9L}4e$d0WW`XRC;}{pUiJjLI1UpC8-l`h zn&yyqFDY53m{N&b_Y#0K#g7u{h@ukdIL=AOYqtHf^iTJcb*phGt1Bpc9K<7^2JtN_ zOmbi_vRJSF38lpMGu(crue?s#VVwUCWBiA!K^`8x9I6*XLx&Dy98D-FyF1%My?+k- zOUyI4IHf}BU76DkQgLAisU?oKe;l@H;ML-{vE=!;;5X0-HyyYf6u$Gq^wA%EvuL+& z#$CQP@Z`XaM7TNB&o`9P%B^ zhHN)1D?1kseG1~QTI!-y5e4uDrf{dviCeXB)~@4wPn;T=MSDH|_N7h~oak^W?p-{O zDA(R;Zo@U6)_>O1$4U$%GN}kBfdCqUNXCTrI3<|Y3D%S7gq-XJSOTa^0m-xh1e7|_ zPU@PbQ0t@qy?O?n0N!c9x5-Lc!m!F6o~eN-7ZVynDi|}H0J13{?HWmj z(=zo5zEZTkcT`Bi#)hLhAp|8#2y*%~+CNhF&|bPGOokJ*Vrxa`M&K~937GALb4Vd!Dc2ZBBYBLnh6gYb0$g@KMJf$j4^_09A9PvDH8_R zOYb8U6|DX~r6o8N^ylnHMMRHPU50^D5*pMl`UT&8>wnx>l$Q_KT-41T(@b+`{_gX< zDNN=$Oq*JW0J1!XX|q^i?iECeyrfo=RS~Q4WLZ|=$n`*P9KGb{*r=*1Qr+0L8SF#N zj=`j3f#ny5ZWio?ic|e&XjkpOerzw*Zpew)G1;2<`D4rcEtG;Ek<&X?hZd!T|hlbjB4B zpk?7gM;#aHIL_$GO$ec7425!O)n9LNaxT#7d^3J|@+O>yaB)*TMZq>ioNebnJywyb zBHDP~34C`s&Z8JkVq@NqDId&AR87o1< zs0ACwTF^2Y!IrTRJTY3qGh@rhrKgdmg(PiBZZ%nL#kj%>k2~`&@qdsO-jGFu<cK0?3j?rSr)|J`0ib4>VK)1FfT>_d zJaJt@I((5Sl~BMM$20Q^e*M#LmWO0ha}(xRI@ieU#b07ks2zswBGywBYKK|Y-tip1 zj?l&yRJG~09yE7b=)Rlb(p`9mDg`K_)6`3?%`YE3as39-j&tXDYpJ$G5C4;br8B7t z)Vb^VK#iEJiwXKRsMGVAG%Z0VzK_^L80^7X%G6DyyKRtEQoyhsm7F@+U9PUDUj#M5 zvPBsBv97nC9u33dKHZ+6L`TMs6J@L+U1jR#=Ly z5>t_eX5f99Bxs{sXT}t9>3S=QN13lMCt``X=n1V%ifGH!!9%DS?iVVnZuWia$URuy zx~n9QxY?oxi-XO_m<0T#r{RuNC2%C?uL3vxwVS7-t*K+au6iObv?izGxU`&l{`-;a zW3RLALcJz??1e9TWl;DWl^O?~S!xu?&?rZeQ3G)0tu>Ch`)*QXO-3w%HwVsd??RQobYKO@4``IDP z1x$}R$l1Q50&=Kw_cnqc*L0M@)qF`8C;&gPah_L791PUFI){*C8G>CNX!Ck#5%~RC zlW;Lm@7o~P{V*a){Uhu=mu9D7Fnlev0S1Oi-E8Q+_clYvNgP-R-$HhmI@~+aYs-@2 z1N?yV>5(iuw&U*XOM1#(qLUjf>VSS$v%RJXXjoPM*z^I8PS6lgnv(Psp~zDe^x8{| zO?BK&5kj4=ZlRx>^f*4g{mtdov?0tz;`#D6`=S6|B`=#YkTm|R#ty#!So|L{(wWFg z`E$)gRytsbR&}%}So!Ic2GHa_5S9^2oA?a{!ZLZm_=f!+5l9o{<8B~c!0M(_JuYLQs%NNM@AZ;%ybH=;|5@nT#&ptF+m_Z*sQ>iLKwLXkSr3^ex=yi5uP6O*&N#DlZ(n8Lqf zdelSW?=K3s3Da*Q3Xj>428r=8UP-NF9f03w+~=_(Ae;| z6Mp;hdcLi1Y_;jT)h+2wiAI~jZC(C&8K1TOfWF(Frd^Yn4c3s0EBr62{Vi+xvJ0g#>fQX-mBwa;OMlh#{%Oen;7 z6A8W+oe_tGeon3?FdAW~;lwdOjnEq1epZ8uCI)4>a%3X%R6}nD9WEgC%*W{Eye6YI zkc&8$QO3=bY?sha>4C<;mOuP2^vzVsA>o(XD12tF7X*^AT@rvTu7q*jrFHQ@k_?ky z@6j0@L?wNZd6GN{Tl_Zm{jy*Ms7XoWk7c_A8c~f7dvf1>=Q-;N^yx2KRKjY}3rj~J z$??8MFaZvMUJ!s%SN&sABBl+n=4f2R!WeZe3Dt)F3*4DvIFb#`Sci zUH2F4exg;%2(y}cs|texgqC8qCa>{E-nW*2d|D<6G*SvrE=?TACW7$>+mDOi5ze)=gD+%$n*PHBWNS0KN#zqt$YY4REcl9`EFH5K)50ck>*=``C47V+;uO`nXQyrj} zk#jMP!9(p1?5W|nKK(3qh{W?K<>;nt^?d}C?`K75$y0`s&wYtLSKBUgV8Z^e>WACMT70otU+`I1Pqt&x}Yvhd4Jq-F} zaF4`QRw=2gREB)=vkg=#O`ch8(the!GypHUHDx}u97Ys*QfaXYJSkR5IyDhPV1F6 zs8lAkhrL#YSW{FX%G~d))w$y?SEmOmqi%C*^3-u4U2E{Zu6Be_7J#Ptnt@F7HIlo0 zXb;N_52)53sYbJfoq#rga~h$~2SjjP&p+}QB&5uul8_$l&w;F`v~e>>Fel=P+*H3i zw;W0T2-esY5sb=oNvsMJ%#-HIa$P4P+YJnL*qu zYU!?oR}DIZ+4WA|rvU-aifB4J)H@1lPe5(q0$~{;w29wPAS}b= zlDr;*Oi#rKCQA}~ig&l15ll`rGiO(|?*KVqS=Nvxsur?|3R$erOqFH-#e z1YD4bWSZ;X#N;AbsOcnLOpyn?bsxXZZ3GQEH<1Mxf6vN!lQ)qC3aJk`ZMB(XmME-J z`wfuH64Yxte&dk4zmKrL4}YJeOv0N)y}PiBp(Jv5p1Gmwk$HJT1z#C%JK)tV zvKUgp!TN$hu=pQn(C?|k`K8DDl=eJTHl$yadafF>GhPphLIve%{CLG zX@rqM6CqjHJ{~BPIhS90GO=hTE4^D=Ruz!iEiMt8Arow5EfR?qxki%JK(Z>xKm+83 zPn}Ln;wwq)ATH@)Mp(04O#|d#RB*@u;vn>>GT!xomvLm``apITdIWbY5;`YV36nH7 z0jfmu@;er5DQp7MJp* zh0HFy4&o~*@fGABk~tE1rz)NU;B(Xl`XnDAOM&-6|BE&N08u7t7~t`2d0UJ^%y0{j zdd>AU+*4o8O535`Dc;6#j7wCMuilo$hU`Qc|4DgNiAwwHRFIFTrrM#N7p)oIb$Gk7 z_Qs)PRC^O@6f#T#0!TUdNMtsI`g&FGNC%)!<97~(#Aok+{JZP+4<+d12wwX*f~%>u z-|01iDL7r;m-&9*0_jn!>qfA3SD6l=X5@JcD34w5mf5 z%@IuPb~Oa_=2jCeWU*>OvJv~&q#T^otC@7VKd2Dikd}yd>s9s{1YtkI&}BKL+^7yf z>nJm+p(m6zjx8l*mV}KYpO#@OppWQ6x5>Njf4q3T%vQAl{$?QJKI@gK8RVzy_p%i^ z0G)rNRZeHt`1+{98mCpEWb$UIr!?#12ovm9$?&3VVY8n8Jl|cnCh2tN&8gb&^RWkt z4_M~_E;-m@G>duR=`HHW>h=>>u3z6DBP3v2!3MeYhdz_o)IdLf@9)gs=^J)IZcA|> zBHw>9CVoSKL>VR{J3Z9o)GV`YNd#aK_R7F-1b{_&kYUY{0*G86Nv}pRHJ;-Y6{4jO zUIhW5DImv5n=t?^lEFNiSMik9^aDjCHN7lJHVa`ilMjSta%4>Wh60H)Oit{yIYK znj*wmNa>l#+5Uc-0MELbl|a`~-m}30NwEx+BqfhQ@4u4;%+O3{`+GyQT&;UpZh^hN zBUg=8uwLByJtL;xlX}<*7yz=TJ7KJny6i2|Kv*V|yk$lk1FUQ5#nux5y{FPf z_DUjsB$q@QCch?BM+73yuQtE+oxiezg++LsZ$GMHIgpViEm|nOa<)A`$t)p&sQm^= z76FDYdC=+pH}wDl$60^R9$~3bdn7B9%g6&wS|V?4!(pkcZX-WxG9)7F)ddAJ)BO5CRu*-z zk_?6;k!wf#EQ38+Wf^=V`rYdNU2;$8Eq%PYB^!Obx+M!eSslqjPgX~=$V;gry9@{G zyp-_h8OFu98IXr0@nJs71}nTX^|-OS)GJh-C${bYrwAXjce;MHsB>z(IV&WWJ;w>lsYV zFbYJcfJf#En2H!gd6@!2&m!Y#pyg*qDMdfaSyHx=saoIFkzJP*vI4rgQwmx3NR~lE zuuAjaDEkDa2rfd>Om7*~th5-3yr_vMqOSgST?Mkn*~(um!QhJ^{pdOTafsxyOo`2j z-4dH9|IIFRjbvNoVP)C?L}1Yv5R!c3^bb;M23O2#L%xVVYrz|X@w#uBGBFD)gdRbnieD+s)XILqRZKTR)bG^P0^PF1S z$=K!xi^hYF0o74eT7-Pb<2U+r8Gz&LQ1&SNoHT38PPZINrOgkw^qE$lOG=rPd8I0nF0WF@oi0@ZPGlaWG8$WJUimKdYoUB(1>8ZFwYet90#Mxhoq-8Z z?+hFRu@+`$pqqj0&Oj+_O|TA7C6fCKV2P!VmY3avXB)9z-aJI+f5AZl_M9lN&LvuT zMp4_o24?IP>M4#o`&AA*!zSy5kRJUU{b2x7hxKOo|LLTcACQR#H3iW5cA;N)@Eq|V z*do0@)B|u0H_#`!gDm~_G3bBM1^^&pV)lnnu4g@T9zpc#?gXL+WHA&qj5hx|Ov3fi z<6M)6If^&weMH@{OX<=w^}mO9(fLpA=gak+@EGwuLL8z)iOZ_)9jb@J^UvAcA2(G+TtI^@b(#)NEMxAS6D$&2F#TKjiu22;TlUf~z#L2#|HR7=bYgg<{8JJI=M}C?*tADY!Z-2S0Ya$EgmzbaUgcRy`Qo_c4pXlHObrl-$! z)kL$;Ss_RFv_hQUrwpr*GpBJ)OFFb&0l*>*ru6wZNa}T&i-1zv>mctwvk-{L_v3cb zAYaa5#H6g4Omc@Qp<5~lM-NZz{Y3>vB9>7u9uEN1D%-{c?tab!ohQE}ewepcjDpY#fL*PqXFTg#KpEv@{aHYITgBDE$i#WoxP_k@1L+nKwS@0#_< zriPJ04Uqm0Ca$Daz_O*=L)ITwq{P*T)qYP=^Yew{fdd}eS*O>V>^U6{Uf3mdIxRzM zHe7yAZO~RTNoEOZvnMU-+I`PP6#DjeO}S^*#F`E^1|4Cg*Tfp6)uIEC{@4LrWnVjx zl;|7e72=TAXCecUYsjYcK{0!^57$=>kY0A}K=it6Aa+p&OxDZ_h~`LkO7y$*0p`=M z{vK^vF)01V-=D@G|5JVU?^-(0dvA-~H`ywni@-OGF>;lBVQ4p>vQ|1rSWiPPHNWaFX*Ns>+Um$V|e`i0zazdVnZ9p<|Gz1ROw$ zJ5)A34~K!ChXa@`jX-p|CJ@yFwE$|hSsrnbLM$NjOwsy(o3V|=&i`yy*(Fb#X^W~V zMFdPt^70iit-IV4>o)|k>17FJrz=lGL=Uv3@+?9j zFVauHq;2m4><(~SROfa^bu0N$U`7~V>96#cAdw(-MS7DrF$plvzjIRsg?xhqbPDv} zF9sii!T#P_AFy4KQ!Ab)xFQn z?mXlNXk*FU^H`e+eUI~PQH`QjhcI{be$bEq?C55jUlKh;nt@Bo!Fl4(C_^EYHom9e=S6?IuK`=t8w7d0Np+3Lk7C5c z|B}C5(A*2t+ARC%>)I$}BshTRk>JcWGMt+vu#C>Eiw}icM|$KlF!2dZgf8-|Wsr4- zM8v>U-26ZkI-LxUHSl&8{c6WkOz&O(dg@h1;1g+>{IWxN6s979{DM!>>E;9MXJIwi zZD4S0B1mf*qw18kyCai(G$NuwvaLNRaPEGzg#-c@wost?IhnQ*NSY7EP}1B-a?kby z8k^=`Q^v;q^}EH6w9F4e(6?*?VHshx$-JRJScZw(Zbdxy1Mo5?u^LIbAGHo|lzv65 z3gL7=CF^c@cak^+5f%1<@TXtTX@q|O(jPzQi2SNQ78r6HSbsj%jX*DJgvdTMRvyS$ z%?POPMye>{wJSwl*T>5mAbUFBgDo#8vk+3Bl2Q)iMu{eNXF_RK?X?cb80)m_&tH$i ze=|#1HIQy?4 z2g1{`Tn=eW_pe_;9<_m0 z9pTKcKPPWJi1{KkkyRH4>IsXkZD5cJ?+9^9>M6)xwq+V7=XuZ4)l0gkM{<&&{)yF8 zAxLHk>eF}Xy3hgWEXfSO{!m#5_G^++f$X=l-^<5ohz*z%4?EoI;}>TO8VJh>qfO=w z1;R2+&P&R9L~lF(tuO*%nZnqPe?x&p879~tcXC_DW{E;5 z^}GR+qXhM@^5WMu-mG6e4jAe;6l|4EhI(RZ57gE}6Z!l2;pp%EB`r6HuQAYAn3F?Q zfMk)NHbdn$z`ZPeq(jfMn>&H%Nz(?l6yYnK7OLK4rcff+ko`J_cJHAeoxOF|9FButtPTnAIC@jh&)F5R|ZoHKp!cW4OSre)cK+C z6xB=E70pgdnO?Y0HGsge2o+lc+N|bxEOGKzByVZ+`?sjSKnX4Jy&@$BLA&&v> zJid|w)iDslsD#+x(m`D_q-L9oEy?vxl~g3J?2?!zP=ANNK>q2k@PolY_z41#a36*z(D_=U7mmGMm9LpLzKHhaaau>5nZvpS<^Rg!E^CtGV1q8Lztj zs>X^Pda@7A>6x~Hr9mywbQ)6~a3H%|fHj~xfZW5o0!W3q%vVL?nYcER#T!4XzPCqB z9{`ImSf#D(JGe1d`9SPdzN!E-%b<~PFr@H91suZY89JW9UheZi=5n6{GMD>CAbq*7 zX@TtJz9y#Nn#@pFR*g#Z7Q01R5OdwnA?*f@!RmBQRpY?qP9Io8P;=oA{$JE&rj%+@ zBD2gDz#4?>;@>R6;44V_3g8H0uK@bQZp`|EVm1ev+9R1+gbHa6GPQVEi#i~E1+WLX z4V>Z+Wq=u~kjM>WeFd-sSj_D{I5gJ+Cnl>!`nDgk&bx&{IR;?912IGC3&@%V~|dJIR-h9 zbpoiHpz4YBy_bf7zV|Ygk=zm~m@FySNPfRRr@jk;L>{9o*V74LGvuDvGJDqYy-eGF z<(n&&1juk^Jz4AQlEBz-B>COUItI-yXQm|I`*vo>>U&<#Y$vVGZ^pH`Iwdwe%&U3% z6V_KWrA)2z_OmWrsP1)1vr)SI-sH$y{BIYuXJvk&vge1-Z%rOVBiAM?hIuxoht4lf zB6EeOat&oBIlmZICT!82{y{cR#N5}KK=ger*qHlT9f-bXbO6c5vd9oU zmW6kF!^i{K^(mApO+xJ_fBFtN86$o){w?dzeFL=H%&rKUD?n%~M^x+E z;$QZQ`@>JnXJqMZF?U?G6!arISf_MdEE)(6`l(?wstN0n9GSt=p@5A+C9G1Q z5f*70I6%}35EF>nmxnB~;s*ZA;LF3rpcz)DbxZ^i8#00DDYy$nB0B(>DR>XGtF$$s zGV724HRLPFLgWVW)|?C+!ZBemwh^SfI3PLpL_3VkiS{Fio@@kSdy&9KIgGizBP5G- zKmR`OQ~3Mxo7y?-fv)!U$|1tL9r=f@b6Iv8hQaWf*Wd+c>LjOKG6M`Nn1P-(lPhHg z+MJehdwQbZk)=QG*)Zsne9Lj_*p{t7X`WdtI>l1%g6OjIhvH4;vZE#ubp zCL!EU%9M9%u1_v1^*$)M8q#)(;%26$lB*$mBu}=rQ#7#ju1uqnA*C%8k@uy8!&7E! zmDwn<47Z9jL$X7LY|A(9V>EmY`TGRv+1>XcWd*OCqcP9a^GE_eXW_pV-mOVx$QyC$G zF&WuJsmHgu;ycmmo|`E+O|WkZLPn_-@ndXBywvm!*wres7r?$6rJzgGD~Zv44xe7Xc}wIcFLYOJ<)Ca9P%KaHp-)%X+;`n? zOH&!eiWNES)3PCHER|NQKPU5H$!J*T?B~5rz#DS;HX)2L|CR`KmP_$hn`QQqNY_YK zG37M;v)#Bb;OXXH|9EH_#_)OYt7tXs43sr2-W%DVSiiPY2|3V}NHy|dgs%Pj+aEi4 z+<}~rL(}Jn(FarJOVfCf9?5N9dSfIezr2yjIHO2ZhKU>g3S{fRC>DM=REx6@Z?YHI z`pdNkN#{v5hz*6lLi=xwda-hgsOTR6DoPq}FwO)(MdV)w7_Mm8iY>d`&(ARul_epWj5CTvWijzP#%P}pvEPmh;XSJx zU5khYbG-I0q2a=igSaDmy1;NJE%Sc$H98uR7Ua8+WyCDVP#@F)i+?vFNSTizcuEzw8+(msi%2yizY=p;su|9?U445BG>rTpiCtBNoL)c$$ z`Bg#VS~PoP*tKXFZnOk!>A)}A?tgA_9e7*#(SJ`_yBsb`V7HQd=rsp?O8<xH;U^ z#5%mK)#}SAwGMbKvKe@sm_4y}#aC-0?RT#-pkDJ@kZ4}v>FguM z$Lu540_!wwwW7-pla(!z#)$3)eH{ZlTw(uZd&=YGCX(cD|BOjDqKQNqUJlZ&?3gBj zZ3hceI}4Z?Qo=@@)UXgAl*2NlhqmP?MgfUkfozb(703d%Kcqii!t9zr&aC(?)>g1{ zxTs+5!?}gE4`+b2_Q3<}v=dICO}_EzL5>m}B=wpbR=lMM0ilFFEvjH;2EfY}Ru%1u^s>`_S;Ig<0}%8Sr;Hg4{q1yZ@4x+~nQuB;T_CxDn!v@7`S?%R)hwwE z!{Ap*a$w@YO<~$zLS3f+KQrylbbDhsq(K3`9 zI)3cdeEuX~RjqPAIY@z9uGlfiQA-+jY{0gSikeIs`qW-Y1)J2eWs*#7PTDW+&39-} zHJPL+6<=_8cNa_ZPAX{uCAPGg)z_9jB&E!e-i28SONy_sefxW#+B2-}dVh)we@-Z1 zOUP z(|d52X-@nL34ZUPw6F=ZVYb=_ls8FlL3&=BNp)95BW-heU17IMYC z2RZOyHMcxCkT=}eqWnp}YOo=Cx$H(WmOemmcSm!_Gn_sVBH=pIKS!{ghe-^F5W+Ga zk$AR14Mp`;TUD4(zDI=!`DIba_kb>xFMz>7~j^l@u3EHal_o8-6KP07l zzH}{>2M5XF>%!QNSp2`~&>+zvxmCJ>*M;%4LCj-v6wetQ<&VwrfB3eaK+e)z?q#;IJ(7K$sOunL&V2nO#If6b0Y=uV1MO(rT+#SJWz zC{3n*JWW{U9*MxFsa#TjluqJ+wQeSpIyGF;qw0;p$)eEHa8SaYd_w}`F`|DFlJ$)D z+D5IqEz|{?Qh<0gu5b=d!_bn7`4($BI?F~t>b@L%jP6K**S^JJ2)f@MxDglG*cImL zR?$t((AWdl!cv3Bf-<69oOf=~@0^wzyfiK!d+HVx5n%KAbUdE3{63>{BKsG9#uk26+U#=2!M%l&;7$!oZ;#~- z*M#~;U;eXy=xIXA)dFe*N1q|u3?1Ci0kn)E!u+`Tfcv#OA_sNF^?N_+$Q zv-^;Lx6NY>#6n>ad(myZ0m?cYDQ(~WohR<`Vvz)Npl$&6f9LLSKx?39_s}Hp#tyuB zz|hEzF**tCu{nxr`L9!o#aS#wGEl}IUH{LDIFF1-2G-b+Tl_|xU(4QP#eQEOeEF^7 z**Yt=!seEq_M;+fn~eE5YcTYzPqKE;*oCS2L#AYP)+E4RKb`v2pW=?S$!!|=L->+v zDA+`KUCW~mZl<&cg@M9MTVO~-$BA`0Q=fff%RRzf{yV!X$&&1(EsuejP9v>WtJP|? zyILt1v8PS8H8$v#*wr^TE;2UDc)7A+6&U}42y5+DX|=$3HT8J_J4-uXiIKfFebMY= zjPdXGV|;7YTpMOc0NLFoc^Htlaz@O;VBVKIXfQq9rn4;1k2F;xNuR?L=g-`Ba}4>o z&tl*xL)AN#Xd7}}3sFSN6|dzk&;Ah6+1?1ktcQse?#Fk)*;V5dyvcdowk}UrA@Aef zCEQJ!msRZ`-vQ(uhBsiK&daOES(*y4laWOK_)`2XMUe&-@W-D84hpW6S4X2vD8xbkYnf4tck=R%ZcamPHT}9>Ixz;7KTRM4u}VQ&yA&&! z-9F^9bLiof+FYI_U{T=Tg8+i^R#>J?_Q{k%NVg;vPIhp>4Ygy zz(Ha!qWmos5Y;+E?e$p*zVhbAX-Ea64l;_ZsL>1H$-C<909JTP@_i7P*(b5o@n8gT zpDIU;*%j0}7qF#?9M~`!(zhv5W*PXD5QF+BNV3;Ug}!eHlj$!FfDL2B=&OT7@aXtP z5-A`sBQ#-LV1Q2vz6AJ+t%!`3&(#t60L_6Tkt>wQ z{)r+9ZGijMsfYZPi{G2&^Jfpc9lmut;QYMhy%nQk+`6@c?O{NA!K=@wMl8tW;%}`` z(Hbc)@Z@bhHEfahjJs&4(b$Z%sH8Hr%dvE+OB>Pvk%$O&lN!<_(1xB z`C#%ZyJ7E7wwy5s_#pyby!gH|R!N4a_0Q83Z#gKW~3O8Ry2Gb3G%6Q6~Hs>@iKX2y4 zVHrLSBv(YiUWSWWDbZ^~%C>RvieaSN8EegT*7r3qdqQzUz#fpY?Y-dV<%Bx7Pc{Cv6ql_|nSL+($5 zIVBgO4s0|7Qr?*@yg!-&WA&oJ5acq?qyqc<-Ky9CGqn3~{9Bn73R55Uf)gAKA;Whg z)Tb17MTuV^ZStfeqB&WLQsqV=+UhEf**nd=j63##QTn57JFsAxjQ)5q`sL-y6sDtl ztB*nkbQZ7#rJ3D~8`C{H0SXSAC1>bq7;ujr-qp5PSU{F3L~OwIX~mU*`81B zmcIYVbWxyn49oFHXbvC)E5Hv#)Jys}E`pus)=AW=^io#SC%`S% z&cV_rArZ%|iM5Dpi-;JMjU~N5KHe9pl?xkD%Ly9M_87+<5s` zf;x-);4rhM-5K)x1FL&;b3h?1(5|3`+0`PLzcN0|h9;Ja@BYf&g6;OwW&ZQobit-< zXgdV6X&Cuc+xLe+83KXXK3WMb<0Vi;*Y>zhUYEGUz26ghk-1f++Nn{Z?{*I?YzLC0qk}+ zxpNEmn9baDF2rn>!MPaI37p2}kMMrXrgNNmC`vP4*@OhI<4RKlTWzjGtv%0pH~oZa ze)~4leu>>?=)sEnaot9F^ZF_SkAxjINiEpznnk)z4^SZ!E%F z1&!kSK#gkd8``yTz3qMunw&JbjN0tMK5QkM#6V&N!ma0691cNv>mb2Pfrs$1D2H_B zNg`bUIk&Pc_q@PFNF`u+;imgCC*M>CYH4fwkSf#oNcBPlozH8t*$_U?0SmL<4%PzG z39!di1K>mkAao~KN_!0|++?H8Ebb}Vppbea>bi|CTGm_Tb|yyiIYMtvQz}Y_Q@TX5 z%78+~+>;fW2EmO}Imcnv%{DK$-d4bfi1HP3EQ;6TC*MChefjA0i|1e6+%UW!iqT%s zyK%fI4Z=AI7_vJd6ao~bzQKi%WsNB&`s6HQVMupjK;J|da*RK`i=8bCW(%5qs%Kv~ zQ=j|t2Q44mPNM-RJLbo5*YEMJV$daQl2p{N=WPxtZg^udb=P2y(`Y&4CnqbO$t2G< z(ee&IxwGPEmn*zgj+S@%$z5nJ@Q)Wl^;3TG>55;SXHo$2r~J;n72j537cK8ise<2k zc?C_T)*#+ps%&;i0hLcoCxNvSs$C>om~R60kEvdX6v{Iy??j%LS5Uo!)jci7O6TGyR8ig`en=Jc zGVv=as-*t6R5p2>_yJY%k3MJk^Str*RHug%bQ3wA)XgR4+b0IfRGQ;ayky^?gxQz$ z*!sJqg8v^}R#ZkAe$y26e~$2G3;)B*VTM14A{qYr*lYOzk=U>m>_u-IhSyrd5ls3$ zBJBp3%-^stLX^I_5kuZhnT5Pfar;*zWF941Tp9Y7qv$3!tM-C@4yvAupo05#u`HI= zY86ZMId=>_d0}O?fR{;ASChO1*d))^lcG$;%ZoB?KxZdwyZ{mvcoiR>6#$hZRUN6< z9<`66&8ZQMC?`|L$T)yaFP7}ZB|RXJtiC<1emQzYyg(MbHrS~ zMl9|0+*VHpK8}uJzH{4WQ?GL^yyjkX zS<{;x@i}B`>75-^b@cHJx~u4e!4bTv6fA$si51+-z9cUqV6ay7w3oAc44d zCrJsenkW2h?(0V2=?!dvxrsQ*$+8e9;o>Og3zrf>9|{3PAJ+uCdfL*tnwzb-?48yY zGP0ui@OiOGn(evdgQg%4cb18CpqU%cFyjxydEu%&x_O*N6BPcts0;x*RPILhDsmpo zqQcs*aK5IWSf-W}w}rct@X+oYMRO`ArjHGj<1RzIrURHtP*kIt3ZRpCHcvjU<_Vlb zYREawR*pOq@F;H7ScfVg!ixi(`t`px%2{0K_nPP)&NMCEb=r1416-dU`|8S5+9XYl zR(Jdqc_fN8vp^o$I=SxV?4Z^(g>Tb!?kOwC!7%Z`2iQV;DPRs915My#Y(@2RK$I3 zj<3t^L&~o+khzS9=HM_7cn8;s;{$Yu;Q-q)+(Z*tXX{)HtVzcO78hl;8|1KS2C0zr z@@fnRfI)7U8h{!h>^Z2sP`$eLIS2=`1e3F=1a8(GqrWlZhi4IT{{(1rsC}~w5#m&7N$R7RUt1xeG8PGJbWw+_kVYfkV-hG#j4flSn8K;h2o(wO?%?P|NTBz-r4=FM2TDjty+z~iz6cN`RErs%kA1)IZE($!*Q)oYbMwMg@rI>w-V*kzh=G>8Q66M(uY9c->?45LB4}$< zet1@41lIhL%z4FU;Xj(>@g1VDALO|cEcL^b-imt@qsHUhg}rw~_A$hwWBj|u^n(wM zFF6f-h^SgcjA7hvI_(4qT@i&~P-Ip#LV2dXNCGRtV;DV}yfZVkPkURT4S){Ym_q9( z9r0S7IflHnZ?0EugnC4PeO1VhYk;QpmQBCFRBeh;W406>x_X&md+0qdcpy|N*k~!P)9BMiRux!fWU(%S*h4Nw$fSC^=da4Ngts z7yQh5b|#@2f*pLxjqe`a=dA6EBHou?;1A2$M+|8ALL(xz`kqnQNYKYA;NU4`EHjyl znCUDF1BfnSR8?Wp8`J{|VCP?hFnNVBT}B@pp$cbb_(|T63TxmoEBriq_iDi~ZIB09 zJt#^!&?zQ-h=ikVuF|-7CBP<(+RoFgdbdFc^}rBj$J~3QB))Kr0^AR<9Y?Wlny z`^}9`d+l*MyMlwTfYj;BD%m1Wf$*BcNVf-eJ@HOUh4GpwFMz6A`o#KO*g}5-d=~#R H;4A|GFx8L> diff --git a/examples/ESP_AsyncFSBrowser/data/worker-javascript.js.gz b/examples/ESP_AsyncFSBrowser/data/worker-javascript.js.gz deleted file mode 100644 index 9cbfd2049f4dc579c777e291376a775707d0a573..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 112558 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

Fc!=jWPu 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 diff --git a/examples/ESP_AsyncFSBrowser/data/worker-json.js.gz b/examples/ESP_AsyncFSBrowser/data/worker-json.js.gz deleted file mode 100644 index fec1f65b323b3e5e21bf3b6a4945fe7623628312..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6923 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

(-c^| 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 diff --git a/examples/SmartSwitch/2.PNG b/examples/SmartSwitch/2.PNG deleted file mode 100644 index 6c02cabc7a16ade2e4e4e7003a4aa9ec145b9eaf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12835 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 diff --git a/examples/SmartSwitch/3.PNG b/examples/SmartSwitch/3.PNG deleted file mode 100644 index 258c51cc9f14df2753a0a4e82cb97681b53d81d8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 26824 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 diff --git a/examples/SmartSwitch/ESPAsyncWiFiManager.cpp b/examples/SmartSwitch/ESPAsyncWiFiManager.cpp deleted file mode 100644 index 44552582f..000000000 --- a/examples/SmartSwitch/ESPAsyncWiFiManager.cpp +++ /dev/null @@ -1,1177 +0,0 @@ -/************************************************************** - AsyncWiFiManager is a library for the ESP8266/Arduino platform - (https://github.com/esp8266/Arduino) to enable easy - configuration and reconfiguration of WiFi credentials using a Captive Portal - inspired by: - http://www.esp8266.com/viewtopic.php?f=29&t=2520 - https://github.com/chriscook8/esp-arduino-apboot - https://github.com/esp8266/Arduino/tree/esp8266/hardware/esp8266com/esp8266/libraries/DNSServer/examples/CaptivePortalAdvanced - Built by AlexT https://github.com/tzapu - Ported to Async Web Server by https://github.com/alanswx - Licensed under MIT license - **************************************************************/ - -#include "ESPAsyncWiFiManager.h" - -AsyncWiFiManagerParameter::AsyncWiFiManagerParameter(const char *custom) { - _id = NULL; - _placeholder = NULL; - _length = 0; - _value = NULL; - - _customHTML = custom; -} - -AsyncWiFiManagerParameter::AsyncWiFiManagerParameter(const char *id, const char *placeholder, const char *defaultValue, int length) { - init(id, placeholder, defaultValue, length, ""); -} - -AsyncWiFiManagerParameter::AsyncWiFiManagerParameter(const char *id, const char *placeholder, const char *defaultValue, int length, const char *custom) { - init(id, placeholder, defaultValue, length, custom); -} - -void AsyncWiFiManagerParameter::init(const char *id, const char *placeholder, const char *defaultValue, int length, const char *custom) { - _id = id; - _placeholder = placeholder; - _length = length; - _value = new char[length + 1]; - for (int i = 0; i < length; i++) { - _value[i] = 0; - } - if (defaultValue != NULL) { - strncpy(_value, defaultValue, length); - } - - _customHTML = custom; -} - -const char* AsyncWiFiManagerParameter::getValue() { - return _value; -} -const char* AsyncWiFiManagerParameter::getID() { - return _id; -} -const char* AsyncWiFiManagerParameter::getPlaceholder() { - return _placeholder; -} -int AsyncWiFiManagerParameter::getValueLength() { - return _length; -} -const char* AsyncWiFiManagerParameter::getCustomHTML() { - return _customHTML; -} - -#ifdef USE_EADNS -AsyncWiFiManager::AsyncWiFiManager(AsyncWebServer *server, AsyncDNSServer *dns) :server(server), dnsServer(dns) { -#else -AsyncWiFiManager::AsyncWiFiManager(AsyncWebServer *server, DNSServer *dns) :server(server), dnsServer(dns) { -#endif - wifiSSIDs = NULL; - wifiSSIDscan=true; - _modeless=false; - shouldscan=true; -} - -void AsyncWiFiManager::addParameter(AsyncWiFiManagerParameter *p) { - _params[_paramsCount] = p; - _paramsCount++; - DEBUG_WM("Adding parameter"); - DEBUG_WM(p->getID()); -} - -void AsyncWiFiManager::setupConfigPortal() { - // dnsServer.reset(new DNSServer()); - // server.reset(new ESP8266WebServer(80)); - server->reset(); - - DEBUG_WM(F("")); - _configPortalStart = millis(); - - DEBUG_WM(F("Configuring access point... ")); - DEBUG_WM(_apName); - if (_apPassword != NULL) { - if (strlen(_apPassword) < 8 || strlen(_apPassword) > 63) { - // fail passphrase to short or long! - DEBUG_WM(F("Invalid AccessPoint password. Ignoring")); - _apPassword = NULL; - } - DEBUG_WM(_apPassword); - } - - //optional soft ip config - if (_ap_static_ip) { - DEBUG_WM(F("Custom AP IP/GW/Subnet")); - WiFi.softAPConfig(_ap_static_ip, _ap_static_gw, _ap_static_sn); - } - - if (_apPassword != NULL) { - WiFi.softAP(_apName, _apPassword);//password option - } else { - WiFi.softAP(_apName); - } - - delay(500); // Without delay I've seen the IP address blank - DEBUG_WM(F("AP IP address: ")); - DEBUG_WM(WiFi.softAPIP()); - - /* Setup the DNS server redirecting all the domains to the apIP */ - #ifdef USE_EADNS - dnsServer->setErrorReplyCode(AsyncDNSReplyCode::NoError); - #else - dnsServer->setErrorReplyCode(DNSReplyCode::NoError); - #endif - dnsServer->start(DNS_PORT, "*", WiFi.softAPIP()); - - setInfo(); - - /* Setup web pages: root, wifi config pages, SO captive portal detectors and not found. */ - server->on("/", std::bind(&AsyncWiFiManager::handleRoot, this,std::placeholders::_1)).setFilter(ON_AP_FILTER); - server->on("/wifi", std::bind(&AsyncWiFiManager::handleWifi, this, std::placeholders::_1,true)).setFilter(ON_AP_FILTER); - server->on("/0wifi", std::bind(&AsyncWiFiManager::handleWifi, this,std::placeholders::_1, false)).setFilter(ON_AP_FILTER); - server->on("/wifisave", std::bind(&AsyncWiFiManager::handleWifiSave,this,std::placeholders::_1)).setFilter(ON_AP_FILTER); - server->on("/i", std::bind(&AsyncWiFiManager::handleInfo,this, std::placeholders::_1)).setFilter(ON_AP_FILTER); - server->on("/r", std::bind(&AsyncWiFiManager::handleReset, this,std::placeholders::_1)).setFilter(ON_AP_FILTER); - //server->on("/generate_204", std::bind(&AsyncWiFiManager::handle204, this)); //Android/Chrome OS captive portal check. - server->on("/fwlink", std::bind(&AsyncWiFiManager::handleRoot, this,std::placeholders::_1)).setFilter(ON_AP_FILTER); //Microsoft captive portal. Maybe not needed. Might be handled by notFound handler. - server->onNotFound (std::bind(&AsyncWiFiManager::handleNotFound,this,std::placeholders::_1)); - server->begin(); // Web server start - DEBUG_WM(F("HTTP server started")); - -} - -static const char HEX_CHAR_ARRAY[17] = "0123456789ABCDEF"; -/** -* convert char array (hex values) to readable string by seperator -* buf: buffer to convert -* length: data length -* strSeperator seperator between each hex value -* return: formated value as String -*/ -static String byteToHexString(uint8_t* buf, uint8_t length, String strSeperator="-") { - String dataString = ""; - for (uint8_t i = 0; i < length; i++) { - byte v = buf[i] / 16; - byte w = buf[i] % 16; - if (i>0) { - dataString += strSeperator; - } - dataString += String(HEX_CHAR_ARRAY[v]); - dataString += String(HEX_CHAR_ARRAY[w]); - } - dataString.toUpperCase(); - return dataString; -} // byteToHexString - -#if !defined(ESP8266) -String getESP32ChipID() { - uint64_t chipid; - chipid=ESP.getEfuseMac();//The chip ID is essentially its MAC address(length: 6 bytes). - int chipid_size = 6; - uint8_t chipid_arr[chipid_size]; - for (uint8_t i=0; i < chipid_size; i++) { - chipid_arr[i] = (chipid >> (8 * i)) & 0xff; - } - return byteToHexString(chipid_arr, chipid_size, ""); -} -#endif - -boolean AsyncWiFiManager::autoConnect(unsigned long maxConnectRetries, unsigned long retryDelayMs) { - String ssid = "ESP"; - #if defined(ESP8266) - ssid += String(ESP.getChipId()); - #else - ssid += getESP32ChipID(); - #endif - return autoConnect(ssid.c_str(), NULL); -} - -boolean AsyncWiFiManager::autoConnect(char const *apName, char const *apPassword, unsigned long maxConnectRetries, unsigned long retryDelayMs) { - DEBUG_WM(F("")); - - // read eeprom for ssid and pass - //String ssid = getSSID(); - //String pass = getPassword(); - - // attempt to connect; should it fail, fall back to AP - WiFi.mode(WIFI_STA); - - for(unsigned long tryNumber = 0; tryNumber < maxConnectRetries; tryNumber++) { - DEBUG_WM(F("AutoConnect Try No.:")); - DEBUG_WM(tryNumber); - - if (connectWifi("", "") == WL_CONNECTED) { - DEBUG_WM(F("IP Address:")); - DEBUG_WM(WiFi.localIP()); - //connected - return true; - } - - if(tryNumber + 1 < maxConnectRetries) { - - // we might connect during the delay - unsigned long restDelayMs = retryDelayMs; - while(restDelayMs != 0) { - if(WiFi.status() == WL_CONNECTED) { - DEBUG_WM(F("IP Address (connected during delay):")); - DEBUG_WM(WiFi.localIP()); - return true; - } - unsigned long thisDelay = std::min(restDelayMs, 100ul); - delay(thisDelay); - restDelayMs -= thisDelay; - } - - } - } - - - return startConfigPortal(apName, apPassword); -} - - -String AsyncWiFiManager::networkListAsString() -{ - String pager ; - //display networks in page - for (int i = 0; i < wifiSSIDCount; i++) { - if (wifiSSIDs[i].duplicate == true) continue; // skip dups - int quality = getRSSIasQuality(wifiSSIDs[i].RSSI); - - if (_minimumQuality == -1 || _minimumQuality < quality) { - String item = FPSTR(HTTP_ITEM); - String rssiQ; - rssiQ += quality; - item.replace("{v}", wifiSSIDs[i].SSID); - item.replace("{r}", rssiQ); -#if defined(ESP8266) - if (wifiSSIDs[i].encryptionType != ENC_TYPE_NONE) { -#else - if (wifiSSIDs[i].encryptionType != WIFI_AUTH_OPEN) { -#endif - item.replace("{i}", "l"); - } else { - item.replace("{i}", ""); - } - pager += item; - - } else { - DEBUG_WM(F("Skipping due to quality")); - } - - } - return pager; -} - -String AsyncWiFiManager::scanModal() -{ - shouldscan=true; - scan(); - String pager=networkListAsString(); - return pager; -} - -void AsyncWiFiManager::scan() -{ - if (!shouldscan) return; - DEBUG_WM(F("About to scan()")); - if (wifiSSIDscan) - { - delay(100); - } - - if (wifiSSIDscan) - { - wifi_ssid_count_t n = WiFi.scanNetworks(); - DEBUG_WM(F("Scan done")); - if(n == WIFI_SCAN_FAILED) { - DEBUG_WM(F("scanNetworks returned: WIFI_SCAN_FAILED!")); - } else if(n == WIFI_SCAN_RUNNING) { - DEBUG_WM(F("scanNetworks returned: WIFI_SCAN_RUNNING!")); - } else if(n < 0) { - DEBUG_WM(F("scanNetworks failed with unknown error code!")); - } else if (n == 0) { - DEBUG_WM(F("No networks found")); - // page += F("No networks found. Refresh to scan again."); - } else { - - - if (wifiSSIDscan) - { - /* WE SHOULD MOVE THIS IN PLACE ATOMICALLY */ - if (wifiSSIDs) delete [] wifiSSIDs; - wifiSSIDs = new WiFiResult[n]; - wifiSSIDCount = n; - - if (n>0) - shouldscan=false; - - for (wifi_ssid_count_t i=0;i wifiSSIDs[i].RSSI) { - std::swap(wifiSSIDs[i], wifiSSIDs[j]); - } - } - } - - - // remove duplicates ( must be RSSI sorted ) - if (_removeDuplicateAPs) { - String cssid; - for (int i = 0; i < n; i++) { - if (wifiSSIDs[i].duplicate == true) continue; - cssid = wifiSSIDs[i].SSID; - for (int j = i + 1; j < n; j++) { - if (cssid == wifiSSIDs[j].SSID) { - DEBUG_WM("DUP AP: " +wifiSSIDs[j].SSID); - wifiSSIDs[j].duplicate=true; // set dup aps to NULL - } - } - } - } - - } - } - } -} - - -void AsyncWiFiManager::startConfigPortalModeless(char const *apName, char const *apPassword) { - - _modeless =true; - _apName = apName; - _apPassword = apPassword; - - /* - AJS - do we want this? - - */ - - //setup AP - WiFi.mode(WIFI_AP_STA); - DEBUG_WM("SET AP STA"); - - // try to connect - if (connectWifi("", "") == WL_CONNECTED) { - DEBUG_WM(F("IP Address:")); - DEBUG_WM(WiFi.localIP()); - //connected - // call the callback! - if ( _savecallback != NULL) { - //todo: check if any custom parameters actually exist, and check if they really changed maybe - _savecallback(); - } - } - - - - //notify we entered AP mode - if ( _apcallback != NULL) { - _apcallback(this); - } - - connect = false; - setupConfigPortal(); - scannow= -1 ; - -} - -void AsyncWiFiManager::loop(){ - safeLoop(); - criticalLoop(); -} - -void AsyncWiFiManager::setInfo() { - if (needInfo) { - pager = infoAsString(); - wifiStatus = WiFi.status(); - needInfo = false; - } -} - -/** - * Anything that accesses WiFi, ESP or EEPROM goes here - */ -void AsyncWiFiManager::criticalLoop(){ - if (_modeless) - { - - if ( scannow==-1 || millis() > scannow + 60000) - { - scan(); - scannow= millis() ; - } - if (connect) { - connect = false; - //delay(2000); - DEBUG_WM(F("Connecting to new AP")); - - // using user-provided _ssid, _pass in place of system-stored ssid and pass - if (connectWifi(_ssid, _pass) != WL_CONNECTED) { - DEBUG_WM(F("Failed to connect.")); - } else { - //connected - // alanswx - should we have a config to decide if we should shut down AP? - // WiFi.mode(WIFI_STA); - //notify that configuration has changed and any optional parameters should be saved - if ( _savecallback != NULL) { - //todo: check if any custom parameters actually exist, and check if they really changed maybe - _savecallback(); - } - - return; - } - - if (_shouldBreakAfterConfig) { - //flag set to exit after config after trying to connect - //notify that configuration has changed and any optional parameters should be saved - if ( _savecallback != NULL) { - //todo: check if any custom parameters actually exist, and check if they really changed maybe - _savecallback(); - } - } - } - } -} - -/* - * Anything that doesn't access WiFi, ESP or EEPROM can go here - */ -void AsyncWiFiManager::safeLoop(){ - #ifndef USE_EADNS - dnsServer->processNextRequest(); - #endif -} - -boolean AsyncWiFiManager::startConfigPortal(char const *apName, char const *apPassword) { - //setup AP - WiFi.mode(WIFI_AP_STA); - DEBUG_WM("SET AP STA"); - - _apName = apName; - _apPassword = apPassword; - - //notify we entered AP mode - if ( _apcallback != NULL) { - _apcallback(this); - } - - connect = false; - setupConfigPortal(); - scannow= -1 ; - while (_configPortalTimeout == 0 || millis() < _configPortalStart + _configPortalTimeout) { - //DNS - #ifndef USE_EADNS - dnsServer->processNextRequest(); - #endif - - // - // we should do a scan every so often here and - // try to reconnect to AP while we are at it - // - if ( scannow == -1 || millis() > scannow + 10000) - { - DEBUG_WM(F("About to scan()")); - shouldscan=true; // since we are modal, we can scan every time - #if defined(ESP8266) - // we might still be connecting, so that has to stop for scanning - ETS_UART_INTR_DISABLE (); - wifi_station_disconnect (); - ETS_UART_INTR_ENABLE (); - #else - WiFi.disconnect (false); - #endif - scan(); - if(_tryConnectDuringConfigPortal) WiFi.begin(); // try to reconnect to AP - scannow= millis() ; - } - - // attempts to reconnect were successful - if(WiFi.status() == WL_CONNECTED) { - //connected - WiFi.mode(WIFI_STA); - //notify that configuration has changed and any optional parameters should be saved - if ( _savecallback != NULL) { - //todo: check if any custom parameters actually exist, and check if they really changed maybe - _savecallback(); - } - break; - } - - - if (connect) { - connect = false; - delay(2000); - DEBUG_WM(F("Connecting to new AP")); - - // using user-provided _ssid, _pass in place of system-stored ssid and pass - if (connectWifi(_ssid, _pass) == WL_CONNECTED) { - //connected - WiFi.mode(WIFI_STA); - //notify that configuration has changed and any optional parameters should be saved - if ( _savecallback != NULL) { - //todo: check if any custom parameters actually exist, and check if they really changed maybe - _savecallback(); - } - break; - } else { - DEBUG_WM(F("Failed to connect.")); - } - - if (_shouldBreakAfterConfig) { - //flag set to exit after config after trying to connect - //notify that configuration has changed and any optional parameters should be saved - if ( _savecallback != NULL) { - //todo: check if any custom parameters actually exist, and check if they really changed maybe - _savecallback(); - } - break; - } - } - yield(); - } - - server->reset(); - #ifdef USE_EADNS - *dnsServer=AsyncDNSServer(); - #else - *dnsServer=DNSServer(); - #endif - - return WiFi.status() == WL_CONNECTED; -} - - -int AsyncWiFiManager::connectWifi(String ssid, String pass) { - DEBUG_WM(F("Connecting as wifi client...")); - - // check if we've got static_ip settings, if we do, use those. - if (_sta_static_ip) { - DEBUG_WM(F("Custom STA IP/GW/Subnet/DNS")); - WiFi.config(_sta_static_ip, _sta_static_gw, _sta_static_sn, _sta_static_dns1, _sta_static_dns2); - DEBUG_WM(WiFi.localIP()); - } - //fix for auto connect racing issue - // if (WiFi.status() == WL_CONNECTED) { - // DEBUG_WM("Already connected. Bailing out."); - // return WL_CONNECTED; - // } - //check if we have ssid and pass and force those, if not, try with last saved values - if (ssid != "") { - #if defined(ESP8266) - //trying to fix connection in progress hanging - ETS_UART_INTR_DISABLE(); - wifi_station_disconnect(); - ETS_UART_INTR_ENABLE(); - #else - WiFi.disconnect(false); - #endif - - WiFi.begin(ssid.c_str(), pass.c_str()); - } else { - - if (WiFi.SSID().length() > 0) { - DEBUG_WM("Using last saved values, should be faster"); -#if defined(ESP8266) - //trying to fix connection in progress hanging - ETS_UART_INTR_DISABLE(); - wifi_station_disconnect(); - ETS_UART_INTR_ENABLE(); -#else - WiFi.disconnect(false); -#endif - - WiFi.begin(); - } else { - DEBUG_WM("Try to connect with saved credentials"); - WiFi.begin(); - } - } - - int connRes = waitForConnectResult(); - DEBUG_WM ("Connection result: "); - DEBUG_WM ( connRes ); - //not connected, WPS enabled, no pass - first attempt -#ifdef NO_EXTRA_4K_HEAP - if (_tryWPS && connRes != WL_CONNECTED && pass == "") { - startWPS(); - //should be connected at the end of WPS - connRes = waitForConnectResult(); - } -#endif - needInfo = true; - setInfo(); - return connRes; -} - -uint8_t AsyncWiFiManager::waitForConnectResult() { - if (_connectTimeout == 0) { - return WiFi.waitForConnectResult(); - } else { - DEBUG_WM (F("Waiting for connection result with time out")); - unsigned long start = millis(); - boolean keepConnecting = true; - uint8_t status; - while (keepConnecting) { - status = WiFi.status(); - if (millis() > start + _connectTimeout) { - keepConnecting = false; - DEBUG_WM (F("Connection timed out")); - } - if (status == WL_CONNECTED || status == WL_CONNECT_FAILED) { - keepConnecting = false; - } - delay(100); - } - return status; - } -} -#ifdef NO_EXTRA_4K_HEAP -void AsyncWiFiManager::startWPS() { - DEBUG_WM("START WPS"); -#if defined(ESP8266) - WiFi.beginWPSConfig(); -#else - //esp_wps_config_t config = WPS_CONFIG_INIT_DEFAULT(ESP_WPS_MODE); - esp_wps_config_t config = {}; - config.wps_type = ESP_WPS_MODE; - config.crypto_funcs = &g_wifi_default_wps_crypto_funcs; - strcpy(config.factory_info.manufacturer,"ESPRESSIF"); - strcpy(config.factory_info.model_number, "ESP32"); - strcpy(config.factory_info.model_name, "ESPRESSIF IOT"); - strcpy(config.factory_info.device_name,"ESP STATION"); - - esp_wifi_wps_enable(&config); - esp_wifi_wps_start(0); -#endif - DEBUG_WM("END WPS"); - -} -#endif -/* -String AsyncWiFiManager::getSSID() { -if (_ssid == "") { -DEBUG_WM(F("Reading SSID")); -_ssid = WiFi.SSID(); -DEBUG_WM(F("SSID: ")); -DEBUG_WM(_ssid); -} -return _ssid; -} - -String AsyncWiFiManager::getPassword() { -if (_pass == "") { -DEBUG_WM(F("Reading Password")); -_pass = WiFi.psk(); -DEBUG_WM("Password: " + _pass); -//DEBUG_WM(_pass); -} -return _pass; -} -*/ -String AsyncWiFiManager::getConfigPortalSSID() { - return _apName; -} - -void AsyncWiFiManager::resetSettings() { - DEBUG_WM(F("settings invalidated")); - DEBUG_WM(F("THIS MAY CAUSE AP NOT TO START UP PROPERLY. YOU NEED TO COMMENT IT OUT AFTER ERASING THE DATA.")); - WiFi.disconnect(true); - //delay(200); -} -void AsyncWiFiManager::setTimeout(unsigned long seconds) { - setConfigPortalTimeout(seconds); -} - -void AsyncWiFiManager::setConfigPortalTimeout(unsigned long seconds) { - _configPortalTimeout = seconds * 1000; -} - -void AsyncWiFiManager::setConnectTimeout(unsigned long seconds) { - _connectTimeout = seconds * 1000; -} - -void AsyncWiFiManager::setTryConnectDuringConfigPortal(boolean v) { - _tryConnectDuringConfigPortal = v; -} - -void AsyncWiFiManager::setDebugOutput(boolean debug) { - _debug = debug; -} - -void AsyncWiFiManager::setAPStaticIPConfig(IPAddress ip, IPAddress gw, IPAddress sn) { - _ap_static_ip = ip; - _ap_static_gw = gw; - _ap_static_sn = sn; -} - -void AsyncWiFiManager::setSTAStaticIPConfig(IPAddress ip, IPAddress gw, IPAddress sn, IPAddress dns1, IPAddress dns2) { - _sta_static_ip = ip; - _sta_static_gw = gw; - _sta_static_sn = sn; - _sta_static_dns1 = dns1; - _sta_static_dns2 = dns2; -} - -void AsyncWiFiManager::setMinimumSignalQuality(int quality) { - _minimumQuality = quality; -} - -void AsyncWiFiManager::setBreakAfterConfig(boolean shouldBreak) { - _shouldBreakAfterConfig = shouldBreak; -} - -/** Handle root or redirect to captive portal */ -void AsyncWiFiManager::handleRoot(AsyncWebServerRequest *request) { - // AJS - maybe we should set a scan when we get to the root??? - // and only scan on demand? timer + on demand? plus a link to make it happen? - shouldscan=true; - scannow= -1 ; - DEBUG_WM(F("Handle root")); - if (captivePortal(request)) { // If captive portal redirect instead of displaying the page. - return; - } - - String page = FPSTR(WFM_HTTP_HEAD); - page.replace("{v}", "Options"); - page += FPSTR(HTTP_SCRIPT); - page += FPSTR(HTTP_STYLE); - page += _customHeadElement; - page += FPSTR(HTTP_HEAD_END); - page += "

"; - page += _apName; - page += "

"; - page += F("

AsyncWiFiManager

"); - page += FPSTR(HTTP_PORTAL_OPTIONS); - page += _customOptionsElement; - page += FPSTR(HTTP_END); - - request->send(200, "text/html", page); - -} - -/** Wifi config page handler */ -void AsyncWiFiManager::handleWifi(AsyncWebServerRequest *request,boolean scan) { - shouldscan=true; - scannow= -1 ; - - DEBUG_WM(F("Handle wifi")); - - String page = FPSTR(WFM_HTTP_HEAD); - page.replace("{v}", "Config ESP"); - page += FPSTR(HTTP_SCRIPT); - page += FPSTR(HTTP_STYLE); - page += _customHeadElement; - page += FPSTR(HTTP_HEAD_END); - - if (scan) { - wifiSSIDscan=false; - - - - DEBUG_WM(F("Scan done")); - if (wifiSSIDCount==0) { - DEBUG_WM(F("No networks found")); - page += F("No networks found. Refresh to scan again."); - } else { - - - //display networks in page - String pager = networkListAsString(); - - page += pager; - page += "
"; - } - - } - wifiSSIDscan=true; - - page += FPSTR(HTTP_FORM_START); - char parLength[2]; - // add the extra parameters to the form - for (int i = 0; i < _paramsCount; i++) { - if (_params[i] == NULL) { - break; - } - - String pitem = FPSTR(HTTP_FORM_PARAM); - if (_params[i]->getID() != NULL) { - pitem.replace("{i}", _params[i]->getID()); - pitem.replace("{n}", _params[i]->getID()); - pitem.replace("{p}", _params[i]->getPlaceholder()); - snprintf(parLength, 2, "%d", _params[i]->getValueLength()); - pitem.replace("{l}", parLength); - pitem.replace("{v}", _params[i]->getValue()); - pitem.replace("{c}", _params[i]->getCustomHTML()); - } else { - pitem = _params[i]->getCustomHTML(); - } - - page += pitem; - } - if (_params[0] != NULL) { - page += "
"; - } - - if (_sta_static_ip) { - - String item = FPSTR(HTTP_FORM_PARAM); - item.replace("{i}", "ip"); - item.replace("{n}", "ip"); - item.replace("{p}", "Static IP"); - item.replace("{l}", "15"); - item.replace("{v}", _sta_static_ip.toString()); - - page += item; - - item = FPSTR(HTTP_FORM_PARAM); - item.replace("{i}", "gw"); - item.replace("{n}", "gw"); - item.replace("{p}", "Static Gateway"); - item.replace("{l}", "15"); - item.replace("{v}", _sta_static_gw.toString()); - - page += item; - - item = FPSTR(HTTP_FORM_PARAM); - item.replace("{i}", "sn"); - item.replace("{n}", "sn"); - item.replace("{p}", "Subnet"); - item.replace("{l}", "15"); - item.replace("{v}", _sta_static_sn.toString()); - - page += item; - - item = FPSTR(HTTP_FORM_PARAM); - item.replace("{i}", "dns1"); - item.replace("{n}", "dns1"); - item.replace("{p}", "DNS1"); - item.replace("{l}", "15"); - item.replace("{v}", _sta_static_dns1.toString()); - - page += item; - - item = FPSTR(HTTP_FORM_PARAM); - item.replace("{i}", "dns2"); - item.replace("{n}", "dns2"); - item.replace("{p}", "DNS2"); - item.replace("{l}", "15"); - item.replace("{v}", _sta_static_dns2.toString()); - - page += item; - - page += "
"; - } - - page += FPSTR(HTTP_FORM_END); - page += FPSTR(HTTP_SCAN_LINK); - - page += FPSTR(HTTP_END); - - request->send(200, "text/html", page); - - - DEBUG_WM(F("Sent config page")); -} - -/** Handle the WLAN save form and redirect to WLAN config page again */ -void AsyncWiFiManager::handleWifiSave(AsyncWebServerRequest *request) { - DEBUG_WM(F("WiFi save")); - - //SAVE/connect here - needInfo = true; - _ssid = request->arg("s").c_str(); - _pass = request->arg("p").c_str(); - - //parameters - for (int i = 0; i < _paramsCount; i++) { - if (_params[i] == NULL) { - break; - } - //read parameter - String value = request->arg(_params[i]->getID()).c_str(); - //store it in array - value.toCharArray(_params[i]->_value, _params[i]->_length); - DEBUG_WM(F("Parameter")); - DEBUG_WM(_params[i]->getID()); - DEBUG_WM(value); - } - - if (request->hasArg("ip")) { - DEBUG_WM(F("static ip")); - DEBUG_WM(request->arg("ip")); - //_sta_static_ip.fromString(request->arg("ip")); - String ip = request->arg("ip"); - optionalIPFromString(&_sta_static_ip, ip.c_str()); - } - if (request->hasArg("gw")) { - DEBUG_WM(F("static gateway")); - DEBUG_WM(request->arg("gw")); - String gw = request->arg("gw"); - optionalIPFromString(&_sta_static_gw, gw.c_str()); - } - if (request->hasArg("sn")) { - DEBUG_WM(F("static netmask")); - DEBUG_WM(request->arg("sn")); - String sn = request->arg("sn"); - optionalIPFromString(&_sta_static_sn, sn.c_str()); - } - if (request->hasArg("dns1")) { - DEBUG_WM(F("static DNS 1")); - DEBUG_WM(request->arg("dns1")); - String dns1 = request->arg("dns1"); - optionalIPFromString(&_sta_static_dns1, dns1.c_str()); - } - if (request->hasArg("dns2")) { - DEBUG_WM(F("static DNS 2")); - DEBUG_WM(request->arg("dns2")); - String dns2 = request->arg("dns2"); - optionalIPFromString(&_sta_static_dns2, dns2.c_str()); - } - - String page = FPSTR(WFM_HTTP_HEAD); - page.replace("{v}", "Credentials Saved"); - page += FPSTR(HTTP_SCRIPT); - page += FPSTR(HTTP_STYLE); - page += _customHeadElement; - page += F(""); - page += FPSTR(HTTP_HEAD_END); - page += FPSTR(HTTP_SAVED); - page += FPSTR(HTTP_END); - - request->send(200, "text/html", page); - - DEBUG_WM(F("Sent wifi save page")); - - connect = true; //signal ready to connect/reset -} - -/** Handle the info page */ -String AsyncWiFiManager::infoAsString() -{ - String page; - page += F("
Chip ID
"); -#if defined(ESP8266) - page += ESP.getChipId(); -#else - page += getESP32ChipID(); -#endif - page += F("
"); - page += F("
Flash Chip ID
"); -#if defined(ESP8266) - page += ESP.getFlashChipId(); -#else - page += F("N/A for ESP32"); -#endif - page += F("
"); - page += F("
IDE Flash Size
"); - page += ESP.getFlashChipSize(); - page += F(" bytes
"); - page += F("
Real Flash Size
"); -#if defined(ESP8266) - page += ESP.getFlashChipRealSize(); -#else - page += F("N/A for ESP32"); -#endif - page += F(" bytes
"); - page += F("
Soft AP IP
"); - page += WiFi.softAPIP().toString(); - page += F("
"); - page += F("
Soft AP MAC
"); - page += WiFi.softAPmacAddress(); - page += F("
"); - page += F("
Station SSID
"); - page += WiFi.SSID(); - page += F("
"); - page += F("
Station IP
"); - page += WiFi.localIP().toString(); - page += F("
"); - page += F("
Station MAC
"); - page += WiFi.macAddress(); - page += F("
"); - page += F("

Try opening this link instead

H!I$bwY@yMu}H2v>*!Ap3B`Gs)@5OWTL> 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 z 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 acefull.js +"C:\Program Files\7-Zip\7z.exe" a -tgzip -mx9 acefull.js.gz acefull.js +REM update: +copy acefull.js.gz ..\..\examples\SmartSwitch\data\acefull.js.gz +pause diff --git a/src/edit.htm.gz.h b/src/edit.htm.gz.h index f482f1e82..21057eefb 100644 --- a/src/edit.htm.gz.h +++ b/src/edit.htm.gz.h @@ -1,219 +1,219 @@ -#define edit_htm_gz_len 4314 +#define edit_htm_gz_len 4316 const uint8_t edit_htm_gz[] PROGMEM = { -0x1F,0x8B,0x08,0x08,0x30,0xC1,0x84,0x5E,0x02,0x00,0x65,0x64,0x69,0x74,0x2E,0x68,0x74,0x6D,0x00,0xB5, +0x1F,0x8B,0x08,0x08,0x33,0x95,0x87,0x5E,0x02,0x00,0x65,0x64,0x69,0x74,0x2E,0x68,0x74,0x6D,0x00,0xB5, 0x1A,0x0B,0x5B,0xDB,0x36,0xF0,0xAF,0x18,0x6F,0x63,0xF6,0xE2,0x38,0x0E,0x50,0xD6,0x39,0x18,0x16,0x1E, 0x2B,0x7D,0x01,0x25,0x49,0x3B,0xCA,0xD8,0x3E,0xC5,0x56,0x12,0x15,0x5B,0xF6,0x2C,0x99,0x40,0xB3,0xFC, 0xF7,0x9D,0x24,0x3F,0x43,0xE8,0x1E,0xDF,0xD6,0x07,0x91,0x74,0xBA,0xD3,0xDD,0xE9,0x9E,0x0A,0x7B,0x1B, 0xC7,0xE7,0x47,0xC3,0xAB,0x8B,0x13,0x6D,0xC6,0xA3,0x70,0x7F,0x4F,0xFC,0xD4,0x42,0x44,0xA7,0x9E,0x8E, 0xA9,0xBE,0xBF,0x17,0x61,0x8E,0x00,0xC4,0x93,0x36,0xFE,0x3D,0x23,0x77,0x9E,0x7E,0x14,0x53,0x8E,0x29, -0x6F,0xF3,0x87,0x04,0xEB,0xBE,0x9A,0x78,0x3A,0xC7,0xF7,0xBC,0x23,0x70,0x7B,0x9A,0x3F,0x43,0x29,0xC3, -0xDC,0xCB,0xF8,0xA4,0xFD,0x1C,0x28,0x70,0xC2,0x43,0xBC,0x7F,0x32,0xB8,0xD0,0x4E,0x02,0xC2,0xE3,0x74, -0xAF,0xA3,0x56,0xF6,0x18,0x7F,0x08,0xB1,0x26,0xE8,0xE4,0xF8,0x3E,0x63,0x7A,0x84,0x03,0x82,0x3C,0x9D, -0xF9,0x29,0x16,0xE7,0x87,0x68,0x8C,0xC3,0xC5,0x24,0x86,0x03,0x19,0xF9,0x8C,0xDD,0xEE,0x56,0x72,0xDF, -0x93,0xD3,0x09,0x8A,0x48,0xF8,0xE0,0x32,0x44,0x59,0x9B,0xE1,0x94,0x4C,0x96,0xB6,0x1F,0x2D,0x3E,0xB7, -0x09,0x0D,0xF0,0xBD,0xBB,0xED,0x38,0xBD,0x24,0x66,0x84,0x93,0x98,0xBA,0x68,0xCC,0xE2,0x30,0xE3,0xB8, -0x17,0xE2,0x09,0x77,0x9F,0x01,0x85,0x71,0x9C,0x06,0x38,0x75,0xBB,0xC9,0xBD,0x06,0x20,0x12,0x68,0x5F, -0xED,0xEC,0xEC,0xF4,0xC6,0xC8,0xBF,0x9D,0xA6,0x71,0x46,0x83,0xB6,0x1F,0x87,0x71,0xEA,0x7E,0x35,0x79, -0x26,0xFE,0xF6,0x02,0xC2,0x92,0x10,0x3D,0xB8,0x34,0xA6,0x18,0x70,0xEF,0xDB,0x6C,0x86,0x82,0x78,0xEE, -0x3A,0x9A,0xA3,0x75,0x1D,0x20,0x92,0x4E,0xC7,0xC8,0x70,0x2C,0xF1,0xD7,0xDE,0x31,0x7B,0x7F,0x8B,0x5F, -0xB5,0x3C,0xC7,0x64,0x3A,0xE3,0xEE,0xF7,0x8E,0x23,0xF8,0xD7,0xB2,0x70,0x11,0x12,0xC6,0xDB,0x52,0x37, -0xEA,0x3C,0x1E,0x27,0xAE,0x23,0x59,0x87,0x8F,0x08,0xA5,0x53,0x42,0x61,0x90,0xA0,0x20,0x20,0x74,0xEA, -0x2A,0xB4,0x90,0x2C,0x4A,0x69,0x53,0x1C,0x22,0x4E,0xEE,0x70,0x2F,0x22,0xB4,0x3D,0x27,0x01,0x9F,0xB9, -0xBB,0x0E,0x70,0xE1,0x67,0x29,0x03,0x99,0x92,0x98,0x50,0x8E,0x53,0x89,0xC6,0x12,0x44,0x17,0x4A,0x54, -0xA1,0x80,0x52,0x4E,0x42,0x43,0x42,0x71,0x7B,0x1C,0xC6,0xFE,0x6D,0x79,0xD2,0x6E,0x72,0x9F,0x9F,0xE5, -0xCE,0xE2,0x3B,0x9C,0x2E,0x2A,0x75,0x49,0xEC,0x06,0xB0,0x41,0x1A,0x63,0xBC,0xB4,0xF9,0x5D,0x06,0x50, -0x4B,0x7E,0x82,0x94,0x39,0xD5,0xBA,0x48,0x4D,0xC1,0x73,0x14,0x42,0x93,0x8C,0x2F,0x1E,0x5F,0x65,0x9C, -0x20,0x9F,0xF0,0x07,0xD7,0x91,0xDB,0xA4,0x85,0xB8,0x3B,0x8E,0xA3,0x09,0x85,0x6B,0xEF,0x71,0x1A,0x20, -0x8A,0xAC,0x7E,0x4A,0x50,0x68,0x0D,0x2A,0x95,0xB7,0xA3,0xF8,0x73,0x3B,0x83,0x31,0xCC,0x43,0xEC,0x73, -0xA5,0x61,0xB8,0x84,0xF1,0x2D,0xE1,0x8F,0x01,0x8F,0x16,0x6A,0xBA,0x92,0x1A,0x9A,0xA9,0xDB,0xEB,0x82, -0x6E,0x24,0x1F,0x4A,0x6C,0x25,0x51,0x7B,0x1C,0x73,0x1E,0x47,0xD2,0xDE,0x4A,0x69,0x35,0x69,0x32,0xCF, -0x1F,0x5D,0xC7,0x7A,0xD5,0xD7,0xC8,0xF7,0x40,0xA9,0x9C,0xF8,0x28,0x6C,0xA3,0x90,0x4C,0xA9,0x1B,0x91, -0x20,0x08,0x71,0xCD,0x64,0xDD,0x2C,0x0D,0x8D,0x00,0x71,0xE4,0x92,0x08,0x4D,0x71,0x27,0xA1,0x53,0x80, -0x32,0xBC,0xBB,0x63,0x91,0xF7,0x87,0xE7,0x97,0x73,0xE7,0xF5,0x8B,0x69,0xDC,0x87,0x3F,0x67,0x83,0xD1, -0xEC,0x64,0x34,0x85,0xD1,0xA1,0x98,0xF6,0xDF,0x1D,0xF5,0xDF,0xC1,0xC7,0x51,0xB7,0xF5,0x69,0xF2,0x7B, -0x5F,0x2C,0xBF,0x08,0x0E,0x87,0xA3,0x93,0x7E,0xFF,0x75,0xE7,0xE5,0xD9,0xFC,0xC3,0xEB,0x5D,0x01,0x3E, -0x0C,0x9D,0xCB,0xF7,0x33,0x67,0xB4,0xF5,0x43,0x14,0x9C,0x06,0x33,0x3F,0x1A,0xF5,0xDF,0x7D,0xB8,0xBC, -0xBB,0x8A,0x46,0xD3,0xC1,0x87,0xEE,0xEC,0xE3,0xD6,0xFB,0xC1,0xC7,0x0F,0x3F,0xDD,0xE2,0x9F,0x4F,0x5F, -0x7D,0x1C,0xCE,0x01,0xE1,0x38,0x1E,0x8C,0x2E,0x0F,0xDF,0x1F,0x4E,0x3F,0x1E,0xFA,0x27,0xF7,0xE3,0xF0, -0xEC,0xF0,0x45,0x7F,0xDC,0xDF,0xF2,0x31,0x9E,0x0E,0x2F,0x0F,0xB3,0x97,0xAF,0xCF,0xA7,0x84,0xCC,0x06, -0x1F,0xCF,0x86,0xFE,0xD1,0xB3,0x37,0xA3,0xD3,0x3E,0x99,0x9D,0xBD,0xBA,0x74,0x6E,0x5F,0xBC,0x3E,0x3A, -0xF6,0xAF,0x5E,0x5D,0xED,0x1E,0x6F,0x77,0xBE,0xFF,0xFE,0x6D,0x70,0x4E,0xE8,0xF0,0xEE,0x73,0x7F,0x7A, -0x34,0x7F,0xFE,0xC0,0x86,0xB3,0x97,0x77,0xB4,0xF3,0x3E,0xFE,0xF4,0xF2,0xE1,0x2D,0xFC,0xBF,0xB8,0x68, -0x8D,0x07,0x5D,0x36,0x7A,0xF7,0xF2,0xFD,0x16,0xFB,0xE1,0x59,0x72,0x78,0x7C,0x7C,0x17,0x8D,0x2F,0x3A, -0x51,0x70,0x3B,0xE1,0xCF,0xB7,0x79,0x72,0x35,0xCD,0x3E,0xFE,0xFE,0xEC,0xD5,0xAC,0x73,0x8E,0xD1,0xD5, -0xAC,0xF5,0xF0,0xF9,0xE1,0xF9,0x6C,0x78,0x7A,0x77,0x16,0xA2,0xFB,0xB3,0x33,0xFF,0x73,0xD4,0x0A,0xD1, -0x0F,0xE7,0xC3,0x10,0xA5,0xDD,0x51,0xD0,0xEF,0xB4,0x8E,0xB6,0xFA,0x3B,0x3C,0xBD,0x3C,0xA2,0xC7,0xDB, -0x9F,0x06,0xCF,0x0F,0x0F,0xBB,0xF1,0xF8,0xF7,0xAD,0x17,0xB7,0xBB,0x2F,0x46,0xBB,0xEF,0xC6,0xEF,0xFA, -0x83,0x9D,0xC3,0x11,0xBA,0x1A,0xBC,0xEB,0x4F,0x76,0xC6,0xB3,0xD9,0xEB,0xD7,0xC3,0x9F,0x82,0xFE,0xE7, -0xB4,0x7F,0x3E,0xEF,0xDF,0x9F,0x8C,0xFA,0xA7,0xAD,0xD7,0x27,0x6F,0x9D,0xEE,0xE0,0x6A,0x7B,0xFA,0x76, -0x77,0x7E,0xC8,0x4E,0xFA,0xEF,0x0E,0x9D,0xE9,0xAB,0x56,0x84,0x3E,0xC6,0x47,0xDB,0xD3,0x97,0xBB,0xE4, -0xE2,0x0A,0xF5,0x5F,0x1E,0xBE,0x62,0xE4,0x32,0x3A,0x1D,0x39,0xFD,0xFE,0x9B,0x73,0xFC,0xD3,0xD1,0x36, -0x7A,0xBD,0xE5,0x7F,0x00,0xFD,0x8F,0x7E,0xC6,0xDF,0xB7,0xFA,0xF3,0x73,0x27,0xF4,0x7F,0xC0,0xC3,0xD3, -0xAB,0xA1,0xBC,0x9D,0x93,0xF0,0xA7,0xE1,0xED,0x20,0x7B,0x17,0x1D,0x1D,0x99,0x1A,0x8D,0xDB,0x29,0x4E, -0x30,0xE2,0xF5,0x58,0x55,0x3A,0x07,0xD8,0x56,0x65,0x85,0xB9,0x93,0x8A,0xC0,0xDA,0x0E,0xB0,0x1F,0xA7, -0x48,0xEE,0x01,0x04,0x9C,0x0A,0x13,0x5B,0xFE,0x28,0x43,0xAD,0xA6,0x22,0xAD,0x86,0x68,0xA0,0x19,0x85, -0x23,0x44,0x84,0x02,0xCE,0x1D,0xF1,0x71,0x3B,0x21,0xF7,0x38,0x6C,0x4B,0x64,0xD7,0x31,0x17,0xD2,0xD9, -0x8A,0x6D,0x88,0x92,0x48,0x51,0x2D,0x16,0x82,0x4F,0xC8,0x17,0xC9,0x01,0x5C,0x26,0x82,0xCF,0xDC,0x77, -0xE2,0xB4,0x3D,0xCE,0xA6,0x13,0x72,0x0F,0xDE,0x3C,0x21,0x94,0x70,0xAC,0x75,0xD9,0xF2,0xC7,0x82,0xCC, -0x2D,0x7E,0x98,0xA4,0x28,0xC2,0x4C,0xFB,0x9B,0x64,0x16,0x93,0x34,0x8E,0x16,0x55,0x04,0xE4,0x71,0x6D, -0xB2,0x5C,0x7E,0x95,0x25,0x61,0x8C,0x40,0xCC,0x35,0x61,0x43,0x05,0xD3,0x54,0xB8,0x55,0x19,0x54,0x0B, -0x37,0xDB,0x02,0xB7,0x6C,0xB8,0xF5,0xD6,0x4E,0xE5,0xBA,0x6D,0xB9,0x57,0x04,0xFB,0xBA,0xEA,0x6B,0xF1, -0xA0,0x16,0xEB,0xBE,0xE2,0xA0,0xD2,0xF5,0x87,0xAB,0x43,0x54,0x64,0xA8,0x18,0x50,0x51,0xBA,0xBB,0xEB, -0xD4,0x42,0x05,0xEC,0x5B,0x7E,0x85,0x65,0xC6,0xB4,0xBE,0x4A,0x52,0xB8,0x0D,0x3C,0xFF,0x02,0xCD,0x52, -0xA6,0x26,0x6D,0xA0,0x59,0xA6,0x3B,0x25,0x42,0x95,0xF3,0x24,0xAF,0x25,0xE9,0xC7,0x52,0x01,0xB8,0xE4, -0xE6,0x99,0xE0,0xE6,0x8B,0x5A,0xDD,0xDE,0xFD,0x26,0xE7,0x61,0xC7,0xF9,0x66,0x69,0xAB,0xBD,0x65,0x3E, -0xEE,0x3A,0xF0,0xA7,0x48,0xBB,0xCF,0x2B,0x16,0xC6,0xCF,0xC4,0xDF,0x82,0x41,0xA0,0x53,0x07,0x6E,0xEF, -0xFC,0xF0,0x3C,0x18,0x17,0x40,0x25,0xD8,0xD3,0xF0,0x14,0x05,0x24,0x63,0xEE,0x33,0xE7,0x1B,0xA5,0x4F, -0xB8,0x3E,0x90,0xBD,0xB8,0x5C,0x35,0xA9,0x2C,0x96,0x25,0x84,0x6A,0x5B,0x4C,0x13,0xF7,0x8D,0xD2,0xD2, -0x30,0xEB,0xA9,0x1E,0x5C,0xA4,0x32,0x4D,0xB1,0x7F,0xE1,0x7C,0xB3,0xE0,0x29,0xA2,0x6C,0x12,0xA7,0x91, -0x9B,0xC6,0x1C,0x71,0x6C,0x38,0xE6,0xB2,0xEB,0xAC,0x03,0x6C,0xEF,0x3A,0x01,0x9E,0x9A,0xCB,0xE5,0x5E, -0x07,0x92,0x9A,0x2C,0x78,0xFC,0x94,0x24,0x7C,0x7F,0x92,0x51,0x5F,0xF0,0xA0,0x4D,0xB1,0x81,0xCD,0x45, -0x8A,0x79,0x96,0x52,0x2D,0x88,0xFD,0x4C,0x18,0xBB,0x3D,0xC5,0xFC,0x44,0xD9,0xFD,0xE1,0xC3,0xCB,0x00, -0x76,0x2C,0x4B,0x04,0x7F,0x2D,0x02,0x38,0x30,0x9C,0x97,0xE3,0x34,0xF6,0x43,0x82,0x01,0x22,0xAF,0xF1, -0x83,0x81,0x2D,0x5E,0x22,0x62,0x5B,0xAC,0x1B,0x46,0xB1,0x0D,0x80,0xD4,0x5C,0xDC,0x81,0x16,0x90,0x87, -0xAF,0xF9,0x8D,0x45,0x3C,0x0A,0x1F,0xBD,0x7C,0x3B,0xD9,0x47,0x07,0xED,0xAE,0x8B,0xF6,0xC9,0x41,0x17, -0xFC,0xCB,0xAC,0xD1,0x57,0x27,0xFF,0x44,0x42,0x3C,0xCA,0x5D,0x4E,0x1C,0x54,0x51,0xEB,0x18,0xE4,0x62, -0x06,0x8A,0x34,0xBF,0x33,0xCE,0x07,0x9A,0x71,0xFD,0x7D,0xFB,0x87,0x9B,0x3F,0xBA,0xD7,0x4E,0xBB,0x7B, -0x63,0xFE,0x66,0x76,0x88,0xCD,0x31,0xE3,0x06,0x45,0x77,0x64,0x8A,0xC0,0xCE,0x6D,0x91,0x6F,0xFB,0x53, -0x90,0xC2,0xEC,0x95,0x67,0x10,0xC5,0xDE,0x96,0xE3,0x6C,0x78,0xF8,0x00,0x85,0x18,0x58,0xD7,0x4F,0x2E, -0x2F,0xCF,0x2F,0xAF,0xF5,0x16,0x6E,0xE9,0x37,0xAE,0xA6,0xB7,0xA8,0xE9,0x72,0x3B,0xC5,0x93,0x14,0xB3, -0xD9,0x05,0xE2,0x33,0x23,0xB0,0xEF,0x50,0x98,0x81,0x2E,0x04,0x23,0xB1,0x07,0x8A,0xD3,0xC7,0x19,0xD8, -0x0F,0xD5,0xCD,0x5E,0x6C,0x13,0x4A,0x71,0x7A,0x3A,0x7C,0xFB,0xC6,0xD3,0x2F,0x15,0x92,0xF6,0x86,0x30, -0xAE,0x5B,0xF2,0x46,0x6C,0x94,0x24,0x98,0x06,0x47,0x33,0x12,0x06,0x46,0x6C,0xF6,0x04,0x09,0x5F,0x92, -0x90,0xC5,0x08,0x50,0xF0,0x6D,0x55,0xB5,0x4E,0x40,0x72,0xDD,0xF2,0xED,0x28,0x0B,0x39,0x49,0x42,0xEC, -0x6D,0x74,0x61,0x46,0x51,0x04,0x30,0x91,0x8A,0x05,0x8C,0x04,0x9E,0xAE,0x02,0x92,0x0A,0x63,0x6B,0x4F, -0xF1,0xD5,0x29,0x41,0xE3,0x94,0xA0,0x8E,0x9B,0x80,0x54,0xBA,0x15,0xD8,0x55,0xB9,0x0C,0xB3,0xFC,0xA8, -0x02,0x16,0xE0,0x09,0x02,0x4E,0xDE,0x83,0xE4,0xB0,0xDA,0x59,0x77,0x50,0xA0,0x0E,0x62,0x4D,0x8D,0xB0, -0xBA,0x46,0xD4,0x55,0xAE,0x43,0x66,0x0A,0x39,0x6D,0x22,0xA7,0x75,0xE4,0x23,0x69,0x11,0xEB,0x90,0x53, -0x85,0x1C,0x36,0x44,0x0C,0xA5,0x88,0x2A,0xCA,0xB5,0x85,0x36,0x41,0x20,0xC0,0x0E,0xEB,0x62,0xC2,0x0C, -0x9C,0x12,0x8D,0x43,0x1C,0x78,0x1B,0x0E,0xCC,0x44,0x61,0xED,0x6D,0x39,0x6B,0xCE,0x08,0xD5,0x19,0x59, -0xE3,0x8C,0x4C,0x9E,0x41,0x12,0x50,0x22,0xE4,0x0E,0xDD,0xCA,0xA4,0xD6,0x9A,0x2B,0xEA,0x38,0x7F,0x86, -0xFD,0x5B,0x28,0xEF,0xD7,0xB1,0x9F,0x99,0xB0,0x4D,0x6E,0x10,0x6C,0x6C,0x20,0x79,0x50,0x22,0x0F,0x92, -0x3D,0x0A,0x1C,0x94,0xD8,0xE0,0xFE,0x9E,0x38,0xCE,0x4A,0xEA,0x3A,0x39,0x0F,0x03,0x8D,0x80,0xFD,0xAF, -0x23,0x9B,0x28,0x8E,0xA3,0xA6,0x4A,0xA3,0x3A,0xBA,0x36,0x40,0x77,0x78,0x2D,0x72,0x64,0x5A,0xA9,0x1D, -0x53,0x3F,0x24,0xFE,0xAD,0x57,0x79,0xB3,0xB9,0x30,0xEA,0x13,0x41,0x9F,0x7B,0x14,0xCF,0xB5,0x9F,0x20, -0x3A,0x1D,0x23,0x8E,0x7A,0x3C,0x27,0x63,0xE4,0xA6,0x83,0x81,0x10,0xB4,0x77,0x98,0x71,0x66,0xA3,0x00, -0x96,0x2F,0x46,0x43,0xDD,0xD2,0x3B,0xE2,0x62,0x74,0x70,0x68,0x62,0x2E,0xCD,0xD2,0xA5,0x2C,0x2A,0x83, -0xFB,0x28,0x0D,0xAB,0x25,0x18,0x14,0x46,0xB7,0xB4,0xA2,0xB5,0x3C,0x91,0x89,0x51,0x2A,0xB0,0x60,0x0A, -0xF9,0xD8,0x16,0x67,0x18,0xB9,0x09,0xE8,0x26,0x44,0x3F,0x65,0xBF,0x86,0x69,0xA1,0x26,0xD3,0xA8,0x64, -0x3A,0x45,0xF3,0xC2,0x4E,0xD4,0xF9,0x3D,0xE5,0xE5,0x0E,0x24,0x61,0xCA,0xB8,0x86,0xBD,0x1D,0xE7,0x87, -0xDD,0x1E,0xDC,0x86,0xA1,0x7C,0x17,0x00,0x7B,0xDC,0x06,0xEB,0x9A,0xF2,0x59,0xCF,0x6F,0x79,0xB9,0x56, -0x02,0x8F,0xDB,0x2C,0x1B,0x33,0x9E,0x42,0x8A,0x33,0x7C,0xCB,0x6F,0x61,0xB3,0x79,0x8C,0xDE,0x8A,0xAD, -0xC0,0xB4,0xE2,0x56,0x6B,0xB9,0xA2,0xA0,0xF3,0x41,0x4D,0x43,0x48,0x68,0x08,0x87,0x0C,0x6B,0xD4,0xC6, -0xF7,0xD8,0x3F,0x8A,0xA3,0x08,0x09,0x12,0x0C,0xAE,0x2E,0x9F,0xE8,0xE6,0xD2,0x8A,0xD7,0x6A,0xE6,0x89, -0xC8,0x65,0xB1,0xA7,0xF4,0x08,0x91,0xD0,0xF3,0x6D,0xE1,0x2E,0x2C,0x17,0xEA,0xCB,0xB7,0x5C,0xC4,0x22, -0x85,0x72,0xED,0xDC,0x58,0xE5,0xC5,0xAD,0x97,0xAA,0xBA,0x77,0x61,0x75,0x8D,0x10,0x64,0x56,0x37,0x2D, -0x60,0xCD,0xD0,0x56,0x41,0xF5,0xE5,0xD2,0xF2,0x05,0xFF,0x33,0x44,0xA7,0xF8,0xEF,0x0B,0x50,0xF1,0x28, -0xBD,0xD4,0xA2,0x90,0x43,0x0E,0xDC,0x5F,0x6C,0xE3,0xFA,0x57,0xFB,0xA6,0x65,0x9A,0x07,0x5F,0x77,0xA4, -0x86,0x0D,0x6E,0x5E,0x77,0x6F,0x2C,0x04,0x60,0xFB,0x3B,0xF3,0x17,0x5B,0x82,0x1B,0xB0,0xDE,0x5D,0x4C, -0x02,0x4D,0x9C,0x24,0x9C,0x3B,0x9E,0x68,0x68,0x73,0xD3,0x00,0x93,0x6B,0x18,0x6B,0x8B,0xB7,0x74,0x1B, -0xD2,0xC7,0x72,0xB9,0x9A,0xD4,0x86,0x29,0xC6,0x2A,0x6B,0x96,0x00,0xC9,0x3D,0xC8,0xBC,0x1A,0xAF,0x4A, -0xA9,0xB1,0x55,0x41,0x61,0x51,0x66,0x7D,0x3B,0x2F,0x28,0x3C,0x5D,0x54,0x14,0x10,0x6B,0x56,0x97,0x65, -0xA7,0x07,0xEB,0x35,0x97,0xFF,0x76,0x8F,0x44,0x53,0x8D,0xA5,0xBE,0xA7,0xAE,0xE2,0x40,0xFC,0xF0,0xBE, -0x15,0xD9,0x6E,0xF3,0x37,0x7F,0xEC,0xE9,0x2D,0xB8,0x5F,0x6C,0xD3,0x78,0x6E,0x98,0xAD,0x6F,0x75,0x4D, -0x52,0xF4,0xF4,0x08,0xDD,0xE7,0xFD,0xBE,0x28,0x48,0x7A,0x1A,0xCC,0xCB,0x06,0x55,0x2D,0xA8,0x4E,0x1B, -0x65,0x3C,0xEE,0x69,0x45,0xA1,0xA3,0x3A,0x4D,0x5D,0xEB,0xEC,0x7F,0x5B,0xE9,0x00,0x81,0xE8,0x48,0xDD, -0x09,0x91,0xA1,0x29,0x13,0x01,0x0E,0x37,0xA2,0x0F,0xC9,0xDD,0x4E,0xC5,0x40,0x02,0x70,0xB2,0x92,0x39, -0xAD,0xC0,0x40,0xE6,0x81,0xD1,0xC8,0xB7,0x7B,0xA2,0x37,0xD9,0xBF,0x50,0x45,0xE7,0x5E,0x47,0xCE,0xF4, -0x75,0x8E,0x01,0x9A,0xA7,0x80,0x6E,0x95,0x65,0xCE,0x38,0x0E,0x1E,0x6A,0xC5,0x11,0x3B,0x7C,0x38,0x0A, -0x11,0x63,0x67,0x28,0x82,0xF3,0xFD,0x48,0x37,0x73,0x53,0xDA,0x77,0x36,0x37,0x9B,0x48,0x29,0x8E,0xA0, -0x17,0x52,0x5C,0x61,0x08,0x65,0xAE,0x0F,0x84,0x37,0x37,0xD7,0x31,0x26,0x9E,0xA8,0xBE,0xC4,0x15,0x05, -0x77,0x2D,0xC2,0xDF,0xFF,0xC4,0x9D,0xCA,0xB1,0x4F,0x69,0x35,0x05,0x9F,0x7D,0xCC,0xF6,0x71,0x3C,0xA7, -0x82,0xAB,0x92,0xF5,0x74,0x8D,0x42,0xAB,0xBC,0x50,0x5A,0x72,0x90,0xE3,0xB5,0x27,0xA9,0x32,0xE4,0x9A, -0xD1,0x15,0x30,0x30,0x37,0xBC,0x34,0xFF,0x1F,0x61,0x55,0x49,0xF0,0x94,0xAC,0xA1,0x69,0x85,0x6B,0x64, -0xC5,0x21,0xE6,0xB8,0x94,0x34,0x5C,0x2B,0x29,0xFB,0x7F,0xF8,0xAD,0x3C,0x84,0xA8,0x4A,0xB7,0xEE,0x23, -0x01,0xB9,0xD3,0x21,0x57,0x78,0x4D,0x0A,0xCC,0x4F,0xE3,0x30,0x1C,0xC6,0xC9,0xC1,0x13,0xEB,0x6E,0xB9, -0x9E,0x0F,0x0A,0x36,0xAB,0x2D,0x96,0xBF,0x96,0xE8,0x1B,0x3C,0xE1,0x07,0x4F,0x01,0x9E,0x26,0x5B,0xED, -0xB1,0x02,0x0F,0xDB,0xA0,0x3C,0x58,0xFD,0xB9,0xE5,0x5B,0xAC,0x9C,0x5D,0xB5,0x62,0xB8,0x0B,0xBF,0x50, -0x92,0x27,0x94,0x64,0x91,0xB5,0xA1,0xAB,0x5A,0x17,0xED,0xA5,0x17,0xB4,0xF4,0xE4,0xBE,0x5A,0xE3,0x71, -0xE2,0x31,0xB5,0x84,0x0C,0x62,0xF1,0x95,0x4B,0x59,0x17,0x50,0x52,0x8F,0xD8,0xF1,0x64,0xC2,0x30,0xFF, -0x20,0x82,0x99,0x15,0x96,0xF3,0x53,0x19,0xCC,0x7A,0x30,0xA5,0x51,0x9C,0x31,0x1C,0x67,0xBC,0x59,0xF6, -0x94,0xC2,0xEC,0x05,0x7F,0xFC,0x51,0x4E,0xF6,0x83,0x56,0x5A,0x4D,0xAF,0xF6,0x58,0x6D,0xB2,0xCF,0x5A, -0x21,0x84,0x82,0xFF,0xD8,0x52,0x48,0xDD,0x52,0x62,0x11,0x4B,0xAD,0x58,0x59,0x0A,0xAB,0x6C,0x9D,0x89, -0xBA,0x14,0xD5,0xBC,0x5D,0x18,0xB4,0x6E,0x16,0x6D,0x57,0xDD,0xCB,0x91,0xC5,0x56,0x83,0xC0,0xFA,0xE2, -0xC0,0x37,0x04,0x55,0xD0,0xFA,0x9B,0x78,0x8E,0xD3,0x23,0xC4,0xB0,0x01,0x39,0xB3,0x8C,0x58,0x12,0x6A, -0xBA,0xC1,0x9A,0x5D,0xA0,0x04,0xAA,0xC0,0x79,0xE1,0x11,0x53,0x51,0x7D,0x83,0x7C,0x59,0xE3,0x04,0x6C, -0x8B,0x07,0x03,0x90,0xFA,0x58,0x35,0x1B,0x50,0xA7,0x61,0x9B,0xC1,0x35,0x5F,0xA4,0x71,0x82,0xA6,0xB2, -0xB9,0x86,0x35,0xE1,0x1E,0x05,0xB5,0x5A,0x6A,0x2D,0xEB,0x51,0x99,0xD6,0x1F,0x67,0x75,0x2C,0x33,0x37, -0x54,0x08,0xAB,0xC9,0x9B,0x9B,0x6C,0x4E,0xB8,0x3F,0x13,0xBE,0xED,0x03,0xC3,0x3A,0x87,0xCE,0xC0,0x95, -0xA3,0x19,0x8F,0xAA,0x51,0x98,0x0F,0x3F,0xB1,0x7C,0xE0,0xB3,0x62,0x74,0x5F,0x03,0xC6,0xB4,0x00,0xC7, -0x74,0x92,0x0F,0x09,0x25,0x05,0x9D,0x02,0x58,0x7C,0x26,0x49,0x3E,0x4A,0x66,0xC5,0x68,0x86,0xEF,0x4B, -0xBC,0xB8,0x80,0x06,0x58,0x77,0xD5,0xF5,0x6D,0x38,0xCB,0x7C,0xD0,0xAD,0xC4,0x0F,0xFE,0x3B,0xF1,0x13, -0x3A,0x2D,0x84,0x49,0x8A,0xD1,0x94,0x14,0xA2,0x8C,0xA3,0xE4,0x8B,0x8C,0xB0,0x7F,0xDB,0x17,0x1C,0x9F, -0xBC,0x39,0x19,0x9E,0xD4,0x4B,0xC4,0xFA,0x2B,0x02,0xFF,0xAB,0x36,0x9D,0x9B,0xAE,0x91,0xD4,0x3D,0x05, -0x66,0xBE,0xF8,0x3C,0x8B,0x03,0x59,0xF4,0x41,0xC0,0x37,0x12,0xA0,0xAE,0x9B,0x66,0xE3,0xA1,0x21,0x6D, -0x3C,0x60,0x54,0x81,0x3E,0x7F,0x19,0x00,0x3D,0x6D,0x6E,0xD6,0x18,0x91,0xEB,0xD5,0xE3,0x07,0xB5,0x74, -0x55,0xA7,0x49,0x67,0x43,0x4F,0x15,0x34,0xC8,0x2C,0x5B,0x06,0xE2,0xD1,0xDC,0xD1,0x2D,0xD1,0x3D,0x90, -0x7D,0x1F,0xDA,0x86,0x96,0xA9,0x1A,0x7E,0xCF,0xF3,0xE8,0xB5,0x7F,0x23,0x9B,0xC6,0xCD,0x4D,0xD4,0x2C, -0x7A,0x0C,0xC7,0x92,0x40,0x71,0xA0,0x1C,0xC9,0x76,0x15,0x64,0x01,0xB6,0x1C,0xEB,0xD5,0xE0,0xFC,0xCC, -0x4E,0x50,0x0A,0x1E,0x47,0xCD,0x7A,0x90,0x08,0x95,0x80,0x4D,0x6D,0xBF,0x38,0xA9,0x55,0xE3,0xF2,0x7B, -0x21,0x97,0x2F,0xAD,0xD4,0x10,0xE4,0x54,0x9F,0x2B,0x72,0x78,0xFE,0x80,0x07,0xA9,0x27,0x29,0xD2,0x50, -0x15,0x45,0x92,0x7A,0x10,0xE7,0x77,0xD9,0xFA,0x1E,0xD4,0xE2,0x33,0xC2,0xEA,0x5D,0x48,0xC3,0xE5,0xFF, -0xE6,0x8D,0x2D,0x8B,0x91,0x22,0xB7,0x5A,0x50,0xAB,0x2F,0xFF,0xD4,0xE5,0xC8,0x86,0x69,0x51,0x45,0xC8, -0xCA,0x1C,0x75,0xC8,0x2C,0x84,0xEA,0x16,0xFD,0xA7,0x1E,0x42,0x0B,0x0F,0xA1,0x8F,0x03,0x04,0xBE,0x6F, -0x78,0x7B,0x79,0x4A,0x6F,0x0C,0x9C,0xDD,0xF6,0xCA,0x28,0x02,0x10,0x19,0x43,0x1A,0x80,0x4F,0x4C,0xAE, -0x7F,0x42,0x77,0x48,0xBD,0xDF,0x55,0xD0,0xF5,0xA1,0x42,0x6E,0xF7,0x7F,0x83,0x51,0xB9,0xB3,0x19,0x88, -0x18,0x0C,0x1F,0xC7,0x13,0xDE,0x08,0x4F,0x55,0xCC,0xAA,0x47,0x27,0x70,0xD7,0xDC,0x9B,0x35,0x5E,0xD3, -0x6F,0xCD,0xF5,0xC0,0x20,0x9F,0xF4,0xBD,0x5A,0x20,0x52,0x18,0x75,0xEB,0x59,0xDF,0xAE,0x34,0x1B,0x9A, -0xF5,0xE9,0x5F,0xFA,0x1F,0x3E,0x60,0x36,0x2B,0x5A,0x77,0x70,0xF3,0xDA,0x4C,0xD7,0x45,0xB6,0xF2,0x43, -0x8C,0xD2,0x81,0xE8,0x12,0x55,0x86,0x58,0xAA,0x0B,0xF4,0xA4,0xEB,0x1A,0xA0,0xB1,0x8E,0x7C,0x28,0xB6, -0x85,0x1E,0x00,0xA1,0x84,0x52,0x80,0x52,0x2F,0x06,0x9A,0xB5,0x45,0x04,0x8B,0x08,0x1A,0x9E,0x98,0xC6, -0xB7,0x88,0xD4,0xB7,0x13,0x80,0x90,0xFC,0xEB,0x64,0xE8,0xEB,0xAC,0xFC,0x22,0x24,0xA1,0x0A,0xA2,0xAE, -0xDF,0xCC,0xDF,0xC2,0xAA,0x67,0x08,0x5C,0xF8,0x4D,0x6E,0x20,0x1B,0x12,0x8D,0x89,0x82,0x60,0x80,0x19, -0x93,0x8C,0x0B,0xC1,0xDE,0xC6,0x01,0xC8,0x05,0x68,0x9D,0x08,0x46,0xE2,0x20,0x10,0x51,0x00,0x86,0x33, -0x1C,0xE5,0x10,0x0E,0x43,0x01,0x42,0x02,0xF4,0xB5,0xD4,0xD5,0x40,0x16,0x5E,0x84,0x4E,0xBD,0x6E,0xC7, -0xB1,0x1E,0x93,0x1D,0x31,0x3C,0x88,0x27,0x7C,0x88,0xC6,0xCC,0xD8,0x70,0xCC,0x35,0x3B,0x00,0x34,0x80, -0x70,0x62,0x6C,0x99,0xEB,0xD1,0x3F,0xC4,0xE9,0x2D,0x4E,0x8D,0x8D,0x6E,0xCE,0xCF,0x29,0x14,0x4C,0x21, -0xFC,0xE7,0x7D,0x50,0xFB,0x1D,0x7E,0x43,0x28,0xCE,0x29,0x33,0x40,0x9E,0xC5,0xF3,0x8B,0x94,0x50,0xFE, -0x56,0xF6,0x85,0x39,0x96,0xAF,0x9E,0x2B,0x64,0x08,0x2A,0xDE,0x31,0x16,0x22,0x9A,0xB9,0x8D,0xD7,0x0C, -0x6B,0x0C,0xF7,0x05,0xC1,0xD5,0x5D,0xCC,0x09,0x75,0xF5,0x23,0x9E,0x86,0xED,0x81,0x6E,0x45,0xC8,0x87, -0x89,0xDA,0x03,0xF3,0xA5,0x25,0xBC,0xD6,0xAD,0x47,0x93,0x8D,0x6A,0x52,0x15,0xD0,0x6B,0x9F,0x7A,0xAA, -0x97,0x0B,0x01,0x3C,0x0C,0xE3,0xB1,0x21,0x5E,0xA7,0x17,0xC2,0xE3,0x5D,0xBA,0x34,0x45,0x7A,0xFA,0xF2, -0xAB,0x8C,0x0F,0x61,0x97,0x5B,0xB8,0xF6,0xA8,0xD4,0xD2,0x75,0xF1,0x56,0x03,0x78,0x28,0x38,0xA7,0xE1, -0x83,0x0B,0x69,0xF1,0x2F,0xA4,0xCE,0x68,0x10,0x7F,0x49,0xEA,0x8F,0x2B,0x52,0x7F,0x5C,0x27,0x35,0x6E, -0xDE,0x16,0x4C,0x46,0x40,0xF6,0x2D,0xA2,0x68,0x8A,0x53,0x58,0x10,0x87,0xC0,0x05,0xFC,0x33,0xCE,0x52, -0xFC,0x65,0xCE,0x06,0x33,0x32,0xE1,0xAB,0xFC,0xA9,0xD5,0x7F,0xC7,0x65,0x8A,0x9F,0xE0,0xB2,0x28,0x30, -0xCB,0xBC,0xF1,0xD7,0x4F,0x25,0xD2,0xA9,0x3D,0xB8,0xC2,0xBA,0xBB,0xFE,0x0B,0xBF,0xAB,0x4E,0xFC,0x72, -0xFA,0x14,0x1F,0x2E,0x5E,0x5A,0x81,0xB0,0x89,0x66,0x59,0x1A,0xD3,0x43,0xA8,0xE0,0xDF,0x80,0x08,0x86, -0x32,0x47,0xEC,0x2D,0x96,0x16,0xF7,0x0C,0x50,0x25,0x74,0xC1,0x20,0x9C,0x2F,0xEB,0x5A,0x7B,0x06,0x29, -0x12,0x94,0x00,0x4C,0x42,0xA2,0xED,0x5C,0x1F,0x6C,0xDE,0xB4,0x20,0x43,0x79,0xF0,0x61,0x7A,0x30,0xD8, -0xBC,0xF9,0xCE,0xEC,0x4C,0x49,0xAD,0x26,0x92,0xB9,0x0E,0xF4,0x7A,0x4D,0x6F,0x3C,0xB4,0x84,0x10,0x56, -0xCF,0x85,0x65,0x64,0xB5,0xB0,0x7C,0xF5,0x82,0x8F,0x10,0xD1,0x29,0x7C,0xC8,0xD8,0x01,0xE1,0x69,0xCD, -0xF7,0x2B,0x7A,0xA6,0x46,0x80,0x55,0x7B,0xA8,0xD2,0x39,0xFC,0xD4,0x45,0x7B,0xC5,0x6B,0xC1,0x50,0x91, -0x85,0xB8,0xA7,0x06,0xF5,0x18,0x2B,0x92,0x74,0x71,0x69,0x39,0xD8,0x5C,0x0A,0x53,0xC7,0x13,0x42,0x71, -0xA0,0x97,0x79,0xF5,0xE7,0xB7,0x6F,0x4E,0x39,0x4F,0x2E,0x95,0x66,0x81,0x56,0x73,0xA1,0xBA,0x70,0x73, -0xC1,0xD3,0x87,0xA2,0x42,0x13,0x0E,0xAB,0x42,0xCE,0xCF,0xE7,0xE3,0x4F,0xD8,0x87,0x7C,0xF4,0x96,0x41, -0x32,0xDB,0xB2,0x05,0xFA,0x70,0x78,0x61,0xEF,0xDA,0x0E,0x94,0x0C,0x3E,0x82,0x94,0x2D,0x6E,0x6E,0xF9, -0x8F,0x90,0xB7,0xFF,0x19,0x32,0x81,0xB8,0xCB,0x20,0xB0,0x16,0xF8,0x4D,0xDC,0x59,0x1A,0xCF,0x25,0xDA, -0x49,0x9A,0x8A,0x4B,0x19,0xCE,0x08,0xD3,0xC6,0xB0,0xC8,0x70,0xAA,0x05,0x31,0x66,0x1A,0x8D,0xB9,0xC6, -0xB2,0x24,0x89,0x53,0xBE,0xA2,0x0F,0x5B,0x2F,0x1E,0x6C,0xDE,0x65,0x38,0xC3,0x41,0xBE,0x8C,0xD3,0xBA, -0x5E,0x64,0x71,0x05,0xEB,0x60,0xF6,0xD7,0x37,0x79,0xA9,0x95,0x51,0x2A,0xF2,0xC0,0x46,0x57,0xCD,0x41, -0xBA,0x19,0x50,0xF5,0x68,0x16,0x86,0xCB,0xDE,0x0A,0x2D,0xE8,0xB8,0x62,0x1E,0xCB,0xAF,0x28,0x16,0xBF, -0xE5,0x26,0xEE,0xAE,0xBC,0xA8,0x36,0xA9,0x3A,0xD6,0x86,0xB1,0x81,0x35,0x42,0x19,0x47,0xD4,0x17,0xD7, -0xA8,0x74,0x61,0x16,0x65,0x96,0xD8,0xDE,0x13,0xFE,0x29,0x6D,0xE9,0xC9,0xDC,0x2E,0x25,0xA3,0x9E,0xAE, -0x8B,0x8A,0x0B,0x8B,0xC2,0x15,0x45,0xAC,0x46,0xB6,0x8C,0xD8,0x26,0xF5,0x0A,0x70,0x4F,0xBE,0x83,0x37, -0xF7,0xAF,0xB2,0x51,0x94,0xD9,0x08,0x60,0x5A,0xB1,0xCF,0xA4,0x2D,0x4F,0x97,0x99,0xFA,0x40,0xBA,0xAE, -0x34,0xE0,0x08,0xF3,0x59,0x1C,0x1C,0xE8,0x07,0xBA,0xAB,0xC3,0xBF,0x4D,0xDD,0x82,0x5D,0x98,0xFA,0xE0, -0xFE,0xA3,0xCB,0x97,0x10,0xD2,0x92,0x98,0x62,0xCA,0x0D,0x04,0x91,0xDD,0xD3,0x5B,0x6B,0x20,0x05,0xF9, -0x6B,0x74,0x63,0xF6,0x9A,0xCA,0xC6,0xF3,0x95,0xEB,0x6C,0x5C,0x86,0x1D,0x53,0x11,0xE5,0x1E,0x80,0x79, -0x8E,0x1F,0xBD,0x63,0x5B,0xF4,0x71,0x3B,0x62,0x2E,0x76,0x04,0xCF,0x12,0x6B,0x00,0x58,0xC2,0xF5,0x2A, -0x25,0x3F,0x55,0x62,0x51,0xDB,0x47,0x61,0x28,0xBE,0x7E,0x07,0x5E,0xC5,0x61,0x19,0xB3,0x04,0x11,0x06, -0x02,0x30,0x3C,0xC4,0xF7,0xE0,0xD2,0xB2,0x4E,0x52,0x36,0x94,0xF7,0x25,0x40,0x9A,0xD7,0xCC,0xC8,0xB4, -0xCA,0xD9,0xE6,0x26,0xB7,0x0B,0x33,0x31,0x0A,0x24,0x26,0x82,0xBE,0x61,0x8A,0x9E,0xC3,0xA8,0x0B,0x29, -0x72,0xE8,0x23,0x6D,0x1B,0x4D,0x35,0x24,0x98,0x1A,0x05,0x0C,0x38,0xCB,0xD2,0x10,0x22,0xB5,0xA8,0x22, -0x1A,0xDB,0x18,0xA6,0x01,0x1C,0xE0,0xFE,0x25,0xB2,0x44,0xA5,0x75,0xAB,0x18,0xF0,0x54,0xF1,0xDD,0xA4, -0xC7,0xF3,0x5B,0x39,0xC5,0x32,0xF2,0x35,0x7F,0xF3,0xD0,0xD2,0x51,0x92,0x84,0x44,0x05,0xE6,0x0E,0x3C, -0x7C,0xCF,0xE7,0x6D,0x30,0xAB,0xA8,0x0D,0x27,0x28,0x2B,0x08,0xF4,0x35,0x1C,0xAA,0xB6,0xCB,0x12,0x0F, -0x16,0xEE,0x8A,0x8B,0x56,0xFA,0x33,0x56,0x7C,0xB4,0x49,0xA7,0xC9,0x67,0xED,0xB6,0xF7,0x76,0x56,0x40, -0x68,0x2C,0xBE,0x67,0x87,0x5C,0x03,0xE9,0xA8,0x3C,0xAD,0xE8,0x80,0xEA,0x71,0xC1,0x4E,0x32,0x36,0x33, -0x16,0xC0,0xBA,0xCB,0x2D,0xA5,0x2B,0x17,0x5B,0xCA,0x6E,0x5D,0x6A,0x15,0xF6,0xE1,0x42,0x0A,0x69,0xC4, -0x8F,0x3F,0xFE,0x90,0xB3,0xEA,0xB6,0x61,0xB6,0x72,0xE1,0x4B,0xF5,0xC6,0x5A,0x64,0x46,0x61,0xF4,0xAB, -0xB1,0x6A,0xAF,0xA3,0x1A,0x9B,0xE2,0x17,0x14,0x34,0x12,0x78,0x22,0xC9,0xEA,0xEA,0x31,0x18,0x46,0x13, -0x08,0x4B,0x36,0x34,0x42,0xC5,0xAF,0x76,0xEA,0xF9,0xEF,0x76,0xAE,0x62,0xEE,0x97,0x8D,0x99,0xE7,0x95, -0x55,0xB5,0x8A,0x39,0x6A,0x83,0xF7,0xC4,0x2F,0x2D,0xE8,0x0A,0x0C,0x7D,0xAB,0x1A,0xD8,0xE5,0xD1,0xE2, -0x58,0x2B,0x5F,0x44,0xEC,0x81,0xFA,0x22,0x66,0x96,0x54,0x66,0xA0,0xFC,0x46,0x2F,0xAB,0x76,0x9A,0xCB, -0x8A,0x33,0xF1,0x38,0xA7,0xC5,0xF9,0x4B,0x76,0x3D,0xD3,0x03,0xFB,0xD0,0x2A,0x0B,0x61,0x0B,0x07,0x95, -0xAD,0x72,0x39,0x03,0xE9,0x00,0x5E,0x6D,0xCA,0x92,0xF5,0x00,0x95,0x7B,0x57,0x17,0x55,0x6A,0x5F,0x5D, -0x2E,0xDB,0xAD,0xFC,0x2B,0x9B,0xDA,0x6F,0x9B,0x54,0x24,0x88,0x7C,0x8C,0x97,0xDB,0x9B,0xEF,0xF3,0x4F, -0x61,0x29,0x84,0xFD,0x3F,0x01,0xA4,0x40,0xDC,0x9E,0xCB,0x2B,0x00,0x00 +0x6F,0xF3,0x87,0x04,0xEB,0x9A,0xAF,0x66,0x9E,0xCE,0xF1,0x3D,0xEF,0x08,0xE4,0x9E,0xE6,0xCF,0x50,0xCA, +0x30,0xF7,0x32,0x3E,0x69,0x3F,0x07,0x12,0x9C,0xF0,0x10,0xEF,0x9F,0x0C,0x2E,0xB4,0x93,0x80,0xF0,0x38, +0xDD,0xEB,0xA8,0x95,0x3D,0xC6,0x1F,0x42,0xAC,0x09,0x42,0x39,0xBE,0xCF,0x98,0xAE,0x45,0x38,0x20,0xC8, +0xD3,0x99,0x9F,0x62,0xC1,0x41,0x88,0xC6,0x38,0x5C,0x4C,0x62,0x38,0x92,0x91,0xCF,0xD8,0xED,0x6E,0x25, +0xF7,0x3D,0x39,0x9D,0xA0,0x88,0x84,0x0F,0x2E,0x43,0x94,0xB5,0x19,0x4E,0xC9,0x64,0x69,0xFB,0xD1,0xE2, +0x73,0x9B,0xD0,0x00,0xDF,0xBB,0xDB,0x8E,0xD3,0x4B,0x62,0x46,0x38,0x89,0xA9,0x8B,0xC6,0x2C,0x0E,0x33, +0x8E,0x7B,0x21,0x9E,0x70,0xF7,0x19,0x50,0x18,0xC7,0x69,0x80,0x53,0xB7,0x9B,0xDC,0x6B,0x00,0x22,0x81, +0xF6,0xD5,0xCE,0xCE,0x4E,0x6F,0x8C,0xFC,0xDB,0x69,0x1A,0x67,0x34,0x68,0xFB,0x71,0x18,0xA7,0xEE,0x57, +0x93,0x67,0xE2,0x6F,0x2F,0x20,0x2C,0x09,0xD1,0x83,0x4B,0x63,0x8A,0x01,0xF7,0xBE,0xCD,0x66,0x28,0x88, +0xE7,0xAE,0xA3,0x39,0x5A,0xD7,0x01,0x22,0xE9,0x74,0x8C,0x0C,0xC7,0x12,0x7F,0xED,0x1D,0xB3,0xF7,0xB7, +0xF8,0x55,0xCB,0x73,0x4C,0xA6,0x33,0xEE,0x7E,0xEF,0x38,0x82,0x7F,0x2D,0x0B,0x17,0x21,0x61,0xBC,0x2D, +0x95,0xA3,0xCE,0xE3,0x71,0xE2,0x3A,0x92,0x75,0xF8,0x88,0x50,0x3A,0x25,0x14,0x06,0x09,0x0A,0x02,0x42, +0xA7,0xAE,0x42,0x0B,0xC9,0xA2,0x94,0x36,0xC5,0x21,0xE2,0xE4,0x0E,0xF7,0x22,0x42,0xDB,0x73,0x12,0xF0, +0x99,0xBB,0xEB,0x00,0x17,0x7E,0x96,0x32,0x90,0x29,0x89,0x09,0xE5,0x38,0x95,0x68,0x2C,0x41,0x74,0xA1, +0x44,0x15,0x0A,0x28,0xE5,0x24,0x34,0x24,0x14,0xB7,0xC7,0x61,0xEC,0xDF,0x96,0x27,0xED,0x26,0xF7,0xF9, +0x59,0xEE,0x2C,0xBE,0xC3,0xE9,0xA2,0x52,0x97,0xC4,0x6E,0x00,0x1B,0xA4,0x31,0xC6,0x4B,0x9B,0xDF,0x65, +0x00,0xB5,0xE4,0x27,0x48,0x99,0x53,0xAD,0x8B,0xD4,0x14,0x3C,0x47,0x21,0x34,0xC9,0xF8,0xE2,0xF1,0x55, +0xC6,0x09,0xF2,0x09,0x7F,0x70,0x1D,0xB9,0x4D,0x5A,0x88,0xBB,0xE3,0x38,0x9A,0x50,0xB8,0xF6,0x1E,0xA7, +0x01,0xA2,0xC8,0xEA,0xA7,0x04,0x85,0xD6,0xA0,0x52,0x79,0x3B,0x8A,0x3F,0xB7,0x33,0x18,0xC3,0x3C,0xC4, +0x3E,0x57,0x1A,0x86,0x4B,0x18,0xDF,0x12,0xFE,0x18,0xF0,0x68,0xA1,0xA6,0x2B,0xA9,0xA1,0x99,0xBA,0xBD, +0x2E,0xE8,0x46,0xF2,0xA1,0xC4,0x56,0x12,0xB5,0xC7,0x31,0xE7,0x71,0x24,0xED,0xAD,0x94,0x56,0x93,0x26, +0xF3,0xFC,0xD1,0x75,0xAC,0x57,0x7D,0x8D,0x7C,0x0F,0x94,0xCA,0x89,0x8F,0xC2,0x36,0x0A,0xC9,0x94,0xBA, +0x11,0x09,0x82,0x10,0xD7,0x4C,0xD6,0xCD,0xD2,0xD0,0x08,0x10,0x47,0x2E,0x89,0xD0,0x14,0x77,0x12,0x3A, +0x05,0x28,0xC3,0xBB,0x3B,0x16,0x79,0x7F,0x78,0x7E,0x39,0x77,0x5E,0xBF,0x98,0xC6,0x7D,0xF8,0x73,0x36, +0x18,0xCD,0x4E,0x46,0x53,0x18,0x1D,0x8A,0x69,0xFF,0xDD,0x51,0xFF,0x1D,0x7C,0x1C,0x75,0x5B,0x9F,0x26, +0xBF,0xF7,0xC5,0xF2,0x8B,0xE0,0x70,0x38,0x3A,0xE9,0xF7,0x5F,0x77,0x5E,0x9E,0xCD,0x3F,0xBC,0xDE,0x15, +0xE0,0xC3,0xD0,0xB9,0x7C,0x3F,0x73,0x46,0x5B,0x3F,0x44,0xC1,0x69,0x30,0xF3,0xA3,0x51,0xFF,0xDD,0x87, +0xCB,0xBB,0xAB,0x68,0x34,0x1D,0x7C,0xE8,0xCE,0x3E,0x6E,0xBD,0x1F,0x7C,0xFC,0xF0,0xD3,0x2D,0xFE,0xF9, +0xF4,0xD5,0xC7,0xE1,0x1C,0x10,0x8E,0xE3,0xC1,0xE8,0xF2,0xF0,0xFD,0xE1,0xF4,0xE3,0xA1,0x7F,0x72,0x3F, +0x0E,0xCF,0x0E,0x5F,0xF4,0xC7,0xFD,0x2D,0x1F,0xE3,0xE9,0xF0,0xF2,0x30,0x7B,0xF9,0xFA,0x7C,0x4A,0xC8, +0x6C,0xF0,0xF1,0x6C,0xE8,0x1F,0x3D,0x7B,0x33,0x3A,0xED,0x93,0xD9,0xD9,0xAB,0x4B,0xE7,0xF6,0xC5,0xEB, +0xA3,0x63,0xFF,0xEA,0xD5,0xD5,0xEE,0xF1,0x76,0xE7,0xFB,0xEF,0xDF,0x06,0xE7,0x84,0x0E,0xEF,0x3E,0xF7, +0xA7,0x47,0xF3,0xE7,0x0F,0x6C,0x38,0x7B,0x79,0x47,0x3B,0xEF,0xE3,0x4F,0x2F,0x1F,0xDE,0xC2,0xFF,0x8B, +0x8B,0xD6,0x78,0xD0,0x65,0xA3,0x77,0x2F,0xDF,0x6F,0xB1,0x1F,0x9E,0x25,0x87,0xC7,0xC7,0x77,0xD1,0xF8, +0xA2,0x13,0x05,0xB7,0x13,0xFE,0x7C,0x9B,0x27,0x57,0xD3,0xEC,0xE3,0xEF,0xCF,0x5E,0xCD,0x3A,0xE7,0x18, +0x5D,0xCD,0x5A,0x0F,0x9F,0x1F,0x9E,0xCF,0x86,0xA7,0x77,0x67,0x21,0xBA,0x3F,0x3B,0xF3,0x3F,0x47,0xAD, +0x10,0xFD,0x70,0x3E,0x0C,0x51,0xDA,0x1D,0x05,0xFD,0x4E,0xEB,0x68,0xAB,0xBF,0xC3,0xD3,0xCB,0x23,0x7A, +0xBC,0xFD,0x69,0xF0,0xFC,0xF0,0xB0,0x1B,0x8F,0x7F,0xDF,0x7A,0x71,0xBB,0xFB,0x62,0xB4,0xFB,0x6E,0xFC, +0xAE,0x3F,0xD8,0x39,0x1C,0xA1,0xAB,0xC1,0xBB,0xFE,0x64,0x67,0x3C,0x9B,0xBD,0x7E,0x3D,0xFC,0x29,0xE8, +0x7F,0x4E,0xFB,0xE7,0xF3,0xFE,0xFD,0xC9,0xA8,0x7F,0xDA,0x7A,0x7D,0xF2,0xD6,0xE9,0x0E,0xAE,0xB6,0xA7, +0x6F,0x77,0xE7,0x87,0xEC,0xA4,0xFF,0xEE,0xD0,0x99,0xBE,0x6A,0x45,0xE8,0x63,0x7C,0xB4,0x3D,0x7D,0xB9, +0x4B,0x2E,0xAE,0x50,0xFF,0xE5,0xE1,0x2B,0x46,0x2E,0xA3,0xD3,0x91,0xD3,0xEF,0xBF,0x39,0xC7,0x3F,0x1D, +0x6D,0xA3,0xD7,0x5B,0xFE,0x07,0xD0,0xFF,0xE8,0x67,0xFC,0x7D,0xAB,0x3F,0x3F,0x77,0x42,0xFF,0x07,0x3C, +0x3C,0xBD,0x1A,0xCA,0xDB,0x39,0x09,0x7F,0x1A,0xDE,0x0E,0xB2,0x77,0xD1,0xD1,0x91,0xA9,0xD1,0xB8,0x9D, +0xE2,0x04,0x23,0x5E,0x8F,0x55,0xA5,0x73,0x80,0x6D,0x55,0x56,0x98,0x3B,0xA9,0x88,0xAC,0xED,0x00,0xFB, +0x71,0x8A,0xE4,0x1E,0x40,0xC0,0xA9,0x30,0xB1,0xE5,0x8F,0x32,0xD4,0x6A,0x2A,0xD2,0x6A,0x88,0x06,0x9A, +0x51,0x38,0x42,0x44,0x28,0xE0,0xDC,0x11,0x1F,0xB7,0x13,0x72,0x8F,0xC3,0xB6,0x44,0x76,0x1D,0x73,0x21, +0x9D,0xAD,0xD8,0x86,0x28,0x89,0x14,0xD5,0x62,0x21,0xF8,0x84,0x7C,0x91,0x1E,0xC0,0x65,0x22,0xF8,0xCC, +0x7D,0x27,0x4E,0xDB,0xE3,0x6C,0x3A,0x21,0xF7,0xE0,0xCD,0x13,0x42,0x09,0xC7,0x5A,0x97,0x2D,0x7F,0x2C, +0xC8,0xDC,0xE2,0x87,0x49,0x8A,0x22,0xCC,0xB4,0xBF,0x49,0x66,0x31,0x49,0xE3,0x68,0x51,0x45,0x40,0x1E, +0xD7,0x26,0xCB,0xE5,0x57,0x59,0x12,0xC6,0x08,0xC4,0x5C,0x13,0x36,0x54,0x30,0x4D,0x85,0x5B,0x95,0x41, +0xB5,0x70,0xB3,0x2D,0x70,0xCB,0x86,0x5B,0x6F,0xED,0x54,0xAE,0xDB,0x96,0x7B,0x45,0xB0,0xAF,0xAB,0xBE, +0x16,0x0F,0x6A,0xB1,0xEE,0x2B,0x0E,0x2A,0x5D,0x7F,0xB8,0x3A,0x44,0x45,0x86,0x8A,0x01,0x15,0xA5,0xBB, +0xBB,0x4E,0x2D,0x54,0xC0,0xBE,0xE5,0x57,0x58,0xA6,0x4C,0xEB,0xAB,0x24,0x85,0xDB,0xC0,0xF3,0x2F,0xD0, +0x2C,0x65,0x6A,0xD2,0x06,0x9A,0x65,0xBA,0x53,0x22,0x54,0x39,0x4F,0xF2,0x5A,0x92,0x7E,0x2C,0x15,0x80, +0x4B,0x6E,0x9E,0x09,0x6E,0xBE,0xA8,0xD5,0xED,0xDD,0x6F,0x72,0x1E,0x76,0x9C,0x6F,0x96,0xB6,0xDA,0x5B, +0xE6,0xE3,0xAE,0x03,0x7F,0x8A,0xB4,0xFB,0xBC,0x62,0x61,0xFC,0x4C,0xFC,0x2D,0x18,0x04,0x3A,0x75,0xE0, +0xF6,0xCE,0x0F,0xCF,0x83,0x71,0x01,0x54,0x82,0x3D,0x0D,0x4F,0x51,0x40,0x32,0xE6,0x3E,0x73,0xBE,0x51, +0xFA,0x84,0xEB,0x03,0xD9,0x8B,0xCB,0x55,0x93,0xCA,0x62,0x59,0x42,0xA8,0xB6,0xC5,0x34,0x71,0xDF,0x28, +0x2D,0x0D,0xB3,0x9E,0xEA,0xC1,0x45,0x2A,0xD3,0x14,0xFB,0x17,0xCE,0x37,0x0B,0x9E,0x22,0xCA,0x26,0x71, +0x1A,0xB9,0x69,0xCC,0x11,0xC7,0x86,0x63,0x2E,0xBB,0xCE,0x3A,0xC0,0xF6,0xAE,0x13,0xE0,0xA9,0xB9,0x5C, +0xEE,0x75,0x20,0xA9,0xC9,0x8A,0xC7,0x4F,0x49,0xC2,0xF7,0x27,0x19,0xF5,0x05,0x0F,0xDA,0x14,0x1B,0xD8, +0x5C,0xA4,0x98,0x67,0x29,0xD5,0x82,0xD8,0xCF,0x84,0xB1,0xDB,0x53,0xCC,0x4F,0x94,0xDD,0x1F,0x3E,0xBC, +0x0C,0x60,0xC7,0xB2,0x44,0xF0,0xD7,0x22,0x80,0x03,0xC3,0x79,0x39,0x4E,0x63,0x3F,0x24,0x18,0x20,0xF2, +0x1A,0x3F,0x18,0xD8,0xE2,0x25,0x22,0xB6,0xC5,0xBA,0x61,0x14,0xDB,0x00,0x48,0xCD,0xC5,0x1D,0x68,0x01, +0x79,0xF8,0x9A,0xDF,0x58,0xC4,0xA3,0xF0,0xD1,0xCB,0xB7,0x93,0x7D,0x74,0xD0,0xEE,0xBA,0x68,0x9F,0x1C, +0x74,0xC1,0xBF,0xCC,0x1A,0x7D,0x75,0xF2,0x4F,0x24,0xC4,0xA3,0xDC,0xE5,0xC4,0x41,0x15,0xB5,0x8E,0x41, +0x2E,0x66,0xA0,0x48,0xF3,0x3B,0xE3,0x7C,0xA0,0x19,0xD7,0xDF,0xB7,0x7F,0xB8,0xF9,0xA3,0x7B,0xED,0xB4, +0xBB,0x37,0xE6,0x6F,0x66,0x87,0xD8,0x1C,0x33,0x6E,0x50,0x74,0x47,0xA6,0x08,0xEC,0xDC,0x16,0xF9,0xB6, +0x3F,0x05,0x29,0xCC,0x5E,0x79,0x06,0x51,0xEC,0x6D,0x39,0xCE,0x86,0x87,0x0F,0x50,0x88,0x81,0x75,0xFD, +0xE4,0xF2,0xF2,0xFC,0xF2,0x5A,0x6F,0xE1,0x96,0x7E,0xE3,0x6A,0x7A,0x8B,0x9A,0x2E,0xB7,0x53,0x3C,0x49, +0x31,0x9B,0x5D,0x20,0x3E,0x33,0x02,0xFB,0x0E,0x85,0x19,0xE8,0x42,0x30,0x12,0x7B,0xA0,0x38,0x7D,0x9C, +0x81,0xFD,0x50,0xDD,0xEC,0xC5,0x36,0xA1,0x14,0xA7,0xA7,0xC3,0xB7,0x6F,0x3C,0xFD,0x52,0x21,0x69,0x6F, +0x08,0xE3,0xBA,0x25,0x6F,0xC4,0x46,0x49,0x82,0x69,0x70,0x34,0x23,0x61,0x60,0xC4,0x66,0x4F,0x90,0xF0, +0x25,0x09,0x59,0x8C,0x00,0x05,0xDF,0x56,0x65,0xEB,0x04,0x24,0xD7,0x2D,0xDF,0x8E,0xB2,0x90,0x93,0x24, +0xC4,0xDE,0x46,0x17,0x66,0x14,0x45,0x00,0x13,0xA9,0x58,0xC0,0x48,0xE0,0xE9,0x2A,0x20,0xA9,0x30,0xB6, +0xF6,0x14,0x5F,0x9D,0x12,0x34,0x4E,0x09,0xEA,0xB8,0x09,0x48,0xA5,0x5B,0x81,0x5D,0xD5,0xCB,0x30,0xCB, +0x8F,0x2A,0x60,0x01,0x9E,0x20,0xE0,0xE4,0x3D,0x48,0x0E,0xAB,0x9D,0x75,0x07,0x05,0xEA,0x20,0xD6,0xD4, +0x08,0xAB,0x6B,0x44,0x5D,0xE5,0x3A,0x64,0xA6,0x90,0xD3,0x26,0x72,0x5A,0x47,0x3E,0x92,0x16,0xB1,0x0E, +0x39,0x55,0xC8,0x61,0x43,0xC4,0x50,0x8A,0xA8,0xA2,0x5C,0x5B,0x68,0x13,0x04,0x02,0xEC,0xB0,0x2E,0x26, +0xCC,0xC0,0x29,0xD1,0x38,0xC4,0x81,0xB7,0xE1,0xC0,0x4C,0x14,0xD6,0xDE,0x96,0xB3,0xE6,0x8C,0x50,0x9D, +0x91,0x35,0xCE,0xC8,0xE4,0x19,0x24,0x01,0x25,0x42,0xEE,0xD0,0xAD,0x4C,0x6A,0xAD,0xB9,0xA2,0x8E,0xF3, +0x67,0xD8,0xBF,0x85,0xF2,0x7E,0x1D,0xFB,0x99,0x09,0xDB,0xE4,0x06,0xC1,0xC6,0x06,0x92,0x07,0x25,0xF2, +0x20,0xD9,0xA3,0xC0,0x41,0x89,0x0D,0xEE,0xEF,0x89,0xE3,0xAC,0xA4,0xAE,0x93,0xF3,0x30,0xD0,0x08,0xD8, +0xFF,0x3A,0xB2,0x89,0xE2,0x38,0x6A,0xAA,0x34,0xAA,0xA3,0x6B,0x03,0x74,0x87,0xD7,0x22,0x47,0xA6,0x95, +0xDA,0x31,0xF5,0x43,0xE2,0xDF,0x7A,0x95,0x37,0x9B,0x0B,0xA3,0x3E,0x11,0xF4,0xB9,0x47,0xF1,0x5C,0xFB, +0x09,0xA2,0xD3,0x31,0xE2,0xA8,0xC7,0x73,0x32,0x46,0x6E,0x3A,0x18,0x08,0x41,0x83,0x87,0x19,0x67,0x36, +0x0A,0x60,0xF9,0x62,0x34,0xD4,0x2D,0xBD,0x23,0x2E,0x46,0x07,0x87,0x26,0xE6,0xD2,0x2C,0x5D,0xCA,0xA2, +0x32,0xB8,0x8F,0xD2,0xB0,0x5A,0x82,0x41,0x61,0x74,0x4B,0x2B,0x5A,0xCB,0x13,0x99,0x18,0xA5,0x02,0x0B, +0xA6,0x90,0x8F,0x6D,0x71,0x86,0x91,0x9B,0x80,0x6E,0x42,0xF4,0x53,0xF6,0x6B,0x98,0x16,0x6A,0x32,0x8D, +0x4A,0xA6,0x53,0x34,0x2F,0xEC,0x44,0x9D,0xDF,0x53,0x5E,0xEE,0x40,0x12,0xA6,0x8C,0x6B,0xD8,0xDB,0x71, +0x7E,0xD8,0xED,0xC1,0x6D,0x18,0xCA,0x77,0x01,0xB0,0xC7,0x6D,0xB0,0xAE,0x29,0x9F,0xF5,0xFC,0x96,0x97, +0x6B,0x25,0xF0,0xB8,0xCD,0xB2,0x31,0xE3,0x29,0xA4,0x38,0xC3,0xB7,0xFC,0x16,0x36,0x9B,0xC7,0xE8,0xAD, +0xD8,0x0A,0x4C,0x2B,0x6E,0xB5,0x96,0x2B,0x0A,0x3A,0x1F,0xD4,0x34,0x84,0x84,0x86,0x70,0xC8,0xB0,0x46, +0x6D,0x7C,0x8F,0xFD,0xA3,0x38,0x8A,0x90,0x20,0xC1,0xE0,0xEA,0xF2,0x89,0x6E,0x2E,0xAD,0x78,0xAD,0x66, +0x9E,0x88,0x5C,0x16,0x7B,0x4A,0x8F,0x10,0x09,0x3D,0xDF,0x16,0xEE,0xC2,0x72,0xA1,0xBE,0x7C,0xCB,0x45, +0x2C,0x52,0x28,0xD7,0xCE,0x8D,0x55,0x5E,0xDC,0x7A,0xA9,0xAA,0x7B,0x17,0x56,0xD7,0x08,0x41,0x66,0x75, +0xD3,0x02,0xD6,0x0C,0x6D,0x15,0x54,0x5F,0x2E,0x2D,0x5F,0xF0,0x3F,0x43,0x74,0x8A,0xFF,0xBE,0x00,0x15, +0x8F,0xD2,0x4B,0x2D,0x0A,0x39,0xE4,0xC0,0xFD,0xC5,0x36,0xAE,0x7F,0xB5,0x6F,0x5A,0xA6,0x79,0xF0,0x75, +0x47,0x6A,0xD8,0xE0,0xE6,0x75,0xF7,0xC6,0x42,0x00,0xB6,0xBF,0x33,0x7F,0xB1,0x25,0xB8,0x01,0xEB,0xDD, +0xC5,0x24,0xD0,0xC4,0x49,0xC2,0xB9,0xE3,0x89,0x86,0x36,0x37,0x0D,0x30,0xB9,0x86,0xB1,0xB6,0x78,0x4B, +0xB7,0x21,0x7D,0x2C,0x97,0xAB,0x49,0x6D,0x98,0x62,0xAC,0xB2,0x66,0x09,0x90,0xDC,0x83,0xCC,0xAB,0xF1, +0xAA,0x94,0x1A,0x5B,0x15,0x14,0x16,0x65,0xD6,0xB7,0xF3,0x82,0xC2,0xD3,0x45,0x45,0x01,0xB1,0x66,0x75, +0x59,0x76,0x7A,0xB0,0x5E,0x73,0xF9,0x6F,0xF7,0x48,0x34,0xD5,0x58,0xEA,0x7B,0xEA,0x2A,0x0E,0xC4,0x0F, +0xEF,0x5B,0x91,0xED,0x36,0x7F,0xF3,0xC7,0x9E,0xDE,0x82,0xFB,0xC5,0x36,0x8D,0xE7,0x86,0xD9,0xFA,0x56, +0xD7,0x24,0x45,0x4F,0x8F,0xD0,0x7D,0xDE,0xEF,0x8B,0x82,0xA4,0xA7,0xC1,0xBC,0x6C,0x50,0xD5,0x82,0xEA, +0xB4,0x51,0xC6,0xE3,0x9E,0x56,0x14,0x3A,0xAA,0xD3,0xD4,0xB5,0xCE,0xFE,0xB7,0x95,0x0E,0x10,0x88,0x8E, +0xD4,0x9D,0x10,0x19,0x9A,0x32,0x11,0xE0,0x70,0x23,0xFA,0x90,0xDC,0xED,0x54,0x0C,0x24,0x00,0x27,0x2B, +0x99,0xD3,0x0A,0x0C,0x64,0x1E,0x18,0x8D,0x7C,0xBB,0x27,0x7A,0x93,0xFD,0x0B,0x55,0x74,0xEE,0x75,0xE4, +0x4C,0x5F,0xE7,0x18,0xA0,0x79,0x0A,0xE8,0x56,0x59,0xE6,0x8C,0xE3,0xE0,0xA1,0x56,0x1C,0xB1,0xC3,0x87, +0xA3,0x10,0x31,0x76,0x86,0x22,0x38,0xDF,0x8F,0x74,0x33,0x37,0xA5,0x7D,0x67,0x73,0xB3,0x89,0x94,0xE2, +0x08,0x7A,0x21,0xC5,0x15,0x86,0x50,0xE6,0xFA,0x40,0x78,0x73,0x73,0x1D,0x63,0xE2,0x8D,0xEA,0x4B,0x5C, +0x51,0x70,0xD7,0x22,0xFC,0xFD,0x4F,0xDC,0xA9,0x1C,0xFB,0x94,0x56,0x53,0xF0,0xD9,0xC7,0x6C,0x1F,0xC7, +0x73,0x2A,0xB8,0x2A,0x59,0x4F,0xD7,0x28,0xB4,0xCA,0x0B,0xA5,0x25,0x07,0x39,0x5E,0x7B,0x92,0x2A,0x43, +0xAE,0x19,0x5D,0x01,0x03,0x73,0xC3,0x4B,0xF3,0xFF,0x11,0x56,0x95,0x04,0x4F,0xC9,0x1A,0x9A,0x56,0xB8, +0x46,0x56,0x1C,0x62,0x8E,0x4B,0x49,0xC3,0xB5,0x92,0xB2,0xFF,0x87,0xDF,0xCA,0x43,0x88,0xAA,0x74,0xEB, +0x3E,0x12,0x90,0x3B,0x1D,0x72,0x85,0xD7,0xA4,0xC0,0xFC,0x34,0x0E,0xC3,0x61,0x9C,0x1C,0x3C,0xB1,0xEE, +0x96,0xEB,0xF9,0xA0,0x60,0xB3,0xDA,0x62,0xF9,0x6B,0x89,0xBE,0xC1,0x13,0x7E,0xF0,0x14,0xE0,0x69,0xB2, +0xD5,0x1E,0x2B,0xF0,0xB0,0x0D,0xCA,0x83,0xD5,0x9F,0x5B,0xBE,0xC5,0xCA,0xD9,0x55,0x2B,0x86,0xBB,0xF0, +0x0B,0x25,0x79,0x42,0x49,0x16,0x59,0x1B,0xBA,0xAA,0x75,0xD1,0x5E,0x7A,0x41,0x4B,0x4F,0xEE,0xAB,0x35, +0x1E,0x27,0x1E,0x53,0x4B,0xC8,0x20,0x16,0x5F,0xB9,0x94,0x75,0x01,0x25,0xF5,0x88,0x1D,0x4F,0x26,0x0C, +0xF3,0x0F,0x22,0x98,0x59,0x61,0x39,0x3F,0x95,0xC1,0xAC,0x07,0x53,0x1A,0xC5,0x19,0xC3,0x71,0xC6,0x9B, +0x65,0x4F,0x29,0xCC,0x5E,0xF0,0xC7,0x1F,0xE5,0x64,0x3F,0x68,0xA5,0xD5,0xF4,0x6A,0x8F,0xD5,0x26,0xFB, +0xAC,0x15,0x42,0x28,0xF8,0x8F,0x2D,0x85,0xD4,0x2D,0x25,0x16,0xB1,0xD4,0x8A,0x95,0xA5,0xB0,0xCA,0xD6, +0x99,0xA8,0x4B,0x51,0xCD,0xDB,0x85,0x41,0xEB,0x66,0xD1,0x76,0xD5,0xBD,0x1C,0x59,0x6C,0x35,0x08,0xAC, +0x2F,0x0E,0x7C,0x43,0x50,0x05,0xAD,0xBF,0x89,0xE7,0x38,0x3D,0x42,0x0C,0x1B,0x90,0x33,0xCB,0x88,0x25, +0xA1,0xA6,0x1B,0xAC,0xD9,0x05,0x4A,0xA0,0x0A,0x9C,0x17,0x1E,0x31,0x15,0xD5,0x37,0xC8,0x97,0x35,0x4E, +0xC0,0xB6,0x78,0x30,0x00,0xA9,0x8F,0x55,0xB3,0x01,0x75,0x1A,0xB6,0x19,0x5C,0xF3,0x45,0x1A,0x27,0x68, +0x2A,0x9B,0x6B,0x58,0x13,0xEE,0x51,0x50,0xAB,0xA5,0xD6,0xB2,0x1E,0x95,0x69,0xFD,0x71,0x56,0xC7,0x32, +0x73,0x43,0x85,0xB0,0x9A,0xBC,0xB9,0xC9,0xE6,0x84,0xFB,0x33,0xE1,0xDB,0x3E,0x30,0xAC,0x73,0xE8,0x0C, +0x5C,0x39,0x9A,0xF1,0xA8,0x1A,0x85,0xF9,0xF0,0x13,0xCB,0x07,0x3E,0x2B,0x46,0xF7,0x35,0x60,0x4C,0x0B, +0x70,0x4C,0x27,0xF9,0x90,0x50,0x52,0xD0,0x29,0x80,0xC5,0x67,0x92,0xE4,0xA3,0x64,0x56,0x8C,0x66,0xF8, +0xBE,0xC4,0x8B,0x0B,0x68,0x80,0x75,0x57,0x5D,0xDF,0x86,0xB3,0xCC,0x07,0xDD,0x4A,0xFC,0xE0,0xBF,0x13, +0x3F,0xA1,0xD3,0x42,0x98,0xA4,0x18,0x4D,0x49,0x21,0xCA,0x38,0x4A,0xBE,0xC8,0x08,0xFB,0xB7,0x7D,0xC1, +0xF1,0xC9,0x9B,0x93,0xE1,0x49,0xBD,0x44,0xAC,0xBF,0x22,0xF0,0xBF,0x6A,0xD3,0xB9,0xE9,0x1A,0x49,0xDD, +0x53,0x60,0xE6,0x8B,0xCF,0xB3,0x38,0x90,0x45,0x1F,0x04,0x7C,0x23,0x01,0xEA,0xBA,0x69,0x36,0x1E,0x1A, +0xD2,0xC6,0x03,0x46,0x15,0xE8,0xF3,0x97,0x01,0xD0,0xD3,0xE6,0x66,0x8D,0x11,0xB9,0x5E,0x3D,0x7E,0x50, +0x4B,0x57,0x75,0x9A,0x74,0x36,0xF4,0x54,0x41,0x83,0xCC,0xB2,0x65,0x20,0x1E,0xCD,0x1D,0xDD,0x12,0xDD, +0x03,0xD9,0xF7,0xA1,0x6D,0x68,0x99,0xAA,0xE1,0xF7,0x3C,0x8F,0x5E,0xFB,0x37,0xB2,0x69,0xDC,0xDC,0x44, +0xCD,0xA2,0xC7,0x70,0x2C,0x09,0x14,0x07,0xCA,0x91,0x6C,0x57,0x41,0x16,0x60,0xCB,0xB1,0x5E,0x0D,0xCE, +0xCF,0xEC,0x04,0xA5,0xE0,0x71,0xD4,0xAC,0x07,0x89,0x50,0x09,0xD8,0xD4,0xF6,0x8B,0x93,0x5A,0x35,0x2E, +0xBF,0x17,0x72,0xF9,0xD2,0x4A,0x0D,0x41,0x4E,0xF5,0xB9,0x22,0x87,0xE7,0x0F,0x78,0x90,0x7A,0x92,0x22, +0x0D,0x55,0x51,0x24,0xA9,0x07,0x71,0x7E,0x97,0xAD,0xEF,0x41,0x2D,0x3E,0x23,0xAC,0xDE,0x85,0x34,0x5C, +0xFE,0x6F,0xDE,0xD8,0xB2,0x18,0x29,0x72,0xAB,0x05,0xB5,0xFA,0xF6,0x4F,0x5D,0x8E,0x6C,0x98,0x16,0x55, +0x84,0xAC,0xCC,0x51,0x87,0xCC,0x42,0xA8,0x6E,0xD1,0x7F,0xEA,0x21,0xB4,0xF0,0x10,0xFA,0x38,0x40,0xE0, +0xFB,0x86,0xB7,0x97,0xA7,0xF4,0xC6,0xC0,0xD9,0x6D,0xAF,0x8C,0x22,0x00,0x91,0x31,0xA4,0x01,0xF8,0xC4, +0xE4,0xFA,0x27,0x74,0x87,0xD4,0xFB,0x5D,0x05,0x5D,0x1F,0x2A,0xE4,0x76,0xFF,0x37,0x18,0x95,0x3B,0x9B, +0x81,0x88,0xC1,0xF0,0x71,0x3C,0xE1,0x8D,0xF0,0x54,0xC5,0xAC,0x7A,0x74,0x02,0x77,0xCD,0xBD,0x59,0xE3, +0x35,0xFD,0xD6,0x5C,0x0F,0x0C,0xF2,0x49,0xDF,0xAB,0x05,0x22,0x85,0x51,0xB7,0x9E,0xF5,0xED,0x4A,0xB3, +0xA1,0x59,0x9F,0xFE,0xA5,0xFF,0xE1,0x03,0x66,0xB3,0xA2,0x75,0x07,0x37,0xAF,0xCD,0x74,0x5D,0x64,0x2B, +0x3F,0xC4,0x28,0x1D,0x88,0x2E,0x51,0x65,0x88,0xA5,0xBA,0x40,0x4F,0xBA,0xAE,0x01,0x1A,0xEB,0xC8,0x87, +0x62,0x5B,0xE8,0x01,0x10,0x4A,0x28,0x05,0x28,0xF5,0x62,0xA0,0x59,0x5B,0x44,0xB0,0x88,0xA0,0xE1,0x89, +0x69,0x7C,0x8B,0x48,0x7D,0x3B,0x01,0x08,0xC9,0xBF,0x4F,0x86,0xBE,0xCE,0xCA,0x2F,0x42,0x12,0xAA,0x20, +0xEA,0xFA,0xCD,0xFC,0x2D,0xAC,0x7A,0x86,0xC0,0x85,0xDF,0xE4,0x06,0xB2,0x21,0xD1,0x98,0x28,0x08,0x06, +0x98,0x31,0xC9,0xB8,0x10,0xEC,0x6D,0x1C,0x80,0x5C,0x80,0xD6,0x89,0x60,0x24,0x0E,0x02,0x11,0x05,0x60, +0x38,0xC3,0x51,0x0E,0xE1,0x30,0x14,0x20,0x24,0x40,0x5F,0x4B,0x5D,0x0D,0x64,0xE1,0x45,0xE8,0xD4,0xEB, +0x76,0x1C,0xEB,0x31,0xD9,0x11,0xC3,0x83,0x78,0xC2,0x87,0x68,0xCC,0x8C,0x0D,0xC7,0x5C,0xB3,0x03,0x40, +0x03,0x08,0x27,0xC6,0x96,0xB9,0x1E,0xFD,0x43,0x9C,0xDE,0xE2,0xD4,0xD8,0xE8,0xE6,0xFC,0x9C,0x42,0xC1, +0x14,0xC2,0x7F,0xDE,0x07,0xB5,0xDF,0xE1,0x37,0x84,0xE2,0x9C,0x32,0x03,0xE4,0x59,0x3C,0xBF,0x48,0x09, +0xE5,0x6F,0x65,0x5F,0x98,0x63,0xF9,0xEA,0xB9,0x42,0x86,0xA0,0xE2,0x1D,0x63,0x21,0xA2,0x99,0xDB,0x78, +0xCD,0xB0,0xC6,0x70,0x5F,0x10,0x5C,0xDD,0xC5,0x9C,0x50,0x57,0x3F,0xE2,0x69,0xD8,0x1E,0xE8,0x56,0x84, +0x7C,0x98,0xA8,0x3D,0x30,0x5F,0x5A,0xC2,0x6B,0xDD,0x7A,0x34,0xD9,0xA8,0x26,0x55,0x01,0xBD,0xF6,0xA9, +0xA7,0x7A,0xB9,0x10,0xC0,0xC3,0x30,0x1E,0x1B,0xE2,0x75,0x7A,0x21,0x3C,0xDE,0xA5,0x4B,0x53,0xA4,0xA7, +0x2F,0xBF,0xCA,0xF8,0x10,0x76,0xB9,0x85,0x6B,0x8F,0x4A,0x2D,0x5D,0x17,0x6F,0x35,0x80,0x87,0x82,0x73, +0x1A,0x3E,0xB8,0x90,0x16,0xFF,0x42,0xEA,0x8C,0x06,0xF1,0x97,0xA4,0xFE,0xB8,0x22,0xF5,0xC7,0x75,0x52, +0xE3,0xE6,0x6D,0xC1,0x64,0x04,0x64,0xDF,0x22,0x8A,0xA6,0x38,0x85,0x05,0x71,0x08,0x5C,0xC0,0x3F,0xE3, +0x2C,0xC5,0x5F,0xE6,0x6C,0x30,0x23,0x13,0xBE,0xCA,0x9F,0x5A,0xFD,0x77,0x5C,0xA6,0xF8,0x09,0x2E,0x8B, +0x02,0xB3,0xCC,0x1B,0x7F,0xFD,0x54,0x22,0x9D,0xDA,0x83,0x2B,0xAC,0xBB,0xEB,0xBF,0xF0,0xBB,0xEA,0xC4, +0x2F,0xA7,0x4F,0xF1,0xE1,0xE2,0xA5,0x15,0x08,0x9B,0x68,0x96,0xA5,0x31,0x3D,0x84,0x0A,0xFE,0x0D,0x88, +0x60,0x28,0x73,0xC4,0xDE,0x62,0x69,0x71,0xCF,0x00,0x55,0x42,0x17,0x0C,0xC2,0xF9,0xB2,0xAE,0xB5,0x67, +0x90,0x22,0x41,0x09,0xC0,0x24,0x24,0xDA,0xCE,0xF5,0xC1,0xE6,0x4D,0x0B,0x32,0x94,0x07,0x1F,0xA6,0x07, +0x83,0xCD,0x9B,0xEF,0xCC,0xCE,0x94,0xD4,0x6A,0x22,0x99,0xEB,0x40,0xAF,0xD7,0xF4,0xC6,0x43,0x4B,0x08, +0x61,0xF5,0x5C,0x58,0x46,0x56,0x0B,0xCB,0x57,0x2F,0xF8,0x08,0x11,0x9D,0xC2,0x87,0x8C,0x1D,0x10,0x9E, +0xD6,0x7C,0xBF,0xA2,0x67,0x6A,0x04,0x58,0xB5,0x87,0x2A,0x9D,0xC3,0x4F,0x5D,0xB4,0x57,0xBC,0x16,0x0C, +0x15,0x59,0x88,0x7B,0x6A,0x50,0x8F,0xB1,0x22,0x49,0x17,0x97,0x96,0x83,0xCD,0xA5,0x30,0x75,0x3C,0x21, +0x14,0x07,0x7A,0x99,0x57,0x7F,0x7E,0xFB,0xE6,0x94,0xF3,0xE4,0x52,0x69,0x16,0x68,0x35,0x17,0xAA,0x0B, +0x37,0x17,0x3C,0x7D,0x28,0x2A,0x34,0xE1,0xB0,0x2A,0xE4,0xFC,0x7C,0x3E,0xFE,0x84,0x7D,0xC8,0x47,0x6F, +0x19,0x24,0xB3,0x2D,0x5B,0xA0,0x0F,0x87,0x17,0xF6,0xAE,0xED,0x40,0xC9,0xE0,0x23,0x48,0xD9,0xE2,0xE6, +0x96,0xFF,0x08,0x79,0xFB,0x9F,0x21,0x13,0x88,0xBB,0x0C,0x02,0x6B,0x81,0xDF,0xC4,0x9D,0xA5,0xF1,0x5C, +0xA2,0x9D,0xA4,0xA9,0xB8,0x94,0xE1,0x8C,0x30,0x6D,0x0C,0x8B,0x0C,0xA7,0x5A,0x10,0x63,0xA6,0xD1,0x98, +0x6B,0x2C,0x4B,0x92,0x38,0xE5,0x2B,0xFA,0xB0,0xF5,0xE2,0xC1,0xE6,0x5D,0x86,0x33,0x1C,0xE4,0xCB,0x38, +0xAD,0xEB,0x45,0x16,0x57,0xB0,0x0E,0x66,0x7F,0x7D,0x93,0x97,0x5A,0x19,0xA5,0x22,0x0F,0x6C,0x74,0xD5, +0x1C,0xA4,0x9B,0x01,0x55,0x8F,0x66,0x61,0xB8,0xEC,0xAD,0xD0,0x82,0x8E,0x2B,0xE6,0xB1,0xFC,0x8A,0x62, +0xF1,0x5B,0x6E,0xE2,0xEE,0xCA,0x8B,0x6A,0x93,0xAA,0x63,0x6D,0x18,0x1B,0x58,0x23,0x94,0x71,0x44,0x7D, +0x71,0x8D,0x4A,0x17,0x66,0x51,0x66,0x89,0xED,0x3D,0xE1,0x9F,0xD2,0x96,0x9E,0xCC,0xED,0x52,0x32,0xEA, +0xE9,0xBA,0xA8,0xB8,0xB0,0x28,0x5C,0x51,0xC4,0x6A,0x64,0xCB,0x88,0x6D,0x52,0xAF,0x00,0xF7,0xE4,0x3B, +0x78,0x73,0xFF,0x2A,0x1B,0x45,0x99,0x8D,0x00,0xA6,0x15,0xFB,0x4C,0xDA,0xF2,0x74,0x99,0xA9,0x0F,0xA4, +0xEB,0x4A,0x03,0x8E,0x30,0x9F,0xC5,0xC1,0x81,0x7E,0xA0,0xBB,0x3A,0xFC,0xDB,0xD4,0x2D,0xD8,0x85,0xA9, +0x0F,0xEE,0x3F,0xBA,0x7C,0x09,0x21,0x2D,0x89,0x29,0xA6,0xDC,0x40,0x10,0xD9,0x3D,0xBD,0xB5,0x06,0x52, +0x90,0xBF,0x46,0x37,0x66,0xAF,0xA9,0x6C,0x3C,0x5F,0xB9,0xCE,0xC6,0x65,0xD8,0x31,0x15,0x51,0xEE,0x01, +0x98,0xE7,0xF8,0xD1,0x3B,0xB6,0x45,0x1F,0xB7,0x23,0xE6,0x62,0x47,0xF0,0x2C,0xB1,0x06,0x80,0x25,0x5C, +0xAF,0x52,0xF2,0x53,0x25,0x16,0xB5,0x7D,0x14,0x86,0xE2,0xEB,0x77,0xE0,0x55,0x1C,0x96,0x31,0x4B,0x10, +0x61,0x20,0x00,0xC3,0x43,0x7C,0x0F,0x2E,0x2D,0xEB,0x24,0x65,0x43,0x79,0x5F,0x02,0xA4,0x79,0xCD,0x8C, +0x4C,0xAB,0x9C,0x6D,0x6E,0x72,0xBB,0x30,0x13,0xA3,0x40,0x62,0x22,0xE8,0x1B,0xA6,0xE8,0x39,0x8C,0xBA, +0x90,0x22,0x87,0x3E,0xD2,0xB6,0xD1,0x54,0x43,0x82,0xA9,0x51,0xC0,0x80,0xB3,0x2C,0x0D,0x21,0x52,0x8B, +0x2A,0xA2,0xB1,0x8D,0x61,0x1A,0xC0,0x01,0xEE,0x5F,0x22,0x4B,0x54,0x5A,0xB7,0x8A,0x01,0x4F,0x15,0xDF, +0x4D,0x7A,0x3C,0xBF,0x95,0x53,0x2C,0x23,0x5F,0xF3,0x77,0x0F,0x2D,0x1D,0x25,0x49,0x48,0x54,0x60,0xEE, +0xC0,0xC3,0xF7,0x7C,0xDE,0x06,0xB3,0x8A,0xDA,0x70,0x82,0xB2,0x82,0x40,0x5F,0xC3,0xA1,0x6A,0xBB,0x2C, +0xF1,0x60,0xE1,0xAE,0xB8,0x68,0xA5,0x3F,0x63,0xC5,0x47,0x9B,0x74,0x9A,0x7C,0xD6,0x6E,0x7B,0x6F,0x67, +0x05,0x84,0xC6,0xE2,0x7B,0x76,0xC8,0x35,0x90,0x8E,0xCA,0xD3,0x8A,0x0E,0xA8,0x1E,0x17,0xEC,0x24,0x63, +0x33,0x63,0x01,0xAC,0xBB,0xDC,0x52,0xBA,0x72,0xB1,0xA5,0xEC,0xD6,0xA5,0x56,0x61,0x1F,0x2E,0xA4,0x90, +0x46,0xFC,0xF8,0xE3,0x0F,0x39,0xAB,0x6E,0x1B,0x66,0x2B,0x17,0xBE,0x54,0x6F,0xAC,0x45,0x66,0x14,0x46, +0xBF,0x1A,0xAB,0xF6,0x3A,0xAA,0xB1,0x29,0x7E,0x41,0x41,0x23,0x81,0x27,0x92,0xAC,0x9E,0x7F,0x05,0x01, +0xC3,0x09,0xC4,0x25,0x1B,0x3A,0xA1,0xF2,0xB7,0x3B,0xF5,0xFC,0xD7,0x3B,0x57,0x71,0xF7,0xCB,0xD6,0xCC, +0xF3,0xCA,0xBA,0x5A,0x45,0x1D,0xB5,0xC1,0x7B,0xE2,0xD7,0x16,0x74,0x05,0x86,0xCE,0x55,0x0D,0xEC,0xF2, +0x6C,0x71,0xAE,0x95,0x2F,0x22,0xF6,0x40,0x7D,0x11,0x35,0x4B,0x2A,0x33,0x50,0x7F,0xA3,0x9B,0x55,0x3B, +0xCD,0x65,0xC5,0x99,0x78,0x9E,0xD3,0xE2,0xFC,0x2D,0xBB,0x9E,0xEB,0x81,0x7D,0x68,0x96,0x85,0xB8,0x85, +0x8B,0x6A,0xB2,0x5B,0x2E,0xA7,0x20,0x1E,0x6C,0xA8,0x76,0x65,0xC9,0x7A,0x80,0x4A,0xBF,0xAB,0x8B,0x2A, +0xBB,0xAF,0x2E,0x17,0x1D,0x57,0xF9,0xB5,0x4D,0xED,0x37,0x4E,0x2A,0x1A,0x44,0x3E,0xC8,0xCB,0xFD,0xCD, +0x37,0xFA,0x27,0xD1,0x14,0xC6,0xFE,0x9F,0xFB,0x0C,0xD2,0xB3,0xD2,0x2B,0x00,0x00 }; From 902077553f42c4980976c4053e8478f2bd5558f4 Mon Sep 17 00:00:00 2001 From: lorol Date: Tue, 28 Apr 2020 16:36:40 -0400 Subject: [PATCH 052/551] Applied memory optimizations from sascha432 Updated my additions --- README.md | 2 +- examples/SmartSwitch/PinOut_Notes.txt | 69 +- examples/SmartSwitch/README.md | 33 +- examples/SmartSwitch/SmartSwitch.ino | 1027 +++++++++--------- examples/SmartSwitch/data/ace.ico.gz | Bin 0 -> 6307 bytes examples/SmartSwitch/data/acefull.js.gz | Bin 116605 -> 116948 bytes examples/SmartSwitch/data/index.htm | 80 +- examples/SmartSwitch/data/index.min.htm.gz | Bin 3168 -> 4193 bytes extras/Readme | 51 +- extras/do.bat | 2 +- extras/ehg.c | 16 +- extras/ehg.exe | Bin 3584 -> 4096 bytes extras/rehg.c | 4 +- extras/rehg.exe | Bin 2560 -> 2560 bytes extras/update_ace.bat | 4 +- library.json | 2 +- library.properties | 4 +- src/AsyncEventSource.cpp | 53 +- src/AsyncWebSocket.cpp | 163 ++- src/ESPAsyncWebServer.h | 39 +- src/WebAuthentication.cpp | 62 +- src/WebAuthentication.h | 2 +- src/WebHandlers.cpp | 50 +- src/WebRequest.cpp | 237 ++--- src/WebResponses.cpp | 181 ++-- src/WebServer.cpp | 13 +- src/edit.htm | 1103 ++++++++++---------- src/edit.htm.gz.h | 439 ++++---- 28 files changed, 1853 insertions(+), 1783 deletions(-) create mode 100644 examples/SmartSwitch/data/ace.ico.gz diff --git a/README.md b/README.md index d6dd3206a..5cc2fc0c2 100644 --- a/README.md +++ b/README.md @@ -1509,7 +1509,7 @@ For Arduino IDE create/update `platform.local.txt`: Add/Update the following line: ``` - compiler.cpp.extra_flags=-DDASYNCWEBSERVER_REGEX + compiler.cpp.extra_flags=-DASYNCWEBSERVER_REGEX ``` For platformio modify `platformio.ini`: diff --git a/examples/SmartSwitch/PinOut_Notes.txt b/examples/SmartSwitch/PinOut_Notes.txt index c8c2a50a9..2634a19d6 100644 --- a/examples/SmartSwitch/PinOut_Notes.txt +++ b/examples/SmartSwitch/PinOut_Notes.txt @@ -1,13 +1,56 @@ -ESP12 - -static const uint8_t D0 = 16; -static const uint8_t D1 = 5; -static const uint8_t D2 = 4; // DHT DATA I/O -static const uint8_t D3 = 0; // BUTTON - most modules have it populated on PCB -static const uint8_t D4 = 2; // LED (RELAY) - most modules have it populated on PCB -static const uint8_t D5 = 14; -static const uint8_t D6 = 12; -static const uint8_t D7 = 13; -static const uint8_t D8 = 15; -static const uint8_t D9 = 3; -static const uint8_t D10 = 1; \ No newline at end of file +This application: +D2 = 4; // DHT DATA I/O +D3 = 0; // BUTTON - most modules have it populated on PCB +D4 = 2; // LED (RELAY) - most modules have it populated on PCB + + + +Pinout ESP12 (8266) +D GPIO In Out Notes + +D0 16 no interrupt no PWM or I2C support HIGH at boot used to wake up from deep sleep +D1 5 OK OK often used as SCL (I2C) +D2 4 OK OK often used as SDA (I2C) +D3 0 PU OK pulled up connected to FLASH button, boot fails if pulled LOW +D4 2 PU OK pulled up HIGH at boot connected to on-board LED, boot fails if pulled LOW +D5 14 OK OK SPI (SCLK) +D6 12 OK OK SPI (MISO) +D7 13 OK OK SPI (MOSI) +D8 15 pulled to GND OK SPI (CS) Boot fails if pulled HIGH +RX 3 OK RX pin HIGH at boot +TX 1 TX pin OK HIGH at boot debug output at boot, boot fails if pulled LOW +A0 ADC0 Analog Input + + +Pinout ESP32 +IO In Out Notes + +0 PU OK pulled-up input, outputs PWM signal at boot +1 TX OK debug output at boot +2 OK OK connected to on-board LED +3 OK RX pin HIGH at boot +4 OK OK +5 OK OK outputs PWM signal at boot + +6-11 x x connected to the integrated SPI flash + +12 OK OK boot fail if pulled high +13 OK OK +14 OK OK outputs PWM signal at boot +15 OK OK outputs PWM signal at boot +16 OK OK +17 OK OK +18 OK OK +19 OK OK +21 OK OK +22 OK OK +23 OK OK +25 OK OK +26 OK OK +27 OK OK +32 OK OK +33 OK OK +34 OK input only +35 OK input only +36 OK input only +39 OK input only \ No newline at end of file diff --git a/examples/SmartSwitch/README.md b/examples/SmartSwitch/README.md index 1d5171a86..fd8cd4061 100644 --- a/examples/SmartSwitch/README.md +++ b/examples/SmartSwitch/README.md @@ -1,16 +1,17 @@ -![](1.PNG) ![](2.PNG) -## -![](3.PNG) ![](4.PNG) - -## SmartSwitch -* Remote Temperature Control application with schedule (example car block heater or battery charger) -* Based on ESP_AsyncFSBrowser example -* Wide browser compatibility, no extra server-side needed. -* HTTP server and WebSocket, single port -* Standalone, no JS dependencies for the browser from Internet (I hope), ace editor included -* Added ESPAsyncWiFiManager -* Real Time (NTP) w/ Time Zones -* Memorized settings to EEPROM -* Multiple clients can be connected at same time, they see each other' requests -* Default credentials smart:switch -* Use latest ESP8266 core lib (from Github) +![](1.PNG) ![](2.PNG) +## +![](3.PNG) ![](4.PNG) + +## SmartSwitch +* Remote Temperature Control application with schedule (example car block heater or battery charger) +* Based on ESP_AsyncFSBrowser example +* Wide browser compatibility, no extra server-side needed +* HTTP server and WebSocket, single port +* Standalone, no JS dependencies for the browser from Internet (I hope), ace editor included +* Added ESPAsyncWiFiManager +* Fallback to an own WIFI_AP, no Internet to sync but by a browser the clock can be set once +* Real Time (NTP) w/ Time Zones +* Memorized settings to EEPROM +* Multiple clients can be connected at same time, they see each other' requests +* Default credentials smart:switch +* Use latest ESP8266 or ESP32 core(from GitHub) diff --git a/examples/SmartSwitch/SmartSwitch.ino b/examples/SmartSwitch/SmartSwitch.ino index 90aca0302..3dbc61b8e 100644 --- a/examples/SmartSwitch/SmartSwitch.ino +++ b/examples/SmartSwitch/SmartSwitch.ino @@ -1,498 +1,529 @@ -/* -SmartSwitch application -Based on ESP_AsyncFSBrowser -Temperature Control for heater with schedule -Main purpose - for winter outside car block heater or battery charger -Wide browser compatibility, no other server-side needed. -HTTP server and WebSocket, single port -Standalone, no JS dependencies for the browser from Internet (I hope) -Based on ESP_AsyncFSBrowser -Real Time (NTP) w/ Time Zones -Memorized settings to EEPROM -Multiple clients can be connected at same time, they see each other requests -Use latest ESP core lib (from Github) -*/ - -#define USE_WFM // to use ESPAsyncWiFiManager -//#define DEL_WFM // delete Wifi credentials stored - //(use once then comment and flash again), also HTTP /erase-wifi can do the same live - -#define USE_AUTH // .setAuthentication for all static - -#include -#ifdef ESP32 - #include - #include - #include - #include - #include -#elif defined(ESP8266) - #include - #include - #include -#endif -#include -#ifdef USE_WFM - #include "ESPAsyncWiFiManager.h" -#endif -#include -#include -#include -#include -#include -#define MYTZ TZ_America_Toronto -#define RTC_UTC_TEST 1577836800 // Some Date - -#define EESC 100 // fixed eeprom address for sched choice -#define EECH 104 // fixed eeprom address to keep selected active channel, only for reference here -#define EEBEGIN EECH + 1 -#define EEMARK 0x5A -#define MEMMAX 2 // 0,1,2... last max index (only 3 channels) -#define EEALL 512 - -#define HYST 0.5 // C +/- hysteresis - -// DHT -#define DHTTYPE DHT22 // DHT 11 // DHT 22, AM2302, AM2321 // DHT 21, AM2301 -#define DHTPIN 4 //D2 - -DHT dht(DHTPIN, DHTTYPE); - -// SKETCH BEGIN MAIN DECLARATIONS -Ticker tim; -AsyncWebServer server(80); //single port - easy for forwarding -AsyncWebSocket ws("/ws"); - -#ifdef USE_WFM - #ifdef USE_EADNS - AsyncDNSServer dns; - #else - DNSServer dns; - #endif -#else - const char* ssid = "MYSSD"; - const char* password = "MYPASSWD"; -#endif -const char * hostName = "smartsw"; -const char* http_username = "smart"; // for SPIFFSEditor (and static html) -const char* http_password = "switch"; - -// RTC -static timeval tv; -static time_t now; - -// HW I/O -const int btnPin = 0; //D3 -const int ledPin = 2; //D4 -int btnState = HIGH; - -// Globals -uint8_t count = 0; -uint8_t sched = 0; // automatic schedule -byte memch = 0; // select memory "channel" to work with -float t = 0; -float h = 0; -bool udht = false; -bool heat_enabled_prev = false; -int ledState; - -struct EE_bl { - byte memid; //here goes the EEMARK stamp - uint8_t hstart; - uint8_t mstart; - uint8_t hstop; - uint8_t mstop; - float tempe; -}; - -EE_bl ee = {0,0,0,0,0,0.1}; //populate as initial - -// SUBS -void writeEE() { - ee.memid = EEMARK; - //EEPROM.put(EESC, sched); // only separately when needed with commit() - //EEPROM.put(EECH, memch); // not need to store and retrieve memch - EEPROM.put(EEBEGIN + memch*sizeof(ee), ee); - EEPROM.commit(); //needed for ESP8266? -} - -void readEE() { - byte ChkEE; - if (memch > MEMMAX) memch = 0; - EEPROM.get(EEBEGIN + memch*sizeof(ee), ChkEE); - if (ChkEE == EEMARK){ //otherwise stays with defaults - EEPROM.get(EEBEGIN + memch*sizeof(ee), ee); - EEPROM.get(EESC, sched); - if (sched > MEMMAX + 1) sched = 0; - } -} - -void showTime() -{ - byte tmpch = 0; - bool heat_enabled = false; - - gettimeofday(&tv, nullptr); - now = time(nullptr); - const tm* tm = localtime(&now); - ws.printfAll("Now,Clock,%02d:%02d,%d", tm->tm_hour, tm->tm_min, tm->tm_wday); - if ((2==tm->tm_hour )&&(2==tm->tm_min)) { - configTime(MYTZ, "pool.ntp.org"); - Serial.print(F("Sync Clock at 02:02\n")); - } - Serial.printf("RTC: %02d:%02d\n", tm->tm_hour, tm->tm_min); - - if (sched == 0) { // automatic - if ((tm->tm_wday > 0)&&(tm->tm_wday < 6)) tmpch = 0; //Mon - Fri - else if (tm->tm_wday == 6) tmpch = 1; //Sat - else if (tm->tm_wday == 0) tmpch = 2; //Sun - } else { // manual - tmpch = sched - 1; //and stays - } - - if (tmpch != memch) { // update if different - memch = tmpch; - readEE(); - ws.printfAll("Now,Setting,%02d:%02d,%02d:%02d,%+2.1f", ee.hstart, ee.mstart, ee.hstop, ee.mstop, ee.tempe); - } - - // process smart switch by time and temperature - uint16_t xmi = (uint16_t)(60*tm->tm_hour) + tm->tm_min; // max 24h = 1440min, current time - uint16_t bmi = (uint16_t)(60*ee.hstart) + ee.mstart; // begin in minutes - uint16_t emi = (uint16_t)(60*ee.hstop) + ee.mstop; // end in minutes - - if (bmi == emi) heat_enabled = false; - else { //enable smart if different - - if (((bmi < emi)&&(bmi <= xmi)&&(xmi < emi))|| - ((emi < bmi)&&((bmi <= xmi)||(xmi < emi)))) { - heat_enabled = true; - } else heat_enabled = false; - } - - if (heat_enabled_prev) { // smart control (delayed one cycle) - if (((t - HYST) < ee.tempe)&&(ledState == HIGH)) { // OFF->ON once - ledState = LOW; - digitalWrite(ledPin, ledState); // apply change - ws.textAll("led,ledon"); - } - if ((((t + HYST) > ee.tempe)&&(ledState == LOW))||(!heat_enabled)) { // ON->OFF once, also turn off at end of period. - ledState = HIGH; - digitalWrite(ledPin, ledState); // apply change - ws.textAll("led,ledoff"); - } - Serial.printf(ledState ? "LED OFF" : "LED ON"); - Serial.print(F(", Smart enabled\n")); - } - heat_enabled_prev = heat_enabled; //update -} - -void updateDHT(){ - h = dht.readHumidity(); - t = dht.readTemperature(); //Celsius or dht.readTemperature(true) for Fahrenheit - if (isnan(h) || isnan(t)) { - Serial.print(F("Failed to read from DHT sensor!")); - h = 0; // debug w/o sensor - t = 0; - } -} - -void analogSample() -{ - ws.printfAll("wpMeter,Arduino,%+2.1f,%2.1f,%d", t, h, heat_enabled_prev); - Serial.printf("T/H.: %+2.1f°C/%2.1f%%,%d\n", t, h, heat_enabled_prev); -} - -void checkPhysicalButton() -{ - if (digitalRead(btnPin) == LOW) { - if (btnState != LOW) { // btnState is used to avoid sequential toggles - ledState = !ledState; - digitalWrite(ledPin, ledState); - if (ledState) ws.textAll("led,ledoff"); - else ws.textAll("led,ledon"); - } - btnState = LOW; - } else { - btnState = HIGH; - } -} - -void mytimer() { - ++count; //200ms increments - checkPhysicalButton(); - if ((count % 25) == 1) { // update temp every 5 seconds - analogSample(); - udht = true; - } - if ((count % 50) == 0) { // update temp every 10 seconds - ws.cleanupClients(); - } - if (count >= 150) { // cycle every 30 sec - showTime(); - count = 0; - } -} - -// server -void onWsEvent(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventType type, void * arg, uint8_t *data, size_t len){ - if(type == WS_EVT_CONNECT){ - Serial.printf("ws[%s][%u] connect\n", server->url(), client->id()); - //client->printf("Hello Client %u :)", client->id()); - //client->ping(); - - IPAddress ip = client->remoteIP(); - Serial.printf("[%u] Connected from %d.%d.%d.%d\n", client->id(), ip[0], ip[1], ip[2], ip[3]); - showTime(); - analogSample(); - if (ledState) ws.textAll("led,ledoff"); - else ws.textAll("led,ledon"); - - ws.printfAll("Now,Setting,%02d:%02d,%02d:%02d,%+2.1f", ee.hstart, ee.mstart, ee.hstop, ee.mstop, ee.tempe); - ws.printfAll("Now,sched,%d", sched); - - } else if(type == WS_EVT_DISCONNECT){ - Serial.printf("ws[%s][%u] disconnect\n", server->url(), client->id()); - ws.textAll("Now,remoff"); - - } else if(type == WS_EVT_ERROR){ - Serial.printf("ws[%s][%u] error(%u): %s\n", server->url(), client->id(), *((uint16_t*)arg), (char*)data); - } else if(type == WS_EVT_PONG){ - Serial.printf("ws[%s][%u] pong[%u]: %s\n", server->url(), client->id(), len, (len)?(char*)data:""); - } else if(type == WS_EVT_DATA){ - AwsFrameInfo * info = (AwsFrameInfo*)arg; - String msg = ""; - if(info->final && info->index == 0 && info->len == len){ - //the whole message is in a single frame and we got all of it's data - Serial.printf("ws[%s][%u] %s-message[%llu]: ", server->url(), client->id(), (info->opcode == WS_TEXT)?"text":"binary", info->len); - - if(info->opcode == WS_TEXT){ - for(size_t i=0; i < info->len; i++) { //debug - msg += (char) data[i]; - } - if(data[0] == 'L') { // LED - if(data[1] == '1') { - ledState = LOW; - ws.textAll("led,ledon"); // for others - } - else if(data[1] == '0') { - ledState = HIGH; - ws.textAll("led,ledoff"); - } - digitalWrite(ledPin, ledState); // apply change - - - } else if(data[0] == 'T') { // timeset - if (len > 11) { - data[3] = data[6] = data[9] = data[12] = 0; // cut strings - ee.hstart = (uint8_t) atoi((const char *) &data[1]); - ee.mstart = (uint8_t) atoi((const char *) &data[4]); - ee.hstop = (uint8_t) atoi((const char *) &data[7]); - ee.mstop = (uint8_t) atoi((const char *) &data[10]); - Serial.printf("[%u] Timer set %02d:%02d - %02d:%02d\n", client->id(), ee.hstart, ee.mstart, ee.hstop, ee.mstop); - writeEE(); - memch = 255; // to force showTime()to send Setting - showTime(); - } - } else if(data[0] == 'W') { // temperatureset - if (len > 3) { - if (ee.tempe != (float) atof((const char *) &data[1])){ - ee.tempe = (float) atof((const char *) &data[1]); - Serial.printf("[%u] Temp set %+2.1f\n", client->id(), ee.tempe); - writeEE(); - memch = 255; // to force showTime()to send Setting - showTime(); - } - } - } else if ((data[0] == 'Z')&&(len > 2)) { // sched - data[2] = 0; - if (sched != (uint8_t) atoi((const char *) &data[1])){ - sched = (uint8_t) atoi((const char *) &data[1]); - EEPROM.put(EESC, sched); //separately - EEPROM.commit(); //needed for ESP8266? - ws.printfAll("Now,sched,%d", sched); - showTime(); - } - } - - } else { - char buff[3]; - for(size_t i=0; i < info->len; i++) { - sprintf(buff, "%02x ", (uint8_t) data[i]); - msg += buff ; - } - } - Serial.printf("%s\n",msg.c_str()); - - if(info->opcode == WS_TEXT) - client->text("I got your text message"); - else - client->binary("I got your binary message"); - - } else { - //message is comprised of multiple frames or the frame is split into multiple packets - if(info->index == 0){ - if(info->num == 0) - Serial.printf("ws[%s][%u] %s-message start\n", server->url(), client->id(), (info->message_opcode == WS_TEXT)?"text":"binary"); - Serial.printf("ws[%s][%u] frame[%u] start[%llu]\n", server->url(), client->id(), info->num, info->len); - } - - Serial.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 < len; i++) { - msg += (char) data[i]; - } - } else { - char buff[3]; - for(size_t i=0; i < len; i++) { - sprintf(buff, "%02x ", (uint8_t) data[i]); - msg += buff ; - } - } - Serial.printf("%s\n",msg.c_str()); - - if((info->index + len) == info->len){ - Serial.printf("ws[%s][%u] frame[%u] end[%llu]\n", server->url(), client->id(), info->num, info->len); - if(info->final){ - Serial.printf("ws[%s][%u] %s-message end\n", server->url(), client->id(), (info->message_opcode == WS_TEXT)?"text":"binary"); - if(info->message_opcode == WS_TEXT) - client->text("I got your text message"); - else - client->binary("I got your binary message"); - } - } - } - } -} - - -// setup ----------------------------------- - -void setup(){ - Serial.begin(115200); - Serial.setDebugOutput(true); - -//Wifi -#ifdef USE_WFM - AsyncWiFiManager wifiManager(&server,&dns); - #ifdef DEL_WFM - wifiManager.resetSettings(); - #endif - wifiManager.autoConnect(hostName); -#else - //WiFi.mode(WIFI_AP_STA); // Core SVN 5179 use STA as default interface in mDNS (#7042) - //WiFi.softAP(hostName); // Core SVN 5179 use STA as default interface in mDNS (#7042) - WiFi.mode(WIFI_STA); // Core SVN 5179 use STA as default interface in mDNS (#7042) - WiFi.begin(ssid, password); - if (WiFi.waitForConnectResult() != WL_CONNECTED) { - Serial.print(F("STA: Failed!\n")); - WiFi.disconnect(false); - delay(1000); - WiFi.begin(ssid, password); - } -#endif - - Serial.print(F("*CONNECTED*\n")); - -//DHT - dht.begin(); - updateDHT(); //first reading takes time, hold here than the loop; - -//Real Time - time_t rtc = RTC_UTC_TEST; - timeval tv = { rtc, 0 }; - //timezone tz = { 0, 0 }; //(insert) <#5194 - settimeofday(&tv, nullptr); //settimeofday(&tv, &tz); // <#5194 - configTime(MYTZ, "pool.ntp.org"); - -//MDNS (not needed) - // MDNS.begin(hostName); - // MDNS.addService("http","tcp",80); // Core SVN 5179 use STA as default interface in mDNS (#7042) - -//I/O & DHT - pinMode(ledPin, OUTPUT); - pinMode(btnPin, INPUT_PULLUP); - -//EE - EEPROM.begin(EEALL); - //EEPROM.get(EECH, memch); //current channel, no need - readEE(); // populate structure if healthy - digitalWrite(ledPin, ledState); - Serial.printf("Timer set %02d:%02d - %02d:%02d\n", ee.hstart, ee.mstart, ee.hstop, ee.mstop); - Serial.printf("Temp set %+2.1f\n", ee.tempe); - -//SPIFFS - SPIFFS.begin(); - - ws.onEvent(onWsEvent); - server.addHandler(&ws); - -#ifdef ESP32 - server.addHandler(new SPIFFSEditor(SPIFFS, http_username,http_password)); -#elif defined(ESP8266) - server.addHandler(new SPIFFSEditor(http_username,http_password)); -#endif - - server.on("/free-ram", HTTP_GET, [](AsyncWebServerRequest *request){ // direct request->answer - request->send(200, "text/plain", String(ESP.getFreeHeap())); - }); - - server.on("/hw-reset", HTTP_GET, [](AsyncWebServerRequest *request){ - request->onDisconnect([]() { -#ifdef ESP32 - ESP.restart(); -#elif defined(ESP8266) - ESP.reset(); -#endif - }); - request->send(200, "text/plain","Restarting ..."); - }); - - server.on("/erase-wifi", HTTP_GET, [](AsyncWebServerRequest *request){ - request->onDisconnect([]() { - WiFi.disconnect(true); -#ifdef ESP32 - ESP.restart(); -#elif defined(ESP8266) - ESP.reset(); -#endif - }); - request->send(200, "text/plain","Erasing WiFi data ..."); - }); - -#ifdef USE_AUTH - server.serveStatic("/", SPIFFS, "/").setDefaultFile("index.htm").setAuthentication(http_username,http_password); -#else - server.serveStatic("/", SPIFFS, "/").setDefaultFile("index.htm"); -#endif - - server.onNotFound([](AsyncWebServerRequest *request){ // nothing known - Serial.print(F("NOT_FOUND: ")); - if (request->method() == HTTP_OPTIONS) request->send(200); //CORS - else request->send(404); - }); - - DefaultHeaders::Instance().addHeader("Access-Control-Allow-Origin", "*");//CORS - server.begin(); - - //Timer tick - tim.attach(0.2, mytimer); //every 0.2s - - //OTA - ArduinoOTA.setHostname(hostName); - ArduinoOTA.onStart([]() { - Serial.print(F("OTA Started ...\n")); - ws.textAll("Now,OTA"); // for all clients - }); - ArduinoOTA.begin(); -} // setup end - -// loop ----------------------------------- -void loop(){ - if (udht){ // 5sec - updateDHT(); - udht = false; - } - ArduinoOTA.handle(); -} +/* +SmartSwitch application +Based on ESP_AsyncFSBrowser +Temperature Control for heater with schedule +Main purpose - for winter outside car block heater or battery charger +Wide browser compatibility, no other server-side needed. +HTTP server and WebSocket, single port +Standalone, no JS dependencies for the browser from Internet (I hope) +Based on ESP_AsyncFSBrowser +Real Time (NTP) w/ Time Zones +Memorized settings to EEPROM +Multiple clients can be connected at same time, they see each other requests +Use latest ESP core lib (from Github) +*/ + +#define USE_WFM // to use ESPAsyncWiFiManager +//#define DEL_WFM // delete Wifi credentials stored + //(use once then comment and flash again), also HTTP /erase-wifi can do the same live + +#define USE_AUTH // .setAuthentication for all static + +#include +#ifdef ESP32 + #include + #include + #include + #include + #include +#elif defined(ESP8266) + #include + #include + #include +#endif +#include +#ifdef USE_WFM + #include "ESPAsyncWiFiManager.h" +#endif +#include +#include +#include +#include + +#define RTC_UTC_TEST 1577836800 // Some Date +#ifdef ESP32 + #define MYTZ -5*3600,3600 +#elif defined(ESP8266) + #include + #define MYTZ TZ_America_Toronto +#endif + +#define EESC 100 // fixed eeprom address for sched choice +#define EECH 104 // fixed eeprom address to keep selected active channel, only for reference here +#define EEBEGIN EECH + 1 +#define EEMARK 0x5A +#define MEMMAX 2 // 0,1,2... last max index (only 3 channels) +#define EEALL 512 + +#define HYST 0.5 // C +/- hysteresis + +// DHT +#define DHTTYPE DHT22 // DHT 11 // DHT 22, AM2302, AM2321 // DHT 21, AM2301 +#define DHTPIN 4 //D2 + +DHT dht(DHTPIN, DHTTYPE); + +// SKETCH BEGIN MAIN DECLARATIONS +Ticker tim; +AsyncWebServer server(80); //single port - easy for forwarding +AsyncWebSocket ws("/ws"); + +#ifdef USE_WFM + #ifdef USE_EADNS + AsyncDNSServer dns; + #else + DNSServer dns; + #endif + +//Fallback timeout in seconds allowed to config or it creates an own AP, then serves 192.168.4.1 + #define FBTO 120 + const char* fbssid = "FBSSW"; + const char* fbpassword = "FBpassword4"; + +#else + const char* ssid = "MYROUTERSSD"; + const char* password = "MYROUTERPASSWD"; +#endif +const char* hostName = "smartsw"; +const char* http_username = "smart"; // for SPIFFSEditor (and static html) +const char* http_password = "switch"; + +// RTC +static timeval tv; +static time_t now; + +// HW I/O +const int btnPin = 0; //D3 +const int ledPin = 2; //D4 +int btnState = HIGH; + +// Globals +uint8_t count = 0; +uint8_t sched = 0; // automatic schedule +byte memch = 0; // select memory "channel" to work with +float t = 0; +float h = 0; +bool udht = false; +bool heat_enabled_prev = false; +int ledState; + +struct EE_bl { + byte memid; //here goes the EEMARK stamp + uint8_t hstart; + uint8_t mstart; + uint8_t hstop; + uint8_t mstop; + float tempe; +}; + +EE_bl ee = {0,0,0,0,0,0.1}; //populate as initial + +// SUBS +void writeEE() { + ee.memid = EEMARK; + //EEPROM.put(EESC, sched); // only separately when needed with commit() + //EEPROM.put(EECH, memch); // not need to store and retrieve memch + EEPROM.put(EEBEGIN + memch*sizeof(ee), ee); + EEPROM.commit(); //needed for ESP8266? +} + +void readEE() { + byte ChkEE; + if (memch > MEMMAX) memch = 0; + EEPROM.get(EEBEGIN + memch*sizeof(ee), ChkEE); + if (ChkEE == EEMARK){ //otherwise stays with defaults + EEPROM.get(EEBEGIN + memch*sizeof(ee), ee); + EEPROM.get(EESC, sched); + if (sched > MEMMAX + 1) sched = 0; + } +} + +void showTime() +{ + byte tmpch = 0; + bool heat_enabled = false; + + gettimeofday(&tv, nullptr); + now = time(nullptr); + const tm* tm = localtime(&now); + ws.printfAll("Now,Clock,%02d:%02d,%d", tm->tm_hour, tm->tm_min, tm->tm_wday); + if ((2==tm->tm_hour )&&(2==tm->tm_min)) { + configTime(MYTZ, "pool.ntp.org"); + Serial.print(F("Sync Clock at 02:02\n")); + } + Serial.printf("RTC: %02d:%02d\n", tm->tm_hour, tm->tm_min); + + if (sched == 0) { // automatic + if ((tm->tm_wday > 0)&&(tm->tm_wday < 6)) tmpch = 0; //Mon - Fri + else if (tm->tm_wday == 6) tmpch = 1; //Sat + else if (tm->tm_wday == 0) tmpch = 2; //Sun + } else { // manual + tmpch = sched - 1; //and stays + } + + if (tmpch != memch) { // update if different + memch = tmpch; + readEE(); + ws.printfAll("Now,Setting,%02d:%02d,%02d:%02d,%+2.1f", ee.hstart, ee.mstart, ee.hstop, ee.mstop, ee.tempe); + } + + // process smart switch by time and temperature + uint16_t xmi = (uint16_t)(60*tm->tm_hour) + tm->tm_min; // max 24h = 1440min, current time + uint16_t bmi = (uint16_t)(60*ee.hstart) + ee.mstart; // begin in minutes + uint16_t emi = (uint16_t)(60*ee.hstop) + ee.mstop; // end in minutes + + if (bmi == emi) heat_enabled = false; + else { //enable smart if different + + if (((bmi < emi)&&(bmi <= xmi)&&(xmi < emi))|| + ((emi < bmi)&&((bmi <= xmi)||(xmi < emi)))) { + heat_enabled = true; + } else heat_enabled = false; + } + + if (heat_enabled_prev) { // smart control (delayed one cycle) + if (((t - HYST) < ee.tempe)&&(ledState == HIGH)) { // OFF->ON once + ledState = LOW; + digitalWrite(ledPin, ledState); // apply change + ws.textAll("led,ledon"); + } + if ((((t + HYST) > ee.tempe)&&(ledState == LOW))||(!heat_enabled)) { // ON->OFF once, also turn off at end of period. + ledState = HIGH; + digitalWrite(ledPin, ledState); // apply change + ws.textAll("led,ledoff"); + } + Serial.printf(ledState ? "LED OFF" : "LED ON"); + Serial.print(F(", Smart enabled\n")); + } + heat_enabled_prev = heat_enabled; //update +} + +void updateDHT(){ + h = dht.readHumidity(); + t = dht.readTemperature(); //Celsius or dht.readTemperature(true) for Fahrenheit + if (isnan(h) || isnan(t)) { + Serial.print(F("Failed to read from DHT sensor!")); + h = 0; // debug w/o sensor + t = 0; + } +} + +void analogSample() +{ + ws.printfAll("wpMeter,Arduino,%+2.1f,%2.1f,%d", t, h, heat_enabled_prev); + Serial.printf("T/H.: %+2.1f°C/%2.1f%%,%d\n", t, h, heat_enabled_prev); +} + +void checkPhysicalButton() +{ + if (digitalRead(btnPin) == LOW) { + if (btnState != LOW) { // btnState is used to avoid sequential toggles + ledState = !ledState; + digitalWrite(ledPin, ledState); + if (ledState) ws.textAll("led,ledoff"); + else ws.textAll("led,ledon"); + } + btnState = LOW; + } else { + btnState = HIGH; + } +} + +void mytimer() { + ++count; //200ms increments + checkPhysicalButton(); + if ((count % 25) == 1) { // update temp every 5 seconds + analogSample(); + udht = true; + } + if ((count % 50) == 0) { // update temp every 10 seconds + ws.cleanupClients(); + } + if (count >= 150) { // cycle every 30 sec + showTime(); + count = 0; + } +} + +// server +void onWsEvent(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventType type, void * arg, uint8_t *data, size_t len){ + if(type == WS_EVT_CONNECT){ + Serial.printf("ws[%s][%u] connect\n", server->url(), client->id()); + //client->printf("Hello Client %u :)", client->id()); + //client->ping(); + + IPAddress ip = client->remoteIP(); + Serial.printf("[%u] Connected from %d.%d.%d.%d\n", client->id(), ip[0], ip[1], ip[2], ip[3]); + showTime(); + analogSample(); + if (ledState) ws.textAll("led,ledoff"); + else ws.textAll("led,ledon"); + + ws.printfAll("Now,Setting,%02d:%02d,%02d:%02d,%+2.1f", ee.hstart, ee.mstart, ee.hstop, ee.mstop, ee.tempe); + ws.printfAll("Now,sched,%d", sched); + + } else if(type == WS_EVT_DISCONNECT){ + Serial.printf("ws[%s][%u] disconnect\n", server->url(), client->id()); + ws.textAll("Now,remoff"); + + } else if(type == WS_EVT_ERROR){ + Serial.printf("ws[%s][%u] error(%u): %s\n", server->url(), client->id(), *((uint16_t*)arg), (char*)data); + } else if(type == WS_EVT_PONG){ + Serial.printf("ws[%s][%u] pong[%u]: %s\n", server->url(), client->id(), len, (len)?(char*)data:""); + } else if(type == WS_EVT_DATA){ + AwsFrameInfo * info = (AwsFrameInfo*)arg; + String msg = ""; + if(info->final && info->index == 0 && info->len == len){ + //the whole message is in a single frame and we got all of it's data + Serial.printf("ws[%s][%u] %s-message[%llu]: ", server->url(), client->id(), (info->opcode == WS_TEXT)?"text":"binary", info->len); + + if(info->opcode == WS_TEXT){ + for(size_t i=0; i < info->len; i++) { //debug + msg += (char) data[i]; + } + if(data[0] == 'L') { // LED + if(data[1] == '1') { + ledState = LOW; + ws.textAll("led,ledon"); // for others + } + else if(data[1] == '0') { + ledState = HIGH; + ws.textAll("led,ledoff"); + } + digitalWrite(ledPin, ledState); // apply change + + + } else if(data[0] == 'T') { // timeset + if (len > 11) { + data[3] = data[6] = data[9] = data[12] = 0; // cut strings + ee.hstart = (uint8_t) atoi((const char *) &data[1]); + ee.mstart = (uint8_t) atoi((const char *) &data[4]); + ee.hstop = (uint8_t) atoi((const char *) &data[7]); + ee.mstop = (uint8_t) atoi((const char *) &data[10]); + Serial.printf("[%u] Timer set %02d:%02d - %02d:%02d\n", client->id(), ee.hstart, ee.mstart, ee.hstop, ee.mstop); + writeEE(); + memch = 255; // to force showTime()to send Setting + showTime(); + } + } else if(data[0] == 'W') { // temperatureset + if (len > 3) { + if (ee.tempe != (float) atof((const char *) &data[1])){ + ee.tempe = (float) atof((const char *) &data[1]); + Serial.printf("[%u] Temp set %+2.1f\n", client->id(), ee.tempe); + writeEE(); + memch = 255; // to force showTime()to send Setting + showTime(); + } + } + } else if ((data[0] == 'Z')&&(len > 2)) { // sched + data[2] = 0; + if (sched != (uint8_t) atoi((const char *) &data[1])){ + sched = (uint8_t) atoi((const char *) &data[1]); + EEPROM.put(EESC, sched); //separately + EEPROM.commit(); //needed for ESP8266? + ws.printfAll("Now,sched,%d", sched); + showTime(); + } + } + + } else { + char buff[3]; + for(size_t i=0; i < info->len; i++) { + sprintf(buff, "%02x ", (uint8_t) data[i]); + msg += buff ; + } + } + Serial.printf("%s\n",msg.c_str()); + + if(info->opcode == WS_TEXT) + client->text("I got your text message"); + else + client->binary("I got your binary message"); + + } else { + //message is comprised of multiple frames or the frame is split into multiple packets + if(info->index == 0){ + if(info->num == 0) + Serial.printf("ws[%s][%u] %s-message start\n", server->url(), client->id(), (info->message_opcode == WS_TEXT)?"text":"binary"); + Serial.printf("ws[%s][%u] frame[%u] start[%llu]\n", server->url(), client->id(), info->num, info->len); + } + + Serial.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 < len; i++) { + msg += (char) data[i]; + } + } else { + char buff[3]; + for(size_t i=0; i < len; i++) { + sprintf(buff, "%02x ", (uint8_t) data[i]); + msg += buff ; + } + } + Serial.printf("%s\n",msg.c_str()); + + if((info->index + len) == info->len){ + Serial.printf("ws[%s][%u] frame[%u] end[%llu]\n", server->url(), client->id(), info->num, info->len); + if(info->final){ + Serial.printf("ws[%s][%u] %s-message end\n", server->url(), client->id(), (info->message_opcode == WS_TEXT)?"text":"binary"); + if(info->message_opcode == WS_TEXT) + client->text("I got your text message"); + else + client->binary("I got your binary message"); + } + } + } + } +} + + +// setup ----------------------------------- + +void setup(){ + Serial.begin(115200); + Serial.setDebugOutput(true); + +//Wifi +#ifdef USE_WFM + AsyncWiFiManager wifiManager(&server,&dns); + #ifdef DEL_WFM + wifiManager.resetSettings(); + #endif + wifiManager.setTimeout(FBTO); // seconds to config or it creates an own AP, then browse 192.168.4.1 + if (!wifiManager.autoConnect(hostName)){ + Serial.print(F("*FALLBACK AP*\n")); + WiFi.mode(WIFI_AP); + WiFi.softAP(fbssid, fbpassword); + // MDNS.begin(fbssid); + // MDNS.addService("http","tcp",80); // Core SVN 5179 use STA as default interface in mDNS (#7042) + } + +#else +// Manual simple STA mode to connect to known router + //WiFi.mode(WIFI_AP_STA); // Core SVN 5179 use STA as default interface in mDNS (#7042) + //WiFi.softAP(hostName); // Core SVN 5179 use STA as default interface in mDNS (#7042) + WiFi.mode(WIFI_STA); // Core SVN 5179 use STA as default interface in mDNS (#7042) + WiFi.begin(ssid, password); + if (WiFi.waitForConnectResult() != WL_CONNECTED) { + Serial.print(F("STA: Failed!\n")); + WiFi.disconnect(false); + delay(1000); + WiFi.begin(ssid, password); + } +#endif + + Serial.print(F("*CONNECTED*\n")); + +//DHT + dht.begin(); + updateDHT(); //first reading takes time, hold here than the loop; + +//Real Time + time_t rtc = RTC_UTC_TEST; + timeval tv = { rtc, 0 }; + //timezone tz = { 0, 0 }; //(insert) <#5194 + settimeofday(&tv, nullptr); //settimeofday(&tv, &tz); // <#5194 + configTime(MYTZ, "pool.ntp.org"); + +//MDNS (not needed) + // MDNS.begin(hostName); + // MDNS.addService("http","tcp",80); // Core SVN 5179 use STA as default interface in mDNS (#7042) + +//I/O & DHT + pinMode(ledPin, OUTPUT); + pinMode(btnPin, INPUT_PULLUP); + +//EE + EEPROM.begin(EEALL); + //EEPROM.get(EECH, memch); //current channel, no need + readEE(); // populate structure if healthy + digitalWrite(ledPin, ledState); + Serial.printf("Timer set %02d:%02d - %02d:%02d\n", ee.hstart, ee.mstart, ee.hstop, ee.mstop); + Serial.printf("Temp set %+2.1f\n", ee.tempe); + +//SPIFFS + SPIFFS.begin(); + + ws.onEvent(onWsEvent); + server.addHandler(&ws); + +#ifdef ESP32 + server.addHandler(new SPIFFSEditor(SPIFFS, http_username,http_password)); +#elif defined(ESP8266) + server.addHandler(new SPIFFSEditor(http_username,http_password)); +#endif + + server.on("/free-ram", HTTP_GET, [](AsyncWebServerRequest *request){ // direct request->answer + request->send(200, "text/plain", String(ESP.getFreeHeap())); + }); + + + server.on("/get-time", HTTP_GET, [](AsyncWebServerRequest *request){ + if(request->hasParam("btime")){ + time_t rtc = (request->getParam("btime")->value()).toInt(); + timeval tv = { rtc, 0 }; + settimeofday(&tv, nullptr); + } + request->send(200, "text/plain","Got browser time ..."); + }); + + + server.on("/hw-reset", HTTP_GET, [](AsyncWebServerRequest *request){ + request->onDisconnect([]() { +#ifdef ESP32 + ESP.restart(); +#elif defined(ESP8266) + ESP.reset(); +#endif + }); + request->send(200, "text/plain","Restarting ..."); + }); + + server.on("/erase-wifi", HTTP_GET, [](AsyncWebServerRequest *request){ + request->onDisconnect([]() { + WiFi.disconnect(true); +#ifdef ESP32 + ESP.restart(); +#elif defined(ESP8266) + ESP.reset(); +#endif + }); + request->send(200, "text/plain","Erasing WiFi data ..."); + }); + +#ifdef USE_AUTH + server.serveStatic("/", SPIFFS, "/").setDefaultFile("index.htm").setAuthentication(http_username,http_password); +#else + server.serveStatic("/", SPIFFS, "/").setDefaultFile("index.htm"); +#endif + + server.onNotFound([](AsyncWebServerRequest *request){ // nothing known + Serial.print(F("NOT_FOUND: ")); + if (request->method() == HTTP_OPTIONS) request->send(200); //CORS + else request->send(404); + }); + + DefaultHeaders::Instance().addHeader("Access-Control-Allow-Origin", "*");//CORS + server.begin(); + + //Timer tick + tim.attach(0.2, mytimer); //every 0.2s + + //OTA + ArduinoOTA.setHostname(hostName); + ArduinoOTA.onStart([]() { + Serial.print(F("OTA Started ...\n")); + ws.textAll("Now,OTA"); // for all clients + }); + ArduinoOTA.begin(); +} // setup end + +// loop ----------------------------------- +void loop(){ + if (udht){ // 5sec + updateDHT(); + udht = false; + } + ArduinoOTA.handle(); +} diff --git a/examples/SmartSwitch/data/ace.ico.gz b/examples/SmartSwitch/data/ace.ico.gz new file mode 100644 index 0000000000000000000000000000000000000000..49e15bcebdeba0b55db396e5b6266b6e72730070 GIT binary patch literal 6307 zcmV;U7+mKciwFob@SR=)0AXWgE@@+L0PR`_a8yMYj@{9*k2>nu1rnMd78Fq|C|I%g z-h1yN*f4-}LLh+i$y2KqS23|jg21?lm9V9WxUU^Ugfxt zbNpMHo14WvP7C<`hhBH>6-isSeDk+)UbJAg%sCtm9o*K|I=HR1^_iBImb|7|OwkyL zxI@8U*zfm8CCL}_c%>$f$NSI1>uvISrI_UN#R7pqG!zPj8yh3;rly#xwY6ncdwbjK z9UUDbczmdscTH8pu@7lJuwk&FF3Wvju8O}ZT`V!Eor zs9sqXF&VUBhrFCd+b@`yF808>kcltq$j%c;+~eAi_wvH3HB6>Lg$K0 z(YcCPGa8-iE<@)A;_J)NSx9Ug^F#0&@5yc0HvY_)mtxO~QP`b-3EFcnLDLr(qmg3- zmR#K9%^cO^$Q;vcUUL0j-Li-FXx2_{)9&~(X40ubZnrx`J4NXOZgNQL+_R^j@C9n| zo80&8*+c9;V)yRdFVWwPkw`e|a=C&ARYgQyII~5Qbyuf;-X%SjIm2O}doEn_hQXUQ z9D(%Vh-93Hro|)BwsZt`e{nwcF1rBT`4<4oF9cRz1gs*~j0Dyuur2`}%hy*Y+N@-I zKGU6d0sA-~yVzH2)(FHh&qH|8aQHcvH*FZ49NRYMT$pDKg<;k(Xy;tgqsqE(k9u=@ zvsteS`Fy@0#QMg%pL;w+#&GIABy0Dp@=Lz7fl)GqIJnIbYu<3 zp6ub+n=>3;%g#ej9+5u+5GeQ#ye8l4W*gCVH=k+G8itm|!w_R%;q;*hqz#2MKR%Y7 zV_IeohVk>k&`lo2GS*ueAL7O@d4O0igIBg)z(+9#f zV<4Qf2Ej9D5Pb6nA(%E8jp;)WTQ~$Q8AH&vcqlrS48`uObJ4k!$UYZ)zlS}%#(Q#` zw#=bu<}*<~8(AGMB9^0ducRA{3 zj705}A*lUiAd!N)Pm-Y|)SnJO!)F7aPaOc$v}9POC&NA?8Ln9=@Xk(wZ|*?OeIUYV zgAh$0grHz3Cu6D`* zF$d0N02Ch&K<&rLsQEYrHJoS7l)-TgW{v9B6wYXMIqgBN(ILiyj(kVa7vy!Vi#pIp zgx^2Tc=rW^p@3PnGosFUq*Fa_3{-P3hhpZXDF0*_w!M1}irzjO#l((x&qDR2bD;dV zKQy2A=Y0Ch^D<8x0PE)i;E;7lmgg?bNr8V}T#FD9Nh21-(U_=1ycQ;cZ0DaVc&EtE zx@IOPc*pxTrc(1M{h{WVs!#f({^NeA`=}pkKJ1TbqUyr|sQM@w)xuWPK#@8W^|MEH zHxw^vmLw^_y+W8iz7D{#^Z^m`^o6c|T;pn@(P+qF(TB7vU)`l$a23?^ub_UTvGdal zQ9N}VN;03t&b&$3nL80B3m!$$hZmugI@Eo54mIc}&&!b7A12OI%-8mLG8{9LS&Mm} z1N~>`z&y1dZ8-oE`S}Ir2|tk$xAP1>H@(0740%(_ICp9*_pRj^N^-89d^YtbCZ9v} zLzTd!eyE(>AC(CWYCatp_kn5WLYY3k%UoaF$n`PM-qz-496a3K-kx;f;1rSb-)(Ja z2?@W~7iTtW7mn-Eq+LbZk3mK1#n_SlFzR-!hqAs3N@Xok!{bWSm8?N&`lBd$zdvno zjYS--X&QUO?@ldr_Nu0k!HEj}^grRthzvEg4fapN&9u z>P4vjnDb_zTDH?qjrXZy{}mscjqUHJpm_2K6ipg|t?wk$AJ4>&_s&B32j`$Nt^xTE zpbsz>m=o%z4rNXp2FrOkUkKi4}1;aIL7^{wEYfYd%IB;*5*FasZAdX@~7=D z!_JxGq1dq&Dpeg+%IY6NRSQ+!PE_Q)j*^MVvLC7$lUktx=d340Y}OUL36-Lp?Q5W_ zuYhv1rrB9|?QQgdag6&rT3cJ)+(rgWJM)?vGOz2=F1$wOU-S7WRA#>bjj9?Nb?rVF^eUJP zYBXr;p;p&HU0;s!r7xm%Vm~Mtld=Y>$;{2<{@HM-N|r;TQS?3^Kjt%at3F2g$HP(n z>G@C<=kj_zQO7n!qP@_gJpBP|efu2jn0F`Cwc8W-zSoYrDz>de$@~Yf9FwlE)?TV36E5(D%RLdsNVE(}(oSpXk(OjwAnT zW&77L_bJzXCXb`j))O4NdMmb0y$+ivU4U&g6oa}fize6OjG zMq@#zp*Et=y|+uh_&PK!q7S5Bjruv4L0#|)j5;O9Q_|Kd=ry%a)1Io5FQMF408QC? z@=^5O=e2xP7EDBC?ptz9lr4T5+R8%SQzzOmZpzo8cK(g9Y@P+HLDhS2-+j&6kD0sT z^Hyiv3R`&r%tkHr?0?@p>Pt~FZ7jCGcP1)6;l6CqZLm@^3)=~8s`B1K>7-Th zj6=i1vGV$-OurGz?1OkFkuM1OT0_}dlzcn_Ri6%mX~Se{poEe4 z2)0+EHtTWvE^`U@b+ybVHPbGDaqE1Td)p8ORT;{&Uq+GexAzBN2iJwF)bn60Ooh#) zk@YE?eLbo_O`-1(CI8{j%x3&&-?GnkvaW~71G+`mph0Lbe+;yXZ-r&Ud$4W#1lp`Sxu?1m zsyW2m(X2;9!E^nZx8byC=obbUYYI^@_a@ZLxd!^;4EdVPqKm_-hpBE0DyLt9D%x3@ z^8_{0!kV~WoBtZNPacG-#gCxsi|0|2I+}T8APn2HzUzlJcB+fvvQlgMprN`DJ8AFo zkGL0^aS^PWK7%In7SvB0EXTcO&ImNjzX0a-uk8x>eZd6(0`gzU{1@_h>_O{SukJDD z+zjK=8=+rv9k>?6HCT8xvg095n0ZjO zdLkTl6K!G;i2IOc8|r3{W{h*+FlP+x>TPUel-sE{&BgZA%VAZQ%GV5)jF+jGL7DeF zoHo7Ohuxw@Rn`+wE`J?PYT$5~p)1Kj*_7ej?+lcAE2oqD%wgnC+mpLt(J1#hD}>0pF7xZb=r-nn>Gll z8AEAznY(OvefmYPI_3A*3C9b9(0@Q)fExJ-b)$X9&aW<-!J_V1%0FTQ8kJ}1| zt_)Q(FJoR3^Bf}Esh;ndZuK|tdhGB}15@Q1I1JUIJz?iwVc#m_}Ew~7##iQWd_E~#~Up2Vb4Rig^=HB-(z6%~n zEmm?<81{QzLD$wvyKKvEgV4ZC4NTcLz?gL%F^*bXOD(RU76M}vxH^su>X6Vv#h9=a z&xT)ez{UKhTs;XMs|pgiNnX306Km714H=?Hjjq79K~LkL~e+4s=yL(wpA1bN5pZp^qCjx`VLm8|t)?tKM+ zJAHo~?Vd!xPvZC7I~yAtJt8hV4MkDcx`(@E4f3eLGHUR}4bmwF2%s}g>nlbSd=PaW#B?txOyOT(d_%{>yKq%Y`~-3PyZ z8$tm$f&s6Lkk1a&`nRE^PHfA3dm$V}(-86)zH1Zo!mC^h^@7o~`T691A>;jG+WitZ zSKiX?Reu!|{K!+}{<(bjJyd+_<9m>J_dkkSEa$snI2iB;Je3)(?lt%H*p}Z8YyPd& z;b!^*<1yz3YC#>cuOr6C^;kNNwZOI1hLH7OuE@9oh80gB=+Yuc-a*NZpx;HfX*(`u`iM5M#7kR3CvlS!oBLYE^qzHCVnRm2!6EvR_=Sxru~xu z$Pj+O^O4j>#WtaU*AeuV&2IOsyBGGAcR=_8^Pi z?zz-wICN>}5!}Np5cXwUvle`H^l|+{+B;*UY;OyBJM*rBxA4hMsbN#}d)&*(^CEs5 z{>k?*03r_VWjkv)90~fp_Mo?7ew+8JhkBf=?xYU4!%iJ+1-BBnz?MG&*1VgEn_v}s zLj4QK8cxL1zvkqRH{l&UjY{7xNTYr_HZ z4bisWkoyG{6&2!JU(%0@hywrzGBzHg24?Y0z~>D}>UB-NqSrfp8}5gD&0TP=x&scO z#fsYqYO#V^ES~^-!Ohf!TEulAs6))>S@eC{ z-c9WXZ?8HwNaVR|wGWuI;gY^L~eC`-dG;(VM%aqStpz+b4EN zm2+Et+OK1Nry<1ectMgE#X|p{&b97ze$STe{7WU_2M5v*CPc#F$`A|tVfgApzWU|O z{*n)N`@ear+xPW@J<^7IA+5h#29JBBuOI1lt-h;gpALC9Pz#~Mc<7c~4M*{GG?RaG zEGVNG}kra8&UiF5UOL@7A0WrE#MKG#oUq8eua0xiy%zTTYhnB9#XT;YDa2xxG>22lV0Fxv%NR7(a;Lcw|0*w1{}%vxm?ZL|&XiJxi&BjWSSX`M~gX#`S{s7QAWm6*sV-o8VbJ0nXByZQ?gAI-QyJxLB;+|7H>KrBEo67$Z+h zKA+!d(S|%l@9dGjx+kuI>G@8+JB2w;m}N0@)uAFz|LwwDDg59>`oKo7R|-3|+Z(0L&vr>)-3t%b2lv`L z=nJiK%c&}ic_m5M-ay-rqUL`k*8kQV zA$~t*9vH{pP|W;0jgV9MRm{KnnJ(Yg_rkm39(d>r2_1-AY13O0m_SVgZkEAwnX`NK zE!=P13h(;c;M??Am#cm)|Ng@hz#p(_k+Gb9qtx75O>n1cTkVpS>HyU-+|}6&+F^&fd8vI;oI{3UYF{tn7r1<{eB63 z{uuGw)qkyUUcwg+<61n4bEO7S$YoMQyydgo16!Z&4s5y~vOh34Pz&NN0dl=lfX8=2 zB4>Z$T?l;hNVj+A)DD-SDk6MdlB6)#`vS(=sr0k|gx~*?23(I0qmRBy4Xl#n3wzwI zpj%hkC{@mD4{UpNZ*a?FJ;84tM38y}Hr*EokAs^Z=?N6SxK}El*)G1tc-)R4b6v>C zLhcK>mpg^p{%5)W_+5f))Ah_%TP500=-_4ix@`?%cLTX83Yxvu8Ld*)f;MmUqBc)m zev4bXCF-_nL_6~KheV!dK2cH2=h^3x3HQ!a>*w zozRGD=o0GnIC&4?vj_fPdH;$Q`*W>0n!bECzd@eI7#YcYb^-Y&i+v>99K`QY{~JH= zD}AM}^p(ESSNcj{=_~)Qf`6*WpXH7MN<_V1?{0QdSG>NQx8(*+@%j*FqArQo2PEqK zChx2N`SR28IFBFB@2Et5dQ*Z&f)9G)w*mP(x&^YUMBRa{ZyPf_a zPbI>Ps85ME>L4Pfn z0It=$$5wc3T`8{Kh^XIv&ZX+o#mmb#-(0-9y!jU10uqGDoPUOx5)TJKWg)Uau3272 zDDKd1S3YhjUk3LqTk!i135(1qz6cdM#Lx{M4FOe4tIp4PqcJj~Vx^d@RiHS-0zCmY z+nPeFTnd)0LiAK)dS1T{lI=EqjFiqe5vyWDGnu1tH0N2)Q#znRa1n(I!M9sr6KwdR zNNF&m^Q6dWV1E<}?vp%wM+Qk?gbhN39Rn!yQd< z3w8ho4Wo=%NmJ-KRJxx1Oy?j}aLErH!M4cP(Gr!O&UT0uVwj`d z4h*`)qJfM9AdA8fYYc3Ac0}O0c+P@YiCII2!G6Gi-NW@V3Oga{5Yj&}vNHf6-=<8e zf?B*X>3_*+ih4lpnXi*6DmAD1IuRE#8X-V=V1X5cIyS=)4f2$M@r^J@8T`yyrm3+c zq6aTM8Q-s2N`0jUR;g|mCY*&OClZ=S@C@5j+4AsqcssZq4zXfZQzt*&4yQd;W=lg< zx?zwd&V4WhI19q`OKe2c#x17W9pvZ?6K7ztw)cPUmd1wHWYLPQbRlmtq%-wXw`r>BOsjO{Rtj|TheZ5 zE`P(=TbZcqXG909l+VD1!&L|imP~^$@V53R^;? zYcK4a>7SIQ-4lJF^YM3db@{OM#40M5G=Gp^O;?end6S7#b-wM8^LO!ZVl!ILWDGf2i>E0&; z&s5IUugn2tB7{G*)k;Zdd)B4DCx_zeSWp^u=hmgMS72-B*cR z50)th)6uWVEC-$lVOmT1v>q5Y@#0D-(NW-TCkgR`V@sHEp3)?9pINb)QDMK_)U5^m zTnSP!v@(7rx^m8OM(E%!Neg|{lTgRD5nQjj`8^jL^}7UDPyxfc9B z$mo6W8X8}!(7gQIw)HG~27i_Z7JsCqws{-hm{@VMIxr4l)PD*9AbZgQ=45}j zfeVtGH327tY4{^vSs230nz&B#>-)@2cZ5?s$7{UB3pMCq5D~}Wn>S|ud_kq8;?0{7 zp|s|(UyAVju<)iTT>FJ7=f4!&y5;t;uxhCknw;R%DTE9rc1PC1cE~AGadBJTfmV}O zW3I7_Xz#Q#1LdfRRDWT{2+PvcoWQ~pODm@`1sa`>5W;Qr4}qRl`?RV`^Z_2>@W&s2 z457GpLaG|7FAaj7$Pj`@2<;89W#&ibjp^xlg7-Y9FEZ^)Gc=}z+;O%DM#k};86T_N z=_Yvq@f54>(4IWYz$E}aeQJzPXtp+}psEJKEwl4f%}(a^NPoLsWS3~Y-E7QB6sz5_ z*^yX1SO)khxnQTX$H6d@Uf$<81!WREhbPy2+q0w!Bi3XTug_B02d|OhJ6ZPDQ=;Dz zc#GW*eEGt(S(7wg_xo{MWg84Cz30e-lFacRcA-(Vm+Oe!=#|%cQ6-8^*3)XMC(0Uu zJJLSNaXYzvTYt76%$?u)+D<5`OaKf3%lgynKp#Bc)H%79F-B-Sfi4)eSgwD;TpHiC zcAjqVewgF1?rlS?_YIQ};T74yB5Q8NH)IP3Ttozlqqt3>62cI6%cs zPJ~;uIu@oJOp2=^%aB`pPhz(Sx4@M14F#0i$p1f(j$<^69at?G3A!le3Z>S9e-WpD z4j5ph(lv)C5hv}N9n-TwZ9X?!`4}Xs=fORb>wh3qXfnx?G|;=l(B*SSSO+!xGG0Iw z+winDmRWGM?=kBIdQy`;@AanfOwi<)5=vk_c|q7epk8U#r_RXON1TIUfGCvLj>Z~> zi6St!iK~fW zpEI1=-m*RO=?LV~=yr=fiVucHrF0qjGV(_UsofKMK}P3nTy4KbSoD~kXzWbH%y?iH zFmp0DVT}|%t5f(bXt@-(kC;yaY5n&MY=5l{|9j{JytRW@?+h8lmMc_vJFR@HCa*lt%F0M7q!ycwm1@!6dK7lZ}ge8I@gw>m`g6s8(%fvV~(u7 z*HXOv%V#v73$}$OW&|Ed_)I-7t(L$v&H84L#z7cA)3WZ-{^>V3Ny7!sFFcy9uYc2~ zHo@BJO&)vFbkUqw`4o~>5_JPCWQX)l}x9TL1_+P`BLWadK&7V4#LC4Uw~v1eF# zy^&Qix#RLK-EP|<3!`}?aHdR9Ez_;%Fs9>|{>H-E^@8&p=+GQ|pVjUy)tL5g#lV4s<#m=I&PcKod^@E`eA%9De>Os&x8DU+J zn}WG5fKOB(*p{s`$oS&+l064f-JZ}90$N52zV?Z!lKTQ@6EQ_`r2um7DW^#aQoXMh zm+v=N3QB*Yu8I3T(kNB~-l!P){>KgYFX-u6ZWSr3NNs17=h;|7m9lK=hstU#qIWct zm+Fp74h;55AmJ6vlP9Nxi7OE3b`pCUSJ(wt5p7&DZSjA!>Hp{-`M=N;awO8V%kvc^VD|%? zr9Ld_cCSn#)OhBvk*k%F5fS_45<`Ow{vqsh%Ie^F7P$^ke;mI!n4-hT7r|Zeqdr20ejx z5DUG5ASl$@ex^ekdr2w$35rzVyCK5g`Xz??HjG9q-$Q`xHd5~y>#LHV;eRl!zrHm$ zC6yYVR~)Q`(LXYqd7|zdgKghYA%n0-A(!Xv~#Tz&J|^$$1W(7uEvHXFK|7Nb>b#;at0u2>Ef4@LNzWyOOb z86o=BvMcQp;FjFvj;#{4uc|!bc|{vPm6(xexJl-_dzS4|#dyf{wSO~ptt3q(IIj(Y z6i>+Inu5zlaB`|QTK80_JF1b|35$V3?m{8A+l3+KM5u#dwJ%lQu~Pa6mJtR@fSeH9 zZfODt2ZHOCCTTqk@#>OrpuA#p!E?Tp!Br-y$fyj!3#44=dsMu>HT~-5V!Qp4=Q2bp zaRYXc)6Y|$$SBIq&41Bo7@dz_-CSJ;yVrs(KlHZQPQsBZ%hdf}VlRpCnm%X`9yPDMD$hc*g>mQtVWIN|jr$?~bxGjw zw*UtFJSf66_H@&CL!5e$v`_>atocD-PDXKF--XXzM1NNh=&(Ac(jj=!?J^V76;({f zbcB(RBS{l24=)J?o5rcS#azX*OMf2k^?8ZFoKkX%JPp%*4XtX4w>wDn-=4g{7dW{a zF45toVInzh9%yga_x8jU^MwXG;;=BP*5_U-^?!tKn%qvchKiDR8td(eq?ZMlU}gxaM$T6M zoWViqOpYb#E_NU&VT<@MCXJ`k$KY6RoNKAX1&;VIBag`2yYRN9J$^#la|08ojR=jN zG*pIvzB`PC=QNIaM!9LeG%39&Anp8?%jHs-pn@Q@pcl&hCN0l1fDt@8qTDhVK!0hz zg(_1Gt-cu2Z=$s)Uwo$S4gGL>7?5N!OjBH8OmOCXLU$U~CRkmQOl$RKrIk6ZE*Vg1 z2_iP5w!`+0dctCTYgl-Ew<_f%I0&tTvI2%+k7` zqsLoEU}YZrieoO}h+FJIzFb_^H-8c0n8zqiDC6<W(+U|Uu76>wjE6bP zolTWcWmY7m(GeLRrrOrpODl391IAc7;+q>R7fiNibE*2rQNyzWXPk+GU`9iaF20OI z8L38w!4h@o34Xxew`&8dyN2`m{X(yf zbrdwR$p95omXf3$EQbUI{o14 z<;g*is55;3W6ua^Zb$MCOZ`dsUXD)(;AcDNtZw@1S%gZXl@OS<@1w@Vp5X`%r+UC= z$skHeQSo{CCSh}(JlxSt^pP?btPQF`6i$fci1wlCBMFU7=g|_yYJch`a{Wwk2Te*t z_f+{0oE*62tgypL5`zWok1Njfz4)w@7;&QOEc|~&B%TJf!j3T6Jilucon?y3IG%p0 zjx3CzPztlE^Z|xu&@{lFEu>}hF4^c?wifZ;GAa1?NX?=YIYD<|79PzxPz78=`5L;I<_TfXc zi=uIqVHZC_)8j}1>{lQK3PYguJ7O@-{B;qt!5$we(eyWj!++iF_*-HEbO^92P6pA4 zz9#$&v`GvM3$g#ht6iFPnsqSw0*?u#Q#27+@SXF)HFyUrr`$pKM&b#*4uYDXa(gLM zja_hlriygCl>NK>VT$h!_5Bh85@MTxjz;)E^L!gm2p9-d-Mb*nMSxw`f5Y<~RdR#y zV7aG6AUR;^1b^R80l;=RaEk9&Gu%iVd5AnSkq#nTCbEvma}(*JCZ1}M3V;0K9Qpq-zQ4z9zLGaM~4u4^u?$<^wp&=LVv!Y*yGI~F;F<;eVP*%;^g$; z)%nhg!#&;Q)OnwwH9^ip0AfJ52~z6_K&XoVAR7okViN)IKScn<&k%s|Ed*fuIRX^# zIpQhG1qc8#Kmd?y1OOQ#0HF~AK%(QGfzS;C6!;wh2;Cw8p%4KG{eb{j-XZ{&F#=$j zAOMyK0e`T>j@Sa0DFR^m69KR!2!JI;04x~-V3{ERmOBK%@(uy8yhi{mA22$AMdw-fGN7KQ ztk4-u@L2fJSF~;-z`BXwl$Yp2`xvRsdK$lLt&99tXD_0ghjP^{zPw}U+eobjABpI( z1%I1eF7(qhV9Q;>&jM{}0eE28u@l-Iq=XUV(l*io-81c!iO?0SPTa+z?pzxf8dN_a zsT0dyB3Z6|WuYt3#)%u~;dk-Q4k1K&pfC0M(oI(0J#5eur7iitD9m$h_W=DkgXGK( zH5Ew~GCX4Jy-X^LJ>u*zOfwmwdmJ(slz)c9Lfk{}|7;5VMR+F}@4b#ds97v>uN+x= z4&kOSAI?ewF<29`0&Z+7!WL5rDJGDDzm=CEf3r>K8oO)|6(vWeB%h_o5mw(*P{s^M z=0Hk^mZNwS-h?ta%TRlCW<3!u7iV;mY0ANI1KJfjkj;ZFrjV{;HhiNz=vv*!Gk@5p zy2jsE=LOyZnGw`3ovrzt!)J=oLEvClVd#(&v~a;3_j7Gsyt(6W1>PLH=t=?4nK+7Yy$FSNGn z^Vxi^Dpp=HO=@M4?Hdvp+r?13!(dJ;(!Y9e%@THb(n8v;8m!FGOvHgFX1%dx^BhUc z-1vhnAK$j}iBL>~@+5FYF;}daVuKVDPFdoI0jnp?G%ugeSb-_)YXRllw11Q)ELnY& z#V-}RtSx0%A2WGzc)1OXwsQ#)kk9~)RQT<>6z4}4dCOyH<8<7#uyi&>V%QKO+pbzb0%uE)^!K-}zmex5i~ zhnWc-X6AFVuz?Qk%HPWmFn_;En!@Ij_h&@<>%ei%M8Sc1VJKMsMhnHFoEtoRNKXY%zZyIrAKuJYx&8{hNZLI@{(t}X_S>XAG+;*qm!b<>Rw!Oi+-;V40_+>K|d*GNy z4U3ndw08J)d*E(w&gZp^pW8Rc;Efx#iCsbmWA$(>2MM`mLVxYv8oRLVr!q5fYa<#f zeIh);XOOVx^QWE%!A;2@gCM647lE80S^KVd6-$E|Uz2UAIW}UYgnGdVH3Tc35n2%M z7#k0lxTQxA(B}C|pyEc1vAx`{`^6$Da8QNJ3#FHiZ{Qd^8;n$J(W^RQusIzQR+a3^_Rk+{rJ(uExv08jNYOTf_I)QXc6yNea;4TZB^`nVt zl;WgA1L@M(gO!2`=$Z$i5>G?r&&9r3*g%X|7B-8PgQC~*AW@sX6B;$YYepJd+_+&N z*{Ei**^2{dPF4$069y7nV44E7UK8khg`|e19U*@cW`Fh&q4XjrbQ!el7|qd@j(+r4 zVb3$oSsVCeO;QxuLo7qoEjoBUH+_pQ)2;ZR&%3n|?)U#M)`8Aqj%@hm$+l^}njr}Y>xOUNYXVCY2>E~-BfA1H0+ZkM0)~x8;b<&hkWNmHlvOB>4v9DClTW6V?-XSj+{=8|8ht}#GYR@>VQZRi?UlTbi9nmQe+24R#o_n8Kn zkmo*U1kmINJC#|is}Mz`swxuGD7ii{D1RZ1h({4=#$0-z45D8JC}E(a47Bbe@L1TO zuXd;3UiTj^$$%Z7QEZTCQm)TQ9M+H9^`>C7(x9!hCAY~#IG9jNH;&5>qSmvy4Xs8; znoLrxUTK5Yw%RSWk1p4nudRCg+c5}J7}T2kzC840!)VTOBxh8KDw^i`CGDwGLw|*3 zstK3z0=Di;wCY$)e~1cA?kyZ}s>z~`B6ABysAV2z!?a2>6UeBrU?=7p+m$ZBdP47HR!Rd>7JraP0a$(G=x5tOor>q9bafvAKY>Xr071K4XlnDp>+>5Um9Zi`VcwLg=GZ)=^8|#YW(*}rfECgy3_LPg zBIj8?pywL$M7ye56kHKK2!9C5xwN7<)DgmNVWo0~-MJOYb_FU@qOj}36$s6&)2Nba%6~dYfr9F+aEa}GjNDK36XX}e z8tpe1(mW~LVbz@S890@9B)2w}C>{@6O%zy5dpsb?MlqFx>RwoReSaa__Q-D2QEu_9 zUqu=`U0sQ2{uGb7jl1^ioAgckWKD#@8h<@n>lt#mGddy1vSyae-Sk8-k9HyQJ$s;3 zXi5#^=?7&+trg!r94hUWDa7z(Owq<%W zDJ(`?1mpV6tc;|b?tcQbxMr9xdkTW@@D+cb!0b|Y)vgTQS8D;*O)a&`J>LTJ8$g|S$xTPAF7_3f$qn6dc9Bhs3BWI*oakm>MN(nf$SDdE|&Og1qnL6OG^e*$5)5No?&RmdjSO*^w)nkbq>-j3FY`W~{XzO4M4fnH)0@@PCiCTLge6Eiavg*wFPqXnJu& zN|y`n$Djc79lQ2VAs)zGuFF`C{5o^wLbGii&S|;rO|Op=f5J+9)dr@mGs?%F- zyIUjo5b}L|(6_MaiP-eqNclE@MSd!`WyM+XpWg{swU~fpS)^4wra0X&gOu2$7=~bC zQ%M$6Xn&}na2xx&vjyw4GM|gFm9hP_D~7>_=ZV__tMT8O2DiDzRg6^e<1=v=jQS9o z*8DYGJ`@wAn`aV4^$KS$47^5Hz9;ie1gp^u#wUEREe~Hvw;aqK(L~FQfpFV{(_h3d z%bAt(>j)~kv1D-8l3*@h!%}!2XgF8A3U+Z`6@SO%vh`!jEwFzNK1y@yJ6C+S#K^P< zyygzyFiq)3WUwdp0!VNq&|~(=M8X@4YL6Z}A=4=vqe{7NAsA87ziGP?rnZeJ{8x%6 z(~-iOm^8g?77wBHOhOyzHJwhz7-7^J$(3w~Oa0&by|=ft0@5QhG4>vBueWdCzH1L~ zWPcwl4_8%PVh8vo=u9>xPD@pSNW#GD_ZPl}XQhZ+PFAf&+gL5GJFXhUq#~3f4_NY; zia?2JX{(Nz%4r2zWk}$Rk6;+E$%UkxAoV)4QH*4v8802H6-x>A9$O%M3AO$lQxwjy zS9}%(mz7P#5VfBKVV5Y?)WMoU`)Uu;5`S2}T3AsG(snuR65GS3*87L=zkdp&3`s7x zJuZL+bhY+gQ9i;NQ;GMu0Q+#Esl|?RvhfRZ+(%S7+@eo>uWgM+oA#m7+PKMc2TaW5 zr(BPgyVcjAFBR@4(axYWJ0~CdopDu0)fRp$o8JX1{FRWXG={IFdUh5V3B5EbN`GY} zJK>iER35bAfY~%aPf$`B<+_3}k7rOCXu{ww0E)vPnN+-E`$|^gP}bPx93^aI5G;br z76+!6O3_)TtTRt~+U_*4^R|FOBh7AD;N27>Qa4>B=}?*=i9L#)Lp?kDQeI!5SVb5& zqjytHD1I0i$zIyZoUE4Rw5%$0Loi0I%h)iMS)Ze!JyTDj(-wJ7cZE6 zfiG>r;3KLV2r4oi$+i0`M`^dv|L5wM({(%#0qO#0QXdQm-wNY69UimctTuCg z#NAPbfatPHq_pNEc?j(bJGXWn+0&uy>|NKK!nfL7R}~~TOtn6lES$fpb&7W`=?IXQ zfdldiDc5qldSLb0+^<|QvwwQX=5en{nvhcIEjiFLQW*wuVEJ&dx4+360~p;YhfELRMHmSN5c3*10Gh?Ozt<6t7a}# zGgolN*&pz$6{>YAzbi6)V4Q|Un-b>k;j`MCjse1QbklUGYYJW#)KZMZT(v_OHs6w` z0dCFtax>S!5r2ghxv$!s?_q=U<#`8YLH7nM19FGiTk?<(uNcx{vI*%jz^pW}zQplG zC;eu`>Hwn3zyC1cf%7J;d2e^)l#T3_y44>%~hOZ?YTqkm(aeA7f_^vL_Tf;Up-G9~J zrRpw);eXhcG{6-AUi9S@*Y`R9;c;Eci7mHn#pRd$sA(ztmk?jzKzAL1JcGiDfCNtP z{{sI@{9oZe-uCYelN*vnOk6S-0ncw+< z()xQ?f?D1#yfF1voHy#K`a0{bT2Y?y@YAG7&@)FBU-uLH(iYZc04uX=6>2kwEfV(B ztG!)(NKhEPm40ivB{5_mot0lf=r=JIvSBKpZJ=V4kUh8nMH}~Moq9vQbv=QAJ}(p_ zYJWyG=GO!W3QkfEDhG0arw2@$=f6v>6lOYp<9@PhsPF?(yYOJFK_LAX^}q!EGS#cL zXWocF*6Em^W;iB(btdZ$Zf~ZgEA;#kqvs*=6<$({pa_u$aJ0+_$MtFfxS;|l-`x%f zVOJ{~@@@Poz|_x^jAups(M~2U(Q7Z+%zqRHuAE#KMcX1gc; zi01K>^~7t+OyIau76gbMvcOj3-&8wD;3_Hw`!9qT_cLMSw;q;T*0lowtsjV9D}U=~ z$ATT_W`}4Ue*lp0E{FIRubWAq48KAWg{)9K!uKsYh&J_tn7aZGbcJo5Kof6c*;mVU7^4=-&twassa-5XG1ix6|uHG)-uaKK8}TsYylM%8fs`fwn9XRr__GQ$=z zbB?KYRbK1FusoyzUimEbn}1lWf5f|+EFQ3QC8(_nmxUMQD=2`w!vLo_6SeG$)CR?b zq^G_ky|~4CVBEu{fNGKD+=!`}I`g{Ik`*udm~W-~tWXJs8Afy@8!EF@G!kS|j(dOh zIY8}@<5vzw;Mox2M*H`Uds_ND9PI4sEN1Dr4!ZarobK?_)?xbCQ-7mD8ec&^oT+f1 zk9R(#czL6qiGFH4G_tBo94RKU4nsgDUM&g$z9Ko=c47k=O?J-83ay`(3vM)JV~V+4 zu^z`OxY7mb&ft}tO3HvA^i}_&Uuf6iFF7J-|EUN=meww$Akf%(JkL?myqM|xJ0p2Y z)(n@L-BN)RwxqYm4S!jJqe;!c8<(7_afX%d&>n>2=-hw~En@(nM?*W$Z| z$KcZ3ufj^m6wugiS~SH4M))qa%Y8z2SDcDOfp3FwQ=-GjVq|^@ig>%RBH-_}?w0+W z?L|_~$kP#f{d@CL2adAStZvyJQ4pYWxr~`U@F<^XkKQ+zN`K5y|M!m%xR(ReBtBx_ zaz~d~Fk)WnHZ(&>0`MtsT zR>|jwx}caqOO2mgb~ALj_{n*$=w{QjObQ?b+4CjR7z`h0q*;V_jF=oS?$VfRPnP=+8su_w{;8bw{aGPsI zBj?Rt_`jAAh4V+vK)pr ziexc%>9`lr+&S60`Q{-|2KgD}lARdF6Q+jbgmXok_uxALPc-gicjprT6M$T6ly&QD zC>SoeIdtsQ^Uqd{VzCT1AZGBLXCCt$!AvXpjpc>z(1rK7Miwm}+G9!CS&k9R$poM~ zjDPk`pvgk!TH`4)d{q>4<5Z-fy6k|nTOQ)eD2g~5(_%K22_P;G}Ag)^?7zwAZ<6wRIPw^F`R zxp&ec(F~@Nx-(8~%we7C{q9Co1!_ju4PhG6Y4N7e2i=ex4%#z$*k^eYJ6B!US&`m) zrLhw=R|Y$ayRozBigqUft3XX2h@F;Et($#}%^Lec|um z?d{H!j7=(hoc8Y!4djmjaVQE{B8q{z2oCIxf2sVJQ#ERL$n6emid4ka4b4ypm5oZ$ z9QQa%Qi5soFK&sazeq(F;k~1}y-_hSAHG}TuGw(T-DNyJ?D;Xqu!rH?f}AkHsu;H6{CJqy{afz9jqcNaLB_Ax}3OHs;vY&!ZRA40wIR;*mw z&nj&_%J*tE)kw;1Dw95WiefN-zoJb1P|Z(VOvm!c3L;nXaG1b}H*lE9wK*$281j5= zr|B`dC}!EY7!dtHRWbZ3V=hNkGWmpwU`dwkHH4BEh|CLWGSeQTyYEX~E>;hgK-P)5w{rZ(!kR%p%Czpr@duCGqti0; zq#LFS*6GUmR<)%YkMbgqDTKmC^XSt^Vb7Z8|7Oy{Qq4ER3h1eNt?>kJZ3Xokjc($) zt?r?K%do>vJe3sP8Upfv7Q#hY5|Oa(mjySj=9hSg_MV#V@k>|Fo{@nNAX3|ZFey`y zD7DKtGw3B3@pNrwRYKw&JYm>^C!DtKvb<@B_cqU=`m@KEeUni%N;r;y00tBmI6!Q>O9Do#wDPpeOsA52_V zg!$fc6h=C;inFf7m$7x}qe)Se%L%2{zf`}5#&1(?|64Y!ui0QQF;X4pPUcRr1wB}2 zBF6XBY07#o*VS5v)1ct(SlqYJ_88Le9XhL^49(F%4& zjqY3=BK&ajN;1&WEOpu8G;Lgw`O+8KU5v3RL!wK6u(V4?;d4O~Cppj9XxtZJ+(FBXJN)m1YmG)SRcI z+&)p6OhlRbzGipvj20!dH90ez%tg32rJJwW`p?aZDyXUWmwT(KVi=9q@5A;bzV?e0>GeJb67S2WgY7yM-UZDcv%ds_xD%By37Hc`n2k%y zs*^?G&o{g%|303^e;*TLxx@Q~cXQ-|V0XIAd>OC_{PvdDz}Qf^7aX+k)zAIez3ITY z%x(CW%)E%nrWY>W`w33jMRsnv(J%r(XSBnAR(HSI0|vR7nFK>lyL(_ljE00agdOI! zK*vV_z_!=&o}n0_T3r1bI}tnYtXPV%{WeV8`n7BpYp<#0i8@43l zgE=}{`N|zL5R?O5qoQ2`@1)~t3lvbuaf}6n>@c!uS6wHVena+XX|Li9B@9C#| zYB0FLouaT&u{&)N$9;iVAyaxwwdl1Z^6dDg@S7#pvWzM_b1~M-WbEGf3nZ-yWgt-7pg|;T~A(hj?IHM zr%S;hzc0N*F{<>TTz8cTZHU3iwR(1^`7p+ROV_O7qOVMVMWy@#)vc?)*kE>UK@ErJ zD1g60UA>0Z4ETJr!G+4&^GKkTtpe`!|XB6LiPkM7+R6 zwBWmOS6oF8{StGcIUqN294(kJyV`t+t*faisvx_zw?%K&`tb2qM>A zc=(8pF`@$-0`Q>YCUjuLv+y~`9BgR*JRmQ9wJseE^+<=L$Hjodm-;L^;z()UT*O@9 zrS$z(u|cF%eykg>#W!AHSM4Flf7AebfR4{qK~npiBmSJ@%qUQn3WQ||ckZlK$y%SP z=B=lp_4@;T4a+MB+gvJtU%ONCQMdq-W)~MMUSQ=__%5&)0f$crEn>D2Cq>Q2G)6e06w#ioeJ7-jJxxJ7bYp za=jZmWrn+OQ@P}WiN6}}q#=ja8PRDm7!iTSALBLibobfE&p!F!qh}wFtgFnZXF_TH z(rxq2YW&ZTq;tqIX|1xf9-A`}boZeK;Vd9{m}S3yel_$K0T~w8;!4bTcb|zHaU@Q} z+mVJs-C@_arfS`P3!zD6;8Zx>p%KkUv+J7`8oY{c^eV8ANktWksW@g%)K>K>ZZE)N zZ0?3p9_|OK>YT!0M5@u7|GWf3hj`;nn6LNaaG?5(ga?uwC;>Gu?^jp+;92-PDZ~Jy z@nL(QH6^v6b9F$mW4wmU-xX~VfiRzv^aOB}gF(Y=f^m(1EhgNm0_%b`^_I_u5DTF& z3&;#ZO>XCbg&Yf^B` zwopABEl~Ys5)ReKCk?JIJdwt^C%^!^1=dEa5oV)vuH>1d!$#ySPx`Q{$JhUJPZQnM zR2*!12R37W!N2eRi)?Zos(jb|K8IS_qx0iZ^^-XuamJ0_1F~GS+;VMn${2c5TQ{lp zpFdN6^ZGQqa#!*hv(qzcxOF9OnP3fP0w^_{ZH7dMOa##cbkz5-S9GOSgq=D0ie~M} zg3XC%J|XF(8kSKe6m9Ba~iyVW85V8=GcHpFJ6z`cSC}5e;wLi zz1EJqw_bUTY9aPNpw^sltk=T2d+I?l?qii#n(^qMaq*e|b6==VL48CNTX%?JO9-W* zkLAya{ID&^q=|@|$GTg4r(NqP+xN-nOr2(*ku!SY8@O_^6(M>&PrFqQo;&}uO6KIzzH_%j zV8b7&_A-i9`CZea4QTDtnMQX@x;ZEqQ3XhqAM8@?~Ue58AO3Myp^mZ^GT= zVV`nqe`(U=QN%^Cwd>RYN2w{OKvcP8rSTUH+f*%gw-NR_CG^X3HNAYWcs{NM?H1Hy zu^z7C3}B|79`nv~*O{nteCtyhkKr5YuBiKG=F~G9>|%1ALkmX{=$k1n%9^NX+vm-r zvuFl6YX>XPxSPj=%3(w_Ic=}Pz#{&bp$bY;7EB7&?Jj&5r>9C}5rusuaEc4s z;yPoXgB=TCKM-V@WDJ8X&xYkjqvX5dCZowlfNJgl6NPu2c>?ttP_;E4o6x6l7HE5z zPYvx1d9)E@)TXzus2&n)XtZ_~=^Wa8mi^qX=vV&(Wt?dWutp9M^9P*R#1$mne~U>h zpf%A5kGv^3VyOpMh;_80Hrb3;J;ChF`63#|2bxD_(~lrsxtjtsa6EGh-?2DzRt~(+ zm))-Oi&V56tJ%{JvkP3lVe$7(;&u9MXQ#zo?U*4U5b@J-rxhd*CUugMmXjmkWKeZ^ zBMgAmrd$Rf9pe&aTy9LK7}MppfBa}5rh&%K6rk*WpG8_ppvdD;y;_)NJ&~@{y`2H6 ze6QueOTIG6SCo9Y_jJHTc0PT4ZGT?T&nq)m!8Dv05j9pO=A^VccziAJaRs6vJFB7% zit)QaN%Pu9Pl4zOvKXC+3xS0dC`3vHd}0s+Jtoz{D3r5gjYv)R2<|*me;3$Rj|xZm zAj@gB;V5m`gwYWwTFJKSxR2O);k)T=6F)WDPT(?5NbqL~PSAwon8~}J%Q1|7{Q%2| z=>y8FW#;?-`hr>QM( z#LCHoMQ}$ zyiK$v^|@~KRqTW~l<|1}ulzl%9rF?Gxl5&w0enl&4z~BN_We=6Dko&N~CqDaSS zhh%)F;!Ui|i+Gh6TxIlf?}MEW-+%v&`jZs$<^G#-PfZf|12yM3#JIq?kS1mLQYYB5 z9wC|g_5dg18CgM3g}R_OV_#9|`LzO%fX%9Z`~ zvwCw}A9soI_x2~H~I^Zj5LA&6IF5e-UD`)JQ9I>MZ@%k4a zd6(QhH{*(=pZj#_T>00^U2$&QxF_c8&vHuVouz`4bkBaDf2K?g2We1ZiW06gtp=4? zY)N$zPo6Ar(oLT%Y_!kN(FT@I=MjTo=-7y=`pTf0HwIApSqE(`q@8A;i;3F@t_eHM z{=?nC^W{r%n#;S}WDW}Le`xI3L1f2yezE@k^^3OLzjNRd zjM@57T~^rz#;(3}Asgc*?@7@5|KQzK1UV07b9Y($*Uf@a@#?5jL_^{)-2urytJAZB z1()pPhHkAvLL#Z?qtd(pUKlc{ve_)8u#wz%RxoA&ZA4`pGo#x+iLNOY!_KLh$k;F{ z45Mr@=QMuY(!dGeNa46Ci)3~x88TNF0Un4r;jj;ZF#@zerj zBTdqqcd5`X*j1_Fl&onZxQcpFu&-ce}H8 zuj6<v6_QS+JQIoK&I;Lt!nvdsf?|675n{cj=&E`e9*Bw|}&r`slE|(Ol-8KPAf3r?K zyq;G@^Gyp#o#e|%3x3nqK~JiR0#!nhXP-2=7R}0~ohn^j8I@_hCPn-*A>v?Y@whg@ z_c3Y&-DwdkZFG@I+n#FM)0nfBNx$;WF{Iwfxp!- zv*^8{YXDYg*@jq8M3y_Yc|tT$rpqMsf5n*k$2;`A z_PaLh*|2#A$I04ZGg02{A;x}EgYcs@a!|?ye|?1T#i2gBoqU+|=3(SZCDjbGf;F4x zgfSakt@Of#DUd5MspXn37R;K4xhyR}+dqLO5bAsaO_#F2ZhZ&UX{DY3-TK4 z7fZ+y3F3+`fCUcff%@3he>zo(Gg*nAK6LVXT;IdaFMJ^^lhV1@q0-&l!Xp#4yZ70k2xiS1g2>!RL^^3pd19P{&eF1ILDG5;5Mv#cB2$>o zJPvf!l7YwaEt#~?8ft0Xk#oE4s)*Nb6(CU;d&4Q#NIwI&azq6ce`RFRL7BFXOH*Wq zeFNIXz@Ts;*3-gG2mHemsVog+&~#5zBnL={hEaIETB)58Igcn44^$$Suup_Kg>S5i zs3;FnFP0{n%?2yqjfq%c#Xs7Hjmr5Y#TOgd1)cjW56f$)nZ^X=ato|ny=}Mp+nW#bOA6R#%}{PZ3Um1Q z)A7&rZanCv%Gof!ve# zV?>79WxF`MBJ&J#CWk*tPajjM(}UCNemXfl{7apjPPUKI$9xfXQp>aH5S(6fye2xw zCe;u8T14(TootTk!*5_@)_IU}UDCl$PV-;3Tbl!{tjf4Y_my04uGDAu?7m-QWVhQ> zZZAme8a@8ynicR;`&!1s5p1`*{mMzNMFEw#Q%BBCCyubK z_r^WoUQKt8Fl6h^0;df}JunciRa5fme|Ocg9$`$ALG=#|_@}V1e7h{q zM)2ycaZ*0J_)WRmtZG!f3vAv>-pt7j@ZEJmmb0u{lhT{2m4RD@z<2Gh1;+lKBHJEB z`e+Y2lU0M~m|u2+`&|YaZLEelYsl925S<6mY65|gcz=Wl3Cso2a2Mq1rRJn$&KZe} z8Pq0vf3_5j;qTEKcpJ^Roo>z$@j4xb=*P6rAnA6Asj5)UF~2e`C^_ zApfX$&;u`f`G>6HQ%1!(J$8gfHtUxMnqWPC@@19u{@m*$Zrt?r^x)%ctA04;5oV`L z5}q=*!>%UTwM+JM40c*(Kv}n2f_z(g18L(2Bt4%39I<52>gJ_7_%*@DL(8y)<740o z%qxkC1kE1WHVH3+eUp++Eq{86a@<_{6)E8dDhy_19ws4ej!`FtIUtQ&>&eiY!_e!h zBhAGfl&+E-1^tiE(EN90wrZqU^CDn3KG+`eSA~sLNtPg6V`JFvHWC=k=J3*^Ic-!3 z^-ebm8lLp)Ya*_;XR7#m9#Wr{xb)AS|3sxm_PO|M^8_|hZ>uZu#(y3nNBlf;o(QirsG6neJ1|5)}?`i7pVIpB+w1;)| z9^+1GXjx%;LB-eE8GjLSPgnC;zaLZ?aHex_sb~<2I$_N#ElHsskfX*2xF{YzJsb{t zw?`DSF8Kd?Ofhlm9e8&}TkUr9zcsK=_n87u^Z&QUJLB}Qm1#RVx7I|unw&PnzlqHq z2NLG|J)}a~K6xP)oU=ueG(4#wmb!^XM-t~9r>@3++_p^6RDV<}y9z&--t$~N>nSo^ zp6}a*$EUf9JF?w|Y3y>EH6xSQOml$zY_@@=Ofu&Zh&6tPe;{mGMq9HdWi#h8xRLJU z8kKW||G?hxN&7C{jp#M6B6KC(AsUkhRiz>*Z=<3#VNlQk2g1+h!0=fpdyLBhoo+-H zICaje--9f%WPcSzF1BuHLkcj2`fzF3gr12Mn(@S#*65^h{s=)2S0$ZL{OtpPJ2*%;}GyX_mu!jk4S zoqzPGhC#-*&u{B238*{VnJ#~~yx{r39l2&tFzF_}^wtnknCeaB^7DYdqTDm)^8@d2 z@=2ZRBO5SUty7)oeZ!867nqdp(T|O8Y_lhXDLIvPGLOF0(2@14Ms1|l@~Q`LJwR7S z&RbPVcRPGEgaRGcF_9zvb4yEcWG^lWS%1SjvhLl%8^-wXmjLP_T^IY^e>QjG`-g#I za+=3oF{dSfmzCME1zW{tR&49i)17z7eeAJOMyHuXqpBiale=x?+~0{>HaC0ykD}+F zLV#7q%>w9Ff2VYGv=dgJXnisPc8AXfBS<8xX9O@vUitSAwm#!)BxHUF1006f-hUqA z^1RccKq2}cU{HAYZBw~Ayozi_j}8}?@z@s)WlGfQQVz8I;`O=}W?3MDDmyYY14~Ry zXiF-T)G0awjY3=1yKz%ZQe!>s;&5I{j$tBg-f~c?K&5#>C%ZoCBeZEpu622dU`8LW ztNDuZB)PY#-Q!fT&n^5N6cxNutbdGz6xzE2`=&ds^=fUulge5A!VmAhjkWSYY2CMB zBLQ~bwBh#@{MlV;^h)D(T0!pGtibxG_8VV8m{fwC7n&D_nDxHvuwARom}dUB&2|j> zn>nguHf4>ULxNR&B%zd$$4H~CLv`Yqb5PwSEakFvH$>{4EuZ5n!EbyqWq)PtqQv-{ zCYx{4QNm}E_>B*6i}G$Z;)ur<0~hyrumgiRvd6<+kpZ2mGvX$Xh#MGpIWh)6cF1)F#90G=!(k~D&dc;(M-Lvhu>F~2xGiXHAX}UzxpmeUZbGY!D1|yKfpwH z?XNWT3|Ng-qiiZ7skRB=h<`SaOboo`Nb76Vr06%AH$SFpw-F|#RnDOIFSF)XNL2rI zUq+kI-Q*^;bllk}cD@b2hK}6L)r)bpBCXZr>hU6m8*I^m=x!&;OxsOc6ta#B_+BVC z?Pdn!FiaDeSWD+`J89+P{U-Ry#fz`SfVFzbRb=FBf$bmnl=v(S;(vrh?(X#NCRyJ< zs&=wJ93@@Y4OL7cjTD|jq=dU`?=ob?_zu6TYTA5tY+^z3Vtd0egF{u<4RPT@9FL#Hd%e_%6;e@KBxt!H+I`Vll(d-KNS~TU z{zFOtk9gO@QWLRLTuU zaY^iV;p2@pF*L0jum$N_;1xA!!2eLBSQp!uc(AAOXQ23Slu#a}lD*;jslBAY) zdDc?_IkkV~PFO6PADXDHQ%2HDvxkJ@sY%bwfUjvE1o5VOqJIVqW1=zvYC!T09aWvp8zsNW1 ze0lq{fA59GPn#nlm-Xagw9)}NOc?#o>Ic4NE&x9NoJln2nx9QP{10-f{I#o;#?3X# zRFrgmj0p{%X@3>GrQ~mu3_mH||0Omw^yc(uL4TI`!z1nl9&{%tbVBZI=kiK?n4Zk! zC;2yET!|0jBn3k7T${n44rpEd@aQR`Z2XWfu%euw@$qUlea6^az8a+TBjxaU`c)xz z2Aob9r#0a;98+tQe>^>nZxn#%4B#d`(>#ABPuyvuvwv3y!wz_#6}*aYk?&EEu_6t2 zD?jg0c4-J?X@f*2kNlE;Wf)HOyph*H>CG$Tesge;e&wuhpa6WQ-D=l(1JigHll;PS z-7SxO`(h?p07!X-sd=G}@zU;jmYAWS71Y9L$hjPFWD~?S(P~M443=T#C7->Le8pSd zAL@^r<9~`Yl?{K{^!wb5xy`ObVfQSWa?)Dy>uFHrS|ucT3~wtrjps;NlH+Lv&FEcfL#63+?gzDYbs zVrt=;D#=X)=@^5uoSctzMF>MBt5<`G0y=unf>{z2z&l=B7Y_v=9}M8LaTDXWj4{R6 zBv7ra__T2ttt4QHPqtOMcUQ+;&k9A~rmKD*rM$H6nqQ9`D8aBpfUiA(CYV7+{rs82 z9)As=9zDZeIBt%4GI#>VTq&PFJ$m^Za)e4#vCr(!B(WKVzaOkS&dttrQ-ZvzUoa{I z;wzFUbl+Ph(86gTYW3xd`Ld)$-MV**y?(8JexiPUqkcYmZ1{7_K^|}a*1N}pFaMz# z3hUJYDWvOHuU=XNr5sGwuZBM!PA*5^!hc(Rgp_BK$J5iz;MtFd2lTUeI(v*=>6%Ra zlbg{cWqGc$JRc4Y_-9UkpPuo{vjzRVc+M}`Q~vuxyXeq zVi>IudKz8~SA_x=K}_|XZ^@b9S@+6+fS`v21)2Z4Zp zII7{&R6>_>???9i2=7lC?@yi}0e{&5M1`Fiic9?7;P*@(VX}ULnfj@CFQ17o@;RpK z7veklQoNBrMp&TXK)jX1p?EEaN8+6vJ`umhm=hmqQvC_KRQyJwSwEM31UbkKrTl4e~wcANSom@oVu>{6zc)7`_cKjQ`_) zd3bH)d-+ygLiPQvyusg-@8lVN-hKD+xAF-dUVkT_(#MZKm(TF~t$a>zZ%^b43cCC5 z0}uDX*^8baOY^tTjencLpMRifqhOVR)E+(e9GlyR^_k_|Iy18mFK>t{_t;#QNW~_a zIw#Gxmeu5H^jZ8g$)O>ckD_pgK^D;37RRLxvM^oDp#^vjFdQIAlR#S)e+a;&Yd;zso%J{qQn;HtNl2A!P$w!T zY8p4~ugmf>$HIyZ2>d>;5m#kY3R*F}g?@`u1e@JXu%8`q${TaXULEyj*dMl{OJsg@ z3Fr{KjN!?e49jWCp@S3p!1{-J_+TEciCTaCGc$cV zdo0Sp7HqZ}j7gWO{PlbV_j!IdN5y_ys&%c)^gG}sD}Lu*=c^f=)%xV!TP2O==RHp0 zYx#dse9r3}yOg!Pj3}>vyI%ezuWU&BN1S3`e`y~~_B0II)A~hm0fgkh)bmp<^`7fI z7$|o5a0>5kn_HtzxdqaGoe|k{qhYGZ;#(6w{lV70hcH5_pS;p!(_Gs=fwZ ze~rFBbRr_9Geqj6aeD|j$l(@am=O%doLx$7`hrX|q~Xr3wXyOP`QmS9jZGt)lQ!Hbo(C z+;#k(1)1hq2K#S8T~rT8UN1UZ$p;xse?(s&Obe7d7^juAd=eeoI$YE1&6zTJ!)0m>Wk=v=mX6{XN^eij%OhjC z2MQ8zb(QX9kImYbk;!LLk1A5Zbo`I|W!C%WeqV?=m}4;xG4xKlp02l;riVjJ#ylzg zSnTodPx1QGpPoFQbsdA{dt|=Xf5QQ9@?3z-V{#`ggGf3_7E))OY`D{vJMsMNeg1ch z>;60)L8%mOIZb)%(#$^|5k|0O z|0*n9)g|Y=aNVafO99$d18wOtJfbnGH!rCr6ZZ+qp7MWyYNUXWe}OU`-C4o@Z55!f zUxT^l@vHHq669h95_UuIG-c3?)-26{aR=@B-5c25YRhDZy3rx8)Ew=Te_q*Ibj*+#IDDU_?RBfm>t>CE;g4E6*QoU#PR;-l&W~>E-{=0g zLB}VufQIf9Iv2E%*Y^-X)F(LgRO!zCg!Bw)y@O8(I?{ac3%h5g_;bo!Sf1yRuk@y)`%M%54QYqLDfUKRcN@e!7!eaT*e z6$tK(r|>rdfBBSOP7I%Z9~hbScg1#I+S;^I0&jXO!@zP3!)0}FAlA($hdfnb1=9c~ z9WVwwS<7LcaG%@>X>>;pRDjxAo!KM;`!L8BI`E|m3dOLz8^I((x0-(LPc3BP{4I>u zaDG_#Tl`|3g36{-(6?@SlV!wOYc+re#|m|3+OE){e>$BVt{-U1MI~`7u1&c;@Mg*R zRMq&#UfyDJr#TlogUo#Mh`G3ykEPiu!ltrrrFs$>E~EjX8A%=W0x zm#Ca}5&TF3u1a;5;}f?|G#X_tSkZ^B*dS=&ZMQnmi7BgeLy&bJdGsk*h%$@YGE?Ed^gDzb3SamIwVBeRQ&%gwk(|MA zo zsw*T{c}QV-epBYfx+Yt6I%+p2N!yv=@$RRX{tIQIk6UY4B#n2oN6|ShEz@xlVt0q2 ze|>%=xhcNeT%BP7_v_bx{P_FVZ+~|ZBv_z^lmTCJa$NVvx|QyN%+%Q&Q6WV?kNC?t z#HxKft`$mPC&D6)x~<=VKOy)r5pvm}s@5yR%bv$R07LusEJ103P`!N+yBVf*C-JEHA4Q30M930s2 z$6-WJ$1V#}=e^d3J4EKZShcXbn0Ybr^sehf38o+I!rt>`D4+rhogDbG#L!9Fp zRUB299!IkqS~qrn0`c~8Ua{+Pv%DaWB04$!zFe%ac^f^iRY}vqBDaryYYHrm$rSA}e;us7Y-y9E zc}+XSbOJkrl3>>FZsUeKM+a|3Kc~he6h{iJ!AWw+)lm9|yc}PA0427EMw#gKy2aB1 zX1+9>Q`a72>1SQQol7zx$oiBrR5E3Su=o=?G)fM9FilsG)j$c5H#_g?xU+N7r`#MY z?AxWkn}5zPVM6&sjxUAIe^1Mpkb?%|ph!p2biS@BGQ0k#x+dN;W{?Yh3VOxXY>Nir4T_NAMC(^x5Xe2f6*N?&@(j9&JuXkxjkH$JQP;0_Y)#MLsGNRR76HgPT zK#h+X&jl@qG8?Kc2whQtn337wC+g;UHHHLP#M+8aC8;JFnS4jvsD! zI$4qEy{~w;y`98czwT;!ci-IEbsbCmI6Jx((8IZr9cpi5e-TXhF#;E!Zls^vEW%PF z3R=Yjuoa+$3i?lyHafh0r_6O~?#Z++hx$x)_3s%r;#S_Sxq}bx!P~X0wU&El-t;~L zLGk@D9-<5%@(g%_89kzrYL@9{>9EEBVU~VW!??#QSrvDJ4$%31FD;rGnU#R%Z+fl<)Udr@&31S#!J0er^i2ataNja^G3J z9if*G4z%OJ-54Oh%8LK#HCwBiKy2r4##0(|$?K?JS)a4`K!=3h?e~)u6GRIYsewoI*;Xf_H4SgRb z$U_O)50RZW$-+kVRU||?B+}*ygbE}dj$F}(u0%ELvb#UN} zf4M}|f6LSzVbgnr%~ksZT+v6Qz}#NrY8IEtjn!k2s?9O&jF!2Yy47G(FAX@h<<6W`^Y*~i)OU;dcKzoF*c3%!tH-dv*^1ItG6ovJW2tA@gdK=Lc zr}{ma5k+FNdDGZrBjxLGfq~qn7VB?G({alsI&_?7{wA`_YM zy_4DzezH9e0`@DZ;h9QzVP5^p@=^9g)bYDj z+?lzN)bSR%Zo?ug@8Z zP_4PTuz5k0$i66(p$p=wlhJlGu{ei^fxgHTrA-n2d$=|sNzFd=kQT}M$}W>jf1Jz2 zzYaB-jFMh|+3%&>V?|H}MPm}53;K#Fm*R{~S)6-r*fy*T^9dui|p`)Mo zu`voNoJ%@n=Eb1qi%^Jpe#SJmRi^^2VpoRW(mMong8=)or;HY8{ze_*e_Egno%E7( zk@w}fs8sSYb%cewYoE1}Te--Ww7ir9Qx5m?0^laNPnFMNdYExz^l=If>^!k;Ku##@^ACHVjX^)EIxIoMk`PcI=+^fud&1pww+rdt>yT41h za?R1kTsx9eZI{#oh(Yo2f6+!N-7ST*9ir!p=~wzRDg+Yvx}ira z*)};%y03JfkYMhOGKUIG-JL8Ry7svX`vFMyQVQa2X3T-$;88ivt{%b(5KRdy)C?Sf zVmhJs6o00tQ=s2QSJa}UxV{$cYEsD!WWuaB+Tf9*jgv1Mn>L}Pf%eE9iJdu)#WKCh`Q%h^oHSpf@E!5*Bbknp_ zckSe@Re!XE7?7cv<~X+Z^uE8oS`j)0LM7y64Mnnj)?r-qe_%2KfpBD^^hDjzswxC2 zWLtH|XM6E^sBqyUlqyf$GPF&wpFbB18r4hi<~jcRWCRWRR*y_X?blZJx!f2Lp@^`O zWkc5z7bfoboak{Sz4}O~TpfHiOQfZOaM|FFrEodY@h5$a+G_Gi9bxOs%TdCqP~jG8 zmim-hoL3s*e@nQ)8<}*2X5Jjnoj!Hb@2gw$r#Fx{emo+l`d!Ex(Ft!ToU55ECo5^6 zlh2~!nDQeeDnW>h1z&t%rUUiv<^+sMl{7LB31Fl_hYIv}L^f8E@-^5(w%edNVO?pbx2k*_Qi zQ`KYp)RFh-z0c5+Y=3{YE_kc-Yf!d}TbrG~(w)y;ugk8`yD7(Vmv$MhLx7=~#H#20 z{ws<}{_5yQnLRBZc1&J?cXIU2vMg8XHuSvUYuLTj-dFA;zVLFi7Gw~o=|vB!<*`K| z+CbH;f95Dz_T{s|AQjyB9_GhtfeX>la>oxOUUY96!5V@$^D*haB*7>W8lDa}g_2h+ z%$U)>a&u}Z`!zSit|W?41yfL)FtYOBIxbE4U?>#5GlA}#e@wc^$4}VQTGGbWM_O;x z_gXzaJd9=ItaBcE|8w0^b>#@Uom#|Zbhzjvf4USEv#vYp{rM4Awb8ZiEKp;$k%mEs zm-F}mM2W4k)I){hf@b(*94?wUjZGRk8rmkbGN+)Kb#*OC5hJdzSv27|mXUR-9^&eQ z^cEc|#VR}NRByiNoa?@NNCp2Y?nf#25*GD7qP+K(?)-+Y`)GQ#b5nSWeomKjg>>c& ze{0+bxkW*NL`)33*i}dqUb<(gtuBF8Sh*UsVzy}Na_E*Eaazz4`cY=eykX{`o+{Iv zha-nS+ch{MDfJSgFy;@|x7{F`){`EU?TvbR#P$Ha8=Zw+y*OeLZZkpK1{s#{s~c2i zsLjNp`N)4o15)89XzV?W>V(qc{o#tKe+bT*j49#Rk2G>@yS0HMA%3l30wj+;1jI=* z1<1&_dT+Hd`(%}`-B4Eaw%Xd?^Z|4EY-B0jXChcxw$X6)di*B1zc(_OHf@b zSXpXWc;+eDm*iZ`u}FXoV18Js<^Npi&G@R5q)riYJ!lj4Ks}_>RNpjZ(OhXPe>;eD z|GnQME!+sPIlXMRrUq7AdMgBm07|-mbOrU4Gw13+0Au(vh^Y_6$yhHmo4eGS zp9u6(fYTl98<2iwzpqeLLk^acfHO>&jeR?Q1)0cFY^IZCjG9Xbe~EaBjuEPQ_GB@02Wh)u07sD;#?hQ0fAA=hMi@ns*(&R< zko?xc_dBn#H-)3~0He%Of8nQPbr%ufpry3@4pO}8 zK*%EyK!^<5V5YN1qNAq`3ciwANJ516{Pz)Y@DOS_ube6?6m*|r{~9FtvEBwOUPwD7 z#T~;P4q`3aScpP8hZGYz-%eBRh7!mu)8PosPriDh=yOpv>seuD3dHbq{=Z=h`Lb?} zuDhzcyRGo^e~DMo5!mU@-eB5v*Jc}rX{B{=Z;cI}C#h9(uKBcNiH_$^6NLfe{V+kPxQX&jqu-2e2VO29t^QF zc;(_q(Y)S>7M=4@TzZaD`?68OeWAjr+`W&wGVYWVU1E%yalDZ9Hda6K>wL2=X^~aI zOY_?bGa&rAM+4y}LmXk!Y$WO316bw7)%@lx3n9342cnr~4^CSsA#@DzRp)xlx^y0R z?x5!4e<|wb5uCOAm9R7(O$VasS4z944X4q5l1~PsVLC(2z6$U3`lNS;Mv}Q&-zJ0a zUMNMz&{-WfvWi6v2Pfu@6E7Qku)2mO`xTp!aOE`i7Jvvm_2Av&K+wWSB`+Dq`96Ta z7{b3_@xT!1P7kNOo)mLLdcR2QnV(g%6z2ljK}B!ZV=xymJG`G4s$Up!w9Mp(Blzre zcbXax@cDG3X*h%FtqP;2ZMPi4Qc-UL;E1zc;@)V>Rs@~v7OMApUw4zPcNl-~d=g_{ z)7ytJ?GPKwB}|Ubx)_zX0`VU$FlKT6Qh`F6@e^baCN#P$&N0%ti+2p^YTq1WB@#Od zz>RoW){KLgi`sV0#UYGav23=zVRLuf+^@R1rv*%|{7~W1Yx*S^WlUHwHA6JmZh0w7 z|Jn}K%*A1J=)+8-LWe~GrVoE4xTE+DC{6_D?F*0MUoCA#K=++x<^3B&OQJjDaHbUk zj0_d;H_7dAyy4-PS`zMGreAMumf5X|1D>b+0asG@a~;^jI2JbK6?Iepy3apn{mW*b zUYj#-?h(CwD^_%uTtsg1YMaGYTeOPY?i_`(C0CTpy+EoQi{44B!We(Cs)lg$A}`S_ zUV2@h`#$>i#j(JKIl%N?BST;0;|?A?IB2$?oy{MLP5O+&PWB~fC=HD40V$(4e=dn)M zsJ%@+7L&Pi4aEtZ8pklwdyY`%uu_z&Q|HE&AwF!DtsY&dzPyl2uP+xSXy8zo$5ecd zW)TZFvc#3FeEToM_8?q#es&}Cf;8h(5abGuuNiNP>SfIpJ6ENF_IM*Ht3qoVD0#HG#r=&x(J4~&gkN^$wm8mOtnvjE)_!=W|; z%1Pid`d*%>>MqjA*DvlX)$)G3{nD=aGtj}ZupW!UU5eG=saYF-4(ay+_6OVHM>A%k z1kT6hcKZQ;0ZCW)A#D~01qM4`X}+G6{W31Vx(BuqV-J5H*P?uoY@_S@-dz{imt8@M zV9z}DXPMgs9lUZMEa>LMOWk5_Hx8!J``>aVDn8XgXGxoZ*j3Zjnuonod8mB=$0k+F zmI^R-gMXt!*gT%5yVIHBl<=Z5t}C6I%IvW{b5cEy6ex5HTKR2g*$V9TN#$>h5FsK4 z`y{0)S>1m?@L*ERQ&^kYCE|`wZbryhD8Qkmij^`*aZ}-z6FttpyEro(Fl9SR)+$z9w5 zUB}>?8GO641KSR=$Hzy|>=4_qGdd886Whx?5MK7KuH1<(?c3j?it~On)zm(;!yq(& z1V*^7YN1nf@@A%AvXZrM|__25? zj-G#sXJR0Z=mALsF&v5kCp{NONEJ`$L(kH8H0Wt5(xnYsY~>c#_* zWtf5YeQ5A7jQord;XdHO^^}Q#ityQ%1s$mnvkyJd!wXK~_7F$Ec!HD{OgUsfG{+) zk=L{uuk`keliz(Ke=mp%Bsoa(Jm;F!5LcAsp#;dF8uKHu4IpU7eF4anPWU{1N>vgHxGHoA;U6n;3L3m%c}tx0>?O#K@`E3vFM$bW20%hL0}NqK z)B|1sI3&30{{$Q0G*b+zzf~vms7Bh5X9ubR`2h~3WPU>3%xMgshYa;7;SM7603s~# zjE3R6D#Oe{f86vOAX${4f0%=H4%7$EAy6zHfy~oqD2*wHh6W>s>VPitC_35U- z*_TJDK8KR`Wi>5lslZ=8b*|GvKzve(P|^>{f0!;Nf3Kz508&7$zhL92JCyLIyfAL- z?A=_ax1CLUNF*204gz!6F}K^idwfNy<(1Rvx$|(3Oh2fMPH_0A_5h!8*@?F!jre10 z&z-PgXdLH;NHj$NeEc%2#TVN4o`$8$`qp_Ve zqFelV+Usu|-+%RCM||{g)+lsb-8v>nPVJZOmvJf)6E1sU}5tWV(=4n((Vu@SiCM=3?O=+6(8omqc7Py4(v ze99)5ll9gP09>+y`+c8~0p(DCFAcC~+g%+aq;%S`&i?ds*PL)MJ@|m$_uctaH z&lY`t9xnwN*y9p_+$F7QKqQl%}cn~={F6?qn+Xn}*fw?%X+}^a(Vda0YK&)UVn3_dxDQqNo<&4Sg)zO5@ zFMke(BRoh6w&hJHD>%p3NwoXyRWTr4IwrsKgW)78jyEt%ZDf%O+6Ypz2Pq|Oex;+6 zS1xixaw46pHEj;tDjC9ws8L36L4n=!4L6fNabRbJSHR%hJYJ+fT3|aaDJNH>&*{#e zXTJ5MZiAq_An+6o)!?_KMx&P)x zT(w@Jf)D6|j*qo)(L7p`(6Iqu#D(hWyE1;3CHuF#Q~tVX%3;q1MY@u8be9B--05K7 z|ExvCGPx3$0{`_jblt@!PDv@7CwAcJ_D@jqpKmcH;eS(mFM{?0cD%K218PS$Xn!rD zFcAtmb8FvMB!5?4Ox#cMph-pT2>VGklToZ_++>$)M;g{SRHI$0&MIv8&s|w5&&jo* zxj`v0|IP`B%fYYycaN3BD8|X$JB9aM_JtKUrS+)kdc$HS@U)=4E)C7V}Hcg|7%vo3erNgk(J!2e*y|!;<;{=XoYg%LTc+e z4EdQs?cfNgRt)1=5>0CjKXh=h4>ZGXc%@KPa& zX8{Du~DjV@G1y^?TiY#_EkbYstY7q8eyPYB~Nsw$rk&cXi;XXv9Til!! z*sGFQ(1}Rd5I>DfQ&e|r;b9Xy+Tsp#<{hzAz7_~rGs;YmS5d>KB%@<(*?Ks+OXX$K z`$d6<_ImyG&O*vtPDp$r8w)9ZI(F+Zqwe9OdpX7|$r;U@y}rlJ8D(z-q}zj16U^N11(sUpMhHn8ktaEj&`~DTsB?hN0numCC0M(~0ra zOiC#S_Ew@1LPC*WzoxR)D7IUjGA-Rbx|=3)Y^zu3vFzL9OO+$V&<2jsVOGk_#&H!pJ3;=>@!$@_G5O%F`Dna(-j_0j{r*# zPw4$by$Tv-uNl>jKqaNQXoz3U+u<4P1Bn+6eZJ-kdmvf8P~uii>`f?>f4Ncn3gl6k z0XQ_btgIZ(nnRK1e5ysEwA_zeTriRyLIm~5>OvLYLlOY+HZ z1e3^*+|}!U2W#J{xeT&s!O|SQWaZK+qBhG9QP71LBDib!97XIN+Bbs(27z}{# zej``EZs+SKg=+AeekLVE+HTZ+rgXQ1?;B|%Btey4otqsx*HfLU()lu9nN02uDTZV3 zt!rKj=HKq!1=dJ(tBP=c@STBV{cNyl#}znC1AC%>9v$zc?@NQ9v1c~Ry=r|n6CYU8 zhV<}h=`}KfaXJq8zUkS`cixD0ruZB&E+&;^Br;q3ZdA!zdjkMm>=~v@rD)Ae`V2ZdXsqW7#Kw z=pQpM7Sa)}FfgB1|i!g?kWBL`34g?bD~S5tsUcOK4vwcQ$2*xO{$(7&g2 zGHZdLKuUnv=VnI4@@>-y_68l4d;tBG<{ejQks<+*t1*lVAl~_;>8p|Y_AvAwvMb`SPM2o1#!JYGvtXa~H%UjTHITANM+x}% z_f!l@#UzI;coGOSE9$47=w)z;tdiE%-YeWH&8$8Jd6JwX_M~wi7|+(rl8keIw{m}P ze%c>Mk$%T22ONnVsZOO%#^xzk&8X%nmqJvj;d;%FQrZUt8S)vl5+{vfDm<|IO7dJX zfIZ(it~zZ%!Y6W-v}(Ex2V$!Z=ggJ5!A zixgHrs(Wa0pa8o9f4_cqgrb<%>c|xN!QN8d5p<|G?KSJee)pub>iMLFqKY@Wu$$kVyuuDZt2VHh^sx%<9LvgTqh5)MP;&6y4N(I_m8 zWv7fLW9bzc%)XYmKReK2lfg9+Yzd6c4M0H4fR_$42>u_128SyQX4~`&zAzT$2!VT)N8KGe8 z9lCt5y-H3oyK`zCVM@cg(q;l;-u^$igd!|r6-8I3EVNE+8imfDv}`p~c2#cL9J(n^ zOWe@;Y4tMHH@#}E8Ni>G*aj`|3T3eU)-zdbMvFC~)vugDj5fm3Nkn&Mdo)~daW^faTGQID~Tdfuwu@&!rT0}SB|4n>wTl)T9t>}aIt zLWSpVYB(N=?p1=ly-E9|j$at8pAX%VR0fYBq@W$Ld&9ylk63?^v%x5jNzgQTqeRJSuuP z1cmVECoG0fDJTaTcV)%C(EeS+HgBOt#xQcS8+u^x$yiynK*fCC7WEvMXa#C-)Hb&w zwp=Eau@Rbozkn+q`ZFSA>2ZsB`QnqoOh8M%;;qUj*9Yu`}djfSB$`E!A=;WST`xX1VvS4BPB4&t;yu5PF%hqPNa#;(SL85*^IwR?OnRRu@=FuMp)k>NXbG`Y>lYaN>h%`q zsl--fu&&6-Bh|}eSF*+Cu+!$cy5S?81XWdkCz*K-o(4EEE$K;$Nd_<0aa!9wozP^p z$j8_`B9;ZYGn2WKtO4b?cU$rXd-S$RZrA8D=9u9XI7bf6wUVGgBg93nEkP`ID34=Q zQaVF!9)WVe1=&SS(kq@$$2`y#H&|fnJ<%P<0L`b+U6&Qu9FFW zKSvf=eu5k%7sWD*vwUIc&H}+h>klJw$G_vnmWLydn>WYe&*YN=k0+AOr@LQ?Ba#p0 zojzyc(&kN3!OifR9uRvHyV{n2|GNvDM~KlrqH4z3$;ZMJM_46No|JM|EUd3%@ zZ{It9yblu5nh3?oI6lPv-VGaI1EosqH`OWDX4B+^a2m>j#w6IkB@E1za`SP zZdc`*-mgj*f_bB*^NW(g95Ib@>}6gM96sb1n+=B9&&11YS*Q>QwQ(o@0iL*_jXfPL z)F2mZ4Y^~{d5xpm5~swL`&aUF9zJ4^MxY%e>&P2Zq{s7rbr}A19e}tn9_(i(XSrQoT zE&?szzv#-tDBt6-(Oe8_2UQP+#F{1OGj_-2E$w$hE95hQ3c2_9j3oRzcd$_%e$m7W z>ib=X6*2v8*?etxguW1cpWr>(wYI2smH2%!{|~7qA{n=^lR6LG8lA%kHJlO=HD#tuQ61eOEz_P@N*=p& zVk6X;8X_52vZT9sa3b4E3pxb7$YJ@@hvr@1`{ENF1D?{xZ@Ld)i=YUi4^JH+3?d~^ zNx6d+M%5Dm;fXCM#XLxVqB>|PA`mZA1NwggU(h9PEL}46cB$BBTK#aHiZyiHClt45 z5t3~?@5}99#+<>ZI^c+^S1sKQ=?PTvey7|;ZK_5OCPX%&4Kxs&v)b$KXcz8vjpsnB z)mZ`rC?*(;X3rTWjJkahUHT|mdu=mK?4cz3=bu z0f6^+vjPHo$B$H}!@(XR5Qi=(KtvEWbLV>14g5X{)A)a*P_V!ox+%Z_W z?szEt`HXti+I0(m=Qq(@VBty#$gD@1;RPydur zf~c%$-i6ym4oWOxw@|MRTodqfdQ}h08z(=OaO80eQI8bjv+^LxX_xsjB}YADsOBCa z(KiF!CgC+eMvMa$;sc8^lAhE)z)c6y4&&Tgfk+s0Im(!SIY%B`dga7k`NxX;g2CBX z2Z62X{Ry;n#aj;pi#2pft2U6NEs}1lF0X_!gBpZX-^C%-MF3&jNHM4i(6H(pB%Ox@ z{QX4yKp9`6X++@**=K#J89eDNk1nR(m&7A7RAuk3j_AR4&dveYZhB1v z3%PI5nGmJ)=F+6Qv3Sc)4$OvH<{8AfrQiKW;@@}i?X!w(v4x}pM?P=rve%io^>IVG zc9&N8lKZL*BbPn`Cmao3E%oA{uy@4K>JE-7=md^`W?Jw4YJa|nowAg+0MDdf=X-vo z0bXBD=*Mw?e7eM?>iOdSzBJ5uvRn5{q`QDC^i%ew3}H{iio$EcWYB@p!>TdwtMqZ> z40F1qxIKmi21_06GI1}{kw3fnT;z7qzhZwsCUu&CNp2-lP(u$WkOKX><0Ct-Zl_?C zNJSNYF)C5iaTo5*H8jUO*J)4bu#EM|x%O);9S7@%vwT)~9B42i7<`Q%ijHc*zNLeM zH;BS9IuMIM(4e+mL~Yo%Xg)!0P60IQcy^k=%UpXVbjRO@h&rJOd^PeVg{3v3VJ3~v z?{jjd4>^z?9Pl0DdUfLYGn@ByisEjhnASUgRmJlChza{}{)RTQ1!i*4P(li0ZB?eS zfc5HMLq^c31jf)1f=0|hr3T-SMCz6E9pssdM)Wa~bynFvv5I8vjw5LSTI+aPY4y4l zU*~J>q!u3wxL&P~YgcdJo4kWuShGNAPq1|L?w4sF8Mxv0KU_)U>u(V<7mI?&UgcVU zWgBi9Kf{suz9Fbyt`hZltExG*0(iACoWg zV=w(Qp-t0xC$bc5FR?R4+?ktiajxTkekE=eb&w^Z!b|Lsxs8yZHhw1EFI%3 z>6T|*vc|d%`Se)nEk$MmW{yt=oyE|`nOgVk@qbVx0_j+9ox@2PFn`bm0^ zQ|G1KPoBBj%v^-Qvzj>3ng52{AFcgY;2$XjvnXT+x@Z6%I&=7q=c+CSQ*x$%n{c)^ z_xBNc{ZwXq5JZ{PWb}IvVbj1Q3xyZVw3QGyr;zfBl5KI$omPs*6k8!n_(#LL0`9Q*gYyXs+ohKcR z`#ZBecw`iYz-My*X21fwZIsrc@SDJE}X6MqZ>2+>E zkh&XFw+#CzrH|-RMsQIGvhAI3eCcaWs2LkJ(G<&NdvKc8yFh}_Rd@rHTs+Brlhax0 zy!#h_;vkrM9Un=dWR&o4Y&8-eN=0Fkia=kRer-M+!Tf8}Bc$duDPov^<&W=zpdorH zfqMMHDr}2vJc{tuTYC5rs7whGvuwc8Dwzr|3y#7ekV`g;lD>IBq?iD=1D8El|e>Wtbn z%7d@5ShMXf18PK{w&E3k%iT#m1#yiFVy*JH?4bNXX!uYf#0ipDEtDs2cwAF%H^P+R zFiYK;VV3z}mbqb;PZ(y+Ob6ACb~J85{H>LcCo6imL*>^Se?(fkpB~aH-L9_AwyP^Z zRE2}zTwKW^CAmwMAW*4~@;X-*O;(#0; zy0;0o8SF6Z&tfy&Uaam-GB3J-(ZyIa^2DoL{Eki|Sk|Y1Ea8vz*yf{G9UbTneHA#0 zhEwP+hIUU>)w;D$ex0rD+W19pX|Bin_yK#HcS;goII4EwJ;ZA*Sl1p$?ANWMMsn`| z>75mYV!pDDJ%a9zqe4rRiHi&i^zm$sJA{b&2~o$6b$yN8AOa?NbFeTsx*dq9i9{0{ zIi8%5$9KqoXJn09i`u91(e$aHWK3ZU$vARqdJxgc0`Me%JaSy3RrH>?U$?qi&RToI*pckl zW)1^MQW3b*VE!Cuo`#jhdZ_!aFR4YhITdt=|dukxPwPWDq?p zgjw%Vl(C;L$eU9u7L*)-i29kIa8I{i{pxLau-~AFx!;@J`lnjHv&~rq7pMERg^l5z zPL|h9;yng5-AaTz;r#~V`B!z#flQg|Rm#a3e;k}BDMc4_nQN)#M^LfU~9o2;|6>hVbk7!a5Y>!}<_ zs-#S4-)u(25mm1$WAF<%$M)63LZvPr*&P+IUM#H>d(@gXdjw4CrfXNRLd8)REXyew zQP&)cMt6~~6jiZT5^%b)Bk!y+)(6Fq2%}gFy{_$>W`Bh~MCJ?=*gw<_ZG=vL4BeM|9w3n`Vz#Xg=9?7_v$Z9-ls8OSR!Ni0Q$Md!CRJ%xN`J2gCoDfu zrEJ)$&RdFix(c`9+Go_7=|(Kd1J9R@Pj2*xd*UEc7e9+{^>ivaOfqku4FKC4b@!P& zv0G<49Va(uwbyxz$F~}l4%NheEP{3p$s7Mf(8!5(uRtNxkq8PXmmn&QNi?b*tnD$$ z+mB>ld4{Lvj$d)#-;0@utvWJy7@&hi-0igu){l`Va#|XXx!|E+O$w8xtVdg*WXKAIt-5FMs^B2BqEbfMQ&K^ZPIhRJ}`C zY3Cm!%-o9!hz>uq4@17w;jL+fwu)liL`IlkOc2S;n$`8v#mUsQYU11AdGvG)evp>q z9a$IMQBZ;2HFR4xJv7PYaEwdYXH#CDL{LA2m+P8W z5~}V8j=5y8PJ4XzQkcyC8T!1P6_H--6qey={}9R-jv;pWjIP#C={*>K)iKS2i%nGqvAxlz z^*-0};-q`8kJl~j(}S?RZrjFPn1RMXOj9}tdAkW+E#)KaZenq}9u2#DsuC13oD$7< zi(l}T0tIXg2bbGwU+zjrJ^~;?e3|yRl^x9$)(nc9RCy$4zR$Pzs6C2<1Yfp^+;n>m z%MSV;MiUA=j-=jyL_PNL1{KUmR4DBxwAsY&Xd8V}eUUu4_sKKqcSQ+ikdHC2tI^g_)cauvj)zdXzOtywpj1eYG!Stu3a{L%n6X-&AarD zzQlS*)4h!L`Kw*`L3pJsdFC?o5T*s}8T}p@!WAz@2sHQ8J`|_9StLnyBeKm_hu3Vf-CAv_&8jkytdr#m}KHUFI_mgiocDOvBAQS7z;JB@N|_)e7vO;r*>&4$+7Ko zirKUY$$zx1wt4bYH=i@p2MIM+cA=mk0)2W6Oc`%~15$t^E-Y#Hn(N@+E5R9=J4|=5 z`FGMZ-!1i?<8nfl=XT61v>{{@7wd=O{qM()( z{gpC*`ufcloS{cpkiOXErlYJ$ zI~3~^NZV2UtvYccLFry_XF$LstESBZ6jTquUNsjaj7D4 zgxbhbZIr>}N%eBMu)?F@d5s&XcI{W&G7-RH-6lGW+bfnNz;H@lkU_CRWkjD=Ubi`a zZAwC|k0}DI+}cA5Da_DyPBn%NU5GiiI(O>h!ASoh?RO8(&yGo|(e}Uz!}Vvvg}5zZ zF~NzI+pLGAHWr#mV+4u#Y?th=}w@&tpr+crHI{&1TI%z2JK^Nz$&JSL; z%qL+1Wy;mgOd3ZoE_>{UN$>WGm<)Qx-UasI!=n6dCrl~pf!Hd(c{ zk=UpaxqNv0vHix_ob0-P%og*F(J=jq&;L)d$c+2`EMHDNbdGslS7xK~w)q1CCbzKf z?{mR8Acl3XcD}APNg%S#dP{KnkJ-iR+3SnfA1{l0{48EyzCK(Q&*f$Cxz%qc#^Gf1eq-()3mUUTIh5g-z4qP8wSHKcSXZGaA9y< zAmxfT4b3GFLAdT@#srGfr$MoQSCxfgsOc535-7N&x3&<9kVPSs(La?m@-)#=kfFy3 z9Rp}SgC?HV{Fq&3Zykh~)&*)6ClF!(OBP^EmhQdz-a^qD@y`i<(I@X)uA16kI(ggj zQ7C7o1-z=yz!zuuTj1{{{$Akk1^!;*???PS;O_x{KjQBh{+>@2{=dY3?}HkHeMB1^ z_m4vzm;!9e?B%REGxG?-=-O>YgSf}kBPZ5)#)Q9Wh&)1F?{xP1^|SSKz9+4v1lycG z!+?-8EhMSCBVh{Z&&-b^2+jFswqDYs{MT=ut0{i-y0~X;)jg#{PsIOo+Gf9~+c6C$ zsVw#0Xfe$*&QNt;!vy46t5M}avQ;d^Vm zo%VALA}Z0z0cvreJg*ktlOF@CrT2PqHV&h8V@=Eb7*(m|g-B}dDXZoGhoH6(5mZb> z|3bp@#6%SY{eeeLOJ!$UdrL4Rva5e9kzGYZHWwn3Y4}7MEA=9OBq)(*9~VVcofCT@ zpfU;CeeTicr=J>qAa&ULroOIkpf=e0(AKyJ*wk+yiGS_SoAw(WR?pd;Zu&Y&0&+hP zMPbAP@dIz99uwI=Kd6Gok+>ZeG|^0c2VXxjU-snTu!a@?#JCJ4mlH%H|JUxf+Hj^| z6`7b{5iT2I|NnIFyP*Qi%t z4@&1B<%-rS^)A*np^2dQ>hMW{_PZGR>4*wTLFO&ak_>l$axLExAujTyazbojobXRsGdu7J%H-i_OF#|6o*o4QMWQ^)e99M z&>v`TL$jB&moL6JT~AIZt|$FuKbJ*9kc@&%{h$G1(&Hx^umewZ@fUMx;H z1wT$X<>cgl+l!Z+gkPuMc4;q8Oxo$fwuN6WPHo!h%P(x&={J4aw_dokZ+*+Az4&55 zY5ePjO?&y`TQ=?GOV`I2FS#!N`nF5^*0){Sw_V+DeCr#WhF`vqZ@%C@_}4dF+BZ*J z+PCc303Mg)U#Bk3l>^8NllEfq#Y;-#U$(t(e|y1y@X@btn0{ZL0)9&4Uq0olBciMv_+PUbM2ue`xJVzgMhcbSGRvUf*%Zfa+Xr%;_l0ZMncapiHQyU_Xfu(7bA zbeQSJv)N0~IlH1=xv;a1|nDMi+Dc@EdQ5}+h zEg|45DZxGpKl+CPVv{{pYz?~Hg$@O&8xs<;$flBQxytuZeL^#W#k#@q45O2_T%e#? z@f3P+C=|4fM{X4VB)_90V3w!)+*EjZMyUHuONRHwg9MDUU_j}Vh&4r6tT5|LxTFI! zb<&b&n7&5XgcsgND$4Ml6hJ3NzAub_GHDo}$LmY!w1HP+cJkv*uzj&{Jz|a7y*-3* z%39}NKA6LJ?AM@){2FlhzWy>Yw4=Uiyo((?!{dUgTRRuUx_8QLayl2apgOr-NN6WQ zVnRo{8ZIJX3uCM6iXN|S*)lTLO0SF`5+g-N5_LYVjWV<-t0 zdHH6Pqxo+8>euatib8l?!@8D#EBvautI8c*a8IMgzzwivET>imr3|!lUR>B(6qS#{v{etm z?yhaV5;aD41_Jue%Xjr#aC{n6-8>1oO;RPnbH3Sel;@jtD-qjt_r8OFijyAgduUwZ zgRuIlF?dor50Ug4Ka$DTOCXv};xd(|5ey43AC+&r3f8G(F1$JPof27#O5H1t6Is$rvXa(E`e1%vY@Pio?|dvDTCF z7Ze#CXeWa|NuI8rJ}eG@qL_s*58l%-mJU3zw~U_#?2<8HZq}Lc!o+lm?Yr7lN4Z?} z*&~l8=AZ0A)|OG|j=lwqmAtSE=(ROxtrRImmlUhdcr@!OpsTAo_w1JJR$Q}qc*_Ew z;`nXLovNE3kdApdnLu2f@uVBIae%Ga7>w zHs(;$t)%kJ=+Fq)jdh(iv`iXVSz2xq+Ld-Pcvz+b6i(=R%f_U75>&P+f6FrR*rbnd zUMvDxiGOFJFfrSIFbB*EHqvcJPX5fr(JI@9&e9=0^T-yDB5Dqy=6LRz#ch}9ZsK3Y zo43tsr>#LyWB482zXDKs!?#5v3p9g6K;6{458lkICOVI~%B)6j-~os$Z#aZ3GXO2G zJ#u?aDY+w*E%gVxpk(BB!KC^7`-{tvsCNchS{%g-s{oR!fZpM8Bj zd)=*HH^p;!wsC8u-0xafdk2G{WtvPkT{6nwx1Bt=%&Q3Ge9yj{Ry%ebgrAefUGDE- zWo01~tJGgr1!{l@;-cAt_A#;{kTAzt-(tkC`}vpcvw+6NAw|DxN5OS%&F8QC=cY!` zQqwlZn83e(d}G^#^M!eud3@~NVxDUZ%mdmxKc5_=liORaTZI7+esJ>-VHg zthh?+=GAO*3q^F?#IUjYA3kilQpr(MDrXn2ujtf&)u4`TTgo;0xB@({Mt7#rv8bKC zbYeK=VB71~{*XlL?^?cpeC<-?$~F}!VEH1RO5FXj$swG0cnd*^(oNAMI9$n5Be$GGLk!e^B-UZqW6ch5Cc{+?3=C3uE^lUC=%XcJ z24T|?xjn)XL~o$Prv*?=20^!cWK=-EG}qj+k5}gW0jPOF*R!(;N7xQlQSn%{5vzb+}9S@SQy^ z!b}lV1jnR!S`I1kh$#8!z2E0jPy+Sx$c`(0ALRBNuhxD8ji!XZ|Fuuca!RS9X+Nm( z4)f=MSN&n3yu9uEh_`H?JO;cp9FO3Cr`2W`4nY$0W03spAd*t~QAjuOFeH6+9MX1F zt*RP4p4#1v)*~-B`(4F_96gfC#6G!Nd-qNv9lFe)m4Az>_0nCj9Ht!9XamFWS3?-M z%*3n?fjuq49JGSoFJCC{u8#J>5YBV6!$xVvAwi6R8)TniF-IX{o^XGku~;B~v*pxR zp$s-gr52v|(;B?W+bf9p`^ubZdk*KAGx1O+;>1Gr1J6{}$?&=l{F%AqwAyQD$T0Ny zZbLV0@D!j$EEjRw0c#dc)q89EoOU>$k9T=!E=qAsLLXxIV{WGcBA@M$Uy#ouMJ3NW zxfW3`+I8I%NNu^YOeKA_EANa2`6Y;?2y$Ytmzd0_AWupsIHapgBV_hD9cb)#a1|Tr=t&UAH#E^= ze?=5Z)J3AGC~|L?M5n|1&}=Utgbh@L$S z(}fsSV%IA-)hl|;Z1MdRe7>U4?qldo3VseYPaeW%A6Cejk4PrAmwYGjG>Fx7v7J^E7AD?K(+Db>~v7Za|s_>jE{nv9%OKL4^?t?;6)TQisjS0nmsaxB5|c} zuTCFjcw8!EbVTyt<`2foi5Y&8x_|XKeGK=`N5Bsq{d$E>t3wZe{Z$Zmpk3Qf`-Up^ z>m22+_P|%4jf#dB&v9J9u%6WN+QdBuKqb; z>0rxr#W~!qxVv>>1S^}n(XL#pH;l{D;&J0JRyu6OyF@+e2~41y@Tky#(sw56sO+nn&9=|?)lr)uxKXk{%I3H7!JMT02~9UU%OkL`XZa3mU5@fM8&EE3zxqJ`rBitbzNlmsxWrZCC|K=j^W=5yzDHrAcj z#j24yMg*7V>%ad)vC zmRStS6e?WujW{}@ZyH8ArB&V~4CxMrImA@07s#`PaI0MHx%C-~a+bOlF1puo<$XLh z=h953E7!<*PJ%u@Nn74=%NUYG`apXU=R-!7W_m9;wF%y0qU=RCkU!^(%V$4(^@l(G z?$u9!`~5tFBbtwy;sc~5UZG}p;Q=T0|XBeGEDXU$#Y z=`L!T-xWh2iY`W=J6ph`mv7aznc70DUDWU|+rFlM#su)hU`U|0n|_7$R%v|cg*X#x zbZ#80>RdN#x_6+9QJsK=WN}Zw(@%uojCmN9|B!^<$xlYGB7n46@QE>11J+k82PxS( zc`#Ik=vdNO7Hb;kXm1CIB;s=v7bHdBPLL-BM}f>o8xiXn(F^HsEt2RlVsRIQ?LS^H6pbKIz8C9zX zOg#L(O~#qO zcn0{L1>Rl8IX!9v6Y{cdd>3fBAxtT5LHtIO?zb5fvM7r{2M5`=QPdAs1LTLAp7G@3 zlN-1*e^b0v=uerFYP3^+sLr3wY8za&*PU@nq-%G^J?>R$T=m6ag>1aA{RI08dq5N2 zl)=>nOaeWJf+^rY^*+7y(Ua8PkpE^F%d;Fk!Y6@SO4GzPjf}w~Db$r_c=6O~OH$jf zxGwP4^#kpO>fCYEr4(vwoVU`(b8LaVNqfTee>dd98}KXA(%;z7Xj@d*Hw3`Og^5BM z#AP}HT_L=(_wRD$R7_h<@s(HG@O)mI!)gr4q1C;38@sdn03f{c9uRxAFaYDszK*wz zW$sF3bsf7$yjFMl*-;r>_kw2^rfwUBBL&^|HH;_>nROypkla4oqBMug8s;lPXfSjL zlT5iI0~kXulXAH)I-mO>{|KA$(XgqboAMoOG}@y#WT{adQINICv`{hEVYw|Iy{uR5 zL($7PUzG7 zH}RWHNTgb|*1zJ4rC$4b)d3>Wi`-jR<>nXEh$~4gQSdhuo?C)sZ?K5=7n@7V(2ho% z?11DT07|RsLOQ{gQMzE%`^c_KZTyL$yYRm+ZN)h`w?wjExR*M<(gucqO`NHJp8@UE zr@@wioBgUp@13mZ5X(DM=5v36R)UHwxa;7ySWx84G=|PCT6nU$&HA4Z;X<)ci4bE z@(z3Cgm^M#6e^(A+v4CM{t$$JggV{?I?@e=?+#-WS1v}e*1*mEJ^ei`C&IG1XF$D8x+_>CDd zG$(U>@FKi;j~JQf8g5qblYSH*Kg`|-S4gH1*$>>`n;$*s0zJH6y`Sg}x#hrZuauJL z^Y70$!^XJhm8~r_@_s&dElhMDw4gn@Y+~FT4d(lTkN3y34*xqpKP@mFo?!uy@0;PB zH3fjBmT|$5&l{v_T~e}t;VQ!#SFSZA(Mad>WUR_Gf-Mk56`;o)9K_Ffe$~q|l!sbG zJpGCz!!Kg}w>;o)9Zm1Gv3nKWcTB^YZBZ&KUu`F zQdvM6$l>E!&2>VtOK%Q8oc7dDLf+rO@vMq{7Tgnv*@2~(BaflMmn3o+X;nzze{&jk z@uk&+MRQEOI*VM`(Gs#9NTlnfiza~$0vN67=X8$G$QLH|?rCj@bMjrF%c*;GI}zg}NwY&e}5ccv>c z4NbNO8yjvvFVD$z`dr^xfoVV2f2G21rt0%|90d1T4j!X$sOxb^3U!n90>@i-oqB+i z%zeQRI`G&&X!i^ve5c34#R8662c`Xi0RuhLJkq<6Htrm4M79KX-u=-^x^fsdFSuBg zyanaF)qxOQkp^UZ`}i>23gCn81CZ0|4;ODQ)mwUv`9Zvv-Rci^6Hq;se*nSU-+#Dp zCGe>r-vy`BKCpsnCXu^>^m3x^$ulmiiRN!rt=<+a^rQt5(2d`&U^#>H7OI~=WDeZn z`scR5d)1uAzdzS4N8V~lr%&`!U;phltzY+jvE*r~eSlafqI3LujKhm(RtR!aKmKVU ztbgqGcHp+(M0UfK|?5$u`wz?m`{E zO8qTv#u!yejB2aPfKfrX-3X&9p#@Q0miYaIYvENun3rjO(7as_J>_)ae#U@EsMQ(=vZ$$jfj^w%yF zkiG@8DLSzDw|Lilt*?WQZ!MQuC|8^qI~ddYR^-vc*fAnKE$lC|iG+gw)f=dRF$b8V z2a6OcHbQ$he}Mg5f74ThF{bf|K$2F-3nXI#gm&bA{i{>&sp5mkD7 zFRV|lQ$)Q*Pj^Hkz=nVv7g1HmdMClPgmmQwsMc9EJ&RTyK{|YO(wSE$P^pizhW@O! zI*B1&_h3OVm|XAOVUDBpkq4S{v#IQai+p0=#RD`wtAhOwf2o5hn%OI0c>oC?A{F_q z??*g@R89G2Tm7!==n6zE_#anWSXUi<|2fcG*a#FNb6Ld?Pm}6-x{ZnXF81CiL2`QH zIL6em8&g=oG9P&rWf1VV*{wRW?rLia*u*M}PW7@HD=?Y%LrBx9C)3$O&tfIuZB#^a za`s`eTvOq;f5SO~?q@?MrhpC4VddRV-IFPvLI3T6U%rBW-gWJ++97*kjhD-*`I z$XGees0q(pc3L{NE@=SJl6ha=ID$>hw_gddcNNYVcqP)wl8k=N7dOjVi&O`cw+>)@#|A!MSBtDvR-rK(ACA%Gbg zCh00`f|IvZ%YWmL3@eGf)a8~v>Mjk4NDQwXg!Tm2|76ce$3P&*%w^HZsABScjypXY zHVMt3cVLjt$iTxv-VH*Pb9|5kJ@7BN{FvlgZA}V9xaiOuofaeg&cwvb$=F_v`x}?q zBhRBP>z^ib@N!7eiTlay0D)&8_BtJ664D)s$)SzJr-6w$X3V3ZGSeVL5~1j`LT2vA z-_AXM{oZ(lLJ|c}?l_Rv8qu=efQ3$-e1;nI))?XW=~pGH5OXH$l9)jCFlD1Fn1q*!5)9&R=nyqQ@t9( z>;zKGch3KR3|?cuSq5<-uV$6JQ?r*ZCswP$TdP&BpQJBlWfuMhLR<3T$EqQ%$HNUxhW>)-ce{plkPb$6D#8G7x z&wnU*3H2tGFG;!hPTx5I?yS$TJuN=`-@$mRuYC^c_&iZHZRG`=zT!`LHW*lLII{># zELZBCVklsu0p@jnihb=$Q_5*^5U2D`!}0d4cD+KU;gqeNk3sqi#ujWZNzDosZH%c8 zuI`Pi`$m5NnjBCDq_^sg#k!K8^EXaS0)MdRVCD=a;)h`B`@@8{Y{=0LW0kx;gF>kV zlu_xk_faAvGa$PHV~*+r_7KhAmn2hH$n*yG2(5074?YYLhiZeJ7(O7_U^a$g9zvmz z$9*I@V!x0)%*|fT32W+fc1bqokz2fc+|C#UXLV1{5O2StXk46G;~GHdbRs4rVShl^ zotChT&}rKq@5lnZgY{zB6Vuf@Ye71l3Q_f94d+@`zKc~4j7LwqTZ+ZMYk%6luR3aW zR!nre-XTlVKgjy+-JQ!?N_te~08ni7v#Hoo9#jr}8Gmz@6CTwKCat-mW0xuGP(rxS zu9)G6@<}*#A5jHt8I|40Sv`Si=zp)uJDJ7;h2V2gPeHA?0?Or$cueg5_Gf_}duT=w$bp+*l_T;32=k2%3fpUaqG~BcTvmC{D$W%EU#PVg^+XSA8nW6C+}cZ86ma4TJ6h1``S5O2q*RT6~e>2X#l!k>0MAlXYB1;=RS)p;9KgE79&sikm+C!t^ z6%y2$J@IyNKNPeZRS z8r46C7xX$SYAW&+g?~)BR%fH_1j zN||~SSdZ#bMu@T*YME_p_pV&|hioTitHb;&8*aGfK2uBjq0MbU?uEkt=zQrM(>wcj zj9Pn$H>n<(dp%N1k1!^Hga0RU!GybNp53^>Yh%h+JAK!)U4Ni%ED_8ZYPv*Prq#Z+ ztM=_oJlDLAoaFyee12bpxjsR3oXdA6?(N{7&vgr~{{d`y?<0Nf#I?W<)=?y& zoZL>9M_AAEi__87`~ocaQ(4*f6)+>e0-AKR_7Z+meEu4JOb;(^#QFZuO=*cD*P_I# zFzGqwz)-(XJAb|^k&vi&;zod$&d6-E=Rt>L{9f%hFaGlGci;Zv^=vHzlskhJ4Xj!? zDuU3lFS+AK-Ow%Q8Ym zeBOvy^r(bDV;MkW?!;TVlQ3{O%`#Sg$%anmzdZ+l_|d<`0-E)Ke%aO9r-U`zZuI8+ zlt)nWmbRB{WA43dHwKn!(V0L(upegx9oWwW$jdl1cx%mUWc^)>X8|MOHmu}3m^R}Z z;(60f8Gj_Fg`zQ;c04q=FWO*utn_(1$|C9>`&eT%VtKpoG4iKEJ!b9EEf_d5XCS z&pMgE2lRD&8)0)9<>ZyVSM#Si&y|^CjTbHg ztQ6IasS-nV?w#wvwHahtoMSn*y0)5|TbW@~OT)+1mEmsS@jI*X@Q{TwO1Kfw z(tkY}u9!;LldKn6!5olw77J#>%TzC=YLmGTB|f-qt};t&tbgQPHYBdMZw`2DNctXh z$JjnPLE3O>ybpBgpicRa!;QlQ@7L}38~emvR$%;oIu;oHgiSpUgRp8)A{ zg`;fL+0TZp^DP_78~fbs=;a@N|MNHBe1H4J99S9AMlYhMy z^Jr3uHGYgG!b-^i)KV{USQ3tew-H}gq7>9ks5-%LF~X!|0tGO2DcSXdeCgzv4TC-u7A-LAFIQ%N8CP}=<%sHe&F178#q)HiP)tHjc=kS zAYvZIA~~<|&8h-7aUD4uS-H{vcy~nsH}^aq$wg=Sm?b6Qfwt<{jXk){uG5o$@Ze_T z+>vN13rJS2fbiQ#;TQD%LVv1ysPlE5`Kvy#{pa7$uLi=n#N5~C57YE`M1PyzNX59S zt!s4dM`Z9+H#kqgd!g1*zPWWt|E_Nu( zp*Nj5x#E3c^Ze@ke)!-7m#N9gAL=(X zJyLl=qOynP^Hq2F0$9HM$!_$H7&#WV-|5hy1Kb!RZo`CBg#9h!q=S*bII#X>S$u+R zW>sEMOrj*Rui!Pmtk-QE;nz5gXtedOFNOT!J+Rl;e^^8#wJ1=tWOIS(=ryN5LPj`E zo;%azd5jc$tAF?$Ycny#7i8ty^p}r=)_=~qk0e`gFo8cAk>AD}*RaKY%fs?;$2tQ-T3A)>H#gAIZCY# zviS_=*l%wcyO$>pdOF>FAuBahY}#mc8L}27>v0%Wl7EQ&T94y}?i#bHjDjhqdpthF z)|DU}EDD1*e+0-&8I#7}cOvBY0SOVf`ss>C(#x+#3jgebnLrpnICih*4a!IhLAMj0 z{Nt{;K2%@I91fWdwI(blSnhTjXrs-;`!Txop13JV z)9YkBuz$!vDc;aqig$C5br*K>ACNBH9IVM0IW{9rln`*|{ssya_PSwrBl!`fhaC7f z4t~FkqeMUZ?LJ$w?fD34gebk1m+1BO02)d|9qYQ_}3>7%ow1K^voDaQS6Z zuYa#m9pHbxzPcWH!Y7j%N}uTt@JaWGPLgY%68%>xl%ZZ<$443IE_wZsss5)c8NRy1 zQ2yci&P;RNv~`m>-SH7YsE}cz^dT8cfI&TmwCda;0jAwiS6&tEgCQ&{3?`V#^@Y6D z>OwRUnPHMPSX&g~;*P5eK>nL+OURcYOMj8>6YY|lBvc0Rzet-5?*eGWN0)QLmBn-@ z=fhoHzrVv!Qr(ANUqVl?!UBQ}DMG~Wcdauj`o&fn0uJLAXPMZ{DEASvle?J?mOCnKf_Pg0T?86Ls^!MPw$uI;i0Pckl&kQtc(;SQ4ME`Oot zcNi}ycX%g$-~kh2qa&6k)KKFK7m}vQe7=1Qg{B7|#N^@%r=K@q@qzmK4g>Wi7FB9N zg~S*#gn+Mi@i{8`MfqG)ez@Gm=qNwQ>As^(;R}*@S6)YT9(-Jcyg0W@Q|Hr_rbxy~ zi1u(|p5!NKn!p#kc^=9> z{2->6S!53S!*;(_^+i@xdNqYaSoHa?xyjhY?WpXRV|UlMI!;U3$Q??irt4oJhb7ds zV#yXs=|~byzmhh6?YLz<(sp#@bswY~myr_$!od^Ly#W-m`KJiye~cqT&3^=_BnM)B zy=54X85;x~#nVHe3#1y3Hu*~0N_9R!?&x}y*wOK5INI$YsX}D3chjwDjKY59WV91* zbJP?O93`*;hb@|-F_eD&nQR)r`jL|XLlM~Cvdsefg!@%N%XcewG|A%lQBH^<&80iy zcs~?na&A9fL`CkAqs9E69)B5xgtWX6?w%u26aBBYeYx%I&7}s|zv0|Rk{!$ywj&Ad zxl%j6HKhqHu@bXG8-lSV)&MnaGxdnGk~+9R{@R6?ZZC<>-=RY4YJNW(b{6TEh{M?I z5UaOujY3oKLRuUpY6^yO2G))tzmKU(k`CQOniA<>rbl$kL2vI#+ke6FLsAD*Gi_rS zr|t!3??c`1M#}r#lNR-`pms$#kVuP*>W{U-Jr@~w z$;PDtje5i=O9#5+{V1~W%L>Nt#O5zCv+vajR8{coLv_DS7_j}q77!b@#Cr9x=adu; z(&$5tCkkp2X2?pB{)jW;JLl`6omL!S0-x-1>6g8FT{eB%^nbAQ<6FMT4AFifDC2jQ zzQX=FLlC@oAeW{KrdZt&_petqzfedM@SaKt8PO@@5yL4dlEPNEle9NE{A%s9c9rsn z;VI&GocXBY+~{FKu6srGl)S-q+ZvzTd&-B1>jOg?^~5A`;A~>zB-gILUDSL6r=yDrM$mL zLy}>>|B~7*Y{Mc>FgsjdN2ChPDF^f1o7ce*BP z1Dj-i+-kAMDCA9MTJFJm)+*P%cz+sI@;%mGhrH)&Ne>j$ecr8CsY0tV6SfIOmd@tsWuMv)jSwEw1=eVN#BplA_VHYSKjx&92djpb$_=Ak6GWE)R2wC!~RIg?>LTpJR=wn zca$ot2%6ti0hSuSBxYsxfH*Ok@ebs}p5^6PF{oahq$ASW%#BrdU?HDvi8c!TPi#gxLqY615 zQGe!I{`U4H`<_^`Gopw_kb}bV=8sMLj?I2# z@)M_?Kie7jCXR34%x^WADB6iSqA6@iak87FdQC2p$We5loq8l$;oa~^nICZ)#P!nm z@AZ0Be@dY!St*T^cQ=wo7tW|21YM5m6Mtn(&yn#+xO{N!5k-uk-Ip23ea+y?NlR(T z>n6%f8ZU=-v7_%PjC#V_v647+6XgPEEr1SgvL5hWnf$)TG~&NTx@g3M(b|h>M2WS| zyW@92{c8O!FvC4iD*JhLaalKjQ3{M?q3QNURGo_iY{G0XcjP#%Hh8aEho#_!%72VO zd}OtoXz|5fy={N=M8Vfr4|KV;>6!R8u1q}B6(SbfpOcC8Zftj^erk0cZVq;o+8q^n`=BR_BQos*b)Q9#PXR+%z<<+yDWujy- z)#_MjB)(F|Knk6T0HR)xvok`T(tmGiQ>U__ZdLefF(^cim#5>sroprNw1$W9TJ31R z&h~!|}Yk>r??z=VYTu{~Ph-}M|nP*7aV zBsp0c6RIDgaUSt@#UAbU_tdy7{{=@5#we#9xNwxOMSYbFYbVa$hkrgF>4;cX*K3<` zRimi>S6o3#4hMsk3=bCn&`v^iju#M?lO#HyIOj@wnp8U+UGDN67CHm#D6a0i(!_r; zi4^~y@!#bojNCxQ1|$=wm!Z!~J2XgWg9v^#rG(!2*PI+1qwI*pyl?2YnsX_Cz{H^@ zeOqUmODX9Opb6<~%YUu7Tx>j1(DB!O!R7qX&D^+*>XJ*?!OqO}w7QN3C|q#jZcm>d zxmPjlaXGkW#KtFI<@#6NGzlReB-A@TNfRK96rDO)7;-|oirwK(`|H1@` zJ~NK~4M(r5ZVt}SyfAJ-vl&;ou<3cDD8bl8OMuoALHZ3NnSVT*Og+fWjU#o`bhHV-AgC6_*hJ#Tzc`VU! zRq1!9_@aygvwuyHhdpd@&73Ad5SaVjV@z+|7d*RjiXKj;?u(z3>%?S~U&EtsEG4w= z*rd_@azlrwb6|0QSuED#eSKK*YugBc-%+2ufx@;K%#JM(2ta!9gsgS*Ek&%0(1IB%MMSLBGOJlB6#oap zlvffAM2k`!uqH;6U?dvQFNs=MGL7KIDbLR1^*1>#Lc+}^HtIub+36q= z;|08w+J6+5a_ch5Y-Sp#0+__+hpfHKrNdqMCaL#dURZ?4U$yq6tiALa!TwEsJ@r|6 zpT5~O3X%w=?XO>d`+G1KnfAN8&*xd3Ngk8~|IF;PR|<-EUT-94RGq^RgrgBl(?Kip z5${KRPz#?8zh`1!IMj@^qig|ZDw<-j_J5=8pQ8u}C~iNMcmhDbNN;ZZhaFl~ z@wCc&weid;Fp7?tJ}lY>^kL@cr`e1Hk?86@U=55a><7$);$N#xC5%y2>7q)`i$3(4 zjT=!qJj+WCIQCur37QbAt00}@vTQgRnvfW-J(KCt9UwDjWvm*cu5fI#bQxK3x~X#M z@_%7#CSAXRgG}PgWLY$s4rq~DAG6q!VjV`_Dvz_JAc#C*`k4$ojSM`_NT(vo1n|5# z{~2<@O&>9{Xg(Bh%`P!o&RoMYZ7=8Fpq|HNt)UT?1D`O4DMB}I2a88=#j1%T#G!O$ zSr>!V+eKvliwXS;%-^G`#)3Z7(+CQQqPk$w zkhhp;Ull(l-6yy%=sES~+5j#vn{LMkfa0y>f`=0g-bOvKXM-@hFM2l;&7c5g|a&Uqw)FNMKubO0AV9ROMOvCX3w zVkXkZ4zPuVC4oqiJtbbuYH$3EbZf8ydW~{kgOZ%C z_a~f9e_P@#HK-{W+v|o@N_x5`DSX^oHf>9d24{Wk)jX&uS?T(8%^FmfoL#kPKfbQZ zD(EK3N!NZ}RdvVna9CS%(zV6urc`D*Xx9XMZFhgE*eC5*mu^m_vZR^X!hgiPt>3*i z@PKNxQ)GBWdl*u>PcjuY9wR7JaXOAKQH|g*)jfh0$lY_Hi^_Fn5YxQQ01q>yjp6#P?tjBgLry7eOZv{H@5G3cOja89)3-OgKMzmxXKC0^-`Vi~ z>_23Rx=}xEXM?+UjOcbC%}Mg^7Wdz3lG}*1D(SnM-G7%FoUrqOLlQ4v!0+6zqWhAN zBgsi>q`^DvdMemfECoJ(k}3ls8DWP@PKY})QoKg8WDQGBe61oUv45CidW6<;SfCN; zJ{Espx1DA57O>>6d3Srcrl<o8-wMvP+-(189|z|P?-z7 zhhScq>w_EA)xTNeh1#TSOqMQ!qW*PDk-lS*qgqd7>WF42lcN}GJ^iDvUqNi8`r<4W zop#WD@_{{cjy&!3aeq9>HRw*A@iKuigaW}RjelRxBc0)GBi*dvjS_`8_tQW(!fC;Kykx!lbe-=$)6l&#P^C+9HDIy4s_f6hfZh`4T(;a$FMC z5BB10JX)HfBWRdP(#YV}u2^W0{ylScWXoEzq@fVSHqwLwj(@%C@5AK^|94-r@~>+J zf+!NC)T@G(60Y)3GxJ%zAO+VmS0MGeb1zMcSmBe|!0b?K?CBQ4U9+}%gt&aK(f*YM z1;te)^+-no`)1Kb0*1EWq*FKa8}#1;_RJ4aWwP8k5<`fKWd|C+lVKA{({6`aHEP7~b+j{vpB{%RiS)t<%kH-}r2IXX zhnc9+*{HPr#%GyiYG?sn=8dUIk+B%~SWm?N z(6tORe$JB-c`Kf;*WpHn!_r{;UXndf8K zu7Bq%@Jg=C*%FGHsdr=~7)}Tgax1zoS|@|HFUv)-3oUAJfED$WE4W=a=UA_U!^534 zmyr386Yf%ys)5)^%Xa1;3;Pl@syFsJE4)SmNI9|6I}$M^$njz92TuE6({HLJS%ZC^ zMW{2*=^PlUQeFI9N*x&XpU@F%kz-F{kbg1Xf=Q>X9#qFR5dvCt48fqq&3OJY4sH!B z2)TU?RTR4c|2Y6GFkHw#PtCEg2jl%Mx*7o8F_}WHHaLh=8#58U0tha*=+CEofWj>^ zzs3}6BzaoMuVVCM&h#ve$xDOb?&w$vX+BJprfKi0*;)q92eI97(=m58w7u}9y?+nx z@zwlaJfVDBEB6sr&cgk{cv!KlxZ<-D3!C?DSE@w5*~@h^TOF6E4@L^dB6{OL>0NbE()f1l*UfqWOoeH^9bR&p+ObQU zi#4)h-Q|a@5Koj1N7i|y*ogJT_8n-Zt$=){U=S!4ZPxyTbunSbz^q61R9 zey@#k#;C{5w)W}jPm3SZdGGA)r?-o9bG&Q4mh0R#>pyxtZ`=U zI!(FUJj81IXeAZOY#JWiA-ffK@({HPFIk(#f;wUkow~g8Pc3c-Hu-rJxIUu@TPK7$ zWB1#6Rblt%1!TmPl*jGt1|^SYViBB*rY%o|OFR)Sf~Qe+S|4$x z5pwvK%o!9IWTRR*f- zE!bT(S$g}L9)sA73yB-2UgE4W%1HYfh^zhm_T>QSx4F^H+!#4S`$2+R zj^=H3`?k4#TRovIbVvKD&Pz|reo#WEjeWI*mYa7tn|+YmoqzZCwwCu2!Bp^!q0Nlw zWO1&0FthdH;Y?4mdETC_&u4R2qG+u9zImql4w)Opdx_%N#+aCMyVkbZpTTJ~3yT?G z$k@defG-m@IWqxscVDItX6QPb_jPfJ3(^`TUR1CQ?w!y>SI>3h`sj;& z5xQ3`3z=R;rhi>zv>aMmHqZoW%@sbj%xft5wwqp`q^!kH$kT~wBiqoT{QrqX)sB=p z$*oFP#WCCHr$Pk!_LhG%)XI&X^RjX9cNmFutKm#B0st0$@y247ooo%XBSH|geosxUo!YI zDi3p&M&c9wv!;LOE@nkO2K*k9P3SVOW|vR%W`A}G+3@n&F-^?8kZFGj)}U%RmvRDN zcag!t7OF1DHQdRPO!W?=R~c$LH41Nx zFP+g{qh#leZL11(DI#9)_#u1-gUu-Z%EPTT#`2Cmt?eI%#++epHlC&V{Q7$J89U20 zHh;>&^JBtg786%~UazZ;d4!dggnd=nl=ZLSn~{x*HWn7hDK(mLsUj}DCPrZ!^Q{N2LFcUlPsvM#?QF|7 zV+acAeH*1kSmIa_n&+WDz0_mlFLa{)CVx}0yZ507&Gw>X3g|6#Zsa&blat-?1b#J= zQ(o$rq6S(kB1NE>kil_Ec~)1Fy2mkHAZP$KR9zH?SJ^M;8=2|Ht=G_OZ8gYhrQApf z1p$Dh=~xKH!QvNiQ}YY*Nw5`%g)QY_AeGbYhajZ&p$d3=H+V&TJbW-oWKzIfjDJGa z&vvxJ8zv98IKVW5X|QoDf4L@SI{RTM<3OiE6{1dw|%$!yra zN8u?hJB@)O){_fSs|_7qQgPw-tnK~io@*_e)!oTqh#_kA+LOP%Z6}iv?G=A@DTN~^ z596E22yYwU=*T%SQlk3B)KKn=A7;(>MGqjp1a=Z#>Rt$j;ndX~tA0_sa7g{0Q~`p~ z(H7|iUHG;=c_EV>O4qm*Be5FaHGd(l`Q!ajY$aR*aqL4ft|K0x%cWIwr;pdxz#Z z-8)X?Hz_Pjqg>>w3Q5ZRf{rMga#bnrRsJfh{FSYo1(QSjxGz=X=L{W7OHZ@**7mjp z=kO-Zjwyc+4mRGkF)FX?!;L6PcBd+b1fHt9?j2;NaU7NZciKV1J!pS7@vXj}37T-W zr?UII^2=k#LBaleN#gNQ1nk&Y8~Lgkj3ano^ijfmjn*TX8OKxeK`N& zTCMWdj~Inm8)_+r2`GPvV)hx)nctsUlzW7`zCJMi>|5rNHL)Xu=hVB=+^>Nh1Vi08MY3F~R9-eW$z`7Lr!+u!RuJ6Uzs9GaHS?Oj47oc#82mIG5t6wvFo z+iw=iAuB`#L*b2a{HaG6JU%2KEw#jHvvNt5V$^9W!cg{|PetV&$aOS|=W!bym;oQ2 zpPn5b{_K2$_n&`nkMz&%^vQ>rW~9Uc{*{X*VNArbFAbdnF~%Du=aM5< z^Ls*;Q}(7d@2z`o_&wm1G8IqAsVT2838#^|z4c(bv3!ke;B`lMq307u_`)(}AoW~R z)s_Nco^4)1C~#=L{ZeIGHZc8h09%In@5gwj*cLBWHFkf3l5Pv}+>9Pg6!^0JF&s{6 zhe5RVMBnNslwz)PG|KS&^weBDPh$B9V#F7~*!l*=tlpr;Cg`ANa$@$UmjiK zspkpa;bI@fMLh$9f5xZvY2g>(oI`X?HjU?Cw}rKknm-x9otga*6aQuTFKAlO)T-}m zgSF~3n1p}8wNlH-2?o`Tk20#HCbBP{jR`XV%{(aQ(zgfx7(DoS99=@{OoMR z{A8p?v@k~J2t3j?>jK})IUsSu=c2`TRrANEa?xGl^Rj?e!&Kl{Bk$|3tFJi0gqLM) z7bkFt5BQPekALC!Xa4n}pi*t23xP;{;VBV+!3lqF`EPPSu|gsRlqxUq6FICSBm~L@ zqelUB@X5zaovdRXY<24= zmTwOm*bCKcErCb#8nrc47jyi-WK3q{UZEo!If8~3un)XDpFAOE6dK!h3h%~YX*cPt z6o7~B`knb)`@c}jZBd_={yHqwdeR^@=t+Ohn@5yrY;;irDNDBt*pW9 zrImE9^VQj<2yqJ(TRhEAW(!;3V?H@psH@y|25}kl>Sgq|w{P3iccog26Q_k$a2#hramfO5sA_F5N&K8pOR2h(z9`wr zY7bI!3b`Ol$pn3jo5=*=vm0z~F4Va)d+A~;WDGUBbfF<1 zCdhwCnn=MUvPihn-vr~>*U}es#j#hKsf*zv@f3KtE@h|@cZFnGMSO{ z5_BjF-Rn(kOiMF%IALYV9lv>Z*YP_6?}&C#9&zVXDqMBnYMw4mw?_SSj%y4lhOi9L!#ng+BE_jd42pQ8NSl9`IK_#xB_IV? zWr1%J2O0OCp1SRi+Jp$y?=(&ctGLj9JHHFCu!iHD245yUIy;`_2@3eF%2UqW1)pSq z&$}B5iI<9glOb(kQD+HAGTUhH>MpS${hCjK4DK*d1kOY_e{y0Q)Jy->{6qYmq6bGc z=@2pW;`~Q^U|z0jFy4RWNS{)lH2jwESNs8)E6>5PhgKMjg~(M7#e-uxm{h5-uVzyQ zL@dn*6_!5sjd3hL}`NvfEEVrGAmW|C40nS-jdNe)Cu z)r1hFuq|T&=?G70fj@mG*ya4nMAnMC15IRyIdnIsCtqdeRZ6U)&f&UZ)$eB#gw4#S zZw`yv$|x;5Oj*zt*HlM%P*VGm1i}|&yBzEW7izY4Qr(aC;$6KL(p=KwES`1K#uicr zwPL5jbk*?q7;1kVBmQwyLF7>&1|b}?A_^yMsqy#q)%Ba&dL~V73tK%+Qh~cUn^bKM zSCcUZkFDo^M6Kyn?VMr&E^`a>&}eA+h1$(1Lp;?n6eDBv_Z)xE@b}F8y}{ob{N3>1 z&1_M_1jTBvdsWxXW}Lk}dwYKVMMQm>SupFThg(D@Vq!Pxo6AsbMbbt z%Ds#UH0zU=ojCTono$EKI_pJO`bVa;>VJ+S0>lXZOR6~&hfctmfOH^~|DKt@Adsp| zCT={q%w(RMzZ+c$#|Q>*jtF%=vQ7!9tBDkR?a6RMt z{T){t&?O3*>xP7%%cPgf$r5|#eJW*YkzeZhPB`GOwlE>%D{X_uI|SJk^m{?S_MU!~ z?I3Jn2i$ZC_p_eh?d@%P7VyZp-TKkqInD0dLokz&_XvOAb3EWZ+9;M-2o^mlOH>(k zxf=CFd$FopneUf$48sBI?gNhzZ2Rf{5wE#-F0J9h`50d^A9=Ch50Qy#dUc4$S(^Ww zc3Xp})K4zO(`vt2rR(t}TeiV3>K^Sf5VKP)kX@W2u{%w@F1*a9TnRePe?mu)wpl!l z?71o1ZR~%NOoOs0qg=QXhNT=CI3_9X+}M4Ky>&&w-HqRo!~X3!)@>gEyZBex4Rn3z ztVGT@c3Vk+31XHw$x?yLXij{&mX8WnD=J|J_K`(I3UOMxQOEu$8 z3>1HyoFxQ?fo309K$ZzrHrim*q3MRId>;)Gi{&m?9&pc zZ`1%*T-BSlMk{2a@%yUjhgs`ISuuL5)lh$V%+`wA0})dy=wA@LW{~>XU;JU9G%ODU z<>4@mTOg;g7k&=XA9}~Ty~P=)YCCMK$T7AOr`?fuQJNQ1r%L_)@95PL`T4mj|5bvO zg9sV=gb$7$mQfgwi*zS*uxa13YON_WKvY3zTmcZ61-ZU_N?-SVBrRsl}JF?|Qir6!ML8hQ;26qyN;-88E7#D6b>PM zVJy~0p((Kk-gHOM`h8}=_&q}%^Rp`$n?o;U(21q8pnQKI4_||J znI3w!JagG^(i6eMNyaYd8HAVAU7>wf-QbF)(meTWiTf%D$pZr|JeSc(K$WVFJU*aH zH$6Epte>YNW6V`3U}}xchNw}TV|E#W@__D2uwU{-X%!4-XgAubn~lORAV~2f$?Tra z>(R@H`wf`1H4WJvC01`f1DSsaY_sT0H4fcotgGH3BiOX)=aOl{HQWJK;YK+e`!YNZ zH5Bjj8_#OPPC>3NRFnR5s|uC;2@FI@p4J_Xh4#&~<+mX`VZYmb}~3 z3d3c?Y?{;O6-vOmNsIqqP8UeFSwkO{R!sx4^sS3bszAwm^|UC#h#3YDNTibxz{N~^ z&KI>+0jFkGAOzV>k}a4~+oTP0?+yJ#8K!j^H0TS^jC0#aosoSOHHJRlo_D>t2u!Dw|PlOVNGE=+H7fp{a9BgV8wAF(e_^92qDT%bG^wM zjQyhY?qLENY>K;6jYyM-bNuv8m`-nNkV|u;MgM+g{`hQD<*R>BD~wW_CTHic*PQEG z!GbGbcnz$y76gPs+QF_1SC^-l)m9XgO*}r+QLhZY9A=6{*(j>9Bdr;Hx3h3Ev49na z0>OA-03BoKAS<~O_;97jHxz?(rsK5i1b33@>QB!5ow&C~q8fy#{L%)QU-87spa>x`7^yO13yl86S( zfD^<=6)^Q5kl*%t9L&dYK^nKmt}MR`BVg@a@xv8NcB+5Xe5LRvVFrq|#e6DKw-2@C zg9i7Sffcp_DpG?6=tz@3jP#+#44i!}-B#q_S3h=Zc#FNW;W0V2qqBkVh^y1;j4N!a zYU?6Jr*Y=>2M<1b|K_Lnzxn#>n=dKev|TKloHip5d2th3!)CLa(71VUbKx+?)@F|e za7Gu zxQ`J;Gf|k^hdZ}pMqD4>w|Ns(N;0t*83QprP^=#*3v^w3%k!`&$M-Q`t)8cY)^$ZO zcn<=$X^D_N1EsK}>JC#vgU+36Xh4-#B)AP{O_F~cAWYlKUuszBSs0S&R+R3Apj9a+ z2WAaq?+0_ZBiYWoQ_h6Dq7``Pjt@vSmXqRAyfp^9@b-yLJ)@(YB^J#@JULv1d+m&} z^T;)2nA1caBBPwx{b883?KvOhnY>Qyyp6RqlC@&)Az4k`<1p2RJMX8xm){ke`!Ll; z+KYeEijt*S!_)?iJR-1g5k~XNU_H1sJxsp9ORc^GhB;kB@0D^` zn(qNW@#zgmj649(60nek!o)IQp7YK-m}B@NmPbKQO*mPW*;W;3uD38)8+cUlDdw>< zB+KyU(JV3NKq4yZGC4>qwS#`Rw?d&}ttoK85(h z;8QyvQ7f$bU7Uq7RAP67w7UpXBiO!?&x{;>Hsrh`b@no9AkfWei{k#t#UyPn-(Dm? zbkpghH@+r08838ni}#8E})Y zYM`HS+Hu(cM?kp0+K4WNT%}lAz@G`mF~Sd7Kpm4JF}#r|Clljg16bPK&f$@VL3MLV zlhTAWNPJjeQA@2&C}djGN-4 z4Fuy;9#%k0*`>MhnX$f{I_q8f*4A`7ut5&oK;E24Ad3DME%fHL_--vPcIFxSVm(8c zHNo6mO`!r=_{&1%E&u@~Nl86jG_$FPgs=ZLmt@AL3lSY$RayGjGK8MN3=qo#s;~XS zC2fBeM!Zr6L{NU?%Nsr3+G=?+^sPdFpQLryLpZZzDK>b1!YBQj$SNTwOInoDyxv2a zJgDpZ9t3an3%OR$hZfk|beWy~Toolc7<9~PlFV&;i*#rnEs_arqNlJXClZXICkCAf z*gR)5rR^nwRB_8DJzKQW{7VSjh6v1BdFu*h!jJ^H%L!(fD-6W21+6mb>oP=t;Dt1q zM2V9mOPng*ljb&jUFNm8*p*4|iAN%@APq;rl?Wewc$nKzwa*EKVr7;{ugpQmoxyLF zwxMzleZ^#VDSQcBWXOAyLMA9@rwPniH5G7s=pE8BhootV82KlwW| zxpF${*3x^ru%j}w<2es!W>m>e%Y_@2*#Jlxz)Z1Z6U04Z69b_LTRxkA$1|2K2?v|n z=5y5IX4-C}wi&9_HkD^>|NSLt_yp0}J#L8ls5FyGC$P3#8ar@m8Fz@CF5<-iKOvkcec ze)oh%u|#aCHJ0I_Joc}D4wYsC(pt)kMLR1q>q^+M3H2+fd+O9WD|JB?O)gz3@Ndw@ zeY|vtESABVYjUj9)+)URUmgm28M~$9yb#X(4MSWmEGDyd_|4(mI6Ooz0YRwesi**V zOq4-RT3OFSj`1)oM{RhErq6RYr*56^@*{I`ksIt7-z6FIdt`)vTj=nUv=Q`#xk8?| zvLQSv!e<4c>lSJ4C^fkd7otLb7;`d#&}R4z5>;PHTtE)&wJ_0K7*J(%OUQM*tMA~` z-u@3*mwumz-Pvgq4|EPGg*^i%O;_NLZ}Z>2R8Qno=ug~MP=Vv3T9SeYn7nz~tBS%% zBkq?2vTKv0cET2aW(rZ*W8y}wK37MC)OmQxC2f+;w0aS>{Zg&q+6(4XPJ&(A6hi}P zqHNJSavPq@L2R<#H~9CoBE8ZAqRHK_Cy?QjwoULEH3^A{P5Lv;dQO8;XGd7p>!Vcj zUQ@b#m3cC{OX=RH8>XW1p{N94iH}hn$~yy*)-r~fe!s4Ny6u=rrpHI0-X4r_SF8`| zPPyu1^Gfj)B9k?qk9arPlav@9LR$yHkKa#6Usf@!E`fBmmF?U;f)HsCu zz)RwBOIc6OBQP^)LH{n5W%dvy%EZgGD0X2y7Ld)3Kf5M6xzeTse~Y%la9+4eaI55b z<2q9Tz73IoxiVBesp-Dmn9%){EYbP|ll1FT?{O2ag~qA5$Dg$A#;?qg-QcxBp7^|# zvG;79@JTUDG3}u#E&YjT_aHRWRi?N%8H~4}ck)KTAfHH&m)2wOZ3?lEGhipm*p57% z+X=X>wrM5|?$%1(#NtHsHNl#+7A?a|Zw$3fZ|=)~C7_vR*}w_VFmuYiWE4Ym;oU&G zju6Y!%C5tB1&q`a(e!`XFC|7t$G6unFl?Gh!n0Lxzt=>{%n8fLO=DHCu|i&~R)b^J zm49KZid|faDR0?^&;oCyd~_I5N;LG;U4&PL^AVDjp4zh91zbYd;+|u}rJBSTD?Eew zVhEalocbe2PLCW`zmEef>(L=EiFADb?P26%$oh)NdFI=S2_NcNiFca!4s%W#_~Cqpv>yEUaWQa1xDVfntkj6cWtk5D`L(SQM}E zh9w!kzB{gfr->QJEp(*4C+*~*Tc!m{7-!3Wv^PW`bo&8#{!@_RO_u%D54>-tZRTok z7H7?I(frN`+p{w|o44ai48AKU(D zZknyv)d`y&DE?5{Q=z#n)-As!FL8QbL($Y#GG(1}B0T7isz@bWH9F!W?1r=^&wOpF zprdmKFom-EliC>jya%=bIE2yq$>y<4L4`7f$TEjy$iA8b!VGwfpuC45AT36J>nNM* z*>p|!iP@di*M+6(e=B*+H`M4ija0TMt%0=S%o>HeO^?_DDTO@9T`< z$b%iTfEK|TVVS@)+Bcr@TpxeZ;}G%2b@34r%RBS{#xRXYwXlM_e*J1|T}s*OY&~rL z2IAx*t;VM*<~8z}$(dE6MKh3pBoU-zbr;@-1iMN!j?E}S)BN^KUt5b&9zmNUJQtJT zzp82*d~M+D3O?zzbaNKoczr;FBA9N zIIe~7Sa)Mg4yCwmc9&qLDW@i&X1p-wW^K?~eKR%pwO21ti1dV#Ap z0DM<1t2!SL7n)~eOQ=+TZ2-La=M3KXmhl%p$lTUyi3Xc5;zBcM4K-q?)_4(WJ`SDv zuVc#E;mGn*9A6skfY|Yf^ZDyl9IXVggg>j>$;4^C9=1P<+8EFjl0hN)EQqIuv*a_{ z+(9^y&24mCOqo}*TG-GEAAJ4kCvYf$YyI2yZbJsp1(mW+wjk4g_^#9GbeMUaS4keZ z=AD#@s_Uvw7Dc#a&`zN^LX0(}?&G+*q*lp6(LYY~W|Tvt&4#1})$7+#6W!996w zHLwGn(J*$IVHmJb#aITa$Cgz0C+MbaP*svK@K#^eiW0PL$aDmu^0Yrn%_KrLoGgx4 zLJhbWgJxJqmK}tDI_O5cbT8>us#Mfb7U#j=4Mi=r6=wl;ox!FuTlVL)TZ-0SYSIif z@B|LF`A>9tS&OLAaLbMF(12e!gvN6WUf!(!m)b)A2Y8Ioqq>s3axMbT60;AXow8`} zMWsb_9n5Kw%aWGi9MlB)RfEQ8(#3{@K^cObi((u)acTK~Rc#GYf?kCLx$0m@!#v{f zjMkx&y;|vHf`O(+xER9QeeiCr&g??K{XPI5QI?>vRQq2l#79vN_`IBAvHZp$5 z5f8=t{*d!o^)n-TrZ;chVal3 zAlxXlrKVVa6orgt?gT>&8LiTy#2nq*Rut$Brr<`(uc)4dvaqAIh4T(d+P)bn!WTLf zM!%WJO24{>fhM^|1KUZT8^WEB{FOH7posBGP0YQKS61R?jVSCXl?uy58MLsMs@O2d znGu!oXS3l@<8$k5H@se1;AASqAA`7y6@Q*J?6}!~5A4#lB_-LISWx|J%8d3ylIB=k z{#jIYv)CfXqmTQwLd9P{Mcdi9)_4U5V}O4@T*UkJ4H*2K-YTEsih3~-iS;$nMvITG z&@o=6Csw!&L1`}t33v>t}5arjGp5qus7fa%NI$X+^34!9g9G^dGWdm6R)rGH) zJWX*moue6)r<)U?(saHmk8cEdz}kc4%zhvxXb;;JHzb>sQH zgJ4B74p>Kmy(-P_LD!=(KCR$<+MKau9TaMi*{t=5bYzWZMRavcv%TU(?XRGJxo!mm*`JJ$Z85At-bXx-5!aD0+rC4jIr(eQzDIJ+U%TM9;&CQ_hO*7$ zVT`m{BDhluA)gqP3500dU#YB0m1uVJ?(Kv9=t7I3;hHb_nIKWi2KBm|;oKYzt<+mlbj51nORunhvKe{kqx#*OEBRX&!4%_3k0_QPnA- zaQuVnzhP??n}`)mIoXVVYYvOQqdCML9;G>q)of06>tdQYmjw#mP){>>F|l}+e#^yc z^jk09g5O=dO#IHpmM(NNE~|D&Yx2UfpXzDE%bNM+%BoE}ZmD0KklrOGs^`rq9hjwZ zq5p%(DrvdjP3X8?fD3ji@t$7xe1-zGgW*(6kuYc&!9*1VeyXK^M_wv~uiQi0*qdIM zX5>RBwGP+{>N@e~vy1sjxdeDbrOA%Is+prU4=nI?=nh?CD$JoTyY77B! zN6@wN#b7R7K6Wm#F@e@dWqpzGBzAkvM96awog~kdXoNDHVND7+DU-Dc0iNjTu&VQ? zHYzwyM^m-Nas2&%cNAW`nhkZVS6BCTymk?X23a_0$f5;saQ+NKa77%L1LeK~Qf<_5 z!HH(uHLGtv9@Q7GCqmIp!7r#R(99H=aW zHDhdo2rxMDJSe)^i$+v>qQ#MvQKJ=1wY9&gijB<0QceYb+EZ+0M+^|PZbWY;%F`wj zE7CpI=|&h>&SQhP&9wYvb18LP>XmOzu54R!BUVvOxsfto#L#A)F^ELni}sm>jS~=C zZ3`IRid*>IVgTsN^uj^p6fOh%~nAs5Rxtb0aw>Q{-Su&~cS~-W^!f@g6FWyHXr=uKX z4B;a;#Zn?%mK{wxB*Q4-{IYRG6zh1=OrMV?ul7mtjLjC?P^~2e8%ar{b7hE>uMSd> zw1<$ep#)Dy`)Nqo^hmj@q{r&i%{3BCN70MviQc80TGnEG9cVGSj+URsi@`97VV_~4 zzLkZ4{Y;k&zw(#36YQHX$9I%%L;JP@0Zh>IuTQ7dIW%j0D?}%@#Y7aME=;r2n3Nft zEF#~#HLZIbkIgIwadO49od>xm(rpgts$ep{ot-wB z7^j5qYZLW#IyVcMuT;+h|I_{ZXV7%wg(em+7)+Z{@dB~uhlLB=5}Tv~%r2YRUyoU8 zA1{~i#?VYAF=igkt)9ChZKj9JqoE~Ph)CXH)Bldx11W!4=n<<)Z>kOG?Q1!Zw$Gk_ zx!Na3sr%;2odIz3`FlTsPsA^!cI)^?Vv|3iWc^0Hz5*lVg{GqkoNDB4?ny4>64q!-v9aod7)k#A{>7(+z;B0FNU?E zSHH}%$55I{K%oS+QJAg6n4ZW)+Z{K52?`w-{VvWpb&!FHQcq-Q&+C|8rJxu}$BU?j zUOe8BOIw*t!5~GE_QXqB*}F9^@kR%jTcvu7iA~723sA>H_zOCK>b^_{001f-uk=% zcaFNRz=82r2IN_kwGMO2hX)yo9N)g-kCuk=aawM=F46Z)Q=Nj z0l>FMDS|fq)R8wT)dHg3q(fP1Ae7!B?W1@OE_lxi8~vn*?sM9%Rk&mVX7&-TL3t{0=Pp8$zO)RBvJ zXpGQ;K$ZYHjm|)F z{qf=t?H@n1FaGgE^U}F7u&2)IvZs%+a3U(%o8EM79w!N{9F(kyj@4wei5LM9j&?TV zU5^WhJX&ZBFFsU+)w)+}bi6o5op`R9Q%tJf-00Zac?jM5QPxEM=LDYjfUgIDzktAZ z%>20-^k(LjI95?|BAw2E1a+}KpQPGU;Gpd$e{oVv?;BhM^+n;0PRl@BBN{oP8533D z4yp@qnRl1aIKRmESu1u|Xbly#GPyViR^;P=se|2B5m+lOW%Ce!P$x~>(qDx_wMVT= z$YREt=~8siQMp;<5Thv*Ye01w1en`n-_!LhA&sdIA#^KM=s=;@SsYMfTioed^JV1k z<3yqpsx_XGafZCjb{&iny2v)#pz6}&7(WQtb7d=8zNXdI&cEZjyTw5m?DF5V1pn78 zzWrJkHC}b>7x*lH{})WP37%`?D7X&4|FbFhpS&GwQ{y)9bN|Jir=5u#2ND7tB$!Ni zWXeq2>y*A`fVuI311`p9{5ZIw{P*taVQC{N@f~;f0R_p{YPFJ9tM%@x>C%3KZu>@M z6s!f=K4B*%?HYHUgdh(+rx!IWTb=+NNlyK8*xjjRtnX(JzjSU_#$-5#%Q zcT<}?thN|`C{NTNjYSl4-R;FM#G))(EQ%mgO8|wqKl0l+6Mo#VjTOwD5C2Q$e{{jH z_YF0*?j{8@dcAXA!Dp~nT}aN(AN&2@`Qu=I{}*jAv#Cti?eOe}>1HZt~3THcNL|2HP19 z`dgS8Y#d=a9I(vJF{ZnHmN}SWddM@!LriBZvoScvbc1I$-(b4MGc$ZLWVme}9n2s- zW|`@K=FTCeyF7Ea4e9PS%j~|vCx`5{qc_tbrUyI&uVH$?GT6D>$aZ|5EJ0U_K z2W5=K4gTk^!-$6{m=q#9>pT!8K05o(<@0U?iU4V305<$JQN6oP*dHvX=~VhCB$Cf5 zV-%^JsJaq~F>NRzN3gpKZVJHK0`-ZH7k}LK2F(Qxmp&vq4S3tvs}6(Lggvf2kO$X) z%d`}Uehj~CLa5V@T?>_kg|3$-T`w2uDm#4hRXQlkqBObsl+NC)=q&eGfiWA5+hI+- ztP^=)rXRg!I6}RP2~n{ySCxNn+h|(ky9>Rh0QEkP?%jR8`X+sKp?qZ`_S|k2&lPj< zM}=iczh2mD&v-nO3qBb?a+JI-D^=cqRqN+#zzw-#38b8r6v-MJO%NPC5Hcx=GJZXe z3?P8O>_p>I6`|Qj$mx`*K{&ULA}y_z3qiM_fd#oFp=k?UAsNM;_#KNXk( z_q7jQSd77VffTPiP^9$2;s;%sCiIQPIw@3>3)vVL5ho_xyK9~_T9Sd zB9wa*)U(gw4%og1IbZUcEK&4-nyNS#imuG<<$fI+k~Ki7gERmQSkY}NvK>r>dr<)P z!=(`Dts*^;jR1AM6w87l%$HF&Sfp+ck%E?A5BPWcz6aL6d=dMUQ8KsVpcaFkz)c{F z9=K!K>(}f;H;p*KGAaTa2ZpNxFYepE?Bl>I0B=9U#XQX)egXLlG+YROikm!op8N`> zUOq)T2Szfhk3}C3Z#ap8;fTrRnq%lQ?3!6|kRXZRmCVxDSl9{q8W$UkOEvRLocV}I zsUw2=vTh>YvC^gCscz~tjgOaMhKffw46Dr(_(~h_#B;gd+RZe2l`n!+ui7$8Q_N#p zfcJG(^5quc{n^zs0Za z@*-YaTiahW$0N9c4mnu&4=9kkBBm zxM&@7X@S+z>r~|~jyrhS9MQ{e3~ZeUp?grZ?1n};ZUxLuDhy*99uN0Vh*u@JYpz#S zyIR#Nfr65)WxWc2%{s%J?1oV4H!&}sP;eeGSomMS0FLr!_VuruE36J~UTHP{#l*dAI{4Jg>N?N-u5(W6D z3aZv=ELdV7X8uvH?Q)YvVP%PvEDv4r4K5-0O2KnE{;jP+6M2okw2(p%0N4+2VP-Zq zK<}~O1UO9rlOr6&LovvAd0yS9w*>%>0b1$k`A`Okm9f==RsQ?1wSp|v6W}~stVSA= z_bsR%;OmHgW>!bdQ!VehPDi3q&B~`Dx8-SpCosgA{F;$-s6h9L2SP#LYxaBg5eGUu z&62wa8#Jtv>$D_)jHPM=2bfVArnXNYtI;sP8{-8n zn1w4FIVB6xXvJKs*o;{U?XY>hWVCn%HCRDxU6!b>aNtbYfVm2arCN!2k?~1(?Y=$1 z*SV0oZXqVIpiOK*=pglkWHGR;R`GFM;izI`63<@Ns%RFNo25~MC4Ux^q*NzXw5yx! z2WruOzPwdhXpXjJ?u;+fI4b1a7Yk10POkibJ(lc@Yx8&p9y(YOY&OAUH#C%;VpIC=Z4 z@7S?AS`cYs;7<4lM(0eYx`@|CwEB*d~CiKQ^Rx^SU637cz)q!JDy_t7gV+zcBSD zOFaUiDU86=T%GKXe;*EPA)KE%US>XKIn+{2lU%@ zO*W-7I8cK|)eyU*u;v2fxN%41&n63h`A!{R>~6%4n&6Bq!-iqL{Ygg;C8r0G6CvjU z{id=y;6bSa)+Ilnbsu=pXJ(*VV6dgmV(b!25V%O0DCq{C{6&96-ZVno@ngPq*H3&y zRuD1b=Z4+|)tnDS0v(h_kfmNYZ(M!E90+sA?ny_3$Cft%TBW^QJ_SLK7J!U@w>olK z^S0XIN$j-t)s~#kU$D))?hfLVvR)pJ4WrJ@(jBuTtj&`Dw{5_^XP3 zt2>0ae1>9*EW1ta8C_8hXFT+O=cKG+0Jt#sInJK+Njha&UC>%u`!0vc0Un>37of*A z8`-0H9@Xhe_uAaRo{qTby(xHJ$n+DO?=9+q9c=l3-7W3vf$zZ$ zgyR76T>)TkV&G*Z8h`l#k#^~H553-pg|RmxHj?QCAP8*;zN#3-05uY?Lv`|`i!^~B zbrU8f@z`id&;HmM^kRQqYX!3W_`z69reKN+?_H(q5M6c7b84P{Kpd3u9D#F1K#*m8$n0P#HF59UuO}M4!g?Lb!rC8^k%C=U zUqi-3b>ep_iR(ZFAIUh+l=S_@1xKB?^#?yH++Zi=t9HJ)y3^LH8_yGBdCP7Y%i2i* z_t14Tfcj!3YcpNFHgA@!O-e*K($Q{F^tAF|$r_;$o`LxSIY?pL%3)E4uEnG`8*?>{#6`ll-2>p&k4-uaDx}~ zC=__}HUCf3V~qKK?4PHLSMg?ATjIE#iRPdZn(wT!bKuDph*@B=?+2NNP1ay8Z5x`W z{uAaFQSJ5iny6hF4E#-ur0oc+#LVp3v-vrwsYW_N=%i= zb~G~ibSRWP5j*9$K0-;-DV{(^&vgpoMEn^h;gV}qF@D2;yE`7h;mZZ>ai5T2HiJd~ zr=6N!9Jz!GfyLcMALC(G zYfFQT#Hs6mB+vO!H!ACb*?=;|MRV@v3>Ni8Qe29X>@&cr${b`=I9f=wfK1oSb?YZfMzX%68IpiHC_Ss{ttU9_yts8bz zd4c=O-L?^-yr`~nrU}FCkb4k&{rg8OVzxv{il4we{xt_n@1=&^gGdE=T30caf?lkO znO%SA-6M~vK{Poz-rJePXC5+=-aNWX(vRT#?+MX=%p1jP_(T-|oLm?HhSfy2Ir4;2 zljja}Lp5BwRu&j;9Fj5rpS3IMZ5sr_e?tB>j4J`2W2axxTY+WR_=ihK46UU(Lqn5V`QmMl<*5c$t37{^YaT9e1Rk`DF9z8eIO2n$YM|rkHva z%Z6z+fmlpT8*RPT@3n}P+`MAjirpVV<~?q4!ARPR7{9ISj-X9{Az=>mDj{8RmmFvh z66bh3f|P_k9YHXhqC}@}q_NfNPUN(J!lPAxA+8XRqhQ0O!B+AXs#C?k=4b>;XxaYn z0#2ny;aZ{3xEr%!R3Tq!9M!EY{~k@}z$0A*lUnNQEcs0{y&;9ntE zBl1^w)L%x*ttGX=zbfJh>b3bK$86&Ed}Ii|72(z|UUWM>Gc0q5fk{3!#7+iB4{GXv zZ!U<(!Ld?E)wzw|EiG=xg`l}{+M0wl>yfx))By8Dfpw(92lF{lw>_r+DvC{Nz4D-% zh4x*|JPy@P3V~X6`fU>(T8F)9m8iT zPZ*@?x_>E(E#wrFN${-i_Cz9%8*l@_Q@V{- z(USCD`mE`LEp7^wh~En#0p2-&h(iPFnQpf-z@>y4Sj%>O@nV=f)bu>9f zGef9=d_OnF!KJk<_N;^VtF7AIuYdFV7jHKV>XQbp<63$rk0^T{;b}R}^_)R=ESLVc zyXO>G;D^@SzV-S4v|chx%zE7Air^QEcwz4HN3g$PUY*;V68Z?YTyTPa%`w3yV7b$YA4Q&+d{qRrrHb88Ue$h_1@6R3Z;sTi|wG^o?UD=tq+~8 zJ)hRcx3lB?!akkw%PG%)Mg2$Hwe2Vf1JPfZeb^W`b{AZISo#h7xNp7`=#oaDrhseo z=Xcr;qSi}HG%-R8&dfPyq?a`1>khsGTgkCZadeTd`)$RK9zd2)7Izhz#r#q zc8T$4IGaCIlKZ0>f|0puwSnExYc;YIty)Xo&-NtX=Xy9TX-pu0;`XtbKs;S-K5A_$ zQNm*Mt!t6##b{#BWnI$gPukUO2Y8h#aP-yaQZ&BQ=+0!4WjdE^W!x>CY46N1LuzDYPcqOc%g^FO|6Nt=@V9#Pm z^@cTSYn2*uV8bg_Ge7=@IEr35ZC#mw8@B-dLISplx@(=fY%PouctlP`+Zox|Xb^LS z@(h&}Pi{m}phq~OI7#KNHu7AM#H&@&9$oq#6HO2k%#p=^=zw+-b~;B;0FAk#Co>Y@!v^&;S4ahirUhybZ##EcY0{4SjuPS^P&zK-)>uRw?erYGiOJol&n!vBk z5_x@@Udi1Xz!Qme3BN;8s0)Y9hwZ4LIRfa-@qN&UeAd(c zqrk6!wy+PY#2jh*l+>>{u1CnOa{MSr*AB(N7U)tR7c8Rwie z9b3^FU^CXL(I1T+l^2n%@s$qM{XuqrJlQORLEtJ_Mupp^k70;;CoM)po6TyPo?Z&mKMDnn$3SLOW^7D397uUKdBO^ zvfHY6J&r&%15mpec)ZYLt;Aq|RyY6LDMg^&AGSGd;ilcE7_|A?7pKaXUvabt`x7$@ zk8QU)vDMWA-`~^KpZM|arM@inJY^fJ!D6$|ZjaP;;657jI-BG4(YcU>CeL9aMLzBF}X1i%$a3>wtz|oSaqVafWs$ z*Vh}sZ%Z}9#YgcRZmB{D6$PXi->lHlT|#mZg~~;sNZq!7kQ}DR^Dq)ClF*T&^6}Hx zpgwcHMfJC$3$Tl;rZwL(vG$~L)c!`2ut5lT2Lm#;@C{FiLm+##I0GbY&}d-L-YGGg zj3mX9qy(aCPO~FQa7><>0H@$oWsOqt2&rJQ5TJ(wLBBHSXMD=gi91#>=9nsuAP4#kU4pN>$$$vZ_`HJ_ z<%E>%Nmg$Y4S@F2BpF8?;wf*Wi7e_NPVxhOLgm)A)@Xh+m`;o|LpQ--KGcqbNkATa z7fcXion&ue-5c1%68R%63%9I%euw&TT%-v64*A1>Nqf(Hy6t0PCErVHV_4u1sbcib z_Kc?}v^4O!Hb7KJ?l4@{ifTj}K-oHoJ$jtW zr${-Kp8=Z!5L_lWs34{gRikE5+<@=koHW$ObHO9PG2X%O!_mc;Z^9}K0N#TTG3X8Z zQ;ITwt`@O}Ki>JrfB~jVn7Fs%7=%JgkM4@_`lZF%L}oN%F9H=F@j*|2)7z z*Z}o=#CX9UNbktqxeac5M3`_Sak2i(d2~k)_2~^yw$ba`L$}Yw zc(@~X172^qyKfox*SltUFAOiFw zE#kGYfQh}HF=^^=nZVY5}i64Hp1`79yy+qnwJ3we^`b{kwRA`CMe5+!wJ>L{p->OD9<1p8P}~WsWMsGA6+Z@dda9 zsq%qIJqZ!j_ha0AC5`g!K@;C6z@-v@SRSBv?FTV-F{L>HjK4=D)y$d4)fxvMDlALw zi^A^H*v4Rldsd!0AoLdOJH_t3ihy zbGpzPWV@4gZ!3JvH6>SWHh24f-hnU7`i1L))vZfU>Wp(zYtsS=$o^Vy81s+1vq->6 z9)3sCJeG8xNV?ZEc<#3(Ew*oxeh!k}ob@pu464Gpdakmi@^CbNzR+ryYP~C>k+kxy zo;^2$O^zDLkC5O8Cj8Ev6M-QT@Q^R$H@$GTo6gvXP2XGl(gKokTgSnF%niLDaeHF? zP61J&&3(Qdzuuw<`8Q2Oh?~f@fK5a}Cc@1N2Dj;SYe8FwPWakjT3zmXLAj)) z!gxp5h1ePL1Nx$h$Mt%h_QVYG?EsJIXkz1Av0Nrx@E-2X;(^)^hBwnC*b0!j#7!lP zwWGaef*>ISqG;xy5sM^$HfO8n`wJ{05GoIi3qUrq@QrcS*3lC93V%}8L28?y!UXPM z1N=TYyy#Z&GDsFc0w;tQcHo3HUKGTuSsF?jaTkagQk;q<5Z?e*A&gc5ELo!*kluHX z@0@2rEO)Ju=ydIvvcShNJkSQ#OSJ4`UTy$DmR{VE7p?pm0G*$Ipnvtyn#A7nvb1o8 z8rc%EXOb_o0Iy%gvT^QMhpW81+JaHrc`RR?1%fyl=n_A7JLZ1m9!pLyf9VFplBeWz zy{jjgQ@1Ki&JzD;wiwAe5})UIQqmT2Z$#9Bk*sM-fhie1!!VSx!^qZw73ME#Cf^KX z6Ew4}vWu%fTy5)rQmf?ihN;cW!#NnOY69zQIjtm(2Q$M~OrvmIY^KZk^KQ>7co$`^ z?I!(f^5$>y@K%=VYkzKp;SvcW#NXUV#s&Qe8R2d&g(K9fffVeeYM~a$xuQSno734& zZ?&5Ibzq3Px;OStyQw%*OB8CuW-t4y(C3z~J}x^aemd-bJh#}z%%ME@oKGHU7#1*} zs0o$iG-+o~F6iPOnCKrM4$o*ujQ&!pmy-AjQ<+pU0e|ve5mT$^NCf=X~}1r{6w<`}`*-e=mM@`rDrszj~3petmNJ`|RxI z`S96KpTjNd+52z*SWN%+{*WEjYykg-_51R$HIUE0{n^bo-@iKf{_8gvFP@!z{{F@9 ze)BvlUqRi&zyAGcxw!ni?ASfoVEz-U)sE+6`nx25qw$=&PkogUxFu*E5w-$Q{!%yI|OYY%k9f!r=;|zij5N@1`&LhnKIJN+&ouKez#0gXw zV3nVLKYRXc>;Y!9KBl<@%&VO?D>iE(-RrZ8bd0q5RnARss9}Ys-I}LHJKHzcm-raA zREj9N5}2ja!YD_ZJY!c+vZ}|=Vv^3y3(9v(a?aPxdkwgrVhPJGt28WNv~dG-IT~Iz zbZlr6*rWsdg>Ki{u(_!|U4Jm{*?7^y=_U100VaKpkb4EZjS=3WTaOIz0G) zMQl?C1qgMSdX>QhR0|+-X^tQ_JVXib$Knbf+Hto&7xIeSl#Da_LfC+^L<`TO(<^(E(iinaWdvx*H&}8rJ^riefs*_R}e^NYbClX?OA`H z?=PX(s5YUYY2-0PU?eq#v9NexH^Vu4A($sQ;=#GrYeo4^os zUZIdb*zEw?7Ghg6=;_uk)9zCz_gu(WkG8sxlGn+tc5+hqh~uRWirlzap_j1aioyCT zRB6gbisMbzG^Dop=ddiPx0Mf*ey3}L&|0{XR!Q}h0EbY?(m2xdI{9S@Wo<8iY~*TF zvOUZ@OI^Y$|GRd=xIfg1*R6!A@vrB9{*D@+w$}z>q*e1J6%r0UWoKMi zHsKHM?{nkk+jG?!r3c8@4|3h?8`_}ArTLnH_VE6!&%{87xOc{D?szxkt5Z!HIv~F* z;ruuhDh_~kIW@PBnF*uI7Di)#(V{N$Qsq2>j#xXqN|6UV4f)6+@BV&~DAq0mEBx3$ zgs%&`iUcB*JeYW2iao)apDNJnC5u4ssllYG$Nh2%vn{-AC;VQQd^F2SIJEW+KIwY% z1wDv2%?*V<+o8A#r9eOZs0w0{m@Mnl9w$t}Y`cWZeVsWJpiXXntJnd52)#*Bn0ia; z#*>LhPSOOtAa$z=d?A#!9DZD5YYnYjJ)q8`zozLDU-F;8{(Pb%X2^XywBMfTGWh(S zi0?9T13GHQGS05pIv#va(Fa=hje!bcr)BFjlF}d^;y1rK{q)Q4UcXkQ0%X?;M-@Gb z1-kD?ul!3S*-C>{St7H4P9_3z$xP=jzI%7}_MIFGH}TEMyWgC?lTW?GUw!xfJtRK! z63^5Qpg`1I#pdB1%3 z_M7+Q8?lW>`IDjF!%G9<@bKv~!Mx(l!gyzXd+jFD@^`i`Rlc8pO3vVTvfSJjfn%da z^sFcd3{F>jaqO>l9!-UMWNAJW+znLJ(XQPLsJ{2j+k4&QMt;n$Z_(;ot$N7G>}Wmq z$Aq|Zq&!8;EY8NxA=oI`uOAl&!>HfLij zJJIITEbBoLOM(+8Lm6yS=Vfpc=9H6v8R2+wgD|yXk(jwZwO7ha@77F->TpKYClOC; zA|xFHU2e*kILka+pZrHP)DCCMI*vy?Ti!KHMcVKX^&07aWkXkNn=y^3SO&Qzv>-UF z37xT~p2Ii_)!Rhd?4XO+p*d$~2ye?jAKAh)Tjpu8!0p+RA&a&}Yt$5Lw_<`Xw?TcM zob#h@JDB(UOlFX``-pt{M?UOJyY*Z6B`kL4eUfo(Y%4-F!DyE~%kK@ht1VnXz=5bn zOxp{(Y8H!so>aH_G=K~3z?(*CMiW(6Hmn6nLr^MjN)f+d3(=>Jt?$QcOmMCc zWoAg~D6+_Dmyb?;4Uh^pGIyB~wk6Y|H4DC=3fbQG zdW49tjM?kp0@fS8WMilcY@Z(!3 z@p4lO#Fir1e_T>haR&5=jc4dQj_?^jig$rPX>itq2! zmq;@DvoG#6N>kVlu)B%WZ=>pJ!ynl%lNks-iy7<-@U;th&HWk{B;FXuc(56tq+S|> z69qEL*&7?X3d9mn3|z`@n`PEgI(*KR1A&Z(R{oa$Om3s|EBM_SqW~{Nj(^jYIgu%h;aDr;M-SJwv7ZBTV#u;e@s_zt3@fl zd*u22a?$4VyGfqCT`mq^7`LOks`L&er_xWe`_*wqap}_gLy!q-D~U|q`1+<$bl)33_*)mj)I{9A;c&;h%Sf;OePax&Uzn0{7i|n5 zs9hK~a>mKxCb>0HiGy~FwCI~L%**2MY2H}N&f#3-m!P(ov9(*}+e!}Cg59gJFkqJ>MgcM_KET!@ zf9iev1+wr}?#lhY3J-)UoJp1e<>ZE}w)Gp~rpqeF#^m;hQ^h`)fJOl&OMe}yTeybn z+?PRy^hZCk#S~X4Sz*6`iB;F$v7G(}!4}k(=&_r}z(ln69a)OB>vBxmuG-0EP0w$-G6j zhCX{XC_d-+HWRNW)1w|#gWWYtiCjzfYmmWz07JsEnT-PDuVi?W(3%mtuX`X2O7{NLLs=6F6 z*#>gCX#=^`AkA8G;1An$aIMaOX__sf`IGkK4u;~&HI;NOvRgAUn8mC%IVI>{i(7Fn zZrD}al>~JjE#>!xdAW#p9#`T}!G5aZk)t&Rt=_A6dh1SXHgoFQE1Qxo9JOaQpa%Msy}&Vax;S zwS5U^?J7Q#U2-2*TixF;=4RT4Gj` zeDGYM;8|MdMNOUf4RO%?!ca!+-kAlQS$B1U%+(C06)=?RXoG7YY`F-lnialFRa?$h zrKNXff+f7l>jHf?@Q1m!uxi1Sj8e!J;cTqE=J|n+=okqdZDa%E9w_B5CT1zgXNu9T zWPfSQ$3T$BpP(ENEBeyBJ0>V0i1~+^Y%q8k`TW*6=@-Ymqn9d$s2z;3BD=om(S^Dx3dG7$Q!LAW6!R<=Z>@%%WO zMA?ydWEiO_>=FVmF*@){RI*Wa%K)?Uet+ofI?DPT2h?Okd(Pq3S$7cX3gI}C-mt-| z*bn>vY4LL>9Xqd2Y3iz z*-FswhmV5$jxctKkJX}D7H~F!_TZ}+`2T*r9?xNRp{;R#RF3=oJkAc5s|p02D1YKK z4vh^`D_mx+8MVwfH$dA3#cXy&rGG5X#_CK6qyNcMHIs#G9W|Sd0Rc*7xo?zo`Z<^? zfX0Z0C>5RYysn98_pC%d{?Lq{(Ik;cnL83!=Mn2*l4l-Zv?yu{4D(3c0d@~E1M}uq z^Xs+JT$c`E5uY;dY*$jes}YQ|80CUG8C7dRCIYX}=OKQHoyF49{SRDSAXDLSr)_e<)_M^ zn7~zM?e3Vc6k5QWd6C+0_ka0qyWLIZwi}M~K6IOIi(jWgc&CWdlbWHu*dn4B73Xkr2GzQyfDW9d;0$&-B|l-qKEx=NxqF zayv&rmj$+CJx}zc$0)8}022hvBy8rLXR+P6FOv%V=e{={g{$}uHh)s(e^5CkT`p~ei(inwDrgX_JpLCrFq!mpG@l5eO|1{bIc36u6&nH0f*XS zOWJR(<$-F_*LdQ=-1S6U6w+fC`z=j7Q7B^$?PVQ#l2;7f#A&FCM~*B|83u&-g~IR) zD^Y>;KdJ^Ra8WZH4S$TI$v=!Ta}#PV6VNE(|8u!@F28J2#Ofh)-^m!WTc3tSTv;7y zfww@J*-ufiy3;b<6^EkS{QiePG7XDN`a*UTzD&rf=kSI1SS4POi8P*s3KMY95zZZy zR)p@M-6VGFeqm~tABw%on}da>U@3w^9&brGJ=@QuhU`=yk{A?};7)?0N)nrVioceq#I%n{c+;i}cv2_um(PO>u$t zoL=4N0Dur$g0)#%n-JvbqHTMDYd%}Rh;=NZL7&guXlmCe4A+VUTNwWod9a>Lj=rDV zj&cpoDVmpQ)TtS3u2W z@gey*UiIZ%JzLf#sOclQQl%EH+(EP&l(CpL$<-p8rV;QSvAAp{F5+=$W4(C^y#>e1^HS=2uP8a?%eI(W+v;_KHY3A$tgse`Ge`MACW65B(k+@~1FCW5uTTFmkv*L#a1neAN_D0%Mn z`f0znR{&|$d$WwPrwPPyRNFP!$%71@!9sL;mw%KL3m&keG%G_`I7IHaqK6M`1mr}v zM4e)$lpTwv#-8RPdRe|#PRaxQIdak?UHAU}ZXHjajq--|80U`8yV{rTXYM|>tzuyY zE4^{(BpW+~0d9-yClj5edL~*;PaxOxHT;T=>wCbo=MrBYik!KL8i6#=(|`NUd&tL!YVeG+=l^b|a2)^N`C94GolCkSe1Pej#*FUJG|QbB?k0fyH-CdA zxtr@=-n;KLr`5gboqGUaZGj?(x$b#zYd`l}V@T<~cM3QVvRcyCVCDXPDmH+GVF~#@ z@nvrJKz_3(TznkNccx{+(n*gr0=kQ%tdqarA zHg?qQ2H&goMFuf^tjtN?ZtILY<9~bjVk0;@-Usc7j+eaVKZlZl(LV<#+TZd@V4qp} zZ^w|mlVId>{iT3iZvpK3UjWoxJ09P0BTD;H`3dTLn_?Q1Df4aKwOEHwRsX-F*m@j- zKp&<;u$Q$kZytD?%q<9(&hkKM|E1K?Pk#FJ7ten2i=TY;?CJ2U;Sf|ket!YwUz>N} zzggM}6hjnHwfFpjw~)#{(1p6O;me$ZN)l#JC`TGP^_IR2zL44w+y z9lEWAr`FC3e=Ufi1X6oEBHn7D3MvVxb-wbncD^X|?x*xB!wJ&qQ@Z!+eH3kzklqTt zo*|!F_r{GBzOp*Dp5l~Yo644O(*3vx&VK%eD%$z&ckf<9xqk1*@qf5CuFG3JD+~vq9hhIE)j0B92oWktp9wKp?>cEUZ?#& zJ^xKscjde({_Z3T6&tQJmkO13EQy!JBxDhAA&`J98$2XYO4=Z*Wy&&s&HJuy?@dTj14-eR#3A8Rxs0F zr;9rI?J8ZRvMZ6tXd~g@$Xv1`ts?@E9)R>eSwR%eFi0i>xj~#kl0_X|7KDxg*wc<=> z7_C5URFDwmqJO6b)$=r@3QiT88czCe6Ht9p-IeLKV|P6G9yUSJ5%)gzjGZeWZ(IW_ zQJ#XJZ_$IwMA&zvZLhXfLB1x%fAl2!Gc+1cqCZa#9>UVINar2CBW0BxII^+8Wxh>>N*}U*yFynMfUsS7EP5O z(I}8ETkrsDU~}Ka;4##K71R)-3&?)(_-co z$M5x~#ZQY7@InjETYfI<<5OO)I*ZqyF4NjUcqG`Gb50>Nv8kPos0WNSF|fdG(%V@2 zh~kfUon7RciDliD$^o)Oi~^RQg0{)X+k@F-v8to416mx$2uwnaO4(DczI&5aONuIt zSAXPGUFyZ7Ev29*8V2u{zaeZj#ljl$*Zy6c-?ORF3Ichc%FNG4ErG<{1Z5GP&)qD;TVG>|! z1!ICWNhEp-^wnKs;yiK4U>c965sqTKfPeK(tmK&+^o%%hnJP1@DW9oCoAIJcd%Yb^ z$`8%&kNU(YVS;dvLc;}In{Z#WYW8EDBvO5x7#@1%u4xaVg*~JrI~8KpY+xN*sJ}sw zc%+VBkI*#P&2~fEaN*rQ8JVu9?|cdrz4scfX=0(NFEVGao{6DpGq$=9*H*h%0mk<>#1t}hgClW?u5qg#y+ z$Sg%mJKIGYl7ULKorL5brVd;~$Xk6=Ni#MD1Rg&eT;x?{m3eaPe zl}a+cEsOj+(mP4|)L&c>@dJ|fT7Q*e^GzMd(tPTdHFQ1dZII5|byAB1zXpodbHV>vVTTC5`XLZyo6ag zZXv&Gm{k4r(DJ&L*`*%z1Pyf4`g7!e4&0(5lYZ{8g@h77lJ^T7*#dk~_J^X9?e6^I z<4)9x45Tf$A*l@LGUi_c-|&YGPxxAkF7 zz(D-H!!@C`zh(V}8)w>VoSEG$$9ZJX);iKG>as4>Wr(`m+ke-xkBsp%*y6ldc$d4s z_ZFQ+U)YWsSukVuJf=-e`kNZ;BjGJ(r_E&&b)BEqqq&xK35e5N2cU~b5j%>4wO*&m zb&9n#()0=M(pLCQR=hs4#ysw-LR{xW=W{0=k+*;Lq9#hLXo$kVPKssvz{J~O*~kL zf$pkhH712?IaeQii{j}^5>I8(A--M}s|x-_9{iJP^AlYrZ;@u11nYc5gJp67XPj7qosf?2E8wS78mgE zt+@5}cg#^H1Al;g^ZSo$aV{6ldbxq$#?~|Vgf+Sn7qK{%H{uK@ZE^63=-WI!dz9w* zIQiGBt0gF)(|HWIhcFlk{5v_5g|z~NW3xAcNq>O`C`k?Olxm|%{h8E7<0igag3}n^ zK@L_X-5@w(DU6E(Dz;mTXAT)QSN=xx>A1+HA4@<-+zW4e)k4W{8crrbxR_9e+ zCR06xCTkQGJoj^x`x(X(hFMGzfdmPBd7mkKhLJQ}Tb}$(Hk5FOYW`vwg{vBw>l^U` zRSAD(N}JsmO)byEZ&dw9Pw+#(Lnex=qJLA75~^!~9&VFaY)I}@refioVe|^Eu;CzM zVd3lcCl-fjq>5g|;sp{Eqymmti=-r6KS$&NNH?)y>mPO&v-Bu>%nPH*ltcIcqI5|o z!UVac4cM#-bWaMfG-`~lbtD!D4l%HNB*0`};t4RBwiR9@T)_#z@=X`Di_R7M4SxVr zOm5_P_<^sUrqQ%LBTL*pNrW2=wfqLZ)IG&(Z`1y36t`Tayxlxk2G?+h2E@unLsxd+ zIO~fKOSI4fNv`w;QT2~ZC*vB}E@%C{0J&|`HZ|NxE0*s(k$)ZI*1H7qPNRkMh~!qh zRtlE4Ax|$SC>cJrev?w*)QES2lYc0I(-*Rt^%CV<`=u6tg^~=808+j#Zt_kBPhS~T zK96TocVhDXn%OQJ><+CUQw%&ywI)74|jNlL+7bl*C*!%N-(pO?9;IF zsCP1(?WqlRFHza)=X5&qjjSronUwk!9y#B_O940=M_>y9?Yw}Ka&WS!2Y=teVR4mA z{S;%dYIc@U^US7%rSLXi+>+^J8{p^ZqPPhIe2&>W0lWcToI4A#O?xQJgygfoW=r@i zfljvIdoQY>EF@9kct`Yu023b388YB}9w_~vo((p#;KV#+WZMVEC(PtLXxc0QN|bAj zN$o&;SC9jP!U9`{v2kgj6MqB?xlMa8%qJL9WCO?v=5K>|1HgEl!63%Ohk^VJ@XDLe zoJ0PuXx>gK9=>_b!-qgv5079stZ#>(q2FdbY!d3?0uJvpFjcNSAGEaeTH~Qodl}^J zk=nX*I9FC`Rg%SvVwKlmisEN|UpNA41#Fd{U13)Z9MOj5!`4o3-G4n*|BfMYK)XA4 zd`Px?Ji#ozM|OATRNjP%lQt$!!lcjuHix$0IcN)}Uqb3$0?A$A=qei^`Ar*=U+qYg zpo?~p%bAvnIL&4f+jB>`dzH;L@b#cr*I2q$Hao#8vg+hI$;h?ZsKaIx6+>KyvtEB3 zI}BxjkBbjp!l!0?fq$VirF4o^7YCiFiaEdOv6;IY#C%$0Ro!7Bn=)CVj>JjI(-ejyYc~yTuWn#U zDw#`(f*CCfn18Dmy?&rR^-5i^pt_q-qA>C{Kf@85i!LM1r+=urKhZLk^u7+x6-0tk z-;o5Ti`fKT(j{5hPVh^r1!s!d6kaww5I{iTr?~Yf9PJxhS=R~X?AB+L`lhHlv$wgH zsY3)mBYv~MG()Q7$U^^)=54_%78f3M;Fl%H65kb|34CgmFTT5is0T7= zGZuMRM`T^5dKD$weGW336GuNi+O+A#uKX`nSl(A0B!84-x4~Gb;1u{f>9+olX*5r-hY=*jfs$7%sT6U)vLo0(v_nJ4EC_0UKmjKsDQM!QMkiOH9w^?X4f1`_vkd} ztVQ%>u1Ba5?4LPN84Dlp6v{3*N0I-s#S%F#DPGB3b+jVwG`HBW88Y0|WSi&Kh&Li$ zU-|nQQ2!;Oap7a{SoAg>p0aVh5p9lV;4nz7>wgjtrq2HT@`h?Xy5w-wFdW_A6V_UbP*G(t z&w+b59E4!MJY9Kold{5JsKsTmBqWk8Y0cJ^JX~87h}86-qb<-~due0ev-I=Zd4$IL z?tj)&8K-Zh03O6gmm*&eV-=u`LqeD7!6hDA#zTL0JTb5rZ&>4p?KM72JJ-0Z+sjnc zxEJBw6F$9*%xS0h|2Vh;>xNA5S!Tm&aEllVRl~sfsY=Ro20*6Cd}@V(4R#OeFL(so zYLiYnGAu+q`p_D$Ugn;%WApNEEU=s;-hZs9VN5Oi97~}6zM)T~MRYT3?O#P9OJgBR zH=a_;A~x^%%oU)18myBMp;=Uk(z7-dm1tWYk%O5kHl}yx!Aieh9W{Mm9aB~frvl|2 zl=V6*#GxoeY0YQRax%wNU{1Q~xsfF4g0q%*7{EqaA^2-{zCfyjui9J89xoKtfDtoI zjJ~ohFmH?;L=AXP8#~jNS7reqfBtKrRVvBnR*>KhP#Nd&zc!NQN&2o1p0SiMY7o_z zR7%LIHrAfB1DEfm03o1g?!!G&p@HFR&~W|06F-UqlNw7*v!ZA{##o|gGSTkK{7htH zt$^`V&2MG5qpH=mT57A+wwi6ih&H$r9Mxt&SWy2{l`JkLW#}F#qt+QIe`ORHL?9~A zInR`SPU)wV7^jLPQtD>eti73>j%P>may&D;)Rj+DyLlR)i9#f?*tPIV%wuBBuB=rA zt%oHT6+t4V7y*_IQLpD4ZCqJ zhK<{Va=lhEW7U3yI<{r#k*JvtqdB=M-&%_P9ZD`JIKs-iqi>y^k zCS5Dvl#RG$d|roqVrxIxj;^*9$b`$|<_)c1tX0bLwc&;gqn&!*e|$Hg1L@6-$S^}; zt7%ix#Z?#@!_ShOye|iu#ST|6bXSYvzYG_fFyTLk*kwrLAUAKhCG`^8U1-o9p1wXAx(N{v~RsnWw6wO-f2 zP9fu8hcU&5g-~Xx&{cg}yRz*lw2znaFF>NEm@mbnuJ#{7C4abL?mVn|dmZYw%P)`_ zhsYb_b=qq@QP8^eFU4;Twd}=AAEAy6jLXVYOIXs`FSb zg^x5@IKMA7FT5*G_JQ%A?fVgB7IKEY)kOys>r4BBe|-ZOE0r0x>}5!widAsQij`H% zp*IzdA*Xc)?==1L+$l<0%QCweQdl9$Oav`m~cruSfbl>Um3 zMY1CpD-FiVfMFH7i7XJNQb)n^b+Ls=e}Hlf=I5$gt)l0p6H&OONryT=@USNhA_xyH zM05GwFJKAH41n(1l^VO*{X%u-u>hvc&uw4dFU(m_p+T2LWu?7s+9r|vf&`MRJ{}y` z5~b%*;!el<{*cl6QMtNlO=bR0R5|x}=C_$qCr=i^aws^1_xZ+YWvb zQ@AnKSZlExZ0PCoUJJCCd+rP@_2w#<4TD~yQFDb_jBJ5Cv#)h)ZY`7`TiQU{rF65_ z=Aba|Osj_3w!F64B!b+DSb0P}ch>kquB4pPg`a9>>W$F#hAQB$t^l#VfAg|`ZtnP> ze2}A$Pr!z@s-sI_3;O-}(KOyra}}yNz!1?uLv)?E!t2EOu~cp>ruZIAsSLP6p2B;m z$0REOaOpCS%9LJ;AgxAAvGDIEv~#IQxq33sgfWhkl5={020dS&{uK)lR{Whn9twAV zl*W@<4Ct2eAusbGBfD?TE5EXXfSgtt|WR(TG}=&ccm)| zq%nj3oKz>c>*#(U#c=!wqJVt}>zwXT+2}M#aZWHdRG-bPXxjGJ~I} zljK9Q`=14@lCyykK13m};2vghJ+6+6Noppj6c`b;#1ki7rU|HHfA@N#8WeCaq^<|9 ztR>3`|8r3F3)~+3X{_BzoS9s#sIusnYRJH>GSE`1>o9;*;GfpwuLYyuP;kzb^M0lS zO|JR;+$oxVc=~a&0$IL~zxu1F8sHD(7p}ncXCJL^{=Y=HRO3HaeQ?YFXt;+_hGC?( z@kK}DeXr4`t1oYSe;R=N%bKGlK|Uq%pG;JuaPNkf5ohx-y~gzr{keJ^M+c85G5w+* zAWFd#Ys@>zR213?ER*^}vj?EGVsRh}`1-2(s^bx2sbB27Rr*eazEd1l7eGFQ$W@31rx2Ob zIJU0rmNpiwxNqypZdOB;oP^FxuC7YHnJ2#te>*;To!!t`cc3%h6`OS@HuK$)88QvtcZt8#a(H9@gd+%zTp0!^IYxz? zQ&3)sH0s${L#@E4GdJ+5d4+hVoLV_!2ra?SI9_vkFqonwm#ggR#?`ng424rf7!)=b`K(9*VDC0?w*uCDU zma>P&Jm={JG?33AC}THFJiXl_)*fL%d=5B!apgX!bzDMb6hAb92$p?CgyH1HITK%N-V^(VV#R* znnR1vOW>>1x(kVJNB|N6b0Y#~{o$I7Xdj_gfBwaysBB9Be<3P0f|ZL^#N*tCpZ!33 z*N+CsMDd2O>q0r7CL$^s#{$YIY6RM&wBtfOd{!j}gGPsI(V;6hTw3X?a92%i7#PHZ z(cvKDEuhs$hK~v}UIS^rFA5`m4SeWUqOhD}=5UUDdt-qjcXa6qjw-ipY_*PmPv%Tb zfAD;XO$_R*o=PM6>&FKwZ4du`QlU2Y?(j|fMOmysHNW?R`62!{hVd39e17%SSL3x; zi-J85t|;2`-W|o)AMFj7pT}M^|6uLfyW6Ir`2Tzg*Ki=FN}6Qt*phjr8-)!98-u~1 z?dfqFw=rw&96#2MHs77!y^<`;k0t{$e{gL{SI?`fE9pMM2lTH7O1M=muCGhE|KzLj z{(Y0WEzP(5(-k|pK#E%S%HGh;9Z4eXKfFwpo}cta4@bh$53dH2VQDANO;#X8y{>R( zSt+Xs>$OQ@%!D|vmGqTx?xUQM*O8n*PKt;~vjzI#fpESW3unB2|4vxaEiO>ue+KZw zb%3LjG)O;KuvFchAs*Xavo~?-Xb-6Y40_|89pMb+e*?5w$AzcEm{Emw{3vNgdKoShw3NYDYfnCSZn3}Ug z-SY5m^o|Q$!$gh3hbVg3C>rEE3hFaqE9epp$aS2Ro7$Y&Q^-3@g<8Sas5ve;Yk+#~FT2 z!}IXES|>9PJsU_$e)liP*)oS1#Q}R&kkutzAKk09ZBUb!t>wdC%n=~R8`HD>O|aEH!S8ECAiovisZAuY^*=(dt}Im~lXRI@6YG$~-s`srN>h#$G zM$b;^-|9Y7GGl!rXl?zEYN*GK*U|X#kf$~$Y7CRyC-l#YXjW@$K~7uQ<5+Zw1#N2) zpM%NBLJU{*+mn~CuZBN-cb@Fw_tP(L=KF8X>2;qTPoM7nL4W={e?R#n=Fs8A{?EVt z{QUCwSKC|ooo%1IxcIQO_2g>r^0)KZXzOY;+G6-8-@ksdv!A~E{`~wL%&h06WL(Wj z`8c}&VY>W6){CR9kecohqU44_N`_RRI^wGCJ6`HD*k+h< zN@nY8sEv%@3~B&ehCx=Op@A@AO%S_T$MURYreTdIDOEeEl;*buc4caxpEVoYnVL3b zH3$l7O>e5rD(>;Bx${d&+re+Wt6mO$DdvTD)o?QjC+ zcd;R>3zYsn4Hi;VR)t+5;2RJPfbEVp^GPFA-%22IDel0%<|X>Dt0}GSqWNfESDdc~ z;MHRmvbCp8-$c>850|Y2V0C82XKU#L!LwYsTFJ=}ojrRS0UJC3^4#BoGH9&JtcllzmC7!CvE2YAUiO>gj zb^~;vsm|HiS}m|aRyRT2-&m8if@pM?V=ko|!yR78=U@>a+x(|wCIrbJN#!TFtv|>pG}(*4@{q!mfDyxe5j>R=77ZqG$lHSjPM3p zMxlPBf27Yu)P*z^9mp4Dy|w9`(*L~d01$btN+o5~SXX8*O@j}lEh_6lPc4A04h%!v zZ=6X1Y^LKiV~{5nLr>@iD%ZNXXs^by5!j&EcaMvu%9N8zPuS8+N+SxrCFc$cQ^e|Q z8ApocA*fgVkf}uIR|A(zd2`rREAB4O2u_fae@vK~VX+XeE0f#X?)=SgbxBKkZQ9lL zYHS?}qd8V5kRw_qLwSP?<=s?=Hu=)LPn3LM38m_GaU#}~c?^@M^<*`%b} ze->~)Qmx;#|EYF%p!3Q|d3CT*64M}_CmALfwj|Z)zn`-z*^bDKw*;DGXhDVei`sfI zWLuXInf;D;mcXxOmiGW9y_!4=X}?rn71*H!sO)#h5D#!ABV>R~kOjY$4|r$#l<#C2 z9b`n?vZ-$<_HvmY-PzC$0D^oTV0{JEe@!G94z`gpmdh^VG>hcw^ECP3K@0Gv9th%o$|6hPGL``E8X(1ktfEys*u=c9NN3S%e^L1W zk!$VRY7!;VFP8d}DO?VaJ^_%XK`+nOw6e4-yK;A4MY{alV!9g6mf8iGhHQ#0xc(gWt^QB_LM)vOjPdV?Z3Ak@LRZouO zq>&gxPOTCg7|9ovom13uIFIA|tuRfKl&?+JcGGH3^zAeIkCA0FPFQX6u_2i@Zy0WS zMRWNs#q+d z`qh*)dS91@oaXF0dmp&198kBeHb(Njc1;ALV25beC14S25#@olB95q!@n~BTL>38@ zuIT+*26cWGf2tHMx@*Q82Tg9@cSF-Qcj=J@gkU!?`;SQiqNa&qFBS<}E$z^pX-UE} z0xFfRd#B2wH?mL8oYV3I%!RPS2@2We1fWb49p_OR4KKE71Je5ae0NnM_^{t z0fQVZ^-K*kqF(qnbP+i@a9SMD3>^)JYS22*kplgEU)fW;?VeW@{&%&IV=c)tIZ9 zaU9^|%5gU@ObTT}#tg!WWjgbCeM2FY#qRy4fv>Kb{T;aqQq?;vMYmK7T1XaMN$eUU zojF9he_#(FO7HK{N%|N)y;!T4*o~kmTfCxbv8h=Xq#ejiY{5k&!5#hiQ~gbsS5(G=r6xN}R+YeJ&fN zAa^TiAH4EJNwkb15r9 z&aqut?*uFAp1kYK7;)X%23EGs3=D4Q(=e} zt%#8i6DytQy|jCEtjLfKzDkI{P=6rC8=<^zU&S(%|A=r{OMtB7`QWseM}e^N%u zUaJspTKiCWg5ui8N=KT((m~c}sj!aWQnB`U>ConYfqB)(P?mZig4Mk6L!mYSa_)d# z(!=WVEvO2Xe+ZEJ*l%1ot4uj(_IJfgB6Q-8^<%4 zOL9(w_>0^jO&ACKpYy4^nXzv#hKV9hA#?FjuBCMtzuHQ(T%Ws$8>TY}d+W zu13flNz$-M_xUKK7JSN2xP@DamTqc00N`FLI6$|W&4W~E0Cy?c9#f`Lb1=i3l5R`* z)s#`-y8`S7BCnGQ{|sT+e`a!eJr#8TEOt1RUqw#Qx%tGY{eVb%%JvS*_3cPFB~)O* z>|b=|bVqXDx?*&9(96>z^rqd36-97-$E>*R$(Nng*{PEML@d0VYn1t*P3~)uP?2$G;Bp{hTecg+Mnsr*Ayt4PBuQ{)V{hY zJGjY7t#;yS9V0ZK)(Tg!B7e)o{rceW@aphzc6_u+?xa}}H#n!v>9j%N%dd?*TyYv? z;qy2P<18Xw2zE5R1c4r??O@i+MC4gH`pq-Lj_M7RULYSRmUTTmJn8LDetr4P%iC|C zzx{Fl_U+rZx6k&T{@@|TU8?G{68HMWRdU}tJp8h^>*MLUBBs;6P=9B-AJ6_(mR};* zN?!Q@*I7?FWo;z=tV?PCui$;a{wES(HhKzCK@HL&j+2fl=FXcgK?v%W?Yt$jjB;Jvx`hJP&tcV>nPp2s?>@jrf*S zSVGBC(593!kp+y|E`P5L4j~iR%aLArHt6;CmY%rFiM8QDq2IK7oqxEy8n*UnApTXP zqAqM~pgz8!*ar|4-xYk_26kHq)w0&LRpxGfc7JzCnsuW%^zX}~f7#L{x#V7Qxn3?w zcdi|>yz5LvJ7rXhK)k?SQ*iM;?|@GQ08yGA%Ixyy^ftEId4J|qhtMo_?6o*3eH9|t z;N5kV8usKaROm0PK)&7ay=K_-j7WMvWcNooST`tg=6#8%oJKL{0Xo{*sIa*K zJ@;B>B#2Gf#tna2q$_zXUVAz4!v>5m&LOjRvQ53?6D$#2;SX-jCyal`=R zvWDGhYj)W#*9yVkII9rx&~r6ecL=S;<0cNbO4(j7Yk!*Jj;~AL8Odsmm%LWSsNyY0 zqkGMzuYWSa)qM&mEB-0;;$lO|s|U-R*u3?Zyq6wEe}wK^nTU6>4M3e)0M4-tL?I=39#7>7E~h-SN@xS@~l(*!}fr_d8@41ZS*cPpM-ypM)|fsuX3rzQI~MrnJ=&(LztkQ4d(66g zboy7d21+Y?s%@GadWNaJ-u88`*xL*CcYDPc|Mkm^(R$tvqFHJJC(Wz#hgvUvENc~w zxo3B=mlBETR3h=|I7#9#n9#eZMP~*ko#$Gg(SIkhd`zFpYYXAxjMMv+^y&!VW$b=N z7^PZ$(dV3`Z$AEr|JX%9(!?=34G?E>66CMEEI;Xo*Iv~RSf$y2%_dQ#OunI0Uq-F~ z(kS85Z!9GduYQ+?BmIlGo#+%pS5g26lqU8`d;unD#-w@V* znSU?8IM<0$ID{RDN0)+Vq{#%rL4av8ky^_{$0*9q_zgWo;*;PLf?1G-LK&Szm+6Cx zPd_0Jdn4v9VL3-ULK&5zLZn{`$vTU?mYI}{9->(k#v{^hcf$Ch41Ym3n+z%VC5Up8 z=wIT2LK62(Hr|ZPn8J4)=6Fnq?LQhvAb(^$qcKQe#gL*gMH5QK^b>^(ny93({mGI*B=6?)*Xxd)|iyf(k(lU&lkh+5;K2T!y_nG=`Sr8V~p7RoJ8o{^w8_!Kg>eQ6Vv?V1r^KBui|;W z{KJ0hwZ($)%gcRyyxyPhwNU33Nq@_SPu*8tx~;soDzE61L#BG zlAIhIBe~yis@|Zp0X%@i95CA9?>4@bPyF3f+)jAf?>2Y)KAw96zCGz*G!t8YQSVsjZ$lwXPYMn!XB3FvGA`;edpC+ z_RRWgbE?qoujZ94maiJzs<_yMZQ4F#6m5p)KZ3yKo&FE=rUu$G zu+p0K^*HoORcvR1vin#Z4)WgMFDrN1@W8f}gWTZ8k{Ifk#{oyv5C^?boZL_-CTUc4Sx%ts$<{J&B~6WNPiVcTl4UpPKAJL zL|<=gcb9t2UK7*i{FMbEfROlq+QR=xyxlzX=^g&qq8DGJ9{y3!KcMc`_6slWG<&R$V=p5JQkYPDt}%1o9Tk5i?*w=Iuf0Am!UVe_=CTcl3$R(X)^c>VgF|DMgb4R zAl3;*?}u@!6iI|53VlPzGkkpp5@sZKcPO8}rOO0gIWm%zrqPd~q6iNY`W5liCP0DT zv4Sb-dl3|&YgC|2N&|et*2O2xUFG8+r7>6M@vkUkKqCSE1%Icp($8)M`l$#rL{bJ= zBvV$`qmTTSXW8k={>GD2J;eqhgBOZ$orR2X4|ObPZ!r-YJVBAoTLWb4=7?i%OqD4*lJm+G@rk^OegZw%^-RIf;b*1OE~C33 zjukPx5@Z3Wb@BKl} ztkU;_m`kn|{lM5p6EH5YoubrGAf;abF}tO>Kv1lBZl@t0850SJ&1jl2ML~G&p z7PDyaSqEt3jtpk>71vNSwj*GK7PSUp7r;nl{Q|K#bRx1c(xWCF*|Z|;pU~1NY|OZ< zglqzB7z4Y(0@%qmY-`rBQ3xtBxmshVkS~p@|BVS z1+P>V5@q2IYD09D0CP`(qsQS!5pP+)~|f^l)loIEmd#OUYI0A&>M zeRXcFOc=}TpYi~rd!>YDc@j``BeD>WXgV@`PJlwpG6HX!g0;xja^tZ{u?=oiC&q%I zYu5|pH6Uzymib7oP7`5Zrm@?31fT64m47|uUs+mxbU~}Z+kgQ|>>lT2bQT5>2UbqD zy6A2Z?4cIy3}ZVKI8NI#%d~Mt?;c$qU1+vbkZSH|{84x?40Kq~-IYn(TeoCjb(ILvA#wtA+$WYVsI*f4KdlI3~~R&$A?1}m(R z%!e4}V?c&gw%VXffIps@9Kte@e4p6eNQyWFRXr#KgSeR1i=cbws*2w%L+c+IpDPVz zCP?#)V12=Q$|wvcY=w!*l@fLz+kg3XCVE)rWH!klXbet-78SWe(I5uzc?|OKv!hMs zV=BhHu`MG}E(ORhMqYxsbEbUJYDVbBJfg*TWJ7vJNyd${JaeOBS<)FZ5yfWo4J(_E ztR&J!nN(t#aOY4HDPGNyZ(it7EUKx}R^9n0*Iyld^yMiXeWMdf#*95d;eP_mPwb2> zLd`FbY^<{Oq2$LXv{M)6n0Lbzp8GqQohRC=2}Qh%>6AN|7Q$MJje_KY5``@i&0zp` z1Be%&f5C%f|N3Qm*%;LP7k{!)nEm>q^c4CHijFcE*BFc1lG4W%X`M1m3!(QE!)+$( z+CM!LC==*jT4ePTxDaJpbzS`uvl#^H0t%ztx78 za5N5P#P1LeG(=W|7r~_?`<}xCnHd*_cD`j(Md%@mLB<>@G7Mo6#eW}}>{FiIi1%74 z<{(!SJZz`SQFL@uN?Zgh=loqVOCZLSD~(>d9_n`$!JcaWa4y+-s}tPRN-N?=8XP!HS^Z5g=RqYQ-C!;dzi%*B)!G zPv4W|DZPAZtT#rR>xkiov_?*#Nz#DSX<;h~7r6~b2uT4Vt0SY@Wo9dPM*_00c77+U zsQ3?;7cQME(MHadfpZ~W+-qDkZp{x~E%B25;VPj?u7AcN36yj>B*ivi;J0dBWpuS& zo83=tqPtmtXRTkZ zuDM>rg$~VSm9gbx5wf@FHh21jkL@eJuhZLC{jT4qot9uTruu zuFNt60`Oo9YXZUflJhJ?V{>A7{gqL$dClEtMkRAP*KHnZ5-`=)T(gd3F3u?pc*e4l zu=&b_*KIwAK>rO3Z$D|g+b9BbcSA}}S4VP%<9{F~0{{&$-|)%|g4^l?8fg2a4QbDP z{TI9Hy+kO!aaR|5$Dy41JV{P3UQ^4_nHE49mOZz8o-g|K5zQ{xm^VPqJ--^X4E}Pf zIuDV`_7EW#Id7wr?ZJ$u^kTX6+{H<|_R8P5f%4~eq+M$bi?`askzqt@1tho`x$eTc zN`JIDU#w>j1~r&f7gSajm?{y}8l_dXRpQvKBK^MOLUlJ5pStLHr=GXx8g6Z09G0#p zE&#YjicB?@CDjs93OQna>yV?+138;ZIHAlr?QD-r0B0j=iHU(A^k``h%yKwV-}08< zQ)3v|x}vJ=11ef_RQm^TT8m$Jb>~Y_w}10RZdL{Yaw$xBofJ8nQGdssmFpK)K7LE3 z+_w6u^k?9x5aiE-QFCQZlkZdSG`5A-&6ga zZDL_+@b&=Jsq1&=3KdWpRd)bHS5$ch_!{-@-AowN1PGe4|aT-)&7bA)+-x z)U^^Rt2b>67BeX(xB_;BK3ipNbY6{6OKaujtC_Zj#TdFi z3G#w=0|lB{cdwi^_EmXVD}NYPw4+S!-WCEVK1km$O1Ux%MH)~D#161M(}T|TP_WPk z@nQy8m}Ae}P0F6>{-cCQ(nsj9+-KWiM%Z`v+SU`~pq3OZOj+2m`w)VEJWoRj+WU|B z3T6d8p7XJwwwrnLaNka;s~0R+FIKJsmOA4qa3RY0aP5NS={sY6TYs`So})(EfrId= zl?$L)&H2-vyN?5aH5kdQ3W3TGV|#r6^4?j~@B-K^mM&qA8X4$Xv>Zl-G8BPnP(M~` z^iuAq09DCEt`d?7-YSf`^bbmf`8#b_(-SugME^>)C$ivhr&TMJQ!hPL;sBMJT@pxT zCEGY#mMZ-B&ODEknSWivbi{_zk9F`8-JDjrImb_h zpTb%o`q6Xd$9(eRd{BtIDjy48DdYm zS30kYGrNl)i+?NnnJmTEa)<6IbBP%%VP_neMFAY|oTq7Pcb28T4k$2xGaHmT@1b9` zBw{%eL(oVL9B#vOFO<;Vj@wg5qGI`)BCf|UkgO)rLapA9^PU{$YQ?9U?pFEoYJgLE zcl$kyhVK2AM_(c^7K$cGeOeBH4R2M3tLcr@C72KeO%j zqgA!{jw?rDyeJeUoFkn=!0w<_-YMZ=#}wGt)PL9>+<4ZNIbZptsQW!F$WJ`5N_4Rs zaFf^Q%9BY)5j9F9;703MLDm57A=W_K)iguUh;V`$EM6Y05p48~Je`B#khPkWz+&L_ z?27w(8*B(TLT7?781G@YT|qF;$rqcDp0PROy^Z3?$dQFGn7pUOzzSm_d|R=YDGT0E z%YU{oK=3{qu_@R(K)q7z{fD@FSjZ}9ilkJ zgj(^o2uKfIlEPz0TSg#*ahW8h0jSz0{&E$zR7og`P>|J;UNfW9lqQ-LBi0}<<@ zDXpitk%f1iu~kzmoWo-b;sopJd9>T;5x(qu)ehN_b@6$UgJh>fbS(oU4P8;;4uA>cy^OUMrbGK2J& ztt-lM8-#%;;;TpKNpQ^CG{oeA-PHRyd`E*6yxV>(jO4@yAtd3j;&`@F+PtT+Dmu`r4zFKrQSK-~HrB0$@lnH?pQ+b@cKVh>KM(&10kG zH(KTSolB8_V^X@x?ML}{tQy=2lPoEkE5rMH_ooQ%LK(9D4+bAdS|wu80)Ljl7}3d< zXa9kxy#EFm#};J+pPS+w+fhStJ()0ZS6}pLkBCH7#Ft3qlEb}qb(38qeYgp24wLBi z=9AKsW0FP$XW3wI;KDLB{P}j2)FdyGnMkVE z{+_F!0(u1a@@H-Meni)N<$v~4*yRXAE^C_RB`JmLW?Tu;XF>_Sl4Q0(T>~|yt302r z7?o&)2$#B1WCC#Y?XFgh9JsYKv$)1ee*nKY!KU*qB}F1y@q=;a&%Oey-q_q@y9JRQ ztK#AQRu3YUoA|R|cZXKx1%tCfD7TciAY~0srXW3@(^;s&lX*c@oPX2BaVtS>nrYWO z9^22;QW^%JVm?HmV~RJJhtCN1?CT1#W17K+Czpb!arq1-8*}7_iIw|T1>B@4Vew_Q zXM+VH_Y1RomBCTP9Sp#XkIbkJJf{Wgb-(~aYps@$uww%)Bm^DehQlWRkipDf zt{l_Z7;f-?Lzj+r+ zUcHe3xx`PAeQFW1Z|?zhRQC(5Nk1-}p7~}CX#U`;Y_5tCH%~(iaOt1EgF+o;7NMqM zQ=^T57AU-Gy|HM@l|Us9O+5wkA(z3E55z#S$Rsby}n)UqDv-J97dV{l;;RC z{s1pvWDaS2maZ8Da(@64H55b!KW5;(fRu0`d1_&Ar~6~zRM7ON?71Ss@Y?~nz^e~2E@ER9nu+BB7=Nu#n~H5d=m1~&X+|ejM|G1g zfKW%V6a@SfVQm&w^Zf~!$D}!>s_xxT{aeq%v8 z-|3FpKDm-K%o?7Sw7EZHSTIS3vBjE?FHe7sFDVw+aPoL0m- ztqzP?e}8c{B9@E&8caT%Q4IR?mMasKjTD&{r!=}EiG%R|@87_K8_oIh=@zDhX#k!~ z2e}al=mCp|FL49?c`zo33(5#BL6y9?eu*UD2z`2F=!M*g#qXF?ki2QKdYF!q&R5Rj z?dPz|b$W8>%uxkqjI^i2EA-ke2(kgepo zQ^lVOLf8y-)_wK&NF+-zI3VJjFhj?uGdI#Gyup_>s&i8YW?na!~IPb_r_>iz6@iVxm{bwHixMdibcB}FvyBZ>U_2#QA6y*KLPxUDt% zwtsl|rzt}%mNnPCe^5l$hTQlReyx{h5c}Eq&=scjoWl!XXA7Zd(Ql9k(UM#Ioy*y} zY?J@ZBLNh!wRHvc+WP%dfcPNQ4=lO6TVsESs0kf%aEacn)JBoX1{3LB6)KbMB+}s` z*6~uxgiKkA-MSjT`}S{Y-k z{C6Hdv73Z;VJ{#dc$c_w+#JqjJ8n4($W1}!C4Y?Q0>8>v2(d+4=!zJ|ls*70i+UDQ zV6|DVW|m^bHP9H$;FXwY#u&y}hT&NY9VH9!!kQYu;)^Id=7{0Ywq8nx<$KIZAAfn~ zFFq~FBog1%XnkHCmqDVx<8|?__M=1td52bHRm@83G7qtcj5P%$6pDw%zt|OcDOS=F zV&N4o%OJMi)a=L=76dH5+p+S#wh{(FiBcN`I;hHylMiCM!uMEJ$lk+0B{N8{7%QH( zF(cU8%TfyU>Y_j}lXHMENof4QDSv@Uss-2~?vKDQUkW+J7c*KUe~}dl>j2Jbp(%6% z*kWDN8C~b~IrN9M=QRyT+zn>!iTyry)732}(ySTJO&g3zXcOgx1hFp8E)>^E7fyg) zR2c5qC!jT&jXrknsIsg%;tR6CdOq8{|2Rfd?B+P;A&^_YsL&KOpwAJ;*441Wo_kXJU%Yb3CClOaF7)d6v=lFj!`o0@;=lLziwHc{ z__$ncOW?j6Opz4_yUlpXdv~ln{M3vt^u^UbmwG$X@?+L|oHBqTars?^2iy-?%)6pm zHS~GcwiNOs($-T2)sW>loPY8t^u&RRkiG{4VrKE>gd#n?JU-MDt#SPE>5LI41uY97SbVvd?G%qudrn=OA3dOr-JQ5XWl6Z}zzNeg$v7xQ z)j@yGv2NRI=Vs8pRX!@3hw3?W*~Yp^sh1l~I+7;B_ii-%VQ!G{Nq_E}onNys2iLFE zwp~<;*rDK8mG00E<{eOhN%waDg2ci@i_*#AfLQ-XiE zO>QQ5dDnKVP^~;$HGhtXxeEsKnCsz1<0$%22A)2t^T1msYr(ILb4=10Yc(cx;i3N7 zE1brPO74f_MRX?+zFJ&MrjHdSea5KPX|COwa-{FjIo9;(pPa|?^X7{FD5vRJ7v*>> z-m3!*1eL(BhqdK14nOlsrto^%AG$$&4fWXjY@?fR{(vn`#($l!ItGhzO5&sKz4&Dl z57ToT06x@MXGLEIM`YZakL!ou#XIq51oOGneD%IwfiJ$*lDGzXRnuGX*J=F~;u!pV z1OQ?9wm#cGcI@U+IQ2|q1>Rr(;ZB5qEy8~lcZ(b3zAd3E@UY|(k6FK}nns)c4MAR+ zOvtUGo@IA7WeRBZM-<&@Mt!`$FG>LLUE;-Yb8N`G57;I~B)unC3zM638BL%Wmv% z+1;zEU+g}|Ijb$qb~ttk<7F+jjy1^LN1uz{yVGYbyAkfWxnHe*T$4D6gm8eUv(PN5 zU65pv!FBG^nak(;fox&~1SCd;lrveai+~-0M&K-vHXsRhSQ@#JeN_AEz$>&65n(<8 zigpp=(0_zqBXkvnI!&ZN$_siARFvXMAW?S(9Mx+nR$@mbtr4_!tdz;Q4UV*7p|ujj zsy`s&(UH%8dD(ZNqdqM_Xs!SS9$?nc|4D*ve2_rOXigGk1oRkjUPa~*^_nY0yoxHc zK4VoWp(qm&h(drc#qncyPimDVZ?!0jY_fMLoPT!xe)SCrd4PYOh2=C)6rE25P4yFqiKYdC?1vCQRxE*N<`9@}Lg<<@ z#t|rEC;_SzN`P$)CBVWUmRPNWMtfh$0d;N&y(&%cV`Ur(1a*P$@W`-8`g^+E0t+2k zGJln(L9W%b)}}797XsE@5tRsU+!HCusb`o>PCb4mEOL*opNoo#UU+iqNx79I1rdAT zg(iqSHi3rV3z^|F5p+0$5QUYeUOW=uIRz*3RNNm{Lh{s8Q3^OdGf9dT;-wd)go3jj zJNU^(rb|c{g*+1dgdfsvjCc)X8^QMaK!356feXqbzR7F*I*Pys?KFXv5I7pRj<{F5tO*y$!0p%nHsFf4kaJXY?eo(y`P7XqJJtb z#Kf2dfh~EU6|BMBNptLu%%KZdS4}jD?VL%^bYyC;mP0w**}qz^0ZA+24TBJ&p%21j z22As++VcdNZ9jt?YP5t@(`$zf$-sHdF$>GgU6qIp;ZO$4%d#*%wPFjSzfrRavDo&( zaVddll=*`}U27rGO&B6-f58l?wSOBj1=A#8nz~lvjYUMXrhp^5YMGj#fhh2h?0a7@ zf>BzVIY}WhRYP`f#n8;!T*TQBW{Kbo5ImNFBd@D$B6{eYlEqS&J2XyRJvHpSb>{Mw z%ev=qk(rIeJ;1*f%Q=|T8_+SZ$EL)AHR2}5>BB%sk_!)r(qcUDp1g9SjX+>4h3-) zNC*%h0U86wU{Ewxv~B`K_kZqucI~EV8rE?K0q3;2)QKJEX8XHdh09Ejqg_anUF$WQ z!B)jyZhE?^ml^V`Ap06yH=4tvhu0%Vpgd-0FaltI!<8tK`D8Oap6YJC_U#p*+l`G^ zF~OnH^z7Tjk6sduD15~xzmrQidGgRYTDS4tSEelE^<*_o$;mv}2Y=@ruV_v7;u8dW zu`Ij$FgD_mnATSy$a>}^9Sg7)X z0L7y#;d-vBty>;lc+ zPhlTEBzfA^WV$44gZwfImk2OFTmHi!?f?L9!kUWQ43IIUtS|=ARry-OfTX zg?Tujr&>L9j4wOfehP*E!BJPEuR?);T(9#({Sy63dib;R!GGV2Oh86|Iw+9+v^irP z!V69fJB;VHN|zqwXa}8HZ%&qw2OIN-|cb87Y=A z$AYUb-N!<(M$@%0w$MmZLcnwKOmgLoKL>YE{#Td83@sVF8{&X>m z!s3T`rHs(_66}D)1j!_*SUcuR!R=F*^#BWJH4C@Q!hdbe!bLjkVBumgSah=x`MX$1 z1-{3^Ws8LpXs=@AJY6=rn4{?_Gx@<~=$t-rRD1F}IfhBr>h9s|bG?zZw=a{e5((~DOq z(@U*Q(|_%EE>V6}02WmByCSdncRhjW@sCAh>1?f`PX9YGSiBxGt@TB+@ME<|E<5Qi z_eE)$|GFqG3wbLI}jBT=a8>r;Ca?vWM*?)gBVhW_+hD!M#1EinhXEKX8MRi$IEic8IZs9wZ z34d5~GmNa&O^spoqERsNP)KEQ*(Q55l8Q86lU`&VeSAZU9Fis>(|zevc-+L-?_GQJ z^!^P4q^Ai08m2X|QYcD%^QEQ<%x3nsh4(-U+7Vu}L!R4+v+b`_>A?_pHBgudp1s@0tW{!jQS`qJJ2Rvt{A5CUsh4J+m6GRa^rmio`|wj#Dkf z>r%@GaheFv#*>3T=!=T|l=~g8jFT5bwjQwKATB_Li)C74ziHZkPQ;ijLh1`iMVsuC zi@@9JjbiV&+!E7{Wgl~uDT8ptJ+kdYJ z@%<_O26!9n;&3{-Xgo)a(-Qx|f}JWiX4tS1_Kbf?Q#f^uMlL-;8(iR=C_co zcV*Cp3T~OEDfYtw(_{A%SAjzSTgo~74X$1Ov$jwqnIF@8(Qq}4LR#&ji8&pMWQ_Il z63z;Lt1{aRtvWMFqoETJF(TviY5E(rXc*>4V@;naK2oTF_?%G3-`ruuwE$nZoHG-J zXPLvfayHBs?WbLG=#CIY`hTvSz@ETWV&h<}NHW^nKl!k1pUZ_d`tLR$mcKgqY4||+ z@POUuiQgPRwf|A>PsHMuBi+vC7@uD_)y?E&3(lvc>$BH4mmpp^bIjZHvsS%Ms~Z&}lrqyK5+39Bs9^qnekyw%Fj5j+>wl zzkAhh5`W16-5WuZ;Mh#YM`xzEx?BDV1T(_WGJHiKi;^UIPsMdCnyv*6?vD5SQZ14# z%>uVJ-ZZe-Z)AeD{}Lk;-;l(eDfVe`O+2=xWDBn~7`!>dr+-EiW8k*n>R}DTOf#28 z=XXD9k<#1ZB$u4-Y%*(VFjZO#3Hai56`Hf}Vh1xdcWWp7HOrngTWb-+@h)@@mP>WQDOkI3y5KU5@6Cyk+#H3fDa#fCDlXCj`AjF{0jB4@ zn=GeQ-@oHNu1L7DiM3Z%X}e6AL$Eztnyo>Qr;o#`n%S#|l|a^}8L*alr#+j}CGTYs zEq|~dlEpthy2ABZ5drP5)7`jPY`62Q=w|gvinXGf?ZamMK%QiWte$@t9BUYLweV0^ zrFvPj%9$%C<1Jp1TA)Xibb6@pjIe}}9-yoGr {C>&G|;6vm3vpC-~kUlG+8yXqs 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
<4aUor(?{>r^7=P^sP&6{a453+uc(dHRmO&O*sH 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 Xrt@}Pw5ogkr~2q0=W!#5h`|N`X>YZL diff --git a/examples/SmartSwitch/data/index.htm b/examples/SmartSwitch/data/index.htm index 65a7eaf6f..9f7da5b6e 100644 --- a/examples/SmartSwitch/data/index.htm +++ b/examples/SmartSwitch/data/index.htm @@ -1,6 +1,6 @@ + - Smart Switch @@ -54,6 +54,7 @@ appearance: none; } + .switch { position: relative; display: inline-block; @@ -116,6 +117,12 @@ .clk { font-size: 54px; color: #444; + cursor: pointer + } + + .clk2 { + font-size: 32px; + color: #444 } .clear:after, @@ -136,6 +143,7 @@ left: 0; margin: auto; max-width: 500px; + text-align: center; border: 0px solid #ccc } @@ -185,7 +193,7 @@ .container { display: inline-block; position: relative; - padding-left: 28px; + padding-left: 19px; padding-top: 4px; margin-top: 8px; margin-bottom: 8px; @@ -194,6 +202,9 @@ -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; + + width: 12.5%; + user-select: none } @@ -239,6 +250,7 @@ border-radius: 50%; background: white } + @@ -249,7 +261,7 @@

"); - return page; -} - -void AsyncWiFiManager::handleInfo(AsyncWebServerRequest *request) { - DEBUG_WM(F("Info")); - - String page = FPSTR(WFM_HTTP_HEAD); - page.replace("{v}", "Info"); - page += FPSTR(HTTP_SCRIPT); - page += FPSTR(HTTP_STYLE); - page += _customHeadElement; - if (connect==true) - page += F(""); - page += FPSTR(HTTP_HEAD_END); - page += F("
"); - if (connect==true) - { - page += F("
Trying to connect
"); - page += wifiStatus; - page += F("
"); - } - - page +=pager; - page += FPSTR(HTTP_END); - - request->send(200, "text/html", page); - - DEBUG_WM(F("Sent info page")); -} - -/** Handle the reset page */ -void AsyncWiFiManager::handleReset(AsyncWebServerRequest *request) { - DEBUG_WM(F("Reset")); - - String page = FPSTR(WFM_HTTP_HEAD); - page.replace("{v}", "Info"); - page += FPSTR(HTTP_SCRIPT); - page += FPSTR(HTTP_STYLE); - page += _customHeadElement; - page += FPSTR(HTTP_HEAD_END); - page += F("Module will reset in a few seconds."); - page += FPSTR(HTTP_END); - request->send(200, "text/html", page); - - DEBUG_WM(F("Sent reset page")); - delay(5000); - #if defined(ESP8266) - ESP.reset(); - #else - ESP.restart(); - #endif - delay(2000); -} - - - -//removed as mentioned here https://github.com/tzapu/AsyncWiFiManager/issues/114 -/*void AsyncWiFiManager::handle204(AsyncWebServerRequest *request) { -DEBUG_WM(F("204 No Response")); -request->sendHeader("Cache-Control", "no-cache, no-store, must-revalidate"); -request->sendHeader("Pragma", "no-cache"); -request->sendHeader("Expires", "-1"); -request->send ( 204, "text/plain", ""); - -}*/ - -void AsyncWiFiManager::handleNotFound(AsyncWebServerRequest *request) { - DEBUG_WM(F("Handle not found")); - if (captivePortal(request)) { // If captive portal redirect instead of displaying the error page. - return; - } - String message = "File Not Found\n\n"; - message += "URI: "; - message += request->url(); - message += "\nMethod: "; - message += ( request->method() == HTTP_GET ) ? "GET" : "POST"; - message += "\nArguments: "; - message += request->args(); - message += "\n"; - - for ( uint8_t i = 0; i < request->args(); i++ ) { - message += " " + request->argName ( i ) + ": " + request->arg ( i ) + "\n"; - } - AsyncWebServerResponse *response = request->beginResponse(404,"text/plain",message); - response->addHeader("Cache-Control", "no-cache, no-store, must-revalidate"); - response->addHeader("Pragma", "no-cache"); - response->addHeader("Expires", "-1"); - request->send (response ); -} - - -/** Redirect to captive portal if we got a request for another domain. Return true in that case so the page handler do not try to handle the request again. */ -boolean AsyncWiFiManager::captivePortal(AsyncWebServerRequest *request) { - if (!isIp(request->host()) ) { - DEBUG_WM(F("Request redirected to captive portal")); - AsyncWebServerResponse *response = request->beginResponse(302,"text/plain",""); - response->addHeader("Location", String("http://") + toStringIp(request->client()->localIP())); - request->send ( response); - return true; - } - return false; -} - -//start up config portal callback -void AsyncWiFiManager::setAPCallback( void (*func)(AsyncWiFiManager* myAsyncWiFiManager) ) { - _apcallback = func; -} - -//start up save config callback -void AsyncWiFiManager::setSaveConfigCallback( void (*func)(void) ) { - _savecallback = func; -} - -//sets a custom element to add to head, like a new style tag -void AsyncWiFiManager::setCustomHeadElement(const char* element) { - _customHeadElement = element; -} - -//sets a custom element to add to options page -void AsyncWiFiManager::setCustomOptionsElement(const char* element) { - _customOptionsElement = element; -} - -//if this is true, remove duplicated Access Points - defaut true -void AsyncWiFiManager::setRemoveDuplicateAPs(boolean removeDuplicates) { - _removeDuplicateAPs = removeDuplicates; -} - - - -template -void AsyncWiFiManager::DEBUG_WM(Generic text) { - if (_debug) { - Serial.print("*WM: "); - Serial.println(text); - } -} - -int AsyncWiFiManager::getRSSIasQuality(int RSSI) { - int quality = 0; - - if (RSSI <= -100) { - quality = 0; - } else if (RSSI >= -50) { - quality = 100; - } else { - quality = 2 * (RSSI + 100); - } - return quality; -} - -/** Is this an IP? */ -boolean AsyncWiFiManager::isIp(String str) { - for (int i = 0; i < str.length(); i++) { - int c = str.charAt(i); - if (c != '.' && (c < '0' || c > '9')) { - return false; - } - } - return true; -} - -/** IP to String? */ -String AsyncWiFiManager::toStringIp(IPAddress ip) { - String res = ""; - for (int i = 0; i < 3; i++) { - res += String((ip >> (8 * i)) & 0xFF) + "."; - } - res += String(((ip >> 8 * 3)) & 0xFF); - return res; -} diff --git a/examples/SmartSwitch/ESPAsyncWiFiManager.h b/examples/SmartSwitch/ESPAsyncWiFiManager.h deleted file mode 100644 index deecf4f7f..000000000 --- a/examples/SmartSwitch/ESPAsyncWiFiManager.h +++ /dev/null @@ -1,283 +0,0 @@ -/************************************************************** - WiFiManager is a library for the ESP8266/Arduino platform - (https://github.com/esp8266/Arduino) to enable easy - configuration and reconfiguration of WiFi credentials using a Captive Portal - inspired by: - http://www.esp8266.com/viewtopic.php?f=29&t=2520 - https://github.com/chriscook8/esp-arduino-apboot - https://github.com/esp8266/Arduino/tree/esp8266/hardware/esp8266com/esp8266/libraries/DNSServer/examples/CaptivePortalAdvanced - Built by AlexT https://github.com/tzapu - Ported to Async Web Server by https://github.com/alanswx - Licensed under MIT license - **************************************************************/ - -#ifndef ESPAsyncWiFiManager_h -#define ESPAsyncWiFiManager_h - -#if defined(ESP8266) -#include //https://github.com/esp8266/Arduino -#else -#include -#include "esp_wps.h" -#define ESP_WPS_MODE WPS_TYPE_PBC -#endif -#include - -//#define USE_EADNS //Uncomment to use ESPAsyncDNSServer -#ifdef USE_EADNS -#include //https://github.com/devyte/ESPAsyncDNSServer - //https://github.com/me-no-dev/ESPAsyncUDP -#else -#include -#endif -#include - -// fix crash on ESP32 (see https://github.com/alanswx/ESPAsyncWiFiManager/issues/44) -#if defined(ESP8266) -typedef int wifi_ssid_count_t; -#else -typedef int16_t wifi_ssid_count_t; -#endif - -#if defined(ESP8266) -extern "C" { - #include "user_interface.h" -} -#else -#if __has_include() -#include -#else -#include -#endif -#endif - -const char WFM_HTTP_HEAD[] PROGMEM = "{v}"; -const char HTTP_STYLE[] PROGMEM = ""; -const char HTTP_SCRIPT[] PROGMEM = ""; -const char HTTP_HEAD_END[] PROGMEM = "
"; -const char HTTP_PORTAL_OPTIONS[] PROGMEM = "



"; -const char HTTP_ITEM[] PROGMEM = "
{v} {r}%
"; -const char HTTP_FORM_START[] PROGMEM = "


"; -const char HTTP_FORM_PARAM[] PROGMEM = "
"; -const char HTTP_FORM_END[] PROGMEM = "
"; -const char HTTP_SCAN_LINK[] PROGMEM = "
"; -const char HTTP_SAVED[] PROGMEM = "
Credentials Saved
Trying to connect ESP to network.
If it fails reconnect to AP to try again
"; -const char HTTP_END[] PROGMEM = "
"; - -#define WIFI_MANAGER_MAX_PARAMS 10 - -class AsyncWiFiManagerParameter { -public: - AsyncWiFiManagerParameter(const char *custom); - AsyncWiFiManagerParameter(const char *id, const char *placeholder, const char *defaultValue, int length); - AsyncWiFiManagerParameter(const char *id, const char *placeholder, const char *defaultValue, int length, const char *custom); - - const char *getID(); - const char *getValue(); - const char *getPlaceholder(); - int getValueLength(); - const char *getCustomHTML(); -private: - const char *_id; - const char *_placeholder; - char *_value; - int _length; - const char *_customHTML; - - void init(const char *id, const char *placeholder, const char *defaultValue, int length, const char *custom); - - friend class AsyncWiFiManager; -}; - - -class WiFiResult -{ -public: - bool duplicate; - String SSID; - uint8_t encryptionType; - int32_t RSSI; - uint8_t* BSSID; - int32_t channel; - bool isHidden; - - WiFiResult() - { - } - - -}; - -class AsyncWiFiManager -{ -public: - #ifdef USE_EADNS - AsyncWiFiManager(AsyncWebServer * server, AsyncDNSServer *dns); - #else - AsyncWiFiManager(AsyncWebServer * server, DNSServer *dns); - #endif - - void scan(); - String scanModal(); - void loop(); - void safeLoop(); - void criticalLoop(); - String infoAsString(); - - boolean autoConnect(unsigned long maxConnectRetries = 1, unsigned long retryDelayMs = 1000); - boolean autoConnect(char const *apName, char const *apPassword = NULL, unsigned long maxConnectRetries = 1, unsigned long retryDelayMs = 1000); - - //if you want to always start the config portal, without trying to connect first - boolean startConfigPortal(char const *apName, char const *apPassword = NULL); - void startConfigPortalModeless(char const *apName, char const *apPassword); - - // get the AP name of the config portal, so it can be used in the callback - String getConfigPortalSSID(); - - void resetSettings(); - - //sets timeout before webserver loop ends and exits even if there has been no setup. - //usefully for devices that failed to connect at some point and got stuck in a webserver loop - //in seconds setConfigPortalTimeout is a new name for setTimeout - void setConfigPortalTimeout(unsigned long seconds); - void setTimeout(unsigned long seconds); - - //sets timeout for which to attempt connecting, usefull if you get a lot of failed connects - void setConnectTimeout(unsigned long seconds); - - //wether or not the wifi manager tries to connect to configured access point even when - //configuration portal (ESP as access point) is running [default true/on] - void setTryConnectDuringConfigPortal(boolean v); - - - void setDebugOutput(boolean debug); - //defaults to not showing anything under 8% signal quality if called - void setMinimumSignalQuality(int quality = 8); - //sets a custom ip /gateway /subnet configuration - void setAPStaticIPConfig(IPAddress ip, IPAddress gw, IPAddress sn); - //sets config for a static IP - void setSTAStaticIPConfig(IPAddress ip, IPAddress gw, IPAddress sn, IPAddress dns1=(uint32_t)0x00000000, IPAddress dns2=(uint32_t)0x00000000); - //called when AP mode and config portal is started - void setAPCallback( void (*func)(AsyncWiFiManager*) ); - //called when settings have been changed and connection was successful - void setSaveConfigCallback( void (*func)(void) ); - //adds a custom parameter - void addParameter(AsyncWiFiManagerParameter *p); - //if this is set, it will exit after config, even if connection is unsucessful. - void setBreakAfterConfig(boolean shouldBreak); - //if this is set, try WPS setup when starting (this will delay config portal for up to 2 mins) - //TODO - //if this is set, customise style - void setCustomHeadElement(const char* element); - //if this is true, remove duplicated Access Points - defaut true - void setRemoveDuplicateAPs(boolean removeDuplicates); - //sets a custom element to add to options page - void setCustomOptionsElement(const char* element); - -private: - AsyncWebServer *server; - #ifdef USE_EADNS - AsyncDNSServer *dnsServer; - #else - DNSServer *dnsServer; - #endif - - - boolean _modeless; - int scannow; - int shouldscan; - boolean needInfo = true; - - //const int WM_DONE = 0; - //const int WM_WAIT = 10; - - //const String HTTP_HEAD = "{v}"; - - void setupConfigPortal(); -#ifdef NO_EXTRA_4K_HEAP - void startWPS(); -#endif - String pager; - wl_status_t wifiStatus; - const char* _apName = "no-net"; - const char* _apPassword = NULL; - String _ssid = ""; - String _pass = ""; - unsigned long _configPortalTimeout = 0; - unsigned long _connectTimeout = 0; - unsigned long _configPortalStart = 0; - - IPAddress _ap_static_ip; - IPAddress _ap_static_gw; - IPAddress _ap_static_sn; - IPAddress _sta_static_ip; - IPAddress _sta_static_gw; - IPAddress _sta_static_sn; - IPAddress _sta_static_dns1= (uint32_t)0x00000000; - IPAddress _sta_static_dns2= (uint32_t)0x00000000; - - int _paramsCount = 0; - int _minimumQuality = -1; - boolean _removeDuplicateAPs = true; - boolean _shouldBreakAfterConfig = false; -#ifdef NO_EXTRA_4K_HEAP - boolean _tryWPS = false; -#endif - const char* _customHeadElement = ""; - const char* _customOptionsElement = ""; - - //String getEEPROMString(int start, int len); - //void setEEPROMString(int start, int len, String string); - - int status = WL_IDLE_STATUS; - int connectWifi(String ssid, String pass); - uint8_t waitForConnectResult(); - void setInfo(); - - String networkListAsString(); - - void handleRoot(AsyncWebServerRequest *); - void handleWifi(AsyncWebServerRequest*,boolean scan); - void handleWifiSave(AsyncWebServerRequest*); - void handleInfo(AsyncWebServerRequest*); - void handleReset(AsyncWebServerRequest*); - void handleNotFound(AsyncWebServerRequest*); - void handle204(AsyncWebServerRequest*); - boolean captivePortal(AsyncWebServerRequest*); - - // DNS server - const byte DNS_PORT = 53; - - //helpers - int getRSSIasQuality(int RSSI); - boolean isIp(String str); - String toStringIp(IPAddress ip); - - boolean connect; - boolean _debug = true; - - WiFiResult *wifiSSIDs; - wifi_ssid_count_t wifiSSIDCount; - boolean wifiSSIDscan; - - boolean _tryConnectDuringConfigPortal = true; - - void (*_apcallback)(AsyncWiFiManager*) = NULL; - void (*_savecallback)(void) = NULL; - - AsyncWiFiManagerParameter* _params[WIFI_MANAGER_MAX_PARAMS]; - - template - void DEBUG_WM(Generic text); - - template - auto optionalIPFromString(T *obj, const char *s) -> decltype( obj->fromString(s) ) { - return obj->fromString(s); - } - auto optionalIPFromString(...) -> bool { - DEBUG_WM("NO fromString METHOD ON IPAddress, you need ESP8266 core 2.1.0 or newer for Custom IP configuration to work."); - return false; - } -}; - -#endif diff --git a/examples/SmartSwitch/PinOut_Notes.txt b/examples/SmartSwitch/PinOut_Notes.txt deleted file mode 100644 index a55977a82..000000000 --- a/examples/SmartSwitch/PinOut_Notes.txt +++ /dev/null @@ -1,56 +0,0 @@ -This application: -D2 = 4; // DHT DATA I/O -D3 = 0; // BUTTON - most modules have it populated on PCB -D4 = 2; // LED (RELAY) - most modules have it populated, on ESP32 is with reversed logic levels - - - -Pinout ESP12 (8266) -D GPIO In Out Notes - -D0 16 no interrupt no PWM or I2C support HIGH at boot used to wake up from deep sleep -D1 5 OK OK often used as SCL (I2C) -D2 4 OK OK often used as SDA (I2C) -D3 0 PU OK pulled up connected to FLASH button, boot fails if pulled LOW -D4 2 PU OK pulled up HIGH at boot connected to on-board LED, boot fails if pulled LOW -D5 14 OK OK SPI (SCLK) -D6 12 OK OK SPI (MISO) -D7 13 OK OK SPI (MOSI) -D8 15 pulled to GND OK SPI (CS) Boot fails if pulled HIGH -RX 3 OK RX pin HIGH at boot -TX 1 TX pin OK HIGH at boot debug output at boot, boot fails if pulled LOW -A0 ADC0 Analog Input - - -Pinout ESP32 -IO In Out Notes - -0 PU OK pulled-up input, outputs PWM signal at boot -1 TX OK debug output at boot -2 OK OK connected to on-board LED -3 OK RX HIGH at boot -4 OK OK -5 OK OK outputs PWM signal at boot - -6-11 x x connected to the integrated SPI flash - -12 OK OK boot fail if pulled high -13 OK OK -14 OK OK outputs PWM signal at boot -15 OK OK outputs PWM signal at boot -16 OK OK -17 OK OK -18 OK OK -19 OK OK -21 OK OK -22 OK OK -23 OK OK -25 OK OK -26 OK OK -27 OK OK -32 OK OK -33 OK OK -34 OK input only -35 OK input only -36 OK input only -39 OK input only \ No newline at end of file diff --git a/examples/SmartSwitch/README.md b/examples/SmartSwitch/README.md deleted file mode 100644 index ffafef743..000000000 --- a/examples/SmartSwitch/README.md +++ /dev/null @@ -1,19 +0,0 @@ - - -## SmartSwitch -- Remote Temperature Control application with schedule - (example: car block heater or car battery charger for winter) -- Based on [ESP_AsyncFSBrowser](https://github.com/lorol/ESPAsyncWebServer/tree/master/examples/ESP_AsyncFSBrowser) example that uses embedded ACE editor -- Wide browser compatibility, no extra server-side needed -- HTTP server and WebSocket on same port -- Standalone, no JS dependencies for the browser from Internet -- [Ace Editor](https://github.com/ajaxorg/ace) embedded to source but also - editable, upgradeable see [extras folder](https://github.com/lorol/ESPAsyncWebServer/tree/master/extras) -- Added [ESPAsyncWiFiManager](https://github.com/alanswx/ESPAsyncWiFiManager) and fallback AP mode after timeout -- Real Time (NTP) w/ Time Zones. Sync from browser time if in AP mode -- Memorized settings to EEPROM -- Multiple clients can be connected at same time, they see each other' requests -- Authentication variants including [Cookie-based](https://github.com/me-no-dev/ESPAsyncWebServer/pull/684) idea -- Used [this Xtea implementation](https://github.com/franksmicro/Arduino/tree/master/libraries/Xtea) for getting a fancier Cookie token -- Default credentials **smart : switch** or only **switch** as password -- OTA included -- Use the latest ESP8266 ESP32 cores from GitHub \ No newline at end of file diff --git a/examples/SmartSwitch/SmartSwitch.ino b/examples/SmartSwitch/SmartSwitch.ino deleted file mode 100644 index 658942f34..000000000 --- a/examples/SmartSwitch/SmartSwitch.ino +++ /dev/null @@ -1,750 +0,0 @@ -/* -SmartSwitch application -Based on ESP_AsyncFSBrowser -Temperature Control for heater with schedule -Main purpose - for winter outside car block heater or battery charger -Wide browser compatibility, no other server-side needed. -HTTP server and WebSocket, single port -Standalone, no JS dependencies for the browser from Internet (I hope) -Based on ESP_AsyncFSBrowser -Real Time (NTP) w/ Time Zones -Memorized settings to EEPROM -Multiple clients can be connected at same time, they see each other requests -Use latest ESP core lib (from Github) -*/ - -// Defaulut is SPIFFS, FatFS: only on ESP32 -// Comment 2 lines below or uncomment only one of them - -#define USE_LittleFS -//#define USE_FatFS // select partition scheme w/ ffat! - - -#define USE_WFM // to use ESPAsyncWiFiManager -//#define DEL_WFM // delete Wifi credentials stored - //(use once then comment and flash again), also HTTP /erase-wifi can do the same live - -// AUTH COOKIE uses only the password and unsigned long MY_SECRET_NUMBER - -#define http_username "smart" -#define http_password "switch" - -#define MY_SECRET_NUMBER 0xA217B02F - -//See https://github.com/me-no-dev/ESPAsyncWebServer/pull/684 -//SSWI or other 4 chars -#define USE_AUTH_COOKIE -#define MY_COOKIE_DEL "SSWI=;Max-Age=-1;Path=/;" -#define MY_COOKIE_PREF "SSWI=" -#define MY_COOKIE_SUFF ";Max-Age=31536000;Path=/;" - -#ifndef USE_AUTH_COOKIE - #define USE_AUTH_STAT //Base Auth for stat, /commands and SPIFFSEditor - //#define USE_AUTH_WS //Base Auth also for WS, not very supported -#endif - -#include -#ifdef ESP32 - #include - #ifdef USE_LittleFS - #define HSTNM "ssw32-littlefs" - #define MYFS LITTLEFS - #include "LITTLEFS.h" - #elif defined(USE_FatFS) - #define HSTNM "ssw32-ffat" - #define MYFS FFat - #include "FFat.h" - #else - #define MYFS SPIFFS - #include - #define HSTNM "ssw32-spiffs" - #endif - #include - #include - #include -#elif defined(ESP8266) - #ifdef USE_LittleFS - #include - #define HSTNM "ssw8266-littlefs" - #define MYFS LittleFS - #include - #elif defined(USE_FatFS) - #error "FatFS only on ESP32 for now!" - #else - #define HSTNM "ssw8266-spiffs" - #define MYFS SPIFFS - #endif - #include - #include - #include -#endif - -#include -#ifdef USE_WFM - #include "ESPAsyncWiFiManager.h" -#endif -#include -#include -#include -#include - -#ifdef USE_AUTH_COOKIE - #include - #include "Xtea.h" -#endif - - -#define RTC_UTC_TEST 1577836800 // Some Date -#define MYTZ PSTR("EST5EDT,M3.2.0,M11.1.0") - -#define EESC 100 // fixed eeprom address for sched choice -#define EECH 104 // fixed eeprom address to keep selected active channel, only for reference here -#define EEBEGIN EECH + 1 -#define EEMARK 0x5A -#define MEMMAX 2 // 0,1,2... last max index (only 3 channels) -#define EEALL 512 - -#define HYST 0.5 // C +/- hysteresis - -// DHT -#define DHTTYPE DHT22 // DHT 11 // DHT 22, AM2302, AM2321 // DHT 21, AM2301 -#define DHTPIN 4 //D2 - -#define DHT_T_CORR -0.3 //Temperature offset compensation of the sensor (can be -) -#define DHT_H_CORR -2.2 //Humidity offset compensation of the sensor - -// SKETCH BEGIN MAIN DECLARATIONS - -DHT dht(DHTPIN, DHTTYPE); - -Ticker tim; -AsyncWebServer server(80); //single port - easy for forwarding -AsyncWebSocket ws("/ws"); - -#ifdef USE_WFM - #ifdef USE_EADNS - AsyncDNSServer dns; - #else - DNSServer dns; - #endif - -//Fallback timeout in seconds allowed to config or it creates an own AP, then serves 192.168.4.1 - #define FBTO 120 - const char* fbssid = "FBSSW"; - const char* fbpassword = "FBpassword4"; - -#else - const char* ssid = "MYROUTERSSD"; - const char* password = "MYROUTERPASSWD"; -#endif - -const char* hostName = HSTNM; - -// RTC -static timeval tv; -static time_t now; - -// HW I/O -const int btnPin = 0; //D3 -const int ledPin = 2; //D4 - -#ifdef ESP32 - #define LED_ON 0x1 - #define LED_OFF 0x0 -#elif defined(ESP8266) - #define LED_ON 0x0 - #define LED_OFF 0x1 -#endif - -int btnState = HIGH; - -// Globals -uint8_t count = 0; -uint8_t sched = 0; // automatic schedule -byte memch = 0; // select memory "channel" to work with -float t = 0; -float h = 0; -bool udht = false; -bool heat_enabled_prev = false; -bool ledState = LED_OFF; -bool ledOut = LED_OFF; - -struct EE_bl { - byte memid; //here goes the EEMARK stamp - uint8_t hstart; - uint8_t mstart; - uint8_t hstop; - uint8_t mstop; - float tempe; -}; - -EE_bl ee = {0,0,0,0,0,0.1}; //populate as initial - -// SUBS -void writeEE(){ - ee.memid = EEMARK; - //EEPROM.put(EESC, sched); // only separately when needed with commit() - //EEPROM.put(EECH, memch); // not need to store and retrieve memch - EEPROM.put(EEBEGIN + memch*sizeof(ee), ee); - EEPROM.commit(); //needed for ESP8266? -} - -void readEE(){ - byte ChkEE; - if (memch > MEMMAX) memch = 0; - EEPROM.get(EEBEGIN + memch*sizeof(ee), ChkEE); - if (ChkEE == EEMARK){ //otherwise stays with defaults - EEPROM.get(EEBEGIN + memch*sizeof(ee), ee); - EEPROM.get(EESC, sched); - if (sched > MEMMAX + 1) sched = 0; - } -} - -void doOut(){ - if (ledOut != ledState){ // only if changed - digitalWrite(ledPin, ledState); //consolidated here - ledOut = ledState; //update - if (ledState == LED_OFF){ - ws.textAll("led,ledoff"); - Serial.println(F("LED-OFF")); - } else { - ws.textAll("led,ledon"); - Serial.println(F("LED-ON")); - } - } -} - -void showTime() -{ - byte tmpch = 0; - bool heat_enabled = false; - - gettimeofday(&tv, nullptr); - now = time(nullptr); - const tm* tm = localtime(&now); - ws.printfAll("Now,Clock,%02d:%02d,%d", tm->tm_hour, tm->tm_min, tm->tm_wday); - if ((2==tm->tm_hour )&&(2==tm->tm_min)){ - configTzTime(MYTZ, "pool.ntp.org"); - Serial.print(F("Sync Clock at 02:02\n")); - } - Serial.printf("RTC: %02d:%02d\n", tm->tm_hour, tm->tm_min); - - if (sched == 0){ // automatic - if ((tm->tm_wday > 0)&&(tm->tm_wday < 6)) tmpch = 0; //Mon - Fri - else if (tm->tm_wday == 6) tmpch = 1; //Sat - else if (tm->tm_wday == 0) tmpch = 2; //Sun - } else { // manual - tmpch = sched - 1; //and stays - } - - if (tmpch != memch){ // update if different - memch = tmpch; - readEE(); - ws.printfAll("Now,Setting,%02d:%02d,%02d:%02d,%+2.1f", ee.hstart, ee.mstart, ee.hstop, ee.mstop, ee.tempe); - } - - // process smart switch by time and temperature - uint16_t xmi = (uint16_t)(60*tm->tm_hour) + tm->tm_min; // max 24h = 1440min, current time - uint16_t bmi = (uint16_t)(60*ee.hstart) + ee.mstart; // begin in minutes - uint16_t emi = (uint16_t)(60*ee.hstop) + ee.mstop; // end in minutes - - if (bmi == emi) heat_enabled = false; - else { //enable smart if different - - if (((bmi < emi)&&(bmi <= xmi)&&(xmi < emi))|| - ((emi < bmi)&&((bmi <= xmi)||(xmi < emi)))){ - heat_enabled = true; - } else heat_enabled = false; - } - - if (heat_enabled_prev){ // smart control (delayed one cycle) - if (((t + HYST) < ee.tempe)&&(ledState == LED_OFF)){ // OFF->ON once - ledState = LED_ON; - ws.textAll("led,ledon"); - } - if ((((t - HYST) > ee.tempe)&&(ledState == LED_ON))||(!heat_enabled)){ // ->OFF - ledState = LED_OFF; - ws.textAll("led,ledoff"); - } - - Serial.printf(ledState == LED_ON ? "LED ON" : "LED OFF"); - Serial.print(F(", Smart enabled\n")); - } - heat_enabled_prev = heat_enabled; //update -} - -void updateDHT(){ - float h1 = dht.readHumidity(); - float t1 = dht.readTemperature(); //Celsius or dht.readTemperature(true) for Fahrenheit - if (isnan(h1) || isnan(t1)){ - Serial.println(F("Failed to read from DHT sensor!")); - } else { - h = h1 + DHT_H_CORR; - t = t1 + DHT_T_CORR; - } -} - -void analogSample() -{ - ws.printfAll("wpMeter,Arduino,%+2.1f,%2.1f,%d", t, h, heat_enabled_prev); - Serial.printf("T/H.: %+2.1f°C/%2.1f%%,%d\n", t, h, heat_enabled_prev); -} - -void checkPhysicalButton() -{ - if (digitalRead(btnPin) == LOW){ - if (btnState != LOW){ // btnState is used to avoid sequential toggles - ledState = !ledState; - } - btnState = LOW; - } else { - btnState = HIGH; - } -} - -void mytimer(){ - ++count; //200ms increments - checkPhysicalButton(); - if ((count % 25) == 1){ // update temp every 5 seconds - analogSample(); - udht = true; - } - if ((count % 50) == 0){ // update temp every 10 seconds - ws.cleanupClients(); - } - if (count >= 150){ // cycle every 30 sec - showTime(); - count = 0; - } -} - -#ifdef USE_AUTH_COOKIE - unsigned long key[4] = {0x01F20304,0x05060708,0x090a0b0c,0x0d0e0f00}; - Xtea x(key); - -void encip(String &mtk, unsigned long token){ - unsigned long res[2] = {(unsigned long)random(0xFFFFFFFF),token}; - x.encrypt(res); - char buf1[18]; - sprintf(buf1, "%08X_%08X",res[0],res[1]); //8 bytes for encryping the IP cookie - mtk = (String)buf1; -} - -unsigned long decip(const char *pch){ - unsigned long res[2] = {0,0}; - res[0] = strtoul(pch, NULL, 16); - res[1] = strtoul(&pch[9], NULL, 16); - x.decrypt(res); - return res[1]; -} - -bool myHandshake(AsyncWebServerRequest *request){ // false will 401 - bool rslt = false; - if (request->hasHeader("Cookie")){ - String cookie = request->header("Cookie"); - Serial.println(cookie); - - uint8_t pos = cookie.indexOf(MY_COOKIE_PREF); - if (pos != -1){ - unsigned long ix = decip(cookie.substring(pos+5, pos+22).c_str()); - Serial.printf("Ask:%08X Got:%08X\n", MY_SECRET_NUMBER, ix); - if (MY_SECRET_NUMBER == ix) - rslt=true; - } else rslt=false; - } else rslt=false; - Serial.printf(rslt ? "C-YES\n" : "C-NO\n"); - return rslt; -} -#endif - -// server -void onWsEvent(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventType type, void * arg, uint8_t *data, size_t len){ - if(type == WS_EVT_CONNECT){ - Serial.printf("ws[%s][%u] connect\n", server->url(), client->id()); - //client->printf("Hello Client %u :)", client->id()); - //client->ping(); - - IPAddress ip = client->remoteIP(); - Serial.printf("[%u] Connected from %d.%d.%d.%d\n", client->id(), ip[0], ip[1], ip[2], ip[3]); - showTime(); - analogSample(); - if (ledState == LED_OFF) ws.textAll("led,ledoff"); - else ws.textAll("led,ledon"); - - ws.printfAll("Now,Setting,%02d:%02d,%02d:%02d,%+2.1f", ee.hstart, ee.mstart, ee.hstop, ee.mstop, ee.tempe); - ws.printfAll("Now,sched,%d", sched); - - } else if(type == WS_EVT_DISCONNECT){ - Serial.printf("ws[%s][%u] disconnect\n", server->url(), client->id()); - ws.textAll("Now,remoff"); - - } else if(type == WS_EVT_ERROR){ - Serial.printf("ws[%s][%u] error(%u): %s\n", server->url(), client->id(), *((uint16_t*)arg), (char*)data); - } else if(type == WS_EVT_PONG){ - Serial.printf("ws[%s][%u] pong[%u]: %s\n", server->url(), client->id(), len, (len)?(char*)data:""); - } else if(type == WS_EVT_DATA){ - AwsFrameInfo * info = (AwsFrameInfo*)arg; - String msg = ""; - if(info->final && info->index == 0 && info->len == len){ - //the whole message is in a single frame and we got all of it's data - Serial.printf("ws[%s][%u] %s-message[%llu]: ", server->url(), client->id(), (info->opcode == WS_TEXT)?"text":"binary", info->len); - - if(info->opcode == WS_TEXT){ - for(size_t i=0; i < info->len; i++){ //debug - msg += (char) data[i]; - } - if(data[0] == 'L'){ // LED - if(data[1] == '1'){ - ledState = LED_ON; - ws.textAll("led,ledon"); // for others - } - else if(data[1] == '0'){ - ledState = LED_OFF; - ws.textAll("led,ledoff"); - } - - } else if(data[0] == 'T'){ // timeset - if (len > 11){ - data[3] = data[6] = data[9] = data[12] = 0; // cut strings - ee.hstart = (uint8_t) atoi((const char *) &data[1]); - ee.mstart = (uint8_t) atoi((const char *) &data[4]); - ee.hstop = (uint8_t) atoi((const char *) &data[7]); - ee.mstop = (uint8_t) atoi((const char *) &data[10]); - Serial.printf("[%u] Timer set %02d:%02d - %02d:%02d\n", client->id(), ee.hstart, ee.mstart, ee.hstop, ee.mstop); - writeEE(); - memch = 255; // to force showTime()to send Setting - showTime(); - } - } else if(data[0] == 'W'){ // temperatureset - if (len > 3){ - if (ee.tempe != (float) atof((const char *) &data[1])){ - ee.tempe = (float) atof((const char *) &data[1]); - Serial.printf("[%u] Temp set %+2.1f\n", client->id(), ee.tempe); - writeEE(); - memch = 255; // to force showTime()to send Setting - showTime(); - } - } - } else if ((data[0] == 'Z')&&(len > 2)){ // sched - data[2] = 0; - if (sched != (uint8_t) atoi((const char *) &data[1])){ - sched = (uint8_t) atoi((const char *) &data[1]); - EEPROM.put(EESC, sched); //separately - EEPROM.commit(); //needed for ESP8266? - ws.printfAll("Now,sched,%d", sched); - showTime(); - } - } - - } else { - char buff[3]; - for(size_t i=0; i < info->len; i++){ - sprintf(buff, "%02x ", (uint8_t) data[i]); - msg += buff ; - } - } - Serial.printf("%s\n",msg.c_str()); - - if(info->opcode == WS_TEXT) - client->text("I got your text message"); - else - client->binary("I got your binary message"); - - } else { - //message is comprised of multiple frames or the frame is split into multiple packets - if(info->index == 0){ - if(info->num == 0) - Serial.printf("ws[%s][%u] %s-message start\n", server->url(), client->id(), (info->message_opcode == WS_TEXT)?"text":"binary"); - Serial.printf("ws[%s][%u] frame[%u] start[%llu]\n", server->url(), client->id(), info->num, info->len); - } - - Serial.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 < len; i++){ - msg += (char) data[i]; - } - } else { - char buff[3]; - for(size_t i=0; i < len; i++){ - sprintf(buff, "%02x ", (uint8_t) data[i]); - msg += buff ; - } - } - Serial.printf("%s\n",msg.c_str()); - - if((info->index + len) == info->len){ - Serial.printf("ws[%s][%u] frame[%u] end[%llu]\n", server->url(), client->id(), info->num, info->len); - if(info->final){ - Serial.printf("ws[%s][%u] %s-message end\n", server->url(), client->id(), (info->message_opcode == WS_TEXT)?"text":"binary"); - if(info->message_opcode == WS_TEXT) - client->text("I got your text message"); - else - client->binary("I got your binary message"); - } - } - } - } -} - - -// setup ----------------------------------- - -void setup(){ - Serial.begin(115200); - //Serial.setDebugOutput(true); - -//Wifi -#ifdef USE_WFM - AsyncWiFiManager wifiManager(&server,&dns); - #ifdef DEL_WFM - wifiManager.resetSettings(); - #endif - wifiManager.setTimeout(FBTO); // seconds to config or it creates an own AP, then browse 192.168.4.1 - if (!wifiManager.autoConnect(hostName)){ - Serial.print(F("*FALLBACK AP*\n")); - WiFi.mode(WIFI_AP); - WiFi.softAP(fbssid, fbpassword); - // MDNS.begin(fbssid); - // MDNS.addService("http","tcp",80); // Core SVN 5179 use STA as default interface in mDNS (#7042) - } - -#else -// Manual simple STA mode to connect to known router - //WiFi.mode(WIFI_AP_STA); // Core SVN 5179 use STA as default interface in mDNS (#7042) - //WiFi.softAP(hostName); // Core SVN 5179 use STA as default interface in mDNS (#7042) - WiFi.mode(WIFI_STA); // Core SVN 5179 use STA as default interface in mDNS (#7042) - WiFi.begin(ssid, password); - if (WiFi.waitForConnectResult() != WL_CONNECTED){ - Serial.print(F("STA: Failed!\n")); - WiFi.disconnect(false); - delay(1000); - WiFi.begin(ssid, password); - } -#endif - - Serial.print(F("*CONNECTED* OWN IP:")); - Serial.println(WiFi.localIP()); - -//DHT - dht.begin(); - updateDHT(); //first reading takes time, hold here than the loop; - -//Real Time - time_t rtc = RTC_UTC_TEST; - timeval tv = { rtc, 0 }; - //timezone tz = { 0, 0 }; //(insert) <#5194 - settimeofday(&tv, nullptr); //settimeofday(&tv, &tz); // <#5194 - configTzTime(MYTZ, "pool.ntp.org"); - -//MDNS (not needed) - // MDNS.begin(hostName); - // MDNS.addService("http","tcp",80); // Core SVN 5179 use STA as default interface in mDNS (#7042) - -//I/O & DHT - pinMode(ledPin, OUTPUT); - pinMode(btnPin, INPUT_PULLUP); - -//EE - EEPROM.begin(EEALL); - //EEPROM.get(EECH, memch); //current channel, no need - readEE(); // populate structure if healthy - Serial.printf("Timer set %02d:%02d - %02d:%02d\n", ee.hstart, ee.mstart, ee.hstop, ee.mstop); - Serial.printf("Temp set %+2.1f\n", ee.tempe); - -//FS -#ifdef USE_FatFS - if (MYFS.begin(false,"/ffat",3)){ //limit the RAM usage, bottom line 8kb + 4kb takes per each file, default is 10 -#else - if (MYFS.begin()){ -#endif - Serial.print(F("FS mounted\n")); - } else { - Serial.print(F("FS mount failed\n")); - } - -#ifdef USE_AUTH_WS - ws.setAuthentication(http_username,http_password); -#endif - -#ifdef USE_AUTH_COOKIE - ws.handleHandshake(myHandshake); -#endif - - ws.onEvent(onWsEvent); - server.addHandler(&ws); - -#ifdef ESP32 - #ifdef USE_AUTH_STAT - server.addHandler(new SPIFFSEditor(MYFS, http_username,http_password)); - #elif defined(USE_AUTH_COOKIE) - server.addHandler(new SPIFFSEditor(MYFS)).setFilter(myHandshake); - #else - server.addHandler(new SPIFFSEditor(MYFS)); - #endif -#elif defined(ESP8266) - #ifdef USE_AUTH_STAT - server.addHandler(new SPIFFSEditor(http_username,http_password,MYFS)); - #elif defined(USE_AUTH_COOKIE) - server.addHandler(new SPIFFSEditor("","",MYFS)).setFilter(myHandshake); - #else - server.addHandler(new SPIFFSEditor("","",MYFS)); - #endif -#endif - -#ifdef USE_AUTH_COOKIE - server.on("/lg2n", HTTP_POST, [](AsyncWebServerRequest *request){ - - String ckx; - encip(ckx, MY_SECRET_NUMBER); - - AsyncWebServerResponse *response; - - if(request->hasParam("lg0f",true)){ - response = request->beginResponse(200, "text/html;charset=utf-8", "

Logged Out! Back

"); - response->addHeader("Cache-Control", "no-cache"); - response->addHeader("Set-Cookie", MY_COOKIE_DEL); - - } else if(request->hasParam("pa2w",true) && (String(request->getParam("pa2w",true)->value().c_str()) == String(http_password))){ - response = request->beginResponse(301); - response->addHeader("Location", "/"); - response->addHeader("Cache-Control", "no-cache"); - response->addHeader("Set-Cookie", MY_COOKIE_PREF + ckx + MY_COOKIE_SUFF); - - } else response = request->beginResponse(200, "text/html;charset=utf-8", "

Wrong password! Back

"); - - request->send(response); - }); -#endif - -// below paths need individual auth //////////////////////////////////////////////// - - server.on("/free-ram", HTTP_GET, [](AsyncWebServerRequest *request){ // direct request->answer -#ifdef USE_AUTH_STAT - if(!request->authenticate(http_username, http_password)) return request->requestAuthentication(); -#endif - -#ifdef ESP32 - request->send(200, "text/plain", String(ESP.getMinFreeHeap()) + ':' + String(ESP.getFreeHeap()) + ':'+ String(ESP.getHeapSize())); -#else - request->send(200, "text/plain", String(ESP.getFreeHeap())); -#endif - - -#ifdef USE_AUTH_COOKIE - }).setFilter(myHandshake); -#else - }); -#endif - - server.on("/get-time", HTTP_GET, [](AsyncWebServerRequest *request){ -#ifdef USE_AUTH_STAT - if(!request->authenticate(http_username, http_password)) return request->requestAuthentication(); -#endif - if(request->hasParam("btime")){ - time_t rtc = (request->getParam("btime")->value()).toInt(); - timeval tv = { rtc, 0 }; - settimeofday(&tv, nullptr); - } - request->send(200, "text/plain","Got browser time ..."); -#ifdef USE_AUTH_COOKIE - }).setFilter(myHandshake); -#else - }); -#endif - - server.on("/hw-reset", HTTP_GET, [](AsyncWebServerRequest *request){ -#ifdef USE_AUTH_STAT - if(!request->authenticate(http_username, http_password)) return request->requestAuthentication(); -#endif - request->onDisconnect([](){ -#ifdef ESP32 - ESP.restart(); -#elif defined(ESP8266) - ESP.reset(); -#endif - }); - request->send(200, "text/plain","Restarting ..."); -#ifdef USE_AUTH_COOKIE - }).setFilter(myHandshake); -#else - }); -#endif - - server.on("/erase-wifi", HTTP_GET, [](AsyncWebServerRequest *request){ -#ifdef USE_AUTH_STAT - if(!request->authenticate(http_username, http_password)) return request->requestAuthentication(); -#endif - request->onDisconnect([](){ -#ifdef ESP32 -/* - //https://github.com/espressif/arduino-esp32/issues/400#issuecomment-499631249 - //WiFi.disconnect(true); // doesn't work on esp32, below needs #include "esp_wifi.h" - wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); //load the flash-saved configs - esp_wifi_init(&cfg); //initiate and allocate wifi resources (does not matter if connection fails) - if(esp_wifi_restore()!=ESP_OK){ - Serial.print(F("WiFi is not initialized by esp_wifi_init ")); - } else { - Serial.print(F("WiFi Configurations Cleared!")); - } -*/ - WiFi.disconnect(true, true); // Works on esp32 - ESP.restart(); -#elif defined(ESP8266) - WiFi.disconnect(true); - ESP.reset(); -#endif - }); - request->send(200, "text/plain","Erasing WiFi data ..."); -#ifdef USE_AUTH_COOKIE - }).setFilter(myHandshake); -#else - }); -#endif - -// above paths need individual auth //////////////////////////////////////////////// - -#ifdef USE_AUTH_COOKIE - server.serveStatic("/", MYFS, "/").setDefaultFile("index.htm").setFilter(myHandshake); - server.serveStatic("/", MYFS, "/login/").setDefaultFile("index.htm"); -#else - #ifdef USE_AUTH_STAT - server.serveStatic("/", MYFS, "/").setDefaultFile("index.htm").setAuthentication(http_username,http_password); - #else - server.serveStatic("/", MYFS, "/").setDefaultFile("index.htm"); - #endif -#endif - - server.onNotFound([](AsyncWebServerRequest *request){ // nothing known - Serial.print(F("NOT_FOUND: ")); - if (request->method() == HTTP_OPTIONS) request->send(200); //CORS - else request->send(404); - }); - - DefaultHeaders::Instance().addHeader("Access-Control-Allow-Origin", "*");//CORS - server.begin(); - - //Timer tick - tim.attach(0.2, mytimer); //every 0.2s - - //OTA - ArduinoOTA.setHostname(hostName); - ArduinoOTA.onStart([](){ - Serial.print(F("OTA Started ...\n")); - MYFS.end(); // Clean FS - ws.textAll("Now,OTA"); // for all clients - ws.enable(false); - ws.closeAll(); - }); - ArduinoOTA.begin(); -} // setup end - -// loop ----------------------------------- -void loop(){ - if (udht){ // 5sec - updateDHT(); - udht = false; - } - doOut(); - ArduinoOTA.handle(); -} diff --git a/examples/SmartSwitch/Xtea.cpp b/examples/SmartSwitch/Xtea.cpp deleted file mode 100644 index 97d99b0ab..000000000 --- a/examples/SmartSwitch/Xtea.cpp +++ /dev/null @@ -1,48 +0,0 @@ -/* - Xtea.cpp - Xtea encryption/decryption - Written by Frank Kienast in November, 2010 - https://github.com/franksmicro/Arduino/tree/master/libraries/Xtea -*/ -#include -#include "Xtea.h" - -#define NUM_ROUNDS 32 - -Xtea::Xtea(unsigned long key[4]) -{ - _key[0] = key[0]; - _key[1] = key[1]; - _key[2] = key[2]; - _key[3] = key[3]; -} - -void Xtea::encrypt(unsigned long v[2]) -{ - unsigned int i; - unsigned long v0=v[0], v1=v[1], sum=0, delta=0x9E3779B9; - - for (i=0; i < NUM_ROUNDS; i++) - { - v0 += (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + _key[sum & 3]); - sum += delta; - v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + _key[(sum>>11) & 3]); - } - - v[0]=v0; v[1]=v1; -} - -void Xtea::decrypt(unsigned long v[2]) -{ - unsigned int i; - uint32_t v0=v[0], v1=v[1], delta=0x9E3779B9, sum=delta*NUM_ROUNDS; - - for (i=0; i < NUM_ROUNDS; i++) - { - v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + _key[(sum>>11) & 3]); - sum -= delta; - v0 -= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + _key[sum & 3]); - } - - v[0]=v0; v[1]=v1; -} - diff --git a/examples/SmartSwitch/Xtea.h b/examples/SmartSwitch/Xtea.h deleted file mode 100644 index fc8fa43cc..000000000 --- a/examples/SmartSwitch/Xtea.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - Xtea.h - Crypto library - Written by Frank Kienast in November, 2010 - https://github.com/franksmicro/Arduino/tree/master/libraries/Xtea -*/ -#ifndef Xtea_h -#define Xtea_h - - -class Xtea -{ - public: - Xtea(unsigned long key[4]); - void encrypt(unsigned long data[2]); - void decrypt(unsigned long data[2]); - private: - unsigned long _key[4]; -}; - -#endif diff --git a/examples/SmartSwitch/data/.exclude.files b/examples/SmartSwitch/data/.exclude.files deleted file mode 100644 index a1c42787a..000000000 --- a/examples/SmartSwitch/data/.exclude.files +++ /dev/null @@ -1,3 +0,0 @@ -/*.gz -/edit_gz -/.exclude.files diff --git a/examples/SmartSwitch/data/ace.ico.gz b/examples/SmartSwitch/data/ace.ico.gz deleted file mode 100644 index 49e15bcebdeba0b55db396e5b6266b6e72730070..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6307 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 diff --git a/examples/SmartSwitch/data/edit_gz b/examples/SmartSwitch/data/edit_gz deleted file mode 100644 index be687a3942deeecdc96ea3fc3a2302c7b73408b7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4503 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 diff --git a/examples/SmartSwitch/data/favicon.ico.gz b/examples/SmartSwitch/data/favicon.ico.gz deleted file mode 100644 index 0cab430e3937861565e9a75680255486ee4df01c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4314 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 IB`!Pw0Np(IrT_o{ diff --git a/examples/SmartSwitch/data/index.htm b/examples/SmartSwitch/data/index.htm deleted file mode 100644 index 2a9d283f4..000000000 --- a/examples/SmartSwitch/data/index.htm +++ /dev/null @@ -1,626 +0,0 @@ - - - - - Smart Switch - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - -
-
- - - - - - - - -
- - - - - -
-
- -
-
-
- -
-
- - - - - -
- -
-
-
-
-
- -
- - - - - - - - \ No newline at end of file diff --git a/examples/SmartSwitch/data/login/favicon.ico.gz b/examples/SmartSwitch/data/login/favicon.ico.gz deleted file mode 100644 index 9e605465c6e22500502ba34a11be2488bc508355..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5806 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 diff --git a/examples/SmartSwitch/data/login/index.htm b/examples/SmartSwitch/data/login/index.htm deleted file mode 100644 index d17ef7f49..000000000 --- a/examples/SmartSwitch/data/login/index.htm +++ /dev/null @@ -1,36 +0,0 @@ - - - - - Login - - - - - - -
- - - - - \ No newline at end of file diff --git a/examples/SmartSwitch/data/worker-css.js.gz b/examples/SmartSwitch/data/worker-css.js.gz deleted file mode 100644 index 6bab483026a8fb0ef25353f10db64a75d38d99b3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 32927 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≥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 H;4A|GFx8L> diff --git a/examples/SmartSwitch/data/worker-javascript.js.gz b/examples/SmartSwitch/data/worker-javascript.js.gz deleted file mode 100644 index 9cbfd2049f4dc579c777e291376a775707d0a573..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 112558 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

Fc!=jWPu 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 diff --git a/examples/SmartSwitch/data/worker-json.js.gz b/examples/SmartSwitch/data/worker-json.js.gz deleted file mode 100644 index fec1f65b323b3e5e21bf3b6a4945fe7623628312..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6923 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,"")>-1&&(a=RegExp(this.source,r.replace.call(o(this),"g","")),r.replace.call(e.slice(t.index),a,function(){for(var e=1;et.index&&this.lastIndex--}return t},s||(RegExp.prototype.test=function(e){var t=r.exec.call(this,e);return t&&this.global&&!t[0].length&&this.lastIndex>t.index&&this.lastIndex--,!!t})}),define("ace/lib/es5-shim",["require","exports","module"],function(e,t,n){function r(){}function w(e){try{return Object.defineProperty(e,"sentinel",{}),"sentinel"in e}catch(t){}}function H(e){return e=+e,e!==e?e=0:e!==0&&e!==1/0&&e!==-1/0&&(e=(e>0||-1)*Math.floor(Math.abs(e))),e}function B(e){var t=typeof e;return e===null||t==="undefined"||t==="boolean"||t==="number"||t==="string"}function j(e){var t,n,r;if(B(e))return e;n=e.valueOf;if(typeof n=="function"){t=n.call(e);if(B(t))return t}r=e.toString;if(typeof r=="function"){t=r.call(e);if(B(t))return t}throw new TypeError}Function.prototype.bind||(Function.prototype.bind=function(t){var n=this;if(typeof n!="function")throw new TypeError("Function.prototype.bind called on incompatible "+n);var i=u.call(arguments,1),s=function(){if(this instanceof s){var e=n.apply(this,i.concat(u.call(arguments)));return Object(e)===e?e:this}return n.apply(t,i.concat(u.call(arguments)))};return n.prototype&&(r.prototype=n.prototype,s.prototype=new r,r.prototype=null),s});var i=Function.prototype.call,s=Array.prototype,o=Object.prototype,u=s.slice,a=i.bind(o.toString),f=i.bind(o.hasOwnProperty),l,c,h,p,d;if(d=f(o,"__defineGetter__"))l=i.bind(o.__defineGetter__),c=i.bind(o.__defineSetter__),h=i.bind(o.__lookupGetter__),p=i.bind(o.__lookupSetter__);if([1,2].splice(0).length!=2)if(!function(){function e(e){var t=new Array(e+2);return t[0]=t[1]=0,t}var t=[],n;t.splice.apply(t,e(20)),t.splice.apply(t,e(26)),n=t.length,t.splice(5,0,"XXX"),n+1==t.length;if(n+1==t.length)return!0}())Array.prototype.splice=function(e,t){var n=this.length;e>0?e>n&&(e=n):e==void 0?e=0:e<0&&(e=Math.max(n+e,0)),e+ta)for(h=l;h--;)this[f+h]=this[a+h];if(s&&e===c)this.length=c,this.push.apply(this,i);else{this.length=c+s;for(h=0;h>>0;if(a(t)!="[object Function]")throw new TypeError;while(++s>>0,s=Array(i),o=arguments[1];if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");for(var u=0;u>>0,s=[],o,u=arguments[1];if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");for(var f=0;f>>0,s=arguments[1];if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");for(var o=0;o>>0,s=arguments[1];if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");for(var o=0;o>>0;if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");if(!i&&arguments.length==1)throw new TypeError("reduce of empty array with no initial value");var s=0,o;if(arguments.length>=2)o=arguments[1];else do{if(s in r){o=r[s++];break}if(++s>=i)throw new TypeError("reduce of empty array with no initial value")}while(!0);for(;s>>0;if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");if(!i&&arguments.length==1)throw new TypeError("reduceRight of empty array with no initial value");var s,o=i-1;if(arguments.length>=2)s=arguments[1];else do{if(o in r){s=r[o--];break}if(--o<0)throw new TypeError("reduceRight of empty array with no initial value")}while(!0);do o in this&&(s=t.call(void 0,s,r[o],o,n));while(o--);return s});if(!Array.prototype.indexOf||[0,1].indexOf(1,2)!=-1)Array.prototype.indexOf=function(t){var n=g&&a(this)=="[object String]"?this.split(""):F(this),r=n.length>>>0;if(!r)return-1;var i=0;arguments.length>1&&(i=H(arguments[1])),i=i>=0?i:Math.max(0,r+i);for(;i>>0;if(!r)return-1;var i=r-1;arguments.length>1&&(i=Math.min(i,H(arguments[1]))),i=i>=0?i:r-Math.abs(i);for(;i>=0;i--)if(i in n&&t===n[i])return i;return-1};Object.getPrototypeOf||(Object.getPrototypeOf=function(t){return t.__proto__||(t.constructor?t.constructor.prototype:o)});if(!Object.getOwnPropertyDescriptor){var y="Object.getOwnPropertyDescriptor called on a non-object: ";Object.getOwnPropertyDescriptor=function(t,n){if(typeof t!="object"&&typeof t!="function"||t===null)throw new TypeError(y+t);if(!f(t,n))return;var r,i,s;r={enumerable:!0,configurable:!0};if(d){var u=t.__proto__;t.__proto__=o;var i=h(t,n),s=p(t,n);t.__proto__=u;if(i||s)return i&&(r.get=i),s&&(r.set=s),r}return r.value=t[n],r}}Object.getOwnPropertyNames||(Object.getOwnPropertyNames=function(t){return Object.keys(t)});if(!Object.create){var b;Object.prototype.__proto__===null?b=function(){return{__proto__:null}}:b=function(){var e={};for(var t in e)e[t]=null;return e.constructor=e.hasOwnProperty=e.propertyIsEnumerable=e.isPrototypeOf=e.toLocaleString=e.toString=e.valueOf=e.__proto__=null,e},Object.create=function(t,n){var r;if(t===null)r=b();else{if(typeof t!="object")throw new TypeError("typeof prototype["+typeof t+"] != 'object'");var i=function(){};i.prototype=t,r=new i,r.__proto__=t}return n!==void 0&&Object.defineProperties(r,n),r}}if(Object.defineProperty){var E=w({}),S=typeof document=="undefined"||w(document.createElement("div"));if(!E||!S)var x=Object.defineProperty}if(!Object.defineProperty||x){var T="Property description must be an object: ",N="Object.defineProperty called on non-object: ",C="getters & setters can not be defined on this javascript engine";Object.defineProperty=function(t,n,r){if(typeof t!="object"&&typeof t!="function"||t===null)throw new TypeError(N+t);if(typeof r!="object"&&typeof r!="function"||r===null)throw new TypeError(T+r);if(x)try{return x.call(Object,t,n,r)}catch(i){}if(f(r,"value"))if(d&&(h(t,n)||p(t,n))){var s=t.__proto__;t.__proto__=o,delete t[n],t[n]=r.value,t.__proto__=s}else t[n]=r.value;else{if(!d)throw new TypeError(C);f(r,"get")&&l(t,n,r.get),f(r,"set")&&c(t,n,r.set)}return t}}Object.defineProperties||(Object.defineProperties=function(t,n){for(var r in n)f(n,r)&&Object.defineProperty(t,r,n[r]);return t}),Object.seal||(Object.seal=function(t){return t}),Object.freeze||(Object.freeze=function(t){return t});try{Object.freeze(function(){})}catch(k){Object.freeze=function(t){return function(n){return typeof n=="function"?n:t(n)}}(Object.freeze)}Object.preventExtensions||(Object.preventExtensions=function(t){return t}),Object.isSealed||(Object.isSealed=function(t){return!1}),Object.isFrozen||(Object.isFrozen=function(t){return!1}),Object.isExtensible||(Object.isExtensible=function(t){if(Object(t)===t)throw new TypeError;var n="";while(f(t,n))n+="?";t[n]=!0;var r=f(t,n);return delete t[n],r});if(!Object.keys){var L=!0,A=["toString","toLocaleString","valueOf","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","constructor"],O=A.length;for(var M in{toString:null})L=!1;Object.keys=function I(e){if(typeof e!="object"&&typeof e!="function"||e===null)throw new TypeError("Object.keys called on a non-object");var I=[];for(var t in e)f(e,t)&&I.push(t);if(L)for(var n=0,r=O;n=0?parseFloat((s.match(/(?:MSIE |Trident\/[0-9]+[\.0-9]+;.*rv:)([0-9]+[\.0-9]+)/)||[])[1]):parseFloat((s.match(/(?:Trident\/[0-9]+[\.0-9]+;.*rv:)([0-9]+[\.0-9]+)/)||[])[1]),t.isOldIE=t.isIE&&t.isIE<9,t.isGecko=t.isMozilla=s.match(/ Gecko\/\d+/),t.isOpera=typeof opera=="object"&&Object.prototype.toString.call(window.opera)=="[object Opera]",t.isWebKit=parseFloat(s.split("WebKit/")[1])||undefined,t.isChrome=parseFloat(s.split(" Chrome/")[1])||undefined,t.isEdge=parseFloat(s.split(" Edge/")[1])||undefined,t.isAIR=s.indexOf("AdobeAIR")>=0,t.isAndroid=s.indexOf("Android")>=0,t.isChromeOS=s.indexOf(" CrOS ")>=0,t.isIOS=/iPad|iPhone|iPod/.test(s)&&!window.MSStream,t.isIOS&&(t.isMac=!0),t.isMobile=t.isIOS||t.isAndroid}),define("ace/lib/dom",["require","exports","module","ace/lib/useragent"],function(e,t,n){"use strict";var r=e("./useragent"),i="http://www.w3.org/1999/xhtml";t.buildDom=function o(e,t,n){if(typeof e=="string"&&e){var r=document.createTextNode(e);return t&&t.appendChild(r),r}if(!Array.isArray(e))return e;if(typeof e[0]!="string"||!e[0]){var i=[];for(var s=0;s=1.5:!0;if(typeof document!="undefined"){var s=document.createElement("div");t.HI_DPI&&s.style.transform!==undefined&&(t.HAS_CSS_TRANSFORMS=!0),!r.isEdge&&typeof s.style.animationName!="undefined"&&(t.HAS_CSS_ANIMATION=!0),s=null}t.HAS_CSS_TRANSFORMS?t.translate=function(e,t,n){e.style.transform="translate("+Math.round(t)+"px, "+Math.round(n)+"px)"}:t.translate=function(e,t,n){e.style.top=Math.round(n)+"px",e.style.left=Math.round(t)+"px"}}),define("ace/lib/oop",["require","exports","module"],function(e,t,n){"use strict";t.inherits=function(e,t){e.super_=t,e.prototype=Object.create(t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}})},t.mixin=function(e,t){for(var n in t)e[n]=t[n];return e},t.implement=function(e,n){t.mixin(e,n)}}),define("ace/lib/keys",["require","exports","module","ace/lib/oop"],function(e,t,n){"use strict";var r=e("./oop"),i=function(){var e={MODIFIER_KEYS:{16:"Shift",17:"Ctrl",18:"Alt",224:"Meta",91:"MetaLeft",92:"MetaRight",93:"ContextMenu"},KEY_MODS:{ctrl:1,alt:2,option:2,shift:4,"super":8,meta:8,command:8,cmd:8},FUNCTION_KEYS:{8:"Backspace",9:"Tab",13:"Return",19:"Pause",27:"Esc",32:"Space",33:"PageUp",34:"PageDown",35:"End",36:"Home",37:"Left",38:"Up",39:"Right",40:"Down",44:"Print",45:"Insert",46:"Delete",96:"Numpad0",97:"Numpad1",98:"Numpad2",99:"Numpad3",100:"Numpad4",101:"Numpad5",102:"Numpad6",103:"Numpad7",104:"Numpad8",105:"Numpad9","-13":"NumpadEnter",112:"F1",113:"F2",114:"F3",115:"F4",116:"F5",117:"F6",118:"F7",119:"F8",120:"F9",121:"F10",122:"F11",123:"F12",144:"Numlock",145:"Scrolllock"},PRINTABLE_KEYS:{32:" ",48:"0",49:"1",50:"2",51:"3",52:"4",53:"5",54:"6",55:"7",56:"8",57:"9",59:";",61:"=",65:"a",66:"b",67:"c",68:"d",69:"e",70:"f",71:"g",72:"h",73:"i",74:"j",75:"k",76:"l",77:"m",78:"n",79:"o",80:"p",81:"q",82:"r",83:"s",84:"t",85:"u",86:"v",87:"w",88:"x",89:"y",90:"z",107:"+",109:"-",110:".",186:";",187:"=",188:",",189:"-",190:".",191:"/",192:"`",219:"[",220:"\\",221:"]",222:"'",111:"/",106:"*"}},t,n;for(n in e.FUNCTION_KEYS)t=e.FUNCTION_KEYS[n].toLowerCase(),e[t]=parseInt(n,10);for(n in e.PRINTABLE_KEYS)t=e.PRINTABLE_KEYS[n].toLowerCase(),e[t]=parseInt(n,10);return r.mixin(e,e.MODIFIER_KEYS),r.mixin(e,e.PRINTABLE_KEYS),r.mixin(e,e.FUNCTION_KEYS),e.enter=e["return"],e.escape=e.esc,e.del=e["delete"],e[173]="-",function(){var t=["cmd","ctrl","alt","shift"];for(var n=Math.pow(2,t.length);n--;)e.KEY_MODS[n]=t.filter(function(t){return n&e.KEY_MODS[t]}).join("-")+"-"}(),e.KEY_MODS[0]="",e.KEY_MODS[-1]="input-",e}();r.mixin(t,i),t.keyCodeToString=function(e){var t=i[e];return typeof t!="string"&&(t=String.fromCharCode(e)),t.toLowerCase()}}),define("ace/lib/event",["require","exports","module","ace/lib/keys","ace/lib/useragent"],function(e,t,n){"use strict";function a(){u=!1;try{document.createComment("").addEventListener("test",function(){},{get passive(){u={passive:!1}}})}catch(e){}}function f(){return u==undefined&&a(),u}function c(e,t,n){var u=l(t);if(!i.isMac&&s){t.getModifierState&&(t.getModifierState("OS")||t.getModifierState("Win"))&&(u|=8);if(s.altGr){if((3&u)==3)return;s.altGr=0}if(n===18||n===17){var a="location"in t?t.location:t.keyLocation;if(n===17&&a===1)s[n]==1&&(o=t.timeStamp);else if(n===18&&u===3&&a===2){var f=t.timeStamp-o;f<50&&(s.altGr=!0)}}}n in r.MODIFIER_KEYS&&(n=-1);if(!u&&n===13){var a="location"in t?t.location:t.keyLocation;if(a===3){e(t,u,-n);if(t.defaultPrevented)return}}if(i.isChromeOS&&u&8){e(t,u,n);if(t.defaultPrevented)return;u&=-9}return!!u||n in r.FUNCTION_KEYS||n in r.PRINTABLE_KEYS?e(t,u,n):!1}function h(){s=Object.create(null)}var r=e("./keys"),i=e("./useragent"),s=null,o=0,u;t.addListener=function(e,t,n){return e.addEventListener(t,n,f())},t.removeListener=function(e,t,n){return e.removeEventListener(t,n,f())},t.stopEvent=function(e){return t.stopPropagation(e),t.preventDefault(e),!1},t.stopPropagation=function(e){e.stopPropagation&&e.stopPropagation()},t.preventDefault=function(e){e.preventDefault&&e.preventDefault()},t.getButton=function(e){return e.type=="dblclick"?0:e.type=="contextmenu"||i.isMac&&e.ctrlKey&&!e.altKey&&!e.shiftKey?2:e.button},t.capture=function(e,n,r){function i(e){n&&n(e),r&&r(e),t.removeListener(document,"mousemove",n,!0),t.removeListener(document,"mouseup",i,!0),t.removeListener(document,"dragstart",i,!0)}return t.addListener(document,"mousemove",n,!0),t.addListener(document,"mouseup",i,!0),t.addListener(document,"dragstart",i,!0),i},t.addMouseWheelListener=function(e,n){"onmousewheel"in e?t.addListener(e,"mousewheel",function(e){var t=8;e.wheelDeltaX!==undefined?(e.wheelX=-e.wheelDeltaX/t,e.wheelY=-e.wheelDeltaY/t):(e.wheelX=0,e.wheelY=-e.wheelDelta/t),n(e)}):"onwheel"in e?t.addListener(e,"wheel",function(e){var t=.35;switch(e.deltaMode){case e.DOM_DELTA_PIXEL:e.wheelX=e.deltaX*t||0,e.wheelY=e.deltaY*t||0;break;case e.DOM_DELTA_LINE:case e.DOM_DELTA_PAGE:e.wheelX=(e.deltaX||0)*5,e.wheelY=(e.deltaY||0)*5}n(e)}):t.addListener(e,"DOMMouseScroll",function(e){e.axis&&e.axis==e.HORIZONTAL_AXIS?(e.wheelX=(e.detail||0)*5,e.wheelY=0):(e.wheelX=0,e.wheelY=(e.detail||0)*5),n(e)})},t.addMultiMouseDownListener=function(e,n,r,s){function c(e){t.getButton(e)!==0?o=0:e.detail>1?(o++,o>4&&(o=1)):o=1;if(i.isIE){var c=Math.abs(e.clientX-u)>5||Math.abs(e.clientY-a)>5;if(!f||c)o=1;f&&clearTimeout(f),f=setTimeout(function(){f=null},n[o-1]||600),o==1&&(u=e.clientX,a=e.clientY)}e._clicks=o,r[s]("mousedown",e);if(o>4)o=0;else if(o>1)return r[s](l[o],e)}var o=0,u,a,f,l={2:"dblclick",3:"tripleclick",4:"quadclick"};Array.isArray(e)||(e=[e]),e.forEach(function(e){t.addListener(e,"mousedown",c)})};var l=function(e){return 0|(e.ctrlKey?1:0)|(e.altKey?2:0)|(e.shiftKey?4:0)|(e.metaKey?8:0)};t.getModifierString=function(e){return r.KEY_MODS[l(e)]},t.addCommandKeyListener=function(e,n){var r=t.addListener;if(i.isOldGecko||i.isOpera&&!("KeyboardEvent"in window)){var o=null;r(e,"keydown",function(e){o=e.keyCode}),r(e,"keypress",function(e){return c(n,e,o)})}else{var u=null;r(e,"keydown",function(e){s[e.keyCode]=(s[e.keyCode]||0)+1;var t=c(n,e,e.keyCode);return u=e.defaultPrevented,t}),r(e,"keypress",function(e){u&&(e.ctrlKey||e.altKey||e.shiftKey||e.metaKey)&&(t.stopEvent(e),u=null)}),r(e,"keyup",function(e){s[e.keyCode]=null}),s||(h(),r(window,"focus",h))}};if(typeof window=="object"&&window.postMessage&&!i.isOldIE){var p=1;t.nextTick=function(e,n){n=n||window;var r="zero-timeout-message-"+p++,i=function(s){s.data==r&&(t.stopPropagation(s),t.removeListener(n,"message",i),e())};t.addListener(n,"message",i),n.postMessage(r,"*")}}t.$idleBlocked=!1,t.onIdle=function(e,n){return setTimeout(function r(){t.$idleBlocked?setTimeout(r,100):e()},n)},t.$idleBlockId=null,t.blockIdle=function(e){t.$idleBlockId&&clearTimeout(t.$idleBlockId),t.$idleBlocked=!0,t.$idleBlockId=setTimeout(function(){t.$idleBlocked=!1},e||100)},t.nextFrame=typeof window=="object"&&(window.requestAnimationFrame||window.mozRequestAnimationFrame||window.webkitRequestAnimationFrame||window.msRequestAnimationFrame||window.oRequestAnimationFrame),t.nextFrame?t.nextFrame=t.nextFrame.bind(window):t.nextFrame=function(e){setTimeout(e,17)}}),define("ace/range",["require","exports","module"],function(e,t,n){"use strict";var r=function(e,t){return e.row-t.row||e.column-t.column},i=function(e,t,n,r){this.start={row:e,column:t},this.end={row:n,column:r}};(function(){this.isEqual=function(e){return this.start.row===e.start.row&&this.end.row===e.end.row&&this.start.column===e.start.column&&this.end.column===e.end.column},this.toString=function(){return"Range: ["+this.start.row+"/"+this.start.column+"] -> ["+this.end.row+"/"+this.end.column+"]"},this.contains=function(e,t){return this.compare(e,t)==0},this.compareRange=function(e){var t,n=e.end,r=e.start;return t=this.compare(n.row,n.column),t==1?(t=this.compare(r.row,r.column),t==1?2:t==0?1:0):t==-1?-2:(t=this.compare(r.row,r.column),t==-1?-1:t==1?42:0)},this.comparePoint=function(e){return this.compare(e.row,e.column)},this.containsRange=function(e){return this.comparePoint(e.start)==0&&this.comparePoint(e.end)==0},this.intersects=function(e){var t=this.compareRange(e);return t==-1||t==0||t==1},this.isEnd=function(e,t){return this.end.row==e&&this.end.column==t},this.isStart=function(e,t){return this.start.row==e&&this.start.column==t},this.setStart=function(e,t){typeof e=="object"?(this.start.column=e.column,this.start.row=e.row):(this.start.row=e,this.start.column=t)},this.setEnd=function(e,t){typeof e=="object"?(this.end.column=e.column,this.end.row=e.row):(this.end.row=e,this.end.column=t)},this.inside=function(e,t){return this.compare(e,t)==0?this.isEnd(e,t)||this.isStart(e,t)?!1:!0:!1},this.insideStart=function(e,t){return this.compare(e,t)==0?this.isEnd(e,t)?!1:!0:!1},this.insideEnd=function(e,t){return this.compare(e,t)==0?this.isStart(e,t)?!1:!0:!1},this.compare=function(e,t){return!this.isMultiLine()&&e===this.start.row?tthis.end.column?1:0:ethis.end.row?1:this.start.row===e?t>=this.start.column?0:-1:this.end.row===e?t<=this.end.column?0:1:0},this.compareStart=function(e,t){return this.start.row==e&&this.start.column==t?-1:this.compare(e,t)},this.compareEnd=function(e,t){return this.end.row==e&&this.end.column==t?1:this.compare(e,t)},this.compareInside=function(e,t){return this.end.row==e&&this.end.column==t?1:this.start.row==e&&this.start.column==t?-1:this.compare(e,t)},this.clipRows=function(e,t){if(this.end.row>t)var n={row:t+1,column:0};else if(this.end.rowt)var r={row:t+1,column:0};else if(this.start.row0){t&1&&(n+=e);if(t>>=1)e+=e}return n};var r=/^\s\s*/,i=/\s\s*$/;t.stringTrimLeft=function(e){return e.replace(r,"")},t.stringTrimRight=function(e){return e.replace(i,"")},t.copyObject=function(e){var t={};for(var n in e)t[n]=e[n];return t},t.copyArray=function(e){var t=[];for(var n=0,r=e.length;nDate.now()-50?!0:r=!1},cancel:function(){r=Date.now()}}}),define("ace/keyboard/textinput",["require","exports","module","ace/lib/event","ace/lib/useragent","ace/lib/dom","ace/lib/lang","ace/clipboard","ace/lib/keys"],function(e,t,n){"use strict";var r=e("../lib/event"),i=e("../lib/useragent"),s=e("../lib/dom"),o=e("../lib/lang"),u=e("../clipboard"),a=i.isChrome<18,f=i.isIE,l=i.isChrome>63,c=400,h=e("../lib/keys"),p=h.KEY_MODS,d=i.isIOS,v=d?/\s/:/\n/,m=function(e,t){function W(){S=!0,n.blur(),n.focus(),S=!1}function V(e){e.keyCode==27&&n.value.lengthN&&x[s]=="\n")o=h.end;else if(rN&&x.slice(0,s).split("\n").length>2)o=h.down;else if(s>N&&x[s-1]==" ")o=h.right,u=p.option;else if(s>N||s==N&&N!=T&&r==s)o=h.right;r!==s&&(u|=p.shift);if(o){var a=t.onCommandKey({},u,o);if(!a&&t.commands){o=h.keyCodeToString(o);var f=t.commands.findKeyCommand(u,o);f&&t.execCommand(f)}T=r,N=s,A("")}};document.addEventListener("selectionchange",s),t.on("destroy",function(){document.removeEventListener("selectionchange",s)})}var n=s.createElement("textarea");n.className="ace_text-input",n.setAttribute("wrap","off"),n.setAttribute("autocorrect","off"),n.setAttribute("autocapitalize","off"),n.setAttribute("spellcheck",!1),n.style.opacity="0",e.insertBefore(n,e.firstChild);var m=!1,g=!1,y=!1,b=!1,w="";i.isMobile||(n.style.fontSize="1px");var E=!1,S=!1,x="",T=0,N=0,C=0;try{var k=document.activeElement===n}catch(L){}r.addListener(n,"blur",function(e){if(S)return;t.onBlur(e),k=!1}),r.addListener(n,"focus",function(e){if(S)return;k=!0;if(i.isEdge)try{if(!document.hasFocus())return}catch(e){}t.onFocus(e),i.isEdge?setTimeout(A):A()}),this.$focusScroll=!1,this.focus=function(){if(w||l||this.$focusScroll=="browser")return n.focus({preventScroll:!0});var e=n.style.top;n.style.position="fixed",n.style.top="0px";try{var t=n.getBoundingClientRect().top!=0}catch(r){return}var i=[];if(t){var s=n.parentElement;while(s&&s.nodeType==1)i.push(s),s.setAttribute("ace_nocontext",!0),!s.parentElement&&s.getRootNode?s=s.getRootNode().host:s=s.parentElement}n.focus({preventScroll:!0}),t&&i.forEach(function(e){e.removeAttribute("ace_nocontext")}),setTimeout(function(){n.style.position="",n.style.top=="0px"&&(n.style.top=e)},0)},this.blur=function(){n.blur()},this.isFocused=function(){return k},t.on("beforeEndOperation",function(){if(t.curOp&&t.curOp.command.name=="insertstring")return;y&&(x=n.value="",z()),A()});var A=d?function(e){if(!k||m&&!e||b)return;e||(e="");var r="\n ab"+e+"cde fg\n";r!=n.value&&(n.value=x=r);var i=4,s=4+(e.length||(t.selection.isEmpty()?0:1));(T!=i||N!=s)&&n.setSelectionRange(i,s),T=i,N=s}:function(){if(y||b)return;if(!k&&!D)return;y=!0;var e=t.selection,r=e.getRange(),i=e.cursor.row,s=r.start.column,o=r.end.column,u=t.session.getLine(i);if(r.start.row!=i){var a=t.session.getLine(i-1);s=r.start.rowi+1?f.length:o,o+=u.length+1,u=u+"\n"+f}u.length>c&&(s=x.length&&e.value===x&&x&&e.selectionEnd!==N},M=function(e){if(y)return;m?m=!1:O(n)&&(t.selectAll(),A())},_=null;this.setInputHandler=function(e){_=e},this.getInputHandler=function(){return _};var D=!1,P=function(e,r){D&&(D=!1);if(g)return A(),e&&t.onPaste(e),g=!1,"";var i=n.selectionStart,s=n.selectionEnd,o=T,u=x.length-N,a=e,f=e.length-i,l=e.length-s,c=0;while(o>0&&x[c]==e[c])c++,o--;a=a.slice(c),c=1;while(u>0&&x.length-c>T-1&&x[x.length-c]==e[e.length-c])c++,u--;f-=c-1,l-=c-1;var h=a.length-c+1;return h<0&&(o=-h,h=0),a=a.slice(0,h),!r&&!a&&!f&&!o&&!u&&!l?"":(b=!0,a&&!o&&!u&&!f&&!l||E?t.onTextInput(a):t.onTextInput(a,{extendLeft:o,extendRight:u,restoreStart:f,restoreEnd:l}),b=!1,x=e,T=i,N=s,C=l,a)},H=function(e){if(y)return U();if(e&&e.inputType){if(e.inputType=="historyUndo")return t.execCommand("undo");if(e.inputType=="historyRedo")return t.execCommand("redo")}var r=n.value,i=P(r,!0);(r.length>c+100||v.test(i))&&A()},B=function(e,t,n){var r=e.clipboardData||window.clipboardData;if(!r||a)return;var i=f||n?"Text":"text/plain";try{return t?r.setData(i,t)!==!1:r.getData(i)}catch(e){if(!n)return B(e,t,!0)}},j=function(e,i){var s=t.getCopyText();if(!s)return r.preventDefault(e);B(e,s)?(d&&(A(s),m=s,setTimeout(function(){m=!1},10)),i?t.onCut():t.onCopy(),r.preventDefault(e)):(m=!0,n.value=s,n.select(),setTimeout(function(){m=!1,A(),i?t.onCut():t.onCopy()}))},F=function(e){j(e,!0)},I=function(e){j(e,!1)},q=function(e){var s=B(e);if(u.pasteCancelled())return;typeof s=="string"?(s&&t.onPaste(s,e),i.isIE&&setTimeout(A),r.preventDefault(e)):(n.value="",g=!0)};r.addCommandKeyListener(n,t.onCommandKey.bind(t)),r.addListener(n,"select",M),r.addListener(n,"input",H),r.addListener(n,"cut",F),r.addListener(n,"copy",I),r.addListener(n,"paste",q),(!("oncut"in n)||!("oncopy"in n)||!("onpaste"in n))&&r.addListener(e,"keydown",function(e){if(i.isMac&&!e.metaKey||!e.ctrlKey)return;switch(e.keyCode){case 67:I(e);break;case 86:q(e);break;case 88:F(e)}});var R=function(e){if(y||!t.onCompositionStart||t.$readOnly)return;y={};if(E)return;setTimeout(U,0),t.on("mousedown",W);var r=t.getSelectionRange();r.end.row=r.start.row,r.end.column=r.start.column,y.markerRange=r,y.selectionStart=T,t.onCompositionStart(y),y.useTextareaForIME?(n.value="",x="",T=0,N=0):(n.msGetInputContext&&(y.context=n.msGetInputContext()),n.getInputContext&&(y.context=n.getInputContext()))},U=function(){if(!y||!t.onCompositionUpdate||t.$readOnly)return;if(E)return W();if(y.useTextareaForIME)t.onCompositionUpdate(n.value);else{var e=n.value;P(e),y.markerRange&&(y.context&&(y.markerRange.start.column=y.selectionStart=y.context.compositionStartOffset),y.markerRange.end.column=y.markerRange.start.column+N-y.selectionStart+C)}},z=function(e){if(!t.onCompositionEnd||t.$readOnly)return;y=!1,t.onCompositionEnd(),t.off("mousedown",W),e&&H()},X=o.delayedCall(U,50).schedule.bind(null,null);r.addListener(n,"compositionstart",R),r.addListener(n,"compositionupdate",U),r.addListener(n,"keyup",V),r.addListener(n,"keydown",X),r.addListener(n,"compositionend",z),this.getElement=function(){return n},this.setCommandMode=function(e){E=e,n.readOnly=!1},this.setReadOnly=function(e){E||(n.readOnly=e)},this.setCopyWithEmptySelection=function(e){},this.onContextMenu=function(e){D=!0,A(),t._emit("nativecontextmenu",{target:t,domEvent:e}),this.moveToMouse(e,!0)},this.moveToMouse=function(e,o){w||(w=n.style.cssText),n.style.cssText=(o?"z-index:100000;":"")+(i.isIE?"opacity:0.1;":"")+"text-indent: -"+(T+N)*t.renderer.characterWidth*.5+"px;";var u=t.container.getBoundingClientRect(),a=s.computedStyle(t.container),f=u.top+(parseInt(a.borderTopWidth)||0),l=u.left+(parseInt(u.borderLeftWidth)||0),c=u.bottom-f-n.clientHeight-2,h=function(e){s.translate(n,e.clientX-l-2,Math.min(e.clientY-f-2,c))};h(e);if(e.type!="mousedown")return;t.renderer.$isMousePressed=!0,clearTimeout($),i.isWin&&r.capture(t.container,h,J)},this.onContextMenuClose=J;var $,K=function(e){t.textInput.onContextMenu(e),J()};r.addListener(n,"mouseup",K),r.addListener(n,"mousedown",function(e){e.preventDefault(),J()}),r.addListener(t.renderer.scroller,"contextmenu",K),r.addListener(n,"contextmenu",K),d&&Q(e,t,n)};t.TextInput=m}),define("ace/mouse/default_handlers",["require","exports","module","ace/lib/useragent"],function(e,t,n){"use strict";function o(e){e.$clickSelection=null;var t=e.editor;t.setDefaultHandler("mousedown",this.onMouseDown.bind(e)),t.setDefaultHandler("dblclick",this.onDoubleClick.bind(e)),t.setDefaultHandler("tripleclick",this.onTripleClick.bind(e)),t.setDefaultHandler("quadclick",this.onQuadClick.bind(e)),t.setDefaultHandler("mousewheel",this.onMouseWheel.bind(e));var n=["select","startSelect","selectEnd","selectAllEnd","selectByWordsEnd","selectByLinesEnd","dragWait","dragWaitEnd","focusWait"];n.forEach(function(t){e[t]=this[t]},this),e.selectByLines=this.extendSelectionBy.bind(e,"getLineRange"),e.selectByWords=this.extendSelectionBy.bind(e,"getWordRange")}function u(e,t,n,r){return Math.sqrt(Math.pow(n-e,2)+Math.pow(r-t,2))}function a(e,t){if(e.start.row==e.end.row)var n=2*t.column-e.start.column-e.end.column;else if(e.start.row==e.end.row-1&&!e.start.column&&!e.end.column)var n=t.column-4;else var n=2*t.row-e.start.row-e.end.row;return n<0?{cursor:e.start,anchor:e.end}:{cursor:e.end,anchor:e.start}}var r=e("../lib/useragent"),i=0,s=550;(function(){this.onMouseDown=function(e){var t=e.inSelection(),n=e.getDocumentPosition();this.mousedownEvent=e;var i=this.editor,s=e.getButton();if(s!==0){var o=i.getSelectionRange(),u=o.isEmpty();(u||s==1)&&i.selection.moveToPosition(n),s==2&&(i.textInput.onContextMenu(e.domEvent),r.isMozilla||e.preventDefault());return}this.mousedownEvent.time=Date.now();if(t&&!i.isFocused()){i.focus();if(this.$focusTimeout&&!this.$clickSelection&&!i.inMultiSelectMode){this.setState("focusWait"),this.captureMouse(e);return}}return this.captureMouse(e),this.startSelect(n,e.domEvent._clicks>1),e.preventDefault()},this.startSelect=function(e,t){e=e||this.editor.renderer.screenToTextCoordinates(this.x,this.y);var n=this.editor;if(!this.mousedownEvent)return;this.mousedownEvent.getShiftKey()?n.selection.selectToPosition(e):t||n.selection.moveToPosition(e),t||this.select(),n.renderer.scroller.setCapture&&n.renderer.scroller.setCapture(),n.setStyle("ace_selecting"),this.setState("select")},this.select=function(){var e,t=this.editor,n=t.renderer.screenToTextCoordinates(this.x,this.y);if(this.$clickSelection){var r=this.$clickSelection.comparePoint(n);if(r==-1)e=this.$clickSelection.end;else if(r==1)e=this.$clickSelection.start;else{var i=a(this.$clickSelection,n);n=i.cursor,e=i.anchor}t.selection.setSelectionAnchor(e.row,e.column)}t.selection.selectToPosition(n),t.renderer.scrollCursorIntoView()},this.extendSelectionBy=function(e){var t,n=this.editor,r=n.renderer.screenToTextCoordinates(this.x,this.y),i=n.selection[e](r.row,r.column);if(this.$clickSelection){var s=this.$clickSelection.comparePoint(i.start),o=this.$clickSelection.comparePoint(i.end);if(s==-1&&o<=0){t=this.$clickSelection.end;if(i.end.row!=r.row||i.end.column!=r.column)r=i.start}else if(o==1&&s>=0){t=this.$clickSelection.start;if(i.start.row!=r.row||i.start.column!=r.column)r=i.end}else if(s==-1&&o==1)r=i.end,t=i.start;else{var u=a(this.$clickSelection,r);r=u.cursor,t=u.anchor}n.selection.setSelectionAnchor(t.row,t.column)}n.selection.selectToPosition(r),n.renderer.scrollCursorIntoView()},this.selectEnd=this.selectAllEnd=this.selectByWordsEnd=this.selectByLinesEnd=function(){this.$clickSelection=null,this.editor.unsetStyle("ace_selecting"),this.editor.renderer.scroller.releaseCapture&&this.editor.renderer.scroller.releaseCapture()},this.focusWait=function(){var e=u(this.mousedownEvent.x,this.mousedownEvent.y,this.x,this.y),t=Date.now();(e>i||t-this.mousedownEvent.time>this.$focusTimeout)&&this.startSelect(this.mousedownEvent.getDocumentPosition())},this.onDoubleClick=function(e){var t=e.getDocumentPosition(),n=this.editor,r=n.session,i=r.getBracketRange(t);i?(i.isEmpty()&&(i.start.column--,i.end.column++),this.setState("select")):(i=n.selection.getWordRange(t.row,t.column),this.setState("selectByWords")),this.$clickSelection=i,this.select()},this.onTripleClick=function(e){var t=e.getDocumentPosition(),n=this.editor;this.setState("selectByLines");var r=n.getSelectionRange();r.isMultiLine()&&r.contains(t.row,t.column)?(this.$clickSelection=n.selection.getLineRange(r.start.row),this.$clickSelection.end=n.selection.getLineRange(r.end.row).end):this.$clickSelection=n.selection.getLineRange(t.row),this.select()},this.onQuadClick=function(e){var t=this.editor;t.selectAll(),this.$clickSelection=t.getSelectionRange(),this.setState("selectAll")},this.onMouseWheel=function(e){if(e.getAccelKey())return;e.getShiftKey()&&e.wheelY&&!e.wheelX&&(e.wheelX=e.wheelY,e.wheelY=0);var t=this.editor;this.$lastScroll||(this.$lastScroll={t:0,vx:0,vy:0,allowed:0});var n=this.$lastScroll,r=e.domEvent.timeStamp,i=r-n.t,o=i?e.wheelX/i:n.vx,u=i?e.wheelY/i:n.vy;i=1&&t.renderer.isScrollableBy(e.wheelX*e.speed,0)&&(f=!0),a<=1&&t.renderer.isScrollableBy(0,e.wheelY*e.speed)&&(f=!0);if(f)n.allowed=r;else if(r-n.allowedt.session.documentToScreenRow(l.row,l.column))return c()}if(f==s)return;f=s.text.join("
"),i.setHtml(f),i.show(),t._signal("showGutterTooltip",i),t.on("mousewheel",c);if(e.$tooltipFollowsMouse)h(u);else{var p=u.domEvent.target,d=p.getBoundingClientRect(),v=i.getElement().style;v.left=d.right+"px",v.top=d.bottom+"px"}}function c(){o&&(o=clearTimeout(o)),f&&(i.hide(),f=null,t._signal("hideGutterTooltip",i),t.removeEventListener("mousewheel",c))}function h(e){i.setPosition(e.x,e.y)}var t=e.editor,n=t.renderer.$gutterLayer,i=new a(t.container);e.editor.setDefaultHandler("guttermousedown",function(r){if(!t.isFocused()||r.getButton()!=0)return;var i=n.getRegion(r);if(i=="foldWidgets")return;var s=r.getDocumentPosition().row,o=t.session.selection;if(r.getShiftKey())o.selectTo(s,0);else{if(r.domEvent.detail==2)return t.selectAll(),r.preventDefault();e.$clickSelection=t.selection.getLineRange(s)}return e.setState("selectByLines"),e.captureMouse(r),r.preventDefault()});var o,u,f;e.editor.setDefaultHandler("guttermousemove",function(t){var n=t.domEvent.target||t.domEvent.srcElement;if(r.hasCssClass(n,"ace_fold-widget"))return c();f&&e.$tooltipFollowsMouse&&h(t),u=t;if(o)return;o=setTimeout(function(){o=null,u&&!e.isMousePressed?l():c()},50)}),s.addListener(t.renderer.$gutter,"mouseout",function(e){u=null;if(!f||o)return;o=setTimeout(function(){o=null,c()},50)}),t.on("changeSession",c)}function a(e){o.call(this,e)}var r=e("../lib/dom"),i=e("../lib/oop"),s=e("../lib/event"),o=e("../tooltip").Tooltip;i.inherits(a,o),function(){this.setPosition=function(e,t){var n=window.innerWidth||document.documentElement.clientWidth,r=window.innerHeight||document.documentElement.clientHeight,i=this.getWidth(),s=this.getHeight();e+=15,t+=15,e+i>n&&(e-=e+i-n),t+s>r&&(t-=20+s),o.prototype.setPosition.call(this,e,t)}}.call(a.prototype),t.GutterHandler=u}),define("ace/mouse/mouse_event",["require","exports","module","ace/lib/event","ace/lib/useragent"],function(e,t,n){"use strict";var r=e("../lib/event"),i=e("../lib/useragent"),s=t.MouseEvent=function(e,t){this.domEvent=e,this.editor=t,this.x=this.clientX=e.clientX,this.y=this.clientY=e.clientY,this.$pos=null,this.$inSelection=null,this.propagationStopped=!1,this.defaultPrevented=!1};(function(){this.stopPropagation=function(){r.stopPropagation(this.domEvent),this.propagationStopped=!0},this.preventDefault=function(){r.preventDefault(this.domEvent),this.defaultPrevented=!0},this.stop=function(){this.stopPropagation(),this.preventDefault()},this.getDocumentPosition=function(){return this.$pos?this.$pos:(this.$pos=this.editor.renderer.screenToTextCoordinates(this.clientX,this.clientY),this.$pos)},this.inSelection=function(){if(this.$inSelection!==null)return this.$inSelection;var e=this.editor,t=e.getSelectionRange();if(t.isEmpty())this.$inSelection=!1;else{var n=this.getDocumentPosition();this.$inSelection=t.contains(n.row,n.column)}return this.$inSelection},this.getButton=function(){return r.getButton(this.domEvent)},this.getShiftKey=function(){return this.domEvent.shiftKey},this.getAccelKey=i.isMac?function(){return this.domEvent.metaKey}:function(){return this.domEvent.ctrlKey}}).call(s.prototype)}),define("ace/mouse/dragdrop_handler",["require","exports","module","ace/lib/dom","ace/lib/event","ace/lib/useragent"],function(e,t,n){"use strict";function f(e){function T(e,n){var r=Date.now(),i=!n||e.row!=n.row,s=!n||e.column!=n.column;if(!S||i||s)t.moveCursorToPosition(e),S=r,x={x:p,y:d};else{var o=l(x.x,x.y,p,d);o>a?S=null:r-S>=u&&(t.renderer.scrollCursorIntoView(),S=null)}}function N(e,n){var r=Date.now(),i=t.renderer.layerConfig.lineHeight,s=t.renderer.layerConfig.characterWidth,u=t.renderer.scroller.getBoundingClientRect(),a={x:{left:p-u.left,right:u.right-p},y:{top:d-u.top,bottom:u.bottom-d}},f=Math.min(a.x.left,a.x.right),l=Math.min(a.y.top,a.y.bottom),c={row:e.row,column:e.column};f/s<=2&&(c.column+=a.x.left=o&&t.renderer.scrollCursorIntoView(c):E=r:E=null}function C(){var e=g;g=t.renderer.screenToTextCoordinates(p,d),T(g,e),N(g,e)}function k(){m=t.selection.toOrientedRange(),h=t.session.addMarker(m,"ace_selection",t.getSelectionStyle()),t.clearSelection(),t.isFocused()&&t.renderer.$cursorLayer.setBlinking(!1),clearInterval(v),C(),v=setInterval(C,20),y=0,i.addListener(document,"mousemove",O)}function L(){clearInterval(v),t.session.removeMarker(h),h=null,t.selection.fromOrientedRange(m),t.isFocused()&&!w&&t.$resetCursorStyle(),m=null,g=null,y=0,E=null,S=null,i.removeListener(document,"mousemove",O)}function O(){A==null&&(A=setTimeout(function(){A!=null&&h&&L()},20))}function M(e){var t=e.types;return!t||Array.prototype.some.call(t,function(e){return e=="text/plain"||e=="Text"})}function _(e){var t=["copy","copymove","all","uninitialized"],n=["move","copymove","linkmove","all","uninitialized"],r=s.isMac?e.altKey:e.ctrlKey,i="uninitialized";try{i=e.dataTransfer.effectAllowed.toLowerCase()}catch(e){}var o="none";return r&&t.indexOf(i)>=0?o="copy":n.indexOf(i)>=0?o="move":t.indexOf(i)>=0&&(o="copy"),o}var t=e.editor,n=r.createElement("img");n.src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==",s.isOpera&&(n.style.cssText="width:1px;height:1px;position:fixed;top:0;left:0;z-index:2147483647;opacity:0;");var f=["dragWait","dragWaitEnd","startDrag","dragReadyEnd","onMouseDrag"];f.forEach(function(t){e[t]=this[t]},this),t.addEventListener("mousedown",this.onMouseDown.bind(e));var c=t.container,h,p,d,v,m,g,y=0,b,w,E,S,x;this.onDragStart=function(e){if(this.cancelDrag||!c.draggable){var r=this;return setTimeout(function(){r.startSelect(),r.captureMouse(e)},0),e.preventDefault()}m=t.getSelectionRange();var i=e.dataTransfer;i.effectAllowed=t.getReadOnly()?"copy":"copyMove",s.isOpera&&(t.container.appendChild(n),n.scrollTop=0),i.setDragImage&&i.setDragImage(n,0,0),s.isOpera&&t.container.removeChild(n),i.clearData(),i.setData("Text",t.session.getTextRange()),w=!0,this.setState("drag")},this.onDragEnd=function(e){c.draggable=!1,w=!1,this.setState(null);if(!t.getReadOnly()){var n=e.dataTransfer.dropEffect;!b&&n=="move"&&t.session.remove(t.getSelectionRange()),t.$resetCursorStyle()}this.editor.unsetStyle("ace_dragging"),this.editor.renderer.setCursorStyle("")},this.onDragEnter=function(e){if(t.getReadOnly()||!M(e.dataTransfer))return;return p=e.clientX,d=e.clientY,h||k(),y++,e.dataTransfer.dropEffect=b=_(e),i.preventDefault(e)},this.onDragOver=function(e){if(t.getReadOnly()||!M(e.dataTransfer))return;return p=e.clientX,d=e.clientY,h||(k(),y++),A!==null&&(A=null),e.dataTransfer.dropEffect=b=_(e),i.preventDefault(e)},this.onDragLeave=function(e){y--;if(y<=0&&h)return L(),b=null,i.preventDefault(e)},this.onDrop=function(e){if(!g)return;var n=e.dataTransfer;if(w)switch(b){case"move":m.contains(g.row,g.column)?m={start:g,end:g}:m=t.moveText(m,g);break;case"copy":m=t.moveText(m,g,!0)}else{var r=n.getData("Text");m={start:g,end:t.session.insert(g,r)},t.focus(),b=null}return L(),i.preventDefault(e)},i.addListener(c,"dragstart",this.onDragStart.bind(e)),i.addListener(c,"dragend",this.onDragEnd.bind(e)),i.addListener(c,"dragenter",this.onDragEnter.bind(e)),i.addListener(c,"dragover",this.onDragOver.bind(e)),i.addListener(c,"dragleave",this.onDragLeave.bind(e)),i.addListener(c,"drop",this.onDrop.bind(e));var A=null}function l(e,t,n,r){return Math.sqrt(Math.pow(n-e,2)+Math.pow(r-t,2))}var r=e("../lib/dom"),i=e("../lib/event"),s=e("../lib/useragent"),o=200,u=200,a=5;(function(){this.dragWait=function(){var e=Date.now()-this.mousedownEvent.time;e>this.editor.getDragDelay()&&this.startDrag()},this.dragWaitEnd=function(){var e=this.editor.container;e.draggable=!1,this.startSelect(this.mousedownEvent.getDocumentPosition()),this.selectEnd()},this.dragReadyEnd=function(e){this.editor.$resetCursorStyle(),this.editor.unsetStyle("ace_dragging"),this.editor.renderer.setCursorStyle(""),this.dragWaitEnd()},this.startDrag=function(){this.cancelDrag=!1;var e=this.editor,t=e.container;t.draggable=!0,e.renderer.$cursorLayer.setBlinking(!1),e.setStyle("ace_dragging");var n=s.isWin?"default":"move";e.renderer.setCursorStyle(n),this.setState("dragReady")},this.onMouseDrag=function(e){var t=this.editor.container;if(s.isIE&&this.state=="dragReady"){var n=l(this.mousedownEvent.x,this.mousedownEvent.y,this.x,this.y);n>3&&t.dragDrop()}if(this.state==="dragWait"){var n=l(this.mousedownEvent.x,this.mousedownEvent.y,this.x,this.y);n>0&&(t.draggable=!1,this.startSelect(this.mousedownEvent.getDocumentPosition()))}},this.onMouseDown=function(e){if(!this.$dragEnabled)return;this.mousedownEvent=e;var t=this.editor,n=e.inSelection(),r=e.getButton(),i=e.domEvent.detail||1;if(i===1&&r===0&&n){if(e.editor.inMultiSelectMode&&(e.getAccelKey()||e.getShiftKey()))return;this.mousedownEvent.time=Date.now();var o=e.domEvent.target||e.domEvent.srcElement;"unselectable"in o&&(o.unselectable="on");if(t.getDragDelay()){if(s.isWebKit){this.cancelDrag=!0;var u=t.container;u.draggable=!0}this.setState("dragWait")}else this.startDrag();this.captureMouse(e,this.onMouseDrag.bind(this)),e.defaultPrevented=!0}}}).call(f.prototype),t.DragdropHandler=f}),define("ace/mouse/touch_handler",["require","exports","module","ace/mouse/mouse_event","ace/lib/event","ace/lib/dom"],function(e,t,n){"use strict";var r=e("./mouse_event").MouseEvent,i=e("../lib/event"),s=e("../lib/dom");t.addTouchListeners=function(e,t){function b(){var e=window.navigator&&window.navigator.clipboard,r=!1,i=function(){var n=t.getCopyText(),i=t.session.getUndoManager().hasUndo();y.replaceChild(s.buildDom(r?["span",!n&&["span",{"class":"ace_mobile-button",action:"selectall"},"Select All"],n&&["span",{"class":"ace_mobile-button",action:"copy"},"Copy"],n&&["span",{"class":"ace_mobile-button",action:"cut"},"Cut"],e&&["span",{"class":"ace_mobile-button",action:"paste"},"Paste"],i&&["span",{"class":"ace_mobile-button",action:"undo"},"Undo"],["span",{"class":"ace_mobile-button",action:"find"},"Find"],["span",{"class":"ace_mobile-button",action:"openCommandPallete"},"Pallete"]]:["span"]),y.firstChild)},o=function(n){var s=n.target.getAttribute("action");if(s=="more"||!r)return r=!r,i();if(s=="paste")e.readText().then(function(e){t.execCommand(s,e)});else if(s){if(s=="cut"||s=="copy")e?e.writeText(t.getCopyText()):document.execCommand("copy");t.execCommand(s)}y.firstChild.style.display="none",r=!1,s!="openCommandPallete"&&t.focus()};y=s.buildDom(["div",{"class":"ace_mobile-menu",ontouchstart:function(e){n="menu",e.stopPropagation(),e.preventDefault(),t.textInput.focus()},ontouchend:function(e){e.stopPropagation(),e.preventDefault(),o(e)},onclick:o},["span"],["span",{"class":"ace_mobile-button",action:"more"},"..."]],t.container)}function w(){y||b();var e=t.selection.cursor,n=t.renderer.textToScreenCoordinates(e.row,e.column),r=t.container.getBoundingClientRect();y.style.top=n.pageY-r.top-3+"px",y.style.right="10px",y.style.display="",y.firstChild.style.display="none",t.on("input",E)}function E(e){y&&(y.style.display="none"),t.off("input",E)}function S(){l=null,clearTimeout(l);var e=t.selection.getRange(),r=e.contains(p.row,p.column);if(e.isEmpty()||!r)t.selection.moveToPosition(p),t.selection.selectWord();n="wait",w()}function x(){l=null,clearTimeout(l),t.selection.moveToPosition(p);var e=d>=2?t.selection.getLineRange(p.row):t.session.getBracketRange(p);e&&!e.isEmpty()?t.selection.setRange(e):t.selection.selectWord(),n="wait"}function T(){h+=60,c=setInterval(function(){h--<=0&&(clearInterval(c),c=null),Math.abs(v)<.01&&(v=0),Math.abs(m)<.01&&(m=0),h<20&&(v=.9*v),h<20&&(m=.9*m);var e=t.session.getScrollTop();t.renderer.scrollBy(10*v,10*m),e==t.session.getScrollTop()&&(h=0)},10)}var n="scroll",o,u,a,f,l,c,h=0,p,d=0,v=0,m=0,g,y;i.addListener(e,"contextmenu",function(e){if(!g)return;var n=t.textInput.getElement();n.focus()}),i.addListener(e,"touchstart",function(e){var i=e.touches;if(l||i.length>1){clearTimeout(l),l=null,a=-1,n="zoom";return}g=t.$mouseHandler.isMousePressed=!0;var s=t.renderer.layerConfig.lineHeight,c=t.renderer.layerConfig.lineHeight,y=e.timeStamp;f=y;var b=i[0],w=b.clientX,E=b.clientY;Math.abs(o-w)+Math.abs(u-E)>s&&(a=-1),o=e.clientX=w,u=e.clientY=E,v=m=0;var T=new r(e,t);p=T.getDocumentPosition();if(y-a<500&&i.length==1&&!h)d++,e.preventDefault(),e.button=0,x();else{d=0;var N=t.selection.cursor,C=t.selection.isEmpty()?N:t.selection.anchor,k=t.renderer.$cursorLayer.getPixelPosition(N,!0),L=t.renderer.$cursorLayer.getPixelPosition(C,!0),A=t.renderer.scroller.getBoundingClientRect(),O=function(e,t){return e/=c,t=t/s-.75,e*e+t*t};if(e.clientX_?"cursor":"anchor"),_<3.5?n="anchor":M<3.5?n="cursor":n="scroll",l=setTimeout(S,450)}a=y}),i.addListener(e,"touchend",function(e){g=t.$mouseHandler.isMousePressed=!1,c&&clearInterval(c),n=="zoom"?(n="",h=0):l?(t.selection.moveToPosition(p),h=0,w()):n=="scroll"?(T(),e.preventDefault(),E()):w(),clearTimeout(l),l=null}),i.addListener(e,"touchmove",function(e){l&&(clearTimeout(l),l=null);var i=e.touches;if(i.length>1||n=="zoom")return;var s=i[0],a=o-s.clientX,c=u-s.clientY;if(n=="wait"){if(!(a*a+c*c>4))return e.preventDefault();n="cursor"}o=s.clientX,u=s.clientY,e.clientX=s.clientX,e.clientY=s.clientY;var h=e.timeStamp,p=h-f;f=h;if(n=="scroll"){var d=new r(e,t);d.speed=1,d.wheelX=a,d.wheelY=c,10*Math.abs(a)1&&(i=n[n.length-2]);var o=a[t+"Path"];return o==null?o=a.basePath:r=="/"&&(t=r=""),o&&o.slice(-1)!="/"&&(o+="/"),o+t+r+i+this.get("suffix")},t.setModuleUrl=function(e,t){return a.$moduleUrls[e]=t},t.$loading={},t.loadModule=function(n,r){var i,o;Array.isArray(n)&&(o=n[0],n=n[1]);try{i=e(n)}catch(u){}if(i&&!t.$loading[n])return r&&r(i);t.$loading[n]||(t.$loading[n]=[]),t.$loading[n].push(r);if(t.$loading[n].length>1)return;var a=function(){e([n],function(e){t._emit("load.module",{name:n,module:e});var r=t.$loading[n];t.$loading[n]=null,r.forEach(function(t){t&&t(e)})})};if(!t.get("packaged"))return a();s.loadScript(t.moduleUrl(n,o),a),f()};var f=function(){!a.basePath&&!a.workerPath&&!a.modePath&&!a.themePath&&!Object.keys(a.$moduleUrls).length&&(console.error("Unable to infer path to ace from script src,","use ace.config.set('basePath', 'path') to enable dynamic loading of modes and themes","or with webpack use ace/webpack-resolver"),f=function(){})};t.init=l,t.version="1.4.8"}),define("ace/mouse/mouse_handler",["require","exports","module","ace/lib/event","ace/lib/useragent","ace/mouse/default_handlers","ace/mouse/default_gutter_handler","ace/mouse/mouse_event","ace/mouse/dragdrop_handler","ace/mouse/touch_handler","ace/config"],function(e,t,n){"use strict";var r=e("../lib/event"),i=e("../lib/useragent"),s=e("./default_handlers").DefaultHandlers,o=e("./default_gutter_handler").GutterHandler,u=e("./mouse_event").MouseEvent,a=e("./dragdrop_handler").DragdropHandler,f=e("./touch_handler").addTouchListeners,l=e("../config"),c=function(e){var t=this;this.editor=e,new s(this),new o(this),new a(this);var n=function(t){var n=!document.hasFocus||!document.hasFocus()||!e.isFocused()&&document.activeElement==(e.textInput&&e.textInput.getElement());n&&window.focus(),e.focus()},u=e.renderer.getMouseEventTarget();r.addListener(u,"click",this.onMouseEvent.bind(this,"click")),r.addListener(u,"mousemove",this.onMouseMove.bind(this,"mousemove")),r.addMultiMouseDownListener([u,e.renderer.scrollBarV&&e.renderer.scrollBarV.inner,e.renderer.scrollBarH&&e.renderer.scrollBarH.inner,e.textInput&&e.textInput.getElement()].filter(Boolean),[400,300,250],this,"onMouseEvent"),r.addMouseWheelListener(e.container,this.onMouseWheel.bind(this,"mousewheel")),f(e.container,e);var l=e.renderer.$gutter;r.addListener(l,"mousedown",this.onMouseEvent.bind(this,"guttermousedown")),r.addListener(l,"click",this.onMouseEvent.bind(this,"gutterclick")),r.addListener(l,"dblclick",this.onMouseEvent.bind(this,"gutterdblclick")),r.addListener(l,"mousemove",this.onMouseEvent.bind(this,"guttermousemove")),r.addListener(u,"mousedown",n),r.addListener(l,"mousedown",n),i.isIE&&e.renderer.scrollBarV&&(r.addListener(e.renderer.scrollBarV.element,"mousedown",n),r.addListener(e.renderer.scrollBarH.element,"mousedown",n)),e.on("mousemove",function(n){if(t.state||t.$dragDelay||!t.$dragEnabled)return;var r=e.renderer.screenToTextCoordinates(n.x,n.y),i=e.session.selection.getRange(),s=e.renderer;!i.isEmpty()&&i.insideStart(r.row,r.column)?s.setCursorStyle("default"):s.setCursorStyle("")})};(function(){this.onMouseEvent=function(e,t){this.editor._emit(e,new u(t,this.editor))},this.onMouseMove=function(e,t){var n=this.editor._eventRegistry&&this.editor._eventRegistry.mousemove;if(!n||!n.length)return;this.editor._emit(e,new u(t,this.editor))},this.onMouseWheel=function(e,t){var n=new u(t,this.editor);n.speed=this.$scrollSpeed*2,n.wheelX=t.wheelX,n.wheelY=t.wheelY,this.editor._emit(e,n)},this.setState=function(e){this.state=e},this.captureMouse=function(e,t){this.x=e.x,this.y=e.y,this.isMousePressed=!0;var n=this.editor,s=this.editor.renderer;s.$isMousePressed=!0;var o=this,a=function(e){if(!e)return;if(i.isWebKit&&!e.which&&o.releaseMouse)return o.releaseMouse();o.x=e.clientX,o.y=e.clientY,t&&t(e),o.mouseEvent=new u(e,o.editor),o.$mouseMoved=!0},f=function(e){n.off("beforeEndOperation",c),clearInterval(h),l(),o[o.state+"End"]&&o[o.state+"End"](e),o.state="",o.isMousePressed=s.$isMousePressed=!1,s.$keepTextAreaAtCursor&&s.$moveTextAreaToCursor(),o.$onCaptureMouseMove=o.releaseMouse=null,e&&o.onMouseEvent("mouseup",e),n.endOperation()},l=function(){o[o.state]&&o[o.state](),o.$mouseMoved=!1};if(i.isOldIE&&e.domEvent.type=="dblclick")return setTimeout(function(){f(e)});var c=function(e){if(!o.releaseMouse)return;n.curOp.command.name&&n.curOp.selectionChanged&&(o[o.state+"End"]&&o[o.state+"End"](),o.state="",o.releaseMouse())};n.on("beforeEndOperation",c),n.startOperation({command:{name:"mouse"}}),o.$onCaptureMouseMove=a,o.releaseMouse=r.capture(this.editor.container,a,f);var h=setInterval(l,20)},this.releaseMouse=null,this.cancelContextMenu=function(){var e=function(t){if(t&&t.domEvent&&t.domEvent.type!="contextmenu")return;this.editor.off("nativecontextmenu",e),t&&t.domEvent&&r.stopEvent(t.domEvent)}.bind(this);setTimeout(e,10),this.editor.on("nativecontextmenu",e)}}).call(c.prototype),l.defineOptions(c.prototype,"mouseHandler",{scrollSpeed:{initialValue:2},dragDelay:{initialValue:i.isMac?150:0},dragEnabled:{initialValue:!0},focusTimeout:{initialValue:0},tooltipFollowsMouse:{initialValue:!0}}),t.MouseHandler=c}),define("ace/mouse/fold_handler",["require","exports","module","ace/lib/dom"],function(e,t,n){"use strict";function i(e){e.on("click",function(t){var n=t.getDocumentPosition(),i=e.session,s=i.getFoldAt(n.row,n.column,1);s&&(t.getAccelKey()?i.removeFold(s):i.expandFold(s),t.stop());var o=t.domEvent&&t.domEvent.target;o&&r.hasCssClass(o,"ace_inline_button")&&r.hasCssClass(o,"ace_toggle_wrap")&&(i.setOption("wrap",!i.getUseWrapMode()),e.renderer.scrollCursorIntoView())}),e.on("gutterclick",function(t){var n=e.renderer.$gutterLayer.getRegion(t);if(n=="foldWidgets"){var r=t.getDocumentPosition().row,i=e.session;i.foldWidgets&&i.foldWidgets[r]&&e.session.onFoldWidgetClick(r,t),e.isFocused()||e.focus(),t.stop()}}),e.on("gutterdblclick",function(t){var n=e.renderer.$gutterLayer.getRegion(t);if(n=="foldWidgets"){var r=t.getDocumentPosition().row,i=e.session,s=i.getParentFoldRangeData(r,!0),o=s.range||s.firstRange;if(o){r=o.start.row;var u=i.getFoldAt(r,i.getLine(r).length,1);u?i.removeFold(u):(i.addFold("...",o),e.renderer.scrollCursorIntoView({row:o.start.row,column:0}))}t.stop()}})}var r=e("../lib/dom");t.FoldHandler=i}),define("ace/keyboard/keybinding",["require","exports","module","ace/lib/keys","ace/lib/event"],function(e,t,n){"use strict";var r=e("../lib/keys"),i=e("../lib/event"),s=function(e){this.$editor=e,this.$data={editor:e},this.$handlers=[],this.setDefaultHandler(e.commands)};(function(){this.setDefaultHandler=function(e){this.removeKeyboardHandler(this.$defaultHandler),this.$defaultHandler=e,this.addKeyboardHandler(e,0)},this.setKeyboardHandler=function(e){var t=this.$handlers;if(t[t.length-1]==e)return;while(t[t.length-1]&&t[t.length-1]!=this.$defaultHandler)this.removeKeyboardHandler(t[t.length-1]);this.addKeyboardHandler(e,1)},this.addKeyboardHandler=function(e,t){if(!e)return;typeof e=="function"&&!e.handleKeyboard&&(e.handleKeyboard=e);var n=this.$handlers.indexOf(e);n!=-1&&this.$handlers.splice(n,1),t==undefined?this.$handlers.push(e):this.$handlers.splice(t,0,e),n==-1&&e.attach&&e.attach(this.$editor)},this.removeKeyboardHandler=function(e){var t=this.$handlers.indexOf(e);return t==-1?!1:(this.$handlers.splice(t,1),e.detach&&e.detach(this.$editor),!0)},this.getKeyboardHandler=function(){return this.$handlers[this.$handlers.length-1]},this.getStatusText=function(){var e=this.$data,t=e.editor;return this.$handlers.map(function(n){return n.getStatusText&&n.getStatusText(t,e)||""}).filter(Boolean).join(" ")},this.$callKeyboardHandlers=function(e,t,n,r){var s,o=!1,u=this.$editor.commands;for(var a=this.$handlers.length;a--;){s=this.$handlers[a].handleKeyboard(this.$data,e,t,n,r);if(!s||!s.command)continue;s.command=="null"?o=!0:o=u.exec(s.command,this.$editor,s.args,r),o&&r&&e!=-1&&s.passEvent!=1&&s.command.passEvent!=1&&i.stopEvent(r);if(o)break}return!o&&e==-1&&(s={command:"insertstring"},o=u.exec("insertstring",this.$editor,t)),o&&this.$editor._signal&&this.$editor._signal("keyboardActivity",s),o},this.onCommandKey=function(e,t,n){var i=r.keyCodeToString(n);return this.$callKeyboardHandlers(t,i,n,e)},this.onTextInput=function(e){return this.$callKeyboardHandlers(-1,e)}}).call(s.prototype),t.KeyBinding=s}),define("ace/lib/bidiutil",["require","exports","module"],function(e,t,n){"use strict";function F(e,t,n,r){var i=s?d:p,c=null,h=null,v=null,m=0,g=null,y=null,b=-1,w=null,E=null,T=[];if(!r)for(w=0,r=[];w0)if(g==16){for(w=b;w-1){for(w=b;w=0;C--){if(r[C]!=N)break;t[C]=s}}}function I(e,t,n){if(o=e){u=i+1;while(u=e)u++;for(a=i,l=u-1;a=t.length||(o=n[r-1])!=b&&o!=w||(c=t[r+1])!=b&&c!=w)return E;return u&&(c=w),c==o?c:E;case k:o=r>0?n[r-1]:S;if(o==b&&r+10&&n[r-1]==b)return b;if(u)return E;p=r+1,h=t.length;while(p=1425&&d<=2303||d==64286;o=t[p];if(v&&(o==y||o==T))return y}if(r<1||(o=t[r-1])==S)return E;return n[r-1];case S:return u=!1,f=!0,s;case x:return l=!0,E;case O:case M:case D:case P:case _:u=!1;case H:return E}}function R(e){var t=e.charCodeAt(0),n=t>>8;return n==0?t>191?g:B[t]:n==5?/[\u0591-\u05f4]/.test(e)?y:g:n==6?/[\u0610-\u061a\u064b-\u065f\u06d6-\u06e4\u06e7-\u06ed]/.test(e)?A:/[\u0660-\u0669\u066b-\u066c]/.test(e)?w:t==1642?L:/[\u06f0-\u06f9]/.test(e)?b:T:n==32&&t<=8287?j[t&255]:n==254?t>=65136?T:E:E}function U(e){return e>="\u064b"&&e<="\u0655"}var r=["\u0621","\u0641"],i=["\u063a","\u064a"],s=0,o=0,u=!1,a=!1,f=!1,l=!1,c=!1,h=!1,p=[[0,3,0,1,0,0,0],[0,3,0,1,2,2,0],[0,3,0,17,2,0,1],[0,3,5,5,4,1,0],[0,3,21,21,4,0,1],[0,3,5,5,4,2,0]],d=[[2,0,1,1,0,1,0],[2,0,1,1,0,2,0],[2,0,2,1,3,2,0],[2,0,2,33,3,1,1]],v=0,m=1,g=0,y=1,b=2,w=3,E=4,S=5,x=6,T=7,N=8,C=9,k=10,L=11,A=12,O=13,M=14,_=15,D=16,P=17,H=18,B=[H,H,H,H,H,H,H,H,H,x,S,x,N,S,H,H,H,H,H,H,H,H,H,H,H,H,H,H,S,S,S,x,N,E,E,L,L,L,E,E,E,E,E,k,C,k,C,C,b,b,b,b,b,b,b,b,b,b,C,E,E,E,E,E,E,g,g,g,g,g,g,g,g,g,g,g,g,g,g,g,g,g,g,g,g,g,g,g,g,g,g,E,E,E,E,E,E,g,g,g,g,g,g,g,g,g,g,g,g,g,g,g,g,g,g,g,g,g,g,g,g,g,g,E,E,E,E,H,H,H,H,H,H,S,H,H,H,H,H,H,H,H,H,H,H,H,H,H,H,H,H,H,H,H,H,H,H,H,H,H,C,E,L,L,L,L,E,E,E,E,g,E,E,H,E,E,L,L,b,b,E,g,E,E,E,b,g,E,E,E,E,E],j=[N,N,N,N,N,N,N,N,N,N,N,H,H,H,g,y,E,E,E,E,E,E,E,E,E,E,E,E,E,E,E,E,E,E,E,E,E,E,E,E,N,S,O,M,_,D,P,C,L,L,L,L,L,E,E,E,E,E,E,E,E,E,E,E,E,E,E,E,C,E,E,E,E,E,E,E,E,E,E,E,E,E,E,E,E,E,E,E,E,E,E,E,E,E,E,N];t.L=g,t.R=y,t.EN=b,t.ON_R=3,t.AN=4,t.R_H=5,t.B=6,t.RLE=7,t.DOT="\u00b7",t.doBidiReorder=function(e,n,r){if(e.length<2)return{};var i=e.split(""),o=new Array(i.length),u=new Array(i.length),a=[];s=r?m:v,F(i,a,i.length,n);for(var f=0;fT&&n[f]0&&i[f-1]==="\u0644"&&/\u0622|\u0623|\u0625|\u0627/.test(i[f])&&(a[f-1]=a[f]=t.R_H,f++);i[i.length-1]===t.DOT&&(a[i.length-1]=t.B),i[0]==="\u202b"&&(a[0]=t.RLE);for(var f=0;f=0&&(e=this.session.$docRowCache[n])}return e},this.getSplitIndex=function(){var e=0,t=this.session.$screenRowCache;if(t.length){var n,r=this.session.$getRowCacheIndex(t,this.currentRow);while(this.currentRow-e>0){n=this.session.$getRowCacheIndex(t,this.currentRow-e-1);if(n!==r)break;r=n,e++}}else e=this.currentRow;return e},this.updateRowLine=function(e,t){e===undefined&&(e=this.getDocumentRow());var n=e===this.session.getLength()-1,s=n?this.EOF:this.EOL;this.wrapIndent=0,this.line=this.session.getLine(e),this.isRtlDir=this.$isRtl||this.line.charAt(0)===this.RLE;if(this.session.$useWrapMode){var o=this.session.$wrapData[e];o&&(t===undefined&&(t=this.getSplitIndex()),t>0&&o.length?(this.wrapIndent=o.indent,this.wrapOffset=this.wrapIndent*this.charWidths[r.L],this.line=tt?this.session.getOverwrite()?e:e-1:t,i=r.getVisualFromLogicalIdx(n,this.bidiMap),s=this.bidiMap.bidiLevels,o=0;!this.session.getOverwrite()&&e<=t&&s[i]%2!==0&&i++;for(var u=0;ut&&s[i]%2===0&&(o+=this.charWidths[s[i]]),this.wrapIndent&&(o+=this.isRtlDir?-1*this.wrapOffset:this.wrapOffset),this.isRtlDir&&(o+=this.rtlLineOffset),o},this.getSelections=function(e,t){var n=this.bidiMap,r=n.bidiLevels,i,s=[],o=0,u=Math.min(e,t)-this.wrapIndent,a=Math.max(e,t)-this.wrapIndent,f=!1,l=!1,c=0;this.wrapIndent&&(o+=this.isRtlDir?-1*this.wrapOffset:this.wrapOffset);for(var h,p=0;p=u&&hn+s/2){n+=s;if(r===i.length-1){s=0;break}s=this.charWidths[i[++r]]}return r>0&&i[r-1]%2!==0&&i[r]%2===0?(e0&&i[r-1]%2===0&&i[r]%2!==0?t=1+(e>n?this.bidiMap.logicalFromVisual[r]:this.bidiMap.logicalFromVisual[r-1]):this.isRtlDir&&r===i.length-1&&s===0&&i[r-1]%2===0||!this.isRtlDir&&r===0&&i[r]%2!==0?t=1+this.bidiMap.logicalFromVisual[r]:(r>0&&i[r-1]%2!==0&&s!==0&&r--,t=this.bidiMap.logicalFromVisual[r]),t===0&&this.isRtlDir&&t++,t+this.wrapIndent}}).call(o.prototype),t.BidiHandler=o}),define("ace/selection",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/lib/event_emitter","ace/range"],function(e,t,n){"use strict";var r=e("./lib/oop"),i=e("./lib/lang"),s=e("./lib/event_emitter").EventEmitter,o=e("./range").Range,u=function(e){this.session=e,this.doc=e.getDocument(),this.clearSelection(),this.cursor=this.lead=this.doc.createAnchor(0,0),this.anchor=this.doc.createAnchor(0,0),this.$silent=!1;var t=this;this.cursor.on("change",function(e){t.$cursorChanged=!0,t.$silent||t._emit("changeCursor"),!t.$isEmpty&&!t.$silent&&t._emit("changeSelection"),!t.$keepDesiredColumnOnChange&&e.old.column!=e.value.column&&(t.$desiredColumn=null)}),this.anchor.on("change",function(){t.$anchorChanged=!0,!t.$isEmpty&&!t.$silent&&t._emit("changeSelection")})};(function(){r.implement(this,s),this.isEmpty=function(){return this.$isEmpty||this.anchor.row==this.lead.row&&this.anchor.column==this.lead.column},this.isMultiLine=function(){return!this.$isEmpty&&this.anchor.row!=this.cursor.row},this.getCursor=function(){return this.lead.getPosition()},this.setSelectionAnchor=function(e,t){this.$isEmpty=!1,this.anchor.setPosition(e,t)},this.getAnchor=this.getSelectionAnchor=function(){return this.$isEmpty?this.getSelectionLead():this.anchor.getPosition()},this.getSelectionLead=function(){return this.lead.getPosition()},this.isBackwards=function(){var e=this.anchor,t=this.lead;return e.row>t.row||e.row==t.row&&e.column>t.column},this.getRange=function(){var e=this.anchor,t=this.lead;return this.$isEmpty?o.fromPoints(t,t):this.isBackwards()?o.fromPoints(t,e):o.fromPoints(e,t)},this.clearSelection=function(){this.$isEmpty||(this.$isEmpty=!0,this._emit("changeSelection"))},this.selectAll=function(){this.$setSelection(0,0,Number.MAX_VALUE,Number.MAX_VALUE)},this.setRange=this.setSelectionRange=function(e,t){var n=t?e.end:e.start,r=t?e.start:e.end;this.$setSelection(n.row,n.column,r.row,r.column)},this.$setSelection=function(e,t,n,r){if(this.$silent)return;var i=this.$isEmpty,s=this.inMultiSelectMode;this.$silent=!0,this.$cursorChanged=this.$anchorChanged=!1,this.anchor.setPosition(e,t),this.cursor.setPosition(n,r),this.$isEmpty=!o.comparePoints(this.anchor,this.cursor),this.$silent=!1,this.$cursorChanged&&this._emit("changeCursor"),(this.$cursorChanged||this.$anchorChanged||i!=this.$isEmpty||s)&&this._emit("changeSelection")},this.$moveSelection=function(e){var t=this.lead;this.$isEmpty&&this.setSelectionAnchor(t.row,t.column),e.call(this)},this.selectTo=function(e,t){this.$moveSelection(function(){this.moveCursorTo(e,t)})},this.selectToPosition=function(e){this.$moveSelection(function(){this.moveCursorToPosition(e)})},this.moveTo=function(e,t){this.clearSelection(),this.moveCursorTo(e,t)},this.moveToPosition=function(e){this.clearSelection(),this.moveCursorToPosition(e)},this.selectUp=function(){this.$moveSelection(this.moveCursorUp)},this.selectDown=function(){this.$moveSelection(this.moveCursorDown)},this.selectRight=function(){this.$moveSelection(this.moveCursorRight)},this.selectLeft=function(){this.$moveSelection(this.moveCursorLeft)},this.selectLineStart=function(){this.$moveSelection(this.moveCursorLineStart)},this.selectLineEnd=function(){this.$moveSelection(this.moveCursorLineEnd)},this.selectFileEnd=function(){this.$moveSelection(this.moveCursorFileEnd)},this.selectFileStart=function(){this.$moveSelection(this.moveCursorFileStart)},this.selectWordRight=function(){this.$moveSelection(this.moveCursorWordRight)},this.selectWordLeft=function(){this.$moveSelection(this.moveCursorWordLeft)},this.getWordRange=function(e,t){if(typeof t=="undefined"){var n=e||this.lead;e=n.row,t=n.column}return this.session.getWordRange(e,t)},this.selectWord=function(){this.setSelectionRange(this.getWordRange())},this.selectAWord=function(){var e=this.getCursor(),t=this.session.getAWordRange(e.row,e.column);this.setSelectionRange(t)},this.getLineRange=function(e,t){var n=typeof e=="number"?e:this.lead.row,r,i=this.session.getFoldLine(n);return i?(n=i.start.row,r=i.end.row):r=n,t===!0?new o(n,0,r,this.session.getLine(r).length):new o(n,0,r+1,0)},this.selectLine=function(){this.setSelectionRange(this.getLineRange())},this.moveCursorUp=function(){this.moveCursorBy(-1,0)},this.moveCursorDown=function(){this.moveCursorBy(1,0)},this.wouldMoveIntoSoftTab=function(e,t,n){var r=e.column,i=e.column+t;return n<0&&(r=e.column-t,i=e.column),this.session.isTabStop(e)&&this.doc.getLine(e.row).slice(r,i).split(" ").length-1==t},this.moveCursorLeft=function(){var e=this.lead.getPosition(),t;if(t=this.session.getFoldAt(e.row,e.column,-1))this.moveCursorTo(t.start.row,t.start.column);else if(e.column===0)e.row>0&&this.moveCursorTo(e.row-1,this.doc.getLine(e.row-1).length);else{var n=this.session.getTabSize();this.wouldMoveIntoSoftTab(e,n,-1)&&!this.session.getNavigateWithinSoftTabs()?this.moveCursorBy(0,-n):this.moveCursorBy(0,-1)}},this.moveCursorRight=function(){var e=this.lead.getPosition(),t;if(t=this.session.getFoldAt(e.row,e.column,1))this.moveCursorTo(t.end.row,t.end.column);else if(this.lead.column==this.doc.getLine(this.lead.row).length)this.lead.row0&&(t.column=r)}}this.moveCursorTo(t.row,t.column)},this.moveCursorFileEnd=function(){var e=this.doc.getLength()-1,t=this.doc.getLine(e).length;this.moveCursorTo(e,t)},this.moveCursorFileStart=function(){this.moveCursorTo(0,0)},this.moveCursorLongWordRight=function(){var e=this.lead.row,t=this.lead.column,n=this.doc.getLine(e),r=n.substring(t);this.session.nonTokenRe.lastIndex=0,this.session.tokenRe.lastIndex=0;var i=this.session.getFoldAt(e,t,1);if(i){this.moveCursorTo(i.end.row,i.end.column);return}this.session.nonTokenRe.exec(r)&&(t+=this.session.nonTokenRe.lastIndex,this.session.nonTokenRe.lastIndex=0,r=n.substring(t));if(t>=n.length){this.moveCursorTo(e,n.length),this.moveCursorRight(),e0&&this.moveCursorWordLeft();return}this.session.tokenRe.exec(s)&&(t-=this.session.tokenRe.lastIndex,this.session.tokenRe.lastIndex=0),this.moveCursorTo(e,t)},this.$shortWordEndIndex=function(e){var t=0,n,r=/\s/,i=this.session.tokenRe;i.lastIndex=0;if(this.session.tokenRe.exec(e))t=this.session.tokenRe.lastIndex;else{while((n=e[t])&&r.test(n))t++;if(t<1){i.lastIndex=0;while((n=e[t])&&!i.test(n)){i.lastIndex=0,t++;if(r.test(n)){if(t>2){t--;break}while((n=e[t])&&r.test(n))t++;if(t>2)break}}}}return i.lastIndex=0,t},this.moveCursorShortWordRight=function(){var e=this.lead.row,t=this.lead.column,n=this.doc.getLine(e),r=n.substring(t),i=this.session.getFoldAt(e,t,1);if(i)return this.moveCursorTo(i.end.row,i.end.column);if(t==n.length){var s=this.doc.getLength();do e++,r=this.doc.getLine(e);while(e0&&/^\s*$/.test(r));t=r.length,/\s+$/.test(r)||(r="")}var s=i.stringReverse(r),o=this.$shortWordEndIndex(s);return this.moveCursorTo(e,t-o)},this.moveCursorWordRight=function(){this.session.$selectLongWords?this.moveCursorLongWordRight():this.moveCursorShortWordRight()},this.moveCursorWordLeft=function(){this.session.$selectLongWords?this.moveCursorLongWordLeft():this.moveCursorShortWordLeft()},this.moveCursorBy=function(e,t){var n=this.session.documentToScreenPosition(this.lead.row,this.lead.column),r;t===0&&(e!==0&&(this.session.$bidiHandler.isBidiRow(n.row,this.lead.row)?(r=this.session.$bidiHandler.getPosLeft(n.column),n.column=Math.round(r/this.session.$bidiHandler.charWidths[0])):r=n.column*this.session.$bidiHandler.charWidths[0]),this.$desiredColumn?n.column=this.$desiredColumn:this.$desiredColumn=n.column);if(e!=0&&this.session.lineWidgets&&this.session.lineWidgets[this.lead.row]){var i=this.session.lineWidgets[this.lead.row];e<0?e-=i.rowsAbove||0:e>0&&(e+=i.rowCount-(i.rowsAbove||0))}var s=this.session.screenToDocumentPosition(n.row+e,n.column,r);e!==0&&t===0&&s.row===this.lead.row&&s.column===this.lead.column,this.moveCursorTo(s.row,s.column+t,t===0)},this.moveCursorToPosition=function(e){this.moveCursorTo(e.row,e.column)},this.moveCursorTo=function(e,t,n){var r=this.session.getFoldAt(e,t,1);r&&(e=r.start.row,t=r.start.column),this.$keepDesiredColumnOnChange=!0;var i=this.session.getLine(e);/[\uDC00-\uDFFF]/.test(i.charAt(t))&&i.charAt(t-1)&&(this.lead.row==e&&this.lead.column==t+1?t-=1:t+=1),this.lead.setPosition(e,t),this.$keepDesiredColumnOnChange=!1,n||(this.$desiredColumn=null)},this.moveCursorToScreen=function(e,t,n){var r=this.session.screenToDocumentPosition(e,t);this.moveCursorTo(r.row,r.column,n)},this.detach=function(){this.lead.detach(),this.anchor.detach(),this.session=this.doc=null},this.fromOrientedRange=function(e){this.setSelectionRange(e,e.cursor==e.start),this.$desiredColumn=e.desiredColumn||this.$desiredColumn},this.toOrientedRange=function(e){var t=this.getRange();return e?(e.start.column=t.start.column,e.start.row=t.start.row,e.end.column=t.end.column,e.end.row=t.end.row):e=t,e.cursor=this.isBackwards()?e.start:e.end,e.desiredColumn=this.$desiredColumn,e},this.getRangeOfMovements=function(e){var t=this.getCursor();try{e(this);var n=this.getCursor();return o.fromPoints(t,n)}catch(r){return o.fromPoints(t,t)}finally{this.moveCursorToPosition(t)}},this.toJSON=function(){if(this.rangeCount)var e=this.ranges.map(function(e){var t=e.clone();return t.isBackwards=e.cursor==e.start,t});else{var e=this.getRange();e.isBackwards=this.isBackwards()}return e},this.fromJSON=function(e){if(e.start==undefined){if(this.rangeList&&e.length>1){this.toSingleRange(e[0]);for(var t=e.length;t--;){var n=o.fromPoints(e[t].start,e[t].end);e[t].isBackwards&&(n.cursor=n.start),this.addRange(n,!0)}return}e=e[0]}this.rangeList&&this.toSingleRange(e),this.setSelectionRange(e,e.isBackwards)},this.isEqual=function(e){if((e.length||this.rangeCount)&&e.length!=this.rangeCount)return!1;if(!e.length||!this.ranges)return this.getRange().isEqual(e);for(var t=this.ranges.length;t--;)if(!this.ranges[t].isEqual(e[t]))return!1;return!0}}).call(u.prototype),t.Selection=u}),define("ace/tokenizer",["require","exports","module","ace/config"],function(e,t,n){"use strict";var r=e("./config"),i=2e3,s=function(e){this.states=e,this.regExps={},this.matchMappings={};for(var t in this.states){var n=this.states[t],r=[],i=0,s=this.matchMappings[t]={defaultToken:"text"},o="g",u=[];for(var a=0;a1?f.onMatch=this.$applyToken:f.onMatch=f.token),c>1&&(/\\\d/.test(f.regex)?l=f.regex.replace(/\\([0-9]+)/g,function(e,t){return"\\"+(parseInt(t,10)+i+1)}):(c=1,l=this.removeCapturingGroups(f.regex)),!f.splitRegex&&typeof f.token!="string"&&u.push(f)),s[i]=a,i+=c,r.push(l),f.onMatch||(f.onMatch=null)}r.length||(s[0]=0,r.push("$")),u.forEach(function(e){e.splitRegex=this.createSplitterRegexp(e.regex,o)},this),this.regExps[t]=new RegExp("("+r.join(")|(")+")|($)",o)}};(function(){this.$setMaxTokenCount=function(e){i=e|0},this.$applyToken=function(e){var t=this.splitRegex.exec(e).slice(1),n=this.token.apply(this,t);if(typeof n=="string")return[{type:n,value:e}];var r=[];for(var i=0,s=n.length;il){var g=e.substring(l,m-v.length);h.type==p?h.value+=g:(h.type&&f.push(h),h={type:p,value:g})}for(var y=0;yi){c>2*e.length&&this.reportError("infinite loop with in ace tokenizer",{startState:t,line:e});while(l1&&n[0]!==r&&n.unshift("#tmp",r),{tokens:f,state:n.length?n:r}},this.reportError=r.reportError}).call(s.prototype),t.Tokenizer=s}),define("ace/mode/text_highlight_rules",["require","exports","module","ace/lib/lang"],function(e,t,n){"use strict";var r=e("../lib/lang"),i=function(){this.$rules={start:[{token:"empty_line",regex:"^$"},{defaultToken:"text"}]}};(function(){this.addRules=function(e,t){if(!t){for(var n in e)this.$rules[n]=e[n];return}for(var n in e){var r=e[n];for(var i=0;i=this.$rowTokens.length){this.$row+=1,e||(e=this.$session.getLength());if(this.$row>=e)return this.$row=e-1,null;this.$rowTokens=this.$session.getTokens(this.$row),this.$tokenIndex=0}return this.$rowTokens[this.$tokenIndex]},this.getCurrentToken=function(){return this.$rowTokens[this.$tokenIndex]},this.getCurrentTokenRow=function(){return this.$row},this.getCurrentTokenColumn=function(){var e=this.$rowTokens,t=this.$tokenIndex,n=e[t].start;if(n!==undefined)return n;n=0;while(t>0)t-=1,n+=e[t].value.length;return n},this.getCurrentTokenPosition=function(){return{row:this.$row,column:this.getCurrentTokenColumn()}},this.getCurrentTokenRange=function(){var e=this.$rowTokens[this.$tokenIndex],t=this.getCurrentTokenColumn();return new r(this.$row,t,this.$row,t+e.value.length)}}).call(i.prototype),t.TokenIterator=i}),define("ace/mode/behaviour/cstyle",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator","ace/lib/lang"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("../../token_iterator").TokenIterator,o=e("../../lib/lang"),u=["text","paren.rparen","rparen","paren","punctuation.operator"],a=["text","paren.rparen","rparen","paren","punctuation.operator","comment"],f,l={},c={'"':'"',"'":"'"},h=function(e){var t=-1;e.multiSelect&&(t=e.selection.index,l.rangeCount!=e.multiSelect.rangeCount&&(l={rangeCount:e.multiSelect.rangeCount}));if(l[t])return f=l[t];f=l[t]={autoInsertedBrackets:0,autoInsertedRow:-1,autoInsertedLineEnd:"",maybeInsertedBrackets:0,maybeInsertedRow:-1,maybeInsertedLineStart:"",maybeInsertedLineEnd:""}},p=function(e,t,n,r){var i=e.end.row-e.start.row;return{text:n+t+r,selection:[0,e.start.column+1,i,e.end.column+(i?0:1)]}},d=function(e){this.add("braces","insertion",function(t,n,r,i,s){var u=r.getCursorPosition(),a=i.doc.getLine(u.row);if(s=="{"){h(r);var l=r.getSelectionRange(),c=i.doc.getTextRange(l);if(c!==""&&c!=="{"&&r.getWrapBehavioursEnabled())return p(l,c,"{","}");if(d.isSaneInsertion(r,i))return/[\]\}\)]/.test(a[u.column])||r.inMultiSelectMode||e&&e.braces?(d.recordAutoInsert(r,i,"}"),{text:"{}",selection:[1,1]}):(d.recordMaybeInsert(r,i,"{"),{text:"{",selection:[1,1]})}else if(s=="}"){h(r);var v=a.substring(u.column,u.column+1);if(v=="}"){var m=i.$findOpeningBracket("}",{column:u.column+1,row:u.row});if(m!==null&&d.isAutoInsertedClosing(u,a,s))return d.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}else{if(s=="\n"||s=="\r\n"){h(r);var g="";d.isMaybeInsertedClosing(u,a)&&(g=o.stringRepeat("}",f.maybeInsertedBrackets),d.clearMaybeInsertedClosing());var v=a.substring(u.column,u.column+1);if(v==="}"){var y=i.findMatchingBracket({row:u.row,column:u.column+1},"}");if(!y)return null;var b=this.$getIndent(i.getLine(y.row))}else{if(!g){d.clearMaybeInsertedClosing();return}var b=this.$getIndent(a)}var w=b+i.getTabString();return{text:"\n"+w+"\n"+b+g,selection:[1,w.length,1,w.length]}}d.clearMaybeInsertedClosing()}}),this.add("braces","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="{"){h(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.end.column,i.end.column+1);if(u=="}")return i.end.column++,i;f.maybeInsertedBrackets--}}),this.add("parens","insertion",function(e,t,n,r,i){if(i=="("){h(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return p(s,o,"(",")");if(d.isSaneInsertion(n,r))return d.recordAutoInsert(n,r,")"),{text:"()",selection:[1,1]}}else if(i==")"){h(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f==")"){var l=r.$findOpeningBracket(")",{column:u.column+1,row:u.row});if(l!==null&&d.isAutoInsertedClosing(u,a,i))return d.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("parens","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="("){h(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==")")return i.end.column++,i}}),this.add("brackets","insertion",function(e,t,n,r,i){if(i=="["){h(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return p(s,o,"[","]");if(d.isSaneInsertion(n,r))return d.recordAutoInsert(n,r,"]"),{text:"[]",selection:[1,1]}}else if(i=="]"){h(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f=="]"){var l=r.$findOpeningBracket("]",{column:u.column+1,row:u.row});if(l!==null&&d.isAutoInsertedClosing(u,a,i))return d.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("brackets","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="["){h(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u=="]")return i.end.column++,i}}),this.add("string_dquotes","insertion",function(e,t,n,r,i){var s=r.$mode.$quotes||c;if(i.length==1&&s[i]){if(this.lineCommentStart&&this.lineCommentStart.indexOf(i)!=-1)return;h(n);var o=i,u=n.getSelectionRange(),a=r.doc.getTextRange(u);if(a!==""&&(a.length!=1||!s[a])&&n.getWrapBehavioursEnabled())return p(u,a,o,o);if(!a){var f=n.getCursorPosition(),l=r.doc.getLine(f.row),d=l.substring(f.column-1,f.column),v=l.substring(f.column,f.column+1),m=r.getTokenAt(f.row,f.column),g=r.getTokenAt(f.row,f.column+1);if(d=="\\"&&m&&/escape/.test(m.type))return null;var y=m&&/string|escape/.test(m.type),b=!g||/string|escape/.test(g.type),w;if(v==o)w=y!==b,w&&/string\.end/.test(g.type)&&(w=!1);else{if(y&&!b)return null;if(y&&b)return null;var E=r.$mode.tokenRe;E.lastIndex=0;var S=E.test(d);E.lastIndex=0;var x=E.test(d);if(S||x)return null;if(v&&!/[\s;,.})\]\\]/.test(v))return null;var T=l[f.column-2];if(!(d!=o||T!=o&&!E.test(T)))return null;w=!0}return{text:w?o+o:"",selection:[1,1]}}}}),this.add("string_dquotes","deletion",function(e,t,n,r,i){var s=r.$mode.$quotes||c,o=r.doc.getTextRange(i);if(!i.isMultiLine()&&s.hasOwnProperty(o)){h(n);var u=r.doc.getLine(i.start.row),a=u.substring(i.start.column+1,i.start.column+2);if(a==o)return i.end.column++,i}})};d.isSaneInsertion=function(e,t){var n=e.getCursorPosition(),r=new s(t,n.row,n.column);if(!this.$matchTokenType(r.getCurrentToken()||"text",u)){if(/[)}\]]/.test(e.session.getLine(n.row)[n.column]))return!0;var i=new s(t,n.row,n.column+1);if(!this.$matchTokenType(i.getCurrentToken()||"text",u))return!1}return r.stepForward(),r.getCurrentTokenRow()!==n.row||this.$matchTokenType(r.getCurrentToken()||"text",a)},d.$matchTokenType=function(e,t){return t.indexOf(e.type||e)>-1},d.recordAutoInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isAutoInsertedClosing(r,i,f.autoInsertedLineEnd[0])||(f.autoInsertedBrackets=0),f.autoInsertedRow=r.row,f.autoInsertedLineEnd=n+i.substr(r.column),f.autoInsertedBrackets++},d.recordMaybeInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isMaybeInsertedClosing(r,i)||(f.maybeInsertedBrackets=0),f.maybeInsertedRow=r.row,f.maybeInsertedLineStart=i.substr(0,r.column)+n,f.maybeInsertedLineEnd=i.substr(r.column),f.maybeInsertedBrackets++},d.isAutoInsertedClosing=function(e,t,n){return f.autoInsertedBrackets>0&&e.row===f.autoInsertedRow&&n===f.autoInsertedLineEnd[0]&&t.substr(e.column)===f.autoInsertedLineEnd},d.isMaybeInsertedClosing=function(e,t){return f.maybeInsertedBrackets>0&&e.row===f.maybeInsertedRow&&t.substr(e.column)===f.maybeInsertedLineEnd&&t.substr(0,e.column)==f.maybeInsertedLineStart},d.popAutoInsertedClosing=function(){f.autoInsertedLineEnd=f.autoInsertedLineEnd.substr(1),f.autoInsertedBrackets--},d.clearMaybeInsertedClosing=function(){f&&(f.maybeInsertedBrackets=0,f.maybeInsertedRow=-1)},r.inherits(d,i),t.CstyleBehaviour=d}),define("ace/unicode",["require","exports","module"],function(e,t,n){"use strict";var r=[48,9,8,25,5,0,2,25,48,0,11,0,5,0,6,22,2,30,2,457,5,11,15,4,8,0,2,0,18,116,2,1,3,3,9,0,2,2,2,0,2,19,2,82,2,138,2,4,3,155,12,37,3,0,8,38,10,44,2,0,2,1,2,1,2,0,9,26,6,2,30,10,7,61,2,9,5,101,2,7,3,9,2,18,3,0,17,58,3,100,15,53,5,0,6,45,211,57,3,18,2,5,3,11,3,9,2,1,7,6,2,2,2,7,3,1,3,21,2,6,2,0,4,3,3,8,3,1,3,3,9,0,5,1,2,4,3,11,16,2,2,5,5,1,3,21,2,6,2,1,2,1,2,1,3,0,2,4,5,1,3,2,4,0,8,3,2,0,8,15,12,2,2,8,2,2,2,21,2,6,2,1,2,4,3,9,2,2,2,2,3,0,16,3,3,9,18,2,2,7,3,1,3,21,2,6,2,1,2,4,3,8,3,1,3,2,9,1,5,1,2,4,3,9,2,0,17,1,2,5,4,2,2,3,4,1,2,0,2,1,4,1,4,2,4,11,5,4,4,2,2,3,3,0,7,0,15,9,18,2,2,7,2,2,2,22,2,9,2,4,4,7,2,2,2,3,8,1,2,1,7,3,3,9,19,1,2,7,2,2,2,22,2,9,2,4,3,8,2,2,2,3,8,1,8,0,2,3,3,9,19,1,2,7,2,2,2,22,2,15,4,7,2,2,2,3,10,0,9,3,3,9,11,5,3,1,2,17,4,23,2,8,2,0,3,6,4,0,5,5,2,0,2,7,19,1,14,57,6,14,2,9,40,1,2,0,3,1,2,0,3,0,7,3,2,6,2,2,2,0,2,0,3,1,2,12,2,2,3,4,2,0,2,5,3,9,3,1,35,0,24,1,7,9,12,0,2,0,2,0,5,9,2,35,5,19,2,5,5,7,2,35,10,0,58,73,7,77,3,37,11,42,2,0,4,328,2,3,3,6,2,0,2,3,3,40,2,3,3,32,2,3,3,6,2,0,2,3,3,14,2,56,2,3,3,66,5,0,33,15,17,84,13,619,3,16,2,25,6,74,22,12,2,6,12,20,12,19,13,12,2,2,2,1,13,51,3,29,4,0,5,1,3,9,34,2,3,9,7,87,9,42,6,69,11,28,4,11,5,11,11,39,3,4,12,43,5,25,7,10,38,27,5,62,2,28,3,10,7,9,14,0,89,75,5,9,18,8,13,42,4,11,71,55,9,9,4,48,83,2,2,30,14,230,23,280,3,5,3,37,3,5,3,7,2,0,2,0,2,0,2,30,3,52,2,6,2,0,4,2,2,6,4,3,3,5,5,12,6,2,2,6,67,1,20,0,29,0,14,0,17,4,60,12,5,0,4,11,18,0,5,0,3,9,2,0,4,4,7,0,2,0,2,0,2,3,2,10,3,3,6,4,5,0,53,1,2684,46,2,46,2,132,7,6,15,37,11,53,10,0,17,22,10,6,2,6,2,6,2,6,2,6,2,6,2,6,2,6,2,31,48,0,470,1,36,5,2,4,6,1,5,85,3,1,3,2,2,89,2,3,6,40,4,93,18,23,57,15,513,6581,75,20939,53,1164,68,45,3,268,4,27,21,31,3,13,13,1,2,24,9,69,11,1,38,8,3,102,3,1,111,44,25,51,13,68,12,9,7,23,4,0,5,45,3,35,13,28,4,64,15,10,39,54,10,13,3,9,7,22,4,1,5,66,25,2,227,42,2,1,3,9,7,11171,13,22,5,48,8453,301,3,61,3,105,39,6,13,4,6,11,2,12,2,4,2,0,2,1,2,1,2,107,34,362,19,63,3,53,41,11,5,15,17,6,13,1,25,2,33,4,2,134,20,9,8,25,5,0,2,25,12,88,4,5,3,5,3,5,3,2],i=0,s=[];for(var o=0;o2?r%f!=f-1:r%f==0}}var E=Infinity;w(function(e,t){var n=e.search(/\S/);n!==-1?(ne.length&&(E=e.length)}),u==Infinity&&(u=E,s=!1,o=!1),l&&u%f!=0&&(u=Math.floor(u/f)*f),w(o?m:v)},this.toggleBlockComment=function(e,t,n,r){var i=this.blockComment;if(!i)return;!i.start&&i[0]&&(i=i[0]);var s=new f(t,r.row,r.column),o=s.getCurrentToken(),u=t.selection,a=t.selection.toOrientedRange(),c,h;if(o&&/comment/.test(o.type)){var p,d;while(o&&/comment/.test(o.type)){var v=o.value.indexOf(i.start);if(v!=-1){var m=s.getCurrentTokenRow(),g=s.getCurrentTokenColumn()+v;p=new l(m,g,m,g+i.start.length);break}o=s.stepBackward()}var s=new f(t,r.row,r.column),o=s.getCurrentToken();while(o&&/comment/.test(o.type)){var v=o.value.indexOf(i.end);if(v!=-1){var m=s.getCurrentTokenRow(),g=s.getCurrentTokenColumn()+v;d=new l(m,g,m,g+i.end.length);break}o=s.stepForward()}d&&t.remove(d),p&&(t.remove(p),c=p.start.row,h=-i.start.length)}else h=i.start.length,c=n.start.row,t.insert(n.end,i.end),t.insert(n.start,i.start);a.start.row==c&&(a.start.column+=h),a.end.row==c&&(a.end.column+=h),t.selection.fromOrientedRange(a)},this.getNextLineIndent=function(e,t,n){return this.$getIndent(t)},this.checkOutdent=function(e,t,n){return!1},this.autoOutdent=function(e,t,n){},this.$getIndent=function(e){return e.match(/^\s*/)[0]},this.createWorker=function(e){return null},this.createModeDelegates=function(e){this.$embeds=[],this.$modes={};for(var t in e)if(e[t]){var n=e[t],i=n.prototype.$id,s=r.$modes[i];s||(r.$modes[i]=s=new n),r.$modes[t]||(r.$modes[t]=s),this.$embeds.push(t),this.$modes[t]=s}var o=["toggleBlockComment","toggleCommentLines","getNextLineIndent","checkOutdent","autoOutdent","transformAction","getCompletions"];for(var t=0;t=0&&t.row=0&&t.column<=e[t.row].length}function s(e,t){t.action!="insert"&&t.action!="remove"&&r(t,"delta.action must be 'insert' or 'remove'"),t.lines instanceof Array||r(t,"delta.lines must be an Array"),(!t.start||!t.end)&&r(t,"delta.start/end must be an present");var n=t.start;i(e,t.start)||r(t,"delta.start must be contained in document");var s=t.end;t.action=="remove"&&!i(e,s)&&r(t,"delta.end must contained in document for 'remove' actions");var o=s.row-n.row,u=s.column-(o==0?n.column:0);(o!=t.lines.length-1||t.lines[o].length!=u)&&r(t,"delta.range must match delta lines")}t.applyDelta=function(e,t,n){var r=t.start.row,i=t.start.column,s=e[r]||"";switch(t.action){case"insert":var o=t.lines;if(o.length===1)e[r]=s.substring(0,i)+t.lines[0]+s.substring(i);else{var u=[r,1].concat(t.lines);e.splice.apply(e,u),e[r]=s.substring(0,i)+e[r],e[r+t.lines.length-1]+=s.substring(i)}break;case"remove":var a=t.end.column,f=t.end.row;r===f?e[r]=s.substring(0,i)+s.substring(a):e.splice(r,f-r+1,s.substring(0,i)+e[f].substring(a))}}}),define("ace/anchor",["require","exports","module","ace/lib/oop","ace/lib/event_emitter"],function(e,t,n){"use strict";var r=e("./lib/oop"),i=e("./lib/event_emitter").EventEmitter,s=t.Anchor=function(e,t,n){this.$onChange=this.onChange.bind(this),this.attach(e),typeof n=="undefined"?this.setPosition(t.row,t.column):this.setPosition(t,n)};(function(){function e(e,t,n){var r=n?e.column<=t.column:e.columnthis.row)return;var n=t(e,{row:this.row,column:this.column},this.$insertRight);this.setPosition(n.row,n.column,!0)},this.setPosition=function(e,t,n){var r;n?r={row:e,column:t}:r=this.$clipPositionToDocument(e,t);if(this.row==r.row&&this.column==r.column)return;var i={row:this.row,column:this.column};this.row=r.row,this.column=r.column,this._signal("change",{old:i,value:r})},this.detach=function(){this.document.removeEventListener("change",this.$onChange)},this.attach=function(e){this.document=e||this.document,this.document.on("change",this.$onChange)},this.$clipPositionToDocument=function(e,t){var n={};return e>=this.document.getLength()?(n.row=Math.max(0,this.document.getLength()-1),n.column=this.document.getLine(n.row).length):e<0?(n.row=0,n.column=0):(n.row=e,n.column=Math.min(this.document.getLine(n.row).length,Math.max(0,t))),t<0&&(n.column=0),n}}).call(s.prototype)}),define("ace/document",["require","exports","module","ace/lib/oop","ace/apply_delta","ace/lib/event_emitter","ace/range","ace/anchor"],function(e,t,n){"use strict";var r=e("./lib/oop"),i=e("./apply_delta").applyDelta,s=e("./lib/event_emitter").EventEmitter,o=e("./range").Range,u=e("./anchor").Anchor,a=function(e){this.$lines=[""],e.length===0?this.$lines=[""]:Array.isArray(e)?this.insertMergedLines({row:0,column:0},e):this.insert({row:0,column:0},e)};(function(){r.implement(this,s),this.setValue=function(e){var t=this.getLength()-1;this.remove(new o(0,0,t,this.getLine(t).length)),this.insert({row:0,column:0},e)},this.getValue=function(){return this.getAllLines().join(this.getNewLineCharacter())},this.createAnchor=function(e,t){return new u(this,e,t)},"aaa".split(/a/).length===0?this.$split=function(e){return e.replace(/\r\n|\r/g,"\n").split("\n")}:this.$split=function(e){return e.split(/\r\n|\r|\n/)},this.$detectNewLine=function(e){var t=e.match(/^.*?(\r\n|\r|\n)/m);this.$autoNewLine=t?t[1]:"\n",this._signal("changeNewLineMode")},this.getNewLineCharacter=function(){switch(this.$newLineMode){case"windows":return"\r\n";case"unix":return"\n";default:return this.$autoNewLine||"\n"}},this.$autoNewLine="",this.$newLineMode="auto",this.setNewLineMode=function(e){if(this.$newLineMode===e)return;this.$newLineMode=e,this._signal("changeNewLineMode")},this.getNewLineMode=function(){return this.$newLineMode},this.isNewLine=function(e){return e=="\r\n"||e=="\r"||e=="\n"},this.getLine=function(e){return this.$lines[e]||""},this.getLines=function(e,t){return this.$lines.slice(e,t+1)},this.getAllLines=function(){return this.getLines(0,this.getLength())},this.getLength=function(){return this.$lines.length},this.getTextRange=function(e){return this.getLinesForRange(e).join(this.getNewLineCharacter())},this.getLinesForRange=function(e){var t;if(e.start.row===e.end.row)t=[this.getLine(e.start.row).substring(e.start.column,e.end.column)];else{t=this.getLines(e.start.row,e.end.row),t[0]=(t[0]||"").substring(e.start.column);var n=t.length-1;e.end.row-e.start.row==n&&(t[n]=t[n].substring(0,e.end.column))}return t},this.insertLines=function(e,t){return console.warn("Use of document.insertLines is deprecated. Use the insertFullLines method instead."),this.insertFullLines(e,t)},this.removeLines=function(e,t){return console.warn("Use of document.removeLines is deprecated. Use the removeFullLines method instead."),this.removeFullLines(e,t)},this.insertNewLine=function(e){return console.warn("Use of document.insertNewLine is deprecated. Use insertMergedLines(position, ['', '']) instead."),this.insertMergedLines(e,["",""])},this.insert=function(e,t){return this.getLength()<=1&&this.$detectNewLine(t),this.insertMergedLines(e,this.$split(t))},this.insertInLine=function(e,t){var n=this.clippedPos(e.row,e.column),r=this.pos(e.row,e.column+t.length);return this.applyDelta({start:n,end:r,action:"insert",lines:[t]},!0),this.clonePos(r)},this.clippedPos=function(e,t){var n=this.getLength();e===undefined?e=n:e<0?e=0:e>=n&&(e=n-1,t=undefined);var r=this.getLine(e);return t==undefined&&(t=r.length),t=Math.min(Math.max(t,0),r.length),{row:e,column:t}},this.clonePos=function(e){return{row:e.row,column:e.column}},this.pos=function(e,t){return{row:e,column:t}},this.$clipPosition=function(e){var t=this.getLength();return e.row>=t?(e.row=Math.max(0,t-1),e.column=this.getLine(t-1).length):(e.row=Math.max(0,e.row),e.column=Math.min(Math.max(e.column,0),this.getLine(e.row).length)),e},this.insertFullLines=function(e,t){e=Math.min(Math.max(e,0),this.getLength());var n=0;e0,r=t=0&&this.applyDelta({start:this.pos(e,this.getLine(e).length),end:this.pos(e+1,0),action:"remove",lines:["",""]})},this.replace=function(e,t){e instanceof o||(e=o.fromPoints(e.start,e.end));if(t.length===0&&e.isEmpty())return e.start;if(t==this.getTextRange(e))return e.end;this.remove(e);var n;return t?n=this.insert(e.start,t):n=e.start,n},this.applyDeltas=function(e){for(var t=0;t=0;t--)this.revertDelta(e[t])},this.applyDelta=function(e,t){var n=e.action=="insert";if(n?e.lines.length<=1&&!e.lines[0]:!o.comparePoints(e.start,e.end))return;n&&e.lines.length>2e4?this.$splitAndapplyLargeDelta(e,2e4):(i(this.$lines,e,t),this._signal("change",e))},this.$splitAndapplyLargeDelta=function(e,t){var n=e.lines,r=n.length-t+1,i=e.start.row,s=e.start.column;for(var o=0,u=0;o20){n.running=setTimeout(n.$worker,20);break}}n.currentLine=t,r==-1&&(r=t),s<=r&&n.fireUpdateEvent(s,r)}};(function(){r.implement(this,i),this.setTokenizer=function(e){this.tokenizer=e,this.lines=[],this.states=[],this.start(0)},this.setDocument=function(e){this.doc=e,this.lines=[],this.states=[],this.stop()},this.fireUpdateEvent=function(e,t){var n={first:e,last:t};this._signal("update",{data:n})},this.start=function(e){this.currentLine=Math.min(e||0,this.currentLine,this.doc.getLength()),this.lines.splice(this.currentLine,this.lines.length),this.states.splice(this.currentLine,this.states.length),this.stop(),this.running=setTimeout(this.$worker,700)},this.scheduleStart=function(){this.running||(this.running=setTimeout(this.$worker,700))},this.$updateOnChange=function(e){var t=e.start.row,n=e.end.row-t;if(n===0)this.lines[t]=null;else if(e.action=="remove")this.lines.splice(t,n+1,null),this.states.splice(t,n+1,null);else{var r=Array(n+1);r.unshift(t,1),this.lines.splice.apply(this.lines,r),this.states.splice.apply(this.states,r)}this.currentLine=Math.min(t,this.currentLine,this.doc.getLength()),this.stop()},this.stop=function(){this.running&&clearTimeout(this.running),this.running=!1},this.getTokens=function(e){return this.lines[e]||this.$tokenizeRow(e)},this.getState=function(e){return this.currentLine==e&&this.$tokenizeRow(e),this.states[e]||"start"},this.$tokenizeRow=function(e){var t=this.doc.getLine(e),n=this.states[e-1],r=this.tokenizer.getLineTokens(t,n,e);return this.states[e]+""!=r.state+""?(this.states[e]=r.state,this.lines[e+1]=null,this.currentLine>e+1&&(this.currentLine=e+1)):this.currentLine==e&&(this.currentLine=e+1),this.lines[e]=r.tokens}}).call(s.prototype),t.BackgroundTokenizer=s}),define("ace/search_highlight",["require","exports","module","ace/lib/lang","ace/lib/oop","ace/range"],function(e,t,n){"use strict";var r=e("./lib/lang"),i=e("./lib/oop"),s=e("./range").Range,o=function(e,t,n){this.setRegexp(e),this.clazz=t,this.type=n||"text"};(function(){this.MAX_RANGES=500,this.setRegexp=function(e){if(this.regExp+""==e+"")return;this.regExp=e,this.cache=[]},this.update=function(e,t,n,i){if(!this.regExp)return;var o=i.firstRow,u=i.lastRow;for(var a=o;a<=u;a++){var f=this.cache[a];f==null&&(f=r.getMatchOffsets(n.getLine(a),this.regExp),f.length>this.MAX_RANGES&&(f=f.slice(0,this.MAX_RANGES)),f=f.map(function(e){return new s(a,e.offset,a,e.offset+e.length)}),this.cache[a]=f.length?f:"");for(var l=f.length;l--;)t.drawSingleLineMarker(e,f[l].toScreenRange(n),this.clazz,i)}}}).call(o.prototype),t.SearchHighlight=o}),define("ace/edit_session/fold_line",["require","exports","module","ace/range"],function(e,t,n){"use strict";function i(e,t){this.foldData=e,Array.isArray(t)?this.folds=t:t=this.folds=[t];var n=t[t.length-1];this.range=new r(t[0].start.row,t[0].start.column,n.end.row,n.end.column),this.start=this.range.start,this.end=this.range.end,this.folds.forEach(function(e){e.setFoldLine(this)},this)}var r=e("../range").Range;(function(){this.shiftRow=function(e){this.start.row+=e,this.end.row+=e,this.folds.forEach(function(t){t.start.row+=e,t.end.row+=e})},this.addFold=function(e){if(e.sameRow){if(e.start.rowthis.endRow)throw new Error("Can't add a fold to this FoldLine as it has no connection");this.folds.push(e),this.folds.sort(function(e,t){return-e.range.compareEnd(t.start.row,t.start.column)}),this.range.compareEnd(e.start.row,e.start.column)>0?(this.end.row=e.end.row,this.end.column=e.end.column):this.range.compareStart(e.end.row,e.end.column)<0&&(this.start.row=e.start.row,this.start.column=e.start.column)}else if(e.start.row==this.end.row)this.folds.push(e),this.end.row=e.end.row,this.end.column=e.end.column;else{if(e.end.row!=this.start.row)throw new Error("Trying to add fold to FoldRow that doesn't have a matching row");this.folds.unshift(e),this.start.row=e.start.row,this.start.column=e.start.column}e.foldLine=this},this.containsRow=function(e){return e>=this.start.row&&e<=this.end.row},this.walk=function(e,t,n){var r=0,i=this.folds,s,o,u,a=!0;t==null&&(t=this.end.row,n=this.end.column);for(var f=0;f0)continue;var a=i(e,o.start);return u===0?t&&a!==0?-s-2:s:a>0||a===0&&!t?s:-s-1}return-s-1},this.add=function(e){var t=!e.isEmpty(),n=this.pointIndex(e.start,t);n<0&&(n=-n-1);var r=this.pointIndex(e.end,t,n);return r<0?r=-r-1:r++,this.ranges.splice(n,r-n,e)},this.addList=function(e){var t=[];for(var n=e.length;n--;)t.push.apply(t,this.add(e[n]));return t},this.substractPoint=function(e){var t=this.pointIndex(e);if(t>=0)return this.ranges.splice(t,1)},this.merge=function(){var e=[],t=this.ranges;t=t.sort(function(e,t){return i(e.start,t.start)});var n=t[0],r;for(var s=1;s=0},this.containsPoint=function(e){return this.pointIndex(e)>=0},this.rangeAtPoint=function(e){var t=this.pointIndex(e);if(t>=0)return this.ranges[t]},this.clipRows=function(e,t){var n=this.ranges;if(n[0].start.row>t||n[n.length-1].start.row=r)break}if(e.action=="insert"){var f=i-r,l=-t.column+n.column;for(;or)break;a.start.row==r&&a.start.column>=t.column&&(a.start.column==t.column&&this.$bias<=0||(a.start.column+=l,a.start.row+=f));if(a.end.row==r&&a.end.column>=t.column){if(a.end.column==t.column&&this.$bias<0)continue;a.end.column==t.column&&l>0&&oa.start.column&&a.end.column==s[o+1].start.column&&(a.end.column-=l),a.end.column+=l,a.end.row+=f}}}else{var f=r-i,l=t.column-n.column;for(;oi)break;if(a.end.rowt.column)a.end.column=t.column,a.end.row=t.row}else a.end.column+=l,a.end.row+=f;else a.end.row>i&&(a.end.row+=f);if(a.start.rowt.column)a.start.column=t.column,a.start.row=t.row}else a.start.column+=l,a.start.row+=f;else a.start.row>i&&(a.start.row+=f)}}if(f!=0&&o=e)return i;if(i.end.row>e)return null}return null},this.getNextFoldLine=function(e,t){var n=this.$foldData,r=0;t&&(r=n.indexOf(t)),r==-1&&(r=0);for(r;r=e)return i}return null},this.getFoldedRowCount=function(e,t){var n=this.$foldData,r=t-e+1;for(var i=0;i=t){u=e?r-=t-u:r=0);break}o>=e&&(u>=e?r-=o-u:r-=o-e+1)}return r},this.$addFoldLine=function(e){return this.$foldData.push(e),this.$foldData.sort(function(e,t){return e.start.row-t.start.row}),e},this.addFold=function(e,t){var n=this.$foldData,r=!1,o;e instanceof s?o=e:(o=new s(t,e),o.collapseChildren=t.collapseChildren),this.$clipRangeToDocument(o.range);var u=o.start.row,a=o.start.column,f=o.end.row,l=o.end.column,c=this.getFoldAt(u,a,1),h=this.getFoldAt(f,l,-1);if(c&&h==c)return c.addSubFold(o);c&&!c.range.isStart(u,a)&&this.removeFold(c),h&&!h.range.isEnd(f,l)&&this.removeFold(h);var p=this.getFoldsInRange(o.range);p.length>0&&(this.removeFolds(p),p.forEach(function(e){o.addSubFold(e)}));for(var d=0;d0&&this.foldAll(e.start.row+1,e.end.row,e.collapseChildren-1),e.subFolds=[]},this.expandFolds=function(e){e.forEach(function(e){this.expandFold(e)},this)},this.unfold=function(e,t){var n,i;e==null?(n=new r(0,0,this.getLength(),0),t=!0):typeof e=="number"?n=new r(e,0,e,this.getLine(e).length):"row"in e?n=r.fromPoints(e,e):n=e,i=this.getFoldsInRangeList(n);if(t)this.removeFolds(i);else{var s=i;while(s.length)this.expandFolds(s),s=this.getFoldsInRangeList(n)}if(i.length)return i},this.isRowFolded=function(e,t){return!!this.getFoldLine(e,t)},this.getRowFoldEnd=function(e,t){var n=this.getFoldLine(e,t);return n?n.end.row:e},this.getRowFoldStart=function(e,t){var n=this.getFoldLine(e,t);return n?n.start.row:e},this.getFoldDisplayLine=function(e,t,n,r,i){r==null&&(r=e.start.row),i==null&&(i=0),t==null&&(t=e.end.row),n==null&&(n=this.getLine(t).length);var s=this.doc,o="";return e.walk(function(e,t,n,u){if(tl)break}while(s&&a.test(s.type));s=i.stepBackward()}else s=i.getCurrentToken();return f.end.row=i.getCurrentTokenRow(),f.end.column=i.getCurrentTokenColumn()+s.value.length-2,f}},this.foldAll=function(e,t,n){n==undefined&&(n=1e5);var r=this.foldWidgets;if(!r)return;t=t||this.getLength(),e=e||0;for(var i=e;i=e){i=s.end.row;try{var o=this.addFold("...",s);o&&(o.collapseChildren=n)}catch(u){}}}},this.$foldStyles={manual:1,markbegin:1,markbeginend:1},this.$foldStyle="markbegin",this.setFoldStyle=function(e){if(!this.$foldStyles[e])throw new Error("invalid fold style: "+e+"["+Object.keys(this.$foldStyles).join(", ")+"]");if(this.$foldStyle==e)return;this.$foldStyle=e,e=="manual"&&this.unfold();var t=this.$foldMode;this.$setFolding(null),this.$setFolding(t)},this.$setFolding=function(e){if(this.$foldMode==e)return;this.$foldMode=e,this.off("change",this.$updateFoldWidgets),this.off("tokenizerUpdate",this.$tokenizerUpdateFoldWidgets),this._signal("changeAnnotation");if(!e||this.$foldStyle=="manual"){this.foldWidgets=null;return}this.foldWidgets=[],this.getFoldWidget=e.getFoldWidget.bind(e,this,this.$foldStyle),this.getFoldWidgetRange=e.getFoldWidgetRange.bind(e,this,this.$foldStyle),this.$updateFoldWidgets=this.updateFoldWidgets.bind(this),this.$tokenizerUpdateFoldWidgets=this.tokenizerUpdateFoldWidgets.bind(this),this.on("change",this.$updateFoldWidgets),this.on("tokenizerUpdate",this.$tokenizerUpdateFoldWidgets)},this.getParentFoldRangeData=function(e,t){var n=this.foldWidgets;if(!n||t&&n[e])return{};var r=e-1,i;while(r>=0){var s=n[r];s==null&&(s=n[r]=this.getFoldWidget(r));if(s=="start"){var o=this.getFoldWidgetRange(r);i||(i=o);if(o&&o.end.row>=e)break}r--}return{range:r!==-1&&o,firstRange:i}},this.onFoldWidgetClick=function(e,t){t=t.domEvent;var n={children:t.shiftKey,all:t.ctrlKey||t.metaKey,siblings:t.altKey},r=this.$toggleFoldWidget(e,n);if(!r){var i=t.target||t.srcElement;i&&/ace_fold-widget/.test(i.className)&&(i.className+=" ace_invalid")}},this.$toggleFoldWidget=function(e,t){if(!this.getFoldWidget)return;var n=this.getFoldWidget(e),r=this.getLine(e),i=n==="end"?-1:1,s=this.getFoldAt(e,i===-1?0:r.length,i);if(s)return t.children||t.all?this.removeFold(s):this.expandFold(s),s;var o=this.getFoldWidgetRange(e,!0);if(o&&!o.isMultiLine()){s=this.getFoldAt(o.start.row,o.start.column,1);if(s&&o.isEqual(s.range))return this.removeFold(s),s}if(t.siblings){var u=this.getParentFoldRangeData(e);if(u.range)var a=u.range.start.row+1,f=u.range.end.row;this.foldAll(a,f,t.all?1e4:0)}else t.children?(f=o?o.end.row:this.getLength(),this.foldAll(e+1,f,t.all?1e4:0)):o&&(t.all&&(o.collapseChildren=1e4),this.addFold("...",o));return o},this.toggleFoldWidget=function(e){var t=this.selection.getCursor().row;t=this.getRowFoldStart(t);var n=this.$toggleFoldWidget(t,{});if(n)return;var r=this.getParentFoldRangeData(t,!0);n=r.range||r.firstRange;if(n){t=n.start.row;var i=this.getFoldAt(t,this.getLine(t).length,1);i?this.removeFold(i):this.addFold("...",n)}},this.updateFoldWidgets=function(e){var t=e.start.row,n=e.end.row-t;if(n===0)this.foldWidgets[t]=null;else if(e.action=="remove")this.foldWidgets.splice(t,n+1,null);else{var r=Array(n+1);r.unshift(t,1),this.foldWidgets.splice.apply(this.foldWidgets,r)}},this.tokenizerUpdateFoldWidgets=function(e){var t=e.data;t.first!=t.last&&this.foldWidgets.length>t.first&&this.foldWidgets.splice(t.first,this.foldWidgets.length)}}var r=e("../range").Range,i=e("./fold_line").FoldLine,s=e("./fold").Fold,o=e("../token_iterator").TokenIterator;t.Folding=u}),define("ace/edit_session/bracket_match",["require","exports","module","ace/token_iterator","ace/range"],function(e,t,n){"use strict";function s(){this.findMatchingBracket=function(e,t){if(e.column==0)return null;var n=t||this.getLine(e.row).charAt(e.column-1);if(n=="")return null;var r=n.match(/([\(\[\{])|([\)\]\}])/);return r?r[1]?this.$findClosingBracket(r[1],e):this.$findOpeningBracket(r[2],e):null},this.getBracketRange=function(e){var t=this.getLine(e.row),n=!0,r,s=t.charAt(e.column-1),o=s&&s.match(/([\(\[\{])|([\)\]\}])/);o||(s=t.charAt(e.column),e={row:e.row,column:e.column+1},o=s&&s.match(/([\(\[\{])|([\)\]\}])/),n=!1);if(!o)return null;if(o[1]){var u=this.$findClosingBracket(o[1],e);if(!u)return null;r=i.fromPoints(e,u),n||(r.end.column++,r.start.column--),r.cursor=r.end}else{var u=this.$findOpeningBracket(o[2],e);if(!u)return null;r=i.fromPoints(u,e),n||(r.start.column++,r.end.column--),r.cursor=r.start}return r},this.getMatchingBracketRanges=function(e){var t=this.getLine(e.row),n=t.charAt(e.column-1),r=n&&n.match(/([\(\[\{])|([\)\]\}])/);r||(n=t.charAt(e.column),e={row:e.row,column:e.column+1},r=n&&n.match(/([\(\[\{])|([\)\]\}])/));if(!r)return null;var s=new i(e.row,e.column-1,e.row,e.column),o=r[1]?this.$findClosingBracket(r[1],e):this.$findOpeningBracket(r[2],e);if(!o)return[s];var u=new i(o.row,o.column,o.row,o.column+1);return[s,u]},this.$brackets={")":"(","(":")","]":"[","[":"]","{":"}","}":"{","<":">",">":"<"},this.$findOpeningBracket=function(e,t,n){var i=this.$brackets[e],s=1,o=new r(this,t.row,t.column),u=o.getCurrentToken();u||(u=o.stepForward());if(!u)return;n||(n=new RegExp("(\\.?"+u.type.replace(".","\\.").replace("rparen",".paren").replace(/\b(?:end)\b/,"(?:start|begin|end)")+")+"));var a=t.column-o.getCurrentTokenColumn()-2,f=u.value;for(;;){while(a>=0){var l=f.charAt(a);if(l==i){s-=1;if(s==0)return{row:o.getCurrentTokenRow(),column:a+o.getCurrentTokenColumn()}}else l==e&&(s+=1);a-=1}do u=o.stepBackward();while(u&&!n.test(u.type));if(u==null)break;f=u.value,a=f.length-1}return null},this.$findClosingBracket=function(e,t,n){var i=this.$brackets[e],s=1,o=new r(this,t.row,t.column),u=o.getCurrentToken();u||(u=o.stepForward());if(!u)return;n||(n=new RegExp("(\\.?"+u.type.replace(".","\\.").replace("lparen",".paren").replace(/\b(?:start|begin)\b/,"(?:start|begin|end)")+")+"));var a=t.column-o.getCurrentTokenColumn();for(;;){var f=u.value,l=f.length;while(a=4352&&e<=4447||e>=4515&&e<=4519||e>=4602&&e<=4607||e>=9001&&e<=9002||e>=11904&&e<=11929||e>=11931&&e<=12019||e>=12032&&e<=12245||e>=12272&&e<=12283||e>=12288&&e<=12350||e>=12353&&e<=12438||e>=12441&&e<=12543||e>=12549&&e<=12589||e>=12593&&e<=12686||e>=12688&&e<=12730||e>=12736&&e<=12771||e>=12784&&e<=12830||e>=12832&&e<=12871||e>=12880&&e<=13054||e>=13056&&e<=19903||e>=19968&&e<=42124||e>=42128&&e<=42182||e>=43360&&e<=43388||e>=44032&&e<=55203||e>=55216&&e<=55238||e>=55243&&e<=55291||e>=63744&&e<=64255||e>=65040&&e<=65049||e>=65072&&e<=65106||e>=65108&&e<=65126||e>=65128&&e<=65131||e>=65281&&e<=65376||e>=65504&&e<=65510}r.implement(this,u),this.setDocument=function(e){this.doc&&this.doc.removeListener("change",this.$onChange),this.doc=e,e.on("change",this.$onChange),this.bgTokenizer&&this.bgTokenizer.setDocument(this.getDocument()),this.resetCaches()},this.getDocument=function(){return this.doc},this.$resetRowCache=function(e){if(!e){this.$docRowCache=[],this.$screenRowCache=[];return}var t=this.$docRowCache.length,n=this.$getRowCacheIndex(this.$docRowCache,e)+1;t>n&&(this.$docRowCache.splice(n,t),this.$screenRowCache.splice(n,t))},this.$getRowCacheIndex=function(e,t){var n=0,r=e.length-1;while(n<=r){var i=n+r>>1,s=e[i];if(t>s)n=i+1;else{if(!(t=t)break}return r=n[s],r?(r.index=s,r.start=i-r.value.length,r):null},this.setUndoManager=function(e){this.$undoManager=e,this.$informUndoManager&&this.$informUndoManager.cancel();if(e){var t=this;e.addSession(this),this.$syncInformUndoManager=function(){t.$informUndoManager.cancel(),t.mergeUndoDeltas=!1},this.$informUndoManager=i.delayedCall(this.$syncInformUndoManager)}else this.$syncInformUndoManager=function(){}},this.markUndoGroup=function(){this.$syncInformUndoManager&&this.$syncInformUndoManager()},this.$defaultUndoManager={undo:function(){},redo:function(){},hasUndo:function(){},hasRedo:function(){},reset:function(){},add:function(){},addSelection:function(){},startNewGroup:function(){},addSession:function(){}},this.getUndoManager=function(){return this.$undoManager||this.$defaultUndoManager},this.getTabString=function(){return this.getUseSoftTabs()?i.stringRepeat(" ",this.getTabSize()):" "},this.setUseSoftTabs=function(e){this.setOption("useSoftTabs",e)},this.getUseSoftTabs=function(){return this.$useSoftTabs&&!this.$mode.$indentWithTabs},this.setTabSize=function(e){this.setOption("tabSize",e)},this.getTabSize=function(){return this.$tabSize},this.isTabStop=function(e){return this.$useSoftTabs&&e.column%this.$tabSize===0},this.setNavigateWithinSoftTabs=function(e){this.setOption("navigateWithinSoftTabs",e)},this.getNavigateWithinSoftTabs=function(){return this.$navigateWithinSoftTabs},this.$overwrite=!1,this.setOverwrite=function(e){this.setOption("overwrite",e)},this.getOverwrite=function(){return this.$overwrite},this.toggleOverwrite=function(){this.setOverwrite(!this.$overwrite)},this.addGutterDecoration=function(e,t){this.$decorations[e]||(this.$decorations[e]=""),this.$decorations[e]+=" "+t,this._signal("changeBreakpoint",{})},this.removeGutterDecoration=function(e,t){this.$decorations[e]=(this.$decorations[e]||"").replace(" "+t,""),this._signal("changeBreakpoint",{})},this.getBreakpoints=function(){return this.$breakpoints},this.setBreakpoints=function(e){this.$breakpoints=[];for(var t=0;t0&&(r=!!n.charAt(t-1).match(this.tokenRe)),r||(r=!!n.charAt(t).match(this.tokenRe));if(r)var i=this.tokenRe;else if(/^\s+$/.test(n.slice(t-1,t+1)))var i=/\s/;else var i=this.nonTokenRe;var s=t;if(s>0){do s--;while(s>=0&&n.charAt(s).match(i));s++}var o=t;while(oe&&(e=t.screenWidth)}),this.lineWidgetWidth=e},this.$computeWidth=function(e){if(this.$modified||e){this.$modified=!1;if(this.$useWrapMode)return this.screenWidth=this.$wrapLimit;var t=this.doc.getAllLines(),n=this.$rowLengthCache,r=0,i=0,s=this.$foldData[i],o=s?s.start.row:Infinity,u=t.length;for(var a=0;ao){a=s.end.row+1;if(a>=u)break;s=this.$foldData[i++],o=s?s.start.row:Infinity}n[a]==null&&(n[a]=this.$getStringScreenWidth(t[a])[0]),n[a]>r&&(r=n[a])}this.screenWidth=r}},this.getLine=function(e){return this.doc.getLine(e)},this.getLines=function(e,t){return this.doc.getLines(e,t)},this.getLength=function(){return this.doc.getLength()},this.getTextRange=function(e){return this.doc.getTextRange(e||this.selection.getRange())},this.insert=function(e,t){return this.doc.insert(e,t)},this.remove=function(e){return this.doc.remove(e)},this.removeFullLines=function(e,t){return this.doc.removeFullLines(e,t)},this.undoChanges=function(e,t){if(!e.length)return;this.$fromUndo=!0;for(var n=e.length-1;n!=-1;n--){var r=e[n];r.action=="insert"||r.action=="remove"?this.doc.revertDelta(r):r.folds&&this.addFolds(r.folds)}!t&&this.$undoSelect&&(e.selectionBefore?this.selection.fromJSON(e.selectionBefore):this.selection.setRange(this.$getUndoSelection(e,!0))),this.$fromUndo=!1},this.redoChanges=function(e,t){if(!e.length)return;this.$fromUndo=!0;for(var n=0;ne.end.column&&(s.start.column+=u),s.end.row==e.end.row&&s.end.column>e.end.column&&(s.end.column+=u)),o&&s.start.row>=e.end.row&&(s.start.row+=o,s.end.row+=o)}s.end=this.insert(s.start,r);if(i.length){var a=e.start,f=s.start,o=f.row-a.row,u=f.column-a.column;this.addFolds(i.map(function(e){return e=e.clone(),e.start.row==a.row&&(e.start.column+=u),e.end.row==a.row&&(e.end.column+=u),e.start.row+=o,e.end.row+=o,e}))}return s},this.indentRows=function(e,t,n){n=n.replace(/\t/g,this.getTabString());for(var r=e;r<=t;r++)this.doc.insertInLine({row:r,column:0},n)},this.outdentRows=function(e){var t=e.collapseRows(),n=new l(0,0,0,0),r=this.getTabSize();for(var i=t.start.row;i<=t.end.row;++i){var s=this.getLine(i);n.start.row=i,n.end.row=i;for(var o=0;o0){var r=this.getRowFoldEnd(t+n);if(r>this.doc.getLength()-1)return 0;var i=r-t}else{e=this.$clipRowToDocument(e),t=this.$clipRowToDocument(t);var i=t-e+1}var s=new l(e,0,t,Number.MAX_VALUE),o=this.getFoldsInRange(s).map(function(e){return e=e.clone(),e.start.row+=i,e.end.row+=i,e}),u=n==0?this.doc.getLines(e,t):this.doc.removeFullLines(e,t);return this.doc.insertFullLines(e+i,u),o.length&&this.addFolds(o),i},this.moveLinesUp=function(e,t){return this.$moveLines(e,t,-1)},this.moveLinesDown=function(e,t){return this.$moveLines(e,t,1)},this.duplicateLines=function(e,t){return this.$moveLines(e,t,0)},this.$clipRowToDocument=function(e){return Math.max(0,Math.min(e,this.doc.getLength()-1))},this.$clipColumnToRow=function(e,t){return t<0?0:Math.min(this.doc.getLine(e).length,t)},this.$clipPositionToDocument=function(e,t){t=Math.max(0,t);if(e<0)e=0,t=0;else{var n=this.doc.getLength();e>=n?(e=n-1,t=this.doc.getLine(n-1).length):t=Math.min(this.doc.getLine(e).length,t)}return{row:e,column:t}},this.$clipRangeToDocument=function(e){e.start.row<0?(e.start.row=0,e.start.column=0):e.start.column=this.$clipColumnToRow(e.start.row,e.start.column);var t=this.doc.getLength()-1;return e.end.row>t?(e.end.row=t,e.end.column=this.doc.getLine(t).length):e.end.column=this.$clipColumnToRow(e.end.row,e.end.column),e},this.$wrapLimit=80,this.$useWrapMode=!1,this.$wrapLimitRange={min:null,max:null},this.setUseWrapMode=function(e){if(e!=this.$useWrapMode){this.$useWrapMode=e,this.$modified=!0,this.$resetRowCache(0);if(e){var t=this.getLength();this.$wrapData=Array(t),this.$updateWrapData(0,t-1)}this._signal("changeWrapMode")}},this.getUseWrapMode=function(){return this.$useWrapMode},this.setWrapLimitRange=function(e,t){if(this.$wrapLimitRange.min!==e||this.$wrapLimitRange.max!==t)this.$wrapLimitRange={min:e,max:t},this.$modified=!0,this.$bidiHandler.markAsDirty(),this.$useWrapMode&&this._signal("changeWrapMode")},this.adjustWrapLimit=function(e,t){var n=this.$wrapLimitRange;n.max<0&&(n={min:t,max:t});var r=this.$constrainWrapLimit(e,n.min,n.max);return r!=this.$wrapLimit&&r>1?(this.$wrapLimit=r,this.$modified=!0,this.$useWrapMode&&(this.$updateWrapData(0,this.getLength()-1),this.$resetRowCache(0),this._signal("changeWrapLimit")),!0):!1},this.$constrainWrapLimit=function(e,t,n){return t&&(e=Math.max(t,e)),n&&(e=Math.min(n,e)),e},this.getWrapLimit=function(){return this.$wrapLimit},this.setWrapLimit=function(e){this.setWrapLimitRange(e,e)},this.getWrapLimitRange=function(){return{min:this.$wrapLimitRange.min,max:this.$wrapLimitRange.max}},this.$updateInternalDataOnChange=function(e){var t=this.$useWrapMode,n=e.action,r=e.start,i=e.end,s=r.row,o=i.row,u=o-s,a=null;this.$updating=!0;if(u!=0)if(n==="remove"){this[t?"$wrapData":"$rowLengthCache"].splice(s,u);var f=this.$foldData;a=this.getFoldsInRange(e),this.removeFolds(a);var l=this.getFoldLine(i.row),c=0;if(l){l.addRemoveChars(i.row,i.column,r.column-i.column),l.shiftRow(-u);var h=this.getFoldLine(s);h&&h!==l&&(h.merge(l),l=h),c=f.indexOf(l)+1}for(c;c=i.row&&l.shiftRow(-u)}o=s}else{var p=Array(u);p.unshift(s,0);var d=t?this.$wrapData:this.$rowLengthCache;d.splice.apply(d,p);var f=this.$foldData,l=this.getFoldLine(s),c=0;if(l){var v=l.range.compareInside(r.row,r.column);v==0?(l=l.split(r.row,r.column),l&&(l.shiftRow(u),l.addRemoveChars(o,0,i.column-r.column))):v==-1&&(l.addRemoveChars(s,0,i.column-r.column),l.shiftRow(u)),c=f.indexOf(l)+1}for(c;c=s&&l.shiftRow(u)}}else{u=Math.abs(e.start.column-e.end.column),n==="remove"&&(a=this.getFoldsInRange(e),this.removeFolds(a),u=-u);var l=this.getFoldLine(s);l&&l.addRemoveChars(s,r.column,u)}return t&&this.$wrapData.length!=this.doc.getLength()&&console.error("doc.getLength() and $wrapData.length have to be the same!"),this.$updating=!1,t?this.$updateWrapData(s,o):this.$updateRowLengthCache(s,o),a},this.$updateRowLengthCache=function(e,t,n){this.$rowLengthCache[e]=null,this.$rowLengthCache[t]=null},this.$updateWrapData=function(e,t){var r=this.doc.getAllLines(),i=this.getTabSize(),o=this.$wrapData,u=this.$wrapLimit,a,f,l=e;t=Math.min(t,r.length-1);while(l<=t)f=this.getFoldLine(l,f),f?(a=[],f.walk(function(e,t,i,o){var u;if(e!=null){u=this.$getDisplayTokens(e,a.length),u[0]=n;for(var f=1;fr-b){var w=f+r-b;if(e[w-1]>=c&&e[w]>=c){y(w);continue}if(e[w]==n||e[w]==s){for(w;w!=f-1;w--)if(e[w]==n)break;if(w>f){y(w);continue}w=f+r;for(w;w>2)),f-1);while(w>E&&e[w]E&&e[w]E&&e[w]==a)w--}else while(w>E&&e[w]E){y(++w);continue}w=f+r,e[w]==t&&w--,y(w-b)}return o},this.$getDisplayTokens=function(n,r){var i=[],s;r=r||0;for(var o=0;o39&&u<48||u>57&&u<64?i.push(a):u>=4352&&m(u)?i.push(e,t):i.push(e)}return i},this.$getStringScreenWidth=function(e,t,n){if(t==0)return[0,0];t==null&&(t=Infinity),n=n||0;var r,i;for(i=0;i=4352&&m(r)?n+=2:n+=1;if(n>t)break}return[n,i]},this.lineWidgets=null,this.getRowLength=function(e){var t=1;return this.lineWidgets&&(t+=this.lineWidgets[e]&&this.lineWidgets[e].rowCount||0),!this.$useWrapMode||!this.$wrapData[e]?t:this.$wrapData[e].length+t},this.getRowLineCount=function(e){return!this.$useWrapMode||!this.$wrapData[e]?1:this.$wrapData[e].length+1},this.getRowWrapIndent=function(e){if(this.$useWrapMode){var t=this.screenToDocumentPosition(e,Number.MAX_VALUE),n=this.$wrapData[t.row];return n.length&&n[0]=0)var u=f[l],i=this.$docRowCache[l],h=e>f[c-1];else var h=!c;var p=this.getLength()-1,d=this.getNextFoldLine(i),v=d?d.start.row:Infinity;while(u<=e){a=this.getRowLength(i);if(u+a>e||i>=p)break;u+=a,i++,i>v&&(i=d.end.row+1,d=this.getNextFoldLine(i,d),v=d?d.start.row:Infinity),h&&(this.$docRowCache.push(i),this.$screenRowCache.push(u))}if(d&&d.start.row<=i)r=this.getFoldDisplayLine(d),i=d.start.row;else{if(u+a<=e||i>p)return{row:p,column:this.getLine(p).length};r=this.getLine(i),d=null}var m=0,g=Math.floor(e-u);if(this.$useWrapMode){var y=this.$wrapData[i];y&&(o=y[g],g>0&&y.length&&(m=y.indent,s=y[g-1]||y[y.length-1],r=r.substring(s)))}return n!==undefined&&this.$bidiHandler.isBidiRow(u+g,i,g)&&(t=this.$bidiHandler.offsetToCol(n)),s+=this.$getStringScreenWidth(r,t-m)[1],this.$useWrapMode&&s>=o&&(s=o-1),d?d.idxToPosition(s):{row:i,column:s}},this.documentToScreenPosition=function(e,t){if(typeof t=="undefined")var n=this.$clipPositionToDocument(e.row,e.column);else n=this.$clipPositionToDocument(e,t);e=n.row,t=n.column;var r=0,i=null,s=null;s=this.getFoldAt(e,t,1),s&&(e=s.start.row,t=s.start.column);var o,u=0,a=this.$docRowCache,f=this.$getRowCacheIndex(a,e),l=a.length;if(l&&f>=0)var u=a[f],r=this.$screenRowCache[f],c=e>a[l-1];else var c=!l;var h=this.getNextFoldLine(u),p=h?h.start.row:Infinity;while(u=p){o=h.end.row+1;if(o>e)break;h=this.getNextFoldLine(o,h),p=h?h.start.row:Infinity}else o=u+1;r+=this.getRowLength(u),u=o,c&&(this.$docRowCache.push(u),this.$screenRowCache.push(r))}var d="";h&&u>=p?(d=this.getFoldDisplayLine(h,e,t),i=h.start.row):(d=this.getLine(e).substring(0,t),i=e);var v=0;if(this.$useWrapMode){var m=this.$wrapData[i];if(m){var g=0;while(d.length>=m[g])r++,g++;d=d.substring(m[g-1]||0,d.length),v=g>0?m.indent:0}}return this.lineWidgets&&this.lineWidgets[u]&&this.lineWidgets[u].rowsAbove&&(r+=this.lineWidgets[u].rowsAbove),{row:r,column:v+this.$getStringScreenWidth(d)[0]}},this.documentToScreenColumn=function(e,t){return this.documentToScreenPosition(e,t).column},this.documentToScreenRow=function(e,t){return this.documentToScreenPosition(e,t).row},this.getScreenLength=function(){var e=0,t=null;if(!this.$useWrapMode){e=this.getLength();var n=this.$foldData;for(var r=0;ro&&(s=t.end.row+1,t=this.$foldData[r++],o=t?t.start.row:Infinity)}}return this.lineWidgets&&(e+=this.$getWidgetScreenLength()),e},this.$setFontMetrics=function(e){if(!this.$enableVarChar)return;this.$getStringScreenWidth=function(t,n,r){if(n===0)return[0,0];n||(n=Infinity),r=r||0;var i,s;for(s=0;sn)break}return[r,s]}},this.destroy=function(){this.bgTokenizer&&(this.bgTokenizer.setDocument(null),this.bgTokenizer=null),this.$stopWorker()},this.isFullWidth=m}.call(d.prototype),e("./edit_session/folding").Folding.call(d.prototype),e("./edit_session/bracket_match").BracketMatch.call(d.prototype),o.defineOptions(d.prototype,"session",{wrap:{set:function(e){!e||e=="off"?e=!1:e=="free"?e=!0:e=="printMargin"?e=-1:typeof e=="string"&&(e=parseInt(e,10)||!1);if(this.$wrap==e)return;this.$wrap=e;if(!e)this.setUseWrapMode(!1);else{var t=typeof e=="number"?e:null;this.setWrapLimitRange(t,t),this.setUseWrapMode(!0)}},get:function(){return this.getUseWrapMode()?this.$wrap==-1?"printMargin":this.getWrapLimitRange().min?this.$wrap:"free":"off"},handlesSet:!0},wrapMethod:{set:function(e){e=e=="auto"?this.$mode.type!="text":e!="text",e!=this.$wrapAsCode&&(this.$wrapAsCode=e,this.$useWrapMode&&(this.$useWrapMode=!1,this.setUseWrapMode(!0)))},initialValue:"auto"},indentedSoftWrap:{set:function(){this.$useWrapMode&&(this.$useWrapMode=!1,this.setUseWrapMode(!0))},initialValue:!0},firstLineNumber:{set:function(){this._signal("changeBreakpoint")},initialValue:1},useWorker:{set:function(e){this.$useWorker=e,this.$stopWorker(),e&&this.$startWorker()},initialValue:!0},useSoftTabs:{initialValue:!0},tabSize:{set:function(e){e=parseInt(e),e>0&&this.$tabSize!==e&&(this.$modified=!0,this.$rowLengthCache=[],this.$tabSize=e,this._signal("changeTabSize"))},initialValue:4,handlesSet:!0},navigateWithinSoftTabs:{initialValue:!1},foldStyle:{set:function(e){this.setFoldStyle(e)},handlesSet:!0},overwrite:{set:function(e){this._signal("changeOverwrite")},initialValue:!1},newLineMode:{set:function(e){this.doc.setNewLineMode(e)},get:function(){return this.doc.getNewLineMode()},handlesSet:!0},mode:{set:function(e){this.setMode(e)},get:function(){return this.$modeId},handlesSet:!0}}),t.EditSession=d}),define("ace/search",["require","exports","module","ace/lib/lang","ace/lib/oop","ace/range"],function(e,t,n){"use strict";function u(e,t){function n(e){return/\w/.test(e)||t.regExp?"\\b":""}return n(e[0])+e+n(e[e.length-1])}var r=e("./lib/lang"),i=e("./lib/oop"),s=e("./range").Range,o=function(){this.$options={}};(function(){this.set=function(e){return i.mixin(this.$options,e),this},this.getOptions=function(){return r.copyObject(this.$options)},this.setOptions=function(e){this.$options=e},this.find=function(e){var t=this.$options,n=this.$matchIterator(e,t);if(!n)return!1;var r=null;return n.forEach(function(e,n,i,o){return r=new s(e,n,i,o),n==o&&t.start&&t.start.start&&t.skipCurrent!=0&&r.isEqual(t.start)?(r=null,!1):!0}),r},this.findAll=function(e){var t=this.$options;if(!t.needle)return[];this.$assembleRegExp(t);var n=t.range,i=n?e.getLines(n.start.row,n.end.row):e.doc.getAllLines(),o=[],u=t.re;if(t.$isMultiLine){var a=u.length,f=i.length-a,l;e:for(var c=u.offset||0;c<=f;c++){for(var h=0;hv)continue;o.push(l=new s(c,v,c+a-1,m)),a>2&&(c=c+a-2)}}else for(var g=0;gE&&o[h].end.row==n.end.row)h--;o=o.slice(g,h+1);for(g=0,h=o.length;g=u;n--)if(c(n,Number.MAX_VALUE,e))return;if(t.wrap==0)return;for(n=a,u=o.row;n>=u;n--)if(c(n,Number.MAX_VALUE,e))return};else var f=function(e){var n=o.row;if(c(n,o.column,e))return;for(n+=1;n<=a;n++)if(c(n,0,e))return;if(t.wrap==0)return;for(n=u,a=o.row;n<=a;n++)if(c(n,0,e))return};if(t.$isMultiLine)var l=n.length,c=function(t,i,s){var o=r?t-l+1:t;if(o<0)return;var u=e.getLine(o),a=u.search(n[0]);if(!r&&ai)return;if(s(o,a,o+l-1,c))return!0};else if(r)var c=function(t,r,i){var s=e.getLine(t),o=[],u,a=0;n.lastIndex=0;while(u=n.exec(s)){var f=u[0].length;a=u.index;if(!f){if(a>=s.length)break;n.lastIndex=a+=1}if(u.index+f>r)break;o.push(u.index,f)}for(var l=o.length-1;l>=0;l-=2){var c=o[l-1],f=o[l];if(i(t,c,t,c+f))return!0}};else var c=function(t,r,i){var s=e.getLine(t),o,u;n.lastIndex=r;while(u=n.exec(s)){var a=u[0].length;o=u.index;if(i(t,o,t,o+a))return!0;if(!a){n.lastIndex=o+=1;if(o>=s.length)return!1}}};return{forEach:f}}}).call(o.prototype),t.Search=o}),define("ace/keyboard/hash_handler",["require","exports","module","ace/lib/keys","ace/lib/useragent"],function(e,t,n){"use strict";function o(e,t){this.platform=t||(i.isMac?"mac":"win"),this.commands={},this.commandKeyBinding={},this.addCommands(e),this.$singleCommand=!0}function u(e,t){o.call(this,e,t),this.$singleCommand=!1}var r=e("../lib/keys"),i=e("../lib/useragent"),s=r.KEY_MODS;u.prototype=o.prototype,function(){function e(e){return typeof e=="object"&&e.bindKey&&e.bindKey.position||(e.isDefault?-100:0)}this.addCommand=function(e){this.commands[e.name]&&this.removeCommand(e),this.commands[e.name]=e,e.bindKey&&this._buildKeyHash(e)},this.removeCommand=function(e,t){var n=e&&(typeof e=="string"?e:e.name);e=this.commands[n],t||delete this.commands[n];var r=this.commandKeyBinding;for(var i in r){var s=r[i];if(s==e)delete r[i];else if(Array.isArray(s)){var o=s.indexOf(e);o!=-1&&(s.splice(o,1),s.length==1&&(r[i]=s[0]))}}},this.bindKey=function(e,t,n){typeof e=="object"&&e&&(n==undefined&&(n=e.position),e=e[this.platform]);if(!e)return;if(typeof t=="function")return this.addCommand({exec:t,bindKey:e,name:t.name||e});e.split("|").forEach(function(e){var r="";if(e.indexOf(" ")!=-1){var i=e.split(/\s+/);e=i.pop(),i.forEach(function(e){var t=this.parseKeys(e),n=s[t.hashId]+t.key;r+=(r?" ":"")+n,this._addCommandToBinding(r,"chainKeys")},this),r+=" "}var o=this.parseKeys(e),u=s[o.hashId]+o.key;this._addCommandToBinding(r+u,t,n)},this)},this._addCommandToBinding=function(t,n,r){var i=this.commandKeyBinding,s;if(!n)delete i[t];else if(!i[t]||this.$singleCommand)i[t]=n;else{Array.isArray(i[t])?(s=i[t].indexOf(n))!=-1&&i[t].splice(s,1):i[t]=[i[t]],typeof r!="number"&&(r=e(n));var o=i[t];for(s=0;sr)break}o.splice(s,0,n)}},this.addCommands=function(e){e&&Object.keys(e).forEach(function(t){var n=e[t];if(!n)return;if(typeof n=="string")return this.bindKey(n,t);typeof n=="function"&&(n={exec:n});if(typeof n!="object")return;n.name||(n.name=t),this.addCommand(n)},this)},this.removeCommands=function(e){Object.keys(e).forEach(function(t){this.removeCommand(e[t])},this)},this.bindKeys=function(e){Object.keys(e).forEach(function(t){this.bindKey(t,e[t])},this)},this._buildKeyHash=function(e){this.bindKey(e.bindKey,e)},this.parseKeys=function(e){var t=e.toLowerCase().split(/[\-\+]([\-\+])?/).filter(function(e){return e}),n=t.pop(),i=r[n];if(r.FUNCTION_KEYS[i])n=r.FUNCTION_KEYS[i].toLowerCase();else{if(!t.length)return{key:n,hashId:-1};if(t.length==1&&t[0]=="shift")return{key:n.toUpperCase(),hashId:-1}}var s=0;for(var o=t.length;o--;){var u=r.KEY_MODS[t[o]];if(u==null)return typeof console!="undefined"&&console.error("invalid modifier "+t[o]+" in "+e),!1;s|=u}return{key:n,hashId:s}},this.findKeyCommand=function(t,n){var r=s[t]+n;return this.commandKeyBinding[r]},this.handleKeyboard=function(e,t,n,r){if(r<0)return;var i=s[t]+n,o=this.commandKeyBinding[i];e.$keyChain&&(e.$keyChain+=" "+i,o=this.commandKeyBinding[e.$keyChain]||o);if(o)if(o=="chainKeys"||o[o.length-1]=="chainKeys")return e.$keyChain=e.$keyChain||i,{command:"null"};if(e.$keyChain)if(!!t&&t!=4||n.length!=1){if(t==-1||r>0)e.$keyChain=""}else e.$keyChain=e.$keyChain.slice(0,-i.length-1);return{command:o}},this.getStatusText=function(e,t){return t.$keyChain||""}}.call(o.prototype),t.HashHandler=o,t.MultiHashHandler=u}),define("ace/commands/command_manager",["require","exports","module","ace/lib/oop","ace/keyboard/hash_handler","ace/lib/event_emitter"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../keyboard/hash_handler").MultiHashHandler,s=e("../lib/event_emitter").EventEmitter,o=function(e,t){i.call(this,t,e),this.byName=this.commands,this.setDefaultHandler("exec",function(e){return e.command.exec(e.editor,e.args||{})})};r.inherits(o,i),function(){r.implement(this,s),this.exec=function(e,t,n){if(Array.isArray(e)){for(var r=e.length;r--;)if(this.exec(e[r],t,n))return!0;return!1}typeof e=="string"&&(e=this.commands[e]);if(!e)return!1;if(t&&t.$readOnly&&!e.readOnly)return!1;if(this.$checkCommandState!=0&&e.isAvailable&&!e.isAvailable(t))return!1;var i={editor:t,command:e,args:n};return i.returnValue=this._emit("exec",i),this._signal("afterExec",i),i.returnValue===!1?!1:!0},this.toggleRecording=function(e){if(this.$inReplay)return;return e&&e._emit("changeStatus"),this.recording?(this.macro.pop(),this.removeEventListener("exec",this.$addCommandToMacro),this.macro.length||(this.macro=this.oldMacro),this.recording=!1):(this.$addCommandToMacro||(this.$addCommandToMacro=function(e){this.macro.push([e.command,e.args])}.bind(this)),this.oldMacro=this.macro,this.macro=[],this.on("exec",this.$addCommandToMacro),this.recording=!0)},this.replay=function(e){if(this.$inReplay||!this.macro)return;if(this.recording)return this.toggleRecording(e);try{this.$inReplay=!0,this.macro.forEach(function(t){typeof t=="string"?this.exec(t,e):this.exec(t[0],e,t[1])},this)}finally{this.$inReplay=!1}},this.trimMacro=function(e){return e.map(function(e){return typeof e[0]!="string"&&(e[0]=e[0].name),e[1]||(e=e[0]),e})}}.call(o.prototype),t.CommandManager=o}),define("ace/commands/default_commands",["require","exports","module","ace/lib/lang","ace/config","ace/range"],function(e,t,n){"use strict";function o(e,t){return{win:e,mac:t}}var r=e("../lib/lang"),i=e("../config"),s=e("../range").Range;t.commands=[{name:"showSettingsMenu",bindKey:o("Ctrl-,","Command-,"),exec:function(e){i.loadModule("ace/ext/settings_menu",function(t){t.init(e),e.showSettingsMenu()})},readOnly:!0},{name:"goToNextError",bindKey:o("Alt-E","F4"),exec:function(e){i.loadModule("./ext/error_marker",function(t){t.showErrorMarker(e,1)})},scrollIntoView:"animate",readOnly:!0},{name:"goToPreviousError",bindKey:o("Alt-Shift-E","Shift-F4"),exec:function(e){i.loadModule("./ext/error_marker",function(t){t.showErrorMarker(e,-1)})},scrollIntoView:"animate",readOnly:!0},{name:"selectall",description:"Select all",bindKey:o("Ctrl-A","Command-A"),exec:function(e){e.selectAll()},readOnly:!0},{name:"centerselection",description:"Center selection",bindKey:o(null,"Ctrl-L"),exec:function(e){e.centerSelection()},readOnly:!0},{name:"gotoline",description:"Go to line...",bindKey:o("Ctrl-L","Command-L"),exec:function(e,t){typeof t=="number"&&!isNaN(t)&&e.gotoLine(t),e.prompt({$type:"gotoLine"})},readOnly:!0},{name:"fold",bindKey:o("Alt-L|Ctrl-F1","Command-Alt-L|Command-F1"),exec:function(e){e.session.toggleFold(!1)},multiSelectAction:"forEach",scrollIntoView:"center",readOnly:!0},{name:"unfold",bindKey:o("Alt-Shift-L|Ctrl-Shift-F1","Command-Alt-Shift-L|Command-Shift-F1"),exec:function(e){e.session.toggleFold(!0)},multiSelectAction:"forEach",scrollIntoView:"center",readOnly:!0},{name:"toggleFoldWidget",bindKey:o("F2","F2"),exec:function(e){e.session.toggleFoldWidget()},multiSelectAction:"forEach",scrollIntoView:"center",readOnly:!0},{name:"toggleParentFoldWidget",bindKey:o("Alt-F2","Alt-F2"),exec:function(e){e.session.toggleFoldWidget(!0)},multiSelectAction:"forEach",scrollIntoView:"center",readOnly:!0},{name:"foldall",description:"Fold all",bindKey:o(null,"Ctrl-Command-Option-0"),exec:function(e){e.session.foldAll()},scrollIntoView:"center",readOnly:!0},{name:"foldOther",description:"Fold other",bindKey:o("Alt-0","Command-Option-0"),exec:function(e){e.session.foldAll(),e.session.unfold(e.selection.getAllRanges())},scrollIntoView:"center",readOnly:!0},{name:"unfoldall",description:"Unfold all",bindKey:o("Alt-Shift-0","Command-Option-Shift-0"),exec:function(e){e.session.unfold()},scrollIntoView:"center",readOnly:!0},{name:"findnext",description:"Find next",bindKey:o("Ctrl-K","Command-G"),exec:function(e){e.findNext()},multiSelectAction:"forEach",scrollIntoView:"center",readOnly:!0},{name:"findprevious",description:"Find previous",bindKey:o("Ctrl-Shift-K","Command-Shift-G"),exec:function(e){e.findPrevious()},multiSelectAction:"forEach",scrollIntoView:"center",readOnly:!0},{name:"selectOrFindNext",description:"Select or find next",bindKey:o("Alt-K","Ctrl-G"),exec:function(e){e.selection.isEmpty()?e.selection.selectWord():e.findNext()},readOnly:!0},{name:"selectOrFindPrevious",description:"Select or find previous",bindKey:o("Alt-Shift-K","Ctrl-Shift-G"),exec:function(e){e.selection.isEmpty()?e.selection.selectWord():e.findPrevious()},readOnly:!0},{name:"find",description:"Find",bindKey:o("Ctrl-F","Command-F"),exec:function(e){i.loadModule("ace/ext/searchbox",function(t){t.Search(e)})},readOnly:!0},{name:"overwrite",description:"Overwrite",bindKey:"Insert",exec:function(e){e.toggleOverwrite()},readOnly:!0},{name:"selecttostart",description:"Select to start",bindKey:o("Ctrl-Shift-Home","Command-Shift-Home|Command-Shift-Up"),exec:function(e){e.getSelection().selectFileStart()},multiSelectAction:"forEach",readOnly:!0,scrollIntoView:"animate",aceCommandGroup:"fileJump"},{name:"gotostart",description:"Go to start",bindKey:o("Ctrl-Home","Command-Home|Command-Up"),exec:function(e){e.navigateFileStart()},multiSelectAction:"forEach",readOnly:!0,scrollIntoView:"animate",aceCommandGroup:"fileJump"},{name:"selectup",description:"Select up",bindKey:o("Shift-Up","Shift-Up|Ctrl-Shift-P"),exec:function(e){e.getSelection().selectUp()},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"golineup",description:"Go line up",bindKey:o("Up","Up|Ctrl-P"),exec:function(e,t){e.navigateUp(t.times)},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"selecttoend",description:"Select to end",bindKey:o("Ctrl-Shift-End","Command-Shift-End|Command-Shift-Down"),exec:function(e){e.getSelection().selectFileEnd()},multiSelectAction:"forEach",readOnly:!0,scrollIntoView:"animate",aceCommandGroup:"fileJump"},{name:"gotoend",description:"Go to end",bindKey:o("Ctrl-End","Command-End|Command-Down"),exec:function(e){e.navigateFileEnd()},multiSelectAction:"forEach",readOnly:!0,scrollIntoView:"animate",aceCommandGroup:"fileJump"},{name:"selectdown",description:"Select down",bindKey:o("Shift-Down","Shift-Down|Ctrl-Shift-N"),exec:function(e){e.getSelection().selectDown()},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"golinedown",description:"Go line down",bindKey:o("Down","Down|Ctrl-N"),exec:function(e,t){e.navigateDown(t.times)},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"selectwordleft",description:"Select word left",bindKey:o("Ctrl-Shift-Left","Option-Shift-Left"),exec:function(e){e.getSelection().selectWordLeft()},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"gotowordleft",description:"Go to word left",bindKey:o("Ctrl-Left","Option-Left"),exec:function(e){e.navigateWordLeft()},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"selecttolinestart",description:"Select to line start",bindKey:o("Alt-Shift-Left","Command-Shift-Left|Ctrl-Shift-A"),exec:function(e){e.getSelection().selectLineStart()},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"gotolinestart",description:"Go to line start",bindKey:o("Alt-Left|Home","Command-Left|Home|Ctrl-A"),exec:function(e){e.navigateLineStart()},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"selectleft",description:"Select left",bindKey:o("Shift-Left","Shift-Left|Ctrl-Shift-B"),exec:function(e){e.getSelection().selectLeft()},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"gotoleft",description:"Go to left",bindKey:o("Left","Left|Ctrl-B"),exec:function(e,t){e.navigateLeft(t.times)},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"selectwordright",description:"Select word right",bindKey:o("Ctrl-Shift-Right","Option-Shift-Right"),exec:function(e){e.getSelection().selectWordRight()},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"gotowordright",description:"Go to word right",bindKey:o("Ctrl-Right","Option-Right"),exec:function(e){e.navigateWordRight()},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"selecttolineend",description:"Select to line end",bindKey:o("Alt-Shift-Right","Command-Shift-Right|Shift-End|Ctrl-Shift-E"),exec:function(e){e.getSelection().selectLineEnd()},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"gotolineend",description:"Go to line end",bindKey:o("Alt-Right|End","Command-Right|End|Ctrl-E"),exec:function(e){e.navigateLineEnd()},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"selectright",description:"Select right",bindKey:o("Shift-Right","Shift-Right"),exec:function(e){e.getSelection().selectRight()},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"gotoright",description:"Go to right",bindKey:o("Right","Right|Ctrl-F"),exec:function(e,t){e.navigateRight(t.times)},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"selectpagedown",description:"Select page down",bindKey:"Shift-PageDown",exec:function(e){e.selectPageDown()},readOnly:!0},{name:"pagedown",description:"Page down",bindKey:o(null,"Option-PageDown"),exec:function(e){e.scrollPageDown()},readOnly:!0},{name:"gotopagedown",description:"Go to page down",bindKey:o("PageDown","PageDown|Ctrl-V"),exec:function(e){e.gotoPageDown()},readOnly:!0},{name:"selectpageup",description:"Select page up",bindKey:"Shift-PageUp",exec:function(e){e.selectPageUp()},readOnly:!0},{name:"pageup",description:"Page up",bindKey:o(null,"Option-PageUp"),exec:function(e){e.scrollPageUp()},readOnly:!0},{name:"gotopageup",description:"Go to page up",bindKey:"PageUp",exec:function(e){e.gotoPageUp()},readOnly:!0},{name:"scrollup",description:"Scroll up",bindKey:o("Ctrl-Up",null),exec:function(e){e.renderer.scrollBy(0,-2*e.renderer.layerConfig.lineHeight)},readOnly:!0},{name:"scrolldown",description:"Scroll down",bindKey:o("Ctrl-Down",null),exec:function(e){e.renderer.scrollBy(0,2*e.renderer.layerConfig.lineHeight)},readOnly:!0},{name:"selectlinestart",description:"Select line start",bindKey:"Shift-Home",exec:function(e){e.getSelection().selectLineStart()},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"selectlineend",description:"Select line end",bindKey:"Shift-End",exec:function(e){e.getSelection().selectLineEnd()},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"togglerecording",description:"Toggle recording",bindKey:o("Ctrl-Alt-E","Command-Option-E"),exec:function(e){e.commands.toggleRecording(e)},readOnly:!0},{name:"replaymacro",description:"Replay macro",bindKey:o("Ctrl-Shift-E","Command-Shift-E"),exec:function(e){e.commands.replay(e)},readOnly:!0},{name:"jumptomatching",description:"Jump to matching",bindKey:o("Ctrl-\\|Ctrl-P","Command-\\"),exec:function(e){e.jumpToMatching()},multiSelectAction:"forEach",scrollIntoView:"animate",readOnly:!0},{name:"selecttomatching",description:"Select to matching",bindKey:o("Ctrl-Shift-\\|Ctrl-Shift-P","Command-Shift-\\"),exec:function(e){e.jumpToMatching(!0)},multiSelectAction:"forEach",scrollIntoView:"animate",readOnly:!0},{name:"expandToMatching",description:"Expand to matching",bindKey:o("Ctrl-Shift-M","Ctrl-Shift-M"),exec:function(e){e.jumpToMatching(!0,!0)},multiSelectAction:"forEach",scrollIntoView:"animate",readOnly:!0},{name:"passKeysToBrowser",description:"Pass keys to browser",bindKey:o(null,null),exec:function(){},passEvent:!0,readOnly:!0},{name:"copy",description:"Copy",exec:function(e){},readOnly:!0},{name:"cut",description:"Cut",exec:function(e){var t=e.$copyWithEmptySelection&&e.selection.isEmpty(),n=t?e.selection.getLineRange():e.selection.getRange();e._emit("cut",n),n.isEmpty()||e.session.remove(n),e.clearSelection()},scrollIntoView:"cursor",multiSelectAction:"forEach"},{name:"paste",description:"Paste",exec:function(e,t){e.$handlePaste(t)},scrollIntoView:"cursor"},{name:"removeline",description:"Remove line",bindKey:o("Ctrl-D","Command-D"),exec:function(e){e.removeLines()},scrollIntoView:"cursor",multiSelectAction:"forEachLine"},{name:"duplicateSelection",description:"Duplicate selection",bindKey:o("Ctrl-Shift-D","Command-Shift-D"),exec:function(e){e.duplicateSelection()},scrollIntoView:"cursor",multiSelectAction:"forEach"},{name:"sortlines",description:"Sort lines",bindKey:o("Ctrl-Alt-S","Command-Alt-S"),exec:function(e){e.sortLines()},scrollIntoView:"selection",multiSelectAction:"forEachLine"},{name:"togglecomment",description:"Toggle comment",bindKey:o("Ctrl-/","Command-/"),exec:function(e){e.toggleCommentLines()},multiSelectAction:"forEachLine",scrollIntoView:"selectionPart"},{name:"toggleBlockComment",description:"Toggle block comment",bindKey:o("Ctrl-Shift-/","Command-Shift-/"),exec:function(e){e.toggleBlockComment()},multiSelectAction:"forEach",scrollIntoView:"selectionPart"},{name:"modifyNumberUp",description:"Modify number up",bindKey:o("Ctrl-Shift-Up","Alt-Shift-Up"),exec:function(e){e.modifyNumber(1)},scrollIntoView:"cursor",multiSelectAction:"forEach"},{name:"modifyNumberDown",description:"Modify number down",bindKey:o("Ctrl-Shift-Down","Alt-Shift-Down"),exec:function(e){e.modifyNumber(-1)},scrollIntoView:"cursor",multiSelectAction:"forEach"},{name:"replace",description:"Replace",bindKey:o("Ctrl-H","Command-Option-F"),exec:function(e){i.loadModule("ace/ext/searchbox",function(t){t.Search(e,!0)})}},{name:"undo",description:"Undo",bindKey:o("Ctrl-Z","Command-Z"),exec:function(e){e.undo()}},{name:"redo",description:"Redo",bindKey:o("Ctrl-Shift-Z|Ctrl-Y","Command-Shift-Z|Command-Y"),exec:function(e){e.redo()}},{name:"copylinesup",description:"Copy lines up",bindKey:o("Alt-Shift-Up","Command-Option-Up"),exec:function(e){e.copyLinesUp()},scrollIntoView:"cursor"},{name:"movelinesup",description:"Move lines up",bindKey:o("Alt-Up","Option-Up"),exec:function(e){e.moveLinesUp()},scrollIntoView:"cursor"},{name:"copylinesdown",description:"Copy lines down",bindKey:o("Alt-Shift-Down","Command-Option-Down"),exec:function(e){e.copyLinesDown()},scrollIntoView:"cursor"},{name:"movelinesdown",description:"Move lines down",bindKey:o("Alt-Down","Option-Down"),exec:function(e){e.moveLinesDown()},scrollIntoView:"cursor"},{name:"del",description:"Delete",bindKey:o("Delete","Delete|Ctrl-D|Shift-Delete"),exec:function(e){e.remove("right")},multiSelectAction:"forEach",scrollIntoView:"cursor"},{name:"backspace",description:"Backspace",bindKey:o("Shift-Backspace|Backspace","Ctrl-Backspace|Shift-Backspace|Backspace|Ctrl-H"),exec:function(e){e.remove("left")},multiSelectAction:"forEach",scrollIntoView:"cursor"},{name:"cut_or_delete",description:"Cut or delete",bindKey:o("Shift-Delete",null),exec:function(e){if(!e.selection.isEmpty())return!1;e.remove("left")},multiSelectAction:"forEach",scrollIntoView:"cursor"},{name:"removetolinestart",description:"Remove to line start",bindKey:o("Alt-Backspace","Command-Backspace"),exec:function(e){e.removeToLineStart()},multiSelectAction:"forEach",scrollIntoView:"cursor"},{name:"removetolineend",description:"Remove to line end",bindKey:o("Alt-Delete","Ctrl-K|Command-Delete"),exec:function(e){e.removeToLineEnd()},multiSelectAction:"forEach",scrollIntoView:"cursor"},{name:"removetolinestarthard",description:"Remove to line start hard",bindKey:o("Ctrl-Shift-Backspace",null),exec:function(e){var t=e.selection.getRange();t.start.column=0,e.session.remove(t)},multiSelectAction:"forEach",scrollIntoView:"cursor"},{name:"removetolineendhard",description:"Remove to line end hard",bindKey:o("Ctrl-Shift-Delete",null),exec:function(e){var t=e.selection.getRange();t.end.column=Number.MAX_VALUE,e.session.remove(t)},multiSelectAction:"forEach",scrollIntoView:"cursor"},{name:"removewordleft",description:"Remove word left",bindKey:o("Ctrl-Backspace","Alt-Backspace|Ctrl-Alt-Backspace"),exec:function(e){e.removeWordLeft()},multiSelectAction:"forEach",scrollIntoView:"cursor"},{name:"removewordright",description:"Remove word right",bindKey:o("Ctrl-Delete","Alt-Delete"),exec:function(e){e.removeWordRight()},multiSelectAction:"forEach",scrollIntoView:"cursor"},{name:"outdent",description:"Outdent",bindKey:o("Shift-Tab","Shift-Tab"),exec:function(e){e.blockOutdent()},multiSelectAction:"forEach",scrollIntoView:"selectionPart"},{name:"indent",description:"Indent",bindKey:o("Tab","Tab"),exec:function(e){e.indent()},multiSelectAction:"forEach",scrollIntoView:"selectionPart"},{name:"blockoutdent",description:"Block outdent",bindKey:o("Ctrl-[","Ctrl-["),exec:function(e){e.blockOutdent()},multiSelectAction:"forEachLine",scrollIntoView:"selectionPart"},{name:"blockindent",description:"Block indent",bindKey:o("Ctrl-]","Ctrl-]"),exec:function(e){e.blockIndent()},multiSelectAction:"forEachLine",scrollIntoView:"selectionPart"},{name:"insertstring",description:"Insert string",exec:function(e,t){e.insert(t)},multiSelectAction:"forEach",scrollIntoView:"cursor"},{name:"inserttext",description:"Insert text",exec:function(e,t){e.insert(r.stringRepeat(t.text||"",t.times||1))},multiSelectAction:"forEach",scrollIntoView:"cursor"},{name:"splitline",description:"Split line",bindKey:o(null,"Ctrl-O"),exec:function(e){e.splitLine()},multiSelectAction:"forEach",scrollIntoView:"cursor"},{name:"transposeletters",description:"Transpose letters",bindKey:o("Alt-Shift-X","Ctrl-T"),exec:function(e){e.transposeLetters()},multiSelectAction:function(e){e.transposeSelections(1)},scrollIntoView:"cursor"},{name:"touppercase",description:"To uppercase",bindKey:o("Ctrl-U","Ctrl-U"),exec:function(e){e.toUpperCase()},multiSelectAction:"forEach",scrollIntoView:"cursor"},{name:"tolowercase",description:"To lowercase",bindKey:o("Ctrl-Shift-U","Ctrl-Shift-U"),exec:function(e){e.toLowerCase()},multiSelectAction:"forEach",scrollIntoView:"cursor"},{name:"expandtoline",description:"Expand to line",bindKey:o("Ctrl-Shift-L","Command-Shift-L"),exec:function(e){var t=e.selection.getRange();t.start.column=t.end.column=0,t.end.row++,e.selection.setRange(t,!1)},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"joinlines",description:"Join lines",bindKey:o(null,null),exec:function(e){var t=e.selection.isBackwards(),n=t?e.selection.getSelectionLead():e.selection.getSelectionAnchor(),i=t?e.selection.getSelectionAnchor():e.selection.getSelectionLead(),o=e.session.doc.getLine(n.row).length,u=e.session.doc.getTextRange(e.selection.getRange()),a=u.replace(/\n\s*/," ").length,f=e.session.doc.getLine(n.row);for(var l=n.row+1;l<=i.row+1;l++){var c=r.stringTrimLeft(r.stringTrimRight(e.session.doc.getLine(l)));c.length!==0&&(c=" "+c),f+=c}i.row+10?(e.selection.moveCursorTo(n.row,n.column),e.selection.selectTo(n.row,n.column+a)):(o=e.session.doc.getLine(n.row).length>o?o+1:o,e.selection.moveCursorTo(n.row,o))},multiSelectAction:"forEach",readOnly:!0},{name:"invertSelection",description:"Invert selection",bindKey:o(null,null),exec:function(e){var t=e.session.doc.getLength()-1,n=e.session.doc.getLine(t).length,r=e.selection.rangeList.ranges,i=[];r.length<1&&(r=[e.selection.getRange()]);for(var o=0;o=i.lastRow||r.end.row<=i.firstRow)&&this.renderer.scrollSelectionIntoView(this.selection.anchor,this.selection.lead);break;default:}n=="animate"&&this.renderer.animateScrolling(this.curOp.scrollTop)}var s=this.selection.toJSON();this.curOp.selectionAfter=s,this.$lastSel=this.selection.toJSON(),this.session.getUndoManager().addSelection(s),this.prevOp=this.curOp,this.curOp=null}},this.$mergeableCommands=["backspace","del","insertstring"],this.$historyTracker=function(e){if(!this.$mergeUndoDeltas)return;var t=this.prevOp,n=this.$mergeableCommands,r=t.command&&e.command.name==t.command.name;if(e.command.name=="insertstring"){var i=e.args;this.mergeNextCommand===undefined&&(this.mergeNextCommand=!0),r=r&&this.mergeNextCommand&&(!/\s/.test(i)||/\s/.test(t.args)),this.mergeNextCommand=!0}else r=r&&n.indexOf(e.command.name)!==-1;this.$mergeUndoDeltas!="always"&&Date.now()-this.sequenceStartTime>2e3&&(r=!1),r?this.session.mergeUndoDeltas=!0:n.indexOf(e.command.name)!==-1&&(this.sequenceStartTime=Date.now())},this.setKeyboardHandler=function(e,t){if(e&&typeof e=="string"&&e!="ace"){this.$keybindingId=e;var n=this;g.loadModule(["keybinding",e],function(r){n.$keybindingId==e&&n.keyBinding.setKeyboardHandler(r&&r.handler),t&&t()})}else this.$keybindingId=null,this.keyBinding.setKeyboardHandler(e),t&&t()},this.getKeyboardHandler=function(){return this.keyBinding.getKeyboardHandler()},this.setSession=function(e){if(this.session==e)return;this.curOp&&this.endOperation(),this.curOp={};var t=this.session;if(t){this.session.off("change",this.$onDocumentChange),this.session.off("changeMode",this.$onChangeMode),this.session.off("tokenizerUpdate",this.$onTokenizerUpdate),this.session.off("changeTabSize",this.$onChangeTabSize),this.session.off("changeWrapLimit",this.$onChangeWrapLimit),this.session.off("changeWrapMode",this.$onChangeWrapMode),this.session.off("changeFold",this.$onChangeFold),this.session.off("changeFrontMarker",this.$onChangeFrontMarker),this.session.off("changeBackMarker",this.$onChangeBackMarker),this.session.off("changeBreakpoint",this.$onChangeBreakpoint),this.session.off("changeAnnotation",this.$onChangeAnnotation),this.session.off("changeOverwrite",this.$onCursorChange),this.session.off("changeScrollTop",this.$onScrollTopChange),this.session.off("changeScrollLeft",this.$onScrollLeftChange);var n=this.session.getSelection();n.off("changeCursor",this.$onCursorChange),n.off("changeSelection",this.$onSelectionChange)}this.session=e,e?(this.$onDocumentChange=this.onDocumentChange.bind(this),e.on("change",this.$onDocumentChange),this.renderer.setSession(e),this.$onChangeMode=this.onChangeMode.bind(this),e.on("changeMode",this.$onChangeMode),this.$onTokenizerUpdate=this.onTokenizerUpdate.bind(this),e.on("tokenizerUpdate",this.$onTokenizerUpdate),this.$onChangeTabSize=this.renderer.onChangeTabSize.bind(this.renderer),e.on("changeTabSize",this.$onChangeTabSize),this.$onChangeWrapLimit=this.onChangeWrapLimit.bind(this),e.on("changeWrapLimit",this.$onChangeWrapLimit),this.$onChangeWrapMode=this.onChangeWrapMode.bind(this),e.on("changeWrapMode",this.$onChangeWrapMode),this.$onChangeFold=this.onChangeFold.bind(this),e.on("changeFold",this.$onChangeFold),this.$onChangeFrontMarker=this.onChangeFrontMarker.bind(this),this.session.on("changeFrontMarker",this.$onChangeFrontMarker),this.$onChangeBackMarker=this.onChangeBackMarker.bind(this),this.session.on("changeBackMarker",this.$onChangeBackMarker),this.$onChangeBreakpoint=this.onChangeBreakpoint.bind(this),this.session.on("changeBreakpoint",this.$onChangeBreakpoint),this.$onChangeAnnotation=this.onChangeAnnotation.bind(this),this.session.on("changeAnnotation",this.$onChangeAnnotation),this.$onCursorChange=this.onCursorChange.bind(this),this.session.on("changeOverwrite",this.$onCursorChange),this.$onScrollTopChange=this.onScrollTopChange.bind(this),this.session.on("changeScrollTop",this.$onScrollTopChange),this.$onScrollLeftChange=this.onScrollLeftChange.bind(this),this.session.on("changeScrollLeft",this.$onScrollLeftChange),this.selection=e.getSelection(),this.selection.on("changeCursor",this.$onCursorChange),this.$onSelectionChange=this.onSelectionChange.bind(this),this.selection.on("changeSelection",this.$onSelectionChange),this.onChangeMode(),this.onCursorChange(),this.onScrollTopChange(),this.onScrollLeftChange(),this.onSelectionChange(),this.onChangeFrontMarker(),this.onChangeBackMarker(),this.onChangeBreakpoint(),this.onChangeAnnotation(),this.session.getUseWrapMode()&&this.renderer.adjustWrapLimit(),this.renderer.updateFull()):(this.selection=null,this.renderer.setSession(e)),this._signal("changeSession",{session:e,oldSession:t}),this.curOp=null,t&&t._signal("changeEditor",{oldEditor:this}),e&&e._signal("changeEditor",{editor:this}),e&&e.bgTokenizer&&e.bgTokenizer.scheduleStart()},this.getSession=function(){return this.session},this.setValue=function(e,t){return this.session.doc.setValue(e),t?t==1?this.navigateFileEnd():t==-1&&this.navigateFileStart():this.selectAll(),e},this.getValue=function(){return this.session.getValue()},this.getSelection=function(){return this.selection},this.resize=function(e){this.renderer.onResize(e)},this.setTheme=function(e,t){this.renderer.setTheme(e,t)},this.getTheme=function(){return this.renderer.getTheme()},this.setStyle=function(e){this.renderer.setStyle(e)},this.unsetStyle=function(e){this.renderer.unsetStyle(e)},this.getFontSize=function(){return this.getOption("fontSize")||i.computedStyle(this.container).fontSize},this.setFontSize=function(e){this.setOption("fontSize",e)},this.$highlightBrackets=function(){if(this.$highlightPending)return;var e=this;this.$highlightPending=!0,setTimeout(function(){e.$highlightPending=!1;var t=e.session;if(!t||!t.bgTokenizer)return;t.$bracketHighlight&&(t.$bracketHighlight.markerIds.forEach(function(e){t.removeMarker(e)}),t.$bracketHighlight=null);var n=t.getMatchingBracketRanges(e.getCursorPosition());!n&&t.$mode.getMatching&&(n=t.$mode.getMatching(e.session));if(!n)return;var r="ace_bracket";Array.isArray(n)?n.length==1&&(r="ace_error_bracket"):n=[n],n.length==2&&(p.comparePoints(n[0].end,n[1].start)==0?n=[p.fromPoints(n[0].start,n[1].end)]:p.comparePoints(n[0].start,n[1].end)==0&&(n=[p.fromPoints(n[1].start,n[0].end)])),t.$bracketHighlight={ranges:n,markerIds:n.map(function(e){return t.addMarker(e,r,"text")})}},50)},this.$highlightTags=function(){if(this.$highlightTagPending)return;var e=this;this.$highlightTagPending=!0,setTimeout(function(){e.$highlightTagPending=!1;var t=e.session;if(!t||!t.bgTokenizer)return;var n=e.getCursorPosition(),r=new y(e.session,n.row,n.column),i=r.getCurrentToken();if(!i||!/\b(?:tag-open|tag-name)/.test(i.type)){t.removeMarker(t.$tagHighlight),t.$tagHighlight=null;return}if(i.type.indexOf("tag-open")!=-1){i=r.stepForward();if(!i)return}var s=i.value,o=0,u=r.stepBackward();if(u.value=="<"){do u=i,i=r.stepForward(),i&&i.value===s&&i.type.indexOf("tag-name")!==-1&&(u.value==="<"?o++:u.value==="=0)}else{do i=u,u=r.stepBackward(),i&&i.value===s&&i.type.indexOf("tag-name")!==-1&&(u.value==="<"?o++:u.value==="1)&&(t=!1)}if(e.$highlightLineMarker&&!t)e.removeMarker(e.$highlightLineMarker.id),e.$highlightLineMarker=null;else if(!e.$highlightLineMarker&&t){var n=new p(t.row,t.column,t.row,Infinity);n.id=e.addMarker(n,"ace_active-line","screenLine"),e.$highlightLineMarker=n}else t&&(e.$highlightLineMarker.start.row=t.row,e.$highlightLineMarker.end.row=t.row,e.$highlightLineMarker.start.column=t.column,e._signal("changeBackMarker"))},this.onSelectionChange=function(e){var t=this.session;t.$selectionMarker&&t.removeMarker(t.$selectionMarker),t.$selectionMarker=null;if(!this.selection.isEmpty()){var n=this.selection.getRange(),r=this.getSelectionStyle();t.$selectionMarker=t.addMarker(n,"ace_selection",r)}else this.$updateHighlightActiveLine();var i=this.$highlightSelectedWord&&this.$getSelectionHighLightRegexp();this.session.highlight(i),this._signal("changeSelection")},this.$getSelectionHighLightRegexp=function(){var e=this.session,t=this.getSelectionRange();if(t.isEmpty()||t.isMultiLine())return;var n=t.start.column,r=t.end.column,i=e.getLine(t.start.row),s=i.substring(n,r);if(s.length>5e3||!/[\w\d]/.test(s))return;var o=this.$search.$assembleRegExp({wholeWord:!0,caseSensitive:!0,needle:s}),u=i.substring(n-1,r+1);if(!o.test(u))return;return o},this.onChangeFrontMarker=function(){this.renderer.updateFrontMarkers()},this.onChangeBackMarker=function(){this.renderer.updateBackMarkers()},this.onChangeBreakpoint=function(){this.renderer.updateBreakpoints()},this.onChangeAnnotation=function(){this.renderer.setAnnotations(this.session.getAnnotations())},this.onChangeMode=function(e){this.renderer.updateText(),this._emit("changeMode",e)},this.onChangeWrapLimit=function(){this.renderer.updateFull()},this.onChangeWrapMode=function(){this.renderer.onResize(!0)},this.onChangeFold=function(){this.$updateHighlightActiveLine(),this.renderer.updateFull()},this.getSelectedText=function(){return this.session.getTextRange(this.getSelectionRange())},this.getCopyText=function(){var e=this.getSelectedText(),t=this.session.doc.getNewLineCharacter(),n=!1;if(!e&&this.$copyWithEmptySelection){n=!0;var r=this.selection.getAllRanges();for(var i=0;iu.search(/\S|$/)){var a=u.substr(i.column).search(/\S|$/);n.doc.removeInLine(i.row,i.column,i.column+a)}}this.clearSelection();var f=i.column,l=n.getState(i.row),u=n.getLine(i.row),c=r.checkOutdent(l,u,e);n.insert(i,e),s&&s.selection&&(s.selection.length==2?this.selection.setSelectionRange(new p(i.row,f+s.selection[0],i.row,f+s.selection[1])):this.selection.setSelectionRange(new p(i.row+s.selection[0],s.selection[1],i.row+s.selection[2],s.selection[3])));if(n.getDocument().isNewLine(e)){var h=r.getNextLineIndent(l,u.slice(0,i.column),n.getTabString());n.insert({row:i.row+1,column:0},h)}c&&r.autoOutdent(l,n,i.row)},this.onTextInput=function(e,t){if(!t)return this.keyBinding.onTextInput(e);this.startOperation({command:{name:"insertstring"}});var n=this.applyComposition.bind(this,e,t);this.selection.rangeCount?this.forEachSelection(n):n(),this.endOperation()},this.applyComposition=function(e,t){if(t.extendLeft||t.extendRight){var n=this.selection.getRange();n.start.column-=t.extendLeft,n.end.column+=t.extendRight,this.selection.setRange(n),!e&&!n.isEmpty()&&this.remove()}(e||!this.selection.isEmpty())&&this.insert(e,!0);if(t.restoreStart||t.restoreEnd){var n=this.selection.getRange();n.start.column-=t.restoreStart,n.end.column-=t.restoreEnd,this.selection.setRange(n)}},this.onCommandKey=function(e,t,n){return this.keyBinding.onCommandKey(e,t,n)},this.setOverwrite=function(e){this.session.setOverwrite(e)},this.getOverwrite=function(){return this.session.getOverwrite()},this.toggleOverwrite=function(){this.session.toggleOverwrite()},this.setScrollSpeed=function(e){this.setOption("scrollSpeed",e)},this.getScrollSpeed=function(){return this.getOption("scrollSpeed")},this.setDragDelay=function(e){this.setOption("dragDelay",e)},this.getDragDelay=function(){return this.getOption("dragDelay")},this.setSelectionStyle=function(e){this.setOption("selectionStyle",e)},this.getSelectionStyle=function(){return this.getOption("selectionStyle")},this.setHighlightActiveLine=function(e){this.setOption("highlightActiveLine",e)},this.getHighlightActiveLine=function(){return this.getOption("highlightActiveLine")},this.setHighlightGutterLine=function(e){this.setOption("highlightGutterLine",e)},this.getHighlightGutterLine=function(){return this.getOption("highlightGutterLine")},this.setHighlightSelectedWord=function(e){this.setOption("highlightSelectedWord",e)},this.getHighlightSelectedWord=function(){return this.$highlightSelectedWord},this.setAnimatedScroll=function(e){this.renderer.setAnimatedScroll(e)},this.getAnimatedScroll=function(){return this.renderer.getAnimatedScroll()},this.setShowInvisibles=function(e){this.renderer.setShowInvisibles(e)},this.getShowInvisibles=function(){return this.renderer.getShowInvisibles()},this.setDisplayIndentGuides=function(e){this.renderer.setDisplayIndentGuides(e)},this.getDisplayIndentGuides=function(){return this.renderer.getDisplayIndentGuides()},this.setShowPrintMargin=function(e){this.renderer.setShowPrintMargin(e)},this.getShowPrintMargin=function(){return this.renderer.getShowPrintMargin()},this.setPrintMarginColumn=function(e){this.renderer.setPrintMarginColumn(e)},this.getPrintMarginColumn=function(){return this.renderer.getPrintMarginColumn()},this.setReadOnly=function(e){this.setOption("readOnly",e)},this.getReadOnly=function(){return this.getOption("readOnly")},this.setBehavioursEnabled=function(e){this.setOption("behavioursEnabled",e)},this.getBehavioursEnabled=function(){return this.getOption("behavioursEnabled")},this.setWrapBehavioursEnabled=function(e){this.setOption("wrapBehavioursEnabled",e)},this.getWrapBehavioursEnabled=function(){return this.getOption("wrapBehavioursEnabled")},this.setShowFoldWidgets=function(e){this.setOption("showFoldWidgets",e)},this.getShowFoldWidgets=function(){return this.getOption("showFoldWidgets")},this.setFadeFoldWidgets=function(e){this.setOption("fadeFoldWidgets",e)},this.getFadeFoldWidgets=function(){return this.getOption("fadeFoldWidgets")},this.remove=function(e){this.selection.isEmpty()&&(e=="left"?this.selection.selectLeft():this.selection.selectRight());var t=this.getSelectionRange();if(this.getBehavioursEnabled()){var n=this.session,r=n.getState(t.start.row),i=n.getMode().transformAction(r,"deletion",this,n,t);if(t.end.column===0){var s=n.getTextRange(t);if(s[s.length-1]=="\n"){var o=n.getLine(t.end.row);/^\s+$/.test(o)&&(t.end.column=o.length)}}i&&(t=i)}this.session.remove(t),this.clearSelection()},this.removeWordRight=function(){this.selection.isEmpty()&&this.selection.selectWordRight(),this.session.remove(this.getSelectionRange()),this.clearSelection()},this.removeWordLeft=function(){this.selection.isEmpty()&&this.selection.selectWordLeft(),this.session.remove(this.getSelectionRange()),this.clearSelection()},this.removeToLineStart=function(){this.selection.isEmpty()&&this.selection.selectLineStart(),this.selection.isEmpty()&&this.selection.selectLeft(),this.session.remove(this.getSelectionRange()),this.clearSelection()},this.removeToLineEnd=function(){this.selection.isEmpty()&&this.selection.selectLineEnd();var e=this.getSelectionRange();e.start.column==e.end.column&&e.start.row==e.end.row&&(e.end.column=0,e.end.row++),this.session.remove(e),this.clearSelection()},this.splitLine=function(){this.selection.isEmpty()||(this.session.remove(this.getSelectionRange()),this.clearSelection());var e=this.getCursorPosition();this.insert("\n"),this.moveCursorToPosition(e)},this.transposeLetters=function(){if(!this.selection.isEmpty())return;var e=this.getCursorPosition(),t=e.column;if(t===0)return;var n=this.session.getLine(e.row),r,i;tt.toLowerCase()?1:0});var i=new p(0,0,0,0);for(var r=e.first;r<=e.last;r++){var s=t.getLine(r);i.start.row=r,i.end.row=r,i.end.column=s.length,t.replace(i,n[r-e.first])}},this.toggleCommentLines=function(){var e=this.session.getState(this.getCursorPosition().row),t=this.$getSelectedRows();this.session.getMode().toggleCommentLines(e,this.session,t.first,t.last)},this.toggleBlockComment=function(){var e=this.getCursorPosition(),t=this.session.getState(e.row),n=this.getSelectionRange();this.session.getMode().toggleBlockComment(t,this.session,n,e)},this.getNumberAt=function(e,t){var n=/[\-]?[0-9]+(?:\.[0-9]+)?/g;n.lastIndex=0;var r=this.session.getLine(e);while(n.lastIndex=t){var s={value:i[0],start:i.index,end:i.index+i[0].length};return s}}return null},this.modifyNumber=function(e){var t=this.selection.getCursor().row,n=this.selection.getCursor().column,r=new p(t,n-1,t,n),i=this.session.getTextRange(r);if(!isNaN(parseFloat(i))&&isFinite(i)){var s=this.getNumberAt(t,n);if(s){var o=s.value.indexOf(".")>=0?s.start+s.value.indexOf(".")+1:s.end,u=s.start+s.value.length-o,a=parseFloat(s.value);a*=Math.pow(10,u),o!==s.end&&n=u&&o<=a&&(n=t,f.selection.clearSelection(),f.moveCursorTo(e,u+r),f.selection.selectTo(e,a+r)),u=a});var l=this.$toggleWordPairs,c;for(var h=0;hp+1)break;p=d.last}l--,u=this.session.$moveLines(h,p,t?0:e),t&&e==-1&&(c=l+1);while(c<=l)o[c].moveBy(u,0),c++;t||(u=0),a+=u}i.fromOrientedRange(i.ranges[0]),i.rangeList.attach(this.session),this.inVirtualSelectionMode=!1}},this.$getSelectedRows=function(e){return e=(e||this.getSelectionRange()).collapseRows(),{first:this.session.getRowFoldStart(e.start.row),last:this.session.getRowFoldEnd(e.end.row)}},this.onCompositionStart=function(e){this.renderer.showComposition(e)},this.onCompositionUpdate=function(e){this.renderer.setCompositionText(e)},this.onCompositionEnd=function(){this.renderer.hideComposition()},this.getFirstVisibleRow=function(){return this.renderer.getFirstVisibleRow()},this.getLastVisibleRow=function(){return this.renderer.getLastVisibleRow()},this.isRowVisible=function(e){return e>=this.getFirstVisibleRow()&&e<=this.getLastVisibleRow()},this.isRowFullyVisible=function(e){return e>=this.renderer.getFirstFullyVisibleRow()&&e<=this.renderer.getLastFullyVisibleRow()},this.$getVisibleRowCount=function(){return this.renderer.getScrollBottomRow()-this.renderer.getScrollTopRow()+1},this.$moveByPage=function(e,t){var n=this.renderer,r=this.renderer.layerConfig,i=e*Math.floor(r.height/r.lineHeight);t===!0?this.selection.$moveSelection(function(){this.moveCursorBy(i,0)}):t===!1&&(this.selection.moveCursorBy(i,0),this.selection.clearSelection());var s=n.scrollTop;n.scrollBy(0,i*r.lineHeight),t!=null&&n.scrollCursorIntoView(null,.5),n.animateScrolling(s)},this.selectPageDown=function(){this.$moveByPage(1,!0)},this.selectPageUp=function(){this.$moveByPage(-1,!0)},this.gotoPageDown=function(){this.$moveByPage(1,!1)},this.gotoPageUp=function(){this.$moveByPage(-1,!1)},this.scrollPageDown=function(){this.$moveByPage(1)},this.scrollPageUp=function(){this.$moveByPage(-1)},this.scrollToRow=function(e){this.renderer.scrollToRow(e)},this.scrollToLine=function(e,t,n,r){this.renderer.scrollToLine(e,t,n,r)},this.centerSelection=function(){var e=this.getSelectionRange(),t={row:Math.floor(e.start.row+(e.end.row-e.start.row)/2),column:Math.floor(e.start.column+(e.end.column-e.start.column)/2)};this.renderer.alignCursor(t,.5)},this.getCursorPosition=function(){return this.selection.getCursor()},this.getCursorPositionScreen=function(){return this.session.documentToScreenPosition(this.getCursorPosition())},this.getSelectionRange=function(){return this.selection.getRange()},this.selectAll=function(){this.selection.selectAll()},this.clearSelection=function(){this.selection.clearSelection()},this.moveCursorTo=function(e,t){this.selection.moveCursorTo(e,t)},this.moveCursorToPosition=function(e){this.selection.moveCursorToPosition(e)},this.jumpToMatching=function(e,t){var n=this.getCursorPosition(),r=new y(this.session,n.row,n.column),i=r.getCurrentToken(),s=i||r.stepForward();if(!s)return;var o,u=!1,a={},f=n.column-s.start,l,c={")":"(","(":"(","]":"[","[":"[","{":"{","}":"{"};do{if(s.value.match(/[{}()\[\]]/g))for(;f=0;--s)this.$tryReplace(n[s],e)&&r++;return this.selection.setSelectionRange(i),r},this.$tryReplace=function(e,t){var n=this.session.getTextRange(e);return t=this.$search.replace(n,t),t!==null?(e.end=this.session.replace(e,t),e):null},this.getLastSearchOptions=function(){return this.$search.getOptions()},this.find=function(e,t,n){t||(t={}),typeof e=="string"||e instanceof RegExp?t.needle=e:typeof e=="object"&&r.mixin(t,e);var i=this.selection.getRange();t.needle==null&&(e=this.session.getTextRange(i)||this.$search.$options.needle,e||(i=this.session.getWordRange(i.start.row,i.start.column),e=this.session.getTextRange(i)),this.$search.set({needle:e})),this.$search.set(t),t.start||this.$search.set({start:i});var s=this.$search.find(this.session);if(t.preventScroll)return s;if(s)return this.revealRange(s,n),s;t.backwards?i.start=i.end:i.end=i.start,this.selection.setRange(i)},this.findNext=function(e,t){this.find({skipCurrent:!0,backwards:!1},e,t)},this.findPrevious=function(e,t){this.find(e,{skipCurrent:!0,backwards:!0},t)},this.revealRange=function(e,t){this.session.unfold(e),this.selection.setSelectionRange(e);var n=this.renderer.scrollTop;this.renderer.scrollSelectionIntoView(e.start,e.end,.5),t!==!1&&this.renderer.animateScrolling(n)},this.undo=function(){this.session.getUndoManager().undo(this.session),this.renderer.scrollCursorIntoView(null,.5)},this.redo=function(){this.session.getUndoManager().redo(this.session),this.renderer.scrollCursorIntoView(null,.5)},this.destroy=function(){this.renderer.destroy(),this._signal("destroy",this),this.session&&this.session.destroy(),this._$emitInputEvent&&this._$emitInputEvent.cancel(),this.session=null},this.setAutoScrollEditorIntoView=function(e){if(!e)return;var t,n=this,r=!1;this.$scrollAnchor||(this.$scrollAnchor=document.createElement("div"));var i=this.$scrollAnchor;i.style.cssText="position:absolute",this.container.insertBefore(i,this.container.firstChild);var s=this.on("changeSelection",function(){r=!0}),o=this.renderer.on("beforeRender",function(){r&&(t=n.renderer.container.getBoundingClientRect())}),u=this.renderer.on("afterRender",function(){if(r&&t&&(n.isFocused()||n.searchBox&&n.searchBox.isFocused())){var e=n.renderer,s=e.$cursorLayer.$pixelPos,o=e.layerConfig,u=s.top-o.offset;s.top>=0&&u+t.top<0?r=!0:s.topwindow.innerHeight?r=!1:r=null,r!=null&&(i.style.top=u+"px",i.style.left=s.left+"px",i.style.height=o.lineHeight+"px",i.scrollIntoView(r)),r=t=null}});this.setAutoScrollEditorIntoView=function(e){if(e)return;delete this.setAutoScrollEditorIntoView,this.off("changeSelection",s),this.renderer.off("afterRender",u),this.renderer.off("beforeRender",o)}},this.$resetCursorStyle=function(){var e=this.$cursorStyle||"ace",t=this.renderer.$cursorLayer;if(!t)return;t.setSmoothBlinking(/smooth/.test(e)),t.isBlinking=!this.$readOnly&&e!="wide",i.setCssClass(t.element,"ace_slim-cursors",/slim/.test(e))},this.prompt=function(e,t,n){var r=this;g.loadModule("./ext/prompt",function(i){i.prompt(r,e,t,n)})}}.call(w.prototype),g.defineOptions(w.prototype,"editor",{selectionStyle:{set:function(e){this.onSelectionChange(),this._signal("changeSelectionStyle",{data:e})},initialValue:"line"},highlightActiveLine:{set:function(){this.$updateHighlightActiveLine()},initialValue:!0},highlightSelectedWord:{set:function(e){this.$onSelectionChange()},initialValue:!0},readOnly:{set:function(e){this.textInput.setReadOnly(e),this.$resetCursorStyle()},initialValue:!1},copyWithEmptySelection:{set:function(e){this.textInput.setCopyWithEmptySelection(e)},initialValue:!1},cursorStyle:{set:function(e){this.$resetCursorStyle()},values:["ace","slim","smooth","wide"],initialValue:"ace"},mergeUndoDeltas:{values:[!1,!0,"always"],initialValue:!0},behavioursEnabled:{initialValue:!0},wrapBehavioursEnabled:{initialValue:!0},autoScrollEditorIntoView:{set:function(e){this.setAutoScrollEditorIntoView(e)}},keyboardHandler:{set:function(e){this.setKeyboardHandler(e)},get:function(){return this.$keybindingId},handlesSet:!0},value:{set:function(e){this.session.setValue(e)},get:function(){return this.getValue()},handlesSet:!0,hidden:!0},session:{set:function(e){this.setSession(e)},get:function(){return this.session},handlesSet:!0,hidden:!0},showLineNumbers:{set:function(e){this.renderer.$gutterLayer.setShowLineNumbers(e),this.renderer.$loop.schedule(this.renderer.CHANGE_GUTTER),e&&this.$relativeLineNumbers?E.attach(this):E.detach(this)},initialValue:!0},relativeLineNumbers:{set:function(e){this.$showLineNumbers&&e?E.attach(this):E.detach(this)}},placeholder:{set:function(e){this.$updatePlaceholder||(this.$updatePlaceholder=function(){var e=this.renderer.$composition||this.getValue();if(e&&this.renderer.placeholderNode)this.renderer.off("afterRender",this.$updatePlaceholder),i.removeCssClass(this.container,"ace_hasPlaceholder"),this.renderer.placeholderNode.remove(),this.renderer.placeholderNode=null;else if(!e&&!this.renderer.placeholderNode){this.renderer.on("afterRender",this.$updatePlaceholder),i.addCssClass(this.container,"ace_hasPlaceholder");var t=i.createElement("div");t.className="ace_placeholder",t.textContent=this.$placeholder||"",this.renderer.placeholderNode=t,this.renderer.content.appendChild(this.renderer.placeholderNode)}}.bind(this),this.on("input",this.$updatePlaceholder)),this.$updatePlaceholder()}},hScrollBarAlwaysVisible:"renderer",vScrollBarAlwaysVisible:"renderer",highlightGutterLine:"renderer",animatedScroll:"renderer",showInvisibles:"renderer",showPrintMargin:"renderer",printMarginColumn:"renderer",printMargin:"renderer",fadeFoldWidgets:"renderer",showFoldWidgets:"renderer",displayIndentGuides:"renderer",showGutter:"renderer",fontSize:"renderer",fontFamily:"renderer",maxLines:"renderer",minLines:"renderer",scrollPastEnd:"renderer",fixedWidthGutter:"renderer",theme:"renderer",hasCssTransforms:"renderer",maxPixelHeight:"renderer",useTextareaForIME:"renderer",scrollSpeed:"$mouseHandler",dragDelay:"$mouseHandler",dragEnabled:"$mouseHandler",focusTimeout:"$mouseHandler",tooltipFollowsMouse:"$mouseHandler",firstLineNumber:"session",overwrite:"session",newLineMode:"session",useWorker:"session",useSoftTabs:"session",navigateWithinSoftTabs:"session",tabSize:"session",wrap:"session",indentedSoftWrap:"session",foldStyle:"session",mode:"session"});var E={getText:function(e,t){return(Math.abs(e.selection.lead.row-t)||t+1+(t<9?"\u00b7":""))+""},getWidth:function(e,t,n){return Math.max(t.toString().length,(n.lastRow+1).toString().length,2)*n.characterWidth},update:function(e,t){t.renderer.$loop.schedule(t.renderer.CHANGE_GUTTER)},attach:function(e){e.renderer.$gutterLayer.$renderer=this,e.on("changeSelection",this.update),this.update(null,e)},detach:function(e){e.renderer.$gutterLayer.$renderer==this&&(e.renderer.$gutterLayer.$renderer=null),e.off("changeSelection",this.update),this.update(null,e)}};t.Editor=w}),define("ace/undomanager",["require","exports","module","ace/range"],function(e,t,n){"use strict";function i(e,t){for(var n=t;n--;){var r=e[n];if(r&&!r[0].ignore){while(n0){a.row+=i,a.column+=a.row==r.row?s:0;continue}!t&&l<=0&&(a.row=n.row,a.column=n.column,l===0&&(a.bias=1))}}function f(e){return{row:e.row,column:e.column}}function l(e){return{start:f(e.start),end:f(e.end),action:e.action,lines:e.lines.slice()}}function c(e){e=e||this;if(Array.isArray(e))return e.map(c).join("\n");var t="";e.action?(t=e.action=="insert"?"+":"-",t+="["+e.lines+"]"):e.value&&(Array.isArray(e.value)?t=e.value.map(h).join("\n"):t=h(e.value)),e.start&&(t+=h(e));if(e.id||e.rev)t+=" ("+(e.id||e.rev)+")";return t}function h(e){return e.start.row+":"+e.start.column+"=>"+e.end.row+":"+e.end.column}function p(e,t){var n=e.action=="insert",r=t.action=="insert";if(n&&r)if(o(t.start,e.end)>=0)m(t,e,-1);else{if(!(o(t.start,e.start)<=0))return null;m(e,t,1)}else if(n&&!r)if(o(t.start,e.end)>=0)m(t,e,-1);else{if(!(o(t.end,e.start)<=0))return null;m(e,t,-1)}else if(!n&&r)if(o(t.start,e.start)>=0)m(t,e,1);else{if(!(o(t.start,e.start)<=0))return null;m(e,t,1)}else if(!n&&!r)if(o(t.start,e.start)>=0)m(t,e,1);else{if(!(o(t.end,e.start)<=0))return null;m(e,t,-1)}return[t,e]}function d(e,t){for(var n=e.length;n--;)for(var r=0;r=0?m(e,t,-1):o(e.start,t.start)<=0?m(t,e,1):(m(e,s.fromPoints(t.start,e.start),-1),m(t,e,1));else if(!n&&r)o(t.start,e.end)>=0?m(t,e,-1):o(t.start,e.start)<=0?m(e,t,1):(m(t,s.fromPoints(e.start,t.start),-1),m(e,t,1));else if(!n&&!r)if(o(t.start,e.end)>=0)m(t,e,-1);else{if(!(o(t.end,e.start)<=0)){var i,u;return o(e.start,t.start)<0&&(i=e,e=y(e,t.start)),o(e.end,t.end)>0&&(u=y(e,t.end)),g(t.end,e.start,e.end,-1),u&&!i&&(e.lines=u.lines,e.start=u.start,e.end=u.end,u=e),[t,i,u].filter(Boolean)}m(e,t,-1)}return[t,e]}function m(e,t,n){g(e.start,t.start,t.end,n),g(e.end,t.start,t.end,n)}function g(e,t,n,r){e.row==(r==1?t:n).row&&(e.column+=r*(n.column-t.column)),e.row+=r*(n.row-t.row)}function y(e,t){var n=e.lines,r=e.end;e.end=f(t);var i=e.end.row-e.start.row,s=n.splice(i,n.length),o=i?t.column:t.column-e.start.column;n.push(s[0].substring(0,o)),s[0]=s[0].substr(o);var u={start:f(t),end:r,lines:s,action:e.action};return u}function b(e,t){t=l(t);for(var n=e.length;n--;){var r=e[n];for(var i=0;i0},this.canRedo=function(){return this.$redoStack.length>0},this.bookmark=function(e){e==undefined&&(e=this.$rev),this.mark=e},this.isAtBookmark=function(){return this.$rev===this.mark},this.toJSON=function(){},this.fromJSON=function(){},this.hasUndo=this.canUndo,this.hasRedo=this.canRedo,this.isClean=this.isAtBookmark,this.markClean=this.bookmark,this.$prettyPrint=function(e){return e?c(e):c(this.$undoStack)+"\n---\n"+c(this.$redoStack)}}).call(r.prototype);var s=e("./range").Range,o=s.comparePoints,u=s.comparePoints;t.UndoManager=r}),define("ace/layer/lines",["require","exports","module","ace/lib/dom"],function(e,t,n){"use strict";var r=e("../lib/dom"),i=function(e,t){this.element=e,this.canvasHeight=t||5e5,this.element.style.height=this.canvasHeight*2+"px",this.cells=[],this.cellCache=[],this.$offsetCoefficient=0};(function(){this.moveContainer=function(e){r.translate(this.element,0,-(e.firstRowScreen*e.lineHeight%this.canvasHeight)-e.offset*this.$offsetCoefficient)},this.pageChanged=function(e,t){return Math.floor(e.firstRowScreen*e.lineHeight/this.canvasHeight)!==Math.floor(t.firstRowScreen*t.lineHeight/this.canvasHeight)},this.computeLineTop=function(e,t,n){var r=t.firstRowScreen*t.lineHeight,i=Math.floor(r/this.canvasHeight),s=n.documentToScreenRow(e,0)*t.lineHeight;return s-i*this.canvasHeight},this.computeLineHeight=function(e,t,n){return t.lineHeight*n.getRowLineCount(e)},this.getLength=function(){return this.cells.length},this.get=function(e){return this.cells[e]},this.shift=function(){this.$cacheCell(this.cells.shift())},this.pop=function(){this.$cacheCell(this.cells.pop())},this.push=function(e){if(Array.isArray(e)){this.cells.push.apply(this.cells,e);var t=r.createFragment(this.element);for(var n=0;ns&&(a=i.end.row+1,i=t.getNextFoldLine(a,i),s=i?i.start.row:Infinity);if(a>r){while(this.$lines.getLength()>u+1)this.$lines.pop();break}o=this.$lines.get(++u),o?o.row=a:(o=this.$lines.createCell(a,e,this.session,f),this.$lines.push(o)),this.$renderCell(o,e,i,a),a++}this._signal("afterRender"),this.$updateGutterWidth(e)},this.$updateGutterWidth=function(e){var t=this.session,n=t.gutterRenderer||this.$renderer,r=t.$firstLineNumber,i=this.$lines.last()?this.$lines.last().text:"";if(this.$fixedWidth||t.$useWrapMode)i=t.getLength()+r-1;var s=n?n.getWidth(t,i,e):i.toString().length*e.characterWidth,o=this.$padding||this.$computePadding();s+=o.left+o.right,s!==this.gutterWidth&&!isNaN(s)&&(this.gutterWidth=s,this.element.parentNode.style.width=this.element.style.width=Math.ceil(this.gutterWidth)+"px",this._signal("changeGutterWidth",s))},this.$updateCursorRow=function(){if(!this.$highlightGutterLine)return;var e=this.session.selection.getCursor();if(this.$cursorRow===e.row)return;this.$cursorRow=e.row},this.updateLineHighlight=function(){if(!this.$highlightGutterLine)return;var e=this.session.selection.cursor.row;this.$cursorRow=e;if(this.$cursorCell&&this.$cursorCell.row==e)return;this.$cursorCell&&(this.$cursorCell.element.className=this.$cursorCell.element.className.replace("ace_gutter-active-line ",""));var t=this.$lines.cells;this.$cursorCell=null;for(var n=0;n=this.$cursorRow){if(r.row>this.$cursorRow){var i=this.session.getFoldLine(this.$cursorRow);if(!(n>0&&i&&i.start.row==t[n-1].row))break;r=t[n-1]}r.element.className="ace_gutter-active-line "+r.element.className,this.$cursorCell=r;break}}},this.scrollLines=function(e){var t=this.config;this.config=e,this.$updateCursorRow();if(this.$lines.pageChanged(t,e))return this.update(e);this.$lines.moveContainer(e);var n=Math.min(e.lastRow+e.gutterOffset,this.session.getLength()-1),r=this.oldLastRow;this.oldLastRow=n;if(!t||r0;i--)this.$lines.shift();if(r>n)for(var i=this.session.getFoldedRowCount(n+1,r);i>0;i--)this.$lines.pop();e.firstRowr&&this.$lines.push(this.$renderLines(e,r+1,n)),this.updateLineHighlight(),this._signal("afterRender"),this.$updateGutterWidth(e)},this.$renderLines=function(e,t,n){var r=[],i=t,s=this.session.getNextFoldLine(i),o=s?s.start.row:Infinity;for(;;){i>o&&(i=s.end.row+1,s=this.session.getNextFoldLine(i,s),o=s?s.start.row:Infinity);if(i>n)break;var u=this.$lines.createCell(i,e,this.session,f);this.$renderCell(u,e,s,i),r.push(u),i++}return r},this.$renderCell=function(e,t,n,i){var s=e.element,o=this.session,u=s.childNodes[0],a=s.childNodes[1],f=o.$firstLineNumber,l=o.$breakpoints,c=o.$decorations,h=o.gutterRenderer||this.$renderer,p=this.$showFoldWidgets&&o.foldWidgets,d=n?n.start.row:Number.MAX_VALUE,v="ace_gutter-cell ";this.$highlightGutterLine&&(i==this.$cursorRow||n&&i=d&&this.$cursorRow<=n.end.row)&&(v+="ace_gutter-active-line ",this.$cursorCell!=e&&(this.$cursorCell&&(this.$cursorCell.element.className=this.$cursorCell.element.className.replace("ace_gutter-active-line ","")),this.$cursorCell=e)),l[i]&&(v+=l[i]),c[i]&&(v+=c[i]),this.$annotations[i]&&(v+=this.$annotations[i].className),s.className!=v&&(s.className=v);if(p){var m=p[i];m==null&&(m=p[i]=o.getFoldWidget(i))}if(m){var v="ace_fold-widget ace_"+m;m=="start"&&i==d&&in.right-t.right)return"foldWidgets"}}).call(a.prototype),t.Gutter=a}),define("ace/layer/marker",["require","exports","module","ace/range","ace/lib/dom"],function(e,t,n){"use strict";var r=e("../range").Range,i=e("../lib/dom"),s=function(e){this.element=i.createElement("div"),this.element.className="ace_layer ace_marker-layer",e.appendChild(this.element)};(function(){function e(e,t,n,r){return(e?1:0)|(t?2:0)|(n?4:0)|(r?8:0)}this.$padding=0,this.setPadding=function(e){this.$padding=e},this.setSession=function(e){this.session=e},this.setMarkers=function(e){this.markers=e},this.elt=function(e,t){var n=this.i!=-1&&this.element.childNodes[this.i];n?this.i++:(n=document.createElement("div"),this.element.appendChild(n),this.i=-1),n.style.cssText=t,n.className=e},this.update=function(e){if(!e)return;this.config=e,this.i=0;var t;for(var n in this.markers){var r=this.markers[n];if(!r.range){r.update(t,this,this.session,e);continue}var i=r.range.clipRows(e.firstRow,e.lastRow);if(i.isEmpty())continue;i=i.toScreenRange(this.session);if(r.renderer){var s=this.$getTop(i.start.row,e),o=this.$padding+i.start.column*e.characterWidth;r.renderer(t,i,o,s,e)}else r.type=="fullLine"?this.drawFullLineMarker(t,i,r.clazz,e):r.type=="screenLine"?this.drawScreenLineMarker(t,i,r.clazz,e):i.isMultiLine()?r.type=="text"?this.drawTextMarker(t,i,r.clazz,e):this.drawMultiLineMarker(t,i,r.clazz,e):this.drawSingleLineMarker(t,i,r.clazz+" ace_start"+" ace_br15",e)}if(this.i!=-1)while(this.ip,l==f),s,l==f?0:1,o)},this.drawMultiLineMarker=function(e,t,n,r,i){var s=this.$padding,o=r.lineHeight,u=this.$getTop(t.start.row,r),a=s+t.start.column*r.characterWidth;i=i||"";if(this.session.$bidiHandler.isBidiRow(t.start.row)){var f=t.clone();f.end.row=f.start.row,f.end.column=this.session.getLine(f.start.row).length,this.drawBidiSingleLineMarker(e,f,n+" ace_br1 ace_start",r,null,i)}else this.elt(n+" ace_br1 ace_start","height:"+o+"px;"+"right:0;"+"top:"+u+"px;left:"+a+"px;"+(i||""));if(this.session.$bidiHandler.isBidiRow(t.end.row)){var f=t.clone();f.start.row=f.end.row,f.start.column=0,this.drawBidiSingleLineMarker(e,f,n+" ace_br12",r,null,i)}else{u=this.$getTop(t.end.row,r);var l=t.end.column*r.characterWidth;this.elt(n+" ace_br12","height:"+o+"px;"+"width:"+l+"px;"+"top:"+u+"px;"+"left:"+s+"px;"+(i||""))}o=(t.end.row-t.start.row-1)*r.lineHeight;if(o<=0)return;u=this.$getTop(t.start.row+1,r);var c=(t.start.column?1:0)|(t.end.column?0:8);this.elt(n+(c?" ace_br"+c:""),"height:"+o+"px;"+"right:0;"+"top:"+u+"px;"+"left:"+s+"px;"+(i||""))},this.drawSingleLineMarker=function(e,t,n,r,i,s){if(this.session.$bidiHandler.isBidiRow(t.start.row))return this.drawBidiSingleLineMarker(e,t,n,r,i,s);var o=r.lineHeight,u=(t.end.column+(i||0)-t.start.column)*r.characterWidth,a=this.$getTop(t.start.row,r),f=this.$padding+t.start.column*r.characterWidth;this.elt(n,"height:"+o+"px;"+"width:"+u+"px;"+"top:"+a+"px;"+"left:"+f+"px;"+(s||""))},this.drawBidiSingleLineMarker=function(e,t,n,r,i,s){var o=r.lineHeight,u=this.$getTop(t.start.row,r),a=this.$padding,f=this.session.$bidiHandler.getSelections(t.start.column,t.end.column);f.forEach(function(e){this.elt(n,"height:"+o+"px;"+"width:"+e.width+(i||0)+"px;"+"top:"+u+"px;"+"left:"+(a+e.left)+"px;"+(s||""))},this)},this.drawFullLineMarker=function(e,t,n,r,i){var s=this.$getTop(t.start.row,r),o=r.lineHeight;t.start.row!=t.end.row&&(o+=this.$getTop(t.end.row,r)-s),this.elt(n,"height:"+o+"px;"+"top:"+s+"px;"+"left:0;right:0;"+(i||""))},this.drawScreenLineMarker=function(e,t,n,r,i){var s=this.$getTop(t.start.row,r),o=r.lineHeight;this.elt(n,"height:"+o+"px;"+"top:"+s+"px;"+"left:0;right:0;"+(i||""))}}).call(s.prototype),t.Marker=s}),define("ace/layer/text",["require","exports","module","ace/lib/oop","ace/lib/dom","ace/lib/lang","ace/layer/lines","ace/lib/event_emitter"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/dom"),s=e("../lib/lang"),o=e("./lines").Lines,u=e("../lib/event_emitter").EventEmitter,a=function(e){this.dom=i,this.element=this.dom.createElement("div"),this.element.className="ace_layer ace_text-layer",e.appendChild(this.element),this.$updateEolChar=this.$updateEolChar.bind(this),this.$lines=new o(this.element)};(function(){r.implement(this,u),this.EOF_CHAR="\u00b6",this.EOL_CHAR_LF="\u00ac",this.EOL_CHAR_CRLF="\u00a4",this.EOL_CHAR=this.EOL_CHAR_LF,this.TAB_CHAR="\u2014",this.SPACE_CHAR="\u00b7",this.$padding=0,this.MAX_LINE_LENGTH=1e4,this.$updateEolChar=function(){var e=this.session.doc,t=e.getNewLineCharacter()=="\n"&&e.getNewLineMode()!="windows",n=t?this.EOL_CHAR_LF:this.EOL_CHAR_CRLF;if(this.EOL_CHAR!=n)return this.EOL_CHAR=n,!0},this.setPadding=function(e){this.$padding=e,this.element.style.margin="0 "+e+"px"},this.getLineHeight=function(){return this.$fontMetrics.$characterSize.height||0},this.getCharacterWidth=function(){return this.$fontMetrics.$characterSize.width||0},this.$setFontMetrics=function(e){this.$fontMetrics=e,this.$fontMetrics.on("changeCharacterSize",function(e){this._signal("changeCharacterSize",e)}.bind(this)),this.$pollSizeChanges()},this.checkForSizeChanges=function(){this.$fontMetrics.checkForSizeChanges()},this.$pollSizeChanges=function(){return this.$pollSizeChangesTimer=this.$fontMetrics.$pollSizeChanges()},this.setSession=function(e){this.session=e,e&&this.$computeTabString()},this.showInvisibles=!1,this.setShowInvisibles=function(e){return this.showInvisibles==e?!1:(this.showInvisibles=e,this.$computeTabString(),!0)},this.displayIndentGuides=!0,this.setDisplayIndentGuides=function(e){return this.displayIndentGuides==e?!1:(this.displayIndentGuides=e,this.$computeTabString(),!0)},this.$tabStrings=[],this.onChangeTabSize=this.$computeTabString=function(){var e=this.session.getTabSize();this.tabSize=e;var t=this.$tabStrings=[0];for(var n=1;nl&&(u=a.end.row+1,a=this.session.getNextFoldLine(u,a),l=a?a.start.row:Infinity);if(u>i)break;var c=s[o++];if(c){this.dom.removeChildren(c),this.$renderLine(c,u,u==l?a:!1),f&&(c.style.top=this.$lines.computeLineTop(u,e,this.session)+"px");var h=e.lineHeight*this.session.getRowLength(u)+"px";c.style.height!=h&&(f=!0,c.style.height=h)}u++}if(f)while(o0;i--)this.$lines.shift();if(t.lastRow>e.lastRow)for(var i=this.session.getFoldedRowCount(e.lastRow+1,t.lastRow);i>0;i--)this.$lines.pop();e.firstRowt.lastRow&&this.$lines.push(this.$renderLinesFragment(e,t.lastRow+1,e.lastRow))},this.$renderLinesFragment=function(e,t,n){var r=[],s=t,o=this.session.getNextFoldLine(s),u=o?o.start.row:Infinity;for(;;){s>u&&(s=o.end.row+1,o=this.session.getNextFoldLine(s,o),u=o?o.start.row:Infinity);if(s>n)break;var a=this.$lines.createCell(s,e,this.session),f=a.element;this.dom.removeChildren(f),i.setStyle(f.style,"height",this.$lines.computeLineHeight(s,e,this.session)+"px"),i.setStyle(f.style,"top",this.$lines.computeLineTop(s,e,this.session)+"px"),this.$renderLine(f,s,s==u?o:!1),this.$useLineGroups()?f.className="ace_line_group":f.className="ace_line",r.push(a),s++}return r},this.update=function(e){this.$lines.moveContainer(e),this.config=e;var t=e.firstRow,n=e.lastRow,r=this.$lines;while(r.getLength())r.pop();r.push(this.$renderLinesFragment(e,t,n))},this.$textToken={text:!0,rparen:!0,lparen:!0},this.$renderToken=function(e,t,n,r){var i=this,o=/(\t)|( +)|([\x00-\x1f\x80-\xa0\xad\u1680\u180E\u2000-\u200f\u2028\u2029\u202F\u205F\uFEFF\uFFF9-\uFFFC]+)|(\u3000)|([\u1100-\u115F\u11A3-\u11A7\u11FA-\u11FF\u2329-\u232A\u2E80-\u2E99\u2E9B-\u2EF3\u2F00-\u2FD5\u2FF0-\u2FFB\u3001-\u303E\u3041-\u3096\u3099-\u30FF\u3105-\u312D\u3131-\u318E\u3190-\u31BA\u31C0-\u31E3\u31F0-\u321E\u3220-\u3247\u3250-\u32FE\u3300-\u4DBF\u4E00-\uA48C\uA490-\uA4C6\uA960-\uA97C\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFAFF\uFE10-\uFE19\uFE30-\uFE52\uFE54-\uFE66\uFE68-\uFE6B\uFF01-\uFF60\uFFE0-\uFFE6]|[\uD800-\uDBFF][\uDC00-\uDFFF])/g,u=this.dom.createFragment(this.element),a,f=0;while(a=o.exec(r)){var l=a[1],c=a[2],h=a[3],p=a[4],d=a[5];if(!i.showInvisibles&&c)continue;var v=f!=a.index?r.slice(f,a.index):"";f=a.index+a[0].length,v&&u.appendChild(this.dom.createTextNode(v,this.element));if(l){var m=i.session.getScreenTabSize(t+a.index);u.appendChild(i.$tabStrings[m].cloneNode(!0)),t+=m-1}else if(c)if(i.showInvisibles){var g=this.dom.createElement("span");g.className="ace_invisible ace_invisible_space",g.textContent=s.stringRepeat(i.SPACE_CHAR,c.length),u.appendChild(g)}else u.appendChild(this.com.createTextNode(c,this.element));else if(h){var g=this.dom.createElement("span");g.className="ace_invisible ace_invisible_space ace_invalid",g.textContent=s.stringRepeat(i.SPACE_CHAR,h.length),u.appendChild(g)}else if(p){t+=1;var g=this.dom.createElement("span");g.style.width=i.config.characterWidth*2+"px",g.className=i.showInvisibles?"ace_cjk ace_invisible ace_invisible_space":"ace_cjk",g.textContent=i.showInvisibles?i.SPACE_CHAR:p,u.appendChild(g)}else if(d){t+=1;var g=this.dom.createElement("span");g.style.width=i.config.characterWidth*2+"px",g.className="ace_cjk",g.textContent=d,u.appendChild(g)}}u.appendChild(this.dom.createTextNode(f?r.slice(f):r,this.element));if(!this.$textToken[n.type]){var y="ace_"+n.type.replace(/\./g," ace_"),g=this.dom.createElement("span");n.type=="fold"&&(g.style.width=n.value.length*this.config.characterWidth+"px"),g.className=y,g.appendChild(u),e.appendChild(g)}else e.appendChild(u);return t+r.length},this.renderIndentGuide=function(e,t,n){var r=t.search(this.$indentGuideRe);if(r<=0||r>=n)return t;if(t[0]==" "){r-=r%this.tabSize;var i=r/this.tabSize;for(var s=0;s=o)u=this.$renderToken(a,u,l,c.substring(0,o-r)),c=c.substring(o-r),r=o,a=this.$createLineElement(),e.appendChild(a),a.appendChild(this.dom.createTextNode(s.stringRepeat("\u00a0",n.indent),this.element)),i++,u=0,o=n[i]||Number.MAX_VALUE;c.length!=0&&(r+=c.length,u=this.$renderToken(a,u,l,c))}}n[n.length-1]>this.MAX_LINE_LENGTH&&this.$renderOverflowMessage(a,u,null,"",!0)},this.$renderSimpleLine=function(e,t){var n=0,r=t[0],i=r.value;this.displayIndentGuides&&(i=this.renderIndentGuide(e,i)),i&&(n=this.$renderToken(e,n,r,i));for(var s=1;sthis.MAX_LINE_LENGTH)return this.$renderOverflowMessage(e,n,r,i);n=this.$renderToken(e,n,r,i)}},this.$renderOverflowMessage=function(e,t,n,r,i){n&&this.$renderToken(e,t,n,r.slice(0,this.MAX_LINE_LENGTH-t));var s=this.dom.createElement("span");s.className="ace_inline_button ace_keyword ace_toggle_wrap",s.textContent=i?"":"",e.appendChild(s)},this.$renderLine=function(e,t,n){!n&&n!=0&&(n=this.session.getFoldLine(t));if(n)var r=this.$getFoldLineTokens(t,n);else var r=this.session.getTokens(t);var i=e;if(r.length){var s=this.session.getRowSplitData(t);if(s&&s.length){this.$renderWrappedLine(e,r,s);var i=e.lastChild}else{var i=e;this.$useLineGroups()&&(i=this.$createLineElement(),e.appendChild(i)),this.$renderSimpleLine(i,r)}}else this.$useLineGroups()&&(i=this.$createLineElement(),e.appendChild(i));if(this.showInvisibles&&i){n&&(t=n.end.row);var o=this.dom.createElement("span");o.className="ace_invisible ace_invisible_eol",o.textContent=t==this.session.getLength()-1?this.EOF_CHAR:this.EOL_CHAR,i.appendChild(o)}},this.$getFoldLineTokens=function(e,t){function i(e,t,n){var i=0,s=0;while(s+e[i].value.lengthn-t&&(o=o.substring(0,n-t)),r.push({type:e[i].type,value:o}),s=t+o.length,i+=1}while(sn?r.push({type:e[i].type,value:o.substring(0,n-s)}):r.push(e[i]),s+=o.length,i+=1}}var n=this.session,r=[],s=n.getTokens(e);return t.walk(function(e,t,o,u,a){e!=null?r.push({type:"fold",value:e}):(a&&(s=n.getTokens(t)),s.length&&i(s,u,o))},t.end.row,this.session.getLine(t.end.row).length),r},this.$useLineGroups=function(){return this.session.getUseWrapMode()},this.destroy=function(){}}).call(a.prototype),t.Text=a}),define("ace/layer/cursor",["require","exports","module","ace/lib/dom"],function(e,t,n){"use strict";var r=e("../lib/dom"),i=function(e){this.element=r.createElement("div"),this.element.className="ace_layer ace_cursor-layer",e.appendChild(this.element),this.isVisible=!1,this.isBlinking=!0,this.blinkInterval=1e3,this.smoothBlinking=!1,this.cursors=[],this.cursor=this.addCursor(),r.addCssClass(this.element,"ace_hidden-cursors"),this.$updateCursors=this.$updateOpacity.bind(this)};(function(){this.$updateOpacity=function(e){var t=this.cursors;for(var n=t.length;n--;)r.setStyle(t[n].style,"opacity",e?"":"0")},this.$startCssAnimation=function(){var e=this.cursors;for(var t=e.length;t--;)e[t].style.animationDuration=this.blinkInterval+"ms";setTimeout(function(){r.addCssClass(this.element,"ace_animate-blinking")}.bind(this))},this.$stopCssAnimation=function(){r.removeCssClass(this.element,"ace_animate-blinking")},this.$padding=0,this.setPadding=function(e){this.$padding=e},this.setSession=function(e){this.session=e},this.setBlinking=function(e){e!=this.isBlinking&&(this.isBlinking=e,this.restartTimer())},this.setBlinkInterval=function(e){e!=this.blinkInterval&&(this.blinkInterval=e,this.restartTimer())},this.setSmoothBlinking=function(e){e!=this.smoothBlinking&&(this.smoothBlinking=e,r.setCssClass(this.element,"ace_smooth-blinking",e),this.$updateCursors(!0),this.restartTimer())},this.addCursor=function(){var e=r.createElement("div");return e.className="ace_cursor",this.element.appendChild(e),this.cursors.push(e),e},this.removeCursor=function(){if(this.cursors.length>1){var e=this.cursors.pop();return e.parentNode.removeChild(e),e}},this.hideCursor=function(){this.isVisible=!1,r.addCssClass(this.element,"ace_hidden-cursors"),this.restartTimer()},this.showCursor=function(){this.isVisible=!0,r.removeCssClass(this.element,"ace_hidden-cursors"),this.restartTimer()},this.restartTimer=function(){var e=this.$updateCursors;clearInterval(this.intervalId),clearTimeout(this.timeoutId),this.$stopCssAnimation(),this.smoothBlinking&&r.removeCssClass(this.element,"ace_smooth-blinking"),e(!0);if(!this.isBlinking||!this.blinkInterval||!this.isVisible){this.$stopCssAnimation();return}this.smoothBlinking&&setTimeout(function(){r.addCssClass(this.element,"ace_smooth-blinking")}.bind(this));if(r.HAS_CSS_ANIMATION)this.$startCssAnimation();else{var t=function(){this.timeoutId=setTimeout(function(){e(!1)},.6*this.blinkInterval)}.bind(this);this.intervalId=setInterval(function(){e(!0),t()},this.blinkInterval),t()}},this.getPixelPosition=function(e,t){if(!this.config||!this.session)return{left:0,top:0};e||(e=this.session.selection.getCursor());var n=this.session.documentToScreenPosition(e),r=this.$padding+(this.session.$bidiHandler.isBidiRow(n.row,e.row)?this.session.$bidiHandler.getPosLeft(n.column):n.column*this.config.characterWidth),i=(n.row-(t?this.config.firstRowScreen:0))*this.config.lineHeight;return{left:r,top:i}},this.isCursorInView=function(e,t){return e.top>=0&&e.tope.height+e.offset||o.top<0)&&n>1)continue;var u=this.cursors[i++]||this.addCursor(),a=u.style;this.drawCursor?this.drawCursor(u,o,e,t[n],this.session):this.isCursorInView(o,e)?(r.setStyle(a,"display","block"),r.translate(u,o.left,o.top),r.setStyle(a,"width",Math.round(e.characterWidth)+"px"),r.setStyle(a,"height",e.lineHeight+"px")):r.setStyle(a,"display","none")}while(this.cursors.length>i)this.removeCursor();var f=this.session.getOverwrite();this.$setOverwrite(f),this.$pixelPos=o,this.restartTimer()},this.drawCursor=null,this.$setOverwrite=function(e){e!=this.overwrite&&(this.overwrite=e,e?r.addCssClass(this.element,"ace_overwrite-cursors"):r.removeCssClass(this.element,"ace_overwrite-cursors"))},this.destroy=function(){clearInterval(this.intervalId),clearTimeout(this.timeoutId)}}).call(i.prototype),t.Cursor=i}),define("ace/scrollbar",["require","exports","module","ace/lib/oop","ace/lib/dom","ace/lib/event","ace/lib/event_emitter"],function(e,t,n){"use strict";var r=e("./lib/oop"),i=e("./lib/dom"),s=e("./lib/event"),o=e("./lib/event_emitter").EventEmitter,u=32768,a=function(e){this.element=i.createElement("div"),this.element.className="ace_scrollbar ace_scrollbar"+this.classSuffix,this.inner=i.createElement("div"),this.inner.className="ace_scrollbar-inner",this.inner.textContent="\u00a0",this.element.appendChild(this.inner),e.appendChild(this.element),this.setVisible(!1),this.skipEvent=!1,s.addListener(this.element,"scroll",this.onScroll.bind(this)),s.addListener(this.element,"mousedown",s.preventDefault)};(function(){r.implement(this,o),this.setVisible=function(e){this.element.style.display=e?"":"none",this.isVisible=e,this.coeff=1}}).call(a.prototype);var f=function(e,t){a.call(this,e),this.scrollTop=0,this.scrollHeight=0,t.$scrollbarWidth=this.width=i.scrollbarWidth(e.ownerDocument),this.inner.style.width=this.element.style.width=(this.width||15)+5+"px",this.$minWidth=0};r.inherits(f,a),function(){this.classSuffix="-v",this.onScroll=function(){if(!this.skipEvent){this.scrollTop=this.element.scrollTop;if(this.coeff!=1){var e=this.element.clientHeight/this.scrollHeight;this.scrollTop=this.scrollTop*(1-e)/(this.coeff-e)}this._emit("scroll",{data:this.scrollTop})}this.skipEvent=!1},this.getWidth=function(){return Math.max(this.isVisible?this.width:0,this.$minWidth||0)},this.setHeight=function(e){this.element.style.height=e+"px"},this.setInnerHeight=this.setScrollHeight=function(e){this.scrollHeight=e,e>u?(this.coeff=u/e,e=u):this.coeff!=1&&(this.coeff=1),this.inner.style.height=e+"px"},this.setScrollTop=function(e){this.scrollTop!=e&&(this.skipEvent=!0,this.scrollTop=e,this.element.scrollTop=e*this.coeff)}}.call(f.prototype);var l=function(e,t){a.call(this,e),this.scrollLeft=0,this.height=t.$scrollbarWidth,this.inner.style.height=this.element.style.height=(this.height||15)+5+"px"};r.inherits(l,a),function(){this.classSuffix="-h",this.onScroll=function(){this.skipEvent||(this.scrollLeft=this.element.scrollLeft,this._emit("scroll",{data:this.scrollLeft})),this.skipEvent=!1},this.getHeight=function(){return this.isVisible?this.height:0},this.setWidth=function(e){this.element.style.width=e+"px"},this.setInnerWidth=function(e){this.inner.style.width=e+"px"},this.setScrollWidth=function(e){this.inner.style.width=e+"px"},this.setScrollLeft=function(e){this.scrollLeft!=e&&(this.skipEvent=!0,this.scrollLeft=this.element.scrollLeft=e)}}.call(l.prototype),t.ScrollBar=f,t.ScrollBarV=f,t.ScrollBarH=l,t.VScrollBar=f,t.HScrollBar=l}),define("ace/renderloop",["require","exports","module","ace/lib/event"],function(e,t,n){"use strict";var r=e("./lib/event"),i=function(e,t){this.onRender=e,this.pending=!1,this.changes=0,this.$recursionLimit=2,this.window=t||window;var n=this;this._flush=function(e){n.pending=!1;var t=n.changes;t&&(r.blockIdle(100),n.changes=0,n.onRender(t));if(n.changes){if(n.$recursionLimit--<0)return;n.schedule()}else n.$recursionLimit=2}};(function(){this.schedule=function(e){this.changes=this.changes|e,this.changes&&!this.pending&&(r.nextFrame(this._flush),this.pending=!0)},this.clear=function(e){var t=this.changes;return this.changes=0,t}}).call(i.prototype),t.RenderLoop=i}),define("ace/layer/font_metrics",["require","exports","module","ace/lib/oop","ace/lib/dom","ace/lib/lang","ace/lib/event","ace/lib/useragent","ace/lib/event_emitter"],function(e,t,n){var r=e("../lib/oop"),i=e("../lib/dom"),s=e("../lib/lang"),o=e("../lib/event"),u=e("../lib/useragent"),a=e("../lib/event_emitter").EventEmitter,f=256,l=typeof ResizeObserver=="function",c=200,h=t.FontMetrics=function(e){this.el=i.createElement("div"),this.$setMeasureNodeStyles(this.el.style,!0),this.$main=i.createElement("div"),this.$setMeasureNodeStyles(this.$main.style),this.$measureNode=i.createElement("div"),this.$setMeasureNodeStyles(this.$measureNode.style),this.el.appendChild(this.$main),this.el.appendChild(this.$measureNode),e.appendChild(this.el),this.$measureNode.innerHTML=s.stringRepeat("X",f),this.$characterSize={width:0,height:0},l?this.$addObserver():this.checkForSizeChanges()};(function(){r.implement(this,a),this.$characterSize={width:0,height:0},this.$setMeasureNodeStyles=function(e,t){e.width=e.height="auto",e.left=e.top="0px",e.visibility="hidden",e.position="absolute",e.whiteSpace="pre",u.isIE<8?e["font-family"]="inherit":e.font="inherit",e.overflow=t?"hidden":"visible"},this.checkForSizeChanges=function(e){e===undefined&&(e=this.$measureSizes());if(e&&(this.$characterSize.width!==e.width||this.$characterSize.height!==e.height)){this.$measureNode.style.fontWeight="bold";var t=this.$measureSizes();this.$measureNode.style.fontWeight="",this.$characterSize=e,this.charSizes=Object.create(null),this.allowBoldFonts=t&&t.width===e.width&&t.height===e.height,this._emit("changeCharacterSize",{data:e})}},this.$addObserver=function(){var e=this;this.$observer=new window.ResizeObserver(function(t){var n=t[0].contentRect;e.checkForSizeChanges({height:n.height,width:n.width/f})}),this.$observer.observe(this.$measureNode)},this.$pollSizeChanges=function(){if(this.$pollSizeChangesTimer||this.$observer)return this.$pollSizeChangesTimer;var e=this;return this.$pollSizeChangesTimer=o.onIdle(function t(){e.checkForSizeChanges(),o.onIdle(t,500)},500)},this.setPolling=function(e){e?this.$pollSizeChanges():this.$pollSizeChangesTimer&&(clearInterval(this.$pollSizeChangesTimer),this.$pollSizeChangesTimer=0)},this.$measureSizes=function(e){var t={height:(e||this.$measureNode).clientHeight,width:(e||this.$measureNode).clientWidth/f};return t.width===0||t.height===0?null:t},this.$measureCharWidth=function(e){this.$main.innerHTML=s.stringRepeat(e,f);var t=this.$main.getBoundingClientRect();return t.width/f},this.getCharacterWidth=function(e){var t=this.charSizes[e];return t===undefined&&(t=this.charSizes[e]=this.$measureCharWidth(e)/this.$characterSize.width),t},this.destroy=function(){clearInterval(this.$pollSizeChangesTimer),this.$observer&&this.$observer.disconnect(),this.el&&this.el.parentNode&&this.el.parentNode.removeChild(this.el)},this.$getZoom=function e(t){return t?(window.getComputedStyle(t).zoom||1)*e(t.parentElement):1},this.$initTransformMeasureNodes=function(){var e=function(e,t){return["div",{style:"position: absolute;top:"+e+"px;left:"+t+"px;"}]};this.els=i.buildDom([e(0,0),e(c,0),e(0,c),e(c,c)],this.el)},this.transformCoordinates=function(e,t){function r(e,t,n){var r=e[1]*t[0]-e[0]*t[1];return[(-t[1]*n[0]+t[0]*n[1])/r,(+e[1]*n[0]-e[0]*n[1])/r]}function i(e,t){return[e[0]-t[0],e[1]-t[1]]}function s(e,t){return[e[0]+t[0],e[1]+t[1]]}function o(e,t){return[e*t[0],e*t[1]]}function u(e){var t=e.getBoundingClientRect();return[t.left,t.top]}if(e){var n=this.$getZoom(this.el);e=o(1/n,e)}this.els||this.$initTransformMeasureNodes();var a=u(this.els[0]),f=u(this.els[1]),l=u(this.els[2]),h=u(this.els[3]),p=r(i(h,f),i(h,l),i(s(f,l),s(h,a))),d=o(1+p[0],i(f,a)),v=o(1+p[1],i(l,a));if(t){var m=t,g=p[0]*m[0]/c+p[1]*m[1]/c+1,y=s(o(m[0],d),o(m[1],v));return s(o(1/g/c,y),a)}var b=i(e,a),w=r(i(d,o(p[0],b)),i(v,o(p[1],b)),b);return o(c,w)}}).call(h.prototype)}),define("ace/virtual_renderer",["require","exports","module","ace/lib/oop","ace/lib/dom","ace/config","ace/layer/gutter","ace/layer/marker","ace/layer/text","ace/layer/cursor","ace/scrollbar","ace/scrollbar","ace/renderloop","ace/layer/font_metrics","ace/lib/event_emitter","ace/lib/useragent"],function(e,t,n){"use strict";var r=e("./lib/oop"),i=e("./lib/dom"),s=e("./config"),o=e("./layer/gutter").Gutter,u=e("./layer/marker").Marker,a=e("./layer/text").Text,f=e("./layer/cursor").Cursor,l=e("./scrollbar").HScrollBar,c=e("./scrollbar").VScrollBar,h=e("./renderloop").RenderLoop,p=e("./layer/font_metrics").FontMetrics,d=e("./lib/event_emitter").EventEmitter,v='.ace_br1 {border-top-left-radius : 3px;}.ace_br2 {border-top-right-radius : 3px;}.ace_br3 {border-top-left-radius : 3px; border-top-right-radius: 3px;}.ace_br4 {border-bottom-right-radius: 3px;}.ace_br5 {border-top-left-radius : 3px; border-bottom-right-radius: 3px;}.ace_br6 {border-top-right-radius : 3px; border-bottom-right-radius: 3px;}.ace_br7 {border-top-left-radius : 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px;}.ace_br8 {border-bottom-left-radius : 3px;}.ace_br9 {border-top-left-radius : 3px; border-bottom-left-radius: 3px;}.ace_br10{border-top-right-radius : 3px; border-bottom-left-radius: 3px;}.ace_br11{border-top-left-radius : 3px; border-top-right-radius: 3px; border-bottom-left-radius: 3px;}.ace_br12{border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;}.ace_br13{border-top-left-radius : 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;}.ace_br14{border-top-right-radius : 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;}.ace_br15{border-top-left-radius : 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;}.ace_editor {position: relative;overflow: hidden;font: 12px/normal \'Monaco\', \'Menlo\', \'Ubuntu Mono\', \'Consolas\', \'source-code-pro\', monospace;direction: ltr;text-align: left;-webkit-tap-highlight-color: rgba(0, 0, 0, 0);}.ace_scroller {position: absolute;overflow: hidden;top: 0;bottom: 0;background-color: inherit;-ms-user-select: none;-moz-user-select: none;-webkit-user-select: none;user-select: none;cursor: text;}.ace_content {position: absolute;box-sizing: border-box;min-width: 100%;contain: style size layout;font-variant-ligatures: no-common-ligatures;}.ace_dragging .ace_scroller:before{position: absolute;top: 0;left: 0;right: 0;bottom: 0;content: \'\';background: rgba(250, 250, 250, 0.01);z-index: 1000;}.ace_dragging.ace_dark .ace_scroller:before{background: rgba(0, 0, 0, 0.01);}.ace_selecting, .ace_selecting * {cursor: text !important;}.ace_gutter {position: absolute;overflow : hidden;width: auto;top: 0;bottom: 0;left: 0;cursor: default;z-index: 4;-ms-user-select: none;-moz-user-select: none;-webkit-user-select: none;user-select: none;contain: style size layout;}.ace_gutter-active-line {position: absolute;left: 0;right: 0;}.ace_scroller.ace_scroll-left {box-shadow: 17px 0 16px -16px rgba(0, 0, 0, 0.4) inset;}.ace_gutter-cell {position: absolute;top: 0;left: 0;right: 0;padding-left: 19px;padding-right: 6px;background-repeat: no-repeat;}.ace_gutter-cell.ace_error {background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAABOFBMVEX/////////QRswFAb/Ui4wFAYwFAYwFAaWGAfDRymzOSH/PxswFAb/SiUwFAYwFAbUPRvjQiDllog5HhHdRybsTi3/Tyv9Tir+Syj/UC3////XurebMBIwFAb/RSHbPx/gUzfdwL3kzMivKBAwFAbbvbnhPx66NhowFAYwFAaZJg8wFAaxKBDZurf/RB6mMxb/SCMwFAYwFAbxQB3+RB4wFAb/Qhy4Oh+4QifbNRcwFAYwFAYwFAb/QRzdNhgwFAYwFAbav7v/Uy7oaE68MBK5LxLewr/r2NXewLswFAaxJw4wFAbkPRy2PyYwFAaxKhLm1tMwFAazPiQwFAaUGAb/QBrfOx3bvrv/VC/maE4wFAbRPBq6MRO8Qynew8Dp2tjfwb0wFAbx6eju5+by6uns4uH9/f36+vr/GkHjAAAAYnRSTlMAGt+64rnWu/bo8eAA4InH3+DwoN7j4eLi4xP99Nfg4+b+/u9B/eDs1MD1mO7+4PHg2MXa347g7vDizMLN4eG+Pv7i5evs/v79yu7S3/DV7/498Yv24eH+4ufQ3Ozu/v7+y13sRqwAAADLSURBVHjaZc/XDsFgGIBhtDrshlitmk2IrbHFqL2pvXf/+78DPokj7+Fz9qpU/9UXJIlhmPaTaQ6QPaz0mm+5gwkgovcV6GZzd5JtCQwgsxoHOvJO15kleRLAnMgHFIESUEPmawB9ngmelTtipwwfASilxOLyiV5UVUyVAfbG0cCPHig+GBkzAENHS0AstVF6bacZIOzgLmxsHbt2OecNgJC83JERmePUYq8ARGkJx6XtFsdddBQgZE2nPR6CICZhawjA4Fb/chv+399kfR+MMMDGOQAAAABJRU5ErkJggg==");background-repeat: no-repeat;background-position: 2px center;}.ace_gutter-cell.ace_warning {background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAmVBMVEX///8AAAD///8AAAAAAABPSzb/5sAAAAB/blH/73z/ulkAAAAAAAD85pkAAAAAAAACAgP/vGz/rkDerGbGrV7/pkQICAf////e0IsAAAD/oED/qTvhrnUAAAD/yHD/njcAAADuv2r/nz//oTj/p064oGf/zHAAAAA9Nir/tFIAAAD/tlTiuWf/tkIAAACynXEAAAAAAAAtIRW7zBpBAAAAM3RSTlMAABR1m7RXO8Ln31Z36zT+neXe5OzooRDfn+TZ4p3h2hTf4t3k3ucyrN1K5+Xaks52Sfs9CXgrAAAAjklEQVR42o3PbQ+CIBQFYEwboPhSYgoYunIqqLn6/z8uYdH8Vmdnu9vz4WwXgN/xTPRD2+sgOcZjsge/whXZgUaYYvT8QnuJaUrjrHUQreGczuEafQCO/SJTufTbroWsPgsllVhq3wJEk2jUSzX3CUEDJC84707djRc5MTAQxoLgupWRwW6UB5fS++NV8AbOZgnsC7BpEAAAAABJRU5ErkJggg==");background-position: 2px center;}.ace_gutter-cell.ace_info {background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAAAAAA6mKC9AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAAJ0Uk5TAAB2k804AAAAPklEQVQY02NgIB68QuO3tiLznjAwpKTgNyDbMegwisCHZUETUZV0ZqOquBpXj2rtnpSJT1AEnnRmL2OgGgAAIKkRQap2htgAAAAASUVORK5CYII=");background-position: 2px center;}.ace_dark .ace_gutter-cell.ace_info {background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAJFBMVEUAAAChoaGAgIAqKiq+vr6tra1ZWVmUlJSbm5s8PDxubm56enrdgzg3AAAAAXRSTlMAQObYZgAAAClJREFUeNpjYMAPdsMYHegyJZFQBlsUlMFVCWUYKkAZMxZAGdxlDMQBAG+TBP4B6RyJAAAAAElFTkSuQmCC");}.ace_scrollbar {contain: strict;position: absolute;right: 0;bottom: 0;z-index: 6;}.ace_scrollbar-inner {position: absolute;cursor: text;left: 0;top: 0;}.ace_scrollbar-v{overflow-x: hidden;overflow-y: scroll;top: 0;}.ace_scrollbar-h {overflow-x: scroll;overflow-y: hidden;left: 0;}.ace_print-margin {position: absolute;height: 100%;}.ace_text-input {position: absolute;z-index: 0;width: 0.5em;height: 1em;opacity: 0;background: transparent;-moz-appearance: none;appearance: none;border: none;resize: none;outline: none;overflow: hidden;font: inherit;padding: 0 1px;margin: 0 -1px;contain: strict;-ms-user-select: text;-moz-user-select: text;-webkit-user-select: text;user-select: text;white-space: pre!important;}.ace_text-input.ace_composition {background: transparent;color: inherit;z-index: 1000;opacity: 1;}.ace_composition_placeholder { color: transparent }.ace_composition_marker { border-bottom: 1px solid;position: absolute;border-radius: 0;margin-top: 1px;}[ace_nocontext=true] {transform: none!important;filter: none!important;clip-path: none!important;mask : none!important;contain: none!important;perspective: none!important;mix-blend-mode: initial!important;z-index: auto;}.ace_layer {z-index: 1;position: absolute;overflow: hidden;word-wrap: normal;white-space: pre;height: 100%;width: 100%;box-sizing: border-box;pointer-events: none;}.ace_gutter-layer {position: relative;width: auto;text-align: right;pointer-events: auto;height: 1000000px;contain: style size layout;}.ace_text-layer {font: inherit !important;position: absolute;height: 1000000px;width: 1000000px;contain: style size layout;}.ace_text-layer > .ace_line, .ace_text-layer > .ace_line_group {contain: style size layout;position: absolute;top: 0;left: 0;right: 0;}.ace_hidpi .ace_text-layer,.ace_hidpi .ace_gutter-layer,.ace_hidpi .ace_content,.ace_hidpi .ace_gutter {contain: strict;will-change: transform;}.ace_hidpi .ace_text-layer > .ace_line, .ace_hidpi .ace_text-layer > .ace_line_group {contain: strict;}.ace_cjk {display: inline-block;text-align: center;}.ace_cursor-layer {z-index: 4;}.ace_cursor {z-index: 4;position: absolute;box-sizing: border-box;border-left: 2px solid;transform: translatez(0);}.ace_multiselect .ace_cursor {border-left-width: 1px;}.ace_slim-cursors .ace_cursor {border-left-width: 1px;}.ace_overwrite-cursors .ace_cursor {border-left-width: 0;border-bottom: 1px solid;}.ace_hidden-cursors .ace_cursor {opacity: 0.2;}.ace_hasPlaceholder .ace_hidden-cursors .ace_cursor {opacity: 0;}.ace_smooth-blinking .ace_cursor {transition: opacity 0.18s;}.ace_animate-blinking .ace_cursor {animation-duration: 1000ms;animation-timing-function: step-end;animation-name: blink-ace-animate;animation-iteration-count: infinite;}.ace_animate-blinking.ace_smooth-blinking .ace_cursor {animation-duration: 1000ms;animation-timing-function: ease-in-out;animation-name: blink-ace-animate-smooth;}@keyframes blink-ace-animate {from, to { opacity: 1; }60% { opacity: 0; }}@keyframes blink-ace-animate-smooth {from, to { opacity: 1; }45% { opacity: 1; }60% { opacity: 0; }85% { opacity: 0; }}.ace_marker-layer .ace_step, .ace_marker-layer .ace_stack {position: absolute;z-index: 3;}.ace_marker-layer .ace_selection {position: absolute;z-index: 5;}.ace_marker-layer .ace_bracket {position: absolute;z-index: 6;}.ace_marker-layer .ace_error_bracket {position: absolute;border-bottom: 1px solid #DE5555;border-radius: 0;}.ace_marker-layer .ace_active-line {position: absolute;z-index: 2;}.ace_marker-layer .ace_selected-word {position: absolute;z-index: 4;box-sizing: border-box;}.ace_line .ace_fold {box-sizing: border-box;display: inline-block;height: 11px;margin-top: -2px;vertical-align: middle;background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABEAAAAJCAYAAADU6McMAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAJpJREFUeNpi/P//PwOlgAXGYGRklAVSokD8GmjwY1wasKljQpYACtpCFeADcHVQfQyMQAwzwAZI3wJKvCLkfKBaMSClBlR7BOQikCFGQEErIH0VqkabiGCAqwUadAzZJRxQr/0gwiXIal8zQQPnNVTgJ1TdawL0T5gBIP1MUJNhBv2HKoQHHjqNrA4WO4zY0glyNKLT2KIfIMAAQsdgGiXvgnYAAAAASUVORK5CYII="),url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAA3CAYAAADNNiA5AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAACJJREFUeNpi+P//fxgTAwPDBxDxD078RSX+YeEyDFMCIMAAI3INmXiwf2YAAAAASUVORK5CYII=");background-repeat: no-repeat, repeat-x;background-position: center center, top left;color: transparent;border: 1px solid black;border-radius: 2px;cursor: pointer;pointer-events: auto;}.ace_dark .ace_fold {}.ace_fold:hover{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABEAAAAJCAYAAADU6McMAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAJpJREFUeNpi/P//PwOlgAXGYGRklAVSokD8GmjwY1wasKljQpYACtpCFeADcHVQfQyMQAwzwAZI3wJKvCLkfKBaMSClBlR7BOQikCFGQEErIH0VqkabiGCAqwUadAzZJRxQr/0gwiXIal8zQQPnNVTgJ1TdawL0T5gBIP1MUJNhBv2HKoQHHjqNrA4WO4zY0glyNKLT2KIfIMAAQsdgGiXvgnYAAAAASUVORK5CYII="),url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAA3CAYAAADNNiA5AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAACBJREFUeNpi+P//fz4TAwPDZxDxD5X4i5fLMEwJgAADAEPVDbjNw87ZAAAAAElFTkSuQmCC");}.ace_tooltip {background-color: #FFF;background-image: linear-gradient(to bottom, transparent, rgba(0, 0, 0, 0.1));border: 1px solid gray;border-radius: 1px;box-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);color: black;max-width: 100%;padding: 3px 4px;position: fixed;z-index: 999999;box-sizing: border-box;cursor: default;white-space: pre;word-wrap: break-word;line-height: normal;font-style: normal;font-weight: normal;letter-spacing: normal;pointer-events: none;}.ace_folding-enabled > .ace_gutter-cell {padding-right: 13px;}.ace_fold-widget {box-sizing: border-box;margin: 0 -12px 0 1px;display: none;width: 11px;vertical-align: top;background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAANElEQVR42mWKsQ0AMAzC8ixLlrzQjzmBiEjp0A6WwBCSPgKAXoLkqSot7nN3yMwR7pZ32NzpKkVoDBUxKAAAAABJRU5ErkJggg==");background-repeat: no-repeat;background-position: center;border-radius: 3px;border: 1px solid transparent;cursor: pointer;}.ace_folding-enabled .ace_fold-widget {display: inline-block; }.ace_fold-widget.ace_end {background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAANElEQVR42m3HwQkAMAhD0YzsRchFKI7sAikeWkrxwScEB0nh5e7KTPWimZki4tYfVbX+MNl4pyZXejUO1QAAAABJRU5ErkJggg==");}.ace_fold-widget.ace_closed {background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAGCAYAAAAG5SQMAAAAOUlEQVR42jXKwQkAMAgDwKwqKD4EwQ26sSOkVWjgIIHAzPiCgaqiqnJHZnKICBERHN194O5b9vbLuAVRL+l0YWnZAAAAAElFTkSuQmCCXA==");}.ace_fold-widget:hover {border: 1px solid rgba(0, 0, 0, 0.3);background-color: rgba(255, 255, 255, 0.2);box-shadow: 0 1px 1px rgba(255, 255, 255, 0.7);}.ace_fold-widget:active {border: 1px solid rgba(0, 0, 0, 0.4);background-color: rgba(0, 0, 0, 0.05);box-shadow: 0 1px 1px rgba(255, 255, 255, 0.8);}.ace_dark .ace_fold-widget {background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHklEQVQIW2P4//8/AzoGEQ7oGCaLLAhWiSwB146BAQCSTPYocqT0AAAAAElFTkSuQmCC");}.ace_dark .ace_fold-widget.ace_end {background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAH0lEQVQIW2P4//8/AxQ7wNjIAjDMgC4AxjCVKBirIAAF0kz2rlhxpAAAAABJRU5ErkJggg==");}.ace_dark .ace_fold-widget.ace_closed {background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAFCAYAAACAcVaiAAAAHElEQVQIW2P4//+/AxAzgDADlOOAznHAKgPWAwARji8UIDTfQQAAAABJRU5ErkJggg==");}.ace_dark .ace_fold-widget:hover {box-shadow: 0 1px 1px rgba(255, 255, 255, 0.2);background-color: rgba(255, 255, 255, 0.1);}.ace_dark .ace_fold-widget:active {box-shadow: 0 1px 1px rgba(255, 255, 255, 0.2);}.ace_inline_button {border: 1px solid lightgray;display: inline-block;margin: -1px 8px;padding: 0 5px;pointer-events: auto;cursor: pointer;}.ace_inline_button:hover {border-color: gray;background: rgba(200,200,200,0.2);display: inline-block;pointer-events: auto;}.ace_fold-widget.ace_invalid {background-color: #FFB4B4;border-color: #DE5555;}.ace_fade-fold-widgets .ace_fold-widget {transition: opacity 0.4s ease 0.05s;opacity: 0;}.ace_fade-fold-widgets:hover .ace_fold-widget {transition: opacity 0.05s ease 0.05s;opacity:1;}.ace_underline {text-decoration: underline;}.ace_bold {font-weight: bold;}.ace_nobold .ace_bold {font-weight: normal;}.ace_italic {font-style: italic;}.ace_error-marker {background-color: rgba(255, 0, 0,0.2);position: absolute;z-index: 9;}.ace_highlight-marker {background-color: rgba(255, 255, 0,0.2);position: absolute;z-index: 8;}.ace_mobile-menu {position: absolute;line-height: 1.5;border-radius: 4px;-ms-user-select: none;-moz-user-select: none;-webkit-user-select: none;user-select: none;background: white;box-shadow: 1px 3px 2px grey;border: 1px solid #dcdcdc;color: black;}.ace_dark > .ace_mobile-menu {background: #333;color: #ccc;box-shadow: 1px 3px 2px grey;border: 1px solid #444;}.ace_mobile-button {padding: 2px;cursor: pointer;overflow: hidden;}.ace_mobile-button:hover {background-color: #eee;opacity:1;}.ace_mobile-button:active {background-color: #ddd;}.ace_placeholder {font-family: arial;transform: scale(0.9);transform-origin: left;white-space: pre;opacity: 0.7;margin: 0 10px;}',m=e("./lib/useragent"),g=m.isIE;i.importCssString(v,"ace_editor.css");var y=function(e,t){var n=this;this.container=e||i.createElement("div"),i.addCssClass(this.container,"ace_editor"),i.HI_DPI&&i.addCssClass(this.container,"ace_hidpi"),this.setTheme(t),this.$gutter=i.createElement("div"),this.$gutter.className="ace_gutter",this.container.appendChild(this.$gutter),this.$gutter.setAttribute("aria-hidden",!0),this.scroller=i.createElement("div"),this.scroller.className="ace_scroller",this.container.appendChild(this.scroller),this.content=i.createElement("div"),this.content.className="ace_content",this.scroller.appendChild(this.content),this.$gutterLayer=new o(this.$gutter),this.$gutterLayer.on("changeGutterWidth",this.onGutterResize.bind(this)),this.$markerBack=new u(this.content);var r=this.$textLayer=new a(this.content);this.canvas=r.element,this.$markerFront=new u(this.content),this.$cursorLayer=new f(this.content),this.$horizScroll=!1,this.$vScroll=!1,this.scrollBar=this.scrollBarV=new c(this.container,this),this.scrollBarH=new l(this.container,this),this.scrollBarV.addEventListener("scroll",function(e){n.$scrollAnimation||n.session.setScrollTop(e.data-n.scrollMargin.top)}),this.scrollBarH.addEventListener("scroll",function(e){n.$scrollAnimation||n.session.setScrollLeft(e.data-n.scrollMargin.left)}),this.scrollTop=0,this.scrollLeft=0,this.cursorPos={row:0,column:0},this.$fontMetrics=new p(this.container),this.$textLayer.$setFontMetrics(this.$fontMetrics),this.$textLayer.addEventListener("changeCharacterSize",function(e){n.updateCharacterSize(),n.onResize(!0,n.gutterWidth,n.$size.width,n.$size.height),n._signal("changeCharacterSize",e)}),this.$size={width:0,height:0,scrollerHeight:0,scrollerWidth:0,$dirty:!0},this.layerConfig={width:1,padding:0,firstRow:0,firstRowScreen:0,lastRow:0,lineHeight:0,characterWidth:0,minHeight:1,maxHeight:1,offset:0,height:1,gutterOffset:1},this.scrollMargin={left:0,right:0,top:0,bottom:0,v:0,h:0},this.margin={left:0,right:0,top:0,bottom:0,v:0,h:0},this.$keepTextAreaAtCursor=!m.isIOS,this.$loop=new h(this.$renderChanges.bind(this),this.container.ownerDocument.defaultView),this.$loop.schedule(this.CHANGE_FULL),this.updateCharacterSize(),this.setPadding(4),s.resetOptions(this),s._signal("renderer",this)};(function(){this.CHANGE_CURSOR=1,this.CHANGE_MARKER=2,this.CHANGE_GUTTER=4,this.CHANGE_SCROLL=8,this.CHANGE_LINES=16,this.CHANGE_TEXT=32,this.CHANGE_SIZE=64,this.CHANGE_MARKER_BACK=128,this.CHANGE_MARKER_FRONT=256,this.CHANGE_FULL=512,this.CHANGE_H_SCROLL=1024,r.implement(this,d),this.updateCharacterSize=function(){this.$textLayer.allowBoldFonts!=this.$allowBoldFonts&&(this.$allowBoldFonts=this.$textLayer.allowBoldFonts,this.setStyle("ace_nobold",!this.$allowBoldFonts)),this.layerConfig.characterWidth=this.characterWidth=this.$textLayer.getCharacterWidth(),this.layerConfig.lineHeight=this.lineHeight=this.$textLayer.getLineHeight(),this.$updatePrintMargin(),i.setStyle(this.scroller.style,"line-height",this.lineHeight+"px")},this.setSession=function(e){this.session&&this.session.doc.off("changeNewLineMode",this.onChangeNewLineMode),this.session=e,e&&this.scrollMargin.top&&e.getScrollTop()<=0&&e.setScrollTop(-this.scrollMargin.top),this.$cursorLayer.setSession(e),this.$markerBack.setSession(e),this.$markerFront.setSession(e),this.$gutterLayer.setSession(e),this.$textLayer.setSession(e);if(!e)return;this.$loop.schedule(this.CHANGE_FULL),this.session.$setFontMetrics(this.$fontMetrics),this.scrollBarH.scrollLeft=this.scrollBarV.scrollTop=null,this.onChangeNewLineMode=this.onChangeNewLineMode.bind(this),this.onChangeNewLineMode(),this.session.doc.on("changeNewLineMode",this.onChangeNewLineMode)},this.updateLines=function(e,t,n){t===undefined&&(t=Infinity),this.$changedLines?(this.$changedLines.firstRow>e&&(this.$changedLines.firstRow=e),this.$changedLines.lastRowthis.layerConfig.lastRow)return;this.$loop.schedule(this.CHANGE_LINES)},this.onChangeNewLineMode=function(){this.$loop.schedule(this.CHANGE_TEXT),this.$textLayer.$updateEolChar(),this.session.$bidiHandler.setEolChar(this.$textLayer.EOL_CHAR)},this.onChangeTabSize=function(){this.$loop.schedule(this.CHANGE_TEXT|this.CHANGE_MARKER),this.$textLayer.onChangeTabSize()},this.updateText=function(){this.$loop.schedule(this.CHANGE_TEXT)},this.updateFull=function(e){e?this.$renderChanges(this.CHANGE_FULL,!0):this.$loop.schedule(this.CHANGE_FULL)},this.updateFontSize=function(){this.$textLayer.checkForSizeChanges()},this.$changes=0,this.$updateSizeAsync=function(){this.$loop.pending?this.$size.$dirty=!0:this.onResize()},this.onResize=function(e,t,n,r){if(this.resizing>2)return;this.resizing>0?this.resizing++:this.resizing=e?1:0;var i=this.container;r||(r=i.clientHeight||i.scrollHeight),n||(n=i.clientWidth||i.scrollWidth);var s=this.$updateCachedSize(e,t,n,r);if(!this.$size.scrollerHeight||!n&&!r)return this.resizing=0;e&&(this.$gutterLayer.$padding=null),e?this.$renderChanges(s|this.$changes,!0):this.$loop.schedule(s|this.$changes),this.resizing&&(this.resizing=0),this.scrollBarV.scrollLeft=this.scrollBarV.scrollTop=null},this.$updateCachedSize=function(e,t,n,r){r-=this.$extraHeight||0;var s=0,o=this.$size,u={width:o.width,height:o.height,scrollerHeight:o.scrollerHeight,scrollerWidth:o.scrollerWidth};r&&(e||o.height!=r)&&(o.height=r,s|=this.CHANGE_SIZE,o.scrollerHeight=o.height,this.$horizScroll&&(o.scrollerHeight-=this.scrollBarH.getHeight()),this.scrollBarV.element.style.bottom=this.scrollBarH.getHeight()+"px",s|=this.CHANGE_SCROLL);if(n&&(e||o.width!=n)){s|=this.CHANGE_SIZE,o.width=n,t==null&&(t=this.$showGutter?this.$gutter.offsetWidth:0),this.gutterWidth=t,i.setStyle(this.scrollBarH.element.style,"left",t+"px"),i.setStyle(this.scroller.style,"left",t+this.margin.left+"px"),o.scrollerWidth=Math.max(0,n-t-this.scrollBarV.getWidth()-this.margin.h),i.setStyle(this.$gutter.style,"left",this.margin.left+"px");var a=this.scrollBarV.getWidth()+"px";i.setStyle(this.scrollBarH.element.style,"right",a),i.setStyle(this.scroller.style,"right",a),i.setStyle(this.scroller.style,"bottom",this.scrollBarH.getHeight());if(this.session&&this.session.getUseWrapMode()&&this.adjustWrapLimit()||e)s|=this.CHANGE_FULL}return o.$dirty=!n||!r,s&&this._signal("resize",u),s},this.onGutterResize=function(e){var t=this.$showGutter?e:0;t!=this.gutterWidth&&(this.$changes|=this.$updateCachedSize(!0,t,this.$size.width,this.$size.height)),this.session.getUseWrapMode()&&this.adjustWrapLimit()?this.$loop.schedule(this.CHANGE_FULL):this.$size.$dirty?this.$loop.schedule(this.CHANGE_FULL):this.$computeLayerConfig()},this.adjustWrapLimit=function(){var e=this.$size.scrollerWidth-this.$padding*2,t=Math.floor(e/this.characterWidth);return this.session.adjustWrapLimit(t,this.$showPrintMargin&&this.$printMarginColumn)},this.setAnimatedScroll=function(e){this.setOption("animatedScroll",e)},this.getAnimatedScroll=function(){return this.$animatedScroll},this.setShowInvisibles=function(e){this.setOption("showInvisibles",e),this.session.$bidiHandler.setShowInvisibles(e)},this.getShowInvisibles=function(){return this.getOption("showInvisibles")},this.getDisplayIndentGuides=function(){return this.getOption("displayIndentGuides")},this.setDisplayIndentGuides=function(e){this.setOption("displayIndentGuides",e)},this.setShowPrintMargin=function(e){this.setOption("showPrintMargin",e)},this.getShowPrintMargin=function(){return this.getOption("showPrintMargin")},this.setPrintMarginColumn=function(e){this.setOption("printMarginColumn",e)},this.getPrintMarginColumn=function(){return this.getOption("printMarginColumn")},this.getShowGutter=function(){return this.getOption("showGutter")},this.setShowGutter=function(e){return this.setOption("showGutter",e)},this.getFadeFoldWidgets=function(){return this.getOption("fadeFoldWidgets")},this.setFadeFoldWidgets=function(e){this.setOption("fadeFoldWidgets",e)},this.setHighlightGutterLine=function(e){this.setOption("highlightGutterLine",e)},this.getHighlightGutterLine=function(){return this.getOption("highlightGutterLine")},this.$updatePrintMargin=function(){if(!this.$showPrintMargin&&!this.$printMarginEl)return;if(!this.$printMarginEl){var e=i.createElement("div");e.className="ace_layer ace_print-margin-layer",this.$printMarginEl=i.createElement("div"),this.$printMarginEl.className="ace_print-margin",e.appendChild(this.$printMarginEl),this.content.insertBefore(e,this.content.firstChild)}var t=this.$printMarginEl.style;t.left=Math.round(this.characterWidth*this.$printMarginColumn+this.$padding)+"px",t.visibility=this.$showPrintMargin?"visible":"hidden",this.session&&this.session.$wrap==-1&&this.adjustWrapLimit()},this.getContainerElement=function(){return this.container},this.getMouseEventTarget=function(){return this.scroller},this.getTextAreaContainer=function(){return this.container},this.$moveTextAreaToCursor=function(){if(this.$isMousePressed)return;var e=this.textarea.style,t=this.$composition;if(!this.$keepTextAreaAtCursor&&!t){i.translate(this.textarea,-100,0);return}var n=this.$cursorLayer.$pixelPos;if(!n)return;t&&t.markerRange&&(n=this.$cursorLayer.getPixelPosition(t.markerRange.start,!0));var r=this.layerConfig,s=n.top,o=n.left;s-=r.offset;var u=t&&t.useTextareaForIME?this.lineHeight:g?0:1;if(s<0||s>r.height-u){i.translate(this.textarea,0,0);return}var a=1,f=this.$size.height-u;if(!t)s+=this.lineHeight;else if(t.useTextareaForIME){var l=this.textarea.value;a=this.characterWidth*this.session.$getStringScreenWidth(l)[0]}else s+=this.lineHeight+2;o-=this.scrollLeft,o>this.$size.scrollerWidth-a&&(o=this.$size.scrollerWidth-a),o+=this.gutterWidth+this.margin.left,i.setStyle(e,"height",u+"px"),i.setStyle(e,"width",a+"px"),i.translate(this.textarea,Math.min(o,this.$size.scrollerWidth-a),Math.min(s,f))},this.getFirstVisibleRow=function(){return this.layerConfig.firstRow},this.getFirstFullyVisibleRow=function(){return this.layerConfig.firstRow+(this.layerConfig.offset===0?0:1)},this.getLastFullyVisibleRow=function(){var e=this.layerConfig,t=e.lastRow,n=this.session.documentToScreenRow(t,0)*e.lineHeight;return n-this.session.getScrollTop()>e.height-e.lineHeight?t-1:t},this.getLastVisibleRow=function(){return this.layerConfig.lastRow},this.$padding=null,this.setPadding=function(e){this.$padding=e,this.$textLayer.setPadding(e),this.$cursorLayer.setPadding(e),this.$markerFront.setPadding(e),this.$markerBack.setPadding(e),this.$loop.schedule(this.CHANGE_FULL),this.$updatePrintMargin()},this.setScrollMargin=function(e,t,n,r){var i=this.scrollMargin;i.top=e|0,i.bottom=t|0,i.right=r|0,i.left=n|0,i.v=i.top+i.bottom,i.h=i.left+i.right,i.top&&this.scrollTop<=0&&this.session&&this.session.setScrollTop(-i.top),this.updateFull()},this.setMargin=function(e,t,n,r){var i=this.margin;i.top=e|0,i.bottom=t|0,i.right=r|0,i.left=n|0,i.v=i.top+i.bottom,i.h=i.left+i.right,this.$updateCachedSize(!0,this.gutterWidth,this.$size.width,this.$size.height),this.updateFull()},this.getHScrollBarAlwaysVisible=function(){return this.$hScrollBarAlwaysVisible},this.setHScrollBarAlwaysVisible=function(e){this.setOption("hScrollBarAlwaysVisible",e)},this.getVScrollBarAlwaysVisible=function(){return this.$vScrollBarAlwaysVisible},this.setVScrollBarAlwaysVisible=function(e){this.setOption("vScrollBarAlwaysVisible",e)},this.$updateScrollBarV=function(){var e=this.layerConfig.maxHeight,t=this.$size.scrollerHeight;!this.$maxLines&&this.$scrollPastEnd&&(e-=(t-this.lineHeight)*this.$scrollPastEnd,this.scrollTop>e-t&&(e=this.scrollTop+t,this.scrollBarV.scrollTop=null)),this.scrollBarV.setScrollHeight(e+this.scrollMargin.v),this.scrollBarV.setScrollTop(this.scrollTop+this.scrollMargin.top)},this.$updateScrollBarH=function(){this.scrollBarH.setScrollWidth(this.layerConfig.width+2*this.$padding+this.scrollMargin.h),this.scrollBarH.setScrollLeft(this.scrollLeft+this.scrollMargin.left)},this.$frozen=!1,this.freeze=function(){this.$frozen=!0},this.unfreeze=function(){this.$frozen=!1},this.$renderChanges=function(e,t){this.$changes&&(e|=this.$changes,this.$changes=0);if(!this.session||!this.container.offsetWidth||this.$frozen||!e&&!t){this.$changes|=e;return}if(this.$size.$dirty)return this.$changes|=e,this.onResize(!0);this.lineHeight||this.$textLayer.checkForSizeChanges(),this._signal("beforeRender",e),this.session&&this.session.$bidiHandler&&this.session.$bidiHandler.updateCharacterWidths(this.$fontMetrics);var n=this.layerConfig;if(e&this.CHANGE_FULL||e&this.CHANGE_SIZE||e&this.CHANGE_TEXT||e&this.CHANGE_LINES||e&this.CHANGE_SCROLL||e&this.CHANGE_H_SCROLL){e|=this.$computeLayerConfig()|this.$loop.clear();if(n.firstRow!=this.layerConfig.firstRow&&n.firstRowScreen==this.layerConfig.firstRowScreen){var r=this.scrollTop+(n.firstRow-this.layerConfig.firstRow)*this.lineHeight;r>0&&(this.scrollTop=r,e|=this.CHANGE_SCROLL,e|=this.$computeLayerConfig()|this.$loop.clear())}n=this.layerConfig,this.$updateScrollBarV(),e&this.CHANGE_H_SCROLL&&this.$updateScrollBarH(),i.translate(this.content,-this.scrollLeft,-n.offset);var s=n.width+2*this.$padding+"px",o=n.minHeight+"px";i.setStyle(this.content.style,"width",s),i.setStyle(this.content.style,"height",o)}e&this.CHANGE_H_SCROLL&&(i.translate(this.content,-this.scrollLeft,-n.offset),this.scroller.className=this.scrollLeft<=0?"ace_scroller":"ace_scroller ace_scroll-left");if(e&this.CHANGE_FULL){this.$changedLines=null,this.$textLayer.update(n),this.$showGutter&&this.$gutterLayer.update(n),this.$markerBack.update(n),this.$markerFront.update(n),this.$cursorLayer.update(n),this.$moveTextAreaToCursor(),this._signal("afterRender",e);return}if(e&this.CHANGE_SCROLL){this.$changedLines=null,e&this.CHANGE_TEXT||e&this.CHANGE_LINES?this.$textLayer.update(n):this.$textLayer.scrollLines(n),this.$showGutter&&(e&this.CHANGE_GUTTER||e&this.CHANGE_LINES?this.$gutterLayer.update(n):this.$gutterLayer.scrollLines(n)),this.$markerBack.update(n),this.$markerFront.update(n),this.$cursorLayer.update(n),this.$moveTextAreaToCursor(),this._signal("afterRender",e);return}e&this.CHANGE_TEXT?(this.$changedLines=null,this.$textLayer.update(n),this.$showGutter&&this.$gutterLayer.update(n)):e&this.CHANGE_LINES?(this.$updateLines()||e&this.CHANGE_GUTTER&&this.$showGutter)&&this.$gutterLayer.update(n):e&this.CHANGE_TEXT||e&this.CHANGE_GUTTER?this.$showGutter&&this.$gutterLayer.update(n):e&this.CHANGE_CURSOR&&this.$highlightGutterLine&&this.$gutterLayer.updateLineHighlight(n),e&this.CHANGE_CURSOR&&(this.$cursorLayer.update(n),this.$moveTextAreaToCursor()),e&(this.CHANGE_MARKER|this.CHANGE_MARKER_FRONT)&&this.$markerFront.update(n),e&(this.CHANGE_MARKER|this.CHANGE_MARKER_BACK)&&this.$markerBack.update(n),this._signal("afterRender",e)},this.$autosize=function(){var e=this.session.getScreenLength()*this.lineHeight,t=this.$maxLines*this.lineHeight,n=Math.min(t,Math.max((this.$minLines||1)*this.lineHeight,e))+this.scrollMargin.v+(this.$extraHeight||0);this.$horizScroll&&(n+=this.scrollBarH.getHeight()),this.$maxPixelHeight&&n>this.$maxPixelHeight&&(n=this.$maxPixelHeight);var r=n<=2*this.lineHeight,i=!r&&e>t;if(n!=this.desiredHeight||this.$size.height!=this.desiredHeight||i!=this.$vScroll){i!=this.$vScroll&&(this.$vScroll=i,this.scrollBarV.setVisible(i));var s=this.container.clientWidth;this.container.style.height=n+"px",this.$updateCachedSize(!0,this.$gutterWidth,s,n),this.desiredHeight=n,this._signal("autosize")}},this.$computeLayerConfig=function(){var e=this.session,t=this.$size,n=t.height<=2*this.lineHeight,r=this.session.getScreenLength(),i=r*this.lineHeight,s=this.$getLongestLine(),o=!n&&(this.$hScrollBarAlwaysVisible||t.scrollerWidth-s-2*this.$padding<0),u=this.$horizScroll!==o;u&&(this.$horizScroll=o,this.scrollBarH.setVisible(o));var a=this.$vScroll;this.$maxLines&&this.lineHeight>1&&this.$autosize();var f=t.scrollerHeight+this.lineHeight,l=!this.$maxLines&&this.$scrollPastEnd?(t.scrollerHeight-this.lineHeight)*this.$scrollPastEnd:0;i+=l;var c=this.scrollMargin;this.session.setScrollTop(Math.max(-c.top,Math.min(this.scrollTop,i-t.scrollerHeight+c.bottom))),this.session.setScrollLeft(Math.max(-c.left,Math.min(this.scrollLeft,s+2*this.$padding-t.scrollerWidth+c.right)));var h=!n&&(this.$vScrollBarAlwaysVisible||t.scrollerHeight-i+l<0||this.scrollTop>c.top),p=a!==h;p&&(this.$vScroll=h,this.scrollBarV.setVisible(h));var d=this.scrollTop%this.lineHeight,v=Math.ceil(f/this.lineHeight)-1,m=Math.max(0,Math.round((this.scrollTop-d)/this.lineHeight)),g=m+v,y,b,w=this.lineHeight;m=e.screenToDocumentRow(m,0);var E=e.getFoldLine(m);E&&(m=E.start.row),y=e.documentToScreenRow(m,0),b=e.getRowLength(m)*w,g=Math.min(e.screenToDocumentRow(g,0),e.getLength()-1),f=t.scrollerHeight+e.getRowLength(g)*w+b,d=this.scrollTop-y*w;var S=0;if(this.layerConfig.width!=s||u)S=this.CHANGE_H_SCROLL;if(u||p)S|=this.$updateCachedSize(!0,this.gutterWidth,t.width,t.height),this._signal("scrollbarVisibilityChanged"),p&&(s=this.$getLongestLine());return this.layerConfig={width:s,padding:this.$padding,firstRow:m,firstRowScreen:y,lastRow:g,lineHeight:w,characterWidth:this.characterWidth,minHeight:f,maxHeight:i,offset:d,gutterOffset:w?Math.max(0,Math.ceil((d+t.height-t.scrollerHeight)/w)):0,height:this.$size.scrollerHeight},this.session.$bidiHandler&&this.session.$bidiHandler.setContentWidth(s-this.$padding),S},this.$updateLines=function(){if(!this.$changedLines)return;var e=this.$changedLines.firstRow,t=this.$changedLines.lastRow;this.$changedLines=null;var n=this.layerConfig;if(e>n.lastRow+1)return;if(tthis.$textLayer.MAX_LINE_LENGTH&&(e=this.$textLayer.MAX_LINE_LENGTH+30),Math.max(this.$size.scrollerWidth-2*this.$padding,Math.round(e*this.characterWidth))},this.updateFrontMarkers=function(){this.$markerFront.setMarkers(this.session.getMarkers(!0)),this.$loop.schedule(this.CHANGE_MARKER_FRONT)},this.updateBackMarkers=function(){this.$markerBack.setMarkers(this.session.getMarkers()),this.$loop.schedule(this.CHANGE_MARKER_BACK)},this.addGutterDecoration=function(e,t){this.$gutterLayer.addGutterDecoration(e,t)},this.removeGutterDecoration=function(e,t){this.$gutterLayer.removeGutterDecoration(e,t)},this.updateBreakpoints=function(e){this.$loop.schedule(this.CHANGE_GUTTER)},this.setAnnotations=function(e){this.$gutterLayer.setAnnotations(e),this.$loop.schedule(this.CHANGE_GUTTER)},this.updateCursor=function(){this.$loop.schedule(this.CHANGE_CURSOR)},this.hideCursor=function(){this.$cursorLayer.hideCursor()},this.showCursor=function(){this.$cursorLayer.showCursor()},this.scrollSelectionIntoView=function(e,t,n){this.scrollCursorIntoView(e,n),this.scrollCursorIntoView(t,n)},this.scrollCursorIntoView=function(e,t,n){if(this.$size.scrollerHeight===0)return;var r=this.$cursorLayer.getPixelPosition(e),i=r.left,s=r.top,o=n&&n.top||0,u=n&&n.bottom||0,a=this.$scrollAnimation?this.session.getScrollTop():this.scrollTop;a+o>s?(t&&a+o>s+this.lineHeight&&(s-=t*this.$size.scrollerHeight),s===0&&(s=-this.scrollMargin.top),this.session.setScrollTop(s)):a+this.$size.scrollerHeight-ui?(i=1-this.scrollMargin.top)return!0;if(t>0&&this.session.getScrollTop()+this.$size.scrollerHeight-this.layerConfig.maxHeight<-1+this.scrollMargin.bottom)return!0;if(e<0&&this.session.getScrollLeft()>=1-this.scrollMargin.left)return!0;if(e>0&&this.session.getScrollLeft()+this.$size.scrollerWidth-this.layerConfig.width<-1+this.scrollMargin.right)return!0},this.pixelToScreenCoordinates=function(e,t){var n;if(this.$hasCssTransforms){n={top:0,left:0};var r=this.$fontMetrics.transformCoordinates([e,t]);e=r[1]-this.gutterWidth-this.margin.left,t=r[0]}else n=this.scroller.getBoundingClientRect();var i=e+this.scrollLeft-n.left-this.$padding,s=i/this.characterWidth,o=Math.floor((t+this.scrollTop-n.top)/this.lineHeight),u=this.$blockCursor?Math.floor(s):Math.round(s);return{row:o,column:u,side:s-u>0?1:-1,offsetX:i}},this.screenToTextCoordinates=function(e,t){var n;if(this.$hasCssTransforms){n={top:0,left:0};var r=this.$fontMetrics.transformCoordinates([e,t]);e=r[1]-this.gutterWidth-this.margin.left,t=r[0]}else n=this.scroller.getBoundingClientRect();var i=e+this.scrollLeft-n.left-this.$padding,s=i/this.characterWidth,o=this.$blockCursor?Math.floor(s):Math.round(s),u=Math.floor((t+this.scrollTop-n.top)/this.lineHeight);return this.session.screenToDocumentPosition(u,Math.max(o,0),i)},this.textToScreenCoordinates=function(e,t){var n=this.scroller.getBoundingClientRect(),r=this.session.documentToScreenPosition(e,t),i=this.$padding+(this.session.$bidiHandler.isBidiRow(r.row,e)?this.session.$bidiHandler.getPosLeft(r.column):Math.round(r.column*this.characterWidth)),s=r.row*this.lineHeight;return{pageX:n.left+i-this.scrollLeft,pageY:n.top+s-this.scrollTop}},this.visualizeFocus=function(){i.addCssClass(this.container,"ace_focus")},this.visualizeBlur=function(){i.removeCssClass(this.container,"ace_focus")},this.showComposition=function(e){this.$composition=e,e.cssText||(e.cssText=this.textarea.style.cssText),e.useTextareaForIME=this.$useTextareaForIME,this.$useTextareaForIME?(i.addCssClass(this.textarea,"ace_composition"),this.textarea.style.cssText="",this.$moveTextAreaToCursor(),this.$cursorLayer.element.style.display="none"):e.markerId=this.session.addMarker(e.markerRange,"ace_composition_marker","text")},this.setCompositionText=function(e){var t=this.session.selection.cursor;this.addToken(e,"composition_placeholder",t.row,t.column),this.$moveTextAreaToCursor()},this.hideComposition=function(){if(!this.$composition)return;this.$composition.markerId&&this.session.removeMarker(this.$composition.markerId),i.removeCssClass(this.textarea,"ace_composition"),this.textarea.style.cssText=this.$composition.cssText,this.$composition=null,this.$cursorLayer.element.style.display=""},this.addToken=function(e,t,n,r){var i=this.session;i.bgTokenizer.lines[n]=null;var s={type:t,value:e},o=i.getTokens(n);if(r==null)o.push(s);else{var u=0;for(var a=0;a50&&e.length>this.$doc.getLength()>>1?this.call("setValue",[this.$doc.getValue()]):this.emit("change",{data:e})}}).call(f.prototype);var l=function(e,t,n){var r=null,i=!1,u=Object.create(s),a=[],l=new f({messageBuffer:a,terminate:function(){},postMessage:function(e){a.push(e);if(!r)return;i?setTimeout(c):c()}});l.setEmitSync=function(e){i=e};var c=function(){var e=a.shift();e.command?r[e.command].apply(r,e.args):e.event&&u._signal(e.event,e.data)};return u.postMessage=function(e){l.onMessage({data:e})},u.callback=function(e,t){this.postMessage({type:"call",id:t,data:e})},u.emit=function(e,t){this.postMessage({type:"event",name:e,data:t})},o.loadModule(["worker",t],function(e){r=new e[n](u);while(a.length)c()}),l};t.UIWorkerClient=l,t.WorkerClient=f,t.createWorker=a}),define("ace/placeholder",["require","exports","module","ace/range","ace/lib/event_emitter","ace/lib/oop"],function(e,t,n){"use strict";var r=e("./range").Range,i=e("./lib/event_emitter").EventEmitter,s=e("./lib/oop"),o=function(e,t,n,r,i,s){var o=this;this.length=t,this.session=e,this.doc=e.getDocument(),this.mainClass=i,this.othersClass=s,this.$onUpdate=this.onUpdate.bind(this),this.doc.on("change",this.$onUpdate),this.$others=r,this.$onCursorChange=function(){setTimeout(function(){o.onCursorChange()})},this.$pos=n;var u=e.getUndoManager().$undoStack||e.getUndoManager().$undostack||{length:-1};this.$undoStackDepth=u.length,this.setup(),e.selection.on("changeCursor",this.$onCursorChange)};(function(){s.implement(this,i),this.setup=function(){var e=this,t=this.doc,n=this.session;this.selectionBefore=n.selection.toJSON(),n.selection.inMultiSelectMode&&n.selection.toSingleRange(),this.pos=t.createAnchor(this.$pos.row,this.$pos.column);var i=this.pos;i.$insertRight=!0,i.detach(),i.markerId=n.addMarker(new r(i.row,i.column,i.row,i.column+this.length),this.mainClass,null,!1),this.others=[],this.$others.forEach(function(n){var r=t.createAnchor(n.row,n.column);r.$insertRight=!0,r.detach(),e.others.push(r)}),n.setUndoSelect(!1)},this.showOtherMarkers=function(){if(this.othersActive)return;var e=this.session,t=this;this.othersActive=!0,this.others.forEach(function(n){n.markerId=e.addMarker(new r(n.row,n.column,n.row,n.column+t.length),t.othersClass,null,!1)})},this.hideOtherMarkers=function(){if(!this.othersActive)return;this.othersActive=!1;for(var e=0;e=this.pos.column&&t.start.column<=this.pos.column+this.length+1,s=t.start.column-this.pos.column;this.updateAnchors(e),i&&(this.length+=n);if(i&&!this.session.$fromUndo)if(e.action==="insert")for(var o=this.others.length-1;o>=0;o--){var u=this.others[o],a={row:u.row,column:u.column+s};this.doc.insertMergedLines(a,e.lines)}else if(e.action==="remove")for(var o=this.others.length-1;o>=0;o--){var u=this.others[o],a={row:u.row,column:u.column+s};this.doc.remove(new r(a.row,a.column,a.row,a.column-n))}this.$updating=!1,this.updateMarkers()},this.updateAnchors=function(e){this.pos.onChange(e);for(var t=this.others.length;t--;)this.others[t].onChange(e);this.updateMarkers()},this.updateMarkers=function(){if(this.$updating)return;var e=this,t=this.session,n=function(n,i){t.removeMarker(n.markerId),n.markerId=t.addMarker(new r(n.row,n.column,n.row,n.column+e.length),i,null,!1)};n(this.pos,this.mainClass);for(var i=this.others.length;i--;)n(this.others[i],this.othersClass)},this.onCursorChange=function(e){if(this.$updating||!this.session)return;var t=this.session.selection.getCursor();t.row===this.pos.row&&t.column>=this.pos.column&&t.column<=this.pos.column+this.length?(this.showOtherMarkers(),this._emit("cursorEnter",e)):(this.hideOtherMarkers(),this._emit("cursorLeave",e))},this.detach=function(){this.session.removeMarker(this.pos&&this.pos.markerId),this.hideOtherMarkers(),this.doc.removeEventListener("change",this.$onUpdate),this.session.selection.removeEventListener("changeCursor",this.$onCursorChange),this.session.setUndoSelect(!0),this.session=null},this.cancel=function(){if(this.$undoStackDepth===-1)return;var e=this.session.getUndoManager(),t=(e.$undoStack||e.$undostack).length-this.$undoStackDepth;for(var n=0;n1?e.multiSelect.joinSelections():e.multiSelect.splitIntoLines()},bindKey:{win:"Ctrl-Alt-L",mac:"Ctrl-Alt-L"},readOnly:!0},{name:"splitSelectionIntoLines",description:"Split into lines",exec:function(e){e.multiSelect.splitIntoLines()},readOnly:!0},{name:"alignCursors",description:"Align cursors",exec:function(e){e.alignCursors()},bindKey:{win:"Ctrl-Alt-A",mac:"Ctrl-Alt-A"},scrollIntoView:"cursor"},{name:"findAll",description:"Find all",exec:function(e){e.findAll()},bindKey:{win:"Ctrl-Alt-K",mac:"Ctrl-Alt-G"},scrollIntoView:"cursor",readOnly:!0}],t.multiSelectCommands=[{name:"singleSelection",description:"Single selection",bindKey:"esc",exec:function(e){e.exitMultiSelectMode()},scrollIntoView:"cursor",readOnly:!0,isAvailable:function(e){return e&&e.inMultiSelectMode}}];var r=e("../keyboard/hash_handler").HashHandler;t.keyboardHandler=new r(t.multiSelectCommands)}),define("ace/multi_select",["require","exports","module","ace/range_list","ace/range","ace/selection","ace/mouse/multi_select_handler","ace/lib/event","ace/lib/lang","ace/commands/multi_select_commands","ace/search","ace/edit_session","ace/editor","ace/config"],function(e,t,n){function h(e,t,n){return c.$options.wrap=!0,c.$options.needle=t,c.$options.backwards=n==-1,c.find(e)}function v(e,t){return e.row==t.row&&e.column==t.column}function m(e){if(e.$multiselectOnSessionChange)return;e.$onAddRange=e.$onAddRange.bind(e),e.$onRemoveRange=e.$onRemoveRange.bind(e),e.$onMultiSelect=e.$onMultiSelect.bind(e),e.$onSingleSelect=e.$onSingleSelect.bind(e),e.$multiselectOnSessionChange=t.onSessionChange.bind(e),e.$checkMultiselectChange=e.$checkMultiselectChange.bind(e),e.$multiselectOnSessionChange(e),e.on("changeSession",e.$multiselectOnSessionChange),e.on("mousedown",o),e.commands.addCommands(f.defaultCommands),g(e)}function g(e){function r(t){n&&(e.renderer.setMouseCursor(""),n=!1)}if(!e.textInput)return;var t=e.textInput.getElement(),n=!1;u.addListener(t,"keydown",function(t){var i=t.keyCode==18&&!(t.ctrlKey||t.shiftKey||t.metaKey);e.$blockSelectEnabled&&i?n||(e.renderer.setMouseCursor("crosshair"),n=!0):n&&r()}),u.addListener(t,"keyup",r),u.addListener(t,"blur",r)}var r=e("./range_list").RangeList,i=e("./range").Range,s=e("./selection").Selection,o=e("./mouse/multi_select_handler").onMouseDown,u=e("./lib/event"),a=e("./lib/lang"),f=e("./commands/multi_select_commands");t.commands=f.defaultCommands.concat(f.multiSelectCommands);var l=e("./search").Search,c=new l,p=e("./edit_session").EditSession;(function(){this.getSelectionMarkers=function(){return this.$selectionMarkers}}).call(p.prototype),function(){this.ranges=null,this.rangeList=null,this.addRange=function(e,t){if(!e)return;if(!this.inMultiSelectMode&&this.rangeCount===0){var n=this.toOrientedRange();this.rangeList.add(n),this.rangeList.add(e);if(this.rangeList.ranges.length!=2)return this.rangeList.removeAll(),t||this.fromOrientedRange(e);this.rangeList.removeAll(),this.rangeList.add(n),this.$onAddRange(n)}e.cursor||(e.cursor=e.end);var r=this.rangeList.add(e);return this.$onAddRange(e),r.length&&this.$onRemoveRange(r),this.rangeCount>1&&!this.inMultiSelectMode&&(this._signal("multiSelect"),this.inMultiSelectMode=!0,this.session.$undoSelect=!1,this.rangeList.attach(this.session)),t||this.fromOrientedRange(e)},this.toSingleRange=function(e){e=e||this.ranges[0];var t=this.rangeList.removeAll();t.length&&this.$onRemoveRange(t),e&&this.fromOrientedRange(e)},this.substractPoint=function(e){var t=this.rangeList.substractPoint(e);if(t)return this.$onRemoveRange(t),t[0]},this.mergeOverlappingRanges=function(){var e=this.rangeList.merge();e.length&&this.$onRemoveRange(e)},this.$onAddRange=function(e){this.rangeCount=this.rangeList.ranges.length,this.ranges.unshift(e),this._signal("addRange",{range:e})},this.$onRemoveRange=function(e){this.rangeCount=this.rangeList.ranges.length;if(this.rangeCount==1&&this.inMultiSelectMode){var t=this.rangeList.ranges.pop();e.push(t),this.rangeCount=0}for(var n=e.length;n--;){var r=this.ranges.indexOf(e[n]);this.ranges.splice(r,1)}this._signal("removeRange",{ranges:e}),this.rangeCount===0&&this.inMultiSelectMode&&(this.inMultiSelectMode=!1,this._signal("singleSelect"),this.session.$undoSelect=!0,this.rangeList.detach(this.session)),t=t||this.ranges[0],t&&!t.isEqual(this.getRange())&&this.fromOrientedRange(t)},this.$initRangeList=function(){if(this.rangeList)return;this.rangeList=new r,this.ranges=[],this.rangeCount=0},this.getAllRanges=function(){return this.rangeCount?this.rangeList.ranges.concat():[this.getRange()]},this.splitIntoLines=function(){var e=this.ranges.length?this.ranges:[this.getRange()],t=[];for(var n=0;n1){var e=this.rangeList.ranges,t=e[e.length-1],n=i.fromPoints(e[0].start,t.end);this.toSingleRange(),this.setSelectionRange(n,t.cursor==t.start)}else{var r=this.session.documentToScreenPosition(this.cursor),s=this.session.documentToScreenPosition(this.anchor),o=this.rectangularRangeBlock(r,s);o.forEach(this.addRange,this)}},this.rectangularRangeBlock=function(e,t,n){var r=[],s=e.column0)g--;if(g>0){var y=0;while(r[y].isEmpty())y++}for(var b=g;b>=y;b--)r[b].isEmpty()&&r.splice(b,1)}return r}}.call(s.prototype);var d=e("./editor").Editor;(function(){this.updateSelectionMarkers=function(){this.renderer.updateCursor(),this.renderer.updateBackMarkers()},this.addSelectionMarker=function(e){e.cursor||(e.cursor=e.end);var t=this.getSelectionStyle();return e.marker=this.session.addMarker(e,"ace_selection",t),this.session.$selectionMarkers.push(e),this.session.selectionMarkerCount=this.session.$selectionMarkers.length,e},this.removeSelectionMarker=function(e){if(!e.marker)return;this.session.removeMarker(e.marker);var t=this.session.$selectionMarkers.indexOf(e);t!=-1&&this.session.$selectionMarkers.splice(t,1),this.session.selectionMarkerCount=this.session.$selectionMarkers.length},this.removeSelectionMarkers=function(e){var t=this.session.$selectionMarkers;for(var n=e.length;n--;){var r=e[n];if(!r.marker)continue;this.session.removeMarker(r.marker);var i=t.indexOf(r);i!=-1&&t.splice(i,1)}this.session.selectionMarkerCount=t.length},this.$onAddRange=function(e){this.addSelectionMarker(e.range),this.renderer.updateCursor(),this.renderer.updateBackMarkers()},this.$onRemoveRange=function(e){this.removeSelectionMarkers(e.ranges),this.renderer.updateCursor(),this.renderer.updateBackMarkers()},this.$onMultiSelect=function(e){if(this.inMultiSelectMode)return;this.inMultiSelectMode=!0,this.setStyle("ace_multiselect"),this.keyBinding.addKeyboardHandler(f.keyboardHandler),this.commands.setDefaultHandler("exec",this.$onMultiSelectExec),this.renderer.updateCursor(),this.renderer.updateBackMarkers()},this.$onSingleSelect=function(e){if(this.session.multiSelect.inVirtualMode)return;this.inMultiSelectMode=!1,this.unsetStyle("ace_multiselect"),this.keyBinding.removeKeyboardHandler(f.keyboardHandler),this.commands.removeDefaultHandler("exec",this.$onMultiSelectExec),this.renderer.updateCursor(),this.renderer.updateBackMarkers(),this._emit("changeSelection")},this.$onMultiSelectExec=function(e){var t=e.command,n=e.editor;if(!n.multiSelect)return;if(!t.multiSelectAction){var r=t.exec(n,e.args||{});n.multiSelect.addRange(n.multiSelect.toOrientedRange()),n.multiSelect.mergeOverlappingRanges()}else t.multiSelectAction=="forEach"?r=n.forEachSelection(t,e.args):t.multiSelectAction=="forEachLine"?r=n.forEachSelection(t,e.args,!0):t.multiSelectAction=="single"?(n.exitMultiSelectMode(),r=t.exec(n,e.args||{})):r=t.multiSelectAction(n,e.args||{});return r},this.forEachSelection=function(e,t,n){if(this.inVirtualSelectionMode)return;var r=n&&n.keepOrder,i=n==1||n&&n.$byLines,o=this.session,u=this.selection,a=u.rangeList,f=(r?u:a).ranges,l;if(!f.length)return e.exec?e.exec(this,t||{}):e(this,t||{});var c=u._eventRegistry;u._eventRegistry={};var h=new s(o);this.inVirtualSelectionMode=!0;for(var p=f.length;p--;){if(i)while(p>0&&f[p].start.row==f[p-1].end.row)p--;h.fromOrientedRange(f[p]),h.index=p,this.selection=o.selection=h;var d=e.exec?e.exec(this,t||{}):e(this,t||{});!l&&d!==undefined&&(l=d),h.toOrientedRange(f[p])}h.detach(),this.selection=o.selection=u,this.inVirtualSelectionMode=!1,u._eventRegistry=c,u.mergeOverlappingRanges(),u.ranges[0]&&u.fromOrientedRange(u.ranges[0]);var v=this.renderer.$scrollAnimation;return this.onCursorChange(),this.onSelectionChange(),v&&v.from==v.to&&this.renderer.animateScrolling(v.from),l},this.exitMultiSelectMode=function(){if(!this.inMultiSelectMode||this.inVirtualSelectionMode)return;this.multiSelect.toSingleRange()},this.getSelectedText=function(){var e="";if(this.inMultiSelectMode&&!this.inVirtualSelectionMode){var t=this.multiSelect.rangeList.ranges,n=[];for(var r=0;r0);u<0&&(u=0),f>=c&&(f=c-1)}var p=this.session.removeFullLines(u,f);p=this.$reAlignText(p,l),this.session.insert({row:u,column:0},p.join("\n")+"\n"),l||(o.start.column=0,o.end.column=p[p.length-1].length),this.selection.setRange(o)}else{s.forEach(function(e){t.substractPoint(e.cursor)});var d=0,v=Infinity,m=n.map(function(t){var n=t.cursor,r=e.getLine(n.row),i=r.substr(n.column).search(/\S/g);return i==-1&&(i=0),n.column>d&&(d=n.column),io?e.insert(r,a.stringRepeat(" ",s-o)):e.remove(new i(r.row,r.column,r.row,r.column-s+o)),t.start.column=t.end.column=d,t.start.row=t.end.row=r.row,t.cursor=t.end}),t.fromOrientedRange(n[0]),this.renderer.updateCursor(),this.renderer.updateBackMarkers()}},this.$reAlignText=function(e,t){function u(e){return a.stringRepeat(" ",e)}function f(e){return e[2]?u(i)+e[2]+u(s-e[2].length+o)+e[4].replace(/^([=:])\s+/,"$1 "):e[0]}function l(e){return e[2]?u(i+s-e[2].length)+e[2]+u(o)+e[4].replace(/^([=:])\s+/,"$1 "):e[0]}function c(e){return e[2]?u(i)+e[2]+u(o)+e[4].replace(/^([=:])\s+/,"$1 "):e[0]}var n=!0,r=!0,i,s,o;return e.map(function(e){var t=e.match(/(\s*)(.*?)(\s*)([=:].*)/);return t?i==null?(i=t[1].length,s=t[2].length,o=t[3].length,t):(i+s+o!=t[1].length+t[2].length+t[3].length&&(r=!1),i!=t[1].length&&(n=!1),i>t[1].length&&(i=t[1].length),st[3].length&&(o=t[3].length),t):[e]}).map(t?f:n?r?l:f:c)}}).call(d.prototype),t.onSessionChange=function(e){var t=e.session;t&&!t.multiSelect&&(t.$selectionMarkers=[],t.selection.$initRangeList(),t.multiSelect=t.selection),this.multiSelect=t&&t.multiSelect;var n=e.oldSession;n&&(n.multiSelect.off("addRange",this.$onAddRange),n.multiSelect.off("removeRange",this.$onRemoveRange),n.multiSelect.off("multiSelect",this.$onMultiSelect),n.multiSelect.off("singleSelect",this.$onSingleSelect),n.multiSelect.lead.off("change",this.$checkMultiselectChange),n.multiSelect.anchor.off("change",this.$checkMultiselectChange)),t&&(t.multiSelect.on("addRange",this.$onAddRange),t.multiSelect.on("removeRange",this.$onRemoveRange),t.multiSelect.on("multiSelect",this.$onMultiSelect),t.multiSelect.on("singleSelect",this.$onSingleSelect),t.multiSelect.lead.on("change",this.$checkMultiselectChange),t.multiSelect.anchor.on("change",this.$checkMultiselectChange)),t&&this.inMultiSelectMode!=t.selection.inMultiSelectMode&&(t.selection.inMultiSelectMode?this.$onMultiSelect():this.$onSingleSelect())},t.MultiSelect=m,e("./config").defineOptions(d.prototype,"editor",{enableMultiselect:{set:function(e){m(this),e?(this.on("changeSession",this.$multiselectOnSessionChange),this.on("mousedown",o)):(this.off("changeSession",this.$multiselectOnSessionChange),this.off("mousedown",o))},value:!0},enableBlockSelect:{set:function(e){this.$blockSelectEnabled=e},value:!0}})}),define("ace/mode/folding/fold_mode",["require","exports","module","ace/range"],function(e,t,n){"use strict";var r=e("../../range").Range,i=t.FoldMode=function(){};(function(){this.foldingStartMarker=null,this.foldingStopMarker=null,this.getFoldWidget=function(e,t,n){var r=e.getLine(n);return this.foldingStartMarker.test(r)?"start":t=="markbeginend"&&this.foldingStopMarker&&this.foldingStopMarker.test(r)?"end":""},this.getFoldWidgetRange=function(e,t,n){return null},this.indentationBlock=function(e,t,n){var i=/\S/,s=e.getLine(t),o=s.search(i);if(o==-1)return;var u=n||s.length,a=e.getLength(),f=t,l=t;while(++tf){var p=e.getLine(l).length;return new r(f,u,l,p)}},this.openingBracketBlock=function(e,t,n,i,s){var o={row:n,column:i+1},u=e.$findClosingBracket(t,o,s);if(!u)return;var a=e.foldWidgets[u.row];return a==null&&(a=e.getFoldWidget(u.row)),a=="start"&&u.row>o.row&&(u.row--,u.column=e.getLine(u.row).length),r.fromPoints(o,u)},this.closingBracketBlock=function(e,t,n,i,s){var o={row:n,column:i},u=e.$findOpeningBracket(t,o);if(!u)return;return u.column++,o.column--,r.fromPoints(u,o)}}).call(i.prototype)}),define("ace/theme/textmate",["require","exports","module","ace/lib/dom"],function(e,t,n){"use strict";t.isDark=!1,t.cssClass="ace-tm",t.cssText='.ace-tm .ace_gutter {background: #f0f0f0;color: #333;}.ace-tm .ace_print-margin {width: 1px;background: #e8e8e8;}.ace-tm .ace_fold {background-color: #6B72E6;}.ace-tm {background-color: #FFFFFF;color: black;}.ace-tm .ace_cursor {color: black;}.ace-tm .ace_invisible {color: rgb(191, 191, 191);}.ace-tm .ace_storage,.ace-tm .ace_keyword {color: blue;}.ace-tm .ace_constant {color: rgb(197, 6, 11);}.ace-tm .ace_constant.ace_buildin {color: rgb(88, 72, 246);}.ace-tm .ace_constant.ace_language {color: rgb(88, 92, 246);}.ace-tm .ace_constant.ace_library {color: rgb(6, 150, 14);}.ace-tm .ace_invalid {background-color: rgba(255, 0, 0, 0.1);color: red;}.ace-tm .ace_support.ace_function {color: rgb(60, 76, 114);}.ace-tm .ace_support.ace_constant {color: rgb(6, 150, 14);}.ace-tm .ace_support.ace_type,.ace-tm .ace_support.ace_class {color: rgb(109, 121, 222);}.ace-tm .ace_keyword.ace_operator {color: rgb(104, 118, 135);}.ace-tm .ace_string {color: rgb(3, 106, 7);}.ace-tm .ace_comment {color: rgb(76, 136, 107);}.ace-tm .ace_comment.ace_doc {color: rgb(0, 102, 255);}.ace-tm .ace_comment.ace_doc.ace_tag {color: rgb(128, 159, 191);}.ace-tm .ace_constant.ace_numeric {color: rgb(0, 0, 205);}.ace-tm .ace_variable {color: rgb(49, 132, 149);}.ace-tm .ace_xml-pe {color: rgb(104, 104, 91);}.ace-tm .ace_entity.ace_name.ace_function {color: #0000A2;}.ace-tm .ace_heading {color: rgb(12, 7, 255);}.ace-tm .ace_list {color:rgb(185, 6, 144);}.ace-tm .ace_meta.ace_tag {color:rgb(0, 22, 142);}.ace-tm .ace_string.ace_regex {color: rgb(255, 0, 0)}.ace-tm .ace_marker-layer .ace_selection {background: rgb(181, 213, 255);}.ace-tm.ace_multiselect .ace_selection.ace_start {box-shadow: 0 0 3px 0px white;}.ace-tm .ace_marker-layer .ace_step {background: rgb(252, 255, 0);}.ace-tm .ace_marker-layer .ace_stack {background: rgb(164, 229, 101);}.ace-tm .ace_marker-layer .ace_bracket {margin: -1px 0 0 -1px;border: 1px solid rgb(192, 192, 192);}.ace-tm .ace_marker-layer .ace_active-line {background: rgba(0, 0, 0, 0.07);}.ace-tm .ace_gutter-active-line {background-color : #dcdcdc;}.ace-tm .ace_marker-layer .ace_selected-word {background: rgb(250, 250, 255);border: 1px solid rgb(200, 200, 250);}.ace-tm .ace_indent-guide {background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAE0lEQVQImWP4////f4bLly//BwAmVgd1/w11/gAAAABJRU5ErkJggg==") right repeat-y;}',t.$id="ace/theme/textmate";var r=e("../lib/dom");r.importCssString(t.cssText,t.cssClass)}),define("ace/line_widgets",["require","exports","module","ace/lib/dom"],function(e,t,n){"use strict";function i(e){this.session=e,this.session.widgetManager=this,this.session.getRowLength=this.getRowLength,this.session.$getWidgetScreenLength=this.$getWidgetScreenLength,this.updateOnChange=this.updateOnChange.bind(this),this.renderWidgets=this.renderWidgets.bind(this),this.measureWidgets=this.measureWidgets.bind(this),this.session._changedWidgets=[],this.$onChangeEditor=this.$onChangeEditor.bind(this),this.session.on("change",this.updateOnChange),this.session.on("changeFold",this.updateOnFold),this.session.on("changeEditor",this.$onChangeEditor)}var r=e("./lib/dom");(function(){this.getRowLength=function(e){var t;return this.lineWidgets?t=this.lineWidgets[e]&&this.lineWidgets[e].rowCount||0:t=0,!this.$useWrapMode||!this.$wrapData[e]?1+t:this.$wrapData[e].length+1+t},this.$getWidgetScreenLength=function(){var e=0;return this.lineWidgets.forEach(function(t){t&&t.rowCount&&!t.hidden&&(e+=t.rowCount)}),e},this.$onChangeEditor=function(e){this.attach(e.editor)},this.attach=function(e){e&&e.widgetManager&&e.widgetManager!=this&&e.widgetManager.detach();if(this.editor==e)return;this.detach(),this.editor=e,e&&(e.widgetManager=this,e.renderer.on("beforeRender",this.measureWidgets),e.renderer.on("afterRender",this.renderWidgets))},this.detach=function(e){var t=this.editor;if(!t)return;this.editor=null,t.widgetManager=null,t.renderer.off("beforeRender",this.measureWidgets),t.renderer.off("afterRender",this.renderWidgets);var n=this.session.lineWidgets;n&&n.forEach(function(e){e&&e.el&&e.el.parentNode&&(e._inDocument=!1,e.el.parentNode.removeChild(e.el))})},this.updateOnFold=function(e,t){var n=t.lineWidgets;if(!n||!e.action)return;var r=e.data,i=r.start.row,s=r.end.row,o=e.action=="add";for(var u=i+1;ut[n].column&&n++,s.unshift(n,0),t.splice.apply(t,s),this.$updateRows()}},this.$updateRows=function(){var e=this.session.lineWidgets;if(!e)return;var t=!0;e.forEach(function(e,n){if(e){t=!1,e.row=n;while(e.$oldWidget)e.$oldWidget.row=n,e=e.$oldWidget}}),t&&(this.session.lineWidgets=null)},this.$registerLineWidget=function(e){this.session.lineWidgets||(this.session.lineWidgets=new Array(this.session.getLength()));var t=this.session.lineWidgets[e.row];return t&&(e.$oldWidget=t,t.el&&t.el.parentNode&&(t.el.parentNode.removeChild(t.el),t._inDocument=!1)),this.session.lineWidgets[e.row]=e,e},this.addLineWidget=function(e){this.$registerLineWidget(e),e.session=this.session;if(!this.editor)return e;var t=this.editor.renderer;e.html&&!e.el&&(e.el=r.createElement("div"),e.el.innerHTML=e.html),e.el&&(r.addCssClass(e.el,"ace_lineWidgetContainer"),e.el.style.position="absolute",e.el.style.zIndex=5,t.container.appendChild(e.el),e._inDocument=!0,e.coverGutter||(e.el.style.zIndex=3),e.pixelHeight==null&&(e.pixelHeight=e.el.offsetHeight)),e.rowCount==null&&(e.rowCount=e.pixelHeight/t.layerConfig.lineHeight);var n=this.session.getFoldAt(e.row,0);e.$fold=n;if(n){var i=this.session.lineWidgets;e.row==n.end.row&&!i[n.start.row]?i[n.start.row]=e:e.hidden=!0}return this.session._emit("changeFold",{data:{start:{row:e.row}}}),this.$updateRows(),this.renderWidgets(null,t),this.onWidgetChanged(e),e},this.removeLineWidget=function(e){e._inDocument=!1,e.session=null,e.el&&e.el.parentNode&&e.el.parentNode.removeChild(e.el);if(e.editor&&e.editor.destroy)try{e.editor.destroy()}catch(t){}if(this.session.lineWidgets){var n=this.session.lineWidgets[e.row];if(n==e)this.session.lineWidgets[e.row]=e.$oldWidget,e.$oldWidget&&this.onWidgetChanged(e.$oldWidget);else while(n){if(n.$oldWidget==e){n.$oldWidget=e.$oldWidget;break}n=n.$oldWidget}}this.session._emit("changeFold",{data:{start:{row:e.row}}}),this.$updateRows()},this.getWidgetsAtRow=function(e){var t=this.session.lineWidgets,n=t&&t[e],r=[];while(n)r.push(n),n=n.$oldWidget;return r},this.onWidgetChanged=function(e){this.session._changedWidgets.push(e),this.editor&&this.editor.renderer.updateFull()},this.measureWidgets=function(e,t){var n=this.session._changedWidgets,r=t.layerConfig;if(!n||!n.length)return;var i=Infinity;for(var s=0;s0&&!r[i])i--;this.firstRow=n.firstRow,this.lastRow=n.lastRow,t.$cursorLayer.config=n;for(var o=i;o<=s;o++){var u=r[o];if(!u||!u.el)continue;if(u.hidden){u.el.style.top=-100-(u.pixelHeight||0)+"px";continue}u._inDocument||(u._inDocument=!0,t.container.appendChild(u.el));var a=t.$cursorLayer.getPixelPosition({row:o,column:0},!0).top;u.coverLine||(a+=n.lineHeight*this.session.getRowLineCount(u.row)),u.el.style.top=a-n.offset+"px";var f=u.coverGutter?0:t.gutterWidth;u.fixedWidth||(f-=t.scrollLeft),u.el.style.left=f+"px",u.fullWidth&&u.screenWidth&&(u.el.style.minWidth=n.width+2*n.padding+"px"),u.fixedWidth?u.el.style.right=t.scrollBar.getWidth()+"px":u.el.style.right=""}}}).call(i.prototype),t.LineWidgets=i}),define("ace/ext/error_marker",["require","exports","module","ace/line_widgets","ace/lib/dom","ace/range"],function(e,t,n){"use strict";function o(e,t,n){var r=0,i=e.length-1;while(r<=i){var s=r+i>>1,o=n(t,e[s]);if(o>0)r=s+1;else{if(!(o<0))return s;i=s-1}}return-(r+1)}function u(e,t,n){var r=e.getAnnotations().sort(s.comparePoints);if(!r.length)return;var i=o(r,{row:t,column:-1},s.comparePoints);i<0&&(i=-i-1),i>=r.length?i=n>0?0:r.length-1:i===0&&n<0&&(i=r.length-1);var u=r[i];if(!u||!n)return;if(u.row===t){do u=r[i+=n];while(u&&u.row===t);if(!u)return r.slice()}var a=[];t=u.row;do a[n<0?"unshift":"push"](u),u=r[i+=n];while(u&&u.row==t);return a.length&&a}var r=e("../line_widgets").LineWidgets,i=e("../lib/dom"),s=e("../range").Range;t.showErrorMarker=function(e,t){var n=e.session;n.widgetManager||(n.widgetManager=new r(n),n.widgetManager.attach(e));var s=e.getCursorPosition(),o=s.row,a=n.widgetManager.getWidgetsAtRow(o).filter(function(e){return e.type=="errorMarker"})[0];a?a.destroy():o-=t;var f=u(n,o,t),l;if(f){var c=f[0];s.column=(c.pos&&typeof c.column!="number"?c.pos.sc:c.column)||0,s.row=c.row,l=e.renderer.$gutterLayer.$annotations[s.row]}else{if(a)return;l={text:["Looks good!"],className:"ace_ok"}}e.session.unfold(s.row),e.selection.moveToPosition(s);var h={row:s.row,fixedWidth:!0,coverGutter:!0,el:i.createElement("div"),type:"errorMarker"},p=h.el.appendChild(i.createElement("div")),d=h.el.appendChild(i.createElement("div"));d.className="error_widget_arrow "+l.className;var v=e.renderer.$cursorLayer.getPixelPosition(s).left;d.style.left=v+e.renderer.gutterWidth-5+"px",h.el.className="error_widget_wrapper",p.className="error_widget "+l.className,p.innerHTML=l.text.join("
"),p.appendChild(i.createElement("div"));var m=function(e,t,n){if(t===0&&(n==="esc"||n==="return"))return h.destroy(),{command:"null"}};h.destroy=function(){if(e.$mouseHandler.isMousePressed)return;e.keyBinding.removeKeyboardHandler(m),n.widgetManager.removeLineWidget(h),e.off("changeSelection",h.destroy),e.off("changeSession",h.destroy),e.off("mouseup",h.destroy),e.off("change",h.destroy)},e.keyBinding.addKeyboardHandler(m),e.on("changeSelection",h.destroy),e.on("changeSession",h.destroy),e.on("mouseup",h.destroy),e.on("change",h.destroy),e.session.widgetManager.addLineWidget(h),h.el.onmousedown=e.focus.bind(e),e.renderer.scrollCursorIntoView(null,.5,{bottom:h.el.offsetHeight})},i.importCssString(" .error_widget_wrapper { background: inherit; color: inherit; border:none } .error_widget { border-top: solid 2px; border-bottom: solid 2px; margin: 5px 0; padding: 10px 40px; white-space: pre-wrap; } .error_widget.ace_error, .error_widget_arrow.ace_error{ border-color: #ff5a5a } .error_widget.ace_warning, .error_widget_arrow.ace_warning{ border-color: #F1D817 } .error_widget.ace_info, .error_widget_arrow.ace_info{ border-color: #5a5a5a } .error_widget.ace_ok, .error_widget_arrow.ace_ok{ border-color: #5aaa5a } .error_widget_arrow { position: absolute; border: solid 5px; border-top-color: transparent!important; border-right-color: transparent!important; border-left-color: transparent!important; top: -5px; }","")}),define("ace/ace",["require","exports","module","ace/lib/fixoldbrowsers","ace/lib/dom","ace/lib/event","ace/range","ace/editor","ace/edit_session","ace/undomanager","ace/virtual_renderer","ace/worker/worker_client","ace/keyboard/hash_handler","ace/placeholder","ace/multi_select","ace/mode/folding/fold_mode","ace/theme/textmate","ace/ext/error_marker","ace/config"],function(e,t,n){"use strict";e("./lib/fixoldbrowsers");var r=e("./lib/dom"),i=e("./lib/event"),s=e("./range").Range,o=e("./editor").Editor,u=e("./edit_session").EditSession,a=e("./undomanager").UndoManager,f=e("./virtual_renderer").VirtualRenderer;e("./worker/worker_client"),e("./keyboard/hash_handler"),e("./placeholder"),e("./multi_select"),e("./mode/folding/fold_mode"),e("./theme/textmate"),e("./ext/error_marker"),t.config=e("./config"),t.require=e,typeof define=="function"&&(t.define=define),t.edit=function(e,n){if(typeof e=="string"){var s=e;e=document.getElementById(s);if(!e)throw new Error("ace.edit can't find div #"+s)}if(e&&e.env&&e.env.editor instanceof o)return e.env.editor;var u="";if(e&&/input|textarea/i.test(e.tagName)){var a=e;u=a.value,e=r.createElement("pre"),a.parentNode.replaceChild(e,a)}else e&&(u=e.textContent,e.innerHTML="");var l=t.createEditSession(u),c=new o(new f(e),l,n),h={document:l,editor:c,onResize:c.resize.bind(c,null)};return a&&(h.textarea=a),i.addListener(window,"resize",h.onResize),c.on("destroy",function(){i.removeListener(window,"resize",h.onResize),h.editor.container.env=null}),c.container.env=c.env=h,c},t.createEditSession=function(e,t){var n=new u(e,t);return n.setUndoManager(new a),n},t.Range=s,t.Editor=o,t.EditSession=u,t.UndoManager=a,t.VirtualRenderer=f,t.version=t.config.version}); (function() { - window.require(["ace/ace"], function(a) { - if (a) { - a.config.init(true); - a.define = window.define; - } - if (!window.ace) - window.ace = a; - for (var key in a) if (a.hasOwnProperty(key)) - window.ace[key] = a[key]; - window.ace["default"] = window.ace; - if (typeof module == "object" && typeof exports == "object" && module) { - module.exports = window.ace; - } - }); - })(); -define("ace/mode/doc_comment_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){this.$rules={start:[{token:"comment.doc.tag",regex:"@[\\w\\d_]+"},s.getTagRule(),{defaultToken:"comment.doc",caseInsensitive:!0}]}};r.inherits(s,i),s.getTagRule=function(e){return{token:"comment.doc.tag.storage.type",regex:"\\b(?:TODO|FIXME|XXX|HACK)\\b"}},s.getStartRule=function(e){return{token:"comment.doc",regex:"\\/\\*(?=\\*)",next:e}},s.getEndRule=function(e){return{token:"comment.doc",regex:"\\*\\/",next:e}},t.DocCommentHighlightRules=s}),define("ace/mode/javascript_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/doc_comment_highlight_rules","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";function a(){var e=o.replace("\\d","\\d\\-"),t={onMatch:function(e,t,n){var r=e.charAt(1)=="/"?2:1;if(r==1)t!=this.nextState?n.unshift(this.next,this.nextState,0):n.unshift(this.next),n[2]++;else if(r==2&&t==this.nextState){n[1]--;if(!n[1]||n[1]<0)n.shift(),n.shift()}return[{type:"meta.tag.punctuation."+(r==1?"":"end-")+"tag-open.xml",value:e.slice(0,r)},{type:"meta.tag.tag-name.xml",value:e.substr(r)}]},regex:"",onMatch:function(e,t,n){return t==n[0]&&n.shift(),e.length==2&&(n[0]==this.nextState&&n[1]--,(!n[1]||n[1]<0)&&n.splice(0,2)),this.next=n[0]||"start",[{type:this.token,value:e}]},nextState:"jsx"},n,f("jsxAttributes"),{token:"entity.other.attribute-name.xml",regex:e},{token:"keyword.operator.attribute-equals.xml",regex:"="},{token:"text.tag-whitespace.xml",regex:"\\s+"},{token:"string.attribute-value.xml",regex:"'",stateName:"jsx_attr_q",push:[{token:"string.attribute-value.xml",regex:"'",next:"pop"},{include:"reference"},{defaultToken:"string.attribute-value.xml"}]},{token:"string.attribute-value.xml",regex:'"',stateName:"jsx_attr_qq",push:[{token:"string.attribute-value.xml",regex:'"',next:"pop"},{include:"reference"},{defaultToken:"string.attribute-value.xml"}]},t],this.$rules.reference=[{token:"constant.language.escape.reference.xml",regex:"(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)"}]}function f(e){return[{token:"comment",regex:/\/\*/,next:[i.getTagRule(),{token:"comment",regex:"\\*\\/",next:e||"pop"},{defaultToken:"comment",caseInsensitive:!0}]},{token:"comment",regex:"\\/\\/",next:[i.getTagRule(),{token:"comment",regex:"$|^",next:e||"pop"},{defaultToken:"comment",caseInsensitive:!0}]}]}var r=e("../lib/oop"),i=e("./doc_comment_highlight_rules").DocCommentHighlightRules,s=e("./text_highlight_rules").TextHighlightRules,o="[a-zA-Z\\$_\u00a1-\uffff][a-zA-Z\\d\\$_\u00a1-\uffff]*",u=function(e){var t=this.createKeywordMapper({"variable.language":"Array|Boolean|Date|Function|Iterator|Number|Object|RegExp|String|Proxy|Namespace|QName|XML|XMLList|ArrayBuffer|Float32Array|Float64Array|Int16Array|Int32Array|Int8Array|Uint16Array|Uint32Array|Uint8Array|Uint8ClampedArray|Error|EvalError|InternalError|RangeError|ReferenceError|StopIteration|SyntaxError|TypeError|URIError|decodeURI|decodeURIComponent|encodeURI|encodeURIComponent|eval|isFinite|isNaN|parseFloat|parseInt|JSON|Math|this|arguments|prototype|window|document",keyword:"const|yield|import|get|set|async|await|break|case|catch|continue|default|delete|do|else|finally|for|function|if|in|of|instanceof|new|return|switch|throw|try|typeof|let|var|while|with|debugger|__parent__|__count__|escape|unescape|with|__proto__|class|enum|extends|super|export|implements|private|public|interface|package|protected|static","storage.type":"const|let|var|function","constant.language":"null|Infinity|NaN|undefined","support.function":"alert","constant.language.boolean":"true|false"},"identifier"),n="case|do|else|finally|in|instanceof|return|throw|try|typeof|yield|void",r="\\\\(?:x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|u{[0-9a-fA-F]{1,6}}|[0-2][0-7]{0,2}|3[0-7][0-7]?|[4-7][0-7]?|.)";this.$rules={no_regex:[i.getStartRule("doc-start"),f("no_regex"),{token:"string",regex:"'(?=.)",next:"qstring"},{token:"string",regex:'"(?=.)',next:"qqstring"},{token:"constant.numeric",regex:/0(?:[xX][0-9a-fA-F]+|[oO][0-7]+|[bB][01]+)\b/},{token:"constant.numeric",regex:/(?:\d\d*(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+\b)?/},{token:["storage.type","punctuation.operator","support.function","punctuation.operator","entity.name.function","text","keyword.operator"],regex:"("+o+")(\\.)(prototype)(\\.)("+o+")(\\s*)(=)",next:"function_arguments"},{token:["storage.type","punctuation.operator","entity.name.function","text","keyword.operator","text","storage.type","text","paren.lparen"],regex:"("+o+")(\\.)("+o+")(\\s*)(=)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["entity.name.function","text","keyword.operator","text","storage.type","text","paren.lparen"],regex:"("+o+")(\\s*)(=)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["storage.type","punctuation.operator","entity.name.function","text","keyword.operator","text","storage.type","text","entity.name.function","text","paren.lparen"],regex:"("+o+")(\\.)("+o+")(\\s*)(=)(\\s*)(function)(\\s+)(\\w+)(\\s*)(\\()",next:"function_arguments"},{token:["storage.type","text","entity.name.function","text","paren.lparen"],regex:"(function)(\\s+)("+o+")(\\s*)(\\()",next:"function_arguments"},{token:["entity.name.function","text","punctuation.operator","text","storage.type","text","paren.lparen"],regex:"("+o+")(\\s*)(:)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["text","text","storage.type","text","paren.lparen"],regex:"(:)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:"keyword",regex:"from(?=\\s*('|\"))"},{token:"keyword",regex:"(?:"+n+")\\b",next:"start"},{token:["support.constant"],regex:/that\b/},{token:["storage.type","punctuation.operator","support.function.firebug"],regex:/(console)(\.)(warn|info|log|error|time|trace|timeEnd|assert)\b/},{token:t,regex:o},{token:"punctuation.operator",regex:/[.](?![.])/,next:"property"},{token:"storage.type",regex:/=>/,next:"start"},{token:"keyword.operator",regex:/--|\+\+|\.{3}|===|==|=|!=|!==|<+=?|>+=?|!|&&|\|\||\?:|[!$%&*+\-~\/^]=?/,next:"start"},{token:"punctuation.operator",regex:/[?:,;.]/,next:"start"},{token:"paren.lparen",regex:/[\[({]/,next:"start"},{token:"paren.rparen",regex:/[\])}]/},{token:"comment",regex:/^#!.*$/}],property:[{token:"text",regex:"\\s+"},{token:["storage.type","punctuation.operator","entity.name.function","text","keyword.operator","text","storage.type","text","entity.name.function","text","paren.lparen"],regex:"("+o+")(\\.)("+o+")(\\s*)(=)(\\s*)(function)(?:(\\s+)(\\w+))?(\\s*)(\\()",next:"function_arguments"},{token:"punctuation.operator",regex:/[.](?![.])/},{token:"support.function",regex:/(s(?:h(?:ift|ow(?:Mod(?:elessDialog|alDialog)|Help))|croll(?:X|By(?:Pages|Lines)?|Y|To)?|t(?:op|rike)|i(?:n|zeToContent|debar|gnText)|ort|u(?:p|b(?:str(?:ing)?)?)|pli(?:ce|t)|e(?:nd|t(?:Re(?:sizable|questHeader)|M(?:i(?:nutes|lliseconds)|onth)|Seconds|Ho(?:tKeys|urs)|Year|Cursor|Time(?:out)?|Interval|ZOptions|Date|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Date|FullYear)|FullYear|Active)|arch)|qrt|lice|avePreferences|mall)|h(?:ome|andleEvent)|navigate|c(?:har(?:CodeAt|At)|o(?:s|n(?:cat|textual|firm)|mpile)|eil|lear(?:Timeout|Interval)?|a(?:ptureEvents|ll)|reate(?:StyleSheet|Popup|EventObject))|t(?:o(?:GMTString|S(?:tring|ource)|U(?:TCString|pperCase)|Lo(?:caleString|werCase))|est|a(?:n|int(?:Enabled)?))|i(?:s(?:NaN|Finite)|ndexOf|talics)|d(?:isableExternalCapture|ump|etachEvent)|u(?:n(?:shift|taint|escape|watch)|pdateCommands)|j(?:oin|avaEnabled)|p(?:o(?:p|w)|ush|lugins.refresh|a(?:ddings|rse(?:Int|Float)?)|r(?:int|ompt|eference))|e(?:scape|nableExternalCapture|val|lementFromPoint|x(?:p|ec(?:Script|Command)?))|valueOf|UTC|queryCommand(?:State|Indeterm|Enabled|Value)|f(?:i(?:nd|le(?:ModifiedDate|Size|CreatedDate|UpdatedDate)|xed)|o(?:nt(?:size|color)|rward)|loor|romCharCode)|watch|l(?:ink|o(?:ad|g)|astIndexOf)|a(?:sin|nchor|cos|t(?:tachEvent|ob|an(?:2)?)|pply|lert|b(?:s|ort))|r(?:ou(?:nd|teEvents)|e(?:size(?:By|To)|calc|turnValue|place|verse|l(?:oad|ease(?:Capture|Events)))|andom)|g(?:o|et(?:ResponseHeader|M(?:i(?:nutes|lliseconds)|onth)|Se(?:conds|lection)|Hours|Year|Time(?:zoneOffset)?|Da(?:y|te)|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Da(?:y|te)|FullYear)|FullYear|A(?:ttention|llResponseHeaders)))|m(?:in|ove(?:B(?:y|elow)|To(?:Absolute)?|Above)|ergeAttributes|a(?:tch|rgins|x))|b(?:toa|ig|o(?:ld|rderWidths)|link|ack))\b(?=\()/},{token:"support.function.dom",regex:/(s(?:ub(?:stringData|mit)|plitText|e(?:t(?:NamedItem|Attribute(?:Node)?)|lect))|has(?:ChildNodes|Feature)|namedItem|c(?:l(?:ick|o(?:se|neNode))|reate(?:C(?:omment|DATASection|aption)|T(?:Head|extNode|Foot)|DocumentFragment|ProcessingInstruction|E(?:ntityReference|lement)|Attribute))|tabIndex|i(?:nsert(?:Row|Before|Cell|Data)|tem)|open|delete(?:Row|C(?:ell|aption)|T(?:Head|Foot)|Data)|focus|write(?:ln)?|a(?:dd|ppend(?:Child|Data))|re(?:set|place(?:Child|Data)|move(?:NamedItem|Child|Attribute(?:Node)?)?)|get(?:NamedItem|Element(?:sBy(?:Name|TagName|ClassName)|ById)|Attribute(?:Node)?)|blur)\b(?=\()/},{token:"support.constant",regex:/(s(?:ystemLanguage|cr(?:ipts|ollbars|een(?:X|Y|Top|Left))|t(?:yle(?:Sheets)?|atus(?:Text|bar)?)|ibling(?:Below|Above)|ource|uffixes|e(?:curity(?:Policy)?|l(?:ection|f)))|h(?:istory|ost(?:name)?|as(?:h|Focus))|y|X(?:MLDocument|SLDocument)|n(?:ext|ame(?:space(?:s|URI)|Prop))|M(?:IN_VALUE|AX_VALUE)|c(?:haracterSet|o(?:n(?:structor|trollers)|okieEnabled|lorDepth|mp(?:onents|lete))|urrent|puClass|l(?:i(?:p(?:boardData)?|entInformation)|osed|asses)|alle(?:e|r)|rypto)|t(?:o(?:olbar|p)|ext(?:Transform|Indent|Decoration|Align)|ags)|SQRT(?:1_2|2)|i(?:n(?:ner(?:Height|Width)|put)|ds|gnoreCase)|zIndex|o(?:scpu|n(?:readystatechange|Line)|uter(?:Height|Width)|p(?:sProfile|ener)|ffscreenBuffering)|NEGATIVE_INFINITY|d(?:i(?:splay|alog(?:Height|Top|Width|Left|Arguments)|rectories)|e(?:scription|fault(?:Status|Ch(?:ecked|arset)|View)))|u(?:ser(?:Profile|Language|Agent)|n(?:iqueID|defined)|pdateInterval)|_content|p(?:ixelDepth|ort|ersonalbar|kcs11|l(?:ugins|atform)|a(?:thname|dding(?:Right|Bottom|Top|Left)|rent(?:Window|Layer)?|ge(?:X(?:Offset)?|Y(?:Offset)?))|r(?:o(?:to(?:col|type)|duct(?:Sub)?|mpter)|e(?:vious|fix)))|e(?:n(?:coding|abledPlugin)|x(?:ternal|pando)|mbeds)|v(?:isibility|endor(?:Sub)?|Linkcolor)|URLUnencoded|P(?:I|OSITIVE_INFINITY)|f(?:ilename|o(?:nt(?:Size|Family|Weight)|rmName)|rame(?:s|Element)|gColor)|E|whiteSpace|l(?:i(?:stStyleType|n(?:eHeight|kColor))|o(?:ca(?:tion(?:bar)?|lName)|wsrc)|e(?:ngth|ft(?:Context)?)|a(?:st(?:M(?:odified|atch)|Index|Paren)|yer(?:s|X)|nguage))|a(?:pp(?:MinorVersion|Name|Co(?:deName|re)|Version)|vail(?:Height|Top|Width|Left)|ll|r(?:ity|guments)|Linkcolor|bove)|r(?:ight(?:Context)?|e(?:sponse(?:XML|Text)|adyState))|global|x|m(?:imeTypes|ultiline|enubar|argin(?:Right|Bottom|Top|Left))|L(?:N(?:10|2)|OG(?:10E|2E))|b(?:o(?:ttom|rder(?:Width|RightWidth|BottomWidth|Style|Color|TopWidth|LeftWidth))|ufferDepth|elow|ackground(?:Color|Image)))\b/},{token:"identifier",regex:o},{regex:"",token:"empty",next:"no_regex"}],start:[i.getStartRule("doc-start"),f("start"),{token:"string.regexp",regex:"\\/",next:"regex"},{token:"text",regex:"\\s+|^$",next:"start"},{token:"empty",regex:"",next:"no_regex"}],regex:[{token:"regexp.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"string.regexp",regex:"/[sxngimy]*",next:"no_regex"},{token:"invalid",regex:/\{\d+\b,?\d*\}[+*]|[+*$^?][+*]|[$^][?]|\?{3,}/},{token:"constant.language.escape",regex:/\(\?[:=!]|\)|\{\d+\b,?\d*\}|[+*]\?|[()$^+*?.]/},{token:"constant.language.delimiter",regex:/\|/},{token:"constant.language.escape",regex:/\[\^?/,next:"regex_character_class"},{token:"empty",regex:"$",next:"no_regex"},{defaultToken:"string.regexp"}],regex_character_class:[{token:"regexp.charclass.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"constant.language.escape",regex:"]",next:"regex"},{token:"constant.language.escape",regex:"-"},{token:"empty",regex:"$",next:"no_regex"},{defaultToken:"string.regexp.charachterclass"}],function_arguments:[{token:"variable.parameter",regex:o},{token:"punctuation.operator",regex:"[, ]+"},{token:"punctuation.operator",regex:"$"},{token:"empty",regex:"",next:"no_regex"}],qqstring:[{token:"constant.language.escape",regex:r},{token:"string",regex:"\\\\$",consumeLineEnd:!0},{token:"string",regex:'"|$',next:"no_regex"},{defaultToken:"string"}],qstring:[{token:"constant.language.escape",regex:r},{token:"string",regex:"\\\\$",consumeLineEnd:!0},{token:"string",regex:"'|$",next:"no_regex"},{defaultToken:"string"}]};if(!e||!e.noES6)this.$rules.no_regex.unshift({regex:"[{}]",onMatch:function(e,t,n){this.next=e=="{"?this.nextState:"";if(e=="{"&&n.length)n.unshift("start",t);else if(e=="}"&&n.length){n.shift(),this.next=n.shift();if(this.next.indexOf("string")!=-1||this.next.indexOf("jsx")!=-1)return"paren.quasi.end"}return e=="{"?"paren.lparen":"paren.rparen"},nextState:"start"},{token:"string.quasi.start",regex:/`/,push:[{token:"constant.language.escape",regex:r},{token:"paren.quasi.start",regex:/\${/,push:"start"},{token:"string.quasi.end",regex:/`/,next:"pop"},{defaultToken:"string.quasi"}]}),(!e||e.jsx!=0)&&a.call(this);this.embedRules(i,"doc-",[i.getEndRule("no_regex")]),this.normalizeRules()};r.inherits(u,s),t.JavaScriptHighlightRules=u}),define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],function(e,t,n){"use strict";var r=e("../range").Range,i=function(){};(function(){this.checkOutdent=function(e,t){return/^\s+$/.test(e)?/^\s*\}/.test(t):!1},this.autoOutdent=function(e,t){var n=e.getLine(t),i=n.match(/^(\s*\})/);if(!i)return 0;var s=i[1].length,o=e.findMatchingBracket({row:t,column:s});if(!o||o.row==t)return 0;var u=this.$getIndent(e.getLine(o.row));e.replace(new r(t,0,t,s-1),u)},this.$getIndent=function(e){return e.match(/^\s*/)[0]}}).call(i.prototype),t.MatchingBraceOutdent=i}),define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../../range").Range,s=e("./fold_mode").FoldMode,o=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end)))};r.inherits(o,s),function(){this.foldingStartMarker=/([\{\[\(])[^\}\]\)]*$|^\s*(\/\*)/,this.foldingStopMarker=/^[^\[\{\(]*([\}\]\)])|^[\s\*]*(\*\/)/,this.singleLineBlockCommentRe=/^\s*(\/\*).*\*\/\s*$/,this.tripleStarBlockCommentRe=/^\s*(\/\*\*\*).*\*\/\s*$/,this.startRegionRe=/^\s*(\/\*|\/\/)#?region\b/,this._getFoldWidgetBase=this.getFoldWidget,this.getFoldWidget=function(e,t,n){var r=e.getLine(n);if(this.singleLineBlockCommentRe.test(r)&&!this.startRegionRe.test(r)&&!this.tripleStarBlockCommentRe.test(r))return"";var i=this._getFoldWidgetBase(e,t,n);return!i&&this.startRegionRe.test(r)?"start":i},this.getFoldWidgetRange=function(e,t,n,r){var i=e.getLine(n);if(this.startRegionRe.test(i))return this.getCommentRegionBlock(e,i,n);var s=i.match(this.foldingStartMarker);if(s){var o=s.index;if(s[1])return this.openingBracketBlock(e,s[1],n,o);var u=e.getCommentFoldRange(n,o+s[0].length,1);return u&&!u.isMultiLine()&&(r?u=this.getSectionRange(e,n):t!="all"&&(u=null)),u}if(t==="markbegin")return;var s=i.match(this.foldingStopMarker);if(s){var o=s.index+s[0].length;return s[1]?this.closingBracketBlock(e,s[1],n,o):e.getCommentFoldRange(n,o,-1)}},this.getSectionRange=function(e,t){var n=e.getLine(t),r=n.search(/\S/),s=t,o=n.length;t+=1;var u=t,a=e.getLength();while(++tf)break;var l=this.getFoldWidgetRange(e,"all",t);if(l){if(l.start.row<=s)break;if(l.isMultiLine())t=l.end.row;else if(r==f)break}u=t}return new i(s,o,u,e.getLine(u).length)},this.getCommentRegionBlock=function(e,t,n){var r=t.search(/\s*$/),s=e.getLength(),o=n,u=/^\s*(?:\/\*|\/\/|--)#?(end)?region\b/,a=1;while(++no)return new i(o,r,l,t.length)}}.call(o.prototype)}),define("ace/mode/javascript",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/javascript_highlight_rules","ace/mode/matching_brace_outdent","ace/worker/worker_client","ace/mode/behaviour/cstyle","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./javascript_highlight_rules").JavaScriptHighlightRules,o=e("./matching_brace_outdent").MatchingBraceOutdent,u=e("../worker/worker_client").WorkerClient,a=e("./behaviour/cstyle").CstyleBehaviour,f=e("./folding/cstyle").FoldMode,l=function(){this.HighlightRules=s,this.$outdent=new o,this.$behaviour=new a,this.foldingRules=new f};r.inherits(l,i),function(){this.lineCommentStart="//",this.blockComment={start:"/*",end:"*/"},this.$quotes={'"':'"',"'":"'","`":"`"},this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),i=this.getTokenizer().getLineTokens(t,e),s=i.tokens,o=i.state;if(s.length&&s[s.length-1].type=="comment")return r;if(e=="start"||e=="no_regex"){var u=t.match(/^.*(?:\bcase\b.*:|[\{\(\[])\s*$/);u&&(r+=n)}else if(e=="doc-start"){if(o=="start"||o=="no_regex")return"";var u=t.match(/^\s*(\/?)\*/);u&&(u[1]&&(r+=" "),r+="* ")}return r},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.createWorker=function(e){var t=new u(["ace"],"ace/mode/javascript_worker","JavaScriptWorker");return t.attachToDocument(e.getDocument()),t.on("annotate",function(t){e.setAnnotations(t.data)}),t.on("terminate",function(){e.clearAnnotations()}),t},this.$id="ace/mode/javascript"}.call(l.prototype),t.Mode=l}),define("ace/mode/css_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./text_highlight_rules").TextHighlightRules,o=t.supportType="align-content|align-items|align-self|all|animation|animation-delay|animation-direction|animation-duration|animation-fill-mode|animation-iteration-count|animation-name|animation-play-state|animation-timing-function|backface-visibility|background|background-attachment|background-blend-mode|background-clip|background-color|background-image|background-origin|background-position|background-repeat|background-size|border|border-bottom|border-bottom-color|border-bottom-left-radius|border-bottom-right-radius|border-bottom-style|border-bottom-width|border-collapse|border-color|border-image|border-image-outset|border-image-repeat|border-image-slice|border-image-source|border-image-width|border-left|border-left-color|border-left-style|border-left-width|border-radius|border-right|border-right-color|border-right-style|border-right-width|border-spacing|border-style|border-top|border-top-color|border-top-left-radius|border-top-right-radius|border-top-style|border-top-width|border-width|bottom|box-shadow|box-sizing|caption-side|clear|clip|color|column-count|column-fill|column-gap|column-rule|column-rule-color|column-rule-style|column-rule-width|column-span|column-width|columns|content|counter-increment|counter-reset|cursor|direction|display|empty-cells|filter|flex|flex-basis|flex-direction|flex-flow|flex-grow|flex-shrink|flex-wrap|float|font|font-family|font-size|font-size-adjust|font-stretch|font-style|font-variant|font-weight|hanging-punctuation|height|justify-content|left|letter-spacing|line-height|list-style|list-style-image|list-style-position|list-style-type|margin|margin-bottom|margin-left|margin-right|margin-top|max-height|max-width|max-zoom|min-height|min-width|min-zoom|nav-down|nav-index|nav-left|nav-right|nav-up|opacity|order|outline|outline-color|outline-offset|outline-style|outline-width|overflow|overflow-x|overflow-y|padding|padding-bottom|padding-left|padding-right|padding-top|page-break-after|page-break-before|page-break-inside|perspective|perspective-origin|position|quotes|resize|right|tab-size|table-layout|text-align|text-align-last|text-decoration|text-decoration-color|text-decoration-line|text-decoration-style|text-indent|text-justify|text-overflow|text-shadow|text-transform|top|transform|transform-origin|transform-style|transition|transition-delay|transition-duration|transition-property|transition-timing-function|unicode-bidi|user-select|user-zoom|vertical-align|visibility|white-space|width|word-break|word-spacing|word-wrap|z-index",u=t.supportFunction="rgb|rgba|url|attr|counter|counters",a=t.supportConstant="absolute|after-edge|after|all-scroll|all|alphabetic|always|antialiased|armenian|auto|avoid-column|avoid-page|avoid|balance|baseline|before-edge|before|below|bidi-override|block-line-height|block|bold|bolder|border-box|both|bottom|box|break-all|break-word|capitalize|caps-height|caption|center|central|char|circle|cjk-ideographic|clone|close-quote|col-resize|collapse|column|consider-shifts|contain|content-box|cover|crosshair|cubic-bezier|dashed|decimal-leading-zero|decimal|default|disabled|disc|disregard-shifts|distribute-all-lines|distribute-letter|distribute-space|distribute|dotted|double|e-resize|ease-in|ease-in-out|ease-out|ease|ellipsis|end|exclude-ruby|fill|fixed|georgian|glyphs|grid-height|groove|hand|hanging|hebrew|help|hidden|hiragana-iroha|hiragana|horizontal|icon|ideograph-alpha|ideograph-numeric|ideograph-parenthesis|ideograph-space|ideographic|inactive|include-ruby|inherit|initial|inline-block|inline-box|inline-line-height|inline-table|inline|inset|inside|inter-ideograph|inter-word|invert|italic|justify|katakana-iroha|katakana|keep-all|last|left|lighter|line-edge|line-through|line|linear|list-item|local|loose|lower-alpha|lower-greek|lower-latin|lower-roman|lowercase|lr-tb|ltr|mathematical|max-height|max-size|medium|menu|message-box|middle|move|n-resize|ne-resize|newspaper|no-change|no-close-quote|no-drop|no-open-quote|no-repeat|none|normal|not-allowed|nowrap|nw-resize|oblique|open-quote|outset|outside|overline|padding-box|page|pointer|pre-line|pre-wrap|pre|preserve-3d|progress|relative|repeat-x|repeat-y|repeat|replaced|reset-size|ridge|right|round|row-resize|rtl|s-resize|scroll|se-resize|separate|slice|small-caps|small-caption|solid|space|square|start|static|status-bar|step-end|step-start|steps|stretch|strict|sub|super|sw-resize|table-caption|table-cell|table-column-group|table-column|table-footer-group|table-header-group|table-row-group|table-row|table|tb-rl|text-after-edge|text-before-edge|text-bottom|text-size|text-top|text|thick|thin|transparent|underline|upper-alpha|upper-latin|upper-roman|uppercase|use-script|vertical-ideographic|vertical-text|visible|w-resize|wait|whitespace|z-index|zero|zoom",f=t.supportConstantColor="aliceblue|antiquewhite|aqua|aquamarine|azure|beige|bisque|black|blanchedalmond|blue|blueviolet|brown|burlywood|cadetblue|chartreuse|chocolate|coral|cornflowerblue|cornsilk|crimson|cyan|darkblue|darkcyan|darkgoldenrod|darkgray|darkgreen|darkgrey|darkkhaki|darkmagenta|darkolivegreen|darkorange|darkorchid|darkred|darksalmon|darkseagreen|darkslateblue|darkslategray|darkslategrey|darkturquoise|darkviolet|deeppink|deepskyblue|dimgray|dimgrey|dodgerblue|firebrick|floralwhite|forestgreen|fuchsia|gainsboro|ghostwhite|gold|goldenrod|gray|green|greenyellow|grey|honeydew|hotpink|indianred|indigo|ivory|khaki|lavender|lavenderblush|lawngreen|lemonchiffon|lightblue|lightcoral|lightcyan|lightgoldenrodyellow|lightgray|lightgreen|lightgrey|lightpink|lightsalmon|lightseagreen|lightskyblue|lightslategray|lightslategrey|lightsteelblue|lightyellow|lime|limegreen|linen|magenta|maroon|mediumaquamarine|mediumblue|mediumorchid|mediumpurple|mediumseagreen|mediumslateblue|mediumspringgreen|mediumturquoise|mediumvioletred|midnightblue|mintcream|mistyrose|moccasin|navajowhite|navy|oldlace|olive|olivedrab|orange|orangered|orchid|palegoldenrod|palegreen|paleturquoise|palevioletred|papayawhip|peachpuff|peru|pink|plum|powderblue|purple|rebeccapurple|red|rosybrown|royalblue|saddlebrown|salmon|sandybrown|seagreen|seashell|sienna|silver|skyblue|slateblue|slategray|slategrey|snow|springgreen|steelblue|tan|teal|thistle|tomato|turquoise|violet|wheat|white|whitesmoke|yellow|yellowgreen",l=t.supportConstantFonts="arial|century|comic|courier|cursive|fantasy|garamond|georgia|helvetica|impact|lucida|symbol|system|tahoma|times|trebuchet|utopia|verdana|webdings|sans-serif|serif|monospace",c=t.numRe="\\-?(?:(?:[0-9]+(?:\\.[0-9]+)?)|(?:\\.[0-9]+))",h=t.pseudoElements="(\\:+)\\b(after|before|first-letter|first-line|moz-selection|selection)\\b",p=t.pseudoClasses="(:)\\b(active|checked|disabled|empty|enabled|first-child|first-of-type|focus|hover|indeterminate|invalid|last-child|last-of-type|link|not|nth-child|nth-last-child|nth-last-of-type|nth-of-type|only-child|only-of-type|required|root|target|valid|visited)\\b",d=function(){var e=this.createKeywordMapper({"support.function":u,"support.constant":a,"support.type":o,"support.constant.color":f,"support.constant.fonts":l},"text",!0);this.$rules={start:[{include:["strings","url","comments"]},{token:"paren.lparen",regex:"\\{",next:"ruleset"},{token:"paren.rparen",regex:"\\}"},{token:"string",regex:"@(?!viewport)",next:"media"},{token:"keyword",regex:"#[a-z0-9-_]+"},{token:"keyword",regex:"%"},{token:"variable",regex:"\\.[a-z0-9-_]+"},{token:"string",regex:":[a-z0-9-_]+"},{token:"constant.numeric",regex:c},{token:"constant",regex:"[a-z0-9-_]+"},{caseInsensitive:!0}],media:[{include:["strings","url","comments"]},{token:"paren.lparen",regex:"\\{",next:"start"},{token:"paren.rparen",regex:"\\}",next:"start"},{token:"string",regex:";",next:"start"},{token:"keyword",regex:"(?:media|supports|document|charset|import|namespace|media|supports|document|page|font|keyframes|viewport|counter-style|font-feature-values|swash|ornaments|annotation|stylistic|styleset|character-variant)"}],comments:[{token:"comment",regex:"\\/\\*",push:[{token:"comment",regex:"\\*\\/",next:"pop"},{defaultToken:"comment"}]}],ruleset:[{regex:"-(webkit|ms|moz|o)-",token:"text"},{token:"punctuation.operator",regex:"[:;]"},{token:"paren.rparen",regex:"\\}",next:"start"},{include:["strings","url","comments"]},{token:["constant.numeric","keyword"],regex:"("+c+")(ch|cm|deg|em|ex|fr|gd|grad|Hz|in|kHz|mm|ms|pc|pt|px|rad|rem|s|turn|vh|vmax|vmin|vm|vw|%)"},{token:"constant.numeric",regex:c},{token:"constant.numeric",regex:"#[a-f0-9]{6}"},{token:"constant.numeric",regex:"#[a-f0-9]{3}"},{token:["punctuation","entity.other.attribute-name.pseudo-element.css"],regex:h},{token:["punctuation","entity.other.attribute-name.pseudo-class.css"],regex:p},{include:"url"},{token:e,regex:"\\-?[a-zA-Z_][a-zA-Z0-9_\\-]*"},{caseInsensitive:!0}],url:[{token:"support.function",regex:"(?:url(:?-prefix)?|domain|regexp)\\(",push:[{token:"support.function",regex:"\\)",next:"pop"},{defaultToken:"string"}]}],strings:[{token:"string.start",regex:"'",push:[{token:"string.end",regex:"'|$",next:"pop"},{include:"escapes"},{token:"constant.language.escape",regex:/\\$/,consumeLineEnd:!0},{defaultToken:"string"}]},{token:"string.start",regex:'"',push:[{token:"string.end",regex:'"|$',next:"pop"},{include:"escapes"},{token:"constant.language.escape",regex:/\\$/,consumeLineEnd:!0},{defaultToken:"string"}]}],escapes:[{token:"constant.language.escape",regex:/\\([a-fA-F\d]{1,6}|[^a-fA-F\d])/}]},this.normalizeRules()};r.inherits(d,s),t.CssHighlightRules=d}),define("ace/mode/css_completions",["require","exports","module"],function(e,t,n){"use strict";var r={background:{"#$0":1},"background-color":{"#$0":1,transparent:1,fixed:1},"background-image":{"url('/$0')":1},"background-repeat":{repeat:1,"repeat-x":1,"repeat-y":1,"no-repeat":1,inherit:1},"background-position":{bottom:2,center:2,left:2,right:2,top:2,inherit:2},"background-attachment":{scroll:1,fixed:1},"background-size":{cover:1,contain:1},"background-clip":{"border-box":1,"padding-box":1,"content-box":1},"background-origin":{"border-box":1,"padding-box":1,"content-box":1},border:{"solid $0":1,"dashed $0":1,"dotted $0":1,"#$0":1},"border-color":{"#$0":1},"border-style":{solid:2,dashed:2,dotted:2,"double":2,groove:2,hidden:2,inherit:2,inset:2,none:2,outset:2,ridged:2},"border-collapse":{collapse:1,separate:1},bottom:{px:1,em:1,"%":1},clear:{left:1,right:1,both:1,none:1},color:{"#$0":1,"rgb(#$00,0,0)":1},cursor:{"default":1,pointer:1,move:1,text:1,wait:1,help:1,progress:1,"n-resize":1,"ne-resize":1,"e-resize":1,"se-resize":1,"s-resize":1,"sw-resize":1,"w-resize":1,"nw-resize":1},display:{none:1,block:1,inline:1,"inline-block":1,"table-cell":1},"empty-cells":{show:1,hide:1},"float":{left:1,right:1,none:1},"font-family":{Arial:2,"Comic Sans MS":2,Consolas:2,"Courier New":2,Courier:2,Georgia:2,Monospace:2,"Sans-Serif":2,"Segoe UI":2,Tahoma:2,"Times New Roman":2,"Trebuchet MS":2,Verdana:1},"font-size":{px:1,em:1,"%":1},"font-weight":{bold:1,normal:1},"font-style":{italic:1,normal:1},"font-variant":{normal:1,"small-caps":1},height:{px:1,em:1,"%":1},left:{px:1,em:1,"%":1},"letter-spacing":{normal:1},"line-height":{normal:1},"list-style-type":{none:1,disc:1,circle:1,square:1,decimal:1,"decimal-leading-zero":1,"lower-roman":1,"upper-roman":1,"lower-greek":1,"lower-latin":1,"upper-latin":1,georgian:1,"lower-alpha":1,"upper-alpha":1},margin:{px:1,em:1,"%":1},"margin-right":{px:1,em:1,"%":1},"margin-left":{px:1,em:1,"%":1},"margin-top":{px:1,em:1,"%":1},"margin-bottom":{px:1,em:1,"%":1},"max-height":{px:1,em:1,"%":1},"max-width":{px:1,em:1,"%":1},"min-height":{px:1,em:1,"%":1},"min-width":{px:1,em:1,"%":1},overflow:{hidden:1,visible:1,auto:1,scroll:1},"overflow-x":{hidden:1,visible:1,auto:1,scroll:1},"overflow-y":{hidden:1,visible:1,auto:1,scroll:1},padding:{px:1,em:1,"%":1},"padding-top":{px:1,em:1,"%":1},"padding-right":{px:1,em:1,"%":1},"padding-bottom":{px:1,em:1,"%":1},"padding-left":{px:1,em:1,"%":1},"page-break-after":{auto:1,always:1,avoid:1,left:1,right:1},"page-break-before":{auto:1,always:1,avoid:1,left:1,right:1},position:{absolute:1,relative:1,fixed:1,"static":1},right:{px:1,em:1,"%":1},"table-layout":{fixed:1,auto:1},"text-decoration":{none:1,underline:1,"line-through":1,blink:1},"text-align":{left:1,right:1,center:1,justify:1},"text-transform":{capitalize:1,uppercase:1,lowercase:1,none:1},top:{px:1,em:1,"%":1},"vertical-align":{top:1,bottom:1},visibility:{hidden:1,visible:1},"white-space":{nowrap:1,normal:1,pre:1,"pre-line":1,"pre-wrap":1},width:{px:1,em:1,"%":1},"word-spacing":{normal:1},filter:{"alpha(opacity=$0100)":1},"text-shadow":{"$02px 2px 2px #777":1},"text-overflow":{"ellipsis-word":1,clip:1,ellipsis:1},"-moz-border-radius":1,"-moz-border-radius-topright":1,"-moz-border-radius-bottomright":1,"-moz-border-radius-topleft":1,"-moz-border-radius-bottomleft":1,"-webkit-border-radius":1,"-webkit-border-top-right-radius":1,"-webkit-border-top-left-radius":1,"-webkit-border-bottom-right-radius":1,"-webkit-border-bottom-left-radius":1,"-moz-box-shadow":1,"-webkit-box-shadow":1,transform:{"rotate($00deg)":1,"skew($00deg)":1},"-moz-transform":{"rotate($00deg)":1,"skew($00deg)":1},"-webkit-transform":{"rotate($00deg)":1,"skew($00deg)":1}},i=function(){};(function(){this.completionsDefined=!1,this.defineCompletions=function(){if(document){var e=document.createElement("c").style;for(var t in e){if(typeof e[t]!="string")continue;var n=t.replace(/[A-Z]/g,function(e){return"-"+e.toLowerCase()});r.hasOwnProperty(n)||(r[n]=1)}}this.completionsDefined=!0},this.getCompletions=function(e,t,n,r){this.completionsDefined||this.defineCompletions();if(e==="ruleset"||t.$mode.$id=="ace/mode/scss"){var i=t.getLine(n.row).substr(0,n.column);return/:[^;]+$/.test(i)?(/([\w\-]+):[^:]*$/.test(i),this.getPropertyValueCompletions(e,t,n,r)):this.getPropertyCompletions(e,t,n,r)}return[]},this.getPropertyCompletions=function(e,t,n,i){var s=Object.keys(r);return s.map(function(e){return{caption:e,snippet:e+": $0;",meta:"property",score:1e6}})},this.getPropertyValueCompletions=function(e,t,n,i){var s=t.getLine(n.row).substr(0,n.column),o=(/([\w\-]+):[^:]*$/.exec(s)||{})[1];if(!o)return[];var u=[];return o in r&&typeof r[o]=="object"&&(u=Object.keys(r[o])),u.map(function(e){return{caption:e,snippet:e,meta:"property value",score:1e6}})}}).call(i.prototype),t.CssCompletions=i}),define("ace/mode/behaviour/css",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/mode/behaviour/cstyle","ace/token_iterator"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("./cstyle").CstyleBehaviour,o=e("../../token_iterator").TokenIterator,u=function(){this.inherit(s),this.add("colon","insertion",function(e,t,n,r,i){if(i===":"&&n.selection.isEmpty()){var s=n.getCursorPosition(),u=new o(r,s.row,s.column),a=u.getCurrentToken();a&&a.value.match(/\s+/)&&(a=u.stepBackward());if(a&&a.type==="support.type"){var f=r.doc.getLine(s.row),l=f.substring(s.column,s.column+1);if(l===":")return{text:"",selection:[1,1]};if(/^(\s+[^;]|\s*$)/.test(f.substring(s.column)))return{text:":;",selection:[1,1]}}}}),this.add("colon","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s===":"){var u=n.getCursorPosition(),a=new o(r,u.row,u.column),f=a.getCurrentToken();f&&f.value.match(/\s+/)&&(f=a.stepBackward());if(f&&f.type==="support.type"){var l=r.doc.getLine(i.start.row),c=l.substring(i.end.column,i.end.column+1);if(c===";")return i.end.column++,i}}}),this.add("semicolon","insertion",function(e,t,n,r,i){if(i===";"&&n.selection.isEmpty()){var s=n.getCursorPosition(),o=r.doc.getLine(s.row),u=o.substring(s.column,s.column+1);if(u===";")return{text:"",selection:[1,1]}}}),this.add("!important","insertion",function(e,t,n,r,i){if(i==="!"&&n.selection.isEmpty()){var s=n.getCursorPosition(),o=r.doc.getLine(s.row);if(/^\s*(;|}|$)/.test(o.substring(s.column)))return{text:"!important",selection:[10,10]}}})};r.inherits(u,s),t.CssBehaviour=u}),define("ace/mode/css",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/css_highlight_rules","ace/mode/matching_brace_outdent","ace/worker/worker_client","ace/mode/css_completions","ace/mode/behaviour/css","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./css_highlight_rules").CssHighlightRules,o=e("./matching_brace_outdent").MatchingBraceOutdent,u=e("../worker/worker_client").WorkerClient,a=e("./css_completions").CssCompletions,f=e("./behaviour/css").CssBehaviour,l=e("./folding/cstyle").FoldMode,c=function(){this.HighlightRules=s,this.$outdent=new o,this.$behaviour=new f,this.$completer=new a,this.foldingRules=new l};r.inherits(c,i),function(){this.foldingRules="cStyle",this.blockComment={start:"/*",end:"*/"},this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),i=this.getTokenizer().getLineTokens(t,e).tokens;if(i.length&&i[i.length-1].type=="comment")return r;var s=t.match(/^.*\{\s*$/);return s&&(r+=n),r},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.getCompletions=function(e,t,n,r){return this.$completer.getCompletions(e,t,n,r)},this.createWorker=function(e){var t=new u(["ace"],"ace/mode/css_worker","Worker");return t.attachToDocument(e.getDocument()),t.on("annotate",function(t){e.setAnnotations(t.data)}),t.on("terminate",function(){e.clearAnnotations()}),t},this.$id="ace/mode/css"}.call(c.prototype),t.Mode=c}),define("ace/mode/xml_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(e){var t="[_:a-zA-Z\u00c0-\uffff][-_:.a-zA-Z0-9\u00c0-\uffff]*";this.$rules={start:[{token:"string.cdata.xml",regex:"<\\!\\[CDATA\\[",next:"cdata"},{token:["punctuation.instruction.xml","keyword.instruction.xml"],regex:"(<\\?)("+t+")",next:"processing_instruction"},{token:"comment.start.xml",regex:"<\\!--",next:"comment"},{token:["xml-pe.doctype.xml","xml-pe.doctype.xml"],regex:"(<\\!)(DOCTYPE)(?=[\\s])",next:"doctype",caseInsensitive:!0},{include:"tag"},{token:"text.end-tag-open.xml",regex:"",next:"start"}],doctype:[{include:"whitespace"},{include:"string"},{token:"xml-pe.doctype.xml",regex:">",next:"start"},{token:"xml-pe.xml",regex:"[-_a-zA-Z0-9:]+"},{token:"punctuation.int-subset",regex:"\\[",push:"int_subset"}],int_subset:[{token:"text.xml",regex:"\\s+"},{token:"punctuation.int-subset.xml",regex:"]",next:"pop"},{token:["punctuation.markup-decl.xml","keyword.markup-decl.xml"],regex:"(<\\!)("+t+")",push:[{token:"text",regex:"\\s+"},{token:"punctuation.markup-decl.xml",regex:">",next:"pop"},{include:"string"}]}],cdata:[{token:"string.cdata.xml",regex:"\\]\\]>",next:"start"},{token:"text.xml",regex:"\\s+"},{token:"text.xml",regex:"(?:[^\\]]|\\](?!\\]>))+"}],comment:[{token:"comment.end.xml",regex:"-->",next:"start"},{defaultToken:"comment.xml"}],reference:[{token:"constant.language.escape.reference.xml",regex:"(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)"}],attr_reference:[{token:"constant.language.escape.reference.attribute-value.xml",regex:"(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)"}],tag:[{token:["meta.tag.punctuation.tag-open.xml","meta.tag.punctuation.end-tag-open.xml","meta.tag.tag-name.xml"],regex:"(?:(<)|(",next:"start"}]}],tag_whitespace:[{token:"text.tag-whitespace.xml",regex:"\\s+"}],whitespace:[{token:"text.whitespace.xml",regex:"\\s+"}],string:[{token:"string.xml",regex:"'",push:[{token:"string.xml",regex:"'",next:"pop"},{defaultToken:"string.xml"}]},{token:"string.xml",regex:'"',push:[{token:"string.xml",regex:'"',next:"pop"},{defaultToken:"string.xml"}]}],attributes:[{token:"entity.other.attribute-name.xml",regex:t},{token:"keyword.operator.attribute-equals.xml",regex:"="},{include:"tag_whitespace"},{include:"attribute_value"}],attribute_value:[{token:"string.attribute-value.xml",regex:"'",push:[{token:"string.attribute-value.xml",regex:"'",next:"pop"},{include:"attr_reference"},{defaultToken:"string.attribute-value.xml"}]},{token:"string.attribute-value.xml",regex:'"',push:[{token:"string.attribute-value.xml",regex:'"',next:"pop"},{include:"attr_reference"},{defaultToken:"string.attribute-value.xml"}]}]},this.constructor===s&&this.normalizeRules()};(function(){this.embedTagRules=function(e,t,n){this.$rules.tag.unshift({token:["meta.tag.punctuation.tag-open.xml","meta.tag."+n+".tag-name.xml"],regex:"(<)("+n+"(?=\\s|>|$))",next:[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:t+"start"}]}),this.$rules[n+"-end"]=[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:"start",onMatch:function(e,t,n){return n.splice(0),this.token}}],this.embedRules(e,t,[{token:["meta.tag.punctuation.end-tag-open.xml","meta.tag."+n+".tag-name.xml"],regex:"(|$))",next:n+"-end"},{token:"string.cdata.xml",regex:"<\\!\\[CDATA\\["},{token:"string.cdata.xml",regex:"\\]\\]>"}])}}).call(i.prototype),r.inherits(s,i),t.XmlHighlightRules=s}),define("ace/mode/html_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/css_highlight_rules","ace/mode/javascript_highlight_rules","ace/mode/xml_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./css_highlight_rules").CssHighlightRules,o=e("./javascript_highlight_rules").JavaScriptHighlightRules,u=e("./xml_highlight_rules").XmlHighlightRules,a=i.createMap({a:"anchor",button:"form",form:"form",img:"image",input:"form",label:"form",option:"form",script:"script",select:"form",textarea:"form",style:"style",table:"table",tbody:"table",td:"table",tfoot:"table",th:"table",tr:"table"}),f=function(){u.call(this),this.addRules({attributes:[{include:"tag_whitespace"},{token:"entity.other.attribute-name.xml",regex:"[-_a-zA-Z0-9:.]+"},{token:"keyword.operator.attribute-equals.xml",regex:"=",push:[{include:"tag_whitespace"},{token:"string.unquoted.attribute-value.html",regex:"[^<>='\"`\\s]+",next:"pop"},{token:"empty",regex:"",next:"pop"}]},{include:"attribute_value"}],tag:[{token:function(e,t){var n=a[t];return["meta.tag.punctuation."+(e=="<"?"":"end-")+"tag-open.xml","meta.tag"+(n?"."+n:"")+".tag-name.xml"]},regex:"(",next:"start"}]}),this.embedTagRules(s,"css-","style"),this.embedTagRules((new o({jsx:!1})).getRules(),"js-","script"),this.constructor===f&&this.normalizeRules()};r.inherits(f,u),t.HtmlHighlightRules=f}),define("ace/mode/behaviour/xml",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator","ace/lib/lang"],function(e,t,n){"use strict";function u(e,t){return e&&e.type.lastIndexOf(t+".xml")>-1}var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("../../token_iterator").TokenIterator,o=e("../../lib/lang"),a=function(){this.add("string_dquotes","insertion",function(e,t,n,r,i){if(i=='"'||i=="'"){var o=i,a=r.doc.getTextRange(n.getSelectionRange());if(a!==""&&a!=="'"&&a!='"'&&n.getWrapBehavioursEnabled())return{text:o+a+o,selection:!1};var f=n.getCursorPosition(),l=r.doc.getLine(f.row),c=l.substring(f.column,f.column+1),h=new s(r,f.row,f.column),p=h.getCurrentToken();if(c==o&&(u(p,"attribute-value")||u(p,"string")))return{text:"",selection:[1,1]};p||(p=h.stepBackward());if(!p)return;while(u(p,"tag-whitespace")||u(p,"whitespace"))p=h.stepBackward();var d=!c||c.match(/\s/);if(u(p,"attribute-equals")&&(d||c==">")||u(p,"decl-attribute-equals")&&(d||c=="?"))return{text:o+o,selection:[1,1]}}}),this.add("string_dquotes","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&(s=='"'||s=="'")){var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==s)return i.end.column++,i}}),this.add("autoclosing","insertion",function(e,t,n,r,i){if(i==">"){var o=n.getSelectionRange().start,a=new s(r,o.row,o.column),f=a.getCurrentToken()||a.stepBackward();if(!f||!(u(f,"tag-name")||u(f,"tag-whitespace")||u(f,"attribute-name")||u(f,"attribute-equals")||u(f,"attribute-value")))return;if(u(f,"reference.attribute-value"))return;if(u(f,"attribute-value")){var l=a.getCurrentTokenColumn()+f.value.length;if(o.column/.test(r.getLine(o.row).slice(o.column)))return;while(!u(f,"tag-name")){f=a.stepBackward();if(f.value=="<"){f=a.stepForward();break}}var h=a.getCurrentTokenRow(),p=a.getCurrentTokenColumn();if(u(a.stepBackward(),"end-tag-open"))return;var d=f.value;h==o.row&&(d=d.substring(0,o.column-p));if(this.voidElements.hasOwnProperty(d.toLowerCase()))return;return{text:">",selection:[1,1]}}}),this.add("autoindent","insertion",function(e,t,n,r,i){if(i=="\n"){var o=n.getCursorPosition(),u=r.getLine(o.row),a=new s(r,o.row,o.column),f=a.getCurrentToken();if(f&&f.type.indexOf("tag-close")!==-1){if(f.value=="/>")return;while(f&&f.type.indexOf("tag-name")===-1)f=a.stepBackward();if(!f)return;var l=f.value,c=a.getCurrentTokenRow();f=a.stepBackward();if(!f||f.type.indexOf("end-tag")!==-1)return;if(this.voidElements&&!this.voidElements[l]){var h=r.getTokenAt(o.row,o.column+1),u=r.getLine(c),p=this.$getIndent(u),d=p+r.getTabString();return h&&h.value==="-1}var r=e("../../lib/oop"),i=e("../../lib/lang"),s=e("../../range").Range,o=e("./fold_mode").FoldMode,u=e("../../token_iterator").TokenIterator,a=t.FoldMode=function(e,t){o.call(this),this.voidElements=e||{},this.optionalEndTags=r.mixin({},this.voidElements),t&&r.mixin(this.optionalEndTags,t)};r.inherits(a,o);var f=function(){this.tagName="",this.closing=!1,this.selfClosing=!1,this.start={row:0,column:0},this.end={row:0,column:0}};(function(){this.getFoldWidget=function(e,t,n){var r=this._getFirstTagInLine(e,n);return r?r.closing||!r.tagName&&r.selfClosing?t=="markbeginend"?"end":"":!r.tagName||r.selfClosing||this.voidElements.hasOwnProperty(r.tagName.toLowerCase())?"":this._findEndTagInLine(e,n,r.tagName,r.end.column)?"":"start":this.getCommentFoldWidget(e,n)},this.getCommentFoldWidget=function(e,t){return/comment/.test(e.getState(t))&&/";break}}return r}if(l(s,"tag-close"))return r.selfClosing=s.value=="/>",r;r.start.column+=s.value.length}return null},this._findEndTagInLine=function(e,t,n,r){var i=e.getTokens(t),s=0;for(var o=0;o",n.end.row=e.getCurrentTokenRow(),n.end.column=e.getCurrentTokenColumn()+t.value.length,e.stepForward(),n;while(t=e.stepForward());return null},this._readTagBackward=function(e){var t=e.getCurrentToken();if(!t)return null;var n=new f;do{if(l(t,"tag-open"))return n.closing=l(t,"end-tag-open"),n.start.row=e.getCurrentTokenRow(),n.start.column=e.getCurrentTokenColumn(),e.stepBackward(),n;l(t,"tag-name")?n.tagName=t.value:l(t,"tag-close")&&(n.selfClosing=t.value=="/>",n.end.row=e.getCurrentTokenRow(),n.end.column=e.getCurrentTokenColumn()+t.value.length)}while(t=e.stepBackward());return null},this._pop=function(e,t){while(e.length){var n=e[e.length-1];if(!t||n.tagName==t.tagName)return e.pop();if(this.optionalEndTags.hasOwnProperty(n.tagName)){e.pop();continue}return null}},this.getFoldWidgetRange=function(e,t,n){var r=this._getFirstTagInLine(e,n);if(!r)return this.getCommentFoldWidget(e,n)&&e.getCommentFoldRange(n,e.getLine(n).length);var i=r.closing||r.selfClosing,o=[],a;if(!i){var f=new u(e,n,r.start.column),l={row:n,column:r.start.column+r.tagName.length+2};r.start.row==r.end.row&&(l.column=r.end.column);while(a=this._readTagForward(f)){if(a.selfClosing){if(!o.length)return a.start.column+=a.tagName.length+2,a.end.column-=2,s.fromPoints(a.start,a.end);continue}if(a.closing){this._pop(o,a);if(o.length==0)return s.fromPoints(l,a.start)}else o.push(a)}}else{var f=new u(e,n,r.end.column),c={row:n,column:r.start.column};while(a=this._readTagBackward(f)){if(a.selfClosing){if(!o.length)return a.start.column+=a.tagName.length+2,a.end.column-=2,s.fromPoints(a.start,a.end);continue}if(!a.closing){this._pop(o,a);if(o.length==0)return a.start.column+=a.tagName.length+2,a.start.row==a.end.row&&a.start.column-1}function l(e,t){var n=new r(e,t.row,t.column),i=n.getCurrentToken();while(i&&!f(i,"tag-name"))i=n.stepBackward();if(i)return i.value}function c(e,t){var n=new r(e,t.row,t.column),i=n.getCurrentToken();while(i&&!f(i,"attribute-name"))i=n.stepBackward();if(i)return i.value}var r=e("../token_iterator").TokenIterator,i=["accesskey","class","contenteditable","contextmenu","dir","draggable","dropzone","hidden","id","inert","itemid","itemprop","itemref","itemscope","itemtype","lang","spellcheck","style","tabindex","title","translate"],s=["onabort","onblur","oncancel","oncanplay","oncanplaythrough","onchange","onclick","onclose","oncontextmenu","oncuechange","ondblclick","ondrag","ondragend","ondragenter","ondragleave","ondragover","ondragstart","ondrop","ondurationchange","onemptied","onended","onerror","onfocus","oninput","oninvalid","onkeydown","onkeypress","onkeyup","onload","onloadeddata","onloadedmetadata","onloadstart","onmousedown","onmousemove","onmouseout","onmouseover","onmouseup","onmousewheel","onpause","onplay","onplaying","onprogress","onratechange","onreset","onscroll","onseeked","onseeking","onselect","onshow","onstalled","onsubmit","onsuspend","ontimeupdate","onvolumechange","onwaiting"],o=i.concat(s),u={a:{href:1,target:{_blank:1,top:1},ping:1,rel:{nofollow:1,alternate:1,author:1,bookmark:1,help:1,license:1,next:1,noreferrer:1,prefetch:1,prev:1,search:1,tag:1},media:1,hreflang:1,type:1},abbr:{},address:{},area:{shape:1,coords:1,href:1,hreflang:1,alt:1,target:1,media:1,rel:1,ping:1,type:1},article:{pubdate:1},aside:{},audio:{src:1,autobuffer:1,autoplay:{autoplay:1},loop:{loop:1},controls:{controls:1},muted:{muted:1},preload:{auto:1,metadata:1,none:1}},b:{},base:{href:1,target:1},bdi:{},bdo:{},blockquote:{cite:1},body:{onafterprint:1,onbeforeprint:1,onbeforeunload:1,onhashchange:1,onmessage:1,onoffline:1,onpopstate:1,onredo:1,onresize:1,onstorage:1,onundo:1,onunload:1},br:{},button:{autofocus:1,disabled:{disabled:1},form:1,formaction:1,formenctype:1,formmethod:1,formnovalidate:1,formtarget:1,name:1,value:1,type:{button:1,submit:1}},canvas:{width:1,height:1},caption:{},cite:{},code:{},col:{span:1},colgroup:{span:1},command:{type:1,label:1,icon:1,disabled:1,checked:1,radiogroup:1,command:1},data:{},datalist:{},dd:{},del:{cite:1,datetime:1},details:{open:1},dfn:{},dialog:{open:1},div:{},dl:{},dt:{},em:{},embed:{src:1,height:1,width:1,type:1},fieldset:{disabled:1,form:1,name:1},figcaption:{},figure:{},footer:{},form:{"accept-charset":1,action:1,autocomplete:1,enctype:{"multipart/form-data":1,"application/x-www-form-urlencoded":1},method:{get:1,post:1},name:1,novalidate:1,target:{_blank:1,top:1}},h1:{},h2:{},h3:{},h4:{},h5:{},h6:{},head:{},header:{},hr:{},html:{manifest:1},i:{},iframe:{name:1,src:1,height:1,width:1,sandbox:{"allow-same-origin":1,"allow-top-navigation":1,"allow-forms":1,"allow-scripts":1},seamless:{seamless:1}},img:{alt:1,src:1,height:1,width:1,usemap:1,ismap:1},input:{type:{text:1,password:1,hidden:1,checkbox:1,submit:1,radio:1,file:1,button:1,reset:1,image:31,color:1,date:1,datetime:1,"datetime-local":1,email:1,month:1,number:1,range:1,search:1,tel:1,time:1,url:1,week:1},accept:1,alt:1,autocomplete:{on:1,off:1},autofocus:{autofocus:1},checked:{checked:1},disabled:{disabled:1},form:1,formaction:1,formenctype:{"application/x-www-form-urlencoded":1,"multipart/form-data":1,"text/plain":1},formmethod:{get:1,post:1},formnovalidate:{formnovalidate:1},formtarget:{_blank:1,_self:1,_parent:1,_top:1},height:1,list:1,max:1,maxlength:1,min:1,multiple:{multiple:1},name:1,pattern:1,placeholder:1,readonly:{readonly:1},required:{required:1},size:1,src:1,step:1,width:1,files:1,value:1},ins:{cite:1,datetime:1},kbd:{},keygen:{autofocus:1,challenge:{challenge:1},disabled:{disabled:1},form:1,keytype:{rsa:1,dsa:1,ec:1},name:1},label:{form:1,"for":1},legend:{},li:{value:1},link:{href:1,hreflang:1,rel:{stylesheet:1,icon:1},media:{all:1,screen:1,print:1},type:{"text/css":1,"image/png":1,"image/jpeg":1,"image/gif":1},sizes:1},main:{},map:{name:1},mark:{},math:{},menu:{type:1,label:1},meta:{"http-equiv":{"content-type":1},name:{description:1,keywords:1},content:{"text/html; charset=UTF-8":1},charset:1},meter:{value:1,min:1,max:1,low:1,high:1,optimum:1},nav:{},noscript:{href:1},object:{param:1,data:1,type:1,height:1,width:1,usemap:1,name:1,form:1,classid:1},ol:{start:1,reversed:1},optgroup:{disabled:1,label:1},option:{disabled:1,selected:1,label:1,value:1},output:{"for":1,form:1,name:1},p:{},param:{name:1,value:1},pre:{},progress:{value:1,max:1},q:{cite:1},rp:{},rt:{},ruby:{},s:{},samp:{},script:{charset:1,type:{"text/javascript":1},src:1,defer:1,async:1},select:{autofocus:1,disabled:1,form:1,multiple:{multiple:1},name:1,size:1,readonly:{readonly:1}},small:{},source:{src:1,type:1,media:1},span:{},strong:{},style:{type:1,media:{all:1,screen:1,print:1},scoped:1},sub:{},sup:{},svg:{},table:{summary:1},tbody:{},td:{headers:1,rowspan:1,colspan:1},textarea:{autofocus:{autofocus:1},disabled:{disabled:1},form:1,maxlength:1,name:1,placeholder:1,readonly:{readonly:1},required:{required:1},rows:1,cols:1,wrap:{on:1,off:1,hard:1,soft:1}},tfoot:{},th:{headers:1,rowspan:1,colspan:1,scope:1},thead:{},time:{datetime:1},title:{},tr:{},track:{kind:1,src:1,srclang:1,label:1,"default":1},section:{},summary:{},u:{},ul:{},"var":{},video:{src:1,autobuffer:1,autoplay:{autoplay:1},loop:{loop:1},controls:{controls:1},width:1,height:1,poster:1,muted:{muted:1},preload:{auto:1,metadata:1,none:1}},wbr:{}},a=Object.keys(u),h=function(){};(function(){this.getCompletions=function(e,t,n,r){var i=t.getTokenAt(n.row,n.column);if(!i)return[];if(f(i,"tag-name")||f(i,"tag-open")||f(i,"end-tag-open"))return this.getTagCompletions(e,t,n,r);if(f(i,"tag-whitespace")||f(i,"attribute-name"))return this.getAttributeCompletions(e,t,n,r);if(f(i,"attribute-value"))return this.getAttributeValueCompletions(e,t,n,r);var s=t.getLine(n.row).substr(0,n.column);return/&[a-z]*$/i.test(s)?this.getHTMLEntityCompletions(e,t,n,r):[]},this.getTagCompletions=function(e,t,n,r){return a.map(function(e){return{value:e,meta:"tag",score:1e6}})},this.getAttributeCompletions=function(e,t,n,r){var i=l(t,n);if(!i)return[];var s=o;return i in u&&(s=s.concat(Object.keys(u[i]))),s.map(function(e){return{caption:e,snippet:e+'="$0"',meta:"attribute",score:1e6}})},this.getAttributeValueCompletions=function(e,t,n,r){var i=l(t,n),s=c(t,n);if(!i)return[];var o=[];return i in u&&s in u[i]&&typeof u[i][s]=="object"&&(o=Object.keys(u[i][s])),o.map(function(e){return{caption:e,snippet:e,meta:"attribute value",score:1e6}})},this.getHTMLEntityCompletions=function(e,t,n,r){var i=["Aacute;","aacute;","Acirc;","acirc;","acute;","AElig;","aelig;","Agrave;","agrave;","alefsym;","Alpha;","alpha;","amp;","and;","ang;","Aring;","aring;","asymp;","Atilde;","atilde;","Auml;","auml;","bdquo;","Beta;","beta;","brvbar;","bull;","cap;","Ccedil;","ccedil;","cedil;","cent;","Chi;","chi;","circ;","clubs;","cong;","copy;","crarr;","cup;","curren;","Dagger;","dagger;","dArr;","darr;","deg;","Delta;","delta;","diams;","divide;","Eacute;","eacute;","Ecirc;","ecirc;","Egrave;","egrave;","empty;","emsp;","ensp;","Epsilon;","epsilon;","equiv;","Eta;","eta;","ETH;","eth;","Euml;","euml;","euro;","exist;","fnof;","forall;","frac12;","frac14;","frac34;","frasl;","Gamma;","gamma;","ge;","gt;","hArr;","harr;","hearts;","hellip;","Iacute;","iacute;","Icirc;","icirc;","iexcl;","Igrave;","igrave;","image;","infin;","int;","Iota;","iota;","iquest;","isin;","Iuml;","iuml;","Kappa;","kappa;","Lambda;","lambda;","lang;","laquo;","lArr;","larr;","lceil;","ldquo;","le;","lfloor;","lowast;","loz;","lrm;","lsaquo;","lsquo;","lt;","macr;","mdash;","micro;","middot;","minus;","Mu;","mu;","nabla;","nbsp;","ndash;","ne;","ni;","not;","notin;","nsub;","Ntilde;","ntilde;","Nu;","nu;","Oacute;","oacute;","Ocirc;","ocirc;","OElig;","oelig;","Ograve;","ograve;","oline;","Omega;","omega;","Omicron;","omicron;","oplus;","or;","ordf;","ordm;","Oslash;","oslash;","Otilde;","otilde;","otimes;","Ouml;","ouml;","para;","part;","permil;","perp;","Phi;","phi;","Pi;","pi;","piv;","plusmn;","pound;","Prime;","prime;","prod;","prop;","Psi;","psi;","quot;","radic;","rang;","raquo;","rArr;","rarr;","rceil;","rdquo;","real;","reg;","rfloor;","Rho;","rho;","rlm;","rsaquo;","rsquo;","sbquo;","Scaron;","scaron;","sdot;","sect;","shy;","Sigma;","sigma;","sigmaf;","sim;","spades;","sub;","sube;","sum;","sup;","sup1;","sup2;","sup3;","supe;","szlig;","Tau;","tau;","there4;","Theta;","theta;","thetasym;","thinsp;","THORN;","thorn;","tilde;","times;","trade;","Uacute;","uacute;","uArr;","uarr;","Ucirc;","ucirc;","Ugrave;","ugrave;","uml;","upsih;","Upsilon;","upsilon;","Uuml;","uuml;","weierp;","Xi;","xi;","Yacute;","yacute;","yen;","Yuml;","yuml;","Zeta;","zeta;","zwj;","zwnj;"];return i.map(function(e){return{caption:e,snippet:e,meta:"html entity",score:1e6}})}}).call(h.prototype),t.HtmlCompletions=h}),define("ace/mode/html",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/text","ace/mode/javascript","ace/mode/css","ace/mode/html_highlight_rules","ace/mode/behaviour/xml","ace/mode/folding/html","ace/mode/html_completions","ace/worker/worker_client"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./text").Mode,o=e("./javascript").Mode,u=e("./css").Mode,a=e("./html_highlight_rules").HtmlHighlightRules,f=e("./behaviour/xml").XmlBehaviour,l=e("./folding/html").FoldMode,c=e("./html_completions").HtmlCompletions,h=e("../worker/worker_client").WorkerClient,p=["area","base","br","col","embed","hr","img","input","keygen","link","meta","menuitem","param","source","track","wbr"],d=["li","dt","dd","p","rt","rp","optgroup","option","colgroup","td","th"],v=function(e){this.fragmentContext=e&&e.fragmentContext,this.HighlightRules=a,this.$behaviour=new f,this.$completer=new c,this.createModeDelegates({"js-":o,"css-":u}),this.foldingRules=new l(this.voidElements,i.arrayToMap(d))};r.inherits(v,s),function(){this.blockComment={start:""},this.voidElements=i.arrayToMap(p),this.getNextLineIndent=function(e,t,n){return this.$getIndent(t)},this.checkOutdent=function(e,t,n){return!1},this.getCompletions=function(e,t,n,r){return this.$completer.getCompletions(e,t,n,r)},this.createWorker=function(e){if(this.constructor!=v)return;var t=new h(["ace"],"ace/mode/html_worker","Worker");return t.attachToDocument(e.getDocument()),this.fragmentContext&&t.call("setOptions",[{context:this.fragmentContext}]),t.on("error",function(t){e.setAnnotations(t.data)}),t.on("terminate",function(){e.clearAnnotations()}),t},this.$id="ace/mode/html"}.call(v.prototype),t.Mode=v}); (function() { - window.require(["ace/mode/html"], function(m) { - if (typeof module == "object" && typeof exports == "object" && module) { - module.exports = m; - } - }); - })(); -define("ace/theme/monokai",["require","exports","module","ace/lib/dom"],function(e,t,n){t.isDark=!0,t.cssClass="ace-monokai",t.cssText=".ace-monokai .ace_gutter {background: #2F3129;color: #8F908A}.ace-monokai .ace_print-margin {width: 1px;background: #555651}.ace-monokai {background-color: #272822;color: #F8F8F2}.ace-monokai .ace_cursor {color: #F8F8F0}.ace-monokai .ace_marker-layer .ace_selection {background: #49483E}.ace-monokai.ace_multiselect .ace_selection.ace_start {box-shadow: 0 0 3px 0px #272822;}.ace-monokai .ace_marker-layer .ace_step {background: rgb(102, 82, 0)}.ace-monokai .ace_marker-layer .ace_bracket {margin: -1px 0 0 -1px;border: 1px solid #49483E}.ace-monokai .ace_marker-layer .ace_active-line {background: #202020}.ace-monokai .ace_gutter-active-line {background-color: #272727}.ace-monokai .ace_marker-layer .ace_selected-word {border: 1px solid #49483E}.ace-monokai .ace_invisible {color: #52524d}.ace-monokai .ace_entity.ace_name.ace_tag,.ace-monokai .ace_keyword,.ace-monokai .ace_meta.ace_tag,.ace-monokai .ace_storage {color: #F92672}.ace-monokai .ace_punctuation,.ace-monokai .ace_punctuation.ace_tag {color: #fff}.ace-monokai .ace_constant.ace_character,.ace-monokai .ace_constant.ace_language,.ace-monokai .ace_constant.ace_numeric,.ace-monokai .ace_constant.ace_other {color: #AE81FF}.ace-monokai .ace_invalid {color: #F8F8F0;background-color: #F92672}.ace-monokai .ace_invalid.ace_deprecated {color: #F8F8F0;background-color: #AE81FF}.ace-monokai .ace_support.ace_constant,.ace-monokai .ace_support.ace_function {color: #66D9EF}.ace-monokai .ace_fold {background-color: #A6E22E;border-color: #F8F8F2}.ace-monokai .ace_storage.ace_type,.ace-monokai .ace_support.ace_class,.ace-monokai .ace_support.ace_type {font-style: italic;color: #66D9EF}.ace-monokai .ace_entity.ace_name.ace_function,.ace-monokai .ace_entity.ace_other,.ace-monokai .ace_entity.ace_other.ace_attribute-name,.ace-monokai .ace_variable {color: #A6E22E}.ace-monokai .ace_variable.ace_parameter {font-style: italic;color: #FD971F}.ace-monokai .ace_string {color: #E6DB74}.ace-monokai .ace_comment {color: #75715E}.ace-monokai .ace_indent-guide {background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWPQ0FD0ZXBzd/wPAAjVAoxeSgNeAAAAAElFTkSuQmCC) right repeat-y}";var r=e("../lib/dom");r.importCssString(t.cssText,t.cssClass)}); (function() { - window.require(["ace/theme/monokai"], function(m) { - if (typeof module == "object" && typeof exports == "object" && module) { - module.exports = m; - } - }); - })(); diff --git a/examples/SmartSwitch/data_src/app.css b/examples/SmartSwitch/data_src/app.css deleted file mode 100644 index ea5eebbdb..000000000 --- a/examples/SmartSwitch/data_src/app.css +++ /dev/null @@ -1 +0,0 @@ -.fpicker{background:#f2f2f2;padding:10px;width:100%;max-width:150px;white-space:nowrap;font-size:32px;font-weight:700;text-align:center}.tpop .fpicker{margin:20px auto 0 auto}.fpicker-h,.fpicker-m{display:inline-block;width:50%}.fpicker input[type=text]{box-sizing:border-box;width:70%;padding:2px;margin:5px 0;border:0;background:#fff;color:#888;text-align:center;font-size:24px}.fpicker-down,.fpicker-up{text-align:center;color:#468c00;cursor:pointer}.fpicker-btn{margin-top:10px}.fpicker-btn input[type=button]{width:50%;padding:10px 0;border:0;background:#468c00;color:#fff;font-size:20px;cursor:pointer}.ncf-container{font-size:14px;box-sizing:border-box;position:fixed;z-index:999999}.ncf-container.nfc-top-left{top:12px;left:12px}.ncf-container.nfc-top-right{top:12px;right:12px}.ncf-container.nfc-bottom-right{bottom:12px;right:12px}.ncf-container.nfc-bottom-left{bottom:12px;left:12px}@media (max-width:350px){.ncf-container{left:0;right:0}}.ncf-container .ncf{background:#fff;transition:.3s ease;position:relative;pointer-events:auto;overflow:hidden;margin:0 0 6px;padding:30px;width:100px;border-radius:3px 3px 3px 3px;box-shadow:0 0 12px #999;color:#000;opacity:.9;background-position:15px!important;background-repeat:no-repeat!important;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.ncf-container .ncf:hover{box-shadow:0 0 12px #000;opacity:1;cursor:pointer}.ncf-container .ncf .ncf-title{font-weight:700;font-size:16px;text-align:left;margin-top:0;margin-bottom:6px;word-wrap:break-word}.ncf-container .ncf .nfc-message{margin:0;text-align:left;word-wrap:break-word}.ncf-container .success{background:#51a351;color:#fff;padding:15px 15px 15px 50px;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAADsSURBVEhLY2AYBfQMgf///3P8+/evAIgvA/FsIF+BavYDDWMBGroaSMMBiE8VC7AZDrIFaMFnii3AZTjUgsUUWUDA8OdAH6iQbQEhw4HyGsPEcKBXBIC4ARhex4G4BsjmweU1soIFaGg/WtoFZRIZdEvIMhxkCCjXIVsATV6gFGACs4Rsw0EGgIIH3QJYJgHSARQZDrWAB+jawzgs+Q2UO49D7jnRSRGoEFRILcdmEMWGI0cm0JJ2QpYA1RDvcmzJEWhABhD/pqrL0S0CWuABKgnRki9lLseS7g2AlqwHWQSKH4oKLrILpRGhEQCw2LiRUIa4lwAAAABJRU5ErkJggg==)}.ncf-container .info{background:#2f96b4;color:#fff;padding:15px 15px 15px 50px;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGwSURBVEhLtZa9SgNBEMc9sUxxRcoUKSzSWIhXpFMhhYWFhaBg4yPYiWCXZxBLERsLRS3EQkEfwCKdjWJAwSKCgoKCcudv4O5YLrt7EzgXhiU3/4+b2ckmwVjJSpKkQ6wAi4gwhT+z3wRBcEz0yjSseUTrcRyfsHsXmD0AmbHOC9Ii8VImnuXBPglHpQ5wwSVM7sNnTG7Za4JwDdCjxyAiH3nyA2mtaTJufiDZ5dCaqlItILh1NHatfN5skvjx9Z38m69CgzuXmZgVrPIGE763Jx9qKsRozWYw6xOHdER+nn2KkO+Bb+UV5CBN6WC6QtBgbRVozrahAbmm6HtUsgtPC19tFdxXZYBOfkbmFJ1VaHA1VAHjd0pp70oTZzvR+EVrx2Ygfdsq6eu55BHYR8hlcki+n+kERUFG8BrA0BwjeAv2M8WLQBtcy+SD6fNsmnB3AlBLrgTtVW1c2QN4bVWLATaIS60J2Du5y1TiJgjSBvFVZgTmwCU+dAZFoPxGEEs8nyHC9Bwe2GvEJv2WXZb0vjdyFT4Cxk3e/kIqlOGoVLwwPevpYHT+00T+hWwXDf4AJAOUqWcDhbwAAAAASUVORK5CYII=)}.ncf-container .warning{background:#f87400;color:#fff;padding:15px 15px 15px 50px;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGYSURBVEhL5ZSvTsNQFMbXZGICMYGYmJhAQIJAICYQPAACiSDB8AiICQQJT4CqQEwgJvYASAQCiZiYmJhAIBATCARJy+9rTsldd8sKu1M0+dLb057v6/lbq/2rK0mS/TRNj9cWNAKPYIJII7gIxCcQ51cvqID+GIEX8ASG4B1bK5gIZFeQfoJdEXOfgX4QAQg7kH2A65yQ87lyxb27sggkAzAuFhbbg1K2kgCkB1bVwyIR9m2L7PRPIhDUIXgGtyKw575yz3lTNs6X4JXnjV+LKM/m3MydnTbtOKIjtz6VhCBq4vSm3ncdrD2lk0VgUXSVKjVDJXJzijW1RQdsU7F77He8u68koNZTz8Oz5yGa6J3H3lZ0xYgXBK2QymlWWA+RWnYhskLBv2vmE+hBMCtbA7KX5drWyRT/2JsqZ2IvfB9Y4bWDNMFbJRFmC9E74SoS0CqulwjkC0+5bpcV1CZ8NMej4pjy0U+doDQsGyo1hzVJttIjhQ7GnBtRFN1UarUlH8F3xict+HY07rEzoUGPlWcjRFRr4/gChZgc3ZL2d8oAAAAASUVORK5CYII=)}.ncf-container .error{background:#bd362f;color:#fff;padding:15px 15px 15px 50px;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAHOSURBVEhLrZa/SgNBEMZzh0WKCClSCKaIYOED+AAKeQQLG8HWztLCImBrYadgIdY+gIKNYkBFSwu7CAoqCgkkoGBI/E28PdbLZmeDLgzZzcx83/zZ2SSXC1j9fr+I1Hq93g2yxH4iwM1vkoBWAdxCmpzTxfkN2RcyZNaHFIkSo10+8kgxkXIURV5HGxTmFuc75B2RfQkpxHG8aAgaAFa0tAHqYFfQ7Iwe2yhODk8+J4C7yAoRTWI3w/4klGRgR4lO7Rpn9+gvMyWp+uxFh8+H+ARlgN1nJuJuQAYvNkEnwGFck18Er4q3egEc/oO+mhLdKgRyhdNFiacC0rlOCbhNVz4H9FnAYgDBvU3QIioZlJFLJtsoHYRDfiZoUyIxqCtRpVlANq0EU4dApjrtgezPFad5S19Wgjkc0hNVnuF4HjVA6C7QrSIbylB+oZe3aHgBsqlNqKYH48jXyJKMuAbiyVJ8KzaB3eRc0pg9VwQ4niFryI68qiOi3AbjwdsfnAtk0bCjTLJKr6mrD9g8iq/S/B81hguOMlQTnVyG40wAcjnmgsCNESDrjme7wfftP4P7SP4N3CJZdvzoNyGq2c/HWOXJGsvVg+RA/k2MC/wN6I2YA2Pt8GkAAAAASUVORK5CYII=)!important}.ncf-container button{position:relative;right:-.3em;top:-.3em;float:right;font-weight:700;color:#fff;text-shadow:0 1px 0 #fff;opacity:.8;line-height:1;font-size:16px;padding:0;cursor:pointer;background:0 0;border:0}.ncf-container button:hover{opacity:1}.tpop{position:fixed;top:0;left:0;width:100%;height:100vh;background:rgba(0,0,0,.7);transition:all .5s;visibility:hidden;opacity:0}.tpop.show{visibility:visible;opacity:1}.tpicker{background:#f2f2f2;padding:10px;width:100%;max-width:150px;white-space:nowrap;font-size:32px;font-weight:700;text-align:center}.tpop .tpicker{margin:20px auto 0 auto}.tpicker-h,.tpicker-m{display:inline-block;width:50%}.tpicker input[type=text]{box-sizing:border-box;width:70%;padding:10px;margin:5px 0;border:0;background:#fff;color:#888;text-align:center;font-size:24px}.tpicker-down,.tpicker-up{text-align:center;color:#ff853f;cursor:pointer}.tpicker-btn{margin-top:10px}.tpicker-btn input[type=button]{width:50%;padding:10px 0;border:0;background:#a83a0b;color:#fff;font-size:20px;cursor:pointer} \ No newline at end of file diff --git a/examples/SmartSwitch/data_src/app.min.js b/examples/SmartSwitch/data_src/app.min.js deleted file mode 100644 index f493e7f78..000000000 --- a/examples/SmartSwitch/data_src/app.min.js +++ /dev/null @@ -1,533 +0,0 @@ -var tpick={attach:function(target){var dig=document.getElementById(target).value.split(":");var t1=dig[0]||"23";var t2=dig[1]||"59";var uniqueID=0;while(document.getElementById("tpick-"+uniqueID)!=null){uniqueID=Math.floor(Math.random()*(100-2))+1;} -var tw=document.createElement("div");tw.id="tpick-"+uniqueID;tw.classList.add("tpop");tw.dataset.target=target;tw.addEventListener("click",function(evt){if(evt.target.classList.contains("tpop")){this.classList.remove("show");}});var tp=document.createElement("div");tp.classList.add("tpicker");tp.appendChild(this.draw("h",t1));tp.appendChild(this.draw("m",t2));var bottom=document.createElement("div"),ok=document.createElement("input");ok.setAttribute("type","button");ok.value="OK";ok.addEventListener("click",function(){tpick.set(this);});bottom.classList.add("tpicker-btn");bottom.appendChild(ok);tp.appendChild(bottom);tw.appendChild(tp);document.body.appendChild(tw);var target=document.getElementById(target);target.dataset.dp=uniqueID;target.onfocus=function(){document.getElementById("tpick-"+this.dataset.dp).classList.add("show");};},draw:function(type,tv){var docket=document.createElement("div"),up=document.createElement("div"),down=document.createElement("div"),text=document.createElement("input");docket.classList.add("tpicker-"+type);up.classList.add("tpicker-up");down.classList.add("tpicker-down");up.innerHTML="︿";down.innerHTML="﹀";text.readOnly=true;text.setAttribute("type","text");if(type=="h"){text.value=tv;up.addEventListener("click",function(){tpick.spin("h",1,this);});down.addEventListener("click",function(){tpick.spin("h",0,this);});}else if(type=="m"){text.value=tv;up.addEventListener("click",function(){tpick.spin("m",1,this);});down.addEventListener("click",function(){tpick.spin("m",0,this);});} -docket.appendChild(up);docket.appendChild(text);docket.appendChild(down);return docket;},spin:function(type,direction,el){var parent=el.parentElement,field=parent.getElementsByTagName("input")[0],value=field.value;if(type=="h"){value=parseInt(value);if(direction){value++;}else{value--;} -if(value==-1){value=23;}else if(value>23){value=0;}}else if(type=="m"){value=parseInt(value);if(direction){value+=5;}else{value-=5;} -if(value<0){value=55;}else if(value>59){value=0;} -if(value<10){value="0"+value;}} -field.value=('00'+value).substr(-2);},set:function(el){var parent=el.parentElement;while(parent.classList.contains("tpop")==false){parent=parent.parentElement;} -var input=parent.querySelectorAll("input[type=text]");var time=input[0].value+":"+input[1].value;document.getElementById(parent.dataset.target).value=time;parent.classList.remove("show");}};var fpick={attach:function(target){var dig=document.getElementById(target).value.split(".");var t1=dig[0]||"1";var t2=dig[1]||"2";var uniqueID=0;while(document.getElementById("fpick-"+uniqueID)!=null){uniqueID=Math.floor(Math.random()*(100-2))+1;} -var tw=document.createElement("div");tw.id="fpick-"+uniqueID;tw.classList.add("tpop");tw.dataset.target=target;tw.addEventListener("click",function(evt){if(evt.target.classList.contains("tpop")){this.classList.remove("show");}});var tp=document.createElement("div");tp.classList.add("fpicker");tp.appendChild(this.draw("h",t1));tp.appendChild(this.draw("m",t2));var bottom=document.createElement("div"),ok=document.createElement("input");ok.setAttribute("type","button");ok.value="OK";ok.addEventListener("click",function(){fpick.set(this);});bottom.classList.add("fpicker-btn");bottom.appendChild(ok);tp.appendChild(bottom);tw.appendChild(tp);document.body.appendChild(tw);var target=document.getElementById(target);target.dataset.dp=uniqueID;target.onfocus=function(){document.getElementById("fpick-"+this.dataset.dp).classList.add("show");};},draw:function(type,tv){var docket=document.createElement("div"),up=document.createElement("div"),down=document.createElement("div"),text=document.createElement("input");docket.classList.add("fpicker-"+type);up.classList.add("fpicker-up");down.classList.add("fpicker-down");up.innerHTML="︿";down.innerHTML="﹀";text.readOnly=true;text.setAttribute("type","text");if(type=="h"){text.value=tv;up.addEventListener("click",function(){fpick.spin("h",1,this);});down.addEventListener("click",function(){fpick.spin("h",0,this);});}else if(type=="m"){text.value=tv;up.addEventListener("click",function(){fpick.spin("m",1,this);});down.addEventListener("click",function(){fpick.spin("m",0,this);});} -docket.appendChild(up);docket.appendChild(text);docket.appendChild(down);return docket;},spin:function(type,direction,el){var parent=el.parentElement,field=parent.getElementsByTagName("input")[0],value=field.value;if(type=="h"){value=parseInt(value);if(direction){value++;}else{value--;} -if(value==-41){value=99;}else if(value>99){value=-40;}}else if(type=="m"){value=parseInt(value);if(direction){value++;}else{value--;} -if(value<0){value=9;}else if(value>9){value=0;}} -field.value=value;},set:function(el){var parent=el.parentElement;while(parent.classList.contains("tpop")==false){parent=parent.parentElement;} -var input=parent.querySelectorAll("input[type=text]");var temperature=input[0].value+"."+input[1].value;document.getElementById(parent.dataset.target).value=temperature;parent.classList.remove("show");}};!function(t){function n(i){if(e[i]) -return e[i].exports;var o=e[i]={i:i,l:!1,exports:{}};return t[i].call(o.exports,o,o.exports,n),o.l=!0,o.exports} -var e={};n.m=t,n.c=e,n.d=function(t,e,i){n.o(t,e)||Object.defineProperty(t,e,{configurable:!1,enumerable:!0,get:i})},n.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return n.d(e,"a",e),e},n.o=function(t,n){return Object.prototype.hasOwnProperty.call(t,n)},n.p="",n(n.s=0)} -([function(t,n,e){e(1),t.exports=e(4)},function(t,n,e){"use strict";var i=Object.assign||function(t){for(var n=1;n-1} -(t.positionClass)||(console.warn("An invalid notification position class has been specified."),t.positionClass=c.positionClass),t.onclick&&"function"!=typeof t.onclick&&(console.warn("Notification on click must be a function."),t.onclick=c.onclick),"number"!=typeof t.showDuration&&(t.showDuration=c.showDuration),(0,o.isString)(t.theme)&&0!==t.theme.length||(console.warn("Notification theme must be a string with length"),t.theme=c.theme),t} -function e(t){return t=n(t),function(){var n=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},e=n.title,i=n.message,c=r(t.positionClass);if(!e&&!i) -return console.warn("Notification must contain a title or a message!");var a=(0,o.createElement)("div","ncf",t.theme);if(!0===t.closeOnClick&&a.addEventListener("click",function(){return c.removeChild(a)}),t.onclick&&a.addEventListener("click",function(n){return t.onclick(n)}),t.displayCloseButton){var s=(0,o.createElement)("button");s.innerText="X",!1===t.closeOnClick&&s.addEventListener("click",function(){return c.removeChild(a)}),(0,o.append)(a,s)} -if((0,o.isString)(e)&&e.length&&(0,o.append)(a,(0,o.createParagraph)("ncf-title")(e)),(0,o.isString)(i)&&i.length&&(0,o.append)(a,(0,o.createParagraph)("nfc-message")(i)),(0,o.append)(c,a),t.showDuration&&t.showDuration>0){var l=setTimeout(function(){c.removeChild(a),0===c.querySelectorAll(".ncf").length&&document.body.removeChild(c)},t.showDuration);(t.closeOnClick||t.displayCloseButton)&&a.addEventListener("click",function(){return clearTimeout(l)})}}} -function r(t){var n=document.querySelector("."+t);return n||(n=(0,o.createElement)("div","ncf-container",t),(0,o.append)(document.body,n)),n} -var c={closeOnClick:!0,displayCloseButton:!1,positionClass:"nfc-top-right",onclick:!1,showDuration:3500,theme:"success"};t.createNotification?console.warn("Window already contains a create notification function. Have you included the script twice?"):t.createNotification=e} -(window)},function(t,n,e){"use strict";!function(){function t(t){this.el=t;for(var n=t.className.replace(/^\s+|\s+$/g,"").split(/\s+/),i=0;i1?n-1:0),i=1;i1?n-1:0),i=1;i1?n-1:0),i=1;i1?n-1:0),c=1;cp;p++)"zIndex"in i[p]&&(l.push(i[p].zIndex),i[p].zIndex<0&&(m[i[p].zIndex]=i[p]));for(l.sort(h);l[k]<0;) -if(e=m[l[k++]],n.push(e.apply(d,g)),b) -return b=f,n;for(p=0;q>p;p++) -if(e=i[p],"zIndex"in e) -if(e.zIndex==l[k]){if(n.push(e.apply(d,g)),b) -break;do -if(k++,e=m[l[k]],e&&n.push(e.apply(d,g)),b) -break;while(e)}else -m[e.zIndex]=e;else if(n.push(e.apply(d,g)),b) -break;return b=f,a=o,n.length?n:null};return j._events=i,j.listeners=function(a){var b,c,d,g,h,j,k,l,m=a.split(e),n=i,o=[n],p=[];for(g=0,h=m.length;h>g;g++){for(l=[],j=0,k=o.length;k>j;j++) -for(n=o[j].n,c=[n[m[g]],n[f]],d=2;d--;) -b=c[d],b&&(l.push(b),p=p.concat(b.f||[]));o=l} -return p},j.on=function(a,b){if(a=String(a),"function"!=typeof b) -return function(){};for(var c=a.split(e),d=i,f=0,h=c.length;h>f;f++) -d=d.n,d=d.hasOwnProperty(c[f])&&d[c[f]]||(d[c[f]]={n:{}});for(d.f=d.f||[],f=0,h=d.f.length;h>f;f++) -if(d.f[f]==b) -return g;return d.f.push(b),function(a){+a==+a&&(b.zIndex=+a)}},j.f=function(a){var b=[].slice.call(arguments,1);return function(){j.apply(null,[a,null].concat(b).concat([].slice.call(arguments,0)))}},j.stop=function(){b=1},j.nt=function(b){return b?new RegExp("(?:\\.|\\/|^)"+b+"(?:\\.|\\/|$)").test(a):a},j.nts=function(){return a.split(e)},j.off=j.unbind=function(a,b){if(!a) -return void(j._events=i={n:{}});var c,g,h,k,l,m,n,o=a.split(e),p=[i];for(k=0,l=o.length;l>k;k++) -for(m=0;mk;k++) -for(c=p[k];c.n;){if(b){if(c.f){for(m=0,n=c.f.length;n>m;m++) -if(c.f[m]==b){c.f.splice(m,1);break} -!c.f.length&&delete c.f} -for(g in c.n) -if(c.n[d](g)&&c.n[g].f){var q=c.n[g].f;for(m=0,n=q.length;n>m;m++) -if(q[m]==b){q.splice(m,1);break} -!q.length&&delete c.n[g].f}}else{delete c.f;for(g in c.n) -c.n[d](g)&&c.n[g].f&&delete c.n[g].f} -c=c.n}},j.once=function(a,b){var c=function(){return j.unbind(a,c),b.apply(this,arguments)};return j.on(a,c)},j.version=c,j.toString=function(){return"You are running Eve "+c},j}),function(a,b){"function"==typeof define&&define.amd?define("raphael.core",["eve"],function(a){return b(a)}):"object"==typeof exports?module.exports=b(require("eve")):a.Raphael=b(a.eve)} -(this,function(a){function b(c){if(b.is(c,"function")) -return t?c():a.on("raphael.DOMload",c);if(b.is(c,U)) -return b._engine.create[C](b,c.splice(0,3+b.is(c[0],S))).add(c);var d=Array.prototype.slice.call(arguments,0);if(b.is(d[d.length-1],"function")){var e=d.pop();return t?e.call(b._engine.create[C](b,d)):a.on("raphael.DOMload",function(){e.call(b._engine.create[C](b,d))})} -return b._engine.create[C](b,arguments)} -function c(a){if("function"==typeof a||Object(a)!==a) -return a;var b=new a.constructor;for(var d in a) -a[y](d)&&(b[d]=c(a[d]));return b} -function d(a,b){for(var c=0,d=a.length;d>c;c++) -if(a[c]===b) -return a.push(a.splice(c,1)[0])} -function e(a,b,c){function e(){var f=Array.prototype.slice.call(arguments,0),g=f.join("␀"),h=e.cache=e.cache||{},i=e.count=e.count||[];return h[y](g)?(d(i,g),c?c(h[g]):h[g]):(i.length>=1e3&&delete h[i.shift()],i.push(g),h[g]=a[C](b,f),c?c(h[g]):h[g])} -return e} -function f(){return this.hex} -function g(a,b){for(var c=[],d=0,e=a.length;e-2*!b>d;d+=2){var f=[{x:+a[d-2],y:+a[d-1]},{x:+a[d],y:+a[d+1]},{x:+a[d+2],y:+a[d+3]},{x:+a[d+4],y:+a[d+5]}];b?d?e-4==d?f[3]={x:+a[0],y:+a[1]}:e-2==d&&(f[2]={x:+a[0],y:+a[1]},f[3]={x:+a[2],y:+a[3]}):f[0]={x:+a[e-2],y:+a[e-1]}:e-4==d?f[3]=f[2]:d||(f[0]={x:+a[d],y:+a[d+1]}),c.push(["C",(-f[0].x+6*f[1].x+f[2].x)/6,(-f[0].y+6*f[1].y+f[2].y)/6,(f[1].x+6*f[2].x-f[3].x)/6,(f[1].y+6*f[2].y-f[3].y)/6,f[2].x,f[2].y])} -return c} -function h(a,b,c,d,e){var f=-3*b+9*c-9*d+3*e,g=a*f+6*b-12*c+6*d;return a*g-3*b+3*c} -function i(a,b,c,d,e,f,g,i,j){null==j&&(j=1),j=j>1?1:0>j?0:j;for(var k=j/2,l=12,m=[-.1252,.1252,-.3678,.3678,-.5873,.5873,-.7699,.7699,-.9041,.9041,-.9816,.9816],n=[.2491,.2491,.2335,.2335,.2032,.2032,.1601,.1601,.1069,.1069,.0472,.0472],o=0,p=0;l>p;p++){var q=k*m[p]+k,r=h(q,a,c,e,g),s=h(q,b,d,f,i),t=r*r+s*s;o+=n[p]*M.sqrt(t)} -return k*o} -function j(a,b,c,d,e,f,g,h,j){if(!(0>j||i(a,b,c,d,e,f,g,h)o;) -m/=2,n+=(j>k?1:-1)*m,k=i(a,b,c,d,e,f,g,h,n);return n}} -function k(a,b,c,d,e,f,g,h){if(!(N(a,c)N(e,g)||N(b,d)N(f,h))){var i=(a*d-b*c)*(e-g)-(a-c)*(e*h-f*g),j=(a*d-b*c)*(f-h)-(b-d)*(e*h-f*g),k=(a-c)*(f-h)-(b-d)*(e-g);if(k){var l=i/k,m=j/k,n=+l.toFixed(2),o=+m.toFixed(2);if(!(n<+O(a,c).toFixed(2)||n>+N(a,c).toFixed(2)||n<+O(e,g).toFixed(2)||n>+N(e,g).toFixed(2)||o<+O(b,d).toFixed(2)||o>+N(b,d).toFixed(2)||o<+O(f,h).toFixed(2)||o>+N(f,h).toFixed(2))) -return{x:l,y:m}}}} -function l(a,c,d){var e=b.bezierBBox(a),f=b.bezierBBox(c);if(!b.isBBoxIntersect(e,f)) -return d?0:[];for(var g=i.apply(0,a),h=i.apply(0,c),j=N(~~(g/5),1),l=N(~~(h/5),1),m=[],n=[],o={},p=d?0:[],q=0;j+1>q;q++){var r=b.findDotsAtSegment.apply(b,a.concat(q/j));m.push({x:r.x,y:r.y,t:q/j})} -for(q=0;l+1>q;q++) -r=b.findDotsAtSegment.apply(b,c.concat(q/l)),n.push({x:r.x,y:r.y,t:q/l});for(q=0;j>q;q++) -for(var s=0;l>s;s++){var t=m[q],u=m[q+1],v=n[s],w=n[s+1],x=P(u.x-t.x)<.001?"y":"x",y=P(w.x-v.x)<.001?"y":"x",z=k(t.x,t.y,u.x,u.y,v.x,v.y,w.x,w.y);if(z){if(o[z.x.toFixed(4)]==z.y.toFixed(4)) -continue;o[z.x.toFixed(4)]=z.y.toFixed(4);var A=t.t+P((z[x]-t[x])/(u[x]-t[x]))*(u.t-t.t),B=v.t+P((z[y]-v[y])/(w[y]-v[y]))*(w.t-v.t);A>=0&&1.001>=A&&B>=0&&1.001>=B&&(d?p++:p.push({x:z.x,y:z.y,t1:O(A,1),t2:O(B,1)}))}} -return p} -function m(a,c,d){a=b._path2curve(a),c=b._path2curve(c);for(var e,f,g,h,i,j,k,m,n,o,p=d?0:[],q=0,r=a.length;r>q;q++){var s=a[q];if("M"==s[0]) -e=i=s[1],f=j=s[2];else{"C"==s[0]?(n=[e,f].concat(s.slice(1)),e=n[6],f=n[7]):(n=[e,f,e,f,i,j,i,j],e=i,f=j);for(var t=0,u=c.length;u>t;t++){var v=c[t];if("M"==v[0]) -g=k=v[1],h=m=v[2];else{"C"==v[0]?(o=[g,h].concat(v.slice(1)),g=o[6],h=o[7]):(o=[g,h,g,h,k,m,k,m],g=k,h=m);var w=l(n,o,d);if(d) -p+=w;else{for(var x=0,y=w.length;y>x;x++) -w[x].segment1=q,w[x].segment2=t,w[x].bez1=n,w[x].bez2=o;p=p.concat(w)}}}}} -return p} -function n(a,b,c,d,e,f){null!=a?(this.a=+a,this.b=+b,this.c=+c,this.d=+d,this.e=+e,this.f=+f):(this.a=1,this.b=0,this.c=0,this.d=1,this.e=0,this.f=0)} -function o(){return this.x+G+this.y+G+this.width+" × "+this.height} -function p(a,b,c,d,e,f){function g(a){return((l*a+k)*a+j)*a} -function h(a,b){var c=i(a,b);return((o*c+n)*c+m)*c} -function i(a,b){var c,d,e,f,h,i;for(e=a,i=0;8>i;i++){if(f=g(e)-a,P(f)e) -return c;if(e>d) -return d;for(;d>c;){if(f=g(e),P(f-a)f?c=e:d=e,e=(d-c)/2+c} -return e} -var j=3*b,k=3*(d-b)-j,l=1-j-k,m=3*c,n=3*(e-c)-m,o=1-m-n;return h(a,1/(200*f))} -function q(a,b){var c=[],d={};if(this.ms=b,this.times=1,a){for(var e in a) -a[y](e)&&(d[$(e)]=a[e],c.push($(e)));c.sort(ka)} -this.anim=d,this.top=c[c.length-1],this.percents=c} -function r(c,d,e,f,g,h){e=$(e);var i,j,k,l,m,o,q=c.ms,r={},s={},t={};if(f) -for(w=0,x=fb.length;x>w;w++){var u=fb[w];if(u.el.id==d.id&&u.anim==c){u.percent!=e?(fb.splice(w,1),k=1):j=u,d.attr(u.totalOrigin);break}} -else -f=+s;for(var w=0,x=c.percents.length;x>w;w++){if(c.percents[w]==e||c.percents[w]>f*c.top){e=c.percents[w],m=c.percents[w-1]||0,q=q/c.top*(e-m),l=c.percents[w+1],i=c.anim[e];break} -f&&d.attr(c.anim[c.percents[w]])} -if(i){if(j) -j.initstatus=f,j.start=new Date-j.ms*f;else{for(var z in i) -if(i[y](z)&&(ca[y](z)||d.paper.customAttributes[y](z))) -switch(r[z]=d.attr(z),null==r[z]&&(r[z]=ba[z]),s[z]=i[z],ca[z]){case S:t[z]=(s[z]-r[z])/q;break;case"colour":r[z]=b.getRGB(r[z]);var A=b.getRGB(s[z]);t[z]={r:(A.r-r[z].r)/q,g:(A.g-r[z].g)/q,b:(A.b-r[z].b)/q};break;case"path":var B=Ia(r[z],s[z]),C=B[1];for(r[z]=B[0],t[z]=[],w=0,x=r[z].length;x>w;w++){t[z][w]=[0];for(var E=1,F=r[z][w].length;F>E;E++) -t[z][w][E]=(C[w][E]-r[z][w][E])/q} -break;case"transform":var G=d._,J=Na(G[z],s[z]);if(J) -for(r[z]=J.from,s[z]=J.to,t[z]=[],t[z].real=!0,w=0,x=r[z].length;x>w;w++) -for(t[z][w]=[r[z][w][0]],E=1,F=r[z][w].length;F>E;E++) -t[z][w][E]=(s[z][w][E]-r[z][w][E])/q;else{var K=d.matrix||new n,L={_:{transform:G.transform},getBBox:function(){return d.getBBox(1)}};r[z]=[K.a,K.b,K.c,K.d,K.e,K.f],La(L,s[z]),s[z]=L._.transform,t[z]=[(L.matrix.a-K.a)/q,(L.matrix.b-K.b)/q,(L.matrix.c-K.c)/q,(L.matrix.d-K.d)/q,(L.matrix.e-K.e)/q,(L.matrix.f-K.f)/q]} -break;case"csv":var M=H(i[z])[I](v),N=H(r[z])[I](v);if("clip-rect"==z) -for(r[z]=N,t[z]=[],w=N.length;w--;) -t[z][w]=(M[w]-r[z][w])/q;s[z]=M;break;default:for(M=[][D](i[z]),N=[][D](r[z]),t[z]=[],w=d.paper.customAttributes[z].length;w--;) -t[z][w]=((M[w]||0)-(N[w]||0))/q} -var O=i.easing,P=b.easing_formulas[O];if(!P) -if(P=H(O).match(Y),P&&5==P.length){var Q=P;P=function(a){return p(a,+Q[1],+Q[2],+Q[3],+Q[4],q)}}else -P=la;if(o=i.start||c.start||+new Date,u={anim:c,percent:e,timestamp:o,start:o+(c.del||0),status:0,initstatus:f||0,stop:!1,ms:q,easing:P,from:r,diff:t,to:s,el:d,callback:i.callback,prev:m,next:l,repeat:h||c.times,origin:d.attr(),totalOrigin:g},fb.push(u),f&&!j&&!k&&(u.stop=!0,u.start=new Date-q*f,1==fb.length)) -return hb();k&&(u.start=new Date-u.ms*f),1==fb.length&&gb(hb)} -a("raphael.anim.start."+d.id,d,c)}} -function s(a){for(var b=0;be;e++) -for(i=a[e],f=1,h=i.length;h>f;f+=2) -c=b.x(i[f],i[f+1]),d=b.y(i[f],i[f+1]),i[f]=c,i[f+1]=d;return a};if(b._g=z,b.type=z.win.SVGAngle||z.doc.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure","1.1")?"SVG":"VML","VML"==b.type){var qa,ra=z.doc.createElement("div");if(ra.innerHTML='',qa=ra.firstChild,qa.style.behavior="url(#default#VML)",!qa||"object"!=typeof qa.adj) -return b.type=F;ra=null} -b.svg=!(b.vml="VML"==b.type),b._Paper=B,b.fn=u=B.prototype=b.prototype,b._id=0,b._oid=0,b.is=function(a,b){return b=L.call(b),"finite"==b?!X[y](+a):"array"==b?a instanceof Array:"null"==b&&null===a||b==typeof a&&null!==a||"object"==b&&a===Object(a)||"array"==b&&Array.isArray&&Array.isArray(a)||V.call(a).slice(8,-1).toLowerCase()==b},b.angle=function(a,c,d,e,f,g){if(null==f){var h=a-d,i=c-e;return h||i?(180+180*M.atan2(-i,-h)/R+360)%360:0} -return b.angle(a,c,f,g)-b.angle(d,e,f,g)},b.rad=function(a){return a%360*R/180},b.deg=function(a){return Math.round(180*a/R%360*1e3)/1e3},b.snapTo=function(a,c,d){if(d=b.is(d,"finite")?d:10,b.is(a,U)){for(var e=a.length;e--;) -if(P(a[e]-c)<=d) -return a[e]}else{a=+a;var f=c%a;if(d>f) -return c-f;if(f>a-d) -return c-f+a} -return c};b.createUUID=function(a,b){return function(){return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(a,b).toUpperCase()}} -(/[xy]/g,function(a){var b=16*M.random()|0,c="x"==a?b:3&b|8;return c.toString(16)});b.setWindow=function(c){a("raphael.setWindow",b,z.win,c),z.win=c,z.doc=z.win.document,b._engine.initWin&&b._engine.initWin(z.win)};var sa=function(a){if(b.vml){var c,d=/^\s+|\s+$/g;try{var f=new ActiveXObject("htmlfile");f.write(""),f.close(),c=f.body}catch(g){c=createPopup().document.body} -var h=c.createTextRange();sa=e(function(a){try{c.style.color=H(a).replace(d,F);var b=h.queryCommandValue("ForeColor");return b=(255&b)<<16|65280&b|(16711680&b)>>>16,"#"+("000000"+b.toString(16)).slice(-6)}catch(e){return"none"}})}else{var i=z.doc.createElement("i");i.title="Raphaël Colour Picker",i.style.display="none",z.doc.body.appendChild(i),sa=e(function(a){return i.style.color=a,z.doc.defaultView.getComputedStyle(i,F).getPropertyValue("color")})} -return sa(a)},ta=function(){return"hsb("+[this.h,this.s,this.b]+")"},ua=function(){return"hsl("+[this.h,this.s,this.l]+")"},va=function(){return this.hex},wa=function(a,c,d){if(null==c&&b.is(a,"object")&&"r"in a&&"g"in a&&"b"in a&&(d=a.b,c=a.g,a=a.r),null==c&&b.is(a,T)){var e=b.getRGB(a);a=e.r,c=e.g,d=e.b} -return(a>1||c>1||d>1)&&(a/=255,c/=255,d/=255),[a,c,d]},xa=function(a,c,d,e){a*=255,c*=255,d*=255;var f={r:a,g:c,b:d,hex:b.rgb(a,c,d),toString:va};return b.is(e,"finite")&&(f.opacity=e),f};b.color=function(a){var c;return b.is(a,"object")&&"h"in a&&"s"in a&&"b"in a?(c=b.hsb2rgb(a),a.r=c.r,a.g=c.g,a.b=c.b,a.hex=c.hex):b.is(a,"object")&&"h"in a&&"s"in a&&"l"in a?(c=b.hsl2rgb(a),a.r=c.r,a.g=c.g,a.b=c.b,a.hex=c.hex):(b.is(a,"string")&&(a=b.getRGB(a)),b.is(a,"object")&&"r"in a&&"g"in a&&"b"in a?(c=b.rgb2hsl(a),a.h=c.h,a.s=c.s,a.l=c.l,c=b.rgb2hsb(a),a.v=c.b):(a={hex:"none"},a.r=a.g=a.b=a.h=a.s=a.v=a.l=-1)),a.toString=va,a},b.hsb2rgb=function(a,b,c,d){this.is(a,"object")&&"h"in a&&"s"in a&&"b"in a&&(c=a.b,b=a.s,d=a.o,a=a.h),a*=360;var e,f,g,h,i;return a=a%360/60,i=c*b,h=i*(1-P(a%2-1)),e=f=g=c-i,a=~~a,e+=[i,h,0,0,h,i][a],f+=[h,i,i,h,0,0][a],g+=[0,0,h,i,i,h][a],xa(e,f,g,d)},b.hsl2rgb=function(a,b,c,d){this.is(a,"object")&&"h"in a&&"s"in a&&"l"in a&&(c=a.l,b=a.s,a=a.h),(a>1||b>1||c>1)&&(a/=360,b/=100,c/=100),a*=360;var e,f,g,h,i;return a=a%360/60,i=2*b*(.5>c?c:1-c),h=i*(1-P(a%2-1)),e=f=g=c-i/2,a=~~a,e+=[i,h,0,0,h,i][a],f+=[h,i,i,h,0,0][a],g+=[0,0,h,i,i,h][a],xa(e,f,g,d)},b.rgb2hsb=function(a,b,c){c=wa(a,b,c),a=c[0],b=c[1],c=c[2];var d,e,f,g;return f=N(a,b,c),g=f-O(a,b,c),d=0==g?null:f==a?(b-c)/g:f==b?(c-a)/g+2:(a-b)/g+4,d=(d+360)%6*60/360,e=0==g?0:g/f,{h:d,s:e,b:f,toString:ta}},b.rgb2hsl=function(a,b,c){c=wa(a,b,c),a=c[0],b=c[1],c=c[2];var d,e,f,g,h,i;return g=N(a,b,c),h=O(a,b,c),i=g-h,d=0==i?null:g==a?(b-c)/i:g==b?(c-a)/i+2:(a-b)/i+4,d=(d+360)%6*60/360,f=(g+h)/2,e=0==i?0:.5>f?i/(2*f):i/(2-2*f),{h:d,s:e,l:f,toString:ua}},b._path2string=function(){return this.join(",").replace(fa,"$1")};b._preload=function(a,b){var c=z.doc.createElement("img");c.style.cssText="position:absolute;left:-9999em;top:-9999em",c.onload=function(){b.call(this),this.onload=null,z.doc.body.removeChild(this)},c.onerror=function(){z.doc.body.removeChild(this)},z.doc.body.appendChild(c),c.src=a};b.getRGB=e(function(a){if(!a||(a=H(a)).indexOf("-")+1) -return{r:-1,g:-1,b:-1,hex:"none",error:1,toString:f};if("none"==a) -return{r:-1,g:-1,b:-1,hex:"none",toString:f};!(ea[y](a.toLowerCase().substring(0,2))||"#"==a.charAt())&&(a=sa(a));var c,d,e,g,h,i,j=a.match(W);return j?(j[2]&&(e=_(j[2].substring(5),16),d=_(j[2].substring(3,5),16),c=_(j[2].substring(1,3),16)),j[3]&&(e=_((h=j[3].charAt(3))+h,16),d=_((h=j[3].charAt(2))+h,16),c=_((h=j[3].charAt(1))+h,16)),j[4]&&(i=j[4][I](da),c=$(i[0]),"%"==i[0].slice(-1)&&(c*=2.55),d=$(i[1]),"%"==i[1].slice(-1)&&(d*=2.55),e=$(i[2]),"%"==i[2].slice(-1)&&(e*=2.55),"rgba"==j[1].toLowerCase().slice(0,4)&&(g=$(i[3])),i[3]&&"%"==i[3].slice(-1)&&(g/=100)),j[5]?(i=j[5][I](da),c=$(i[0]),"%"==i[0].slice(-1)&&(c*=2.55),d=$(i[1]),"%"==i[1].slice(-1)&&(d*=2.55),e=$(i[2]),"%"==i[2].slice(-1)&&(e*=2.55),("deg"==i[0].slice(-3)||"°"==i[0].slice(-1))&&(c/=360),"hsba"==j[1].toLowerCase().slice(0,4)&&(g=$(i[3])),i[3]&&"%"==i[3].slice(-1)&&(g/=100),b.hsb2rgb(c,d,e,g)):j[6]?(i=j[6][I](da),c=$(i[0]),"%"==i[0].slice(-1)&&(c*=2.55),d=$(i[1]),"%"==i[1].slice(-1)&&(d*=2.55),e=$(i[2]),"%"==i[2].slice(-1)&&(e*=2.55),("deg"==i[0].slice(-3)||"°"==i[0].slice(-1))&&(c/=360),"hsla"==j[1].toLowerCase().slice(0,4)&&(g=$(i[3])),i[3]&&"%"==i[3].slice(-1)&&(g/=100),b.hsl2rgb(c,d,e,g)):(j={r:c,g:d,b:e,toString:f},j.hex="#"+(16777216|e|d<<8|c<<16).toString(16).slice(1),b.is(g,"finite")&&(j.opacity=g),j)):{r:-1,g:-1,b:-1,hex:"none",error:1,toString:f}},b),b.hsb=e(function(a,c,d){return b.hsb2rgb(a,c,d).hex}),b.hsl=e(function(a,c,d){return b.hsl2rgb(a,c,d).hex}),b.rgb=e(function(a,b,c){function d(a){return a+.5|0} -return"#"+(16777216|d(c)|d(b)<<8|d(a)<<16).toString(16).slice(1)}),b.getColor=function(a){var b=this.getColor.start=this.getColor.start||{h:0,s:1,b:a||.75},c=this.hsb2rgb(b.h,b.s,b.b);return b.h+=.075,b.h>1&&(b.h=0,b.s-=.2,b.s<=0&&(this.getColor.start={h:0,s:1,b:b.b})),c.hex},b.getColor.reset=function(){delete this.start},b.parsePathString=function(a){if(!a) -return null;var c=ya(a);if(c.arr) -return Aa(c.arr);var d={a:7,c:6,h:1,l:2,m:2,r:4,q:4,s:4,t:2,v:1,z:0},e=[];return b.is(a,U)&&b.is(a[0],U)&&(e=Aa(a)),e.length||H(a).replace(ga,function(a,b,c){var f=[],g=b.toLowerCase();if(c.replace(ia,function(a,b){b&&f.push(+b)}),"m"==g&&f.length>2&&(e.push([b][D](f.splice(0,2))),g="l",b="m"==b?"l":"L"),"r"==g) -e.push([b][D](f));else -for(;f.length>=d[g]&&(e.push([b][D](f.splice(0,d[g]))),d[g]););}),e.toString=b._path2string,c.arr=Aa(e),e},b.parseTransformString=e(function(a){if(!a) -return null;var c=[];return b.is(a,U)&&b.is(a[0],U)&&(c=Aa(a)),c.length||H(a).replace(ha,function(a,b,d){{var e=[];L.call(b)} -d.replace(ia,function(a,b){b&&e.push(+b)}),c.push([b][D](e))}),c.toString=b._path2string,c});var ya=function(a){var b=ya.ps=ya.ps||{};return b[a]?b[a].sleep=100:b[a]={sleep:100},setTimeout(function(){for(var c in b) -b[y](c)&&c!=a&&(b[c].sleep--,!b[c].sleep&&delete b[c])}),b[a]};b.findDotsAtSegment=function(a,b,c,d,e,f,g,h,i){var j=1-i,k=Q(j,3),l=Q(j,2),m=i*i,n=m*i,o=k*a+3*l*i*c+3*j*i*i*e+n*g,p=k*b+3*l*i*d+3*j*i*i*f+n*h,q=a+2*i*(c-a)+m*(e-2*c+a),r=b+2*i*(d-b)+m*(f-2*d+b),s=c+2*i*(e-c)+m*(g-2*e+c),t=d+2*i*(f-d)+m*(h-2*f+d),u=j*a+i*c,v=j*b+i*d,w=j*e+i*g,x=j*f+i*h,y=90-180*M.atan2(q-s,r-t)/R;return(q>s||t>r)&&(y+=180),{x:o,y:p,m:{x:q,y:r},n:{x:s,y:t},start:{x:u,y:v},end:{x:w,y:x},alpha:y}},b.bezierBBox=function(a,c,d,e,f,g,h,i){b.is(a,"array")||(a=[a,c,d,e,f,g,h,i]);var j=Ha.apply(null,a);return{x:j.min.x,y:j.min.y,x2:j.max.x,y2:j.max.y,width:j.max.x-j.min.x,height:j.max.y-j.min.y}},b.isPointInsideBBox=function(a,b,c){return b>=a.x&&b<=a.x2&&c>=a.y&&c<=a.y2},b.isBBoxIntersect=function(a,c){var d=b.isPointInsideBBox;return d(c,a.x,a.y)||d(c,a.x2,a.y)||d(c,a.x,a.y2)||d(c,a.x2,a.y2)||d(a,c.x,c.y)||d(a,c.x2,c.y)||d(a,c.x,c.y2)||d(a,c.x2,c.y2)||(a.xc.x||c.xa.x)&&(a.yc.y||c.ya.y)},b.pathIntersection=function(a,b){return m(a,b)},b.pathIntersectionNumber=function(a,b){return m(a,b,1)},b.isPointInsidePath=function(a,c,d){var e=b.pathBBox(a);return b.isPointInsideBBox(e,c,d)&&m(a,[["M",c,d],["H",e.x2+10]],1)%2==1},b._removedFactory=function(b){return function(){a("raphael.log",null,"Raphaël: you are calling to method “"+b+"” of removed object",b)}};var za=b.pathBBox=function(a){var b=ya(a);if(b.bbox) -return c(b.bbox);if(!a) -return{x:0,y:0,width:0,height:0,x2:0,y2:0};a=Ia(a);for(var d,e=0,f=0,g=[],h=[],i=0,j=a.length;j>i;i++) -if(d=a[i],"M"==d[0]) -e=d[1],f=d[2],g.push(e),h.push(f);else{var k=Ha(e,f,d[1],d[2],d[3],d[4],d[5],d[6]);g=g[D](k.min.x,k.max.x),h=h[D](k.min.y,k.max.y),e=d[5],f=d[6]} -var l=O[C](0,g),m=O[C](0,h),n=N[C](0,g),o=N[C](0,h),p=n-l,q=o-m,r={x:l,y:m,x2:n,y2:o,width:p,height:q,cx:l+p/2,cy:m+q/2};return b.bbox=c(r),r},Aa=function(a){var d=c(a);return d.toString=b._path2string,d},Ba=b._pathToRelative=function(a){var c=ya(a);if(c.rel) -return Aa(c.rel);b.is(a,U)&&b.is(a&&a[0],U)||(a=b.parsePathString(a));var d=[],e=0,f=0,g=0,h=0,i=0;"M"==a[0][0]&&(e=a[0][1],f=a[0][2],g=e,h=f,i++,d.push(["M",e,f]));for(var j=i,k=a.length;k>j;j++){var l=d[j]=[],m=a[j];if(m[0]!=L.call(m[0])) -switch(l[0]=L.call(m[0]),l[0]){case"a":l[1]=m[1],l[2]=m[2],l[3]=m[3],l[4]=m[4],l[5]=m[5],l[6]=+(m[6]-e).toFixed(3),l[7]=+(m[7]-f).toFixed(3);break;case"v":l[1]=+(m[1]-f).toFixed(3);break;case"m":g=m[1],h=m[2];default:for(var n=1,o=m.length;o>n;n++) -l[n]=+(m[n]-(n%2?e:f)).toFixed(3)} -else{l=d[j]=[],"m"==m[0]&&(g=m[1]+e,h=m[2]+f);for(var p=0,q=m.length;q>p;p++) -d[j][p]=m[p]} -var r=d[j].length;switch(d[j][0]){case"z":e=g,f=h;break;case"h":e+=+d[j][r-1];break;case"v":f+=+d[j][r-1];break;default:e+=+d[j][r-2],f+=+d[j][r-1]}} -return d.toString=b._path2string,c.rel=Aa(d),d},Ca=b._pathToAbsolute=function(a){var c=ya(a);if(c.abs) -return Aa(c.abs);if(b.is(a,U)&&b.is(a&&a[0],U)||(a=b.parsePathString(a)),!a||!a.length) -return[["M",0,0]];var d=[],e=0,f=0,h=0,i=0,j=0;"M"==a[0][0]&&(e=+a[0][1],f=+a[0][2],h=e,i=f,j++,d[0]=["M",e,f]);for(var k,l,m=3==a.length&&"M"==a[0][0]&&"R"==a[1][0].toUpperCase()&&"Z"==a[2][0].toUpperCase(),n=j,o=a.length;o>n;n++){if(d.push(k=[]),l=a[n],l[0]!=aa.call(l[0])) -switch(k[0]=aa.call(l[0]),k[0]){case"A":k[1]=l[1],k[2]=l[2],k[3]=l[3],k[4]=l[4],k[5]=l[5],k[6]=+(l[6]+e),k[7]=+(l[7]+f);break;case"V":k[1]=+l[1]+f;break;case"H":k[1]=+l[1]+e;break;case"R":for(var p=[e,f][D](l.slice(1)),q=2,r=p.length;r>q;q++) -p[q]=+p[q]+e,p[++q]=+p[q]+f;d.pop(),d=d[D](g(p,m));break;case"M":h=+l[1]+e,i=+l[2]+f;default:for(q=1,r=l.length;r>q;q++) -k[q]=+l[q]+(q%2?e:f)} -else if("R"==l[0]) -p=[e,f][D](l.slice(1)),d.pop(),d=d[D](g(p,m)),k=["R"][D](l.slice(-2));else -for(var s=0,t=l.length;t>s;s++) -k[s]=l[s];switch(k[0]){case"Z":e=h,f=i;break;case"H":e=k[1];break;case"V":f=k[1];break;case"M":h=k[k.length-2],i=k[k.length-1];default:e=k[k.length-2],f=k[k.length-1]}} -return d.toString=b._path2string,c.abs=Aa(d),d},Da=function(a,b,c,d){return[a,b,c,d,c,d]},Ea=function(a,b,c,d,e,f){var g=1/3,h=2/3;return[g*a+h*c,g*b+h*d,g*e+h*c,g*f+h*d,e,f]},Fa=function(a,b,c,d,f,g,h,i,j,k){var l,m=120*R/180,n=R/180*(+f||0),o=[],p=e(function(a,b,c){var d=a*M.cos(c)-b*M.sin(c),e=a*M.sin(c)+b*M.cos(c);return{x:d,y:e}});if(k) -y=k[0],z=k[1],w=k[2],x=k[3];else{l=p(a,b,-n),a=l.x,b=l.y,l=p(i,j,-n),i=l.x,j=l.y;var q=(M.cos(R/180*f),M.sin(R/180*f),(a-i)/2),r=(b-j)/2,s=q*q/(c*c)+r*r/(d*d);s>1&&(s=M.sqrt(s),c=s*c,d=s*d);var t=c*c,u=d*d,v=(g==h?-1:1)*M.sqrt(P((t*u-t*r*r-u*q*q)/(t*r*r+u*q*q))),w=v*c*r/d+(a+i)/2,x=v* -d*q/c+(b+j)/2,y=M.asin(((b-x)/d).toFixed(9)),z=M.asin(((j-x)/d).toFixed(9));y=w>a?R-y:y,z=w>i?R-z:z,0>y&&(y=2*R+y),0>z&&(z=2*R+z),h&&y>z&&(y-=2*R),!h&&z>y&&(z-=2*R)} -var A=z-y;if(P(A)>m){var B=z,C=i,E=j;z=y+m*(h&&z>y?1:-1),i=w+c*M.cos(z),j=x+d*M.sin(z),o=Fa(i,j,c,d,f,0,h,C,E,[z,B,w,x])} -A=z-y;var F=M.cos(y),G=M.sin(y),H=M.cos(z),J=M.sin(z),K=M.tan(A/4),L=4/3*c*K,N=4/3*d*K,O=[a,b],Q=[a+L*G,b-N*F],S=[i+L*J,j-N*H],T=[i,j];if(Q[0]=2*O[0]-Q[0],Q[1]=2*O[1]-Q[1],k) -return[Q,S,T][D](o);o=[Q,S,T][D](o).join()[I](",");for(var U=[],V=0,W=o.length;W>V;V++) -U[V]=V%2?p(o[V-1],o[V],n).y:p(o[V],o[V+1],n).x;return U},Ga=function(a,b,c,d,e,f,g,h,i){var j=1-i;return{x:Q(j,3)*a+3*Q(j,2)*i*c+3*j*i*i*e+Q(i,3)*g,y:Q(j,3)*b+3*Q(j,2)*i*d+3*j*i*i*f+Q(i,3)*h}},Ha=e(function(a,b,c,d,e,f,g,h){var i,j=e-2*c+a-(g-2*e+c),k=2*(c-a)-2*(e-c),l=a-c,m=(-k+M.sqrt(k*k-4*j*l))/2/j,n=(-k-M.sqrt(k*k-4*j*l))/2/j,o=[b,h],p=[a,g];return P(m)>"1e12"&&(m=.5),P(n)>"1e12"&&(n=.5),m>0&&1>m&&(i=Ga(a,b,c,d,e,f,g,h,m),p.push(i.x),o.push(i.y)),n>0&&1>n&&(i=Ga(a,b,c,d,e,f,g,h,n),p.push(i.x),o.push(i.y)),j=f-2*d+b-(h-2*f+d),k=2*(d-b)-2*(f-d),l=b-d,m=(-k+M.sqrt(k*k-4*j*l))/2/j,n=(-k-M.sqrt(k*k-4*j*l))/2/j,P(m)>"1e12"&&(m=.5),P(n)>"1e12"&&(n=.5),m>0&&1>m&&(i=Ga(a,b,c,d,e,f,g,h,m),p.push(i.x),o.push(i.y)),n>0&&1>n&&(i=Ga(a,b,c,d,e,f,g,h,n),p.push(i.x),o.push(i.y)),{min:{x:O[C](0,p),y:O[C](0,o)},max:{x:N[C](0,p),y:N[C](0,o)}}}),Ia=b._path2curve=e(function(a,b){var c=!b&&ya(a);if(!b&&c.curve) -return Aa(c.curve);for(var d=Ca(a),e=b&&Ca(b),f={x:0,y:0,bx:0,by:0,X:0,Y:0,qx:null,qy:null},g={x:0,y:0,bx:0,by:0,X:0,Y:0,qx:null,qy:null},h=(function(a,b,c){var d,e,f={T:1,Q:1};if(!a) -return["C",b.x,b.y,b.x,b.y,b.x,b.y];switch(!(a[0]in f)&&(b.qx=b.qy=null),a[0]){case"M":b.X=a[1],b.Y=a[2];break;case"A":a=["C"][D](Fa[C](0,[b.x,b.y][D](a.slice(1))));break;case"S":"C"==c||"S"==c?(d=2*b.x-b.bx,e=2*b.y-b.by):(d=b.x,e=b.y),a=["C",d,e][D](a.slice(1));break;case"T":"Q"==c||"T"==c?(b.qx=2*b.x-b.qx,b.qy=2*b.y-b.qy):(b.qx=b.x,b.qy=b.y),a=["C"][D](Ea(b.x,b.y,b.qx,b.qy,a[1],a[2]));break;case"Q":b.qx=a[1],b.qy=a[2],a=["C"][D](Ea(b.x,b.y,a[1],a[2],a[3],a[4]));break;case"L":a=["C"][D](Da(b.x,b.y,a[1],a[2]));break;case"H":a=["C"][D](Da(b.x,b.y,a[1],b.y));break;case"V":a=["C"][D](Da(b.x,b.y,b.x,a[1]));break;case"Z":a=["C"][D](Da(b.x,b.y,b.X,b.Y))} -return a}),i=function(a,b){if(a[b].length>7){a[b].shift();for(var c=a[b];c.length;) -k[b]="A",e&&(l[b]="A"),a.splice(b++,0,["C"][D](c.splice(0,6)));a.splice(b,1),p=N(d.length,e&&e.length||0)}},j=function(a,b,c,f,g){a&&b&&"M"==a[g][0]&&"M"!=b[g][0]&&(b.splice(g,0,["M",f.x,f.y]),c.bx=0,c.by=0,c.x=a[g][1],c.y=a[g][2],p=N(d.length,e&&e.length||0))},k=[],l=[],m="",n="",o=0,p=N(d.length,e&&e.length||0);p>o;o++){d[o]&&(m=d[o][0]),"C"!=m&&(k[o]=m,o&&(n=k[o-1])),d[o]=h(d[o],f,n),"A"!=k[o]&&"C"==m&&(k[o]="C"),i(d,o),e&&(e[o]&&(m=e[o][0]),"C"!=m&&(l[o]=m,o&&(n=l[o-1])),e[o]=h(e[o],g,n),"A"!=l[o]&&"C"==m&&(l[o]="C"),i(e,o)),j(d,e,f,g,o),j(e,d,g,f,o);var q=d[o],r=e&&e[o],s=q.length,t=e&&r.length;f.x=q[s-2],f.y=q[s-1],f.bx=$(q[s-4])||f.x,f.by=$(q[s-3])||f.y,g.bx=e&&($(r[t-4])||g.x),g.by=e&&($(r[t-3])||g.y),g.x=e&&r[t-2],g.y=e&&r[t-1]} -return e||(c.curve=Aa(d)),e?[d,e]:d},null,Aa),Ja=(b._parseDots=e(function(a){for(var c=[],d=0,e=a.length;e>d;d++){var f={},g=a[d].match(/^([^:]*):?([\d\.]*)/);if(f.color=b.getRGB(g[1]),f.color.error) -return null;f.opacity=f.color.opacity,f.color=f.color.hex,g[2]&&(f.offset=g[2]+"%"),c.push(f)} -for(d=1,e=c.length-1;e>d;d++) -if(!c[d].offset){for(var h=$(c[d-1].offset||0),i=0,j=d+1;e>j;j++) -if(c[j].offset){i=c[j].offset;break} -i||(i=100,j=e),i=$(i);for(var k=(i-h)/(j-d+1);j>d;d++) -h+=k,c[d].offset=h+"%"} -return c}),b._tear=function(a,b){a==b.top&&(b.top=a.prev),a==b.bottom&&(b.bottom=a.next),a.next&&(a.next.prev=a.prev),a.prev&&(a.prev.next=a.next)}),Ka=(b._tofront=function(a,b){b.top!==a&&(Ja(a,b),a.next=null,a.prev=b.top,b.top.next=a,b.top=a)},b._toback=function(a,b){b.bottom!==a&&(Ja(a,b),a.next=b.bottom,a.prev=null,b.bottom.prev=a,b.bottom=a)},b._insertafter=function(a,b,c){Ja(a,c),b==c.top&&(c.top=a),b.next&&(b.next.prev=a),a.next=b.next,a.prev=b,b.next=a},b._insertbefore=function(a,b,c){Ja(a,c),b==c.bottom&&(c.bottom=a),b.prev&&(b.prev.next=a),a.prev=b.prev,b.prev=a,a.next=b},b.toMatrix=function(a,b){var c=za(a),d={_:{transform:F},getBBox:function(){return c}};return La(d,b),d.matrix}),La=(b.transformPath=function(a,b){return pa(a,Ka(a,b))},b._extractTransform=function(a,c){if(null==c) -return a._.transform;c=H(c).replace(/\.{3}|\u2026/g,a._.transform||F);var d=b.parseTransformString(c),e=0,f=0,g=0,h=1,i=1,j=a._,k=new n;if(j.transform=d||[],d) -for(var l=0,m=d.length;m>l;l++){var o,p,q,r,s,t=d[l],u=t.length,v=H(t[0]).toLowerCase(),w=t[0]!=v,x=w?k.invert():0;"t"==v&&3==u?w?(o=x.x(0,0),p=x.y(0,0),q=x.x(t[1],t[2]),r=x.y(t[1],t[2]),k.translate(q-o,r-p)):k.translate(t[1],t[2]):"r"==v?2==u?(s=s||a.getBBox(1),k.rotate(t[1],s.x+s.width/2,s.y+s.height/2),e+=t[1]):4==u&&(w?(q=x.x(t[2],t[3]),r=x.y(t[2],t[3]),k.rotate(t[1],q,r)):k.rotate(t[1],t[2],t[3]),e+=t[1]):"s"==v?2==u||3==u?(s=s||a.getBBox(1),k.scale(t[1],t[u-1],s.x+s.width/2,s.y+s.height/2),h*=t[1],i*=t[u-1]):5==u&&(w?(q=x.x(t[3],t[4]),r=x.y(t[3],t[4]),k.scale(t[1],t[2],q,r)):k.scale(t[1],t[2],t[3],t[4]),h*=t[1],i*=t[2]):"m"==v&&7==u&&k.add(t[1],t[2],t[3],t[4],t[5],t[6]),j.dirtyT=1,a.matrix=k} -a.matrix=k,j.sx=h,j.sy=i,j.deg=e,j.dx=f=k.e,j.dy=g=k.f,1==h&&1==i&&!e&&j.bbox?(j.bbox.x+=+f,j.bbox.y+=+g):j.dirtyT=1}),Ma=function(a){var b=a[0];switch(b.toLowerCase()){case"t":return[b,0,0];case"m":return[b,1,0,0,1,0,0];case"r":return 4==a.length?[b,0,a[2],a[3]]:[b,0];case"s":return 5==a.length?[b,1,1,a[3],a[4]]:3==a.length?[b,1,1]:[b,1]}},Na=b._equaliseTransform=function(a,c){c=H(c).replace(/\.{3}|\u2026/g,a),a=b.parseTransformString(a)||[],c=b.parseTransformString(c)||[];for(var d,e,f,g,h=N(a.length,c.length),i=[],j=[],k=0;h>k;k++){if(f=a[k]||Ma(c[k]),g=c[k]||Ma(f),f[0]!=g[0]||"r"==f[0].toLowerCase()&&(f[2]!=g[2]||f[3]!=g[3])||"s"==f[0].toLowerCase()&&(f[3]!=g[3]||f[4]!=g[4])) -return;for(i[k]=[],j[k]=[],d=0,e=N(f.length,g.length);e>d;d++) -d in f&&(i[k][d]=f[d]),d in g&&(j[k][d]=g[d])} -return{from:i,to:j}};b._getContainer=function(a,c,d,e){var f;return f=null!=e||b.is(a,"object")?a:z.doc.getElementById(a),null!=f?f.tagName?null==c?{container:f,width:f.style.pixelWidth||f.offsetWidth,height:f.style.pixelHeight||f.offsetHeight}:{container:f,width:c,height:d}:{container:1,x:a,y:c,width:d,height:e}:void 0},b.pathToRelative=Ba,b._engine={},b.path2curve=Ia,b.matrix=function(a,b,c,d,e,f){return new n(a,b,c,d,e,f)},function(a){function c(a){return a[0]*a[0]+a[1]*a[1]} -function d(a){var b=M.sqrt(c(a));a[0]&&(a[0]/=b),a[1]&&(a[1]/=b)} -a.add=function(a,b,c,d,e,f){var g,h,i,j,k=[[],[],[]],l=[[this.a,this.c,this.e],[this.b,this.d,this.f],[0,0,1]],m=[[a,c,e],[b,d,f],[0,0,1]];for(a&&a instanceof n&&(m=[[a.a,a.c,a.e],[a.b,a.d,a.f],[0,0,1]]),g=0;3>g;g++) -for(h=0;3>h;h++){for(j=0,i=0;3>i;i++) -j+=l[g][i]*m[i][h];k[g][h]=j} -this.a=k[0][0],this.b=k[1][0],this.c=k[0][1],this.d=k[1][1],this.e=k[0][2],this.f=k[1][2]},a.invert=function(){var a=this,b=a.a*a.d-a.b*a.c;return new n(a.d/b,-a.b/b,-a.c/b,a.a/b,(a.c*a.f-a.d*a.e)/b,(a.b*a.e-a.a*a.f)/b)},a.clone=function(){return new n(this.a,this.b,this.c,this.d,this.e,this.f)},a.translate=function(a,b){this.add(1,0,0,1,a,b)},a.scale=function(a,b,c,d){null==b&&(b=a),(c||d)&&this.add(1,0,0,1,c,d),this.add(a,0,0,b,0,0),(c||d)&&this.add(1,0,0,1,-c,-d)},a.rotate=function(a,c,d){a=b.rad(a),c=c||0,d=d||0;var e=+M.cos(a).toFixed(9),f=+M.sin(a).toFixed(9);this.add(e,f,-f,e,c,d),this.add(1,0,0,1,-c,-d)},a.x=function(a,b){return a*this.a+b*this.c+this.e},a.y=function(a,b){return a*this.b+b*this.d+this.f},a.get=function(a){return+this[H.fromCharCode(97+a)].toFixed(4)},a.toString=function(){return b.svg?"matrix("+[this.get(0),this.get(1),this.get(2),this.get(3),this.get(4),this.get(5)].join()+")":[this.get(0),this.get(2),this.get(1),this.get(3),0,0].join()},a.toFilter=function(){return"progid:DXImageTransform.Microsoft.Matrix(M11="+this.get(0)+", M12="+this.get(2)+", M21="+this.get(1)+", M22="+this.get(3)+", Dx="+this.get(4)+", Dy="+this.get(5)+", sizingmethod='auto expand')"},a.offset=function(){return[this.e.toFixed(4),this.f.toFixed(4)]},a.split=function(){var a={};a.dx=this.e,a.dy=this.f;var e=[[this.a,this.c],[this.b,this.d]];a.scalex=M.sqrt(c(e[0])),d(e[0]),a.shear=e[0][0]*e[1][0]+e[0][1]*e[1][1],e[1]=[e[1][0]-e[0][0]*a.shear,e[1][1]-e[0][1]*a.shear],a.scaley=M.sqrt(c(e[1])),d(e[1]),a.shear/=a.scaley;var f=-e[0][1],g=e[1][1];return 0>g?(a.rotate=b.deg(M.acos(g)),0>f&&(a.rotate=360-a.rotate)):a.rotate=b.deg(M.asin(f)),a.isSimple=!(+a.shear.toFixed(9)||a.scalex.toFixed(9)!=a.scaley.toFixed(9)&&a.rotate),a.isSuperSimple=!+a.shear.toFixed(9)&&a.scalex.toFixed(9)==a.scaley.toFixed(9)&&!a.rotate,a.noRotation=!+a.shear.toFixed(9)&&!a.rotate,a},a.toTransformString=function(a){var b=a||this[I]();return b.isSimple?(b.scalex=+b.scalex.toFixed(4),b.scaley=+b.scaley.toFixed(4),b.rotate=+b.rotate.toFixed(4),(b.dx||b.dy?"t"+[b.dx,b.dy]:F)+(1!=b.scalex||1!=b.scaley?"s"+[b.scalex,b.scaley,0,0]:F)+(b.rotate?"r"+[b.rotate,0,0]:F)):"m"+[this.get(0),this.get(1),this.get(2),this.get(3),this.get(4),this.get(5)]}} -(n.prototype);for(var Oa=function(){this.returnValue=!1},Pa=function(){return this.originalEvent.preventDefault()},Qa=function(){this.cancelBubble=!0},Ra=function(){return this.originalEvent.stopPropagation()},Sa=function(a){var b=z.doc.documentElement.scrollTop||z.doc.body.scrollTop,c=z.doc.documentElement.scrollLeft||z.doc.body.scrollLeft;return{x:a.clientX+c,y:a.clientY+b}},Ta=function(){return z.doc.addEventListener?function(a,b,c,d){var e=function(a){var b=Sa(a);return c.call(d,a,b.x,b.y)};if(a.addEventListener(b,e,!1),E&&K[b]){var f=function(b){for(var e=Sa(b),f=b,g=0,h=b.targetTouches&&b.targetTouches.length;h>g;g++) -if(b.targetTouches[g].target==a){b=b.targetTouches[g],b.originalEvent=f,b.preventDefault=Pa,b.stopPropagation=Ra;break} -return c.call(d,b,e.x,e.y)};a.addEventListener(K[b],f,!1)} -return function(){return a.removeEventListener(b,e,!1),E&&K[b]&&a.removeEventListener(K[b],f,!1),!0}}:z.doc.attachEvent?function(a,b,c,d){var e=function(a){a=a||z.win.event;var b=z.doc.documentElement.scrollTop||z.doc.body.scrollTop,e=z.doc.documentElement.scrollLeft||z.doc.body.scrollLeft,f=a.clientX+e,g=a.clientY+b;return a.preventDefault=a.preventDefault||Oa,a.stopPropagation=a.stopPropagation||Qa,c.call(d,a,f,g)};a.attachEvent("on"+b,e);var f=function(){return a.detachEvent("on"+b,e),!0};return f}:void 0} -(),Ua=[],Va=function(b){for(var c,d=b.clientX,e=b.clientY,f=z.doc.documentElement.scrollTop||z.doc.body.scrollTop,g=z.doc.documentElement.scrollLeft||z.doc.body.scrollLeft,h=Ua.length;h--;){if(c=Ua[h],E&&b.touches){for(var i,j=b.touches.length;j--;) -if(i=b.touches[j],i.identifier==c.el._drag.id){d=i.clientX,e=i.clientY,(b.originalEvent?b.originalEvent:b).preventDefault();break}}else -b.preventDefault();var k,l=c.el.node,m=l.nextSibling,n=l.parentNode,o=l.style.display;z.win.opera&&n.removeChild(l),l.style.display="none",k=c.el.paper.getElementByPoint(d,e),l.style.display=o,z.win.opera&&(m?n.insertBefore(l,m):n.appendChild(l)),k&&a("raphael.drag.over."+c.el.id,c.el,k),d+=g,e+=f,a("raphael.drag.move."+c.el.id,c.move_scope||c.el,d-c.el._drag.x,e-c.el._drag.y,d,e,b)}},Wa=function(c){b.unmousemove(Va).unmouseup(Wa);for(var d,e=Ua.length;e--;) -d=Ua[e],d.el._drag={},a("raphael.drag.end."+d.el.id,d.end_scope||d.start_scope||d.move_scope||d.el,c);Ua=[]},Xa=b.el={},Ya=J.length;Ya--;) -!function(a){b[a]=Xa[a]=function(c,d){return b.is(c,"function")&&(this.events=this.events||[],this.events.push({name:a,f:c,unbind:Ta(this.shape||this.node||z.doc,a,c,d||this)})),this},b["un"+a]=Xa["un"+a]=function(c){for(var d=this.events||[],e=d.length;e--;) -d[e].name!=a||!b.is(c,"undefined")&&d[e].f!=c||(d[e].unbind(),d.splice(e,1),!d.length&&delete this.events);return this}} -(J[Ya]);Xa.data=function(c,d){var e=ja[this.id]=ja[this.id]||{};if(0==arguments.length) -return e;if(1==arguments.length){if(b.is(c,"object")){for(var f in c) -c[y](f)&&this.data(f,c[f]);return this} -return a("raphael.data.get."+this.id,this,e[c],c),e[c]} -return e[c]=d,a("raphael.data.set."+this.id,this,d,c),this},Xa.removeData=function(a){return null==a?ja[this.id]={}:ja[this.id]&&delete ja[this.id][a],this},Xa.getData=function(){return c(ja[this.id]||{})},Xa.hover=function(a,b,c,d){return this.mouseover(a,c).mouseout(b,d||c)},Xa.unhover=function(a,b){return this.unmouseover(a).unmouseout(b)};var Za=[];Xa.drag=function(c,d,e,f,g,h){function i(i){(i.originalEvent||i).preventDefault();var j=i.clientX,k=i.clientY,l=z.doc.documentElement.scrollTop||z.doc.body.scrollTop,m=z.doc.documentElement.scrollLeft||z.doc.body.scrollLeft;if(this._drag.id=i.identifier,E&&i.touches) -for(var n,o=i.touches.length;o--;) -if(n=i.touches[o],this._drag.id=n.identifier,n.identifier==this._drag.id){j=n.clientX,k=n.clientY;break} -this._drag.x=j+m,this._drag.y=k+l,!Ua.length&&b.mousemove(Va).mouseup(Wa),Ua.push({el:this,move_scope:f,start_scope:g,end_scope:h}),d&&a.on("raphael.drag.start."+this.id,d),c&&a.on("raphael.drag.move."+this.id,c),e&&a.on("raphael.drag.end."+this.id,e),a("raphael.drag.start."+this.id,g||f||this,i.clientX+m,i.clientY+l,i)} -return this._drag={},Za.push({el:this,start:i}),this.mousedown(i),this},Xa.onDragOver=function(b){b?a.on("raphael.drag.over."+this.id,b):a.unbind("raphael.drag.over."+this.id)},Xa.undrag=function(){for(var c=Za.length;c--;) -Za[c].el==this&&(this.unmousedown(Za[c].start),Za.splice(c,1),a.unbind("raphael.drag.*."+this.id));!Za.length&&b.unmousemove(Va).unmouseup(Wa),Ua=[]},u.circle=function(a,c,d){var e=b._engine.circle(this,a||0,c||0,d||0);return this.__set__&&this.__set__.push(e),e},u.rect=function(a,c,d,e,f){var g=b._engine.rect(this,a||0,c||0,d||0,e||0,f||0);return this.__set__&&this.__set__.push(g),g},u.ellipse=function(a,c,d,e){var f=b._engine.ellipse(this,a||0,c||0,d||0,e||0);return this.__set__&&this.__set__.push(f),f},u.path=function(a){a&&!b.is(a,T)&&!b.is(a[0],U)&&(a+=F);var c=b._engine.path(b.format[C](b,arguments),this);return this.__set__&&this.__set__.push(c),c},u.image=function(a,c,d,e,f){var g=b._engine.image(this,a||"about:blank",c||0,d||0,e||0,f||0);return this.__set__&&this.__set__.push(g),g},u.text=function(a,c,d){var e=b._engine.text(this,a||0,c||0,H(d));return this.__set__&&this.__set__.push(e),e},u.set=function(a){!b.is(a,"array")&&(a=Array.prototype.splice.call(arguments,0,arguments.length));var c=new jb(a);return this.__set__&&this.__set__.push(c),c.paper=this,c.type="set",c},u.setStart=function(a){this.__set__=a||this.set()},u.setFinish=function(a){var b=this.__set__;return delete this.__set__,b},u.getSize=function(){var a=this.canvas.parentNode;return{width:a.offsetWidth,height:a.offsetHeight}},u.setSize=function(a,c){return b._engine.setSize.call(this,a,c)},u.setViewBox=function(a,c,d,e,f){return b._engine.setViewBox.call(this,a,c,d,e,f)},u.top=u.bottom=null,u.raphael=b;var $a=function(a){var b=a.getBoundingClientRect(),c=a.ownerDocument,d=c.body,e=c.documentElement,f=e.clientTop||d.clientTop||0,g=e.clientLeft||d.clientLeft||0,h=b.top+(z.win.pageYOffset||e.scrollTop||d.scrollTop)-f,i=b.left+(z.win.pageXOffset||e.scrollLeft||d.scrollLeft)-g;return{y:h,x:i}};u.getElementByPoint=function(a,b){var c=this,d=c.canvas,e=z.doc.elementFromPoint(a,b);if(z.win.opera&&"svg"==e.tagName){var f=$a(d),g=d.createSVGRect();g.x=a-f.x,g.y=b-f.y,g.width=g.height=1;var h=d.getIntersectionList(g,null);h.length&&(e=h[h.length-1])} -if(!e) -return null;for(;e.parentNode&&e!=d.parentNode&&!e.raphael;) -e=e.parentNode;return e==c.canvas.parentNode&&(e=d),e=e&&e.raphael?c.getById(e.raphaelid):null},u.getElementsByBBox=function(a){var c=this.set();return this.forEach(function(d){b.isBBoxIntersect(d.getBBox(),a)&&c.push(d)}),c},u.getById=function(a){for(var b=this.bottom;b;){if(b.id==a) -return b;b=b.next} -return null},u.forEach=function(a,b){for(var c=this.bottom;c;){if(a.call(b,c)===!1) -return this;c=c.next} -return this},u.getElementsByPoint=function(a,b){var c=this.set();return this.forEach(function(d){d.isPointInside(a,b)&&c.push(d)}),c},Xa.isPointInside=function(a,c){var d=this.realPath=oa[this.type](this);return this.attr("transform")&&this.attr("transform").length&&(d=b.transformPath(d,this.attr("transform"))),b.isPointInsidePath(d,a,c)},Xa.getBBox=function(a){if(this.removed) -return{};var b=this._;return a?((b.dirty||!b.bboxwt)&&(this.realPath=oa[this.type](this),b.bboxwt=za(this.realPath),b.bboxwt.toString=o,b.dirty=0),b.bboxwt):((b.dirty||b.dirtyT||!b.bbox)&&((b.dirty||!this.realPath)&&(b.bboxwt=0,this.realPath=oa[this.type](this)),b.bbox=za(pa(this.realPath,this.matrix)),b.bbox.toString=o,b.dirty=b.dirtyT=0),b.bbox)},Xa.clone=function(){if(this.removed) -return null;var a=this.paper[this.type]().attr(this.attr());return this.__set__&&this.__set__.push(a),a},Xa.glow=function(a){if("text"==this.type) -return null;a=a||{};var b={width:(a.width||10)+(+this.attr("stroke-width")||1),fill:a.fill||!1,opacity:null==a.opacity?.5:a.opacity,offsetx:a.offsetx||0,offsety:a.offsety||0,color:a.color||"#000"},c=b.width/2,d=this.paper,e=d.set(),f=this.realPath||oa[this.type](this);f=this.matrix?pa(f,this.matrix):f;for(var g=1;c+1>g;g++) -e.push(d.path(f).attr({stroke:b.color,fill:b.fill?b.color:"none","stroke-linejoin":"round","stroke-linecap":"round","stroke-width":+(b.width/c*g).toFixed(3),opacity:+(b.opacity/c).toFixed(3)}));return e.insertBefore(this).translate(b.offsetx,b.offsety)};var _a=function(a,c,d,e,f,g,h,k,l){return null==l?i(a,c,d,e,f,g,h,k):b.findDotsAtSegment(a,c,d,e,f,g,h,k,j(a,c,d,e,f,g,h,k,l))},ab=function(a,c){return function(d,e,f){d=Ia(d);for(var g,h,i,j,k,l="",m={},n=0,o=0,p=d.length;p>o;o++){if(i=d[o],"M"==i[0]) -g=+i[1],h=+i[2];else{if(j=_a(g,h,i[1],i[2],i[3],i[4],i[5],i[6]),n+j>e){if(c&&!m.start){if(k=_a(g,h,i[1],i[2],i[3],i[4],i[5],i[6],e-n),l+=["C"+k.start.x,k.start.y,k.m.x,k.m.y,k.x,k.y],f) -return l;m.start=l,l=["M"+k.x,k.y+"C"+k.n.x,k.n.y,k.end.x,k.end.y,i[5],i[6]].join(),n+=j,g=+i[5],h=+i[6];continue} -if(!a&&!c) -return k=_a(g,h,i[1],i[2],i[3],i[4],i[5],i[6],e-n),{x:k.x,y:k.y,alpha:k.alpha}} -n+=j,g=+i[5],h=+i[6]} -l+=i.shift()+i} -return m.end=l,k=a?n:c?m:b.findDotsAtSegment(g,h,i[0],i[1],i[2],i[3],i[4],i[5],1),k.alpha&&(k={x:k.x,y:k.y,alpha:k.alpha}),k}},bb=ab(1),cb=ab(),db=ab(0,1);b.getTotalLength=bb,b.getPointAtLength=cb,b.getSubpath=function(a,b,c){if(this.getTotalLength(a)-c<1e-6) -return db(a,b).end;var d=db(a,c,1);return b?db(d,b).end:d},Xa.getTotalLength=function(){var a=this.getPath();if(a) -return this.node.getTotalLength?this.node.getTotalLength():bb(a)},Xa.getPointAtLength=function(a){var b=this.getPath();if(b) -return cb(b,a)},Xa.getPath=function(){var a,c=b._getPath[this.type];if("text"!=this.type&&"set"!=this.type) -return c&&(a=c(this)),a},Xa.getSubpath=function(a,c){var d=this.getPath();if(d) -return b.getSubpath(d,a,c)};var eb=b.easing_formulas={linear:function(a){return a},"<":function(a){return Q(a,1.7)},">":function(a){return Q(a,.48)},"<>":function(a){var b=.48-a/1.04,c=M.sqrt(.1734+b*b),d=c-b,e=Q(P(d),1/3)*(0>d?-1:1),f=-c-b,g=Q(P(f),1/3)*(0>f?-1:1),h=e+g+.5;return 3*(1-h)*h*h+h*h*h},backIn:function(a){var b=1.70158;return a*a*((b+1)*a-b)},backOut:function(a){a-=1;var b=1.70158;return a*a*((b+1)*a+b)+1},elastic:function(a){return a==!!a?a:Q(2,-10*a)*M.sin(2*(a-.075)*R/.3)+1},bounce:function(a){var b,c=7.5625,d=2.75;return 1/d>a?b=c*a*a:2/d>a?(a-=1.5/d,b=c*a*a+.75):2.5/d>a?(a-=2.25/d,b=c*a*a+.9375):(a-=2.625/d,b=c*a*a+.984375),b}};eb.easeIn=eb["ease-in"]=eb["<"],eb.easeOut=eb["ease-out"]=eb[">"],eb.easeInOut=eb["ease-in-out"]=eb["<>"],eb["back-in"]=eb.backIn,eb["back-out"]=eb.backOut;var fb=[],gb=window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(a){setTimeout(a,16)},hb=function(){for(var c=+new Date,d=0;dh)) -if(i>h){var q=j(h/i);for(var s in k) -if(k[y](s)){switch(ca[s]){case S:f=+k[s]+q*i*l[s];break;case"colour":f="rgb("+[ib(Z(k[s].r+q*i*l[s].r)),ib(Z(k[s].g+q*i*l[s].g)),ib(Z(k[s].b+q*i*l[s].b))].join(",")+")";break;case"path":f=[];for(var t=0,u=k[s].length;u>t;t++){f[t]=[k[s][t][0]];for(var v=1,w=k[s][t].length;w>v;v++) -f[t][v]=+k[s][t][v]+q*i*l[s][t][v];f[t]=f[t].join(G)} -f=f.join(G);break;case"transform":if(l[s].real) -for(f=[],t=0,u=k[s].length;u>t;t++) -for(f[t]=[k[s][t][0]],v=1,w=k[s][t].length;w>v;v++) -f[t][v]=k[s][t][v]+q*i*l[s][t][v];else{var x=function(a){return+k[s][a]+q*i*l[s][a]};f=[["m",x(0),x(1),x(2),x(3),x(4),x(5)]]} -break;case"csv":if("clip-rect"==s) -for(f=[],t=4;t--;) -f[t]=+k[s][t]+q*i*l[s][t];break;default:var z=[][D](k[s]);for(f=[],t=n.paper.customAttributes[s].length;t--;) -f[t]=+z[t]+q*i*l[s][t]} -o[s]=f} -n.attr(o),function(b,c,d){setTimeout(function(){a("raphael.anim.frame."+b,c,d)})} -(n.id,n,e.anim)}else{if(function(c,d,e){setTimeout(function(){a("raphael.anim.frame."+d.id,d,e),a("raphael.anim.finish."+d.id,d,e),b.is(c,"function")&&c.call(d)})} -(e.callback,n,e.anim),n.attr(m),fb.splice(d--,1),e.repeat>1&&!e.next){for(g in m) -m[y](g)&&(p[g]=e.totalOrigin[g]);e.el.attr(p),r(e.anim,e.el,e.anim.percents[0],null,e.totalOrigin,e.repeat-1)} -e.next&&!e.stop&&r(e.anim,e.el,e.next,null,e.totalOrigin,e.repeat)}}} -fb.length&&gb(hb)},ib=function(a){return a>255?255:0>a?0:a};Xa.animateWith=function(a,c,d,e,f,g){var h=this;if(h.removed) -return g&&g.call(h),h;var i=d instanceof q?d:b.animation(d,e,f,g);r(i,h,i.percents[0],null,h.attr());for(var j=0,k=fb.length;k>j;j++) -if(fb[j].anim==c&&fb[j].el==a){fb[k-1].start=fb[j].start;break} -return h},Xa.onAnimation=function(b){return b?a.on("raphael.anim.frame."+this.id,b):a.unbind("raphael.anim.frame."+this.id),this},q.prototype.delay=function(a){var b=new q(this.anim,this.ms);return b.times=this.times,b.del=+a||0,b},q.prototype.repeat=function(a){var b=new q(this.anim,this.ms);return b.del=this.del,b.times=M.floor(N(a,0))||1,b},b.animation=function(a,c,d,e){if(a instanceof q) -return a;(b.is(d,"function")||!d)&&(e=e||d||null,d=null),a=Object(a),c=+c||0;var f,g,h={};for(g in a) -a[y](g)&&$(g)!=g&&$(g)+"%"!=g&&(f=!0,h[g]=a[g]);if(f) -return d&&(h.easing=d),e&&(h.callback=e),new q({100:h},c);if(e){var i=0;for(var j in a){var k=_(j);a[y](j)&&k>i&&(i=k)} -i+="%",!a[i].callback&&(a[i].callback=e)} -return new q(a,c)},Xa.animate=function(a,c,d,e){var f=this;if(f.removed) -return e&&e.call(f),f;var g=a instanceof q?a:b.animation(a,c,d,e);return r(g,f,g.percents[0],null,f.attr()),f},Xa.setTime=function(a,b){return a&&null!=b&&this.status(a,O(b,a.ms)/a.ms),this},Xa.status=function(a,b){var c,d,e=[],f=0;if(null!=b) -return r(a,this,-1,O(b,1)),this;for(c=fb.length;c>f;f++) -if(d=fb[f],d.el.id==this.id&&(!a||d.anim==a)){if(a) -return d.status;e.push({anim:d.anim,status:d.status})} -return a?0:e},Xa.pause=function(b){for(var c=0;cb;b++) -!a[b]||a[b].constructor!=Xa.constructor&&a[b].constructor!=jb||(this[this.items.length]=this.items[this.items.length]=a[b],this.length++)},kb=jb.prototype;kb.push=function(){for(var a,b,c=0,d=arguments.length;d>c;c++) -a=arguments[c],!a||a.constructor!=Xa.constructor&&a.constructor!=jb||(b=this.items.length,this[b]=this.items[b]=a,this.length++);return this},kb.pop=function(){return this.length&&delete this[this.length--],this.items.pop()},kb.forEach=function(a,b){for(var c=0,d=this.items.length;d>c;c++) -if(a.call(b,this.items[c],c)===!1) -return this;return this};for(var lb in Xa) -Xa[y](lb)&&(kb[lb]=function(a){return function(){var b=arguments;return this.forEach(function(c){c[a][C](c,b)})}} -(lb));return kb.attr=function(a,c){if(a&&b.is(a,U)&&b.is(a[0],"object")) -for(var d=0,e=a.length;e>d;d++) -this.items[d].attr(a[d]);else -for(var f=0,g=this.items.length;g>f;f++) -this.items[f].attr(a,c);return this},kb.clear=function(){for(;this.length;) -this.pop()},kb.splice=function(a,b,c){a=0>a?N(this.length+a,0):a,b=N(0,O(this.length-a,b));var d,e=[],f=[],g=[];for(d=2;dd;d++) -f.push(this[a+d]);for(;dd?g[d]:e[d-h];for(d=this.items.length=this.length-=b-h;this[d];) -delete this[d++];return new jb(f)},kb.exclude=function(a){for(var b=0,c=this.length;c>b;b++) -if(this[b]==a) -return this.splice(b,1),!0},kb.animate=function(a,c,d,e){(b.is(d,"function")||!d)&&(e=d||null);var f,g,h=this.items.length,i=h,j=this;if(!h) -return this;e&&(g=function(){!--h&&e.call(j)}),d=b.is(d,T)?d:g;var k=b.animation(a,c,d,g);for(f=this.items[--i].animate(k);i--;) -this.items[i]&&!this.items[i].removed&&this.items[i].animateWith(f,k,k),this.items[i]&&!this.items[i].removed||h--;return this},kb.insertAfter=function(a){for(var b=this.items.length;b--;) -this.items[b].insertAfter(a);return this},kb.getBBox=function(){for(var a=[],b=[],c=[],d=[],e=this.items.length;e--;) -if(!this.items[e].removed){var f=this.items[e].getBBox();a.push(f.x),b.push(f.y),c.push(f.x+f.width),d.push(f.y+f.height)} -return a=O[C](0,a),b=O[C](0,b),c=N[C](0,c),d=N[C](0,d),{x:a,y:b,x2:c,y2:d,width:c-a,height:d-b}},kb.clone=function(a){a=this.paper.set();for(var b=0,c=this.items.length;c>b;b++) -a.push(this.items[b].clone());return a},kb.toString=function(){return"Raphaël‘s set"},kb.glow=function(a){var b=this.paper.set();return this.forEach(function(c,d){var e=c.glow(a);null!=e&&e.forEach(function(a,c){b.push(a)})}),b},kb.isPointInside=function(a,b){var c=!1;return this.forEach(function(d){return d.isPointInside(a,b)?(c=!0,!1):void 0}),c},b.registerFont=function(a){if(!a.face) -return a;this.fonts=this.fonts||{};var b={w:a.w,face:{},glyphs:{}},c=a.face["font-family"];for(var d in a.face) -a.face[y](d)&&(b.face[d]=a.face[d]);if(this.fonts[c]?this.fonts[c].push(b):this.fonts[c]=[b],!a.svg){b.face["units-per-em"]=_(a.face["units-per-em"],10);for(var e in a.glyphs) -if(a.glyphs[y](e)){var f=a.glyphs[e];if(b.glyphs[e]={w:f.w,k:{},d:f.d&&"M"+f.d.replace(/[mlcxtrv]/g,function(a){return{l:"L",c:"C",x:"z",t:"m",r:"l",v:"c"} -[a]||"M"})+"z"},f.k) -for(var g in f.k) -f[y](g)&&(b.glyphs[e].k[g]=f.k[g])}} -return a},u.getFont=function(a,c,d,e){if(e=e||"normal",d=d||"normal",c=+c||{normal:400,bold:700,lighter:300,bolder:800} -[c]||400,b.fonts){var f=b.fonts[a];if(!f){var g=new RegExp("(^|\\s)"+a.replace(/[^\w\d\s+!~.:_-]/g,F)+"(\\s|$)","i");for(var h in b.fonts) -if(b.fonts[y](h)&&g.test(h)){f=b.fonts[h];break}} -var i;if(f) -for(var j=0,k=f.length;k>j&&(i=f[j],i.face["font-weight"]!=c||i.face["font-style"]!=d&&i.face["font-style"]||i.face["font-stretch"]!=e);j++);return i}},u.print=function(a,c,d,e,f,g,h,i){g=g||"middle",h=N(O(h||0,1),-1),i=N(O(i||1,3),1);var j,k=H(d)[I](F),l=0,m=0,n=F;if(b.is(e,"string")&&(e=this.getFont(e)),e){j=(f||16)/e.face["units-per-em"];for(var o=e.face.bbox[I](v),p=+o[0],q=o[3]-o[1],r=0,s=+o[1]+("baseline"==g?q+ +e.face.descent:q/2),t=0,u=k.length;u>t;t++){if("\n"==k[t]) -l=0,x=0,m=0,r+=q*i;else{var w=m&&e.glyphs[k[t-1]]||{},x=e.glyphs[k[t]];l+=m?(w.w||e.w)+(w.k&&w.k[k[t]]||0)+e.w*h:0,m=1} -x&&x.d&&(n+=b.transformPath(x.d,["t",l*j,r*j,"s",j,j,p,s,"t",(a-p)/j,(c-s)/j]))}} -return this.path(n).attr({fill:"#000",stroke:"none"})},u.add=function(a){if(b.is(a,"array")) -for(var c,d=this.set(),e=0,f=a.length;f>e;e++) -c=a[e]||{},w[y](c.type)&&d.push(this[c.type]().attr(c));return d},b.format=function(a,c){var d=b.is(c,U)?[0][D](c):arguments;return a&&b.is(a,T)&&d.length-1&&(a=a.replace(x,function(a,b){return null==d[++b]?F:d[b]})),a||F},b.fullfill=function(){var a=/\{([^\}]+)\}/g,b=/(?:(?:^|\.)(.+?)(?=\[|\.|$|\()|\[('|")(.+?)\2\])(\(\))?/g,c=function(a,c,d){var e=d;return c.replace(b,function(a,b,c,d,f){b=b||d,e&&(b in e&&(e=e[b]),"function"==typeof e&&f&&(e=e()))}),e=(null==e||e==d?a:e)+""};return function(b,d){return String(b).replace(a,function(a,b){return c(a,b,d)})}} -(),b.ninja=function(){return A.was?z.win.Raphael=A.is:delete Raphael,b},b.st=kb,a.on("raphael.DOMload",function(){t=!0}),function(a,c,d){function e(){/in/.test(a.readyState)?setTimeout(e,9):b.eve("raphael.DOMload")} -null==a.readyState&&a.addEventListener&&(a.addEventListener(c,d=function(){a.removeEventListener(c,d,!1),a.readyState="complete"},!1),a.readyState="loading"),e()} -(document,"DOMContentLoaded"),b}),function(a,b){"function"==typeof define&&define.amd?define("raphael.svg",["raphael.core"],function(a){return b(a)}):b("object"==typeof exports?require("./raphael.core"):a.Raphael)} -(this,function(a){if(!a||a.svg){var b="hasOwnProperty",c=String,d=parseFloat,e=parseInt,f=Math,g=f.max,h=f.abs,i=f.pow,j=/[, ]+/,k=a.eve,l="",m=" ",n="http://www.w3.org/1999/xlink",o={block:"M5,0 0,2.5 5,5z",classic:"M5,0 0,2.5 5,5 3.5,3 3.5,2z",diamond:"M2.5,0 5,2.5 2.5,5 0,2.5z",open:"M6,1 1,3.5 6,6",oval:"M2.5,0A2.5,2.5,0,0,1,2.5,5 2.5,2.5,0,0,1,2.5,0z"},p={};a.toString=function(){return"Your browser supports SVG.\nYou are running Raphaël "+this.version};var q=function(d,e){if(e){"string"==typeof d&&(d=q(d));for(var f in e) -e[b](f)&&("xlink:"==f.substring(0,6)?d.setAttributeNS(n,f.substring(6),c(e[f])):d.setAttribute(f,c(e[f])))}else -d=a._g.doc.createElementNS("http://www.w3.org/2000/svg",d),d.style&&(d.style.webkitTapHighlightColor="rgba(0,0,0,0)");return d},r=function(b,e){var j="linear",k=b.id+e,m=.5,n=.5,o=b.node,p=b.paper,r=o.style,s=a._g.doc.getElementById(k);if(!s){if(e=c(e).replace(a._radial_gradient,function(a,b,c){if(j="radial",b&&c){m=d(b),n=d(c);var e=2*(n>.5)-1;i(m-.5,2)+i(n-.5,2)>.25&&(n=f.sqrt(.25-i(m-.5,2))*e+.5)&&.5!=n&&(n=n.toFixed(5)-1e-5*e)} -return l}),e=e.split(/\s*\-\s*/),"linear"==j){var t=e.shift();if(t=-d(t),isNaN(t)) -return null;var u=[0,0,f.cos(a.rad(t)),f.sin(a.rad(t))],v=1/(g(h(u[2]),h(u[3]))||1);u[2]*=v,u[3]*=v,u[2]<0&&(u[0]=-u[2],u[2]=0),u[3]<0&&(u[1]=-u[3],u[3]=0)} -var w=a._parseDots(e);if(!w) -return null;if(k=k.replace(/[\(\)\s,\xb0#]/g,"_"),b.gradient&&k!=b.gradient.id&&(p.defs.removeChild(b.gradient),delete b.gradient),!b.gradient){s=q(j+"Gradient",{id:k}),b.gradient=s,q(s,"radial"==j?{fx:m,fy:n}:{x1:u[0],y1:u[1],x2:u[2],y2:u[3],gradientTransform:b.matrix.invert()}),p.defs.appendChild(s);for(var x=0,y=w.length;y>x;x++) -s.appendChild(q("stop",{offset:w[x].offset?w[x].offset:x?"100%":"0%","stop-color":w[x].color||"#fff","stop-opacity":isFinite(w[x].opacity)?w[x].opacity:1}))}} -return q(o,{fill:"url('"+document.location.origin+document.location.pathname+"#"+k+"')",opacity:1,"fill-opacity":1}),r.fill=l,r.opacity=1,r.fillOpacity=1,1},s=function(a){var b=a.getBBox(1);q(a.pattern,{patternTransform:a.matrix.invert()+" translate("+b.x+","+b.y+")"})},t=function(d,e,f){if("path"==d.type){for(var g,h,i,j,k,m=c(e).toLowerCase().split("-"),n=d.paper,r=f?"end":"start",s=d.node,t=d.attrs,u=t["stroke-width"],v=m.length,w="classic",x=3,y=3,z=5;v--;) -switch(m[v]){case"block":case"classic":case"oval":case"diamond":case"open":case"none":w=m[v];break;case"wide":y=5;break;case"narrow":y=2;break;case"long":x=5;break;case"short":x=2} -if("open"==w?(x+=2,y+=2,z+=2,i=1,j=f?4:1,k={fill:"none",stroke:t.stroke}):(j=i=x/2,k={fill:t.stroke,stroke:"none"}),d._.arrows?f?(d._.arrows.endPath&&p[d._.arrows.endPath]--,d._.arrows.endMarker&&p[d._.arrows.endMarker]--):(d._.arrows.startPath&&p[d._.arrows.startPath]--,d._.arrows.startMarker&&p[d._.arrows.startMarker]--):d._.arrows={},"none"!=w){var A="raphael-marker-"+w,B="raphael-marker-"+r+w+x+y+"-obj"+d.id;a._g.doc.getElementById(A)?p[A]++:(n.defs.appendChild(q(q("path"),{"stroke-linecap":"round",d:o[w],id:A})),p[A]=1);var C,D=a._g.doc.getElementById(B);D?(p[B]++,C=D.getElementsByTagName("use")[0]):(D=q(q("marker"),{id:B,markerHeight:y,markerWidth:x,orient:"auto",refX:j,refY:y/2}),C=q(q("use"),{"xlink:href":"#"+A,transform:(f?"rotate(180 "+x/2+" "+y/2+") ":l)+"scale("+x/z+","+y/z+")","stroke-width":(1/((x/z+y/z)/2)).toFixed(4)}),D.appendChild(C),n.defs.appendChild(D),p[B]=1),q(C,k);var E=i*("diamond"!=w&&"oval"!=w);f?(g=d._.arrows.startdx*u||0,h=a.getTotalLength(t.path)-E*u):(g=E*u,h=a.getTotalLength(t.path)-(d._.arrows.enddx*u||0)),k={},k["marker-"+r]="url(#"+B+")",(h||g)&&(k.d=a.getSubpath(t.path,g,h)),q(s,k),d._.arrows[r+"Path"]=A,d._.arrows[r+"Marker"]=B,d._.arrows[r+"dx"]=E,d._.arrows[r+"Type"]=w,d._.arrows[r+"String"]=e}else -f?(g=d._.arrows.startdx*u||0,h=a.getTotalLength(t.path)-g):(g=0,h=a.getTotalLength(t.path)-(d._.arrows.enddx*u||0)),d._.arrows[r+"Path"]&&q(s,{d:a.getSubpath(t.path,g,h)}),delete d._.arrows[r+"Path"],delete d._.arrows[r+"Marker"],delete d._.arrows[r+"dx"],delete d._.arrows[r+"Type"],delete d._.arrows[r+"String"];for(k in p) -if(p[b](k)&&!p[k]){var F=a._g.doc.getElementById(k);F&&F.parentNode.removeChild(F)}}},u={"-":[3,1],".":[1,1],"-.":[3,1,1,1],"-..":[3,1,1,1,1,1],". ":[1,3],"- ":[4,3],"--":[8,3],"- .":[4,3,1,3],"--.":[8,3,1,3],"--..":[8,3,1,3,1,3]},v=function(a,b,d){if(b=u[c(b).toLowerCase()]){for(var e=a.attrs["stroke-width"]||"1",f={round:e,square:e,butt:0} -[a.attrs["stroke-linecap"]||d["stroke-linecap"]]||0,g=[],h=b.length;h--;) -g[h]=b[h]*e+(h%2?1:-1)*f;q(a.node,{"stroke-dasharray":g.join(",")})}else -q(a.node,{"stroke-dasharray":"none"})},w=function(d,f){var i=d.node,k=d.attrs,m=i.style.visibility;i.style.visibility="hidden";for(var o in f) -if(f[b](o)){if(!a._availableAttrs[b](o)) -continue;var p=f[o];switch(k[o]=p,o){case"blur":d.blur(p);break;case"title":var u=i.getElementsByTagName("title");if(u.length&&(u=u[0])) -u.firstChild.nodeValue=p;else{u=q("title");var w=a._g.doc.createTextNode(p);u.appendChild(w),i.appendChild(u)} -break;case"href":case"target":var x=i.parentNode;if("a"!=x.tagName.toLowerCase()){var z=q("a");x.insertBefore(z,i),z.appendChild(i),x=z}"target"==o?x.setAttributeNS(n,"show","blank"==p?"new":p):x.setAttributeNS(n,o,p);break;case"cursor":i.style.cursor=p;break;case"transform":d.transform(p);break;case"arrow-start":t(d,p);break;case"arrow-end":t(d,p,1);break;case"clip-rect":var A=c(p).split(j);if(4==A.length){d.clip&&d.clip.parentNode.parentNode.removeChild(d.clip.parentNode);var B=q("clipPath"),C=q("rect");B.id=a.createUUID(),q(C,{x:A[0],y:A[1],width:A[2],height:A[3]}),B.appendChild(C),d.paper.defs.appendChild(B),q(i,{"clip-path":"url(#"+B.id+")"}),d.clip=C} -if(!p){var D=i.getAttribute("clip-path");if(D){var E=a._g.doc.getElementById(D.replace(/(^url\(#|\)$)/g,l));E&&E.parentNode.removeChild(E),q(i,{"clip-path":l}),delete d.clip}} -break;case"path":"path"==d.type&&(q(i,{d:p?k.path=a._pathToAbsolute(p):"M0,0"}),d._.dirty=1,d._.arrows&&("startString"in d._.arrows&&t(d,d._.arrows.startString),"endString"in d._.arrows&&t(d,d._.arrows.endString,1)));break;case"width":if(i.setAttribute(o,p),d._.dirty=1,!k.fx) -break;o="x",p=k.x;case"x":k.fx&&(p=-k.x-(k.width||0));case"rx":if("rx"==o&&"rect"==d.type) -break;case"cx":i.setAttribute(o,p),d.pattern&&s(d),d._.dirty=1;break;case"height":if(i.setAttribute(o,p),d._.dirty=1,!k.fy) -break;o="y",p=k.y;case"y":k.fy&&(p=-k.y-(k.height||0));case"ry":if("ry"==o&&"rect"==d.type) -break;case"cy":i.setAttribute(o,p),d.pattern&&s(d),d._.dirty=1;break;case"r":"rect"==d.type?q(i,{rx:p,ry:p}):i.setAttribute(o,p),d._.dirty=1;break;case"src":"image"==d.type&&i.setAttributeNS(n,"href",p);break;case"stroke-width":(1!=d._.sx||1!=d._.sy)&&(p/=g(h(d._.sx),h(d._.sy))||1),i.setAttribute(o,p),k["stroke-dasharray"]&&v(d,k["stroke-dasharray"],f),d._.arrows&&("startString"in d._.arrows&&t(d,d._.arrows.startString),"endString"in d._.arrows&&t(d,d._.arrows.endString,1));break;case"stroke-dasharray":v(d,p,f);break;case"fill":var F=c(p).match(a._ISURL);if(F){B=q("pattern");var G=q("image");B.id=a.createUUID(),q(B,{x:0,y:0,patternUnits:"userSpaceOnUse",height:1,width:1}),q(G,{x:0,y:0,"xlink:href":F[1]}),B.appendChild(G),function(b){a._preload(F[1],function(){var a=this.offsetWidth,c=this.offsetHeight;q(b,{width:a,height:c}),q(G,{width:a,height:c})})} -(B),d.paper.defs.appendChild(B),q(i,{fill:"url(#"+B.id+")"}),d.pattern=B,d.pattern&&s(d);break} -var H=a.getRGB(p);if(H.error){if(("circle"==d.type||"ellipse"==d.type||"r"!=c(p).charAt())&&r(d,p)){if("opacity"in k||"fill-opacity"in k){var I=a._g.doc.getElementById(i.getAttribute("fill").replace(/^url\(#|\)$/g,l));if(I){var J=I.getElementsByTagName("stop");q(J[J.length-1],{"stop-opacity":("opacity"in k?k.opacity:1)*("fill-opacity"in k?k["fill-opacity"]:1)})}} -k.gradient=p,k.fill="none";break}}else -delete f.gradient,delete k.gradient,!a.is(k.opacity,"undefined")&&a.is(f.opacity,"undefined")&&q(i,{opacity:k.opacity}),!a.is(k["fill-opacity"],"undefined")&&a.is(f["fill-opacity"],"undefined")&&q(i,{"fill-opacity":k["fill-opacity"]});H[b]("opacity")&&q(i,{"fill-opacity":H.opacity>1?H.opacity/100:H.opacity});case"stroke":H=a.getRGB(p),i.setAttribute(o,H.hex),"stroke"==o&&H[b]("opacity")&&q(i,{"stroke-opacity":H.opacity>1?H.opacity/100:H.opacity}),"stroke"==o&&d._.arrows&&("startString"in d._.arrows&&t(d,d._.arrows.startString),"endString"in d._.arrows&&t(d,d._.arrows.endString,1));break;case"gradient":("circle"==d.type||"ellipse"==d.type||"r"!=c(p).charAt())&&r(d,p);break;case"opacity":k.gradient&&!k[b]("stroke-opacity")&&q(i,{"stroke-opacity":p>1?p/100:p});case"fill-opacity":if(k.gradient){I=a._g.doc.getElementById(i.getAttribute("fill").replace(/^url\(#|\)$/g,l)),I&&(J=I.getElementsByTagName("stop"),q(J[J.length-1],{"stop-opacity":p}));break} -default:"font-size"==o&&(p=e(p,10)+"px");var K=o.replace(/(\-.)/g,function(a){return a.substring(1).toUpperCase()});i.style[K]=p,d._.dirty=1,i.setAttribute(o,p)}} -y(d,f),i.style.visibility=m},x=1.2,y=function(d,f){if("text"==d.type&&(f[b]("text")||f[b]("font")||f[b]("font-size")||f[b]("x")||f[b]("y"))){var g=d.attrs,h=d.node,i=h.firstChild?e(a._g.doc.defaultView.getComputedStyle(h.firstChild,l).getPropertyValue("font-size"),10):10;if(f[b]("text")){for(g.text=f.text;h.firstChild;) -h.removeChild(h.firstChild);for(var j,k=c(f.text).split("\n"),m=[],n=0,o=k.length;o>n;n++) -j=q("tspan"),n&&q(j,{dy:i*x,x:g.x}),j.appendChild(a._g.doc.createTextNode(k[n])),h.appendChild(j),m[n]=j}else -for(m=h.getElementsByTagName("tspan"),n=0,o=m.length;o>n;n++) -n?q(m[n],{dy:i*x,x:g.x}):q(m[0],{dy:0});q(h,{x:g.x,y:g.y}),d._.dirty=1;var p=d._getBBox(),r=g.y-(p.y+p.height/2);r&&a.is(r,"finite")&&q(m[0],{dy:r})}},z=function(a){return a.parentNode&&"a"===a.parentNode.tagName.toLowerCase()?a.parentNode:a},A=function(b,c){this[0]=this.node=b,b.raphael=!0,this.id=a._oid++,b.raphaelid=this.id,this.matrix=a.matrix(),this.realPath=null,this.paper=c,this.attrs=this.attrs||{},this._={transform:[],sx:1,sy:1,deg:0,dx:0,dy:0,dirty:1},!c.bottom&&(c.bottom=this),this.prev=c.top,c.top&&(c.top.next=this),c.top=this,this.next=null},B=a.el;A.prototype=B,B.constructor=A,a._engine.path=function(a,b){var c=q("path");b.canvas&&b.canvas.appendChild(c);var d=new A(c,b);return d.type="path",w(d,{fill:"none",stroke:"#000",path:a}),d},B.rotate=function(a,b,e){if(this.removed) -return this;if(a=c(a).split(j),a.length-1&&(b=d(a[1]),e=d(a[2])),a=d(a[0]),null==e&&(b=e),null==b||null==e){var f=this.getBBox(1);b=f.x+f.width/2,e=f.y+f.height/2} -return this.transform(this._.transform.concat([["r",a,b,e]])),this},B.scale=function(a,b,e,f){if(this.removed) -return this;if(a=c(a).split(j),a.length-1&&(b=d(a[1]),e=d(a[2]),f=d(a[3])),a=d(a[0]),null==b&&(b=a),null==f&&(e=f),null==e||null==f) -var g=this.getBBox(1);return e=null==e?g.x+g.width/2:e,f=null==f?g.y+g.height/2:f,this.transform(this._.transform.concat([["s",a,b,e,f]])),this},B.translate=function(a,b){return this.removed?this:(a=c(a).split(j),a.length-1&&(b=d(a[1])),a=d(a[0])||0,b=+b||0,this.transform(this._.transform.concat([["t",a,b]])),this)},B.transform=function(c){var d=this._;if(null==c) -return d.transform;if(a._extractTransform(this,c),this.clip&&q(this.clip,{transform:this.matrix.invert()}),this.pattern&&s(this),this.node&&q(this.node,{transform:this.matrix}),1!=d.sx||1!=d.sy){var e=this.attrs[b]("stroke-width")?this.attrs["stroke-width"]:1;this.attr({"stroke-width":e})} -return this},B.hide=function(){return this.removed||(this.node.style.display="none"),this},B.show=function(){return this.removed||(this.node.style.display=""),this},B.remove=function(){var b=z(this.node);if(!this.removed&&b.parentNode){var c=this.paper;c.__set__&&c.__set__.exclude(this),k.unbind("raphael.*.*."+this.id),this.gradient&&c.defs.removeChild(this.gradient),a._tear(this,c),b.parentNode.removeChild(b),this.removeData();for(var d in this) -this[d]="function"==typeof this[d]?a._removedFactory(d):null;this.removed=!0}},B._getBBox=function(){if("none"==this.node.style.display){this.show();var a=!0} -var b,c=!1;this.paper.canvas.parentElement?b=this.paper.canvas.parentElement.style:this.paper.canvas.parentNode&&(b=this.paper.canvas.parentNode.style),b&&"none"==b.display&&(c=!0,b.display="");var d={};try{d=this.node.getBBox()}catch(e){d={x:this.node.clientLeft,y:this.node.clientTop,width:this.node.clientWidth,height:this.node.clientHeight}} -finally{d=d||{},c&&(b.display="none")} -return a&&this.hide(),d},B.attr=function(c,d){if(this.removed) -return this;if(null==c){var e={};for(var f in this.attrs) -this.attrs[b](f)&&(e[f]=this.attrs[f]);return e.gradient&&"none"==e.fill&&(e.fill=e.gradient)&&delete e.gradient,e.transform=this._.transform,e} -if(null==d&&a.is(c,"string")){if("fill"==c&&"none"==this.attrs.fill&&this.attrs.gradient) -return this.attrs.gradient;if("transform"==c) -return this._.transform;for(var g=c.split(j),h={},i=0,l=g.length;l>i;i++) -c=g[i],c in this.attrs?h[c]=this.attrs[c]:a.is(this.paper.customAttributes[c],"function")?h[c]=this.paper.customAttributes[c].def:h[c]=a._availableAttrs[c];return l-1?h:h[g[0]]} -if(null==d&&a.is(c,"array")){for(h={},i=0,l=c.length;l>i;i++) -h[c[i]]=this.attr(c[i]);return h} -if(null!=d){var m={};m[c]=d}else -null!=c&&a.is(c,"object")&&(m=c);for(var n in m) -k("raphael.attr."+n+"."+this.id,this,m[n]);for(n in this.paper.customAttributes) -if(this.paper.customAttributes[b](n)&&m[b](n)&&a.is(this.paper.customAttributes[n],"function")){var o=this.paper.customAttributes[n].apply(this,[].concat(m[n]));this.attrs[n]=m[n];for(var p in o) -o[b](p)&&(m[p]=o[p])} -return w(this,m),this},B.toFront=function(){if(this.removed) -return this;var b=z(this.node);b.parentNode.appendChild(b);var c=this.paper;return c.top!=this&&a._tofront(this,c),this},B.toBack=function(){if(this.removed) -return this;var b=z(this.node),c=b.parentNode;c.insertBefore(b,c.firstChild),a._toback(this,this.paper);this.paper;return this},B.insertAfter=function(b){if(this.removed||!b) -return this;var c=z(this.node),d=z(b.node||b[b.length-1].node);return d.nextSibling?d.parentNode.insertBefore(c,d.nextSibling):d.parentNode.appendChild(c),a._insertafter(this,b,this.paper),this},B.insertBefore=function(b){if(this.removed||!b) -return this;var c=z(this.node),d=z(b.node||b[0].node);return d.parentNode.insertBefore(c,d),a._insertbefore(this,b,this.paper),this},B.blur=function(b){var c=this;if(0!==+b){var d=q("filter"),e=q("feGaussianBlur");c.attrs.blur=b,d.id=a.createUUID(),q(e,{stdDeviation:+b||1.5}),d.appendChild(e),c.paper.defs.appendChild(d),c._blur=d,q(c.node,{filter:"url(#"+d.id+")"})}else -c._blur&&(c._blur.parentNode.removeChild(c._blur),delete c._blur,delete c.attrs.blur),c.node.removeAttribute("filter");return c},a._engine.circle=function(a,b,c,d){var e=q("circle");a.canvas&&a.canvas.appendChild(e);var f=new A(e,a);return f.attrs={cx:b,cy:c,r:d,fill:"none",stroke:"#000"},f.type="circle",q(e,f.attrs),f},a._engine.rect=function(a,b,c,d,e,f){var g=q("rect");a.canvas&&a.canvas.appendChild(g);var h=new A(g,a);return h.attrs={x:b,y:c,width:d,height:e,rx:f||0,ry:f||0,fill:"none",stroke:"#000"},h.type="rect",q(g,h.attrs),h},a._engine.ellipse=function(a,b,c,d,e){var f=q("ellipse");a.canvas&&a.canvas.appendChild(f);var g=new A(f,a);return g.attrs={cx:b,cy:c,rx:d,ry:e,fill:"none",stroke:"#000"},g.type="ellipse",q(f,g.attrs),g},a._engine.image=function(a,b,c,d,e,f){var g=q("image");q(g,{x:c,y:d,width:e,height:f,preserveAspectRatio:"none"}),g.setAttributeNS(n,"href",b),a.canvas&&a.canvas.appendChild(g);var h=new A(g,a);return h.attrs={x:c,y:d,width:e,height:f,src:b},h.type="image",h},a._engine.text=function(b,c,d,e){var f=q("text");b.canvas&&b.canvas.appendChild(f);var g=new A(f,b);return g.attrs={x:c,y:d,"text-anchor":"middle",text:e,"font-family":a._availableAttrs["font-family"],"font-size":a._availableAttrs["font-size"],stroke:"none",fill:"#000"},g.type="text",w(g,g.attrs),g},a._engine.setSize=function(a,b){return this.width=a||this.width,this.height=b||this.height,this.canvas.setAttribute("width",this.width),this.canvas.setAttribute("height",this.height),this._viewBox&&this.setViewBox.apply(this,this._viewBox),this},a._engine.create=function(){var b=a._getContainer.apply(0,arguments),c=b&&b.container,d=b.x,e=b.y,f=b.width,g=b.height;if(!c) -throw new Error("SVG container not found.");var h,i=q("svg"),j="overflow:hidden;";return d=d||0,e=e||0,f=f||512,g=g||342,q(i,{height:g,version:1.1,width:f,xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink"}),1==c?(i.style.cssText=j+"position:absolute;left:"+d+"px;top:"+e+"px",a._g.doc.body.appendChild(i),h=1):(i.style.cssText=j+"position:relative",c.firstChild?c.insertBefore(i,c.firstChild):c.appendChild(i)),c=new a._Paper,c.width=f,c.height=g,c.canvas=i,c.clear(),c._left=c._top=0,h&&(c.renderfix=function(){}),c.renderfix(),c},a._engine.setViewBox=function(a,b,c,d,e){k("raphael.setViewBox",this,this._viewBox,[a,b,c,d,e]);var f,h,i=this.getSize(),j=g(c/i.width,d/i.height),l=this.top,n=e?"xMidYMid meet":"xMinYMin";for(null==a?(this._vbSize&&(j=1),delete this._vbSize,f="0 0 "+this.width+m+this.height):(this._vbSize=j,f=a+m+b+m+c+m+d),q(this.canvas,{viewBox:f,preserveAspectRatio:n});j&&l;) -h="stroke-width"in l.attrs?l.attrs["stroke-width"]:1,l.attr({"stroke-width":h}),l._.dirty=1,l._.dirtyT=1,l=l.prev;return this._viewBox=[a,b,c,d,!!e],this},a.prototype.renderfix=function(){var a,b=this.canvas,c=b.style;try{a=b.getScreenCTM()||b.createSVGMatrix()}catch(d){a=b.createSVGMatrix()} -var e=-a.e%1,f=-a.f%1;(e||f)&&(e&&(this._left=(this._left+e)%1,c.left=this._left+"px"),f&&(this._top=(this._top+f)%1,c.top=this._top+"px"))},a.prototype.clear=function(){a.eve("raphael.clear",this);for(var b=this.canvas;b.firstChild;) -b.removeChild(b.firstChild);this.bottom=this.top=null,(this.desc=q("desc")).appendChild(a._g.doc.createTextNode("Created with Raphaël "+a.version)),b.appendChild(this.desc),b.appendChild(this.defs=q("defs"))},a.prototype.remove=function(){k("raphael.remove",this),this.canvas.parentNode&&this.canvas.parentNode.removeChild(this.canvas);for(var b in this) -this[b]="function"==typeof this[b]?a._removedFactory(b):null};var C=a.st;for(var D in B) -B[b](D)&&!C[b](D)&&(C[D]=function(a){return function(){var b=arguments;return this.forEach(function(c){c[a].apply(c,b)})}} -(D))}}),function(a,b){"function"==typeof define&&define.amd?define("raphael.vml",["raphael.core"],function(a){return b(a)}):b("object"==typeof exports?require("./raphael.core"):a.Raphael)} -(this,function(a){if(!a||a.vml){var b="hasOwnProperty",c=String,d=parseFloat,e=Math,f=e.round,g=e.max,h=e.min,i=e.abs,j="fill",k=/[, ]+/,l=a.eve,m=" progid:DXImageTransform.Microsoft",n=" ",o="",p={M:"m",L:"l",C:"c",Z:"x",m:"t",l:"r",c:"v",z:"x"},q=/([clmz]),?([^clmz]*)/gi,r=/ progid:\S+Blur\([^\)]+\)/g,s=/-?[^,\s-]+/g,t="position:absolute;left:0;top:0;width:1px;height:1px;behavior:url(#default#VML)",u=21600,v={path:1,rect:1,image:1},w={circle:1,ellipse:1},x=function(b){var d=/[ahqstv]/gi,e=a._pathToAbsolute;if(c(b).match(d)&&(e=a._path2curve),d=/[clmz]/g,e==a._pathToAbsolute&&!c(b).match(d)){var g=c(b).replace(q,function(a,b,c){var d=[],e="m"==b.toLowerCase(),g=p[b];return c.replace(s,function(a){e&&2==d.length&&(g+=d+p["m"==b?"l":"L"],d=[]),d.push(f(a*u))}),g+d});return g} -var h,i,j=e(b);g=[];for(var k=0,l=j.length;l>k;k++){h=j[k],i=j[k][0].toLowerCase(),"z"==i&&(i="x");for(var m=1,r=h.length;r>m;m++) -i+=f(h[m]*u)+(m!=r-1?",":o);g.push(i)} -return g.join(n)},y=function(b,c,d){var e=a.matrix();return e.rotate(-b,.5,.5),{dx:e.x(c,d),dy:e.y(c,d)}},z=function(a,b,c,d,e,f){var g=a._,h=a.matrix,k=g.fillpos,l=a.node,m=l.style,o=1,p="",q=u/b,r=u/c;if(m.visibility="hidden",b&&c){if(l.coordsize=i(q)+n+i(r),m.rotation=f*(0>b*c?-1:1),f){var s=y(f,d,e);d=s.dx,e=s.dy} -if(0>b&&(p+="x"),0>c&&(p+=" y")&&(o=-1),m.flip=p,l.coordorigin=d* -q+n+e* -r,k||g.fillsize){var t=l.getElementsByTagName(j);t=t&&t[0],l.removeChild(t),k&&(s=y(f,h.x(k[0],k[1]),h.y(k[0],k[1])),t.position=s.dx*o+n+s.dy*o),g.fillsize&&(t.size=g.fillsize[0]*i(b)+n+g.fillsize[1]*i(c)),l.appendChild(t)} -m.visibility="visible"}};a.toString=function(){return"Your browser doesn’t support SVG. Falling down to VML.\nYou are running Raphaël "+this.version};var A=function(a,b,d){for(var e=c(b).toLowerCase().split("-"),f=d?"end":"start",g=e.length,h="classic",i="medium",j="medium";g--;) -switch(e[g]){case"block":case"classic":case"oval":case"diamond":case"open":case"none":h=e[g];break;case"wide":case"narrow":j=e[g];break;case"long":case"short":i=e[g]} -var k=a.node.getElementsByTagName("stroke")[0];k[f+"arrow"]=h,k[f+"arrowlength"]=i,k[f+"arrowwidth"]=j},B=function(e,i){e.attrs=e.attrs||{};var l=e.node,m=e.attrs,p=l.style,q=v[e.type]&&(i.x!=m.x||i.y!=m.y||i.width!=m.width||i.height!=m.height||i.cx!=m.cx||i.cy!=m.cy||i.rx!=m.rx||i.ry!=m.ry||i.r!=m.r),r=w[e.type]&&(m.cx!=i.cx||m.cy!=i.cy||m.r!=i.r||m.rx!=i.rx||m.ry!=i.ry),s=e;for(var t in i) -i[b](t)&&(m[t]=i[t]);if(q&&(m.path=a._getPath[e.type](e),e._.dirty=1),i.href&&(l.href=i.href),i.title&&(l.title=i.title),i.target&&(l.target=i.target),i.cursor&&(p.cursor=i.cursor),"blur"in i&&e.blur(i.blur),(i.path&&"path"==e.type||q)&&(l.path=x(~c(m.path).toLowerCase().indexOf("r")?a._pathToAbsolute(m.path):m.path),e._.dirty=1,"image"==e.type&&(e._.fillpos=[m.x,m.y],e._.fillsize=[m.width,m.height],z(e,1,1,0,0,0))),"transform"in i&&e.transform(i.transform),r){var y=+m.cx,B=+m.cy,D=+m.rx||+m.r||0,E=+m.ry||+m.r||0;l.path=a.format("ar{0},{1},{2},{3},{4},{1},{4},{1}x",f((y-D)*u),f((B-E)*u),f((y+D)*u),f((B+E)*u),f(y*u)),e._.dirty=1} -if("clip-rect"in i){var G=c(i["clip-rect"]).split(k);if(4==G.length){G[2]=+G[2]+ +G[0],G[3]=+G[3]+ +G[1];var H=l.clipRect||a._g.doc.createElement("div"),I=H.style;I.clip=a.format("rect({1}px {2}px {3}px {0}px)",G),l.clipRect||(I.position="absolute",I.top=0,I.left=0,I.width=e.paper.width+"px",I.height=e.paper.height+"px",l.parentNode.insertBefore(H,l),H.appendChild(l),l.clipRect=H)} -i["clip-rect"]||l.clipRect&&(l.clipRect.style.clip="auto")} -if(e.textpath){var J=e.textpath.style;i.font&&(J.font=i.font),i["font-family"]&&(J.fontFamily='"'+i["font-family"].split(",")[0].replace(/^['"]+|['"]+$/g,o)+'"'),i["font-size"]&&(J.fontSize=i["font-size"]),i["font-weight"]&&(J.fontWeight=i["font-weight"]),i["font-style"]&&(J.fontStyle=i["font-style"])} -if("arrow-start"in i&&A(s,i["arrow-start"]),"arrow-end"in i&&A(s,i["arrow-end"],1),null!=i.opacity||null!=i["stroke-width"]||null!=i.fill||null!=i.src||null!=i.stroke||null!=i["stroke-width"]||null!=i["stroke-opacity"]||null!=i["fill-opacity"]||null!=i["stroke-dasharray"]||null!=i["stroke-miterlimit"]||null!=i["stroke-linejoin"]||null!=i["stroke-linecap"]){var K=l.getElementsByTagName(j),L=!1;if(K=K&&K[0],!K&&(L=K=F(j)),"image"==e.type&&i.src&&(K.src=i.src),i.fill&&(K.on=!0),(null==K.on||"none"==i.fill||null===i.fill)&&(K.on=!1),K.on&&i.fill){var M=c(i.fill).match(a._ISURL);if(M){K.parentNode==l&&l.removeChild(K),K.rotate=!0,K.src=M[1],K.type="tile";var N=e.getBBox(1);K.position=N.x+n+N.y,e._.fillpos=[N.x,N.y],a._preload(M[1],function(){e._.fillsize=[this.offsetWidth,this.offsetHeight]})}else -K.color=a.getRGB(i.fill).hex,K.src=o,K.type="solid",a.getRGB(i.fill).error&&(s.type in{circle:1,ellipse:1}||"r"!=c(i.fill).charAt())&&C(s,i.fill,K)&&(m.fill="none",m.gradient=i.fill,K.rotate=!1)} -if("fill-opacity"in i||"opacity"in i){var O=((+m["fill-opacity"]+1||2)-1)*((+m.opacity+1||2)-1)*((+a.getRGB(i.fill).o+1||2)-1);O=h(g(O,0),1),K.opacity=O,K.src&&(K.color="none")} -l.appendChild(K);var P=l.getElementsByTagName("stroke")&&l.getElementsByTagName("stroke")[0],Q=!1;!P&&(Q=P=F("stroke")),(i.stroke&&"none"!=i.stroke||i["stroke-width"]||null!=i["stroke-opacity"]||i["stroke-dasharray"]||i["stroke-miterlimit"]||i["stroke-linejoin"]||i["stroke-linecap"])&&(P.on=!0),("none"==i.stroke||null===i.stroke||null==P.on||0==i.stroke||0==i["stroke-width"])&&(P.on=!1);var R=a.getRGB(i.stroke);P.on&&i.stroke&&(P.color=R.hex),O=((+m["stroke-opacity"]+1||2)-1)*((+m.opacity+1||2)-1)*((+R.o+1||2)-1);var S=.75*(d(i["stroke-width"])||1);if(O=h(g(O,0),1),null==i["stroke-width"]&&(S=m["stroke-width"]),i["stroke-width"]&&(P.weight=S),S&&1>S&&(O*=S)&&(P.weight=1),P.opacity=O,i["stroke-linejoin"]&&(P.joinstyle=i["stroke-linejoin"]||"miter"),P.miterlimit=i["stroke-miterlimit"]||8,i["stroke-linecap"]&&(P.endcap="butt"==i["stroke-linecap"]?"flat":"square"==i["stroke-linecap"]?"square":"round"),"stroke-dasharray"in i){var T={"-":"shortdash",".":"shortdot","-.":"shortdashdot","-..":"shortdashdotdot",". ":"dot","- ":"dash","--":"longdash","- .":"dashdot","--.":"longdashdot","--..":"longdashdotdot"};P.dashstyle=T[b](i["stroke-dasharray"])?T[i["stroke-dasharray"]]:o} -Q&&l.appendChild(P)} -if("text"==s.type){s.paper.canvas.style.display=o;var U=s.paper.span,V=100,W=m.font&&m.font.match(/\d+(?:\.\d*)?(?=px)/);p=U.style,m.font&&(p.font=m.font),m["font-family"]&&(p.fontFamily=m["font-family"]),m["font-weight"]&&(p.fontWeight=m["font-weight"]),m["font-style"]&&(p.fontStyle=m["font-style"]),W=d(m["font-size"]||W&&W[0])||10,p.fontSize=W*V+"px",s.textpath.string&&(U.innerHTML=c(s.textpath.string).replace(/"));var X=U.getBoundingClientRect();s.W=m.w=(X.right-X.left)/V,s.H=m.h=(X.bottom-X.top)/V,s.X=m.x,s.Y=m.y+s.H/2,("x"in i||"y"in i)&&(s.path.v=a.format("m{0},{1}l{2},{1}",f(m.x*u),f(m.y*u),f(m.x*u)+1));for(var Y=["x","y","text","font","font-family","font-weight","font-style","font-size"],Z=0,$=Y.length;$>Z;Z++) -if(Y[Z]in i){s._.dirty=1;break} -switch(m["text-anchor"]){case"start":s.textpath.style["v-text-align"]="left",s.bbx=s.W/2;break;case"end":s.textpath.style["v-text-align"]="right",s.bbx=-s.W/2;break;default:s.textpath.style["v-text-align"]="center",s.bbx=0} -s.textpath.style["v-text-kern"]=!0}},C=function(b,f,g){b.attrs=b.attrs||{};var h=(b.attrs,Math.pow),i="linear",j=".5 .5";if(b.attrs.gradient=f,f=c(f).replace(a._radial_gradient,function(a,b,c){return i="radial",b&&c&&(b=d(b),c=d(c),h(b-.5,2)+h(c-.5,2)>.25&&(c=e.sqrt(.25-h(b-.5,2))*(2*(c>.5)-1)+.5),j=b+n+c),o}),f=f.split(/\s*\-\s*/),"linear"==i){var k=f.shift();if(k=-d(k),isNaN(k)) -return null} -var l=a._parseDots(f);if(!l) -return null;if(b=b.shape||b.node,l.length){b.removeChild(g),g.on=!0,g.method="none",g.color=l[0].color,g.color2=l[l.length-1].color;for(var m=[],p=0,q=l.length;q>p;p++) -l[p].offset&&m.push(l[p].offset+n+l[p].color);g.colors=m.length?m.join():"0% "+g.color,"radial"==i?(g.type="gradientTitle",g.focus="100%",g.focussize="0 0",g.focusposition=j,g.angle=0):(g.type="gradient",g.angle=(270-k)%360),b.appendChild(g)} -return 1},D=function(b,c){this[0]=this.node=b,b.raphael=!0,this.id=a._oid++,b.raphaelid=this.id,this.X=0,this.Y=0,this.attrs={},this.paper=c,this.matrix=a.matrix(),this._={transform:[],sx:1,sy:1,dx:0,dy:0,deg:0,dirty:1,dirtyT:1},!c.bottom&&(c.bottom=this),this.prev=c.top,c.top&&(c.top.next=this),c.top=this,this.next=null},E=a.el;D.prototype=E,E.constructor=D,E.transform=function(b){if(null==b) -return this._.transform;var d,e=this.paper._viewBoxShift,f=e?"s"+[e.scale,e.scale]+"-1-1t"+[e.dx,e.dy]:o;e&&(d=b=c(b).replace(/\.{3}|\u2026/g,this._.transform||o)),a._extractTransform(this,f+b);var g,h=this.matrix.clone(),i=this.skew,j=this.node,k=~c(this.attrs.fill).indexOf("-"),l=!c(this.attrs.fill).indexOf("url(");if(h.translate(1,1),l||k||"image"==this.type) -if(i.matrix="1 0 0 1",i.offset="0 0",g=h.split(),k&&g.noRotation||!g.isSimple){j.style.filter=h.toFilter();var m=this.getBBox(),p=this.getBBox(1),q=m.x-p.x,r=m.y-p.y;j.coordorigin=q* -u+n+r* -u,z(this,1,1,q,r,0)}else -j.style.filter=o,z(this,g.scalex,g.scaley,g.dx,g.dy,g.rotate);else -j.style.filter=o,i.matrix=c(h),i.offset=h.offset();return null!==d&&(this._.transform=d,a._extractTransform(this,d)),this},E.rotate=function(a,b,e){if(this.removed) -return this;if(null!=a){if(a=c(a).split(k),a.length-1&&(b=d(a[1]),e=d(a[2])),a=d(a[0]),null==e&&(b=e),null==b||null==e){var f=this.getBBox(1);b=f.x+f.width/2,e=f.y+f.height/2} -return this._.dirtyT=1,this.transform(this._.transform.concat([["r",a,b,e]])),this}},E.translate=function(a,b){return this.removed?this:(a=c(a).split(k),a.length-1&&(b=d(a[1])),a=d(a[0])||0,b=+b||0,this._.bbox&&(this._.bbox.x+=a,this._.bbox.y+=b),this.transform(this._.transform.concat([["t",a,b]])),this)},E.scale=function(a,b,e,f){if(this.removed) -return this;if(a=c(a).split(k),a.length-1&&(b=d(a[1]),e=d(a[2]),f=d(a[3]),isNaN(e)&&(e=null),isNaN(f)&&(f=null)),a=d(a[0]),null==b&&(b=a),null==f&&(e=f),null==e||null==f) -var g=this.getBBox(1);return e=null==e?g.x+g.width/2:e,f=null==f?g.y+g.height/2:f,this.transform(this._.transform.concat([["s",a,b,e,f]])),this._.dirtyT=1,this},E.hide=function(){return!this.removed&&(this.node.style.display="none"),this},E.show=function(){return!this.removed&&(this.node.style.display=o),this},E.auxGetBBox=a.el.getBBox,E.getBBox=function(){var a=this.auxGetBBox();if(this.paper&&this.paper._viewBoxShift){var b={},c=1/this.paper._viewBoxShift.scale;return b.x=a.x-this.paper._viewBoxShift.dx,b.x*=c,b.y=a.y-this.paper._viewBoxShift.dy,b.y*=c,b.width=a.width*c,b.height=a.height*c,b.x2=b.x+b.width,b.y2=b.y+b.height,b} -return a},E._getBBox=function(){return this.removed?{}:{x:this.X+(this.bbx||0)-this.W/2,y:this.Y-this.H,width:this.W,height:this.H}},E.remove=function(){if(!this.removed&&this.node.parentNode){this.paper.__set__&&this.paper.__set__.exclude(this),a.eve.unbind("raphael.*.*."+this.id),a._tear(this,this.paper),this.node.parentNode.removeChild(this.node),this.shape&&this.shape.parentNode.removeChild(this.shape);for(var b in this) -this[b]="function"==typeof this[b]?a._removedFactory(b):null;this.removed=!0}},E.attr=function(c,d){if(this.removed) -return this;if(null==c){var e={};for(var f in this.attrs) -this.attrs[b](f)&&(e[f]=this.attrs[f]);return e.gradient&&"none"==e.fill&&(e.fill=e.gradient)&&delete e.gradient,e.transform=this._.transform,e} -if(null==d&&a.is(c,"string")){if(c==j&&"none"==this.attrs.fill&&this.attrs.gradient) -return this.attrs.gradient;for(var g=c.split(k),h={},i=0,m=g.length;m>i;i++) -c=g[i],c in this.attrs?h[c]=this.attrs[c]:a.is(this.paper.customAttributes[c],"function")?h[c]=this.paper.customAttributes[c].def:h[c]=a._availableAttrs[c];return m-1?h:h[g[0]]} -if(this.attrs&&null==d&&a.is(c,"array")){for(h={},i=0,m=c.length;m>i;i++) -h[c[i]]=this.attr(c[i]);return h} -var n;null!=d&&(n={},n[c]=d),null==d&&a.is(c,"object")&&(n=c);for(var o in n) -l("raphael.attr."+o+"."+this.id,this,n[o]);if(n){for(o in this.paper.customAttributes) -if(this.paper.customAttributes[b](o)&&n[b](o)&&a.is(this.paper.customAttributes[o],"function")){var p=this.paper.customAttributes[o].apply(this,[].concat(n[o]));this.attrs[o]=n[o];for(var q in p) -p[b](q)&&(n[q]=p[q])} -n.text&&"text"==this.type&&(this.textpath.string=n.text),B(this,n)} -return this},E.toFront=function(){return!this.removed&&this.node.parentNode.appendChild(this.node),this.paper&&this.paper.top!=this&&a._tofront(this,this.paper),this},E.toBack=function(){return this.removed?this:(this.node.parentNode.firstChild!=this.node&&(this.node.parentNode.insertBefore(this.node,this.node.parentNode.firstChild),a._toback(this,this.paper)),this)},E.insertAfter=function(b){return this.removed?this:(b.constructor==a.st.constructor&&(b=b[b.length-1]),b.node.nextSibling?b.node.parentNode.insertBefore(this.node,b.node.nextSibling):b.node.parentNode.appendChild(this.node),a._insertafter(this,b,this.paper),this)},E.insertBefore=function(b){return this.removed?this:(b.constructor==a.st.constructor&&(b=b[0]),b.node.parentNode.insertBefore(this.node,b.node),a._insertbefore(this,b,this.paper),this)},E.blur=function(b){var c=this.node.runtimeStyle,d=c.filter;return d=d.replace(r,o),0!==+b?(this.attrs.blur=b,c.filter=d+n+m+".Blur(pixelradius="+(+b||1.5)+")",c.margin=a.format("-{0}px 0 0 -{0}px",f(+b||1.5))):(c.filter=d,c.margin=0,delete this.attrs.blur),this},a._engine.path=function(a,b){var c=F("shape");c.style.cssText=t,c.coordsize=u+n+u,c.coordorigin=b.coordorigin;var d=new D(c,b),e={fill:"none",stroke:"#000"};a&&(e.path=a),d.type="path",d.path=[],d.Path=o,B(d,e),b.canvas.appendChild(c);var f=F("skew");return f.on=!0,c.appendChild(f),d.skew=f,d.transform(o),d},a._engine.rect=function(b,c,d,e,f,g){var h=a._rectPath(c,d,e,f,g),i=b.path(h),j=i.attrs;return i.X=j.x=c,i.Y=j.y=d,i.W=j.width=e,i.H=j.height=f,j.r=g,j.path=h,i.type="rect",i},a._engine.ellipse=function(a,b,c,d,e){{var f=a.path();f.attrs} -return f.X=b-d,f.Y=c-e,f.W=2*d,f.H=2*e,f.type="ellipse",B(f,{cx:b,cy:c,rx:d,ry:e}),f},a._engine.circle=function(a,b,c,d){{var e=a.path();e.attrs} -return e.X=b-d,e.Y=c-d,e.W=e.H=2*d,e.type="circle",B(e,{cx:b,cy:c,r:d}),e},a._engine.image=function(b,c,d,e,f,g){var h=a._rectPath(d,e,f,g),i=b.path(h).attr({stroke:"none"}),k=i.attrs,l=i.node,m=l.getElementsByTagName(j)[0];return k.src=c,i.X=k.x=d,i.Y=k.y=e,i.W=k.width=f,i.H=k.height=g,k.path=h,i.type="image",m.parentNode==l&&l.removeChild(m),m.rotate=!0,m.src=c,m.type="tile",i._.fillpos=[d,e],i._.fillsize=[f,g],l.appendChild(m),z(i,1,1,0,0,0),i},a._engine.text=function(b,d,e,g){var h=F("shape"),i=F("path"),j=F("textpath");d=d||0,e=e||0,g=g||"",i.v=a.format("m{0},{1}l{2},{1}",f(d*u),f(e*u),f(d*u)+1),i.textpathok=!0,j.string=c(g),j.on=!0,h.style.cssText=t,h.coordsize=u+n+u,h.coordorigin="0 0";var k=new D(h,b),l={fill:"#000",stroke:"none",font:a._availableAttrs.font,text:g};k.shape=h,k.path=i,k.textpath=j,k.type="text",k.attrs.text=c(g),k.attrs.x=d,k.attrs.y=e,k.attrs.w=1,k.attrs.h=1,B(k,l),h.appendChild(j),h.appendChild(i),b.canvas.appendChild(h);var m=F("skew");return m.on=!0,h.appendChild(m),k.skew=m,k.transform(o),k},a._engine.setSize=function(b,c){var d=this.canvas.style;return this.width=b,this.height=c,b==+b&&(b+="px"),c==+c&&(c+="px"),d.width=b,d.height=c,d.clip="rect(0 "+b+" "+c+" 0)",this._viewBox&&a._engine.setViewBox.apply(this,this._viewBox),this},a._engine.setViewBox=function(b,c,d,e,f){a.eve("raphael.setViewBox",this,this._viewBox,[b,c,d,e,f]);var g,h,i=this.getSize(),j=i.width,k=i.height;return f&&(g=k/e,h=j/d,j>d*g&&(b-=(j-d*g)/2/g),k>e*h&&(c-=(k-e*h)/2/h)),this._viewBox=[b,c,d,e,!!f],this._viewBoxShift={dx:-b,dy:-c,scale:i},this.forEach(function(a){a.transform("...")}),this};var F;a._engine.initWin=function(a){var b=a.document;b.styleSheets.length<31?b.createStyleSheet().addRule(".rvml","behavior:url(#default#VML)"):b.styleSheets[0].addRule(".rvml","behavior:url(#default#VML)");try{!b.namespaces.rvml&&b.namespaces.add("rvml","urn:schemas-microsoft-com:vml"),F=function(a){return b.createElement("')}}catch(c){F=function(a){return b.createElement("<"+a+' xmlns="urn:schemas-microsoft.com:vml" class="rvml">')}}},a._engine.initWin(a._g.win),a._engine.create=function(){var b=a._getContainer.apply(0,arguments),c=b.container,d=b.height,e=b.width,f=b.x,g=b.y;if(!c) -throw new Error("VML container not found.");var h=new a._Paper,i=h.canvas=a._g.doc.createElement("div"),j=i.style;return f=f||0,g=g||0,e=e||512,d=d||342,h.width=e,h.height=d,e==+e&&(e+="px"),d==+d&&(d+="px"),h.coordsize=1e3*u+n+1e3*u,h.coordorigin="0 0",h.span=a._g.doc.createElement("span"),h.span.style.cssText="position:absolute;left:-9999em;top:-9999em;padding:0;margin:0;line-height:1;",i.appendChild(h.span),j.cssText=a.format("top:0;left:0;width:{0};height:{1};display:inline-block;position:relative;clip:rect(0 {0} {1} 0);overflow:hidden",e,d),1==c?(a._g.doc.body.appendChild(i),j.left=f+"px",j.top=g+"px",j.position="absolute"):c.firstChild?c.insertBefore(i,c.firstChild):c.appendChild(i),h.renderfix=function(){},h},a.prototype.clear=function(){a.eve("raphael.clear",this),this.canvas.innerHTML=o,this.span=a._g.doc.createElement("span"),this.span.style.cssText="position:absolute;left:-9999em;top:-9999em;padding:0;margin:0;line-height:1;display:inline;",this.canvas.appendChild(this.span),this.bottom=this.top=null},a.prototype.remove=function(){a.eve("raphael.remove",this),this.canvas.parentNode.removeChild(this.canvas);for(var b in this) -this[b]="function"==typeof this[b]?a._removedFactory(b):null;return!0};var G=a.st;for(var H in E) -E[b](H)&&!G[b](H)&&(G[H]=function(a){return function(){var b=arguments;return this.forEach(function(c){c[a].apply(c,b)})}} -(H))}});JustGage=function(config){var obj=this;if(config===null||config===undefined){console.log('* justgage: Make sure to pass options to the constructor!');return false;} -var node;if(config.id!==null&&config.id!==undefined){node=document.getElementById(config.id);if(!node){console.log('* justgage: No element with id : %s found',config.id);return false;}}else if(config.parentNode!==null&&config.parentNode!==undefined){node=config.parentNode;}else{console.log('* justgage: Make sure to pass the existing element id or parentNode to the constructor.');return false;} -var dataset=node.dataset?node.dataset:{};var defaults=(config.defaults!==null&&config.defaults!==undefined)?config.defaults:false;if(defaults!==false){config=extend({},config,defaults);delete config.defaults;} -obj.config={id:config.id,value:kvLookup('value',config,dataset,0,'float'),defaults:kvLookup('defaults',config,dataset,0,false),parentNode:kvLookup('parentNode',config,dataset,null),width:kvLookup('width',config,dataset,null),height:kvLookup('height',config,dataset,null),title:kvLookup('title',config,dataset,""),titleFontColor:kvLookup('titleFontColor',config,dataset,"#999999"),titleFontFamily:kvLookup('titleFontFamily',config,dataset,"sans-serif"),titlePosition:kvLookup('titlePosition',config,dataset,"above"),valueFontColor:kvLookup('valueFontColor',config,dataset,"#010101"),valueFontFamily:kvLookup('valueFontFamily',config,dataset,"Arial"),symbol:kvLookup('symbol',config,dataset,''),min:kvLookup('min',config,dataset,0,'float'),max:kvLookup('max',config,dataset,100,'float'),reverse:kvLookup('reverse',config,dataset,false),humanFriendlyDecimal:kvLookup('humanFriendlyDecimal',config,dataset,0),textRenderer:kvLookup('textRenderer',config,dataset,null),gaugeWidthScale:kvLookup('gaugeWidthScale',config,dataset,1.0),gaugeColor:kvLookup('gaugeColor',config,dataset,"#edebeb"),label:kvLookup('label',config,dataset,''),labelFontColor:kvLookup('labelFontColor',config,dataset,"#b3b3b3"),shadowOpacity:kvLookup('shadowOpacity',config,dataset,0.2),shadowSize:kvLookup('shadowSize',config,dataset,5),shadowVerticalOffset:kvLookup('shadowVerticalOffset',config,dataset,3),levelColors:kvLookup('levelColors',config,dataset,["#a9d70b","#f9c802","#ff0000"],'array',','),startAnimationTime:kvLookup('startAnimationTime',config,dataset,700),startAnimationType:kvLookup('startAnimationType',config,dataset,'>'),refreshAnimationTime:kvLookup('refreshAnimationTime',config,dataset,700),refreshAnimationType:kvLookup('refreshAnimationType',config,dataset,'>'),donutStartAngle:kvLookup('donutStartAngle',config,dataset,90),valueMinFontSize:kvLookup('valueMinFontSize',config,dataset,16),titleMinFontSize:kvLookup('titleMinFontSize',config,dataset,10),labelMinFontSize:kvLookup('labelMinFontSize',config,dataset,10),minLabelMinFontSize:kvLookup('minLabelMinFontSize',config,dataset,10),maxLabelMinFontSize:kvLookup('maxLabelMinFontSize',config,dataset,10),hideValue:kvLookup('hideValue',config,dataset,false),hideMinMax:kvLookup('hideMinMax',config,dataset,false),hideInnerShadow:kvLookup('hideInnerShadow',config,dataset,false),humanFriendly:kvLookup('humanFriendly',config,dataset,false),noGradient:kvLookup('noGradient',config,dataset,false),donut:kvLookup('donut',config,dataset,false),relativeGaugeSize:kvLookup('relativeGaugeSize',config,dataset,false),counter:kvLookup('counter',config,dataset,false),decimals:kvLookup('decimals',config,dataset,0),customSectors:kvLookup('customSectors',config,dataset,[]),formatNumber:kvLookup('formatNumber',config,dataset,false),pointer:kvLookup('pointer',config,dataset,false),pointerOptions:kvLookup('pointerOptions',config,dataset,[])};var -canvasW,canvasH,widgetW,widgetH,aspect,dx,dy,titleFontSize,titleX,titleY,valueFontSize,valueX,valueY,labelFontSize,labelX,labelY,minFontSize,minX,minY,maxFontSize,maxX,maxY;if(obj.config.value>obj.config.max) -obj.config.value=obj.config.max;if(obj.config.valuecanvasH){widgetH=canvasH;widgetW=widgetH;}else if(canvasWcanvasH){aspect=widgetH/canvasH;widgetH=widgetH/aspect;widgetW=widgetH/aspect;}}else{widgetW=canvasW;widgetH=widgetW;} -dx=(canvasW-widgetW)/2;dy=(canvasH-widgetH)/2;titleFontSize=((widgetH/8)>10)?(widgetH/10):10;titleX=dx+widgetW/2;titleY=dy+widgetH/11;valueFontSize=((widgetH/6.4)>16)?(widgetH/5.4):18;valueX=dx+widgetW/2;if(obj.config.label!==''){valueY=dy+widgetH/1.85;}else{valueY=dy+widgetH/1.7;} -labelFontSize=((widgetH/16)>10)?(widgetH/16):10;labelX=dx+widgetW/2;labelY=valueY+labelFontSize;minFontSize=((widgetH/16)>10)?(widgetH/16):10;minX=dx+(widgetW/10)+(widgetW/6.666666666666667*obj.config.gaugeWidthScale)/2;minY=labelY;maxFontSize=((widgetH/16)>10)?(widgetH/16):10;maxX=dx+widgetW-(widgetW/10)-(widgetW/6.666666666666667*obj.config.gaugeWidthScale)/2;maxY=labelY;}else{if(canvasW>canvasH){widgetH=canvasH;widgetW=widgetH*1.25;if(widgetW>canvasW){aspect=widgetW/canvasW;widgetW=widgetW/aspect;widgetH=widgetH/aspect;}}else if(canvasWcanvasH){aspect=widgetH/canvasH;widgetH=widgetH/aspect;widgetW=widgetH/aspect;}}else{widgetW=canvasW;widgetH=widgetW*0.75;} -dx=(canvasW-widgetW)/2;dy=(canvasH-widgetH)/2;if(obj.config.titlePosition==='below'){dy-=(widgetH/6.4);} -titleFontSize=((widgetH/8)>obj.config.titleMinFontSize)?(widgetH/10):obj.config.titleMinFontSize;titleX=dx+widgetW/2;titleY=dy+(obj.config.titlePosition==='below'?(widgetH*1.07):(widgetH/6.4));valueFontSize=((widgetH/6.5)>obj.config.valueMinFontSize)?(widgetH/6.5):obj.config.valueMinFontSize;valueX=dx+widgetW/2;valueY=dy+widgetH/1.275;labelFontSize=((widgetH/16)>obj.config.labelMinFontSize)?(widgetH/16):obj.config.labelMinFontSize;labelX=dx+widgetW/2;labelY=valueY+valueFontSize/2+5;minFontSize=((widgetH/16)>obj.config.minLabelMinFontSize)?(widgetH/16):obj.config.minLabelMinFontSize;minX=dx+(widgetW/10)+(widgetW/6.666666666666667*obj.config.gaugeWidthScale)/2;minY=labelY;maxFontSize=((widgetH/16)>obj.config.maxLabelMinFontSize)?(widgetH/16):obj.config.maxLabelMinFontSize;maxX=dx+widgetW-(widgetW/10)-(widgetW/6.666666666666667*obj.config.gaugeWidthScale)/2;maxY=labelY;} -obj.params={canvasW:canvasW,canvasH:canvasH,widgetW:widgetW,widgetH:widgetH,dx:dx,dy:dy,titleFontSize:titleFontSize,titleX:titleX,titleY:titleY,valueFontSize:valueFontSize,valueX:valueX,valueY:valueY,labelFontSize:labelFontSize,labelX:labelX,labelY:labelY,minFontSize:minFontSize,minX:minX,minY:minY,maxFontSize:maxFontSize,maxX:maxX,maxY:maxY};canvasW,canvasH,widgetW,widgetH,aspect,dx,dy,titleFontSize,titleX,titleY,valueFontSize,valueX,valueY,labelFontSize,labelX,labelY,minFontSize,minX,minY,maxFontSize,maxX,maxY=null;obj.canvas.customAttributes.pki=function(value,min,max,w,h,dx,dy,gws,donut,reverse){var alpha,Ro,Ri,Cx,Cy,Xo,Yo,Xi,Yi,path;if(donut){alpha=(1-2*(value-min)/(max-min))*Math.PI;Ro=w/2-w/7;Ri=Ro-w/6.666666666666667*gws;Cx=w/2+dx;Cy=h/1.95+dy;Xo=w/2+dx+Ro*Math.cos(alpha);Yo=h-(h-Cy)-Ro*Math.sin(alpha);Xi=w/2+dx+Ri*Math.cos(alpha);Yi=h-(h-Cy)-Ri*Math.sin(alpha);path="M"+(Cx-Ri)+","+Cy+" ";path+="L"+(Cx-Ro)+","+Cy+" ";if(value>((max-min)/2)){path+="A"+Ro+","+Ro+" 0 0 1 "+(Cx+Ro)+","+Cy+" ";} -path+="A"+Ro+","+Ro+" 0 0 1 "+Xo+","+Yo+" ";path+="L"+Xi+","+Yi+" ";if(value>((max-min)/2)){path+="A"+Ri+","+Ri+" 0 0 0 "+(Cx+Ri)+","+Cy+" ";} -path+="A"+Ri+","+Ri+" 0 0 0 "+(Cx-Ri)+","+Cy+" ";path+="Z ";return{path:path};}else{alpha=(1-(value-min)/(max-min))*Math.PI;Ro=w/2-w/10;Ri=Ro-w/6.666666666666667*gws;Cx=w/2+dx;Cy=h/1.25+dy;Xo=w/2+dx+Ro*Math.cos(alpha);Yo=h-(h-Cy)-Ro*Math.sin(alpha);Xi=w/2+dx+Ri*Math.cos(alpha);Yi=h-(h-Cy)-Ri*Math.sin(alpha);path="M"+(Cx-Ri)+","+Cy+" ";path+="L"+(Cx-Ro)+","+Cy+" ";path+="A"+Ro+","+Ro+" 0 0 1 "+Xo+","+Yo+" ";path+="L"+Xi+","+Yi+" ";path+="A"+Ri+","+Ri+" 0 0 0 "+(Cx-Ri)+","+Cy+" ";path+="Z ";return{path:path};} -alpha,Ro,Ri,Cx,Cy,Xo,Yo,Xi,Yi,path=null;};obj.canvas.customAttributes.ndl=function(value,min,max,w,h,dx,dy,gws,donut){var dlt=w*3.5/100;var dlb=w/15;var dw=w/100;if(obj.config.pointerOptions.toplength!=null&&obj.config.pointerOptions.toplength!=undefined) -dlt=obj.config.pointerOptions.toplength;if(obj.config.pointerOptions.bottomlength!=null&&obj.config.pointerOptions.bottomlength!=undefined) -dlb=obj.config.pointerOptions.bottomlength;if(obj.config.pointerOptions.bottomwidth!=null&&obj.config.pointerOptions.bottomwidth!=undefined) -dw=obj.config.pointerOptions.bottomwidth;var alpha,Ro,Ri,Cx,Cy,Xo,Yo,Xi,Yi,Xc,Yc,Xz,Yz,Xa,Ya,Xb,Yb,path;if(donut){alpha=(1-2*(value-min)/(max-min))*Math.PI;Ro=w/2-w/7;Ri=Ro-w/6.666666666666667*gws;Cx=w/2+dx;Cy=h/1.95+dy;Xo=w/2+dx+Ro*Math.cos(alpha);Yo=h-(h-Cy)-Ro*Math.sin(alpha);Xi=w/2+dx+Ri*Math.cos(alpha);Yi=h-(h-Cy)-Ri*Math.sin(alpha);Xc=Xo+dlt*Math.cos(alpha);Yc=Yo-dlt*Math.sin(alpha);Xz=Xi-dlb*Math.cos(alpha);Yz=Yi+dlb*Math.sin(alpha);Xa=Xz+dw*Math.sin(alpha);Ya=Yz+dw*Math.cos(alpha);Xb=Xz-dw*Math.sin(alpha);Yb=Yz-dw*Math.cos(alpha);path='M'+Xa+','+Ya+' ';path+='L'+Xb+','+Yb+' ';path+='L'+Xc+','+Yc+' ';path+='Z ';return{path:path};}else{alpha=(1-(value-min)/(max-min))*Math.PI;Ro=w/2-w/10;Ri=Ro-w/6.666666666666667*gws;Cx=w/2+dx;Cy=h/1.25+dy;Xo=w/2+dx+Ro*Math.cos(alpha);Yo=h-(h-Cy)-Ro*Math.sin(alpha);Xi=w/2+dx+Ri*Math.cos(alpha);Yi=h-(h-Cy)-Ri*Math.sin(alpha);Xc=Xo+dlt*Math.cos(alpha);Yc=Yo-dlt*Math.sin(alpha);Xz=Xi-dlb*Math.cos(alpha);Yz=Yi+dlb*Math.sin(alpha);Xa=Xz+dw*Math.sin(alpha);Ya=Yz+dw*Math.cos(alpha);Xb=Xz-dw*Math.sin(alpha);Yb=Yz-dw*Math.cos(alpha);path='M'+Xa+','+Ya+' ';path+='L'+Xb+','+Yb+' ';path+='L'+Xc+','+Yc+' ';path+='Z ';return{path:path};} -alpha,Ro,Ri,Cx,Cy,Xo,Yo,Xi,Yi,Xc,Yc,Xz,Yz,Xa,Ya,Xb,Yb,path=null;};obj.gauge=obj.canvas.path().attr({"stroke":"none","fill":obj.config.gaugeColor,pki:[obj.config.max,obj.config.min,obj.config.max,obj.params.widgetW,obj.params.widgetH,obj.params.dx,obj.params.dy,obj.config.gaugeWidthScale,obj.config.donut,obj.config.reverse]});obj.level=obj.canvas.path().attr({"stroke":"none","fill":getColor(obj.config.value,(obj.config.value-obj.config.min)/(obj.config.max-obj.config.min),obj.config.levelColors,obj.config.noGradient,obj.config.customSectors),pki:[obj.config.min,obj.config.min,obj.config.max,obj.params.widgetW,obj.params.widgetH,obj.params.dx,obj.params.dy,obj.config.gaugeWidthScale,obj.config.donut,obj.config.reverse]});if(obj.config.donut){obj.level.transform("r"+obj.config.donutStartAngle+", "+(obj.params.widgetW/2+obj.params.dx)+", "+(obj.params.widgetH/1.95+obj.params.dy));} -if(obj.config.pointer){obj.needle=obj.canvas.path().attr({"stroke":(obj.config.pointerOptions.stroke!==null&&obj.config.pointerOptions.stroke!==undefined)?obj.config.pointerOptions.stroke:"none","stroke-width":(obj.config.pointerOptions.stroke_width!==null&&obj.config.pointerOptions.stroke_width!==undefined)?obj.config.pointerOptions.stroke_width:0,"stroke-linecap":(obj.config.pointerOptions.stroke_linecap!==null&&obj.config.pointerOptions.stroke_linecap!==undefined)?obj.config.pointerOptions.stroke_linecap:"square","fill":(obj.config.pointerOptions.color!==null&&obj.config.pointerOptions.color!==undefined)?obj.config.pointerOptions.color:"#000000",ndl:[obj.config.min,obj.config.min,obj.config.max,obj.params.widgetW,obj.params.widgetH,obj.params.dx,obj.params.dy,obj.config.gaugeWidthScale,obj.config.donut]});if(obj.config.donut){obj.needle.transform("r"+obj.config.donutStartAngle+", "+(obj.params.widgetW/2+obj.params.dx)+", "+(obj.params.widgetH/1.95+obj.params.dy));}} -obj.txtTitle=obj.canvas.text(obj.params.titleX,obj.params.titleY,obj.config.title);obj.txtTitle.attr({"font-size":obj.params.titleFontSize,"font-weight":"bold","font-family":obj.config.titleFontFamily,"fill":obj.config.titleFontColor,"fill-opacity":"1"});setDy(obj.txtTitle,obj.params.titleFontSize,obj.params.titleY);obj.txtValue=obj.canvas.text(obj.params.valueX,obj.params.valueY,0);obj.txtValue.attr({"font-size":obj.params.valueFontSize,"font-weight":"bold","font-family":obj.config.valueFontFamily,"fill":obj.config.valueFontColor,"fill-opacity":"0"});setDy(obj.txtValue,obj.params.valueFontSize,obj.params.valueY);obj.txtLabel=obj.canvas.text(obj.params.labelX,obj.params.labelY,obj.config.label);obj.txtLabel.attr({"font-size":obj.params.labelFontSize,"font-weight":"normal","font-family":"Arial","fill":obj.config.labelFontColor,"fill-opacity":"0"});setDy(obj.txtLabel,obj.params.labelFontSize,obj.params.labelY);var min=obj.config.min;if(obj.config.reverse){min=obj.config.max;} -obj.txtMinimum=min;if(obj.config.humanFriendly){obj.txtMinimum=humanFriendlyNumber(min,obj.config.humanFriendlyDecimal);}else if(obj.config.formatNumber){obj.txtMinimum=formatNumber(min);} -obj.txtMin=obj.canvas.text(obj.params.minX,obj.params.minY,obj.txtMinimum);obj.txtMin.attr({"font-size":obj.params.minFontSize,"font-weight":"normal","font-family":"Arial","fill":obj.config.labelFontColor,"fill-opacity":(obj.config.hideMinMax||obj.config.donut)?"0":"1"});setDy(obj.txtMin,obj.params.minFontSize,obj.params.minY);var max=obj.config.max;if(obj.config.reverse){max=obj.config.min;} -obj.txtMaximum=max;if(obj.config.humanFriendly){obj.txtMaximum=humanFriendlyNumber(max,obj.config.humanFriendlyDecimal);}else if(obj.config.formatNumber){obj.txtMaximum=formatNumber(max);} -obj.txtMax=obj.canvas.text(obj.params.maxX,obj.params.maxY,obj.txtMaximum);obj.txtMax.attr({"font-size":obj.params.maxFontSize,"font-weight":"normal","font-family":"Arial","fill":obj.config.labelFontColor,"fill-opacity":(obj.config.hideMinMax||obj.config.donut)?"0":"1"});setDy(obj.txtMax,obj.params.maxFontSize,obj.params.maxY);var defs=obj.canvas.canvas.childNodes[1];var svg="http://www.w3.org/2000/svg";if(ie!=='undefined'&&ie<9){} -else if(ie!=='undefined'){onCreateElementNsReady(function(){obj.generateShadow(svg,defs);});}else{obj.generateShadow(svg,defs);} -defs,svg=null;if(obj.config.textRenderer){obj.originalValue=obj.config.textRenderer(obj.originalValue);}else if(obj.config.humanFriendly){obj.originalValue=humanFriendlyNumber(obj.originalValue,obj.config.humanFriendlyDecimal)+obj.config.symbol;}else if(obj.config.formatNumber){obj.originalValue=formatNumber(obj.originalValue)+obj.config.symbol;}else{obj.originalValue=(obj.originalValue*1).toFixed(obj.config.decimals)+obj.config.symbol;} -if(obj.config.counter===true){eve.on("raphael.anim.frame."+(obj.level.id),function(){var currentValue=obj.level.attr("pki")[0];if(obj.config.reverse){currentValue=(obj.config.max*1)+(obj.config.min*1)-(obj.level.attr("pki")[0]*1);} -if(obj.config.textRenderer){obj.txtValue.attr("text",obj.config.textRenderer(Math.floor(currentValue)));}else if(obj.config.humanFriendly){obj.txtValue.attr("text",humanFriendlyNumber(Math.floor(currentValue),obj.config.humanFriendlyDecimal)+obj.config.symbol);}else if(obj.config.formatNumber){obj.txtValue.attr("text",formatNumber(Math.floor(currentValue))+obj.config.symbol);}else{obj.txtValue.attr("text",(currentValue*1).toFixed(obj.config.decimals)+obj.config.symbol);} -setDy(obj.txtValue,obj.params.valueFontSize,obj.params.valueY);currentValue=null;});eve.on("raphael.anim.finish."+(obj.level.id),function(){obj.txtValue.attr({"text":obj.originalValue});setDy(obj.txtValue,obj.params.valueFontSize,obj.params.valueY);});}else{eve.on("raphael.anim.start."+(obj.level.id),function(){obj.txtValue.attr({"text":obj.originalValue});setDy(obj.txtValue,obj.params.valueFontSize,obj.params.valueY);});} -var rvl=obj.config.value;if(obj.config.reverse){rvl=(obj.config.max*1)+(obj.config.min*1)-(obj.config.value*1);} -obj.level.animate({pki:[rvl,obj.config.min,obj.config.max,obj.params.widgetW,obj.params.widgetH,obj.params.dx,obj.params.dy,obj.config.gaugeWidthScale,obj.config.donut,obj.config.reverse]},obj.config.startAnimationTime,obj.config.startAnimationType);if(obj.config.pointer){obj.needle.animate({ndl:[rvl,obj.config.min,obj.config.max,obj.params.widgetW,obj.params.widgetH,obj.params.dx,obj.params.dy,obj.config.gaugeWidthScale,obj.config.donut]},obj.config.startAnimationTime,obj.config.startAnimationType);} -obj.txtValue.animate({"fill-opacity":(obj.config.hideValue)?"0":"1"},obj.config.startAnimationTime,obj.config.startAnimationType);obj.txtLabel.animate({"fill-opacity":"1"},obj.config.startAnimationTime,obj.config.startAnimationType);};JustGage.prototype.refresh=function(val,max){var obj=this;var displayVal,color,max=max||null;if(max!==null){obj.config.max=max;obj.txtMaximum=obj.config.max;if(obj.config.humanFriendly){obj.txtMaximum=humanFriendlyNumber(obj.config.max,obj.config.humanFriendlyDecimal);}else if(obj.config.formatNumber){obj.txtMaximum=formatNumber(obj.config.max);} -if(!obj.config.reverse){obj.txtMax.attr({"text":obj.txtMaximum});setDy(obj.txtMax,obj.params.maxFontSize,obj.params.maxY);}else{obj.txtMin.attr({"text":obj.txtMaximum});setDy(obj.txtMin,obj.params.minFontSize,obj.params.minY);}} -displayVal=val;if((val*1)>(obj.config.max*1)){val=(obj.config.max*1);} -if((val*1)<(obj.config.min*1)){val=(obj.config.min*1);} -color=getColor(val,(val-obj.config.min)/(obj.config.max-obj.config.min),obj.config.levelColors,obj.config.noGradient,obj.config.customSectors);if(obj.config.textRenderer){displayVal=obj.config.textRenderer(displayVal);}else if(obj.config.humanFriendly){displayVal=humanFriendlyNumber(displayVal,obj.config.humanFriendlyDecimal)+obj.config.symbol;}else if(obj.config.formatNumber){displayVal=formatNumber((displayVal*1).toFixed(obj.config.decimals))+obj.config.symbol;}else{displayVal=(displayVal*1).toFixed(obj.config.decimals)+obj.config.symbol;} -obj.originalValue=displayVal;obj.config.value=val*1;if(!obj.config.counter){obj.txtValue.attr({"text":displayVal});setDy(obj.txtValue,obj.params.valueFontSize,obj.params.valueY);} -var rvl=obj.config.value;if(obj.config.reverse){rvl=(obj.config.max*1)+(obj.config.min*1)-(obj.config.value*1);} -obj.level.animate({pki:[rvl,obj.config.min,obj.config.max,obj.params.widgetW,obj.params.widgetH,obj.params.dx,obj.params.dy,obj.config.gaugeWidthScale,obj.config.donut,obj.config.reverse],"fill":color},obj.config.refreshAnimationTime,obj.config.refreshAnimationType);if(obj.config.pointer){obj.needle.animate({ndl:[rvl,obj.config.min,obj.config.max,obj.params.widgetW,obj.params.widgetH,obj.params.dx,obj.params.dy,obj.config.gaugeWidthScale,obj.config.donut]},obj.config.refreshAnimationTime,obj.config.refreshAnimationType);} -obj,displayVal,color,max=null;};JustGage.prototype.generateShadow=function(svg,defs){var obj=this;var sid="inner-shadow-"+obj.config.id;var gaussFilter,feOffset,feGaussianBlur,feComposite1,feFlood,feComposite2,feComposite3;gaussFilter=document.createElementNS(svg,"filter");gaussFilter.setAttribute("id",sid);defs.appendChild(gaussFilter);feOffset=document.createElementNS(svg,"feOffset");feOffset.setAttribute("dx",0);feOffset.setAttribute("dy",obj.config.shadowVerticalOffset);gaussFilter.appendChild(feOffset);feGaussianBlur=document.createElementNS(svg,"feGaussianBlur");feGaussianBlur.setAttribute("result","offset-blur");feGaussianBlur.setAttribute("stdDeviation",obj.config.shadowSize);gaussFilter.appendChild(feGaussianBlur);feComposite1=document.createElementNS(svg,"feComposite");feComposite1.setAttribute("operator","out");feComposite1.setAttribute("in","SourceGraphic");feComposite1.setAttribute("in2","offset-blur");feComposite1.setAttribute("result","inverse");gaussFilter.appendChild(feComposite1);feFlood=document.createElementNS(svg,"feFlood");feFlood.setAttribute("flood-color","black");feFlood.setAttribute("flood-opacity",obj.config.shadowOpacity);feFlood.setAttribute("result","color");gaussFilter.appendChild(feFlood);feComposite2=document.createElementNS(svg,"feComposite");feComposite2.setAttribute("operator","in");feComposite2.setAttribute("in","color");feComposite2.setAttribute("in2","inverse");feComposite2.setAttribute("result","shadow");gaussFilter.appendChild(feComposite2);feComposite3=document.createElementNS(svg,"feComposite");feComposite3.setAttribute("operator","over");feComposite3.setAttribute("in","shadow");feComposite3.setAttribute("in2","SourceGraphic");gaussFilter.appendChild(feComposite3);if(!obj.config.hideInnerShadow){obj.canvas.canvas.childNodes[2].setAttribute("filter","url(#"+sid+")");obj.canvas.canvas.childNodes[3].setAttribute("filter","url(#"+sid+")");} -gaussFilter,feOffset,feGaussianBlur,feComposite1,feFlood,feComposite2,feComposite3=null;};function kvLookup(key,tablea,tableb,defval,datatype,delimiter){var val=defval;var canConvert=false;if(!(key===null||key===undefined)){if(tableb!==null&&tableb!==undefined&&typeof tableb==="object"&&key in tableb){val=tableb[key];canConvert=true;}else if(tablea!==null&&tablea!==undefined&&typeof tablea==="object"&&key in tablea){val=tablea[key];canConvert=true;}else{val=defval;} -if(canConvert===true){if(datatype!==null&&datatype!==undefined){switch(datatype){case'int':val=parseInt(val,10);break;case'float':val=parseFloat(val);break;default:break;}}}} -return val;};function getColor(val,pct,col,noGradient,custSec){var no,inc,colors,percentage,rval,gval,bval,lower,upper,range,rangePct,pctLower,pctUpper,color;var noGradient=noGradient||custSec.length>0;if(custSec.length>0){for(var i=0;icustSec[i].lo&&val<=custSec[i].hi){return custSec[i].color;}}} -no=col.length;if(no===1) -return col[0];inc=(noGradient)?(1/no):(1/(no-1));colors=[];for(i=0;i9)&&elem.node.firstChild.attributes.dy){elem.node.firstChild.attributes.dy.value=0;}} -function getRandomInt(min,max){return Math.floor(Math.random()*(max-min+1))+min;} -function cutHex(str){return(str.charAt(0)=="#")?str.substring(1,7):str;} -function humanFriendlyNumber(n,d){var p,d2,i,s;p=Math.pow;d2=p(10,d);i=7;while(i){s=p(10,i-- *3);if(s<=n){n=Math.round(n*d2/s)/d2+"KMGTPE"[i];}} -return n;} -function formatNumber(x){var parts=x.toString().split(".");parts[0]=parts[0].replace(/\B(?=(\d{3})+(?!\d))/g,",");return parts.join(".");} -function getStyle(oElm,strCssRule){var strValue="";if(document.defaultView&&document.defaultView.getComputedStyle){strValue=document.defaultView.getComputedStyle(oElm,"").getPropertyValue(strCssRule);}else if(oElm.currentStyle){strCssRule=strCssRule.replace(/\-(\w)/g,function(strMatch,p1){return p1.toUpperCase();});strValue=oElm.currentStyle[strCssRule];} -return strValue;} -function onCreateElementNsReady(func){if(document.createElementNS!==undefined){func();}else{setTimeout(function(){onCreateElementNsReady(func);},100);}} -var ie=(function(){var undef,v=3,div=document.createElement('div'),all=div.getElementsByTagName('i');while(div.innerHTML='',all[0]);return v>4?v:undef;} -());function extend(out){out=out||{};for(var i=1;il#$}4M(9jq&>BeA4QV~fmX|+Udl~OUG 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 diff --git a/examples/SmartSwitch/data_src/index.htm b/examples/SmartSwitch/data_src/index.htm deleted file mode 100644 index 6f2c73117..000000000 --- a/examples/SmartSwitch/data_src/index.htm +++ /dev/null @@ -1,599 +0,0 @@ - - - - - - Smart Switch - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - -
-
- - - - - - - - -
- - - - - -
-
- -
-
-
- -
-
-
- -
-
-
-
-
- -
-
- -

-
-
-
- -
-
- - - - - - - - \ No newline at end of file diff --git a/examples/SmartSwitch/data_src/js_css_src/.exclude.files b/examples/SmartSwitch/data_src/js_css_src/.exclude.files deleted file mode 100644 index 955397fa2..000000000 --- a/examples/SmartSwitch/data_src/js_css_src/.exclude.files +++ /dev/null @@ -1,2 +0,0 @@ -/*.js.gz -/.exclude.files diff --git a/examples/SmartSwitch/data_src/js_css_src/ace-drafts/ace.js b/examples/SmartSwitch/data_src/js_css_src/ace-drafts/ace.js deleted file mode 100644 index f54ebb2e1..000000000 --- a/examples/SmartSwitch/data_src/js_css_src/ace-drafts/ace.js +++ /dev/null @@ -1,14 +0,0 @@ -(function(){function o(n){var i=e;n&&(e[n]||(e[n]={}),i=e[n]);if(!i.define||!i.define.packaged)t.original=i.define,i.define=t,i.define.packaged=!0;if(!i.require||!i.require.packaged)r.original=i.require,i.require=r,i.require.packaged=!0}var ACE_NAMESPACE="",e=function(){return this}();!e&&typeof window!="undefined"&&(e=window);if(!ACE_NAMESPACE&&typeof requirejs!="undefined")return;var t=function(e,n,r){if(typeof e!="string"){t.original?t.original.apply(this,arguments):(console.error("dropping module because define wasn't a string."),console.trace());return}arguments.length==2&&(r=n),t.modules[e]||(t.payloads[e]=r,t.modules[e]=null)};t.modules={},t.payloads={};var n=function(e,t,n){if(typeof t=="string"){var i=s(e,t);if(i!=undefined)return n&&n(),i}else if(Object.prototype.toString.call(t)==="[object Array]"){var o=[];for(var u=0,a=t.length;u1&&u(t,"")>-1&&(a=RegExp(this.source,r.replace.call(o(this),"g","")),r.replace.call(e.slice(t.index),a,function(){for(var e=1;et.index&&this.lastIndex--}return t},s||(RegExp.prototype.test=function(e){var t=r.exec.call(this,e);return t&&this.global&&!t[0].length&&this.lastIndex>t.index&&this.lastIndex--,!!t})}),define("ace/lib/es5-shim",["require","exports","module"],function(e,t,n){function r(){}function w(e){try{return Object.defineProperty(e,"sentinel",{}),"sentinel"in e}catch(t){}}function H(e){return e=+e,e!==e?e=0:e!==0&&e!==1/0&&e!==-1/0&&(e=(e>0||-1)*Math.floor(Math.abs(e))),e}function B(e){var t=typeof e;return e===null||t==="undefined"||t==="boolean"||t==="number"||t==="string"}function j(e){var t,n,r;if(B(e))return e;n=e.valueOf;if(typeof n=="function"){t=n.call(e);if(B(t))return t}r=e.toString;if(typeof r=="function"){t=r.call(e);if(B(t))return t}throw new TypeError}Function.prototype.bind||(Function.prototype.bind=function(t){var n=this;if(typeof n!="function")throw new TypeError("Function.prototype.bind called on incompatible "+n);var i=u.call(arguments,1),s=function(){if(this instanceof s){var e=n.apply(this,i.concat(u.call(arguments)));return Object(e)===e?e:this}return n.apply(t,i.concat(u.call(arguments)))};return n.prototype&&(r.prototype=n.prototype,s.prototype=new r,r.prototype=null),s});var i=Function.prototype.call,s=Array.prototype,o=Object.prototype,u=s.slice,a=i.bind(o.toString),f=i.bind(o.hasOwnProperty),l,c,h,p,d;if(d=f(o,"__defineGetter__"))l=i.bind(o.__defineGetter__),c=i.bind(o.__defineSetter__),h=i.bind(o.__lookupGetter__),p=i.bind(o.__lookupSetter__);if([1,2].splice(0).length!=2)if(!function(){function e(e){var t=new Array(e+2);return t[0]=t[1]=0,t}var t=[],n;t.splice.apply(t,e(20)),t.splice.apply(t,e(26)),n=t.length,t.splice(5,0,"XXX"),n+1==t.length;if(n+1==t.length)return!0}())Array.prototype.splice=function(e,t){var n=this.length;e>0?e>n&&(e=n):e==void 0?e=0:e<0&&(e=Math.max(n+e,0)),e+ta)for(h=l;h--;)this[f+h]=this[a+h];if(s&&e===c)this.length=c,this.push.apply(this,i);else{this.length=c+s;for(h=0;h>>0;if(a(t)!="[object Function]")throw new TypeError;while(++s>>0,s=Array(i),o=arguments[1];if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");for(var u=0;u>>0,s=[],o,u=arguments[1];if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");for(var f=0;f>>0,s=arguments[1];if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");for(var o=0;o>>0,s=arguments[1];if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");for(var o=0;o>>0;if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");if(!i&&arguments.length==1)throw new TypeError("reduce of empty array with no initial value");var s=0,o;if(arguments.length>=2)o=arguments[1];else do{if(s in r){o=r[s++];break}if(++s>=i)throw new TypeError("reduce of empty array with no initial value")}while(!0);for(;s>>0;if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");if(!i&&arguments.length==1)throw new TypeError("reduceRight of empty array with no initial value");var s,o=i-1;if(arguments.length>=2)s=arguments[1];else do{if(o in r){s=r[o--];break}if(--o<0)throw new TypeError("reduceRight of empty array with no initial value")}while(!0);do o in this&&(s=t.call(void 0,s,r[o],o,n));while(o--);return s});if(!Array.prototype.indexOf||[0,1].indexOf(1,2)!=-1)Array.prototype.indexOf=function(t){var n=g&&a(this)=="[object String]"?this.split(""):F(this),r=n.length>>>0;if(!r)return-1;var i=0;arguments.length>1&&(i=H(arguments[1])),i=i>=0?i:Math.max(0,r+i);for(;i>>0;if(!r)return-1;var i=r-1;arguments.length>1&&(i=Math.min(i,H(arguments[1]))),i=i>=0?i:r-Math.abs(i);for(;i>=0;i--)if(i in n&&t===n[i])return i;return-1};Object.getPrototypeOf||(Object.getPrototypeOf=function(t){return t.__proto__||(t.constructor?t.constructor.prototype:o)});if(!Object.getOwnPropertyDescriptor){var y="Object.getOwnPropertyDescriptor called on a non-object: ";Object.getOwnPropertyDescriptor=function(t,n){if(typeof t!="object"&&typeof t!="function"||t===null)throw new TypeError(y+t);if(!f(t,n))return;var r,i,s;r={enumerable:!0,configurable:!0};if(d){var u=t.__proto__;t.__proto__=o;var i=h(t,n),s=p(t,n);t.__proto__=u;if(i||s)return i&&(r.get=i),s&&(r.set=s),r}return r.value=t[n],r}}Object.getOwnPropertyNames||(Object.getOwnPropertyNames=function(t){return Object.keys(t)});if(!Object.create){var b;Object.prototype.__proto__===null?b=function(){return{__proto__:null}}:b=function(){var e={};for(var t in e)e[t]=null;return e.constructor=e.hasOwnProperty=e.propertyIsEnumerable=e.isPrototypeOf=e.toLocaleString=e.toString=e.valueOf=e.__proto__=null,e},Object.create=function(t,n){var r;if(t===null)r=b();else{if(typeof t!="object")throw new TypeError("typeof prototype["+typeof t+"] != 'object'");var i=function(){};i.prototype=t,r=new i,r.__proto__=t}return n!==void 0&&Object.defineProperties(r,n),r}}if(Object.defineProperty){var E=w({}),S=typeof document=="undefined"||w(document.createElement("div"));if(!E||!S)var x=Object.defineProperty}if(!Object.defineProperty||x){var T="Property description must be an object: ",N="Object.defineProperty called on non-object: ",C="getters & setters can not be defined on this javascript engine";Object.defineProperty=function(t,n,r){if(typeof t!="object"&&typeof t!="function"||t===null)throw new TypeError(N+t);if(typeof r!="object"&&typeof r!="function"||r===null)throw new TypeError(T+r);if(x)try{return x.call(Object,t,n,r)}catch(i){}if(f(r,"value"))if(d&&(h(t,n)||p(t,n))){var s=t.__proto__;t.__proto__=o,delete t[n],t[n]=r.value,t.__proto__=s}else t[n]=r.value;else{if(!d)throw new TypeError(C);f(r,"get")&&l(t,n,r.get),f(r,"set")&&c(t,n,r.set)}return t}}Object.defineProperties||(Object.defineProperties=function(t,n){for(var r in n)f(n,r)&&Object.defineProperty(t,r,n[r]);return t}),Object.seal||(Object.seal=function(t){return t}),Object.freeze||(Object.freeze=function(t){return t});try{Object.freeze(function(){})}catch(k){Object.freeze=function(t){return function(n){return typeof n=="function"?n:t(n)}}(Object.freeze)}Object.preventExtensions||(Object.preventExtensions=function(t){return t}),Object.isSealed||(Object.isSealed=function(t){return!1}),Object.isFrozen||(Object.isFrozen=function(t){return!1}),Object.isExtensible||(Object.isExtensible=function(t){if(Object(t)===t)throw new TypeError;var n="";while(f(t,n))n+="?";t[n]=!0;var r=f(t,n);return delete t[n],r});if(!Object.keys){var L=!0,A=["toString","toLocaleString","valueOf","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","constructor"],O=A.length;for(var M in{toString:null})L=!1;Object.keys=function I(e){if(typeof e!="object"&&typeof e!="function"||e===null)throw new TypeError("Object.keys called on a non-object");var I=[];for(var t in e)f(e,t)&&I.push(t);if(L)for(var n=0,r=O;n=0?parseFloat((i.match(/(?:MSIE |Trident\/[0-9]+[\.0-9]+;.*rv:)([0-9]+[\.0-9]+)/)||[])[1]):parseFloat((i.match(/(?:Trident\/[0-9]+[\.0-9]+;.*rv:)([0-9]+[\.0-9]+)/)||[])[1]),t.isOldIE=t.isIE&&t.isIE<9,t.isGecko=t.isMozilla=(window.Controllers||window.controllers)&&window.navigator.product==="Gecko",t.isOldGecko=t.isGecko&&parseInt((i.match(/rv:(\d+)/)||[])[1],10)<4,t.isOpera=window.opera&&Object.prototype.toString.call(window.opera)=="[object Opera]",t.isWebKit=parseFloat(i.split("WebKit/")[1])||undefined,t.isChrome=parseFloat(i.split(" Chrome/")[1])||undefined,t.isAIR=i.indexOf("AdobeAIR")>=0,t.isIPad=i.indexOf("iPad")>=0,t.isTouchPad=i.indexOf("TouchPad")>=0,t.isChromeOS=i.indexOf(" CrOS ")>=0}),define("ace/lib/event",["require","exports","module","ace/lib/keys","ace/lib/useragent"],function(e,t,n){"use strict";function a(e,t,n){var a=u(t);if(!i.isMac&&s){t.getModifierState&&(t.getModifierState("OS")||t.getModifierState("Win"))&&(a|=8);if(s.altGr){if((3&a)==3)return;s.altGr=0}if(n===18||n===17){var f="location"in t?t.location:t.keyLocation;if(n===17&&f===1)s[n]==1&&(o=t.timeStamp);else if(n===18&&a===3&&f===2){var l=t.timeStamp-o;l<50&&(s.altGr=!0)}}}n in r.MODIFIER_KEYS&&(n=-1),a&8&&n>=91&&n<=93&&(n=-1);if(!a&&n===13){var f="location"in t?t.location:t.keyLocation;if(f===3){e(t,a,-n);if(t.defaultPrevented)return}}if(i.isChromeOS&&a&8){e(t,a,n);if(t.defaultPrevented)return;a&=-9}return!!a||n in r.FUNCTION_KEYS||n in r.PRINTABLE_KEYS?e(t,a,n):!1}function f(){s=Object.create(null)}var r=e("./keys"),i=e("./useragent"),s=null,o=0;t.addListener=function(e,t,n){if(e.addEventListener)return e.addEventListener(t,n,!1);if(e.attachEvent){var r=function(){n.call(e,window.event)};n._wrapper=r,e.attachEvent("on"+t,r)}},t.removeListener=function(e,t,n){if(e.removeEventListener)return e.removeEventListener(t,n,!1);e.detachEvent&&e.detachEvent("on"+t,n._wrapper||n)},t.stopEvent=function(e){return t.stopPropagation(e),t.preventDefault(e),!1},t.stopPropagation=function(e){e.stopPropagation?e.stopPropagation():e.cancelBubble=!0},t.preventDefault=function(e){e.preventDefault?e.preventDefault():e.returnValue=!1},t.getButton=function(e){return e.type=="dblclick"?0:e.type=="contextmenu"||i.isMac&&e.ctrlKey&&!e.altKey&&!e.shiftKey?2:e.preventDefault?e.button:{1:0,2:2,4:1}[e.button]},t.capture=function(e,n,r){function i(e){n&&n(e),r&&r(e),t.removeListener(document,"mousemove",n,!0),t.removeListener(document,"mouseup",i,!0),t.removeListener(document,"dragstart",i,!0)}return t.addListener(document,"mousemove",n,!0),t.addListener(document,"mouseup",i,!0),t.addListener(document,"dragstart",i,!0),i},t.addTouchMoveListener=function(e,n){if("ontouchmove"in e){var r,i;t.addListener(e,"touchstart",function(e){var t=e.changedTouches[0];r=t.clientX,i=t.clientY}),t.addListener(e,"touchmove",function(e){var t=1,s=e.changedTouches[0];e.wheelX=-(s.clientX-r)/t,e.wheelY=-(s.clientY-i)/t,r=s.clientX,i=s.clientY,n(e)})}},t.addMouseWheelListener=function(e,n){"onmousewheel"in e?t.addListener(e,"mousewheel",function(e){var t=8;e.wheelDeltaX!==undefined?(e.wheelX=-e.wheelDeltaX/t,e.wheelY=-e.wheelDeltaY/t):(e.wheelX=0,e.wheelY=-e.wheelDelta/t),n(e)}):"onwheel"in e?t.addListener(e,"wheel",function(e){var t=.35;switch(e.deltaMode){case e.DOM_DELTA_PIXEL:e.wheelX=e.deltaX*t||0,e.wheelY=e.deltaY*t||0;break;case e.DOM_DELTA_LINE:case e.DOM_DELTA_PAGE:e.wheelX=(e.deltaX||0)*5,e.wheelY=(e.deltaY||0)*5}n(e)}):t.addListener(e,"DOMMouseScroll",function(e){e.axis&&e.axis==e.HORIZONTAL_AXIS?(e.wheelX=(e.detail||0)*5,e.wheelY=0):(e.wheelX=0,e.wheelY=(e.detail||0)*5),n(e)})},t.addMultiMouseDownListener=function(e,n,r,s){function c(e){t.getButton(e)!==0?o=0:e.detail>1?(o++,o>4&&(o=1)):o=1;if(i.isIE){var c=Math.abs(e.clientX-u)>5||Math.abs(e.clientY-a)>5;if(!f||c)o=1;f&&clearTimeout(f),f=setTimeout(function(){f=null},n[o-1]||600),o==1&&(u=e.clientX,a=e.clientY)}e._clicks=o,r[s]("mousedown",e);if(o>4)o=0;else if(o>1)return r[s](l[o],e)}function h(e){o=2,f&&clearTimeout(f),f=setTimeout(function(){f=null},n[o-1]||600),r[s]("mousedown",e),r[s](l[o],e)}var o=0,u,a,f,l={2:"dblclick",3:"tripleclick",4:"quadclick"};Array.isArray(e)||(e=[e]),e.forEach(function(e){t.addListener(e,"mousedown",c),i.isOldIE&&t.addListener(e,"dblclick",h)})};var u=!i.isMac||!i.isOpera||"KeyboardEvent"in window?function(e){return 0|(e.ctrlKey?1:0)|(e.altKey?2:0)|(e.shiftKey?4:0)|(e.metaKey?8:0)}:function(e){return 0|(e.metaKey?1:0)|(e.altKey?2:0)|(e.shiftKey?4:0)|(e.ctrlKey?8:0)};t.getModifierString=function(e){return r.KEY_MODS[u(e)]},t.addCommandKeyListener=function(e,n){var r=t.addListener;if(i.isOldGecko||i.isOpera&&!("KeyboardEvent"in window)){var o=null;r(e,"keydown",function(e){o=e.keyCode}),r(e,"keypress",function(e){return a(n,e,o)})}else{var u=null;r(e,"keydown",function(e){s[e.keyCode]=(s[e.keyCode]||0)+1;var t=a(n,e,e.keyCode);return u=e.defaultPrevented,t}),r(e,"keypress",function(e){u&&(e.ctrlKey||e.altKey||e.shiftKey||e.metaKey)&&(t.stopEvent(e),u=null)}),r(e,"keyup",function(e){s[e.keyCode]=null}),s||(f(),r(window,"focus",f))}};if(typeof window=="object"&&window.postMessage&&!i.isOldIE){var l=1;t.nextTick=function(e,n){n=n||window;var r="zero-timeout-message-"+l;t.addListener(n,"message",function i(s){s.data==r&&(t.stopPropagation(s),t.removeListener(n,"message",i),e())}),n.postMessage(r,"*")}}t.nextFrame=typeof window=="object"&&(window.requestAnimationFrame||window.mozRequestAnimationFrame||window.webkitRequestAnimationFrame||window.msRequestAnimationFrame||window.oRequestAnimationFrame),t.nextFrame?t.nextFrame=t.nextFrame.bind(window):t.nextFrame=function(e){setTimeout(e,17)}}),define("ace/lib/lang",["require","exports","module"],function(e,t,n){"use strict";t.last=function(e){return e[e.length-1]},t.stringReverse=function(e){return e.split("").reverse().join("")},t.stringRepeat=function(e,t){var n="";while(t>0){t&1&&(n+=e);if(t>>=1)e+=e}return n};var r=/^\s\s*/,i=/\s\s*$/;t.stringTrimLeft=function(e){return e.replace(r,"")},t.stringTrimRight=function(e){return e.replace(i,"")},t.copyObject=function(e){var t={};for(var n in e)t[n]=e[n];return t},t.copyArray=function(e){var t=[];for(var n=0,r=e.length;n=53&&O()},I=o.delayedCall(j,50);r.addListener(n,"compositionstart",B),i.isGecko?r.addListener(n,"text",function(){I.schedule()}):(r.addListener(n,"keyup",function(){I.schedule()}),r.addListener(n,"keydown",function(){I.schedule()})),r.addListener(n,"compositionend",F),this.getElement=function(){return n},this.setReadOnly=function(e){n.readOnly=e},this.onContextMenu=function(e){L=!0,b(t.selection.isEmpty()),t._emit("nativecontextmenu",{target:t,domEvent:e}),this.moveToMouse(e,!0)},this.moveToMouse=function(e,o){if(!o&&i.isOldIE)return;p||(p=n.style.cssText),n.style.cssText=(o?"z-index:100000;":"")+"height:"+n.style.height+";"+(i.isIE?"opacity:0.1;":"");var u=t.container.getBoundingClientRect(),a=s.computedStyle(t.container),f=u.top+(parseInt(a.borderTopWidth)||0),l=u.left+(parseInt(u.borderLeftWidth)||0),c=u.bottom-f-n.clientHeight-2,h=function(e){n.style.left=e.clientX-l-2+"px",n.style.top=Math.min(e.clientY-f-2,c)+"px"};h(e);if(e.type!="mousedown")return;t.renderer.$keepTextAreaAtCursor&&(t.renderer.$keepTextAreaAtCursor=null),clearTimeout(q),i.isWin&&!i.isOldIE&&r.capture(t.container,h,R)},this.onContextMenuClose=R;var q,U=function(e){t.textInput.onContextMenu(e),R()};r.addListener(n,"mouseup",U),r.addListener(n,"mousedown",function(e){e.preventDefault(),R()}),r.addListener(t.renderer.scroller,"contextmenu",U),r.addListener(n,"contextmenu",U)};t.TextInput=f}),define("ace/mouse/default_handlers",["require","exports","module","ace/lib/dom","ace/lib/event","ace/lib/useragent"],function(e,t,n){"use strict";function u(e){e.$clickSelection=null;var t=e.editor;t.setDefaultHandler("mousedown",this.onMouseDown.bind(e)),t.setDefaultHandler("dblclick",this.onDoubleClick.bind(e)),t.setDefaultHandler("tripleclick",this.onTripleClick.bind(e)),t.setDefaultHandler("quadclick",this.onQuadClick.bind(e)),t.setDefaultHandler("mousewheel",this.onMouseWheel.bind(e)),t.setDefaultHandler("touchmove",this.onTouchMove.bind(e));var n=["select","startSelect","selectEnd","selectAllEnd","selectByWordsEnd","selectByLinesEnd","dragWait","dragWaitEnd","focusWait"];n.forEach(function(t){e[t]=this[t]},this),e.selectByLines=this.extendSelectionBy.bind(e,"getLineRange"),e.selectByWords=this.extendSelectionBy.bind(e,"getWordRange")}function a(e,t,n,r){return Math.sqrt(Math.pow(n-e,2)+Math.pow(r-t,2))}function f(e,t){if(e.start.row==e.end.row)var n=2*t.column-e.start.column-e.end.column;else if(e.start.row==e.end.row-1&&!e.start.column&&!e.end.column)var n=t.column-4;else var n=2*t.row-e.start.row-e.end.row;return n<0?{cursor:e.start,anchor:e.end}:{cursor:e.end,anchor:e.start}}var r=e("../lib/dom"),i=e("../lib/event"),s=e("../lib/useragent"),o=0;(function(){this.onMouseDown=function(e){var t=e.inSelection(),n=e.getDocumentPosition();this.mousedownEvent=e;var r=this.editor,i=e.getButton();if(i!==0){var s=r.getSelectionRange(),o=s.isEmpty();r.$blockScrolling++,(o||i==1)&&r.selection.moveToPosition(n),r.$blockScrolling--,i==2&&r.textInput.onContextMenu(e.domEvent);return}this.mousedownEvent.time=Date.now();if(t&&!r.isFocused()){r.focus();if(this.$focusTimout&&!this.$clickSelection&&!r.inMultiSelectMode){this.setState("focusWait"),this.captureMouse(e);return}}return this.captureMouse(e),this.startSelect(n,e.domEvent._clicks>1),e.preventDefault()},this.startSelect=function(e,t){e=e||this.editor.renderer.screenToTextCoordinates(this.x,this.y);var n=this.editor;n.$blockScrolling++,this.mousedownEvent.getShiftKey()?n.selection.selectToPosition(e):t||n.selection.moveToPosition(e),t||this.select(),n.renderer.scroller.setCapture&&n.renderer.scroller.setCapture(),n.setStyle("ace_selecting"),this.setState("select"),n.$blockScrolling--},this.select=function(){var e,t=this.editor,n=t.renderer.screenToTextCoordinates(this.x,this.y);t.$blockScrolling++;if(this.$clickSelection){var r=this.$clickSelection.comparePoint(n);if(r==-1)e=this.$clickSelection.end;else if(r==1)e=this.$clickSelection.start;else{var i=f(this.$clickSelection,n);n=i.cursor,e=i.anchor}t.selection.setSelectionAnchor(e.row,e.column)}t.selection.selectToPosition(n),t.$blockScrolling--,t.renderer.scrollCursorIntoView()},this.extendSelectionBy=function(e){var t,n=this.editor,r=n.renderer.screenToTextCoordinates(this.x,this.y),i=n.selection[e](r.row,r.column);n.$blockScrolling++;if(this.$clickSelection){var s=this.$clickSelection.comparePoint(i.start),o=this.$clickSelection.comparePoint(i.end);if(s==-1&&o<=0){t=this.$clickSelection.end;if(i.end.row!=r.row||i.end.column!=r.column)r=i.start}else if(o==1&&s>=0){t=this.$clickSelection.start;if(i.start.row!=r.row||i.start.column!=r.column)r=i.end}else if(s==-1&&o==1)r=i.end,t=i.start;else{var u=f(this.$clickSelection,r);r=u.cursor,t=u.anchor}n.selection.setSelectionAnchor(t.row,t.column)}n.selection.selectToPosition(r),n.$blockScrolling--,n.renderer.scrollCursorIntoView()},this.selectEnd=this.selectAllEnd=this.selectByWordsEnd=this.selectByLinesEnd=function(){this.$clickSelection=null,this.editor.unsetStyle("ace_selecting"),this.editor.renderer.scroller.releaseCapture&&this.editor.renderer.scroller.releaseCapture()},this.focusWait=function(){var e=a(this.mousedownEvent.x,this.mousedownEvent.y,this.x,this.y),t=Date.now();(e>o||t-this.mousedownEvent.time>this.$focusTimout)&&this.startSelect(this.mousedownEvent.getDocumentPosition())},this.onDoubleClick=function(e){var t=e.getDocumentPosition(),n=this.editor,r=n.session,i=r.getBracketRange(t);i?(i.isEmpty()&&(i.start.column--,i.end.column++),this.setState("select")):(i=n.selection.getWordRange(t.row,t.column),this.setState("selectByWords")),this.$clickSelection=i,this.select()},this.onTripleClick=function(e){var t=e.getDocumentPosition(),n=this.editor;this.setState("selectByLines");var r=n.getSelectionRange();r.isMultiLine()&&r.contains(t.row,t.column)?(this.$clickSelection=n.selection.getLineRange(r.start.row),this.$clickSelection.end=n.selection.getLineRange(r.end.row).end):this.$clickSelection=n.selection.getLineRange(t.row),this.select()},this.onQuadClick=function(e){var t=this.editor;t.selectAll(),this.$clickSelection=t.getSelectionRange(),this.setState("selectAll")},this.onMouseWheel=function(e){if(e.getAccelKey())return;e.getShiftKey()&&e.wheelY&&!e.wheelX&&(e.wheelX=e.wheelY,e.wheelY=0);var t=e.domEvent.timeStamp,n=t-(this.$lastScrollTime||0),r=this.editor,i=r.renderer.isScrollableBy(e.wheelX*e.speed,e.wheelY*e.speed);if(i||n<200)return this.$lastScrollTime=t,r.renderer.scrollBy(e.wheelX*e.speed,e.wheelY*e.speed),e.stop()},this.onTouchMove=function(e){var t=e.domEvent.timeStamp,n=t-(this.$lastScrollTime||0),r=this.editor,i=r.renderer.isScrollableBy(e.wheelX*e.speed,e.wheelY*e.speed);if(i||n<200)return this.$lastScrollTime=t,r.renderer.scrollBy(e.wheelX*e.speed,e.wheelY*e.speed),e.stop()}}).call(u.prototype),t.DefaultHandlers=u}),define("ace/tooltip",["require","exports","module","ace/lib/oop","ace/lib/dom"],function(e,t,n){"use strict";function s(e){this.isOpen=!1,this.$element=null,this.$parentNode=e}var r=e("./lib/oop"),i=e("./lib/dom");(function(){this.$init=function(){return this.$element=i.createElement("div"),this.$element.className="ace_tooltip",this.$element.style.display="none",this.$parentNode.appendChild(this.$element),this.$element},this.getElement=function(){return this.$element||this.$init()},this.setText=function(e){i.setInnerText(this.getElement(),e)},this.setHtml=function(e){this.getElement().innerHTML=e},this.setPosition=function(e,t){this.getElement().style.left=e+"px",this.getElement().style.top=t+"px"},this.setClassName=function(e){i.addCssClass(this.getElement(),e)},this.show=function(e,t,n){e!=null&&this.setText(e),t!=null&&n!=null&&this.setPosition(t,n),this.isOpen||(this.getElement().style.display="block",this.isOpen=!0)},this.hide=function(){this.isOpen&&(this.getElement().style.display="none",this.isOpen=!1)},this.getHeight=function(){return this.getElement().offsetHeight},this.getWidth=function(){return this.getElement().offsetWidth}}).call(s.prototype),t.Tooltip=s}),define("ace/mouse/default_gutter_handler",["require","exports","module","ace/lib/dom","ace/lib/oop","ace/lib/event","ace/tooltip"],function(e,t,n){"use strict";function u(e){function l(){var r=u.getDocumentPosition().row,s=n.$annotations[r];if(!s)return c();var o=t.session.getLength();if(r==o){var a=t.renderer.pixelToScreenCoordinates(0,u.y).row,l=u.$pos;if(a>t.session.documentToScreenRow(l.row,l.column))return c()}if(f==s)return;f=s.text.join("
"),i.setHtml(f),i.show(),t._signal("showGutterTooltip",i),t.on("mousewheel",c);if(e.$tooltipFollowsMouse)h(u);else{var p=u.domEvent.target,d=p.getBoundingClientRect(),v=i.getElement().style;v.left=d.right+"px",v.top=d.bottom+"px"}}function c(){o&&(o=clearTimeout(o)),f&&(i.hide(),f=null,t._signal("hideGutterTooltip",i),t.removeEventListener("mousewheel",c))}function h(e){i.setPosition(e.x,e.y)}var t=e.editor,n=t.renderer.$gutterLayer,i=new a(t.container);e.editor.setDefaultHandler("guttermousedown",function(r){if(!t.isFocused()||r.getButton()!=0)return;var i=n.getRegion(r);if(i=="foldWidgets")return;var s=r.getDocumentPosition().row,o=t.session.selection;if(r.getShiftKey())o.selectTo(s,0);else{if(r.domEvent.detail==2)return t.selectAll(),r.preventDefault();e.$clickSelection=t.selection.getLineRange(s)}return e.setState("selectByLines"),e.captureMouse(r),r.preventDefault()});var o,u,f;e.editor.setDefaultHandler("guttermousemove",function(t){var n=t.domEvent.target||t.domEvent.srcElement;if(r.hasCssClass(n,"ace_fold-widget"))return c();f&&e.$tooltipFollowsMouse&&h(t),u=t;if(o)return;o=setTimeout(function(){o=null,u&&!e.isMousePressed?l():c()},50)}),s.addListener(t.renderer.$gutter,"mouseout",function(e){u=null;if(!f||o)return;o=setTimeout(function(){o=null,c()},50)}),t.on("changeSession",c)}function a(e){o.call(this,e)}var r=e("../lib/dom"),i=e("../lib/oop"),s=e("../lib/event"),o=e("../tooltip").Tooltip;i.inherits(a,o),function(){this.setPosition=function(e,t){var n=window.innerWidth||document.documentElement.clientWidth,r=window.innerHeight||document.documentElement.clientHeight,i=this.getWidth(),s=this.getHeight();e+=15,t+=15,e+i>n&&(e-=e+i-n),t+s>r&&(t-=20+s),o.prototype.setPosition.call(this,e,t)}}.call(a.prototype),t.GutterHandler=u}),define("ace/mouse/mouse_event",["require","exports","module","ace/lib/event","ace/lib/useragent"],function(e,t,n){"use strict";var r=e("../lib/event"),i=e("../lib/useragent"),s=t.MouseEvent=function(e,t){this.domEvent=e,this.editor=t,this.x=this.clientX=e.clientX,this.y=this.clientY=e.clientY,this.$pos=null,this.$inSelection=null,this.propagationStopped=!1,this.defaultPrevented=!1};(function(){this.stopPropagation=function(){r.stopPropagation(this.domEvent),this.propagationStopped=!0},this.preventDefault=function(){r.preventDefault(this.domEvent),this.defaultPrevented=!0},this.stop=function(){this.stopPropagation(),this.preventDefault()},this.getDocumentPosition=function(){return this.$pos?this.$pos:(this.$pos=this.editor.renderer.screenToTextCoordinates(this.clientX,this.clientY),this.$pos)},this.inSelection=function(){if(this.$inSelection!==null)return this.$inSelection;var e=this.editor,t=e.getSelectionRange();if(t.isEmpty())this.$inSelection=!1;else{var n=this.getDocumentPosition();this.$inSelection=t.contains(n.row,n.column)}return this.$inSelection},this.getButton=function(){return r.getButton(this.domEvent)},this.getShiftKey=function(){return this.domEvent.shiftKey},this.getAccelKey=i.isMac?function(){return this.domEvent.metaKey}:function(){return this.domEvent.ctrlKey}}).call(s.prototype)}),define("ace/mouse/dragdrop_handler",["require","exports","module","ace/lib/dom","ace/lib/event","ace/lib/useragent"],function(e,t,n){"use strict";function f(e){function T(e,n){var r=Date.now(),i=!n||e.row!=n.row,s=!n||e.column!=n.column;if(!S||i||s)t.$blockScrolling+=1,t.moveCursorToPosition(e),t.$blockScrolling-=1,S=r,x={x:p,y:d};else{var o=l(x.x,x.y,p,d);o>a?S=null:r-S>=u&&(t.renderer.scrollCursorIntoView(),S=null)}}function N(e,n){var r=Date.now(),i=t.renderer.layerConfig.lineHeight,s=t.renderer.layerConfig.characterWidth,u=t.renderer.scroller.getBoundingClientRect(),a={x:{left:p-u.left,right:u.right-p},y:{top:d-u.top,bottom:u.bottom-d}},f=Math.min(a.x.left,a.x.right),l=Math.min(a.y.top,a.y.bottom),c={row:e.row,column:e.column};f/s<=2&&(c.column+=a.x.left=o&&t.renderer.scrollCursorIntoView(c):E=r:E=null}function C(){var e=g;g=t.renderer.screenToTextCoordinates(p,d),T(g,e),N(g,e)}function k(){m=t.selection.toOrientedRange(),h=t.session.addMarker(m,"ace_selection",t.getSelectionStyle()),t.clearSelection(),t.isFocused()&&t.renderer.$cursorLayer.setBlinking(!1),clearInterval(v),C(),v=setInterval(C,20),y=0,i.addListener(document,"mousemove",O)}function L(){clearInterval(v),t.session.removeMarker(h),h=null,t.$blockScrolling+=1,t.selection.fromOrientedRange(m),t.$blockScrolling-=1,t.isFocused()&&!w&&t.renderer.$cursorLayer.setBlinking(!t.getReadOnly()),m=null,g=null,y=0,E=null,S=null,i.removeListener(document,"mousemove",O)}function O(){A==null&&(A=setTimeout(function(){A!=null&&h&&L()},20))}function M(e){var t=e.types;return!t||Array.prototype.some.call(t,function(e){return e=="text/plain"||e=="Text"})}function _(e){var t=["copy","copymove","all","uninitialized"],n=["move","copymove","linkmove","all","uninitialized"],r=s.isMac?e.altKey:e.ctrlKey,i="uninitialized";try{i=e.dataTransfer.effectAllowed.toLowerCase()}catch(e){}var o="none";return r&&t.indexOf(i)>=0?o="copy":n.indexOf(i)>=0?o="move":t.indexOf(i)>=0&&(o="copy"),o}var t=e.editor,n=r.createElement("img");n.src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==",s.isOpera&&(n.style.cssText="width:1px;height:1px;position:fixed;top:0;left:0;z-index:2147483647;opacity:0;");var f=["dragWait","dragWaitEnd","startDrag","dragReadyEnd","onMouseDrag"];f.forEach(function(t){e[t]=this[t]},this),t.addEventListener("mousedown",this.onMouseDown.bind(e));var c=t.container,h,p,d,v,m,g,y=0,b,w,E,S,x;this.onDragStart=function(e){if(this.cancelDrag||!c.draggable){var r=this;return setTimeout(function(){r.startSelect(),r.captureMouse(e)},0),e.preventDefault()}m=t.getSelectionRange();var i=e.dataTransfer;i.effectAllowed=t.getReadOnly()?"copy":"copyMove",s.isOpera&&(t.container.appendChild(n),n.scrollTop=0),i.setDragImage&&i.setDragImage(n,0,0),s.isOpera&&t.container.removeChild(n),i.clearData(),i.setData("Text",t.session.getTextRange()),w=!0,this.setState("drag")},this.onDragEnd=function(e){c.draggable=!1,w=!1,this.setState(null);if(!t.getReadOnly()){var n=e.dataTransfer.dropEffect;!b&&n=="move"&&t.session.remove(t.getSelectionRange()),t.renderer.$cursorLayer.setBlinking(!0)}this.editor.unsetStyle("ace_dragging"),this.editor.renderer.setCursorStyle("")},this.onDragEnter=function(e){if(t.getReadOnly()||!M(e.dataTransfer))return;return p=e.clientX,d=e.clientY,h||k(),y++,e.dataTransfer.dropEffect=b=_(e),i.preventDefault(e)},this.onDragOver=function(e){if(t.getReadOnly()||!M(e.dataTransfer))return;return p=e.clientX,d=e.clientY,h||(k(),y++),A!==null&&(A=null),e.dataTransfer.dropEffect=b=_(e),i.preventDefault(e)},this.onDragLeave=function(e){y--;if(y<=0&&h)return L(),b=null,i.preventDefault(e)},this.onDrop=function(e){if(!g)return;var n=e.dataTransfer;if(w)switch(b){case"move":m.contains(g.row,g.column)?m={start:g,end:g}:m=t.moveText(m,g);break;case"copy":m=t.moveText(m,g,!0)}else{var r=n.getData("Text");m={start:g,end:t.session.insert(g,r)},t.focus(),b=null}return L(),i.preventDefault(e)},i.addListener(c,"dragstart",this.onDragStart.bind(e)),i.addListener(c,"dragend",this.onDragEnd.bind(e)),i.addListener(c,"dragenter",this.onDragEnter.bind(e)),i.addListener(c,"dragover",this.onDragOver.bind(e)),i.addListener(c,"dragleave",this.onDragLeave.bind(e)),i.addListener(c,"drop",this.onDrop.bind(e));var A=null}function l(e,t,n,r){return Math.sqrt(Math.pow(n-e,2)+Math.pow(r-t,2))}var r=e("../lib/dom"),i=e("../lib/event"),s=e("../lib/useragent"),o=200,u=200,a=5;(function(){this.dragWait=function(){var e=Date.now()-this.mousedownEvent.time;e>this.editor.getDragDelay()&&this.startDrag()},this.dragWaitEnd=function(){var e=this.editor.container;e.draggable=!1,this.startSelect(this.mousedownEvent.getDocumentPosition()),this.selectEnd()},this.dragReadyEnd=function(e){this.editor.renderer.$cursorLayer.setBlinking(!this.editor.getReadOnly()),this.editor.unsetStyle("ace_dragging"),this.editor.renderer.setCursorStyle(""),this.dragWaitEnd()},this.startDrag=function(){this.cancelDrag=!1;var e=this.editor,t=e.container;t.draggable=!0,e.renderer.$cursorLayer.setBlinking(!1),e.setStyle("ace_dragging");var n=s.isWin?"default":"move";e.renderer.setCursorStyle(n),this.setState("dragReady")},this.onMouseDrag=function(e){var t=this.editor.container;if(s.isIE&&this.state=="dragReady"){var n=l(this.mousedownEvent.x,this.mousedownEvent.y,this.x,this.y);n>3&&t.dragDrop()}if(this.state==="dragWait"){var n=l(this.mousedownEvent.x,this.mousedownEvent.y,this.x,this.y);n>0&&(t.draggable=!1,this.startSelect(this.mousedownEvent.getDocumentPosition()))}},this.onMouseDown=function(e){if(!this.$dragEnabled)return;this.mousedownEvent=e;var t=this.editor,n=e.inSelection(),r=e.getButton(),i=e.domEvent.detail||1;if(i===1&&r===0&&n){if(e.editor.inMultiSelectMode&&(e.getAccelKey()||e.getShiftKey()))return;this.mousedownEvent.time=Date.now();var o=e.domEvent.target||e.domEvent.srcElement;"unselectable"in o&&(o.unselectable="on");if(t.getDragDelay()){if(s.isWebKit){this.cancelDrag=!0;var u=t.container;u.draggable=!0}this.setState("dragWait")}else this.startDrag();this.captureMouse(e,this.onMouseDrag.bind(this)),e.defaultPrevented=!0}}}).call(f.prototype),t.DragdropHandler=f}),define("ace/lib/net",["require","exports","module","ace/lib/dom"],function(e,t,n){"use strict";var r=e("./dom");t.get=function(e,t){var n=new XMLHttpRequest;n.open("GET",e,!0),n.onreadystatechange=function(){n.readyState===4&&t(n.responseText)},n.send(null)},t.loadScript=function(e,t){var n=r.getDocumentHead(),i=document.createElement("script");i.src=e,n.appendChild(i),i.onload=i.onreadystatechange=function(e,n){if(n||!i.readyState||i.readyState=="loaded"||i.readyState=="complete")i=i.onload=i.onreadystatechange=null,n||t()}},t.qualifyURL=function(e){var t=document.createElement("a");return t.href=e,t.href}}),define("ace/lib/event_emitter",["require","exports","module"],function(e,t,n){"use strict";var r={},i=function(){this.propagationStopped=!0},s=function(){this.defaultPrevented=!0};r._emit=r._dispatchEvent=function(e,t){this._eventRegistry||(this._eventRegistry={}),this._defaultHandlers||(this._defaultHandlers={});var n=this._eventRegistry[e]||[],r=this._defaultHandlers[e];if(!n.length&&!r)return;if(typeof t!="object"||!t)t={};t.type||(t.type=e),t.stopPropagation||(t.stopPropagation=i),t.preventDefault||(t.preventDefault=s),n=n.slice();for(var o=0;o1&&(i=n[n.length-2]);var o=a[t+"Path"];return o==null?o=a.basePath:r=="/"&&(t=r=""),o&&o.slice(-1)!="/"&&(o+="/"),o+t+r+i+this.get("suffix")},t.setModuleUrl=function(e,t){return a.$moduleUrls[e]=t},t.$loading={},t.loadModule=function(n,r){var i,o;Array.isArray(n)&&(o=n[0],n=n[1]);try{i=e(n)}catch(u){}if(i&&!t.$loading[n])return r&&r(i);t.$loading[n]||(t.$loading[n]=[]),t.$loading[n].push(r);if(t.$loading[n].length>1)return;var a=function(){e([n],function(e){t._emit("load.module",{name:n,module:e});var r=t.$loading[n];t.$loading[n]=null,r.forEach(function(t){t&&t(e)})})};if(!t.get("packaged"))return a();s.loadScript(t.moduleUrl(n,o),a)},t.init=f}),define("ace/mouse/mouse_handler",["require","exports","module","ace/lib/event","ace/lib/useragent","ace/mouse/default_handlers","ace/mouse/default_gutter_handler","ace/mouse/mouse_event","ace/mouse/dragdrop_handler","ace/config"],function(e,t,n){"use strict";var r=e("../lib/event"),i=e("../lib/useragent"),s=e("./default_handlers").DefaultHandlers,o=e("./default_gutter_handler").GutterHandler,u=e("./mouse_event").MouseEvent,a=e("./dragdrop_handler").DragdropHandler,f=e("../config"),l=function(e){var t=this;this.editor=e,new s(this),new o(this),new a(this);var n=function(t){var n=!document.hasFocus||!document.hasFocus()||!e.isFocused()&&document.activeElement==(e.textInput&&e.textInput.getElement());n&&window.focus(),e.focus()},u=e.renderer.getMouseEventTarget();r.addListener(u,"click",this.onMouseEvent.bind(this,"click")),r.addListener(u,"mousemove",this.onMouseMove.bind(this,"mousemove")),r.addMultiMouseDownListener([u,e.renderer.scrollBarV&&e.renderer.scrollBarV.inner,e.renderer.scrollBarH&&e.renderer.scrollBarH.inner,e.textInput&&e.textInput.getElement()].filter(Boolean),[400,300,250],this,"onMouseEvent"),r.addMouseWheelListener(e.container,this.onMouseWheel.bind(this,"mousewheel")),r.addTouchMoveListener(e.container,this.onTouchMove.bind(this,"touchmove"));var f=e.renderer.$gutter;r.addListener(f,"mousedown",this.onMouseEvent.bind(this,"guttermousedown")),r.addListener(f,"click",this.onMouseEvent.bind(this,"gutterclick")),r.addListener(f,"dblclick",this.onMouseEvent.bind(this,"gutterdblclick")),r.addListener(f,"mousemove",this.onMouseEvent.bind(this,"guttermousemove")),r.addListener(u,"mousedown",n),r.addListener(f,"mousedown",n),i.isIE&&e.renderer.scrollBarV&&(r.addListener(e.renderer.scrollBarV.element,"mousedown",n),r.addListener(e.renderer.scrollBarH.element,"mousedown",n)),e.on("mousemove",function(n){if(t.state||t.$dragDelay||!t.$dragEnabled)return;var r=e.renderer.screenToTextCoordinates(n.x,n.y),i=e.session.selection.getRange(),s=e.renderer;!i.isEmpty()&&i.insideStart(r.row,r.column)?s.setCursorStyle("default"):s.setCursorStyle("")})};(function(){this.onMouseEvent=function(e,t){this.editor._emit(e,new u(t,this.editor))},this.onMouseMove=function(e,t){var n=this.editor._eventRegistry&&this.editor._eventRegistry.mousemove;if(!n||!n.length)return;this.editor._emit(e,new u(t,this.editor))},this.onMouseWheel=function(e,t){var n=new u(t,this.editor);n.speed=this.$scrollSpeed*2,n.wheelX=t.wheelX,n.wheelY=t.wheelY,this.editor._emit(e,n)},this.onTouchMove=function(e,t){var n=new u(t,this.editor);n.speed=1,n.wheelX=t.wheelX,n.wheelY=t.wheelY,this.editor._emit(e,n)},this.setState=function(e){this.state=e},this.captureMouse=function(e,t){this.x=e.x,this.y=e.y,this.isMousePressed=!0;var n=this.editor.renderer;n.$keepTextAreaAtCursor&&(n.$keepTextAreaAtCursor=null);var s=this,o=function(e){if(!e)return;if(i.isWebKit&&!e.which&&s.releaseMouse)return s.releaseMouse();s.x=e.clientX,s.y=e.clientY,t&&t(e),s.mouseEvent=new u(e,s.editor),s.$mouseMoved=!0},a=function(e){clearInterval(l),f(),s[s.state+"End"]&&s[s.state+"End"](e),s.state="",n.$keepTextAreaAtCursor==null&&(n.$keepTextAreaAtCursor=!0,n.$moveTextAreaToCursor()),s.isMousePressed=!1,s.$onCaptureMouseMove=s.releaseMouse=null,e&&s.onMouseEvent("mouseup",e)},f=function(){s[s.state]&&s[s.state](),s.$mouseMoved=!1};if(i.isOldIE&&e.domEvent.type=="dblclick")return setTimeout(function(){a(e)});s.$onCaptureMouseMove=o,s.releaseMouse=r.capture(this.editor.container,o,a);var l=setInterval(f,20)},this.releaseMouse=null,this.cancelContextMenu=function(){var e=function(t){if(t&&t.domEvent&&t.domEvent.type!="contextmenu")return;this.editor.off("nativecontextmenu",e),t&&t.domEvent&&r.stopEvent(t.domEvent)}.bind(this);setTimeout(e,10),this.editor.on("nativecontextmenu",e)}}).call(l.prototype),f.defineOptions(l.prototype,"mouseHandler",{scrollSpeed:{initialValue:2},dragDelay:{initialValue:i.isMac?150:0},dragEnabled:{initialValue:!0},focusTimout:{initialValue:0},tooltipFollowsMouse:{initialValue:!0}}),t.MouseHandler=l}),define("ace/mouse/fold_handler",["require","exports","module"],function(e,t,n){"use strict";function r(e){e.on("click",function(t){var n=t.getDocumentPosition(),r=e.session,i=r.getFoldAt(n.row,n.column,1);i&&(t.getAccelKey()?r.removeFold(i):r.expandFold(i),t.stop())}),e.on("gutterclick",function(t){var n=e.renderer.$gutterLayer.getRegion(t);if(n=="foldWidgets"){var r=t.getDocumentPosition().row,i=e.session;i.foldWidgets&&i.foldWidgets[r]&&e.session.onFoldWidgetClick(r,t),e.isFocused()||e.focus(),t.stop()}}),e.on("gutterdblclick",function(t){var n=e.renderer.$gutterLayer.getRegion(t);if(n=="foldWidgets"){var r=t.getDocumentPosition().row,i=e.session,s=i.getParentFoldRangeData(r,!0),o=s.range||s.firstRange;if(o){r=o.start.row;var u=i.getFoldAt(r,i.getLine(r).length,1);u?i.removeFold(u):(i.addFold("...",o),e.renderer.scrollCursorIntoView({row:o.start.row,column:0}))}t.stop()}})}t.FoldHandler=r}),define("ace/keyboard/keybinding",["require","exports","module","ace/lib/keys","ace/lib/event"],function(e,t,n){"use strict";var r=e("../lib/keys"),i=e("../lib/event"),s=function(e){this.$editor=e,this.$data={editor:e},this.$handlers=[],this.setDefaultHandler(e.commands)};(function(){this.setDefaultHandler=function(e){this.removeKeyboardHandler(this.$defaultHandler),this.$defaultHandler=e,this.addKeyboardHandler(e,0)},this.setKeyboardHandler=function(e){var t=this.$handlers;if(t[t.length-1]==e)return;while(t[t.length-1]&&t[t.length-1]!=this.$defaultHandler)this.removeKeyboardHandler(t[t.length-1]);this.addKeyboardHandler(e,1)},this.addKeyboardHandler=function(e,t){if(!e)return;typeof e=="function"&&!e.handleKeyboard&&(e.handleKeyboard=e);var n=this.$handlers.indexOf(e);n!=-1&&this.$handlers.splice(n,1),t==undefined?this.$handlers.push(e):this.$handlers.splice(t,0,e),n==-1&&e.attach&&e.attach(this.$editor)},this.removeKeyboardHandler=function(e){var t=this.$handlers.indexOf(e);return t==-1?!1:(this.$handlers.splice(t,1),e.detach&&e.detach(this.$editor),!0)},this.getKeyboardHandler=function(){return this.$handlers[this.$handlers.length-1]},this.getStatusText=function(){var e=this.$data,t=e.editor;return this.$handlers.map(function(n){return n.getStatusText&&n.getStatusText(t,e)||""}).filter(Boolean).join(" ")},this.$callKeyboardHandlers=function(e,t,n,r){var s,o=!1,u=this.$editor.commands;for(var a=this.$handlers.length;a--;){s=this.$handlers[a].handleKeyboard(this.$data,e,t,n,r);if(!s||!s.command)continue;s.command=="null"?o=!0:o=u.exec(s.command,this.$editor,s.args,r),o&&r&&e!=-1&&s.passEvent!=1&&s.command.passEvent!=1&&i.stopEvent(r);if(o)break}return!o&&e==-1&&(s={command:"insertstring"},o=u.exec("insertstring",this.$editor,t)),o&&this.$editor._signal&&this.$editor._signal("keyboardActivity",s),o},this.onCommandKey=function(e,t,n){var i=r.keyCodeToString(n);this.$callKeyboardHandlers(t,i,n,e)},this.onTextInput=function(e){this.$callKeyboardHandlers(-1,e)}}).call(s.prototype),t.KeyBinding=s}),define("ace/range",["require","exports","module"],function(e,t,n){"use strict";var r=function(e,t){return e.row-t.row||e.column-t.column},i=function(e,t,n,r){this.start={row:e,column:t},this.end={row:n,column:r}};(function(){this.isEqual=function(e){return this.start.row===e.start.row&&this.end.row===e.end.row&&this.start.column===e.start.column&&this.end.column===e.end.column},this.toString=function(){return"Range: ["+this.start.row+"/"+this.start.column+"] -> ["+this.end.row+"/"+this.end.column+"]"},this.contains=function(e,t){return this.compare(e,t)==0},this.compareRange=function(e){var t,n=e.end,r=e.start;return t=this.compare(n.row,n.column),t==1?(t=this.compare(r.row,r.column),t==1?2:t==0?1:0):t==-1?-2:(t=this.compare(r.row,r.column),t==-1?-1:t==1?42:0)},this.comparePoint=function(e){return this.compare(e.row,e.column)},this.containsRange=function(e){return this.comparePoint(e.start)==0&&this.comparePoint(e.end)==0},this.intersects=function(e){var t=this.compareRange(e);return t==-1||t==0||t==1},this.isEnd=function(e,t){return this.end.row==e&&this.end.column==t},this.isStart=function(e,t){return this.start.row==e&&this.start.column==t},this.setStart=function(e,t){typeof e=="object"?(this.start.column=e.column,this.start.row=e.row):(this.start.row=e,this.start.column=t)},this.setEnd=function(e,t){typeof e=="object"?(this.end.column=e.column,this.end.row=e.row):(this.end.row=e,this.end.column=t)},this.inside=function(e,t){return this.compare(e,t)==0?this.isEnd(e,t)||this.isStart(e,t)?!1:!0:!1},this.insideStart=function(e,t){return this.compare(e,t)==0?this.isEnd(e,t)?!1:!0:!1},this.insideEnd=function(e,t){return this.compare(e,t)==0?this.isStart(e,t)?!1:!0:!1},this.compare=function(e,t){return!this.isMultiLine()&&e===this.start.row?tthis.end.column?1:0:ethis.end.row?1:this.start.row===e?t>=this.start.column?0:-1:this.end.row===e?t<=this.end.column?0:1:0},this.compareStart=function(e,t){return this.start.row==e&&this.start.column==t?-1:this.compare(e,t)},this.compareEnd=function(e,t){return this.end.row==e&&this.end.column==t?1:this.compare(e,t)},this.compareInside=function(e,t){return this.end.row==e&&this.end.column==t?1:this.start.row==e&&this.start.column==t?-1:this.compare(e,t)},this.clipRows=function(e,t){if(this.end.row>t)var n={row:t+1,column:0};else if(this.end.rowt)var r={row:t+1,column:0};else if(this.start.rowt.row||e.row==t.row&&e.column>t.column},this.getRange=function(){var e=this.anchor,t=this.lead;return this.isEmpty()?o.fromPoints(t,t):this.isBackwards()?o.fromPoints(t,e):o.fromPoints(e,t)},this.clearSelection=function(){this.$isEmpty||(this.$isEmpty=!0,this._emit("changeSelection"))},this.selectAll=function(){var e=this.doc.getLength()-1;this.setSelectionAnchor(0,0),this.moveCursorTo(e,this.doc.getLine(e).length)},this.setRange=this.setSelectionRange=function(e,t){t?(this.setSelectionAnchor(e.end.row,e.end.column),this.selectTo(e.start.row,e.start.column)):(this.setSelectionAnchor(e.start.row,e.start.column),this.selectTo(e.end.row,e.end.column)),this.getRange().isEmpty()&&(this.$isEmpty=!0),this.$desiredColumn=null},this.$moveSelection=function(e){var t=this.lead;this.$isEmpty&&this.setSelectionAnchor(t.row,t.column),e.call(this)},this.selectTo=function(e,t){this.$moveSelection(function(){this.moveCursorTo(e,t)})},this.selectToPosition=function(e){this.$moveSelection(function(){this.moveCursorToPosition(e)})},this.moveTo=function(e,t){this.clearSelection(),this.moveCursorTo(e,t)},this.moveToPosition=function(e){this.clearSelection(),this.moveCursorToPosition(e)},this.selectUp=function(){this.$moveSelection(this.moveCursorUp)},this.selectDown=function(){this.$moveSelection(this.moveCursorDown)},this.selectRight=function(){this.$moveSelection(this.moveCursorRight)},this.selectLeft=function(){this.$moveSelection(this.moveCursorLeft)},this.selectLineStart=function(){this.$moveSelection(this.moveCursorLineStart)},this.selectLineEnd=function(){this.$moveSelection(this.moveCursorLineEnd)},this.selectFileEnd=function(){this.$moveSelection(this.moveCursorFileEnd)},this.selectFileStart=function(){this.$moveSelection(this.moveCursorFileStart)},this.selectWordRight=function(){this.$moveSelection(this.moveCursorWordRight)},this.selectWordLeft=function(){this.$moveSelection(this.moveCursorWordLeft)},this.getWordRange=function(e,t){if(typeof t=="undefined"){var n=e||this.lead;e=n.row,t=n.column}return this.session.getWordRange(e,t)},this.selectWord=function(){this.setSelectionRange(this.getWordRange())},this.selectAWord=function(){var e=this.getCursor(),t=this.session.getAWordRange(e.row,e.column);this.setSelectionRange(t)},this.getLineRange=function(e,t){var n=typeof e=="number"?e:this.lead.row,r,i=this.session.getFoldLine(n);return i?(n=i.start.row,r=i.end.row):r=n,t===!0?new o(n,0,r,this.session.getLine(r).length):new o(n,0,r+1,0)},this.selectLine=function(){this.setSelectionRange(this.getLineRange())},this.moveCursorUp=function(){this.moveCursorBy(-1,0)},this.moveCursorDown=function(){this.moveCursorBy(1,0)},this.moveCursorLeft=function(){var e=this.lead.getPosition(),t;if(t=this.session.getFoldAt(e.row,e.column,-1))this.moveCursorTo(t.start.row,t.start.column);else if(e.column===0)e.row>0&&this.moveCursorTo(e.row-1,this.doc.getLine(e.row-1).length);else{var n=this.session.getTabSize();this.session.isTabStop(e)&&this.doc.getLine(e.row).slice(e.column-n,e.column).split(" ").length-1==n?this.moveCursorBy(0,-n):this.moveCursorBy(0,-1)}},this.moveCursorRight=function(){var e=this.lead.getPosition(),t;if(t=this.session.getFoldAt(e.row,e.column,1))this.moveCursorTo(t.end.row,t.end.column);else if(this.lead.column==this.doc.getLine(this.lead.row).length)this.lead.row0&&(t.column=r)}}this.moveCursorTo(t.row,t.column)},this.moveCursorFileEnd=function(){var e=this.doc.getLength()-1,t=this.doc.getLine(e).length;this.moveCursorTo(e,t)},this.moveCursorFileStart=function(){this.moveCursorTo(0,0)},this.moveCursorLongWordRight=function(){var e=this.lead.row,t=this.lead.column,n=this.doc.getLine(e),r=n.substring(t),i;this.session.nonTokenRe.lastIndex=0,this.session.tokenRe.lastIndex=0;var s=this.session.getFoldAt(e,t,1);if(s){this.moveCursorTo(s.end.row,s.end.column);return}if(i=this.session.nonTokenRe.exec(r))t+=this.session.nonTokenRe.lastIndex,this.session.nonTokenRe.lastIndex=0,r=n.substring(t);if(t>=n.length){this.moveCursorTo(e,n.length),this.moveCursorRight(),e0&&this.moveCursorWordLeft();return}if(o=this.session.tokenRe.exec(s))t-=this.session.tokenRe.lastIndex,this.session.tokenRe.lastIndex=0;this.moveCursorTo(e,t)},this.$shortWordEndIndex=function(e){var t,n=0,r,i=/\s/,s=this.session.tokenRe;s.lastIndex=0;if(t=this.session.tokenRe.exec(e))n=this.session.tokenRe.lastIndex;else{while((r=e[n])&&i.test(r))n++;if(n<1){s.lastIndex=0;while((r=e[n])&&!s.test(r)){s.lastIndex=0,n++;if(i.test(r)){if(n>2){n--;break}while((r=e[n])&&i.test(r))n++;if(n>2)break}}}}return s.lastIndex=0,n},this.moveCursorShortWordRight=function(){var e=this.lead.row,t=this.lead.column,n=this.doc.getLine(e),r=n.substring(t),i=this.session.getFoldAt(e,t,1);if(i)return this.moveCursorTo(i.end.row,i.end.column);if(t==n.length){var s=this.doc.getLength();do e++,r=this.doc.getLine(e);while(e0&&/^\s*$/.test(r));t=r.length,/\s+$/.test(r)||(r="")}var s=i.stringReverse(r),o=this.$shortWordEndIndex(s);return this.moveCursorTo(e,t-o)},this.moveCursorWordRight=function(){this.session.$selectLongWords?this.moveCursorLongWordRight():this.moveCursorShortWordRight()},this.moveCursorWordLeft=function(){this.session.$selectLongWords?this.moveCursorLongWordLeft():this.moveCursorShortWordLeft()},this.moveCursorBy=function(e,t){var n=this.session.documentToScreenPosition(this.lead.row,this.lead.column);t===0&&(this.$desiredColumn?n.column=this.$desiredColumn:this.$desiredColumn=n.column);var r=this.session.screenToDocumentPosition(n.row+e,n.column);e!==0&&t===0&&r.row===this.lead.row&&r.column===this.lead.column&&this.session.lineWidgets&&this.session.lineWidgets[r.row]&&(r.row>0||e>0)&&r.row++,this.moveCursorTo(r.row,r.column+t,t===0)},this.moveCursorToPosition=function(e){this.moveCursorTo(e.row,e.column)},this.moveCursorTo=function(e,t,n){var r=this.session.getFoldAt(e,t,1);r&&(e=r.start.row,t=r.start.column),this.$keepDesiredColumnOnChange=!0,this.lead.setPosition(e,t),this.$keepDesiredColumnOnChange=!1,n||(this.$desiredColumn=null)},this.moveCursorToScreen=function(e,t,n){var r=this.session.screenToDocumentPosition(e,t);this.moveCursorTo(r.row,r.column,n)},this.detach=function(){this.lead.detach(),this.anchor.detach(),this.session=this.doc=null},this.fromOrientedRange=function(e){this.setSelectionRange(e,e.cursor==e.start),this.$desiredColumn=e.desiredColumn||this.$desiredColumn},this.toOrientedRange=function(e){var t=this.getRange();return e?(e.start.column=t.start.column,e.start.row=t.start.row,e.end.column=t.end.column,e.end.row=t.end.row):e=t,e.cursor=this.isBackwards()?e.start:e.end,e.desiredColumn=this.$desiredColumn,e},this.getRangeOfMovements=function(e){var t=this.getCursor();try{e(this);var n=this.getCursor();return o.fromPoints(t,n)}catch(r){return o.fromPoints(t,t)}finally{this.moveCursorToPosition(t)}},this.toJSON=function(){if(this.rangeCount)var e=this.ranges.map(function(e){var t=e.clone();return t.isBackwards=e.cursor==e.start,t});else{var e=this.getRange();e.isBackwards=this.isBackwards()}return e},this.fromJSON=function(e){if(e.start==undefined){if(this.rangeList){this.toSingleRange(e[0]);for(var t=e.length;t--;){var n=o.fromPoints(e[t].start,e[t].end);e[t].isBackwards&&(n.cursor=n.start),this.addRange(n,!0)}return}e=e[0]}this.rangeList&&this.toSingleRange(e),this.setSelectionRange(e,e.isBackwards)},this.isEqual=function(e){if((e.length||this.rangeCount)&&e.length!=this.rangeCount)return!1;if(!e.length||!this.ranges)return this.getRange().isEqual(e);for(var t=this.ranges.length;t--;)if(!this.ranges[t].isEqual(e[t]))return!1;return!0}}).call(u.prototype),t.Selection=u}),define("ace/tokenizer",["require","exports","module","ace/config"],function(e,t,n){"use strict";var r=e("./config"),i=2e3,s=function(e){this.states=e,this.regExps={},this.matchMappings={};for(var t in this.states){var n=this.states[t],r=[],i=0,s=this.matchMappings[t]={defaultToken:"text"},o="g",u=[];for(var a=0;a1?f.onMatch=this.$applyToken:f.onMatch=f.token),c>1&&(/\\\d/.test(f.regex)?l=f.regex.replace(/\\([0-9]+)/g,function(e,t){return"\\"+(parseInt(t,10)+i+1)}):(c=1,l=this.removeCapturingGroups(f.regex)),!f.splitRegex&&typeof f.token!="string"&&u.push(f)),s[i]=a,i+=c,r.push(l),f.onMatch||(f.onMatch=null)}r.length||(s[0]=0,r.push("$")),u.forEach(function(e){e.splitRegex=this.createSplitterRegexp(e.regex,o)},this),this.regExps[t]=new RegExp("("+r.join(")|(")+")|($)",o)}};(function(){this.$setMaxTokenCount=function(e){i=e|0},this.$applyToken=function(e){var t=this.splitRegex.exec(e).slice(1),n=this.token.apply(this,t);if(typeof n=="string")return[{type:n,value:e}];var r=[];for(var i=0,s=n.length;il){var g=e.substring(l,m-v.length);h.type==p?h.value+=g:(h.type&&f.push(h),h={type:p,value:g})}for(var y=0;yi){c>2*e.length&&this.reportError("infinite loop with in ace tokenizer",{startState:t,line:e});while(l1&&n[0]!==r&&n.unshift("#tmp",r),{tokens:f,state:n.length?n:r}},this.reportError=r.reportError}).call(s.prototype),t.Tokenizer=s}),define("ace/mode/text_highlight_rules",["require","exports","module","ace/lib/lang"],function(e,t,n){"use strict";var r=e("../lib/lang"),i=function(){this.$rules={start:[{token:"empty_line",regex:"^$"},{defaultToken:"text"}]}};(function(){this.addRules=function(e,t){if(!t){for(var n in e)this.$rules[n]=e[n];return}for(var n in e){var r=e[n];for(var i=0;i=this.$rowTokens.length){this.$row+=1,e||(e=this.$session.getLength());if(this.$row>=e)return this.$row=e-1,null;this.$rowTokens=this.$session.getTokens(this.$row),this.$tokenIndex=0}return this.$rowTokens[this.$tokenIndex]},this.getCurrentToken=function(){return this.$rowTokens[this.$tokenIndex]},this.getCurrentTokenRow=function(){return this.$row},this.getCurrentTokenColumn=function(){var e=this.$rowTokens,t=this.$tokenIndex,n=e[t].start;if(n!==undefined)return n;n=0;while(t>0)t-=1,n+=e[t].value.length;return n},this.getCurrentTokenPosition=function(){return{row:this.$row,column:this.getCurrentTokenColumn()}}}).call(r.prototype),t.TokenIterator=r}),define("ace/mode/behaviour/cstyle",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator","ace/lib/lang"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("../../token_iterator").TokenIterator,o=e("../../lib/lang"),u=["text","paren.rparen","punctuation.operator"],a=["text","paren.rparen","punctuation.operator","comment"],f,l={},c=function(e){var t=-1;e.multiSelect&&(t=e.selection.index,l.rangeCount!=e.multiSelect.rangeCount&&(l={rangeCount:e.multiSelect.rangeCount}));if(l[t])return f=l[t];f=l[t]={autoInsertedBrackets:0,autoInsertedRow:-1,autoInsertedLineEnd:"",maybeInsertedBrackets:0,maybeInsertedRow:-1,maybeInsertedLineStart:"",maybeInsertedLineEnd:""}},h=function(e,t,n,r){var i=e.end.row-e.start.row;return{text:n+t+r,selection:[0,e.start.column+1,i,e.end.column+(i?0:1)]}},p=function(){this.add("braces","insertion",function(e,t,n,r,i){var s=n.getCursorPosition(),u=r.doc.getLine(s.row);if(i=="{"){c(n);var a=n.getSelectionRange(),l=r.doc.getTextRange(a);if(l!==""&&l!=="{"&&n.getWrapBehavioursEnabled())return h(a,l,"{","}");if(p.isSaneInsertion(n,r))return/[\]\}\)]/.test(u[s.column])||n.inMultiSelectMode?(p.recordAutoInsert(n,r,"}"),{text:"{}",selection:[1,1]}):(p.recordMaybeInsert(n,r,"{"),{text:"{",selection:[1,1]})}else if(i=="}"){c(n);var d=u.substring(s.column,s.column+1);if(d=="}"){var v=r.$findOpeningBracket("}",{column:s.column+1,row:s.row});if(v!==null&&p.isAutoInsertedClosing(s,u,i))return p.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}else{if(i=="\n"||i=="\r\n"){c(n);var m="";p.isMaybeInsertedClosing(s,u)&&(m=o.stringRepeat("}",f.maybeInsertedBrackets),p.clearMaybeInsertedClosing());var d=u.substring(s.column,s.column+1);if(d==="}"){var g=r.findMatchingBracket({row:s.row,column:s.column+1},"}");if(!g)return null;var y=this.$getIndent(r.getLine(g.row))}else{if(!m){p.clearMaybeInsertedClosing();return}var y=this.$getIndent(u)}var b=y+r.getTabString();return{text:"\n"+b+"\n"+y+m,selection:[1,b.length,1,b.length]}}p.clearMaybeInsertedClosing()}}),this.add("braces","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="{"){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.end.column,i.end.column+1);if(u=="}")return i.end.column++,i;f.maybeInsertedBrackets--}}),this.add("parens","insertion",function(e,t,n,r,i){if(i=="("){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return h(s,o,"(",")");if(p.isSaneInsertion(n,r))return p.recordAutoInsert(n,r,")"),{text:"()",selection:[1,1]}}else if(i==")"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f==")"){var l=r.$findOpeningBracket(")",{column:u.column+1,row:u.row});if(l!==null&&p.isAutoInsertedClosing(u,a,i))return p.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("parens","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="("){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==")")return i.end.column++,i}}),this.add("brackets","insertion",function(e,t,n,r,i){if(i=="["){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return h(s,o,"[","]");if(p.isSaneInsertion(n,r))return p.recordAutoInsert(n,r,"]"),{text:"[]",selection:[1,1]}}else if(i=="]"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f=="]"){var l=r.$findOpeningBracket("]",{column:u.column+1,row:u.row});if(l!==null&&p.isAutoInsertedClosing(u,a,i))return p.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("brackets","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="["){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u=="]")return i.end.column++,i}}),this.add("string_dquotes","insertion",function(e,t,n,r,i){if(i=='"'||i=="'"){if(this.lineCommentStart&&this.lineCommentStart.indexOf(i)!=-1)return;c(n);var s=i,o=n.getSelectionRange(),u=r.doc.getTextRange(o);if(u!==""&&u!=="'"&&u!='"'&&n.getWrapBehavioursEnabled())return h(o,u,s,s);if(!u){var a=n.getCursorPosition(),f=r.doc.getLine(a.row),l=f.substring(a.column-1,a.column),p=f.substring(a.column,a.column+1),d=r.getTokenAt(a.row,a.column),v=r.getTokenAt(a.row,a.column+1);if(l=="\\"&&d&&/escape/.test(d.type))return null;var m=d&&/string|escape/.test(d.type),g=!v||/string|escape/.test(v.type),y;if(p==s)y=m!==g,y&&/string\.end/.test(v.type)&&(y=!1);else{if(m&&!g)return null;if(m&&g)return null;var b=r.$mode.tokenRe;b.lastIndex=0;var w=b.test(l);b.lastIndex=0;var E=b.test(l);if(w||E)return null;if(p&&!/[\s;,.})\]\\]/.test(p))return null;y=!0}return{text:y?s+s:"",selection:[1,1]}}}}),this.add("string_dquotes","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&(s=='"'||s=="'")){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==s)return i.end.column++,i}})};p.isSaneInsertion=function(e,t){var n=e.getCursorPosition(),r=new s(t,n.row,n.column);if(!this.$matchTokenType(r.getCurrentToken()||"text",u)){var i=new s(t,n.row,n.column+1);if(!this.$matchTokenType(i.getCurrentToken()||"text",u))return!1}return r.stepForward(),r.getCurrentTokenRow()!==n.row||this.$matchTokenType(r.getCurrentToken()||"text",a)},p.$matchTokenType=function(e,t){return t.indexOf(e.type||e)>-1},p.recordAutoInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isAutoInsertedClosing(r,i,f.autoInsertedLineEnd[0])||(f.autoInsertedBrackets=0),f.autoInsertedRow=r.row,f.autoInsertedLineEnd=n+i.substr(r.column),f.autoInsertedBrackets++},p.recordMaybeInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isMaybeInsertedClosing(r,i)||(f.maybeInsertedBrackets=0),f.maybeInsertedRow=r.row,f.maybeInsertedLineStart=i.substr(0,r.column)+n,f.maybeInsertedLineEnd=i.substr(r.column),f.maybeInsertedBrackets++},p.isAutoInsertedClosing=function(e,t,n){return f.autoInsertedBrackets>0&&e.row===f.autoInsertedRow&&n===f.autoInsertedLineEnd[0]&&t.substr(e.column)===f.autoInsertedLineEnd},p.isMaybeInsertedClosing=function(e,t){return f.maybeInsertedBrackets>0&&e.row===f.maybeInsertedRow&&t.substr(e.column)===f.maybeInsertedLineEnd&&t.substr(0,e.column)==f.maybeInsertedLineStart},p.popAutoInsertedClosing=function(){f.autoInsertedLineEnd=f.autoInsertedLineEnd.substr(1),f.autoInsertedBrackets--},p.clearMaybeInsertedClosing=function(){f&&(f.maybeInsertedBrackets=0,f.maybeInsertedRow=-1)},r.inherits(p,i),t.CstyleBehaviour=p}),define("ace/unicode",["require","exports","module"],function(e,t,n){"use strict";function r(e){var n=/\w{4}/g;for(var r in e)t.packages[r]=e[r].replace(n,"\\u$&")}t.packages={},r({L:"0041-005A0061-007A00AA00B500BA00C0-00D600D8-00F600F8-02C102C6-02D102E0-02E402EC02EE0370-037403760377037A-037D03860388-038A038C038E-03A103A3-03F503F7-0481048A-05250531-055605590561-058705D0-05EA05F0-05F20621-064A066E066F0671-06D306D506E506E606EE06EF06FA-06FC06FF07100712-072F074D-07A507B107CA-07EA07F407F507FA0800-0815081A082408280904-0939093D09500958-0961097109720979-097F0985-098C098F09900993-09A809AA-09B009B209B6-09B909BD09CE09DC09DD09DF-09E109F009F10A05-0A0A0A0F0A100A13-0A280A2A-0A300A320A330A350A360A380A390A59-0A5C0A5E0A72-0A740A85-0A8D0A8F-0A910A93-0AA80AAA-0AB00AB20AB30AB5-0AB90ABD0AD00AE00AE10B05-0B0C0B0F0B100B13-0B280B2A-0B300B320B330B35-0B390B3D0B5C0B5D0B5F-0B610B710B830B85-0B8A0B8E-0B900B92-0B950B990B9A0B9C0B9E0B9F0BA30BA40BA8-0BAA0BAE-0BB90BD00C05-0C0C0C0E-0C100C12-0C280C2A-0C330C35-0C390C3D0C580C590C600C610C85-0C8C0C8E-0C900C92-0CA80CAA-0CB30CB5-0CB90CBD0CDE0CE00CE10D05-0D0C0D0E-0D100D12-0D280D2A-0D390D3D0D600D610D7A-0D7F0D85-0D960D9A-0DB10DB3-0DBB0DBD0DC0-0DC60E01-0E300E320E330E40-0E460E810E820E840E870E880E8A0E8D0E94-0E970E99-0E9F0EA1-0EA30EA50EA70EAA0EAB0EAD-0EB00EB20EB30EBD0EC0-0EC40EC60EDC0EDD0F000F40-0F470F49-0F6C0F88-0F8B1000-102A103F1050-1055105A-105D106110651066106E-10701075-1081108E10A0-10C510D0-10FA10FC1100-1248124A-124D1250-12561258125A-125D1260-1288128A-128D1290-12B012B2-12B512B8-12BE12C012C2-12C512C8-12D612D8-13101312-13151318-135A1380-138F13A0-13F41401-166C166F-167F1681-169A16A0-16EA1700-170C170E-17111720-17311740-17511760-176C176E-17701780-17B317D717DC1820-18771880-18A818AA18B0-18F51900-191C1950-196D1970-19741980-19AB19C1-19C71A00-1A161A20-1A541AA71B05-1B331B45-1B4B1B83-1BA01BAE1BAF1C00-1C231C4D-1C4F1C5A-1C7D1CE9-1CEC1CEE-1CF11D00-1DBF1E00-1F151F18-1F1D1F20-1F451F48-1F4D1F50-1F571F591F5B1F5D1F5F-1F7D1F80-1FB41FB6-1FBC1FBE1FC2-1FC41FC6-1FCC1FD0-1FD31FD6-1FDB1FE0-1FEC1FF2-1FF41FF6-1FFC2071207F2090-209421022107210A-211321152119-211D212421262128212A-212D212F-2139213C-213F2145-2149214E218321842C00-2C2E2C30-2C5E2C60-2CE42CEB-2CEE2D00-2D252D30-2D652D6F2D80-2D962DA0-2DA62DA8-2DAE2DB0-2DB62DB8-2DBE2DC0-2DC62DC8-2DCE2DD0-2DD62DD8-2DDE2E2F300530063031-3035303B303C3041-3096309D-309F30A1-30FA30FC-30FF3105-312D3131-318E31A0-31B731F0-31FF3400-4DB54E00-9FCBA000-A48CA4D0-A4FDA500-A60CA610-A61FA62AA62BA640-A65FA662-A66EA67F-A697A6A0-A6E5A717-A71FA722-A788A78BA78CA7FB-A801A803-A805A807-A80AA80C-A822A840-A873A882-A8B3A8F2-A8F7A8FBA90A-A925A930-A946A960-A97CA984-A9B2A9CFAA00-AA28AA40-AA42AA44-AA4BAA60-AA76AA7AAA80-AAAFAAB1AAB5AAB6AAB9-AABDAAC0AAC2AADB-AADDABC0-ABE2AC00-D7A3D7B0-D7C6D7CB-D7FBF900-FA2DFA30-FA6DFA70-FAD9FB00-FB06FB13-FB17FB1DFB1F-FB28FB2A-FB36FB38-FB3CFB3EFB40FB41FB43FB44FB46-FBB1FBD3-FD3DFD50-FD8FFD92-FDC7FDF0-FDFBFE70-FE74FE76-FEFCFF21-FF3AFF41-FF5AFF66-FFBEFFC2-FFC7FFCA-FFCFFFD2-FFD7FFDA-FFDC",Ll:"0061-007A00AA00B500BA00DF-00F600F8-00FF01010103010501070109010B010D010F01110113011501170119011B011D011F01210123012501270129012B012D012F01310133013501370138013A013C013E014001420144014601480149014B014D014F01510153015501570159015B015D015F01610163016501670169016B016D016F0171017301750177017A017C017E-0180018301850188018C018D019201950199-019B019E01A101A301A501A801AA01AB01AD01B001B401B601B901BA01BD-01BF01C601C901CC01CE01D001D201D401D601D801DA01DC01DD01DF01E101E301E501E701E901EB01ED01EF01F001F301F501F901FB01FD01FF02010203020502070209020B020D020F02110213021502170219021B021D021F02210223022502270229022B022D022F02310233-0239023C023F0240024202470249024B024D024F-02930295-02AF037103730377037B-037D039003AC-03CE03D003D103D5-03D703D903DB03DD03DF03E103E303E503E703E903EB03ED03EF-03F303F503F803FB03FC0430-045F04610463046504670469046B046D046F04710473047504770479047B047D047F0481048B048D048F04910493049504970499049B049D049F04A104A304A504A704A904AB04AD04AF04B104B304B504B704B904BB04BD04BF04C204C404C604C804CA04CC04CE04CF04D104D304D504D704D904DB04DD04DF04E104E304E504E704E904EB04ED04EF04F104F304F504F704F904FB04FD04FF05010503050505070509050B050D050F05110513051505170519051B051D051F0521052305250561-05871D00-1D2B1D62-1D771D79-1D9A1E011E031E051E071E091E0B1E0D1E0F1E111E131E151E171E191E1B1E1D1E1F1E211E231E251E271E291E2B1E2D1E2F1E311E331E351E371E391E3B1E3D1E3F1E411E431E451E471E491E4B1E4D1E4F1E511E531E551E571E591E5B1E5D1E5F1E611E631E651E671E691E6B1E6D1E6F1E711E731E751E771E791E7B1E7D1E7F1E811E831E851E871E891E8B1E8D1E8F1E911E931E95-1E9D1E9F1EA11EA31EA51EA71EA91EAB1EAD1EAF1EB11EB31EB51EB71EB91EBB1EBD1EBF1EC11EC31EC51EC71EC91ECB1ECD1ECF1ED11ED31ED51ED71ED91EDB1EDD1EDF1EE11EE31EE51EE71EE91EEB1EED1EEF1EF11EF31EF51EF71EF91EFB1EFD1EFF-1F071F10-1F151F20-1F271F30-1F371F40-1F451F50-1F571F60-1F671F70-1F7D1F80-1F871F90-1F971FA0-1FA71FB0-1FB41FB61FB71FBE1FC2-1FC41FC61FC71FD0-1FD31FD61FD71FE0-1FE71FF2-1FF41FF61FF7210A210E210F2113212F21342139213C213D2146-2149214E21842C30-2C5E2C612C652C662C682C6A2C6C2C712C732C742C76-2C7C2C812C832C852C872C892C8B2C8D2C8F2C912C932C952C972C992C9B2C9D2C9F2CA12CA32CA52CA72CA92CAB2CAD2CAF2CB12CB32CB52CB72CB92CBB2CBD2CBF2CC12CC32CC52CC72CC92CCB2CCD2CCF2CD12CD32CD52CD72CD92CDB2CDD2CDF2CE12CE32CE42CEC2CEE2D00-2D25A641A643A645A647A649A64BA64DA64FA651A653A655A657A659A65BA65DA65FA663A665A667A669A66BA66DA681A683A685A687A689A68BA68DA68FA691A693A695A697A723A725A727A729A72BA72DA72F-A731A733A735A737A739A73BA73DA73FA741A743A745A747A749A74BA74DA74FA751A753A755A757A759A75BA75DA75FA761A763A765A767A769A76BA76DA76FA771-A778A77AA77CA77FA781A783A785A787A78CFB00-FB06FB13-FB17FF41-FF5A",Lu:"0041-005A00C0-00D600D8-00DE01000102010401060108010A010C010E01100112011401160118011A011C011E01200122012401260128012A012C012E01300132013401360139013B013D013F0141014301450147014A014C014E01500152015401560158015A015C015E01600162016401660168016A016C016E017001720174017601780179017B017D018101820184018601870189-018B018E-0191019301940196-0198019C019D019F01A001A201A401A601A701A901AC01AE01AF01B1-01B301B501B701B801BC01C401C701CA01CD01CF01D101D301D501D701D901DB01DE01E001E201E401E601E801EA01EC01EE01F101F401F6-01F801FA01FC01FE02000202020402060208020A020C020E02100212021402160218021A021C021E02200222022402260228022A022C022E02300232023A023B023D023E02410243-02460248024A024C024E03700372037603860388-038A038C038E038F0391-03A103A3-03AB03CF03D2-03D403D803DA03DC03DE03E003E203E403E603E803EA03EC03EE03F403F703F903FA03FD-042F04600462046404660468046A046C046E04700472047404760478047A047C047E0480048A048C048E04900492049404960498049A049C049E04A004A204A404A604A804AA04AC04AE04B004B204B404B604B804BA04BC04BE04C004C104C304C504C704C904CB04CD04D004D204D404D604D804DA04DC04DE04E004E204E404E604E804EA04EC04EE04F004F204F404F604F804FA04FC04FE05000502050405060508050A050C050E05100512051405160518051A051C051E0520052205240531-055610A0-10C51E001E021E041E061E081E0A1E0C1E0E1E101E121E141E161E181E1A1E1C1E1E1E201E221E241E261E281E2A1E2C1E2E1E301E321E341E361E381E3A1E3C1E3E1E401E421E441E461E481E4A1E4C1E4E1E501E521E541E561E581E5A1E5C1E5E1E601E621E641E661E681E6A1E6C1E6E1E701E721E741E761E781E7A1E7C1E7E1E801E821E841E861E881E8A1E8C1E8E1E901E921E941E9E1EA01EA21EA41EA61EA81EAA1EAC1EAE1EB01EB21EB41EB61EB81EBA1EBC1EBE1EC01EC21EC41EC61EC81ECA1ECC1ECE1ED01ED21ED41ED61ED81EDA1EDC1EDE1EE01EE21EE41EE61EE81EEA1EEC1EEE1EF01EF21EF41EF61EF81EFA1EFC1EFE1F08-1F0F1F18-1F1D1F28-1F2F1F38-1F3F1F48-1F4D1F591F5B1F5D1F5F1F68-1F6F1FB8-1FBB1FC8-1FCB1FD8-1FDB1FE8-1FEC1FF8-1FFB21022107210B-210D2110-211221152119-211D212421262128212A-212D2130-2133213E213F214521832C00-2C2E2C602C62-2C642C672C692C6B2C6D-2C702C722C752C7E-2C802C822C842C862C882C8A2C8C2C8E2C902C922C942C962C982C9A2C9C2C9E2CA02CA22CA42CA62CA82CAA2CAC2CAE2CB02CB22CB42CB62CB82CBA2CBC2CBE2CC02CC22CC42CC62CC82CCA2CCC2CCE2CD02CD22CD42CD62CD82CDA2CDC2CDE2CE02CE22CEB2CEDA640A642A644A646A648A64AA64CA64EA650A652A654A656A658A65AA65CA65EA662A664A666A668A66AA66CA680A682A684A686A688A68AA68CA68EA690A692A694A696A722A724A726A728A72AA72CA72EA732A734A736A738A73AA73CA73EA740A742A744A746A748A74AA74CA74EA750A752A754A756A758A75AA75CA75EA760A762A764A766A768A76AA76CA76EA779A77BA77DA77EA780A782A784A786A78BFF21-FF3A",Lt:"01C501C801CB01F21F88-1F8F1F98-1F9F1FA8-1FAF1FBC1FCC1FFC",Lm:"02B0-02C102C6-02D102E0-02E402EC02EE0374037A0559064006E506E607F407F507FA081A0824082809710E460EC610FC17D718431AA71C78-1C7D1D2C-1D611D781D9B-1DBF2071207F2090-20942C7D2D6F2E2F30053031-3035303B309D309E30FC-30FEA015A4F8-A4FDA60CA67FA717-A71FA770A788A9CFAA70AADDFF70FF9EFF9F",Lo:"01BB01C0-01C3029405D0-05EA05F0-05F20621-063F0641-064A066E066F0671-06D306D506EE06EF06FA-06FC06FF07100712-072F074D-07A507B107CA-07EA0800-08150904-0939093D09500958-096109720979-097F0985-098C098F09900993-09A809AA-09B009B209B6-09B909BD09CE09DC09DD09DF-09E109F009F10A05-0A0A0A0F0A100A13-0A280A2A-0A300A320A330A350A360A380A390A59-0A5C0A5E0A72-0A740A85-0A8D0A8F-0A910A93-0AA80AAA-0AB00AB20AB30AB5-0AB90ABD0AD00AE00AE10B05-0B0C0B0F0B100B13-0B280B2A-0B300B320B330B35-0B390B3D0B5C0B5D0B5F-0B610B710B830B85-0B8A0B8E-0B900B92-0B950B990B9A0B9C0B9E0B9F0BA30BA40BA8-0BAA0BAE-0BB90BD00C05-0C0C0C0E-0C100C12-0C280C2A-0C330C35-0C390C3D0C580C590C600C610C85-0C8C0C8E-0C900C92-0CA80CAA-0CB30CB5-0CB90CBD0CDE0CE00CE10D05-0D0C0D0E-0D100D12-0D280D2A-0D390D3D0D600D610D7A-0D7F0D85-0D960D9A-0DB10DB3-0DBB0DBD0DC0-0DC60E01-0E300E320E330E40-0E450E810E820E840E870E880E8A0E8D0E94-0E970E99-0E9F0EA1-0EA30EA50EA70EAA0EAB0EAD-0EB00EB20EB30EBD0EC0-0EC40EDC0EDD0F000F40-0F470F49-0F6C0F88-0F8B1000-102A103F1050-1055105A-105D106110651066106E-10701075-1081108E10D0-10FA1100-1248124A-124D1250-12561258125A-125D1260-1288128A-128D1290-12B012B2-12B512B8-12BE12C012C2-12C512C8-12D612D8-13101312-13151318-135A1380-138F13A0-13F41401-166C166F-167F1681-169A16A0-16EA1700-170C170E-17111720-17311740-17511760-176C176E-17701780-17B317DC1820-18421844-18771880-18A818AA18B0-18F51900-191C1950-196D1970-19741980-19AB19C1-19C71A00-1A161A20-1A541B05-1B331B45-1B4B1B83-1BA01BAE1BAF1C00-1C231C4D-1C4F1C5A-1C771CE9-1CEC1CEE-1CF12135-21382D30-2D652D80-2D962DA0-2DA62DA8-2DAE2DB0-2DB62DB8-2DBE2DC0-2DC62DC8-2DCE2DD0-2DD62DD8-2DDE3006303C3041-3096309F30A1-30FA30FF3105-312D3131-318E31A0-31B731F0-31FF3400-4DB54E00-9FCBA000-A014A016-A48CA4D0-A4F7A500-A60BA610-A61FA62AA62BA66EA6A0-A6E5A7FB-A801A803-A805A807-A80AA80C-A822A840-A873A882-A8B3A8F2-A8F7A8FBA90A-A925A930-A946A960-A97CA984-A9B2AA00-AA28AA40-AA42AA44-AA4BAA60-AA6FAA71-AA76AA7AAA80-AAAFAAB1AAB5AAB6AAB9-AABDAAC0AAC2AADBAADCABC0-ABE2AC00-D7A3D7B0-D7C6D7CB-D7FBF900-FA2DFA30-FA6DFA70-FAD9FB1DFB1F-FB28FB2A-FB36FB38-FB3CFB3EFB40FB41FB43FB44FB46-FBB1FBD3-FD3DFD50-FD8FFD92-FDC7FDF0-FDFBFE70-FE74FE76-FEFCFF66-FF6FFF71-FF9DFFA0-FFBEFFC2-FFC7FFCA-FFCFFFD2-FFD7FFDA-FFDC",M:"0300-036F0483-04890591-05BD05BF05C105C205C405C505C70610-061A064B-065E067006D6-06DC06DE-06E406E706E806EA-06ED07110730-074A07A6-07B007EB-07F30816-0819081B-08230825-08270829-082D0900-0903093C093E-094E0951-0955096209630981-098309BC09BE-09C409C709C809CB-09CD09D709E209E30A01-0A030A3C0A3E-0A420A470A480A4B-0A4D0A510A700A710A750A81-0A830ABC0ABE-0AC50AC7-0AC90ACB-0ACD0AE20AE30B01-0B030B3C0B3E-0B440B470B480B4B-0B4D0B560B570B620B630B820BBE-0BC20BC6-0BC80BCA-0BCD0BD70C01-0C030C3E-0C440C46-0C480C4A-0C4D0C550C560C620C630C820C830CBC0CBE-0CC40CC6-0CC80CCA-0CCD0CD50CD60CE20CE30D020D030D3E-0D440D46-0D480D4A-0D4D0D570D620D630D820D830DCA0DCF-0DD40DD60DD8-0DDF0DF20DF30E310E34-0E3A0E47-0E4E0EB10EB4-0EB90EBB0EBC0EC8-0ECD0F180F190F350F370F390F3E0F3F0F71-0F840F860F870F90-0F970F99-0FBC0FC6102B-103E1056-1059105E-10601062-10641067-106D1071-10741082-108D108F109A-109D135F1712-17141732-1734175217531772177317B6-17D317DD180B-180D18A91920-192B1930-193B19B0-19C019C819C91A17-1A1B1A55-1A5E1A60-1A7C1A7F1B00-1B041B34-1B441B6B-1B731B80-1B821BA1-1BAA1C24-1C371CD0-1CD21CD4-1CE81CED1CF21DC0-1DE61DFD-1DFF20D0-20F02CEF-2CF12DE0-2DFF302A-302F3099309AA66F-A672A67CA67DA6F0A6F1A802A806A80BA823-A827A880A881A8B4-A8C4A8E0-A8F1A926-A92DA947-A953A980-A983A9B3-A9C0AA29-AA36AA43AA4CAA4DAA7BAAB0AAB2-AAB4AAB7AAB8AABEAABFAAC1ABE3-ABEAABECABEDFB1EFE00-FE0FFE20-FE26",Mn:"0300-036F0483-04870591-05BD05BF05C105C205C405C505C70610-061A064B-065E067006D6-06DC06DF-06E406E706E806EA-06ED07110730-074A07A6-07B007EB-07F30816-0819081B-08230825-08270829-082D0900-0902093C0941-0948094D0951-095509620963098109BC09C1-09C409CD09E209E30A010A020A3C0A410A420A470A480A4B-0A4D0A510A700A710A750A810A820ABC0AC1-0AC50AC70AC80ACD0AE20AE30B010B3C0B3F0B41-0B440B4D0B560B620B630B820BC00BCD0C3E-0C400C46-0C480C4A-0C4D0C550C560C620C630CBC0CBF0CC60CCC0CCD0CE20CE30D41-0D440D4D0D620D630DCA0DD2-0DD40DD60E310E34-0E3A0E47-0E4E0EB10EB4-0EB90EBB0EBC0EC8-0ECD0F180F190F350F370F390F71-0F7E0F80-0F840F860F870F90-0F970F99-0FBC0FC6102D-10301032-10371039103A103D103E10581059105E-10601071-1074108210851086108D109D135F1712-17141732-1734175217531772177317B7-17BD17C617C9-17D317DD180B-180D18A91920-19221927192819321939-193B1A171A181A561A58-1A5E1A601A621A65-1A6C1A73-1A7C1A7F1B00-1B031B341B36-1B3A1B3C1B421B6B-1B731B801B811BA2-1BA51BA81BA91C2C-1C331C361C371CD0-1CD21CD4-1CE01CE2-1CE81CED1DC0-1DE61DFD-1DFF20D0-20DC20E120E5-20F02CEF-2CF12DE0-2DFF302A-302F3099309AA66FA67CA67DA6F0A6F1A802A806A80BA825A826A8C4A8E0-A8F1A926-A92DA947-A951A980-A982A9B3A9B6-A9B9A9BCAA29-AA2EAA31AA32AA35AA36AA43AA4CAAB0AAB2-AAB4AAB7AAB8AABEAABFAAC1ABE5ABE8ABEDFB1EFE00-FE0FFE20-FE26",Mc:"0903093E-09400949-094C094E0982098309BE-09C009C709C809CB09CC09D70A030A3E-0A400A830ABE-0AC00AC90ACB0ACC0B020B030B3E0B400B470B480B4B0B4C0B570BBE0BBF0BC10BC20BC6-0BC80BCA-0BCC0BD70C01-0C030C41-0C440C820C830CBE0CC0-0CC40CC70CC80CCA0CCB0CD50CD60D020D030D3E-0D400D46-0D480D4A-0D4C0D570D820D830DCF-0DD10DD8-0DDF0DF20DF30F3E0F3F0F7F102B102C10311038103B103C105610571062-10641067-106D108310841087-108C108F109A-109C17B617BE-17C517C717C81923-19261929-192B193019311933-193819B0-19C019C819C91A19-1A1B1A551A571A611A631A641A6D-1A721B041B351B3B1B3D-1B411B431B441B821BA11BA61BA71BAA1C24-1C2B1C341C351CE11CF2A823A824A827A880A881A8B4-A8C3A952A953A983A9B4A9B5A9BAA9BBA9BD-A9C0AA2FAA30AA33AA34AA4DAA7BABE3ABE4ABE6ABE7ABE9ABEAABEC",Me:"0488048906DE20DD-20E020E2-20E4A670-A672",N:"0030-003900B200B300B900BC-00BE0660-066906F0-06F907C0-07C90966-096F09E6-09EF09F4-09F90A66-0A6F0AE6-0AEF0B66-0B6F0BE6-0BF20C66-0C6F0C78-0C7E0CE6-0CEF0D66-0D750E50-0E590ED0-0ED90F20-0F331040-10491090-10991369-137C16EE-16F017E0-17E917F0-17F91810-18191946-194F19D0-19DA1A80-1A891A90-1A991B50-1B591BB0-1BB91C40-1C491C50-1C5920702074-20792080-20892150-21822185-21892460-249B24EA-24FF2776-27932CFD30073021-30293038-303A3192-31953220-32293251-325F3280-328932B1-32BFA620-A629A6E6-A6EFA830-A835A8D0-A8D9A900-A909A9D0-A9D9AA50-AA59ABF0-ABF9FF10-FF19",Nd:"0030-00390660-066906F0-06F907C0-07C90966-096F09E6-09EF0A66-0A6F0AE6-0AEF0B66-0B6F0BE6-0BEF0C66-0C6F0CE6-0CEF0D66-0D6F0E50-0E590ED0-0ED90F20-0F291040-10491090-109917E0-17E91810-18191946-194F19D0-19DA1A80-1A891A90-1A991B50-1B591BB0-1BB91C40-1C491C50-1C59A620-A629A8D0-A8D9A900-A909A9D0-A9D9AA50-AA59ABF0-ABF9FF10-FF19",Nl:"16EE-16F02160-21822185-218830073021-30293038-303AA6E6-A6EF",No:"00B200B300B900BC-00BE09F4-09F90BF0-0BF20C78-0C7E0D70-0D750F2A-0F331369-137C17F0-17F920702074-20792080-20892150-215F21892460-249B24EA-24FF2776-27932CFD3192-31953220-32293251-325F3280-328932B1-32BFA830-A835",P:"0021-00230025-002A002C-002F003A003B003F0040005B-005D005F007B007D00A100AB00B700BB00BF037E0387055A-055F0589058A05BE05C005C305C605F305F40609060A060C060D061B061E061F066A-066D06D40700-070D07F7-07F90830-083E0964096509700DF40E4F0E5A0E5B0F04-0F120F3A-0F3D0F850FD0-0FD4104A-104F10FB1361-13681400166D166E169B169C16EB-16ED1735173617D4-17D617D8-17DA1800-180A1944194519DE19DF1A1E1A1F1AA0-1AA61AA8-1AAD1B5A-1B601C3B-1C3F1C7E1C7F1CD32010-20272030-20432045-20512053-205E207D207E208D208E2329232A2768-277527C527C627E6-27EF2983-299829D8-29DB29FC29FD2CF9-2CFC2CFE2CFF2E00-2E2E2E302E313001-30033008-30113014-301F3030303D30A030FBA4FEA4FFA60D-A60FA673A67EA6F2-A6F7A874-A877A8CEA8CFA8F8-A8FAA92EA92FA95FA9C1-A9CDA9DEA9DFAA5C-AA5FAADEAADFABEBFD3EFD3FFE10-FE19FE30-FE52FE54-FE61FE63FE68FE6AFE6BFF01-FF03FF05-FF0AFF0C-FF0FFF1AFF1BFF1FFF20FF3B-FF3DFF3FFF5BFF5DFF5F-FF65",Pd:"002D058A05BE140018062010-20152E172E1A301C303030A0FE31FE32FE58FE63FF0D",Ps:"0028005B007B0F3A0F3C169B201A201E2045207D208D23292768276A276C276E27702772277427C527E627E827EA27EC27EE2983298529872989298B298D298F299129932995299729D829DA29FC2E222E242E262E283008300A300C300E3010301430163018301A301DFD3EFE17FE35FE37FE39FE3BFE3DFE3FFE41FE43FE47FE59FE5BFE5DFF08FF3BFF5BFF5FFF62",Pe:"0029005D007D0F3B0F3D169C2046207E208E232A2769276B276D276F27712773277527C627E727E927EB27ED27EF298429862988298A298C298E2990299229942996299829D929DB29FD2E232E252E272E293009300B300D300F3011301530173019301B301E301FFD3FFE18FE36FE38FE3AFE3CFE3EFE40FE42FE44FE48FE5AFE5CFE5EFF09FF3DFF5DFF60FF63",Pi:"00AB2018201B201C201F20392E022E042E092E0C2E1C2E20",Pf:"00BB2019201D203A2E032E052E0A2E0D2E1D2E21",Pc:"005F203F20402054FE33FE34FE4D-FE4FFF3F",Po:"0021-00230025-0027002A002C002E002F003A003B003F0040005C00A100B700BF037E0387055A-055F058905C005C305C605F305F40609060A060C060D061B061E061F066A-066D06D40700-070D07F7-07F90830-083E0964096509700DF40E4F0E5A0E5B0F04-0F120F850FD0-0FD4104A-104F10FB1361-1368166D166E16EB-16ED1735173617D4-17D617D8-17DA1800-18051807-180A1944194519DE19DF1A1E1A1F1AA0-1AA61AA8-1AAD1B5A-1B601C3B-1C3F1C7E1C7F1CD3201620172020-20272030-2038203B-203E2041-20432047-205120532055-205E2CF9-2CFC2CFE2CFF2E002E012E06-2E082E0B2E0E-2E162E182E192E1B2E1E2E1F2E2A-2E2E2E302E313001-3003303D30FBA4FEA4FFA60D-A60FA673A67EA6F2-A6F7A874-A877A8CEA8CFA8F8-A8FAA92EA92FA95FA9C1-A9CDA9DEA9DFAA5C-AA5FAADEAADFABEBFE10-FE16FE19FE30FE45FE46FE49-FE4CFE50-FE52FE54-FE57FE5F-FE61FE68FE6AFE6BFF01-FF03FF05-FF07FF0AFF0CFF0EFF0FFF1AFF1BFF1FFF20FF3CFF61FF64FF65",S:"0024002B003C-003E005E0060007C007E00A2-00A900AC00AE-00B100B400B600B800D700F702C2-02C502D2-02DF02E5-02EB02ED02EF-02FF03750384038503F604820606-0608060B060E060F06E906FD06FE07F609F209F309FA09FB0AF10B700BF3-0BFA0C7F0CF10CF20D790E3F0F01-0F030F13-0F170F1A-0F1F0F340F360F380FBE-0FC50FC7-0FCC0FCE0FCF0FD5-0FD8109E109F13601390-139917DB194019E0-19FF1B61-1B6A1B74-1B7C1FBD1FBF-1FC11FCD-1FCF1FDD-1FDF1FED-1FEF1FFD1FFE20442052207A-207C208A-208C20A0-20B8210021012103-21062108210921142116-2118211E-2123212521272129212E213A213B2140-2144214A-214D214F2190-2328232B-23E82400-24262440-244A249C-24E92500-26CD26CF-26E126E326E8-26FF2701-27042706-2709270C-27272729-274B274D274F-27522756-275E2761-276727942798-27AF27B1-27BE27C0-27C427C7-27CA27CC27D0-27E527F0-29822999-29D729DC-29FB29FE-2B4C2B50-2B592CE5-2CEA2E80-2E992E9B-2EF32F00-2FD52FF0-2FFB300430123013302030363037303E303F309B309C319031913196-319F31C0-31E33200-321E322A-32503260-327F328A-32B032C0-32FE3300-33FF4DC0-4DFFA490-A4C6A700-A716A720A721A789A78AA828-A82BA836-A839AA77-AA79FB29FDFCFDFDFE62FE64-FE66FE69FF04FF0BFF1C-FF1EFF3EFF40FF5CFF5EFFE0-FFE6FFE8-FFEEFFFCFFFD",Sm:"002B003C-003E007C007E00AC00B100D700F703F60606-060820442052207A-207C208A-208C2140-2144214B2190-2194219A219B21A021A321A621AE21CE21CF21D221D421F4-22FF2308-230B23202321237C239B-23B323DC-23E125B725C125F8-25FF266F27C0-27C427C7-27CA27CC27D0-27E527F0-27FF2900-29822999-29D729DC-29FB29FE-2AFF2B30-2B442B47-2B4CFB29FE62FE64-FE66FF0BFF1C-FF1EFF5CFF5EFFE2FFE9-FFEC",Sc:"002400A2-00A5060B09F209F309FB0AF10BF90E3F17DB20A0-20B8A838FDFCFE69FF04FFE0FFE1FFE5FFE6",Sk:"005E006000A800AF00B400B802C2-02C502D2-02DF02E5-02EB02ED02EF-02FF0375038403851FBD1FBF-1FC11FCD-1FCF1FDD-1FDF1FED-1FEF1FFD1FFE309B309CA700-A716A720A721A789A78AFF3EFF40FFE3",So:"00A600A700A900AE00B000B60482060E060F06E906FD06FE07F609FA0B700BF3-0BF80BFA0C7F0CF10CF20D790F01-0F030F13-0F170F1A-0F1F0F340F360F380FBE-0FC50FC7-0FCC0FCE0FCF0FD5-0FD8109E109F13601390-1399194019E0-19FF1B61-1B6A1B74-1B7C210021012103-21062108210921142116-2118211E-2123212521272129212E213A213B214A214C214D214F2195-2199219C-219F21A121A221A421A521A7-21AD21AF-21CD21D021D121D321D5-21F32300-2307230C-231F2322-2328232B-237B237D-239A23B4-23DB23E2-23E82400-24262440-244A249C-24E92500-25B625B8-25C025C2-25F72600-266E2670-26CD26CF-26E126E326E8-26FF2701-27042706-2709270C-27272729-274B274D274F-27522756-275E2761-276727942798-27AF27B1-27BE2800-28FF2B00-2B2F2B452B462B50-2B592CE5-2CEA2E80-2E992E9B-2EF32F00-2FD52FF0-2FFB300430123013302030363037303E303F319031913196-319F31C0-31E33200-321E322A-32503260-327F328A-32B032C0-32FE3300-33FF4DC0-4DFFA490-A4C6A828-A82BA836A837A839AA77-AA79FDFDFFE4FFE8FFEDFFEEFFFCFFFD",Z:"002000A01680180E2000-200A20282029202F205F3000",Zs:"002000A01680180E2000-200A202F205F3000",Zl:"2028",Zp:"2029",C:"0000-001F007F-009F00AD03780379037F-0383038B038D03A20526-05300557055805600588058B-059005C8-05CF05EB-05EF05F5-0605061C061D0620065F06DD070E070F074B074C07B2-07BF07FB-07FF082E082F083F-08FF093A093B094F095609570973-097809800984098D098E0991099209A909B109B3-09B509BA09BB09C509C609C909CA09CF-09D609D8-09DB09DE09E409E509FC-0A000A040A0B-0A0E0A110A120A290A310A340A370A3A0A3B0A3D0A43-0A460A490A4A0A4E-0A500A52-0A580A5D0A5F-0A650A76-0A800A840A8E0A920AA90AB10AB40ABA0ABB0AC60ACA0ACE0ACF0AD1-0ADF0AE40AE50AF00AF2-0B000B040B0D0B0E0B110B120B290B310B340B3A0B3B0B450B460B490B4A0B4E-0B550B58-0B5B0B5E0B640B650B72-0B810B840B8B-0B8D0B910B96-0B980B9B0B9D0BA0-0BA20BA5-0BA70BAB-0BAD0BBA-0BBD0BC3-0BC50BC90BCE0BCF0BD1-0BD60BD8-0BE50BFB-0C000C040C0D0C110C290C340C3A-0C3C0C450C490C4E-0C540C570C5A-0C5F0C640C650C70-0C770C800C810C840C8D0C910CA90CB40CBA0CBB0CC50CC90CCE-0CD40CD7-0CDD0CDF0CE40CE50CF00CF3-0D010D040D0D0D110D290D3A-0D3C0D450D490D4E-0D560D58-0D5F0D640D650D76-0D780D800D810D840D97-0D990DB20DBC0DBE0DBF0DC7-0DC90DCB-0DCE0DD50DD70DE0-0DF10DF5-0E000E3B-0E3E0E5C-0E800E830E850E860E890E8B0E8C0E8E-0E930E980EA00EA40EA60EA80EA90EAC0EBA0EBE0EBF0EC50EC70ECE0ECF0EDA0EDB0EDE-0EFF0F480F6D-0F700F8C-0F8F0F980FBD0FCD0FD9-0FFF10C6-10CF10FD-10FF1249124E124F12571259125E125F1289128E128F12B112B612B712BF12C112C612C712D7131113161317135B-135E137D-137F139A-139F13F5-13FF169D-169F16F1-16FF170D1715-171F1737-173F1754-175F176D17711774-177F17B417B517DE17DF17EA-17EF17FA-17FF180F181A-181F1878-187F18AB-18AF18F6-18FF191D-191F192C-192F193C-193F1941-1943196E196F1975-197F19AC-19AF19CA-19CF19DB-19DD1A1C1A1D1A5F1A7D1A7E1A8A-1A8F1A9A-1A9F1AAE-1AFF1B4C-1B4F1B7D-1B7F1BAB-1BAD1BBA-1BFF1C38-1C3A1C4A-1C4C1C80-1CCF1CF3-1CFF1DE7-1DFC1F161F171F1E1F1F1F461F471F4E1F4F1F581F5A1F5C1F5E1F7E1F7F1FB51FC51FD41FD51FDC1FF01FF11FF51FFF200B-200F202A-202E2060-206F20722073208F2095-209F20B9-20CF20F1-20FF218A-218F23E9-23FF2427-243F244B-245F26CE26E226E4-26E727002705270A270B2728274C274E2753-2755275F27602795-279727B027BF27CB27CD-27CF2B4D-2B4F2B5A-2BFF2C2F2C5F2CF2-2CF82D26-2D2F2D66-2D6E2D70-2D7F2D97-2D9F2DA72DAF2DB72DBF2DC72DCF2DD72DDF2E32-2E7F2E9A2EF4-2EFF2FD6-2FEF2FFC-2FFF3040309730983100-3104312E-3130318F31B8-31BF31E4-31EF321F32FF4DB6-4DBF9FCC-9FFFA48D-A48FA4C7-A4CFA62C-A63FA660A661A674-A67BA698-A69FA6F8-A6FFA78D-A7FAA82C-A82FA83A-A83FA878-A87FA8C5-A8CDA8DA-A8DFA8FC-A8FFA954-A95EA97D-A97FA9CEA9DA-A9DDA9E0-A9FFAA37-AA3FAA4EAA4FAA5AAA5BAA7C-AA7FAAC3-AADAAAE0-ABBFABEEABEFABFA-ABFFD7A4-D7AFD7C7-D7CAD7FC-F8FFFA2EFA2FFA6EFA6FFADA-FAFFFB07-FB12FB18-FB1CFB37FB3DFB3FFB42FB45FBB2-FBD2FD40-FD4FFD90FD91FDC8-FDEFFDFEFDFFFE1A-FE1FFE27-FE2FFE53FE67FE6C-FE6FFE75FEFD-FF00FFBF-FFC1FFC8FFC9FFD0FFD1FFD8FFD9FFDD-FFDFFFE7FFEF-FFFBFFFEFFFF",Cc:"0000-001F007F-009F",Cf:"00AD0600-060306DD070F17B417B5200B-200F202A-202E2060-2064206A-206FFEFFFFF9-FFFB",Co:"E000-F8FF",Cs:"D800-DFFF",Cn:"03780379037F-0383038B038D03A20526-05300557055805600588058B-059005C8-05CF05EB-05EF05F5-05FF06040605061C061D0620065F070E074B074C07B2-07BF07FB-07FF082E082F083F-08FF093A093B094F095609570973-097809800984098D098E0991099209A909B109B3-09B509BA09BB09C509C609C909CA09CF-09D609D8-09DB09DE09E409E509FC-0A000A040A0B-0A0E0A110A120A290A310A340A370A3A0A3B0A3D0A43-0A460A490A4A0A4E-0A500A52-0A580A5D0A5F-0A650A76-0A800A840A8E0A920AA90AB10AB40ABA0ABB0AC60ACA0ACE0ACF0AD1-0ADF0AE40AE50AF00AF2-0B000B040B0D0B0E0B110B120B290B310B340B3A0B3B0B450B460B490B4A0B4E-0B550B58-0B5B0B5E0B640B650B72-0B810B840B8B-0B8D0B910B96-0B980B9B0B9D0BA0-0BA20BA5-0BA70BAB-0BAD0BBA-0BBD0BC3-0BC50BC90BCE0BCF0BD1-0BD60BD8-0BE50BFB-0C000C040C0D0C110C290C340C3A-0C3C0C450C490C4E-0C540C570C5A-0C5F0C640C650C70-0C770C800C810C840C8D0C910CA90CB40CBA0CBB0CC50CC90CCE-0CD40CD7-0CDD0CDF0CE40CE50CF00CF3-0D010D040D0D0D110D290D3A-0D3C0D450D490D4E-0D560D58-0D5F0D640D650D76-0D780D800D810D840D97-0D990DB20DBC0DBE0DBF0DC7-0DC90DCB-0DCE0DD50DD70DE0-0DF10DF5-0E000E3B-0E3E0E5C-0E800E830E850E860E890E8B0E8C0E8E-0E930E980EA00EA40EA60EA80EA90EAC0EBA0EBE0EBF0EC50EC70ECE0ECF0EDA0EDB0EDE-0EFF0F480F6D-0F700F8C-0F8F0F980FBD0FCD0FD9-0FFF10C6-10CF10FD-10FF1249124E124F12571259125E125F1289128E128F12B112B612B712BF12C112C612C712D7131113161317135B-135E137D-137F139A-139F13F5-13FF169D-169F16F1-16FF170D1715-171F1737-173F1754-175F176D17711774-177F17DE17DF17EA-17EF17FA-17FF180F181A-181F1878-187F18AB-18AF18F6-18FF191D-191F192C-192F193C-193F1941-1943196E196F1975-197F19AC-19AF19CA-19CF19DB-19DD1A1C1A1D1A5F1A7D1A7E1A8A-1A8F1A9A-1A9F1AAE-1AFF1B4C-1B4F1B7D-1B7F1BAB-1BAD1BBA-1BFF1C38-1C3A1C4A-1C4C1C80-1CCF1CF3-1CFF1DE7-1DFC1F161F171F1E1F1F1F461F471F4E1F4F1F581F5A1F5C1F5E1F7E1F7F1FB51FC51FD41FD51FDC1FF01FF11FF51FFF2065-206920722073208F2095-209F20B9-20CF20F1-20FF218A-218F23E9-23FF2427-243F244B-245F26CE26E226E4-26E727002705270A270B2728274C274E2753-2755275F27602795-279727B027BF27CB27CD-27CF2B4D-2B4F2B5A-2BFF2C2F2C5F2CF2-2CF82D26-2D2F2D66-2D6E2D70-2D7F2D97-2D9F2DA72DAF2DB72DBF2DC72DCF2DD72DDF2E32-2E7F2E9A2EF4-2EFF2FD6-2FEF2FFC-2FFF3040309730983100-3104312E-3130318F31B8-31BF31E4-31EF321F32FF4DB6-4DBF9FCC-9FFFA48D-A48FA4C7-A4CFA62C-A63FA660A661A674-A67BA698-A69FA6F8-A6FFA78D-A7FAA82C-A82FA83A-A83FA878-A87FA8C5-A8CDA8DA-A8DFA8FC-A8FFA954-A95EA97D-A97FA9CEA9DA-A9DDA9E0-A9FFAA37-AA3FAA4EAA4FAA5AAA5BAA7C-AA7FAAC3-AADAAAE0-ABBFABEEABEFABFA-ABFFD7A4-D7AFD7C7-D7CAD7FC-D7FFFA2EFA2FFA6EFA6FFADA-FAFFFB07-FB12FB18-FB1CFB37FB3DFB3FFB42FB45FBB2-FBD2FD40-FD4FFD90FD91FDC8-FDEFFDFEFDFFFE1A-FE1FFE27-FE2FFE53FE67FE6C-FE6FFE75FEFDFEFEFF00FFBF-FFC1FFC8FFC9FFD0FFD1FFD8FFD9FFDD-FFDFFFE7FFEF-FFF8FFFEFFFF"})}),define("ace/mode/text",["require","exports","module","ace/tokenizer","ace/mode/text_highlight_rules","ace/mode/behaviour/cstyle","ace/unicode","ace/lib/lang","ace/token_iterator","ace/range"],function(e,t,n){"use strict";var r=e("../tokenizer").Tokenizer,i=e("./text_highlight_rules").TextHighlightRules,s=e("./behaviour/cstyle").CstyleBehaviour,o=e("../unicode"),u=e("../lib/lang"),a=e("../token_iterator").TokenIterator,f=e("../range").Range,l=function(){this.HighlightRules=i};(function(){this.$defaultBehaviour=new s,this.tokenRe=new RegExp("^["+o.packages.L+o.packages.Mn+o.packages.Mc+o.packages.Nd+o.packages.Pc+"\\$_]+","g"),this.nonTokenRe=new RegExp("^(?:[^"+o.packages.L+o.packages.Mn+o.packages.Mc+o.packages.Nd+o.packages.Pc+"\\$_]|\\s])+","g"),this.getTokenizer=function(){return this.$tokenizer||(this.$highlightRules=this.$highlightRules||new this.HighlightRules(this.$highlightRuleConfig),this.$tokenizer=new r(this.$highlightRules.getRules())),this.$tokenizer},this.lineCommentStart="",this.blockComment="",this.toggleCommentLines=function(e,t,n,r){function w(e){for(var t=n;t<=r;t++)e(i.getLine(t),t)}var i=t.doc,s=!0,o=!0,a=Infinity,f=t.getTabSize(),l=!1;if(!this.lineCommentStart){if(!this.blockComment)return!1;var c=this.blockComment.start,h=this.blockComment.end,p=new RegExp("^(\\s*)(?:"+u.escapeRegExp(c)+")"),d=new RegExp("(?:"+u.escapeRegExp(h)+")\\s*$"),v=function(e,t){if(g(e,t))return;if(!s||/\S/.test(e))i.insertInLine({row:t,column:e.length},h),i.insertInLine({row:t,column:a},c)},m=function(e,t){var n;(n=e.match(d))&&i.removeInLine(t,e.length-n[0].length,e.length),(n=e.match(p))&&i.removeInLine(t,n[1].length,n[0].length)},g=function(e,n){if(p.test(e))return!0;var r=t.getTokens(n);for(var i=0;i2?r%f!=f-1:r%f==0}}var E=Infinity;w(function(e,t){var n=e.search(/\S/);n!==-1?(ne.length&&(E=e.length)}),a==Infinity&&(a=E,s=!1,o=!1),l&&a%f!=0&&(a=Math.floor(a/f)*f),w(o?m:v)},this.toggleBlockComment=function(e,t,n,r){var i=this.blockComment;if(!i)return;!i.start&&i[0]&&(i=i[0]);var s=new a(t,r.row,r.column),o=s.getCurrentToken(),u=t.selection,l=t.selection.toOrientedRange(),c,h;if(o&&/comment/.test(o.type)){var p,d;while(o&&/comment/.test(o.type)){var v=o.value.indexOf(i.start);if(v!=-1){var m=s.getCurrentTokenRow(),g=s.getCurrentTokenColumn()+v;p=new f(m,g,m,g+i.start.length);break}o=s.stepBackward()}var s=new a(t,r.row,r.column),o=s.getCurrentToken();while(o&&/comment/.test(o.type)){var v=o.value.indexOf(i.end);if(v!=-1){var m=s.getCurrentTokenRow(),g=s.getCurrentTokenColumn()+v;d=new f(m,g,m,g+i.end.length);break}o=s.stepForward()}d&&t.remove(d),p&&(t.remove(p),c=p.start.row,h=-i.start.length)}else h=i.start.length,c=n.start.row,t.insert(n.end,i.end),t.insert(n.start,i.start);l.start.row==c&&(l.start.column+=h),l.end.row==c&&(l.end.column+=h),t.selection.fromOrientedRange(l)},this.getNextLineIndent=function(e,t,n){return this.$getIndent(t)},this.checkOutdent=function(e,t,n){return!1},this.autoOutdent=function(e,t,n){},this.$getIndent=function(e){return e.match(/^\s*/)[0]},this.createWorker=function(e){return null},this.createModeDelegates=function(e){this.$embeds=[],this.$modes={};for(var t in e)e[t]&&(this.$embeds.push(t),this.$modes[t]=new e[t]);var n=["toggleBlockComment","toggleCommentLines","getNextLineIndent","checkOutdent","autoOutdent","transformAction","getCompletions"];for(var t=0;t=0&&t.row=0&&t.column<=e[t.row].length}function s(e,t){t.action!="insert"&&t.action!="remove"&&r(t,"delta.action must be 'insert' or 'remove'"),t.lines instanceof Array||r(t,"delta.lines must be an Array"),(!t.start||!t.end)&&r(t,"delta.start/end must be an present");var n=t.start;i(e,t.start)||r(t,"delta.start must be contained in document");var s=t.end;t.action=="remove"&&!i(e,s)&&r(t,"delta.end must contained in document for 'remove' actions");var o=s.row-n.row,u=s.column-(o==0?n.column:0);(o!=t.lines.length-1||t.lines[o].length!=u)&&r(t,"delta.range must match delta lines")}t.applyDelta=function(e,t,n){var r=t.start.row,i=t.start.column,s=e[r]||"";switch(t.action){case"insert":var o=t.lines;if(o.length===1)e[r]=s.substring(0,i)+t.lines[0]+s.substring(i);else{var u=[r,1].concat(t.lines);e.splice.apply(e,u),e[r]=s.substring(0,i)+e[r],e[r+t.lines.length-1]+=s.substring(i)}break;case"remove":var a=t.end.column,f=t.end.row;r===f?e[r]=s.substring(0,i)+s.substring(a):e.splice(r,f-r+1,s.substring(0,i)+e[f].substring(a))}}}),define("ace/anchor",["require","exports","module","ace/lib/oop","ace/lib/event_emitter"],function(e,t,n){"use strict";var r=e("./lib/oop"),i=e("./lib/event_emitter").EventEmitter,s=t.Anchor=function(e,t,n){this.$onChange=this.onChange.bind(this),this.attach(e),typeof n=="undefined"?this.setPosition(t.row,t.column):this.setPosition(t,n)};(function(){function e(e,t,n){var r=n?e.column<=t.column:e.columnthis.row)return;var n=t(e,{row:this.row,column:this.column},this.$insertRight);this.setPosition(n.row,n.column,!0)},this.setPosition=function(e,t,n){var r;n?r={row:e,column:t}:r=this.$clipPositionToDocument(e,t);if(this.row==r.row&&this.column==r.column)return;var i={row:this.row,column:this.column};this.row=r.row,this.column=r.column,this._signal("change",{old:i,value:r})},this.detach=function(){this.document.removeEventListener("change",this.$onChange)},this.attach=function(e){this.document=e||this.document,this.document.on("change",this.$onChange)},this.$clipPositionToDocument=function(e,t){var n={};return e>=this.document.getLength()?(n.row=Math.max(0,this.document.getLength()-1),n.column=this.document.getLine(n.row).length):e<0?(n.row=0,n.column=0):(n.row=e,n.column=Math.min(this.document.getLine(n.row).length,Math.max(0,t))),t<0&&(n.column=0),n}}).call(s.prototype)}),define("ace/document",["require","exports","module","ace/lib/oop","ace/apply_delta","ace/lib/event_emitter","ace/range","ace/anchor"],function(e,t,n){"use strict";var r=e("./lib/oop"),i=e("./apply_delta").applyDelta,s=e("./lib/event_emitter").EventEmitter,o=e("./range").Range,u=e("./anchor").Anchor,a=function(e){this.$lines=[""],e.length===0?this.$lines=[""]:Array.isArray(e)?this.insertMergedLines({row:0,column:0},e):this.insert({row:0,column:0},e)};(function(){r.implement(this,s),this.setValue=function(e){var t=this.getLength()-1;this.remove(new o(0,0,t,this.getLine(t).length)),this.insert({row:0,column:0},e)},this.getValue=function(){return this.getAllLines().join(this.getNewLineCharacter())},this.createAnchor=function(e,t){return new u(this,e,t)},"aaa".split(/a/).length===0?this.$split=function(e){return e.replace(/\r\n|\r/g,"\n").split("\n")}:this.$split=function(e){return e.split(/\r\n|\r|\n/)},this.$detectNewLine=function(e){var t=e.match(/^.*?(\r\n|\r|\n)/m);this.$autoNewLine=t?t[1]:"\n",this._signal("changeNewLineMode")},this.getNewLineCharacter=function(){switch(this.$newLineMode){case"windows":return"\r\n";case"unix":return"\n";default:return this.$autoNewLine||"\n"}},this.$autoNewLine="",this.$newLineMode="auto",this.setNewLineMode=function(e){if(this.$newLineMode===e)return;this.$newLineMode=e,this._signal("changeNewLineMode")},this.getNewLineMode=function(){return this.$newLineMode},this.isNewLine=function(e){return e=="\r\n"||e=="\r"||e=="\n"},this.getLine=function(e){return this.$lines[e]||""},this.getLines=function(e,t){return this.$lines.slice(e,t+1)},this.getAllLines=function(){return this.getLines(0,this.getLength())},this.getLength=function(){return this.$lines.length},this.getTextRange=function(e){return this.getLinesForRange(e).join(this.getNewLineCharacter())},this.getLinesForRange=function(e){var t;if(e.start.row===e.end.row)t=[this.getLine(e.start.row).substring(e.start.column,e.end.column)];else{t=this.getLines(e.start.row,e.end.row),t[0]=(t[0]||"").substring(e.start.column);var n=t.length-1;e.end.row-e.start.row==n&&(t[n]=t[n].substring(0,e.end.column))}return t},this.insertLines=function(e,t){return console.warn("Use of document.insertLines is deprecated. Use the insertFullLines method instead."),this.insertFullLines(e,t)},this.removeLines=function(e,t){return console.warn("Use of document.removeLines is deprecated. Use the removeFullLines method instead."),this.removeFullLines(e,t)},this.insertNewLine=function(e){return console.warn("Use of document.insertNewLine is deprecated. Use insertMergedLines(position, ['', '']) instead."),this.insertMergedLines(e,["",""])},this.insert=function(e,t){return this.getLength()<=1&&this.$detectNewLine(t),this.insertMergedLines(e,this.$split(t))},this.insertInLine=function(e,t){var n=this.clippedPos(e.row,e.column),r=this.pos(e.row,e.column+t.length);return this.applyDelta({start:n,end:r,action:"insert",lines:[t]},!0),this.clonePos(r)},this.clippedPos=function(e,t){var n=this.getLength();e===undefined?e=n:e<0?e=0:e>=n&&(e=n-1,t=undefined);var r=this.getLine(e);return t==undefined&&(t=r.length),t=Math.min(Math.max(t,0),r.length),{row:e,column:t}},this.clonePos=function(e){return{row:e.row,column:e.column}},this.pos=function(e,t){return{row:e,column:t}},this.$clipPosition=function(e){var t=this.getLength();return e.row>=t?(e.row=Math.max(0,t-1),e.column=this.getLine(t-1).length):(e.row=Math.max(0,e.row),e.column=Math.min(Math.max(e.column,0),this.getLine(e.row).length)),e},this.insertFullLines=function(e,t){e=Math.min(Math.max(e,0),this.getLength());var n=0;e0,r=t=0&&this.applyDelta({start:this.pos(e,this.getLine(e).length),end:this.pos(e+1,0),action:"remove",lines:["",""]})},this.replace=function(e,t){e instanceof o||(e=o.fromPoints(e.start,e.end));if(t.length===0&&e.isEmpty())return e.start;if(t==this.getTextRange(e))return e.end;this.remove(e);var n;return t?n=this.insert(e.start,t):n=e.start,n},this.applyDeltas=function(e){for(var t=0;t=0;t--)this.revertDelta(e[t])},this.applyDelta=function(e,t){var n=e.action=="insert";if(n?e.lines.length<=1&&!e.lines[0]:!o.comparePoints(e.start,e.end))return;n&&e.lines.length>2e4&&this.$splitAndapplyLargeDelta(e,2e4),i(this.$lines,e,t),this._signal("change",e)},this.$splitAndapplyLargeDelta=function(e,t){var n=e.lines,r=n.length,i=e.start.row,s=e.start.column,o=0,u=0;do{o=u,u+=t-1;var a=n.slice(o,u);if(u>r){e.lines=a,e.start.row=i+o,e.start.column=s;break}a.push(""),this.applyDelta({start:this.pos(i+o,s),end:this.pos(i+u,s=0),action:e.action,lines:a},!0)}while(!0)},this.revertDelta=function(e){this.applyDelta({start:this.clonePos(e.start),end:this.clonePos(e.end),action:e.action=="insert"?"remove":"insert",lines:e.lines.slice()})},this.indexToPosition=function(e,t){var n=this.$lines||this.getAllLines(),r=this.getNewLineCharacter().length;for(var i=t||0,s=n.length;i20){n.running=setTimeout(n.$worker,20);break}}n.currentLine=t,s<=r&&n.fireUpdateEvent(s,r)}};(function(){r.implement(this,i),this.setTokenizer=function(e){this.tokenizer=e,this.lines=[],this.states=[],this.start(0)},this.setDocument=function(e){this.doc=e,this.lines=[],this.states=[],this.stop()},this.fireUpdateEvent=function(e,t){var n={first:e,last:t};this._signal("update",{data:n})},this.start=function(e){this.currentLine=Math.min(e||0,this.currentLine,this.doc.getLength()),this.lines.splice(this.currentLine,this.lines.length),this.states.splice(this.currentLine,this.states.length),this.stop(),this.running=setTimeout(this.$worker,700)},this.scheduleStart=function(){this.running||(this.running=setTimeout(this.$worker,700))},this.$updateOnChange=function(e){var t=e.start.row,n=e.end.row-t;if(n===0)this.lines[t]=null;else if(e.action=="remove")this.lines.splice(t,n+1,null),this.states.splice(t,n+1,null);else{var r=Array(n+1);r.unshift(t,1),this.lines.splice.apply(this.lines,r),this.states.splice.apply(this.states,r)}this.currentLine=Math.min(t,this.currentLine,this.doc.getLength()),this.stop()},this.stop=function(){this.running&&clearTimeout(this.running),this.running=!1},this.getTokens=function(e){return this.lines[e]||this.$tokenizeRow(e)},this.getState=function(e){return this.currentLine==e&&this.$tokenizeRow(e),this.states[e]||"start"},this.$tokenizeRow=function(e){var t=this.doc.getLine(e),n=this.states[e-1],r=this.tokenizer.getLineTokens(t,n,e);return this.states[e]+""!=r.state+""?(this.states[e]=r.state,this.lines[e+1]=null,this.currentLine>e+1&&(this.currentLine=e+1)):this.currentLine==e&&(this.currentLine=e+1),this.lines[e]=r.tokens}}).call(s.prototype),t.BackgroundTokenizer=s}),define("ace/search_highlight",["require","exports","module","ace/lib/lang","ace/lib/oop","ace/range"],function(e,t,n){"use strict";var r=e("./lib/lang"),i=e("./lib/oop"),s=e("./range").Range,o=function(e,t,n){this.setRegexp(e),this.clazz=t,this.type=n||"text"};(function(){this.MAX_RANGES=500,this.setRegexp=function(e){if(this.regExp+""==e+"")return;this.regExp=e,this.cache=[]},this.update=function(e,t,n,i){if(!this.regExp)return;var o=i.firstRow,u=i.lastRow;for(var a=o;a<=u;a++){var f=this.cache[a];f==null&&(f=r.getMatchOffsets(n.getLine(a),this.regExp),f.length>this.MAX_RANGES&&(f=f.slice(0,this.MAX_RANGES)),f=f.map(function(e){return new s(a,e.offset,a,e.offset+e.length)}),this.cache[a]=f.length?f:"");for(var l=f.length;l--;)t.drawSingleLineMarker(e,f[l].toScreenRange(n),this.clazz,i)}}}).call(o.prototype),t.SearchHighlight=o}),define("ace/edit_session/fold_line",["require","exports","module","ace/range"],function(e,t,n){"use strict";function i(e,t){this.foldData=e,Array.isArray(t)?this.folds=t:t=this.folds=[t];var n=t[t.length-1];this.range=new r(t[0].start.row,t[0].start.column,n.end.row,n.end.column),this.start=this.range.start,this.end=this.range.end,this.folds.forEach(function(e){e.setFoldLine(this)},this)}var r=e("../range").Range;(function(){this.shiftRow=function(e){this.start.row+=e,this.end.row+=e,this.folds.forEach(function(t){t.start.row+=e,t.end.row+=e})},this.addFold=function(e){if(e.sameRow){if(e.start.rowthis.endRow)throw new Error("Can't add a fold to this FoldLine as it has no connection");this.folds.push(e),this.folds.sort(function(e,t){return-e.range.compareEnd(t.start.row,t.start.column)}),this.range.compareEnd(e.start.row,e.start.column)>0?(this.end.row=e.end.row,this.end.column=e.end.column):this.range.compareStart(e.end.row,e.end.column)<0&&(this.start.row=e.start.row,this.start.column=e.start.column)}else if(e.start.row==this.end.row)this.folds.push(e),this.end.row=e.end.row,this.end.column=e.end.column;else{if(e.end.row!=this.start.row)throw new Error("Trying to add fold to FoldRow that doesn't have a matching row");this.folds.unshift(e),this.start.row=e.start.row,this.start.column=e.start.column}e.foldLine=this},this.containsRow=function(e){return e>=this.start.row&&e<=this.end.row},this.walk=function(e,t,n){var r=0,i=this.folds,s,o,u,a=!0;t==null&&(t=this.end.row,n=this.end.column);for(var f=0;f0)continue;var a=i(e,o.start);return u===0?t&&a!==0?-s-2:s:a>0||a===0&&!t?s:-s-1}return-s-1},this.add=function(e){var t=!e.isEmpty(),n=this.pointIndex(e.start,t);n<0&&(n=-n-1);var r=this.pointIndex(e.end,t,n);return r<0?r=-r-1:r++,this.ranges.splice(n,r-n,e)},this.addList=function(e){var t=[];for(var n=e.length;n--;)t.push.apply(t,this.add(e[n]));return t},this.substractPoint=function(e){var t=this.pointIndex(e);if(t>=0)return this.ranges.splice(t,1)},this.merge=function(){var e=[],t=this.ranges;t=t.sort(function(e,t){return i(e.start,t.start)});var n=t[0],r;for(var s=1;s=0},this.containsPoint=function(e){return this.pointIndex(e)>=0},this.rangeAtPoint=function(e){var t=this.pointIndex(e);if(t>=0)return this.ranges[t]},this.clipRows=function(e,t){var n=this.ranges;if(n[0].start.row>t||n[n.length-1].start.rowr)break;l.start.row==r&&l.start.column>=t.column&&(l.start.column!=t.column||!this.$insertRight)&&(l.start.column+=o,l.start.row+=s);if(l.end.row==r&&l.end.column>=t.column){if(l.end.column==t.column&&this.$insertRight)continue;l.end.column==t.column&&o>0&&al.start.column&&l.end.column==u[a+1].start.column&&(l.end.column-=o),l.end.column+=o,l.end.row+=s}}if(s!=0&&a=e)return i;if(i.end.row>e)return null}return null},this.getNextFoldLine=function(e,t){var n=this.$foldData,r=0;t&&(r=n.indexOf(t)),r==-1&&(r=0);for(r;r=e)return i}return null},this.getFoldedRowCount=function(e,t){var n=this.$foldData,r=t-e+1;for(var i=0;i=t){u=e?r-=t-u:r=0);break}o>=e&&(u>=e?r-=o-u:r-=o-e+1)}return r},this.$addFoldLine=function(e){return this.$foldData.push(e),this.$foldData.sort(function(e,t){return e.start.row-t.start.row}),e},this.addFold=function(e,t){var n=this.$foldData,r=!1,o;e instanceof s?o=e:(o=new s(t,e),o.collapseChildren=t.collapseChildren),this.$clipRangeToDocument(o.range);var u=o.start.row,a=o.start.column,f=o.end.row,l=o.end.column;if(u0&&(this.removeFolds(p),p.forEach(function(e){o.addSubFold(e)}));for(var d=0;d0&&this.foldAll(e.start.row+1,e.end.row,e.collapseChildren-1),e.subFolds=[]},this.expandFolds=function(e){e.forEach(function(e){this.expandFold(e)},this)},this.unfold=function(e,t){var n,i;e==null?(n=new r(0,0,this.getLength(),0),t=!0):typeof e=="number"?n=new r(e,0,e,this.getLine(e).length):"row"in e?n=r.fromPoints(e,e):n=e,i=this.getFoldsInRangeList(n);if(t)this.removeFolds(i);else{var s=i;while(s.length)this.expandFolds(s),s=this.getFoldsInRangeList(n)}if(i.length)return i},this.isRowFolded=function(e,t){return!!this.getFoldLine(e,t)},this.getRowFoldEnd=function(e,t){var n=this.getFoldLine(e,t);return n?n.end.row:e},this.getRowFoldStart=function(e,t){var n=this.getFoldLine(e,t);return n?n.start.row:e},this.getFoldDisplayLine=function(e,t,n,r,i){r==null&&(r=e.start.row),i==null&&(i=0),t==null&&(t=e.end.row),n==null&&(n=this.getLine(t).length);var s=this.doc,o="";return e.walk(function(e,t,n,u){if(t=e){i=s.end.row;try{var o=this.addFold("...",s);o&&(o.collapseChildren=n)}catch(u){}}}},this.$foldStyles={manual:1,markbegin:1,markbeginend:1},this.$foldStyle="markbegin",this.setFoldStyle=function(e){if(!this.$foldStyles[e])throw new Error("invalid fold style: "+e+"["+Object.keys(this.$foldStyles).join(", ")+"]");if(this.$foldStyle==e)return;this.$foldStyle=e,e=="manual"&&this.unfold();var t=this.$foldMode;this.$setFolding(null),this.$setFolding(t)},this.$setFolding=function(e){if(this.$foldMode==e)return;this.$foldMode=e,this.off("change",this.$updateFoldWidgets),this.off("tokenizerUpdate",this.$tokenizerUpdateFoldWidgets),this._signal("changeAnnotation");if(!e||this.$foldStyle=="manual"){this.foldWidgets=null;return}this.foldWidgets=[],this.getFoldWidget=e.getFoldWidget.bind(e,this,this.$foldStyle),this.getFoldWidgetRange=e.getFoldWidgetRange.bind(e,this,this.$foldStyle),this.$updateFoldWidgets=this.updateFoldWidgets.bind(this),this.$tokenizerUpdateFoldWidgets=this.tokenizerUpdateFoldWidgets.bind(this),this.on("change",this.$updateFoldWidgets),this.on("tokenizerUpdate",this.$tokenizerUpdateFoldWidgets)},this.getParentFoldRangeData=function(e,t){var n=this.foldWidgets;if(!n||t&&n[e])return{};var r=e-1,i;while(r>=0){var s=n[r];s==null&&(s=n[r]=this.getFoldWidget(r));if(s=="start"){var o=this.getFoldWidgetRange(r);i||(i=o);if(o&&o.end.row>=e)break}r--}return{range:r!==-1&&o,firstRange:i}},this.onFoldWidgetClick=function(e,t){t=t.domEvent;var n={children:t.shiftKey,all:t.ctrlKey||t.metaKey,siblings:t.altKey},r=this.$toggleFoldWidget(e,n);if(!r){var i=t.target||t.srcElement;i&&/ace_fold-widget/.test(i.className)&&(i.className+=" ace_invalid")}},this.$toggleFoldWidget=function(e,t){if(!this.getFoldWidget)return;var n=this.getFoldWidget(e),r=this.getLine(e),i=n==="end"?-1:1,s=this.getFoldAt(e,i===-1?0:r.length,i);if(s)return t.children||t.all?this.removeFold(s):this.expandFold(s),s;var o=this.getFoldWidgetRange(e,!0);if(o&&!o.isMultiLine()){s=this.getFoldAt(o.start.row,o.start.column,1);if(s&&o.isEqual(s.range))return this.removeFold(s),s}if(t.siblings){var u=this.getParentFoldRangeData(e);if(u.range)var a=u.range.start.row+1,f=u.range.end.row;this.foldAll(a,f,t.all?1e4:0)}else t.children?(f=o?o.end.row:this.getLength(),this.foldAll(e+1,f,t.all?1e4:0)):o&&(t.all&&(o.collapseChildren=1e4),this.addFold("...",o));return o},this.toggleFoldWidget=function(e){var t=this.selection.getCursor().row;t=this.getRowFoldStart(t);var n=this.$toggleFoldWidget(t,{});if(n)return;var r=this.getParentFoldRangeData(t,!0);n=r.range||r.firstRange;if(n){t=n.start.row;var i=this.getFoldAt(t,this.getLine(t).length,1);i?this.removeFold(i):this.addFold("...",n)}},this.updateFoldWidgets=function(e){var t=e.start.row,n=e.end.row-t;if(n===0)this.foldWidgets[t]=null;else if(e.action=="remove")this.foldWidgets.splice(t,n+1,null);else{var r=Array(n+1);r.unshift(t,1),this.foldWidgets.splice.apply(this.foldWidgets,r)}},this.tokenizerUpdateFoldWidgets=function(e){var t=e.data;t.first!=t.last&&this.foldWidgets.length>t.first&&this.foldWidgets.splice(t.first,this.foldWidgets.length)}}var r=e("../range").Range,i=e("./fold_line").FoldLine,s=e("./fold").Fold,o=e("../token_iterator").TokenIterator;t.Folding=u}),define("ace/edit_session/bracket_match",["require","exports","module","ace/token_iterator","ace/range"],function(e,t,n){"use strict";function s(){this.findMatchingBracket=function(e,t){if(e.column==0)return null;var n=t||this.getLine(e.row).charAt(e.column-1);if(n=="")return null;var r=n.match(/([\(\[\{])|([\)\]\}])/);return r?r[1]?this.$findClosingBracket(r[1],e):this.$findOpeningBracket(r[2],e):null},this.getBracketRange=function(e){var t=this.getLine(e.row),n=!0,r,s=t.charAt(e.column-1),o=s&&s.match(/([\(\[\{])|([\)\]\}])/);o||(s=t.charAt(e.column),e={row:e.row,column:e.column+1},o=s&&s.match(/([\(\[\{])|([\)\]\}])/),n=!1);if(!o)return null;if(o[1]){var u=this.$findClosingBracket(o[1],e);if(!u)return null;r=i.fromPoints(e,u),n||(r.end.column++,r.start.column--),r.cursor=r.end}else{var u=this.$findOpeningBracket(o[2],e);if(!u)return null;r=i.fromPoints(u,e),n||(r.start.column++,r.end.column--),r.cursor=r.start}return r},this.$brackets={")":"(","(":")","]":"[","[":"]","{":"}","}":"{"},this.$findOpeningBracket=function(e,t,n){var i=this.$brackets[e],s=1,o=new r(this,t.row,t.column),u=o.getCurrentToken();u||(u=o.stepForward());if(!u)return;n||(n=new RegExp("(\\.?"+u.type.replace(".","\\.").replace("rparen",".paren").replace(/\b(?:end)\b/,"(?:start|begin|end)")+")+"));var a=t.column-o.getCurrentTokenColumn()-2,f=u.value;for(;;){while(a>=0){var l=f.charAt(a);if(l==i){s-=1;if(s==0)return{row:o.getCurrentTokenRow(),column:a+o.getCurrentTokenColumn()}}else l==e&&(s+=1);a-=1}do u=o.stepBackward();while(u&&!n.test(u.type));if(u==null)break;f=u.value,a=f.length-1}return null},this.$findClosingBracket=function(e,t,n){var i=this.$brackets[e],s=1,o=new r(this,t.row,t.column),u=o.getCurrentToken();u||(u=o.stepForward());if(!u)return;n||(n=new RegExp("(\\.?"+u.type.replace(".","\\.").replace("lparen",".paren").replace(/\b(?:start|begin)\b/,"(?:start|begin|end)")+")+"));var a=t.column-o.getCurrentTokenColumn();for(;;){var f=u.value,l=f.length;while(a=4352&&e<=4447||e>=4515&&e<=4519||e>=4602&&e<=4607||e>=9001&&e<=9002||e>=11904&&e<=11929||e>=11931&&e<=12019||e>=12032&&e<=12245||e>=12272&&e<=12283||e>=12288&&e<=12350||e>=12353&&e<=12438||e>=12441&&e<=12543||e>=12549&&e<=12589||e>=12593&&e<=12686||e>=12688&&e<=12730||e>=12736&&e<=12771||e>=12784&&e<=12830||e>=12832&&e<=12871||e>=12880&&e<=13054||e>=13056&&e<=19903||e>=19968&&e<=42124||e>=42128&&e<=42182||e>=43360&&e<=43388||e>=44032&&e<=55203||e>=55216&&e<=55238||e>=55243&&e<=55291||e>=63744&&e<=64255||e>=65040&&e<=65049||e>=65072&&e<=65106||e>=65108&&e<=65126||e>=65128&&e<=65131||e>=65281&&e<=65376||e>=65504&&e<=65510}r.implement(this,o),this.setDocument=function(e){this.doc&&this.doc.removeListener("change",this.$onChange),this.doc=e,e.on("change",this.$onChange),this.bgTokenizer&&this.bgTokenizer.setDocument(this.getDocument()),this.resetCaches()},this.getDocument=function(){return this.doc},this.$resetRowCache=function(e){if(!e){this.$docRowCache=[],this.$screenRowCache=[];return}var t=this.$docRowCache.length,n=this.$getRowCacheIndex(this.$docRowCache,e)+1;t>n&&(this.$docRowCache.splice(n,t),this.$screenRowCache.splice(n,t))},this.$getRowCacheIndex=function(e,t){var n=0,r=e.length-1;while(n<=r){var i=n+r>>1,s=e[i];if(t>s)n=i+1;else{if(!(t=t)break}return r=n[s],r?(r.index=s,r.start=i-r.value.length,r):null},this.setUndoManager=function(e){this.$undoManager=e,this.$deltas=[],this.$deltasDoc=[],this.$deltasFold=[],this.$informUndoManager&&this.$informUndoManager.cancel();if(e){var t=this;this.$syncInformUndoManager=function(){t.$informUndoManager.cancel(),t.$deltasFold.length&&(t.$deltas.push({group:"fold",deltas:t.$deltasFold}),t.$deltasFold=[]),t.$deltasDoc.length&&(t.$deltas.push({group:"doc",deltas:t.$deltasDoc}),t.$deltasDoc=[]),t.$deltas.length>0&&e.execute({action:"aceupdate",args:[t.$deltas,t],merge:t.mergeUndoDeltas}),t.mergeUndoDeltas=!1,t.$deltas=[]},this.$informUndoManager=i.delayedCall(this.$syncInformUndoManager)}},this.markUndoGroup=function(){this.$syncInformUndoManager&&this.$syncInformUndoManager()},this.$defaultUndoManager={undo:function(){},redo:function(){},reset:function(){}},this.getUndoManager=function(){return this.$undoManager||this.$defaultUndoManager},this.getTabString=function(){return this.getUseSoftTabs()?i.stringRepeat(" ",this.getTabSize()):" "},this.setUseSoftTabs=function(e){this.setOption("useSoftTabs",e)},this.getUseSoftTabs=function(){return this.$useSoftTabs&&!this.$mode.$indentWithTabs},this.setTabSize=function(e){this.setOption("tabSize",e)},this.getTabSize=function(){return this.$tabSize},this.isTabStop=function(e){return this.$useSoftTabs&&e.column%this.$tabSize===0},this.$overwrite=!1,this.setOverwrite=function(e){this.setOption("overwrite",e)},this.getOverwrite=function(){return this.$overwrite},this.toggleOverwrite=function(){this.setOverwrite(!this.$overwrite)},this.addGutterDecoration=function(e,t){this.$decorations[e]||(this.$decorations[e]=""),this.$decorations[e]+=" "+t,this._signal("changeBreakpoint",{})},this.removeGutterDecoration=function(e,t){this.$decorations[e]=(this.$decorations[e]||"").replace(" "+t,""),this._signal("changeBreakpoint",{})},this.getBreakpoints=function(){return this.$breakpoints},this.setBreakpoints=function(e){this.$breakpoints=[];for(var t=0;t0&&(r=!!n.charAt(t-1).match(this.tokenRe)),r||(r=!!n.charAt(t).match(this.tokenRe));if(r)var i=this.tokenRe;else if(/^\s+$/.test(n.slice(t-1,t+1)))var i=/\s/;else var i=this.nonTokenRe;var s=t;if(s>0){do s--;while(s>=0&&n.charAt(s).match(i));s++}var o=t;while(oe&&(e=t.screenWidth)}),this.lineWidgetWidth=e},this.$computeWidth=function(e){if(this.$modified||e){this.$modified=!1;if(this.$useWrapMode)return this.screenWidth=this.$wrapLimit;var t=this.doc.getAllLines(),n=this.$rowLengthCache,r=0,i=0,s=this.$foldData[i],o=s?s.start.row:Infinity,u=t.length;for(var a=0;ao){a=s.end.row+1;if(a>=u)break;s=this.$foldData[i++],o=s?s.start.row:Infinity}n[a]==null&&(n[a]=this.$getStringScreenWidth(t[a])[0]),n[a]>r&&(r=n[a])}this.screenWidth=r}},this.getLine=function(e){return this.doc.getLine(e)},this.getLines=function(e,t){return this.doc.getLines(e,t)},this.getLength=function(){return this.doc.getLength()},this.getTextRange=function(e){return this.doc.getTextRange(e||this.selection.getRange())},this.insert=function(e,t){return this.doc.insert(e,t)},this.remove=function(e){return this.doc.remove(e)},this.removeFullLines=function(e,t){return this.doc.removeFullLines(e,t)},this.undoChanges=function(e,t){if(!e.length)return;this.$fromUndo=!0;var n=null;for(var r=e.length-1;r!=-1;r--){var i=e[r];i.group=="doc"?(this.doc.revertDeltas(i.deltas),n=this.$getUndoSelection(i.deltas,!0,n)):i.deltas.forEach(function(e){this.addFolds(e.folds)},this)}return this.$fromUndo=!1,n&&this.$undoSelect&&!t&&this.selection.setSelectionRange(n),n},this.redoChanges=function(e,t){if(!e.length)return;this.$fromUndo=!0;var n=null;for(var r=0;re.end.column&&(s.start.column+=u),s.end.row==e.end.row&&s.end.column>e.end.column&&(s.end.column+=u)),o&&s.start.row>=e.end.row&&(s.start.row+=o,s.end.row+=o)}s.end=this.insert(s.start,r);if(i.length){var a=e.start,l=s.start,o=l.row-a.row,u=l.column-a.column;this.addFolds(i.map(function(e){return e=e.clone(),e.start.row==a.row&&(e.start.column+=u),e.end.row==a.row&&(e.end.column+=u),e.start.row+=o,e.end.row+=o,e}))}return s},this.indentRows=function(e,t,n){n=n.replace(/\t/g,this.getTabString());for(var r=e;r<=t;r++)this.doc.insertInLine({row:r,column:0},n)},this.outdentRows=function(e){var t=e.collapseRows(),n=new f(0,0,0,0),r=this.getTabSize();for(var i=t.start.row;i<=t.end.row;++i){var s=this.getLine(i);n.start.row=i,n.end.row=i;for(var o=0;o0){var r=this.getRowFoldEnd(t+n);if(r>this.doc.getLength()-1)return 0;var i=r-t}else{e=this.$clipRowToDocument(e),t=this.$clipRowToDocument(t);var i=t-e+1}var s=new f(e,0,t,Number.MAX_VALUE),o=this.getFoldsInRange(s).map(function(e){return e=e.clone(),e.start.row+=i,e.end.row+=i,e}),u=n==0?this.doc.getLines(e,t):this.doc.removeFullLines(e,t);return this.doc.insertFullLines(e+i,u),o.length&&this.addFolds(o),i},this.moveLinesUp=function(e,t){return this.$moveLines(e,t,-1)},this.moveLinesDown=function(e,t){return this.$moveLines(e,t,1)},this.duplicateLines=function(e,t){return this.$moveLines(e,t,0)},this.$clipRowToDocument=function(e){return Math.max(0,Math.min(e,this.doc.getLength()-1))},this.$clipColumnToRow=function(e,t){return t<0?0:Math.min(this.doc.getLine(e).length,t)},this.$clipPositionToDocument=function(e,t){t=Math.max(0,t);if(e<0)e=0,t=0;else{var n=this.doc.getLength();e>=n?(e=n-1,t=this.doc.getLine(n-1).length):t=Math.min(this.doc.getLine(e).length,t)}return{row:e,column:t}},this.$clipRangeToDocument=function(e){e.start.row<0?(e.start.row=0,e.start.column=0):e.start.column=this.$clipColumnToRow(e.start.row,e.start.column);var t=this.doc.getLength()-1;return e.end.row>t?(e.end.row=t,e.end.column=this.doc.getLine(t).length):e.end.column=this.$clipColumnToRow(e.end.row,e.end.column),e},this.$wrapLimit=80,this.$useWrapMode=!1,this.$wrapLimitRange={min:null,max:null},this.setUseWrapMode=function(e){if(e!=this.$useWrapMode){this.$useWrapMode=e,this.$modified=!0,this.$resetRowCache(0);if(e){var t=this.getLength();this.$wrapData=Array(t),this.$updateWrapData(0,t-1)}this._signal("changeWrapMode")}},this.getUseWrapMode=function(){return this.$useWrapMode},this.setWrapLimitRange=function(e,t){if(this.$wrapLimitRange.min!==e||this.$wrapLimitRange.max!==t)this.$wrapLimitRange={min:e,max:t},this.$modified=!0,this.$useWrapMode&&this._signal("changeWrapMode")},this.adjustWrapLimit=function(e,t){var n=this.$wrapLimitRange;n.max<0&&(n={min:t,max:t});var r=this.$constrainWrapLimit(e,n.min,n.max);return r!=this.$wrapLimit&&r>1?(this.$wrapLimit=r,this.$modified=!0,this.$useWrapMode&&(this.$updateWrapData(0,this.getLength()-1),this.$resetRowCache(0),this._signal("changeWrapLimit")),!0):!1},this.$constrainWrapLimit=function(e,t,n){return t&&(e=Math.max(t,e)),n&&(e=Math.min(n,e)),e},this.getWrapLimit=function(){return this.$wrapLimit},this.setWrapLimit=function(e){this.setWrapLimitRange(e,e)},this.getWrapLimitRange=function(){return{min:this.$wrapLimitRange.min,max:this.$wrapLimitRange.max}},this.$updateInternalDataOnChange=function(e){var t=this.$useWrapMode,n=e.action,r=e.start,i=e.end,s=r.row,o=i.row,u=o-s,a=null;this.$updating=!0;if(u!=0)if(n==="remove"){this[t?"$wrapData":"$rowLengthCache"].splice(s,u);var f=this.$foldData;a=this.getFoldsInRange(e),this.removeFolds(a);var l=this.getFoldLine(i.row),c=0;if(l){l.addRemoveChars(i.row,i.column,r.column-i.column),l.shiftRow(-u);var h=this.getFoldLine(s);h&&h!==l&&(h.merge(l),l=h),c=f.indexOf(l)+1}for(c;c=i.row&&l.shiftRow(-u)}o=s}else{var p=Array(u);p.unshift(s,0);var d=t?this.$wrapData:this.$rowLengthCache;d.splice.apply(d,p);var f=this.$foldData,l=this.getFoldLine(s),c=0;if(l){var v=l.range.compareInside(r.row,r.column);v==0?(l=l.split(r.row,r.column),l&&(l.shiftRow(u),l.addRemoveChars(o,0,i.column-r.column))):v==-1&&(l.addRemoveChars(s,0,i.column-r.column),l.shiftRow(u)),c=f.indexOf(l)+1}for(c;c=s&&l.shiftRow(u)}}else{u=Math.abs(e.start.column-e.end.column),n==="remove"&&(a=this.getFoldsInRange(e),this.removeFolds(a),u=-u);var l=this.getFoldLine(s);l&&l.addRemoveChars(s,r.column,u)}return t&&this.$wrapData.length!=this.doc.getLength()&&console.error("doc.getLength() and $wrapData.length have to be the same!"),this.$updating=!1,t?this.$updateWrapData(s,o):this.$updateRowLengthCache(s,o),a},this.$updateRowLengthCache=function(e,t,n){this.$rowLengthCache[e]=null,this.$rowLengthCache[t]=null},this.$updateWrapData=function(e,t){var r=this.doc.getAllLines(),i=this.getTabSize(),s=this.$wrapData,o=this.$wrapLimit,a,f,l=e;t=Math.min(t,r.length-1);while(l<=t)f=this.getFoldLine(l,f),f?(a=[],f.walk(function(e,t,i,s){var o;if(e!=null){o=this.$getDisplayTokens(e,a.length),o[0]=n;for(var f=1;fr-b){var w=a+r-b;if(e[w-1]>=p&&e[w]>=p){y(w);continue}if(e[w]==n||e[w]==u){for(w;w!=a-1;w--)if(e[w]==n)break;if(w>a){y(w);continue}w=a+r;for(w;w>2)),a-1);while(w>E&&e[w]E&&e[w]E&&e[w]==l)w--}else while(w>E&&e[w]E){y(++w);continue}w=a+r,e[w]==t&&w--,y(w-b)}return s},this.$getDisplayTokens=function(n,r){var i=[],s;r=r||0;for(var o=0;o39&&u<48||u>57&&u<64?i.push(l):u>=4352&&m(u)?i.push(e,t):i.push(e)}return i},this.$getStringScreenWidth=function(e,t,n){if(t==0)return[0,0];t==null&&(t=Infinity),n=n||0;var r,i;for(i=0;i=4352&&m(r)?n+=2:n+=1;if(n>t)break}return[n,i]},this.lineWidgets=null,this.getRowLength=function(e){if(this.lineWidgets)var t=this.lineWidgets[e]&&this.lineWidgets[e].rowCount||0;else t=0;return!this.$useWrapMode||!this.$wrapData[e]?1+t:this.$wrapData[e].length+1+t},this.getRowLineCount=function(e){return!this.$useWrapMode||!this.$wrapData[e]?1:this.$wrapData[e].length+1},this.getRowWrapIndent=function(e){if(this.$useWrapMode){var t=this.screenToDocumentPosition(e,Number.MAX_VALUE),n=this.$wrapData[t.row];return n.length&&n[0]=0)var o=a[f],r=this.$docRowCache[f],c=e>a[l-1];else var c=!l;var h=this.getLength()-1,p=this.getNextFoldLine(r),d=p?p.start.row:Infinity;while(o<=e){u=this.getRowLength(r);if(o+u>e||r>=h)break;o+=u,r++,r>d&&(r=p.end.row+1,p=this.getNextFoldLine(r,p),d=p?p.start.row:Infinity),c&&(this.$docRowCache.push(r),this.$screenRowCache.push(o))}if(p&&p.start.row<=r)n=this.getFoldDisplayLine(p),r=p.start.row;else{if(o+u<=e||r>h)return{row:h,column:this.getLine(h).length};n=this.getLine(r),p=null}var v=0;if(this.$useWrapMode){var m=this.$wrapData[r];if(m){var g=Math.floor(e-o);s=m[g],g>0&&m.length&&(v=m.indent,i=m[g-1]||m[m.length-1],n=n.substring(i))}}return i+=this.$getStringScreenWidth(n,t-v)[1],this.$useWrapMode&&i>=s&&(i=s-1),p?p.idxToPosition(i):{row:r,column:i}},this.documentToScreenPosition=function(e,t){if(typeof t=="undefined")var n=this.$clipPositionToDocument(e.row,e.column);else n=this.$clipPositionToDocument(e,t);e=n.row,t=n.column;var r=0,i=null,s=null;s=this.getFoldAt(e,t,1),s&&(e=s.start.row,t=s.start.column);var o,u=0,a=this.$docRowCache,f=this.$getRowCacheIndex(a,e),l=a.length;if(l&&f>=0)var u=a[f],r=this.$screenRowCache[f],c=e>a[l-1];else var c=!l;var h=this.getNextFoldLine(u),p=h?h.start.row:Infinity;while(u=p){o=h.end.row+1;if(o>e)break;h=this.getNextFoldLine(o,h),p=h?h.start.row:Infinity}else o=u+1;r+=this.getRowLength(u),u=o,c&&(this.$docRowCache.push(u),this.$screenRowCache.push(r))}var d="";h&&u>=p?(d=this.getFoldDisplayLine(h,e,t),i=h.start.row):(d=this.getLine(e).substring(0,t),i=e);var v=0;if(this.$useWrapMode){var m=this.$wrapData[i];if(m){var g=0;while(d.length>=m[g])r++,g++;d=d.substring(m[g-1]||0,d.length),v=g>0?m.indent:0}}return{row:r,column:v+this.$getStringScreenWidth(d)[0]}},this.documentToScreenColumn=function(e,t){return this.documentToScreenPosition(e,t).column},this.documentToScreenRow=function(e,t){return this.documentToScreenPosition(e,t).row},this.getScreenLength=function(){var e=0,t=null;if(!this.$useWrapMode){e=this.getLength();var n=this.$foldData;for(var r=0;ro&&(s=t.end.row+1,t=this.$foldData[r++],o=t?t.start.row:Infinity)}}return this.lineWidgets&&(e+=this.$getWidgetScreenLength()),e},this.$setFontMetrics=function(e){if(!this.$enableVarChar)return;this.$getStringScreenWidth=function(t,n,r){if(n===0)return[0,0];n||(n=Infinity),r=r||0;var i,s;for(s=0;sn)break}return[r,s]}},this.destroy=function(){this.bgTokenizer&&(this.bgTokenizer.setDocument(null),this.bgTokenizer=null),this.$stopWorker()}}).call(p.prototype),e("./edit_session/folding").Folding.call(p.prototype),e("./edit_session/bracket_match").BracketMatch.call(p.prototype),s.defineOptions(p.prototype,"session",{wrap:{set:function(e){!e||e=="off"?e=!1:e=="free"?e=!0:e=="printMargin"?e=-1:typeof e=="string"&&(e=parseInt(e,10)||!1);if(this.$wrap==e)return;this.$wrap=e;if(!e)this.setUseWrapMode(!1);else{var t=typeof e=="number"?e:null;this.setWrapLimitRange(t,t),this.setUseWrapMode(!0)}},get:function(){return this.getUseWrapMode()?this.$wrap==-1?"printMargin":this.getWrapLimitRange().min?this.$wrap:"free":"off"},handlesSet:!0},wrapMethod:{set:function(e){e=e=="auto"?this.$mode.type!="text":e!="text",e!=this.$wrapAsCode&&(this.$wrapAsCode=e,this.$useWrapMode&&(this.$modified=!0,this.$resetRowCache(0),this.$updateWrapData(0,this.getLength()-1)))},initialValue:"auto"},indentedSoftWrap:{initialValue:!0},firstLineNumber:{set:function(){this._signal("changeBreakpoint")},initialValue:1},useWorker:{set:function(e){this.$useWorker=e,this.$stopWorker(),e&&this.$startWorker()},initialValue:!0},useSoftTabs:{initialValue:!0},tabSize:{set:function(e){if(isNaN(e)||this.$tabSize===e)return;this.$modified=!0,this.$rowLengthCache=[],this.$tabSize=e,this._signal("changeTabSize")},initialValue:4,handlesSet:!0},overwrite:{set:function(e){this._signal("changeOverwrite")},initialValue:!1},newLineMode:{set:function(e){this.doc.setNewLineMode(e)},get:function(){return this.doc.getNewLineMode()},handlesSet:!0},mode:{set:function(e){this.setMode(e)},get:function(){return this.$modeId}}}),t.EditSession=p}),define("ace/search",["require","exports","module","ace/lib/lang","ace/lib/oop","ace/range"],function(e,t,n){"use strict";function u(e,t){function n(e){return/\w/.test(e)||t.regExp?"\\b":""}return n(e[0])+e+n(e[e.length-1])}var r=e("./lib/lang"),i=e("./lib/oop"),s=e("./range").Range,o=function(){this.$options={}};(function(){this.set=function(e){return i.mixin(this.$options,e),this},this.getOptions=function(){return r.copyObject(this.$options)},this.setOptions=function(e){this.$options=e},this.find=function(e){var t=this.$options,n=this.$matchIterator(e,t);if(!n)return!1;var r=null;return n.forEach(function(e,n,i){if(!e.start){var o=e.offset+(i||0);r=new s(n,o,n,o+e.length);if(!e.length&&t.start&&t.start.start&&t.skipCurrent!=0&&r.isEqual(t.start))return r=null,!1}else r=e;return!0}),r},this.findAll=function(e){var t=this.$options;if(!t.needle)return[];this.$assembleRegExp(t);var n=t.range,i=n?e.getLines(n.start.row,n.end.row):e.doc.getAllLines(),o=[],u=t.re;if(t.$isMultiLine){var a=u.length,f=i.length-a,l;e:for(var c=u.offset||0;c<=f;c++){for(var h=0;hv)continue;o.push(l=new s(c,v,c+a-1,m)),a>2&&(c=c+a-2)}}else for(var g=0;gE&&o[h].end.row==n.end.row)h--;o=o.slice(g,h+1);for(g=0,h=o.length;g=0;u--)if(i(o[u],t,s))return!0};else var u=function(e,t,s){var o=r.getMatchOffsets(e,n);for(var u=0;u=o;r--)if(n(e.getLine(r),r))return;if(t.wrap==0)return;for(r=u,o=s.row;r>=o;r--)if(n(e.getLine(r),r))return}:function(n){var r=s.row,i=e.getLine(r).substr(s.column);if(n(i,r,s.column))return;for(r+=1;r<=u;r++)if(n(e.getLine(r),r))return;if(t.wrap==0)return;for(r=o,u=s.row;r<=u;r++)if(n(e.getLine(r),r))return};return{forEach:a}}}).call(o.prototype),t.Search=o}),define("ace/keyboard/hash_handler",["require","exports","module","ace/lib/keys","ace/lib/useragent"],function(e,t,n){"use strict";function o(e,t){this.platform=t||(i.isMac?"mac":"win"),this.commands={},this.commandKeyBinding={},this.addCommands(e),this.$singleCommand=!0}function u(e,t){o.call(this,e,t),this.$singleCommand=!1}var r=e("../lib/keys"),i=e("../lib/useragent"),s=r.KEY_MODS;u.prototype=o.prototype,function(){function e(e){return typeof e=="object"&&e.bindKey&&e.bindKey.position||0}this.addCommand=function(e){this.commands[e.name]&&this.removeCommand(e),this.commands[e.name]=e,e.bindKey&&this._buildKeyHash(e)},this.removeCommand=function(e,t){var n=e&&(typeof e=="string"?e:e.name);e=this.commands[n],t||delete this.commands[n];var r=this.commandKeyBinding;for(var i in r){var s=r[i];if(s==e)delete r[i];else if(Array.isArray(s)){var o=s.indexOf(e);o!=-1&&(s.splice(o,1),s.length==1&&(r[i]=s[0]))}}},this.bindKey=function(e,t,n){typeof e=="object"&&e&&(n==undefined&&(n=e.position),e=e[this.platform]);if(!e)return;if(typeof t=="function")return this.addCommand({exec:t,bindKey:e,name:t.name||e});e.split("|").forEach(function(e){var r="";if(e.indexOf(" ")!=-1){var i=e.split(/\s+/);e=i.pop(),i.forEach(function(e){var t=this.parseKeys(e),n=s[t.hashId]+t.key;r+=(r?" ":"")+n,this._addCommandToBinding(r,"chainKeys")},this),r+=" "}var o=this.parseKeys(e),u=s[o.hashId]+o.key;this._addCommandToBinding(r+u,t,n)},this)},this._addCommandToBinding=function(t,n,r){var i=this.commandKeyBinding,s;if(!n)delete i[t];else if(!i[t]||this.$singleCommand)i[t]=n;else{Array.isArray(i[t])?(s=i[t].indexOf(n))!=-1&&i[t].splice(s,1):i[t]=[i[t]],typeof r!="number"&&(r||n.isDefault?r=-100:r=e(n));var o=i[t];for(s=0;sr)break}o.splice(s,0,n)}},this.addCommands=function(e){e&&Object.keys(e).forEach(function(t){var n=e[t];if(!n)return;if(typeof n=="string")return this.bindKey(n,t);typeof n=="function"&&(n={exec:n});if(typeof n!="object")return;n.name||(n.name=t),this.addCommand(n)},this)},this.removeCommands=function(e){Object.keys(e).forEach(function(t){this.removeCommand(e[t])},this)},this.bindKeys=function(e){Object.keys(e).forEach(function(t){this.bindKey(t,e[t])},this)},this._buildKeyHash=function(e){this.bindKey(e.bindKey,e)},this.parseKeys=function(e){var t=e.toLowerCase().split(/[\-\+]([\-\+])?/).filter(function(e){return e}),n=t.pop(),i=r[n];if(r.FUNCTION_KEYS[i])n=r.FUNCTION_KEYS[i].toLowerCase();else{if(!t.length)return{key:n,hashId:-1};if(t.length==1&&t[0]=="shift")return{key:n.toUpperCase(),hashId:-1}}var s=0;for(var o=t.length;o--;){var u=r.KEY_MODS[t[o]];if(u==null)return typeof console!="undefined"&&console.error("invalid modifier "+t[o]+" in "+e),!1;s|=u}return{key:n,hashId:s}},this.findKeyCommand=function(t,n){var r=s[t]+n;return this.commandKeyBinding[r]},this.handleKeyboard=function(e,t,n,r){if(r<0)return;var i=s[t]+n,o=this.commandKeyBinding[i];e.$keyChain&&(e.$keyChain+=" "+i,o=this.commandKeyBinding[e.$keyChain]||o);if(o)if(o=="chainKeys"||o[o.length-1]=="chainKeys")return e.$keyChain=e.$keyChain||i,{command:"null"};if(e.$keyChain)if(!!t&&t!=4||n.length!=1){if(t==-1||r>0)e.$keyChain=""}else e.$keyChain=e.$keyChain.slice(0,-i.length-1);return{command:o}},this.getStatusText=function(e,t){return t.$keyChain||""}}.call(o.prototype),t.HashHandler=o,t.MultiHashHandler=u}),define("ace/commands/command_manager",["require","exports","module","ace/lib/oop","ace/keyboard/hash_handler","ace/lib/event_emitter"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../keyboard/hash_handler").MultiHashHandler,s=e("../lib/event_emitter").EventEmitter,o=function(e,t){i.call(this,t,e),this.byName=this.commands,this.setDefaultHandler("exec",function(e){return e.command.exec(e.editor,e.args||{})})};r.inherits(o,i),function(){r.implement(this,s),this.exec=function(e,t,n){if(Array.isArray(e)){for(var r=e.length;r--;)if(this.exec(e[r],t,n))return!0;return!1}typeof e=="string"&&(e=this.commands[e]);if(!e)return!1;if(t&&t.$readOnly&&!e.readOnly)return!1;var i={editor:t,command:e,args:n};return i.returnValue=this._emit("exec",i),this._signal("afterExec",i),i.returnValue===!1?!1:!0},this.toggleRecording=function(e){if(this.$inReplay)return;return e&&e._emit("changeStatus"),this.recording?(this.macro.pop(),this.removeEventListener("exec",this.$addCommandToMacro),this.macro.length||(this.macro=this.oldMacro),this.recording=!1):(this.$addCommandToMacro||(this.$addCommandToMacro=function(e){this.macro.push([e.command,e.args])}.bind(this)),this.oldMacro=this.macro,this.macro=[],this.on("exec",this.$addCommandToMacro),this.recording=!0)},this.replay=function(e){if(this.$inReplay||!this.macro)return;if(this.recording)return this.toggleRecording(e);try{this.$inReplay=!0,this.macro.forEach(function(t){typeof t=="string"?this.exec(t,e):this.exec(t[0],e,t[1])},this)}finally{this.$inReplay=!1}},this.trimMacro=function(e){return e.map(function(e){return typeof e[0]!="string"&&(e[0]=e[0].name),e[1]||(e=e[0]),e})}}.call(o.prototype),t.CommandManager=o}),define("ace/commands/default_commands",["require","exports","module","ace/lib/lang","ace/config","ace/range"],function(e,t,n){"use strict";function o(e,t){return{win:e,mac:t}}var r=e("../lib/lang"),i=e("../config"),s=e("../range").Range;t.commands=[{name:"showSettingsMenu",bindKey:o("Ctrl-,","Command-,"),exec:function(e){i.loadModule("ace/ext/settings_menu",function(t){t.init(e),e.showSettingsMenu()})},readOnly:!0},{name:"goToNextError",bindKey:o("Alt-E","F4"),exec:function(e){i.loadModule("ace/ext/error_marker",function(t){t.showErrorMarker(e,1)})},scrollIntoView:"animate",readOnly:!0},{name:"goToPreviousError",bindKey:o("Alt-Shift-E","Shift-F4"),exec:function(e){i.loadModule("ace/ext/error_marker",function(t){t.showErrorMarker(e,-1)})},scrollIntoView:"animate",readOnly:!0},{name:"selectall",bindKey:o("Ctrl-A","Command-A"),exec:function(e){e.selectAll()},readOnly:!0},{name:"centerselection",bindKey:o(null,"Ctrl-L"),exec:function(e){e.centerSelection()},readOnly:!0},{name:"gotoline",bindKey:o("Ctrl-L","Command-L"),exec:function(e){var t=parseInt(prompt("Enter line number:"),10);isNaN(t)||e.gotoLine(t)},readOnly:!0},{name:"fold",bindKey:o("Alt-L|Ctrl-F1","Command-Alt-L|Command-F1"),exec:function(e){e.session.toggleFold(!1)},multiSelectAction:"forEach",scrollIntoView:"center",readOnly:!0},{name:"unfold",bindKey:o("Alt-Shift-L|Ctrl-Shift-F1","Command-Alt-Shift-L|Command-Shift-F1"),exec:function(e){e.session.toggleFold(!0)},multiSelectAction:"forEach",scrollIntoView:"center",readOnly:!0},{name:"toggleFoldWidget",bindKey:o("F2","F2"),exec:function(e){e.session.toggleFoldWidget()},multiSelectAction:"forEach",scrollIntoView:"center",readOnly:!0},{name:"toggleParentFoldWidget",bindKey:o("Alt-F2","Alt-F2"),exec:function(e){e.session.toggleFoldWidget(!0)},multiSelectAction:"forEach",scrollIntoView:"center",readOnly:!0},{name:"foldall",bindKey:o(null,"Ctrl-Command-Option-0"),exec:function(e){e.session.foldAll()},scrollIntoView:"center",readOnly:!0},{name:"foldOther",bindKey:o("Alt-0","Command-Option-0"),exec:function(e){e.session.foldAll(),e.session.unfold(e.selection.getAllRanges())},scrollIntoView:"center",readOnly:!0},{name:"unfoldall",bindKey:o("Alt-Shift-0","Command-Option-Shift-0"),exec:function(e){e.session.unfold()},scrollIntoView:"center",readOnly:!0},{name:"findnext",bindKey:o("Ctrl-K","Command-G"),exec:function(e){e.findNext()},multiSelectAction:"forEach",scrollIntoView:"center",readOnly:!0},{name:"findprevious",bindKey:o("Ctrl-Shift-K","Command-Shift-G"),exec:function(e){e.findPrevious()},multiSelectAction:"forEach",scrollIntoView:"center",readOnly:!0},{name:"selectOrFindNext",bindKey:o("Alt-K","Ctrl-G"),exec:function(e){e.selection.isEmpty()?e.selection.selectWord():e.findNext()},readOnly:!0},{name:"selectOrFindPrevious",bindKey:o("Alt-Shift-K","Ctrl-Shift-G"),exec:function(e){e.selection.isEmpty()?e.selection.selectWord():e.findPrevious()},readOnly:!0},{name:"find",bindKey:o("Ctrl-F","Command-F"),exec:function(e){i.loadModule("ace/ext/searchbox",function(t){t.Search(e)})},readOnly:!0},{name:"overwrite",bindKey:"Insert",exec:function(e){e.toggleOverwrite()},readOnly:!0},{name:"selecttostart",bindKey:o("Ctrl-Shift-Home","Command-Shift-Home|Command-Shift-Up"),exec:function(e){e.getSelection().selectFileStart()},multiSelectAction:"forEach",readOnly:!0,scrollIntoView:"animate",aceCommandGroup:"fileJump"},{name:"gotostart",bindKey:o("Ctrl-Home","Command-Home|Command-Up"),exec:function(e){e.navigateFileStart()},multiSelectAction:"forEach",readOnly:!0,scrollIntoView:"animate",aceCommandGroup:"fileJump"},{name:"selectup",bindKey:o("Shift-Up","Shift-Up|Ctrl-Shift-P"),exec:function(e){e.getSelection().selectUp()},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"golineup",bindKey:o("Up","Up|Ctrl-P"),exec:function(e,t){e.navigateUp(t.times)},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"selecttoend",bindKey:o("Ctrl-Shift-End","Command-Shift-End|Command-Shift-Down"),exec:function(e){e.getSelection().selectFileEnd()},multiSelectAction:"forEach",readOnly:!0,scrollIntoView:"animate",aceCommandGroup:"fileJump"},{name:"gotoend",bindKey:o("Ctrl-End","Command-End|Command-Down"),exec:function(e){e.navigateFileEnd()},multiSelectAction:"forEach",readOnly:!0,scrollIntoView:"animate",aceCommandGroup:"fileJump"},{name:"selectdown",bindKey:o("Shift-Down","Shift-Down|Ctrl-Shift-N"),exec:function(e){e.getSelection().selectDown()},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"golinedown",bindKey:o("Down","Down|Ctrl-N"),exec:function(e,t){e.navigateDown(t.times)},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"selectwordleft",bindKey:o("Ctrl-Shift-Left","Option-Shift-Left"),exec:function(e){e.getSelection().selectWordLeft()},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"gotowordleft",bindKey:o("Ctrl-Left","Option-Left"),exec:function(e){e.navigateWordLeft()},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"selecttolinestart",bindKey:o("Alt-Shift-Left","Command-Shift-Left|Ctrl-Shift-A"),exec:function(e){e.getSelection().selectLineStart()},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"gotolinestart",bindKey:o("Alt-Left|Home","Command-Left|Home|Ctrl-A"),exec:function(e){e.navigateLineStart()},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"selectleft",bindKey:o("Shift-Left","Shift-Left|Ctrl-Shift-B"),exec:function(e){e.getSelection().selectLeft()},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"gotoleft",bindKey:o("Left","Left|Ctrl-B"),exec:function(e,t){e.navigateLeft(t.times)},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"selectwordright",bindKey:o("Ctrl-Shift-Right","Option-Shift-Right"),exec:function(e){e.getSelection().selectWordRight()},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"gotowordright",bindKey:o("Ctrl-Right","Option-Right"),exec:function(e){e.navigateWordRight()},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"selecttolineend",bindKey:o("Alt-Shift-Right","Command-Shift-Right|Shift-End|Ctrl-Shift-E"),exec:function(e){e.getSelection().selectLineEnd()},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"gotolineend",bindKey:o("Alt-Right|End","Command-Right|End|Ctrl-E"),exec:function(e){e.navigateLineEnd()},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"selectright",bindKey:o("Shift-Right","Shift-Right"),exec:function(e){e.getSelection().selectRight()},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"gotoright",bindKey:o("Right","Right|Ctrl-F"),exec:function(e,t){e.navigateRight(t.times)},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"selectpagedown",bindKey:"Shift-PageDown",exec:function(e){e.selectPageDown()},readOnly:!0},{name:"pagedown",bindKey:o(null,"Option-PageDown"),exec:function(e){e.scrollPageDown()},readOnly:!0},{name:"gotopagedown",bindKey:o("PageDown","PageDown|Ctrl-V"),exec:function(e){e.gotoPageDown()},readOnly:!0},{name:"selectpageup",bindKey:"Shift-PageUp",exec:function(e){e.selectPageUp()},readOnly:!0},{name:"pageup",bindKey:o(null,"Option-PageUp"),exec:function(e){e.scrollPageUp()},readOnly:!0},{name:"gotopageup",bindKey:"PageUp",exec:function(e){e.gotoPageUp()},readOnly:!0},{name:"scrollup",bindKey:o("Ctrl-Up",null),exec:function(e){e.renderer.scrollBy(0,-2*e.renderer.layerConfig.lineHeight)},readOnly:!0},{name:"scrolldown",bindKey:o("Ctrl-Down",null),exec:function(e){e.renderer.scrollBy(0,2*e.renderer.layerConfig.lineHeight)},readOnly:!0},{name:"selectlinestart",bindKey:"Shift-Home",exec:function(e){e.getSelection().selectLineStart()},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"selectlineend",bindKey:"Shift-End",exec:function(e){e.getSelection().selectLineEnd()},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"togglerecording",bindKey:o("Ctrl-Alt-E","Command-Option-E"),exec:function(e){e.commands.toggleRecording(e)},readOnly:!0},{name:"replaymacro",bindKey:o("Ctrl-Shift-E","Command-Shift-E"),exec:function(e){e.commands.replay(e)},readOnly:!0},{name:"jumptomatching",bindKey:o("Ctrl-P","Ctrl-P"),exec:function(e){e.jumpToMatching()},multiSelectAction:"forEach",scrollIntoView:"animate",readOnly:!0},{name:"selecttomatching",bindKey:o("Ctrl-Shift-P","Ctrl-Shift-P"),exec:function(e){e.jumpToMatching(!0)},multiSelectAction:"forEach",scrollIntoView:"animate",readOnly:!0},{name:"expandToMatching",bindKey:o("Ctrl-Shift-M","Ctrl-Shift-M"),exec:function(e){e.jumpToMatching(!0,!0)},multiSelectAction:"forEach",scrollIntoView:"animate",readOnly:!0},{name:"passKeysToBrowser",bindKey:o(null,null),exec:function(){},passEvent:!0,readOnly:!0},{name:"copy",exec:function(e){},readOnly:!0},{name:"cut",exec:function(e){var t=e.getSelectionRange();e._emit("cut",t),e.selection.isEmpty()||(e.session.remove(t),e.clearSelection())},scrollIntoView:"cursor",multiSelectAction:"forEach"},{name:"paste",exec:function(e,t){e.$handlePaste(t)},scrollIntoView:"cursor"},{name:"removeline",bindKey:o("Ctrl-D","Command-D"),exec:function(e){e.removeLines()},scrollIntoView:"cursor",multiSelectAction:"forEachLine"},{name:"duplicateSelection",bindKey:o("Ctrl-Shift-D","Command-Shift-D"),exec:function(e){e.duplicateSelection()},scrollIntoView:"cursor",multiSelectAction:"forEach"},{name:"sortlines",bindKey:o("Ctrl-Alt-S","Command-Alt-S"),exec:function(e){e.sortLines()},scrollIntoView:"selection",multiSelectAction:"forEachLine"},{name:"togglecomment",bindKey:o("Ctrl-/","Command-/"),exec:function(e){e.toggleCommentLines()},multiSelectAction:"forEachLine",scrollIntoView:"selectionPart"},{name:"toggleBlockComment",bindKey:o("Ctrl-Shift-/","Command-Shift-/"),exec:function(e){e.toggleBlockComment()},multiSelectAction:"forEach",scrollIntoView:"selectionPart"},{name:"modifyNumberUp",bindKey:o("Ctrl-Shift-Up","Alt-Shift-Up"),exec:function(e){e.modifyNumber(1)},scrollIntoView:"cursor",multiSelectAction:"forEach"},{name:"modifyNumberDown",bindKey:o("Ctrl-Shift-Down","Alt-Shift-Down"),exec:function(e){e.modifyNumber(-1)},scrollIntoView:"cursor",multiSelectAction:"forEach"},{name:"replace",bindKey:o("Ctrl-H","Command-Option-F"),exec:function(e){i.loadModule("ace/ext/searchbox",function(t){t.Search(e,!0)})}},{name:"undo",bindKey:o("Ctrl-Z","Command-Z"),exec:function(e){e.undo()}},{name:"redo",bindKey:o("Ctrl-Shift-Z|Ctrl-Y","Command-Shift-Z|Command-Y"),exec:function(e){e.redo()}},{name:"copylinesup",bindKey:o("Alt-Shift-Up","Command-Option-Up"),exec:function(e){e.copyLinesUp()},scrollIntoView:"cursor"},{name:"movelinesup",bindKey:o("Alt-Up","Option-Up"),exec:function(e){e.moveLinesUp()},scrollIntoView:"cursor"},{name:"copylinesdown",bindKey:o("Alt-Shift-Down","Command-Option-Down"),exec:function(e){e.copyLinesDown()},scrollIntoView:"cursor"},{name:"movelinesdown",bindKey:o("Alt-Down","Option-Down"),exec:function(e){e.moveLinesDown()},scrollIntoView:"cursor"},{name:"del",bindKey:o("Delete","Delete|Ctrl-D|Shift-Delete"),exec:function(e){e.remove("right")},multiSelectAction:"forEach",scrollIntoView:"cursor"},{name:"backspace",bindKey:o("Shift-Backspace|Backspace","Ctrl-Backspace|Shift-Backspace|Backspace|Ctrl-H"),exec:function(e){e.remove("left")},multiSelectAction:"forEach",scrollIntoView:"cursor"},{name:"cut_or_delete",bindKey:o("Shift-Delete",null),exec:function(e){if(!e.selection.isEmpty())return!1;e.remove("left")},multiSelectAction:"forEach",scrollIntoView:"cursor"},{name:"removetolinestart",bindKey:o("Alt-Backspace","Command-Backspace"),exec:function(e){e.removeToLineStart()},multiSelectAction:"forEach",scrollIntoView:"cursor"},{name:"removetolineend",bindKey:o("Alt-Delete","Ctrl-K"),exec:function(e){e.removeToLineEnd()},multiSelectAction:"forEach",scrollIntoView:"cursor"},{name:"removewordleft",bindKey:o("Ctrl-Backspace","Alt-Backspace|Ctrl-Alt-Backspace"),exec:function(e){e.removeWordLeft()},multiSelectAction:"forEach",scrollIntoView:"cursor"},{name:"removewordright",bindKey:o("Ctrl-Delete","Alt-Delete"),exec:function(e){e.removeWordRight()},multiSelectAction:"forEach",scrollIntoView:"cursor"},{name:"outdent",bindKey:o("Shift-Tab","Shift-Tab"),exec:function(e){e.blockOutdent()},multiSelectAction:"forEach",scrollIntoView:"selectionPart"},{name:"indent",bindKey:o("Tab","Tab"),exec:function(e){e.indent()},multiSelectAction:"forEach",scrollIntoView:"selectionPart"},{name:"blockoutdent",bindKey:o("Ctrl-[","Ctrl-["),exec:function(e){e.blockOutdent()},multiSelectAction:"forEachLine",scrollIntoView:"selectionPart"},{name:"blockindent",bindKey:o("Ctrl-]","Ctrl-]"),exec:function(e){e.blockIndent()},multiSelectAction:"forEachLine",scrollIntoView:"selectionPart"},{name:"insertstring",exec:function(e,t){e.insert(t)},multiSelectAction:"forEach",scrollIntoView:"cursor"},{name:"inserttext",exec:function(e,t){e.insert(r.stringRepeat(t.text||"",t.times||1))},multiSelectAction:"forEach",scrollIntoView:"cursor"},{name:"splitline",bindKey:o(null,"Ctrl-O"),exec:function(e){e.splitLine()},multiSelectAction:"forEach",scrollIntoView:"cursor"},{name:"transposeletters",bindKey:o("Ctrl-T","Ctrl-T"),exec:function(e){e.transposeLetters()},multiSelectAction:function(e){e.transposeSelections(1)},scrollIntoView:"cursor"},{name:"touppercase",bindKey:o("Ctrl-U","Ctrl-U"),exec:function(e){e.toUpperCase()},multiSelectAction:"forEach",scrollIntoView:"cursor"},{name:"tolowercase",bindKey:o("Ctrl-Shift-U","Ctrl-Shift-U"),exec:function(e){e.toLowerCase()},multiSelectAction:"forEach",scrollIntoView:"cursor"},{name:"expandtoline",bindKey:o("Ctrl-Shift-L","Command-Shift-L"),exec:function(e){var t=e.selection.getRange();t.start.column=t.end.column=0,t.end.row++,e.selection.setRange(t,!1)},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"joinlines",bindKey:o(null,null),exec:function(e){var t=e.selection.isBackwards(),n=t?e.selection.getSelectionLead():e.selection.getSelectionAnchor(),i=t?e.selection.getSelectionAnchor():e.selection.getSelectionLead(),o=e.session.doc.getLine(n.row).length,u=e.session.doc.getTextRange(e.selection.getRange()),a=u.replace(/\n\s*/," ").length,f=e.session.doc.getLine(n.row);for(var l=n.row+1;l<=i.row+1;l++){var c=r.stringTrimLeft(r.stringTrimRight(e.session.doc.getLine(l)));c.length!==0&&(c=" "+c),f+=c}i.row+10?(e.selection.moveCursorTo(n.row,n.column),e.selection.selectTo(n.row,n.column+a)):(o=e.session.doc.getLine(n.row).length>o?o+1:o,e.selection.moveCursorTo(n.row,o))},multiSelectAction:"forEach",readOnly:!0},{name:"invertSelection",bindKey:o(null,null),exec:function(e){var t=e.session.doc.getLength()-1,n=e.session.doc.getLine(t).length,r=e.selection.rangeList.ranges,i=[];r.length<1&&(r=[e.selection.getRange()]);for(var o=0;o0&&this.$blockScrolling--;var n=t&&t.scrollIntoView;if(n){switch(n){case"center-animate":n="animate";case"center":this.renderer.scrollCursorIntoView(null,.5);break;case"animate":case"cursor":this.renderer.scrollCursorIntoView();break;case"selectionPart":var r=this.selection.getRange(),i=this.renderer.layerConfig;(r.start.row>=i.lastRow||r.end.row<=i.firstRow)&&this.renderer.scrollSelectionIntoView(this.selection.anchor,this.selection.lead);break;default:}n=="animate"&&this.renderer.animateScrolling(this.curOp.scrollTop)}this.prevOp=this.curOp,this.curOp=null}},this.$mergeableCommands=["backspace","del","insertstring"],this.$historyTracker=function(e){if(!this.$mergeUndoDeltas)return;var t=this.prevOp,n=this.$mergeableCommands,r=t.command&&e.command.name==t.command.name;if(e.command.name=="insertstring"){var i=e.args;this.mergeNextCommand===undefined&&(this.mergeNextCommand=!0),r=r&&this.mergeNextCommand&&(!/\s/.test(i)||/\s/.test(t.args)),this.mergeNextCommand=!0}else r=r&&n.indexOf(e.command.name)!==-1;this.$mergeUndoDeltas!="always"&&Date.now()-this.sequenceStartTime>2e3&&(r=!1),r?this.session.mergeUndoDeltas=!0:n.indexOf(e.command.name)!==-1&&(this.sequenceStartTime=Date.now())},this.setKeyboardHandler=function(e,t){if(e&&typeof e=="string"){this.$keybindingId=e;var n=this;g.loadModule(["keybinding",e],function(r){n.$keybindingId==e&&n.keyBinding.setKeyboardHandler(r&&r.handler),t&&t()})}else this.$keybindingId=null,this.keyBinding.setKeyboardHandler(e),t&&t()},this.getKeyboardHandler=function(){return this.keyBinding.getKeyboardHandler()},this.setSession=function(e){if(this.session==e)return;this.curOp&&this.endOperation(),this.curOp={};var t=this.session;if(t){this.session.off("change",this.$onDocumentChange),this.session.off("changeMode",this.$onChangeMode),this.session.off("tokenizerUpdate",this.$onTokenizerUpdate),this.session.off("changeTabSize",this.$onChangeTabSize),this.session.off("changeWrapLimit",this.$onChangeWrapLimit),this.session.off("changeWrapMode",this.$onChangeWrapMode),this.session.off("changeFold",this.$onChangeFold),this.session.off("changeFrontMarker",this.$onChangeFrontMarker),this.session.off("changeBackMarker",this.$onChangeBackMarker),this.session.off("changeBreakpoint",this.$onChangeBreakpoint),this.session.off("changeAnnotation",this.$onChangeAnnotation),this.session.off("changeOverwrite",this.$onCursorChange),this.session.off("changeScrollTop",this.$onScrollTopChange),this.session.off("changeScrollLeft",this.$onScrollLeftChange);var n=this.session.getSelection();n.off("changeCursor",this.$onCursorChange),n.off("changeSelection",this.$onSelectionChange)}this.session=e,e?(this.$onDocumentChange=this.onDocumentChange.bind(this),e.on("change",this.$onDocumentChange),this.renderer.setSession(e),this.$onChangeMode=this.onChangeMode.bind(this),e.on("changeMode",this.$onChangeMode),this.$onTokenizerUpdate=this.onTokenizerUpdate.bind(this),e.on("tokenizerUpdate",this.$onTokenizerUpdate),this.$onChangeTabSize=this.renderer.onChangeTabSize.bind(this.renderer),e.on("changeTabSize",this.$onChangeTabSize),this.$onChangeWrapLimit=this.onChangeWrapLimit.bind(this),e.on("changeWrapLimit",this.$onChangeWrapLimit),this.$onChangeWrapMode=this.onChangeWrapMode.bind(this),e.on("changeWrapMode",this.$onChangeWrapMode),this.$onChangeFold=this.onChangeFold.bind(this),e.on("changeFold",this.$onChangeFold),this.$onChangeFrontMarker=this.onChangeFrontMarker.bind(this),this.session.on("changeFrontMarker",this.$onChangeFrontMarker),this.$onChangeBackMarker=this.onChangeBackMarker.bind(this),this.session.on("changeBackMarker",this.$onChangeBackMarker),this.$onChangeBreakpoint=this.onChangeBreakpoint.bind(this),this.session.on("changeBreakpoint",this.$onChangeBreakpoint),this.$onChangeAnnotation=this.onChangeAnnotation.bind(this),this.session.on("changeAnnotation",this.$onChangeAnnotation),this.$onCursorChange=this.onCursorChange.bind(this),this.session.on("changeOverwrite",this.$onCursorChange),this.$onScrollTopChange=this.onScrollTopChange.bind(this),this.session.on("changeScrollTop",this.$onScrollTopChange),this.$onScrollLeftChange=this.onScrollLeftChange.bind(this),this.session.on("changeScrollLeft",this.$onScrollLeftChange),this.selection=e.getSelection(),this.selection.on("changeCursor",this.$onCursorChange),this.$onSelectionChange=this.onSelectionChange.bind(this),this.selection.on("changeSelection",this.$onSelectionChange),this.onChangeMode(),this.$blockScrolling+=1,this.onCursorChange(),this.$blockScrolling-=1,this.onScrollTopChange(),this.onScrollLeftChange(),this.onSelectionChange(),this.onChangeFrontMarker(),this.onChangeBackMarker(),this.onChangeBreakpoint(),this.onChangeAnnotation(),this.session.getUseWrapMode()&&this.renderer.adjustWrapLimit(),this.renderer.updateFull()):(this.selection=null,this.renderer.setSession(e)),this._signal("changeSession",{session:e,oldSession:t}),this.curOp=null,t&&t._signal("changeEditor",{oldEditor:this}),e&&e._signal("changeEditor",{editor:this})},this.getSession=function(){return this.session},this.setValue=function(e,t){return this.session.doc.setValue(e),t?t==1?this.navigateFileEnd():t==-1&&this.navigateFileStart():this.selectAll(),e},this.getValue=function(){return this.session.getValue()},this.getSelection=function(){return this.selection},this.resize=function(e){this.renderer.onResize(e)},this.setTheme=function(e,t){this.renderer.setTheme(e,t)},this.getTheme=function(){return this.renderer.getTheme()},this.setStyle=function(e){this.renderer.setStyle(e)},this.unsetStyle=function(e){this.renderer.unsetStyle(e)},this.getFontSize=function(){return this.getOption("fontSize")||i.computedStyle(this.container,"fontSize")},this.setFontSize=function(e){this.setOption("fontSize",e)},this.$highlightBrackets=function(){this.session.$bracketHighlight&&(this.session.removeMarker(this.session.$bracketHighlight),this.session.$bracketHighlight=null);if(this.$highlightPending)return;var e=this;this.$highlightPending=!0,setTimeout(function(){e.$highlightPending=!1;var t=e.session;if(!t||!t.bgTokenizer)return;var n=t.findMatchingBracket(e.getCursorPosition());if(n)var r=new p(n.row,n.column,n.row,n.column+1);else if(t.$mode.getMatching)var r=t.$mode.getMatching(e.session);r&&(t.$bracketHighlight=t.addMarker(r,"ace_bracket","text"))},50)},this.$highlightTags=function(){if(this.$highlightTagPending)return;var e=this;this.$highlightTagPending=!0,setTimeout(function(){e.$highlightTagPending=!1;var t=e.session;if(!t||!t.bgTokenizer)return;var n=e.getCursorPosition(),r=new y(e.session,n.row,n.column),i=r.getCurrentToken();if(!i||!/\b(?:tag-open|tag-name)/.test(i.type)){t.removeMarker(t.$tagHighlight),t.$tagHighlight=null;return}if(i.type.indexOf("tag-open")!=-1){i=r.stepForward();if(!i)return}var s=i.value,o=0,u=r.stepBackward();if(u.value=="<"){do u=i,i=r.stepForward(),i&&i.value===s&&i.type.indexOf("tag-name")!==-1&&(u.value==="<"?o++:u.value==="=0)}else{do i=u,u=r.stepBackward(),i&&i.value===s&&i.type.indexOf("tag-name")!==-1&&(u.value==="<"?o++:u.value==="1)&&(t=!1)}if(e.$highlightLineMarker&&!t)e.removeMarker(e.$highlightLineMarker.id),e.$highlightLineMarker=null;else if(!e.$highlightLineMarker&&t){var n=new p(t.row,t.column,t.row,Infinity);n.id=e.addMarker(n,"ace_active-line","screenLine"),e.$highlightLineMarker=n}else t&&(e.$highlightLineMarker.start.row=t.row,e.$highlightLineMarker.end.row=t.row,e.$highlightLineMarker.start.column=t.column,e._signal("changeBackMarker"))},this.onSelectionChange=function(e){var t=this.session;t.$selectionMarker&&t.removeMarker(t.$selectionMarker),t.$selectionMarker=null;if(!this.selection.isEmpty()){var n=this.selection.getRange(),r=this.getSelectionStyle();t.$selectionMarker=t.addMarker(n,"ace_selection",r)}else this.$updateHighlightActiveLine();var i=this.$highlightSelectedWord&&this.$getSelectionHighLightRegexp();this.session.highlight(i),this._signal("changeSelection")},this.$getSelectionHighLightRegexp=function(){var e=this.session,t=this.getSelectionRange();if(t.isEmpty()||t.isMultiLine())return;var n=t.start.column-1,r=t.end.column+1,i=e.getLine(t.start.row),s=i.length,o=i.substring(Math.max(n,0),Math.min(r,s));if(n>=0&&/^[\w\d]/.test(o)||r<=s&&/[\w\d]$/.test(o))return;o=i.substring(t.start.column,t.end.column);if(!/^[\w\d]+$/.test(o))return;var u=this.$search.$assembleRegExp({wholeWord:!0,caseSensitive:!0,needle:o});return u},this.onChangeFrontMarker=function(){this.renderer.updateFrontMarkers()},this.onChangeBackMarker=function(){this.renderer.updateBackMarkers()},this.onChangeBreakpoint=function(){this.renderer.updateBreakpoints()},this.onChangeAnnotation=function(){this.renderer.setAnnotations(this.session.getAnnotations())},this.onChangeMode=function(e){this.renderer.updateText(),this._emit("changeMode",e)},this.onChangeWrapLimit=function(){this.renderer.updateFull()},this.onChangeWrapMode=function(){this.renderer.onResize(!0)},this.onChangeFold=function(){this.$updateHighlightActiveLine(),this.renderer.updateFull()},this.getSelectedText=function(){return this.session.getTextRange(this.getSelectionRange())},this.getCopyText=function(){var e=this.getSelectedText();return this._signal("copy",e),e},this.onCopy=function(){this.commands.exec("copy",this)},this.onCut=function(){this.commands.exec("cut",this)},this.onPaste=function(e,t){var n={text:e,event:t};this.commands.exec("paste",this,n)},this.$handlePaste=function(e){typeof e=="string"&&(e={text:e}),this._signal("paste",e);var t=e.text;if(!this.inMultiSelectMode||this.inVirtualSelectionMode)this.insert(t);else{var n=t.split(/\r\n|\r|\n/),r=this.selection.rangeList.ranges;if(n.length>r.length||n.length<2||!n[1])return this.commands.exec("insertstring",this,t);for(var i=r.length;i--;){var s=r[i];s.isEmpty()||this.session.remove(s),this.session.insert(s.start,n[i])}}},this.execCommand=function(e,t){return this.commands.exec(e,this,t)},this.insert=function(e,t){var n=this.session,r=n.getMode(),i=this.getCursorPosition();if(this.getBehavioursEnabled()&&!t){var s=r.transformAction(n.getState(i.row),"insertion",this,n,e);s&&(e!==s.text&&(this.session.mergeUndoDeltas=!1,this.$mergeNextCommand=!1),e=s.text)}e==" "&&(e=this.session.getTabString());if(!this.selection.isEmpty()){var o=this.getSelectionRange();i=this.session.remove(o),this.clearSelection()}else if(this.session.getOverwrite()){var o=new p.fromPoints(i,i);o.end.column+=e.length,this.session.remove(o)}if(e=="\n"||e=="\r\n"){var u=n.getLine(i.row);if(i.column>u.search(/\S|$/)){var a=u.substr(i.column).search(/\S|$/);n.doc.removeInLine(i.row,i.column,i.column+a)}}this.clearSelection();var f=i.column,l=n.getState(i.row),u=n.getLine(i.row),c=r.checkOutdent(l,u,e),h=n.insert(i,e);s&&s.selection&&(s.selection.length==2?this.selection.setSelectionRange(new p(i.row,f+s.selection[0],i.row,f+s.selection[1])):this.selection.setSelectionRange(new p(i.row+s.selection[0],s.selection[1],i.row+s.selection[2],s.selection[3])));if(n.getDocument().isNewLine(e)){var d=r.getNextLineIndent(l,u.slice(0,i.column),n.getTabString());n.insert({row:i.row+1,column:0},d)}c&&r.autoOutdent(l,n,i.row)},this.onTextInput=function(e){this.keyBinding.onTextInput(e)},this.onCommandKey=function(e,t,n){this.keyBinding.onCommandKey(e,t,n)},this.setOverwrite=function(e){this.session.setOverwrite(e)},this.getOverwrite=function(){return this.session.getOverwrite()},this.toggleOverwrite=function(){this.session.toggleOverwrite()},this.setScrollSpeed=function(e){this.setOption("scrollSpeed",e)},this.getScrollSpeed=function(){return this.getOption("scrollSpeed")},this.setDragDelay=function(e){this.setOption("dragDelay",e)},this.getDragDelay=function(){return this.getOption("dragDelay")},this.setSelectionStyle=function(e){this.setOption("selectionStyle",e)},this.getSelectionStyle=function(){return this.getOption("selectionStyle")},this.setHighlightActiveLine=function(e){this.setOption("highlightActiveLine",e)},this.getHighlightActiveLine=function(){return this.getOption("highlightActiveLine")},this.setHighlightGutterLine=function(e){this.setOption("highlightGutterLine",e)},this.getHighlightGutterLine=function(){return this.getOption("highlightGutterLine")},this.setHighlightSelectedWord=function(e){this.setOption("highlightSelectedWord",e)},this.getHighlightSelectedWord=function(){return this.$highlightSelectedWord},this.setAnimatedScroll=function(e){this.renderer.setAnimatedScroll(e)},this.getAnimatedScroll=function(){return this.renderer.getAnimatedScroll()},this.setShowInvisibles=function(e){this.renderer.setShowInvisibles(e)},this.getShowInvisibles=function(){return this.renderer.getShowInvisibles()},this.setDisplayIndentGuides=function(e){this.renderer.setDisplayIndentGuides(e)},this.getDisplayIndentGuides=function(){return this.renderer.getDisplayIndentGuides()},this.setShowPrintMargin=function(e){this.renderer.setShowPrintMargin(e)},this.getShowPrintMargin=function(){return this.renderer.getShowPrintMargin()},this.setPrintMarginColumn=function(e){this.renderer.setPrintMarginColumn(e)},this.getPrintMarginColumn=function(){return this.renderer.getPrintMarginColumn()},this.setReadOnly=function(e){this.setOption("readOnly",e)},this.getReadOnly=function(){return this.getOption("readOnly")},this.setBehavioursEnabled=function(e){this.setOption("behavioursEnabled",e)},this.getBehavioursEnabled=function(){return this.getOption("behavioursEnabled")},this.setWrapBehavioursEnabled=function(e){this.setOption("wrapBehavioursEnabled",e)},this.getWrapBehavioursEnabled=function(){return this.getOption("wrapBehavioursEnabled")},this.setShowFoldWidgets=function(e){this.setOption("showFoldWidgets",e)},this.getShowFoldWidgets=function(){return this.getOption("showFoldWidgets")},this.setFadeFoldWidgets=function(e){this.setOption("fadeFoldWidgets",e)},this.getFadeFoldWidgets=function(){return this.getOption("fadeFoldWidgets")},this.remove=function(e){this.selection.isEmpty()&&(e=="left"?this.selection.selectLeft():this.selection.selectRight());var t=this.getSelectionRange();if(this.getBehavioursEnabled()){var n=this.session,r=n.getState(t.start.row),i=n.getMode().transformAction(r,"deletion",this,n,t);if(t.end.column===0){var s=n.getTextRange(t);if(s[s.length-1]=="\n"){var o=n.getLine(t.end.row);/^\s+$/.test(o)&&(t.end.column=o.length)}}i&&(t=i)}this.session.remove(t),this.clearSelection()},this.removeWordRight=function(){this.selection.isEmpty()&&this.selection.selectWordRight(),this.session.remove(this.getSelectionRange()),this.clearSelection()},this.removeWordLeft=function(){this.selection.isEmpty()&&this.selection.selectWordLeft(),this.session.remove(this.getSelectionRange()),this.clearSelection()},this.removeToLineStart=function(){this.selection.isEmpty()&&this.selection.selectLineStart(),this.session.remove(this.getSelectionRange()),this.clearSelection()},this.removeToLineEnd=function(){this.selection.isEmpty()&&this.selection.selectLineEnd();var e=this.getSelectionRange();e.start.column==e.end.column&&e.start.row==e.end.row&&(e.end.column=0,e.end.row++),this.session.remove(e),this.clearSelection()},this.splitLine=function(){this.selection.isEmpty()||(this.session.remove(this.getSelectionRange()),this.clearSelection());var e=this.getCursorPosition();this.insert("\n"),this.moveCursorToPosition(e)},this.transposeLetters=function(){if(!this.selection.isEmpty())return;var e=this.getCursorPosition(),t=e.column;if(t===0)return;var n=this.session.getLine(e.row),r,i;tt.toLowerCase()?1:0});var r=new p(0,0,0,0);for(var i=e.first;i<=e.last;i++){var s=t.getLine(i);r.start.row=i,r.end.row=i,r.end.column=s.length,t.replace(r,n[i-e.first])}},this.toggleCommentLines=function(){var e=this.session.getState(this.getCursorPosition().row),t=this.$getSelectedRows();this.session.getMode().toggleCommentLines(e,this.session,t.first,t.last)},this.toggleBlockComment=function(){var e=this.getCursorPosition(),t=this.session.getState(e.row),n=this.getSelectionRange();this.session.getMode().toggleBlockComment(t,this.session,n,e)},this.getNumberAt=function(e,t){var n=/[\-]?[0-9]+(?:\.[0-9]+)?/g;n.lastIndex=0;var r=this.session.getLine(e);while(n.lastIndex=t){var s={value:i[0],start:i.index,end:i.index+i[0].length};return s}}return null},this.modifyNumber=function(e){var t=this.selection.getCursor().row,n=this.selection.getCursor().column,r=new p(t,n-1,t,n),i=this.session.getTextRange(r);if(!isNaN(parseFloat(i))&&isFinite(i)){var s=this.getNumberAt(t,n);if(s){var o=s.value.indexOf(".")>=0?s.start+s.value.indexOf(".")+1:s.end,u=s.start+s.value.length-o,a=parseFloat(s.value);a*=Math.pow(10,u),o!==s.end&&np+1)break;p=d.last}l--,u=this.session.$moveLines(h,p,t?0:e),t&&e==-1&&(c=l+1);while(c<=l)o[c].moveBy(u,0),c++;t||(u=0),a+=u}i.fromOrientedRange(i.ranges[0]),i.rangeList.attach(this.session),this.inVirtualSelectionMode=!1}},this.$getSelectedRows=function(e){return e=(e||this.getSelectionRange()).collapseRows(),{first:this.session.getRowFoldStart(e.start.row),last:this.session.getRowFoldEnd(e.end.row)}},this.onCompositionStart=function(e){this.renderer.showComposition(this.getCursorPosition())},this.onCompositionUpdate=function(e){this.renderer.setCompositionText(e)},this.onCompositionEnd=function(){this.renderer.hideComposition()},this.getFirstVisibleRow=function(){return this.renderer.getFirstVisibleRow()},this.getLastVisibleRow=function(){return this.renderer.getLastVisibleRow()},this.isRowVisible=function(e){return e>=this.getFirstVisibleRow()&&e<=this.getLastVisibleRow()},this.isRowFullyVisible=function(e){return e>=this.renderer.getFirstFullyVisibleRow()&&e<=this.renderer.getLastFullyVisibleRow()},this.$getVisibleRowCount=function(){return this.renderer.getScrollBottomRow()-this.renderer.getScrollTopRow()+1},this.$moveByPage=function(e,t){var n=this.renderer,r=this.renderer.layerConfig,i=e*Math.floor(r.height/r.lineHeight);this.$blockScrolling++,t===!0?this.selection.$moveSelection(function(){this.moveCursorBy(i,0)}):t===!1&&(this.selection.moveCursorBy(i,0),this.selection.clearSelection()),this.$blockScrolling--;var s=n.scrollTop;n.scrollBy(0,i*r.lineHeight),t!=null&&n.scrollCursorIntoView(null,.5),n.animateScrolling(s)},this.selectPageDown=function(){this.$moveByPage(1,!0)},this.selectPageUp=function(){this.$moveByPage(-1,!0)},this.gotoPageDown=function(){this.$moveByPage(1,!1)},this.gotoPageUp=function(){this.$moveByPage(-1,!1)},this.scrollPageDown=function(){this.$moveByPage(1)},this.scrollPageUp=function(){this.$moveByPage(-1)},this.scrollToRow=function(e){this.renderer.scrollToRow(e)},this.scrollToLine=function(e,t,n,r){this.renderer.scrollToLine(e,t,n,r)},this.centerSelection=function(){var e=this.getSelectionRange(),t={row:Math.floor(e.start.row+(e.end.row-e.start.row)/2),column:Math.floor(e.start.column+(e.end.column-e.start.column)/2)};this.renderer.alignCursor(t,.5)},this.getCursorPosition=function(){return this.selection.getCursor()},this.getCursorPositionScreen=function(){return this.session.documentToScreenPosition(this.getCursorPosition())},this.getSelectionRange=function(){return this.selection.getRange()},this.selectAll=function(){this.$blockScrolling+=1,this.selection.selectAll(),this.$blockScrolling-=1},this.clearSelection=function(){this.selection.clearSelection()},this.moveCursorTo=function(e,t){this.selection.moveCursorTo(e,t)},this.moveCursorToPosition=function(e){this.selection.moveCursorToPosition(e)},this.jumpToMatching=function(e,t){var n=this.getCursorPosition(),r=new y(this.session,n.row,n.column),i=r.getCurrentToken(),s=i||r.stepForward();if(!s)return;var o,u=!1,a={},f=n.column-s.start,l,c={")":"(","(":"(","]":"[","[":"[","{":"{","}":"{"};do{if(s.value.match(/[{}()\[\]]/g))for(;f=0;--s)this.$tryReplace(n[s],e)&&r++;return this.selection.setSelectionRange(i),this.$blockScrolling-=1,r},this.$tryReplace=function(e,t){var n=this.session.getTextRange(e);return t=this.$search.replace(n,t),t!==null?(e.end=this.session.replace(e,t),e):null},this.getLastSearchOptions=function(){return this.$search.getOptions()},this.find=function(e,t,n){t||(t={}),typeof e=="string"||e instanceof RegExp?t.needle=e:typeof e=="object"&&r.mixin(t,e);var i=this.selection.getRange();t.needle==null&&(e=this.session.getTextRange(i)||this.$search.$options.needle,e||(i=this.session.getWordRange(i.start.row,i.start.column),e=this.session.getTextRange(i)),this.$search.set({needle:e})),this.$search.set(t),t.start||this.$search.set({start:i});var s=this.$search.find(this.session);if(t.preventScroll)return s;if(s)return this.revealRange(s,n),s;t.backwards?i.start=i.end:i.end=i.start,this.selection.setRange(i)},this.findNext=function(e,t){this.find({skipCurrent:!0,backwards:!1},e,t)},this.findPrevious=function(e,t){this.find(e,{skipCurrent:!0,backwards:!0},t)},this.revealRange=function(e,t){this.$blockScrolling+=1,this.session.unfold(e),this.selection.setSelectionRange(e),this.$blockScrolling-=1;var n=this.renderer.scrollTop;this.renderer.scrollSelectionIntoView(e.start,e.end,.5),t!==!1&&this.renderer.animateScrolling(n)},this.undo=function(){this.$blockScrolling++,this.session.getUndoManager().undo(),this.$blockScrolling--,this.renderer.scrollCursorIntoView(null,.5)},this.redo=function(){this.$blockScrolling++,this.session.getUndoManager().redo(),this.$blockScrolling--,this.renderer.scrollCursorIntoView(null,.5)},this.destroy=function(){this.renderer.destroy(),this._signal("destroy",this),this.session&&this.session.destroy()},this.setAutoScrollEditorIntoView=function(e){if(!e)return;var t,n=this,r=!1;this.$scrollAnchor||(this.$scrollAnchor=document.createElement("div"));var i=this.$scrollAnchor;i.style.cssText="position:absolute",this.container.insertBefore(i,this.container.firstChild);var s=this.on("changeSelection",function(){r=!0}),o=this.renderer.on("beforeRender",function(){r&&(t=n.renderer.container.getBoundingClientRect())}),u=this.renderer.on("afterRender",function(){if(r&&t&&(n.isFocused()||n.searchBox&&n.searchBox.isFocused())){var e=n.renderer,s=e.$cursorLayer.$pixelPos,o=e.layerConfig,u=s.top-o.offset;s.top>=0&&u+t.top<0?r=!0:s.topwindow.innerHeight?r=!1:r=null,r!=null&&(i.style.top=u+"px",i.style.left=s.left+"px",i.style.height=o.lineHeight+"px",i.scrollIntoView(r)),r=t=null}});this.setAutoScrollEditorIntoView=function(e){if(e)return;delete this.setAutoScrollEditorIntoView,this.off("changeSelection",s),this.renderer.off("afterRender",u),this.renderer.off("beforeRender",o)}},this.$resetCursorStyle=function(){var e=this.$cursorStyle||"ace",t=this.renderer.$cursorLayer;if(!t)return;t.setSmoothBlinking(/smooth/.test(e)),t.isBlinking=!this.$readOnly&&e!="wide",i.setCssClass(t.element,"ace_slim-cursors",/slim/.test(e))}}).call(b.prototype),g.defineOptions(b.prototype,"editor",{selectionStyle:{set:function(e){this.onSelectionChange(),this._signal("changeSelectionStyle",{data:e})},initialValue:"line"},highlightActiveLine:{set:function(){this.$updateHighlightActiveLine()},initialValue:!0},highlightSelectedWord:{set:function(e){this.$onSelectionChange()},initialValue:!0},readOnly:{set:function(e){this.$resetCursorStyle()},initialValue:!1},cursorStyle:{set:function(e){this.$resetCursorStyle()},values:["ace","slim","smooth","wide"],initialValue:"ace"},mergeUndoDeltas:{values:[!1,!0,"always"],initialValue:!0},behavioursEnabled:{initialValue:!0},wrapBehavioursEnabled:{initialValue:!0},autoScrollEditorIntoView:{set:function(e){this.setAutoScrollEditorIntoView(e)}},keyboardHandler:{set:function(e){this.setKeyboardHandler(e)},get:function(){return this.keybindingId},handlesSet:!0},hScrollBarAlwaysVisible:"renderer",vScrollBarAlwaysVisible:"renderer",highlightGutterLine:"renderer",animatedScroll:"renderer",showInvisibles:"renderer",showPrintMargin:"renderer",printMarginColumn:"renderer",printMargin:"renderer",fadeFoldWidgets:"renderer",showFoldWidgets:"renderer",showLineNumbers:"renderer",showGutter:"renderer",displayIndentGuides:"renderer",fontSize:"renderer",fontFamily:"renderer",maxLines:"renderer",minLines:"renderer",scrollPastEnd:"renderer",fixedWidthGutter:"renderer",theme:"renderer",scrollSpeed:"$mouseHandler",dragDelay:"$mouseHandler",dragEnabled:"$mouseHandler",focusTimout:"$mouseHandler",tooltipFollowsMouse:"$mouseHandler",firstLineNumber:"session",overwrite:"session",newLineMode:"session",useWorker:"session",useSoftTabs:"session",tabSize:"session",wrap:"session",indentedSoftWrap:"session",foldStyle:"session",mode:"session"}),t.Editor=b}),define("ace/undomanager",["require","exports","module"],function(e,t,n){"use strict";var r=function(){this.reset()};(function(){function e(e){return{action:e.action,start:e.start,end:e.end,lines:e.lines.length==1?null:e.lines,text:e.lines.length==1?e.lines[0]:null}}function t(e){return{action:e.action,start:e.start,end:e.end,lines:e.lines||[e.text]}}function n(e,t){var n=new Array(e.length);for(var r=0;r0},this.hasRedo=function(){return this.$redoStack.length>0},this.markClean=function(){this.dirtyCounter=0},this.isClean=function(){return this.dirtyCounter===0},this.$serializeDeltas=function(t){return n(t,e)},this.$deserializeDeltas=function(e){return n(e,t)}}).call(r.prototype),t.UndoManager=r}),define("ace/layer/gutter",["require","exports","module","ace/lib/dom","ace/lib/oop","ace/lib/lang","ace/lib/event_emitter"],function(e,t,n){"use strict";var r=e("../lib/dom"),i=e("../lib/oop"),s=e("../lib/lang"),o=e("../lib/event_emitter").EventEmitter,u=function(e){this.element=r.createElement("div"),this.element.className="ace_layer ace_gutter-layer",e.appendChild(this.element),this.setShowFoldWidgets(this.$showFoldWidgets),this.gutterWidth=0,this.$annotations=[],this.$updateAnnotations=this.$updateAnnotations.bind(this),this.$cells=[]};(function(){i.implement(this,o),this.setSession=function(e){this.session&&this.session.removeEventListener("change",this.$updateAnnotations),this.session=e,e&&e.on("change",this.$updateAnnotations)},this.addGutterDecoration=function(e,t){window.console&&console.warn&&console.warn("deprecated use session.addGutterDecoration"),this.session.addGutterDecoration(e,t)},this.removeGutterDecoration=function(e,t){window.console&&console.warn&&console.warn("deprecated use session.removeGutterDecoration"),this.session.removeGutterDecoration(e,t)},this.setAnnotations=function(e){this.$annotations=[];for(var t=0;to&&(v=s.end.row+1,s=t.getNextFoldLine(v,s),o=s?s.start.row:Infinity);if(v>i){while(this.$cells.length>d+1)p=this.$cells.pop(),this.element.removeChild(p.element);break}p=this.$cells[++d],p||(p={element:null,textNode:null,foldWidget:null},p.element=r.createElement("div"),p.textNode=document.createTextNode(""),p.element.appendChild(p.textNode),this.element.appendChild(p.element),this.$cells[d]=p);var m="ace_gutter-cell ";a[v]&&(m+=a[v]),f[v]&&(m+=f[v]),this.$annotations[v]&&(m+=this.$annotations[v].className),p.element.className!=m&&(p.element.className=m);var g=t.getRowLength(v)*e.lineHeight+"px";g!=p.element.style.height&&(p.element.style.height=g);if(u){var y=u[v];y==null&&(y=u[v]=t.getFoldWidget(v))}if(y){p.foldWidget||(p.foldWidget=r.createElement("span"),p.element.appendChild(p.foldWidget));var m="ace_fold-widget ace_"+y;y=="start"&&v==o&&vn.right-t.right)return"foldWidgets"}}).call(u.prototype),t.Gutter=u}),define("ace/layer/marker",["require","exports","module","ace/range","ace/lib/dom"],function(e,t,n){"use strict";var r=e("../range").Range,i=e("../lib/dom"),s=function(e){this.element=i.createElement("div"),this.element.className="ace_layer ace_marker-layer",e.appendChild(this.element)};(function(){function e(e,t,n,r){return(e?1:0)|(t?2:0)|(n?4:0)|(r?8:0)}this.$padding=0,this.setPadding=function(e){this.$padding=e},this.setSession=function(e){this.session=e},this.setMarkers=function(e){this.markers=e},this.update=function(e){var e=e||this.config;if(!e)return;this.config=e;var t=[];for(var n in this.markers){var r=this.markers[n];if(!r.range){r.update(t,this,this.session,e);continue}var i=r.range.clipRows(e.firstRow,e.lastRow);if(i.isEmpty())continue;i=i.toScreenRange(this.session);if(r.renderer){var s=this.$getTop(i.start.row,e),o=this.$padding+i.start.column*e.characterWidth;r.renderer(t,i,o,s,e)}else r.type=="fullLine"?this.drawFullLineMarker(t,i,r.clazz,e):r.type=="screenLine"?this.drawScreenLineMarker(t,i,r.clazz,e):i.isMultiLine()?r.type=="text"?this.drawTextMarker(t,i,r.clazz,e):this.drawMultiLineMarker(t,i,r.clazz,e):this.drawSingleLineMarker(t,i,r.clazz+" ace_start"+" ace_br15",e)}this.element.innerHTML=t.join("")},this.$getTop=function(e,t){return(e-t.firstRowScreen)*t.lineHeight},this.drawTextMarker=function(t,n,i,s,o){var u=this.session,a=n.start.row,f=n.end.row,l=a,c=0,h=0,p=u.getScreenLastRowColumn(l),d=new r(l,n.start.column,l,h);for(;l<=f;l++)d.start.row=d.end.row=l,d.start.column=l==a?n.start.column:u.getRowWrapIndent(l),d.end.column=p,c=h,h=p,p=l+1p,l==f),s,l==f?0:1,o)},this.drawMultiLineMarker=function(e,t,n,r,i){var s=this.$padding,o=r.lineHeight,u=this.$getTop(t.start.row,r),a=s+t.start.column*r.characterWidth;i=i||"",e.push("
"),u=this.$getTop(t.end.row,r);var f=t.end.column*r.characterWidth;e.push("
"),o=(t.end.row-t.start.row-1)*r.lineHeight;if(o<=0)return;u=this.$getTop(t.start.row+1,r);var l=(t.start.column?1:0)|(t.end.column?0:8);e.push("
")},this.drawSingleLineMarker=function(e,t,n,r,i,s){var o=r.lineHeight,u=(t.end.column+(i||0)-t.start.column)*r.characterWidth,a=this.$getTop(t.start.row,r),f=this.$padding+t.start.column*r.characterWidth;e.push("
")},this.drawFullLineMarker=function(e,t,n,r,i){var s=this.$getTop(t.start.row,r),o=r.lineHeight;t.start.row!=t.end.row&&(o+=this.$getTop(t.end.row,r)-s),e.push("
")},this.drawScreenLineMarker=function(e,t,n,r,i){var s=this.$getTop(t.start.row,r),o=r.lineHeight;e.push("
")}}).call(s.prototype),t.Marker=s}),define("ace/layer/text",["require","exports","module","ace/lib/oop","ace/lib/dom","ace/lib/lang","ace/lib/useragent","ace/lib/event_emitter"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/dom"),s=e("../lib/lang"),o=e("../lib/useragent"),u=e("../lib/event_emitter").EventEmitter,a=function(e){this.element=i.createElement("div"),this.element.className="ace_layer ace_text-layer",e.appendChild(this.element),this.$updateEolChar=this.$updateEolChar.bind(this)};(function(){r.implement(this,u),this.EOF_CHAR="\u00b6",this.EOL_CHAR_LF="\u00ac",this.EOL_CHAR_CRLF="\u00a4",this.EOL_CHAR=this.EOL_CHAR_LF,this.TAB_CHAR="\u2014",this.SPACE_CHAR="\u00b7",this.$padding=0,this.$updateEolChar=function(){var e=this.session.doc.getNewLineCharacter()=="\n"?this.EOL_CHAR_LF:this.EOL_CHAR_CRLF;if(this.EOL_CHAR!=e)return this.EOL_CHAR=e,!0},this.setPadding=function(e){this.$padding=e,this.element.style.padding="0 "+e+"px"},this.getLineHeight=function(){return this.$fontMetrics.$characterSize.height||0},this.getCharacterWidth=function(){return this.$fontMetrics.$characterSize.width||0},this.$setFontMetrics=function(e){this.$fontMetrics=e,this.$fontMetrics.on("changeCharacterSize",function(e){this._signal("changeCharacterSize",e)}.bind(this)),this.$pollSizeChanges()},this.checkForSizeChanges=function(){this.$fontMetrics.checkForSizeChanges()},this.$pollSizeChanges=function(){return this.$pollSizeChangesTimer=this.$fontMetrics.$pollSizeChanges()},this.setSession=function(e){this.session=e,e&&this.$computeTabString()},this.showInvisibles=!1,this.setShowInvisibles=function(e){return this.showInvisibles==e?!1:(this.showInvisibles=e,this.$computeTabString(),!0)},this.displayIndentGuides=!0,this.setDisplayIndentGuides=function(e){return this.displayIndentGuides==e?!1:(this.displayIndentGuides=e,this.$computeTabString(),!0)},this.$tabStrings=[],this.onChangeTabSize=this.$computeTabString=function(){var e=this.session.getTabSize();this.tabSize=e;var t=this.$tabStrings=[0];for(var n=1;n"+s.stringRepeat(this.TAB_CHAR,n)+""):t.push(s.stringRepeat(" ",n));if(this.displayIndentGuides){this.$indentGuideRe=/\s\S| \t|\t |\s$/;var r="ace_indent-guide",i="",o="";if(this.showInvisibles){r+=" ace_invisible",i=" ace_invisible_space",o=" ace_invisible_tab";var u=s.stringRepeat(this.SPACE_CHAR,this.tabSize),a=s.stringRepeat(this.TAB_CHAR,this.tabSize)}else var u=s.stringRepeat(" ",this.tabSize),a=u;this.$tabStrings[" "]=""+u+"",this.$tabStrings[" "]=""+a+""}},this.updateLines=function(e,t,n){(this.config.lastRow!=e.lastRow||this.config.firstRow!=e.firstRow)&&this.scrollLines(e),this.config=e;var r=Math.max(t,e.firstRow),i=Math.min(n,e.lastRow),s=this.element.childNodes,o=0;for(var u=e.firstRow;uf&&(u=a.end.row+1,a=this.session.getNextFoldLine(u,a),f=a?a.start.row:Infinity);if(u>i)break;var l=s[o++];if(l){var c=[];this.$renderLine(c,u,!this.$useLineGroups(),u==f?a:!1),l.style.height=e.lineHeight*this.session.getRowLength(u)+"px",l.innerHTML=c.join("")}u++}},this.scrollLines=function(e){var t=this.config;this.config=e;if(!t||t.lastRow0;r--)n.removeChild(n.firstChild);if(t.lastRow>e.lastRow)for(var r=this.session.getFoldedRowCount(e.lastRow+1,t.lastRow);r>0;r--)n.removeChild(n.lastChild);if(e.firstRowt.lastRow){var i=this.$renderLinesFragment(e,t.lastRow+1,e.lastRow);n.appendChild(i)}},this.$renderLinesFragment=function(e,t,n){var r=this.element.ownerDocument.createDocumentFragment(),s=t,o=this.session.getNextFoldLine(s),u=o?o.start.row:Infinity;for(;;){s>u&&(s=o.end.row+1,o=this.session.getNextFoldLine(s,o),u=o?o.start.row:Infinity);if(s>n)break;var a=i.createElement("div"),f=[];this.$renderLine(f,s,!1,s==u?o:!1),a.innerHTML=f.join("");if(this.$useLineGroups())a.className="ace_line_group",r.appendChild(a),a.style.height=e.lineHeight*this.session.getRowLength(s)+"px";else while(a.firstChild)r.appendChild(a.firstChild);s++}return r},this.update=function(e){this.config=e;var t=[],n=e.firstRow,r=e.lastRow,i=n,s=this.session.getNextFoldLine(i),o=s?s.start.row:Infinity;for(;;){i>o&&(i=s.end.row+1,s=this.session.getNextFoldLine(i,s),o=s?s.start.row:Infinity);if(i>r)break;this.$useLineGroups()&&t.push("
"),this.$renderLine(t,i,!1,i==o?s:!1),this.$useLineGroups()&&t.push("
"),i++}this.element.innerHTML=t.join("")},this.$textToken={text:!0,rparen:!0,lparen:!0},this.$renderToken=function(e,t,n,r){var i=this,o=/\t|&|<|>|( +)|([\x00-\x1f\x80-\xa0\xad\u1680\u180E\u2000-\u200f\u2028\u2029\u202F\u205F\u3000\uFEFF\uFFF9-\uFFFC])|[\u1100-\u115F\u11A3-\u11A7\u11FA-\u11FF\u2329-\u232A\u2E80-\u2E99\u2E9B-\u2EF3\u2F00-\u2FD5\u2FF0-\u2FFB\u3000-\u303E\u3041-\u3096\u3099-\u30FF\u3105-\u312D\u3131-\u318E\u3190-\u31BA\u31C0-\u31E3\u31F0-\u321E\u3220-\u3247\u3250-\u32FE\u3300-\u4DBF\u4E00-\uA48C\uA490-\uA4C6\uA960-\uA97C\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFAFF\uFE10-\uFE19\uFE30-\uFE52\uFE54-\uFE66\uFE68-\uFE6B\uFF01-\uFF60\uFFE0-\uFFE6]/g,u=function(e,n,r,o,u){if(n)return i.showInvisibles?""+s.stringRepeat(i.SPACE_CHAR,e.length)+"":e;if(e=="&")return"&";if(e=="<")return"<";if(e==">")return">";if(e==" "){var a=i.session.getScreenTabSize(t+o);return t+=a-1,i.$tabStrings[a]}if(e=="\u3000"){var f=i.showInvisibles?"ace_cjk ace_invisible ace_invisible_space":"ace_cjk",l=i.showInvisibles?i.SPACE_CHAR:"";return t+=1,""+l+""}return r?""+i.SPACE_CHAR+"":(t+=1,""+e+"")},a=r.replace(o,u);if(!this.$textToken[n.type]){var f="ace_"+n.type.replace(/\./g," ace_"),l="";n.type=="fold"&&(l=" style='width:"+n.value.length*this.config.characterWidth+"px;' "),e.push("",a,"")}else e.push(a);return t+r.length},this.renderIndentGuide=function(e,t,n){var r=t.search(this.$indentGuideRe);return r<=0||r>=n?t:t[0]==" "?(r-=r%this.tabSize,e.push(s.stringRepeat(this.$tabStrings[" "],r/this.tabSize)),t.substr(r)):t[0]==" "?(e.push(s.stringRepeat(this.$tabStrings[" "],r)),t.substr(r)):t},this.$renderWrappedLine=function(e,t,n,r){var i=0,o=0,u=n[0],a=0;for(var f=0;f=u)a=this.$renderToken(e,a,l,c.substring(0,u-i)),c=c.substring(u-i),i=u,r||e.push("","
"),e.push(s.stringRepeat("\u00a0",n.indent)),o++,a=0,u=n[o]||Number.MAX_VALUE;c.length!=0&&(i+=c.length,a=this.$renderToken(e,a,l,c))}}},this.$renderSimpleLine=function(e,t){var n=0,r=t[0],i=r.value;this.displayIndentGuides&&(i=this.renderIndentGuide(e,i)),i&&(n=this.$renderToken(e,n,r,i));for(var s=1;s");if(i.length){var s=this.session.getRowSplitData(t);s&&s.length?this.$renderWrappedLine(e,i,s,n):this.$renderSimpleLine(e,i)}this.showInvisibles&&(r&&(t=r.end.row),e.push("",t==this.session.getLength()-1?this.EOF_CHAR:this.EOL_CHAR,"")),n||e.push("
")},this.$getFoldLineTokens=function(e,t){function i(e,t,n){var i=0,s=0;while(s+e[i].value.lengthn-t&&(o=o.substring(0,n-t)),r.push({type:e[i].type,value:o}),s=t+o.length,i+=1}while(sn?r.push({type:e[i].type,value:o.substring(0,n-s)}):r.push(e[i]),s+=o.length,i+=1}}var n=this.session,r=[],s=n.getTokens(e);return t.walk(function(e,t,o,u,a){e!=null?r.push({type:"fold",value:e}):(a&&(s=n.getTokens(t)),s.length&&i(s,u,o))},t.end.row,this.session.getLine(t.end.row).length),r},this.$useLineGroups=function(){return this.session.getUseWrapMode()},this.destroy=function(){clearInterval(this.$pollSizeChangesTimer),this.$measureNode&&this.$measureNode.parentNode.removeChild(this.$measureNode),delete this.$measureNode}}).call(a.prototype),t.Text=a}),define("ace/layer/cursor",["require","exports","module","ace/lib/dom"],function(e,t,n){"use strict";var r=e("../lib/dom"),i,s=function(e){this.element=r.createElement("div"),this.element.className="ace_layer ace_cursor-layer",e.appendChild(this.element),i===undefined&&(i=!("opacity"in this.element.style)),this.isVisible=!1,this.isBlinking=!0,this.blinkInterval=1e3,this.smoothBlinking=!1,this.cursors=[],this.cursor=this.addCursor(),r.addCssClass(this.element,"ace_hidden-cursors"),this.$updateCursors=(i?this.$updateVisibility:this.$updateOpacity).bind(this)};(function(){this.$updateVisibility=function(e){var t=this.cursors;for(var n=t.length;n--;)t[n].style.visibility=e?"":"hidden"},this.$updateOpacity=function(e){var t=this.cursors;for(var n=t.length;n--;)t[n].style.opacity=e?"":"0"},this.$padding=0,this.setPadding=function(e){this.$padding=e},this.setSession=function(e){this.session=e},this.setBlinking=function(e){e!=this.isBlinking&&(this.isBlinking=e,this.restartTimer())},this.setBlinkInterval=function(e){e!=this.blinkInterval&&(this.blinkInterval=e,this.restartTimer())},this.setSmoothBlinking=function(e){e!=this.smoothBlinking&&!i&&(this.smoothBlinking=e,r.setCssClass(this.element,"ace_smooth-blinking",e),this.$updateCursors(!0),this.$updateCursors=this.$updateOpacity.bind(this),this.restartTimer())},this.addCursor=function(){var e=r.createElement("div");return e.className="ace_cursor",this.element.appendChild(e),this.cursors.push(e),e},this.removeCursor=function(){if(this.cursors.length>1){var e=this.cursors.pop();return e.parentNode.removeChild(e),e}},this.hideCursor=function(){this.isVisible=!1,r.addCssClass(this.element,"ace_hidden-cursors"),this.restartTimer()},this.showCursor=function(){this.isVisible=!0,r.removeCssClass(this.element,"ace_hidden-cursors"),this.restartTimer()},this.restartTimer=function(){var e=this.$updateCursors;clearInterval(this.intervalId),clearTimeout(this.timeoutId),this.smoothBlinking&&r.removeCssClass(this.element,"ace_smooth-blinking"),e(!0);if(!this.isBlinking||!this.blinkInterval||!this.isVisible)return;this.smoothBlinking&&setTimeout(function(){r.addCssClass(this.element,"ace_smooth-blinking")}.bind(this));var t=function(){this.timeoutId=setTimeout(function(){e(!1)},.6*this.blinkInterval)}.bind(this);this.intervalId=setInterval(function(){e(!0),t()},this.blinkInterval),t()},this.getPixelPosition=function(e,t){if(!this.config||!this.session)return{left:0,top:0};e||(e=this.session.selection.getCursor());var n=this.session.documentToScreenPosition(e),r=this.$padding+n.column*this.config.characterWidth,i=(n.row-(t?this.config.firstRowScreen:0))*this.config.lineHeight;return{left:r,top:i}},this.update=function(e){this.config=e;var t=this.session.$selectionMarkers,n=0,r=0;if(t===undefined||t.length===0)t=[{cursor:null}];for(var n=0,i=t.length;ne.height+e.offset||s.top<0)&&n>1)continue;var o=(this.cursors[r++]||this.addCursor()).style;this.drawCursor?this.drawCursor(o,s,e,t[n],this.session):(o.left=s.left+"px",o.top=s.top+"px",o.width=e.characterWidth+"px",o.height=e.lineHeight+"px")}while(this.cursors.length>r)this.removeCursor();var u=this.session.getOverwrite();this.$setOverwrite(u),this.$pixelPos=s,this.restartTimer()},this.drawCursor=null,this.$setOverwrite=function(e){e!=this.overwrite&&(this.overwrite=e,e?r.addCssClass(this.element,"ace_overwrite-cursors"):r.removeCssClass(this.element,"ace_overwrite-cursors"))},this.destroy=function(){clearInterval(this.intervalId),clearTimeout(this.timeoutId)}}).call(s.prototype),t.Cursor=s}),define("ace/scrollbar",["require","exports","module","ace/lib/oop","ace/lib/dom","ace/lib/event","ace/lib/event_emitter"],function(e,t,n){"use strict";var r=e("./lib/oop"),i=e("./lib/dom"),s=e("./lib/event"),o=e("./lib/event_emitter").EventEmitter,u=32768,a=function(e){this.element=i.createElement("div"),this.element.className="ace_scrollbar ace_scrollbar"+this.classSuffix,this.inner=i.createElement("div"),this.inner.className="ace_scrollbar-inner",this.element.appendChild(this.inner),e.appendChild(this.element),this.setVisible(!1),this.skipEvent=!1,s.addListener(this.element,"scroll",this.onScroll.bind(this)),s.addListener(this.element,"mousedown",s.preventDefault)};(function(){r.implement(this,o),this.setVisible=function(e){this.element.style.display=e?"":"none",this.isVisible=e,this.coeff=1}}).call(a.prototype);var f=function(e,t){a.call(this,e),this.scrollTop=0,this.scrollHeight=0,t.$scrollbarWidth=this.width=i.scrollbarWidth(e.ownerDocument),this.inner.style.width=this.element.style.width=(this.width||15)+5+"px"};r.inherits(f,a),function(){this.classSuffix="-v",this.onScroll=function(){if(!this.skipEvent){this.scrollTop=this.element.scrollTop;if(this.coeff!=1){var e=this.element.clientHeight/this.scrollHeight;this.scrollTop=this.scrollTop*(1-e)/(this.coeff-e)}this._emit("scroll",{data:this.scrollTop})}this.skipEvent=!1},this.getWidth=function(){return this.isVisible?this.width:0},this.setHeight=function(e){this.element.style.height=e+"px"},this.setInnerHeight=this.setScrollHeight=function(e){this.scrollHeight=e,e>u?(this.coeff=u/e,e=u):this.coeff!=1&&(this.coeff=1),this.inner.style.height=e+"px"},this.setScrollTop=function(e){this.scrollTop!=e&&(this.skipEvent=!0,this.scrollTop=e,this.element.scrollTop=e*this.coeff)}}.call(f.prototype);var l=function(e,t){a.call(this,e),this.scrollLeft=0,this.height=t.$scrollbarWidth,this.inner.style.height=this.element.style.height=(this.height||15)+5+"px"};r.inherits(l,a),function(){this.classSuffix="-h",this.onScroll=function(){this.skipEvent||(this.scrollLeft=this.element.scrollLeft,this._emit("scroll",{data:this.scrollLeft})),this.skipEvent=!1},this.getHeight=function(){return this.isVisible?this.height:0},this.setWidth=function(e){this.element.style.width=e+"px"},this.setInnerWidth=function(e){this.inner.style.width=e+"px"},this.setScrollWidth=function(e){this.inner.style.width=e+"px"},this.setScrollLeft=function(e){this.scrollLeft!=e&&(this.skipEvent=!0,this.scrollLeft=this.element.scrollLeft=e)}}.call(l.prototype),t.ScrollBar=f,t.ScrollBarV=f,t.ScrollBarH=l,t.VScrollBar=f,t.HScrollBar=l}),define("ace/renderloop",["require","exports","module","ace/lib/event"],function(e,t,n){"use strict";var r=e("./lib/event"),i=function(e,t){this.onRender=e,this.pending=!1,this.changes=0,this.window=t||window};(function(){this.schedule=function(e){this.changes=this.changes|e;if(!this.pending&&this.changes){this.pending=!0;var t=this;r.nextFrame(function(){t.pending=!1;var e;while(e=t.changes)t.changes=0,t.onRender(e)},this.window)}}}).call(i.prototype),t.RenderLoop=i}),define("ace/layer/font_metrics",["require","exports","module","ace/lib/oop","ace/lib/dom","ace/lib/lang","ace/lib/useragent","ace/lib/event_emitter"],function(e,t,n){var r=e("../lib/oop"),i=e("../lib/dom"),s=e("../lib/lang"),o=e("../lib/useragent"),u=e("../lib/event_emitter").EventEmitter,a=0,f=t.FontMetrics=function(e){this.el=i.createElement("div"),this.$setMeasureNodeStyles(this.el.style,!0),this.$main=i.createElement("div"),this.$setMeasureNodeStyles(this.$main.style),this.$measureNode=i.createElement("div"),this.$setMeasureNodeStyles(this.$measureNode.style),this.el.appendChild(this.$main),this.el.appendChild(this.$measureNode),e.appendChild(this.el),a||this.$testFractionalRect(),this.$measureNode.innerHTML=s.stringRepeat("X",a),this.$characterSize={width:0,height:0},this.checkForSizeChanges()};(function(){r.implement(this,u),this.$characterSize={width:0,height:0},this.$testFractionalRect=function(){var e=i.createElement("div");this.$setMeasureNodeStyles(e.style),e.style.width="0.2px",document.documentElement.appendChild(e);var t=e.getBoundingClientRect().width;t>0&&t<1?a=50:a=100,e.parentNode.removeChild(e)},this.$setMeasureNodeStyles=function(e,t){e.width=e.height="auto",e.left=e.top="0px",e.visibility="hidden",e.position="absolute",e.whiteSpace="pre",o.isIE<8?e["font-family"]="inherit":e.font="inherit",e.overflow=t?"hidden":"visible"},this.checkForSizeChanges=function(){var e=this.$measureSizes();if(e&&(this.$characterSize.width!==e.width||this.$characterSize.height!==e.height)){this.$measureNode.style.fontWeight="bold";var t=this.$measureSizes();this.$measureNode.style.fontWeight="",this.$characterSize=e,this.charSizes=Object.create(null),this.allowBoldFonts=t&&t.width===e.width&&t.height===e.height,this._emit("changeCharacterSize",{data:e})}},this.$pollSizeChanges=function(){if(this.$pollSizeChangesTimer)return this.$pollSizeChangesTimer;var e=this;return this.$pollSizeChangesTimer=setInterval(function(){e.checkForSizeChanges()},500)},this.setPolling=function(e){e?this.$pollSizeChanges():this.$pollSizeChangesTimer&&(clearInterval(this.$pollSizeChangesTimer),this.$pollSizeChangesTimer=0)},this.$measureSizes=function(){if(a===50){var e=null;try{e=this.$measureNode.getBoundingClientRect()}catch(t){e={width:0,height:0}}var n={height:e.height,width:e.width/a}}else var n={height:this.$measureNode.clientHeight,width:this.$measureNode.clientWidth/a};return n.width===0||n.height===0?null:n},this.$measureCharWidth=function(e){this.$main.innerHTML=s.stringRepeat(e,a);var t=this.$main.getBoundingClientRect();return t.width/a},this.getCharacterWidth=function(e){var t=this.charSizes[e];return t===undefined&&(t=this.charSizes[e]=this.$measureCharWidth(e)/this.$characterSize.width),t},this.destroy=function(){clearInterval(this.$pollSizeChangesTimer),this.el&&this.el.parentNode&&this.el.parentNode.removeChild(this.el)}}).call(f.prototype)}),define("ace/virtual_renderer",["require","exports","module","ace/lib/oop","ace/lib/dom","ace/config","ace/lib/useragent","ace/layer/gutter","ace/layer/marker","ace/layer/text","ace/layer/cursor","ace/scrollbar","ace/scrollbar","ace/renderloop","ace/layer/font_metrics","ace/lib/event_emitter"],function(e,t,n){"use strict";var r=e("./lib/oop"),i=e("./lib/dom"),s=e("./config"),o=e("./lib/useragent"),u=e("./layer/gutter").Gutter,a=e("./layer/marker").Marker,f=e("./layer/text").Text,l=e("./layer/cursor").Cursor,c=e("./scrollbar").HScrollBar,h=e("./scrollbar").VScrollBar,p=e("./renderloop").RenderLoop,d=e("./layer/font_metrics").FontMetrics,v=e("./lib/event_emitter").EventEmitter,m='.ace_editor {position: relative;overflow: hidden;font: 12px/normal \'Monaco\', \'Menlo\', \'Ubuntu Mono\', \'Consolas\', \'source-code-pro\', monospace;direction: ltr;text-align: left;}.ace_scroller {position: absolute;overflow: hidden;top: 0;bottom: 0;background-color: inherit;-ms-user-select: none;-moz-user-select: none;-webkit-user-select: none;user-select: none;cursor: text;}.ace_content {position: absolute;-moz-box-sizing: border-box;-webkit-box-sizing: border-box;box-sizing: border-box;min-width: 100%;}.ace_dragging .ace_scroller:before{position: absolute;top: 0;left: 0;right: 0;bottom: 0;content: \'\';background: rgba(250, 250, 250, 0.01);z-index: 1000;}.ace_dragging.ace_dark .ace_scroller:before{background: rgba(0, 0, 0, 0.01);}.ace_selecting, .ace_selecting * {cursor: text !important;}.ace_gutter {position: absolute;overflow : hidden;width: auto;top: 0;bottom: 0;left: 0;cursor: default;z-index: 4;-ms-user-select: none;-moz-user-select: none;-webkit-user-select: none;user-select: none;}.ace_gutter-active-line {position: absolute;left: 0;right: 0;}.ace_scroller.ace_scroll-left {box-shadow: 17px 0 16px -16px rgba(0, 0, 0, 0.4) inset;}.ace_gutter-cell {padding-left: 19px;padding-right: 6px;background-repeat: no-repeat;}.ace_gutter-cell.ace_error {background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAABOFBMVEX/////////QRswFAb/Ui4wFAYwFAYwFAaWGAfDRymzOSH/PxswFAb/SiUwFAYwFAbUPRvjQiDllog5HhHdRybsTi3/Tyv9Tir+Syj/UC3////XurebMBIwFAb/RSHbPx/gUzfdwL3kzMivKBAwFAbbvbnhPx66NhowFAYwFAaZJg8wFAaxKBDZurf/RB6mMxb/SCMwFAYwFAbxQB3+RB4wFAb/Qhy4Oh+4QifbNRcwFAYwFAYwFAb/QRzdNhgwFAYwFAbav7v/Uy7oaE68MBK5LxLewr/r2NXewLswFAaxJw4wFAbkPRy2PyYwFAaxKhLm1tMwFAazPiQwFAaUGAb/QBrfOx3bvrv/VC/maE4wFAbRPBq6MRO8Qynew8Dp2tjfwb0wFAbx6eju5+by6uns4uH9/f36+vr/GkHjAAAAYnRSTlMAGt+64rnWu/bo8eAA4InH3+DwoN7j4eLi4xP99Nfg4+b+/u9B/eDs1MD1mO7+4PHg2MXa347g7vDizMLN4eG+Pv7i5evs/v79yu7S3/DV7/498Yv24eH+4ufQ3Ozu/v7+y13sRqwAAADLSURBVHjaZc/XDsFgGIBhtDrshlitmk2IrbHFqL2pvXf/+78DPokj7+Fz9qpU/9UXJIlhmPaTaQ6QPaz0mm+5gwkgovcV6GZzd5JtCQwgsxoHOvJO15kleRLAnMgHFIESUEPmawB9ngmelTtipwwfASilxOLyiV5UVUyVAfbG0cCPHig+GBkzAENHS0AstVF6bacZIOzgLmxsHbt2OecNgJC83JERmePUYq8ARGkJx6XtFsdddBQgZE2nPR6CICZhawjA4Fb/chv+399kfR+MMMDGOQAAAABJRU5ErkJggg==");background-repeat: no-repeat;background-position: 2px center;}.ace_gutter-cell.ace_warning {background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAmVBMVEX///8AAAD///8AAAAAAABPSzb/5sAAAAB/blH/73z/ulkAAAAAAAD85pkAAAAAAAACAgP/vGz/rkDerGbGrV7/pkQICAf////e0IsAAAD/oED/qTvhrnUAAAD/yHD/njcAAADuv2r/nz//oTj/p064oGf/zHAAAAA9Nir/tFIAAAD/tlTiuWf/tkIAAACynXEAAAAAAAAtIRW7zBpBAAAAM3RSTlMAABR1m7RXO8Ln31Z36zT+neXe5OzooRDfn+TZ4p3h2hTf4t3k3ucyrN1K5+Xaks52Sfs9CXgrAAAAjklEQVR42o3PbQ+CIBQFYEwboPhSYgoYunIqqLn6/z8uYdH8Vmdnu9vz4WwXgN/xTPRD2+sgOcZjsge/whXZgUaYYvT8QnuJaUrjrHUQreGczuEafQCO/SJTufTbroWsPgsllVhq3wJEk2jUSzX3CUEDJC84707djRc5MTAQxoLgupWRwW6UB5fS++NV8AbOZgnsC7BpEAAAAABJRU5ErkJggg==");background-position: 2px center;}.ace_gutter-cell.ace_info {background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAAAAAA6mKC9AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAAJ0Uk5TAAB2k804AAAAPklEQVQY02NgIB68QuO3tiLznjAwpKTgNyDbMegwisCHZUETUZV0ZqOquBpXj2rtnpSJT1AEnnRmL2OgGgAAIKkRQap2htgAAAAASUVORK5CYII=");background-position: 2px center;}.ace_dark .ace_gutter-cell.ace_info {background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAJFBMVEUAAAChoaGAgIAqKiq+vr6tra1ZWVmUlJSbm5s8PDxubm56enrdgzg3AAAAAXRSTlMAQObYZgAAAClJREFUeNpjYMAPdsMYHegyJZFQBlsUlMFVCWUYKkAZMxZAGdxlDMQBAG+TBP4B6RyJAAAAAElFTkSuQmCC");}.ace_scrollbar {position: absolute;right: 0;bottom: 0;z-index: 6;}.ace_scrollbar-inner {position: absolute;cursor: text;left: 0;top: 0;}.ace_scrollbar-v{overflow-x: hidden;overflow-y: scroll;top: 0;}.ace_scrollbar-h {overflow-x: scroll;overflow-y: hidden;left: 0;}.ace_print-margin {position: absolute;height: 100%;}.ace_text-input {position: absolute;z-index: 0;width: 0.5em;height: 1em;opacity: 0;background: transparent;-moz-appearance: none;appearance: none;border: none;resize: none;outline: none;overflow: hidden;font: inherit;padding: 0 1px;margin: 0 -1px;text-indent: -1em;-ms-user-select: text;-moz-user-select: text;-webkit-user-select: text;user-select: text;white-space: pre!important;}.ace_text-input.ace_composition {background: inherit;color: inherit;z-index: 1000;opacity: 1;text-indent: 0;}.ace_layer {z-index: 1;position: absolute;overflow: hidden;word-wrap: normal;white-space: pre;height: 100%;width: 100%;-moz-box-sizing: border-box;-webkit-box-sizing: border-box;box-sizing: border-box;pointer-events: none;}.ace_gutter-layer {position: relative;width: auto;text-align: right;pointer-events: auto;}.ace_text-layer {font: inherit !important;}.ace_cjk {display: inline-block;text-align: center;}.ace_cursor-layer {z-index: 4;}.ace_cursor {z-index: 4;position: absolute;-moz-box-sizing: border-box;-webkit-box-sizing: border-box;box-sizing: border-box;border-left: 2px solid;transform: translatez(0);}.ace_slim-cursors .ace_cursor {border-left-width: 1px;}.ace_overwrite-cursors .ace_cursor {border-left-width: 0;border-bottom: 1px solid;}.ace_hidden-cursors .ace_cursor {opacity: 0.2;}.ace_smooth-blinking .ace_cursor {-webkit-transition: opacity 0.18s;transition: opacity 0.18s;}.ace_editor.ace_multiselect .ace_cursor {border-left-width: 1px;}.ace_marker-layer .ace_step, .ace_marker-layer .ace_stack {position: absolute;z-index: 3;}.ace_marker-layer .ace_selection {position: absolute;z-index: 5;}.ace_marker-layer .ace_bracket {position: absolute;z-index: 6;}.ace_marker-layer .ace_active-line {position: absolute;z-index: 2;}.ace_marker-layer .ace_selected-word {position: absolute;z-index: 4;-moz-box-sizing: border-box;-webkit-box-sizing: border-box;box-sizing: border-box;}.ace_line .ace_fold {-moz-box-sizing: border-box;-webkit-box-sizing: border-box;box-sizing: border-box;display: inline-block;height: 11px;margin-top: -2px;vertical-align: middle;background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABEAAAAJCAYAAADU6McMAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAJpJREFUeNpi/P//PwOlgAXGYGRklAVSokD8GmjwY1wasKljQpYACtpCFeADcHVQfQyMQAwzwAZI3wJKvCLkfKBaMSClBlR7BOQikCFGQEErIH0VqkabiGCAqwUadAzZJRxQr/0gwiXIal8zQQPnNVTgJ1TdawL0T5gBIP1MUJNhBv2HKoQHHjqNrA4WO4zY0glyNKLT2KIfIMAAQsdgGiXvgnYAAAAASUVORK5CYII="),url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAA3CAYAAADNNiA5AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAACJJREFUeNpi+P//fxgTAwPDBxDxD078RSX+YeEyDFMCIMAAI3INmXiwf2YAAAAASUVORK5CYII=");background-repeat: no-repeat, repeat-x;background-position: center center, top left;color: transparent;border: 1px solid black;border-radius: 2px;cursor: pointer;pointer-events: auto;}.ace_dark .ace_fold {}.ace_fold:hover{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABEAAAAJCAYAAADU6McMAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAJpJREFUeNpi/P//PwOlgAXGYGRklAVSokD8GmjwY1wasKljQpYACtpCFeADcHVQfQyMQAwzwAZI3wJKvCLkfKBaMSClBlR7BOQikCFGQEErIH0VqkabiGCAqwUadAzZJRxQr/0gwiXIal8zQQPnNVTgJ1TdawL0T5gBIP1MUJNhBv2HKoQHHjqNrA4WO4zY0glyNKLT2KIfIMAAQsdgGiXvgnYAAAAASUVORK5CYII="),url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAA3CAYAAADNNiA5AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAACBJREFUeNpi+P//fz4TAwPDZxDxD5X4i5fLMEwJgAADAEPVDbjNw87ZAAAAAElFTkSuQmCC");}.ace_tooltip {background-color: #FFF;background-image: -webkit-linear-gradient(top, transparent, rgba(0, 0, 0, 0.1));background-image: linear-gradient(to bottom, transparent, rgba(0, 0, 0, 0.1));border: 1px solid gray;border-radius: 1px;box-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);color: black;max-width: 100%;padding: 3px 4px;position: fixed;z-index: 999999;-moz-box-sizing: border-box;-webkit-box-sizing: border-box;box-sizing: border-box;cursor: default;white-space: pre;word-wrap: break-word;line-height: normal;font-style: normal;font-weight: normal;letter-spacing: normal;pointer-events: none;}.ace_folding-enabled > .ace_gutter-cell {padding-right: 13px;}.ace_fold-widget {-moz-box-sizing: border-box;-webkit-box-sizing: border-box;box-sizing: border-box;margin: 0 -12px 0 1px;display: none;width: 11px;vertical-align: top;background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAANElEQVR42mWKsQ0AMAzC8ixLlrzQjzmBiEjp0A6WwBCSPgKAXoLkqSot7nN3yMwR7pZ32NzpKkVoDBUxKAAAAABJRU5ErkJggg==");background-repeat: no-repeat;background-position: center;border-radius: 3px;border: 1px solid transparent;cursor: pointer;}.ace_folding-enabled .ace_fold-widget {display: inline-block; }.ace_fold-widget.ace_end {background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAANElEQVR42m3HwQkAMAhD0YzsRchFKI7sAikeWkrxwScEB0nh5e7KTPWimZki4tYfVbX+MNl4pyZXejUO1QAAAABJRU5ErkJggg==");}.ace_fold-widget.ace_closed {background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAGCAYAAAAG5SQMAAAAOUlEQVR42jXKwQkAMAgDwKwqKD4EwQ26sSOkVWjgIIHAzPiCgaqiqnJHZnKICBERHN194O5b9vbLuAVRL+l0YWnZAAAAAElFTkSuQmCCXA==");}.ace_fold-widget:hover {border: 1px solid rgba(0, 0, 0, 0.3);background-color: rgba(255, 255, 255, 0.2);box-shadow: 0 1px 1px rgba(255, 255, 255, 0.7);}.ace_fold-widget:active {border: 1px solid rgba(0, 0, 0, 0.4);background-color: rgba(0, 0, 0, 0.05);box-shadow: 0 1px 1px rgba(255, 255, 255, 0.8);}.ace_dark .ace_fold-widget {background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHklEQVQIW2P4//8/AzoGEQ7oGCaLLAhWiSwB146BAQCSTPYocqT0AAAAAElFTkSuQmCC");}.ace_dark .ace_fold-widget.ace_end {background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAH0lEQVQIW2P4//8/AxQ7wNjIAjDMgC4AxjCVKBirIAAF0kz2rlhxpAAAAABJRU5ErkJggg==");}.ace_dark .ace_fold-widget.ace_closed {background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAFCAYAAACAcVaiAAAAHElEQVQIW2P4//+/AxAzgDADlOOAznHAKgPWAwARji8UIDTfQQAAAABJRU5ErkJggg==");}.ace_dark .ace_fold-widget:hover {box-shadow: 0 1px 1px rgba(255, 255, 255, 0.2);background-color: rgba(255, 255, 255, 0.1);}.ace_dark .ace_fold-widget:active {box-shadow: 0 1px 1px rgba(255, 255, 255, 0.2);}.ace_fold-widget.ace_invalid {background-color: #FFB4B4;border-color: #DE5555;}.ace_fade-fold-widgets .ace_fold-widget {-webkit-transition: opacity 0.4s ease 0.05s;transition: opacity 0.4s ease 0.05s;opacity: 0;}.ace_fade-fold-widgets:hover .ace_fold-widget {-webkit-transition: opacity 0.05s ease 0.05s;transition: opacity 0.05s ease 0.05s;opacity:1;}.ace_underline {text-decoration: underline;}.ace_bold {font-weight: bold;}.ace_nobold .ace_bold {font-weight: normal;}.ace_italic {font-style: italic;}.ace_error-marker {background-color: rgba(255, 0, 0,0.2);position: absolute;z-index: 9;}.ace_highlight-marker {background-color: rgba(255, 255, 0,0.2);position: absolute;z-index: 8;}.ace_br1 {border-top-left-radius : 3px;}.ace_br2 {border-top-right-radius : 3px;}.ace_br3 {border-top-left-radius : 3px; border-top-right-radius: 3px;}.ace_br4 {border-bottom-right-radius: 3px;}.ace_br5 {border-top-left-radius : 3px; border-bottom-right-radius: 3px;}.ace_br6 {border-top-right-radius : 3px; border-bottom-right-radius: 3px;}.ace_br7 {border-top-left-radius : 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px;}.ace_br8 {border-bottom-left-radius : 3px;}.ace_br9 {border-top-left-radius : 3px; border-bottom-left-radius: 3px;}.ace_br10{border-top-right-radius : 3px; border-bottom-left-radius: 3px;}.ace_br11{border-top-left-radius : 3px; border-top-right-radius: 3px; border-bottom-left-radius: 3px;}.ace_br12{border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;}.ace_br13{border-top-left-radius : 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;}.ace_br14{border-top-right-radius : 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;}.ace_br15{border-top-left-radius : 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;}';i.importCssString(m,"ace_editor.css");var g=function(e,t){var n=this;this.container=e||i.createElement("div"),this.$keepTextAreaAtCursor=!o.isOldIE,i.addCssClass(this.container,"ace_editor"),this.setTheme(t),this.$gutter=i.createElement("div"),this.$gutter.className="ace_gutter",this.container.appendChild(this.$gutter),this.scroller=i.createElement("div"),this.scroller.className="ace_scroller",this.container.appendChild(this.scroller),this.content=i.createElement("div"),this.content.className="ace_content",this.scroller.appendChild(this.content),this.$gutterLayer=new u(this.$gutter),this.$gutterLayer.on("changeGutterWidth",this.onGutterResize.bind(this)),this.$markerBack=new a(this.content);var r=this.$textLayer=new f(this.content);this.canvas=r.element,this.$markerFront=new a(this.content),this.$cursorLayer=new l(this.content),this.$horizScroll=!1,this.$vScroll=!1,this.scrollBar=this.scrollBarV=new h(this.container,this),this.scrollBarH=new c(this.container,this),this.scrollBarV.addEventListener("scroll",function(e){n.$scrollAnimation||n.session.setScrollTop(e.data-n.scrollMargin.top)}),this.scrollBarH.addEventListener("scroll",function(e){n.$scrollAnimation||n.session.setScrollLeft(e.data-n.scrollMargin.left)}),this.scrollTop=0,this.scrollLeft=0,this.cursorPos={row:0,column:0},this.$fontMetrics=new d(this.container),this.$textLayer.$setFontMetrics(this.$fontMetrics),this.$textLayer.addEventListener("changeCharacterSize",function(e){n.updateCharacterSize(),n.onResize(!0,n.gutterWidth,n.$size.width,n.$size.height),n._signal("changeCharacterSize",e)}),this.$size={width:0,height:0,scrollerHeight:0,scrollerWidth:0,$dirty:!0},this.layerConfig={width:1,padding:0,firstRow:0,firstRowScreen:0,lastRow:0,lineHeight:0,characterWidth:0,minHeight:1,maxHeight:1,offset:0,height:1,gutterOffset:1},this.scrollMargin={left:0,right:0,top:0,bottom:0,v:0,h:0},this.$loop=new p(this.$renderChanges.bind(this),this.container.ownerDocument.defaultView),this.$loop.schedule(this.CHANGE_FULL),this.updateCharacterSize(),this.setPadding(4),s.resetOptions(this),s._emit("renderer",this)};(function(){this.CHANGE_CURSOR=1,this.CHANGE_MARKER=2,this.CHANGE_GUTTER=4,this.CHANGE_SCROLL=8,this.CHANGE_LINES=16,this.CHANGE_TEXT=32,this.CHANGE_SIZE=64,this.CHANGE_MARKER_BACK=128,this.CHANGE_MARKER_FRONT=256,this.CHANGE_FULL=512,this.CHANGE_H_SCROLL=1024,r.implement(this,v),this.updateCharacterSize=function(){this.$textLayer.allowBoldFonts!=this.$allowBoldFonts&&(this.$allowBoldFonts=this.$textLayer.allowBoldFonts,this.setStyle("ace_nobold",!this.$allowBoldFonts)),this.layerConfig.characterWidth=this.characterWidth=this.$textLayer.getCharacterWidth(),this.layerConfig.lineHeight=this.lineHeight=this.$textLayer.getLineHeight(),this.$updatePrintMargin()},this.setSession=function(e){this.session&&this.session.doc.off("changeNewLineMode",this.onChangeNewLineMode),this.session=e,e&&this.scrollMargin.top&&e.getScrollTop()<=0&&e.setScrollTop(-this.scrollMargin.top),this.$cursorLayer.setSession(e),this.$markerBack.setSession(e),this.$markerFront.setSession(e),this.$gutterLayer.setSession(e),this.$textLayer.setSession(e);if(!e)return;this.$loop.schedule(this.CHANGE_FULL),this.session.$setFontMetrics(this.$fontMetrics),this.scrollBarV.scrollLeft=this.scrollBarV.scrollTop=null,this.onChangeNewLineMode=this.onChangeNewLineMode.bind(this),this.onChangeNewLineMode(),this.session.doc.on("changeNewLineMode",this.onChangeNewLineMode)},this.updateLines=function(e,t,n){t===undefined&&(t=Infinity),this.$changedLines?(this.$changedLines.firstRow>e&&(this.$changedLines.firstRow=e),this.$changedLines.lastRowthis.layerConfig.lastRow)return;this.$loop.schedule(this.CHANGE_LINES)},this.onChangeNewLineMode=function(){this.$loop.schedule(this.CHANGE_TEXT),this.$textLayer.$updateEolChar()},this.onChangeTabSize=function(){this.$loop.schedule(this.CHANGE_TEXT|this.CHANGE_MARKER),this.$textLayer.onChangeTabSize()},this.updateText=function(){this.$loop.schedule(this.CHANGE_TEXT)},this.updateFull=function(e){e?this.$renderChanges(this.CHANGE_FULL,!0):this.$loop.schedule(this.CHANGE_FULL)},this.updateFontSize=function(){this.$textLayer.checkForSizeChanges()},this.$changes=0,this.$updateSizeAsync=function(){this.$loop.pending?this.$size.$dirty=!0:this.onResize()},this.onResize=function(e,t,n,r){if(this.resizing>2)return;this.resizing>0?this.resizing++:this.resizing=e?1:0;var i=this.container;r||(r=i.clientHeight||i.scrollHeight),n||(n=i.clientWidth||i.scrollWidth);var s=this.$updateCachedSize(e,t,n,r);if(!this.$size.scrollerHeight||!n&&!r)return this.resizing=0;e&&(this.$gutterLayer.$padding=null),e?this.$renderChanges(s|this.$changes,!0):this.$loop.schedule(s|this.$changes),this.resizing&&(this.resizing=0),this.scrollBarV.scrollLeft=this.scrollBarV.scrollTop=null},this.$updateCachedSize=function(e,t,n,r){r-=this.$extraHeight||0;var i=0,s=this.$size,o={width:s.width,height:s.height,scrollerHeight:s.scrollerHeight,scrollerWidth:s.scrollerWidth};r&&(e||s.height!=r)&&(s.height=r,i|=this.CHANGE_SIZE,s.scrollerHeight=s.height,this.$horizScroll&&(s.scrollerHeight-=this.scrollBarH.getHeight()),this.scrollBarV.element.style.bottom=this.scrollBarH.getHeight()+"px",i|=this.CHANGE_SCROLL);if(n&&(e||s.width!=n)){i|=this.CHANGE_SIZE,s.width=n,t==null&&(t=this.$showGutter?this.$gutter.offsetWidth:0),this.gutterWidth=t,this.scrollBarH.element.style.left=this.scroller.style.left=t+"px",s.scrollerWidth=Math.max(0,n-t-this.scrollBarV.getWidth()),this.scrollBarH.element.style.right=this.scroller.style.right=this.scrollBarV.getWidth()+"px",this.scroller.style.bottom=this.scrollBarH.getHeight()+"px";if(this.session&&this.session.getUseWrapMode()&&this.adjustWrapLimit()||e)i|=this.CHANGE_FULL}return s.$dirty=!n||!r,i&&this._signal("resize",o),i},this.onGutterResize=function(){var e=this.$showGutter?this.$gutter.offsetWidth:0;e!=this.gutterWidth&&(this.$changes|=this.$updateCachedSize(!0,e,this.$size.width,this.$size.height)),this.session.getUseWrapMode()&&this.adjustWrapLimit()?this.$loop.schedule(this.CHANGE_FULL):this.$size.$dirty?this.$loop.schedule(this.CHANGE_FULL):(this.$computeLayerConfig(),this.$loop.schedule(this.CHANGE_MARKER))},this.adjustWrapLimit=function(){var e=this.$size.scrollerWidth-this.$padding*2,t=Math.floor(e/this.characterWidth);return this.session.adjustWrapLimit(t,this.$showPrintMargin&&this.$printMarginColumn)},this.setAnimatedScroll=function(e){this.setOption("animatedScroll",e)},this.getAnimatedScroll=function(){return this.$animatedScroll},this.setShowInvisibles=function(e){this.setOption("showInvisibles",e)},this.getShowInvisibles=function(){return this.getOption("showInvisibles")},this.getDisplayIndentGuides=function(){return this.getOption("displayIndentGuides")},this.setDisplayIndentGuides=function(e){this.setOption("displayIndentGuides",e)},this.setShowPrintMargin=function(e){this.setOption("showPrintMargin",e)},this.getShowPrintMargin=function(){return this.getOption("showPrintMargin")},this.setPrintMarginColumn=function(e){this.setOption("printMarginColumn",e)},this.getPrintMarginColumn=function(){return this.getOption("printMarginColumn")},this.getShowGutter=function(){return this.getOption("showGutter")},this.setShowGutter=function(e){return this.setOption("showGutter",e)},this.getFadeFoldWidgets=function(){return this.getOption("fadeFoldWidgets")},this.setFadeFoldWidgets=function(e){this.setOption("fadeFoldWidgets",e)},this.setHighlightGutterLine=function(e){this.setOption("highlightGutterLine",e)},this.getHighlightGutterLine=function(){return this.getOption("highlightGutterLine")},this.$updateGutterLineHighlight=function(){var e=this.$cursorLayer.$pixelPos,t=this.layerConfig.lineHeight;if(this.session.getUseWrapMode()){var n=this.session.selection.getCursor();n.column=0,e=this.$cursorLayer.getPixelPosition(n,!0),t*=this.session.getRowLength(n.row)}this.$gutterLineHighlight.style.top=e.top-this.layerConfig.offset+"px",this.$gutterLineHighlight.style.height=t+"px"},this.$updatePrintMargin=function(){if(!this.$showPrintMargin&&!this.$printMarginEl)return;if(!this.$printMarginEl){var e=i.createElement("div");e.className="ace_layer ace_print-margin-layer",this.$printMarginEl=i.createElement("div"),this.$printMarginEl.className="ace_print-margin",e.appendChild(this.$printMarginEl),this.content.insertBefore(e,this.content.firstChild)}var t=this.$printMarginEl.style;t.left=this.characterWidth*this.$printMarginColumn+this.$padding+"px",t.visibility=this.$showPrintMargin?"visible":"hidden",this.session&&this.session.$wrap==-1&&this.adjustWrapLimit()},this.getContainerElement=function(){return this.container},this.getMouseEventTarget=function(){return this.scroller},this.getTextAreaContainer=function(){return this.container},this.$moveTextAreaToCursor=function(){if(!this.$keepTextAreaAtCursor)return;var e=this.layerConfig,t=this.$cursorLayer.$pixelPos.top,n=this.$cursorLayer.$pixelPos.left;t-=e.offset;var r=this.textarea.style,i=this.lineHeight;if(t<0||t>e.height-i){r.top=r.left="0";return}var s=this.characterWidth;if(this.$composition){var o=this.textarea.value.replace(/^\x01+/,"");s*=this.session.$getStringScreenWidth(o)[0]+2,i+=2}n-=this.scrollLeft,n>this.$size.scrollerWidth-s&&(n=this.$size.scrollerWidth-s),n+=this.gutterWidth,r.height=i+"px",r.width=s+"px",r.left=Math.min(n,this.$size.scrollerWidth-s)+"px",r.top=Math.min(t,this.$size.height-i)+"px"},this.getFirstVisibleRow=function(){return this.layerConfig.firstRow},this.getFirstFullyVisibleRow=function(){return this.layerConfig.firstRow+(this.layerConfig.offset===0?0:1)},this.getLastFullyVisibleRow=function(){var e=this.layerConfig,t=e.lastRow,n=this.session.documentToScreenRow(t,0)*e.lineHeight;return n-this.session.getScrollTop()>e.height-e.lineHeight?t-1:t},this.getLastVisibleRow=function(){return this.layerConfig.lastRow},this.$padding=null,this.setPadding=function(e){this.$padding=e,this.$textLayer.setPadding(e),this.$cursorLayer.setPadding(e),this.$markerFront.setPadding(e),this.$markerBack.setPadding(e),this.$loop.schedule(this.CHANGE_FULL),this.$updatePrintMargin()},this.setScrollMargin=function(e,t,n,r){var i=this.scrollMargin;i.top=e|0,i.bottom=t|0,i.right=r|0,i.left=n|0,i.v=i.top+i.bottom,i.h=i.left+i.right,i.top&&this.scrollTop<=0&&this.session&&this.session.setScrollTop(-i.top),this.updateFull()},this.getHScrollBarAlwaysVisible=function(){return this.$hScrollBarAlwaysVisible},this.setHScrollBarAlwaysVisible=function(e){this.setOption("hScrollBarAlwaysVisible",e)},this.getVScrollBarAlwaysVisible=function(){return this.$vScrollBarAlwaysVisible},this.setVScrollBarAlwaysVisible=function(e){this.setOption("vScrollBarAlwaysVisible",e)},this.$updateScrollBarV=function(){var e=this.layerConfig.maxHeight,t=this.$size.scrollerHeight;!this.$maxLines&&this.$scrollPastEnd&&(e-=(t-this.lineHeight)*this.$scrollPastEnd,this.scrollTop>e-t&&(e=this.scrollTop+t,this.scrollBarV.scrollTop=null)),this.scrollBarV.setScrollHeight(e+this.scrollMargin.v),this.scrollBarV.setScrollTop(this.scrollTop+this.scrollMargin.top)},this.$updateScrollBarH=function(){this.scrollBarH.setScrollWidth(this.layerConfig.width+2*this.$padding+this.scrollMargin.h),this.scrollBarH.setScrollLeft(this.scrollLeft+this.scrollMargin.left)},this.$frozen=!1,this.freeze=function(){this.$frozen=!0},this.unfreeze=function(){this.$frozen=!1},this.$renderChanges=function(e,t){this.$changes&&(e|=this.$changes,this.$changes=0);if(!this.session||!this.container.offsetWidth||this.$frozen||!e&&!t){this.$changes|=e;return}if(this.$size.$dirty)return this.$changes|=e,this.onResize(!0);this.lineHeight||this.$textLayer.checkForSizeChanges(),this._signal("beforeRender");var n=this.layerConfig;if(e&this.CHANGE_FULL||e&this.CHANGE_SIZE||e&this.CHANGE_TEXT||e&this.CHANGE_LINES||e&this.CHANGE_SCROLL||e&this.CHANGE_H_SCROLL){e|=this.$computeLayerConfig();if(n.firstRow!=this.layerConfig.firstRow&&n.firstRowScreen==this.layerConfig.firstRowScreen){var r=this.scrollTop+(n.firstRow-this.layerConfig.firstRow)*this.lineHeight;r>0&&(this.scrollTop=r,e|=this.CHANGE_SCROLL,e|=this.$computeLayerConfig())}n=this.layerConfig,this.$updateScrollBarV(),e&this.CHANGE_H_SCROLL&&this.$updateScrollBarH(),this.$gutterLayer.element.style.marginTop=-n.offset+"px",this.content.style.marginTop=-n.offset+"px",this.content.style.width=n.width+2*this.$padding+"px",this.content.style.height=n.minHeight+"px"}e&this.CHANGE_H_SCROLL&&(this.content.style.marginLeft=-this.scrollLeft+"px",this.scroller.className=this.scrollLeft<=0?"ace_scroller":"ace_scroller ace_scroll-left");if(e&this.CHANGE_FULL){this.$textLayer.update(n),this.$showGutter&&this.$gutterLayer.update(n),this.$markerBack.update(n),this.$markerFront.update(n),this.$cursorLayer.update(n),this.$moveTextAreaToCursor(),this.$highlightGutterLine&&this.$updateGutterLineHighlight(),this._signal("afterRender");return}if(e&this.CHANGE_SCROLL){e&this.CHANGE_TEXT||e&this.CHANGE_LINES?this.$textLayer.update(n):this.$textLayer.scrollLines(n),this.$showGutter&&this.$gutterLayer.update(n),this.$markerBack.update(n),this.$markerFront.update(n),this.$cursorLayer.update(n),this.$highlightGutterLine&&this.$updateGutterLineHighlight(),this.$moveTextAreaToCursor(),this._signal("afterRender");return}e&this.CHANGE_TEXT?(this.$textLayer.update(n),this.$showGutter&&this.$gutterLayer.update(n)):e&this.CHANGE_LINES?(this.$updateLines()||e&this.CHANGE_GUTTER&&this.$showGutter)&&this.$gutterLayer.update(n):(e&this.CHANGE_TEXT||e&this.CHANGE_GUTTER)&&this.$showGutter&&this.$gutterLayer.update(n),e&this.CHANGE_CURSOR&&(this.$cursorLayer.update(n),this.$moveTextAreaToCursor(),this.$highlightGutterLine&&this.$updateGutterLineHighlight()),e&(this.CHANGE_MARKER|this.CHANGE_MARKER_FRONT)&&this.$markerFront.update(n),e&(this.CHANGE_MARKER|this.CHANGE_MARKER_BACK)&&this.$markerBack.update(n),this._signal("afterRender")},this.$autosize=function(){var e=this.session.getScreenLength()*this.lineHeight,t=this.$maxLines*this.lineHeight,n=Math.min(t,Math.max((this.$minLines||1)*this.lineHeight,e))+this.scrollMargin.v+(this.$extraHeight||0);this.$horizScroll&&(n+=this.scrollBarH.getHeight()),this.$maxPixelHeight&&n>this.$maxPixelHeight&&(n=this.$maxPixelHeight);var r=e>t;if(n!=this.desiredHeight||this.$size.height!=this.desiredHeight||r!=this.$vScroll){r!=this.$vScroll&&(this.$vScroll=r,this.scrollBarV.setVisible(r));var i=this.container.clientWidth;this.container.style.height=n+"px",this.$updateCachedSize(!0,this.$gutterWidth,i,n),this.desiredHeight=n,this._signal("autosize")}},this.$computeLayerConfig=function(){var e=this.session,t=this.$size,n=t.height<=2*this.lineHeight,r=this.session.getScreenLength(),i=r*this.lineHeight,s=this.$getLongestLine(),o=!n&&(this.$hScrollBarAlwaysVisible||t.scrollerWidth-s-2*this.$padding<0),u=this.$horizScroll!==o;u&&(this.$horizScroll=o,this.scrollBarH.setVisible(o));var a=this.$vScroll;this.$maxLines&&this.lineHeight>1&&this.$autosize();var f=this.scrollTop%this.lineHeight,l=t.scrollerHeight+this.lineHeight,c=!this.$maxLines&&this.$scrollPastEnd?(t.scrollerHeight-this.lineHeight)*this.$scrollPastEnd:0;i+=c;var h=this.scrollMargin;this.session.setScrollTop(Math.max(-h.top,Math.min(this.scrollTop,i-t.scrollerHeight+h.bottom))),this.session.setScrollLeft(Math.max(-h.left,Math.min(this.scrollLeft,s+2*this.$padding-t.scrollerWidth+h.right)));var p=!n&&(this.$vScrollBarAlwaysVisible||t.scrollerHeight-i+c<0||this.scrollTop>h.top),d=a!==p;d&&(this.$vScroll=p,this.scrollBarV.setVisible(p));var v=Math.ceil(l/this.lineHeight)-1,m=Math.max(0,Math.round((this.scrollTop-f)/this.lineHeight)),g=m+v,y,b,w=this.lineHeight;m=e.screenToDocumentRow(m,0);var E=e.getFoldLine(m);E&&(m=E.start.row),y=e.documentToScreenRow(m,0),b=e.getRowLength(m)*w,g=Math.min(e.screenToDocumentRow(g,0),e.getLength()-1),l=t.scrollerHeight+e.getRowLength(g)*w+b,f=this.scrollTop-y*w;var S=0;this.layerConfig.width!=s&&(S=this.CHANGE_H_SCROLL);if(u||d)S=this.$updateCachedSize(!0,this.gutterWidth,t.width,t.height),this._signal("scrollbarVisibilityChanged"),d&&(s=this.$getLongestLine());return this.layerConfig={width:s,padding:this.$padding,firstRow:m,firstRowScreen:y,lastRow:g,lineHeight:w,characterWidth:this.characterWidth,minHeight:l,maxHeight:i,offset:f,gutterOffset:w?Math.max(0,Math.ceil((f+t.height-t.scrollerHeight)/w)):0,height:this.$size.scrollerHeight},S},this.$updateLines=function(){var e=this.$changedLines.firstRow,t=this.$changedLines.lastRow;this.$changedLines=null;var n=this.layerConfig;if(e>n.lastRow+1)return;if(ts?(t&&a+o>s+this.lineHeight&&(s-=t*this.$size.scrollerHeight),s===0&&(s=-this.scrollMargin.top),this.session.setScrollTop(s)):a+this.$size.scrollerHeight-ui?(i=1-this.scrollMargin.top)return!0;if(t>0&&this.session.getScrollTop()+this.$size.scrollerHeight-this.layerConfig.maxHeight<-1+this.scrollMargin.bottom)return!0;if(e<0&&this.session.getScrollLeft()>=1-this.scrollMargin.left)return!0;if(e>0&&this.session.getScrollLeft()+this.$size.scrollerWidth-this.layerConfig.width<-1+this.scrollMargin.right)return!0},this.pixelToScreenCoordinates=function(e,t){var n=this.scroller.getBoundingClientRect(),r=(e+this.scrollLeft-n.left-this.$padding)/this.characterWidth,i=Math.floor((t+this.scrollTop-n.top)/this.lineHeight),s=Math.round(r);return{row:i,column:s,side:r-s>0?1:-1}},this.screenToTextCoordinates=function(e,t){var n=this.scroller.getBoundingClientRect(),r=Math.round((e+this.scrollLeft-n.left-this.$padding)/this.characterWidth),i=(t+this.scrollTop-n.top)/this.lineHeight;return this.session.screenToDocumentPosition(i,Math.max(r,0))},this.textToScreenCoordinates=function(e,t){var n=this.scroller.getBoundingClientRect(),r=this.session.documentToScreenPosition(e,t),i=this.$padding+Math.round(r.column*this.characterWidth),s=r.row*this.lineHeight;return{pageX:n.left+i-this.scrollLeft,pageY:n.top+s-this.scrollTop}},this.visualizeFocus=function(){i.addCssClass(this.container,"ace_focus")},this.visualizeBlur=function(){i.removeCssClass(this.container,"ace_focus")},this.showComposition=function(e){this.$composition||(this.$composition={keepTextAreaAtCursor:this.$keepTextAreaAtCursor,cssText:this.textarea.style.cssText}),this.$keepTextAreaAtCursor=!0,i.addCssClass(this.textarea,"ace_composition"),this.textarea.style.cssText="",this.$moveTextAreaToCursor()},this.setCompositionText=function(e){this.$moveTextAreaToCursor()},this.hideComposition=function(){if(!this.$composition)return;i.removeCssClass(this.textarea,"ace_composition"),this.$keepTextAreaAtCursor=this.$composition.keepTextAreaAtCursor,this.textarea.style.cssText=this.$composition.cssText,this.$composition=null},this.setTheme=function(e,t){function o(r){if(n.$themeId!=e)return t&&t();if(!r||!r.cssClass)throw new Error("couldn't load module "+e+" or it didn't call define");i.importCssString(r.cssText,r.cssClass,n.container.ownerDocument),n.theme&&i.removeCssClass(n.container,n.theme.cssClass);var s="padding"in r?r.padding:"padding"in(n.theme||{})?4:n.$padding;n.$padding&&s!=n.$padding&&n.setPadding(s),n.$theme=r.cssClass,n.theme=r,i.addCssClass(n.container,r.cssClass),i.setCssClass(n.container,"ace_dark",r.isDark),n.$size&&(n.$size.width=0,n.$updateSizeAsync()),n._dispatchEvent("themeLoaded",{theme:r}),t&&t()}var n=this;this.$themeId=e,n._dispatchEvent("themeChange",{theme:e});if(!e||typeof e=="string"){var r=e||this.$options.theme.initialValue;s.loadModule(["theme",r],o)}else o(e)},this.getTheme=function(){return this.$themeId},this.setStyle=function(e,t){i.setCssClass(this.container,e,t!==!1)},this.unsetStyle=function(e){i.removeCssClass(this.container,e)},this.setCursorStyle=function(e){this.scroller.style.cursor!=e&&(this.scroller.style.cursor=e)},this.setMouseCursor=function(e){this.scroller.style.cursor=e},this.destroy=function(){this.$textLayer.destroy(),this.$cursorLayer.destroy()}}).call(g.prototype),s.defineOptions(g.prototype,"renderer",{animatedScroll:{initialValue:!1},showInvisibles:{set:function(e){this.$textLayer.setShowInvisibles(e)&&this.$loop.schedule(this.CHANGE_TEXT)},initialValue:!1},showPrintMargin:{set:function(){this.$updatePrintMargin()},initialValue:!0},printMarginColumn:{set:function(){this.$updatePrintMargin()},initialValue:80},printMargin:{set:function(e){typeof e=="number"&&(this.$printMarginColumn=e),this.$showPrintMargin=!!e,this.$updatePrintMargin()},get:function(){return this.$showPrintMargin&&this.$printMarginColumn}},showGutter:{set:function(e){this.$gutter.style.display=e?"block":"none",this.$loop.schedule(this.CHANGE_FULL),this.onGutterResize()},initialValue:!0},fadeFoldWidgets:{set:function(e){i.setCssClass(this.$gutter,"ace_fade-fold-widgets",e)},initialValue:!1},showFoldWidgets:{set:function(e){this.$gutterLayer.setShowFoldWidgets(e)},initialValue:!0},showLineNumbers:{set:function(e){this.$gutterLayer.setShowLineNumbers(e),this.$loop.schedule(this.CHANGE_GUTTER)},initialValue:!0},displayIndentGuides:{set:function(e){this.$textLayer.setDisplayIndentGuides(e)&&this.$loop.schedule(this.CHANGE_TEXT)},initialValue:!0},highlightGutterLine:{set:function(e){if(!this.$gutterLineHighlight){this.$gutterLineHighlight=i.createElement("div"),this.$gutterLineHighlight.className="ace_gutter-active-line",this.$gutter.appendChild(this.$gutterLineHighlight);return}this.$gutterLineHighlight.style.display=e?"":"none",this.$cursorLayer.$pixelPos&&this.$updateGutterLineHighlight()},initialValue:!1,value:!0},hScrollBarAlwaysVisible:{set:function(e){(!this.$hScrollBarAlwaysVisible||!this.$horizScroll)&&this.$loop.schedule(this.CHANGE_SCROLL)},initialValue:!1},vScrollBarAlwaysVisible:{set:function(e){(!this.$vScrollBarAlwaysVisible||!this.$vScroll)&&this.$loop.schedule(this.CHANGE_SCROLL)},initialValue:!1},fontSize:{set:function(e){typeof e=="number"&&(e+="px"),this.container.style.fontSize=e,this.updateFontSize()},initialValue:12},fontFamily:{set:function(e){this.container.style.fontFamily=e,this.updateFontSize()}},maxLines:{set:function(e){this.updateFull()}},minLines:{set:function(e){this.updateFull()}},maxPixelHeight:{set:function(e){this.updateFull()},initialValue:0},scrollPastEnd:{set:function(e){e=+e||0;if(this.$scrollPastEnd==e)return;this.$scrollPastEnd=e,this.$loop.schedule(this.CHANGE_SCROLL)},initialValue:0,handlesSet:!0},fixedWidthGutter:{set:function(e){this.$gutterLayer.$fixedWidth=!!e,this.$loop.schedule(this.CHANGE_GUTTER)}},theme:{set:function(e){this.setTheme(e)},get:function(){return this.$themeId||this.theme},initialValue:"./theme/textmate",handlesSet:!0}}),t.VirtualRenderer=g}),define("ace/worker/worker_client",["require","exports","module","ace/lib/oop","ace/lib/net","ace/lib/event_emitter","ace/config"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/net"),s=e("../lib/event_emitter").EventEmitter,o=e("../config"),u=function(t,n,r,i){this.$sendDeltaQueue=this.$sendDeltaQueue.bind(this),this.changeListener=this.changeListener.bind(this),this.onMessage=this.onMessage.bind(this),e.nameToUrl&&!e.toUrl&&(e.toUrl=e.nameToUrl);if(o.get("packaged")||!e.toUrl)i=i||o.moduleUrl(n,"worker");else{var s=this.$normalizePath;i=i||s(e.toUrl("ace/worker/worker.js",null,"_"));var u={};t.forEach(function(t){u[t]=s(e.toUrl(t,null,"_").replace(/(\.js)?(\?.*)?$/,""))})}try{this.$worker=new Worker(i)}catch(a){if(!(a instanceof window.DOMException))throw a;var f=this.$workerBlob(i),l=window.URL||window.webkitURL,c=l.createObjectURL(f);this.$worker=new Worker(c),l.revokeObjectURL(c)}this.$worker.postMessage({init:!0,tlns:u,module:n,classname:r}),this.callbackId=1,this.callbacks={},this.$worker.onmessage=this.onMessage};(function(){r.implement(this,s),this.onMessage=function(e){var t=e.data;switch(t.type){case"event":this._signal(t.name,{data:t.data});break;case"call":var n=this.callbacks[t.id];n&&(n(t.data),delete this.callbacks[t.id]);break;case"error":this.reportError(t.data);break;case"log":window.console&&console.log&&console.log.apply(console,t.data)}},this.reportError=function(e){window.console&&console.error&&console.error(e)},this.$normalizePath=function(e){return i.qualifyURL(e)},this.terminate=function(){this._signal("terminate",{}),this.deltaQueue=null,this.$worker.terminate(),this.$worker=null,this.$doc&&this.$doc.off("change",this.changeListener),this.$doc=null},this.send=function(e,t){this.$worker.postMessage({command:e,args:t})},this.call=function(e,t,n){if(n){var r=this.callbackId++;this.callbacks[r]=n,t.push(r)}this.send(e,t)},this.emit=function(e,t){try{this.$worker.postMessage({event:e,data:{data:t.data}})}catch(n){console.error(n.stack)}},this.attachToDocument=function(e){this.$doc&&this.terminate(),this.$doc=e,this.call("setValue",[e.getValue()]),e.on("change",this.changeListener)},this.changeListener=function(e){this.deltaQueue||(this.deltaQueue=[],setTimeout(this.$sendDeltaQueue,0)),e.action=="insert"?this.deltaQueue.push(e.start,e.lines):this.deltaQueue.push(e.start,e.end)},this.$sendDeltaQueue=function(){var e=this.deltaQueue;if(!e)return;this.deltaQueue=null,e.length>50&&e.length>this.$doc.getLength()>>1?this.call("setValue",[this.$doc.getValue()]):this.emit("change",{data:e})},this.$workerBlob=function(e){var t="importScripts('"+i.qualifyURL(e)+"');";try{return new Blob([t],{type:"application/javascript"})}catch(n){var r=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder,s=new r;return s.append(t),s.getBlob("application/javascript")}}}).call(u.prototype);var a=function(e,t,n){this.$sendDeltaQueue=this.$sendDeltaQueue.bind(this),this.changeListener=this.changeListener.bind(this),this.callbackId=1,this.callbacks={},this.messageBuffer=[];var r=null,i=!1,u=Object.create(s),a=this;this.$worker={},this.$worker.terminate=function(){},this.$worker.postMessage=function(e){a.messageBuffer.push(e),r&&(i?setTimeout(f):f())},this.setEmitSync=function(e){i=e};var f=function(){var e=a.messageBuffer.shift();e.command?r[e.command].apply(r,e.args):e.event&&u._signal(e.event,e.data)};u.postMessage=function(e){a.onMessage({data:e})},u.callback=function(e,t){this.postMessage({type:"call",id:t,data:e})},u.emit=function(e,t){this.postMessage({type:"event",name:e,data:t})},o.loadModule(["worker",t],function(e){r=new e[n](u);while(a.messageBuffer.length)f()})};a.prototype=u.prototype,t.UIWorkerClient=a,t.WorkerClient=u}),define("ace/placeholder",["require","exports","module","ace/range","ace/lib/event_emitter","ace/lib/oop"],function(e,t,n){"use strict";var r=e("./range").Range,i=e("./lib/event_emitter").EventEmitter,s=e("./lib/oop"),o=function(e,t,n,r,i,s){var o=this;this.length=t,this.session=e,this.doc=e.getDocument(),this.mainClass=i,this.othersClass=s,this.$onUpdate=this.onUpdate.bind(this),this.doc.on("change",this.$onUpdate),this.$others=r,this.$onCursorChange=function(){setTimeout(function(){o.onCursorChange()})},this.$pos=n;var u=e.getUndoManager().$undoStack||e.getUndoManager().$undostack||{length:-1};this.$undoStackDepth=u.length,this.setup(),e.selection.on("changeCursor",this.$onCursorChange)};(function(){s.implement(this,i),this.setup=function(){var e=this,t=this.doc,n=this.session;this.selectionBefore=n.selection.toJSON(),n.selection.inMultiSelectMode&&n.selection.toSingleRange(),this.pos=t.createAnchor(this.$pos.row,this.$pos.column);var i=this.pos;i.$insertRight=!0,i.detach(),i.markerId=n.addMarker(new r(i.row,i.column,i.row,i.column+this.length),this.mainClass,null,!1),this.others=[],this.$others.forEach(function(n){var r=t.createAnchor(n.row,n.column);r.$insertRight=!0,r.detach(),e.others.push(r)}),n.setUndoSelect(!1)},this.showOtherMarkers=function(){if(this.othersActive)return;var e=this.session,t=this;this.othersActive=!0,this.others.forEach(function(n){n.markerId=e.addMarker(new r(n.row,n.column,n.row,n.column+t.length),t.othersClass,null,!1)})},this.hideOtherMarkers=function(){if(!this.othersActive)return;this.othersActive=!1;for(var e=0;e=this.pos.column&&t.start.column<=this.pos.column+this.length+1,s=t.start.column-this.pos.column;this.updateAnchors(e),i&&(this.length+=n);if(i&&!this.session.$fromUndo)if(e.action==="insert")for(var o=this.others.length-1;o>=0;o--){var u=this.others[o],a={row:u.row,column:u.column+s};this.doc.insertMergedLines(a,e.lines)}else if(e.action==="remove")for(var o=this.others.length-1;o>=0;o--){var u=this.others[o],a={row:u.row,column:u.column+s};this.doc.remove(new r(a.row,a.column,a.row,a.column-n))}this.$updating=!1,this.updateMarkers()},this.updateAnchors=function(e){this.pos.onChange(e);for(var t=this.others.length;t--;)this.others[t].onChange(e);this.updateMarkers()},this.updateMarkers=function(){if(this.$updating)return;var e=this,t=this.session,n=function(n,i){t.removeMarker(n.markerId),n.markerId=t.addMarker(new r(n.row,n.column,n.row,n.column+e.length),i,null,!1)};n(this.pos,this.mainClass);for(var i=this.others.length;i--;)n(this.others[i],this.othersClass)},this.onCursorChange=function(e){if(this.$updating||!this.session)return;var t=this.session.selection.getCursor();t.row===this.pos.row&&t.column>=this.pos.column&&t.column<=this.pos.column+this.length?(this.showOtherMarkers(),this._emit("cursorEnter",e)):(this.hideOtherMarkers(),this._emit("cursorLeave",e))},this.detach=function(){this.session.removeMarker(this.pos&&this.pos.markerId),this.hideOtherMarkers(),this.doc.removeEventListener("change",this.$onUpdate),this.session.selection.removeEventListener("changeCursor",this.$onCursorChange),this.session.setUndoSelect(!0),this.session=null},this.cancel=function(){if(this.$undoStackDepth===-1)return;var e=this.session.getUndoManager(),t=(e.$undoStack||e.$undostack).length-this.$undoStackDepth;for(var n=0;n1&&!this.inMultiSelectMode&&(this._signal("multiSelect"),this.inMultiSelectMode=!0,this.session.$undoSelect=!1,this.rangeList.attach(this.session)),t||this.fromOrientedRange(e)},this.toSingleRange=function(e){e=e||this.ranges[0];var t=this.rangeList.removeAll();t.length&&this.$onRemoveRange(t),e&&this.fromOrientedRange(e)},this.substractPoint=function(e){var t=this.rangeList.substractPoint(e);if(t)return this.$onRemoveRange(t),t[0]},this.mergeOverlappingRanges=function(){var e=this.rangeList.merge();e.length?this.$onRemoveRange(e):this.ranges[0]&&this.fromOrientedRange(this.ranges[0])},this.$onAddRange=function(e){this.rangeCount=this.rangeList.ranges.length,this.ranges.unshift(e),this._signal("addRange",{range:e})},this.$onRemoveRange=function(e){this.rangeCount=this.rangeList.ranges.length;if(this.rangeCount==1&&this.inMultiSelectMode){var t=this.rangeList.ranges.pop();e.push(t),this.rangeCount=0}for(var n=e.length;n--;){var r=this.ranges.indexOf(e[n]);this.ranges.splice(r,1)}this._signal("removeRange",{ranges:e}),this.rangeCount===0&&this.inMultiSelectMode&&(this.inMultiSelectMode=!1,this._signal("singleSelect"),this.session.$undoSelect=!0,this.rangeList.detach(this.session)),t=t||this.ranges[0],t&&!t.isEqual(this.getRange())&&this.fromOrientedRange(t)},this.$initRangeList=function(){if(this.rangeList)return;this.rangeList=new r,this.ranges=[],this.rangeCount=0},this.getAllRanges=function(){return this.rangeCount?this.rangeList.ranges.concat():[this.getRange()]},this.splitIntoLines=function(){if(this.rangeCount>1){var e=this.rangeList.ranges,t=e[e.length-1],n=i.fromPoints(e[0].start,t.end);this.toSingleRange(),this.setSelectionRange(n,t.cursor==t.start)}else{var n=this.getRange(),r=this.isBackwards(),s=n.start.row,o=n.end.row;if(s==o){if(r)var u=n.end,a=n.start;else var u=n.start,a=n.end;this.addRange(i.fromPoints(a,a)),this.addRange(i.fromPoints(u,u));return}var f=[],l=this.getLineRange(s,!0);l.start.column=n.start.column,f.push(l);for(var c=s+1;c1){var e=this.rangeList.ranges,t=e[e.length-1],n=i.fromPoints(e[0].start,t.end);this.toSingleRange(),this.setSelectionRange(n,t.cursor==t.start)}else{var r=this.session.documentToScreenPosition(this.selectionLead),s=this.session.documentToScreenPosition(this.selectionAnchor),o=this.rectangularRangeBlock(r,s);o.forEach(this.addRange,this)}},this.rectangularRangeBlock=function(e,t,n){var r=[],s=e.column0)d--;if(d>0){var m=0;while(r[m].isEmpty())m++}for(var g=d;g>=m;g--)r[g].isEmpty()&&r.splice(g,1)}return r}}.call(s.prototype);var d=e("./editor").Editor;(function(){this.updateSelectionMarkers=function(){this.renderer.updateCursor(),this.renderer.updateBackMarkers()},this.addSelectionMarker=function(e){e.cursor||(e.cursor=e.end);var t=this.getSelectionStyle();return e.marker=this.session.addMarker(e,"ace_selection",t),this.session.$selectionMarkers.push(e),this.session.selectionMarkerCount=this.session.$selectionMarkers.length,e},this.removeSelectionMarker=function(e){if(!e.marker)return;this.session.removeMarker(e.marker);var t=this.session.$selectionMarkers.indexOf(e);t!=-1&&this.session.$selectionMarkers.splice(t,1),this.session.selectionMarkerCount=this.session.$selectionMarkers.length},this.removeSelectionMarkers=function(e){var t=this.session.$selectionMarkers;for(var n=e.length;n--;){var r=e[n];if(!r.marker)continue;this.session.removeMarker(r.marker);var i=t.indexOf(r);i!=-1&&t.splice(i,1)}this.session.selectionMarkerCount=t.length},this.$onAddRange=function(e){this.addSelectionMarker(e.range),this.renderer.updateCursor(),this.renderer.updateBackMarkers()},this.$onRemoveRange=function(e){this.removeSelectionMarkers(e.ranges),this.renderer.updateCursor(),this.renderer.updateBackMarkers()},this.$onMultiSelect=function(e){if(this.inMultiSelectMode)return;this.inMultiSelectMode=!0,this.setStyle("ace_multiselect"),this.keyBinding.addKeyboardHandler(f.keyboardHandler),this.commands.setDefaultHandler("exec",this.$onMultiSelectExec),this.renderer.updateCursor(),this.renderer.updateBackMarkers()},this.$onSingleSelect=function(e){if(this.session.multiSelect.inVirtualMode)return;this.inMultiSelectMode=!1,this.unsetStyle("ace_multiselect"),this.keyBinding.removeKeyboardHandler(f.keyboardHandler),this.commands.removeDefaultHandler("exec",this.$onMultiSelectExec),this.renderer.updateCursor(),this.renderer.updateBackMarkers(),this._emit("changeSelection")},this.$onMultiSelectExec=function(e){var t=e.command,n=e.editor;if(!n.multiSelect)return;if(!t.multiSelectAction){var r=t.exec(n,e.args||{});n.multiSelect.addRange(n.multiSelect.toOrientedRange()),n.multiSelect.mergeOverlappingRanges()}else t.multiSelectAction=="forEach"?r=n.forEachSelection(t,e.args):t.multiSelectAction=="forEachLine"?r=n.forEachSelection(t,e.args,!0):t.multiSelectAction=="single"?(n.exitMultiSelectMode(),r=t.exec(n,e.args||{})):r=t.multiSelectAction(n,e.args||{});return r},this.forEachSelection=function(e,t,n){if(this.inVirtualSelectionMode)return;var r=n&&n.keepOrder,i=n==1||n&&n.$byLines,o=this.session,u=this.selection,a=u.rangeList,f=(r?u:a).ranges,l;if(!f.length)return e.exec?e.exec(this,t||{}):e(this,t||{});var c=u._eventRegistry;u._eventRegistry={};var h=new s(o);this.inVirtualSelectionMode=!0;for(var p=f.length;p--;){if(i)while(p>0&&f[p].start.row==f[p-1].end.row)p--;h.fromOrientedRange(f[p]),h.index=p,this.selection=o.selection=h;var d=e.exec?e.exec(this,t||{}):e(this,t||{});!l&&d!==undefined&&(l=d),h.toOrientedRange(f[p])}h.detach(),this.selection=o.selection=u,this.inVirtualSelectionMode=!1,u._eventRegistry=c,u.mergeOverlappingRanges();var v=this.renderer.$scrollAnimation;return this.onCursorChange(),this.onSelectionChange(),v&&v.from==v.to&&this.renderer.animateScrolling(v.from),l},this.exitMultiSelectMode=function(){if(!this.inMultiSelectMode||this.inVirtualSelectionMode)return;this.multiSelect.toSingleRange()},this.getSelectedText=function(){var e="";if(this.inMultiSelectMode&&!this.inVirtualSelectionMode){var t=this.multiSelect.rangeList.ranges,n=[];for(var r=0;r0);u<0&&(u=0),f>=c&&(f=c-1)}var p=this.session.removeFullLines(u,f);p=this.$reAlignText(p,l),this.session.insert({row:u,column:0},p.join("\n")+"\n"),l||(o.start.column=0,o.end.column=p[p.length-1].length),this.selection.setRange(o)}else{s.forEach(function(e){t.substractPoint(e.cursor)});var d=0,v=Infinity,m=n.map(function(t){var n=t.cursor,r=e.getLine(n.row),i=r.substr(n.column).search(/\S/g);return i==-1&&(i=0),n.column>d&&(d=n.column),io?e.insert(r,a.stringRepeat(" ",s-o)):e.remove(new i(r.row,r.column,r.row,r.column-s+o)),t.start.column=t.end.column=d,t.start.row=t.end.row=r.row,t.cursor=t.end}),t.fromOrientedRange(n[0]),this.renderer.updateCursor(),this.renderer.updateBackMarkers()}},this.$reAlignText=function(e,t){function u(e){return a.stringRepeat(" ",e)}function f(e){return e[2]?u(i)+e[2]+u(s-e[2].length+o)+e[4].replace(/^([=:])\s+/,"$1 "):e[0]}function l(e){return e[2]?u(i+s-e[2].length)+e[2]+u(o," ")+e[4].replace(/^([=:])\s+/,"$1 "):e[0]}function c(e){return e[2]?u(i)+e[2]+u(o)+e[4].replace(/^([=:])\s+/,"$1 "):e[0]}var n=!0,r=!0,i,s,o;return e.map(function(e){var t=e.match(/(\s*)(.*?)(\s*)([=:].*)/);return t?i==null?(i=t[1].length,s=t[2].length,o=t[3].length,t):(i+s+o!=t[1].length+t[2].length+t[3].length&&(r=!1),i!=t[1].length&&(n=!1),i>t[1].length&&(i=t[1].length),st[3].length&&(o=t[3].length),t):[e]}).map(t?f:n?r?l:f:c)}}).call(d.prototype),t.onSessionChange=function(e){var t=e.session;t&&!t.multiSelect&&(t.$selectionMarkers=[],t.selection.$initRangeList(),t.multiSelect=t.selection),this.multiSelect=t&&t.multiSelect;var n=e.oldSession;n&&(n.multiSelect.off("addRange",this.$onAddRange),n.multiSelect.off("removeRange",this.$onRemoveRange),n.multiSelect.off("multiSelect",this.$onMultiSelect),n.multiSelect.off("singleSelect",this.$onSingleSelect),n.multiSelect.lead.off("change",this.$checkMultiselectChange),n.multiSelect.anchor.off("change",this.$checkMultiselectChange)),t&&(t.multiSelect.on("addRange",this.$onAddRange),t.multiSelect.on("removeRange",this.$onRemoveRange),t.multiSelect.on("multiSelect",this.$onMultiSelect),t.multiSelect.on("singleSelect",this.$onSingleSelect),t.multiSelect.lead.on("change",this.$checkMultiselectChange),t.multiSelect.anchor.on("change",this.$checkMultiselectChange)),t&&this.inMultiSelectMode!=t.selection.inMultiSelectMode&&(t.selection.inMultiSelectMode?this.$onMultiSelect():this.$onSingleSelect())},t.MultiSelect=m,e("./config").defineOptions(d.prototype,"editor",{enableMultiselect:{set:function(e){m(this),e?(this.on("changeSession",this.$multiselectOnSessionChange),this.on("mousedown",o)):(this.off("changeSession",this.$multiselectOnSessionChange),this.off("mousedown",o))},value:!0},enableBlockSelect:{set:function(e){this.$blockSelectEnabled=e},value:!0}})}),define("ace/mode/folding/fold_mode",["require","exports","module","ace/range"],function(e,t,n){"use strict";var r=e("../../range").Range,i=t.FoldMode=function(){};(function(){this.foldingStartMarker=null,this.foldingStopMarker=null,this.getFoldWidget=function(e,t,n){var r=e.getLine(n);return this.foldingStartMarker.test(r)?"start":t=="markbeginend"&&this.foldingStopMarker&&this.foldingStopMarker.test(r)?"end":""},this.getFoldWidgetRange=function(e,t,n){return null},this.indentationBlock=function(e,t,n){var i=/\S/,s=e.getLine(t),o=s.search(i);if(o==-1)return;var u=n||s.length,a=e.getLength(),f=t,l=t;while(++tf){var h=e.getLine(l).length;return new r(f,u,l,h)}},this.openingBracketBlock=function(e,t,n,i,s){var o={row:n,column:i+1},u=e.$findClosingBracket(t,o,s);if(!u)return;var a=e.foldWidgets[u.row];return a==null&&(a=e.getFoldWidget(u.row)),a=="start"&&u.row>o.row&&(u.row--,u.column=e.getLine(u.row).length),r.fromPoints(o,u)},this.closingBracketBlock=function(e,t,n,i,s){var o={row:n,column:i},u=e.$findOpeningBracket(t,o);if(!u)return;return u.column++,o.column--,r.fromPoints(u,o)}}).call(i.prototype)}),define("ace/theme/textmate",["require","exports","module","ace/lib/dom"],function(e,t,n){"use strict";t.isDark=!1,t.cssClass="ace-tm",t.cssText='.ace-tm .ace_gutter {background: #f0f0f0;color: #333;}.ace-tm .ace_print-margin {width: 1px;background: #e8e8e8;}.ace-tm .ace_fold {background-color: #6B72E6;}.ace-tm {background-color: #FFFFFF;color: black;}.ace-tm .ace_cursor {color: black;}.ace-tm .ace_invisible {color: rgb(191, 191, 191);}.ace-tm .ace_storage,.ace-tm .ace_keyword {color: blue;}.ace-tm .ace_constant {color: rgb(197, 6, 11);}.ace-tm .ace_constant.ace_buildin {color: rgb(88, 72, 246);}.ace-tm .ace_constant.ace_language {color: rgb(88, 92, 246);}.ace-tm .ace_constant.ace_library {color: rgb(6, 150, 14);}.ace-tm .ace_invalid {background-color: rgba(255, 0, 0, 0.1);color: red;}.ace-tm .ace_support.ace_function {color: rgb(60, 76, 114);}.ace-tm .ace_support.ace_constant {color: rgb(6, 150, 14);}.ace-tm .ace_support.ace_type,.ace-tm .ace_support.ace_class {color: rgb(109, 121, 222);}.ace-tm .ace_keyword.ace_operator {color: rgb(104, 118, 135);}.ace-tm .ace_string {color: rgb(3, 106, 7);}.ace-tm .ace_comment {color: rgb(76, 136, 107);}.ace-tm .ace_comment.ace_doc {color: rgb(0, 102, 255);}.ace-tm .ace_comment.ace_doc.ace_tag {color: rgb(128, 159, 191);}.ace-tm .ace_constant.ace_numeric {color: rgb(0, 0, 205);}.ace-tm .ace_variable {color: rgb(49, 132, 149);}.ace-tm .ace_xml-pe {color: rgb(104, 104, 91);}.ace-tm .ace_entity.ace_name.ace_function {color: #0000A2;}.ace-tm .ace_heading {color: rgb(12, 7, 255);}.ace-tm .ace_list {color:rgb(185, 6, 144);}.ace-tm .ace_meta.ace_tag {color:rgb(0, 22, 142);}.ace-tm .ace_string.ace_regex {color: rgb(255, 0, 0)}.ace-tm .ace_marker-layer .ace_selection {background: rgb(181, 213, 255);}.ace-tm.ace_multiselect .ace_selection.ace_start {box-shadow: 0 0 3px 0px white;}.ace-tm .ace_marker-layer .ace_step {background: rgb(252, 255, 0);}.ace-tm .ace_marker-layer .ace_stack {background: rgb(164, 229, 101);}.ace-tm .ace_marker-layer .ace_bracket {margin: -1px 0 0 -1px;border: 1px solid rgb(192, 192, 192);}.ace-tm .ace_marker-layer .ace_active-line {background: rgba(0, 0, 0, 0.07);}.ace-tm .ace_gutter-active-line {background-color : #dcdcdc;}.ace-tm .ace_marker-layer .ace_selected-word {background: rgb(250, 250, 255);border: 1px solid rgb(200, 200, 250);}.ace-tm .ace_indent-guide {background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAE0lEQVQImWP4////f4bLly//BwAmVgd1/w11/gAAAABJRU5ErkJggg==") right repeat-y;}';var r=e("../lib/dom");r.importCssString(t.cssText,t.cssClass)}),define("ace/line_widgets",["require","exports","module","ace/lib/oop","ace/lib/dom","ace/range"],function(e,t,n){"use strict";function o(e){this.session=e,this.session.widgetManager=this,this.session.getRowLength=this.getRowLength,this.session.$getWidgetScreenLength=this.$getWidgetScreenLength,this.updateOnChange=this.updateOnChange.bind(this),this.renderWidgets=this.renderWidgets.bind(this),this.measureWidgets=this.measureWidgets.bind(this),this.session._changedWidgets=[],this.$onChangeEditor=this.$onChangeEditor.bind(this),this.session.on("change",this.updateOnChange),this.session.on("changeFold",this.updateOnFold),this.session.on("changeEditor",this.$onChangeEditor)}var r=e("./lib/oop"),i=e("./lib/dom"),s=e("./range").Range;(function(){this.getRowLength=function(e){var t;return this.lineWidgets?t=this.lineWidgets[e]&&this.lineWidgets[e].rowCount||0:t=0,!this.$useWrapMode||!this.$wrapData[e]?1+t:this.$wrapData[e].length+1+t},this.$getWidgetScreenLength=function(){var e=0;return this.lineWidgets.forEach(function(t){t&&t.rowCount&&!t.hidden&&(e+=t.rowCount)}),e},this.$onChangeEditor=function(e){this.attach(e.editor)},this.attach=function(e){e&&e.widgetManager&&e.widgetManager!=this&&e.widgetManager.detach();if(this.editor==e)return;this.detach(),this.editor=e,e&&(e.widgetManager=this,e.renderer.on("beforeRender",this.measureWidgets),e.renderer.on("afterRender",this.renderWidgets))},this.detach=function(e){var t=this.editor;if(!t)return;this.editor=null,t.widgetManager=null,t.renderer.off("beforeRender",this.measureWidgets),t.renderer.off("afterRender",this.renderWidgets);var n=this.session.lineWidgets;n&&n.forEach(function(e){e&&e.el&&e.el.parentNode&&(e._inDocument=!1,e.el.parentNode.removeChild(e.el))})},this.updateOnFold=function(e,t){var n=t.lineWidgets;if(!n||!e.action)return;var r=e.data,i=r.start.row,s=r.end.row,o=e.action=="add";for(var u=i+1;u0&&!r[i])i--;this.firstRow=n.firstRow,this.lastRow=n.lastRow,t.$cursorLayer.config=n;for(var o=i;o<=s;o++){var u=r[o];if(!u||!u.el)continue;if(u.hidden){u.el.style.top=-100-(u.pixelHeight||0)+"px";continue}u._inDocument||(u._inDocument=!0,t.container.appendChild(u.el));var a=t.$cursorLayer.getPixelPosition({row:o,column:0},!0).top;u.coverLine||(a+=n.lineHeight*this.session.getRowLineCount(u.row)),u.el.style.top=a-n.offset+"px";var f=u.coverGutter?0:t.gutterWidth;u.fixedWidth||(f-=t.scrollLeft),u.el.style.left=f+"px",u.fullWidth&&u.screenWidth&&(u.el.style.minWidth=n.width+2*n.padding+"px"),u.fixedWidth?u.el.style.right=t.scrollBar.getWidth()+"px":u.el.style.right=""}}}).call(o.prototype),t.LineWidgets=o}),define("ace/ext/error_marker",["require","exports","module","ace/line_widgets","ace/lib/dom","ace/range"],function(e,t,n){"use strict";function o(e,t,n){var r=0,i=e.length-1;while(r<=i){var s=r+i>>1,o=n(t,e[s]);if(o>0)r=s+1;else{if(!(o<0))return s;i=s-1}}return-(r+1)}function u(e,t,n){var r=e.getAnnotations().sort(s.comparePoints);if(!r.length)return;var i=o(r,{row:t,column:-1},s.comparePoints);i<0&&(i=-i-1),i>=r.length?i=n>0?0:r.length-1:i===0&&n<0&&(i=r.length-1);var u=r[i];if(!u||!n)return;if(u.row===t){do u=r[i+=n];while(u&&u.row===t);if(!u)return r.slice()}var a=[];t=u.row;do a[n<0?"unshift":"push"](u),u=r[i+=n];while(u&&u.row==t);return a.length&&a}var r=e("../line_widgets").LineWidgets,i=e("../lib/dom"),s=e("../range").Range;t.showErrorMarker=function(e,t){var n=e.session;n.widgetManager||(n.widgetManager=new r(n),n.widgetManager.attach(e));var s=e.getCursorPosition(),o=s.row,a=n.widgetManager.getWidgetsAtRow(o).filter(function(e){return e.type=="errorMarker"})[0];a?a.destroy():o-=t;var f=u(n,o,t),l;if(f){var c=f[0];s.column=(c.pos&&typeof c.column!="number"?c.pos.sc:c.column)||0,s.row=c.row,l=e.renderer.$gutterLayer.$annotations[s.row]}else{if(a)return;l={text:["Looks good!"],className:"ace_ok"}}e.session.unfold(s.row),e.selection.moveToPosition(s);var h={row:s.row,fixedWidth:!0,coverGutter:!0,el:i.createElement("div"),type:"errorMarker"},p=h.el.appendChild(i.createElement("div")),d=h.el.appendChild(i.createElement("div"));d.className="error_widget_arrow "+l.className;var v=e.renderer.$cursorLayer.getPixelPosition(s).left;d.style.left=v+e.renderer.gutterWidth-5+"px",h.el.className="error_widget_wrapper",p.className="error_widget "+l.className,p.innerHTML=l.text.join("
"),p.appendChild(i.createElement("div"));var m=function(e,t,n){if(t===0&&(n==="esc"||n==="return"))return h.destroy(),{command:"null"}};h.destroy=function(){if(e.$mouseHandler.isMousePressed)return;e.keyBinding.removeKeyboardHandler(m),n.widgetManager.removeLineWidget(h),e.off("changeSelection",h.destroy),e.off("changeSession",h.destroy),e.off("mouseup",h.destroy),e.off("change",h.destroy)},e.keyBinding.addKeyboardHandler(m),e.on("changeSelection",h.destroy),e.on("changeSession",h.destroy),e.on("mouseup",h.destroy),e.on("change",h.destroy),e.session.widgetManager.addLineWidget(h),h.el.onmousedown=e.focus.bind(e),e.renderer.scrollCursorIntoView(null,.5,{bottom:h.el.offsetHeight})},i.importCssString(" .error_widget_wrapper { background: inherit; color: inherit; border:none } .error_widget { border-top: solid 2px; border-bottom: solid 2px; margin: 5px 0; padding: 10px 40px; white-space: pre-wrap; } .error_widget.ace_error, .error_widget_arrow.ace_error{ border-color: #ff5a5a } .error_widget.ace_warning, .error_widget_arrow.ace_warning{ border-color: #F1D817 } .error_widget.ace_info, .error_widget_arrow.ace_info{ border-color: #5a5a5a } .error_widget.ace_ok, .error_widget_arrow.ace_ok{ border-color: #5aaa5a } .error_widget_arrow { position: absolute; border: solid 5px; border-top-color: transparent!important; border-right-color: transparent!important; border-left-color: transparent!important; top: -5px; }","")}),define("ace/ace",["require","exports","module","ace/lib/fixoldbrowsers","ace/lib/dom","ace/lib/event","ace/editor","ace/edit_session","ace/undomanager","ace/virtual_renderer","ace/worker/worker_client","ace/keyboard/hash_handler","ace/placeholder","ace/multi_select","ace/mode/folding/fold_mode","ace/theme/textmate","ace/ext/error_marker","ace/config"],function(e,t,n){"use strict";e("./lib/fixoldbrowsers");var r=e("./lib/dom"),i=e("./lib/event"),s=e("./editor").Editor,o=e("./edit_session").EditSession,u=e("./undomanager").UndoManager,a=e("./virtual_renderer").VirtualRenderer;e("./worker/worker_client"),e("./keyboard/hash_handler"),e("./placeholder"),e("./multi_select"),e("./mode/folding/fold_mode"),e("./theme/textmate"),e("./ext/error_marker"),t.config=e("./config"),t.require=e,typeof define=="function"&&(t.define=define),t.edit=function(e){if(typeof e=="string"){var n=e;e=document.getElementById(n);if(!e)throw new Error("ace.edit can't find div #"+n)}if(e&&e.env&&e.env.editor instanceof s)return e.env.editor;var o="";if(e&&/input|textarea/i.test(e.tagName)){var u=e;o=u.value,e=r.createElement("pre"),u.parentNode.replaceChild(e,u)}else e&&(o=r.getInnerText(e),e.innerHTML="");var f=t.createEditSession(o),l=new s(new a(e));l.setSession(f);var c={document:f,editor:l,onResize:l.resize.bind(l,null)};return u&&(c.textarea=u),i.addListener(window,"resize",c.onResize),l.on("destroy",function(){i.removeListener(window,"resize",c.onResize),c.editor.container.env=null}),l.container.env=l.env=c,l},t.createEditSession=function(e,t){var n=new o(e,t);return n.setUndoManager(new u),n},t.EditSession=o,t.UndoManager=u,t.version="1.2.6"}); - (function() { - window.require(["ace/ace"], function(a) { - if (a) { - a.config.init(true); - a.define = window.define; - } - if (!window.ace) - window.ace = a; - for (var key in a) if (a.hasOwnProperty(key)) - window.ace[key] = a[key]; - }); - })(); - \ No newline at end of file diff --git a/examples/SmartSwitch/data_src/js_css_src/ace-drafts/ext-searchbox.js b/examples/SmartSwitch/data_src/js_css_src/ace-drafts/ext-searchbox.js deleted file mode 100644 index b38b622ce..000000000 --- a/examples/SmartSwitch/data_src/js_css_src/ace-drafts/ext-searchbox.js +++ /dev/null @@ -1,5 +0,0 @@ -define("ace/ext/searchbox",["require","exports","module","ace/lib/dom","ace/lib/lang","ace/lib/event","ace/keyboard/hash_handler","ace/lib/keys"],function(e,t,n){"use strict";var r=e("../lib/dom"),i=e("../lib/lang"),s=e("../lib/event"),o=".ace_search {background-color: #ddd;border: 1px solid #cbcbcb;border-top: 0 none;max-width: 325px;overflow: hidden;margin: 0;padding: 4px;padding-right: 6px;padding-bottom: 0;position: absolute;top: 0px;z-index: 99;white-space: normal;}.ace_search.left {border-left: 0 none;border-radius: 0px 0px 5px 0px;left: 0;}.ace_search.right {border-radius: 0px 0px 0px 5px;border-right: 0 none;right: 0;}.ace_search_form, .ace_replace_form {border-radius: 3px;border: 1px solid #cbcbcb;float: left;margin-bottom: 4px;overflow: hidden;}.ace_search_form.ace_nomatch {outline: 1px solid red;}.ace_search_field {background-color: white;color: black;border-right: 1px solid #cbcbcb;border: 0 none;-webkit-box-sizing: border-box;-moz-box-sizing: border-box;box-sizing: border-box;float: left;height: 22px;outline: 0;padding: 0 7px;width: 214px;margin: 0;}.ace_searchbtn,.ace_replacebtn {background: #fff;border: 0 none;border-left: 1px solid #dcdcdc;cursor: pointer;float: left;height: 22px;margin: 0;position: relative;}.ace_searchbtn:last-child,.ace_replacebtn:last-child {border-top-right-radius: 3px;border-bottom-right-radius: 3px;}.ace_searchbtn:disabled {background: none;cursor: default;}.ace_searchbtn {background-position: 50% 50%;background-repeat: no-repeat;width: 27px;}.ace_searchbtn.prev {background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAFCAYAAAB4ka1VAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAADFJREFUeNpiSU1NZUAC/6E0I0yACYskCpsJiySKIiY0SUZk40FyTEgCjGgKwTRAgAEAQJUIPCE+qfkAAAAASUVORK5CYII=); }.ace_searchbtn.next {background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAFCAYAAAB4ka1VAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAADRJREFUeNpiTE1NZQCC/0DMyIAKwGJMUAYDEo3M/s+EpvM/mkKwCQxYjIeLMaELoLMBAgwAU7UJObTKsvAAAAAASUVORK5CYII=); }.ace_searchbtn_close {background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAcCAYAAABRVo5BAAAAZ0lEQVR42u2SUQrAMAhDvazn8OjZBilCkYVVxiis8H4CT0VrAJb4WHT3C5xU2a2IQZXJjiQIRMdkEoJ5Q2yMqpfDIo+XY4k6h+YXOyKqTIj5REaxloNAd0xiKmAtsTHqW8sR2W5f7gCu5nWFUpVjZwAAAABJRU5ErkJggg==) no-repeat 50% 0;border-radius: 50%;border: 0 none;color: #656565;cursor: pointer;float: right;font: 16px/16px Arial;height: 14px;margin: 5px 1px 9px 5px;padding: 0;text-align: center;width: 14px;}.ace_searchbtn_close:hover {background-color: #656565;background-position: 50% 100%;color: white;}.ace_replacebtn.prev {width: 54px}.ace_replacebtn.next {width: 27px}.ace_button {margin-left: 2px;cursor: pointer;-webkit-user-select: none;-moz-user-select: none;-o-user-select: none;-ms-user-select: none;user-select: none;overflow: hidden;opacity: 0.7;border: 1px solid rgba(100,100,100,0.23);padding: 1px;-moz-box-sizing: border-box;box-sizing: border-box;color: black;}.ace_button:hover {background-color: #eee;opacity:1;}.ace_button:active {background-color: #ddd;}.ace_button.checked {border-color: #3399ff;opacity:1;}.ace_search_options{margin-bottom: 3px;text-align: right;-webkit-user-select: none;-moz-user-select: none;-o-user-select: none;-ms-user-select: none;user-select: none;}",u=e("../keyboard/hash_handler").HashHandler,a=e("../lib/keys");r.importCssString(o,"ace_searchbox");var f=''.replace(/>\s+/g,">"),l=function(e,t,n){var i=r.createElement("div");i.innerHTML=f,this.element=i.firstChild,this.$init(),this.setEditor(e)};(function(){this.setEditor=function(e){e.searchBox=this,e.container.appendChild(this.element),this.editor=e},this.$initElements=function(e){this.searchBox=e.querySelector(".ace_search_form"),this.replaceBox=e.querySelector(".ace_replace_form"),this.searchOptions=e.querySelector(".ace_search_options"),this.regExpOption=e.querySelector("[action=toggleRegexpMode]"),this.caseSensitiveOption=e.querySelector("[action=toggleCaseSensitive]"),this.wholeWordOption=e.querySelector("[action=toggleWholeWords]"),this.searchInput=this.searchBox.querySelector(".ace_search_field"),this.replaceInput=this.replaceBox.querySelector(".ace_search_field")},this.$init=function(){var e=this.element;this.$initElements(e);var t=this;s.addListener(e,"mousedown",function(e){setTimeout(function(){t.activeInput.focus()},0),s.stopPropagation(e)}),s.addListener(e,"click",function(e){var n=e.target||e.srcElement,r=n.getAttribute("action");r&&t[r]?t[r]():t.$searchBarKb.commands[r]&&t.$searchBarKb.commands[r].exec(t),s.stopPropagation(e)}),s.addCommandKeyListener(e,function(e,n,r){var i=a.keyCodeToString(r),o=t.$searchBarKb.findKeyCommand(n,i);o&&o.exec&&(o.exec(t),s.stopEvent(e))}),this.$onChange=i.delayedCall(function(){t.find(!1,!1)}),s.addListener(this.searchInput,"input",function(){t.$onChange.schedule(20)}),s.addListener(this.searchInput,"focus",function(){t.activeInput=t.searchInput,t.searchInput.value&&t.highlight()}),s.addListener(this.replaceInput,"focus",function(){t.activeInput=t.replaceInput,t.searchInput.value&&t.highlight()})},this.$closeSearchBarKb=new u([{bindKey:"Esc",name:"closeSearchBar",exec:function(e){e.searchBox.hide()}}]),this.$searchBarKb=new u,this.$searchBarKb.bindKeys({"Ctrl-f|Command-f":function(e){var t=e.isReplace=!e.isReplace;e.replaceBox.style.display=t?"":"none",e.searchInput.focus()},"Ctrl-H|Command-Option-F":function(e){e.replaceBox.style.display="",e.replaceInput.focus()},"Ctrl-G|Command-G":function(e){e.findNext()},"Ctrl-Shift-G|Command-Shift-G":function(e){e.findPrev()},esc:function(e){setTimeout(function(){e.hide()})},Return:function(e){e.activeInput==e.replaceInput&&e.replace(),e.findNext()},"Shift-Return":function(e){e.activeInput==e.replaceInput&&e.replace(),e.findPrev()},"Alt-Return":function(e){e.activeInput==e.replaceInput&&e.replaceAll(),e.findAll()},Tab:function(e){(e.activeInput==e.replaceInput?e.searchInput:e.replaceInput).focus()}}),this.$searchBarKb.addCommands([{name:"toggleRegexpMode",bindKey:{win:"Alt-R|Alt-/",mac:"Ctrl-Alt-R|Ctrl-Alt-/"},exec:function(e){e.regExpOption.checked=!e.regExpOption.checked,e.$syncOptions()}},{name:"toggleCaseSensitive",bindKey:{win:"Alt-C|Alt-I",mac:"Ctrl-Alt-R|Ctrl-Alt-I"},exec:function(e){e.caseSensitiveOption.checked=!e.caseSensitiveOption.checked,e.$syncOptions()}},{name:"toggleWholeWords",bindKey:{win:"Alt-B|Alt-W",mac:"Ctrl-Alt-B|Ctrl-Alt-W"},exec:function(e){e.wholeWordOption.checked=!e.wholeWordOption.checked,e.$syncOptions()}}]),this.$syncOptions=function(){r.setCssClass(this.regExpOption,"checked",this.regExpOption.checked),r.setCssClass(this.wholeWordOption,"checked",this.wholeWordOption.checked),r.setCssClass(this.caseSensitiveOption,"checked",this.caseSensitiveOption.checked),this.find(!1,!1)},this.highlight=function(e){this.editor.session.highlight(e||this.editor.$search.$options.re),this.editor.renderer.updateBackMarkers()},this.find=function(e,t,n){var i=this.editor.find(this.searchInput.value,{skipCurrent:e,backwards:t,wrap:!0,regExp:this.regExpOption.checked,caseSensitive:this.caseSensitiveOption.checked,wholeWord:this.wholeWordOption.checked,preventScroll:n}),s=!i&&this.searchInput.value;r.setCssClass(this.searchBox,"ace_nomatch",s),this.editor._emit("findSearchBox",{match:!s}),this.highlight()},this.findNext=function(){this.find(!0,!1)},this.findPrev=function(){this.find(!0,!0)},this.findAll=function(){var e=this.editor.findAll(this.searchInput.value,{regExp:this.regExpOption.checked,caseSensitive:this.caseSensitiveOption.checked,wholeWord:this.wholeWordOption.checked}),t=!e&&this.searchInput.value;r.setCssClass(this.searchBox,"ace_nomatch",t),this.editor._emit("findSearchBox",{match:!t}),this.highlight(),this.hide()},this.replace=function(){this.editor.getReadOnly()||this.editor.replace(this.replaceInput.value)},this.replaceAndFindNext=function(){this.editor.getReadOnly()||(this.editor.replace(this.replaceInput.value),this.findNext())},this.replaceAll=function(){this.editor.getReadOnly()||this.editor.replaceAll(this.replaceInput.value)},this.hide=function(){this.element.style.display="none",this.editor.keyBinding.removeKeyboardHandler(this.$closeSearchBarKb),this.editor.focus()},this.show=function(e,t){this.element.style.display="",this.replaceBox.style.display=t?"":"none",this.isReplace=t,e&&(this.searchInput.value=e),this.find(!1,!1,!0),this.searchInput.focus(),this.searchInput.select(),this.editor.keyBinding.addKeyboardHandler(this.$closeSearchBarKb)},this.isFocused=function(){var e=document.activeElement;return e==this.searchInput||e==this.replaceInput}}).call(l.prototype),t.SearchBox=l,t.Search=function(e,t){var n=e.searchBox||new l(e);n.show(e.session.getTextRange(),t)}}); - (function() { - window.require(["ace/ext/searchbox"], function() {}); - })(); - \ No newline at end of file diff --git a/examples/SmartSwitch/data_src/js_css_src/ace-drafts/mode-css.js b/examples/SmartSwitch/data_src/js_css_src/ace-drafts/mode-css.js deleted file mode 100644 index b41ecdc82..000000000 --- a/examples/SmartSwitch/data_src/js_css_src/ace-drafts/mode-css.js +++ /dev/null @@ -1 +0,0 @@ -define("ace/mode/css_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./text_highlight_rules").TextHighlightRules,o=t.supportType="align-content|align-items|align-self|all|animation|animation-delay|animation-direction|animation-duration|animation-fill-mode|animation-iteration-count|animation-name|animation-play-state|animation-timing-function|backface-visibility|background|background-attachment|background-blend-mode|background-clip|background-color|background-image|background-origin|background-position|background-repeat|background-size|border|border-bottom|border-bottom-color|border-bottom-left-radius|border-bottom-right-radius|border-bottom-style|border-bottom-width|border-collapse|border-color|border-image|border-image-outset|border-image-repeat|border-image-slice|border-image-source|border-image-width|border-left|border-left-color|border-left-style|border-left-width|border-radius|border-right|border-right-color|border-right-style|border-right-width|border-spacing|border-style|border-top|border-top-color|border-top-left-radius|border-top-right-radius|border-top-style|border-top-width|border-width|bottom|box-shadow|box-sizing|caption-side|clear|clip|color|column-count|column-fill|column-gap|column-rule|column-rule-color|column-rule-style|column-rule-width|column-span|column-width|columns|content|counter-increment|counter-reset|cursor|direction|display|empty-cells|filter|flex|flex-basis|flex-direction|flex-flow|flex-grow|flex-shrink|flex-wrap|float|font|font-family|font-size|font-size-adjust|font-stretch|font-style|font-variant|font-weight|hanging-punctuation|height|justify-content|left|letter-spacing|line-height|list-style|list-style-image|list-style-position|list-style-type|margin|margin-bottom|margin-left|margin-right|margin-top|max-height|max-width|min-height|min-width|nav-down|nav-index|nav-left|nav-right|nav-up|opacity|order|outline|outline-color|outline-offset|outline-style|outline-width|overflow|overflow-x|overflow-y|padding|padding-bottom|padding-left|padding-right|padding-top|page-break-after|page-break-before|page-break-inside|perspective|perspective-origin|position|quotes|resize|right|tab-size|table-layout|text-align|text-align-last|text-decoration|text-decoration-color|text-decoration-line|text-decoration-style|text-indent|text-justify|text-overflow|text-shadow|text-transform|top|transform|transform-origin|transform-style|transition|transition-delay|transition-duration|transition-property|transition-timing-function|unicode-bidi|vertical-align|visibility|white-space|width|word-break|word-spacing|word-wrap|z-index",u=t.supportFunction="rgb|rgba|url|attr|counter|counters",a=t.supportConstant="absolute|after-edge|after|all-scroll|all|alphabetic|always|antialiased|armenian|auto|avoid-column|avoid-page|avoid|balance|baseline|before-edge|before|below|bidi-override|block-line-height|block|bold|bolder|border-box|both|bottom|box|break-all|break-word|capitalize|caps-height|caption|center|central|char|circle|cjk-ideographic|clone|close-quote|col-resize|collapse|column|consider-shifts|contain|content-box|cover|crosshair|cubic-bezier|dashed|decimal-leading-zero|decimal|default|disabled|disc|disregard-shifts|distribute-all-lines|distribute-letter|distribute-space|distribute|dotted|double|e-resize|ease-in|ease-in-out|ease-out|ease|ellipsis|end|exclude-ruby|fill|fixed|georgian|glyphs|grid-height|groove|hand|hanging|hebrew|help|hidden|hiragana-iroha|hiragana|horizontal|icon|ideograph-alpha|ideograph-numeric|ideograph-parenthesis|ideograph-space|ideographic|inactive|include-ruby|inherit|initial|inline-block|inline-box|inline-line-height|inline-table|inline|inset|inside|inter-ideograph|inter-word|invert|italic|justify|katakana-iroha|katakana|keep-all|last|left|lighter|line-edge|line-through|line|linear|list-item|local|loose|lower-alpha|lower-greek|lower-latin|lower-roman|lowercase|lr-tb|ltr|mathematical|max-height|max-size|medium|menu|message-box|middle|move|n-resize|ne-resize|newspaper|no-change|no-close-quote|no-drop|no-open-quote|no-repeat|none|normal|not-allowed|nowrap|nw-resize|oblique|open-quote|outset|outside|overline|padding-box|page|pointer|pre-line|pre-wrap|pre|preserve-3d|progress|relative|repeat-x|repeat-y|repeat|replaced|reset-size|ridge|right|round|row-resize|rtl|s-resize|scroll|se-resize|separate|slice|small-caps|small-caption|solid|space|square|start|static|status-bar|step-end|step-start|steps|stretch|strict|sub|super|sw-resize|table-caption|table-cell|table-column-group|table-column|table-footer-group|table-header-group|table-row-group|table-row|table|tb-rl|text-after-edge|text-before-edge|text-bottom|text-size|text-top|text|thick|thin|transparent|underline|upper-alpha|upper-latin|upper-roman|uppercase|use-script|vertical-ideographic|vertical-text|visible|w-resize|wait|whitespace|z-index|zero",f=t.supportConstantColor="aqua|black|blue|fuchsia|gray|green|lime|maroon|navy|olive|orange|purple|red|silver|teal|white|yellow",l=t.supportConstantFonts="arial|century|comic|courier|cursive|fantasy|garamond|georgia|helvetica|impact|lucida|symbol|system|tahoma|times|trebuchet|utopia|verdana|webdings|sans-serif|serif|monospace",c=t.numRe="\\-?(?:(?:[0-9]+)|(?:[0-9]*\\.[0-9]+))",h=t.pseudoElements="(\\:+)\\b(after|before|first-letter|first-line|moz-selection|selection)\\b",p=t.pseudoClasses="(:)\\b(active|checked|disabled|empty|enabled|first-child|first-of-type|focus|hover|indeterminate|invalid|last-child|last-of-type|link|not|nth-child|nth-last-child|nth-last-of-type|nth-of-type|only-child|only-of-type|required|root|target|valid|visited)\\b",d=function(){var e=this.createKeywordMapper({"support.function":u,"support.constant":a,"support.type":o,"support.constant.color":f,"support.constant.fonts":l},"text",!0);this.$rules={start:[{token:"comment",regex:"\\/\\*",push:"comment"},{token:"paren.lparen",regex:"\\{",push:"ruleset"},{token:"string",regex:"@.*?{",push:"media"},{token:"keyword",regex:"#[a-z0-9-_]+"},{token:"variable",regex:"\\.[a-z0-9-_]+"},{token:"string",regex:":[a-z0-9-_]+"},{token:"constant",regex:"[a-z0-9-_]+"},{caseInsensitive:!0}],media:[{token:"comment",regex:"\\/\\*",push:"comment"},{token:"paren.lparen",regex:"\\{",push:"ruleset"},{token:"string",regex:"\\}",next:"pop"},{token:"keyword",regex:"#[a-z0-9-_]+"},{token:"variable",regex:"\\.[a-z0-9-_]+"},{token:"string",regex:":[a-z0-9-_]+"},{token:"constant",regex:"[a-z0-9-_]+"},{caseInsensitive:!0}],comment:[{token:"comment",regex:"\\*\\/",next:"pop"},{defaultToken:"comment"}],ruleset:[{token:"paren.rparen",regex:"\\}",next:"pop"},{token:"comment",regex:"\\/\\*",push:"comment"},{token:"string",regex:'["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]'},{token:"string",regex:"['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']"},{token:["constant.numeric","keyword"],regex:"("+c+")(ch|cm|deg|em|ex|fr|gd|grad|Hz|in|kHz|mm|ms|pc|pt|px|rad|rem|s|turn|vh|vm|vw|%)"},{token:"constant.numeric",regex:c},{token:"constant.numeric",regex:"#[a-f0-9]{6}"},{token:"constant.numeric",regex:"#[a-f0-9]{3}"},{token:["punctuation","entity.other.attribute-name.pseudo-element.css"],regex:h},{token:["punctuation","entity.other.attribute-name.pseudo-class.css"],regex:p},{token:["support.function","string","support.function"],regex:"(url\\()(.*)(\\))"},{token:e,regex:"\\-?[a-zA-Z_][a-zA-Z0-9_\\-]*"},{caseInsensitive:!0}]},this.normalizeRules()};r.inherits(d,s),t.CssHighlightRules=d}),define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],function(e,t,n){"use strict";var r=e("../range").Range,i=function(){};(function(){this.checkOutdent=function(e,t){return/^\s+$/.test(e)?/^\s*\}/.test(t):!1},this.autoOutdent=function(e,t){var n=e.getLine(t),i=n.match(/^(\s*\})/);if(!i)return 0;var s=i[1].length,o=e.findMatchingBracket({row:t,column:s});if(!o||o.row==t)return 0;var u=this.$getIndent(e.getLine(o.row));e.replace(new r(t,0,t,s-1),u)},this.$getIndent=function(e){return e.match(/^\s*/)[0]}}).call(i.prototype),t.MatchingBraceOutdent=i}),define("ace/mode/css_completions",["require","exports","module"],function(e,t,n){"use strict";var r={background:{"#$0":1},"background-color":{"#$0":1,transparent:1,fixed:1},"background-image":{"url('/$0')":1},"background-repeat":{repeat:1,"repeat-x":1,"repeat-y":1,"no-repeat":1,inherit:1},"background-position":{bottom:2,center:2,left:2,right:2,top:2,inherit:2},"background-attachment":{scroll:1,fixed:1},"background-size":{cover:1,contain:1},"background-clip":{"border-box":1,"padding-box":1,"content-box":1},"background-origin":{"border-box":1,"padding-box":1,"content-box":1},border:{"solid $0":1,"dashed $0":1,"dotted $0":1,"#$0":1},"border-color":{"#$0":1},"border-style":{solid:2,dashed:2,dotted:2,"double":2,groove:2,hidden:2,inherit:2,inset:2,none:2,outset:2,ridged:2},"border-collapse":{collapse:1,separate:1},bottom:{px:1,em:1,"%":1},clear:{left:1,right:1,both:1,none:1},color:{"#$0":1,"rgb(#$00,0,0)":1},cursor:{"default":1,pointer:1,move:1,text:1,wait:1,help:1,progress:1,"n-resize":1,"ne-resize":1,"e-resize":1,"se-resize":1,"s-resize":1,"sw-resize":1,"w-resize":1,"nw-resize":1},display:{none:1,block:1,inline:1,"inline-block":1,"table-cell":1},"empty-cells":{show:1,hide:1},"float":{left:1,right:1,none:1},"font-family":{Arial:2,"Comic Sans MS":2,Consolas:2,"Courier New":2,Courier:2,Georgia:2,Monospace:2,"Sans-Serif":2,"Segoe UI":2,Tahoma:2,"Times New Roman":2,"Trebuchet MS":2,Verdana:1},"font-size":{px:1,em:1,"%":1},"font-weight":{bold:1,normal:1},"font-style":{italic:1,normal:1},"font-variant":{normal:1,"small-caps":1},height:{px:1,em:1,"%":1},left:{px:1,em:1,"%":1},"letter-spacing":{normal:1},"line-height":{normal:1},"list-style-type":{none:1,disc:1,circle:1,square:1,decimal:1,"decimal-leading-zero":1,"lower-roman":1,"upper-roman":1,"lower-greek":1,"lower-latin":1,"upper-latin":1,georgian:1,"lower-alpha":1,"upper-alpha":1},margin:{px:1,em:1,"%":1},"margin-right":{px:1,em:1,"%":1},"margin-left":{px:1,em:1,"%":1},"margin-top":{px:1,em:1,"%":1},"margin-bottom":{px:1,em:1,"%":1},"max-height":{px:1,em:1,"%":1},"max-width":{px:1,em:1,"%":1},"min-height":{px:1,em:1,"%":1},"min-width":{px:1,em:1,"%":1},overflow:{hidden:1,visible:1,auto:1,scroll:1},"overflow-x":{hidden:1,visible:1,auto:1,scroll:1},"overflow-y":{hidden:1,visible:1,auto:1,scroll:1},padding:{px:1,em:1,"%":1},"padding-top":{px:1,em:1,"%":1},"padding-right":{px:1,em:1,"%":1},"padding-bottom":{px:1,em:1,"%":1},"padding-left":{px:1,em:1,"%":1},"page-break-after":{auto:1,always:1,avoid:1,left:1,right:1},"page-break-before":{auto:1,always:1,avoid:1,left:1,right:1},position:{absolute:1,relative:1,fixed:1,"static":1},right:{px:1,em:1,"%":1},"table-layout":{fixed:1,auto:1},"text-decoration":{none:1,underline:1,"line-through":1,blink:1},"text-align":{left:1,right:1,center:1,justify:1},"text-transform":{capitalize:1,uppercase:1,lowercase:1,none:1},top:{px:1,em:1,"%":1},"vertical-align":{top:1,bottom:1},visibility:{hidden:1,visible:1},"white-space":{nowrap:1,normal:1,pre:1,"pre-line":1,"pre-wrap":1},width:{px:1,em:1,"%":1},"word-spacing":{normal:1},filter:{"alpha(opacity=$0100)":1},"text-shadow":{"$02px 2px 2px #777":1},"text-overflow":{"ellipsis-word":1,clip:1,ellipsis:1},"-moz-border-radius":1,"-moz-border-radius-topright":1,"-moz-border-radius-bottomright":1,"-moz-border-radius-topleft":1,"-moz-border-radius-bottomleft":1,"-webkit-border-radius":1,"-webkit-border-top-right-radius":1,"-webkit-border-top-left-radius":1,"-webkit-border-bottom-right-radius":1,"-webkit-border-bottom-left-radius":1,"-moz-box-shadow":1,"-webkit-box-shadow":1,transform:{"rotate($00deg)":1,"skew($00deg)":1},"-moz-transform":{"rotate($00deg)":1,"skew($00deg)":1},"-webkit-transform":{"rotate($00deg)":1,"skew($00deg)":1}},i=function(){};(function(){this.completionsDefined=!1,this.defineCompletions=function(){if(document){var e=document.createElement("c").style;for(var t in e){if(typeof e[t]!="string")continue;var n=t.replace(/[A-Z]/g,function(e){return"-"+e.toLowerCase()});r.hasOwnProperty(n)||(r[n]=1)}}this.completionsDefined=!0},this.getCompletions=function(e,t,n,r){this.completionsDefined||this.defineCompletions();var i=t.getTokenAt(n.row,n.column);if(!i)return[];if(e==="ruleset"){var s=t.getLine(n.row).substr(0,n.column);return/:[^;]+$/.test(s)?(/([\w\-]+):[^:]*$/.test(s),this.getPropertyValueCompletions(e,t,n,r)):this.getPropertyCompletions(e,t,n,r)}return[]},this.getPropertyCompletions=function(e,t,n,i){var s=Object.keys(r);return s.map(function(e){return{caption:e,snippet:e+": $0",meta:"property",score:Number.MAX_VALUE}})},this.getPropertyValueCompletions=function(e,t,n,i){var s=t.getLine(n.row).substr(0,n.column),o=(/([\w\-]+):[^:]*$/.exec(s)||{})[1];if(!o)return[];var u=[];return o in r&&typeof r[o]=="object"&&(u=Object.keys(r[o])),u.map(function(e){return{caption:e,snippet:e,meta:"property value",score:Number.MAX_VALUE}})}}).call(i.prototype),t.CssCompletions=i}),define("ace/mode/behaviour/css",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/mode/behaviour/cstyle","ace/token_iterator"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("./cstyle").CstyleBehaviour,o=e("../../token_iterator").TokenIterator,u=function(){this.inherit(s),this.add("colon","insertion",function(e,t,n,r,i){if(i===":"){var s=n.getCursorPosition(),u=new o(r,s.row,s.column),a=u.getCurrentToken();a&&a.value.match(/\s+/)&&(a=u.stepBackward());if(a&&a.type==="support.type"){var f=r.doc.getLine(s.row),l=f.substring(s.column,s.column+1);if(l===":")return{text:"",selection:[1,1]};if(!f.substring(s.column).match(/^\s*;/))return{text:":;",selection:[1,1]}}}}),this.add("colon","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s===":"){var u=n.getCursorPosition(),a=new o(r,u.row,u.column),f=a.getCurrentToken();f&&f.value.match(/\s+/)&&(f=a.stepBackward());if(f&&f.type==="support.type"){var l=r.doc.getLine(i.start.row),c=l.substring(i.end.column,i.end.column+1);if(c===";")return i.end.column++,i}}}),this.add("semicolon","insertion",function(e,t,n,r,i){if(i===";"){var s=n.getCursorPosition(),o=r.doc.getLine(s.row),u=o.substring(s.column,s.column+1);if(u===";")return{text:"",selection:[1,1]}}})};r.inherits(u,s),t.CssBehaviour=u}),define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../../range").Range,s=e("./fold_mode").FoldMode,o=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end)))};r.inherits(o,s),function(){this.foldingStartMarker=/(\{|\[)[^\}\]]*$|^\s*(\/\*)/,this.foldingStopMarker=/^[^\[\{]*(\}|\])|^[\s\*]*(\*\/)/,this.singleLineBlockCommentRe=/^\s*(\/\*).*\*\/\s*$/,this.tripleStarBlockCommentRe=/^\s*(\/\*\*\*).*\*\/\s*$/,this.startRegionRe=/^\s*(\/\*|\/\/)#?region\b/,this._getFoldWidgetBase=this.getFoldWidget,this.getFoldWidget=function(e,t,n){var r=e.getLine(n);if(this.singleLineBlockCommentRe.test(r)&&!this.startRegionRe.test(r)&&!this.tripleStarBlockCommentRe.test(r))return"";var i=this._getFoldWidgetBase(e,t,n);return!i&&this.startRegionRe.test(r)?"start":i},this.getFoldWidgetRange=function(e,t,n,r){var i=e.getLine(n);if(this.startRegionRe.test(i))return this.getCommentRegionBlock(e,i,n);var s=i.match(this.foldingStartMarker);if(s){var o=s.index;if(s[1])return this.openingBracketBlock(e,s[1],n,o);var u=e.getCommentFoldRange(n,o+s[0].length,1);return u&&!u.isMultiLine()&&(r?u=this.getSectionRange(e,n):t!="all"&&(u=null)),u}if(t==="markbegin")return;var s=i.match(this.foldingStopMarker);if(s){var o=s.index+s[0].length;return s[1]?this.closingBracketBlock(e,s[1],n,o):e.getCommentFoldRange(n,o,-1)}},this.getSectionRange=function(e,t){var n=e.getLine(t),r=n.search(/\S/),s=t,o=n.length;t+=1;var u=t,a=e.getLength();while(++tf)break;var l=this.getFoldWidgetRange(e,"all",t);if(l){if(l.start.row<=s)break;if(l.isMultiLine())t=l.end.row;else if(r==f)break}u=t}return new i(s,o,u,e.getLine(u).length)},this.getCommentRegionBlock=function(e,t,n){var r=t.search(/\s*$/),s=e.getLength(),o=n,u=/^\s*(?:\/\*|\/\/|--)#?(end)?region\b/,a=1;while(++no)return new i(o,r,l,t.length)}}.call(o.prototype)}),define("ace/mode/css",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/css_highlight_rules","ace/mode/matching_brace_outdent","ace/worker/worker_client","ace/mode/css_completions","ace/mode/behaviour/css","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./css_highlight_rules").CssHighlightRules,o=e("./matching_brace_outdent").MatchingBraceOutdent,u=e("../worker/worker_client").WorkerClient,a=e("./css_completions").CssCompletions,f=e("./behaviour/css").CssBehaviour,l=e("./folding/cstyle").FoldMode,c=function(){this.HighlightRules=s,this.$outdent=new o,this.$behaviour=new f,this.$completer=new a,this.foldingRules=new l};r.inherits(c,i),function(){this.foldingRules="cStyle",this.blockComment={start:"/*",end:"*/"},this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),i=this.getTokenizer().getLineTokens(t,e).tokens;if(i.length&&i[i.length-1].type=="comment")return r;var s=t.match(/^.*\{\s*$/);return s&&(r+=n),r},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.getCompletions=function(e,t,n,r){return this.$completer.getCompletions(e,t,n,r)},this.createWorker=function(e){var t=new u(["ace"],"ace/mode/css_worker","Worker");return t.attachToDocument(e.getDocument()),t.on("annotate",function(t){e.setAnnotations(t.data)}),t.on("terminate",function(){e.clearAnnotations()}),t},this.$id="ace/mode/css"}.call(c.prototype),t.Mode=c}) \ No newline at end of file diff --git a/examples/SmartSwitch/data_src/js_css_src/ace-drafts/mode-html.js b/examples/SmartSwitch/data_src/js_css_src/ace-drafts/mode-html.js deleted file mode 100644 index faee4472e..000000000 --- a/examples/SmartSwitch/data_src/js_css_src/ace-drafts/mode-html.js +++ /dev/null @@ -1 +0,0 @@ -define("ace/mode/doc_comment_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){this.$rules={start:[{token:"comment.doc.tag",regex:"@[\\w\\d_]+"},s.getTagRule(),{defaultToken:"comment.doc",caseInsensitive:!0}]}};r.inherits(s,i),s.getTagRule=function(e){return{token:"comment.doc.tag.storage.type",regex:"\\b(?:TODO|FIXME|XXX|HACK)\\b"}},s.getStartRule=function(e){return{token:"comment.doc",regex:"\\/\\*(?=\\*)",next:e}},s.getEndRule=function(e){return{token:"comment.doc",regex:"\\*\\/",next:e}},t.DocCommentHighlightRules=s}),define("ace/mode/javascript_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/doc_comment_highlight_rules","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";function a(){var e=o.replace("\\d","\\d\\-"),t={onMatch:function(e,t,n){var r=e.charAt(1)=="/"?2:1;if(r==1)t!=this.nextState?n.unshift(this.next,this.nextState,0):n.unshift(this.next),n[2]++;else if(r==2&&t==this.nextState){n[1]--;if(!n[1]||n[1]<0)n.shift(),n.shift()}return[{type:"meta.tag.punctuation."+(r==1?"":"end-")+"tag-open.xml",value:e.slice(0,r)},{type:"meta.tag.tag-name.xml",value:e.substr(r)}]},regex:"",onMatch:function(e,t,n){return t==n[0]&&n.shift(),e.length==2&&(n[0]==this.nextState&&n[1]--,(!n[1]||n[1]<0)&&n.splice(0,2)),this.next=n[0]||"start",[{type:this.token,value:e}]},nextState:"jsx"},n,f("jsxAttributes"),{token:"entity.other.attribute-name.xml",regex:e},{token:"keyword.operator.attribute-equals.xml",regex:"="},{token:"text.tag-whitespace.xml",regex:"\\s+"},{token:"string.attribute-value.xml",regex:"'",stateName:"jsx_attr_q",push:[{token:"string.attribute-value.xml",regex:"'",next:"pop"},{include:"reference"},{defaultToken:"string.attribute-value.xml"}]},{token:"string.attribute-value.xml",regex:'"',stateName:"jsx_attr_qq",push:[{token:"string.attribute-value.xml",regex:'"',next:"pop"},{include:"reference"},{defaultToken:"string.attribute-value.xml"}]},t],this.$rules.reference=[{token:"constant.language.escape.reference.xml",regex:"(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)"}]}function f(e){return[{token:"comment",regex:/\/\*/,next:[i.getTagRule(),{token:"comment",regex:"\\*\\/",next:e||"pop"},{defaultToken:"comment",caseInsensitive:!0}]},{token:"comment",regex:"\\/\\/",next:[i.getTagRule(),{token:"comment",regex:"$|^",next:e||"pop"},{defaultToken:"comment",caseInsensitive:!0}]}]}var r=e("../lib/oop"),i=e("./doc_comment_highlight_rules").DocCommentHighlightRules,s=e("./text_highlight_rules").TextHighlightRules,o="[a-zA-Z\\$_\u00a1-\uffff][a-zA-Z\\d\\$_\u00a1-\uffff]*",u=function(e){var t=this.createKeywordMapper({"variable.language":"Array|Boolean|Date|Function|Iterator|Number|Object|RegExp|String|Proxy|Namespace|QName|XML|XMLList|ArrayBuffer|Float32Array|Float64Array|Int16Array|Int32Array|Int8Array|Uint16Array|Uint32Array|Uint8Array|Uint8ClampedArray|Error|EvalError|InternalError|RangeError|ReferenceError|StopIteration|SyntaxError|TypeError|URIError|decodeURI|decodeURIComponent|encodeURI|encodeURIComponent|eval|isFinite|isNaN|parseFloat|parseInt|JSON|Math|this|arguments|prototype|window|document",keyword:"const|yield|import|get|set|async|await|break|case|catch|continue|default|delete|do|else|finally|for|function|if|in|of|instanceof|new|return|switch|throw|try|typeof|let|var|while|with|debugger|__parent__|__count__|escape|unescape|with|__proto__|class|enum|extends|super|export|implements|private|public|interface|package|protected|static","storage.type":"const|let|var|function","constant.language":"null|Infinity|NaN|undefined","support.function":"alert","constant.language.boolean":"true|false"},"identifier"),n="case|do|else|finally|in|instanceof|return|throw|try|typeof|yield|void",r="\\\\(?:x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|u{[0-9a-fA-F]{1,6}}|[0-2][0-7]{0,2}|3[0-7][0-7]?|[4-7][0-7]?|.)";this.$rules={no_regex:[i.getStartRule("doc-start"),f("no_regex"),{token:"string",regex:"'(?=.)",next:"qstring"},{token:"string",regex:'"(?=.)',next:"qqstring"},{token:"constant.numeric",regex:/0(?:[xX][0-9a-fA-F]+|[bB][01]+)\b/},{token:"constant.numeric",regex:/[+-]?\d[\d_]*(?:(?:\.\d*)?(?:[eE][+-]?\d+)?)?\b/},{token:["storage.type","punctuation.operator","support.function","punctuation.operator","entity.name.function","text","keyword.operator"],regex:"("+o+")(\\.)(prototype)(\\.)("+o+")(\\s*)(=)",next:"function_arguments"},{token:["storage.type","punctuation.operator","entity.name.function","text","keyword.operator","text","storage.type","text","paren.lparen"],regex:"("+o+")(\\.)("+o+")(\\s*)(=)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["entity.name.function","text","keyword.operator","text","storage.type","text","paren.lparen"],regex:"("+o+")(\\s*)(=)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["storage.type","punctuation.operator","entity.name.function","text","keyword.operator","text","storage.type","text","entity.name.function","text","paren.lparen"],regex:"("+o+")(\\.)("+o+")(\\s*)(=)(\\s*)(function)(\\s+)(\\w+)(\\s*)(\\()",next:"function_arguments"},{token:["storage.type","text","entity.name.function","text","paren.lparen"],regex:"(function)(\\s+)("+o+")(\\s*)(\\()",next:"function_arguments"},{token:["entity.name.function","text","punctuation.operator","text","storage.type","text","paren.lparen"],regex:"("+o+")(\\s*)(:)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["text","text","storage.type","text","paren.lparen"],regex:"(:)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:"keyword",regex:"(?:"+n+")\\b",next:"start"},{token:["support.constant"],regex:/that\b/},{token:["storage.type","punctuation.operator","support.function.firebug"],regex:/(console)(\.)(warn|info|log|error|time|trace|timeEnd|assert)\b/},{token:t,regex:o},{token:"punctuation.operator",regex:/[.](?![.])/,next:"property"},{token:"keyword.operator",regex:/--|\+\+|\.{3}|===|==|=|!=|!==|<+=?|>+=?|!|&&|\|\||\?:|[!$%&*+\-~\/^]=?/,next:"start"},{token:"punctuation.operator",regex:/[?:,;.]/,next:"start"},{token:"paren.lparen",regex:/[\[({]/,next:"start"},{token:"paren.rparen",regex:/[\])}]/},{token:"comment",regex:/^#!.*$/}],property:[{token:"text",regex:"\\s+"},{token:["storage.type","punctuation.operator","entity.name.function","text","keyword.operator","text","storage.type","text","entity.name.function","text","paren.lparen"],regex:"("+o+")(\\.)("+o+")(\\s*)(=)(\\s*)(function)(?:(\\s+)(\\w+))?(\\s*)(\\()",next:"function_arguments"},{token:"punctuation.operator",regex:/[.](?![.])/},{token:"support.function",regex:/(s(?:h(?:ift|ow(?:Mod(?:elessDialog|alDialog)|Help))|croll(?:X|By(?:Pages|Lines)?|Y|To)?|t(?:op|rike)|i(?:n|zeToContent|debar|gnText)|ort|u(?:p|b(?:str(?:ing)?)?)|pli(?:ce|t)|e(?:nd|t(?:Re(?:sizable|questHeader)|M(?:i(?:nutes|lliseconds)|onth)|Seconds|Ho(?:tKeys|urs)|Year|Cursor|Time(?:out)?|Interval|ZOptions|Date|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Date|FullYear)|FullYear|Active)|arch)|qrt|lice|avePreferences|mall)|h(?:ome|andleEvent)|navigate|c(?:har(?:CodeAt|At)|o(?:s|n(?:cat|textual|firm)|mpile)|eil|lear(?:Timeout|Interval)?|a(?:ptureEvents|ll)|reate(?:StyleSheet|Popup|EventObject))|t(?:o(?:GMTString|S(?:tring|ource)|U(?:TCString|pperCase)|Lo(?:caleString|werCase))|est|a(?:n|int(?:Enabled)?))|i(?:s(?:NaN|Finite)|ndexOf|talics)|d(?:isableExternalCapture|ump|etachEvent)|u(?:n(?:shift|taint|escape|watch)|pdateCommands)|j(?:oin|avaEnabled)|p(?:o(?:p|w)|ush|lugins.refresh|a(?:ddings|rse(?:Int|Float)?)|r(?:int|ompt|eference))|e(?:scape|nableExternalCapture|val|lementFromPoint|x(?:p|ec(?:Script|Command)?))|valueOf|UTC|queryCommand(?:State|Indeterm|Enabled|Value)|f(?:i(?:nd|le(?:ModifiedDate|Size|CreatedDate|UpdatedDate)|xed)|o(?:nt(?:size|color)|rward)|loor|romCharCode)|watch|l(?:ink|o(?:ad|g)|astIndexOf)|a(?:sin|nchor|cos|t(?:tachEvent|ob|an(?:2)?)|pply|lert|b(?:s|ort))|r(?:ou(?:nd|teEvents)|e(?:size(?:By|To)|calc|turnValue|place|verse|l(?:oad|ease(?:Capture|Events)))|andom)|g(?:o|et(?:ResponseHeader|M(?:i(?:nutes|lliseconds)|onth)|Se(?:conds|lection)|Hours|Year|Time(?:zoneOffset)?|Da(?:y|te)|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Da(?:y|te)|FullYear)|FullYear|A(?:ttention|llResponseHeaders)))|m(?:in|ove(?:B(?:y|elow)|To(?:Absolute)?|Above)|ergeAttributes|a(?:tch|rgins|x))|b(?:toa|ig|o(?:ld|rderWidths)|link|ack))\b(?=\()/},{token:"support.function.dom",regex:/(s(?:ub(?:stringData|mit)|plitText|e(?:t(?:NamedItem|Attribute(?:Node)?)|lect))|has(?:ChildNodes|Feature)|namedItem|c(?:l(?:ick|o(?:se|neNode))|reate(?:C(?:omment|DATASection|aption)|T(?:Head|extNode|Foot)|DocumentFragment|ProcessingInstruction|E(?:ntityReference|lement)|Attribute))|tabIndex|i(?:nsert(?:Row|Before|Cell|Data)|tem)|open|delete(?:Row|C(?:ell|aption)|T(?:Head|Foot)|Data)|focus|write(?:ln)?|a(?:dd|ppend(?:Child|Data))|re(?:set|place(?:Child|Data)|move(?:NamedItem|Child|Attribute(?:Node)?)?)|get(?:NamedItem|Element(?:sBy(?:Name|TagName|ClassName)|ById)|Attribute(?:Node)?)|blur)\b(?=\()/},{token:"support.constant",regex:/(s(?:ystemLanguage|cr(?:ipts|ollbars|een(?:X|Y|Top|Left))|t(?:yle(?:Sheets)?|atus(?:Text|bar)?)|ibling(?:Below|Above)|ource|uffixes|e(?:curity(?:Policy)?|l(?:ection|f)))|h(?:istory|ost(?:name)?|as(?:h|Focus))|y|X(?:MLDocument|SLDocument)|n(?:ext|ame(?:space(?:s|URI)|Prop))|M(?:IN_VALUE|AX_VALUE)|c(?:haracterSet|o(?:n(?:structor|trollers)|okieEnabled|lorDepth|mp(?:onents|lete))|urrent|puClass|l(?:i(?:p(?:boardData)?|entInformation)|osed|asses)|alle(?:e|r)|rypto)|t(?:o(?:olbar|p)|ext(?:Transform|Indent|Decoration|Align)|ags)|SQRT(?:1_2|2)|i(?:n(?:ner(?:Height|Width)|put)|ds|gnoreCase)|zIndex|o(?:scpu|n(?:readystatechange|Line)|uter(?:Height|Width)|p(?:sProfile|ener)|ffscreenBuffering)|NEGATIVE_INFINITY|d(?:i(?:splay|alog(?:Height|Top|Width|Left|Arguments)|rectories)|e(?:scription|fault(?:Status|Ch(?:ecked|arset)|View)))|u(?:ser(?:Profile|Language|Agent)|n(?:iqueID|defined)|pdateInterval)|_content|p(?:ixelDepth|ort|ersonalbar|kcs11|l(?:ugins|atform)|a(?:thname|dding(?:Right|Bottom|Top|Left)|rent(?:Window|Layer)?|ge(?:X(?:Offset)?|Y(?:Offset)?))|r(?:o(?:to(?:col|type)|duct(?:Sub)?|mpter)|e(?:vious|fix)))|e(?:n(?:coding|abledPlugin)|x(?:ternal|pando)|mbeds)|v(?:isibility|endor(?:Sub)?|Linkcolor)|URLUnencoded|P(?:I|OSITIVE_INFINITY)|f(?:ilename|o(?:nt(?:Size|Family|Weight)|rmName)|rame(?:s|Element)|gColor)|E|whiteSpace|l(?:i(?:stStyleType|n(?:eHeight|kColor))|o(?:ca(?:tion(?:bar)?|lName)|wsrc)|e(?:ngth|ft(?:Context)?)|a(?:st(?:M(?:odified|atch)|Index|Paren)|yer(?:s|X)|nguage))|a(?:pp(?:MinorVersion|Name|Co(?:deName|re)|Version)|vail(?:Height|Top|Width|Left)|ll|r(?:ity|guments)|Linkcolor|bove)|r(?:ight(?:Context)?|e(?:sponse(?:XML|Text)|adyState))|global|x|m(?:imeTypes|ultiline|enubar|argin(?:Right|Bottom|Top|Left))|L(?:N(?:10|2)|OG(?:10E|2E))|b(?:o(?:ttom|rder(?:Width|RightWidth|BottomWidth|Style|Color|TopWidth|LeftWidth))|ufferDepth|elow|ackground(?:Color|Image)))\b/},{token:"identifier",regex:o},{regex:"",token:"empty",next:"no_regex"}],start:[i.getStartRule("doc-start"),f("start"),{token:"string.regexp",regex:"\\/",next:"regex"},{token:"text",regex:"\\s+|^$",next:"start"},{token:"empty",regex:"",next:"no_regex"}],regex:[{token:"regexp.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"string.regexp",regex:"/[sxngimy]*",next:"no_regex"},{token:"invalid",regex:/\{\d+\b,?\d*\}[+*]|[+*$^?][+*]|[$^][?]|\?{3,}/},{token:"constant.language.escape",regex:/\(\?[:=!]|\)|\{\d+\b,?\d*\}|[+*]\?|[()$^+*?.]/},{token:"constant.language.delimiter",regex:/\|/},{token:"constant.language.escape",regex:/\[\^?/,next:"regex_character_class"},{token:"empty",regex:"$",next:"no_regex"},{defaultToken:"string.regexp"}],regex_character_class:[{token:"regexp.charclass.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"constant.language.escape",regex:"]",next:"regex"},{token:"constant.language.escape",regex:"-"},{token:"empty",regex:"$",next:"no_regex"},{defaultToken:"string.regexp.charachterclass"}],function_arguments:[{token:"variable.parameter",regex:o},{token:"punctuation.operator",regex:"[, ]+"},{token:"punctuation.operator",regex:"$"},{token:"empty",regex:"",next:"no_regex"}],qqstring:[{token:"constant.language.escape",regex:r},{token:"string",regex:"\\\\$",next:"qqstring"},{token:"string",regex:'"|$',next:"no_regex"},{defaultToken:"string"}],qstring:[{token:"constant.language.escape",regex:r},{token:"string",regex:"\\\\$",next:"qstring"},{token:"string",regex:"'|$",next:"no_regex"},{defaultToken:"string"}]};if(!e||!e.noES6)this.$rules.no_regex.unshift({regex:"[{}]",onMatch:function(e,t,n){this.next=e=="{"?this.nextState:"";if(e=="{"&&n.length)n.unshift("start",t);else if(e=="}"&&n.length){n.shift(),this.next=n.shift();if(this.next.indexOf("string")!=-1||this.next.indexOf("jsx")!=-1)return"paren.quasi.end"}return e=="{"?"paren.lparen":"paren.rparen"},nextState:"start"},{token:"string.quasi.start",regex:/`/,push:[{token:"constant.language.escape",regex:r},{token:"paren.quasi.start",regex:/\${/,push:"start"},{token:"string.quasi.end",regex:/`/,next:"pop"},{defaultToken:"string.quasi"}]}),(!e||e.jsx!=0)&&a.call(this);this.embedRules(i,"doc-",[i.getEndRule("no_regex")]),this.normalizeRules()};r.inherits(u,s),t.JavaScriptHighlightRules=u}),define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],function(e,t,n){"use strict";var r=e("../range").Range,i=function(){};(function(){this.checkOutdent=function(e,t){return/^\s+$/.test(e)?/^\s*\}/.test(t):!1},this.autoOutdent=function(e,t){var n=e.getLine(t),i=n.match(/^(\s*\})/);if(!i)return 0;var s=i[1].length,o=e.findMatchingBracket({row:t,column:s});if(!o||o.row==t)return 0;var u=this.$getIndent(e.getLine(o.row));e.replace(new r(t,0,t,s-1),u)},this.$getIndent=function(e){return e.match(/^\s*/)[0]}}).call(i.prototype),t.MatchingBraceOutdent=i}),define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../../range").Range,s=e("./fold_mode").FoldMode,o=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end)))};r.inherits(o,s),function(){this.foldingStartMarker=/(\{|\[)[^\}\]]*$|^\s*(\/\*)/,this.foldingStopMarker=/^[^\[\{]*(\}|\])|^[\s\*]*(\*\/)/,this.singleLineBlockCommentRe=/^\s*(\/\*).*\*\/\s*$/,this.tripleStarBlockCommentRe=/^\s*(\/\*\*\*).*\*\/\s*$/,this.startRegionRe=/^\s*(\/\*|\/\/)#?region\b/,this._getFoldWidgetBase=this.getFoldWidget,this.getFoldWidget=function(e,t,n){var r=e.getLine(n);if(this.singleLineBlockCommentRe.test(r)&&!this.startRegionRe.test(r)&&!this.tripleStarBlockCommentRe.test(r))return"";var i=this._getFoldWidgetBase(e,t,n);return!i&&this.startRegionRe.test(r)?"start":i},this.getFoldWidgetRange=function(e,t,n,r){var i=e.getLine(n);if(this.startRegionRe.test(i))return this.getCommentRegionBlock(e,i,n);var s=i.match(this.foldingStartMarker);if(s){var o=s.index;if(s[1])return this.openingBracketBlock(e,s[1],n,o);var u=e.getCommentFoldRange(n,o+s[0].length,1);return u&&!u.isMultiLine()&&(r?u=this.getSectionRange(e,n):t!="all"&&(u=null)),u}if(t==="markbegin")return;var s=i.match(this.foldingStopMarker);if(s){var o=s.index+s[0].length;return s[1]?this.closingBracketBlock(e,s[1],n,o):e.getCommentFoldRange(n,o,-1)}},this.getSectionRange=function(e,t){var n=e.getLine(t),r=n.search(/\S/),s=t,o=n.length;t+=1;var u=t,a=e.getLength();while(++tf)break;var l=this.getFoldWidgetRange(e,"all",t);if(l){if(l.start.row<=s)break;if(l.isMultiLine())t=l.end.row;else if(r==f)break}u=t}return new i(s,o,u,e.getLine(u).length)},this.getCommentRegionBlock=function(e,t,n){var r=t.search(/\s*$/),s=e.getLength(),o=n,u=/^\s*(?:\/\*|\/\/|--)#?(end)?region\b/,a=1;while(++no)return new i(o,r,l,t.length)}}.call(o.prototype)}),define("ace/mode/javascript",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/javascript_highlight_rules","ace/mode/matching_brace_outdent","ace/worker/worker_client","ace/mode/behaviour/cstyle","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./javascript_highlight_rules").JavaScriptHighlightRules,o=e("./matching_brace_outdent").MatchingBraceOutdent,u=e("../worker/worker_client").WorkerClient,a=e("./behaviour/cstyle").CstyleBehaviour,f=e("./folding/cstyle").FoldMode,l=function(){this.HighlightRules=s,this.$outdent=new o,this.$behaviour=new a,this.foldingRules=new f};r.inherits(l,i),function(){this.lineCommentStart="//",this.blockComment={start:"/*",end:"*/"},this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),i=this.getTokenizer().getLineTokens(t,e),s=i.tokens,o=i.state;if(s.length&&s[s.length-1].type=="comment")return r;if(e=="start"||e=="no_regex"){var u=t.match(/^.*(?:\bcase\b.*:|[\{\(\[])\s*$/);u&&(r+=n)}else if(e=="doc-start"){if(o=="start"||o=="no_regex")return"";var u=t.match(/^\s*(\/?)\*/);u&&(u[1]&&(r+=" "),r+="* ")}return r},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.createWorker=function(e){var t=new u(["ace"],"ace/mode/javascript_worker","JavaScriptWorker");return t.attachToDocument(e.getDocument()),t.on("annotate",function(t){e.setAnnotations(t.data)}),t.on("terminate",function(){e.clearAnnotations()}),t},this.$id="ace/mode/javascript"}.call(l.prototype),t.Mode=l}),define("ace/mode/css_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./text_highlight_rules").TextHighlightRules,o=t.supportType="align-content|align-items|align-self|all|animation|animation-delay|animation-direction|animation-duration|animation-fill-mode|animation-iteration-count|animation-name|animation-play-state|animation-timing-function|backface-visibility|background|background-attachment|background-blend-mode|background-clip|background-color|background-image|background-origin|background-position|background-repeat|background-size|border|border-bottom|border-bottom-color|border-bottom-left-radius|border-bottom-right-radius|border-bottom-style|border-bottom-width|border-collapse|border-color|border-image|border-image-outset|border-image-repeat|border-image-slice|border-image-source|border-image-width|border-left|border-left-color|border-left-style|border-left-width|border-radius|border-right|border-right-color|border-right-style|border-right-width|border-spacing|border-style|border-top|border-top-color|border-top-left-radius|border-top-right-radius|border-top-style|border-top-width|border-width|bottom|box-shadow|box-sizing|caption-side|clear|clip|color|column-count|column-fill|column-gap|column-rule|column-rule-color|column-rule-style|column-rule-width|column-span|column-width|columns|content|counter-increment|counter-reset|cursor|direction|display|empty-cells|filter|flex|flex-basis|flex-direction|flex-flow|flex-grow|flex-shrink|flex-wrap|float|font|font-family|font-size|font-size-adjust|font-stretch|font-style|font-variant|font-weight|hanging-punctuation|height|justify-content|left|letter-spacing|line-height|list-style|list-style-image|list-style-position|list-style-type|margin|margin-bottom|margin-left|margin-right|margin-top|max-height|max-width|min-height|min-width|nav-down|nav-index|nav-left|nav-right|nav-up|opacity|order|outline|outline-color|outline-offset|outline-style|outline-width|overflow|overflow-x|overflow-y|padding|padding-bottom|padding-left|padding-right|padding-top|page-break-after|page-break-before|page-break-inside|perspective|perspective-origin|position|quotes|resize|right|tab-size|table-layout|text-align|text-align-last|text-decoration|text-decoration-color|text-decoration-line|text-decoration-style|text-indent|text-justify|text-overflow|text-shadow|text-transform|top|transform|transform-origin|transform-style|transition|transition-delay|transition-duration|transition-property|transition-timing-function|unicode-bidi|vertical-align|visibility|white-space|width|word-break|word-spacing|word-wrap|z-index",u=t.supportFunction="rgb|rgba|url|attr|counter|counters",a=t.supportConstant="absolute|after-edge|after|all-scroll|all|alphabetic|always|antialiased|armenian|auto|avoid-column|avoid-page|avoid|balance|baseline|before-edge|before|below|bidi-override|block-line-height|block|bold|bolder|border-box|both|bottom|box|break-all|break-word|capitalize|caps-height|caption|center|central|char|circle|cjk-ideographic|clone|close-quote|col-resize|collapse|column|consider-shifts|contain|content-box|cover|crosshair|cubic-bezier|dashed|decimal-leading-zero|decimal|default|disabled|disc|disregard-shifts|distribute-all-lines|distribute-letter|distribute-space|distribute|dotted|double|e-resize|ease-in|ease-in-out|ease-out|ease|ellipsis|end|exclude-ruby|fill|fixed|georgian|glyphs|grid-height|groove|hand|hanging|hebrew|help|hidden|hiragana-iroha|hiragana|horizontal|icon|ideograph-alpha|ideograph-numeric|ideograph-parenthesis|ideograph-space|ideographic|inactive|include-ruby|inherit|initial|inline-block|inline-box|inline-line-height|inline-table|inline|inset|inside|inter-ideograph|inter-word|invert|italic|justify|katakana-iroha|katakana|keep-all|last|left|lighter|line-edge|line-through|line|linear|list-item|local|loose|lower-alpha|lower-greek|lower-latin|lower-roman|lowercase|lr-tb|ltr|mathematical|max-height|max-size|medium|menu|message-box|middle|move|n-resize|ne-resize|newspaper|no-change|no-close-quote|no-drop|no-open-quote|no-repeat|none|normal|not-allowed|nowrap|nw-resize|oblique|open-quote|outset|outside|overline|padding-box|page|pointer|pre-line|pre-wrap|pre|preserve-3d|progress|relative|repeat-x|repeat-y|repeat|replaced|reset-size|ridge|right|round|row-resize|rtl|s-resize|scroll|se-resize|separate|slice|small-caps|small-caption|solid|space|square|start|static|status-bar|step-end|step-start|steps|stretch|strict|sub|super|sw-resize|table-caption|table-cell|table-column-group|table-column|table-footer-group|table-header-group|table-row-group|table-row|table|tb-rl|text-after-edge|text-before-edge|text-bottom|text-size|text-top|text|thick|thin|transparent|underline|upper-alpha|upper-latin|upper-roman|uppercase|use-script|vertical-ideographic|vertical-text|visible|w-resize|wait|whitespace|z-index|zero",f=t.supportConstantColor="aqua|black|blue|fuchsia|gray|green|lime|maroon|navy|olive|orange|purple|red|silver|teal|white|yellow",l=t.supportConstantFonts="arial|century|comic|courier|cursive|fantasy|garamond|georgia|helvetica|impact|lucida|symbol|system|tahoma|times|trebuchet|utopia|verdana|webdings|sans-serif|serif|monospace",c=t.numRe="\\-?(?:(?:[0-9]+)|(?:[0-9]*\\.[0-9]+))",h=t.pseudoElements="(\\:+)\\b(after|before|first-letter|first-line|moz-selection|selection)\\b",p=t.pseudoClasses="(:)\\b(active|checked|disabled|empty|enabled|first-child|first-of-type|focus|hover|indeterminate|invalid|last-child|last-of-type|link|not|nth-child|nth-last-child|nth-last-of-type|nth-of-type|only-child|only-of-type|required|root|target|valid|visited)\\b",d=function(){var e=this.createKeywordMapper({"support.function":u,"support.constant":a,"support.type":o,"support.constant.color":f,"support.constant.fonts":l},"text",!0);this.$rules={start:[{token:"comment",regex:"\\/\\*",push:"comment"},{token:"paren.lparen",regex:"\\{",push:"ruleset"},{token:"string",regex:"@.*?{",push:"media"},{token:"keyword",regex:"#[a-z0-9-_]+"},{token:"variable",regex:"\\.[a-z0-9-_]+"},{token:"string",regex:":[a-z0-9-_]+"},{token:"constant",regex:"[a-z0-9-_]+"},{caseInsensitive:!0}],media:[{token:"comment",regex:"\\/\\*",push:"comment"},{token:"paren.lparen",regex:"\\{",push:"ruleset"},{token:"string",regex:"\\}",next:"pop"},{token:"keyword",regex:"#[a-z0-9-_]+"},{token:"variable",regex:"\\.[a-z0-9-_]+"},{token:"string",regex:":[a-z0-9-_]+"},{token:"constant",regex:"[a-z0-9-_]+"},{caseInsensitive:!0}],comment:[{token:"comment",regex:"\\*\\/",next:"pop"},{defaultToken:"comment"}],ruleset:[{token:"paren.rparen",regex:"\\}",next:"pop"},{token:"comment",regex:"\\/\\*",push:"comment"},{token:"string",regex:'["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]'},{token:"string",regex:"['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']"},{token:["constant.numeric","keyword"],regex:"("+c+")(ch|cm|deg|em|ex|fr|gd|grad|Hz|in|kHz|mm|ms|pc|pt|px|rad|rem|s|turn|vh|vm|vw|%)"},{token:"constant.numeric",regex:c},{token:"constant.numeric",regex:"#[a-f0-9]{6}"},{token:"constant.numeric",regex:"#[a-f0-9]{3}"},{token:["punctuation","entity.other.attribute-name.pseudo-element.css"],regex:h},{token:["punctuation","entity.other.attribute-name.pseudo-class.css"],regex:p},{token:["support.function","string","support.function"],regex:"(url\\()(.*)(\\))"},{token:e,regex:"\\-?[a-zA-Z_][a-zA-Z0-9_\\-]*"},{caseInsensitive:!0}]},this.normalizeRules()};r.inherits(d,s),t.CssHighlightRules=d}),define("ace/mode/css_completions",["require","exports","module"],function(e,t,n){"use strict";var r={background:{"#$0":1},"background-color":{"#$0":1,transparent:1,fixed:1},"background-image":{"url('/$0')":1},"background-repeat":{repeat:1,"repeat-x":1,"repeat-y":1,"no-repeat":1,inherit:1},"background-position":{bottom:2,center:2,left:2,right:2,top:2,inherit:2},"background-attachment":{scroll:1,fixed:1},"background-size":{cover:1,contain:1},"background-clip":{"border-box":1,"padding-box":1,"content-box":1},"background-origin":{"border-box":1,"padding-box":1,"content-box":1},border:{"solid $0":1,"dashed $0":1,"dotted $0":1,"#$0":1},"border-color":{"#$0":1},"border-style":{solid:2,dashed:2,dotted:2,"double":2,groove:2,hidden:2,inherit:2,inset:2,none:2,outset:2,ridged:2},"border-collapse":{collapse:1,separate:1},bottom:{px:1,em:1,"%":1},clear:{left:1,right:1,both:1,none:1},color:{"#$0":1,"rgb(#$00,0,0)":1},cursor:{"default":1,pointer:1,move:1,text:1,wait:1,help:1,progress:1,"n-resize":1,"ne-resize":1,"e-resize":1,"se-resize":1,"s-resize":1,"sw-resize":1,"w-resize":1,"nw-resize":1},display:{none:1,block:1,inline:1,"inline-block":1,"table-cell":1},"empty-cells":{show:1,hide:1},"float":{left:1,right:1,none:1},"font-family":{Arial:2,"Comic Sans MS":2,Consolas:2,"Courier New":2,Courier:2,Georgia:2,Monospace:2,"Sans-Serif":2,"Segoe UI":2,Tahoma:2,"Times New Roman":2,"Trebuchet MS":2,Verdana:1},"font-size":{px:1,em:1,"%":1},"font-weight":{bold:1,normal:1},"font-style":{italic:1,normal:1},"font-variant":{normal:1,"small-caps":1},height:{px:1,em:1,"%":1},left:{px:1,em:1,"%":1},"letter-spacing":{normal:1},"line-height":{normal:1},"list-style-type":{none:1,disc:1,circle:1,square:1,decimal:1,"decimal-leading-zero":1,"lower-roman":1,"upper-roman":1,"lower-greek":1,"lower-latin":1,"upper-latin":1,georgian:1,"lower-alpha":1,"upper-alpha":1},margin:{px:1,em:1,"%":1},"margin-right":{px:1,em:1,"%":1},"margin-left":{px:1,em:1,"%":1},"margin-top":{px:1,em:1,"%":1},"margin-bottom":{px:1,em:1,"%":1},"max-height":{px:1,em:1,"%":1},"max-width":{px:1,em:1,"%":1},"min-height":{px:1,em:1,"%":1},"min-width":{px:1,em:1,"%":1},overflow:{hidden:1,visible:1,auto:1,scroll:1},"overflow-x":{hidden:1,visible:1,auto:1,scroll:1},"overflow-y":{hidden:1,visible:1,auto:1,scroll:1},padding:{px:1,em:1,"%":1},"padding-top":{px:1,em:1,"%":1},"padding-right":{px:1,em:1,"%":1},"padding-bottom":{px:1,em:1,"%":1},"padding-left":{px:1,em:1,"%":1},"page-break-after":{auto:1,always:1,avoid:1,left:1,right:1},"page-break-before":{auto:1,always:1,avoid:1,left:1,right:1},position:{absolute:1,relative:1,fixed:1,"static":1},right:{px:1,em:1,"%":1},"table-layout":{fixed:1,auto:1},"text-decoration":{none:1,underline:1,"line-through":1,blink:1},"text-align":{left:1,right:1,center:1,justify:1},"text-transform":{capitalize:1,uppercase:1,lowercase:1,none:1},top:{px:1,em:1,"%":1},"vertical-align":{top:1,bottom:1},visibility:{hidden:1,visible:1},"white-space":{nowrap:1,normal:1,pre:1,"pre-line":1,"pre-wrap":1},width:{px:1,em:1,"%":1},"word-spacing":{normal:1},filter:{"alpha(opacity=$0100)":1},"text-shadow":{"$02px 2px 2px #777":1},"text-overflow":{"ellipsis-word":1,clip:1,ellipsis:1},"-moz-border-radius":1,"-moz-border-radius-topright":1,"-moz-border-radius-bottomright":1,"-moz-border-radius-topleft":1,"-moz-border-radius-bottomleft":1,"-webkit-border-radius":1,"-webkit-border-top-right-radius":1,"-webkit-border-top-left-radius":1,"-webkit-border-bottom-right-radius":1,"-webkit-border-bottom-left-radius":1,"-moz-box-shadow":1,"-webkit-box-shadow":1,transform:{"rotate($00deg)":1,"skew($00deg)":1},"-moz-transform":{"rotate($00deg)":1,"skew($00deg)":1},"-webkit-transform":{"rotate($00deg)":1,"skew($00deg)":1}},i=function(){};(function(){this.completionsDefined=!1,this.defineCompletions=function(){if(document){var e=document.createElement("c").style;for(var t in e){if(typeof e[t]!="string")continue;var n=t.replace(/[A-Z]/g,function(e){return"-"+e.toLowerCase()});r.hasOwnProperty(n)||(r[n]=1)}}this.completionsDefined=!0},this.getCompletions=function(e,t,n,r){this.completionsDefined||this.defineCompletions();var i=t.getTokenAt(n.row,n.column);if(!i)return[];if(e==="ruleset"){var s=t.getLine(n.row).substr(0,n.column);return/:[^;]+$/.test(s)?(/([\w\-]+):[^:]*$/.test(s),this.getPropertyValueCompletions(e,t,n,r)):this.getPropertyCompletions(e,t,n,r)}return[]},this.getPropertyCompletions=function(e,t,n,i){var s=Object.keys(r);return s.map(function(e){return{caption:e,snippet:e+": $0",meta:"property",score:Number.MAX_VALUE}})},this.getPropertyValueCompletions=function(e,t,n,i){var s=t.getLine(n.row).substr(0,n.column),o=(/([\w\-]+):[^:]*$/.exec(s)||{})[1];if(!o)return[];var u=[];return o in r&&typeof r[o]=="object"&&(u=Object.keys(r[o])),u.map(function(e){return{caption:e,snippet:e,meta:"property value",score:Number.MAX_VALUE}})}}).call(i.prototype),t.CssCompletions=i}),define("ace/mode/behaviour/css",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/mode/behaviour/cstyle","ace/token_iterator"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("./cstyle").CstyleBehaviour,o=e("../../token_iterator").TokenIterator,u=function(){this.inherit(s),this.add("colon","insertion",function(e,t,n,r,i){if(i===":"){var s=n.getCursorPosition(),u=new o(r,s.row,s.column),a=u.getCurrentToken();a&&a.value.match(/\s+/)&&(a=u.stepBackward());if(a&&a.type==="support.type"){var f=r.doc.getLine(s.row),l=f.substring(s.column,s.column+1);if(l===":")return{text:"",selection:[1,1]};if(!f.substring(s.column).match(/^\s*;/))return{text:":;",selection:[1,1]}}}}),this.add("colon","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s===":"){var u=n.getCursorPosition(),a=new o(r,u.row,u.column),f=a.getCurrentToken();f&&f.value.match(/\s+/)&&(f=a.stepBackward());if(f&&f.type==="support.type"){var l=r.doc.getLine(i.start.row),c=l.substring(i.end.column,i.end.column+1);if(c===";")return i.end.column++,i}}}),this.add("semicolon","insertion",function(e,t,n,r,i){if(i===";"){var s=n.getCursorPosition(),o=r.doc.getLine(s.row),u=o.substring(s.column,s.column+1);if(u===";")return{text:"",selection:[1,1]}}})};r.inherits(u,s),t.CssBehaviour=u}),define("ace/mode/css",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/css_highlight_rules","ace/mode/matching_brace_outdent","ace/worker/worker_client","ace/mode/css_completions","ace/mode/behaviour/css","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./css_highlight_rules").CssHighlightRules,o=e("./matching_brace_outdent").MatchingBraceOutdent,u=e("../worker/worker_client").WorkerClient,a=e("./css_completions").CssCompletions,f=e("./behaviour/css").CssBehaviour,l=e("./folding/cstyle").FoldMode,c=function(){this.HighlightRules=s,this.$outdent=new o,this.$behaviour=new f,this.$completer=new a,this.foldingRules=new l};r.inherits(c,i),function(){this.foldingRules="cStyle",this.blockComment={start:"/*",end:"*/"},this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),i=this.getTokenizer().getLineTokens(t,e).tokens;if(i.length&&i[i.length-1].type=="comment")return r;var s=t.match(/^.*\{\s*$/);return s&&(r+=n),r},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.getCompletions=function(e,t,n,r){return this.$completer.getCompletions(e,t,n,r)},this.createWorker=function(e){var t=new u(["ace"],"ace/mode/css_worker","Worker");return t.attachToDocument(e.getDocument()),t.on("annotate",function(t){e.setAnnotations(t.data)}),t.on("terminate",function(){e.clearAnnotations()}),t},this.$id="ace/mode/css"}.call(c.prototype),t.Mode=c}),define("ace/mode/xml_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(e){var t="[_:a-zA-Z\u00c0-\uffff][-_:.a-zA-Z0-9\u00c0-\uffff]*";this.$rules={start:[{token:"string.cdata.xml",regex:"<\\!\\[CDATA\\[",next:"cdata"},{token:["punctuation.xml-decl.xml","keyword.xml-decl.xml"],regex:"(<\\?)(xml)(?=[\\s])",next:"xml_decl",caseInsensitive:!0},{token:["punctuation.instruction.xml","keyword.instruction.xml"],regex:"(<\\?)("+t+")",next:"processing_instruction"},{token:"comment.xml",regex:"<\\!--",next:"comment"},{token:["xml-pe.doctype.xml","xml-pe.doctype.xml"],regex:"(<\\!)(DOCTYPE)(?=[\\s])",next:"doctype",caseInsensitive:!0},{include:"tag"},{token:"text.end-tag-open.xml",regex:"",next:"start"}],processing_instruction:[{token:"punctuation.instruction.xml",regex:"\\?>",next:"start"},{defaultToken:"instruction.xml"}],doctype:[{include:"whitespace"},{include:"string"},{token:"xml-pe.doctype.xml",regex:">",next:"start"},{token:"xml-pe.xml",regex:"[-_a-zA-Z0-9:]+"},{token:"punctuation.int-subset",regex:"\\[",push:"int_subset"}],int_subset:[{token:"text.xml",regex:"\\s+"},{token:"punctuation.int-subset.xml",regex:"]",next:"pop"},{token:["punctuation.markup-decl.xml","keyword.markup-decl.xml"],regex:"(<\\!)("+t+")",push:[{token:"text",regex:"\\s+"},{token:"punctuation.markup-decl.xml",regex:">",next:"pop"},{include:"string"}]}],cdata:[{token:"string.cdata.xml",regex:"\\]\\]>",next:"start"},{token:"text.xml",regex:"\\s+"},{token:"text.xml",regex:"(?:[^\\]]|\\](?!\\]>))+"}],comment:[{token:"comment.xml",regex:"-->",next:"start"},{defaultToken:"comment.xml"}],reference:[{token:"constant.language.escape.reference.xml",regex:"(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)"}],attr_reference:[{token:"constant.language.escape.reference.attribute-value.xml",regex:"(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)"}],tag:[{token:["meta.tag.punctuation.tag-open.xml","meta.tag.punctuation.end-tag-open.xml","meta.tag.tag-name.xml"],regex:"(?:(<)|(",next:"start"}]}],tag_whitespace:[{token:"text.tag-whitespace.xml",regex:"\\s+"}],whitespace:[{token:"text.whitespace.xml",regex:"\\s+"}],string:[{token:"string.xml",regex:"'",push:[{token:"string.xml",regex:"'",next:"pop"},{defaultToken:"string.xml"}]},{token:"string.xml",regex:'"',push:[{token:"string.xml",regex:'"',next:"pop"},{defaultToken:"string.xml"}]}],attributes:[{token:"entity.other.attribute-name.xml",regex:"(?:"+t+":)?"+t+""},{token:"keyword.operator.attribute-equals.xml",regex:"="},{include:"tag_whitespace"},{include:"attribute_value"}],attribute_value:[{token:"string.attribute-value.xml",regex:"'",push:[{token:"string.attribute-value.xml",regex:"'",next:"pop"},{include:"attr_reference"},{defaultToken:"string.attribute-value.xml"}]},{token:"string.attribute-value.xml",regex:'"',push:[{token:"string.attribute-value.xml",regex:'"',next:"pop"},{include:"attr_reference"},{defaultToken:"string.attribute-value.xml"}]}]},this.constructor===s&&this.normalizeRules()};(function(){this.embedTagRules=function(e,t,n){this.$rules.tag.unshift({token:["meta.tag.punctuation.tag-open.xml","meta.tag."+n+".tag-name.xml"],regex:"(<)("+n+"(?=\\s|>|$))",next:[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:t+"start"}]}),this.$rules[n+"-end"]=[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:"start",onMatch:function(e,t,n){return n.splice(0),this.token}}],this.embedRules(e,t,[{token:["meta.tag.punctuation.end-tag-open.xml","meta.tag."+n+".tag-name.xml"],regex:"(|$))",next:n+"-end"},{token:"string.cdata.xml",regex:"<\\!\\[CDATA\\["},{token:"string.cdata.xml",regex:"\\]\\]>"}])}}).call(i.prototype),r.inherits(s,i),t.XmlHighlightRules=s}),define("ace/mode/html_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/css_highlight_rules","ace/mode/javascript_highlight_rules","ace/mode/xml_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./css_highlight_rules").CssHighlightRules,o=e("./javascript_highlight_rules").JavaScriptHighlightRules,u=e("./xml_highlight_rules").XmlHighlightRules,a=i.createMap({a:"anchor",button:"form",form:"form",img:"image",input:"form",label:"form",option:"form",script:"script",select:"form",textarea:"form",style:"style",table:"table",tbody:"table",td:"table",tfoot:"table",th:"table",tr:"table"}),f=function(){u.call(this),this.addRules({attributes:[{include:"tag_whitespace"},{token:"entity.other.attribute-name.xml",regex:"[-_a-zA-Z0-9:.]+"},{token:"keyword.operator.attribute-equals.xml",regex:"=",push:[{include:"tag_whitespace"},{token:"string.unquoted.attribute-value.html",regex:"[^<>='\"`\\s]+",next:"pop"},{token:"empty",regex:"",next:"pop"}]},{include:"attribute_value"}],tag:[{token:function(e,t){var n=a[t];return["meta.tag.punctuation."+(e=="<"?"":"end-")+"tag-open.xml","meta.tag"+(n?"."+n:"")+".tag-name.xml"]},regex:"(",next:"start"}]}),this.embedTagRules(s,"css-","style"),this.embedTagRules((new o({jsx:!1})).getRules(),"js-","script"),this.constructor===f&&this.normalizeRules()};r.inherits(f,u),t.HtmlHighlightRules=f}),define("ace/mode/behaviour/xml",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator","ace/lib/lang"],function(e,t,n){"use strict";function u(e,t){return e.type.lastIndexOf(t+".xml")>-1}var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("../../token_iterator").TokenIterator,o=e("../../lib/lang"),a=function(){this.add("string_dquotes","insertion",function(e,t,n,r,i){if(i=='"'||i=="'"){var o=i,a=r.doc.getTextRange(n.getSelectionRange());if(a!==""&&a!=="'"&&a!='"'&&n.getWrapBehavioursEnabled())return{text:o+a+o,selection:!1};var f=n.getCursorPosition(),l=r.doc.getLine(f.row),c=l.substring(f.column,f.column+1),h=new s(r,f.row,f.column),p=h.getCurrentToken();if(c==o&&(u(p,"attribute-value")||u(p,"string")))return{text:"",selection:[1,1]};p||(p=h.stepBackward());if(!p)return;while(u(p,"tag-whitespace")||u(p,"whitespace"))p=h.stepBackward();var d=!c||c.match(/\s/);if(u(p,"attribute-equals")&&(d||c==">")||u(p,"decl-attribute-equals")&&(d||c=="?"))return{text:o+o,selection:[1,1]}}}),this.add("string_dquotes","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&(s=='"'||s=="'")){var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==s)return i.end.column++,i}}),this.add("autoclosing","insertion",function(e,t,n,r,i){if(i==">"){var o=n.getSelectionRange().start,a=new s(r,o.row,o.column),f=a.getCurrentToken()||a.stepBackward();if(!f||!(u(f,"tag-name")||u(f,"tag-whitespace")||u(f,"attribute-name")||u(f,"attribute-equals")||u(f,"attribute-value")))return;if(u(f,"reference.attribute-value"))return;if(u(f,"attribute-value")){var l=f.value.charAt(0);if(l=='"'||l=="'"){var c=f.value.charAt(f.value.length-1),h=a.getCurrentTokenColumn()+f.value.length;if(h>o.column||h==o.column&&l!=c)return}}while(!u(f,"tag-name")){f=a.stepBackward();if(f.value=="<"){f=a.stepForward();break}}var p=a.getCurrentTokenRow(),d=a.getCurrentTokenColumn();if(u(a.stepBackward(),"end-tag-open"))return;var v=f.value;p==o.row&&(v=v.substring(0,o.column-d));if(this.voidElements.hasOwnProperty(v.toLowerCase()))return;return{text:">",selection:[1,1]}}}),this.add("autoindent","insertion",function(e,t,n,r,i){if(i=="\n"){var o=n.getCursorPosition(),u=r.getLine(o.row),a=new s(r,o.row,o.column),f=a.getCurrentToken();if(f&&f.type.indexOf("tag-close")!==-1){if(f.value=="/>")return;while(f&&f.type.indexOf("tag-name")===-1)f=a.stepBackward();if(!f)return;var l=f.value,c=a.getCurrentTokenRow();f=a.stepBackward();if(!f||f.type.indexOf("end-tag")!==-1)return;if(this.voidElements&&!this.voidElements[l]){var h=r.getTokenAt(o.row,o.column+1),u=r.getLine(c),p=this.$getIndent(u),d=p+r.getTabString();return h&&h.value==="-1}var r=e("../../lib/oop"),i=e("../../lib/lang"),s=e("../../range").Range,o=e("./fold_mode").FoldMode,u=e("../../token_iterator").TokenIterator,a=t.FoldMode=function(e,t){o.call(this),this.voidElements=e||{},this.optionalEndTags=r.mixin({},this.voidElements),t&&r.mixin(this.optionalEndTags,t)};r.inherits(a,o);var f=function(){this.tagName="",this.closing=!1,this.selfClosing=!1,this.start={row:0,column:0},this.end={row:0,column:0}};(function(){this.getFoldWidget=function(e,t,n){var r=this._getFirstTagInLine(e,n);return r?r.closing||!r.tagName&&r.selfClosing?t=="markbeginend"?"end":"":!r.tagName||r.selfClosing||this.voidElements.hasOwnProperty(r.tagName.toLowerCase())?"":this._findEndTagInLine(e,n,r.tagName,r.end.column)?"":"start":""},this._getFirstTagInLine=function(e,t){var n=e.getTokens(t),r=new f;for(var i=0;i";break}}return r}if(l(s,"tag-close"))return r.selfClosing=s.value=="/>",r;r.start.column+=s.value.length}return null},this._findEndTagInLine=function(e,t,n,r){var i=e.getTokens(t),s=0;for(var o=0;o",n.end.row=e.getCurrentTokenRow(),n.end.column=e.getCurrentTokenColumn()+t.value.length,e.stepForward(),n;while(t=e.stepForward());return null},this._readTagBackward=function(e){var t=e.getCurrentToken();if(!t)return null;var n=new f;do{if(l(t,"tag-open"))return n.closing=l(t,"end-tag-open"),n.start.row=e.getCurrentTokenRow(),n.start.column=e.getCurrentTokenColumn(),e.stepBackward(),n;l(t,"tag-name")?n.tagName=t.value:l(t,"tag-close")&&(n.selfClosing=t.value=="/>",n.end.row=e.getCurrentTokenRow(),n.end.column=e.getCurrentTokenColumn()+t.value.length)}while(t=e.stepBackward());return null},this._pop=function(e,t){while(e.length){var n=e[e.length-1];if(!t||n.tagName==t.tagName)return e.pop();if(this.optionalEndTags.hasOwnProperty(n.tagName)){e.pop();continue}return null}},this.getFoldWidgetRange=function(e,t,n){var r=this._getFirstTagInLine(e,n);if(!r)return null;var i=r.closing||r.selfClosing,o=[],a;if(!i){var f=new u(e,n,r.start.column),l={row:n,column:r.start.column+r.tagName.length+2};r.start.row==r.end.row&&(l.column=r.end.column);while(a=this._readTagForward(f)){if(a.selfClosing){if(!o.length)return a.start.column+=a.tagName.length+2,a.end.column-=2,s.fromPoints(a.start,a.end);continue}if(a.closing){this._pop(o,a);if(o.length==0)return s.fromPoints(l,a.start)}else o.push(a)}}else{var f=new u(e,n,r.end.column),c={row:n,column:r.start.column};while(a=this._readTagBackward(f)){if(a.selfClosing){if(!o.length)return a.start.column+=a.tagName.length+2,a.end.column-=2,s.fromPoints(a.start,a.end);continue}if(!a.closing){this._pop(o,a);if(o.length==0)return a.start.column+=a.tagName.length+2,a.start.row==a.end.row&&a.start.column-1}function l(e,t){var n=new r(e,t.row,t.column),i=n.getCurrentToken();while(i&&!f(i,"tag-name"))i=n.stepBackward();if(i)return i.value}function c(e,t){var n=new r(e,t.row,t.column),i=n.getCurrentToken();while(i&&!f(i,"attribute-name"))i=n.stepBackward();if(i)return i.value}var r=e("../token_iterator").TokenIterator,i=["accesskey","class","contenteditable","contextmenu","dir","draggable","dropzone","hidden","id","inert","itemid","itemprop","itemref","itemscope","itemtype","lang","spellcheck","style","tabindex","title","translate"],s=["onabort","onblur","oncancel","oncanplay","oncanplaythrough","onchange","onclick","onclose","oncontextmenu","oncuechange","ondblclick","ondrag","ondragend","ondragenter","ondragleave","ondragover","ondragstart","ondrop","ondurationchange","onemptied","onended","onerror","onfocus","oninput","oninvalid","onkeydown","onkeypress","onkeyup","onload","onloadeddata","onloadedmetadata","onloadstart","onmousedown","onmousemove","onmouseout","onmouseover","onmouseup","onmousewheel","onpause","onplay","onplaying","onprogress","onratechange","onreset","onscroll","onseeked","onseeking","onselect","onshow","onstalled","onsubmit","onsuspend","ontimeupdate","onvolumechange","onwaiting"],o=i.concat(s),u={html:{manifest:1},head:{},title:{},base:{href:1,target:1},link:{href:1,hreflang:1,rel:{stylesheet:1,icon:1},media:{all:1,screen:1,print:1},type:{"text/css":1,"image/png":1,"image/jpeg":1,"image/gif":1},sizes:1},meta:{"http-equiv":{"content-type":1},name:{description:1,keywords:1},content:{"text/html; charset=UTF-8":1},charset:1},style:{type:1,media:{all:1,screen:1,print:1},scoped:1},script:{charset:1,type:{"text/javascript":1},src:1,defer:1,async:1},noscript:{href:1},body:{onafterprint:1,onbeforeprint:1,onbeforeunload:1,onhashchange:1,onmessage:1,onoffline:1,onpopstate:1,onredo:1,onresize:1,onstorage:1,onundo:1,onunload:1},section:{},nav:{},article:{pubdate:1},aside:{},h1:{},h2:{},h3:{},h4:{},h5:{},h6:{},header:{},footer:{},address:{},main:{},p:{},hr:{},pre:{},blockquote:{cite:1},ol:{start:1,reversed:1},ul:{},li:{value:1},dl:{},dt:{},dd:{},figure:{},figcaption:{},div:{},a:{href:1,target:{_blank:1,top:1},ping:1,rel:{nofollow:1,alternate:1,author:1,bookmark:1,help:1,license:1,next:1,noreferrer:1,prefetch:1,prev:1,search:1,tag:1},media:1,hreflang:1,type:1},em:{},strong:{},small:{},s:{},cite:{},q:{cite:1},dfn:{},abbr:{},data:{},time:{datetime:1},code:{},"var":{},samp:{},kbd:{},sub:{},sup:{},i:{},b:{},u:{},mark:{},ruby:{},rt:{},rp:{},bdi:{},bdo:{},span:{},br:{},wbr:{},ins:{cite:1,datetime:1},del:{cite:1,datetime:1},img:{alt:1,src:1,height:1,width:1,usemap:1,ismap:1},iframe:{name:1,src:1,height:1,width:1,sandbox:{"allow-same-origin":1,"allow-top-navigation":1,"allow-forms":1,"allow-scripts":1},seamless:{seamless:1}},embed:{src:1,height:1,width:1,type:1},object:{param:1,data:1,type:1,height:1,width:1,usemap:1,name:1,form:1,classid:1},param:{name:1,value:1},video:{src:1,autobuffer:1,autoplay:{autoplay:1},loop:{loop:1},controls:{controls:1},width:1,height:1,poster:1,muted:{muted:1},preload:{auto:1,metadata:1,none:1}},audio:{src:1,autobuffer:1,autoplay:{autoplay:1},loop:{loop:1},controls:{controls:1},muted:{muted:1},preload:{auto:1,metadata:1,none:1}},source:{src:1,type:1,media:1},track:{kind:1,src:1,srclang:1,label:1,"default":1},canvas:{width:1,height:1},map:{name:1},area:{shape:1,coords:1,href:1,hreflang:1,alt:1,target:1,media:1,rel:1,ping:1,type:1},svg:{},math:{},table:{summary:1},caption:{},colgroup:{span:1},col:{span:1},tbody:{},thead:{},tfoot:{},tr:{},td:{headers:1,rowspan:1,colspan:1},th:{headers:1,rowspan:1,colspan:1,scope:1},form:{"accept-charset":1,action:1,autocomplete:1,enctype:{"multipart/form-data":1,"application/x-www-form-urlencoded":1},method:{get:1,post:1},name:1,novalidate:1,target:{_blank:1,top:1}},fieldset:{disabled:1,form:1,name:1},legend:{},label:{form:1,"for":1},input:{type:{text:1,password:1,hidden:1,checkbox:1,submit:1,radio:1,file:1,button:1,reset:1,image:31,color:1,date:1,datetime:1,"datetime-local":1,email:1,month:1,number:1,range:1,search:1,tel:1,time:1,url:1,week:1},accept:1,alt:1,autocomplete:{on:1,off:1},autofocus:{autofocus:1},checked:{checked:1},disabled:{disabled:1},form:1,formaction:1,formenctype:{"application/x-www-form-urlencoded":1,"multipart/form-data":1,"text/plain":1},formmethod:{get:1,post:1},formnovalidate:{formnovalidate:1},formtarget:{_blank:1,_self:1,_parent:1,_top:1},height:1,list:1,max:1,maxlength:1,min:1,multiple:{multiple:1},name:1,pattern:1,placeholder:1,readonly:{readonly:1},required:{required:1},size:1,src:1,step:1,width:1,files:1,value:1},button:{autofocus:1,disabled:{disabled:1},form:1,formaction:1,formenctype:1,formmethod:1,formnovalidate:1,formtarget:1,name:1,value:1,type:{button:1,submit:1}},select:{autofocus:1,disabled:1,form:1,multiple:{multiple:1},name:1,size:1,readonly:{readonly:1}},datalist:{},optgroup:{disabled:1,label:1},option:{disabled:1,selected:1,label:1,value:1},textarea:{autofocus:{autofocus:1},disabled:{disabled:1},form:1,maxlength:1,name:1,placeholder:1,readonly:{readonly:1},required:{required:1},rows:1,cols:1,wrap:{on:1,off:1,hard:1,soft:1}},keygen:{autofocus:1,challenge:{challenge:1},disabled:{disabled:1},form:1,keytype:{rsa:1,dsa:1,ec:1},name:1},output:{"for":1,form:1,name:1},progress:{value:1,max:1},meter:{value:1,min:1,max:1,low:1,high:1,optimum:1},details:{open:1},summary:{},command:{type:1,label:1,icon:1,disabled:1,checked:1,radiogroup:1,command:1},menu:{type:1,label:1},dialog:{open:1}},a=Object.keys(u),h=function(){};(function(){this.getCompletions=function(e,t,n,r){var i=t.getTokenAt(n.row,n.column);if(!i)return[];if(f(i,"tag-name")||f(i,"tag-open")||f(i,"end-tag-open"))return this.getTagCompletions(e,t,n,r);if(f(i,"tag-whitespace")||f(i,"attribute-name"))return this.getAttributeCompletions(e,t,n,r);if(f(i,"attribute-value"))return this.getAttributeValueCompletions(e,t,n,r);var s=t.getLine(n.row).substr(0,n.column);return/&[a-z]*$/i.test(s)?this.getHTMLEntityCompletions(e,t,n,r):[]},this.getTagCompletions=function(e,t,n,r){return a.map(function(e){return{value:e,meta:"tag",score:Number.MAX_VALUE}})},this.getAttributeCompletions=function(e,t,n,r){var i=l(t,n);if(!i)return[];var s=o;return i in u&&(s=s.concat(Object.keys(u[i]))),s.map(function(e){return{caption:e,snippet:e+'="$0"',meta:"attribute",score:Number.MAX_VALUE}})},this.getAttributeValueCompletions=function(e,t,n,r){var i=l(t,n),s=c(t,n);if(!i)return[];var o=[];return i in u&&s in u[i]&&typeof u[i][s]=="object"&&(o=Object.keys(u[i][s])),o.map(function(e){return{caption:e,snippet:e,meta:"attribute value",score:Number.MAX_VALUE}})},this.getHTMLEntityCompletions=function(e,t,n,r){var i=["Aacute;","aacute;","Acirc;","acirc;","acute;","AElig;","aelig;","Agrave;","agrave;","alefsym;","Alpha;","alpha;","amp;","and;","ang;","Aring;","aring;","asymp;","Atilde;","atilde;","Auml;","auml;","bdquo;","Beta;","beta;","brvbar;","bull;","cap;","Ccedil;","ccedil;","cedil;","cent;","Chi;","chi;","circ;","clubs;","cong;","copy;","crarr;","cup;","curren;","Dagger;","dagger;","dArr;","darr;","deg;","Delta;","delta;","diams;","divide;","Eacute;","eacute;","Ecirc;","ecirc;","Egrave;","egrave;","empty;","emsp;","ensp;","Epsilon;","epsilon;","equiv;","Eta;","eta;","ETH;","eth;","Euml;","euml;","euro;","exist;","fnof;","forall;","frac12;","frac14;","frac34;","frasl;","Gamma;","gamma;","ge;","gt;","hArr;","harr;","hearts;","hellip;","Iacute;","iacute;","Icirc;","icirc;","iexcl;","Igrave;","igrave;","image;","infin;","int;","Iota;","iota;","iquest;","isin;","Iuml;","iuml;","Kappa;","kappa;","Lambda;","lambda;","lang;","laquo;","lArr;","larr;","lceil;","ldquo;","le;","lfloor;","lowast;","loz;","lrm;","lsaquo;","lsquo;","lt;","macr;","mdash;","micro;","middot;","minus;","Mu;","mu;","nabla;","nbsp;","ndash;","ne;","ni;","not;","notin;","nsub;","Ntilde;","ntilde;","Nu;","nu;","Oacute;","oacute;","Ocirc;","ocirc;","OElig;","oelig;","Ograve;","ograve;","oline;","Omega;","omega;","Omicron;","omicron;","oplus;","or;","ordf;","ordm;","Oslash;","oslash;","Otilde;","otilde;","otimes;","Ouml;","ouml;","para;","part;","permil;","perp;","Phi;","phi;","Pi;","pi;","piv;","plusmn;","pound;","Prime;","prime;","prod;","prop;","Psi;","psi;","quot;","radic;","rang;","raquo;","rArr;","rarr;","rceil;","rdquo;","real;","reg;","rfloor;","Rho;","rho;","rlm;","rsaquo;","rsquo;","sbquo;","Scaron;","scaron;","sdot;","sect;","shy;","Sigma;","sigma;","sigmaf;","sim;","spades;","sub;","sube;","sum;","sup;","sup1;","sup2;","sup3;","supe;","szlig;","Tau;","tau;","there4;","Theta;","theta;","thetasym;","thinsp;","THORN;","thorn;","tilde;","times;","trade;","Uacute;","uacute;","uArr;","uarr;","Ucirc;","ucirc;","Ugrave;","ugrave;","uml;","upsih;","Upsilon;","upsilon;","Uuml;","uuml;","weierp;","Xi;","xi;","Yacute;","yacute;","yen;","Yuml;","yuml;","Zeta;","zeta;","zwj;","zwnj;"];return i.map(function(e){return{caption:e,snippet:e,meta:"html entity",score:Number.MAX_VALUE}})}}).call(h.prototype),t.HtmlCompletions=h}),define("ace/mode/html",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/text","ace/mode/javascript","ace/mode/css","ace/mode/html_highlight_rules","ace/mode/behaviour/xml","ace/mode/folding/html","ace/mode/html_completions","ace/worker/worker_client"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./text").Mode,o=e("./javascript").Mode,u=e("./css").Mode,a=e("./html_highlight_rules").HtmlHighlightRules,f=e("./behaviour/xml").XmlBehaviour,l=e("./folding/html").FoldMode,c=e("./html_completions").HtmlCompletions,h=e("../worker/worker_client").WorkerClient,p=["area","base","br","col","embed","hr","img","input","keygen","link","meta","menuitem","param","source","track","wbr"],d=["li","dt","dd","p","rt","rp","optgroup","option","colgroup","td","th"],v=function(e){this.fragmentContext=e&&e.fragmentContext,this.HighlightRules=a,this.$behaviour=new f,this.$completer=new c,this.createModeDelegates({"js-":o,"css-":u}),this.foldingRules=new l(this.voidElements,i.arrayToMap(d))};r.inherits(v,s),function(){this.blockComment={start:""},this.voidElements=i.arrayToMap(p),this.getNextLineIndent=function(e,t,n){return this.$getIndent(t)},this.checkOutdent=function(e,t,n){return!1},this.getCompletions=function(e,t,n,r){return this.$completer.getCompletions(e,t,n,r)},this.createWorker=function(e){if(this.constructor!=v)return;var t=new h(["ace"],"ace/mode/html_worker","Worker");return t.attachToDocument(e.getDocument()),this.fragmentContext&&t.call("setOptions",[{context:this.fragmentContext}]),t.on("error",function(t){e.setAnnotations(t.data)}),t.on("terminate",function(){e.clearAnnotations()}),t},this.$id="ace/mode/html"}.call(v.prototype),t.Mode=v}) \ No newline at end of file diff --git a/examples/SmartSwitch/data_src/js_css_src/ace-drafts/mode-javascript.js b/examples/SmartSwitch/data_src/js_css_src/ace-drafts/mode-javascript.js deleted file mode 100644 index 6bad9f609..000000000 --- a/examples/SmartSwitch/data_src/js_css_src/ace-drafts/mode-javascript.js +++ /dev/null @@ -1 +0,0 @@ -ace.define("ace/mode/doc_comment_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){this.$rules={start:[{token:"comment.doc.tag",regex:"@[\\w\\d_]+"},s.getTagRule(),{defaultToken:"comment.doc",caseInsensitive:!0}]}};r.inherits(s,i),s.getTagRule=function(e){return{token:"comment.doc.tag.storage.type",regex:"\\b(?:TODO|FIXME|XXX|HACK)\\b"}},s.getStartRule=function(e){return{token:"comment.doc",regex:"\\/\\*(?=\\*)",next:e}},s.getEndRule=function(e){return{token:"comment.doc",regex:"\\*\\/",next:e}},t.DocCommentHighlightRules=s}),ace.define("ace/mode/javascript_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/doc_comment_highlight_rules","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";function a(){var e=o.replace("\\d","\\d\\-"),t={onMatch:function(e,t,n){var r=e.charAt(1)=="/"?2:1;if(r==1)t!=this.nextState?n.unshift(this.next,this.nextState,0):n.unshift(this.next),n[2]++;else if(r==2&&t==this.nextState){n[1]--;if(!n[1]||n[1]<0)n.shift(),n.shift()}return[{type:"meta.tag.punctuation."+(r==1?"":"end-")+"tag-open.xml",value:e.slice(0,r)},{type:"meta.tag.tag-name.xml",value:e.substr(r)}]},regex:"",onMatch:function(e,t,n){return t==n[0]&&n.shift(),e.length==2&&(n[0]==this.nextState&&n[1]--,(!n[1]||n[1]<0)&&n.splice(0,2)),this.next=n[0]||"start",[{type:this.token,value:e}]},nextState:"jsx"},n,f("jsxAttributes"),{token:"entity.other.attribute-name.xml",regex:e},{token:"keyword.operator.attribute-equals.xml",regex:"="},{token:"text.tag-whitespace.xml",regex:"\\s+"},{token:"string.attribute-value.xml",regex:"'",stateName:"jsx_attr_q",push:[{token:"string.attribute-value.xml",regex:"'",next:"pop"},{include:"reference"},{defaultToken:"string.attribute-value.xml"}]},{token:"string.attribute-value.xml",regex:'"',stateName:"jsx_attr_qq",push:[{token:"string.attribute-value.xml",regex:'"',next:"pop"},{include:"reference"},{defaultToken:"string.attribute-value.xml"}]},t],this.$rules.reference=[{token:"constant.language.escape.reference.xml",regex:"(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)"}]}function f(e){return[{token:"comment",regex:/\/\*/,next:[i.getTagRule(),{token:"comment",regex:"\\*\\/",next:e||"pop"},{defaultToken:"comment",caseInsensitive:!0}]},{token:"comment",regex:"\\/\\/",next:[i.getTagRule(),{token:"comment",regex:"$|^",next:e||"pop"},{defaultToken:"comment",caseInsensitive:!0}]}]}var r=e("../lib/oop"),i=e("./doc_comment_highlight_rules").DocCommentHighlightRules,s=e("./text_highlight_rules").TextHighlightRules,o="[a-zA-Z\\$_\u00a1-\uffff][a-zA-Z\\d\\$_\u00a1-\uffff]*",u=function(e){var t=this.createKeywordMapper({"variable.language":"Array|Boolean|Date|Function|Iterator|Number|Object|RegExp|String|Proxy|Namespace|QName|XML|XMLList|ArrayBuffer|Float32Array|Float64Array|Int16Array|Int32Array|Int8Array|Uint16Array|Uint32Array|Uint8Array|Uint8ClampedArray|Error|EvalError|InternalError|RangeError|ReferenceError|StopIteration|SyntaxError|TypeError|URIError|decodeURI|decodeURIComponent|encodeURI|encodeURIComponent|eval|isFinite|isNaN|parseFloat|parseInt|JSON|Math|this|arguments|prototype|window|document",keyword:"const|yield|import|get|set|async|await|break|case|catch|continue|default|delete|do|else|finally|for|function|if|in|of|instanceof|new|return|switch|throw|try|typeof|let|var|while|with|debugger|__parent__|__count__|escape|unescape|with|__proto__|class|enum|extends|super|export|implements|private|public|interface|package|protected|static","storage.type":"const|let|var|function","constant.language":"null|Infinity|NaN|undefined","support.function":"alert","constant.language.boolean":"true|false"},"identifier"),n="case|do|else|finally|in|instanceof|return|throw|try|typeof|yield|void",r="\\\\(?:x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|u{[0-9a-fA-F]{1,6}}|[0-2][0-7]{0,2}|3[0-7][0-7]?|[4-7][0-7]?|.)";this.$rules={no_regex:[i.getStartRule("doc-start"),f("no_regex"),{token:"string",regex:"'(?=.)",next:"qstring"},{token:"string",regex:'"(?=.)',next:"qqstring"},{token:"constant.numeric",regex:/0(?:[xX][0-9a-fA-F]+|[bB][01]+)\b/},{token:"constant.numeric",regex:/[+-]?\d[\d_]*(?:(?:\.\d*)?(?:[eE][+-]?\d+)?)?\b/},{token:["storage.type","punctuation.operator","support.function","punctuation.operator","entity.name.function","text","keyword.operator"],regex:"("+o+")(\\.)(prototype)(\\.)("+o+")(\\s*)(=)",next:"function_arguments"},{token:["storage.type","punctuation.operator","entity.name.function","text","keyword.operator","text","storage.type","text","paren.lparen"],regex:"("+o+")(\\.)("+o+")(\\s*)(=)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["entity.name.function","text","keyword.operator","text","storage.type","text","paren.lparen"],regex:"("+o+")(\\s*)(=)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["storage.type","punctuation.operator","entity.name.function","text","keyword.operator","text","storage.type","text","entity.name.function","text","paren.lparen"],regex:"("+o+")(\\.)("+o+")(\\s*)(=)(\\s*)(function)(\\s+)(\\w+)(\\s*)(\\()",next:"function_arguments"},{token:["storage.type","text","entity.name.function","text","paren.lparen"],regex:"(function)(\\s+)("+o+")(\\s*)(\\()",next:"function_arguments"},{token:["entity.name.function","text","punctuation.operator","text","storage.type","text","paren.lparen"],regex:"("+o+")(\\s*)(:)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["text","text","storage.type","text","paren.lparen"],regex:"(:)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:"keyword",regex:"(?:"+n+")\\b",next:"start"},{token:["support.constant"],regex:/that\b/},{token:["storage.type","punctuation.operator","support.function.firebug"],regex:/(console)(\.)(warn|info|log|error|time|trace|timeEnd|assert)\b/},{token:t,regex:o},{token:"punctuation.operator",regex:/[.](?![.])/,next:"property"},{token:"keyword.operator",regex:/--|\+\+|\.{3}|===|==|=|!=|!==|<+=?|>+=?|!|&&|\|\||\?:|[!$%&*+\-~\/^]=?/,next:"start"},{token:"punctuation.operator",regex:/[?:,;.]/,next:"start"},{token:"paren.lparen",regex:/[\[({]/,next:"start"},{token:"paren.rparen",regex:/[\])}]/},{token:"comment",regex:/^#!.*$/}],property:[{token:"text",regex:"\\s+"},{token:["storage.type","punctuation.operator","entity.name.function","text","keyword.operator","text","storage.type","text","entity.name.function","text","paren.lparen"],regex:"("+o+")(\\.)("+o+")(\\s*)(=)(\\s*)(function)(?:(\\s+)(\\w+))?(\\s*)(\\()",next:"function_arguments"},{token:"punctuation.operator",regex:/[.](?![.])/},{token:"support.function",regex:/(s(?:h(?:ift|ow(?:Mod(?:elessDialog|alDialog)|Help))|croll(?:X|By(?:Pages|Lines)?|Y|To)?|t(?:op|rike)|i(?:n|zeToContent|debar|gnText)|ort|u(?:p|b(?:str(?:ing)?)?)|pli(?:ce|t)|e(?:nd|t(?:Re(?:sizable|questHeader)|M(?:i(?:nutes|lliseconds)|onth)|Seconds|Ho(?:tKeys|urs)|Year|Cursor|Time(?:out)?|Interval|ZOptions|Date|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Date|FullYear)|FullYear|Active)|arch)|qrt|lice|avePreferences|mall)|h(?:ome|andleEvent)|navigate|c(?:har(?:CodeAt|At)|o(?:s|n(?:cat|textual|firm)|mpile)|eil|lear(?:Timeout|Interval)?|a(?:ptureEvents|ll)|reate(?:StyleSheet|Popup|EventObject))|t(?:o(?:GMTString|S(?:tring|ource)|U(?:TCString|pperCase)|Lo(?:caleString|werCase))|est|a(?:n|int(?:Enabled)?))|i(?:s(?:NaN|Finite)|ndexOf|talics)|d(?:isableExternalCapture|ump|etachEvent)|u(?:n(?:shift|taint|escape|watch)|pdateCommands)|j(?:oin|avaEnabled)|p(?:o(?:p|w)|ush|lugins.refresh|a(?:ddings|rse(?:Int|Float)?)|r(?:int|ompt|eference))|e(?:scape|nableExternalCapture|val|lementFromPoint|x(?:p|ec(?:Script|Command)?))|valueOf|UTC|queryCommand(?:State|Indeterm|Enabled|Value)|f(?:i(?:nd|le(?:ModifiedDate|Size|CreatedDate|UpdatedDate)|xed)|o(?:nt(?:size|color)|rward)|loor|romCharCode)|watch|l(?:ink|o(?:ad|g)|astIndexOf)|a(?:sin|nchor|cos|t(?:tachEvent|ob|an(?:2)?)|pply|lert|b(?:s|ort))|r(?:ou(?:nd|teEvents)|e(?:size(?:By|To)|calc|turnValue|place|verse|l(?:oad|ease(?:Capture|Events)))|andom)|g(?:o|et(?:ResponseHeader|M(?:i(?:nutes|lliseconds)|onth)|Se(?:conds|lection)|Hours|Year|Time(?:zoneOffset)?|Da(?:y|te)|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Da(?:y|te)|FullYear)|FullYear|A(?:ttention|llResponseHeaders)))|m(?:in|ove(?:B(?:y|elow)|To(?:Absolute)?|Above)|ergeAttributes|a(?:tch|rgins|x))|b(?:toa|ig|o(?:ld|rderWidths)|link|ack))\b(?=\()/},{token:"support.function.dom",regex:/(s(?:ub(?:stringData|mit)|plitText|e(?:t(?:NamedItem|Attribute(?:Node)?)|lect))|has(?:ChildNodes|Feature)|namedItem|c(?:l(?:ick|o(?:se|neNode))|reate(?:C(?:omment|DATASection|aption)|T(?:Head|extNode|Foot)|DocumentFragment|ProcessingInstruction|E(?:ntityReference|lement)|Attribute))|tabIndex|i(?:nsert(?:Row|Before|Cell|Data)|tem)|open|delete(?:Row|C(?:ell|aption)|T(?:Head|Foot)|Data)|focus|write(?:ln)?|a(?:dd|ppend(?:Child|Data))|re(?:set|place(?:Child|Data)|move(?:NamedItem|Child|Attribute(?:Node)?)?)|get(?:NamedItem|Element(?:sBy(?:Name|TagName|ClassName)|ById)|Attribute(?:Node)?)|blur)\b(?=\()/},{token:"support.constant",regex:/(s(?:ystemLanguage|cr(?:ipts|ollbars|een(?:X|Y|Top|Left))|t(?:yle(?:Sheets)?|atus(?:Text|bar)?)|ibling(?:Below|Above)|ource|uffixes|e(?:curity(?:Policy)?|l(?:ection|f)))|h(?:istory|ost(?:name)?|as(?:h|Focus))|y|X(?:MLDocument|SLDocument)|n(?:ext|ame(?:space(?:s|URI)|Prop))|M(?:IN_VALUE|AX_VALUE)|c(?:haracterSet|o(?:n(?:structor|trollers)|okieEnabled|lorDepth|mp(?:onents|lete))|urrent|puClass|l(?:i(?:p(?:boardData)?|entInformation)|osed|asses)|alle(?:e|r)|rypto)|t(?:o(?:olbar|p)|ext(?:Transform|Indent|Decoration|Align)|ags)|SQRT(?:1_2|2)|i(?:n(?:ner(?:Height|Width)|put)|ds|gnoreCase)|zIndex|o(?:scpu|n(?:readystatechange|Line)|uter(?:Height|Width)|p(?:sProfile|ener)|ffscreenBuffering)|NEGATIVE_INFINITY|d(?:i(?:splay|alog(?:Height|Top|Width|Left|Arguments)|rectories)|e(?:scription|fault(?:Status|Ch(?:ecked|arset)|View)))|u(?:ser(?:Profile|Language|Agent)|n(?:iqueID|defined)|pdateInterval)|_content|p(?:ixelDepth|ort|ersonalbar|kcs11|l(?:ugins|atform)|a(?:thname|dding(?:Right|Bottom|Top|Left)|rent(?:Window|Layer)?|ge(?:X(?:Offset)?|Y(?:Offset)?))|r(?:o(?:to(?:col|type)|duct(?:Sub)?|mpter)|e(?:vious|fix)))|e(?:n(?:coding|abledPlugin)|x(?:ternal|pando)|mbeds)|v(?:isibility|endor(?:Sub)?|Linkcolor)|URLUnencoded|P(?:I|OSITIVE_INFINITY)|f(?:ilename|o(?:nt(?:Size|Family|Weight)|rmName)|rame(?:s|Element)|gColor)|E|whiteSpace|l(?:i(?:stStyleType|n(?:eHeight|kColor))|o(?:ca(?:tion(?:bar)?|lName)|wsrc)|e(?:ngth|ft(?:Context)?)|a(?:st(?:M(?:odified|atch)|Index|Paren)|yer(?:s|X)|nguage))|a(?:pp(?:MinorVersion|Name|Co(?:deName|re)|Version)|vail(?:Height|Top|Width|Left)|ll|r(?:ity|guments)|Linkcolor|bove)|r(?:ight(?:Context)?|e(?:sponse(?:XML|Text)|adyState))|global|x|m(?:imeTypes|ultiline|enubar|argin(?:Right|Bottom|Top|Left))|L(?:N(?:10|2)|OG(?:10E|2E))|b(?:o(?:ttom|rder(?:Width|RightWidth|BottomWidth|Style|Color|TopWidth|LeftWidth))|ufferDepth|elow|ackground(?:Color|Image)))\b/},{token:"identifier",regex:o},{regex:"",token:"empty",next:"no_regex"}],start:[i.getStartRule("doc-start"),f("start"),{token:"string.regexp",regex:"\\/",next:"regex"},{token:"text",regex:"\\s+|^$",next:"start"},{token:"empty",regex:"",next:"no_regex"}],regex:[{token:"regexp.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"string.regexp",regex:"/[sxngimy]*",next:"no_regex"},{token:"invalid",regex:/\{\d+\b,?\d*\}[+*]|[+*$^?][+*]|[$^][?]|\?{3,}/},{token:"constant.language.escape",regex:/\(\?[:=!]|\)|\{\d+\b,?\d*\}|[+*]\?|[()$^+*?.]/},{token:"constant.language.delimiter",regex:/\|/},{token:"constant.language.escape",regex:/\[\^?/,next:"regex_character_class"},{token:"empty",regex:"$",next:"no_regex"},{defaultToken:"string.regexp"}],regex_character_class:[{token:"regexp.charclass.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"constant.language.escape",regex:"]",next:"regex"},{token:"constant.language.escape",regex:"-"},{token:"empty",regex:"$",next:"no_regex"},{defaultToken:"string.regexp.charachterclass"}],function_arguments:[{token:"variable.parameter",regex:o},{token:"punctuation.operator",regex:"[, ]+"},{token:"punctuation.operator",regex:"$"},{token:"empty",regex:"",next:"no_regex"}],qqstring:[{token:"constant.language.escape",regex:r},{token:"string",regex:"\\\\$",next:"qqstring"},{token:"string",regex:'"|$',next:"no_regex"},{defaultToken:"string"}],qstring:[{token:"constant.language.escape",regex:r},{token:"string",regex:"\\\\$",next:"qstring"},{token:"string",regex:"'|$",next:"no_regex"},{defaultToken:"string"}]};if(!e||!e.noES6)this.$rules.no_regex.unshift({regex:"[{}]",onMatch:function(e,t,n){this.next=e=="{"?this.nextState:"";if(e=="{"&&n.length)n.unshift("start",t);else if(e=="}"&&n.length){n.shift(),this.next=n.shift();if(this.next.indexOf("string")!=-1||this.next.indexOf("jsx")!=-1)return"paren.quasi.end"}return e=="{"?"paren.lparen":"paren.rparen"},nextState:"start"},{token:"string.quasi.start",regex:/`/,push:[{token:"constant.language.escape",regex:r},{token:"paren.quasi.start",regex:/\${/,push:"start"},{token:"string.quasi.end",regex:/`/,next:"pop"},{defaultToken:"string.quasi"}]}),(!e||e.jsx!=0)&&a.call(this);this.embedRules(i,"doc-",[i.getEndRule("no_regex")]),this.normalizeRules()};r.inherits(u,s),t.JavaScriptHighlightRules=u}),ace.define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],function(e,t,n){"use strict";var r=e("../range").Range,i=function(){};(function(){this.checkOutdent=function(e,t){return/^\s+$/.test(e)?/^\s*\}/.test(t):!1},this.autoOutdent=function(e,t){var n=e.getLine(t),i=n.match(/^(\s*\})/);if(!i)return 0;var s=i[1].length,o=e.findMatchingBracket({row:t,column:s});if(!o||o.row==t)return 0;var u=this.$getIndent(e.getLine(o.row));e.replace(new r(t,0,t,s-1),u)},this.$getIndent=function(e){return e.match(/^\s*/)[0]}}).call(i.prototype),t.MatchingBraceOutdent=i}),ace.define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../../range").Range,s=e("./fold_mode").FoldMode,o=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end)))};r.inherits(o,s),function(){this.foldingStartMarker=/(\{|\[)[^\}\]]*$|^\s*(\/\*)/,this.foldingStopMarker=/^[^\[\{]*(\}|\])|^[\s\*]*(\*\/)/,this.singleLineBlockCommentRe=/^\s*(\/\*).*\*\/\s*$/,this.tripleStarBlockCommentRe=/^\s*(\/\*\*\*).*\*\/\s*$/,this.startRegionRe=/^\s*(\/\*|\/\/)#?region\b/,this._getFoldWidgetBase=this.getFoldWidget,this.getFoldWidget=function(e,t,n){var r=e.getLine(n);if(this.singleLineBlockCommentRe.test(r)&&!this.startRegionRe.test(r)&&!this.tripleStarBlockCommentRe.test(r))return"";var i=this._getFoldWidgetBase(e,t,n);return!i&&this.startRegionRe.test(r)?"start":i},this.getFoldWidgetRange=function(e,t,n,r){var i=e.getLine(n);if(this.startRegionRe.test(i))return this.getCommentRegionBlock(e,i,n);var s=i.match(this.foldingStartMarker);if(s){var o=s.index;if(s[1])return this.openingBracketBlock(e,s[1],n,o);var u=e.getCommentFoldRange(n,o+s[0].length,1);return u&&!u.isMultiLine()&&(r?u=this.getSectionRange(e,n):t!="all"&&(u=null)),u}if(t==="markbegin")return;var s=i.match(this.foldingStopMarker);if(s){var o=s.index+s[0].length;return s[1]?this.closingBracketBlock(e,s[1],n,o):e.getCommentFoldRange(n,o,-1)}},this.getSectionRange=function(e,t){var n=e.getLine(t),r=n.search(/\S/),s=t,o=n.length;t+=1;var u=t,a=e.getLength();while(++tf)break;var l=this.getFoldWidgetRange(e,"all",t);if(l){if(l.start.row<=s)break;if(l.isMultiLine())t=l.end.row;else if(r==f)break}u=t}return new i(s,o,u,e.getLine(u).length)},this.getCommentRegionBlock=function(e,t,n){var r=t.search(/\s*$/),s=e.getLength(),o=n,u=/^\s*(?:\/\*|\/\/|--)#?(end)?region\b/,a=1;while(++no)return new i(o,r,l,t.length)}}.call(o.prototype)}),ace.define("ace/mode/javascript",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/javascript_highlight_rules","ace/mode/matching_brace_outdent","ace/worker/worker_client","ace/mode/behaviour/cstyle","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./javascript_highlight_rules").JavaScriptHighlightRules,o=e("./matching_brace_outdent").MatchingBraceOutdent,u=e("../worker/worker_client").WorkerClient,a=e("./behaviour/cstyle").CstyleBehaviour,f=e("./folding/cstyle").FoldMode,l=function(){this.HighlightRules=s,this.$outdent=new o,this.$behaviour=new a,this.foldingRules=new f};r.inherits(l,i),function(){this.lineCommentStart="//",this.blockComment={start:"/*",end:"*/"},this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),i=this.getTokenizer().getLineTokens(t,e),s=i.tokens,o=i.state;if(s.length&&s[s.length-1].type=="comment")return r;if(e=="start"||e=="no_regex"){var u=t.match(/^.*(?:\bcase\b.*:|[\{\(\[])\s*$/);u&&(r+=n)}else if(e=="doc-start"){if(o=="start"||o=="no_regex")return"";var u=t.match(/^\s*(\/?)\*/);u&&(u[1]&&(r+=" "),r+="* ")}return r},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.createWorker=function(e){var t=new u(["ace"],"ace/mode/javascript_worker","JavaScriptWorker");return t.attachToDocument(e.getDocument()),t.on("annotate",function(t){e.setAnnotations(t.data)}),t.on("terminate",function(){e.clearAnnotations()}),t},this.$id="ace/mode/javascript"}.call(l.prototype),t.Mode=l}) \ No newline at end of file diff --git a/examples/SmartSwitch/data_src/js_css_src/ace-drafts/worker-html.js b/examples/SmartSwitch/data_src/js_css_src/ace-drafts/worker-html.js deleted file mode 100644 index 58a39b130..000000000 --- a/examples/SmartSwitch/data_src/js_css_src/ace-drafts/worker-html.js +++ /dev/null @@ -1 +0,0 @@ -"no use strict";(function(e){function t(e,t){var n=e,r="";while(n){var i=t[n];if(typeof i=="string")return i+r;if(i)return i.location.replace(/\/*$/,"/")+(r||i.main||i.name);if(i===!1)return"";var s=n.lastIndexOf("/");if(s===-1)break;r=n.substr(s)+r,n=n.slice(0,s)}return e}if(typeof e.window!="undefined"&&e.document)return;if(e.require&&e.define)return;e.console||(e.console=function(){var e=Array.prototype.slice.call(arguments,0);postMessage({type:"log",data:e})},e.console.error=e.console.warn=e.console.log=e.console.trace=e.console),e.window=e,e.ace=e,e.onerror=function(e,t,n,r,i){postMessage({type:"error",data:{message:e,data:i.data,file:t,line:n,col:r,stack:i.stack}})},e.normalizeModule=function(t,n){if(n.indexOf("!")!==-1){var r=n.split("!");return e.normalizeModule(t,r[0])+"!"+e.normalizeModule(t,r[1])}if(n.charAt(0)=="."){var i=t.split("/").slice(0,-1).join("/");n=(i?i+"/":"")+n;while(n.indexOf(".")!==-1&&s!=n){var s=n;n=n.replace(/^\.\//,"").replace(/\/\.\//,"/").replace(/[^\/]+\/\.\.\//,"")}}return n},e.require=function(r,i){i||(i=r,r=null);if(!i.charAt)throw new Error("worker.js require() accepts only (parentId, id) as arguments");i=e.normalizeModule(r,i);var s=e.require.modules[i];if(s)return s.initialized||(s.initialized=!0,s.exports=s.factory().exports),s.exports;if(!e.require.tlns)return console.log("unable to load "+i);var o=t(i,e.require.tlns);return o.slice(-3)!=".js"&&(o+=".js"),e.require.id=i,e.require.modules[i]={},importScripts(o),e.require(r,i)},e.require.modules={},e.require.tlns={},e.define=function(t,n,r){arguments.length==2?(r=n,typeof t!="string"&&(n=t,t=e.require.id)):arguments.length==1&&(r=t,n=[],t=e.require.id);if(typeof r!="function"){e.require.modules[t]={exports:r,initialized:!0};return}n.length||(n=["require","exports","module"]);var i=function(n){return e.require(t,n)};e.require.modules[t]={exports:{},factory:function(){var e=this,t=r.apply(this,n.map(function(t){switch(t){case"require":return i;case"exports":return e.exports;case"module":return e;default:return i(t)}}));return t&&(e.exports=t),e}}},e.define.amd={},require.tlns={},e.initBaseUrls=function(t){for(var n in t)require.tlns[n]=t[n]},e.initSender=function(){var n=e.require("ace/lib/event_emitter").EventEmitter,r=e.require("ace/lib/oop"),i=function(){};return function(){r.implement(this,n),this.callback=function(e,t){postMessage({type:"call",id:t,data:e})},this.emit=function(e,t){postMessage({type:"event",name:e,data:t})}}.call(i.prototype),new i};var n=e.main=null,r=e.sender=null;e.onmessage=function(t){var i=t.data;if(i.event&&r)r._signal(i.event,i.data);else if(i.command)if(n[i.command])n[i.command].apply(n,i.args);else{if(!e[i.command])throw new Error("Unknown command:"+i.command);e[i.command].apply(e,i.args)}else if(i.init){e.initBaseUrls(i.tlns),require("ace/lib/es5-shim"),r=e.sender=e.initSender();var s=require(i.module)[i.classname];n=e.main=new s(r)}}})(this),define("ace/lib/oop",["require","exports","module"],function(e,t,n){"use strict";t.inherits=function(e,t){e.super_=t,e.prototype=Object.create(t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}})},t.mixin=function(e,t){for(var n in t)e[n]=t[n];return e},t.implement=function(e,n){t.mixin(e,n)}}),define("ace/lib/lang",["require","exports","module"],function(e,t,n){"use strict";t.last=function(e){return e[e.length-1]},t.stringReverse=function(e){return e.split("").reverse().join("")},t.stringRepeat=function(e,t){var n="";while(t>0){t&1&&(n+=e);if(t>>=1)e+=e}return n};var r=/^\s\s*/,i=/\s\s*$/;t.stringTrimLeft=function(e){return e.replace(r,"")},t.stringTrimRight=function(e){return e.replace(i,"")},t.copyObject=function(e){var t={};for(var n in e)t[n]=e[n];return t},t.copyArray=function(e){var t=[];for(var n=0,r=e.length;n ["+this.end.row+"/"+this.end.column+"]"},this.contains=function(e,t){return this.compare(e,t)==0},this.compareRange=function(e){var t,n=e.end,r=e.start;return t=this.compare(n.row,n.column),t==1?(t=this.compare(r.row,r.column),t==1?2:t==0?1:0):t==-1?-2:(t=this.compare(r.row,r.column),t==-1?-1:t==1?42:0)},this.comparePoint=function(e){return this.compare(e.row,e.column)},this.containsRange=function(e){return this.comparePoint(e.start)==0&&this.comparePoint(e.end)==0},this.intersects=function(e){var t=this.compareRange(e);return t==-1||t==0||t==1},this.isEnd=function(e,t){return this.end.row==e&&this.end.column==t},this.isStart=function(e,t){return this.start.row==e&&this.start.column==t},this.setStart=function(e,t){typeof e=="object"?(this.start.column=e.column,this.start.row=e.row):(this.start.row=e,this.start.column=t)},this.setEnd=function(e,t){typeof e=="object"?(this.end.column=e.column,this.end.row=e.row):(this.end.row=e,this.end.column=t)},this.inside=function(e,t){return this.compare(e,t)==0?this.isEnd(e,t)||this.isStart(e,t)?!1:!0:!1},this.insideStart=function(e,t){return this.compare(e,t)==0?this.isEnd(e,t)?!1:!0:!1},this.insideEnd=function(e,t){return this.compare(e,t)==0?this.isStart(e,t)?!1:!0:!1},this.compare=function(e,t){return!this.isMultiLine()&&e===this.start.row?tthis.end.column?1:0:ethis.end.row?1:this.start.row===e?t>=this.start.column?0:-1:this.end.row===e?t<=this.end.column?0:1:0},this.compareStart=function(e,t){return this.start.row==e&&this.start.column==t?-1:this.compare(e,t)},this.compareEnd=function(e,t){return this.end.row==e&&this.end.column==t?1:this.compare(e,t)},this.compareInside=function(e,t){return this.end.row==e&&this.end.column==t?1:this.start.row==e&&this.start.column==t?-1:this.compare(e,t)},this.clipRows=function(e,t){if(this.end.row>t)var n={row:t+1,column:0};else if(this.end.rowt)var r={row:t+1,column:0};else if(this.start.row=0&&t.row=0&&t.column<=e[t.row].length}function s(e,t){t.action!="insert"&&t.action!="remove"&&r(t,"delta.action must be 'insert' or 'remove'"),t.lines instanceof Array||r(t,"delta.lines must be an Array"),(!t.start||!t.end)&&r(t,"delta.start/end must be an present");var n=t.start;i(e,t.start)||r(t,"delta.start must be contained in document");var s=t.end;t.action=="remove"&&!i(e,s)&&r(t,"delta.end must contained in document for 'remove' actions");var o=s.row-n.row,u=s.column-(o==0?n.column:0);(o!=t.lines.length-1||t.lines[o].length!=u)&&r(t,"delta.range must match delta lines")}t.applyDelta=function(e,t,n){var r=t.start.row,i=t.start.column,s=e[r]||"";switch(t.action){case"insert":var o=t.lines;if(o.length===1)e[r]=s.substring(0,i)+t.lines[0]+s.substring(i);else{var u=[r,1].concat(t.lines);e.splice.apply(e,u),e[r]=s.substring(0,i)+e[r],e[r+t.lines.length-1]+=s.substring(i)}break;case"remove":var a=t.end.column,f=t.end.row;r===f?e[r]=s.substring(0,i)+s.substring(a):e.splice(r,f-r+1,s.substring(0,i)+e[f].substring(a))}}}),define("ace/lib/event_emitter",["require","exports","module"],function(e,t,n){"use strict";var r={},i=function(){this.propagationStopped=!0},s=function(){this.defaultPrevented=!0};r._emit=r._dispatchEvent=function(e,t){this._eventRegistry||(this._eventRegistry={}),this._defaultHandlers||(this._defaultHandlers={});var n=this._eventRegistry[e]||[],r=this._defaultHandlers[e];if(!n.length&&!r)return;if(typeof t!="object"||!t)t={};t.type||(t.type=e),t.stopPropagation||(t.stopPropagation=i),t.preventDefault||(t.preventDefault=s),n=n.slice();for(var o=0;othis.row)return;var n=t(e,{row:this.row,column:this.column},this.$insertRight);this.setPosition(n.row,n.column,!0)},this.setPosition=function(e,t,n){var r;n?r={row:e,column:t}:r=this.$clipPositionToDocument(e,t);if(this.row==r.row&&this.column==r.column)return;var i={row:this.row,column:this.column};this.row=r.row,this.column=r.column,this._signal("change",{old:i,value:r})},this.detach=function(){this.document.removeEventListener("change",this.$onChange)},this.attach=function(e){this.document=e||this.document,this.document.on("change",this.$onChange)},this.$clipPositionToDocument=function(e,t){var n={};return e>=this.document.getLength()?(n.row=Math.max(0,this.document.getLength()-1),n.column=this.document.getLine(n.row).length):e<0?(n.row=0,n.column=0):(n.row=e,n.column=Math.min(this.document.getLine(n.row).length,Math.max(0,t))),t<0&&(n.column=0),n}}).call(s.prototype)}),define("ace/document",["require","exports","module","ace/lib/oop","ace/apply_delta","ace/lib/event_emitter","ace/range","ace/anchor"],function(e,t,n){"use strict";var r=e("./lib/oop"),i=e("./apply_delta").applyDelta,s=e("./lib/event_emitter").EventEmitter,o=e("./range").Range,u=e("./anchor").Anchor,a=function(e){this.$lines=[""],e.length===0?this.$lines=[""]:Array.isArray(e)?this.insertMergedLines({row:0,column:0},e):this.insert({row:0,column:0},e)};(function(){r.implement(this,s),this.setValue=function(e){var t=this.getLength()-1;this.remove(new o(0,0,t,this.getLine(t).length)),this.insert({row:0,column:0},e)},this.getValue=function(){return this.getAllLines().join(this.getNewLineCharacter())},this.createAnchor=function(e,t){return new u(this,e,t)},"aaa".split(/a/).length===0?this.$split=function(e){return e.replace(/\r\n|\r/g,"\n").split("\n")}:this.$split=function(e){return e.split(/\r\n|\r|\n/)},this.$detectNewLine=function(e){var t=e.match(/^.*?(\r\n|\r|\n)/m);this.$autoNewLine=t?t[1]:"\n",this._signal("changeNewLineMode")},this.getNewLineCharacter=function(){switch(this.$newLineMode){case"windows":return"\r\n";case"unix":return"\n";default:return this.$autoNewLine||"\n"}},this.$autoNewLine="",this.$newLineMode="auto",this.setNewLineMode=function(e){if(this.$newLineMode===e)return;this.$newLineMode=e,this._signal("changeNewLineMode")},this.getNewLineMode=function(){return this.$newLineMode},this.isNewLine=function(e){return e=="\r\n"||e=="\r"||e=="\n"},this.getLine=function(e){return this.$lines[e]||""},this.getLines=function(e,t){return this.$lines.slice(e,t+1)},this.getAllLines=function(){return this.getLines(0,this.getLength())},this.getLength=function(){return this.$lines.length},this.getTextRange=function(e){return this.getLinesForRange(e).join(this.getNewLineCharacter())},this.getLinesForRange=function(e){var t;if(e.start.row===e.end.row)t=[this.getLine(e.start.row).substring(e.start.column,e.end.column)];else{t=this.getLines(e.start.row,e.end.row),t[0]=(t[0]||"").substring(e.start.column);var n=t.length-1;e.end.row-e.start.row==n&&(t[n]=t[n].substring(0,e.end.column))}return t},this.insertLines=function(e,t){return console.warn("Use of document.insertLines is deprecated. Use the insertFullLines method instead."),this.insertFullLines(e,t)},this.removeLines=function(e,t){return console.warn("Use of document.removeLines is deprecated. Use the removeFullLines method instead."),this.removeFullLines(e,t)},this.insertNewLine=function(e){return console.warn("Use of document.insertNewLine is deprecated. Use insertMergedLines(position, ['', '']) instead."),this.insertMergedLines(e,["",""])},this.insert=function(e,t){return this.getLength()<=1&&this.$detectNewLine(t),this.insertMergedLines(e,this.$split(t))},this.insertInLine=function(e,t){var n=this.clippedPos(e.row,e.column),r=this.pos(e.row,e.column+t.length);return this.applyDelta({start:n,end:r,action:"insert",lines:[t]},!0),this.clonePos(r)},this.clippedPos=function(e,t){var n=this.getLength();e===undefined?e=n:e<0?e=0:e>=n&&(e=n-1,t=undefined);var r=this.getLine(e);return t==undefined&&(t=r.length),t=Math.min(Math.max(t,0),r.length),{row:e,column:t}},this.clonePos=function(e){return{row:e.row,column:e.column}},this.pos=function(e,t){return{row:e,column:t}},this.$clipPosition=function(e){var t=this.getLength();return e.row>=t?(e.row=Math.max(0,t-1),e.column=this.getLine(t-1).length):(e.row=Math.max(0,e.row),e.column=Math.min(Math.max(e.column,0),this.getLine(e.row).length)),e},this.insertFullLines=function(e,t){e=Math.min(Math.max(e,0),this.getLength());var n=0;e0,r=t=0&&this.applyDelta({start:this.pos(e,this.getLine(e).length),end:this.pos(e+1,0),action:"remove",lines:["",""]})},this.replace=function(e,t){e instanceof o||(e=o.fromPoints(e.start,e.end));if(t.length===0&&e.isEmpty())return e.start;if(t==this.getTextRange(e))return e.end;this.remove(e);var n;return t?n=this.insert(e.start,t):n=e.start,n},this.applyDeltas=function(e){for(var t=0;t=0;t--)this.revertDelta(e[t])},this.applyDelta=function(e,t){var n=e.action=="insert";if(n?e.lines.length<=1&&!e.lines[0]:!o.comparePoints(e.start,e.end))return;n&&e.lines.length>2e4&&this.$splitAndapplyLargeDelta(e,2e4),i(this.$lines,e,t),this._signal("change",e)},this.$splitAndapplyLargeDelta=function(e,t){var n=e.lines,r=n.length,i=e.start.row,s=e.start.column,o=0,u=0;do{o=u,u+=t-1;var a=n.slice(o,u);if(u>r){e.lines=a,e.start.row=i+o,e.start.column=s;break}a.push(""),this.applyDelta({start:this.pos(i+o,s),end:this.pos(i+u,s=0),action:e.action,lines:a},!0)}while(!0)},this.revertDelta=function(e){this.applyDelta({start:this.clonePos(e.start),end:this.clonePos(e.end),action:e.action=="insert"?"remove":"insert",lines:e.lines.slice()})},this.indexToPosition=function(e,t){var n=this.$lines||this.getAllLines(),r=this.getNewLineCharacter().length;for(var i=t||0,s=n.length;i=0;n--){var r=this.elements[n];if(r.localName===e)return!0;if(t(r))return!1}},l.prototype.push=function(e){this.elements.push(e)},l.prototype.pushHtmlElement=function(e){this.rootNode=e.node,this.push(e)},l.prototype.pushHeadElement=function(e){this.headElement=e.node,this.push(e)},l.prototype.pushBodyElement=function(e){this.bodyElement=e.node,this.push(e)},l.prototype.pop=function(){return this.elements.pop()},l.prototype.remove=function(e){this.elements.splice(this.elements.indexOf(e),1)},l.prototype.popUntilPopped=function(e){var t;do t=this.pop();while(t.localName!=e)},l.prototype.popUntilTableScopeMarker=function(){while(!s(this.top))this.pop()},l.prototype.popUntilTableBodyScopeMarker=function(){while(!o(this.top))this.pop()},l.prototype.popUntilTableRowScopeMarker=function(){while(!u(this.top))this.pop()},l.prototype.item=function(e){return this.elements[e]},l.prototype.contains=function(e){return this.elements.indexOf(e)!==-1},l.prototype.inScope=function(e){return this._inScope(e,r)},l.prototype.inListItemScope=function(e){return this._inScope(e,i)},l.prototype.inTableScope=function(e){return this._inScope(e,s)},l.prototype.inButtonScope=function(e){return this._inScope(e,a)},l.prototype.inSelectScope=function(e){return this._inScope(e,f)},l.prototype.hasNumberedHeaderElementInScope=function(){for(var e=this.elements.length-1;e>=0;e--){var t=this.elements[e];if(t.isNumberedHeader())return!0;if(r(t))return!1}},l.prototype.furthestBlockForFormattingElement=function(e){var t=null;for(var n=this.elements.length-1;n>=0;n--){var r=this.elements[n];if(r.node===e)break;r.isSpecial()&&(t=r)}return t},l.prototype.findIndex=function(e){for(var t=this.elements.length-1;t>=0;t--)if(this.elements[t].localName==e)return t;return-1},l.prototype.remove_openElements_until=function(e){var t=!1,n;while(!t)n=this.elements.pop(),t=e(n);return n},Object.defineProperty(l.prototype,"top",{get:function(){return this.elements[this.elements.length-1]}}),Object.defineProperty(l.prototype,"length",{get:function(){return this.elements.length}}),n.ElementStack=l},{}],2:[function(e,t,n){function o(e){return e>="0"&&e<="9"||e>="a"&&e<="z"||e>="A"&&e<="Z"}function u(e){return e>="0"&&e<="9"||e>="a"&&e<="f"||e>="A"&&e<="F"}function a(e){return e>="0"&&e<="9"}var r=e("html5-entities"),i=e("./InputStream").InputStream,s={};Object.keys(r).forEach(function(e){for(var t=0;t65535&&d<=1114111){d-=65536;var m=((1047552&d)>>10)+55296,g=(1023&d)+56320;f=String.fromCharCode(m,g)}else f=String.fromCharCode(d);return c!==";"&&(t._parseError("numeric-entity-without-semicolon"),e.unget(c)),f}return e.unget(l),t._parseError("expected-numeric-entity"),!1}if(c>="a"&&c<="z"||c>="A"&&c<="Z"){var y="";while(s[l]){r[l]&&(y=l);if(c==";")break;c=e.char();if(c===i.EOF)break;l+=c}return y?(f=r[y],c===";"||!n||!o(c)&&c!=="="?(l.length>y.length&&e.unget(l.substring(y.length)),c!==";"&&t._parseError("named-entity-without-semicolon"),f):(e.unget(l),!1)):(t._parseError("expected-named-entity"),e.unget(l),!1)}},f.replaceEntityNumbers=function(e){switch(e){case 0:return 65533;case 19:return 16;case 128:return 8364;case 129:return 129;case 130:return 8218;case 131:return 402;case 132:return 8222;case 133:return 8230;case 134:return 8224;case 135:return 8225;case 136:return 710;case 137:return 8240;case 138:return 352;case 139:return 8249;case 140:return 338;case 141:return 141;case 142:return 381;case 143:return 143;case 144:return 144;case 145:return 8216;case 146:return 8217;case 147:return 8220;case 148:return 8221;case 149:return 8226;case 150:return 8211;case 151:return 8212;case 152:return 732;case 153:return 8482;case 154:return 353;case 155:return 8250;case 156:return 339;case 157:return 157;case 158:return 382;case 159:return 376;default:if(e>=55296&&e<=57343||e>1114111)return 65533;if(e>=1&&e<=8||e>=14&&e<=31||e>=127&&e<=159||e>=64976&&e<=65007||e==11||e==65534||e==131070||e==3145726||e==196607||e==262142||e==262143||e==327678||e==327679||e==393214||e==393215||e==458750||e==458751||e==524286||e==524287||e==589822||e==589823||e==655358||e==655359||e==720894||e==720895||e==786430||e==786431||e==851966||e==851967||e==917502||e==917503||e==983038||e==983039||e==1048574||e==1048575||e==1114110||e==1114111)return e}},n.EntityParser=f},{"./InputStream":3,"html5-entities":12}],3:[function(e,t,n){function r(){this.data="",this.start=0,this.committed=0,this.eof=!1,this.lastLocation={line:0,column:0}}r.EOF=-1,r.DRAIN=-2,r.prototype={slice:function(){if(this.start>=this.data.length){if(!this.eof)throw r.DRAIN;return r.EOF}return this.data.slice(this.start,this.data.length)},"char":function(){if(!this.eof&&this.start>=this.data.length-1)throw r.DRAIN;if(this.start>=this.data.length)return r.EOF;var e=this.data[this.start++];return e==="\r"&&(e="\n"),e},advance:function(e){this.start+=e;if(this.start>=this.data.length){if(!this.eof)throw r.DRAIN;return r.EOF}this.committed>this.data.length/2&&(this.lastLocation=this.location(),this.data=this.data.slice(this.committed),this.start=this.start-this.committed,this.committed=0)},matchWhile:function(e){if(this.eof&&this.start>=this.data.length)return"";var t=new RegExp("^"+e+"+"),n=t.exec(this.slice());if(n){if(!this.eof&&n[0].length==this.data.length-this.start)throw r.DRAIN;return this.advance(n[0].length),n[0]}return""},matchUntil:function(e){var t,n;n=this.slice();if(n===r.EOF)return"";if(t=(new RegExp(e+(this.eof?"|$":""))).exec(n)){var i=this.data.slice(this.start,this.start+t.index);return this.advance(t.index),i.replace(/\r/g,"\n").replace(/\n{2,}/g,"\n")}throw r.DRAIN},append:function(e){this.data+=e},shift:function(e){if(!this.eof&&this.start+e>=this.data.length)throw r.DRAIN;if(this.eof&&this.start>=this.data.length)return r.EOF;var t=this.data.slice(this.start,this.start+e).toString();return this.advance(Math.min(e,this.data.length-this.start)),t},peek:function(e){if(!this.eof&&this.start+e>=this.data.length)throw r.DRAIN;return this.eof&&this.start>=this.data.length?r.EOF:this.data.slice(this.start,Math.min(this.start+e,this.data.length)).toString()},length:function(){return this.data.length-this.start-1},unget:function(e){if(e===r.EOF)return;this.start-=e.length},undo:function(){this.start=this.committed},commit:function(){this.committed=this.start},location:function(){var e=this.lastLocation.line,t=this.lastLocation.column,n=this.data.slice(0,this.committed),r=n.match(/\n/g),i=r?e+r.length:e,s=r?n.length-n.lastIndexOf("\n")-1:t+n.length;return{line:i,column:s}}},n.InputStream=r},{}],4:[function(e,t,n){function i(e,t,n,r){this.localName=t,this.namespaceURI=e,this.attributes=n,this.node=r}function s(e,t){for(var n=0;n-1},i.prototype.isFosterParenting=function(){return this.namespaceURI==="http://www.w3.org/1999/xhtml"?this.localName==="table"||this.localName==="tbody"||this.localName==="tfoot"||this.localName==="thead"||this.localName==="tr":!1},i.prototype.isNumberedHeader=function(){return this.namespaceURI==="http://www.w3.org/1999/xhtml"?this.localName==="h1"||this.localName==="h2"||this.localName==="h3"||this.localName==="h4"||this.localName==="h5"||this.localName==="h6":!1},i.prototype.isForeign=function(){return this.namespaceURI!="http://www.w3.org/1999/xhtml"},i.prototype.isHtmlIntegrationPoint=function(){if(this.namespaceURI==="http://www.w3.org/1998/Math/MathML"){if(this.localName!=="annotation-xml")return!1;var e=s(this,"encoding");return e?(e=e.toLowerCase(),e==="text/html"||e==="application/xhtml+xml"):!1}return this.namespaceURI==="http://www.w3.org/2000/svg"?this.localName==="foreignObject"||this.localName==="desc"||this.localName==="title":!1},i.prototype.isMathMLTextIntegrationPoint=function(){return this.namespaceURI==="http://www.w3.org/1998/Math/MathML"?this.localName==="mi"||this.localName==="mo"||this.localName==="mn"||this.localName==="ms"||this.localName==="mtext":!1},n.StackItem=i},{}],5:[function(e,t,n){function s(e){return e===" "||e==="\n"||e===" "||e==="\r"||e==="\f"}function o(e){return e>="A"&&e<="Z"||e>="a"&&e<="z"}function u(e){this._tokenHandler=e,this._state=u.DATA,this._inputStream=new r,this._currentToken=null,this._temporaryBuffer="",this._additionalAllowedCharacter=""}var r=e("./InputStream").InputStream,i=e("./EntityParser").EntityParser;u.prototype._parseError=function(e,t){this._tokenHandler.parseError(e,t)},u.prototype._emitToken=function(e){if(e.type==="StartTag")for(var t=1;t"&&r?(t._currentToken={type:"EndTag",name:this._temporaryBuffer,data:[],selfClosing:!1},t._emitCurrentToken(),t.setState(n)):o(i)?(this._temporaryBuffer+=i,e.commit()):(t._emitToken({type:"Characters",data:""&&r?(t._currentToken={type:"EndTag",name:this._temporaryBuffer,data:[],selfClosing:!1},t._emitCurrentToken(),t.setState(n)):o(i)?(this._temporaryBuffer+=i,e.commit()):(t._emitToken({type:"Characters",data:""&&n?(t._currentToken={type:"EndTag",name:"script",data:[],selfClosing:!1},t._emitCurrentToken()):o(r)?(this._temporaryBuffer+=r,e.commit()):(t._emitToken({type:"Characters",data:""?(t._emitToken({type:"Characters",data:">"}),t.setState(p)):i==="\0"?(t._parseError("invalid-codepoint"),t._emitToken({type:"Characters",data:"\ufffd"}),t.setState(N)):(t._emitToken({type:"Characters",data:i}),t.setState(N)),!0}function L(e){var n=e.char();return n==="/"?(this._temporaryBuffer="",t.setState(A)):o(n)?(t._emitToken({type:"Characters",data:"<"+n}),this._temporaryBuffer=n,t.setState(M)):(t._emitToken({type:"Characters",data:"<"}),e.unget(n),t.setState(N)),!0}function A(e){var n=e.char();return o(n)?(this._temporaryBuffer=n,t.setState(O)):(t._emitToken({type:"Characters",data:""&&r?(t._currentToken={type:"EndTag",name:"script",data:[],selfClosing:!1},t.setState(n),t._emitCurrentToken()):o(i)?(this._temporaryBuffer+=i,e.commit()):(t._emitToken({type:"Characters",data:""?(t._emitToken({type:"Characters",data:n}),this._temporaryBuffer.toLowerCase()==="script"?t.setState(_):t.setState(N)):o(n)?(t._emitToken({type:"Characters",data:n}),this._temporaryBuffer+=n,e.commit()):(e.unget(n),t.setState(N)),!0}function _(e){var i=e.char();return i===r.EOF?(t._parseError("eof-in-script"),e.unget(i),t.setState(n)):i==="-"?(t._emitToken({type:"Characters",data:"-"}),t.setState(D)):i==="<"?(t._emitToken({type:"Characters",data:"<"}),t.setState(H)):i==="\0"?(t._parseError("invalid-codepoint"),t._emitToken({type:"Characters",data:"\ufffd"}),e.commit()):(t._emitToken({type:"Characters",data:i}),e.commit()),!0}function D(e){var i=e.char();return i===r.EOF?(t._parseError("eof-in-script"),e.unget(i),t.setState(n)):i==="-"?(t._emitToken({type:"Characters",data:"-"}),t.setState(P)):i==="<"?(t._emitToken({type:"Characters",data:"<"}),t.setState(H)):i==="\0"?(t._parseError("invalid-codepoint"),t._emitToken({type:"Characters",data:"\ufffd"}),t.setState(_)):(t._emitToken({type:"Characters",data:i}),t.setState(_)),!0}function P(e){var i=e.char();return i===r.EOF?(t._parseError("eof-in-script"),e.unget(i),t.setState(n)):i==="-"?(t._emitToken({type:"Characters",data:"-"}),e.commit()):i==="<"?(t._emitToken({type:"Characters",data:"<"}),t.setState(H)):i===">"?(t._emitToken({type:"Characters",data:">"}),t.setState(p)):i==="\0"?(t._parseError("invalid-codepoint"),t._emitToken({type:"Characters",data:"\ufffd"}),t.setState(_)):(t._emitToken({type:"Characters",data:i}),t.setState(_)),!0}function H(e){var n=e.char();return n==="/"?(t._emitToken({type:"Characters",data:"/"}),this._temporaryBuffer="",t.setState(B)):(e.unget(n),t.setState(_)),!0}function B(e){var n=e.char();return s(n)||n==="/"||n===">"?(t._emitToken({type:"Characters",data:n}),this._temporaryBuffer.toLowerCase()==="script"?t.setState(N):t.setState(_)):o(n)?(t._emitToken({type:"Characters",data:n}),this._temporaryBuffer+=n,e.commit()):(e.unget(n),t.setState(_)),!0}function j(e){var i=e.char();return i===r.EOF?(t._parseError("bare-less-than-sign-at-eof"),t._emitToken({type:"Characters",data:"<"}),e.unget(i),t.setState(n)):o(i)?(t._currentToken={type:"StartTag",name:i.toLowerCase(),data:[]},t.setState(I)):i==="!"?t.setState(G):i==="/"?t.setState(F):i===">"?(t._parseError("expected-tag-name-but-got-right-bracket"),t._emitToken({type:"Characters",data:"<>"}),t.setState(n)):i==="?"?(t._parseError("expected-tag-name-but-got-question-mark"),e.unget(i),t.setState(Q)):(t._parseError("expected-tag-name"),t._emitToken({type:"Characters",data:"<"}),e.unget(i),t.setState(n)),!0}function F(e){var i=e.char();return i===r.EOF?(t._parseError("expected-closing-tag-but-got-eof"),t._emitToken({type:"Characters",data:""?(t._parseError("expected-closing-tag-but-got-right-bracket"),t.setState(n)):(t._parseError("expected-closing-tag-but-got-char",{data:i}),e.unget(i),t.setState(Q)),!0}function I(e){var i=e.char();return i===r.EOF?(t._parseError("eof-in-tag-name"),e.unget(i),t.setState(n)):s(i)?t.setState(q):o(i)?t._currentToken.name+=i.toLowerCase():i===">"?t._emitCurrentToken():i==="/"?t.setState(K):i==="\0"?(t._parseError("invalid-codepoint"),t._currentToken.name+="\ufffd"):t._currentToken.name+=i,e.commit(),!0}function q(e){var i=e.char();if(i===r.EOF)t._parseError("expected-attribute-name-but-got-eof"),e.unget(i),t.setState(n);else{if(s(i))return!0;o(i)?(t._currentToken.data.push({nodeName:i.toLowerCase(),nodeValue:""}),t.setState(R)):i===">"?t._emitCurrentToken():i==="/"?t.setState(K):i==="'"||i==='"'||i==="="||i==="<"?(t._parseError("invalid-character-in-attribute-name"),t._currentToken.data.push({nodeName:i,nodeValue:""}),t.setState(R)):i==="\0"?(t._parseError("invalid-codepoint"),t._currentToken.data.push({nodeName:"\ufffd",nodeValue:""})):(t._currentToken.data.push({nodeName:i,nodeValue:""}),t.setState(R))}return!0}function R(e){var i=e.char(),u=!0,a=!1;i===r.EOF?(t._parseError("eof-in-attribute-name"),e.unget(i),t.setState(n),a=!0):i==="="?t.setState(z):o(i)?(t._currentAttribute().nodeName+=i.toLowerCase(),u=!1):i===">"?a=!0:s(i)?t.setState(U):i==="/"?t.setState(K):i==="'"||i==='"'?(t._parseError("invalid-character-in-attribute-name"),t._currentAttribute().nodeName+=i,u=!1):i==="\0"?(t._parseError("invalid-codepoint"),t._currentAttribute().nodeName+="\ufffd"):(t._currentAttribute().nodeName+=i,u=!1);if(u){var f=t._currentToken.data,l=f[f.length-1];for(var c=f.length-2;c>=0;c--)if(l.nodeName===f[c].nodeName){t._parseError("duplicate-attribute",{name:l.nodeName}),l.nodeName=null;break}a&&t._emitCurrentToken()}else e.commit();return!0}function U(e){var i=e.char();if(i===r.EOF)t._parseError("expected-end-of-tag-but-got-eof"),e.unget(i),t.setState(n);else{if(s(i))return!0;i==="="?t.setState(z):i===">"?t._emitCurrentToken():o(i)?(t._currentToken.data.push({nodeName:i,nodeValue:""}),t.setState(R)):i==="/"?t.setState(K):i==="'"||i==='"'||i==="<"?(t._parseError("invalid-character-after-attribute-name"),t._currentToken.data.push({nodeName:i,nodeValue:""}),t.setState(R)):i==="\0"?(t._parseError("invalid-codepoint"),t._currentToken.data.push({nodeName:"\ufffd",nodeValue:""})):(t._currentToken.data.push({nodeName:i,nodeValue:""}),t.setState(R))}return!0}function z(e){var i=e.char();if(i===r.EOF)t._parseError("expected-attribute-value-but-got-eof"),e.unget(i),t.setState(n);else{if(s(i))return!0;i==='"'?t.setState(W):i==="&"?(t.setState(V),e.unget(i)):i==="'"?t.setState(X):i===">"?(t._parseError("expected-attribute-value-but-got-right-bracket"),t._emitCurrentToken()):i==="="||i==="<"||i==="`"?(t._parseError("unexpected-character-in-unquoted-attribute-value"),t._currentAttribute().nodeValue+=i,t.setState(V)):i==="\0"?(t._parseError("invalid-codepoint"),t._currentAttribute().nodeValue+="\ufffd"):(t._currentAttribute().nodeValue+=i,t.setState(V))}return!0}function W(e){var i=e.char();if(i===r.EOF)t._parseError("eof-in-attribute-value-double-quote"),e.unget(i),t.setState(n);else if(i==='"')t.setState(J);else if(i==="&")this._additionalAllowedCharacter='"',t.setState($);else if(i==="\0")t._parseError("invalid-codepoint"),t._currentAttribute().nodeValue+="\ufffd";else{var s=e.matchUntil('[\0"&]');i+=s,t._currentAttribute().nodeValue+=i}return!0}function X(e){var i=e.char();return i===r.EOF?(t._parseError("eof-in-attribute-value-single-quote"),e.unget(i),t.setState(n)):i==="'"?t.setState(J):i==="&"?(this._additionalAllowedCharacter="'",t.setState($)):i==="\0"?(t._parseError("invalid-codepoint"),t._currentAttribute().nodeValue+="\ufffd"):t._currentAttribute().nodeValue+=i+e.matchUntil("\0|['&]"),!0}function V(e){var i=e.char();if(i===r.EOF)t._parseError("eof-after-attribute-value"),e.unget(i),t.setState(n);else if(s(i))t.setState(q);else if(i==="&")this._additionalAllowedCharacter=">",t.setState($);else if(i===">")t._emitCurrentToken();else if(i==='"'||i==="'"||i==="="||i==="`"||i==="<")t._parseError("unexpected-character-in-unquoted-attribute-value"),t._currentAttribute().nodeValue+=i,e.commit();else if(i==="\0")t._parseError("invalid-codepoint"),t._currentAttribute().nodeValue+="\ufffd";else{var o=e.matchUntil("\0|[ \n \f \r&<>\"'=`]");o===r.EOF&&(t._parseError("eof-in-attribute-value-no-quotes"),t._emitCurrentToken()),e.commit(),t._currentAttribute().nodeValue+=i+o}return!0}function $(e){var n=i.consumeEntity(e,t,this._additionalAllowedCharacter);return this._currentAttribute().nodeValue+=n||"&",this._additionalAllowedCharacter==='"'?t.setState(W):this._additionalAllowedCharacter==="'"?t.setState(X):this._additionalAllowedCharacter===">"&&t.setState(V),!0}function J(e){var i=e.char();return i===r.EOF?(t._parseError("eof-after-attribute-value"),e.unget(i),t.setState(n)):s(i)?t.setState(q):i===">"?(t.setState(n),t._emitCurrentToken()):i==="/"?t.setState(K):(t._parseError("unexpected-character-after-attribute-value"),e.unget(i),t.setState(q)),!0}function K(e){var i=e.char();return i===r.EOF?(t._parseError("unexpected-eof-after-solidus-in-tag"),e.unget(i),t.setState(n)):i===">"?(t._currentToken.selfClosing=!0,t.setState(n),t._emitCurrentToken()):(t._parseError("unexpected-character-after-solidus-in-tag"),e.unget(i),t.setState(q)),!0}function Q(e){var r=e.matchUntil(">");return r=r.replace(/\u0000/g,"\ufffd"),e.char(),t._emitToken({type:"Comment",data:r}),t.setState(n),!0}function G(e){var n=e.shift(2);if(n==="--")t._currentToken={type:"Comment",data:""},t.setState(Z);else{var i=e.shift(5);if(i===r.EOF||n===r.EOF)return t._parseError("expected-dashes-or-doctype"),t.setState(Q),e.unget(n),!0;n+=i,n.toUpperCase()==="DOCTYPE"?(t._currentToken={type:"Doctype",name:"",publicId:null,systemId:null,forceQuirks:!1},t.setState(st)):t._tokenHandler.isCdataSectionAllowed()&&n==="[CDATA["?t.setState(Y):(t._parseError("expected-dashes-or-doctype"),e.unget(n),t.setState(Q))}return!0}function Y(e){var r=e.matchUntil("]]>");return e.shift(3),r&&t._emitToken({type:"Characters",data:r}),t.setState(n),!0}function Z(e){var i=e.char();return i===r.EOF?(t._parseError("eof-in-comment"),t._emitToken(t._currentToken),e.unget(i),t.setState(n)):i==="-"?t.setState(et):i===">"?(t._parseError("incorrect-comment"),t._emitToken(t._currentToken),t.setState(n)):i==="\0"?(t._parseError("invalid-codepoint"),t._currentToken.data+="\ufffd"):(t._currentToken.data+=i,t.setState(tt)),!0}function et(e){var i=e.char();return i===r.EOF?(t._parseError("eof-in-comment"),t._emitToken(t._currentToken),e.unget(i),t.setState(n)):i==="-"?t.setState(rt):i===">"?(t._parseError("incorrect-comment"),t._emitToken(t._currentToken),t.setState(n)):i==="\0"?(t._parseError("invalid-codepoint"),t._currentToken.data+="\ufffd"):(t._currentToken.data+="-"+i,t.setState(tt)),!0}function tt(e){var i=e.char();return i===r.EOF?(t._parseError("eof-in-comment"),t._emitToken(t._currentToken),e.unget(i),t.setState(n)):i==="-"?t.setState(nt):i==="\0"?(t._parseError("invalid-codepoint"),t._currentToken.data+="\ufffd"):(t._currentToken.data+=i,e.commit()),!0}function nt(e){var i=e.char();return i===r.EOF?(t._parseError("eof-in-comment-end-dash"),t._emitToken(t._currentToken),e.unget(i),t.setState(n)):i==="-"?t.setState(rt):i==="\0"?(t._parseError("invalid-codepoint"),t._currentToken.data+="-\ufffd",t.setState(tt)):(t._currentToken.data+="-"+i+e.matchUntil("\0|-"),e.char()),!0}function rt(e){var i=e.char();return i===r.EOF?(t._parseError("eof-in-comment-double-dash"),t._emitToken(t._currentToken),e.unget(i),t.setState(n)):i===">"?(t._emitToken(t._currentToken),t.setState(n)):i==="!"?(t._parseError("unexpected-bang-after-double-dash-in-comment"),t.setState(it)):i==="-"?(t._parseError("unexpected-dash-after-double-dash-in-comment"),t._currentToken.data+=i):i==="\0"?(t._parseError("invalid-codepoint"),t._currentToken.data+="--\ufffd",t.setState(tt)):(t._parseError("unexpected-char-in-comment"),t._currentToken.data+="--"+i,t.setState(tt)),!0}function it(e){var i=e.char();return i===r.EOF?(t._parseError("eof-in-comment-end-bang-state"),t._emitToken(t._currentToken),e.unget(i),t.setState(n)):i===">"?(t._emitToken(t._currentToken),t.setState(n)):i==="-"?(t._currentToken.data+="--!",t.setState(nt)):(t._currentToken.data+="--!"+i,t.setState(tt)),!0}function st(e){var i=e.char();return i===r.EOF?(t._parseError("expected-doctype-name-but-got-eof"),t._currentToken.forceQuirks=!0,e.unget(i),t.setState(n),t._emitCurrentToken()):s(i)?t.setState(ot):(t._parseError("need-space-after-doctype"),e.unget(i),t.setState(ot)),!0}function ot(e){var i=e.char();return i===r.EOF?(t._parseError("expected-doctype-name-but-got-eof"),t._currentToken.forceQuirks=!0,e.unget(i),t.setState(n),t._emitCurrentToken()):s(i)||(i===">"?(t._parseError("expected-doctype-name-but-got-right-bracket"),t._currentToken.forceQuirks=!0,t.setState(n),t._emitCurrentToken()):(o(i)&&(i=i.toLowerCase()),t._currentToken.name=i,t.setState(ut))),!0}function ut(e){var i=e.char();return i===r.EOF?(t._currentToken.forceQuirks=!0,e.unget(i),t._parseError("eof-in-doctype-name"),t.setState(n),t._emitCurrentToken()):s(i)?t.setState(at):i===">"?(t.setState(n),t._emitCurrentToken()):(o(i)&&(i=i.toLowerCase()),t._currentToken.name+=i,e.commit()),!0}function at(e){var i=e.char();if(i===r.EOF)t._currentToken.forceQuirks=!0,e.unget(i),t._parseError("eof-in-doctype"),t.setState(n),t._emitCurrentToken();else if(!s(i))if(i===">")t.setState(n),t._emitCurrentToken();else{if(["p","P"].indexOf(i)>-1){var o=[["u","U"],["b","B"],["l","L"],["i","I"],["c","C"]],u=o.every(function(t){return i=e.char(),t.indexOf(i)>-1});if(u)return t.setState(ft),!0}else if(["s","S"].indexOf(i)>-1){var o=[["y","Y"],["s","S"],["t","T"],["e","E"],["m","M"]],u=o.every(function(t){return i=e.char(),t.indexOf(i)>-1});if(u)return t.setState(vt),!0}e.unget(i),t._currentToken.forceQuirks=!0,i===r.EOF?(t._parseError("eof-in-doctype"),e.unget(i),t.setState(n),t._emitCurrentToken()):(t._parseError("expected-space-or-right-bracket-in-doctype",{data:i}),t.setState(wt))}return!0}function ft(e){var i=e.char();return i===r.EOF?(t._parseError("eof-in-doctype"),t._currentToken.forceQuirks=!0,e.unget(i),t.setState(n),t._emitCurrentToken()):s(i)?t.setState(lt):i==="'"||i==='"'?(t._parseError("unexpected-char-in-doctype"),e.unget(i),t.setState(lt)):(e.unget(i),t.setState(lt)),!0}function lt(e){var i=e.char();return i===r.EOF?(t._parseError("eof-in-doctype"),t._currentToken.forceQuirks=!0,e.unget(i),t.setState(n),t._emitCurrentToken()):s(i)||(i==='"'?(t._currentToken.publicId="",t.setState(ct)):i==="'"?(t._currentToken.publicId="",t.setState(ht)):i===">"?(t._parseError("unexpected-end-of-doctype"),t._currentToken.forceQuirks=!0,t.setState(n),t._emitCurrentToken()):(t._parseError("unexpected-char-in-doctype"),t._currentToken.forceQuirks=!0,t.setState(wt))),!0}function ct(e){var i=e.char();return i===r.EOF?(t._parseError("eof-in-doctype"),t._currentToken.forceQuirks=!0,e.unget(i),t.setState(n),t._emitCurrentToken()):i==='"'?t.setState(pt):i===">"?(t._parseError("unexpected-end-of-doctype"),t._currentToken.forceQuirks=!0,t.setState(n),t._emitCurrentToken()):t._currentToken.publicId+=i,!0}function ht(e){var i=e.char();return i===r.EOF?(t._parseError("eof-in-doctype"),t._currentToken.forceQuirks=!0,e.unget(i),t.setState(n),t._emitCurrentToken()):i==="'"?t.setState(pt):i===">"?(t._parseError("unexpected-end-of-doctype"),t._currentToken.forceQuirks=!0,t.setState(n),t._emitCurrentToken()):t._currentToken.publicId+=i,!0}function pt(e){var i=e.char();return i===r.EOF?(t._parseError("eof-in-doctype"),t._currentToken.forceQuirks=!0,t._emitCurrentToken(),e.unget(i),t.setState(n)):s(i)?t.setState(dt):i===">"?(t.setState(n),t._emitCurrentToken()):i==='"'?(t._parseError("unexpected-char-in-doctype"),t._currentToken.systemId="",t.setState(gt)):i==="'"?(t._parseError("unexpected-char-in-doctype"),t._currentToken.systemId="",t.setState(yt)):(t._parseError("unexpected-char-in-doctype"),t._currentToken.forceQuirks=!0,t.setState(wt)),!0}function dt(e){var i=e.char();return i===r.EOF?(t._parseError("eof-in-doctype"),t._currentToken.forceQuirks=!0,t._emitCurrentToken(),e.unget(i),t.setState(n)):s(i)||(i===">"?(t._emitCurrentToken(),t.setState(n)):i==='"'?(t._currentToken.systemId="",t.setState(gt)):i==="'"?(t._currentToken.systemId="",t.setState(yt)):(t._parseError("unexpected-char-in-doctype"),t._currentToken.forceQuirks=!0,t.setState(wt))),!0}function vt(e){var i=e.char();return i===r.EOF?(t._parseError("eof-in-doctype"),t._currentToken.forceQuirks=!0,t._emitCurrentToken(),e.unget(i),t.setState(n)):s(i)?t.setState(mt):i==="'"||i==='"'?(t._parseError("unexpected-char-in-doctype"),e.unget(i),t.setState(mt)):(e.unget(i),t.setState(mt)),!0}function mt(e){var i=e.char();return i===r.EOF?(t._parseError("eof-in-doctype"),t._currentToken.forceQuirks=!0,t._emitCurrentToken(),e.unget(i),t.setState(n)):s(i)||(i==='"'?(t._currentToken.systemId="",t.setState(gt)):i==="'"?(t._currentToken.systemId="",t.setState(yt)):i===">"?(t._parseError("unexpected-end-of-doctype"),t._currentToken.forceQuirks=!0,t._emitCurrentToken(),t.setState(n)):(t._parseError("unexpected-char-in-doctype"),t._currentToken.forceQuirks=!0,t.setState(wt))),!0}function gt(e){var i=e.char();return i===r.EOF?(t._parseError("eof-in-doctype"),t._currentToken.forceQuirks=!0,t._emitCurrentToken(),e.unget(i),t.setState(n)):i==='"'?t.setState(bt):i===">"?(t._parseError("unexpected-end-of-doctype"),t._currentToken.forceQuirks=!0,t._emitCurrentToken(),t.setState(n)):t._currentToken.systemId+=i,!0}function yt(e){var i=e.char();return i===r.EOF?(t._parseError("eof-in-doctype"),t._currentToken.forceQuirks=!0,t._emitCurrentToken(),e.unget(i),t.setState(n)):i==="'"?t.setState(bt):i===">"?(t._parseError("unexpected-end-of-doctype"),t._currentToken.forceQuirks=!0,t._emitCurrentToken(),t.setState(n)):t._currentToken.systemId+=i,!0}function bt(e){var i=e.char();return i===r.EOF?(t._parseError("eof-in-doctype"),t._currentToken.forceQuirks=!0,t._emitCurrentToken(),e.unget(i),t.setState(n)):s(i)||(i===">"?(t._emitCurrentToken(),t.setState(n)):(t._parseError("unexpected-char-in-doctype"),t.setState(wt))),!0}function wt(e){var i=e.char();return i===r.EOF?(e.unget(i),t._emitCurrentToken(),t.setState(n)):i===">"&&(t._emitCurrentToken(),t.setState(n)),!0}u.DATA=n,u.RCDATA=f,u.RAWTEXT=c,u.SCRIPT_DATA=p,u.PLAINTEXT=h,this._state=u.DATA,this._inputStream.append(e),this._tokenHandler.startTokenization(this),this._inputStream.eof=!0;var t=this;while(this._state.call(this,this._inputStream));},Object.defineProperty(u.prototype,"lineNumber",{get:function(){return this._inputStream.location().line}}),Object.defineProperty(u.prototype,"columnNumber",{get:function(){return this._inputStream.location().column}}),n.Tokenizer=u},{"./EntityParser":2,"./InputStream":3}],6:[function(e,t,n){function c(e){return e===" "||e==="\n"||e===" "||e==="\r"||e==="\f"}function h(e){return c(e)||e==="\ufffd"}function p(e){for(var t=0;t2?e.parseError("expected-closing-tag-but-got-eof"):e.openElements.length==2&&e.openElements.item(1).localName!="body"?e.parseError("expected-closing-tag-but-got-eof"):e.context&&e.openElements.length>1},processComment:function(t){e.insertComment(t,e.currentStackItem().node)},processDoctype:function(t,n,r,i){e.parseError("unexpected-doctype")},processStartTag:function(e,t,n){if(this[this.start_tag_handlers[e]])this[this.start_tag_handlers[e]](e,t,n);else{if(!this[this.start_tag_handlers["-default"]])throw new Error("No handler found for "+e);this[this.start_tag_handlers["-default"]](e,t,n)}},processEndTag:function(e){if(this[this.end_tag_handlers[e]])this[this.end_tag_handlers[e]](e);else{if(!this[this.end_tag_handlers["-default"]])throw new Error("No handler found for "+e);this[this.end_tag_handlers["-default"]](e)}},startTagHtml:function(e,n){t.inBody.startTagHtml(e,n)}},t.initial=Object.create(t.base),t.initial.processEOF=function(){e.parseError("expected-doctype-but-got-eof"),this.anythingElse(),e.insertionMode.processEOF()},t.initial.processComment=function(t){e.insertComment(t,e.document)},t.initial.processDoctype=function(t,n,r,i){function s(e){return n.toLowerCase().indexOf(e)===0}e.insertDoctype(t||"",n||"",r||""),i||t!="html"||n!=null&&(["+//silmaril//dtd html pro v0r11 19970101//","-//advasoft ltd//dtd html 3.0 aswedit + extensions//","-//as//dtd html 3.0 aswedit + extensions//","-//ietf//dtd html 2.0 level 1//","-//ietf//dtd html 2.0 level 2//","-//ietf//dtd html 2.0 strict level 1//","-//ietf//dtd html 2.0 strict level 2//","-//ietf//dtd html 2.0 strict//","-//ietf//dtd html 2.0//","-//ietf//dtd html 2.1e//","-//ietf//dtd html 3.0//","-//ietf//dtd html 3.0//","-//ietf//dtd html 3.2 final//","-//ietf//dtd html 3.2//","-//ietf//dtd html 3//","-//ietf//dtd html level 0//","-//ietf//dtd html level 0//","-//ietf//dtd html level 1//","-//ietf//dtd html level 1//","-//ietf//dtd html level 2//","-//ietf//dtd html level 2//","-//ietf//dtd html level 3//","-//ietf//dtd html level 3//","-//ietf//dtd html strict level 0//","-//ietf//dtd html strict level 0//","-//ietf//dtd html strict level 1//","-//ietf//dtd html strict level 1//","-//ietf//dtd html strict level 2//","-//ietf//dtd html strict level 2//","-//ietf//dtd html strict level 3//","-//ietf//dtd html strict level 3//","-//ietf//dtd html strict//","-//ietf//dtd html strict//","-//ietf//dtd html strict//","-//ietf//dtd html//","-//ietf//dtd html//","-//ietf//dtd html//","-//metrius//dtd metrius presentational//","-//microsoft//dtd internet explorer 2.0 html strict//","-//microsoft//dtd internet explorer 2.0 html//","-//microsoft//dtd internet explorer 2.0 tables//","-//microsoft//dtd internet explorer 3.0 html strict//","-//microsoft//dtd internet explorer 3.0 html//","-//microsoft//dtd internet explorer 3.0 tables//","-//netscape comm. corp.//dtd html//","-//netscape comm. corp.//dtd strict html//","-//o'reilly and associates//dtd html 2.0//","-//o'reilly and associates//dtd html extended 1.0//","-//spyglass//dtd html 2.0 extended//","-//sq//dtd html 2.0 hotmetal + extensions//","-//sun microsystems corp.//dtd hotjava html//","-//sun microsystems corp.//dtd hotjava strict html//","-//w3c//dtd html 3 1995-03-24//","-//w3c//dtd html 3.2 draft//","-//w3c//dtd html 3.2 final//","-//w3c//dtd html 3.2//","-//w3c//dtd html 3.2s draft//","-//w3c//dtd html 4.0 frameset//","-//w3c//dtd html 4.0 transitional//","-//w3c//dtd html experimental 19960712//","-//w3c//dtd html experimental 970421//","-//w3c//dtd w3 html//","-//w3o//dtd w3 html 3.0//","-//webtechs//dtd mozilla html 2.0//","-//webtechs//dtd mozilla html//","html"].some(s)||["-//w3o//dtd w3 html strict 3.0//en//","-/w3c/dtd html 4.0 transitional/en","html"].indexOf(n.toLowerCase())>-1||r==null&&["-//w3c//dtd html 4.01 transitional//","-//w3c//dtd html 4.01 frameset//"].some(s))||r!=null&&r.toLowerCase()=="http://www.ibm.com/data/dtd/v11/ibmxhtml1-transitional.dtd"?(e.compatMode="quirks",e.parseError("quirky-doctype")):n!=null&&(["-//w3c//dtd xhtml 1.0 transitional//","-//w3c//dtd xhtml 1.0 frameset//"].some(s)||r!=null&&["-//w3c//dtd html 4.01 transitional//","-//w3c//dtd html 4.01 frameset//"].indexOf(n.toLowerCase())>-1)?(e.compatMode="limited quirks",e.parseError("almost-standards-doctype")):n=="-//W3C//DTD HTML 4.0//EN"&&(r==null||r=="http://www.w3.org/TR/REC-html40/strict.dtd")||n=="-//W3C//DTD HTML 4.01//EN"&&(r==null||r=="http://www.w3.org/TR/html4/strict.dtd")||n=="-//W3C//DTD XHTML 1.0 Strict//EN"&&r=="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"||n=="-//W3C//DTD XHTML 1.1//EN"&&r=="http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"||(r!=null&&r!="about:legacy-compat"||n!=null)&&e.parseError("unknown-doctype"),e.setInsertionMode("beforeHTML")},t.initial.processCharacters=function(t){t.skipLeadingWhitespace();if(!t.length)return;e.parseError("expected-doctype-but-got-chars"),this.anythingElse(),e.insertionMode.processCharacters(t)},t.initial.processStartTag=function(t,n,r){e.parseError("expected-doctype-but-got-start-tag",{name:t}),this.anythingElse(),e.insertionMode.processStartTag(t,n,r)},t.initial.processEndTag=function(t){e.parseError("expected-doctype-but-got-end-tag",{name:t}),this.anythingElse(),e.insertionMode.processEndTag(t)},t.initial.anythingElse=function(){e.compatMode="quirks",e.setInsertionMode("beforeHTML")},t.beforeHTML=Object.create(t.base),t.beforeHTML.start_tag_handlers={html:"startTagHtml","-default":"startTagOther"},t.beforeHTML.processEOF=function(){this.anythingElse(),e.insertionMode.processEOF()},t.beforeHTML.processComment=function(t){e.insertComment(t,e.document)},t.beforeHTML.processCharacters=function(t){t.skipLeadingWhitespace();if(!t.length)return;this.anythingElse(),e.insertionMode.processCharacters(t)},t.beforeHTML.startTagHtml=function(t,n,r){e.insertHtmlElement(n),e.setInsertionMode("beforeHead")},t.beforeHTML.startTagOther=function(t,n,r){this.anythingElse(),e.insertionMode.processStartTag(t,n,r)},t.beforeHTML.processEndTag=function(t){this.anythingElse(),e.insertionMode.processEndTag(t)},t.beforeHTML.anythingElse=function(){e.insertHtmlElement(),e.setInsertionMode("beforeHead")},t.afterAfterBody=Object.create(t.base),t.afterAfterBody.start_tag_handlers={html:"startTagHtml","-default":"startTagOther"},t.afterAfterBody.processComment=function(t){e.insertComment(t,e.document)},t.afterAfterBody.processDoctype=function(e){t.inBody.processDoctype(e)},t.afterAfterBody.startTagHtml=function(e,n){t.inBody.startTagHtml(e,n)},t.afterAfterBody.startTagOther=function(t,n,r){e.parseError("unexpected-start-tag",{name:t}),e.setInsertionMode("inBody"),e.insertionMode.processStartTag(t,n,r)},t.afterAfterBody.endTagOther=function(t){e.parseError("unexpected-end-tag",{name:t}),e.setInsertionMode("inBody"),e.insertionMode.processEndTag(t)},t.afterAfterBody.processCharacters=function(n){if(!p(n.characters))return e.parseError("unexpected-char-after-body"),e.setInsertionMode("inBody"),e.insertionMode.processCharacters(n);t.inBody.processCharacters(n)},t.afterBody=Object.create(t.base),t.afterBody.end_tag_handlers={html:"endTagHtml","-default":"endTagOther"},t.afterBody.processComment=function(t){e.insertComment(t,e.openElements.rootNode)},t.afterBody.processCharacters=function(n){if(!p(n.characters))return e.parseError("unexpected-char-after-body"),e.setInsertionMode("inBody"),e.insertionMode.processCharacters(n);t.inBody.processCharacters(n)},t.afterBody.processStartTag=function(t,n,r){e.parseError("unexpected-start-tag-after-body",{name:t}),e.setInsertionMode("inBody"),e.insertionMode.processStartTag(t,n,r)},t.afterBody.endTagHtml=function(t){e.context?e.parseError("end-html-in-innerhtml"):e.setInsertionMode("afterAfterBody")},t.afterBody.endTagOther=function(t){e.parseError("unexpected-end-tag-after-body",{name:t}),e.setInsertionMode("inBody"),e.insertionMode.processEndTag(t)},t.afterFrameset=Object.create(t.base),t.afterFrameset.start_tag_handlers={html:"startTagHtml",noframes:"startTagNoframes","-default":"startTagOther"},t.afterFrameset.end_tag_handlers={html:"endTagHtml","-default":"endTagOther"},t.afterFrameset.processCharacters=function(t){var n=t.takeRemaining(),r="";for(var i=0;i1)e.openElements.pop();e.insertElement(t,n),e.setInsertionMode("inFrameset")}},t.inBody.startTagCloseP=function(t,n){e.openElements.inButtonScope("p")&&this.endTagP("p"),e.insertElement(t,n)},t.inBody.startTagPreListing=function(t,n){e.openElements.inButtonScope("p")&&this.endTagP("p"),e.insertElement(t,n),e.framesetOk=!1,e.shouldSkipLeadingNewline=!0},t.inBody.startTagForm=function(t,n){e.form?e.parseError("unexpected-start-tag",{name:t}):(e.openElements.inButtonScope("p")&&this.endTagP("p"),e.insertElement(t,n),e.form=e.currentStackItem())},t.inBody.startTagRpRt=function(t,n){e.openElements.inScope("ruby")&&(e.generateImpliedEndTags(),e.currentStackItem().localName!="ruby"&&e.parseError("unexpected-start-tag",{name:t})),e.insertElement(t,n)},t.inBody.startTagListItem=function(t,n){var r={li:["li"],dd:["dd","dt"],dt:["dd","dt"]},i=r[t],s=e.openElements;for(var o=s.length-1;o>=0;o--){var u=s.item(o);if(i.indexOf(u.localName)!=-1){e.insertionMode.processEndTag(u.localName);break}if(u.isSpecial()&&u.localName!=="p"&&u.localName!=="address"&&u.localName!=="div")break}e.openElements.inButtonScope("p")&&this.endTagP("p"),e.insertElement(t,n),e.framesetOk=!1},t.inBody.startTagPlaintext=function(t,n){e.openElements.inButtonScope("p")&&this.endTagP("p"),e.insertElement(t,n),e.tokenizer.setState(u.PLAINTEXT)},t.inBody.startTagHeading=function(t,n){e.openElements.inButtonScope("p")&&this.endTagP("p"),e.currentStackItem().isNumberedHeader()&&(e.parseError("unexpected-start-tag",{name:t}),e.popElement()),e.insertElement(t,n)},t.inBody.startTagA=function(t,n){var r=e.elementInActiveFormattingElements("a");r&&(e.parseError("unexpected-start-tag-implies-end-tag",{startName:"a",endName:"a"}),e.adoptionAgencyEndTag("a"),e.openElements.contains(r)&&e.openElements.remove(r),e.removeElementFromActiveFormattingElements(r)),e.reconstructActiveFormattingElements(),e.insertFormattingElement(t,n)},t.inBody.startTagFormatting=function(t,n){e.reconstructActiveFormattingElements(),e.insertFormattingElement(t,n)},t.inBody.startTagNobr=function(t,n){e.reconstructActiveFormattingElements(),e.openElements.inScope("nobr")&&(e.parseError("unexpected-start-tag-implies-end-tag",{startName:"nobr",endName:"nobr"}),this.processEndTag("nobr"),e.reconstructActiveFormattingElements()),e.insertFormattingElement(t,n)},t.inBody.startTagButton=function(t,n){e.openElements.inScope("button")?(e.parseError("unexpected-start-tag-implies-end-tag",{startName:"button",endName:"button"}),this.processEndTag("button"),e.insertionMode.processStartTag(t,n)):(e.framesetOk=!1,e.reconstructActiveFormattingElements(),e.insertElement(t,n))},t.inBody.startTagAppletMarqueeObject=function(t,n){e.reconstructActiveFormattingElements(),e.insertElement(t,n),e.activeFormattingElements.push(l),e.framesetOk=!1},t.inBody.endTagAppletMarqueeObject=function(t){e.openElements.inScope(t)?(e.generateImpliedEndTags(),e.currentStackItem().localName!=t&&e.parseError("end-tag-too-early",{name:t}),e.openElements.popUntilPopped(t),e.clearActiveFormattingElements()):e.parseError("unexpected-end-tag",{name:t})},t.inBody.startTagXmp=function(t,n){e.openElements.inButtonScope("p")&&this.processEndTag("p"),e.reconstructActiveFormattingElements(),e.processGenericRawTextStartTag(t,n),e.framesetOk=!1},t.inBody.startTagTable=function(t,n){e.compatMode!=="quirks"&&e.openElements.inButtonScope("p")&&this.processEndTag("p"),e.insertElement(t,n),e.setInsertionMode("inTable"),e.framesetOk=!1},t.inBody.startTagVoidFormatting=function(t,n){e.reconstructActiveFormattingElements(),e.insertSelfClosingElement(t,n),e.framesetOk=!1},t.inBody.startTagParamSourceTrack=function(t,n){e.insertSelfClosingElement(t,n)},t.inBody.startTagHr=function(t,n){e.openElements.inButtonScope("p")&&this.endTagP("p"),e.insertSelfClosingElement(t,n),e.framesetOk=!1},t.inBody.startTagImage=function(t,n){e.parseError("unexpected-start-tag-treated-as",{originalName:"image",newName:"img"}),this.processStartTag("img",n)},t.inBody.startTagInput=function(t,n){var r=e.framesetOk;this.startTagVoidFormatting(t,n);for(var i in n)if(n[i].nodeName=="type"){n[i].nodeValue.toLowerCase()=="hidden"&&(e.framesetOk=r);break}},t.inBody.startTagIsindex=function(t,n){e.parseError("deprecated-tag",{name:"isindex"}),e.selfClosingFlagAcknowledged=!0;if(e.form)return;var r=[],i=[],s="This is a searchable index. Enter search keywords: ";for(var o in n)switch(n[o].nodeName){case"action":r.push({nodeName:"action",nodeValue:n[o].nodeValue});break;case"prompt":s=n[o].nodeValue;break;case"name":break;default:i.push({nodeName:n[o].nodeName,nodeValue:n[o].nodeValue})}i.push({nodeName:"name",nodeValue:"isindex"}),this.processStartTag("form",r),this.processStartTag("hr"),this.processStartTag("label"),this.processCharacters(new m(s)),this.processStartTag("input",i),this.processEndTag("label"),this.processStartTag("hr"),this.processEndTag("form")},t.inBody.startTagTextarea=function(t,n){e.insertElement(t,n),e.tokenizer.setState(u.RCDATA),e.originalInsertionMode=e.insertionModeName,e.shouldSkipLeadingNewline=!0,e.framesetOk=!1,e.setInsertionMode("text")},t.inBody.startTagIFrame=function(t,n){e.framesetOk=!1,this.startTagRawText(t,n)},t.inBody.startTagRawText=function(t,n){e.processGenericRawTextStartTag(t,n)},t.inBody.startTagSelect=function(t,n){e.reconstructActiveFormattingElements(),e.insertElement(t,n),e.framesetOk=!1;var r=e.insertionModeName;r=="inTable"||r=="inCaption"||r=="inColumnGroup"||r=="inTableBody"||r=="inRow"||r=="inCell"?e.setInsertionMode("inSelectInTable"):e.setInsertionMode("inSelect")},t.inBody.startTagMisplaced=function(t,n){e.parseError("unexpected-start-tag-ignored",{name:t})},t.inBody.endTagMisplaced=function(t){e.parseError("unexpected-end-tag",{name:t})},t.inBody.endTagBr=function(t){e.parseError("unexpected-end-tag-treated-as",{originalName:"br",newName:"br element"}),e.reconstructActiveFormattingElements(),e.insertElement(t,[]),e.popElement()},t.inBody.startTagOptionOptgroup=function(t,n){e.currentStackItem().localName=="option"&&e.popElement(),e.reconstructActiveFormattingElements(),e.insertElement(t,n)},t.inBody.startTagOther=function(t,n){e.reconstructActiveFormattingElements(),e.insertElement(t,n)},t.inBody.endTagOther=function(t){var n;for(var r=e.openElements.length-1;r>0;r--){n=e.openElements.item(r);if(n.localName==t){e.generateImpliedEndTags(t),e.currentStackItem().localName!=t&&e.parseError("unexpected-end-tag",{name:t}),e.openElements.remove_openElements_until(function(e){return e===n});break}if(n.isSpecial()){e.parseError("unexpected-end-tag",{name:t});break}}},t.inBody.startTagMath=function(t,n,r){e.reconstructActiveFormattingElements(),n=e.adjustMathMLAttributes(n),n=e.adjustForeignAttributes(n),e.insertForeignElement(t,n,"http://www.w3.org/1998/Math/MathML",r)},t.inBody.startTagSVG=function(t,n,r){e.reconstructActiveFormattingElements(),n=e.adjustSVGAttributes(n),n=e.adjustForeignAttributes(n),e.insertForeignElement(t,n,"http://www.w3.org/2000/svg",r)},t.inBody.endTagP=function(t){e.openElements.inButtonScope("p")?(e.generateImpliedEndTags("p"),e.currentStackItem().localName!="p"&&e.parseError("unexpected-implied-end-tag",{name:"p"}),e.openElements.popUntilPopped(t)):(e.parseError("unexpected-end-tag",{name:"p"}),this.startTagCloseP("p",[]),this.endTagP("p"))},t.inBody.endTagBody=function(t){if(!e.openElements.inScope("body")){e.parseError("unexpected-end-tag",{name:t});return}e.currentStackItem().localName!="body"&&e.parseError("expected-one-end-tag-but-got-another",{expectedName:e.currentStackItem().localName,gotName:t}),e.setInsertionMode("afterBody")},t.inBody.endTagHtml=function(t){if(!e.openElements.inScope("body")){e.parseError("unexpected-end-tag",{name:t});return}e.currentStackItem().localName!="body"&&e.parseError("expected-one-end-tag-but-got-another",{expectedName:e.currentStackItem().localName,gotName:t}),e.setInsertionMode("afterBody"),e.insertionMode.processEndTag(t)},t.inBody.endTagBlock=function(t){e.openElements.inScope(t)?(e.generateImpliedEndTags(),e.currentStackItem().localName!=t&&e.parseError("end-tag-too-early",{name:t}),e.openElements.popUntilPopped(t)):e.parseError("unexpected-end-tag",{name:t})},t.inBody.endTagForm=function(t){var n=e.form;e.form=null,!n||!e.openElements.inScope(t)?e.parseError("unexpected-end-tag",{name:t}):(e.generateImpliedEndTags(),e.currentStackItem()!=n&&e.parseError("end-tag-too-early-ignored",{name:"form"}),e.openElements.remove(n))},t.inBody.endTagListItem=function(t){e.openElements.inListItemScope(t)?(e.generateImpliedEndTags(t),e.currentStackItem().localName!=t&&e.parseError("end-tag-too-early",{name:t}),e.openElements.popUntilPopped(t)):e.parseError("unexpected-end-tag",{name:t})},t.inBody.endTagHeading=function(t){if(!e.openElements.hasNumberedHeaderElementInScope()){e.parseError("unexpected-end-tag",{name:t});return}e.generateImpliedEndTags(),e.currentStackItem().localName!=t&&e.parseError("end-tag-too-early",{name:t}),e.openElements.remove_openElements_until(function(e){return e.isNumberedHeader()})},t.inBody.endTagFormatting=function(t,n){e.adoptionAgencyEndTag(t)||this.endTagOther(t,n)},t.inCaption=Object.create(t.base),t.inCaption.start_tag_handlers={html:"startTagHtml",caption:"startTagTableElement",col:"startTagTableElement",colgroup:"startTagTableElement",tbody:"startTagTableElement",td:"startTagTableElement",tfoot:"startTagTableElement",thead:"startTagTableElement",tr:"startTagTableElement","-default":"startTagOther"},t.inCaption.end_tag_handlers={caption:"endTagCaption",table:"endTagTable",body:"endTagIgnore",col:"endTagIgnore",colgroup:"endTagIgnore",html:"endTagIgnore",tbody:"endTagIgnore",td:"endTagIgnore",tfood:"endTagIgnore",thead:"endTagIgnore",tr:"endTagIgnore","-default":"endTagOther"},t.inCaption.processCharacters=function(e){t.inBody.processCharacters(e)},t.inCaption.startTagTableElement=function(t,n){e.parseError("unexpected-end-tag",{name:t});var r=!e.openElements.inTableScope("caption");e.insertionMode.processEndTag("caption"),r||e.insertionMode.processStartTag(t,n)},t.inCaption.startTagOther=function(e,n,r){t.inBody.processStartTag(e,n,r)},t.inCaption.endTagCaption=function(t){e.openElements.inTableScope("caption")?(e.generateImpliedEndTags(),e.currentStackItem().localName!="caption"&&e.parseError("expected-one-end-tag-but-got-another",{gotName:"caption",expectedName:e.currentStackItem().localName}),e.openElements.popUntilPopped("caption"),e.clearActiveFormattingElements(),e.setInsertionMode("inTable")):(r.ok(e.context),e.parseError("unexpected-end-tag",{name:t}))},t.inCaption.endTagTable=function(t){e.parseError("unexpected-end-table-in-caption");var n=!e.openElements.inTableScope("caption");e.insertionMode.processEndTag("caption"),n||e.insertionMode.processEndTag(t)},t.inCaption.endTagIgnore=function(t){e.parseError("unexpected-end-tag",{name:t})},t.inCaption.endTagOther=function(e){t.inBody.processEndTag(e)},t.inCell=Object.create(t.base),t.inCell.start_tag_handlers={html:"startTagHtml",caption:"startTagTableOther",col:"startTagTableOther",colgroup:"startTagTableOther",tbody:"startTagTableOther",td:"startTagTableOther",tfoot:"startTagTableOther",th:"startTagTableOther",thead:"startTagTableOther",tr:"startTagTableOther","-default":"startTagOther"},t.inCell.end_tag_handlers={td:"endTagTableCell",th:"endTagTableCell",body:"endTagIgnore",caption:"endTagIgnore",col:"endTagIgnore",colgroup:"endTagIgnore",html:"endTagIgnore",table:"endTagImply",tbody:"endTagImply",tfoot:"endTagImply",thead:"endTagImply",tr:"endTagImply","-default":"endTagOther"},t.inCell.processCharacters=function(e){t.inBody.processCharacters(e)},t.inCell.startTagTableOther=function(t,n,r){e.openElements.inTableScope("td")||e.openElements.inTableScope("th")?(this.closeCell(),e.insertionMode.processStartTag(t,n,r)):e.parseError("unexpected-start-tag",{name:t})},t.inCell.startTagOther=function(e,n,r){t.inBody.processStartTag(e,n,r)},t.inCell.endTagTableCell=function(t){e.openElements.inTableScope(t)?(e.generateImpliedEndTags(t),e.currentStackItem().localName!=t.toLowerCase()?(e.parseError("unexpected-cell-end-tag",{name:t}),e.openElements.popUntilPopped(t)):e.popElement(),e.clearActiveFormattingElements(),e.setInsertionMode("inRow")):e.parseError("unexpected-end-tag",{name:t})},t.inCell.endTagIgnore=function(t){e.parseError("unexpected-end-tag",{name:t})},t.inCell.endTagImply=function(t){e.openElements.inTableScope(t)?(this.closeCell(),e.insertionMode.processEndTag(t)):e.parseError("unexpected-end-tag",{name:t})},t.inCell.endTagOther=function(e){t.inBody.processEndTag(e)},t.inCell.closeCell=function(){e.openElements.inTableScope("td")?this.endTagTableCell("td"):e.openElements.inTableScope("th")&&this.endTagTableCell("th")},t.inColumnGroup=Object.create(t.base),t.inColumnGroup.start_tag_handlers={html:"startTagHtml",col:"startTagCol","-default":"startTagOther"},t.inColumnGroup.end_tag_handlers={colgroup:"endTagColgroup",col:"endTagCol","-default":"endTagOther"},t.inColumnGroup.ignoreEndTagColgroup=function(){return e.currentStackItem().localName=="html"},t.inColumnGroup.processCharacters=function(t){var n=t.takeLeadingWhitespace();n&&e.insertText(n);if(!t.length)return;var r=this.ignoreEndTagColgroup();this.endTagColgroup("colgroup"),r||e.insertionMode.processCharacters(t)},t.inColumnGroup.startTagCol=function(t,n){e.insertSelfClosingElement(t,n)},t.inColumnGroup.startTagOther=function(t,n,r){var i=this.ignoreEndTagColgroup();this.endTagColgroup("colgroup"),i||e.insertionMode.processStartTag(t,n,r)},t.inColumnGroup.endTagColgroup=function(t){this.ignoreEndTagColgroup()?(r.ok(e.context),e.parseError("unexpected-end-tag",{name:t})):(e.popElement(),e.setInsertionMode("inTable"))},t.inColumnGroup.endTagCol=function(t){e.parseError("no-end-tag",{name:"col"})},t.inColumnGroup.endTagOther=function(t){var n=this.ignoreEndTagColgroup();this.endTagColgroup("colgroup"),n||e.insertionMode.processEndTag(t)},t.inForeignContent=Object.create(t.base),t.inForeignContent.processStartTag=function(t,n,r){if(["b","big","blockquote","body","br","center","code","dd","div","dl","dt","em","embed","h1","h2","h3","h4","h5","h6","head","hr","i","img","li","listing","menu","meta","nobr","ol","p","pre","ruby","s","small","span","strong","strike","sub","sup","table","tt","u","ul","var"].indexOf(t)!=-1||t=="font"&&n.some(function(e){return["color","face","size"].indexOf(e.nodeName)>=0})){e.parseError("unexpected-html-element-in-foreign-content",{name:t});while(e.currentStackItem().isForeign()&&!e.currentStackItem().isHtmlIntegrationPoint()&&!e.currentStackItem().isMathMLTextIntegrationPoint())e.openElements.pop();e.insertionMode.processStartTag(t,n,r);return}e.currentStackItem().namespaceURI=="http://www.w3.org/1998/Math/MathML"&&(n=e.adjustMathMLAttributes(n)),e.currentStackItem().namespaceURI=="http://www.w3.org/2000/svg"&&(t=e.adjustSVGTagNameCase(t),n=e.adjustSVGAttributes(n)),n=e.adjustForeignAttributes(n),e.insertForeignElement(t,n,e.currentStackItem().namespaceURI,r)},t.inForeignContent.processEndTag=function(t){var n=e.currentStackItem(),r=e.openElements.length-1;n.localName.toLowerCase()!=t&&e.parseError("unexpected-end-tag",{name:t});for(;;){if(r===0)break;if(n.localName.toLowerCase()==t){while(e.openElements.pop()!=n);break}r-=1,n=e.openElements.item(r);if(n.isForeign())continue;e.insertionMode.processEndTag(t);break}},t.inForeignContent.processCharacters=function(t){var n=t.takeRemaining();n=n.replace(/\u0000/g,function(t,n){return e.parseError("invalid-codepoint"),"\ufffd"}),e.framesetOk&&!d(n)&&(e.framesetOk=!1),e.insertText(n)},t.inHeadNoscript=Object.create(t.base),t.inHeadNoscript.start_tag_handlers={html:"startTagHtml",basefont:"startTagBasefontBgsoundLinkMetaNoframesStyle",bgsound:"startTagBasefontBgsoundLinkMetaNoframesStyle",link:"startTagBasefontBgsoundLinkMetaNoframesStyle",meta:"startTagBasefontBgsoundLinkMetaNoframesStyle",noframes:"startTagBasefontBgsoundLinkMetaNoframesStyle",style:"startTagBasefontBgsoundLinkMetaNoframesStyle",head:"startTagHeadNoscript",noscript:"startTagHeadNoscript","-default":"startTagOther"},t.inHeadNoscript.end_tag_handlers={noscript:"endTagNoscript",br:"endTagBr","-default":"endTagOther"},t.inHeadNoscript.processCharacters=function(t){var n=t.takeLeadingWhitespace();n&&e.insertText(n);if(!t.length)return;e.parseError("unexpected-char-in-frameset"),this.anythingElse(),e.insertionMode.processCharacters(t)},t.inHeadNoscript.processComment=function(e){t.inHead.processComment(e)},t.inHeadNoscript.startTagBasefontBgsoundLinkMetaNoframesStyle=function(e,n){t.inHead.processStartTag(e,n)},t.inHeadNoscript.startTagHeadNoscript=function(t,n){e.parseError("unexpected-start-tag-in-frameset",{name:t})},t.inHeadNoscript.startTagOther=function(t,n){e.parseError("unexpected-start-tag-in-frameset",{name:t}),this.anythingElse(),e.insertionMode.processStartTag(t,n)},t.inHeadNoscript.endTagBr=function(t,n){e.parseError("unexpected-end-tag-in-frameset",{name:t}),this.anythingElse(),e.insertionMode.processEndTag(t,n)},t.inHeadNoscript.endTagNoscript=function(t,n){e.popElement(),e.setInsertionMode("inHead")},t.inHeadNoscript.endTagOther=function(t,n){e.parseError("unexpected-end-tag-in-frameset",{name:t})},t.inHeadNoscript.anythingElse=function(){e.popElement(),e.setInsertionMode("inHead")},t.inFrameset=Object.create(t.base),t.inFrameset.start_tag_handlers={html:"startTagHtml",frameset:"startTagFrameset",frame:"startTagFrame",noframes:"startTagNoframes","-default":"startTagOther"},t.inFrameset.end_tag_handlers={frameset:"endTagFrameset",noframes:"endTagNoframes","-default":"endTagOther"},t.inFrameset.processCharacters=function(t){e.parseError("unexpected-char-in-frameset")},t.inFrameset.startTagFrameset=function(t,n){e.insertElement(t,n)},t.inFrameset.startTagFrame=function(t,n){e.insertSelfClosingElement(t,n)},t.inFrameset.startTagNoframes=function(e,n){t.inBody.processStartTag(e,n)},t.inFrameset.startTagOther=function(t,n){e.parseError("unexpected-start-tag-in-frameset",{name:t})},t.inFrameset.endTagFrameset=function(t,n){e.currentStackItem().localName=="html"?e.parseError("unexpected-frameset-in-frameset-innerhtml"):e.popElement(),!e.context&&e.currentStackItem().localName!="frameset"&&e.setInsertionMode("afterFrameset")},t.inFrameset.endTagNoframes=function(e){t.inBody.processEndTag(e)},t.inFrameset.endTagOther=function(t){e.parseError("unexpected-end-tag-in-frameset",{name:t})},t.inTable=Object.create(t.base),t.inTable.start_tag_handlers={html:"startTagHtml",caption:"startTagCaption",colgroup:"startTagColgroup",col:"startTagCol",table:"startTagTable",tbody:"startTagRowGroup",tfoot:"startTagRowGroup",thead:"startTagRowGroup",td:"startTagImplyTbody",th:"startTagImplyTbody",tr:"startTagImplyTbody",style:"startTagStyleScript",script:"startTagStyleScript",input:"startTagInput",form:"startTagForm","-default":"startTagOther"},t.inTable.end_tag_handlers={table:"endTagTable",body:"endTagIgnore",caption:"endTagIgnore",col:"endTagIgnore",colgroup:"endTagIgnore",html:"endTagIgnore",tbody:"endTagIgnore",td:"endTagIgnore",tfoot:"endTagIgnore",th:"endTagIgnore",thead:"endTagIgnore",tr:"endTagIgnore","-default":"endTagOther"},t.inTable.processCharacters=function(n){if(e.currentStackItem().isFosterParenting()){var r=e.insertionModeName;e.setInsertionMode("inTableText"),e.originalInsertionMode=r,e.insertionMode.processCharacters(n)}else e.redirectAttachToFosterParent=!0,t.inBody.processCharacters(n),e.redirectAttachToFosterParent=!1},t.inTable.startTagCaption=function(t,n){e.openElements.popUntilTableScopeMarker(),e.activeFormattingElements.push(l),e.insertElement(t,n),e.setInsertionMode("inCaption")},t.inTable.startTagColgroup=function(t,n){e.openElements.popUntilTableScopeMarker(),e.insertElement(t,n),e.setInsertionMode("inColumnGroup")},t.inTable.startTagCol=function(t,n){this.startTagColgroup("colgroup",[]),e.insertionMode.processStartTag(t,n)},t.inTable.startTagRowGroup=function(t,n){e.openElements.popUntilTableScopeMarker(),e.insertElement(t,n),e.setInsertionMode("inTableBody")},t.inTable.startTagImplyTbody=function(t,n){this.startTagRowGroup("tbody",[]),e.insertionMode.processStartTag(t,n)},t.inTable.startTagTable=function(t,n){e.parseError("unexpected-start-tag-implies-end-tag",{startName:"table",endName:"table"}),e.insertionMode.processEndTag("table"),e.context||e.insertionMode.processStartTag(t,n)},t.inTable.startTagStyleScript=function(e,n){t.inHead.processStartTag(e,n)},t.inTable.startTagInput=function(t,n){for(var r in n)if(n[r].nodeName.toLowerCase()=="type"){if(n[r].nodeValue.toLowerCase()=="hidden"){e.parseError("unexpected-hidden-input-in-table"),e.insertElement(t,n),e.openElements.pop();return}break}this.startTagOther(t,n)},t.inTable.startTagForm=function(t,n){e.parseError("unexpected-form-in-table"),e.form||(e.insertElement(t,n),e.form=e.currentStackItem(),e.openElements.pop())},t.inTable.startTagOther=function(n,r,i){e.parseError("unexpected-start-tag-implies-table-voodoo",{name:n}),e.redirectAttachToFosterParent=!0,t.inBody.processStartTag(n,r,i),e.redirectAttachToFosterParent=!1},t.inTable.endTagTable=function(t){e.openElements.inTableScope(t)?(e.generateImpliedEndTags(),e.currentStackItem().localName!=t&&e.parseError("end-tag-too-early-named",{gotName:"table",expectedName:e.currentStackItem().localName}),e.openElements.popUntilPopped("table"),e.resetInsertionMode()):(r.ok(e.context),e.parseError("unexpected-end-tag",{name:t}))},t.inTable.endTagIgnore=function(t){e.parseError("unexpected-end-tag",{name:t})},t.inTable.endTagOther=function(n){e.parseError("unexpected-end-tag-implies-table-voodoo",{name:n}),e.redirectAttachToFosterParent=!0,t.inBody.processEndTag(n),e.redirectAttachToFosterParent=!1},t.inTableText=Object.create(t.base),t.inTableText.flushCharacters=function(){var t=e.pendingTableCharacters.join("");p(t)?e.insertText(t):(e.redirectAttachToFosterParent=!0,e.reconstructActiveFormattingElements(),e.insertText(t),e.framesetOk=!1,e.redirectAttachToFosterParent=!1),e.pendingTableCharacters=[]},t.inTableText.processComment=function(t){this.flushCharacters(),e.setInsertionMode(e.originalInsertionMode),e.insertionMode.processComment(t)},t.inTableText.processEOF=function(t){this.flushCharacters(),e.setInsertionMode(e.originalInsertionMode),e.insertionMode.processEOF()},t.inTableText.processCharacters=function(t){var n=t.takeRemaining();n=n.replace(/\u0000/g,function(t,n){return e.parseError("invalid-codepoint"),""});if(!n)return;e.pendingTableCharacters.push(n)},t.inTableText.processStartTag=function(t,n,r){this.flushCharacters(),e.setInsertionMode(e.originalInsertionMode),e.insertionMode.processStartTag(t,n,r)},t.inTableText.processEndTag=function(t,n){this.flushCharacters(),e.setInsertionMode(e.originalInsertionMode),e.insertionMode.processEndTag(t,n)},t.inTableBody=Object.create(t.base),t.inTableBody.start_tag_handlers={html:"startTagHtml",tr:"startTagTr",td:"startTagTableCell",th:"startTagTableCell",caption:"startTagTableOther",col:"startTagTableOther",colgroup:"startTagTableOther",tbody:"startTagTableOther",tfoot:"startTagTableOther",thead:"startTagTableOther","-default":"startTagOther"},t.inTableBody.end_tag_handlers={table:"endTagTable",tbody:"endTagTableRowGroup",tfoot:"endTagTableRowGroup",thead:"endTagTableRowGroup",body:"endTagIgnore",caption:"endTagIgnore",col:"endTagIgnore",colgroup:"endTagIgnore",html:"endTagIgnore",td:"endTagIgnore",th:"endTagIgnore",tr:"endTagIgnore","-default":"endTagOther"},t.inTableBody.processCharacters=function(e){t.inTable.processCharacters(e)},t.inTableBody.startTagTr=function(t,n){e.openElements.popUntilTableBodyScopeMarker(),e.insertElement(t,n),e.setInsertionMode("inRow")},t.inTableBody.startTagTableCell=function(t,n){e.parseError("unexpected-cell-in-table-body",{name:t}),this.startTagTr("tr",[]),e.insertionMode.processStartTag(t,n)},t.inTableBody.startTagTableOther=function(t,n){e.openElements.inTableScope("tbody")||e.openElements.inTableScope("thead")||e.openElements.inTableScope("tfoot")?(e.openElements.popUntilTableBodyScopeMarker(),this.endTagTableRowGroup(e.currentStackItem().localName),e.insertionMode.processStartTag(t,n)):e.parseError("unexpected-start-tag",{name:t})},t.inTableBody.startTagOther=function(e,n){t.inTable.processStartTag(e,n)},t.inTableBody.endTagTableRowGroup=function(t){e.openElements.inTableScope(t)?(e.openElements.popUntilTableBodyScopeMarker(),e.popElement(),e.setInsertionMode("inTable")):e.parseError("unexpected-end-tag-in-table-body",{name:t})},t.inTableBody.endTagTable=function(t){e.openElements.inTableScope("tbody")||e.openElements.inTableScope("thead")||e.openElements.inTableScope("tfoot")?(e.openElements.popUntilTableBodyScopeMarker(),this.endTagTableRowGroup(e.currentStackItem().localName),e.insertionMode.processEndTag(t)):e.parseError("unexpected-end-tag",{name:t})},t.inTableBody.endTagIgnore=function(t){e.parseError("unexpected-end-tag-in-table-body",{name:t})},t.inTableBody.endTagOther=function(e){t.inTable.processEndTag(e)},t.inSelect=Object.create(t.base),t.inSelect.start_tag_handlers={html:"startTagHtml",option:"startTagOption",optgroup:"startTagOptgroup",select:"startTagSelect",input:"startTagInput",keygen:"startTagInput",textarea:"startTagInput",script:"startTagScript","-default":"startTagOther"},t.inSelect.end_tag_handlers={option:"endTagOption",optgroup:"endTagOptgroup",select:"endTagSelect",caption:"endTagTableElements",table:"endTagTableElements",tbody:"endTagTableElements",tfoot:"endTagTableElements",thead:"endTagTableElements",tr:"endTagTableElements",td:"endTagTableElements",th:"endTagTableElements","-default":"endTagOther"},t.inSelect.processCharacters=function(t){var n=t.takeRemaining();n=n.replace(/\u0000/g,function(t,n){return e.parseError("invalid-codepoint"),""});if(!n)return;e.insertText(n)},t.inSelect.startTagOption=function(t,n){e.currentStackItem().localName=="option"&&e.popElement(),e.insertElement(t,n)},t.inSelect.startTagOptgroup=function(t,n){e.currentStackItem().localName=="option"&&e.popElement(),e.currentStackItem().localName=="optgroup"&&e.popElement(),e.insertElement(t,n)},t.inSelect.endTagOption=function(t){if(e.currentStackItem().localName!=="option"){e.parseError("unexpected-end-tag-in-select",{name:t});return}e.popElement()},t.inSelect.endTagOptgroup=function(t){e.currentStackItem().localName=="option"&&e.openElements.item(e.openElements.length-2).localName=="optgroup"&&e.popElement(),e.currentStackItem().localName=="optgroup"?e.popElement():e.parseError("unexpected-end-tag-in-select",{name:"optgroup"})},t.inSelect.startTagSelect=function(t){e.parseError("unexpected-select-in-select"),this.endTagSelect("select")},t.inSelect.endTagSelect=function(t){e.openElements.inTableScope("select")?(e.openElements.popUntilPopped("select"),e.resetInsertionMode()):e.parseError("unexpected-end-tag",{name:t})},t.inSelect.startTagInput=function(t,n){e.parseError("unexpected-input-in-select"),e.openElements.inSelectScope("select")&&(this.endTagSelect("select"),e.insertionMode.processStartTag(t,n))},t.inSelect.startTagScript=function(e,n){t.inHead.processStartTag(e,n)},t.inSelect.endTagTableElements=function(t){e.parseError("unexpected-end-tag-in-select",{name:t}),e.openElements.inTableScope(t)&&(this.endTagSelect("select"),e.insertionMode.processEndTag(t))},t.inSelect.startTagOther=function(t,n){e.parseError("unexpected-start-tag-in-select",{name:t})},t.inSelect.endTagOther=function(t){e.parseError("unexpected-end-tag-in-select",{name:t})},t.inSelectInTable=Object.create(t.base),t.inSelectInTable.start_tag_handlers={caption:"startTagTable",table:"startTagTable",tbody:"startTagTable",tfoot:"startTagTable",thead:"startTagTable",tr:"startTagTable",td:"startTagTable",th:"startTagTable","-default":"startTagOther"},t.inSelectInTable.end_tag_handlers={caption:"endTagTable",table:"endTagTable",tbody:"endTagTable",tfoot:"endTagTable",thead:"endTagTable",tr:"endTagTable",td:"endTagTable",th:"endTagTable","-default":"endTagOther"},t.inSelectInTable.processCharacters=function(e){t.inSelect.processCharacters(e)},t.inSelectInTable.startTagTable=function(t,n){e.parseError("unexpected-table-element-start-tag-in-select-in-table",{name:t}),this.endTagOther("select"),e.insertionMode.processStartTag(t,n)},t.inSelectInTable.startTagOther=function(e,n,r){t.inSelect.processStartTag(e,n,r)},t.inSelectInTable.endTagTable=function(t){e.parseError("unexpected-table-element-end-tag-in-select-in-table",{name:t}),e.openElements.inTableScope(t)&&(this.endTagOther("select"),e.insertionMode.processEndTag(t))},t.inSelectInTable.endTagOther=function(e){t.inSelect.processEndTag(e)},t.inRow=Object.create(t.base),t.inRow.start_tag_handlers={html:"startTagHtml",td:"startTagTableCell",th:"startTagTableCell",caption:"startTagTableOther",col:"startTagTableOther",colgroup:"startTagTableOther",tbody:"startTagTableOther",tfoot:"startTagTableOther",thead:"startTagTableOther",tr:"startTagTableOther","-default":"startTagOther"},t.inRow.end_tag_handlers={tr:"endTagTr",table:"endTagTable",tbody:"endTagTableRowGroup",tfoot:"endTagTableRowGroup",thead:"endTagTableRowGroup",body:"endTagIgnore",caption:"endTagIgnore",col:"endTagIgnore",colgroup:"endTagIgnore",html:"endTagIgnore",td:"endTagIgnore",th:"endTagIgnore","-default":"endTagOther"},t.inRow.processCharacters=function(e){t.inTable.processCharacters(e)},t.inRow.startTagTableCell=function(t,n){e.openElements.popUntilTableRowScopeMarker(),e.insertElement(t,n),e.setInsertionMode("inCell"),e.activeFormattingElements.push(l)},t.inRow.startTagTableOther=function(t,n){var r=this.ignoreEndTagTr();this.endTagTr("tr"),r||e.insertionMode.processStartTag(t,n)},t.inRow.startTagOther=function(e,n,r){t.inTable.processStartTag(e,n,r)},t.inRow.endTagTr=function(t){this.ignoreEndTagTr()?(r.ok(e.context),e.parseError("unexpected-end-tag",{name:t})):(e.openElements.popUntilTableRowScopeMarker(),e.popElement(),e.setInsertionMode("inTableBody"))},t.inRow.endTagTable=function(t){var n=this.ignoreEndTagTr();this.endTagTr("tr"),n||e.insertionMode.processEndTag(t)},t.inRow.endTagTableRowGroup=function(t){e.openElements.inTableScope(t)?(this.endTagTr("tr"),e.insertionMode.processEndTag(t)):e.parseError("unexpected-end-tag",{name:t})},t.inRow.endTagIgnore=function(t){e.parseError("unexpected-end-tag-in-table-row",{name:t})},t.inRow.endTagOther=function(e){t.inTable.processEndTag(e)},t.inRow.ignoreEndTagTr=function(){return!e.openElements.inTableScope("tr")},t.afterAfterFrameset=Object.create(t.base),t.afterAfterFrameset.start_tag_handlers={html:"startTagHtml",noframes:"startTagNoFrames","-default":"startTagOther"},t.afterAfterFrameset.processEOF=function(){},t.afterAfterFrameset.processComment=function(t){e.insertComment(t,e.document)},t.afterAfterFrameset.processCharacters=function(t){var n=t.takeRemaining(),r="";for(var i=0;i0&&this.currentStackItem().isForeign()},g.prototype.isSelfClosingFlagAcknowledged=function(){return this.selfClosingFlagAcknowledged},g.prototype.createElement=function(e,t,n){throw new Error("Not implemented")},g.prototype.attachNode=function(e,t){throw new Error("Not implemented")},g.prototype.attachNodeToFosterParent=function(e,t,n){throw new Error("Not implemented")},g.prototype.detachFromParent=function(e){throw new Error("Not implemented")},g.prototype.addAttributesToElement=function(e,t){throw new Error("Not implemented")},g.prototype.insertHtmlElement=function(e){var t=this.createElement("http://www.w3.org/1999/xhtml","html",e);return this.attachNode(t,this.document),this.openElements.pushHtmlElement(new f("http://www.w3.org/1999/xhtml","html",e,t)),t},g.prototype.insertHeadElement=function(e){var t=this.createElement("http://www.w3.org/1999/xhtml","head",e);return this.head=new f("http://www.w3.org/1999/xhtml","head",e,t),this.attachNode(t,this.openElements.top.node),this.openElements.pushHeadElement(this.head),t},g.prototype.insertBodyElement=function(e){var t=this.createElement("http://www.w3.org/1999/xhtml","body",e);return this.attachNode(t,this.openElements.top.node),this.openElements.pushBodyElement(new f("http://www.w3.org/1999/xhtml","body",e,t)),t},g.prototype.insertIntoFosterParent=function(e){var t=this.openElements.findIndex("table"),n=this.openElements.item(t).node;if(t===0)return this.attachNode(e,n);this.attachNodeToFosterParent(e,n,this.openElements.item(t-1).node)},g.prototype.insertElement=function(e,t,n,r){n||(n="http://www.w3.org/1999/xhtml");var i=this.createElement(n,e,t);this.shouldFosterParent()?this.insertIntoFosterParent(i):this.attachNode(i,this.openElements.top.node),r||this.openElements.push(new f(n,e,t,i))},g.prototype.insertFormattingElement=function(e,t){this.insertElement(e,t,"http://www.w3.org/1999/xhtml"),this.appendElementToActiveFormattingElements(this.currentStackItem())},g.prototype.insertSelfClosingElement=function(e,t){this.selfClosingFlagAcknowledged=!0,this.insertElement(e,t,"http://www.w3.org/1999/xhtml",!0)},g.prototype.insertForeignElement=function(e,t,n,r){r&&(this.selfClosingFlagAcknowledged=!0),this.insertElement(e,t,n,r)},g.prototype.insertComment=function(e,t){throw new Error("Not implemented")},g.prototype.insertDoctype=function(e,t,n){throw new Error("Not implemented")},g.prototype.insertText=function(e){throw new Error("Not implemented")},g.prototype.currentStackItem=function(){return this.openElements.top},g.prototype.popElement=function(){return this.openElements.pop()},g.prototype.shouldFosterParent=function(){return this.redirectAttachToFosterParent&&this.currentStackItem().isFosterParenting()},g.prototype.generateImpliedEndTags=function(e){var t=this.openElements.top.localName;["dd","dt","li","option","optgroup","p","rp","rt"].indexOf(t)!=-1&&t!=e&&(this.popElement(),this.generateImpliedEndTags(e))},g.prototype.reconstructActiveFormattingElements=function(){if(this.activeFormattingElements.length===0)return;var e=this.activeFormattingElements.length-1,t=this.activeFormattingElements[e];if(t==l||this.openElements.contains(t))return;while(t!=l&&!this.openElements.contains(t)){e-=1,t=this.activeFormattingElements[e];if(!t)break}for(;;){e+=1,t=this.activeFormattingElements[e],this.insertElement(t.localName,t.attributes);var n=this.currentStackItem();this.activeFormattingElements[e]=n;if(n==this.activeFormattingElements[this.activeFormattingElements.length-1])break}},g.prototype.ensureNoahsArkCondition=function(e){var t=3;if(this.activeFormattingElements.length=0;i--){var s=this.activeFormattingElements[i];if(s===l)break;if(e.localName!==s.localName||e.namespaceURI!==s.namespaceURI)continue;if(s.attributes.length!=r)continue;n.push(s)}if(n.length=0&&this.activeFormattingElements.splice(t,1)},g.prototype.elementInActiveFormattingElements=function(e){var t=this.activeFormattingElements;for(var n=t.length-1;n>=0;n--){if(t[n]==l)break;if(t[n].localName==e)return t[n]}return!1},g.prototype.clearActiveFormattingElements=function(){while(this.activeFormattingElements.length!==0&&this.activeFormattingElements.pop()!=l);},g.prototype.reparentChildren=function(e,t){throw new Error("Not implemented")},g.prototype.setFragmentContext=function(e){this.context=e},g.prototype.parseError=function(e,t){if(!this.errorHandler)return;var n=y(i[e],t);this.errorHandler.error(n,this.tokenizer._inputStream.location(),e)},g.prototype.resetInsertionMode=function(){var e=!1,t=null;for(var n=this.openElements.length-1;n>=0;n--){t=this.openElements.item(n),n===0&&(r.ok(this.context),e=!0,t=new f("http://www.w3.org/1999/xhtml",this.context,[],null));if(t.namespaceURI==="http://www.w3.org/1999/xhtml"){if(t.localName==="select")return this.setInsertionMode("inSelect");if(t.localName==="td"||t.localName==="th")return this.setInsertionMode("inCell");if(t.localName==="tr")return this.setInsertionMode("inRow");if(t.localName==="tbody"||t.localName==="thead"||t.localName==="tfoot")return this.setInsertionMode("inTableBody");if(t.localName==="caption")return this.setInsertionMode("inCaption");if(t.localName==="colgroup")return this.setInsertionMode("inColumnGroup");if(t.localName==="table")return this.setInsertionMode("inTable");if(t.localName==="head"&&!e)return this.setInsertionMode("inHead");if(t.localName==="body")return this.setInsertionMode("inBody");if(t.localName==="frameset")return this.setInsertionMode("inFrameset");if(t.localName==="html")return this.openElements.headElement?this.setInsertionMode("afterHead"):this.setInsertionMode("beforeHead")}if(e)return this.setInsertionMode("inBody")}},g.prototype.processGenericRCDATAStartTag=function(e,t){this.insertElement(e,t),this.tokenizer.setState(u.RCDATA),this.originalInsertionMode=this.insertionModeName,this.setInsertionMode("text")},g.prototype.processGenericRawTextStartTag=function(e,t){this.insertElement(e,t),this.tokenizer.setState(u.RAWTEXT),this.originalInsertionMode=this.insertionModeName,this.setInsertionMode("text")},g.prototype.adjustMathMLAttributes=function(e){return e.forEach(function(e){e.namespaceURI="http://www.w3.org/1998/Math/MathML",s.MATHMLAttributeMap[e.nodeName]&&(e.nodeName=s.MATHMLAttributeMap[e.nodeName])}),e},g.prototype.adjustSVGTagNameCase=function(e){return s.SVGTagMap[e]||e},g.prototype.adjustSVGAttributes=function(e){return e.forEach(function(e){e.namespaceURI="http://www.w3.org/2000/svg",s.SVGAttributeMap[e.nodeName]&&(e.nodeName=s.SVGAttributeMap[e.nodeName])}),e},g.prototype.adjustForeignAttributes=function(e){for(var t=0;t' instead.","expected-tag-name-but-got-question-mark":"Expected tag name. Got '?' instead. (HTML doesn't support processing instructions.)","expected-tag-name":"Expected tag name. Got something else instead.","expected-closing-tag-but-got-right-bracket":"Expected closing tag. Got '>' instead. Ignoring ''.","expected-closing-tag-but-got-eof":"Expected closing tag. Unexpected end of file.","expected-closing-tag-but-got-char":"Expected closing tag. Unexpected character '{data}' found.","eof-in-tag-name":"Unexpected end of file in the tag name.","expected-attribute-name-but-got-eof":"Unexpected end of file. Expected attribute name instead.","eof-in-attribute-name":"Unexpected end of file in attribute name.","invalid-character-in-attribute-name":"Invalid character in attribute name.","duplicate-attribute":"Dropped duplicate attribute '{name}' on tag.","expected-end-of-tag-but-got-eof":"Unexpected end of file. Expected = or end of tag.","expected-attribute-value-but-got-eof":"Unexpected end of file. Expected attribute value.","expected-attribute-value-but-got-right-bracket":"Expected attribute value. Got '>' instead.","unexpected-character-in-unquoted-attribute-value":"Unexpected character in unquoted attribute","invalid-character-after-attribute-name":"Unexpected character after attribute name.","unexpected-character-after-attribute-value":"Unexpected character after attribute value.","eof-in-attribute-value-double-quote":'Unexpected end of file in attribute value (").',"eof-in-attribute-value-single-quote":"Unexpected end of file in attribute value (').","eof-in-attribute-value-no-quotes":"Unexpected end of file in attribute value.","eof-after-attribute-value":"Unexpected end of file after attribute value.","unexpected-eof-after-solidus-in-tag":"Unexpected end of file in tag. Expected >.","unexpected-character-after-solidus-in-tag":"Unexpected character after / in tag. Expected >.","expected-dashes-or-doctype":"Expected '--' or 'DOCTYPE'. Not found.","unexpected-bang-after-double-dash-in-comment":"Unexpected ! after -- in comment.","incorrect-comment":"Incorrect comment.","eof-in-comment":"Unexpected end of file in comment.","eof-in-comment-end-dash":"Unexpected end of file in comment (-).","unexpected-dash-after-double-dash-in-comment":"Unexpected '-' after '--' found in comment.","eof-in-comment-double-dash":"Unexpected end of file in comment (--).","eof-in-comment-end-bang-state":"Unexpected end of file in comment.","unexpected-char-in-comment":"Unexpected character in comment found.","need-space-after-doctype":"No space after literal string 'DOCTYPE'.","expected-doctype-name-but-got-right-bracket":"Unexpected > character. Expected DOCTYPE name.","expected-doctype-name-but-got-eof":"Unexpected end of file. Expected DOCTYPE name.","eof-in-doctype-name":"Unexpected end of file in DOCTYPE name.","eof-in-doctype":"Unexpected end of file in DOCTYPE.","expected-space-or-right-bracket-in-doctype":"Expected space or '>'. Got '{data}'.","unexpected-end-of-doctype":"Unexpected end of DOCTYPE.","unexpected-char-in-doctype":"Unexpected character in DOCTYPE.","eof-in-bogus-doctype":"Unexpected end of file in bogus doctype.","eof-in-innerhtml":"Unexpected EOF in inner html mode.","unexpected-doctype":"Unexpected DOCTYPE. Ignored.","non-html-root":"html needs to be the first start tag.","expected-doctype-but-got-eof":"Unexpected End of file. Expected DOCTYPE.","unknown-doctype":"Erroneous DOCTYPE. Expected .","quirky-doctype":"Quirky doctype. Expected .","almost-standards-doctype":"Almost standards mode doctype. Expected .","obsolete-doctype":"Obsolete doctype. Expected .","expected-doctype-but-got-chars":"Non-space characters found without seeing a doctype first. Expected e.g. .","expected-doctype-but-got-start-tag":"Start tag seen without seeing a doctype first. Expected e.g. .","expected-doctype-but-got-end-tag":"End tag seen without seeing a doctype first. Expected e.g. .","end-tag-after-implied-root":"Unexpected end tag ({name}) after the (implied) root element.","expected-named-closing-tag-but-got-eof":"Unexpected end of file. Expected end tag ({name}).","two-heads-are-not-better-than-one":"Unexpected start tag head in existing head. Ignored.","unexpected-end-tag":"Unexpected end tag ({name}). Ignored.","unexpected-implied-end-tag":"End tag {name} implied, but there were open elements.","unexpected-start-tag-out-of-my-head":"Unexpected start tag ({name}) that can be in head. Moved.","unexpected-start-tag":"Unexpected start tag ({name}).","missing-end-tag":"Missing end tag ({name}).","missing-end-tags":"Missing end tags ({name}).","unexpected-start-tag-implies-end-tag":"Unexpected start tag ({startName}) implies end tag ({endName}).","unexpected-start-tag-treated-as":"Unexpected start tag ({originalName}). Treated as {newName}.","deprecated-tag":"Unexpected start tag {name}. Don't use it!","unexpected-start-tag-ignored":"Unexpected start tag {name}. Ignored.","expected-one-end-tag-but-got-another":"Unexpected end tag ({gotName}). Missing end tag ({expectedName}).","end-tag-too-early":"End tag ({name}) seen too early. Expected other end tag.","end-tag-too-early-named":"Unexpected end tag ({gotName}). Expected end tag ({expectedName}.","end-tag-too-early-ignored":"End tag ({name}) seen too early. Ignored.","adoption-agency-1.1":"End tag ({name}) violates step 1, paragraph 1 of the adoption agency algorithm.","adoption-agency-1.2":"End tag ({name}) violates step 1, paragraph 2 of the adoption agency algorithm.","adoption-agency-1.3":"End tag ({name}) violates step 1, paragraph 3 of the adoption agency algorithm.","adoption-agency-4.4":"End tag ({name}) violates step 4, paragraph 4 of the adoption agency algorithm.","unexpected-end-tag-treated-as":"Unexpected end tag ({originalName}). Treated as {newName}.","no-end-tag":"This element ({name}) has no end tag.","unexpected-implied-end-tag-in-table":"Unexpected implied end tag ({name}) in the table phase.","unexpected-implied-end-tag-in-table-body":"Unexpected implied end tag ({name}) in the table body phase.","unexpected-char-implies-table-voodoo":"Unexpected non-space characters in table context caused voodoo mode.","unexpected-hidden-input-in-table":"Unexpected input with type hidden in table context.","unexpected-form-in-table":"Unexpected form in table context.","unexpected-start-tag-implies-table-voodoo":"Unexpected start tag ({name}) in table context caused voodoo mode.","unexpected-end-tag-implies-table-voodoo":"Unexpected end tag ({name}) in table context caused voodoo mode.","unexpected-cell-in-table-body":"Unexpected table cell start tag ({name}) in the table body phase.","unexpected-cell-end-tag":"Got table cell end tag ({name}) while required end tags are missing.","unexpected-end-tag-in-table-body":"Unexpected end tag ({name}) in the table body phase. Ignored.","unexpected-implied-end-tag-in-table-row":"Unexpected implied end tag ({name}) in the table row phase.","unexpected-end-tag-in-table-row":"Unexpected end tag ({name}) in the table row phase. Ignored.","unexpected-select-in-select":"Unexpected select start tag in the select phase treated as select end tag.","unexpected-input-in-select":"Unexpected input start tag in the select phase.","unexpected-start-tag-in-select":"Unexpected start tag token ({name}) in the select phase. Ignored.","unexpected-end-tag-in-select":"Unexpected end tag ({name}) in the select phase. Ignored.","unexpected-table-element-start-tag-in-select-in-table":"Unexpected table element start tag ({name}) in the select in table phase.","unexpected-table-element-end-tag-in-select-in-table":"Unexpected table element end tag ({name}) in the select in table phase.","unexpected-char-after-body":"Unexpected non-space characters in the after body phase.","unexpected-start-tag-after-body":"Unexpected start tag token ({name}) in the after body phase.","unexpected-end-tag-after-body":"Unexpected end tag token ({name}) in the after body phase.","unexpected-char-in-frameset":"Unepxected characters in the frameset phase. Characters ignored.","unexpected-start-tag-in-frameset":"Unexpected start tag token ({name}) in the frameset phase. Ignored.","unexpected-frameset-in-frameset-innerhtml":"Unexpected end tag token (frameset in the frameset phase (innerHTML).","unexpected-end-tag-in-frameset":"Unexpected end tag token ({name}) in the frameset phase. Ignored.","unexpected-char-after-frameset":"Unexpected non-space characters in the after frameset phase. Ignored.","unexpected-start-tag-after-frameset":"Unexpected start tag ({name}) in the after frameset phase. Ignored.","unexpected-end-tag-after-frameset":"Unexpected end tag ({name}) in the after frameset phase. Ignored.","expected-eof-but-got-char":"Unexpected non-space characters. Expected end of file.","expected-eof-but-got-start-tag":"Unexpected start tag ({name}). Expected end of file.","expected-eof-but-got-end-tag":"Unexpected end tag ({name}). Expected end of file.","unexpected-end-table-in-caption":"Unexpected end table tag in caption. Generates implied end caption.","end-html-in-innerhtml":"Unexpected html end tag in inner html mode.","eof-in-table":"Unexpected end of file. Expected table content.","eof-in-script":"Unexpected end of file. Expected script content.","non-void-element-with-trailing-solidus":"Trailing solidus not allowed on element {name}.","unexpected-html-element-in-foreign-content":'HTML start tag "{name}" in a foreign namespace context.',"unexpected-start-tag-in-table":"Unexpected {name}. Expected table content."}},{}],9:[function(e,t,n){function o(){this.contentHandler=null,this._errorHandler=null,this._treeBuilder=new r,this._tokenizer=new i(this._treeBuilder),this._scriptingEnabled=!1}var r=e("./SAXTreeBuilder").SAXTreeBuilder,i=e("../Tokenizer").Tokenizer,s=e("./TreeParser").TreeParser;o.prototype.parse=function(e){this._tokenizer.tokenize(e);var t=this._treeBuilder.document;t&&(new s(this.contentHandler)).parse(t)},o.prototype.parseFragment=function(e,t){this._treeBuilder.setFragmentContext(t),this._tokenizer.tokenize(e);var n=this._treeBuilder.getFragment();n&&(new s(this.contentHandler)).parse(n)},Object.defineProperty(o.prototype,"scriptingEnabled",{get:function(){return this._scriptingEnabled},set:function(e){this._scriptingEnabled=e,this._treeBuilder.scriptingEnabled=e}}),Object.defineProperty(o.prototype,"errorHandler",{get:function(){return this._errorHandler},set:function(e){this._errorHandler=e,this._treeBuilder.errorHandler=e}}),n.SAXParser=o},{"../Tokenizer":5,"./SAXTreeBuilder":10,"./TreeParser":11}],10:[function(e,t,n){function s(){i.call(this)}function o(e,t){for(var n=0;n",gt:">","GT;":">",GT:">","Gt;":"\u226b","gtdot;":"\u22d7","gtlPar;":"\u2995","gtquest;":"\u2a7c","gtrapprox;":"\u2a86","gtrarr;":"\u2978","gtrdot;":"\u22d7","gtreqless;":"\u22db","gtreqqless;":"\u2a8c","gtrless;":"\u2277","gtrsim;":"\u2273","gvertneqq;":"\u2269\ufe00","gvnE;":"\u2269\ufe00","Hacek;":"\u02c7","hairsp;":"\u200a","half;":"\u00bd","hamilt;":"\u210b","HARDcy;":"\u042a","hardcy;":"\u044a","harrcir;":"\u2948","harr;":"\u2194","hArr;":"\u21d4","harrw;":"\u21ad","Hat;":"^","hbar;":"\u210f","Hcirc;":"\u0124","hcirc;":"\u0125","hearts;":"\u2665","heartsuit;":"\u2665","hellip;":"\u2026","hercon;":"\u22b9","hfr;":"\ud835\udd25","Hfr;":"\u210c","HilbertSpace;":"\u210b","hksearow;":"\u2925","hkswarow;":"\u2926","hoarr;":"\u21ff","homtht;":"\u223b","hookleftarrow;":"\u21a9","hookrightarrow;":"\u21aa","hopf;":"\ud835\udd59","Hopf;":"\u210d","horbar;":"\u2015","HorizontalLine;":"\u2500","hscr;":"\ud835\udcbd","Hscr;":"\u210b","hslash;":"\u210f","Hstrok;":"\u0126","hstrok;":"\u0127","HumpDownHump;":"\u224e","HumpEqual;":"\u224f","hybull;":"\u2043","hyphen;":"\u2010","Iacute;":"\u00cd",Iacute:"\u00cd","iacute;":"\u00ed",iacute:"\u00ed","ic;":"\u2063","Icirc;":"\u00ce",Icirc:"\u00ce","icirc;":"\u00ee",icirc:"\u00ee","Icy;":"\u0418","icy;":"\u0438","Idot;":"\u0130","IEcy;":"\u0415","iecy;":"\u0435","iexcl;":"\u00a1",iexcl:"\u00a1","iff;":"\u21d4","ifr;":"\ud835\udd26","Ifr;":"\u2111","Igrave;":"\u00cc",Igrave:"\u00cc","igrave;":"\u00ec",igrave:"\u00ec","ii;":"\u2148","iiiint;":"\u2a0c","iiint;":"\u222d","iinfin;":"\u29dc","iiota;":"\u2129","IJlig;":"\u0132","ijlig;":"\u0133","Imacr;":"\u012a","imacr;":"\u012b","image;":"\u2111","ImaginaryI;":"\u2148","imagline;":"\u2110","imagpart;":"\u2111","imath;":"\u0131","Im;":"\u2111","imof;":"\u22b7","imped;":"\u01b5","Implies;":"\u21d2","incare;":"\u2105","in;":"\u2208","infin;":"\u221e","infintie;":"\u29dd","inodot;":"\u0131","intcal;":"\u22ba","int;":"\u222b","Int;":"\u222c","integers;":"\u2124","Integral;":"\u222b","intercal;":"\u22ba","Intersection;":"\u22c2","intlarhk;":"\u2a17","intprod;":"\u2a3c","InvisibleComma;":"\u2063","InvisibleTimes;":"\u2062","IOcy;":"\u0401","iocy;":"\u0451","Iogon;":"\u012e","iogon;":"\u012f","Iopf;":"\ud835\udd40","iopf;":"\ud835\udd5a","Iota;":"\u0399","iota;":"\u03b9","iprod;":"\u2a3c","iquest;":"\u00bf",iquest:"\u00bf","iscr;":"\ud835\udcbe","Iscr;":"\u2110","isin;":"\u2208","isindot;":"\u22f5","isinE;":"\u22f9","isins;":"\u22f4","isinsv;":"\u22f3","isinv;":"\u2208","it;":"\u2062","Itilde;":"\u0128","itilde;":"\u0129","Iukcy;":"\u0406","iukcy;":"\u0456","Iuml;":"\u00cf",Iuml:"\u00cf","iuml;":"\u00ef",iuml:"\u00ef","Jcirc;":"\u0134","jcirc;":"\u0135","Jcy;":"\u0419","jcy;":"\u0439","Jfr;":"\ud835\udd0d","jfr;":"\ud835\udd27","jmath;":"\u0237","Jopf;":"\ud835\udd41","jopf;":"\ud835\udd5b","Jscr;":"\ud835\udca5","jscr;":"\ud835\udcbf","Jsercy;":"\u0408","jsercy;":"\u0458","Jukcy;":"\u0404","jukcy;":"\u0454","Kappa;":"\u039a","kappa;":"\u03ba","kappav;":"\u03f0","Kcedil;":"\u0136","kcedil;":"\u0137","Kcy;":"\u041a","kcy;":"\u043a","Kfr;":"\ud835\udd0e","kfr;":"\ud835\udd28","kgreen;":"\u0138","KHcy;":"\u0425","khcy;":"\u0445","KJcy;":"\u040c","kjcy;":"\u045c","Kopf;":"\ud835\udd42","kopf;":"\ud835\udd5c","Kscr;":"\ud835\udca6","kscr;":"\ud835\udcc0","lAarr;":"\u21da","Lacute;":"\u0139","lacute;":"\u013a","laemptyv;":"\u29b4","lagran;":"\u2112","Lambda;":"\u039b","lambda;":"\u03bb","lang;":"\u27e8","Lang;":"\u27ea","langd;":"\u2991","langle;":"\u27e8","lap;":"\u2a85","Laplacetrf;":"\u2112","laquo;":"\u00ab",laquo:"\u00ab","larrb;":"\u21e4","larrbfs;":"\u291f","larr;":"\u2190","Larr;":"\u219e","lArr;":"\u21d0","larrfs;":"\u291d","larrhk;":"\u21a9","larrlp;":"\u21ab","larrpl;":"\u2939","larrsim;":"\u2973","larrtl;":"\u21a2","latail;":"\u2919","lAtail;":"\u291b","lat;":"\u2aab","late;":"\u2aad","lates;":"\u2aad\ufe00","lbarr;":"\u290c","lBarr;":"\u290e","lbbrk;":"\u2772","lbrace;":"{","lbrack;":"[","lbrke;":"\u298b","lbrksld;":"\u298f","lbrkslu;":"\u298d","Lcaron;":"\u013d","lcaron;":"\u013e","Lcedil;":"\u013b","lcedil;":"\u013c","lceil;":"\u2308","lcub;":"{","Lcy;":"\u041b","lcy;":"\u043b","ldca;":"\u2936","ldquo;":"\u201c","ldquor;":"\u201e","ldrdhar;":"\u2967","ldrushar;":"\u294b","ldsh;":"\u21b2","le;":"\u2264","lE;":"\u2266","LeftAngleBracket;":"\u27e8","LeftArrowBar;":"\u21e4","leftarrow;":"\u2190","LeftArrow;":"\u2190","Leftarrow;":"\u21d0","LeftArrowRightArrow;":"\u21c6","leftarrowtail;":"\u21a2","LeftCeiling;":"\u2308","LeftDoubleBracket;":"\u27e6","LeftDownTeeVector;":"\u2961","LeftDownVectorBar;":"\u2959","LeftDownVector;":"\u21c3","LeftFloor;":"\u230a","leftharpoondown;":"\u21bd","leftharpoonup;":"\u21bc","leftleftarrows;":"\u21c7","leftrightarrow;":"\u2194","LeftRightArrow;":"\u2194","Leftrightarrow;":"\u21d4","leftrightarrows;":"\u21c6","leftrightharpoons;":"\u21cb","leftrightsquigarrow;":"\u21ad","LeftRightVector;":"\u294e","LeftTeeArrow;":"\u21a4","LeftTee;":"\u22a3","LeftTeeVector;":"\u295a","leftthreetimes;":"\u22cb","LeftTriangleBar;":"\u29cf","LeftTriangle;":"\u22b2","LeftTriangleEqual;":"\u22b4","LeftUpDownVector;":"\u2951","LeftUpTeeVector;":"\u2960","LeftUpVectorBar;":"\u2958","LeftUpVector;":"\u21bf","LeftVectorBar;":"\u2952","LeftVector;":"\u21bc","lEg;":"\u2a8b","leg;":"\u22da","leq;":"\u2264","leqq;":"\u2266","leqslant;":"\u2a7d","lescc;":"\u2aa8","les;":"\u2a7d","lesdot;":"\u2a7f","lesdoto;":"\u2a81","lesdotor;":"\u2a83","lesg;":"\u22da\ufe00","lesges;":"\u2a93","lessapprox;":"\u2a85","lessdot;":"\u22d6","lesseqgtr;":"\u22da","lesseqqgtr;":"\u2a8b","LessEqualGreater;":"\u22da","LessFullEqual;":"\u2266","LessGreater;":"\u2276","lessgtr;":"\u2276","LessLess;":"\u2aa1","lesssim;":"\u2272","LessSlantEqual;":"\u2a7d","LessTilde;":"\u2272","lfisht;":"\u297c","lfloor;":"\u230a","Lfr;":"\ud835\udd0f","lfr;":"\ud835\udd29","lg;":"\u2276","lgE;":"\u2a91","lHar;":"\u2962","lhard;":"\u21bd","lharu;":"\u21bc","lharul;":"\u296a","lhblk;":"\u2584","LJcy;":"\u0409","ljcy;":"\u0459","llarr;":"\u21c7","ll;":"\u226a","Ll;":"\u22d8","llcorner;":"\u231e","Lleftarrow;":"\u21da","llhard;":"\u296b","lltri;":"\u25fa","Lmidot;":"\u013f","lmidot;":"\u0140","lmoustache;":"\u23b0","lmoust;":"\u23b0","lnap;":"\u2a89","lnapprox;":"\u2a89","lne;":"\u2a87","lnE;":"\u2268","lneq;":"\u2a87","lneqq;":"\u2268","lnsim;":"\u22e6","loang;":"\u27ec","loarr;":"\u21fd","lobrk;":"\u27e6","longleftarrow;":"\u27f5","LongLeftArrow;":"\u27f5","Longleftarrow;":"\u27f8","longleftrightarrow;":"\u27f7","LongLeftRightArrow;":"\u27f7","Longleftrightarrow;":"\u27fa","longmapsto;":"\u27fc","longrightarrow;":"\u27f6","LongRightArrow;":"\u27f6","Longrightarrow;":"\u27f9","looparrowleft;":"\u21ab","looparrowright;":"\u21ac","lopar;":"\u2985","Lopf;":"\ud835\udd43","lopf;":"\ud835\udd5d","loplus;":"\u2a2d","lotimes;":"\u2a34","lowast;":"\u2217","lowbar;":"_","LowerLeftArrow;":"\u2199","LowerRightArrow;":"\u2198","loz;":"\u25ca","lozenge;":"\u25ca","lozf;":"\u29eb","lpar;":"(","lparlt;":"\u2993","lrarr;":"\u21c6","lrcorner;":"\u231f","lrhar;":"\u21cb","lrhard;":"\u296d","lrm;":"\u200e","lrtri;":"\u22bf","lsaquo;":"\u2039","lscr;":"\ud835\udcc1","Lscr;":"\u2112","lsh;":"\u21b0","Lsh;":"\u21b0","lsim;":"\u2272","lsime;":"\u2a8d","lsimg;":"\u2a8f","lsqb;":"[","lsquo;":"\u2018","lsquor;":"\u201a","Lstrok;":"\u0141","lstrok;":"\u0142","ltcc;":"\u2aa6","ltcir;":"\u2a79","lt;":"<",lt:"<","LT;":"<",LT:"<","Lt;":"\u226a","ltdot;":"\u22d6","lthree;":"\u22cb","ltimes;":"\u22c9","ltlarr;":"\u2976","ltquest;":"\u2a7b","ltri;":"\u25c3","ltrie;":"\u22b4","ltrif;":"\u25c2","ltrPar;":"\u2996","lurdshar;":"\u294a","luruhar;":"\u2966","lvertneqq;":"\u2268\ufe00","lvnE;":"\u2268\ufe00","macr;":"\u00af",macr:"\u00af","male;":"\u2642","malt;":"\u2720","maltese;":"\u2720","Map;":"\u2905","map;":"\u21a6","mapsto;":"\u21a6","mapstodown;":"\u21a7","mapstoleft;":"\u21a4","mapstoup;":"\u21a5","marker;":"\u25ae","mcomma;":"\u2a29","Mcy;":"\u041c","mcy;":"\u043c","mdash;":"\u2014","mDDot;":"\u223a","measuredangle;":"\u2221","MediumSpace;":"\u205f","Mellintrf;":"\u2133","Mfr;":"\ud835\udd10","mfr;":"\ud835\udd2a","mho;":"\u2127","micro;":"\u00b5",micro:"\u00b5","midast;":"*","midcir;":"\u2af0","mid;":"\u2223","middot;":"\u00b7",middot:"\u00b7","minusb;":"\u229f","minus;":"\u2212","minusd;":"\u2238","minusdu;":"\u2a2a","MinusPlus;":"\u2213","mlcp;":"\u2adb","mldr;":"\u2026","mnplus;":"\u2213","models;":"\u22a7","Mopf;":"\ud835\udd44","mopf;":"\ud835\udd5e","mp;":"\u2213","mscr;":"\ud835\udcc2","Mscr;":"\u2133","mstpos;":"\u223e","Mu;":"\u039c","mu;":"\u03bc","multimap;":"\u22b8","mumap;":"\u22b8","nabla;":"\u2207","Nacute;":"\u0143","nacute;":"\u0144","nang;":"\u2220\u20d2","nap;":"\u2249","napE;":"\u2a70\u0338","napid;":"\u224b\u0338","napos;":"\u0149","napprox;":"\u2249","natural;":"\u266e","naturals;":"\u2115","natur;":"\u266e","nbsp;":"\u00a0",nbsp:"\u00a0","nbump;":"\u224e\u0338","nbumpe;":"\u224f\u0338","ncap;":"\u2a43","Ncaron;":"\u0147","ncaron;":"\u0148","Ncedil;":"\u0145","ncedil;":"\u0146","ncong;":"\u2247","ncongdot;":"\u2a6d\u0338","ncup;":"\u2a42","Ncy;":"\u041d","ncy;":"\u043d","ndash;":"\u2013","nearhk;":"\u2924","nearr;":"\u2197","neArr;":"\u21d7","nearrow;":"\u2197","ne;":"\u2260","nedot;":"\u2250\u0338","NegativeMediumSpace;":"\u200b","NegativeThickSpace;":"\u200b","NegativeThinSpace;":"\u200b","NegativeVeryThinSpace;":"\u200b","nequiv;":"\u2262","nesear;":"\u2928","nesim;":"\u2242\u0338","NestedGreaterGreater;":"\u226b","NestedLessLess;":"\u226a","NewLine;":"\n","nexist;":"\u2204","nexists;":"\u2204","Nfr;":"\ud835\udd11","nfr;":"\ud835\udd2b","ngE;":"\u2267\u0338","nge;":"\u2271","ngeq;":"\u2271","ngeqq;":"\u2267\u0338","ngeqslant;":"\u2a7e\u0338","nges;":"\u2a7e\u0338","nGg;":"\u22d9\u0338","ngsim;":"\u2275","nGt;":"\u226b\u20d2","ngt;":"\u226f","ngtr;":"\u226f","nGtv;":"\u226b\u0338","nharr;":"\u21ae","nhArr;":"\u21ce","nhpar;":"\u2af2","ni;":"\u220b","nis;":"\u22fc","nisd;":"\u22fa","niv;":"\u220b","NJcy;":"\u040a","njcy;":"\u045a","nlarr;":"\u219a","nlArr;":"\u21cd","nldr;":"\u2025","nlE;":"\u2266\u0338","nle;":"\u2270","nleftarrow;":"\u219a","nLeftarrow;":"\u21cd","nleftrightarrow;":"\u21ae","nLeftrightarrow;":"\u21ce","nleq;":"\u2270","nleqq;":"\u2266\u0338","nleqslant;":"\u2a7d\u0338","nles;":"\u2a7d\u0338","nless;":"\u226e","nLl;":"\u22d8\u0338","nlsim;":"\u2274","nLt;":"\u226a\u20d2","nlt;":"\u226e","nltri;":"\u22ea","nltrie;":"\u22ec","nLtv;":"\u226a\u0338","nmid;":"\u2224","NoBreak;":"\u2060","NonBreakingSpace;":"\u00a0","nopf;":"\ud835\udd5f","Nopf;":"\u2115","Not;":"\u2aec","not;":"\u00ac",not:"\u00ac","NotCongruent;":"\u2262","NotCupCap;":"\u226d","NotDoubleVerticalBar;":"\u2226","NotElement;":"\u2209","NotEqual;":"\u2260","NotEqualTilde;":"\u2242\u0338","NotExists;":"\u2204","NotGreater;":"\u226f","NotGreaterEqual;":"\u2271","NotGreaterFullEqual;":"\u2267\u0338","NotGreaterGreater;":"\u226b\u0338","NotGreaterLess;":"\u2279","NotGreaterSlantEqual;":"\u2a7e\u0338","NotGreaterTilde;":"\u2275","NotHumpDownHump;":"\u224e\u0338","NotHumpEqual;":"\u224f\u0338","notin;":"\u2209","notindot;":"\u22f5\u0338","notinE;":"\u22f9\u0338","notinva;":"\u2209","notinvb;":"\u22f7","notinvc;":"\u22f6","NotLeftTriangleBar;":"\u29cf\u0338","NotLeftTriangle;":"\u22ea","NotLeftTriangleEqual;":"\u22ec","NotLess;":"\u226e","NotLessEqual;":"\u2270","NotLessGreater;":"\u2278","NotLessLess;":"\u226a\u0338","NotLessSlantEqual;":"\u2a7d\u0338","NotLessTilde;":"\u2274","NotNestedGreaterGreater;":"\u2aa2\u0338","NotNestedLessLess;":"\u2aa1\u0338","notni;":"\u220c","notniva;":"\u220c","notnivb;":"\u22fe","notnivc;":"\u22fd","NotPrecedes;":"\u2280","NotPrecedesEqual;":"\u2aaf\u0338","NotPrecedesSlantEqual;":"\u22e0","NotReverseElement;":"\u220c","NotRightTriangleBar;":"\u29d0\u0338","NotRightTriangle;":"\u22eb","NotRightTriangleEqual;":"\u22ed","NotSquareSubset;":"\u228f\u0338","NotSquareSubsetEqual;":"\u22e2","NotSquareSuperset;":"\u2290\u0338","NotSquareSupersetEqual;":"\u22e3","NotSubset;":"\u2282\u20d2","NotSubsetEqual;":"\u2288","NotSucceeds;":"\u2281","NotSucceedsEqual;":"\u2ab0\u0338","NotSucceedsSlantEqual;":"\u22e1","NotSucceedsTilde;":"\u227f\u0338","NotSuperset;":"\u2283\u20d2","NotSupersetEqual;":"\u2289","NotTilde;":"\u2241","NotTildeEqual;":"\u2244","NotTildeFullEqual;":"\u2247","NotTildeTilde;":"\u2249","NotVerticalBar;":"\u2224","nparallel;":"\u2226","npar;":"\u2226","nparsl;":"\u2afd\u20e5","npart;":"\u2202\u0338","npolint;":"\u2a14","npr;":"\u2280","nprcue;":"\u22e0","nprec;":"\u2280","npreceq;":"\u2aaf\u0338","npre;":"\u2aaf\u0338","nrarrc;":"\u2933\u0338","nrarr;":"\u219b","nrArr;":"\u21cf","nrarrw;":"\u219d\u0338","nrightarrow;":"\u219b","nRightarrow;":"\u21cf","nrtri;":"\u22eb","nrtrie;":"\u22ed","nsc;":"\u2281","nsccue;":"\u22e1","nsce;":"\u2ab0\u0338","Nscr;":"\ud835\udca9","nscr;":"\ud835\udcc3","nshortmid;":"\u2224","nshortparallel;":"\u2226","nsim;":"\u2241","nsime;":"\u2244","nsimeq;":"\u2244","nsmid;":"\u2224","nspar;":"\u2226","nsqsube;":"\u22e2","nsqsupe;":"\u22e3","nsub;":"\u2284","nsubE;":"\u2ac5\u0338","nsube;":"\u2288","nsubset;":"\u2282\u20d2","nsubseteq;":"\u2288","nsubseteqq;":"\u2ac5\u0338","nsucc;":"\u2281","nsucceq;":"\u2ab0\u0338","nsup;":"\u2285","nsupE;":"\u2ac6\u0338","nsupe;":"\u2289","nsupset;":"\u2283\u20d2","nsupseteq;":"\u2289","nsupseteqq;":"\u2ac6\u0338","ntgl;":"\u2279","Ntilde;":"\u00d1",Ntilde:"\u00d1","ntilde;":"\u00f1",ntilde:"\u00f1","ntlg;":"\u2278","ntriangleleft;":"\u22ea","ntrianglelefteq;":"\u22ec","ntriangleright;":"\u22eb","ntrianglerighteq;":"\u22ed","Nu;":"\u039d","nu;":"\u03bd","num;":"#","numero;":"\u2116","numsp;":"\u2007","nvap;":"\u224d\u20d2","nvdash;":"\u22ac","nvDash;":"\u22ad","nVdash;":"\u22ae","nVDash;":"\u22af","nvge;":"\u2265\u20d2","nvgt;":">\u20d2","nvHarr;":"\u2904","nvinfin;":"\u29de","nvlArr;":"\u2902","nvle;":"\u2264\u20d2","nvlt;":"<\u20d2","nvltrie;":"\u22b4\u20d2","nvrArr;":"\u2903","nvrtrie;":"\u22b5\u20d2","nvsim;":"\u223c\u20d2","nwarhk;":"\u2923","nwarr;":"\u2196","nwArr;":"\u21d6","nwarrow;":"\u2196","nwnear;":"\u2927","Oacute;":"\u00d3",Oacute:"\u00d3","oacute;":"\u00f3",oacute:"\u00f3","oast;":"\u229b","Ocirc;":"\u00d4",Ocirc:"\u00d4","ocirc;":"\u00f4",ocirc:"\u00f4","ocir;":"\u229a","Ocy;":"\u041e","ocy;":"\u043e","odash;":"\u229d","Odblac;":"\u0150","odblac;":"\u0151","odiv;":"\u2a38","odot;":"\u2299","odsold;":"\u29bc","OElig;":"\u0152","oelig;":"\u0153","ofcir;":"\u29bf","Ofr;":"\ud835\udd12","ofr;":"\ud835\udd2c","ogon;":"\u02db","Ograve;":"\u00d2",Ograve:"\u00d2","ograve;":"\u00f2",ograve:"\u00f2","ogt;":"\u29c1","ohbar;":"\u29b5","ohm;":"\u03a9","oint;":"\u222e","olarr;":"\u21ba","olcir;":"\u29be","olcross;":"\u29bb","oline;":"\u203e","olt;":"\u29c0","Omacr;":"\u014c","omacr;":"\u014d","Omega;":"\u03a9","omega;":"\u03c9","Omicron;":"\u039f","omicron;":"\u03bf","omid;":"\u29b6","ominus;":"\u2296","Oopf;":"\ud835\udd46","oopf;":"\ud835\udd60","opar;":"\u29b7","OpenCurlyDoubleQuote;":"\u201c","OpenCurlyQuote;":"\u2018","operp;":"\u29b9","oplus;":"\u2295","orarr;":"\u21bb","Or;":"\u2a54","or;":"\u2228","ord;":"\u2a5d","order;":"\u2134","orderof;":"\u2134","ordf;":"\u00aa",ordf:"\u00aa","ordm;":"\u00ba",ordm:"\u00ba","origof;":"\u22b6","oror;":"\u2a56","orslope;":"\u2a57","orv;":"\u2a5b","oS;":"\u24c8","Oscr;":"\ud835\udcaa","oscr;":"\u2134","Oslash;":"\u00d8",Oslash:"\u00d8","oslash;":"\u00f8",oslash:"\u00f8","osol;":"\u2298","Otilde;":"\u00d5",Otilde:"\u00d5","otilde;":"\u00f5",otilde:"\u00f5","otimesas;":"\u2a36","Otimes;":"\u2a37","otimes;":"\u2297","Ouml;":"\u00d6",Ouml:"\u00d6","ouml;":"\u00f6",ouml:"\u00f6","ovbar;":"\u233d","OverBar;":"\u203e","OverBrace;":"\u23de","OverBracket;":"\u23b4","OverParenthesis;":"\u23dc","para;":"\u00b6",para:"\u00b6","parallel;":"\u2225","par;":"\u2225","parsim;":"\u2af3","parsl;":"\u2afd","part;":"\u2202","PartialD;":"\u2202","Pcy;":"\u041f","pcy;":"\u043f","percnt;":"%","period;":".","permil;":"\u2030","perp;":"\u22a5","pertenk;":"\u2031","Pfr;":"\ud835\udd13","pfr;":"\ud835\udd2d","Phi;":"\u03a6","phi;":"\u03c6","phiv;":"\u03d5","phmmat;":"\u2133","phone;":"\u260e","Pi;":"\u03a0","pi;":"\u03c0","pitchfork;":"\u22d4","piv;":"\u03d6","planck;":"\u210f","planckh;":"\u210e","plankv;":"\u210f","plusacir;":"\u2a23","plusb;":"\u229e","pluscir;":"\u2a22","plus;":"+","plusdo;":"\u2214","plusdu;":"\u2a25","pluse;":"\u2a72","PlusMinus;":"\u00b1","plusmn;":"\u00b1",plusmn:"\u00b1","plussim;":"\u2a26","plustwo;":"\u2a27","pm;":"\u00b1","Poincareplane;":"\u210c","pointint;":"\u2a15","popf;":"\ud835\udd61","Popf;":"\u2119","pound;":"\u00a3",pound:"\u00a3","prap;":"\u2ab7","Pr;":"\u2abb","pr;":"\u227a","prcue;":"\u227c","precapprox;":"\u2ab7","prec;":"\u227a","preccurlyeq;":"\u227c","Precedes;":"\u227a","PrecedesEqual;":"\u2aaf","PrecedesSlantEqual;":"\u227c","PrecedesTilde;":"\u227e","preceq;":"\u2aaf","precnapprox;":"\u2ab9","precneqq;":"\u2ab5","precnsim;":"\u22e8","pre;":"\u2aaf","prE;":"\u2ab3","precsim;":"\u227e","prime;":"\u2032","Prime;":"\u2033","primes;":"\u2119","prnap;":"\u2ab9","prnE;":"\u2ab5","prnsim;":"\u22e8","prod;":"\u220f","Product;":"\u220f","profalar;":"\u232e","profline;":"\u2312","profsurf;":"\u2313","prop;":"\u221d","Proportional;":"\u221d","Proportion;":"\u2237","propto;":"\u221d","prsim;":"\u227e","prurel;":"\u22b0","Pscr;":"\ud835\udcab","pscr;":"\ud835\udcc5","Psi;":"\u03a8","psi;":"\u03c8","puncsp;":"\u2008","Qfr;":"\ud835\udd14","qfr;":"\ud835\udd2e","qint;":"\u2a0c","qopf;":"\ud835\udd62","Qopf;":"\u211a","qprime;":"\u2057","Qscr;":"\ud835\udcac","qscr;":"\ud835\udcc6","quaternions;":"\u210d","quatint;":"\u2a16","quest;":"?","questeq;":"\u225f","quot;":'"',quot:'"',"QUOT;":'"',QUOT:'"',"rAarr;":"\u21db","race;":"\u223d\u0331","Racute;":"\u0154","racute;":"\u0155","radic;":"\u221a","raemptyv;":"\u29b3","rang;":"\u27e9","Rang;":"\u27eb","rangd;":"\u2992","range;":"\u29a5","rangle;":"\u27e9","raquo;":"\u00bb",raquo:"\u00bb","rarrap;":"\u2975","rarrb;":"\u21e5","rarrbfs;":"\u2920","rarrc;":"\u2933","rarr;":"\u2192","Rarr;":"\u21a0","rArr;":"\u21d2","rarrfs;":"\u291e","rarrhk;":"\u21aa","rarrlp;":"\u21ac","rarrpl;":"\u2945","rarrsim;":"\u2974","Rarrtl;":"\u2916","rarrtl;":"\u21a3","rarrw;":"\u219d","ratail;":"\u291a","rAtail;":"\u291c","ratio;":"\u2236","rationals;":"\u211a","rbarr;":"\u290d","rBarr;":"\u290f","RBarr;":"\u2910","rbbrk;":"\u2773","rbrace;":"}","rbrack;":"]","rbrke;":"\u298c","rbrksld;":"\u298e","rbrkslu;":"\u2990","Rcaron;":"\u0158","rcaron;":"\u0159","Rcedil;":"\u0156","rcedil;":"\u0157","rceil;":"\u2309","rcub;":"}","Rcy;":"\u0420","rcy;":"\u0440","rdca;":"\u2937","rdldhar;":"\u2969","rdquo;":"\u201d","rdquor;":"\u201d","rdsh;":"\u21b3","real;":"\u211c","realine;":"\u211b","realpart;":"\u211c","reals;":"\u211d","Re;":"\u211c","rect;":"\u25ad","reg;":"\u00ae",reg:"\u00ae","REG;":"\u00ae",REG:"\u00ae","ReverseElement;":"\u220b","ReverseEquilibrium;":"\u21cb","ReverseUpEquilibrium;":"\u296f","rfisht;":"\u297d","rfloor;":"\u230b","rfr;":"\ud835\udd2f","Rfr;":"\u211c","rHar;":"\u2964","rhard;":"\u21c1","rharu;":"\u21c0","rharul;":"\u296c","Rho;":"\u03a1","rho;":"\u03c1","rhov;":"\u03f1","RightAngleBracket;":"\u27e9","RightArrowBar;":"\u21e5","rightarrow;":"\u2192","RightArrow;":"\u2192","Rightarrow;":"\u21d2","RightArrowLeftArrow;":"\u21c4","rightarrowtail;":"\u21a3","RightCeiling;":"\u2309","RightDoubleBracket;":"\u27e7","RightDownTeeVector;":"\u295d","RightDownVectorBar;":"\u2955","RightDownVector;":"\u21c2","RightFloor;":"\u230b","rightharpoondown;":"\u21c1","rightharpoonup;":"\u21c0","rightleftarrows;":"\u21c4","rightleftharpoons;":"\u21cc","rightrightarrows;":"\u21c9","rightsquigarrow;":"\u219d","RightTeeArrow;":"\u21a6","RightTee;":"\u22a2","RightTeeVector;":"\u295b","rightthreetimes;":"\u22cc","RightTriangleBar;":"\u29d0","RightTriangle;":"\u22b3","RightTriangleEqual;":"\u22b5","RightUpDownVector;":"\u294f","RightUpTeeVector;":"\u295c","RightUpVectorBar;":"\u2954","RightUpVector;":"\u21be","RightVectorBar;":"\u2953","RightVector;":"\u21c0","ring;":"\u02da","risingdotseq;":"\u2253","rlarr;":"\u21c4","rlhar;":"\u21cc","rlm;":"\u200f","rmoustache;":"\u23b1","rmoust;":"\u23b1","rnmid;":"\u2aee","roang;":"\u27ed","roarr;":"\u21fe","robrk;":"\u27e7","ropar;":"\u2986","ropf;":"\ud835\udd63","Ropf;":"\u211d","roplus;":"\u2a2e","rotimes;":"\u2a35","RoundImplies;":"\u2970","rpar;":")","rpargt;":"\u2994","rppolint;":"\u2a12","rrarr;":"\u21c9","Rrightarrow;":"\u21db","rsaquo;":"\u203a","rscr;":"\ud835\udcc7","Rscr;":"\u211b","rsh;":"\u21b1","Rsh;":"\u21b1","rsqb;":"]","rsquo;":"\u2019","rsquor;":"\u2019","rthree;":"\u22cc","rtimes;":"\u22ca","rtri;":"\u25b9","rtrie;":"\u22b5","rtrif;":"\u25b8","rtriltri;":"\u29ce","RuleDelayed;":"\u29f4","ruluhar;":"\u2968","rx;":"\u211e","Sacute;":"\u015a","sacute;":"\u015b","sbquo;":"\u201a","scap;":"\u2ab8","Scaron;":"\u0160","scaron;":"\u0161","Sc;":"\u2abc","sc;":"\u227b","sccue;":"\u227d","sce;":"\u2ab0","scE;":"\u2ab4","Scedil;":"\u015e","scedil;":"\u015f","Scirc;":"\u015c","scirc;":"\u015d","scnap;":"\u2aba","scnE;":"\u2ab6","scnsim;":"\u22e9","scpolint;":"\u2a13","scsim;":"\u227f","Scy;":"\u0421","scy;":"\u0441","sdotb;":"\u22a1","sdot;":"\u22c5","sdote;":"\u2a66","searhk;":"\u2925","searr;":"\u2198","seArr;":"\u21d8","searrow;":"\u2198","sect;":"\u00a7",sect:"\u00a7","semi;":";","seswar;":"\u2929","setminus;":"\u2216","setmn;":"\u2216","sext;":"\u2736","Sfr;":"\ud835\udd16","sfr;":"\ud835\udd30","sfrown;":"\u2322","sharp;":"\u266f","SHCHcy;":"\u0429","shchcy;":"\u0449","SHcy;":"\u0428","shcy;":"\u0448","ShortDownArrow;":"\u2193","ShortLeftArrow;":"\u2190","shortmid;":"\u2223","shortparallel;":"\u2225","ShortRightArrow;":"\u2192","ShortUpArrow;":"\u2191","shy;":"\u00ad",shy:"\u00ad","Sigma;":"\u03a3","sigma;":"\u03c3","sigmaf;":"\u03c2","sigmav;":"\u03c2","sim;":"\u223c","simdot;":"\u2a6a","sime;":"\u2243","simeq;":"\u2243","simg;":"\u2a9e","simgE;":"\u2aa0","siml;":"\u2a9d","simlE;":"\u2a9f","simne;":"\u2246","simplus;":"\u2a24","simrarr;":"\u2972","slarr;":"\u2190","SmallCircle;":"\u2218","smallsetminus;":"\u2216","smashp;":"\u2a33","smeparsl;":"\u29e4","smid;":"\u2223","smile;":"\u2323","smt;":"\u2aaa","smte;":"\u2aac","smtes;":"\u2aac\ufe00","SOFTcy;":"\u042c","softcy;":"\u044c","solbar;":"\u233f","solb;":"\u29c4","sol;":"/","Sopf;":"\ud835\udd4a","sopf;":"\ud835\udd64","spades;":"\u2660","spadesuit;":"\u2660","spar;":"\u2225","sqcap;":"\u2293","sqcaps;":"\u2293\ufe00","sqcup;":"\u2294","sqcups;":"\u2294\ufe00","Sqrt;":"\u221a","sqsub;":"\u228f","sqsube;":"\u2291","sqsubset;":"\u228f","sqsubseteq;":"\u2291","sqsup;":"\u2290","sqsupe;":"\u2292","sqsupset;":"\u2290","sqsupseteq;":"\u2292","square;":"\u25a1","Square;":"\u25a1","SquareIntersection;":"\u2293","SquareSubset;":"\u228f","SquareSubsetEqual;":"\u2291","SquareSuperset;":"\u2290","SquareSupersetEqual;":"\u2292","SquareUnion;":"\u2294","squarf;":"\u25aa","squ;":"\u25a1","squf;":"\u25aa","srarr;":"\u2192","Sscr;":"\ud835\udcae","sscr;":"\ud835\udcc8","ssetmn;":"\u2216","ssmile;":"\u2323","sstarf;":"\u22c6","Star;":"\u22c6","star;":"\u2606","starf;":"\u2605","straightepsilon;":"\u03f5","straightphi;":"\u03d5","strns;":"\u00af","sub;":"\u2282","Sub;":"\u22d0","subdot;":"\u2abd","subE;":"\u2ac5","sube;":"\u2286","subedot;":"\u2ac3","submult;":"\u2ac1","subnE;":"\u2acb","subne;":"\u228a","subplus;":"\u2abf","subrarr;":"\u2979","subset;":"\u2282","Subset;":"\u22d0","subseteq;":"\u2286","subseteqq;":"\u2ac5","SubsetEqual;":"\u2286","subsetneq;":"\u228a","subsetneqq;":"\u2acb","subsim;":"\u2ac7","subsub;":"\u2ad5","subsup;":"\u2ad3","succapprox;":"\u2ab8","succ;":"\u227b","succcurlyeq;":"\u227d","Succeeds;":"\u227b","SucceedsEqual;":"\u2ab0","SucceedsSlantEqual;":"\u227d","SucceedsTilde;":"\u227f","succeq;":"\u2ab0","succnapprox;":"\u2aba","succneqq;":"\u2ab6","succnsim;":"\u22e9","succsim;":"\u227f","SuchThat;":"\u220b","sum;":"\u2211","Sum;":"\u2211","sung;":"\u266a","sup1;":"\u00b9",sup1:"\u00b9","sup2;":"\u00b2",sup2:"\u00b2","sup3;":"\u00b3",sup3:"\u00b3","sup;":"\u2283","Sup;":"\u22d1","supdot;":"\u2abe","supdsub;":"\u2ad8","supE;":"\u2ac6","supe;":"\u2287","supedot;":"\u2ac4","Superset;":"\u2283","SupersetEqual;":"\u2287","suphsol;":"\u27c9","suphsub;":"\u2ad7","suplarr;":"\u297b","supmult;":"\u2ac2","supnE;":"\u2acc","supne;":"\u228b","supplus;":"\u2ac0","supset;":"\u2283","Supset;":"\u22d1","supseteq;":"\u2287","supseteqq;":"\u2ac6","supsetneq;":"\u228b","supsetneqq;":"\u2acc","supsim;":"\u2ac8","supsub;":"\u2ad4","supsup;":"\u2ad6","swarhk;":"\u2926","swarr;":"\u2199","swArr;":"\u21d9","swarrow;":"\u2199","swnwar;":"\u292a","szlig;":"\u00df",szlig:"\u00df","Tab;":" ","target;":"\u2316","Tau;":"\u03a4","tau;":"\u03c4","tbrk;":"\u23b4","Tcaron;":"\u0164","tcaron;":"\u0165","Tcedil;":"\u0162","tcedil;":"\u0163","Tcy;":"\u0422","tcy;":"\u0442","tdot;":"\u20db","telrec;":"\u2315","Tfr;":"\ud835\udd17","tfr;":"\ud835\udd31","there4;":"\u2234","therefore;":"\u2234","Therefore;":"\u2234","Theta;":"\u0398","theta;":"\u03b8","thetasym;":"\u03d1","thetav;":"\u03d1","thickapprox;":"\u2248","thicksim;":"\u223c","ThickSpace;":"\u205f\u200a","ThinSpace;":"\u2009","thinsp;":"\u2009","thkap;":"\u2248","thksim;":"\u223c","THORN;":"\u00de",THORN:"\u00de","thorn;":"\u00fe",thorn:"\u00fe","tilde;":"\u02dc","Tilde;":"\u223c","TildeEqual;":"\u2243","TildeFullEqual;":"\u2245","TildeTilde;":"\u2248","timesbar;":"\u2a31","timesb;":"\u22a0","times;":"\u00d7",times:"\u00d7","timesd;":"\u2a30","tint;":"\u222d","toea;":"\u2928","topbot;":"\u2336","topcir;":"\u2af1","top;":"\u22a4","Topf;":"\ud835\udd4b","topf;":"\ud835\udd65","topfork;":"\u2ada","tosa;":"\u2929","tprime;":"\u2034","trade;":"\u2122","TRADE;":"\u2122","triangle;":"\u25b5","triangledown;":"\u25bf","triangleleft;":"\u25c3","trianglelefteq;":"\u22b4","triangleq;":"\u225c","triangleright;":"\u25b9","trianglerighteq;":"\u22b5","tridot;":"\u25ec","trie;":"\u225c","triminus;":"\u2a3a","TripleDot;":"\u20db","triplus;":"\u2a39","trisb;":"\u29cd","tritime;":"\u2a3b","trpezium;":"\u23e2","Tscr;":"\ud835\udcaf","tscr;":"\ud835\udcc9","TScy;":"\u0426","tscy;":"\u0446","TSHcy;":"\u040b","tshcy;":"\u045b","Tstrok;":"\u0166","tstrok;":"\u0167","twixt;":"\u226c","twoheadleftarrow;":"\u219e","twoheadrightarrow;":"\u21a0","Uacute;":"\u00da",Uacute:"\u00da","uacute;":"\u00fa",uacute:"\u00fa","uarr;":"\u2191","Uarr;":"\u219f","uArr;":"\u21d1","Uarrocir;":"\u2949","Ubrcy;":"\u040e","ubrcy;":"\u045e","Ubreve;":"\u016c","ubreve;":"\u016d","Ucirc;":"\u00db",Ucirc:"\u00db","ucirc;":"\u00fb",ucirc:"\u00fb","Ucy;":"\u0423","ucy;":"\u0443","udarr;":"\u21c5","Udblac;":"\u0170","udblac;":"\u0171","udhar;":"\u296e","ufisht;":"\u297e","Ufr;":"\ud835\udd18","ufr;":"\ud835\udd32","Ugrave;":"\u00d9",Ugrave:"\u00d9","ugrave;":"\u00f9",ugrave:"\u00f9","uHar;":"\u2963","uharl;":"\u21bf","uharr;":"\u21be","uhblk;":"\u2580","ulcorn;":"\u231c","ulcorner;":"\u231c","ulcrop;":"\u230f","ultri;":"\u25f8","Umacr;":"\u016a","umacr;":"\u016b","uml;":"\u00a8",uml:"\u00a8","UnderBar;":"_","UnderBrace;":"\u23df","UnderBracket;":"\u23b5","UnderParenthesis;":"\u23dd","Union;":"\u22c3","UnionPlus;":"\u228e","Uogon;":"\u0172","uogon;":"\u0173","Uopf;":"\ud835\udd4c","uopf;":"\ud835\udd66","UpArrowBar;":"\u2912","uparrow;":"\u2191","UpArrow;":"\u2191","Uparrow;":"\u21d1","UpArrowDownArrow;":"\u21c5","updownarrow;":"\u2195","UpDownArrow;":"\u2195","Updownarrow;":"\u21d5","UpEquilibrium;":"\u296e","upharpoonleft;":"\u21bf","upharpoonright;":"\u21be","uplus;":"\u228e","UpperLeftArrow;":"\u2196","UpperRightArrow;":"\u2197","upsi;":"\u03c5","Upsi;":"\u03d2","upsih;":"\u03d2","Upsilon;":"\u03a5","upsilon;":"\u03c5","UpTeeArrow;":"\u21a5","UpTee;":"\u22a5","upuparrows;":"\u21c8","urcorn;":"\u231d","urcorner;":"\u231d","urcrop;":"\u230e","Uring;":"\u016e","uring;":"\u016f","urtri;":"\u25f9","Uscr;":"\ud835\udcb0","uscr;":"\ud835\udcca","utdot;":"\u22f0","Utilde;":"\u0168","utilde;":"\u0169","utri;":"\u25b5","utrif;":"\u25b4","uuarr;":"\u21c8","Uuml;":"\u00dc",Uuml:"\u00dc","uuml;":"\u00fc",uuml:"\u00fc","uwangle;":"\u29a7","vangrt;":"\u299c","varepsilon;":"\u03f5","varkappa;":"\u03f0","varnothing;":"\u2205","varphi;":"\u03d5","varpi;":"\u03d6","varpropto;":"\u221d","varr;":"\u2195","vArr;":"\u21d5","varrho;":"\u03f1","varsigma;":"\u03c2","varsubsetneq;":"\u228a\ufe00","varsubsetneqq;":"\u2acb\ufe00","varsupsetneq;":"\u228b\ufe00","varsupsetneqq;":"\u2acc\ufe00","vartheta;":"\u03d1","vartriangleleft;":"\u22b2","vartriangleright;":"\u22b3","vBar;":"\u2ae8","Vbar;":"\u2aeb","vBarv;":"\u2ae9","Vcy;":"\u0412","vcy;":"\u0432","vdash;":"\u22a2","vDash;":"\u22a8","Vdash;":"\u22a9","VDash;":"\u22ab","Vdashl;":"\u2ae6","veebar;":"\u22bb","vee;":"\u2228","Vee;":"\u22c1","veeeq;":"\u225a","vellip;":"\u22ee","verbar;":"|","Verbar;":"\u2016","vert;":"|","Vert;":"\u2016","VerticalBar;":"\u2223","VerticalLine;":"|","VerticalSeparator;":"\u2758","VerticalTilde;":"\u2240","VeryThinSpace;":"\u200a","Vfr;":"\ud835\udd19","vfr;":"\ud835\udd33","vltri;":"\u22b2","vnsub;":"\u2282\u20d2","vnsup;":"\u2283\u20d2","Vopf;":"\ud835\udd4d","vopf;":"\ud835\udd67","vprop;":"\u221d","vrtri;":"\u22b3","Vscr;":"\ud835\udcb1","vscr;":"\ud835\udccb","vsubnE;":"\u2acb\ufe00","vsubne;":"\u228a\ufe00","vsupnE;":"\u2acc\ufe00","vsupne;":"\u228b\ufe00","Vvdash;":"\u22aa","vzigzag;":"\u299a","Wcirc;":"\u0174","wcirc;":"\u0175","wedbar;":"\u2a5f","wedge;":"\u2227","Wedge;":"\u22c0","wedgeq;":"\u2259","weierp;":"\u2118","Wfr;":"\ud835\udd1a","wfr;":"\ud835\udd34","Wopf;":"\ud835\udd4e","wopf;":"\ud835\udd68","wp;":"\u2118","wr;":"\u2240","wreath;":"\u2240","Wscr;":"\ud835\udcb2","wscr;":"\ud835\udccc","xcap;":"\u22c2","xcirc;":"\u25ef","xcup;":"\u22c3","xdtri;":"\u25bd","Xfr;":"\ud835\udd1b","xfr;":"\ud835\udd35","xharr;":"\u27f7","xhArr;":"\u27fa","Xi;":"\u039e","xi;":"\u03be","xlarr;":"\u27f5","xlArr;":"\u27f8","xmap;":"\u27fc","xnis;":"\u22fb","xodot;":"\u2a00","Xopf;":"\ud835\udd4f","xopf;":"\ud835\udd69","xoplus;":"\u2a01","xotime;":"\u2a02","xrarr;":"\u27f6","xrArr;":"\u27f9","Xscr;":"\ud835\udcb3","xscr;":"\ud835\udccd","xsqcup;":"\u2a06","xuplus;":"\u2a04","xutri;":"\u25b3","xvee;":"\u22c1","xwedge;":"\u22c0","Yacute;":"\u00dd",Yacute:"\u00dd","yacute;":"\u00fd",yacute:"\u00fd","YAcy;":"\u042f","yacy;":"\u044f","Ycirc;":"\u0176","ycirc;":"\u0177","Ycy;":"\u042b","ycy;":"\u044b","yen;":"\u00a5",yen:"\u00a5","Yfr;":"\ud835\udd1c","yfr;":"\ud835\udd36","YIcy;":"\u0407","yicy;":"\u0457","Yopf;":"\ud835\udd50","yopf;":"\ud835\udd6a","Yscr;":"\ud835\udcb4","yscr;":"\ud835\udcce","YUcy;":"\u042e","yucy;":"\u044e","yuml;":"\u00ff",yuml:"\u00ff","Yuml;":"\u0178","Zacute;":"\u0179","zacute;":"\u017a","Zcaron;":"\u017d","zcaron;":"\u017e","Zcy;":"\u0417","zcy;":"\u0437","Zdot;":"\u017b","zdot;":"\u017c","zeetrf;":"\u2128","ZeroWidthSpace;":"\u200b","Zeta;":"\u0396","zeta;":"\u03b6","zfr;":"\ud835\udd37","Zfr;":"\u2128","ZHcy;":"\u0416","zhcy;":"\u0436","zigrarr;":"\u21dd","zopf;":"\ud835\udd6b","Zopf;":"\u2124","Zscr;":"\ud835\udcb5","zscr;":"\ud835\udccf","zwj;":"\u200d","zwnj;":"\u200c"}},{}],13:[function(e,t,n){function u(e,t){return r.isUndefined(t)?""+t:r.isNumber(t)&&(isNaN(t)||!isFinite(t))?t.toString():r.isFunction(t)||r.isRegExp(t)?t.toString():t}function a(e,t){return r.isString(e)?e.length=0;u--)if(n[u]!=s[u])return!1;for(u=n.length-1;u>=0;u--){o=n[u];if(!h(e[o],t[o]))return!1}return!0}function v(e,t){return!e||!t?!1:Object.prototype.toString.call(t)=="[object RegExp]"?t.test(e):e instanceof t?!0:t.call({},e)===!0?!0:!1}function m(e,t,n,i){var s;r.isString(n)&&(i=n,n=null);try{t()}catch(o){s=o}i=(n&&n.name?" ("+n.name+").":".")+(i?" "+i:"."),e&&!s&&l(s,n,"Missing expected exception"+i),!e&&v(s,n)&&l(s,n,"Got unwanted exception"+i);if(e&&s&&n&&!v(s,n)||!e&&s)throw s}var r=e("util/"),i=Array.prototype.slice,s=Object.prototype.hasOwnProperty,o=t.exports=c;o.AssertionError=function(t){this.name="AssertionError",this.actual=t.actual,this.expected=t.expected,this.operator=t.operator,t.message?(this.message=t.message,this.generatedMessage=!1):(this.message=f(this),this.generatedMessage=!0);var n=t.stackStartFunction||l;if(Error.captureStackTrace)Error.captureStackTrace(this,n);else{var r=new Error;if(r.stack){var i=r.stack,s=n.name,o=i.indexOf("\n"+s);if(o>=0){var u=i.indexOf("\n",o+1);i=i.substring(u+1)}this.stack=i}}},r.inherits(o.AssertionError,Error),o.fail=l,o.ok=c,o.equal=function(t,n,r){t!=n&&l(t,n,r,"==",o.equal)},o.notEqual=function(t,n,r){t==n&&l(t,n,r,"!=",o.notEqual)},o.deepEqual=function(t,n,r){h(t,n)||l(t,n,r,"deepEqual",o.deepEqual)},o.notDeepEqual=function(t,n,r){h(t,n)&&l(t,n,r,"notDeepEqual",o.notDeepEqual)},o.strictEqual=function(t,n,r){t!==n&&l(t,n,r,"===",o.strictEqual)},o.notStrictEqual=function(t,n,r){t===n&&l(t,n,r,"!==",o.notStrictEqual)},o.throws=function(e,t,n){m.apply(this,[!0].concat(i.call(arguments)))},o.doesNotThrow=function(e,t){m.apply(this,[!1].concat(i.call(arguments)))},o.ifError=function(e){if(e)throw e};var g=Object.keys||function(e){var t=[];for(var n in e)s.call(e,n)&&t.push(n);return t}},{"util/":15}],14:[function(e,t,n){t.exports=function(t){return t&&typeof t=="object"&&typeof t.copy=="function"&&typeof t.fill=="function"&&typeof t.readUInt8=="function"}},{}],15:[function(e,t,n){(function(t,r){function u(e,t){var r={seen:[],stylize:f};return arguments.length>=3&&(r.depth=arguments[2]),arguments.length>=4&&(r.colors=arguments[3]),y(t)?r.showHidden=t:t&&n._extend(r,t),T(r.showHidden)&&(r.showHidden=!1),T(r.depth)&&(r.depth=2),T(r.colors)&&(r.colors=!1),T(r.customInspect)&&(r.customInspect=!0),r.colors&&(r.stylize=a),c(r,e,r.depth)}function a(e,t){var n=u.styles[t];return n?"["+u.colors[n][0]+"m"+e+"["+u.colors[n][1]+"m":e}function f(e,t){return e}function l(e){var t={};return e.forEach(function(e,n){t[e]=!0}),t}function c(e,t,r){if(e.customInspect&&t&&A(t.inspect)&&t.inspect!==n.inspect&&(!t.constructor||t.constructor.prototype!==t)){var i=t.inspect(r,e);return S(i)||(i=c(e,i,r)),i}var s=h(e,t);if(s)return s;var o=Object.keys(t),u=l(o);e.showHidden&&(o=Object.getOwnPropertyNames(t));if(L(t)&&(o.indexOf("message")>=0||o.indexOf("description")>=0))return p(t);if(o.length===0){if(A(t)){var a=t.name?": "+t.name:"";return e.stylize("[Function"+a+"]","special")}if(N(t))return e.stylize(RegExp.prototype.toString.call(t),"regexp");if(k(t))return e.stylize(Date.prototype.toString.call(t),"date");if(L(t))return p(t)}var f="",y=!1,b=["{","}"];g(t)&&(y=!0,b=["[","]"]);if(A(t)){var w=t.name?": "+t.name:"";f=" [Function"+w+"]"}N(t)&&(f=" "+RegExp.prototype.toString.call(t)),k(t)&&(f=" "+Date.prototype.toUTCString.call(t)),L(t)&&(f=" "+p(t));if(o.length!==0||!!y&&t.length!=0){if(r<0)return N(t)?e.stylize(RegExp.prototype.toString.call(t),"regexp"):e.stylize("[Object]","special");e.seen.push(t);var E;return y?E=d(e,t,r,u,o):E=o.map(function(n){return v(e,t,r,u,n,y)}),e.seen.pop(),m(E,f,b)}return b[0]+f+b[1]}function h(e,t){if(T(t))return e.stylize("undefined","undefined");if(S(t)){var n="'"+JSON.stringify(t).replace(/^"|"$/g,"").replace(/'/g,"\\'").replace(/\\"/g,'"')+"'";return e.stylize(n,"string")}if(E(t))return e.stylize(""+t,"number");if(y(t))return e.stylize(""+t,"boolean");if(b(t))return e.stylize("null","null")}function p(e){return"["+Error.prototype.toString.call(e)+"]"}function d(e,t,n,r,i){var s=[];for(var o=0,u=t.length;o-1&&(s?u=u.split("\n").map(function(e){return" "+e}).join("\n").substr(2):u="\n"+u.split("\n").map(function(e){return" "+e}).join("\n"))):u=e.stylize("[Circular]","special"));if(T(o)){if(s&&i.match(/^\d+$/))return u;o=JSON.stringify(""+i),o.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)?(o=o.substr(1,o.length-2),o=e.stylize(o,"name")):(o=o.replace(/'/g,"\\'").replace(/\\"/g,'"').replace(/(^"|"$)/g,"'"),o=e.stylize(o,"string"))}return o+": "+u}function m(e,t,n){var r=0,i=e.reduce(function(e,t){return r++,t.indexOf("\n")>=0&&r++,e+t.replace(/\u001b\[\d\d?m/g,"").length+1},0);return i>60?n[0]+(t===""?"":t+"\n ")+" "+e.join(",\n ")+" "+n[1]:n[0]+t+" "+e.join(", ")+" "+n[1]}function g(e){return Array.isArray(e)}function y(e){return typeof e=="boolean"}function b(e){return e===null}function w(e){return e==null}function E(e){return typeof e=="number"}function S(e){return typeof e=="string"}function x(e){return typeof e=="symbol"}function T(e){return e===void 0}function N(e){return C(e)&&M(e)==="[object RegExp]"}function C(e){return typeof e=="object"&&e!==null}function k(e){return C(e)&&M(e)==="[object Date]"}function L(e){return C(e)&&(M(e)==="[object Error]"||e instanceof Error)}function A(e){return typeof e=="function"}function O(e){return e===null||typeof e=="boolean"||typeof e=="number"||typeof e=="string"||typeof e=="symbol"||typeof e=="undefined"}function M(e){return Object.prototype.toString.call(e)}function _(e){return e<10?"0"+e.toString(10):e.toString(10)}function P(){var e=new Date,t=[_(e.getHours()),_(e.getMinutes()),_(e.getSeconds())].join(":");return[e.getDate(),D[e.getMonth()],t].join(" ")}function H(e,t){return Object.prototype.hasOwnProperty.call(e,t)}var i=/%[sdj%]/g;n.format=function(e){if(!S(e)){var t=[];for(var n=0;n=s)return e;switch(e){case"%s":return String(r[n++]);case"%d":return Number(r[n++]);case"%j":try{return JSON.stringify(r[n++])}catch(t){return"[Circular]"};default:return e}});for(var a=r[n];n0&&this._events[e].length>n&&(this._events[e].warned=!0,console.error("(node) warning: possible EventEmitter memory leak detected. %d listeners added. Use emitter.setMaxListeners() to increase limit.",this._events[e].length),console.trace())}return this},r.prototype.on=r.prototype.addListener,r.prototype.once=function(e,t){function r(){this.removeListener(e,r),n||(n=!0,t.apply(this,arguments))}if(!i(t))throw TypeError("listener must be a function");var n=!1;return r.listener=t,this.on(e,r),this},r.prototype.removeListener=function(e,t){var n,r,s,u;if(!i(t))throw TypeError("listener must be a function");if(!this._events||!this._events[e])return this;n=this._events[e],s=n.length,r=-1;if(n===t||i(n.listener)&&n.listener===t)delete this._events[e],this._events.removeListener&&this.emit("removeListener",e,t);else if(o(n)){for(u=s;u-->0;)if(n[u]===t||n[u].listener&&n[u].listener===t){r=u;break}if(r<0)return this;n.length===1?(n.length=0,delete this._events[e]):n.splice(r,1),this._events.removeListener&&this.emit("removeListener",e,t)}return this},r.prototype.removeAllListeners=function(e){var t,n;if(!this._events)return this;if(!this._events.removeListener)return arguments.length===0?this._events={}:this._events[e]&&delete this._events[e],this;if(arguments.length===0){for(t in this._events){if(t==="removeListener")continue;this.removeAllListeners(t)}return this.removeAllListeners("removeListener"),this._events={},this}n=this._events[e];if(i(n))this.removeListener(e,n);else while(n.length)this.removeListener(e,n[n.length-1]);return delete this._events[e],this},r.prototype.listeners=function(e){var t;return!this._events||!this._events[e]?t=[]:i(this._events[e])?t=[this._events[e]]:t=this._events[e].slice(),t},r.listenerCount=function(e,t){var n;return!e._events||!e._events[t]?n=0:i(e._events[t])?n=1:n=e._events[t].length,n}},{}],17:[function(e,t,n){typeof Object.create=="function"?t.exports=function(t,n){t.super_=n,t.prototype=Object.create(n.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}})}:t.exports=function(t,n){t.super_=n;var r=function(){};r.prototype=n.prototype,t.prototype=new r,t.prototype.constructor=t}},{}],18:[function(e,t,n){function i(){}var r=t.exports={};r.nextTick=function(){var e=typeof window!="undefined"&&window.setImmediate,t=typeof window!="undefined"&&window.postMessage&&window.addEventListener;if(e)return function(e){return window.setImmediate(e)};if(t){var n=[];return window.addEventListener("message",function(e){var t=e.source;if((t===window||t===null)&&e.data==="process-tick"){e.stopPropagation();if(n.length>0){var r=n.shift();r()}}},!0),function(t){n.push(t),window.postMessage("process-tick","*")}}return function(t){setTimeout(t,0)}}(),r.title="browser",r.browser=!0,r.env={},r.argv=[],r.on=i,r.once=i,r.off=i,r.emit=i,r.binding=function(e){throw new Error("process.binding is not supported")},r.cwd=function(){return"/"},r.chdir=function(e){throw new Error("process.chdir is not supported")}},{}],19:[function(e,t,n){t.exports=e(14)},{}],20:[function(e,t,n){t.exports=e(15)},{"./support/isBuffer":19,"/usr/local/lib/node_modules/browserify/node_modules/insert-module-globals/node_modules/process/browser.js":18,inherits:17}]},{},[9])(9)}),define("ace/mode/html_worker",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/worker/mirror","ace/mode/html/saxparser"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("../worker/mirror").Mirror,o=e("./html/saxparser").SAXParser,u={"expected-doctype-but-got-start-tag":"info","expected-doctype-but-got-chars":"info","non-html-root":"info"},a=t.Worker=function(e){s.call(this,e),this.setTimeout(400),this.context=null};r.inherits(a,s),function(){this.setOptions=function(e){this.context=e.context},this.onUpdate=function(){var e=this.doc.getValue();if(!e)return;var t=new o,n=[],r=function(){};t.contentHandler={startDocument:r,endDocument:r,startElement:r,endElement:r,characters:r},t.errorHandler={error:function(e,t,r){n.push({row:t.line,column:t.column,text:e,type:u[r]||"error"})}},this.context?t.parseFragment(e,this.context):t.parse(e),this.sender.emit("error",n)}}.call(a.prototype)}),define("ace/lib/es5-shim",["require","exports","module"],function(e,t,n){function r(){}function w(e){try{return Object.defineProperty(e,"sentinel",{}),"sentinel"in e}catch(t){}}function H(e){return e=+e,e!==e?e=0:e!==0&&e!==1/0&&e!==-1/0&&(e=(e>0||-1)*Math.floor(Math.abs(e))),e}function B(e){var t=typeof e;return e===null||t==="undefined"||t==="boolean"||t==="number"||t==="string"}function j(e){var t,n,r;if(B(e))return e;n=e.valueOf;if(typeof n=="function"){t=n.call(e);if(B(t))return t}r=e.toString;if(typeof r=="function"){t=r.call(e);if(B(t))return t}throw new TypeError}Function.prototype.bind||(Function.prototype.bind=function(t){var n=this;if(typeof n!="function")throw new TypeError("Function.prototype.bind called on incompatible "+n);var i=u.call(arguments,1),s=function(){if(this instanceof s){var e=n.apply(this,i.concat(u.call(arguments)));return Object(e)===e?e:this}return n.apply(t,i.concat(u.call(arguments)))};return n.prototype&&(r.prototype=n.prototype,s.prototype=new r,r.prototype=null),s});var i=Function.prototype.call,s=Array.prototype,o=Object.prototype,u=s.slice,a=i.bind(o.toString),f=i.bind(o.hasOwnProperty),l,c,h,p,d;if(d=f(o,"__defineGetter__"))l=i.bind(o.__defineGetter__),c=i.bind(o.__defineSetter__),h=i.bind(o.__lookupGetter__),p=i.bind(o.__lookupSetter__);if([1,2].splice(0).length!=2)if(!function(){function e(e){var t=new Array(e+2);return t[0]=t[1]=0,t}var t=[],n;t.splice.apply(t,e(20)),t.splice.apply(t,e(26)),n=t.length,t.splice(5,0,"XXX"),n+1==t.length;if(n+1==t.length)return!0}())Array.prototype.splice=function(e,t){var n=this.length;e>0?e>n&&(e=n):e==void 0?e=0:e<0&&(e=Math.max(n+e,0)),e+ta)for(h=l;h--;)this[f+h]=this[a+h];if(s&&e===c)this.length=c,this.push.apply(this,i);else{this.length=c+s;for(h=0;h>>0;if(a(t)!="[object Function]")throw new TypeError;while(++s>>0,s=Array(i),o=arguments[1];if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");for(var u=0;u>>0,s=[],o,u=arguments[1];if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");for(var f=0;f>>0,s=arguments[1];if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");for(var o=0;o>>0,s=arguments[1];if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");for(var o=0;o>>0;if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");if(!i&&arguments.length==1)throw new TypeError("reduce of empty array with no initial value");var s=0,o;if(arguments.length>=2)o=arguments[1];else do{if(s in r){o=r[s++];break}if(++s>=i)throw new TypeError("reduce of empty array with no initial value")}while(!0);for(;s>>0;if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");if(!i&&arguments.length==1)throw new TypeError("reduceRight of empty array with no initial value");var s,o=i-1;if(arguments.length>=2)s=arguments[1];else do{if(o in r){s=r[o--];break}if(--o<0)throw new TypeError("reduceRight of empty array with no initial value")}while(!0);do o in this&&(s=t.call(void 0,s,r[o],o,n));while(o--);return s});if(!Array.prototype.indexOf||[0,1].indexOf(1,2)!=-1)Array.prototype.indexOf=function(t){var n=g&&a(this)=="[object String]"?this.split(""):F(this),r=n.length>>>0;if(!r)return-1;var i=0;arguments.length>1&&(i=H(arguments[1])),i=i>=0?i:Math.max(0,r+i);for(;i>>0;if(!r)return-1;var i=r-1;arguments.length>1&&(i=Math.min(i,H(arguments[1]))),i=i>=0?i:r-Math.abs(i);for(;i>=0;i--)if(i in n&&t===n[i])return i;return-1};Object.getPrototypeOf||(Object.getPrototypeOf=function(t){return t.__proto__||(t.constructor?t.constructor.prototype:o)});if(!Object.getOwnPropertyDescriptor){var y="Object.getOwnPropertyDescriptor called on a non-object: ";Object.getOwnPropertyDescriptor=function(t,n){if(typeof t!="object"&&typeof t!="function"||t===null)throw new TypeError(y+t);if(!f(t,n))return;var r,i,s;r={enumerable:!0,configurable:!0};if(d){var u=t.__proto__;t.__proto__=o;var i=h(t,n),s=p(t,n);t.__proto__=u;if(i||s)return i&&(r.get=i),s&&(r.set=s),r}return r.value=t[n],r}}Object.getOwnPropertyNames||(Object.getOwnPropertyNames=function(t){return Object.keys(t)});if(!Object.create){var b;Object.prototype.__proto__===null?b=function(){return{__proto__:null}}:b=function(){var e={};for(var t in e)e[t]=null;return e.constructor=e.hasOwnProperty=e.propertyIsEnumerable=e.isPrototypeOf=e.toLocaleString=e.toString=e.valueOf=e.__proto__=null,e},Object.create=function(t,n){var r;if(t===null)r=b();else{if(typeof t!="object")throw new TypeError("typeof prototype["+typeof t+"] != 'object'");var i=function(){};i.prototype=t,r=new i,r.__proto__=t}return n!==void 0&&Object.defineProperties(r,n),r}}if(Object.defineProperty){var E=w({}),S=typeof document=="undefined"||w(document.createElement("div"));if(!E||!S)var x=Object.defineProperty}if(!Object.defineProperty||x){var T="Property description must be an object: ",N="Object.defineProperty called on non-object: ",C="getters & setters can not be defined on this javascript engine";Object.defineProperty=function(t,n,r){if(typeof t!="object"&&typeof t!="function"||t===null)throw new TypeError(N+t);if(typeof r!="object"&&typeof r!="function"||r===null)throw new TypeError(T+r);if(x)try{return x.call(Object,t,n,r)}catch(i){}if(f(r,"value"))if(d&&(h(t,n)||p(t,n))){var s=t.__proto__;t.__proto__=o,delete t[n],t[n]=r.value,t.__proto__=s}else t[n]=r.value;else{if(!d)throw new TypeError(C);f(r,"get")&&l(t,n,r.get),f(r,"set")&&c(t,n,r.set)}return t}}Object.defineProperties||(Object.defineProperties=function(t,n){for(var r in n)f(n,r)&&Object.defineProperty(t,r,n[r]);return t}),Object.seal||(Object.seal=function(t){return t}),Object.freeze||(Object.freeze=function(t){return t});try{Object.freeze(function(){})}catch(k){Object.freeze=function(t){return function(n){return typeof n=="function"?n:t(n)}}(Object.freeze)}Object.preventExtensions||(Object.preventExtensions=function(t){return t}),Object.isSealed||(Object.isSealed=function(t){return!1}),Object.isFrozen||(Object.isFrozen=function(t){return!1}),Object.isExtensible||(Object.isExtensible=function(t){if(Object(t)===t)throw new TypeError;var n="";while(f(t,n))n+="?";t[n]=!0;var r=f(t,n);return delete t[n],r});if(!Object.keys){var L=!0,A=["toString","toLocaleString","valueOf","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","constructor"],O=A.length;for(var M in{toString:null})L=!1;Object.keys=function I(e){if(typeof e!="object"&&typeof e!="function"||e===null)throw new TypeError("Object.keys called on a non-object");var I=[];for(var t in e)f(e,t)&&I.push(t);if(L)for(var n=0,r=O;n1&&u(t,"")>-1&&(a=RegExp(this.source,r.replace.call(o(this),"g","")),r.replace.call(e.slice(t.index),a,function(){for(var e=1;et.index&&this.lastIndex--}return t},s||(RegExp.prototype.test=function(e){var t=r.exec.call(this,e);return t&&this.global&&!t[0].length&&this.lastIndex>t.index&&this.lastIndex--,!!t})}),define("ace/lib/es5-shim",["require","exports","module"],function(e,t,n){function r(){}function w(e){try{return Object.defineProperty(e,"sentinel",{}),"sentinel"in e}catch(t){}}function H(e){return e=+e,e!==e?e=0:e!==0&&e!==1/0&&e!==-1/0&&(e=(e>0||-1)*Math.floor(Math.abs(e))),e}function B(e){var t=typeof e;return e===null||t==="undefined"||t==="boolean"||t==="number"||t==="string"}function j(e){var t,n,r;if(B(e))return e;n=e.valueOf;if(typeof n=="function"){t=n.call(e);if(B(t))return t}r=e.toString;if(typeof r=="function"){t=r.call(e);if(B(t))return t}throw new TypeError}Function.prototype.bind||(Function.prototype.bind=function(t){var n=this;if(typeof n!="function")throw new TypeError("Function.prototype.bind called on incompatible "+n);var i=u.call(arguments,1),s=function(){if(this instanceof s){var e=n.apply(this,i.concat(u.call(arguments)));return Object(e)===e?e:this}return n.apply(t,i.concat(u.call(arguments)))};return n.prototype&&(r.prototype=n.prototype,s.prototype=new r,r.prototype=null),s});var i=Function.prototype.call,s=Array.prototype,o=Object.prototype,u=s.slice,a=i.bind(o.toString),f=i.bind(o.hasOwnProperty),l,c,h,p,d;if(d=f(o,"__defineGetter__"))l=i.bind(o.__defineGetter__),c=i.bind(o.__defineSetter__),h=i.bind(o.__lookupGetter__),p=i.bind(o.__lookupSetter__);if([1,2].splice(0).length!=2)if(!function(){function e(e){var t=new Array(e+2);return t[0]=t[1]=0,t}var t=[],n;t.splice.apply(t,e(20)),t.splice.apply(t,e(26)),n=t.length,t.splice(5,0,"XXX"),n+1==t.length;if(n+1==t.length)return!0}())Array.prototype.splice=function(e,t){var n=this.length;e>0?e>n&&(e=n):e==void 0?e=0:e<0&&(e=Math.max(n+e,0)),e+ta)for(h=l;h--;)this[f+h]=this[a+h];if(s&&e===c)this.length=c,this.push.apply(this,i);else{this.length=c+s;for(h=0;h>>0;if(a(t)!="[object Function]")throw new TypeError;while(++s>>0,s=Array(i),o=arguments[1];if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");for(var u=0;u>>0,s=[],o,u=arguments[1];if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");for(var f=0;f>>0,s=arguments[1];if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");for(var o=0;o>>0,s=arguments[1];if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");for(var o=0;o>>0;if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");if(!i&&arguments.length==1)throw new TypeError("reduce of empty array with no initial value");var s=0,o;if(arguments.length>=2)o=arguments[1];else do{if(s in r){o=r[s++];break}if(++s>=i)throw new TypeError("reduce of empty array with no initial value")}while(!0);for(;s>>0;if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");if(!i&&arguments.length==1)throw new TypeError("reduceRight of empty array with no initial value");var s,o=i-1;if(arguments.length>=2)s=arguments[1];else do{if(o in r){s=r[o--];break}if(--o<0)throw new TypeError("reduceRight of empty array with no initial value")}while(!0);do o in this&&(s=t.call(void 0,s,r[o],o,n));while(o--);return s});if(!Array.prototype.indexOf||[0,1].indexOf(1,2)!=-1)Array.prototype.indexOf=function(t){var n=g&&a(this)=="[object String]"?this.split(""):F(this),r=n.length>>>0;if(!r)return-1;var i=0;arguments.length>1&&(i=H(arguments[1])),i=i>=0?i:Math.max(0,r+i);for(;i>>0;if(!r)return-1;var i=r-1;arguments.length>1&&(i=Math.min(i,H(arguments[1]))),i=i>=0?i:r-Math.abs(i);for(;i>=0;i--)if(i in n&&t===n[i])return i;return-1};Object.getPrototypeOf||(Object.getPrototypeOf=function(t){return t.__proto__||(t.constructor?t.constructor.prototype:o)});if(!Object.getOwnPropertyDescriptor){var y="Object.getOwnPropertyDescriptor called on a non-object: ";Object.getOwnPropertyDescriptor=function(t,n){if(typeof t!="object"&&typeof t!="function"||t===null)throw new TypeError(y+t);if(!f(t,n))return;var r,i,s;r={enumerable:!0,configurable:!0};if(d){var u=t.__proto__;t.__proto__=o;var i=h(t,n),s=p(t,n);t.__proto__=u;if(i||s)return i&&(r.get=i),s&&(r.set=s),r}return r.value=t[n],r}}Object.getOwnPropertyNames||(Object.getOwnPropertyNames=function(t){return Object.keys(t)});if(!Object.create){var b;Object.prototype.__proto__===null?b=function(){return{__proto__:null}}:b=function(){var e={};for(var t in e)e[t]=null;return e.constructor=e.hasOwnProperty=e.propertyIsEnumerable=e.isPrototypeOf=e.toLocaleString=e.toString=e.valueOf=e.__proto__=null,e},Object.create=function(t,n){var r;if(t===null)r=b();else{if(typeof t!="object")throw new TypeError("typeof prototype["+typeof t+"] != 'object'");var i=function(){};i.prototype=t,r=new i,r.__proto__=t}return n!==void 0&&Object.defineProperties(r,n),r}}if(Object.defineProperty){var E=w({}),S=typeof document=="undefined"||w(document.createElement("div"));if(!E||!S)var x=Object.defineProperty}if(!Object.defineProperty||x){var T="Property description must be an object: ",N="Object.defineProperty called on non-object: ",C="getters & setters can not be defined on this javascript engine";Object.defineProperty=function(t,n,r){if(typeof t!="object"&&typeof t!="function"||t===null)throw new TypeError(N+t);if(typeof r!="object"&&typeof r!="function"||r===null)throw new TypeError(T+r);if(x)try{return x.call(Object,t,n,r)}catch(i){}if(f(r,"value"))if(d&&(h(t,n)||p(t,n))){var s=t.__proto__;t.__proto__=o,delete t[n],t[n]=r.value,t.__proto__=s}else t[n]=r.value;else{if(!d)throw new TypeError(C);f(r,"get")&&l(t,n,r.get),f(r,"set")&&c(t,n,r.set)}return t}}Object.defineProperties||(Object.defineProperties=function(t,n){for(var r in n)f(n,r)&&Object.defineProperty(t,r,n[r]);return t}),Object.seal||(Object.seal=function(t){return t}),Object.freeze||(Object.freeze=function(t){return t});try{Object.freeze(function(){})}catch(k){Object.freeze=function(t){return function(n){return typeof n=="function"?n:t(n)}}(Object.freeze)}Object.preventExtensions||(Object.preventExtensions=function(t){return t}),Object.isSealed||(Object.isSealed=function(t){return!1}),Object.isFrozen||(Object.isFrozen=function(t){return!1}),Object.isExtensible||(Object.isExtensible=function(t){if(Object(t)===t)throw new TypeError;var n="";while(f(t,n))n+="?";t[n]=!0;var r=f(t,n);return delete t[n],r});if(!Object.keys){var L=!0,A=["toString","toLocaleString","valueOf","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","constructor"],O=A.length;for(var M in{toString:null})L=!1;Object.keys=function I(e){if(typeof e!="object"&&typeof e!="function"||e===null)throw new TypeError("Object.keys called on a non-object");var I=[];for(var t in e)f(e,t)&&I.push(t);if(L)for(var n=0,r=O;n=0?parseFloat((i.match(/(?:MSIE |Trident\/[0-9]+[\.0-9]+;.*rv:)([0-9]+[\.0-9]+)/)||[])[1]):parseFloat((i.match(/(?:Trident\/[0-9]+[\.0-9]+;.*rv:)([0-9]+[\.0-9]+)/)||[])[1]),t.isOldIE=t.isIE&&t.isIE<9,t.isGecko=t.isMozilla=(window.Controllers||window.controllers)&&window.navigator.product==="Gecko",t.isOldGecko=t.isGecko&&parseInt((i.match(/rv:(\d+)/)||[])[1],10)<4,t.isOpera=window.opera&&Object.prototype.toString.call(window.opera)=="[object Opera]",t.isWebKit=parseFloat(i.split("WebKit/")[1])||undefined,t.isChrome=parseFloat(i.split(" Chrome/")[1])||undefined,t.isAIR=i.indexOf("AdobeAIR")>=0,t.isIPad=i.indexOf("iPad")>=0,t.isTouchPad=i.indexOf("TouchPad")>=0,t.isChromeOS=i.indexOf(" CrOS ")>=0}),define("ace/lib/event",["require","exports","module","ace/lib/keys","ace/lib/useragent"],function(e,t,n){"use strict";function a(e,t,n){var a=u(t);if(!i.isMac&&s){t.getModifierState&&(t.getModifierState("OS")||t.getModifierState("Win"))&&(a|=8);if(s.altGr){if((3&a)==3)return;s.altGr=0}if(n===18||n===17){var f="location"in t?t.location:t.keyLocation;if(n===17&&f===1)s[n]==1&&(o=t.timeStamp);else if(n===18&&a===3&&f===2){var l=t.timeStamp-o;l<50&&(s.altGr=!0)}}}n in r.MODIFIER_KEYS&&(n=-1),a&8&&n>=91&&n<=93&&(n=-1);if(!a&&n===13){var f="location"in t?t.location:t.keyLocation;if(f===3){e(t,a,-n);if(t.defaultPrevented)return}}if(i.isChromeOS&&a&8){e(t,a,n);if(t.defaultPrevented)return;a&=-9}return!!a||n in r.FUNCTION_KEYS||n in r.PRINTABLE_KEYS?e(t,a,n):!1}function f(){s=Object.create(null)}var r=e("./keys"),i=e("./useragent"),s=null,o=0;t.addListener=function(e,t,n){if(e.addEventListener)return e.addEventListener(t,n,!1);if(e.attachEvent){var r=function(){n.call(e,window.event)};n._wrapper=r,e.attachEvent("on"+t,r)}},t.removeListener=function(e,t,n){if(e.removeEventListener)return e.removeEventListener(t,n,!1);e.detachEvent&&e.detachEvent("on"+t,n._wrapper||n)},t.stopEvent=function(e){return t.stopPropagation(e),t.preventDefault(e),!1},t.stopPropagation=function(e){e.stopPropagation?e.stopPropagation():e.cancelBubble=!0},t.preventDefault=function(e){e.preventDefault?e.preventDefault():e.returnValue=!1},t.getButton=function(e){return e.type=="dblclick"?0:e.type=="contextmenu"||i.isMac&&e.ctrlKey&&!e.altKey&&!e.shiftKey?2:e.preventDefault?e.button:{1:0,2:2,4:1}[e.button]},t.capture=function(e,n,r){function i(e){n&&n(e),r&&r(e),t.removeListener(document,"mousemove",n,!0),t.removeListener(document,"mouseup",i,!0),t.removeListener(document,"dragstart",i,!0)}return t.addListener(document,"mousemove",n,!0),t.addListener(document,"mouseup",i,!0),t.addListener(document,"dragstart",i,!0),i},t.addTouchMoveListener=function(e,n){if("ontouchmove"in e){var r,i;t.addListener(e,"touchstart",function(e){var t=e.changedTouches[0];r=t.clientX,i=t.clientY}),t.addListener(e,"touchmove",function(e){var t=1,s=e.changedTouches[0];e.wheelX=-(s.clientX-r)/t,e.wheelY=-(s.clientY-i)/t,r=s.clientX,i=s.clientY,n(e)})}},t.addMouseWheelListener=function(e,n){"onmousewheel"in e?t.addListener(e,"mousewheel",function(e){var t=8;e.wheelDeltaX!==undefined?(e.wheelX=-e.wheelDeltaX/t,e.wheelY=-e.wheelDeltaY/t):(e.wheelX=0,e.wheelY=-e.wheelDelta/t),n(e)}):"onwheel"in e?t.addListener(e,"wheel",function(e){var t=.35;switch(e.deltaMode){case e.DOM_DELTA_PIXEL:e.wheelX=e.deltaX*t||0,e.wheelY=e.deltaY*t||0;break;case e.DOM_DELTA_LINE:case e.DOM_DELTA_PAGE:e.wheelX=(e.deltaX||0)*5,e.wheelY=(e.deltaY||0)*5}n(e)}):t.addListener(e,"DOMMouseScroll",function(e){e.axis&&e.axis==e.HORIZONTAL_AXIS?(e.wheelX=(e.detail||0)*5,e.wheelY=0):(e.wheelX=0,e.wheelY=(e.detail||0)*5),n(e)})},t.addMultiMouseDownListener=function(e,n,r,s){function c(e){t.getButton(e)!==0?o=0:e.detail>1?(o++,o>4&&(o=1)):o=1;if(i.isIE){var c=Math.abs(e.clientX-u)>5||Math.abs(e.clientY-a)>5;if(!f||c)o=1;f&&clearTimeout(f),f=setTimeout(function(){f=null},n[o-1]||600),o==1&&(u=e.clientX,a=e.clientY)}e._clicks=o,r[s]("mousedown",e);if(o>4)o=0;else if(o>1)return r[s](l[o],e)}function h(e){o=2,f&&clearTimeout(f),f=setTimeout(function(){f=null},n[o-1]||600),r[s]("mousedown",e),r[s](l[o],e)}var o=0,u,a,f,l={2:"dblclick",3:"tripleclick",4:"quadclick"};Array.isArray(e)||(e=[e]),e.forEach(function(e){t.addListener(e,"mousedown",c),i.isOldIE&&t.addListener(e,"dblclick",h)})};var u=!i.isMac||!i.isOpera||"KeyboardEvent"in window?function(e){return 0|(e.ctrlKey?1:0)|(e.altKey?2:0)|(e.shiftKey?4:0)|(e.metaKey?8:0)}:function(e){return 0|(e.metaKey?1:0)|(e.altKey?2:0)|(e.shiftKey?4:0)|(e.ctrlKey?8:0)};t.getModifierString=function(e){return r.KEY_MODS[u(e)]},t.addCommandKeyListener=function(e,n){var r=t.addListener;if(i.isOldGecko||i.isOpera&&!("KeyboardEvent"in window)){var o=null;r(e,"keydown",function(e){o=e.keyCode}),r(e,"keypress",function(e){return a(n,e,o)})}else{var u=null;r(e,"keydown",function(e){s[e.keyCode]=(s[e.keyCode]||0)+1;var t=a(n,e,e.keyCode);return u=e.defaultPrevented,t}),r(e,"keypress",function(e){u&&(e.ctrlKey||e.altKey||e.shiftKey||e.metaKey)&&(t.stopEvent(e),u=null)}),r(e,"keyup",function(e){s[e.keyCode]=null}),s||(f(),r(window,"focus",f))}};if(typeof window=="object"&&window.postMessage&&!i.isOldIE){var l=1;t.nextTick=function(e,n){n=n||window;var r="zero-timeout-message-"+l;t.addListener(n,"message",function i(s){s.data==r&&(t.stopPropagation(s),t.removeListener(n,"message",i),e())}),n.postMessage(r,"*")}}t.nextFrame=typeof window=="object"&&(window.requestAnimationFrame||window.mozRequestAnimationFrame||window.webkitRequestAnimationFrame||window.msRequestAnimationFrame||window.oRequestAnimationFrame),t.nextFrame?t.nextFrame=t.nextFrame.bind(window):t.nextFrame=function(e){setTimeout(e,17)}}),define("ace/lib/lang",["require","exports","module"],function(e,t,n){"use strict";t.last=function(e){return e[e.length-1]},t.stringReverse=function(e){return e.split("").reverse().join("")},t.stringRepeat=function(e,t){var n="";while(t>0){t&1&&(n+=e);if(t>>=1)e+=e}return n};var r=/^\s\s*/,i=/\s\s*$/;t.stringTrimLeft=function(e){return e.replace(r,"")},t.stringTrimRight=function(e){return e.replace(i,"")},t.copyObject=function(e){var t={};for(var n in e)t[n]=e[n];return t},t.copyArray=function(e){var t=[];for(var n=0,r=e.length;n=53&&O()},I=o.delayedCall(j,50);r.addListener(n,"compositionstart",B),i.isGecko?r.addListener(n,"text",function(){I.schedule()}):(r.addListener(n,"keyup",function(){I.schedule()}),r.addListener(n,"keydown",function(){I.schedule()})),r.addListener(n,"compositionend",F),this.getElement=function(){return n},this.setReadOnly=function(e){n.readOnly=e},this.onContextMenu=function(e){L=!0,b(t.selection.isEmpty()),t._emit("nativecontextmenu",{target:t,domEvent:e}),this.moveToMouse(e,!0)},this.moveToMouse=function(e,o){if(!o&&i.isOldIE)return;p||(p=n.style.cssText),n.style.cssText=(o?"z-index:100000;":"")+"height:"+n.style.height+";"+(i.isIE?"opacity:0.1;":"");var u=t.container.getBoundingClientRect(),a=s.computedStyle(t.container),f=u.top+(parseInt(a.borderTopWidth)||0),l=u.left+(parseInt(u.borderLeftWidth)||0),c=u.bottom-f-n.clientHeight-2,h=function(e){n.style.left=e.clientX-l-2+"px",n.style.top=Math.min(e.clientY-f-2,c)+"px"};h(e);if(e.type!="mousedown")return;t.renderer.$keepTextAreaAtCursor&&(t.renderer.$keepTextAreaAtCursor=null),clearTimeout(q),i.isWin&&!i.isOldIE&&r.capture(t.container,h,R)},this.onContextMenuClose=R;var q,U=function(e){t.textInput.onContextMenu(e),R()};r.addListener(n,"mouseup",U),r.addListener(n,"mousedown",function(e){e.preventDefault(),R()}),r.addListener(t.renderer.scroller,"contextmenu",U),r.addListener(n,"contextmenu",U)};t.TextInput=f}),define("ace/mouse/default_handlers",["require","exports","module","ace/lib/dom","ace/lib/event","ace/lib/useragent"],function(e,t,n){"use strict";function u(e){e.$clickSelection=null;var t=e.editor;t.setDefaultHandler("mousedown",this.onMouseDown.bind(e)),t.setDefaultHandler("dblclick",this.onDoubleClick.bind(e)),t.setDefaultHandler("tripleclick",this.onTripleClick.bind(e)),t.setDefaultHandler("quadclick",this.onQuadClick.bind(e)),t.setDefaultHandler("mousewheel",this.onMouseWheel.bind(e)),t.setDefaultHandler("touchmove",this.onTouchMove.bind(e));var n=["select","startSelect","selectEnd","selectAllEnd","selectByWordsEnd","selectByLinesEnd","dragWait","dragWaitEnd","focusWait"];n.forEach(function(t){e[t]=this[t]},this),e.selectByLines=this.extendSelectionBy.bind(e,"getLineRange"),e.selectByWords=this.extendSelectionBy.bind(e,"getWordRange")}function a(e,t,n,r){return Math.sqrt(Math.pow(n-e,2)+Math.pow(r-t,2))}function f(e,t){if(e.start.row==e.end.row)var n=2*t.column-e.start.column-e.end.column;else if(e.start.row==e.end.row-1&&!e.start.column&&!e.end.column)var n=t.column-4;else var n=2*t.row-e.start.row-e.end.row;return n<0?{cursor:e.start,anchor:e.end}:{cursor:e.end,anchor:e.start}}var r=e("../lib/dom"),i=e("../lib/event"),s=e("../lib/useragent"),o=0;(function(){this.onMouseDown=function(e){var t=e.inSelection(),n=e.getDocumentPosition();this.mousedownEvent=e;var r=this.editor,i=e.getButton();if(i!==0){var s=r.getSelectionRange(),o=s.isEmpty();r.$blockScrolling++,(o||i==1)&&r.selection.moveToPosition(n),r.$blockScrolling--,i==2&&r.textInput.onContextMenu(e.domEvent);return}this.mousedownEvent.time=Date.now();if(t&&!r.isFocused()){r.focus();if(this.$focusTimout&&!this.$clickSelection&&!r.inMultiSelectMode){this.setState("focusWait"),this.captureMouse(e);return}}return this.captureMouse(e),this.startSelect(n,e.domEvent._clicks>1),e.preventDefault()},this.startSelect=function(e,t){e=e||this.editor.renderer.screenToTextCoordinates(this.x,this.y);var n=this.editor;n.$blockScrolling++,this.mousedownEvent.getShiftKey()?n.selection.selectToPosition(e):t||n.selection.moveToPosition(e),t||this.select(),n.renderer.scroller.setCapture&&n.renderer.scroller.setCapture(),n.setStyle("ace_selecting"),this.setState("select"),n.$blockScrolling--},this.select=function(){var e,t=this.editor,n=t.renderer.screenToTextCoordinates(this.x,this.y);t.$blockScrolling++;if(this.$clickSelection){var r=this.$clickSelection.comparePoint(n);if(r==-1)e=this.$clickSelection.end;else if(r==1)e=this.$clickSelection.start;else{var i=f(this.$clickSelection,n);n=i.cursor,e=i.anchor}t.selection.setSelectionAnchor(e.row,e.column)}t.selection.selectToPosition(n),t.$blockScrolling--,t.renderer.scrollCursorIntoView()},this.extendSelectionBy=function(e){var t,n=this.editor,r=n.renderer.screenToTextCoordinates(this.x,this.y),i=n.selection[e](r.row,r.column);n.$blockScrolling++;if(this.$clickSelection){var s=this.$clickSelection.comparePoint(i.start),o=this.$clickSelection.comparePoint(i.end);if(s==-1&&o<=0){t=this.$clickSelection.end;if(i.end.row!=r.row||i.end.column!=r.column)r=i.start}else if(o==1&&s>=0){t=this.$clickSelection.start;if(i.start.row!=r.row||i.start.column!=r.column)r=i.end}else if(s==-1&&o==1)r=i.end,t=i.start;else{var u=f(this.$clickSelection,r);r=u.cursor,t=u.anchor}n.selection.setSelectionAnchor(t.row,t.column)}n.selection.selectToPosition(r),n.$blockScrolling--,n.renderer.scrollCursorIntoView()},this.selectEnd=this.selectAllEnd=this.selectByWordsEnd=this.selectByLinesEnd=function(){this.$clickSelection=null,this.editor.unsetStyle("ace_selecting"),this.editor.renderer.scroller.releaseCapture&&this.editor.renderer.scroller.releaseCapture()},this.focusWait=function(){var e=a(this.mousedownEvent.x,this.mousedownEvent.y,this.x,this.y),t=Date.now();(e>o||t-this.mousedownEvent.time>this.$focusTimout)&&this.startSelect(this.mousedownEvent.getDocumentPosition())},this.onDoubleClick=function(e){var t=e.getDocumentPosition(),n=this.editor,r=n.session,i=r.getBracketRange(t);i?(i.isEmpty()&&(i.start.column--,i.end.column++),this.setState("select")):(i=n.selection.getWordRange(t.row,t.column),this.setState("selectByWords")),this.$clickSelection=i,this.select()},this.onTripleClick=function(e){var t=e.getDocumentPosition(),n=this.editor;this.setState("selectByLines");var r=n.getSelectionRange();r.isMultiLine()&&r.contains(t.row,t.column)?(this.$clickSelection=n.selection.getLineRange(r.start.row),this.$clickSelection.end=n.selection.getLineRange(r.end.row).end):this.$clickSelection=n.selection.getLineRange(t.row),this.select()},this.onQuadClick=function(e){var t=this.editor;t.selectAll(),this.$clickSelection=t.getSelectionRange(),this.setState("selectAll")},this.onMouseWheel=function(e){if(e.getAccelKey())return;e.getShiftKey()&&e.wheelY&&!e.wheelX&&(e.wheelX=e.wheelY,e.wheelY=0);var t=e.domEvent.timeStamp,n=t-(this.$lastScrollTime||0),r=this.editor,i=r.renderer.isScrollableBy(e.wheelX*e.speed,e.wheelY*e.speed);if(i||n<200)return this.$lastScrollTime=t,r.renderer.scrollBy(e.wheelX*e.speed,e.wheelY*e.speed),e.stop()},this.onTouchMove=function(e){var t=e.domEvent.timeStamp,n=t-(this.$lastScrollTime||0),r=this.editor,i=r.renderer.isScrollableBy(e.wheelX*e.speed,e.wheelY*e.speed);if(i||n<200)return this.$lastScrollTime=t,r.renderer.scrollBy(e.wheelX*e.speed,e.wheelY*e.speed),e.stop()}}).call(u.prototype),t.DefaultHandlers=u}),define("ace/tooltip",["require","exports","module","ace/lib/oop","ace/lib/dom"],function(e,t,n){"use strict";function s(e){this.isOpen=!1,this.$element=null,this.$parentNode=e}var r=e("./lib/oop"),i=e("./lib/dom");(function(){this.$init=function(){return this.$element=i.createElement("div"),this.$element.className="ace_tooltip",this.$element.style.display="none",this.$parentNode.appendChild(this.$element),this.$element},this.getElement=function(){return this.$element||this.$init()},this.setText=function(e){i.setInnerText(this.getElement(),e)},this.setHtml=function(e){this.getElement().innerHTML=e},this.setPosition=function(e,t){this.getElement().style.left=e+"px",this.getElement().style.top=t+"px"},this.setClassName=function(e){i.addCssClass(this.getElement(),e)},this.show=function(e,t,n){e!=null&&this.setText(e),t!=null&&n!=null&&this.setPosition(t,n),this.isOpen||(this.getElement().style.display="block",this.isOpen=!0)},this.hide=function(){this.isOpen&&(this.getElement().style.display="none",this.isOpen=!1)},this.getHeight=function(){return this.getElement().offsetHeight},this.getWidth=function(){return this.getElement().offsetWidth}}).call(s.prototype),t.Tooltip=s}),define("ace/mouse/default_gutter_handler",["require","exports","module","ace/lib/dom","ace/lib/oop","ace/lib/event","ace/tooltip"],function(e,t,n){"use strict";function u(e){function l(){var r=u.getDocumentPosition().row,s=n.$annotations[r];if(!s)return c();var o=t.session.getLength();if(r==o){var a=t.renderer.pixelToScreenCoordinates(0,u.y).row,l=u.$pos;if(a>t.session.documentToScreenRow(l.row,l.column))return c()}if(f==s)return;f=s.text.join("
"),i.setHtml(f),i.show(),t._signal("showGutterTooltip",i),t.on("mousewheel",c);if(e.$tooltipFollowsMouse)h(u);else{var p=u.domEvent.target,d=p.getBoundingClientRect(),v=i.getElement().style;v.left=d.right+"px",v.top=d.bottom+"px"}}function c(){o&&(o=clearTimeout(o)),f&&(i.hide(),f=null,t._signal("hideGutterTooltip",i),t.removeEventListener("mousewheel",c))}function h(e){i.setPosition(e.x,e.y)}var t=e.editor,n=t.renderer.$gutterLayer,i=new a(t.container);e.editor.setDefaultHandler("guttermousedown",function(r){if(!t.isFocused()||r.getButton()!=0)return;var i=n.getRegion(r);if(i=="foldWidgets")return;var s=r.getDocumentPosition().row,o=t.session.selection;if(r.getShiftKey())o.selectTo(s,0);else{if(r.domEvent.detail==2)return t.selectAll(),r.preventDefault();e.$clickSelection=t.selection.getLineRange(s)}return e.setState("selectByLines"),e.captureMouse(r),r.preventDefault()});var o,u,f;e.editor.setDefaultHandler("guttermousemove",function(t){var n=t.domEvent.target||t.domEvent.srcElement;if(r.hasCssClass(n,"ace_fold-widget"))return c();f&&e.$tooltipFollowsMouse&&h(t),u=t;if(o)return;o=setTimeout(function(){o=null,u&&!e.isMousePressed?l():c()},50)}),s.addListener(t.renderer.$gutter,"mouseout",function(e){u=null;if(!f||o)return;o=setTimeout(function(){o=null,c()},50)}),t.on("changeSession",c)}function a(e){o.call(this,e)}var r=e("../lib/dom"),i=e("../lib/oop"),s=e("../lib/event"),o=e("../tooltip").Tooltip;i.inherits(a,o),function(){this.setPosition=function(e,t){var n=window.innerWidth||document.documentElement.clientWidth,r=window.innerHeight||document.documentElement.clientHeight,i=this.getWidth(),s=this.getHeight();e+=15,t+=15,e+i>n&&(e-=e+i-n),t+s>r&&(t-=20+s),o.prototype.setPosition.call(this,e,t)}}.call(a.prototype),t.GutterHandler=u}),define("ace/mouse/mouse_event",["require","exports","module","ace/lib/event","ace/lib/useragent"],function(e,t,n){"use strict";var r=e("../lib/event"),i=e("../lib/useragent"),s=t.MouseEvent=function(e,t){this.domEvent=e,this.editor=t,this.x=this.clientX=e.clientX,this.y=this.clientY=e.clientY,this.$pos=null,this.$inSelection=null,this.propagationStopped=!1,this.defaultPrevented=!1};(function(){this.stopPropagation=function(){r.stopPropagation(this.domEvent),this.propagationStopped=!0},this.preventDefault=function(){r.preventDefault(this.domEvent),this.defaultPrevented=!0},this.stop=function(){this.stopPropagation(),this.preventDefault()},this.getDocumentPosition=function(){return this.$pos?this.$pos:(this.$pos=this.editor.renderer.screenToTextCoordinates(this.clientX,this.clientY),this.$pos)},this.inSelection=function(){if(this.$inSelection!==null)return this.$inSelection;var e=this.editor,t=e.getSelectionRange();if(t.isEmpty())this.$inSelection=!1;else{var n=this.getDocumentPosition();this.$inSelection=t.contains(n.row,n.column)}return this.$inSelection},this.getButton=function(){return r.getButton(this.domEvent)},this.getShiftKey=function(){return this.domEvent.shiftKey},this.getAccelKey=i.isMac?function(){return this.domEvent.metaKey}:function(){return this.domEvent.ctrlKey}}).call(s.prototype)}),define("ace/mouse/dragdrop_handler",["require","exports","module","ace/lib/dom","ace/lib/event","ace/lib/useragent"],function(e,t,n){"use strict";function f(e){function T(e,n){var r=Date.now(),i=!n||e.row!=n.row,s=!n||e.column!=n.column;if(!S||i||s)t.$blockScrolling+=1,t.moveCursorToPosition(e),t.$blockScrolling-=1,S=r,x={x:p,y:d};else{var o=l(x.x,x.y,p,d);o>a?S=null:r-S>=u&&(t.renderer.scrollCursorIntoView(),S=null)}}function N(e,n){var r=Date.now(),i=t.renderer.layerConfig.lineHeight,s=t.renderer.layerConfig.characterWidth,u=t.renderer.scroller.getBoundingClientRect(),a={x:{left:p-u.left,right:u.right-p},y:{top:d-u.top,bottom:u.bottom-d}},f=Math.min(a.x.left,a.x.right),l=Math.min(a.y.top,a.y.bottom),c={row:e.row,column:e.column};f/s<=2&&(c.column+=a.x.left=o&&t.renderer.scrollCursorIntoView(c):E=r:E=null}function C(){var e=g;g=t.renderer.screenToTextCoordinates(p,d),T(g,e),N(g,e)}function k(){m=t.selection.toOrientedRange(),h=t.session.addMarker(m,"ace_selection",t.getSelectionStyle()),t.clearSelection(),t.isFocused()&&t.renderer.$cursorLayer.setBlinking(!1),clearInterval(v),C(),v=setInterval(C,20),y=0,i.addListener(document,"mousemove",O)}function L(){clearInterval(v),t.session.removeMarker(h),h=null,t.$blockScrolling+=1,t.selection.fromOrientedRange(m),t.$blockScrolling-=1,t.isFocused()&&!w&&t.renderer.$cursorLayer.setBlinking(!t.getReadOnly()),m=null,g=null,y=0,E=null,S=null,i.removeListener(document,"mousemove",O)}function O(){A==null&&(A=setTimeout(function(){A!=null&&h&&L()},20))}function M(e){var t=e.types;return!t||Array.prototype.some.call(t,function(e){return e=="text/plain"||e=="Text"})}function _(e){var t=["copy","copymove","all","uninitialized"],n=["move","copymove","linkmove","all","uninitialized"],r=s.isMac?e.altKey:e.ctrlKey,i="uninitialized";try{i=e.dataTransfer.effectAllowed.toLowerCase()}catch(e){}var o="none";return r&&t.indexOf(i)>=0?o="copy":n.indexOf(i)>=0?o="move":t.indexOf(i)>=0&&(o="copy"),o}var t=e.editor,n=r.createElement("img");n.src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==",s.isOpera&&(n.style.cssText="width:1px;height:1px;position:fixed;top:0;left:0;z-index:2147483647;opacity:0;");var f=["dragWait","dragWaitEnd","startDrag","dragReadyEnd","onMouseDrag"];f.forEach(function(t){e[t]=this[t]},this),t.addEventListener("mousedown",this.onMouseDown.bind(e));var c=t.container,h,p,d,v,m,g,y=0,b,w,E,S,x;this.onDragStart=function(e){if(this.cancelDrag||!c.draggable){var r=this;return setTimeout(function(){r.startSelect(),r.captureMouse(e)},0),e.preventDefault()}m=t.getSelectionRange();var i=e.dataTransfer;i.effectAllowed=t.getReadOnly()?"copy":"copyMove",s.isOpera&&(t.container.appendChild(n),n.scrollTop=0),i.setDragImage&&i.setDragImage(n,0,0),s.isOpera&&t.container.removeChild(n),i.clearData(),i.setData("Text",t.session.getTextRange()),w=!0,this.setState("drag")},this.onDragEnd=function(e){c.draggable=!1,w=!1,this.setState(null);if(!t.getReadOnly()){var n=e.dataTransfer.dropEffect;!b&&n=="move"&&t.session.remove(t.getSelectionRange()),t.renderer.$cursorLayer.setBlinking(!0)}this.editor.unsetStyle("ace_dragging"),this.editor.renderer.setCursorStyle("")},this.onDragEnter=function(e){if(t.getReadOnly()||!M(e.dataTransfer))return;return p=e.clientX,d=e.clientY,h||k(),y++,e.dataTransfer.dropEffect=b=_(e),i.preventDefault(e)},this.onDragOver=function(e){if(t.getReadOnly()||!M(e.dataTransfer))return;return p=e.clientX,d=e.clientY,h||(k(),y++),A!==null&&(A=null),e.dataTransfer.dropEffect=b=_(e),i.preventDefault(e)},this.onDragLeave=function(e){y--;if(y<=0&&h)return L(),b=null,i.preventDefault(e)},this.onDrop=function(e){if(!g)return;var n=e.dataTransfer;if(w)switch(b){case"move":m.contains(g.row,g.column)?m={start:g,end:g}:m=t.moveText(m,g);break;case"copy":m=t.moveText(m,g,!0)}else{var r=n.getData("Text");m={start:g,end:t.session.insert(g,r)},t.focus(),b=null}return L(),i.preventDefault(e)},i.addListener(c,"dragstart",this.onDragStart.bind(e)),i.addListener(c,"dragend",this.onDragEnd.bind(e)),i.addListener(c,"dragenter",this.onDragEnter.bind(e)),i.addListener(c,"dragover",this.onDragOver.bind(e)),i.addListener(c,"dragleave",this.onDragLeave.bind(e)),i.addListener(c,"drop",this.onDrop.bind(e));var A=null}function l(e,t,n,r){return Math.sqrt(Math.pow(n-e,2)+Math.pow(r-t,2))}var r=e("../lib/dom"),i=e("../lib/event"),s=e("../lib/useragent"),o=200,u=200,a=5;(function(){this.dragWait=function(){var e=Date.now()-this.mousedownEvent.time;e>this.editor.getDragDelay()&&this.startDrag()},this.dragWaitEnd=function(){var e=this.editor.container;e.draggable=!1,this.startSelect(this.mousedownEvent.getDocumentPosition()),this.selectEnd()},this.dragReadyEnd=function(e){this.editor.renderer.$cursorLayer.setBlinking(!this.editor.getReadOnly()),this.editor.unsetStyle("ace_dragging"),this.editor.renderer.setCursorStyle(""),this.dragWaitEnd()},this.startDrag=function(){this.cancelDrag=!1;var e=this.editor,t=e.container;t.draggable=!0,e.renderer.$cursorLayer.setBlinking(!1),e.setStyle("ace_dragging");var n=s.isWin?"default":"move";e.renderer.setCursorStyle(n),this.setState("dragReady")},this.onMouseDrag=function(e){var t=this.editor.container;if(s.isIE&&this.state=="dragReady"){var n=l(this.mousedownEvent.x,this.mousedownEvent.y,this.x,this.y);n>3&&t.dragDrop()}if(this.state==="dragWait"){var n=l(this.mousedownEvent.x,this.mousedownEvent.y,this.x,this.y);n>0&&(t.draggable=!1,this.startSelect(this.mousedownEvent.getDocumentPosition()))}},this.onMouseDown=function(e){if(!this.$dragEnabled)return;this.mousedownEvent=e;var t=this.editor,n=e.inSelection(),r=e.getButton(),i=e.domEvent.detail||1;if(i===1&&r===0&&n){if(e.editor.inMultiSelectMode&&(e.getAccelKey()||e.getShiftKey()))return;this.mousedownEvent.time=Date.now();var o=e.domEvent.target||e.domEvent.srcElement;"unselectable"in o&&(o.unselectable="on");if(t.getDragDelay()){if(s.isWebKit){this.cancelDrag=!0;var u=t.container;u.draggable=!0}this.setState("dragWait")}else this.startDrag();this.captureMouse(e,this.onMouseDrag.bind(this)),e.defaultPrevented=!0}}}).call(f.prototype),t.DragdropHandler=f}),define("ace/lib/net",["require","exports","module","ace/lib/dom"],function(e,t,n){"use strict";var r=e("./dom");t.get=function(e,t){var n=new XMLHttpRequest;n.open("GET",e,!0),n.onreadystatechange=function(){n.readyState===4&&t(n.responseText)},n.send(null)},t.loadScript=function(e,t){var n=r.getDocumentHead(),i=document.createElement("script");i.src=e,n.appendChild(i),i.onload=i.onreadystatechange=function(e,n){if(n||!i.readyState||i.readyState=="loaded"||i.readyState=="complete")i=i.onload=i.onreadystatechange=null,n||t()}},t.qualifyURL=function(e){var t=document.createElement("a");return t.href=e,t.href}}),define("ace/lib/event_emitter",["require","exports","module"],function(e,t,n){"use strict";var r={},i=function(){this.propagationStopped=!0},s=function(){this.defaultPrevented=!0};r._emit=r._dispatchEvent=function(e,t){this._eventRegistry||(this._eventRegistry={}),this._defaultHandlers||(this._defaultHandlers={});var n=this._eventRegistry[e]||[],r=this._defaultHandlers[e];if(!n.length&&!r)return;if(typeof t!="object"||!t)t={};t.type||(t.type=e),t.stopPropagation||(t.stopPropagation=i),t.preventDefault||(t.preventDefault=s),n=n.slice();for(var o=0;o1&&(i=n[n.length-2]);var o=a[t+"Path"];return o==null?o=a.basePath:r=="/"&&(t=r=""),o&&o.slice(-1)!="/"&&(o+="/"),o+t+r+i+this.get("suffix")},t.setModuleUrl=function(e,t){return a.$moduleUrls[e]=t},t.$loading={},t.loadModule=function(n,r){var i,o;Array.isArray(n)&&(o=n[0],n=n[1]);try{i=e(n)}catch(u){}if(i&&!t.$loading[n])return r&&r(i);t.$loading[n]||(t.$loading[n]=[]),t.$loading[n].push(r);if(t.$loading[n].length>1)return;var a=function(){e([n],function(e){t._emit("load.module",{name:n,module:e});var r=t.$loading[n];t.$loading[n]=null,r.forEach(function(t){t&&t(e)})})};if(!t.get("packaged"))return a();s.loadScript(t.moduleUrl(n,o),a)},t.init=f}),define("ace/mouse/mouse_handler",["require","exports","module","ace/lib/event","ace/lib/useragent","ace/mouse/default_handlers","ace/mouse/default_gutter_handler","ace/mouse/mouse_event","ace/mouse/dragdrop_handler","ace/config"],function(e,t,n){"use strict";var r=e("../lib/event"),i=e("../lib/useragent"),s=e("./default_handlers").DefaultHandlers,o=e("./default_gutter_handler").GutterHandler,u=e("./mouse_event").MouseEvent,a=e("./dragdrop_handler").DragdropHandler,f=e("../config"),l=function(e){var t=this;this.editor=e,new s(this),new o(this),new a(this);var n=function(t){var n=!document.hasFocus||!document.hasFocus()||!e.isFocused()&&document.activeElement==(e.textInput&&e.textInput.getElement());n&&window.focus(),e.focus()},u=e.renderer.getMouseEventTarget();r.addListener(u,"click",this.onMouseEvent.bind(this,"click")),r.addListener(u,"mousemove",this.onMouseMove.bind(this,"mousemove")),r.addMultiMouseDownListener([u,e.renderer.scrollBarV&&e.renderer.scrollBarV.inner,e.renderer.scrollBarH&&e.renderer.scrollBarH.inner,e.textInput&&e.textInput.getElement()].filter(Boolean),[400,300,250],this,"onMouseEvent"),r.addMouseWheelListener(e.container,this.onMouseWheel.bind(this,"mousewheel")),r.addTouchMoveListener(e.container,this.onTouchMove.bind(this,"touchmove"));var f=e.renderer.$gutter;r.addListener(f,"mousedown",this.onMouseEvent.bind(this,"guttermousedown")),r.addListener(f,"click",this.onMouseEvent.bind(this,"gutterclick")),r.addListener(f,"dblclick",this.onMouseEvent.bind(this,"gutterdblclick")),r.addListener(f,"mousemove",this.onMouseEvent.bind(this,"guttermousemove")),r.addListener(u,"mousedown",n),r.addListener(f,"mousedown",n),i.isIE&&e.renderer.scrollBarV&&(r.addListener(e.renderer.scrollBarV.element,"mousedown",n),r.addListener(e.renderer.scrollBarH.element,"mousedown",n)),e.on("mousemove",function(n){if(t.state||t.$dragDelay||!t.$dragEnabled)return;var r=e.renderer.screenToTextCoordinates(n.x,n.y),i=e.session.selection.getRange(),s=e.renderer;!i.isEmpty()&&i.insideStart(r.row,r.column)?s.setCursorStyle("default"):s.setCursorStyle("")})};(function(){this.onMouseEvent=function(e,t){this.editor._emit(e,new u(t,this.editor))},this.onMouseMove=function(e,t){var n=this.editor._eventRegistry&&this.editor._eventRegistry.mousemove;if(!n||!n.length)return;this.editor._emit(e,new u(t,this.editor))},this.onMouseWheel=function(e,t){var n=new u(t,this.editor);n.speed=this.$scrollSpeed*2,n.wheelX=t.wheelX,n.wheelY=t.wheelY,this.editor._emit(e,n)},this.onTouchMove=function(e,t){var n=new u(t,this.editor);n.speed=1,n.wheelX=t.wheelX,n.wheelY=t.wheelY,this.editor._emit(e,n)},this.setState=function(e){this.state=e},this.captureMouse=function(e,t){this.x=e.x,this.y=e.y,this.isMousePressed=!0;var n=this.editor.renderer;n.$keepTextAreaAtCursor&&(n.$keepTextAreaAtCursor=null);var s=this,o=function(e){if(!e)return;if(i.isWebKit&&!e.which&&s.releaseMouse)return s.releaseMouse();s.x=e.clientX,s.y=e.clientY,t&&t(e),s.mouseEvent=new u(e,s.editor),s.$mouseMoved=!0},a=function(e){clearInterval(l),f(),s[s.state+"End"]&&s[s.state+"End"](e),s.state="",n.$keepTextAreaAtCursor==null&&(n.$keepTextAreaAtCursor=!0,n.$moveTextAreaToCursor()),s.isMousePressed=!1,s.$onCaptureMouseMove=s.releaseMouse=null,e&&s.onMouseEvent("mouseup",e)},f=function(){s[s.state]&&s[s.state](),s.$mouseMoved=!1};if(i.isOldIE&&e.domEvent.type=="dblclick")return setTimeout(function(){a(e)});s.$onCaptureMouseMove=o,s.releaseMouse=r.capture(this.editor.container,o,a);var l=setInterval(f,20)},this.releaseMouse=null,this.cancelContextMenu=function(){var e=function(t){if(t&&t.domEvent&&t.domEvent.type!="contextmenu")return;this.editor.off("nativecontextmenu",e),t&&t.domEvent&&r.stopEvent(t.domEvent)}.bind(this);setTimeout(e,10),this.editor.on("nativecontextmenu",e)}}).call(l.prototype),f.defineOptions(l.prototype,"mouseHandler",{scrollSpeed:{initialValue:2},dragDelay:{initialValue:i.isMac?150:0},dragEnabled:{initialValue:!0},focusTimout:{initialValue:0},tooltipFollowsMouse:{initialValue:!0}}),t.MouseHandler=l}),define("ace/mouse/fold_handler",["require","exports","module"],function(e,t,n){"use strict";function r(e){e.on("click",function(t){var n=t.getDocumentPosition(),r=e.session,i=r.getFoldAt(n.row,n.column,1);i&&(t.getAccelKey()?r.removeFold(i):r.expandFold(i),t.stop())}),e.on("gutterclick",function(t){var n=e.renderer.$gutterLayer.getRegion(t);if(n=="foldWidgets"){var r=t.getDocumentPosition().row,i=e.session;i.foldWidgets&&i.foldWidgets[r]&&e.session.onFoldWidgetClick(r,t),e.isFocused()||e.focus(),t.stop()}}),e.on("gutterdblclick",function(t){var n=e.renderer.$gutterLayer.getRegion(t);if(n=="foldWidgets"){var r=t.getDocumentPosition().row,i=e.session,s=i.getParentFoldRangeData(r,!0),o=s.range||s.firstRange;if(o){r=o.start.row;var u=i.getFoldAt(r,i.getLine(r).length,1);u?i.removeFold(u):(i.addFold("...",o),e.renderer.scrollCursorIntoView({row:o.start.row,column:0}))}t.stop()}})}t.FoldHandler=r}),define("ace/keyboard/keybinding",["require","exports","module","ace/lib/keys","ace/lib/event"],function(e,t,n){"use strict";var r=e("../lib/keys"),i=e("../lib/event"),s=function(e){this.$editor=e,this.$data={editor:e},this.$handlers=[],this.setDefaultHandler(e.commands)};(function(){this.setDefaultHandler=function(e){this.removeKeyboardHandler(this.$defaultHandler),this.$defaultHandler=e,this.addKeyboardHandler(e,0)},this.setKeyboardHandler=function(e){var t=this.$handlers;if(t[t.length-1]==e)return;while(t[t.length-1]&&t[t.length-1]!=this.$defaultHandler)this.removeKeyboardHandler(t[t.length-1]);this.addKeyboardHandler(e,1)},this.addKeyboardHandler=function(e,t){if(!e)return;typeof e=="function"&&!e.handleKeyboard&&(e.handleKeyboard=e);var n=this.$handlers.indexOf(e);n!=-1&&this.$handlers.splice(n,1),t==undefined?this.$handlers.push(e):this.$handlers.splice(t,0,e),n==-1&&e.attach&&e.attach(this.$editor)},this.removeKeyboardHandler=function(e){var t=this.$handlers.indexOf(e);return t==-1?!1:(this.$handlers.splice(t,1),e.detach&&e.detach(this.$editor),!0)},this.getKeyboardHandler=function(){return this.$handlers[this.$handlers.length-1]},this.getStatusText=function(){var e=this.$data,t=e.editor;return this.$handlers.map(function(n){return n.getStatusText&&n.getStatusText(t,e)||""}).filter(Boolean).join(" ")},this.$callKeyboardHandlers=function(e,t,n,r){var s,o=!1,u=this.$editor.commands;for(var a=this.$handlers.length;a--;){s=this.$handlers[a].handleKeyboard(this.$data,e,t,n,r);if(!s||!s.command)continue;s.command=="null"?o=!0:o=u.exec(s.command,this.$editor,s.args,r),o&&r&&e!=-1&&s.passEvent!=1&&s.command.passEvent!=1&&i.stopEvent(r);if(o)break}return!o&&e==-1&&(s={command:"insertstring"},o=u.exec("insertstring",this.$editor,t)),o&&this.$editor._signal&&this.$editor._signal("keyboardActivity",s),o},this.onCommandKey=function(e,t,n){var i=r.keyCodeToString(n);this.$callKeyboardHandlers(t,i,n,e)},this.onTextInput=function(e){this.$callKeyboardHandlers(-1,e)}}).call(s.prototype),t.KeyBinding=s}),define("ace/range",["require","exports","module"],function(e,t,n){"use strict";var r=function(e,t){return e.row-t.row||e.column-t.column},i=function(e,t,n,r){this.start={row:e,column:t},this.end={row:n,column:r}};(function(){this.isEqual=function(e){return this.start.row===e.start.row&&this.end.row===e.end.row&&this.start.column===e.start.column&&this.end.column===e.end.column},this.toString=function(){return"Range: ["+this.start.row+"/"+this.start.column+"] -> ["+this.end.row+"/"+this.end.column+"]"},this.contains=function(e,t){return this.compare(e,t)==0},this.compareRange=function(e){var t,n=e.end,r=e.start;return t=this.compare(n.row,n.column),t==1?(t=this.compare(r.row,r.column),t==1?2:t==0?1:0):t==-1?-2:(t=this.compare(r.row,r.column),t==-1?-1:t==1?42:0)},this.comparePoint=function(e){return this.compare(e.row,e.column)},this.containsRange=function(e){return this.comparePoint(e.start)==0&&this.comparePoint(e.end)==0},this.intersects=function(e){var t=this.compareRange(e);return t==-1||t==0||t==1},this.isEnd=function(e,t){return this.end.row==e&&this.end.column==t},this.isStart=function(e,t){return this.start.row==e&&this.start.column==t},this.setStart=function(e,t){typeof e=="object"?(this.start.column=e.column,this.start.row=e.row):(this.start.row=e,this.start.column=t)},this.setEnd=function(e,t){typeof e=="object"?(this.end.column=e.column,this.end.row=e.row):(this.end.row=e,this.end.column=t)},this.inside=function(e,t){return this.compare(e,t)==0?this.isEnd(e,t)||this.isStart(e,t)?!1:!0:!1},this.insideStart=function(e,t){return this.compare(e,t)==0?this.isEnd(e,t)?!1:!0:!1},this.insideEnd=function(e,t){return this.compare(e,t)==0?this.isStart(e,t)?!1:!0:!1},this.compare=function(e,t){return!this.isMultiLine()&&e===this.start.row?tthis.end.column?1:0:ethis.end.row?1:this.start.row===e?t>=this.start.column?0:-1:this.end.row===e?t<=this.end.column?0:1:0},this.compareStart=function(e,t){return this.start.row==e&&this.start.column==t?-1:this.compare(e,t)},this.compareEnd=function(e,t){return this.end.row==e&&this.end.column==t?1:this.compare(e,t)},this.compareInside=function(e,t){return this.end.row==e&&this.end.column==t?1:this.start.row==e&&this.start.column==t?-1:this.compare(e,t)},this.clipRows=function(e,t){if(this.end.row>t)var n={row:t+1,column:0};else if(this.end.rowt)var r={row:t+1,column:0};else if(this.start.rowt.row||e.row==t.row&&e.column>t.column},this.getRange=function(){var e=this.anchor,t=this.lead;return this.isEmpty()?o.fromPoints(t,t):this.isBackwards()?o.fromPoints(t,e):o.fromPoints(e,t)},this.clearSelection=function(){this.$isEmpty||(this.$isEmpty=!0,this._emit("changeSelection"))},this.selectAll=function(){var e=this.doc.getLength()-1;this.setSelectionAnchor(0,0),this.moveCursorTo(e,this.doc.getLine(e).length)},this.setRange=this.setSelectionRange=function(e,t){t?(this.setSelectionAnchor(e.end.row,e.end.column),this.selectTo(e.start.row,e.start.column)):(this.setSelectionAnchor(e.start.row,e.start.column),this.selectTo(e.end.row,e.end.column)),this.getRange().isEmpty()&&(this.$isEmpty=!0),this.$desiredColumn=null},this.$moveSelection=function(e){var t=this.lead;this.$isEmpty&&this.setSelectionAnchor(t.row,t.column),e.call(this)},this.selectTo=function(e,t){this.$moveSelection(function(){this.moveCursorTo(e,t)})},this.selectToPosition=function(e){this.$moveSelection(function(){this.moveCursorToPosition(e)})},this.moveTo=function(e,t){this.clearSelection(),this.moveCursorTo(e,t)},this.moveToPosition=function(e){this.clearSelection(),this.moveCursorToPosition(e)},this.selectUp=function(){this.$moveSelection(this.moveCursorUp)},this.selectDown=function(){this.$moveSelection(this.moveCursorDown)},this.selectRight=function(){this.$moveSelection(this.moveCursorRight)},this.selectLeft=function(){this.$moveSelection(this.moveCursorLeft)},this.selectLineStart=function(){this.$moveSelection(this.moveCursorLineStart)},this.selectLineEnd=function(){this.$moveSelection(this.moveCursorLineEnd)},this.selectFileEnd=function(){this.$moveSelection(this.moveCursorFileEnd)},this.selectFileStart=function(){this.$moveSelection(this.moveCursorFileStart)},this.selectWordRight=function(){this.$moveSelection(this.moveCursorWordRight)},this.selectWordLeft=function(){this.$moveSelection(this.moveCursorWordLeft)},this.getWordRange=function(e,t){if(typeof t=="undefined"){var n=e||this.lead;e=n.row,t=n.column}return this.session.getWordRange(e,t)},this.selectWord=function(){this.setSelectionRange(this.getWordRange())},this.selectAWord=function(){var e=this.getCursor(),t=this.session.getAWordRange(e.row,e.column);this.setSelectionRange(t)},this.getLineRange=function(e,t){var n=typeof e=="number"?e:this.lead.row,r,i=this.session.getFoldLine(n);return i?(n=i.start.row,r=i.end.row):r=n,t===!0?new o(n,0,r,this.session.getLine(r).length):new o(n,0,r+1,0)},this.selectLine=function(){this.setSelectionRange(this.getLineRange())},this.moveCursorUp=function(){this.moveCursorBy(-1,0)},this.moveCursorDown=function(){this.moveCursorBy(1,0)},this.moveCursorLeft=function(){var e=this.lead.getPosition(),t;if(t=this.session.getFoldAt(e.row,e.column,-1))this.moveCursorTo(t.start.row,t.start.column);else if(e.column===0)e.row>0&&this.moveCursorTo(e.row-1,this.doc.getLine(e.row-1).length);else{var n=this.session.getTabSize();this.session.isTabStop(e)&&this.doc.getLine(e.row).slice(e.column-n,e.column).split(" ").length-1==n?this.moveCursorBy(0,-n):this.moveCursorBy(0,-1)}},this.moveCursorRight=function(){var e=this.lead.getPosition(),t;if(t=this.session.getFoldAt(e.row,e.column,1))this.moveCursorTo(t.end.row,t.end.column);else if(this.lead.column==this.doc.getLine(this.lead.row).length)this.lead.row0&&(t.column=r)}}this.moveCursorTo(t.row,t.column)},this.moveCursorFileEnd=function(){var e=this.doc.getLength()-1,t=this.doc.getLine(e).length;this.moveCursorTo(e,t)},this.moveCursorFileStart=function(){this.moveCursorTo(0,0)},this.moveCursorLongWordRight=function(){var e=this.lead.row,t=this.lead.column,n=this.doc.getLine(e),r=n.substring(t),i;this.session.nonTokenRe.lastIndex=0,this.session.tokenRe.lastIndex=0;var s=this.session.getFoldAt(e,t,1);if(s){this.moveCursorTo(s.end.row,s.end.column);return}if(i=this.session.nonTokenRe.exec(r))t+=this.session.nonTokenRe.lastIndex,this.session.nonTokenRe.lastIndex=0,r=n.substring(t);if(t>=n.length){this.moveCursorTo(e,n.length),this.moveCursorRight(),e0&&this.moveCursorWordLeft();return}if(o=this.session.tokenRe.exec(s))t-=this.session.tokenRe.lastIndex,this.session.tokenRe.lastIndex=0;this.moveCursorTo(e,t)},this.$shortWordEndIndex=function(e){var t,n=0,r,i=/\s/,s=this.session.tokenRe;s.lastIndex=0;if(t=this.session.tokenRe.exec(e))n=this.session.tokenRe.lastIndex;else{while((r=e[n])&&i.test(r))n++;if(n<1){s.lastIndex=0;while((r=e[n])&&!s.test(r)){s.lastIndex=0,n++;if(i.test(r)){if(n>2){n--;break}while((r=e[n])&&i.test(r))n++;if(n>2)break}}}}return s.lastIndex=0,n},this.moveCursorShortWordRight=function(){var e=this.lead.row,t=this.lead.column,n=this.doc.getLine(e),r=n.substring(t),i=this.session.getFoldAt(e,t,1);if(i)return this.moveCursorTo(i.end.row,i.end.column);if(t==n.length){var s=this.doc.getLength();do e++,r=this.doc.getLine(e);while(e0&&/^\s*$/.test(r));t=r.length,/\s+$/.test(r)||(r="")}var s=i.stringReverse(r),o=this.$shortWordEndIndex(s);return this.moveCursorTo(e,t-o)},this.moveCursorWordRight=function(){this.session.$selectLongWords?this.moveCursorLongWordRight():this.moveCursorShortWordRight()},this.moveCursorWordLeft=function(){this.session.$selectLongWords?this.moveCursorLongWordLeft():this.moveCursorShortWordLeft()},this.moveCursorBy=function(e,t){var n=this.session.documentToScreenPosition(this.lead.row,this.lead.column);t===0&&(this.$desiredColumn?n.column=this.$desiredColumn:this.$desiredColumn=n.column);var r=this.session.screenToDocumentPosition(n.row+e,n.column);e!==0&&t===0&&r.row===this.lead.row&&r.column===this.lead.column&&this.session.lineWidgets&&this.session.lineWidgets[r.row]&&(r.row>0||e>0)&&r.row++,this.moveCursorTo(r.row,r.column+t,t===0)},this.moveCursorToPosition=function(e){this.moveCursorTo(e.row,e.column)},this.moveCursorTo=function(e,t,n){var r=this.session.getFoldAt(e,t,1);r&&(e=r.start.row,t=r.start.column),this.$keepDesiredColumnOnChange=!0,this.lead.setPosition(e,t),this.$keepDesiredColumnOnChange=!1,n||(this.$desiredColumn=null)},this.moveCursorToScreen=function(e,t,n){var r=this.session.screenToDocumentPosition(e,t);this.moveCursorTo(r.row,r.column,n)},this.detach=function(){this.lead.detach(),this.anchor.detach(),this.session=this.doc=null},this.fromOrientedRange=function(e){this.setSelectionRange(e,e.cursor==e.start),this.$desiredColumn=e.desiredColumn||this.$desiredColumn},this.toOrientedRange=function(e){var t=this.getRange();return e?(e.start.column=t.start.column,e.start.row=t.start.row,e.end.column=t.end.column,e.end.row=t.end.row):e=t,e.cursor=this.isBackwards()?e.start:e.end,e.desiredColumn=this.$desiredColumn,e},this.getRangeOfMovements=function(e){var t=this.getCursor();try{e(this);var n=this.getCursor();return o.fromPoints(t,n)}catch(r){return o.fromPoints(t,t)}finally{this.moveCursorToPosition(t)}},this.toJSON=function(){if(this.rangeCount)var e=this.ranges.map(function(e){var t=e.clone();return t.isBackwards=e.cursor==e.start,t});else{var e=this.getRange();e.isBackwards=this.isBackwards()}return e},this.fromJSON=function(e){if(e.start==undefined){if(this.rangeList){this.toSingleRange(e[0]);for(var t=e.length;t--;){var n=o.fromPoints(e[t].start,e[t].end);e[t].isBackwards&&(n.cursor=n.start),this.addRange(n,!0)}return}e=e[0]}this.rangeList&&this.toSingleRange(e),this.setSelectionRange(e,e.isBackwards)},this.isEqual=function(e){if((e.length||this.rangeCount)&&e.length!=this.rangeCount)return!1;if(!e.length||!this.ranges)return this.getRange().isEqual(e);for(var t=this.ranges.length;t--;)if(!this.ranges[t].isEqual(e[t]))return!1;return!0}}).call(u.prototype),t.Selection=u}),define("ace/tokenizer",["require","exports","module","ace/config"],function(e,t,n){"use strict";var r=e("./config"),i=2e3,s=function(e){this.states=e,this.regExps={},this.matchMappings={};for(var t in this.states){var n=this.states[t],r=[],i=0,s=this.matchMappings[t]={defaultToken:"text"},o="g",u=[];for(var a=0;a1?f.onMatch=this.$applyToken:f.onMatch=f.token),c>1&&(/\\\d/.test(f.regex)?l=f.regex.replace(/\\([0-9]+)/g,function(e,t){return"\\"+(parseInt(t,10)+i+1)}):(c=1,l=this.removeCapturingGroups(f.regex)),!f.splitRegex&&typeof f.token!="string"&&u.push(f)),s[i]=a,i+=c,r.push(l),f.onMatch||(f.onMatch=null)}r.length||(s[0]=0,r.push("$")),u.forEach(function(e){e.splitRegex=this.createSplitterRegexp(e.regex,o)},this),this.regExps[t]=new RegExp("("+r.join(")|(")+")|($)",o)}};(function(){this.$setMaxTokenCount=function(e){i=e|0},this.$applyToken=function(e){var t=this.splitRegex.exec(e).slice(1),n=this.token.apply(this,t);if(typeof n=="string")return[{type:n,value:e}];var r=[];for(var i=0,s=n.length;il){var g=e.substring(l,m-v.length);h.type==p?h.value+=g:(h.type&&f.push(h),h={type:p,value:g})}for(var y=0;yi){c>2*e.length&&this.reportError("infinite loop with in ace tokenizer",{startState:t,line:e});while(l1&&n[0]!==r&&n.unshift("#tmp",r),{tokens:f,state:n.length?n:r}},this.reportError=r.reportError}).call(s.prototype),t.Tokenizer=s}),define("ace/mode/text_highlight_rules",["require","exports","module","ace/lib/lang"],function(e,t,n){"use strict";var r=e("../lib/lang"),i=function(){this.$rules={start:[{token:"empty_line",regex:"^$"},{defaultToken:"text"}]}};(function(){this.addRules=function(e,t){if(!t){for(var n in e)this.$rules[n]=e[n];return}for(var n in e){var r=e[n];for(var i=0;i=this.$rowTokens.length){this.$row+=1,e||(e=this.$session.getLength());if(this.$row>=e)return this.$row=e-1,null;this.$rowTokens=this.$session.getTokens(this.$row),this.$tokenIndex=0}return this.$rowTokens[this.$tokenIndex]},this.getCurrentToken=function(){return this.$rowTokens[this.$tokenIndex]},this.getCurrentTokenRow=function(){return this.$row},this.getCurrentTokenColumn=function(){var e=this.$rowTokens,t=this.$tokenIndex,n=e[t].start;if(n!==undefined)return n;n=0;while(t>0)t-=1,n+=e[t].value.length;return n},this.getCurrentTokenPosition=function(){return{row:this.$row,column:this.getCurrentTokenColumn()}}}).call(r.prototype),t.TokenIterator=r}),define("ace/mode/behaviour/cstyle",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator","ace/lib/lang"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("../../token_iterator").TokenIterator,o=e("../../lib/lang"),u=["text","paren.rparen","punctuation.operator"],a=["text","paren.rparen","punctuation.operator","comment"],f,l={},c=function(e){var t=-1;e.multiSelect&&(t=e.selection.index,l.rangeCount!=e.multiSelect.rangeCount&&(l={rangeCount:e.multiSelect.rangeCount}));if(l[t])return f=l[t];f=l[t]={autoInsertedBrackets:0,autoInsertedRow:-1,autoInsertedLineEnd:"",maybeInsertedBrackets:0,maybeInsertedRow:-1,maybeInsertedLineStart:"",maybeInsertedLineEnd:""}},h=function(e,t,n,r){var i=e.end.row-e.start.row;return{text:n+t+r,selection:[0,e.start.column+1,i,e.end.column+(i?0:1)]}},p=function(){this.add("braces","insertion",function(e,t,n,r,i){var s=n.getCursorPosition(),u=r.doc.getLine(s.row);if(i=="{"){c(n);var a=n.getSelectionRange(),l=r.doc.getTextRange(a);if(l!==""&&l!=="{"&&n.getWrapBehavioursEnabled())return h(a,l,"{","}");if(p.isSaneInsertion(n,r))return/[\]\}\)]/.test(u[s.column])||n.inMultiSelectMode?(p.recordAutoInsert(n,r,"}"),{text:"{}",selection:[1,1]}):(p.recordMaybeInsert(n,r,"{"),{text:"{",selection:[1,1]})}else if(i=="}"){c(n);var d=u.substring(s.column,s.column+1);if(d=="}"){var v=r.$findOpeningBracket("}",{column:s.column+1,row:s.row});if(v!==null&&p.isAutoInsertedClosing(s,u,i))return p.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}else{if(i=="\n"||i=="\r\n"){c(n);var m="";p.isMaybeInsertedClosing(s,u)&&(m=o.stringRepeat("}",f.maybeInsertedBrackets),p.clearMaybeInsertedClosing());var d=u.substring(s.column,s.column+1);if(d==="}"){var g=r.findMatchingBracket({row:s.row,column:s.column+1},"}");if(!g)return null;var y=this.$getIndent(r.getLine(g.row))}else{if(!m){p.clearMaybeInsertedClosing();return}var y=this.$getIndent(u)}var b=y+r.getTabString();return{text:"\n"+b+"\n"+y+m,selection:[1,b.length,1,b.length]}}p.clearMaybeInsertedClosing()}}),this.add("braces","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="{"){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.end.column,i.end.column+1);if(u=="}")return i.end.column++,i;f.maybeInsertedBrackets--}}),this.add("parens","insertion",function(e,t,n,r,i){if(i=="("){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return h(s,o,"(",")");if(p.isSaneInsertion(n,r))return p.recordAutoInsert(n,r,")"),{text:"()",selection:[1,1]}}else if(i==")"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f==")"){var l=r.$findOpeningBracket(")",{column:u.column+1,row:u.row});if(l!==null&&p.isAutoInsertedClosing(u,a,i))return p.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("parens","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="("){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==")")return i.end.column++,i}}),this.add("brackets","insertion",function(e,t,n,r,i){if(i=="["){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return h(s,o,"[","]");if(p.isSaneInsertion(n,r))return p.recordAutoInsert(n,r,"]"),{text:"[]",selection:[1,1]}}else if(i=="]"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f=="]"){var l=r.$findOpeningBracket("]",{column:u.column+1,row:u.row});if(l!==null&&p.isAutoInsertedClosing(u,a,i))return p.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("brackets","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="["){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u=="]")return i.end.column++,i}}),this.add("string_dquotes","insertion",function(e,t,n,r,i){if(i=='"'||i=="'"){if(this.lineCommentStart&&this.lineCommentStart.indexOf(i)!=-1)return;c(n);var s=i,o=n.getSelectionRange(),u=r.doc.getTextRange(o);if(u!==""&&u!=="'"&&u!='"'&&n.getWrapBehavioursEnabled())return h(o,u,s,s);if(!u){var a=n.getCursorPosition(),f=r.doc.getLine(a.row),l=f.substring(a.column-1,a.column),p=f.substring(a.column,a.column+1),d=r.getTokenAt(a.row,a.column),v=r.getTokenAt(a.row,a.column+1);if(l=="\\"&&d&&/escape/.test(d.type))return null;var m=d&&/string|escape/.test(d.type),g=!v||/string|escape/.test(v.type),y;if(p==s)y=m!==g,y&&/string\.end/.test(v.type)&&(y=!1);else{if(m&&!g)return null;if(m&&g)return null;var b=r.$mode.tokenRe;b.lastIndex=0;var w=b.test(l);b.lastIndex=0;var E=b.test(l);if(w||E)return null;if(p&&!/[\s;,.})\]\\]/.test(p))return null;y=!0}return{text:y?s+s:"",selection:[1,1]}}}}),this.add("string_dquotes","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&(s=='"'||s=="'")){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==s)return i.end.column++,i}})};p.isSaneInsertion=function(e,t){var n=e.getCursorPosition(),r=new s(t,n.row,n.column);if(!this.$matchTokenType(r.getCurrentToken()||"text",u)){var i=new s(t,n.row,n.column+1);if(!this.$matchTokenType(i.getCurrentToken()||"text",u))return!1}return r.stepForward(),r.getCurrentTokenRow()!==n.row||this.$matchTokenType(r.getCurrentToken()||"text",a)},p.$matchTokenType=function(e,t){return t.indexOf(e.type||e)>-1},p.recordAutoInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isAutoInsertedClosing(r,i,f.autoInsertedLineEnd[0])||(f.autoInsertedBrackets=0),f.autoInsertedRow=r.row,f.autoInsertedLineEnd=n+i.substr(r.column),f.autoInsertedBrackets++},p.recordMaybeInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isMaybeInsertedClosing(r,i)||(f.maybeInsertedBrackets=0),f.maybeInsertedRow=r.row,f.maybeInsertedLineStart=i.substr(0,r.column)+n,f.maybeInsertedLineEnd=i.substr(r.column),f.maybeInsertedBrackets++},p.isAutoInsertedClosing=function(e,t,n){return f.autoInsertedBrackets>0&&e.row===f.autoInsertedRow&&n===f.autoInsertedLineEnd[0]&&t.substr(e.column)===f.autoInsertedLineEnd},p.isMaybeInsertedClosing=function(e,t){return f.maybeInsertedBrackets>0&&e.row===f.maybeInsertedRow&&t.substr(e.column)===f.maybeInsertedLineEnd&&t.substr(0,e.column)==f.maybeInsertedLineStart},p.popAutoInsertedClosing=function(){f.autoInsertedLineEnd=f.autoInsertedLineEnd.substr(1),f.autoInsertedBrackets--},p.clearMaybeInsertedClosing=function(){f&&(f.maybeInsertedBrackets=0,f.maybeInsertedRow=-1)},r.inherits(p,i),t.CstyleBehaviour=p}),define("ace/unicode",["require","exports","module"],function(e,t,n){"use strict";function r(e){var n=/\w{4}/g;for(var r in e)t.packages[r]=e[r].replace(n,"\\u$&")}t.packages={},r({L:"0041-005A0061-007A00AA00B500BA00C0-00D600D8-00F600F8-02C102C6-02D102E0-02E402EC02EE0370-037403760377037A-037D03860388-038A038C038E-03A103A3-03F503F7-0481048A-05250531-055605590561-058705D0-05EA05F0-05F20621-064A066E066F0671-06D306D506E506E606EE06EF06FA-06FC06FF07100712-072F074D-07A507B107CA-07EA07F407F507FA0800-0815081A082408280904-0939093D09500958-0961097109720979-097F0985-098C098F09900993-09A809AA-09B009B209B6-09B909BD09CE09DC09DD09DF-09E109F009F10A05-0A0A0A0F0A100A13-0A280A2A-0A300A320A330A350A360A380A390A59-0A5C0A5E0A72-0A740A85-0A8D0A8F-0A910A93-0AA80AAA-0AB00AB20AB30AB5-0AB90ABD0AD00AE00AE10B05-0B0C0B0F0B100B13-0B280B2A-0B300B320B330B35-0B390B3D0B5C0B5D0B5F-0B610B710B830B85-0B8A0B8E-0B900B92-0B950B990B9A0B9C0B9E0B9F0BA30BA40BA8-0BAA0BAE-0BB90BD00C05-0C0C0C0E-0C100C12-0C280C2A-0C330C35-0C390C3D0C580C590C600C610C85-0C8C0C8E-0C900C92-0CA80CAA-0CB30CB5-0CB90CBD0CDE0CE00CE10D05-0D0C0D0E-0D100D12-0D280D2A-0D390D3D0D600D610D7A-0D7F0D85-0D960D9A-0DB10DB3-0DBB0DBD0DC0-0DC60E01-0E300E320E330E40-0E460E810E820E840E870E880E8A0E8D0E94-0E970E99-0E9F0EA1-0EA30EA50EA70EAA0EAB0EAD-0EB00EB20EB30EBD0EC0-0EC40EC60EDC0EDD0F000F40-0F470F49-0F6C0F88-0F8B1000-102A103F1050-1055105A-105D106110651066106E-10701075-1081108E10A0-10C510D0-10FA10FC1100-1248124A-124D1250-12561258125A-125D1260-1288128A-128D1290-12B012B2-12B512B8-12BE12C012C2-12C512C8-12D612D8-13101312-13151318-135A1380-138F13A0-13F41401-166C166F-167F1681-169A16A0-16EA1700-170C170E-17111720-17311740-17511760-176C176E-17701780-17B317D717DC1820-18771880-18A818AA18B0-18F51900-191C1950-196D1970-19741980-19AB19C1-19C71A00-1A161A20-1A541AA71B05-1B331B45-1B4B1B83-1BA01BAE1BAF1C00-1C231C4D-1C4F1C5A-1C7D1CE9-1CEC1CEE-1CF11D00-1DBF1E00-1F151F18-1F1D1F20-1F451F48-1F4D1F50-1F571F591F5B1F5D1F5F-1F7D1F80-1FB41FB6-1FBC1FBE1FC2-1FC41FC6-1FCC1FD0-1FD31FD6-1FDB1FE0-1FEC1FF2-1FF41FF6-1FFC2071207F2090-209421022107210A-211321152119-211D212421262128212A-212D212F-2139213C-213F2145-2149214E218321842C00-2C2E2C30-2C5E2C60-2CE42CEB-2CEE2D00-2D252D30-2D652D6F2D80-2D962DA0-2DA62DA8-2DAE2DB0-2DB62DB8-2DBE2DC0-2DC62DC8-2DCE2DD0-2DD62DD8-2DDE2E2F300530063031-3035303B303C3041-3096309D-309F30A1-30FA30FC-30FF3105-312D3131-318E31A0-31B731F0-31FF3400-4DB54E00-9FCBA000-A48CA4D0-A4FDA500-A60CA610-A61FA62AA62BA640-A65FA662-A66EA67F-A697A6A0-A6E5A717-A71FA722-A788A78BA78CA7FB-A801A803-A805A807-A80AA80C-A822A840-A873A882-A8B3A8F2-A8F7A8FBA90A-A925A930-A946A960-A97CA984-A9B2A9CFAA00-AA28AA40-AA42AA44-AA4BAA60-AA76AA7AAA80-AAAFAAB1AAB5AAB6AAB9-AABDAAC0AAC2AADB-AADDABC0-ABE2AC00-D7A3D7B0-D7C6D7CB-D7FBF900-FA2DFA30-FA6DFA70-FAD9FB00-FB06FB13-FB17FB1DFB1F-FB28FB2A-FB36FB38-FB3CFB3EFB40FB41FB43FB44FB46-FBB1FBD3-FD3DFD50-FD8FFD92-FDC7FDF0-FDFBFE70-FE74FE76-FEFCFF21-FF3AFF41-FF5AFF66-FFBEFFC2-FFC7FFCA-FFCFFFD2-FFD7FFDA-FFDC",Ll:"0061-007A00AA00B500BA00DF-00F600F8-00FF01010103010501070109010B010D010F01110113011501170119011B011D011F01210123012501270129012B012D012F01310133013501370138013A013C013E014001420144014601480149014B014D014F01510153015501570159015B015D015F01610163016501670169016B016D016F0171017301750177017A017C017E-0180018301850188018C018D019201950199-019B019E01A101A301A501A801AA01AB01AD01B001B401B601B901BA01BD-01BF01C601C901CC01CE01D001D201D401D601D801DA01DC01DD01DF01E101E301E501E701E901EB01ED01EF01F001F301F501F901FB01FD01FF02010203020502070209020B020D020F02110213021502170219021B021D021F02210223022502270229022B022D022F02310233-0239023C023F0240024202470249024B024D024F-02930295-02AF037103730377037B-037D039003AC-03CE03D003D103D5-03D703D903DB03DD03DF03E103E303E503E703E903EB03ED03EF-03F303F503F803FB03FC0430-045F04610463046504670469046B046D046F04710473047504770479047B047D047F0481048B048D048F04910493049504970499049B049D049F04A104A304A504A704A904AB04AD04AF04B104B304B504B704B904BB04BD04BF04C204C404C604C804CA04CC04CE04CF04D104D304D504D704D904DB04DD04DF04E104E304E504E704E904EB04ED04EF04F104F304F504F704F904FB04FD04FF05010503050505070509050B050D050F05110513051505170519051B051D051F0521052305250561-05871D00-1D2B1D62-1D771D79-1D9A1E011E031E051E071E091E0B1E0D1E0F1E111E131E151E171E191E1B1E1D1E1F1E211E231E251E271E291E2B1E2D1E2F1E311E331E351E371E391E3B1E3D1E3F1E411E431E451E471E491E4B1E4D1E4F1E511E531E551E571E591E5B1E5D1E5F1E611E631E651E671E691E6B1E6D1E6F1E711E731E751E771E791E7B1E7D1E7F1E811E831E851E871E891E8B1E8D1E8F1E911E931E95-1E9D1E9F1EA11EA31EA51EA71EA91EAB1EAD1EAF1EB11EB31EB51EB71EB91EBB1EBD1EBF1EC11EC31EC51EC71EC91ECB1ECD1ECF1ED11ED31ED51ED71ED91EDB1EDD1EDF1EE11EE31EE51EE71EE91EEB1EED1EEF1EF11EF31EF51EF71EF91EFB1EFD1EFF-1F071F10-1F151F20-1F271F30-1F371F40-1F451F50-1F571F60-1F671F70-1F7D1F80-1F871F90-1F971FA0-1FA71FB0-1FB41FB61FB71FBE1FC2-1FC41FC61FC71FD0-1FD31FD61FD71FE0-1FE71FF2-1FF41FF61FF7210A210E210F2113212F21342139213C213D2146-2149214E21842C30-2C5E2C612C652C662C682C6A2C6C2C712C732C742C76-2C7C2C812C832C852C872C892C8B2C8D2C8F2C912C932C952C972C992C9B2C9D2C9F2CA12CA32CA52CA72CA92CAB2CAD2CAF2CB12CB32CB52CB72CB92CBB2CBD2CBF2CC12CC32CC52CC72CC92CCB2CCD2CCF2CD12CD32CD52CD72CD92CDB2CDD2CDF2CE12CE32CE42CEC2CEE2D00-2D25A641A643A645A647A649A64BA64DA64FA651A653A655A657A659A65BA65DA65FA663A665A667A669A66BA66DA681A683A685A687A689A68BA68DA68FA691A693A695A697A723A725A727A729A72BA72DA72F-A731A733A735A737A739A73BA73DA73FA741A743A745A747A749A74BA74DA74FA751A753A755A757A759A75BA75DA75FA761A763A765A767A769A76BA76DA76FA771-A778A77AA77CA77FA781A783A785A787A78CFB00-FB06FB13-FB17FF41-FF5A",Lu:"0041-005A00C0-00D600D8-00DE01000102010401060108010A010C010E01100112011401160118011A011C011E01200122012401260128012A012C012E01300132013401360139013B013D013F0141014301450147014A014C014E01500152015401560158015A015C015E01600162016401660168016A016C016E017001720174017601780179017B017D018101820184018601870189-018B018E-0191019301940196-0198019C019D019F01A001A201A401A601A701A901AC01AE01AF01B1-01B301B501B701B801BC01C401C701CA01CD01CF01D101D301D501D701D901DB01DE01E001E201E401E601E801EA01EC01EE01F101F401F6-01F801FA01FC01FE02000202020402060208020A020C020E02100212021402160218021A021C021E02200222022402260228022A022C022E02300232023A023B023D023E02410243-02460248024A024C024E03700372037603860388-038A038C038E038F0391-03A103A3-03AB03CF03D2-03D403D803DA03DC03DE03E003E203E403E603E803EA03EC03EE03F403F703F903FA03FD-042F04600462046404660468046A046C046E04700472047404760478047A047C047E0480048A048C048E04900492049404960498049A049C049E04A004A204A404A604A804AA04AC04AE04B004B204B404B604B804BA04BC04BE04C004C104C304C504C704C904CB04CD04D004D204D404D604D804DA04DC04DE04E004E204E404E604E804EA04EC04EE04F004F204F404F604F804FA04FC04FE05000502050405060508050A050C050E05100512051405160518051A051C051E0520052205240531-055610A0-10C51E001E021E041E061E081E0A1E0C1E0E1E101E121E141E161E181E1A1E1C1E1E1E201E221E241E261E281E2A1E2C1E2E1E301E321E341E361E381E3A1E3C1E3E1E401E421E441E461E481E4A1E4C1E4E1E501E521E541E561E581E5A1E5C1E5E1E601E621E641E661E681E6A1E6C1E6E1E701E721E741E761E781E7A1E7C1E7E1E801E821E841E861E881E8A1E8C1E8E1E901E921E941E9E1EA01EA21EA41EA61EA81EAA1EAC1EAE1EB01EB21EB41EB61EB81EBA1EBC1EBE1EC01EC21EC41EC61EC81ECA1ECC1ECE1ED01ED21ED41ED61ED81EDA1EDC1EDE1EE01EE21EE41EE61EE81EEA1EEC1EEE1EF01EF21EF41EF61EF81EFA1EFC1EFE1F08-1F0F1F18-1F1D1F28-1F2F1F38-1F3F1F48-1F4D1F591F5B1F5D1F5F1F68-1F6F1FB8-1FBB1FC8-1FCB1FD8-1FDB1FE8-1FEC1FF8-1FFB21022107210B-210D2110-211221152119-211D212421262128212A-212D2130-2133213E213F214521832C00-2C2E2C602C62-2C642C672C692C6B2C6D-2C702C722C752C7E-2C802C822C842C862C882C8A2C8C2C8E2C902C922C942C962C982C9A2C9C2C9E2CA02CA22CA42CA62CA82CAA2CAC2CAE2CB02CB22CB42CB62CB82CBA2CBC2CBE2CC02CC22CC42CC62CC82CCA2CCC2CCE2CD02CD22CD42CD62CD82CDA2CDC2CDE2CE02CE22CEB2CEDA640A642A644A646A648A64AA64CA64EA650A652A654A656A658A65AA65CA65EA662A664A666A668A66AA66CA680A682A684A686A688A68AA68CA68EA690A692A694A696A722A724A726A728A72AA72CA72EA732A734A736A738A73AA73CA73EA740A742A744A746A748A74AA74CA74EA750A752A754A756A758A75AA75CA75EA760A762A764A766A768A76AA76CA76EA779A77BA77DA77EA780A782A784A786A78BFF21-FF3A",Lt:"01C501C801CB01F21F88-1F8F1F98-1F9F1FA8-1FAF1FBC1FCC1FFC",Lm:"02B0-02C102C6-02D102E0-02E402EC02EE0374037A0559064006E506E607F407F507FA081A0824082809710E460EC610FC17D718431AA71C78-1C7D1D2C-1D611D781D9B-1DBF2071207F2090-20942C7D2D6F2E2F30053031-3035303B309D309E30FC-30FEA015A4F8-A4FDA60CA67FA717-A71FA770A788A9CFAA70AADDFF70FF9EFF9F",Lo:"01BB01C0-01C3029405D0-05EA05F0-05F20621-063F0641-064A066E066F0671-06D306D506EE06EF06FA-06FC06FF07100712-072F074D-07A507B107CA-07EA0800-08150904-0939093D09500958-096109720979-097F0985-098C098F09900993-09A809AA-09B009B209B6-09B909BD09CE09DC09DD09DF-09E109F009F10A05-0A0A0A0F0A100A13-0A280A2A-0A300A320A330A350A360A380A390A59-0A5C0A5E0A72-0A740A85-0A8D0A8F-0A910A93-0AA80AAA-0AB00AB20AB30AB5-0AB90ABD0AD00AE00AE10B05-0B0C0B0F0B100B13-0B280B2A-0B300B320B330B35-0B390B3D0B5C0B5D0B5F-0B610B710B830B85-0B8A0B8E-0B900B92-0B950B990B9A0B9C0B9E0B9F0BA30BA40BA8-0BAA0BAE-0BB90BD00C05-0C0C0C0E-0C100C12-0C280C2A-0C330C35-0C390C3D0C580C590C600C610C85-0C8C0C8E-0C900C92-0CA80CAA-0CB30CB5-0CB90CBD0CDE0CE00CE10D05-0D0C0D0E-0D100D12-0D280D2A-0D390D3D0D600D610D7A-0D7F0D85-0D960D9A-0DB10DB3-0DBB0DBD0DC0-0DC60E01-0E300E320E330E40-0E450E810E820E840E870E880E8A0E8D0E94-0E970E99-0E9F0EA1-0EA30EA50EA70EAA0EAB0EAD-0EB00EB20EB30EBD0EC0-0EC40EDC0EDD0F000F40-0F470F49-0F6C0F88-0F8B1000-102A103F1050-1055105A-105D106110651066106E-10701075-1081108E10D0-10FA1100-1248124A-124D1250-12561258125A-125D1260-1288128A-128D1290-12B012B2-12B512B8-12BE12C012C2-12C512C8-12D612D8-13101312-13151318-135A1380-138F13A0-13F41401-166C166F-167F1681-169A16A0-16EA1700-170C170E-17111720-17311740-17511760-176C176E-17701780-17B317DC1820-18421844-18771880-18A818AA18B0-18F51900-191C1950-196D1970-19741980-19AB19C1-19C71A00-1A161A20-1A541B05-1B331B45-1B4B1B83-1BA01BAE1BAF1C00-1C231C4D-1C4F1C5A-1C771CE9-1CEC1CEE-1CF12135-21382D30-2D652D80-2D962DA0-2DA62DA8-2DAE2DB0-2DB62DB8-2DBE2DC0-2DC62DC8-2DCE2DD0-2DD62DD8-2DDE3006303C3041-3096309F30A1-30FA30FF3105-312D3131-318E31A0-31B731F0-31FF3400-4DB54E00-9FCBA000-A014A016-A48CA4D0-A4F7A500-A60BA610-A61FA62AA62BA66EA6A0-A6E5A7FB-A801A803-A805A807-A80AA80C-A822A840-A873A882-A8B3A8F2-A8F7A8FBA90A-A925A930-A946A960-A97CA984-A9B2AA00-AA28AA40-AA42AA44-AA4BAA60-AA6FAA71-AA76AA7AAA80-AAAFAAB1AAB5AAB6AAB9-AABDAAC0AAC2AADBAADCABC0-ABE2AC00-D7A3D7B0-D7C6D7CB-D7FBF900-FA2DFA30-FA6DFA70-FAD9FB1DFB1F-FB28FB2A-FB36FB38-FB3CFB3EFB40FB41FB43FB44FB46-FBB1FBD3-FD3DFD50-FD8FFD92-FDC7FDF0-FDFBFE70-FE74FE76-FEFCFF66-FF6FFF71-FF9DFFA0-FFBEFFC2-FFC7FFCA-FFCFFFD2-FFD7FFDA-FFDC",M:"0300-036F0483-04890591-05BD05BF05C105C205C405C505C70610-061A064B-065E067006D6-06DC06DE-06E406E706E806EA-06ED07110730-074A07A6-07B007EB-07F30816-0819081B-08230825-08270829-082D0900-0903093C093E-094E0951-0955096209630981-098309BC09BE-09C409C709C809CB-09CD09D709E209E30A01-0A030A3C0A3E-0A420A470A480A4B-0A4D0A510A700A710A750A81-0A830ABC0ABE-0AC50AC7-0AC90ACB-0ACD0AE20AE30B01-0B030B3C0B3E-0B440B470B480B4B-0B4D0B560B570B620B630B820BBE-0BC20BC6-0BC80BCA-0BCD0BD70C01-0C030C3E-0C440C46-0C480C4A-0C4D0C550C560C620C630C820C830CBC0CBE-0CC40CC6-0CC80CCA-0CCD0CD50CD60CE20CE30D020D030D3E-0D440D46-0D480D4A-0D4D0D570D620D630D820D830DCA0DCF-0DD40DD60DD8-0DDF0DF20DF30E310E34-0E3A0E47-0E4E0EB10EB4-0EB90EBB0EBC0EC8-0ECD0F180F190F350F370F390F3E0F3F0F71-0F840F860F870F90-0F970F99-0FBC0FC6102B-103E1056-1059105E-10601062-10641067-106D1071-10741082-108D108F109A-109D135F1712-17141732-1734175217531772177317B6-17D317DD180B-180D18A91920-192B1930-193B19B0-19C019C819C91A17-1A1B1A55-1A5E1A60-1A7C1A7F1B00-1B041B34-1B441B6B-1B731B80-1B821BA1-1BAA1C24-1C371CD0-1CD21CD4-1CE81CED1CF21DC0-1DE61DFD-1DFF20D0-20F02CEF-2CF12DE0-2DFF302A-302F3099309AA66F-A672A67CA67DA6F0A6F1A802A806A80BA823-A827A880A881A8B4-A8C4A8E0-A8F1A926-A92DA947-A953A980-A983A9B3-A9C0AA29-AA36AA43AA4CAA4DAA7BAAB0AAB2-AAB4AAB7AAB8AABEAABFAAC1ABE3-ABEAABECABEDFB1EFE00-FE0FFE20-FE26",Mn:"0300-036F0483-04870591-05BD05BF05C105C205C405C505C70610-061A064B-065E067006D6-06DC06DF-06E406E706E806EA-06ED07110730-074A07A6-07B007EB-07F30816-0819081B-08230825-08270829-082D0900-0902093C0941-0948094D0951-095509620963098109BC09C1-09C409CD09E209E30A010A020A3C0A410A420A470A480A4B-0A4D0A510A700A710A750A810A820ABC0AC1-0AC50AC70AC80ACD0AE20AE30B010B3C0B3F0B41-0B440B4D0B560B620B630B820BC00BCD0C3E-0C400C46-0C480C4A-0C4D0C550C560C620C630CBC0CBF0CC60CCC0CCD0CE20CE30D41-0D440D4D0D620D630DCA0DD2-0DD40DD60E310E34-0E3A0E47-0E4E0EB10EB4-0EB90EBB0EBC0EC8-0ECD0F180F190F350F370F390F71-0F7E0F80-0F840F860F870F90-0F970F99-0FBC0FC6102D-10301032-10371039103A103D103E10581059105E-10601071-1074108210851086108D109D135F1712-17141732-1734175217531772177317B7-17BD17C617C9-17D317DD180B-180D18A91920-19221927192819321939-193B1A171A181A561A58-1A5E1A601A621A65-1A6C1A73-1A7C1A7F1B00-1B031B341B36-1B3A1B3C1B421B6B-1B731B801B811BA2-1BA51BA81BA91C2C-1C331C361C371CD0-1CD21CD4-1CE01CE2-1CE81CED1DC0-1DE61DFD-1DFF20D0-20DC20E120E5-20F02CEF-2CF12DE0-2DFF302A-302F3099309AA66FA67CA67DA6F0A6F1A802A806A80BA825A826A8C4A8E0-A8F1A926-A92DA947-A951A980-A982A9B3A9B6-A9B9A9BCAA29-AA2EAA31AA32AA35AA36AA43AA4CAAB0AAB2-AAB4AAB7AAB8AABEAABFAAC1ABE5ABE8ABEDFB1EFE00-FE0FFE20-FE26",Mc:"0903093E-09400949-094C094E0982098309BE-09C009C709C809CB09CC09D70A030A3E-0A400A830ABE-0AC00AC90ACB0ACC0B020B030B3E0B400B470B480B4B0B4C0B570BBE0BBF0BC10BC20BC6-0BC80BCA-0BCC0BD70C01-0C030C41-0C440C820C830CBE0CC0-0CC40CC70CC80CCA0CCB0CD50CD60D020D030D3E-0D400D46-0D480D4A-0D4C0D570D820D830DCF-0DD10DD8-0DDF0DF20DF30F3E0F3F0F7F102B102C10311038103B103C105610571062-10641067-106D108310841087-108C108F109A-109C17B617BE-17C517C717C81923-19261929-192B193019311933-193819B0-19C019C819C91A19-1A1B1A551A571A611A631A641A6D-1A721B041B351B3B1B3D-1B411B431B441B821BA11BA61BA71BAA1C24-1C2B1C341C351CE11CF2A823A824A827A880A881A8B4-A8C3A952A953A983A9B4A9B5A9BAA9BBA9BD-A9C0AA2FAA30AA33AA34AA4DAA7BABE3ABE4ABE6ABE7ABE9ABEAABEC",Me:"0488048906DE20DD-20E020E2-20E4A670-A672",N:"0030-003900B200B300B900BC-00BE0660-066906F0-06F907C0-07C90966-096F09E6-09EF09F4-09F90A66-0A6F0AE6-0AEF0B66-0B6F0BE6-0BF20C66-0C6F0C78-0C7E0CE6-0CEF0D66-0D750E50-0E590ED0-0ED90F20-0F331040-10491090-10991369-137C16EE-16F017E0-17E917F0-17F91810-18191946-194F19D0-19DA1A80-1A891A90-1A991B50-1B591BB0-1BB91C40-1C491C50-1C5920702074-20792080-20892150-21822185-21892460-249B24EA-24FF2776-27932CFD30073021-30293038-303A3192-31953220-32293251-325F3280-328932B1-32BFA620-A629A6E6-A6EFA830-A835A8D0-A8D9A900-A909A9D0-A9D9AA50-AA59ABF0-ABF9FF10-FF19",Nd:"0030-00390660-066906F0-06F907C0-07C90966-096F09E6-09EF0A66-0A6F0AE6-0AEF0B66-0B6F0BE6-0BEF0C66-0C6F0CE6-0CEF0D66-0D6F0E50-0E590ED0-0ED90F20-0F291040-10491090-109917E0-17E91810-18191946-194F19D0-19DA1A80-1A891A90-1A991B50-1B591BB0-1BB91C40-1C491C50-1C59A620-A629A8D0-A8D9A900-A909A9D0-A9D9AA50-AA59ABF0-ABF9FF10-FF19",Nl:"16EE-16F02160-21822185-218830073021-30293038-303AA6E6-A6EF",No:"00B200B300B900BC-00BE09F4-09F90BF0-0BF20C78-0C7E0D70-0D750F2A-0F331369-137C17F0-17F920702074-20792080-20892150-215F21892460-249B24EA-24FF2776-27932CFD3192-31953220-32293251-325F3280-328932B1-32BFA830-A835",P:"0021-00230025-002A002C-002F003A003B003F0040005B-005D005F007B007D00A100AB00B700BB00BF037E0387055A-055F0589058A05BE05C005C305C605F305F40609060A060C060D061B061E061F066A-066D06D40700-070D07F7-07F90830-083E0964096509700DF40E4F0E5A0E5B0F04-0F120F3A-0F3D0F850FD0-0FD4104A-104F10FB1361-13681400166D166E169B169C16EB-16ED1735173617D4-17D617D8-17DA1800-180A1944194519DE19DF1A1E1A1F1AA0-1AA61AA8-1AAD1B5A-1B601C3B-1C3F1C7E1C7F1CD32010-20272030-20432045-20512053-205E207D207E208D208E2329232A2768-277527C527C627E6-27EF2983-299829D8-29DB29FC29FD2CF9-2CFC2CFE2CFF2E00-2E2E2E302E313001-30033008-30113014-301F3030303D30A030FBA4FEA4FFA60D-A60FA673A67EA6F2-A6F7A874-A877A8CEA8CFA8F8-A8FAA92EA92FA95FA9C1-A9CDA9DEA9DFAA5C-AA5FAADEAADFABEBFD3EFD3FFE10-FE19FE30-FE52FE54-FE61FE63FE68FE6AFE6BFF01-FF03FF05-FF0AFF0C-FF0FFF1AFF1BFF1FFF20FF3B-FF3DFF3FFF5BFF5DFF5F-FF65",Pd:"002D058A05BE140018062010-20152E172E1A301C303030A0FE31FE32FE58FE63FF0D",Ps:"0028005B007B0F3A0F3C169B201A201E2045207D208D23292768276A276C276E27702772277427C527E627E827EA27EC27EE2983298529872989298B298D298F299129932995299729D829DA29FC2E222E242E262E283008300A300C300E3010301430163018301A301DFD3EFE17FE35FE37FE39FE3BFE3DFE3FFE41FE43FE47FE59FE5BFE5DFF08FF3BFF5BFF5FFF62",Pe:"0029005D007D0F3B0F3D169C2046207E208E232A2769276B276D276F27712773277527C627E727E927EB27ED27EF298429862988298A298C298E2990299229942996299829D929DB29FD2E232E252E272E293009300B300D300F3011301530173019301B301E301FFD3FFE18FE36FE38FE3AFE3CFE3EFE40FE42FE44FE48FE5AFE5CFE5EFF09FF3DFF5DFF60FF63",Pi:"00AB2018201B201C201F20392E022E042E092E0C2E1C2E20",Pf:"00BB2019201D203A2E032E052E0A2E0D2E1D2E21",Pc:"005F203F20402054FE33FE34FE4D-FE4FFF3F",Po:"0021-00230025-0027002A002C002E002F003A003B003F0040005C00A100B700BF037E0387055A-055F058905C005C305C605F305F40609060A060C060D061B061E061F066A-066D06D40700-070D07F7-07F90830-083E0964096509700DF40E4F0E5A0E5B0F04-0F120F850FD0-0FD4104A-104F10FB1361-1368166D166E16EB-16ED1735173617D4-17D617D8-17DA1800-18051807-180A1944194519DE19DF1A1E1A1F1AA0-1AA61AA8-1AAD1B5A-1B601C3B-1C3F1C7E1C7F1CD3201620172020-20272030-2038203B-203E2041-20432047-205120532055-205E2CF9-2CFC2CFE2CFF2E002E012E06-2E082E0B2E0E-2E162E182E192E1B2E1E2E1F2E2A-2E2E2E302E313001-3003303D30FBA4FEA4FFA60D-A60FA673A67EA6F2-A6F7A874-A877A8CEA8CFA8F8-A8FAA92EA92FA95FA9C1-A9CDA9DEA9DFAA5C-AA5FAADEAADFABEBFE10-FE16FE19FE30FE45FE46FE49-FE4CFE50-FE52FE54-FE57FE5F-FE61FE68FE6AFE6BFF01-FF03FF05-FF07FF0AFF0CFF0EFF0FFF1AFF1BFF1FFF20FF3CFF61FF64FF65",S:"0024002B003C-003E005E0060007C007E00A2-00A900AC00AE-00B100B400B600B800D700F702C2-02C502D2-02DF02E5-02EB02ED02EF-02FF03750384038503F604820606-0608060B060E060F06E906FD06FE07F609F209F309FA09FB0AF10B700BF3-0BFA0C7F0CF10CF20D790E3F0F01-0F030F13-0F170F1A-0F1F0F340F360F380FBE-0FC50FC7-0FCC0FCE0FCF0FD5-0FD8109E109F13601390-139917DB194019E0-19FF1B61-1B6A1B74-1B7C1FBD1FBF-1FC11FCD-1FCF1FDD-1FDF1FED-1FEF1FFD1FFE20442052207A-207C208A-208C20A0-20B8210021012103-21062108210921142116-2118211E-2123212521272129212E213A213B2140-2144214A-214D214F2190-2328232B-23E82400-24262440-244A249C-24E92500-26CD26CF-26E126E326E8-26FF2701-27042706-2709270C-27272729-274B274D274F-27522756-275E2761-276727942798-27AF27B1-27BE27C0-27C427C7-27CA27CC27D0-27E527F0-29822999-29D729DC-29FB29FE-2B4C2B50-2B592CE5-2CEA2E80-2E992E9B-2EF32F00-2FD52FF0-2FFB300430123013302030363037303E303F309B309C319031913196-319F31C0-31E33200-321E322A-32503260-327F328A-32B032C0-32FE3300-33FF4DC0-4DFFA490-A4C6A700-A716A720A721A789A78AA828-A82BA836-A839AA77-AA79FB29FDFCFDFDFE62FE64-FE66FE69FF04FF0BFF1C-FF1EFF3EFF40FF5CFF5EFFE0-FFE6FFE8-FFEEFFFCFFFD",Sm:"002B003C-003E007C007E00AC00B100D700F703F60606-060820442052207A-207C208A-208C2140-2144214B2190-2194219A219B21A021A321A621AE21CE21CF21D221D421F4-22FF2308-230B23202321237C239B-23B323DC-23E125B725C125F8-25FF266F27C0-27C427C7-27CA27CC27D0-27E527F0-27FF2900-29822999-29D729DC-29FB29FE-2AFF2B30-2B442B47-2B4CFB29FE62FE64-FE66FF0BFF1C-FF1EFF5CFF5EFFE2FFE9-FFEC",Sc:"002400A2-00A5060B09F209F309FB0AF10BF90E3F17DB20A0-20B8A838FDFCFE69FF04FFE0FFE1FFE5FFE6",Sk:"005E006000A800AF00B400B802C2-02C502D2-02DF02E5-02EB02ED02EF-02FF0375038403851FBD1FBF-1FC11FCD-1FCF1FDD-1FDF1FED-1FEF1FFD1FFE309B309CA700-A716A720A721A789A78AFF3EFF40FFE3",So:"00A600A700A900AE00B000B60482060E060F06E906FD06FE07F609FA0B700BF3-0BF80BFA0C7F0CF10CF20D790F01-0F030F13-0F170F1A-0F1F0F340F360F380FBE-0FC50FC7-0FCC0FCE0FCF0FD5-0FD8109E109F13601390-1399194019E0-19FF1B61-1B6A1B74-1B7C210021012103-21062108210921142116-2118211E-2123212521272129212E213A213B214A214C214D214F2195-2199219C-219F21A121A221A421A521A7-21AD21AF-21CD21D021D121D321D5-21F32300-2307230C-231F2322-2328232B-237B237D-239A23B4-23DB23E2-23E82400-24262440-244A249C-24E92500-25B625B8-25C025C2-25F72600-266E2670-26CD26CF-26E126E326E8-26FF2701-27042706-2709270C-27272729-274B274D274F-27522756-275E2761-276727942798-27AF27B1-27BE2800-28FF2B00-2B2F2B452B462B50-2B592CE5-2CEA2E80-2E992E9B-2EF32F00-2FD52FF0-2FFB300430123013302030363037303E303F319031913196-319F31C0-31E33200-321E322A-32503260-327F328A-32B032C0-32FE3300-33FF4DC0-4DFFA490-A4C6A828-A82BA836A837A839AA77-AA79FDFDFFE4FFE8FFEDFFEEFFFCFFFD",Z:"002000A01680180E2000-200A20282029202F205F3000",Zs:"002000A01680180E2000-200A202F205F3000",Zl:"2028",Zp:"2029",C:"0000-001F007F-009F00AD03780379037F-0383038B038D03A20526-05300557055805600588058B-059005C8-05CF05EB-05EF05F5-0605061C061D0620065F06DD070E070F074B074C07B2-07BF07FB-07FF082E082F083F-08FF093A093B094F095609570973-097809800984098D098E0991099209A909B109B3-09B509BA09BB09C509C609C909CA09CF-09D609D8-09DB09DE09E409E509FC-0A000A040A0B-0A0E0A110A120A290A310A340A370A3A0A3B0A3D0A43-0A460A490A4A0A4E-0A500A52-0A580A5D0A5F-0A650A76-0A800A840A8E0A920AA90AB10AB40ABA0ABB0AC60ACA0ACE0ACF0AD1-0ADF0AE40AE50AF00AF2-0B000B040B0D0B0E0B110B120B290B310B340B3A0B3B0B450B460B490B4A0B4E-0B550B58-0B5B0B5E0B640B650B72-0B810B840B8B-0B8D0B910B96-0B980B9B0B9D0BA0-0BA20BA5-0BA70BAB-0BAD0BBA-0BBD0BC3-0BC50BC90BCE0BCF0BD1-0BD60BD8-0BE50BFB-0C000C040C0D0C110C290C340C3A-0C3C0C450C490C4E-0C540C570C5A-0C5F0C640C650C70-0C770C800C810C840C8D0C910CA90CB40CBA0CBB0CC50CC90CCE-0CD40CD7-0CDD0CDF0CE40CE50CF00CF3-0D010D040D0D0D110D290D3A-0D3C0D450D490D4E-0D560D58-0D5F0D640D650D76-0D780D800D810D840D97-0D990DB20DBC0DBE0DBF0DC7-0DC90DCB-0DCE0DD50DD70DE0-0DF10DF5-0E000E3B-0E3E0E5C-0E800E830E850E860E890E8B0E8C0E8E-0E930E980EA00EA40EA60EA80EA90EAC0EBA0EBE0EBF0EC50EC70ECE0ECF0EDA0EDB0EDE-0EFF0F480F6D-0F700F8C-0F8F0F980FBD0FCD0FD9-0FFF10C6-10CF10FD-10FF1249124E124F12571259125E125F1289128E128F12B112B612B712BF12C112C612C712D7131113161317135B-135E137D-137F139A-139F13F5-13FF169D-169F16F1-16FF170D1715-171F1737-173F1754-175F176D17711774-177F17B417B517DE17DF17EA-17EF17FA-17FF180F181A-181F1878-187F18AB-18AF18F6-18FF191D-191F192C-192F193C-193F1941-1943196E196F1975-197F19AC-19AF19CA-19CF19DB-19DD1A1C1A1D1A5F1A7D1A7E1A8A-1A8F1A9A-1A9F1AAE-1AFF1B4C-1B4F1B7D-1B7F1BAB-1BAD1BBA-1BFF1C38-1C3A1C4A-1C4C1C80-1CCF1CF3-1CFF1DE7-1DFC1F161F171F1E1F1F1F461F471F4E1F4F1F581F5A1F5C1F5E1F7E1F7F1FB51FC51FD41FD51FDC1FF01FF11FF51FFF200B-200F202A-202E2060-206F20722073208F2095-209F20B9-20CF20F1-20FF218A-218F23E9-23FF2427-243F244B-245F26CE26E226E4-26E727002705270A270B2728274C274E2753-2755275F27602795-279727B027BF27CB27CD-27CF2B4D-2B4F2B5A-2BFF2C2F2C5F2CF2-2CF82D26-2D2F2D66-2D6E2D70-2D7F2D97-2D9F2DA72DAF2DB72DBF2DC72DCF2DD72DDF2E32-2E7F2E9A2EF4-2EFF2FD6-2FEF2FFC-2FFF3040309730983100-3104312E-3130318F31B8-31BF31E4-31EF321F32FF4DB6-4DBF9FCC-9FFFA48D-A48FA4C7-A4CFA62C-A63FA660A661A674-A67BA698-A69FA6F8-A6FFA78D-A7FAA82C-A82FA83A-A83FA878-A87FA8C5-A8CDA8DA-A8DFA8FC-A8FFA954-A95EA97D-A97FA9CEA9DA-A9DDA9E0-A9FFAA37-AA3FAA4EAA4FAA5AAA5BAA7C-AA7FAAC3-AADAAAE0-ABBFABEEABEFABFA-ABFFD7A4-D7AFD7C7-D7CAD7FC-F8FFFA2EFA2FFA6EFA6FFADA-FAFFFB07-FB12FB18-FB1CFB37FB3DFB3FFB42FB45FBB2-FBD2FD40-FD4FFD90FD91FDC8-FDEFFDFEFDFFFE1A-FE1FFE27-FE2FFE53FE67FE6C-FE6FFE75FEFD-FF00FFBF-FFC1FFC8FFC9FFD0FFD1FFD8FFD9FFDD-FFDFFFE7FFEF-FFFBFFFEFFFF",Cc:"0000-001F007F-009F",Cf:"00AD0600-060306DD070F17B417B5200B-200F202A-202E2060-2064206A-206FFEFFFFF9-FFFB",Co:"E000-F8FF",Cs:"D800-DFFF",Cn:"03780379037F-0383038B038D03A20526-05300557055805600588058B-059005C8-05CF05EB-05EF05F5-05FF06040605061C061D0620065F070E074B074C07B2-07BF07FB-07FF082E082F083F-08FF093A093B094F095609570973-097809800984098D098E0991099209A909B109B3-09B509BA09BB09C509C609C909CA09CF-09D609D8-09DB09DE09E409E509FC-0A000A040A0B-0A0E0A110A120A290A310A340A370A3A0A3B0A3D0A43-0A460A490A4A0A4E-0A500A52-0A580A5D0A5F-0A650A76-0A800A840A8E0A920AA90AB10AB40ABA0ABB0AC60ACA0ACE0ACF0AD1-0ADF0AE40AE50AF00AF2-0B000B040B0D0B0E0B110B120B290B310B340B3A0B3B0B450B460B490B4A0B4E-0B550B58-0B5B0B5E0B640B650B72-0B810B840B8B-0B8D0B910B96-0B980B9B0B9D0BA0-0BA20BA5-0BA70BAB-0BAD0BBA-0BBD0BC3-0BC50BC90BCE0BCF0BD1-0BD60BD8-0BE50BFB-0C000C040C0D0C110C290C340C3A-0C3C0C450C490C4E-0C540C570C5A-0C5F0C640C650C70-0C770C800C810C840C8D0C910CA90CB40CBA0CBB0CC50CC90CCE-0CD40CD7-0CDD0CDF0CE40CE50CF00CF3-0D010D040D0D0D110D290D3A-0D3C0D450D490D4E-0D560D58-0D5F0D640D650D76-0D780D800D810D840D97-0D990DB20DBC0DBE0DBF0DC7-0DC90DCB-0DCE0DD50DD70DE0-0DF10DF5-0E000E3B-0E3E0E5C-0E800E830E850E860E890E8B0E8C0E8E-0E930E980EA00EA40EA60EA80EA90EAC0EBA0EBE0EBF0EC50EC70ECE0ECF0EDA0EDB0EDE-0EFF0F480F6D-0F700F8C-0F8F0F980FBD0FCD0FD9-0FFF10C6-10CF10FD-10FF1249124E124F12571259125E125F1289128E128F12B112B612B712BF12C112C612C712D7131113161317135B-135E137D-137F139A-139F13F5-13FF169D-169F16F1-16FF170D1715-171F1737-173F1754-175F176D17711774-177F17DE17DF17EA-17EF17FA-17FF180F181A-181F1878-187F18AB-18AF18F6-18FF191D-191F192C-192F193C-193F1941-1943196E196F1975-197F19AC-19AF19CA-19CF19DB-19DD1A1C1A1D1A5F1A7D1A7E1A8A-1A8F1A9A-1A9F1AAE-1AFF1B4C-1B4F1B7D-1B7F1BAB-1BAD1BBA-1BFF1C38-1C3A1C4A-1C4C1C80-1CCF1CF3-1CFF1DE7-1DFC1F161F171F1E1F1F1F461F471F4E1F4F1F581F5A1F5C1F5E1F7E1F7F1FB51FC51FD41FD51FDC1FF01FF11FF51FFF2065-206920722073208F2095-209F20B9-20CF20F1-20FF218A-218F23E9-23FF2427-243F244B-245F26CE26E226E4-26E727002705270A270B2728274C274E2753-2755275F27602795-279727B027BF27CB27CD-27CF2B4D-2B4F2B5A-2BFF2C2F2C5F2CF2-2CF82D26-2D2F2D66-2D6E2D70-2D7F2D97-2D9F2DA72DAF2DB72DBF2DC72DCF2DD72DDF2E32-2E7F2E9A2EF4-2EFF2FD6-2FEF2FFC-2FFF3040309730983100-3104312E-3130318F31B8-31BF31E4-31EF321F32FF4DB6-4DBF9FCC-9FFFA48D-A48FA4C7-A4CFA62C-A63FA660A661A674-A67BA698-A69FA6F8-A6FFA78D-A7FAA82C-A82FA83A-A83FA878-A87FA8C5-A8CDA8DA-A8DFA8FC-A8FFA954-A95EA97D-A97FA9CEA9DA-A9DDA9E0-A9FFAA37-AA3FAA4EAA4FAA5AAA5BAA7C-AA7FAAC3-AADAAAE0-ABBFABEEABEFABFA-ABFFD7A4-D7AFD7C7-D7CAD7FC-D7FFFA2EFA2FFA6EFA6FFADA-FAFFFB07-FB12FB18-FB1CFB37FB3DFB3FFB42FB45FBB2-FBD2FD40-FD4FFD90FD91FDC8-FDEFFDFEFDFFFE1A-FE1FFE27-FE2FFE53FE67FE6C-FE6FFE75FEFDFEFEFF00FFBF-FFC1FFC8FFC9FFD0FFD1FFD8FFD9FFDD-FFDFFFE7FFEF-FFF8FFFEFFFF"})}),define("ace/mode/text",["require","exports","module","ace/tokenizer","ace/mode/text_highlight_rules","ace/mode/behaviour/cstyle","ace/unicode","ace/lib/lang","ace/token_iterator","ace/range"],function(e,t,n){"use strict";var r=e("../tokenizer").Tokenizer,i=e("./text_highlight_rules").TextHighlightRules,s=e("./behaviour/cstyle").CstyleBehaviour,o=e("../unicode"),u=e("../lib/lang"),a=e("../token_iterator").TokenIterator,f=e("../range").Range,l=function(){this.HighlightRules=i};(function(){this.$defaultBehaviour=new s,this.tokenRe=new RegExp("^["+o.packages.L+o.packages.Mn+o.packages.Mc+o.packages.Nd+o.packages.Pc+"\\$_]+","g"),this.nonTokenRe=new RegExp("^(?:[^"+o.packages.L+o.packages.Mn+o.packages.Mc+o.packages.Nd+o.packages.Pc+"\\$_]|\\s])+","g"),this.getTokenizer=function(){return this.$tokenizer||(this.$highlightRules=this.$highlightRules||new this.HighlightRules(this.$highlightRuleConfig),this.$tokenizer=new r(this.$highlightRules.getRules())),this.$tokenizer},this.lineCommentStart="",this.blockComment="",this.toggleCommentLines=function(e,t,n,r){function w(e){for(var t=n;t<=r;t++)e(i.getLine(t),t)}var i=t.doc,s=!0,o=!0,a=Infinity,f=t.getTabSize(),l=!1;if(!this.lineCommentStart){if(!this.blockComment)return!1;var c=this.blockComment.start,h=this.blockComment.end,p=new RegExp("^(\\s*)(?:"+u.escapeRegExp(c)+")"),d=new RegExp("(?:"+u.escapeRegExp(h)+")\\s*$"),v=function(e,t){if(g(e,t))return;if(!s||/\S/.test(e))i.insertInLine({row:t,column:e.length},h),i.insertInLine({row:t,column:a},c)},m=function(e,t){var n;(n=e.match(d))&&i.removeInLine(t,e.length-n[0].length,e.length),(n=e.match(p))&&i.removeInLine(t,n[1].length,n[0].length)},g=function(e,n){if(p.test(e))return!0;var r=t.getTokens(n);for(var i=0;i2?r%f!=f-1:r%f==0}}var E=Infinity;w(function(e,t){var n=e.search(/\S/);n!==-1?(ne.length&&(E=e.length)}),a==Infinity&&(a=E,s=!1,o=!1),l&&a%f!=0&&(a=Math.floor(a/f)*f),w(o?m:v)},this.toggleBlockComment=function(e,t,n,r){var i=this.blockComment;if(!i)return;!i.start&&i[0]&&(i=i[0]);var s=new a(t,r.row,r.column),o=s.getCurrentToken(),u=t.selection,l=t.selection.toOrientedRange(),c,h;if(o&&/comment/.test(o.type)){var p,d;while(o&&/comment/.test(o.type)){var v=o.value.indexOf(i.start);if(v!=-1){var m=s.getCurrentTokenRow(),g=s.getCurrentTokenColumn()+v;p=new f(m,g,m,g+i.start.length);break}o=s.stepBackward()}var s=new a(t,r.row,r.column),o=s.getCurrentToken();while(o&&/comment/.test(o.type)){var v=o.value.indexOf(i.end);if(v!=-1){var m=s.getCurrentTokenRow(),g=s.getCurrentTokenColumn()+v;d=new f(m,g,m,g+i.end.length);break}o=s.stepForward()}d&&t.remove(d),p&&(t.remove(p),c=p.start.row,h=-i.start.length)}else h=i.start.length,c=n.start.row,t.insert(n.end,i.end),t.insert(n.start,i.start);l.start.row==c&&(l.start.column+=h),l.end.row==c&&(l.end.column+=h),t.selection.fromOrientedRange(l)},this.getNextLineIndent=function(e,t,n){return this.$getIndent(t)},this.checkOutdent=function(e,t,n){return!1},this.autoOutdent=function(e,t,n){},this.$getIndent=function(e){return e.match(/^\s*/)[0]},this.createWorker=function(e){return null},this.createModeDelegates=function(e){this.$embeds=[],this.$modes={};for(var t in e)e[t]&&(this.$embeds.push(t),this.$modes[t]=new e[t]);var n=["toggleBlockComment","toggleCommentLines","getNextLineIndent","checkOutdent","autoOutdent","transformAction","getCompletions"];for(var t=0;t=0&&t.row=0&&t.column<=e[t.row].length}function s(e,t){t.action!="insert"&&t.action!="remove"&&r(t,"delta.action must be 'insert' or 'remove'"),t.lines instanceof Array||r(t,"delta.lines must be an Array"),(!t.start||!t.end)&&r(t,"delta.start/end must be an present");var n=t.start;i(e,t.start)||r(t,"delta.start must be contained in document");var s=t.end;t.action=="remove"&&!i(e,s)&&r(t,"delta.end must contained in document for 'remove' actions");var o=s.row-n.row,u=s.column-(o==0?n.column:0);(o!=t.lines.length-1||t.lines[o].length!=u)&&r(t,"delta.range must match delta lines")}t.applyDelta=function(e,t,n){var r=t.start.row,i=t.start.column,s=e[r]||"";switch(t.action){case"insert":var o=t.lines;if(o.length===1)e[r]=s.substring(0,i)+t.lines[0]+s.substring(i);else{var u=[r,1].concat(t.lines);e.splice.apply(e,u),e[r]=s.substring(0,i)+e[r],e[r+t.lines.length-1]+=s.substring(i)}break;case"remove":var a=t.end.column,f=t.end.row;r===f?e[r]=s.substring(0,i)+s.substring(a):e.splice(r,f-r+1,s.substring(0,i)+e[f].substring(a))}}}),define("ace/anchor",["require","exports","module","ace/lib/oop","ace/lib/event_emitter"],function(e,t,n){"use strict";var r=e("./lib/oop"),i=e("./lib/event_emitter").EventEmitter,s=t.Anchor=function(e,t,n){this.$onChange=this.onChange.bind(this),this.attach(e),typeof n=="undefined"?this.setPosition(t.row,t.column):this.setPosition(t,n)};(function(){function e(e,t,n){var r=n?e.column<=t.column:e.columnthis.row)return;var n=t(e,{row:this.row,column:this.column},this.$insertRight);this.setPosition(n.row,n.column,!0)},this.setPosition=function(e,t,n){var r;n?r={row:e,column:t}:r=this.$clipPositionToDocument(e,t);if(this.row==r.row&&this.column==r.column)return;var i={row:this.row,column:this.column};this.row=r.row,this.column=r.column,this._signal("change",{old:i,value:r})},this.detach=function(){this.document.removeEventListener("change",this.$onChange)},this.attach=function(e){this.document=e||this.document,this.document.on("change",this.$onChange)},this.$clipPositionToDocument=function(e,t){var n={};return e>=this.document.getLength()?(n.row=Math.max(0,this.document.getLength()-1),n.column=this.document.getLine(n.row).length):e<0?(n.row=0,n.column=0):(n.row=e,n.column=Math.min(this.document.getLine(n.row).length,Math.max(0,t))),t<0&&(n.column=0),n}}).call(s.prototype)}),define("ace/document",["require","exports","module","ace/lib/oop","ace/apply_delta","ace/lib/event_emitter","ace/range","ace/anchor"],function(e,t,n){"use strict";var r=e("./lib/oop"),i=e("./apply_delta").applyDelta,s=e("./lib/event_emitter").EventEmitter,o=e("./range").Range,u=e("./anchor").Anchor,a=function(e){this.$lines=[""],e.length===0?this.$lines=[""]:Array.isArray(e)?this.insertMergedLines({row:0,column:0},e):this.insert({row:0,column:0},e)};(function(){r.implement(this,s),this.setValue=function(e){var t=this.getLength()-1;this.remove(new o(0,0,t,this.getLine(t).length)),this.insert({row:0,column:0},e)},this.getValue=function(){return this.getAllLines().join(this.getNewLineCharacter())},this.createAnchor=function(e,t){return new u(this,e,t)},"aaa".split(/a/).length===0?this.$split=function(e){return e.replace(/\r\n|\r/g,"\n").split("\n")}:this.$split=function(e){return e.split(/\r\n|\r|\n/)},this.$detectNewLine=function(e){var t=e.match(/^.*?(\r\n|\r|\n)/m);this.$autoNewLine=t?t[1]:"\n",this._signal("changeNewLineMode")},this.getNewLineCharacter=function(){switch(this.$newLineMode){case"windows":return"\r\n";case"unix":return"\n";default:return this.$autoNewLine||"\n"}},this.$autoNewLine="",this.$newLineMode="auto",this.setNewLineMode=function(e){if(this.$newLineMode===e)return;this.$newLineMode=e,this._signal("changeNewLineMode")},this.getNewLineMode=function(){return this.$newLineMode},this.isNewLine=function(e){return e=="\r\n"||e=="\r"||e=="\n"},this.getLine=function(e){return this.$lines[e]||""},this.getLines=function(e,t){return this.$lines.slice(e,t+1)},this.getAllLines=function(){return this.getLines(0,this.getLength())},this.getLength=function(){return this.$lines.length},this.getTextRange=function(e){return this.getLinesForRange(e).join(this.getNewLineCharacter())},this.getLinesForRange=function(e){var t;if(e.start.row===e.end.row)t=[this.getLine(e.start.row).substring(e.start.column,e.end.column)];else{t=this.getLines(e.start.row,e.end.row),t[0]=(t[0]||"").substring(e.start.column);var n=t.length-1;e.end.row-e.start.row==n&&(t[n]=t[n].substring(0,e.end.column))}return t},this.insertLines=function(e,t){return console.warn("Use of document.insertLines is deprecated. Use the insertFullLines method instead."),this.insertFullLines(e,t)},this.removeLines=function(e,t){return console.warn("Use of document.removeLines is deprecated. Use the removeFullLines method instead."),this.removeFullLines(e,t)},this.insertNewLine=function(e){return console.warn("Use of document.insertNewLine is deprecated. Use insertMergedLines(position, ['', '']) instead."),this.insertMergedLines(e,["",""])},this.insert=function(e,t){return this.getLength()<=1&&this.$detectNewLine(t),this.insertMergedLines(e,this.$split(t))},this.insertInLine=function(e,t){var n=this.clippedPos(e.row,e.column),r=this.pos(e.row,e.column+t.length);return this.applyDelta({start:n,end:r,action:"insert",lines:[t]},!0),this.clonePos(r)},this.clippedPos=function(e,t){var n=this.getLength();e===undefined?e=n:e<0?e=0:e>=n&&(e=n-1,t=undefined);var r=this.getLine(e);return t==undefined&&(t=r.length),t=Math.min(Math.max(t,0),r.length),{row:e,column:t}},this.clonePos=function(e){return{row:e.row,column:e.column}},this.pos=function(e,t){return{row:e,column:t}},this.$clipPosition=function(e){var t=this.getLength();return e.row>=t?(e.row=Math.max(0,t-1),e.column=this.getLine(t-1).length):(e.row=Math.max(0,e.row),e.column=Math.min(Math.max(e.column,0),this.getLine(e.row).length)),e},this.insertFullLines=function(e,t){e=Math.min(Math.max(e,0),this.getLength());var n=0;e0,r=t=0&&this.applyDelta({start:this.pos(e,this.getLine(e).length),end:this.pos(e+1,0),action:"remove",lines:["",""]})},this.replace=function(e,t){e instanceof o||(e=o.fromPoints(e.start,e.end));if(t.length===0&&e.isEmpty())return e.start;if(t==this.getTextRange(e))return e.end;this.remove(e);var n;return t?n=this.insert(e.start,t):n=e.start,n},this.applyDeltas=function(e){for(var t=0;t=0;t--)this.revertDelta(e[t])},this.applyDelta=function(e,t){var n=e.action=="insert";if(n?e.lines.length<=1&&!e.lines[0]:!o.comparePoints(e.start,e.end))return;n&&e.lines.length>2e4&&this.$splitAndapplyLargeDelta(e,2e4),i(this.$lines,e,t),this._signal("change",e)},this.$splitAndapplyLargeDelta=function(e,t){var n=e.lines,r=n.length,i=e.start.row,s=e.start.column,o=0,u=0;do{o=u,u+=t-1;var a=n.slice(o,u);if(u>r){e.lines=a,e.start.row=i+o,e.start.column=s;break}a.push(""),this.applyDelta({start:this.pos(i+o,s),end:this.pos(i+u,s=0),action:e.action,lines:a},!0)}while(!0)},this.revertDelta=function(e){this.applyDelta({start:this.clonePos(e.start),end:this.clonePos(e.end),action:e.action=="insert"?"remove":"insert",lines:e.lines.slice()})},this.indexToPosition=function(e,t){var n=this.$lines||this.getAllLines(),r=this.getNewLineCharacter().length;for(var i=t||0,s=n.length;i20){n.running=setTimeout(n.$worker,20);break}}n.currentLine=t,s<=r&&n.fireUpdateEvent(s,r)}};(function(){r.implement(this,i),this.setTokenizer=function(e){this.tokenizer=e,this.lines=[],this.states=[],this.start(0)},this.setDocument=function(e){this.doc=e,this.lines=[],this.states=[],this.stop()},this.fireUpdateEvent=function(e,t){var n={first:e,last:t};this._signal("update",{data:n})},this.start=function(e){this.currentLine=Math.min(e||0,this.currentLine,this.doc.getLength()),this.lines.splice(this.currentLine,this.lines.length),this.states.splice(this.currentLine,this.states.length),this.stop(),this.running=setTimeout(this.$worker,700)},this.scheduleStart=function(){this.running||(this.running=setTimeout(this.$worker,700))},this.$updateOnChange=function(e){var t=e.start.row,n=e.end.row-t;if(n===0)this.lines[t]=null;else if(e.action=="remove")this.lines.splice(t,n+1,null),this.states.splice(t,n+1,null);else{var r=Array(n+1);r.unshift(t,1),this.lines.splice.apply(this.lines,r),this.states.splice.apply(this.states,r)}this.currentLine=Math.min(t,this.currentLine,this.doc.getLength()),this.stop()},this.stop=function(){this.running&&clearTimeout(this.running),this.running=!1},this.getTokens=function(e){return this.lines[e]||this.$tokenizeRow(e)},this.getState=function(e){return this.currentLine==e&&this.$tokenizeRow(e),this.states[e]||"start"},this.$tokenizeRow=function(e){var t=this.doc.getLine(e),n=this.states[e-1],r=this.tokenizer.getLineTokens(t,n,e);return this.states[e]+""!=r.state+""?(this.states[e]=r.state,this.lines[e+1]=null,this.currentLine>e+1&&(this.currentLine=e+1)):this.currentLine==e&&(this.currentLine=e+1),this.lines[e]=r.tokens}}).call(s.prototype),t.BackgroundTokenizer=s}),define("ace/search_highlight",["require","exports","module","ace/lib/lang","ace/lib/oop","ace/range"],function(e,t,n){"use strict";var r=e("./lib/lang"),i=e("./lib/oop"),s=e("./range").Range,o=function(e,t,n){this.setRegexp(e),this.clazz=t,this.type=n||"text"};(function(){this.MAX_RANGES=500,this.setRegexp=function(e){if(this.regExp+""==e+"")return;this.regExp=e,this.cache=[]},this.update=function(e,t,n,i){if(!this.regExp)return;var o=i.firstRow,u=i.lastRow;for(var a=o;a<=u;a++){var f=this.cache[a];f==null&&(f=r.getMatchOffsets(n.getLine(a),this.regExp),f.length>this.MAX_RANGES&&(f=f.slice(0,this.MAX_RANGES)),f=f.map(function(e){return new s(a,e.offset,a,e.offset+e.length)}),this.cache[a]=f.length?f:"");for(var l=f.length;l--;)t.drawSingleLineMarker(e,f[l].toScreenRange(n),this.clazz,i)}}}).call(o.prototype),t.SearchHighlight=o}),define("ace/edit_session/fold_line",["require","exports","module","ace/range"],function(e,t,n){"use strict";function i(e,t){this.foldData=e,Array.isArray(t)?this.folds=t:t=this.folds=[t];var n=t[t.length-1];this.range=new r(t[0].start.row,t[0].start.column,n.end.row,n.end.column),this.start=this.range.start,this.end=this.range.end,this.folds.forEach(function(e){e.setFoldLine(this)},this)}var r=e("../range").Range;(function(){this.shiftRow=function(e){this.start.row+=e,this.end.row+=e,this.folds.forEach(function(t){t.start.row+=e,t.end.row+=e})},this.addFold=function(e){if(e.sameRow){if(e.start.rowthis.endRow)throw new Error("Can't add a fold to this FoldLine as it has no connection");this.folds.push(e),this.folds.sort(function(e,t){return-e.range.compareEnd(t.start.row,t.start.column)}),this.range.compareEnd(e.start.row,e.start.column)>0?(this.end.row=e.end.row,this.end.column=e.end.column):this.range.compareStart(e.end.row,e.end.column)<0&&(this.start.row=e.start.row,this.start.column=e.start.column)}else if(e.start.row==this.end.row)this.folds.push(e),this.end.row=e.end.row,this.end.column=e.end.column;else{if(e.end.row!=this.start.row)throw new Error("Trying to add fold to FoldRow that doesn't have a matching row");this.folds.unshift(e),this.start.row=e.start.row,this.start.column=e.start.column}e.foldLine=this},this.containsRow=function(e){return e>=this.start.row&&e<=this.end.row},this.walk=function(e,t,n){var r=0,i=this.folds,s,o,u,a=!0;t==null&&(t=this.end.row,n=this.end.column);for(var f=0;f0)continue;var a=i(e,o.start);return u===0?t&&a!==0?-s-2:s:a>0||a===0&&!t?s:-s-1}return-s-1},this.add=function(e){var t=!e.isEmpty(),n=this.pointIndex(e.start,t);n<0&&(n=-n-1);var r=this.pointIndex(e.end,t,n);return r<0?r=-r-1:r++,this.ranges.splice(n,r-n,e)},this.addList=function(e){var t=[];for(var n=e.length;n--;)t.push.apply(t,this.add(e[n]));return t},this.substractPoint=function(e){var t=this.pointIndex(e);if(t>=0)return this.ranges.splice(t,1)},this.merge=function(){var e=[],t=this.ranges;t=t.sort(function(e,t){return i(e.start,t.start)});var n=t[0],r;for(var s=1;s=0},this.containsPoint=function(e){return this.pointIndex(e)>=0},this.rangeAtPoint=function(e){var t=this.pointIndex(e);if(t>=0)return this.ranges[t]},this.clipRows=function(e,t){var n=this.ranges;if(n[0].start.row>t||n[n.length-1].start.rowr)break;l.start.row==r&&l.start.column>=t.column&&(l.start.column!=t.column||!this.$insertRight)&&(l.start.column+=o,l.start.row+=s);if(l.end.row==r&&l.end.column>=t.column){if(l.end.column==t.column&&this.$insertRight)continue;l.end.column==t.column&&o>0&&al.start.column&&l.end.column==u[a+1].start.column&&(l.end.column-=o),l.end.column+=o,l.end.row+=s}}if(s!=0&&a=e)return i;if(i.end.row>e)return null}return null},this.getNextFoldLine=function(e,t){var n=this.$foldData,r=0;t&&(r=n.indexOf(t)),r==-1&&(r=0);for(r;r=e)return i}return null},this.getFoldedRowCount=function(e,t){var n=this.$foldData,r=t-e+1;for(var i=0;i=t){u=e?r-=t-u:r=0);break}o>=e&&(u>=e?r-=o-u:r-=o-e+1)}return r},this.$addFoldLine=function(e){return this.$foldData.push(e),this.$foldData.sort(function(e,t){return e.start.row-t.start.row}),e},this.addFold=function(e,t){var n=this.$foldData,r=!1,o;e instanceof s?o=e:(o=new s(t,e),o.collapseChildren=t.collapseChildren),this.$clipRangeToDocument(o.range);var u=o.start.row,a=o.start.column,f=o.end.row,l=o.end.column;if(u0&&(this.removeFolds(p),p.forEach(function(e){o.addSubFold(e)}));for(var d=0;d0&&this.foldAll(e.start.row+1,e.end.row,e.collapseChildren-1),e.subFolds=[]},this.expandFolds=function(e){e.forEach(function(e){this.expandFold(e)},this)},this.unfold=function(e,t){var n,i;e==null?(n=new r(0,0,this.getLength(),0),t=!0):typeof e=="number"?n=new r(e,0,e,this.getLine(e).length):"row"in e?n=r.fromPoints(e,e):n=e,i=this.getFoldsInRangeList(n);if(t)this.removeFolds(i);else{var s=i;while(s.length)this.expandFolds(s),s=this.getFoldsInRangeList(n)}if(i.length)return i},this.isRowFolded=function(e,t){return!!this.getFoldLine(e,t)},this.getRowFoldEnd=function(e,t){var n=this.getFoldLine(e,t);return n?n.end.row:e},this.getRowFoldStart=function(e,t){var n=this.getFoldLine(e,t);return n?n.start.row:e},this.getFoldDisplayLine=function(e,t,n,r,i){r==null&&(r=e.start.row),i==null&&(i=0),t==null&&(t=e.end.row),n==null&&(n=this.getLine(t).length);var s=this.doc,o="";return e.walk(function(e,t,n,u){if(t=e){i=s.end.row;try{var o=this.addFold("...",s);o&&(o.collapseChildren=n)}catch(u){}}}},this.$foldStyles={manual:1,markbegin:1,markbeginend:1},this.$foldStyle="markbegin",this.setFoldStyle=function(e){if(!this.$foldStyles[e])throw new Error("invalid fold style: "+e+"["+Object.keys(this.$foldStyles).join(", ")+"]");if(this.$foldStyle==e)return;this.$foldStyle=e,e=="manual"&&this.unfold();var t=this.$foldMode;this.$setFolding(null),this.$setFolding(t)},this.$setFolding=function(e){if(this.$foldMode==e)return;this.$foldMode=e,this.off("change",this.$updateFoldWidgets),this.off("tokenizerUpdate",this.$tokenizerUpdateFoldWidgets),this._signal("changeAnnotation");if(!e||this.$foldStyle=="manual"){this.foldWidgets=null;return}this.foldWidgets=[],this.getFoldWidget=e.getFoldWidget.bind(e,this,this.$foldStyle),this.getFoldWidgetRange=e.getFoldWidgetRange.bind(e,this,this.$foldStyle),this.$updateFoldWidgets=this.updateFoldWidgets.bind(this),this.$tokenizerUpdateFoldWidgets=this.tokenizerUpdateFoldWidgets.bind(this),this.on("change",this.$updateFoldWidgets),this.on("tokenizerUpdate",this.$tokenizerUpdateFoldWidgets)},this.getParentFoldRangeData=function(e,t){var n=this.foldWidgets;if(!n||t&&n[e])return{};var r=e-1,i;while(r>=0){var s=n[r];s==null&&(s=n[r]=this.getFoldWidget(r));if(s=="start"){var o=this.getFoldWidgetRange(r);i||(i=o);if(o&&o.end.row>=e)break}r--}return{range:r!==-1&&o,firstRange:i}},this.onFoldWidgetClick=function(e,t){t=t.domEvent;var n={children:t.shiftKey,all:t.ctrlKey||t.metaKey,siblings:t.altKey},r=this.$toggleFoldWidget(e,n);if(!r){var i=t.target||t.srcElement;i&&/ace_fold-widget/.test(i.className)&&(i.className+=" ace_invalid")}},this.$toggleFoldWidget=function(e,t){if(!this.getFoldWidget)return;var n=this.getFoldWidget(e),r=this.getLine(e),i=n==="end"?-1:1,s=this.getFoldAt(e,i===-1?0:r.length,i);if(s)return t.children||t.all?this.removeFold(s):this.expandFold(s),s;var o=this.getFoldWidgetRange(e,!0);if(o&&!o.isMultiLine()){s=this.getFoldAt(o.start.row,o.start.column,1);if(s&&o.isEqual(s.range))return this.removeFold(s),s}if(t.siblings){var u=this.getParentFoldRangeData(e);if(u.range)var a=u.range.start.row+1,f=u.range.end.row;this.foldAll(a,f,t.all?1e4:0)}else t.children?(f=o?o.end.row:this.getLength(),this.foldAll(e+1,f,t.all?1e4:0)):o&&(t.all&&(o.collapseChildren=1e4),this.addFold("...",o));return o},this.toggleFoldWidget=function(e){var t=this.selection.getCursor().row;t=this.getRowFoldStart(t);var n=this.$toggleFoldWidget(t,{});if(n)return;var r=this.getParentFoldRangeData(t,!0);n=r.range||r.firstRange;if(n){t=n.start.row;var i=this.getFoldAt(t,this.getLine(t).length,1);i?this.removeFold(i):this.addFold("...",n)}},this.updateFoldWidgets=function(e){var t=e.start.row,n=e.end.row-t;if(n===0)this.foldWidgets[t]=null;else if(e.action=="remove")this.foldWidgets.splice(t,n+1,null);else{var r=Array(n+1);r.unshift(t,1),this.foldWidgets.splice.apply(this.foldWidgets,r)}},this.tokenizerUpdateFoldWidgets=function(e){var t=e.data;t.first!=t.last&&this.foldWidgets.length>t.first&&this.foldWidgets.splice(t.first,this.foldWidgets.length)}}var r=e("../range").Range,i=e("./fold_line").FoldLine,s=e("./fold").Fold,o=e("../token_iterator").TokenIterator;t.Folding=u}),define("ace/edit_session/bracket_match",["require","exports","module","ace/token_iterator","ace/range"],function(e,t,n){"use strict";function s(){this.findMatchingBracket=function(e,t){if(e.column==0)return null;var n=t||this.getLine(e.row).charAt(e.column-1);if(n=="")return null;var r=n.match(/([\(\[\{])|([\)\]\}])/);return r?r[1]?this.$findClosingBracket(r[1],e):this.$findOpeningBracket(r[2],e):null},this.getBracketRange=function(e){var t=this.getLine(e.row),n=!0,r,s=t.charAt(e.column-1),o=s&&s.match(/([\(\[\{])|([\)\]\}])/);o||(s=t.charAt(e.column),e={row:e.row,column:e.column+1},o=s&&s.match(/([\(\[\{])|([\)\]\}])/),n=!1);if(!o)return null;if(o[1]){var u=this.$findClosingBracket(o[1],e);if(!u)return null;r=i.fromPoints(e,u),n||(r.end.column++,r.start.column--),r.cursor=r.end}else{var u=this.$findOpeningBracket(o[2],e);if(!u)return null;r=i.fromPoints(u,e),n||(r.start.column++,r.end.column--),r.cursor=r.start}return r},this.$brackets={")":"(","(":")","]":"[","[":"]","{":"}","}":"{"},this.$findOpeningBracket=function(e,t,n){var i=this.$brackets[e],s=1,o=new r(this,t.row,t.column),u=o.getCurrentToken();u||(u=o.stepForward());if(!u)return;n||(n=new RegExp("(\\.?"+u.type.replace(".","\\.").replace("rparen",".paren").replace(/\b(?:end)\b/,"(?:start|begin|end)")+")+"));var a=t.column-o.getCurrentTokenColumn()-2,f=u.value;for(;;){while(a>=0){var l=f.charAt(a);if(l==i){s-=1;if(s==0)return{row:o.getCurrentTokenRow(),column:a+o.getCurrentTokenColumn()}}else l==e&&(s+=1);a-=1}do u=o.stepBackward();while(u&&!n.test(u.type));if(u==null)break;f=u.value,a=f.length-1}return null},this.$findClosingBracket=function(e,t,n){var i=this.$brackets[e],s=1,o=new r(this,t.row,t.column),u=o.getCurrentToken();u||(u=o.stepForward());if(!u)return;n||(n=new RegExp("(\\.?"+u.type.replace(".","\\.").replace("lparen",".paren").replace(/\b(?:start|begin)\b/,"(?:start|begin|end)")+")+"));var a=t.column-o.getCurrentTokenColumn();for(;;){var f=u.value,l=f.length;while(a=4352&&e<=4447||e>=4515&&e<=4519||e>=4602&&e<=4607||e>=9001&&e<=9002||e>=11904&&e<=11929||e>=11931&&e<=12019||e>=12032&&e<=12245||e>=12272&&e<=12283||e>=12288&&e<=12350||e>=12353&&e<=12438||e>=12441&&e<=12543||e>=12549&&e<=12589||e>=12593&&e<=12686||e>=12688&&e<=12730||e>=12736&&e<=12771||e>=12784&&e<=12830||e>=12832&&e<=12871||e>=12880&&e<=13054||e>=13056&&e<=19903||e>=19968&&e<=42124||e>=42128&&e<=42182||e>=43360&&e<=43388||e>=44032&&e<=55203||e>=55216&&e<=55238||e>=55243&&e<=55291||e>=63744&&e<=64255||e>=65040&&e<=65049||e>=65072&&e<=65106||e>=65108&&e<=65126||e>=65128&&e<=65131||e>=65281&&e<=65376||e>=65504&&e<=65510}r.implement(this,o),this.setDocument=function(e){this.doc&&this.doc.removeListener("change",this.$onChange),this.doc=e,e.on("change",this.$onChange),this.bgTokenizer&&this.bgTokenizer.setDocument(this.getDocument()),this.resetCaches()},this.getDocument=function(){return this.doc},this.$resetRowCache=function(e){if(!e){this.$docRowCache=[],this.$screenRowCache=[];return}var t=this.$docRowCache.length,n=this.$getRowCacheIndex(this.$docRowCache,e)+1;t>n&&(this.$docRowCache.splice(n,t),this.$screenRowCache.splice(n,t))},this.$getRowCacheIndex=function(e,t){var n=0,r=e.length-1;while(n<=r){var i=n+r>>1,s=e[i];if(t>s)n=i+1;else{if(!(t=t)break}return r=n[s],r?(r.index=s,r.start=i-r.value.length,r):null},this.setUndoManager=function(e){this.$undoManager=e,this.$deltas=[],this.$deltasDoc=[],this.$deltasFold=[],this.$informUndoManager&&this.$informUndoManager.cancel();if(e){var t=this;this.$syncInformUndoManager=function(){t.$informUndoManager.cancel(),t.$deltasFold.length&&(t.$deltas.push({group:"fold",deltas:t.$deltasFold}),t.$deltasFold=[]),t.$deltasDoc.length&&(t.$deltas.push({group:"doc",deltas:t.$deltasDoc}),t.$deltasDoc=[]),t.$deltas.length>0&&e.execute({action:"aceupdate",args:[t.$deltas,t],merge:t.mergeUndoDeltas}),t.mergeUndoDeltas=!1,t.$deltas=[]},this.$informUndoManager=i.delayedCall(this.$syncInformUndoManager)}},this.markUndoGroup=function(){this.$syncInformUndoManager&&this.$syncInformUndoManager()},this.$defaultUndoManager={undo:function(){},redo:function(){},reset:function(){}},this.getUndoManager=function(){return this.$undoManager||this.$defaultUndoManager},this.getTabString=function(){return this.getUseSoftTabs()?i.stringRepeat(" ",this.getTabSize()):" "},this.setUseSoftTabs=function(e){this.setOption("useSoftTabs",e)},this.getUseSoftTabs=function(){return this.$useSoftTabs&&!this.$mode.$indentWithTabs},this.setTabSize=function(e){this.setOption("tabSize",e)},this.getTabSize=function(){return this.$tabSize},this.isTabStop=function(e){return this.$useSoftTabs&&e.column%this.$tabSize===0},this.$overwrite=!1,this.setOverwrite=function(e){this.setOption("overwrite",e)},this.getOverwrite=function(){return this.$overwrite},this.toggleOverwrite=function(){this.setOverwrite(!this.$overwrite)},this.addGutterDecoration=function(e,t){this.$decorations[e]||(this.$decorations[e]=""),this.$decorations[e]+=" "+t,this._signal("changeBreakpoint",{})},this.removeGutterDecoration=function(e,t){this.$decorations[e]=(this.$decorations[e]||"").replace(" "+t,""),this._signal("changeBreakpoint",{})},this.getBreakpoints=function(){return this.$breakpoints},this.setBreakpoints=function(e){this.$breakpoints=[];for(var t=0;t0&&(r=!!n.charAt(t-1).match(this.tokenRe)),r||(r=!!n.charAt(t).match(this.tokenRe));if(r)var i=this.tokenRe;else if(/^\s+$/.test(n.slice(t-1,t+1)))var i=/\s/;else var i=this.nonTokenRe;var s=t;if(s>0){do s--;while(s>=0&&n.charAt(s).match(i));s++}var o=t;while(oe&&(e=t.screenWidth)}),this.lineWidgetWidth=e},this.$computeWidth=function(e){if(this.$modified||e){this.$modified=!1;if(this.$useWrapMode)return this.screenWidth=this.$wrapLimit;var t=this.doc.getAllLines(),n=this.$rowLengthCache,r=0,i=0,s=this.$foldData[i],o=s?s.start.row:Infinity,u=t.length;for(var a=0;ao){a=s.end.row+1;if(a>=u)break;s=this.$foldData[i++],o=s?s.start.row:Infinity}n[a]==null&&(n[a]=this.$getStringScreenWidth(t[a])[0]),n[a]>r&&(r=n[a])}this.screenWidth=r}},this.getLine=function(e){return this.doc.getLine(e)},this.getLines=function(e,t){return this.doc.getLines(e,t)},this.getLength=function(){return this.doc.getLength()},this.getTextRange=function(e){return this.doc.getTextRange(e||this.selection.getRange())},this.insert=function(e,t){return this.doc.insert(e,t)},this.remove=function(e){return this.doc.remove(e)},this.removeFullLines=function(e,t){return this.doc.removeFullLines(e,t)},this.undoChanges=function(e,t){if(!e.length)return;this.$fromUndo=!0;var n=null;for(var r=e.length-1;r!=-1;r--){var i=e[r];i.group=="doc"?(this.doc.revertDeltas(i.deltas),n=this.$getUndoSelection(i.deltas,!0,n)):i.deltas.forEach(function(e){this.addFolds(e.folds)},this)}return this.$fromUndo=!1,n&&this.$undoSelect&&!t&&this.selection.setSelectionRange(n),n},this.redoChanges=function(e,t){if(!e.length)return;this.$fromUndo=!0;var n=null;for(var r=0;re.end.column&&(s.start.column+=u),s.end.row==e.end.row&&s.end.column>e.end.column&&(s.end.column+=u)),o&&s.start.row>=e.end.row&&(s.start.row+=o,s.end.row+=o)}s.end=this.insert(s.start,r);if(i.length){var a=e.start,l=s.start,o=l.row-a.row,u=l.column-a.column;this.addFolds(i.map(function(e){return e=e.clone(),e.start.row==a.row&&(e.start.column+=u),e.end.row==a.row&&(e.end.column+=u),e.start.row+=o,e.end.row+=o,e}))}return s},this.indentRows=function(e,t,n){n=n.replace(/\t/g,this.getTabString());for(var r=e;r<=t;r++)this.doc.insertInLine({row:r,column:0},n)},this.outdentRows=function(e){var t=e.collapseRows(),n=new f(0,0,0,0),r=this.getTabSize();for(var i=t.start.row;i<=t.end.row;++i){var s=this.getLine(i);n.start.row=i,n.end.row=i;for(var o=0;o0){var r=this.getRowFoldEnd(t+n);if(r>this.doc.getLength()-1)return 0;var i=r-t}else{e=this.$clipRowToDocument(e),t=this.$clipRowToDocument(t);var i=t-e+1}var s=new f(e,0,t,Number.MAX_VALUE),o=this.getFoldsInRange(s).map(function(e){return e=e.clone(),e.start.row+=i,e.end.row+=i,e}),u=n==0?this.doc.getLines(e,t):this.doc.removeFullLines(e,t);return this.doc.insertFullLines(e+i,u),o.length&&this.addFolds(o),i},this.moveLinesUp=function(e,t){return this.$moveLines(e,t,-1)},this.moveLinesDown=function(e,t){return this.$moveLines(e,t,1)},this.duplicateLines=function(e,t){return this.$moveLines(e,t,0)},this.$clipRowToDocument=function(e){return Math.max(0,Math.min(e,this.doc.getLength()-1))},this.$clipColumnToRow=function(e,t){return t<0?0:Math.min(this.doc.getLine(e).length,t)},this.$clipPositionToDocument=function(e,t){t=Math.max(0,t);if(e<0)e=0,t=0;else{var n=this.doc.getLength();e>=n?(e=n-1,t=this.doc.getLine(n-1).length):t=Math.min(this.doc.getLine(e).length,t)}return{row:e,column:t}},this.$clipRangeToDocument=function(e){e.start.row<0?(e.start.row=0,e.start.column=0):e.start.column=this.$clipColumnToRow(e.start.row,e.start.column);var t=this.doc.getLength()-1;return e.end.row>t?(e.end.row=t,e.end.column=this.doc.getLine(t).length):e.end.column=this.$clipColumnToRow(e.end.row,e.end.column),e},this.$wrapLimit=80,this.$useWrapMode=!1,this.$wrapLimitRange={min:null,max:null},this.setUseWrapMode=function(e){if(e!=this.$useWrapMode){this.$useWrapMode=e,this.$modified=!0,this.$resetRowCache(0);if(e){var t=this.getLength();this.$wrapData=Array(t),this.$updateWrapData(0,t-1)}this._signal("changeWrapMode")}},this.getUseWrapMode=function(){return this.$useWrapMode},this.setWrapLimitRange=function(e,t){if(this.$wrapLimitRange.min!==e||this.$wrapLimitRange.max!==t)this.$wrapLimitRange={min:e,max:t},this.$modified=!0,this.$useWrapMode&&this._signal("changeWrapMode")},this.adjustWrapLimit=function(e,t){var n=this.$wrapLimitRange;n.max<0&&(n={min:t,max:t});var r=this.$constrainWrapLimit(e,n.min,n.max);return r!=this.$wrapLimit&&r>1?(this.$wrapLimit=r,this.$modified=!0,this.$useWrapMode&&(this.$updateWrapData(0,this.getLength()-1),this.$resetRowCache(0),this._signal("changeWrapLimit")),!0):!1},this.$constrainWrapLimit=function(e,t,n){return t&&(e=Math.max(t,e)),n&&(e=Math.min(n,e)),e},this.getWrapLimit=function(){return this.$wrapLimit},this.setWrapLimit=function(e){this.setWrapLimitRange(e,e)},this.getWrapLimitRange=function(){return{min:this.$wrapLimitRange.min,max:this.$wrapLimitRange.max}},this.$updateInternalDataOnChange=function(e){var t=this.$useWrapMode,n=e.action,r=e.start,i=e.end,s=r.row,o=i.row,u=o-s,a=null;this.$updating=!0;if(u!=0)if(n==="remove"){this[t?"$wrapData":"$rowLengthCache"].splice(s,u);var f=this.$foldData;a=this.getFoldsInRange(e),this.removeFolds(a);var l=this.getFoldLine(i.row),c=0;if(l){l.addRemoveChars(i.row,i.column,r.column-i.column),l.shiftRow(-u);var h=this.getFoldLine(s);h&&h!==l&&(h.merge(l),l=h),c=f.indexOf(l)+1}for(c;c=i.row&&l.shiftRow(-u)}o=s}else{var p=Array(u);p.unshift(s,0);var d=t?this.$wrapData:this.$rowLengthCache;d.splice.apply(d,p);var f=this.$foldData,l=this.getFoldLine(s),c=0;if(l){var v=l.range.compareInside(r.row,r.column);v==0?(l=l.split(r.row,r.column),l&&(l.shiftRow(u),l.addRemoveChars(o,0,i.column-r.column))):v==-1&&(l.addRemoveChars(s,0,i.column-r.column),l.shiftRow(u)),c=f.indexOf(l)+1}for(c;c=s&&l.shiftRow(u)}}else{u=Math.abs(e.start.column-e.end.column),n==="remove"&&(a=this.getFoldsInRange(e),this.removeFolds(a),u=-u);var l=this.getFoldLine(s);l&&l.addRemoveChars(s,r.column,u)}return t&&this.$wrapData.length!=this.doc.getLength()&&console.error("doc.getLength() and $wrapData.length have to be the same!"),this.$updating=!1,t?this.$updateWrapData(s,o):this.$updateRowLengthCache(s,o),a},this.$updateRowLengthCache=function(e,t,n){this.$rowLengthCache[e]=null,this.$rowLengthCache[t]=null},this.$updateWrapData=function(e,t){var r=this.doc.getAllLines(),i=this.getTabSize(),s=this.$wrapData,o=this.$wrapLimit,a,f,l=e;t=Math.min(t,r.length-1);while(l<=t)f=this.getFoldLine(l,f),f?(a=[],f.walk(function(e,t,i,s){var o;if(e!=null){o=this.$getDisplayTokens(e,a.length),o[0]=n;for(var f=1;fr-b){var w=a+r-b;if(e[w-1]>=p&&e[w]>=p){y(w);continue}if(e[w]==n||e[w]==u){for(w;w!=a-1;w--)if(e[w]==n)break;if(w>a){y(w);continue}w=a+r;for(w;w>2)),a-1);while(w>E&&e[w]E&&e[w]E&&e[w]==l)w--}else while(w>E&&e[w]E){y(++w);continue}w=a+r,e[w]==t&&w--,y(w-b)}return s},this.$getDisplayTokens=function(n,r){var i=[],s;r=r||0;for(var o=0;o39&&u<48||u>57&&u<64?i.push(l):u>=4352&&m(u)?i.push(e,t):i.push(e)}return i},this.$getStringScreenWidth=function(e,t,n){if(t==0)return[0,0];t==null&&(t=Infinity),n=n||0;var r,i;for(i=0;i=4352&&m(r)?n+=2:n+=1;if(n>t)break}return[n,i]},this.lineWidgets=null,this.getRowLength=function(e){if(this.lineWidgets)var t=this.lineWidgets[e]&&this.lineWidgets[e].rowCount||0;else t=0;return!this.$useWrapMode||!this.$wrapData[e]?1+t:this.$wrapData[e].length+1+t},this.getRowLineCount=function(e){return!this.$useWrapMode||!this.$wrapData[e]?1:this.$wrapData[e].length+1},this.getRowWrapIndent=function(e){if(this.$useWrapMode){var t=this.screenToDocumentPosition(e,Number.MAX_VALUE),n=this.$wrapData[t.row];return n.length&&n[0]=0)var o=a[f],r=this.$docRowCache[f],c=e>a[l-1];else var c=!l;var h=this.getLength()-1,p=this.getNextFoldLine(r),d=p?p.start.row:Infinity;while(o<=e){u=this.getRowLength(r);if(o+u>e||r>=h)break;o+=u,r++,r>d&&(r=p.end.row+1,p=this.getNextFoldLine(r,p),d=p?p.start.row:Infinity),c&&(this.$docRowCache.push(r),this.$screenRowCache.push(o))}if(p&&p.start.row<=r)n=this.getFoldDisplayLine(p),r=p.start.row;else{if(o+u<=e||r>h)return{row:h,column:this.getLine(h).length};n=this.getLine(r),p=null}var v=0;if(this.$useWrapMode){var m=this.$wrapData[r];if(m){var g=Math.floor(e-o);s=m[g],g>0&&m.length&&(v=m.indent,i=m[g-1]||m[m.length-1],n=n.substring(i))}}return i+=this.$getStringScreenWidth(n,t-v)[1],this.$useWrapMode&&i>=s&&(i=s-1),p?p.idxToPosition(i):{row:r,column:i}},this.documentToScreenPosition=function(e,t){if(typeof t=="undefined")var n=this.$clipPositionToDocument(e.row,e.column);else n=this.$clipPositionToDocument(e,t);e=n.row,t=n.column;var r=0,i=null,s=null;s=this.getFoldAt(e,t,1),s&&(e=s.start.row,t=s.start.column);var o,u=0,a=this.$docRowCache,f=this.$getRowCacheIndex(a,e),l=a.length;if(l&&f>=0)var u=a[f],r=this.$screenRowCache[f],c=e>a[l-1];else var c=!l;var h=this.getNextFoldLine(u),p=h?h.start.row:Infinity;while(u=p){o=h.end.row+1;if(o>e)break;h=this.getNextFoldLine(o,h),p=h?h.start.row:Infinity}else o=u+1;r+=this.getRowLength(u),u=o,c&&(this.$docRowCache.push(u),this.$screenRowCache.push(r))}var d="";h&&u>=p?(d=this.getFoldDisplayLine(h,e,t),i=h.start.row):(d=this.getLine(e).substring(0,t),i=e);var v=0;if(this.$useWrapMode){var m=this.$wrapData[i];if(m){var g=0;while(d.length>=m[g])r++,g++;d=d.substring(m[g-1]||0,d.length),v=g>0?m.indent:0}}return{row:r,column:v+this.$getStringScreenWidth(d)[0]}},this.documentToScreenColumn=function(e,t){return this.documentToScreenPosition(e,t).column},this.documentToScreenRow=function(e,t){return this.documentToScreenPosition(e,t).row},this.getScreenLength=function(){var e=0,t=null;if(!this.$useWrapMode){e=this.getLength();var n=this.$foldData;for(var r=0;ro&&(s=t.end.row+1,t=this.$foldData[r++],o=t?t.start.row:Infinity)}}return this.lineWidgets&&(e+=this.$getWidgetScreenLength()),e},this.$setFontMetrics=function(e){if(!this.$enableVarChar)return;this.$getStringScreenWidth=function(t,n,r){if(n===0)return[0,0];n||(n=Infinity),r=r||0;var i,s;for(s=0;sn)break}return[r,s]}},this.destroy=function(){this.bgTokenizer&&(this.bgTokenizer.setDocument(null),this.bgTokenizer=null),this.$stopWorker()}}).call(p.prototype),e("./edit_session/folding").Folding.call(p.prototype),e("./edit_session/bracket_match").BracketMatch.call(p.prototype),s.defineOptions(p.prototype,"session",{wrap:{set:function(e){!e||e=="off"?e=!1:e=="free"?e=!0:e=="printMargin"?e=-1:typeof e=="string"&&(e=parseInt(e,10)||!1);if(this.$wrap==e)return;this.$wrap=e;if(!e)this.setUseWrapMode(!1);else{var t=typeof e=="number"?e:null;this.setWrapLimitRange(t,t),this.setUseWrapMode(!0)}},get:function(){return this.getUseWrapMode()?this.$wrap==-1?"printMargin":this.getWrapLimitRange().min?this.$wrap:"free":"off"},handlesSet:!0},wrapMethod:{set:function(e){e=e=="auto"?this.$mode.type!="text":e!="text",e!=this.$wrapAsCode&&(this.$wrapAsCode=e,this.$useWrapMode&&(this.$modified=!0,this.$resetRowCache(0),this.$updateWrapData(0,this.getLength()-1)))},initialValue:"auto"},indentedSoftWrap:{initialValue:!0},firstLineNumber:{set:function(){this._signal("changeBreakpoint")},initialValue:1},useWorker:{set:function(e){this.$useWorker=e,this.$stopWorker(),e&&this.$startWorker()},initialValue:!0},useSoftTabs:{initialValue:!0},tabSize:{set:function(e){if(isNaN(e)||this.$tabSize===e)return;this.$modified=!0,this.$rowLengthCache=[],this.$tabSize=e,this._signal("changeTabSize")},initialValue:4,handlesSet:!0},overwrite:{set:function(e){this._signal("changeOverwrite")},initialValue:!1},newLineMode:{set:function(e){this.doc.setNewLineMode(e)},get:function(){return this.doc.getNewLineMode()},handlesSet:!0},mode:{set:function(e){this.setMode(e)},get:function(){return this.$modeId}}}),t.EditSession=p}),define("ace/search",["require","exports","module","ace/lib/lang","ace/lib/oop","ace/range"],function(e,t,n){"use strict";function u(e,t){function n(e){return/\w/.test(e)||t.regExp?"\\b":""}return n(e[0])+e+n(e[e.length-1])}var r=e("./lib/lang"),i=e("./lib/oop"),s=e("./range").Range,o=function(){this.$options={}};(function(){this.set=function(e){return i.mixin(this.$options,e),this},this.getOptions=function(){return r.copyObject(this.$options)},this.setOptions=function(e){this.$options=e},this.find=function(e){var t=this.$options,n=this.$matchIterator(e,t);if(!n)return!1;var r=null;return n.forEach(function(e,n,i){if(!e.start){var o=e.offset+(i||0);r=new s(n,o,n,o+e.length);if(!e.length&&t.start&&t.start.start&&t.skipCurrent!=0&&r.isEqual(t.start))return r=null,!1}else r=e;return!0}),r},this.findAll=function(e){var t=this.$options;if(!t.needle)return[];this.$assembleRegExp(t);var n=t.range,i=n?e.getLines(n.start.row,n.end.row):e.doc.getAllLines(),o=[],u=t.re;if(t.$isMultiLine){var a=u.length,f=i.length-a,l;e:for(var c=u.offset||0;c<=f;c++){for(var h=0;hv)continue;o.push(l=new s(c,v,c+a-1,m)),a>2&&(c=c+a-2)}}else for(var g=0;gE&&o[h].end.row==n.end.row)h--;o=o.slice(g,h+1);for(g=0,h=o.length;g=0;u--)if(i(o[u],t,s))return!0};else var u=function(e,t,s){var o=r.getMatchOffsets(e,n);for(var u=0;u=o;r--)if(n(e.getLine(r),r))return;if(t.wrap==0)return;for(r=u,o=s.row;r>=o;r--)if(n(e.getLine(r),r))return}:function(n){var r=s.row,i=e.getLine(r).substr(s.column);if(n(i,r,s.column))return;for(r+=1;r<=u;r++)if(n(e.getLine(r),r))return;if(t.wrap==0)return;for(r=o,u=s.row;r<=u;r++)if(n(e.getLine(r),r))return};return{forEach:a}}}).call(o.prototype),t.Search=o}),define("ace/keyboard/hash_handler",["require","exports","module","ace/lib/keys","ace/lib/useragent"],function(e,t,n){"use strict";function o(e,t){this.platform=t||(i.isMac?"mac":"win"),this.commands={},this.commandKeyBinding={},this.addCommands(e),this.$singleCommand=!0}function u(e,t){o.call(this,e,t),this.$singleCommand=!1}var r=e("../lib/keys"),i=e("../lib/useragent"),s=r.KEY_MODS;u.prototype=o.prototype,function(){function e(e){return typeof e=="object"&&e.bindKey&&e.bindKey.position||0}this.addCommand=function(e){this.commands[e.name]&&this.removeCommand(e),this.commands[e.name]=e,e.bindKey&&this._buildKeyHash(e)},this.removeCommand=function(e,t){var n=e&&(typeof e=="string"?e:e.name);e=this.commands[n],t||delete this.commands[n];var r=this.commandKeyBinding;for(var i in r){var s=r[i];if(s==e)delete r[i];else if(Array.isArray(s)){var o=s.indexOf(e);o!=-1&&(s.splice(o,1),s.length==1&&(r[i]=s[0]))}}},this.bindKey=function(e,t,n){typeof e=="object"&&e&&(n==undefined&&(n=e.position),e=e[this.platform]);if(!e)return;if(typeof t=="function")return this.addCommand({exec:t,bindKey:e,name:t.name||e});e.split("|").forEach(function(e){var r="";if(e.indexOf(" ")!=-1){var i=e.split(/\s+/);e=i.pop(),i.forEach(function(e){var t=this.parseKeys(e),n=s[t.hashId]+t.key;r+=(r?" ":"")+n,this._addCommandToBinding(r,"chainKeys")},this),r+=" "}var o=this.parseKeys(e),u=s[o.hashId]+o.key;this._addCommandToBinding(r+u,t,n)},this)},this._addCommandToBinding=function(t,n,r){var i=this.commandKeyBinding,s;if(!n)delete i[t];else if(!i[t]||this.$singleCommand)i[t]=n;else{Array.isArray(i[t])?(s=i[t].indexOf(n))!=-1&&i[t].splice(s,1):i[t]=[i[t]],typeof r!="number"&&(r||n.isDefault?r=-100:r=e(n));var o=i[t];for(s=0;sr)break}o.splice(s,0,n)}},this.addCommands=function(e){e&&Object.keys(e).forEach(function(t){var n=e[t];if(!n)return;if(typeof n=="string")return this.bindKey(n,t);typeof n=="function"&&(n={exec:n});if(typeof n!="object")return;n.name||(n.name=t),this.addCommand(n)},this)},this.removeCommands=function(e){Object.keys(e).forEach(function(t){this.removeCommand(e[t])},this)},this.bindKeys=function(e){Object.keys(e).forEach(function(t){this.bindKey(t,e[t])},this)},this._buildKeyHash=function(e){this.bindKey(e.bindKey,e)},this.parseKeys=function(e){var t=e.toLowerCase().split(/[\-\+]([\-\+])?/).filter(function(e){return e}),n=t.pop(),i=r[n];if(r.FUNCTION_KEYS[i])n=r.FUNCTION_KEYS[i].toLowerCase();else{if(!t.length)return{key:n,hashId:-1};if(t.length==1&&t[0]=="shift")return{key:n.toUpperCase(),hashId:-1}}var s=0;for(var o=t.length;o--;){var u=r.KEY_MODS[t[o]];if(u==null)return typeof console!="undefined"&&console.error("invalid modifier "+t[o]+" in "+e),!1;s|=u}return{key:n,hashId:s}},this.findKeyCommand=function(t,n){var r=s[t]+n;return this.commandKeyBinding[r]},this.handleKeyboard=function(e,t,n,r){if(r<0)return;var i=s[t]+n,o=this.commandKeyBinding[i];e.$keyChain&&(e.$keyChain+=" "+i,o=this.commandKeyBinding[e.$keyChain]||o);if(o)if(o=="chainKeys"||o[o.length-1]=="chainKeys")return e.$keyChain=e.$keyChain||i,{command:"null"};if(e.$keyChain)if(!!t&&t!=4||n.length!=1){if(t==-1||r>0)e.$keyChain=""}else e.$keyChain=e.$keyChain.slice(0,-i.length-1);return{command:o}},this.getStatusText=function(e,t){return t.$keyChain||""}}.call(o.prototype),t.HashHandler=o,t.MultiHashHandler=u}),define("ace/commands/command_manager",["require","exports","module","ace/lib/oop","ace/keyboard/hash_handler","ace/lib/event_emitter"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../keyboard/hash_handler").MultiHashHandler,s=e("../lib/event_emitter").EventEmitter,o=function(e,t){i.call(this,t,e),this.byName=this.commands,this.setDefaultHandler("exec",function(e){return e.command.exec(e.editor,e.args||{})})};r.inherits(o,i),function(){r.implement(this,s),this.exec=function(e,t,n){if(Array.isArray(e)){for(var r=e.length;r--;)if(this.exec(e[r],t,n))return!0;return!1}typeof e=="string"&&(e=this.commands[e]);if(!e)return!1;if(t&&t.$readOnly&&!e.readOnly)return!1;var i={editor:t,command:e,args:n};return i.returnValue=this._emit("exec",i),this._signal("afterExec",i),i.returnValue===!1?!1:!0},this.toggleRecording=function(e){if(this.$inReplay)return;return e&&e._emit("changeStatus"),this.recording?(this.macro.pop(),this.removeEventListener("exec",this.$addCommandToMacro),this.macro.length||(this.macro=this.oldMacro),this.recording=!1):(this.$addCommandToMacro||(this.$addCommandToMacro=function(e){this.macro.push([e.command,e.args])}.bind(this)),this.oldMacro=this.macro,this.macro=[],this.on("exec",this.$addCommandToMacro),this.recording=!0)},this.replay=function(e){if(this.$inReplay||!this.macro)return;if(this.recording)return this.toggleRecording(e);try{this.$inReplay=!0,this.macro.forEach(function(t){typeof t=="string"?this.exec(t,e):this.exec(t[0],e,t[1])},this)}finally{this.$inReplay=!1}},this.trimMacro=function(e){return e.map(function(e){return typeof e[0]!="string"&&(e[0]=e[0].name),e[1]||(e=e[0]),e})}}.call(o.prototype),t.CommandManager=o}),define("ace/commands/default_commands",["require","exports","module","ace/lib/lang","ace/config","ace/range"],function(e,t,n){"use strict";function o(e,t){return{win:e,mac:t}}var r=e("../lib/lang"),i=e("../config"),s=e("../range").Range;t.commands=[{name:"showSettingsMenu",bindKey:o("Ctrl-,","Command-,"),exec:function(e){i.loadModule("ace/ext/settings_menu",function(t){t.init(e),e.showSettingsMenu()})},readOnly:!0},{name:"goToNextError",bindKey:o("Alt-E","F4"),exec:function(e){i.loadModule("ace/ext/error_marker",function(t){t.showErrorMarker(e,1)})},scrollIntoView:"animate",readOnly:!0},{name:"goToPreviousError",bindKey:o("Alt-Shift-E","Shift-F4"),exec:function(e){i.loadModule("ace/ext/error_marker",function(t){t.showErrorMarker(e,-1)})},scrollIntoView:"animate",readOnly:!0},{name:"selectall",bindKey:o("Ctrl-A","Command-A"),exec:function(e){e.selectAll()},readOnly:!0},{name:"centerselection",bindKey:o(null,"Ctrl-L"),exec:function(e){e.centerSelection()},readOnly:!0},{name:"gotoline",bindKey:o("Ctrl-L","Command-L"),exec:function(e){var t=parseInt(prompt("Enter line number:"),10);isNaN(t)||e.gotoLine(t)},readOnly:!0},{name:"fold",bindKey:o("Alt-L|Ctrl-F1","Command-Alt-L|Command-F1"),exec:function(e){e.session.toggleFold(!1)},multiSelectAction:"forEach",scrollIntoView:"center",readOnly:!0},{name:"unfold",bindKey:o("Alt-Shift-L|Ctrl-Shift-F1","Command-Alt-Shift-L|Command-Shift-F1"),exec:function(e){e.session.toggleFold(!0)},multiSelectAction:"forEach",scrollIntoView:"center",readOnly:!0},{name:"toggleFoldWidget",bindKey:o("F2","F2"),exec:function(e){e.session.toggleFoldWidget()},multiSelectAction:"forEach",scrollIntoView:"center",readOnly:!0},{name:"toggleParentFoldWidget",bindKey:o("Alt-F2","Alt-F2"),exec:function(e){e.session.toggleFoldWidget(!0)},multiSelectAction:"forEach",scrollIntoView:"center",readOnly:!0},{name:"foldall",bindKey:o(null,"Ctrl-Command-Option-0"),exec:function(e){e.session.foldAll()},scrollIntoView:"center",readOnly:!0},{name:"foldOther",bindKey:o("Alt-0","Command-Option-0"),exec:function(e){e.session.foldAll(),e.session.unfold(e.selection.getAllRanges())},scrollIntoView:"center",readOnly:!0},{name:"unfoldall",bindKey:o("Alt-Shift-0","Command-Option-Shift-0"),exec:function(e){e.session.unfold()},scrollIntoView:"center",readOnly:!0},{name:"findnext",bindKey:o("Ctrl-K","Command-G"),exec:function(e){e.findNext()},multiSelectAction:"forEach",scrollIntoView:"center",readOnly:!0},{name:"findprevious",bindKey:o("Ctrl-Shift-K","Command-Shift-G"),exec:function(e){e.findPrevious()},multiSelectAction:"forEach",scrollIntoView:"center",readOnly:!0},{name:"selectOrFindNext",bindKey:o("Alt-K","Ctrl-G"),exec:function(e){e.selection.isEmpty()?e.selection.selectWord():e.findNext()},readOnly:!0},{name:"selectOrFindPrevious",bindKey:o("Alt-Shift-K","Ctrl-Shift-G"),exec:function(e){e.selection.isEmpty()?e.selection.selectWord():e.findPrevious()},readOnly:!0},{name:"find",bindKey:o("Ctrl-F","Command-F"),exec:function(e){i.loadModule("ace/ext/searchbox",function(t){t.Search(e)})},readOnly:!0},{name:"overwrite",bindKey:"Insert",exec:function(e){e.toggleOverwrite()},readOnly:!0},{name:"selecttostart",bindKey:o("Ctrl-Shift-Home","Command-Shift-Home|Command-Shift-Up"),exec:function(e){e.getSelection().selectFileStart()},multiSelectAction:"forEach",readOnly:!0,scrollIntoView:"animate",aceCommandGroup:"fileJump"},{name:"gotostart",bindKey:o("Ctrl-Home","Command-Home|Command-Up"),exec:function(e){e.navigateFileStart()},multiSelectAction:"forEach",readOnly:!0,scrollIntoView:"animate",aceCommandGroup:"fileJump"},{name:"selectup",bindKey:o("Shift-Up","Shift-Up|Ctrl-Shift-P"),exec:function(e){e.getSelection().selectUp()},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"golineup",bindKey:o("Up","Up|Ctrl-P"),exec:function(e,t){e.navigateUp(t.times)},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"selecttoend",bindKey:o("Ctrl-Shift-End","Command-Shift-End|Command-Shift-Down"),exec:function(e){e.getSelection().selectFileEnd()},multiSelectAction:"forEach",readOnly:!0,scrollIntoView:"animate",aceCommandGroup:"fileJump"},{name:"gotoend",bindKey:o("Ctrl-End","Command-End|Command-Down"),exec:function(e){e.navigateFileEnd()},multiSelectAction:"forEach",readOnly:!0,scrollIntoView:"animate",aceCommandGroup:"fileJump"},{name:"selectdown",bindKey:o("Shift-Down","Shift-Down|Ctrl-Shift-N"),exec:function(e){e.getSelection().selectDown()},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"golinedown",bindKey:o("Down","Down|Ctrl-N"),exec:function(e,t){e.navigateDown(t.times)},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"selectwordleft",bindKey:o("Ctrl-Shift-Left","Option-Shift-Left"),exec:function(e){e.getSelection().selectWordLeft()},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"gotowordleft",bindKey:o("Ctrl-Left","Option-Left"),exec:function(e){e.navigateWordLeft()},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"selecttolinestart",bindKey:o("Alt-Shift-Left","Command-Shift-Left|Ctrl-Shift-A"),exec:function(e){e.getSelection().selectLineStart()},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"gotolinestart",bindKey:o("Alt-Left|Home","Command-Left|Home|Ctrl-A"),exec:function(e){e.navigateLineStart()},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"selectleft",bindKey:o("Shift-Left","Shift-Left|Ctrl-Shift-B"),exec:function(e){e.getSelection().selectLeft()},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"gotoleft",bindKey:o("Left","Left|Ctrl-B"),exec:function(e,t){e.navigateLeft(t.times)},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"selectwordright",bindKey:o("Ctrl-Shift-Right","Option-Shift-Right"),exec:function(e){e.getSelection().selectWordRight()},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"gotowordright",bindKey:o("Ctrl-Right","Option-Right"),exec:function(e){e.navigateWordRight()},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"selecttolineend",bindKey:o("Alt-Shift-Right","Command-Shift-Right|Shift-End|Ctrl-Shift-E"),exec:function(e){e.getSelection().selectLineEnd()},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"gotolineend",bindKey:o("Alt-Right|End","Command-Right|End|Ctrl-E"),exec:function(e){e.navigateLineEnd()},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"selectright",bindKey:o("Shift-Right","Shift-Right"),exec:function(e){e.getSelection().selectRight()},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"gotoright",bindKey:o("Right","Right|Ctrl-F"),exec:function(e,t){e.navigateRight(t.times)},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"selectpagedown",bindKey:"Shift-PageDown",exec:function(e){e.selectPageDown()},readOnly:!0},{name:"pagedown",bindKey:o(null,"Option-PageDown"),exec:function(e){e.scrollPageDown()},readOnly:!0},{name:"gotopagedown",bindKey:o("PageDown","PageDown|Ctrl-V"),exec:function(e){e.gotoPageDown()},readOnly:!0},{name:"selectpageup",bindKey:"Shift-PageUp",exec:function(e){e.selectPageUp()},readOnly:!0},{name:"pageup",bindKey:o(null,"Option-PageUp"),exec:function(e){e.scrollPageUp()},readOnly:!0},{name:"gotopageup",bindKey:"PageUp",exec:function(e){e.gotoPageUp()},readOnly:!0},{name:"scrollup",bindKey:o("Ctrl-Up",null),exec:function(e){e.renderer.scrollBy(0,-2*e.renderer.layerConfig.lineHeight)},readOnly:!0},{name:"scrolldown",bindKey:o("Ctrl-Down",null),exec:function(e){e.renderer.scrollBy(0,2*e.renderer.layerConfig.lineHeight)},readOnly:!0},{name:"selectlinestart",bindKey:"Shift-Home",exec:function(e){e.getSelection().selectLineStart()},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"selectlineend",bindKey:"Shift-End",exec:function(e){e.getSelection().selectLineEnd()},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"togglerecording",bindKey:o("Ctrl-Alt-E","Command-Option-E"),exec:function(e){e.commands.toggleRecording(e)},readOnly:!0},{name:"replaymacro",bindKey:o("Ctrl-Shift-E","Command-Shift-E"),exec:function(e){e.commands.replay(e)},readOnly:!0},{name:"jumptomatching",bindKey:o("Ctrl-P","Ctrl-P"),exec:function(e){e.jumpToMatching()},multiSelectAction:"forEach",scrollIntoView:"animate",readOnly:!0},{name:"selecttomatching",bindKey:o("Ctrl-Shift-P","Ctrl-Shift-P"),exec:function(e){e.jumpToMatching(!0)},multiSelectAction:"forEach",scrollIntoView:"animate",readOnly:!0},{name:"expandToMatching",bindKey:o("Ctrl-Shift-M","Ctrl-Shift-M"),exec:function(e){e.jumpToMatching(!0,!0)},multiSelectAction:"forEach",scrollIntoView:"animate",readOnly:!0},{name:"passKeysToBrowser",bindKey:o(null,null),exec:function(){},passEvent:!0,readOnly:!0},{name:"copy",exec:function(e){},readOnly:!0},{name:"cut",exec:function(e){var t=e.getSelectionRange();e._emit("cut",t),e.selection.isEmpty()||(e.session.remove(t),e.clearSelection())},scrollIntoView:"cursor",multiSelectAction:"forEach"},{name:"paste",exec:function(e,t){e.$handlePaste(t)},scrollIntoView:"cursor"},{name:"removeline",bindKey:o("Ctrl-D","Command-D"),exec:function(e){e.removeLines()},scrollIntoView:"cursor",multiSelectAction:"forEachLine"},{name:"duplicateSelection",bindKey:o("Ctrl-Shift-D","Command-Shift-D"),exec:function(e){e.duplicateSelection()},scrollIntoView:"cursor",multiSelectAction:"forEach"},{name:"sortlines",bindKey:o("Ctrl-Alt-S","Command-Alt-S"),exec:function(e){e.sortLines()},scrollIntoView:"selection",multiSelectAction:"forEachLine"},{name:"togglecomment",bindKey:o("Ctrl-/","Command-/"),exec:function(e){e.toggleCommentLines()},multiSelectAction:"forEachLine",scrollIntoView:"selectionPart"},{name:"toggleBlockComment",bindKey:o("Ctrl-Shift-/","Command-Shift-/"),exec:function(e){e.toggleBlockComment()},multiSelectAction:"forEach",scrollIntoView:"selectionPart"},{name:"modifyNumberUp",bindKey:o("Ctrl-Shift-Up","Alt-Shift-Up"),exec:function(e){e.modifyNumber(1)},scrollIntoView:"cursor",multiSelectAction:"forEach"},{name:"modifyNumberDown",bindKey:o("Ctrl-Shift-Down","Alt-Shift-Down"),exec:function(e){e.modifyNumber(-1)},scrollIntoView:"cursor",multiSelectAction:"forEach"},{name:"replace",bindKey:o("Ctrl-H","Command-Option-F"),exec:function(e){i.loadModule("ace/ext/searchbox",function(t){t.Search(e,!0)})}},{name:"undo",bindKey:o("Ctrl-Z","Command-Z"),exec:function(e){e.undo()}},{name:"redo",bindKey:o("Ctrl-Shift-Z|Ctrl-Y","Command-Shift-Z|Command-Y"),exec:function(e){e.redo()}},{name:"copylinesup",bindKey:o("Alt-Shift-Up","Command-Option-Up"),exec:function(e){e.copyLinesUp()},scrollIntoView:"cursor"},{name:"movelinesup",bindKey:o("Alt-Up","Option-Up"),exec:function(e){e.moveLinesUp()},scrollIntoView:"cursor"},{name:"copylinesdown",bindKey:o("Alt-Shift-Down","Command-Option-Down"),exec:function(e){e.copyLinesDown()},scrollIntoView:"cursor"},{name:"movelinesdown",bindKey:o("Alt-Down","Option-Down"),exec:function(e){e.moveLinesDown()},scrollIntoView:"cursor"},{name:"del",bindKey:o("Delete","Delete|Ctrl-D|Shift-Delete"),exec:function(e){e.remove("right")},multiSelectAction:"forEach",scrollIntoView:"cursor"},{name:"backspace",bindKey:o("Shift-Backspace|Backspace","Ctrl-Backspace|Shift-Backspace|Backspace|Ctrl-H"),exec:function(e){e.remove("left")},multiSelectAction:"forEach",scrollIntoView:"cursor"},{name:"cut_or_delete",bindKey:o("Shift-Delete",null),exec:function(e){if(!e.selection.isEmpty())return!1;e.remove("left")},multiSelectAction:"forEach",scrollIntoView:"cursor"},{name:"removetolinestart",bindKey:o("Alt-Backspace","Command-Backspace"),exec:function(e){e.removeToLineStart()},multiSelectAction:"forEach",scrollIntoView:"cursor"},{name:"removetolineend",bindKey:o("Alt-Delete","Ctrl-K"),exec:function(e){e.removeToLineEnd()},multiSelectAction:"forEach",scrollIntoView:"cursor"},{name:"removewordleft",bindKey:o("Ctrl-Backspace","Alt-Backspace|Ctrl-Alt-Backspace"),exec:function(e){e.removeWordLeft()},multiSelectAction:"forEach",scrollIntoView:"cursor"},{name:"removewordright",bindKey:o("Ctrl-Delete","Alt-Delete"),exec:function(e){e.removeWordRight()},multiSelectAction:"forEach",scrollIntoView:"cursor"},{name:"outdent",bindKey:o("Shift-Tab","Shift-Tab"),exec:function(e){e.blockOutdent()},multiSelectAction:"forEach",scrollIntoView:"selectionPart"},{name:"indent",bindKey:o("Tab","Tab"),exec:function(e){e.indent()},multiSelectAction:"forEach",scrollIntoView:"selectionPart"},{name:"blockoutdent",bindKey:o("Ctrl-[","Ctrl-["),exec:function(e){e.blockOutdent()},multiSelectAction:"forEachLine",scrollIntoView:"selectionPart"},{name:"blockindent",bindKey:o("Ctrl-]","Ctrl-]"),exec:function(e){e.blockIndent()},multiSelectAction:"forEachLine",scrollIntoView:"selectionPart"},{name:"insertstring",exec:function(e,t){e.insert(t)},multiSelectAction:"forEach",scrollIntoView:"cursor"},{name:"inserttext",exec:function(e,t){e.insert(r.stringRepeat(t.text||"",t.times||1))},multiSelectAction:"forEach",scrollIntoView:"cursor"},{name:"splitline",bindKey:o(null,"Ctrl-O"),exec:function(e){e.splitLine()},multiSelectAction:"forEach",scrollIntoView:"cursor"},{name:"transposeletters",bindKey:o("Ctrl-T","Ctrl-T"),exec:function(e){e.transposeLetters()},multiSelectAction:function(e){e.transposeSelections(1)},scrollIntoView:"cursor"},{name:"touppercase",bindKey:o("Ctrl-U","Ctrl-U"),exec:function(e){e.toUpperCase()},multiSelectAction:"forEach",scrollIntoView:"cursor"},{name:"tolowercase",bindKey:o("Ctrl-Shift-U","Ctrl-Shift-U"),exec:function(e){e.toLowerCase()},multiSelectAction:"forEach",scrollIntoView:"cursor"},{name:"expandtoline",bindKey:o("Ctrl-Shift-L","Command-Shift-L"),exec:function(e){var t=e.selection.getRange();t.start.column=t.end.column=0,t.end.row++,e.selection.setRange(t,!1)},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"joinlines",bindKey:o(null,null),exec:function(e){var t=e.selection.isBackwards(),n=t?e.selection.getSelectionLead():e.selection.getSelectionAnchor(),i=t?e.selection.getSelectionAnchor():e.selection.getSelectionLead(),o=e.session.doc.getLine(n.row).length,u=e.session.doc.getTextRange(e.selection.getRange()),a=u.replace(/\n\s*/," ").length,f=e.session.doc.getLine(n.row);for(var l=n.row+1;l<=i.row+1;l++){var c=r.stringTrimLeft(r.stringTrimRight(e.session.doc.getLine(l)));c.length!==0&&(c=" "+c),f+=c}i.row+10?(e.selection.moveCursorTo(n.row,n.column),e.selection.selectTo(n.row,n.column+a)):(o=e.session.doc.getLine(n.row).length>o?o+1:o,e.selection.moveCursorTo(n.row,o))},multiSelectAction:"forEach",readOnly:!0},{name:"invertSelection",bindKey:o(null,null),exec:function(e){var t=e.session.doc.getLength()-1,n=e.session.doc.getLine(t).length,r=e.selection.rangeList.ranges,i=[];r.length<1&&(r=[e.selection.getRange()]);for(var o=0;o0&&this.$blockScrolling--;var n=t&&t.scrollIntoView;if(n){switch(n){case"center-animate":n="animate";case"center":this.renderer.scrollCursorIntoView(null,.5);break;case"animate":case"cursor":this.renderer.scrollCursorIntoView();break;case"selectionPart":var r=this.selection.getRange(),i=this.renderer.layerConfig;(r.start.row>=i.lastRow||r.end.row<=i.firstRow)&&this.renderer.scrollSelectionIntoView(this.selection.anchor,this.selection.lead);break;default:}n=="animate"&&this.renderer.animateScrolling(this.curOp.scrollTop)}this.prevOp=this.curOp,this.curOp=null}},this.$mergeableCommands=["backspace","del","insertstring"],this.$historyTracker=function(e){if(!this.$mergeUndoDeltas)return;var t=this.prevOp,n=this.$mergeableCommands,r=t.command&&e.command.name==t.command.name;if(e.command.name=="insertstring"){var i=e.args;this.mergeNextCommand===undefined&&(this.mergeNextCommand=!0),r=r&&this.mergeNextCommand&&(!/\s/.test(i)||/\s/.test(t.args)),this.mergeNextCommand=!0}else r=r&&n.indexOf(e.command.name)!==-1;this.$mergeUndoDeltas!="always"&&Date.now()-this.sequenceStartTime>2e3&&(r=!1),r?this.session.mergeUndoDeltas=!0:n.indexOf(e.command.name)!==-1&&(this.sequenceStartTime=Date.now())},this.setKeyboardHandler=function(e,t){if(e&&typeof e=="string"){this.$keybindingId=e;var n=this;g.loadModule(["keybinding",e],function(r){n.$keybindingId==e&&n.keyBinding.setKeyboardHandler(r&&r.handler),t&&t()})}else this.$keybindingId=null,this.keyBinding.setKeyboardHandler(e),t&&t()},this.getKeyboardHandler=function(){return this.keyBinding.getKeyboardHandler()},this.setSession=function(e){if(this.session==e)return;this.curOp&&this.endOperation(),this.curOp={};var t=this.session;if(t){this.session.off("change",this.$onDocumentChange),this.session.off("changeMode",this.$onChangeMode),this.session.off("tokenizerUpdate",this.$onTokenizerUpdate),this.session.off("changeTabSize",this.$onChangeTabSize),this.session.off("changeWrapLimit",this.$onChangeWrapLimit),this.session.off("changeWrapMode",this.$onChangeWrapMode),this.session.off("changeFold",this.$onChangeFold),this.session.off("changeFrontMarker",this.$onChangeFrontMarker),this.session.off("changeBackMarker",this.$onChangeBackMarker),this.session.off("changeBreakpoint",this.$onChangeBreakpoint),this.session.off("changeAnnotation",this.$onChangeAnnotation),this.session.off("changeOverwrite",this.$onCursorChange),this.session.off("changeScrollTop",this.$onScrollTopChange),this.session.off("changeScrollLeft",this.$onScrollLeftChange);var n=this.session.getSelection();n.off("changeCursor",this.$onCursorChange),n.off("changeSelection",this.$onSelectionChange)}this.session=e,e?(this.$onDocumentChange=this.onDocumentChange.bind(this),e.on("change",this.$onDocumentChange),this.renderer.setSession(e),this.$onChangeMode=this.onChangeMode.bind(this),e.on("changeMode",this.$onChangeMode),this.$onTokenizerUpdate=this.onTokenizerUpdate.bind(this),e.on("tokenizerUpdate",this.$onTokenizerUpdate),this.$onChangeTabSize=this.renderer.onChangeTabSize.bind(this.renderer),e.on("changeTabSize",this.$onChangeTabSize),this.$onChangeWrapLimit=this.onChangeWrapLimit.bind(this),e.on("changeWrapLimit",this.$onChangeWrapLimit),this.$onChangeWrapMode=this.onChangeWrapMode.bind(this),e.on("changeWrapMode",this.$onChangeWrapMode),this.$onChangeFold=this.onChangeFold.bind(this),e.on("changeFold",this.$onChangeFold),this.$onChangeFrontMarker=this.onChangeFrontMarker.bind(this),this.session.on("changeFrontMarker",this.$onChangeFrontMarker),this.$onChangeBackMarker=this.onChangeBackMarker.bind(this),this.session.on("changeBackMarker",this.$onChangeBackMarker),this.$onChangeBreakpoint=this.onChangeBreakpoint.bind(this),this.session.on("changeBreakpoint",this.$onChangeBreakpoint),this.$onChangeAnnotation=this.onChangeAnnotation.bind(this),this.session.on("changeAnnotation",this.$onChangeAnnotation),this.$onCursorChange=this.onCursorChange.bind(this),this.session.on("changeOverwrite",this.$onCursorChange),this.$onScrollTopChange=this.onScrollTopChange.bind(this),this.session.on("changeScrollTop",this.$onScrollTopChange),this.$onScrollLeftChange=this.onScrollLeftChange.bind(this),this.session.on("changeScrollLeft",this.$onScrollLeftChange),this.selection=e.getSelection(),this.selection.on("changeCursor",this.$onCursorChange),this.$onSelectionChange=this.onSelectionChange.bind(this),this.selection.on("changeSelection",this.$onSelectionChange),this.onChangeMode(),this.$blockScrolling+=1,this.onCursorChange(),this.$blockScrolling-=1,this.onScrollTopChange(),this.onScrollLeftChange(),this.onSelectionChange(),this.onChangeFrontMarker(),this.onChangeBackMarker(),this.onChangeBreakpoint(),this.onChangeAnnotation(),this.session.getUseWrapMode()&&this.renderer.adjustWrapLimit(),this.renderer.updateFull()):(this.selection=null,this.renderer.setSession(e)),this._signal("changeSession",{session:e,oldSession:t}),this.curOp=null,t&&t._signal("changeEditor",{oldEditor:this}),e&&e._signal("changeEditor",{editor:this})},this.getSession=function(){return this.session},this.setValue=function(e,t){return this.session.doc.setValue(e),t?t==1?this.navigateFileEnd():t==-1&&this.navigateFileStart():this.selectAll(),e},this.getValue=function(){return this.session.getValue()},this.getSelection=function(){return this.selection},this.resize=function(e){this.renderer.onResize(e)},this.setTheme=function(e,t){this.renderer.setTheme(e,t)},this.getTheme=function(){return this.renderer.getTheme()},this.setStyle=function(e){this.renderer.setStyle(e)},this.unsetStyle=function(e){this.renderer.unsetStyle(e)},this.getFontSize=function(){return this.getOption("fontSize")||i.computedStyle(this.container,"fontSize")},this.setFontSize=function(e){this.setOption("fontSize",e)},this.$highlightBrackets=function(){this.session.$bracketHighlight&&(this.session.removeMarker(this.session.$bracketHighlight),this.session.$bracketHighlight=null);if(this.$highlightPending)return;var e=this;this.$highlightPending=!0,setTimeout(function(){e.$highlightPending=!1;var t=e.session;if(!t||!t.bgTokenizer)return;var n=t.findMatchingBracket(e.getCursorPosition());if(n)var r=new p(n.row,n.column,n.row,n.column+1);else if(t.$mode.getMatching)var r=t.$mode.getMatching(e.session);r&&(t.$bracketHighlight=t.addMarker(r,"ace_bracket","text"))},50)},this.$highlightTags=function(){if(this.$highlightTagPending)return;var e=this;this.$highlightTagPending=!0,setTimeout(function(){e.$highlightTagPending=!1;var t=e.session;if(!t||!t.bgTokenizer)return;var n=e.getCursorPosition(),r=new y(e.session,n.row,n.column),i=r.getCurrentToken();if(!i||!/\b(?:tag-open|tag-name)/.test(i.type)){t.removeMarker(t.$tagHighlight),t.$tagHighlight=null;return}if(i.type.indexOf("tag-open")!=-1){i=r.stepForward();if(!i)return}var s=i.value,o=0,u=r.stepBackward();if(u.value=="<"){do u=i,i=r.stepForward(),i&&i.value===s&&i.type.indexOf("tag-name")!==-1&&(u.value==="<"?o++:u.value==="=0)}else{do i=u,u=r.stepBackward(),i&&i.value===s&&i.type.indexOf("tag-name")!==-1&&(u.value==="<"?o++:u.value==="1)&&(t=!1)}if(e.$highlightLineMarker&&!t)e.removeMarker(e.$highlightLineMarker.id),e.$highlightLineMarker=null;else if(!e.$highlightLineMarker&&t){var n=new p(t.row,t.column,t.row,Infinity);n.id=e.addMarker(n,"ace_active-line","screenLine"),e.$highlightLineMarker=n}else t&&(e.$highlightLineMarker.start.row=t.row,e.$highlightLineMarker.end.row=t.row,e.$highlightLineMarker.start.column=t.column,e._signal("changeBackMarker"))},this.onSelectionChange=function(e){var t=this.session;t.$selectionMarker&&t.removeMarker(t.$selectionMarker),t.$selectionMarker=null;if(!this.selection.isEmpty()){var n=this.selection.getRange(),r=this.getSelectionStyle();t.$selectionMarker=t.addMarker(n,"ace_selection",r)}else this.$updateHighlightActiveLine();var i=this.$highlightSelectedWord&&this.$getSelectionHighLightRegexp();this.session.highlight(i),this._signal("changeSelection")},this.$getSelectionHighLightRegexp=function(){var e=this.session,t=this.getSelectionRange();if(t.isEmpty()||t.isMultiLine())return;var n=t.start.column-1,r=t.end.column+1,i=e.getLine(t.start.row),s=i.length,o=i.substring(Math.max(n,0),Math.min(r,s));if(n>=0&&/^[\w\d]/.test(o)||r<=s&&/[\w\d]$/.test(o))return;o=i.substring(t.start.column,t.end.column);if(!/^[\w\d]+$/.test(o))return;var u=this.$search.$assembleRegExp({wholeWord:!0,caseSensitive:!0,needle:o});return u},this.onChangeFrontMarker=function(){this.renderer.updateFrontMarkers()},this.onChangeBackMarker=function(){this.renderer.updateBackMarkers()},this.onChangeBreakpoint=function(){this.renderer.updateBreakpoints()},this.onChangeAnnotation=function(){this.renderer.setAnnotations(this.session.getAnnotations())},this.onChangeMode=function(e){this.renderer.updateText(),this._emit("changeMode",e)},this.onChangeWrapLimit=function(){this.renderer.updateFull()},this.onChangeWrapMode=function(){this.renderer.onResize(!0)},this.onChangeFold=function(){this.$updateHighlightActiveLine(),this.renderer.updateFull()},this.getSelectedText=function(){return this.session.getTextRange(this.getSelectionRange())},this.getCopyText=function(){var e=this.getSelectedText();return this._signal("copy",e),e},this.onCopy=function(){this.commands.exec("copy",this)},this.onCut=function(){this.commands.exec("cut",this)},this.onPaste=function(e,t){var n={text:e,event:t};this.commands.exec("paste",this,n)},this.$handlePaste=function(e){typeof e=="string"&&(e={text:e}),this._signal("paste",e);var t=e.text;if(!this.inMultiSelectMode||this.inVirtualSelectionMode)this.insert(t);else{var n=t.split(/\r\n|\r|\n/),r=this.selection.rangeList.ranges;if(n.length>r.length||n.length<2||!n[1])return this.commands.exec("insertstring",this,t);for(var i=r.length;i--;){var s=r[i];s.isEmpty()||this.session.remove(s),this.session.insert(s.start,n[i])}}},this.execCommand=function(e,t){return this.commands.exec(e,this,t)},this.insert=function(e,t){var n=this.session,r=n.getMode(),i=this.getCursorPosition();if(this.getBehavioursEnabled()&&!t){var s=r.transformAction(n.getState(i.row),"insertion",this,n,e);s&&(e!==s.text&&(this.session.mergeUndoDeltas=!1,this.$mergeNextCommand=!1),e=s.text)}e==" "&&(e=this.session.getTabString());if(!this.selection.isEmpty()){var o=this.getSelectionRange();i=this.session.remove(o),this.clearSelection()}else if(this.session.getOverwrite()){var o=new p.fromPoints(i,i);o.end.column+=e.length,this.session.remove(o)}if(e=="\n"||e=="\r\n"){var u=n.getLine(i.row);if(i.column>u.search(/\S|$/)){var a=u.substr(i.column).search(/\S|$/);n.doc.removeInLine(i.row,i.column,i.column+a)}}this.clearSelection();var f=i.column,l=n.getState(i.row),u=n.getLine(i.row),c=r.checkOutdent(l,u,e),h=n.insert(i,e);s&&s.selection&&(s.selection.length==2?this.selection.setSelectionRange(new p(i.row,f+s.selection[0],i.row,f+s.selection[1])):this.selection.setSelectionRange(new p(i.row+s.selection[0],s.selection[1],i.row+s.selection[2],s.selection[3])));if(n.getDocument().isNewLine(e)){var d=r.getNextLineIndent(l,u.slice(0,i.column),n.getTabString());n.insert({row:i.row+1,column:0},d)}c&&r.autoOutdent(l,n,i.row)},this.onTextInput=function(e){this.keyBinding.onTextInput(e)},this.onCommandKey=function(e,t,n){this.keyBinding.onCommandKey(e,t,n)},this.setOverwrite=function(e){this.session.setOverwrite(e)},this.getOverwrite=function(){return this.session.getOverwrite()},this.toggleOverwrite=function(){this.session.toggleOverwrite()},this.setScrollSpeed=function(e){this.setOption("scrollSpeed",e)},this.getScrollSpeed=function(){return this.getOption("scrollSpeed")},this.setDragDelay=function(e){this.setOption("dragDelay",e)},this.getDragDelay=function(){return this.getOption("dragDelay")},this.setSelectionStyle=function(e){this.setOption("selectionStyle",e)},this.getSelectionStyle=function(){return this.getOption("selectionStyle")},this.setHighlightActiveLine=function(e){this.setOption("highlightActiveLine",e)},this.getHighlightActiveLine=function(){return this.getOption("highlightActiveLine")},this.setHighlightGutterLine=function(e){this.setOption("highlightGutterLine",e)},this.getHighlightGutterLine=function(){return this.getOption("highlightGutterLine")},this.setHighlightSelectedWord=function(e){this.setOption("highlightSelectedWord",e)},this.getHighlightSelectedWord=function(){return this.$highlightSelectedWord},this.setAnimatedScroll=function(e){this.renderer.setAnimatedScroll(e)},this.getAnimatedScroll=function(){return this.renderer.getAnimatedScroll()},this.setShowInvisibles=function(e){this.renderer.setShowInvisibles(e)},this.getShowInvisibles=function(){return this.renderer.getShowInvisibles()},this.setDisplayIndentGuides=function(e){this.renderer.setDisplayIndentGuides(e)},this.getDisplayIndentGuides=function(){return this.renderer.getDisplayIndentGuides()},this.setShowPrintMargin=function(e){this.renderer.setShowPrintMargin(e)},this.getShowPrintMargin=function(){return this.renderer.getShowPrintMargin()},this.setPrintMarginColumn=function(e){this.renderer.setPrintMarginColumn(e)},this.getPrintMarginColumn=function(){return this.renderer.getPrintMarginColumn()},this.setReadOnly=function(e){this.setOption("readOnly",e)},this.getReadOnly=function(){return this.getOption("readOnly")},this.setBehavioursEnabled=function(e){this.setOption("behavioursEnabled",e)},this.getBehavioursEnabled=function(){return this.getOption("behavioursEnabled")},this.setWrapBehavioursEnabled=function(e){this.setOption("wrapBehavioursEnabled",e)},this.getWrapBehavioursEnabled=function(){return this.getOption("wrapBehavioursEnabled")},this.setShowFoldWidgets=function(e){this.setOption("showFoldWidgets",e)},this.getShowFoldWidgets=function(){return this.getOption("showFoldWidgets")},this.setFadeFoldWidgets=function(e){this.setOption("fadeFoldWidgets",e)},this.getFadeFoldWidgets=function(){return this.getOption("fadeFoldWidgets")},this.remove=function(e){this.selection.isEmpty()&&(e=="left"?this.selection.selectLeft():this.selection.selectRight());var t=this.getSelectionRange();if(this.getBehavioursEnabled()){var n=this.session,r=n.getState(t.start.row),i=n.getMode().transformAction(r,"deletion",this,n,t);if(t.end.column===0){var s=n.getTextRange(t);if(s[s.length-1]=="\n"){var o=n.getLine(t.end.row);/^\s+$/.test(o)&&(t.end.column=o.length)}}i&&(t=i)}this.session.remove(t),this.clearSelection()},this.removeWordRight=function(){this.selection.isEmpty()&&this.selection.selectWordRight(),this.session.remove(this.getSelectionRange()),this.clearSelection()},this.removeWordLeft=function(){this.selection.isEmpty()&&this.selection.selectWordLeft(),this.session.remove(this.getSelectionRange()),this.clearSelection()},this.removeToLineStart=function(){this.selection.isEmpty()&&this.selection.selectLineStart(),this.session.remove(this.getSelectionRange()),this.clearSelection()},this.removeToLineEnd=function(){this.selection.isEmpty()&&this.selection.selectLineEnd();var e=this.getSelectionRange();e.start.column==e.end.column&&e.start.row==e.end.row&&(e.end.column=0,e.end.row++),this.session.remove(e),this.clearSelection()},this.splitLine=function(){this.selection.isEmpty()||(this.session.remove(this.getSelectionRange()),this.clearSelection());var e=this.getCursorPosition();this.insert("\n"),this.moveCursorToPosition(e)},this.transposeLetters=function(){if(!this.selection.isEmpty())return;var e=this.getCursorPosition(),t=e.column;if(t===0)return;var n=this.session.getLine(e.row),r,i;tt.toLowerCase()?1:0});var r=new p(0,0,0,0);for(var i=e.first;i<=e.last;i++){var s=t.getLine(i);r.start.row=i,r.end.row=i,r.end.column=s.length,t.replace(r,n[i-e.first])}},this.toggleCommentLines=function(){var e=this.session.getState(this.getCursorPosition().row),t=this.$getSelectedRows();this.session.getMode().toggleCommentLines(e,this.session,t.first,t.last)},this.toggleBlockComment=function(){var e=this.getCursorPosition(),t=this.session.getState(e.row),n=this.getSelectionRange();this.session.getMode().toggleBlockComment(t,this.session,n,e)},this.getNumberAt=function(e,t){var n=/[\-]?[0-9]+(?:\.[0-9]+)?/g;n.lastIndex=0;var r=this.session.getLine(e);while(n.lastIndex=t){var s={value:i[0],start:i.index,end:i.index+i[0].length};return s}}return null},this.modifyNumber=function(e){var t=this.selection.getCursor().row,n=this.selection.getCursor().column,r=new p(t,n-1,t,n),i=this.session.getTextRange(r);if(!isNaN(parseFloat(i))&&isFinite(i)){var s=this.getNumberAt(t,n);if(s){var o=s.value.indexOf(".")>=0?s.start+s.value.indexOf(".")+1:s.end,u=s.start+s.value.length-o,a=parseFloat(s.value);a*=Math.pow(10,u),o!==s.end&&np+1)break;p=d.last}l--,u=this.session.$moveLines(h,p,t?0:e),t&&e==-1&&(c=l+1);while(c<=l)o[c].moveBy(u,0),c++;t||(u=0),a+=u}i.fromOrientedRange(i.ranges[0]),i.rangeList.attach(this.session),this.inVirtualSelectionMode=!1}},this.$getSelectedRows=function(e){return e=(e||this.getSelectionRange()).collapseRows(),{first:this.session.getRowFoldStart(e.start.row),last:this.session.getRowFoldEnd(e.end.row)}},this.onCompositionStart=function(e){this.renderer.showComposition(this.getCursorPosition())},this.onCompositionUpdate=function(e){this.renderer.setCompositionText(e)},this.onCompositionEnd=function(){this.renderer.hideComposition()},this.getFirstVisibleRow=function(){return this.renderer.getFirstVisibleRow()},this.getLastVisibleRow=function(){return this.renderer.getLastVisibleRow()},this.isRowVisible=function(e){return e>=this.getFirstVisibleRow()&&e<=this.getLastVisibleRow()},this.isRowFullyVisible=function(e){return e>=this.renderer.getFirstFullyVisibleRow()&&e<=this.renderer.getLastFullyVisibleRow()},this.$getVisibleRowCount=function(){return this.renderer.getScrollBottomRow()-this.renderer.getScrollTopRow()+1},this.$moveByPage=function(e,t){var n=this.renderer,r=this.renderer.layerConfig,i=e*Math.floor(r.height/r.lineHeight);this.$blockScrolling++,t===!0?this.selection.$moveSelection(function(){this.moveCursorBy(i,0)}):t===!1&&(this.selection.moveCursorBy(i,0),this.selection.clearSelection()),this.$blockScrolling--;var s=n.scrollTop;n.scrollBy(0,i*r.lineHeight),t!=null&&n.scrollCursorIntoView(null,.5),n.animateScrolling(s)},this.selectPageDown=function(){this.$moveByPage(1,!0)},this.selectPageUp=function(){this.$moveByPage(-1,!0)},this.gotoPageDown=function(){this.$moveByPage(1,!1)},this.gotoPageUp=function(){this.$moveByPage(-1,!1)},this.scrollPageDown=function(){this.$moveByPage(1)},this.scrollPageUp=function(){this.$moveByPage(-1)},this.scrollToRow=function(e){this.renderer.scrollToRow(e)},this.scrollToLine=function(e,t,n,r){this.renderer.scrollToLine(e,t,n,r)},this.centerSelection=function(){var e=this.getSelectionRange(),t={row:Math.floor(e.start.row+(e.end.row-e.start.row)/2),column:Math.floor(e.start.column+(e.end.column-e.start.column)/2)};this.renderer.alignCursor(t,.5)},this.getCursorPosition=function(){return this.selection.getCursor()},this.getCursorPositionScreen=function(){return this.session.documentToScreenPosition(this.getCursorPosition())},this.getSelectionRange=function(){return this.selection.getRange()},this.selectAll=function(){this.$blockScrolling+=1,this.selection.selectAll(),this.$blockScrolling-=1},this.clearSelection=function(){this.selection.clearSelection()},this.moveCursorTo=function(e,t){this.selection.moveCursorTo(e,t)},this.moveCursorToPosition=function(e){this.selection.moveCursorToPosition(e)},this.jumpToMatching=function(e,t){var n=this.getCursorPosition(),r=new y(this.session,n.row,n.column),i=r.getCurrentToken(),s=i||r.stepForward();if(!s)return;var o,u=!1,a={},f=n.column-s.start,l,c={")":"(","(":"(","]":"[","[":"[","{":"{","}":"{"};do{if(s.value.match(/[{}()\[\]]/g))for(;f=0;--s)this.$tryReplace(n[s],e)&&r++;return this.selection.setSelectionRange(i),this.$blockScrolling-=1,r},this.$tryReplace=function(e,t){var n=this.session.getTextRange(e);return t=this.$search.replace(n,t),t!==null?(e.end=this.session.replace(e,t),e):null},this.getLastSearchOptions=function(){return this.$search.getOptions()},this.find=function(e,t,n){t||(t={}),typeof e=="string"||e instanceof RegExp?t.needle=e:typeof e=="object"&&r.mixin(t,e);var i=this.selection.getRange();t.needle==null&&(e=this.session.getTextRange(i)||this.$search.$options.needle,e||(i=this.session.getWordRange(i.start.row,i.start.column),e=this.session.getTextRange(i)),this.$search.set({needle:e})),this.$search.set(t),t.start||this.$search.set({start:i});var s=this.$search.find(this.session);if(t.preventScroll)return s;if(s)return this.revealRange(s,n),s;t.backwards?i.start=i.end:i.end=i.start,this.selection.setRange(i)},this.findNext=function(e,t){this.find({skipCurrent:!0,backwards:!1},e,t)},this.findPrevious=function(e,t){this.find(e,{skipCurrent:!0,backwards:!0},t)},this.revealRange=function(e,t){this.$blockScrolling+=1,this.session.unfold(e),this.selection.setSelectionRange(e),this.$blockScrolling-=1;var n=this.renderer.scrollTop;this.renderer.scrollSelectionIntoView(e.start,e.end,.5),t!==!1&&this.renderer.animateScrolling(n)},this.undo=function(){this.$blockScrolling++,this.session.getUndoManager().undo(),this.$blockScrolling--,this.renderer.scrollCursorIntoView(null,.5)},this.redo=function(){this.$blockScrolling++,this.session.getUndoManager().redo(),this.$blockScrolling--,this.renderer.scrollCursorIntoView(null,.5)},this.destroy=function(){this.renderer.destroy(),this._signal("destroy",this),this.session&&this.session.destroy()},this.setAutoScrollEditorIntoView=function(e){if(!e)return;var t,n=this,r=!1;this.$scrollAnchor||(this.$scrollAnchor=document.createElement("div"));var i=this.$scrollAnchor;i.style.cssText="position:absolute",this.container.insertBefore(i,this.container.firstChild);var s=this.on("changeSelection",function(){r=!0}),o=this.renderer.on("beforeRender",function(){r&&(t=n.renderer.container.getBoundingClientRect())}),u=this.renderer.on("afterRender",function(){if(r&&t&&(n.isFocused()||n.searchBox&&n.searchBox.isFocused())){var e=n.renderer,s=e.$cursorLayer.$pixelPos,o=e.layerConfig,u=s.top-o.offset;s.top>=0&&u+t.top<0?r=!0:s.topwindow.innerHeight?r=!1:r=null,r!=null&&(i.style.top=u+"px",i.style.left=s.left+"px",i.style.height=o.lineHeight+"px",i.scrollIntoView(r)),r=t=null}});this.setAutoScrollEditorIntoView=function(e){if(e)return;delete this.setAutoScrollEditorIntoView,this.off("changeSelection",s),this.renderer.off("afterRender",u),this.renderer.off("beforeRender",o)}},this.$resetCursorStyle=function(){var e=this.$cursorStyle||"ace",t=this.renderer.$cursorLayer;if(!t)return;t.setSmoothBlinking(/smooth/.test(e)),t.isBlinking=!this.$readOnly&&e!="wide",i.setCssClass(t.element,"ace_slim-cursors",/slim/.test(e))}}).call(b.prototype),g.defineOptions(b.prototype,"editor",{selectionStyle:{set:function(e){this.onSelectionChange(),this._signal("changeSelectionStyle",{data:e})},initialValue:"line"},highlightActiveLine:{set:function(){this.$updateHighlightActiveLine()},initialValue:!0},highlightSelectedWord:{set:function(e){this.$onSelectionChange()},initialValue:!0},readOnly:{set:function(e){this.$resetCursorStyle()},initialValue:!1},cursorStyle:{set:function(e){this.$resetCursorStyle()},values:["ace","slim","smooth","wide"],initialValue:"ace"},mergeUndoDeltas:{values:[!1,!0,"always"],initialValue:!0},behavioursEnabled:{initialValue:!0},wrapBehavioursEnabled:{initialValue:!0},autoScrollEditorIntoView:{set:function(e){this.setAutoScrollEditorIntoView(e)}},keyboardHandler:{set:function(e){this.setKeyboardHandler(e)},get:function(){return this.keybindingId},handlesSet:!0},hScrollBarAlwaysVisible:"renderer",vScrollBarAlwaysVisible:"renderer",highlightGutterLine:"renderer",animatedScroll:"renderer",showInvisibles:"renderer",showPrintMargin:"renderer",printMarginColumn:"renderer",printMargin:"renderer",fadeFoldWidgets:"renderer",showFoldWidgets:"renderer",showLineNumbers:"renderer",showGutter:"renderer",displayIndentGuides:"renderer",fontSize:"renderer",fontFamily:"renderer",maxLines:"renderer",minLines:"renderer",scrollPastEnd:"renderer",fixedWidthGutter:"renderer",theme:"renderer",scrollSpeed:"$mouseHandler",dragDelay:"$mouseHandler",dragEnabled:"$mouseHandler",focusTimout:"$mouseHandler",tooltipFollowsMouse:"$mouseHandler",firstLineNumber:"session",overwrite:"session",newLineMode:"session",useWorker:"session",useSoftTabs:"session",tabSize:"session",wrap:"session",indentedSoftWrap:"session",foldStyle:"session",mode:"session"}),t.Editor=b}),define("ace/undomanager",["require","exports","module"],function(e,t,n){"use strict";var r=function(){this.reset()};(function(){function e(e){return{action:e.action,start:e.start,end:e.end,lines:e.lines.length==1?null:e.lines,text:e.lines.length==1?e.lines[0]:null}}function t(e){return{action:e.action,start:e.start,end:e.end,lines:e.lines||[e.text]}}function n(e,t){var n=new Array(e.length);for(var r=0;r0},this.hasRedo=function(){return this.$redoStack.length>0},this.markClean=function(){this.dirtyCounter=0},this.isClean=function(){return this.dirtyCounter===0},this.$serializeDeltas=function(t){return n(t,e)},this.$deserializeDeltas=function(e){return n(e,t)}}).call(r.prototype),t.UndoManager=r}),define("ace/layer/gutter",["require","exports","module","ace/lib/dom","ace/lib/oop","ace/lib/lang","ace/lib/event_emitter"],function(e,t,n){"use strict";var r=e("../lib/dom"),i=e("../lib/oop"),s=e("../lib/lang"),o=e("../lib/event_emitter").EventEmitter,u=function(e){this.element=r.createElement("div"),this.element.className="ace_layer ace_gutter-layer",e.appendChild(this.element),this.setShowFoldWidgets(this.$showFoldWidgets),this.gutterWidth=0,this.$annotations=[],this.$updateAnnotations=this.$updateAnnotations.bind(this),this.$cells=[]};(function(){i.implement(this,o),this.setSession=function(e){this.session&&this.session.removeEventListener("change",this.$updateAnnotations),this.session=e,e&&e.on("change",this.$updateAnnotations)},this.addGutterDecoration=function(e,t){window.console&&console.warn&&console.warn("deprecated use session.addGutterDecoration"),this.session.addGutterDecoration(e,t)},this.removeGutterDecoration=function(e,t){window.console&&console.warn&&console.warn("deprecated use session.removeGutterDecoration"),this.session.removeGutterDecoration(e,t)},this.setAnnotations=function(e){this.$annotations=[];for(var t=0;to&&(v=s.end.row+1,s=t.getNextFoldLine(v,s),o=s?s.start.row:Infinity);if(v>i){while(this.$cells.length>d+1)p=this.$cells.pop(),this.element.removeChild(p.element);break}p=this.$cells[++d],p||(p={element:null,textNode:null,foldWidget:null},p.element=r.createElement("div"),p.textNode=document.createTextNode(""),p.element.appendChild(p.textNode),this.element.appendChild(p.element),this.$cells[d]=p);var m="ace_gutter-cell ";a[v]&&(m+=a[v]),f[v]&&(m+=f[v]),this.$annotations[v]&&(m+=this.$annotations[v].className),p.element.className!=m&&(p.element.className=m);var g=t.getRowLength(v)*e.lineHeight+"px";g!=p.element.style.height&&(p.element.style.height=g);if(u){var y=u[v];y==null&&(y=u[v]=t.getFoldWidget(v))}if(y){p.foldWidget||(p.foldWidget=r.createElement("span"),p.element.appendChild(p.foldWidget));var m="ace_fold-widget ace_"+y;y=="start"&&v==o&&vn.right-t.right)return"foldWidgets"}}).call(u.prototype),t.Gutter=u}),define("ace/layer/marker",["require","exports","module","ace/range","ace/lib/dom"],function(e,t,n){"use strict";var r=e("../range").Range,i=e("../lib/dom"),s=function(e){this.element=i.createElement("div"),this.element.className="ace_layer ace_marker-layer",e.appendChild(this.element)};(function(){function e(e,t,n,r){return(e?1:0)|(t?2:0)|(n?4:0)|(r?8:0)}this.$padding=0,this.setPadding=function(e){this.$padding=e},this.setSession=function(e){this.session=e},this.setMarkers=function(e){this.markers=e},this.update=function(e){var e=e||this.config;if(!e)return;this.config=e;var t=[];for(var n in this.markers){var r=this.markers[n];if(!r.range){r.update(t,this,this.session,e);continue}var i=r.range.clipRows(e.firstRow,e.lastRow);if(i.isEmpty())continue;i=i.toScreenRange(this.session);if(r.renderer){var s=this.$getTop(i.start.row,e),o=this.$padding+i.start.column*e.characterWidth;r.renderer(t,i,o,s,e)}else r.type=="fullLine"?this.drawFullLineMarker(t,i,r.clazz,e):r.type=="screenLine"?this.drawScreenLineMarker(t,i,r.clazz,e):i.isMultiLine()?r.type=="text"?this.drawTextMarker(t,i,r.clazz,e):this.drawMultiLineMarker(t,i,r.clazz,e):this.drawSingleLineMarker(t,i,r.clazz+" ace_start"+" ace_br15",e)}this.element.innerHTML=t.join("")},this.$getTop=function(e,t){return(e-t.firstRowScreen)*t.lineHeight},this.drawTextMarker=function(t,n,i,s,o){var u=this.session,a=n.start.row,f=n.end.row,l=a,c=0,h=0,p=u.getScreenLastRowColumn(l),d=new r(l,n.start.column,l,h);for(;l<=f;l++)d.start.row=d.end.row=l,d.start.column=l==a?n.start.column:u.getRowWrapIndent(l),d.end.column=p,c=h,h=p,p=l+1p,l==f),s,l==f?0:1,o)},this.drawMultiLineMarker=function(e,t,n,r,i){var s=this.$padding,o=r.lineHeight,u=this.$getTop(t.start.row,r),a=s+t.start.column*r.characterWidth;i=i||"",e.push("
"),u=this.$getTop(t.end.row,r);var f=t.end.column*r.characterWidth;e.push("
"),o=(t.end.row-t.start.row-1)*r.lineHeight;if(o<=0)return;u=this.$getTop(t.start.row+1,r);var l=(t.start.column?1:0)|(t.end.column?0:8);e.push("
")},this.drawSingleLineMarker=function(e,t,n,r,i,s){var o=r.lineHeight,u=(t.end.column+(i||0)-t.start.column)*r.characterWidth,a=this.$getTop(t.start.row,r),f=this.$padding+t.start.column*r.characterWidth;e.push("
")},this.drawFullLineMarker=function(e,t,n,r,i){var s=this.$getTop(t.start.row,r),o=r.lineHeight;t.start.row!=t.end.row&&(o+=this.$getTop(t.end.row,r)-s),e.push("
")},this.drawScreenLineMarker=function(e,t,n,r,i){var s=this.$getTop(t.start.row,r),o=r.lineHeight;e.push("
")}}).call(s.prototype),t.Marker=s}),define("ace/layer/text",["require","exports","module","ace/lib/oop","ace/lib/dom","ace/lib/lang","ace/lib/useragent","ace/lib/event_emitter"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/dom"),s=e("../lib/lang"),o=e("../lib/useragent"),u=e("../lib/event_emitter").EventEmitter,a=function(e){this.element=i.createElement("div"),this.element.className="ace_layer ace_text-layer",e.appendChild(this.element),this.$updateEolChar=this.$updateEolChar.bind(this)};(function(){r.implement(this,u),this.EOF_CHAR="\u00b6",this.EOL_CHAR_LF="\u00ac",this.EOL_CHAR_CRLF="\u00a4",this.EOL_CHAR=this.EOL_CHAR_LF,this.TAB_CHAR="\u2014",this.SPACE_CHAR="\u00b7",this.$padding=0,this.$updateEolChar=function(){var e=this.session.doc.getNewLineCharacter()=="\n"?this.EOL_CHAR_LF:this.EOL_CHAR_CRLF;if(this.EOL_CHAR!=e)return this.EOL_CHAR=e,!0},this.setPadding=function(e){this.$padding=e,this.element.style.padding="0 "+e+"px"},this.getLineHeight=function(){return this.$fontMetrics.$characterSize.height||0},this.getCharacterWidth=function(){return this.$fontMetrics.$characterSize.width||0},this.$setFontMetrics=function(e){this.$fontMetrics=e,this.$fontMetrics.on("changeCharacterSize",function(e){this._signal("changeCharacterSize",e)}.bind(this)),this.$pollSizeChanges()},this.checkForSizeChanges=function(){this.$fontMetrics.checkForSizeChanges()},this.$pollSizeChanges=function(){return this.$pollSizeChangesTimer=this.$fontMetrics.$pollSizeChanges()},this.setSession=function(e){this.session=e,e&&this.$computeTabString()},this.showInvisibles=!1,this.setShowInvisibles=function(e){return this.showInvisibles==e?!1:(this.showInvisibles=e,this.$computeTabString(),!0)},this.displayIndentGuides=!0,this.setDisplayIndentGuides=function(e){return this.displayIndentGuides==e?!1:(this.displayIndentGuides=e,this.$computeTabString(),!0)},this.$tabStrings=[],this.onChangeTabSize=this.$computeTabString=function(){var e=this.session.getTabSize();this.tabSize=e;var t=this.$tabStrings=[0];for(var n=1;n"+s.stringRepeat(this.TAB_CHAR,n)+""):t.push(s.stringRepeat(" ",n));if(this.displayIndentGuides){this.$indentGuideRe=/\s\S| \t|\t |\s$/;var r="ace_indent-guide",i="",o="";if(this.showInvisibles){r+=" ace_invisible",i=" ace_invisible_space",o=" ace_invisible_tab";var u=s.stringRepeat(this.SPACE_CHAR,this.tabSize),a=s.stringRepeat(this.TAB_CHAR,this.tabSize)}else var u=s.stringRepeat(" ",this.tabSize),a=u;this.$tabStrings[" "]=""+u+"",this.$tabStrings[" "]=""+a+""}},this.updateLines=function(e,t,n){(this.config.lastRow!=e.lastRow||this.config.firstRow!=e.firstRow)&&this.scrollLines(e),this.config=e;var r=Math.max(t,e.firstRow),i=Math.min(n,e.lastRow),s=this.element.childNodes,o=0;for(var u=e.firstRow;uf&&(u=a.end.row+1,a=this.session.getNextFoldLine(u,a),f=a?a.start.row:Infinity);if(u>i)break;var l=s[o++];if(l){var c=[];this.$renderLine(c,u,!this.$useLineGroups(),u==f?a:!1),l.style.height=e.lineHeight*this.session.getRowLength(u)+"px",l.innerHTML=c.join("")}u++}},this.scrollLines=function(e){var t=this.config;this.config=e;if(!t||t.lastRow0;r--)n.removeChild(n.firstChild);if(t.lastRow>e.lastRow)for(var r=this.session.getFoldedRowCount(e.lastRow+1,t.lastRow);r>0;r--)n.removeChild(n.lastChild);if(e.firstRowt.lastRow){var i=this.$renderLinesFragment(e,t.lastRow+1,e.lastRow);n.appendChild(i)}},this.$renderLinesFragment=function(e,t,n){var r=this.element.ownerDocument.createDocumentFragment(),s=t,o=this.session.getNextFoldLine(s),u=o?o.start.row:Infinity;for(;;){s>u&&(s=o.end.row+1,o=this.session.getNextFoldLine(s,o),u=o?o.start.row:Infinity);if(s>n)break;var a=i.createElement("div"),f=[];this.$renderLine(f,s,!1,s==u?o:!1),a.innerHTML=f.join("");if(this.$useLineGroups())a.className="ace_line_group",r.appendChild(a),a.style.height=e.lineHeight*this.session.getRowLength(s)+"px";else while(a.firstChild)r.appendChild(a.firstChild);s++}return r},this.update=function(e){this.config=e;var t=[],n=e.firstRow,r=e.lastRow,i=n,s=this.session.getNextFoldLine(i),o=s?s.start.row:Infinity;for(;;){i>o&&(i=s.end.row+1,s=this.session.getNextFoldLine(i,s),o=s?s.start.row:Infinity);if(i>r)break;this.$useLineGroups()&&t.push("
"),this.$renderLine(t,i,!1,i==o?s:!1),this.$useLineGroups()&&t.push("
"),i++}this.element.innerHTML=t.join("")},this.$textToken={text:!0,rparen:!0,lparen:!0},this.$renderToken=function(e,t,n,r){var i=this,o=/\t|&|<|>|( +)|([\x00-\x1f\x80-\xa0\xad\u1680\u180E\u2000-\u200f\u2028\u2029\u202F\u205F\u3000\uFEFF\uFFF9-\uFFFC])|[\u1100-\u115F\u11A3-\u11A7\u11FA-\u11FF\u2329-\u232A\u2E80-\u2E99\u2E9B-\u2EF3\u2F00-\u2FD5\u2FF0-\u2FFB\u3000-\u303E\u3041-\u3096\u3099-\u30FF\u3105-\u312D\u3131-\u318E\u3190-\u31BA\u31C0-\u31E3\u31F0-\u321E\u3220-\u3247\u3250-\u32FE\u3300-\u4DBF\u4E00-\uA48C\uA490-\uA4C6\uA960-\uA97C\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFAFF\uFE10-\uFE19\uFE30-\uFE52\uFE54-\uFE66\uFE68-\uFE6B\uFF01-\uFF60\uFFE0-\uFFE6]/g,u=function(e,n,r,o,u){if(n)return i.showInvisibles?""+s.stringRepeat(i.SPACE_CHAR,e.length)+"":e;if(e=="&")return"&";if(e=="<")return"<";if(e==">")return">";if(e==" "){var a=i.session.getScreenTabSize(t+o);return t+=a-1,i.$tabStrings[a]}if(e=="\u3000"){var f=i.showInvisibles?"ace_cjk ace_invisible ace_invisible_space":"ace_cjk",l=i.showInvisibles?i.SPACE_CHAR:"";return t+=1,""+l+""}return r?""+i.SPACE_CHAR+"":(t+=1,""+e+"")},a=r.replace(o,u);if(!this.$textToken[n.type]){var f="ace_"+n.type.replace(/\./g," ace_"),l="";n.type=="fold"&&(l=" style='width:"+n.value.length*this.config.characterWidth+"px;' "),e.push("",a,"")}else e.push(a);return t+r.length},this.renderIndentGuide=function(e,t,n){var r=t.search(this.$indentGuideRe);return r<=0||r>=n?t:t[0]==" "?(r-=r%this.tabSize,e.push(s.stringRepeat(this.$tabStrings[" "],r/this.tabSize)),t.substr(r)):t[0]==" "?(e.push(s.stringRepeat(this.$tabStrings[" "],r)),t.substr(r)):t},this.$renderWrappedLine=function(e,t,n,r){var i=0,o=0,u=n[0],a=0;for(var f=0;f=u)a=this.$renderToken(e,a,l,c.substring(0,u-i)),c=c.substring(u-i),i=u,r||e.push("","
"),e.push(s.stringRepeat("\u00a0",n.indent)),o++,a=0,u=n[o]||Number.MAX_VALUE;c.length!=0&&(i+=c.length,a=this.$renderToken(e,a,l,c))}}},this.$renderSimpleLine=function(e,t){var n=0,r=t[0],i=r.value;this.displayIndentGuides&&(i=this.renderIndentGuide(e,i)),i&&(n=this.$renderToken(e,n,r,i));for(var s=1;s");if(i.length){var s=this.session.getRowSplitData(t);s&&s.length?this.$renderWrappedLine(e,i,s,n):this.$renderSimpleLine(e,i)}this.showInvisibles&&(r&&(t=r.end.row),e.push("",t==this.session.getLength()-1?this.EOF_CHAR:this.EOL_CHAR,"")),n||e.push("
")},this.$getFoldLineTokens=function(e,t){function i(e,t,n){var i=0,s=0;while(s+e[i].value.lengthn-t&&(o=o.substring(0,n-t)),r.push({type:e[i].type,value:o}),s=t+o.length,i+=1}while(sn?r.push({type:e[i].type,value:o.substring(0,n-s)}):r.push(e[i]),s+=o.length,i+=1}}var n=this.session,r=[],s=n.getTokens(e);return t.walk(function(e,t,o,u,a){e!=null?r.push({type:"fold",value:e}):(a&&(s=n.getTokens(t)),s.length&&i(s,u,o))},t.end.row,this.session.getLine(t.end.row).length),r},this.$useLineGroups=function(){return this.session.getUseWrapMode()},this.destroy=function(){clearInterval(this.$pollSizeChangesTimer),this.$measureNode&&this.$measureNode.parentNode.removeChild(this.$measureNode),delete this.$measureNode}}).call(a.prototype),t.Text=a}),define("ace/layer/cursor",["require","exports","module","ace/lib/dom"],function(e,t,n){"use strict";var r=e("../lib/dom"),i,s=function(e){this.element=r.createElement("div"),this.element.className="ace_layer ace_cursor-layer",e.appendChild(this.element),i===undefined&&(i=!("opacity"in this.element.style)),this.isVisible=!1,this.isBlinking=!0,this.blinkInterval=1e3,this.smoothBlinking=!1,this.cursors=[],this.cursor=this.addCursor(),r.addCssClass(this.element,"ace_hidden-cursors"),this.$updateCursors=(i?this.$updateVisibility:this.$updateOpacity).bind(this)};(function(){this.$updateVisibility=function(e){var t=this.cursors;for(var n=t.length;n--;)t[n].style.visibility=e?"":"hidden"},this.$updateOpacity=function(e){var t=this.cursors;for(var n=t.length;n--;)t[n].style.opacity=e?"":"0"},this.$padding=0,this.setPadding=function(e){this.$padding=e},this.setSession=function(e){this.session=e},this.setBlinking=function(e){e!=this.isBlinking&&(this.isBlinking=e,this.restartTimer())},this.setBlinkInterval=function(e){e!=this.blinkInterval&&(this.blinkInterval=e,this.restartTimer())},this.setSmoothBlinking=function(e){e!=this.smoothBlinking&&!i&&(this.smoothBlinking=e,r.setCssClass(this.element,"ace_smooth-blinking",e),this.$updateCursors(!0),this.$updateCursors=this.$updateOpacity.bind(this),this.restartTimer())},this.addCursor=function(){var e=r.createElement("div");return e.className="ace_cursor",this.element.appendChild(e),this.cursors.push(e),e},this.removeCursor=function(){if(this.cursors.length>1){var e=this.cursors.pop();return e.parentNode.removeChild(e),e}},this.hideCursor=function(){this.isVisible=!1,r.addCssClass(this.element,"ace_hidden-cursors"),this.restartTimer()},this.showCursor=function(){this.isVisible=!0,r.removeCssClass(this.element,"ace_hidden-cursors"),this.restartTimer()},this.restartTimer=function(){var e=this.$updateCursors;clearInterval(this.intervalId),clearTimeout(this.timeoutId),this.smoothBlinking&&r.removeCssClass(this.element,"ace_smooth-blinking"),e(!0);if(!this.isBlinking||!this.blinkInterval||!this.isVisible)return;this.smoothBlinking&&setTimeout(function(){r.addCssClass(this.element,"ace_smooth-blinking")}.bind(this));var t=function(){this.timeoutId=setTimeout(function(){e(!1)},.6*this.blinkInterval)}.bind(this);this.intervalId=setInterval(function(){e(!0),t()},this.blinkInterval),t()},this.getPixelPosition=function(e,t){if(!this.config||!this.session)return{left:0,top:0};e||(e=this.session.selection.getCursor());var n=this.session.documentToScreenPosition(e),r=this.$padding+n.column*this.config.characterWidth,i=(n.row-(t?this.config.firstRowScreen:0))*this.config.lineHeight;return{left:r,top:i}},this.update=function(e){this.config=e;var t=this.session.$selectionMarkers,n=0,r=0;if(t===undefined||t.length===0)t=[{cursor:null}];for(var n=0,i=t.length;ne.height+e.offset||s.top<0)&&n>1)continue;var o=(this.cursors[r++]||this.addCursor()).style;this.drawCursor?this.drawCursor(o,s,e,t[n],this.session):(o.left=s.left+"px",o.top=s.top+"px",o.width=e.characterWidth+"px",o.height=e.lineHeight+"px")}while(this.cursors.length>r)this.removeCursor();var u=this.session.getOverwrite();this.$setOverwrite(u),this.$pixelPos=s,this.restartTimer()},this.drawCursor=null,this.$setOverwrite=function(e){e!=this.overwrite&&(this.overwrite=e,e?r.addCssClass(this.element,"ace_overwrite-cursors"):r.removeCssClass(this.element,"ace_overwrite-cursors"))},this.destroy=function(){clearInterval(this.intervalId),clearTimeout(this.timeoutId)}}).call(s.prototype),t.Cursor=s}),define("ace/scrollbar",["require","exports","module","ace/lib/oop","ace/lib/dom","ace/lib/event","ace/lib/event_emitter"],function(e,t,n){"use strict";var r=e("./lib/oop"),i=e("./lib/dom"),s=e("./lib/event"),o=e("./lib/event_emitter").EventEmitter,u=32768,a=function(e){this.element=i.createElement("div"),this.element.className="ace_scrollbar ace_scrollbar"+this.classSuffix,this.inner=i.createElement("div"),this.inner.className="ace_scrollbar-inner",this.element.appendChild(this.inner),e.appendChild(this.element),this.setVisible(!1),this.skipEvent=!1,s.addListener(this.element,"scroll",this.onScroll.bind(this)),s.addListener(this.element,"mousedown",s.preventDefault)};(function(){r.implement(this,o),this.setVisible=function(e){this.element.style.display=e?"":"none",this.isVisible=e,this.coeff=1}}).call(a.prototype);var f=function(e,t){a.call(this,e),this.scrollTop=0,this.scrollHeight=0,t.$scrollbarWidth=this.width=i.scrollbarWidth(e.ownerDocument),this.inner.style.width=this.element.style.width=(this.width||15)+5+"px"};r.inherits(f,a),function(){this.classSuffix="-v",this.onScroll=function(){if(!this.skipEvent){this.scrollTop=this.element.scrollTop;if(this.coeff!=1){var e=this.element.clientHeight/this.scrollHeight;this.scrollTop=this.scrollTop*(1-e)/(this.coeff-e)}this._emit("scroll",{data:this.scrollTop})}this.skipEvent=!1},this.getWidth=function(){return this.isVisible?this.width:0},this.setHeight=function(e){this.element.style.height=e+"px"},this.setInnerHeight=this.setScrollHeight=function(e){this.scrollHeight=e,e>u?(this.coeff=u/e,e=u):this.coeff!=1&&(this.coeff=1),this.inner.style.height=e+"px"},this.setScrollTop=function(e){this.scrollTop!=e&&(this.skipEvent=!0,this.scrollTop=e,this.element.scrollTop=e*this.coeff)}}.call(f.prototype);var l=function(e,t){a.call(this,e),this.scrollLeft=0,this.height=t.$scrollbarWidth,this.inner.style.height=this.element.style.height=(this.height||15)+5+"px"};r.inherits(l,a),function(){this.classSuffix="-h",this.onScroll=function(){this.skipEvent||(this.scrollLeft=this.element.scrollLeft,this._emit("scroll",{data:this.scrollLeft})),this.skipEvent=!1},this.getHeight=function(){return this.isVisible?this.height:0},this.setWidth=function(e){this.element.style.width=e+"px"},this.setInnerWidth=function(e){this.inner.style.width=e+"px"},this.setScrollWidth=function(e){this.inner.style.width=e+"px"},this.setScrollLeft=function(e){this.scrollLeft!=e&&(this.skipEvent=!0,this.scrollLeft=this.element.scrollLeft=e)}}.call(l.prototype),t.ScrollBar=f,t.ScrollBarV=f,t.ScrollBarH=l,t.VScrollBar=f,t.HScrollBar=l}),define("ace/renderloop",["require","exports","module","ace/lib/event"],function(e,t,n){"use strict";var r=e("./lib/event"),i=function(e,t){this.onRender=e,this.pending=!1,this.changes=0,this.window=t||window};(function(){this.schedule=function(e){this.changes=this.changes|e;if(!this.pending&&this.changes){this.pending=!0;var t=this;r.nextFrame(function(){t.pending=!1;var e;while(e=t.changes)t.changes=0,t.onRender(e)},this.window)}}}).call(i.prototype),t.RenderLoop=i}),define("ace/layer/font_metrics",["require","exports","module","ace/lib/oop","ace/lib/dom","ace/lib/lang","ace/lib/useragent","ace/lib/event_emitter"],function(e,t,n){var r=e("../lib/oop"),i=e("../lib/dom"),s=e("../lib/lang"),o=e("../lib/useragent"),u=e("../lib/event_emitter").EventEmitter,a=0,f=t.FontMetrics=function(e){this.el=i.createElement("div"),this.$setMeasureNodeStyles(this.el.style,!0),this.$main=i.createElement("div"),this.$setMeasureNodeStyles(this.$main.style),this.$measureNode=i.createElement("div"),this.$setMeasureNodeStyles(this.$measureNode.style),this.el.appendChild(this.$main),this.el.appendChild(this.$measureNode),e.appendChild(this.el),a||this.$testFractionalRect(),this.$measureNode.innerHTML=s.stringRepeat("X",a),this.$characterSize={width:0,height:0},this.checkForSizeChanges()};(function(){r.implement(this,u),this.$characterSize={width:0,height:0},this.$testFractionalRect=function(){var e=i.createElement("div");this.$setMeasureNodeStyles(e.style),e.style.width="0.2px",document.documentElement.appendChild(e);var t=e.getBoundingClientRect().width;t>0&&t<1?a=50:a=100,e.parentNode.removeChild(e)},this.$setMeasureNodeStyles=function(e,t){e.width=e.height="auto",e.left=e.top="0px",e.visibility="hidden",e.position="absolute",e.whiteSpace="pre",o.isIE<8?e["font-family"]="inherit":e.font="inherit",e.overflow=t?"hidden":"visible"},this.checkForSizeChanges=function(){var e=this.$measureSizes();if(e&&(this.$characterSize.width!==e.width||this.$characterSize.height!==e.height)){this.$measureNode.style.fontWeight="bold";var t=this.$measureSizes();this.$measureNode.style.fontWeight="",this.$characterSize=e,this.charSizes=Object.create(null),this.allowBoldFonts=t&&t.width===e.width&&t.height===e.height,this._emit("changeCharacterSize",{data:e})}},this.$pollSizeChanges=function(){if(this.$pollSizeChangesTimer)return this.$pollSizeChangesTimer;var e=this;return this.$pollSizeChangesTimer=setInterval(function(){e.checkForSizeChanges()},500)},this.setPolling=function(e){e?this.$pollSizeChanges():this.$pollSizeChangesTimer&&(clearInterval(this.$pollSizeChangesTimer),this.$pollSizeChangesTimer=0)},this.$measureSizes=function(){if(a===50){var e=null;try{e=this.$measureNode.getBoundingClientRect()}catch(t){e={width:0,height:0}}var n={height:e.height,width:e.width/a}}else var n={height:this.$measureNode.clientHeight,width:this.$measureNode.clientWidth/a};return n.width===0||n.height===0?null:n},this.$measureCharWidth=function(e){this.$main.innerHTML=s.stringRepeat(e,a);var t=this.$main.getBoundingClientRect();return t.width/a},this.getCharacterWidth=function(e){var t=this.charSizes[e];return t===undefined&&(t=this.charSizes[e]=this.$measureCharWidth(e)/this.$characterSize.width),t},this.destroy=function(){clearInterval(this.$pollSizeChangesTimer),this.el&&this.el.parentNode&&this.el.parentNode.removeChild(this.el)}}).call(f.prototype)}),define("ace/virtual_renderer",["require","exports","module","ace/lib/oop","ace/lib/dom","ace/config","ace/lib/useragent","ace/layer/gutter","ace/layer/marker","ace/layer/text","ace/layer/cursor","ace/scrollbar","ace/scrollbar","ace/renderloop","ace/layer/font_metrics","ace/lib/event_emitter"],function(e,t,n){"use strict";var r=e("./lib/oop"),i=e("./lib/dom"),s=e("./config"),o=e("./lib/useragent"),u=e("./layer/gutter").Gutter,a=e("./layer/marker").Marker,f=e("./layer/text").Text,l=e("./layer/cursor").Cursor,c=e("./scrollbar").HScrollBar,h=e("./scrollbar").VScrollBar,p=e("./renderloop").RenderLoop,d=e("./layer/font_metrics").FontMetrics,v=e("./lib/event_emitter").EventEmitter,m='.ace_editor {position: relative;overflow: hidden;font: 12px/normal \'Monaco\', \'Menlo\', \'Ubuntu Mono\', \'Consolas\', \'source-code-pro\', monospace;direction: ltr;text-align: left;}.ace_scroller {position: absolute;overflow: hidden;top: 0;bottom: 0;background-color: inherit;-ms-user-select: none;-moz-user-select: none;-webkit-user-select: none;user-select: none;cursor: text;}.ace_content {position: absolute;-moz-box-sizing: border-box;-webkit-box-sizing: border-box;box-sizing: border-box;min-width: 100%;}.ace_dragging .ace_scroller:before{position: absolute;top: 0;left: 0;right: 0;bottom: 0;content: \'\';background: rgba(250, 250, 250, 0.01);z-index: 1000;}.ace_dragging.ace_dark .ace_scroller:before{background: rgba(0, 0, 0, 0.01);}.ace_selecting, .ace_selecting * {cursor: text !important;}.ace_gutter {position: absolute;overflow : hidden;width: auto;top: 0;bottom: 0;left: 0;cursor: default;z-index: 4;-ms-user-select: none;-moz-user-select: none;-webkit-user-select: none;user-select: none;}.ace_gutter-active-line {position: absolute;left: 0;right: 0;}.ace_scroller.ace_scroll-left {box-shadow: 17px 0 16px -16px rgba(0, 0, 0, 0.4) inset;}.ace_gutter-cell {padding-left: 19px;padding-right: 6px;background-repeat: no-repeat;}.ace_gutter-cell.ace_error {background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAABOFBMVEX/////////QRswFAb/Ui4wFAYwFAYwFAaWGAfDRymzOSH/PxswFAb/SiUwFAYwFAbUPRvjQiDllog5HhHdRybsTi3/Tyv9Tir+Syj/UC3////XurebMBIwFAb/RSHbPx/gUzfdwL3kzMivKBAwFAbbvbnhPx66NhowFAYwFAaZJg8wFAaxKBDZurf/RB6mMxb/SCMwFAYwFAbxQB3+RB4wFAb/Qhy4Oh+4QifbNRcwFAYwFAYwFAb/QRzdNhgwFAYwFAbav7v/Uy7oaE68MBK5LxLewr/r2NXewLswFAaxJw4wFAbkPRy2PyYwFAaxKhLm1tMwFAazPiQwFAaUGAb/QBrfOx3bvrv/VC/maE4wFAbRPBq6MRO8Qynew8Dp2tjfwb0wFAbx6eju5+by6uns4uH9/f36+vr/GkHjAAAAYnRSTlMAGt+64rnWu/bo8eAA4InH3+DwoN7j4eLi4xP99Nfg4+b+/u9B/eDs1MD1mO7+4PHg2MXa347g7vDizMLN4eG+Pv7i5evs/v79yu7S3/DV7/498Yv24eH+4ufQ3Ozu/v7+y13sRqwAAADLSURBVHjaZc/XDsFgGIBhtDrshlitmk2IrbHFqL2pvXf/+78DPokj7+Fz9qpU/9UXJIlhmPaTaQ6QPaz0mm+5gwkgovcV6GZzd5JtCQwgsxoHOvJO15kleRLAnMgHFIESUEPmawB9ngmelTtipwwfASilxOLyiV5UVUyVAfbG0cCPHig+GBkzAENHS0AstVF6bacZIOzgLmxsHbt2OecNgJC83JERmePUYq8ARGkJx6XtFsdddBQgZE2nPR6CICZhawjA4Fb/chv+399kfR+MMMDGOQAAAABJRU5ErkJggg==");background-repeat: no-repeat;background-position: 2px center;}.ace_gutter-cell.ace_warning {background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAmVBMVEX///8AAAD///8AAAAAAABPSzb/5sAAAAB/blH/73z/ulkAAAAAAAD85pkAAAAAAAACAgP/vGz/rkDerGbGrV7/pkQICAf////e0IsAAAD/oED/qTvhrnUAAAD/yHD/njcAAADuv2r/nz//oTj/p064oGf/zHAAAAA9Nir/tFIAAAD/tlTiuWf/tkIAAACynXEAAAAAAAAtIRW7zBpBAAAAM3RSTlMAABR1m7RXO8Ln31Z36zT+neXe5OzooRDfn+TZ4p3h2hTf4t3k3ucyrN1K5+Xaks52Sfs9CXgrAAAAjklEQVR42o3PbQ+CIBQFYEwboPhSYgoYunIqqLn6/z8uYdH8Vmdnu9vz4WwXgN/xTPRD2+sgOcZjsge/whXZgUaYYvT8QnuJaUrjrHUQreGczuEafQCO/SJTufTbroWsPgsllVhq3wJEk2jUSzX3CUEDJC84707djRc5MTAQxoLgupWRwW6UB5fS++NV8AbOZgnsC7BpEAAAAABJRU5ErkJggg==");background-position: 2px center;}.ace_gutter-cell.ace_info {background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAAAAAA6mKC9AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAAJ0Uk5TAAB2k804AAAAPklEQVQY02NgIB68QuO3tiLznjAwpKTgNyDbMegwisCHZUETUZV0ZqOquBpXj2rtnpSJT1AEnnRmL2OgGgAAIKkRQap2htgAAAAASUVORK5CYII=");background-position: 2px center;}.ace_dark .ace_gutter-cell.ace_info {background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAJFBMVEUAAAChoaGAgIAqKiq+vr6tra1ZWVmUlJSbm5s8PDxubm56enrdgzg3AAAAAXRSTlMAQObYZgAAAClJREFUeNpjYMAPdsMYHegyJZFQBlsUlMFVCWUYKkAZMxZAGdxlDMQBAG+TBP4B6RyJAAAAAElFTkSuQmCC");}.ace_scrollbar {position: absolute;right: 0;bottom: 0;z-index: 6;}.ace_scrollbar-inner {position: absolute;cursor: text;left: 0;top: 0;}.ace_scrollbar-v{overflow-x: hidden;overflow-y: scroll;top: 0;}.ace_scrollbar-h {overflow-x: scroll;overflow-y: hidden;left: 0;}.ace_print-margin {position: absolute;height: 100%;}.ace_text-input {position: absolute;z-index: 0;width: 0.5em;height: 1em;opacity: 0;background: transparent;-moz-appearance: none;appearance: none;border: none;resize: none;outline: none;overflow: hidden;font: inherit;padding: 0 1px;margin: 0 -1px;text-indent: -1em;-ms-user-select: text;-moz-user-select: text;-webkit-user-select: text;user-select: text;white-space: pre!important;}.ace_text-input.ace_composition {background: inherit;color: inherit;z-index: 1000;opacity: 1;text-indent: 0;}.ace_layer {z-index: 1;position: absolute;overflow: hidden;word-wrap: normal;white-space: pre;height: 100%;width: 100%;-moz-box-sizing: border-box;-webkit-box-sizing: border-box;box-sizing: border-box;pointer-events: none;}.ace_gutter-layer {position: relative;width: auto;text-align: right;pointer-events: auto;}.ace_text-layer {font: inherit !important;}.ace_cjk {display: inline-block;text-align: center;}.ace_cursor-layer {z-index: 4;}.ace_cursor {z-index: 4;position: absolute;-moz-box-sizing: border-box;-webkit-box-sizing: border-box;box-sizing: border-box;border-left: 2px solid;transform: translatez(0);}.ace_slim-cursors .ace_cursor {border-left-width: 1px;}.ace_overwrite-cursors .ace_cursor {border-left-width: 0;border-bottom: 1px solid;}.ace_hidden-cursors .ace_cursor {opacity: 0.2;}.ace_smooth-blinking .ace_cursor {-webkit-transition: opacity 0.18s;transition: opacity 0.18s;}.ace_editor.ace_multiselect .ace_cursor {border-left-width: 1px;}.ace_marker-layer .ace_step, .ace_marker-layer .ace_stack {position: absolute;z-index: 3;}.ace_marker-layer .ace_selection {position: absolute;z-index: 5;}.ace_marker-layer .ace_bracket {position: absolute;z-index: 6;}.ace_marker-layer .ace_active-line {position: absolute;z-index: 2;}.ace_marker-layer .ace_selected-word {position: absolute;z-index: 4;-moz-box-sizing: border-box;-webkit-box-sizing: border-box;box-sizing: border-box;}.ace_line .ace_fold {-moz-box-sizing: border-box;-webkit-box-sizing: border-box;box-sizing: border-box;display: inline-block;height: 11px;margin-top: -2px;vertical-align: middle;background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABEAAAAJCAYAAADU6McMAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAJpJREFUeNpi/P//PwOlgAXGYGRklAVSokD8GmjwY1wasKljQpYACtpCFeADcHVQfQyMQAwzwAZI3wJKvCLkfKBaMSClBlR7BOQikCFGQEErIH0VqkabiGCAqwUadAzZJRxQr/0gwiXIal8zQQPnNVTgJ1TdawL0T5gBIP1MUJNhBv2HKoQHHjqNrA4WO4zY0glyNKLT2KIfIMAAQsdgGiXvgnYAAAAASUVORK5CYII="),url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAA3CAYAAADNNiA5AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAACJJREFUeNpi+P//fxgTAwPDBxDxD078RSX+YeEyDFMCIMAAI3INmXiwf2YAAAAASUVORK5CYII=");background-repeat: no-repeat, repeat-x;background-position: center center, top left;color: transparent;border: 1px solid black;border-radius: 2px;cursor: pointer;pointer-events: auto;}.ace_dark .ace_fold {}.ace_fold:hover{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABEAAAAJCAYAAADU6McMAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAJpJREFUeNpi/P//PwOlgAXGYGRklAVSokD8GmjwY1wasKljQpYACtpCFeADcHVQfQyMQAwzwAZI3wJKvCLkfKBaMSClBlR7BOQikCFGQEErIH0VqkabiGCAqwUadAzZJRxQr/0gwiXIal8zQQPnNVTgJ1TdawL0T5gBIP1MUJNhBv2HKoQHHjqNrA4WO4zY0glyNKLT2KIfIMAAQsdgGiXvgnYAAAAASUVORK5CYII="),url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAA3CAYAAADNNiA5AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAACBJREFUeNpi+P//fz4TAwPDZxDxD5X4i5fLMEwJgAADAEPVDbjNw87ZAAAAAElFTkSuQmCC");}.ace_tooltip {background-color: #FFF;background-image: -webkit-linear-gradient(top, transparent, rgba(0, 0, 0, 0.1));background-image: linear-gradient(to bottom, transparent, rgba(0, 0, 0, 0.1));border: 1px solid gray;border-radius: 1px;box-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);color: black;max-width: 100%;padding: 3px 4px;position: fixed;z-index: 999999;-moz-box-sizing: border-box;-webkit-box-sizing: border-box;box-sizing: border-box;cursor: default;white-space: pre;word-wrap: break-word;line-height: normal;font-style: normal;font-weight: normal;letter-spacing: normal;pointer-events: none;}.ace_folding-enabled > .ace_gutter-cell {padding-right: 13px;}.ace_fold-widget {-moz-box-sizing: border-box;-webkit-box-sizing: border-box;box-sizing: border-box;margin: 0 -12px 0 1px;display: none;width: 11px;vertical-align: top;background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAANElEQVR42mWKsQ0AMAzC8ixLlrzQjzmBiEjp0A6WwBCSPgKAXoLkqSot7nN3yMwR7pZ32NzpKkVoDBUxKAAAAABJRU5ErkJggg==");background-repeat: no-repeat;background-position: center;border-radius: 3px;border: 1px solid transparent;cursor: pointer;}.ace_folding-enabled .ace_fold-widget {display: inline-block; }.ace_fold-widget.ace_end {background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAANElEQVR42m3HwQkAMAhD0YzsRchFKI7sAikeWkrxwScEB0nh5e7KTPWimZki4tYfVbX+MNl4pyZXejUO1QAAAABJRU5ErkJggg==");}.ace_fold-widget.ace_closed {background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAGCAYAAAAG5SQMAAAAOUlEQVR42jXKwQkAMAgDwKwqKD4EwQ26sSOkVWjgIIHAzPiCgaqiqnJHZnKICBERHN194O5b9vbLuAVRL+l0YWnZAAAAAElFTkSuQmCCXA==");}.ace_fold-widget:hover {border: 1px solid rgba(0, 0, 0, 0.3);background-color: rgba(255, 255, 255, 0.2);box-shadow: 0 1px 1px rgba(255, 255, 255, 0.7);}.ace_fold-widget:active {border: 1px solid rgba(0, 0, 0, 0.4);background-color: rgba(0, 0, 0, 0.05);box-shadow: 0 1px 1px rgba(255, 255, 255, 0.8);}.ace_dark .ace_fold-widget {background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHklEQVQIW2P4//8/AzoGEQ7oGCaLLAhWiSwB146BAQCSTPYocqT0AAAAAElFTkSuQmCC");}.ace_dark .ace_fold-widget.ace_end {background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAH0lEQVQIW2P4//8/AxQ7wNjIAjDMgC4AxjCVKBirIAAF0kz2rlhxpAAAAABJRU5ErkJggg==");}.ace_dark .ace_fold-widget.ace_closed {background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAFCAYAAACAcVaiAAAAHElEQVQIW2P4//+/AxAzgDADlOOAznHAKgPWAwARji8UIDTfQQAAAABJRU5ErkJggg==");}.ace_dark .ace_fold-widget:hover {box-shadow: 0 1px 1px rgba(255, 255, 255, 0.2);background-color: rgba(255, 255, 255, 0.1);}.ace_dark .ace_fold-widget:active {box-shadow: 0 1px 1px rgba(255, 255, 255, 0.2);}.ace_fold-widget.ace_invalid {background-color: #FFB4B4;border-color: #DE5555;}.ace_fade-fold-widgets .ace_fold-widget {-webkit-transition: opacity 0.4s ease 0.05s;transition: opacity 0.4s ease 0.05s;opacity: 0;}.ace_fade-fold-widgets:hover .ace_fold-widget {-webkit-transition: opacity 0.05s ease 0.05s;transition: opacity 0.05s ease 0.05s;opacity:1;}.ace_underline {text-decoration: underline;}.ace_bold {font-weight: bold;}.ace_nobold .ace_bold {font-weight: normal;}.ace_italic {font-style: italic;}.ace_error-marker {background-color: rgba(255, 0, 0,0.2);position: absolute;z-index: 9;}.ace_highlight-marker {background-color: rgba(255, 255, 0,0.2);position: absolute;z-index: 8;}.ace_br1 {border-top-left-radius : 3px;}.ace_br2 {border-top-right-radius : 3px;}.ace_br3 {border-top-left-radius : 3px; border-top-right-radius: 3px;}.ace_br4 {border-bottom-right-radius: 3px;}.ace_br5 {border-top-left-radius : 3px; border-bottom-right-radius: 3px;}.ace_br6 {border-top-right-radius : 3px; border-bottom-right-radius: 3px;}.ace_br7 {border-top-left-radius : 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px;}.ace_br8 {border-bottom-left-radius : 3px;}.ace_br9 {border-top-left-radius : 3px; border-bottom-left-radius: 3px;}.ace_br10{border-top-right-radius : 3px; border-bottom-left-radius: 3px;}.ace_br11{border-top-left-radius : 3px; border-top-right-radius: 3px; border-bottom-left-radius: 3px;}.ace_br12{border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;}.ace_br13{border-top-left-radius : 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;}.ace_br14{border-top-right-radius : 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;}.ace_br15{border-top-left-radius : 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;}';i.importCssString(m,"ace_editor.css");var g=function(e,t){var n=this;this.container=e||i.createElement("div"),this.$keepTextAreaAtCursor=!o.isOldIE,i.addCssClass(this.container,"ace_editor"),this.setTheme(t),this.$gutter=i.createElement("div"),this.$gutter.className="ace_gutter",this.container.appendChild(this.$gutter),this.scroller=i.createElement("div"),this.scroller.className="ace_scroller",this.container.appendChild(this.scroller),this.content=i.createElement("div"),this.content.className="ace_content",this.scroller.appendChild(this.content),this.$gutterLayer=new u(this.$gutter),this.$gutterLayer.on("changeGutterWidth",this.onGutterResize.bind(this)),this.$markerBack=new a(this.content);var r=this.$textLayer=new f(this.content);this.canvas=r.element,this.$markerFront=new a(this.content),this.$cursorLayer=new l(this.content),this.$horizScroll=!1,this.$vScroll=!1,this.scrollBar=this.scrollBarV=new h(this.container,this),this.scrollBarH=new c(this.container,this),this.scrollBarV.addEventListener("scroll",function(e){n.$scrollAnimation||n.session.setScrollTop(e.data-n.scrollMargin.top)}),this.scrollBarH.addEventListener("scroll",function(e){n.$scrollAnimation||n.session.setScrollLeft(e.data-n.scrollMargin.left)}),this.scrollTop=0,this.scrollLeft=0,this.cursorPos={row:0,column:0},this.$fontMetrics=new d(this.container),this.$textLayer.$setFontMetrics(this.$fontMetrics),this.$textLayer.addEventListener("changeCharacterSize",function(e){n.updateCharacterSize(),n.onResize(!0,n.gutterWidth,n.$size.width,n.$size.height),n._signal("changeCharacterSize",e)}),this.$size={width:0,height:0,scrollerHeight:0,scrollerWidth:0,$dirty:!0},this.layerConfig={width:1,padding:0,firstRow:0,firstRowScreen:0,lastRow:0,lineHeight:0,characterWidth:0,minHeight:1,maxHeight:1,offset:0,height:1,gutterOffset:1},this.scrollMargin={left:0,right:0,top:0,bottom:0,v:0,h:0},this.$loop=new p(this.$renderChanges.bind(this),this.container.ownerDocument.defaultView),this.$loop.schedule(this.CHANGE_FULL),this.updateCharacterSize(),this.setPadding(4),s.resetOptions(this),s._emit("renderer",this)};(function(){this.CHANGE_CURSOR=1,this.CHANGE_MARKER=2,this.CHANGE_GUTTER=4,this.CHANGE_SCROLL=8,this.CHANGE_LINES=16,this.CHANGE_TEXT=32,this.CHANGE_SIZE=64,this.CHANGE_MARKER_BACK=128,this.CHANGE_MARKER_FRONT=256,this.CHANGE_FULL=512,this.CHANGE_H_SCROLL=1024,r.implement(this,v),this.updateCharacterSize=function(){this.$textLayer.allowBoldFonts!=this.$allowBoldFonts&&(this.$allowBoldFonts=this.$textLayer.allowBoldFonts,this.setStyle("ace_nobold",!this.$allowBoldFonts)),this.layerConfig.characterWidth=this.characterWidth=this.$textLayer.getCharacterWidth(),this.layerConfig.lineHeight=this.lineHeight=this.$textLayer.getLineHeight(),this.$updatePrintMargin()},this.setSession=function(e){this.session&&this.session.doc.off("changeNewLineMode",this.onChangeNewLineMode),this.session=e,e&&this.scrollMargin.top&&e.getScrollTop()<=0&&e.setScrollTop(-this.scrollMargin.top),this.$cursorLayer.setSession(e),this.$markerBack.setSession(e),this.$markerFront.setSession(e),this.$gutterLayer.setSession(e),this.$textLayer.setSession(e);if(!e)return;this.$loop.schedule(this.CHANGE_FULL),this.session.$setFontMetrics(this.$fontMetrics),this.scrollBarV.scrollLeft=this.scrollBarV.scrollTop=null,this.onChangeNewLineMode=this.onChangeNewLineMode.bind(this),this.onChangeNewLineMode(),this.session.doc.on("changeNewLineMode",this.onChangeNewLineMode)},this.updateLines=function(e,t,n){t===undefined&&(t=Infinity),this.$changedLines?(this.$changedLines.firstRow>e&&(this.$changedLines.firstRow=e),this.$changedLines.lastRowthis.layerConfig.lastRow)return;this.$loop.schedule(this.CHANGE_LINES)},this.onChangeNewLineMode=function(){this.$loop.schedule(this.CHANGE_TEXT),this.$textLayer.$updateEolChar()},this.onChangeTabSize=function(){this.$loop.schedule(this.CHANGE_TEXT|this.CHANGE_MARKER),this.$textLayer.onChangeTabSize()},this.updateText=function(){this.$loop.schedule(this.CHANGE_TEXT)},this.updateFull=function(e){e?this.$renderChanges(this.CHANGE_FULL,!0):this.$loop.schedule(this.CHANGE_FULL)},this.updateFontSize=function(){this.$textLayer.checkForSizeChanges()},this.$changes=0,this.$updateSizeAsync=function(){this.$loop.pending?this.$size.$dirty=!0:this.onResize()},this.onResize=function(e,t,n,r){if(this.resizing>2)return;this.resizing>0?this.resizing++:this.resizing=e?1:0;var i=this.container;r||(r=i.clientHeight||i.scrollHeight),n||(n=i.clientWidth||i.scrollWidth);var s=this.$updateCachedSize(e,t,n,r);if(!this.$size.scrollerHeight||!n&&!r)return this.resizing=0;e&&(this.$gutterLayer.$padding=null),e?this.$renderChanges(s|this.$changes,!0):this.$loop.schedule(s|this.$changes),this.resizing&&(this.resizing=0),this.scrollBarV.scrollLeft=this.scrollBarV.scrollTop=null},this.$updateCachedSize=function(e,t,n,r){r-=this.$extraHeight||0;var i=0,s=this.$size,o={width:s.width,height:s.height,scrollerHeight:s.scrollerHeight,scrollerWidth:s.scrollerWidth};r&&(e||s.height!=r)&&(s.height=r,i|=this.CHANGE_SIZE,s.scrollerHeight=s.height,this.$horizScroll&&(s.scrollerHeight-=this.scrollBarH.getHeight()),this.scrollBarV.element.style.bottom=this.scrollBarH.getHeight()+"px",i|=this.CHANGE_SCROLL);if(n&&(e||s.width!=n)){i|=this.CHANGE_SIZE,s.width=n,t==null&&(t=this.$showGutter?this.$gutter.offsetWidth:0),this.gutterWidth=t,this.scrollBarH.element.style.left=this.scroller.style.left=t+"px",s.scrollerWidth=Math.max(0,n-t-this.scrollBarV.getWidth()),this.scrollBarH.element.style.right=this.scroller.style.right=this.scrollBarV.getWidth()+"px",this.scroller.style.bottom=this.scrollBarH.getHeight()+"px";if(this.session&&this.session.getUseWrapMode()&&this.adjustWrapLimit()||e)i|=this.CHANGE_FULL}return s.$dirty=!n||!r,i&&this._signal("resize",o),i},this.onGutterResize=function(){var e=this.$showGutter?this.$gutter.offsetWidth:0;e!=this.gutterWidth&&(this.$changes|=this.$updateCachedSize(!0,e,this.$size.width,this.$size.height)),this.session.getUseWrapMode()&&this.adjustWrapLimit()?this.$loop.schedule(this.CHANGE_FULL):this.$size.$dirty?this.$loop.schedule(this.CHANGE_FULL):(this.$computeLayerConfig(),this.$loop.schedule(this.CHANGE_MARKER))},this.adjustWrapLimit=function(){var e=this.$size.scrollerWidth-this.$padding*2,t=Math.floor(e/this.characterWidth);return this.session.adjustWrapLimit(t,this.$showPrintMargin&&this.$printMarginColumn)},this.setAnimatedScroll=function(e){this.setOption("animatedScroll",e)},this.getAnimatedScroll=function(){return this.$animatedScroll},this.setShowInvisibles=function(e){this.setOption("showInvisibles",e)},this.getShowInvisibles=function(){return this.getOption("showInvisibles")},this.getDisplayIndentGuides=function(){return this.getOption("displayIndentGuides")},this.setDisplayIndentGuides=function(e){this.setOption("displayIndentGuides",e)},this.setShowPrintMargin=function(e){this.setOption("showPrintMargin",e)},this.getShowPrintMargin=function(){return this.getOption("showPrintMargin")},this.setPrintMarginColumn=function(e){this.setOption("printMarginColumn",e)},this.getPrintMarginColumn=function(){return this.getOption("printMarginColumn")},this.getShowGutter=function(){return this.getOption("showGutter")},this.setShowGutter=function(e){return this.setOption("showGutter",e)},this.getFadeFoldWidgets=function(){return this.getOption("fadeFoldWidgets")},this.setFadeFoldWidgets=function(e){this.setOption("fadeFoldWidgets",e)},this.setHighlightGutterLine=function(e){this.setOption("highlightGutterLine",e)},this.getHighlightGutterLine=function(){return this.getOption("highlightGutterLine")},this.$updateGutterLineHighlight=function(){var e=this.$cursorLayer.$pixelPos,t=this.layerConfig.lineHeight;if(this.session.getUseWrapMode()){var n=this.session.selection.getCursor();n.column=0,e=this.$cursorLayer.getPixelPosition(n,!0),t*=this.session.getRowLength(n.row)}this.$gutterLineHighlight.style.top=e.top-this.layerConfig.offset+"px",this.$gutterLineHighlight.style.height=t+"px"},this.$updatePrintMargin=function(){if(!this.$showPrintMargin&&!this.$printMarginEl)return;if(!this.$printMarginEl){var e=i.createElement("div");e.className="ace_layer ace_print-margin-layer",this.$printMarginEl=i.createElement("div"),this.$printMarginEl.className="ace_print-margin",e.appendChild(this.$printMarginEl),this.content.insertBefore(e,this.content.firstChild)}var t=this.$printMarginEl.style;t.left=this.characterWidth*this.$printMarginColumn+this.$padding+"px",t.visibility=this.$showPrintMargin?"visible":"hidden",this.session&&this.session.$wrap==-1&&this.adjustWrapLimit()},this.getContainerElement=function(){return this.container},this.getMouseEventTarget=function(){return this.scroller},this.getTextAreaContainer=function(){return this.container},this.$moveTextAreaToCursor=function(){if(!this.$keepTextAreaAtCursor)return;var e=this.layerConfig,t=this.$cursorLayer.$pixelPos.top,n=this.$cursorLayer.$pixelPos.left;t-=e.offset;var r=this.textarea.style,i=this.lineHeight;if(t<0||t>e.height-i){r.top=r.left="0";return}var s=this.characterWidth;if(this.$composition){var o=this.textarea.value.replace(/^\x01+/,"");s*=this.session.$getStringScreenWidth(o)[0]+2,i+=2}n-=this.scrollLeft,n>this.$size.scrollerWidth-s&&(n=this.$size.scrollerWidth-s),n+=this.gutterWidth,r.height=i+"px",r.width=s+"px",r.left=Math.min(n,this.$size.scrollerWidth-s)+"px",r.top=Math.min(t,this.$size.height-i)+"px"},this.getFirstVisibleRow=function(){return this.layerConfig.firstRow},this.getFirstFullyVisibleRow=function(){return this.layerConfig.firstRow+(this.layerConfig.offset===0?0:1)},this.getLastFullyVisibleRow=function(){var e=this.layerConfig,t=e.lastRow,n=this.session.documentToScreenRow(t,0)*e.lineHeight;return n-this.session.getScrollTop()>e.height-e.lineHeight?t-1:t},this.getLastVisibleRow=function(){return this.layerConfig.lastRow},this.$padding=null,this.setPadding=function(e){this.$padding=e,this.$textLayer.setPadding(e),this.$cursorLayer.setPadding(e),this.$markerFront.setPadding(e),this.$markerBack.setPadding(e),this.$loop.schedule(this.CHANGE_FULL),this.$updatePrintMargin()},this.setScrollMargin=function(e,t,n,r){var i=this.scrollMargin;i.top=e|0,i.bottom=t|0,i.right=r|0,i.left=n|0,i.v=i.top+i.bottom,i.h=i.left+i.right,i.top&&this.scrollTop<=0&&this.session&&this.session.setScrollTop(-i.top),this.updateFull()},this.getHScrollBarAlwaysVisible=function(){return this.$hScrollBarAlwaysVisible},this.setHScrollBarAlwaysVisible=function(e){this.setOption("hScrollBarAlwaysVisible",e)},this.getVScrollBarAlwaysVisible=function(){return this.$vScrollBarAlwaysVisible},this.setVScrollBarAlwaysVisible=function(e){this.setOption("vScrollBarAlwaysVisible",e)},this.$updateScrollBarV=function(){var e=this.layerConfig.maxHeight,t=this.$size.scrollerHeight;!this.$maxLines&&this.$scrollPastEnd&&(e-=(t-this.lineHeight)*this.$scrollPastEnd,this.scrollTop>e-t&&(e=this.scrollTop+t,this.scrollBarV.scrollTop=null)),this.scrollBarV.setScrollHeight(e+this.scrollMargin.v),this.scrollBarV.setScrollTop(this.scrollTop+this.scrollMargin.top)},this.$updateScrollBarH=function(){this.scrollBarH.setScrollWidth(this.layerConfig.width+2*this.$padding+this.scrollMargin.h),this.scrollBarH.setScrollLeft(this.scrollLeft+this.scrollMargin.left)},this.$frozen=!1,this.freeze=function(){this.$frozen=!0},this.unfreeze=function(){this.$frozen=!1},this.$renderChanges=function(e,t){this.$changes&&(e|=this.$changes,this.$changes=0);if(!this.session||!this.container.offsetWidth||this.$frozen||!e&&!t){this.$changes|=e;return}if(this.$size.$dirty)return this.$changes|=e,this.onResize(!0);this.lineHeight||this.$textLayer.checkForSizeChanges(),this._signal("beforeRender");var n=this.layerConfig;if(e&this.CHANGE_FULL||e&this.CHANGE_SIZE||e&this.CHANGE_TEXT||e&this.CHANGE_LINES||e&this.CHANGE_SCROLL||e&this.CHANGE_H_SCROLL){e|=this.$computeLayerConfig();if(n.firstRow!=this.layerConfig.firstRow&&n.firstRowScreen==this.layerConfig.firstRowScreen){var r=this.scrollTop+(n.firstRow-this.layerConfig.firstRow)*this.lineHeight;r>0&&(this.scrollTop=r,e|=this.CHANGE_SCROLL,e|=this.$computeLayerConfig())}n=this.layerConfig,this.$updateScrollBarV(),e&this.CHANGE_H_SCROLL&&this.$updateScrollBarH(),this.$gutterLayer.element.style.marginTop=-n.offset+"px",this.content.style.marginTop=-n.offset+"px",this.content.style.width=n.width+2*this.$padding+"px",this.content.style.height=n.minHeight+"px"}e&this.CHANGE_H_SCROLL&&(this.content.style.marginLeft=-this.scrollLeft+"px",this.scroller.className=this.scrollLeft<=0?"ace_scroller":"ace_scroller ace_scroll-left");if(e&this.CHANGE_FULL){this.$textLayer.update(n),this.$showGutter&&this.$gutterLayer.update(n),this.$markerBack.update(n),this.$markerFront.update(n),this.$cursorLayer.update(n),this.$moveTextAreaToCursor(),this.$highlightGutterLine&&this.$updateGutterLineHighlight(),this._signal("afterRender");return}if(e&this.CHANGE_SCROLL){e&this.CHANGE_TEXT||e&this.CHANGE_LINES?this.$textLayer.update(n):this.$textLayer.scrollLines(n),this.$showGutter&&this.$gutterLayer.update(n),this.$markerBack.update(n),this.$markerFront.update(n),this.$cursorLayer.update(n),this.$highlightGutterLine&&this.$updateGutterLineHighlight(),this.$moveTextAreaToCursor(),this._signal("afterRender");return}e&this.CHANGE_TEXT?(this.$textLayer.update(n),this.$showGutter&&this.$gutterLayer.update(n)):e&this.CHANGE_LINES?(this.$updateLines()||e&this.CHANGE_GUTTER&&this.$showGutter)&&this.$gutterLayer.update(n):(e&this.CHANGE_TEXT||e&this.CHANGE_GUTTER)&&this.$showGutter&&this.$gutterLayer.update(n),e&this.CHANGE_CURSOR&&(this.$cursorLayer.update(n),this.$moveTextAreaToCursor(),this.$highlightGutterLine&&this.$updateGutterLineHighlight()),e&(this.CHANGE_MARKER|this.CHANGE_MARKER_FRONT)&&this.$markerFront.update(n),e&(this.CHANGE_MARKER|this.CHANGE_MARKER_BACK)&&this.$markerBack.update(n),this._signal("afterRender")},this.$autosize=function(){var e=this.session.getScreenLength()*this.lineHeight,t=this.$maxLines*this.lineHeight,n=Math.min(t,Math.max((this.$minLines||1)*this.lineHeight,e))+this.scrollMargin.v+(this.$extraHeight||0);this.$horizScroll&&(n+=this.scrollBarH.getHeight()),this.$maxPixelHeight&&n>this.$maxPixelHeight&&(n=this.$maxPixelHeight);var r=e>t;if(n!=this.desiredHeight||this.$size.height!=this.desiredHeight||r!=this.$vScroll){r!=this.$vScroll&&(this.$vScroll=r,this.scrollBarV.setVisible(r));var i=this.container.clientWidth;this.container.style.height=n+"px",this.$updateCachedSize(!0,this.$gutterWidth,i,n),this.desiredHeight=n,this._signal("autosize")}},this.$computeLayerConfig=function(){var e=this.session,t=this.$size,n=t.height<=2*this.lineHeight,r=this.session.getScreenLength(),i=r*this.lineHeight,s=this.$getLongestLine(),o=!n&&(this.$hScrollBarAlwaysVisible||t.scrollerWidth-s-2*this.$padding<0),u=this.$horizScroll!==o;u&&(this.$horizScroll=o,this.scrollBarH.setVisible(o));var a=this.$vScroll;this.$maxLines&&this.lineHeight>1&&this.$autosize();var f=this.scrollTop%this.lineHeight,l=t.scrollerHeight+this.lineHeight,c=!this.$maxLines&&this.$scrollPastEnd?(t.scrollerHeight-this.lineHeight)*this.$scrollPastEnd:0;i+=c;var h=this.scrollMargin;this.session.setScrollTop(Math.max(-h.top,Math.min(this.scrollTop,i-t.scrollerHeight+h.bottom))),this.session.setScrollLeft(Math.max(-h.left,Math.min(this.scrollLeft,s+2*this.$padding-t.scrollerWidth+h.right)));var p=!n&&(this.$vScrollBarAlwaysVisible||t.scrollerHeight-i+c<0||this.scrollTop>h.top),d=a!==p;d&&(this.$vScroll=p,this.scrollBarV.setVisible(p));var v=Math.ceil(l/this.lineHeight)-1,m=Math.max(0,Math.round((this.scrollTop-f)/this.lineHeight)),g=m+v,y,b,w=this.lineHeight;m=e.screenToDocumentRow(m,0);var E=e.getFoldLine(m);E&&(m=E.start.row),y=e.documentToScreenRow(m,0),b=e.getRowLength(m)*w,g=Math.min(e.screenToDocumentRow(g,0),e.getLength()-1),l=t.scrollerHeight+e.getRowLength(g)*w+b,f=this.scrollTop-y*w;var S=0;this.layerConfig.width!=s&&(S=this.CHANGE_H_SCROLL);if(u||d)S=this.$updateCachedSize(!0,this.gutterWidth,t.width,t.height),this._signal("scrollbarVisibilityChanged"),d&&(s=this.$getLongestLine());return this.layerConfig={width:s,padding:this.$padding,firstRow:m,firstRowScreen:y,lastRow:g,lineHeight:w,characterWidth:this.characterWidth,minHeight:l,maxHeight:i,offset:f,gutterOffset:w?Math.max(0,Math.ceil((f+t.height-t.scrollerHeight)/w)):0,height:this.$size.scrollerHeight},S},this.$updateLines=function(){var e=this.$changedLines.firstRow,t=this.$changedLines.lastRow;this.$changedLines=null;var n=this.layerConfig;if(e>n.lastRow+1)return;if(ts?(t&&a+o>s+this.lineHeight&&(s-=t*this.$size.scrollerHeight),s===0&&(s=-this.scrollMargin.top),this.session.setScrollTop(s)):a+this.$size.scrollerHeight-ui?(i=1-this.scrollMargin.top)return!0;if(t>0&&this.session.getScrollTop()+this.$size.scrollerHeight-this.layerConfig.maxHeight<-1+this.scrollMargin.bottom)return!0;if(e<0&&this.session.getScrollLeft()>=1-this.scrollMargin.left)return!0;if(e>0&&this.session.getScrollLeft()+this.$size.scrollerWidth-this.layerConfig.width<-1+this.scrollMargin.right)return!0},this.pixelToScreenCoordinates=function(e,t){var n=this.scroller.getBoundingClientRect(),r=(e+this.scrollLeft-n.left-this.$padding)/this.characterWidth,i=Math.floor((t+this.scrollTop-n.top)/this.lineHeight),s=Math.round(r);return{row:i,column:s,side:r-s>0?1:-1}},this.screenToTextCoordinates=function(e,t){var n=this.scroller.getBoundingClientRect(),r=Math.round((e+this.scrollLeft-n.left-this.$padding)/this.characterWidth),i=(t+this.scrollTop-n.top)/this.lineHeight;return this.session.screenToDocumentPosition(i,Math.max(r,0))},this.textToScreenCoordinates=function(e,t){var n=this.scroller.getBoundingClientRect(),r=this.session.documentToScreenPosition(e,t),i=this.$padding+Math.round(r.column*this.characterWidth),s=r.row*this.lineHeight;return{pageX:n.left+i-this.scrollLeft,pageY:n.top+s-this.scrollTop}},this.visualizeFocus=function(){i.addCssClass(this.container,"ace_focus")},this.visualizeBlur=function(){i.removeCssClass(this.container,"ace_focus")},this.showComposition=function(e){this.$composition||(this.$composition={keepTextAreaAtCursor:this.$keepTextAreaAtCursor,cssText:this.textarea.style.cssText}),this.$keepTextAreaAtCursor=!0,i.addCssClass(this.textarea,"ace_composition"),this.textarea.style.cssText="",this.$moveTextAreaToCursor()},this.setCompositionText=function(e){this.$moveTextAreaToCursor()},this.hideComposition=function(){if(!this.$composition)return;i.removeCssClass(this.textarea,"ace_composition"),this.$keepTextAreaAtCursor=this.$composition.keepTextAreaAtCursor,this.textarea.style.cssText=this.$composition.cssText,this.$composition=null},this.setTheme=function(e,t){function o(r){if(n.$themeId!=e)return t&&t();if(!r||!r.cssClass)throw new Error("couldn't load module "+e+" or it didn't call define");i.importCssString(r.cssText,r.cssClass,n.container.ownerDocument),n.theme&&i.removeCssClass(n.container,n.theme.cssClass);var s="padding"in r?r.padding:"padding"in(n.theme||{})?4:n.$padding;n.$padding&&s!=n.$padding&&n.setPadding(s),n.$theme=r.cssClass,n.theme=r,i.addCssClass(n.container,r.cssClass),i.setCssClass(n.container,"ace_dark",r.isDark),n.$size&&(n.$size.width=0,n.$updateSizeAsync()),n._dispatchEvent("themeLoaded",{theme:r}),t&&t()}var n=this;this.$themeId=e,n._dispatchEvent("themeChange",{theme:e});if(!e||typeof e=="string"){var r=e||this.$options.theme.initialValue;s.loadModule(["theme",r],o)}else o(e)},this.getTheme=function(){return this.$themeId},this.setStyle=function(e,t){i.setCssClass(this.container,e,t!==!1)},this.unsetStyle=function(e){i.removeCssClass(this.container,e)},this.setCursorStyle=function(e){this.scroller.style.cursor!=e&&(this.scroller.style.cursor=e)},this.setMouseCursor=function(e){this.scroller.style.cursor=e},this.destroy=function(){this.$textLayer.destroy(),this.$cursorLayer.destroy()}}).call(g.prototype),s.defineOptions(g.prototype,"renderer",{animatedScroll:{initialValue:!1},showInvisibles:{set:function(e){this.$textLayer.setShowInvisibles(e)&&this.$loop.schedule(this.CHANGE_TEXT)},initialValue:!1},showPrintMargin:{set:function(){this.$updatePrintMargin()},initialValue:!0},printMarginColumn:{set:function(){this.$updatePrintMargin()},initialValue:80},printMargin:{set:function(e){typeof e=="number"&&(this.$printMarginColumn=e),this.$showPrintMargin=!!e,this.$updatePrintMargin()},get:function(){return this.$showPrintMargin&&this.$printMarginColumn}},showGutter:{set:function(e){this.$gutter.style.display=e?"block":"none",this.$loop.schedule(this.CHANGE_FULL),this.onGutterResize()},initialValue:!0},fadeFoldWidgets:{set:function(e){i.setCssClass(this.$gutter,"ace_fade-fold-widgets",e)},initialValue:!1},showFoldWidgets:{set:function(e){this.$gutterLayer.setShowFoldWidgets(e)},initialValue:!0},showLineNumbers:{set:function(e){this.$gutterLayer.setShowLineNumbers(e),this.$loop.schedule(this.CHANGE_GUTTER)},initialValue:!0},displayIndentGuides:{set:function(e){this.$textLayer.setDisplayIndentGuides(e)&&this.$loop.schedule(this.CHANGE_TEXT)},initialValue:!0},highlightGutterLine:{set:function(e){if(!this.$gutterLineHighlight){this.$gutterLineHighlight=i.createElement("div"),this.$gutterLineHighlight.className="ace_gutter-active-line",this.$gutter.appendChild(this.$gutterLineHighlight);return}this.$gutterLineHighlight.style.display=e?"":"none",this.$cursorLayer.$pixelPos&&this.$updateGutterLineHighlight()},initialValue:!1,value:!0},hScrollBarAlwaysVisible:{set:function(e){(!this.$hScrollBarAlwaysVisible||!this.$horizScroll)&&this.$loop.schedule(this.CHANGE_SCROLL)},initialValue:!1},vScrollBarAlwaysVisible:{set:function(e){(!this.$vScrollBarAlwaysVisible||!this.$vScroll)&&this.$loop.schedule(this.CHANGE_SCROLL)},initialValue:!1},fontSize:{set:function(e){typeof e=="number"&&(e+="px"),this.container.style.fontSize=e,this.updateFontSize()},initialValue:12},fontFamily:{set:function(e){this.container.style.fontFamily=e,this.updateFontSize()}},maxLines:{set:function(e){this.updateFull()}},minLines:{set:function(e){this.updateFull()}},maxPixelHeight:{set:function(e){this.updateFull()},initialValue:0},scrollPastEnd:{set:function(e){e=+e||0;if(this.$scrollPastEnd==e)return;this.$scrollPastEnd=e,this.$loop.schedule(this.CHANGE_SCROLL)},initialValue:0,handlesSet:!0},fixedWidthGutter:{set:function(e){this.$gutterLayer.$fixedWidth=!!e,this.$loop.schedule(this.CHANGE_GUTTER)}},theme:{set:function(e){this.setTheme(e)},get:function(){return this.$themeId||this.theme},initialValue:"./theme/textmate",handlesSet:!0}}),t.VirtualRenderer=g}),define("ace/worker/worker_client",["require","exports","module","ace/lib/oop","ace/lib/net","ace/lib/event_emitter","ace/config"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/net"),s=e("../lib/event_emitter").EventEmitter,o=e("../config"),u=function(t,n,r,i){this.$sendDeltaQueue=this.$sendDeltaQueue.bind(this),this.changeListener=this.changeListener.bind(this),this.onMessage=this.onMessage.bind(this),e.nameToUrl&&!e.toUrl&&(e.toUrl=e.nameToUrl);if(o.get("packaged")||!e.toUrl)i=i||o.moduleUrl(n,"worker");else{var s=this.$normalizePath;i=i||s(e.toUrl("ace/worker/worker.js",null,"_"));var u={};t.forEach(function(t){u[t]=s(e.toUrl(t,null,"_").replace(/(\.js)?(\?.*)?$/,""))})}try{this.$worker=new Worker(i)}catch(a){if(!(a instanceof window.DOMException))throw a;var f=this.$workerBlob(i),l=window.URL||window.webkitURL,c=l.createObjectURL(f);this.$worker=new Worker(c),l.revokeObjectURL(c)}this.$worker.postMessage({init:!0,tlns:u,module:n,classname:r}),this.callbackId=1,this.callbacks={},this.$worker.onmessage=this.onMessage};(function(){r.implement(this,s),this.onMessage=function(e){var t=e.data;switch(t.type){case"event":this._signal(t.name,{data:t.data});break;case"call":var n=this.callbacks[t.id];n&&(n(t.data),delete this.callbacks[t.id]);break;case"error":this.reportError(t.data);break;case"log":window.console&&console.log&&console.log.apply(console,t.data)}},this.reportError=function(e){window.console&&console.error&&console.error(e)},this.$normalizePath=function(e){return i.qualifyURL(e)},this.terminate=function(){this._signal("terminate",{}),this.deltaQueue=null,this.$worker.terminate(),this.$worker=null,this.$doc&&this.$doc.off("change",this.changeListener),this.$doc=null},this.send=function(e,t){this.$worker.postMessage({command:e,args:t})},this.call=function(e,t,n){if(n){var r=this.callbackId++;this.callbacks[r]=n,t.push(r)}this.send(e,t)},this.emit=function(e,t){try{this.$worker.postMessage({event:e,data:{data:t.data}})}catch(n){console.error(n.stack)}},this.attachToDocument=function(e){this.$doc&&this.terminate(),this.$doc=e,this.call("setValue",[e.getValue()]),e.on("change",this.changeListener)},this.changeListener=function(e){this.deltaQueue||(this.deltaQueue=[],setTimeout(this.$sendDeltaQueue,0)),e.action=="insert"?this.deltaQueue.push(e.start,e.lines):this.deltaQueue.push(e.start,e.end)},this.$sendDeltaQueue=function(){var e=this.deltaQueue;if(!e)return;this.deltaQueue=null,e.length>50&&e.length>this.$doc.getLength()>>1?this.call("setValue",[this.$doc.getValue()]):this.emit("change",{data:e})},this.$workerBlob=function(e){var t="importScripts('"+i.qualifyURL(e)+"');";try{return new Blob([t],{type:"application/javascript"})}catch(n){var r=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder,s=new r;return s.append(t),s.getBlob("application/javascript")}}}).call(u.prototype);var a=function(e,t,n){this.$sendDeltaQueue=this.$sendDeltaQueue.bind(this),this.changeListener=this.changeListener.bind(this),this.callbackId=1,this.callbacks={},this.messageBuffer=[];var r=null,i=!1,u=Object.create(s),a=this;this.$worker={},this.$worker.terminate=function(){},this.$worker.postMessage=function(e){a.messageBuffer.push(e),r&&(i?setTimeout(f):f())},this.setEmitSync=function(e){i=e};var f=function(){var e=a.messageBuffer.shift();e.command?r[e.command].apply(r,e.args):e.event&&u._signal(e.event,e.data)};u.postMessage=function(e){a.onMessage({data:e})},u.callback=function(e,t){this.postMessage({type:"call",id:t,data:e})},u.emit=function(e,t){this.postMessage({type:"event",name:e,data:t})},o.loadModule(["worker",t],function(e){r=new e[n](u);while(a.messageBuffer.length)f()})};a.prototype=u.prototype,t.UIWorkerClient=a,t.WorkerClient=u}),define("ace/placeholder",["require","exports","module","ace/range","ace/lib/event_emitter","ace/lib/oop"],function(e,t,n){"use strict";var r=e("./range").Range,i=e("./lib/event_emitter").EventEmitter,s=e("./lib/oop"),o=function(e,t,n,r,i,s){var o=this;this.length=t,this.session=e,this.doc=e.getDocument(),this.mainClass=i,this.othersClass=s,this.$onUpdate=this.onUpdate.bind(this),this.doc.on("change",this.$onUpdate),this.$others=r,this.$onCursorChange=function(){setTimeout(function(){o.onCursorChange()})},this.$pos=n;var u=e.getUndoManager().$undoStack||e.getUndoManager().$undostack||{length:-1};this.$undoStackDepth=u.length,this.setup(),e.selection.on("changeCursor",this.$onCursorChange)};(function(){s.implement(this,i),this.setup=function(){var e=this,t=this.doc,n=this.session;this.selectionBefore=n.selection.toJSON(),n.selection.inMultiSelectMode&&n.selection.toSingleRange(),this.pos=t.createAnchor(this.$pos.row,this.$pos.column);var i=this.pos;i.$insertRight=!0,i.detach(),i.markerId=n.addMarker(new r(i.row,i.column,i.row,i.column+this.length),this.mainClass,null,!1),this.others=[],this.$others.forEach(function(n){var r=t.createAnchor(n.row,n.column);r.$insertRight=!0,r.detach(),e.others.push(r)}),n.setUndoSelect(!1)},this.showOtherMarkers=function(){if(this.othersActive)return;var e=this.session,t=this;this.othersActive=!0,this.others.forEach(function(n){n.markerId=e.addMarker(new r(n.row,n.column,n.row,n.column+t.length),t.othersClass,null,!1)})},this.hideOtherMarkers=function(){if(!this.othersActive)return;this.othersActive=!1;for(var e=0;e=this.pos.column&&t.start.column<=this.pos.column+this.length+1,s=t.start.column-this.pos.column;this.updateAnchors(e),i&&(this.length+=n);if(i&&!this.session.$fromUndo)if(e.action==="insert")for(var o=this.others.length-1;o>=0;o--){var u=this.others[o],a={row:u.row,column:u.column+s};this.doc.insertMergedLines(a,e.lines)}else if(e.action==="remove")for(var o=this.others.length-1;o>=0;o--){var u=this.others[o],a={row:u.row,column:u.column+s};this.doc.remove(new r(a.row,a.column,a.row,a.column-n))}this.$updating=!1,this.updateMarkers()},this.updateAnchors=function(e){this.pos.onChange(e);for(var t=this.others.length;t--;)this.others[t].onChange(e);this.updateMarkers()},this.updateMarkers=function(){if(this.$updating)return;var e=this,t=this.session,n=function(n,i){t.removeMarker(n.markerId),n.markerId=t.addMarker(new r(n.row,n.column,n.row,n.column+e.length),i,null,!1)};n(this.pos,this.mainClass);for(var i=this.others.length;i--;)n(this.others[i],this.othersClass)},this.onCursorChange=function(e){if(this.$updating||!this.session)return;var t=this.session.selection.getCursor();t.row===this.pos.row&&t.column>=this.pos.column&&t.column<=this.pos.column+this.length?(this.showOtherMarkers(),this._emit("cursorEnter",e)):(this.hideOtherMarkers(),this._emit("cursorLeave",e))},this.detach=function(){this.session.removeMarker(this.pos&&this.pos.markerId),this.hideOtherMarkers(),this.doc.removeEventListener("change",this.$onUpdate),this.session.selection.removeEventListener("changeCursor",this.$onCursorChange),this.session.setUndoSelect(!0),this.session=null},this.cancel=function(){if(this.$undoStackDepth===-1)return;var e=this.session.getUndoManager(),t=(e.$undoStack||e.$undostack).length-this.$undoStackDepth;for(var n=0;n1&&!this.inMultiSelectMode&&(this._signal("multiSelect"),this.inMultiSelectMode=!0,this.session.$undoSelect=!1,this.rangeList.attach(this.session)),t||this.fromOrientedRange(e)},this.toSingleRange=function(e){e=e||this.ranges[0];var t=this.rangeList.removeAll();t.length&&this.$onRemoveRange(t),e&&this.fromOrientedRange(e)},this.substractPoint=function(e){var t=this.rangeList.substractPoint(e);if(t)return this.$onRemoveRange(t),t[0]},this.mergeOverlappingRanges=function(){var e=this.rangeList.merge();e.length?this.$onRemoveRange(e):this.ranges[0]&&this.fromOrientedRange(this.ranges[0])},this.$onAddRange=function(e){this.rangeCount=this.rangeList.ranges.length,this.ranges.unshift(e),this._signal("addRange",{range:e})},this.$onRemoveRange=function(e){this.rangeCount=this.rangeList.ranges.length;if(this.rangeCount==1&&this.inMultiSelectMode){var t=this.rangeList.ranges.pop();e.push(t),this.rangeCount=0}for(var n=e.length;n--;){var r=this.ranges.indexOf(e[n]);this.ranges.splice(r,1)}this._signal("removeRange",{ranges:e}),this.rangeCount===0&&this.inMultiSelectMode&&(this.inMultiSelectMode=!1,this._signal("singleSelect"),this.session.$undoSelect=!0,this.rangeList.detach(this.session)),t=t||this.ranges[0],t&&!t.isEqual(this.getRange())&&this.fromOrientedRange(t)},this.$initRangeList=function(){if(this.rangeList)return;this.rangeList=new r,this.ranges=[],this.rangeCount=0},this.getAllRanges=function(){return this.rangeCount?this.rangeList.ranges.concat():[this.getRange()]},this.splitIntoLines=function(){if(this.rangeCount>1){var e=this.rangeList.ranges,t=e[e.length-1],n=i.fromPoints(e[0].start,t.end);this.toSingleRange(),this.setSelectionRange(n,t.cursor==t.start)}else{var n=this.getRange(),r=this.isBackwards(),s=n.start.row,o=n.end.row;if(s==o){if(r)var u=n.end,a=n.start;else var u=n.start,a=n.end;this.addRange(i.fromPoints(a,a)),this.addRange(i.fromPoints(u,u));return}var f=[],l=this.getLineRange(s,!0);l.start.column=n.start.column,f.push(l);for(var c=s+1;c1){var e=this.rangeList.ranges,t=e[e.length-1],n=i.fromPoints(e[0].start,t.end);this.toSingleRange(),this.setSelectionRange(n,t.cursor==t.start)}else{var r=this.session.documentToScreenPosition(this.selectionLead),s=this.session.documentToScreenPosition(this.selectionAnchor),o=this.rectangularRangeBlock(r,s);o.forEach(this.addRange,this)}},this.rectangularRangeBlock=function(e,t,n){var r=[],s=e.column0)d--;if(d>0){var m=0;while(r[m].isEmpty())m++}for(var g=d;g>=m;g--)r[g].isEmpty()&&r.splice(g,1)}return r}}.call(s.prototype);var d=e("./editor").Editor;(function(){this.updateSelectionMarkers=function(){this.renderer.updateCursor(),this.renderer.updateBackMarkers()},this.addSelectionMarker=function(e){e.cursor||(e.cursor=e.end);var t=this.getSelectionStyle();return e.marker=this.session.addMarker(e,"ace_selection",t),this.session.$selectionMarkers.push(e),this.session.selectionMarkerCount=this.session.$selectionMarkers.length,e},this.removeSelectionMarker=function(e){if(!e.marker)return;this.session.removeMarker(e.marker);var t=this.session.$selectionMarkers.indexOf(e);t!=-1&&this.session.$selectionMarkers.splice(t,1),this.session.selectionMarkerCount=this.session.$selectionMarkers.length},this.removeSelectionMarkers=function(e){var t=this.session.$selectionMarkers;for(var n=e.length;n--;){var r=e[n];if(!r.marker)continue;this.session.removeMarker(r.marker);var i=t.indexOf(r);i!=-1&&t.splice(i,1)}this.session.selectionMarkerCount=t.length},this.$onAddRange=function(e){this.addSelectionMarker(e.range),this.renderer.updateCursor(),this.renderer.updateBackMarkers()},this.$onRemoveRange=function(e){this.removeSelectionMarkers(e.ranges),this.renderer.updateCursor(),this.renderer.updateBackMarkers()},this.$onMultiSelect=function(e){if(this.inMultiSelectMode)return;this.inMultiSelectMode=!0,this.setStyle("ace_multiselect"),this.keyBinding.addKeyboardHandler(f.keyboardHandler),this.commands.setDefaultHandler("exec",this.$onMultiSelectExec),this.renderer.updateCursor(),this.renderer.updateBackMarkers()},this.$onSingleSelect=function(e){if(this.session.multiSelect.inVirtualMode)return;this.inMultiSelectMode=!1,this.unsetStyle("ace_multiselect"),this.keyBinding.removeKeyboardHandler(f.keyboardHandler),this.commands.removeDefaultHandler("exec",this.$onMultiSelectExec),this.renderer.updateCursor(),this.renderer.updateBackMarkers(),this._emit("changeSelection")},this.$onMultiSelectExec=function(e){var t=e.command,n=e.editor;if(!n.multiSelect)return;if(!t.multiSelectAction){var r=t.exec(n,e.args||{});n.multiSelect.addRange(n.multiSelect.toOrientedRange()),n.multiSelect.mergeOverlappingRanges()}else t.multiSelectAction=="forEach"?r=n.forEachSelection(t,e.args):t.multiSelectAction=="forEachLine"?r=n.forEachSelection(t,e.args,!0):t.multiSelectAction=="single"?(n.exitMultiSelectMode(),r=t.exec(n,e.args||{})):r=t.multiSelectAction(n,e.args||{});return r},this.forEachSelection=function(e,t,n){if(this.inVirtualSelectionMode)return;var r=n&&n.keepOrder,i=n==1||n&&n.$byLines,o=this.session,u=this.selection,a=u.rangeList,f=(r?u:a).ranges,l;if(!f.length)return e.exec?e.exec(this,t||{}):e(this,t||{});var c=u._eventRegistry;u._eventRegistry={};var h=new s(o);this.inVirtualSelectionMode=!0;for(var p=f.length;p--;){if(i)while(p>0&&f[p].start.row==f[p-1].end.row)p--;h.fromOrientedRange(f[p]),h.index=p,this.selection=o.selection=h;var d=e.exec?e.exec(this,t||{}):e(this,t||{});!l&&d!==undefined&&(l=d),h.toOrientedRange(f[p])}h.detach(),this.selection=o.selection=u,this.inVirtualSelectionMode=!1,u._eventRegistry=c,u.mergeOverlappingRanges();var v=this.renderer.$scrollAnimation;return this.onCursorChange(),this.onSelectionChange(),v&&v.from==v.to&&this.renderer.animateScrolling(v.from),l},this.exitMultiSelectMode=function(){if(!this.inMultiSelectMode||this.inVirtualSelectionMode)return;this.multiSelect.toSingleRange()},this.getSelectedText=function(){var e="";if(this.inMultiSelectMode&&!this.inVirtualSelectionMode){var t=this.multiSelect.rangeList.ranges,n=[];for(var r=0;r0);u<0&&(u=0),f>=c&&(f=c-1)}var p=this.session.removeFullLines(u,f);p=this.$reAlignText(p,l),this.session.insert({row:u,column:0},p.join("\n")+"\n"),l||(o.start.column=0,o.end.column=p[p.length-1].length),this.selection.setRange(o)}else{s.forEach(function(e){t.substractPoint(e.cursor)});var d=0,v=Infinity,m=n.map(function(t){var n=t.cursor,r=e.getLine(n.row),i=r.substr(n.column).search(/\S/g);return i==-1&&(i=0),n.column>d&&(d=n.column),io?e.insert(r,a.stringRepeat(" ",s-o)):e.remove(new i(r.row,r.column,r.row,r.column-s+o)),t.start.column=t.end.column=d,t.start.row=t.end.row=r.row,t.cursor=t.end}),t.fromOrientedRange(n[0]),this.renderer.updateCursor(),this.renderer.updateBackMarkers()}},this.$reAlignText=function(e,t){function u(e){return a.stringRepeat(" ",e)}function f(e){return e[2]?u(i)+e[2]+u(s-e[2].length+o)+e[4].replace(/^([=:])\s+/,"$1 "):e[0]}function l(e){return e[2]?u(i+s-e[2].length)+e[2]+u(o," ")+e[4].replace(/^([=:])\s+/,"$1 "):e[0]}function c(e){return e[2]?u(i)+e[2]+u(o)+e[4].replace(/^([=:])\s+/,"$1 "):e[0]}var n=!0,r=!0,i,s,o;return e.map(function(e){var t=e.match(/(\s*)(.*?)(\s*)([=:].*)/);return t?i==null?(i=t[1].length,s=t[2].length,o=t[3].length,t):(i+s+o!=t[1].length+t[2].length+t[3].length&&(r=!1),i!=t[1].length&&(n=!1),i>t[1].length&&(i=t[1].length),st[3].length&&(o=t[3].length),t):[e]}).map(t?f:n?r?l:f:c)}}).call(d.prototype),t.onSessionChange=function(e){var t=e.session;t&&!t.multiSelect&&(t.$selectionMarkers=[],t.selection.$initRangeList(),t.multiSelect=t.selection),this.multiSelect=t&&t.multiSelect;var n=e.oldSession;n&&(n.multiSelect.off("addRange",this.$onAddRange),n.multiSelect.off("removeRange",this.$onRemoveRange),n.multiSelect.off("multiSelect",this.$onMultiSelect),n.multiSelect.off("singleSelect",this.$onSingleSelect),n.multiSelect.lead.off("change",this.$checkMultiselectChange),n.multiSelect.anchor.off("change",this.$checkMultiselectChange)),t&&(t.multiSelect.on("addRange",this.$onAddRange),t.multiSelect.on("removeRange",this.$onRemoveRange),t.multiSelect.on("multiSelect",this.$onMultiSelect),t.multiSelect.on("singleSelect",this.$onSingleSelect),t.multiSelect.lead.on("change",this.$checkMultiselectChange),t.multiSelect.anchor.on("change",this.$checkMultiselectChange)),t&&this.inMultiSelectMode!=t.selection.inMultiSelectMode&&(t.selection.inMultiSelectMode?this.$onMultiSelect():this.$onSingleSelect())},t.MultiSelect=m,e("./config").defineOptions(d.prototype,"editor",{enableMultiselect:{set:function(e){m(this),e?(this.on("changeSession",this.$multiselectOnSessionChange),this.on("mousedown",o)):(this.off("changeSession",this.$multiselectOnSessionChange),this.off("mousedown",o))},value:!0},enableBlockSelect:{set:function(e){this.$blockSelectEnabled=e},value:!0}})}),define("ace/mode/folding/fold_mode",["require","exports","module","ace/range"],function(e,t,n){"use strict";var r=e("../../range").Range,i=t.FoldMode=function(){};(function(){this.foldingStartMarker=null,this.foldingStopMarker=null,this.getFoldWidget=function(e,t,n){var r=e.getLine(n);return this.foldingStartMarker.test(r)?"start":t=="markbeginend"&&this.foldingStopMarker&&this.foldingStopMarker.test(r)?"end":""},this.getFoldWidgetRange=function(e,t,n){return null},this.indentationBlock=function(e,t,n){var i=/\S/,s=e.getLine(t),o=s.search(i);if(o==-1)return;var u=n||s.length,a=e.getLength(),f=t,l=t;while(++tf){var h=e.getLine(l).length;return new r(f,u,l,h)}},this.openingBracketBlock=function(e,t,n,i,s){var o={row:n,column:i+1},u=e.$findClosingBracket(t,o,s);if(!u)return;var a=e.foldWidgets[u.row];return a==null&&(a=e.getFoldWidget(u.row)),a=="start"&&u.row>o.row&&(u.row--,u.column=e.getLine(u.row).length),r.fromPoints(o,u)},this.closingBracketBlock=function(e,t,n,i,s){var o={row:n,column:i},u=e.$findOpeningBracket(t,o);if(!u)return;return u.column++,o.column--,r.fromPoints(u,o)}}).call(i.prototype)}),define("ace/theme/textmate",["require","exports","module","ace/lib/dom"],function(e,t,n){"use strict";t.isDark=!1,t.cssClass="ace-tm",t.cssText='.ace-tm .ace_gutter {background: #f0f0f0;color: #333;}.ace-tm .ace_print-margin {width: 1px;background: #e8e8e8;}.ace-tm .ace_fold {background-color: #6B72E6;}.ace-tm {background-color: #FFFFFF;color: black;}.ace-tm .ace_cursor {color: black;}.ace-tm .ace_invisible {color: rgb(191, 191, 191);}.ace-tm .ace_storage,.ace-tm .ace_keyword {color: blue;}.ace-tm .ace_constant {color: rgb(197, 6, 11);}.ace-tm .ace_constant.ace_buildin {color: rgb(88, 72, 246);}.ace-tm .ace_constant.ace_language {color: rgb(88, 92, 246);}.ace-tm .ace_constant.ace_library {color: rgb(6, 150, 14);}.ace-tm .ace_invalid {background-color: rgba(255, 0, 0, 0.1);color: red;}.ace-tm .ace_support.ace_function {color: rgb(60, 76, 114);}.ace-tm .ace_support.ace_constant {color: rgb(6, 150, 14);}.ace-tm .ace_support.ace_type,.ace-tm .ace_support.ace_class {color: rgb(109, 121, 222);}.ace-tm .ace_keyword.ace_operator {color: rgb(104, 118, 135);}.ace-tm .ace_string {color: rgb(3, 106, 7);}.ace-tm .ace_comment {color: rgb(76, 136, 107);}.ace-tm .ace_comment.ace_doc {color: rgb(0, 102, 255);}.ace-tm .ace_comment.ace_doc.ace_tag {color: rgb(128, 159, 191);}.ace-tm .ace_constant.ace_numeric {color: rgb(0, 0, 205);}.ace-tm .ace_variable {color: rgb(49, 132, 149);}.ace-tm .ace_xml-pe {color: rgb(104, 104, 91);}.ace-tm .ace_entity.ace_name.ace_function {color: #0000A2;}.ace-tm .ace_heading {color: rgb(12, 7, 255);}.ace-tm .ace_list {color:rgb(185, 6, 144);}.ace-tm .ace_meta.ace_tag {color:rgb(0, 22, 142);}.ace-tm .ace_string.ace_regex {color: rgb(255, 0, 0)}.ace-tm .ace_marker-layer .ace_selection {background: rgb(181, 213, 255);}.ace-tm.ace_multiselect .ace_selection.ace_start {box-shadow: 0 0 3px 0px white;}.ace-tm .ace_marker-layer .ace_step {background: rgb(252, 255, 0);}.ace-tm .ace_marker-layer .ace_stack {background: rgb(164, 229, 101);}.ace-tm .ace_marker-layer .ace_bracket {margin: -1px 0 0 -1px;border: 1px solid rgb(192, 192, 192);}.ace-tm .ace_marker-layer .ace_active-line {background: rgba(0, 0, 0, 0.07);}.ace-tm .ace_gutter-active-line {background-color : #dcdcdc;}.ace-tm .ace_marker-layer .ace_selected-word {background: rgb(250, 250, 255);border: 1px solid rgb(200, 200, 250);}.ace-tm .ace_indent-guide {background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAE0lEQVQImWP4////f4bLly//BwAmVgd1/w11/gAAAABJRU5ErkJggg==") right repeat-y;}';var r=e("../lib/dom");r.importCssString(t.cssText,t.cssClass)}),define("ace/line_widgets",["require","exports","module","ace/lib/oop","ace/lib/dom","ace/range"],function(e,t,n){"use strict";function o(e){this.session=e,this.session.widgetManager=this,this.session.getRowLength=this.getRowLength,this.session.$getWidgetScreenLength=this.$getWidgetScreenLength,this.updateOnChange=this.updateOnChange.bind(this),this.renderWidgets=this.renderWidgets.bind(this),this.measureWidgets=this.measureWidgets.bind(this),this.session._changedWidgets=[],this.$onChangeEditor=this.$onChangeEditor.bind(this),this.session.on("change",this.updateOnChange),this.session.on("changeFold",this.updateOnFold),this.session.on("changeEditor",this.$onChangeEditor)}var r=e("./lib/oop"),i=e("./lib/dom"),s=e("./range").Range;(function(){this.getRowLength=function(e){var t;return this.lineWidgets?t=this.lineWidgets[e]&&this.lineWidgets[e].rowCount||0:t=0,!this.$useWrapMode||!this.$wrapData[e]?1+t:this.$wrapData[e].length+1+t},this.$getWidgetScreenLength=function(){var e=0;return this.lineWidgets.forEach(function(t){t&&t.rowCount&&!t.hidden&&(e+=t.rowCount)}),e},this.$onChangeEditor=function(e){this.attach(e.editor)},this.attach=function(e){e&&e.widgetManager&&e.widgetManager!=this&&e.widgetManager.detach();if(this.editor==e)return;this.detach(),this.editor=e,e&&(e.widgetManager=this,e.renderer.on("beforeRender",this.measureWidgets),e.renderer.on("afterRender",this.renderWidgets))},this.detach=function(e){var t=this.editor;if(!t)return;this.editor=null,t.widgetManager=null,t.renderer.off("beforeRender",this.measureWidgets),t.renderer.off("afterRender",this.renderWidgets);var n=this.session.lineWidgets;n&&n.forEach(function(e){e&&e.el&&e.el.parentNode&&(e._inDocument=!1,e.el.parentNode.removeChild(e.el))})},this.updateOnFold=function(e,t){var n=t.lineWidgets;if(!n||!e.action)return;var r=e.data,i=r.start.row,s=r.end.row,o=e.action=="add";for(var u=i+1;u0&&!r[i])i--;this.firstRow=n.firstRow,this.lastRow=n.lastRow,t.$cursorLayer.config=n;for(var o=i;o<=s;o++){var u=r[o];if(!u||!u.el)continue;if(u.hidden){u.el.style.top=-100-(u.pixelHeight||0)+"px";continue}u._inDocument||(u._inDocument=!0,t.container.appendChild(u.el));var a=t.$cursorLayer.getPixelPosition({row:o,column:0},!0).top;u.coverLine||(a+=n.lineHeight*this.session.getRowLineCount(u.row)),u.el.style.top=a-n.offset+"px";var f=u.coverGutter?0:t.gutterWidth;u.fixedWidth||(f-=t.scrollLeft),u.el.style.left=f+"px",u.fullWidth&&u.screenWidth&&(u.el.style.minWidth=n.width+2*n.padding+"px"),u.fixedWidth?u.el.style.right=t.scrollBar.getWidth()+"px":u.el.style.right=""}}}).call(o.prototype),t.LineWidgets=o}),define("ace/ext/error_marker",["require","exports","module","ace/line_widgets","ace/lib/dom","ace/range"],function(e,t,n){"use strict";function o(e,t,n){var r=0,i=e.length-1;while(r<=i){var s=r+i>>1,o=n(t,e[s]);if(o>0)r=s+1;else{if(!(o<0))return s;i=s-1}}return-(r+1)}function u(e,t,n){var r=e.getAnnotations().sort(s.comparePoints);if(!r.length)return;var i=o(r,{row:t,column:-1},s.comparePoints);i<0&&(i=-i-1),i>=r.length?i=n>0?0:r.length-1:i===0&&n<0&&(i=r.length-1);var u=r[i];if(!u||!n)return;if(u.row===t){do u=r[i+=n];while(u&&u.row===t);if(!u)return r.slice()}var a=[];t=u.row;do a[n<0?"unshift":"push"](u),u=r[i+=n];while(u&&u.row==t);return a.length&&a}var r=e("../line_widgets").LineWidgets,i=e("../lib/dom"),s=e("../range").Range;t.showErrorMarker=function(e,t){var n=e.session;n.widgetManager||(n.widgetManager=new r(n),n.widgetManager.attach(e));var s=e.getCursorPosition(),o=s.row,a=n.widgetManager.getWidgetsAtRow(o).filter(function(e){return e.type=="errorMarker"})[0];a?a.destroy():o-=t;var f=u(n,o,t),l;if(f){var c=f[0];s.column=(c.pos&&typeof c.column!="number"?c.pos.sc:c.column)||0,s.row=c.row,l=e.renderer.$gutterLayer.$annotations[s.row]}else{if(a)return;l={text:["Looks good!"],className:"ace_ok"}}e.session.unfold(s.row),e.selection.moveToPosition(s);var h={row:s.row,fixedWidth:!0,coverGutter:!0,el:i.createElement("div"),type:"errorMarker"},p=h.el.appendChild(i.createElement("div")),d=h.el.appendChild(i.createElement("div"));d.className="error_widget_arrow "+l.className;var v=e.renderer.$cursorLayer.getPixelPosition(s).left;d.style.left=v+e.renderer.gutterWidth-5+"px",h.el.className="error_widget_wrapper",p.className="error_widget "+l.className,p.innerHTML=l.text.join("
"),p.appendChild(i.createElement("div"));var m=function(e,t,n){if(t===0&&(n==="esc"||n==="return"))return h.destroy(),{command:"null"}};h.destroy=function(){if(e.$mouseHandler.isMousePressed)return;e.keyBinding.removeKeyboardHandler(m),n.widgetManager.removeLineWidget(h),e.off("changeSelection",h.destroy),e.off("changeSession",h.destroy),e.off("mouseup",h.destroy),e.off("change",h.destroy)},e.keyBinding.addKeyboardHandler(m),e.on("changeSelection",h.destroy),e.on("changeSession",h.destroy),e.on("mouseup",h.destroy),e.on("change",h.destroy),e.session.widgetManager.addLineWidget(h),h.el.onmousedown=e.focus.bind(e),e.renderer.scrollCursorIntoView(null,.5,{bottom:h.el.offsetHeight})},i.importCssString(" .error_widget_wrapper { background: inherit; color: inherit; border:none } .error_widget { border-top: solid 2px; border-bottom: solid 2px; margin: 5px 0; padding: 10px 40px; white-space: pre-wrap; } .error_widget.ace_error, .error_widget_arrow.ace_error{ border-color: #ff5a5a } .error_widget.ace_warning, .error_widget_arrow.ace_warning{ border-color: #F1D817 } .error_widget.ace_info, .error_widget_arrow.ace_info{ border-color: #5a5a5a } .error_widget.ace_ok, .error_widget_arrow.ace_ok{ border-color: #5aaa5a } .error_widget_arrow { position: absolute; border: solid 5px; border-top-color: transparent!important; border-right-color: transparent!important; border-left-color: transparent!important; top: -5px; }","")}),define("ace/ace",["require","exports","module","ace/lib/fixoldbrowsers","ace/lib/dom","ace/lib/event","ace/editor","ace/edit_session","ace/undomanager","ace/virtual_renderer","ace/worker/worker_client","ace/keyboard/hash_handler","ace/placeholder","ace/multi_select","ace/mode/folding/fold_mode","ace/theme/textmate","ace/ext/error_marker","ace/config"],function(e,t,n){"use strict";e("./lib/fixoldbrowsers");var r=e("./lib/dom"),i=e("./lib/event"),s=e("./editor").Editor,o=e("./edit_session").EditSession,u=e("./undomanager").UndoManager,a=e("./virtual_renderer").VirtualRenderer;e("./worker/worker_client"),e("./keyboard/hash_handler"),e("./placeholder"),e("./multi_select"),e("./mode/folding/fold_mode"),e("./theme/textmate"),e("./ext/error_marker"),t.config=e("./config"),t.require=e,typeof define=="function"&&(t.define=define),t.edit=function(e){if(typeof e=="string"){var n=e;e=document.getElementById(n);if(!e)throw new Error("ace.edit can't find div #"+n)}if(e&&e.env&&e.env.editor instanceof s)return e.env.editor;var o="";if(e&&/input|textarea/i.test(e.tagName)){var u=e;o=u.value,e=r.createElement("pre"),u.parentNode.replaceChild(e,u)}else e&&(o=r.getInnerText(e),e.innerHTML="");var f=t.createEditSession(o),l=new s(new a(e));l.setSession(f);var c={document:f,editor:l,onResize:l.resize.bind(l,null)};return u&&(c.textarea=u),i.addListener(window,"resize",c.onResize),l.on("destroy",function(){i.removeListener(window,"resize",c.onResize),c.editor.container.env=null}),l.container.env=l.env=c,l},t.createEditSession=function(e,t){var n=new o(e,t);return n.setUndoManager(new u),n},t.EditSession=o,t.UndoManager=u,t.version="1.2.6"}); - (function() { - window.require(["ace/ace"], function(a) { - if (a) { - a.config.init(true); - a.define = window.define; - } - if (!window.ace) - window.ace = a; - for (var key in a) if (a.hasOwnProperty(key)) - window.ace[key] = a[key]; - }); - })(); - \ No newline at end of file diff --git a/examples/SmartSwitch/data_src/js_css_src/app.js b/examples/SmartSwitch/data_src/js_css_src/app.js deleted file mode 100644 index 46305f295..000000000 --- a/examples/SmartSwitch/data_src/js_css_src/app.js +++ /dev/null @@ -1,5787 +0,0 @@ -var tpick = { - attach: function (target) { - - var dig = document.getElementById(target).value.split(":"); - var t1 = dig[0] || "23"; - var t2 = dig[1] || "59"; - - var uniqueID = 0; - while (document.getElementById("tpick-" + uniqueID) != null) { - uniqueID = Math.floor(Math.random() * (100 - 2)) + 1; - } - var tw = document.createElement("div"); - tw.id = "tpick-" + uniqueID; - tw.classList.add("tpop"); - tw.dataset.target = target; - tw.addEventListener("click", function (evt) { - if (evt.target.classList.contains("tpop")) { - this.classList.remove("show"); - } - }); - var tp = document.createElement("div"); - tp.classList.add("tpicker"); - tp.appendChild(this.draw("h",t1)); - tp.appendChild(this.draw("m",t2)); - var bottom = document.createElement("div"), - ok = document.createElement("input"); - ok.setAttribute("type", "button"); - ok.value = "OK"; - ok.addEventListener("click", function () { - tpick.set(this); - }); - bottom.classList.add("tpicker-btn"); - bottom.appendChild(ok); - tp.appendChild(bottom); - tw.appendChild(tp); - document.body.appendChild(tw); - var target = document.getElementById(target); - target.dataset.dp = uniqueID; - target.onfocus = function () { - document.getElementById("tpick-" + this.dataset.dp).classList.add("show"); - }; - }, - draw: function (type,tv) { - var docket = document.createElement("div"), - up = document.createElement("div"), - down = document.createElement("div"), - text = document.createElement("input"); - docket.classList.add("tpicker-" + type); - up.classList.add("tpicker-up"); - down.classList.add("tpicker-down"); - up.innerHTML = "︿"; - down.innerHTML = "﹀"; - text.readOnly = true; - text.setAttribute("type", "text"); - if (type == "h") { - text.value = tv; - up.addEventListener("click", function () { - tpick.spin("h", 1, this); - }); - down.addEventListener("click", function () { - tpick.spin("h", 0, this); - }); - } else if (type == "m") { - text.value = tv; - up.addEventListener("click", function () { - tpick.spin("m", 1, this); - }); - down.addEventListener("click", function () { - tpick.spin("m", 0, this); - }); - } - docket.appendChild(up); - docket.appendChild(text); - docket.appendChild(down); - return docket; - }, - spin: function (type, direction, el) { - var parent = el.parentElement, - field = parent.getElementsByTagName("input")[0], - value = field.value; - if (type == "h") { - value = parseInt(value); - if (direction) { - value++; - } else { - value--; - } - if (value == -1) { - value = 23; - } else if (value > 23) { - value = 0; - } - } else if (type == "m") { - value = parseInt(value); - if (direction) { - value += 5; - } else { - value -= 5; - } - if (value < 0) { - value = 55; - } else if (value > 59) { - value = 0; - } - if (value < 10) { - value = "0" + value; - } - } - field.value = ('00' + value).substr(-2); - }, - set: function (el) { - var parent = el.parentElement; - while (parent.classList.contains("tpop") == false) { - parent = parent.parentElement; - } - var input = parent.querySelectorAll("input[type=text]"); - var time = input[0].value + ":" + input[1].value; - document.getElementById(parent.dataset.target).value = time; - parent.classList.remove("show"); - } -}; -var fpick = { - attach: function (target) { - - var dig = document.getElementById(target).value.split("."); - var t1 = dig[0] || "1"; - var t2 = dig[1] || "2"; - var uniqueID = 0; - while (document.getElementById("fpick-" + uniqueID) != null) { - uniqueID = Math.floor(Math.random() * (100 - 2)) + 1; - } - var tw = document.createElement("div"); - tw.id = "fpick-" + uniqueID; - tw.classList.add("tpop"); - tw.dataset.target = target; - tw.addEventListener("click", function (evt) { - if (evt.target.classList.contains("tpop")) { - this.classList.remove("show"); - } - }); - var tp = document.createElement("div"); - tp.classList.add("fpicker"); - tp.appendChild(this.draw("h",t1)); - tp.appendChild(this.draw("m",t2)); - var bottom = document.createElement("div"), - ok = document.createElement("input"); - ok.setAttribute("type", "button"); - ok.value = "OK"; - ok.addEventListener("click", function () { - fpick.set(this); - }); - bottom.classList.add("fpicker-btn"); - bottom.appendChild(ok); - tp.appendChild(bottom); - tw.appendChild(tp); - document.body.appendChild(tw); - var target = document.getElementById(target); - target.dataset.dp = uniqueID; - target.onfocus = function () { - document.getElementById("fpick-" + this.dataset.dp).classList.add("show"); - }; - }, - draw: function (type,tv) { - - var docket = document.createElement("div"), - up = document.createElement("div"), - down = document.createElement("div"), - text = document.createElement("input"); - docket.classList.add("fpicker-" + type); - up.classList.add("fpicker-up"); - down.classList.add("fpicker-down"); - up.innerHTML = "︿"; - down.innerHTML = "﹀"; - text.readOnly = true; - text.setAttribute("type", "text"); - if (type == "h") { - text.value = tv; - up.addEventListener("click", function () { - fpick.spin("h", 1, this); - }); - down.addEventListener("click", function () { - fpick.spin("h", 0, this); - }); - } else if (type == "m") { - text.value = tv; - up.addEventListener("click", function () { - fpick.spin("m", 1, this); - }); - down.addEventListener("click", function () { - fpick.spin("m", 0, this); - }); - } - docket.appendChild(up); - docket.appendChild(text); - docket.appendChild(down); - return docket; - }, - spin: function (type, direction, el) { - var parent = el.parentElement, - field = parent.getElementsByTagName("input")[0], - value = field.value; - if (type == "h") { - value = parseInt(value); - if (direction) { - value++; - } else { - value--; - } - if (value == -41) { - value = 99; - } else if (value > 99) { - value = -40; - } - } else if (type == "m") { - value = parseInt(value); - if (direction) { - value++; - } else { - value--; - } - if (value < 0) { - value = 9; - } else if (value > 9) { - value = 0; - } - } - field.value = value; - }, - set: function (el) { - var parent = el.parentElement; - while (parent.classList.contains("tpop") == false) { - parent = parent.parentElement; - } - var input = parent.querySelectorAll("input[type=text]"); - var temperature = input[0].value + "." + input[1].value; - document.getElementById(parent.dataset.target).value = temperature; - parent.classList.remove("show"); - } -}; -!function (t) { - function n(i) { - if (e[i]) - return e[i].exports; - var o = e[i] = { - i: i, - l: !1, - exports: {} - }; - return t[i].call(o.exports, o, o.exports, n), - o.l = !0, - o.exports - } - var e = {}; - n.m = t, - n.c = e, - n.d = function (t, e, i) { - n.o(t, e) || Object.defineProperty(t, e, { - configurable: !1, - enumerable: !0, - get: i - }) - }, - n.n = function (t) { - var e = t && t.__esModule ? function () { - return t.default - } - : function () { - return t - }; - return n.d(e, "a", e), - e - }, - n.o = function (t, n) { - return Object.prototype.hasOwnProperty.call(t, n) - }, - n.p = "", - n(n.s = 0) -} -([function (t, n, e) { - e(1), - t.exports = e(4) - }, function (t, n, e) { - "use strict"; - var i = Object.assign || function (t) { - for (var n = 1; n < arguments.length; n++) { - var e = arguments[n]; - for (var i in e) - Object.prototype.hasOwnProperty.call(e, i) && (t[i] = e[i]) - } - return t - }; - e(2); - var o = e(3); - !function (t) { - function n(t) { - return t = i({}, c, t), - function (t) { - return ["nfc-top-left", "nfc-top-right", "nfc-bottom-left", "nfc-bottom-right"].indexOf(t) > -1 - } - (t.positionClass) || (console.warn("An invalid notification position class has been specified."), t.positionClass = c.positionClass), - t.onclick && "function" != typeof t.onclick && (console.warn("Notification on click must be a function."), t.onclick = c.onclick), - "number" != typeof t.showDuration && (t.showDuration = c.showDuration), - (0, o.isString)(t.theme) && 0 !== t.theme.length || (console.warn("Notification theme must be a string with length"), t.theme = c.theme), - t - } - function e(t) { - return t = n(t), - function () { - var n = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : {}, - e = n.title, - i = n.message, - c = r(t.positionClass); - if (!e && !i) - return console.warn("Notification must contain a title or a message!"); - var a = (0, o.createElement)("div", "ncf", t.theme); - if (!0 === t.closeOnClick && a.addEventListener("click", function () { - return c.removeChild(a) - }), t.onclick && a.addEventListener("click", function (n) { - return t.onclick(n) - }), t.displayCloseButton) { - var s = (0, o.createElement)("button"); - s.innerText = "X", - !1 === t.closeOnClick && s.addEventListener("click", function () { - return c.removeChild(a) - }), - (0, o.append)(a, s) - } - if ((0, o.isString)(e) && e.length && (0, o.append)(a, (0, o.createParagraph)("ncf-title")(e)), (0, o.isString)(i) && i.length && (0, o.append)(a, (0, o.createParagraph)("nfc-message")(i)), (0, o.append)(c, a), t.showDuration && t.showDuration > 0) { - var l = setTimeout(function () { - c.removeChild(a), - 0 === c.querySelectorAll(".ncf").length && document.body.removeChild(c) - }, t.showDuration); - (t.closeOnClick || t.displayCloseButton) && a.addEventListener("click", function () { - return clearTimeout(l) - }) - } - } - } - function r(t) { - var n = document.querySelector("." + t); - return n || (n = (0, o.createElement)("div", "ncf-container", t), (0, o.append)(document.body, n)), - n - } - var c = { - closeOnClick: !0, - displayCloseButton: !1, - positionClass: "nfc-top-right", - onclick: !1, - showDuration: 3500, - theme: "success" - }; - t.createNotification ? console.warn("Window already contains a create notification function. Have you included the script twice?") : t.createNotification = e - } - (window) - }, function (t, n, e) { - "use strict"; - !function () { - function t(t) { - this.el = t; - for (var n = t.className.replace(/^\s+|\s+$/g, "").split(/\s+/), i = 0; i < n.length; i++) - e.call(this, n[i]) - } - if (!(void 0 === window.Element || "classList" in document.documentElement)) { - var n = Array.prototype, - e = n.push, - i = n.splice, - o = n.join; - t.prototype = { - add: function (t) { - this.contains(t) || (e.call(this, t), this.el.className = this.toString()) - }, - contains: function (t) { - return -1 != this.el.className.indexOf(t) - }, - item: function (t) { - return this[t] || null - }, - remove: function (t) { - if (this.contains(t)) { - for (var n = 0; n < this.length && this[n] != t; n++); - i.call(this, n, 1), - this.el.className = this.toString() - } - }, - toString: function () { - return o.call(this, " ") - }, - toggle: function (t) { - return this.contains(t) ? this.remove(t) : this.add(t), - this.contains(t) - } - }, - window.DOMTokenList = t, - function (t, n, e) { - Object.defineProperty ? Object.defineProperty(t, n, { - get: e - }) : t.__defineGetter__(n, e) - } - (Element.prototype, "classList", function () { - return new t(this) - }) - } - } - () - }, function (t, n, e) { - "use strict"; - Object.defineProperty(n, "__esModule", { - value: !0 - }); - var i = n.partial = function (t) { - for (var n = arguments.length, e = Array(n > 1 ? n - 1 : 0), i = 1; i < n; i++) - e[i - 1] = arguments[i]; - return function () { - for (var n = arguments.length, i = Array(n), o = 0; o < n; o++) - i[o] = arguments[o]; - return t.apply(void 0, e.concat(i)) - } - }, - o = (n.append = function (t) { - for (var n = arguments.length, e = Array(n > 1 ? n - 1 : 0), i = 1; i < n; i++) - e[i - 1] = arguments[i]; - return e.forEach(function (n) { - return t.appendChild(n) - }) - }, n.isString = function (t) { - return "string" == typeof t - }, n.createElement = function (t) { - for (var n = arguments.length, e = Array(n > 1 ? n - 1 : 0), i = 1; i < n; i++) - e[i - 1] = arguments[i]; - var o = document.createElement(t); - return e.length && e.forEach(function (t) { - return o.classList.add(t) - }), - o - }), - r = function (t, n) { - return t.innerText = n, - t - }, - c = function (t) { - for (var n = arguments.length, e = Array(n > 1 ? n - 1 : 0), c = 1; c < n; c++) - e[c - 1] = arguments[c]; - return i(r, o.apply(void 0, [t].concat(e))) - }; - n.createParagraph = function () { - for (var t = arguments.length, n = Array(t), e = 0; e < t; e++) - n[e] = arguments[e]; - return c.apply(void 0, ["p"].concat(n)) - } - }, function (t, n) {} - ]); -!function (a, b) { - "function" == typeof define && define.amd ? define("eve", function () { - return b() - }) : "object" == typeof exports ? module.exports = b() : a.eve = b() -} -(this, function () { - var a, - b, - c = "0.4.2", - d = "hasOwnProperty", - e = /[\.\/]/, - f = "*", - g = function () {}, - h = function (a, b) { - return a - b - }, - i = { - n: {} - }, - j = function (c, d) { - c = String(c); - var e, - f = b, - g = Array.prototype.slice.call(arguments, 2), - i = j.listeners(c), - k = 0, - l = [], - m = {}, - n = [], - o = a; - a = c, - b = 0; - for (var p = 0, q = i.length; q > p; p++) - "zIndex" in i[p] && (l.push(i[p].zIndex), i[p].zIndex < 0 && (m[i[p].zIndex] = i[p])); - for (l.sort(h); l[k] < 0; ) - if (e = m[l[k++]], n.push(e.apply(d, g)), b) - return b = f, n; - for (p = 0; q > p; p++) - if (e = i[p], "zIndex" in e) - if (e.zIndex == l[k]) { - if (n.push(e.apply(d, g)), b) - break; - do - if (k++, e = m[l[k]], e && n.push(e.apply(d, g)), b) - break; - while (e) - } else - m[e.zIndex] = e; - else if (n.push(e.apply(d, g)), b) - break; - return b = f, - a = o, - n.length ? n : null - }; - return j._events = i, - j.listeners = function (a) { - var b, - c, - d, - g, - h, - j, - k, - l, - m = a.split(e), - n = i, - o = [n], - p = []; - for (g = 0, h = m.length; h > g; g++) { - for (l = [], j = 0, k = o.length; k > j; j++) - for (n = o[j].n, c = [n[m[g]], n[f]], d = 2; d--; ) - b = c[d], b && (l.push(b), p = p.concat(b.f || [])); - o = l - } - return p - }, - j.on = function (a, b) { - if (a = String(a), "function" != typeof b) - return function () {}; - for (var c = a.split(e), d = i, f = 0, h = c.length; h > f; f++) - d = d.n, d = d.hasOwnProperty(c[f]) && d[c[f]] || (d[c[f]] = { - n: {} - }); - for (d.f = d.f || [], f = 0, h = d.f.length; h > f; f++) - if (d.f[f] == b) - return g; - return d.f.push(b), - function (a) { - +a == +a && (b.zIndex = +a) - } - }, - j.f = function (a) { - var b = [].slice.call(arguments, 1); - return function () { - j.apply(null, [a, null].concat(b).concat([].slice.call(arguments, 0))) - } - }, - j.stop = function () { - b = 1 - }, - j.nt = function (b) { - return b ? new RegExp("(?:\\.|\\/|^)" + b + "(?:\\.|\\/|$)").test(a) : a - }, - j.nts = function () { - return a.split(e) - }, - j.off = j.unbind = function (a, b) { - if (!a) - return void(j._events = i = { - n: {} - }); - var c, - g, - h, - k, - l, - m, - n, - o = a.split(e), - p = [i]; - for (k = 0, l = o.length; l > k; k++) - for (m = 0; m < p.length; m += h.length - 2) { - if (h = [m, 1], c = p[m].n, o[k] != f) - c[o[k]] && h.push(c[o[k]]); - else - for (g in c) - c[d](g) && h.push(c[g]); - p.splice.apply(p, h) - } - for (k = 0, l = p.length; l > k; k++) - for (c = p[k]; c.n; ) { - if (b) { - if (c.f) { - for (m = 0, n = c.f.length; n > m; m++) - if (c.f[m] == b) { - c.f.splice(m, 1); - break - } - !c.f.length && delete c.f - } - for (g in c.n) - if (c.n[d](g) && c.n[g].f) { - var q = c.n[g].f; - for (m = 0, n = q.length; n > m; m++) - if (q[m] == b) { - q.splice(m, 1); - break - } - !q.length && delete c.n[g].f - } - } else { - delete c.f; - for (g in c.n) - c.n[d](g) && c.n[g].f && delete c.n[g].f - } - c = c.n - } - }, - j.once = function (a, b) { - var c = function () { - return j.unbind(a, c), - b.apply(this, arguments) - }; - return j.on(a, c) - }, - j.version = c, - j.toString = function () { - return "You are running Eve " + c - }, - j -}), function (a, b) { - "function" == typeof define && define.amd ? define("raphael.core", ["eve"], function (a) { - return b(a) - }) : "object" == typeof exports ? module.exports = b(require("eve")) : a.Raphael = b(a.eve) -} -(this, function (a) { - function b(c) { - if (b.is(c, "function")) - return t ? c() : a.on("raphael.DOMload", c); - if (b.is(c, U)) - return b._engine.create[C](b, c.splice(0, 3 + b.is(c[0], S))).add(c); - var d = Array.prototype.slice.call(arguments, 0); - if (b.is(d[d.length - 1], "function")) { - var e = d.pop(); - return t ? e.call(b._engine.create[C](b, d)) : a.on("raphael.DOMload", function () { - e.call(b._engine.create[C](b, d)) - }) - } - return b._engine.create[C](b, arguments) - } - function c(a) { - if ("function" == typeof a || Object(a) !== a) - return a; - var b = new a.constructor; - for (var d in a) - a[y](d) && (b[d] = c(a[d])); - return b - } - function d(a, b) { - for (var c = 0, d = a.length; d > c; c++) - if (a[c] === b) - return a.push(a.splice(c, 1)[0]) - } - function e(a, b, c) { - function e() { - var f = Array.prototype.slice.call(arguments, 0), - g = f.join("␀"), - h = e.cache = e.cache || {}, - i = e.count = e.count || []; - return h[y](g) ? (d(i, g), c ? c(h[g]) : h[g]) : (i.length >= 1e3 && delete h[i.shift()], i.push(g), h[g] = a[C](b, f), c ? c(h[g]) : h[g]) - } - return e - } - function f() { - return this.hex - } - function g(a, b) { - for (var c = [], d = 0, e = a.length; e - 2 * !b > d; d += 2) { - var f = [{ - x: +a[d - 2], - y: +a[d - 1] - }, { - x: +a[d], - y: +a[d + 1] - }, { - x: +a[d + 2], - y: +a[d + 3] - }, { - x: +a[d + 4], - y: +a[d + 5] - } - ]; - b ? d ? e - 4 == d ? f[3] = { - x: +a[0], - y: +a[1] - } - : e - 2 == d && (f[2] = { - x: +a[0], - y: +a[1] - }, f[3] = { - x: +a[2], - y: +a[3] - }) : f[0] = { - x: +a[e - 2], - y: +a[e - 1] - } - : e - 4 == d ? f[3] = f[2] : d || (f[0] = { - x: +a[d], - y: +a[d + 1] - }), - c.push(["C", (-f[0].x + 6 * f[1].x + f[2].x) / 6, (-f[0].y + 6 * f[1].y + f[2].y) / 6, (f[1].x + 6 * f[2].x - f[3].x) / 6, (f[1].y + 6 * f[2].y - f[3].y) / 6, f[2].x, f[2].y]) - } - return c - } - function h(a, b, c, d, e) { - var f = -3 * b + 9 * c - 9 * d + 3 * e, - g = a * f + 6 * b - 12 * c + 6 * d; - return a * g - 3 * b + 3 * c - } - function i(a, b, c, d, e, f, g, i, j) { - null == j && (j = 1), - j = j > 1 ? 1 : 0 > j ? 0 : j; - for (var k = j / 2, l = 12, m = [ - .1252, .1252, - .3678, .3678, - .5873, .5873, - .7699, .7699, - .9041, .9041, - .9816, .9816], n = [.2491, .2491, .2335, .2335, .2032, .2032, .1601, .1601, .1069, .1069, .0472, .0472], o = 0, p = 0; l > p; p++) { - var q = k * m[p] + k, - r = h(q, a, c, e, g), - s = h(q, b, d, f, i), - t = r * r + s * s; - o += n[p] * M.sqrt(t) - } - return k * o - } - function j(a, b, c, d, e, f, g, h, j) { - if (!(0 > j || i(a, b, c, d, e, f, g, h) < j)) { - var k, - l = 1, - m = l / 2, - n = l - m, - o = .01; - for (k = i(a, b, c, d, e, f, g, h, n); P(k - j) > o; ) - m /= 2, n += (j > k ? 1 : -1) * m, k = i(a, b, c, d, e, f, g, h, n); - return n - } - } - function k(a, b, c, d, e, f, g, h) { - if (!(N(a, c) < O(e, g) || O(a, c) > N(e, g) || N(b, d) < O(f, h) || O(b, d) > N(f, h))) { - var i = (a * d - b * c) * (e - g) - (a - c) * (e * h - f * g), - j = (a * d - b * c) * (f - h) - (b - d) * (e * h - f * g), - k = (a - c) * (f - h) - (b - d) * (e - g); - if (k) { - var l = i / k, - m = j / k, - n = +l.toFixed(2), - o = +m.toFixed(2); - if (!(n < +O(a, c).toFixed(2) || n > +N(a, c).toFixed(2) || n < +O(e, g).toFixed(2) || n > +N(e, g).toFixed(2) || o < +O(b, d).toFixed(2) || o > +N(b, d).toFixed(2) || o < +O(f, h).toFixed(2) || o > +N(f, h).toFixed(2))) - return { - x: l, - y: m - } - } - } - } - function l(a, c, d) { - var e = b.bezierBBox(a), - f = b.bezierBBox(c); - if (!b.isBBoxIntersect(e, f)) - return d ? 0 : []; - for (var g = i.apply(0, a), h = i.apply(0, c), j = N(~~(g / 5), 1), l = N(~~(h / 5), 1), m = [], n = [], o = {}, p = d ? 0 : [], q = 0; j + 1 > q; q++) { - var r = b.findDotsAtSegment.apply(b, a.concat(q / j)); - m.push({ - x: r.x, - y: r.y, - t: q / j - }) - } - for (q = 0; l + 1 > q; q++) - r = b.findDotsAtSegment.apply(b, c.concat(q / l)), n.push({ - x: r.x, - y: r.y, - t: q / l - }); - for (q = 0; j > q; q++) - for (var s = 0; l > s; s++) { - var t = m[q], - u = m[q + 1], - v = n[s], - w = n[s + 1], - x = P(u.x - t.x) < .001 ? "y" : "x", - y = P(w.x - v.x) < .001 ? "y" : "x", - z = k(t.x, t.y, u.x, u.y, v.x, v.y, w.x, w.y); - if (z) { - if (o[z.x.toFixed(4)] == z.y.toFixed(4)) - continue; - o[z.x.toFixed(4)] = z.y.toFixed(4); - var A = t.t + P((z[x] - t[x]) / (u[x] - t[x])) * (u.t - t.t), - B = v.t + P((z[y] - v[y]) / (w[y] - v[y])) * (w.t - v.t); - A >= 0 && 1.001 >= A && B >= 0 && 1.001 >= B && (d ? p++ : p.push({ - x: z.x, - y: z.y, - t1: O(A, 1), - t2: O(B, 1) - })) - } - } - return p - } - function m(a, c, d) { - a = b._path2curve(a), - c = b._path2curve(c); - for (var e, f, g, h, i, j, k, m, n, o, p = d ? 0 : [], q = 0, r = a.length; r > q; q++) { - var s = a[q]; - if ("M" == s[0]) - e = i = s[1], f = j = s[2]; - else { - "C" == s[0] ? (n = [e, f].concat(s.slice(1)), e = n[6], f = n[7]) : (n = [e, f, e, f, i, j, i, j], e = i, f = j); - for (var t = 0, u = c.length; u > t; t++) { - var v = c[t]; - if ("M" == v[0]) - g = k = v[1], h = m = v[2]; - else { - "C" == v[0] ? (o = [g, h].concat(v.slice(1)), g = o[6], h = o[7]) : (o = [g, h, g, h, k, m, k, m], g = k, h = m); - var w = l(n, o, d); - if (d) - p += w; - else { - for (var x = 0, y = w.length; y > x; x++) - w[x].segment1 = q, w[x].segment2 = t, w[x].bez1 = n, w[x].bez2 = o; - p = p.concat(w) - } - } - } - } - } - return p - } - function n(a, b, c, d, e, f) { - null != a ? (this.a = +a, this.b = +b, this.c = +c, this.d = +d, this.e = +e, this.f = +f) : (this.a = 1, this.b = 0, this.c = 0, this.d = 1, this.e = 0, this.f = 0) - } - function o() { - return this.x + G + this.y + G + this.width + " × " + this.height - } - function p(a, b, c, d, e, f) { - function g(a) { - return ((l * a + k) * a + j) * a - } - function h(a, b) { - var c = i(a, b); - return ((o * c + n) * c + m) * c - } - function i(a, b) { - var c, - d, - e, - f, - h, - i; - for (e = a, i = 0; 8 > i; i++) { - if (f = g(e) - a, P(f) < b) - return e; - if (h = (3 * l * e + 2 * k) * e + j, P(h) < 1e-6) - break; - e -= f / h - } - if (c = 0, d = 1, e = a, c > e) - return c; - if (e > d) - return d; - for (; d > c; ) { - if (f = g(e), P(f - a) < b) - return e; - a > f ? c = e : d = e, - e = (d - c) / 2 + c - } - return e - } - var j = 3 * b, - k = 3 * (d - b) - j, - l = 1 - j - k, - m = 3 * c, - n = 3 * (e - c) - m, - o = 1 - m - n; - return h(a, 1 / (200 * f)) - } - function q(a, b) { - var c = [], - d = {}; - if (this.ms = b, this.times = 1, a) { - for (var e in a) - a[y](e) && (d[$(e)] = a[e], c.push($(e))); - c.sort(ka) - } - this.anim = d, - this.top = c[c.length - 1], - this.percents = c - } - function r(c, d, e, f, g, h) { - e = $(e); - var i, - j, - k, - l, - m, - o, - q = c.ms, - r = {}, - s = {}, - t = {}; - if (f) - for (w = 0, x = fb.length; x > w; w++) { - var u = fb[w]; - if (u.el.id == d.id && u.anim == c) { - u.percent != e ? (fb.splice(w, 1), k = 1) : j = u, - d.attr(u.totalOrigin); - break - } - } - else - f = +s; - for (var w = 0, x = c.percents.length; x > w; w++) { - if (c.percents[w] == e || c.percents[w] > f * c.top) { - e = c.percents[w], - m = c.percents[w - 1] || 0, - q = q / c.top * (e - m), - l = c.percents[w + 1], - i = c.anim[e]; - break - } - f && d.attr(c.anim[c.percents[w]]) - } - if (i) { - if (j) - j.initstatus = f, j.start = new Date - j.ms * f; - else { - for (var z in i) - if (i[y](z) && (ca[y](z) || d.paper.customAttributes[y](z))) - switch (r[z] = d.attr(z), null == r[z] && (r[z] = ba[z]), s[z] = i[z], ca[z]) { - case S: - t[z] = (s[z] - r[z]) / q; - break; - case "colour": - r[z] = b.getRGB(r[z]); - var A = b.getRGB(s[z]); - t[z] = { - r: (A.r - r[z].r) / q, - g: (A.g - r[z].g) / q, - b: (A.b - r[z].b) / q - }; - break; - case "path": - var B = Ia(r[z], s[z]), - C = B[1]; - for (r[z] = B[0], t[z] = [], w = 0, x = r[z].length; x > w; w++) { - t[z][w] = [0]; - for (var E = 1, F = r[z][w].length; F > E; E++) - t[z][w][E] = (C[w][E] - r[z][w][E]) / q - } - break; - case "transform": - var G = d._, - J = Na(G[z], s[z]); - if (J) - for (r[z] = J.from, s[z] = J.to, t[z] = [], t[z].real = !0, w = 0, x = r[z].length; x > w; w++) - for (t[z][w] = [r[z][w][0]], E = 1, F = r[z][w].length; F > E; E++) - t[z][w][E] = (s[z][w][E] - r[z][w][E]) / q; - else { - var K = d.matrix || new n, - L = { - _: { - transform: G.transform - }, - getBBox: function () { - return d.getBBox(1) - } - }; - r[z] = [K.a, K.b, K.c, K.d, K.e, K.f], - La(L, s[z]), - s[z] = L._.transform, - t[z] = [(L.matrix.a - K.a) / q, (L.matrix.b - K.b) / q, (L.matrix.c - K.c) / q, (L.matrix.d - K.d) / q, (L.matrix.e - K.e) / q, (L.matrix.f - K.f) / q] - } - break; - case "csv": - var M = H(i[z])[I](v), - N = H(r[z])[I](v); - if ("clip-rect" == z) - for (r[z] = N, t[z] = [], w = N.length; w--; ) - t[z][w] = (M[w] - r[z][w]) / q; - s[z] = M; - break; - default: - for (M = [][D](i[z]), N = [][D](r[z]), t[z] = [], w = d.paper.customAttributes[z].length; w--; ) - t[z][w] = ((M[w] || 0) - (N[w] || 0)) / q - } - var O = i.easing, - P = b.easing_formulas[O]; - if (!P) - if (P = H(O).match(Y), P && 5 == P.length) { - var Q = P; - P = function (a) { - return p(a, +Q[1], +Q[2], +Q[3], +Q[4], q) - } - } else - P = la; - if (o = i.start || c.start || +new Date, u = { - anim: c, - percent: e, - timestamp: o, - start: o + (c.del || 0), - status: 0, - initstatus: f || 0, - stop: !1, - ms: q, - easing: P, - from: r, - diff: t, - to: s, - el: d, - callback: i.callback, - prev: m, - next: l, - repeat: h || c.times, - origin: d.attr(), - totalOrigin: g - }, fb.push(u), f && !j && !k && (u.stop = !0, u.start = new Date - q * f, 1 == fb.length)) - return hb(); - k && (u.start = new Date - u.ms * f), - 1 == fb.length && gb(hb) - } - a("raphael.anim.start." + d.id, d, c) - } - } - function s(a) { - for (var b = 0; b < fb.length; b++) - fb[b].el.paper == a && fb.splice(b--, 1) - } - b.version = "2.1.4", - b.eve = a; - var t, - u, - v = /[, ]+/, - w = { - circle: 1, - rect: 1, - path: 1, - ellipse: 1, - text: 1, - image: 1 - }, - x = /\{(\d+)\}/g, - y = "hasOwnProperty", - z = { - doc: document, - win: window - }, - A = { - was: Object.prototype[y].call(z.win, "Raphael"), - is: z.win.Raphael - }, - B = function () { - this.ca = this.customAttributes = {} - }, - C = "apply", - D = "concat", - E = "ontouchstart" in z.win || z.win.DocumentTouch && z.doc instanceof DocumentTouch, - F = "", - G = " ", - H = String, - I = "split", - J = "click dblclick mousedown mousemove mouseout mouseover mouseup touchstart touchmove touchend touchcancel"[I](G), - K = { - mousedown: "touchstart", - mousemove: "touchmove", - mouseup: "touchend" - }, - L = H.prototype.toLowerCase, - M = Math, - N = M.max, - O = M.min, - P = M.abs, - Q = M.pow, - R = M.PI, - S = "number", - T = "string", - U = "array", - V = Object.prototype.toString, - W = (b._ISURL = /^url\(['"]?(.+?)['"]?\)$/i, /^\s*((#[a-f\d]{6})|(#[a-f\d]{3})|rgba?\(\s*([\d\.]+%?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+%?(?:\s*,\s*[\d\.]+%?)?)\s*\)|hsba?\(\s*([\d\.]+(?:deg|\xb0|%)?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+(?:%?\s*,\s*[\d\.]+)?)%?\s*\)|hsla?\(\s*([\d\.]+(?:deg|\xb0|%)?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+(?:%?\s*,\s*[\d\.]+)?)%?\s*\))\s*$/i), - X = { - NaN: 1, - Infinity: 1, - "-Infinity": 1 - }, - Y = /^(?:cubic-)?bezier\(([^,]+),([^,]+),([^,]+),([^\)]+)\)/, - Z = M.round, - $ = parseFloat, - _ = parseInt, - aa = H.prototype.toUpperCase, - ba = b._availableAttrs = { - "arrow-end": "none", - "arrow-start": "none", - blur: 0, - "clip-rect": "0 0 1e9 1e9", - cursor: "default", - cx: 0, - cy: 0, - fill: "#fff", - "fill-opacity": 1, - font: '10px "Arial"', - "font-family": '"Arial"', - "font-size": "10", - "font-style": "normal", - "font-weight": 400, - gradient: 0, - height: 0, - href: "http://raphaeljs.com/", - "letter-spacing": 0, - opacity: 1, - path: "M0,0", - r: 0, - rx: 0, - ry: 0, - src: "", - stroke: "#000", - "stroke-dasharray": "", - "stroke-linecap": "butt", - "stroke-linejoin": "butt", - "stroke-miterlimit": 0, - "stroke-opacity": 1, - "stroke-width": 1, - target: "_blank", - "text-anchor": "middle", - title: "Raphael", - transform: "", - width: 0, - x: 0, - y: 0 - }, - ca = b._availableAnimAttrs = { - blur: S, - "clip-rect": "csv", - cx: S, - cy: S, - fill: "colour", - "fill-opacity": S, - "font-size": S, - height: S, - opacity: S, - path: "path", - r: S, - rx: S, - ry: S, - stroke: "colour", - "stroke-opacity": S, - "stroke-width": S, - transform: "transform", - width: S, - x: S, - y: S - }, - da = /[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029]*,[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029]*/, - ea = { - hs: 1, - rg: 1 - }, - fa = /,?([achlmqrstvxz]),?/gi, - ga = /([achlmrqstvz])[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029,]*((-?\d*\.?\d*(?:e[\-+]?\d+)?[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029]*,?[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029]*)+)/gi, - ha = /([rstm])[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029,]*((-?\d*\.?\d*(?:e[\-+]?\d+)?[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029]*,?[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029]*)+)/gi, - ia = /(-?\d*\.?\d*(?:e[\-+]?\d+)?)[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029]*,?[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029]*/gi, - ja = (b._radial_gradient = /^r(?:\(([^,]+?)[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029]*,[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029]*([^\)]+?)\))?/, {}), - ka = function (a, b) { - return $(a) - $(b) - }, - la = function (a) { - return a - }, - ma = b._rectPath = function (a, b, c, d, e) { - return e ? [["M", a + e, b], ["l", c - 2 * e, 0], ["a", e, e, 0, 0, 1, e, e], ["l", 0, d - 2 * e], ["a", e, e, 0, 0, 1, -e, e], ["l", 2 * e - c, 0], ["a", e, e, 0, 0, 1, -e, -e], ["l", 0, 2 * e - d], ["a", e, e, 0, 0, 1, e, -e], ["z"]] : [["M", a, b], ["l", c, 0], ["l", 0, d], ["l", -c, 0], ["z"]] - }, - na = function (a, b, c, d) { - return null == d && (d = c), - [["M", a, b], ["m", 0, -d], ["a", c, d, 0, 1, 1, 0, 2 * d], ["a", c, d, 0, 1, 1, 0, -2 * d], ["z"]] - }, - oa = b._getPath = { - path: function (a) { - return a.attr("path") - }, - circle: function (a) { - var b = a.attrs; - return na(b.cx, b.cy, b.r) - }, - ellipse: function (a) { - var b = a.attrs; - return na(b.cx, b.cy, b.rx, b.ry) - }, - rect: function (a) { - var b = a.attrs; - return ma(b.x, b.y, b.width, b.height, b.r) - }, - image: function (a) { - var b = a.attrs; - return ma(b.x, b.y, b.width, b.height) - }, - text: function (a) { - var b = a._getBBox(); - return ma(b.x, b.y, b.width, b.height) - }, - set: function (a) { - var b = a._getBBox(); - return ma(b.x, b.y, b.width, b.height) - } - }, - pa = b.mapPath = function (a, b) { - if (!b) - return a; - var c, - d, - e, - f, - g, - h, - i; - for (a = Ia(a), e = 0, g = a.length; g > e; e++) - for (i = a[e], f = 1, h = i.length; h > f; f += 2) - c = b.x(i[f], i[f + 1]), d = b.y(i[f], i[f + 1]), i[f] = c, i[f + 1] = d; - return a - }; - if (b._g = z, b.type = z.win.SVGAngle || z.doc.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1") ? "SVG" : "VML", "VML" == b.type) { - var qa, - ra = z.doc.createElement("div"); - if (ra.innerHTML = '', qa = ra.firstChild, qa.style.behavior = "url(#default#VML)", !qa || "object" != typeof qa.adj) - return b.type = F; - ra = null - } - b.svg = !(b.vml = "VML" == b.type), - b._Paper = B, - b.fn = u = B.prototype = b.prototype, - b._id = 0, - b._oid = 0, - b.is = function (a, b) { - return b = L.call(b), - "finite" == b ? !X[y](+a) : "array" == b ? a instanceof Array : "null" == b && null === a || b == typeof a && null !== a || "object" == b && a === Object(a) || "array" == b && Array.isArray && Array.isArray(a) || V.call(a).slice(8, -1).toLowerCase() == b - }, - b.angle = function (a, c, d, e, f, g) { - if (null == f) { - var h = a - d, - i = c - e; - return h || i ? (180 + 180 * M.atan2(-i, -h) / R + 360) % 360 : 0 - } - return b.angle(a, c, f, g) - b.angle(d, e, f, g) - }, - b.rad = function (a) { - return a % 360 * R / 180 - }, - b.deg = function (a) { - return Math.round(180 * a / R % 360 * 1e3) / 1e3 - }, - b.snapTo = function (a, c, d) { - if (d = b.is(d, "finite") ? d : 10, b.is(a, U)) { - for (var e = a.length; e--; ) - if (P(a[e] - c) <= d) - return a[e] - } else { - a = +a; - var f = c % a; - if (d > f) - return c - f; - if (f > a - d) - return c - f + a - } - return c - }; - b.createUUID = function (a, b) { - return function () { - return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(a, b).toUpperCase() - } - } - (/[xy]/g, function (a) { - var b = 16 * M.random() | 0, - c = "x" == a ? b : 3 & b | 8; - return c.toString(16) - }); - b.setWindow = function (c) { - a("raphael.setWindow", b, z.win, c), - z.win = c, - z.doc = z.win.document, - b._engine.initWin && b._engine.initWin(z.win) - }; - var sa = function (a) { - if (b.vml) { - var c, - d = /^\s+|\s+$/g; - try { - var f = new ActiveXObject("htmlfile"); - f.write(""), - f.close(), - c = f.body - } catch (g) { - c = createPopup().document.body - } - var h = c.createTextRange(); - sa = e(function (a) { - try { - c.style.color = H(a).replace(d, F); - var b = h.queryCommandValue("ForeColor"); - return b = (255 & b) << 16 | 65280 & b | (16711680 & b) >>> 16, - "#" + ("000000" + b.toString(16)).slice(-6) - } catch (e) { - return "none" - } - }) - } else { - var i = z.doc.createElement("i"); - i.title = "Raphaël Colour Picker", - i.style.display = "none", - z.doc.body.appendChild(i), - sa = e(function (a) { - return i.style.color = a, - z.doc.defaultView.getComputedStyle(i, F).getPropertyValue("color") - }) - } - return sa(a) - }, - ta = function () { - return "hsb(" + [this.h, this.s, this.b] + ")" - }, - ua = function () { - return "hsl(" + [this.h, this.s, this.l] + ")" - }, - va = function () { - return this.hex - }, - wa = function (a, c, d) { - if (null == c && b.is(a, "object") && "r" in a && "g" in a && "b" in a && (d = a.b, c = a.g, a = a.r), null == c && b.is(a, T)) { - var e = b.getRGB(a); - a = e.r, - c = e.g, - d = e.b - } - return (a > 1 || c > 1 || d > 1) && (a /= 255, c /= 255, d /= 255), - [a, c, d] - }, - xa = function (a, c, d, e) { - a *= 255, - c *= 255, - d *= 255; - var f = { - r: a, - g: c, - b: d, - hex: b.rgb(a, c, d), - toString: va - }; - return b.is(e, "finite") && (f.opacity = e), - f - }; - b.color = function (a) { - var c; - return b.is(a, "object") && "h" in a && "s" in a && "b" in a ? (c = b.hsb2rgb(a), a.r = c.r, a.g = c.g, a.b = c.b, a.hex = c.hex) : b.is(a, "object") && "h" in a && "s" in a && "l" in a ? (c = b.hsl2rgb(a), a.r = c.r, a.g = c.g, a.b = c.b, a.hex = c.hex) : (b.is(a, "string") && (a = b.getRGB(a)), b.is(a, "object") && "r" in a && "g" in a && "b" in a ? (c = b.rgb2hsl(a), a.h = c.h, a.s = c.s, a.l = c.l, c = b.rgb2hsb(a), a.v = c.b) : (a = { - hex: "none" - }, a.r = a.g = a.b = a.h = a.s = a.v = a.l = -1)), - a.toString = va, - a - }, - b.hsb2rgb = function (a, b, c, d) { - this.is(a, "object") && "h" in a && "s" in a && "b" in a && (c = a.b, b = a.s, d = a.o, a = a.h), - a *= 360; - var e, - f, - g, - h, - i; - return a = a % 360 / 60, - i = c * b, - h = i * (1 - P(a % 2 - 1)), - e = f = g = c - i, - a = ~~a, - e += [i, h, 0, 0, h, i][a], - f += [h, i, i, h, 0, 0][a], - g += [0, 0, h, i, i, h][a], - xa(e, f, g, d) - }, - b.hsl2rgb = function (a, b, c, d) { - this.is(a, "object") && "h" in a && "s" in a && "l" in a && (c = a.l, b = a.s, a = a.h), - (a > 1 || b > 1 || c > 1) && (a /= 360, b /= 100, c /= 100), - a *= 360; - var e, - f, - g, - h, - i; - return a = a % 360 / 60, - i = 2 * b * (.5 > c ? c : 1 - c), - h = i * (1 - P(a % 2 - 1)), - e = f = g = c - i / 2, - a = ~~a, - e += [i, h, 0, 0, h, i][a], - f += [h, i, i, h, 0, 0][a], - g += [0, 0, h, i, i, h][a], - xa(e, f, g, d) - }, - b.rgb2hsb = function (a, b, c) { - c = wa(a, b, c), - a = c[0], - b = c[1], - c = c[2]; - var d, - e, - f, - g; - return f = N(a, b, c), - g = f - O(a, b, c), - d = 0 == g ? null : f == a ? (b - c) / g : f == b ? (c - a) / g + 2 : (a - b) / g + 4, - d = (d + 360) % 6 * 60 / 360, - e = 0 == g ? 0 : g / f, { - h: d, - s: e, - b: f, - toString: ta - } - }, - b.rgb2hsl = function (a, b, c) { - c = wa(a, b, c), - a = c[0], - b = c[1], - c = c[2]; - var d, - e, - f, - g, - h, - i; - return g = N(a, b, c), - h = O(a, b, c), - i = g - h, - d = 0 == i ? null : g == a ? (b - c) / i : g == b ? (c - a) / i + 2 : (a - b) / i + 4, - d = (d + 360) % 6 * 60 / 360, - f = (g + h) / 2, - e = 0 == i ? 0 : .5 > f ? i / (2 * f) : i / (2 - 2 * f), { - h: d, - s: e, - l: f, - toString: ua - } - }, - b._path2string = function () { - return this.join(",").replace(fa, "$1") - }; - b._preload = function (a, b) { - var c = z.doc.createElement("img"); - c.style.cssText = "position:absolute;left:-9999em;top:-9999em", - c.onload = function () { - b.call(this), - this.onload = null, - z.doc.body.removeChild(this) - }, - c.onerror = function () { - z.doc.body.removeChild(this) - }, - z.doc.body.appendChild(c), - c.src = a - }; - b.getRGB = e(function (a) { - if (!a || (a = H(a)).indexOf("-") + 1) - return { - r: -1, - g: -1, - b: -1, - hex: "none", - error: 1, - toString: f - }; - if ("none" == a) - return { - r: -1, - g: -1, - b: -1, - hex: "none", - toString: f - }; - !(ea[y](a.toLowerCase().substring(0, 2)) || "#" == a.charAt()) && (a = sa(a)); - var c, - d, - e, - g, - h, - i, - j = a.match(W); - return j ? (j[2] && (e = _(j[2].substring(5), 16), d = _(j[2].substring(3, 5), 16), c = _(j[2].substring(1, 3), 16)), j[3] && (e = _((h = j[3].charAt(3)) + h, 16), d = _((h = j[3].charAt(2)) + h, 16), c = _((h = j[3].charAt(1)) + h, 16)), j[4] && (i = j[4][I](da), c = $(i[0]), "%" == i[0].slice(-1) && (c *= 2.55), d = $(i[1]), "%" == i[1].slice(-1) && (d *= 2.55), e = $(i[2]), "%" == i[2].slice(-1) && (e *= 2.55), "rgba" == j[1].toLowerCase().slice(0, 4) && (g = $(i[3])), i[3] && "%" == i[3].slice(-1) && (g /= 100)), j[5] ? (i = j[5][I](da), c = $(i[0]), "%" == i[0].slice(-1) && (c *= 2.55), d = $(i[1]), "%" == i[1].slice(-1) && (d *= 2.55), e = $(i[2]), "%" == i[2].slice(-1) && (e *= 2.55), ("deg" == i[0].slice(-3) || "°" == i[0].slice(-1)) && (c /= 360), "hsba" == j[1].toLowerCase().slice(0, 4) && (g = $(i[3])), i[3] && "%" == i[3].slice(-1) && (g /= 100), b.hsb2rgb(c, d, e, g)) : j[6] ? (i = j[6][I](da), c = $(i[0]), "%" == i[0].slice(-1) && (c *= 2.55), d = $(i[1]), "%" == i[1].slice(-1) && (d *= 2.55), e = $(i[2]), "%" == i[2].slice(-1) && (e *= 2.55), ("deg" == i[0].slice(-3) || "°" == i[0].slice(-1)) && (c /= 360), "hsla" == j[1].toLowerCase().slice(0, 4) && (g = $(i[3])), i[3] && "%" == i[3].slice(-1) && (g /= 100), b.hsl2rgb(c, d, e, g)) : (j = { - r: c, - g: d, - b: e, - toString: f - }, j.hex = "#" + (16777216 | e | d << 8 | c << 16).toString(16).slice(1), b.is(g, "finite") && (j.opacity = g), j)) : { - r: -1, - g: -1, - b: -1, - hex: "none", - error: 1, - toString: f - } - }, b), - b.hsb = e(function (a, c, d) { - return b.hsb2rgb(a, c, d).hex - }), - b.hsl = e(function (a, c, d) { - return b.hsl2rgb(a, c, d).hex - }), - b.rgb = e(function (a, b, c) { - function d(a) { - return a + .5 | 0 - } - return "#" + (16777216 | d(c) | d(b) << 8 | d(a) << 16).toString(16).slice(1) - }), - b.getColor = function (a) { - var b = this.getColor.start = this.getColor.start || { - h: 0, - s: 1, - b: a || .75 - }, - c = this.hsb2rgb(b.h, b.s, b.b); - return b.h += .075, - b.h > 1 && (b.h = 0, b.s -= .2, b.s <= 0 && (this.getColor.start = { - h: 0, - s: 1, - b: b.b - })), - c.hex - }, - b.getColor.reset = function () { - delete this.start - }, - b.parsePathString = function (a) { - if (!a) - return null; - var c = ya(a); - if (c.arr) - return Aa(c.arr); - var d = { - a: 7, - c: 6, - h: 1, - l: 2, - m: 2, - r: 4, - q: 4, - s: 4, - t: 2, - v: 1, - z: 0 - }, - e = []; - return b.is(a, U) && b.is(a[0], U) && (e = Aa(a)), - e.length || H(a).replace(ga, function (a, b, c) { - var f = [], - g = b.toLowerCase(); - if (c.replace(ia, function (a, b) { - b && f.push(+b) - }), "m" == g && f.length > 2 && (e.push([b][D](f.splice(0, 2))), g = "l", b = "m" == b ? "l" : "L"), "r" == g) - e.push([b][D](f)); - else - for (; f.length >= d[g] && (e.push([b][D](f.splice(0, d[g]))), d[g]); ); - }), - e.toString = b._path2string, - c.arr = Aa(e), - e - }, - b.parseTransformString = e(function (a) { - if (!a) - return null; - var c = []; - return b.is(a, U) && b.is(a[0], U) && (c = Aa(a)), - c.length || H(a).replace(ha, function (a, b, d) { { - var e = []; - L.call(b) - } - d.replace(ia, function (a, b) { - b && e.push(+b) - }), - c.push([b][D](e)) - }), - c.toString = b._path2string, - c - }); - var ya = function (a) { - var b = ya.ps = ya.ps || {}; - return b[a] ? b[a].sleep = 100 : b[a] = { - sleep: 100 - }, - setTimeout(function () { - for (var c in b) - b[y](c) && c != a && (b[c].sleep--, !b[c].sleep && delete b[c]) - }), - b[a] - }; - b.findDotsAtSegment = function (a, b, c, d, e, f, g, h, i) { - var j = 1 - i, - k = Q(j, 3), - l = Q(j, 2), - m = i * i, - n = m * i, - o = k * a + 3 * l * i * c + 3 * j * i * i * e + n * g, - p = k * b + 3 * l * i * d + 3 * j * i * i * f + n * h, - q = a + 2 * i * (c - a) + m * (e - 2 * c + a), - r = b + 2 * i * (d - b) + m * (f - 2 * d + b), - s = c + 2 * i * (e - c) + m * (g - 2 * e + c), - t = d + 2 * i * (f - d) + m * (h - 2 * f + d), - u = j * a + i * c, - v = j * b + i * d, - w = j * e + i * g, - x = j * f + i * h, - y = 90 - 180 * M.atan2(q - s, r - t) / R; - return (q > s || t > r) && (y += 180), { - x: o, - y: p, - m: { - x: q, - y: r - }, - n: { - x: s, - y: t - }, - start: { - x: u, - y: v - }, - end: { - x: w, - y: x - }, - alpha: y - } - }, - b.bezierBBox = function (a, c, d, e, f, g, h, i) { - b.is(a, "array") || (a = [a, c, d, e, f, g, h, i]); - var j = Ha.apply(null, a); - return { - x: j.min.x, - y: j.min.y, - x2: j.max.x, - y2: j.max.y, - width: j.max.x - j.min.x, - height: j.max.y - j.min.y - } - }, - b.isPointInsideBBox = function (a, b, c) { - return b >= a.x && b <= a.x2 && c >= a.y && c <= a.y2 - }, - b.isBBoxIntersect = function (a, c) { - var d = b.isPointInsideBBox; - return d(c, a.x, a.y) || d(c, a.x2, a.y) || d(c, a.x, a.y2) || d(c, a.x2, a.y2) || d(a, c.x, c.y) || d(a, c.x2, c.y) || d(a, c.x, c.y2) || d(a, c.x2, c.y2) || (a.x < c.x2 && a.x > c.x || c.x < a.x2 && c.x > a.x) && (a.y < c.y2 && a.y > c.y || c.y < a.y2 && c.y > a.y) - }, - b.pathIntersection = function (a, b) { - return m(a, b) - }, - b.pathIntersectionNumber = function (a, b) { - return m(a, b, 1) - }, - b.isPointInsidePath = function (a, c, d) { - var e = b.pathBBox(a); - return b.isPointInsideBBox(e, c, d) && m(a, [["M", c, d], ["H", e.x2 + 10]], 1) % 2 == 1 - }, - b._removedFactory = function (b) { - return function () { - a("raphael.log", null, "Raphaël: you are calling to method “" + b + "” of removed object", b) - } - }; - var za = b.pathBBox = function (a) { - var b = ya(a); - if (b.bbox) - return c(b.bbox); - if (!a) - return { - x: 0, - y: 0, - width: 0, - height: 0, - x2: 0, - y2: 0 - }; - a = Ia(a); - for (var d, e = 0, f = 0, g = [], h = [], i = 0, j = a.length; j > i; i++) - if (d = a[i], "M" == d[0]) - e = d[1], f = d[2], g.push(e), h.push(f); - else { - var k = Ha(e, f, d[1], d[2], d[3], d[4], d[5], d[6]); - g = g[D](k.min.x, k.max.x), - h = h[D](k.min.y, k.max.y), - e = d[5], - f = d[6] - } - var l = O[C](0, g), - m = O[C](0, h), - n = N[C](0, g), - o = N[C](0, h), - p = n - l, - q = o - m, - r = { - x: l, - y: m, - x2: n, - y2: o, - width: p, - height: q, - cx: l + p / 2, - cy: m + q / 2 - }; - return b.bbox = c(r), - r - }, - Aa = function (a) { - var d = c(a); - return d.toString = b._path2string, - d - }, - Ba = b._pathToRelative = function (a) { - var c = ya(a); - if (c.rel) - return Aa(c.rel); - b.is(a, U) && b.is(a && a[0], U) || (a = b.parsePathString(a)); - var d = [], - e = 0, - f = 0, - g = 0, - h = 0, - i = 0; - "M" == a[0][0] && (e = a[0][1], f = a[0][2], g = e, h = f, i++, d.push(["M", e, f])); - for (var j = i, k = a.length; k > j; j++) { - var l = d[j] = [], - m = a[j]; - if (m[0] != L.call(m[0])) - switch (l[0] = L.call(m[0]), l[0]) { - case "a": - l[1] = m[1], - l[2] = m[2], - l[3] = m[3], - l[4] = m[4], - l[5] = m[5], - l[6] = + (m[6] - e).toFixed(3), - l[7] = + (m[7] - f).toFixed(3); - break; - case "v": - l[1] = + (m[1] - f).toFixed(3); - break; - case "m": - g = m[1], - h = m[2]; - default: - for (var n = 1, o = m.length; o > n; n++) - l[n] = + (m[n] - (n % 2 ? e : f)).toFixed(3) - } - else { - l = d[j] = [], - "m" == m[0] && (g = m[1] + e, h = m[2] + f); - for (var p = 0, q = m.length; q > p; p++) - d[j][p] = m[p] - } - var r = d[j].length; - switch (d[j][0]) { - case "z": - e = g, - f = h; - break; - case "h": - e += +d[j][r - 1]; - break; - case "v": - f += +d[j][r - 1]; - break; - default: - e += +d[j][r - 2], - f += +d[j][r - 1] - } - } - return d.toString = b._path2string, - c.rel = Aa(d), - d - }, - Ca = b._pathToAbsolute = function (a) { - var c = ya(a); - if (c.abs) - return Aa(c.abs); - if (b.is(a, U) && b.is(a && a[0], U) || (a = b.parsePathString(a)), !a || !a.length) - return [["M", 0, 0]]; - var d = [], - e = 0, - f = 0, - h = 0, - i = 0, - j = 0; - "M" == a[0][0] && (e = +a[0][1], f = +a[0][2], h = e, i = f, j++, d[0] = ["M", e, f]); - for (var k, l, m = 3 == a.length && "M" == a[0][0] && "R" == a[1][0].toUpperCase() && "Z" == a[2][0].toUpperCase(), n = j, o = a.length; o > n; n++) { - if (d.push(k = []), l = a[n], l[0] != aa.call(l[0])) - switch (k[0] = aa.call(l[0]), k[0]) { - case "A": - k[1] = l[1], - k[2] = l[2], - k[3] = l[3], - k[4] = l[4], - k[5] = l[5], - k[6] = + (l[6] + e), - k[7] = + (l[7] + f); - break; - case "V": - k[1] = +l[1] + f; - break; - case "H": - k[1] = +l[1] + e; - break; - case "R": - for (var p = [e, f][D](l.slice(1)), q = 2, r = p.length; r > q; q++) - p[q] = +p[q] + e, p[++q] = +p[q] + f; - d.pop(), - d = d[D](g(p, m)); - break; - case "M": - h = +l[1] + e, - i = +l[2] + f; - default: - for (q = 1, r = l.length; r > q; q++) - k[q] = +l[q] + (q % 2 ? e : f) - } - else if ("R" == l[0]) - p = [e, f][D](l.slice(1)), d.pop(), d = d[D](g(p, m)), k = ["R"][D](l.slice(-2)); - else - for (var s = 0, t = l.length; t > s; s++) - k[s] = l[s]; - switch (k[0]) { - case "Z": - e = h, - f = i; - break; - case "H": - e = k[1]; - break; - case "V": - f = k[1]; - break; - case "M": - h = k[k.length - 2], - i = k[k.length - 1]; - default: - e = k[k.length - 2], - f = k[k.length - 1] - } - } - return d.toString = b._path2string, - c.abs = Aa(d), - d - }, - Da = function (a, b, c, d) { - return [a, b, c, d, c, d] - }, - Ea = function (a, b, c, d, e, f) { - var g = 1 / 3, - h = 2 / 3; - return [g * a + h * c, g * b + h * d, g * e + h * c, g * f + h * d, e, f] - }, - Fa = function (a, b, c, d, f, g, h, i, j, k) { - var l, - m = 120 * R / 180, - n = R / 180 * (+f || 0), - o = [], - p = e(function (a, b, c) { - var d = a * M.cos(c) - b * M.sin(c), - e = a * M.sin(c) + b * M.cos(c); - return { - x: d, - y: e - } - }); - if (k) - y = k[0], z = k[1], w = k[2], x = k[3]; - else { - l = p(a, b, -n), - a = l.x, - b = l.y, - l = p(i, j, -n), - i = l.x, - j = l.y; - var q = (M.cos(R / 180 * f), M.sin(R / 180 * f), (a - i) / 2), - r = (b - j) / 2, - s = q * q / (c * c) + r * r / (d * d); - s > 1 && (s = M.sqrt(s), c = s * c, d = s * d); - var t = c * c, - u = d * d, - v = (g == h ? -1 : 1) * M.sqrt(P((t * u - t * r * r - u * q * q) / (t * r * r + u * q * q))), - w = v * c * r / d + (a + i) / 2, - x = v * -d * q / c + (b + j) / 2, - y = M.asin(((b - x) / d).toFixed(9)), - z = M.asin(((j - x) / d).toFixed(9)); - y = w > a ? R - y : y, - z = w > i ? R - z : z, - 0 > y && (y = 2 * R + y), - 0 > z && (z = 2 * R + z), - h && y > z && (y -= 2 * R), - !h && z > y && (z -= 2 * R) - } - var A = z - y; - if (P(A) > m) { - var B = z, - C = i, - E = j; - z = y + m * (h && z > y ? 1 : -1), - i = w + c * M.cos(z), - j = x + d * M.sin(z), - o = Fa(i, j, c, d, f, 0, h, C, E, [z, B, w, x]) - } - A = z - y; - var F = M.cos(y), - G = M.sin(y), - H = M.cos(z), - J = M.sin(z), - K = M.tan(A / 4), - L = 4 / 3 * c * K, - N = 4 / 3 * d * K, - O = [a, b], - Q = [a + L * G, b - N * F], - S = [i + L * J, j - N * H], - T = [i, j]; - if (Q[0] = 2 * O[0] - Q[0], Q[1] = 2 * O[1] - Q[1], k) - return [Q, S, T][D](o); - o = [Q, S, T][D](o).join()[I](","); - for (var U = [], V = 0, W = o.length; W > V; V++) - U[V] = V % 2 ? p(o[V - 1], o[V], n).y : p(o[V], o[V + 1], n).x; - return U - }, - Ga = function (a, b, c, d, e, f, g, h, i) { - var j = 1 - i; - return { - x: Q(j, 3) * a + 3 * Q(j, 2) * i * c + 3 * j * i * i * e + Q(i, 3) * g, - y: Q(j, 3) * b + 3 * Q(j, 2) * i * d + 3 * j * i * i * f + Q(i, 3) * h - } - }, - Ha = e(function (a, b, c, d, e, f, g, h) { - var i, - j = e - 2 * c + a - (g - 2 * e + c), - k = 2 * (c - a) - 2 * (e - c), - l = a - c, - m = (-k + M.sqrt(k * k - 4 * j * l)) / 2 / j, - n = (-k - M.sqrt(k * k - 4 * j * l)) / 2 / j, - o = [b, h], - p = [a, g]; - return P(m) > "1e12" && (m = .5), - P(n) > "1e12" && (n = .5), - m > 0 && 1 > m && (i = Ga(a, b, c, d, e, f, g, h, m), p.push(i.x), o.push(i.y)), - n > 0 && 1 > n && (i = Ga(a, b, c, d, e, f, g, h, n), p.push(i.x), o.push(i.y)), - j = f - 2 * d + b - (h - 2 * f + d), - k = 2 * (d - b) - 2 * (f - d), - l = b - d, - m = (-k + M.sqrt(k * k - 4 * j * l)) / 2 / j, - n = (-k - M.sqrt(k * k - 4 * j * l)) / 2 / j, - P(m) > "1e12" && (m = .5), - P(n) > "1e12" && (n = .5), - m > 0 && 1 > m && (i = Ga(a, b, c, d, e, f, g, h, m), p.push(i.x), o.push(i.y)), - n > 0 && 1 > n && (i = Ga(a, b, c, d, e, f, g, h, n), p.push(i.x), o.push(i.y)), { - min: { - x: O[C](0, p), - y: O[C](0, o) - }, - max: { - x: N[C](0, p), - y: N[C](0, o) - } - } - }), - Ia = b._path2curve = e(function (a, b) { - var c = !b && ya(a); - if (!b && c.curve) - return Aa(c.curve); - for (var d = Ca(a), e = b && Ca(b), f = { - x: 0, - y: 0, - bx: 0, - by: 0, - X: 0, - Y: 0, - qx: null, - qy: null - }, g = { - x: 0, - y: 0, - bx: 0, - by: 0, - X: 0, - Y: 0, - qx: null, - qy: null - }, h = (function (a, b, c) { - var d, - e, - f = { - T: 1, - Q: 1 - }; - if (!a) - return ["C", b.x, b.y, b.x, b.y, b.x, b.y]; - switch (!(a[0]in f) && (b.qx = b.qy = null), a[0]) { - case "M": - b.X = a[1], - b.Y = a[2]; - break; - case "A": - a = ["C"][D](Fa[C](0, [b.x, b.y][D](a.slice(1)))); - break; - case "S": - "C" == c || "S" == c ? (d = 2 * b.x - b.bx, e = 2 * b.y - b.by) : (d = b.x, e = b.y), - a = ["C", d, e][D](a.slice(1)); - break; - case "T": - "Q" == c || "T" == c ? (b.qx = 2 * b.x - b.qx, b.qy = 2 * b.y - b.qy) : (b.qx = b.x, b.qy = b.y), - a = ["C"][D](Ea(b.x, b.y, b.qx, b.qy, a[1], a[2])); - break; - case "Q": - b.qx = a[1], - b.qy = a[2], - a = ["C"][D](Ea(b.x, b.y, a[1], a[2], a[3], a[4])); - break; - case "L": - a = ["C"][D](Da(b.x, b.y, a[1], a[2])); - break; - case "H": - a = ["C"][D](Da(b.x, b.y, a[1], b.y)); - break; - case "V": - a = ["C"][D](Da(b.x, b.y, b.x, a[1])); - break; - case "Z": - a = ["C"][D](Da(b.x, b.y, b.X, b.Y)) - } - return a - }), i = function (a, b) { - if (a[b].length > 7) { - a[b].shift(); - for (var c = a[b]; c.length; ) - k[b] = "A", e && (l[b] = "A") , a.splice(b++, 0, ["C"][D](c.splice(0, 6))); - a.splice(b, 1), - p = N(d.length, e && e.length || 0) - } - }, j = function (a, b, c, f, g) { - a && b && "M" == a[g][0] && "M" != b[g][0] && (b.splice(g, 0, ["M", f.x, f.y]), c.bx = 0, c.by = 0, c.x = a[g][1], c.y = a[g][2], p = N(d.length, e && e.length || 0)) - }, k = [], l = [], m = "", n = "", o = 0, p = N(d.length, e && e.length || 0); p > o; o++) { - d[o] && (m = d[o][0]), - "C" != m && (k[o] = m, o && (n = k[o - 1])), - d[o] = h(d[o], f, n), - "A" != k[o] && "C" == m && (k[o] = "C"), - i(d, o), - e && (e[o] && (m = e[o][0]), "C" != m && (l[o] = m, o && (n = l[o - 1])), e[o] = h(e[o], g, n), "A" != l[o] && "C" == m && (l[o] = "C"), i(e, o)), - j(d, e, f, g, o), - j(e, d, g, f, o); - var q = d[o], - r = e && e[o], - s = q.length, - t = e && r.length; - f.x = q[s - 2], - f.y = q[s - 1], - f.bx = $(q[s - 4]) || f.x, - f.by = $(q[s - 3]) || f.y, - g.bx = e && ($(r[t - 4]) || g.x), - g.by = e && ($(r[t - 3]) || g.y), - g.x = e && r[t - 2], - g.y = e && r[t - 1] - } - return e || (c.curve = Aa(d)), - e ? [d, e] : d - }, null, Aa), - Ja = (b._parseDots = e(function (a) { - for (var c = [], d = 0, e = a.length; e > d; d++) { - var f = {}, - g = a[d].match(/^([^:]*):?([\d\.]*)/); - if (f.color = b.getRGB(g[1]), f.color.error) - return null; - f.opacity = f.color.opacity, - f.color = f.color.hex, - g[2] && (f.offset = g[2] + "%"), - c.push(f) - } - for (d = 1, e = c.length - 1; e > d; d++) - if (!c[d].offset) { - for (var h = $(c[d - 1].offset || 0), i = 0, j = d + 1; e > j; j++) - if (c[j].offset) { - i = c[j].offset; - break - } - i || (i = 100, j = e), - i = $(i); - for (var k = (i - h) / (j - d + 1); j > d; d++) - h += k, c[d].offset = h + "%" - } - return c - }), b._tear = function (a, b) { - a == b.top && (b.top = a.prev), - a == b.bottom && (b.bottom = a.next), - a.next && (a.next.prev = a.prev), - a.prev && (a.prev.next = a.next) - }), - Ka = (b._tofront = function (a, b) { - b.top !== a && (Ja(a, b), a.next = null, a.prev = b.top, b.top.next = a, b.top = a) - }, b._toback = function (a, b) { - b.bottom !== a && (Ja(a, b), a.next = b.bottom, a.prev = null, b.bottom.prev = a, b.bottom = a) - }, b._insertafter = function (a, b, c) { - Ja(a, c), - b == c.top && (c.top = a), - b.next && (b.next.prev = a), - a.next = b.next, - a.prev = b, - b.next = a - }, b._insertbefore = function (a, b, c) { - Ja(a, c), - b == c.bottom && (c.bottom = a), - b.prev && (b.prev.next = a), - a.prev = b.prev, - b.prev = a, - a.next = b - }, b.toMatrix = function (a, b) { - var c = za(a), - d = { - _: { - transform: F - }, - getBBox: function () { - return c - } - }; - return La(d, b), - d.matrix - }), - La = (b.transformPath = function (a, b) { - return pa(a, Ka(a, b)) - }, b._extractTransform = function (a, c) { - if (null == c) - return a._.transform; - c = H(c).replace(/\.{3}|\u2026/g, a._.transform || F); - var d = b.parseTransformString(c), - e = 0, - f = 0, - g = 0, - h = 1, - i = 1, - j = a._, - k = new n; - if (j.transform = d || [], d) - for (var l = 0, m = d.length; m > l; l++) { - var o, - p, - q, - r, - s, - t = d[l], - u = t.length, - v = H(t[0]).toLowerCase(), - w = t[0] != v, - x = w ? k.invert() : 0; - "t" == v && 3 == u ? w ? (o = x.x(0, 0), p = x.y(0, 0), q = x.x(t[1], t[2]), r = x.y(t[1], t[2]), k.translate(q - o, r - p)) : k.translate(t[1], t[2]) : "r" == v ? 2 == u ? (s = s || a.getBBox(1), k.rotate(t[1], s.x + s.width / 2, s.y + s.height / 2), e += t[1]) : 4 == u && (w ? (q = x.x(t[2], t[3]), r = x.y(t[2], t[3]), k.rotate(t[1], q, r)) : k.rotate(t[1], t[2], t[3]), e += t[1]) : "s" == v ? 2 == u || 3 == u ? (s = s || a.getBBox(1), k.scale(t[1], t[u - 1], s.x + s.width / 2, s.y + s.height / 2), h *= t[1], i *= t[u - 1]) : 5 == u && (w ? (q = x.x(t[3], t[4]), r = x.y(t[3], t[4]), k.scale(t[1], t[2], q, r)) : k.scale(t[1], t[2], t[3], t[4]), h *= t[1], i *= t[2]) : "m" == v && 7 == u && k.add(t[1], t[2], t[3], t[4], t[5], t[6]), - j.dirtyT = 1, - a.matrix = k - } - a.matrix = k, - j.sx = h, - j.sy = i, - j.deg = e, - j.dx = f = k.e, - j.dy = g = k.f, - 1 == h && 1 == i && !e && j.bbox ? (j.bbox.x += +f, j.bbox.y += +g) : j.dirtyT = 1 - }), - Ma = function (a) { - var b = a[0]; - switch (b.toLowerCase()) { - case "t": - return [b, 0, 0]; - case "m": - return [b, 1, 0, 0, 1, 0, 0]; - case "r": - return 4 == a.length ? [b, 0, a[2], a[3]] : [b, 0]; - case "s": - return 5 == a.length ? [b, 1, 1, a[3], a[4]] : 3 == a.length ? [b, 1, 1] : [b, 1] - } - }, - Na = b._equaliseTransform = function (a, c) { - c = H(c).replace(/\.{3}|\u2026/g, a), - a = b.parseTransformString(a) || [], - c = b.parseTransformString(c) || []; - for (var d, e, f, g, h = N(a.length, c.length), i = [], j = [], k = 0; h > k; k++) { - if (f = a[k] || Ma(c[k]), g = c[k] || Ma(f), f[0] != g[0] || "r" == f[0].toLowerCase() && (f[2] != g[2] || f[3] != g[3]) || "s" == f[0].toLowerCase() && (f[3] != g[3] || f[4] != g[4])) - return; - for (i[k] = [], j[k] = [], d = 0, e = N(f.length, g.length); e > d; d++) - d in f && (i[k][d] = f[d]), d in g && (j[k][d] = g[d]) - } - return { - from: i, - to: j - } - }; - b._getContainer = function (a, c, d, e) { - var f; - return f = null != e || b.is(a, "object") ? a : z.doc.getElementById(a), - null != f ? f.tagName ? null == c ? { - container: f, - width: f.style.pixelWidth || f.offsetWidth, - height: f.style.pixelHeight || f.offsetHeight - } - : { - container: f, - width: c, - height: d - } - : { - container: 1, - x: a, - y: c, - width: d, - height: e - } - : void 0 - }, - b.pathToRelative = Ba, - b._engine = {}, - b.path2curve = Ia, - b.matrix = function (a, b, c, d, e, f) { - return new n(a, b, c, d, e, f) - }, - function (a) { - function c(a) { - return a[0] * a[0] + a[1] * a[1] - } - function d(a) { - var b = M.sqrt(c(a)); - a[0] && (a[0] /= b), - a[1] && (a[1] /= b) - } - a.add = function (a, b, c, d, e, f) { - var g, - h, - i, - j, - k = [[], [], []], - l = [[this.a, this.c, this.e], [this.b, this.d, this.f], [0, 0, 1]], - m = [[a, c, e], [b, d, f], [0, 0, 1]]; - for (a && a instanceof n && (m = [[a.a, a.c, a.e], [a.b, a.d, a.f], [0, 0, 1]]), g = 0; 3 > g; g++) - for (h = 0; 3 > h; h++) { - for (j = 0, i = 0; 3 > i; i++) - j += l[g][i] * m[i][h]; - k[g][h] = j - } - this.a = k[0][0], - this.b = k[1][0], - this.c = k[0][1], - this.d = k[1][1], - this.e = k[0][2], - this.f = k[1][2] - }, - a.invert = function () { - var a = this, - b = a.a * a.d - a.b * a.c; - return new n(a.d / b, -a.b / b, -a.c / b, a.a / b, (a.c * a.f - a.d * a.e) / b, (a.b * a.e - a.a * a.f) / b) - }, - a.clone = function () { - return new n(this.a, this.b, this.c, this.d, this.e, this.f) - }, - a.translate = function (a, b) { - this.add(1, 0, 0, 1, a, b) - }, - a.scale = function (a, b, c, d) { - null == b && (b = a), - (c || d) && this.add(1, 0, 0, 1, c, d), - this.add(a, 0, 0, b, 0, 0), - (c || d) && this.add(1, 0, 0, 1, -c, -d) - }, - a.rotate = function (a, c, d) { - a = b.rad(a), - c = c || 0, - d = d || 0; - var e = +M.cos(a).toFixed(9), - f = +M.sin(a).toFixed(9); - this.add(e, f, -f, e, c, d), - this.add(1, 0, 0, 1, -c, -d) - }, - a.x = function (a, b) { - return a * this.a + b * this.c + this.e - }, - a.y = function (a, b) { - return a * this.b + b * this.d + this.f - }, - a.get = function (a) { - return +this[H.fromCharCode(97 + a)].toFixed(4) - }, - a.toString = function () { - return b.svg ? "matrix(" + [this.get(0), this.get(1), this.get(2), this.get(3), this.get(4), this.get(5)].join() + ")" : [this.get(0), this.get(2), this.get(1), this.get(3), 0, 0].join() - }, - a.toFilter = function () { - return "progid:DXImageTransform.Microsoft.Matrix(M11=" + this.get(0) + ", M12=" + this.get(2) + ", M21=" + this.get(1) + ", M22=" + this.get(3) + ", Dx=" + this.get(4) + ", Dy=" + this.get(5) + ", sizingmethod='auto expand')" - }, - a.offset = function () { - return [this.e.toFixed(4), this.f.toFixed(4)] - }, - a.split = function () { - var a = {}; - a.dx = this.e, - a.dy = this.f; - var e = [[this.a, this.c], [this.b, this.d]]; - a.scalex = M.sqrt(c(e[0])), - d(e[0]), - a.shear = e[0][0] * e[1][0] + e[0][1] * e[1][1], - e[1] = [e[1][0] - e[0][0] * a.shear, e[1][1] - e[0][1] * a.shear], - a.scaley = M.sqrt(c(e[1])), - d(e[1]), - a.shear /= a.scaley; - var f = -e[0][1], - g = e[1][1]; - return 0 > g ? (a.rotate = b.deg(M.acos(g)), 0 > f && (a.rotate = 360 - a.rotate)) : a.rotate = b.deg(M.asin(f)), - a.isSimple = !(+a.shear.toFixed(9) || a.scalex.toFixed(9) != a.scaley.toFixed(9) && a.rotate), - a.isSuperSimple = !+a.shear.toFixed(9) && a.scalex.toFixed(9) == a.scaley.toFixed(9) && !a.rotate, - a.noRotation = !+a.shear.toFixed(9) && !a.rotate, - a - }, - a.toTransformString = function (a) { - var b = a || this[I](); - return b.isSimple ? (b.scalex = +b.scalex.toFixed(4), b.scaley = +b.scaley.toFixed(4), b.rotate = +b.rotate.toFixed(4), (b.dx || b.dy ? "t" + [b.dx, b.dy] : F) + (1 != b.scalex || 1 != b.scaley ? "s" + [b.scalex, b.scaley, 0, 0] : F) + (b.rotate ? "r" + [b.rotate, 0, 0] : F)) : "m" + [this.get(0), this.get(1), this.get(2), this.get(3), this.get(4), this.get(5)] - } - } - (n.prototype); - for (var Oa = function () { - this.returnValue = !1 - }, Pa = function () { - return this.originalEvent.preventDefault() - }, Qa = function () { - this.cancelBubble = !0 - }, Ra = function () { - return this.originalEvent.stopPropagation() - }, Sa = function (a) { - var b = z.doc.documentElement.scrollTop || z.doc.body.scrollTop, - c = z.doc.documentElement.scrollLeft || z.doc.body.scrollLeft; - return { - x: a.clientX + c, - y: a.clientY + b - } - }, Ta = function () { - return z.doc.addEventListener ? function (a, b, c, d) { - var e = function (a) { - var b = Sa(a); - return c.call(d, a, b.x, b.y) - }; - if (a.addEventListener(b, e, !1), E && K[b]) { - var f = function (b) { - for (var e = Sa(b), f = b, g = 0, h = b.targetTouches && b.targetTouches.length; h > g; g++) - if (b.targetTouches[g].target == a) { - b = b.targetTouches[g], - b.originalEvent = f, - b.preventDefault = Pa, - b.stopPropagation = Ra; - break - } - return c.call(d, b, e.x, e.y) - }; - a.addEventListener(K[b], f, !1) - } - return function () { - return a.removeEventListener(b, e, !1), - E && K[b] && a.removeEventListener(K[b], f, !1), - !0 - } - } - : z.doc.attachEvent ? function (a, b, c, d) { - var e = function (a) { - a = a || z.win.event; - var b = z.doc.documentElement.scrollTop || z.doc.body.scrollTop, - e = z.doc.documentElement.scrollLeft || z.doc.body.scrollLeft, - f = a.clientX + e, - g = a.clientY + b; - return a.preventDefault = a.preventDefault || Oa, - a.stopPropagation = a.stopPropagation || Qa, - c.call(d, a, f, g) - }; - a.attachEvent("on" + b, e); - var f = function () { - return a.detachEvent("on" + b, e), - !0 - }; - return f - } - : void 0 - } - (), Ua = [], Va = function (b) { - for (var c, d = b.clientX, e = b.clientY, f = z.doc.documentElement.scrollTop || z.doc.body.scrollTop, g = z.doc.documentElement.scrollLeft || z.doc.body.scrollLeft, h = Ua.length; h--; ) { - if (c = Ua[h], E && b.touches) { - for (var i, j = b.touches.length; j--; ) - if (i = b.touches[j], i.identifier == c.el._drag.id) { - d = i.clientX, - e = i.clientY, - (b.originalEvent ? b.originalEvent : b).preventDefault(); - break - } - } else - b.preventDefault(); - var k, - l = c.el.node, - m = l.nextSibling, - n = l.parentNode, - o = l.style.display; - z.win.opera && n.removeChild(l), - l.style.display = "none", - k = c.el.paper.getElementByPoint(d, e), - l.style.display = o, - z.win.opera && (m ? n.insertBefore(l, m) : n.appendChild(l)), - k && a("raphael.drag.over." + c.el.id, c.el, k), - d += g, - e += f, - a("raphael.drag.move." + c.el.id, c.move_scope || c.el, d - c.el._drag.x, e - c.el._drag.y, d, e, b) - } - }, Wa = function (c) { - b.unmousemove(Va).unmouseup(Wa); - for (var d, e = Ua.length; e--; ) - d = Ua[e], d.el._drag = {}, - a("raphael.drag.end." + d.el.id, d.end_scope || d.start_scope || d.move_scope || d.el, c); - Ua = [] - }, Xa = b.el = {}, Ya = J.length; Ya--; ) - !function (a) { - b[a] = Xa[a] = function (c, d) { - return b.is(c, "function") && (this.events = this.events || [], this.events.push({ - name: a, - f: c, - unbind: Ta(this.shape || this.node || z.doc, a, c, d || this) - })), - this - }, - b["un" + a] = Xa["un" + a] = function (c) { - for (var d = this.events || [], e = d.length; e--; ) - d[e].name != a || !b.is(c, "undefined") && d[e].f != c || (d[e].unbind(), d.splice(e, 1), !d.length && delete this.events); - return this - } - } - (J[Ya]); - Xa.data = function (c, d) { - var e = ja[this.id] = ja[this.id] || {}; - if (0 == arguments.length) - return e; - if (1 == arguments.length) { - if (b.is(c, "object")) { - for (var f in c) - c[y](f) && this.data(f, c[f]); - return this - } - return a("raphael.data.get." + this.id, this, e[c], c), - e[c] - } - return e[c] = d, - a("raphael.data.set." + this.id, this, d, c), - this - }, - Xa.removeData = function (a) { - return null == a ? ja[this.id] = {} - : ja[this.id] && delete ja[this.id][a], - this - }, - Xa.getData = function () { - return c(ja[this.id] || {}) - }, - Xa.hover = function (a, b, c, d) { - return this.mouseover(a, c).mouseout(b, d || c) - }, - Xa.unhover = function (a, b) { - return this.unmouseover(a).unmouseout(b) - }; - var Za = []; - Xa.drag = function (c, d, e, f, g, h) { - function i(i) { - (i.originalEvent || i).preventDefault(); - var j = i.clientX, - k = i.clientY, - l = z.doc.documentElement.scrollTop || z.doc.body.scrollTop, - m = z.doc.documentElement.scrollLeft || z.doc.body.scrollLeft; - if (this._drag.id = i.identifier, E && i.touches) - for (var n, o = i.touches.length; o--; ) - if (n = i.touches[o], this._drag.id = n.identifier, n.identifier == this._drag.id) { - j = n.clientX, - k = n.clientY; - break - } - this._drag.x = j + m, - this._drag.y = k + l, - !Ua.length && b.mousemove(Va).mouseup(Wa), - Ua.push({ - el: this, - move_scope: f, - start_scope: g, - end_scope: h - }), - d && a.on("raphael.drag.start." + this.id, d), - c && a.on("raphael.drag.move." + this.id, c), - e && a.on("raphael.drag.end." + this.id, e), - a("raphael.drag.start." + this.id, g || f || this, i.clientX + m, i.clientY + l, i) - } - return this._drag = {}, - Za.push({ - el: this, - start: i - }), - this.mousedown(i), - this - }, - Xa.onDragOver = function (b) { - b ? a.on("raphael.drag.over." + this.id, b) : a.unbind("raphael.drag.over." + this.id) - }, - Xa.undrag = function () { - for (var c = Za.length; c--; ) - Za[c].el == this && (this.unmousedown(Za[c].start), Za.splice(c, 1), a.unbind("raphael.drag.*." + this.id)); - !Za.length && b.unmousemove(Va).unmouseup(Wa), - Ua = [] - }, - u.circle = function (a, c, d) { - var e = b._engine.circle(this, a || 0, c || 0, d || 0); - return this.__set__ && this.__set__.push(e), - e - }, - u.rect = function (a, c, d, e, f) { - var g = b._engine.rect(this, a || 0, c || 0, d || 0, e || 0, f || 0); - return this.__set__ && this.__set__.push(g), - g - }, - u.ellipse = function (a, c, d, e) { - var f = b._engine.ellipse(this, a || 0, c || 0, d || 0, e || 0); - return this.__set__ && this.__set__.push(f), - f - }, - u.path = function (a) { - a && !b.is(a, T) && !b.is(a[0], U) && (a += F); - var c = b._engine.path(b.format[C](b, arguments), this); - return this.__set__ && this.__set__.push(c), - c - }, - u.image = function (a, c, d, e, f) { - var g = b._engine.image(this, a || "about:blank", c || 0, d || 0, e || 0, f || 0); - return this.__set__ && this.__set__.push(g), - g - }, - u.text = function (a, c, d) { - var e = b._engine.text(this, a || 0, c || 0, H(d)); - return this.__set__ && this.__set__.push(e), - e - }, - u.set = function (a) { - !b.is(a, "array") && (a = Array.prototype.splice.call(arguments, 0, arguments.length)); - var c = new jb(a); - return this.__set__ && this.__set__.push(c), - c.paper = this, - c.type = "set", - c - }, - u.setStart = function (a) { - this.__set__ = a || this.set() - }, - u.setFinish = function (a) { - var b = this.__set__; - return delete this.__set__, - b - }, - u.getSize = function () { - var a = this.canvas.parentNode; - return { - width: a.offsetWidth, - height: a.offsetHeight - } - }, - u.setSize = function (a, c) { - return b._engine.setSize.call(this, a, c) - }, - u.setViewBox = function (a, c, d, e, f) { - return b._engine.setViewBox.call(this, a, c, d, e, f) - }, - u.top = u.bottom = null, - u.raphael = b; - var $a = function (a) { - var b = a.getBoundingClientRect(), - c = a.ownerDocument, - d = c.body, - e = c.documentElement, - f = e.clientTop || d.clientTop || 0, - g = e.clientLeft || d.clientLeft || 0, - h = b.top + (z.win.pageYOffset || e.scrollTop || d.scrollTop) - f, - i = b.left + (z.win.pageXOffset || e.scrollLeft || d.scrollLeft) - g; - return { - y: h, - x: i - } - }; - u.getElementByPoint = function (a, b) { - var c = this, - d = c.canvas, - e = z.doc.elementFromPoint(a, b); - if (z.win.opera && "svg" == e.tagName) { - var f = $a(d), - g = d.createSVGRect(); - g.x = a - f.x, - g.y = b - f.y, - g.width = g.height = 1; - var h = d.getIntersectionList(g, null); - h.length && (e = h[h.length - 1]) - } - if (!e) - return null; - for (; e.parentNode && e != d.parentNode && !e.raphael; ) - e = e.parentNode; - return e == c.canvas.parentNode && (e = d), - e = e && e.raphael ? c.getById(e.raphaelid) : null - }, - u.getElementsByBBox = function (a) { - var c = this.set(); - return this.forEach(function (d) { - b.isBBoxIntersect(d.getBBox(), a) && c.push(d) - }), - c - }, - u.getById = function (a) { - for (var b = this.bottom; b; ) { - if (b.id == a) - return b; - b = b.next - } - return null - }, - u.forEach = function (a, b) { - for (var c = this.bottom; c; ) { - if (a.call(b, c) === !1) - return this; - c = c.next - } - return this - }, - u.getElementsByPoint = function (a, b) { - var c = this.set(); - return this.forEach(function (d) { - d.isPointInside(a, b) && c.push(d) - }), - c - }, - Xa.isPointInside = function (a, c) { - var d = this.realPath = oa[this.type](this); - return this.attr("transform") && this.attr("transform").length && (d = b.transformPath(d, this.attr("transform"))), - b.isPointInsidePath(d, a, c) - }, - Xa.getBBox = function (a) { - if (this.removed) - return {}; - var b = this._; - return a ? ((b.dirty || !b.bboxwt) && (this.realPath = oa[this.type](this), b.bboxwt = za(this.realPath), b.bboxwt.toString = o, b.dirty = 0), b.bboxwt) : ((b.dirty || b.dirtyT || !b.bbox) && ((b.dirty || !this.realPath) && (b.bboxwt = 0, this.realPath = oa[this.type](this)), b.bbox = za(pa(this.realPath, this.matrix)), b.bbox.toString = o, b.dirty = b.dirtyT = 0), b.bbox) - }, - Xa.clone = function () { - if (this.removed) - return null; - var a = this.paper[this.type]().attr(this.attr()); - return this.__set__ && this.__set__.push(a), - a - }, - Xa.glow = function (a) { - if ("text" == this.type) - return null; - a = a || {}; - var b = { - width: (a.width || 10) + (+this.attr("stroke-width") || 1), - fill: a.fill || !1, - opacity: null == a.opacity ? .5 : a.opacity, - offsetx: a.offsetx || 0, - offsety: a.offsety || 0, - color: a.color || "#000" - }, - c = b.width / 2, - d = this.paper, - e = d.set(), - f = this.realPath || oa[this.type](this); - f = this.matrix ? pa(f, this.matrix) : f; - for (var g = 1; c + 1 > g; g++) - e.push(d.path(f).attr({ - stroke: b.color, - fill: b.fill ? b.color : "none", - "stroke-linejoin": "round", - "stroke-linecap": "round", - "stroke-width": + (b.width / c * g).toFixed(3), - opacity: + (b.opacity / c).toFixed(3) - })); - return e.insertBefore(this).translate(b.offsetx, b.offsety) - }; - var _a = function (a, c, d, e, f, g, h, k, l) { - return null == l ? i(a, c, d, e, f, g, h, k) : b.findDotsAtSegment(a, c, d, e, f, g, h, k, j(a, c, d, e, f, g, h, k, l)) - }, - ab = function (a, c) { - return function (d, e, f) { - d = Ia(d); - for (var g, h, i, j, k, l = "", m = {}, n = 0, o = 0, p = d.length; p > o; o++) { - if (i = d[o], "M" == i[0]) - g = +i[1], h = +i[2]; - else { - if (j = _a(g, h, i[1], i[2], i[3], i[4], i[5], i[6]), n + j > e) { - if (c && !m.start) { - if (k = _a(g, h, i[1], i[2], i[3], i[4], i[5], i[6], e - n), l += ["C" + k.start.x, k.start.y, k.m.x, k.m.y, k.x, k.y], f) - return l; - m.start = l, - l = ["M" + k.x, k.y + "C" + k.n.x, k.n.y, k.end.x, k.end.y, i[5], i[6]].join(), - n += j, - g = +i[5], - h = +i[6]; - continue - } - if (!a && !c) - return k = _a(g, h, i[1], i[2], i[3], i[4], i[5], i[6], e - n), { - x: k.x, - y: k.y, - alpha: k.alpha - } - } - n += j, - g = +i[5], - h = +i[6] - } - l += i.shift() + i - } - return m.end = l, - k = a ? n : c ? m : b.findDotsAtSegment(g, h, i[0], i[1], i[2], i[3], i[4], i[5], 1), - k.alpha && (k = { - x: k.x, - y: k.y, - alpha: k.alpha - }), - k - } - }, - bb = ab(1), - cb = ab(), - db = ab(0, 1); - b.getTotalLength = bb, - b.getPointAtLength = cb, - b.getSubpath = function (a, b, c) { - if (this.getTotalLength(a) - c < 1e-6) - return db(a, b).end; - var d = db(a, c, 1); - return b ? db(d, b).end : d - }, - Xa.getTotalLength = function () { - var a = this.getPath(); - if (a) - return this.node.getTotalLength ? this.node.getTotalLength() : bb(a) - }, - Xa.getPointAtLength = function (a) { - var b = this.getPath(); - if (b) - return cb(b, a) - }, - Xa.getPath = function () { - var a, - c = b._getPath[this.type]; - if ("text" != this.type && "set" != this.type) - return c && (a = c(this)), a - }, - Xa.getSubpath = function (a, c) { - var d = this.getPath(); - if (d) - return b.getSubpath(d, a, c) - }; - var eb = b.easing_formulas = { - linear: function (a) { - return a - }, - "<": function (a) { - return Q(a, 1.7) - }, - ">": function (a) { - return Q(a, .48) - }, - "<>": function (a) { - var b = .48 - a / 1.04, - c = M.sqrt(.1734 + b * b), - d = c - b, - e = Q(P(d), 1 / 3) * (0 > d ? -1 : 1), - f = -c - b, - g = Q(P(f), 1 / 3) * (0 > f ? -1 : 1), - h = e + g + .5; - return 3 * (1 - h) * h * h + h * h * h - }, - backIn: function (a) { - var b = 1.70158; - return a * a * ((b + 1) * a - b) - }, - backOut: function (a) { - a -= 1; - var b = 1.70158; - return a * a * ((b + 1) * a + b) + 1 - }, - elastic: function (a) { - return a == !!a ? a : Q(2, -10 * a) * M.sin(2 * (a - .075) * R / .3) + 1 - }, - bounce: function (a) { - var b, - c = 7.5625, - d = 2.75; - return 1 / d > a ? b = c * a * a : 2 / d > a ? (a -= 1.5 / d, b = c * a * a + .75) : 2.5 / d > a ? (a -= 2.25 / d, b = c * a * a + .9375) : (a -= 2.625 / d, b = c * a * a + .984375), - b - } - }; - eb.easeIn = eb["ease-in"] = eb["<"], - eb.easeOut = eb["ease-out"] = eb[">"], - eb.easeInOut = eb["ease-in-out"] = eb["<>"], - eb["back-in"] = eb.backIn, - eb["back-out"] = eb.backOut; - var fb = [], - gb = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function (a) { - setTimeout(a, 16) - }, - hb = function () { - for (var c = +new Date, d = 0; d < fb.length; d++) { - var e = fb[d]; - if (!e.el.removed && !e.paused) { - var f, - g, - h = c - e.start, - i = e.ms, - j = e.easing, - k = e.from, - l = e.diff, - m = e.to, - n = (e.t, e.el), - o = {}, - p = {}; - if (e.initstatus ? (h = (e.initstatus * e.anim.top - e.prev) / (e.percent - e.prev) * i, e.status = e.initstatus, delete e.initstatus, e.stop && fb.splice(d--, 1)) : e.status = (e.prev + (e.percent - e.prev) * (h / i)) / e.anim.top, !(0 > h)) - if (i > h) { - var q = j(h / i); - for (var s in k) - if (k[y](s)) { - switch (ca[s]) { - case S: - f = +k[s] + q * i * l[s]; - break; - case "colour": - f = "rgb(" + [ib(Z(k[s].r + q * i * l[s].r)), ib(Z(k[s].g + q * i * l[s].g)), ib(Z(k[s].b + q * i * l[s].b))].join(",") + ")"; - break; - case "path": - f = []; - for (var t = 0, u = k[s].length; u > t; t++) { - f[t] = [k[s][t][0]]; - for (var v = 1, w = k[s][t].length; w > v; v++) - f[t][v] = +k[s][t][v] + q * i * l[s][t][v]; - f[t] = f[t].join(G) - } - f = f.join(G); - break; - case "transform": - if (l[s].real) - for (f = [], t = 0, u = k[s].length; u > t; t++) - for (f[t] = [k[s][t][0]], v = 1, w = k[s][t].length; w > v; v++) - f[t][v] = k[s][t][v] + q * i * l[s][t][v]; - else { - var x = function (a) { - return +k[s][a] + q * i * l[s][a] - }; - f = [["m", x(0), x(1), x(2), x(3), x(4), x(5)]] - } - break; - case "csv": - if ("clip-rect" == s) - for (f = [], t = 4; t--; ) - f[t] = +k[s][t] + q * i * l[s][t]; - break; - default: - var z = [][D](k[s]); - for (f = [], t = n.paper.customAttributes[s].length; t--; ) - f[t] = +z[t] + q * i * l[s][t] - } - o[s] = f - } - n.attr(o), - function (b, c, d) { - setTimeout(function () { - a("raphael.anim.frame." + b, c, d) - }) - } - (n.id, n, e.anim) - } else { - if (function (c, d, e) { - setTimeout(function () { - a("raphael.anim.frame." + d.id, d, e), - a("raphael.anim.finish." + d.id, d, e), - b.is(c, "function") && c.call(d) - }) - } - (e.callback, n, e.anim), n.attr(m), fb.splice(d--, 1), e.repeat > 1 && !e.next) { - for (g in m) - m[y](g) && (p[g] = e.totalOrigin[g]); - e.el.attr(p), - r(e.anim, e.el, e.anim.percents[0], null, e.totalOrigin, e.repeat - 1) - } - e.next && !e.stop && r(e.anim, e.el, e.next, null, e.totalOrigin, e.repeat) - } - } - } - fb.length && gb(hb) - }, - ib = function (a) { - return a > 255 ? 255 : 0 > a ? 0 : a - }; - Xa.animateWith = function (a, c, d, e, f, g) { - var h = this; - if (h.removed) - return g && g.call(h), h; - var i = d instanceof q ? d : b.animation(d, e, f, g); - r(i, h, i.percents[0], null, h.attr()); - for (var j = 0, k = fb.length; k > j; j++) - if (fb[j].anim == c && fb[j].el == a) { - fb[k - 1].start = fb[j].start; - break - } - return h - }, - Xa.onAnimation = function (b) { - return b ? a.on("raphael.anim.frame." + this.id, b) : a.unbind("raphael.anim.frame." + this.id), - this - }, - q.prototype.delay = function (a) { - var b = new q(this.anim, this.ms); - return b.times = this.times, - b.del = +a || 0, - b - }, - q.prototype.repeat = function (a) { - var b = new q(this.anim, this.ms); - return b.del = this.del, - b.times = M.floor(N(a, 0)) || 1, - b - }, - b.animation = function (a, c, d, e) { - if (a instanceof q) - return a; - (b.is(d, "function") || !d) && (e = e || d || null, d = null), - a = Object(a), - c = +c || 0; - var f, - g, - h = {}; - for (g in a) - a[y](g) && $(g) != g && $(g) + "%" != g && (f = !0, h[g] = a[g]); - if (f) - return d && (h.easing = d), e && (h.callback = e), new q({ - 100: h - }, c); - if (e) { - var i = 0; - for (var j in a) { - var k = _(j); - a[y](j) && k > i && (i = k) - } - i += "%", - !a[i].callback && (a[i].callback = e) - } - return new q(a, c) - }, - Xa.animate = function (a, c, d, e) { - var f = this; - if (f.removed) - return e && e.call(f), f; - var g = a instanceof q ? a : b.animation(a, c, d, e); - return r(g, f, g.percents[0], null, f.attr()), - f - }, - Xa.setTime = function (a, b) { - return a && null != b && this.status(a, O(b, a.ms) / a.ms), - this - }, - Xa.status = function (a, b) { - var c, - d, - e = [], - f = 0; - if (null != b) - return r(a, this, -1, O(b, 1)), this; - for (c = fb.length; c > f; f++) - if (d = fb[f], d.el.id == this.id && (!a || d.anim == a)) { - if (a) - return d.status; - e.push({ - anim: d.anim, - status: d.status - }) - } - return a ? 0 : e - }, - Xa.pause = function (b) { - for (var c = 0; c < fb.length; c++) - fb[c].el.id != this.id || b && fb[c].anim != b || a("raphael.anim.pause." + this.id, this, fb[c].anim) !== !1 && (fb[c].paused = !0); - return this - }, - Xa.resume = function (b) { - for (var c = 0; c < fb.length; c++) - if (fb[c].el.id == this.id && (!b || fb[c].anim == b)) { - var d = fb[c]; - a("raphael.anim.resume." + this.id, this, d.anim) !== !1 && (delete d.paused, this.status(d.anim, d.status)) - } - return this - }, - Xa.stop = function (b) { - for (var c = 0; c < fb.length; c++) - fb[c].el.id != this.id || b && fb[c].anim != b || a("raphael.anim.stop." + this.id, this, fb[c].anim) !== !1 && fb.splice(c--, 1); - return this - }, - a.on("raphael.remove", s), - a.on("raphael.clear", s), - Xa.toString = function () { - return "Raphaël’s object" - }; - var jb = function (a) { - if (this.items = [], this.length = 0, this.type = "set", a) - for (var b = 0, c = a.length; c > b; b++) - !a[b] || a[b].constructor != Xa.constructor && a[b].constructor != jb || (this[this.items.length] = this.items[this.items.length] = a[b], this.length++) - }, - kb = jb.prototype; - kb.push = function () { - for (var a, b, c = 0, d = arguments.length; d > c; c++) - a = arguments[c], !a || a.constructor != Xa.constructor && a.constructor != jb || (b = this.items.length, this[b] = this.items[b] = a, this.length++); - return this - }, - kb.pop = function () { - return this.length && delete this[this.length--], - this.items.pop() - }, - kb.forEach = function (a, b) { - for (var c = 0, d = this.items.length; d > c; c++) - if (a.call(b, this.items[c], c) === !1) - return this; - return this - }; - for (var lb in Xa) - Xa[y](lb) && (kb[lb] = function (a) { - return function () { - var b = arguments; - return this.forEach(function (c) { - c[a][C](c, b) - }) - } - } - (lb)); - return kb.attr = function (a, c) { - if (a && b.is(a, U) && b.is(a[0], "object")) - for (var d = 0, e = a.length; e > d; d++) - this.items[d].attr(a[d]); - else - for (var f = 0, g = this.items.length; g > f; f++) - this.items[f].attr(a, c); - return this - }, - kb.clear = function () { - for (; this.length; ) - this.pop() - }, - kb.splice = function (a, b, c) { - a = 0 > a ? N(this.length + a, 0) : a, - b = N(0, O(this.length - a, b)); - var d, - e = [], - f = [], - g = []; - for (d = 2; d < arguments.length; d++) - g.push(arguments[d]); - for (d = 0; b > d; d++) - f.push(this[a + d]); - for (; d < this.length - a; d++) - e.push(this[a + d]); - var h = g.length; - for (d = 0; d < h + e.length; d++) - this.items[a + d] = this[a + d] = h > d ? g[d] : e[d - h]; - for (d = this.items.length = this.length -= b - h; this[d]; ) - delete this[d++]; - return new jb(f) - }, - kb.exclude = function (a) { - for (var b = 0, c = this.length; c > b; b++) - if (this[b] == a) - return this.splice(b, 1), !0 - }, - kb.animate = function (a, c, d, e) { - (b.is(d, "function") || !d) && (e = d || null); - var f, - g, - h = this.items.length, - i = h, - j = this; - if (!h) - return this; - e && (g = function () { - !--h && e.call(j) - }), - d = b.is(d, T) ? d : g; - var k = b.animation(a, c, d, g); - for (f = this.items[--i].animate(k); i--; ) - this.items[i] && !this.items[i].removed && this.items[i].animateWith(f, k, k), this.items[i] && !this.items[i].removed || h--; - return this - }, - kb.insertAfter = function (a) { - for (var b = this.items.length; b--; ) - this.items[b].insertAfter(a); - return this - }, - kb.getBBox = function () { - for (var a = [], b = [], c = [], d = [], e = this.items.length; e--; ) - if (!this.items[e].removed) { - var f = this.items[e].getBBox(); - a.push(f.x), - b.push(f.y), - c.push(f.x + f.width), - d.push(f.y + f.height) - } - return a = O[C](0, a), - b = O[C](0, b), - c = N[C](0, c), - d = N[C](0, d), { - x: a, - y: b, - x2: c, - y2: d, - width: c - a, - height: d - b - } - }, - kb.clone = function (a) { - a = this.paper.set(); - for (var b = 0, c = this.items.length; c > b; b++) - a.push(this.items[b].clone()); - return a - }, - kb.toString = function () { - return "Raphaël‘s set" - }, - kb.glow = function (a) { - var b = this.paper.set(); - return this.forEach(function (c, d) { - var e = c.glow(a); - null != e && e.forEach(function (a, c) { - b.push(a) - }) - }), - b - }, - kb.isPointInside = function (a, b) { - var c = !1; - return this.forEach(function (d) { - return d.isPointInside(a, b) ? (c = !0, !1) : void 0 - }), - c - }, - b.registerFont = function (a) { - if (!a.face) - return a; - this.fonts = this.fonts || {}; - var b = { - w: a.w, - face: {}, - glyphs: {} - }, - c = a.face["font-family"]; - for (var d in a.face) - a.face[y](d) && (b.face[d] = a.face[d]); - if (this.fonts[c] ? this.fonts[c].push(b) : this.fonts[c] = [b], !a.svg) { - b.face["units-per-em"] = _(a.face["units-per-em"], 10); - for (var e in a.glyphs) - if (a.glyphs[y](e)) { - var f = a.glyphs[e]; - if (b.glyphs[e] = { - w: f.w, - k: {}, - d: f.d && "M" + f.d.replace(/[mlcxtrv]/g, function (a) { - return { - l: "L", - c: "C", - x: "z", - t: "m", - r: "l", - v: "c" - } - [a] || "M" - }) + "z" - }, f.k) - for (var g in f.k) - f[y](g) && (b.glyphs[e].k[g] = f.k[g]) - } - } - return a - }, - u.getFont = function (a, c, d, e) { - if (e = e || "normal", d = d || "normal", c = +c || { - normal: 400, - bold: 700, - lighter: 300, - bolder: 800 - } - [c] || 400, b.fonts) { - var f = b.fonts[a]; - if (!f) { - var g = new RegExp("(^|\\s)" + a.replace(/[^\w\d\s+!~.:_-]/g, F) + "(\\s|$)", "i"); - for (var h in b.fonts) - if (b.fonts[y](h) && g.test(h)) { - f = b.fonts[h]; - break - } - } - var i; - if (f) - for (var j = 0, k = f.length; k > j && (i = f[j], i.face["font-weight"] != c || i.face["font-style"] != d && i.face["font-style"] || i.face["font-stretch"] != e); j++); - return i - } - }, - u.print = function (a, c, d, e, f, g, h, i) { - g = g || "middle", - h = N(O(h || 0, 1), -1), - i = N(O(i || 1, 3), 1); - var j, - k = H(d)[I](F), - l = 0, - m = 0, - n = F; - if (b.is(e, "string") && (e = this.getFont(e)), e) { - j = (f || 16) / e.face["units-per-em"]; - for (var o = e.face.bbox[I](v), p = +o[0], q = o[3] - o[1], r = 0, s = +o[1] + ("baseline" == g ? q + +e.face.descent : q / 2), t = 0, u = k.length; u > t; t++) { - if ("\n" == k[t]) - l = 0, x = 0, m = 0, r += q * i; - else { - var w = m && e.glyphs[k[t - 1]] || {}, - x = e.glyphs[k[t]]; - l += m ? (w.w || e.w) + (w.k && w.k[k[t]] || 0) + e.w * h : 0, - m = 1 - } - x && x.d && (n += b.transformPath(x.d, ["t", l * j, r * j, "s", j, j, p, s, "t", (a - p) / j, (c - s) / j])) - } - } - return this.path(n).attr({ - fill: "#000", - stroke: "none" - }) - }, - u.add = function (a) { - if (b.is(a, "array")) - for (var c, d = this.set(), e = 0, f = a.length; f > e; e++) - c = a[e] || {}, - w[y](c.type) && d.push(this[c.type]().attr(c)); - return d - }, - b.format = function (a, c) { - var d = b.is(c, U) ? [0][D](c) : arguments; - return a && b.is(a, T) && d.length - 1 && (a = a.replace(x, function (a, b) { - return null == d[++b] ? F : d[b] - })), - a || F - }, - b.fullfill = function () { - var a = /\{([^\}]+)\}/g, - b = /(?:(?:^|\.)(.+?)(?=\[|\.|$|\()|\[('|")(.+?)\2\])(\(\))?/g, - c = function (a, c, d) { - var e = d; - return c.replace(b, function (a, b, c, d, f) { - b = b || d, - e && (b in e && (e = e[b]), "function" == typeof e && f && (e = e())) - }), - e = (null == e || e == d ? a : e) + "" - }; - return function (b, d) { - return String(b).replace(a, function (a, b) { - return c(a, b, d) - }) - } - } - (), - b.ninja = function () { - return A.was ? z.win.Raphael = A.is : delete Raphael, - b - }, - b.st = kb, - a.on("raphael.DOMload", function () { - t = !0 - }), - function (a, c, d) { - function e() { - /in/.test(a.readyState) ? setTimeout(e, 9) : b.eve("raphael.DOMload") - } - null == a.readyState && a.addEventListener && (a.addEventListener(c, d = function () { - a.removeEventListener(c, d, !1), - a.readyState = "complete" - }, !1), a.readyState = "loading"), - e() - } - (document, "DOMContentLoaded"), - b -}), function (a, b) { - "function" == typeof define && define.amd ? define("raphael.svg", ["raphael.core"], function (a) { - return b(a) - }) : b("object" == typeof exports ? require("./raphael.core") : a.Raphael) -} -(this, function (a) { - if (!a || a.svg) { - var b = "hasOwnProperty", - c = String, - d = parseFloat, - e = parseInt, - f = Math, - g = f.max, - h = f.abs, - i = f.pow, - j = /[, ]+/, - k = a.eve, - l = "", - m = " ", - n = "http://www.w3.org/1999/xlink", - o = { - block: "M5,0 0,2.5 5,5z", - classic: "M5,0 0,2.5 5,5 3.5,3 3.5,2z", - diamond: "M2.5,0 5,2.5 2.5,5 0,2.5z", - open: "M6,1 1,3.5 6,6", - oval: "M2.5,0A2.5,2.5,0,0,1,2.5,5 2.5,2.5,0,0,1,2.5,0z" - }, - p = {}; - a.toString = function () { - return "Your browser supports SVG.\nYou are running Raphaël " + this.version - }; - var q = function (d, e) { - if (e) { - "string" == typeof d && (d = q(d)); - for (var f in e) - e[b](f) && ("xlink:" == f.substring(0, 6) ? d.setAttributeNS(n, f.substring(6), c(e[f])) : d.setAttribute(f, c(e[f]))) - } else - d = a._g.doc.createElementNS("http://www.w3.org/2000/svg", d), d.style && (d.style.webkitTapHighlightColor = "rgba(0,0,0,0)"); - return d - }, - r = function (b, e) { - var j = "linear", - k = b.id + e, - m = .5, - n = .5, - o = b.node, - p = b.paper, - r = o.style, - s = a._g.doc.getElementById(k); - if (!s) { - if (e = c(e).replace(a._radial_gradient, function (a, b, c) { - if (j = "radial", b && c) { - m = d(b), - n = d(c); - var e = 2 * (n > .5) - 1; - i(m - .5, 2) + i(n - .5, 2) > .25 && (n = f.sqrt(.25 - i(m - .5, 2)) * e + .5) && .5 != n && (n = n.toFixed(5) - 1e-5 * e) - } - return l - }), e = e.split(/\s*\-\s*/), "linear" == j) { - var t = e.shift(); - if (t = -d(t), isNaN(t)) - return null; - var u = [0, 0, f.cos(a.rad(t)), f.sin(a.rad(t))], - v = 1 / (g(h(u[2]), h(u[3])) || 1); - u[2] *= v, - u[3] *= v, - u[2] < 0 && (u[0] = -u[2], u[2] = 0), - u[3] < 0 && (u[1] = -u[3], u[3] = 0) - } - var w = a._parseDots(e); - if (!w) - return null; - if (k = k.replace(/[\(\)\s,\xb0#]/g, "_"), b.gradient && k != b.gradient.id && (p.defs.removeChild(b.gradient), delete b.gradient), !b.gradient) { - s = q(j + "Gradient", { - id: k - }), - b.gradient = s, - q(s, "radial" == j ? { - fx: m, - fy: n - } - : { - x1: u[0], - y1: u[1], - x2: u[2], - y2: u[3], - gradientTransform: b.matrix.invert() - }), - p.defs.appendChild(s); - for (var x = 0, y = w.length; y > x; x++) - s.appendChild(q("stop", { - offset: w[x].offset ? w[x].offset : x ? "100%" : "0%", - "stop-color": w[x].color || "#fff", - "stop-opacity": isFinite(w[x].opacity) ? w[x].opacity : 1 - })) - } - } - return q(o, { - fill: "url('" + document.location.origin + document.location.pathname + "#" + k + "')", - opacity: 1, - "fill-opacity": 1 - }), - r.fill = l, - r.opacity = 1, - r.fillOpacity = 1, - 1 - }, - s = function (a) { - var b = a.getBBox(1); - q(a.pattern, { - patternTransform: a.matrix.invert() + " translate(" + b.x + "," + b.y + ")" - }) - }, - t = function (d, e, f) { - if ("path" == d.type) { - for (var g, h, i, j, k, m = c(e).toLowerCase().split("-"), n = d.paper, r = f ? "end" : "start", s = d.node, t = d.attrs, u = t["stroke-width"], v = m.length, w = "classic", x = 3, y = 3, z = 5; v--; ) - switch (m[v]) { - case "block": - case "classic": - case "oval": - case "diamond": - case "open": - case "none": - w = m[v]; - break; - case "wide": - y = 5; - break; - case "narrow": - y = 2; - break; - case "long": - x = 5; - break; - case "short": - x = 2 - } - if ("open" == w ? (x += 2, y += 2, z += 2, i = 1, j = f ? 4 : 1, k = { - fill: "none", - stroke: t.stroke - }) : (j = i = x / 2, k = { - fill: t.stroke, - stroke: "none" - }), d._.arrows ? f ? (d._.arrows.endPath && p[d._.arrows.endPath]--, d._.arrows.endMarker && p[d._.arrows.endMarker]--) : (d._.arrows.startPath && p[d._.arrows.startPath]--, d._.arrows.startMarker && p[d._.arrows.startMarker]--) : d._.arrows = {}, "none" != w) { - var A = "raphael-marker-" + w, - B = "raphael-marker-" + r + w + x + y + "-obj" + d.id; - a._g.doc.getElementById(A) ? p[A]++ : (n.defs.appendChild(q(q("path"), { - "stroke-linecap": "round", - d: o[w], - id: A - })), p[A] = 1); - var C, - D = a._g.doc.getElementById(B); - D ? (p[B]++, C = D.getElementsByTagName("use")[0]) : (D = q(q("marker"), { - id: B, - markerHeight: y, - markerWidth: x, - orient: "auto", - refX: j, - refY: y / 2 - }), C = q(q("use"), { - "xlink:href": "#" + A, - transform: (f ? "rotate(180 " + x / 2 + " " + y / 2 + ") " : l) + "scale(" + x / z + "," + y / z + ")", - "stroke-width": (1 / ((x / z + y / z) / 2)).toFixed(4) - }), D.appendChild(C), n.defs.appendChild(D), p[B] = 1), - q(C, k); - var E = i * ("diamond" != w && "oval" != w); - f ? (g = d._.arrows.startdx * u || 0, h = a.getTotalLength(t.path) - E * u) : (g = E * u, h = a.getTotalLength(t.path) - (d._.arrows.enddx * u || 0)), - k = {}, - k["marker-" + r] = "url(#" + B + ")", - (h || g) && (k.d = a.getSubpath(t.path, g, h)), - q(s, k), - d._.arrows[r + "Path"] = A, - d._.arrows[r + "Marker"] = B, - d._.arrows[r + "dx"] = E, - d._.arrows[r + "Type"] = w, - d._.arrows[r + "String"] = e - } else - f ? (g = d._.arrows.startdx * u || 0, h = a.getTotalLength(t.path) - g) : (g = 0, h = a.getTotalLength(t.path) - (d._.arrows.enddx * u || 0)), d._.arrows[r + "Path"] && q(s, { - d: a.getSubpath(t.path, g, h) - }), delete d._.arrows[r + "Path"], delete d._.arrows[r + "Marker"], delete d._.arrows[r + "dx"], delete d._.arrows[r + "Type"], delete d._.arrows[r + "String"]; - for (k in p) - if (p[b](k) && !p[k]) { - var F = a._g.doc.getElementById(k); - F && F.parentNode.removeChild(F) - } - } - }, - u = { - "-": [3, 1], - ".": [1, 1], - "-.": [3, 1, 1, 1], - "-..": [3, 1, 1, 1, 1, 1], - ". ": [1, 3], - "- ": [4, 3], - "--": [8, 3], - "- .": [4, 3, 1, 3], - "--.": [8, 3, 1, 3], - "--..": [8, 3, 1, 3, 1, 3] - }, - v = function (a, b, d) { - if (b = u[c(b).toLowerCase()]) { - for (var e = a.attrs["stroke-width"] || "1", f = { - round: e, - square: e, - butt: 0 - } - [a.attrs["stroke-linecap"] || d["stroke-linecap"]] || 0, g = [], h = b.length; h--; ) - g[h] = b[h] * e + (h % 2 ? 1 : -1) * f; - q(a.node, { - "stroke-dasharray": g.join(",") - }) - } else - q(a.node, { - "stroke-dasharray": "none" - }) - }, - w = function (d, f) { - var i = d.node, - k = d.attrs, - m = i.style.visibility; - i.style.visibility = "hidden"; - for (var o in f) - if (f[b](o)) { - if (!a._availableAttrs[b](o)) - continue; - var p = f[o]; - switch (k[o] = p, o) { - case "blur": - d.blur(p); - break; - case "title": - var u = i.getElementsByTagName("title"); - if (u.length && (u = u[0])) - u.firstChild.nodeValue = p; - else { - u = q("title"); - var w = a._g.doc.createTextNode(p); - u.appendChild(w), - i.appendChild(u) - } - break; - case "href": - case "target": - var x = i.parentNode; - if ("a" != x.tagName.toLowerCase()) { - var z = q("a"); - x.insertBefore(z, i), - z.appendChild(i), - x = z - } - "target" == o ? x.setAttributeNS(n, "show", "blank" == p ? "new" : p) : x.setAttributeNS(n, o, p); - break; - case "cursor": - i.style.cursor = p; - break; - case "transform": - d.transform(p); - break; - case "arrow-start": - t(d, p); - break; - case "arrow-end": - t(d, p, 1); - break; - case "clip-rect": - var A = c(p).split(j); - if (4 == A.length) { - d.clip && d.clip.parentNode.parentNode.removeChild(d.clip.parentNode); - var B = q("clipPath"), - C = q("rect"); - B.id = a.createUUID(), - q(C, { - x: A[0], - y: A[1], - width: A[2], - height: A[3] - }), - B.appendChild(C), - d.paper.defs.appendChild(B), - q(i, { - "clip-path": "url(#" + B.id + ")" - }), - d.clip = C - } - if (!p) { - var D = i.getAttribute("clip-path"); - if (D) { - var E = a._g.doc.getElementById(D.replace(/(^url\(#|\)$)/g, l)); - E && E.parentNode.removeChild(E), - q(i, { - "clip-path": l - }), - delete d.clip - } - } - break; - case "path": - "path" == d.type && (q(i, { - d: p ? k.path = a._pathToAbsolute(p) : "M0,0" - }), d._.dirty = 1, d._.arrows && ("startString" in d._.arrows && t(d, d._.arrows.startString), "endString" in d._.arrows && t(d, d._.arrows.endString, 1))); - break; - case "width": - if (i.setAttribute(o, p), d._.dirty = 1, !k.fx) - break; - o = "x", - p = k.x; - case "x": - k.fx && (p = -k.x - (k.width || 0)); - case "rx": - if ("rx" == o && "rect" == d.type) - break; - case "cx": - i.setAttribute(o, p), - d.pattern && s(d), - d._.dirty = 1; - break; - case "height": - if (i.setAttribute(o, p), d._.dirty = 1, !k.fy) - break; - o = "y", - p = k.y; - case "y": - k.fy && (p = -k.y - (k.height || 0)); - case "ry": - if ("ry" == o && "rect" == d.type) - break; - case "cy": - i.setAttribute(o, p), - d.pattern && s(d), - d._.dirty = 1; - break; - case "r": - "rect" == d.type ? q(i, { - rx: p, - ry: p - }) : i.setAttribute(o, p), - d._.dirty = 1; - break; - case "src": - "image" == d.type && i.setAttributeNS(n, "href", p); - break; - case "stroke-width": - (1 != d._.sx || 1 != d._.sy) && (p /= g(h(d._.sx), h(d._.sy)) || 1), - i.setAttribute(o, p), - k["stroke-dasharray"] && v(d, k["stroke-dasharray"], f), - d._.arrows && ("startString" in d._.arrows && t(d, d._.arrows.startString), "endString" in d._.arrows && t(d, d._.arrows.endString, 1)); - break; - case "stroke-dasharray": - v(d, p, f); - break; - case "fill": - var F = c(p).match(a._ISURL); - if (F) { - B = q("pattern"); - var G = q("image"); - B.id = a.createUUID(), - q(B, { - x: 0, - y: 0, - patternUnits: "userSpaceOnUse", - height: 1, - width: 1 - }), - q(G, { - x: 0, - y: 0, - "xlink:href": F[1] - }), - B.appendChild(G), - function (b) { - a._preload(F[1], function () { - var a = this.offsetWidth, - c = this.offsetHeight; - q(b, { - width: a, - height: c - }), - q(G, { - width: a, - height: c - }) - }) - } - (B), - d.paper.defs.appendChild(B), - q(i, { - fill: "url(#" + B.id + ")" - }), - d.pattern = B, - d.pattern && s(d); - break - } - var H = a.getRGB(p); - if (H.error) { - if (("circle" == d.type || "ellipse" == d.type || "r" != c(p).charAt()) && r(d, p)) { - if ("opacity" in k || "fill-opacity" in k) { - var I = a._g.doc.getElementById(i.getAttribute("fill").replace(/^url\(#|\)$/g, l)); - if (I) { - var J = I.getElementsByTagName("stop"); - q(J[J.length - 1], { - "stop-opacity": ("opacity" in k ? k.opacity : 1) * ("fill-opacity" in k ? k["fill-opacity"] : 1) - }) - } - } - k.gradient = p, - k.fill = "none"; - break - } - } else - delete f.gradient, delete k.gradient, !a.is(k.opacity, "undefined") && a.is(f.opacity, "undefined") && q(i, { - opacity: k.opacity - }), !a.is(k["fill-opacity"], "undefined") && a.is(f["fill-opacity"], "undefined") && q(i, { - "fill-opacity": k["fill-opacity"] - }); - H[b]("opacity") && q(i, { - "fill-opacity": H.opacity > 1 ? H.opacity / 100 : H.opacity - }); - case "stroke": - H = a.getRGB(p), - i.setAttribute(o, H.hex), - "stroke" == o && H[b]("opacity") && q(i, { - "stroke-opacity": H.opacity > 1 ? H.opacity / 100 : H.opacity - }), - "stroke" == o && d._.arrows && ("startString" in d._.arrows && t(d, d._.arrows.startString), "endString" in d._.arrows && t(d, d._.arrows.endString, 1)); - break; - case "gradient": - ("circle" == d.type || "ellipse" == d.type || "r" != c(p).charAt()) && r(d, p); - break; - case "opacity": - k.gradient && !k[b]("stroke-opacity") && q(i, { - "stroke-opacity": p > 1 ? p / 100 : p - }); - case "fill-opacity": - if (k.gradient) { - I = a._g.doc.getElementById(i.getAttribute("fill").replace(/^url\(#|\)$/g, l)), - I && (J = I.getElementsByTagName("stop"), q(J[J.length - 1], { - "stop-opacity": p - })); - break - } - default: - "font-size" == o && (p = e(p, 10) + "px"); - var K = o.replace(/(\-.)/g, function (a) { - return a.substring(1).toUpperCase() - }); - i.style[K] = p, - d._.dirty = 1, - i.setAttribute(o, p) - } - } - y(d, f), - i.style.visibility = m - }, - x = 1.2, - y = function (d, f) { - if ("text" == d.type && (f[b]("text") || f[b]("font") || f[b]("font-size") || f[b]("x") || f[b]("y"))) { - var g = d.attrs, - h = d.node, - i = h.firstChild ? e(a._g.doc.defaultView.getComputedStyle(h.firstChild, l).getPropertyValue("font-size"), 10) : 10; - if (f[b]("text")) { - for (g.text = f.text; h.firstChild; ) - h.removeChild(h.firstChild); - for (var j, k = c(f.text).split("\n"), m = [], n = 0, o = k.length; o > n; n++) - j = q("tspan"), n && q(j, { - dy: i * x, - x: g.x - }), j.appendChild(a._g.doc.createTextNode(k[n])), h.appendChild(j), m[n] = j - } else - for (m = h.getElementsByTagName("tspan"), n = 0, o = m.length; o > n; n++) - n ? q(m[n], { - dy: i * x, - x: g.x - }) : q(m[0], { - dy: 0 - }); - q(h, { - x: g.x, - y: g.y - }), - d._.dirty = 1; - var p = d._getBBox(), - r = g.y - (p.y + p.height / 2); - r && a.is(r, "finite") && q(m[0], { - dy: r - }) - } - }, - z = function (a) { - return a.parentNode && "a" === a.parentNode.tagName.toLowerCase() ? a.parentNode : a - }, - A = function (b, c) { - this[0] = this.node = b, - b.raphael = !0, - this.id = a._oid++, - b.raphaelid = this.id, - this.matrix = a.matrix(), - this.realPath = null, - this.paper = c, - this.attrs = this.attrs || {}, - this._ = { - transform: [], - sx: 1, - sy: 1, - deg: 0, - dx: 0, - dy: 0, - dirty: 1 - }, - !c.bottom && (c.bottom = this), - this.prev = c.top, - c.top && (c.top.next = this), - c.top = this, - this.next = null - }, - B = a.el; - A.prototype = B, - B.constructor = A, - a._engine.path = function (a, b) { - var c = q("path"); - b.canvas && b.canvas.appendChild(c); - var d = new A(c, b); - return d.type = "path", - w(d, { - fill: "none", - stroke: "#000", - path: a - }), - d - }, - B.rotate = function (a, b, e) { - if (this.removed) - return this; - if (a = c(a).split(j), a.length - 1 && (b = d(a[1]), e = d(a[2])), a = d(a[0]), null == e && (b = e), null == b || null == e) { - var f = this.getBBox(1); - b = f.x + f.width / 2, - e = f.y + f.height / 2 - } - return this.transform(this._.transform.concat([["r", a, b, e]])), - this - }, - B.scale = function (a, b, e, f) { - if (this.removed) - return this; - if (a = c(a).split(j), a.length - 1 && (b = d(a[1]), e = d(a[2]), f = d(a[3])), a = d(a[0]), null == b && (b = a), null == f && (e = f), null == e || null == f) - var g = this.getBBox(1); - return e = null == e ? g.x + g.width / 2 : e, - f = null == f ? g.y + g.height / 2 : f, - this.transform(this._.transform.concat([["s", a, b, e, f]])), - this - }, - B.translate = function (a, b) { - return this.removed ? this : (a = c(a).split(j), a.length - 1 && (b = d(a[1])), a = d(a[0]) || 0, b = +b || 0, this.transform(this._.transform.concat([["t", a, b]])), this) - }, - B.transform = function (c) { - var d = this._; - if (null == c) - return d.transform; - if (a._extractTransform(this, c), this.clip && q(this.clip, { - transform: this.matrix.invert() - }), this.pattern && s(this), this.node && q(this.node, { - transform: this.matrix - }), 1 != d.sx || 1 != d.sy) { - var e = this.attrs[b]("stroke-width") ? this.attrs["stroke-width"] : 1; - this.attr({ - "stroke-width": e - }) - } - return this - }, - B.hide = function () { - return this.removed || (this.node.style.display = "none"), - this - }, - B.show = function () { - return this.removed || (this.node.style.display = ""), - this - }, - B.remove = function () { - var b = z(this.node); - if (!this.removed && b.parentNode) { - var c = this.paper; - c.__set__ && c.__set__.exclude(this), - k.unbind("raphael.*.*." + this.id), - this.gradient && c.defs.removeChild(this.gradient), - a._tear(this, c), - b.parentNode.removeChild(b), - this.removeData(); - for (var d in this) - this[d] = "function" == typeof this[d] ? a._removedFactory(d) : null; - this.removed = !0 - } - }, - B._getBBox = function () { - if ("none" == this.node.style.display) { - this.show(); - var a = !0 - } - var b, - c = !1; - this.paper.canvas.parentElement ? b = this.paper.canvas.parentElement.style : this.paper.canvas.parentNode && (b = this.paper.canvas.parentNode.style), - b && "none" == b.display && (c = !0, b.display = ""); - var d = {}; - try { - d = this.node.getBBox() - } catch (e) { - d = { - x: this.node.clientLeft, - y: this.node.clientTop, - width: this.node.clientWidth, - height: this.node.clientHeight - } - } - finally { - d = d || {}, - c && (b.display = "none") - } - return a && this.hide(), - d - }, - B.attr = function (c, d) { - if (this.removed) - return this; - if (null == c) { - var e = {}; - for (var f in this.attrs) - this.attrs[b](f) && (e[f] = this.attrs[f]); - return e.gradient && "none" == e.fill && (e.fill = e.gradient) && delete e.gradient, - e.transform = this._.transform, - e - } - if (null == d && a.is(c, "string")) { - if ("fill" == c && "none" == this.attrs.fill && this.attrs.gradient) - return this.attrs.gradient; - if ("transform" == c) - return this._.transform; - for (var g = c.split(j), h = {}, i = 0, l = g.length; l > i; i++) - c = g[i], c in this.attrs ? h[c] = this.attrs[c] : a.is(this.paper.customAttributes[c], "function") ? h[c] = this.paper.customAttributes[c].def : h[c] = a._availableAttrs[c]; - return l - 1 ? h : h[g[0]] - } - if (null == d && a.is(c, "array")) { - for (h = {}, i = 0, l = c.length; l > i; i++) - h[c[i]] = this.attr(c[i]); - return h - } - if (null != d) { - var m = {}; - m[c] = d - } else - null != c && a.is(c, "object") && (m = c); - for (var n in m) - k("raphael.attr." + n + "." + this.id, this, m[n]); - for (n in this.paper.customAttributes) - if (this.paper.customAttributes[b](n) && m[b](n) && a.is(this.paper.customAttributes[n], "function")) { - var o = this.paper.customAttributes[n].apply(this, [].concat(m[n])); - this.attrs[n] = m[n]; - for (var p in o) - o[b](p) && (m[p] = o[p]) - } - return w(this, m), - this - }, - B.toFront = function () { - if (this.removed) - return this; - var b = z(this.node); - b.parentNode.appendChild(b); - var c = this.paper; - return c.top != this && a._tofront(this, c), - this - }, - B.toBack = function () { - if (this.removed) - return this; - var b = z(this.node), - c = b.parentNode; - c.insertBefore(b, c.firstChild), - a._toback(this, this.paper); - this.paper; - return this - }, - B.insertAfter = function (b) { - if (this.removed || !b) - return this; - var c = z(this.node), - d = z(b.node || b[b.length - 1].node); - return d.nextSibling ? d.parentNode.insertBefore(c, d.nextSibling) : d.parentNode.appendChild(c), - a._insertafter(this, b, this.paper), - this - }, - B.insertBefore = function (b) { - if (this.removed || !b) - return this; - var c = z(this.node), - d = z(b.node || b[0].node); - return d.parentNode.insertBefore(c, d), - a._insertbefore(this, b, this.paper), - this - }, - B.blur = function (b) { - var c = this; - if (0 !== +b) { - var d = q("filter"), - e = q("feGaussianBlur"); - c.attrs.blur = b, - d.id = a.createUUID(), - q(e, { - stdDeviation: +b || 1.5 - }), - d.appendChild(e), - c.paper.defs.appendChild(d), - c._blur = d, - q(c.node, { - filter: "url(#" + d.id + ")" - }) - } else - c._blur && (c._blur.parentNode.removeChild(c._blur), delete c._blur, delete c.attrs.blur), c.node.removeAttribute("filter"); - return c - }, - a._engine.circle = function (a, b, c, d) { - var e = q("circle"); - a.canvas && a.canvas.appendChild(e); - var f = new A(e, a); - return f.attrs = { - cx: b, - cy: c, - r: d, - fill: "none", - stroke: "#000" - }, - f.type = "circle", - q(e, f.attrs), - f - }, - a._engine.rect = function (a, b, c, d, e, f) { - var g = q("rect"); - a.canvas && a.canvas.appendChild(g); - var h = new A(g, a); - return h.attrs = { - x: b, - y: c, - width: d, - height: e, - rx: f || 0, - ry: f || 0, - fill: "none", - stroke: "#000" - }, - h.type = "rect", - q(g, h.attrs), - h - }, - a._engine.ellipse = function (a, b, c, d, e) { - var f = q("ellipse"); - a.canvas && a.canvas.appendChild(f); - var g = new A(f, a); - return g.attrs = { - cx: b, - cy: c, - rx: d, - ry: e, - fill: "none", - stroke: "#000" - }, - g.type = "ellipse", - q(f, g.attrs), - g - }, - a._engine.image = function (a, b, c, d, e, f) { - var g = q("image"); - q(g, { - x: c, - y: d, - width: e, - height: f, - preserveAspectRatio: "none" - }), - g.setAttributeNS(n, "href", b), - a.canvas && a.canvas.appendChild(g); - var h = new A(g, a); - return h.attrs = { - x: c, - y: d, - width: e, - height: f, - src: b - }, - h.type = "image", - h - }, - a._engine.text = function (b, c, d, e) { - var f = q("text"); - b.canvas && b.canvas.appendChild(f); - var g = new A(f, b); - return g.attrs = { - x: c, - y: d, - "text-anchor": "middle", - text: e, - "font-family": a._availableAttrs["font-family"], - "font-size": a._availableAttrs["font-size"], - stroke: "none", - fill: "#000" - }, - g.type = "text", - w(g, g.attrs), - g - }, - a._engine.setSize = function (a, b) { - return this.width = a || this.width, - this.height = b || this.height, - this.canvas.setAttribute("width", this.width), - this.canvas.setAttribute("height", this.height), - this._viewBox && this.setViewBox.apply(this, this._viewBox), - this - }, - a._engine.create = function () { - var b = a._getContainer.apply(0, arguments), - c = b && b.container, - d = b.x, - e = b.y, - f = b.width, - g = b.height; - if (!c) - throw new Error("SVG container not found."); - var h, - i = q("svg"), - j = "overflow:hidden;"; - return d = d || 0, - e = e || 0, - f = f || 512, - g = g || 342, - q(i, { - height: g, - version: 1.1, - width: f, - xmlns: "http://www.w3.org/2000/svg", - "xmlns:xlink": "http://www.w3.org/1999/xlink" - }), - 1 == c ? (i.style.cssText = j + "position:absolute;left:" + d + "px;top:" + e + "px", a._g.doc.body.appendChild(i), h = 1) : (i.style.cssText = j + "position:relative", c.firstChild ? c.insertBefore(i, c.firstChild) : c.appendChild(i)), - c = new a._Paper, - c.width = f, - c.height = g, - c.canvas = i, - c.clear(), - c._left = c._top = 0, - h && (c.renderfix = function () {}), - c.renderfix(), - c - }, - a._engine.setViewBox = function (a, b, c, d, e) { - k("raphael.setViewBox", this, this._viewBox, [a, b, c, d, e]); - var f, - h, - i = this.getSize(), - j = g(c / i.width, d / i.height), - l = this.top, - n = e ? "xMidYMid meet" : "xMinYMin"; - for (null == a ? (this._vbSize && (j = 1), delete this._vbSize, f = "0 0 " + this.width + m + this.height) : (this._vbSize = j, f = a + m + b + m + c + m + d), q(this.canvas, { - viewBox: f, - preserveAspectRatio: n - }); j && l; ) - h = "stroke-width" in l.attrs ? l.attrs["stroke-width"] : 1, l.attr({ - "stroke-width": h - }), l._.dirty = 1, l._.dirtyT = 1, l = l.prev; - return this._viewBox = [a, b, c, d, !!e], - this - }, - a.prototype.renderfix = function () { - var a, - b = this.canvas, - c = b.style; - try { - a = b.getScreenCTM() || b.createSVGMatrix() - } catch (d) { - a = b.createSVGMatrix() - } - var e = -a.e % 1, - f = -a.f % 1; - (e || f) && (e && (this._left = (this._left + e) % 1, c.left = this._left + "px"), f && (this._top = (this._top + f) % 1, c.top = this._top + "px")) - }, - a.prototype.clear = function () { - a.eve("raphael.clear", this); - for (var b = this.canvas; b.firstChild; ) - b.removeChild(b.firstChild); - this.bottom = this.top = null, - (this.desc = q("desc")).appendChild(a._g.doc.createTextNode("Created with Raphaël " + a.version)), - b.appendChild(this.desc), - b.appendChild(this.defs = q("defs")) - }, - a.prototype.remove = function () { - k("raphael.remove", this), - this.canvas.parentNode && this.canvas.parentNode.removeChild(this.canvas); - for (var b in this) - this[b] = "function" == typeof this[b] ? a._removedFactory(b) : null - }; - var C = a.st; - for (var D in B) - B[b](D) && !C[b](D) && (C[D] = function (a) { - return function () { - var b = arguments; - return this.forEach(function (c) { - c[a].apply(c, b) - }) - } - } - (D)) - } -}), function (a, b) { - "function" == typeof define && define.amd ? define("raphael.vml", ["raphael.core"], function (a) { - return b(a) - }) : b("object" == typeof exports ? require("./raphael.core") : a.Raphael) -} -(this, function (a) { - if (!a || a.vml) { - var b = "hasOwnProperty", - c = String, - d = parseFloat, - e = Math, - f = e.round, - g = e.max, - h = e.min, - i = e.abs, - j = "fill", - k = /[, ]+/, - l = a.eve, - m = " progid:DXImageTransform.Microsoft", - n = " ", - o = "", - p = { - M: "m", - L: "l", - C: "c", - Z: "x", - m: "t", - l: "r", - c: "v", - z: "x" - }, - q = /([clmz]),?([^clmz]*)/gi, - r = / progid:\S+Blur\([^\)]+\)/g, - s = /-?[^,\s-]+/g, - t = "position:absolute;left:0;top:0;width:1px;height:1px;behavior:url(#default#VML)", - u = 21600, - v = { - path: 1, - rect: 1, - image: 1 - }, - w = { - circle: 1, - ellipse: 1 - }, - x = function (b) { - var d = /[ahqstv]/gi, - e = a._pathToAbsolute; - if (c(b).match(d) && (e = a._path2curve), d = /[clmz]/g, e == a._pathToAbsolute && !c(b).match(d)) { - var g = c(b).replace(q, function (a, b, c) { - var d = [], - e = "m" == b.toLowerCase(), - g = p[b]; - return c.replace(s, function (a) { - e && 2 == d.length && (g += d + p["m" == b ? "l" : "L"], d = []), - d.push(f(a * u)) - }), - g + d - }); - return g - } - var h, - i, - j = e(b); - g = []; - for (var k = 0, l = j.length; l > k; k++) { - h = j[k], - i = j[k][0].toLowerCase(), - "z" == i && (i = "x"); - for (var m = 1, r = h.length; r > m; m++) - i += f(h[m] * u) + (m != r - 1 ? "," : o); - g.push(i) - } - return g.join(n) - }, - y = function (b, c, d) { - var e = a.matrix(); - return e.rotate(-b, .5, .5), { - dx: e.x(c, d), - dy: e.y(c, d) - } - }, - z = function (a, b, c, d, e, f) { - var g = a._, - h = a.matrix, - k = g.fillpos, - l = a.node, - m = l.style, - o = 1, - p = "", - q = u / b, - r = u / c; - if (m.visibility = "hidden", b && c) { - if (l.coordsize = i(q) + n + i(r), m.rotation = f * (0 > b * c ? -1 : 1), f) { - var s = y(f, d, e); - d = s.dx, - e = s.dy - } - if (0 > b && (p += "x"), 0 > c && (p += " y") && (o = -1), m.flip = p, l.coordorigin = d * -q + n + e * -r, k || g.fillsize) { - var t = l.getElementsByTagName(j); - t = t && t[0], - l.removeChild(t), - k && (s = y(f, h.x(k[0], k[1]), h.y(k[0], k[1])), t.position = s.dx * o + n + s.dy * o), - g.fillsize && (t.size = g.fillsize[0] * i(b) + n + g.fillsize[1] * i(c)), - l.appendChild(t) - } - m.visibility = "visible" - } - }; - a.toString = function () { - return "Your browser doesn’t support SVG. Falling down to VML.\nYou are running Raphaël " + this.version - }; - var A = function (a, b, d) { - for (var e = c(b).toLowerCase().split("-"), f = d ? "end" : "start", g = e.length, h = "classic", i = "medium", j = "medium"; g--; ) - switch (e[g]) { - case "block": - case "classic": - case "oval": - case "diamond": - case "open": - case "none": - h = e[g]; - break; - case "wide": - case "narrow": - j = e[g]; - break; - case "long": - case "short": - i = e[g] - } - var k = a.node.getElementsByTagName("stroke")[0]; - k[f + "arrow"] = h, - k[f + "arrowlength"] = i, - k[f + "arrowwidth"] = j - }, - B = function (e, i) { - e.attrs = e.attrs || {}; - var l = e.node, - m = e.attrs, - p = l.style, - q = v[e.type] && (i.x != m.x || i.y != m.y || i.width != m.width || i.height != m.height || i.cx != m.cx || i.cy != m.cy || i.rx != m.rx || i.ry != m.ry || i.r != m.r), - r = w[e.type] && (m.cx != i.cx || m.cy != i.cy || m.r != i.r || m.rx != i.rx || m.ry != i.ry), - s = e; - for (var t in i) - i[b](t) && (m[t] = i[t]); - if (q && (m.path = a._getPath[e.type](e), e._.dirty = 1), i.href && (l.href = i.href), i.title && (l.title = i.title), i.target && (l.target = i.target), i.cursor && (p.cursor = i.cursor), "blur" in i && e.blur(i.blur), (i.path && "path" == e.type || q) && (l.path = x(~c(m.path).toLowerCase().indexOf("r") ? a._pathToAbsolute(m.path) : m.path), e._.dirty = 1, "image" == e.type && (e._.fillpos = [m.x, m.y], e._.fillsize = [m.width, m.height], z(e, 1, 1, 0, 0, 0))), "transform" in i && e.transform(i.transform), r) { - var y = +m.cx, - B = +m.cy, - D = +m.rx || +m.r || 0, - E = +m.ry || +m.r || 0; - l.path = a.format("ar{0},{1},{2},{3},{4},{1},{4},{1}x", f((y - D) * u), f((B - E) * u), f((y + D) * u), f((B + E) * u), f(y * u)), - e._.dirty = 1 - } - if ("clip-rect" in i) { - var G = c(i["clip-rect"]).split(k); - if (4 == G.length) { - G[2] = +G[2] + +G[0], - G[3] = +G[3] + +G[1]; - var H = l.clipRect || a._g.doc.createElement("div"), - I = H.style; - I.clip = a.format("rect({1}px {2}px {3}px {0}px)", G), - l.clipRect || (I.position = "absolute", I.top = 0, I.left = 0, I.width = e.paper.width + "px", I.height = e.paper.height + "px", l.parentNode.insertBefore(H, l), H.appendChild(l), l.clipRect = H) - } - i["clip-rect"] || l.clipRect && (l.clipRect.style.clip = "auto") - } - if (e.textpath) { - var J = e.textpath.style; - i.font && (J.font = i.font), - i["font-family"] && (J.fontFamily = '"' + i["font-family"].split(",")[0].replace(/^['"]+|['"]+$/g, o) + '"'), - i["font-size"] && (J.fontSize = i["font-size"]), - i["font-weight"] && (J.fontWeight = i["font-weight"]), - i["font-style"] && (J.fontStyle = i["font-style"]) - } - if ("arrow-start" in i && A(s, i["arrow-start"]), "arrow-end" in i && A(s, i["arrow-end"], 1), null != i.opacity || null != i["stroke-width"] || null != i.fill || null != i.src || null != i.stroke || null != i["stroke-width"] || null != i["stroke-opacity"] || null != i["fill-opacity"] || null != i["stroke-dasharray"] || null != i["stroke-miterlimit"] || null != i["stroke-linejoin"] || null != i["stroke-linecap"]) { - var K = l.getElementsByTagName(j), - L = !1; - if (K = K && K[0], !K && (L = K = F(j)), "image" == e.type && i.src && (K.src = i.src), i.fill && (K.on = !0), (null == K.on || "none" == i.fill || null === i.fill) && (K.on = !1), K.on && i.fill) { - var M = c(i.fill).match(a._ISURL); - if (M) { - K.parentNode == l && l.removeChild(K), - K.rotate = !0, - K.src = M[1], - K.type = "tile"; - var N = e.getBBox(1); - K.position = N.x + n + N.y, - e._.fillpos = [N.x, N.y], - a._preload(M[1], function () { - e._.fillsize = [this.offsetWidth, this.offsetHeight] - }) - } else - K.color = a.getRGB(i.fill).hex, K.src = o, K.type = "solid", a.getRGB(i.fill).error && (s.type in { - circle: 1, - ellipse: 1 - } - || "r" != c(i.fill).charAt()) && C(s, i.fill, K) && (m.fill = "none", m.gradient = i.fill, K.rotate = !1) - } - if ("fill-opacity" in i || "opacity" in i) { - var O = ((+m["fill-opacity"] + 1 || 2) - 1) * ((+m.opacity + 1 || 2) - 1) * ((+a.getRGB(i.fill).o + 1 || 2) - 1); - O = h(g(O, 0), 1), - K.opacity = O, - K.src && (K.color = "none") - } - l.appendChild(K); - var P = l.getElementsByTagName("stroke") && l.getElementsByTagName("stroke")[0], - Q = !1; - !P && (Q = P = F("stroke")), - (i.stroke && "none" != i.stroke || i["stroke-width"] || null != i["stroke-opacity"] || i["stroke-dasharray"] || i["stroke-miterlimit"] || i["stroke-linejoin"] || i["stroke-linecap"]) && (P.on = !0), - ("none" == i.stroke || null === i.stroke || null == P.on || 0 == i.stroke || 0 == i["stroke-width"]) && (P.on = !1); - var R = a.getRGB(i.stroke); - P.on && i.stroke && (P.color = R.hex), - O = ((+m["stroke-opacity"] + 1 || 2) - 1) * ((+m.opacity + 1 || 2) - 1) * ((+R.o + 1 || 2) - 1); - var S = .75 * (d(i["stroke-width"]) || 1); - if (O = h(g(O, 0), 1), null == i["stroke-width"] && (S = m["stroke-width"]), i["stroke-width"] && (P.weight = S), S && 1 > S && (O *= S) && (P.weight = 1), P.opacity = O, i["stroke-linejoin"] && (P.joinstyle = i["stroke-linejoin"] || "miter"), P.miterlimit = i["stroke-miterlimit"] || 8, i["stroke-linecap"] && (P.endcap = "butt" == i["stroke-linecap"] ? "flat" : "square" == i["stroke-linecap"] ? "square" : "round"), "stroke-dasharray" in i) { - var T = { - "-": "shortdash", - ".": "shortdot", - "-.": "shortdashdot", - "-..": "shortdashdotdot", - ". ": "dot", - "- ": "dash", - "--": "longdash", - "- .": "dashdot", - "--.": "longdashdot", - "--..": "longdashdotdot" - }; - P.dashstyle = T[b](i["stroke-dasharray"]) ? T[i["stroke-dasharray"]] : o - } - Q && l.appendChild(P) - } - if ("text" == s.type) { - s.paper.canvas.style.display = o; - var U = s.paper.span, - V = 100, - W = m.font && m.font.match(/\d+(?:\.\d*)?(?=px)/); - p = U.style, - m.font && (p.font = m.font), - m["font-family"] && (p.fontFamily = m["font-family"]), - m["font-weight"] && (p.fontWeight = m["font-weight"]), - m["font-style"] && (p.fontStyle = m["font-style"]), - W = d(m["font-size"] || W && W[0]) || 10, - p.fontSize = W * V + "px", - s.textpath.string && (U.innerHTML = c(s.textpath.string).replace(/")); - var X = U.getBoundingClientRect(); - s.W = m.w = (X.right - X.left) / V, - s.H = m.h = (X.bottom - X.top) / V, - s.X = m.x, - s.Y = m.y + s.H / 2, - ("x" in i || "y" in i) && (s.path.v = a.format("m{0},{1}l{2},{1}", f(m.x * u), f(m.y * u), f(m.x * u) + 1)); - for (var Y = ["x", "y", "text", "font", "font-family", "font-weight", "font-style", "font-size"], Z = 0, $ = Y.length; $ > Z; Z++) - if (Y[Z]in i) { - s._.dirty = 1; - break - } - switch (m["text-anchor"]) { - case "start": - s.textpath.style["v-text-align"] = "left", - s.bbx = s.W / 2; - break; - case "end": - s.textpath.style["v-text-align"] = "right", - s.bbx = -s.W / 2; - break; - default: - s.textpath.style["v-text-align"] = "center", - s.bbx = 0 - } - s.textpath.style["v-text-kern"] = !0 - } - }, - C = function (b, f, g) { - b.attrs = b.attrs || {}; - var h = (b.attrs, Math.pow), - i = "linear", - j = ".5 .5"; - if (b.attrs.gradient = f, f = c(f).replace(a._radial_gradient, function (a, b, c) { - return i = "radial", - b && c && (b = d(b), c = d(c), h(b - .5, 2) + h(c - .5, 2) > .25 && (c = e.sqrt(.25 - h(b - .5, 2)) * (2 * (c > .5) - 1) + .5), j = b + n + c), - o - }), f = f.split(/\s*\-\s*/), "linear" == i) { - var k = f.shift(); - if (k = -d(k), isNaN(k)) - return null - } - var l = a._parseDots(f); - if (!l) - return null; - if (b = b.shape || b.node, l.length) { - b.removeChild(g), - g.on = !0, - g.method = "none", - g.color = l[0].color, - g.color2 = l[l.length - 1].color; - for (var m = [], p = 0, q = l.length; q > p; p++) - l[p].offset && m.push(l[p].offset + n + l[p].color); - g.colors = m.length ? m.join() : "0% " + g.color, - "radial" == i ? (g.type = "gradientTitle", g.focus = "100%", g.focussize = "0 0", g.focusposition = j, g.angle = 0) : (g.type = "gradient", g.angle = (270 - k) % 360), - b.appendChild(g) - } - return 1 - }, - D = function (b, c) { - this[0] = this.node = b, - b.raphael = !0, - this.id = a._oid++, - b.raphaelid = this.id, - this.X = 0, - this.Y = 0, - this.attrs = {}, - this.paper = c, - this.matrix = a.matrix(), - this._ = { - transform: [], - sx: 1, - sy: 1, - dx: 0, - dy: 0, - deg: 0, - dirty: 1, - dirtyT: 1 - }, - !c.bottom && (c.bottom = this), - this.prev = c.top, - c.top && (c.top.next = this), - c.top = this, - this.next = null - }, - E = a.el; - D.prototype = E, - E.constructor = D, - E.transform = function (b) { - if (null == b) - return this._.transform; - var d, - e = this.paper._viewBoxShift, - f = e ? "s" + [e.scale, e.scale] + "-1-1t" + [e.dx, e.dy] : o; - e && (d = b = c(b).replace(/\.{3}|\u2026/g, this._.transform || o)), - a._extractTransform(this, f + b); - var g, - h = this.matrix.clone(), - i = this.skew, - j = this.node, - k = ~c(this.attrs.fill).indexOf("-"), - l = !c(this.attrs.fill).indexOf("url("); - if (h.translate(1, 1), l || k || "image" == this.type) - if (i.matrix = "1 0 0 1", i.offset = "0 0", g = h.split(), k && g.noRotation || !g.isSimple) { - j.style.filter = h.toFilter(); - var m = this.getBBox(), - p = this.getBBox(1), - q = m.x - p.x, - r = m.y - p.y; - j.coordorigin = q * -u + n + r * -u, - z(this, 1, 1, q, r, 0) - } else - j.style.filter = o, z(this, g.scalex, g.scaley, g.dx, g.dy, g.rotate); - else - j.style.filter = o, i.matrix = c(h), i.offset = h.offset(); - return null !== d && (this._.transform = d, a._extractTransform(this, d)), - this - }, - E.rotate = function (a, b, e) { - if (this.removed) - return this; - if (null != a) { - if (a = c(a).split(k), a.length - 1 && (b = d(a[1]), e = d(a[2])), a = d(a[0]), null == e && (b = e), null == b || null == e) { - var f = this.getBBox(1); - b = f.x + f.width / 2, - e = f.y + f.height / 2 - } - return this._.dirtyT = 1, - this.transform(this._.transform.concat([["r", a, b, e]])), - this - } - }, - E.translate = function (a, b) { - return this.removed ? this : (a = c(a).split(k), a.length - 1 && (b = d(a[1])), a = d(a[0]) || 0, b = +b || 0, this._.bbox && (this._.bbox.x += a, this._.bbox.y += b), this.transform(this._.transform.concat([["t", a, b]])), this) - }, - E.scale = function (a, b, e, f) { - if (this.removed) - return this; - if (a = c(a).split(k), a.length - 1 && (b = d(a[1]), e = d(a[2]), f = d(a[3]), isNaN(e) && (e = null), isNaN(f) && (f = null)), a = d(a[0]), null == b && (b = a), null == f && (e = f), null == e || null == f) - var g = this.getBBox(1); - return e = null == e ? g.x + g.width / 2 : e, - f = null == f ? g.y + g.height / 2 : f, - this.transform(this._.transform.concat([["s", a, b, e, f]])), - this._.dirtyT = 1, - this - }, - E.hide = function () { - return !this.removed && (this.node.style.display = "none"), - this - }, - E.show = function () { - return !this.removed && (this.node.style.display = o), - this - }, - E.auxGetBBox = a.el.getBBox, - E.getBBox = function () { - var a = this.auxGetBBox(); - if (this.paper && this.paper._viewBoxShift) { - var b = {}, - c = 1 / this.paper._viewBoxShift.scale; - return b.x = a.x - this.paper._viewBoxShift.dx, - b.x *= c, - b.y = a.y - this.paper._viewBoxShift.dy, - b.y *= c, - b.width = a.width * c, - b.height = a.height * c, - b.x2 = b.x + b.width, - b.y2 = b.y + b.height, - b - } - return a - }, - E._getBBox = function () { - return this.removed ? {} - : { - x: this.X + (this.bbx || 0) - this.W / 2, - y: this.Y - this.H, - width: this.W, - height: this.H - } - }, - E.remove = function () { - if (!this.removed && this.node.parentNode) { - this.paper.__set__ && this.paper.__set__.exclude(this), - a.eve.unbind("raphael.*.*." + this.id), - a._tear(this, this.paper), - this.node.parentNode.removeChild(this.node), - this.shape && this.shape.parentNode.removeChild(this.shape); - for (var b in this) - this[b] = "function" == typeof this[b] ? a._removedFactory(b) : null; - this.removed = !0 - } - }, - E.attr = function (c, d) { - if (this.removed) - return this; - if (null == c) { - var e = {}; - for (var f in this.attrs) - this.attrs[b](f) && (e[f] = this.attrs[f]); - return e.gradient && "none" == e.fill && (e.fill = e.gradient) && delete e.gradient, - e.transform = this._.transform, - e - } - if (null == d && a.is(c, "string")) { - if (c == j && "none" == this.attrs.fill && this.attrs.gradient) - return this.attrs.gradient; - for (var g = c.split(k), h = {}, i = 0, m = g.length; m > i; i++) - c = g[i], c in this.attrs ? h[c] = this.attrs[c] : a.is(this.paper.customAttributes[c], "function") ? h[c] = this.paper.customAttributes[c].def : h[c] = a._availableAttrs[c]; - return m - 1 ? h : h[g[0]] - } - if (this.attrs && null == d && a.is(c, "array")) { - for (h = {}, i = 0, m = c.length; m > i; i++) - h[c[i]] = this.attr(c[i]); - return h - } - var n; - null != d && (n = {}, n[c] = d), - null == d && a.is(c, "object") && (n = c); - for (var o in n) - l("raphael.attr." + o + "." + this.id, this, n[o]); - if (n) { - for (o in this.paper.customAttributes) - if (this.paper.customAttributes[b](o) && n[b](o) && a.is(this.paper.customAttributes[o], "function")) { - var p = this.paper.customAttributes[o].apply(this, [].concat(n[o])); - this.attrs[o] = n[o]; - for (var q in p) - p[b](q) && (n[q] = p[q]) - } - n.text && "text" == this.type && (this.textpath.string = n.text), - B(this, n) - } - return this - }, - E.toFront = function () { - return !this.removed && this.node.parentNode.appendChild(this.node), - this.paper && this.paper.top != this && a._tofront(this, this.paper), - this - }, - E.toBack = function () { - return this.removed ? this : (this.node.parentNode.firstChild != this.node && (this.node.parentNode.insertBefore(this.node, this.node.parentNode.firstChild), a._toback(this, this.paper)), this) - }, - E.insertAfter = function (b) { - return this.removed ? this : (b.constructor == a.st.constructor && (b = b[b.length - 1]), b.node.nextSibling ? b.node.parentNode.insertBefore(this.node, b.node.nextSibling) : b.node.parentNode.appendChild(this.node), a._insertafter(this, b, this.paper), this) - }, - E.insertBefore = function (b) { - return this.removed ? this : (b.constructor == a.st.constructor && (b = b[0]), b.node.parentNode.insertBefore(this.node, b.node), a._insertbefore(this, b, this.paper), this) - }, - E.blur = function (b) { - var c = this.node.runtimeStyle, - d = c.filter; - return d = d.replace(r, o), - 0 !== +b ? (this.attrs.blur = b, c.filter = d + n + m + ".Blur(pixelradius=" + (+b || 1.5) + ")", c.margin = a.format("-{0}px 0 0 -{0}px", f(+b || 1.5))) : (c.filter = d, c.margin = 0, delete this.attrs.blur), - this - }, - a._engine.path = function (a, b) { - var c = F("shape"); - c.style.cssText = t, - c.coordsize = u + n + u, - c.coordorigin = b.coordorigin; - var d = new D(c, b), - e = { - fill: "none", - stroke: "#000" - }; - a && (e.path = a), - d.type = "path", - d.path = [], - d.Path = o, - B(d, e), - b.canvas.appendChild(c); - var f = F("skew"); - return f.on = !0, - c.appendChild(f), - d.skew = f, - d.transform(o), - d - }, - a._engine.rect = function (b, c, d, e, f, g) { - var h = a._rectPath(c, d, e, f, g), - i = b.path(h), - j = i.attrs; - return i.X = j.x = c, - i.Y = j.y = d, - i.W = j.width = e, - i.H = j.height = f, - j.r = g, - j.path = h, - i.type = "rect", - i - }, - a._engine.ellipse = function (a, b, c, d, e) { { - var f = a.path(); - f.attrs - } - return f.X = b - d, - f.Y = c - e, - f.W = 2 * d, - f.H = 2 * e, - f.type = "ellipse", - B(f, { - cx: b, - cy: c, - rx: d, - ry: e - }), - f - }, - a._engine.circle = function (a, b, c, d) { { - var e = a.path(); - e.attrs - } - return e.X = b - d, - e.Y = c - d, - e.W = e.H = 2 * d, - e.type = "circle", - B(e, { - cx: b, - cy: c, - r: d - }), - e - }, - a._engine.image = function (b, c, d, e, f, g) { - var h = a._rectPath(d, e, f, g), - i = b.path(h).attr({ - stroke: "none" - }), - k = i.attrs, - l = i.node, - m = l.getElementsByTagName(j)[0]; - return k.src = c, - i.X = k.x = d, - i.Y = k.y = e, - i.W = k.width = f, - i.H = k.height = g, - k.path = h, - i.type = "image", - m.parentNode == l && l.removeChild(m), - m.rotate = !0, - m.src = c, - m.type = "tile", - i._.fillpos = [d, e], - i._.fillsize = [f, g], - l.appendChild(m), - z(i, 1, 1, 0, 0, 0), - i - }, - a._engine.text = function (b, d, e, g) { - var h = F("shape"), - i = F("path"), - j = F("textpath"); - d = d || 0, - e = e || 0, - g = g || "", - i.v = a.format("m{0},{1}l{2},{1}", f(d * u), f(e * u), f(d * u) + 1), - i.textpathok = !0, - j.string = c(g), - j.on = !0, - h.style.cssText = t, - h.coordsize = u + n + u, - h.coordorigin = "0 0"; - var k = new D(h, b), - l = { - fill: "#000", - stroke: "none", - font: a._availableAttrs.font, - text: g - }; - k.shape = h, - k.path = i, - k.textpath = j, - k.type = "text", - k.attrs.text = c(g), - k.attrs.x = d, - k.attrs.y = e, - k.attrs.w = 1, - k.attrs.h = 1, - B(k, l), - h.appendChild(j), - h.appendChild(i), - b.canvas.appendChild(h); - var m = F("skew"); - return m.on = !0, - h.appendChild(m), - k.skew = m, - k.transform(o), - k - }, - a._engine.setSize = function (b, c) { - var d = this.canvas.style; - return this.width = b, - this.height = c, - b == +b && (b += "px"), - c == +c && (c += "px"), - d.width = b, - d.height = c, - d.clip = "rect(0 " + b + " " + c + " 0)", - this._viewBox && a._engine.setViewBox.apply(this, this._viewBox), - this - }, - a._engine.setViewBox = function (b, c, d, e, f) { - a.eve("raphael.setViewBox", this, this._viewBox, [b, c, d, e, f]); - var g, - h, - i = this.getSize(), - j = i.width, - k = i.height; - return f && (g = k / e, h = j / d, j > d * g && (b -= (j - d * g) / 2 / g), k > e * h && (c -= (k - e * h) / 2 / h)), - this._viewBox = [b, c, d, e, !!f], - this._viewBoxShift = { - dx: -b, - dy: -c, - scale: i - }, - this.forEach(function (a) { - a.transform("...") - }), - this - }; - var F; - a._engine.initWin = function (a) { - var b = a.document; - b.styleSheets.length < 31 ? b.createStyleSheet().addRule(".rvml", "behavior:url(#default#VML)") : b.styleSheets[0].addRule(".rvml", "behavior:url(#default#VML)"); - try { - !b.namespaces.rvml && b.namespaces.add("rvml", "urn:schemas-microsoft-com:vml"), - F = function (a) { - return b.createElement("') - } - } catch (c) { - F = function (a) { - return b.createElement("<" + a + ' xmlns="urn:schemas-microsoft.com:vml" class="rvml">') - } - } - }, - a._engine.initWin(a._g.win), - a._engine.create = function () { - var b = a._getContainer.apply(0, arguments), - c = b.container, - d = b.height, - e = b.width, - f = b.x, - g = b.y; - if (!c) - throw new Error("VML container not found."); - var h = new a._Paper, - i = h.canvas = a._g.doc.createElement("div"), - j = i.style; - return f = f || 0, - g = g || 0, - e = e || 512, - d = d || 342, - h.width = e, - h.height = d, - e == +e && (e += "px"), - d == +d && (d += "px"), - h.coordsize = 1e3 * u + n + 1e3 * u, - h.coordorigin = "0 0", - h.span = a._g.doc.createElement("span"), - h.span.style.cssText = "position:absolute;left:-9999em;top:-9999em;padding:0;margin:0;line-height:1;", - i.appendChild(h.span), - j.cssText = a.format("top:0;left:0;width:{0};height:{1};display:inline-block;position:relative;clip:rect(0 {0} {1} 0);overflow:hidden", e, d), - 1 == c ? (a._g.doc.body.appendChild(i), j.left = f + "px", j.top = g + "px", j.position = "absolute") : c.firstChild ? c.insertBefore(i, c.firstChild) : c.appendChild(i), - h.renderfix = function () {}, - h - }, - a.prototype.clear = function () { - a.eve("raphael.clear", this), - this.canvas.innerHTML = o, - this.span = a._g.doc.createElement("span"), - this.span.style.cssText = "position:absolute;left:-9999em;top:-9999em;padding:0;margin:0;line-height:1;display:inline;", - this.canvas.appendChild(this.span), - this.bottom = this.top = null - }, - a.prototype.remove = function () { - a.eve("raphael.remove", this), - this.canvas.parentNode.removeChild(this.canvas); - for (var b in this) - this[b] = "function" == typeof this[b] ? a._removedFactory(b) : null; - return !0 - }; - var G = a.st; - for (var H in E) - E[b](H) && !G[b](H) && (G[H] = function (a) { - return function () { - var b = arguments; - return this.forEach(function (c) { - c[a].apply(c, b) - }) - } - } - (H)) - } -}); -JustGage = function (config) { - var obj = this; - if (config === null || config === undefined) { - console.log('* justgage: Make sure to pass options to the constructor!'); - return false; - } - var node; - if (config.id !== null && config.id !== undefined) { - node = document.getElementById(config.id); - if (!node) { - console.log('* justgage: No element with id : %s found', config.id); - return false; - } - } else if (config.parentNode !== null && config.parentNode !== undefined) { - node = config.parentNode; - } else { - console.log('* justgage: Make sure to pass the existing element id or parentNode to the constructor.'); - return false; - } - var dataset = node.dataset ? node.dataset : {}; - var defaults = (config.defaults !== null && config.defaults !== undefined) ? config.defaults : false; - if (defaults !== false) { - config = extend({}, config, defaults); - delete config.defaults; - } - obj.config = { - id: config.id, - value: kvLookup('value', config, dataset, 0, 'float'), - defaults: kvLookup('defaults', config, dataset, 0, false), - parentNode: kvLookup('parentNode', config, dataset, null), - width: kvLookup('width', config, dataset, null), - height: kvLookup('height', config, dataset, null), - title: kvLookup('title', config, dataset, ""), - titleFontColor: kvLookup('titleFontColor', config, dataset, "#999999"), - titleFontFamily: kvLookup('titleFontFamily', config, dataset, "sans-serif"), - titlePosition: kvLookup('titlePosition', config, dataset, "above"), - valueFontColor: kvLookup('valueFontColor', config, dataset, "#010101"), - valueFontFamily: kvLookup('valueFontFamily', config, dataset, "Arial"), - symbol: kvLookup('symbol', config, dataset, ''), - min: kvLookup('min', config, dataset, 0, 'float'), - max: kvLookup('max', config, dataset, 100, 'float'), - reverse: kvLookup('reverse', config, dataset, false), - humanFriendlyDecimal: kvLookup('humanFriendlyDecimal', config, dataset, 0), - textRenderer: kvLookup('textRenderer', config, dataset, null), - gaugeWidthScale: kvLookup('gaugeWidthScale', config, dataset, 1.0), - gaugeColor: kvLookup('gaugeColor', config, dataset, "#edebeb"), - label: kvLookup('label', config, dataset, ''), - labelFontColor: kvLookup('labelFontColor', config, dataset, "#b3b3b3"), - shadowOpacity: kvLookup('shadowOpacity', config, dataset, 0.2), - shadowSize: kvLookup('shadowSize', config, dataset, 5), - shadowVerticalOffset: kvLookup('shadowVerticalOffset', config, dataset, 3), - levelColors: kvLookup('levelColors', config, dataset, ["#a9d70b", "#f9c802", "#ff0000"], 'array', ','), - startAnimationTime: kvLookup('startAnimationTime', config, dataset, 700), - startAnimationType: kvLookup('startAnimationType', config, dataset, '>'), - refreshAnimationTime: kvLookup('refreshAnimationTime', config, dataset, 700), - refreshAnimationType: kvLookup('refreshAnimationType', config, dataset, '>'), - donutStartAngle: kvLookup('donutStartAngle', config, dataset, 90), - valueMinFontSize: kvLookup('valueMinFontSize', config, dataset, 16), - titleMinFontSize: kvLookup('titleMinFontSize', config, dataset, 10), - labelMinFontSize: kvLookup('labelMinFontSize', config, dataset, 10), - minLabelMinFontSize: kvLookup('minLabelMinFontSize', config, dataset, 10), - maxLabelMinFontSize: kvLookup('maxLabelMinFontSize', config, dataset, 10), - hideValue: kvLookup('hideValue', config, dataset, false), - hideMinMax: kvLookup('hideMinMax', config, dataset, false), - hideInnerShadow: kvLookup('hideInnerShadow', config, dataset, false), - humanFriendly: kvLookup('humanFriendly', config, dataset, false), - noGradient: kvLookup('noGradient', config, dataset, false), - donut: kvLookup('donut', config, dataset, false), - relativeGaugeSize: kvLookup('relativeGaugeSize', config, dataset, false), - counter: kvLookup('counter', config, dataset, false), - decimals: kvLookup('decimals', config, dataset, 0), - customSectors: kvLookup('customSectors', config, dataset, []), - formatNumber: kvLookup('formatNumber', config, dataset, false), - pointer: kvLookup('pointer', config, dataset, false), - pointerOptions: kvLookup('pointerOptions', config, dataset, []) - }; - var - canvasW, - canvasH, - widgetW, - widgetH, - aspect, - dx, - dy, - titleFontSize, - titleX, - titleY, - valueFontSize, - valueX, - valueY, - labelFontSize, - labelX, - labelY, - minFontSize, - minX, - minY, - maxFontSize, - maxX, - maxY; - if (obj.config.value > obj.config.max) - obj.config.value = obj.config.max; - if (obj.config.value < obj.config.min) - obj.config.value = obj.config.min; - obj.originalValue = kvLookup('value', config, dataset, -1, 'float'); - if (obj.config.id !== null && (document.getElementById(obj.config.id)) !== null) { - obj.canvas = Raphael(obj.config.id, "100%", "100%"); - } else if (obj.config.parentNode !== null) { - obj.canvas = Raphael(obj.config.parentNode, "100%", "100%"); - } - if (obj.config.relativeGaugeSize === true) { - obj.canvas.setViewBox(0, 0, 200, 150, true); - } - if (obj.config.relativeGaugeSize === true) { - canvasW = 200; - canvasH = 150; - } else if (obj.config.width !== null && obj.config.height !== null) { - canvasW = obj.config.width; - canvasH = obj.config.height; - } else if (obj.config.parentNode !== null) { - obj.canvas.setViewBox(0, 0, 200, 150, true); - canvasW = 200; - canvasH = 150; - } else { - canvasW = getStyle(document.getElementById(obj.config.id), "width").slice(0, -2) * 1; - canvasH = getStyle(document.getElementById(obj.config.id), "height").slice(0, -2) * 1; - } - if (obj.config.donut === true) { - if (canvasW > canvasH) { - widgetH = canvasH; - widgetW = widgetH; - } else if (canvasW < canvasH) { - widgetW = canvasW; - widgetH = widgetW; - if (widgetH > canvasH) { - aspect = widgetH / canvasH; - widgetH = widgetH / aspect; - widgetW = widgetH / aspect; - } - } else { - widgetW = canvasW; - widgetH = widgetW; - } - dx = (canvasW - widgetW) / 2; - dy = (canvasH - widgetH) / 2; - titleFontSize = ((widgetH / 8) > 10) ? (widgetH / 10) : 10; - titleX = dx + widgetW / 2; - titleY = dy + widgetH / 11; - valueFontSize = ((widgetH / 6.4) > 16) ? (widgetH / 5.4) : 18; - valueX = dx + widgetW / 2; - if (obj.config.label !== '') { - valueY = dy + widgetH / 1.85; - } else { - valueY = dy + widgetH / 1.7; - } - labelFontSize = ((widgetH / 16) > 10) ? (widgetH / 16) : 10; - labelX = dx + widgetW / 2; - labelY = valueY + labelFontSize; - minFontSize = ((widgetH / 16) > 10) ? (widgetH / 16) : 10; - minX = dx + (widgetW / 10) + (widgetW / 6.666666666666667 * obj.config.gaugeWidthScale) / 2; - minY = labelY; - maxFontSize = ((widgetH / 16) > 10) ? (widgetH / 16) : 10; - maxX = dx + widgetW - (widgetW / 10) - (widgetW / 6.666666666666667 * obj.config.gaugeWidthScale) / 2; - maxY = labelY; - } else { - if (canvasW > canvasH) { - widgetH = canvasH; - widgetW = widgetH * 1.25; - if (widgetW > canvasW) { - aspect = widgetW / canvasW; - widgetW = widgetW / aspect; - widgetH = widgetH / aspect; - } - } else if (canvasW < canvasH) { - widgetW = canvasW; - widgetH = widgetW / 1.25; - if (widgetH > canvasH) { - aspect = widgetH / canvasH; - widgetH = widgetH / aspect; - widgetW = widgetH / aspect; - } - } else { - widgetW = canvasW; - widgetH = widgetW * 0.75; - } - dx = (canvasW - widgetW) / 2; - dy = (canvasH - widgetH) / 2; - if (obj.config.titlePosition === 'below') { - dy -= (widgetH / 6.4); - } - titleFontSize = ((widgetH / 8) > obj.config.titleMinFontSize) ? (widgetH / 10) : obj.config.titleMinFontSize; - titleX = dx + widgetW / 2; - titleY = dy + (obj.config.titlePosition === 'below' ? (widgetH * 1.07) : (widgetH / 6.4)); - valueFontSize = ((widgetH / 6.5) > obj.config.valueMinFontSize) ? (widgetH / 6.5) : obj.config.valueMinFontSize; - valueX = dx + widgetW / 2; - valueY = dy + widgetH / 1.275; - labelFontSize = ((widgetH / 16) > obj.config.labelMinFontSize) ? (widgetH / 16) : obj.config.labelMinFontSize; - labelX = dx + widgetW / 2; - labelY = valueY + valueFontSize / 2 + 5; - minFontSize = ((widgetH / 16) > obj.config.minLabelMinFontSize) ? (widgetH / 16) : obj.config.minLabelMinFontSize; - minX = dx + (widgetW / 10) + (widgetW / 6.666666666666667 * obj.config.gaugeWidthScale) / 2; - minY = labelY; - maxFontSize = ((widgetH / 16) > obj.config.maxLabelMinFontSize) ? (widgetH / 16) : obj.config.maxLabelMinFontSize; - maxX = dx + widgetW - (widgetW / 10) - (widgetW / 6.666666666666667 * obj.config.gaugeWidthScale) / 2; - maxY = labelY; - } - obj.params = { - canvasW: canvasW, - canvasH: canvasH, - widgetW: widgetW, - widgetH: widgetH, - dx: dx, - dy: dy, - titleFontSize: titleFontSize, - titleX: titleX, - titleY: titleY, - valueFontSize: valueFontSize, - valueX: valueX, - valueY: valueY, - labelFontSize: labelFontSize, - labelX: labelX, - labelY: labelY, - minFontSize: minFontSize, - minX: minX, - minY: minY, - maxFontSize: maxFontSize, - maxX: maxX, - maxY: maxY - }; - canvasW, - canvasH, - widgetW, - widgetH, - aspect, - dx, - dy, - titleFontSize, - titleX, - titleY, - valueFontSize, - valueX, - valueY, - labelFontSize, - labelX, - labelY, - minFontSize, - minX, - minY, - maxFontSize, - maxX, - maxY = null; - obj.canvas.customAttributes.pki = function (value, min, max, w, h, dx, dy, gws, donut, reverse) { - var alpha, - Ro, - Ri, - Cx, - Cy, - Xo, - Yo, - Xi, - Yi, - path; - if (donut) { - alpha = (1 - 2 * (value - min) / (max - min)) * Math.PI; - Ro = w / 2 - w / 7; - Ri = Ro - w / 6.666666666666667 * gws; - Cx = w / 2 + dx; - Cy = h / 1.95 + dy; - Xo = w / 2 + dx + Ro * Math.cos(alpha); - Yo = h - (h - Cy) - Ro * Math.sin(alpha); - Xi = w / 2 + dx + Ri * Math.cos(alpha); - Yi = h - (h - Cy) - Ri * Math.sin(alpha); - path = "M" + (Cx - Ri) + "," + Cy + " "; - path += "L" + (Cx - Ro) + "," + Cy + " "; - if (value > ((max - min) / 2)) { - path += "A" + Ro + "," + Ro + " 0 0 1 " + (Cx + Ro) + "," + Cy + " "; - } - path += "A" + Ro + "," + Ro + " 0 0 1 " + Xo + "," + Yo + " "; - path += "L" + Xi + "," + Yi + " "; - if (value > ((max - min) / 2)) { - path += "A" + Ri + "," + Ri + " 0 0 0 " + (Cx + Ri) + "," + Cy + " "; - } - path += "A" + Ri + "," + Ri + " 0 0 0 " + (Cx - Ri) + "," + Cy + " "; - path += "Z "; - return { - path: path - }; - } else { - alpha = (1 - (value - min) / (max - min)) * Math.PI; - Ro = w / 2 - w / 10; - Ri = Ro - w / 6.666666666666667 * gws; - Cx = w / 2 + dx; - Cy = h / 1.25 + dy; - Xo = w / 2 + dx + Ro * Math.cos(alpha); - Yo = h - (h - Cy) - Ro * Math.sin(alpha); - Xi = w / 2 + dx + Ri * Math.cos(alpha); - Yi = h - (h - Cy) - Ri * Math.sin(alpha); - path = "M" + (Cx - Ri) + "," + Cy + " "; - path += "L" + (Cx - Ro) + "," + Cy + " "; - path += "A" + Ro + "," + Ro + " 0 0 1 " + Xo + "," + Yo + " "; - path += "L" + Xi + "," + Yi + " "; - path += "A" + Ri + "," + Ri + " 0 0 0 " + (Cx - Ri) + "," + Cy + " "; - path += "Z "; - return { - path: path - }; - } - alpha, - Ro, - Ri, - Cx, - Cy, - Xo, - Yo, - Xi, - Yi, - path = null; - }; - obj.canvas.customAttributes.ndl = function (value, min, max, w, h, dx, dy, gws, donut) { - var dlt = w * 3.5 / 100; - var dlb = w / 15; - var dw = w / 100; - if (obj.config.pointerOptions.toplength != null && obj.config.pointerOptions.toplength != undefined) - dlt = obj.config.pointerOptions.toplength; - if (obj.config.pointerOptions.bottomlength != null && obj.config.pointerOptions.bottomlength != undefined) - dlb = obj.config.pointerOptions.bottomlength; - if (obj.config.pointerOptions.bottomwidth != null && obj.config.pointerOptions.bottomwidth != undefined) - dw = obj.config.pointerOptions.bottomwidth; - var alpha, - Ro, - Ri, - Cx, - Cy, - Xo, - Yo, - Xi, - Yi, - Xc, - Yc, - Xz, - Yz, - Xa, - Ya, - Xb, - Yb, - path; - if (donut) { - alpha = (1 - 2 * (value - min) / (max - min)) * Math.PI; - Ro = w / 2 - w / 7; - Ri = Ro - w / 6.666666666666667 * gws; - Cx = w / 2 + dx; - Cy = h / 1.95 + dy; - Xo = w / 2 + dx + Ro * Math.cos(alpha); - Yo = h - (h - Cy) - Ro * Math.sin(alpha); - Xi = w / 2 + dx + Ri * Math.cos(alpha); - Yi = h - (h - Cy) - Ri * Math.sin(alpha); - Xc = Xo + dlt * Math.cos(alpha); - Yc = Yo - dlt * Math.sin(alpha); - Xz = Xi - dlb * Math.cos(alpha); - Yz = Yi + dlb * Math.sin(alpha); - Xa = Xz + dw * Math.sin(alpha); - Ya = Yz + dw * Math.cos(alpha); - Xb = Xz - dw * Math.sin(alpha); - Yb = Yz - dw * Math.cos(alpha); - path = 'M' + Xa + ',' + Ya + ' '; - path += 'L' + Xb + ',' + Yb + ' '; - path += 'L' + Xc + ',' + Yc + ' '; - path += 'Z '; - return { - path: path - }; - } else { - alpha = (1 - (value - min) / (max - min)) * Math.PI; - Ro = w / 2 - w / 10; - Ri = Ro - w / 6.666666666666667 * gws; - Cx = w / 2 + dx; - Cy = h / 1.25 + dy; - Xo = w / 2 + dx + Ro * Math.cos(alpha); - Yo = h - (h - Cy) - Ro * Math.sin(alpha); - Xi = w / 2 + dx + Ri * Math.cos(alpha); - Yi = h - (h - Cy) - Ri * Math.sin(alpha); - Xc = Xo + dlt * Math.cos(alpha); - Yc = Yo - dlt * Math.sin(alpha); - Xz = Xi - dlb * Math.cos(alpha); - Yz = Yi + dlb * Math.sin(alpha); - Xa = Xz + dw * Math.sin(alpha); - Ya = Yz + dw * Math.cos(alpha); - Xb = Xz - dw * Math.sin(alpha); - Yb = Yz - dw * Math.cos(alpha); - path = 'M' + Xa + ',' + Ya + ' '; - path += 'L' + Xb + ',' + Yb + ' '; - path += 'L' + Xc + ',' + Yc + ' '; - path += 'Z '; - return { - path: path - }; - } - alpha, - Ro, - Ri, - Cx, - Cy, - Xo, - Yo, - Xi, - Yi, - Xc, - Yc, - Xz, - Yz, - Xa, - Ya, - Xb, - Yb, - path = null; - }; - obj.gauge = obj.canvas.path().attr({ - "stroke": "none", - "fill": obj.config.gaugeColor, - pki: [obj.config.max, obj.config.min, obj.config.max, obj.params.widgetW, obj.params.widgetH, obj.params.dx, obj.params.dy, obj.config.gaugeWidthScale, obj.config.donut, obj.config.reverse] - }); - obj.level = obj.canvas.path().attr({ - "stroke": "none", - "fill": getColor(obj.config.value, (obj.config.value - obj.config.min) / (obj.config.max - obj.config.min), obj.config.levelColors, obj.config.noGradient, obj.config.customSectors), - pki: [obj.config.min, obj.config.min, obj.config.max, obj.params.widgetW, obj.params.widgetH, obj.params.dx, obj.params.dy, obj.config.gaugeWidthScale, obj.config.donut, obj.config.reverse] - }); - if (obj.config.donut) { - obj.level.transform("r" + obj.config.donutStartAngle + ", " + (obj.params.widgetW / 2 + obj.params.dx) + ", " + (obj.params.widgetH / 1.95 + obj.params.dy)); - } - if (obj.config.pointer) { - obj.needle = obj.canvas.path().attr({ - "stroke": (obj.config.pointerOptions.stroke !== null && obj.config.pointerOptions.stroke !== undefined) ? obj.config.pointerOptions.stroke : "none", - "stroke-width": (obj.config.pointerOptions.stroke_width !== null && obj.config.pointerOptions.stroke_width !== undefined) ? obj.config.pointerOptions.stroke_width : 0, - "stroke-linecap": (obj.config.pointerOptions.stroke_linecap !== null && obj.config.pointerOptions.stroke_linecap !== undefined) ? obj.config.pointerOptions.stroke_linecap : "square", - "fill": (obj.config.pointerOptions.color !== null && obj.config.pointerOptions.color !== undefined) ? obj.config.pointerOptions.color : "#000000", - ndl: [obj.config.min, obj.config.min, obj.config.max, obj.params.widgetW, obj.params.widgetH, obj.params.dx, obj.params.dy, obj.config.gaugeWidthScale, obj.config.donut] - }); - if (obj.config.donut) { - obj.needle.transform("r" + obj.config.donutStartAngle + ", " + (obj.params.widgetW / 2 + obj.params.dx) + ", " + (obj.params.widgetH / 1.95 + obj.params.dy)); - } - } - obj.txtTitle = obj.canvas.text(obj.params.titleX, obj.params.titleY, obj.config.title); - obj.txtTitle.attr({ - "font-size": obj.params.titleFontSize, - "font-weight": "bold", - "font-family": obj.config.titleFontFamily, - "fill": obj.config.titleFontColor, - "fill-opacity": "1" - }); - setDy(obj.txtTitle, obj.params.titleFontSize, obj.params.titleY); - obj.txtValue = obj.canvas.text(obj.params.valueX, obj.params.valueY, 0); - obj.txtValue.attr({ - "font-size": obj.params.valueFontSize, - "font-weight": "bold", - "font-family": obj.config.valueFontFamily, - "fill": obj.config.valueFontColor, - "fill-opacity": "0" - }); - setDy(obj.txtValue, obj.params.valueFontSize, obj.params.valueY); - obj.txtLabel = obj.canvas.text(obj.params.labelX, obj.params.labelY, obj.config.label); - obj.txtLabel.attr({ - "font-size": obj.params.labelFontSize, - "font-weight": "normal", - "font-family": "Arial", - "fill": obj.config.labelFontColor, - "fill-opacity": "0" - }); - setDy(obj.txtLabel, obj.params.labelFontSize, obj.params.labelY); - var min = obj.config.min; - if (obj.config.reverse) { - min = obj.config.max; - } - obj.txtMinimum = min; - if (obj.config.humanFriendly) { - obj.txtMinimum = humanFriendlyNumber(min, obj.config.humanFriendlyDecimal); - } else if (obj.config.formatNumber) { - obj.txtMinimum = formatNumber(min); - } - obj.txtMin = obj.canvas.text(obj.params.minX, obj.params.minY, obj.txtMinimum); - obj.txtMin.attr({ - "font-size": obj.params.minFontSize, - "font-weight": "normal", - "font-family": "Arial", - "fill": obj.config.labelFontColor, - "fill-opacity": (obj.config.hideMinMax || obj.config.donut) ? "0" : "1" - }); - setDy(obj.txtMin, obj.params.minFontSize, obj.params.minY); - var max = obj.config.max; - if (obj.config.reverse) { - max = obj.config.min; - } - obj.txtMaximum = max; - if (obj.config.humanFriendly) { - obj.txtMaximum = humanFriendlyNumber(max, obj.config.humanFriendlyDecimal); - } else if (obj.config.formatNumber) { - obj.txtMaximum = formatNumber(max); - } - obj.txtMax = obj.canvas.text(obj.params.maxX, obj.params.maxY, obj.txtMaximum); - obj.txtMax.attr({ - "font-size": obj.params.maxFontSize, - "font-weight": "normal", - "font-family": "Arial", - "fill": obj.config.labelFontColor, - "fill-opacity": (obj.config.hideMinMax || obj.config.donut) ? "0" : "1" - }); - setDy(obj.txtMax, obj.params.maxFontSize, obj.params.maxY); - var defs = obj.canvas.canvas.childNodes[1]; - var svg = "http://www.w3.org/2000/svg"; - if (ie !== 'undefined' && ie < 9) {} - else if (ie !== 'undefined') { - onCreateElementNsReady(function () { - obj.generateShadow(svg, defs); - }); - } else { - obj.generateShadow(svg, defs); - } - defs, - svg = null; - if (obj.config.textRenderer) { - obj.originalValue = obj.config.textRenderer(obj.originalValue); - } else if (obj.config.humanFriendly) { - obj.originalValue = humanFriendlyNumber(obj.originalValue, obj.config.humanFriendlyDecimal) + obj.config.symbol; - } else if (obj.config.formatNumber) { - obj.originalValue = formatNumber(obj.originalValue) + obj.config.symbol; - } else { - obj.originalValue = (obj.originalValue * 1).toFixed(obj.config.decimals) + obj.config.symbol; - } - if (obj.config.counter === true) { - eve.on("raphael.anim.frame." + (obj.level.id), function () { - var currentValue = obj.level.attr("pki")[0]; - if (obj.config.reverse) { - currentValue = (obj.config.max * 1) + (obj.config.min * 1) - (obj.level.attr("pki")[0] * 1); - } - if (obj.config.textRenderer) { - obj.txtValue.attr("text", obj.config.textRenderer(Math.floor(currentValue))); - } else if (obj.config.humanFriendly) { - obj.txtValue.attr("text", humanFriendlyNumber(Math.floor(currentValue), obj.config.humanFriendlyDecimal) + obj.config.symbol); - } else if (obj.config.formatNumber) { - obj.txtValue.attr("text", formatNumber(Math.floor(currentValue)) + obj.config.symbol); - } else { - obj.txtValue.attr("text", (currentValue * 1).toFixed(obj.config.decimals) + obj.config.symbol); - } - setDy(obj.txtValue, obj.params.valueFontSize, obj.params.valueY); - currentValue = null; - }); - eve.on("raphael.anim.finish." + (obj.level.id), function () { - obj.txtValue.attr({ - "text": obj.originalValue - }); - setDy(obj.txtValue, obj.params.valueFontSize, obj.params.valueY); - }); - } else { - eve.on("raphael.anim.start." + (obj.level.id), function () { - obj.txtValue.attr({ - "text": obj.originalValue - }); - setDy(obj.txtValue, obj.params.valueFontSize, obj.params.valueY); - }); - } - var rvl = obj.config.value; - if (obj.config.reverse) { - rvl = (obj.config.max * 1) + (obj.config.min * 1) - (obj.config.value * 1); - } - obj.level.animate({ - pki: [rvl, obj.config.min, obj.config.max, obj.params.widgetW, obj.params.widgetH, obj.params.dx, obj.params.dy, obj.config.gaugeWidthScale, obj.config.donut, obj.config.reverse] - }, obj.config.startAnimationTime, obj.config.startAnimationType); - if (obj.config.pointer) { - obj.needle.animate({ - ndl: [rvl, obj.config.min, obj.config.max, obj.params.widgetW, obj.params.widgetH, obj.params.dx, obj.params.dy, obj.config.gaugeWidthScale, obj.config.donut] - }, obj.config.startAnimationTime, obj.config.startAnimationType); - } - obj.txtValue.animate({ - "fill-opacity": (obj.config.hideValue) ? "0" : "1" - }, obj.config.startAnimationTime, obj.config.startAnimationType); - obj.txtLabel.animate({ - "fill-opacity": "1" - }, obj.config.startAnimationTime, obj.config.startAnimationType); -}; -JustGage.prototype.refresh = function (val, max) { - var obj = this; - var displayVal, - color, - max = max || null; - if (max !== null) { - obj.config.max = max; - obj.txtMaximum = obj.config.max; - if (obj.config.humanFriendly) { - obj.txtMaximum = humanFriendlyNumber(obj.config.max, obj.config.humanFriendlyDecimal); - } else if (obj.config.formatNumber) { - obj.txtMaximum = formatNumber(obj.config.max); - } - if (!obj.config.reverse) { - obj.txtMax.attr({ - "text": obj.txtMaximum - }); - setDy(obj.txtMax, obj.params.maxFontSize, obj.params.maxY); - } else { - obj.txtMin.attr({ - "text": obj.txtMaximum - }); - setDy(obj.txtMin, obj.params.minFontSize, obj.params.minY); - } - } - displayVal = val; - if ((val * 1) > (obj.config.max * 1)) { - val = (obj.config.max * 1); - } - if ((val * 1) < (obj.config.min * 1)) { - val = (obj.config.min * 1); - } - color = getColor(val, (val - obj.config.min) / (obj.config.max - obj.config.min), obj.config.levelColors, obj.config.noGradient, obj.config.customSectors); - if (obj.config.textRenderer) { - displayVal = obj.config.textRenderer(displayVal); - } else if (obj.config.humanFriendly) { - displayVal = humanFriendlyNumber(displayVal, obj.config.humanFriendlyDecimal) + obj.config.symbol; - } else if (obj.config.formatNumber) { - displayVal = formatNumber((displayVal * 1).toFixed(obj.config.decimals)) + obj.config.symbol; - } else { - displayVal = (displayVal * 1).toFixed(obj.config.decimals) + obj.config.symbol; - } - obj.originalValue = displayVal; - obj.config.value = val * 1; - if (!obj.config.counter) { - obj.txtValue.attr({ - "text": displayVal - }); - setDy(obj.txtValue, obj.params.valueFontSize, obj.params.valueY); - } - var rvl = obj.config.value; - if (obj.config.reverse) { - rvl = (obj.config.max * 1) + (obj.config.min * 1) - (obj.config.value * 1); - } - obj.level.animate({ - pki: [rvl, obj.config.min, obj.config.max, obj.params.widgetW, obj.params.widgetH, obj.params.dx, obj.params.dy, obj.config.gaugeWidthScale, obj.config.donut, obj.config.reverse], - "fill": color - }, obj.config.refreshAnimationTime, obj.config.refreshAnimationType); - if (obj.config.pointer) { - obj.needle.animate({ - ndl: [rvl, obj.config.min, obj.config.max, obj.params.widgetW, obj.params.widgetH, obj.params.dx, obj.params.dy, obj.config.gaugeWidthScale, obj.config.donut] - }, obj.config.refreshAnimationTime, obj.config.refreshAnimationType); - } - obj, - displayVal, - color, - max = null; -}; -JustGage.prototype.generateShadow = function (svg, defs) { - var obj = this; - var sid = "inner-shadow-" + obj.config.id; - var gaussFilter, - feOffset, - feGaussianBlur, - feComposite1, - feFlood, - feComposite2, - feComposite3; - gaussFilter = document.createElementNS(svg, "filter"); - gaussFilter.setAttribute("id", sid); - defs.appendChild(gaussFilter); - feOffset = document.createElementNS(svg, "feOffset"); - feOffset.setAttribute("dx", 0); - feOffset.setAttribute("dy", obj.config.shadowVerticalOffset); - gaussFilter.appendChild(feOffset); - feGaussianBlur = document.createElementNS(svg, "feGaussianBlur"); - feGaussianBlur.setAttribute("result", "offset-blur"); - feGaussianBlur.setAttribute("stdDeviation", obj.config.shadowSize); - gaussFilter.appendChild(feGaussianBlur); - feComposite1 = document.createElementNS(svg, "feComposite"); - feComposite1.setAttribute("operator", "out"); - feComposite1.setAttribute("in", "SourceGraphic"); - feComposite1.setAttribute("in2", "offset-blur"); - feComposite1.setAttribute("result", "inverse"); - gaussFilter.appendChild(feComposite1); - feFlood = document.createElementNS(svg, "feFlood"); - feFlood.setAttribute("flood-color", "black"); - feFlood.setAttribute("flood-opacity", obj.config.shadowOpacity); - feFlood.setAttribute("result", "color"); - gaussFilter.appendChild(feFlood); - feComposite2 = document.createElementNS(svg, "feComposite"); - feComposite2.setAttribute("operator", "in"); - feComposite2.setAttribute("in", "color"); - feComposite2.setAttribute("in2", "inverse"); - feComposite2.setAttribute("result", "shadow"); - gaussFilter.appendChild(feComposite2); - feComposite3 = document.createElementNS(svg, "feComposite"); - feComposite3.setAttribute("operator", "over"); - feComposite3.setAttribute("in", "shadow"); - feComposite3.setAttribute("in2", "SourceGraphic"); - gaussFilter.appendChild(feComposite3); - if (!obj.config.hideInnerShadow) { - obj.canvas.canvas.childNodes[2].setAttribute("filter", "url(#" + sid + ")"); - obj.canvas.canvas.childNodes[3].setAttribute("filter", "url(#" + sid + ")"); - } - gaussFilter, - feOffset, - feGaussianBlur, - feComposite1, - feFlood, - feComposite2, - feComposite3 = null; -}; -function kvLookup(key, tablea, tableb, defval, datatype, delimiter) { - var val = defval; - var canConvert = false; - if (!(key === null || key === undefined)) { - if (tableb !== null && tableb !== undefined && typeof tableb === "object" && key in tableb) { - val = tableb[key]; - canConvert = true; - } else if (tablea !== null && tablea !== undefined && typeof tablea === "object" && key in tablea) { - val = tablea[key]; - canConvert = true; - } else { - val = defval; - } - if (canConvert === true) { - if (datatype !== null && datatype !== undefined) { - switch (datatype) { - case 'int': - val = parseInt(val, 10); - break; - case 'float': - val = parseFloat(val); - break; - default: - break; - } - } - } - } - return val; -}; -function getColor(val, pct, col, noGradient, custSec) { - var no, - inc, - colors, - percentage, - rval, - gval, - bval, - lower, - upper, - range, - rangePct, - pctLower, - pctUpper, - color; - var noGradient = noGradient || custSec.length > 0; - if (custSec.length > 0) { - for (var i = 0; i < custSec.length; i++) { - if (val > custSec[i].lo && val <= custSec[i].hi) { - return custSec[i].color; - } - } - } - no = col.length; - if (no === 1) - return col[0]; - inc = (noGradient) ? (1 / no) : (1 / (no - 1)); - colors = []; - for (i = 0; i < col.length; i++) { - percentage = (noGradient) ? (inc * (i + 1)) : (inc * i); - rval = parseInt((cutHex(col[i])).substring(0, 2), 16); - gval = parseInt((cutHex(col[i])).substring(2, 4), 16); - bval = parseInt((cutHex(col[i])).substring(4, 6), 16); - colors[i] = { - pct: percentage, - color: { - r: rval, - g: gval, - b: bval - } - }; - } - if (pct === 0) { - return 'rgb(' + [colors[0].color.r, colors[0].color.g, colors[0].color.b].join(',') + ')'; - } - for (var j = 0; j < colors.length; j++) { - if (pct <= colors[j].pct) { - if (noGradient) { - return 'rgb(' + [colors[j].color.r, colors[j].color.g, colors[j].color.b].join(',') + ')'; - } else { - lower = colors[j - 1]; - upper = colors[j]; - range = upper.pct - lower.pct; - rangePct = (pct - lower.pct) / range; - pctLower = 1 - rangePct; - pctUpper = rangePct; - color = { - r: Math.floor(lower.color.r * pctLower + upper.color.r * pctUpper), - g: Math.floor(lower.color.g * pctLower + upper.color.g * pctUpper), - b: Math.floor(lower.color.b * pctLower + upper.color.b * pctUpper) - }; - return 'rgb(' + [color.r, color.g, color.b].join(',') + ')'; - } - } - } -} -function setDy(elem, fontSize, txtYpos) { - if ((!ie || ie > 9) && elem.node.firstChild.attributes.dy) { - elem.node.firstChild.attributes.dy.value = 0; - } -} -function getRandomInt(min, max) { - return Math.floor(Math.random() * (max - min + 1)) + min; -} -function cutHex(str) { - return (str.charAt(0) == "#") ? str.substring(1, 7) : str; -} -function humanFriendlyNumber(n, d) { - var p, - d2, - i, - s; - p = Math.pow; - d2 = p(10, d); - i = 7; - while (i) { - s = p(10, i-- * 3); - if (s <= n) { - n = Math.round(n * d2 / s) / d2 + "KMGTPE"[i]; - } - } - return n; -} -function formatNumber(x) { - var parts = x.toString().split("."); - parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ","); - return parts.join("."); -} -function getStyle(oElm, strCssRule) { - var strValue = ""; - if (document.defaultView && document.defaultView.getComputedStyle) { - strValue = document.defaultView.getComputedStyle(oElm, "").getPropertyValue(strCssRule); - } else if (oElm.currentStyle) { - strCssRule = strCssRule.replace(/\-(\w)/g, function (strMatch, p1) { - return p1.toUpperCase(); - }); - strValue = oElm.currentStyle[strCssRule]; - } - return strValue; -} -function onCreateElementNsReady(func) { - if (document.createElementNS !== undefined) { - func(); - } else { - setTimeout(function () { - onCreateElementNsReady(func); - }, 100); - } -} -var ie = (function () { - var undef, - v = 3, - div = document.createElement('div'), - all = div.getElementsByTagName('i'); - while (div.innerHTML = '', all[0]); - return v > 4 ? v : undef; -} - ()); -function extend(out) { - out = out || {}; - for (var i = 1; i < arguments.length; i++) { - if (!arguments[i]) - continue; - for (var key in arguments[i]) { - if (arguments[i].hasOwnProperty(key)) - out[key] = arguments[i][key]; - } - } - return out; -}; diff --git a/examples/SmartSwitch/data_src/js_css_src/js-time-picker/1-inline.html b/examples/SmartSwitch/data_src/js_css_src/js-time-picker/1-inline.html deleted file mode 100644 index 22160e924..000000000 --- a/examples/SmartSwitch/data_src/js_css_src/js-time-picker/1-inline.html +++ /dev/null @@ -1,30 +0,0 @@ - - - - Inline Timepicker Example - - - - - - -

Inline Time Picker

- -
TIME ON
-
-
TIME OFF
- - - - - \ No newline at end of file diff --git a/examples/SmartSwitch/data_src/js_css_src/js-time-picker/2-popup.html b/examples/SmartSwitch/data_src/js_css_src/js-time-picker/2-popup.html deleted file mode 100644 index 162339a50..000000000 --- a/examples/SmartSwitch/data_src/js_css_src/js-time-picker/2-popup.html +++ /dev/null @@ -1,27 +0,0 @@ - - - - Popup Timeicker Example - - - - - - -

Popup Time Picker

- - - ON/OFF -

Line

- - - - - \ No newline at end of file diff --git a/examples/SmartSwitch/data_src/js_css_src/js-time-picker/README.txt b/examples/SmartSwitch/data_src/js_css_src/js-time-picker/README.txt deleted file mode 100644 index b09dd21f3..000000000 --- a/examples/SmartSwitch/data_src/js_css_src/js-time-picker/README.txt +++ /dev/null @@ -1,29 +0,0 @@ -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -LICENSE -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - -Copyright 2018 by Code Boxx - -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: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -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. - - -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -MORE -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -Please visit https://code-boxx.com/ for more! \ No newline at end of file diff --git a/examples/SmartSwitch/data_src/js_css_src/js-time-picker/tpick-light-pop.css b/examples/SmartSwitch/data_src/js_css_src/js-time-picker/tpick-light-pop.css deleted file mode 100644 index cacbdb365..000000000 --- a/examples/SmartSwitch/data_src/js_css_src/js-time-picker/tpick-light-pop.css +++ /dev/null @@ -1,65 +0,0 @@ -/* [CONTAINER] */ -.tpop { - position: fixed; - top: 0; - left: 0; - width: 100%; - height: 100vh; - background: rgba(0, 0, 0, 0.7); - transition: all 0.5s; - visibility: hidden; - opacity: 0; -} -.tpop.show { - visibility: visible; - opacity: 1; -} -.tpicker { - background: #f2f2f2; - padding: 10px; - width: 100%; - max-width: 320px; - white-space: nowrap; - font-size: 32px; - font-weight: bold; - text-align: center; -} -.tpop .tpicker { - margin: 20px auto 0 auto; -} - -/* [HR + MIN + AM/PM] */ -.tpicker-h, .tpicker-m, .tpicker-ap { - display: inline-block; - width: 30%; -} -.tpicker input[type=text] { - box-sizing: border-box; - width: 70%; - padding: 10px; - margin: 5px 0; - border: 0; - background: #fff; - color: #888; - text-align: center; - font-size: 28px; -} -.tpicker-up, .tpicker-down { - text-align: center; - color: #ff853f; - cursor: pointer; -} - -/* [CANCEL + OK BUTTON] */ -.tpicker-btn { - margin-top: 10px; -} -.tpicker-btn input[type=button] { - width: 50%; - padding: 10px 0; - border: 0; - background: #a83a0b; - color: #fff; - font-size: 20px; - cursor: pointer; -} \ No newline at end of file diff --git a/examples/SmartSwitch/data_src/js_css_src/js-time-picker/tpick-light.css b/examples/SmartSwitch/data_src/js_css_src/js-time-picker/tpick-light.css deleted file mode 100644 index 58676b4ff..000000000 --- a/examples/SmartSwitch/data_src/js_css_src/js-time-picker/tpick-light.css +++ /dev/null @@ -1,47 +0,0 @@ -/* [CONTAINER] */ -.tpicker { - background: #f2f2f2; - padding: 10px; - width: 100%; - max-width: 320px; - white-space: nowrap; - font-size: 32px; - font-weight: bold; - text-align: center; -} - -/* [HR + MIN + AM/PM] */ -.tpicker-h, .tpicker-m, .tpicker-ap { - display: inline-block; - width: 30%; -} -.tpicker input[type=text] { - box-sizing: border-box; - width: 70%; - padding: 10px; - margin: 5px 0; - border: 0; - background: #fff; - color: #888; - text-align: center; - font-size: 28px; -} -.tpicker-up, .tpicker-down { - text-align: center; - color: #ff853f; - cursor: pointer; -} - -/* [CANCEL + OK BUTTON] */ -.tpicker-btn { - margin-top: 10px; -} -.tpicker-btn input[type=button] { - width: 50%; - padding: 10px 0; - border: 0; - background: #a83a0b; - color: #fff; - font-size: 20px; - cursor: pointer; -} \ No newline at end of file diff --git a/examples/SmartSwitch/data_src/js_css_src/js-time-picker/tpick-pop.js b/examples/SmartSwitch/data_src/js_css_src/js-time-picker/tpick-pop.js deleted file mode 100644 index c52a2da5b..000000000 --- a/examples/SmartSwitch/data_src/js_css_src/js-time-picker/tpick-pop.js +++ /dev/null @@ -1,136 +0,0 @@ -var tpick = { - attach : function (target) { - // attach() : attach time picker to target - - // Generate a unique random ID for the time picker - var uniqueID = 0; - while (document.getElementById("tpick-" + uniqueID) != null) { - uniqueID = Math.floor(Math.random() * (100 - 2)) + 1; - } - - // Create wrapper - var tw = document.createElement("div"); - tw.id = "tpick-" + uniqueID; - tw.classList.add("tpop"); - tw.dataset.target = target; - tw.addEventListener("click", function (evt) { - if (evt.target.classList.contains("tpop")) { - this.classList.remove("show"); - } - }); - - // Create new time picker - var tp = document.createElement("div"); - tp.classList.add("tpicker"); - - // Create hour picker - tp.appendChild(this.draw("h")); - tp.appendChild(this.draw("m")); - tp.appendChild(this.draw("ap")); - - // OK button - var bottom = document.createElement("div"), - ok = document.createElement("input"); - ok.setAttribute("type", "button"); - ok.value = "OK"; - ok.addEventListener("click", function(){ tpick.set(this); }); - bottom.classList.add("tpicker-btn"); - bottom.appendChild(ok); - tp.appendChild(bottom); - - // Attach time picker to body - tw.appendChild(tp); - document.body.appendChild(tw); - - // Attach on focus event - var target = document.getElementById(target); - target.dataset.dp = uniqueID; - target.onfocus = function () { - document.getElementById("tpick-" + this.dataset.dp).classList.add("show"); - }; - }, - - draw : function (type) { - // draw() : support function to create the hr, min, am/pm selector - - // Create the controls - var docket = document.createElement("div"), - up = document.createElement("div"), - down = document.createElement("div"), - text = document.createElement("input"); - docket.classList.add("tpicker-" + type); - up.classList.add("tpicker-up"); - down.classList.add("tpicker-down"); - up.innerHTML = "︿"; - down.innerHTML = "﹀"; - text.readOnly = true; - text.setAttribute("type", "text"); - - // Default values + click event - // You can do your own modifications here - if (type=="h") { - text.value = "12"; - up.addEventListener("click", function(){ tpick.spin("h", 1, this); }); - down.addEventListener("click", function(){ tpick.spin("h", 0, this); }); - } else if (type=="m") { - text.value = "10"; - up.addEventListener("click", function(){ tpick.spin("m", 1, this); }); - down.addEventListener("click", function(){ tpick.spin("m", 0, this); }); - } else { - text.value = "AM"; - up.addEventListener("click", function(){ tpick.spin("ap", 1, this); }); - down.addEventListener("click", function(){ tpick.spin("ap", 0, this); }); - } - - // Complete + return the docket - docket.appendChild(up); - docket.appendChild(text); - docket.appendChild(down); - return docket; - }, - - spin : function (type, direction, el) { - // spin() : when the up/down button is pressed - - // Get current field + value - var parent = el.parentElement, - field = parent.getElementsByTagName("input")[0], - value = field.value; - - // Spin it - if (type=="h") { - value = parseInt(value); - if (direction) { value++; } else { value--; } - if (value==0) { value = 12; } - else if (value>12) { value = 1; } - } else if (type=="m") { - value = parseInt(value); - if (direction) { value+=5; } else { value-=5; } - if (value<0) { value = 55; } - else if (value>60) { value = 0; } - if (value<10) { value = "0" + value; } - } - else { - value = value=="PM" ? "AM" : "PM"; - } - field.value = value; - }, - - set : function (el) { - // set() : set the selected time on the target - - // Get the parent container - var parent = el.parentElement; - while (parent.classList.contains("tpop") == false) { - parent = parent.parentElement; - } - - // Formulate + set selected time - var input = parent.querySelectorAll("input[type=text]"); - var time = input[0].value + ":" + input[1].value + " " + input[2].value; - document.getElementById(parent.dataset.target).value = time; - - // Close popup - parent.classList.remove("show"); - } -}; \ No newline at end of file diff --git a/examples/SmartSwitch/data_src/js_css_src/js-time-picker/tpick.js b/examples/SmartSwitch/data_src/js_css_src/js-time-picker/tpick.js deleted file mode 100644 index 799142c30..000000000 --- a/examples/SmartSwitch/data_src/js_css_src/js-time-picker/tpick.js +++ /dev/null @@ -1,116 +0,0 @@ -var tpick = { - attach : function (container, target) { - // attach() : attach time picker to target - - // Generate a unique random ID for the time picker - var uniqueID = 0; - while (document.getElementById("tpick-" + uniqueID) != null) { - uniqueID = Math.floor(Math.random() * (100 - 2)) + 1; - } - - // Create new time picker - var tp = document.createElement("div"); - tp.id = "tpick-" + uniqueID; - tp.dataset.target = target; - tp.classList.add("tpicker"); - - // Create hour picker - tp.appendChild(this.draw("h")); - tp.appendChild(this.draw("m")); - tp.appendChild(this.draw("ap")); - - // OK button - var bottom = document.createElement("div"), - ok = document.createElement("input"); - ok.setAttribute("type", "button"); - ok.value = "OK"; - ok.addEventListener("click", function(){ tpick.set(this); }); - bottom.classList.add("tpicker-btn"); - bottom.appendChild(ok); - tp.appendChild(bottom); - - // Attach time picker to target container - document.getElementById(container).appendChild(tp); - }, - - draw : function (type) { - // draw() : support function to create the hr, min, am/pm selector - - // Create the controls - var docket = document.createElement("div"), - up = document.createElement("div"), - down = document.createElement("div"), - text = document.createElement("input"); - docket.classList.add("tpicker-" + type); - up.classList.add("tpicker-up"); - down.classList.add("tpicker-down"); - up.innerHTML = "︿"; - down.innerHTML = "﹀"; - text.readOnly = true; - text.setAttribute("type", "text"); - - // Default values + click event - // You can do your own modifications here - if (type=="h") { - text.value = "12"; - up.addEventListener("click", function(){ tpick.spin("h", 1, this); }); - down.addEventListener("click", function(){ tpick.spin("h", 0, this); }); - } else if (type=="m") { - text.value = "10"; - up.addEventListener("click", function(){ tpick.spin("m", 1, this); }); - down.addEventListener("click", function(){ tpick.spin("m", 0, this); }); - } else { - text.value = "AM"; - up.addEventListener("click", function(){ tpick.spin("ap", 1, this); }); - down.addEventListener("click", function(){ tpick.spin("ap", 0, this); }); - } - - // Complete + return the docket - docket.appendChild(up); - docket.appendChild(text); - docket.appendChild(down); - return docket; - }, - - spin : function (type, direction, el) { - // spin() : when the up/down button is pressed - - // Get current field + value - var parent = el.parentElement, - field = parent.getElementsByTagName("input")[0], - value = field.value; - - // Spin it - if (type=="h") { - value = parseInt(value); - if (direction) { value++; } else { value--; } - if (value==0) { value = 12; } - else if (value>12) { value = 1; } - } else if (type=="m") { - value = parseInt(value); - if (direction) { value+=5; } else { value-=5; } - if (value<0) { value = 55; } - else if (value>60) { value = 0; } - if (value<10) { value = "0" + value; } - } - else { - value = value=="PM" ? "AM" : "PM"; - } - field.value = value; - }, - - set : function (el) { - // set() : set the selected time on the target - - // Get the parent container - var parent = el.parentElement; - while (parent.classList.contains("tpicker") == false) { - parent = parent.parentElement; - } - - // Formulate + set selected time - var input = parent.querySelectorAll("input[type=text]"); - var time = input[0].value + ":" + input[1].value + " " + input[2].value; - document.getElementById(parent.dataset.target).value = time; - } -}; \ No newline at end of file diff --git a/examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/auto-adjust.htm b/examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/auto-adjust.htm deleted file mode 100644 index 28903cfaa..000000000 --- a/examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/auto-adjust.htm +++ /dev/null @@ -1,94 +0,0 @@ - - - - - Auto-adjust - - - - - - -
-
-
-
-

- JustGage auto-adjusts to the size of containing element. And to the screen zoom level. And screen density. Nice. This means you’ll get clean, sharp and nice looking gauge at all times. Try zooming the page to see the results. -

- - - - - - diff --git a/examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/counter.html b/examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/counter.html deleted file mode 100644 index 406959395..000000000 --- a/examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/counter.html +++ /dev/null @@ -1,58 +0,0 @@ - - - - - - Counter - - - - - - - - - - - - diff --git a/examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/custom-interval.htm b/examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/custom-interval.htm deleted file mode 100644 index 6c58bda33..000000000 --- a/examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/custom-interval.htm +++ /dev/null @@ -1,82 +0,0 @@ - - - - - Custom interval - - - - - -
-
-
-

- You need to measure, say, between 350 and 980? No problem, just tell it to justGage. Displayed value and color are calculated as a percentage in defined range, with optional min and max labels shown. -

-

- Also, if displayed value is out of range, relax and kick your feet up - justGage will take care of it for you. -

- - - - - - diff --git a/examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/custom-node.html b/examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/custom-node.html deleted file mode 100644 index 98964e13d..000000000 --- a/examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/custom-node.html +++ /dev/null @@ -1,130 +0,0 @@ - - - - - Custom Node - - - - - - -
-
-
-
-
- - -
-
- - - - -
- - - - - - diff --git a/examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/custom-sectors.html b/examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/custom-sectors.html deleted file mode 100644 index a868de6d3..000000000 --- a/examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/custom-sectors.html +++ /dev/null @@ -1,88 +0,0 @@ - - - - - - Custom Sectors - - - - - - - - - -
-
-

0-50 is green, 51-100 is red

- Random Refresh - Update Sectors -
- - - - - - \ No newline at end of file diff --git a/examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/custom-value-renderer.html b/examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/custom-value-renderer.html deleted file mode 100644 index 2e5b0f395..000000000 --- a/examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/custom-value-renderer.html +++ /dev/null @@ -1,116 +0,0 @@ - - - - - - Custom Render Function - - - - -
- Random Refresh - - - - - - diff --git a/examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/customize-style.htm b/examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/customize-style.htm deleted file mode 100644 index 9be11d1eb..000000000 --- a/examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/customize-style.htm +++ /dev/null @@ -1,137 +0,0 @@ - - - - - Customize style - - - - - - -
-
-
-
-
-
-

- Not digging default style? Then mock your own, Picasso! JustGage features bunch of styling options including gauge width, gauge color and shadow, gauge level colors, colors for title, value, min & max etc. -

-

- Check non-minified version of justgage.js for list of all setup parameters. -

- - - - - - diff --git a/examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/defaults.html b/examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/defaults.html deleted file mode 100644 index 99f8827bd..000000000 --- a/examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/defaults.html +++ /dev/null @@ -1,60 +0,0 @@ - - - - - - Defaults - - - - - -
-
-
-
- - - - - - diff --git a/examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/font-options.html b/examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/font-options.html deleted file mode 100644 index 11063c73c..000000000 --- a/examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/font-options.html +++ /dev/null @@ -1,62 +0,0 @@ - - - - - - Counter - - - - - - - - - - - - diff --git a/examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/format-number.html b/examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/format-number.html deleted file mode 100644 index 4bf2c366b..000000000 --- a/examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/format-number.html +++ /dev/null @@ -1,56 +0,0 @@ - - - - - - Counter - - - - - - - - - - - - \ No newline at end of file diff --git a/examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/html5-data-attribute-config.html b/examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/html5-data-attribute-config.html deleted file mode 100644 index 3c2ab0b58..000000000 --- a/examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/html5-data-attribute-config.html +++ /dev/null @@ -1,54 +0,0 @@ - - - - - - html5 data-attribute setup - - - - - - - - - -
-
- -
- - - - - - \ No newline at end of file diff --git a/examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/human-friendly-numbers.html b/examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/human-friendly-numbers.html deleted file mode 100644 index f0e7ddc8d..000000000 --- a/examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/human-friendly-numbers.html +++ /dev/null @@ -1,109 +0,0 @@ - - - - - - Guage - - - - -
- Random Refresh - - - - - - diff --git a/examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/pointer.html b/examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/pointer.html deleted file mode 100644 index b20ae5f4c..000000000 --- a/examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/pointer.html +++ /dev/null @@ -1,168 +0,0 @@ - - - - - - Pointer - - - - - -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
- - - - - - diff --git a/examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/refresh-maximum.html b/examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/refresh-maximum.html deleted file mode 100644 index e1502a100..000000000 --- a/examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/refresh-maximum.html +++ /dev/null @@ -1,91 +0,0 @@ - - - - - - Donuts, baby! - - - - - - - - - - - - diff --git a/examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/responsive-gauges.htm b/examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/responsive-gauges.htm deleted file mode 100644 index 68680c6e3..000000000 --- a/examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/responsive-gauges.htm +++ /dev/null @@ -1,71 +0,0 @@ - - - - - Dynamic Resize - - - - - -
-
-
-
-
- - - - - - diff --git a/examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/reverse.html b/examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/reverse.html deleted file mode 100644 index e17b6750a..000000000 --- a/examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/examples/reverse.html +++ /dev/null @@ -1,144 +0,0 @@ - - - - - - Reverse - - - - - -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
- - - - - - diff --git a/examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/justgage.js b/examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/justgage.js deleted file mode 100644 index c852491ba..000000000 --- a/examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/justgage.js +++ /dev/null @@ -1,1220 +0,0 @@ -/** - * JustGage - animated gauges using RaphaelJS - * Check http://www.justgage.com for official releases - * Licensed under MIT. - * @author Bojan Djuricic (@Toorshia) - **/ - -JustGage = function(config) { - - var obj = this; - - // Helps in case developer wants to debug it. unobtrusive - if (config === null || config === undefined) { - console.log('* justgage: Make sure to pass options to the constructor!'); - return false; - } - - var node; - - if (config.id !== null && config.id !== undefined) { - node = document.getElementById(config.id); - if (!node) { - console.log('* justgage: No element with id : %s found', config.id); - return false; - } - } else if (config.parentNode !== null && config.parentNode !== undefined) { - node = config.parentNode; - } else { - console.log('* justgage: Make sure to pass the existing element id or parentNode to the constructor.'); - return false; - } - - var dataset = node.dataset ? node.dataset : {}; - - // check for defaults - var defaults = (config.defaults !== null && config.defaults !== undefined) ? config.defaults : false; - if (defaults !== false) { - config = extend({}, config, defaults); - delete config.defaults; - } - - // configurable parameters - obj.config = { - // id : string - // this is container element id - id: config.id, - - // value : float - // value gauge is showing - value: kvLookup('value', config, dataset, 0, 'float'), - - // defaults : bool - // defaults parameter to use - defaults: kvLookup('defaults', config, dataset, 0, false), - - // parentNode : node object - // this is container element - parentNode: kvLookup('parentNode', config, dataset, null), - - // width : int - // gauge width - width: kvLookup('width', config, dataset, null), - - // height : int - // gauge height - height: kvLookup('height', config, dataset, null), - - // title : string - // gauge title - title: kvLookup('title', config, dataset, ""), - - // titleFontColor : string - // color of gauge title - titleFontColor: kvLookup('titleFontColor', config, dataset, "#999999"), - - // titleFontFamily : string - // color of gauge title - titleFontFamily: kvLookup('titleFontFamily', config, dataset, "sans-serif"), - - // titlePosition : string - // 'above' or 'below' - titlePosition: kvLookup('titlePosition', config, dataset, "above"), - - // valueFontColor : string - // color of label showing current value - valueFontColor: kvLookup('valueFontColor', config, dataset, "#010101"), - - // valueFontFamily : string - // color of label showing current value - valueFontFamily: kvLookup('valueFontFamily', config, dataset, "Arial"), - - // symbol : string - // special symbol to show next to value - symbol: kvLookup('symbol', config, dataset, ''), - - // min : float - // min value - min: kvLookup('min', config, dataset, 0, 'float'), - - // max : float - // max value - max: kvLookup('max', config, dataset, 100, 'float'), - - // reverse : bool - // reverse min and max - reverse: kvLookup('reverse', config, dataset, false), - - // humanFriendlyDecimal : int - // number of decimal places for our human friendly number to contain - humanFriendlyDecimal: kvLookup('humanFriendlyDecimal', config, dataset, 0), - - - // textRenderer: func - // function applied before rendering text - textRenderer: kvLookup('textRenderer', config, dataset, null), - - // gaugeWidthScale : float - // width of the gauge element - gaugeWidthScale: kvLookup('gaugeWidthScale', config, dataset, 1.0), - - // gaugeColor : string - // background color of gauge element - gaugeColor: kvLookup('gaugeColor', config, dataset, "#edebeb"), - - // label : string - // text to show below value - label: kvLookup('label', config, dataset, ''), - - // labelFontColor : string - // color of label showing label under value - labelFontColor: kvLookup('labelFontColor', config, dataset, "#b3b3b3"), - - // shadowOpacity : int - // 0 ~ 1 - shadowOpacity: kvLookup('shadowOpacity', config, dataset, 0.2), - - // shadowSize: int - // inner shadow size - shadowSize: kvLookup('shadowSize', config, dataset, 5), - - // shadowVerticalOffset : int - // how much shadow is offset from top - shadowVerticalOffset: kvLookup('shadowVerticalOffset', config, dataset, 3), - - // levelColors : string[] - // colors of indicator, from lower to upper, in RGB format - levelColors: kvLookup('levelColors', config, dataset, ["#a9d70b", "#f9c802", "#ff0000"], 'array', ','), - - // startAnimationTime : int - // length of initial animation - startAnimationTime: kvLookup('startAnimationTime', config, dataset, 700), - - // startAnimationType : string - // type of initial animation (linear, >, <, <>, bounce) - startAnimationType: kvLookup('startAnimationType', config, dataset, '>'), - - // refreshAnimationTime : int - // length of refresh animation - refreshAnimationTime: kvLookup('refreshAnimationTime', config, dataset, 700), - - // refreshAnimationType : string - // type of refresh animation (linear, >, <, <>, bounce) - refreshAnimationType: kvLookup('refreshAnimationType', config, dataset, '>'), - - // donutStartAngle : int - // angle to start from when in donut mode - donutStartAngle: kvLookup('donutStartAngle', config, dataset, 90), - - // valueMinFontSize : int - // absolute minimum font size for the value - valueMinFontSize: kvLookup('valueMinFontSize', config, dataset, 16), - - // titleMinFontSize - // absolute minimum font size for the title - titleMinFontSize: kvLookup('titleMinFontSize', config, dataset, 10), - - // labelMinFontSize - // absolute minimum font size for the label - labelMinFontSize: kvLookup('labelMinFontSize', config, dataset, 10), - - // minLabelMinFontSize - // absolute minimum font size for the minimum label - minLabelMinFontSize: kvLookup('minLabelMinFontSize', config, dataset, 10), - - // maxLabelMinFontSize - // absolute minimum font size for the maximum label - maxLabelMinFontSize: kvLookup('maxLabelMinFontSize', config, dataset, 10), - - // hideValue : bool - // hide value text - hideValue: kvLookup('hideValue', config, dataset, false), - - // hideMinMax : bool - // hide min and max values - hideMinMax: kvLookup('hideMinMax', config, dataset, false), - - // hideInnerShadow : bool - // hide inner shadow - hideInnerShadow: kvLookup('hideInnerShadow', config, dataset, false), - - // humanFriendly : bool - // convert large numbers for min, max, value to human friendly (e.g. 1234567 -> 1.23M) - humanFriendly: kvLookup('humanFriendly', config, dataset, false), - - // noGradient : bool - // whether to use gradual color change for value, or sector-based - noGradient: kvLookup('noGradient', config, dataset, false), - - // donut : bool - // show full donut gauge - donut: kvLookup('donut', config, dataset, false), - - // relativeGaugeSize : bool - // whether gauge size should follow changes in container element size - relativeGaugeSize: kvLookup('relativeGaugeSize', config, dataset, false), - - // counter : bool - // animate level number change - counter: kvLookup('counter', config, dataset, false), - - // decimals : int - // number of digits after floating point - decimals: kvLookup('decimals', config, dataset, 0), - - // customSectors : [] of objects - // number of digits after floating point - customSectors: kvLookup('customSectors', config, dataset, []), - - // formatNumber: boolean - // formats numbers with commas where appropriate - formatNumber: kvLookup('formatNumber', config, dataset, false), - - // pointer : bool - // show value pointer - pointer: kvLookup('pointer', config, dataset, false), - - // pointerOptions : object - // define pointer look - pointerOptions: kvLookup('pointerOptions', config, dataset, []) - }; - - // variables - var - canvasW, - canvasH, - widgetW, - widgetH, - aspect, - dx, - dy, - titleFontSize, - titleX, - titleY, - valueFontSize, - valueX, - valueY, - labelFontSize, - labelX, - labelY, - minFontSize, - minX, - minY, - maxFontSize, - maxX, - maxY; - - // overflow values - if (obj.config.value > obj.config.max) obj.config.value = obj.config.max; - if (obj.config.value < obj.config.min) obj.config.value = obj.config.min; - obj.originalValue = kvLookup('value', config, dataset, -1, 'float'); - - // create canvas - if (obj.config.id !== null && (document.getElementById(obj.config.id)) !== null) { - obj.canvas = Raphael(obj.config.id, "100%", "100%"); - } else if (obj.config.parentNode !== null) { - obj.canvas = Raphael(obj.config.parentNode, "100%", "100%"); - } - - if (obj.config.relativeGaugeSize === true) { - obj.canvas.setViewBox(0, 0, 200, 150, true); - } - - // canvas dimensions - if (obj.config.relativeGaugeSize === true) { - canvasW = 200; - canvasH = 150; - } else if (obj.config.width !== null && obj.config.height !== null) { - canvasW = obj.config.width; - canvasH = obj.config.height; - } else if (obj.config.parentNode !== null) { - obj.canvas.setViewBox(0, 0, 200, 150, true); - canvasW = 200; - canvasH = 150; - } else { - canvasW = getStyle(document.getElementById(obj.config.id), "width").slice(0, -2) * 1; - canvasH = getStyle(document.getElementById(obj.config.id), "height").slice(0, -2) * 1; - } - - // widget dimensions - if (obj.config.donut === true) { - - // DONUT ******************************* - - // width more than height - if (canvasW > canvasH) { - widgetH = canvasH; - widgetW = widgetH; - // width less than height - } else if (canvasW < canvasH) { - widgetW = canvasW; - widgetH = widgetW; - // if height don't fit, rescale both - if (widgetH > canvasH) { - aspect = widgetH / canvasH; - widgetH = widgetH / aspect; - widgetW = widgetH / aspect; - } - // equal - } else { - widgetW = canvasW; - widgetH = widgetW; - } - - // delta - dx = (canvasW - widgetW) / 2; - dy = (canvasH - widgetH) / 2; - - // title - titleFontSize = ((widgetH / 8) > 10) ? (widgetH / 10) : 10; - titleX = dx + widgetW / 2; - titleY = dy + widgetH / 11; - - // value - valueFontSize = ((widgetH / 6.4) > 16) ? (widgetH / 5.4) : 18; - valueX = dx + widgetW / 2; - if (obj.config.label !== '') { - valueY = dy + widgetH / 1.85; - } else { - valueY = dy + widgetH / 1.7; - } - - // label - labelFontSize = ((widgetH / 16) > 10) ? (widgetH / 16) : 10; - labelX = dx + widgetW / 2; - labelY = valueY + labelFontSize; - - // min - minFontSize = ((widgetH / 16) > 10) ? (widgetH / 16) : 10; - minX = dx + (widgetW / 10) + (widgetW / 6.666666666666667 * obj.config.gaugeWidthScale) / 2; - minY = labelY; - - // max - maxFontSize = ((widgetH / 16) > 10) ? (widgetH / 16) : 10; - maxX = dx + widgetW - (widgetW / 10) - (widgetW / 6.666666666666667 * obj.config.gaugeWidthScale) / 2; - maxY = labelY; - - } else { - // HALF ******************************* - - // width more than height - if (canvasW > canvasH) { - widgetH = canvasH; - widgetW = widgetH * 1.25; - //if width doesn't fit, rescale both - if (widgetW > canvasW) { - aspect = widgetW / canvasW; - widgetW = widgetW / aspect; - widgetH = widgetH / aspect; - } - // width less than height - } else if (canvasW < canvasH) { - widgetW = canvasW; - widgetH = widgetW / 1.25; - // if height don't fit, rescale both - if (widgetH > canvasH) { - aspect = widgetH / canvasH; - widgetH = widgetH / aspect; - widgetW = widgetH / aspect; - } - // equal - } else { - widgetW = canvasW; - widgetH = widgetW * 0.75; - } - - // delta - dx = (canvasW - widgetW) / 2; - dy = (canvasH - widgetH) / 2; - if (obj.config.titlePosition === 'below') { - // shift whole thing down - dy -= (widgetH / 6.4); - } - - // title - titleFontSize = ((widgetH / 8) > obj.config.titleMinFontSize) ? (widgetH / 10) : obj.config.titleMinFontSize; - titleX = dx + widgetW / 2; - titleY = dy + (obj.config.titlePosition === 'below' ? (widgetH * 1.07) : (widgetH / 6.4)); - - // value - valueFontSize = ((widgetH / 6.5) > obj.config.valueMinFontSize) ? (widgetH / 6.5) : obj.config.valueMinFontSize; - valueX = dx + widgetW / 2; - valueY = dy + widgetH / 1.275; - - // label - labelFontSize = ((widgetH / 16) > obj.config.labelMinFontSize) ? (widgetH / 16) : obj.config.labelMinFontSize; - labelX = dx + widgetW / 2; - labelY = valueY + valueFontSize / 2 + 5; - - // min - minFontSize = ((widgetH / 16) > obj.config.minLabelMinFontSize) ? (widgetH / 16) : obj.config.minLabelMinFontSize; - minX = dx + (widgetW / 10) + (widgetW / 6.666666666666667 * obj.config.gaugeWidthScale) / 2; - minY = labelY; - - // max - maxFontSize = ((widgetH / 16) > obj.config.maxLabelMinFontSize) ? (widgetH / 16) : obj.config.maxLabelMinFontSize; - maxX = dx + widgetW - (widgetW / 10) - (widgetW / 6.666666666666667 * obj.config.gaugeWidthScale) / 2; - maxY = labelY; - } - - // parameters - obj.params = { - canvasW: canvasW, - canvasH: canvasH, - widgetW: widgetW, - widgetH: widgetH, - dx: dx, - dy: dy, - titleFontSize: titleFontSize, - titleX: titleX, - titleY: titleY, - valueFontSize: valueFontSize, - valueX: valueX, - valueY: valueY, - labelFontSize: labelFontSize, - labelX: labelX, - labelY: labelY, - minFontSize: minFontSize, - minX: minX, - minY: minY, - maxFontSize: maxFontSize, - maxX: maxX, - maxY: maxY - }; - - // var clear - canvasW, canvasH, widgetW, widgetH, aspect, dx, dy, titleFontSize, titleX, titleY, valueFontSize, valueX, valueY, labelFontSize, labelX, labelY, minFontSize, minX, minY, maxFontSize, maxX, maxY = null; - - // pki - custom attribute for generating gauge paths - obj.canvas.customAttributes.pki = function(value, min, max, w, h, dx, dy, gws, donut, reverse) { - - var alpha, Ro, Ri, Cx, Cy, Xo, Yo, Xi, Yi, path; - - if (donut) { - alpha = (1 - 2 * (value - min) / (max - min)) * Math.PI; - Ro = w / 2 - w / 7; - Ri = Ro - w / 6.666666666666667 * gws; - - Cx = w / 2 + dx; - Cy = h / 1.95 + dy; - - Xo = w / 2 + dx + Ro * Math.cos(alpha); - Yo = h - (h - Cy) - Ro * Math.sin(alpha); - Xi = w / 2 + dx + Ri * Math.cos(alpha); - Yi = h - (h - Cy) - Ri * Math.sin(alpha); - - path = "M" + (Cx - Ri) + "," + Cy + " "; - path += "L" + (Cx - Ro) + "," + Cy + " "; - if (value > ((max - min) / 2)) { - path += "A" + Ro + "," + Ro + " 0 0 1 " + (Cx + Ro) + "," + Cy + " "; - } - path += "A" + Ro + "," + Ro + " 0 0 1 " + Xo + "," + Yo + " "; - path += "L" + Xi + "," + Yi + " "; - if (value > ((max - min) / 2)) { - path += "A" + Ri + "," + Ri + " 0 0 0 " + (Cx + Ri) + "," + Cy + " "; - } - path += "A" + Ri + "," + Ri + " 0 0 0 " + (Cx - Ri) + "," + Cy + " "; - path += "Z "; - - return { - path: path - }; - - } else { - alpha = (1 - (value - min) / (max - min)) * Math.PI; - Ro = w / 2 - w / 10; - Ri = Ro - w / 6.666666666666667 * gws; - - Cx = w / 2 + dx; - Cy = h / 1.25 + dy; - - Xo = w / 2 + dx + Ro * Math.cos(alpha); - Yo = h - (h - Cy) - Ro * Math.sin(alpha); - Xi = w / 2 + dx + Ri * Math.cos(alpha); - Yi = h - (h - Cy) - Ri * Math.sin(alpha); - - path = "M" + (Cx - Ri) + "," + Cy + " "; - path += "L" + (Cx - Ro) + "," + Cy + " "; - path += "A" + Ro + "," + Ro + " 0 0 1 " + Xo + "," + Yo + " "; - path += "L" + Xi + "," + Yi + " "; - path += "A" + Ri + "," + Ri + " 0 0 0 " + (Cx - Ri) + "," + Cy + " "; - path += "Z "; - - return { - path: path - }; - } - - // var clear - alpha, Ro, Ri, Cx, Cy, Xo, Yo, Xi, Yi, path = null; - }; - - // ndl - custom attribute for generating needle path - obj.canvas.customAttributes.ndl = function(value, min, max, w, h, dx, dy, gws, donut) { - - var dlt = w * 3.5 / 100; - var dlb = w / 15; - var dw = w / 100; - - if (obj.config.pointerOptions.toplength != null && obj.config.pointerOptions.toplength != undefined) dlt = obj.config.pointerOptions.toplength; - if (obj.config.pointerOptions.bottomlength != null && obj.config.pointerOptions.bottomlength != undefined) dlb = obj.config.pointerOptions.bottomlength; - if (obj.config.pointerOptions.bottomwidth != null && obj.config.pointerOptions.bottomwidth != undefined) dw = obj.config.pointerOptions.bottomwidth; - - var alpha, Ro, Ri, Cx, Cy, Xo, Yo, Xi, Yi, Xc, Yc, Xz, Yz, Xa, Ya, Xb, Yb, path; - - if (donut) { - - alpha = (1 - 2 * (value - min) / (max - min)) * Math.PI; - Ro = w / 2 - w / 7; - Ri = Ro - w / 6.666666666666667 * gws; - - Cx = w / 2 + dx; - Cy = h / 1.95 + dy; - - Xo = w / 2 + dx + Ro * Math.cos(alpha); - Yo = h - (h - Cy) - Ro * Math.sin(alpha); - Xi = w / 2 + dx + Ri * Math.cos(alpha); - Yi = h - (h - Cy) - Ri * Math.sin(alpha); - - Xc = Xo + dlt * Math.cos(alpha); - Yc = Yo - dlt * Math.sin(alpha); - Xz = Xi - dlb * Math.cos(alpha); - Yz = Yi + dlb * Math.sin(alpha); - - Xa = Xz + dw * Math.sin(alpha); - Ya = Yz + dw * Math.cos(alpha); - Xb = Xz - dw * Math.sin(alpha); - Yb = Yz - dw * Math.cos(alpha); - - path = 'M' + Xa + ',' + Ya + ' '; - path += 'L' + Xb + ',' + Yb + ' '; - path += 'L' + Xc + ',' + Yc + ' '; - path += 'Z '; - - return { - path: path - }; - - } else { - alpha = (1 - (value - min) / (max - min)) * Math.PI; - Ro = w / 2 - w / 10; - Ri = Ro - w / 6.666666666666667 * gws; - - Cx = w / 2 + dx; - Cy = h / 1.25 + dy; - - Xo = w / 2 + dx + Ro * Math.cos(alpha); - Yo = h - (h - Cy) - Ro * Math.sin(alpha); - Xi = w / 2 + dx + Ri * Math.cos(alpha); - Yi = h - (h - Cy) - Ri * Math.sin(alpha); - - Xc = Xo + dlt * Math.cos(alpha); - Yc = Yo - dlt * Math.sin(alpha); - Xz = Xi - dlb * Math.cos(alpha); - Yz = Yi + dlb * Math.sin(alpha); - - Xa = Xz + dw * Math.sin(alpha); - Ya = Yz + dw * Math.cos(alpha); - Xb = Xz - dw * Math.sin(alpha); - Yb = Yz - dw * Math.cos(alpha); - - path = 'M' + Xa + ',' + Ya + ' '; - path += 'L' + Xb + ',' + Yb + ' '; - path += 'L' + Xc + ',' + Yc + ' '; - path += 'Z '; - - return { - path: path - }; - } - - // var clear - alpha, Ro, Ri, Cx, Cy, Xo, Yo, Xi, Yi, Xc, Yc, Xz, Yz, Xa, Ya, Xb, Yb, path = null; - }; - - // gauge - obj.gauge = obj.canvas.path().attr({ - "stroke": "none", - "fill": obj.config.gaugeColor, - pki: [ - obj.config.max, - obj.config.min, - obj.config.max, - obj.params.widgetW, - obj.params.widgetH, - obj.params.dx, - obj.params.dy, - obj.config.gaugeWidthScale, - obj.config.donut, - obj.config.reverse - ] - }); - - // level - obj.level = obj.canvas.path().attr({ - "stroke": "none", - "fill": getColor(obj.config.value, (obj.config.value - obj.config.min) / (obj.config.max - obj.config.min), obj.config.levelColors, obj.config.noGradient, obj.config.customSectors), - pki: [ - obj.config.min, - obj.config.min, - obj.config.max, - obj.params.widgetW, - obj.params.widgetH, - obj.params.dx, - obj.params.dy, - obj.config.gaugeWidthScale, - obj.config.donut, - obj.config.reverse - ] - }); - if (obj.config.donut) { - obj.level.transform("r" + obj.config.donutStartAngle + ", " + (obj.params.widgetW / 2 + obj.params.dx) + ", " + (obj.params.widgetH / 1.95 + obj.params.dy)); - } - - if (obj.config.pointer) { - // needle - obj.needle = obj.canvas.path().attr({ - "stroke": (obj.config.pointerOptions.stroke !== null && obj.config.pointerOptions.stroke !== undefined) ? obj.config.pointerOptions.stroke : "none", - "stroke-width": (obj.config.pointerOptions.stroke_width !== null && obj.config.pointerOptions.stroke_width !== undefined) ? obj.config.pointerOptions.stroke_width : 0, - "stroke-linecap": (obj.config.pointerOptions.stroke_linecap !== null && obj.config.pointerOptions.stroke_linecap !== undefined) ? obj.config.pointerOptions.stroke_linecap : "square", - "fill": (obj.config.pointerOptions.color !== null && obj.config.pointerOptions.color !== undefined) ? obj.config.pointerOptions.color : "#000000", - ndl: [ - obj.config.min, - obj.config.min, - obj.config.max, - obj.params.widgetW, - obj.params.widgetH, - obj.params.dx, - obj.params.dy, - obj.config.gaugeWidthScale, - obj.config.donut - ] - }); - - if (obj.config.donut) { - obj.needle.transform("r" + obj.config.donutStartAngle + ", " + (obj.params.widgetW / 2 + obj.params.dx) + ", " + (obj.params.widgetH / 1.95 + obj.params.dy)); - } - - } - - // title - obj.txtTitle = obj.canvas.text(obj.params.titleX, obj.params.titleY, obj.config.title); - obj.txtTitle.attr({ - "font-size": obj.params.titleFontSize, - "font-weight": "bold", - "font-family": obj.config.titleFontFamily, - "fill": obj.config.titleFontColor, - "fill-opacity": "1" - }); - setDy(obj.txtTitle, obj.params.titleFontSize, obj.params.titleY); - - // value - obj.txtValue = obj.canvas.text(obj.params.valueX, obj.params.valueY, 0); - obj.txtValue.attr({ - "font-size": obj.params.valueFontSize, - "font-weight": "bold", - "font-family": obj.config.valueFontFamily, - "fill": obj.config.valueFontColor, - "fill-opacity": "0" - }); - setDy(obj.txtValue, obj.params.valueFontSize, obj.params.valueY); - - // label - obj.txtLabel = obj.canvas.text(obj.params.labelX, obj.params.labelY, obj.config.label); - obj.txtLabel.attr({ - "font-size": obj.params.labelFontSize, - "font-weight": "normal", - "font-family": "Arial", - "fill": obj.config.labelFontColor, - "fill-opacity": "0" - }); - setDy(obj.txtLabel, obj.params.labelFontSize, obj.params.labelY); - - // min - var min = obj.config.min; - if (obj.config.reverse) { - min = obj.config.max; - } - - obj.txtMinimum = min; - if (obj.config.humanFriendly) { - obj.txtMinimum = humanFriendlyNumber(min, obj.config.humanFriendlyDecimal); - } else if (obj.config.formatNumber) { - obj.txtMinimum = formatNumber(min); - } - obj.txtMin = obj.canvas.text(obj.params.minX, obj.params.minY, obj.txtMinimum); - obj.txtMin.attr({ - "font-size": obj.params.minFontSize, - "font-weight": "normal", - "font-family": "Arial", - "fill": obj.config.labelFontColor, - "fill-opacity": (obj.config.hideMinMax || obj.config.donut) ? "0" : "1" - }); - setDy(obj.txtMin, obj.params.minFontSize, obj.params.minY); - - // max - var max = obj.config.max; - if (obj.config.reverse) { - max = obj.config.min; - } - obj.txtMaximum = max; - if (obj.config.humanFriendly) { - obj.txtMaximum = humanFriendlyNumber(max, obj.config.humanFriendlyDecimal); - } else if (obj.config.formatNumber) { - obj.txtMaximum = formatNumber(max); - } - obj.txtMax = obj.canvas.text(obj.params.maxX, obj.params.maxY, obj.txtMaximum); - obj.txtMax.attr({ - "font-size": obj.params.maxFontSize, - "font-weight": "normal", - "font-family": "Arial", - "fill": obj.config.labelFontColor, - "fill-opacity": (obj.config.hideMinMax || obj.config.donut) ? "0" : "1" - }); - setDy(obj.txtMax, obj.params.maxFontSize, obj.params.maxY); - - var defs = obj.canvas.canvas.childNodes[1]; - var svg = "http://www.w3.org/2000/svg"; - - if (ie !== 'undefined' && ie < 9) { - // VML mode - no SVG & SVG filter support - } else if (ie !== 'undefined') { - onCreateElementNsReady(function() { - obj.generateShadow(svg, defs); - }); - } else { - obj.generateShadow(svg, defs); - } - - // var clear - defs, svg = null; - - // set value to display - if (obj.config.textRenderer) { - obj.originalValue = obj.config.textRenderer(obj.originalValue); - } else if (obj.config.humanFriendly) { - obj.originalValue = humanFriendlyNumber(obj.originalValue, obj.config.humanFriendlyDecimal) + obj.config.symbol; - } else if (obj.config.formatNumber) { - obj.originalValue = formatNumber(obj.originalValue) + obj.config.symbol; - } else { - obj.originalValue = (obj.originalValue * 1).toFixed(obj.config.decimals) + obj.config.symbol; - } - - if (obj.config.counter === true) { - //on each animation frame - eve.on("raphael.anim.frame." + (obj.level.id), function() { - var currentValue = obj.level.attr("pki")[0]; - if (obj.config.reverse) { - currentValue = (obj.config.max * 1) + (obj.config.min * 1) - (obj.level.attr("pki")[0] * 1); - } - if (obj.config.textRenderer) { - obj.txtValue.attr("text", obj.config.textRenderer(Math.floor(currentValue))); - } else if (obj.config.humanFriendly) { - obj.txtValue.attr("text", humanFriendlyNumber(Math.floor(currentValue), obj.config.humanFriendlyDecimal) + obj.config.symbol); - } else if (obj.config.formatNumber) { - obj.txtValue.attr("text", formatNumber(Math.floor(currentValue)) + obj.config.symbol); - } else { - obj.txtValue.attr("text", (currentValue * 1).toFixed(obj.config.decimals) + obj.config.symbol); - } - setDy(obj.txtValue, obj.params.valueFontSize, obj.params.valueY); - currentValue = null; - }); - //on animation end - eve.on("raphael.anim.finish." + (obj.level.id), function() { - obj.txtValue.attr({ - "text": obj.originalValue - }); - setDy(obj.txtValue, obj.params.valueFontSize, obj.params.valueY); - }); - } else { - //on animation start - eve.on("raphael.anim.start." + (obj.level.id), function() { - obj.txtValue.attr({ - "text": obj.originalValue - }); - setDy(obj.txtValue, obj.params.valueFontSize, obj.params.valueY); - }); - } - - // animate gauge level, value & label - var rvl = obj.config.value; - if (obj.config.reverse) { - rvl = (obj.config.max * 1) + (obj.config.min * 1) - (obj.config.value * 1); - } - obj.level.animate({ - pki: [ - rvl, - obj.config.min, - obj.config.max, - obj.params.widgetW, - obj.params.widgetH, - obj.params.dx, - obj.params.dy, - obj.config.gaugeWidthScale, - obj.config.donut, - obj.config.reverse - ] - }, obj.config.startAnimationTime, obj.config.startAnimationType); - - if (obj.config.pointer) { - obj.needle.animate({ - ndl: [ - rvl, - obj.config.min, - obj.config.max, - obj.params.widgetW, - obj.params.widgetH, - obj.params.dx, - obj.params.dy, - obj.config.gaugeWidthScale, - obj.config.donut - ] - }, obj.config.startAnimationTime, obj.config.startAnimationType); - } - - obj.txtValue.animate({ - "fill-opacity": (obj.config.hideValue) ? "0" : "1" - }, obj.config.startAnimationTime, obj.config.startAnimationType); - obj.txtLabel.animate({ - "fill-opacity": "1" - }, obj.config.startAnimationTime, obj.config.startAnimationType); -}; - -/** Refresh gauge level */ -JustGage.prototype.refresh = function(val, max) { - - var obj = this; - var displayVal, color, max = max || null; - - // set new max - if (max !== null) { - obj.config.max = max; - // TODO: update customSectors - - obj.txtMaximum = obj.config.max; - if (obj.config.humanFriendly) { - obj.txtMaximum = humanFriendlyNumber(obj.config.max, obj.config.humanFriendlyDecimal); - } else if (obj.config.formatNumber) { - obj.txtMaximum = formatNumber(obj.config.max); - } - if (!obj.config.reverse) { - obj.txtMax.attr({ - "text": obj.txtMaximum - }); - setDy(obj.txtMax, obj.params.maxFontSize, obj.params.maxY); - } else { - obj.txtMin.attr({ - "text": obj.txtMaximum - }); - setDy(obj.txtMin, obj.params.minFontSize, obj.params.minY); - } - } - - // overflow values - displayVal = val; - if ((val * 1) > (obj.config.max * 1)) { - val = (obj.config.max * 1); - } - if ((val * 1) < (obj.config.min * 1)) { - val = (obj.config.min * 1); - } - - color = getColor(val, (val - obj.config.min) / (obj.config.max - obj.config.min), obj.config.levelColors, obj.config.noGradient, obj.config.customSectors); - - if (obj.config.textRenderer) { - displayVal = obj.config.textRenderer(displayVal); - } else if (obj.config.humanFriendly) { - displayVal = humanFriendlyNumber(displayVal, obj.config.humanFriendlyDecimal) + obj.config.symbol; - } else if (obj.config.formatNumber) { - displayVal = formatNumber((displayVal * 1).toFixed(obj.config.decimals)) + obj.config.symbol; - } else { - displayVal = (displayVal * 1).toFixed(obj.config.decimals) + obj.config.symbol; - } - obj.originalValue = displayVal; - obj.config.value = val * 1; - - if (!obj.config.counter) { - obj.txtValue.attr({ - "text": displayVal - }); - setDy(obj.txtValue, obj.params.valueFontSize, obj.params.valueY); - } - - var rvl = obj.config.value; - if (obj.config.reverse) { - rvl = (obj.config.max * 1) + (obj.config.min * 1) - (obj.config.value * 1); - } - obj.level.animate({ - pki: [ - rvl, - obj.config.min, - obj.config.max, - obj.params.widgetW, - obj.params.widgetH, - obj.params.dx, - obj.params.dy, - obj.config.gaugeWidthScale, - obj.config.donut, - obj.config.reverse - ], - "fill": color - }, obj.config.refreshAnimationTime, obj.config.refreshAnimationType); - - if (obj.config.pointer) { - obj.needle.animate({ - ndl: [ - rvl, - obj.config.min, - obj.config.max, - obj.params.widgetW, - obj.params.widgetH, - obj.params.dx, - obj.params.dy, - obj.config.gaugeWidthScale, - obj.config.donut - ] - }, obj.config.refreshAnimationTime, obj.config.refreshAnimationType); - } - - // var clear - obj, displayVal, color, max = null; -}; - -/** Generate shadow */ -JustGage.prototype.generateShadow = function(svg, defs) { - - var obj = this; - var sid = "inner-shadow-" + obj.config.id; - var gaussFilter, feOffset, feGaussianBlur, feComposite1, feFlood, feComposite2, feComposite3; - - // FILTER - gaussFilter = document.createElementNS(svg, "filter"); - gaussFilter.setAttribute("id", sid); - defs.appendChild(gaussFilter); - - // offset - feOffset = document.createElementNS(svg, "feOffset"); - feOffset.setAttribute("dx", 0); - feOffset.setAttribute("dy", obj.config.shadowVerticalOffset); - gaussFilter.appendChild(feOffset); - - // blur - feGaussianBlur = document.createElementNS(svg, "feGaussianBlur"); - feGaussianBlur.setAttribute("result", "offset-blur"); - feGaussianBlur.setAttribute("stdDeviation", obj.config.shadowSize); - gaussFilter.appendChild(feGaussianBlur); - - // composite 1 - feComposite1 = document.createElementNS(svg, "feComposite"); - feComposite1.setAttribute("operator", "out"); - feComposite1.setAttribute("in", "SourceGraphic"); - feComposite1.setAttribute("in2", "offset-blur"); - feComposite1.setAttribute("result", "inverse"); - gaussFilter.appendChild(feComposite1); - - // flood - feFlood = document.createElementNS(svg, "feFlood"); - feFlood.setAttribute("flood-color", "black"); - feFlood.setAttribute("flood-opacity", obj.config.shadowOpacity); - feFlood.setAttribute("result", "color"); - gaussFilter.appendChild(feFlood); - - // composite 2 - feComposite2 = document.createElementNS(svg, "feComposite"); - feComposite2.setAttribute("operator", "in"); - feComposite2.setAttribute("in", "color"); - feComposite2.setAttribute("in2", "inverse"); - feComposite2.setAttribute("result", "shadow"); - gaussFilter.appendChild(feComposite2); - - // composite 3 - feComposite3 = document.createElementNS(svg, "feComposite"); - feComposite3.setAttribute("operator", "over"); - feComposite3.setAttribute("in", "shadow"); - feComposite3.setAttribute("in2", "SourceGraphic"); - gaussFilter.appendChild(feComposite3); - - // set shadow - if (!obj.config.hideInnerShadow) { - obj.canvas.canvas.childNodes[2].setAttribute("filter", "url(#" + sid + ")"); - obj.canvas.canvas.childNodes[3].setAttribute("filter", "url(#" + sid + ")"); - } - - // var clear - gaussFilter, feOffset, feGaussianBlur, feComposite1, feFlood, feComposite2, feComposite3 = null; -}; - -// -// tiny helper function to lookup value of a key from two hash tables -// if none found, return defaultvalue -// -// key: string -// tablea: object -// tableb: DOMStringMap|object -// defval: string|integer|float|null -// datatype: return datatype -// delimiter: delimiter to be used in conjunction with datatype formatting -// -function kvLookup(key, tablea, tableb, defval, datatype, delimiter) { - var val = defval; - var canConvert = false; - if (!(key === null || key === undefined)) { - if (tableb !== null && tableb !== undefined && typeof tableb === "object" && key in tableb) { - val = tableb[key]; - canConvert = true; - } else if (tablea !== null && tablea !== undefined && typeof tablea === "object" && key in tablea) { - val = tablea[key]; - canConvert = true; - } else { - val = defval; - } - if (canConvert === true) { - if (datatype !== null && datatype !== undefined) { - switch (datatype) { - case 'int': - val = parseInt(val, 10); - break; - case 'float': - val = parseFloat(val); - break; - default: - break; - } - } - } - } - return val; -}; - -/** Get color for value */ -function getColor(val, pct, col, noGradient, custSec) { - - var no, inc, colors, percentage, rval, gval, bval, lower, upper, range, rangePct, pctLower, pctUpper, color; - var noGradient = noGradient || custSec.length > 0; - - if (custSec.length > 0) { - for (var i = 0; i < custSec.length; i++) { - if (val > custSec[i].lo && val <= custSec[i].hi) { - return custSec[i].color; - } - } - } - - no = col.length; - if (no === 1) return col[0]; - inc = (noGradient) ? (1 / no) : (1 / (no - 1)); - colors = []; - for (i = 0; i < col.length; i++) { - percentage = (noGradient) ? (inc * (i + 1)) : (inc * i); - rval = parseInt((cutHex(col[i])).substring(0, 2), 16); - gval = parseInt((cutHex(col[i])).substring(2, 4), 16); - bval = parseInt((cutHex(col[i])).substring(4, 6), 16); - colors[i] = { - pct: percentage, - color: { - r: rval, - g: gval, - b: bval - } - }; - } - - if (pct === 0) { - return 'rgb(' + [colors[0].color.r, colors[0].color.g, colors[0].color.b].join(',') + ')'; - } - - for (var j = 0; j < colors.length; j++) { - if (pct <= colors[j].pct) { - if (noGradient) { - return 'rgb(' + [colors[j].color.r, colors[j].color.g, colors[j].color.b].join(',') + ')'; - } else { - lower = colors[j - 1]; - upper = colors[j]; - range = upper.pct - lower.pct; - rangePct = (pct - lower.pct) / range; - pctLower = 1 - rangePct; - pctUpper = rangePct; - color = { - r: Math.floor(lower.color.r * pctLower + upper.color.r * pctUpper), - g: Math.floor(lower.color.g * pctLower + upper.color.g * pctUpper), - b: Math.floor(lower.color.b * pctLower + upper.color.b * pctUpper) - }; - return 'rgb(' + [color.r, color.g, color.b].join(',') + ')'; - } - } - } - -} - -/** Fix Raphael display:none tspan dy attribute bug */ -function setDy(elem, fontSize, txtYpos) { - if ((!ie || ie > 9) && elem.node.firstChild.attributes.dy) { - elem.node.firstChild.attributes.dy.value = 0; - } -} - -/** Random integer */ -function getRandomInt(min, max) { - return Math.floor(Math.random() * (max - min + 1)) + min; -} - -/** Cut hex */ -function cutHex(str) { - return (str.charAt(0) == "#") ? str.substring(1, 7) : str; -} - -/** Human friendly number suffix - From: http://stackoverflow.com/questions/2692323/code-golf-friendly-number-abbreviator */ -function humanFriendlyNumber(n, d) { - var p, d2, i, s; - - p = Math.pow; - d2 = p(10, d); - i = 7; - while (i) { - s = p(10, i-- * 3); - if (s <= n) { - n = Math.round(n * d2 / s) / d2 + "KMGTPE" [i]; - } - } - return n; -} - -/** Format numbers with commas - From: http://stackoverflow.com/questions/2901102/how-to-print-a-number-with-commas-as-thousands-separators-in-javascript */ -function formatNumber(x) { - var parts = x.toString().split("."); - parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ","); - return parts.join("."); -} - -/** Get style */ -function getStyle(oElm, strCssRule) { - var strValue = ""; - if (document.defaultView && document.defaultView.getComputedStyle) { - strValue = document.defaultView.getComputedStyle(oElm, "").getPropertyValue(strCssRule); - } else if (oElm.currentStyle) { - strCssRule = strCssRule.replace(/\-(\w)/g, function(strMatch, p1) { - return p1.toUpperCase(); - }); - strValue = oElm.currentStyle[strCssRule]; - } - return strValue; -} - -/** Create Element NS Ready */ -function onCreateElementNsReady(func) { - if (document.createElementNS !== undefined) { - func(); - } else { - setTimeout(function() { - onCreateElementNsReady(func); - }, 100); - } -} - -/** Get IE version */ -// ---------------------------------------------------------- -// A short snippet for detecting versions of IE in JavaScript -// without resorting to user-agent sniffing -// ---------------------------------------------------------- -// If you're not in IE (or IE version is less than 5) then: -// ie === undefined -// If you're in IE (>=5) then you can determine which version: -// ie === 7; // IE7 -// Thus, to detect IE: -// if (ie) {} -// And to detect the version: -// ie === 6 // IE6 -// ie > 7 // IE8, IE9 ... -// ie < 9 // Anything less than IE9 -// ---------------------------------------------------------- -// UPDATE: Now using Live NodeList idea from @jdalton -var ie = (function() { - - var undef, - v = 3, - div = document.createElement('div'), - all = div.getElementsByTagName('i'); - - while ( - div.innerHTML = '', - all[0] - ); - return v > 4 ? v : undef; -}()); - -// extend target object with second object -function extend(out) { - out = out || {}; - - for (var i = 1; i < arguments.length; i++) { - if (!arguments[i]) - continue; - - for (var key in arguments[i]) { - if (arguments[i].hasOwnProperty(key)) - out[key] = arguments[i][key]; - } - } - - return out; -}; diff --git a/examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/raphael-2.1.4.min.js b/examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/raphael-2.1.4.min.js deleted file mode 100644 index b907338b7..000000000 --- a/examples/SmartSwitch/data_src/js_css_src/justgage-1.2.2/raphael-2.1.4.min.js +++ /dev/null @@ -1,12 +0,0 @@ -// ┌────────────────────────────────────────────────────────────────────┐ \\ -// │ Raphaël 2.1.4 - JavaScript Vector Library │ \\ -// ├────────────────────────────────────────────────────────────────────┤ \\ -// │ Copyright © 2008-2012 Dmitry Baranovskiy (http://raphaeljs.com) │ \\ -// │ Copyright © 2008-2012 Sencha Labs (http://sencha.com) │ \\ -// ├────────────────────────────────────────────────────────────────────┤ \\ -// │ Licensed under the MIT (http://raphaeljs.com/license.html) license.│ \\ -// └────────────────────────────────────────────────────────────────────┘ \\ -!function(a,b){"function"==typeof define&&define.amd?define("eve",function(){return b()}):"object"==typeof exports?module.exports=b():a.eve=b()}(this,function(){var a,b,c="0.4.2",d="hasOwnProperty",e=/[\.\/]/,f="*",g=function(){},h=function(a,b){return a-b},i={n:{}},j=function(c,d){c=String(c);var e,f=b,g=Array.prototype.slice.call(arguments,2),i=j.listeners(c),k=0,l=[],m={},n=[],o=a;a=c,b=0;for(var p=0,q=i.length;q>p;p++)"zIndex"in i[p]&&(l.push(i[p].zIndex),i[p].zIndex<0&&(m[i[p].zIndex]=i[p]));for(l.sort(h);l[k]<0;)if(e=m[l[k++]],n.push(e.apply(d,g)),b)return b=f,n;for(p=0;q>p;p++)if(e=i[p],"zIndex"in e)if(e.zIndex==l[k]){if(n.push(e.apply(d,g)),b)break;do if(k++,e=m[l[k]],e&&n.push(e.apply(d,g)),b)break;while(e)}else m[e.zIndex]=e;else if(n.push(e.apply(d,g)),b)break;return b=f,a=o,n.length?n:null};return j._events=i,j.listeners=function(a){var b,c,d,g,h,j,k,l,m=a.split(e),n=i,o=[n],p=[];for(g=0,h=m.length;h>g;g++){for(l=[],j=0,k=o.length;k>j;j++)for(n=o[j].n,c=[n[m[g]],n[f]],d=2;d--;)b=c[d],b&&(l.push(b),p=p.concat(b.f||[]));o=l}return p},j.on=function(a,b){if(a=String(a),"function"!=typeof b)return function(){};for(var c=a.split(e),d=i,f=0,h=c.length;h>f;f++)d=d.n,d=d.hasOwnProperty(c[f])&&d[c[f]]||(d[c[f]]={n:{}});for(d.f=d.f||[],f=0,h=d.f.length;h>f;f++)if(d.f[f]==b)return g;return d.f.push(b),function(a){+a==+a&&(b.zIndex=+a)}},j.f=function(a){var b=[].slice.call(arguments,1);return function(){j.apply(null,[a,null].concat(b).concat([].slice.call(arguments,0)))}},j.stop=function(){b=1},j.nt=function(b){return b?new RegExp("(?:\\.|\\/|^)"+b+"(?:\\.|\\/|$)").test(a):a},j.nts=function(){return a.split(e)},j.off=j.unbind=function(a,b){if(!a)return void(j._events=i={n:{}});var c,g,h,k,l,m,n,o=a.split(e),p=[i];for(k=0,l=o.length;l>k;k++)for(m=0;mk;k++)for(c=p[k];c.n;){if(b){if(c.f){for(m=0,n=c.f.length;n>m;m++)if(c.f[m]==b){c.f.splice(m,1);break}!c.f.length&&delete c.f}for(g in c.n)if(c.n[d](g)&&c.n[g].f){var q=c.n[g].f;for(m=0,n=q.length;n>m;m++)if(q[m]==b){q.splice(m,1);break}!q.length&&delete c.n[g].f}}else{delete c.f;for(g in c.n)c.n[d](g)&&c.n[g].f&&delete c.n[g].f}c=c.n}},j.once=function(a,b){var c=function(){return j.unbind(a,c),b.apply(this,arguments)};return j.on(a,c)},j.version=c,j.toString=function(){return"You are running Eve "+c},j}),function(a,b){"function"==typeof define&&define.amd?define("raphael.core",["eve"],function(a){return b(a)}):"object"==typeof exports?module.exports=b(require("eve")):a.Raphael=b(a.eve)}(this,function(a){function b(c){if(b.is(c,"function"))return t?c():a.on("raphael.DOMload",c);if(b.is(c,U))return b._engine.create[C](b,c.splice(0,3+b.is(c[0],S))).add(c);var d=Array.prototype.slice.call(arguments,0);if(b.is(d[d.length-1],"function")){var e=d.pop();return t?e.call(b._engine.create[C](b,d)):a.on("raphael.DOMload",function(){e.call(b._engine.create[C](b,d))})}return b._engine.create[C](b,arguments)}function c(a){if("function"==typeof a||Object(a)!==a)return a;var b=new a.constructor;for(var d in a)a[y](d)&&(b[d]=c(a[d]));return b}function d(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c]===b)return a.push(a.splice(c,1)[0])}function e(a,b,c){function e(){var f=Array.prototype.slice.call(arguments,0),g=f.join("␀"),h=e.cache=e.cache||{},i=e.count=e.count||[];return h[y](g)?(d(i,g),c?c(h[g]):h[g]):(i.length>=1e3&&delete h[i.shift()],i.push(g),h[g]=a[C](b,f),c?c(h[g]):h[g])}return e}function f(){return this.hex}function g(a,b){for(var c=[],d=0,e=a.length;e-2*!b>d;d+=2){var f=[{x:+a[d-2],y:+a[d-1]},{x:+a[d],y:+a[d+1]},{x:+a[d+2],y:+a[d+3]},{x:+a[d+4],y:+a[d+5]}];b?d?e-4==d?f[3]={x:+a[0],y:+a[1]}:e-2==d&&(f[2]={x:+a[0],y:+a[1]},f[3]={x:+a[2],y:+a[3]}):f[0]={x:+a[e-2],y:+a[e-1]}:e-4==d?f[3]=f[2]:d||(f[0]={x:+a[d],y:+a[d+1]}),c.push(["C",(-f[0].x+6*f[1].x+f[2].x)/6,(-f[0].y+6*f[1].y+f[2].y)/6,(f[1].x+6*f[2].x-f[3].x)/6,(f[1].y+6*f[2].y-f[3].y)/6,f[2].x,f[2].y])}return c}function h(a,b,c,d,e){var f=-3*b+9*c-9*d+3*e,g=a*f+6*b-12*c+6*d;return a*g-3*b+3*c}function i(a,b,c,d,e,f,g,i,j){null==j&&(j=1),j=j>1?1:0>j?0:j;for(var k=j/2,l=12,m=[-.1252,.1252,-.3678,.3678,-.5873,.5873,-.7699,.7699,-.9041,.9041,-.9816,.9816],n=[.2491,.2491,.2335,.2335,.2032,.2032,.1601,.1601,.1069,.1069,.0472,.0472],o=0,p=0;l>p;p++){var q=k*m[p]+k,r=h(q,a,c,e,g),s=h(q,b,d,f,i),t=r*r+s*s;o+=n[p]*M.sqrt(t)}return k*o}function j(a,b,c,d,e,f,g,h,j){if(!(0>j||i(a,b,c,d,e,f,g,h)o;)m/=2,n+=(j>k?1:-1)*m,k=i(a,b,c,d,e,f,g,h,n);return n}}function k(a,b,c,d,e,f,g,h){if(!(N(a,c)N(e,g)||N(b,d)N(f,h))){var i=(a*d-b*c)*(e-g)-(a-c)*(e*h-f*g),j=(a*d-b*c)*(f-h)-(b-d)*(e*h-f*g),k=(a-c)*(f-h)-(b-d)*(e-g);if(k){var l=i/k,m=j/k,n=+l.toFixed(2),o=+m.toFixed(2);if(!(n<+O(a,c).toFixed(2)||n>+N(a,c).toFixed(2)||n<+O(e,g).toFixed(2)||n>+N(e,g).toFixed(2)||o<+O(b,d).toFixed(2)||o>+N(b,d).toFixed(2)||o<+O(f,h).toFixed(2)||o>+N(f,h).toFixed(2)))return{x:l,y:m}}}}function l(a,c,d){var e=b.bezierBBox(a),f=b.bezierBBox(c);if(!b.isBBoxIntersect(e,f))return d?0:[];for(var g=i.apply(0,a),h=i.apply(0,c),j=N(~~(g/5),1),l=N(~~(h/5),1),m=[],n=[],o={},p=d?0:[],q=0;j+1>q;q++){var r=b.findDotsAtSegment.apply(b,a.concat(q/j));m.push({x:r.x,y:r.y,t:q/j})}for(q=0;l+1>q;q++)r=b.findDotsAtSegment.apply(b,c.concat(q/l)),n.push({x:r.x,y:r.y,t:q/l});for(q=0;j>q;q++)for(var s=0;l>s;s++){var t=m[q],u=m[q+1],v=n[s],w=n[s+1],x=P(u.x-t.x)<.001?"y":"x",y=P(w.x-v.x)<.001?"y":"x",z=k(t.x,t.y,u.x,u.y,v.x,v.y,w.x,w.y);if(z){if(o[z.x.toFixed(4)]==z.y.toFixed(4))continue;o[z.x.toFixed(4)]=z.y.toFixed(4);var A=t.t+P((z[x]-t[x])/(u[x]-t[x]))*(u.t-t.t),B=v.t+P((z[y]-v[y])/(w[y]-v[y]))*(w.t-v.t);A>=0&&1.001>=A&&B>=0&&1.001>=B&&(d?p++:p.push({x:z.x,y:z.y,t1:O(A,1),t2:O(B,1)}))}}return p}function m(a,c,d){a=b._path2curve(a),c=b._path2curve(c);for(var e,f,g,h,i,j,k,m,n,o,p=d?0:[],q=0,r=a.length;r>q;q++){var s=a[q];if("M"==s[0])e=i=s[1],f=j=s[2];else{"C"==s[0]?(n=[e,f].concat(s.slice(1)),e=n[6],f=n[7]):(n=[e,f,e,f,i,j,i,j],e=i,f=j);for(var t=0,u=c.length;u>t;t++){var v=c[t];if("M"==v[0])g=k=v[1],h=m=v[2];else{"C"==v[0]?(o=[g,h].concat(v.slice(1)),g=o[6],h=o[7]):(o=[g,h,g,h,k,m,k,m],g=k,h=m);var w=l(n,o,d);if(d)p+=w;else{for(var x=0,y=w.length;y>x;x++)w[x].segment1=q,w[x].segment2=t,w[x].bez1=n,w[x].bez2=o;p=p.concat(w)}}}}}return p}function n(a,b,c,d,e,f){null!=a?(this.a=+a,this.b=+b,this.c=+c,this.d=+d,this.e=+e,this.f=+f):(this.a=1,this.b=0,this.c=0,this.d=1,this.e=0,this.f=0)}function o(){return this.x+G+this.y+G+this.width+" × "+this.height}function p(a,b,c,d,e,f){function g(a){return((l*a+k)*a+j)*a}function h(a,b){var c=i(a,b);return((o*c+n)*c+m)*c}function i(a,b){var c,d,e,f,h,i;for(e=a,i=0;8>i;i++){if(f=g(e)-a,P(f)e)return c;if(e>d)return d;for(;d>c;){if(f=g(e),P(f-a)f?c=e:d=e,e=(d-c)/2+c}return e}var j=3*b,k=3*(d-b)-j,l=1-j-k,m=3*c,n=3*(e-c)-m,o=1-m-n;return h(a,1/(200*f))}function q(a,b){var c=[],d={};if(this.ms=b,this.times=1,a){for(var e in a)a[y](e)&&(d[$(e)]=a[e],c.push($(e)));c.sort(ka)}this.anim=d,this.top=c[c.length-1],this.percents=c}function r(c,d,e,f,g,h){e=$(e);var i,j,k,l,m,o,q=c.ms,r={},s={},t={};if(f)for(w=0,x=fb.length;x>w;w++){var u=fb[w];if(u.el.id==d.id&&u.anim==c){u.percent!=e?(fb.splice(w,1),k=1):j=u,d.attr(u.totalOrigin);break}}else f=+s;for(var w=0,x=c.percents.length;x>w;w++){if(c.percents[w]==e||c.percents[w]>f*c.top){e=c.percents[w],m=c.percents[w-1]||0,q=q/c.top*(e-m),l=c.percents[w+1],i=c.anim[e];break}f&&d.attr(c.anim[c.percents[w]])}if(i){if(j)j.initstatus=f,j.start=new Date-j.ms*f;else{for(var z in i)if(i[y](z)&&(ca[y](z)||d.paper.customAttributes[y](z)))switch(r[z]=d.attr(z),null==r[z]&&(r[z]=ba[z]),s[z]=i[z],ca[z]){case S:t[z]=(s[z]-r[z])/q;break;case"colour":r[z]=b.getRGB(r[z]);var A=b.getRGB(s[z]);t[z]={r:(A.r-r[z].r)/q,g:(A.g-r[z].g)/q,b:(A.b-r[z].b)/q};break;case"path":var B=Ia(r[z],s[z]),C=B[1];for(r[z]=B[0],t[z]=[],w=0,x=r[z].length;x>w;w++){t[z][w]=[0];for(var E=1,F=r[z][w].length;F>E;E++)t[z][w][E]=(C[w][E]-r[z][w][E])/q}break;case"transform":var G=d._,J=Na(G[z],s[z]);if(J)for(r[z]=J.from,s[z]=J.to,t[z]=[],t[z].real=!0,w=0,x=r[z].length;x>w;w++)for(t[z][w]=[r[z][w][0]],E=1,F=r[z][w].length;F>E;E++)t[z][w][E]=(s[z][w][E]-r[z][w][E])/q;else{var K=d.matrix||new n,L={_:{transform:G.transform},getBBox:function(){return d.getBBox(1)}};r[z]=[K.a,K.b,K.c,K.d,K.e,K.f],La(L,s[z]),s[z]=L._.transform,t[z]=[(L.matrix.a-K.a)/q,(L.matrix.b-K.b)/q,(L.matrix.c-K.c)/q,(L.matrix.d-K.d)/q,(L.matrix.e-K.e)/q,(L.matrix.f-K.f)/q]}break;case"csv":var M=H(i[z])[I](v),N=H(r[z])[I](v);if("clip-rect"==z)for(r[z]=N,t[z]=[],w=N.length;w--;)t[z][w]=(M[w]-r[z][w])/q;s[z]=M;break;default:for(M=[][D](i[z]),N=[][D](r[z]),t[z]=[],w=d.paper.customAttributes[z].length;w--;)t[z][w]=((M[w]||0)-(N[w]||0))/q}var O=i.easing,P=b.easing_formulas[O];if(!P)if(P=H(O).match(Y),P&&5==P.length){var Q=P;P=function(a){return p(a,+Q[1],+Q[2],+Q[3],+Q[4],q)}}else P=la;if(o=i.start||c.start||+new Date,u={anim:c,percent:e,timestamp:o,start:o+(c.del||0),status:0,initstatus:f||0,stop:!1,ms:q,easing:P,from:r,diff:t,to:s,el:d,callback:i.callback,prev:m,next:l,repeat:h||c.times,origin:d.attr(),totalOrigin:g},fb.push(u),f&&!j&&!k&&(u.stop=!0,u.start=new Date-q*f,1==fb.length))return hb();k&&(u.start=new Date-u.ms*f),1==fb.length&&gb(hb)}a("raphael.anim.start."+d.id,d,c)}}function s(a){for(var b=0;be;e++)for(i=a[e],f=1,h=i.length;h>f;f+=2)c=b.x(i[f],i[f+1]),d=b.y(i[f],i[f+1]),i[f]=c,i[f+1]=d;return a};if(b._g=z,b.type=z.win.SVGAngle||z.doc.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure","1.1")?"SVG":"VML","VML"==b.type){var qa,ra=z.doc.createElement("div");if(ra.innerHTML='',qa=ra.firstChild,qa.style.behavior="url(#default#VML)",!qa||"object"!=typeof qa.adj)return b.type=F;ra=null}b.svg=!(b.vml="VML"==b.type),b._Paper=B,b.fn=u=B.prototype=b.prototype,b._id=0,b._oid=0,b.is=function(a,b){return b=L.call(b),"finite"==b?!X[y](+a):"array"==b?a instanceof Array:"null"==b&&null===a||b==typeof a&&null!==a||"object"==b&&a===Object(a)||"array"==b&&Array.isArray&&Array.isArray(a)||V.call(a).slice(8,-1).toLowerCase()==b},b.angle=function(a,c,d,e,f,g){if(null==f){var h=a-d,i=c-e;return h||i?(180+180*M.atan2(-i,-h)/R+360)%360:0}return b.angle(a,c,f,g)-b.angle(d,e,f,g)},b.rad=function(a){return a%360*R/180},b.deg=function(a){return Math.round(180*a/R%360*1e3)/1e3},b.snapTo=function(a,c,d){if(d=b.is(d,"finite")?d:10,b.is(a,U)){for(var e=a.length;e--;)if(P(a[e]-c)<=d)return a[e]}else{a=+a;var f=c%a;if(d>f)return c-f;if(f>a-d)return c-f+a}return c};b.createUUID=function(a,b){return function(){return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(a,b).toUpperCase()}}(/[xy]/g,function(a){var b=16*M.random()|0,c="x"==a?b:3&b|8;return c.toString(16)});b.setWindow=function(c){a("raphael.setWindow",b,z.win,c),z.win=c,z.doc=z.win.document,b._engine.initWin&&b._engine.initWin(z.win)};var sa=function(a){if(b.vml){var c,d=/^\s+|\s+$/g;try{var f=new ActiveXObject("htmlfile");f.write(""),f.close(),c=f.body}catch(g){c=createPopup().document.body}var h=c.createTextRange();sa=e(function(a){try{c.style.color=H(a).replace(d,F);var b=h.queryCommandValue("ForeColor");return b=(255&b)<<16|65280&b|(16711680&b)>>>16,"#"+("000000"+b.toString(16)).slice(-6)}catch(e){return"none"}})}else{var i=z.doc.createElement("i");i.title="Raphaël Colour Picker",i.style.display="none",z.doc.body.appendChild(i),sa=e(function(a){return i.style.color=a,z.doc.defaultView.getComputedStyle(i,F).getPropertyValue("color")})}return sa(a)},ta=function(){return"hsb("+[this.h,this.s,this.b]+")"},ua=function(){return"hsl("+[this.h,this.s,this.l]+")"},va=function(){return this.hex},wa=function(a,c,d){if(null==c&&b.is(a,"object")&&"r"in a&&"g"in a&&"b"in a&&(d=a.b,c=a.g,a=a.r),null==c&&b.is(a,T)){var e=b.getRGB(a);a=e.r,c=e.g,d=e.b}return(a>1||c>1||d>1)&&(a/=255,c/=255,d/=255),[a,c,d]},xa=function(a,c,d,e){a*=255,c*=255,d*=255;var f={r:a,g:c,b:d,hex:b.rgb(a,c,d),toString:va};return b.is(e,"finite")&&(f.opacity=e),f};b.color=function(a){var c;return b.is(a,"object")&&"h"in a&&"s"in a&&"b"in a?(c=b.hsb2rgb(a),a.r=c.r,a.g=c.g,a.b=c.b,a.hex=c.hex):b.is(a,"object")&&"h"in a&&"s"in a&&"l"in a?(c=b.hsl2rgb(a),a.r=c.r,a.g=c.g,a.b=c.b,a.hex=c.hex):(b.is(a,"string")&&(a=b.getRGB(a)),b.is(a,"object")&&"r"in a&&"g"in a&&"b"in a?(c=b.rgb2hsl(a),a.h=c.h,a.s=c.s,a.l=c.l,c=b.rgb2hsb(a),a.v=c.b):(a={hex:"none"},a.r=a.g=a.b=a.h=a.s=a.v=a.l=-1)),a.toString=va,a},b.hsb2rgb=function(a,b,c,d){this.is(a,"object")&&"h"in a&&"s"in a&&"b"in a&&(c=a.b,b=a.s,d=a.o,a=a.h),a*=360;var e,f,g,h,i;return a=a%360/60,i=c*b,h=i*(1-P(a%2-1)),e=f=g=c-i,a=~~a,e+=[i,h,0,0,h,i][a],f+=[h,i,i,h,0,0][a],g+=[0,0,h,i,i,h][a],xa(e,f,g,d)},b.hsl2rgb=function(a,b,c,d){this.is(a,"object")&&"h"in a&&"s"in a&&"l"in a&&(c=a.l,b=a.s,a=a.h),(a>1||b>1||c>1)&&(a/=360,b/=100,c/=100),a*=360;var e,f,g,h,i;return a=a%360/60,i=2*b*(.5>c?c:1-c),h=i*(1-P(a%2-1)),e=f=g=c-i/2,a=~~a,e+=[i,h,0,0,h,i][a],f+=[h,i,i,h,0,0][a],g+=[0,0,h,i,i,h][a],xa(e,f,g,d)},b.rgb2hsb=function(a,b,c){c=wa(a,b,c),a=c[0],b=c[1],c=c[2];var d,e,f,g;return f=N(a,b,c),g=f-O(a,b,c),d=0==g?null:f==a?(b-c)/g:f==b?(c-a)/g+2:(a-b)/g+4,d=(d+360)%6*60/360,e=0==g?0:g/f,{h:d,s:e,b:f,toString:ta}},b.rgb2hsl=function(a,b,c){c=wa(a,b,c),a=c[0],b=c[1],c=c[2];var d,e,f,g,h,i;return g=N(a,b,c),h=O(a,b,c),i=g-h,d=0==i?null:g==a?(b-c)/i:g==b?(c-a)/i+2:(a-b)/i+4,d=(d+360)%6*60/360,f=(g+h)/2,e=0==i?0:.5>f?i/(2*f):i/(2-2*f),{h:d,s:e,l:f,toString:ua}},b._path2string=function(){return this.join(",").replace(fa,"$1")};b._preload=function(a,b){var c=z.doc.createElement("img");c.style.cssText="position:absolute;left:-9999em;top:-9999em",c.onload=function(){b.call(this),this.onload=null,z.doc.body.removeChild(this)},c.onerror=function(){z.doc.body.removeChild(this)},z.doc.body.appendChild(c),c.src=a};b.getRGB=e(function(a){if(!a||(a=H(a)).indexOf("-")+1)return{r:-1,g:-1,b:-1,hex:"none",error:1,toString:f};if("none"==a)return{r:-1,g:-1,b:-1,hex:"none",toString:f};!(ea[y](a.toLowerCase().substring(0,2))||"#"==a.charAt())&&(a=sa(a));var c,d,e,g,h,i,j=a.match(W);return j?(j[2]&&(e=_(j[2].substring(5),16),d=_(j[2].substring(3,5),16),c=_(j[2].substring(1,3),16)),j[3]&&(e=_((h=j[3].charAt(3))+h,16),d=_((h=j[3].charAt(2))+h,16),c=_((h=j[3].charAt(1))+h,16)),j[4]&&(i=j[4][I](da),c=$(i[0]),"%"==i[0].slice(-1)&&(c*=2.55),d=$(i[1]),"%"==i[1].slice(-1)&&(d*=2.55),e=$(i[2]),"%"==i[2].slice(-1)&&(e*=2.55),"rgba"==j[1].toLowerCase().slice(0,4)&&(g=$(i[3])),i[3]&&"%"==i[3].slice(-1)&&(g/=100)),j[5]?(i=j[5][I](da),c=$(i[0]),"%"==i[0].slice(-1)&&(c*=2.55),d=$(i[1]),"%"==i[1].slice(-1)&&(d*=2.55),e=$(i[2]),"%"==i[2].slice(-1)&&(e*=2.55),("deg"==i[0].slice(-3)||"°"==i[0].slice(-1))&&(c/=360),"hsba"==j[1].toLowerCase().slice(0,4)&&(g=$(i[3])),i[3]&&"%"==i[3].slice(-1)&&(g/=100),b.hsb2rgb(c,d,e,g)):j[6]?(i=j[6][I](da),c=$(i[0]),"%"==i[0].slice(-1)&&(c*=2.55),d=$(i[1]),"%"==i[1].slice(-1)&&(d*=2.55),e=$(i[2]),"%"==i[2].slice(-1)&&(e*=2.55),("deg"==i[0].slice(-3)||"°"==i[0].slice(-1))&&(c/=360),"hsla"==j[1].toLowerCase().slice(0,4)&&(g=$(i[3])),i[3]&&"%"==i[3].slice(-1)&&(g/=100),b.hsl2rgb(c,d,e,g)):(j={r:c,g:d,b:e,toString:f},j.hex="#"+(16777216|e|d<<8|c<<16).toString(16).slice(1),b.is(g,"finite")&&(j.opacity=g),j)):{r:-1,g:-1,b:-1,hex:"none",error:1,toString:f}},b),b.hsb=e(function(a,c,d){return b.hsb2rgb(a,c,d).hex}),b.hsl=e(function(a,c,d){return b.hsl2rgb(a,c,d).hex}),b.rgb=e(function(a,b,c){function d(a){return a+.5|0}return"#"+(16777216|d(c)|d(b)<<8|d(a)<<16).toString(16).slice(1)}),b.getColor=function(a){var b=this.getColor.start=this.getColor.start||{h:0,s:1,b:a||.75},c=this.hsb2rgb(b.h,b.s,b.b);return b.h+=.075,b.h>1&&(b.h=0,b.s-=.2,b.s<=0&&(this.getColor.start={h:0,s:1,b:b.b})),c.hex},b.getColor.reset=function(){delete this.start},b.parsePathString=function(a){if(!a)return null;var c=ya(a);if(c.arr)return Aa(c.arr);var d={a:7,c:6,h:1,l:2,m:2,r:4,q:4,s:4,t:2,v:1,z:0},e=[];return b.is(a,U)&&b.is(a[0],U)&&(e=Aa(a)),e.length||H(a).replace(ga,function(a,b,c){var f=[],g=b.toLowerCase();if(c.replace(ia,function(a,b){b&&f.push(+b)}),"m"==g&&f.length>2&&(e.push([b][D](f.splice(0,2))),g="l",b="m"==b?"l":"L"),"r"==g)e.push([b][D](f));else for(;f.length>=d[g]&&(e.push([b][D](f.splice(0,d[g]))),d[g]););}),e.toString=b._path2string,c.arr=Aa(e),e},b.parseTransformString=e(function(a){if(!a)return null;var c=[];return b.is(a,U)&&b.is(a[0],U)&&(c=Aa(a)),c.length||H(a).replace(ha,function(a,b,d){{var e=[];L.call(b)}d.replace(ia,function(a,b){b&&e.push(+b)}),c.push([b][D](e))}),c.toString=b._path2string,c});var ya=function(a){var b=ya.ps=ya.ps||{};return b[a]?b[a].sleep=100:b[a]={sleep:100},setTimeout(function(){for(var c in b)b[y](c)&&c!=a&&(b[c].sleep--,!b[c].sleep&&delete b[c])}),b[a]};b.findDotsAtSegment=function(a,b,c,d,e,f,g,h,i){var j=1-i,k=Q(j,3),l=Q(j,2),m=i*i,n=m*i,o=k*a+3*l*i*c+3*j*i*i*e+n*g,p=k*b+3*l*i*d+3*j*i*i*f+n*h,q=a+2*i*(c-a)+m*(e-2*c+a),r=b+2*i*(d-b)+m*(f-2*d+b),s=c+2*i*(e-c)+m*(g-2*e+c),t=d+2*i*(f-d)+m*(h-2*f+d),u=j*a+i*c,v=j*b+i*d,w=j*e+i*g,x=j*f+i*h,y=90-180*M.atan2(q-s,r-t)/R;return(q>s||t>r)&&(y+=180),{x:o,y:p,m:{x:q,y:r},n:{x:s,y:t},start:{x:u,y:v},end:{x:w,y:x},alpha:y}},b.bezierBBox=function(a,c,d,e,f,g,h,i){b.is(a,"array")||(a=[a,c,d,e,f,g,h,i]);var j=Ha.apply(null,a);return{x:j.min.x,y:j.min.y,x2:j.max.x,y2:j.max.y,width:j.max.x-j.min.x,height:j.max.y-j.min.y}},b.isPointInsideBBox=function(a,b,c){return b>=a.x&&b<=a.x2&&c>=a.y&&c<=a.y2},b.isBBoxIntersect=function(a,c){var d=b.isPointInsideBBox;return d(c,a.x,a.y)||d(c,a.x2,a.y)||d(c,a.x,a.y2)||d(c,a.x2,a.y2)||d(a,c.x,c.y)||d(a,c.x2,c.y)||d(a,c.x,c.y2)||d(a,c.x2,c.y2)||(a.xc.x||c.xa.x)&&(a.yc.y||c.ya.y)},b.pathIntersection=function(a,b){return m(a,b)},b.pathIntersectionNumber=function(a,b){return m(a,b,1)},b.isPointInsidePath=function(a,c,d){var e=b.pathBBox(a);return b.isPointInsideBBox(e,c,d)&&m(a,[["M",c,d],["H",e.x2+10]],1)%2==1},b._removedFactory=function(b){return function(){a("raphael.log",null,"Raphaël: you are calling to method “"+b+"” of removed object",b)}};var za=b.pathBBox=function(a){var b=ya(a);if(b.bbox)return c(b.bbox);if(!a)return{x:0,y:0,width:0,height:0,x2:0,y2:0};a=Ia(a);for(var d,e=0,f=0,g=[],h=[],i=0,j=a.length;j>i;i++)if(d=a[i],"M"==d[0])e=d[1],f=d[2],g.push(e),h.push(f);else{var k=Ha(e,f,d[1],d[2],d[3],d[4],d[5],d[6]);g=g[D](k.min.x,k.max.x),h=h[D](k.min.y,k.max.y),e=d[5],f=d[6]}var l=O[C](0,g),m=O[C](0,h),n=N[C](0,g),o=N[C](0,h),p=n-l,q=o-m,r={x:l,y:m,x2:n,y2:o,width:p,height:q,cx:l+p/2,cy:m+q/2};return b.bbox=c(r),r},Aa=function(a){var d=c(a);return d.toString=b._path2string,d},Ba=b._pathToRelative=function(a){var c=ya(a);if(c.rel)return Aa(c.rel);b.is(a,U)&&b.is(a&&a[0],U)||(a=b.parsePathString(a));var d=[],e=0,f=0,g=0,h=0,i=0;"M"==a[0][0]&&(e=a[0][1],f=a[0][2],g=e,h=f,i++,d.push(["M",e,f]));for(var j=i,k=a.length;k>j;j++){var l=d[j]=[],m=a[j];if(m[0]!=L.call(m[0]))switch(l[0]=L.call(m[0]),l[0]){case"a":l[1]=m[1],l[2]=m[2],l[3]=m[3],l[4]=m[4],l[5]=m[5],l[6]=+(m[6]-e).toFixed(3),l[7]=+(m[7]-f).toFixed(3);break;case"v":l[1]=+(m[1]-f).toFixed(3);break;case"m":g=m[1],h=m[2];default:for(var n=1,o=m.length;o>n;n++)l[n]=+(m[n]-(n%2?e:f)).toFixed(3)}else{l=d[j]=[],"m"==m[0]&&(g=m[1]+e,h=m[2]+f);for(var p=0,q=m.length;q>p;p++)d[j][p]=m[p]}var r=d[j].length;switch(d[j][0]){case"z":e=g,f=h;break;case"h":e+=+d[j][r-1];break;case"v":f+=+d[j][r-1];break;default:e+=+d[j][r-2],f+=+d[j][r-1]}}return d.toString=b._path2string,c.rel=Aa(d),d},Ca=b._pathToAbsolute=function(a){var c=ya(a);if(c.abs)return Aa(c.abs);if(b.is(a,U)&&b.is(a&&a[0],U)||(a=b.parsePathString(a)),!a||!a.length)return[["M",0,0]];var d=[],e=0,f=0,h=0,i=0,j=0;"M"==a[0][0]&&(e=+a[0][1],f=+a[0][2],h=e,i=f,j++,d[0]=["M",e,f]);for(var k,l,m=3==a.length&&"M"==a[0][0]&&"R"==a[1][0].toUpperCase()&&"Z"==a[2][0].toUpperCase(),n=j,o=a.length;o>n;n++){if(d.push(k=[]),l=a[n],l[0]!=aa.call(l[0]))switch(k[0]=aa.call(l[0]),k[0]){case"A":k[1]=l[1],k[2]=l[2],k[3]=l[3],k[4]=l[4],k[5]=l[5],k[6]=+(l[6]+e),k[7]=+(l[7]+f);break;case"V":k[1]=+l[1]+f;break;case"H":k[1]=+l[1]+e;break;case"R":for(var p=[e,f][D](l.slice(1)),q=2,r=p.length;r>q;q++)p[q]=+p[q]+e,p[++q]=+p[q]+f;d.pop(),d=d[D](g(p,m));break;case"M":h=+l[1]+e,i=+l[2]+f;default:for(q=1,r=l.length;r>q;q++)k[q]=+l[q]+(q%2?e:f)}else if("R"==l[0])p=[e,f][D](l.slice(1)),d.pop(),d=d[D](g(p,m)),k=["R"][D](l.slice(-2));else for(var s=0,t=l.length;t>s;s++)k[s]=l[s];switch(k[0]){case"Z":e=h,f=i;break;case"H":e=k[1];break;case"V":f=k[1];break;case"M":h=k[k.length-2],i=k[k.length-1];default:e=k[k.length-2],f=k[k.length-1]}}return d.toString=b._path2string,c.abs=Aa(d),d},Da=function(a,b,c,d){return[a,b,c,d,c,d]},Ea=function(a,b,c,d,e,f){var g=1/3,h=2/3;return[g*a+h*c,g*b+h*d,g*e+h*c,g*f+h*d,e,f]},Fa=function(a,b,c,d,f,g,h,i,j,k){var l,m=120*R/180,n=R/180*(+f||0),o=[],p=e(function(a,b,c){var d=a*M.cos(c)-b*M.sin(c),e=a*M.sin(c)+b*M.cos(c);return{x:d,y:e}});if(k)y=k[0],z=k[1],w=k[2],x=k[3];else{l=p(a,b,-n),a=l.x,b=l.y,l=p(i,j,-n),i=l.x,j=l.y;var q=(M.cos(R/180*f),M.sin(R/180*f),(a-i)/2),r=(b-j)/2,s=q*q/(c*c)+r*r/(d*d);s>1&&(s=M.sqrt(s),c=s*c,d=s*d);var t=c*c,u=d*d,v=(g==h?-1:1)*M.sqrt(P((t*u-t*r*r-u*q*q)/(t*r*r+u*q*q))),w=v*c*r/d+(a+i)/2,x=v*-d*q/c+(b+j)/2,y=M.asin(((b-x)/d).toFixed(9)),z=M.asin(((j-x)/d).toFixed(9));y=w>a?R-y:y,z=w>i?R-z:z,0>y&&(y=2*R+y),0>z&&(z=2*R+z),h&&y>z&&(y-=2*R),!h&&z>y&&(z-=2*R)}var A=z-y;if(P(A)>m){var B=z,C=i,E=j;z=y+m*(h&&z>y?1:-1),i=w+c*M.cos(z),j=x+d*M.sin(z),o=Fa(i,j,c,d,f,0,h,C,E,[z,B,w,x])}A=z-y;var F=M.cos(y),G=M.sin(y),H=M.cos(z),J=M.sin(z),K=M.tan(A/4),L=4/3*c*K,N=4/3*d*K,O=[a,b],Q=[a+L*G,b-N*F],S=[i+L*J,j-N*H],T=[i,j];if(Q[0]=2*O[0]-Q[0],Q[1]=2*O[1]-Q[1],k)return[Q,S,T][D](o);o=[Q,S,T][D](o).join()[I](",");for(var U=[],V=0,W=o.length;W>V;V++)U[V]=V%2?p(o[V-1],o[V],n).y:p(o[V],o[V+1],n).x;return U},Ga=function(a,b,c,d,e,f,g,h,i){var j=1-i;return{x:Q(j,3)*a+3*Q(j,2)*i*c+3*j*i*i*e+Q(i,3)*g,y:Q(j,3)*b+3*Q(j,2)*i*d+3*j*i*i*f+Q(i,3)*h}},Ha=e(function(a,b,c,d,e,f,g,h){var i,j=e-2*c+a-(g-2*e+c),k=2*(c-a)-2*(e-c),l=a-c,m=(-k+M.sqrt(k*k-4*j*l))/2/j,n=(-k-M.sqrt(k*k-4*j*l))/2/j,o=[b,h],p=[a,g];return P(m)>"1e12"&&(m=.5),P(n)>"1e12"&&(n=.5),m>0&&1>m&&(i=Ga(a,b,c,d,e,f,g,h,m),p.push(i.x),o.push(i.y)),n>0&&1>n&&(i=Ga(a,b,c,d,e,f,g,h,n),p.push(i.x),o.push(i.y)),j=f-2*d+b-(h-2*f+d),k=2*(d-b)-2*(f-d),l=b-d,m=(-k+M.sqrt(k*k-4*j*l))/2/j,n=(-k-M.sqrt(k*k-4*j*l))/2/j,P(m)>"1e12"&&(m=.5),P(n)>"1e12"&&(n=.5),m>0&&1>m&&(i=Ga(a,b,c,d,e,f,g,h,m),p.push(i.x),o.push(i.y)),n>0&&1>n&&(i=Ga(a,b,c,d,e,f,g,h,n),p.push(i.x),o.push(i.y)),{min:{x:O[C](0,p),y:O[C](0,o)},max:{x:N[C](0,p),y:N[C](0,o)}}}),Ia=b._path2curve=e(function(a,b){var c=!b&&ya(a);if(!b&&c.curve)return Aa(c.curve);for(var d=Ca(a),e=b&&Ca(b),f={x:0,y:0,bx:0,by:0,X:0,Y:0,qx:null,qy:null},g={x:0,y:0,bx:0,by:0,X:0,Y:0,qx:null,qy:null},h=(function(a,b,c){var d,e,f={T:1,Q:1};if(!a)return["C",b.x,b.y,b.x,b.y,b.x,b.y];switch(!(a[0]in f)&&(b.qx=b.qy=null),a[0]){case"M":b.X=a[1],b.Y=a[2];break;case"A":a=["C"][D](Fa[C](0,[b.x,b.y][D](a.slice(1))));break;case"S":"C"==c||"S"==c?(d=2*b.x-b.bx,e=2*b.y-b.by):(d=b.x,e=b.y),a=["C",d,e][D](a.slice(1));break;case"T":"Q"==c||"T"==c?(b.qx=2*b.x-b.qx,b.qy=2*b.y-b.qy):(b.qx=b.x,b.qy=b.y),a=["C"][D](Ea(b.x,b.y,b.qx,b.qy,a[1],a[2]));break;case"Q":b.qx=a[1],b.qy=a[2],a=["C"][D](Ea(b.x,b.y,a[1],a[2],a[3],a[4]));break;case"L":a=["C"][D](Da(b.x,b.y,a[1],a[2]));break;case"H":a=["C"][D](Da(b.x,b.y,a[1],b.y));break;case"V":a=["C"][D](Da(b.x,b.y,b.x,a[1]));break;case"Z":a=["C"][D](Da(b.x,b.y,b.X,b.Y))}return a}),i=function(a,b){if(a[b].length>7){a[b].shift();for(var c=a[b];c.length;)k[b]="A",e&&(l[b]="A"),a.splice(b++,0,["C"][D](c.splice(0,6)));a.splice(b,1),p=N(d.length,e&&e.length||0)}},j=function(a,b,c,f,g){a&&b&&"M"==a[g][0]&&"M"!=b[g][0]&&(b.splice(g,0,["M",f.x,f.y]),c.bx=0,c.by=0,c.x=a[g][1],c.y=a[g][2],p=N(d.length,e&&e.length||0))},k=[],l=[],m="",n="",o=0,p=N(d.length,e&&e.length||0);p>o;o++){d[o]&&(m=d[o][0]),"C"!=m&&(k[o]=m,o&&(n=k[o-1])),d[o]=h(d[o],f,n),"A"!=k[o]&&"C"==m&&(k[o]="C"),i(d,o),e&&(e[o]&&(m=e[o][0]),"C"!=m&&(l[o]=m,o&&(n=l[o-1])),e[o]=h(e[o],g,n),"A"!=l[o]&&"C"==m&&(l[o]="C"),i(e,o)),j(d,e,f,g,o),j(e,d,g,f,o);var q=d[o],r=e&&e[o],s=q.length,t=e&&r.length;f.x=q[s-2],f.y=q[s-1],f.bx=$(q[s-4])||f.x,f.by=$(q[s-3])||f.y,g.bx=e&&($(r[t-4])||g.x),g.by=e&&($(r[t-3])||g.y),g.x=e&&r[t-2],g.y=e&&r[t-1]}return e||(c.curve=Aa(d)),e?[d,e]:d},null,Aa),Ja=(b._parseDots=e(function(a){for(var c=[],d=0,e=a.length;e>d;d++){var f={},g=a[d].match(/^([^:]*):?([\d\.]*)/);if(f.color=b.getRGB(g[1]),f.color.error)return null;f.opacity=f.color.opacity,f.color=f.color.hex,g[2]&&(f.offset=g[2]+"%"),c.push(f)}for(d=1,e=c.length-1;e>d;d++)if(!c[d].offset){for(var h=$(c[d-1].offset||0),i=0,j=d+1;e>j;j++)if(c[j].offset){i=c[j].offset;break}i||(i=100,j=e),i=$(i);for(var k=(i-h)/(j-d+1);j>d;d++)h+=k,c[d].offset=h+"%"}return c}),b._tear=function(a,b){a==b.top&&(b.top=a.prev),a==b.bottom&&(b.bottom=a.next),a.next&&(a.next.prev=a.prev),a.prev&&(a.prev.next=a.next)}),Ka=(b._tofront=function(a,b){b.top!==a&&(Ja(a,b),a.next=null,a.prev=b.top,b.top.next=a,b.top=a)},b._toback=function(a,b){b.bottom!==a&&(Ja(a,b),a.next=b.bottom,a.prev=null,b.bottom.prev=a,b.bottom=a)},b._insertafter=function(a,b,c){Ja(a,c),b==c.top&&(c.top=a),b.next&&(b.next.prev=a),a.next=b.next,a.prev=b,b.next=a},b._insertbefore=function(a,b,c){Ja(a,c),b==c.bottom&&(c.bottom=a),b.prev&&(b.prev.next=a),a.prev=b.prev,b.prev=a,a.next=b},b.toMatrix=function(a,b){var c=za(a),d={_:{transform:F},getBBox:function(){return c}};return La(d,b),d.matrix}),La=(b.transformPath=function(a,b){return pa(a,Ka(a,b))},b._extractTransform=function(a,c){if(null==c)return a._.transform;c=H(c).replace(/\.{3}|\u2026/g,a._.transform||F);var d=b.parseTransformString(c),e=0,f=0,g=0,h=1,i=1,j=a._,k=new n;if(j.transform=d||[],d)for(var l=0,m=d.length;m>l;l++){var o,p,q,r,s,t=d[l],u=t.length,v=H(t[0]).toLowerCase(),w=t[0]!=v,x=w?k.invert():0;"t"==v&&3==u?w?(o=x.x(0,0),p=x.y(0,0),q=x.x(t[1],t[2]),r=x.y(t[1],t[2]),k.translate(q-o,r-p)):k.translate(t[1],t[2]):"r"==v?2==u?(s=s||a.getBBox(1),k.rotate(t[1],s.x+s.width/2,s.y+s.height/2),e+=t[1]):4==u&&(w?(q=x.x(t[2],t[3]),r=x.y(t[2],t[3]),k.rotate(t[1],q,r)):k.rotate(t[1],t[2],t[3]),e+=t[1]):"s"==v?2==u||3==u?(s=s||a.getBBox(1),k.scale(t[1],t[u-1],s.x+s.width/2,s.y+s.height/2),h*=t[1],i*=t[u-1]):5==u&&(w?(q=x.x(t[3],t[4]),r=x.y(t[3],t[4]),k.scale(t[1],t[2],q,r)):k.scale(t[1],t[2],t[3],t[4]),h*=t[1],i*=t[2]):"m"==v&&7==u&&k.add(t[1],t[2],t[3],t[4],t[5],t[6]),j.dirtyT=1,a.matrix=k}a.matrix=k,j.sx=h,j.sy=i,j.deg=e,j.dx=f=k.e,j.dy=g=k.f,1==h&&1==i&&!e&&j.bbox?(j.bbox.x+=+f,j.bbox.y+=+g):j.dirtyT=1}),Ma=function(a){var b=a[0];switch(b.toLowerCase()){case"t":return[b,0,0];case"m":return[b,1,0,0,1,0,0];case"r":return 4==a.length?[b,0,a[2],a[3]]:[b,0];case"s":return 5==a.length?[b,1,1,a[3],a[4]]:3==a.length?[b,1,1]:[b,1]}},Na=b._equaliseTransform=function(a,c){ -c=H(c).replace(/\.{3}|\u2026/g,a),a=b.parseTransformString(a)||[],c=b.parseTransformString(c)||[];for(var d,e,f,g,h=N(a.length,c.length),i=[],j=[],k=0;h>k;k++){if(f=a[k]||Ma(c[k]),g=c[k]||Ma(f),f[0]!=g[0]||"r"==f[0].toLowerCase()&&(f[2]!=g[2]||f[3]!=g[3])||"s"==f[0].toLowerCase()&&(f[3]!=g[3]||f[4]!=g[4]))return;for(i[k]=[],j[k]=[],d=0,e=N(f.length,g.length);e>d;d++)d in f&&(i[k][d]=f[d]),d in g&&(j[k][d]=g[d])}return{from:i,to:j}};b._getContainer=function(a,c,d,e){var f;return f=null!=e||b.is(a,"object")?a:z.doc.getElementById(a),null!=f?f.tagName?null==c?{container:f,width:f.style.pixelWidth||f.offsetWidth,height:f.style.pixelHeight||f.offsetHeight}:{container:f,width:c,height:d}:{container:1,x:a,y:c,width:d,height:e}:void 0},b.pathToRelative=Ba,b._engine={},b.path2curve=Ia,b.matrix=function(a,b,c,d,e,f){return new n(a,b,c,d,e,f)},function(a){function c(a){return a[0]*a[0]+a[1]*a[1]}function d(a){var b=M.sqrt(c(a));a[0]&&(a[0]/=b),a[1]&&(a[1]/=b)}a.add=function(a,b,c,d,e,f){var g,h,i,j,k=[[],[],[]],l=[[this.a,this.c,this.e],[this.b,this.d,this.f],[0,0,1]],m=[[a,c,e],[b,d,f],[0,0,1]];for(a&&a instanceof n&&(m=[[a.a,a.c,a.e],[a.b,a.d,a.f],[0,0,1]]),g=0;3>g;g++)for(h=0;3>h;h++){for(j=0,i=0;3>i;i++)j+=l[g][i]*m[i][h];k[g][h]=j}this.a=k[0][0],this.b=k[1][0],this.c=k[0][1],this.d=k[1][1],this.e=k[0][2],this.f=k[1][2]},a.invert=function(){var a=this,b=a.a*a.d-a.b*a.c;return new n(a.d/b,-a.b/b,-a.c/b,a.a/b,(a.c*a.f-a.d*a.e)/b,(a.b*a.e-a.a*a.f)/b)},a.clone=function(){return new n(this.a,this.b,this.c,this.d,this.e,this.f)},a.translate=function(a,b){this.add(1,0,0,1,a,b)},a.scale=function(a,b,c,d){null==b&&(b=a),(c||d)&&this.add(1,0,0,1,c,d),this.add(a,0,0,b,0,0),(c||d)&&this.add(1,0,0,1,-c,-d)},a.rotate=function(a,c,d){a=b.rad(a),c=c||0,d=d||0;var e=+M.cos(a).toFixed(9),f=+M.sin(a).toFixed(9);this.add(e,f,-f,e,c,d),this.add(1,0,0,1,-c,-d)},a.x=function(a,b){return a*this.a+b*this.c+this.e},a.y=function(a,b){return a*this.b+b*this.d+this.f},a.get=function(a){return+this[H.fromCharCode(97+a)].toFixed(4)},a.toString=function(){return b.svg?"matrix("+[this.get(0),this.get(1),this.get(2),this.get(3),this.get(4),this.get(5)].join()+")":[this.get(0),this.get(2),this.get(1),this.get(3),0,0].join()},a.toFilter=function(){return"progid:DXImageTransform.Microsoft.Matrix(M11="+this.get(0)+", M12="+this.get(2)+", M21="+this.get(1)+", M22="+this.get(3)+", Dx="+this.get(4)+", Dy="+this.get(5)+", sizingmethod='auto expand')"},a.offset=function(){return[this.e.toFixed(4),this.f.toFixed(4)]},a.split=function(){var a={};a.dx=this.e,a.dy=this.f;var e=[[this.a,this.c],[this.b,this.d]];a.scalex=M.sqrt(c(e[0])),d(e[0]),a.shear=e[0][0]*e[1][0]+e[0][1]*e[1][1],e[1]=[e[1][0]-e[0][0]*a.shear,e[1][1]-e[0][1]*a.shear],a.scaley=M.sqrt(c(e[1])),d(e[1]),a.shear/=a.scaley;var f=-e[0][1],g=e[1][1];return 0>g?(a.rotate=b.deg(M.acos(g)),0>f&&(a.rotate=360-a.rotate)):a.rotate=b.deg(M.asin(f)),a.isSimple=!(+a.shear.toFixed(9)||a.scalex.toFixed(9)!=a.scaley.toFixed(9)&&a.rotate),a.isSuperSimple=!+a.shear.toFixed(9)&&a.scalex.toFixed(9)==a.scaley.toFixed(9)&&!a.rotate,a.noRotation=!+a.shear.toFixed(9)&&!a.rotate,a},a.toTransformString=function(a){var b=a||this[I]();return b.isSimple?(b.scalex=+b.scalex.toFixed(4),b.scaley=+b.scaley.toFixed(4),b.rotate=+b.rotate.toFixed(4),(b.dx||b.dy?"t"+[b.dx,b.dy]:F)+(1!=b.scalex||1!=b.scaley?"s"+[b.scalex,b.scaley,0,0]:F)+(b.rotate?"r"+[b.rotate,0,0]:F)):"m"+[this.get(0),this.get(1),this.get(2),this.get(3),this.get(4),this.get(5)]}}(n.prototype);for(var Oa=function(){this.returnValue=!1},Pa=function(){return this.originalEvent.preventDefault()},Qa=function(){this.cancelBubble=!0},Ra=function(){return this.originalEvent.stopPropagation()},Sa=function(a){var b=z.doc.documentElement.scrollTop||z.doc.body.scrollTop,c=z.doc.documentElement.scrollLeft||z.doc.body.scrollLeft;return{x:a.clientX+c,y:a.clientY+b}},Ta=function(){return z.doc.addEventListener?function(a,b,c,d){var e=function(a){var b=Sa(a);return c.call(d,a,b.x,b.y)};if(a.addEventListener(b,e,!1),E&&K[b]){var f=function(b){for(var e=Sa(b),f=b,g=0,h=b.targetTouches&&b.targetTouches.length;h>g;g++)if(b.targetTouches[g].target==a){b=b.targetTouches[g],b.originalEvent=f,b.preventDefault=Pa,b.stopPropagation=Ra;break}return c.call(d,b,e.x,e.y)};a.addEventListener(K[b],f,!1)}return function(){return a.removeEventListener(b,e,!1),E&&K[b]&&a.removeEventListener(K[b],f,!1),!0}}:z.doc.attachEvent?function(a,b,c,d){var e=function(a){a=a||z.win.event;var b=z.doc.documentElement.scrollTop||z.doc.body.scrollTop,e=z.doc.documentElement.scrollLeft||z.doc.body.scrollLeft,f=a.clientX+e,g=a.clientY+b;return a.preventDefault=a.preventDefault||Oa,a.stopPropagation=a.stopPropagation||Qa,c.call(d,a,f,g)};a.attachEvent("on"+b,e);var f=function(){return a.detachEvent("on"+b,e),!0};return f}:void 0}(),Ua=[],Va=function(b){for(var c,d=b.clientX,e=b.clientY,f=z.doc.documentElement.scrollTop||z.doc.body.scrollTop,g=z.doc.documentElement.scrollLeft||z.doc.body.scrollLeft,h=Ua.length;h--;){if(c=Ua[h],E&&b.touches){for(var i,j=b.touches.length;j--;)if(i=b.touches[j],i.identifier==c.el._drag.id){d=i.clientX,e=i.clientY,(b.originalEvent?b.originalEvent:b).preventDefault();break}}else b.preventDefault();var k,l=c.el.node,m=l.nextSibling,n=l.parentNode,o=l.style.display;z.win.opera&&n.removeChild(l),l.style.display="none",k=c.el.paper.getElementByPoint(d,e),l.style.display=o,z.win.opera&&(m?n.insertBefore(l,m):n.appendChild(l)),k&&a("raphael.drag.over."+c.el.id,c.el,k),d+=g,e+=f,a("raphael.drag.move."+c.el.id,c.move_scope||c.el,d-c.el._drag.x,e-c.el._drag.y,d,e,b)}},Wa=function(c){b.unmousemove(Va).unmouseup(Wa);for(var d,e=Ua.length;e--;)d=Ua[e],d.el._drag={},a("raphael.drag.end."+d.el.id,d.end_scope||d.start_scope||d.move_scope||d.el,c);Ua=[]},Xa=b.el={},Ya=J.length;Ya--;)!function(a){b[a]=Xa[a]=function(c,d){return b.is(c,"function")&&(this.events=this.events||[],this.events.push({name:a,f:c,unbind:Ta(this.shape||this.node||z.doc,a,c,d||this)})),this},b["un"+a]=Xa["un"+a]=function(c){for(var d=this.events||[],e=d.length;e--;)d[e].name!=a||!b.is(c,"undefined")&&d[e].f!=c||(d[e].unbind(),d.splice(e,1),!d.length&&delete this.events);return this}}(J[Ya]);Xa.data=function(c,d){var e=ja[this.id]=ja[this.id]||{};if(0==arguments.length)return e;if(1==arguments.length){if(b.is(c,"object")){for(var f in c)c[y](f)&&this.data(f,c[f]);return this}return a("raphael.data.get."+this.id,this,e[c],c),e[c]}return e[c]=d,a("raphael.data.set."+this.id,this,d,c),this},Xa.removeData=function(a){return null==a?ja[this.id]={}:ja[this.id]&&delete ja[this.id][a],this},Xa.getData=function(){return c(ja[this.id]||{})},Xa.hover=function(a,b,c,d){return this.mouseover(a,c).mouseout(b,d||c)},Xa.unhover=function(a,b){return this.unmouseover(a).unmouseout(b)};var Za=[];Xa.drag=function(c,d,e,f,g,h){function i(i){(i.originalEvent||i).preventDefault();var j=i.clientX,k=i.clientY,l=z.doc.documentElement.scrollTop||z.doc.body.scrollTop,m=z.doc.documentElement.scrollLeft||z.doc.body.scrollLeft;if(this._drag.id=i.identifier,E&&i.touches)for(var n,o=i.touches.length;o--;)if(n=i.touches[o],this._drag.id=n.identifier,n.identifier==this._drag.id){j=n.clientX,k=n.clientY;break}this._drag.x=j+m,this._drag.y=k+l,!Ua.length&&b.mousemove(Va).mouseup(Wa),Ua.push({el:this,move_scope:f,start_scope:g,end_scope:h}),d&&a.on("raphael.drag.start."+this.id,d),c&&a.on("raphael.drag.move."+this.id,c),e&&a.on("raphael.drag.end."+this.id,e),a("raphael.drag.start."+this.id,g||f||this,i.clientX+m,i.clientY+l,i)}return this._drag={},Za.push({el:this,start:i}),this.mousedown(i),this},Xa.onDragOver=function(b){b?a.on("raphael.drag.over."+this.id,b):a.unbind("raphael.drag.over."+this.id)},Xa.undrag=function(){for(var c=Za.length;c--;)Za[c].el==this&&(this.unmousedown(Za[c].start),Za.splice(c,1),a.unbind("raphael.drag.*."+this.id));!Za.length&&b.unmousemove(Va).unmouseup(Wa),Ua=[]},u.circle=function(a,c,d){var e=b._engine.circle(this,a||0,c||0,d||0);return this.__set__&&this.__set__.push(e),e},u.rect=function(a,c,d,e,f){var g=b._engine.rect(this,a||0,c||0,d||0,e||0,f||0);return this.__set__&&this.__set__.push(g),g},u.ellipse=function(a,c,d,e){var f=b._engine.ellipse(this,a||0,c||0,d||0,e||0);return this.__set__&&this.__set__.push(f),f},u.path=function(a){a&&!b.is(a,T)&&!b.is(a[0],U)&&(a+=F);var c=b._engine.path(b.format[C](b,arguments),this);return this.__set__&&this.__set__.push(c),c},u.image=function(a,c,d,e,f){var g=b._engine.image(this,a||"about:blank",c||0,d||0,e||0,f||0);return this.__set__&&this.__set__.push(g),g},u.text=function(a,c,d){var e=b._engine.text(this,a||0,c||0,H(d));return this.__set__&&this.__set__.push(e),e},u.set=function(a){!b.is(a,"array")&&(a=Array.prototype.splice.call(arguments,0,arguments.length));var c=new jb(a);return this.__set__&&this.__set__.push(c),c.paper=this,c.type="set",c},u.setStart=function(a){this.__set__=a||this.set()},u.setFinish=function(a){var b=this.__set__;return delete this.__set__,b},u.getSize=function(){var a=this.canvas.parentNode;return{width:a.offsetWidth,height:a.offsetHeight}},u.setSize=function(a,c){return b._engine.setSize.call(this,a,c)},u.setViewBox=function(a,c,d,e,f){return b._engine.setViewBox.call(this,a,c,d,e,f)},u.top=u.bottom=null,u.raphael=b;var $a=function(a){var b=a.getBoundingClientRect(),c=a.ownerDocument,d=c.body,e=c.documentElement,f=e.clientTop||d.clientTop||0,g=e.clientLeft||d.clientLeft||0,h=b.top+(z.win.pageYOffset||e.scrollTop||d.scrollTop)-f,i=b.left+(z.win.pageXOffset||e.scrollLeft||d.scrollLeft)-g;return{y:h,x:i}};u.getElementByPoint=function(a,b){var c=this,d=c.canvas,e=z.doc.elementFromPoint(a,b);if(z.win.opera&&"svg"==e.tagName){var f=$a(d),g=d.createSVGRect();g.x=a-f.x,g.y=b-f.y,g.width=g.height=1;var h=d.getIntersectionList(g,null);h.length&&(e=h[h.length-1])}if(!e)return null;for(;e.parentNode&&e!=d.parentNode&&!e.raphael;)e=e.parentNode;return e==c.canvas.parentNode&&(e=d),e=e&&e.raphael?c.getById(e.raphaelid):null},u.getElementsByBBox=function(a){var c=this.set();return this.forEach(function(d){b.isBBoxIntersect(d.getBBox(),a)&&c.push(d)}),c},u.getById=function(a){for(var b=this.bottom;b;){if(b.id==a)return b;b=b.next}return null},u.forEach=function(a,b){for(var c=this.bottom;c;){if(a.call(b,c)===!1)return this;c=c.next}return this},u.getElementsByPoint=function(a,b){var c=this.set();return this.forEach(function(d){d.isPointInside(a,b)&&c.push(d)}),c},Xa.isPointInside=function(a,c){var d=this.realPath=oa[this.type](this);return this.attr("transform")&&this.attr("transform").length&&(d=b.transformPath(d,this.attr("transform"))),b.isPointInsidePath(d,a,c)},Xa.getBBox=function(a){if(this.removed)return{};var b=this._;return a?((b.dirty||!b.bboxwt)&&(this.realPath=oa[this.type](this),b.bboxwt=za(this.realPath),b.bboxwt.toString=o,b.dirty=0),b.bboxwt):((b.dirty||b.dirtyT||!b.bbox)&&((b.dirty||!this.realPath)&&(b.bboxwt=0,this.realPath=oa[this.type](this)),b.bbox=za(pa(this.realPath,this.matrix)),b.bbox.toString=o,b.dirty=b.dirtyT=0),b.bbox)},Xa.clone=function(){if(this.removed)return null;var a=this.paper[this.type]().attr(this.attr());return this.__set__&&this.__set__.push(a),a},Xa.glow=function(a){if("text"==this.type)return null;a=a||{};var b={width:(a.width||10)+(+this.attr("stroke-width")||1),fill:a.fill||!1,opacity:null==a.opacity?.5:a.opacity,offsetx:a.offsetx||0,offsety:a.offsety||0,color:a.color||"#000"},c=b.width/2,d=this.paper,e=d.set(),f=this.realPath||oa[this.type](this);f=this.matrix?pa(f,this.matrix):f;for(var g=1;c+1>g;g++)e.push(d.path(f).attr({stroke:b.color,fill:b.fill?b.color:"none","stroke-linejoin":"round","stroke-linecap":"round","stroke-width":+(b.width/c*g).toFixed(3),opacity:+(b.opacity/c).toFixed(3)}));return e.insertBefore(this).translate(b.offsetx,b.offsety)};var _a=function(a,c,d,e,f,g,h,k,l){return null==l?i(a,c,d,e,f,g,h,k):b.findDotsAtSegment(a,c,d,e,f,g,h,k,j(a,c,d,e,f,g,h,k,l))},ab=function(a,c){return function(d,e,f){d=Ia(d);for(var g,h,i,j,k,l="",m={},n=0,o=0,p=d.length;p>o;o++){if(i=d[o],"M"==i[0])g=+i[1],h=+i[2];else{if(j=_a(g,h,i[1],i[2],i[3],i[4],i[5],i[6]),n+j>e){if(c&&!m.start){if(k=_a(g,h,i[1],i[2],i[3],i[4],i[5],i[6],e-n),l+=["C"+k.start.x,k.start.y,k.m.x,k.m.y,k.x,k.y],f)return l;m.start=l,l=["M"+k.x,k.y+"C"+k.n.x,k.n.y,k.end.x,k.end.y,i[5],i[6]].join(),n+=j,g=+i[5],h=+i[6];continue}if(!a&&!c)return k=_a(g,h,i[1],i[2],i[3],i[4],i[5],i[6],e-n),{x:k.x,y:k.y,alpha:k.alpha}}n+=j,g=+i[5],h=+i[6]}l+=i.shift()+i}return m.end=l,k=a?n:c?m:b.findDotsAtSegment(g,h,i[0],i[1],i[2],i[3],i[4],i[5],1),k.alpha&&(k={x:k.x,y:k.y,alpha:k.alpha}),k}},bb=ab(1),cb=ab(),db=ab(0,1);b.getTotalLength=bb,b.getPointAtLength=cb,b.getSubpath=function(a,b,c){if(this.getTotalLength(a)-c<1e-6)return db(a,b).end;var d=db(a,c,1);return b?db(d,b).end:d},Xa.getTotalLength=function(){var a=this.getPath();if(a)return this.node.getTotalLength?this.node.getTotalLength():bb(a)},Xa.getPointAtLength=function(a){var b=this.getPath();if(b)return cb(b,a)},Xa.getPath=function(){var a,c=b._getPath[this.type];if("text"!=this.type&&"set"!=this.type)return c&&(a=c(this)),a},Xa.getSubpath=function(a,c){var d=this.getPath();if(d)return b.getSubpath(d,a,c)};var eb=b.easing_formulas={linear:function(a){return a},"<":function(a){return Q(a,1.7)},">":function(a){return Q(a,.48)},"<>":function(a){var b=.48-a/1.04,c=M.sqrt(.1734+b*b),d=c-b,e=Q(P(d),1/3)*(0>d?-1:1),f=-c-b,g=Q(P(f),1/3)*(0>f?-1:1),h=e+g+.5;return 3*(1-h)*h*h+h*h*h},backIn:function(a){var b=1.70158;return a*a*((b+1)*a-b)},backOut:function(a){a-=1;var b=1.70158;return a*a*((b+1)*a+b)+1},elastic:function(a){return a==!!a?a:Q(2,-10*a)*M.sin(2*(a-.075)*R/.3)+1},bounce:function(a){var b,c=7.5625,d=2.75;return 1/d>a?b=c*a*a:2/d>a?(a-=1.5/d,b=c*a*a+.75):2.5/d>a?(a-=2.25/d,b=c*a*a+.9375):(a-=2.625/d,b=c*a*a+.984375),b}};eb.easeIn=eb["ease-in"]=eb["<"],eb.easeOut=eb["ease-out"]=eb[">"],eb.easeInOut=eb["ease-in-out"]=eb["<>"],eb["back-in"]=eb.backIn,eb["back-out"]=eb.backOut;var fb=[],gb=window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(a){setTimeout(a,16)},hb=function(){for(var c=+new Date,d=0;dh))if(i>h){var q=j(h/i);for(var s in k)if(k[y](s)){switch(ca[s]){case S:f=+k[s]+q*i*l[s];break;case"colour":f="rgb("+[ib(Z(k[s].r+q*i*l[s].r)),ib(Z(k[s].g+q*i*l[s].g)),ib(Z(k[s].b+q*i*l[s].b))].join(",")+")";break;case"path":f=[];for(var t=0,u=k[s].length;u>t;t++){f[t]=[k[s][t][0]];for(var v=1,w=k[s][t].length;w>v;v++)f[t][v]=+k[s][t][v]+q*i*l[s][t][v];f[t]=f[t].join(G)}f=f.join(G);break;case"transform":if(l[s].real)for(f=[],t=0,u=k[s].length;u>t;t++)for(f[t]=[k[s][t][0]],v=1,w=k[s][t].length;w>v;v++)f[t][v]=k[s][t][v]+q*i*l[s][t][v];else{var x=function(a){return+k[s][a]+q*i*l[s][a]};f=[["m",x(0),x(1),x(2),x(3),x(4),x(5)]]}break;case"csv":if("clip-rect"==s)for(f=[],t=4;t--;)f[t]=+k[s][t]+q*i*l[s][t];break;default:var z=[][D](k[s]);for(f=[],t=n.paper.customAttributes[s].length;t--;)f[t]=+z[t]+q*i*l[s][t]}o[s]=f}n.attr(o),function(b,c,d){setTimeout(function(){a("raphael.anim.frame."+b,c,d)})}(n.id,n,e.anim)}else{if(function(c,d,e){setTimeout(function(){a("raphael.anim.frame."+d.id,d,e),a("raphael.anim.finish."+d.id,d,e),b.is(c,"function")&&c.call(d)})}(e.callback,n,e.anim),n.attr(m),fb.splice(d--,1),e.repeat>1&&!e.next){for(g in m)m[y](g)&&(p[g]=e.totalOrigin[g]);e.el.attr(p),r(e.anim,e.el,e.anim.percents[0],null,e.totalOrigin,e.repeat-1)}e.next&&!e.stop&&r(e.anim,e.el,e.next,null,e.totalOrigin,e.repeat)}}}fb.length&&gb(hb)},ib=function(a){return a>255?255:0>a?0:a};Xa.animateWith=function(a,c,d,e,f,g){var h=this;if(h.removed)return g&&g.call(h),h;var i=d instanceof q?d:b.animation(d,e,f,g);r(i,h,i.percents[0],null,h.attr());for(var j=0,k=fb.length;k>j;j++)if(fb[j].anim==c&&fb[j].el==a){fb[k-1].start=fb[j].start;break}return h},Xa.onAnimation=function(b){return b?a.on("raphael.anim.frame."+this.id,b):a.unbind("raphael.anim.frame."+this.id),this},q.prototype.delay=function(a){var b=new q(this.anim,this.ms);return b.times=this.times,b.del=+a||0,b},q.prototype.repeat=function(a){var b=new q(this.anim,this.ms);return b.del=this.del,b.times=M.floor(N(a,0))||1,b},b.animation=function(a,c,d,e){if(a instanceof q)return a;(b.is(d,"function")||!d)&&(e=e||d||null,d=null),a=Object(a),c=+c||0;var f,g,h={};for(g in a)a[y](g)&&$(g)!=g&&$(g)+"%"!=g&&(f=!0,h[g]=a[g]);if(f)return d&&(h.easing=d),e&&(h.callback=e),new q({100:h},c);if(e){var i=0;for(var j in a){var k=_(j);a[y](j)&&k>i&&(i=k)}i+="%",!a[i].callback&&(a[i].callback=e)}return new q(a,c)},Xa.animate=function(a,c,d,e){var f=this;if(f.removed)return e&&e.call(f),f;var g=a instanceof q?a:b.animation(a,c,d,e);return r(g,f,g.percents[0],null,f.attr()),f},Xa.setTime=function(a,b){return a&&null!=b&&this.status(a,O(b,a.ms)/a.ms),this},Xa.status=function(a,b){var c,d,e=[],f=0;if(null!=b)return r(a,this,-1,O(b,1)),this;for(c=fb.length;c>f;f++)if(d=fb[f],d.el.id==this.id&&(!a||d.anim==a)){if(a)return d.status;e.push({anim:d.anim,status:d.status})}return a?0:e},Xa.pause=function(b){for(var c=0;cb;b++)!a[b]||a[b].constructor!=Xa.constructor&&a[b].constructor!=jb||(this[this.items.length]=this.items[this.items.length]=a[b],this.length++)},kb=jb.prototype;kb.push=function(){for(var a,b,c=0,d=arguments.length;d>c;c++)a=arguments[c],!a||a.constructor!=Xa.constructor&&a.constructor!=jb||(b=this.items.length,this[b]=this.items[b]=a,this.length++);return this},kb.pop=function(){return this.length&&delete this[this.length--],this.items.pop()},kb.forEach=function(a,b){for(var c=0,d=this.items.length;d>c;c++)if(a.call(b,this.items[c],c)===!1)return this;return this};for(var lb in Xa)Xa[y](lb)&&(kb[lb]=function(a){return function(){var b=arguments;return this.forEach(function(c){c[a][C](c,b)})}}(lb));return kb.attr=function(a,c){if(a&&b.is(a,U)&&b.is(a[0],"object"))for(var d=0,e=a.length;e>d;d++)this.items[d].attr(a[d]);else for(var f=0,g=this.items.length;g>f;f++)this.items[f].attr(a,c);return this},kb.clear=function(){for(;this.length;)this.pop()},kb.splice=function(a,b,c){a=0>a?N(this.length+a,0):a,b=N(0,O(this.length-a,b));var d,e=[],f=[],g=[];for(d=2;dd;d++)f.push(this[a+d]);for(;dd?g[d]:e[d-h];for(d=this.items.length=this.length-=b-h;this[d];)delete this[d++];return new jb(f)},kb.exclude=function(a){for(var b=0,c=this.length;c>b;b++)if(this[b]==a)return this.splice(b,1),!0},kb.animate=function(a,c,d,e){(b.is(d,"function")||!d)&&(e=d||null);var f,g,h=this.items.length,i=h,j=this;if(!h)return this;e&&(g=function(){!--h&&e.call(j)}),d=b.is(d,T)?d:g;var k=b.animation(a,c,d,g);for(f=this.items[--i].animate(k);i--;)this.items[i]&&!this.items[i].removed&&this.items[i].animateWith(f,k,k),this.items[i]&&!this.items[i].removed||h--;return this},kb.insertAfter=function(a){for(var b=this.items.length;b--;)this.items[b].insertAfter(a);return this},kb.getBBox=function(){for(var a=[],b=[],c=[],d=[],e=this.items.length;e--;)if(!this.items[e].removed){var f=this.items[e].getBBox();a.push(f.x),b.push(f.y),c.push(f.x+f.width),d.push(f.y+f.height)}return a=O[C](0,a),b=O[C](0,b),c=N[C](0,c),d=N[C](0,d),{x:a,y:b,x2:c,y2:d,width:c-a,height:d-b}},kb.clone=function(a){a=this.paper.set();for(var b=0,c=this.items.length;c>b;b++)a.push(this.items[b].clone());return a},kb.toString=function(){return"Raphaël‘s set"},kb.glow=function(a){var b=this.paper.set();return this.forEach(function(c,d){var e=c.glow(a);null!=e&&e.forEach(function(a,c){b.push(a)})}),b},kb.isPointInside=function(a,b){var c=!1;return this.forEach(function(d){return d.isPointInside(a,b)?(c=!0,!1):void 0}),c},b.registerFont=function(a){if(!a.face)return a;this.fonts=this.fonts||{};var b={w:a.w,face:{},glyphs:{}},c=a.face["font-family"];for(var d in a.face)a.face[y](d)&&(b.face[d]=a.face[d]);if(this.fonts[c]?this.fonts[c].push(b):this.fonts[c]=[b],!a.svg){b.face["units-per-em"]=_(a.face["units-per-em"],10);for(var e in a.glyphs)if(a.glyphs[y](e)){var f=a.glyphs[e];if(b.glyphs[e]={w:f.w,k:{},d:f.d&&"M"+f.d.replace(/[mlcxtrv]/g,function(a){return{l:"L",c:"C",x:"z",t:"m",r:"l",v:"c"}[a]||"M"})+"z"},f.k)for(var g in f.k)f[y](g)&&(b.glyphs[e].k[g]=f.k[g])}}return a},u.getFont=function(a,c,d,e){if(e=e||"normal",d=d||"normal",c=+c||{normal:400,bold:700,lighter:300,bolder:800}[c]||400,b.fonts){var f=b.fonts[a];if(!f){var g=new RegExp("(^|\\s)"+a.replace(/[^\w\d\s+!~.:_-]/g,F)+"(\\s|$)","i");for(var h in b.fonts)if(b.fonts[y](h)&&g.test(h)){f=b.fonts[h];break}}var i;if(f)for(var j=0,k=f.length;k>j&&(i=f[j],i.face["font-weight"]!=c||i.face["font-style"]!=d&&i.face["font-style"]||i.face["font-stretch"]!=e);j++);return i}},u.print=function(a,c,d,e,f,g,h,i){g=g||"middle",h=N(O(h||0,1),-1),i=N(O(i||1,3),1);var j,k=H(d)[I](F),l=0,m=0,n=F;if(b.is(e,"string")&&(e=this.getFont(e)),e){j=(f||16)/e.face["units-per-em"];for(var o=e.face.bbox[I](v),p=+o[0],q=o[3]-o[1],r=0,s=+o[1]+("baseline"==g?q+ +e.face.descent:q/2),t=0,u=k.length;u>t;t++){if("\n"==k[t])l=0,x=0,m=0,r+=q*i;else{var w=m&&e.glyphs[k[t-1]]||{},x=e.glyphs[k[t]];l+=m?(w.w||e.w)+(w.k&&w.k[k[t]]||0)+e.w*h:0,m=1}x&&x.d&&(n+=b.transformPath(x.d,["t",l*j,r*j,"s",j,j,p,s,"t",(a-p)/j,(c-s)/j]))}}return this.path(n).attr({fill:"#000",stroke:"none"})},u.add=function(a){if(b.is(a,"array"))for(var c,d=this.set(),e=0,f=a.length;f>e;e++)c=a[e]||{},w[y](c.type)&&d.push(this[c.type]().attr(c));return d},b.format=function(a,c){var d=b.is(c,U)?[0][D](c):arguments;return a&&b.is(a,T)&&d.length-1&&(a=a.replace(x,function(a,b){return null==d[++b]?F:d[b]})),a||F},b.fullfill=function(){var a=/\{([^\}]+)\}/g,b=/(?:(?:^|\.)(.+?)(?=\[|\.|$|\()|\[('|")(.+?)\2\])(\(\))?/g,c=function(a,c,d){var e=d;return c.replace(b,function(a,b,c,d,f){b=b||d,e&&(b in e&&(e=e[b]),"function"==typeof e&&f&&(e=e()))}),e=(null==e||e==d?a:e)+""};return function(b,d){return String(b).replace(a,function(a,b){return c(a,b,d)})}}(),b.ninja=function(){return A.was?z.win.Raphael=A.is:delete Raphael,b},b.st=kb,a.on("raphael.DOMload",function(){t=!0}),function(a,c,d){function e(){/in/.test(a.readyState)?setTimeout(e,9):b.eve("raphael.DOMload")}null==a.readyState&&a.addEventListener&&(a.addEventListener(c,d=function(){a.removeEventListener(c,d,!1),a.readyState="complete"},!1),a.readyState="loading"),e()}(document,"DOMContentLoaded"),b}),function(a,b){"function"==typeof define&&define.amd?define("raphael.svg",["raphael.core"],function(a){return b(a)}):b("object"==typeof exports?require("./raphael.core"):a.Raphael)}(this,function(a){if(!a||a.svg){var b="hasOwnProperty",c=String,d=parseFloat,e=parseInt,f=Math,g=f.max,h=f.abs,i=f.pow,j=/[, ]+/,k=a.eve,l="",m=" ",n="http://www.w3.org/1999/xlink",o={block:"M5,0 0,2.5 5,5z",classic:"M5,0 0,2.5 5,5 3.5,3 3.5,2z",diamond:"M2.5,0 5,2.5 2.5,5 0,2.5z",open:"M6,1 1,3.5 6,6",oval:"M2.5,0A2.5,2.5,0,0,1,2.5,5 2.5,2.5,0,0,1,2.5,0z"},p={};a.toString=function(){return"Your browser supports SVG.\nYou are running Raphaël "+this.version};var q=function(d,e){if(e){"string"==typeof d&&(d=q(d));for(var f in e)e[b](f)&&("xlink:"==f.substring(0,6)?d.setAttributeNS(n,f.substring(6),c(e[f])):d.setAttribute(f,c(e[f])))}else d=a._g.doc.createElementNS("http://www.w3.org/2000/svg",d),d.style&&(d.style.webkitTapHighlightColor="rgba(0,0,0,0)");return d},r=function(b,e){var j="linear",k=b.id+e,m=.5,n=.5,o=b.node,p=b.paper,r=o.style,s=a._g.doc.getElementById(k);if(!s){if(e=c(e).replace(a._radial_gradient,function(a,b,c){if(j="radial",b&&c){m=d(b),n=d(c);var e=2*(n>.5)-1;i(m-.5,2)+i(n-.5,2)>.25&&(n=f.sqrt(.25-i(m-.5,2))*e+.5)&&.5!=n&&(n=n.toFixed(5)-1e-5*e)}return l}),e=e.split(/\s*\-\s*/),"linear"==j){var t=e.shift();if(t=-d(t),isNaN(t))return null;var u=[0,0,f.cos(a.rad(t)),f.sin(a.rad(t))],v=1/(g(h(u[2]),h(u[3]))||1);u[2]*=v,u[3]*=v,u[2]<0&&(u[0]=-u[2],u[2]=0),u[3]<0&&(u[1]=-u[3],u[3]=0)}var w=a._parseDots(e);if(!w)return null;if(k=k.replace(/[\(\)\s,\xb0#]/g,"_"),b.gradient&&k!=b.gradient.id&&(p.defs.removeChild(b.gradient),delete b.gradient),!b.gradient){s=q(j+"Gradient",{id:k}),b.gradient=s,q(s,"radial"==j?{fx:m,fy:n}:{x1:u[0],y1:u[1],x2:u[2],y2:u[3],gradientTransform:b.matrix.invert()}),p.defs.appendChild(s);for(var x=0,y=w.length;y>x;x++)s.appendChild(q("stop",{offset:w[x].offset?w[x].offset:x?"100%":"0%","stop-color":w[x].color||"#fff","stop-opacity":isFinite(w[x].opacity)?w[x].opacity:1}))}}return q(o,{fill:"url('"+document.location.origin+document.location.pathname+"#"+k+"')",opacity:1,"fill-opacity":1}),r.fill=l,r.opacity=1,r.fillOpacity=1,1},s=function(a){var b=a.getBBox(1);q(a.pattern,{patternTransform:a.matrix.invert()+" translate("+b.x+","+b.y+")"})},t=function(d,e,f){if("path"==d.type){for(var g,h,i,j,k,m=c(e).toLowerCase().split("-"),n=d.paper,r=f?"end":"start",s=d.node,t=d.attrs,u=t["stroke-width"],v=m.length,w="classic",x=3,y=3,z=5;v--;)switch(m[v]){case"block":case"classic":case"oval":case"diamond":case"open":case"none":w=m[v];break;case"wide":y=5;break;case"narrow":y=2;break;case"long":x=5;break;case"short":x=2}if("open"==w?(x+=2,y+=2,z+=2,i=1,j=f?4:1,k={fill:"none",stroke:t.stroke}):(j=i=x/2,k={fill:t.stroke,stroke:"none"}),d._.arrows?f?(d._.arrows.endPath&&p[d._.arrows.endPath]--,d._.arrows.endMarker&&p[d._.arrows.endMarker]--):(d._.arrows.startPath&&p[d._.arrows.startPath]--,d._.arrows.startMarker&&p[d._.arrows.startMarker]--):d._.arrows={},"none"!=w){var A="raphael-marker-"+w,B="raphael-marker-"+r+w+x+y+"-obj"+d.id;a._g.doc.getElementById(A)?p[A]++:(n.defs.appendChild(q(q("path"),{"stroke-linecap":"round",d:o[w],id:A})),p[A]=1);var C,D=a._g.doc.getElementById(B);D?(p[B]++,C=D.getElementsByTagName("use")[0]):(D=q(q("marker"),{id:B,markerHeight:y,markerWidth:x,orient:"auto",refX:j,refY:y/2}),C=q(q("use"),{"xlink:href":"#"+A,transform:(f?"rotate(180 "+x/2+" "+y/2+") ":l)+"scale("+x/z+","+y/z+")","stroke-width":(1/((x/z+y/z)/2)).toFixed(4)}),D.appendChild(C),n.defs.appendChild(D),p[B]=1),q(C,k);var E=i*("diamond"!=w&&"oval"!=w);f?(g=d._.arrows.startdx*u||0,h=a.getTotalLength(t.path)-E*u):(g=E*u,h=a.getTotalLength(t.path)-(d._.arrows.enddx*u||0)),k={},k["marker-"+r]="url(#"+B+")",(h||g)&&(k.d=a.getSubpath(t.path,g,h)),q(s,k),d._.arrows[r+"Path"]=A,d._.arrows[r+"Marker"]=B,d._.arrows[r+"dx"]=E,d._.arrows[r+"Type"]=w,d._.arrows[r+"String"]=e}else f?(g=d._.arrows.startdx*u||0,h=a.getTotalLength(t.path)-g):(g=0,h=a.getTotalLength(t.path)-(d._.arrows.enddx*u||0)),d._.arrows[r+"Path"]&&q(s,{d:a.getSubpath(t.path,g,h)}),delete d._.arrows[r+"Path"],delete d._.arrows[r+"Marker"],delete d._.arrows[r+"dx"],delete d._.arrows[r+"Type"],delete d._.arrows[r+"String"];for(k in p)if(p[b](k)&&!p[k]){var F=a._g.doc.getElementById(k);F&&F.parentNode.removeChild(F)}}},u={"-":[3,1],".":[1,1],"-.":[3,1,1,1],"-..":[3,1,1,1,1,1],". ":[1,3],"- ":[4,3],"--":[8,3],"- .":[4,3,1,3],"--.":[8,3,1,3],"--..":[8,3,1,3,1,3]},v=function(a,b,d){if(b=u[c(b).toLowerCase()]){for(var e=a.attrs["stroke-width"]||"1",f={round:e,square:e,butt:0}[a.attrs["stroke-linecap"]||d["stroke-linecap"]]||0,g=[],h=b.length;h--;)g[h]=b[h]*e+(h%2?1:-1)*f;q(a.node,{"stroke-dasharray":g.join(",")})}else q(a.node,{"stroke-dasharray":"none"})},w=function(d,f){var i=d.node,k=d.attrs,m=i.style.visibility;i.style.visibility="hidden";for(var o in f)if(f[b](o)){if(!a._availableAttrs[b](o))continue;var p=f[o];switch(k[o]=p,o){case"blur":d.blur(p);break;case"title":var u=i.getElementsByTagName("title");if(u.length&&(u=u[0]))u.firstChild.nodeValue=p;else{u=q("title");var w=a._g.doc.createTextNode(p);u.appendChild(w),i.appendChild(u)}break;case"href":case"target":var x=i.parentNode;if("a"!=x.tagName.toLowerCase()){var z=q("a");x.insertBefore(z,i),z.appendChild(i),x=z}"target"==o?x.setAttributeNS(n,"show","blank"==p?"new":p):x.setAttributeNS(n,o,p);break;case"cursor":i.style.cursor=p;break;case"transform":d.transform(p);break;case"arrow-start":t(d,p);break;case"arrow-end":t(d,p,1);break;case"clip-rect":var A=c(p).split(j);if(4==A.length){d.clip&&d.clip.parentNode.parentNode.removeChild(d.clip.parentNode);var B=q("clipPath"),C=q("rect");B.id=a.createUUID(),q(C,{x:A[0],y:A[1],width:A[2],height:A[3]}),B.appendChild(C),d.paper.defs.appendChild(B),q(i,{"clip-path":"url(#"+B.id+")"}),d.clip=C}if(!p){var D=i.getAttribute("clip-path");if(D){var E=a._g.doc.getElementById(D.replace(/(^url\(#|\)$)/g,l));E&&E.parentNode.removeChild(E),q(i,{"clip-path":l}),delete d.clip}}break;case"path":"path"==d.type&&(q(i,{d:p?k.path=a._pathToAbsolute(p):"M0,0"}),d._.dirty=1,d._.arrows&&("startString"in d._.arrows&&t(d,d._.arrows.startString),"endString"in d._.arrows&&t(d,d._.arrows.endString,1)));break;case"width":if(i.setAttribute(o,p),d._.dirty=1,!k.fx)break;o="x",p=k.x;case"x":k.fx&&(p=-k.x-(k.width||0));case"rx":if("rx"==o&&"rect"==d.type)break;case"cx":i.setAttribute(o,p),d.pattern&&s(d),d._.dirty=1;break;case"height":if(i.setAttribute(o,p),d._.dirty=1,!k.fy)break;o="y",p=k.y;case"y":k.fy&&(p=-k.y-(k.height||0));case"ry":if("ry"==o&&"rect"==d.type)break;case"cy":i.setAttribute(o,p),d.pattern&&s(d),d._.dirty=1;break;case"r":"rect"==d.type?q(i,{rx:p,ry:p}):i.setAttribute(o,p),d._.dirty=1;break;case"src":"image"==d.type&&i.setAttributeNS(n,"href",p);break;case"stroke-width":(1!=d._.sx||1!=d._.sy)&&(p/=g(h(d._.sx),h(d._.sy))||1),i.setAttribute(o,p),k["stroke-dasharray"]&&v(d,k["stroke-dasharray"],f),d._.arrows&&("startString"in d._.arrows&&t(d,d._.arrows.startString),"endString"in d._.arrows&&t(d,d._.arrows.endString,1));break;case"stroke-dasharray":v(d,p,f);break;case"fill":var F=c(p).match(a._ISURL);if(F){B=q("pattern");var G=q("image");B.id=a.createUUID(),q(B,{x:0,y:0,patternUnits:"userSpaceOnUse",height:1,width:1}),q(G,{x:0,y:0,"xlink:href":F[1]}),B.appendChild(G),function(b){a._preload(F[1],function(){var a=this.offsetWidth,c=this.offsetHeight;q(b,{width:a,height:c}),q(G,{width:a,height:c})})}(B),d.paper.defs.appendChild(B),q(i,{fill:"url(#"+B.id+")"}),d.pattern=B,d.pattern&&s(d);break}var H=a.getRGB(p);if(H.error){if(("circle"==d.type||"ellipse"==d.type||"r"!=c(p).charAt())&&r(d,p)){if("opacity"in k||"fill-opacity"in k){var I=a._g.doc.getElementById(i.getAttribute("fill").replace(/^url\(#|\)$/g,l));if(I){var J=I.getElementsByTagName("stop");q(J[J.length-1],{"stop-opacity":("opacity"in k?k.opacity:1)*("fill-opacity"in k?k["fill-opacity"]:1)})}}k.gradient=p,k.fill="none";break}}else delete f.gradient,delete k.gradient,!a.is(k.opacity,"undefined")&&a.is(f.opacity,"undefined")&&q(i,{opacity:k.opacity}),!a.is(k["fill-opacity"],"undefined")&&a.is(f["fill-opacity"],"undefined")&&q(i,{"fill-opacity":k["fill-opacity"]});H[b]("opacity")&&q(i,{"fill-opacity":H.opacity>1?H.opacity/100:H.opacity});case"stroke":H=a.getRGB(p),i.setAttribute(o,H.hex),"stroke"==o&&H[b]("opacity")&&q(i,{"stroke-opacity":H.opacity>1?H.opacity/100:H.opacity}),"stroke"==o&&d._.arrows&&("startString"in d._.arrows&&t(d,d._.arrows.startString),"endString"in d._.arrows&&t(d,d._.arrows.endString,1));break;case"gradient":("circle"==d.type||"ellipse"==d.type||"r"!=c(p).charAt())&&r(d,p); - -break;case"opacity":k.gradient&&!k[b]("stroke-opacity")&&q(i,{"stroke-opacity":p>1?p/100:p});case"fill-opacity":if(k.gradient){I=a._g.doc.getElementById(i.getAttribute("fill").replace(/^url\(#|\)$/g,l)),I&&(J=I.getElementsByTagName("stop"),q(J[J.length-1],{"stop-opacity":p}));break}default:"font-size"==o&&(p=e(p,10)+"px");var K=o.replace(/(\-.)/g,function(a){return a.substring(1).toUpperCase()});i.style[K]=p,d._.dirty=1,i.setAttribute(o,p)}}y(d,f),i.style.visibility=m},x=1.2,y=function(d,f){if("text"==d.type&&(f[b]("text")||f[b]("font")||f[b]("font-size")||f[b]("x")||f[b]("y"))){var g=d.attrs,h=d.node,i=h.firstChild?e(a._g.doc.defaultView.getComputedStyle(h.firstChild,l).getPropertyValue("font-size"),10):10;if(f[b]("text")){for(g.text=f.text;h.firstChild;)h.removeChild(h.firstChild);for(var j,k=c(f.text).split("\n"),m=[],n=0,o=k.length;o>n;n++)j=q("tspan"),n&&q(j,{dy:i*x,x:g.x}),j.appendChild(a._g.doc.createTextNode(k[n])),h.appendChild(j),m[n]=j}else for(m=h.getElementsByTagName("tspan"),n=0,o=m.length;o>n;n++)n?q(m[n],{dy:i*x,x:g.x}):q(m[0],{dy:0});q(h,{x:g.x,y:g.y}),d._.dirty=1;var p=d._getBBox(),r=g.y-(p.y+p.height/2);r&&a.is(r,"finite")&&q(m[0],{dy:r})}},z=function(a){return a.parentNode&&"a"===a.parentNode.tagName.toLowerCase()?a.parentNode:a},A=function(b,c){this[0]=this.node=b,b.raphael=!0,this.id=a._oid++,b.raphaelid=this.id,this.matrix=a.matrix(),this.realPath=null,this.paper=c,this.attrs=this.attrs||{},this._={transform:[],sx:1,sy:1,deg:0,dx:0,dy:0,dirty:1},!c.bottom&&(c.bottom=this),this.prev=c.top,c.top&&(c.top.next=this),c.top=this,this.next=null},B=a.el;A.prototype=B,B.constructor=A,a._engine.path=function(a,b){var c=q("path");b.canvas&&b.canvas.appendChild(c);var d=new A(c,b);return d.type="path",w(d,{fill:"none",stroke:"#000",path:a}),d},B.rotate=function(a,b,e){if(this.removed)return this;if(a=c(a).split(j),a.length-1&&(b=d(a[1]),e=d(a[2])),a=d(a[0]),null==e&&(b=e),null==b||null==e){var f=this.getBBox(1);b=f.x+f.width/2,e=f.y+f.height/2}return this.transform(this._.transform.concat([["r",a,b,e]])),this},B.scale=function(a,b,e,f){if(this.removed)return this;if(a=c(a).split(j),a.length-1&&(b=d(a[1]),e=d(a[2]),f=d(a[3])),a=d(a[0]),null==b&&(b=a),null==f&&(e=f),null==e||null==f)var g=this.getBBox(1);return e=null==e?g.x+g.width/2:e,f=null==f?g.y+g.height/2:f,this.transform(this._.transform.concat([["s",a,b,e,f]])),this},B.translate=function(a,b){return this.removed?this:(a=c(a).split(j),a.length-1&&(b=d(a[1])),a=d(a[0])||0,b=+b||0,this.transform(this._.transform.concat([["t",a,b]])),this)},B.transform=function(c){var d=this._;if(null==c)return d.transform;if(a._extractTransform(this,c),this.clip&&q(this.clip,{transform:this.matrix.invert()}),this.pattern&&s(this),this.node&&q(this.node,{transform:this.matrix}),1!=d.sx||1!=d.sy){var e=this.attrs[b]("stroke-width")?this.attrs["stroke-width"]:1;this.attr({"stroke-width":e})}return this},B.hide=function(){return this.removed||(this.node.style.display="none"),this},B.show=function(){return this.removed||(this.node.style.display=""),this},B.remove=function(){var b=z(this.node);if(!this.removed&&b.parentNode){var c=this.paper;c.__set__&&c.__set__.exclude(this),k.unbind("raphael.*.*."+this.id),this.gradient&&c.defs.removeChild(this.gradient),a._tear(this,c),b.parentNode.removeChild(b),this.removeData();for(var d in this)this[d]="function"==typeof this[d]?a._removedFactory(d):null;this.removed=!0}},B._getBBox=function(){if("none"==this.node.style.display){this.show();var a=!0}var b,c=!1;this.paper.canvas.parentElement?b=this.paper.canvas.parentElement.style:this.paper.canvas.parentNode&&(b=this.paper.canvas.parentNode.style),b&&"none"==b.display&&(c=!0,b.display="");var d={};try{d=this.node.getBBox()}catch(e){d={x:this.node.clientLeft,y:this.node.clientTop,width:this.node.clientWidth,height:this.node.clientHeight}}finally{d=d||{},c&&(b.display="none")}return a&&this.hide(),d},B.attr=function(c,d){if(this.removed)return this;if(null==c){var e={};for(var f in this.attrs)this.attrs[b](f)&&(e[f]=this.attrs[f]);return e.gradient&&"none"==e.fill&&(e.fill=e.gradient)&&delete e.gradient,e.transform=this._.transform,e}if(null==d&&a.is(c,"string")){if("fill"==c&&"none"==this.attrs.fill&&this.attrs.gradient)return this.attrs.gradient;if("transform"==c)return this._.transform;for(var g=c.split(j),h={},i=0,l=g.length;l>i;i++)c=g[i],c in this.attrs?h[c]=this.attrs[c]:a.is(this.paper.customAttributes[c],"function")?h[c]=this.paper.customAttributes[c].def:h[c]=a._availableAttrs[c];return l-1?h:h[g[0]]}if(null==d&&a.is(c,"array")){for(h={},i=0,l=c.length;l>i;i++)h[c[i]]=this.attr(c[i]);return h}if(null!=d){var m={};m[c]=d}else null!=c&&a.is(c,"object")&&(m=c);for(var n in m)k("raphael.attr."+n+"."+this.id,this,m[n]);for(n in this.paper.customAttributes)if(this.paper.customAttributes[b](n)&&m[b](n)&&a.is(this.paper.customAttributes[n],"function")){var o=this.paper.customAttributes[n].apply(this,[].concat(m[n]));this.attrs[n]=m[n];for(var p in o)o[b](p)&&(m[p]=o[p])}return w(this,m),this},B.toFront=function(){if(this.removed)return this;var b=z(this.node);b.parentNode.appendChild(b);var c=this.paper;return c.top!=this&&a._tofront(this,c),this},B.toBack=function(){if(this.removed)return this;var b=z(this.node),c=b.parentNode;c.insertBefore(b,c.firstChild),a._toback(this,this.paper);this.paper;return this},B.insertAfter=function(b){if(this.removed||!b)return this;var c=z(this.node),d=z(b.node||b[b.length-1].node);return d.nextSibling?d.parentNode.insertBefore(c,d.nextSibling):d.parentNode.appendChild(c),a._insertafter(this,b,this.paper),this},B.insertBefore=function(b){if(this.removed||!b)return this;var c=z(this.node),d=z(b.node||b[0].node);return d.parentNode.insertBefore(c,d),a._insertbefore(this,b,this.paper),this},B.blur=function(b){var c=this;if(0!==+b){var d=q("filter"),e=q("feGaussianBlur");c.attrs.blur=b,d.id=a.createUUID(),q(e,{stdDeviation:+b||1.5}),d.appendChild(e),c.paper.defs.appendChild(d),c._blur=d,q(c.node,{filter:"url(#"+d.id+")"})}else c._blur&&(c._blur.parentNode.removeChild(c._blur),delete c._blur,delete c.attrs.blur),c.node.removeAttribute("filter");return c},a._engine.circle=function(a,b,c,d){var e=q("circle");a.canvas&&a.canvas.appendChild(e);var f=new A(e,a);return f.attrs={cx:b,cy:c,r:d,fill:"none",stroke:"#000"},f.type="circle",q(e,f.attrs),f},a._engine.rect=function(a,b,c,d,e,f){var g=q("rect");a.canvas&&a.canvas.appendChild(g);var h=new A(g,a);return h.attrs={x:b,y:c,width:d,height:e,rx:f||0,ry:f||0,fill:"none",stroke:"#000"},h.type="rect",q(g,h.attrs),h},a._engine.ellipse=function(a,b,c,d,e){var f=q("ellipse");a.canvas&&a.canvas.appendChild(f);var g=new A(f,a);return g.attrs={cx:b,cy:c,rx:d,ry:e,fill:"none",stroke:"#000"},g.type="ellipse",q(f,g.attrs),g},a._engine.image=function(a,b,c,d,e,f){var g=q("image");q(g,{x:c,y:d,width:e,height:f,preserveAspectRatio:"none"}),g.setAttributeNS(n,"href",b),a.canvas&&a.canvas.appendChild(g);var h=new A(g,a);return h.attrs={x:c,y:d,width:e,height:f,src:b},h.type="image",h},a._engine.text=function(b,c,d,e){var f=q("text");b.canvas&&b.canvas.appendChild(f);var g=new A(f,b);return g.attrs={x:c,y:d,"text-anchor":"middle",text:e,"font-family":a._availableAttrs["font-family"],"font-size":a._availableAttrs["font-size"],stroke:"none",fill:"#000"},g.type="text",w(g,g.attrs),g},a._engine.setSize=function(a,b){return this.width=a||this.width,this.height=b||this.height,this.canvas.setAttribute("width",this.width),this.canvas.setAttribute("height",this.height),this._viewBox&&this.setViewBox.apply(this,this._viewBox),this},a._engine.create=function(){var b=a._getContainer.apply(0,arguments),c=b&&b.container,d=b.x,e=b.y,f=b.width,g=b.height;if(!c)throw new Error("SVG container not found.");var h,i=q("svg"),j="overflow:hidden;";return d=d||0,e=e||0,f=f||512,g=g||342,q(i,{height:g,version:1.1,width:f,xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink"}),1==c?(i.style.cssText=j+"position:absolute;left:"+d+"px;top:"+e+"px",a._g.doc.body.appendChild(i),h=1):(i.style.cssText=j+"position:relative",c.firstChild?c.insertBefore(i,c.firstChild):c.appendChild(i)),c=new a._Paper,c.width=f,c.height=g,c.canvas=i,c.clear(),c._left=c._top=0,h&&(c.renderfix=function(){}),c.renderfix(),c},a._engine.setViewBox=function(a,b,c,d,e){k("raphael.setViewBox",this,this._viewBox,[a,b,c,d,e]);var f,h,i=this.getSize(),j=g(c/i.width,d/i.height),l=this.top,n=e?"xMidYMid meet":"xMinYMin";for(null==a?(this._vbSize&&(j=1),delete this._vbSize,f="0 0 "+this.width+m+this.height):(this._vbSize=j,f=a+m+b+m+c+m+d),q(this.canvas,{viewBox:f,preserveAspectRatio:n});j&&l;)h="stroke-width"in l.attrs?l.attrs["stroke-width"]:1,l.attr({"stroke-width":h}),l._.dirty=1,l._.dirtyT=1,l=l.prev;return this._viewBox=[a,b,c,d,!!e],this},a.prototype.renderfix=function(){var a,b=this.canvas,c=b.style;try{a=b.getScreenCTM()||b.createSVGMatrix()}catch(d){a=b.createSVGMatrix()}var e=-a.e%1,f=-a.f%1;(e||f)&&(e&&(this._left=(this._left+e)%1,c.left=this._left+"px"),f&&(this._top=(this._top+f)%1,c.top=this._top+"px"))},a.prototype.clear=function(){a.eve("raphael.clear",this);for(var b=this.canvas;b.firstChild;)b.removeChild(b.firstChild);this.bottom=this.top=null,(this.desc=q("desc")).appendChild(a._g.doc.createTextNode("Created with Raphaël "+a.version)),b.appendChild(this.desc),b.appendChild(this.defs=q("defs"))},a.prototype.remove=function(){k("raphael.remove",this),this.canvas.parentNode&&this.canvas.parentNode.removeChild(this.canvas);for(var b in this)this[b]="function"==typeof this[b]?a._removedFactory(b):null};var C=a.st;for(var D in B)B[b](D)&&!C[b](D)&&(C[D]=function(a){return function(){var b=arguments;return this.forEach(function(c){c[a].apply(c,b)})}}(D))}}),function(a,b){"function"==typeof define&&define.amd?define("raphael.vml",["raphael.core"],function(a){return b(a)}):b("object"==typeof exports?require("./raphael.core"):a.Raphael)}(this,function(a){if(!a||a.vml){var b="hasOwnProperty",c=String,d=parseFloat,e=Math,f=e.round,g=e.max,h=e.min,i=e.abs,j="fill",k=/[, ]+/,l=a.eve,m=" progid:DXImageTransform.Microsoft",n=" ",o="",p={M:"m",L:"l",C:"c",Z:"x",m:"t",l:"r",c:"v",z:"x"},q=/([clmz]),?([^clmz]*)/gi,r=/ progid:\S+Blur\([^\)]+\)/g,s=/-?[^,\s-]+/g,t="position:absolute;left:0;top:0;width:1px;height:1px;behavior:url(#default#VML)",u=21600,v={path:1,rect:1,image:1},w={circle:1,ellipse:1},x=function(b){var d=/[ahqstv]/gi,e=a._pathToAbsolute;if(c(b).match(d)&&(e=a._path2curve),d=/[clmz]/g,e==a._pathToAbsolute&&!c(b).match(d)){var g=c(b).replace(q,function(a,b,c){var d=[],e="m"==b.toLowerCase(),g=p[b];return c.replace(s,function(a){e&&2==d.length&&(g+=d+p["m"==b?"l":"L"],d=[]),d.push(f(a*u))}),g+d});return g}var h,i,j=e(b);g=[];for(var k=0,l=j.length;l>k;k++){h=j[k],i=j[k][0].toLowerCase(),"z"==i&&(i="x");for(var m=1,r=h.length;r>m;m++)i+=f(h[m]*u)+(m!=r-1?",":o);g.push(i)}return g.join(n)},y=function(b,c,d){var e=a.matrix();return e.rotate(-b,.5,.5),{dx:e.x(c,d),dy:e.y(c,d)}},z=function(a,b,c,d,e,f){var g=a._,h=a.matrix,k=g.fillpos,l=a.node,m=l.style,o=1,p="",q=u/b,r=u/c;if(m.visibility="hidden",b&&c){if(l.coordsize=i(q)+n+i(r),m.rotation=f*(0>b*c?-1:1),f){var s=y(f,d,e);d=s.dx,e=s.dy}if(0>b&&(p+="x"),0>c&&(p+=" y")&&(o=-1),m.flip=p,l.coordorigin=d*-q+n+e*-r,k||g.fillsize){var t=l.getElementsByTagName(j);t=t&&t[0],l.removeChild(t),k&&(s=y(f,h.x(k[0],k[1]),h.y(k[0],k[1])),t.position=s.dx*o+n+s.dy*o),g.fillsize&&(t.size=g.fillsize[0]*i(b)+n+g.fillsize[1]*i(c)),l.appendChild(t)}m.visibility="visible"}};a.toString=function(){return"Your browser doesn’t support SVG. Falling down to VML.\nYou are running Raphaël "+this.version};var A=function(a,b,d){for(var e=c(b).toLowerCase().split("-"),f=d?"end":"start",g=e.length,h="classic",i="medium",j="medium";g--;)switch(e[g]){case"block":case"classic":case"oval":case"diamond":case"open":case"none":h=e[g];break;case"wide":case"narrow":j=e[g];break;case"long":case"short":i=e[g]}var k=a.node.getElementsByTagName("stroke")[0];k[f+"arrow"]=h,k[f+"arrowlength"]=i,k[f+"arrowwidth"]=j},B=function(e,i){e.attrs=e.attrs||{};var l=e.node,m=e.attrs,p=l.style,q=v[e.type]&&(i.x!=m.x||i.y!=m.y||i.width!=m.width||i.height!=m.height||i.cx!=m.cx||i.cy!=m.cy||i.rx!=m.rx||i.ry!=m.ry||i.r!=m.r),r=w[e.type]&&(m.cx!=i.cx||m.cy!=i.cy||m.r!=i.r||m.rx!=i.rx||m.ry!=i.ry),s=e;for(var t in i)i[b](t)&&(m[t]=i[t]);if(q&&(m.path=a._getPath[e.type](e),e._.dirty=1),i.href&&(l.href=i.href),i.title&&(l.title=i.title),i.target&&(l.target=i.target),i.cursor&&(p.cursor=i.cursor),"blur"in i&&e.blur(i.blur),(i.path&&"path"==e.type||q)&&(l.path=x(~c(m.path).toLowerCase().indexOf("r")?a._pathToAbsolute(m.path):m.path),e._.dirty=1,"image"==e.type&&(e._.fillpos=[m.x,m.y],e._.fillsize=[m.width,m.height],z(e,1,1,0,0,0))),"transform"in i&&e.transform(i.transform),r){var y=+m.cx,B=+m.cy,D=+m.rx||+m.r||0,E=+m.ry||+m.r||0;l.path=a.format("ar{0},{1},{2},{3},{4},{1},{4},{1}x",f((y-D)*u),f((B-E)*u),f((y+D)*u),f((B+E)*u),f(y*u)),e._.dirty=1}if("clip-rect"in i){var G=c(i["clip-rect"]).split(k);if(4==G.length){G[2]=+G[2]+ +G[0],G[3]=+G[3]+ +G[1];var H=l.clipRect||a._g.doc.createElement("div"),I=H.style;I.clip=a.format("rect({1}px {2}px {3}px {0}px)",G),l.clipRect||(I.position="absolute",I.top=0,I.left=0,I.width=e.paper.width+"px",I.height=e.paper.height+"px",l.parentNode.insertBefore(H,l),H.appendChild(l),l.clipRect=H)}i["clip-rect"]||l.clipRect&&(l.clipRect.style.clip="auto")}if(e.textpath){var J=e.textpath.style;i.font&&(J.font=i.font),i["font-family"]&&(J.fontFamily='"'+i["font-family"].split(",")[0].replace(/^['"]+|['"]+$/g,o)+'"'),i["font-size"]&&(J.fontSize=i["font-size"]),i["font-weight"]&&(J.fontWeight=i["font-weight"]),i["font-style"]&&(J.fontStyle=i["font-style"])}if("arrow-start"in i&&A(s,i["arrow-start"]),"arrow-end"in i&&A(s,i["arrow-end"],1),null!=i.opacity||null!=i["stroke-width"]||null!=i.fill||null!=i.src||null!=i.stroke||null!=i["stroke-width"]||null!=i["stroke-opacity"]||null!=i["fill-opacity"]||null!=i["stroke-dasharray"]||null!=i["stroke-miterlimit"]||null!=i["stroke-linejoin"]||null!=i["stroke-linecap"]){var K=l.getElementsByTagName(j),L=!1;if(K=K&&K[0],!K&&(L=K=F(j)),"image"==e.type&&i.src&&(K.src=i.src),i.fill&&(K.on=!0),(null==K.on||"none"==i.fill||null===i.fill)&&(K.on=!1),K.on&&i.fill){var M=c(i.fill).match(a._ISURL);if(M){K.parentNode==l&&l.removeChild(K),K.rotate=!0,K.src=M[1],K.type="tile";var N=e.getBBox(1);K.position=N.x+n+N.y,e._.fillpos=[N.x,N.y],a._preload(M[1],function(){e._.fillsize=[this.offsetWidth,this.offsetHeight]})}else K.color=a.getRGB(i.fill).hex,K.src=o,K.type="solid",a.getRGB(i.fill).error&&(s.type in{circle:1,ellipse:1}||"r"!=c(i.fill).charAt())&&C(s,i.fill,K)&&(m.fill="none",m.gradient=i.fill,K.rotate=!1)}if("fill-opacity"in i||"opacity"in i){var O=((+m["fill-opacity"]+1||2)-1)*((+m.opacity+1||2)-1)*((+a.getRGB(i.fill).o+1||2)-1);O=h(g(O,0),1),K.opacity=O,K.src&&(K.color="none")}l.appendChild(K);var P=l.getElementsByTagName("stroke")&&l.getElementsByTagName("stroke")[0],Q=!1;!P&&(Q=P=F("stroke")),(i.stroke&&"none"!=i.stroke||i["stroke-width"]||null!=i["stroke-opacity"]||i["stroke-dasharray"]||i["stroke-miterlimit"]||i["stroke-linejoin"]||i["stroke-linecap"])&&(P.on=!0),("none"==i.stroke||null===i.stroke||null==P.on||0==i.stroke||0==i["stroke-width"])&&(P.on=!1);var R=a.getRGB(i.stroke);P.on&&i.stroke&&(P.color=R.hex),O=((+m["stroke-opacity"]+1||2)-1)*((+m.opacity+1||2)-1)*((+R.o+1||2)-1);var S=.75*(d(i["stroke-width"])||1);if(O=h(g(O,0),1),null==i["stroke-width"]&&(S=m["stroke-width"]),i["stroke-width"]&&(P.weight=S),S&&1>S&&(O*=S)&&(P.weight=1),P.opacity=O,i["stroke-linejoin"]&&(P.joinstyle=i["stroke-linejoin"]||"miter"),P.miterlimit=i["stroke-miterlimit"]||8,i["stroke-linecap"]&&(P.endcap="butt"==i["stroke-linecap"]?"flat":"square"==i["stroke-linecap"]?"square":"round"),"stroke-dasharray"in i){var T={"-":"shortdash",".":"shortdot","-.":"shortdashdot","-..":"shortdashdotdot",". ":"dot","- ":"dash","--":"longdash","- .":"dashdot","--.":"longdashdot","--..":"longdashdotdot"};P.dashstyle=T[b](i["stroke-dasharray"])?T[i["stroke-dasharray"]]:o}Q&&l.appendChild(P)}if("text"==s.type){s.paper.canvas.style.display=o;var U=s.paper.span,V=100,W=m.font&&m.font.match(/\d+(?:\.\d*)?(?=px)/);p=U.style,m.font&&(p.font=m.font),m["font-family"]&&(p.fontFamily=m["font-family"]),m["font-weight"]&&(p.fontWeight=m["font-weight"]),m["font-style"]&&(p.fontStyle=m["font-style"]),W=d(m["font-size"]||W&&W[0])||10,p.fontSize=W*V+"px",s.textpath.string&&(U.innerHTML=c(s.textpath.string).replace(/"));var X=U.getBoundingClientRect();s.W=m.w=(X.right-X.left)/V,s.H=m.h=(X.bottom-X.top)/V,s.X=m.x,s.Y=m.y+s.H/2,("x"in i||"y"in i)&&(s.path.v=a.format("m{0},{1}l{2},{1}",f(m.x*u),f(m.y*u),f(m.x*u)+1));for(var Y=["x","y","text","font","font-family","font-weight","font-style","font-size"],Z=0,$=Y.length;$>Z;Z++)if(Y[Z]in i){s._.dirty=1;break}switch(m["text-anchor"]){case"start":s.textpath.style["v-text-align"]="left",s.bbx=s.W/2;break;case"end":s.textpath.style["v-text-align"]="right",s.bbx=-s.W/2;break;default:s.textpath.style["v-text-align"]="center",s.bbx=0}s.textpath.style["v-text-kern"]=!0}},C=function(b,f,g){b.attrs=b.attrs||{};var h=(b.attrs,Math.pow),i="linear",j=".5 .5";if(b.attrs.gradient=f,f=c(f).replace(a._radial_gradient,function(a,b,c){return i="radial",b&&c&&(b=d(b),c=d(c),h(b-.5,2)+h(c-.5,2)>.25&&(c=e.sqrt(.25-h(b-.5,2))*(2*(c>.5)-1)+.5),j=b+n+c),o}),f=f.split(/\s*\-\s*/),"linear"==i){var k=f.shift();if(k=-d(k),isNaN(k))return null}var l=a._parseDots(f);if(!l)return null;if(b=b.shape||b.node,l.length){b.removeChild(g),g.on=!0,g.method="none",g.color=l[0].color,g.color2=l[l.length-1].color;for(var m=[],p=0,q=l.length;q>p;p++)l[p].offset&&m.push(l[p].offset+n+l[p].color);g.colors=m.length?m.join():"0% "+g.color,"radial"==i?(g.type="gradientTitle",g.focus="100%",g.focussize="0 0",g.focusposition=j,g.angle=0):(g.type="gradient",g.angle=(270-k)%360),b.appendChild(g)}return 1},D=function(b,c){this[0]=this.node=b,b.raphael=!0,this.id=a._oid++,b.raphaelid=this.id,this.X=0,this.Y=0,this.attrs={},this.paper=c,this.matrix=a.matrix(),this._={transform:[],sx:1,sy:1,dx:0,dy:0,deg:0,dirty:1,dirtyT:1},!c.bottom&&(c.bottom=this),this.prev=c.top,c.top&&(c.top.next=this),c.top=this,this.next=null},E=a.el;D.prototype=E,E.constructor=D,E.transform=function(b){if(null==b)return this._.transform;var d,e=this.paper._viewBoxShift,f=e?"s"+[e.scale,e.scale]+"-1-1t"+[e.dx,e.dy]:o;e&&(d=b=c(b).replace(/\.{3}|\u2026/g,this._.transform||o)),a._extractTransform(this,f+b);var g,h=this.matrix.clone(),i=this.skew,j=this.node,k=~c(this.attrs.fill).indexOf("-"),l=!c(this.attrs.fill).indexOf("url(");if(h.translate(1,1),l||k||"image"==this.type)if(i.matrix="1 0 0 1",i.offset="0 0",g=h.split(),k&&g.noRotation||!g.isSimple){j.style.filter=h.toFilter();var m=this.getBBox(),p=this.getBBox(1),q=m.x-p.x,r=m.y-p.y;j.coordorigin=q*-u+n+r*-u,z(this,1,1,q,r,0)}else j.style.filter=o,z(this,g.scalex,g.scaley,g.dx,g.dy,g.rotate);else j.style.filter=o,i.matrix=c(h),i.offset=h.offset();return null!==d&&(this._.transform=d,a._extractTransform(this,d)),this},E.rotate=function(a,b,e){if(this.removed)return this;if(null!=a){if(a=c(a).split(k),a.length-1&&(b=d(a[1]),e=d(a[2])),a=d(a[0]),null==e&&(b=e),null==b||null==e){var f=this.getBBox(1);b=f.x+f.width/2,e=f.y+f.height/2}return this._.dirtyT=1,this.transform(this._.transform.concat([["r",a,b,e]])),this}},E.translate=function(a,b){return this.removed?this:(a=c(a).split(k),a.length-1&&(b=d(a[1])),a=d(a[0])||0,b=+b||0,this._.bbox&&(this._.bbox.x+=a,this._.bbox.y+=b),this.transform(this._.transform.concat([["t",a,b]])),this)},E.scale=function(a,b,e,f){if(this.removed)return this;if(a=c(a).split(k),a.length-1&&(b=d(a[1]),e=d(a[2]),f=d(a[3]),isNaN(e)&&(e=null),isNaN(f)&&(f=null)),a=d(a[0]),null==b&&(b=a),null==f&&(e=f),null==e||null==f)var g=this.getBBox(1);return e=null==e?g.x+g.width/2:e,f=null==f?g.y+g.height/2:f,this.transform(this._.transform.concat([["s",a,b,e,f]])),this._.dirtyT=1,this},E.hide=function(){return!this.removed&&(this.node.style.display="none"),this},E.show=function(){return!this.removed&&(this.node.style.display=o),this},E.auxGetBBox=a.el.getBBox,E.getBBox=function(){var a=this.auxGetBBox();if(this.paper&&this.paper._viewBoxShift){var b={},c=1/this.paper._viewBoxShift.scale;return b.x=a.x-this.paper._viewBoxShift.dx,b.x*=c,b.y=a.y-this.paper._viewBoxShift.dy,b.y*=c,b.width=a.width*c,b.height=a.height*c,b.x2=b.x+b.width,b.y2=b.y+b.height,b}return a},E._getBBox=function(){return this.removed?{}:{x:this.X+(this.bbx||0)-this.W/2,y:this.Y-this.H,width:this.W,height:this.H}},E.remove=function(){if(!this.removed&&this.node.parentNode){this.paper.__set__&&this.paper.__set__.exclude(this),a.eve.unbind("raphael.*.*."+this.id),a._tear(this,this.paper),this.node.parentNode.removeChild(this.node),this.shape&&this.shape.parentNode.removeChild(this.shape);for(var b in this)this[b]="function"==typeof this[b]?a._removedFactory(b):null;this.removed=!0}},E.attr=function(c,d){if(this.removed)return this;if(null==c){var e={};for(var f in this.attrs)this.attrs[b](f)&&(e[f]=this.attrs[f]);return e.gradient&&"none"==e.fill&&(e.fill=e.gradient)&&delete e.gradient,e.transform=this._.transform,e}if(null==d&&a.is(c,"string")){if(c==j&&"none"==this.attrs.fill&&this.attrs.gradient)return this.attrs.gradient;for(var g=c.split(k),h={},i=0,m=g.length;m>i;i++)c=g[i],c in this.attrs?h[c]=this.attrs[c]:a.is(this.paper.customAttributes[c],"function")?h[c]=this.paper.customAttributes[c].def:h[c]=a._availableAttrs[c];return m-1?h:h[g[0]]}if(this.attrs&&null==d&&a.is(c,"array")){for(h={},i=0,m=c.length;m>i;i++)h[c[i]]=this.attr(c[i]);return h}var n;null!=d&&(n={},n[c]=d),null==d&&a.is(c,"object")&&(n=c);for(var o in n)l("raphael.attr."+o+"."+this.id,this,n[o]);if(n){for(o in this.paper.customAttributes)if(this.paper.customAttributes[b](o)&&n[b](o)&&a.is(this.paper.customAttributes[o],"function")){var p=this.paper.customAttributes[o].apply(this,[].concat(n[o]));this.attrs[o]=n[o];for(var q in p)p[b](q)&&(n[q]=p[q])}n.text&&"text"==this.type&&(this.textpath.string=n.text),B(this,n)}return this},E.toFront=function(){return!this.removed&&this.node.parentNode.appendChild(this.node),this.paper&&this.paper.top!=this&&a._tofront(this,this.paper),this},E.toBack=function(){return this.removed?this:(this.node.parentNode.firstChild!=this.node&&(this.node.parentNode.insertBefore(this.node,this.node.parentNode.firstChild),a._toback(this,this.paper)),this)},E.insertAfter=function(b){return this.removed?this:(b.constructor==a.st.constructor&&(b=b[b.length-1]),b.node.nextSibling?b.node.parentNode.insertBefore(this.node,b.node.nextSibling):b.node.parentNode.appendChild(this.node),a._insertafter(this,b,this.paper),this)},E.insertBefore=function(b){return this.removed?this:(b.constructor==a.st.constructor&&(b=b[0]),b.node.parentNode.insertBefore(this.node,b.node),a._insertbefore(this,b,this.paper),this)},E.blur=function(b){var c=this.node.runtimeStyle,d=c.filter;return d=d.replace(r,o),0!==+b?(this.attrs.blur=b,c.filter=d+n+m+".Blur(pixelradius="+(+b||1.5)+")",c.margin=a.format("-{0}px 0 0 -{0}px",f(+b||1.5))):(c.filter=d,c.margin=0,delete this.attrs.blur),this},a._engine.path=function(a,b){var c=F("shape");c.style.cssText=t,c.coordsize=u+n+u,c.coordorigin=b.coordorigin;var d=new D(c,b),e={fill:"none",stroke:"#000"};a&&(e.path=a),d.type="path",d.path=[],d.Path=o,B(d,e),b.canvas.appendChild(c);var f=F("skew");return f.on=!0,c.appendChild(f),d.skew=f,d.transform(o),d},a._engine.rect=function(b,c,d,e,f,g){var h=a._rectPath(c,d,e,f,g),i=b.path(h),j=i.attrs;return i.X=j.x=c,i.Y=j.y=d,i.W=j.width=e,i.H=j.height=f,j.r=g,j.path=h,i.type="rect",i},a._engine.ellipse=function(a,b,c,d,e){{var f=a.path();f.attrs}return f.X=b-d,f.Y=c-e,f.W=2*d,f.H=2*e,f.type="ellipse",B(f,{cx:b,cy:c,rx:d,ry:e}),f},a._engine.circle=function(a,b,c,d){{var e=a.path();e.attrs}return e.X=b-d,e.Y=c-d,e.W=e.H=2*d,e.type="circle",B(e,{cx:b,cy:c,r:d}),e},a._engine.image=function(b,c,d,e,f,g){var h=a._rectPath(d,e,f,g),i=b.path(h).attr({stroke:"none"}),k=i.attrs,l=i.node,m=l.getElementsByTagName(j)[0];return k.src=c,i.X=k.x=d,i.Y=k.y=e,i.W=k.width=f,i.H=k.height=g,k.path=h,i.type="image",m.parentNode==l&&l.removeChild(m),m.rotate=!0,m.src=c,m.type="tile",i._.fillpos=[d,e],i._.fillsize=[f,g],l.appendChild(m),z(i,1,1,0,0,0),i},a._engine.text=function(b,d,e,g){var h=F("shape"),i=F("path"),j=F("textpath");d=d||0,e=e||0,g=g||"",i.v=a.format("m{0},{1}l{2},{1}",f(d*u),f(e*u),f(d*u)+1),i.textpathok=!0,j.string=c(g),j.on=!0,h.style.cssText=t,h.coordsize=u+n+u,h.coordorigin="0 0";var k=new D(h,b),l={fill:"#000",stroke:"none",font:a._availableAttrs.font,text:g};k.shape=h,k.path=i,k.textpath=j,k.type="text",k.attrs.text=c(g),k.attrs.x=d,k.attrs.y=e,k.attrs.w=1,k.attrs.h=1,B(k,l),h.appendChild(j),h.appendChild(i),b.canvas.appendChild(h);var m=F("skew");return m.on=!0,h.appendChild(m),k.skew=m,k.transform(o),k},a._engine.setSize=function(b,c){var d=this.canvas.style;return this.width=b,this.height=c,b==+b&&(b+="px"),c==+c&&(c+="px"),d.width=b,d.height=c,d.clip="rect(0 "+b+" "+c+" 0)",this._viewBox&&a._engine.setViewBox.apply(this,this._viewBox),this},a._engine.setViewBox=function(b,c,d,e,f){a.eve("raphael.setViewBox",this,this._viewBox,[b,c,d,e,f]);var g,h,i=this.getSize(),j=i.width,k=i.height;return f&&(g=k/e,h=j/d,j>d*g&&(b-=(j-d*g)/2/g),k>e*h&&(c-=(k-e*h)/2/h)),this._viewBox=[b,c,d,e,!!f],this._viewBoxShift={dx:-b,dy:-c,scale:i},this.forEach(function(a){a.transform("...")}),this};var F;a._engine.initWin=function(a){var b=a.document;b.styleSheets.length<31?b.createStyleSheet().addRule(".rvml","behavior:url(#default#VML)"):b.styleSheets[0].addRule(".rvml","behavior:url(#default#VML)");try{!b.namespaces.rvml&&b.namespaces.add("rvml","urn:schemas-microsoft-com:vml"),F=function(a){return b.createElement("')}}catch(c){F=function(a){return b.createElement("<"+a+' xmlns="urn:schemas-microsoft.com:vml" class="rvml">')}}},a._engine.initWin(a._g.win),a._engine.create=function(){var b=a._getContainer.apply(0,arguments),c=b.container,d=b.height,e=b.width,f=b.x,g=b.y;if(!c)throw new Error("VML container not found.");var h=new a._Paper,i=h.canvas=a._g.doc.createElement("div"),j=i.style;return f=f||0,g=g||0,e=e||512,d=d||342,h.width=e,h.height=d,e==+e&&(e+="px"),d==+d&&(d+="px"),h.coordsize=1e3*u+n+1e3*u,h.coordorigin="0 0",h.span=a._g.doc.createElement("span"),h.span.style.cssText="position:absolute;left:-9999em;top:-9999em;padding:0;margin:0;line-height:1;",i.appendChild(h.span),j.cssText=a.format("top:0;left:0;width:{0};height:{1};display:inline-block;position:relative;clip:rect(0 {0} {1} 0);overflow:hidden",e,d),1==c?(a._g.doc.body.appendChild(i),j.left=f+"px",j.top=g+"px",j.position="absolute"):c.firstChild?c.insertBefore(i,c.firstChild):c.appendChild(i),h.renderfix=function(){},h},a.prototype.clear=function(){a.eve("raphael.clear",this),this.canvas.innerHTML=o,this.span=a._g.doc.createElement("span"),this.span.style.cssText="position:absolute;left:-9999em;top:-9999em;padding:0;margin:0;line-height:1;display:inline;",this.canvas.appendChild(this.span),this.bottom=this.top=null},a.prototype.remove=function(){a.eve("raphael.remove",this),this.canvas.parentNode.removeChild(this.canvas);for(var b in this)this[b]="function"==typeof this[b]?a._removedFactory(b):null;return!0};var G=a.st;for(var H in E)E[b](H)&&!G[b](H)&&(G[H]=function(a){return function(){var b=arguments;return this.forEach(function(c){c[a].apply(c,b)})}}(H))}}); \ No newline at end of file diff --git a/examples/SmartSwitch/data_src/js_css_src/styled-notifications/.babelrc b/examples/SmartSwitch/data_src/js_css_src/styled-notifications/.babelrc deleted file mode 100644 index 377ca7046..000000000 --- a/examples/SmartSwitch/data_src/js_css_src/styled-notifications/.babelrc +++ /dev/null @@ -1,3 +0,0 @@ -{ - "presets": ["es2015"] -} \ No newline at end of file diff --git a/examples/SmartSwitch/data_src/js_css_src/styled-notifications/.eslintrc.js b/examples/SmartSwitch/data_src/js_css_src/styled-notifications/.eslintrc.js deleted file mode 100644 index 5bebe588f..000000000 --- a/examples/SmartSwitch/data_src/js_css_src/styled-notifications/.eslintrc.js +++ /dev/null @@ -1,31 +0,0 @@ -module.exports = { - "env": { - "browser": true, - "commonjs": true, - "es6": true - }, - "extends": "eslint:recommended", - "parserOptions": { - "sourceType": "module" - }, - "rules": { - "indent": [ - "error", - "tab" - ], - "linebreak-style": [ - "error", - "windows" - ], - "quotes": [ - "error", - "single" - ], - "semi": [ - "error", - "always" - ], - "no-console": 0, - "no-undef": 0 - } -}; \ No newline at end of file diff --git a/examples/SmartSwitch/data_src/js_css_src/styled-notifications/.gitignore b/examples/SmartSwitch/data_src/js_css_src/styled-notifications/.gitignore deleted file mode 100644 index f949f35de..000000000 --- a/examples/SmartSwitch/data_src/js_css_src/styled-notifications/.gitignore +++ /dev/null @@ -1,30 +0,0 @@ -# IDE files -.idea/ -.DS_Store - -# Build directories -build/ - -# Dependency directories -node_modules/ -jspm_packages/ - -# Lock files -yarn.lock -package-lock.json - -# Logs -logs -*.log -npm-debug.log* -yarn-debug.log* -yarn-error.log* - -# Optional npm cache directory -.npm - -# Optional eslint cache -.eslintcache - -# Yarn Integrity file -.yarn-integrity diff --git a/examples/SmartSwitch/data_src/js_css_src/styled-notifications/.travis.yml b/examples/SmartSwitch/data_src/js_css_src/styled-notifications/.travis.yml deleted file mode 100644 index 0fe294a6f..000000000 --- a/examples/SmartSwitch/data_src/js_css_src/styled-notifications/.travis.yml +++ /dev/null @@ -1,3 +0,0 @@ -language: node_js -node_js: - - "7" diff --git a/examples/SmartSwitch/data_src/js_css_src/styled-notifications/LICENSE.md b/examples/SmartSwitch/data_src/js_css_src/styled-notifications/LICENSE.md deleted file mode 100644 index 5506c2df6..000000000 --- a/examples/SmartSwitch/data_src/js_css_src/styled-notifications/LICENSE.md +++ /dev/null @@ -1,7 +0,0 @@ -# Notifications license - -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: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -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. \ No newline at end of file diff --git a/examples/SmartSwitch/data_src/js_css_src/styled-notifications/__tests__/helpers.test.js b/examples/SmartSwitch/data_src/js_css_src/styled-notifications/__tests__/helpers.test.js deleted file mode 100644 index b97ad7557..000000000 --- a/examples/SmartSwitch/data_src/js_css_src/styled-notifications/__tests__/helpers.test.js +++ /dev/null @@ -1,104 +0,0 @@ -const { partial, append, isString, createElement, createParagraph } = require('../src/helpers'); - -const addNumbers = (x, y) => x + y; - -const sum = (...numbers) => numbers.reduce((total, current) => total + current, 0); - -describe('Helpers', () => { - beforeEach(() => { - document.body.innerHTML = ''; - }); - - describe('Partial', () => { - it('should return a partially applied function', () => { - expect(typeof partial(addNumbers, 10)).toEqual('function'); - }); - - it('should execute function when partially applied function is called', () => { - expect(partial(addNumbers, 20)(10)).toEqual(30); - }); - - it('should gather argument', () => { - expect(partial(sum, 5, 10)(15, 20, 25)).toEqual(75); - }); - }); - - describe('Append', () => { - const container = document.createElement('div'); - document.body.appendChild(container); - - const elementToAppend = document.createElement('h1'); - elementToAppend.classList.add('heading'); - elementToAppend.innerText = 'working'; - - append(container, elementToAppend); - - const element = document.querySelector('.heading'); - expect(element); - - expect(element.innerText).toEqual('working'); - }); - - describe('Is string', () => { - expect(isString(1)).toEqual(false); - expect(isString(null)).toEqual(false); - expect(isString(undefined)).toEqual(false); - expect(isString({})).toEqual(false); - - expect(isString('')).toEqual(true); - expect(isString('a')).toEqual(true); - expect(isString('1')).toEqual(true); - expect(isString('some string')).toEqual(true); - }); - - describe('Create element', () => { - it('should create an element', () => { - expect(createElement('p')).toEqual(document.createElement('p')); - expect(createElement('h1')).toEqual(document.createElement('h1')); - expect(createElement('ul')).toEqual(document.createElement('ul')); - expect(createElement('li')).toEqual(document.createElement('li')); - expect(createElement('div')).toEqual(document.createElement('div')); - expect(createElement('span')).toEqual(document.createElement('span')); - }); - - it('should add class names', () => { - expect(createElement('div', 'someclass1', 'someclass2').classList.contains('someclass2')); - expect(createElement('p', 'para', 'test').classList.contains('para')); - - const mockUl = document.createElement('ul'); - mockUl.classList.add('nav'); - mockUl.classList.add('foo'); - - expect(createElement('ul', 'nav', 'foo').classList).toEqual(mockUl.classList); - }); - }); - - describe('Create paragraph', () => { - it('should create a paragraph', () => { - const p = document.createElement('p'); - p.innerText = 'Some text'; - expect(createParagraph()('Some text')).toEqual(p); - }); - - it('should add class names', () => { - const p = document.createElement('p'); - p.classList.add('body-text'); - p.classList.add('para'); - - expect(createParagraph('body-text', 'para')('')).toEqual(p); - }); - - it('should set inner text', () => { - const p = document.createElement('p'); - p.innerText = 'Hello world!'; - p.classList.add('text'); - - expect(createParagraph('text')('Hello world!')).toEqual(p); - }); - - it('should append to DOM', () => { - append(document.body, createParagraph('text')('hello')); - expect(document.querySelector('.text').innerText).toEqual('hello'); - }); - }); -}); diff --git a/examples/SmartSwitch/data_src/js_css_src/styled-notifications/__tests__/index.tests.js b/examples/SmartSwitch/data_src/js_css_src/styled-notifications/__tests__/index.tests.js deleted file mode 100644 index 9a69d1630..000000000 --- a/examples/SmartSwitch/data_src/js_css_src/styled-notifications/__tests__/index.tests.js +++ /dev/null @@ -1,144 +0,0 @@ -require('../src/index'); - -describe('Notifications', () => { - beforeEach(() => { - document.body.innerHTML = ''; - }); - - it('should display a console warning if no title or message is passed', () => { - jest.spyOn(global.console, 'warn'); - window.createNotification()(); - expect(console.warn).toBeCalled(); - }); - - it('should render a default notification', () => { - const notification = window.createNotification(); - - const title = 'I am a title'; - - // Should initially not contain any notifications - expect(document.querySelectorAll('.ncf').length).toEqual(0); - - // Create a notification instance with a title - notification({ title }); - - // Should be one notification with the title passed in - expect(document.querySelectorAll('.ncf').length).toEqual(1); - expect(document.querySelector('.ncf-title').innerText).toEqual(title); - - // Create a second instance so there should now be two instances - notification({ title }); - expect(document.querySelectorAll('.ncf').length).toEqual(2); - }); - - it('should close on click if the option is enabled', () => { - const notification = window.createNotification({ - closeOnClick: true - }); - - // Create a notification with a generic body - notification({ message: 'some text' }); - - // Should be one notification instance - expect(document.querySelectorAll('.ncf').length).toEqual(1); - - // Click the notification - document.querySelector('.ncf').click(); - - expect(document.querySelectorAll('.ncf').length).toEqual(0); - }); - - it('should not close on click if the option is disabled', () => { - const notification = window.createNotification({ - closeOnClick: false - }); - - // Create a notification with a generic body - notification({ message: 'some text' }); - - // Should be one notification instance - expect(document.querySelectorAll('.ncf').length).toEqual(1); - - // Click the notification - document.querySelector('.ncf').click(); - - expect(document.querySelectorAll('.ncf').length).toEqual(1); - }); - - it('should set position class if valid', () => { - const validPositions = [ - 'nfc-top-left', - 'nfc-top-right', - 'nfc-bottom-left', - 'nfc-bottom-right' - ]; - - validPositions.forEach(position => { - const notification = window.createNotification({ - positionClass: position - }); - - notification({ title: 'title here' }); - - const className = `.${position}`; - - expect(document.querySelectorAll(className).length).toEqual(1); - - const container = document.querySelector(className); - expect(container.querySelectorAll('.ncf').length).toEqual(1); - }); - }); - - it('should revert to default to default position and warn if class is invalid', () => { - const notification = window.createNotification({ - positionClass: 'invalid-name' - }); - - jest.spyOn(global.console, 'warn'); - - notification({ message: 'test' }); - - expect(console.warn).toBeCalled(); - - expect(document.querySelectorAll('.nfc-top-right').length).toEqual(1); - }); - - it('should allow a custom onclick callback', () => { - let a = 'not clicked'; - - const notification = window.createNotification({ - onclick: () => { - a = 'clicked'; - } - }); - - notification({ message: 'click test' }); - - expect(a).toEqual('not clicked'); - - // Click the notification - document.querySelector('.ncf').click(); - - expect(a).toEqual('clicked'); - }); - - it('should show for correct duration', () => { - const notification = window.createNotification({ - showDuration: 500 - }); - - notification({ message: 'test' }); - - expect(document.querySelectorAll('.ncf').length).toEqual(1); - - // Should exist after 400ms - setTimeout(() => { - expect(document.querySelectorAll('.ncf').length).toEqual(1); - }, 400); - - // Should delete after 500ms - setTimeout(() => { - expect(document.querySelectorAll('.ncf').length).toEqual(0); - }); - }, 501); -}); diff --git a/examples/SmartSwitch/data_src/js_css_src/styled-notifications/demo/demo.js b/examples/SmartSwitch/data_src/js_css_src/styled-notifications/demo/demo.js deleted file mode 100644 index d2f0fad2b..000000000 --- a/examples/SmartSwitch/data_src/js_css_src/styled-notifications/demo/demo.js +++ /dev/null @@ -1,34 +0,0 @@ -'use strict'; - -// Written using ES5 JS for browser support -window.addEventListener('DOMContentLoaded', function () { - var form = document.querySelector('form'); - - form.addEventListener('submit', function (e) { - e.preventDefault(); - - // Form elements - var title = form.querySelector('#title').value; - var message = form.querySelector('#message').value; - var position = form.querySelector('#position').value; - var duration = form.querySelector('#duration').value; - var theme = form.querySelector('#theme').value; - var closeOnClick = form.querySelector('#close').checked; - var displayClose = form.querySelector('#closeButton').checked; - - if(!message) { - message = 'You did not enter a message...'; - } - - window.createNotification({ - closeOnClick: closeOnClick, - displayCloseButton: displayClose, - positionClass: position, - showDuration: duration, - theme: theme - })({ - title: title, - message: message - }); - }); -}); \ No newline at end of file diff --git a/examples/SmartSwitch/data_src/js_css_src/styled-notifications/demo/index.html b/examples/SmartSwitch/data_src/js_css_src/styled-notifications/demo/index.html deleted file mode 100644 index d5dd6a6fd..000000000 --- a/examples/SmartSwitch/data_src/js_css_src/styled-notifications/demo/index.html +++ /dev/null @@ -1,101 +0,0 @@ - - - - -Notifications - - - - - - - - - -

Notifications

-
- -
- - - -
- - - -
- - - -
- - - -
- - - - - -
- - - - - -
- - - - - \ No newline at end of file diff --git a/examples/SmartSwitch/data_src/js_css_src/styled-notifications/demo/index_my.html b/examples/SmartSwitch/data_src/js_css_src/styled-notifications/demo/index_my.html deleted file mode 100644 index 412e25d4b..000000000 --- a/examples/SmartSwitch/data_src/js_css_src/styled-notifications/demo/index_my.html +++ /dev/null @@ -1,37 +0,0 @@ - - - - -Notifications - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/examples/SmartSwitch/data_src/js_css_src/styled-notifications/dist/notifications.css b/examples/SmartSwitch/data_src/js_css_src/styled-notifications/dist/notifications.css deleted file mode 100644 index 90d9e61dd..000000000 --- a/examples/SmartSwitch/data_src/js_css_src/styled-notifications/dist/notifications.css +++ /dev/null @@ -1 +0,0 @@ -.ncf-container{font-size:14px;box-sizing:border-box;position:fixed;z-index:999999}.ncf-container.nfc-top-left{top:12px;left:12px}.ncf-container.nfc-top-right{top:12px;right:12px}.ncf-container.nfc-bottom-right{bottom:12px;right:12px}.ncf-container.nfc-bottom-left{bottom:12px;left:12px}@media (max-width:767px){.ncf-container{left:0;right:0}}.ncf-container .ncf{background:#fff;transition:.3s ease;position:relative;pointer-events:auto;overflow:hidden;margin:0 0 6px;padding:30px;width:300px;border-radius:3px 3px 3px 3px;box-shadow:0 0 12px #999;color:#000;opacity:.9;-ms-filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=90);filter:alpha(opacity=90);background-position:15px!important;background-repeat:no-repeat!important;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.ncf-container .ncf:hover{box-shadow:0 0 12px #000;opacity:1;cursor:pointer}.ncf-container .ncf .ncf-title{font-weight:700;font-size:16px;text-align:left;margin-top:0;margin-bottom:6px;word-wrap:break-word}.ncf-container .ncf .nfc-message{margin:0;text-align:left;word-wrap:break-word}.ncf-container .success{background:#51a351;color:#fff;padding:15px 15px 15px 50px;background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAADsSURBVEhLY2AYBfQMgf///3P8+/evAIgvA/FsIF+BavYDDWMBGroaSMMBiE8VC7AZDrIFaMFnii3AZTjUgsUUWUDA8OdAH6iQbQEhw4HyGsPEcKBXBIC4ARhex4G4BsjmweU1soIFaGg/WtoFZRIZdEvIMhxkCCjXIVsATV6gFGACs4Rsw0EGgIIH3QJYJgHSARQZDrWAB+jawzgs+Q2UO49D7jnRSRGoEFRILcdmEMWGI0cm0JJ2QpYA1RDvcmzJEWhABhD/pqrL0S0CWuABKgnRki9lLseS7g2AlqwHWQSKH4oKLrILpRGhEQCw2LiRUIa4lwAAAABJRU5ErkJggg==")}.ncf-container .info{background:#2f96b4;color:#fff;padding:15px 15px 15px 50px;background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGwSURBVEhLtZa9SgNBEMc9sUxxRcoUKSzSWIhXpFMhhYWFhaBg4yPYiWCXZxBLERsLRS3EQkEfwCKdjWJAwSKCgoKCcudv4O5YLrt7EzgXhiU3/4+b2ckmwVjJSpKkQ6wAi4gwhT+z3wRBcEz0yjSseUTrcRyfsHsXmD0AmbHOC9Ii8VImnuXBPglHpQ5wwSVM7sNnTG7Za4JwDdCjxyAiH3nyA2mtaTJufiDZ5dCaqlItILh1NHatfN5skvjx9Z38m69CgzuXmZgVrPIGE763Jx9qKsRozWYw6xOHdER+nn2KkO+Bb+UV5CBN6WC6QtBgbRVozrahAbmm6HtUsgtPC19tFdxXZYBOfkbmFJ1VaHA1VAHjd0pp70oTZzvR+EVrx2Ygfdsq6eu55BHYR8hlcki+n+kERUFG8BrA0BwjeAv2M8WLQBtcy+SD6fNsmnB3AlBLrgTtVW1c2QN4bVWLATaIS60J2Du5y1TiJgjSBvFVZgTmwCU+dAZFoPxGEEs8nyHC9Bwe2GvEJv2WXZb0vjdyFT4Cxk3e/kIqlOGoVLwwPevpYHT+00T+hWwXDf4AJAOUqWcDhbwAAAAASUVORK5CYII=")}.ncf-container .warning{background:#f87400;color:#fff;padding:15px 15px 15px 50px;background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGYSURBVEhL5ZSvTsNQFMbXZGICMYGYmJhAQIJAICYQPAACiSDB8AiICQQJT4CqQEwgJvYASAQCiZiYmJhAIBATCARJy+9rTsldd8sKu1M0+dLb057v6/lbq/2rK0mS/TRNj9cWNAKPYIJII7gIxCcQ51cvqID+GIEX8ASG4B1bK5gIZFeQfoJdEXOfgX4QAQg7kH2A65yQ87lyxb27sggkAzAuFhbbg1K2kgCkB1bVwyIR9m2L7PRPIhDUIXgGtyKw575yz3lTNs6X4JXnjV+LKM/m3MydnTbtOKIjtz6VhCBq4vSm3ncdrD2lk0VgUXSVKjVDJXJzijW1RQdsU7F77He8u68koNZTz8Oz5yGa6J3H3lZ0xYgXBK2QymlWWA+RWnYhskLBv2vmE+hBMCtbA7KX5drWyRT/2JsqZ2IvfB9Y4bWDNMFbJRFmC9E74SoS0CqulwjkC0+5bpcV1CZ8NMej4pjy0U+doDQsGyo1hzVJttIjhQ7GnBtRFN1UarUlH8F3xict+HY07rEzoUGPlWcjRFRr4/gChZgc3ZL2d8oAAAAASUVORK5CYII=")}.ncf-container .error{background:#bd362f;color:#fff;padding:15px 15px 15px 50px;background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAHOSURBVEhLrZa/SgNBEMZzh0WKCClSCKaIYOED+AAKeQQLG8HWztLCImBrYadgIdY+gIKNYkBFSwu7CAoqCgkkoGBI/E28PdbLZmeDLgzZzcx83/zZ2SSXC1j9fr+I1Hq93g2yxH4iwM1vkoBWAdxCmpzTxfkN2RcyZNaHFIkSo10+8kgxkXIURV5HGxTmFuc75B2RfQkpxHG8aAgaAFa0tAHqYFfQ7Iwe2yhODk8+J4C7yAoRTWI3w/4klGRgR4lO7Rpn9+gvMyWp+uxFh8+H+ARlgN1nJuJuQAYvNkEnwGFck18Er4q3egEc/oO+mhLdKgRyhdNFiacC0rlOCbhNVz4H9FnAYgDBvU3QIioZlJFLJtsoHYRDfiZoUyIxqCtRpVlANq0EU4dApjrtgezPFad5S19Wgjkc0hNVnuF4HjVA6C7QrSIbylB+oZe3aHgBsqlNqKYH48jXyJKMuAbiyVJ8KzaB3eRc0pg9VwQ4niFryI68qiOi3AbjwdsfnAtk0bCjTLJKr6mrD9g8iq/S/B81hguOMlQTnVyG40wAcjnmgsCNESDrjme7wfftP4P7SP4N3CJZdvzoNyGq2c/HWOXJGsvVg+RA/k2MC/wN6I2YA2Pt8GkAAAAASUVORK5CYII=")!important}.ncf-container button{position:relative;right:-.3em;top:-.3em;float:right;font-weight:700;color:#fff;text-shadow:0 1px 0 #fff;opacity:.8;line-height:1;font-size:16px;padding:0;cursor:pointer;background:transparent;border:0}.ncf-container button:hover{opacity:1} \ No newline at end of file diff --git a/examples/SmartSwitch/data_src/js_css_src/styled-notifications/dist/notifications.css.gz b/examples/SmartSwitch/data_src/js_css_src/styled-notifications/dist/notifications.css.gz deleted file mode 100644 index b1e1ecb19e475a9932e331065120ac6a1bdbbc3c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2487 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 B-pc?0 diff --git a/examples/SmartSwitch/data_src/js_css_src/styled-notifications/dist/notifications.js b/examples/SmartSwitch/data_src/js_css_src/styled-notifications/dist/notifications.js deleted file mode 100644 index 34b339e61..000000000 --- a/examples/SmartSwitch/data_src/js_css_src/styled-notifications/dist/notifications.js +++ /dev/null @@ -1 +0,0 @@ -!function(t){function n(i){if(e[i])return e[i].exports;var o=e[i]={i:i,l:!1,exports:{}};return t[i].call(o.exports,o,o.exports,n),o.l=!0,o.exports}var e={};n.m=t,n.c=e,n.d=function(t,e,i){n.o(t,e)||Object.defineProperty(t,e,{configurable:!1,enumerable:!0,get:i})},n.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return n.d(e,"a",e),e},n.o=function(t,n){return Object.prototype.hasOwnProperty.call(t,n)},n.p="",n(n.s=0)}([function(t,n,e){e(1),t.exports=e(4)},function(t,n,e){"use strict";var i=Object.assign||function(t){for(var n=1;n-1}(t.positionClass)||(console.warn("An invalid notification position class has been specified."),t.positionClass=c.positionClass),t.onclick&&"function"!=typeof t.onclick&&(console.warn("Notification on click must be a function."),t.onclick=c.onclick),"number"!=typeof t.showDuration&&(t.showDuration=c.showDuration),(0,o.isString)(t.theme)&&0!==t.theme.length||(console.warn("Notification theme must be a string with length"),t.theme=c.theme),t}function e(t){return t=n(t),function(){var n=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},e=n.title,i=n.message,c=r(t.positionClass);if(!e&&!i)return console.warn("Notification must contain a title or a message!");var a=(0,o.createElement)("div","ncf",t.theme);if(!0===t.closeOnClick&&a.addEventListener("click",function(){return c.removeChild(a)}),t.onclick&&a.addEventListener("click",function(n){return t.onclick(n)}),t.displayCloseButton){var s=(0,o.createElement)("button");s.innerText="X",!1===t.closeOnClick&&s.addEventListener("click",function(){return c.removeChild(a)}),(0,o.append)(a,s)}if((0,o.isString)(e)&&e.length&&(0,o.append)(a,(0,o.createParagraph)("ncf-title")(e)),(0,o.isString)(i)&&i.length&&(0,o.append)(a,(0,o.createParagraph)("nfc-message")(i)),(0,o.append)(c,a),t.showDuration&&t.showDuration>0){var l=setTimeout(function(){c.removeChild(a),0===c.querySelectorAll(".ncf").length&&document.body.removeChild(c)},t.showDuration);(t.closeOnClick||t.displayCloseButton)&&a.addEventListener("click",function(){return clearTimeout(l)})}}}function r(t){var n=document.querySelector("."+t);return n||(n=(0,o.createElement)("div","ncf-container",t),(0,o.append)(document.body,n)),n}var c={closeOnClick:!0,displayCloseButton:!1,positionClass:"nfc-top-right",onclick:!1,showDuration:3500,theme:"success"};t.createNotification?console.warn("Window already contains a create notification function. Have you included the script twice?"):t.createNotification=e}(window)},function(t,n,e){"use strict";!function(){function t(t){this.el=t;for(var n=t.className.replace(/^\s+|\s+$/g,"").split(/\s+/),i=0;i1?n-1:0),i=1;i1?n-1:0),i=1;i1?n-1:0),i=1;i1?n-1:0),c=1;cLmfM||m-$;8>RU#q-s5XUMp@m@G?VkH3orlN<+fg?Z@TR&u{)6)+hLAf}EjW+Nsw+G1G zdDwPT)@<~)%;kp+0!UNtp_wiD7Tj7_tU~=p3|&!!aEpbD-@k|Au}#YiZgo4@u`w_l zD$C4O>zR+89}qqTP9#CN9Q<*1XpZSb8cPnjb=I99Al}L1=~vU*6nyCg0_1}rgd1w& zLM&NDUk^3nK}Vn~#$D@J0rVP*O*fIUfT(b}R*r~^8R-YCN(ppT;g!i}IM1!vrR8NLb@F(nw_GRG^MI@tE zS4;+H2-S`lCzxU%ARnGp?CjTjWgc|mf#U_CMpMSAF9*7Kj-)hOhP&Mk_JCwqo(a*+ z8pfSYzd|2&4xkr7WAs(KT~y1X4UIyf>i@VI*iWCUSir(FhI<7f{>A-BMl$bX3 zewi>h+K56YYMP+wkSd*eu3b{h6#5FbyE77fSk$S03YQIJ@ z!;R^ATcHZ9OSS0e66~*;=%M@q(YY-njflz=QeW4jLgo74BKK7*xJB4{4uF7)ehsJo zuJP#`h(Z70d_dh!7cpeQC4KMX;&3xRk$XTMqGuJ*%kSP47f<+m;qsOfq%C?}J9-&c zE;FvhGSN3o+b3!4lb~tlP(L@Jzwt$u)>nrRq6Qu}q&S^OIMb7qXcKk8ZwD=TS_bQ0wMksRQ5-QJx@NZXKpQPwK-vzmBP|;r^2d&Y9n#F4pWR4j`?&i zqG$+o@9Ey#Fn)zs3K}~Zt{C@)>Mz!~)+R?eztbtMA&4z{db=Q@MABj%tzMP2e!GHqeJMll7 z` - -2. Link to notifications.js `` - -## Usage -### Custom options -- closeOnClick - Close the notification dialog when a click is invoked. -- displayCloseButton - Display a close button in the top right hand corner of the notification. -- positionClass - Set the position of the notification dialog. Accepted positions: ('nfc-top-right', 'nfc-bottom-right', 'nfc-bottom-left', 'nfc-top-left'). -- onClick - Call a callback function when a click is invoked on a notification. -- showDuration - Milliseconds the notification should be visible (0 for a notification that will remain open until clicked) -- theme - Set the position of the notification dialog. Accepted positions: ('success', 'info', 'warning', 'error', 'A custom clasName'). -``` -const defaultOptions = { - closeOnClick: true, - displayCloseButton: false, - positionClass: 'nfc-top-right', - onclick: false, - showDuration: 3500, - theme: 'success' -}; -``` - -## Example - -### Success notification -``` -// Create a success notification instance -const successNotification = window.createNotification({ - theme: 'success', - showDuration: 5000 -}); - -// Invoke success notification -successNotification({ - message: 'Simple success notification' -}); - -// Use the same instance but pass a title -successNotification({ - title: 'Working', - message: 'Simple success notification' -}); -``` - -### Information notification -``` -// Only running it once? Invoke immediately like this -window.createNotification({ - theme: 'success', - showDuration: 5000 -})({ - message: 'I have some information for you...' -}); -``` - -### Todo -~~1. Add to NPM~~ -2. Improve documentation -3. Further device testing -4. Add contributor instructions \ No newline at end of file diff --git a/examples/SmartSwitch/data_src/js_css_src/styled-notifications/src/helpers.js b/examples/SmartSwitch/data_src/js_css_src/styled-notifications/src/helpers.js deleted file mode 100644 index 5a7de2b95..000000000 --- a/examples/SmartSwitch/data_src/js_css_src/styled-notifications/src/helpers.js +++ /dev/null @@ -1,24 +0,0 @@ -export const partial = (fn, ...presetArgs) => (...laterArgs) => fn(...presetArgs, ...laterArgs); - -export const append = (el, ...children) => children.forEach(child => el.appendChild(child)); - -export const isString = input => typeof input === 'string'; - -export const createElement = (elementType, ...classNames) => { - const element = document.createElement(elementType); - - if(classNames.length) { - classNames.forEach(currentClass => element.classList.add(currentClass)); - } - - return element; -}; - -const setInnerText = (element, text) => { - element.innerText = text; - return element; -}; - -const createTextElement = (elementType, ...classNames) => partial(setInnerText, createElement(elementType, ...classNames)); - -export const createParagraph = (...classNames) => createTextElement('p', ...classNames); \ No newline at end of file diff --git a/examples/SmartSwitch/data_src/js_css_src/styled-notifications/src/index.js b/examples/SmartSwitch/data_src/js_css_src/styled-notifications/src/index.js deleted file mode 100644 index 51512babe..000000000 --- a/examples/SmartSwitch/data_src/js_css_src/styled-notifications/src/index.js +++ /dev/null @@ -1,148 +0,0 @@ -'use strict'; - -// Polyfills -import './polyfills/classList'; - -import { - append, - createElement, - createParagraph, - isString -} from './helpers'; - -(function Notifications(window) { - // Default notification options - const defaultOptions = { - closeOnClick: true, - displayCloseButton: false, - positionClass: 'nfc-top-right', - onclick: false, - showDuration: 3500, - theme: 'success' - }; - - function configureOptions(options) { - // Create a copy of options and merge with defaults - options = Object.assign({}, defaultOptions, options); - - // Validate position class - function validatePositionClass(className) { - const validPositions = [ - 'nfc-top-left', - 'nfc-top-right', - 'nfc-bottom-left', - 'nfc-bottom-right' - ]; - - return validPositions.indexOf(className) > -1; - } - - // Verify position, if invalid reset to default - if (!validatePositionClass(options.positionClass)) { - console.warn('An invalid notification position class has been specified.'); - options.positionClass = defaultOptions.positionClass; - } - - // Verify onClick is a function - if (options.onclick && typeof options.onclick !== 'function') { - console.warn('Notification on click must be a function.'); - options.onclick = defaultOptions.onclick; - } - - // Verify show duration - if(typeof options.showDuration !== 'number') { - options.showDuration = defaultOptions.showDuration; - } - - // Verify theme - if(!isString(options.theme) || options.theme.length === 0) { - console.warn('Notification theme must be a string with length'); - options.theme = defaultOptions.theme; - } - - return options; - } - - // Create a new notification instance - function createNotification(options) { - // Validate options and set defaults - options = configureOptions(options); - - // Return a notification function - return function notification({ title, message } = {}) { - const container = createNotificationContainer(options.positionClass); - - if(!title && !message) { - return console.warn('Notification must contain a title or a message!'); - } - - // Create the notification wrapper - const notificationEl = createElement('div', 'ncf', options.theme); - - // Close on click - if(options.closeOnClick === true) { - notificationEl.addEventListener('click', () => container.removeChild(notificationEl)); - } - - // Custom click callback - if(options.onclick) { - notificationEl.addEventListener('click', (e) => options.onclick(e)); - } - - // Display close button - if(options.displayCloseButton) { - const closeButton = createElement('button'); - closeButton.innerText = 'X'; - - // Use the wrappers close on click to avoid useless event listeners - if(options.closeOnClick === false){ - closeButton.addEventListener('click', () =>container.removeChild(notificationEl)); - } - - append(notificationEl, closeButton); - } - - // Append title and message - isString(title) && title.length && append(notificationEl, createParagraph('ncf-title')(title)); - isString(message) && message.length && append(notificationEl, createParagraph('nfc-message')(message)); - - // Append to container - append(container, notificationEl); - - // Remove element after duration - if(options.showDuration && options.showDuration > 0) { - const timeout = setTimeout(() => { - container.removeChild(notificationEl); - - // Remove container if empty - if(container.querySelectorAll('.ncf').length === 0) { - document.body.removeChild(container); - } - }, options.showDuration); - - // If close on click is enabled and the user clicks, cancel timeout - if(options.closeOnClick || options.displayCloseButton) { - notificationEl.addEventListener('click', () => clearTimeout(timeout)); - } - } - }; - } - - function createNotificationContainer(position) { - let container = document.querySelector(`.${position}`); - - if(!container) { - container = createElement('div', 'ncf-container', position); - append(document.body, container); - } - - return container; - } - - // Add Notifications to window to make globally accessible - if (window.createNotification) { - console.warn('Window already contains a create notification function. Have you included the script twice?'); - } else { - window.createNotification = createNotification; - } -})(window); diff --git a/examples/SmartSwitch/data_src/js_css_src/styled-notifications/src/polyfills/classList.js b/examples/SmartSwitch/data_src/js_css_src/styled-notifications/src/polyfills/classList.js deleted file mode 100644 index e040d70d9..000000000 --- a/examples/SmartSwitch/data_src/js_css_src/styled-notifications/src/polyfills/classList.js +++ /dev/null @@ -1,68 +0,0 @@ -(function () { - if (typeof window.Element === 'undefined' || 'classList' in document.documentElement) return; - - var prototype = Array.prototype, - push = prototype.push, - splice = prototype.splice, - join = prototype.join; - - function DOMTokenList(el) { - this.el = el; - // The className needs to be trimmed and split on whitespace - // to retrieve a list of classes. - var classes = el.className.replace(/^\s+|\s+$/g,'').split(/\s+/); - for (var i = 0; i < classes.length; i++) { - push.call(this, classes[i]); - } - } - - DOMTokenList.prototype = { - add: function(token) { - if(this.contains(token)) return; - push.call(this, token); - this.el.className = this.toString(); - }, - contains: function(token) { - return this.el.className.indexOf(token) != -1; - }, - item: function(index) { - return this[index] || null; - }, - remove: function(token) { - if (!this.contains(token)) return; - for (var i = 0; i < this.length; i++) { - if (this[i] == token) break; - } - splice.call(this, i, 1); - this.el.className = this.toString(); - }, - toString: function() { - return join.call(this, ' '); - }, - toggle: function(token) { - if (!this.contains(token)) { - this.add(token); - } else { - this.remove(token); - } - - return this.contains(token); - } - }; - - window.DOMTokenList = DOMTokenList; - - function defineElementGetter (obj, prop, getter) { - if (Object.defineProperty) { - Object.defineProperty(obj, prop,{ - get : getter - }); - } else { - obj.__defineGetter__(prop, getter); - } - } - - defineElementGetter(Element.prototype, 'classList', function () { - return new DOMTokenList(this); - }); -})(); \ No newline at end of file diff --git a/examples/SmartSwitch/data_src/js_css_src/styled-notifications/src/style.scss b/examples/SmartSwitch/data_src/js_css_src/styled-notifications/src/style.scss deleted file mode 100644 index 733bfd590..000000000 --- a/examples/SmartSwitch/data_src/js_css_src/styled-notifications/src/style.scss +++ /dev/null @@ -1,134 +0,0 @@ -// Base colors -$success: #51A351; -$info: #2F96B4; -$warning: #f87400; -$error: #BD362F; -$grey: #999999; - -.ncf-container { - font-size: 14px; - box-sizing: border-box; - position: fixed; - z-index: 999999; - - &.nfc-top-left { - top: 12px; - left: 12px; - } - - &.nfc-top-right { - top: 12px; - right: 12px; - } - - &.nfc-bottom-right { - bottom: 12px; - right: 12px; - } - - &.nfc-bottom-left { - bottom: 12px; - left: 12px; - } - - @media (max-width: 767px) { - left: 0; - right: 0; - } - - .ncf { - background: #ffffff; - transition: .3s ease; - position: relative; - pointer-events: auto; - overflow: hidden; - margin: 0 0 6px; - padding: 30px; - width: 300px; - border-radius: 3px 3px 3px 3px; - box-shadow: 0 0 12px $grey; - color: #000000; - opacity: 0.9; - -ms-filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=90); - filter: alpha(opacity=90); - background-position: 15px center !important; - background-repeat: no-repeat !important; - - // Prevent annoying text selection - -webkit-user-select: none; /* Chrome all / Safari all */ - -moz-user-select: none; /* Firefox all */ - -ms-user-select: none; /* IE 10+ */ - user-select: none; /* Likely future */ - - &:hover { - box-shadow: 0 0 12px #000000; - opacity: 1; - cursor: pointer; - } - - .ncf-title { - font-weight: bold; - font-size: 16px; - text-align: left; - margin-top: 0; - margin-bottom: 6px; - word-wrap: break-word; - } - - .nfc-message { - margin: 0; - text-align: left; - word-wrap: break-word; - } - } - - // Themes - .success { - background: $success; - color: #ffffff; - padding: 15px 15px 15px 50px; - background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAADsSURBVEhLY2AYBfQMgf///3P8+/evAIgvA/FsIF+BavYDDWMBGroaSMMBiE8VC7AZDrIFaMFnii3AZTjUgsUUWUDA8OdAH6iQbQEhw4HyGsPEcKBXBIC4ARhex4G4BsjmweU1soIFaGg/WtoFZRIZdEvIMhxkCCjXIVsATV6gFGACs4Rsw0EGgIIH3QJYJgHSARQZDrWAB+jawzgs+Q2UO49D7jnRSRGoEFRILcdmEMWGI0cm0JJ2QpYA1RDvcmzJEWhABhD/pqrL0S0CWuABKgnRki9lLseS7g2AlqwHWQSKH4oKLrILpRGhEQCw2LiRUIa4lwAAAABJRU5ErkJggg=="); - } - - .info { - background: $info; - color: #ffffff; - padding: 15px 15px 15px 50px; - background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGwSURBVEhLtZa9SgNBEMc9sUxxRcoUKSzSWIhXpFMhhYWFhaBg4yPYiWCXZxBLERsLRS3EQkEfwCKdjWJAwSKCgoKCcudv4O5YLrt7EzgXhiU3/4+b2ckmwVjJSpKkQ6wAi4gwhT+z3wRBcEz0yjSseUTrcRyfsHsXmD0AmbHOC9Ii8VImnuXBPglHpQ5wwSVM7sNnTG7Za4JwDdCjxyAiH3nyA2mtaTJufiDZ5dCaqlItILh1NHatfN5skvjx9Z38m69CgzuXmZgVrPIGE763Jx9qKsRozWYw6xOHdER+nn2KkO+Bb+UV5CBN6WC6QtBgbRVozrahAbmm6HtUsgtPC19tFdxXZYBOfkbmFJ1VaHA1VAHjd0pp70oTZzvR+EVrx2Ygfdsq6eu55BHYR8hlcki+n+kERUFG8BrA0BwjeAv2M8WLQBtcy+SD6fNsmnB3AlBLrgTtVW1c2QN4bVWLATaIS60J2Du5y1TiJgjSBvFVZgTmwCU+dAZFoPxGEEs8nyHC9Bwe2GvEJv2WXZb0vjdyFT4Cxk3e/kIqlOGoVLwwPevpYHT+00T+hWwXDf4AJAOUqWcDhbwAAAAASUVORK5CYII="); - } - - .warning { - background: $warning; - color: #ffffff; - padding: 15px 15px 15px 50px; - background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGYSURBVEhL5ZSvTsNQFMbXZGICMYGYmJhAQIJAICYQPAACiSDB8AiICQQJT4CqQEwgJvYASAQCiZiYmJhAIBATCARJy+9rTsldd8sKu1M0+dLb057v6/lbq/2rK0mS/TRNj9cWNAKPYIJII7gIxCcQ51cvqID+GIEX8ASG4B1bK5gIZFeQfoJdEXOfgX4QAQg7kH2A65yQ87lyxb27sggkAzAuFhbbg1K2kgCkB1bVwyIR9m2L7PRPIhDUIXgGtyKw575yz3lTNs6X4JXnjV+LKM/m3MydnTbtOKIjtz6VhCBq4vSm3ncdrD2lk0VgUXSVKjVDJXJzijW1RQdsU7F77He8u68koNZTz8Oz5yGa6J3H3lZ0xYgXBK2QymlWWA+RWnYhskLBv2vmE+hBMCtbA7KX5drWyRT/2JsqZ2IvfB9Y4bWDNMFbJRFmC9E74SoS0CqulwjkC0+5bpcV1CZ8NMej4pjy0U+doDQsGyo1hzVJttIjhQ7GnBtRFN1UarUlH8F3xict+HY07rEzoUGPlWcjRFRr4/gChZgc3ZL2d8oAAAAASUVORK5CYII="); - } - - .error { - background: $error; - color: #ffffff; - padding: 15px 15px 15px 50px; - background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAHOSURBVEhLrZa/SgNBEMZzh0WKCClSCKaIYOED+AAKeQQLG8HWztLCImBrYadgIdY+gIKNYkBFSwu7CAoqCgkkoGBI/E28PdbLZmeDLgzZzcx83/zZ2SSXC1j9fr+I1Hq93g2yxH4iwM1vkoBWAdxCmpzTxfkN2RcyZNaHFIkSo10+8kgxkXIURV5HGxTmFuc75B2RfQkpxHG8aAgaAFa0tAHqYFfQ7Iwe2yhODk8+J4C7yAoRTWI3w/4klGRgR4lO7Rpn9+gvMyWp+uxFh8+H+ARlgN1nJuJuQAYvNkEnwGFck18Er4q3egEc/oO+mhLdKgRyhdNFiacC0rlOCbhNVz4H9FnAYgDBvU3QIioZlJFLJtsoHYRDfiZoUyIxqCtRpVlANq0EU4dApjrtgezPFad5S19Wgjkc0hNVnuF4HjVA6C7QrSIbylB+oZe3aHgBsqlNqKYH48jXyJKMuAbiyVJ8KzaB3eRc0pg9VwQ4niFryI68qiOi3AbjwdsfnAtk0bCjTLJKr6mrD9g8iq/S/B81hguOMlQTnVyG40wAcjnmgsCNESDrjme7wfftP4P7SP4N3CJZdvzoNyGq2c/HWOXJGsvVg+RA/k2MC/wN6I2YA2Pt8GkAAAAASUVORK5CYII=") !important; - } - - button { - position: relative; - right: -0.3em; - top: -0.3em; - float: right; - font-weight: bold; - color: #FFFFFF; - text-shadow: 0 1px 0 #ffffff; - opacity: 0.8; - line-height: 1; - font-size: 16px; - padding: 0; - cursor: pointer; - background: transparent; - border: 0; - - &:hover { - opacity: 1; - } - } -} diff --git a/examples/SmartSwitch/data_src/js_css_src/styled-notifications/webpack.config.js b/examples/SmartSwitch/data_src/js_css_src/styled-notifications/webpack.config.js deleted file mode 100644 index 36a4ca3d1..000000000 --- a/examples/SmartSwitch/data_src/js_css_src/styled-notifications/webpack.config.js +++ /dev/null @@ -1,41 +0,0 @@ -const webpack = require('webpack'); -const ExtractTextPlugin = require('extract-text-webpack-plugin'); - -const extractSass = new ExtractTextPlugin({ - filename: 'notifications.css', - disable: process.env.NODE_ENV === 'development' -}); - -module.exports = { - entry: ['./src/index.js', './src/style.scss'], - output: { - path: __dirname + '/dist', - filename: 'notifications.js' - }, - module: { - rules: [ - { - test: /\.js$/, - loader: 'babel-loader', - query: { - presets: ['babel-preset-es2015', 'es2015-ie'] - } - }, - { - test: /\.scss$/, - use: extractSass.extract({ - use: [{ - loader: 'css-loader' - }, { - loader: 'sass-loader' - }], - // use style-loader in development - fallback: 'style-loader' - }) - } - ], - }, - plugins: [ - extractSass - ] -}; \ No newline at end of file diff --git a/examples/regex_patterns/.test.build_flags b/examples/regex_patterns/.test.build_flags deleted file mode 100644 index 9ea3bb74a..000000000 --- a/examples/regex_patterns/.test.build_flags +++ /dev/null @@ -1 +0,0 @@ --DASYNCWEBSERVER_REGEX=1 diff --git a/examples/regex_patterns/regex_patterns.ino b/examples/regex_patterns/regex_patterns.ino deleted file mode 100644 index fb013063e..000000000 --- a/examples/regex_patterns/regex_patterns.ino +++ /dev/null @@ -1,77 +0,0 @@ -// -// A simple server implementation with regex routes: -// * serve static messages -// * read GET and POST parameters -// * handle missing pages / 404s -// - -// Add buildflag ASYNCWEBSERVER_REGEX to enable the regex support - -// For platformio: platformio.ini: -// build_flags = -// -DASYNCWEBSERVER_REGEX - -// For arduino IDE: create/update platform.local.txt -// Windows: C:\Users\(username)\AppData\Local\Arduino15\packages\espxxxx\hardware\espxxxx\{version}\platform.local.txt -// Linux: ~/.arduino15/packages/espxxxx/hardware/espxxxx/{version}/platform.local.txt -// -// compiler.cpp.extra_flags=-DASYNCWEBSERVER_REGEX=1 - -#include -#ifdef ESP32 -#include -#include -#elif defined(ESP8266) -#include -#include -#endif -#include - -AsyncWebServer server(80); - -const char* ssid = "YOUR_SSID"; -const char* password = "YOUR_PASSWORD"; - -const char* PARAM_MESSAGE = "message"; - -void notFound(AsyncWebServerRequest *request) { - request->send(404, "text/plain", "Not found"); -} - -void setup() { - - Serial.begin(115200); - WiFi.mode(WIFI_STA); - WiFi.begin(ssid, password); - if (WiFi.waitForConnectResult() != WL_CONNECTED) { - Serial.printf("WiFi Failed!\n"); - return; - } - - Serial.print("IP Address: "); - Serial.println(WiFi.localIP()); - - server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){ - request->send(200, "text/plain", "Hello, world"); - }); - - // Send a GET request to /sensor/ - server.on("^\\/sensor\\/([0-9]+)$", HTTP_GET, [] (AsyncWebServerRequest *request) { - String sensorNumber = request->pathArg(0); - request->send(200, "text/plain", "Hello, sensor: " + sensorNumber); - }); - - // Send a GET request to /sensor//action/ - server.on("^\\/sensor\\/([0-9]+)\\/action\\/([a-zA-Z0-9]+)$", HTTP_GET, [] (AsyncWebServerRequest *request) { - String sensorNumber = request->pathArg(0); - String action = request->pathArg(1); - request->send(200, "text/plain", "Hello, sensor: " + sensorNumber + ", with action: " + action); - }); - - server.onNotFound(notFound); - - server.begin(); -} - -void loop() { -} diff --git a/examples/simple_server/simple_server.ino b/examples/simple_server/simple_server.ino deleted file mode 100644 index bdbcf60dc..000000000 --- a/examples/simple_server/simple_server.ino +++ /dev/null @@ -1,74 +0,0 @@ -// -// A simple server implementation showing how to: -// * serve static messages -// * read GET and POST parameters -// * handle missing pages / 404s -// - -#include -#ifdef ESP32 -#include -#include -#elif defined(ESP8266) -#include -#include -#endif -#include - -AsyncWebServer server(80); - -const char* ssid = "YOUR_SSID"; -const char* password = "YOUR_PASSWORD"; - -const char* PARAM_MESSAGE = "message"; - -void notFound(AsyncWebServerRequest *request) { - request->send(404, "text/plain", "Not found"); -} - -void setup() { - - Serial.begin(115200); - WiFi.mode(WIFI_STA); - WiFi.begin(ssid, password); - if (WiFi.waitForConnectResult() != WL_CONNECTED) { - Serial.printf("WiFi Failed!\n"); - return; - } - - Serial.print("IP Address: "); - Serial.println(WiFi.localIP()); - - server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){ - request->send(200, "text/plain", "Hello, world"); - }); - - // Send a GET request to /get?message= - server.on("/get", HTTP_GET, [] (AsyncWebServerRequest *request) { - String message; - if (request->hasParam(PARAM_MESSAGE)) { - message = request->getParam(PARAM_MESSAGE)->value(); - } else { - message = "No message sent"; - } - request->send(200, "text/plain", "Hello, GET: " + message); - }); - - // Send a POST request to /post with a form field message set to - server.on("/post", HTTP_POST, [](AsyncWebServerRequest *request){ - String message; - if (request->hasParam(PARAM_MESSAGE, true)) { - message = request->getParam(PARAM_MESSAGE, true)->value(); - } else { - message = "No message sent"; - } - request->send(200, "text/plain", "Hello, POST: " + message); - }); - - server.onNotFound(notFound); - - server.begin(); -} - -void loop() { -} \ No newline at end of file diff --git a/extras/README.md b/extras/README.md deleted file mode 100644 index ac2457282..000000000 --- a/extras/README.md +++ /dev/null @@ -1,25 +0,0 @@ -### Extras -Additions to facilitate code modifications (for MS Win, similar can be done on Linux) - -- **ehg.c (ehg.exe):** Tool to generate C-code array from file' bytes -Based on [bin2array](https://github.com/TheLivingOne/bin2array/) PROGMEM keyword can optionally be added. - -- **rehg.c (rehg.exe):** Tool to reverse C-code array generated by **ehg.exe** back to a file -Based on [c2bin](https://github.com/birkett/cbintools/tree/master/c2bin) -First 4 lines of source are ignored, then parses the 0xHH - formated bytes -until a } is found on separate new line. - -### Tools -- [TCC : Tiny C Compiler](https://bellard.org/tcc/) for **ehg** and **rehg** compiling on MS Win -- [7-Zip](https://www.7-zip.org) Install 7z and use the included gzip as command line tool -- [Node.js](https://nodejs.org) Install Node with default settings, then run: - - ``` npm install html-minifier-terser -g, npm install -g github-files-fetcher ``` - -### Batch files provided -- **do_emb.bat:** Generates **edit.htm.gz.h** file for embedding to **SPIFFSEditor.cpp** as binary C array - -You need to comment **#define EDFS** at **SPIFFSEditor.cpp** for this choice -- **do_ed_fs.bat:** Alternatively, makes a gzip-ed **edit.htm** file for fs - -uncomment **#define EDFS** for this choice. Saves about 4k of program flash storage. -- **undo.bat:** Reverts **edit.htm** from C array header to file (still minified!) -- **update_ace.bat:** Updates **acefull.js.gz** file from latest GitHub Ace sources diff --git a/extras/do_ed_fs.bat b/extras/do_ed_fs.bat deleted file mode 100644 index c88b64669..000000000 --- a/extras/do_ed_fs.bat +++ /dev/null @@ -1,9 +0,0 @@ -copy ..\src\edit.htm edit_src.htm -call html-minifier-terser --collapse-whitespace --remove-comments --remove-optional-tags --remove-redundant-attributes --remove-script-type-attributes --minify-css true --minify-js true -o edit.htm edit_src.htm -"C:\Program Files\7-Zip\7z.exe" a -tgzip -mx9 edit.htm.gz edit.htm -copy edit.htm.gz ..\examples\SmartSwitch\data\edit_gz -copy edit.htm.gz ..\examples\ESP_AsyncFSBrowser\data\edit_gz -ehg edit.htm.gz PROGMEM -copy edit.htm.gz.h ..\src\edit.htm.gz.h -pause -del edit.htm edit.htm.gz edit.htm.gz.h edit_src.htm \ No newline at end of file diff --git a/extras/do_emb.bat b/extras/do_emb.bat deleted file mode 100644 index cb116dc5f..000000000 --- a/extras/do_emb.bat +++ /dev/null @@ -1,9 +0,0 @@ -copy ..\src\edit.htm edit_src.htm -call html-minifier-terser --collapse-whitespace --remove-comments --remove-optional-tags --remove-redundant-attributes --remove-script-type-attributes --minify-css true --minify-js true -o edit.htm edit_src.htm -"C:\Program Files\7-Zip\7z.exe" a -tgzip -mx9 edit.htm.gz edit.htm -del ..\examples\SmartSwitch\data\edit.htm -del ..\examples\ESP_AsyncFSBrowser\data\edit.htm -ehg edit.htm.gz PROGMEM -copy edit.htm.gz.h ..\src\edit.htm.gz.h -pause -del edit.htm edit.htm.gz edit.htm.gz.h edit_src.htm \ No newline at end of file diff --git a/extras/ehg.c b/extras/ehg.c deleted file mode 100644 index 0816c44de..000000000 --- a/extras/ehg.c +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Simple, but very fast converter of file to C++ array; written in old school C. - * ehg.c (ehg.exe) - * Based on https://github.com/TheLivingOne/bin2array/ - * by (C) Sergey A. Galin, 2019, sergey.galin@gmail.com, sergey.galin@yandex.ru - * and compiled with TynyCC https://bellard.org/tcc/ - * This file is a Public Domain. - */ - -#include -#include -#include - -char* replace_char(char* str, char find, char replace){ - char *current_pos = strchr(str,find); - for (char* p = current_pos; (current_pos = strchr(str, find)) != NULL; *current_pos = replace); - return str; -} - -int main(int argc, char * argv[]) -{ - if ((argc > 3)||(argc < 2)) { - printf("USAGE: %s [PROGMEM]\n", argv[0]); - return 1; - } - - const char * in = argv[1]; - const char * pr = argv[2]; - char pr_o[8] = " "; - - if (argv[2]) sprintf(pr_o, "%s", pr); - - // Hello stack overflow :) - char out_cpp[4096]; - char usname[4096]; - sprintf(usname, "%s", in); - sprintf(out_cpp, "%s.h", in); - - replace_char(usname,'.', '_'); - - printf("Input: %s, output: %s\n", in, out_cpp); - - // - // Working with the input file - // - FILE * fin = fopen(in, "rb"); - if (!fin) { - printf("Error opening input file!\n"); - return 2; - } - fseek(fin, 0, SEEK_END); - size_t size = (size_t)ftell(fin); - fseek(fin, 0, SEEK_SET); - printf("Input data size: %ld\n", (long)size); - - unsigned char * data = malloc(size); - if (fread(data, size, 1, fin) != 1) { - printf("Failed to read input file!\n"); - free(data); - fclose(fin); - return 2; - } - fclose(fin); - - unsigned char arr[] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'}; - unsigned char * text = malloc(size * 6); - unsigned char * out_ptr = text; - unsigned char * in_ptr = data; - for (size_t i = 1, col = 1; i <= size; i++, in_ptr++) { - unsigned char x = *in_ptr; - unsigned char y = (x & 0xF0) >> 4; - unsigned char z = (x & 0x0F); - - *out_ptr++ = '0'; - *out_ptr++ = 'x'; - - *out_ptr++ = arr[y]; - *out_ptr++ = arr[z]; - - if (i != size) { - *out_ptr++ = ','; - } - if (col == 20) { - *out_ptr++ = '\n'; - col = 1; - } else - col++; - } - free(data); - // *out_ptr = 0; not necessary as we're using fwrite() - - // - // Writing output file - // - - FILE * fout = fopen(out_cpp, "wb"); - if (!fout) { - printf("Error opening output file!\n"); - free(text); - return 2; - } - fprintf( - fout, - "\n//File: %s, Size: %ld\n" - "#define %s_len %ld\n" - "const uint8_t %s[] %s = {\n", - in, - (long)size, - usname, - (long)size, - usname, - pr_o); - if (fwrite(text, out_ptr - text, 1, fout) != 1) { - printf("Error writing output file!"); - free(text); - fclose(fout); - return 2; - } - fprintf(fout, "\n};\n"); - fclose(fout); - free(text); - return 0; -} - diff --git a/extras/ehg.exe b/extras/ehg.exe deleted file mode 100644 index 945f7a3942713850e106da8766db790b5d8a8f40..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4096 zcmeHKYitx%6u#RoIxY)a1s^|*Orcdspnw8`f)-_{%THFXZi}YXl#$$E zgyU*UIFU%2YO}5y8xv|Yp)OgmN{uHYdfm8jz8V>tYm6=TRE$W}%L0{SJ-0FD12Gl` zt>zx+s(@4=tPU}_Np+dCSwdbNXEZM|L|b$qUS=p{YBgh13H`lY1H@f_i;#7u-fn`v zU4ahk!nuxI2At~px=7dzgUXAW1Ol3;i{_RXOGI*O#wBjN{!-gUXnD6gClt znL=gY)jP=!a7AF(7<7Dq1b$m-beLMtxXVR!$Aj7o*w~ss)9JMpD+rYUR1g*%74$i6 zfR1WTyXrs^#%aX!+Hc&gqB#DNOXdcYipR&+3f!5Dsq)$Ycdvq9rU%Rhxl>Eh?7)R$ zk-KMxDW*!ruc$a86i$c|)?uHQKKp+!79ki6(UM}$ph<0!K1*`Av?*L#*regE@T&X>C%iJ_R* zTX3vPrM)2)vmjC~`wdQDHoqJ3+#LnZbF|5fo-z1y6T0CO)+SQ!7hIx z1c3ueE`J0Bfdg4&+j|GVx2xdIWe*QYGrfUa_A?mUR24`H4$8s*33{AFfBHFfovQkmipS4wZ_JWzHiP5iR=yWQCBd zNOlzNWa$vjfrAFS;_Su~DsQQKy@JlYm36?+rhe!qJ_He+y>y^IB|EQ8TgqKm48;jP z2WI%3$cI4QkdY&L4nD?EA_;dtp%AKAY&(yKWZE%1k99O2#P_ceOi{|+*T{6(B`aVc zcM6HiHLWfUF$8ymVkk<)gYQhJ9+rL{so}y4>q#YNkx`M(;Kq)3Ge*A=H8AMNYc6-2 zp*~znR9o65@iMsA%F;@Dj6G1}FCz1rV8QSu@31SR4hnK34?x1fm(;EYW(x6 z21|JcG0%LF2bX~DoL+g22 z7vV@Tn{~Ta0CD#+^;aMiytLi6?z(45auFoZ02iC@t!JBo`c8wO$&S@1`6V@eOJlP; zEzKKw8|^Gjadv}^rTLv4@ha3#%xg;IT{KvS)k3`5hU$9a%O&TMua7gc)FV0XiDs3Ml;h4BWb9~l%9wtHo&)jDN?mh zIH~v);-X_}J1g+_2$iIIdyAejLv7(iB&HkqA^9I~ Fe*mMgq@e%+ diff --git a/extras/rehg.c b/extras/rehg.c deleted file mode 100644 index a88861012..000000000 --- a/extras/rehg.c +++ /dev/null @@ -1,101 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2014-2015 Anthony Birkett - * - * 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: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * 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. - */ - -/* - * rehg.c (rehg.exe): Tool to reverse C-code array to file converted by ehg.exe - * Based on https://github.com/birkett/cbintools/tree/master/c2bin - * and compiled with TynyCC https://bellard.org/tcc/ - */ - -#include -#include -#include - -#define BUFFER_SIZE 500 - -int main(int argc, char *argv[]) -{ - FILE *inputFile = NULL; - FILE *outputFile = NULL; - char sBuffer[BUFFER_SIZE]; - char *pch; - char *newline, *endBracket; - int i; - - if (argc != 3) - { - printf("%s %s %s\n", "Usage:", argv[0], "
"); - return 1; - } - - inputFile = fopen(argv[1], "r"); - - if (inputFile == NULL) - { - printf("%s %s\n", "Unable to open input header:", argv[1]); - return 1; - } - - outputFile = fopen(argv[2], "wb"); - - if (outputFile == NULL) - { - printf("%s %s\n", "Unable to open output file:", argv[2]); - return 1; - } - - // Skip the first 4 lines. - for (i = 0; i < 4; i++) - { - fgets(sBuffer, BUFFER_SIZE, inputFile); - } - - // Get the contents of each line of the array. - while (fgets(sBuffer, BUFFER_SIZE, inputFile)) - { - // Get rid of the new line character. - newline = strchr(sBuffer, '\n'); - if (newline) - { - *newline = 0; - } - - // Skip this line if its the closing "};". - endBracket = strchr(sBuffer, '}'); - if (endBracket) - { - continue; - } - - // Write out each character. - pch = strtok(sBuffer, ","); - while (pch != NULL) - { - fprintf(outputFile, "%c", strtol(pch, NULL, 0)); // autodetect - pch = strtok(NULL, ","); - } - } - - return 0; -} diff --git a/extras/rehg.exe b/extras/rehg.exe deleted file mode 100644 index cec482fe7d5c3d892dd43747973ac8bbbd6f5919..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2560 zcmeHJU1%It6uz5mWQ?1i+WO#wIKc#eh{58Elv-Bo_(y^h+kl8Nne0xI#m&q*J4xe1 zrD411Ff0W1*&+(&L9t?mi4>Z$d9aW|!9FMkj1XbgMDU^DBCF$f&dek!wgsUNK6u%4 zzBA{1_d93q%(6T3%A#l&LZo3~D1;BBm1TcxcM9e1`@ilM=kC1R=ck4*_Z^=ul;x6b zP1*X4oYPIya^wj^wr5SbV9G~dJSNXrd1I)ntFu3rRuv(JQ*GBZ+7LbMcctzS0v{2V zvUelyg~>3Qj$+hkZdwV7$8drCALD}Wi;2Xg4U9WLNpVUR;vtT1uUmrdbGMKja*TNg z^>G@U=Gt?w$u=3~p}g+sl%R7!f>8qQSy>@g_FVp}aLoOAVLJoyMSk+G(u%R^DN?1` z-gEj9=y^(Jd7qpWqn2WjwqG!p0Bi&>Y0tsgM2>R-b~wN_346^3eXrHyVjvvu{KrLUqA&2;)l zsQI06I~&h%RdTB>Zcd(=UEG&0ml26~B>&{zZPUrNCT}Cp+d4pM%!gs+V$d-F&K6(x*jzR$JVM&*1IB{;^uIKRxO;78>+ruBIL(c#_=7?T0T`Q|^Yl z=1Jjr+Ecdc!S8r>p72CH_!W^FY_X?z00&+7j3D@)GoK@ag*bd`e^$H)YkY*nm{;tV zYDfDst|AVuxJo+zA@N*A^3Q_fDjEM{#$Ku(s3}sOwu#s3A{b~fFjCw9*MIi}2FfyjI>lI7pE3@K!_$VIH|!(wVQbbY z%{oVfEfR*QPZSN=v1F@c&@Vd5azsBQPE6c{7Rktyg(B1k#Xt^jcl{>s#!vJKLBE?f zT2G@k3_A{c6=uLp*a_GI>|NLy*b?ju*m>9*>|5ARum+6Q?b4Yk&*f}qC|@i>v}6}d zXA;3A9Sq@=;go@8$IeaLQQ%mwCjsr5+}WgQWy8_*Qb}{(EEyixt2kMr3r)AD za!D{pfnm-SY>WD68XC>$1rr?VXUrGqPlfh!uH-yZC^`o9){?9-pEF91Hm#faqG3Od Hk`R9bQN2Zk diff --git a/extras/tmp1/placeholder b/extras/tmp1/placeholder deleted file mode 100644 index e69de29bb..000000000 diff --git a/extras/undo.bat b/extras/undo.bat deleted file mode 100644 index 3c36e3574..000000000 --- a/extras/undo.bat +++ /dev/null @@ -1,4 +0,0 @@ -copy ..\src\edit.htm.gz.h edit.htm.gz.h -rehg edit.htm.gz.h edit.htm.gz -"C:\Program Files\7-Zip\7z.exe" e -tgzip edit.htm.gz -pause diff --git a/extras/update_ace.bat b/extras/update_ace.bat deleted file mode 100644 index 76e1c7cde..000000000 --- a/extras/update_ace.bat +++ /dev/null @@ -1,44 +0,0 @@ -REM https://www.npmjs.com/package/github-files-fetcher -REM npm install -g github-files-fetcher -REM fetcher --url=resource_url --out=output_directory - -call fetcher --url="https://github.com/ajaxorg/ace-builds/blob/master/src-min-noconflict/ace.js" --out=tmp1 -call fetcher --url="https://github.com/ajaxorg/ace-builds/blob/master/src-min-noconflict/mode-html.js" --out=tmp1 -call fetcher --url="https://github.com/ajaxorg/ace-builds/blob/master/src-min-noconflict/mode-json.js" --out=tmp1 -call fetcher --url="https://github.com/ajaxorg/ace-builds/blob/master/src-min-noconflict/theme-monokai.js" --out=tmp1 -call fetcher --url="https://github.com/ajaxorg/ace-builds/blob/master/src-min-noconflict/ext-searchbox.js" --out=tmp1 - -REM if you don't need worker(s), modify line#446 of edit.htm .setUseWorker(!0) to (!1) (true to false) -REM and do not take and include them below -call fetcher --url="https://github.com/ajaxorg/ace-builds/blob/master/src-min-noconflict/worker-html.js" --out=tmp1 -call fetcher --url="https://github.com/ajaxorg/ace-builds/blob/master/src-min-noconflict/worker-css.js" --out=tmp1 -call fetcher --url="https://github.com/ajaxorg/ace-builds/blob/master/src-min-noconflict/worker-javascript.js" --out=tmp1 -call fetcher --url="https://github.com/ajaxorg/ace-builds/blob/master/src-min-noconflict/worker-json.js" --out=tmp1 - -cd tmp1 -type ace.js mode-html.js mode-json.js theme-monokai.js ext-searchbox.js > acefull.js -"C:\Program Files\7-Zip\7z.exe" a -tgzip -mx9 acefull.js.gz acefull.js -"C:\Program Files\7-Zip\7z.exe" a -tgzip -mx9 worker-html.js.gz worker-html.js -"C:\Program Files\7-Zip\7z.exe" a -tgzip -mx9 worker-javascript.js.gz worker-javascript.js -"C:\Program Files\7-Zip\7z.exe" a -tgzip -mx9 worker-json.js.gz worker-json.js -"C:\Program Files\7-Zip\7z.exe" a -tgzip -mx9 worker-css.js.gz worker-css.js - -REM update SmartSwitch /data: -pause -copy acefull.js.gz ..\..\examples\SmartSwitch\data\acefull.js.gz -copy worker-html.js.gz ..\..\examples\SmartSwitch\data\worker-html.js.gz -copy worker-javascript.js.gz ..\..\examples\SmartSwitch\data\worker-javascript.js.gz -copy worker-json.js.gz ..\..\examples\SmartSwitch\data\worker-json.js.gz -copy worker-css.js.gz ..\..\examples\SmartSwitch\data\worker-css.js.gz - -REM update ESP_AsyncFSBrowser /data: -pause -copy acefull.js.gz ..\..\examples\ESP_AsyncFSBrowser\data\acefull.js.gz -copy worker-html.js.gz ..\..\examples\ESP_AsyncFSBrowser\data\worker-html.js.gz -copy worker-javascript.js.gz ..\..\examples\ESP_AsyncFSBrowser\data\worker-javascript.js.gz -copy worker-json.js.gz ..\..\examples\ESP_AsyncFSBrowser\data\worker-json.js.gz -copy worker-css.js.gz ..\..\examples\ESP_AsyncFSBrowser\data\worker-css.js.gz - -REM delete temporary stuff -pause -del *.js *.gz diff --git a/library.json b/library.json index c5cfbbdf6..5aab55ded 100644 --- a/library.json +++ b/library.json @@ -10,7 +10,7 @@ "type": "git", "url": "https://github.com/mathieucarbou/ESPAsyncWebServer.git" }, - "version": "2.0.0", + "version": "2.1.0", "license": "LGPL-3.0", "frameworks": "arduino", "platforms": [ diff --git a/library.properties b/library.properties index 0d3959e84..cb58f1bb9 100644 --- a/library.properties +++ b/library.properties @@ -1,7 +1,7 @@ name=ESP Async WebServer -version=2.0.0 +version=2.1.0 author=Me-No-Dev -maintainer=lorol +maintainer=mathieucarbou sentence=Async Web Server for ESP8266 and ESP31B paragraph=Async Web Server for ESP8266 and ESP31B category=Other From 8ad2ac9641b45b521437b859029420f588b29c26 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Thu, 18 Jan 2024 11:21:34 +0100 Subject: [PATCH 121/551] Update dependencies to allow fix a more recent version --- library.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library.json b/library.json index 5aab55ded..5f25328f3 100644 --- a/library.json +++ b/library.json @@ -21,13 +21,13 @@ { "owner": "esphome", "name": "ESPAsyncTCP-esphome", - "version": "2.0.0", + "version": ">=2.0.0", "platforms": "espressif8266" }, { "owner": "esphome", "name": "AsyncTCP-esphome", - "version": "2.0.1", + "version": ">=2.0.1", "platforms": "espressif32" }, { From 35727fd8636a1f67a9b3563970c7c4742cf85070 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Thu, 18 Jan 2024 11:22:59 +0100 Subject: [PATCH 122/551] v2.1.1 --- library.json | 2 +- library.properties | 2 +- src/ESPAsyncWebServer.h | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/library.json b/library.json index 5f25328f3..bb0b2e3db 100644 --- a/library.json +++ b/library.json @@ -10,7 +10,7 @@ "type": "git", "url": "https://github.com/mathieucarbou/ESPAsyncWebServer.git" }, - "version": "2.1.0", + "version": "2.1.1", "license": "LGPL-3.0", "frameworks": "arduino", "platforms": [ diff --git a/library.properties b/library.properties index cb58f1bb9..f6e858bfc 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=ESP Async WebServer -version=2.1.0 +version=2.1.1 author=Me-No-Dev maintainer=mathieucarbou sentence=Async Web Server for ESP8266 and ESP31B diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index 23b14c424..add877842 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -40,10 +40,10 @@ #error Platform not supported #endif -#define ASYNCWEBSERVER_VERSION "2.1.0" +#define ASYNCWEBSERVER_VERSION "2.1.1" #define ASYNCWEBSERVER_VERSION_MAJOR 2 #define ASYNCWEBSERVER_VERSION_MINOR 1 -#define ASYNCWEBSERVER_VERSION_REVISION 0 +#define ASYNCWEBSERVER_VERSION_REVISION 1 #define ASYNCWEBSERVER_FORK_mathieucarbou #ifdef ASYNCWEBSERVER_REGEX From ad0c8e8dd4d2302f1438eef17e55a8178622004b Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Sun, 21 Jan 2024 18:02:52 +0100 Subject: [PATCH 123/551] Fixed library.properties --- library.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library.properties b/library.properties index f6e858bfc..7b991c21a 100644 --- a/library.properties +++ b/library.properties @@ -1,9 +1,9 @@ name=ESP Async WebServer version=2.1.1 author=Me-No-Dev -maintainer=mathieucarbou +maintainer=Mathieu Carbou sentence=Async Web Server for ESP8266 and ESP31B paragraph=Async Web Server for ESP8266 and ESP31B category=Other -urlhttps://github.com/mathieucarbou/ESPAsyncWebServer +url=https://github.com/mathieucarbou/ESPAsyncWebServer architectures=* From 6cdcfb0f1ac9337d463145044bee4af89cf3f69e Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Sun, 21 Jan 2024 18:46:42 +0100 Subject: [PATCH 124/551] Prepare v2.1.2 --- library.json | 2 +- library.properties | 2 +- src/ESPAsyncWebServer.h | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/library.json b/library.json index bb0b2e3db..a5a851e5f 100644 --- a/library.json +++ b/library.json @@ -10,7 +10,7 @@ "type": "git", "url": "https://github.com/mathieucarbou/ESPAsyncWebServer.git" }, - "version": "2.1.1", + "version": "2.1.2", "license": "LGPL-3.0", "frameworks": "arduino", "platforms": [ diff --git a/library.properties b/library.properties index 7b991c21a..419f3362c 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=ESP Async WebServer -version=2.1.1 +version=2.1.2 author=Me-No-Dev maintainer=Mathieu Carbou sentence=Async Web Server for ESP8266 and ESP31B diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index add877842..98928a671 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -40,10 +40,10 @@ #error Platform not supported #endif -#define ASYNCWEBSERVER_VERSION "2.1.1" +#define ASYNCWEBSERVER_VERSION "2.1.2" #define ASYNCWEBSERVER_VERSION_MAJOR 2 #define ASYNCWEBSERVER_VERSION_MINOR 1 -#define ASYNCWEBSERVER_VERSION_REVISION 1 +#define ASYNCWEBSERVER_VERSION_REVISION 2 #define ASYNCWEBSERVER_FORK_mathieucarbou #ifdef ASYNCWEBSERVER_REGEX From 1231715c4921a0389bd054033144e97ddfd49828 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Mon, 22 Jan 2024 21:50:22 +0100 Subject: [PATCH 125/551] Rework CI, library descriptor in preparation of deployment --- .clang-format | 16 + .github/FUNDING.yml | 13 + .github/dependabot.yml | 20 + .github/workflows/ci.yml | 92 ++ .github/workflows/dependabot.yml | 19 + .gitignore | 6 +- .travis.yml | 46 - .vscode/settings.json | 10 + CMakeLists.txt | 17 - LICENSE | 165 +++ README.md | 1628 +--------------------- _config.yml | 1 - component.mk | 3 - examples/CaptivePortal/CaptivePortal.ino | 41 + examples/SimpleServer/SimpleServer.ino | 41 + keywords.txt | 3 - library.json | 34 +- library.properties | 8 +- platformio.ini | 23 + src/AsyncJson.h | 209 +-- src/SPIFFSEditor.cpp | 342 ----- src/SPIFFSEditor.h | 25 - src/edit.htm | 581 -------- src/edit.htm.gz.h | 231 --- 24 files changed, 587 insertions(+), 2987 deletions(-) create mode 100644 .clang-format create mode 100644 .github/FUNDING.yml create mode 100644 .github/dependabot.yml create mode 100644 .github/workflows/ci.yml create mode 100644 .github/workflows/dependabot.yml delete mode 100644 .travis.yml create mode 100644 .vscode/settings.json delete mode 100644 CMakeLists.txt create mode 100644 LICENSE delete mode 100644 _config.yml delete mode 100644 component.mk create mode 100644 examples/CaptivePortal/CaptivePortal.ino create mode 100644 examples/SimpleServer/SimpleServer.ino delete mode 100755 keywords.txt create mode 100644 platformio.ini delete mode 100644 src/SPIFFSEditor.cpp delete mode 100644 src/SPIFFSEditor.h delete mode 100644 src/edit.htm delete mode 100644 src/edit.htm.gz.h diff --git a/.clang-format b/.clang-format new file mode 100644 index 000000000..a0498d9ce --- /dev/null +++ b/.clang-format @@ -0,0 +1,16 @@ +Language: Cpp +BasedOnStyle: LLVM + +AccessModifierOffset: -2 +AllowShortIfStatementsOnASingleLine: false +ColumnLimit: 0 +ContinuationIndentWidth: 2 +FixNamespaceComments: false +IndentAccessModifiers: true +IndentCaseLabels: true +IndentWidth: 2 +NamespaceIndentation: All +PointerAlignment: Left +ReferenceAlignment: Left +TabWidth: 2 +UseTab: Never \ No newline at end of file diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 000000000..e411f9b40 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,13 @@ +# These are supported funding model platforms + +github: mathieucarbou +# patreon: # Replace with a single Patreon username +# open_collective: # Replace with a single Open Collective username +# ko_fi: # Replace with a single Ko-fi username +# tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel +# community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry +# liberapay: # Replace with a single Liberapay username +# issuehunt: # Replace with a single IssueHunt username +# otechie: # Replace with a single Otechie username +# lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry +custom: https://paypal.me/mathieucarboufr diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 000000000..bd654c27b --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,20 @@ +# 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 all configuration options: +# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates + +version: 2 +updates: + - package-ecosystem: "gitsubmodule" + directory: "/" + schedule: + interval: "daily" + reviewers: + - "mathieucarbou" + + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "daily" + reviewers: + - "mathieucarbou" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 000000000..3c2a08c2b --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,92 @@ +# yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json + +name: Continuous Integration + +on: + workflow_dispatch: + push: + pull_request: + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +jobs: + arduino: + name: Arduino + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + include: + - core: esp32:esp32 + board: esp32:esp32:esp32 + eeprom: true + softwareserial: false + index_url: https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Install arduino-cli + run: curl -fsSL https://raw.githubusercontent.com/arduino/arduino-cli/master/install.sh | BINDIR=/usr/local/bin sh + + - name: Update core index + run: arduino-cli core update-index --additional-urls "${{ matrix.index_url }}" + + - name: Install core + run: arduino-cli core install --additional-urls "${{ matrix.index_url }}" ${{ matrix.core }} + + - name: Install ArduinoJson + run: arduino-cli lib install ArduinoJson@7.0.2 + + - name: Install AsyncTCP-esphome + run: ARDUINO_LIBRARY_ENABLE_UNSAFE_INSTALL=true arduino-cli lib install --git-url https://github.com/mathieucarbou/esphome-AsyncTCP#v2.1.1 + + - name: Build CaptivePortal + run: arduino-cli compile --library . --warnings all -b ${{ matrix.board }} "examples/CaptivePortal/CaptivePortal.ino" + + - name: Build SimpleServer + run: arduino-cli compile --library . --warnings all -b ${{ matrix.board }} "examples/SimpleServer/SimpleServer.ino" + + platformio: + name: PlatformIO + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + include: + - platform: espressif32 + board: esp32dev + eeprom: true + softwareserial: false + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Set up cache + uses: actions/cache@v4 + with: + path: | + ~/.platformio + ~/.cache/pip + key: ${{ runner.os }}-platformio + + - name: Set up Python 3.x + uses: actions/setup-python@v5 + with: + python-version: '3.x' + + - name: Install PlatformIO + run: pip install platformio + + - name: Install platform "${{ matrix.platform }}" + run: platformio platform install ${{ matrix.platform }} + + - name: Build CaptivePortal + run: platformio ci "examples/CaptivePortal/CaptivePortal.ino" -l '.' -b ${{ matrix.board }} + + - name: Build SimpleServer + run: platformio ci "examples/SimpleServer/SimpleServer.ino" -l '.' -b ${{ matrix.board }} diff --git a/.github/workflows/dependabot.yml b/.github/workflows/dependabot.yml new file mode 100644 index 000000000..da098fd7a --- /dev/null +++ b/.github/workflows/dependabot.yml @@ -0,0 +1,19 @@ +name: PlatformIO Dependabot + +on: + workflow_dispatch: + schedule: + # Runs every day at 01:00 + - cron: "0 1 * * *" + +jobs: + dependabot: + runs-on: ubuntu-latest + name: PlatformIO Dependabot + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: run PlatformIO Dependabot + uses: peterus/platformio_dependabot@v1 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.gitignore b/.gitignore index a0f0e5386..4ac15a42d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,6 @@ -.vscode .DS_Store +.lh +/.pio +/.vscode/* +!/.vscode/settings.json +/logs diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index e1b703527..000000000 --- a/.travis.yml +++ /dev/null @@ -1,46 +0,0 @@ -sudo: false - -language: python - -os: - - linux - -git: - depth: false - -stages: - - build - -jobs: - include: - - - name: "Build Arduino ESP32" - if: tag IS blank AND (type = pull_request OR (type = push AND branch = master)) - stage: build - script: bash $TRAVIS_BUILD_DIR/.github/scripts/on-push.sh esp32 - - - name: "Build Arduino ESP8266" - if: tag IS blank AND (type = pull_request OR (type = push AND branch = master)) - stage: build - script: bash $TRAVIS_BUILD_DIR/.github/scripts/on-push.sh esp8266 - - - name: "Build Platformio ESP32" - if: tag IS blank AND (type = pull_request OR (type = push AND branch = master)) - stage: build - script: bash $TRAVIS_BUILD_DIR/.github/scripts/on-push.sh esp32 1 1 - - - name: "Build Platformio ESP8266" - if: tag IS blank AND (type = pull_request OR (type = push AND branch = master)) - stage: build - script: bash $TRAVIS_BUILD_DIR/.github/scripts/on-push.sh esp8266 1 1 - -notifications: - email: - on_success: change - on_failure: change - webhooks: - urls: - - https://webhooks.gitter.im/e/60e65d0c78ea0a920347 - on_success: change # options: [always|never|change] default: always - on_failure: always # options: [always|never|change] default: always - on_start: never # options: [always|never|change] default: always diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 000000000..06877f577 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,10 @@ +{ + "C_Cpp.clang_format_fallbackStyle": "{ BasedOnStyle: LLVM, UseTab: Never, IndentWidth: 2, TabWidth: 2, AllowShortIfStatementsOnASingleLine: false, IndentCaseLabels: true, ColumnLimit: 0, AccessModifierOffset: -2, NamespaceIndentation: All, FixNamespaceComments: false, IndentAccessModifiers: true, PointerAlignment: Left, ReferenceAlignment: Left, ContinuationIndentWidth: 2}", + "files.exclude": { + "**/.lh": true + }, + "cSpell.words": [ + "YASOLR" + ], + "cmake.configureOnOpen": false +} \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt deleted file mode 100644 index 64292eca4..000000000 --- a/CMakeLists.txt +++ /dev/null @@ -1,17 +0,0 @@ -set(COMPONENT_SRCDIRS - "src" -) - -set(COMPONENT_ADD_INCLUDEDIRS - "src" -) - -set(COMPONENT_REQUIRES - "arduino-esp32" - "AsyncTCP" -) - -register_component() - -target_compile_definitions(${COMPONENT_TARGET} PUBLIC -DESP32) -target_compile_options(${COMPONENT_TARGET} PRIVATE -fno-rtti) diff --git a/LICENSE b/LICENSE new file mode 100644 index 000000000..153d416dc --- /dev/null +++ b/LICENSE @@ -0,0 +1,165 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. \ No newline at end of file diff --git a/README.md b/README.md index fd2c61091..91cf7cca3 100644 --- a/README.md +++ b/README.md @@ -1,1621 +1,19 @@ -# In this fork -- SPIFFSEditor modifications -- Added [extras](https://github.com/mathieucarbou/ESPAsyncWebServer/tree/master/extras) folder with (Win) tools for re-packing, editing, updating and compressing html to binary arrays embedded to source -- Added a [SmartSwitch](https://github.com/mathieucarbou/ESPAsyncWebServer/tree/master/examples/SmartSwitch) example to test code features -- Applied the memory optimizations from [sascha432](https://github.com/sascha432/ESPAsyncWebServer) fork -- Cookie Authentication including on Websocket part, based on [ayushsharma82](https://github.com/me-no-dev/ESPAsyncWebServer/pull/684) PR, new functions added: - - For Websocket: ```void handleHandshake(AwsHandshakeHandler handler) ``` - - For EventSource: ```void authorizeConnect(ArAuthorizeConnectHandler cb)``` -- [Additions to this README.md from jendakol' PR](https://github.com/me-no-dev/ESPAsyncWebServer/pull/770) - - [Respond with file content using a callback and extra headers](#respond-with-file-content-using-a-callback-and-extra-headers) - - [Serving static files by custom handling](#serving-static-files-by-custom-handling) - - Added LittleFS choice for both [esp8266](https://github.com/esp8266/Arduino/tree/master/libraries/LittleFS) / [esp32](https://github.com/lorol/LITTLEFS) , and FatFS tests for esp32 see [SmartSwitch](https://github.com/lorol/ESPAsyncWebServer/blob/master/examples/SmartSwitch/SmartSwitch.ino#L16 ) ------------------------------------------------------------------------------------------- +# ESP Async WebServer -# ESPAsyncWebServer -[![Build Status](https://travis-ci.org/me-no-dev/ESPAsyncWebServer.svg?branch=master)](https://travis-ci.org/me-no-dev/ESPAsyncWebServer) ![](https://github.com/me-no-dev/ESPAsyncWebServer/workflows/ESP%20Async%20Web%20Server%20CI/badge.svg) [![Codacy Badge](https://api.codacy.com/project/badge/Grade/395dd42cfc674e6ca2e326af3af80ffc)](https://www.codacy.com/manual/me-no-dev/ESPAsyncWebServer?utm_source=github.com&utm_medium=referral&utm_content=me-no-dev/ESPAsyncWebServer&utm_campaign=Badge_Grade) +[![License: LGPL 3.0](https://img.shields.io/badge/License-LGPL%203.0-yellow.svg)](https://opensource.org/license/lgpl-3-0/) +[![Continuous Integration](https://github.com/mathieucarbou/ESPAsyncWebServer/actions/workflows/ci.yml/badge.svg)](https://github.com/mathieucarbou/ESPAsyncWebServer/actions/workflows/ci.yml) +[![PlatformIO Registry](https://badges.registry.platformio.org/packages/mathieucarbou/library/ESP Async WebServer.svg)](https://registry.platformio.org/libraries/mathieucarbou/ESP Async WebServer) -For help and support [![Join the chat at https://gitter.im/me-no-dev/ESPAsyncWebServer](https://badges.gitter.im/me-no-dev/ESPAsyncWebServer.svg)](https://gitter.im/me-no-dev/ESPAsyncWebServer?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) +Async Web Server for ESP31B -Async HTTP and WebSocket Server for ESP8266 Arduino +This fork is based on https://github.com/yubox-node-org/ESPAsyncWebServer and includes all the concurrency fixes. -For ESP8266 it requires [ESPAsyncTCP](https://github.com/me-no-dev/ESPAsyncTCP) -To use this library you might need to have the latest git versions of [ESP8266](https://github.com/esp8266/Arduino) Arduino Core +## Changes -For ESP32 it requires [AsyncTCP](https://github.com/me-no-dev/AsyncTCP) to work -To use this library you might need to have the latest git versions of [ESP32](https://github.com/espressif/arduino-esp32) Arduino Core +- SPIFFSEditor is removed +- Arduino Json 7 compatibility +- Deployed in PlatformIO registry and Arduino IDE library manager +- CI -## Table of contents -- [ESPAsyncWebServer](#espasyncwebserver) - - [Table of contents](#table-of-contents) - - [Installation](#installation) - - [Using PlatformIO](#using-platformio) - - [Why should you care](#why-should-you-care) - - [Important things to remember](#important-things-to-remember) - - [Principles of operation](#principles-of-operation) - - [The Async Web server](#the-async-web-server) - - [Request Life Cycle](#request-life-cycle) - - [Rewrites and how do they work](#rewrites-and-how-do-they-work) - - [Handlers and how do they work](#handlers-and-how-do-they-work) - - [Responses and how do they work](#responses-and-how-do-they-work) - - [Template processing](#template-processing) - - [Libraries and projects that use AsyncWebServer](#libraries-and-projects-that-use-asyncwebserver) - - [Request Variables](#request-variables) - - [Common Variables](#common-variables) - - [Headers](#headers) - - [GET, POST and FILE parameters](#get-post-and-file-parameters) - - [FILE Upload handling](#file-upload-handling) - - [Body data handling](#body-data-handling) - - [JSON body handling with ArduinoJson](#json-body-handling-with-arduinojson) - - [Responses](#responses) - - [Redirect to another URL](#redirect-to-another-url) - - [Basic response with HTTP Code](#basic-response-with-http-code) - - [Basic response with HTTP Code and extra headers](#basic-response-with-http-code-and-extra-headers) - - [Basic response with string content](#basic-response-with-string-content) - - [Basic response with string content and extra headers](#basic-response-with-string-content-and-extra-headers) - - [Send large webpage from PROGMEM](#send-large-webpage-from-progmem) - - [Send large webpage from PROGMEM and extra headers](#send-large-webpage-from-progmem-and-extra-headers) - - [Send large webpage from PROGMEM containing templates](#send-large-webpage-from-progmem-containing-templates) - - [Send large webpage from PROGMEM containing templates and extra headers](#send-large-webpage-from-progmem-containing-templates-and-extra-headers) - - [Send binary content from PROGMEM](#send-binary-content-from-progmem) - - [Respond with content coming from a Stream](#respond-with-content-coming-from-a-stream) - - [Respond with content coming from a Stream and extra headers](#respond-with-content-coming-from-a-stream-and-extra-headers) - - [Respond with content coming from a Stream containing templates](#respond-with-content-coming-from-a-stream-containing-templates) - - [Respond with content coming from a Stream containing templates and extra headers](#respond-with-content-coming-from-a-stream-containing-templates-and-extra-headers) - - [Respond with content coming from a File](#respond-with-content-coming-from-a-file) - - [Respond with content coming from a File and extra headers](#respond-with-content-coming-from-a-file-and-extra-headers) - - [Respond with content coming from a File containing templates](#respond-with-content-coming-from-a-file-containing-templates) - - [Respond with content using a callback](#respond-with-content-using-a-callback) - - [Respond with content using a callback and extra headers](#respond-with-content-using-a-callback-and-extra-headers) - - [Respond with file content using a callback and extra headers](#respond-with-file-content-using-a-callback-and-extra-headers) - - [Respond with content using a callback containing templates](#respond-with-content-using-a-callback-containing-templates) - - [Respond with content using a callback containing templates and extra headers](#respond-with-content-using-a-callback-containing-templates-and-extra-headers) - - [Chunked Response](#chunked-response) - - [Chunked Response containing templates](#chunked-response-containing-templates) - - [Print to response](#print-to-response) - - [ArduinoJson Basic Response](#arduinojson-basic-response) - - [ArduinoJson Advanced Response](#arduinojson-advanced-response) - - [Serving static files](#serving-static-files) - - [Serving specific file by name](#serving-specific-file-by-name) - - [Serving files in directory](#serving-files-in-directory) - - [Serving static files with authentication](#serving-static-files-with-authentication) - - [Specifying Cache-Control header](#specifying-cache-control-header) - - [Specifying Date-Modified header](#specifying-date-modified-header) - - [Specifying Template Processor callback](#specifying-template-processor-callback) - - [Serving static files by custom handling](#serving-static-files-by-custom-handling) - - [Param Rewrite With Matching](#param-rewrite-with-matching) - - [Using filters](#using-filters) - - [Serve different site files in AP mode](#serve-different-site-files-in-ap-mode) - - [Rewrite to different index on AP](#rewrite-to-different-index-on-ap) - - [Serving different hosts](#serving-different-hosts) - - [Determine interface inside callbacks](#determine-interface-inside-callbacks) - - [Bad Responses](#bad-responses) - - [Respond with content using a callback without content length to HTTP/1.0 clients](#respond-with-content-using-a-callback-without-content-length-to-http10-clients) - - [Async WebSocket Plugin](#async-websocket-plugin) - - [Async WebSocket Event](#async-websocket-event) - - [Methods for sending data to a socket client](#methods-for-sending-data-to-a-socket-client) - - [Direct access to web socket message buffer](#direct-access-to-web-socket-message-buffer) - - [Limiting the number of web socket clients](#limiting-the-number-of-web-socket-clients) - - [Async Event Source Plugin](#async-event-source-plugin) - - [Setup Event Source on the server](#setup-event-source-on-the-server) - - [Setup Event Source in the browser](#setup-event-source-in-the-browser) - - [Scanning for available WiFi Networks](#scanning-for-available-wifi-networks) - - [Remove handlers and rewrites](#remove-handlers-and-rewrites) - - [Setting up the server](#setting-up-the-server) - - [Setup global and class functions as request handlers](#setup-global-and-class-functions-as-request-handlers) - - [Methods for controlling websocket connections](#methods-for-controlling-websocket-connections) - - [Adding Default Headers](#adding-default-headers) - - [Path variable](#path-variable) - -## Installation - -### Using PlatformIO - -[PlatformIO](http://platformio.org) is an open source ecosystem for IoT development with cross platform build system, library manager and full support for Espressif ESP8266/ESP32 development. It works on the popular host OS: Mac OS X, Windows, Linux 32/64, Linux ARM (like Raspberry Pi, BeagleBone, CubieBoard). - -1. Install [PlatformIO IDE](http://platformio.org/platformio-ide) -2. Create new project using "PlatformIO Home > New Project" -3. Update dev/platform to staging version: - - [Instruction for Espressif 8266](http://docs.platformio.org/en/latest/platforms/espressif8266.html#using-arduino-framework-with-staging-version) - - [Instruction for Espressif 32](http://docs.platformio.org/en/latest/platforms/espressif32.html#using-arduino-framework-with-staging-version) - 4. Add "ESP Async WebServer" to project using [Project Configuration File `platformio.ini`](http://docs.platformio.org/page/projectconf.html) and [lib_deps](http://docs.platformio.org/page/projectconf/section_env_library.html#lib-deps) option: - -```ini -[env:myboard] -platform = espressif... -board = ... -framework = arduino - -# using the latest stable version -lib_deps = ESP Async WebServer - -# or using GIT Url (the latest development version) -lib_deps = https://github.com/me-no-dev/ESPAsyncWebServer.git -``` - 5. Happy coding with PlatformIO! - -## Why should you care -- Using asynchronous network means that you can handle more than one connection at the same time -- You are called once the request is ready and parsed -- When you send the response, you are immediately ready to handle other connections - while the server is taking care of sending the response in the background -- Speed is OMG -- Easy to use API, HTTP Basic and Digest MD5 Authentication (default), ChunkedResponse -- Easily extendible to handle any type of content -- Supports Continue 100 -- Async WebSocket plugin offering different locations without extra servers or ports -- Async EventSource (Server-Sent Events) plugin to send events to the browser -- URL Rewrite plugin for conditional and permanent url rewrites -- ServeStatic plugin that supports cache, Last-Modified, default index and more -- Simple template processing engine to handle templates - -## Important things to remember -- This is fully asynchronous server and as such does not run on the loop thread. -- You can not use yield or delay or any function that uses them inside the callbacks -- The server is smart enough to know when to close the connection and free resources -- You can not send more than one response to a single request - -## Principles of operation - -### The Async Web server -- Listens for connections -- Wraps the new clients into ```Request``` -- Keeps track of clients and cleans memory -- Manages ```Rewrites``` and apply them on the request url -- Manages ```Handlers``` and attaches them to Requests - -### Request Life Cycle -- TCP connection is received by the server -- The connection is wrapped inside ```Request``` object -- When the request head is received (type, url, get params, http version and host), - the server goes through all ```Rewrites``` (in the order they were added) to rewrite the url and inject query parameters, - next, it goes through all attached ```Handlers```(in the order they were added) trying to find one - that ```canHandle``` the given request. If none are found, the default(catch-all) handler is attached. -- The rest of the request is received, calling the ```handleUpload``` or ```handleBody``` methods of the ```Handler``` if they are needed (POST+File/Body) -- When the whole request is parsed, the result is given to the ```handleRequest``` method of the ```Handler``` and is ready to be responded to -- In the ```handleRequest``` method, to the ```Request``` is attached a ```Response``` object (see below) that will serve the response data back to the client -- When the ```Response``` is sent, the client is closed and freed from the memory - -### Rewrites and how do they work -- The ```Rewrites``` are used to rewrite the request url and/or inject get parameters for a specific request url path. -- All ```Rewrites``` are evaluated on the request in the order they have been added to the server. -- The ```Rewrite``` will change the request url only if the request url (excluding get parameters) is fully match - the rewrite url, and when the optional ```Filter``` callback return true. -- Setting a ```Filter``` to the ```Rewrite``` enables to control when to apply the rewrite, decision can be based on - request url, http version, request host/port/target host, get parameters or the request client's localIP or remoteIP. -- Two filter callbacks are provided: ```ON_AP_FILTER``` to execute the rewrite when request is made to the AP interface, - ```ON_STA_FILTER``` to execute the rewrite when request is made to the STA interface. -- The ```Rewrite``` can specify a target url with optional get parameters, e.g. ```/to-url?with=params``` - -### Handlers and how do they work -- The ```Handlers``` are used for executing specific actions to particular requests -- One ```Handler``` instance can be attached to any request and lives together with the server -- Setting a ```Filter``` to the ```Handler``` enables to control when to apply the handler, decision can be based on - request url, http version, request host/port/target host, get parameters or the request client's localIP or remoteIP. -- Two filter callbacks are provided: ```ON_AP_FILTER``` to execute the rewrite when request is made to the AP interface, - ```ON_STA_FILTER``` to execute the rewrite when request is made to the STA interface. -- The ```canHandle``` method is used for handler specific control on whether the requests can be handled - and for declaring any interesting headers that the ```Request``` should parse. Decision can be based on request - method, request url, http version, request host/port/target host and get parameters -- Once a ```Handler``` is attached to given ```Request``` (```canHandle``` returned true) - that ```Handler``` takes care to receive any file/data upload and attach a ```Response``` - once the ```Request``` has been fully parsed -- ```Handlers``` are evaluated in the order they are attached to the server. The ```canHandle``` is called only - if the ```Filter``` that was set to the ```Handler``` return true. -- The first ```Handler``` that can handle the request is selected, not further ```Filter``` and ```canHandle``` are called. - -### Responses and how do they work -- The ```Response``` objects are used to send the response data back to the client -- The ```Response``` object lives with the ```Request``` and is freed on end or disconnect -- Different techniques are used depending on the response type to send the data in packets - returning back almost immediately and sending the next packet when this one is received. - Any time in between is spent to run the user loop and handle other network packets -- Responding asynchronously is probably the most difficult thing for most to understand -- Many different options exist for the user to make responding a background task - -### Template processing -- ESPAsyncWebserver contains simple template processing engine. -- Template processing can be added to most response types. -- Currently it supports only replacing template placeholders with actual values. No conditional processing, cycles, etc. -- Placeholders are delimited with ```%``` symbols. Like this: ```%TEMPLATE_PLACEHOLDER%```. -- It works by extracting placeholder name from response text and passing it to user provided function which should return actual value to be used instead of placeholder. -- Since it's user provided function, it is possible for library users to implement conditional processing and cycles themselves. -- Since it's impossible to know the actual response size after template processing step in advance (and, therefore, to include it in response headers), the response becomes [chunked](#chunked-response). - -## Libraries and projects that use AsyncWebServer -- [WebSocketToSerial](https://github.com/hallard/WebSocketToSerial) - Debug serial devices through the web browser -- [Sattrack](https://github.com/Hopperpop/Sattrack) - Track the ISS with ESP8266 -- [ESP Radio](https://github.com/Edzelf/Esp-radio) - Icecast radio based on ESP8266 and VS1053 -- [VZero](https://github.com/andig/vzero) - the Wireless zero-config controller for volkszaehler.org -- [ESPurna](https://bitbucket.org/xoseperez/espurna) - ESPurna ("spark" in Catalan) is a custom C firmware for ESP8266 based smart switches. It was originally developed with the ITead Sonoff in mind. -- [fauxmoESP](https://bitbucket.org/xoseperez/fauxmoesp) - Belkin WeMo emulator library for ESP8266. -- [ESP-RFID](https://github.com/omersiar/esp-rfid) - MFRC522 RFID Access Control Management project for ESP8266. - -## Request Variables - -### Common Variables -```cpp -request->version(); // uint8_t: 0 = HTTP/1.0, 1 = HTTP/1.1 -request->method(); // enum: HTTP_GET, HTTP_POST, HTTP_DELETE, HTTP_PUT, HTTP_PATCH, HTTP_HEAD, HTTP_OPTIONS -request->url(); // String: URL of the request (not including host, port or GET parameters) -request->host(); // String: The requested host (can be used for virtual hosting) -request->contentType(); // String: ContentType of the request (not avaiable in Handler::canHandle) -request->contentLength(); // size_t: ContentLength of the request (not avaiable in Handler::canHandle) -request->multipart(); // bool: True if the request has content type "multipart" -``` - -### Headers -```cpp -//List all collected headers -int headers = request->headers(); -int i; -for(i=0;igetHeader(i); - Serial.printf("HEADER[%s]: %s\n", h->name().c_str(), h->value().c_str()); -} - -//get specific header by name -if(request->hasHeader("MyHeader")){ - AsyncWebHeader* h = request->getHeader("MyHeader"); - Serial.printf("MyHeader: %s\n", h->value().c_str()); -} - -//List all collected headers (Compatibility) -int headers = request->headers(); -int i; -for(i=0;iheaderName(i).c_str(), request->header(i).c_str()); -} - -//get specific header by name (Compatibility) -if(request->hasHeader("MyHeader")){ - Serial.printf("MyHeader: %s\n", request->header("MyHeader").c_str()); -} -``` - -### GET, POST and FILE parameters -```cpp -//List all parameters -int params = request->params(); -for(int i=0;igetParam(i); - if(p->isFile()){ //p->isPost() is also true - Serial.printf("FILE[%s]: %s, size: %u\n", p->name().c_str(), p->value().c_str(), p->size()); - } else if(p->isPost()){ - Serial.printf("POST[%s]: %s\n", p->name().c_str(), p->value().c_str()); - } else { - Serial.printf("GET[%s]: %s\n", p->name().c_str(), p->value().c_str()); - } -} - -//Check if GET parameter exists -if(request->hasParam("download")) - AsyncWebParameter* p = request->getParam("download"); - -//Check if POST (but not File) parameter exists -if(request->hasParam("download", true)) - AsyncWebParameter* p = request->getParam("download", true); - -//Check if FILE was uploaded -if(request->hasParam("download", true, true)) - AsyncWebParameter* p = request->getParam("download", true, true); - -//List all parameters (Compatibility) -int args = request->args(); -for(int i=0;iargName(i).c_str(), request->arg(i).c_str()); -} - -//Check if parameter exists (Compatibility) -if(request->hasArg("download")) - String arg = request->arg("download"); -``` - -### FILE Upload handling -```cpp -void handleUpload(AsyncWebServerRequest *request, String filename, size_t index, uint8_t *data, size_t len, bool final){ - if(!index){ - Serial.printf("UploadStart: %s\n", filename.c_str()); - } - for(size_t i=0; i(); - // ... -}); -server.addHandler(handler); -``` - -## Responses -### Redirect to another URL -```cpp -//to local url -request->redirect("/login"); - -//to external url -request->redirect("http://esp8266.com"); -``` - -### Basic response with HTTP Code -```cpp -request->send(404); //Sends 404 File Not Found -``` - -### Basic response with HTTP Code and extra headers -```cpp -AsyncWebServerResponse *response = request->beginResponse(404); //Sends 404 File Not Found -response->addHeader("Server","ESP Async Web Server"); -request->send(response); -``` - -### Basic response with string content -```cpp -request->send(200, "text/plain", "Hello World!"); -``` - -### Basic response with string content and extra headers -```cpp -AsyncWebServerResponse *response = request->beginResponse(200, "text/plain", "Hello World!"); -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 large webpage from PROGMEM containing templates -```cpp -String processor(const String& var) -{ - if(var == "HELLO_FROM_TEMPLATE") - return F("Hello world!"); - return String(); -} - -// ... - -const char index_html[] PROGMEM = "..."; // large char array, tested with 14k -request->send_P(200, "text/html", index_html, processor); -``` - -### Send large webpage from PROGMEM containing templates and extra headers -```cpp -String processor(const String& var) -{ - if(var == "HELLO_FROM_TEMPLATE") - return F("Hello world!"); - return String(); -} - -// ... - -const char index_html[] PROGMEM = "..."; // large char array, tested with 14k -AsyncWebServerResponse *response = request->beginResponse_P(200, "text/html", index_html, processor); -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 -request->send(Serial, "text/plain", 12); -``` - -### Respond with content coming from a Stream and extra headers -```cpp -//read 12 bytes from Serial and send them as Content Type text/plain -AsyncWebServerResponse *response = request->beginResponse(Serial, "text/plain", 12); -response->addHeader("Server","ESP Async Web Server"); -request->send(response); -``` - -### Respond with content coming from a Stream containing templates -```cpp -String processor(const String& var) -{ - if(var == "HELLO_FROM_TEMPLATE") - return F("Hello world!"); - return String(); -} - -// ... - -//read 12 bytes from Serial and send them as Content Type text/plain -request->send(Serial, "text/plain", 12, processor); -``` - -### Respond with content coming from a Stream containing templates and extra headers -```cpp -String processor(const String& var) -{ - if(var == "HELLO_FROM_TEMPLATE") - return F("Hello world!"); - return String(); -} - -// ... - -//read 12 bytes from Serial and send them as Content Type text/plain -AsyncWebServerResponse *response = request->beginResponse(Serial, "text/plain", 12, processor); -response->addHeader("Server","ESP Async Web Server"); -request->send(response); -``` - -### Respond with content coming from a File -```cpp -//Send index.htm with default content type -request->send(SPIFFS, "/index.htm"); - -//Send index.htm as text -request->send(SPIFFS, "/index.htm", "text/plain"); - -//Download index.htm -request->send(SPIFFS, "/index.htm", String(), true); -``` - -### Respond with content coming from a File and extra headers -```cpp -//Send index.htm with default content type -AsyncWebServerResponse *response = request->beginResponse(SPIFFS, "/index.htm"); - -//Send index.htm as text -AsyncWebServerResponse *response = request->beginResponse(SPIFFS, "/index.htm", "text/plain"); - -//Download index.htm -AsyncWebServerResponse *response = request->beginResponse(SPIFFS, "/index.htm", String(), true); - -response->addHeader("Server","ESP Async Web Server"); -request->send(response); -``` - -### Respond with content coming from a File containing templates -Internally uses [Chunked Response](#chunked-response). - -Index.htm contents: -``` -%HELLO_FROM_TEMPLATE% -``` - -Somewhere in source files: -```cpp -String processor(const String& var) -{ - if(var == "HELLO_FROM_TEMPLATE") - return F("Hello world!"); - return String(); -} - -// ... - -//Send index.htm with template processor function -request->send(SPIFFS, "/index.htm", String(), false, processor); -``` - -### Respond with content using a callback -```cpp -//send 128 bytes as plain text -request->send("text/plain", 128, [](uint8_t *buffer, size_t maxLen, size_t index) -> size_t { - //Write up to "maxLen" bytes into "buffer" and return the amount written. - //index equals the amount of bytes that have been already sent - //You will not be asked for more bytes once the content length has been reached. - //Keep in mind that you can not delay or yield waiting for more data! - //Send what you currently have and you will be asked for more again - return mySource.read(buffer, maxLen); -}); -``` - -### Respond with content using a callback and extra headers -```cpp -//send 128 bytes as plain text -AsyncWebServerResponse *response = request->beginResponse("text/plain", 128, [](uint8_t *buffer, size_t maxLen, size_t index) -> size_t { - //Write up to "maxLen" bytes into "buffer" and return the amount written. - //index equals the amount of bytes that have been already sent - //You will not be asked for more bytes once the content length has been reached. - //Keep in mind that you can not delay or yield waiting for more data! - //Send what you currently have and you will be asked for more again - return mySource.read(buffer, maxLen); -}); -response->addHeader("Server","ESP Async Web Server"); -request->send(response); -``` - -### Respond with file content using a callback and extra headers - -With this code your ESP is able to serve even large (large in terms of ESP, e.g. 100kB) files -without memory problems. - -You need to create a file handler in outer function (to have a single one for request) but use -it in a lambda. The catch is that the lambda has it's own lifecycle which may/will cause it's -called after the original function is over thus the original file handle is destroyed. Using the -captured `&file` in the lambda then causes segfault (Hello, Exception 9!) and the whole ESP crashes. -By using this code, you tell the compiler to move the handle into the lambda so it won't be -destroyed when outer function (that one where you call `request->send(response)`) ends. - -```cpp -const File file = ... // e.g. SPIFFS.open(path, "r"); - -const contentType = "application/javascript"; - -AsyncWebServerResponse *response = request->beginResponse( - contentType, - file.size(), - [file](uint8_t *buffer, size_t maxLen, size_t total) mutable -> size_t { - int bytes = file.read(buffer, maxLen); - - // close file at the end - if (bytes + total == file.size()) file.close(); - - return max(0, bytes); // return 0 even when no bytes were loaded - } -); - -if (gzipped) { - response->addHeader(F("Content-Encoding"), F("gzip")); -} - -request->send(response); -``` - -### Respond with content using a callback containing templates -```cpp -String processor(const String& var) -{ - if(var == "HELLO_FROM_TEMPLATE") - return F("Hello world!"); - return String(); -} - -// ... - -//send 128 bytes as plain text -request->send("text/plain", 128, [](uint8_t *buffer, size_t maxLen, size_t index) -> size_t { - //Write up to "maxLen" bytes into "buffer" and return the amount written. - //index equals the amount of bytes that have been already sent - //You will not be asked for more bytes once the content length has been reached. - //Keep in mind that you can not delay or yield waiting for more data! - //Send what you currently have and you will be asked for more again - return mySource.read(buffer, maxLen); -}, processor); -``` - -### Respond with content using a callback containing templates and extra headers -```cpp -String processor(const String& var) -{ - if(var == "HELLO_FROM_TEMPLATE") - return F("Hello world!"); - return String(); -} - -// ... - -//send 128 bytes as plain text -AsyncWebServerResponse *response = request->beginResponse("text/plain", 128, [](uint8_t *buffer, size_t maxLen, size_t index) -> size_t { - //Write up to "maxLen" bytes into "buffer" and return the amount written. - //index equals the amount of bytes that have been already sent - //You will not be asked for more bytes once the content length has been reached. - //Keep in mind that you can not delay or yield waiting for more data! - //Send what you currently have and you will be asked for more again - return mySource.read(buffer, maxLen); -}, processor); -response->addHeader("Server","ESP Async Web Server"); -request->send(response); -``` - -### Chunked Response -Used when content length is unknown. Works best if the client supports HTTP/1.1 -```cpp -AsyncWebServerResponse *response = request->beginChunkedResponse("text/plain", [](uint8_t *buffer, size_t maxLen, size_t index) -> size_t { - //Write up to "maxLen" bytes into "buffer" and return the amount written. - //index equals the amount of bytes that have been already sent - //You will be asked for more data until 0 is returned - //Keep in mind that you can not delay or yield waiting for more data! - return mySource.read(buffer, maxLen); -}); -response->addHeader("Server","ESP Async Web Server"); -request->send(response); -``` - -### Chunked Response containing templates -Used when content length is unknown. Works best if the client supports HTTP/1.1 -```cpp -String processor(const String& var) -{ - if(var == "HELLO_FROM_TEMPLATE") - return F("Hello world!"); - return String(); -} - -// ... - -AsyncWebServerResponse *response = request->beginChunkedResponse("text/plain", [](uint8_t *buffer, size_t maxLen, size_t index) -> size_t { - //Write up to "maxLen" bytes into "buffer" and return the amount written. - //index equals the amount of bytes that have been already sent - //You will be asked for more data until 0 is returned - //Keep in mind that you can not delay or yield waiting for more data! - return mySource.read(buffer, maxLen); -}, processor); -response->addHeader("Server","ESP Async Web Server"); -request->send(response); -``` - -### Print to response -```cpp -AsyncResponseStream *response = request->beginResponseStream("text/html"); -response->addHeader("Server","ESP Async Web Server"); -response->printf("Webpage at %s", request->url().c_str()); - -response->print("

Hello "); -response->print(request->client()->remoteIP()); -response->print("

"); - -response->print("

General

"); -response->print("
    "); -response->printf("
  • Version: HTTP/1.%u
  • ", request->version()); -response->printf("
  • Method: %s
  • ", request->methodToString()); -response->printf("
  • URL: %s
  • ", request->url().c_str()); -response->printf("
  • Host: %s
  • ", request->host().c_str()); -response->printf("
  • ContentType: %s
  • ", request->contentType().c_str()); -response->printf("
  • ContentLength: %u
  • ", request->contentLength()); -response->printf("
  • Multipart: %s
  • ", request->multipart()?"true":"false"); -response->print("
"); - -response->print("

Headers

"); -response->print("
    "); -int headers = request->headers(); -for(int i=0;igetHeader(i); - response->printf("
  • %s: %s
  • ", h->name().c_str(), h->value().c_str()); -} -response->print("
"); - -response->print("

Parameters

"); -response->print("
    "); -int params = request->params(); -for(int i=0;igetParam(i); - if(p->isFile()){ - response->printf("
  • FILE[%s]: %s, size: %u
  • ", p->name().c_str(), p->value().c_str(), p->size()); - } else if(p->isPost()){ - response->printf("
  • POST[%s]: %s
  • ", p->name().c_str(), p->value().c_str()); - } else { - response->printf("
  • GET[%s]: %s
  • ", p->name().c_str(), p->value().c_str()); - } -} -response->print("
"); - -response->print(""); -//send the response last -request->send(response); -``` - -### ArduinoJson Basic Response -This way of sending Json is great for when the result is below 4KB -```cpp -#include "AsyncJson.h" -#include "ArduinoJson.h" - - -AsyncResponseStream *response = request->beginResponseStream("application/json"); -DynamicJsonBuffer jsonBuffer; -JsonObject &root = jsonBuffer.createObject(); -root["heap"] = ESP.getFreeHeap(); -root["ssid"] = WiFi.SSID(); -root.printTo(*response); -request->send(response); -``` - -### ArduinoJson Advanced Response -This response can handle really large Json objects (tested to 40KB) -There isn't any noticeable speed decrease for small results with the method above -Since ArduinoJson does not allow reading parts of the string, the whole Json has to -be passed every time a chunks needs to be sent, which shows speed decrease proportional -to the resulting json packets -```cpp -#include "AsyncJson.h" -#include "ArduinoJson.h" - - -AsyncJsonResponse * response = new AsyncJsonResponse(); -response->addHeader("Server","ESP Async Web Server"); -JsonObject& root = response->getRoot(); -root["heap"] = ESP.getFreeHeap(); -root["ssid"] = WiFi.SSID(); -response->setLength(); -request->send(response); -``` - -## Serving static files -In addition to serving files from SPIFFS as described above, the server provide a dedicated handler that optimize the -performance of serving files from SPIFFS - ```AsyncStaticWebHandler```. Use ```server.serveStatic()``` function to -initialize and add a new instance of ```AsyncStaticWebHandler``` to the server. -The Handler will not handle the request if the file does not exists, e.g. the server will continue to look for another -handler that can handle the request. -Notice that you can chain setter functions to setup the handler, or keep a pointer to change it at a later time. - -### Serving specific file by name -```cpp -// Serve the file "/www/page.htm" when request url is "/page.htm" -server.serveStatic("/page.htm", SPIFFS, "/www/page.htm"); -``` - -### Serving files in directory -To serve files in a directory, the path to the files should specify a directory in SPIFFS and ends with "/". -```cpp -// Serve files in directory "/www/" when request url starts with "/" -// Request to the root or none existing files will try to server the defualt -// file name "index.htm" if exists -server.serveStatic("/", SPIFFS, "/www/"); - -// Server with different default file -server.serveStatic("/", SPIFFS, "/www/").setDefaultFile("default.html"); -``` - -### Serving static files with authentication - -```cpp -server - .serveStatic("/", SPIFFS, "/www/") - .setDefaultFile("default.html") - .setAuthentication("user", "pass"); -``` - -### Specifying Cache-Control header -It is possible to specify Cache-Control header value to reduce the number of calls to the server once the client loaded -the files. For more information on Cache-Control values see [Cache-Control](https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9) -```cpp -// Cache responses for 10 minutes (600 seconds) -server.serveStatic("/", SPIFFS, "/www/").setCacheControl("max-age=600"); - -//*** Change Cache-Control after server setup *** - -// During setup - keep a pointer to the handler -AsyncStaticWebHandler* handler = &server.serveStatic("/", SPIFFS, "/www/").setCacheControl("max-age=600"); - -// At a later event - change Cache-Control -handler->setCacheControl("max-age=30"); -``` - -### Specifying Date-Modified header -It is possible to specify Date-Modified header to enable the server to return Not-Modified (304) response for requests -with "If-Modified-Since" header with the same value, instead of responding with the actual file content. -```cpp -// Update the date modified string every time files are updated -server.serveStatic("/", SPIFFS, "/www/").setLastModified("Mon, 20 Jun 2016 14:00:00 GMT"); - -//*** Chage last modified value at a later stage *** - -// During setup - read last modified value from config or EEPROM -String date_modified = loadDateModified(); -AsyncStaticWebHandler* handler = &server.serveStatic("/", SPIFFS, "/www/"); -handler->setLastModified(date_modified); - -// At a later event when files are updated -String date_modified = getNewDateModfied(); -saveDateModified(date_modified); // Save for next reset -handler->setLastModified(date_modified); -``` - -### Specifying Template Processor callback -It is possible to specify template processor for static files. For information on template processor see -[Respond with content coming from a File containing templates](#respond-with-content-coming-from-a-file-containing-templates). -```cpp -String processor(const String& var) -{ - if(var == "HELLO_FROM_TEMPLATE") - return F("Hello world!"); - return String(); -} - -// ... - -server.serveStatic("/", SPIFFS, "/www/").setTemplateProcessor(processor); -``` - -### Serving static files by custom handling - -It may happen your static files are too big and the ESP will crash the request before it sends the whole file. -In that case, you can handle static files with custom file serving through not found handler. - -This code below is more-or-less equivalent to this: -```cpp -webServer.serveStatic("/", SPIFFS, STATIC_FILES_PREFIX).setDefaultFile("index.html") -``` - -First, declare the handling function: -```cpp -bool handleStaticFile(AsyncWebServerRequest *request) { - String path = STATIC_FILES_PREFIX + request->url(); - - if (path.endsWith("/")) path += F("index.html"); - - String contentType = getContentType(path); - String pathWithGz = path + ".gz"; - - if (SPIFFS.exists(pathWithGz) || SPIFFS.exists(path)) { - bool gzipped = false; - if (SPIFFS.exists(pathWithGz)) { - gzipped = true; - path += ".gz"; - } - - // TODO serve the file - - return true; - } - - return false; -} -``` -And then configure your webserver: -```cpp -webServer.onNotFound([](AsyncWebServerRequest *request) { - if (handleStaticFile(request)) return; - - request->send(404); -}); -``` - -You may want to try [Respond with file content using a callback and extra headers](#respond-with-file-content-using-a-callback-and-extra-headers) -For actual serving the file. - -## Param Rewrite With Matching -It is possible to rewrite the request url with parameter matchg. Here is an example with one parameter: -Rewrite for example "/radio/{frequence}" -> "/radio?f={frequence}" - -```cpp -class OneParamRewrite : public AsyncWebRewrite -{ - protected: - String _urlPrefix; - int _paramIndex; - String _paramsBackup; - - public: - OneParamRewrite(const char* from, const char* to) - : AsyncWebRewrite(from, to) { - - _paramIndex = _from.indexOf('{'); - - if( _paramIndex >=0 && _from.endsWith("}")) { - _urlPrefix = _from.substring(0, _paramIndex); - int index = _params.indexOf('{'); - if(index >= 0) { - _params = _params.substring(0, index); - } - } else { - _urlPrefix = _from; - } - _paramsBackup = _params; - } - - bool match(AsyncWebServerRequest *request) override { - if(request->url().startsWith(_urlPrefix)) { - if(_paramIndex >= 0) { - _params = _paramsBackup + request->url().substring(_paramIndex); - } else { - _params = _paramsBackup; - } - return true; - - } else { - return false; - } - } -}; -``` - -Usage: - -```cpp - server.addRewrite( new OneParamRewrite("/radio/{frequence}", "/radio?f={frequence}") ); -``` - -## Using filters -Filters can be set to `Rewrite` or `Handler` in order to control when to apply the rewrite and consider the handler. -A filter is a callback function that evaluates the request and return a boolean `true` to include the item -or `false` to exclude it. -Two filter callback are provided for convince: -* `ON_STA_FILTER` - return true when requests are made to the STA (station mode) interface. -* `ON_AP_FILTER` - return true when requests are made to the AP (access point) interface. - -### Serve different site files in AP mode -```cpp -server.serveStatic("/", SPIFFS, "/www/").setFilter(ON_STA_FILTER); -server.serveStatic("/", SPIFFS, "/ap/").setFilter(ON_AP_FILTER); -``` - -### Rewrite to different index on AP -```cpp -// Serve the file "/www/index-ap.htm" in AP, and the file "/www/index.htm" on STA -server.rewrite("/", "index.htm"); -server.rewrite("/index.htm", "index-ap.htm").setFilter(ON_AP_FILTER); -server.serveStatic("/", SPIFFS, "/www/"); -``` - -### Serving different hosts -```cpp -// Filter callback using request host -bool filterOnHost1(AsyncWebServerRequest *request) { return request->host() == "host1"; } - -// Server setup: server files in "/host1/" to requests for "host1", and files in "/www/" otherwise. -server.serveStatic("/", SPIFFS, "/host1/").setFilter(filterOnHost1); -server.serveStatic("/", SPIFFS, "/www/"); -``` - -### Determine interface inside callbacks -```cpp - String RedirectUrl = "http://"; - if (ON_STA_FILTER(request)) { - RedirectUrl += WiFi.localIP().toString(); - } else { - RedirectUrl += WiFi.softAPIP().toString(); - } - RedirectUrl += "/index.htm"; - request->redirect(RedirectUrl); -``` - -## Bad Responses -Some responses are implemented, but you should not use them, because they do not conform to HTTP. -The following example will lead to unclean close of the connection and more time wasted -than providing the length of the content - -### Respond with content using a callback without content length to HTTP/1.0 clients -```cpp -//This is used as fallback for chunked responses to HTTP/1.0 Clients -request->send("text/plain", 0, [](uint8_t *buffer, size_t maxLen, size_t index) -> size_t { - //Write up to "maxLen" bytes into "buffer" and return the amount written. - //You will be asked for more data until 0 is returned - //Keep in mind that you can not delay or yield waiting for more data! - return mySource.read(buffer, maxLen); -}); -``` - -## Async WebSocket Plugin -The server includes a web socket plugin which lets you define different WebSocket locations to connect to -without starting another listening service or using different port - -### Async WebSocket Event -```cpp - -void onEvent(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventType type, void * arg, uint8_t *data, size_t len){ - if(type == WS_EVT_CONNECT){ - //client connected - os_printf("ws[%s][%u] connect\n", server->url(), client->id()); - client->printf("Hello Client %u :)", client->id()); - client->ping(); - } else if(type == WS_EVT_DISCONNECT){ - //client disconnected - os_printf("ws[%s][%u] disconnect: %u\n", server->url(), client->id()); - } else if(type == WS_EVT_ERROR){ - //error was received from the other end - os_printf("ws[%s][%u] error(%u): %s\n", server->url(), client->id(), *((uint16_t*)arg), (char*)data); - } else if(type == WS_EVT_PONG){ - //pong message was received (in response to a ping request maybe) - os_printf("ws[%s][%u] pong[%u]: %s\n", server->url(), client->id(), len, (len)?(char*)data:""); - } else if(type == WS_EVT_DATA){ - //data packet - AwsFrameInfo * info = (AwsFrameInfo*)arg; - if(info->final && info->index == 0 && info->len == len){ - //the whole message is in a single frame and we got all of it's data - os_printf("ws[%s][%u] %s-message[%llu]: ", server->url(), client->id(), (info->opcode == WS_TEXT)?"text":"binary", info->len); - if(info->opcode == WS_TEXT){ - data[len] = 0; - os_printf("%s\n", (char*)data); - } else { - for(size_t i=0; i < info->len; i++){ - os_printf("%02x ", data[i]); - } - os_printf("\n"); - } - if(info->opcode == WS_TEXT) - client->text("I got your text message"); - else - client->binary("I got your binary message"); - } else { - //message is comprised of multiple frames or the frame is split into multiple packets - if(info->index == 0){ - if(info->num == 0) - os_printf("ws[%s][%u] %s-message start\n", server->url(), client->id(), (info->message_opcode == WS_TEXT)?"text":"binary"); - os_printf("ws[%s][%u] frame[%u] start[%llu]\n", server->url(), client->id(), info->num, info->len); - } - - 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->message_opcode == WS_TEXT){ - data[len] = 0; - os_printf("%s\n", (char*)data); - } else { - for(size_t i=0; i < len; i++){ - os_printf("%02x ", data[i]); - } - os_printf("\n"); - } - - if((info->index + len) == info->len){ - os_printf("ws[%s][%u] frame[%u] end[%llu]\n", server->url(), client->id(), info->num, info->len); - if(info->final){ - os_printf("ws[%s][%u] %s-message end\n", server->url(), client->id(), (info->message_opcode == WS_TEXT)?"text":"binary"); - if(info->message_opcode == WS_TEXT) - client->text("I got your text message"); - else - client->binary("I got your binary message"); - } - } - } - } -} -``` - -### Methods for sending data to a socket client -```cpp - - - -//Server methods -AsyncWebSocket ws("/ws"); -//printf to a client -ws.printf((uint32_t)client_id, arguments...); -//printf to all clients -ws.printfAll(arguments...); -//printf_P to a client -ws.printf_P((uint32_t)client_id, PSTR(format), arguments...); -//printfAll_P to all clients -ws.printfAll_P(PSTR(format), arguments...); -//send text to a client -ws.text((uint32_t)client_id, (char*)text); -ws.text((uint32_t)client_id, (uint8_t*)text, (size_t)len); -//send text from PROGMEM to a client -ws.text((uint32_t)client_id, PSTR("text")); -const char flash_text[] PROGMEM = "Text to send" -ws.text((uint32_t)client_id, FPSTR(flash_text)); -//send text to all clients -ws.textAll((char*)text); -ws.textAll((uint8_t*)text, (size_t)len); -//send binary to a client -ws.binary((uint32_t)client_id, (char*)binary); -ws.binary((uint32_t)client_id, (uint8_t*)binary, (size_t)len); -//send binary from PROGMEM to a client -const uint8_t flash_binary[] PROGMEM = { 0x01, 0x02, 0x03, 0x04 }; -ws.binary((uint32_t)client_id, flash_binary, 4); -//send binary to all clients -ws.binaryAll((char*)binary); -ws.binaryAll((uint8_t*)binary, (size_t)len); -//HTTP Authenticate before switch to Websocket protocol -ws.setAuthentication("user", "pass"); - -//client methods -AsyncWebSocketClient * client; -//printf -client->printf(arguments...); -//printf_P -client->printf_P(PSTR(format), arguments...); -//send text -client->text((char*)text); -client->text((uint8_t*)text, (size_t)len); -//send text from PROGMEM -client->text(PSTR("text")); -const char flash_text[] PROGMEM = "Text to send"; -client->text(FPSTR(flash_text)); -//send binary -client->binary((char*)binary); -client->binary((uint8_t*)binary, (size_t)len); -//send binary from PROGMEM -const uint8_t flash_binary[] PROGMEM = { 0x01, 0x02, 0x03, 0x04 }; -client->binary(flash_binary, 4); -``` - -### Direct access to web socket message buffer -When sending a web socket message using the above methods a buffer is created. Under certain circumstances you might want to manipulate or populate this buffer directly from your application, for example to prevent unnecessary duplications of the data. This example below shows how to create a buffer and print data to it from an ArduinoJson object then send it. - -```cpp -void sendDataWs(AsyncWebSocketClient * client) -{ - DynamicJsonBuffer jsonBuffer; - JsonObject& root = jsonBuffer.createObject(); - root["a"] = "abc"; - root["b"] = "abcd"; - root["c"] = "abcde"; - root["d"] = "abcdef"; - root["e"] = "abcdefg"; - size_t len = root.measureLength(); - AsyncWebSocketMessageBuffer * buffer = ws.makeBuffer(len); // creates a buffer (len + 1) for you. - if (buffer) { - root.printTo((char *)buffer->get(), len + 1); - if (client) { - client->text(buffer); - } else { - ws.textAll(buffer); - } - } -} -``` - -### Limiting the number of web socket clients -Browsers sometimes do not correctly close the websocket connection, even when the close() function is called in javascript. This will eventually exhaust the web server's resources and will cause the server to crash. Periodically calling the cleanClients() function from the main loop() function limits the number of clients by closing the oldest client when the maximum number of clients has been exceeded. This can called be every cycle, however, if you wish to use less power, then calling as infrequently as once per second is sufficient. - -```cpp -void loop(){ - ws.cleanupClients(); -} -``` - - -## Async Event Source Plugin -The server includes EventSource (Server-Sent Events) plugin which can be used to send short text events to the browser. -Difference between EventSource and WebSockets is that EventSource is single direction, text-only protocol. - -### Setup Event Source on the server -```cpp -AsyncWebServer server(80); -AsyncEventSource events("/events"); - -void setup(){ - // setup ...... - events.onConnect([](AsyncEventSourceClient *client){ - if(client->lastId()){ - Serial.printf("Client reconnected! Last message ID that it gat is: %u\n", client->lastId()); - } - //send event with message "hello!", id current millis - // and set reconnect delay to 1 second - client->send("hello!",NULL,millis(),1000); - }); - //HTTP Basic authentication - events.setAuthentication("user", "pass"); - server.addHandler(&events); - // setup ...... -} - -void loop(){ - if(eventTriggered){ // your logic here - //send event "myevent" - events.send("my event content","myevent",millis()); - } -} -``` - -### Setup Event Source in the browser -```javascript -if (!!window.EventSource) { - var source = new EventSource('/events'); - - source.addEventListener('open', function(e) { - console.log("Events Connected"); - }, false); - - source.addEventListener('error', function(e) { - if (e.target.readyState != EventSource.OPEN) { - console.log("Events Disconnected"); - } - }, false); - - source.addEventListener('message', function(e) { - console.log("message", e.data); - }, false); - - source.addEventListener('myevent', function(e) { - console.log("myevent", e.data); - }, false); -} -``` - -## Scanning for available WiFi Networks -```cpp -//First request will return 0 results unless you start scan from somewhere else (loop/setup) -//Do not request more often than 3-5 seconds -server.on("/scan", HTTP_GET, [](AsyncWebServerRequest *request){ - String json = "["; - int n = WiFi.scanComplete(); - if(n == -2){ - WiFi.scanNetworks(true); - } else if(n){ - for (int i = 0; i < n; ++i){ - if(i) json += ","; - json += "{"; - json += "\"rssi\":"+String(WiFi.RSSI(i)); - json += ",\"ssid\":\""+WiFi.SSID(i)+"\""; - json += ",\"bssid\":\""+WiFi.BSSIDstr(i)+"\""; - json += ",\"channel\":"+String(WiFi.channel(i)); - json += ",\"secure\":"+String(WiFi.encryptionType(i)); - json += ",\"hidden\":"+String(WiFi.isHidden(i)?"true":"false"); - json += "}"; - } - WiFi.scanDelete(); - if(WiFi.scanComplete() == -2){ - WiFi.scanNetworks(true); - } - } - json += "]"; - request->send(200, "application/json", json); - json = String(); -}); -``` - -## Remove handlers and rewrites - -Server goes through handlers in same order as they were added. You can't simple add handler with same path to override them. -To remove handler: -```arduino -// save callback for particular URL path -auto handler = server.on("/some/path", [](AsyncWebServerRequest *request){ - //do something useful -}); -// when you don't need handler anymore remove it -server.removeHandler(&handler); - -// same with rewrites -server.removeRewrite(&someRewrite); - -server.onNotFound([](AsyncWebServerRequest *request){ - request->send(404); -}); - -// remove server.onNotFound handler -server.onNotFound(NULL); - -// remove all rewrites, handlers and onNotFound/onFileUpload/onRequestBody callbacks -server.reset(); -``` - -## Setting up the server -```cpp -#include "ESPAsyncTCP.h" -#include "ESPAsyncWebServer.h" - -AsyncWebServer server(80); -AsyncWebSocket ws("/ws"); // access at ws://[esp ip]/ws -AsyncEventSource events("/events"); // event source (Server-Sent events) - -const char* ssid = "your-ssid"; -const char* password = "your-pass"; -const char* http_username = "admin"; -const char* http_password = "admin"; - -//flag to use from web update to reboot the ESP -bool shouldReboot = false; - -void onRequest(AsyncWebServerRequest *request){ - //Handle Unknown Request - request->send(404); -} - -void onBody(AsyncWebServerRequest *request, uint8_t *data, size_t len, size_t index, size_t total){ - //Handle body -} - -void onUpload(AsyncWebServerRequest *request, String filename, size_t index, uint8_t *data, size_t len, bool final){ - //Handle upload -} - -void onEvent(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventType type, void * arg, uint8_t *data, size_t len){ - //Handle WebSocket event -} - -void setup(){ - Serial.begin(115200); - WiFi.mode(WIFI_STA); - WiFi.begin(ssid, password); - if (WiFi.waitForConnectResult() != WL_CONNECTED) { - Serial.printf("WiFi Failed!\n"); - return; - } - - // attach AsyncWebSocket - ws.onEvent(onEvent); - server.addHandler(&ws); - - // attach AsyncEventSource - server.addHandler(&events); - - // respond to GET requests on URL /heap - server.on("/heap", HTTP_GET, [](AsyncWebServerRequest *request){ - request->send(200, "text/plain", String(ESP.getFreeHeap())); - }); - - // upload a file to /upload - server.on("/upload", HTTP_POST, [](AsyncWebServerRequest *request){ - request->send(200); - }, onUpload); - - // send a file when /index is requested - server.on("/index", HTTP_ANY, [](AsyncWebServerRequest *request){ - request->send(SPIFFS, "/index.htm"); - }); - - // HTTP basic authentication - server.on("/login", HTTP_GET, [](AsyncWebServerRequest *request){ - if(!request->authenticate(http_username, http_password)) - return request->requestAuthentication(); - request->send(200, "text/plain", "Login Success!"); - }); - - // Simple Firmware Update Form - server.on("/update", HTTP_GET, [](AsyncWebServerRequest *request){ - request->send(200, "text/html", "
"); - }); - server.on("/update", HTTP_POST, [](AsyncWebServerRequest *request){ - shouldReboot = !Update.hasError(); - AsyncWebServerResponse *response = request->beginResponse(200, "text/plain", shouldReboot?"OK":"FAIL"); - response->addHeader("Connection", "close"); - request->send(response); - },[](AsyncWebServerRequest *request, String filename, size_t index, uint8_t *data, size_t len, bool final){ - if(!index){ - Serial.printf("Update Start: %s\n", filename.c_str()); - Update.runAsync(true); - if(!Update.begin((ESP.getFreeSketchSpace() - 0x1000) & 0xFFFFF000)){ - Update.printError(Serial); - } - } - if(!Update.hasError()){ - if(Update.write(data, len) != len){ - Update.printError(Serial); - } - } - if(final){ - if(Update.end(true)){ - Serial.printf("Update Success: %uB\n", index+len); - } else { - Update.printError(Serial); - } - } - }); - - // attach filesystem root at URL /fs - server.serveStatic("/fs", SPIFFS, "/"); - - // Catch-All Handlers - // Any request that can not find a Handler that canHandle it - // ends in the callbacks below. - server.onNotFound(onRequest); - server.onFileUpload(onUpload); - server.onRequestBody(onBody); - - server.begin(); -} - -void loop(){ - if(shouldReboot){ - Serial.println("Rebooting..."); - delay(100); - ESP.restart(); - } - static char temp[128]; - sprintf(temp, "Seconds since boot: %u", millis()/1000); - events.send(temp, "time"); //send event "time" -} -``` - -### Setup global and class functions as request handlers - -```cpp -#include -#include -#include -#include - -void handleRequest(AsyncWebServerRequest *request){} - -class WebClass { -public : - AsyncWebServer classWebServer = AsyncWebServer(81); - - WebClass(){}; - - void classRequest (AsyncWebServerRequest *request){} - - void begin(){ - // attach global request handler - classWebServer.on("/example", HTTP_ANY, handleRequest); - - // attach class request handler - classWebServer.on("/example", HTTP_ANY, std::bind(&WebClass::classRequest, this, std::placeholders::_1)); - } -}; - -AsyncWebServer globalWebServer(80); -WebClass webClassInstance; - -void setup() { - // attach global request handler - globalWebServer.on("/example", HTTP_ANY, handleRequest); - - // attach class request handler - globalWebServer.on("/example", HTTP_ANY, std::bind(&WebClass::classRequest, webClassInstance, std::placeholders::_1)); -} - -void loop() { - -} -``` - -### Methods for controlling websocket connections - -```cpp - // Disable client connections if it was activated - if ( ws.enabled() ) - ws.enable(false); - - // enable client connections if it was disabled - if ( !ws.enabled() ) - ws.enable(true); -``` - -Example of OTA code - -```cpp - // OTA callbacks - ArduinoOTA.onStart([]() { - // Clean SPIFFS - SPIFFS.end(); - - // Disable client connections - ws.enable(false); - - // Advertise connected clients what's going on - ws.textAll("OTA Update Started"); - - // Close them - ws.closeAll(); - - }); - -``` - -### Adding Default Headers - -In some cases, such as when working with CORS, or with some sort of custom authentication system, -you might need to define a header that should get added to all responses (including static, websocket and EventSource). -The DefaultHeaders singleton allows you to do this. - -Example: - -```cpp -DefaultHeaders::Instance().addHeader("Access-Control-Allow-Origin", "*"); -webServer.begin(); -``` - -*NOTE*: You will still need to respond to the OPTIONS method for CORS pre-flight in most cases. (unless you are only using GET) - -This is one option: - -```cpp -webServer.onNotFound([](AsyncWebServerRequest *request) { - if (request->method() == HTTP_OPTIONS) { - request->send(200); - } else { - request->send(404); - } -}); -``` - -### Path variable - -With path variable you can create a custom regex rule for a specific parameter in a route. -For example we want a `sensorId` parameter in a route rule to match only a integer. - -```cpp - server.on("^\\/sensor\\/([0-9]+)$", HTTP_GET, [] (AsyncWebServerRequest *request) { - String sensorId = request->pathArg(0); - }); -``` -*NOTE*: All regex patterns starts with `^` and ends with `$` - -To enable the `Path variable` support, you have to define the buildflag `-DASYNCWEBSERVER_REGEX`. - - -For Arduino IDE create/update `platform.local.txt`: - -`Windows`: C:\Users\(username)\AppData\Local\Arduino15\packages\\`{espxxxx}`\hardware\\`espxxxx`\\`{version}`\platform.local.txt - -`Linux`: ~/.arduino15/packages/`{espxxxx}`/hardware/`{espxxxx}`/`{version}`/platform.local.txt - -Add/Update the following line: -``` - compiler.cpp.extra_flags=-DDASYNCWEBSERVER_REGEX -``` - -For platformio modify `platformio.ini`: -```ini -[env:myboard] -build_flags = - -DASYNCWEBSERVER_REGEX -``` -*NOTE*: By enabling `ASYNCWEBSERVER_REGEX`, `` will be included. This will add an 100k to your binary. +Usage and API stays the same as the original library. +Please look at the original libraries for more examples and documentation. diff --git a/_config.yml b/_config.yml deleted file mode 100644 index c4192631f..000000000 --- a/_config.yml +++ /dev/null @@ -1 +0,0 @@ -theme: jekyll-theme-cayman \ No newline at end of file diff --git a/component.mk b/component.mk deleted file mode 100644 index bb5bb1614..000000000 --- a/component.mk +++ /dev/null @@ -1,3 +0,0 @@ -COMPONENT_ADD_INCLUDEDIRS := src -COMPONENT_SRCDIRS := src -CXXFLAGS += -fno-rtti diff --git a/examples/CaptivePortal/CaptivePortal.ino b/examples/CaptivePortal/CaptivePortal.ino new file mode 100644 index 000000000..8cfe5613d --- /dev/null +++ b/examples/CaptivePortal/CaptivePortal.ino @@ -0,0 +1,41 @@ +#include "ESPAsyncWebServer.h" +#include +#include +#include + +DNSServer dnsServer; +AsyncWebServer server(80); + +class CaptiveRequestHandler : public AsyncWebHandler { + public: + CaptiveRequestHandler() {} + virtual ~CaptiveRequestHandler() {} + + bool canHandle(AsyncWebServerRequest* request) { + // request->addInterestingHeader("ANY"); + return true; + } + + void handleRequest(AsyncWebServerRequest* request) { + AsyncResponseStream* response = request->beginResponseStream("text/html"); + response->print("Captive Portal"); + response->print("

This is out captive portal front page.

"); + response->printf("

You were trying to reach: http://%s%s

", request->host().c_str(), request->url().c_str()); + response->printf("

Try opening this link instead

", WiFi.softAPIP().toString().c_str()); + response->print(""); + request->send(response); + } +}; + +void setup() { + // your other setup stuff... + WiFi.softAP("esp-captive"); + dnsServer.start(53, "*", WiFi.softAPIP()); + server.addHandler(new CaptiveRequestHandler()).setFilter(ON_AP_FILTER); // only when requested from AP + // more handlers... + server.begin(); +} + +void loop() { + dnsServer.processNextRequest(); +} \ No newline at end of file diff --git a/examples/SimpleServer/SimpleServer.ino b/examples/SimpleServer/SimpleServer.ino new file mode 100644 index 000000000..8cfe5613d --- /dev/null +++ b/examples/SimpleServer/SimpleServer.ino @@ -0,0 +1,41 @@ +#include "ESPAsyncWebServer.h" +#include +#include +#include + +DNSServer dnsServer; +AsyncWebServer server(80); + +class CaptiveRequestHandler : public AsyncWebHandler { + public: + CaptiveRequestHandler() {} + virtual ~CaptiveRequestHandler() {} + + bool canHandle(AsyncWebServerRequest* request) { + // request->addInterestingHeader("ANY"); + return true; + } + + void handleRequest(AsyncWebServerRequest* request) { + AsyncResponseStream* response = request->beginResponseStream("text/html"); + response->print("Captive Portal"); + response->print("

This is out captive portal front page.

"); + response->printf("

You were trying to reach: http://%s%s

", request->host().c_str(), request->url().c_str()); + response->printf("

Try opening this link instead

", WiFi.softAPIP().toString().c_str()); + response->print(""); + request->send(response); + } +}; + +void setup() { + // your other setup stuff... + WiFi.softAP("esp-captive"); + dnsServer.start(53, "*", WiFi.softAPIP()); + server.addHandler(new CaptiveRequestHandler()).setFilter(ON_AP_FILTER); // only when requested from AP + // more handlers... + server.begin(); +} + +void loop() { + dnsServer.processNextRequest(); +} \ No newline at end of file diff --git a/keywords.txt b/keywords.txt deleted file mode 100755 index c391e6c43..000000000 --- a/keywords.txt +++ /dev/null @@ -1,3 +0,0 @@ -JsonArray KEYWORD1 -add KEYWORD2 -createArray KEYWORD3 diff --git a/library.json b/library.json index a5a851e5f..45b2d8e7c 100644 --- a/library.json +++ b/library.json @@ -1,38 +1,40 @@ { "name": "ESP Async WebServer", - "description": "Asynchronous HTTP and WebSocket Server Library for ESP8266 and ESP32", + "description": "Asynchronous HTTP and WebSocket Server Library for ESP32", "keywords": "http,async,websocket,webserver", - "authors": { - "name": "Hristo Gochkov", - "maintainer": true - }, + "homepage": "https://github.com/mathieucarbou/ESPAsyncWebServer", "repository": { "type": "git", "url": "https://github.com/mathieucarbou/ESPAsyncWebServer.git" }, - "version": "2.1.2", + "authors": [ + { + "name": "Me-No-Dev" + }, + { + "name": "Mathieu Carbou", + "maintainer": true + } + ], "license": "LGPL-3.0", "frameworks": "arduino", "platforms": [ - "espressif8266", "espressif32" ], "dependencies": [ - { - "owner": "esphome", - "name": "ESPAsyncTCP-esphome", - "version": ">=2.0.0", - "platforms": "espressif8266" - }, { "owner": "esphome", "name": "AsyncTCP-esphome", - "version": ">=2.0.1", + "version": "^2.1.1", "platforms": "espressif32" }, { - "name": "Hash", - "platforms": "espressif8266" + "owner": "bblanchon", + "name": "ArduinoJson", + "version": "^7.0.2", + "platforms": [ + "espressif32" + ] } ] } \ No newline at end of file diff --git a/library.properties b/library.properties index 419f3362c..790ba2c94 100644 --- a/library.properties +++ b/library.properties @@ -2,8 +2,10 @@ name=ESP Async WebServer version=2.1.2 author=Me-No-Dev maintainer=Mathieu Carbou -sentence=Async Web Server for ESP8266 and ESP31B -paragraph=Async Web Server for ESP8266 and ESP31B +sentence=Asynchronous HTTP and WebSocket Server Library for ESP32 +paragraph= category=Other url=https://github.com/mathieucarbou/ESPAsyncWebServer -architectures=* +architectures==esp32 +license=LGPL-3.0 +depends=ArduinoJson diff --git a/platformio.ini b/platformio.ini new file mode 100644 index 000000000..cad8b22ee --- /dev/null +++ b/platformio.ini @@ -0,0 +1,23 @@ +[env] +lib_deps = + bblanchon/ArduinoJson @ 7.0.2 + esphome/AsyncTCP-esphome @ 2.1.1 + +build_flags = -Wall -Wextra + +upload_protocol = esptool +upload_port = /dev/cu.usbserial-0001 + +monitor_port = /dev/cu.usbserial-0001 +monitor_speed = 115200 +monitor_filters = esp32_exception_decoder, log2file + +[platformio] +lib_dir = . +src_dir = examples/CaptivePortal +; src_dir = examples/SimpleServer + +[env:esp32] +platform = espressif32@6.5.0 +board = esp32dev +framework = arduino diff --git a/src/AsyncJson.h b/src/AsyncJson.h index a6673a8aa..f4e99d123 100644 --- a/src/AsyncJson.h +++ b/src/AsyncJson.h @@ -30,7 +30,7 @@ // ... }); server.addHandler(handler); - + */ #ifndef ASYNC_JSON_H_ #define ASYNC_JSON_H_ @@ -39,9 +39,9 @@ #include #if ARDUINOJSON_VERSION_MAJOR == 6 - #ifndef DYNAMIC_JSON_DOCUMENT_SIZE - #define DYNAMIC_JSON_DOCUMENT_SIZE 1024 - #endif +#ifndef DYNAMIC_JSON_DOCUMENT_SIZE +#define DYNAMIC_JSON_DOCUMENT_SIZE 1024 +#endif #endif constexpr const char* JSON_MIMETYPE = "application/json"; @@ -56,11 +56,12 @@ class ChunkPrint : public Print { size_t _to_skip; size_t _to_write; size_t _pos; + public: ChunkPrint(uint8_t* destination, size_t from, size_t len) - : _destination(destination), _to_skip(from), _to_write(len), _pos{0} {} - virtual ~ChunkPrint(){} - size_t write(uint8_t c){ + : _destination(destination), _to_skip(from), _to_write(len), _pos{0} {} + virtual ~ChunkPrint() {} + size_t write(uint8_t c) { if (_to_skip > 0) { _to_skip--; return 1; @@ -71,15 +72,13 @@ class ChunkPrint : public Print { } return 0; } - size_t write(const uint8_t *buffer, size_t size) - { + size_t write(const uint8_t* buffer, size_t size) { return this->Print::write(buffer, size); } }; -class AsyncJsonResponse: public AsyncAbstractResponse { +class AsyncJsonResponse : public AsyncAbstractResponse { protected: - #if ARDUINOJSON_VERSION_MAJOR == 5 DynamicJsonBuffer _jsonBuffer; #elif ARDUINOJSON_VERSION_MAJOR == 6 @@ -91,31 +90,30 @@ class AsyncJsonResponse: public AsyncAbstractResponse { JsonVariant _root; bool _isValid; - public: - + public: #if ARDUINOJSON_VERSION_MAJOR == 5 - AsyncJsonResponse(bool isArray=false): _isValid{false} { + AsyncJsonResponse(bool isArray = false) : _isValid{false} { _code = 200; _contentType = JSON_MIMETYPE; - if(isArray) + if (isArray) _root = _jsonBuffer.createArray(); else _root = _jsonBuffer.createObject(); } #elif ARDUINOJSON_VERSION_MAJOR == 6 - AsyncJsonResponse(bool isArray=false, size_t maxJsonBufferSize = DYNAMIC_JSON_DOCUMENT_SIZE) : _jsonBuffer(maxJsonBufferSize), _isValid{false} { + AsyncJsonResponse(bool isArray = false, size_t maxJsonBufferSize = DYNAMIC_JSON_DOCUMENT_SIZE) : _jsonBuffer(maxJsonBufferSize), _isValid{false} { _code = 200; _contentType = JSON_MIMETYPE; - if(isArray) + if (isArray) _root = _jsonBuffer.createNestedArray(); else _root = _jsonBuffer.createNestedObject(); } #else - AsyncJsonResponse(bool isArray=false) : _isValid{false} { + AsyncJsonResponse(bool isArray = false) : _isValid{false} { _code = 200; _contentType = JSON_MIMETYPE; - if(isArray) + if (isArray) _root = _jsonBuffer.add(); else _root = _jsonBuffer.add(); @@ -123,7 +121,7 @@ class AsyncJsonResponse: public AsyncAbstractResponse { #endif ~AsyncJsonResponse() {} - JsonVariant & getRoot() { return _root; } + JsonVariant& getRoot() { return _root; } bool _sourceValid() const { return _isValid; } size_t setLength() { @@ -133,17 +131,19 @@ class AsyncJsonResponse: public AsyncAbstractResponse { _contentLength = measureJson(_root); #endif - if (_contentLength) { _isValid = true; } + if (_contentLength) { + _isValid = true; + } return _contentLength; } - size_t getSize() { return _jsonBuffer.size(); } + size_t getSize() { return _jsonBuffer.size(); } - size_t _fillBuffer(uint8_t *data, size_t len){ + size_t _fillBuffer(uint8_t* data, size_t len) { ChunkPrint dest(data, _sentLength, len); #if ARDUINOJSON_VERSION_MAJOR == 5 - _root.printTo( dest ) ; + _root.printTo(dest); #else serializeJson(_root, dest); #endif @@ -151,118 +151,121 @@ class AsyncJsonResponse: public AsyncAbstractResponse { } }; -class PrettyAsyncJsonResponse: public AsyncJsonResponse { -public: +class PrettyAsyncJsonResponse : public AsyncJsonResponse { + public: #if ARDUINOJSON_VERSION_MAJOR == 6 - PrettyAsyncJsonResponse (bool isArray=false, size_t maxJsonBufferSize = DYNAMIC_JSON_DOCUMENT_SIZE) : AsyncJsonResponse{isArray, maxJsonBufferSize} {} + PrettyAsyncJsonResponse(bool isArray = false, size_t maxJsonBufferSize = DYNAMIC_JSON_DOCUMENT_SIZE) : AsyncJsonResponse{isArray, maxJsonBufferSize} {} #else - PrettyAsyncJsonResponse (bool isArray=false) : AsyncJsonResponse{isArray} {} + PrettyAsyncJsonResponse(bool isArray = false) : AsyncJsonResponse{isArray} {} #endif - size_t setLength () { + size_t setLength() { #if ARDUINOJSON_VERSION_MAJOR == 5 - _contentLength = _root.measurePrettyLength (); + _contentLength = _root.measurePrettyLength(); #else - _contentLength = measureJsonPretty(_root); + _contentLength = measureJsonPretty(_root); #endif - if (_contentLength) {_isValid = true;} - return _contentLength; - } - size_t _fillBuffer (uint8_t *data, size_t len) { - ChunkPrint dest (data, _sentLength, len); + if (_contentLength) { + _isValid = true; + } + return _contentLength; + } + size_t _fillBuffer(uint8_t* data, size_t len) { + ChunkPrint dest(data, _sentLength, len); #if ARDUINOJSON_VERSION_MAJOR == 5 - _root.prettyPrintTo (dest); + _root.prettyPrintTo(dest); #else - serializeJsonPretty(_root, dest); + serializeJsonPretty(_root, dest); #endif - return len; - } + return len; + } }; -typedef std::function ArJsonRequestHandlerFunction; +typedef std::function ArJsonRequestHandlerFunction; -class AsyncCallbackJsonWebHandler: public AsyncWebHandler { -private: -protected: - const String _uri; - WebRequestMethodComposite _method; - ArJsonRequestHandlerFunction _onRequest; - size_t _contentLength; +class AsyncCallbackJsonWebHandler : public AsyncWebHandler { + private: + protected: + const String _uri; + WebRequestMethodComposite _method; + ArJsonRequestHandlerFunction _onRequest; + size_t _contentLength; #if ARDUINOJSON_VERSION_MAJOR == 6 - const size_t maxJsonBufferSize; + const size_t maxJsonBufferSize; #endif - size_t _maxContentLength; -public: + size_t _maxContentLength; + + public: #if ARDUINOJSON_VERSION_MAJOR == 6 - AsyncCallbackJsonWebHandler(const String& uri, ArJsonRequestHandlerFunction onRequest, size_t maxJsonBufferSize=DYNAMIC_JSON_DOCUMENT_SIZE) - : _uri(uri), _method(HTTP_POST|HTTP_PUT|HTTP_PATCH), _onRequest(onRequest), maxJsonBufferSize(maxJsonBufferSize), _maxContentLength(16384) {} + AsyncCallbackJsonWebHandler(const String& uri, ArJsonRequestHandlerFunction onRequest, size_t maxJsonBufferSize = DYNAMIC_JSON_DOCUMENT_SIZE) + : _uri(uri), _method(HTTP_POST | HTTP_PUT | HTTP_PATCH), _onRequest(onRequest), maxJsonBufferSize(maxJsonBufferSize), _maxContentLength(16384) {} #else - AsyncCallbackJsonWebHandler(const String& uri, ArJsonRequestHandlerFunction onRequest) - : _uri(uri), _method(HTTP_POST|HTTP_PUT|HTTP_PATCH), _onRequest(onRequest), _maxContentLength(16384) {} + AsyncCallbackJsonWebHandler(const String& uri, ArJsonRequestHandlerFunction onRequest) + : _uri(uri), _method(HTTP_POST | HTTP_PUT | HTTP_PATCH), _onRequest(onRequest), _maxContentLength(16384) {} #endif - - void setMethod(WebRequestMethodComposite method){ _method = method; } - void setMaxContentLength(int maxContentLength){ _maxContentLength = maxContentLength; } - void onRequest(ArJsonRequestHandlerFunction fn){ _onRequest = fn; } - virtual bool canHandle(AsyncWebServerRequest *request) override final{ - if(!_onRequest) - return false; + void setMethod(WebRequestMethodComposite method) { _method = method; } + void setMaxContentLength(int maxContentLength) { _maxContentLength = maxContentLength; } + void onRequest(ArJsonRequestHandlerFunction fn) { _onRequest = fn; } - if(!(_method & request->method())) - return false; + virtual bool canHandle(AsyncWebServerRequest* request) override final { + if (!_onRequest) + return false; - if(_uri.length() && (_uri != request->url() && !request->url().startsWith(_uri+"/"))) - return false; + if (!(_method & request->method())) + return false; - if ( !request->contentType().equalsIgnoreCase(JSON_MIMETYPE) ) - return false; + if (_uri.length() && (_uri != request->url() && !request->url().startsWith(_uri + "/"))) + return false; - request->addInterestingHeader("ANY"); - return true; - } + if (!request->contentType().equalsIgnoreCase(JSON_MIMETYPE)) + return false; - virtual void handleRequest(AsyncWebServerRequest *request) override final { - if(_onRequest) { - if (request->_tempObject != NULL) { + request->addInterestingHeader("ANY"); + return true; + } + + virtual void handleRequest(AsyncWebServerRequest* request) override final { + if (_onRequest) { + if (request->_tempObject != NULL) { #if ARDUINOJSON_VERSION_MAJOR == 5 - DynamicJsonBuffer jsonBuffer; - JsonVariant json = jsonBuffer.parse((uint8_t*)(request->_tempObject)); - if (json.success()) { + DynamicJsonBuffer jsonBuffer; + JsonVariant json = jsonBuffer.parse((uint8_t*)(request->_tempObject)); + if (json.success()) { #elif ARDUINOJSON_VERSION_MAJOR == 6 - DynamicJsonDocument jsonBuffer(this->maxJsonBufferSize); - DeserializationError error = deserializeJson(jsonBuffer, (uint8_t*)(request->_tempObject)); - if(!error) { - JsonVariant json = jsonBuffer.as(); + DynamicJsonDocument jsonBuffer(this->maxJsonBufferSize); + DeserializationError error = deserializeJson(jsonBuffer, (uint8_t*)(request->_tempObject)); + if (!error) { + JsonVariant json = jsonBuffer.as(); #else - JsonDocument jsonBuffer; - DeserializationError error = deserializeJson(jsonBuffer, (uint8_t*)(request->_tempObject)); - if(!error) { - JsonVariant json = jsonBuffer.as(); + JsonDocument jsonBuffer; + DeserializationError error = deserializeJson(jsonBuffer, (uint8_t*)(request->_tempObject)); + if (!error) { + JsonVariant json = jsonBuffer.as(); #endif - _onRequest(request, json); - return; + _onRequest(request, json); + return; + } } + request->send(_contentLength > _maxContentLength ? 413 : 400); + } else { + request->send(500); } - request->send(_contentLength > _maxContentLength ? 413 : 400); - } else { - request->send(500); } - } - virtual void handleUpload(AsyncWebServerRequest *request, const String& filename, size_t index, uint8_t *data, size_t len, bool final) override final { - } - virtual void handleBody(AsyncWebServerRequest *request, uint8_t *data, size_t len, size_t index, size_t total) override final { - if (_onRequest) { - _contentLength = total; - if (total > 0 && request->_tempObject == NULL && total < _maxContentLength) { - request->_tempObject = malloc(total); - } - if (request->_tempObject != NULL) { - memcpy((uint8_t*)(request->_tempObject) + index, data, len); + virtual void handleUpload(AsyncWebServerRequest* request, const String& filename, size_t index, uint8_t* data, size_t len, bool final) override final { + } + virtual void handleBody(AsyncWebServerRequest* request, uint8_t* data, size_t len, size_t index, size_t total) override final { + if (_onRequest) { + _contentLength = total; + if (total > 0 && request->_tempObject == NULL && total < _maxContentLength) { + request->_tempObject = malloc(total); + } + if (request->_tempObject != NULL) { + memcpy((uint8_t*)(request->_tempObject) + index, data, len); + } } } - } - virtual bool isRequestHandlerTrivial() override final {return _onRequest ? false : true;} + virtual bool isRequestHandlerTrivial() override final { return _onRequest ? false : true; } }; #endif diff --git a/src/SPIFFSEditor.cpp b/src/SPIFFSEditor.cpp deleted file mode 100644 index 343ed79e0..000000000 --- a/src/SPIFFSEditor.cpp +++ /dev/null @@ -1,342 +0,0 @@ -#include "SPIFFSEditor.h" -#include - -#define EDFS - -#ifndef EDFS - #include "edit.htm.gz.h" -#endif - -#ifdef ESP32 - #define fullName(x) name(x) -#endif - -#define SPIFFS_MAXLENGTH_FILEPATH 32 -static const char excludeListFile[] PROGMEM = "/.exclude.files"; - -typedef struct ExcludeListS { - char *item; - ExcludeListS *next; -} ExcludeList; - -static ExcludeList *excludes = NULL; - -static bool matchWild(const char *pattern, const char *testee) { - const char *nxPat = NULL, *nxTst = NULL; - - while (*testee) { - if (( *pattern == '?' ) || (*pattern == *testee)){ - pattern++;testee++; - continue; - } - if (*pattern=='*'){ - nxPat=pattern++; nxTst=testee; - continue; - } - if (nxPat){ - pattern = nxPat+1; testee=++nxTst; - continue; - } - return false; - } - while (*pattern=='*'){pattern++;} - return (*pattern == 0); -} - -static bool addExclude(const char *item){ - size_t len = strlen(item); - if(!len){ - return false; - } - ExcludeList *e = (ExcludeList *)malloc(sizeof(ExcludeList)); - if(!e){ - return false; - } - e->item = (char *)malloc(len+1); - if(!e->item){ - free(e); - return false; - } - memcpy(e->item, item, len+1); - e->next = excludes; - excludes = e; - return true; -} - -static void loadExcludeList(fs::FS &_fs, const char *filename){ - static char linebuf[SPIFFS_MAXLENGTH_FILEPATH]; - fs::File excludeFile=_fs.open(filename, "r"); - if(!excludeFile){ - //addExclude("/*.js.gz"); - return; - } -#ifdef ESP32 - if(excludeFile.isDirectory()){ - excludeFile.close(); - return; - } -#endif - if (excludeFile.size() > 0){ - uint8_t idx; - bool isOverflowed = false; - while (excludeFile.available()){ - linebuf[0] = '\0'; - idx = 0; - int lastChar; - do { - lastChar = excludeFile.read(); - if(lastChar != '\r'){ - linebuf[idx++] = (char) lastChar; - } - } while ((lastChar >= 0) && (lastChar != '\n') && (idx < SPIFFS_MAXLENGTH_FILEPATH)); - - if(isOverflowed){ - isOverflowed = (lastChar != '\n'); - continue; - } - isOverflowed = (idx >= SPIFFS_MAXLENGTH_FILEPATH); - linebuf[idx-1] = '\0'; - if(!addExclude(linebuf)){ - excludeFile.close(); - return; - } - } - } - excludeFile.close(); -} - -static bool isExcluded(fs::FS &_fs, const char *filename) { - if(excludes == NULL){ - loadExcludeList(_fs, String(FPSTR(excludeListFile)).c_str()); - } - ExcludeList *e = excludes; - while(e){ - if (matchWild(e->item, filename)){ - return true; - } - e = e->next; - } - return false; -} - -// WEB HANDLER IMPLEMENTATION - -#ifdef ESP32 -SPIFFSEditor::SPIFFSEditor(const fs::FS& fs, const String& username, const String& password) -#else -SPIFFSEditor::SPIFFSEditor(const String& username, const String& password, const fs::FS& fs) -#endif -:_fs(fs) -,_username(username) -,_password(password) -,_authenticated(false) -,_startTime(0) -{} - -bool SPIFFSEditor::canHandle(AsyncWebServerRequest *request){ - if(request->url().equalsIgnoreCase(F("/edit"))){ - if(request->method() == HTTP_GET){ - if(request->hasParam(F("list"))) - return true; - if(request->hasParam(F("edit"))){ - request->_tempFile = _fs.open(request->arg(F("edit")), "r"); - if(!request->_tempFile){ - return false; - } -#ifdef ESP32 - if(request->_tempFile.isDirectory()){ - request->_tempFile.close(); - return false; - } -#endif - } - if(request->hasParam("download")){ - request->_tempFile = _fs.open(request->arg(F("download")), "r"); - if(!request->_tempFile){ - return false; - } -#ifdef ESP32 - if(request->_tempFile.isDirectory()){ - request->_tempFile.close(); - return false; - } -#endif - } - request->addInterestingHeader(F("If-Modified-Since")); - return true; - } - else if(request->method() == HTTP_POST) - return true; - else if(request->method() == HTTP_DELETE) - return true; - else if(request->method() == HTTP_PUT) - return true; - - } - return false; -} - - -void SPIFFSEditor::handleRequest(AsyncWebServerRequest *request){ - if(_username.length() && _password.length() && !request->authenticate(_username.c_str(), _password.c_str())) - return request->requestAuthentication(); - - if(request->method() == HTTP_GET){ - if(request->hasParam(F("list"))){ - String path = request->getParam(F("list"))->value(); -#ifdef ESP32 - File dir = _fs.open(path); -#else - fs::Dir dir = _fs.openDir(path); -#endif - path = String(); - String output = "["; -#ifdef ESP32 - File entry = dir.openNextFile(); - while(entry){ -#else - while(dir.next()){ - fs::File entry = dir.openFile("r"); -#endif - String fname = entry.fullName(); - if (fname.charAt(0) != '/') fname = "/" + fname; - - if (isExcluded(_fs, fname.c_str())) { -#ifdef ESP32 - entry = dir.openNextFile(); -#endif - continue; - } - if (output != "[") output += ','; - output += F("{\"type\":\""); - output += F("file"); - output += F("\",\"name\":\""); - output += String(fname); - output += F("\",\"size\":"); - output += String(entry.size()); - output += "}"; -#ifdef ESP32 - entry = dir.openNextFile(); -#else - entry.close(); -#endif - } -#ifdef ESP32 - dir.close(); -#endif - output += "]"; - request->send(200, F("application/json"), output); - output = String(); - } - else if(request->hasParam(F("edit")) || request->hasParam(F("download"))){ - request->send(request->_tempFile, request->_tempFile.fullName(), String(), request->hasParam(F("download"))); - } - else { - const char * buildTime = __DATE__ " " __TIME__ " GMT"; - if (request->header(F("If-Modified-Since")).equals(buildTime)) { - request->send(304); - } else { -#ifdef EDFS - AsyncWebServerResponse *response = request->beginResponse(_fs, F("/edit_gz"), F("text/html"), false); -#else - AsyncWebServerResponse *response = request->beginResponse_P(200, F("text/html"), edit_htm_gz, edit_htm_gz_len); -#endif - response->addHeader(F("Content-Encoding"), F("gzip")); - response->addHeader(F("Last-Modified"), buildTime); - request->send(response); - } - } - } else if(request->method() == HTTP_DELETE){ - if(request->hasParam(F("path"), true)){ - if(!(_fs.remove(request->getParam(F("path"), true)->value()))){ -#ifdef ESP32 - _fs.rmdir(request->getParam(F("path"), true)->value()); // try rmdir for littlefs -#endif - } - - request->send(200, "", String(F("DELETE: "))+request->getParam(F("path"), true)->value()); - } else - request->send(404); - } else if(request->method() == HTTP_POST){ - if(request->hasParam(F("data"), true, true) && _fs.exists(request->getParam(F("data"), true, true)->value())) - request->send(200, "", String(F("UPLOADED: "))+request->getParam(F("data"), true, true)->value()); - - else if(request->hasParam(F("rawname"), true) && request->hasParam(F("raw0"), true)){ - String rawnam = request->getParam(F("rawname"), true)->value(); - - if (_fs.exists(rawnam)) _fs.remove(rawnam); // delete it to allow a mode - - int k = 0; - uint16_t i = 0; - fs::File f = _fs.open(rawnam, "a"); - - while (request->hasParam(String(F("raw")) + String(k), true)) { //raw0 .. raw1 - if(f){ - i += f.print(request->getParam(String(F("raw")) + String(k), true)->value()); - } - k++; - } - f.close(); - request->send(200, "", String(F("IPADWRITE: ")) + rawnam + ":" + String(i)); - - } else { - request->send(500); - } - - } else if(request->method() == HTTP_PUT){ - if(request->hasParam(F("path"), true)){ - String filename = request->getParam(F("path"), true)->value(); - if(_fs.exists(filename)){ - request->send(200); - } else { -/*******************************************************/ -#ifdef ESP32 - if (strchr(filename.c_str(), '/')) { - // For file creation, silently make subdirs as needed. If any fail, - // it will be caught by the real file open later on - char *pathStr = strdup(filename.c_str()); - if (pathStr) { - // Make dirs up to the final fnamepart - char *ptr = strchr(pathStr, '/'); - while (ptr) { - *ptr = 0; - _fs.mkdir(pathStr); - *ptr = '/'; - ptr = strchr(ptr+1, '/'); - } - } - free(pathStr); - } -#endif -/*******************************************************/ - fs::File f = _fs.open(filename, "w"); - if(f){ - f.write((uint8_t)0x00); - f.close(); - request->send(200, "", String(F("CREATE: "))+filename); - } else { - request->send(500); - } - } - } else - request->send(400); - } -} - -void SPIFFSEditor::handleUpload(AsyncWebServerRequest *request, const 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())){ - _authenticated = true; - request->_tempFile = _fs.open(filename, "w"); - _startTime = millis(); - } - } - if(_authenticated && request->_tempFile){ - if(len){ - request->_tempFile.write(data,len); - } - if(final){ - request->_tempFile.close(); - } - } -} diff --git a/src/SPIFFSEditor.h b/src/SPIFFSEditor.h deleted file mode 100644 index d3b959ff8..000000000 --- a/src/SPIFFSEditor.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef SPIFFSEditor_H_ -#define SPIFFSEditor_H_ -#include - -class SPIFFSEditor: public AsyncWebHandler { - private: - fs::FS _fs; - String _username; - String _password; - bool _authenticated; - uint32_t _startTime; - public: -#ifdef ESP32 - SPIFFSEditor(const fs::FS& fs, const String& username=String(), const String& password=String()); -#else - //SPIFFSEditor(const String& username=String(), const String& password=String(), const fs::FS& fs=SPIFFS); - SPIFFSEditor(const String& username, const String& password, const fs::FS& fs); // do not show warning that SPIFFS has been deprecated -#endif - virtual bool canHandle(AsyncWebServerRequest *request) override final; - virtual void handleRequest(AsyncWebServerRequest *request) override final; - virtual void handleUpload(AsyncWebServerRequest *request, const String& filename, size_t index, uint8_t *data, size_t len, bool final) override final; - virtual bool isRequestHandlerTrivial() override final {return false;} -}; - -#endif diff --git a/src/edit.htm b/src/edit.htm deleted file mode 100644 index 5d497ea45..000000000 --- a/src/edit.htm +++ /dev/null @@ -1,581 +0,0 @@ - - - - - ESP Editor - - - - - - - - - - -
-
-
-
- - - - \ No newline at end of file diff --git a/src/edit.htm.gz.h b/src/edit.htm.gz.h deleted file mode 100644 index aa77e289c..000000000 --- a/src/edit.htm.gz.h +++ /dev/null @@ -1,231 +0,0 @@ - -//File: edit.htm.gz, Size: 4503 -#define edit_htm_gz_len 4503 -const uint8_t edit_htm_gz[] PROGMEM = { -0x1F,0x8B,0x08,0x08,0x5A,0xE6,0xAE,0x5F,0x02,0x00,0x65,0x64,0x69,0x74,0x2E,0x68,0x74,0x6D,0x00,0xB5, -0x1A,0x0B,0x5B,0xDB,0x36,0xF0,0xAF,0x18,0x6F,0x63,0xF6,0xE2,0x38,0x0E,0x50,0xD6,0x3A,0x18,0x16,0x1E, -0xEB,0xBB,0x50,0x12,0xDA,0xD1,0x8E,0xED,0x53,0x6C,0x25,0x56,0xB1,0x25,0xCF,0x96,0x09,0x34,0xCD,0x7F, -0xDF,0x49,0xF2,0x93,0x84,0xEE,0xF1,0x6D,0xA5,0x60,0x49,0xA7,0x3B,0xDD,0x9D,0xEE,0x25,0xD9,0x7B,0x1B, -0xC7,0xA7,0x47,0xE3,0xCB,0xB3,0x13,0x2D,0xE4,0x71,0xB4,0xBF,0x27,0xFE,0x6A,0x11,0xA2,0x33,0x4F,0xC7, -0x54,0xDF,0xDF,0x8B,0x31,0x47,0x00,0xE2,0x49,0x17,0xFF,0x91,0x93,0x1B,0x4F,0x3F,0x62,0x94,0x63,0xCA, -0xBB,0xFC,0x2E,0xC1,0xBA,0xE6,0xAB,0x9E,0xA7,0x73,0x7C,0xCB,0x7B,0x02,0x79,0xA0,0xF9,0x21,0x4A,0x33, -0xCC,0xBD,0x9C,0x4F,0xBB,0x8F,0x81,0x04,0x27,0x3C,0xC2,0xFB,0x27,0xA3,0x33,0xED,0x24,0x20,0x9C,0xA5, -0x7B,0x3D,0x35,0xB2,0x17,0x11,0x7A,0xAD,0xA5,0x38,0xF2,0x74,0x94,0x24,0x11,0xEE,0x72,0x96,0xFB,0x61, -0x97,0x00,0x4D,0x5D,0x0B,0x53,0x3C,0xF5,0xF4,0x1E,0xF2,0xB1,0x0D,0x03,0xBA,0x26,0x96,0xF3,0x74,0x12, -0xA3,0x19,0xEE,0xDD,0xAA,0x39,0x4D,0x02,0x59,0xC8,0x52,0xEE,0xE7,0x5C,0xFB,0x57,0xD8,0xFF,0x00,0x29, -0xE3,0x77,0x11,0x56,0x20,0x25,0xB3,0x9F,0x65,0xBA,0x16,0xE3,0x80,0x20,0xE0,0xC2,0x4F,0xB1,0xD0,0x5A, -0x84,0x26,0x38,0x5A,0x4C,0x19,0xA8,0x29,0x23,0x9F,0xB1,0xDB,0xDF,0x4A,0x6E,0x07,0xB2,0x3B,0x45,0x31, -0x89,0xEE,0xDC,0x0C,0xD1,0xAC,0x9B,0xE1,0x94,0x4C,0x97,0xB6,0x1F,0x2F,0x3E,0x77,0x09,0x0D,0xF0,0xAD, -0xBB,0xED,0x38,0x83,0x84,0x65,0x84,0x13,0x46,0x5D,0x34,0xC9,0x58,0x94,0x73,0x3C,0x88,0xF0,0x94,0xBB, -0x8F,0x80,0xC2,0x84,0xA5,0x01,0x4E,0xDD,0x7E,0x72,0xAB,0x01,0x88,0x04,0xDA,0x37,0x3B,0x3B,0x3B,0x83, -0x09,0xF2,0xAF,0x67,0x29,0xCB,0x69,0xD0,0xF5,0x59,0xC4,0x52,0xF7,0x9B,0xE9,0x23,0xF1,0x33,0x08,0x48, -0x96,0x44,0xE8,0xCE,0xA5,0x8C,0x62,0xC0,0xBD,0xED,0x66,0x21,0x0A,0xD8,0xDC,0x75,0x34,0x47,0xEB,0x3B, -0x40,0x24,0x9D,0x4D,0x90,0xE1,0x58,0xE2,0xC7,0xDE,0x31,0x07,0x7F,0x8B,0x5F,0x35,0x3C,0xC7,0x64,0x16, -0x72,0xF7,0x47,0xC7,0x11,0xFC,0x6B,0x79,0xB4,0x88,0x48,0xC6,0xBB,0x52,0x39,0x6A,0x3D,0xCE,0x12,0xD7, -0x91,0xAC,0xC3,0x23,0x46,0xE9,0x8C,0x50,0x68,0x24,0x28,0x08,0x08,0x9D,0xB9,0x0A,0x2D,0x22,0x8B,0x4A, -0x5A,0xD8,0x07,0xC4,0xC9,0x0D,0x1E,0xC4,0x84,0x76,0xE7,0x24,0xE0,0xA1,0xBB,0xEB,0x00,0x17,0x7E,0x9E, -0x66,0x20,0x53,0xC2,0x08,0xE5,0x38,0x95,0x68,0x59,0x82,0xE8,0x42,0x89,0x2A,0x14,0x50,0xC9,0x49,0x28, -0xEC,0x28,0xEE,0x4E,0x22,0xE6,0x5F,0x57,0x2B,0xED,0x26,0xB7,0xC5,0x5A,0x6E,0xC8,0x6E,0x70,0xBA,0xA8, -0xD5,0x25,0xB1,0x5B,0xC0,0x16,0x69,0x8C,0xF1,0xD2,0xE6,0x37,0x39,0x40,0x2D,0xF9,0x04,0x29,0x0B,0xAA, -0x4D,0x91,0xDA,0x82,0x17,0x28,0x84,0x26,0x39,0x5F,0xAC,0x6E,0x25,0x4B,0x90,0x4F,0xF8,0x9D,0xEB,0xC8, -0x69,0xD2,0x42,0xDC,0x1D,0xC7,0xD1,0x84,0xC2,0xB5,0x77,0x38,0x0D,0x10,0x45,0xD6,0x30,0x25,0x28,0xB2, -0x46,0xB5,0xCA,0xBB,0x31,0xFB,0xDC,0xCD,0xA1,0x0D,0xFD,0x08,0xFB,0x5C,0x69,0x18,0x36,0x61,0x72,0x4D, -0xF8,0x2A,0x60,0x65,0xA0,0xA1,0x2B,0xA9,0xA1,0x50,0xED,0x5E,0x1F,0x74,0x23,0xF9,0x50,0x62,0x2B,0x89, -0xBA,0x13,0xC6,0x39,0x8B,0xA5,0xBD,0x55,0xD2,0x6A,0xD2,0x64,0x1E,0xAF,0x6C,0xC7,0x7A,0xD5,0x37,0xC8, -0x0F,0x40,0xA9,0x9C,0xF8,0x28,0xEA,0xA2,0x88,0xCC,0xA8,0x1B,0x93,0x20,0x88,0x70,0xC3,0x64,0xDD,0x3C, -0x8D,0x8C,0x00,0x71,0xE4,0x2A,0x3F,0x4B,0xE8,0x0C,0xA0,0x19,0xDE,0xDD,0xB1,0xC8,0xBB,0xC3,0xD3,0xF3, -0xB9,0xF3,0xF2,0xE9,0x8C,0x0D,0xE1,0xDF,0x9B,0xD1,0x45,0x78,0x72,0x31,0x83,0xD6,0xA1,0xE8,0x0E,0xDF, -0x1E,0x0D,0xDF,0xC2,0xE3,0xA8,0xDF,0xF9,0x34,0xFD,0x63,0x28,0x86,0x9F,0x06,0x87,0xE3,0x8B,0x93,0xE1, -0xF0,0x65,0xEF,0xF9,0x9B,0xF9,0xFB,0x97,0xBB,0x02,0x7C,0x18,0x39,0xE7,0xEF,0x42,0xE7,0x62,0xEB,0x49, -0x1C,0x3C,0x0B,0x42,0x3F,0xBE,0x18,0xBE,0x7D,0x7F,0x7E,0x73,0x19,0x5F,0xCC,0x46,0xEF,0xFB,0xE1,0x87, -0xAD,0x77,0xA3,0x0F,0xEF,0x7F,0xBE,0xC6,0xBF,0x3C,0x7B,0xF1,0x61,0x3C,0x07,0x84,0x63,0x36,0xBA,0x38, -0x3F,0x7C,0x77,0x38,0xFB,0x70,0xE8,0x9F,0xDC,0x4E,0xA2,0x37,0x87,0x4F,0x87,0x93,0xE1,0x96,0x8F,0xF1, -0x6C,0x7C,0x7E,0x98,0x3F,0x7F,0x79,0x3A,0x23,0x24,0x1C,0x7D,0x78,0x33,0xF6,0x8F,0x1E,0xBD,0xBA,0x78, -0x36,0x24,0xE1,0x9B,0x17,0xE7,0xCE,0xF5,0xD3,0x97,0x47,0xC7,0xFE,0xE5,0x8B,0xCB,0xDD,0xE3,0xED,0xDE, -0x8F,0x3F,0xBE,0x0E,0x4E,0x09,0x1D,0xDF,0x7C,0x1E,0xCE,0x8E,0xE6,0x8F,0xEF,0xB2,0x71,0xF8,0xFC,0x86, -0xF6,0xDE,0xB1,0x4F,0xCF,0xEF,0x5E,0xC3,0xEF,0xD9,0x59,0x67,0x32,0xEA,0x67,0x17,0x6F,0x9F,0xBF,0xDB, -0xCA,0x9E,0x3C,0x4A,0x0E,0x8F,0x8F,0x6F,0xE2,0xC9,0x59,0x2F,0x0E,0xAE,0xA7,0xFC,0xF1,0x36,0x4F,0x2E, -0x67,0xF9,0x87,0x3F,0x1E,0xBD,0x08,0x7B,0xA7,0x18,0x5D,0x86,0x9D,0xBB,0xCF,0x77,0x8F,0xC3,0xF1,0xB3, -0x9B,0x37,0x11,0xBA,0x7D,0xF3,0xC6,0xFF,0x1C,0x77,0x22,0xF4,0xE4,0x74,0x1C,0xA1,0xB4,0x7F,0x11,0x0C, -0x7B,0x9D,0xA3,0xAD,0xE1,0x0E,0x4F,0xCF,0x8F,0xE8,0xF1,0xF6,0xA7,0xD1,0xE3,0xC3,0xC3,0x3E,0x9B,0xFC, -0xB1,0xF5,0xF4,0x7A,0xF7,0xE9,0xC5,0xEE,0xDB,0xC9,0xDB,0xE1,0x68,0xE7,0xF0,0x02,0x5D,0x8E,0xDE,0x0E, -0xA7,0x3B,0x93,0x30,0x7C,0xF9,0x72,0xFC,0x73,0x30,0xFC,0x9C,0x0E,0x4F,0xE7,0xC3,0xDB,0x93,0x8B,0xE1, -0xB3,0xCE,0xCB,0x93,0xD7,0x4E,0x7F,0x74,0xB9,0x3D,0x7B,0xBD,0x3B,0x3F,0xCC,0x4E,0x86,0x6F,0x0F,0x9D, -0xD9,0x8B,0x4E,0x8C,0x3E,0xB0,0xA3,0xED,0xD9,0xF3,0x5D,0x72,0x76,0x89,0x86,0xCF,0x0F,0x5F,0x64,0xE4, -0x3C,0x7E,0x76,0xE1,0x0C,0x87,0xAF,0x4E,0xF1,0xCF,0x47,0xDB,0xE8,0xE5,0x96,0xFF,0x1E,0xF4,0x7F,0xF1, -0x0B,0xFE,0xB1,0x33,0x9C,0x9F,0x3A,0x91,0xFF,0x04,0x8F,0x9F,0x5D,0x8E,0xE5,0xEE,0x9C,0x44,0x3F,0x8F, -0xAF,0x47,0xF9,0xDB,0xF8,0xE8,0xC8,0xD4,0x28,0xEB,0xA6,0x38,0xC1,0x88,0x37,0x63,0x55,0xE5,0x1C,0x60, -0x5B,0xB5,0x15,0x16,0x4E,0x2A,0x22,0x6B,0x37,0xC0,0x3E,0x4B,0x91,0x9C,0x03,0x08,0x38,0x15,0x26,0xB6, -0xFC,0x49,0x86,0x5A,0x4D,0x45,0x5A,0x0D,0xD1,0x40,0x33,0x4A,0x47,0x88,0x09,0x05,0x9C,0x1B,0xE2,0xE3, -0x6E,0x42,0x6E,0x71,0xD4,0x95,0xC8,0xAE,0x63,0x2E,0xA4,0xB3,0x95,0xD3,0x10,0x25,0xB1,0xA2,0x5A,0x0E, -0x04,0x9F,0x90,0x2F,0x52,0x1A,0xB8,0x4C,0x0C,0xCF,0xC2,0x77,0x58,0xDA,0x9D,0xE4,0xB3,0x29,0xB9,0x05, -0x6F,0x9E,0x12,0x4A,0x38,0xD6,0xFA,0xD9,0xF2,0xA7,0x92,0xCC,0x35,0xBE,0x9B,0xA6,0x28,0xC6,0x99,0xF6, -0x37,0xC9,0x2C,0xA6,0x29,0x8B,0x17,0x75,0x04,0xE4,0xAC,0xD1,0x59,0x2E,0xBF,0xC9,0x93,0x88,0x21,0x10, -0x73,0x25,0x6C,0x94,0xC1,0x34,0x15,0x6E,0x55,0x05,0xD5,0xD2,0xCD,0xB6,0xC0,0x2D,0x5B,0x6E,0xBD,0xB5, -0x53,0xBB,0x6E,0x57,0xCE,0x15,0xC1,0xBE,0xA9,0xFA,0x46,0x3C,0x68,0xC4,0xBA,0x6F,0x38,0xA8,0x74,0xFD, -0xE2,0x6A,0x11,0x15,0x19,0x6A,0x06,0x54,0x94,0xEE,0xEF,0x3A,0x8D,0x50,0x01,0xF3,0x96,0xDF,0x60,0x99, -0xE6,0xAD,0x6F,0x92,0x14,0x76,0x03,0xCF,0xBF,0x42,0xB3,0x92,0xA9,0x4D,0x1B,0x68,0x56,0xE9,0x4E,0x89, -0x50,0xE7,0x3C,0xC9,0x6B,0x45,0x7A,0x55,0x2A,0x00,0x57,0xDC,0x3C,0x12,0xDC,0x7C,0x55,0xAB,0xDB,0xBB, -0xDF,0x15,0x3C,0xEC,0x38,0xDF,0x2D,0x6D,0x35,0xB7,0xCA,0xC7,0x7D,0x07,0xFE,0x95,0x69,0xF7,0x71,0xCD, -0xC2,0xE4,0x91,0xF8,0x29,0x19,0x04,0x3A,0x4D,0xE0,0xF6,0xCE,0x93,0xC7,0xC1,0xA4,0x04,0x2A,0xC1,0x1E, -0x86,0xA7,0x28,0x20,0x79,0xE6,0x3E,0x72,0xBE,0x53,0xFA,0x84,0xED,0x03,0xD9,0xCB,0xCD,0x55,0x9D,0xDA, -0x62,0xB3,0x84,0x50,0x6D,0x2B,0xD3,0xC4,0x7E,0xA3,0xB4,0x32,0xCC,0x66,0xAA,0x07,0x17,0xA9,0x4D,0x53, -0xCC,0x5F,0x38,0xDF,0x2D,0x78,0x8A,0x68,0x36,0x65,0x69,0xEC,0xA6,0x8C,0x23,0x8E,0x0D,0xC7,0x5C,0xF6, -0x9D,0x75,0x80,0xED,0x5D,0x27,0xC0,0x33,0x73,0xB9,0xDC,0xEB,0xC9,0xA4,0x06,0x15,0x8F,0x9F,0x92,0x84, -0xEF,0x4F,0x73,0xEA,0x0B,0x1E,0xB4,0x19,0x36,0xB0,0xB9,0x48,0x31,0xCF,0x53,0xAA,0x05,0xCC,0xCF,0x85, -0xB1,0xDB,0x33,0xCC,0x4F,0x94,0xDD,0x1F,0xDE,0x3D,0x0F,0x60,0xC6,0xB2,0x42,0xF0,0xD7,0x22,0x80,0x03, -0xC3,0x7A,0x05,0x4E,0x6B,0x3E,0x24,0x18,0x20,0xF2,0x12,0xDF,0x19,0xD8,0xE2,0x15,0x22,0xB6,0xC5,0xB8, -0x61,0x94,0xD3,0x00,0x48,0xCD,0xC5,0x0D,0x68,0x01,0x79,0xF8,0x23,0xBF,0xB2,0x88,0x47,0xE1,0x31,0x28, -0xA6,0x93,0x7D,0x74,0xD0,0xED,0xBB,0x68,0x9F,0x1C,0xF4,0xC1,0xBF,0xCC,0x06,0x7D,0xB5,0xF2,0xCF,0x24, -0xC2,0x17,0x85,0xCB,0x89,0x85,0x6A,0x6A,0x3D,0x83,0x9C,0x85,0xA0,0x48,0xF3,0x07,0xE3,0x74,0xA4,0x19, -0x1F,0x7F,0xEC,0x3E,0xB9,0xFA,0xD2,0xFF,0xE8,0x74,0xFB,0x57,0xE6,0xEF,0x66,0x8F,0xD8,0x1C,0x67,0xDC, -0xA0,0xE8,0x86,0xCC,0x10,0xD8,0xB9,0x2D,0xF2,0xED,0x70,0x06,0x52,0x98,0x83,0x6A,0x0D,0xA2,0xD8,0xDB, -0x72,0x9C,0x0D,0x0F,0x1F,0xA0,0x08,0x03,0xEB,0xFA,0xC9,0xF9,0xF9,0xE9,0xF9,0x47,0xBD,0x83,0x3B,0xFA, -0x95,0xAB,0xE9,0x1D,0x6A,0xBA,0xDC,0x86,0xA2,0x33,0xC5,0x59,0x78,0x86,0x78,0x68,0x04,0xF6,0x0D,0x8A, -0x72,0xD0,0x85,0x60,0x84,0x79,0xA0,0x38,0x7D,0x92,0x73,0xCE,0xA8,0x6E,0x0E,0x98,0x4D,0x28,0xC5,0xE9, -0xB3,0xF1,0xEB,0x57,0x9E,0x7E,0xCE,0x18,0xD7,0x8E,0x49,0xAA,0x5B,0x72,0x37,0x6C,0x94,0x24,0x98,0x06, -0x47,0x21,0x89,0x02,0x83,0x99,0x03,0x81,0xEE,0x4B,0x74,0x59,0x88,0x00,0xB6,0x6F,0xAB,0x92,0x75,0x0A, -0x52,0xEB,0x96,0x6F,0xC7,0x79,0xC4,0x49,0x12,0x61,0x6F,0xA3,0x0F,0x3D,0x8A,0x62,0x80,0x89,0x34,0x2C, -0x60,0x24,0xF0,0x74,0x15,0x8C,0x8A,0x10,0xB6,0x6E,0x15,0x5F,0xAD,0x12,0xB4,0x56,0x09,0x9A,0xB8,0x09, -0x48,0xA4,0x5B,0x81,0x5D,0xD7,0xCA,0xD0,0x2B,0x96,0x2A,0x61,0x01,0x9E,0x22,0xE0,0xE4,0x9D,0x90,0x1A, -0x4A,0xEF,0x75,0x0B,0x05,0x6A,0xA1,0xAC,0xAD,0x8D,0xAC,0xA9,0x0D,0xB5,0x8D,0xEB,0x90,0x33,0x85,0x9C, -0xB6,0x91,0xD3,0x26,0xF2,0x91,0xB4,0x86,0x75,0xC8,0xA9,0x42,0x8E,0x5A,0x22,0x46,0x52,0x44,0x15,0xE1, -0xBA,0x42,0x9B,0x20,0x10,0x60,0x47,0x4D,0x31,0xA1,0x07,0x0E,0x89,0x26,0x11,0x0E,0xBC,0x0D,0x07,0x7A, -0xA2,0xA8,0xF6,0xB6,0x9C,0x35,0x6B,0x44,0x6A,0x8D,0xBC,0xB5,0x46,0x2E,0xD7,0x20,0x09,0x28,0x11,0xF2, -0x86,0x6E,0xE5,0x52,0x6B,0xED,0x11,0xB5,0x9C,0x1F,0x62,0xFF,0x7A,0xC2,0xE4,0x88,0x6C,0x8B,0x15,0x37, -0x90,0xA4,0x99,0x48,0x9A,0xF2,0x28,0x02,0x34,0x13,0x1B,0xBC,0xDC,0x13,0x94,0xAD,0xA4,0x29,0xBE,0x36, -0x8C,0xB8,0xAD,0x4B,0x84,0xB8,0xAD,0xA5,0xB8,0x35,0x6D,0x84,0x6E,0xB0,0xB6,0x4E,0x4B,0xB1,0xB9,0x66, -0x30,0x59,0x37,0x98,0x9B,0x56,0x6A,0x33,0xEA,0x47,0xC4,0xBF,0xF6,0x6A,0x37,0x36,0x17,0x46,0xB3,0x23, -0x38,0xE1,0x1E,0xC5,0x73,0xED,0x67,0x08,0x4B,0xC7,0x88,0xA3,0x01,0x2F,0xC8,0x18,0x85,0xDD,0x60,0x20, -0x04,0xA7,0x51,0xF0,0xC2,0xCC,0x46,0x01,0x0C,0x9F,0x5D,0x8C,0x75,0x4B,0xEF,0x89,0x5D,0xD1,0xC1,0x93, -0x89,0xB9,0x34,0x2B,0x5F,0xB2,0xA8,0x8C,0xEA,0x17,0x69,0x54,0x0F,0x41,0xA3,0xB4,0xB8,0xA5,0x15,0xAF, -0xE5,0x89,0x4C,0x8D,0x4A,0xA5,0x25,0x53,0xE2,0x64,0x28,0xD6,0x30,0x8A,0xFD,0xD7,0x4D,0x08,0x7B,0xCA, -0x78,0x0D,0xD3,0x42,0x6D,0xA6,0x51,0xC5,0x74,0x8A,0xE6,0xA5,0x91,0xA8,0xF5,0x07,0xCA,0xBD,0x1D,0xC8, -0xBE,0x34,0xE3,0x1A,0xF6,0x76,0x9C,0x27,0xBB,0x03,0xD8,0x1F,0x43,0x39,0x2E,0x00,0xF6,0xB8,0x0D,0xA6, -0x35,0xE3,0xE1,0xC0,0xEF,0x78,0x85,0x56,0x02,0x8F,0xDB,0x59,0x3E,0xC9,0x78,0x0A,0xB9,0xCD,0xF0,0x2D, -0xBF,0x83,0xCD,0xF6,0x32,0x7A,0x87,0x59,0x81,0x69,0xB1,0x4E,0x67,0x79,0x4F,0x41,0xA7,0xA3,0x86,0x86, -0x90,0xD0,0x10,0x8E,0x32,0xAC,0x51,0x1B,0xDF,0x62,0xFF,0x88,0xC5,0x31,0x12,0x24,0x32,0xD8,0xE4,0xA2, -0xA3,0x9B,0x4B,0x8B,0xAD,0xD5,0xCC,0x03,0x21,0xCB,0xCA,0x1E,0xD2,0x23,0x84,0x40,0xCF,0xB7,0x85,0xAF, -0x64,0x85,0x50,0x5F,0xDF,0xE5,0x32,0x10,0x29,0x94,0x8F,0xCE,0x95,0x55,0x6D,0xDC,0x8A,0x54,0xED,0x7D, -0x97,0x56,0xD7,0x8A,0x3F,0x66,0xBD,0xD3,0x02,0xD6,0x8E,0x6B,0x35,0x54,0x5F,0x2E,0x2D,0x5F,0xF0,0x1F, -0x22,0x3A,0xC3,0x7F,0x5F,0x80,0x9A,0x47,0xE9,0xA2,0x16,0x85,0xE4,0x71,0xE0,0xFE,0x6A,0x1B,0x1F,0x7F, -0xB3,0xAF,0x3A,0xA6,0x79,0xF0,0x6D,0x4F,0x6A,0xD8,0xE0,0xE6,0xC7,0xFE,0x95,0x85,0x00,0x6C,0xFF,0x60, -0xFE,0x6A,0x4B,0x70,0x0B,0x36,0xB8,0x61,0x24,0xD0,0xC4,0x4A,0xC2,0xB3,0xD9,0x54,0x43,0x9B,0x9B,0x06, -0x98,0x5C,0xCB,0x58,0x3B,0xBC,0xA3,0xDB,0x90,0x37,0x96,0xCB,0xFB,0xD9,0x6C,0x9C,0x62,0xAC,0xD2,0x65, -0x05,0x90,0xDC,0x83,0xCC,0x2B,0xC1,0xAA,0x94,0x1A,0x5B,0x35,0x14,0x06,0x65,0xBA,0xB7,0x8B,0x4A,0xC2, -0xD3,0x29,0xA3,0x60,0xB2,0xC9,0xFD,0x61,0x79,0xC4,0xD3,0x5B,0x31,0xE4,0xFB,0x3D,0x12,0xCF,0xB4,0x2C, -0xF5,0x3D,0xB5,0x15,0x07,0xE2,0x8F,0xF7,0xBD,0x48,0x73,0x9B,0xBF,0xFB,0x13,0x4F,0xEF,0xC0,0xFE,0x62, -0x9B,0xB2,0xB9,0x61,0x76,0xBE,0xD7,0x35,0x49,0xD1,0xD3,0x63,0x74,0x5B,0x1C,0xF4,0x45,0x25,0x32,0xD0, -0xA0,0x5F,0x96,0xB0,0x6A,0xA0,0x38,0x62,0xA3,0x9C,0xB3,0x81,0x56,0x56,0x38,0xEA,0x88,0xA9,0x6B,0xBD, -0xFD,0xEF,0x6B,0x1D,0x20,0x10,0x1D,0xA9,0x3D,0x21,0x32,0x88,0xE5,0x22,0xE4,0xE1,0x56,0xF4,0x21,0x85, -0xDB,0xA9,0xA8,0x48,0x00,0x4E,0xEE,0xA5,0x4D,0x2B,0x33,0x90,0x79,0x60,0xB4,0x12,0xED,0x9E,0x38,0x94, -0xEC,0x9F,0xA9,0x6A,0x73,0xAF,0x27,0x7B,0xFA,0x3A,0xC7,0x00,0xCD,0x53,0x40,0xB7,0xAA,0xFA,0x66,0xC2, -0x82,0xBB,0x46,0x55,0x94,0x1D,0xDE,0x1D,0x45,0x28,0xCB,0xDE,0xA0,0x18,0xD6,0xF7,0x63,0xDD,0x2C,0x4C, -0x69,0xDF,0xD9,0xDC,0x6C,0x23,0xA5,0x38,0x66,0x37,0x58,0x71,0x85,0x21,0x94,0xB9,0x01,0x10,0xDE,0xDC, -0x5C,0xC7,0x98,0xB8,0x50,0xFB,0x1A,0x57,0x14,0xDC,0xB5,0x0C,0x7F,0xFF,0x13,0x77,0x2A,0x47,0x3E,0xA4, -0xD5,0xC8,0xB4,0x04,0xF7,0x5F,0xBE,0x64,0xF2,0xEF,0x4A,0xA0,0x97,0xFE,0xB2,0xEA,0x2E,0x58,0xBA,0x04, -0xB8,0xDE,0x7D,0xAF,0xE0,0x66,0x36,0x27,0xDC,0x0F,0x85,0xBE,0x7D,0x94,0x61,0x5D,0xDC,0xD4,0xB9,0xB2, -0x35,0xFB,0x5C,0x34,0x3E,0x93,0xA4,0x68,0xCD,0xD1,0x4D,0xD1,0x8A,0x93,0xED,0xA2,0x95,0x04,0x53,0xDD, -0x55,0x45,0xE2,0x86,0xB3,0x2C,0x1A,0xFD,0xA5,0xDC,0xFA,0x68,0x55,0xC3,0xC7,0x6C,0x4E,0x85,0x02,0x2B, -0x2D,0x47,0x6B,0xF6,0xBE,0x4E,0x61,0x95,0xD3,0x05,0x05,0x5E,0x77,0x9A,0x2A,0x9F,0x6B,0xF8,0x47,0x09, -0x03,0xCF,0xC0,0x4B,0xF3,0xFF,0xB2,0x1A,0x5F,0x59,0xCD,0xCA,0x7E,0xAC,0x11,0xF2,0x28,0x84,0x5A,0xF2, -0x2F,0x24,0x8C,0x5B,0x2B,0xC4,0xB6,0x2F,0x9E,0x6F,0x58,0x20,0xA3,0x9F,0x69,0xE5,0x46,0x6C,0xFD,0x8F, -0x06,0x96,0xB4,0x0C,0xAC,0x5D,0x69,0x24,0x6B,0x76,0x0D,0x47,0x98,0xE3,0x4A,0xA2,0x64,0xAD,0x44,0xE9, -0xFF,0xA3,0xF9,0x3A,0x2C,0x11,0x75,0xAE,0x68,0x06,0xA6,0x80,0xDC,0xE8,0x90,0xA0,0xBD,0x36,0x85,0xCC, -0x4F,0x59,0x14,0x8D,0x59,0x72,0xF0,0xC0,0xB8,0x5B,0x8D,0x17,0x8D,0x92,0xCD,0x7A,0x8A,0xE5,0xAF,0x25, -0xFA,0x0A,0x4F,0xF9,0xC1,0x43,0x80,0x87,0xC9,0xD6,0x73,0xAC,0xC0,0xC3,0x36,0x28,0x0F,0x46,0x7F,0xE9, -0xF8,0x56,0x56,0xF5,0x2E,0x3B,0x0C,0xF6,0xC2,0x2F,0x95,0xE4,0x09,0x25,0x59,0x64,0x6D,0xBE,0xA8,0xC7, -0x23,0xA0,0xE8,0x05,0x1D,0x3D,0xB9,0xAD,0xC7,0x38,0x4B,0xBC,0x4C,0x0D,0x21,0x83,0x58,0xFC,0xDE,0xA6, -0xAC,0x8B,0xE2,0xA9,0x47,0x6C,0x36,0x9D,0x66,0x98,0xBF,0x17,0x19,0xC4,0x8A,0xAA,0xFE,0x33,0x99,0x41, -0x06,0xD0,0xA5,0x31,0xCB,0x33,0xCC,0x72,0xDE,0xAE,0x35,0x2B,0x61,0xF6,0x82,0x2F,0x5F,0xAA,0xCE,0x7E, -0xD0,0x49,0xEB,0xEE,0xE5,0x5E,0xD6,0xE8,0xEC,0x67,0x9D,0x08,0x3C,0xE9,0x3F,0xB6,0x14,0xD2,0xB4,0x14, -0x26,0x12,0x98,0xC5,0x94,0xA5,0xA4,0xB5,0xAD,0xA7,0xE2,0x24,0x80,0x1A,0x21,0x56,0x18,0xB4,0x6E,0x96, -0x87,0xDC,0xA6,0x2B,0x23,0x2B,0x6D,0x7B,0xFA,0x43,0xD5,0x76,0x60,0x08,0xAA,0xA0,0xF5,0x57,0x6C,0x8E, -0xD3,0x23,0x94,0x61,0x03,0x22,0x6F,0x95,0x26,0x24,0xD4,0x74,0xB3,0xB5,0xB3,0x68,0x01,0xF5,0xD5,0x13, -0xC2,0xCB,0x57,0xC3,0x02,0x4C,0x10,0x71,0x61,0x0D,0x25,0x73,0xA9,0xB8,0x63,0x54,0x9C,0x98,0x40,0x43, -0x79,0x8B,0x47,0x6C,0x8B,0x0B,0x1E,0xD0,0xDB,0xB1,0x3A,0x20,0x42,0x79,0x8D,0xC1,0x5A,0x58,0x72,0x96, -0xB2,0x04,0xCD,0x90,0x98,0x07,0x63,0xE0,0x60,0x92,0xB8,0xA0,0xD6,0xA8,0x88,0xEA,0xEB,0x86,0x6E,0xDF, -0x03,0x7B,0x95,0x97,0x39,0xA7,0x53,0x03,0x6A,0x27,0xB3,0x9E,0x16,0xFC,0x77,0x49,0x88,0xDF,0xF2,0x22, -0xBB,0x84,0x3C,0xAE,0x5B,0x51,0xD1,0xFC,0x94,0x15,0x0D,0x3F,0x2B,0x5B,0xB7,0x0D,0x20,0xA3,0x25,0x98, -0xD1,0x69,0xD1,0x24,0x94,0x94,0x74,0x4A,0x60,0xF9,0x4C,0x92,0x32,0x93,0x85,0x65,0x2B,0xC4,0xB7,0x15, -0x1E,0xAB,0xF2,0x1C,0x5E,0x97,0xE7,0xEA,0x5B,0x96,0xFF,0x4E,0xFC,0x84,0xCE,0x4A,0x61,0x92,0xB2,0x35, -0x23,0xA5,0x28,0x93,0x38,0xF9,0x2A,0x23,0xE9,0xBF,0x3D,0xF5,0x1D,0x9F,0xBC,0x3A,0x19,0x9F,0x34,0x0F, -0x00,0xCD,0xCB,0x21,0xFE,0x57,0xB7,0x2F,0xDC,0x74,0x8D,0xBF,0x91,0xD4,0xA0,0xEC,0x36,0xCD,0xD6,0xFD, -0x51,0xD4,0xBA,0x97,0xAA,0x33,0x4A,0x71,0xE1,0x03,0x7A,0xDA,0xDC,0x6C,0x30,0x22,0xC7,0xEB,0x3B,0x2D, -0x6A,0xE9,0xAA,0x0A,0x97,0x5E,0x8D,0x1E,0x2A,0x57,0x91,0x59,0x1D,0x08,0x89,0x47,0x8B,0x88,0x62,0x89, -0xB3,0x21,0xD9,0xF7,0xE1,0x50,0xD8,0x31,0xD5,0x5D,0x8E,0xE7,0xC1,0xB5,0x97,0x7F,0x25,0xEF,0x03,0x36, -0x37,0x51,0xBB,0xA4,0x35,0x1C,0x4B,0x02,0xC5,0x82,0xB2,0x25,0x6F,0x22,0x40,0x16,0x60,0xCB,0xB1,0x5E, -0x8C,0x4E,0xDF,0xD8,0x09,0x4A,0xC1,0x21,0xA9,0xD9,0x8C,0x46,0xB9,0x12,0xB0,0xAD,0xED,0xA7,0x27,0x8D, -0xB3,0x96,0x7C,0xDD,0xE7,0xF2,0xA5,0x15,0x19,0x82,0x9C,0xCA,0xD0,0xA2,0xEC,0x29,0xEE,0x65,0x21,0xC7, -0xC5,0x65,0xBE,0xAB,0xC3,0x55,0xDC,0xCC,0x16,0xFC,0x26,0x7F,0xE0,0x3A,0x81,0x87,0x24,0x6B,0x9E,0x31, -0x5B,0x91,0xE1,0x6F,0xEE,0xD8,0xB2,0x6C,0x29,0x72,0xF7,0x8F,0x4B,0xEA,0x45,0xB4,0xDA,0x1C,0x79,0x1C, -0x5E,0xD4,0xA1,0xB8,0x36,0x47,0x1D,0x52,0x18,0xA1,0xBA,0x45,0xFF,0xA9,0x87,0xD0,0xD2,0x43,0xE8,0x6A, -0x80,0xC0,0xB7,0x2D,0x6F,0xAF,0x56,0x19,0x4C,0x80,0xB3,0xEB,0x41,0x1D,0x45,0x00,0x02,0xCF,0xA8,0x05, -0xF8,0x94,0xC9,0xF1,0x4F,0xE8,0x06,0xA9,0x6B,0xD9,0x1A,0xBA,0x3E,0x54,0xC8,0xE9,0xFE,0xEF,0xD0,0xAA, -0x66,0xB6,0x03,0x51,0x06,0xCD,0xD5,0x78,0xC2,0x5B,0xE1,0xA9,0x8E,0x59,0xCD,0xE8,0x04,0xEE,0x5A,0x78, -0xB3,0xC6,0x1B,0xFA,0x6D,0xB8,0x1E,0x18,0xE4,0x43,0xBE,0xD7,0x8C,0xC3,0x0A,0xA3,0x69,0x3D,0xEB,0x0F, -0xA3,0xED,0xE3,0xEA,0xFA,0x3A,0x43,0xFA,0x1F,0x3E,0xC8,0xEC,0xAC,0xBC,0x98,0x01,0x37,0x6F,0xF4,0x74, -0x30,0x88,0x0C,0xCC,0x10,0xA3,0x74,0x24,0xEE,0x00,0x54,0x22,0x59,0xAA,0x0D,0xF4,0xA4,0xEB,0x1A,0xA0, -0xB1,0x9E,0x4C,0x19,0x36,0xE8,0x01,0xE6,0x57,0x40,0x0A,0x40,0xEA,0x31,0x20,0xD9,0x18,0x44,0x30,0x88, -0x3C,0x3D,0x66,0x94,0x5D,0x23,0xD2,0x9C,0x4E,0x00,0x42,0x8A,0xAF,0x04,0xF4,0x0E,0xB5,0x8A,0x7D,0x90, -0x84,0x6A,0x88,0xDA,0x7D,0xB3,0xB8,0xE5,0xAC,0xEF,0x98,0x70,0xE9,0x36,0x85,0x7D,0x6C,0x48,0xB4,0x4C, -0x14,0x1E,0x23,0x9C,0x65,0x92,0x6F,0x21,0xD7,0x6B,0x16,0x80,0x58,0x80,0xD6,0x8B,0xA1,0x25,0x16,0x02, -0x09,0x05,0x60,0x1C,0xE2,0xB8,0x80,0x70,0x68,0x0A,0x10,0x12,0xA0,0x6F,0xA5,0xAA,0x46,0xB2,0xC0,0x23, -0x74,0xE6,0xF5,0x7B,0x8E,0xB5,0x4A,0xF6,0x22,0xC3,0x23,0x36,0xE5,0x63,0x34,0xC9,0x8C,0x0D,0xC7,0x5C, -0x9D,0x21,0x40,0x23,0x88,0x26,0xC6,0x96,0xB9,0x1E,0xFD,0x3D,0x4B,0xAF,0x71,0x5A,0x20,0x8B,0xCA,0x0C, -0x0A,0xB3,0x08,0x7E,0xF9,0xD0,0x17,0x2F,0xFA,0x5F,0x11,0x8A,0x6B,0xE0,0x28,0x64,0xF3,0xB3,0x94,0x50, -0xFE,0x5A,0x1E,0xFA,0x8D,0x8D,0xBE,0xDC,0x27,0x75,0x17,0x25,0x23,0x50,0x79,0x49,0xB5,0x10,0xC1,0xCC, -0x6D,0x5D,0x55,0x59,0x13,0xD8,0x2E,0x88,0xAD,0xEE,0x62,0x4E,0xA8,0xAB,0x1F,0xF1,0x34,0xEA,0x8E,0x74, -0x2B,0x46,0x3E,0x74,0xD4,0x1C,0xE8,0x2F,0x2D,0xE1,0xB4,0x6E,0x33,0x98,0x6C,0xD4,0x9D,0xBA,0x50,0x5F, -0xB9,0xC7,0x6B,0x5F,0x4B,0x09,0xE0,0x61,0xC4,0x26,0x86,0x78,0xE7,0xB0,0x10,0x0E,0xEF,0xD2,0xA5,0x29, -0xB2,0xD3,0xD7,0xAF,0xDC,0x7C,0x88,0xBA,0xDC,0xC2,0x8D,0x1B,0xC3,0x8E,0xAE,0x8B,0x8B,0x38,0xC0,0x43, -0xC1,0x29,0x8D,0xEE,0x5C,0xC8,0x8A,0x7F,0x21,0x75,0x4E,0x03,0xF6,0x35,0xA9,0x3F,0xDC,0x93,0xFA,0xC3, -0x3A,0xA9,0x71,0x7B,0xB7,0xA0,0x73,0x01,0x64,0x5F,0x23,0x8A,0x66,0x38,0x85,0x01,0xB1,0x08,0x6C,0xC0, -0x3F,0xE3,0x2C,0xC5,0x5F,0xE7,0x6C,0x14,0x92,0x29,0x5F,0xE1,0x4F,0x8E,0xFE,0x3B,0x2E,0x53,0xFC,0x00, -0x97,0x65,0x21,0x5B,0xA5,0x8D,0xBF,0xBE,0x07,0x93,0x4E,0xED,0xC1,0x16,0x36,0xDD,0xF5,0x5F,0xF8,0x5D, -0xBD,0xE2,0xD7,0xB3,0xA7,0x78,0xB8,0x78,0x69,0x05,0xC2,0x26,0x40,0x82,0x46,0x7E,0x62,0xF4,0x10,0x4E, -0x0A,0xAF,0x40,0x04,0x43,0x99,0x23,0xF6,0x16,0x4B,0x8B,0x7B,0xC6,0x9C,0x80,0xF8,0x73,0x10,0xCE,0x97, -0xD5,0xAF,0x2D,0xBE,0x56,0x02,0x25,0x00,0x93,0x90,0x67,0x7B,0x1F,0x0F,0x36,0xAF,0x3A,0x90,0xA0,0x3C, -0x78,0x98,0x1E,0x34,0x36,0xAF,0x7E,0x30,0x7B,0x33,0xD2,0x28,0x89,0x64,0xAA,0x03,0xBD,0x7E,0xA4,0x57, -0x1E,0x5A,0x42,0x08,0x6B,0xA6,0xC2,0x2A,0xB0,0x5A,0x58,0x5E,0x69,0xC2,0x43,0x7C,0x04,0x06,0x0F,0x19, -0x3B,0x60,0x36,0xF5,0x1A,0x37,0x8D,0x3A,0x87,0xBF,0x3A,0x84,0xED,0x41,0xC1,0x56,0x80,0xA7,0x84,0x62, -0x19,0xBD,0x54,0xD3,0x2A,0x00,0x42,0x0D,0x24,0x95,0x90,0xB2,0x6D,0x89,0xB6,0xC8,0x7E,0x64,0x26,0x14, -0x69,0xE8,0xE2,0x83,0x0F,0x91,0xE8,0x75,0x99,0xB0,0x57,0xC0,0x73,0x19,0x48,0x1A,0x13,0xD6,0xBC,0xC0, -0xD3,0xF3,0xA2,0xA5,0x83,0x94,0xBC,0x11,0x84,0x95,0x38,0x10,0x6F,0x55,0xE3,0x5E,0x68,0xAF,0x4F,0x3D, -0x0A,0x6C,0x2E,0xC1,0xC5,0x94,0x00,0x81,0x5E,0xA5,0xF3,0x5F,0x5E,0xBF,0x7A,0xC6,0x79,0x72,0xAE,0x76, -0x14,0x68,0xB5,0x07,0x6A,0x43,0x33,0x17,0x3C,0xBD,0x2B,0x0B,0x43,0x11,0x28,0x54,0xA8,0xFB,0xE5,0x74, -0xF2,0x09,0xFB,0x20,0xC9,0xEB,0x0C,0x72,0xE8,0x96,0x2D,0xD0,0xC7,0xE3,0x33,0x7B,0xD7,0x76,0xA0,0x52, -0x81,0xFD,0xF4,0x43,0x61,0x31,0xCB,0x7F,0x84,0xBC,0xFD,0xCF,0x90,0x09,0xC4,0xFB,0x0C,0x02,0x7A,0x89, -0xDF,0xC6,0x0D,0x53,0x36,0x97,0x68,0x27,0x69,0x2A,0x8C,0x61,0x1C,0x92,0x4C,0x9B,0xC0,0x60,0x86,0x53, -0x2D,0x60,0x38,0xD3,0x28,0xE3,0x5A,0x96,0x27,0x09,0x4B,0xF9,0x3D,0x7D,0xD8,0x7A,0x79,0x49,0xF3,0x36, -0xC7,0x39,0x0E,0x8A,0x61,0x9C,0x36,0xF5,0x22,0x6B,0x3A,0x18,0x07,0x77,0xFB,0x78,0x55,0x54,0x78,0x39, -0xA5,0x22,0xFF,0x6C,0xF4,0x55,0x1F,0xA4,0x0B,0x81,0xAA,0x47,0xF3,0x28,0x5A,0x0E,0xEE,0xD1,0xB2,0x93, -0x94,0x71,0x26,0x5F,0x7A,0x2D,0x7E,0x2F,0x5C,0xCB,0xBD,0x77,0x4D,0xDF,0xA6,0xEA,0x58,0x1B,0xC6,0x06, -0xD6,0x08,0xCD,0x38,0xA2,0xBE,0xD8,0x46,0xA5,0x0B,0xB3,0xAC,0xEE,0xC4,0xF4,0x81,0x88,0x0B,0xD2,0x70, -0x1E,0x2C,0x29,0xA4,0x64,0xD4,0xD3,0x75,0x51,0xE8,0x61,0x51,0x2F,0xA3,0x38,0x6B,0x90,0xAD,0x32,0x85, -0x49,0xBD,0x12,0x3C,0x90,0x2F,0x57,0x9A,0xF3,0x57,0xD9,0x28,0xAB,0x7B,0x04,0x30,0xAD,0x9C,0x67,0xD2, -0x8E,0xA7,0xCB,0x0A,0xE1,0x40,0x86,0x0C,0x69,0xC0,0x31,0xE6,0x21,0x0B,0x0E,0xF4,0x03,0xDD,0xD5,0xE1, -0xFF,0xA6,0x6E,0xC1,0x2C,0x4C,0x7D,0x16,0xE0,0x8B,0xF3,0xE7,0x10,0x4A,0x13,0x46,0x31,0xE5,0x06,0x82, -0x8C,0xE2,0xE9,0x9D,0x55,0x48,0xC5,0xC6,0x47,0x74,0x65,0x0E,0xDA,0xCA,0xC6,0xF3,0x7B,0xDB,0xD9,0xDA, -0x0C,0x9B,0x51,0x11,0x5D,0xEF,0x80,0x79,0x8E,0x57,0x5E,0x8E,0x58,0x74,0xF5,0x14,0x64,0x2E,0x76,0x04, -0xCF,0x12,0x6B,0x04,0x58,0xC2,0xF5,0x6A,0x25,0x3F,0x54,0xD9,0x51,0xDB,0x47,0x51,0x24,0x3E,0xE6,0x00, -0x5E,0xC5,0x62,0x79,0x66,0x09,0x22,0x19,0x08,0x90,0xE1,0x31,0xBE,0x05,0x97,0x96,0xE5,0x99,0xB2,0xA1, -0xE2,0x38,0x04,0xA4,0x79,0xC3,0x8C,0x4C,0xAB,0xEA,0x6D,0x6E,0x72,0xBB,0x34,0x13,0xA3,0x44,0xCA,0x44, -0xB2,0x91,0x77,0x0F,0x4B,0xA3,0x29,0xA4,0xC8,0xDD,0x2B,0xDA,0x36,0xDA,0x6A,0x48,0x30,0x35,0x4A,0x18, -0x70,0x96,0xA7,0x11,0x64,0x08,0x51,0xBD,0xB4,0xA6,0x65,0x98,0x06,0xB0,0x80,0xFB,0x97,0xC8,0x12,0x95, -0x36,0xAD,0x62,0xC4,0x53,0xC5,0x77,0x9B,0x1E,0x2F,0x76,0xE5,0x19,0x96,0x61,0xAE,0xFD,0xF5,0xAD,0x25, -0xBF,0x9B,0x25,0x2A,0x21,0xF4,0xE0,0x6D,0xCA,0x7C,0xDE,0x05,0xB3,0x8A,0xBB,0xB0,0x82,0xB2,0x82,0x40, -0x5F,0xC3,0xA1,0x3A,0xED,0x59,0xE2,0x3A,0xC5,0xBD,0xE7,0xA2,0xB5,0xFE,0x8C,0x7B,0x3E,0xDA,0xA6,0xD3, -0xE6,0xB3,0xB1,0xDB,0x7B,0x3B,0xF7,0x40,0x68,0xC2,0x52,0x6E,0x40,0x8E,0x83,0x34,0x58,0xAD,0x56,0x1E, -0xBC,0x9A,0x71,0xC1,0x4E,0xF2,0x2C,0x34,0x16,0xC0,0xBA,0xCB,0x2D,0xA5,0x2B,0x17,0x5B,0xCA,0x6E,0x5D, -0x6A,0x95,0xF6,0xE1,0x42,0xEA,0x6A,0xC5,0x8F,0x2F,0x5F,0x64,0xAF,0xDE,0x6D,0xE8,0xB5,0x37,0x1C,0x84, -0x95,0x4E,0x5C,0x66,0x64,0x61,0xF4,0xF7,0x63,0xD5,0x5E,0x4F,0x9D,0xA7,0xCA,0xCF,0x5D,0x34,0x12,0x78, -0x22,0xB9,0xEB,0xC5,0x7B,0x2D,0x68,0x4E,0x21,0x2E,0xD9,0x70,0x00,0xAB,0xBE,0x6F,0xD6,0x8B,0x0F,0x9C, -0xEF,0xE3,0xEE,0x57,0x27,0x42,0xCF,0xAB,0xEA,0x79,0x15,0x75,0xD4,0x04,0xEF,0x81,0x8F,0x60,0x74,0x05, -0x86,0x03,0xB3,0x6A,0xD8,0xD5,0xDA,0x62,0x5D,0xAB,0x18,0x44,0xD9,0x1D,0xF5,0x45,0xD4,0xAC,0xA8,0x84, -0xA0,0xFE,0xD6,0x21,0x5A,0xCD,0x34,0x97,0x35,0x67,0xE2,0xFA,0x51,0x63,0xC5,0x5B,0x87,0x66,0x8D,0x01, -0xEC,0xC3,0x19,0x5D,0x88,0x5B,0xBA,0xA8,0x26,0x0F,0xE9,0x55,0x17,0xC4,0x83,0x09,0xF5,0xAC,0x3C,0x59, -0x0F,0x90,0x25,0xC1,0xCA,0xA0,0xAA,0x2A,0x56,0x86,0x8B,0x83,0x5E,0xF5,0x2E,0xB0,0xF1,0xFD,0x52,0x4D, -0x83,0xC8,0x57,0x27,0x72,0x7E,0xFB,0x6D,0xCA,0x83,0x68,0x0A,0x63,0xFF,0x4F,0x51,0x09,0xC4,0x79,0xD4, -0x2E,0x00,0x00 -}; From 765cf245a239f82537d9b4d2076d1718bf0c9d20 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Mon, 22 Jan 2024 21:55:08 +0100 Subject: [PATCH 126/551] Prepare v2.2.0 --- README.md | 3 ++- library.json | 1 + library.properties | 2 +- src/ESPAsyncWebServer.h | 6 +++--- 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 91cf7cca3..e5055eedc 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![License: LGPL 3.0](https://img.shields.io/badge/License-LGPL%203.0-yellow.svg)](https://opensource.org/license/lgpl-3-0/) [![Continuous Integration](https://github.com/mathieucarbou/ESPAsyncWebServer/actions/workflows/ci.yml/badge.svg)](https://github.com/mathieucarbou/ESPAsyncWebServer/actions/workflows/ci.yml) -[![PlatformIO Registry](https://badges.registry.platformio.org/packages/mathieucarbou/library/ESP Async WebServer.svg)](https://registry.platformio.org/libraries/mathieucarbou/ESP Async WebServer) +[![PlatformIO Registry](https://badges.registry.platformio.org/packages/mathieucarbou/library/ESP%20Async%20WebServer.svg)](https://registry.platformio.org/libraries/mathieucarbou/ESP%20Async%20WebServer) Async Web Server for ESP31B @@ -14,6 +14,7 @@ This fork is based on https://github.com/yubox-node-org/ESPAsyncWebServer and in - Arduino Json 7 compatibility - Deployed in PlatformIO registry and Arduino IDE library manager - CI +- Only supports ESP32 Usage and API stays the same as the original library. Please look at the original libraries for more examples and documentation. diff --git a/library.json b/library.json index 45b2d8e7c..24327ce87 100644 --- a/library.json +++ b/library.json @@ -1,5 +1,6 @@ { "name": "ESP Async WebServer", + "version": "2.2.0", "description": "Asynchronous HTTP and WebSocket Server Library for ESP32", "keywords": "http,async,websocket,webserver", "homepage": "https://github.com/mathieucarbou/ESPAsyncWebServer", diff --git a/library.properties b/library.properties index 790ba2c94..42445a6d4 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=ESP Async WebServer -version=2.1.2 +version=2.2.0 author=Me-No-Dev maintainer=Mathieu Carbou sentence=Asynchronous HTTP and WebSocket Server Library for ESP32 diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index 98928a671..22d748c9b 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -40,10 +40,10 @@ #error Platform not supported #endif -#define ASYNCWEBSERVER_VERSION "2.1.2" +#define ASYNCWEBSERVER_VERSION "2.2.0" #define ASYNCWEBSERVER_VERSION_MAJOR 2 -#define ASYNCWEBSERVER_VERSION_MINOR 1 -#define ASYNCWEBSERVER_VERSION_REVISION 2 +#define ASYNCWEBSERVER_VERSION_MINOR 2 +#define ASYNCWEBSERVER_VERSION_REVISION 0 #define ASYNCWEBSERVER_FORK_mathieucarbou #ifdef ASYNCWEBSERVER_REGEX From 65142c4b0007d5f7141b921289e217dbad924976 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Mon, 22 Jan 2024 22:10:21 +0100 Subject: [PATCH 127/551] Rename to ESPAsyncWebServer to adhere to Arduino naming convention --- README.md | 2 +- library.json | 2 +- library.properties | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index e5055eedc..dada35f17 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# ESP Async WebServer +# ESPAsyncWebServer [![License: LGPL 3.0](https://img.shields.io/badge/License-LGPL%203.0-yellow.svg)](https://opensource.org/license/lgpl-3-0/) [![Continuous Integration](https://github.com/mathieucarbou/ESPAsyncWebServer/actions/workflows/ci.yml/badge.svg)](https://github.com/mathieucarbou/ESPAsyncWebServer/actions/workflows/ci.yml) diff --git a/library.json b/library.json index 24327ce87..a7944792d 100644 --- a/library.json +++ b/library.json @@ -1,5 +1,5 @@ { - "name": "ESP Async WebServer", + "name": "ESPAsyncWebServer", "version": "2.2.0", "description": "Asynchronous HTTP and WebSocket Server Library for ESP32", "keywords": "http,async,websocket,webserver", diff --git a/library.properties b/library.properties index 42445a6d4..289e14515 100644 --- a/library.properties +++ b/library.properties @@ -1,4 +1,4 @@ -name=ESP Async WebServer +name=ESPAsyncWebServer version=2.2.0 author=Me-No-Dev maintainer=Mathieu Carbou From 9c2540a656c911ce0883fc5518f07e372ea59630 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Mon, 22 Jan 2024 22:11:13 +0100 Subject: [PATCH 128/551] Prepare v2.3.0 --- library.json | 2 +- library.properties | 2 +- src/ESPAsyncWebServer.h | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/library.json b/library.json index a7944792d..71f5d45c0 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "ESPAsyncWebServer", - "version": "2.2.0", + "version": "2.3.0", "description": "Asynchronous HTTP and WebSocket Server Library for ESP32", "keywords": "http,async,websocket,webserver", "homepage": "https://github.com/mathieucarbou/ESPAsyncWebServer", diff --git a/library.properties b/library.properties index 289e14515..6b8d32cbc 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=ESPAsyncWebServer -version=2.2.0 +version=2.3.0 author=Me-No-Dev maintainer=Mathieu Carbou sentence=Asynchronous HTTP and WebSocket Server Library for ESP32 diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index 22d748c9b..f60192f12 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -40,9 +40,9 @@ #error Platform not supported #endif -#define ASYNCWEBSERVER_VERSION "2.2.0" +#define ASYNCWEBSERVER_VERSION "2.3.0" #define ASYNCWEBSERVER_VERSION_MAJOR 2 -#define ASYNCWEBSERVER_VERSION_MINOR 2 +#define ASYNCWEBSERVER_VERSION_MINOR 3 #define ASYNCWEBSERVER_VERSION_REVISION 0 #define ASYNCWEBSERVER_FORK_mathieucarbou From 473ba03c8856acb1724a0c9a6583b00eec93d7b0 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Tue, 23 Jan 2024 00:07:47 +0100 Subject: [PATCH 129/551] Fix README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index dada35f17..4b7a025d0 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![License: LGPL 3.0](https://img.shields.io/badge/License-LGPL%203.0-yellow.svg)](https://opensource.org/license/lgpl-3-0/) [![Continuous Integration](https://github.com/mathieucarbou/ESPAsyncWebServer/actions/workflows/ci.yml/badge.svg)](https://github.com/mathieucarbou/ESPAsyncWebServer/actions/workflows/ci.yml) -[![PlatformIO Registry](https://badges.registry.platformio.org/packages/mathieucarbou/library/ESP%20Async%20WebServer.svg)](https://registry.platformio.org/libraries/mathieucarbou/ESP%20Async%20WebServer) +[![PlatformIO Registry](https://badges.registry.platformio.org/packages/mathieucarbou/library/ESPAsyncWebServer.svg)](https://registry.platformio.org/libraries/mathieucarbou/ESPAsyncWebServer) Async Web Server for ESP31B From 63ce0ab12037e144e4a396aaf99acf18e08d1281 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Tue, 23 Jan 2024 00:30:14 +0100 Subject: [PATCH 130/551] Revert "Rename to ESPAsyncWebServer to adhere to Arduino naming convention" This reverts commit 65142c4b0007d5f7141b921289e217dbad924976. --- README.md | 2 +- library.json | 2 +- library.properties | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 4b7a025d0..d0f68ef48 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# ESPAsyncWebServer +# ESP Async WebServer [![License: LGPL 3.0](https://img.shields.io/badge/License-LGPL%203.0-yellow.svg)](https://opensource.org/license/lgpl-3-0/) [![Continuous Integration](https://github.com/mathieucarbou/ESPAsyncWebServer/actions/workflows/ci.yml/badge.svg)](https://github.com/mathieucarbou/ESPAsyncWebServer/actions/workflows/ci.yml) diff --git a/library.json b/library.json index 71f5d45c0..7775810f9 100644 --- a/library.json +++ b/library.json @@ -1,5 +1,5 @@ { - "name": "ESPAsyncWebServer", + "name": "ESP Async WebServer", "version": "2.3.0", "description": "Asynchronous HTTP and WebSocket Server Library for ESP32", "keywords": "http,async,websocket,webserver", diff --git a/library.properties b/library.properties index 6b8d32cbc..eac430589 100644 --- a/library.properties +++ b/library.properties @@ -1,4 +1,4 @@ -name=ESPAsyncWebServer +name=ESP Async WebServer version=2.3.0 author=Me-No-Dev maintainer=Mathieu Carbou From fabe3f621dc739f9c1b63a249c661a36af0b1962 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Tue, 23 Jan 2024 00:31:16 +0100 Subject: [PATCH 131/551] v2.4.0 --- library.json | 2 +- library.properties | 2 +- src/ESPAsyncWebServer.h | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/library.json b/library.json index 7775810f9..0ce3ecc79 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "ESP Async WebServer", - "version": "2.3.0", + "version": "2.4.0", "description": "Asynchronous HTTP and WebSocket Server Library for ESP32", "keywords": "http,async,websocket,webserver", "homepage": "https://github.com/mathieucarbou/ESPAsyncWebServer", diff --git a/library.properties b/library.properties index eac430589..b0ef85326 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=ESP Async WebServer -version=2.3.0 +version=2.4.0 author=Me-No-Dev maintainer=Mathieu Carbou sentence=Asynchronous HTTP and WebSocket Server Library for ESP32 diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index f60192f12..d6a6beb50 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -40,9 +40,9 @@ #error Platform not supported #endif -#define ASYNCWEBSERVER_VERSION "2.3.0" +#define ASYNCWEBSERVER_VERSION "2.4.0" #define ASYNCWEBSERVER_VERSION_MAJOR 2 -#define ASYNCWEBSERVER_VERSION_MINOR 3 +#define ASYNCWEBSERVER_VERSION_MINOR 4 #define ASYNCWEBSERVER_VERSION_REVISION 0 #define ASYNCWEBSERVER_FORK_mathieucarbou From 977e2887333199cf7df14ba6cbd2313aa4e420ab Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Tue, 23 Jan 2024 00:34:22 +0100 Subject: [PATCH 132/551] Revert "Fix README" This reverts commit 473ba03c8856acb1724a0c9a6583b00eec93d7b0. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d0f68ef48..e5055eedc 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![License: LGPL 3.0](https://img.shields.io/badge/License-LGPL%203.0-yellow.svg)](https://opensource.org/license/lgpl-3-0/) [![Continuous Integration](https://github.com/mathieucarbou/ESPAsyncWebServer/actions/workflows/ci.yml/badge.svg)](https://github.com/mathieucarbou/ESPAsyncWebServer/actions/workflows/ci.yml) -[![PlatformIO Registry](https://badges.registry.platformio.org/packages/mathieucarbou/library/ESPAsyncWebServer.svg)](https://registry.platformio.org/libraries/mathieucarbou/ESPAsyncWebServer) +[![PlatformIO Registry](https://badges.registry.platformio.org/packages/mathieucarbou/library/ESP%20Async%20WebServer.svg)](https://registry.platformio.org/libraries/mathieucarbou/ESP%20Async%20WebServer) Async Web Server for ESP31B From 4a205091a049df06f458ad6c9bfb81f2633618af Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Tue, 23 Jan 2024 00:38:03 +0100 Subject: [PATCH 133/551] v2.4.1 --- library.json | 2 +- library.properties | 2 +- src/ESPAsyncWebServer.h | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/library.json b/library.json index 0ce3ecc79..bbfd3f96a 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "ESP Async WebServer", - "version": "2.4.0", + "version": "2.4.1", "description": "Asynchronous HTTP and WebSocket Server Library for ESP32", "keywords": "http,async,websocket,webserver", "homepage": "https://github.com/mathieucarbou/ESPAsyncWebServer", diff --git a/library.properties b/library.properties index b0ef85326..5d0a96913 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=ESP Async WebServer -version=2.4.0 +version=2.4.1 author=Me-No-Dev maintainer=Mathieu Carbou sentence=Asynchronous HTTP and WebSocket Server Library for ESP32 diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index d6a6beb50..ec0137c79 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -40,10 +40,10 @@ #error Platform not supported #endif -#define ASYNCWEBSERVER_VERSION "2.4.0" +#define ASYNCWEBSERVER_VERSION "2.4.1" #define ASYNCWEBSERVER_VERSION_MAJOR 2 #define ASYNCWEBSERVER_VERSION_MINOR 4 -#define ASYNCWEBSERVER_VERSION_REVISION 0 +#define ASYNCWEBSERVER_VERSION_REVISION 1 #define ASYNCWEBSERVER_FORK_mathieucarbou #ifdef ASYNCWEBSERVER_REGEX From 5ee0f1acfb6be5f62c043a7180890d48b32951ee Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Tue, 23 Jan 2024 09:16:21 +0100 Subject: [PATCH 134/551] Some fixes to please Arduino Lint --- ESP_Async_WebServer.h | 1 + library.json | 4 ++-- library.properties | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) create mode 100644 ESP_Async_WebServer.h diff --git a/ESP_Async_WebServer.h b/ESP_Async_WebServer.h new file mode 100644 index 000000000..11e054c5f --- /dev/null +++ b/ESP_Async_WebServer.h @@ -0,0 +1 @@ +#include "src/ESPAsyncWebServer.h" diff --git a/library.json b/library.json index bbfd3f96a..a20690836 100644 --- a/library.json +++ b/library.json @@ -1,7 +1,7 @@ { "name": "ESP Async WebServer", "version": "2.4.1", - "description": "Asynchronous HTTP and WebSocket Server Library for ESP32", + "description": "Asynchronous HTTP and WebSocket Server Library for ESP32. Supports: WebSocket, SSE, Authentication, Arduino Json 7, File Upload, Static File serving, URL Rewrite, URL Redirect, etc.", "keywords": "http,async,websocket,webserver", "homepage": "https://github.com/mathieucarbou/ESPAsyncWebServer", "repository": { @@ -10,7 +10,7 @@ }, "authors": [ { - "name": "Me-No-Dev" + "name": "Hristo Gochkov" }, { "name": "Mathieu Carbou", diff --git a/library.properties b/library.properties index 5d0a96913..785ce4006 100644 --- a/library.properties +++ b/library.properties @@ -3,7 +3,7 @@ version=2.4.1 author=Me-No-Dev maintainer=Mathieu Carbou sentence=Asynchronous HTTP and WebSocket Server Library for ESP32 -paragraph= +paragraph=Supports: WebSocket, SSE, Authentication, Arduino Json 7, File Upload, Static File serving, URL Rewrite, URL Redirect, etc category=Other url=https://github.com/mathieucarbou/ESPAsyncWebServer architectures==esp32 From fe67eb83d5854ad315832e3882016b9019567215 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Tue, 23 Jan 2024 09:17:50 +0100 Subject: [PATCH 135/551] Please Arduino Lint --- ESPAsyncWebServer.h | 1 + ESP_Async_WebServer.h | 1 + 2 files changed, 2 insertions(+) create mode 100644 ESPAsyncWebServer.h diff --git a/ESPAsyncWebServer.h b/ESPAsyncWebServer.h new file mode 100644 index 000000000..11e054c5f --- /dev/null +++ b/ESPAsyncWebServer.h @@ -0,0 +1 @@ +#include "src/ESPAsyncWebServer.h" diff --git a/ESP_Async_WebServer.h b/ESP_Async_WebServer.h index 11e054c5f..ffcd9880b 100644 --- a/ESP_Async_WebServer.h +++ b/ESP_Async_WebServer.h @@ -1 +1,2 @@ +// to please Arduino Lint #include "src/ESPAsyncWebServer.h" From e2ce968ecb5c256a8b43ab739e42627c82c4beb1 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Tue, 23 Jan 2024 09:21:12 +0100 Subject: [PATCH 136/551] v2.4.2 --- library.json | 2 +- library.properties | 2 +- src/ESPAsyncWebServer.h | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/library.json b/library.json index a20690836..8da50cb54 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "ESP Async WebServer", - "version": "2.4.1", + "version": "2.4.2", "description": "Asynchronous HTTP and WebSocket Server Library for ESP32. Supports: WebSocket, SSE, Authentication, Arduino Json 7, File Upload, Static File serving, URL Rewrite, URL Redirect, etc.", "keywords": "http,async,websocket,webserver", "homepage": "https://github.com/mathieucarbou/ESPAsyncWebServer", diff --git a/library.properties b/library.properties index 785ce4006..da185e50a 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=ESP Async WebServer -version=2.4.1 +version=2.4.2 author=Me-No-Dev maintainer=Mathieu Carbou sentence=Asynchronous HTTP and WebSocket Server Library for ESP32 diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index ec0137c79..14380d785 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -40,10 +40,10 @@ #error Platform not supported #endif -#define ASYNCWEBSERVER_VERSION "2.4.1" +#define ASYNCWEBSERVER_VERSION "2.4.2" #define ASYNCWEBSERVER_VERSION_MAJOR 2 #define ASYNCWEBSERVER_VERSION_MINOR 4 -#define ASYNCWEBSERVER_VERSION_REVISION 1 +#define ASYNCWEBSERVER_VERSION_REVISION 2 #define ASYNCWEBSERVER_FORK_mathieucarbou #ifdef ASYNCWEBSERVER_REGEX From 13a31939f203fcc232881e5c908177c91e7eab32 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Tue, 23 Jan 2024 10:52:24 +0100 Subject: [PATCH 137/551] Add website --- docs/_config.yml | 8 ++++++++ docs/index.md | 20 ++++++++++++++++++++ 2 files changed, 28 insertions(+) create mode 100644 docs/_config.yml create mode 100644 docs/index.md diff --git a/docs/_config.yml b/docs/_config.yml new file mode 100644 index 000000000..4750b0943 --- /dev/null +++ b/docs/_config.yml @@ -0,0 +1,8 @@ +# bundle exec jekyll serve --host=0.0.0.0 + +title: Asynchronous HTTP and WebSocket Server Library for ESP32 +description: "Supports: WebSocket, SSE, Authentication, Arduino Json 7, File Upload, Static File serving, URL Rewrite, URL Redirect, etc" +remote_theme: pages-themes/cayman@v0.2.0 +plugins: + - jekyll-remote-theme + \ No newline at end of file diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 000000000..e5055eedc --- /dev/null +++ b/docs/index.md @@ -0,0 +1,20 @@ +# ESP Async WebServer + +[![License: LGPL 3.0](https://img.shields.io/badge/License-LGPL%203.0-yellow.svg)](https://opensource.org/license/lgpl-3-0/) +[![Continuous Integration](https://github.com/mathieucarbou/ESPAsyncWebServer/actions/workflows/ci.yml/badge.svg)](https://github.com/mathieucarbou/ESPAsyncWebServer/actions/workflows/ci.yml) +[![PlatformIO Registry](https://badges.registry.platformio.org/packages/mathieucarbou/library/ESP%20Async%20WebServer.svg)](https://registry.platformio.org/libraries/mathieucarbou/ESP%20Async%20WebServer) + +Async Web Server for ESP31B + +This fork is based on https://github.com/yubox-node-org/ESPAsyncWebServer and includes all the concurrency fixes. + +## Changes + +- SPIFFSEditor is removed +- Arduino Json 7 compatibility +- Deployed in PlatformIO registry and Arduino IDE library manager +- CI +- Only supports ESP32 + +Usage and API stays the same as the original library. +Please look at the original libraries for more examples and documentation. From b5b26b93791905987311a4e9df0586a3f11cf993 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Tue, 23 Jan 2024 11:43:48 +0100 Subject: [PATCH 138/551] Try fix Arduino Lint Rule LS008 --- ESPAsyncWebServer.h | 1 - ESP_Async_WebServer.h | 2 -- src/ESP_Async_WebServer.h | 2 ++ 3 files changed, 2 insertions(+), 3 deletions(-) delete mode 100644 ESPAsyncWebServer.h delete mode 100644 ESP_Async_WebServer.h create mode 100644 src/ESP_Async_WebServer.h diff --git a/ESPAsyncWebServer.h b/ESPAsyncWebServer.h deleted file mode 100644 index 11e054c5f..000000000 --- a/ESPAsyncWebServer.h +++ /dev/null @@ -1 +0,0 @@ -#include "src/ESPAsyncWebServer.h" diff --git a/ESP_Async_WebServer.h b/ESP_Async_WebServer.h deleted file mode 100644 index ffcd9880b..000000000 --- a/ESP_Async_WebServer.h +++ /dev/null @@ -1,2 +0,0 @@ -// to please Arduino Lint -#include "src/ESPAsyncWebServer.h" diff --git a/src/ESP_Async_WebServer.h b/src/ESP_Async_WebServer.h new file mode 100644 index 000000000..ca6a11262 --- /dev/null +++ b/src/ESP_Async_WebServer.h @@ -0,0 +1,2 @@ +// to please Arduino Lint +#include "ESPAsyncWebServer.h" From 9b752a2feed9c742e3bf6278c1ef230b64a8e6ee Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Tue, 23 Jan 2024 11:51:32 +0100 Subject: [PATCH 139/551] Add Arduino Lint to CI --- .github/workflows/ci.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3c2a08c2b..d748c9c42 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -29,6 +29,11 @@ jobs: - name: Checkout uses: actions/checkout@v4 + - name: Arduino Lint + uses: arduino/arduino-lint-action@v1 + with: + library-manager: update + - name: Install arduino-cli run: curl -fsSL https://raw.githubusercontent.com/arduino/arduino-cli/master/install.sh | BINDIR=/usr/local/bin sh From 9ff7946071f05faf314cc992131073840be584e6 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Tue, 23 Jan 2024 11:57:02 +0100 Subject: [PATCH 140/551] Fix architectures --- library.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library.properties b/library.properties index da185e50a..7046b17db 100644 --- a/library.properties +++ b/library.properties @@ -6,6 +6,6 @@ sentence=Asynchronous HTTP and WebSocket Server Library for ESP32 paragraph=Supports: WebSocket, SSE, Authentication, Arduino Json 7, File Upload, Static File serving, URL Rewrite, URL Redirect, etc category=Other url=https://github.com/mathieucarbou/ESPAsyncWebServer -architectures==esp32 +architectures=esp32 license=LGPL-3.0 depends=ArduinoJson From 50b0e3698c091ff26e7c79f179d2806b4135faa7 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Tue, 23 Jan 2024 11:59:31 +0100 Subject: [PATCH 141/551] v2.4.3 --- library.json | 2 +- library.properties | 2 +- src/ESPAsyncWebServer.h | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/library.json b/library.json index 8da50cb54..325b6d3e5 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "ESP Async WebServer", - "version": "2.4.2", + "version": "2.4.3", "description": "Asynchronous HTTP and WebSocket Server Library for ESP32. Supports: WebSocket, SSE, Authentication, Arduino Json 7, File Upload, Static File serving, URL Rewrite, URL Redirect, etc.", "keywords": "http,async,websocket,webserver", "homepage": "https://github.com/mathieucarbou/ESPAsyncWebServer", diff --git a/library.properties b/library.properties index 7046b17db..93cd8060b 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=ESP Async WebServer -version=2.4.2 +version=2.4.3 author=Me-No-Dev maintainer=Mathieu Carbou sentence=Asynchronous HTTP and WebSocket Server Library for ESP32 diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index 14380d785..1c1a7aedd 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -40,10 +40,10 @@ #error Platform not supported #endif -#define ASYNCWEBSERVER_VERSION "2.4.2" +#define ASYNCWEBSERVER_VERSION "2.4.3" #define ASYNCWEBSERVER_VERSION_MAJOR 2 #define ASYNCWEBSERVER_VERSION_MINOR 4 -#define ASYNCWEBSERVER_VERSION_REVISION 2 +#define ASYNCWEBSERVER_VERSION_REVISION 3 #define ASYNCWEBSERVER_FORK_mathieucarbou #ifdef ASYNCWEBSERVER_REGEX From 8a4b01bdd60c34990dabb986902723e6ea72d21a Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Thu, 25 Jan 2024 16:20:28 +0100 Subject: [PATCH 142/551] Doc update --- README.md | 38 +++++++++++++++++++++++++++++++++++++- docs/index.md | 38 +++++++++++++++++++++++++++++++++++++- 2 files changed, 74 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index e5055eedc..9cf1e0e03 100644 --- a/README.md +++ b/README.md @@ -16,5 +16,41 @@ This fork is based on https://github.com/yubox-node-org/ESPAsyncWebServer and in - CI - Only supports ESP32 -Usage and API stays the same as the original library. +## Documentation + +Usage and API stays the same as the original library. Please look at the original libraries for more examples and documentation. + +[https://github.com/yubox-node-org/ESPAsyncWebServer](https://github.com/yubox-node-org/ESPAsyncWebServer) + +## Pitfalls + +The fork from yubox introduces some breaking API changes compared to the original library, especially regarding the use of `std::shared_ptr>` for WebSocket. +Thanks to this fork, you can handle them by using `ASYNCWEBSERVER_FORK_mathieucarbou`. + +Here is an example for serializing a Json document in a websocket message buffer directly. +This code is compatible with both forks. + +```cpp +void send(JsonDocument& doc) { + const size_t len = measureJson(doc); + +#if defined(ASYNCWEBSERVER_FORK_mathieucarbou) + + // this fork (originally from yubox-node-org), uses another API with shared pointer that better support concurrent use cases then the original project + auto buffer = std::make_shared>(len); + assert(buffer); // up to you to keep or remove this + serializeJson(doc, buffer->data(), len); + _ws->textAll(std::move(buffer)); + +#else + + // original API from me-no-dev + AsyncWebSocketMessageBuffer* buffer = _ws->makeBuffer(len); + assert(buffer); // up to you to keep or remove this + serializeJson(doc, buffer->get(), len); + _ws->textAll(buffer); + +#endif +} +``` diff --git a/docs/index.md b/docs/index.md index e5055eedc..9cf1e0e03 100644 --- a/docs/index.md +++ b/docs/index.md @@ -16,5 +16,41 @@ This fork is based on https://github.com/yubox-node-org/ESPAsyncWebServer and in - CI - Only supports ESP32 -Usage and API stays the same as the original library. +## Documentation + +Usage and API stays the same as the original library. Please look at the original libraries for more examples and documentation. + +[https://github.com/yubox-node-org/ESPAsyncWebServer](https://github.com/yubox-node-org/ESPAsyncWebServer) + +## Pitfalls + +The fork from yubox introduces some breaking API changes compared to the original library, especially regarding the use of `std::shared_ptr>` for WebSocket. +Thanks to this fork, you can handle them by using `ASYNCWEBSERVER_FORK_mathieucarbou`. + +Here is an example for serializing a Json document in a websocket message buffer directly. +This code is compatible with both forks. + +```cpp +void send(JsonDocument& doc) { + const size_t len = measureJson(doc); + +#if defined(ASYNCWEBSERVER_FORK_mathieucarbou) + + // this fork (originally from yubox-node-org), uses another API with shared pointer that better support concurrent use cases then the original project + auto buffer = std::make_shared>(len); + assert(buffer); // up to you to keep or remove this + serializeJson(doc, buffer->data(), len); + _ws->textAll(std::move(buffer)); + +#else + + // original API from me-no-dev + AsyncWebSocketMessageBuffer* buffer = _ws->makeBuffer(len); + assert(buffer); // up to you to keep or remove this + serializeJson(doc, buffer->get(), len); + _ws->textAll(buffer); + +#endif +} +``` From 13d6e5bafeb8e4c654a238fd3b22468c5d898cd7 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Thu, 25 Jan 2024 17:26:54 +0100 Subject: [PATCH 143/551] Fix packaging --- library.json | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/library.json b/library.json index 325b6d3e5..bf39beb1b 100644 --- a/library.json +++ b/library.json @@ -37,5 +37,15 @@ "espressif32" ] } - ] + ], + "export": { + "include": [ + "examples", + "src", + "library.json", + "library.properties", + "LICENSE", + "README.md" + ] + } } \ No newline at end of file From dba25ab71d515bc02ec8ab1d306f7418e4f7bc0b Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Thu, 25 Jan 2024 17:34:16 +0100 Subject: [PATCH 144/551] v2.4.4 --- library.json | 2 +- library.properties | 2 +- src/ESPAsyncWebServer.h | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/library.json b/library.json index bf39beb1b..22ff7da10 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "ESP Async WebServer", - "version": "2.4.3", + "version": "2.4.4", "description": "Asynchronous HTTP and WebSocket Server Library for ESP32. Supports: WebSocket, SSE, Authentication, Arduino Json 7, File Upload, Static File serving, URL Rewrite, URL Redirect, etc.", "keywords": "http,async,websocket,webserver", "homepage": "https://github.com/mathieucarbou/ESPAsyncWebServer", diff --git a/library.properties b/library.properties index 93cd8060b..f41ea3d7f 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=ESP Async WebServer -version=2.4.3 +version=2.4.4 author=Me-No-Dev maintainer=Mathieu Carbou sentence=Asynchronous HTTP and WebSocket Server Library for ESP32 diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index 1c1a7aedd..9f5b7c900 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -40,10 +40,10 @@ #error Platform not supported #endif -#define ASYNCWEBSERVER_VERSION "2.4.3" +#define ASYNCWEBSERVER_VERSION "2.4.4" #define ASYNCWEBSERVER_VERSION_MAJOR 2 #define ASYNCWEBSERVER_VERSION_MINOR 4 -#define ASYNCWEBSERVER_VERSION_REVISION 3 +#define ASYNCWEBSERVER_VERSION_REVISION 4 #define ASYNCWEBSERVER_FORK_mathieucarbou #ifdef ASYNCWEBSERVER_REGEX From 0d96aac454c1777be83af6c9bae791dfe417d177 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Thu, 25 Jan 2024 21:23:48 +0100 Subject: [PATCH 145/551] SSE: Make SSE_MAX_QUEUED_MESSAGES configurable and renamed public _write => write --- src/AsyncEventSource.cpp | 4 ++-- src/AsyncEventSource.h | 18 ++++++++++++------ 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/src/AsyncEventSource.cpp b/src/AsyncEventSource.cpp index b5d72fadd..fdafb1b7a 100644 --- a/src/AsyncEventSource.cpp +++ b/src/AsyncEventSource.cpp @@ -236,7 +236,7 @@ void AsyncEventSourceClient::close(){ _client->close(); } -void AsyncEventSourceClient::_write(const char * message, size_t len){ +void AsyncEventSourceClient::write(const char * message, size_t len){ _queueMessage(new AsyncEventSourceMessage(message, len)); } @@ -344,7 +344,7 @@ void AsyncEventSource::send( AsyncWebLockGuard l(_client_queue_lock); for(const auto &c: _clients){ if(c->connected()) { - c->_write(ev.c_str(), ev.length()); + c->write(ev.c_str(), ev.length()); } } } diff --git a/src/AsyncEventSource.h b/src/AsyncEventSource.h index abb1829c7..18868bafc 100644 --- a/src/AsyncEventSource.h +++ b/src/AsyncEventSource.h @@ -23,11 +23,16 @@ #include #ifdef ESP32 #include +#ifndef SSE_MAX_QUEUED_MESSAGES #define SSE_MAX_QUEUED_MESSAGES 32 +#endif #else #include +#ifndef SSE_MAX_QUEUED_MESSAGES #define SSE_MAX_QUEUED_MESSAGES 8 #endif +#endif + #include #include "AsyncWebSynchronization.h" @@ -53,11 +58,11 @@ typedef std::function ArAuthorizeConnectHa class AsyncEventSourceMessage { private: - uint8_t * _data; + uint8_t * _data; size_t _len; size_t _sent; //size_t _ack; - size_t _acked; + size_t _acked; public: AsyncEventSourceMessage(const char * data, size_t len); ~AsyncEventSourceMessage(); @@ -85,15 +90,15 @@ class AsyncEventSourceClient { AsyncClient* client(){ return _client; } void close(); + void write(const char * message, size_t len); void send(const char *message, const char *event=NULL, uint32_t id=0, uint32_t reconnect=0); bool connected() const { return (_client != NULL) && _client->connected(); } uint32_t lastId() const { return _lastId; } size_t packetsWaiting() const; - void _write(const char * message, size_t len); //system callbacks (do not call) void _onAck(size_t len, uint32_t time); - void _onPoll(); + void _onPoll(); void _onTimeout(uint32_t time); void _onDisconnect(); }; @@ -106,7 +111,7 @@ class AsyncEventSource: public AsyncWebHandler { // since simultaneous access from different tasks is possible AsyncWebLock _client_queue_lock; ArEventHandlerFunction _connectcb; - ArAuthorizeConnectHandler _authorizeConnectHandler; + ArAuthorizeConnectHandler _authorizeConnectHandler; public: AsyncEventSource(const String& url); ~AsyncEventSource(); @@ -116,7 +121,8 @@ class AsyncEventSource: public AsyncWebHandler { void onConnect(ArEventHandlerFunction cb); void authorizeConnect(ArAuthorizeConnectHandler cb); void send(const char *message, const char *event=NULL, uint32_t id=0, uint32_t reconnect=0); - size_t count() const; //number clients connected + // number of clients connected + size_t count() const; size_t avgPacketsWaiting() const; //system callbacks (do not call) From 984284d620e993bafbb6371c1084813c2647607c Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Thu, 25 Jan 2024 23:42:12 +0100 Subject: [PATCH 146/551] API Compatibility with `AsyncWebSocketMessageBuffer` and `makeBuffer()` --- README.md | 27 +++++++++++--- src/AsyncWebSocket.cpp | 81 ++++++++++++++++++++++++++++++++++++++---- src/AsyncWebSocket.h | 26 ++++++++++++++ 3 files changed, 122 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 9cf1e0e03..8b213e81d 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,7 @@ This fork is based on https://github.com/yubox-node-org/ESPAsyncWebServer and in - Deployed in PlatformIO registry and Arduino IDE library manager - CI - Only supports ESP32 +- Resurrected `AsyncWebSocketMessageBuffer` and `makeBuffer()` in order to make the fork API-compatible with the original library from me-no-dev regarding WebSocket. ## Documentation @@ -23,13 +24,29 @@ Please look at the original libraries for more examples and documentation. [https://github.com/yubox-node-org/ESPAsyncWebServer](https://github.com/yubox-node-org/ESPAsyncWebServer) -## Pitfalls +## `AsyncWebSocketMessageBuffer` and `makeBuffer()` -The fork from yubox introduces some breaking API changes compared to the original library, especially regarding the use of `std::shared_ptr>` for WebSocket. -Thanks to this fork, you can handle them by using `ASYNCWEBSERVER_FORK_mathieucarbou`. +The fork from `yubox-node-org` introduces some breaking API changes compared to the original library, especially regarding the use of `std::shared_ptr>` for WebSocket. -Here is an example for serializing a Json document in a websocket message buffer directly. -This code is compatible with both forks. +This fork is compatible with the original library from `me-no-dev` regarding WebSocket, and wraps the optimizations done by `yubox-node-org` in the `AsyncWebSocketMessageBuffer` class. +So you have the choice of which API to use. +I strongly suggest to use the optimized API from `yubox-node-org` as it is much more efficient. + +Here is an example for serializing a Json document in a websocket message buffer. This code is compatible with any forks, but not optimized: + +```cpp +void send(JsonDocument& doc) { + const size_t len = measureJson(doc); + + // original API from me-no-dev + AsyncWebSocketMessageBuffer* buffer = _ws->makeBuffer(len); + assert(buffer); // up to you to keep or remove this + serializeJson(doc, buffer->get(), len); + _ws->textAll(buffer); +} +``` + +Here is an example for serializing a Json document in a more optimized way, and compatible with both forks: ```cpp void send(JsonDocument& doc) { diff --git a/src/AsyncWebSocket.cpp b/src/AsyncWebSocket.cpp index 12be5f83e..443b5f1e0 100644 --- a/src/AsyncWebSocket.cpp +++ b/src/AsyncWebSocket.cpp @@ -123,6 +123,39 @@ size_t webSocketSendFrame(AsyncClient *client, bool final, uint8_t opcode, bool +/* + * AsyncWebSocketMessageBuffer + */ + +AsyncWebSocketMessageBuffer::AsyncWebSocketMessageBuffer() + : _buffer(std::make_shared>(0)) +{ +} + +AsyncWebSocketMessageBuffer::AsyncWebSocketMessageBuffer(uint8_t* data, size_t size) + : _buffer(std::make_shared>(size)) +{ + std::memcpy(_buffer->data(), data, size); +} + +AsyncWebSocketMessageBuffer::AsyncWebSocketMessageBuffer(size_t size) + : _buffer(std::make_shared>(size)) +{ +} + +AsyncWebSocketMessageBuffer::~AsyncWebSocketMessageBuffer() +{ + _buffer.reset(); +} + +bool AsyncWebSocketMessageBuffer::reserve(size_t size) +{ + if (_buffer->capacity() >= size) + return true; + _buffer->reserve(size); + return _buffer->capacity() >= size; +} + /* * Control Frame */ @@ -644,7 +677,7 @@ size_t AsyncWebSocketClient::printf_P(PGM_P formatP, ...) #endif namespace { -std::shared_ptr> makeBuffer(const uint8_t *message, size_t len) +std::shared_ptr> makeSharedBuffer(const uint8_t *message, size_t len) { auto buffer = std::make_shared>(len); std::memcpy(buffer->data(), message, len); @@ -652,6 +685,12 @@ std::shared_ptr> makeBuffer(const uint8_t *message, size_t } } +void AsyncWebSocketClient::text(AsyncWebSocketMessageBuffer * buffer) +{ + text(std::move(buffer->_buffer)); + delete buffer; +} + void AsyncWebSocketClient::text(std::shared_ptr> buffer) { _queueMessage(buffer); @@ -659,7 +698,7 @@ void AsyncWebSocketClient::text(std::shared_ptr> buffer) void AsyncWebSocketClient::text(const uint8_t *message, size_t len) { - text(makeBuffer(message, len)); + text(makeSharedBuffer(message, len)); } void AsyncWebSocketClient::text(const char *message, size_t len) @@ -698,6 +737,12 @@ void AsyncWebSocketClient::text(const __FlashStringHelper *data) } } +void AsyncWebSocketClient::binary(AsyncWebSocketMessageBuffer * buffer) +{ + binary(std::move(buffer->_buffer)); + delete buffer; +} + void AsyncWebSocketClient::binary(std::shared_ptr> buffer) { _queueMessage(buffer, WS_BINARY); @@ -705,7 +750,7 @@ void AsyncWebSocketClient::binary(std::shared_ptr> buffer) void AsyncWebSocketClient::binary(const uint8_t *message, size_t len) { - binary(makeBuffer(message, len)); + binary(makeSharedBuffer(message, len)); } void AsyncWebSocketClient::binary(const char *message, size_t len) @@ -853,7 +898,7 @@ void AsyncWebSocket::pingAll(const uint8_t *data, size_t len) void AsyncWebSocket::text(uint32_t id, const uint8_t *message, size_t len) { if (AsyncWebSocketClient * c = client(id)) - c->text(makeBuffer(message, len)); + c->text(makeSharedBuffer(message, len)); } void AsyncWebSocket::text(uint32_t id, const char *message, size_t len) { @@ -889,6 +934,12 @@ void AsyncWebSocket::text(uint32_t id, const __FlashStringHelper *data) } } +void AsyncWebSocket::textAll(AsyncWebSocketMessageBuffer * buffer) +{ + textAll(std::move(buffer->_buffer)); + delete buffer; +} + void AsyncWebSocket::textAll(std::shared_ptr> buffer) { for (auto &c : _clients) @@ -897,7 +948,7 @@ void AsyncWebSocket::textAll(std::shared_ptr> buffer) } void AsyncWebSocket::textAll(const uint8_t *message, size_t len) { - textAll(makeBuffer(message, len)); + textAll(makeSharedBuffer(message, len)); } void AsyncWebSocket::textAll(const char * message, size_t len) { @@ -935,7 +986,7 @@ void AsyncWebSocket::textAll(const __FlashStringHelper *data) void AsyncWebSocket::binary(uint32_t id, const uint8_t *message, size_t len) { if (AsyncWebSocketClient *c = client(id)) - c->binary(makeBuffer(message, len)); + c->binary(makeSharedBuffer(message, len)); } void AsyncWebSocket::binary(uint32_t id, const char * message, size_t len) { @@ -961,6 +1012,12 @@ void AsyncWebSocket::binary(uint32_t id, const __FlashStringHelper *data, size_t } } +void AsyncWebSocket::binaryAll(AsyncWebSocketMessageBuffer * buffer) +{ + binaryAll(std::move(buffer->_buffer)); + delete buffer; +} + void AsyncWebSocket::binaryAll(std::shared_ptr> buffer) { for (auto &c : _clients) @@ -970,7 +1027,7 @@ void AsyncWebSocket::binaryAll(std::shared_ptr> buffer) void AsyncWebSocket::binaryAll(const uint8_t *message, size_t len) { - binaryAll(makeBuffer(message, len)); + binaryAll(makeSharedBuffer(message, len)); } void AsyncWebSocket::binaryAll(const char *message, size_t len) @@ -1141,6 +1198,16 @@ void AsyncWebSocket::handleRequest(AsyncWebServerRequest *request) request->send(response); } +AsyncWebSocketMessageBuffer * AsyncWebSocket::makeBuffer(size_t size) +{ + return new AsyncWebSocketMessageBuffer(size); +} + +AsyncWebSocketMessageBuffer * AsyncWebSocket::makeBuffer(uint8_t * data, size_t size) +{ + return new AsyncWebSocketMessageBuffer(data, size); +} + /* * Response to Web Socket request - sends the authorization and detaches the TCP Client from the web server * Authentication code from https://github.com/Links2004/arduinoWebSockets/blob/master/src/WebSockets.cpp#L480 diff --git a/src/AsyncWebSocket.h b/src/AsyncWebSocket.h index 46de34066..ac49d2b82 100644 --- a/src/AsyncWebSocket.h +++ b/src/AsyncWebSocket.h @@ -88,6 +88,23 @@ typedef enum { WS_CONTINUATION, WS_TEXT, WS_BINARY, WS_DISCONNECT = 0x08, WS_PIN typedef enum { WS_MSG_SENDING, WS_MSG_SENT, WS_MSG_ERROR } AwsMessageStatus; typedef enum { WS_EVT_CONNECT, WS_EVT_DISCONNECT, WS_EVT_PONG, WS_EVT_ERROR, WS_EVT_DATA } AwsEventType; +class AsyncWebSocketMessageBuffer { + friend AsyncWebSocket; + friend AsyncWebSocketClient; + + private: + std::shared_ptr> _buffer; + + public: + AsyncWebSocketMessageBuffer(); + AsyncWebSocketMessageBuffer(size_t size); + AsyncWebSocketMessageBuffer(uint8_t* data, size_t size); + ~AsyncWebSocketMessageBuffer(); + bool reserve(size_t size); + uint8_t* get() { return _buffer->data(); } + size_t length() const { return _buffer->size(); } +}; + class AsyncWebSocketMessage { private: @@ -180,6 +197,7 @@ class AsyncWebSocketClient { void text(const char *message); void text(const String &message); void text(const __FlashStringHelper *message); + void text(AsyncWebSocketMessageBuffer *buffer); void binary(std::shared_ptr> buffer); void binary(const uint8_t *message, size_t len); @@ -187,6 +205,7 @@ class AsyncWebSocketClient { void binary(const char * message); void binary(const String &message); void binary(const __FlashStringHelper *message, size_t len); + void binary(AsyncWebSocketMessageBuffer *buffer); bool canSend() const; @@ -245,6 +264,7 @@ class AsyncWebSocket: public AsyncWebHandler { void textAll(const char * message); void textAll(const String &message); void textAll(const __FlashStringHelper *message); // need to convert + void textAll(AsyncWebSocketMessageBuffer *buffer); void binary(uint32_t id, const uint8_t *message, size_t len); void binary(uint32_t id, const char *message, size_t len); @@ -258,6 +278,7 @@ class AsyncWebSocket: public AsyncWebHandler { void binaryAll(const char *message); void binaryAll(const String &message); void binaryAll(const __FlashStringHelper *message, size_t len); + void binaryAll(AsyncWebSocketMessageBuffer *buffer); size_t printf(uint32_t id, const char *format, ...) __attribute__ ((format (printf, 3, 4))); size_t printfAll(const char *format, ...) __attribute__ ((format (printf, 2, 3))); @@ -283,6 +304,11 @@ class AsyncWebSocket: public AsyncWebHandler { virtual bool canHandle(AsyncWebServerRequest *request) override final; virtual void handleRequest(AsyncWebServerRequest *request) override final; + + // messagebuffer functions/objects. + AsyncWebSocketMessageBuffer * makeBuffer(size_t size = 0); + AsyncWebSocketMessageBuffer * makeBuffer(uint8_t * data, size_t size); + const std::list &getClients() const { return _clients; } }; From c29edc15e8e77d8eb9b6067d18eb55c9722c431f Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Fri, 26 Jan 2024 00:08:01 +0100 Subject: [PATCH 147/551] Remove requirement on ArduinoJson --- .github/workflows/ci.yml | 3 --- library.json | 8 -------- library.properties | 1 - 3 files changed, 12 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d748c9c42..779263260 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -43,9 +43,6 @@ jobs: - name: Install core run: arduino-cli core install --additional-urls "${{ matrix.index_url }}" ${{ matrix.core }} - - name: Install ArduinoJson - run: arduino-cli lib install ArduinoJson@7.0.2 - - name: Install AsyncTCP-esphome run: ARDUINO_LIBRARY_ENABLE_UNSAFE_INSTALL=true arduino-cli lib install --git-url https://github.com/mathieucarbou/esphome-AsyncTCP#v2.1.1 diff --git a/library.json b/library.json index 22ff7da10..34fb47f5c 100644 --- a/library.json +++ b/library.json @@ -28,14 +28,6 @@ "name": "AsyncTCP-esphome", "version": "^2.1.1", "platforms": "espressif32" - }, - { - "owner": "bblanchon", - "name": "ArduinoJson", - "version": "^7.0.2", - "platforms": [ - "espressif32" - ] } ], "export": { diff --git a/library.properties b/library.properties index f41ea3d7f..b341bbb3c 100644 --- a/library.properties +++ b/library.properties @@ -8,4 +8,3 @@ category=Other url=https://github.com/mathieucarbou/ESPAsyncWebServer architectures=esp32 license=LGPL-3.0 -depends=ArduinoJson From ed538f9a8e8ce8235b55468f97e23d11fc9435d1 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Fri, 26 Jan 2024 00:15:15 +0100 Subject: [PATCH 148/551] v2.5.0 --- library.json | 2 +- library.properties | 2 +- src/ESPAsyncWebServer.h | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/library.json b/library.json index 34fb47f5c..b918a4630 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "ESP Async WebServer", - "version": "2.4.4", + "version": "2.5.0", "description": "Asynchronous HTTP and WebSocket Server Library for ESP32. Supports: WebSocket, SSE, Authentication, Arduino Json 7, File Upload, Static File serving, URL Rewrite, URL Redirect, etc.", "keywords": "http,async,websocket,webserver", "homepage": "https://github.com/mathieucarbou/ESPAsyncWebServer", diff --git a/library.properties b/library.properties index b341bbb3c..0e81e4c5f 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=ESP Async WebServer -version=2.4.4 +version=2.5.0 author=Me-No-Dev maintainer=Mathieu Carbou sentence=Asynchronous HTTP and WebSocket Server Library for ESP32 diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index 9f5b7c900..0babe00f5 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -40,10 +40,10 @@ #error Platform not supported #endif -#define ASYNCWEBSERVER_VERSION "2.4.4" +#define ASYNCWEBSERVER_VERSION "2.5.0" #define ASYNCWEBSERVER_VERSION_MAJOR 2 -#define ASYNCWEBSERVER_VERSION_MINOR 4 -#define ASYNCWEBSERVER_VERSION_REVISION 4 +#define ASYNCWEBSERVER_VERSION_MINOR 5 +#define ASYNCWEBSERVER_VERSION_REVISION 0 #define ASYNCWEBSERVER_FORK_mathieucarbou #ifdef ASYNCWEBSERVER_REGEX From 1455d59bdef211a560ea95954484e490518f033f Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Fri, 26 Jan 2024 08:41:53 +0100 Subject: [PATCH 149/551] Add safety checks around missed allocations for AsyncWebSocketMessageBuffer --- src/AsyncWebSocket.cpp | 56 +++++++++++++++++++++++++++++++++--------- 1 file changed, 45 insertions(+), 11 deletions(-) diff --git a/src/AsyncWebSocket.cpp b/src/AsyncWebSocket.cpp index 443b5f1e0..12a89cbf2 100644 --- a/src/AsyncWebSocket.cpp +++ b/src/AsyncWebSocket.cpp @@ -135,12 +135,21 @@ AsyncWebSocketMessageBuffer::AsyncWebSocketMessageBuffer() AsyncWebSocketMessageBuffer::AsyncWebSocketMessageBuffer(uint8_t* data, size_t size) : _buffer(std::make_shared>(size)) { - std::memcpy(_buffer->data(), data, size); + if (_buffer->capacity() < size) { + _buffer.reset(); + _buffer = std::make_shared>(0); + } else { + std::memcpy(_buffer->data(), data, size); + } } AsyncWebSocketMessageBuffer::AsyncWebSocketMessageBuffer(size_t size) : _buffer(std::make_shared>(size)) { + if (_buffer->capacity() < size) { + _buffer.reset(); + _buffer = std::make_shared>(0); + } } AsyncWebSocketMessageBuffer::~AsyncWebSocketMessageBuffer() @@ -443,6 +452,9 @@ void AsyncWebSocketClient::_queueMessage(std::shared_ptr> b if (!_client) return; + if (buffer->size() == 0) + return; + { AsyncWebLockGuard l(_lock); if (_messageQueue.size() >= WS_MAX_QUEUED_MESSAGES) @@ -687,8 +699,10 @@ std::shared_ptr> makeSharedBuffer(const uint8_t *message, s void AsyncWebSocketClient::text(AsyncWebSocketMessageBuffer * buffer) { - text(std::move(buffer->_buffer)); - delete buffer; + if (buffer) { + text(std::move(buffer->_buffer)); + delete buffer; + } } void AsyncWebSocketClient::text(std::shared_ptr> buffer) @@ -739,8 +753,10 @@ void AsyncWebSocketClient::text(const __FlashStringHelper *data) void AsyncWebSocketClient::binary(AsyncWebSocketMessageBuffer * buffer) { - binary(std::move(buffer->_buffer)); - delete buffer; + if (buffer) { + binary(std::move(buffer->_buffer)); + delete buffer; + } } void AsyncWebSocketClient::binary(std::shared_ptr> buffer) @@ -936,8 +952,10 @@ void AsyncWebSocket::text(uint32_t id, const __FlashStringHelper *data) void AsyncWebSocket::textAll(AsyncWebSocketMessageBuffer * buffer) { - textAll(std::move(buffer->_buffer)); - delete buffer; + if (buffer) { + textAll(std::move(buffer->_buffer)); + delete buffer; + } } void AsyncWebSocket::textAll(std::shared_ptr> buffer) @@ -1014,8 +1032,10 @@ void AsyncWebSocket::binary(uint32_t id, const __FlashStringHelper *data, size_t void AsyncWebSocket::binaryAll(AsyncWebSocketMessageBuffer * buffer) { - binaryAll(std::move(buffer->_buffer)); - delete buffer; + if (buffer) { + binaryAll(std::move(buffer->_buffer)); + delete buffer; + } } void AsyncWebSocket::binaryAll(std::shared_ptr> buffer) @@ -1200,12 +1220,26 @@ void AsyncWebSocket::handleRequest(AsyncWebServerRequest *request) AsyncWebSocketMessageBuffer * AsyncWebSocket::makeBuffer(size_t size) { - return new AsyncWebSocketMessageBuffer(size); + AsyncWebSocketMessageBuffer * buffer = new AsyncWebSocketMessageBuffer(size); + if (buffer->length() != size) + { + delete buffer; + return nullptr; + } else { + return buffer; + } } AsyncWebSocketMessageBuffer * AsyncWebSocket::makeBuffer(uint8_t * data, size_t size) { - return new AsyncWebSocketMessageBuffer(data, size); + AsyncWebSocketMessageBuffer * buffer = new AsyncWebSocketMessageBuffer(data, size); + if (buffer->length() != size) + { + delete buffer; + return nullptr; + } else { + return buffer; + } } /* From b66ffe89fbe10a22f9685c6469aec8c87825b03a Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Fri, 26 Jan 2024 09:02:33 +0100 Subject: [PATCH 150/551] v2.5.1 --- library.json | 2 +- library.properties | 2 +- src/ESPAsyncWebServer.h | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/library.json b/library.json index b918a4630..1730ad578 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "ESP Async WebServer", - "version": "2.5.0", + "version": "2.5.1", "description": "Asynchronous HTTP and WebSocket Server Library for ESP32. Supports: WebSocket, SSE, Authentication, Arduino Json 7, File Upload, Static File serving, URL Rewrite, URL Redirect, etc.", "keywords": "http,async,websocket,webserver", "homepage": "https://github.com/mathieucarbou/ESPAsyncWebServer", diff --git a/library.properties b/library.properties index 0e81e4c5f..2e5699fe7 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=ESP Async WebServer -version=2.5.0 +version=2.5.1 author=Me-No-Dev maintainer=Mathieu Carbou sentence=Asynchronous HTTP and WebSocket Server Library for ESP32 diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index 0babe00f5..2c88bda35 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -40,10 +40,10 @@ #error Platform not supported #endif -#define ASYNCWEBSERVER_VERSION "2.5.0" +#define ASYNCWEBSERVER_VERSION "2.5.1" #define ASYNCWEBSERVER_VERSION_MAJOR 2 #define ASYNCWEBSERVER_VERSION_MINOR 5 -#define ASYNCWEBSERVER_VERSION_REVISION 0 +#define ASYNCWEBSERVER_VERSION_REVISION 1 #define ASYNCWEBSERVER_FORK_mathieucarbou #ifdef ASYNCWEBSERVER_REGEX From 48738633a3285c6ed36673cd1c6f5435520bb25d Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Fri, 26 Jan 2024 10:59:47 +0100 Subject: [PATCH 151/551] Website update --- docs/index.md | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/docs/index.md b/docs/index.md index 9cf1e0e03..8b213e81d 100644 --- a/docs/index.md +++ b/docs/index.md @@ -15,6 +15,7 @@ This fork is based on https://github.com/yubox-node-org/ESPAsyncWebServer and in - Deployed in PlatformIO registry and Arduino IDE library manager - CI - Only supports ESP32 +- Resurrected `AsyncWebSocketMessageBuffer` and `makeBuffer()` in order to make the fork API-compatible with the original library from me-no-dev regarding WebSocket. ## Documentation @@ -23,13 +24,29 @@ Please look at the original libraries for more examples and documentation. [https://github.com/yubox-node-org/ESPAsyncWebServer](https://github.com/yubox-node-org/ESPAsyncWebServer) -## Pitfalls +## `AsyncWebSocketMessageBuffer` and `makeBuffer()` -The fork from yubox introduces some breaking API changes compared to the original library, especially regarding the use of `std::shared_ptr>` for WebSocket. -Thanks to this fork, you can handle them by using `ASYNCWEBSERVER_FORK_mathieucarbou`. +The fork from `yubox-node-org` introduces some breaking API changes compared to the original library, especially regarding the use of `std::shared_ptr>` for WebSocket. -Here is an example for serializing a Json document in a websocket message buffer directly. -This code is compatible with both forks. +This fork is compatible with the original library from `me-no-dev` regarding WebSocket, and wraps the optimizations done by `yubox-node-org` in the `AsyncWebSocketMessageBuffer` class. +So you have the choice of which API to use. +I strongly suggest to use the optimized API from `yubox-node-org` as it is much more efficient. + +Here is an example for serializing a Json document in a websocket message buffer. This code is compatible with any forks, but not optimized: + +```cpp +void send(JsonDocument& doc) { + const size_t len = measureJson(doc); + + // original API from me-no-dev + AsyncWebSocketMessageBuffer* buffer = _ws->makeBuffer(len); + assert(buffer); // up to you to keep or remove this + serializeJson(doc, buffer->get(), len); + _ws->textAll(buffer); +} +``` + +Here is an example for serializing a Json document in a more optimized way, and compatible with both forks: ```cpp void send(JsonDocument& doc) { From 52c0db97b2fa02974ae0e97a4b7c02d5e14ed727 Mon Sep 17 00:00:00 2001 From: Emil Muratov Date: Fri, 26 Jan 2024 14:38:50 +0900 Subject: [PATCH 152/551] set real "Last-Modified" header based on file's LastWrite time Get file's LastWrite timestamp for file handlers (if supported by FS driver) and construct proper "Last-Modified" header. Works fine for LittleFS. If not supported by FS than fallback to previous implementation with manual value for "Last-Modified". an example code to serve static files from LittleFS with IMS revalidation ``` // serve all static files from LittleFS root / server.serveStatic("/", LittleFS, "/") .setDefaultFile("index.html") .setCacheControl("must-revalidate"); // revalidate based on etag/IMS headers ``` Signed-off-by: Emil Muratov --- src/WebHandlerImpl.h | 3 ++- src/WebHandlers.cpp | 21 ++++++++++----------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/WebHandlerImpl.h b/src/WebHandlerImpl.h index 9b7ba1b04..7114bfdcc 100644 --- a/src/WebHandlerImpl.h +++ b/src/WebHandlerImpl.h @@ -28,6 +28,7 @@ #include "stddef.h" #include +#include class AsyncStaticWebHandler: public AsyncWebHandler { using File = fs::File; @@ -55,7 +56,7 @@ class AsyncStaticWebHandler: public AsyncWebHandler { AsyncStaticWebHandler& setDefaultFile(const char* filename); AsyncStaticWebHandler& setCacheControl(const char* cache_control); AsyncStaticWebHandler& setLastModified(const char* last_modified); - AsyncStaticWebHandler& setLastModified(struct tm* last_modified); + AsyncStaticWebHandler& setLastModified(const std::tm* last_modified); #ifdef ESP8266 AsyncStaticWebHandler& setLastModified(time_t last_modified); AsyncStaticWebHandler& setLastModified(); //sets to current time. Make sure sntp is runing and time is updated diff --git a/src/WebHandlers.cpp b/src/WebHandlers.cpp index c79cdbbb5..7d28ddcc1 100644 --- a/src/WebHandlers.cpp +++ b/src/WebHandlers.cpp @@ -58,18 +58,15 @@ AsyncStaticWebHandler& AsyncStaticWebHandler::setCacheControl(const char* cache_ } AsyncStaticWebHandler& AsyncStaticWebHandler::setLastModified(const char* last_modified){ - _last_modified = String(last_modified); + _last_modified = last_modified; return *this; } -AsyncStaticWebHandler& AsyncStaticWebHandler::setLastModified(struct tm* last_modified){ - auto formatP = PSTR("%a, %d %b %Y %H:%M:%S %Z"); - char format[strlen_P(formatP) + 1]; - strcpy_P(format, formatP); - - char result[30]; - strftime(result, sizeof(result), format, last_modified); - return setLastModified((const char *)result); +AsyncStaticWebHandler& AsyncStaticWebHandler::setLastModified(const std::tm* last_modified){ + constexpr size_t buffsize = sizeof("Fri, 27 Jan 2023 15:50:27 GMT"); // a format for LM header + char result[buffsize]; + std::strftime(result, buffsize, "%a, %d %b %Y %H:%M:%S GMT", last_modified); + return setLastModified(static_cast(result)); } #ifdef ESP8266 @@ -198,14 +195,16 @@ uint8_t AsyncStaticWebHandler::_countBits(const uint8_t value) const void AsyncStaticWebHandler::handleRequest(AsyncWebServerRequest *request) { // Get the filename from request->_tempObject and free it - String filename = String((char*)request->_tempObject); + String filename((char*)request->_tempObject); free(request->_tempObject); request->_tempObject = NULL; if((_username.length() && _password.length()) && !request->authenticate(_username.c_str(), _password.c_str())) return request->requestAuthentication(); if (request->_tempFile == true) { - String etag = String(request->_tempFile.size()); + time_t lw = request->_tempFile.getLastWrite(); // get last file mod time (if supported by FS) + if (lw) setLastModified(std::gmtime(&lw)); + String etag(lw ? lw : request->_tempFile.size()); // set etag to lastmod timestamp if available, otherwise to size if (_last_modified.length() && _last_modified == request->header(F("If-Modified-Since"))) { request->_tempFile.close(); request->send(304); // Not modified From 84f45727e7a78c385b7bc5d16fea5a46125b0b76 Mon Sep 17 00:00:00 2001 From: Emil Muratov Date: Sat, 27 Jan 2024 17:58:40 +0900 Subject: [PATCH 153/551] rollback time handling code style from c++ to C and 8266 --- src/WebHandlerImpl.h | 3 +-- src/WebHandlers.cpp | 17 ++++++++++------- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/WebHandlerImpl.h b/src/WebHandlerImpl.h index 7114bfdcc..9b7ba1b04 100644 --- a/src/WebHandlerImpl.h +++ b/src/WebHandlerImpl.h @@ -28,7 +28,6 @@ #include "stddef.h" #include -#include class AsyncStaticWebHandler: public AsyncWebHandler { using File = fs::File; @@ -56,7 +55,7 @@ class AsyncStaticWebHandler: public AsyncWebHandler { AsyncStaticWebHandler& setDefaultFile(const char* filename); AsyncStaticWebHandler& setCacheControl(const char* cache_control); AsyncStaticWebHandler& setLastModified(const char* last_modified); - AsyncStaticWebHandler& setLastModified(const std::tm* last_modified); + AsyncStaticWebHandler& setLastModified(struct tm* last_modified); #ifdef ESP8266 AsyncStaticWebHandler& setLastModified(time_t last_modified); AsyncStaticWebHandler& setLastModified(); //sets to current time. Make sure sntp is runing and time is updated diff --git a/src/WebHandlers.cpp b/src/WebHandlers.cpp index 7d28ddcc1..0b55b0ddf 100644 --- a/src/WebHandlers.cpp +++ b/src/WebHandlers.cpp @@ -62,11 +62,14 @@ AsyncStaticWebHandler& AsyncStaticWebHandler::setLastModified(const char* last_m return *this; } -AsyncStaticWebHandler& AsyncStaticWebHandler::setLastModified(const std::tm* last_modified){ - constexpr size_t buffsize = sizeof("Fri, 27 Jan 2023 15:50:27 GMT"); // a format for LM header - char result[buffsize]; - std::strftime(result, buffsize, "%a, %d %b %Y %H:%M:%S GMT", last_modified); - return setLastModified(static_cast(result)); +AsyncStaticWebHandler& AsyncStaticWebHandler::setLastModified(struct tm* last_modified){ + auto formatP = PSTR("%a, %d %b %Y %H:%M:%S %Z"); + char format[strlen_P(formatP) + 1]; + strcpy_P(format, formatP); + + char result[30]; + strftime(result, sizeof(result), format, last_modified); + return setLastModified((const char *)result); } #ifdef ESP8266 @@ -195,7 +198,7 @@ uint8_t AsyncStaticWebHandler::_countBits(const uint8_t value) const void AsyncStaticWebHandler::handleRequest(AsyncWebServerRequest *request) { // Get the filename from request->_tempObject and free it - String filename((char*)request->_tempObject); + String filename = String((char*)request->_tempObject); free(request->_tempObject); request->_tempObject = NULL; if((_username.length() && _password.length()) && !request->authenticate(_username.c_str(), _password.c_str())) @@ -203,7 +206,7 @@ void AsyncStaticWebHandler::handleRequest(AsyncWebServerRequest *request) if (request->_tempFile == true) { time_t lw = request->_tempFile.getLastWrite(); // get last file mod time (if supported by FS) - if (lw) setLastModified(std::gmtime(&lw)); + if (lw) setLastModified(gmtime(&lw)); String etag(lw ? lw : request->_tempFile.size()); // set etag to lastmod timestamp if available, otherwise to size if (_last_modified.length() && _last_modified == request->header(F("If-Modified-Since"))) { request->_tempFile.close(); From f2873cafebffc196ad4d6f667e500f5cc0c18654 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Sun, 28 Jan 2024 02:48:50 +0100 Subject: [PATCH 154/551] v2.6.0 --- library.json | 2 +- library.properties | 2 +- src/ESPAsyncWebServer.h | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/library.json b/library.json index 1730ad578..cada5e84b 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "ESP Async WebServer", - "version": "2.5.1", + "version": "2.6.0", "description": "Asynchronous HTTP and WebSocket Server Library for ESP32. Supports: WebSocket, SSE, Authentication, Arduino Json 7, File Upload, Static File serving, URL Rewrite, URL Redirect, etc.", "keywords": "http,async,websocket,webserver", "homepage": "https://github.com/mathieucarbou/ESPAsyncWebServer", diff --git a/library.properties b/library.properties index 2e5699fe7..d69a8d246 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=ESP Async WebServer -version=2.5.1 +version=2.6.0 author=Me-No-Dev maintainer=Mathieu Carbou sentence=Asynchronous HTTP and WebSocket Server Library for ESP32 diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index 2c88bda35..7f582219d 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -40,10 +40,10 @@ #error Platform not supported #endif -#define ASYNCWEBSERVER_VERSION "2.5.1" +#define ASYNCWEBSERVER_VERSION "2.6.0" #define ASYNCWEBSERVER_VERSION_MAJOR 2 -#define ASYNCWEBSERVER_VERSION_MINOR 5 -#define ASYNCWEBSERVER_VERSION_REVISION 1 +#define ASYNCWEBSERVER_VERSION_MINOR 6 +#define ASYNCWEBSERVER_VERSION_REVISION 0 #define ASYNCWEBSERVER_FORK_mathieucarbou #ifdef ASYNCWEBSERVER_REGEX From 670466d8b4990841b68a857b9572d15faad8e8d3 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Wed, 31 Jan 2024 10:37:25 +0100 Subject: [PATCH 155/551] Add stale workflow --- .github/workflows/stale.yaml | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 .github/workflows/stale.yaml diff --git a/.github/workflows/stale.yaml b/.github/workflows/stale.yaml new file mode 100644 index 000000000..14ceb43c2 --- /dev/null +++ b/.github/workflows/stale.yaml @@ -0,0 +1,24 @@ +name: "Close stale issues and PRs" +on: + schedule: + - cron: "30 1 * * *" + +jobs: + stale: + runs-on: ubuntu-latest + steps: + - uses: actions/stale@v9 + with: + stale-issue-message: "This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 7 days." + stale-pr-message: "This PR is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 7 days." + close-issue-message: "This issue was closed because it has been stalled for 7 days with no activity." + close-pr-message: "This PR was closed because it has been stalled for 7 days with no activity." + days-before-issue-stale: 30 + days-before-pr-stale: 30 + days-before-issue-close: 7 + days-before-pr-close: 7 + +permissions: + # contents: write # only for delete-branch option + issues: write + pull-requests: write From dc17f5c0684e2da0add05fd8c955470c389c74af Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Thu, 1 Feb 2024 15:57:33 +0100 Subject: [PATCH 156/551] FIx ambiguity with IPAddress(0U) --- src/AsyncWebSocket.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/AsyncWebSocket.cpp b/src/AsyncWebSocket.cpp index 12a89cbf2..90f14cdbc 100644 --- a/src/AsyncWebSocket.cpp +++ b/src/AsyncWebSocket.cpp @@ -798,7 +798,7 @@ void AsyncWebSocketClient::binary(const __FlashStringHelper *data, size_t len) IPAddress AsyncWebSocketClient::remoteIP() const { if (!_client) - return IPAddress(0U); + return IPAddress((uint32_t)0U); return _client->remoteIP(); } From 119130bc17df1aa40961b8a2b663078ac6ca053f Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Thu, 1 Feb 2024 16:00:20 +0100 Subject: [PATCH 157/551] v2.6.1 --- library.json | 2 +- library.properties | 2 +- src/ESPAsyncWebServer.h | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/library.json b/library.json index cada5e84b..94271bdd4 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "ESP Async WebServer", - "version": "2.6.0", + "version": "2.6.1", "description": "Asynchronous HTTP and WebSocket Server Library for ESP32. Supports: WebSocket, SSE, Authentication, Arduino Json 7, File Upload, Static File serving, URL Rewrite, URL Redirect, etc.", "keywords": "http,async,websocket,webserver", "homepage": "https://github.com/mathieucarbou/ESPAsyncWebServer", diff --git a/library.properties b/library.properties index d69a8d246..fda5f3fe8 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=ESP Async WebServer -version=2.6.0 +version=2.6.1 author=Me-No-Dev maintainer=Mathieu Carbou sentence=Asynchronous HTTP and WebSocket Server Library for ESP32 diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index 7f582219d..8955c39f2 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -40,10 +40,10 @@ #error Platform not supported #endif -#define ASYNCWEBSERVER_VERSION "2.6.0" +#define ASYNCWEBSERVER_VERSION "2.6.1" #define ASYNCWEBSERVER_VERSION_MAJOR 2 #define ASYNCWEBSERVER_VERSION_MINOR 6 -#define ASYNCWEBSERVER_VERSION_REVISION 0 +#define ASYNCWEBSERVER_VERSION_REVISION 1 #define ASYNCWEBSERVER_FORK_mathieucarbou #ifdef ASYNCWEBSERVER_REGEX From 11a6439df2186150113b90e9a7173edeeaf4337e Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Mon, 5 Feb 2024 10:43:23 +0100 Subject: [PATCH 158/551] Website update --- README.md | 14 +++++++++----- docs/index.md | 14 +++++++++----- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 8b213e81d..3c23491eb 100644 --- a/README.md +++ b/README.md @@ -8,14 +8,18 @@ Async Web Server for ESP31B This fork is based on https://github.com/yubox-node-org/ESPAsyncWebServer and includes all the concurrency fixes. -## Changes +## Changes in this fork -- SPIFFSEditor is removed -- Arduino Json 7 compatibility +- Removed SPIFFSEditor - Deployed in PlatformIO registry and Arduino IDE library manager - CI -- Only supports ESP32 +- Some code cleanup +- `SSE_MAX_QUEUED_MESSAGES` to control the maximum number of messages that can be queued for a SSE client +- `write()` function public in `AsyncEventSource.h` +- Arduino Json 7 compatibility and by default, still compatible with 6 (`AsyncJson.h`) +- `WS_MAX_QUEUED_MESSAGES`: control the maximum number of messages that can be queued for a Websocket client - Resurrected `AsyncWebSocketMessageBuffer` and `makeBuffer()` in order to make the fork API-compatible with the original library from me-no-dev regarding WebSocket. +- [#5](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/5): set real "Last-Modified" header based on file's LastWrite time ([@vortigont](https://github.com/vortigont)) ## Documentation @@ -37,7 +41,7 @@ Here is an example for serializing a Json document in a websocket message buffer ```cpp void send(JsonDocument& doc) { const size_t len = measureJson(doc); - + // original API from me-no-dev AsyncWebSocketMessageBuffer* buffer = _ws->makeBuffer(len); assert(buffer); // up to you to keep or remove this diff --git a/docs/index.md b/docs/index.md index 8b213e81d..3c23491eb 100644 --- a/docs/index.md +++ b/docs/index.md @@ -8,14 +8,18 @@ Async Web Server for ESP31B This fork is based on https://github.com/yubox-node-org/ESPAsyncWebServer and includes all the concurrency fixes. -## Changes +## Changes in this fork -- SPIFFSEditor is removed -- Arduino Json 7 compatibility +- Removed SPIFFSEditor - Deployed in PlatformIO registry and Arduino IDE library manager - CI -- Only supports ESP32 +- Some code cleanup +- `SSE_MAX_QUEUED_MESSAGES` to control the maximum number of messages that can be queued for a SSE client +- `write()` function public in `AsyncEventSource.h` +- Arduino Json 7 compatibility and by default, still compatible with 6 (`AsyncJson.h`) +- `WS_MAX_QUEUED_MESSAGES`: control the maximum number of messages that can be queued for a Websocket client - Resurrected `AsyncWebSocketMessageBuffer` and `makeBuffer()` in order to make the fork API-compatible with the original library from me-no-dev regarding WebSocket. +- [#5](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/5): set real "Last-Modified" header based on file's LastWrite time ([@vortigont](https://github.com/vortigont)) ## Documentation @@ -37,7 +41,7 @@ Here is an example for serializing a Json document in a websocket message buffer ```cpp void send(JsonDocument& doc) { const size_t len = measureJson(doc); - + // original API from me-no-dev AsyncWebSocketMessageBuffer* buffer = _ws->makeBuffer(len); assert(buffer); // up to you to keep or remove this From 6961aa75eaf26fb8916e41337b9a7e09641d50fb Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Mon, 5 Feb 2024 10:43:35 +0100 Subject: [PATCH 159/551] CI Update --- .github/workflows/ci.yml | 12 ++++ examples/CaptivePortal/CaptivePortal.ino | 54 +++++++------- examples/SimpleServer/SimpleServer.ino | 91 ++++++++++++++++-------- platformio.ini | 22 ++++-- 4 files changed, 119 insertions(+), 60 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 779263260..e1737c2cc 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -24,6 +24,11 @@ jobs: eeprom: true softwareserial: false index_url: https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json + - core: esp8266:esp8266 + board: esp8266:esp8266:huzzah + eeprom: true + softwareserial: true + index_url: https://arduino.esp8266.com/stable/package_esp8266com_index.json steps: - name: Checkout @@ -46,6 +51,9 @@ jobs: - name: Install AsyncTCP-esphome run: ARDUINO_LIBRARY_ENABLE_UNSAFE_INSTALL=true arduino-cli lib install --git-url https://github.com/mathieucarbou/esphome-AsyncTCP#v2.1.1 + - name: Install ESPAsyncTCP-esphome + run: ARDUINO_LIBRARY_ENABLE_UNSAFE_INSTALL=true arduino-cli lib install --git-urlhttps://github.com/mathieucarbou/ESPAsyncTCP-esphome#v2.0.0 + - name: Build CaptivePortal run: arduino-cli compile --library . --warnings all -b ${{ matrix.board }} "examples/CaptivePortal/CaptivePortal.ino" @@ -63,6 +71,10 @@ jobs: board: esp32dev eeprom: true softwareserial: false + - platform: espressif8266 + board: huzzah + eeprom: true + softwareserial: false steps: - name: Checkout diff --git a/examples/CaptivePortal/CaptivePortal.ino b/examples/CaptivePortal/CaptivePortal.ino index 8cfe5613d..f97f142a6 100644 --- a/examples/CaptivePortal/CaptivePortal.ino +++ b/examples/CaptivePortal/CaptivePortal.ino @@ -1,41 +1,47 @@ -#include "ESPAsyncWebServer.h" -#include #include +#ifdef ESP32 #include +#include +#elif defined(ESP8266) +#include +#include +#endif +#include "ESPAsyncWebServer.h" DNSServer dnsServer; AsyncWebServer server(80); class CaptiveRequestHandler : public AsyncWebHandler { - public: - CaptiveRequestHandler() {} - virtual ~CaptiveRequestHandler() {} +public: + CaptiveRequestHandler() {} + virtual ~CaptiveRequestHandler() {} - bool canHandle(AsyncWebServerRequest* request) { - // request->addInterestingHeader("ANY"); - return true; - } + bool canHandle(AsyncWebServerRequest *request){ + //request->addInterestingHeader("ANY"); + return true; + } - void handleRequest(AsyncWebServerRequest* request) { - AsyncResponseStream* response = request->beginResponseStream("text/html"); - response->print("Captive Portal"); - response->print("

This is out captive portal front page.

"); - response->printf("

You were trying to reach: http://%s%s

", request->host().c_str(), request->url().c_str()); - response->printf("

Try opening this link instead

", WiFi.softAPIP().toString().c_str()); - response->print(""); - request->send(response); - } + void handleRequest(AsyncWebServerRequest *request) { + AsyncResponseStream *response = request->beginResponseStream("text/html"); + response->print("Captive Portal"); + response->print("

This is out captive portal front page.

"); + response->printf("

You were trying to reach: http://%s%s

", request->host().c_str(), request->url().c_str()); + response->printf("

Try opening this link instead

", WiFi.softAPIP().toString().c_str()); + response->print(""); + request->send(response); + } }; -void setup() { - // your other setup stuff... + +void setup(){ + //your other setup stuff... WiFi.softAP("esp-captive"); dnsServer.start(53, "*", WiFi.softAPIP()); - server.addHandler(new CaptiveRequestHandler()).setFilter(ON_AP_FILTER); // only when requested from AP - // more handlers... + server.addHandler(new CaptiveRequestHandler()).setFilter(ON_AP_FILTER);//only when requested from AP + //more handlers... server.begin(); } -void loop() { +void loop(){ dnsServer.processNextRequest(); -} \ No newline at end of file +} diff --git a/examples/SimpleServer/SimpleServer.ino b/examples/SimpleServer/SimpleServer.ino index 8cfe5613d..bdbcf60dc 100644 --- a/examples/SimpleServer/SimpleServer.ino +++ b/examples/SimpleServer/SimpleServer.ino @@ -1,41 +1,74 @@ -#include "ESPAsyncWebServer.h" -#include -#include +// +// A simple server implementation showing how to: +// * serve static messages +// * read GET and POST parameters +// * handle missing pages / 404s +// + +#include +#ifdef ESP32 #include +#include +#elif defined(ESP8266) +#include +#include +#endif +#include -DNSServer dnsServer; AsyncWebServer server(80); -class CaptiveRequestHandler : public AsyncWebHandler { - public: - CaptiveRequestHandler() {} - virtual ~CaptiveRequestHandler() {} +const char* ssid = "YOUR_SSID"; +const char* password = "YOUR_PASSWORD"; - bool canHandle(AsyncWebServerRequest* request) { - // request->addInterestingHeader("ANY"); - return true; - } +const char* PARAM_MESSAGE = "message"; - void handleRequest(AsyncWebServerRequest* request) { - AsyncResponseStream* response = request->beginResponseStream("text/html"); - response->print("Captive Portal"); - response->print("

This is out captive portal front page.

"); - response->printf("

You were trying to reach: http://%s%s

", request->host().c_str(), request->url().c_str()); - response->printf("

Try opening this link instead

", WiFi.softAPIP().toString().c_str()); - response->print(""); - request->send(response); - } -}; +void notFound(AsyncWebServerRequest *request) { + request->send(404, "text/plain", "Not found"); +} void setup() { - // your other setup stuff... - WiFi.softAP("esp-captive"); - dnsServer.start(53, "*", WiFi.softAPIP()); - server.addHandler(new CaptiveRequestHandler()).setFilter(ON_AP_FILTER); // only when requested from AP - // more handlers... - server.begin(); + + Serial.begin(115200); + WiFi.mode(WIFI_STA); + WiFi.begin(ssid, password); + if (WiFi.waitForConnectResult() != WL_CONNECTED) { + Serial.printf("WiFi Failed!\n"); + return; + } + + Serial.print("IP Address: "); + Serial.println(WiFi.localIP()); + + server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){ + request->send(200, "text/plain", "Hello, world"); + }); + + // Send a GET request to /get?message= + server.on("/get", HTTP_GET, [] (AsyncWebServerRequest *request) { + String message; + if (request->hasParam(PARAM_MESSAGE)) { + message = request->getParam(PARAM_MESSAGE)->value(); + } else { + message = "No message sent"; + } + request->send(200, "text/plain", "Hello, GET: " + message); + }); + + // Send a POST request to /post with a form field message set to + server.on("/post", HTTP_POST, [](AsyncWebServerRequest *request){ + String message; + if (request->hasParam(PARAM_MESSAGE, true)) { + message = request->getParam(PARAM_MESSAGE, true)->value(); + } else { + message = "No message sent"; + } + request->send(200, "text/plain", "Hello, POST: " + message); + }); + + server.onNotFound(notFound); + + server.begin(); } void loop() { - dnsServer.processNextRequest(); } \ No newline at end of file diff --git a/platformio.ini b/platformio.ini index cad8b22ee..fdd5074cb 100644 --- a/platformio.ini +++ b/platformio.ini @@ -1,7 +1,5 @@ [env] -lib_deps = - bblanchon/ArduinoJson @ 7.0.2 - esphome/AsyncTCP-esphome @ 2.1.1 +framework = arduino build_flags = -Wall -Wextra @@ -13,11 +11,21 @@ monitor_speed = 115200 monitor_filters = esp32_exception_decoder, log2file [platformio] +default_envs = esp8266 lib_dir = . -src_dir = examples/CaptivePortal -; src_dir = examples/SimpleServer +; src_dir = examples/CaptivePortal +src_dir = examples/SimpleServer [env:esp32] -platform = espressif32@6.5.0 +platform = espressif32 board = esp32dev -framework = arduino +lib_deps = + bblanchon/ArduinoJson @ 7.0.2 + esphome/AsyncTCP-esphome @ 2.1.1 + +[env:esp8266] +platform = espressif8266 +board = huzzah +lib_deps = + bblanchon/ArduinoJson @ 7.0.2 + esphome/ESPAsyncTCP-esphome @ 2.0.0 From b317ea70a4f10b38c2a218c561d78d9487195a69 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Mon, 5 Feb 2024 10:46:35 +0100 Subject: [PATCH 160/551] Brought back compat with espressif8266 --- library.json | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/library.json b/library.json index 94271bdd4..7e988b98c 100644 --- a/library.json +++ b/library.json @@ -28,6 +28,16 @@ "name": "AsyncTCP-esphome", "version": "^2.1.1", "platforms": "espressif32" + }, + { + "owner": "esphome", + "name": "ESPAsyncTCP-esphome", + "version": "^2.0.0", + "platforms": "espressif8266" + }, + { + "name": "Hash", + "platforms": "espressif8266" } ], "export": { From ee7d31d92b634183bf9befc53732088cc30c2152 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Mon, 5 Feb 2024 10:48:46 +0100 Subject: [PATCH 161/551] Fix CI --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e1737c2cc..8b5fa0468 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -52,7 +52,7 @@ jobs: run: ARDUINO_LIBRARY_ENABLE_UNSAFE_INSTALL=true arduino-cli lib install --git-url https://github.com/mathieucarbou/esphome-AsyncTCP#v2.1.1 - name: Install ESPAsyncTCP-esphome - run: ARDUINO_LIBRARY_ENABLE_UNSAFE_INSTALL=true arduino-cli lib install --git-urlhttps://github.com/mathieucarbou/ESPAsyncTCP-esphome#v2.0.0 + run: ARDUINO_LIBRARY_ENABLE_UNSAFE_INSTALL=true arduino-cli lib install --git-url https://github.com/mathieucarbou/ESPAsyncTCP-esphome#v2.0.0 - name: Build CaptivePortal run: arduino-cli compile --library . --warnings all -b ${{ matrix.board }} "examples/CaptivePortal/CaptivePortal.ino" From b1ffd3349e566b4ff0ec69377c66de63a9b06672 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Mon, 5 Feb 2024 10:51:46 +0100 Subject: [PATCH 162/551] v2.7.0 --- library.json | 2 +- library.properties | 2 +- src/ESPAsyncWebServer.h | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/library.json b/library.json index 7e988b98c..526a45441 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "ESP Async WebServer", - "version": "2.6.1", + "version": "2.7.0", "description": "Asynchronous HTTP and WebSocket Server Library for ESP32. Supports: WebSocket, SSE, Authentication, Arduino Json 7, File Upload, Static File serving, URL Rewrite, URL Redirect, etc.", "keywords": "http,async,websocket,webserver", "homepage": "https://github.com/mathieucarbou/ESPAsyncWebServer", diff --git a/library.properties b/library.properties index fda5f3fe8..a0bd50d60 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=ESP Async WebServer -version=2.6.1 +version=2.7.0 author=Me-No-Dev maintainer=Mathieu Carbou sentence=Asynchronous HTTP and WebSocket Server Library for ESP32 diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index 8955c39f2..bd3a41b90 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -40,10 +40,10 @@ #error Platform not supported #endif -#define ASYNCWEBSERVER_VERSION "2.6.1" +#define ASYNCWEBSERVER_VERSION "2.7.0" #define ASYNCWEBSERVER_VERSION_MAJOR 2 -#define ASYNCWEBSERVER_VERSION_MINOR 6 -#define ASYNCWEBSERVER_VERSION_REVISION 1 +#define ASYNCWEBSERVER_VERSION_MINOR 7 +#define ASYNCWEBSERVER_VERSION_REVISION 0 #define ASYNCWEBSERVER_FORK_mathieucarbou #ifdef ASYNCWEBSERVER_REGEX From 8bf51555480d39fa2c85cdbe907b194b73dd2011 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Mon, 5 Feb 2024 10:53:53 +0100 Subject: [PATCH 163/551] Website update --- README.md | 2 +- docs/index.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 3c23491eb..d841bb2e5 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ Async Web Server for ESP31B -This fork is based on https://github.com/yubox-node-org/ESPAsyncWebServer and includes all the concurrency fixes. +This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubox-node-org/ESPAsyncWebServer) and includes all the concurrency fixes. ## Changes in this fork diff --git a/docs/index.md b/docs/index.md index 3c23491eb..d841bb2e5 100644 --- a/docs/index.md +++ b/docs/index.md @@ -6,7 +6,7 @@ Async Web Server for ESP31B -This fork is based on https://github.com/yubox-node-org/ESPAsyncWebServer and includes all the concurrency fixes. +This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubox-node-org/ESPAsyncWebServer) and includes all the concurrency fixes. ## Changes in this fork From af1df0390123b28d22c0d78bb699812e08b4f9b1 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Mon, 5 Feb 2024 10:56:11 +0100 Subject: [PATCH 164/551] Website update --- README.md | 3 ++- docs/index.md | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index d841bb2e5..5b6d2de23 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,8 @@ [![Continuous Integration](https://github.com/mathieucarbou/ESPAsyncWebServer/actions/workflows/ci.yml/badge.svg)](https://github.com/mathieucarbou/ESPAsyncWebServer/actions/workflows/ci.yml) [![PlatformIO Registry](https://badges.registry.platformio.org/packages/mathieucarbou/library/ESP%20Async%20WebServer.svg)](https://registry.platformio.org/libraries/mathieucarbou/ESP%20Async%20WebServer) -Async Web Server for ESP31B +Asynchronous HTTP and WebSocket Server Library for ESP32. +Supports: WebSocket, SSE, Authentication, Arduino Json 7, File Upload, Static File serving, URL Rewrite, URL Redirect, etc. This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubox-node-org/ESPAsyncWebServer) and includes all the concurrency fixes. diff --git a/docs/index.md b/docs/index.md index d841bb2e5..5b6d2de23 100644 --- a/docs/index.md +++ b/docs/index.md @@ -4,7 +4,8 @@ [![Continuous Integration](https://github.com/mathieucarbou/ESPAsyncWebServer/actions/workflows/ci.yml/badge.svg)](https://github.com/mathieucarbou/ESPAsyncWebServer/actions/workflows/ci.yml) [![PlatformIO Registry](https://badges.registry.platformio.org/packages/mathieucarbou/library/ESP%20Async%20WebServer.svg)](https://registry.platformio.org/libraries/mathieucarbou/ESP%20Async%20WebServer) -Async Web Server for ESP31B +Asynchronous HTTP and WebSocket Server Library for ESP32. +Supports: WebSocket, SSE, Authentication, Arduino Json 7, File Upload, Static File serving, URL Rewrite, URL Redirect, etc. This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubox-node-org/ESPAsyncWebServer) and includes all the concurrency fixes. From 3bd268ea75dfadd72bce6b5e8800d00273360607 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Thu, 14 Mar 2024 15:31:07 +0100 Subject: [PATCH 165/551] fix website --- docs/_config.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/_config.yml b/docs/_config.yml index 4750b0943..532070ba6 100644 --- a/docs/_config.yml +++ b/docs/_config.yml @@ -1,7 +1,7 @@ # bundle exec jekyll serve --host=0.0.0.0 -title: Asynchronous HTTP and WebSocket Server Library for ESP32 -description: "Supports: WebSocket, SSE, Authentication, Arduino Json 7, File Upload, Static File serving, URL Rewrite, URL Redirect, etc" +title: ESP Async WebServer +description: "Asynchronous HTTP and WebSocket Server Library for ESP32" remote_theme: pages-themes/cayman@v0.2.0 plugins: - jekyll-remote-theme From 8c315c4e3fb3b22145e59fadeaea6559d1fb9de7 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Thu, 14 Mar 2024 19:31:22 +0100 Subject: [PATCH 166/551] Fix Arduino Json 7 API mathieucarbou/ESPAsyncWebServer#10 --- README.md | 2 +- docs/index.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 5b6d2de23..d5bafae36 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo - Some code cleanup - `SSE_MAX_QUEUED_MESSAGES` to control the maximum number of messages that can be queued for a SSE client - `write()` function public in `AsyncEventSource.h` -- Arduino Json 7 compatibility and by default, still compatible with 6 (`AsyncJson.h`) +- Arduino Json 7 compatibility and backward compatible with 6 and 6 (changes in `AsyncJson.h`). The API to use Json has not changed. These are only internal changes. - `WS_MAX_QUEUED_MESSAGES`: control the maximum number of messages that can be queued for a Websocket client - Resurrected `AsyncWebSocketMessageBuffer` and `makeBuffer()` in order to make the fork API-compatible with the original library from me-no-dev regarding WebSocket. - [#5](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/5): set real "Last-Modified" header based on file's LastWrite time ([@vortigont](https://github.com/vortigont)) diff --git a/docs/index.md b/docs/index.md index 5b6d2de23..d5bafae36 100644 --- a/docs/index.md +++ b/docs/index.md @@ -17,7 +17,7 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo - Some code cleanup - `SSE_MAX_QUEUED_MESSAGES` to control the maximum number of messages that can be queued for a SSE client - `write()` function public in `AsyncEventSource.h` -- Arduino Json 7 compatibility and by default, still compatible with 6 (`AsyncJson.h`) +- Arduino Json 7 compatibility and backward compatible with 6 and 6 (changes in `AsyncJson.h`). The API to use Json has not changed. These are only internal changes. - `WS_MAX_QUEUED_MESSAGES`: control the maximum number of messages that can be queued for a Websocket client - Resurrected `AsyncWebSocketMessageBuffer` and `makeBuffer()` in order to make the fork API-compatible with the original library from me-no-dev regarding WebSocket. - [#5](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/5): set real "Last-Modified" header based on file's LastWrite time ([@vortigont](https://github.com/vortigont)) From 64706c15ed9bca6ca55314f6e4c1c04e176e27a2 Mon Sep 17 00:00:00 2001 From: root Date: Wed, 13 Mar 2024 01:25:23 +0000 Subject: [PATCH 167/551] Bump ArduinoJson to 7.0.4 --- platformio.ini | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platformio.ini b/platformio.ini index fdd5074cb..43a3b4e53 100644 --- a/platformio.ini +++ b/platformio.ini @@ -20,12 +20,12 @@ src_dir = examples/SimpleServer platform = espressif32 board = esp32dev lib_deps = - bblanchon/ArduinoJson @ 7.0.2 + bblanchon/ArduinoJson @ 7.0.4 esphome/AsyncTCP-esphome @ 2.1.1 [env:esp8266] platform = espressif8266 board = huzzah lib_deps = - bblanchon/ArduinoJson @ 7.0.2 + bblanchon/ArduinoJson @ 7.0.4 esphome/ESPAsyncTCP-esphome @ 2.0.0 From f477fa5f35b340b0e5f4d2137d37141cb296655d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niklas=20L=C3=B6nn?= Date: Sun, 3 Mar 2024 20:36:12 +0100 Subject: [PATCH 168/551] Reapplied changes from https://github.com/me-no-dev/ESPAsyncWebServer/pull/1384 --- src/AsyncJson.h | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/AsyncJson.h b/src/AsyncJson.h index f4e99d123..309092e3e 100644 --- a/src/AsyncJson.h +++ b/src/AsyncJson.h @@ -197,10 +197,10 @@ class AsyncCallbackJsonWebHandler : public AsyncWebHandler { public: #if ARDUINOJSON_VERSION_MAJOR == 6 AsyncCallbackJsonWebHandler(const String& uri, ArJsonRequestHandlerFunction onRequest, size_t maxJsonBufferSize = DYNAMIC_JSON_DOCUMENT_SIZE) - : _uri(uri), _method(HTTP_POST | HTTP_PUT | HTTP_PATCH), _onRequest(onRequest), maxJsonBufferSize(maxJsonBufferSize), _maxContentLength(16384) {} + : _uri(uri), _method(HTTP_GET | HTTP_POST | HTTP_PUT | HTTP_PATCH), _onRequest(onRequest), maxJsonBufferSize(maxJsonBufferSize), _maxContentLength(16384) {} #else AsyncCallbackJsonWebHandler(const String& uri, ArJsonRequestHandlerFunction onRequest) - : _uri(uri), _method(HTTP_POST | HTTP_PUT | HTTP_PATCH), _onRequest(onRequest), _maxContentLength(16384) {} + : _uri(uri), _method(HTTP_GET | HTTP_POST | HTTP_PUT | HTTP_PATCH), _onRequest(onRequest), _maxContentLength(16384) {} #endif void setMethod(WebRequestMethodComposite method) { _method = method; } @@ -211,13 +211,14 @@ class AsyncCallbackJsonWebHandler : public AsyncWebHandler { if (!_onRequest) return false; - if (!(_method & request->method())) + WebRequestMethodComposite request_method = request->method(); + if (!(_method & request_method)) return false; if (_uri.length() && (_uri != request->url() && !request->url().startsWith(_uri + "/"))) return false; - if (!request->contentType().equalsIgnoreCase(JSON_MIMETYPE)) + if (request_method != HTTP_GET && !request->contentType().equalsIgnoreCase(JSON_MIMETYPE)) return false; request->addInterestingHeader("ANY"); @@ -225,8 +226,14 @@ class AsyncCallbackJsonWebHandler : public AsyncWebHandler { } virtual void handleRequest(AsyncWebServerRequest* request) override final { + if((_username != "" && _password != "") && !request->authenticate(_username.c_str(), _password.c_str())) + return request->requestAuthentication(); if (_onRequest) { - if (request->_tempObject != NULL) { + if (request->method() == HTTP_GET) { + JsonVariant json; + _onRequest(request, json); + return; + } else if (request->_tempObject != NULL) { #if ARDUINOJSON_VERSION_MAJOR == 5 DynamicJsonBuffer jsonBuffer; From 3b0ee64cae40d0b3cd69db1c63b596b76f544ec8 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Thu, 14 Mar 2024 19:59:20 +0100 Subject: [PATCH 169/551] Fix #12: esphome/AsyncTCP-esphome @ 2.1.3 --- .github/workflows/ci.yml | 2 +- library.json | 2 +- platformio.ini | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8b5fa0468..c28d0e2ba 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -49,7 +49,7 @@ jobs: run: arduino-cli core install --additional-urls "${{ matrix.index_url }}" ${{ matrix.core }} - name: Install AsyncTCP-esphome - run: ARDUINO_LIBRARY_ENABLE_UNSAFE_INSTALL=true arduino-cli lib install --git-url https://github.com/mathieucarbou/esphome-AsyncTCP#v2.1.1 + run: ARDUINO_LIBRARY_ENABLE_UNSAFE_INSTALL=true arduino-cli lib install --git-url https://github.com/mathieucarbou/esphome-AsyncTCP#v2.1.3 - name: Install ESPAsyncTCP-esphome run: ARDUINO_LIBRARY_ENABLE_UNSAFE_INSTALL=true arduino-cli lib install --git-url https://github.com/mathieucarbou/ESPAsyncTCP-esphome#v2.0.0 diff --git a/library.json b/library.json index 526a45441..43b3d6c9b 100644 --- a/library.json +++ b/library.json @@ -26,7 +26,7 @@ { "owner": "esphome", "name": "AsyncTCP-esphome", - "version": "^2.1.1", + "version": "^2.1.3", "platforms": "espressif32" }, { diff --git a/platformio.ini b/platformio.ini index 43a3b4e53..9a2617c1a 100644 --- a/platformio.ini +++ b/platformio.ini @@ -21,7 +21,7 @@ platform = espressif32 board = esp32dev lib_deps = bblanchon/ArduinoJson @ 7.0.4 - esphome/AsyncTCP-esphome @ 2.1.1 + esphome/AsyncTCP-esphome @ 2.1.3 [env:esp8266] platform = espressif8266 From 16b640d71fa229191df4048fbf1cb74cf710436e Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Thu, 14 Mar 2024 20:16:25 +0100 Subject: [PATCH 170/551] Fx CI --- .github/workflows/ci.yml | 4 ++-- platformio.ini | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c28d0e2ba..747b704bf 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -55,10 +55,10 @@ jobs: run: ARDUINO_LIBRARY_ENABLE_UNSAFE_INSTALL=true arduino-cli lib install --git-url https://github.com/mathieucarbou/ESPAsyncTCP-esphome#v2.0.0 - name: Build CaptivePortal - run: arduino-cli compile --library . --warnings all -b ${{ matrix.board }} "examples/CaptivePortal/CaptivePortal.ino" + run: arduino-cli compile --library . --warnings none -b ${{ matrix.board }} "examples/CaptivePortal/CaptivePortal.ino" - name: Build SimpleServer - run: arduino-cli compile --library . --warnings all -b ${{ matrix.board }} "examples/SimpleServer/SimpleServer.ino" + run: arduino-cli compile --library . --warnings none -b ${{ matrix.board }} "examples/SimpleServer/SimpleServer.ino" platformio: name: PlatformIO diff --git a/platformio.ini b/platformio.ini index 9a2617c1a..73c5553c8 100644 --- a/platformio.ini +++ b/platformio.ini @@ -13,8 +13,8 @@ monitor_filters = esp32_exception_decoder, log2file [platformio] default_envs = esp8266 lib_dir = . -; src_dir = examples/CaptivePortal -src_dir = examples/SimpleServer +src_dir = examples/CaptivePortal +; src_dir = examples/SimpleServer [env:esp32] platform = espressif32 From b9128452305a56d33a8a85944050435d2861fe08 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Thu, 14 Mar 2024 20:31:10 +0100 Subject: [PATCH 171/551] v2.8.0 --- library.json | 2 +- library.properties | 2 +- src/ESPAsyncWebServer.h | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/library.json b/library.json index 43b3d6c9b..987e3eefa 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "ESP Async WebServer", - "version": "2.7.0", + "version": "2.8.0", "description": "Asynchronous HTTP and WebSocket Server Library for ESP32. Supports: WebSocket, SSE, Authentication, Arduino Json 7, File Upload, Static File serving, URL Rewrite, URL Redirect, etc.", "keywords": "http,async,websocket,webserver", "homepage": "https://github.com/mathieucarbou/ESPAsyncWebServer", diff --git a/library.properties b/library.properties index a0bd50d60..5078f9f27 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=ESP Async WebServer -version=2.7.0 +version=2.8.0 author=Me-No-Dev maintainer=Mathieu Carbou sentence=Asynchronous HTTP and WebSocket Server Library for ESP32 diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index bd3a41b90..360782103 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -40,9 +40,9 @@ #error Platform not supported #endif -#define ASYNCWEBSERVER_VERSION "2.7.0" +#define ASYNCWEBSERVER_VERSION "2.8.0" #define ASYNCWEBSERVER_VERSION_MAJOR 2 -#define ASYNCWEBSERVER_VERSION_MINOR 7 +#define ASYNCWEBSERVER_VERSION_MINOR 8 #define ASYNCWEBSERVER_VERSION_REVISION 0 #define ASYNCWEBSERVER_FORK_mathieucarbou From 3ee4013002c443a1aeb959956c9a177f663c8042 Mon Sep 17 00:00:00 2001 From: tueddy Date: Sat, 2 Mar 2024 17:47:18 +0100 Subject: [PATCH 172/551] Compile with Arduino 3 (ESP-IDF 5.x) --- src/AsyncEventSource.cpp | 1 + src/AsyncWebSocket.cpp | 7 +++++++ src/WebAuthentication.cpp | 6 ++++++ 3 files changed, 14 insertions(+) diff --git a/src/AsyncEventSource.cpp b/src/AsyncEventSource.cpp index fdafb1b7a..3a2f9ea83 100644 --- a/src/AsyncEventSource.cpp +++ b/src/AsyncEventSource.cpp @@ -19,6 +19,7 @@ */ #include "Arduino.h" #include "AsyncEventSource.h" +#include static String generateEventMessage(const char *message, const char *event, uint32_t id, uint32_t reconnect){ String ev; diff --git a/src/AsyncWebSocket.cpp b/src/AsyncWebSocket.cpp index 90f14cdbc..594ffb5cf 100644 --- a/src/AsyncWebSocket.cpp +++ b/src/AsyncWebSocket.cpp @@ -27,6 +27,7 @@ #ifndef ESP8266 #include "mbedtls/sha1.h" +#include #else #include #endif @@ -1272,9 +1273,15 @@ AsyncWebSocketResponse::AsyncWebSocketResponse(const String& key, AsyncWebSocket (String&)key += WS_STR_UUID; mbedtls_sha1_context ctx; mbedtls_sha1_init(&ctx); +#if ESP_IDF_VERSION_MAJOR == 5 + mbedtls_sha1_starts(&ctx); + mbedtls_sha1_update(&ctx, (const unsigned char*)key.c_str(), key.length()); + mbedtls_sha1_finish(&ctx, hash); +#else mbedtls_sha1_starts_ret(&ctx); mbedtls_sha1_update_ret(&ctx, (const unsigned char*)key.c_str(), key.length()); mbedtls_sha1_finish_ret(&ctx, hash); +#endif mbedtls_sha1_free(&ctx); #endif base64_encodestate _state; diff --git a/src/WebAuthentication.cpp b/src/WebAuthentication.cpp index 1a22afdfc..2f122d7cd 100644 --- a/src/WebAuthentication.cpp +++ b/src/WebAuthentication.cpp @@ -77,9 +77,15 @@ static bool getMD5(uint8_t * data, uint16_t len, char * output){//33 bytes or mo memset(_buf, 0x00, 16); #ifdef ESP32 mbedtls_md5_init(&_ctx); +#if ESP_IDF_VERSION_MAJOR == 5 + mbedtls_md5_starts(&_ctx); + mbedtls_md5_update(&_ctx, data, len); + mbedtls_md5_finish(&_ctx, _buf); +#else mbedtls_md5_starts_ret(&_ctx); mbedtls_md5_update_ret(&_ctx, data, len); mbedtls_md5_finish_ret(&_ctx, _buf); +#endif #else MD5Init(&_ctx); MD5Update(&_ctx, data, len); From 5862e135acf3b5165a9f07ed01f6e1f6865e885c Mon Sep 17 00:00:00 2001 From: tueddy Date: Fri, 15 Mar 2024 15:44:46 +0100 Subject: [PATCH 173/551] make the build pass on esp8266 --- src/AsyncEventSource.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/AsyncEventSource.cpp b/src/AsyncEventSource.cpp index 3a2f9ea83..1c34c85ce 100644 --- a/src/AsyncEventSource.cpp +++ b/src/AsyncEventSource.cpp @@ -19,7 +19,9 @@ */ #include "Arduino.h" #include "AsyncEventSource.h" -#include +#ifndef ESP8266 + #include +#endif static String generateEventMessage(const char *message, const char *event, uint32_t id, uint32_t reconnect){ String ev; From 52ee4e1393d8db61e6dd11eb82e57642d25ea53b Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Fri, 15 Mar 2024 08:49:00 +0100 Subject: [PATCH 174/551] Allow back 8266 --- library.json | 3 ++- library.properties | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/library.json b/library.json index 987e3eefa..1c1ed7937 100644 --- a/library.json +++ b/library.json @@ -20,7 +20,8 @@ "license": "LGPL-3.0", "frameworks": "arduino", "platforms": [ - "espressif32" + "espressif32", + "espressif8266" ], "dependencies": [ { diff --git a/library.properties b/library.properties index 5078f9f27..79ebd58f8 100644 --- a/library.properties +++ b/library.properties @@ -6,5 +6,5 @@ sentence=Asynchronous HTTP and WebSocket Server Library for ESP32 paragraph=Supports: WebSocket, SSE, Authentication, Arduino Json 7, File Upload, Static File serving, URL Rewrite, URL Redirect, etc category=Other url=https://github.com/mathieucarbou/ESPAsyncWebServer -architectures=esp32 +architectures=8 license=LGPL-3.0 From 9a54d9f74a286d7a05624f603e331673765a4fb8 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Fri, 15 Mar 2024 16:06:47 +0100 Subject: [PATCH 175/551] Add CI for Arduino 3 (ESP-IDF 5.1) --- .github/workflows/ci.yml | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 747b704bf..9b46f46a0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -69,12 +69,16 @@ jobs: include: - platform: espressif32 board: esp32dev - eeprom: true - softwareserial: false + opts: - platform: espressif8266 board: huzzah - eeprom: true - softwareserial: false + opts: + - platform: espressif32 + board: esp32dev + opts: "--project-option 'platform_packages=platformio/framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#3.0.0-alpha3, platform_packages=platformio/framework-arduinoespressif32-libs @ https://github.com/espressif/esp32-arduino-libs.git#idf-release/v5.1'" + - platform: espressif8266 + board: huzzah + opts: "--project-option 'platform_packages=platformio/framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#3.0.0-alpha3, platform_packages=platformio/framework-arduinoespressif32-libs @ https://github.com/espressif/esp32-arduino-libs.git#idf-release/v5.1'" steps: - name: Checkout @@ -100,7 +104,7 @@ jobs: run: platformio platform install ${{ matrix.platform }} - name: Build CaptivePortal - run: platformio ci "examples/CaptivePortal/CaptivePortal.ino" -l '.' -b ${{ matrix.board }} + run: platformio ci "examples/CaptivePortal/CaptivePortal.ino" -l '.' -b ${{ matrix.board }} ${{ matrix.opts }} - name: Build SimpleServer - run: platformio ci "examples/SimpleServer/SimpleServer.ino" -l '.' -b ${{ matrix.board }} + run: platformio ci "examples/SimpleServer/SimpleServer.ino" -l '.' -b ${{ matrix.board }} ${{ matrix.opts }} From 15605ccce5ea1f3e5b10c9238c19346683f95f4d Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Fri, 15 Mar 2024 16:15:54 +0100 Subject: [PATCH 176/551] doc --- README.md | 4 +++- docs/index.md | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index d5bafae36..864fc3da3 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,9 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo - Arduino Json 7 compatibility and backward compatible with 6 and 6 (changes in `AsyncJson.h`). The API to use Json has not changed. These are only internal changes. - `WS_MAX_QUEUED_MESSAGES`: control the maximum number of messages that can be queued for a Websocket client - Resurrected `AsyncWebSocketMessageBuffer` and `makeBuffer()` in order to make the fork API-compatible with the original library from me-no-dev regarding WebSocket. -- [#5](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/5): set real "Last-Modified" header based on file's LastWrite time ([@vortigont](https://github.com/vortigont)) +- [#5](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/5) ([@vortigont](https://github.com/vortigont)): set real "Last-Modified" header based on file's LastWrite time +- [#13](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/13) ([@tueddy](https://github.com/tueddy)): Compile with Arduino 3 (ESP-IDF 5.1) +- [#14](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/14) ([@nilo85](https://github.com/nilo85)): Add support for Auth & GET requests in AsyncCallbackJsonWebHandler ## Documentation diff --git a/docs/index.md b/docs/index.md index d5bafae36..864fc3da3 100644 --- a/docs/index.md +++ b/docs/index.md @@ -20,7 +20,9 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo - Arduino Json 7 compatibility and backward compatible with 6 and 6 (changes in `AsyncJson.h`). The API to use Json has not changed. These are only internal changes. - `WS_MAX_QUEUED_MESSAGES`: control the maximum number of messages that can be queued for a Websocket client - Resurrected `AsyncWebSocketMessageBuffer` and `makeBuffer()` in order to make the fork API-compatible with the original library from me-no-dev regarding WebSocket. -- [#5](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/5): set real "Last-Modified" header based on file's LastWrite time ([@vortigont](https://github.com/vortigont)) +- [#5](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/5) ([@vortigont](https://github.com/vortigont)): set real "Last-Modified" header based on file's LastWrite time +- [#13](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/13) ([@tueddy](https://github.com/tueddy)): Compile with Arduino 3 (ESP-IDF 5.1) +- [#14](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/14) ([@nilo85](https://github.com/nilo85)): Add support for Auth & GET requests in AsyncCallbackJsonWebHandler ## Documentation From c6de29074522934ae79dd9ba8097bd25f5a6c090 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Fri, 15 Mar 2024 16:16:21 +0100 Subject: [PATCH 177/551] v2.8.1 --- library.json | 2 +- library.properties | 2 +- src/ESPAsyncWebServer.h | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/library.json b/library.json index 1c1ed7937..e20eb4c07 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "ESP Async WebServer", - "version": "2.8.0", + "version": "2.8.1", "description": "Asynchronous HTTP and WebSocket Server Library for ESP32. Supports: WebSocket, SSE, Authentication, Arduino Json 7, File Upload, Static File serving, URL Rewrite, URL Redirect, etc.", "keywords": "http,async,websocket,webserver", "homepage": "https://github.com/mathieucarbou/ESPAsyncWebServer", diff --git a/library.properties b/library.properties index 79ebd58f8..e642f1b8a 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=ESP Async WebServer -version=2.8.0 +version=2.8.1 author=Me-No-Dev maintainer=Mathieu Carbou sentence=Asynchronous HTTP and WebSocket Server Library for ESP32 diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index 360782103..990848e09 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -40,10 +40,10 @@ #error Platform not supported #endif -#define ASYNCWEBSERVER_VERSION "2.8.0" +#define ASYNCWEBSERVER_VERSION "2.8.1" #define ASYNCWEBSERVER_VERSION_MAJOR 2 #define ASYNCWEBSERVER_VERSION_MINOR 8 -#define ASYNCWEBSERVER_VERSION_REVISION 0 +#define ASYNCWEBSERVER_VERSION_REVISION 1 #define ASYNCWEBSERVER_FORK_mathieucarbou #ifdef ASYNCWEBSERVER_REGEX From 6732d01796d03046e68574580dc08b1114c97652 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Fri, 15 Mar 2024 18:37:33 +0100 Subject: [PATCH 178/551] update test files --- .github/workflows/ci.yml | 6 +++--- platformio.ini | 6 +++++- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9b46f46a0..1cbe2b2fc 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -69,10 +69,10 @@ jobs: include: - platform: espressif32 board: esp32dev - opts: + opts: - platform: espressif8266 board: huzzah - opts: + opts: - platform: espressif32 board: esp32dev opts: "--project-option 'platform_packages=platformio/framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#3.0.0-alpha3, platform_packages=platformio/framework-arduinoespressif32-libs @ https://github.com/espressif/esp32-arduino-libs.git#idf-release/v5.1'" @@ -95,7 +95,7 @@ jobs: - name: Set up Python 3.x uses: actions/setup-python@v5 with: - python-version: '3.x' + python-version: "3.x" - name: Install PlatformIO run: pip install platformio diff --git a/platformio.ini b/platformio.ini index 73c5553c8..5b3afe4e2 100644 --- a/platformio.ini +++ b/platformio.ini @@ -1,6 +1,10 @@ [env] framework = arduino +platform_packages= + platformio/framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#3.0.0-alpha3 + platform_packages=platformio/framework-arduinoespressif32-libs @ https://github.com/espressif/esp32-arduino-libs.git#idf-release/v5.1 + build_flags = -Wall -Wextra upload_protocol = esptool @@ -11,7 +15,7 @@ monitor_speed = 115200 monitor_filters = esp32_exception_decoder, log2file [platformio] -default_envs = esp8266 +default_envs = esp32 lib_dir = . src_dir = examples/CaptivePortal ; src_dir = examples/SimpleServer From b30a44e92af4b3651810254412f152ecd0096238 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Mon, 1 Apr 2024 21:39:01 +0200 Subject: [PATCH 179/551] Fix #16: Add overflowed() --- src/AsyncJson.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/AsyncJson.h b/src/AsyncJson.h index 309092e3e..b2f6e2eb8 100644 --- a/src/AsyncJson.h +++ b/src/AsyncJson.h @@ -137,7 +137,11 @@ class AsyncJsonResponse : public AsyncAbstractResponse { return _contentLength; } - size_t getSize() { return _jsonBuffer.size(); } + size_t getSize() const { return _jsonBuffer.size(); } + +#if ARDUINOJSON_VERSION_MAJOR >= 6 + bool overflowed() const { return _jsonBuffer.overflowed(); } +#endif size_t _fillBuffer(uint8_t* data, size_t len) { ChunkPrint dest(data, _sentLength, len); From e8d65d919519ea15735b58ed5c1da6a2ada17165 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Mon, 1 Apr 2024 21:44:22 +0200 Subject: [PATCH 180/551] v2.9.0 --- library.json | 2 +- library.properties | 2 +- src/ESPAsyncWebServer.h | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/library.json b/library.json index e20eb4c07..d3f29eafb 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "ESP Async WebServer", - "version": "2.8.1", + "version": "2.9.0", "description": "Asynchronous HTTP and WebSocket Server Library for ESP32. Supports: WebSocket, SSE, Authentication, Arduino Json 7, File Upload, Static File serving, URL Rewrite, URL Redirect, etc.", "keywords": "http,async,websocket,webserver", "homepage": "https://github.com/mathieucarbou/ESPAsyncWebServer", diff --git a/library.properties b/library.properties index e642f1b8a..cfb1bbde9 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=ESP Async WebServer -version=2.8.1 +version=2.9.0 author=Me-No-Dev maintainer=Mathieu Carbou sentence=Asynchronous HTTP and WebSocket Server Library for ESP32 diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index 990848e09..791dc0d3f 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -40,10 +40,10 @@ #error Platform not supported #endif -#define ASYNCWEBSERVER_VERSION "2.8.1" +#define ASYNCWEBSERVER_VERSION "2.9.0" #define ASYNCWEBSERVER_VERSION_MAJOR 2 -#define ASYNCWEBSERVER_VERSION_MINOR 8 -#define ASYNCWEBSERVER_VERSION_REVISION 1 +#define ASYNCWEBSERVER_VERSION_MINOR 9 +#define ASYNCWEBSERVER_VERSION_REVISION 0 #define ASYNCWEBSERVER_FORK_mathieucarbou #ifdef ASYNCWEBSERVER_REGEX From 478894e039adebfe324a1b259b9d90c2ad805649 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Fri, 19 Apr 2024 15:11:31 +0200 Subject: [PATCH 181/551] Fix architectures --- library.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library.properties b/library.properties index cfb1bbde9..e94d45333 100644 --- a/library.properties +++ b/library.properties @@ -6,5 +6,5 @@ sentence=Asynchronous HTTP and WebSocket Server Library for ESP32 paragraph=Supports: WebSocket, SSE, Authentication, Arduino Json 7, File Upload, Static File serving, URL Rewrite, URL Redirect, etc category=Other url=https://github.com/mathieucarbou/ESPAsyncWebServer -architectures=8 +architectures=* license=LGPL-3.0 From 2d2da0733df0166a4928fdfda460cd34a14811e4 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Fri, 19 Apr 2024 15:12:24 +0200 Subject: [PATCH 182/551] v2.9.1 --- library.json | 2 +- library.properties | 2 +- src/ESPAsyncWebServer.h | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/library.json b/library.json index d3f29eafb..ebff832d1 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "ESP Async WebServer", - "version": "2.9.0", + "version": "2.9.1", "description": "Asynchronous HTTP and WebSocket Server Library for ESP32. Supports: WebSocket, SSE, Authentication, Arduino Json 7, File Upload, Static File serving, URL Rewrite, URL Redirect, etc.", "keywords": "http,async,websocket,webserver", "homepage": "https://github.com/mathieucarbou/ESPAsyncWebServer", diff --git a/library.properties b/library.properties index e94d45333..903e79b39 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=ESP Async WebServer -version=2.9.0 +version=2.9.1 author=Me-No-Dev maintainer=Mathieu Carbou sentence=Asynchronous HTTP and WebSocket Server Library for ESP32 diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index 791dc0d3f..9640b7fd4 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -40,10 +40,10 @@ #error Platform not supported #endif -#define ASYNCWEBSERVER_VERSION "2.9.0" +#define ASYNCWEBSERVER_VERSION "2.9.1" #define ASYNCWEBSERVER_VERSION_MAJOR 2 #define ASYNCWEBSERVER_VERSION_MINOR 9 -#define ASYNCWEBSERVER_VERSION_REVISION 0 +#define ASYNCWEBSERVER_VERSION_REVISION 1 #define ASYNCWEBSERVER_FORK_mathieucarbou #ifdef ASYNCWEBSERVER_REGEX From 6670c2e4e413c4746bfbc54d8c1dc339d77f61f3 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Sat, 20 Apr 2024 00:41:49 +0200 Subject: [PATCH 183/551] Move to mathieucarbou/Async TCP @ ^3.0.0 for Arduino 3 / ESP-IDF 5 compatibility --- .github/workflows/ci.yml | 15 ++++++++++----- .vscode/settings.json | 7 ++++++- examples/CaptivePortal/CaptivePortal.ino | 11 +++++++++-- library.json | 6 +++--- platformio.ini | 15 +++++++++------ 5 files changed, 37 insertions(+), 17 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1cbe2b2fc..081fabe7e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -23,7 +23,12 @@ jobs: board: esp32:esp32:esp32 eeprom: true softwareserial: false - index_url: https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json + index_url: https://espressif.github.io/arduino-esp32/package_esp32_index.json + - core: esp32:esp32 + board: esp32:esp32:esp32 + eeprom: true + softwareserial: false + index_url: https://espressif.github.io/arduino-esp32/package_esp32_dev_index.json - core: esp8266:esp8266 board: esp8266:esp8266:huzzah eeprom: true @@ -49,10 +54,10 @@ jobs: run: arduino-cli core install --additional-urls "${{ matrix.index_url }}" ${{ matrix.core }} - name: Install AsyncTCP-esphome - run: ARDUINO_LIBRARY_ENABLE_UNSAFE_INSTALL=true arduino-cli lib install --git-url https://github.com/mathieucarbou/esphome-AsyncTCP#v2.1.3 + run: ARDUINO_LIBRARY_ENABLE_UNSAFE_INSTALL=true arduino-cli lib install --git-url https://github.com/mathieucarbou/AsyncTCP#v3.0.0 - name: Install ESPAsyncTCP-esphome - run: ARDUINO_LIBRARY_ENABLE_UNSAFE_INSTALL=true arduino-cli lib install --git-url https://github.com/mathieucarbou/ESPAsyncTCP-esphome#v2.0.0 + run: ARDUINO_LIBRARY_ENABLE_UNSAFE_INSTALL=true arduino-cli lib install --git-url https://github.com/mathieucarbou/esphome-ESPAsyncTCP#v2.0.0 - name: Build CaptivePortal run: arduino-cli compile --library . --warnings none -b ${{ matrix.board }} "examples/CaptivePortal/CaptivePortal.ino" @@ -75,10 +80,10 @@ jobs: opts: - platform: espressif32 board: esp32dev - opts: "--project-option 'platform_packages=platformio/framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#3.0.0-alpha3, platform_packages=platformio/framework-arduinoespressif32-libs @ https://github.com/espressif/esp32-arduino-libs.git#idf-release/v5.1'" + opts: "--project-option 'platform_packages=platformio/framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#3.0.0-rc1, platform_packages=platformio/framework-arduinoespressif32-libs @ https://github.com/espressif/esp32-arduino-libs.git#idf-release/v5.1'" - platform: espressif8266 board: huzzah - opts: "--project-option 'platform_packages=platformio/framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#3.0.0-alpha3, platform_packages=platformio/framework-arduinoespressif32-libs @ https://github.com/espressif/esp32-arduino-libs.git#idf-release/v5.1'" + opts: "--project-option 'platform_packages=platformio/framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#3.0.0-rc1, platform_packages=platformio/framework-arduinoespressif32-libs @ https://github.com/espressif/esp32-arduino-libs.git#idf-release/v5.1'" steps: - name: Checkout diff --git a/.vscode/settings.json b/.vscode/settings.json index 06877f577..5af716e2e 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -6,5 +6,10 @@ "cSpell.words": [ "YASOLR" ], - "cmake.configureOnOpen": false + "cmake.configureOnOpen": false, + "files.associations": { + "*.cps": "javascript", + "*.config": "cpp", + "compare": "cpp" + } } \ No newline at end of file diff --git a/examples/CaptivePortal/CaptivePortal.ino b/examples/CaptivePortal/CaptivePortal.ino index f97f142a6..568170917 100644 --- a/examples/CaptivePortal/CaptivePortal.ino +++ b/examples/CaptivePortal/CaptivePortal.ino @@ -34,8 +34,15 @@ public: void setup(){ - //your other setup stuff... - WiFi.softAP("esp-captive"); + Serial.begin(115200); + Serial.println(); + Serial.println("Configuring access point..."); + + if (!WiFi.softAP("esp-captive")) { + Serial.println("Soft AP creation failed."); + while (1); + } + dnsServer.start(53, "*", WiFi.softAPIP()); server.addHandler(new CaptiveRequestHandler()).setFilter(ON_AP_FILTER);//only when requested from AP //more handlers... diff --git a/library.json b/library.json index ebff832d1..4007c831e 100644 --- a/library.json +++ b/library.json @@ -25,9 +25,9 @@ ], "dependencies": [ { - "owner": "esphome", - "name": "AsyncTCP-esphome", - "version": "^2.1.3", + "owner": "mathieucarbou", + "name": "Async TCP", + "version": "^3.0.0", "platforms": "espressif32" }, { diff --git a/platformio.ini b/platformio.ini index 5b3afe4e2..bcb8f6bf5 100644 --- a/platformio.ini +++ b/platformio.ini @@ -1,11 +1,10 @@ [env] framework = arduino -platform_packages= - platformio/framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#3.0.0-alpha3 - platform_packages=platformio/framework-arduinoespressif32-libs @ https://github.com/espressif/esp32-arduino-libs.git#idf-release/v5.1 - -build_flags = -Wall -Wextra +build_flags = + -Wall -Wextra + -D CONFIG_ARDUHAL_LOG_COLORS + -D CORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_DEBUG upload_protocol = esptool upload_port = /dev/cu.usbserial-0001 @@ -21,11 +20,15 @@ src_dir = examples/CaptivePortal ; src_dir = examples/SimpleServer [env:esp32] +; platform = espressif32@6.6.0 platform = espressif32 +platform_packages= + platformio/framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#3.0.0-rc1 + platformio/framework-arduinoespressif32-libs @ https://github.com/espressif/esp32-arduino-libs.git#idf-release/v5.1 board = esp32dev lib_deps = bblanchon/ArduinoJson @ 7.0.4 - esphome/AsyncTCP-esphome @ 2.1.3 + mathieucarbou/Async TCP @ ^3.0.0 [env:esp8266] platform = espressif8266 From db07eac79c082dc106844ec6b915aae1a26cdc6f Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Sat, 20 Apr 2024 00:48:11 +0200 Subject: [PATCH 184/551] v2.9.2 --- library.json | 2 +- library.properties | 2 +- src/ESPAsyncWebServer.h | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/library.json b/library.json index 4007c831e..837fd1e7d 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "ESP Async WebServer", - "version": "2.9.1", + "version": "2.9.2", "description": "Asynchronous HTTP and WebSocket Server Library for ESP32. Supports: WebSocket, SSE, Authentication, Arduino Json 7, File Upload, Static File serving, URL Rewrite, URL Redirect, etc.", "keywords": "http,async,websocket,webserver", "homepage": "https://github.com/mathieucarbou/ESPAsyncWebServer", diff --git a/library.properties b/library.properties index 903e79b39..99679dff0 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=ESP Async WebServer -version=2.9.1 +version=2.9.2 author=Me-No-Dev maintainer=Mathieu Carbou sentence=Asynchronous HTTP and WebSocket Server Library for ESP32 diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index 9640b7fd4..2c71e4ae8 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -40,10 +40,10 @@ #error Platform not supported #endif -#define ASYNCWEBSERVER_VERSION "2.9.1" +#define ASYNCWEBSERVER_VERSION "2.9.2" #define ASYNCWEBSERVER_VERSION_MAJOR 2 #define ASYNCWEBSERVER_VERSION_MINOR 9 -#define ASYNCWEBSERVER_VERSION_REVISION 1 +#define ASYNCWEBSERVER_VERSION_REVISION 2 #define ASYNCWEBSERVER_FORK_mathieucarbou #ifdef ASYNCWEBSERVER_REGEX From b441926fea6215b0a2c86e5691a275cd3287383f Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Sat, 20 Apr 2024 00:50:01 +0200 Subject: [PATCH 185/551] update doc --- README.md | 2 ++ docs/index.md | 2 ++ 2 files changed, 4 insertions(+) diff --git a/README.md b/README.md index 864fc3da3..7e011f098 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,8 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo - [#5](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/5) ([@vortigont](https://github.com/vortigont)): set real "Last-Modified" header based on file's LastWrite time - [#13](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/13) ([@tueddy](https://github.com/tueddy)): Compile with Arduino 3 (ESP-IDF 5.1) - [#14](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/14) ([@nilo85](https://github.com/nilo85)): Add support for Auth & GET requests in AsyncCallbackJsonWebHandler +- Depends on `mathieucarbou/Async TCP @ ^3.0.0` +- Arduino 3 / ESP-IDF 5.1 compatibility ## Documentation diff --git a/docs/index.md b/docs/index.md index 864fc3da3..7e011f098 100644 --- a/docs/index.md +++ b/docs/index.md @@ -23,6 +23,8 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo - [#5](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/5) ([@vortigont](https://github.com/vortigont)): set real "Last-Modified" header based on file's LastWrite time - [#13](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/13) ([@tueddy](https://github.com/tueddy)): Compile with Arduino 3 (ESP-IDF 5.1) - [#14](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/14) ([@nilo85](https://github.com/nilo85)): Add support for Auth & GET requests in AsyncCallbackJsonWebHandler +- Depends on `mathieucarbou/Async TCP @ ^3.0.0` +- Arduino 3 / ESP-IDF 5.1 compatibility ## Documentation From 6e1d46dc63d0fcb7c57b01d121191c73f892dd3e Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Sat, 20 Apr 2024 01:04:53 +0200 Subject: [PATCH 186/551] update CI --- .github/workflows/ci.yml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 081fabe7e..44c6779ae 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,18 +21,12 @@ jobs: include: - core: esp32:esp32 board: esp32:esp32:esp32 - eeprom: true - softwareserial: false index_url: https://espressif.github.io/arduino-esp32/package_esp32_index.json - core: esp32:esp32 board: esp32:esp32:esp32 - eeprom: true - softwareserial: false index_url: https://espressif.github.io/arduino-esp32/package_esp32_dev_index.json - core: esp8266:esp8266 board: esp8266:esp8266:huzzah - eeprom: true - softwareserial: true index_url: https://arduino.esp8266.com/stable/package_esp8266com_index.json steps: From afe2be5999b6adfc047fe621d5147b3a3057d953 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Sat, 20 Apr 2024 16:48:10 +0200 Subject: [PATCH 187/551] mathieucarbou/Async TCP @ ^3.0.2 --- .github/workflows/ci.yml | 63 +++++++++++++++++++++++++--------------- README.md | 2 +- docs/index.md | 2 +- library.json | 2 +- platformio.ini | 34 +++++++++++++++------- 5 files changed, 66 insertions(+), 37 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 44c6779ae..afe6d5efd 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -48,7 +48,7 @@ jobs: run: arduino-cli core install --additional-urls "${{ matrix.index_url }}" ${{ matrix.core }} - name: Install AsyncTCP-esphome - run: ARDUINO_LIBRARY_ENABLE_UNSAFE_INSTALL=true arduino-cli lib install --git-url https://github.com/mathieucarbou/AsyncTCP#v3.0.0 + run: ARDUINO_LIBRARY_ENABLE_UNSAFE_INSTALL=true arduino-cli lib install --git-url https://github.com/mathieucarbou/AsyncTCP#v3.0.2 - name: Install ESPAsyncTCP-esphome run: ARDUINO_LIBRARY_ENABLE_UNSAFE_INSTALL=true arduino-cli lib install --git-url https://github.com/mathieucarbou/esphome-ESPAsyncTCP#v2.0.0 @@ -60,50 +60,67 @@ jobs: run: arduino-cli compile --library . --warnings none -b ${{ matrix.board }} "examples/SimpleServer/SimpleServer.ino" platformio: - name: PlatformIO + name: pio ${{ matrix.name }} runs-on: ubuntu-latest strategy: fail-fast: false matrix: include: - - platform: espressif32 + - name: esp32dev|espressif32 board: esp32dev + platform: espressif32 opts: - - platform: espressif8266 - board: huzzah + - name: esp32dev|espressif32@6.6.0 + board: esp32dev + platform: espressif32@6.6.0 opts: - - platform: espressif32 + - name: esp32dev|arduino@3.0.0-rc1 board: esp32dev + platform: espressif32 opts: "--project-option 'platform_packages=platformio/framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#3.0.0-rc1, platform_packages=platformio/framework-arduinoespressif32-libs @ https://github.com/espressif/esp32-arduino-libs.git#idf-release/v5.1'" - - platform: espressif8266 + - name: esp32dev|arduino@master + board: esp32dev + platform: espressif32 + opts: "--project-option 'platform_packages=platformio/framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#master, platform_packages=platformio/framework-arduinoespressif32-libs @ https://github.com/espressif/esp32-arduino-libs.git#idf-release/v5.1'" + - name: esp32-s3-devkitc-1|espressif32 + board: esp32-s3-devkitc-1 + platform: espressif32 + opts: + - name: esp32-s3-devkitc-1|espressif32@6.6.0 + board: esp32-s3-devkitc-1 + platform: espressif32@6.6.0 + opts: + - name: esp32-s3-devkitc-1|arduino@3.0.0-rc1 + board: esp32-s3-devkitc-1 + platform: espressif32 + opts: "--project-option 'platform_packages=platformio/framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#3.0.0-rc1, platform_packages=platformio/framework-arduinoespressif32-libs @ https://github.com/espressif/esp32-arduino-libs.git#idf-release/v5.1'" + - name: esp32-s3-devkitc-1|arduino@master + board: esp32-s3-devkitc-1 + platform: espressif32 + opts: "--project-option 'platform_packages=platformio/framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#master, platform_packages=platformio/framework-arduinoespressif32-libs @ https://github.com/espressif/esp32-arduino-libs.git#idf-release/v5.1'" + - name: huzzah|espressif8266 + board: huzzah + platform: espressif8266 + opts: + - name: huzzah|arduino@3.0.0-rc1 board: huzzah + platform: espressif8266 opts: "--project-option 'platform_packages=platformio/framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#3.0.0-rc1, platform_packages=platformio/framework-arduinoespressif32-libs @ https://github.com/espressif/esp32-arduino-libs.git#idf-release/v5.1'" - steps: - - name: Checkout - uses: actions/checkout@v4 - + - uses: actions/checkout@v4 - name: Set up cache uses: actions/cache@v4 with: path: | ~/.platformio ~/.cache/pip - key: ${{ runner.os }}-platformio - - - name: Set up Python 3.x - uses: actions/setup-python@v5 + key: ${{ matrix.name }} + - uses: actions/setup-python@v5 with: python-version: "3.x" - - - name: Install PlatformIO - run: pip install platformio - - - name: Install platform "${{ matrix.platform }}" - run: platformio platform install ${{ matrix.platform }} - + - run: pip install platformio + - run: platformio platform install ${{ matrix.platform }} - name: Build CaptivePortal run: platformio ci "examples/CaptivePortal/CaptivePortal.ino" -l '.' -b ${{ matrix.board }} ${{ matrix.opts }} - - name: Build SimpleServer run: platformio ci "examples/SimpleServer/SimpleServer.ino" -l '.' -b ${{ matrix.board }} ${{ matrix.opts }} diff --git a/README.md b/README.md index 7e011f098..d430d1c4e 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo - [#5](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/5) ([@vortigont](https://github.com/vortigont)): set real "Last-Modified" header based on file's LastWrite time - [#13](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/13) ([@tueddy](https://github.com/tueddy)): Compile with Arduino 3 (ESP-IDF 5.1) - [#14](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/14) ([@nilo85](https://github.com/nilo85)): Add support for Auth & GET requests in AsyncCallbackJsonWebHandler -- Depends on `mathieucarbou/Async TCP @ ^3.0.0` +- Depends on `mathieucarbou/Async TCP @ ^3.0.2` - Arduino 3 / ESP-IDF 5.1 compatibility ## Documentation diff --git a/docs/index.md b/docs/index.md index 7e011f098..d430d1c4e 100644 --- a/docs/index.md +++ b/docs/index.md @@ -23,7 +23,7 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo - [#5](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/5) ([@vortigont](https://github.com/vortigont)): set real "Last-Modified" header based on file's LastWrite time - [#13](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/13) ([@tueddy](https://github.com/tueddy)): Compile with Arduino 3 (ESP-IDF 5.1) - [#14](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/14) ([@nilo85](https://github.com/nilo85)): Add support for Auth & GET requests in AsyncCallbackJsonWebHandler -- Depends on `mathieucarbou/Async TCP @ ^3.0.0` +- Depends on `mathieucarbou/Async TCP @ ^3.0.2` - Arduino 3 / ESP-IDF 5.1 compatibility ## Documentation diff --git a/library.json b/library.json index 837fd1e7d..8653427eb 100644 --- a/library.json +++ b/library.json @@ -27,7 +27,7 @@ { "owner": "mathieucarbou", "name": "Async TCP", - "version": "^3.0.0", + "version": "^3.0.2", "platforms": "espressif32" }, { diff --git a/platformio.ini b/platformio.ini index bcb8f6bf5..300a37db4 100644 --- a/platformio.ini +++ b/platformio.ini @@ -1,34 +1,46 @@ [env] framework = arduino - build_flags = -Wall -Wextra -D CONFIG_ARDUHAL_LOG_COLORS -D CORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_DEBUG - +lib_deps = + bblanchon/ArduinoJson @ 7.0.4 + mathieucarbou/Async TCP @ ^3.0.2 upload_protocol = esptool -upload_port = /dev/cu.usbserial-0001 - -monitor_port = /dev/cu.usbserial-0001 monitor_speed = 115200 monitor_filters = esp32_exception_decoder, log2file [platformio] -default_envs = esp32 lib_dir = . src_dir = examples/CaptivePortal ; src_dir = examples/SimpleServer -[env:esp32] -; platform = espressif32@6.6.0 +[env:v660] +platform = espressif32@6.6.0 +board = esp32dev + +[env:latest-espressif32] +platform = https://github.com/platformio/platform-espressif32.git +board = esp32dev + +[env:latest-arduino] +platform = espressif32 +platform_packages= + platformio/framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#master + platformio/framework-arduinoespressif32-libs @ https://github.com/espressif/esp32-arduino-libs.git#idf-release/v5.1 +board = esp32dev + +[env:v300-rc1] platform = espressif32 platform_packages= platformio/framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#3.0.0-rc1 platformio/framework-arduinoespressif32-libs @ https://github.com/espressif/esp32-arduino-libs.git#idf-release/v5.1 board = esp32dev -lib_deps = - bblanchon/ArduinoJson @ 7.0.4 - mathieucarbou/Async TCP @ ^3.0.0 + +[env:Jason2866] +platform = https://github.com/Jason2866/platform-espressif32.git#Arduino/IDF5 +board = esp32dev [env:esp8266] platform = espressif8266 From 316e924a699314c9d8335bad8c86892c090e2a51 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Sat, 20 Apr 2024 17:13:49 +0200 Subject: [PATCH 188/551] v2.9.3 --- library.json | 2 +- library.properties | 2 +- src/ESPAsyncWebServer.h | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/library.json b/library.json index 8653427eb..21ab79683 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "ESP Async WebServer", - "version": "2.9.2", + "version": "2.9.3", "description": "Asynchronous HTTP and WebSocket Server Library for ESP32. Supports: WebSocket, SSE, Authentication, Arduino Json 7, File Upload, Static File serving, URL Rewrite, URL Redirect, etc.", "keywords": "http,async,websocket,webserver", "homepage": "https://github.com/mathieucarbou/ESPAsyncWebServer", diff --git a/library.properties b/library.properties index 99679dff0..d51c521f6 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=ESP Async WebServer -version=2.9.2 +version=2.9.3 author=Me-No-Dev maintainer=Mathieu Carbou sentence=Asynchronous HTTP and WebSocket Server Library for ESP32 diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index 2c71e4ae8..3709414d2 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -40,10 +40,10 @@ #error Platform not supported #endif -#define ASYNCWEBSERVER_VERSION "2.9.2" +#define ASYNCWEBSERVER_VERSION "2.9.3" #define ASYNCWEBSERVER_VERSION_MAJOR 2 #define ASYNCWEBSERVER_VERSION_MINOR 9 -#define ASYNCWEBSERVER_VERSION_REVISION 2 +#define ASYNCWEBSERVER_VERSION_REVISION 3 #define ASYNCWEBSERVER_FORK_mathieucarbou #ifdef ASYNCWEBSERVER_REGEX From 9cd298f18543685608e92e36cb53b27c7fa7054b Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Sat, 20 Apr 2024 23:01:53 +0200 Subject: [PATCH 189/551] Remove Jason2866 branch --- platformio.ini | 4 ---- 1 file changed, 4 deletions(-) diff --git a/platformio.ini b/platformio.ini index 300a37db4..1b922942a 100644 --- a/platformio.ini +++ b/platformio.ini @@ -38,10 +38,6 @@ platform_packages= platformio/framework-arduinoespressif32-libs @ https://github.com/espressif/esp32-arduino-libs.git#idf-release/v5.1 board = esp32dev -[env:Jason2866] -platform = https://github.com/Jason2866/platform-espressif32.git#Arduino/IDF5 -board = esp32dev - [env:esp8266] platform = espressif8266 board = huzzah From 3136ca033053e5d50183eee121fb089f4b022727 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Sat, 27 Apr 2024 14:20:52 +0200 Subject: [PATCH 190/551] Async TCP 3.1.2 --- .github/workflows/ci.yml | 2 +- README.md | 2 +- docs/index.md | 2 +- library.json | 2 +- platformio.ini | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index afe6d5efd..5c3e097df 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -48,7 +48,7 @@ jobs: run: arduino-cli core install --additional-urls "${{ matrix.index_url }}" ${{ matrix.core }} - name: Install AsyncTCP-esphome - run: ARDUINO_LIBRARY_ENABLE_UNSAFE_INSTALL=true arduino-cli lib install --git-url https://github.com/mathieucarbou/AsyncTCP#v3.0.2 + run: ARDUINO_LIBRARY_ENABLE_UNSAFE_INSTALL=true arduino-cli lib install --git-url https://github.com/mathieucarbou/AsyncTCP#v3.1.2 - name: Install ESPAsyncTCP-esphome run: ARDUINO_LIBRARY_ENABLE_UNSAFE_INSTALL=true arduino-cli lib install --git-url https://github.com/mathieucarbou/esphome-ESPAsyncTCP#v2.0.0 diff --git a/README.md b/README.md index d430d1c4e..ee7bb0529 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo - [#5](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/5) ([@vortigont](https://github.com/vortigont)): set real "Last-Modified" header based on file's LastWrite time - [#13](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/13) ([@tueddy](https://github.com/tueddy)): Compile with Arduino 3 (ESP-IDF 5.1) - [#14](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/14) ([@nilo85](https://github.com/nilo85)): Add support for Auth & GET requests in AsyncCallbackJsonWebHandler -- Depends on `mathieucarbou/Async TCP @ ^3.0.2` +- Depends on `mathieucarbou/Async TCP @ ^3.1.2` - Arduino 3 / ESP-IDF 5.1 compatibility ## Documentation diff --git a/docs/index.md b/docs/index.md index d430d1c4e..ee7bb0529 100644 --- a/docs/index.md +++ b/docs/index.md @@ -23,7 +23,7 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo - [#5](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/5) ([@vortigont](https://github.com/vortigont)): set real "Last-Modified" header based on file's LastWrite time - [#13](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/13) ([@tueddy](https://github.com/tueddy)): Compile with Arduino 3 (ESP-IDF 5.1) - [#14](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/14) ([@nilo85](https://github.com/nilo85)): Add support for Auth & GET requests in AsyncCallbackJsonWebHandler -- Depends on `mathieucarbou/Async TCP @ ^3.0.2` +- Depends on `mathieucarbou/Async TCP @ ^3.1.2` - Arduino 3 / ESP-IDF 5.1 compatibility ## Documentation diff --git a/library.json b/library.json index 21ab79683..4c89f8e77 100644 --- a/library.json +++ b/library.json @@ -27,7 +27,7 @@ { "owner": "mathieucarbou", "name": "Async TCP", - "version": "^3.0.2", + "version": "^3.1.2", "platforms": "espressif32" }, { diff --git a/platformio.ini b/platformio.ini index 1b922942a..0bcd99ee7 100644 --- a/platformio.ini +++ b/platformio.ini @@ -6,7 +6,7 @@ build_flags = -D CORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_DEBUG lib_deps = bblanchon/ArduinoJson @ 7.0.4 - mathieucarbou/Async TCP @ ^3.0.2 + mathieucarbou/Async TCP @ ^3.1.2 upload_protocol = esptool monitor_speed = 115200 monitor_filters = esp32_exception_decoder, log2file From 8adfc6fac2a3878d771043d9e4742a55ed9c26a7 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Sat, 27 Apr 2024 14:21:58 +0200 Subject: [PATCH 191/551] v2.9.4 --- library.json | 2 +- library.properties | 2 +- src/ESPAsyncWebServer.h | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/library.json b/library.json index 4c89f8e77..476f3c746 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "ESP Async WebServer", - "version": "2.9.3", + "version": "2.9.4", "description": "Asynchronous HTTP and WebSocket Server Library for ESP32. Supports: WebSocket, SSE, Authentication, Arduino Json 7, File Upload, Static File serving, URL Rewrite, URL Redirect, etc.", "keywords": "http,async,websocket,webserver", "homepage": "https://github.com/mathieucarbou/ESPAsyncWebServer", diff --git a/library.properties b/library.properties index d51c521f6..df7780413 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=ESP Async WebServer -version=2.9.3 +version=2.9.4 author=Me-No-Dev maintainer=Mathieu Carbou sentence=Asynchronous HTTP and WebSocket Server Library for ESP32 diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index 3709414d2..ffba008bf 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -40,10 +40,10 @@ #error Platform not supported #endif -#define ASYNCWEBSERVER_VERSION "2.9.3" +#define ASYNCWEBSERVER_VERSION "2.9.4" #define ASYNCWEBSERVER_VERSION_MAJOR 2 #define ASYNCWEBSERVER_VERSION_MINOR 9 -#define ASYNCWEBSERVER_VERSION_REVISION 3 +#define ASYNCWEBSERVER_VERSION_REVISION 4 #define ASYNCWEBSERVER_FORK_mathieucarbou #ifdef ASYNCWEBSERVER_REGEX From cfbe38ca957e84f9724b51cf6622d06b21daa674 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Thu, 2 May 2024 15:33:31 +0200 Subject: [PATCH 192/551] Remove filename after inline in Content-Disposition header according to RFC2183 --- src/WebResponses.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/WebResponses.cpp b/src/WebResponses.cpp index 22a549f65..a783de0f4 100644 --- a/src/WebResponses.cpp +++ b/src/WebResponses.cpp @@ -539,7 +539,7 @@ AsyncFileResponse::AsyncFileResponse(FS &fs, const String& path, const String& c snprintf_P(buf, sizeof (buf), PSTR("attachment; filename=\"%s\""), filename); } else { // set filename and force rendering - snprintf_P(buf, sizeof (buf), PSTR("inline; filename=\"%s\""), filename); + snprintf_P(buf, sizeof (buf), PSTR("inline")); } addHeader(F("Content-Disposition"), buf); } @@ -570,7 +570,7 @@ AsyncFileResponse::AsyncFileResponse(File content, const String& path, const Str if(download) { snprintf_P(buf, sizeof (buf), PSTR("attachment; filename=\"%s\""), filename); } else { - snprintf_P(buf, sizeof (buf), PSTR("inline; filename=\"%s\""), filename); + snprintf_P(buf, sizeof (buf), PSTR("inline")); } addHeader(F("Content-Disposition"), buf); } From d8555ecbb7fa51832a1c02c43879991845babb80 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Thu, 2 May 2024 16:07:26 +0200 Subject: [PATCH 193/551] v2.9.5 --- library.json | 2 +- library.properties | 2 +- src/ESPAsyncWebServer.h | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/library.json b/library.json index 476f3c746..9d18cf490 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "ESP Async WebServer", - "version": "2.9.4", + "version": "2.9.5", "description": "Asynchronous HTTP and WebSocket Server Library for ESP32. Supports: WebSocket, SSE, Authentication, Arduino Json 7, File Upload, Static File serving, URL Rewrite, URL Redirect, etc.", "keywords": "http,async,websocket,webserver", "homepage": "https://github.com/mathieucarbou/ESPAsyncWebServer", diff --git a/library.properties b/library.properties index df7780413..7d383498c 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=ESP Async WebServer -version=2.9.4 +version=2.9.5 author=Me-No-Dev maintainer=Mathieu Carbou sentence=Asynchronous HTTP and WebSocket Server Library for ESP32 diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index ffba008bf..ba3841ac9 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -40,10 +40,10 @@ #error Platform not supported #endif -#define ASYNCWEBSERVER_VERSION "2.9.4" +#define ASYNCWEBSERVER_VERSION "2.9.5" #define ASYNCWEBSERVER_VERSION_MAJOR 2 #define ASYNCWEBSERVER_VERSION_MINOR 9 -#define ASYNCWEBSERVER_VERSION_REVISION 4 +#define ASYNCWEBSERVER_VERSION_REVISION 5 #define ASYNCWEBSERVER_FORK_mathieucarbou #ifdef ASYNCWEBSERVER_REGEX From 376a2e7f6e9f63d8cb3010715c4776d91a137741 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Sun, 5 May 2024 15:43:31 +0200 Subject: [PATCH 194/551] StreamConcat example --- examples/StreamFiles/StreamConcat.h | 33 +++++++++++++ examples/StreamFiles/StreamFiles.ino | 73 ++++++++++++++++++++++++++++ examples/StreamFiles/StreamString.h | 36 ++++++++++++++ platformio.ini | 5 +- 4 files changed, 145 insertions(+), 2 deletions(-) create mode 100644 examples/StreamFiles/StreamConcat.h create mode 100644 examples/StreamFiles/StreamFiles.ino create mode 100644 examples/StreamFiles/StreamString.h diff --git a/examples/StreamFiles/StreamConcat.h b/examples/StreamFiles/StreamConcat.h new file mode 100644 index 000000000..ba95ebe8c --- /dev/null +++ b/examples/StreamFiles/StreamConcat.h @@ -0,0 +1,33 @@ +#pragma once + +#include + +class StreamConcat : public Stream { + public: + StreamConcat(Stream* s1, Stream* s2) : _s1(s1), _s2(s2) {} + + size_t write(const uint8_t* p, size_t n) override { return 0; } + size_t write(uint8_t c) override { return 0; } + void flush() override {} + + int available() override { return _s1->available() + _s2->available(); } + + int read() override { + int c = _s1->read(); + return c != -1 ? c : _s2->read(); + } + + size_t readBytes(char* buffer, size_t length) override { + size_t count = _s1->readBytes(buffer, length); + return count > 0 ? count : _s2->readBytes(buffer, length); + } + + int peek() override { + int c = _s1->peek(); + return c != -1 ? c : _s2->peek(); + } + + private: + Stream* _s1; + Stream* _s2; +}; diff --git a/examples/StreamFiles/StreamFiles.ino b/examples/StreamFiles/StreamFiles.ino new file mode 100644 index 000000000..d5621f574 --- /dev/null +++ b/examples/StreamFiles/StreamFiles.ino @@ -0,0 +1,73 @@ +#include +#include +#ifdef ESP32 +#include +#include +#elif defined(ESP8266) +#include +#include +#endif +#include "StreamConcat.h" +#include "StreamString.h" +#include +#include + +DNSServer dnsServer; +AsyncWebServer server(80); + +void setup() { + Serial.begin(115200); + + LittleFS.begin(); + + WiFi.mode(WIFI_AP); + WiFi.softAP("esp-captive"); + dnsServer.start(53, "*", WiFi.softAPIP()); + + File file1 = LittleFS.open("/header.html", "w"); + file1.print("ESP Captive Portal"); + file1.close(); + + File file2 = LittleFS.open("/body.html", "w"); + file2.print("

Welcome to ESP Captive Portal

"); + file2.close(); + + File file3 = LittleFS.open("/footer.html", "w"); + file3.print(""); + file3.close(); + + server.on("/", HTTP_GET, [](AsyncWebServerRequest* request) { + File header = LittleFS.open("/header.html", "r"); + File body = LittleFS.open("/body.html", "r"); + StreamConcat stream1(&header, &body); + + StreamString content; + content.printf("FreeHeap: %" PRIu32, ESP.getFreeHeap()); + StreamConcat stream2 = StreamConcat(&stream1, &content); + + File footer = LittleFS.open("/footer.html", "r"); + StreamConcat stream3 = StreamConcat(&stream2, &footer); + + request->send(stream3, "text/html", stream3.available()); + header.close(); + body.close(); + footer.close(); + }); + + server.onNotFound([](AsyncWebServerRequest* request) { + request->send(404, "text/plain", "Not found"); + }); + + server.begin(); +} + +uint32_t last = 0; + +void loop() { + // dnsServer.processNextRequest(); + + if (millis() - last > 2000) { + Serial.printf("FreeHeap: %" PRIu32, ESP.getFreeHeap()); + last = millis(); + } +} \ No newline at end of file diff --git a/examples/StreamFiles/StreamString.h b/examples/StreamFiles/StreamString.h new file mode 100644 index 000000000..f392b4525 --- /dev/null +++ b/examples/StreamFiles/StreamString.h @@ -0,0 +1,36 @@ +#pragma once + +#include + +class StreamString : public Stream { + public: + size_t write(const uint8_t* p, size_t n) override { return _buffer.concat(reinterpret_cast(p), n) ? n : 0; } + size_t write(uint8_t c) override { return _buffer.concat(static_cast(c)) ? 1 : 0; } + void flush() override {} + + int available() override { return static_cast(_buffer.length()); } + + int read() override { + if (_buffer.length() == 0) + return -1; + char c = _buffer[0]; + _buffer.remove(0, 1); + return c; + } + + size_t readBytes(char* buffer, size_t length) override { + if (length > _buffer.length()) + length = _buffer.length(); + // Don't use _str.ToCharArray() because it inserts a terminator + memcpy(buffer, _buffer.c_str(), length); + _buffer.remove(0, static_cast(length)); + return length; + } + + int peek() override { return _buffer.length() > 0 ? _buffer[0] : -1; } + + const String& buffer() const { return _buffer; } + + private: + String _buffer; +}; diff --git a/platformio.ini b/platformio.ini index 0bcd99ee7..cdb03818c 100644 --- a/platformio.ini +++ b/platformio.ini @@ -3,7 +3,7 @@ framework = arduino build_flags = -Wall -Wextra -D CONFIG_ARDUHAL_LOG_COLORS - -D CORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_DEBUG + ; -D CORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_DEBUG lib_deps = bblanchon/ArduinoJson @ 7.0.4 mathieucarbou/Async TCP @ ^3.1.2 @@ -13,8 +13,9 @@ monitor_filters = esp32_exception_decoder, log2file [platformio] lib_dir = . -src_dir = examples/CaptivePortal +; src_dir = examples/CaptivePortal ; src_dir = examples/SimpleServer +src_dir = examples/StreamFiles [env:v660] platform = espressif32@6.6.0 From 84e7ad383ddd61dc2c5978f25555fae273b9789d Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Tue, 7 May 2024 10:02:08 +0200 Subject: [PATCH 195/551] Update dependabot.yml Signed-off-by: Mathieu Carbou --- .github/dependabot.yml | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index bd654c27b..dfd0e3086 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,20 +1,10 @@ -# 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 all configuration options: -# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates +# Set update schedule for GitHub Actions version: 2 updates: - - package-ecosystem: "gitsubmodule" - directory: "/" - schedule: - interval: "daily" - reviewers: - - "mathieucarbou" - package-ecosystem: "github-actions" directory: "/" schedule: - interval: "daily" - reviewers: - - "mathieucarbou" + # Check for updates to GitHub Actions every week + interval: "weekly" From 10c6b04e1da0beac9c93482844a9154ccb890a43 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Wed, 15 May 2024 07:53:11 +0200 Subject: [PATCH 196/551] Update CI --- .github/workflows/ci.yml | 20 ++++++++++---------- platformio.ini | 6 +++--- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5c3e097df..62d56cd6b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -70,14 +70,14 @@ jobs: board: esp32dev platform: espressif32 opts: - - name: esp32dev|espressif32@6.6.0 + - name: esp32dev|espressif32@6.7.0 board: esp32dev - platform: espressif32@6.6.0 + platform: espressif32@6.7.0 opts: - - name: esp32dev|arduino@3.0.0-rc1 + - name: esp32dev|arduino@3 board: esp32dev platform: espressif32 - opts: "--project-option 'platform_packages=platformio/framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#3.0.0-rc1, platform_packages=platformio/framework-arduinoespressif32-libs @ https://github.com/espressif/esp32-arduino-libs.git#idf-release/v5.1'" + opts: "--project-option 'platform_packages=platformio/framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#3.0.0-rc2, platform_packages=platformio/framework-arduinoespressif32-libs @ https://github.com/espressif/esp32-arduino-libs.git#idf-release/v5.1'" - name: esp32dev|arduino@master board: esp32dev platform: espressif32 @@ -86,14 +86,14 @@ jobs: board: esp32-s3-devkitc-1 platform: espressif32 opts: - - name: esp32-s3-devkitc-1|espressif32@6.6.0 + - name: esp32-s3-devkitc-1|espressif32@6.7.0 board: esp32-s3-devkitc-1 - platform: espressif32@6.6.0 + platform: espressif32@6.7.0 opts: - - name: esp32-s3-devkitc-1|arduino@3.0.0-rc1 + - name: esp32-s3-devkitc-1|arduino@3 board: esp32-s3-devkitc-1 platform: espressif32 - opts: "--project-option 'platform_packages=platformio/framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#3.0.0-rc1, platform_packages=platformio/framework-arduinoespressif32-libs @ https://github.com/espressif/esp32-arduino-libs.git#idf-release/v5.1'" + opts: "--project-option 'platform_packages=platformio/framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#3.0.0-rc2, platform_packages=platformio/framework-arduinoespressif32-libs @ https://github.com/espressif/esp32-arduino-libs.git#idf-release/v5.1'" - name: esp32-s3-devkitc-1|arduino@master board: esp32-s3-devkitc-1 platform: espressif32 @@ -102,10 +102,10 @@ jobs: board: huzzah platform: espressif8266 opts: - - name: huzzah|arduino@3.0.0-rc1 + - name: huzzah|arduino@3 board: huzzah platform: espressif8266 - opts: "--project-option 'platform_packages=platformio/framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#3.0.0-rc1, platform_packages=platformio/framework-arduinoespressif32-libs @ https://github.com/espressif/esp32-arduino-libs.git#idf-release/v5.1'" + opts: "--project-option 'platform_packages=platformio/framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#3.0.0-rc2, platform_packages=platformio/framework-arduinoespressif32-libs @ https://github.com/espressif/esp32-arduino-libs.git#idf-release/v5.1'" steps: - uses: actions/checkout@v4 - name: Set up cache diff --git a/platformio.ini b/platformio.ini index cdb03818c..ca52a3cbc 100644 --- a/platformio.ini +++ b/platformio.ini @@ -18,7 +18,7 @@ lib_dir = . src_dir = examples/StreamFiles [env:v660] -platform = espressif32@6.6.0 +platform = espressif32@6.7.0 board = esp32dev [env:latest-espressif32] @@ -32,10 +32,10 @@ platform_packages= platformio/framework-arduinoespressif32-libs @ https://github.com/espressif/esp32-arduino-libs.git#idf-release/v5.1 board = esp32dev -[env:v300-rc1] +[env:arduino-v3] platform = espressif32 platform_packages= - platformio/framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#3.0.0-rc1 + platformio/framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#3.0.0-rc2 platformio/framework-arduinoespressif32-libs @ https://github.com/espressif/esp32-arduino-libs.git#idf-release/v5.1 board = esp32dev From 2800e23a3bbd2de243c24c573d790680cbb78dcb Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Fri, 17 May 2024 18:41:24 +0200 Subject: [PATCH 197/551] typo --- platformio.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platformio.ini b/platformio.ini index ca52a3cbc..13df049ba 100644 --- a/platformio.ini +++ b/platformio.ini @@ -17,7 +17,7 @@ lib_dir = . ; src_dir = examples/SimpleServer src_dir = examples/StreamFiles -[env:v660] +[env:v6] platform = espressif32@6.7.0 board = esp32dev From 6c03ef8ae75b35ea77dd54cb8cf3c184cd0a2559 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Fri, 17 May 2024 18:41:34 +0200 Subject: [PATCH 198/551] Add setAuthentication(const String& username, const String& password) --- src/ESPAsyncWebServer.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index ba3841ac9..6f4000c4d 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -363,6 +363,7 @@ class AsyncWebHandler { AsyncWebHandler():_username(""), _password(""){} AsyncWebHandler& setFilter(ArRequestFilterFunction fn) { _filter = fn; return *this; } AsyncWebHandler& setAuthentication(const char *username, const char *password){ _username = String(username);_password = String(password); return *this; }; + AsyncWebHandler& setAuthentication(const String& username, const String& password){ _username = username;_password = password; return *this; }; bool filter(AsyncWebServerRequest *request){ return _filter == NULL || _filter(request); } virtual ~AsyncWebHandler(){} virtual bool canHandle(AsyncWebServerRequest *request __attribute__((unused))){ From 9a0f72e394dc781879c33d3bf4773c467f07262d Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Fri, 17 May 2024 18:56:08 +0200 Subject: [PATCH 199/551] v2.10.0 --- library.json | 2 +- library.properties | 2 +- src/ESPAsyncWebServer.h | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/library.json b/library.json index 9d18cf490..b0e231d2d 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "ESP Async WebServer", - "version": "2.9.5", + "version": "2.10.0", "description": "Asynchronous HTTP and WebSocket Server Library for ESP32. Supports: WebSocket, SSE, Authentication, Arduino Json 7, File Upload, Static File serving, URL Rewrite, URL Redirect, etc.", "keywords": "http,async,websocket,webserver", "homepage": "https://github.com/mathieucarbou/ESPAsyncWebServer", diff --git a/library.properties b/library.properties index 7d383498c..0d7e42bae 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=ESP Async WebServer -version=2.9.5 +version=2.10.0 author=Me-No-Dev maintainer=Mathieu Carbou sentence=Asynchronous HTTP and WebSocket Server Library for ESP32 diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index 6f4000c4d..8f720e37b 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -40,10 +40,10 @@ #error Platform not supported #endif -#define ASYNCWEBSERVER_VERSION "2.9.5" +#define ASYNCWEBSERVER_VERSION "2.10.0" #define ASYNCWEBSERVER_VERSION_MAJOR 2 -#define ASYNCWEBSERVER_VERSION_MINOR 9 -#define ASYNCWEBSERVER_VERSION_REVISION 5 +#define ASYNCWEBSERVER_VERSION_MINOR 10 +#define ASYNCWEBSERVER_VERSION_REVISION 0 #define ASYNCWEBSERVER_FORK_mathieucarbou #ifdef ASYNCWEBSERVER_REGEX From e9984a6616583799cb3f63a15e08d357085401dd Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Fri, 24 May 2024 21:22:11 +0200 Subject: [PATCH 200/551] arduino-esp32.git#3.0.0-rc3 --- .github/workflows/ci.yml | 6 +++--- platformio.ini | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 62d56cd6b..6bb3d46fd 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -77,7 +77,7 @@ jobs: - name: esp32dev|arduino@3 board: esp32dev platform: espressif32 - opts: "--project-option 'platform_packages=platformio/framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#3.0.0-rc2, platform_packages=platformio/framework-arduinoespressif32-libs @ https://github.com/espressif/esp32-arduino-libs.git#idf-release/v5.1'" + opts: "--project-option 'platform_packages=platformio/framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#3.0.0-rc3, platform_packages=platformio/framework-arduinoespressif32-libs @ https://github.com/espressif/esp32-arduino-libs.git#idf-release/v5.1'" - name: esp32dev|arduino@master board: esp32dev platform: espressif32 @@ -93,7 +93,7 @@ jobs: - name: esp32-s3-devkitc-1|arduino@3 board: esp32-s3-devkitc-1 platform: espressif32 - opts: "--project-option 'platform_packages=platformio/framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#3.0.0-rc2, platform_packages=platformio/framework-arduinoespressif32-libs @ https://github.com/espressif/esp32-arduino-libs.git#idf-release/v5.1'" + opts: "--project-option 'platform_packages=platformio/framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#3.0.0-rc3, platform_packages=platformio/framework-arduinoespressif32-libs @ https://github.com/espressif/esp32-arduino-libs.git#idf-release/v5.1'" - name: esp32-s3-devkitc-1|arduino@master board: esp32-s3-devkitc-1 platform: espressif32 @@ -105,7 +105,7 @@ jobs: - name: huzzah|arduino@3 board: huzzah platform: espressif8266 - opts: "--project-option 'platform_packages=platformio/framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#3.0.0-rc2, platform_packages=platformio/framework-arduinoespressif32-libs @ https://github.com/espressif/esp32-arduino-libs.git#idf-release/v5.1'" + opts: "--project-option 'platform_packages=platformio/framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#3.0.0-rc3, platform_packages=platformio/framework-arduinoespressif32-libs @ https://github.com/espressif/esp32-arduino-libs.git#idf-release/v5.1'" steps: - uses: actions/checkout@v4 - name: Set up cache diff --git a/platformio.ini b/platformio.ini index 13df049ba..d460fc1d8 100644 --- a/platformio.ini +++ b/platformio.ini @@ -3,7 +3,7 @@ framework = arduino build_flags = -Wall -Wextra -D CONFIG_ARDUHAL_LOG_COLORS - ; -D CORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_DEBUG + -D CORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_VERBOSE lib_deps = bblanchon/ArduinoJson @ 7.0.4 mathieucarbou/Async TCP @ ^3.1.2 @@ -13,9 +13,9 @@ monitor_filters = esp32_exception_decoder, log2file [platformio] lib_dir = . -; src_dir = examples/CaptivePortal +src_dir = examples/CaptivePortal ; src_dir = examples/SimpleServer -src_dir = examples/StreamFiles +; src_dir = examples/StreamFiles [env:v6] platform = espressif32@6.7.0 @@ -35,7 +35,7 @@ board = esp32dev [env:arduino-v3] platform = espressif32 platform_packages= - platformio/framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#3.0.0-rc2 + platformio/framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#3.0.0-rc3 platformio/framework-arduinoespressif32-libs @ https://github.com/espressif/esp32-arduino-libs.git#idf-release/v5.1 board = esp32dev From d5fee3f9d888703b5b9426b99489e7441e710f24 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Sun, 26 May 2024 13:56:14 +0200 Subject: [PATCH 201/551] Fix logging --- src/AsyncEventSource.cpp | 6 +++++- src/AsyncWebSocket.cpp | 4 ++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/AsyncEventSource.cpp b/src/AsyncEventSource.cpp index 1c34c85ce..98f18dea4 100644 --- a/src/AsyncEventSource.cpp +++ b/src/AsyncEventSource.cpp @@ -193,7 +193,11 @@ void AsyncEventSourceClient::_queueMessage(AsyncEventSourceMessage *dataMessage) //length() is not thread-safe, thus acquiring the lock before this call.. _lockmq.lock(); if(_messageQueue.length() >= SSE_MAX_QUEUED_MESSAGES){ - ets_printf(String(F("ERROR: Too many messages queued\n")).c_str()); +#ifdef ESP8266 + ets_printf(String(F("ERROR: Too many messages queued\n")).c_str()); +#else + log_e("Too many messages queued: deleting message"); +#endif delete dataMessage; } else { _messageQueue.add(dataMessage); diff --git a/src/AsyncWebSocket.cpp b/src/AsyncWebSocket.cpp index 594ffb5cf..787b52a96 100644 --- a/src/AsyncWebSocket.cpp +++ b/src/AsyncWebSocket.cpp @@ -461,7 +461,11 @@ void AsyncWebSocketClient::_queueMessage(std::shared_ptr> b if (_messageQueue.size() >= WS_MAX_QUEUED_MESSAGES) { l.unlock(); +#ifdef ESP8266 ets_printf("AsyncWebSocketClient::_queueMessage: Too many messages queued, closing connection\n"); +#else + log_e("Too many messages queued: closing connection"); +#endif _status = WS_DISCONNECTED; if (_client) _client->close(true); return; From a28843b24f9baa9e6599af4e6a92f87cfa06383a Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Mon, 27 May 2024 13:31:24 +0200 Subject: [PATCH 202/551] Fix CI --- .github/workflows/ci.yml | 28 ++++++++-------------------- platformio.ini | 19 ++++++------------- 2 files changed, 14 insertions(+), 33 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6bb3d46fd..80d213cbb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -66,46 +66,34 @@ jobs: fail-fast: false matrix: include: - - name: esp32dev|espressif32 + - name: esp32dev|arduino board: esp32dev platform: espressif32 opts: - - name: esp32dev|espressif32@6.7.0 + - name: esp32dev|arduino-2 board: esp32dev platform: espressif32@6.7.0 opts: - - name: esp32dev|arduino@3 + - name: esp32dev|arduino-3 board: esp32dev platform: espressif32 - opts: "--project-option 'platform_packages=platformio/framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#3.0.0-rc3, platform_packages=platformio/framework-arduinoespressif32-libs @ https://github.com/espressif/esp32-arduino-libs.git#idf-release/v5.1'" - - name: esp32dev|arduino@master - board: esp32dev - platform: espressif32 - opts: "--project-option 'platform_packages=platformio/framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#master, platform_packages=platformio/framework-arduinoespressif32-libs @ https://github.com/espressif/esp32-arduino-libs.git#idf-release/v5.1'" - - name: esp32-s3-devkitc-1|espressif32 + opts: "--project-option 'platform_packages=platformio/framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#3.0.0-rc3, platform_packages=platformio/framework-arduinoespressif32-libs @ https://github.com/espressif/esp32-arduino-libs.git#951ade74d7886e1ce931ea46614c4ac47ae3a6c0'" + - name: esp32-s3-devkitc-1|arduino board: esp32-s3-devkitc-1 platform: espressif32 opts: - - name: esp32-s3-devkitc-1|espressif32@6.7.0 + - name: esp32-s3-devkitc-1|arduino-2 board: esp32-s3-devkitc-1 platform: espressif32@6.7.0 opts: - - name: esp32-s3-devkitc-1|arduino@3 - board: esp32-s3-devkitc-1 - platform: espressif32 - opts: "--project-option 'platform_packages=platformio/framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#3.0.0-rc3, platform_packages=platformio/framework-arduinoespressif32-libs @ https://github.com/espressif/esp32-arduino-libs.git#idf-release/v5.1'" - - name: esp32-s3-devkitc-1|arduino@master + - name: esp32-s3-devkitc-1|arduino-3 board: esp32-s3-devkitc-1 platform: espressif32 - opts: "--project-option 'platform_packages=platformio/framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#master, platform_packages=platformio/framework-arduinoespressif32-libs @ https://github.com/espressif/esp32-arduino-libs.git#idf-release/v5.1'" + opts: "--project-option 'platform_packages=platformio/framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#3.0.0-rc3, platform_packages=platformio/framework-arduinoespressif32-libs @ https://github.com/espressif/esp32-arduino-libs.git#951ade74d7886e1ce931ea46614c4ac47ae3a6c0'" - name: huzzah|espressif8266 board: huzzah platform: espressif8266 opts: - - name: huzzah|arduino@3 - board: huzzah - platform: espressif8266 - opts: "--project-option 'platform_packages=platformio/framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#3.0.0-rc3, platform_packages=platformio/framework-arduinoespressif32-libs @ https://github.com/espressif/esp32-arduino-libs.git#idf-release/v5.1'" steps: - uses: actions/checkout@v4 - name: Set up cache diff --git a/platformio.ini b/platformio.ini index d460fc1d8..d71d42c83 100644 --- a/platformio.ini +++ b/platformio.ini @@ -17,26 +17,19 @@ src_dir = examples/CaptivePortal ; src_dir = examples/SimpleServer ; src_dir = examples/StreamFiles -[env:v6] -platform = espressif32@6.7.0 -board = esp32dev - -[env:latest-espressif32] -platform = https://github.com/platformio/platform-espressif32.git +[env:arduino] +platform = espressif32 board = esp32dev -[env:latest-arduino] -platform = espressif32 -platform_packages= - platformio/framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#master - platformio/framework-arduinoespressif32-libs @ https://github.com/espressif/esp32-arduino-libs.git#idf-release/v5.1 +[env:arduino-2] +platform = espressif32@6.7.0 board = esp32dev -[env:arduino-v3] +[env:arduino-3] platform = espressif32 platform_packages= platformio/framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#3.0.0-rc3 - platformio/framework-arduinoespressif32-libs @ https://github.com/espressif/esp32-arduino-libs.git#idf-release/v5.1 + platformio/framework-arduinoespressif32-libs @ https://github.com/espressif/esp32-arduino-libs.git#951ade74d7886e1ce931ea46614c4ac47ae3a6c0 board = esp32dev [env:esp8266] From ae42fb41f485999a4b8fd31a716b2e6c404246a8 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Mon, 27 May 2024 21:03:54 +0200 Subject: [PATCH 203/551] Update CI to Arduino 3 --- .github/workflows/ci.yml | 4 ++-- platformio.ini | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 80d213cbb..79d59d9f9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -77,7 +77,7 @@ jobs: - name: esp32dev|arduino-3 board: esp32dev platform: espressif32 - opts: "--project-option 'platform_packages=platformio/framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#3.0.0-rc3, platform_packages=platformio/framework-arduinoespressif32-libs @ https://github.com/espressif/esp32-arduino-libs.git#951ade74d7886e1ce931ea46614c4ac47ae3a6c0'" + opts: "--project-option 'platform_packages=platformio/framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#3.0.0, platform_packages=platformio/framework-arduinoespressif32-libs @ https://github.com/espressif/arduino-esp32/releases/download/3.0.0/esp32-arduino-libs-3.0.0.zip'" - name: esp32-s3-devkitc-1|arduino board: esp32-s3-devkitc-1 platform: espressif32 @@ -89,7 +89,7 @@ jobs: - name: esp32-s3-devkitc-1|arduino-3 board: esp32-s3-devkitc-1 platform: espressif32 - opts: "--project-option 'platform_packages=platformio/framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#3.0.0-rc3, platform_packages=platformio/framework-arduinoespressif32-libs @ https://github.com/espressif/esp32-arduino-libs.git#951ade74d7886e1ce931ea46614c4ac47ae3a6c0'" + opts: "--project-option 'platform_packages=platformio/framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#3.0.0, platform_packages=platformio/framework-arduinoespressif32-libs @ https://github.com/espressif/arduino-esp32/releases/download/3.0.0/esp32-arduino-libs-3.0.0.zip'" - name: huzzah|espressif8266 board: huzzah platform: espressif8266 diff --git a/platformio.ini b/platformio.ini index d71d42c83..c6182607e 100644 --- a/platformio.ini +++ b/platformio.ini @@ -28,8 +28,8 @@ board = esp32dev [env:arduino-3] platform = espressif32 platform_packages= - platformio/framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#3.0.0-rc3 - platformio/framework-arduinoespressif32-libs @ https://github.com/espressif/esp32-arduino-libs.git#951ade74d7886e1ce931ea46614c4ac47ae3a6c0 + platformio/framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#3.0.0 + platformio/framework-arduinoespressif32-libs @ https://github.com/espressif/arduino-esp32/releases/download/3.0.0/esp32-arduino-libs-3.0.0.zip board = esp32dev [env:esp8266] From 99dec2fb37d56f1dfb147157a99cf079ebed2c5c Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Tue, 28 May 2024 20:25:57 +0200 Subject: [PATCH 204/551] update doc --- README.md | 3 +++ docs/index.md | 3 +++ 2 files changed, 6 insertions(+) diff --git a/README.md b/README.md index ee7bb0529..5c9ffb9ba 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,9 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo - [#5](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/5) ([@vortigont](https://github.com/vortigont)): set real "Last-Modified" header based on file's LastWrite time - [#13](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/13) ([@tueddy](https://github.com/tueddy)): Compile with Arduino 3 (ESP-IDF 5.1) - [#14](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/14) ([@nilo85](https://github.com/nilo85)): Add support for Auth & GET requests in AsyncCallbackJsonWebHandler +- Added `setAuthentication(const String& username, const String& password)` +- Added `StreamConcat` example to shoiw how to stream multiple files in one response +- Remove filename after inline in Content-Disposition header according to RFC2183 - Depends on `mathieucarbou/Async TCP @ ^3.1.2` - Arduino 3 / ESP-IDF 5.1 compatibility diff --git a/docs/index.md b/docs/index.md index ee7bb0529..5c9ffb9ba 100644 --- a/docs/index.md +++ b/docs/index.md @@ -23,6 +23,9 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo - [#5](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/5) ([@vortigont](https://github.com/vortigont)): set real "Last-Modified" header based on file's LastWrite time - [#13](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/13) ([@tueddy](https://github.com/tueddy)): Compile with Arduino 3 (ESP-IDF 5.1) - [#14](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/14) ([@nilo85](https://github.com/nilo85)): Add support for Auth & GET requests in AsyncCallbackJsonWebHandler +- Added `setAuthentication(const String& username, const String& password)` +- Added `StreamConcat` example to shoiw how to stream multiple files in one response +- Remove filename after inline in Content-Disposition header according to RFC2183 - Depends on `mathieucarbou/Async TCP @ ^3.1.2` - Arduino 3 / ESP-IDF 5.1 compatibility From 108bdbf77360aa043cda02bb1d70f3e631e5aef7 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Tue, 28 May 2024 22:07:49 +0200 Subject: [PATCH 205/551] Set architectures=esp8266,esp32 in library.properties --- library.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library.properties b/library.properties index 0d7e42bae..cae31998d 100644 --- a/library.properties +++ b/library.properties @@ -6,5 +6,5 @@ sentence=Asynchronous HTTP and WebSocket Server Library for ESP32 paragraph=Supports: WebSocket, SSE, Authentication, Arduino Json 7, File Upload, Static File serving, URL Rewrite, URL Redirect, etc category=Other url=https://github.com/mathieucarbou/ESPAsyncWebServer -architectures=* +architectures=esp8266,esp32 license=LGPL-3.0 From 499c455844bace6e9e74fa8b674d32f5a954a1f5 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Wed, 29 May 2024 21:59:53 +0200 Subject: [PATCH 206/551] Added Filters example to reproduce https://github.com/mathieucarbou/ESPAsyncWebServer/issues/26 --- .github/workflows/ci.yml | 5 ++ examples/Filters/Filters.ino | 110 +++++++++++++++++++++++++++++++++++ platformio.ini | 5 +- 3 files changed, 119 insertions(+), 1 deletion(-) create mode 100644 examples/Filters/Filters.ino diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 79d59d9f9..925ac0fff 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -59,6 +59,9 @@ jobs: - name: Build SimpleServer run: arduino-cli compile --library . --warnings none -b ${{ matrix.board }} "examples/SimpleServer/SimpleServer.ino" + - name: Build Filters + run: arduino-cli compile --library . --warnings none -b ${{ matrix.board }} "examples/Filters/Filters.ino" + platformio: name: pio ${{ matrix.name }} runs-on: ubuntu-latest @@ -112,3 +115,5 @@ jobs: run: platformio ci "examples/CaptivePortal/CaptivePortal.ino" -l '.' -b ${{ matrix.board }} ${{ matrix.opts }} - name: Build SimpleServer run: platformio ci "examples/SimpleServer/SimpleServer.ino" -l '.' -b ${{ matrix.board }} ${{ matrix.opts }} + - name: Build Filters + run: platformio ci "examples/Filters/Filters.ino" -l '.' -b ${{ matrix.board }} ${{ matrix.opts }} diff --git a/examples/Filters/Filters.ino b/examples/Filters/Filters.ino new file mode 100644 index 000000000..417b88c0d --- /dev/null +++ b/examples/Filters/Filters.ino @@ -0,0 +1,110 @@ +// Reproduced issue https://github.com/mathieucarbou/ESPAsyncWebServer/issues/26 +// The issue is present when using mathieucarbou/Async TCP @ ^3.1.2 (which is based on ESPHome fork) +// The issue is not present when directly using https://github.com/me-no-dev/AsyncTCP + +#include +#ifdef ESP32 +#include +#include +#elif defined(ESP8266) +#include +#include +#endif +#include "ESPAsyncWebServer.h" + +DNSServer dnsServer; +AsyncWebServer server(80); + +class CaptiveRequestHandler : public AsyncWebHandler { + public: + CaptiveRequestHandler() {} + virtual ~CaptiveRequestHandler() {} + + bool canHandle(AsyncWebServerRequest* request) { + // request->addInterestingHeader("ANY"); + return true; + } + + void handleRequest(AsyncWebServerRequest* request) { + AsyncResponseStream* response = request->beginResponseStream("text/html"); + response->print("Captive Portal"); + response->print("

This is out captive portal front page.

"); + response->printf("

You were trying to reach: http://%s%s

", request->host().c_str(), request->url().c_str()); + response->printf("

Try opening this link instead

", WiFi.softAPIP().toString().c_str()); + response->print(""); + request->send(response); + } +}; + +bool hit1 = false; +bool hit2 = false; + +void setup() { + Serial.begin(115200); + + server + .on("/", HTTP_GET, [](AsyncWebServerRequest* request) { + Serial.println("Captive portal request..."); + Serial.println("WiFi.localIP(): " + WiFi.localIP().toString()); + Serial.println("request->client()->localIP(): " + request->client()->localIP().toString()); +#if ESP_IDF_VERSION_MAJOR >= 5 + Serial.println("WiFi.type(): " + String((int)WiFi.localIP().type())); + Serial.println("request->client()->type(): " + String((int)request->client()->localIP().type())); +#endif + Serial.println(WiFi.localIP() == request->client()->localIP() ? "should be: ON_STA_FILTER" : "should be: ON_AP_FILTER"); + Serial.println(WiFi.localIP() == request->client()->localIP()); + Serial.println(WiFi.localIP().toString() == request->client()->localIP().toString()); + request->send(200, "text/plain", "This is the captive portal"); + hit1 = true; + }) + .setFilter(ON_AP_FILTER); + + server + .on("/", HTTP_GET, [](AsyncWebServerRequest* request) { + Serial.println("Website request..."); + Serial.println("WiFi.localIP(): " + WiFi.localIP().toString()); + Serial.println("request->client()->localIP(): " + request->client()->localIP().toString()); +#if ESP_IDF_VERSION_MAJOR >= 5 + Serial.println("WiFi.type(): " + String((int)WiFi.localIP().type())); + Serial.println("request->client()->type(): " + String((int)request->client()->localIP().type())); +#endif + Serial.println(WiFi.localIP() == request->client()->localIP() ? "should be: ON_STA_FILTER" : "should be: ON_AP_FILTER"); + Serial.println(WiFi.localIP() == request->client()->localIP()); + Serial.println(WiFi.localIP().toString() == request->client()->localIP().toString()); + request->send(200, "text/plain", "This is the website"); + hit2 = true; + }) + .setFilter(ON_STA_FILTER); + + assert(WiFi.softAP("esp-captive-portal")); + dnsServer.start(53, "*", WiFi.softAPIP()); + server.begin(); + Serial.println("Captive portal started!"); + + while (!hit1) { + dnsServer.processNextRequest(); + yield(); + } + delay(1000); // Wait for the client to process the response + + Serial.println("Captive portal opened, stopping it and connecting to WiFi..."); + dnsServer.stop(); + WiFi.softAPdisconnect(); + + WiFi.persistent(false); + WiFi.begin("IoT"); + while (WiFi.status() != WL_CONNECTED) { + delay(500); + } + Serial.println("Connected to WiFi with IP address: " + WiFi.localIP().toString()); + + while (!hit2) { + delay(10); + } + delay(1000); // Wait for the client to process the response + + ESP.restart(); +} + +void loop() { +} diff --git a/platformio.ini b/platformio.ini index c6182607e..e1c9b7540 100644 --- a/platformio.ini +++ b/platformio.ini @@ -7,15 +7,18 @@ build_flags = lib_deps = bblanchon/ArduinoJson @ 7.0.4 mathieucarbou/Async TCP @ ^3.1.2 + ; https://github.com/me-no-dev/AsyncTCP + esphome/ESPAsyncTCP-esphome @ 2.0.0 upload_protocol = esptool monitor_speed = 115200 monitor_filters = esp32_exception_decoder, log2file [platformio] lib_dir = . -src_dir = examples/CaptivePortal +; src_dir = examples/CaptivePortal ; src_dir = examples/SimpleServer ; src_dir = examples/StreamFiles +src_dir = examples/Filters [env:arduino] platform = espressif32 From 23e288940203e83140c1465284711a507ae2819f Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Thu, 30 May 2024 01:15:57 +0200 Subject: [PATCH 207/551] mathieucarbou/Async TCP @ ^3.1.3 --- .github/workflows/ci.yml | 2 +- README.md | 2 +- docs/index.md | 2 +- examples/Filters/Filters.ino | 38 +++++++++++++++++------------------- library.json | 2 +- platformio.ini | 3 ++- 6 files changed, 24 insertions(+), 25 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 925ac0fff..07514e7a4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -48,7 +48,7 @@ jobs: run: arduino-cli core install --additional-urls "${{ matrix.index_url }}" ${{ matrix.core }} - name: Install AsyncTCP-esphome - run: ARDUINO_LIBRARY_ENABLE_UNSAFE_INSTALL=true arduino-cli lib install --git-url https://github.com/mathieucarbou/AsyncTCP#v3.1.2 + run: ARDUINO_LIBRARY_ENABLE_UNSAFE_INSTALL=true arduino-cli lib install --git-url https://github.com/mathieucarbou/AsyncTCP#v3.1.3 - name: Install ESPAsyncTCP-esphome run: ARDUINO_LIBRARY_ENABLE_UNSAFE_INSTALL=true arduino-cli lib install --git-url https://github.com/mathieucarbou/esphome-ESPAsyncTCP#v2.0.0 diff --git a/README.md b/README.md index 5c9ffb9ba..ae7a3b027 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo - Added `setAuthentication(const String& username, const String& password)` - Added `StreamConcat` example to shoiw how to stream multiple files in one response - Remove filename after inline in Content-Disposition header according to RFC2183 -- Depends on `mathieucarbou/Async TCP @ ^3.1.2` +- Depends on `mathieucarbou/Async TCP @ ^3.1.3` - Arduino 3 / ESP-IDF 5.1 compatibility ## Documentation diff --git a/docs/index.md b/docs/index.md index 5c9ffb9ba..ae7a3b027 100644 --- a/docs/index.md +++ b/docs/index.md @@ -26,7 +26,7 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo - Added `setAuthentication(const String& username, const String& password)` - Added `StreamConcat` example to shoiw how to stream multiple files in one response - Remove filename after inline in Content-Disposition header according to RFC2183 -- Depends on `mathieucarbou/Async TCP @ ^3.1.2` +- Depends on `mathieucarbou/Async TCP @ ^3.1.3` - Arduino 3 / ESP-IDF 5.1 compatibility ## Documentation diff --git a/examples/Filters/Filters.ino b/examples/Filters/Filters.ino index 417b88c0d..218828ab0 100644 --- a/examples/Filters/Filters.ino +++ b/examples/Filters/Filters.ino @@ -1,6 +1,4 @@ // Reproduced issue https://github.com/mathieucarbou/ESPAsyncWebServer/issues/26 -// The issue is present when using mathieucarbou/Async TCP @ ^3.1.2 (which is based on ESPHome fork) -// The issue is not present when directly using https://github.com/me-no-dev/AsyncTCP #include #ifdef ESP32 @@ -76,20 +74,20 @@ void setup() { }) .setFilter(ON_STA_FILTER); - assert(WiFi.softAP("esp-captive-portal")); - dnsServer.start(53, "*", WiFi.softAPIP()); - server.begin(); - Serial.println("Captive portal started!"); + // assert(WiFi.softAP("esp-captive-portal")); + // dnsServer.start(53, "*", WiFi.softAPIP()); + // server.begin(); + // Serial.println("Captive portal started!"); - while (!hit1) { - dnsServer.processNextRequest(); - yield(); - } - delay(1000); // Wait for the client to process the response + // while (!hit1) { + // dnsServer.processNextRequest(); + // yield(); + // } + // delay(1000); // Wait for the client to process the response - Serial.println("Captive portal opened, stopping it and connecting to WiFi..."); - dnsServer.stop(); - WiFi.softAPdisconnect(); + // Serial.println("Captive portal opened, stopping it and connecting to WiFi..."); + // dnsServer.stop(); + // WiFi.softAPdisconnect(); WiFi.persistent(false); WiFi.begin("IoT"); @@ -97,13 +95,13 @@ void setup() { delay(500); } Serial.println("Connected to WiFi with IP address: " + WiFi.localIP().toString()); + server.begin(); - while (!hit2) { - delay(10); - } - delay(1000); // Wait for the client to process the response - - ESP.restart(); + // while (!hit2) { + // delay(10); + // } + // delay(1000); // Wait for the client to process the response + // ESP.restart(); } void loop() { diff --git a/library.json b/library.json index b0e231d2d..b859c33b7 100644 --- a/library.json +++ b/library.json @@ -27,7 +27,7 @@ { "owner": "mathieucarbou", "name": "Async TCP", - "version": "^3.1.2", + "version": "^3.1.3", "platforms": "espressif32" }, { diff --git a/platformio.ini b/platformio.ini index e1c9b7540..642841c8c 100644 --- a/platformio.ini +++ b/platformio.ini @@ -6,7 +6,8 @@ build_flags = -D CORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_VERBOSE lib_deps = bblanchon/ArduinoJson @ 7.0.4 - mathieucarbou/Async TCP @ ^3.1.2 + mathieucarbou/Async TCP @ ^3.1.3 + ; https://github.com/mathieucarbou/AsyncTCP ; https://github.com/me-no-dev/AsyncTCP esphome/ESPAsyncTCP-esphome @ 2.0.0 upload_protocol = esptool From 325f0cd261369da3da20de9c4bc29c0e857512f4 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Thu, 30 May 2024 01:36:52 +0200 Subject: [PATCH 208/551] mathieucarbou/Async TCP @ ^3.1.4 --- .github/workflows/ci.yml | 2 +- README.md | 2 +- docs/index.md | 2 +- library.json | 2 +- platformio.ini | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 07514e7a4..405ec9803 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -48,7 +48,7 @@ jobs: run: arduino-cli core install --additional-urls "${{ matrix.index_url }}" ${{ matrix.core }} - name: Install AsyncTCP-esphome - run: ARDUINO_LIBRARY_ENABLE_UNSAFE_INSTALL=true arduino-cli lib install --git-url https://github.com/mathieucarbou/AsyncTCP#v3.1.3 + run: ARDUINO_LIBRARY_ENABLE_UNSAFE_INSTALL=true arduino-cli lib install --git-url https://github.com/mathieucarbou/AsyncTCP#v3.1.4 - name: Install ESPAsyncTCP-esphome run: ARDUINO_LIBRARY_ENABLE_UNSAFE_INSTALL=true arduino-cli lib install --git-url https://github.com/mathieucarbou/esphome-ESPAsyncTCP#v2.0.0 diff --git a/README.md b/README.md index ae7a3b027..97abd4918 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo - Added `setAuthentication(const String& username, const String& password)` - Added `StreamConcat` example to shoiw how to stream multiple files in one response - Remove filename after inline in Content-Disposition header according to RFC2183 -- Depends on `mathieucarbou/Async TCP @ ^3.1.3` +- Depends on `mathieucarbou/Async TCP @ ^3.1.4` - Arduino 3 / ESP-IDF 5.1 compatibility ## Documentation diff --git a/docs/index.md b/docs/index.md index ae7a3b027..97abd4918 100644 --- a/docs/index.md +++ b/docs/index.md @@ -26,7 +26,7 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo - Added `setAuthentication(const String& username, const String& password)` - Added `StreamConcat` example to shoiw how to stream multiple files in one response - Remove filename after inline in Content-Disposition header according to RFC2183 -- Depends on `mathieucarbou/Async TCP @ ^3.1.3` +- Depends on `mathieucarbou/Async TCP @ ^3.1.4` - Arduino 3 / ESP-IDF 5.1 compatibility ## Documentation diff --git a/library.json b/library.json index b859c33b7..1c216e5ad 100644 --- a/library.json +++ b/library.json @@ -27,7 +27,7 @@ { "owner": "mathieucarbou", "name": "Async TCP", - "version": "^3.1.3", + "version": "^3.1.4", "platforms": "espressif32" }, { diff --git a/platformio.ini b/platformio.ini index 642841c8c..daf31e4a1 100644 --- a/platformio.ini +++ b/platformio.ini @@ -6,7 +6,7 @@ build_flags = -D CORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_VERBOSE lib_deps = bblanchon/ArduinoJson @ 7.0.4 - mathieucarbou/Async TCP @ ^3.1.3 + mathieucarbou/Async TCP @ ^3.1.4 ; https://github.com/mathieucarbou/AsyncTCP ; https://github.com/me-no-dev/AsyncTCP esphome/ESPAsyncTCP-esphome @ 2.0.0 From c73725fb0db4a2c4e712f124fb59afd90e38f87c Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Thu, 30 May 2024 01:38:25 +0200 Subject: [PATCH 209/551] v2.10.1 --- library.json | 2 +- library.properties | 2 +- src/ESPAsyncWebServer.h | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/library.json b/library.json index 1c216e5ad..cc6cb9a42 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "ESP Async WebServer", - "version": "2.10.0", + "version": "2.10.1", "description": "Asynchronous HTTP and WebSocket Server Library for ESP32. Supports: WebSocket, SSE, Authentication, Arduino Json 7, File Upload, Static File serving, URL Rewrite, URL Redirect, etc.", "keywords": "http,async,websocket,webserver", "homepage": "https://github.com/mathieucarbou/ESPAsyncWebServer", diff --git a/library.properties b/library.properties index cae31998d..e6ca3667a 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=ESP Async WebServer -version=2.10.0 +version=2.10.1 author=Me-No-Dev maintainer=Mathieu Carbou sentence=Asynchronous HTTP and WebSocket Server Library for ESP32 diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index 8f720e37b..7667e2088 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -40,10 +40,10 @@ #error Platform not supported #endif -#define ASYNCWEBSERVER_VERSION "2.10.0" +#define ASYNCWEBSERVER_VERSION "2.10.1" #define ASYNCWEBSERVER_VERSION_MAJOR 2 #define ASYNCWEBSERVER_VERSION_MINOR 10 -#define ASYNCWEBSERVER_VERSION_REVISION 0 +#define ASYNCWEBSERVER_VERSION_REVISION 1 #define ASYNCWEBSERVER_FORK_mathieucarbou #ifdef ASYNCWEBSERVER_REGEX From b8a7b5362acea55e7c4d450147687aeadc4b6269 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Fri, 31 May 2024 23:41:17 +0200 Subject: [PATCH 210/551] Made sure all flavors of AsyncWebSocket binary(), text(), binaryAll() and textAll() are implemented --- src/AsyncWebSocket.cpp | 58 +++++++++++++++++++++++++++++------------- src/AsyncWebSocket.h | 10 +++++--- 2 files changed, 47 insertions(+), 21 deletions(-) diff --git a/src/AsyncWebSocket.cpp b/src/AsyncWebSocket.cpp index 787b52a96..05dcf1af4 100644 --- a/src/AsyncWebSocket.cpp +++ b/src/AsyncWebSocket.cpp @@ -954,21 +954,19 @@ void AsyncWebSocket::text(uint32_t id, const __FlashStringHelper *data) free(message); } } - -void AsyncWebSocket::textAll(AsyncWebSocketMessageBuffer * buffer) +void AsyncWebSocket::text(uint32_t id, AsyncWebSocketMessageBuffer *buffer) { if (buffer) { - textAll(std::move(buffer->_buffer)); - delete buffer; + text(id, std::move(buffer->_buffer)); + delete buffer; } } - -void AsyncWebSocket::textAll(std::shared_ptr> buffer) +void AsyncWebSocket::text(uint32_t id, std::shared_ptr> buffer) { - for (auto &c : _clients) - if (c.status() == WS_CONNECTED) - c.text(buffer); + if (AsyncWebSocketClient *c = client(id)) + c->text(buffer); } + void AsyncWebSocket::textAll(const uint8_t *message, size_t len) { textAll(makeSharedBuffer(message, len)); @@ -1005,6 +1003,20 @@ void AsyncWebSocket::textAll(const __FlashStringHelper *data) free(message); } } +void AsyncWebSocket::textAll(AsyncWebSocketMessageBuffer * buffer) +{ + if (buffer) { + textAll(std::move(buffer->_buffer)); + delete buffer; + } +} + +void AsyncWebSocket::textAll(std::shared_ptr> buffer) +{ + for (auto &c : _clients) + if (c.status() == WS_CONNECTED) + c.text(buffer); +} void AsyncWebSocket::binary(uint32_t id, const uint8_t *message, size_t len) { @@ -1034,27 +1046,24 @@ void AsyncWebSocket::binary(uint32_t id, const __FlashStringHelper *data, size_t free(message); } } - -void AsyncWebSocket::binaryAll(AsyncWebSocketMessageBuffer * buffer) +void AsyncWebSocket::binary(uint32_t id, AsyncWebSocketMessageBuffer *buffer) { if (buffer) { - binaryAll(std::move(buffer->_buffer)); + binary(id, std::move(buffer->_buffer)); delete buffer; } } - -void AsyncWebSocket::binaryAll(std::shared_ptr> buffer) +void AsyncWebSocket::binary(uint32_t id, std::shared_ptr> buffer) { - for (auto &c : _clients) - if (c.status() == WS_CONNECTED) - c.binary(buffer); + if (AsyncWebSocketClient *c = client(id)) + c->binary(buffer); } + void AsyncWebSocket::binaryAll(const uint8_t *message, size_t len) { binaryAll(makeSharedBuffer(message, len)); } - void AsyncWebSocket::binaryAll(const char *message, size_t len) { binaryAll((const uint8_t *)message, len); @@ -1078,6 +1087,19 @@ void AsyncWebSocket::binaryAll(const __FlashStringHelper *data, size_t len) free(message); } } +void AsyncWebSocket::binaryAll(AsyncWebSocketMessageBuffer * buffer) +{ + if (buffer) { + binaryAll(std::move(buffer->_buffer)); + delete buffer; + } +} +void AsyncWebSocket::binaryAll(std::shared_ptr> buffer) +{ + for (auto &c : _clients) + if (c.status() == WS_CONNECTED) + c.binary(buffer); +} size_t AsyncWebSocket::printf(uint32_t id, const char *format, ...){ AsyncWebSocketClient * c = client(id); diff --git a/src/AsyncWebSocket.h b/src/AsyncWebSocket.h index ac49d2b82..1c5e31497 100644 --- a/src/AsyncWebSocket.h +++ b/src/AsyncWebSocket.h @@ -257,28 +257,32 @@ class AsyncWebSocket: public AsyncWebHandler { void text(uint32_t id, const char *message); void text(uint32_t id, const String &message); void text(uint32_t id, const __FlashStringHelper *message); + void text(uint32_t id, AsyncWebSocketMessageBuffer *buffer); + void text(uint32_t id, std::shared_ptr> buffer); - void textAll(std::shared_ptr> buffer); void textAll(const uint8_t *message, size_t len); void textAll(const char * message, size_t len); void textAll(const char * message); void textAll(const String &message); - void textAll(const __FlashStringHelper *message); // need to convert + void textAll(const __FlashStringHelper *message); void textAll(AsyncWebSocketMessageBuffer *buffer); + void textAll(std::shared_ptr> buffer); void binary(uint32_t id, const uint8_t *message, size_t len); void binary(uint32_t id, const char *message, size_t len); void binary(uint32_t id, const char *message); void binary(uint32_t id, const String &message); void binary(uint32_t id, const __FlashStringHelper *message, size_t len); + void binary(uint32_t id, AsyncWebSocketMessageBuffer *buffer); + void binary(uint32_t id, std::shared_ptr> buffer); - void binaryAll(std::shared_ptr> buffer); void binaryAll(const uint8_t *message, size_t len); void binaryAll(const char *message, size_t len); void binaryAll(const char *message); void binaryAll(const String &message); void binaryAll(const __FlashStringHelper *message, size_t len); void binaryAll(AsyncWebSocketMessageBuffer *buffer); + void binaryAll(std::shared_ptr> buffer); size_t printf(uint32_t id, const char *format, ...) __attribute__ ((format (printf, 3, 4))); size_t printfAll(const char *format, ...) __attribute__ ((format (printf, 2, 3))); From 371506a4a3296c9c520b1f656a86e3a745d54094 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Fri, 31 May 2024 23:45:43 +0200 Subject: [PATCH 211/551] v2.10.2 --- library.json | 2 +- library.properties | 2 +- src/ESPAsyncWebServer.h | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/library.json b/library.json index cc6cb9a42..eff8a2c0e 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "ESP Async WebServer", - "version": "2.10.1", + "version": "2.10.2", "description": "Asynchronous HTTP and WebSocket Server Library for ESP32. Supports: WebSocket, SSE, Authentication, Arduino Json 7, File Upload, Static File serving, URL Rewrite, URL Redirect, etc.", "keywords": "http,async,websocket,webserver", "homepage": "https://github.com/mathieucarbou/ESPAsyncWebServer", diff --git a/library.properties b/library.properties index e6ca3667a..3dd0ef1ab 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=ESP Async WebServer -version=2.10.1 +version=2.10.2 author=Me-No-Dev maintainer=Mathieu Carbou sentence=Asynchronous HTTP and WebSocket Server Library for ESP32 diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index 7667e2088..d412e23b2 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -40,10 +40,10 @@ #error Platform not supported #endif -#define ASYNCWEBSERVER_VERSION "2.10.1" +#define ASYNCWEBSERVER_VERSION "2.10.2" #define ASYNCWEBSERVER_VERSION_MAJOR 2 #define ASYNCWEBSERVER_VERSION_MINOR 10 -#define ASYNCWEBSERVER_VERSION_REVISION 1 +#define ASYNCWEBSERVER_VERSION_REVISION 2 #define ASYNCWEBSERVER_FORK_mathieucarbou #ifdef ASYNCWEBSERVER_REGEX From 67ca4bdd39b7d2d3bcdb20fd14b1393b1bb0bb11 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Fri, 31 May 2024 23:48:12 +0200 Subject: [PATCH 212/551] doc update --- README.md | 1 + docs/index.md | 1 + 2 files changed, 2 insertions(+) diff --git a/README.md b/README.md index 97abd4918..26f1f7329 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,7 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo - Remove filename after inline in Content-Disposition header according to RFC2183 - Depends on `mathieucarbou/Async TCP @ ^3.1.4` - Arduino 3 / ESP-IDF 5.1 compatibility +- Added all flavors of `binary()`, `text()`, `binaryAll()` and `textAll()` in `AsyncWebSocket` ## Documentation diff --git a/docs/index.md b/docs/index.md index 97abd4918..26f1f7329 100644 --- a/docs/index.md +++ b/docs/index.md @@ -28,6 +28,7 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo - Remove filename after inline in Content-Disposition header according to RFC2183 - Depends on `mathieucarbou/Async TCP @ ^3.1.4` - Arduino 3 / ESP-IDF 5.1 compatibility +- Added all flavors of `binary()`, `text()`, `binaryAll()` and `textAll()` in `AsyncWebSocket` ## Documentation From da9cfe7f01e5a8cf4dd7d3ff484c6588db71a330 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Sat, 1 Jun 2024 21:44:20 +0200 Subject: [PATCH 213/551] setCloseClientOnQueueFull(bool): Allow to choose between discard message or close client on queue full --- README.md | 1 + docs/index.md | 1 + src/AsyncWebSocket.cpp | 17 +++++++++++++---- src/AsyncWebSocket.h | 22 ++++++++++++++++++++++ 4 files changed, 37 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 26f1f7329..b10865c7d 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,7 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo - Depends on `mathieucarbou/Async TCP @ ^3.1.4` - Arduino 3 / ESP-IDF 5.1 compatibility - Added all flavors of `binary()`, `text()`, `binaryAll()` and `textAll()` in `AsyncWebSocket` +- Added `setCloseClientOnQueueFull(bool)` which can be set on a client to either close the connection or discard messages but not close the connection when the queue is full ## Documentation diff --git a/docs/index.md b/docs/index.md index 26f1f7329..b10865c7d 100644 --- a/docs/index.md +++ b/docs/index.md @@ -29,6 +29,7 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo - Depends on `mathieucarbou/Async TCP @ ^3.1.4` - Arduino 3 / ESP-IDF 5.1 compatibility - Added all flavors of `binary()`, `text()`, `binaryAll()` and `textAll()` in `AsyncWebSocket` +- Added `setCloseClientOnQueueFull(bool)` which can be set on a client to either close the connection or discard messages but not close the connection when the queue is full ## Documentation diff --git a/src/AsyncWebSocket.cpp b/src/AsyncWebSocket.cpp index 05dcf1af4..f231d2364 100644 --- a/src/AsyncWebSocket.cpp +++ b/src/AsyncWebSocket.cpp @@ -461,13 +461,22 @@ void AsyncWebSocketClient::_queueMessage(std::shared_ptr> b if (_messageQueue.size() >= WS_MAX_QUEUED_MESSAGES) { l.unlock(); + if(closeWhenFull) + { #ifdef ESP8266 - ets_printf("AsyncWebSocketClient::_queueMessage: Too many messages queued, closing connection\n"); + ets_printf("AsyncWebSocketClient::_queueMessage: Too many messages queued: closing connection\n"); #else - log_e("Too many messages queued: closing connection"); + log_e("Too many messages queued: closing connection"); #endif - _status = WS_DISCONNECTED; - if (_client) _client->close(true); + _status = WS_DISCONNECTED; + if (_client) _client->close(true); + } else { +#ifdef ESP8266 + ets_printf("AsyncWebSocketClient::_queueMessage: Too many messages queued: discarding new message\n"); +#else + log_e("Too many messages queued: discarding new message"); +#endif + } return; } else diff --git a/src/AsyncWebSocket.h b/src/AsyncWebSocket.h index 1c5e31497..ab182ea9f 100644 --- a/src/AsyncWebSocket.h +++ b/src/AsyncWebSocket.h @@ -137,6 +137,7 @@ class AsyncWebSocketClient { std::deque _controlQueue; std::deque _messageQueue; + bool closeWhenFull = true; uint8_t _pstate; AwsFrameInfo _pinfo; @@ -164,6 +165,27 @@ class AsyncWebSocketClient { const AsyncWebSocket *server() const { return _server; } AwsFrameInfo const &pinfo() const { return _pinfo; } + // - If "true" (default), the connection will be closed if the message queue is full. + // This is the default behavior in yubox-node-org, which is not silently discarding messages but instead closes the connection. + // The big issue with this behavior is that is can cause the UI to automatically re-create a new WS connection, which can be filled again, + // and so on, causing a resource exhaustion. + // + // - If "false", the incoming message will be discarded if the queue is full. + // This is the default behavior in the original ESPAsyncWebServer library from me-no-dev. + // This behavior allows the best performance at the expense of unreliable message delivery in case the queue is full (some messages may be lost). + // + // - In any case, when the queue is full, a message is logged. + // - IT is recommended to use the methods queueIsFull(), availableForWriteAll(), availableForWrite(clientId) to check if the queue is full before sending a message. + // + // Usage: + // - can be set in the onEvent listener when connecting (event type is: WS_EVT_CONNECT) + // + // Use cases:, + // - if using websocket to send logging messages, maybe some loss is acceptable. + // - But if using websocket to send UI update messages, maybe the connection should be closed and the UI redrawn. + void setCloseClientOnQueueFull(bool close) { closeWhenFull = close; } + bool willCloseClientOnQueueFull() const { return closeWhenFull; } + IPAddress remoteIP() const; uint16_t remotePort() const; From 8d94a03c010e3beacab67b69d27105ff3a007a1d Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Sun, 2 Jun 2024 00:56:49 +0200 Subject: [PATCH 214/551] v2.10.3 --- library.json | 2 +- library.properties | 2 +- src/ESPAsyncWebServer.h | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/library.json b/library.json index eff8a2c0e..a245b5a80 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "ESP Async WebServer", - "version": "2.10.2", + "version": "2.10.3", "description": "Asynchronous HTTP and WebSocket Server Library for ESP32. Supports: WebSocket, SSE, Authentication, Arduino Json 7, File Upload, Static File serving, URL Rewrite, URL Redirect, etc.", "keywords": "http,async,websocket,webserver", "homepage": "https://github.com/mathieucarbou/ESPAsyncWebServer", diff --git a/library.properties b/library.properties index 3dd0ef1ab..fb8bb2817 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=ESP Async WebServer -version=2.10.2 +version=2.10.3 author=Me-No-Dev maintainer=Mathieu Carbou sentence=Asynchronous HTTP and WebSocket Server Library for ESP32 diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index d412e23b2..8069d1b50 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -40,10 +40,10 @@ #error Platform not supported #endif -#define ASYNCWEBSERVER_VERSION "2.10.2" +#define ASYNCWEBSERVER_VERSION "2.10.3" #define ASYNCWEBSERVER_VERSION_MAJOR 2 #define ASYNCWEBSERVER_VERSION_MINOR 10 -#define ASYNCWEBSERVER_VERSION_REVISION 2 +#define ASYNCWEBSERVER_VERSION_REVISION 3 #define ASYNCWEBSERVER_FORK_mathieucarbou #ifdef ASYNCWEBSERVER_REGEX From 470469aaa0d92300d80dd9095f3684e855ff34e9 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Sun, 2 Jun 2024 14:05:43 +0200 Subject: [PATCH 215/551] Fix compiler warnings --- examples/CaptivePortal/CaptivePortal.ino | 2 +- examples/Filters/Filters.ino | 2 +- examples/StreamFiles/StreamConcat.h | 4 ++-- platformio.ini | 4 ++-- src/AsyncJson.h | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/examples/CaptivePortal/CaptivePortal.ino b/examples/CaptivePortal/CaptivePortal.ino index 568170917..c06dccd83 100644 --- a/examples/CaptivePortal/CaptivePortal.ino +++ b/examples/CaptivePortal/CaptivePortal.ino @@ -16,7 +16,7 @@ public: CaptiveRequestHandler() {} virtual ~CaptiveRequestHandler() {} - bool canHandle(AsyncWebServerRequest *request){ + bool canHandle(__unused AsyncWebServerRequest *request){ //request->addInterestingHeader("ANY"); return true; } diff --git a/examples/Filters/Filters.ino b/examples/Filters/Filters.ino index 218828ab0..90b6f19a0 100644 --- a/examples/Filters/Filters.ino +++ b/examples/Filters/Filters.ino @@ -18,7 +18,7 @@ class CaptiveRequestHandler : public AsyncWebHandler { CaptiveRequestHandler() {} virtual ~CaptiveRequestHandler() {} - bool canHandle(AsyncWebServerRequest* request) { + bool canHandle(__unused AsyncWebServerRequest* request) { // request->addInterestingHeader("ANY"); return true; } diff --git a/examples/StreamFiles/StreamConcat.h b/examples/StreamFiles/StreamConcat.h index ba95ebe8c..1a53f2cd9 100644 --- a/examples/StreamFiles/StreamConcat.h +++ b/examples/StreamFiles/StreamConcat.h @@ -6,8 +6,8 @@ class StreamConcat : public Stream { public: StreamConcat(Stream* s1, Stream* s2) : _s1(s1), _s2(s2) {} - size_t write(const uint8_t* p, size_t n) override { return 0; } - size_t write(uint8_t c) override { return 0; } + size_t write(__unused const uint8_t* p, __unused size_t n) override { return 0; } + size_t write(__unused uint8_t c) override { return 0; } void flush() override {} int available() override { return _s1->available() + _s2->available(); } diff --git a/platformio.ini b/platformio.ini index daf31e4a1..eff66778f 100644 --- a/platformio.ini +++ b/platformio.ini @@ -18,8 +18,8 @@ monitor_filters = esp32_exception_decoder, log2file lib_dir = . ; src_dir = examples/CaptivePortal ; src_dir = examples/SimpleServer -; src_dir = examples/StreamFiles -src_dir = examples/Filters +src_dir = examples/StreamFiles +; src_dir = examples/Filters [env:arduino] platform = espressif32 diff --git a/src/AsyncJson.h b/src/AsyncJson.h index b2f6e2eb8..677445401 100644 --- a/src/AsyncJson.h +++ b/src/AsyncJson.h @@ -264,7 +264,7 @@ class AsyncCallbackJsonWebHandler : public AsyncWebHandler { request->send(500); } } - virtual void handleUpload(AsyncWebServerRequest* request, const String& filename, size_t index, uint8_t* data, size_t len, bool final) override final { + virtual void handleUpload(__unused AsyncWebServerRequest* request, __unused const String& filename, __unused size_t index, __unused uint8_t* data, __unused size_t len, __unused bool final) override final { } virtual void handleBody(AsyncWebServerRequest* request, uint8_t* data, size_t len, size_t index, size_t total) override final { if (_onRequest) { From bb5285ba73a3fada72f405cfd008038aa8d067f5 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Sun, 2 Jun 2024 14:17:13 +0200 Subject: [PATCH 216/551] v2.10.4 --- library.json | 2 +- library.properties | 2 +- src/ESPAsyncWebServer.h | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/library.json b/library.json index a245b5a80..539ff5d45 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "ESP Async WebServer", - "version": "2.10.3", + "version": "2.10.4", "description": "Asynchronous HTTP and WebSocket Server Library for ESP32. Supports: WebSocket, SSE, Authentication, Arduino Json 7, File Upload, Static File serving, URL Rewrite, URL Redirect, etc.", "keywords": "http,async,websocket,webserver", "homepage": "https://github.com/mathieucarbou/ESPAsyncWebServer", diff --git a/library.properties b/library.properties index fb8bb2817..fc68a1c3f 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=ESP Async WebServer -version=2.10.3 +version=2.10.4 author=Me-No-Dev maintainer=Mathieu Carbou sentence=Asynchronous HTTP and WebSocket Server Library for ESP32 diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index 8069d1b50..8533df678 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -40,10 +40,10 @@ #error Platform not supported #endif -#define ASYNCWEBSERVER_VERSION "2.10.3" +#define ASYNCWEBSERVER_VERSION "2.10.4" #define ASYNCWEBSERVER_VERSION_MAJOR 2 #define ASYNCWEBSERVER_VERSION_MINOR 10 -#define ASYNCWEBSERVER_VERSION_REVISION 3 +#define ASYNCWEBSERVER_VERSION_REVISION 4 #define ASYNCWEBSERVER_FORK_mathieucarbou #ifdef ASYNCWEBSERVER_REGEX From 4a4adcfa44d1e091927d7a40d6e0a1f54c30ebd6 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Sun, 2 Jun 2024 23:27:25 +0200 Subject: [PATCH 217/551] update doc --- README.md | 24 ++++++------------------ docs/index.md | 24 ++++++------------------ 2 files changed, 12 insertions(+), 36 deletions(-) diff --git a/README.md b/README.md index b10865c7d..7c226acaf 100644 --- a/README.md +++ b/README.md @@ -36,7 +36,8 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo Usage and API stays the same as the original library. Please look at the original libraries for more examples and documentation. -[https://github.com/yubox-node-org/ESPAsyncWebServer](https://github.com/yubox-node-org/ESPAsyncWebServer) +- [https://github.com/me-no-dev/ESPAsyncWebServer](https://github.com/me-no-dev/ESPAsyncWebServer) (original library) +- [https://github.com/yubox-node-org/ESPAsyncWebServer](https://github.com/yubox-node-org/ESPAsyncWebServer) (fork of the original library) ## `AsyncWebSocketMessageBuffer` and `makeBuffer()` @@ -44,9 +45,8 @@ The fork from `yubox-node-org` introduces some breaking API changes compared to This fork is compatible with the original library from `me-no-dev` regarding WebSocket, and wraps the optimizations done by `yubox-node-org` in the `AsyncWebSocketMessageBuffer` class. So you have the choice of which API to use. -I strongly suggest to use the optimized API from `yubox-node-org` as it is much more efficient. -Here is an example for serializing a Json document in a websocket message buffer. This code is compatible with any forks, but not optimized: +Here are examples for serializing a Json document in a websocket message buffer: ```cpp void send(JsonDocument& doc) { @@ -60,28 +60,16 @@ void send(JsonDocument& doc) { } ``` -Here is an example for serializing a Json document in a more optimized way, and compatible with both forks: - ```cpp void send(JsonDocument& doc) { const size_t len = measureJson(doc); -#if defined(ASYNCWEBSERVER_FORK_mathieucarbou) - - // this fork (originally from yubox-node-org), uses another API with shared pointer that better support concurrent use cases then the original project + // this fork (originally from yubox-node-org), uses another API with shared pointer auto buffer = std::make_shared>(len); assert(buffer); // up to you to keep or remove this serializeJson(doc, buffer->data(), len); _ws->textAll(std::move(buffer)); - -#else - - // original API from me-no-dev - AsyncWebSocketMessageBuffer* buffer = _ws->makeBuffer(len); - assert(buffer); // up to you to keep or remove this - serializeJson(doc, buffer->get(), len); - _ws->textAll(buffer); - -#endif } ``` + +I recommend to use the official API `AsyncWebSocketMessageBuffer` to retain further compatibility. diff --git a/docs/index.md b/docs/index.md index b10865c7d..7c226acaf 100644 --- a/docs/index.md +++ b/docs/index.md @@ -36,7 +36,8 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo Usage and API stays the same as the original library. Please look at the original libraries for more examples and documentation. -[https://github.com/yubox-node-org/ESPAsyncWebServer](https://github.com/yubox-node-org/ESPAsyncWebServer) +- [https://github.com/me-no-dev/ESPAsyncWebServer](https://github.com/me-no-dev/ESPAsyncWebServer) (original library) +- [https://github.com/yubox-node-org/ESPAsyncWebServer](https://github.com/yubox-node-org/ESPAsyncWebServer) (fork of the original library) ## `AsyncWebSocketMessageBuffer` and `makeBuffer()` @@ -44,9 +45,8 @@ The fork from `yubox-node-org` introduces some breaking API changes compared to This fork is compatible with the original library from `me-no-dev` regarding WebSocket, and wraps the optimizations done by `yubox-node-org` in the `AsyncWebSocketMessageBuffer` class. So you have the choice of which API to use. -I strongly suggest to use the optimized API from `yubox-node-org` as it is much more efficient. -Here is an example for serializing a Json document in a websocket message buffer. This code is compatible with any forks, but not optimized: +Here are examples for serializing a Json document in a websocket message buffer: ```cpp void send(JsonDocument& doc) { @@ -60,28 +60,16 @@ void send(JsonDocument& doc) { } ``` -Here is an example for serializing a Json document in a more optimized way, and compatible with both forks: - ```cpp void send(JsonDocument& doc) { const size_t len = measureJson(doc); -#if defined(ASYNCWEBSERVER_FORK_mathieucarbou) - - // this fork (originally from yubox-node-org), uses another API with shared pointer that better support concurrent use cases then the original project + // this fork (originally from yubox-node-org), uses another API with shared pointer auto buffer = std::make_shared>(len); assert(buffer); // up to you to keep or remove this serializeJson(doc, buffer->data(), len); _ws->textAll(std::move(buffer)); - -#else - - // original API from me-no-dev - AsyncWebSocketMessageBuffer* buffer = _ws->makeBuffer(len); - assert(buffer); // up to you to keep or remove this - serializeJson(doc, buffer->get(), len); - _ws->textAll(buffer); - -#endif } ``` + +I recommend to use the official API `AsyncWebSocketMessageBuffer` to retain further compatibility. From dff9d30828914ba6a1c580996b147775ea5f02d4 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Tue, 4 Jun 2024 11:14:50 +0200 Subject: [PATCH 218/551] update doc --- README.md | 15 +++++++++++++++ docs/index.md | 15 +++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/README.md b/README.md index 7c226acaf..8c56e7ac3 100644 --- a/README.md +++ b/README.md @@ -73,3 +73,18 @@ void send(JsonDocument& doc) { ``` I recommend to use the official API `AsyncWebSocketMessageBuffer` to retain further compatibility. + +## Stack size and queues + +Here are some important flags to tweak depending on your needs: + +```cpp + // Async TCP queue size + -D CONFIG_ASYNC_TCP_QUEUE_SIZE=128 + // Async TCP async task core + -D CONFIG_ASYNC_TCP_RUNNING_CORE=1 + // Async TCP async stac ksize + -D CONFIG_ASYNC_TCP_STACK_SIZE=8096 + // WebSocket queue size + -D WS_MAX_QUEUED_MESSAGES=64 +``` diff --git a/docs/index.md b/docs/index.md index 7c226acaf..8c56e7ac3 100644 --- a/docs/index.md +++ b/docs/index.md @@ -73,3 +73,18 @@ void send(JsonDocument& doc) { ``` I recommend to use the official API `AsyncWebSocketMessageBuffer` to retain further compatibility. + +## Stack size and queues + +Here are some important flags to tweak depending on your needs: + +```cpp + // Async TCP queue size + -D CONFIG_ASYNC_TCP_QUEUE_SIZE=128 + // Async TCP async task core + -D CONFIG_ASYNC_TCP_RUNNING_CORE=1 + // Async TCP async stac ksize + -D CONFIG_ASYNC_TCP_STACK_SIZE=8096 + // WebSocket queue size + -D WS_MAX_QUEUED_MESSAGES=64 +``` From 17a8d442169f3ca8496b20ebd24bbc06f55d4a62 Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Tue, 4 Jun 2024 13:50:37 +0300 Subject: [PATCH 219/551] Add support for Arduino 3.0.0 --- library.json | 2 +- library.properties | 2 +- src/AsyncEventSource.cpp | 5 +++++ src/AsyncWebSocket.cpp | 8 +++++++- src/WebAuthentication.cpp | 6 ++++++ 5 files changed, 20 insertions(+), 3 deletions(-) diff --git a/library.json b/library.json index 750ca28d2..7947a4d3b 100644 --- a/library.json +++ b/library.json @@ -12,7 +12,7 @@ "type": "git", "url": "https://github.com/me-no-dev/ESPAsyncWebServer.git" }, - "version": "1.2.3", + "version": "1.2.4", "license": "LGPL-3.0", "frameworks": "arduino", "platforms": ["espressif8266", "espressif32"], diff --git a/library.properties b/library.properties index 401b04173..fb650fa21 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=ESP Async WebServer -version=1.2.3 +version=1.2.4 author=Me-No-Dev maintainer=Me-No-Dev sentence=Async Web Server for ESP8266 and ESP31B diff --git a/src/AsyncEventSource.cpp b/src/AsyncEventSource.cpp index f2914df54..3b825750e 100644 --- a/src/AsyncEventSource.cpp +++ b/src/AsyncEventSource.cpp @@ -19,6 +19,11 @@ */ #include "Arduino.h" #include "AsyncEventSource.h" +#ifdef ESP32 +#if ESP_IDF_VERSION_MAJOR >= 5 +#include "rom/ets_sys.h" +#endif +#endif static String generateEventMessage(const char *message, const char *event, uint32_t id, uint32_t reconnect){ String ev = ""; diff --git a/src/AsyncWebSocket.cpp b/src/AsyncWebSocket.cpp index f76f2fc96..11a7ff8a6 100644 --- a/src/AsyncWebSocket.cpp +++ b/src/AsyncWebSocket.cpp @@ -829,7 +829,7 @@ void AsyncWebSocketClient::binary(AsyncWebSocketMessageBuffer * buffer) IPAddress AsyncWebSocketClient::remoteIP() { if(!_client) { - return IPAddress(0U); + return IPAddress((uint32_t)0U); } return _client->remoteIP(); } @@ -1259,9 +1259,15 @@ AsyncWebSocketResponse::AsyncWebSocketResponse(const String& key, AsyncWebSocket (String&)key += WS_STR_UUID; mbedtls_sha1_context ctx; mbedtls_sha1_init(&ctx); +#if ESP_IDF_VERSION_MAJOR < 5 mbedtls_sha1_starts_ret(&ctx); mbedtls_sha1_update_ret(&ctx, (const unsigned char*)key.c_str(), key.length()); mbedtls_sha1_finish_ret(&ctx, hash); +#else + mbedtls_sha1_starts(&ctx); + mbedtls_sha1_update(&ctx, (const unsigned char*)key.c_str(), key.length()); + mbedtls_sha1_finish(&ctx, hash); +#endif mbedtls_sha1_free(&ctx); #endif base64_encodestate _state; diff --git a/src/WebAuthentication.cpp b/src/WebAuthentication.cpp index 45246a196..38b20f37c 100644 --- a/src/WebAuthentication.cpp +++ b/src/WebAuthentication.cpp @@ -71,9 +71,15 @@ static bool getMD5(uint8_t * data, uint16_t len, char * output){//33 bytes or mo memset(_buf, 0x00, 16); #ifdef ESP32 mbedtls_md5_init(&_ctx); +#if ESP_IDF_VERSION_MAJOR < 5 mbedtls_md5_starts_ret(&_ctx); mbedtls_md5_update_ret(&_ctx, data, len); mbedtls_md5_finish_ret(&_ctx, _buf); +#else + mbedtls_md5_starts(&_ctx); + mbedtls_md5_update(&_ctx, data, len); + mbedtls_md5_finish(&_ctx, _buf); +#endif #else MD5Init(&_ctx); MD5Update(&_ctx, data, len); From 9d315521eb2ead26f6755a9783b2e5d263da8517 Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Tue, 4 Jun 2024 14:52:27 +0300 Subject: [PATCH 220/551] Add missing include for Arduino 3.0.0 --- src/AsyncWebSocket.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/AsyncWebSocket.cpp b/src/AsyncWebSocket.cpp index 11a7ff8a6..bdfa19718 100644 --- a/src/AsyncWebSocket.cpp +++ b/src/AsyncWebSocket.cpp @@ -28,6 +28,11 @@ #else #include #endif +#ifdef ESP32 +#if ESP_IDF_VERSION_MAJOR >= 5 +#include "rom/ets_sys.h" +#endif +#endif #define MAX_PRINTF_LEN 64 From 7f3753454b1f176c4b6d6bcd1587a135d95ca63c Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Tue, 4 Jun 2024 15:01:45 +0300 Subject: [PATCH 221/551] Add example build flag --- examples/regex_patterns/build_opt.h | 1 + 1 file changed, 1 insertion(+) create mode 100644 examples/regex_patterns/build_opt.h diff --git a/examples/regex_patterns/build_opt.h b/examples/regex_patterns/build_opt.h new file mode 100644 index 000000000..f59785169 --- /dev/null +++ b/examples/regex_patterns/build_opt.h @@ -0,0 +1 @@ +-DASYNCWEBSERVER_REGEX=1 \ No newline at end of file From 10f597d7f2f4fae3d4df424480d28738387748bb Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Wed, 5 Jun 2024 10:50:18 +0200 Subject: [PATCH 222/551] Arduino 3.0.1 --- .github/workflows/ci.yml | 4 ++-- platformio.ini | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 405ec9803..53bd98b5d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -80,7 +80,7 @@ jobs: - name: esp32dev|arduino-3 board: esp32dev platform: espressif32 - opts: "--project-option 'platform_packages=platformio/framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#3.0.0, platform_packages=platformio/framework-arduinoespressif32-libs @ https://github.com/espressif/arduino-esp32/releases/download/3.0.0/esp32-arduino-libs-3.0.0.zip'" + opts: "--project-option 'platform_packages=platformio/framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#3.0.1, platform_packages=platformio/framework-arduinoespressif32-libs @ https://github.com/espressif/arduino-esp32/releases/download/3.0.1/esp32-arduino-libs-3.0.1.zip'" - name: esp32-s3-devkitc-1|arduino board: esp32-s3-devkitc-1 platform: espressif32 @@ -92,7 +92,7 @@ jobs: - name: esp32-s3-devkitc-1|arduino-3 board: esp32-s3-devkitc-1 platform: espressif32 - opts: "--project-option 'platform_packages=platformio/framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#3.0.0, platform_packages=platformio/framework-arduinoespressif32-libs @ https://github.com/espressif/arduino-esp32/releases/download/3.0.0/esp32-arduino-libs-3.0.0.zip'" + opts: "--project-option 'platform_packages=platformio/framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#3.0.1, platform_packages=platformio/framework-arduinoespressif32-libs @ https://github.com/espressif/arduino-esp32/releases/download/3.0.1/esp32-arduino-libs-3.0.1.zip'" - name: huzzah|espressif8266 board: huzzah platform: espressif8266 diff --git a/platformio.ini b/platformio.ini index eff66778f..b85b37ba2 100644 --- a/platformio.ini +++ b/platformio.ini @@ -32,8 +32,8 @@ board = esp32dev [env:arduino-3] platform = espressif32 platform_packages= - platformio/framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#3.0.0 - platformio/framework-arduinoespressif32-libs @ https://github.com/espressif/arduino-esp32/releases/download/3.0.0/esp32-arduino-libs-3.0.0.zip + platformio/framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#3.0.1 + platformio/framework-arduinoespressif32-libs @ https://github.com/espressif/arduino-esp32/releases/download/3.0.1/esp32-arduino-libs-3.0.1.zip board = esp32dev [env:esp8266] From 57244d47444a3281ba30f4c9da60fb23d05eb495 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Wed, 5 Jun 2024 22:30:12 +0200 Subject: [PATCH 223/551] Firmware size optimization: remove mbedtls dependency (accounts for 33KB in firmware) --- examples/Draft/Draft.ino | 37 +++++ platformio.ini | 5 +- src/AsyncWebSocket.cpp | 25 ++-- src/WebAuthentication.cpp | 32 ++--- src/port/SHA1Builder.cpp | 284 ++++++++++++++++++++++++++++++++++++++ src/port/SHA1Builder.h | 39 ++++++ 6 files changed, 387 insertions(+), 35 deletions(-) create mode 100644 examples/Draft/Draft.ino create mode 100644 src/port/SHA1Builder.cpp create mode 100644 src/port/SHA1Builder.h diff --git a/examples/Draft/Draft.ino b/examples/Draft/Draft.ino new file mode 100644 index 000000000..0a1cb1fe7 --- /dev/null +++ b/examples/Draft/Draft.ino @@ -0,0 +1,37 @@ +#include +#include +#include "mbedtls/md5.h" + +void setup() { + Serial.begin(115200); + delay(2000); + + const char* data = "Hello World"; + + { + uint8_t md5[16]; + mbedtls_md5_context _ctx; + mbedtls_md5_init(&_ctx); + mbedtls_md5_starts(&_ctx); + mbedtls_md5_update(&_ctx, (const unsigned char*)data, strlen(data)); + mbedtls_md5_finish(&_ctx, md5); + char output[33]; + for (int i = 0; i < 16; i++) { + sprintf_P(output + (i * 2), PSTR("%02x"), md5[i]); + } + Serial.println(String(output)); + } + + { + MD5Builder md5; + md5.begin(); + md5.add(data, strlen(data); + md5.calculate(); + char output[33]; + md5.getChars(output); + Serial.println(String(output)); + } +} + +void loop() { +} diff --git a/platformio.ini b/platformio.ini index b85b37ba2..1f19720f3 100644 --- a/platformio.ini +++ b/platformio.ini @@ -16,10 +16,11 @@ monitor_filters = esp32_exception_decoder, log2file [platformio] lib_dir = . -; src_dir = examples/CaptivePortal +src_dir = examples/CaptivePortal ; src_dir = examples/SimpleServer -src_dir = examples/StreamFiles +; src_dir = examples/StreamFiles ; src_dir = examples/Filters +; src_dir = examples/Draft [env:arduino] platform = espressif32 diff --git a/src/AsyncWebSocket.cpp b/src/AsyncWebSocket.cpp index f231d2364..9a07d1e0b 100644 --- a/src/AsyncWebSocket.cpp +++ b/src/AsyncWebSocket.cpp @@ -26,7 +26,11 @@ #include #ifndef ESP8266 -#include "mbedtls/sha1.h" +#if ESP_IDF_VERSION_MAJOR < 5 +#include "./port/SHA1Builder.h" +#else +#include +#endif #include #else #include @@ -1305,19 +1309,12 @@ AsyncWebSocketResponse::AsyncWebSocketResponse(const String& key, AsyncWebSocket #ifdef ESP8266 sha1(key + WS_STR_UUID, hash); #else - (String&)key += WS_STR_UUID; - mbedtls_sha1_context ctx; - mbedtls_sha1_init(&ctx); -#if ESP_IDF_VERSION_MAJOR == 5 - mbedtls_sha1_starts(&ctx); - mbedtls_sha1_update(&ctx, (const unsigned char*)key.c_str(), key.length()); - mbedtls_sha1_finish(&ctx, hash); -#else - mbedtls_sha1_starts_ret(&ctx); - mbedtls_sha1_update_ret(&ctx, (const unsigned char*)key.c_str(), key.length()); - mbedtls_sha1_finish_ret(&ctx, hash); -#endif - mbedtls_sha1_free(&ctx); + String k = key + WS_STR_UUID; + SHA1Builder sha1; + sha1.begin(); + sha1.add((const uint8_t*)k.c_str(), k.length()); + sha1.calculate(); + sha1.getBytes(hash); #endif base64_encodestate _state; base64_init_encodestate(&_state); diff --git a/src/WebAuthentication.cpp b/src/WebAuthentication.cpp index 2f122d7cd..839679580 100644 --- a/src/WebAuthentication.cpp +++ b/src/WebAuthentication.cpp @@ -21,7 +21,7 @@ #include "WebAuthentication.h" #include #ifdef ESP32 -#include "mbedtls/md5.h" +#include #else #include "md5.h" #endif @@ -66,35 +66,29 @@ bool checkBasicAuthentication(const char * hash, const char * username, const ch static bool getMD5(uint8_t * data, uint16_t len, char * output){//33 bytes or more #ifdef ESP32 - mbedtls_md5_context _ctx; + MD5Builder md5; + md5.begin(); + md5.add(data, len); + md5.calculate(); + md5.getChars(output); #else - md5_context_t _ctx; -#endif - uint8_t i; + md5_context_t _ctx; + uint8_t * _buf = (uint8_t*)malloc(16); if(_buf == NULL) return false; memset(_buf, 0x00, 16); -#ifdef ESP32 - mbedtls_md5_init(&_ctx); -#if ESP_IDF_VERSION_MAJOR == 5 - mbedtls_md5_starts(&_ctx); - mbedtls_md5_update(&_ctx, data, len); - mbedtls_md5_finish(&_ctx, _buf); -#else - mbedtls_md5_starts_ret(&_ctx); - mbedtls_md5_update_ret(&_ctx, data, len); - mbedtls_md5_finish_ret(&_ctx, _buf); -#endif -#else + MD5Init(&_ctx); MD5Update(&_ctx, data, len); MD5Final(_buf, &_ctx); -#endif - for(i = 0; i < 16; i++) { + + for(uint8_t i = 0; i < 16; i++) { sprintf_P(output + (i * 2), PSTR("%02x"), _buf[i]); } + free(_buf); +#endif return true; } diff --git a/src/port/SHA1Builder.cpp b/src/port/SHA1Builder.cpp new file mode 100644 index 000000000..901fb8021 --- /dev/null +++ b/src/port/SHA1Builder.cpp @@ -0,0 +1,284 @@ +/* + * FIPS-180-1 compliant SHA-1 implementation + * + * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + * Modified for esp32 by Lucas Saavedra Vaz on 11 Jan 2024 + */ + +#include +#if ESP_IDF_VERSION_MAJOR < 5 + +#include "SHA1Builder.h" + +// 32-bit integer manipulation macros (big endian) + +#ifndef GET_UINT32_BE +#define GET_UINT32_BE(n, b, i) \ + { (n) = ((uint32_t)(b)[(i)] << 24) | ((uint32_t)(b)[(i) + 1] << 16) | ((uint32_t)(b)[(i) + 2] << 8) | ((uint32_t)(b)[(i) + 3]); } +#endif + +#ifndef PUT_UINT32_BE +#define PUT_UINT32_BE(n, b, i) \ + { \ + (b)[(i)] = (uint8_t)((n) >> 24); \ + (b)[(i) + 1] = (uint8_t)((n) >> 16); \ + (b)[(i) + 2] = (uint8_t)((n) >> 8); \ + (b)[(i) + 3] = (uint8_t)((n)); \ + } +#endif + +// Constants + +static const uint8_t sha1_padding[64] = {0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + +// Private methods + +void SHA1Builder::process(const uint8_t *data) { + uint32_t temp, W[16], A, B, C, D, E; + + GET_UINT32_BE(W[0], data, 0); + GET_UINT32_BE(W[1], data, 4); + GET_UINT32_BE(W[2], data, 8); + GET_UINT32_BE(W[3], data, 12); + GET_UINT32_BE(W[4], data, 16); + GET_UINT32_BE(W[5], data, 20); + GET_UINT32_BE(W[6], data, 24); + GET_UINT32_BE(W[7], data, 28); + GET_UINT32_BE(W[8], data, 32); + GET_UINT32_BE(W[9], data, 36); + GET_UINT32_BE(W[10], data, 40); + GET_UINT32_BE(W[11], data, 44); + GET_UINT32_BE(W[12], data, 48); + GET_UINT32_BE(W[13], data, 52); + GET_UINT32_BE(W[14], data, 56); + GET_UINT32_BE(W[15], data, 60); + +#define sha1_S(x, n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n))) + +#define sha1_R(t) (temp = W[(t - 3) & 0x0F] ^ W[(t - 8) & 0x0F] ^ W[(t - 14) & 0x0F] ^ W[t & 0x0F], (W[t & 0x0F] = sha1_S(temp, 1))) + +#define sha1_P(a, b, c, d, e, x) \ + { \ + e += sha1_S(a, 5) + sha1_F(b, c, d) + sha1_K + x; \ + b = sha1_S(b, 30); \ + } + + A = state[0]; + B = state[1]; + C = state[2]; + D = state[3]; + E = state[4]; + +#define sha1_F(x, y, z) (z ^ (x & (y ^ z))) +#define sha1_K 0x5A827999 + + sha1_P(A, B, C, D, E, W[0]); + sha1_P(E, A, B, C, D, W[1]); + sha1_P(D, E, A, B, C, W[2]); + sha1_P(C, D, E, A, B, W[3]); + sha1_P(B, C, D, E, A, W[4]); + sha1_P(A, B, C, D, E, W[5]); + sha1_P(E, A, B, C, D, W[6]); + sha1_P(D, E, A, B, C, W[7]); + sha1_P(C, D, E, A, B, W[8]); + sha1_P(B, C, D, E, A, W[9]); + sha1_P(A, B, C, D, E, W[10]); + sha1_P(E, A, B, C, D, W[11]); + sha1_P(D, E, A, B, C, W[12]); + sha1_P(C, D, E, A, B, W[13]); + sha1_P(B, C, D, E, A, W[14]); + sha1_P(A, B, C, D, E, W[15]); + sha1_P(E, A, B, C, D, sha1_R(16)); + sha1_P(D, E, A, B, C, sha1_R(17)); + sha1_P(C, D, E, A, B, sha1_R(18)); + sha1_P(B, C, D, E, A, sha1_R(19)); + +#undef sha1_K +#undef sha1_F + +#define sha1_F(x, y, z) (x ^ y ^ z) +#define sha1_K 0x6ED9EBA1 + + sha1_P(A, B, C, D, E, sha1_R(20)); + sha1_P(E, A, B, C, D, sha1_R(21)); + sha1_P(D, E, A, B, C, sha1_R(22)); + sha1_P(C, D, E, A, B, sha1_R(23)); + sha1_P(B, C, D, E, A, sha1_R(24)); + sha1_P(A, B, C, D, E, sha1_R(25)); + sha1_P(E, A, B, C, D, sha1_R(26)); + sha1_P(D, E, A, B, C, sha1_R(27)); + sha1_P(C, D, E, A, B, sha1_R(28)); + sha1_P(B, C, D, E, A, sha1_R(29)); + sha1_P(A, B, C, D, E, sha1_R(30)); + sha1_P(E, A, B, C, D, sha1_R(31)); + sha1_P(D, E, A, B, C, sha1_R(32)); + sha1_P(C, D, E, A, B, sha1_R(33)); + sha1_P(B, C, D, E, A, sha1_R(34)); + sha1_P(A, B, C, D, E, sha1_R(35)); + sha1_P(E, A, B, C, D, sha1_R(36)); + sha1_P(D, E, A, B, C, sha1_R(37)); + sha1_P(C, D, E, A, B, sha1_R(38)); + sha1_P(B, C, D, E, A, sha1_R(39)); + +#undef sha1_K +#undef sha1_F + +#define sha1_F(x, y, z) ((x & y) | (z & (x | y))) +#define sha1_K 0x8F1BBCDC + + sha1_P(A, B, C, D, E, sha1_R(40)); + sha1_P(E, A, B, C, D, sha1_R(41)); + sha1_P(D, E, A, B, C, sha1_R(42)); + sha1_P(C, D, E, A, B, sha1_R(43)); + sha1_P(B, C, D, E, A, sha1_R(44)); + sha1_P(A, B, C, D, E, sha1_R(45)); + sha1_P(E, A, B, C, D, sha1_R(46)); + sha1_P(D, E, A, B, C, sha1_R(47)); + sha1_P(C, D, E, A, B, sha1_R(48)); + sha1_P(B, C, D, E, A, sha1_R(49)); + sha1_P(A, B, C, D, E, sha1_R(50)); + sha1_P(E, A, B, C, D, sha1_R(51)); + sha1_P(D, E, A, B, C, sha1_R(52)); + sha1_P(C, D, E, A, B, sha1_R(53)); + sha1_P(B, C, D, E, A, sha1_R(54)); + sha1_P(A, B, C, D, E, sha1_R(55)); + sha1_P(E, A, B, C, D, sha1_R(56)); + sha1_P(D, E, A, B, C, sha1_R(57)); + sha1_P(C, D, E, A, B, sha1_R(58)); + sha1_P(B, C, D, E, A, sha1_R(59)); + +#undef sha1_K +#undef sha1_F + +#define sha1_F(x, y, z) (x ^ y ^ z) +#define sha1_K 0xCA62C1D6 + + sha1_P(A, B, C, D, E, sha1_R(60)); + sha1_P(E, A, B, C, D, sha1_R(61)); + sha1_P(D, E, A, B, C, sha1_R(62)); + sha1_P(C, D, E, A, B, sha1_R(63)); + sha1_P(B, C, D, E, A, sha1_R(64)); + sha1_P(A, B, C, D, E, sha1_R(65)); + sha1_P(E, A, B, C, D, sha1_R(66)); + sha1_P(D, E, A, B, C, sha1_R(67)); + sha1_P(C, D, E, A, B, sha1_R(68)); + sha1_P(B, C, D, E, A, sha1_R(69)); + sha1_P(A, B, C, D, E, sha1_R(70)); + sha1_P(E, A, B, C, D, sha1_R(71)); + sha1_P(D, E, A, B, C, sha1_R(72)); + sha1_P(C, D, E, A, B, sha1_R(73)); + sha1_P(B, C, D, E, A, sha1_R(74)); + sha1_P(A, B, C, D, E, sha1_R(75)); + sha1_P(E, A, B, C, D, sha1_R(76)); + sha1_P(D, E, A, B, C, sha1_R(77)); + sha1_P(C, D, E, A, B, sha1_R(78)); + sha1_P(B, C, D, E, A, sha1_R(79)); + +#undef sha1_K +#undef sha1_F + + state[0] += A; + state[1] += B; + state[2] += C; + state[3] += D; + state[4] += E; +} + +// Public methods + +void SHA1Builder::begin(void) { + total[0] = 0; + total[1] = 0; + + state[0] = 0x67452301; + state[1] = 0xEFCDAB89; + state[2] = 0x98BADCFE; + state[3] = 0x10325476; + state[4] = 0xC3D2E1F0; + + memset(buffer, 0x00, sizeof(buffer)); + memset(hash, 0x00, sizeof(hash)); +} + +void SHA1Builder::add(const uint8_t *data, size_t len) { + size_t fill; + uint32_t left; + + if (len == 0) { + return; + } + + left = total[0] & 0x3F; + fill = 64 - left; + + total[0] += (uint32_t)len; + total[0] &= 0xFFFFFFFF; + + if (total[0] < (uint32_t)len) { + total[1]++; + } + + if (left && len >= fill) { + memcpy((void *)(buffer + left), data, fill); + process(buffer); + data += fill; + len -= fill; + left = 0; + } + + while (len >= 64) { + process(data); + data += 64; + len -= 64; + } + + if (len > 0) { + memcpy((void *)(buffer + left), data, len); + } +} + +void SHA1Builder::calculate(void) { + uint32_t last, padn; + uint32_t high, low; + uint8_t msglen[8]; + + high = (total[0] >> 29) | (total[1] << 3); + low = (total[0] << 3); + + PUT_UINT32_BE(high, msglen, 0); + PUT_UINT32_BE(low, msglen, 4); + + last = total[0] & 0x3F; + padn = (last < 56) ? (56 - last) : (120 - last); + + add((uint8_t *)sha1_padding, padn); + add(msglen, 8); + + PUT_UINT32_BE(state[0], hash, 0); + PUT_UINT32_BE(state[1], hash, 4); + PUT_UINT32_BE(state[2], hash, 8); + PUT_UINT32_BE(state[3], hash, 12); + PUT_UINT32_BE(state[4], hash, 16); +} + +void SHA1Builder::getBytes(uint8_t *output) { + memcpy(output, hash, SHA1_HASH_SIZE); +} + +#endif // ESP_IDF_VERSION_MAJOR < 5 diff --git a/src/port/SHA1Builder.h b/src/port/SHA1Builder.h new file mode 100644 index 000000000..da9a77a7b --- /dev/null +++ b/src/port/SHA1Builder.h @@ -0,0 +1,39 @@ +// Copyright 2024 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SHA1Builder_h +#define SHA1Builder_h + +#include +#include + +#define SHA1_HASH_SIZE 20 + +class SHA1Builder { + private: + uint32_t total[2]; /* number of bytes processed */ + uint32_t state[5]; /* intermediate digest state */ + unsigned char buffer[64]; /* data block being processed */ + uint8_t hash[SHA1_HASH_SIZE]; /* SHA-1 result */ + + void process(const uint8_t* data); + + public: + void begin(); + void add(const uint8_t* data, size_t len); + void calculate(); + void getBytes(uint8_t* output); +}; + +#endif // SHA1Builder_h From 7cd9a765a8e15eaba466922a7f9db3fd026eecb7 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Wed, 5 Jun 2024 22:51:29 +0200 Subject: [PATCH 224/551] v2.10.5 --- library.json | 2 +- library.properties | 2 +- src/ESPAsyncWebServer.h | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/library.json b/library.json index 539ff5d45..df9d36ac0 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "ESP Async WebServer", - "version": "2.10.4", + "version": "2.10.5", "description": "Asynchronous HTTP and WebSocket Server Library for ESP32. Supports: WebSocket, SSE, Authentication, Arduino Json 7, File Upload, Static File serving, URL Rewrite, URL Redirect, etc.", "keywords": "http,async,websocket,webserver", "homepage": "https://github.com/mathieucarbou/ESPAsyncWebServer", diff --git a/library.properties b/library.properties index fc68a1c3f..b6e35d035 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=ESP Async WebServer -version=2.10.4 +version=2.10.5 author=Me-No-Dev maintainer=Mathieu Carbou sentence=Asynchronous HTTP and WebSocket Server Library for ESP32 diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index 8533df678..386533350 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -40,10 +40,10 @@ #error Platform not supported #endif -#define ASYNCWEBSERVER_VERSION "2.10.4" +#define ASYNCWEBSERVER_VERSION "2.10.5" #define ASYNCWEBSERVER_VERSION_MAJOR 2 #define ASYNCWEBSERVER_VERSION_MINOR 10 -#define ASYNCWEBSERVER_VERSION_REVISION 4 +#define ASYNCWEBSERVER_VERSION_REVISION 5 #define ASYNCWEBSERVER_FORK_mathieucarbou #ifdef ASYNCWEBSERVER_REGEX From 4accf5cd1d4c79188964e43884f0701878c5ad3c Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Sun, 9 Jun 2024 11:12:19 +0200 Subject: [PATCH 225/551] Fix typo --- README.md | 2 +- docs/index.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 8c56e7ac3..9bab1d55f 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo - [#13](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/13) ([@tueddy](https://github.com/tueddy)): Compile with Arduino 3 (ESP-IDF 5.1) - [#14](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/14) ([@nilo85](https://github.com/nilo85)): Add support for Auth & GET requests in AsyncCallbackJsonWebHandler - Added `setAuthentication(const String& username, const String& password)` -- Added `StreamConcat` example to shoiw how to stream multiple files in one response +- Added `StreamConcat` example to show how to stream multiple files in one response - Remove filename after inline in Content-Disposition header according to RFC2183 - Depends on `mathieucarbou/Async TCP @ ^3.1.4` - Arduino 3 / ESP-IDF 5.1 compatibility diff --git a/docs/index.md b/docs/index.md index 8c56e7ac3..9bab1d55f 100644 --- a/docs/index.md +++ b/docs/index.md @@ -24,7 +24,7 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo - [#13](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/13) ([@tueddy](https://github.com/tueddy)): Compile with Arduino 3 (ESP-IDF 5.1) - [#14](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/14) ([@nilo85](https://github.com/nilo85)): Add support for Auth & GET requests in AsyncCallbackJsonWebHandler - Added `setAuthentication(const String& username, const String& password)` -- Added `StreamConcat` example to shoiw how to stream multiple files in one response +- Added `StreamConcat` example to show how to stream multiple files in one response - Remove filename after inline in Content-Disposition header according to RFC2183 - Depends on `mathieucarbou/Async TCP @ ^3.1.4` - Arduino 3 / ESP-IDF 5.1 compatibility From cceac170c910564eafbfeaa00b13c934015fc8d3 Mon Sep 17 00:00:00 2001 From: Emil Muratov Date: Sun, 9 Jun 2024 16:06:13 +0900 Subject: [PATCH 226/551] websocket code cleanup add explicit constructors remove exra calls, etc... --- src/AsyncWebSocket.cpp | 94 +++++++++++++++++------------------------- src/AsyncWebSocket.h | 61 ++++++++++++++++----------- 2 files changed, 76 insertions(+), 79 deletions(-) diff --git a/src/AsyncWebSocket.cpp b/src/AsyncWebSocket.cpp index 9a07d1e0b..b34d90ea9 100644 --- a/src/AsyncWebSocket.cpp +++ b/src/AsyncWebSocket.cpp @@ -132,17 +132,11 @@ size_t webSocketSendFrame(AsyncClient *client, bool final, uint8_t opcode, bool * AsyncWebSocketMessageBuffer */ -AsyncWebSocketMessageBuffer::AsyncWebSocketMessageBuffer() - : _buffer(std::make_shared>(0)) -{ -} - -AsyncWebSocketMessageBuffer::AsyncWebSocketMessageBuffer(uint8_t* data, size_t size) +AsyncWebSocketMessageBuffer::AsyncWebSocketMessageBuffer(const uint8_t* data, size_t size) : _buffer(std::make_shared>(size)) { if (_buffer->capacity() < size) { - _buffer.reset(); - _buffer = std::make_shared>(0); + _buffer->reserve(size); } else { std::memcpy(_buffer->data(), data, size); } @@ -152,16 +146,10 @@ AsyncWebSocketMessageBuffer::AsyncWebSocketMessageBuffer(size_t size) : _buffer(std::make_shared>(size)) { if (_buffer->capacity() < size) { - _buffer.reset(); - _buffer = std::make_shared>(0); + _buffer->reserve(size); } } -AsyncWebSocketMessageBuffer::~AsyncWebSocketMessageBuffer() -{ - _buffer.reset(); -} - bool AsyncWebSocketMessageBuffer::reserve(size_t size) { if (_buffer->capacity() >= size) @@ -228,7 +216,7 @@ class AsyncWebSocketControl { */ -AsyncWebSocketMessage::AsyncWebSocketMessage(std::shared_ptr> buffer, uint8_t opcode, bool mask) : +AsyncWebSocketMessage::AsyncWebSocketMessage(AsyncWebSocketSharedBuffer buffer, uint8_t opcode, bool mask) : _WSbuffer{buffer}, _opcode(opcode & 0x07), _mask{mask}, @@ -449,7 +437,7 @@ void AsyncWebSocketClient::_queueControl(uint8_t opcode, const uint8_t *data, si _runQueue(); } -void AsyncWebSocketClient::_queueMessage(std::shared_ptr> buffer, uint8_t opcode, bool mask) +void AsyncWebSocketClient::_queueMessage(AsyncWebSocketSharedBuffer buffer, uint8_t opcode, bool mask) { if(_status != WS_CONNECTED) return; @@ -707,7 +695,7 @@ size_t AsyncWebSocketClient::printf_P(PGM_P formatP, ...) #endif namespace { -std::shared_ptr> makeSharedBuffer(const uint8_t *message, size_t len) +AsyncWebSocketSharedBuffer makeSharedBuffer(const uint8_t *message, size_t len) { auto buffer = std::make_shared>(len); std::memcpy(buffer->data(), message, len); @@ -723,7 +711,7 @@ void AsyncWebSocketClient::text(AsyncWebSocketMessageBuffer * buffer) } } -void AsyncWebSocketClient::text(std::shared_ptr> buffer) +void AsyncWebSocketClient::text(AsyncWebSocketSharedBuffer buffer) { _queueMessage(buffer); } @@ -748,6 +736,7 @@ void AsyncWebSocketClient::text(const String &message) text(message.c_str(), message.length()); } +#ifndef ESP32 void AsyncWebSocketClient::text(const __FlashStringHelper *data) { PGM_P p = reinterpret_cast(data); @@ -768,6 +757,7 @@ void AsyncWebSocketClient::text(const __FlashStringHelper *data) free(message); } } +#endif // ESP32 void AsyncWebSocketClient::binary(AsyncWebSocketMessageBuffer * buffer) { @@ -777,7 +767,7 @@ void AsyncWebSocketClient::binary(AsyncWebSocketMessageBuffer * buffer) } } -void AsyncWebSocketClient::binary(std::shared_ptr> buffer) +void AsyncWebSocketClient::binary(AsyncWebSocketSharedBuffer buffer) { _queueMessage(buffer, WS_BINARY); } @@ -802,6 +792,7 @@ void AsyncWebSocketClient::binary(const String &message) binary(message.c_str(), message.length()); } +#ifndef ESP32 void AsyncWebSocketClient::binary(const __FlashStringHelper *data, size_t len) { PGM_P p = reinterpret_cast(data); @@ -812,7 +803,7 @@ void AsyncWebSocketClient::binary(const __FlashStringHelper *data, size_t len) free(message); } } - +#endif IPAddress AsyncWebSocketClient::remoteIP() const { if (!_client) @@ -835,16 +826,6 @@ uint16_t AsyncWebSocketClient::remotePort() const * Async Web Socket - Each separate socket location */ -AsyncWebSocket::AsyncWebSocket(const String& url) - :_url(url) - ,_cNextId(1) - ,_enabled(true) -{ - _eventHandler = NULL; -} - -AsyncWebSocket::~AsyncWebSocket(){} - void AsyncWebSocket::_handleEvent(AsyncWebSocketClient * client, AwsEventType type, void * arg, uint8_t *data, size_t len){ if(_eventHandler != NULL){ _eventHandler(this, client, type, arg, data, len); @@ -880,7 +861,7 @@ size_t AsyncWebSocket::count() const AsyncWebSocketClient * AsyncWebSocket::client(uint32_t id) { - const auto iter = std::find_if(std::begin(_clients), std::end(_clients), + const auto iter = std::find_if(_clients.begin(), _clients.end(), [id](const AsyncWebSocketClient &c){ return c.id() == id && c.status() == WS_CONNECTED; }); if (iter == std::end(_clients)) return nullptr; @@ -946,6 +927,7 @@ void AsyncWebSocket::text(uint32_t id, const String &message) { text(id, message.c_str(), message.length()); } +#ifndef ESP32 void AsyncWebSocket::text(uint32_t id, const __FlashStringHelper *data) { PGM_P p = reinterpret_cast(data); @@ -967,6 +949,7 @@ void AsyncWebSocket::text(uint32_t id, const __FlashStringHelper *data) free(message); } } +#endif // ESP32 void AsyncWebSocket::text(uint32_t id, AsyncWebSocketMessageBuffer *buffer) { if (buffer) { @@ -974,7 +957,7 @@ void AsyncWebSocket::text(uint32_t id, AsyncWebSocketMessageBuffer *buffer) delete buffer; } } -void AsyncWebSocket::text(uint32_t id, std::shared_ptr> buffer) +void AsyncWebSocket::text(uint32_t id, AsyncWebSocketSharedBuffer buffer) { if (AsyncWebSocketClient *c = client(id)) c->text(buffer); @@ -996,6 +979,7 @@ void AsyncWebSocket::textAll(const String &message) { textAll(message.c_str(), message.length()); } +#ifndef ESP32 void AsyncWebSocket::textAll(const __FlashStringHelper *data) { PGM_P p = reinterpret_cast(data); @@ -1016,6 +1000,7 @@ void AsyncWebSocket::textAll(const __FlashStringHelper *data) free(message); } } +#endif // ESP32 void AsyncWebSocket::textAll(AsyncWebSocketMessageBuffer * buffer) { if (buffer) { @@ -1024,7 +1009,7 @@ void AsyncWebSocket::textAll(AsyncWebSocketMessageBuffer * buffer) } } -void AsyncWebSocket::textAll(std::shared_ptr> buffer) +void AsyncWebSocket::textAll(AsyncWebSocketSharedBuffer buffer) { for (auto &c : _clients) if (c.status() == WS_CONNECTED) @@ -1048,6 +1033,7 @@ void AsyncWebSocket::binary(uint32_t id, const String &message) { binary(id, message.c_str(), message.length()); } +#ifndef ESP32 void AsyncWebSocket::binary(uint32_t id, const __FlashStringHelper *data, size_t len) { PGM_P p = reinterpret_cast(data); @@ -1059,6 +1045,7 @@ void AsyncWebSocket::binary(uint32_t id, const __FlashStringHelper *data, size_t free(message); } } +#endif // ESP32 void AsyncWebSocket::binary(uint32_t id, AsyncWebSocketMessageBuffer *buffer) { if (buffer) { @@ -1066,7 +1053,7 @@ void AsyncWebSocket::binary(uint32_t id, AsyncWebSocketMessageBuffer *buffer) delete buffer; } } -void AsyncWebSocket::binary(uint32_t id, std::shared_ptr> buffer) +void AsyncWebSocket::binary(uint32_t id, AsyncWebSocketSharedBuffer buffer) { if (AsyncWebSocketClient *c = client(id)) c->binary(buffer); @@ -1089,6 +1076,7 @@ void AsyncWebSocket::binaryAll(const String &message) { binaryAll(message.c_str(), message.length()); } +#ifndef ESP32 void AsyncWebSocket::binaryAll(const __FlashStringHelper *data, size_t len) { PGM_P p = reinterpret_cast(data); @@ -1100,6 +1088,7 @@ void AsyncWebSocket::binaryAll(const __FlashStringHelper *data, size_t len) free(message); } } +#endif // ESP32 void AsyncWebSocket::binaryAll(AsyncWebSocketMessageBuffer * buffer) { if (buffer) { @@ -1107,7 +1096,7 @@ void AsyncWebSocket::binaryAll(AsyncWebSocketMessageBuffer * buffer) delete buffer; } } -void AsyncWebSocket::binaryAll(std::shared_ptr> buffer) +void AsyncWebSocket::binaryAll(AsyncWebSocketSharedBuffer buffer) { for (auto &c : _clients) if (c.status() == WS_CONNECTED) @@ -1139,7 +1128,7 @@ size_t AsyncWebSocket::printfAll(const char *format, ...) va_end(arg); delete[] temp; - std::shared_ptr> buffer = std::make_shared>(len); + AsyncWebSocketSharedBuffer buffer = std::make_shared>(len); va_start(arg, format); vsnprintf( (char *)buffer->data(), len + 1, format, arg); @@ -1175,7 +1164,7 @@ size_t AsyncWebSocket::printfAll_P(PGM_P formatP, ...) va_end(arg); delete[] temp; - std::shared_ptr> buffer = std::make_shared>(len + 1); + AsyncWebSocketSharedBuffer buffer = std::make_shared>(len + 1); va_start(arg, formatP); vsnprintf_P((char *)buffer->data(), len + 1, formatP, arg); @@ -1195,6 +1184,8 @@ const char __WS_STR_PROTOCOL[] PROGMEM = { "Sec-WebSocket-Protocol" }; const char __WS_STR_ACCEPT[] PROGMEM = { "Sec-WebSocket-Accept" }; const char __WS_STR_UUID[] PROGMEM = { "258EAFA5-E914-47DA-95CA-C5AB0DC85B11" }; +#define WS_STR_UUID_LEN 36 + #define WS_STR_CONNECTION FPSTR(__WS_STR_CONNECTION) #define WS_STR_UPGRADE FPSTR(__WS_STR_UPGRADE) #define WS_STR_ORIGIN FPSTR(__WS_STR_ORIGIN) @@ -1270,7 +1261,7 @@ AsyncWebSocketMessageBuffer * AsyncWebSocket::makeBuffer(size_t size) } } -AsyncWebSocketMessageBuffer * AsyncWebSocket::makeBuffer(uint8_t * data, size_t size) +AsyncWebSocketMessageBuffer * AsyncWebSocket::makeBuffer(const uint8_t * data, size_t size) { AsyncWebSocketMessageBuffer * buffer = new AsyncWebSocketMessageBuffer(data, size); if (buffer->length() != size) @@ -1293,23 +1284,16 @@ AsyncWebSocketResponse::AsyncWebSocketResponse(const String& key, AsyncWebSocket _code = 101; _sendContentLength = false; - uint8_t * hash = (uint8_t*)malloc(20); - if(hash == NULL) - { - _state = RESPONSE_FAILED; - return; - } - char * buffer = (char *) malloc(33); - if(buffer == NULL) - { - free(hash); - _state = RESPONSE_FAILED; - return; - } + uint8_t hash[20]; + char buffer[33]; + #ifdef ESP8266 sha1(key + WS_STR_UUID, hash); #else - String k = key + WS_STR_UUID; + String k; + k.reserve(key.length() + WS_STR_UUID_LEN); + k += key; + k += WS_STR_UUID; SHA1Builder sha1; sha1.begin(); sha1.add((const uint8_t*)k.c_str(), k.length()); @@ -1323,8 +1307,6 @@ AsyncWebSocketResponse::AsyncWebSocketResponse(const String& key, AsyncWebSocket addHeader(WS_STR_CONNECTION, WS_STR_UPGRADE); addHeader(WS_STR_UPGRADE, F("websocket")); addHeader(WS_STR_ACCEPT,buffer); - free(buffer); - free(hash); } void AsyncWebSocketResponse::_respond(AsyncWebServerRequest *request) @@ -1334,7 +1316,7 @@ void AsyncWebSocketResponse::_respond(AsyncWebServerRequest *request) request->client()->close(true); return; } - String out = _assembleHead(request->version()); + String out(_assembleHead(request->version())); request->client()->write(out.c_str(), _headLength); _state = RESPONSE_WAIT_ACK; } diff --git a/src/AsyncWebSocket.h b/src/AsyncWebSocket.h index ab182ea9f..a7faa9511 100644 --- a/src/AsyncWebSocket.h +++ b/src/AsyncWebSocket.h @@ -54,6 +54,8 @@ #define DEFAULT_MAX_WS_CLIENTS 4 #endif +using AsyncWebSocketSharedBuffer = std::shared_ptr>; + class AsyncWebSocket; class AsyncWebSocketResponse; class AsyncWebSocketClient; @@ -93,13 +95,13 @@ class AsyncWebSocketMessageBuffer { friend AsyncWebSocketClient; private: - std::shared_ptr> _buffer; + AsyncWebSocketSharedBuffer _buffer; public: - AsyncWebSocketMessageBuffer(); - AsyncWebSocketMessageBuffer(size_t size); - AsyncWebSocketMessageBuffer(uint8_t* data, size_t size); - ~AsyncWebSocketMessageBuffer(); + AsyncWebSocketMessageBuffer(){} + explicit AsyncWebSocketMessageBuffer(size_t size); + AsyncWebSocketMessageBuffer(const uint8_t* data, size_t size); + //~AsyncWebSocketMessageBuffer(); bool reserve(size_t size); uint8_t* get() { return _buffer->data(); } size_t length() const { return _buffer->size(); } @@ -108,7 +110,7 @@ class AsyncWebSocketMessageBuffer { class AsyncWebSocketMessage { private: - std::shared_ptr> _WSbuffer; + AsyncWebSocketSharedBuffer _WSbuffer; uint8_t _opcode{WS_TEXT}; bool _mask{false}; AwsMessageStatus _status{WS_MSG_ERROR}; @@ -117,7 +119,7 @@ class AsyncWebSocketMessage size_t _acked{}; public: - AsyncWebSocketMessage(std::shared_ptr> buffer, uint8_t opcode=WS_TEXT, bool mask=false); + AsyncWebSocketMessage(AsyncWebSocketSharedBuffer buffer, uint8_t opcode=WS_TEXT, bool mask=false); bool finished() const { return _status != WS_MSG_SENDING; } bool betweenFrames() const { return _acked == _ack; } @@ -146,7 +148,7 @@ class AsyncWebSocketClient { uint32_t _keepAlivePeriod; void _queueControl(uint8_t opcode, const uint8_t *data=NULL, size_t len=0, bool mask=false); - void _queueMessage(std::shared_ptr> buffer, uint8_t opcode=WS_TEXT, bool mask=false); + void _queueMessage(AsyncWebSocketSharedBuffer buffer, uint8_t opcode=WS_TEXT, bool mask=false); void _runQueue(); void _clearQueue(); @@ -204,7 +206,7 @@ class AsyncWebSocketClient { } //data packets - void message(std::shared_ptr> buffer, uint8_t opcode=WS_TEXT, bool mask=false) { _queueMessage(buffer, opcode, mask); } + void message(AsyncWebSocketSharedBuffer buffer, uint8_t opcode=WS_TEXT, bool mask=false) { _queueMessage(buffer, opcode, mask); } bool queueIsFull() const; size_t queueLen() const; @@ -213,20 +215,24 @@ class AsyncWebSocketClient { size_t printf_P(PGM_P formatP, ...) __attribute__ ((format (printf, 2, 3))); #endif - void text(std::shared_ptr> buffer); + void text(AsyncWebSocketSharedBuffer buffer); void text(const uint8_t *message, size_t len); void text(const char *message, size_t len); void text(const char *message); void text(const String &message); +#ifndef ESP32 void text(const __FlashStringHelper *message); +#endif // ESP32 void text(AsyncWebSocketMessageBuffer *buffer); - void binary(std::shared_ptr> buffer); + void binary(AsyncWebSocketSharedBuffer buffer); void binary(const uint8_t *message, size_t len); void binary(const char * message, size_t len); void binary(const char * message); void binary(const String &message); +#ifndef ESP32 void binary(const __FlashStringHelper *message, size_t len); +#endif // ESP32 void binary(AsyncWebSocketMessageBuffer *buffer); bool canSend() const; @@ -240,8 +246,8 @@ class AsyncWebSocketClient { void _onData(void *pbuf, size_t plen); }; -typedef std::function AwsHandshakeHandler; -typedef std::function AwsEventHandler; +using AwsHandshakeHandler = std::function; +using AwsEventHandler = std::function; //WebServer Handler implementation that plays the role of a socket server class AsyncWebSocket: public AsyncWebHandler { @@ -249,14 +255,15 @@ class AsyncWebSocket: public AsyncWebHandler { String _url; std::list _clients; uint32_t _cNextId; - AwsEventHandler _eventHandler; - AwsHandshakeHandler _handshakeHandler; + AwsEventHandler _eventHandler{nullptr}; + AwsHandshakeHandler _handshakeHandler; bool _enabled; AsyncWebLock _lock; public: - AsyncWebSocket(const String& url); - ~AsyncWebSocket(); + explicit AsyncWebSocket(const char* url) : _url(url) ,_cNextId(1), _enabled(true) {} + AsyncWebSocket(const String& url) :_url(url) ,_cNextId(1),_enabled(true) {} + ~AsyncWebSocket(){}; const char * url() const { return _url.c_str(); } void enable(bool e){ _enabled = e; } bool enabled() const { return _enabled; } @@ -265,7 +272,7 @@ class AsyncWebSocket: public AsyncWebHandler { size_t count() const; AsyncWebSocketClient * client(uint32_t id); - bool hasClient(uint32_t id){ return client(id) != NULL; } + bool hasClient(uint32_t id){ return client(id) != nullptr; } void close(uint32_t id, uint16_t code=0, const char * message=NULL); void closeAll(uint16_t code=0, const char * message=NULL); @@ -278,33 +285,41 @@ class AsyncWebSocket: public AsyncWebHandler { void text(uint32_t id, const char *message, size_t len); void text(uint32_t id, const char *message); void text(uint32_t id, const String &message); +#ifndef ESP32 void text(uint32_t id, const __FlashStringHelper *message); +#endif // ESP32 void text(uint32_t id, AsyncWebSocketMessageBuffer *buffer); - void text(uint32_t id, std::shared_ptr> buffer); + void text(uint32_t id, AsyncWebSocketSharedBuffer buffer); void textAll(const uint8_t *message, size_t len); void textAll(const char * message, size_t len); void textAll(const char * message); void textAll(const String &message); +#ifndef ESP32 void textAll(const __FlashStringHelper *message); +#endif // ESP32 void textAll(AsyncWebSocketMessageBuffer *buffer); - void textAll(std::shared_ptr> buffer); + void textAll(AsyncWebSocketSharedBuffer buffer); void binary(uint32_t id, const uint8_t *message, size_t len); void binary(uint32_t id, const char *message, size_t len); void binary(uint32_t id, const char *message); void binary(uint32_t id, const String &message); +#ifndef ESP32 void binary(uint32_t id, const __FlashStringHelper *message, size_t len); +#endif // ESP32 void binary(uint32_t id, AsyncWebSocketMessageBuffer *buffer); - void binary(uint32_t id, std::shared_ptr> buffer); + void binary(uint32_t id, AsyncWebSocketSharedBuffer buffer); void binaryAll(const uint8_t *message, size_t len); void binaryAll(const char *message, size_t len); void binaryAll(const char *message); void binaryAll(const String &message); +#ifndef ESP32 void binaryAll(const __FlashStringHelper *message, size_t len); +#endif // ESP32 void binaryAll(AsyncWebSocketMessageBuffer *buffer); - void binaryAll(std::shared_ptr> buffer); + void binaryAll(AsyncWebSocketSharedBuffer buffer); size_t printf(uint32_t id, const char *format, ...) __attribute__ ((format (printf, 3, 4))); size_t printfAll(const char *format, ...) __attribute__ ((format (printf, 2, 3))); @@ -333,7 +348,7 @@ class AsyncWebSocket: public AsyncWebHandler { // messagebuffer functions/objects. AsyncWebSocketMessageBuffer * makeBuffer(size_t size = 0); - AsyncWebSocketMessageBuffer * makeBuffer(uint8_t * data, size_t size); + AsyncWebSocketMessageBuffer * makeBuffer(const uint8_t * data, size_t size); const std::list &getClients() const { return _clients; } }; From 351d04bb3212ba8ca3d869d2b8f11b7b01197757 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Sun, 9 Jun 2024 12:26:46 +0200 Subject: [PATCH 227/551] concat() to avoid a re-assignment --- src/AsyncWebSocket.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/AsyncWebSocket.cpp b/src/AsyncWebSocket.cpp index b34d90ea9..df6821dd0 100644 --- a/src/AsyncWebSocket.cpp +++ b/src/AsyncWebSocket.cpp @@ -1292,8 +1292,8 @@ AsyncWebSocketResponse::AsyncWebSocketResponse(const String& key, AsyncWebSocket #else String k; k.reserve(key.length() + WS_STR_UUID_LEN); - k += key; - k += WS_STR_UUID; + k.concat(key); + k.concat(WS_STR_UUID); SHA1Builder sha1; sha1.begin(); sha1.add((const uint8_t*)k.c_str(), k.length()); From 2fa1f9b78b43b8140b097d937063588e1bf283fc Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Sun, 9 Jun 2024 12:26:35 +0200 Subject: [PATCH 228/551] doc --- README.md | 1 + docs/index.md | 1 + 2 files changed, 2 insertions(+) diff --git a/README.md b/README.md index 9bab1d55f..61eb90bc8 100644 --- a/README.md +++ b/README.md @@ -30,6 +30,7 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo - Arduino 3 / ESP-IDF 5.1 compatibility - Added all flavors of `binary()`, `text()`, `binaryAll()` and `textAll()` in `AsyncWebSocket` - Added `setCloseClientOnQueueFull(bool)` which can be set on a client to either close the connection or discard messages but not close the connection when the queue is full +- [#29](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/29) ([@vortigont](https://github.com/vortigont)): Some websocket code cleanup ## Documentation diff --git a/docs/index.md b/docs/index.md index 9bab1d55f..61eb90bc8 100644 --- a/docs/index.md +++ b/docs/index.md @@ -30,6 +30,7 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo - Arduino 3 / ESP-IDF 5.1 compatibility - Added all flavors of `binary()`, `text()`, `binaryAll()` and `textAll()` in `AsyncWebSocket` - Added `setCloseClientOnQueueFull(bool)` which can be set on a client to either close the connection or discard messages but not close the connection when the queue is full +- [#29](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/29) ([@vortigont](https://github.com/vortigont)): Some websocket code cleanup ## Documentation From 05206417de37751a43e65e4b520ec7149c7d4201 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Sun, 9 Jun 2024 12:24:20 +0200 Subject: [PATCH 229/551] v2.10.6 --- library.json | 2 +- library.properties | 2 +- src/ESPAsyncWebServer.h | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/library.json b/library.json index df9d36ac0..a19c9d17d 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "ESP Async WebServer", - "version": "2.10.5", + "version": "2.10.6", "description": "Asynchronous HTTP and WebSocket Server Library for ESP32. Supports: WebSocket, SSE, Authentication, Arduino Json 7, File Upload, Static File serving, URL Rewrite, URL Redirect, etc.", "keywords": "http,async,websocket,webserver", "homepage": "https://github.com/mathieucarbou/ESPAsyncWebServer", diff --git a/library.properties b/library.properties index b6e35d035..32ec23b96 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=ESP Async WebServer -version=2.10.5 +version=2.10.6 author=Me-No-Dev maintainer=Mathieu Carbou sentence=Asynchronous HTTP and WebSocket Server Library for ESP32 diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index 386533350..d18aa1dbc 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -40,10 +40,10 @@ #error Platform not supported #endif -#define ASYNCWEBSERVER_VERSION "2.10.5" +#define ASYNCWEBSERVER_VERSION "2.10.6" #define ASYNCWEBSERVER_VERSION_MAJOR 2 #define ASYNCWEBSERVER_VERSION_MINOR 10 -#define ASYNCWEBSERVER_VERSION_REVISION 5 +#define ASYNCWEBSERVER_VERSION_REVISION 6 #define ASYNCWEBSERVER_FORK_mathieucarbou #ifdef ASYNCWEBSERVER_REGEX From 96342ee61cf4f68cf6a23bf03dece9e4a5d67d7c Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Sun, 9 Jun 2024 21:51:53 +0200 Subject: [PATCH 230/551] update doc --- README.md | 1 + docs/index.md | 1 + 2 files changed, 2 insertions(+) diff --git a/README.md b/README.md index 61eb90bc8..9417b441f 100644 --- a/README.md +++ b/README.md @@ -31,6 +31,7 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo - Added all flavors of `binary()`, `text()`, `binaryAll()` and `textAll()` in `AsyncWebSocket` - Added `setCloseClientOnQueueFull(bool)` which can be set on a client to either close the connection or discard messages but not close the connection when the queue is full - [#29](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/29) ([@vortigont](https://github.com/vortigont)): Some websocket code cleanup +- Use `-D DEFAULT_MAX_WS_CLIENTS` to change the number of allows WebSocket clients and use `cleanupClients()` to help cleanup resources about dead clients ## Documentation diff --git a/docs/index.md b/docs/index.md index 61eb90bc8..9417b441f 100644 --- a/docs/index.md +++ b/docs/index.md @@ -31,6 +31,7 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo - Added all flavors of `binary()`, `text()`, `binaryAll()` and `textAll()` in `AsyncWebSocket` - Added `setCloseClientOnQueueFull(bool)` which can be set on a client to either close the connection or discard messages but not close the connection when the queue is full - [#29](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/29) ([@vortigont](https://github.com/vortigont)): Some websocket code cleanup +- Use `-D DEFAULT_MAX_WS_CLIENTS` to change the number of allows WebSocket clients and use `cleanupClients()` to help cleanup resources about dead clients ## Documentation From dd692817dd1a7da9c8d57427017536ffd1643ef7 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Mon, 10 Jun 2024 11:46:42 +0200 Subject: [PATCH 231/551] Made DEFAULT_MAX_WS_CLIENTS customizable --- src/AsyncWebSocket.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/AsyncWebSocket.h b/src/AsyncWebSocket.h index a7faa9511..cde0b437c 100644 --- a/src/AsyncWebSocket.h +++ b/src/AsyncWebSocket.h @@ -48,11 +48,13 @@ #endif #endif +#ifndef DEFAULT_MAX_WS_CLIENTS #ifdef ESP32 #define DEFAULT_MAX_WS_CLIENTS 8 #else #define DEFAULT_MAX_WS_CLIENTS 4 #endif +#endif using AsyncWebSocketSharedBuffer = std::shared_ptr>; From 144d44a230486a0024c82084ee0d33a1293d7bb5 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Mon, 10 Jun 2024 11:47:19 +0200 Subject: [PATCH 232/551] v2.10.7 --- library.json | 2 +- library.properties | 2 +- src/ESPAsyncWebServer.h | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/library.json b/library.json index a19c9d17d..899d04c66 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "ESP Async WebServer", - "version": "2.10.6", + "version": "2.10.7", "description": "Asynchronous HTTP and WebSocket Server Library for ESP32. Supports: WebSocket, SSE, Authentication, Arduino Json 7, File Upload, Static File serving, URL Rewrite, URL Redirect, etc.", "keywords": "http,async,websocket,webserver", "homepage": "https://github.com/mathieucarbou/ESPAsyncWebServer", diff --git a/library.properties b/library.properties index 32ec23b96..46704a583 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=ESP Async WebServer -version=2.10.6 +version=2.10.7 author=Me-No-Dev maintainer=Mathieu Carbou sentence=Asynchronous HTTP and WebSocket Server Library for ESP32 diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index d18aa1dbc..2bef60a1a 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -40,10 +40,10 @@ #error Platform not supported #endif -#define ASYNCWEBSERVER_VERSION "2.10.6" +#define ASYNCWEBSERVER_VERSION "2.10.7" #define ASYNCWEBSERVER_VERSION_MAJOR 2 #define ASYNCWEBSERVER_VERSION_MINOR 10 -#define ASYNCWEBSERVER_VERSION_REVISION 6 +#define ASYNCWEBSERVER_VERSION_REVISION 7 #define ASYNCWEBSERVER_FORK_mathieucarbou #ifdef ASYNCWEBSERVER_REGEX From 3ae2eee54e334b81b622a2ca3b7fdc3e444ea07f Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Mon, 10 Jun 2024 11:49:19 +0200 Subject: [PATCH 233/551] Made DEFAULT_MAX_SSE_CLIENTS customizable --- src/AsyncEventSource.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/AsyncEventSource.h b/src/AsyncEventSource.h index 18868bafc..2efb0ddd3 100644 --- a/src/AsyncEventSource.h +++ b/src/AsyncEventSource.h @@ -44,11 +44,13 @@ #endif #endif +#ifndef DEFAULT_MAX_SSE_CLIENTS #ifdef ESP32 #define DEFAULT_MAX_SSE_CLIENTS 8 #else #define DEFAULT_MAX_SSE_CLIENTS 4 #endif +#endif class AsyncEventSource; class AsyncEventSourceResponse; From b70d36f2bec270e504bdc739b91a0fcbf3d84377 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Mon, 10 Jun 2024 11:49:50 +0200 Subject: [PATCH 234/551] v2.10.8 --- library.json | 2 +- library.properties | 2 +- src/ESPAsyncWebServer.h | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/library.json b/library.json index 899d04c66..37a8190f0 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "ESP Async WebServer", - "version": "2.10.7", + "version": "2.10.8", "description": "Asynchronous HTTP and WebSocket Server Library for ESP32. Supports: WebSocket, SSE, Authentication, Arduino Json 7, File Upload, Static File serving, URL Rewrite, URL Redirect, etc.", "keywords": "http,async,websocket,webserver", "homepage": "https://github.com/mathieucarbou/ESPAsyncWebServer", diff --git a/library.properties b/library.properties index 46704a583..be717338d 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=ESP Async WebServer -version=2.10.7 +version=2.10.8 author=Me-No-Dev maintainer=Mathieu Carbou sentence=Asynchronous HTTP and WebSocket Server Library for ESP32 diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index 2bef60a1a..1bec17384 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -40,10 +40,10 @@ #error Platform not supported #endif -#define ASYNCWEBSERVER_VERSION "2.10.7" +#define ASYNCWEBSERVER_VERSION "2.10.8" #define ASYNCWEBSERVER_VERSION_MAJOR 2 #define ASYNCWEBSERVER_VERSION_MINOR 10 -#define ASYNCWEBSERVER_VERSION_REVISION 7 +#define ASYNCWEBSERVER_VERSION_REVISION 8 #define ASYNCWEBSERVER_FORK_mathieucarbou #ifdef ASYNCWEBSERVER_REGEX From 4cba41098d45319f3b53229a2cd841a519c0e7ef Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Fri, 14 Jun 2024 10:58:45 +0200 Subject: [PATCH 235/551] Little cleanup is doc and descriptors --- .github/workflows/ci.yml | 6 ++++-- README.md | 2 +- docs/_config.yml | 2 +- docs/index.md | 2 +- library.json | 2 +- library.properties | 2 +- platformio.ini | 19 +++++++++++-------- src/WebHandlers.cpp | 10 ++++++++-- 8 files changed, 28 insertions(+), 17 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 53bd98b5d..f0bcf0fc2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -47,10 +47,12 @@ jobs: - name: Install core run: arduino-cli core install --additional-urls "${{ matrix.index_url }}" ${{ matrix.core }} - - name: Install AsyncTCP-esphome + - name: Install AsyncTCP (ESP32) + if: ${{ matrix.core == 'esp32:esp32' }} run: ARDUINO_LIBRARY_ENABLE_UNSAFE_INSTALL=true arduino-cli lib install --git-url https://github.com/mathieucarbou/AsyncTCP#v3.1.4 - - name: Install ESPAsyncTCP-esphome + - name: Install ESPAsyncTCP (ESP8266) + if: ${{ matrix.core == 'esp8266:esp8266' }} run: ARDUINO_LIBRARY_ENABLE_UNSAFE_INSTALL=true arduino-cli lib install --git-url https://github.com/mathieucarbou/esphome-ESPAsyncTCP#v2.0.0 - name: Build CaptivePortal diff --git a/README.md b/README.md index 9417b441f..b4330ac74 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ [![Continuous Integration](https://github.com/mathieucarbou/ESPAsyncWebServer/actions/workflows/ci.yml/badge.svg)](https://github.com/mathieucarbou/ESPAsyncWebServer/actions/workflows/ci.yml) [![PlatformIO Registry](https://badges.registry.platformio.org/packages/mathieucarbou/library/ESP%20Async%20WebServer.svg)](https://registry.platformio.org/libraries/mathieucarbou/ESP%20Async%20WebServer) -Asynchronous HTTP and WebSocket Server Library for ESP32. +Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 Supports: WebSocket, SSE, Authentication, Arduino Json 7, File Upload, Static File serving, URL Rewrite, URL Redirect, etc. This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubox-node-org/ESPAsyncWebServer) and includes all the concurrency fixes. diff --git a/docs/_config.yml b/docs/_config.yml index 532070ba6..95d65c287 100644 --- a/docs/_config.yml +++ b/docs/_config.yml @@ -1,7 +1,7 @@ # bundle exec jekyll serve --host=0.0.0.0 title: ESP Async WebServer -description: "Asynchronous HTTP and WebSocket Server Library for ESP32" +description: "Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266" remote_theme: pages-themes/cayman@v0.2.0 plugins: - jekyll-remote-theme diff --git a/docs/index.md b/docs/index.md index 9417b441f..b4330ac74 100644 --- a/docs/index.md +++ b/docs/index.md @@ -4,7 +4,7 @@ [![Continuous Integration](https://github.com/mathieucarbou/ESPAsyncWebServer/actions/workflows/ci.yml/badge.svg)](https://github.com/mathieucarbou/ESPAsyncWebServer/actions/workflows/ci.yml) [![PlatformIO Registry](https://badges.registry.platformio.org/packages/mathieucarbou/library/ESP%20Async%20WebServer.svg)](https://registry.platformio.org/libraries/mathieucarbou/ESP%20Async%20WebServer) -Asynchronous HTTP and WebSocket Server Library for ESP32. +Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 Supports: WebSocket, SSE, Authentication, Arduino Json 7, File Upload, Static File serving, URL Rewrite, URL Redirect, etc. This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubox-node-org/ESPAsyncWebServer) and includes all the concurrency fixes. diff --git a/library.json b/library.json index 37a8190f0..acd320c53 100644 --- a/library.json +++ b/library.json @@ -1,7 +1,7 @@ { "name": "ESP Async WebServer", "version": "2.10.8", - "description": "Asynchronous HTTP and WebSocket Server Library for ESP32. Supports: WebSocket, SSE, Authentication, Arduino Json 7, File Upload, Static File serving, URL Rewrite, URL Redirect, etc.", + "description": "Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266. Supports: WebSocket, SSE, Authentication, Arduino Json 7, File Upload, Static File serving, URL Rewrite, URL Redirect, etc.", "keywords": "http,async,websocket,webserver", "homepage": "https://github.com/mathieucarbou/ESPAsyncWebServer", "repository": { diff --git a/library.properties b/library.properties index be717338d..3858af9c5 100644 --- a/library.properties +++ b/library.properties @@ -2,7 +2,7 @@ name=ESP Async WebServer version=2.10.8 author=Me-No-Dev maintainer=Mathieu Carbou -sentence=Asynchronous HTTP and WebSocket Server Library for ESP32 +sentence=Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 paragraph=Supports: WebSocket, SSE, Authentication, Arduino Json 7, File Upload, Static File serving, URL Rewrite, URL Redirect, etc category=Other url=https://github.com/mathieucarbou/ESPAsyncWebServer diff --git a/platformio.ini b/platformio.ini index 1f19720f3..3d9a732f1 100644 --- a/platformio.ini +++ b/platformio.ini @@ -4,31 +4,31 @@ build_flags = -Wall -Wextra -D CONFIG_ARDUHAL_LOG_COLORS -D CORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_VERBOSE -lib_deps = - bblanchon/ArduinoJson @ 7.0.4 - mathieucarbou/Async TCP @ ^3.1.4 - ; https://github.com/mathieucarbou/AsyncTCP - ; https://github.com/me-no-dev/AsyncTCP - esphome/ESPAsyncTCP-esphome @ 2.0.0 upload_protocol = esptool monitor_speed = 115200 monitor_filters = esp32_exception_decoder, log2file [platformio] lib_dir = . -src_dir = examples/CaptivePortal +; src_dir = examples/CaptivePortal ; src_dir = examples/SimpleServer -; src_dir = examples/StreamFiles +src_dir = examples/StreamFiles ; src_dir = examples/Filters ; src_dir = examples/Draft [env:arduino] platform = espressif32 board = esp32dev +lib_deps = + bblanchon/ArduinoJson @ 7.0.4 + mathieucarbou/Async TCP @ ^3.1.4 [env:arduino-2] platform = espressif32@6.7.0 board = esp32dev +lib_deps = + bblanchon/ArduinoJson @ 7.0.4 + mathieucarbou/Async TCP @ ^3.1.4 [env:arduino-3] platform = espressif32 @@ -36,6 +36,9 @@ platform_packages= platformio/framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#3.0.1 platformio/framework-arduinoespressif32-libs @ https://github.com/espressif/arduino-esp32/releases/download/3.0.1/esp32-arduino-libs-3.0.1.zip board = esp32dev +lib_deps = + bblanchon/ArduinoJson @ 7.0.4 + mathieucarbou/Async TCP @ ^3.1.4 [env:esp8266] platform = espressif8266 diff --git a/src/WebHandlers.cpp b/src/WebHandlers.cpp index 0b55b0ddf..d3d82cdb2 100644 --- a/src/WebHandlers.cpp +++ b/src/WebHandlers.cpp @@ -206,8 +206,14 @@ void AsyncStaticWebHandler::handleRequest(AsyncWebServerRequest *request) if (request->_tempFile == true) { time_t lw = request->_tempFile.getLastWrite(); // get last file mod time (if supported by FS) - if (lw) setLastModified(gmtime(&lw)); - String etag(lw ? lw : request->_tempFile.size()); // set etag to lastmod timestamp if available, otherwise to size + // set etag to lastmod timestamp if available, otherwise to size + String etag; + if (lw) { + setLastModified(gmtime(&lw)); + etag = String(lw); + } else { + etag = String(request->_tempFile.size()); + } if (_last_modified.length() && _last_modified == request->header(F("If-Modified-Since"))) { request->_tempFile.close(); request->send(304); // Not modified From 77042fabeab7a51fea6a2e0440a68ea59ccacdb7 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Fri, 14 Jun 2024 11:30:07 +0200 Subject: [PATCH 236/551] Use pio file for CI --- .github/workflows/ci.yml | 79 ++++++++++++++++++++-------------------- 1 file changed, 39 insertions(+), 40 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f0bcf0fc2..544e8f600 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -64,58 +64,57 @@ jobs: - name: Build Filters run: arduino-cli compile --library . --warnings none -b ${{ matrix.board }} "examples/Filters/Filters.ino" + pio_envs: + name: Get PlatformIO Envs + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/cache@v4 + with: + key: pip + path: ~/.cache/pip + - uses: actions/setup-python@v5 + with: + python-version: "3.x" + - name: Install PlatformIO + run: | + python -m pip install --upgrade pip + pip install --upgrade platformio + - name: Get Envs + id: envs + run: | + echo "pio_default_envs=$(pio project config --json-output | jq -cr '[ .[][0] | select(startswith("env:") and (endswith("-debug")|not)) | .[4:] ]')" >> $GITHUB_OUTPUT + + outputs: + pio_default_envs: ${{ steps.envs.outputs.pio_default_envs }} + platformio: - name: pio ${{ matrix.name }} + name: "pio:${{ matrix.environment }}" + needs: [pio_envs] runs-on: ubuntu-latest strategy: fail-fast: false matrix: - include: - - name: esp32dev|arduino - board: esp32dev - platform: espressif32 - opts: - - name: esp32dev|arduino-2 - board: esp32dev - platform: espressif32@6.7.0 - opts: - - name: esp32dev|arduino-3 - board: esp32dev - platform: espressif32 - opts: "--project-option 'platform_packages=platformio/framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#3.0.1, platform_packages=platformio/framework-arduinoespressif32-libs @ https://github.com/espressif/arduino-esp32/releases/download/3.0.1/esp32-arduino-libs-3.0.1.zip'" - - name: esp32-s3-devkitc-1|arduino - board: esp32-s3-devkitc-1 - platform: espressif32 - opts: - - name: esp32-s3-devkitc-1|arduino-2 - board: esp32-s3-devkitc-1 - platform: espressif32@6.7.0 - opts: - - name: esp32-s3-devkitc-1|arduino-3 - board: esp32-s3-devkitc-1 - platform: espressif32 - opts: "--project-option 'platform_packages=platformio/framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#3.0.1, platform_packages=platformio/framework-arduinoespressif32-libs @ https://github.com/espressif/arduino-esp32/releases/download/3.0.1/esp32-arduino-libs-3.0.1.zip'" - - name: huzzah|espressif8266 - board: huzzah - platform: espressif8266 - opts: + environment: ${{ fromJSON(needs.pio_envs.outputs.pio_default_envs) }} + steps: - uses: actions/checkout@v4 - - name: Set up cache - uses: actions/cache@v4 + - uses: actions/cache@v4 with: path: | ~/.platformio ~/.cache/pip - key: ${{ matrix.name }} + key: pio - uses: actions/setup-python@v5 with: python-version: "3.x" - run: pip install platformio - - run: platformio platform install ${{ matrix.platform }} - - name: Build CaptivePortal - run: platformio ci "examples/CaptivePortal/CaptivePortal.ino" -l '.' -b ${{ matrix.board }} ${{ matrix.opts }} - - name: Build SimpleServer - run: platformio ci "examples/SimpleServer/SimpleServer.ino" -l '.' -b ${{ matrix.board }} ${{ matrix.opts }} - - name: Build Filters - run: platformio ci "examples/Filters/Filters.ino" -l '.' -b ${{ matrix.board }} ${{ matrix.opts }} + + - name: Install platformio + run: | + python -m pip install --upgrade pip + pip install --upgrade platformio + + - run: PLATFORMIO_SRC_DIR=examples/CaptivePortal pio run -e ${{ matrix.environment }} + - run: PLATFORMIO_SRC_DIR=examples/SimpleServer pio run -e ${{ matrix.environment }} + - run: PLATFORMIO_SRC_DIR=examples/Filters pio run -e ${{ matrix.environment }} From c2f3d4afab6d3f86b436c7f797c4b68e1f7c9fbf Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Fri, 14 Jun 2024 12:01:03 +0200 Subject: [PATCH 237/551] clang update --- .clang-format | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.clang-format b/.clang-format index a0498d9ce..63f29c0be 100644 --- a/.clang-format +++ b/.clang-format @@ -2,15 +2,21 @@ Language: Cpp BasedOnStyle: LLVM AccessModifierOffset: -2 +AlignConsecutiveMacros: true +AllowAllArgumentsOnNextLine: false +AllowAllParametersOfDeclarationOnNextLine: false AllowShortIfStatementsOnASingleLine: false +AllowShortLambdasOnASingleLine: Inline +BinPackArguments: false ColumnLimit: 0 ContinuationIndentWidth: 2 FixNamespaceComments: false IndentAccessModifiers: true IndentCaseLabels: true +IndentPPDirectives: BeforeHash IndentWidth: 2 NamespaceIndentation: All PointerAlignment: Left ReferenceAlignment: Left TabWidth: 2 -UseTab: Never \ No newline at end of file +UseTab: Never From 7348ba59177ab7dce0cd71289644637589a027ec Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Fri, 14 Jun 2024 13:00:44 +0200 Subject: [PATCH 238/551] Add StreamFiles to CI --- .github/workflows/ci.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 544e8f600..c23d2ea8d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -64,6 +64,9 @@ jobs: - name: Build Filters run: arduino-cli compile --library . --warnings none -b ${{ matrix.board }} "examples/Filters/Filters.ino" + - name: Build StreamFiles + run: arduino-cli compile --library . --warnings none -b ${{ matrix.board }} "examples/StreamFiles/StreamFiles.ino" + pio_envs: name: Get PlatformIO Envs runs-on: ubuntu-latest @@ -118,3 +121,4 @@ jobs: - run: PLATFORMIO_SRC_DIR=examples/CaptivePortal pio run -e ${{ matrix.environment }} - run: PLATFORMIO_SRC_DIR=examples/SimpleServer pio run -e ${{ matrix.environment }} - run: PLATFORMIO_SRC_DIR=examples/Filters pio run -e ${{ matrix.environment }} + - run: PLATFORMIO_SRC_DIR=examples/StreamFiles pio run -e ${{ matrix.environment }} From 10811d72db30b921b665ff2530d5826decc3c043 Mon Sep 17 00:00:00 2001 From: p0px Date: Fri, 14 Jun 2024 13:49:50 -0400 Subject: [PATCH 239/551] Add CMakeLists.txt so using ESPAsyncWebServer as an ESPIDF component compiles. --- CMakeLists.txt | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 000000000..64292eca4 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,17 @@ +set(COMPONENT_SRCDIRS + "src" +) + +set(COMPONENT_ADD_INCLUDEDIRS + "src" +) + +set(COMPONENT_REQUIRES + "arduino-esp32" + "AsyncTCP" +) + +register_component() + +target_compile_definitions(${COMPONENT_TARGET} PUBLIC -DESP32) +target_compile_options(${COMPONENT_TARGET} PRIVATE -fno-rtti) From 4d1cf1604a366d6c79ad03492acb1fdd976c7a64 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Thu, 20 Jun 2024 08:56:51 +0200 Subject: [PATCH 240/551] doc update --- README.md | 49 ++++++++++++++++++++++++++++--------------------- docs/index.md | 49 ++++++++++++++++++++++++++++--------------------- 2 files changed, 56 insertions(+), 42 deletions(-) diff --git a/README.md b/README.md index b4330ac74..1c4520ec7 100644 --- a/README.md +++ b/README.md @@ -11,27 +11,34 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo ## Changes in this fork -- Removed SPIFFSEditor -- Deployed in PlatformIO registry and Arduino IDE library manager -- CI -- Some code cleanup -- `SSE_MAX_QUEUED_MESSAGES` to control the maximum number of messages that can be queued for a SSE client -- `write()` function public in `AsyncEventSource.h` -- Arduino Json 7 compatibility and backward compatible with 6 and 6 (changes in `AsyncJson.h`). The API to use Json has not changed. These are only internal changes. -- `WS_MAX_QUEUED_MESSAGES`: control the maximum number of messages that can be queued for a Websocket client -- Resurrected `AsyncWebSocketMessageBuffer` and `makeBuffer()` in order to make the fork API-compatible with the original library from me-no-dev regarding WebSocket. -- [#5](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/5) ([@vortigont](https://github.com/vortigont)): set real "Last-Modified" header based on file's LastWrite time -- [#13](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/13) ([@tueddy](https://github.com/tueddy)): Compile with Arduino 3 (ESP-IDF 5.1) -- [#14](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/14) ([@nilo85](https://github.com/nilo85)): Add support for Auth & GET requests in AsyncCallbackJsonWebHandler -- Added `setAuthentication(const String& username, const String& password)` -- Added `StreamConcat` example to show how to stream multiple files in one response -- Remove filename after inline in Content-Disposition header according to RFC2183 -- Depends on `mathieucarbou/Async TCP @ ^3.1.4` -- Arduino 3 / ESP-IDF 5.1 compatibility -- Added all flavors of `binary()`, `text()`, `binaryAll()` and `textAll()` in `AsyncWebSocket` -- Added `setCloseClientOnQueueFull(bool)` which can be set on a client to either close the connection or discard messages but not close the connection when the queue is full -- [#29](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/29) ([@vortigont](https://github.com/vortigont)): Some websocket code cleanup -- Use `-D DEFAULT_MAX_WS_CLIENTS` to change the number of allows WebSocket clients and use `cleanupClients()` to help cleanup resources about dead clients +- [@mathieucarbou](https://github.com/mathieucarbou): Removed SPIFFSEditor +- [@mathieucarbou](https://github.com/mathieucarbou): Deployed in PlatformIO registry and Arduino IDE library manager +- [@mathieucarbou](https://github.com/mathieucarbou): CI +- [@mathieucarbou](https://github.com/mathieucarbou): Some code cleanup +- [@mathieucarbou](https://github.com/mathieucarbou): `SSE_MAX_QUEUED_MESSAGES` to control the maximum number of messages that can be queued for a SSE client +- [@mathieucarbou](https://github.com/mathieucarbou): `write()` function public in `AsyncEventSource.h` +- [@mathieucarbou](https://github.com/mathieucarbou): Arduino Json 7 compatibility and backward compatible with 6 and 6 (changes in `AsyncJson.h`). The API to use Json has not changed. These are only internal changes. +- [@mathieucarbou](https://github.com/mathieucarbou): `WS_MAX_QUEUED_MESSAGES`: control the maximum number of messages that can be queued for a Websocket client +- [@mathieucarbou](https://github.com/mathieucarbou): Resurrected `AsyncWebSocketMessageBuffer` and `makeBuffer()` in order to make the fork API-compatible with the original library from me-no-dev regarding WebSocket. +- [@vortigont](https://github.com/vortigont): Set real "Last-Modified" header based on file's LastWrite time ([#5](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/5)) +- [@tueddy](https://github.com/tueddy): Compile with Arduino 3 (ESP-IDF 5.1) ([#13](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/13)) +- [@nilo85](https://github.com/nilo85): Add support for Auth & GET requests in AsyncCallbackJsonWebHandler ([#14](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/14)) +- [@mathieucarbou](https://github.com/mathieucarbou): Added `setAuthentication(const String& username, const String& password)` +- [@mathieucarbou](https://github.com/mathieucarbou): Added `StreamConcat` example to show how to stream multiple files in one response +- [@mathieucarbou](https://github.com/mathieucarbou): Remove filename after inline in Content-Disposition header according to RFC2183 +- [@mathieucarbou](https://github.com/mathieucarbou): Depends on `mathieucarbou/Async TCP @ ^3.1.4` +- [@mathieucarbou](https://github.com/mathieucarbou): Arduino 3 / ESP-IDF 5.1 compatibility +- [@mathieucarbou](https://github.com/mathieucarbou): Added all flavors of `binary()`, `text()`, `binaryAll()` and `textAll()` in `AsyncWebSocket` +- [@mathieucarbou](https://github.com/mathieucarbou): Added `setCloseClientOnQueueFull(bool)` which can be set on a client to either close the connection or discard messages but not close the connection when the queue is full +- [@vortigont](https://github.com/vortigont): Some websocket code cleanup ([#29](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/29)) +- [@mathieucarbou](https://github.com/mathieucarbou): Use `-D DEFAULT_MAX_WS_CLIENTS` to change the number of allows WebSocket clients and use `cleanupClients()` to help cleanup resources about dead clients +- [@p0p-x](https://github.com/p0p-x): ESP IDF Compatibility (added back CMakeLists.txt) ([#32](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/32)) + +**In progress** + +In `dev` branch (needs more testing) + +- [@ayushsharma82](https://github.com/ayushsharma82) and [@mathieucarbou](https://github.com/mathieucarbou): Add support for RP2040 ([#31](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/31)) ## Documentation diff --git a/docs/index.md b/docs/index.md index b4330ac74..1c4520ec7 100644 --- a/docs/index.md +++ b/docs/index.md @@ -11,27 +11,34 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo ## Changes in this fork -- Removed SPIFFSEditor -- Deployed in PlatformIO registry and Arduino IDE library manager -- CI -- Some code cleanup -- `SSE_MAX_QUEUED_MESSAGES` to control the maximum number of messages that can be queued for a SSE client -- `write()` function public in `AsyncEventSource.h` -- Arduino Json 7 compatibility and backward compatible with 6 and 6 (changes in `AsyncJson.h`). The API to use Json has not changed. These are only internal changes. -- `WS_MAX_QUEUED_MESSAGES`: control the maximum number of messages that can be queued for a Websocket client -- Resurrected `AsyncWebSocketMessageBuffer` and `makeBuffer()` in order to make the fork API-compatible with the original library from me-no-dev regarding WebSocket. -- [#5](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/5) ([@vortigont](https://github.com/vortigont)): set real "Last-Modified" header based on file's LastWrite time -- [#13](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/13) ([@tueddy](https://github.com/tueddy)): Compile with Arduino 3 (ESP-IDF 5.1) -- [#14](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/14) ([@nilo85](https://github.com/nilo85)): Add support for Auth & GET requests in AsyncCallbackJsonWebHandler -- Added `setAuthentication(const String& username, const String& password)` -- Added `StreamConcat` example to show how to stream multiple files in one response -- Remove filename after inline in Content-Disposition header according to RFC2183 -- Depends on `mathieucarbou/Async TCP @ ^3.1.4` -- Arduino 3 / ESP-IDF 5.1 compatibility -- Added all flavors of `binary()`, `text()`, `binaryAll()` and `textAll()` in `AsyncWebSocket` -- Added `setCloseClientOnQueueFull(bool)` which can be set on a client to either close the connection or discard messages but not close the connection when the queue is full -- [#29](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/29) ([@vortigont](https://github.com/vortigont)): Some websocket code cleanup -- Use `-D DEFAULT_MAX_WS_CLIENTS` to change the number of allows WebSocket clients and use `cleanupClients()` to help cleanup resources about dead clients +- [@mathieucarbou](https://github.com/mathieucarbou): Removed SPIFFSEditor +- [@mathieucarbou](https://github.com/mathieucarbou): Deployed in PlatformIO registry and Arduino IDE library manager +- [@mathieucarbou](https://github.com/mathieucarbou): CI +- [@mathieucarbou](https://github.com/mathieucarbou): Some code cleanup +- [@mathieucarbou](https://github.com/mathieucarbou): `SSE_MAX_QUEUED_MESSAGES` to control the maximum number of messages that can be queued for a SSE client +- [@mathieucarbou](https://github.com/mathieucarbou): `write()` function public in `AsyncEventSource.h` +- [@mathieucarbou](https://github.com/mathieucarbou): Arduino Json 7 compatibility and backward compatible with 6 and 6 (changes in `AsyncJson.h`). The API to use Json has not changed. These are only internal changes. +- [@mathieucarbou](https://github.com/mathieucarbou): `WS_MAX_QUEUED_MESSAGES`: control the maximum number of messages that can be queued for a Websocket client +- [@mathieucarbou](https://github.com/mathieucarbou): Resurrected `AsyncWebSocketMessageBuffer` and `makeBuffer()` in order to make the fork API-compatible with the original library from me-no-dev regarding WebSocket. +- [@vortigont](https://github.com/vortigont): Set real "Last-Modified" header based on file's LastWrite time ([#5](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/5)) +- [@tueddy](https://github.com/tueddy): Compile with Arduino 3 (ESP-IDF 5.1) ([#13](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/13)) +- [@nilo85](https://github.com/nilo85): Add support for Auth & GET requests in AsyncCallbackJsonWebHandler ([#14](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/14)) +- [@mathieucarbou](https://github.com/mathieucarbou): Added `setAuthentication(const String& username, const String& password)` +- [@mathieucarbou](https://github.com/mathieucarbou): Added `StreamConcat` example to show how to stream multiple files in one response +- [@mathieucarbou](https://github.com/mathieucarbou): Remove filename after inline in Content-Disposition header according to RFC2183 +- [@mathieucarbou](https://github.com/mathieucarbou): Depends on `mathieucarbou/Async TCP @ ^3.1.4` +- [@mathieucarbou](https://github.com/mathieucarbou): Arduino 3 / ESP-IDF 5.1 compatibility +- [@mathieucarbou](https://github.com/mathieucarbou): Added all flavors of `binary()`, `text()`, `binaryAll()` and `textAll()` in `AsyncWebSocket` +- [@mathieucarbou](https://github.com/mathieucarbou): Added `setCloseClientOnQueueFull(bool)` which can be set on a client to either close the connection or discard messages but not close the connection when the queue is full +- [@vortigont](https://github.com/vortigont): Some websocket code cleanup ([#29](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/29)) +- [@mathieucarbou](https://github.com/mathieucarbou): Use `-D DEFAULT_MAX_WS_CLIENTS` to change the number of allows WebSocket clients and use `cleanupClients()` to help cleanup resources about dead clients +- [@p0p-x](https://github.com/p0p-x): ESP IDF Compatibility (added back CMakeLists.txt) ([#32](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/32)) + +**In progress** + +In `dev` branch (needs more testing) + +- [@ayushsharma82](https://github.com/ayushsharma82) and [@mathieucarbou](https://github.com/mathieucarbou): Add support for RP2040 ([#31](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/31)) ## Documentation From 5ece1d67a6f5b7a3db95dd680b8090df1f9ab1f8 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Thu, 20 Jun 2024 09:12:08 +0200 Subject: [PATCH 241/551] update doc --- README.md | 29 +++++++++++++++-------------- docs/index.md | 29 +++++++++++++++-------------- 2 files changed, 30 insertions(+), 28 deletions(-) diff --git a/README.md b/README.md index 1c4520ec7..70b6c0741 100644 --- a/README.md +++ b/README.md @@ -11,28 +11,29 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo ## Changes in this fork -- [@mathieucarbou](https://github.com/mathieucarbou): Removed SPIFFSEditor -- [@mathieucarbou](https://github.com/mathieucarbou): Deployed in PlatformIO registry and Arduino IDE library manager -- [@mathieucarbou](https://github.com/mathieucarbou): CI -- [@mathieucarbou](https://github.com/mathieucarbou): Some code cleanup - [@mathieucarbou](https://github.com/mathieucarbou): `SSE_MAX_QUEUED_MESSAGES` to control the maximum number of messages that can be queued for a SSE client - [@mathieucarbou](https://github.com/mathieucarbou): `write()` function public in `AsyncEventSource.h` -- [@mathieucarbou](https://github.com/mathieucarbou): Arduino Json 7 compatibility and backward compatible with 6 and 6 (changes in `AsyncJson.h`). The API to use Json has not changed. These are only internal changes. - [@mathieucarbou](https://github.com/mathieucarbou): `WS_MAX_QUEUED_MESSAGES`: control the maximum number of messages that can be queued for a Websocket client -- [@mathieucarbou](https://github.com/mathieucarbou): Resurrected `AsyncWebSocketMessageBuffer` and `makeBuffer()` in order to make the fork API-compatible with the original library from me-no-dev regarding WebSocket. -- [@vortigont](https://github.com/vortigont): Set real "Last-Modified" header based on file's LastWrite time ([#5](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/5)) -- [@tueddy](https://github.com/tueddy): Compile with Arduino 3 (ESP-IDF 5.1) ([#13](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/13)) -- [@nilo85](https://github.com/nilo85): Add support for Auth & GET requests in AsyncCallbackJsonWebHandler ([#14](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/14)) - [@mathieucarbou](https://github.com/mathieucarbou): Added `setAuthentication(const String& username, const String& password)` +- [@mathieucarbou](https://github.com/mathieucarbou): Added `setCloseClientOnQueueFull(bool)` which can be set on a client to either close the connection or discard messages but not close the connection when the queue is full - [@mathieucarbou](https://github.com/mathieucarbou): Added `StreamConcat` example to show how to stream multiple files in one response -- [@mathieucarbou](https://github.com/mathieucarbou): Remove filename after inline in Content-Disposition header according to RFC2183 -- [@mathieucarbou](https://github.com/mathieucarbou): Depends on `mathieucarbou/Async TCP @ ^3.1.4` -- [@mathieucarbou](https://github.com/mathieucarbou): Arduino 3 / ESP-IDF 5.1 compatibility - [@mathieucarbou](https://github.com/mathieucarbou): Added all flavors of `binary()`, `text()`, `binaryAll()` and `textAll()` in `AsyncWebSocket` -- [@mathieucarbou](https://github.com/mathieucarbou): Added `setCloseClientOnQueueFull(bool)` which can be set on a client to either close the connection or discard messages but not close the connection when the queue is full -- [@vortigont](https://github.com/vortigont): Some websocket code cleanup ([#29](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/29)) +- [@mathieucarbou](https://github.com/mathieucarbou): Arduino 3 / ESP-IDF 5.1 compatibility +- [@mathieucarbou](https://github.com/mathieucarbou): Arduino Json 7 compatibility and backward compatible with 6 and 6 (changes in `AsyncJson.h`). The API to use Json has not changed. These are only internal changes. +- [@mathieucarbou](https://github.com/mathieucarbou): CI +- [@mathieucarbou](https://github.com/mathieucarbou): Depends on `mathieucarbou/Async TCP @ ^3.1.4` +- [@mathieucarbou](https://github.com/mathieucarbou): Deployed in PlatformIO registry and Arduino IDE library manager +- [@mathieucarbou](https://github.com/mathieucarbou): Remove filename after inline in Content-Disposition header according to RFC2183 +- [@mathieucarbou](https://github.com/mathieucarbou): Remove filename after inline in Content-Disposition header according to RFC2183 +- [@mathieucarbou](https://github.com/mathieucarbou): Removed SPIFFSEditor +- [@mathieucarbou](https://github.com/mathieucarbou): Resurrected `AsyncWebSocketMessageBuffer` and `makeBuffer()` in order to make the fork API-compatible with the original library from me-no-dev regarding WebSocket. +- [@mathieucarbou](https://github.com/mathieucarbou): Some code cleanup - [@mathieucarbou](https://github.com/mathieucarbou): Use `-D DEFAULT_MAX_WS_CLIENTS` to change the number of allows WebSocket clients and use `cleanupClients()` to help cleanup resources about dead clients +- [@nilo85](https://github.com/nilo85): Add support for Auth & GET requests in AsyncCallbackJsonWebHandler ([#14](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/14)) - [@p0p-x](https://github.com/p0p-x): ESP IDF Compatibility (added back CMakeLists.txt) ([#32](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/32)) +- [@tueddy](https://github.com/tueddy): Compile with Arduino 3 (ESP-IDF 5.1) ([#13](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/13)) +- [@vortigont](https://github.com/vortigont): Set real "Last-Modified" header based on file's LastWrite time ([#5](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/5)) +- [@vortigont](https://github.com/vortigont): Some websocket code cleanup ([#29](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/29)) **In progress** diff --git a/docs/index.md b/docs/index.md index 1c4520ec7..70b6c0741 100644 --- a/docs/index.md +++ b/docs/index.md @@ -11,28 +11,29 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo ## Changes in this fork -- [@mathieucarbou](https://github.com/mathieucarbou): Removed SPIFFSEditor -- [@mathieucarbou](https://github.com/mathieucarbou): Deployed in PlatformIO registry and Arduino IDE library manager -- [@mathieucarbou](https://github.com/mathieucarbou): CI -- [@mathieucarbou](https://github.com/mathieucarbou): Some code cleanup - [@mathieucarbou](https://github.com/mathieucarbou): `SSE_MAX_QUEUED_MESSAGES` to control the maximum number of messages that can be queued for a SSE client - [@mathieucarbou](https://github.com/mathieucarbou): `write()` function public in `AsyncEventSource.h` -- [@mathieucarbou](https://github.com/mathieucarbou): Arduino Json 7 compatibility and backward compatible with 6 and 6 (changes in `AsyncJson.h`). The API to use Json has not changed. These are only internal changes. - [@mathieucarbou](https://github.com/mathieucarbou): `WS_MAX_QUEUED_MESSAGES`: control the maximum number of messages that can be queued for a Websocket client -- [@mathieucarbou](https://github.com/mathieucarbou): Resurrected `AsyncWebSocketMessageBuffer` and `makeBuffer()` in order to make the fork API-compatible with the original library from me-no-dev regarding WebSocket. -- [@vortigont](https://github.com/vortigont): Set real "Last-Modified" header based on file's LastWrite time ([#5](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/5)) -- [@tueddy](https://github.com/tueddy): Compile with Arduino 3 (ESP-IDF 5.1) ([#13](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/13)) -- [@nilo85](https://github.com/nilo85): Add support for Auth & GET requests in AsyncCallbackJsonWebHandler ([#14](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/14)) - [@mathieucarbou](https://github.com/mathieucarbou): Added `setAuthentication(const String& username, const String& password)` +- [@mathieucarbou](https://github.com/mathieucarbou): Added `setCloseClientOnQueueFull(bool)` which can be set on a client to either close the connection or discard messages but not close the connection when the queue is full - [@mathieucarbou](https://github.com/mathieucarbou): Added `StreamConcat` example to show how to stream multiple files in one response -- [@mathieucarbou](https://github.com/mathieucarbou): Remove filename after inline in Content-Disposition header according to RFC2183 -- [@mathieucarbou](https://github.com/mathieucarbou): Depends on `mathieucarbou/Async TCP @ ^3.1.4` -- [@mathieucarbou](https://github.com/mathieucarbou): Arduino 3 / ESP-IDF 5.1 compatibility - [@mathieucarbou](https://github.com/mathieucarbou): Added all flavors of `binary()`, `text()`, `binaryAll()` and `textAll()` in `AsyncWebSocket` -- [@mathieucarbou](https://github.com/mathieucarbou): Added `setCloseClientOnQueueFull(bool)` which can be set on a client to either close the connection or discard messages but not close the connection when the queue is full -- [@vortigont](https://github.com/vortigont): Some websocket code cleanup ([#29](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/29)) +- [@mathieucarbou](https://github.com/mathieucarbou): Arduino 3 / ESP-IDF 5.1 compatibility +- [@mathieucarbou](https://github.com/mathieucarbou): Arduino Json 7 compatibility and backward compatible with 6 and 6 (changes in `AsyncJson.h`). The API to use Json has not changed. These are only internal changes. +- [@mathieucarbou](https://github.com/mathieucarbou): CI +- [@mathieucarbou](https://github.com/mathieucarbou): Depends on `mathieucarbou/Async TCP @ ^3.1.4` +- [@mathieucarbou](https://github.com/mathieucarbou): Deployed in PlatformIO registry and Arduino IDE library manager +- [@mathieucarbou](https://github.com/mathieucarbou): Remove filename after inline in Content-Disposition header according to RFC2183 +- [@mathieucarbou](https://github.com/mathieucarbou): Remove filename after inline in Content-Disposition header according to RFC2183 +- [@mathieucarbou](https://github.com/mathieucarbou): Removed SPIFFSEditor +- [@mathieucarbou](https://github.com/mathieucarbou): Resurrected `AsyncWebSocketMessageBuffer` and `makeBuffer()` in order to make the fork API-compatible with the original library from me-no-dev regarding WebSocket. +- [@mathieucarbou](https://github.com/mathieucarbou): Some code cleanup - [@mathieucarbou](https://github.com/mathieucarbou): Use `-D DEFAULT_MAX_WS_CLIENTS` to change the number of allows WebSocket clients and use `cleanupClients()` to help cleanup resources about dead clients +- [@nilo85](https://github.com/nilo85): Add support for Auth & GET requests in AsyncCallbackJsonWebHandler ([#14](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/14)) - [@p0p-x](https://github.com/p0p-x): ESP IDF Compatibility (added back CMakeLists.txt) ([#32](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/32)) +- [@tueddy](https://github.com/tueddy): Compile with Arduino 3 (ESP-IDF 5.1) ([#13](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/13)) +- [@vortigont](https://github.com/vortigont): Set real "Last-Modified" header based on file's LastWrite time ([#5](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/5)) +- [@vortigont](https://github.com/vortigont): Some websocket code cleanup ([#29](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/29)) **In progress** From 89c871b6a342517698ea765defc6ec5f68dfcd2a Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Thu, 20 Jun 2024 09:24:33 +0200 Subject: [PATCH 242/551] doc update --- README.md | 4 +++- docs/index.md | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 70b6c0741..eb3a3cc27 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,9 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo - [@mathieucarbou](https://github.com/mathieucarbou): CI - [@mathieucarbou](https://github.com/mathieucarbou): Depends on `mathieucarbou/Async TCP @ ^3.1.4` - [@mathieucarbou](https://github.com/mathieucarbou): Deployed in PlatformIO registry and Arduino IDE library manager -- [@mathieucarbou](https://github.com/mathieucarbou): Remove filename after inline in Content-Disposition header according to RFC2183 +- [@mathieucarbou](https://github.com/mathieucarbou): Firmware size optimization: remove mbedtls dependency (accounts for 33KB in firmware) +- [@mathieucarbou](https://github.com/mathieucarbou): Made DEFAULT_MAX_SSE_CLIENTS customizable +- [@mathieucarbou](https://github.com/mathieucarbou): Made DEFAULT_MAX_WS_CLIENTS customizable - [@mathieucarbou](https://github.com/mathieucarbou): Remove filename after inline in Content-Disposition header according to RFC2183 - [@mathieucarbou](https://github.com/mathieucarbou): Removed SPIFFSEditor - [@mathieucarbou](https://github.com/mathieucarbou): Resurrected `AsyncWebSocketMessageBuffer` and `makeBuffer()` in order to make the fork API-compatible with the original library from me-no-dev regarding WebSocket. diff --git a/docs/index.md b/docs/index.md index 70b6c0741..eb3a3cc27 100644 --- a/docs/index.md +++ b/docs/index.md @@ -23,7 +23,9 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo - [@mathieucarbou](https://github.com/mathieucarbou): CI - [@mathieucarbou](https://github.com/mathieucarbou): Depends on `mathieucarbou/Async TCP @ ^3.1.4` - [@mathieucarbou](https://github.com/mathieucarbou): Deployed in PlatformIO registry and Arduino IDE library manager -- [@mathieucarbou](https://github.com/mathieucarbou): Remove filename after inline in Content-Disposition header according to RFC2183 +- [@mathieucarbou](https://github.com/mathieucarbou): Firmware size optimization: remove mbedtls dependency (accounts for 33KB in firmware) +- [@mathieucarbou](https://github.com/mathieucarbou): Made DEFAULT_MAX_SSE_CLIENTS customizable +- [@mathieucarbou](https://github.com/mathieucarbou): Made DEFAULT_MAX_WS_CLIENTS customizable - [@mathieucarbou](https://github.com/mathieucarbou): Remove filename after inline in Content-Disposition header according to RFC2183 - [@mathieucarbou](https://github.com/mathieucarbou): Removed SPIFFSEditor - [@mathieucarbou](https://github.com/mathieucarbou): Resurrected `AsyncWebSocketMessageBuffer` and `makeBuffer()` in order to make the fork API-compatible with the original library from me-no-dev regarding WebSocket. From 473e610490a72ad43f981b5b770f74d8e8788734 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Sun, 23 Jun 2024 12:30:41 +0200 Subject: [PATCH 243/551] Update doc and issue templates --- .github/ISSUE_TEMPLATE/bug_report.md | 33 ++++++++++++++++++++++++++++ .github/ISSUE_TEMPLATE/question.md | 10 +++++++++ README.md | 33 +++++++++++++++++++--------- docs/index.md | 33 +++++++++++++++++++--------- 4 files changed, 89 insertions(+), 20 deletions(-) create mode 100644 .github/ISSUE_TEMPLATE/bug_report.md create mode 100644 .github/ISSUE_TEMPLATE/question.md diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 000000000..361e6faf4 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,33 @@ +--- +name: Bug report +about: Create a report to help us improve +title: "[BUG]" +labels: bug +assignees: '' + +--- + +**Please make sure to go through the recommendations before opening a bug report:** + +[https://github.com/mathieucarbou/ESPAsyncWebServer?tab=readme-ov-file#important-recommendations](https://github.com/mathieucarbou/ESPAsyncWebServer?tab=readme-ov-file#important-recommendations) + +**Description** + +A clear and concise description of what the bug is. + +**Board** + +esp32dev, esp32s3, etc + +**Ethernet adpater used ?** + +If yes, please specify which one + +**Stack trace** + +Please provide the stack trace here taken with `monitor_filters = esp32_exception_decoder`. +**Any issue opened with a non readable stack trace will be ignored because not helpful at all.** + +**Additional notes** + +Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/question.md b/.github/ISSUE_TEMPLATE/question.md new file mode 100644 index 000000000..634179ca6 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/question.md @@ -0,0 +1,10 @@ +--- +name: Question +about: Describe your question +title: "[Q]" +labels: question +assignees: '' + +--- + + diff --git a/README.md b/README.md index eb3a3cc27..2c7ac66cb 100644 --- a/README.md +++ b/README.md @@ -86,17 +86,30 @@ void send(JsonDocument& doc) { I recommend to use the official API `AsyncWebSocketMessageBuffer` to retain further compatibility. -## Stack size and queues - -Here are some important flags to tweak depending on your needs: - -```cpp - // Async TCP queue size +## Important recommendations + +Most of the crashes are caused by improper configuration of the library for the project. +Here are some recommendations to avoid them. + +1. Set the running core to be on the same core of your application (usually core 1) `-D CONFIG_ASYNC_TCP_RUNNING_CORE=1` +2. Set the stack size appropriately with `-D CONFIG_ASYNC_TCP_STACK_SIZE=16384`. + The default value of `16384` might be too much for your project. + You can look at the [MycilaTaskMonitor](https://oss.carbou.me/MycilaTaskMonitor) project to monitor the stack usage. +3. You can change **if you know what you are doing** the task priority with `-D CONFIG_ASYNC_TCP_PRIORITY=10`. + Default is `10`. +4. You can increase the queue size with `-D CONFIG_ASYNC_TCP_QUEUE_SIZE=128`. + Default is `64`. +5. You can decrease the maximum ack time `-D CONFIG_ASYNC_TCP_MAX_ACK_TIME=3000`. + Default is `5000`. + +I personally use the following configuration in my projects because my WS messages can be big (up to 4k). +If you have smaller messages, you can increase `WS_MAX_QUEUED_MESSAGES` to 128. + +```c++ + -D CONFIG_ASYNC_TCP_MAX_ACK_TIME=3000 + -D CONFIG_ASYNC_TCP_PRIORITY=10 -D CONFIG_ASYNC_TCP_QUEUE_SIZE=128 - // Async TCP async task core -D CONFIG_ASYNC_TCP_RUNNING_CORE=1 - // Async TCP async stac ksize - -D CONFIG_ASYNC_TCP_STACK_SIZE=8096 - // WebSocket queue size + -D CONFIG_ASYNC_TCP_STACK_SIZE=4096 -D WS_MAX_QUEUED_MESSAGES=64 ``` diff --git a/docs/index.md b/docs/index.md index eb3a3cc27..2c7ac66cb 100644 --- a/docs/index.md +++ b/docs/index.md @@ -86,17 +86,30 @@ void send(JsonDocument& doc) { I recommend to use the official API `AsyncWebSocketMessageBuffer` to retain further compatibility. -## Stack size and queues - -Here are some important flags to tweak depending on your needs: - -```cpp - // Async TCP queue size +## Important recommendations + +Most of the crashes are caused by improper configuration of the library for the project. +Here are some recommendations to avoid them. + +1. Set the running core to be on the same core of your application (usually core 1) `-D CONFIG_ASYNC_TCP_RUNNING_CORE=1` +2. Set the stack size appropriately with `-D CONFIG_ASYNC_TCP_STACK_SIZE=16384`. + The default value of `16384` might be too much for your project. + You can look at the [MycilaTaskMonitor](https://oss.carbou.me/MycilaTaskMonitor) project to monitor the stack usage. +3. You can change **if you know what you are doing** the task priority with `-D CONFIG_ASYNC_TCP_PRIORITY=10`. + Default is `10`. +4. You can increase the queue size with `-D CONFIG_ASYNC_TCP_QUEUE_SIZE=128`. + Default is `64`. +5. You can decrease the maximum ack time `-D CONFIG_ASYNC_TCP_MAX_ACK_TIME=3000`. + Default is `5000`. + +I personally use the following configuration in my projects because my WS messages can be big (up to 4k). +If you have smaller messages, you can increase `WS_MAX_QUEUED_MESSAGES` to 128. + +```c++ + -D CONFIG_ASYNC_TCP_MAX_ACK_TIME=3000 + -D CONFIG_ASYNC_TCP_PRIORITY=10 -D CONFIG_ASYNC_TCP_QUEUE_SIZE=128 - // Async TCP async task core -D CONFIG_ASYNC_TCP_RUNNING_CORE=1 - // Async TCP async stac ksize - -D CONFIG_ASYNC_TCP_STACK_SIZE=8096 - // WebSocket queue size + -D CONFIG_ASYNC_TCP_STACK_SIZE=4096 -D WS_MAX_QUEUED_MESSAGES=64 ``` From 41456b106e7ac3a5bd2b95e5dc8127f25e29cf3a Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Sun, 23 Jun 2024 23:10:31 +0200 Subject: [PATCH 244/551] typo --- .github/ISSUE_TEMPLATE/bug_report.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 361e6faf4..b35e87633 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -19,7 +19,7 @@ A clear and concise description of what the bug is. esp32dev, esp32s3, etc -**Ethernet adpater used ?** +**Ethernet adapter used ?** If yes, please specify which one From 28adedaf28802073f7a9852cf592dcf48747cc96 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Mon, 24 Jun 2024 22:30:38 +0200 Subject: [PATCH 245/551] Arduino Release v3.0.2 based on ESP-IDF v5.1.4+ --- platformio.ini | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platformio.ini b/platformio.ini index 3d9a732f1..795b32db3 100644 --- a/platformio.ini +++ b/platformio.ini @@ -33,8 +33,8 @@ lib_deps = [env:arduino-3] platform = espressif32 platform_packages= - platformio/framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#3.0.1 - platformio/framework-arduinoespressif32-libs @ https://github.com/espressif/arduino-esp32/releases/download/3.0.1/esp32-arduino-libs-3.0.1.zip + platformio/framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#3.0.2 + platformio/framework-arduinoespressif32-libs @ https://github.com/espressif/arduino-esp32/releases/download/3.0.2/esp32-arduino-libs-3.0.2.zip board = esp32dev lib_deps = bblanchon/ArduinoJson @ 7.0.4 From 16fd203198d68ea50855ac2afd945df9fd09f126 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Thu, 27 Jun 2024 14:02:23 +0200 Subject: [PATCH 246/551] update doc --- README.md | 2 +- docs/index.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 2c7ac66cb..6ac046985 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo - [@mathieucarbou](https://github.com/mathieucarbou): Made DEFAULT_MAX_SSE_CLIENTS customizable - [@mathieucarbou](https://github.com/mathieucarbou): Made DEFAULT_MAX_WS_CLIENTS customizable - [@mathieucarbou](https://github.com/mathieucarbou): Remove filename after inline in Content-Disposition header according to RFC2183 -- [@mathieucarbou](https://github.com/mathieucarbou): Removed SPIFFSEditor +- [@mathieucarbou](https://github.com/mathieucarbou): Removed SPIFFSEditor to reduce library size and maintainance. SPIFF si also deprecated. If you need it, please copy the files from the original repository in your project. This fork focus on maintaining the server part and the SPIFFEditor is an application which has nothing to do inside a server library. - [@mathieucarbou](https://github.com/mathieucarbou): Resurrected `AsyncWebSocketMessageBuffer` and `makeBuffer()` in order to make the fork API-compatible with the original library from me-no-dev regarding WebSocket. - [@mathieucarbou](https://github.com/mathieucarbou): Some code cleanup - [@mathieucarbou](https://github.com/mathieucarbou): Use `-D DEFAULT_MAX_WS_CLIENTS` to change the number of allows WebSocket clients and use `cleanupClients()` to help cleanup resources about dead clients diff --git a/docs/index.md b/docs/index.md index 2c7ac66cb..6ac046985 100644 --- a/docs/index.md +++ b/docs/index.md @@ -27,7 +27,7 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo - [@mathieucarbou](https://github.com/mathieucarbou): Made DEFAULT_MAX_SSE_CLIENTS customizable - [@mathieucarbou](https://github.com/mathieucarbou): Made DEFAULT_MAX_WS_CLIENTS customizable - [@mathieucarbou](https://github.com/mathieucarbou): Remove filename after inline in Content-Disposition header according to RFC2183 -- [@mathieucarbou](https://github.com/mathieucarbou): Removed SPIFFSEditor +- [@mathieucarbou](https://github.com/mathieucarbou): Removed SPIFFSEditor to reduce library size and maintainance. SPIFF si also deprecated. If you need it, please copy the files from the original repository in your project. This fork focus on maintaining the server part and the SPIFFEditor is an application which has nothing to do inside a server library. - [@mathieucarbou](https://github.com/mathieucarbou): Resurrected `AsyncWebSocketMessageBuffer` and `makeBuffer()` in order to make the fork API-compatible with the original library from me-no-dev regarding WebSocket. - [@mathieucarbou](https://github.com/mathieucarbou): Some code cleanup - [@mathieucarbou](https://github.com/mathieucarbou): Use `-D DEFAULT_MAX_WS_CLIENTS` to change the number of allows WebSocket clients and use `cleanupClients()` to help cleanup resources about dead clients From d614ccde91c726dd03f2feab2f64f49788bce19d Mon Sep 17 00:00:00 2001 From: Emil Muratov Date: Wed, 26 Jun 2024 16:50:45 +0900 Subject: [PATCH 247/551] replace self-implemented mutex structures with std:mutex Use STL's platform implementation for mutex locks --- src/AsyncEventSource.cpp | 55 +++++++++----- src/AsyncEventSource.h | 13 ++-- src/AsyncWebSocket.cpp | 93 +++++++++++------------ src/AsyncWebSocket.h | 12 +-- src/AsyncWebSynchronization.h | 134 ---------------------------------- 5 files changed, 95 insertions(+), 212 deletions(-) delete mode 100644 src/AsyncWebSynchronization.h diff --git a/src/AsyncEventSource.cpp b/src/AsyncEventSource.cpp index 98f18dea4..69371c60c 100644 --- a/src/AsyncEventSource.cpp +++ b/src/AsyncEventSource.cpp @@ -18,10 +18,10 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "Arduino.h" -#include "AsyncEventSource.h" #ifndef ESP8266 #include #endif +#include "AsyncEventSource.h" static String generateEventMessage(const char *message, const char *event, uint32_t id, uint32_t reconnect){ String ev; @@ -177,9 +177,10 @@ AsyncEventSourceClient::AsyncEventSourceClient(AsyncWebServerRequest *request, A } AsyncEventSourceClient::~AsyncEventSourceClient(){ - _lockmq.lock(); +#ifdef ESP32 + std::lock_guard lock(_lockmq); +#endif _messageQueue.free(); - _lockmq.unlock(); close(); } @@ -190,8 +191,10 @@ void AsyncEventSourceClient::_queueMessage(AsyncEventSourceMessage *dataMessage) delete dataMessage; return; } +#ifdef ESP32 //length() is not thread-safe, thus acquiring the lock before this call.. - _lockmq.lock(); + std::lock_guard lock(_lockmq); +#endif if(_messageQueue.length() >= SSE_MAX_QUEUED_MESSAGES){ #ifdef ESP8266 ets_printf(String(F("ERROR: Too many messages queued\n")).c_str()); @@ -206,27 +209,29 @@ void AsyncEventSourceClient::_queueMessage(AsyncEventSourceMessage *dataMessage) _runQueue(); } } - _lockmq.unlock(); } void AsyncEventSourceClient::_onAck(size_t len, uint32_t time){ +#ifdef ESP32 // Same here, acquiring the lock early - _lockmq.lock(); + std::lock_guard lock(_lockmq); +#endif while(len && !_messageQueue.isEmpty()){ len = _messageQueue.front()->ack(len, time); if(_messageQueue.front()->finished()) _messageQueue.remove(_messageQueue.front()); } _runQueue(); - _lockmq.unlock(); } void AsyncEventSourceClient::_onPoll(){ - _lockmq.lock(); +#ifdef ESP32 + // Same here, acquiring the lock early + std::lock_guard lock(_lockmq); +#endif if(!_messageQueue.isEmpty()){ _runQueue(); } - _lockmq.unlock(); } void AsyncEventSourceClient::_onTimeout(uint32_t time __attribute__((unused))){ @@ -253,10 +258,10 @@ void AsyncEventSourceClient::send(const char *message, const char *event, uint32 } size_t AsyncEventSourceClient::packetsWaiting() const { - size_t len; - _lockmq.lock(); - len = _messageQueue.length(); - _lockmq.unlock(); +#ifdef ESP32 + std::lock_guard lock(_lockmq); +#endif + size_t len = _messageQueue.length(); return len; } @@ -306,14 +311,18 @@ void AsyncEventSource::_addClient(AsyncEventSourceClient * client){ client->write((const char *)temp, 2053); free(temp); }*/ - AsyncWebLockGuard l(_client_queue_lock); +#ifdef ESP32 + std::lock_guard lock(_client_queue_lock); +#endif _clients.add(client); if(_connectcb) _connectcb(client); } void AsyncEventSource::_handleDisconnect(AsyncEventSourceClient * client){ - AsyncWebLockGuard l(_client_queue_lock); +#ifdef ESP32 + std::lock_guard lock(_client_queue_lock); +#endif _clients.remove(client); } @@ -321,7 +330,9 @@ void AsyncEventSource::close(){ // While the whole loop is not done, the linked list is locked and so the // iterator should remain valid even when AsyncEventSource::_handleDisconnect() // is called very early - AsyncWebLockGuard l(_client_queue_lock); +#ifdef ESP32 + std::lock_guard lock(_client_queue_lock); +#endif for(const auto &c: _clients){ if(c->connected()) c->close(); @@ -332,7 +343,9 @@ void AsyncEventSource::close(){ size_t AsyncEventSource::avgPacketsWaiting() const { size_t aql = 0; uint32_t nConnectedClients = 0; - AsyncWebLockGuard l(_client_queue_lock); +#ifdef ESP32 + std::lock_guard lock(_client_queue_lock); +#endif if (_clients.isEmpty()) { return 0; } @@ -348,7 +361,9 @@ size_t AsyncEventSource::avgPacketsWaiting() const { void AsyncEventSource::send( const char *message, const char *event, uint32_t id, uint32_t reconnect){ String ev = generateEventMessage(message, event, id, reconnect); - AsyncWebLockGuard l(_client_queue_lock); +#ifdef ESP32 + std::lock_guard lock(_client_queue_lock); +#endif for(const auto &c: _clients){ if(c->connected()) { c->write(ev.c_str(), ev.length()); @@ -358,7 +373,9 @@ void AsyncEventSource::send( size_t AsyncEventSource::count() const { size_t n_clients; - AsyncWebLockGuard l(_client_queue_lock); +#ifdef ESP32 + std::lock_guard lock(_client_queue_lock); +#endif n_clients = _clients.count_if([](AsyncEventSourceClient *c){ return c->connected(); }); diff --git a/src/AsyncEventSource.h b/src/AsyncEventSource.h index 2efb0ddd3..6d76b2f50 100644 --- a/src/AsyncEventSource.h +++ b/src/AsyncEventSource.h @@ -22,11 +22,12 @@ #include #ifdef ESP32 +#include #include #ifndef SSE_MAX_QUEUED_MESSAGES #define SSE_MAX_QUEUED_MESSAGES 32 #endif -#else +#else // esp8266 #include #ifndef SSE_MAX_QUEUED_MESSAGES #define SSE_MAX_QUEUED_MESSAGES 8 @@ -35,8 +36,6 @@ #include -#include "AsyncWebSynchronization.h" - #ifdef ESP8266 #include #ifdef CRYPTO_HASH_h // include Hash.h from espressif framework if the first include was from the crypto library @@ -81,7 +80,9 @@ class AsyncEventSourceClient { uint32_t _lastId; LinkedList _messageQueue; // ArFi 2020-08-27 for protecting/serializing _messageQueue - AsyncPlainLock _lockmq; +#ifdef ESP32 + mutable std::mutex _lockmq; +#endif void _queueMessage(AsyncEventSourceMessage *dataMessage); void _runQueue(); @@ -109,9 +110,11 @@ class AsyncEventSource: public AsyncWebHandler { private: String _url; LinkedList _clients; +#ifdef ESP32 // Same as for individual messages, protect mutations of _clients list // since simultaneous access from different tasks is possible - AsyncWebLock _client_queue_lock; + mutable std::mutex _client_queue_lock; +#endif ArEventHandlerFunction _connectcb; ArAuthorizeConnectHandler _authorizeConnectHandler; public: diff --git a/src/AsyncWebSocket.cpp b/src/AsyncWebSocket.cpp index df6821dd0..926d6a41a 100644 --- a/src/AsyncWebSocket.cpp +++ b/src/AsyncWebSocket.cpp @@ -314,8 +314,9 @@ AsyncWebSocketClient::AsyncWebSocketClient(AsyncWebServerRequest *request, Async AsyncWebSocketClient::~AsyncWebSocketClient() { { - AsyncWebLockGuard l(_lock); - + #ifdef ESP32 + std::lock_guard lock(_lock); + #endif _messageQueue.clear(); _controlQueue.clear(); } @@ -331,7 +332,9 @@ void AsyncWebSocketClient::_clearQueue() void AsyncWebSocketClient::_onAck(size_t len, uint32_t time){ _lastMessageTime = millis(); - AsyncWebLockGuard l(_lock); + #ifdef ESP32 + std::lock_guard lock(_lock); + #endif if (!_controlQueue.empty()) { auto &head = _controlQueue.front(); @@ -340,7 +343,6 @@ void AsyncWebSocketClient::_onAck(size_t len, uint32_t time){ if (_status == WS_DISCONNECTING && head.opcode() == WS_DISCONNECT){ _controlQueue.pop_front(); _status = WS_DISCONNECTED; - l.unlock(); if (_client) _client->close(true); return; } @@ -362,65 +364,64 @@ void AsyncWebSocketClient::_onPoll() if (!_client) return; - AsyncWebLockGuard l(_lock); + #ifdef ESP32 + std::unique_lock lock(_lock); + #endif if (_client->canSend() && (!_controlQueue.empty() || !_messageQueue.empty())) { - l.unlock(); _runQueue(); } else if (_keepAlivePeriod > 0 && (millis() - _lastMessageTime) >= _keepAlivePeriod && (_controlQueue.empty() && _messageQueue.empty())) { - l.unlock(); +#ifdef ESP32 + lock.unlock(); +#endif ping((uint8_t *)AWSC_PING_PAYLOAD, AWSC_PING_PAYLOAD_LEN); } } void AsyncWebSocketClient::_runQueue() { + // all calls to this method MUST be protected by a mutex lock! if (!_client) return; - AsyncWebLockGuard l(_lock); - _clearQueue(); if (!_controlQueue.empty() && (_messageQueue.empty() || _messageQueue.front().betweenFrames()) && webSocketSendFrameWindow(_client) > (size_t)(_controlQueue.front().len() - 1)) { - //l.unlock(); _controlQueue.front().send(_client); } else if (!_messageQueue.empty() && _messageQueue.front().betweenFrames() && webSocketSendFrameWindow(_client)) { - //l.unlock(); _messageQueue.front().send(_client); } } bool AsyncWebSocketClient::queueIsFull() const { - size_t size; - { - AsyncWebLockGuard l(_lock); - size = _messageQueue.size(); - } + #ifdef ESP32 + std::lock_guard lock(_lock); + #endif + size_t size = _messageQueue.size();; return (size >= WS_MAX_QUEUED_MESSAGES) || (_status != WS_CONNECTED); } size_t AsyncWebSocketClient::queueLen() const { - AsyncWebLockGuard l(_lock); + #ifdef ESP32 + std::lock_guard lock(_lock); + #endif return _messageQueue.size() + _controlQueue.size(); } bool AsyncWebSocketClient::canSend() const { - size_t size; - { - AsyncWebLockGuard l(_lock); - size = _messageQueue.size(); - } - return size < WS_MAX_QUEUED_MESSAGES; + #ifdef ESP32 + std::lock_guard lock(_lock); + #endif + return _messageQueue.size() < WS_MAX_QUEUED_MESSAGES; } void AsyncWebSocketClient::_queueControl(uint8_t opcode, const uint8_t *data, size_t len, bool mask) @@ -429,7 +430,9 @@ void AsyncWebSocketClient::_queueControl(uint8_t opcode, const uint8_t *data, si return; { - AsyncWebLockGuard l(_lock); + #ifdef ESP32 + std::lock_guard lock(_lock); + #endif _controlQueue.emplace_back(opcode, data, len, mask); } @@ -439,42 +442,34 @@ void AsyncWebSocketClient::_queueControl(uint8_t opcode, const uint8_t *data, si void AsyncWebSocketClient::_queueMessage(AsyncWebSocketSharedBuffer buffer, uint8_t opcode, bool mask) { - if(_status != WS_CONNECTED) - return; - - if (!_client) - return; - - if (buffer->size() == 0) + if(!_client || buffer->size() == 0 || _status != WS_CONNECTED) return; + #ifdef ESP32 + std::lock_guard lock(_lock); + #endif + if (_messageQueue.size() >= WS_MAX_QUEUED_MESSAGES) { - AsyncWebLockGuard l(_lock); - if (_messageQueue.size() >= WS_MAX_QUEUED_MESSAGES) + if(closeWhenFull) { - l.unlock(); - if(closeWhenFull) - { #ifdef ESP8266 - ets_printf("AsyncWebSocketClient::_queueMessage: Too many messages queued: closing connection\n"); + ets_printf("AsyncWebSocketClient::_queueMessage: Too many messages queued: closing connection\n"); #else - log_e("Too many messages queued: closing connection"); + log_e("Too many messages queued: closing connection"); #endif - _status = WS_DISCONNECTED; - if (_client) _client->close(true); - } else { + _status = WS_DISCONNECTED; + if (_client) _client->close(true); + } else { #ifdef ESP8266 - ets_printf("AsyncWebSocketClient::_queueMessage: Too many messages queued: discarding new message\n"); + ets_printf("AsyncWebSocketClient::_queueMessage: Too many messages queued: discarding new message\n"); #else - log_e("Too many messages queued: discarding new message"); + log_e("Too many messages queued: discarding new message"); #endif - } - return; - } - else - { - _messageQueue.emplace_back(buffer, opcode, mask); } + return; + } + else { + _messageQueue.emplace_back(buffer, opcode, mask); } if (_client && _client->canSend()) diff --git a/src/AsyncWebSocket.h b/src/AsyncWebSocket.h index cde0b437c..a40fc85ca 100644 --- a/src/AsyncWebSocket.h +++ b/src/AsyncWebSocket.h @@ -23,6 +23,7 @@ #include #ifdef ESP32 +#include #include #ifndef WS_MAX_QUEUED_MESSAGES #define WS_MAX_QUEUED_MESSAGES 32 @@ -35,7 +36,6 @@ #endif #include -#include "AsyncWebSynchronization.h" #include #include @@ -136,9 +136,9 @@ class AsyncWebSocketClient { AsyncWebSocket *_server; uint32_t _clientId; AwsClientStatus _status; - - AsyncWebLock _lock; - +#ifdef ESP32 + mutable std::mutex _lock; +#endif std::deque _controlQueue; std::deque _messageQueue; bool closeWhenFull = true; @@ -260,7 +260,9 @@ class AsyncWebSocket: public AsyncWebHandler { AwsEventHandler _eventHandler{nullptr}; AwsHandshakeHandler _handshakeHandler; bool _enabled; - AsyncWebLock _lock; +#ifdef ESP32 + mutable std::mutex _lock; +#endif public: explicit AsyncWebSocket(const char* url) : _url(url) ,_cNextId(1), _enabled(true) {} diff --git a/src/AsyncWebSynchronization.h b/src/AsyncWebSynchronization.h deleted file mode 100644 index 0ff8ab63b..000000000 --- a/src/AsyncWebSynchronization.h +++ /dev/null @@ -1,134 +0,0 @@ -#ifndef ASYNCWEBSYNCHRONIZATION_H_ -#define ASYNCWEBSYNCHRONIZATION_H_ - -// Synchronisation is only available on ESP32, as the ESP8266 isn't using FreeRTOS by default - -#include - -#ifdef ESP32 - -// This is the ESP32 version of the Sync Lock, using the FreeRTOS Semaphore -// Modified 'AsyncWebLock' to just only use mutex since pxCurrentTCB is not -// always available. According to example by Arjan Filius, changed name, -// added unimplemented version for ESP8266 -class AsyncPlainLock -{ -private: - SemaphoreHandle_t _lock; - -public: - AsyncPlainLock() { - _lock = xSemaphoreCreateBinary(); - // In this fails, the system is likely that much out of memory that - // we should abort anyways. If assertions are disabled, nothing is lost.. - assert(_lock); - xSemaphoreGive(_lock); - } - - ~AsyncPlainLock() { - vSemaphoreDelete(_lock); - } - - bool lock() const { - xSemaphoreTake(_lock, portMAX_DELAY); - return true; - } - - void unlock() const { - xSemaphoreGive(_lock); - } -}; - -// This is the ESP32 version of the Sync Lock, using the FreeRTOS Semaphore -class AsyncWebLock -{ -private: - SemaphoreHandle_t _lock; - mutable TaskHandle_t _lockedBy{}; - -public: - AsyncWebLock() - { - _lock = xSemaphoreCreateBinary(); - // In this fails, the system is likely that much out of memory that - // we should abort anyways. If assertions are disabled, nothing is lost.. - assert(_lock); - _lockedBy = NULL; - xSemaphoreGive(_lock); - } - - ~AsyncWebLock() { - vSemaphoreDelete(_lock); - } - - bool lock() const { - const auto currentTask = xTaskGetCurrentTaskHandle(); - if (_lockedBy != currentTask) { - xSemaphoreTake(_lock, portMAX_DELAY); - _lockedBy = currentTask; - return true; - } - return false; - } - - void unlock() const { - _lockedBy = NULL; - xSemaphoreGive(_lock); - } -}; - -#else - -// This is the 8266 version of the Sync Lock which is currently unimplemented -class AsyncWebLock -{ - -public: - AsyncWebLock() { - } - - ~AsyncWebLock() { - } - - bool lock() const { - return false; - } - - void unlock() const { - } -}; - -// Same for AsyncPlainLock, for ESP8266 this is just the unimplemented version above. -using AsyncPlainLock = AsyncWebLock; - -#endif - -class AsyncWebLockGuard -{ -private: - const AsyncWebLock *_lock; - -public: - AsyncWebLockGuard(const AsyncWebLock &l) { - if (l.lock()) { - _lock = &l; - } else { - _lock = NULL; - } - } - - ~AsyncWebLockGuard() { - if (_lock) { - _lock->unlock(); - } - } - - void unlock() { - if (_lock) { - _lock->unlock(); - _lock = NULL; - } - } -}; - -#endif // ASYNCWEBSYNCHRONIZATION_H_ From a1627af702af573e4d791756044be0a4f5749a26 Mon Sep 17 00:00:00 2001 From: Emil Muratov Date: Wed, 26 Jun 2024 17:55:58 +0900 Subject: [PATCH 248/551] AsyncEventSourceClient - replace _messageQueue with std::list replace container with an std::list of unique pointers --- src/AsyncEventSource.cpp | 25 ++++++++++--------------- src/AsyncEventSource.h | 7 ++++--- 2 files changed, 14 insertions(+), 18 deletions(-) diff --git a/src/AsyncEventSource.cpp b/src/AsyncEventSource.cpp index 69371c60c..0efdbd52b 100644 --- a/src/AsyncEventSource.cpp +++ b/src/AsyncEventSource.cpp @@ -156,7 +156,6 @@ size_t AsyncEventSourceMessage::send(AsyncClient *client) { // Client AsyncEventSourceClient::AsyncEventSourceClient(AsyncWebServerRequest *request, AsyncEventSource *server) -: _messageQueue(LinkedList([](AsyncEventSourceMessage *m){ delete m; })) { _client = request->client(); _server = server; @@ -180,7 +179,7 @@ AsyncEventSourceClient::~AsyncEventSourceClient(){ #ifdef ESP32 std::lock_guard lock(_lockmq); #endif - _messageQueue.free(); + _messageQueue.clear(); close(); } @@ -195,7 +194,7 @@ void AsyncEventSourceClient::_queueMessage(AsyncEventSourceMessage *dataMessage) //length() is not thread-safe, thus acquiring the lock before this call.. std::lock_guard lock(_lockmq); #endif - if(_messageQueue.length() >= SSE_MAX_QUEUED_MESSAGES){ + if(_messageQueue.size() >= SSE_MAX_QUEUED_MESSAGES){ #ifdef ESP8266 ets_printf(String(F("ERROR: Too many messages queued\n")).c_str()); #else @@ -203,7 +202,7 @@ void AsyncEventSourceClient::_queueMessage(AsyncEventSourceMessage *dataMessage) #endif delete dataMessage; } else { - _messageQueue.add(dataMessage); + _messageQueue.emplace_back(dataMessage); // runqueue trigger when new messages added if(_client->canSend()) { _runQueue(); @@ -216,10 +215,10 @@ void AsyncEventSourceClient::_onAck(size_t len, uint32_t time){ // Same here, acquiring the lock early std::lock_guard lock(_lockmq); #endif - while(len && !_messageQueue.isEmpty()){ + while(len && _messageQueue.size()){ len = _messageQueue.front()->ack(len, time); if(_messageQueue.front()->finished()) - _messageQueue.remove(_messageQueue.front()); + _messageQueue.pop_front(); } _runQueue(); } @@ -229,7 +228,7 @@ void AsyncEventSourceClient::_onPoll(){ // Same here, acquiring the lock early std::lock_guard lock(_lockmq); #endif - if(!_messageQueue.isEmpty()){ + if(_messageQueue.size()){ _runQueue(); } } @@ -261,19 +260,15 @@ size_t AsyncEventSourceClient::packetsWaiting() const { #ifdef ESP32 std::lock_guard lock(_lockmq); #endif - size_t len = _messageQueue.length(); - return len; + return _messageQueue.size(); } void AsyncEventSourceClient::_runQueue() { // Calls to this private method now already protected by _lockmq acquisition // so no extra call of _lockmq.lock() here.. - for (auto i = _messageQueue.begin(); i != _messageQueue.end(); ++i) { - // If it crashes here, iterator (i) has been invalidated as _messageQueue - // has been changed... (UL 2020-11-15: Not supposed to happen any more ;-) ) - if (!(*i)->sent()) { - (*i)->send(_client); - } + for ( auto &i : _messageQueue){ + if (!i->sent()) + i->send(_client); } } diff --git a/src/AsyncEventSource.h b/src/AsyncEventSource.h index 6d76b2f50..79ccc26ed 100644 --- a/src/AsyncEventSource.h +++ b/src/AsyncEventSource.h @@ -21,6 +21,7 @@ #define ASYNCEVENTSOURCE_H_ #include +#include #ifdef ESP32 #include #include @@ -54,8 +55,8 @@ class AsyncEventSource; class AsyncEventSourceResponse; class AsyncEventSourceClient; -typedef std::function ArEventHandlerFunction; -typedef std::function ArAuthorizeConnectHandler; +using ArEventHandlerFunction = std::function; +using ArAuthorizeConnectHandler = std::function; class AsyncEventSourceMessage { private: @@ -78,7 +79,7 @@ class AsyncEventSourceClient { AsyncClient *_client; AsyncEventSource *_server; uint32_t _lastId; - LinkedList _messageQueue; + std::list< std::unique_ptr > _messageQueue; // ArFi 2020-08-27 for protecting/serializing _messageQueue #ifdef ESP32 mutable std::mutex _lockmq; From bb4eb89c8e028005ef84f875417d32ca095147e7 Mon Sep 17 00:00:00 2001 From: Emil Muratov Date: Wed, 26 Jun 2024 18:26:02 +0900 Subject: [PATCH 249/551] AsyncEventSource - replace _clients with std::list use a list of unique_ptrs for _clients container --- src/AsyncEventSource.cpp | 46 ++++++++++++---------------------------- src/AsyncEventSource.h | 8 +++---- 2 files changed, 18 insertions(+), 36 deletions(-) diff --git a/src/AsyncEventSource.cpp b/src/AsyncEventSource.cpp index 0efdbd52b..77589bb9b 100644 --- a/src/AsyncEventSource.cpp +++ b/src/AsyncEventSource.cpp @@ -274,17 +274,6 @@ void AsyncEventSourceClient::_runQueue() { // Handler - -AsyncEventSource::AsyncEventSource(const String& url) - : _url(url) - , _clients(LinkedList([](AsyncEventSourceClient *c){ delete c; })) - , _connectcb(NULL) -{} - -AsyncEventSource::~AsyncEventSource(){ - close(); -} - void AsyncEventSource::onConnect(ArEventHandlerFunction cb){ _connectcb = cb; } @@ -294,22 +283,12 @@ void AsyncEventSource::authorizeConnect(ArAuthorizeConnectHandler cb){ } void AsyncEventSource::_addClient(AsyncEventSourceClient * client){ - /*char * temp = (char *)malloc(2054); - if(temp != NULL){ - memset(temp+1,' ',2048); - temp[0] = ':'; - temp[2049] = '\r'; - temp[2050] = '\n'; - temp[2051] = '\r'; - temp[2052] = '\n'; - temp[2053] = 0; - client->write((const char *)temp, 2053); - free(temp); - }*/ + if (!client) + return; #ifdef ESP32 std::lock_guard lock(_client_queue_lock); #endif - _clients.add(client); + _clients.emplace_back(client); if(_connectcb) _connectcb(client); } @@ -318,7 +297,10 @@ void AsyncEventSource::_handleDisconnect(AsyncEventSourceClient * client){ #ifdef ESP32 std::lock_guard lock(_client_queue_lock); #endif - _clients.remove(client); + for (auto i = _clients.begin(); i != _clients.end(); ++i){ + if (i->get() == client) + _clients.erase(i); + } } void AsyncEventSource::close(){ @@ -341,9 +323,8 @@ size_t AsyncEventSource::avgPacketsWaiting() const { #ifdef ESP32 std::lock_guard lock(_client_queue_lock); #endif - if (_clients.isEmpty()) { - return 0; - } + if (!_clients.size()) return 0; + for(const auto &c: _clients){ if(c->connected()) { aql += c->packetsWaiting(); @@ -367,13 +348,14 @@ void AsyncEventSource::send( } size_t AsyncEventSource::count() const { - size_t n_clients; #ifdef ESP32 std::lock_guard lock(_client_queue_lock); #endif - n_clients = _clients.count_if([](AsyncEventSourceClient *c){ - return c->connected(); - }); + size_t n_clients{0}; + for (const auto &i : _clients) + if (i->connected()) + ++n_clients; + return n_clients; } diff --git a/src/AsyncEventSource.h b/src/AsyncEventSource.h index 79ccc26ed..351e92c3b 100644 --- a/src/AsyncEventSource.h +++ b/src/AsyncEventSource.h @@ -110,17 +110,17 @@ class AsyncEventSourceClient { class AsyncEventSource: public AsyncWebHandler { private: String _url; - LinkedList _clients; + std::list< std::unique_ptr > _clients; #ifdef ESP32 // Same as for individual messages, protect mutations of _clients list // since simultaneous access from different tasks is possible mutable std::mutex _client_queue_lock; #endif - ArEventHandlerFunction _connectcb; + ArEventHandlerFunction _connectcb{nullptr}; ArAuthorizeConnectHandler _authorizeConnectHandler; public: - AsyncEventSource(const String& url); - ~AsyncEventSource(); + AsyncEventSource(const String& url) : _url(url){}; + ~AsyncEventSource(){ close(); }; const char * url() const { return _url.c_str(); } void close(); From 48968b5be5ffc7dd0b763752e8e7255fbc6c2871 Mon Sep 17 00:00:00 2001 From: Emil Muratov Date: Wed, 26 Jun 2024 21:01:52 +0900 Subject: [PATCH 250/551] refactor AsyncEventSourceMessage --- src/AsyncEventSource.cpp | 37 +++++++++++++++++-------------------- src/AsyncEventSource.h | 5 ++--- 2 files changed, 19 insertions(+), 23 deletions(-) diff --git a/src/AsyncEventSource.cpp b/src/AsyncEventSource.cpp index 77589bb9b..90faa3ff5 100644 --- a/src/AsyncEventSource.cpp +++ b/src/AsyncEventSource.cpp @@ -183,30 +183,25 @@ AsyncEventSourceClient::~AsyncEventSourceClient(){ close(); } -void AsyncEventSourceClient::_queueMessage(AsyncEventSourceMessage *dataMessage){ - if(dataMessage == NULL) - return; - if(!connected()){ - delete dataMessage; - return; - } +void AsyncEventSourceClient::_queueMessage(const char * message, size_t len){ #ifdef ESP32 //length() is not thread-safe, thus acquiring the lock before this call.. std::lock_guard lock(_lockmq); #endif + if(_messageQueue.size() >= SSE_MAX_QUEUED_MESSAGES){ #ifdef ESP8266 ets_printf(String(F("ERROR: Too many messages queued\n")).c_str()); #else log_e("Too many messages queued: deleting message"); #endif - delete dataMessage; - } else { - _messageQueue.emplace_back(dataMessage); - // runqueue trigger when new messages added - if(_client->canSend()) { - _runQueue(); - } + return; + } + + _messageQueue.emplace_back(message, len); + // runqueue trigger when new messages added + if(_client->canSend()) { + _runQueue(); } } @@ -216,8 +211,8 @@ void AsyncEventSourceClient::_onAck(size_t len, uint32_t time){ std::lock_guard lock(_lockmq); #endif while(len && _messageQueue.size()){ - len = _messageQueue.front()->ack(len, time); - if(_messageQueue.front()->finished()) + len = _messageQueue.front().ack(len, time); + if(_messageQueue.front().finished()) _messageQueue.pop_front(); } _runQueue(); @@ -248,12 +243,14 @@ void AsyncEventSourceClient::close(){ } void AsyncEventSourceClient::write(const char * message, size_t len){ - _queueMessage(new AsyncEventSourceMessage(message, len)); + if(!connected()) return; + _queueMessage(message, len); } void AsyncEventSourceClient::send(const char *message, const char *event, uint32_t id, uint32_t reconnect){ + if(!connected()) return; String ev = generateEventMessage(message, event, id, reconnect); - _queueMessage(new AsyncEventSourceMessage(ev.c_str(), ev.length())); + _queueMessage(ev.c_str(), ev.length()); } size_t AsyncEventSourceClient::packetsWaiting() const { @@ -267,8 +264,8 @@ void AsyncEventSourceClient::_runQueue() { // Calls to this private method now already protected by _lockmq acquisition // so no extra call of _lockmq.lock() here.. for ( auto &i : _messageQueue){ - if (!i->sent()) - i->send(_client); + if (!i.sent()) + i.send(_client); } } diff --git a/src/AsyncEventSource.h b/src/AsyncEventSource.h index 351e92c3b..6ce3e5729 100644 --- a/src/AsyncEventSource.h +++ b/src/AsyncEventSource.h @@ -79,12 +79,11 @@ class AsyncEventSourceClient { AsyncClient *_client; AsyncEventSource *_server; uint32_t _lastId; - std::list< std::unique_ptr > _messageQueue; - // ArFi 2020-08-27 for protecting/serializing _messageQueue + std::list< AsyncEventSourceMessage > _messageQueue; #ifdef ESP32 mutable std::mutex _lockmq; #endif - void _queueMessage(AsyncEventSourceMessage *dataMessage); + void _queueMessage(const char * message, size_t len); void _runQueue(); public: From aefc4a0f4eb1f6ee98a7bd8e23cedae08c12c939 Mon Sep 17 00:00:00 2001 From: Emil Muratov Date: Wed, 26 Jun 2024 21:17:44 +0900 Subject: [PATCH 251/551] repalce container for AsyncWebServerRequest::_params with std::list --- src/ESPAsyncWebServer.h | 4 ++-- src/WebRequest.cpp | 46 ++++++++++++++++++++--------------------- 2 files changed, 24 insertions(+), 26 deletions(-) diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index 1bec17384..a7c6da14d 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -188,7 +188,7 @@ class AsyncWebServerRequest { size_t _parsedLength; std::list _headers; - LinkedList _params; + std::list _params; std::vector _pathParams; uint8_t _multiParseState; @@ -210,7 +210,7 @@ class AsyncWebServerRequest { void _onDisconnect(); void _onData(void *buf, size_t len); - void _addParam(AsyncWebParameter*); + //void _addParam(AsyncWebParameter*); void _addPathParam(const char *param); bool _parseReqHead(); diff --git a/src/WebRequest.cpp b/src/WebRequest.cpp index 31613dfda..2cef4af2a 100644 --- a/src/WebRequest.cpp +++ b/src/WebRequest.cpp @@ -51,7 +51,6 @@ AsyncWebServerRequest::AsyncWebServerRequest(AsyncWebServer* s, AsyncClient* c) , _expectingContinue(false) , _contentLength(0) , _parsedLength(0) - , _params(LinkedList([](AsyncWebParameter *p){ delete p; })) , _multiParseState(0) , _boundaryPosition(0) , _itemStartIndex(0) @@ -76,7 +75,6 @@ AsyncWebServerRequest::AsyncWebServerRequest(AsyncWebServer* s, AsyncClient* c) AsyncWebServerRequest::~AsyncWebServerRequest(){ _headers.clear(); - _params.free(); _pathParams.clear(); _interestingHeaders.clear(); @@ -248,10 +246,6 @@ void AsyncWebServerRequest::_onDisconnect(){ _server->_handleDisconnect(this); } -void AsyncWebServerRequest::_addParam(AsyncWebParameter *p){ - _params.add(p); -} - void AsyncWebServerRequest::_addPathParam(const char *p){ _pathParams.emplace_back(p); } @@ -263,9 +257,9 @@ void AsyncWebServerRequest::_addGetParams(const String& params){ if (end < 0) end = params.length(); int equal = params.indexOf('=', start); if (equal < 0 || equal > end) equal = end; - String name = params.substring(start, equal); - String value = equal + 1 < end ? params.substring(equal + 1, end) : String(); - _addParam(new AsyncWebParameter(urlDecode(name), urlDecode(value))); + String name( params.substring(start, equal) ); + String value( equal + 1 < end ? params.substring(equal + 1, end) : String() ); + _params.emplace_back(urlDecode(name), urlDecode(value)); start = end + 1; } } @@ -383,7 +377,7 @@ void AsyncWebServerRequest::_parsePlainPostChar(uint8_t data){ name = _temp.substring(0, _temp.indexOf('=')); value = _temp.substring(_temp.indexOf('=') + 1); } - _addParam(new AsyncWebParameter(urlDecode(name), urlDecode(value), true)); + _params.emplace_back(urlDecode(name), urlDecode(value), true); _temp = String(); } } @@ -530,13 +524,13 @@ void AsyncWebServerRequest::_parseMultipartPostByte(uint8_t data, bool last){ } else if(_boundaryPosition == _boundary.length() - 1){ _multiParseState = DASH3_OR_RETURN2; if(!_itemIsFile){ - _addParam(new AsyncWebParameter(_itemName, _itemValue, true)); + _params.emplace_back(_itemName, _itemValue, true); } else { if(_itemSize){ //check if authenticated before calling the upload if(_handler) _handler->handleUpload(this, _itemFilename, _itemSize - _itemBufferIndex, _itemBuffer, _itemBufferIndex, true); _itemBufferIndex = 0; - _addParam(new AsyncWebParameter(_itemName, _itemFilename, true, true, _itemSize)); + _params.emplace_back(_itemName, _itemFilename, true, true, _itemSize); } free(_itemBuffer); _itemBuffer = NULL; @@ -685,12 +679,12 @@ const AsyncWebHeader* AsyncWebServerRequest::getHeader(size_t num) const { } size_t AsyncWebServerRequest::params() const { - return _params.length(); + return _params.size(); } bool AsyncWebServerRequest::hasParam(const String& name, bool post, bool file) const { for(const auto& p: _params){ - if(p->name() == name && p->isPost() == post && p->isFile() == file){ + if(p.name() == name && p.isPost() == post && p.isFile() == file){ return true; } } @@ -701,22 +695,26 @@ bool AsyncWebServerRequest::hasParam(const __FlashStringHelper * data, bool post return hasParam(String(data).c_str(), post, file); } -AsyncWebParameter* AsyncWebServerRequest::getParam(const String& name, bool post, bool file) const { - for(const auto& p: _params){ - if(p->name() == name && p->isPost() == post && p->isFile() == file){ - return p; +const AsyncWebParameter* AsyncWebServerRequest::getParam(const String& name, bool post, bool file) const { + for(const auto &p: _params){ + if(p.name() == name && p.isPost() == post && p.isFile() == file){ + return &p; } } return nullptr; } +#ifdef ESP8266 AsyncWebParameter* AsyncWebServerRequest::getParam(const __FlashStringHelper * data, bool post, bool file) const { return getParam(String(data).c_str(), post, file); } +#endif -AsyncWebParameter* AsyncWebServerRequest::getParam(size_t num) const { - auto param = _params.nth(num); - return param ? *param : nullptr; +const AsyncWebParameter* AsyncWebServerRequest::getParam(size_t num) const { + if (num >= _params.size()) return nullptr; + auto iter = _params.cbegin(); + std::advance(iter, num); + return &(*iter); } void AsyncWebServerRequest::addInterestingHeader(const String& name){ @@ -880,7 +878,7 @@ void AsyncWebServerRequest::requestAuthentication(const char * realm, bool isDig bool AsyncWebServerRequest::hasArg(const char* name) const { for(const auto& arg: _params){ - if(arg->name() == name){ + if(arg.name() == name){ return true; } } @@ -894,8 +892,8 @@ bool AsyncWebServerRequest::hasArg(const __FlashStringHelper * data) const { const String& AsyncWebServerRequest::arg(const String& name) const { for(const auto& arg: _params){ - if(arg->name() == name){ - return arg->value(); + if(arg.name() == name){ + return arg.value(); } } return emptyString; From d5c2af8dc267ffd4e230cfa7cd7f5fc59d604b5d Mon Sep 17 00:00:00 2001 From: Emil Muratov Date: Wed, 26 Jun 2024 22:27:08 +0900 Subject: [PATCH 252/551] AsyncWebServerRequest::_params replace with STL container - LinkedList _rewrites; + std::list > _rewrites; --- src/ESPAsyncWebServer.h | 55 +++++++++++++++++++++++++++++++++++------ src/WebRequest.cpp | 4 +-- src/WebServer.cpp | 28 ++++++++++++++++----- 3 files changed, 71 insertions(+), 16 deletions(-) diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index a7c6da14d..4ecdee8eb 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -292,9 +292,11 @@ class AsyncWebServerRequest { bool hasParam(const String& name, bool post=false, bool file=false) const; bool hasParam(const __FlashStringHelper * data, bool post=false, bool file=false) const; - AsyncWebParameter* getParam(const String& name, bool post=false, bool file=false) const; - AsyncWebParameter* getParam(const __FlashStringHelper * data, bool post, bool file) const; - AsyncWebParameter* getParam(size_t num) const; + const AsyncWebParameter* getParam(const String& name, bool post=false, bool file=false) const; +#ifdef ESP8266 + const AsyncWebParameter* getParam(const __FlashStringHelper * data, bool post, bool file) const; +#endif + const AsyncWebParameter* getParam(size_t num) const; size_t args() const { return params(); } // get arguments count const String& arg(const String& name) const; // get request argument value by name @@ -317,7 +319,7 @@ class AsyncWebServerRequest { * FILTER :: Callback to filter AsyncWebRewrite and AsyncWebHandler (done by the Server) * */ -typedef std::function ArRequestFilterFunction; +using ArRequestFilterFunction = std::function; bool ON_STA_FILTER(AsyncWebServerRequest *request); @@ -332,9 +334,9 @@ class AsyncWebRewrite { String _from; String _toUrl; String _params; - ArRequestFilterFunction _filter; + ArRequestFilterFunction _filter{nullptr}; public: - AsyncWebRewrite(const char* from, const char* to): _from(from), _toUrl(to), _params(String()), _filter(NULL){ + AsyncWebRewrite(const char* from, const char* to) : _from(from), _toUrl(to){ int index = _toUrl.indexOf('?'); if (index > 0) { _params = _toUrl.substring(index +1); @@ -427,7 +429,7 @@ typedef std::function _rewrites; + std::list > _rewrites; LinkedList _handlers; AsyncCallbackWebHandler* _catchAllHandler; @@ -444,9 +446,46 @@ class AsyncWebServer { #endif AsyncWebRewrite& addRewrite(AsyncWebRewrite* rewrite); - bool removeRewrite(AsyncWebRewrite* rewrite); + + /** + * @brief (compat) Add url rewrite rule by pointer + * a deep copy of the pounter object will be created, + * it is up to user to manage further lifetime of the object in argument + * + * @param rewrite pointer to rewrite object to copy setting from + * @return AsyncWebRewrite& reference to a newly created rewrite rule + */ + AsyncWebRewrite& addRewrite(std::shared_ptr rewrite); + + /** + * @brief add url rewrite rule + * + * @param from + * @param to + * @return AsyncWebRewrite& + */ AsyncWebRewrite& rewrite(const char* from, const char* to); + /** + * @brief (compat) remove rewrite rule via referenced object + * this will NOT deallocate pointed object itself, internal rule with same from/to urls will be removed if any + * it's a compat method, better use `removeRewrite(const char* from, const char* to)` + * @param rewrite + * @return true + * @return false + */ + bool removeRewrite(AsyncWebRewrite* rewrite); + + /** + * @brief remove rewrite rule + * + * @param from + * @param to + * @return true + * @return false + */ + bool removeRewrite(const char* from, const char* to); + AsyncWebHandler& addHandler(AsyncWebHandler* handler); bool removeHandler(AsyncWebHandler* handler); diff --git a/src/WebRequest.cpp b/src/WebRequest.cpp index 2cef4af2a..39d0f9522 100644 --- a/src/WebRequest.cpp +++ b/src/WebRequest.cpp @@ -705,8 +705,8 @@ const AsyncWebParameter* AsyncWebServerRequest::getParam(const String& name, boo } #ifdef ESP8266 -AsyncWebParameter* AsyncWebServerRequest::getParam(const __FlashStringHelper * data, bool post, bool file) const { - return getParam(String(data).c_str(), post, file); +const AsyncWebParameter* AsyncWebServerRequest::getParam(const __FlashStringHelper * data, bool post, bool file) const { + return getParam(String(data), post, file); } #endif diff --git a/src/WebServer.cpp b/src/WebServer.cpp index 62e85b23a..734e70f7e 100644 --- a/src/WebServer.cpp +++ b/src/WebServer.cpp @@ -37,7 +37,6 @@ const char *fs::FileOpenMode::append = "a"; AsyncWebServer::AsyncWebServer(uint16_t port) : _server(port) - , _rewrites(LinkedList([](AsyncWebRewrite* r){ delete r; })) , _handlers(LinkedList([](AsyncWebHandler* h){ delete h; })) { _catchAllHandler = new AsyncCallbackWebHandler(); @@ -62,17 +61,34 @@ AsyncWebServer::~AsyncWebServer(){ if(_catchAllHandler) delete _catchAllHandler; } +AsyncWebRewrite& AsyncWebServer::addRewrite(std::shared_ptr rewrite){ + _rewrites.emplace_back(rewrite); + return *_rewrites.back().get(); +} + + AsyncWebRewrite& AsyncWebServer::addRewrite(AsyncWebRewrite* rewrite){ - _rewrites.add(rewrite); - return *rewrite; + _rewrites.emplace_back(rewrite); + return *_rewrites.back().get(); } bool AsyncWebServer::removeRewrite(AsyncWebRewrite *rewrite){ - return _rewrites.remove(rewrite); + return removeRewrite(rewrite->from().c_str(), rewrite->toUrl().c_str()); +} + +bool AsyncWebServer::removeRewrite(const char* from, const char* to){ + for(auto r = _rewrites.begin(); r != _rewrites.end(); ++r ){ + if (r->get()->from() == from && r->get()->toUrl() == to){ + _rewrites.erase(r); + return true; + } + } + return false; } AsyncWebRewrite& AsyncWebServer::rewrite(const char* from, const char* to){ - return addRewrite(new AsyncWebRewrite(from, to)); + _rewrites.emplace_back(std::make_shared(from, to)); + return *_rewrites.back().get(); } AsyncWebHandler& AsyncWebServer::addHandler(AsyncWebHandler* handler){ @@ -186,7 +202,7 @@ void AsyncWebServer::onRequestBody(ArBodyHandlerFunction fn){ } void AsyncWebServer::reset(){ - _rewrites.free(); + _rewrites.clear(); _handlers.free(); if (_catchAllHandler != NULL){ From 9bd3cd9472f1b184fa6ee73e1ba6590a434768b6 Mon Sep 17 00:00:00 2001 From: Emil Muratov Date: Wed, 26 Jun 2024 22:46:24 +0900 Subject: [PATCH 253/551] AsyncWebServer::_handlers repalce with STL container repalce LinkedList with std::list > _handlers; --- src/ESPAsyncWebServer.h | 6 +++--- src/WebServer.cpp | 19 ++++++++++++------- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index 4ecdee8eb..41e5d6c95 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -358,11 +358,11 @@ class AsyncWebRewrite { class AsyncWebHandler { protected: - ArRequestFilterFunction _filter; + ArRequestFilterFunction _filter{nullptr}; String _username; String _password; public: - AsyncWebHandler():_username(""), _password(""){} + AsyncWebHandler(){} AsyncWebHandler& setFilter(ArRequestFilterFunction fn) { _filter = fn; return *this; } AsyncWebHandler& setAuthentication(const char *username, const char *password){ _username = String(username);_password = String(password); return *this; }; AsyncWebHandler& setAuthentication(const String& username, const String& password){ _username = username;_password = password; return *this; }; @@ -430,7 +430,7 @@ class AsyncWebServer { protected: AsyncServer _server; std::list > _rewrites; - LinkedList _handlers; + std::list > _handlers; AsyncCallbackWebHandler* _catchAllHandler; public: diff --git a/src/WebServer.cpp b/src/WebServer.cpp index 734e70f7e..ebd464a90 100644 --- a/src/WebServer.cpp +++ b/src/WebServer.cpp @@ -37,7 +37,6 @@ const char *fs::FileOpenMode::append = "a"; AsyncWebServer::AsyncWebServer(uint16_t port) : _server(port) - , _handlers(LinkedList([](AsyncWebHandler* h){ delete h; })) { _catchAllHandler = new AsyncCallbackWebHandler(); if(_catchAllHandler == NULL) @@ -92,12 +91,18 @@ AsyncWebRewrite& AsyncWebServer::rewrite(const char* from, const char* to){ } AsyncWebHandler& AsyncWebServer::addHandler(AsyncWebHandler* handler){ - _handlers.add(handler); - return *handler; + _handlers.emplace_back(handler); + return *(_handlers.back().get()); } bool AsyncWebServer::removeHandler(AsyncWebHandler *handler){ - return _handlers.remove(handler); + for (auto i = _handlers.begin(); i != _handlers.end(); ++i){ + if (i->get() == handler ){ + _handlers.erase(i); + return true; + } + } + return false; } void AsyncWebServer::begin(){ @@ -133,9 +138,9 @@ void AsyncWebServer::_rewriteRequest(AsyncWebServerRequest *request){ } void AsyncWebServer::_attachHandler(AsyncWebServerRequest *request){ - for(const auto& h: _handlers){ + for(auto& h: _handlers){ if (h->filter(request) && h->canHandle(request)){ - request->setHandler(h); + request->setHandler(h.get()); return; } } @@ -203,7 +208,7 @@ void AsyncWebServer::onRequestBody(ArBodyHandlerFunction fn){ void AsyncWebServer::reset(){ _rewrites.clear(); - _handlers.free(); + _handlers.clear(); if (_catchAllHandler != NULL){ _catchAllHandler->onRequest(NULL); From 9e93f03525c79a00ed8907a844905053adf1c92a Mon Sep 17 00:00:00 2001 From: Emil Muratov Date: Wed, 26 Jun 2024 23:12:34 +0900 Subject: [PATCH 254/551] remove obsolete StringArray.h --- src/ESPAsyncWebServer.h | 2 - src/StringArray.h | 174 ---------------------------------------- 2 files changed, 176 deletions(-) delete mode 100644 src/StringArray.h diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index 41e5d6c95..2b11be568 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -28,8 +28,6 @@ #include #include "FS.h" -#include "StringArray.h" - #ifdef ESP32 #include #include diff --git a/src/StringArray.h b/src/StringArray.h deleted file mode 100644 index d5096e699..000000000 --- a/src/StringArray.h +++ /dev/null @@ -1,174 +0,0 @@ -/* - Asynchronous WebServer library for Espressif MCUs - - Copyright (c) 2016 Hristo Gochkov. All rights reserved. - This file is part of the esp8266 core for Arduino environment. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ -#ifndef STRINGARRAY_H_ -#define STRINGARRAY_H_ - -#include "stddef.h" -#include "WString.h" - -template -class LinkedListNode { - T _value; - public: - LinkedListNode* next; - LinkedListNode(const T val): _value(val), next(nullptr) {} - ~LinkedListNode(){} - const T& value() const { return _value; }; - T& value(){ return _value; } -}; - -template class Item = LinkedListNode> -class LinkedList { - public: - typedef Item ItemType; - typedef std::function OnRemove; - typedef std::function Predicate; - private: - ItemType* _root; - OnRemove _onRemove; - - class Iterator { - ItemType* _node; - public: - Iterator(ItemType* current = nullptr) : _node(current) {} - Iterator(const Iterator& i) : _node(i._node) {} - Iterator& operator ++() { _node = _node->next; return *this; } - bool operator != (const Iterator& i) const { return _node != i._node; } - const T& operator * () const { return _node->value(); } - const T* operator -> () const { return &_node->value(); } - }; - - public: - typedef const Iterator ConstIterator; - ConstIterator begin() const { return ConstIterator(_root); } - ConstIterator end() const { return ConstIterator(nullptr); } - - LinkedList(OnRemove onRemove) : _root(nullptr), _onRemove(onRemove) {} - ~LinkedList(){} - void add(const T& t){ - auto it = new ItemType(t); - if(!_root){ - _root = it; - } else { - auto i = _root; - while(i->next) i = i->next; - i->next = it; - } - } - T& front() const { - return _root->value(); - } - - bool isEmpty() const { - return _root == nullptr; - } - size_t length() const { - size_t i = 0; - auto it = _root; - while(it){ - i++; - it = it->next; - } - return i; - } - size_t count_if(Predicate predicate) const { - size_t i = 0; - auto it = _root; - while(it){ - if (!predicate){ - i++; - } - else if (predicate(it->value())) { - i++; - } - it = it->next; - } - return i; - } - const T* nth(size_t N) const { - size_t i = 0; - auto it = _root; - while(it){ - if(i++ == N) - return &(it->value()); - it = it->next; - } - return nullptr; - } - bool remove(const T& t){ - auto it = _root; - auto pit = _root; - while(it){ - if(it->value() == t){ - if(it == _root){ - _root = _root->next; - } else { - pit->next = it->next; - } - - if (_onRemove) { - _onRemove(it->value()); - } - - delete it; - return true; - } - pit = it; - it = it->next; - } - return false; - } - bool remove_first(Predicate predicate){ - auto it = _root; - auto pit = _root; - while(it){ - if(predicate(it->value())){ - if(it == _root){ - _root = _root->next; - } else { - pit->next = it->next; - } - if (_onRemove) { - _onRemove(it->value()); - } - delete it; - return true; - } - pit = it; - it = it->next; - } - return false; - } - - void free(){ - while(_root != nullptr){ - auto it = _root; - _root = _root->next; - if (_onRemove) { - _onRemove(it->value()); - } - delete it; - } - _root = nullptr; - } -}; - -#endif /* STRINGARRAY_H_ */ From c79f2d05f0567adc08ca7d80a7ee669a45155e13 Mon Sep 17 00:00:00 2001 From: Emil Muratov Date: Fri, 28 Jun 2024 00:45:05 +0900 Subject: [PATCH 255/551] refactor WebServer methods and const specifiers for immutable returns make &String arg overloads over const char* + some minor cleanups --- src/AsyncWebSocket.cpp | 8 +-- src/AsyncWebSocket.h | 3 +- src/ESPAsyncWebServer.h | 87 +++++++++++++++++++---- src/WebAuthentication.cpp | 31 +++++---- src/WebAuthentication.h | 5 ++ src/WebRequest.cpp | 140 ++++++++++++++++++++------------------ 6 files changed, 175 insertions(+), 99 deletions(-) diff --git a/src/AsyncWebSocket.cpp b/src/AsyncWebSocket.cpp index 926d6a41a..b59c39221 100644 --- a/src/AsyncWebSocket.cpp +++ b/src/AsyncWebSocket.cpp @@ -1145,7 +1145,6 @@ size_t AsyncWebSocket::printf_P(uint32_t id, PGM_P formatP, ...){ } return 0; } -#endif size_t AsyncWebSocket::printfAll_P(PGM_P formatP, ...) { @@ -1168,6 +1167,7 @@ size_t AsyncWebSocket::printfAll_P(PGM_P formatP, ...) textAll(buffer); return len; } +#endif const char __WS_STR_CONNECTION[] PROGMEM = { "Connection" }; const char __WS_STR_UPGRADE[] PROGMEM = { "Upgrade" }; @@ -1225,7 +1225,7 @@ void AsyncWebSocket::handleRequest(AsyncWebServerRequest *request) return; } } - AsyncWebHeader* version = request->getHeader(WS_STR_VERSION); + const AsyncWebHeader* version = request->getHeader(WS_STR_VERSION); if (version->value().toInt() != 13) { AsyncWebServerResponse *response = request->beginResponse(400); @@ -1233,11 +1233,11 @@ void AsyncWebSocket::handleRequest(AsyncWebServerRequest *request) request->send(response); return; } - AsyncWebHeader* key = request->getHeader(WS_STR_KEY); + const AsyncWebHeader* key = request->getHeader(WS_STR_KEY); AsyncWebServerResponse *response = new AsyncWebSocketResponse(key->value(), this); if (request->hasHeader(WS_STR_PROTOCOL)) { - AsyncWebHeader* protocol = request->getHeader(WS_STR_PROTOCOL); + const AsyncWebHeader* protocol = request->getHeader(WS_STR_PROTOCOL); //ToDo: check protocol response->addHeader(WS_STR_PROTOCOL, protocol->value()); } diff --git a/src/AsyncWebSocket.h b/src/AsyncWebSocket.h index a40fc85ca..8b7eca9f6 100644 --- a/src/AsyncWebSocket.h +++ b/src/AsyncWebSocket.h @@ -327,10 +327,11 @@ class AsyncWebSocket: public AsyncWebHandler { size_t printf(uint32_t id, const char *format, ...) __attribute__ ((format (printf, 3, 4))); size_t printfAll(const char *format, ...) __attribute__ ((format (printf, 2, 3))); + #ifndef ESP32 size_t printf_P(uint32_t id, PGM_P formatP, ...) __attribute__ ((format (printf, 3, 4))); -#endif size_t printfAll_P(PGM_P formatP, ...) __attribute__ ((format (printf, 2, 3))); +#endif //event listener void onEvent(AwsEventHandler handler){ diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index 2b11be568..45085219f 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -129,7 +129,7 @@ class AsyncWebHeader { AsyncWebHeader(const AsyncWebHeader &) = default; AsyncWebHeader(const String& name, const String& value): _name(name), _value(value){} - AsyncWebHeader(const String& data): _name(), _value(){ + AsyncWebHeader(const String& data){ if(!data) return; int index = data.indexOf(':'); if (index < 0) return; @@ -237,8 +237,15 @@ class AsyncWebServerRequest { const String& contentType() const { return _contentType; } size_t contentLength() const { return _contentLength; } bool multipart() const { return _isMultipart; } + +#ifndef ESP8266 + const char* methodToString() const; + const char* requestedConnTypeToString() const; +#else const __FlashStringHelper *methodToString() const; const __FlashStringHelper *requestedConnTypeToString() const; +#endif + RequestedConnectionType requestedConnType() const { return _reqconntype; } bool isExpectedRequestedConnType(RequestedConnectionType erct1, RequestedConnectionType erct2 = RCT_NOT_USED, RequestedConnectionType erct3 = RCT_NOT_USED); void onDisconnect (ArDisconnectHandler fn); @@ -251,9 +258,22 @@ class AsyncWebServerRequest { void requestAuthentication(const char * realm = NULL, bool isDigest = true); void setHandler(AsyncWebHandler *handler){ _handler = handler; } - void addInterestingHeader(const String& name); - void redirect(const String& url); + /** + * @brief add header to collect from a response + * + * @param name + */ + void addInterestingHeader(const char* name); + void addInterestingHeader(const String& name){ return addInterestingHeader(name.c_str()); }; + + /** + * @brief issue 302 redirect responce + * + * @param url + */ + void redirect(const char* url); + void redirect(const String& url){ return redirect(url.c_str()); }; void send(AsyncWebServerResponse *response); void send(int code, const String& contentType=String(), const String& content=String()); @@ -262,8 +282,10 @@ class AsyncWebServerRequest { void send(Stream &stream, const String& contentType, size_t len, AwsTemplateProcessor callback=nullptr); void send(const String& contentType, size_t len, AwsResponseFiller callback, AwsTemplateProcessor templateCallback=nullptr); void sendChunked(const String& contentType, AwsResponseFiller callback, AwsTemplateProcessor templateCallback=nullptr); +#ifdef ESP8266 void send_P(int code, const String& contentType, const uint8_t * content, size_t len, AwsTemplateProcessor callback=nullptr); void send_P(int code, const String& contentType, PGM_P content, AwsTemplateProcessor callback=nullptr); +#endif AsyncWebServerResponse *beginResponse(int code, const String& contentType=String(), const String& content=String()); AsyncWebServerResponse *beginResponse(FS &fs, const String& path, const String& contentType=String(), bool download=false, AwsTemplateProcessor callback=nullptr); @@ -272,44 +294,83 @@ class AsyncWebServerRequest { AsyncWebServerResponse *beginResponse(const String& contentType, size_t len, AwsResponseFiller callback, AwsTemplateProcessor templateCallback=nullptr); AsyncWebServerResponse *beginChunkedResponse(const String& contentType, AwsResponseFiller callback, AwsTemplateProcessor templateCallback=nullptr); AsyncResponseStream *beginResponseStream(const String& contentType, size_t bufferSize=1460); +#ifdef ESP8266 AsyncWebServerResponse *beginResponse_P(int code, const String& contentType, const uint8_t * content, size_t len, AwsTemplateProcessor callback=nullptr); AsyncWebServerResponse *beginResponse_P(int code, const String& contentType, PGM_P content, AwsTemplateProcessor callback=nullptr); +#endif size_t headers() const; // get header count - bool hasHeader(const String& name) const; // check if header exists + + // check if header exists + bool hasHeader(const char* name) const; + bool hasHeader(const String& name) const { return hasHeader(name.c_str()); }; +#ifdef ESP8266 bool hasHeader(const __FlashStringHelper * data) const; // check if header exists +#endif - AsyncWebHeader* getHeader(const String& name); - const AsyncWebHeader* getHeader(const String& name) const; - AsyncWebHeader* getHeader(const __FlashStringHelper * data); + const AsyncWebHeader* getHeader(const char* name) const; + const AsyncWebHeader* getHeader(const String& name) const { return getHeader(name.c_str()); }; +#ifdef ESP8266 const AsyncWebHeader* getHeader(const __FlashStringHelper * data) const; - AsyncWebHeader* getHeader(size_t num); +#endif const AsyncWebHeader* getHeader(size_t num) const; size_t params() const; // get arguments count bool hasParam(const String& name, bool post=false, bool file=false) const; bool hasParam(const __FlashStringHelper * data, bool post=false, bool file=false) const; - const AsyncWebParameter* getParam(const String& name, bool post=false, bool file=false) const; + /** + * @brief Get the Request parameter by name + * + * @param name + * @param post + * @param file + * @return const AsyncWebParameter* + */ + const AsyncWebParameter* getParam(const char* name, bool post=false, bool file=false) const; + + const AsyncWebParameter* getParam(const String& name, bool post=false, bool file=false) const { return getParam(name.c_str()); }; #ifdef ESP8266 const AsyncWebParameter* getParam(const __FlashStringHelper * data, bool post, bool file) const; #endif + + /** + * @brief Get request parameter by number + * i.e., n-th parameter + * @param num + * @return const AsyncWebParameter* + */ const AsyncWebParameter* getParam(size_t num) const; size_t args() const { return params(); } // get arguments count - const String& arg(const String& name) const; // get request argument value by name + + // get request argument value by name + const String& arg(const char* name) const; + // get request argument value by name + const String& arg(const String& name) const { return arg(name.c_str()); }; +#ifdef ESP8266 const String& arg(const __FlashStringHelper * data) const; // get request argument value by F(name) +#endif const String& arg(size_t i) const; // get request argument value by number const String& argName(size_t i) const; // get request argument name by number bool hasArg(const char* name) const; // check if argument exists +#ifdef ESP8266 bool hasArg(const __FlashStringHelper * data) const; // check if F(argument) exists +#endif const String& ASYNCWEBSERVER_REGEX_ATTRIBUTE pathArg(size_t i) const; - const String& header(const char* name) const;// get request header value by name + // get request header value by name + const String& header(const char* name) const; + const String& header(const String& name) const { return header(name.c_str()); }; + +#ifdef ESP8266 const String& header(const __FlashStringHelper * data) const;// get request header value by F(name) +#endif + const String& header(size_t i) const; // get request header value by number const String& headerName(size_t i) const; // get request header name by number + String urlDecode(const String& text) const; }; @@ -362,8 +423,8 @@ class AsyncWebHandler { public: AsyncWebHandler(){} AsyncWebHandler& setFilter(ArRequestFilterFunction fn) { _filter = fn; return *this; } - AsyncWebHandler& setAuthentication(const char *username, const char *password){ _username = String(username);_password = String(password); return *this; }; - AsyncWebHandler& setAuthentication(const String& username, const String& password){ _username = username;_password = password; return *this; }; + AsyncWebHandler& setAuthentication(const char *username, const char *password){ _username = username; _password = password; return *this; }; + AsyncWebHandler& setAuthentication(const String& username, const String& password){ _username = username; _password = password; return *this; }; bool filter(AsyncWebServerRequest *request){ return _filter == NULL || _filter(request); } virtual ~AsyncWebHandler(){} virtual bool canHandle(AsyncWebServerRequest *request __attribute__((unused))){ diff --git a/src/WebAuthentication.cpp b/src/WebAuthentication.cpp index 839679580..78c8e4332 100644 --- a/src/WebAuthentication.cpp +++ b/src/WebAuthentication.cpp @@ -147,31 +147,36 @@ String requestDigestAuthentication(const char * realm){ return header; } -bool checkDigestAuthentication(const char * header, const __FlashStringHelper *method, const char * username, const char * password, const char * realm, bool passwordIsHash, const char * nonce, const char * opaque, const char * uri){ +#ifndef ESP8266 +bool checkDigestAuthentication(const char * header, const char* method, const char * username, const char * password, const char * realm, bool passwordIsHash, const char * nonce, const char * opaque, const char * uri) +#else +bool checkDigestAuthentication(const char * header, const __FlashStringHelper *method, const char * username, const char * password, const char * realm, bool passwordIsHash, const char * nonce, const char * opaque, const char * uri) +#endif +{ if(username == NULL || password == NULL || header == NULL || method == NULL){ //os_printf("AUTH FAIL: missing requred fields\n"); return false; } - String myHeader = String(header); + String myHeader(header); int nextBreak = myHeader.indexOf(','); if(nextBreak < 0){ //os_printf("AUTH FAIL: no variables\n"); return false; } - String myUsername = String(); - String myRealm = String(); - String myNonce = String(); - String myUri = String(); - String myResponse = String(); - String myQop = String(); - String myNc = String(); - String myCnonce = String(); + String myUsername; + String myRealm; + String myNonce; + String myUri; + String myResponse; + String myQop; + String myNc; + String myCnonce; myHeader += F(", "); do { - String avLine = myHeader.substring(0, nextBreak); + String avLine(myHeader.substring(0, nextBreak)); avLine.trim(); myHeader = myHeader.substring(nextBreak+1); nextBreak = myHeader.indexOf(','); @@ -181,7 +186,7 @@ bool checkDigestAuthentication(const char * header, const __FlashStringHelper *m //os_printf("AUTH FAIL: no = sign\n"); return false; } - String varName = avLine.substring(0, eqSign); + String varName(avLine.substring(0, eqSign)); avLine = avLine.substring(eqSign + 1); if(avLine.startsWith(String('"'))){ avLine = avLine.substring(1, avLine.length() - 1); @@ -227,7 +232,7 @@ bool checkDigestAuthentication(const char * header, const __FlashStringHelper *m } } while(nextBreak > 0); - String ha1 = (passwordIsHash) ? String(password) : stringMD5(myUsername + ':' + myRealm + ':' + String(password)); + String ha1 = (passwordIsHash) ? String(password) : stringMD5(myUsername + ':' + myRealm + ':' + password); String ha2 = String(method) + ':' + myUri; String response = ha1 + ':' + myNonce + ':' + myNc + ':' + myCnonce + ':' + myQop + ':' + stringMD5(ha2); diff --git a/src/WebAuthentication.h b/src/WebAuthentication.h index a6f1966e3..8bc5f05d7 100644 --- a/src/WebAuthentication.h +++ b/src/WebAuthentication.h @@ -26,7 +26,12 @@ bool checkBasicAuthentication(const char * header, const char * username, const char * password); String requestDigestAuthentication(const char * realm); + +bool checkDigestAuthentication(const char * header, const char* method, const char * username, const char * password, const char * realm, bool passwordIsHash, const char * nonce, const char * opaque, const char * uri); + +#ifdef ESP8266 bool checkDigestAuthentication(const char * header, const __FlashStringHelper *method, const char * username, const char * password, const char * realm, bool passwordIsHash, const char * nonce, const char * opaque, const char * uri); +#endif //for storing hashed versions on the device that can be authenticated against String generateDigestHash(const char * username, const char * password, const char * realm); diff --git a/src/WebRequest.cpp b/src/WebRequest.cpp index 39d0f9522..bb5d14279 100644 --- a/src/WebRequest.cpp +++ b/src/WebRequest.cpp @@ -605,7 +605,7 @@ size_t AsyncWebServerRequest::headers() const{ return _headers.size(); } -bool AsyncWebServerRequest::hasHeader(const String& name) const { +bool AsyncWebServerRequest::hasHeader(const char* name) const { for(const auto& h: _headers){ if(h.name().equalsIgnoreCase(name)){ return true; @@ -614,44 +614,20 @@ bool AsyncWebServerRequest::hasHeader(const String& name) const { return false; } +#ifdef ESP8266 bool AsyncWebServerRequest::hasHeader(const __FlashStringHelper * data) const { return hasHeader(String(data)); } +#endif -AsyncWebHeader* AsyncWebServerRequest::getHeader(const String& name) { - auto iter = std::find_if(std::begin(_headers), std::end(_headers), - [&name](const AsyncWebHeader &header){ return header.name().equalsIgnoreCase(name); }); - - if (iter == std::end(_headers)) - return nullptr; - - return &(*iter); -} - -const AsyncWebHeader* AsyncWebServerRequest::getHeader(const String& name) const { +const AsyncWebHeader* AsyncWebServerRequest::getHeader(const char* name) const { auto iter = std::find_if(std::begin(_headers), std::end(_headers), [&name](const AsyncWebHeader &header){ return header.name().equalsIgnoreCase(name); }); - if (iter == std::end(_headers)) - return nullptr; - - return &(*iter); -} - -AsyncWebHeader* AsyncWebServerRequest::getHeader(const __FlashStringHelper * data) { - PGM_P p = reinterpret_cast(data); - size_t n = strlen_P(p); - char * name = (char*) malloc(n+1); - if (name) { - strcpy_P(name, p); - AsyncWebHeader* result = getHeader( String(name)); - free(name); - return result; - } else { - return nullptr; - } + return (iter == std::end(_headers)) ? nullptr : &(*iter); } +#ifdef ESP8266 const AsyncWebHeader* AsyncWebServerRequest::getHeader(const __FlashStringHelper * data) const { PGM_P p = reinterpret_cast(data); size_t n = strlen_P(p); @@ -665,17 +641,12 @@ const AsyncWebHeader* AsyncWebServerRequest::getHeader(const __FlashStringHelper return nullptr; } } - -AsyncWebHeader* AsyncWebServerRequest::getHeader(size_t num) { - if (num >= _headers.size()) - return nullptr; - return &(*std::next(std::begin(_headers), num)); -} +#endif const AsyncWebHeader* AsyncWebServerRequest::getHeader(size_t num) const { if (num >= _headers.size()) return nullptr; - return &(*std::next(std::begin(_headers), num)); + return &(*std::next(_headers.cbegin(), num)); } size_t AsyncWebServerRequest::params() const { @@ -695,7 +666,7 @@ bool AsyncWebServerRequest::hasParam(const __FlashStringHelper * data, bool post return hasParam(String(data).c_str(), post, file); } -const AsyncWebParameter* AsyncWebServerRequest::getParam(const String& name, bool post, bool file) const { +const AsyncWebParameter* AsyncWebServerRequest::getParam(const char* name, bool post, bool file) const { for(const auto &p: _params){ if(p.name() == name && p.isPost() == post && p.isFile() == file){ return &p; @@ -711,34 +682,15 @@ const AsyncWebParameter* AsyncWebServerRequest::getParam(const __FlashStringHelp #endif const AsyncWebParameter* AsyncWebServerRequest::getParam(size_t num) const { - if (num >= _params.size()) return nullptr; - auto iter = _params.cbegin(); - std::advance(iter, num); - return &(*iter); + if (num >= _params.size()) + return nullptr; + return &(*std::next(_params.cbegin(), num)); } -void AsyncWebServerRequest::addInterestingHeader(const String& name){ +void AsyncWebServerRequest::addInterestingHeader(const char* name){ if(std::none_of(std::begin(_interestingHeaders), std::end(_interestingHeaders), [&name](const String &str){ return str.equalsIgnoreCase(name); })) - _interestingHeaders.push_back(name); -} - -void AsyncWebServerRequest::send(AsyncWebServerResponse *response){ - _response = response; - if(_response == NULL){ - _client->close(true); - _onDisconnect(); - return; - } - if(!_response->_sourceValid()){ - delete response; - _response = NULL; - send(500); - } - else { - _client->setRxTimeout(0); - _response->_respond(this); - } + _interestingHeaders.emplace_back(name); } AsyncWebServerResponse * AsyncWebServerRequest::beginResponse(int code, const String& contentType, const String& content){ @@ -775,6 +727,7 @@ AsyncResponseStream * AsyncWebServerRequest::beginResponseStream(const String& c return new AsyncResponseStream(contentType, bufferSize); } +#ifdef ESP8266 AsyncWebServerResponse * AsyncWebServerRequest::beginResponse_P(int code, const String& contentType, const uint8_t * content, size_t len, AwsTemplateProcessor callback){ return new AsyncProgmemResponse(code, contentType, content, len, callback); } @@ -782,6 +735,25 @@ AsyncWebServerResponse * AsyncWebServerRequest::beginResponse_P(int code, const AsyncWebServerResponse * AsyncWebServerRequest::beginResponse_P(int code, const String& contentType, PGM_P content, AwsTemplateProcessor callback){ return beginResponse_P(code, contentType, (const uint8_t *)content, strlen_P(content), callback); } +#endif + +void AsyncWebServerRequest::send(AsyncWebServerResponse *response){ + _response = response; + if(_response == NULL){ + _client->close(true); + _onDisconnect(); + return; + } + if(!_response->_sourceValid()){ + delete response; + _response = NULL; + send(500); + } + else { + _client->setRxTimeout(0); + _response->_respond(this); + } +} void AsyncWebServerRequest::send(int code, const String& contentType, const String& content){ send(beginResponse(code, contentType, content)); @@ -811,6 +783,7 @@ void AsyncWebServerRequest::sendChunked(const String& contentType, AwsResponseFi send(beginChunkedResponse(contentType, callback, templateCallback)); } +#ifdef ESP8266 void AsyncWebServerRequest::send_P(int code, const String& contentType, const uint8_t * content, size_t len, AwsTemplateProcessor callback){ send(beginResponse_P(code, contentType, content, len, callback)); } @@ -818,8 +791,9 @@ void AsyncWebServerRequest::send_P(int code, const String& contentType, const ui void AsyncWebServerRequest::send_P(int code, const String& contentType, PGM_P content, AwsTemplateProcessor callback){ send(beginResponse_P(code, contentType, content, callback)); } +#endif -void AsyncWebServerRequest::redirect(const String& url){ +void AsyncWebServerRequest::redirect(const char* url){ AsyncWebServerResponse * response = beginResponse(302); response->addHeader(F("Location"), url); send(response); @@ -885,12 +859,13 @@ bool AsyncWebServerRequest::hasArg(const char* name) const { return false; } +#ifdef ESP8266 bool AsyncWebServerRequest::hasArg(const __FlashStringHelper * data) const { return hasArg(String(data).c_str()); } +#endif - -const String& AsyncWebServerRequest::arg(const String& name) const { +const String& AsyncWebServerRequest::arg(const char* name) const { for(const auto& arg: _params){ if(arg.name() == name){ return arg.value(); @@ -899,9 +874,11 @@ const String& AsyncWebServerRequest::arg(const String& name) const { return emptyString; } +#ifdef ESP8266 const String& AsyncWebServerRequest::arg(const __FlashStringHelper * data) const { return arg(String(data).c_str()); } +#endif const String& AsyncWebServerRequest::arg(size_t i) const { return getParam(i)->value(); @@ -916,14 +893,15 @@ const String& AsyncWebServerRequest::pathArg(size_t i) const { } const String& AsyncWebServerRequest::header(const char* name) const { - const AsyncWebHeader* h = getHeader(String(name)); + const AsyncWebHeader* h = getHeader(name); return h ? h->value() : emptyString; } +#ifdef ESP8266 const String& AsyncWebServerRequest::header(const __FlashStringHelper * data) const { return header(String(data).c_str()); }; - +#endif const String& AsyncWebServerRequest::header(size_t i) const { const AsyncWebHeader* h = getHeader(i); @@ -939,7 +917,7 @@ String AsyncWebServerRequest::urlDecode(const String& text) const { char temp[] = "0x00"; unsigned int len = text.length(); unsigned int i = 0; - String decoded = String(); + String decoded; decoded.reserve(len); // Allocate the string internal buffer - never longer from source text while (i < len){ char decodedChar; @@ -958,7 +936,32 @@ String AsyncWebServerRequest::urlDecode(const String& text) const { return decoded; } +#ifndef ESP8266 +const char* AsyncWebServerRequest::methodToString() const { + if(_method == HTTP_ANY) return "ANY"; + if(_method & HTTP_GET) return "GET"; + if(_method & HTTP_POST) return "POST"; + if(_method & HTTP_DELETE) return "DELETE"; + if(_method & HTTP_PUT) return "PUT"; + if(_method & HTTP_PATCH) return "PATCH"; + if(_method & HTTP_HEAD) return "HEAD"; + if(_method & HTTP_OPTIONS) return "OPTIONS"; + return "UNKNOWN"; +} + +const char* AsyncWebServerRequest::requestedConnTypeToString() const { + switch (_reqconntype) { + case RCT_NOT_USED: return "RCT_NOT_USED"; + case RCT_DEFAULT: return "RCT_DEFAULT"; + case RCT_HTTP: return "RCT_HTTP"; + case RCT_WS: return "RCT_WS"; + case RCT_EVENT: return "RCT_EVENT"; + default: return "ERROR"; + } +} +#endif +#ifdef ESP8266 const __FlashStringHelper *AsyncWebServerRequest::methodToString() const { if(_method == HTTP_ANY) return F("ANY"); else if(_method & HTTP_GET) return F("GET"); @@ -981,6 +984,7 @@ const __FlashStringHelper *AsyncWebServerRequest::requestedConnTypeToString() co default: return F("ERROR"); } } +#endif bool AsyncWebServerRequest::isExpectedRequestedConnType(RequestedConnectionType erct1, RequestedConnectionType erct2, RequestedConnectionType erct3) { bool res = false; From b015b8db548030ef8bb5de01e395e5b6a15af048 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Thu, 27 Jun 2024 20:23:23 +0200 Subject: [PATCH 256/551] Small cleanup --- src/ESPAsyncWebServer.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index 45085219f..ec616d3b6 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -208,7 +208,6 @@ class AsyncWebServerRequest { void _onDisconnect(); void _onData(void *buf, size_t len); - //void _addParam(AsyncWebParameter*); void _addPathParam(const char *param); bool _parseReqHead(); @@ -268,7 +267,7 @@ class AsyncWebServerRequest { void addInterestingHeader(const String& name){ return addInterestingHeader(name.c_str()); }; /** - * @brief issue 302 redirect responce + * @brief issue 302 redirect response * * @param url */ From 29976ad85ab85d506beb4b3fc2a21ea5a267400b Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Thu, 27 Jun 2024 20:34:10 +0200 Subject: [PATCH 257/551] Code reformat according to clang file --- src/AsyncEventSource.cpp | 205 +++-- src/AsyncEventSource.h | 109 +-- src/AsyncJson.h | 8 +- src/AsyncWebSocket.cpp | 1572 +++++++++++++++++-------------------- src/AsyncWebSocket.h | 300 +++---- src/ESPAsyncWebServer.h | 375 +++++---- src/WebAuthentication.cpp | 127 ++- src/WebAuthentication.h | 12 +- src/WebHandlerImpl.h | 96 +-- src/WebHandlers.cpp | 128 +-- src/WebRequest.cpp | 797 ++++++++++--------- src/WebResponseImpl.h | 88 ++- src/WebResponses.cpp | 499 ++++++------ src/WebServer.cpp | 98 ++- 14 files changed, 2209 insertions(+), 2205 deletions(-) diff --git a/src/AsyncEventSource.cpp b/src/AsyncEventSource.cpp index 90faa3ff5..87d829383 100644 --- a/src/AsyncEventSource.cpp +++ b/src/AsyncEventSource.cpp @@ -23,38 +23,38 @@ #endif #include "AsyncEventSource.h" -static String generateEventMessage(const char *message, const char *event, uint32_t id, uint32_t reconnect){ +static String generateEventMessage(const char* message, const char* event, uint32_t id, uint32_t reconnect) { String ev; - if(reconnect){ + if (reconnect) { ev += F("retry: "); ev += reconnect; ev += F("\r\n"); } - if(id){ + if (id) { ev += F("id: "); ev += String(id); ev += F("\r\n"); } - if(event != NULL){ + if (event != NULL) { ev += F("event: "); ev += String(event); ev += F("\r\n"); } - if(message != NULL){ + if (message != NULL) { size_t messageLen = strlen(message); - char * lineStart = (char *)message; - char * lineEnd; + char* lineStart = (char*)message; + char* lineEnd; do { - char * nextN = strchr(lineStart, '\n'); - char * nextR = strchr(lineStart, '\r'); - if(nextN == NULL && nextR == NULL){ - size_t llen = ((char *)message + messageLen) - lineStart; - char * ldata = (char *)malloc(llen+1); - if(ldata != NULL){ + char* nextN = strchr(lineStart, '\n'); + char* nextR = strchr(lineStart, '\r'); + if (nextN == NULL && nextR == NULL) { + size_t llen = ((char*)message + messageLen) - lineStart; + char* ldata = (char*)malloc(llen + 1); + if (ldata != NULL) { memcpy(ldata, lineStart, llen); ldata[llen] = 0; ev += F("data: "); @@ -62,24 +62,24 @@ static String generateEventMessage(const char *message, const char *event, uint3 ev += F("\r\n\r\n"); free(ldata); } - lineStart = (char *)message + messageLen; + lineStart = (char*)message + messageLen; } else { - char * nextLine = NULL; - if(nextN != NULL && nextR != NULL){ - if(nextR < nextN){ + char* nextLine = NULL; + if (nextN != NULL && nextR != NULL) { + if (nextR < nextN) { lineEnd = nextR; - if(nextN == (nextR + 1)) + if (nextN == (nextR + 1)) nextLine = nextN + 1; else nextLine = nextR + 1; } else { lineEnd = nextN; - if(nextR == (nextN + 1)) + if (nextR == (nextN + 1)) nextLine = nextR + 1; else nextLine = nextN + 1; } - } else if(nextN != NULL){ + } else if (nextN != NULL) { lineEnd = nextN; nextLine = nextN + 1; } else { @@ -88,8 +88,8 @@ static String generateEventMessage(const char *message, const char *event, uint3 } size_t llen = lineEnd - lineStart; - char * ldata = (char *)malloc(llen+1); - if(ldata != NULL){ + char* ldata = (char*)malloc(llen + 1); + if (ldata != NULL) { memcpy(ldata, lineStart, llen); ldata[llen] = 0; ev += F("data: "); @@ -98,10 +98,10 @@ static String generateEventMessage(const char *message, const char *event, uint3 free(ldata); } lineStart = nextLine; - if(lineStart == ((char *)message + messageLen)) + if (lineStart == ((char*)message + messageLen)) ev += F("\r\n"); } - } while(lineStart < ((char *)message + messageLen)); + } while (lineStart < ((char*)message + messageLen)); } return ev; @@ -109,11 +109,10 @@ static String generateEventMessage(const char *message, const char *event, uint3 // Message -AsyncEventSourceMessage::AsyncEventSourceMessage(const char * data, size_t len) -: _data(nullptr), _len(len), _sent(0), _acked(0) -{ - _data = (uint8_t*)malloc(_len+1); - if(_data == nullptr){ +AsyncEventSourceMessage::AsyncEventSourceMessage(const char* data, size_t len) + : _data(nullptr), _len(len), _sent(0), _acked(0) { + _data = (uint8_t*)malloc(_len + 1); + if (_data == nullptr) { _len = 0; } else { memcpy(_data, data, len); @@ -122,18 +121,18 @@ AsyncEventSourceMessage::AsyncEventSourceMessage(const char * data, size_t len) } AsyncEventSourceMessage::~AsyncEventSourceMessage() { - if(_data != NULL) - free(_data); + if (_data != NULL) + free(_data); } size_t AsyncEventSourceMessage::ack(size_t len, uint32_t time) { (void)time; // If the whole message is now acked... - if(_acked + len > _len){ - // Return the number of extra bytes acked (they will be carried on to the next message) - const size_t extra = _acked + len - _len; - _acked = _len; - return extra; + if (_acked + len > _len) { + // Return the number of extra bytes acked (they will be carried on to the next message) + const size_t extra = _acked + len - _len; + _acked = _len; + return extra; } // Return that no extra bytes left. _acked += len; @@ -142,40 +141,39 @@ size_t AsyncEventSourceMessage::ack(size_t len, uint32_t time) { // This could also return void as the return value is not used. // Leaving as-is for compatibility... -size_t AsyncEventSourceMessage::send(AsyncClient *client) { - if (_sent >= _len) { - return 0; - } - const size_t len_to_send = _len - _sent; - auto position = reinterpret_cast(_data + _sent); - const size_t sent_now = client->write(position, len_to_send); - _sent += sent_now; - return sent_now; +size_t AsyncEventSourceMessage::send(AsyncClient* client) { + if (_sent >= _len) { + return 0; + } + const size_t len_to_send = _len - _sent; + auto position = reinterpret_cast(_data + _sent); + const size_t sent_now = client->write(position, len_to_send); + _sent += sent_now; + return sent_now; } // Client -AsyncEventSourceClient::AsyncEventSourceClient(AsyncWebServerRequest *request, AsyncEventSource *server) -{ +AsyncEventSourceClient::AsyncEventSourceClient(AsyncWebServerRequest* request, AsyncEventSource* server) { _client = request->client(); _server = server; _lastId = 0; - if(request->hasHeader(F("Last-Event-ID"))) + if (request->hasHeader(F("Last-Event-ID"))) _lastId = atoi(request->getHeader(F("Last-Event-ID"))->value().c_str()); _client->setRxTimeout(0); _client->onError(NULL, NULL); - _client->onAck([](void *r, AsyncClient* c, size_t len, uint32_t time){ (void)c; ((AsyncEventSourceClient*)(r))->_onAck(len, time); }, this); - _client->onPoll([](void *r, AsyncClient* c){ (void)c; ((AsyncEventSourceClient*)(r))->_onPoll(); }, this); + _client->onAck([](void* r, AsyncClient* c, size_t len, uint32_t time) { (void)c; ((AsyncEventSourceClient*)(r))->_onAck(len, time); }, this); + _client->onPoll([](void* r, AsyncClient* c) { (void)c; ((AsyncEventSourceClient*)(r))->_onPoll(); }, this); _client->onData(NULL, NULL); - _client->onTimeout([this](void *r, AsyncClient* c __attribute__((unused)), uint32_t time){ ((AsyncEventSourceClient*)(r))->_onTimeout(time); }, this); - _client->onDisconnect([this](void *r, AsyncClient* c){ ((AsyncEventSourceClient*)(r))->_onDisconnect(); delete c; }, this); + _client->onTimeout([this](void* r, AsyncClient* c __attribute__((unused)), uint32_t time) { ((AsyncEventSourceClient*)(r))->_onTimeout(time); }, this); + _client->onDisconnect([this](void* r, AsyncClient* c) { ((AsyncEventSourceClient*)(r))->_onDisconnect(); delete c; }, this); _server->_addClient(this); delete request; } -AsyncEventSourceClient::~AsyncEventSourceClient(){ +AsyncEventSourceClient::~AsyncEventSourceClient() { #ifdef ESP32 std::lock_guard lock(_lockmq); #endif @@ -183,132 +181,133 @@ AsyncEventSourceClient::~AsyncEventSourceClient(){ close(); } -void AsyncEventSourceClient::_queueMessage(const char * message, size_t len){ +void AsyncEventSourceClient::_queueMessage(const char* message, size_t len) { #ifdef ESP32 - //length() is not thread-safe, thus acquiring the lock before this call.. + // length() is not thread-safe, thus acquiring the lock before this call.. std::lock_guard lock(_lockmq); #endif - if(_messageQueue.size() >= SSE_MAX_QUEUED_MESSAGES){ + if (_messageQueue.size() >= SSE_MAX_QUEUED_MESSAGES) { #ifdef ESP8266 ets_printf(String(F("ERROR: Too many messages queued\n")).c_str()); #else log_e("Too many messages queued: deleting message"); #endif - return; + return; } _messageQueue.emplace_back(message, len); // runqueue trigger when new messages added - if(_client->canSend()) { + if (_client->canSend()) { _runQueue(); } } -void AsyncEventSourceClient::_onAck(size_t len, uint32_t time){ +void AsyncEventSourceClient::_onAck(size_t len, uint32_t time) { #ifdef ESP32 // Same here, acquiring the lock early std::lock_guard lock(_lockmq); #endif - while(len && _messageQueue.size()){ + while (len && _messageQueue.size()) { len = _messageQueue.front().ack(len, time); - if(_messageQueue.front().finished()) + if (_messageQueue.front().finished()) _messageQueue.pop_front(); } _runQueue(); } -void AsyncEventSourceClient::_onPoll(){ +void AsyncEventSourceClient::_onPoll() { #ifdef ESP32 // Same here, acquiring the lock early std::lock_guard lock(_lockmq); #endif - if(_messageQueue.size()){ + if (_messageQueue.size()) { _runQueue(); } } -void AsyncEventSourceClient::_onTimeout(uint32_t time __attribute__((unused))){ +void AsyncEventSourceClient::_onTimeout(uint32_t time __attribute__((unused))) { _client->close(true); } -void AsyncEventSourceClient::_onDisconnect(){ +void AsyncEventSourceClient::_onDisconnect() { _client = NULL; _server->_handleDisconnect(this); } -void AsyncEventSourceClient::close(){ - if(_client != NULL) +void AsyncEventSourceClient::close() { + if (_client != NULL) _client->close(); } -void AsyncEventSourceClient::write(const char * message, size_t len){ - if(!connected()) return; +void AsyncEventSourceClient::write(const char* message, size_t len) { + if (!connected()) + return; _queueMessage(message, len); } -void AsyncEventSourceClient::send(const char *message, const char *event, uint32_t id, uint32_t reconnect){ - if(!connected()) return; +void AsyncEventSourceClient::send(const char* message, const char* event, uint32_t id, uint32_t reconnect) { + if (!connected()) + return; String ev = generateEventMessage(message, event, id, reconnect); _queueMessage(ev.c_str(), ev.length()); } size_t AsyncEventSourceClient::packetsWaiting() const { #ifdef ESP32 - std::lock_guard lock(_lockmq); + std::lock_guard lock(_lockmq); #endif - return _messageQueue.size(); + return _messageQueue.size(); } void AsyncEventSourceClient::_runQueue() { // Calls to this private method now already protected by _lockmq acquisition // so no extra call of _lockmq.lock() here.. - for ( auto &i : _messageQueue){ + for (auto& i : _messageQueue) { if (!i.sent()) i.send(_client); } } - // Handler -void AsyncEventSource::onConnect(ArEventHandlerFunction cb){ +void AsyncEventSource::onConnect(ArEventHandlerFunction cb) { _connectcb = cb; } -void AsyncEventSource::authorizeConnect(ArAuthorizeConnectHandler cb){ +void AsyncEventSource::authorizeConnect(ArAuthorizeConnectHandler cb) { _authorizeConnectHandler = cb; } -void AsyncEventSource::_addClient(AsyncEventSourceClient * client){ +void AsyncEventSource::_addClient(AsyncEventSourceClient* client) { if (!client) return; #ifdef ESP32 std::lock_guard lock(_client_queue_lock); #endif _clients.emplace_back(client); - if(_connectcb) + if (_connectcb) _connectcb(client); } -void AsyncEventSource::_handleDisconnect(AsyncEventSourceClient * client){ +void AsyncEventSource::_handleDisconnect(AsyncEventSourceClient* client) { #ifdef ESP32 std::lock_guard lock(_client_queue_lock); #endif - for (auto i = _clients.begin(); i != _clients.end(); ++i){ + for (auto i = _clients.begin(); i != _clients.end(); ++i) { if (i->get() == client) _clients.erase(i); } } -void AsyncEventSource::close(){ +void AsyncEventSource::close() { // While the whole loop is not done, the linked list is locked and so the // iterator should remain valid even when AsyncEventSource::_handleDisconnect() // is called very early #ifdef ESP32 std::lock_guard lock(_client_queue_lock); #endif - for(const auto &c: _clients){ - if(c->connected()) + for (const auto& c : _clients) { + if (c->connected()) c->close(); } } @@ -320,25 +319,26 @@ size_t AsyncEventSource::avgPacketsWaiting() const { #ifdef ESP32 std::lock_guard lock(_client_queue_lock); #endif - if (!_clients.size()) return 0; + if (!_clients.size()) + return 0; - for(const auto &c: _clients){ - if(c->connected()) { + for (const auto& c : _clients) { + if (c->connected()) { aql += c->packetsWaiting(); ++nConnectedClients; } } - return ((aql) + (nConnectedClients/2)) / (nConnectedClients); // round up + return ((aql) + (nConnectedClients / 2)) / (nConnectedClients); // round up } void AsyncEventSource::send( - const char *message, const char *event, uint32_t id, uint32_t reconnect){ + const char* message, const char* event, uint32_t id, uint32_t reconnect) { String ev = generateEventMessage(message, event, id, reconnect); #ifdef ESP32 std::lock_guard lock(_client_queue_lock); #endif - for(const auto &c: _clients){ - if(c->connected()) { + for (const auto& c : _clients) { + if (c->connected()) { c->write(ev.c_str(), ev.length()); } } @@ -349,15 +349,15 @@ size_t AsyncEventSource::count() const { std::lock_guard lock(_client_queue_lock); #endif size_t n_clients{0}; - for (const auto &i : _clients) + for (const auto& i : _clients) if (i->connected()) ++n_clients; return n_clients; } -bool AsyncEventSource::canHandle(AsyncWebServerRequest *request){ - if(request->method() != HTTP_GET || !request->url().equals(_url)) { +bool AsyncEventSource::canHandle(AsyncWebServerRequest* request) { + if (request->method() != HTTP_GET || !request->url().equals(_url)) { return false; } request->addInterestingHeader(F("Last-Event-ID")); @@ -365,12 +365,12 @@ bool AsyncEventSource::canHandle(AsyncWebServerRequest *request){ return true; } -void AsyncEventSource::handleRequest(AsyncWebServerRequest *request){ - if((_username.length() && _password.length()) && !request->authenticate(_username.c_str(), _password.c_str())) { +void AsyncEventSource::handleRequest(AsyncWebServerRequest* request) { + if ((_username.length() && _password.length()) && !request->authenticate(_username.c_str(), _password.c_str())) { return request->requestAuthentication(); } - if(_authorizeConnectHandler != NULL){ - if(!_authorizeConnectHandler(request)){ + if (_authorizeConnectHandler != NULL) { + if (!_authorizeConnectHandler(request)) { return request->send(401); } } @@ -379,7 +379,7 @@ void AsyncEventSource::handleRequest(AsyncWebServerRequest *request){ // Response -AsyncEventSourceResponse::AsyncEventSourceResponse(AsyncEventSource *server){ +AsyncEventSourceResponse::AsyncEventSourceResponse(AsyncEventSource* server) { _server = server; _code = 200; _contentType = F("text/event-stream"); @@ -388,16 +388,15 @@ AsyncEventSourceResponse::AsyncEventSourceResponse(AsyncEventSource *server){ addHeader(F("Connection"), F("keep-alive")); } -void AsyncEventSourceResponse::_respond(AsyncWebServerRequest *request){ +void AsyncEventSourceResponse::_respond(AsyncWebServerRequest* request) { String out = _assembleHead(request->version()); request->client()->write(out.c_str(), _headLength); _state = RESPONSE_WAIT_ACK; } -size_t AsyncEventSourceResponse::_ack(AsyncWebServerRequest *request, size_t len, uint32_t time __attribute__((unused))){ - if(len){ +size_t AsyncEventSourceResponse::_ack(AsyncWebServerRequest* request, size_t len, uint32_t time __attribute__((unused))) { + if (len) { new AsyncEventSourceClient(request, _server); } return 0; } - diff --git a/src/AsyncEventSource.h b/src/AsyncEventSource.h index 6ce3e5729..93a417664 100644 --- a/src/AsyncEventSource.h +++ b/src/AsyncEventSource.h @@ -23,130 +23,131 @@ #include #include #ifdef ESP32 -#include -#include -#ifndef SSE_MAX_QUEUED_MESSAGES -#define SSE_MAX_QUEUED_MESSAGES 32 -#endif + #include + #include + #ifndef SSE_MAX_QUEUED_MESSAGES + #define SSE_MAX_QUEUED_MESSAGES 32 + #endif #else // esp8266 -#include -#ifndef SSE_MAX_QUEUED_MESSAGES -#define SSE_MAX_QUEUED_MESSAGES 8 -#endif + #include + #ifndef SSE_MAX_QUEUED_MESSAGES + #define SSE_MAX_QUEUED_MESSAGES 8 + #endif #endif #include #ifdef ESP8266 -#include -#ifdef CRYPTO_HASH_h // include Hash.h from espressif framework if the first include was from the crypto library -#include <../src/Hash.h> -#endif + #include + #ifdef CRYPTO_HASH_h // include Hash.h from espressif framework if the first include was from the crypto library + #include <../src/Hash.h> + #endif #endif #ifndef DEFAULT_MAX_SSE_CLIENTS -#ifdef ESP32 -#define DEFAULT_MAX_SSE_CLIENTS 8 -#else -#define DEFAULT_MAX_SSE_CLIENTS 4 -#endif + #ifdef ESP32 + #define DEFAULT_MAX_SSE_CLIENTS 8 + #else + #define DEFAULT_MAX_SSE_CLIENTS 4 + #endif #endif class AsyncEventSource; class AsyncEventSourceResponse; class AsyncEventSourceClient; -using ArEventHandlerFunction = std::function; -using ArAuthorizeConnectHandler = std::function; +using ArEventHandlerFunction = std::function; +using ArAuthorizeConnectHandler = std::function; class AsyncEventSourceMessage { private: - uint8_t * _data; + uint8_t* _data; size_t _len; size_t _sent; - //size_t _ack; + // size_t _ack; size_t _acked; + public: - AsyncEventSourceMessage(const char * data, size_t len); + AsyncEventSourceMessage(const char* data, size_t len); ~AsyncEventSourceMessage(); size_t ack(size_t len, uint32_t time __attribute__((unused))); - size_t send(AsyncClient *client); - bool finished(){ return _acked == _len; } + size_t send(AsyncClient* client); + bool finished() { return _acked == _len; } bool sent() { return _sent == _len; } }; class AsyncEventSourceClient { private: - AsyncClient *_client; - AsyncEventSource *_server; + AsyncClient* _client; + AsyncEventSource* _server; uint32_t _lastId; - std::list< AsyncEventSourceMessage > _messageQueue; + std::list _messageQueue; #ifdef ESP32 mutable std::mutex _lockmq; #endif - void _queueMessage(const char * message, size_t len); + void _queueMessage(const char* message, size_t len); void _runQueue(); public: - - AsyncEventSourceClient(AsyncWebServerRequest *request, AsyncEventSource *server); + AsyncEventSourceClient(AsyncWebServerRequest* request, AsyncEventSource* server); ~AsyncEventSourceClient(); - AsyncClient* client(){ return _client; } + AsyncClient* client() { return _client; } void close(); - void write(const char * message, size_t len); - void send(const char *message, const char *event=NULL, uint32_t id=0, uint32_t reconnect=0); + void write(const char* message, size_t len); + void send(const char* message, const char* event = NULL, uint32_t id = 0, uint32_t reconnect = 0); bool connected() const { return (_client != NULL) && _client->connected(); } uint32_t lastId() const { return _lastId; } - size_t packetsWaiting() const; + size_t packetsWaiting() const; - //system callbacks (do not call) + // system callbacks (do not call) void _onAck(size_t len, uint32_t time); void _onPoll(); void _onTimeout(uint32_t time); void _onDisconnect(); }; -class AsyncEventSource: public AsyncWebHandler { +class AsyncEventSource : public AsyncWebHandler { private: String _url; - std::list< std::unique_ptr > _clients; + std::list> _clients; #ifdef ESP32 // Same as for individual messages, protect mutations of _clients list // since simultaneous access from different tasks is possible mutable std::mutex _client_queue_lock; #endif ArEventHandlerFunction _connectcb{nullptr}; - ArAuthorizeConnectHandler _authorizeConnectHandler; + ArAuthorizeConnectHandler _authorizeConnectHandler; + public: AsyncEventSource(const String& url) : _url(url){}; - ~AsyncEventSource(){ close(); }; + ~AsyncEventSource() { close(); }; - const char * url() const { return _url.c_str(); } + const char* url() const { return _url.c_str(); } void close(); void onConnect(ArEventHandlerFunction cb); void authorizeConnect(ArAuthorizeConnectHandler cb); - void send(const char *message, const char *event=NULL, uint32_t id=0, uint32_t reconnect=0); + void send(const char* message, const char* event = NULL, uint32_t id = 0, uint32_t reconnect = 0); // number of clients connected size_t count() const; - size_t avgPacketsWaiting() const; + size_t avgPacketsWaiting() const; - //system callbacks (do not call) - void _addClient(AsyncEventSourceClient * client); - void _handleDisconnect(AsyncEventSourceClient * client); - virtual bool canHandle(AsyncWebServerRequest *request) override final; - virtual void handleRequest(AsyncWebServerRequest *request) override final; + // system callbacks (do not call) + void _addClient(AsyncEventSourceClient* client); + void _handleDisconnect(AsyncEventSourceClient* client); + virtual bool canHandle(AsyncWebServerRequest* request) override final; + virtual void handleRequest(AsyncWebServerRequest* request) override final; }; -class AsyncEventSourceResponse: public AsyncWebServerResponse { +class AsyncEventSourceResponse : public AsyncWebServerResponse { private: String _content; - AsyncEventSource *_server; + AsyncEventSource* _server; + public: - AsyncEventSourceResponse(AsyncEventSource *server); - void _respond(AsyncWebServerRequest *request); - size_t _ack(AsyncWebServerRequest *request, size_t len, uint32_t time); + AsyncEventSourceResponse(AsyncEventSource* server); + void _respond(AsyncWebServerRequest* request); + size_t _ack(AsyncWebServerRequest* request, size_t len, uint32_t time); bool _sourceValid() const { return true; } }; - #endif /* ASYNCEVENTSOURCE_H_ */ diff --git a/src/AsyncJson.h b/src/AsyncJson.h index 677445401..ce89301a3 100644 --- a/src/AsyncJson.h +++ b/src/AsyncJson.h @@ -39,9 +39,9 @@ #include #if ARDUINOJSON_VERSION_MAJOR == 6 -#ifndef DYNAMIC_JSON_DOCUMENT_SIZE -#define DYNAMIC_JSON_DOCUMENT_SIZE 1024 -#endif + #ifndef DYNAMIC_JSON_DOCUMENT_SIZE + #define DYNAMIC_JSON_DOCUMENT_SIZE 1024 + #endif #endif constexpr const char* JSON_MIMETYPE = "application/json"; @@ -230,7 +230,7 @@ class AsyncCallbackJsonWebHandler : public AsyncWebHandler { } virtual void handleRequest(AsyncWebServerRequest* request) override final { - if((_username != "" && _password != "") && !request->authenticate(_username.c_str(), _password.c_str())) + if ((_username != "" && _password != "") && !request->authenticate(_username.c_str(), _password.c_str())) return request->requestAuthentication(); if (_onRequest) { if (request->method() == HTTP_GET) { diff --git a/src/AsyncWebSocket.cpp b/src/AsyncWebSocket.cpp index b59c39221..8f1e6a81f 100644 --- a/src/AsyncWebSocket.cpp +++ b/src/AsyncWebSocket.cpp @@ -18,144 +18,140 @@ License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "Arduino.h" #include "AsyncWebSocket.h" +#include "Arduino.h" #include #include #ifndef ESP8266 -#if ESP_IDF_VERSION_MAJOR < 5 -#include "./port/SHA1Builder.h" -#else -#include -#endif -#include + #if ESP_IDF_VERSION_MAJOR < 5 + #include "./port/SHA1Builder.h" + #else + #include + #endif + #include #else -#include + #include #endif #define MAX_PRINTF_LEN 64 -size_t webSocketSendFrameWindow(AsyncClient *client){ - if(!client->canSend()) +size_t webSocketSendFrameWindow(AsyncClient* client) { + if (!client->canSend()) return 0; size_t space = client->space(); - if(space < 9) + if (space < 9) return 0; return space - 8; } -size_t webSocketSendFrame(AsyncClient *client, bool final, uint8_t opcode, bool mask, uint8_t *data, size_t len){ - if(!client->canSend()) { +size_t webSocketSendFrame(AsyncClient* client, bool final, uint8_t opcode, bool mask, uint8_t* data, size_t len) { + if (!client->canSend()) { // Serial.println("SF 1"); return 0; } size_t space = client->space(); - if(space < 2) { + if (space < 2) { // Serial.println("SF 2"); return 0; } - uint8_t mbuf[4] = {0,0,0,0}; + uint8_t mbuf[4] = {0, 0, 0, 0}; uint8_t headLen = 2; - if(len && mask){ + if (len && mask) { headLen += 4; mbuf[0] = rand() % 0xFF; mbuf[1] = rand() % 0xFF; mbuf[2] = rand() % 0xFF; mbuf[3] = rand() % 0xFF; } - if(len > 125) + if (len > 125) headLen += 2; - if(space < headLen) { + if (space < headLen) { // Serial.println("SF 2"); return 0; } space -= headLen; - if(len > space) len = space; + if (len > space) + len = space; - uint8_t *buf = (uint8_t*)malloc(headLen); - if(buf == NULL){ - //os_printf("could not malloc %u bytes for frame header\n", headLen); - // Serial.println("SF 3"); + uint8_t* buf = (uint8_t*)malloc(headLen); + if (buf == NULL) { + // os_printf("could not malloc %u bytes for frame header\n", headLen); + // Serial.println("SF 3"); return 0; } buf[0] = opcode & 0x0F; - if(final) + if (final) buf[0] |= 0x80; - if(len < 126) + if (len < 126) buf[1] = len & 0x7F; else { buf[1] = 126; buf[2] = (uint8_t)((len >> 8) & 0xFF); buf[3] = (uint8_t)(len & 0xFF); } - if(len && mask){ + if (len && mask) { buf[1] |= 0x80; memcpy(buf + (headLen - 4), mbuf, 4); } - if(client->add((const char *)buf, headLen) != headLen){ - //os_printf("error adding %lu header bytes\n", headLen); + if (client->add((const char*)buf, headLen) != headLen) { + // os_printf("error adding %lu header bytes\n", headLen); free(buf); // Serial.println("SF 4"); return 0; } free(buf); - if(len){ - if(len && mask){ + if (len) { + if (len && mask) { size_t i; - for(i=0;iadd((const char *)data, len) != len){ - //os_printf("error adding %lu data bytes\n", len); - // Serial.println("SF 5"); + if (client->add((const char*)data, len) != len) { + // os_printf("error adding %lu data bytes\n", len); + // Serial.println("SF 5"); return 0; } } - if(!client->send()){ - //os_printf("error sending frame: %lu\n", headLen+len); - // Serial.println("SF 6"); + if (!client->send()) { + // os_printf("error sending frame: %lu\n", headLen+len); + // Serial.println("SF 6"); return 0; } // Serial.println("SF"); return len; } - - /* * AsyncWebSocketMessageBuffer */ AsyncWebSocketMessageBuffer::AsyncWebSocketMessageBuffer(const uint8_t* data, size_t size) - : _buffer(std::make_shared>(size)) -{ - if (_buffer->capacity() < size) { - _buffer->reserve(size); - } else { - std::memcpy(_buffer->data(), data, size); - } + : _buffer(std::make_shared>(size)) { + if (_buffer->capacity() < size) { + _buffer->reserve(size); + } else { + std::memcpy(_buffer->data(), data, size); + } } AsyncWebSocketMessageBuffer::AsyncWebSocketMessageBuffer(size_t size) - : _buffer(std::make_shared>(size)) -{ - if (_buffer->capacity() < size) { - _buffer->reserve(size); - } + : _buffer(std::make_shared>(size)) { + if (_buffer->capacity() < size) { + _buffer->reserve(size); + } } -bool AsyncWebSocketMessageBuffer::reserve(size_t size) -{ - if (_buffer->capacity() >= size) - return true; - _buffer->reserve(size); - return _buffer->capacity() >= size; +bool AsyncWebSocketMessageBuffer::reserve(size_t size) { + if (_buffer->capacity() >= size) + return true; + _buffer->reserve(size); + return _buffer->capacity() >= size; } /* @@ -163,381 +159,340 @@ bool AsyncWebSocketMessageBuffer::reserve(size_t size) */ class AsyncWebSocketControl { -private: + private: uint8_t _opcode; - uint8_t *_data; + uint8_t* _data; size_t _len; bool _mask; bool _finished; -public: - AsyncWebSocketControl(uint8_t opcode, const uint8_t *data=NULL, size_t len=0, bool mask=false) - :_opcode(opcode) - ,_len(len) - ,_mask(len && mask) - ,_finished(false) - { - if (data == NULL) - _len = 0; - if (_len) - { - if (_len > 125) - _len = 125; - - _data = (uint8_t*)malloc(_len); - - if(_data == NULL) - _len = 0; - else - memcpy(_data, data, len); - } + public: + AsyncWebSocketControl(uint8_t opcode, const uint8_t* data = NULL, size_t len = 0, bool mask = false) + : _opcode(opcode), _len(len), _mask(len && mask), _finished(false) { + if (data == NULL) + _len = 0; + if (_len) { + if (_len > 125) + _len = 125; + + _data = (uint8_t*)malloc(_len); + + if (_data == NULL) + _len = 0; else - _data = NULL; + memcpy(_data, data, len); + } else + _data = NULL; } - virtual ~AsyncWebSocketControl() - { - if (_data != NULL) - free(_data); + virtual ~AsyncWebSocketControl() { + if (_data != NULL) + free(_data); } virtual bool finished() const { return _finished; } - uint8_t opcode(){ return _opcode; } - uint8_t len(){ return _len + 2; } - size_t send(AsyncClient *client){ - _finished = true; - return webSocketSendFrame(client, true, _opcode & 0x0F, _mask, _data, _len); + uint8_t opcode() { return _opcode; } + uint8_t len() { return _len + 2; } + size_t send(AsyncClient* client) { + _finished = true; + return webSocketSendFrame(client, true, _opcode & 0x0F, _mask, _data, _len); } }; - /* * AsyncWebSocketMessage Message */ +AsyncWebSocketMessage::AsyncWebSocketMessage(AsyncWebSocketSharedBuffer buffer, uint8_t opcode, bool mask) : _WSbuffer{buffer}, + _opcode(opcode & 0x07), + _mask{mask}, + _status{_WSbuffer ? WS_MSG_SENDING : WS_MSG_ERROR} { +} -AsyncWebSocketMessage::AsyncWebSocketMessage(AsyncWebSocketSharedBuffer buffer, uint8_t opcode, bool mask) : - _WSbuffer{buffer}, - _opcode(opcode & 0x07), - _mask{mask}, - _status{_WSbuffer?WS_MSG_SENDING:WS_MSG_ERROR} -{ -} - -void AsyncWebSocketMessage::ack(size_t len, uint32_t time) -{ - (void)time; - _acked += len; - if (_sent >= _WSbuffer->size() && _acked >= _ack) - { - _status = WS_MSG_SENT; - } - //ets_printf("A: %u\n", len); +void AsyncWebSocketMessage::ack(size_t len, uint32_t time) { + (void)time; + _acked += len; + if (_sent >= _WSbuffer->size() && _acked >= _ack) { + _status = WS_MSG_SENT; + } + // ets_printf("A: %u\n", len); } -size_t AsyncWebSocketMessage::send(AsyncClient *client) -{ - if (_status != WS_MSG_SENDING) - return 0; - if (_acked < _ack){ - return 0; - } - if (_sent == _WSbuffer->size()) - { - if(_acked == _ack) - _status = WS_MSG_SENT; - return 0; - } - if (_sent > _WSbuffer->size()) - { - _status = WS_MSG_ERROR; - //ets_printf("E: %u > %u\n", _sent, _WSbuffer->length()); - return 0; - } +size_t AsyncWebSocketMessage::send(AsyncClient* client) { + if (_status != WS_MSG_SENDING) + return 0; + if (_acked < _ack) { + return 0; + } + if (_sent == _WSbuffer->size()) { + if (_acked == _ack) + _status = WS_MSG_SENT; + return 0; + } + if (_sent > _WSbuffer->size()) { + _status = WS_MSG_ERROR; + // ets_printf("E: %u > %u\n", _sent, _WSbuffer->length()); + return 0; + } - size_t toSend = _WSbuffer->size() - _sent; - size_t window = webSocketSendFrameWindow(client); + size_t toSend = _WSbuffer->size() - _sent; + size_t window = webSocketSendFrameWindow(client); - if (window < toSend) { - toSend = window; - } + if (window < toSend) { + toSend = window; + } - _sent += toSend; - _ack += toSend + ((toSend < 126)?2:4) + (_mask * 4); + _sent += toSend; + _ack += toSend + ((toSend < 126) ? 2 : 4) + (_mask * 4); - //ets_printf("W: %u %u\n", _sent - toSend, toSend); + // ets_printf("W: %u %u\n", _sent - toSend, toSend); - bool final = (_sent == _WSbuffer->size()); - uint8_t* dPtr = (uint8_t*)(_WSbuffer->data() + (_sent - toSend)); - uint8_t opCode = (toSend && _sent == toSend)?_opcode:(uint8_t)WS_CONTINUATION; + bool final = (_sent == _WSbuffer->size()); + uint8_t* dPtr = (uint8_t*)(_WSbuffer->data() + (_sent - toSend)); + uint8_t opCode = (toSend && _sent == toSend) ? _opcode : (uint8_t)WS_CONTINUATION; - size_t sent = webSocketSendFrame(client, final, opCode, _mask, dPtr, toSend); - _status = WS_MSG_SENDING; - if (toSend && sent != toSend){ - //ets_printf("E: %u != %u\n", toSend, sent); - _sent -= (toSend - sent); - _ack -= (toSend - sent); - } - //ets_printf("S: %u %u\n", _sent, sent); - return sent; + size_t sent = webSocketSendFrame(client, final, opCode, _mask, dPtr, toSend); + _status = WS_MSG_SENDING; + if (toSend && sent != toSend) { + // ets_printf("E: %u != %u\n", toSend, sent); + _sent -= (toSend - sent); + _ack -= (toSend - sent); + } + // ets_printf("S: %u %u\n", _sent, sent); + return sent; } - /* * Async WebSocket Client */ - const char * AWSC_PING_PAYLOAD = "ESPAsyncWebServer-PING"; - const size_t AWSC_PING_PAYLOAD_LEN = 22; - -AsyncWebSocketClient::AsyncWebSocketClient(AsyncWebServerRequest *request, AsyncWebSocket *server) - : _tempObject(NULL) -{ - _client = request->client(); - _server = server; - _clientId = _server->_getNextId(); - _status = WS_CONNECTED; - _pstate = 0; - _lastMessageTime = millis(); - _keepAlivePeriod = 0; - _client->setRxTimeout(0); - _client->onError([](void *r, AsyncClient* c, int8_t error){ (void)c; ((AsyncWebSocketClient*)(r))->_onError(error); }, this); - _client->onAck([](void *r, AsyncClient* c, size_t len, uint32_t time){ (void)c; ((AsyncWebSocketClient*)(r))->_onAck(len, time); }, this); - _client->onDisconnect([](void *r, AsyncClient* c){ ((AsyncWebSocketClient*)(r))->_onDisconnect(); delete c; }, this); - _client->onTimeout([](void *r, AsyncClient* c, uint32_t time){ (void)c; ((AsyncWebSocketClient*)(r))->_onTimeout(time); }, this); - _client->onData([](void *r, AsyncClient* c, void *buf, size_t len){ (void)c; ((AsyncWebSocketClient*)(r))->_onData(buf, len); }, this); - _client->onPoll([](void *r, AsyncClient* c){ (void)c; ((AsyncWebSocketClient*)(r))->_onPoll(); }, this); - _server->_handleEvent(this, WS_EVT_CONNECT, request, NULL, 0); - delete request; - memset(&_pinfo,0,sizeof(_pinfo)); -} - -AsyncWebSocketClient::~AsyncWebSocketClient() -{ - { - #ifdef ESP32 - std::lock_guard lock(_lock); - #endif - _messageQueue.clear(); - _controlQueue.clear(); - } - _server->_handleEvent(this, WS_EVT_DISCONNECT, NULL, NULL, 0); +const char* AWSC_PING_PAYLOAD = "ESPAsyncWebServer-PING"; +const size_t AWSC_PING_PAYLOAD_LEN = 22; + +AsyncWebSocketClient::AsyncWebSocketClient(AsyncWebServerRequest* request, AsyncWebSocket* server) + : _tempObject(NULL) { + _client = request->client(); + _server = server; + _clientId = _server->_getNextId(); + _status = WS_CONNECTED; + _pstate = 0; + _lastMessageTime = millis(); + _keepAlivePeriod = 0; + _client->setRxTimeout(0); + _client->onError([](void* r, AsyncClient* c, int8_t error) { (void)c; ((AsyncWebSocketClient*)(r))->_onError(error); }, this); + _client->onAck([](void* r, AsyncClient* c, size_t len, uint32_t time) { (void)c; ((AsyncWebSocketClient*)(r))->_onAck(len, time); }, this); + _client->onDisconnect([](void* r, AsyncClient* c) { ((AsyncWebSocketClient*)(r))->_onDisconnect(); delete c; }, this); + _client->onTimeout([](void* r, AsyncClient* c, uint32_t time) { (void)c; ((AsyncWebSocketClient*)(r))->_onTimeout(time); }, this); + _client->onData([](void* r, AsyncClient* c, void* buf, size_t len) { (void)c; ((AsyncWebSocketClient*)(r))->_onData(buf, len); }, this); + _client->onPoll([](void* r, AsyncClient* c) { (void)c; ((AsyncWebSocketClient*)(r))->_onPoll(); }, this); + _server->_handleEvent(this, WS_EVT_CONNECT, request, NULL, 0); + delete request; + memset(&_pinfo, 0, sizeof(_pinfo)); +} + +AsyncWebSocketClient::~AsyncWebSocketClient() { + { +#ifdef ESP32 + std::lock_guard lock(_lock); +#endif + _messageQueue.clear(); + _controlQueue.clear(); + } + _server->_handleEvent(this, WS_EVT_DISCONNECT, NULL, NULL, 0); } -void AsyncWebSocketClient::_clearQueue() -{ - while (!_messageQueue.empty() && _messageQueue.front().finished()) - _messageQueue.pop_front(); +void AsyncWebSocketClient::_clearQueue() { + while (!_messageQueue.empty() && _messageQueue.front().finished()) + _messageQueue.pop_front(); } -void AsyncWebSocketClient::_onAck(size_t len, uint32_t time){ - _lastMessageTime = millis(); +void AsyncWebSocketClient::_onAck(size_t len, uint32_t time) { + _lastMessageTime = millis(); - #ifdef ESP32 - std::lock_guard lock(_lock); - #endif - - if (!_controlQueue.empty()) { - auto &head = _controlQueue.front(); - if (head.finished()){ - len -= head.len(); - if (_status == WS_DISCONNECTING && head.opcode() == WS_DISCONNECT){ - _controlQueue.pop_front(); - _status = WS_DISCONNECTED; - if (_client) _client->close(true); - return; - } - _controlQueue.pop_front(); - } - } +#ifdef ESP32 + std::lock_guard lock(_lock); +#endif - if(len && !_messageQueue.empty()){ - _messageQueue.front().ack(len, time); + if (!_controlQueue.empty()) { + auto& head = _controlQueue.front(); + if (head.finished()) { + len -= head.len(); + if (_status == WS_DISCONNECTING && head.opcode() == WS_DISCONNECT) { + _controlQueue.pop_front(); + _status = WS_DISCONNECTED; + if (_client) + _client->close(true); + return; + } + _controlQueue.pop_front(); } + } + + if (len && !_messageQueue.empty()) { + _messageQueue.front().ack(len, time); + } - _clearQueue(); + _clearQueue(); - _runQueue(); + _runQueue(); } -void AsyncWebSocketClient::_onPoll() -{ - if (!_client) - return; +void AsyncWebSocketClient::_onPoll() { + if (!_client) + return; - #ifdef ESP32 - std::unique_lock lock(_lock); - #endif - if (_client->canSend() && (!_controlQueue.empty() || !_messageQueue.empty())) - { - _runQueue(); - } - else if (_keepAlivePeriod > 0 && (millis() - _lastMessageTime) >= _keepAlivePeriod && (_controlQueue.empty() && _messageQueue.empty())) - { #ifdef ESP32 - lock.unlock(); + std::unique_lock lock(_lock); #endif - ping((uint8_t *)AWSC_PING_PAYLOAD, AWSC_PING_PAYLOAD_LEN); - } + if (_client->canSend() && (!_controlQueue.empty() || !_messageQueue.empty())) { + _runQueue(); + } else if (_keepAlivePeriod > 0 && (millis() - _lastMessageTime) >= _keepAlivePeriod && (_controlQueue.empty() && _messageQueue.empty())) { +#ifdef ESP32 + lock.unlock(); +#endif + ping((uint8_t*)AWSC_PING_PAYLOAD, AWSC_PING_PAYLOAD_LEN); + } } -void AsyncWebSocketClient::_runQueue() -{ - // all calls to this method MUST be protected by a mutex lock! - if (!_client) - return; +void AsyncWebSocketClient::_runQueue() { + // all calls to this method MUST be protected by a mutex lock! + if (!_client) + return; - _clearQueue(); + _clearQueue(); - if (!_controlQueue.empty() && (_messageQueue.empty() || _messageQueue.front().betweenFrames()) && webSocketSendFrameWindow(_client) > (size_t)(_controlQueue.front().len() - 1)) - { - _controlQueue.front().send(_client); - } - else if (!_messageQueue.empty() && _messageQueue.front().betweenFrames() && webSocketSendFrameWindow(_client)) - { - _messageQueue.front().send(_client); - } + if (!_controlQueue.empty() && (_messageQueue.empty() || _messageQueue.front().betweenFrames()) && webSocketSendFrameWindow(_client) > (size_t)(_controlQueue.front().len() - 1)) { + _controlQueue.front().send(_client); + } else if (!_messageQueue.empty() && _messageQueue.front().betweenFrames() && webSocketSendFrameWindow(_client)) { + _messageQueue.front().send(_client); + } } -bool AsyncWebSocketClient::queueIsFull() const -{ - #ifdef ESP32 - std::lock_guard lock(_lock); - #endif - size_t size = _messageQueue.size();; - return (size >= WS_MAX_QUEUED_MESSAGES) || (_status != WS_CONNECTED); +bool AsyncWebSocketClient::queueIsFull() const { +#ifdef ESP32 + std::lock_guard lock(_lock); +#endif + size_t size = _messageQueue.size(); + ; + return (size >= WS_MAX_QUEUED_MESSAGES) || (_status != WS_CONNECTED); } -size_t AsyncWebSocketClient::queueLen() const -{ - #ifdef ESP32 - std::lock_guard lock(_lock); - #endif +size_t AsyncWebSocketClient::queueLen() const { +#ifdef ESP32 + std::lock_guard lock(_lock); +#endif - return _messageQueue.size() + _controlQueue.size(); + return _messageQueue.size() + _controlQueue.size(); } -bool AsyncWebSocketClient::canSend() const -{ - #ifdef ESP32 - std::lock_guard lock(_lock); - #endif - return _messageQueue.size() < WS_MAX_QUEUED_MESSAGES; +bool AsyncWebSocketClient::canSend() const { +#ifdef ESP32 + std::lock_guard lock(_lock); +#endif + return _messageQueue.size() < WS_MAX_QUEUED_MESSAGES; } -void AsyncWebSocketClient::_queueControl(uint8_t opcode, const uint8_t *data, size_t len, bool mask) -{ - if (!_client) - return; +void AsyncWebSocketClient::_queueControl(uint8_t opcode, const uint8_t* data, size_t len, bool mask) { + if (!_client) + return; - { - #ifdef ESP32 - std::lock_guard lock(_lock); - #endif - _controlQueue.emplace_back(opcode, data, len, mask); - } + { +#ifdef ESP32 + std::lock_guard lock(_lock); +#endif + _controlQueue.emplace_back(opcode, data, len, mask); + } - if (_client && _client->canSend()) - _runQueue(); + if (_client && _client->canSend()) + _runQueue(); } -void AsyncWebSocketClient::_queueMessage(AsyncWebSocketSharedBuffer buffer, uint8_t opcode, bool mask) -{ - if(!_client || buffer->size() == 0 || _status != WS_CONNECTED) - return; +void AsyncWebSocketClient::_queueMessage(AsyncWebSocketSharedBuffer buffer, uint8_t opcode, bool mask) { + if (!_client || buffer->size() == 0 || _status != WS_CONNECTED) + return; - #ifdef ESP32 - std::lock_guard lock(_lock); - #endif - if (_messageQueue.size() >= WS_MAX_QUEUED_MESSAGES) - { - if(closeWhenFull) - { +#ifdef ESP32 + std::lock_guard lock(_lock); +#endif + if (_messageQueue.size() >= WS_MAX_QUEUED_MESSAGES) { + if (closeWhenFull) { #ifdef ESP8266 - ets_printf("AsyncWebSocketClient::_queueMessage: Too many messages queued: closing connection\n"); + ets_printf("AsyncWebSocketClient::_queueMessage: Too many messages queued: closing connection\n"); #else - log_e("Too many messages queued: closing connection"); + log_e("Too many messages queued: closing connection"); #endif - _status = WS_DISCONNECTED; - if (_client) _client->close(true); - } else { + _status = WS_DISCONNECTED; + if (_client) + _client->close(true); + } else { #ifdef ESP8266 - ets_printf("AsyncWebSocketClient::_queueMessage: Too many messages queued: discarding new message\n"); + ets_printf("AsyncWebSocketClient::_queueMessage: Too many messages queued: discarding new message\n"); #else - log_e("Too many messages queued: discarding new message"); + log_e("Too many messages queued: discarding new message"); #endif - } - return; - } - else { - _messageQueue.emplace_back(buffer, opcode, mask); } + return; + } else { + _messageQueue.emplace_back(buffer, opcode, mask); + } - if (_client && _client->canSend()) - _runQueue(); + if (_client && _client->canSend()) + _runQueue(); } -void AsyncWebSocketClient::close(uint16_t code, const char * message) -{ - if(_status != WS_CONNECTED) - return; +void AsyncWebSocketClient::close(uint16_t code, const char* message) { + if (_status != WS_CONNECTED) + return; - if(code) - { - uint8_t packetLen = 2; - if (message != NULL) - { - size_t mlen = strlen(message); - if(mlen > 123) mlen = 123; - packetLen += mlen; - } - char * buf = (char*)malloc(packetLen); - if (buf != NULL) - { - buf[0] = (uint8_t)(code >> 8); - buf[1] = (uint8_t)(code & 0xFF); - if(message != NULL){ - memcpy(buf+2, message, packetLen -2); - } - _queueControl(WS_DISCONNECT, (uint8_t*)buf, packetLen); - free(buf); - return; - } + if (code) { + uint8_t packetLen = 2; + if (message != NULL) { + size_t mlen = strlen(message); + if (mlen > 123) + mlen = 123; + packetLen += mlen; + } + char* buf = (char*)malloc(packetLen); + if (buf != NULL) { + buf[0] = (uint8_t)(code >> 8); + buf[1] = (uint8_t)(code & 0xFF); + if (message != NULL) { + memcpy(buf + 2, message, packetLen - 2); + } + _queueControl(WS_DISCONNECT, (uint8_t*)buf, packetLen); + free(buf); + return; } - _queueControl(WS_DISCONNECT); + } + _queueControl(WS_DISCONNECT); } -void AsyncWebSocketClient::ping(const uint8_t *data, size_t len) -{ - if (_status == WS_CONNECTED) - _queueControl(WS_PING, data, len); +void AsyncWebSocketClient::ping(const uint8_t* data, size_t len) { + if (_status == WS_CONNECTED) + _queueControl(WS_PING, data, len); } -void AsyncWebSocketClient::_onError(int8_t) -{ - //Serial.println("onErr"); +void AsyncWebSocketClient::_onError(int8_t) { + // Serial.println("onErr"); } -void AsyncWebSocketClient::_onTimeout(uint32_t time) -{ - // Serial.println("onTime"); - (void)time; - _client->close(true); +void AsyncWebSocketClient::_onTimeout(uint32_t time) { + // Serial.println("onTime"); + (void)time; + _client->close(true); } -void AsyncWebSocketClient::_onDisconnect() -{ - // Serial.println("onDis"); - _client = NULL; +void AsyncWebSocketClient::_onDisconnect() { + // Serial.println("onDis"); + _client = NULL; } -void AsyncWebSocketClient::_onData(void *pbuf, size_t plen) -{ +void AsyncWebSocketClient::_onData(void* pbuf, size_t plen) { // Serial.println("onData"); _lastMessageTime = millis(); - uint8_t *data = (uint8_t*)pbuf; - while(plen > 0){ - if(!_pstate){ - const uint8_t *fdata = data; + uint8_t* data = (uint8_t*)pbuf; + while (plen > 0) { + if (!_pstate) { + const uint8_t* fdata = data; _pinfo.index = 0; _pinfo.final = (fdata[0] & 0x80) != 0; _pinfo.opcode = fdata[0] & 0x0F; @@ -545,17 +500,17 @@ void AsyncWebSocketClient::_onData(void *pbuf, size_t plen) _pinfo.len = fdata[1] & 0x7F; data += 2; plen -= 2; - if(_pinfo.len == 126){ + if (_pinfo.len == 126) { _pinfo.len = fdata[3] | (uint16_t)(fdata[2]) << 8; data += 2; plen -= 2; - } else if(_pinfo.len == 127){ + } else if (_pinfo.len == 127) { _pinfo.len = fdata[9] | (uint16_t)(fdata[8]) << 8 | (uint32_t)(fdata[7]) << 16 | (uint32_t)(fdata[6]) << 24 | (uint64_t)(fdata[5]) << 32 | (uint64_t)(fdata[4]) << 40 | (uint64_t)(fdata[3]) << 48 | (uint64_t)(fdata[2]) << 56; data += 8; plen -= 8; } - if(_pinfo.masked){ + if (_pinfo.masked) { memcpy(_pinfo.mask, data, 4); data += 4; plen -= 4; @@ -565,34 +520,35 @@ void AsyncWebSocketClient::_onData(void *pbuf, size_t plen) const size_t datalen = std::min((size_t)(_pinfo.len - _pinfo.index), plen); const auto datalast = data[datalen]; - if(_pinfo.masked){ - for(size_t i=0;i 0) _server->_handleEvent(this, WS_EVT_DATA, (void *)&_pinfo, (uint8_t*)data, datalen); + if (datalen > 0) + _server->_handleEvent(this, WS_EVT_DATA, (void*)&_pinfo, (uint8_t*)data, datalen); _pinfo.index += datalen; - } else if((datalen + _pinfo.index) == _pinfo.len){ + } else if ((datalen + _pinfo.index) == _pinfo.len) { _pstate = 0; - if(_pinfo.opcode == WS_DISCONNECT){ - if(datalen){ + if (_pinfo.opcode == WS_DISCONNECT) { + if (datalen) { uint16_t reasonCode = (uint16_t)(data[0] << 8) + data[1]; - char * reasonString = (char*)(data+2); - if(reasonCode > 1001){ - _server->_handleEvent(this, WS_EVT_ERROR, (void *)&reasonCode, (uint8_t*)reasonString, strlen(reasonString)); + char* reasonString = (char*)(data + 2); + if (reasonCode > 1001) { + _server->_handleEvent(this, WS_EVT_ERROR, (void*)&reasonCode, (uint8_t*)reasonString, strlen(reasonString)); } } - if(_status == WS_DISCONNECTING){ + if (_status == WS_DISCONNECTING) { _status = WS_DISCONNECTED; _client->close(true); } else { @@ -600,19 +556,21 @@ void AsyncWebSocketClient::_onData(void *pbuf, size_t plen) _client->ackLater(); _queueControl(WS_DISCONNECT, data, datalen); } - } else if(_pinfo.opcode == WS_PING){ + } else if (_pinfo.opcode == WS_PING) { _queueControl(WS_PONG, data, datalen); - } else if(_pinfo.opcode == WS_PONG){ - if(datalen != AWSC_PING_PAYLOAD_LEN || memcmp(AWSC_PING_PAYLOAD, data, AWSC_PING_PAYLOAD_LEN) != 0) + } else if (_pinfo.opcode == WS_PONG) { + if (datalen != AWSC_PING_PAYLOAD_LEN || memcmp(AWSC_PING_PAYLOAD, data, AWSC_PING_PAYLOAD_LEN) != 0) _server->_handleEvent(this, WS_EVT_PONG, NULL, data, datalen); - } else if(_pinfo.opcode < 8){//continuation or text/binary frame - _server->_handleEvent(this, WS_EVT_DATA, (void *)&_pinfo, data, datalen); - if (_pinfo.final) _pinfo.num = 0; - else _pinfo.num += 1; + } else if (_pinfo.opcode < 8) { // continuation or text/binary frame + _server->_handleEvent(this, WS_EVT_DATA, (void*)&_pinfo, data, datalen); + if (_pinfo.final) + _pinfo.num = 0; + else + _pinfo.num += 1; } } else { - //os_printf("frame error: len: %u, index: %llu, total: %llu\n", datalen, _pinfo.index, _pinfo.len); - //what should we do? + // os_printf("frame error: len: %u, index: %llu, total: %llu\n", datalen, _pinfo.index, _pinfo.len); + // what should we do? break; } @@ -625,12 +583,11 @@ void AsyncWebSocketClient::_onData(void *pbuf, size_t plen) } } -size_t AsyncWebSocketClient::printf(const char *format, ...) -{ +size_t AsyncWebSocketClient::printf(const char* format, ...) { va_list arg; va_start(arg, format); char* temp = new char[MAX_PRINTF_LEN]; - if(!temp){ + if (!temp) { va_end(arg); return 0; } @@ -641,7 +598,7 @@ size_t AsyncWebSocketClient::printf(const char *format, ...) if (len > (MAX_PRINTF_LEN - 1)) { buffer = new char[len + 1]; if (!buffer) { - delete[] temp; + delete[] temp; return 0; } va_start(arg, format); @@ -657,12 +614,11 @@ size_t AsyncWebSocketClient::printf(const char *format, ...) } #ifndef ESP32 -size_t AsyncWebSocketClient::printf_P(PGM_P formatP, ...) -{ +size_t AsyncWebSocketClient::printf_P(PGM_P formatP, ...) { va_list arg; va_start(arg, formatP); char* temp = new char[MAX_PRINTF_LEN]; - if(!temp){ + if (!temp) { va_end(arg); return 0; } @@ -673,7 +629,7 @@ size_t AsyncWebSocketClient::printf_P(PGM_P formatP, ...) if (len > (MAX_PRINTF_LEN - 1)) { buffer = new char[len + 1]; if (!buffer) { - delete[] temp; + delete[] temp; return 0; } va_start(arg, formatP); @@ -690,453 +646,381 @@ size_t AsyncWebSocketClient::printf_P(PGM_P formatP, ...) #endif namespace { -AsyncWebSocketSharedBuffer makeSharedBuffer(const uint8_t *message, size_t len) -{ + AsyncWebSocketSharedBuffer makeSharedBuffer(const uint8_t* message, size_t len) { auto buffer = std::make_shared>(len); std::memcpy(buffer->data(), message, len); return buffer; -} + } } -void AsyncWebSocketClient::text(AsyncWebSocketMessageBuffer * buffer) -{ - if (buffer) { - text(std::move(buffer->_buffer)); - delete buffer; - } +void AsyncWebSocketClient::text(AsyncWebSocketMessageBuffer* buffer) { + if (buffer) { + text(std::move(buffer->_buffer)); + delete buffer; + } } -void AsyncWebSocketClient::text(AsyncWebSocketSharedBuffer buffer) -{ - _queueMessage(buffer); +void AsyncWebSocketClient::text(AsyncWebSocketSharedBuffer buffer) { + _queueMessage(buffer); } -void AsyncWebSocketClient::text(const uint8_t *message, size_t len) -{ - text(makeSharedBuffer(message, len)); +void AsyncWebSocketClient::text(const uint8_t* message, size_t len) { + text(makeSharedBuffer(message, len)); } -void AsyncWebSocketClient::text(const char *message, size_t len) -{ - text((const uint8_t *)message, len); +void AsyncWebSocketClient::text(const char* message, size_t len) { + text((const uint8_t*)message, len); } -void AsyncWebSocketClient::text(const char *message) -{ - text(message, strlen(message)); +void AsyncWebSocketClient::text(const char* message) { + text(message, strlen(message)); } -void AsyncWebSocketClient::text(const String &message) -{ - text(message.c_str(), message.length()); +void AsyncWebSocketClient::text(const String& message) { + text(message.c_str(), message.length()); } #ifndef ESP32 -void AsyncWebSocketClient::text(const __FlashStringHelper *data) -{ - PGM_P p = reinterpret_cast(data); - - size_t n = 0; - while (1) - { - if (pgm_read_byte(p+n) == 0) break; - n += 1; - } +void AsyncWebSocketClient::text(const __FlashStringHelper* data) { + PGM_P p = reinterpret_cast(data); - char * message = (char*) malloc(n+1); - if(message) - { - memcpy_P(message, p, n); - message[n] = 0; - text(message, n); - free(message); - } + size_t n = 0; + while (1) { + if (pgm_read_byte(p + n) == 0) + break; + n += 1; + } + + char* message = (char*)malloc(n + 1); + if (message) { + memcpy_P(message, p, n); + message[n] = 0; + text(message, n); + free(message); + } } -#endif // ESP32 +#endif // ESP32 -void AsyncWebSocketClient::binary(AsyncWebSocketMessageBuffer * buffer) -{ - if (buffer) { - binary(std::move(buffer->_buffer)); - delete buffer; - } +void AsyncWebSocketClient::binary(AsyncWebSocketMessageBuffer* buffer) { + if (buffer) { + binary(std::move(buffer->_buffer)); + delete buffer; + } } -void AsyncWebSocketClient::binary(AsyncWebSocketSharedBuffer buffer) -{ - _queueMessage(buffer, WS_BINARY); +void AsyncWebSocketClient::binary(AsyncWebSocketSharedBuffer buffer) { + _queueMessage(buffer, WS_BINARY); } -void AsyncWebSocketClient::binary(const uint8_t *message, size_t len) -{ - binary(makeSharedBuffer(message, len)); +void AsyncWebSocketClient::binary(const uint8_t* message, size_t len) { + binary(makeSharedBuffer(message, len)); } -void AsyncWebSocketClient::binary(const char *message, size_t len) -{ - binary((const uint8_t *)message, len); +void AsyncWebSocketClient::binary(const char* message, size_t len) { + binary((const uint8_t*)message, len); } -void AsyncWebSocketClient::binary(const char *message) -{ - binary(message, strlen(message)); +void AsyncWebSocketClient::binary(const char* message) { + binary(message, strlen(message)); } -void AsyncWebSocketClient::binary(const String &message) -{ - binary(message.c_str(), message.length()); +void AsyncWebSocketClient::binary(const String& message) { + binary(message.c_str(), message.length()); } #ifndef ESP32 -void AsyncWebSocketClient::binary(const __FlashStringHelper *data, size_t len) -{ - PGM_P p = reinterpret_cast(data); - char *message = (char*) malloc(len); - if (message) { - memcpy_P(message, p, len); - binary(message, len); - free(message); - } +void AsyncWebSocketClient::binary(const __FlashStringHelper* data, size_t len) { + PGM_P p = reinterpret_cast(data); + char* message = (char*)malloc(len); + if (message) { + memcpy_P(message, p, len); + binary(message, len); + free(message); + } } #endif -IPAddress AsyncWebSocketClient::remoteIP() const -{ - if (!_client) - return IPAddress((uint32_t)0U); +IPAddress AsyncWebSocketClient::remoteIP() const { + if (!_client) + return IPAddress((uint32_t)0U); - return _client->remoteIP(); + return _client->remoteIP(); } -uint16_t AsyncWebSocketClient::remotePort() const -{ - if(!_client) - return 0; +uint16_t AsyncWebSocketClient::remotePort() const { + if (!_client) + return 0; - return _client->remotePort(); + return _client->remotePort(); } - - /* * Async Web Socket - Each separate socket location */ -void AsyncWebSocket::_handleEvent(AsyncWebSocketClient * client, AwsEventType type, void * arg, uint8_t *data, size_t len){ - if(_eventHandler != NULL){ +void AsyncWebSocket::_handleEvent(AsyncWebSocketClient* client, AwsEventType type, void* arg, uint8_t* data, size_t len) { + if (_eventHandler != NULL) { _eventHandler(this, client, type, arg, data, len); } } -AsyncWebSocketClient *AsyncWebSocket::_newClient(AsyncWebServerRequest *request) -{ - _clients.emplace_back(request, this); - return &_clients.back(); +AsyncWebSocketClient* AsyncWebSocket::_newClient(AsyncWebServerRequest* request) { + _clients.emplace_back(request, this); + return &_clients.back(); } -bool AsyncWebSocket::availableForWriteAll() -{ - return std::none_of(std::begin(_clients), std::end(_clients), - [](const AsyncWebSocketClient &c){ return c.queueIsFull(); }); +bool AsyncWebSocket::availableForWriteAll() { + return std::none_of(std::begin(_clients), std::end(_clients), [](const AsyncWebSocketClient& c) { return c.queueIsFull(); }); } -bool AsyncWebSocket::availableForWrite(uint32_t id) -{ - const auto iter = std::find_if(std::begin(_clients), std::end(_clients), - [id](const AsyncWebSocketClient &c){ return c.id() == id; }); - if (iter == std::end(_clients)) - return true; - return !iter->queueIsFull(); +bool AsyncWebSocket::availableForWrite(uint32_t id) { + const auto iter = std::find_if(std::begin(_clients), std::end(_clients), [id](const AsyncWebSocketClient& c) { return c.id() == id; }); + if (iter == std::end(_clients)) + return true; + return !iter->queueIsFull(); } -size_t AsyncWebSocket::count() const -{ - return std::count_if(std::begin(_clients), std::end(_clients), - [](const AsyncWebSocketClient &c){ return c.status() == WS_CONNECTED; }); +size_t AsyncWebSocket::count() const { + return std::count_if(std::begin(_clients), std::end(_clients), [](const AsyncWebSocketClient& c) { return c.status() == WS_CONNECTED; }); } -AsyncWebSocketClient * AsyncWebSocket::client(uint32_t id) -{ - const auto iter = std::find_if(_clients.begin(), _clients.end(), - [id](const AsyncWebSocketClient &c){ return c.id() == id && c.status() == WS_CONNECTED; }); - if (iter == std::end(_clients)) - return nullptr; +AsyncWebSocketClient* AsyncWebSocket::client(uint32_t id) { + const auto iter = std::find_if(_clients.begin(), _clients.end(), [id](const AsyncWebSocketClient& c) { return c.id() == id && c.status() == WS_CONNECTED; }); + if (iter == std::end(_clients)) + return nullptr; - return &(*iter); + return &(*iter); } - -void AsyncWebSocket::close(uint32_t id, uint16_t code, const char * message) -{ - if (AsyncWebSocketClient *c = client(id)) - c->close(code, message); +void AsyncWebSocket::close(uint32_t id, uint16_t code, const char* message) { + if (AsyncWebSocketClient* c = client(id)) + c->close(code, message); } -void AsyncWebSocket::closeAll(uint16_t code, const char * message) -{ - for (auto &c : _clients) - if (c.status() == WS_CONNECTED) - c.close(code, message); +void AsyncWebSocket::closeAll(uint16_t code, const char* message) { + for (auto& c : _clients) + if (c.status() == WS_CONNECTED) + c.close(code, message); } -void AsyncWebSocket::cleanupClients(uint16_t maxClients) -{ - if (count() > maxClients) - _clients.front().close(); +void AsyncWebSocket::cleanupClients(uint16_t maxClients) { + if (count() > maxClients) + _clients.front().close(); - for (auto iter = std::begin(_clients); iter != std::end(_clients);) - { - if (iter->shouldBeDeleted()) - iter = _clients.erase(iter); - else - iter++; - } + for (auto iter = std::begin(_clients); iter != std::end(_clients);) { + if (iter->shouldBeDeleted()) + iter = _clients.erase(iter); + else + iter++; + } } -void AsyncWebSocket::ping(uint32_t id, const uint8_t *data, size_t len) -{ - if (AsyncWebSocketClient * c = client(id)) - c->ping(data, len); +void AsyncWebSocket::ping(uint32_t id, const uint8_t* data, size_t len) { + if (AsyncWebSocketClient* c = client(id)) + c->ping(data, len); } -void AsyncWebSocket::pingAll(const uint8_t *data, size_t len) -{ - for (auto &c : _clients) - if (c.status() == WS_CONNECTED) - c.ping(data, len); +void AsyncWebSocket::pingAll(const uint8_t* data, size_t len) { + for (auto& c : _clients) + if (c.status() == WS_CONNECTED) + c.ping(data, len); } -void AsyncWebSocket::text(uint32_t id, const uint8_t *message, size_t len) -{ - if (AsyncWebSocketClient * c = client(id)) - c->text(makeSharedBuffer(message, len)); +void AsyncWebSocket::text(uint32_t id, const uint8_t* message, size_t len) { + if (AsyncWebSocketClient* c = client(id)) + c->text(makeSharedBuffer(message, len)); } -void AsyncWebSocket::text(uint32_t id, const char *message, size_t len) -{ - text(id, (const uint8_t *)message, len); +void AsyncWebSocket::text(uint32_t id, const char* message, size_t len) { + text(id, (const uint8_t*)message, len); } -void AsyncWebSocket::text(uint32_t id, const char * message) -{ - text(id, message, strlen(message)); +void AsyncWebSocket::text(uint32_t id, const char* message) { + text(id, message, strlen(message)); } -void AsyncWebSocket::text(uint32_t id, const String &message) -{ - text(id, message.c_str(), message.length()); +void AsyncWebSocket::text(uint32_t id, const String& message) { + text(id, message.c_str(), message.length()); } #ifndef ESP32 -void AsyncWebSocket::text(uint32_t id, const __FlashStringHelper *data) -{ - PGM_P p = reinterpret_cast(data); - - size_t n = 0; - while (true) - { - if (pgm_read_byte(p+n) == 0) - break; - n += 1; - } +void AsyncWebSocket::text(uint32_t id, const __FlashStringHelper* data) { + PGM_P p = reinterpret_cast(data); - char * message = (char*) malloc(n+1); - if (message) - { - memcpy_P(message, p, n); - message[n] = 0; - text(id, message, n); - free(message); - } + size_t n = 0; + while (true) { + if (pgm_read_byte(p + n) == 0) + break; + n += 1; + } + + char* message = (char*)malloc(n + 1); + if (message) { + memcpy_P(message, p, n); + message[n] = 0; + text(id, message, n); + free(message); + } } -#endif // ESP32 -void AsyncWebSocket::text(uint32_t id, AsyncWebSocketMessageBuffer *buffer) -{ - if (buffer) { - text(id, std::move(buffer->_buffer)); - delete buffer; - } +#endif // ESP32 +void AsyncWebSocket::text(uint32_t id, AsyncWebSocketMessageBuffer* buffer) { + if (buffer) { + text(id, std::move(buffer->_buffer)); + delete buffer; + } } -void AsyncWebSocket::text(uint32_t id, AsyncWebSocketSharedBuffer buffer) -{ - if (AsyncWebSocketClient *c = client(id)) - c->text(buffer); +void AsyncWebSocket::text(uint32_t id, AsyncWebSocketSharedBuffer buffer) { + if (AsyncWebSocketClient* c = client(id)) + c->text(buffer); } -void AsyncWebSocket::textAll(const uint8_t *message, size_t len) -{ - textAll(makeSharedBuffer(message, len)); +void AsyncWebSocket::textAll(const uint8_t* message, size_t len) { + textAll(makeSharedBuffer(message, len)); } -void AsyncWebSocket::textAll(const char * message, size_t len) -{ - textAll((const uint8_t *)message, len); +void AsyncWebSocket::textAll(const char* message, size_t len) { + textAll((const uint8_t*)message, len); } -void AsyncWebSocket::textAll(const char *message) -{ - textAll(message, strlen(message)); +void AsyncWebSocket::textAll(const char* message) { + textAll(message, strlen(message)); } -void AsyncWebSocket::textAll(const String &message) -{ - textAll(message.c_str(), message.length()); +void AsyncWebSocket::textAll(const String& message) { + textAll(message.c_str(), message.length()); } #ifndef ESP32 -void AsyncWebSocket::textAll(const __FlashStringHelper *data) -{ - PGM_P p = reinterpret_cast(data); - - size_t n = 0; - while (1) - { - if (pgm_read_byte(p+n) == 0) break; - n += 1; - } +void AsyncWebSocket::textAll(const __FlashStringHelper* data) { + PGM_P p = reinterpret_cast(data); - char *message = (char*)malloc(n+1); - if(message) - { - memcpy_P(message, p, n); - message[n] = 0; - textAll(message, n); - free(message); - } + size_t n = 0; + while (1) { + if (pgm_read_byte(p + n) == 0) + break; + n += 1; + } + + char* message = (char*)malloc(n + 1); + if (message) { + memcpy_P(message, p, n); + message[n] = 0; + textAll(message, n); + free(message); + } } -#endif // ESP32 -void AsyncWebSocket::textAll(AsyncWebSocketMessageBuffer * buffer) -{ - if (buffer) { - textAll(std::move(buffer->_buffer)); - delete buffer; - } +#endif // ESP32 +void AsyncWebSocket::textAll(AsyncWebSocketMessageBuffer* buffer) { + if (buffer) { + textAll(std::move(buffer->_buffer)); + delete buffer; + } } -void AsyncWebSocket::textAll(AsyncWebSocketSharedBuffer buffer) -{ - for (auto &c : _clients) - if (c.status() == WS_CONNECTED) - c.text(buffer); +void AsyncWebSocket::textAll(AsyncWebSocketSharedBuffer buffer) { + for (auto& c : _clients) + if (c.status() == WS_CONNECTED) + c.text(buffer); } -void AsyncWebSocket::binary(uint32_t id, const uint8_t *message, size_t len) -{ - if (AsyncWebSocketClient *c = client(id)) - c->binary(makeSharedBuffer(message, len)); +void AsyncWebSocket::binary(uint32_t id, const uint8_t* message, size_t len) { + if (AsyncWebSocketClient* c = client(id)) + c->binary(makeSharedBuffer(message, len)); } -void AsyncWebSocket::binary(uint32_t id, const char * message, size_t len) -{ - binary(id, (const uint8_t *)message, len); +void AsyncWebSocket::binary(uint32_t id, const char* message, size_t len) { + binary(id, (const uint8_t*)message, len); } -void AsyncWebSocket::binary(uint32_t id, const char * message) -{ - binary(id, message, strlen(message)); +void AsyncWebSocket::binary(uint32_t id, const char* message) { + binary(id, message, strlen(message)); } -void AsyncWebSocket::binary(uint32_t id, const String &message) -{ - binary(id, message.c_str(), message.length()); +void AsyncWebSocket::binary(uint32_t id, const String& message) { + binary(id, message.c_str(), message.length()); } #ifndef ESP32 -void AsyncWebSocket::binary(uint32_t id, const __FlashStringHelper *data, size_t len) -{ - PGM_P p = reinterpret_cast(data); - char *message = (char*) malloc(len); - if (message) - { - memcpy_P(message, p, len); - binary(id, message, len); - free(message); - } +void AsyncWebSocket::binary(uint32_t id, const __FlashStringHelper* data, size_t len) { + PGM_P p = reinterpret_cast(data); + char* message = (char*)malloc(len); + if (message) { + memcpy_P(message, p, len); + binary(id, message, len); + free(message); + } } -#endif // ESP32 -void AsyncWebSocket::binary(uint32_t id, AsyncWebSocketMessageBuffer *buffer) -{ - if (buffer) { - binary(id, std::move(buffer->_buffer)); - delete buffer; - } +#endif // ESP32 +void AsyncWebSocket::binary(uint32_t id, AsyncWebSocketMessageBuffer* buffer) { + if (buffer) { + binary(id, std::move(buffer->_buffer)); + delete buffer; + } } -void AsyncWebSocket::binary(uint32_t id, AsyncWebSocketSharedBuffer buffer) -{ - if (AsyncWebSocketClient *c = client(id)) - c->binary(buffer); +void AsyncWebSocket::binary(uint32_t id, AsyncWebSocketSharedBuffer buffer) { + if (AsyncWebSocketClient* c = client(id)) + c->binary(buffer); } - -void AsyncWebSocket::binaryAll(const uint8_t *message, size_t len) -{ - binaryAll(makeSharedBuffer(message, len)); +void AsyncWebSocket::binaryAll(const uint8_t* message, size_t len) { + binaryAll(makeSharedBuffer(message, len)); } -void AsyncWebSocket::binaryAll(const char *message, size_t len) -{ - binaryAll((const uint8_t *)message, len); +void AsyncWebSocket::binaryAll(const char* message, size_t len) { + binaryAll((const uint8_t*)message, len); } -void AsyncWebSocket::binaryAll(const char *message) -{ - binaryAll(message, strlen(message)); +void AsyncWebSocket::binaryAll(const char* message) { + binaryAll(message, strlen(message)); } -void AsyncWebSocket::binaryAll(const String &message) -{ - binaryAll(message.c_str(), message.length()); +void AsyncWebSocket::binaryAll(const String& message) { + binaryAll(message.c_str(), message.length()); } #ifndef ESP32 -void AsyncWebSocket::binaryAll(const __FlashStringHelper *data, size_t len) -{ - PGM_P p = reinterpret_cast(data); - char * message = (char*) malloc(len); - if(message) - { - memcpy_P(message, p, len); - binaryAll(message, len); - free(message); - } +void AsyncWebSocket::binaryAll(const __FlashStringHelper* data, size_t len) { + PGM_P p = reinterpret_cast(data); + char* message = (char*)malloc(len); + if (message) { + memcpy_P(message, p, len); + binaryAll(message, len); + free(message); + } } -#endif // ESP32 -void AsyncWebSocket::binaryAll(AsyncWebSocketMessageBuffer * buffer) -{ - if (buffer) { - binaryAll(std::move(buffer->_buffer)); - delete buffer; - } +#endif // ESP32 +void AsyncWebSocket::binaryAll(AsyncWebSocketMessageBuffer* buffer) { + if (buffer) { + binaryAll(std::move(buffer->_buffer)); + delete buffer; + } } -void AsyncWebSocket::binaryAll(AsyncWebSocketSharedBuffer buffer) -{ - for (auto &c : _clients) - if (c.status() == WS_CONNECTED) - c.binary(buffer); -} - -size_t AsyncWebSocket::printf(uint32_t id, const char *format, ...){ - AsyncWebSocketClient * c = client(id); - if (c) - { - va_list arg; - va_start(arg, format); - size_t len = c->printf(format, arg); - va_end(arg); - return len; - } - return 0; +void AsyncWebSocket::binaryAll(AsyncWebSocketSharedBuffer buffer) { + for (auto& c : _clients) + if (c.status() == WS_CONNECTED) + c.binary(buffer); } -size_t AsyncWebSocket::printfAll(const char *format, ...) -{ +size_t AsyncWebSocket::printf(uint32_t id, const char* format, ...) { + AsyncWebSocketClient* c = client(id); + if (c) { va_list arg; - char *temp = new char[MAX_PRINTF_LEN]; - if (!temp) - return 0; - va_start(arg, format); - size_t len = vsnprintf(temp, MAX_PRINTF_LEN, format, arg); + size_t len = c->printf(format, arg); va_end(arg); - delete[] temp; + return len; + } + return 0; +} - AsyncWebSocketSharedBuffer buffer = std::make_shared>(len); +size_t AsyncWebSocket::printfAll(const char* format, ...) { + va_list arg; + char* temp = new char[MAX_PRINTF_LEN]; + if (!temp) + return 0; - va_start(arg, format); - vsnprintf( (char *)buffer->data(), len + 1, format, arg); - va_end(arg); + va_start(arg, format); + size_t len = vsnprintf(temp, MAX_PRINTF_LEN, format, arg); + va_end(arg); + delete[] temp; - textAll(buffer); - return len; + AsyncWebSocketSharedBuffer buffer = std::make_shared>(len); + + va_start(arg, format); + vsnprintf((char*)buffer->data(), len + 1, format, arg); + va_end(arg); + + textAll(buffer); + return len; } #ifndef ESP32 -size_t AsyncWebSocket::printf_P(uint32_t id, PGM_P formatP, ...){ - AsyncWebSocketClient * c = client(id); - if(c != NULL){ +size_t AsyncWebSocket::printf_P(uint32_t id, PGM_P formatP, ...) { + AsyncWebSocketClient* c = client(id); + if (c != NULL) { va_list arg; va_start(arg, formatP); size_t len = c->printf_P(formatP, arg); @@ -1146,126 +1030,116 @@ size_t AsyncWebSocket::printf_P(uint32_t id, PGM_P formatP, ...){ return 0; } -size_t AsyncWebSocket::printfAll_P(PGM_P formatP, ...) -{ - va_list arg; - char *temp = new char[MAX_PRINTF_LEN]; - if (!temp) - return 0; +size_t AsyncWebSocket::printfAll_P(PGM_P formatP, ...) { + va_list arg; + char* temp = new char[MAX_PRINTF_LEN]; + if (!temp) + return 0; - va_start(arg, formatP); - size_t len = vsnprintf_P(temp, MAX_PRINTF_LEN, formatP, arg); - va_end(arg); - delete[] temp; + va_start(arg, formatP); + size_t len = vsnprintf_P(temp, MAX_PRINTF_LEN, formatP, arg); + va_end(arg); + delete[] temp; - AsyncWebSocketSharedBuffer buffer = std::make_shared>(len + 1); + AsyncWebSocketSharedBuffer buffer = std::make_shared>(len + 1); - va_start(arg, formatP); - vsnprintf_P((char *)buffer->data(), len + 1, formatP, arg); - va_end(arg); + va_start(arg, formatP); + vsnprintf_P((char*)buffer->data(), len + 1, formatP, arg); + va_end(arg); - textAll(buffer); - return len; + textAll(buffer); + return len; } #endif -const char __WS_STR_CONNECTION[] PROGMEM = { "Connection" }; -const char __WS_STR_UPGRADE[] PROGMEM = { "Upgrade" }; -const char __WS_STR_ORIGIN[] PROGMEM = { "Origin" }; -const char __WS_STR_COOKIE[] PROGMEM = { "Cookie" }; -const char __WS_STR_VERSION[] PROGMEM = { "Sec-WebSocket-Version" }; -const char __WS_STR_KEY[] PROGMEM = { "Sec-WebSocket-Key" }; -const char __WS_STR_PROTOCOL[] PROGMEM = { "Sec-WebSocket-Protocol" }; -const char __WS_STR_ACCEPT[] PROGMEM = { "Sec-WebSocket-Accept" }; -const char __WS_STR_UUID[] PROGMEM = { "258EAFA5-E914-47DA-95CA-C5AB0DC85B11" }; +const char __WS_STR_CONNECTION[] PROGMEM = {"Connection"}; +const char __WS_STR_UPGRADE[] PROGMEM = {"Upgrade"}; +const char __WS_STR_ORIGIN[] PROGMEM = {"Origin"}; +const char __WS_STR_COOKIE[] PROGMEM = {"Cookie"}; +const char __WS_STR_VERSION[] PROGMEM = {"Sec-WebSocket-Version"}; +const char __WS_STR_KEY[] PROGMEM = {"Sec-WebSocket-Key"}; +const char __WS_STR_PROTOCOL[] PROGMEM = {"Sec-WebSocket-Protocol"}; +const char __WS_STR_ACCEPT[] PROGMEM = {"Sec-WebSocket-Accept"}; +const char __WS_STR_UUID[] PROGMEM = {"258EAFA5-E914-47DA-95CA-C5AB0DC85B11"}; #define WS_STR_UUID_LEN 36 #define WS_STR_CONNECTION FPSTR(__WS_STR_CONNECTION) -#define WS_STR_UPGRADE FPSTR(__WS_STR_UPGRADE) -#define WS_STR_ORIGIN FPSTR(__WS_STR_ORIGIN) -#define WS_STR_COOKIE FPSTR(__WS_STR_COOKIE) -#define WS_STR_VERSION FPSTR(__WS_STR_VERSION) -#define WS_STR_KEY FPSTR(__WS_STR_KEY) -#define WS_STR_PROTOCOL FPSTR(__WS_STR_PROTOCOL) -#define WS_STR_ACCEPT FPSTR(__WS_STR_ACCEPT) -#define WS_STR_UUID FPSTR(__WS_STR_UUID) - -bool AsyncWebSocket::canHandle(AsyncWebServerRequest *request){ - if(!_enabled) - return false; - - if(request->method() != HTTP_GET || !request->url().equals(_url) || !request->isExpectedRequestedConnType(RCT_WS)) - return false; - - request->addInterestingHeader(WS_STR_CONNECTION); - request->addInterestingHeader(WS_STR_UPGRADE); - request->addInterestingHeader(WS_STR_ORIGIN); - request->addInterestingHeader(WS_STR_COOKIE); - request->addInterestingHeader(WS_STR_VERSION); - request->addInterestingHeader(WS_STR_KEY); - request->addInterestingHeader(WS_STR_PROTOCOL); - return true; -} - -void AsyncWebSocket::handleRequest(AsyncWebServerRequest *request) -{ - if (!request->hasHeader(WS_STR_VERSION) || !request->hasHeader(WS_STR_KEY)) - { - request->send(400); - return; - } - if ((_username.length() && _password.length()) && !request->authenticate(_username.c_str(), _password.c_str())) - { - return request->requestAuthentication(); - } - if (_handshakeHandler != nullptr){ - if(!_handshakeHandler(request)){ - request->send(401); - return; - } - } - const AsyncWebHeader* version = request->getHeader(WS_STR_VERSION); - if (version->value().toInt() != 13) - { - AsyncWebServerResponse *response = request->beginResponse(400); - response->addHeader(WS_STR_VERSION, F("13")); - request->send(response); - return; - } - const AsyncWebHeader* key = request->getHeader(WS_STR_KEY); - AsyncWebServerResponse *response = new AsyncWebSocketResponse(key->value(), this); - if (request->hasHeader(WS_STR_PROTOCOL)) - { - const AsyncWebHeader* protocol = request->getHeader(WS_STR_PROTOCOL); - //ToDo: check protocol - response->addHeader(WS_STR_PROTOCOL, protocol->value()); +#define WS_STR_UPGRADE FPSTR(__WS_STR_UPGRADE) +#define WS_STR_ORIGIN FPSTR(__WS_STR_ORIGIN) +#define WS_STR_COOKIE FPSTR(__WS_STR_COOKIE) +#define WS_STR_VERSION FPSTR(__WS_STR_VERSION) +#define WS_STR_KEY FPSTR(__WS_STR_KEY) +#define WS_STR_PROTOCOL FPSTR(__WS_STR_PROTOCOL) +#define WS_STR_ACCEPT FPSTR(__WS_STR_ACCEPT) +#define WS_STR_UUID FPSTR(__WS_STR_UUID) + +bool AsyncWebSocket::canHandle(AsyncWebServerRequest* request) { + if (!_enabled) + return false; + + if (request->method() != HTTP_GET || !request->url().equals(_url) || !request->isExpectedRequestedConnType(RCT_WS)) + return false; + + request->addInterestingHeader(WS_STR_CONNECTION); + request->addInterestingHeader(WS_STR_UPGRADE); + request->addInterestingHeader(WS_STR_ORIGIN); + request->addInterestingHeader(WS_STR_COOKIE); + request->addInterestingHeader(WS_STR_VERSION); + request->addInterestingHeader(WS_STR_KEY); + request->addInterestingHeader(WS_STR_PROTOCOL); + return true; +} + +void AsyncWebSocket::handleRequest(AsyncWebServerRequest* request) { + if (!request->hasHeader(WS_STR_VERSION) || !request->hasHeader(WS_STR_KEY)) { + request->send(400); + return; + } + if ((_username.length() && _password.length()) && !request->authenticate(_username.c_str(), _password.c_str())) { + return request->requestAuthentication(); + } + if (_handshakeHandler != nullptr) { + if (!_handshakeHandler(request)) { + request->send(401); + return; } + } + const AsyncWebHeader* version = request->getHeader(WS_STR_VERSION); + if (version->value().toInt() != 13) { + AsyncWebServerResponse* response = request->beginResponse(400); + response->addHeader(WS_STR_VERSION, F("13")); request->send(response); + return; + } + const AsyncWebHeader* key = request->getHeader(WS_STR_KEY); + AsyncWebServerResponse* response = new AsyncWebSocketResponse(key->value(), this); + if (request->hasHeader(WS_STR_PROTOCOL)) { + const AsyncWebHeader* protocol = request->getHeader(WS_STR_PROTOCOL); + // ToDo: check protocol + response->addHeader(WS_STR_PROTOCOL, protocol->value()); + } + request->send(response); } -AsyncWebSocketMessageBuffer * AsyncWebSocket::makeBuffer(size_t size) -{ - AsyncWebSocketMessageBuffer * buffer = new AsyncWebSocketMessageBuffer(size); - if (buffer->length() != size) - { - delete buffer; - return nullptr; - } else { - return buffer; - } +AsyncWebSocketMessageBuffer* AsyncWebSocket::makeBuffer(size_t size) { + AsyncWebSocketMessageBuffer* buffer = new AsyncWebSocketMessageBuffer(size); + if (buffer->length() != size) { + delete buffer; + return nullptr; + } else { + return buffer; + } } -AsyncWebSocketMessageBuffer * AsyncWebSocket::makeBuffer(const uint8_t * data, size_t size) -{ - AsyncWebSocketMessageBuffer * buffer = new AsyncWebSocketMessageBuffer(data, size); - if (buffer->length() != size) - { - delete buffer; - return nullptr; - } else { - return buffer; - } +AsyncWebSocketMessageBuffer* AsyncWebSocket::makeBuffer(const uint8_t* data, size_t size) { + AsyncWebSocketMessageBuffer* buffer = new AsyncWebSocketMessageBuffer(data, size); + if (buffer->length() != size) { + delete buffer; + return nullptr; + } else { + return buffer; + } } /* @@ -1273,55 +1147,51 @@ AsyncWebSocketMessageBuffer * AsyncWebSocket::makeBuffer(const uint8_t * data, s * Authentication code from https://github.com/Links2004/arduinoWebSockets/blob/master/src/WebSockets.cpp#L480 */ -AsyncWebSocketResponse::AsyncWebSocketResponse(const String& key, AsyncWebSocket *server) -{ - _server = server; - _code = 101; - _sendContentLength = false; +AsyncWebSocketResponse::AsyncWebSocketResponse(const String& key, AsyncWebSocket* server) { + _server = server; + _code = 101; + _sendContentLength = false; - uint8_t hash[20]; - char buffer[33]; + uint8_t hash[20]; + char buffer[33]; #ifdef ESP8266 - sha1(key + WS_STR_UUID, hash); + sha1(key + WS_STR_UUID, hash); #else - String k; - k.reserve(key.length() + WS_STR_UUID_LEN); - k.concat(key); - k.concat(WS_STR_UUID); - SHA1Builder sha1; - sha1.begin(); - sha1.add((const uint8_t*)k.c_str(), k.length()); - sha1.calculate(); - sha1.getBytes(hash); + String k; + k.reserve(key.length() + WS_STR_UUID_LEN); + k.concat(key); + k.concat(WS_STR_UUID); + SHA1Builder sha1; + sha1.begin(); + sha1.add((const uint8_t*)k.c_str(), k.length()); + sha1.calculate(); + sha1.getBytes(hash); #endif - base64_encodestate _state; - base64_init_encodestate(&_state); - int len = base64_encode_block((const char *) hash, 20, buffer, &_state); - len = base64_encode_blockend((buffer + len), &_state); - addHeader(WS_STR_CONNECTION, WS_STR_UPGRADE); - addHeader(WS_STR_UPGRADE, F("websocket")); - addHeader(WS_STR_ACCEPT,buffer); -} - -void AsyncWebSocketResponse::_respond(AsyncWebServerRequest *request) -{ - if(_state == RESPONSE_FAILED) - { - request->client()->close(true); - return; - } - String out(_assembleHead(request->version())); - request->client()->write(out.c_str(), _headLength); - _state = RESPONSE_WAIT_ACK; + base64_encodestate _state; + base64_init_encodestate(&_state); + int len = base64_encode_block((const char*)hash, 20, buffer, &_state); + len = base64_encode_blockend((buffer + len), &_state); + addHeader(WS_STR_CONNECTION, WS_STR_UPGRADE); + addHeader(WS_STR_UPGRADE, F("websocket")); + addHeader(WS_STR_ACCEPT, buffer); +} + +void AsyncWebSocketResponse::_respond(AsyncWebServerRequest* request) { + if (_state == RESPONSE_FAILED) { + request->client()->close(true); + return; + } + String out(_assembleHead(request->version())); + request->client()->write(out.c_str(), _headLength); + _state = RESPONSE_WAIT_ACK; } -size_t AsyncWebSocketResponse::_ack(AsyncWebServerRequest *request, size_t len, uint32_t time) -{ - (void)time; +size_t AsyncWebSocketResponse::_ack(AsyncWebServerRequest* request, size_t len, uint32_t time) { + (void)time; - if(len) - _server->_newClient(request); + if (len) + _server->_newClient(request); - return 0; + return 0; } diff --git a/src/AsyncWebSocket.h b/src/AsyncWebSocket.h index 8b7eca9f6..10e9537fd 100644 --- a/src/AsyncWebSocket.h +++ b/src/AsyncWebSocket.h @@ -23,37 +23,36 @@ #include #ifdef ESP32 -#include -#include -#ifndef WS_MAX_QUEUED_MESSAGES -#define WS_MAX_QUEUED_MESSAGES 32 -#endif + #include + #include + #ifndef WS_MAX_QUEUED_MESSAGES + #define WS_MAX_QUEUED_MESSAGES 32 + #endif #else -#include -#ifndef WS_MAX_QUEUED_MESSAGES -#define WS_MAX_QUEUED_MESSAGES 8 -#endif + #include + #ifndef WS_MAX_QUEUED_MESSAGES + #define WS_MAX_QUEUED_MESSAGES 8 + #endif #endif #include - -#include #include +#include #include #ifdef ESP8266 -#include -#ifdef CRYPTO_HASH_h // include Hash.h from espressif framework if the first include was from the crypto library -#include <../src/Hash.h> -#endif + #include + #ifdef CRYPTO_HASH_h // include Hash.h from espressif framework if the first include was from the crypto library + #include <../src/Hash.h> + #endif #endif #ifndef DEFAULT_MAX_WS_CLIENTS -#ifdef ESP32 -#define DEFAULT_MAX_WS_CLIENTS 8 -#else -#define DEFAULT_MAX_WS_CLIENTS 4 -#endif + #ifdef ESP32 + #define DEFAULT_MAX_WS_CLIENTS 8 + #else + #define DEFAULT_MAX_WS_CLIENTS 4 + #endif #endif using AsyncWebSocketSharedBuffer = std::shared_ptr>; @@ -87,20 +86,33 @@ typedef struct { uint64_t index; } AwsFrameInfo; -typedef enum { WS_DISCONNECTED, WS_CONNECTED, WS_DISCONNECTING } AwsClientStatus; -typedef enum { WS_CONTINUATION, WS_TEXT, WS_BINARY, WS_DISCONNECT = 0x08, WS_PING, WS_PONG } AwsFrameType; -typedef enum { WS_MSG_SENDING, WS_MSG_SENT, WS_MSG_ERROR } AwsMessageStatus; -typedef enum { WS_EVT_CONNECT, WS_EVT_DISCONNECT, WS_EVT_PONG, WS_EVT_ERROR, WS_EVT_DATA } AwsEventType; +typedef enum { WS_DISCONNECTED, + WS_CONNECTED, + WS_DISCONNECTING } AwsClientStatus; +typedef enum { WS_CONTINUATION, + WS_TEXT, + WS_BINARY, + WS_DISCONNECT = 0x08, + WS_PING, + WS_PONG } AwsFrameType; +typedef enum { WS_MSG_SENDING, + WS_MSG_SENT, + WS_MSG_ERROR } AwsMessageStatus; +typedef enum { WS_EVT_CONNECT, + WS_EVT_DISCONNECT, + WS_EVT_PONG, + WS_EVT_ERROR, + WS_EVT_DATA } AwsEventType; class AsyncWebSocketMessageBuffer { - friend AsyncWebSocket; - friend AsyncWebSocketClient; + friend AsyncWebSocket; + friend AsyncWebSocketClient; private: AsyncWebSocketSharedBuffer _buffer; public: - AsyncWebSocketMessageBuffer(){} + AsyncWebSocketMessageBuffer() {} explicit AsyncWebSocketMessageBuffer(size_t size); AsyncWebSocketMessageBuffer(const uint8_t* data, size_t size); //~AsyncWebSocketMessageBuffer(); @@ -109,9 +121,8 @@ class AsyncWebSocketMessageBuffer { size_t length() const { return _buffer->size(); } }; -class AsyncWebSocketMessage -{ -private: +class AsyncWebSocketMessage { + private: AsyncWebSocketSharedBuffer _WSbuffer; uint8_t _opcode{WS_TEXT}; bool _mask{false}; @@ -120,20 +131,20 @@ class AsyncWebSocketMessage size_t _ack{}; size_t _acked{}; -public: - AsyncWebSocketMessage(AsyncWebSocketSharedBuffer buffer, uint8_t opcode=WS_TEXT, bool mask=false); + public: + AsyncWebSocketMessage(AsyncWebSocketSharedBuffer buffer, uint8_t opcode = WS_TEXT, bool mask = false); bool finished() const { return _status != WS_MSG_SENDING; } bool betweenFrames() const { return _acked == _ack; } void ack(size_t len, uint32_t time); - size_t send(AsyncClient *client); + size_t send(AsyncClient* client); }; class AsyncWebSocketClient { private: - AsyncClient *_client; - AsyncWebSocket *_server; + AsyncClient* _client; + AsyncWebSocket* _server; uint32_t _clientId; AwsClientStatus _status; #ifdef ESP32 @@ -149,226 +160,225 @@ class AsyncWebSocketClient { uint32_t _lastMessageTime; uint32_t _keepAlivePeriod; - void _queueControl(uint8_t opcode, const uint8_t *data=NULL, size_t len=0, bool mask=false); - void _queueMessage(AsyncWebSocketSharedBuffer buffer, uint8_t opcode=WS_TEXT, bool mask=false); + void _queueControl(uint8_t opcode, const uint8_t* data = NULL, size_t len = 0, bool mask = false); + void _queueMessage(AsyncWebSocketSharedBuffer buffer, uint8_t opcode = WS_TEXT, bool mask = false); void _runQueue(); void _clearQueue(); public: - void *_tempObject; + void* _tempObject; - AsyncWebSocketClient(AsyncWebServerRequest *request, AsyncWebSocket *server); + AsyncWebSocketClient(AsyncWebServerRequest* request, AsyncWebSocket* server); ~AsyncWebSocketClient(); - //client id increments for the given server + // client id increments for the given server uint32_t id() const { return _clientId; } AwsClientStatus status() const { return _status; } AsyncClient* client() { return _client; } const AsyncClient* client() const { return _client; } - AsyncWebSocket *server(){ return _server; } - const AsyncWebSocket *server() const { return _server; } - AwsFrameInfo const &pinfo() const { return _pinfo; } + AsyncWebSocket* server() { return _server; } + const AsyncWebSocket* server() const { return _server; } + AwsFrameInfo const& pinfo() const { return _pinfo; } // - If "true" (default), the connection will be closed if the message queue is full. // This is the default behavior in yubox-node-org, which is not silently discarding messages but instead closes the connection. - // The big issue with this behavior is that is can cause the UI to automatically re-create a new WS connection, which can be filled again, + // The big issue with this behavior is that is can cause the UI to automatically re-create a new WS connection, which can be filled again, // and so on, causing a resource exhaustion. - // + // // - If "false", the incoming message will be discarded if the queue is full. // This is the default behavior in the original ESPAsyncWebServer library from me-no-dev. // This behavior allows the best performance at the expense of unreliable message delivery in case the queue is full (some messages may be lost). - // + // // - In any case, when the queue is full, a message is logged. // - IT is recommended to use the methods queueIsFull(), availableForWriteAll(), availableForWrite(clientId) to check if the queue is full before sending a message. - // + // // Usage: // - can be set in the onEvent listener when connecting (event type is: WS_EVT_CONNECT) - // - // Use cases:, + // + // Use cases:, // - if using websocket to send logging messages, maybe some loss is acceptable. // - But if using websocket to send UI update messages, maybe the connection should be closed and the UI redrawn. void setCloseClientOnQueueFull(bool close) { closeWhenFull = close; } bool willCloseClientOnQueueFull() const { return closeWhenFull; } IPAddress remoteIP() const; - uint16_t remotePort() const; + uint16_t remotePort() const; bool shouldBeDeleted() const { return !_client; } - //control frames - void close(uint16_t code=0, const char * message=NULL); - void ping(const uint8_t *data=NULL, size_t len=0); + // control frames + void close(uint16_t code = 0, const char* message = NULL); + void ping(const uint8_t* data = NULL, size_t len = 0); - //set auto-ping period in seconds. disabled if zero (default) - void keepAlivePeriod(uint16_t seconds){ + // set auto-ping period in seconds. disabled if zero (default) + void keepAlivePeriod(uint16_t seconds) { _keepAlivePeriod = seconds * 1000; } - uint16_t keepAlivePeriod(){ + uint16_t keepAlivePeriod() { return (uint16_t)(_keepAlivePeriod / 1000); } - //data packets - void message(AsyncWebSocketSharedBuffer buffer, uint8_t opcode=WS_TEXT, bool mask=false) { _queueMessage(buffer, opcode, mask); } + // data packets + void message(AsyncWebSocketSharedBuffer buffer, uint8_t opcode = WS_TEXT, bool mask = false) { _queueMessage(buffer, opcode, mask); } bool queueIsFull() const; size_t queueLen() const; - size_t printf(const char *format, ...) __attribute__ ((format (printf, 2, 3))); + size_t printf(const char* format, ...) __attribute__((format(printf, 2, 3))); #ifndef ESP32 - size_t printf_P(PGM_P formatP, ...) __attribute__ ((format (printf, 2, 3))); + size_t printf_P(PGM_P formatP, ...) __attribute__((format(printf, 2, 3))); #endif void text(AsyncWebSocketSharedBuffer buffer); - void text(const uint8_t *message, size_t len); - void text(const char *message, size_t len); - void text(const char *message); - void text(const String &message); + void text(const uint8_t* message, size_t len); + void text(const char* message, size_t len); + void text(const char* message); + void text(const String& message); #ifndef ESP32 - void text(const __FlashStringHelper *message); -#endif // ESP32 - void text(AsyncWebSocketMessageBuffer *buffer); + void text(const __FlashStringHelper* message); +#endif // ESP32 + void text(AsyncWebSocketMessageBuffer* buffer); void binary(AsyncWebSocketSharedBuffer buffer); - void binary(const uint8_t *message, size_t len); - void binary(const char * message, size_t len); - void binary(const char * message); - void binary(const String &message); + void binary(const uint8_t* message, size_t len); + void binary(const char* message, size_t len); + void binary(const char* message); + void binary(const String& message); #ifndef ESP32 - void binary(const __FlashStringHelper *message, size_t len); -#endif // ESP32 - void binary(AsyncWebSocketMessageBuffer *buffer); + void binary(const __FlashStringHelper* message, size_t len); +#endif // ESP32 + void binary(AsyncWebSocketMessageBuffer* buffer); bool canSend() const; - //system callbacks (do not call) + // system callbacks (do not call) void _onAck(size_t len, uint32_t time); void _onError(int8_t); void _onPoll(); void _onTimeout(uint32_t time); void _onDisconnect(); - void _onData(void *pbuf, size_t plen); + void _onData(void* pbuf, size_t plen); }; -using AwsHandshakeHandler = std::function; -using AwsEventHandler = std::function; +using AwsHandshakeHandler = std::function; +using AwsEventHandler = std::function; -//WebServer Handler implementation that plays the role of a socket server -class AsyncWebSocket: public AsyncWebHandler { +// WebServer Handler implementation that plays the role of a socket server +class AsyncWebSocket : public AsyncWebHandler { private: String _url; std::list _clients; uint32_t _cNextId; AwsEventHandler _eventHandler{nullptr}; - AwsHandshakeHandler _handshakeHandler; + AwsHandshakeHandler _handshakeHandler; bool _enabled; #ifdef ESP32 mutable std::mutex _lock; #endif public: - explicit AsyncWebSocket(const char* url) : _url(url) ,_cNextId(1), _enabled(true) {} - AsyncWebSocket(const String& url) :_url(url) ,_cNextId(1),_enabled(true) {} + explicit AsyncWebSocket(const char* url) : _url(url), _cNextId(1), _enabled(true) {} + AsyncWebSocket(const String& url) : _url(url), _cNextId(1), _enabled(true) {} ~AsyncWebSocket(){}; - const char * url() const { return _url.c_str(); } - void enable(bool e){ _enabled = e; } + const char* url() const { return _url.c_str(); } + void enable(bool e) { _enabled = e; } bool enabled() const { return _enabled; } bool availableForWriteAll(); bool availableForWrite(uint32_t id); size_t count() const; - AsyncWebSocketClient * client(uint32_t id); - bool hasClient(uint32_t id){ return client(id) != nullptr; } + AsyncWebSocketClient* client(uint32_t id); + bool hasClient(uint32_t id) { return client(id) != nullptr; } - void close(uint32_t id, uint16_t code=0, const char * message=NULL); - void closeAll(uint16_t code=0, const char * message=NULL); + void close(uint32_t id, uint16_t code = 0, const char* message = NULL); + void closeAll(uint16_t code = 0, const char* message = NULL); void cleanupClients(uint16_t maxClients = DEFAULT_MAX_WS_CLIENTS); - void ping(uint32_t id, const uint8_t *data=NULL, size_t len=0); - void pingAll(const uint8_t *data=NULL, size_t len=0); // done + void ping(uint32_t id, const uint8_t* data = NULL, size_t len = 0); + void pingAll(const uint8_t* data = NULL, size_t len = 0); // done - void text(uint32_t id, const uint8_t * message, size_t len); - void text(uint32_t id, const char *message, size_t len); - void text(uint32_t id, const char *message); - void text(uint32_t id, const String &message); + void text(uint32_t id, const uint8_t* message, size_t len); + void text(uint32_t id, const char* message, size_t len); + void text(uint32_t id, const char* message); + void text(uint32_t id, const String& message); #ifndef ESP32 - void text(uint32_t id, const __FlashStringHelper *message); -#endif // ESP32 - void text(uint32_t id, AsyncWebSocketMessageBuffer *buffer); + void text(uint32_t id, const __FlashStringHelper* message); +#endif // ESP32 + void text(uint32_t id, AsyncWebSocketMessageBuffer* buffer); void text(uint32_t id, AsyncWebSocketSharedBuffer buffer); - void textAll(const uint8_t *message, size_t len); - void textAll(const char * message, size_t len); - void textAll(const char * message); - void textAll(const String &message); + void textAll(const uint8_t* message, size_t len); + void textAll(const char* message, size_t len); + void textAll(const char* message); + void textAll(const String& message); #ifndef ESP32 - void textAll(const __FlashStringHelper *message); -#endif // ESP32 - void textAll(AsyncWebSocketMessageBuffer *buffer); + void textAll(const __FlashStringHelper* message); +#endif // ESP32 + void textAll(AsyncWebSocketMessageBuffer* buffer); void textAll(AsyncWebSocketSharedBuffer buffer); - void binary(uint32_t id, const uint8_t *message, size_t len); - void binary(uint32_t id, const char *message, size_t len); - void binary(uint32_t id, const char *message); - void binary(uint32_t id, const String &message); + void binary(uint32_t id, const uint8_t* message, size_t len); + void binary(uint32_t id, const char* message, size_t len); + void binary(uint32_t id, const char* message); + void binary(uint32_t id, const String& message); #ifndef ESP32 - void binary(uint32_t id, const __FlashStringHelper *message, size_t len); -#endif // ESP32 - void binary(uint32_t id, AsyncWebSocketMessageBuffer *buffer); + void binary(uint32_t id, const __FlashStringHelper* message, size_t len); +#endif // ESP32 + void binary(uint32_t id, AsyncWebSocketMessageBuffer* buffer); void binary(uint32_t id, AsyncWebSocketSharedBuffer buffer); - void binaryAll(const uint8_t *message, size_t len); - void binaryAll(const char *message, size_t len); - void binaryAll(const char *message); - void binaryAll(const String &message); + void binaryAll(const uint8_t* message, size_t len); + void binaryAll(const char* message, size_t len); + void binaryAll(const char* message); + void binaryAll(const String& message); #ifndef ESP32 - void binaryAll(const __FlashStringHelper *message, size_t len); -#endif // ESP32 - void binaryAll(AsyncWebSocketMessageBuffer *buffer); + void binaryAll(const __FlashStringHelper* message, size_t len); +#endif // ESP32 + void binaryAll(AsyncWebSocketMessageBuffer* buffer); void binaryAll(AsyncWebSocketSharedBuffer buffer); - size_t printf(uint32_t id, const char *format, ...) __attribute__ ((format (printf, 3, 4))); - size_t printfAll(const char *format, ...) __attribute__ ((format (printf, 2, 3))); + size_t printf(uint32_t id, const char* format, ...) __attribute__((format(printf, 3, 4))); + size_t printfAll(const char* format, ...) __attribute__((format(printf, 2, 3))); #ifndef ESP32 - size_t printf_P(uint32_t id, PGM_P formatP, ...) __attribute__ ((format (printf, 3, 4))); - size_t printfAll_P(PGM_P formatP, ...) __attribute__ ((format (printf, 2, 3))); + size_t printf_P(uint32_t id, PGM_P formatP, ...) __attribute__((format(printf, 3, 4))); + size_t printfAll_P(PGM_P formatP, ...) __attribute__((format(printf, 2, 3))); #endif - //event listener - void onEvent(AwsEventHandler handler){ + // event listener + void onEvent(AwsEventHandler handler) { _eventHandler = handler; } // Handshake Handler - void handleHandshake(AwsHandshakeHandler handler){ - _handshakeHandler = handler; + void handleHandshake(AwsHandshakeHandler handler) { + _handshakeHandler = handler; } - - //system callbacks (do not call) - uint32_t _getNextId(){ return _cNextId++; } - AsyncWebSocketClient *_newClient(AsyncWebServerRequest *request); - void _handleEvent(AsyncWebSocketClient * client, AwsEventType type, void * arg, uint8_t *data, size_t len); - virtual bool canHandle(AsyncWebServerRequest *request) override final; - virtual void handleRequest(AsyncWebServerRequest *request) override final; + // system callbacks (do not call) + uint32_t _getNextId() { return _cNextId++; } + AsyncWebSocketClient* _newClient(AsyncWebServerRequest* request); + void _handleEvent(AsyncWebSocketClient* client, AwsEventType type, void* arg, uint8_t* data, size_t len); + virtual bool canHandle(AsyncWebServerRequest* request) override final; + virtual void handleRequest(AsyncWebServerRequest* request) override final; - // messagebuffer functions/objects. - AsyncWebSocketMessageBuffer * makeBuffer(size_t size = 0); - AsyncWebSocketMessageBuffer * makeBuffer(const uint8_t * data, size_t size); + // messagebuffer functions/objects. + AsyncWebSocketMessageBuffer* makeBuffer(size_t size = 0); + AsyncWebSocketMessageBuffer* makeBuffer(const uint8_t* data, size_t size); - const std::list &getClients() const { return _clients; } + const std::list& getClients() const { return _clients; } }; -//WebServer response to authenticate the socket and detach the tcp client from the web server request -class AsyncWebSocketResponse: public AsyncWebServerResponse { +// WebServer response to authenticate the socket and detach the tcp client from the web server request +class AsyncWebSocketResponse : public AsyncWebServerResponse { private: String _content; - AsyncWebSocket *_server; + AsyncWebSocket* _server; + public: - AsyncWebSocketResponse(const String& key, AsyncWebSocket *server); - void _respond(AsyncWebServerRequest *request); - size_t _ack(AsyncWebServerRequest *request, size_t len, uint32_t time); + AsyncWebSocketResponse(const String& key, AsyncWebSocket* server); + void _respond(AsyncWebServerRequest* request); + size_t _ack(AsyncWebServerRequest* request, size_t len, uint32_t time); bool _sourceValid() const { return true; } }; - #endif /* ASYNCWEBSOCKET_H_ */ diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index ec616d3b6..20360c669 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -23,31 +23,31 @@ #include "Arduino.h" +#include "FS.h" #include #include #include -#include "FS.h" #ifdef ESP32 -#include -#include + #include + #include #elif defined(ESP8266) -#include -#include + #include + #include #else -#error Platform not supported + #error Platform not supported #endif -#define ASYNCWEBSERVER_VERSION "2.10.8" -#define ASYNCWEBSERVER_VERSION_MAJOR 2 -#define ASYNCWEBSERVER_VERSION_MINOR 10 +#define ASYNCWEBSERVER_VERSION "2.10.8" +#define ASYNCWEBSERVER_VERSION_MAJOR 2 +#define ASYNCWEBSERVER_VERSION_MINOR 10 #define ASYNCWEBSERVER_VERSION_REVISION 8 #define ASYNCWEBSERVER_FORK_mathieucarbou #ifdef ASYNCWEBSERVER_REGEX -#define ASYNCWEBSERVER_REGEX_ATTRIBUTE + #define ASYNCWEBSERVER_REGEX_ATTRIBUTE #else -#define ASYNCWEBSERVER_REGEX_ATTRIBUTE __attribute__((warning("ASYNCWEBSERVER_REGEX not defined"))) + #define ASYNCWEBSERVER_REGEX_ATTRIBUTE __attribute__((warning("ASYNCWEBSERVER_REGEX not defined"))) #endif class AsyncWebServer; @@ -63,31 +63,31 @@ class AsyncResponseStream; #ifndef WEBSERVER_H typedef enum { - HTTP_GET = 0b00000001, - HTTP_POST = 0b00000010, - HTTP_DELETE = 0b00000100, - HTTP_PUT = 0b00001000, - HTTP_PATCH = 0b00010000, - HTTP_HEAD = 0b00100000, + HTTP_GET = 0b00000001, + HTTP_POST = 0b00000010, + HTTP_DELETE = 0b00000100, + HTTP_PUT = 0b00001000, + HTTP_PATCH = 0b00010000, + HTTP_HEAD = 0b00100000, HTTP_OPTIONS = 0b01000000, - HTTP_ANY = 0b01111111, + HTTP_ANY = 0b01111111, } WebRequestMethod; #endif #ifndef HAVE_FS_FILE_OPEN_MODE namespace fs { - class FileOpenMode { + class FileOpenMode { public: - static const char *read; - static const char *write; - static const char *append; - }; + static const char* read; + static const char* write; + static const char* append; + }; }; #else -#include "FileOpenMode.h" + #include "FileOpenMode.h" #endif -//if this value is returned when asked for data, packet will not be sent and you will be asked for data again +// if this value is returned when asked for data, packet will not be sent and you will be asked for data again #define RESPONSE_TRY_AGAIN 0xFFFFFFFF typedef uint8_t WebRequestMethodComposite; @@ -106,8 +106,7 @@ class AsyncWebParameter { bool _isFile; public: - - AsyncWebParameter(const String& name, const String& value, bool form=false, bool file=false, size_t size=0): _name(name), _value(value), _size(size), _isForm(form), _isFile(file){} + AsyncWebParameter(const String& name, const String& value, bool form = false, bool file = false, size_t size = 0) : _name(name), _value(value), _size(size), _isForm(form), _isFile(file) {} const String& name() const { return _name; } const String& value() const { return _value; } size_t size() const { return _size; } @@ -126,18 +125,20 @@ class AsyncWebHeader { public: AsyncWebHeader() = default; - AsyncWebHeader(const AsyncWebHeader &) = default; + AsyncWebHeader(const AsyncWebHeader&) = default; - AsyncWebHeader(const String& name, const String& value): _name(name), _value(value){} - AsyncWebHeader(const String& data){ - if(!data) return; + AsyncWebHeader(const String& name, const String& value) : _name(name), _value(value) {} + AsyncWebHeader(const String& data) { + if (!data) + return; int index = data.indexOf(':'); - if (index < 0) return; + if (index < 0) + return; _name = data.substring(0, index); _value = data.substring(index + 2); } - AsyncWebHeader &operator=(const AsyncWebHeader &) = default; + AsyncWebHeader& operator=(const AsyncWebHeader&) = default; const String& name() const { return _name; } const String& value() const { return _value; } @@ -148,16 +149,22 @@ class AsyncWebHeader { * REQUEST :: Each incoming Client is wrapped inside a Request and both live together until disconnect * */ -typedef enum { RCT_NOT_USED = -1, RCT_DEFAULT = 0, RCT_HTTP, RCT_WS, RCT_EVENT, RCT_MAX } RequestedConnectionType; +typedef enum { RCT_NOT_USED = -1, + RCT_DEFAULT = 0, + RCT_HTTP, + RCT_WS, + RCT_EVENT, + RCT_MAX } RequestedConnectionType; typedef std::function AwsResponseFiller; typedef std::function AwsTemplateProcessor; class AsyncWebServerRequest { - using File = fs::File; - using FS = fs::FS; - friend class AsyncWebServer; - friend class AsyncCallbackWebHandler; + using File = fs::File; + using FS = fs::FS; + friend class AsyncWebServer; + friend class AsyncCallbackWebHandler; + private: AsyncClient* _client; AsyncWebServer* _server; @@ -197,7 +204,7 @@ class AsyncWebServerRequest { String _itemFilename; String _itemType; String _itemValue; - uint8_t *_itemBuffer; + uint8_t* _itemBuffer; size_t _itemBufferIndex; bool _itemIsFile; @@ -206,9 +213,9 @@ class AsyncWebServerRequest { void _onError(int8_t error); void _onTimeout(uint32_t time); void _onDisconnect(); - void _onData(void *buf, size_t len); + void _onData(void* buf, size_t len); - void _addPathParam(const char *param); + void _addPathParam(const char* param); bool _parseReqHead(); bool _parseReqHeader(); @@ -223,12 +230,12 @@ class AsyncWebServerRequest { public: File _tempFile; - void *_tempObject; + void* _tempObject; AsyncWebServerRequest(AsyncWebServer*, AsyncClient*); ~AsyncWebServerRequest(); - AsyncClient* client(){ return _client; } + AsyncClient* client() { return _client; } uint8_t version() const { return _version; } WebRequestMethodComposite method() const { return _method; } const String& url() const { return _url; } @@ -241,120 +248,120 @@ class AsyncWebServerRequest { const char* methodToString() const; const char* requestedConnTypeToString() const; #else - const __FlashStringHelper *methodToString() const; - const __FlashStringHelper *requestedConnTypeToString() const; + const __FlashStringHelper* methodToString() const; + const __FlashStringHelper* requestedConnTypeToString() const; #endif RequestedConnectionType requestedConnType() const { return _reqconntype; } bool isExpectedRequestedConnType(RequestedConnectionType erct1, RequestedConnectionType erct2 = RCT_NOT_USED, RequestedConnectionType erct3 = RCT_NOT_USED); - void onDisconnect (ArDisconnectHandler fn); + void onDisconnect(ArDisconnectHandler fn); - //hash is the string representation of: - // base64(user:pass) for basic or - // user:realm:md5(user:realm:pass) for digest - bool authenticate(const char * hash); - bool authenticate(const char * username, const char * password, const char * realm = NULL, bool passwordIsHash = false); - void requestAuthentication(const char * realm = NULL, bool isDigest = true); + // hash is the string representation of: + // base64(user:pass) for basic or + // user:realm:md5(user:realm:pass) for digest + bool authenticate(const char* hash); + bool authenticate(const char* username, const char* password, const char* realm = NULL, bool passwordIsHash = false); + void requestAuthentication(const char* realm = NULL, bool isDigest = true); - void setHandler(AsyncWebHandler *handler){ _handler = handler; } + void setHandler(AsyncWebHandler* handler) { _handler = handler; } /** * @brief add header to collect from a response - * - * @param name + * + * @param name */ void addInterestingHeader(const char* name); - void addInterestingHeader(const String& name){ return addInterestingHeader(name.c_str()); }; + void addInterestingHeader(const String& name) { return addInterestingHeader(name.c_str()); }; /** * @brief issue 302 redirect response - * - * @param url + * + * @param url */ void redirect(const char* url); - void redirect(const String& url){ return redirect(url.c_str()); }; - - void send(AsyncWebServerResponse *response); - void send(int code, const String& contentType=String(), const String& content=String()); - void send(FS &fs, const String& path, const String& contentType=String(), bool download=false, AwsTemplateProcessor callback=nullptr); - void send(File content, const String& path, const String& contentType=String(), bool download=false, AwsTemplateProcessor callback=nullptr); - void send(Stream &stream, const String& contentType, size_t len, AwsTemplateProcessor callback=nullptr); - void send(const String& contentType, size_t len, AwsResponseFiller callback, AwsTemplateProcessor templateCallback=nullptr); - void sendChunked(const String& contentType, AwsResponseFiller callback, AwsTemplateProcessor templateCallback=nullptr); + void redirect(const String& url) { return redirect(url.c_str()); }; + + void send(AsyncWebServerResponse* response); + void send(int code, const String& contentType = String(), const String& content = String()); + void send(FS& fs, const String& path, const String& contentType = String(), bool download = false, AwsTemplateProcessor callback = nullptr); + void send(File content, const String& path, const String& contentType = String(), bool download = false, AwsTemplateProcessor callback = nullptr); + void send(Stream& stream, const String& contentType, size_t len, AwsTemplateProcessor callback = nullptr); + void send(const String& contentType, size_t len, AwsResponseFiller callback, AwsTemplateProcessor templateCallback = nullptr); + void sendChunked(const String& contentType, AwsResponseFiller callback, AwsTemplateProcessor templateCallback = nullptr); #ifdef ESP8266 - void send_P(int code, const String& contentType, const uint8_t * content, size_t len, AwsTemplateProcessor callback=nullptr); - void send_P(int code, const String& contentType, PGM_P content, AwsTemplateProcessor callback=nullptr); + void send_P(int code, const String& contentType, const uint8_t* content, size_t len, AwsTemplateProcessor callback = nullptr); + void send_P(int code, const String& contentType, PGM_P content, AwsTemplateProcessor callback = nullptr); #endif - AsyncWebServerResponse *beginResponse(int code, const String& contentType=String(), const String& content=String()); - AsyncWebServerResponse *beginResponse(FS &fs, const String& path, const String& contentType=String(), bool download=false, AwsTemplateProcessor callback=nullptr); - AsyncWebServerResponse *beginResponse(File content, const String& path, const String& contentType=String(), bool download=false, AwsTemplateProcessor callback=nullptr); - AsyncWebServerResponse *beginResponse(Stream &stream, const String& contentType, size_t len, AwsTemplateProcessor callback=nullptr); - AsyncWebServerResponse *beginResponse(const String& contentType, size_t len, AwsResponseFiller callback, AwsTemplateProcessor templateCallback=nullptr); - AsyncWebServerResponse *beginChunkedResponse(const String& contentType, AwsResponseFiller callback, AwsTemplateProcessor templateCallback=nullptr); - AsyncResponseStream *beginResponseStream(const String& contentType, size_t bufferSize=1460); + AsyncWebServerResponse* beginResponse(int code, const String& contentType = String(), const String& content = String()); + AsyncWebServerResponse* beginResponse(FS& fs, const String& path, const String& contentType = String(), bool download = false, AwsTemplateProcessor callback = nullptr); + AsyncWebServerResponse* beginResponse(File content, const String& path, const String& contentType = String(), bool download = false, AwsTemplateProcessor callback = nullptr); + AsyncWebServerResponse* beginResponse(Stream& stream, const String& contentType, size_t len, AwsTemplateProcessor callback = nullptr); + AsyncWebServerResponse* beginResponse(const String& contentType, size_t len, AwsResponseFiller callback, AwsTemplateProcessor templateCallback = nullptr); + AsyncWebServerResponse* beginChunkedResponse(const String& contentType, AwsResponseFiller callback, AwsTemplateProcessor templateCallback = nullptr); + AsyncResponseStream* beginResponseStream(const String& contentType, size_t bufferSize = 1460); #ifdef ESP8266 - AsyncWebServerResponse *beginResponse_P(int code, const String& contentType, const uint8_t * content, size_t len, AwsTemplateProcessor callback=nullptr); - AsyncWebServerResponse *beginResponse_P(int code, const String& contentType, PGM_P content, AwsTemplateProcessor callback=nullptr); + AsyncWebServerResponse* beginResponse_P(int code, const String& contentType, const uint8_t* content, size_t len, AwsTemplateProcessor callback = nullptr); + AsyncWebServerResponse* beginResponse_P(int code, const String& contentType, PGM_P content, AwsTemplateProcessor callback = nullptr); #endif - size_t headers() const; // get header count + size_t headers() const; // get header count // check if header exists bool hasHeader(const char* name) const; bool hasHeader(const String& name) const { return hasHeader(name.c_str()); }; #ifdef ESP8266 - bool hasHeader(const __FlashStringHelper * data) const; // check if header exists + bool hasHeader(const __FlashStringHelper* data) const; // check if header exists #endif const AsyncWebHeader* getHeader(const char* name) const; const AsyncWebHeader* getHeader(const String& name) const { return getHeader(name.c_str()); }; #ifdef ESP8266 - const AsyncWebHeader* getHeader(const __FlashStringHelper * data) const; + const AsyncWebHeader* getHeader(const __FlashStringHelper* data) const; #endif const AsyncWebHeader* getHeader(size_t num) const; - size_t params() const; // get arguments count - bool hasParam(const String& name, bool post=false, bool file=false) const; - bool hasParam(const __FlashStringHelper * data, bool post=false, bool file=false) const; + size_t params() const; // get arguments count + bool hasParam(const String& name, bool post = false, bool file = false) const; + bool hasParam(const __FlashStringHelper* data, bool post = false, bool file = false) const; /** * @brief Get the Request parameter by name - * - * @param name - * @param post - * @param file - * @return const AsyncWebParameter* + * + * @param name + * @param post + * @param file + * @return const AsyncWebParameter* */ - const AsyncWebParameter* getParam(const char* name, bool post=false, bool file=false) const; + const AsyncWebParameter* getParam(const char* name, bool post = false, bool file = false) const; - const AsyncWebParameter* getParam(const String& name, bool post=false, bool file=false) const { return getParam(name.c_str()); }; + const AsyncWebParameter* getParam(const String& name, bool post = false, bool file = false) const { return getParam(name.c_str()); }; #ifdef ESP8266 - const AsyncWebParameter* getParam(const __FlashStringHelper * data, bool post, bool file) const; + const AsyncWebParameter* getParam(const __FlashStringHelper* data, bool post, bool file) const; #endif /** * @brief Get request parameter by number * i.e., n-th parameter - * @param num - * @return const AsyncWebParameter* + * @param num + * @return const AsyncWebParameter* */ const AsyncWebParameter* getParam(size_t num) const; - size_t args() const { return params(); } // get arguments count + size_t args() const { return params(); } // get arguments count // get request argument value by name const String& arg(const char* name) const; // get request argument value by name const String& arg(const String& name) const { return arg(name.c_str()); }; #ifdef ESP8266 - const String& arg(const __FlashStringHelper * data) const; // get request argument value by F(name) + const String& arg(const __FlashStringHelper* data) const; // get request argument value by F(name) #endif - const String& arg(size_t i) const; // get request argument value by number - const String& argName(size_t i) const; // get request argument name by number - bool hasArg(const char* name) const; // check if argument exists + const String& arg(size_t i) const; // get request argument value by number + const String& argName(size_t i) const; // get request argument name by number + bool hasArg(const char* name) const; // check if argument exists #ifdef ESP8266 - bool hasArg(const __FlashStringHelper * data) const; // check if F(argument) exists + bool hasArg(const __FlashStringHelper* data) const; // check if F(argument) exists #endif const String& ASYNCWEBSERVER_REGEX_ATTRIBUTE pathArg(size_t i) const; @@ -364,11 +371,11 @@ class AsyncWebServerRequest { const String& header(const String& name) const { return header(name.c_str()); }; #ifdef ESP8266 - const String& header(const __FlashStringHelper * data) const;// get request header value by F(name) + const String& header(const __FlashStringHelper* data) const; // get request header value by F(name) #endif - const String& header(size_t i) const; // get request header value by number - const String& headerName(size_t i) const; // get request header name by number + const String& header(size_t i) const; // get request header value by number + const String& headerName(size_t i) const; // get request header name by number String urlDecode(const String& text) const; }; @@ -377,11 +384,11 @@ class AsyncWebServerRequest { * FILTER :: Callback to filter AsyncWebRewrite and AsyncWebHandler (done by the Server) * */ -using ArRequestFilterFunction = std::function; +using ArRequestFilterFunction = std::function; -bool ON_STA_FILTER(AsyncWebServerRequest *request); +bool ON_STA_FILTER(AsyncWebServerRequest* request); -bool ON_AP_FILTER(AsyncWebServerRequest *request); +bool ON_AP_FILTER(AsyncWebServerRequest* request); /* * REWRITE :: One instance can be handle any Request (done by the Server) @@ -393,21 +400,25 @@ class AsyncWebRewrite { String _toUrl; String _params; ArRequestFilterFunction _filter{nullptr}; + public: - AsyncWebRewrite(const char* from, const char* to) : _from(from), _toUrl(to){ + AsyncWebRewrite(const char* from, const char* to) : _from(from), _toUrl(to) { int index = _toUrl.indexOf('?'); if (index > 0) { - _params = _toUrl.substring(index +1); + _params = _toUrl.substring(index + 1); _toUrl = _toUrl.substring(0, index); } } - virtual ~AsyncWebRewrite(){} - AsyncWebRewrite& setFilter(ArRequestFilterFunction fn) { _filter = fn; return *this; } - bool filter(AsyncWebServerRequest *request) const { return _filter == NULL || _filter(request); } + virtual ~AsyncWebRewrite() {} + AsyncWebRewrite& setFilter(ArRequestFilterFunction fn) { + _filter = fn; + return *this; + } + bool filter(AsyncWebServerRequest* request) const { return _filter == NULL || _filter(request); } const String& from(void) const { return _from; } const String& toUrl(void) const { return _toUrl; } const String& params(void) const { return _params; } - virtual bool match(AsyncWebServerRequest *request) { return from() == request->url() && filter(request); } + virtual bool match(AsyncWebServerRequest* request) { return from() == request->url() && filter(request); } }; /* @@ -419,20 +430,32 @@ class AsyncWebHandler { ArRequestFilterFunction _filter{nullptr}; String _username; String _password; + public: - AsyncWebHandler(){} - AsyncWebHandler& setFilter(ArRequestFilterFunction fn) { _filter = fn; return *this; } - AsyncWebHandler& setAuthentication(const char *username, const char *password){ _username = username; _password = password; return *this; }; - AsyncWebHandler& setAuthentication(const String& username, const String& password){ _username = username; _password = password; return *this; }; - bool filter(AsyncWebServerRequest *request){ return _filter == NULL || _filter(request); } - virtual ~AsyncWebHandler(){} - virtual bool canHandle(AsyncWebServerRequest *request __attribute__((unused))){ + AsyncWebHandler() {} + AsyncWebHandler& setFilter(ArRequestFilterFunction fn) { + _filter = fn; + return *this; + } + AsyncWebHandler& setAuthentication(const char* username, const char* password) { + _username = username; + _password = password; + return *this; + }; + AsyncWebHandler& setAuthentication(const String& username, const String& password) { + _username = username; + _password = password; + return *this; + }; + bool filter(AsyncWebServerRequest* request) { return _filter == NULL || _filter(request); } + virtual ~AsyncWebHandler() {} + virtual bool canHandle(AsyncWebServerRequest* request __attribute__((unused))) { return false; } - virtual void handleRequest(AsyncWebServerRequest *request __attribute__((unused))){} - virtual void handleUpload(AsyncWebServerRequest *request __attribute__((unused)), const String& filename __attribute__((unused)), size_t index __attribute__((unused)), uint8_t *data __attribute__((unused)), size_t len __attribute__((unused)), bool final __attribute__((unused))){} - virtual void handleBody(AsyncWebServerRequest *request __attribute__((unused)), uint8_t *data __attribute__((unused)), size_t len __attribute__((unused)), size_t index __attribute__((unused)), size_t total __attribute__((unused))){} - virtual bool isRequestHandlerTrivial(){return true;} + virtual void handleRequest(AsyncWebServerRequest* request __attribute__((unused))) {} + virtual void handleUpload(AsyncWebServerRequest* request __attribute__((unused)), const String& filename __attribute__((unused)), size_t index __attribute__((unused)), uint8_t* data __attribute__((unused)), size_t len __attribute__((unused)), bool final __attribute__((unused))) {} + virtual void handleBody(AsyncWebServerRequest* request __attribute__((unused)), uint8_t* data __attribute__((unused)), size_t len __attribute__((unused)), size_t index __attribute__((unused)), size_t total __attribute__((unused))) {} + virtual bool isRequestHandlerTrivial() { return true; } }; /* @@ -440,7 +463,12 @@ class AsyncWebHandler { * */ typedef enum { - RESPONSE_SETUP, RESPONSE_HEADERS, RESPONSE_CONTENT, RESPONSE_WAIT_ACK, RESPONSE_END, RESPONSE_FAILED + RESPONSE_SETUP, + RESPONSE_HEADERS, + RESPONSE_CONTENT, + RESPONSE_WAIT_ACK, + RESPONSE_END, + RESPONSE_FAILED } WebResponseState; class AsyncWebServerResponse { @@ -457,8 +485,9 @@ class AsyncWebServerResponse { size_t _writtenLength; WebResponseState _state; const char* _responseCodeToString(int code); -public: - static const __FlashStringHelper *responseCodeToString(int code); + + public: + static const __FlashStringHelper* responseCodeToString(int code); public: AsyncWebServerResponse(); @@ -472,23 +501,23 @@ class AsyncWebServerResponse { virtual bool _finished() const; virtual bool _failed() const; virtual bool _sourceValid() const; - virtual void _respond(AsyncWebServerRequest *request); - virtual size_t _ack(AsyncWebServerRequest *request, size_t len, uint32_t time); + virtual void _respond(AsyncWebServerRequest* request); + virtual size_t _ack(AsyncWebServerRequest* request, size_t len, uint32_t time); }; /* * SERVER :: One instance * */ -typedef std::function ArRequestHandlerFunction; -typedef std::function ArUploadHandlerFunction; -typedef std::function ArBodyHandlerFunction; +typedef std::function ArRequestHandlerFunction; +typedef std::function ArUploadHandlerFunction; +typedef std::function ArBodyHandlerFunction; class AsyncWebServer { protected: AsyncServer _server; - std::list > _rewrites; - std::list > _handlers; + std::list> _rewrites; + std::list> _handlers; AsyncCallbackWebHandler* _catchAllHandler; public: @@ -500,7 +529,7 @@ class AsyncWebServer { #if ASYNC_TCP_SSL_ENABLED void onSslFileRequest(AcSSlFileHandler cb, void* arg); - void beginSecure(const char *cert, const char *private_key_file, const char *password); + void beginSecure(const char* cert, const char* private_key_file, const char* password); #endif AsyncWebRewrite& addRewrite(AsyncWebRewrite* rewrite); @@ -509,7 +538,7 @@ class AsyncWebServer { * @brief (compat) Add url rewrite rule by pointer * a deep copy of the pounter object will be created, * it is up to user to manage further lifetime of the object in argument - * + * * @param rewrite pointer to rewrite object to copy setting from * @return AsyncWebRewrite& reference to a newly created rewrite rule */ @@ -517,10 +546,10 @@ class AsyncWebServer { /** * @brief add url rewrite rule - * - * @param from - * @param to - * @return AsyncWebRewrite& + * + * @param from + * @param to + * @return AsyncWebRewrite& */ AsyncWebRewrite& rewrite(const char* from, const char* to); @@ -528,19 +557,19 @@ class AsyncWebServer { * @brief (compat) remove rewrite rule via referenced object * this will NOT deallocate pointed object itself, internal rule with same from/to urls will be removed if any * it's a compat method, better use `removeRewrite(const char* from, const char* to)` - * @param rewrite - * @return true - * @return false + * @param rewrite + * @return true + * @return false */ bool removeRewrite(AsyncWebRewrite* rewrite); /** * @brief remove rewrite rule - * - * @param from - * @param to - * @return true - * @return false + * + * @param from + * @param to + * @return true + * @return false */ bool removeRewrite(const char* from, const char* to); @@ -554,45 +583,45 @@ class AsyncWebServer { AsyncStaticWebHandler& serveStatic(const char* uri, fs::FS& fs, const char* path, const char* cache_control = NULL); - void onNotFound(ArRequestHandlerFunction fn); //called when handler is not assigned - void onFileUpload(ArUploadHandlerFunction fn); //handle file uploads - void onRequestBody(ArBodyHandlerFunction fn); //handle posts with plain body content (JSON often transmitted this way as a request) + void onNotFound(ArRequestHandlerFunction fn); // called when handler is not assigned + void onFileUpload(ArUploadHandlerFunction fn); // handle file uploads + void onRequestBody(ArBodyHandlerFunction fn); // handle posts with plain body content (JSON often transmitted this way as a request) - void reset(); //remove all writers and handlers, with onNotFound/onFileUpload/onRequestBody + void reset(); // remove all writers and handlers, with onNotFound/onFileUpload/onRequestBody - void _handleDisconnect(AsyncWebServerRequest *request); - void _attachHandler(AsyncWebServerRequest *request); - void _rewriteRequest(AsyncWebServerRequest *request); + void _handleDisconnect(AsyncWebServerRequest* request); + void _attachHandler(AsyncWebServerRequest* request); + void _rewriteRequest(AsyncWebServerRequest* request); }; class DefaultHeaders { - using headers_t = std::list; - headers_t _headers; + using headers_t = std::list; + headers_t _headers; -public: - DefaultHeaders() = default; + public: + DefaultHeaders() = default; - using ConstIterator = headers_t::const_iterator; + using ConstIterator = headers_t::const_iterator; - void addHeader(const String& name, const String& value){ - _headers.emplace_back(name, value); - } + void addHeader(const String& name, const String& value) { + _headers.emplace_back(name, value); + } - ConstIterator begin() const { return _headers.begin(); } - ConstIterator end() const { return _headers.end(); } + ConstIterator begin() const { return _headers.begin(); } + ConstIterator end() const { return _headers.end(); } - DefaultHeaders(DefaultHeaders const &) = delete; - DefaultHeaders &operator=(DefaultHeaders const &) = delete; + DefaultHeaders(DefaultHeaders const&) = delete; + DefaultHeaders& operator=(DefaultHeaders const&) = delete; - static DefaultHeaders &Instance() { - static DefaultHeaders instance; - return instance; - } + static DefaultHeaders& Instance() { + static DefaultHeaders instance; + return instance; + } }; -#include "WebResponseImpl.h" -#include "WebHandlerImpl.h" -#include "AsyncWebSocket.h" #include "AsyncEventSource.h" +#include "AsyncWebSocket.h" +#include "WebHandlerImpl.h" +#include "WebResponseImpl.h" #endif /* _AsyncWebServer_H_ */ diff --git a/src/WebAuthentication.cpp b/src/WebAuthentication.cpp index 78c8e4332..57616163d 100644 --- a/src/WebAuthentication.cpp +++ b/src/WebAuthentication.cpp @@ -21,40 +21,39 @@ #include "WebAuthentication.h" #include #ifdef ESP32 -#include + #include #else -#include "md5.h" + #include "md5.h" #endif - // Basic Auth hash = base64("username:password") -bool checkBasicAuthentication(const char * hash, const char * username, const char * password){ - if(username == NULL || password == NULL || hash == NULL) +bool checkBasicAuthentication(const char* hash, const char* username, const char* password) { + if (username == NULL || password == NULL || hash == NULL) return false; - size_t toencodeLen = strlen(username)+strlen(password)+1; + size_t toencodeLen = strlen(username) + strlen(password) + 1; size_t encodedLen = base64_encode_expected_len(toencodeLen); - if(strlen(hash) != encodedLen) + if (strlen(hash) != encodedLen) // Fix from https://github.com/me-no-dev/ESPAsyncWebServer/issues/667 #ifdef ARDUINO_ARCH_ESP32 - if(strlen(hash) != encodedLen) + if (strlen(hash) != encodedLen) #else if (strlen(hash) != encodedLen - 1) #endif - return false; + return false; - char *toencode = new char[toencodeLen+1]; - if(toencode == NULL){ + char* toencode = new char[toencodeLen + 1]; + if (toencode == NULL) { return false; } - char *encoded = new char[base64_encode_expected_len(toencodeLen)+1]; - if(encoded == NULL){ + char* encoded = new char[base64_encode_expected_len(toencodeLen) + 1]; + if (encoded == NULL) { delete[] toencode; return false; } sprintf_P(toencode, PSTR("%s:%s"), username, password); - if(base64_encode_chars(toencode, toencodeLen, encoded) > 0 && memcmp(hash, encoded, encodedLen) == 0){ + if (base64_encode_chars(toencode, toencodeLen, encoded) > 0 && memcmp(hash, encoded, encodedLen) == 0) { delete[] toencode; delete[] encoded; return true; @@ -64,7 +63,7 @@ bool checkBasicAuthentication(const char * hash, const char * username, const ch return false; } -static bool getMD5(uint8_t * data, uint16_t len, char * output){//33 bytes or more +static bool getMD5(uint8_t* data, uint16_t len, char* output) { // 33 bytes or more #ifdef ESP32 MD5Builder md5; md5.begin(); @@ -73,9 +72,9 @@ static bool getMD5(uint8_t * data, uint16_t len, char * output){//33 bytes or mo md5.getChars(output); #else md5_context_t _ctx; - - uint8_t * _buf = (uint8_t*)malloc(16); - if(_buf == NULL) + + uint8_t* _buf = (uint8_t*)malloc(16); + if (_buf == NULL) return false; memset(_buf, 0x00, 16); @@ -83,7 +82,7 @@ static bool getMD5(uint8_t * data, uint16_t len, char * output){//33 bytes or mo MD5Update(&_ctx, data, len); MD5Final(_buf, &_ctx); - for(uint8_t i = 0; i < 16; i++) { + for (uint8_t i = 0; i < 16; i++) { sprintf_P(output + (i * 2), PSTR("%02x"), _buf[i]); } @@ -92,50 +91,50 @@ static bool getMD5(uint8_t * data, uint16_t len, char * output){//33 bytes or mo return true; } -static String genRandomMD5(){ +static String genRandomMD5() { #ifdef ESP8266 uint32_t r = RANDOM_REG32; #else uint32_t r = rand(); #endif - char * out = (char*)malloc(33); - if(out == NULL || !getMD5((uint8_t*)(&r), 4, out)) + char* out = (char*)malloc(33); + if (out == NULL || !getMD5((uint8_t*)(&r), 4, out)) return emptyString; String res = String(out); free(out); return res; } -static String stringMD5(const String& in){ - char * out = (char*)malloc(33); - if(out == NULL || !getMD5((uint8_t*)(in.c_str()), in.length(), out)) +static String stringMD5(const String& in) { + char* out = (char*)malloc(33); + if (out == NULL || !getMD5((uint8_t*)(in.c_str()), in.length(), out)) return emptyString; String res = String(out); free(out); return res; } -String generateDigestHash(const char * username, const char * password, const char * realm){ - if(username == NULL || password == NULL || realm == NULL){ +String generateDigestHash(const char* username, const char* password, const char* realm) { + if (username == NULL || password == NULL || realm == NULL) { return emptyString; } - char * out = (char*)malloc(33); + char* out = (char*)malloc(33); String res = String(username); res += ':'; res.concat(realm); res += ':'; String in = res; in.concat(password); - if(out == NULL || !getMD5((uint8_t*)(in.c_str()), in.length(), out)) + if (out == NULL || !getMD5((uint8_t*)(in.c_str()), in.length(), out)) return emptyString; res.concat(out); free(out); return res; } -String requestDigestAuthentication(const char * realm){ +String requestDigestAuthentication(const char* realm) { String header = F("realm=\""); - if(realm == NULL) + if (realm == NULL) header.concat(F("asyncesp")); else header.concat(realm); @@ -148,20 +147,20 @@ String requestDigestAuthentication(const char * realm){ } #ifndef ESP8266 -bool checkDigestAuthentication(const char * header, const char* method, const char * username, const char * password, const char * realm, bool passwordIsHash, const char * nonce, const char * opaque, const char * uri) +bool checkDigestAuthentication(const char* header, const char* method, const char* username, const char* password, const char* realm, bool passwordIsHash, const char* nonce, const char* opaque, const char* uri) #else -bool checkDigestAuthentication(const char * header, const __FlashStringHelper *method, const char * username, const char * password, const char * realm, bool passwordIsHash, const char * nonce, const char * opaque, const char * uri) +bool checkDigestAuthentication(const char* header, const __FlashStringHelper* method, const char* username, const char* password, const char* realm, bool passwordIsHash, const char* nonce, const char* opaque, const char* uri) #endif { - if(username == NULL || password == NULL || header == NULL || method == NULL){ - //os_printf("AUTH FAIL: missing requred fields\n"); + if (username == NULL || password == NULL || header == NULL || method == NULL) { + // os_printf("AUTH FAIL: missing requred fields\n"); return false; } String myHeader(header); int nextBreak = myHeader.indexOf(','); - if(nextBreak < 0){ - //os_printf("AUTH FAIL: no variables\n"); + if (nextBreak < 0) { + // os_printf("AUTH FAIL: no variables\n"); return false; } @@ -178,69 +177,69 @@ bool checkDigestAuthentication(const char * header, const __FlashStringHelper *m do { String avLine(myHeader.substring(0, nextBreak)); avLine.trim(); - myHeader = myHeader.substring(nextBreak+1); + myHeader = myHeader.substring(nextBreak + 1); nextBreak = myHeader.indexOf(','); int eqSign = avLine.indexOf('='); - if(eqSign < 0){ - //os_printf("AUTH FAIL: no = sign\n"); + if (eqSign < 0) { + // os_printf("AUTH FAIL: no = sign\n"); return false; } String varName(avLine.substring(0, eqSign)); avLine = avLine.substring(eqSign + 1); - if(avLine.startsWith(String('"'))){ + if (avLine.startsWith(String('"'))) { avLine = avLine.substring(1, avLine.length() - 1); } - if(varName.equals(F("username"))){ - if(!avLine.equals(username)){ - //os_printf("AUTH FAIL: username\n"); + if (varName.equals(F("username"))) { + if (!avLine.equals(username)) { + // os_printf("AUTH FAIL: username\n"); return false; } myUsername = avLine; - } else if(varName.equals(F("realm"))){ - if(realm != NULL && !avLine.equals(realm)){ - //os_printf("AUTH FAIL: realm\n"); + } else if (varName.equals(F("realm"))) { + if (realm != NULL && !avLine.equals(realm)) { + // os_printf("AUTH FAIL: realm\n"); return false; } myRealm = avLine; - } else if(varName.equals(F("nonce"))){ - if(nonce != NULL && !avLine.equals(nonce)){ - //os_printf("AUTH FAIL: nonce\n"); + } else if (varName.equals(F("nonce"))) { + if (nonce != NULL && !avLine.equals(nonce)) { + // os_printf("AUTH FAIL: nonce\n"); return false; } myNonce = avLine; - } else if(varName.equals(F("opaque"))){ - if(opaque != NULL && !avLine.equals(opaque)){ - //os_printf("AUTH FAIL: opaque\n"); + } else if (varName.equals(F("opaque"))) { + if (opaque != NULL && !avLine.equals(opaque)) { + // os_printf("AUTH FAIL: opaque\n"); return false; } - } else if(varName.equals(F("uri"))){ - if(uri != NULL && !avLine.equals(uri)){ - //os_printf("AUTH FAIL: uri\n"); + } else if (varName.equals(F("uri"))) { + if (uri != NULL && !avLine.equals(uri)) { + // os_printf("AUTH FAIL: uri\n"); return false; } myUri = avLine; - } else if(varName.equals(F("response"))){ + } else if (varName.equals(F("response"))) { myResponse = avLine; - } else if(varName.equals(F("qop"))){ + } else if (varName.equals(F("qop"))) { myQop = avLine; - } else if(varName.equals(F("nc"))){ + } else if (varName.equals(F("nc"))) { myNc = avLine; - } else if(varName.equals(F("cnonce"))){ + } else if (varName.equals(F("cnonce"))) { myCnonce = avLine; } - } while(nextBreak > 0); + } while (nextBreak > 0); String ha1 = (passwordIsHash) ? String(password) : stringMD5(myUsername + ':' + myRealm + ':' + password); String ha2 = String(method) + ':' + myUri; String response = ha1 + ':' + myNonce + ':' + myNc + ':' + myCnonce + ':' + myQop + ':' + stringMD5(ha2); - if(myResponse.equals(stringMD5(response))){ - //os_printf("AUTH SUCCESS\n"); + if (myResponse.equals(stringMD5(response))) { + // os_printf("AUTH SUCCESS\n"); return true; } - //os_printf("AUTH FAIL: password\n"); + // os_printf("AUTH FAIL: password\n"); return false; } diff --git a/src/WebAuthentication.h b/src/WebAuthentication.h index 8bc5f05d7..d519777ca 100644 --- a/src/WebAuthentication.h +++ b/src/WebAuthentication.h @@ -24,16 +24,16 @@ #include "Arduino.h" -bool checkBasicAuthentication(const char * header, const char * username, const char * password); -String requestDigestAuthentication(const char * realm); +bool checkBasicAuthentication(const char* header, const char* username, const char* password); +String requestDigestAuthentication(const char* realm); -bool checkDigestAuthentication(const char * header, const char* method, const char * username, const char * password, const char * realm, bool passwordIsHash, const char * nonce, const char * opaque, const char * uri); +bool checkDigestAuthentication(const char* header, const char* method, const char* username, const char* password, const char* realm, bool passwordIsHash, const char* nonce, const char* opaque, const char* uri); #ifdef ESP8266 -bool checkDigestAuthentication(const char * header, const __FlashStringHelper *method, const char * username, const char * password, const char * realm, bool passwordIsHash, const char * nonce, const char * opaque, const char * uri); +bool checkDigestAuthentication(const char* header, const __FlashStringHelper* method, const char* username, const char* password, const char* realm, bool passwordIsHash, const char* nonce, const char* opaque, const char* uri); #endif -//for storing hashed versions on the device that can be authenticated against -String generateDigestHash(const char * username, const char * password, const char * realm); +// for storing hashed versions on the device that can be authenticated against +String generateDigestHash(const char* username, const char* password, const char* realm); #endif diff --git a/src/WebHandlerImpl.h b/src/WebHandlerImpl.h index 9b7ba1b04..22757d7e4 100644 --- a/src/WebHandlerImpl.h +++ b/src/WebHandlerImpl.h @@ -23,19 +23,21 @@ #include #ifdef ASYNCWEBSERVER_REGEX -#include + #include #endif #include "stddef.h" #include -class AsyncStaticWebHandler: public AsyncWebHandler { - using File = fs::File; - using FS = fs::FS; +class AsyncStaticWebHandler : public AsyncWebHandler { + using File = fs::File; + using FS = fs::FS; + private: - bool _getFile(AsyncWebServerRequest *request); - bool _fileExists(AsyncWebServerRequest *request, const String& path); + bool _getFile(AsyncWebServerRequest* request); + bool _fileExists(AsyncWebServerRequest* request, const String& path); uint8_t _countBits(const uint8_t value) const; + protected: FS _fs; String _uri; @@ -47,23 +49,27 @@ class AsyncStaticWebHandler: public AsyncWebHandler { bool _isDir; bool _gzipFirst; uint8_t _gzipStats; + public: AsyncStaticWebHandler(const char* uri, FS& fs, const char* path, const char* cache_control); - virtual bool canHandle(AsyncWebServerRequest *request) override final; - virtual void handleRequest(AsyncWebServerRequest *request) override final; + virtual bool canHandle(AsyncWebServerRequest* request) override final; + virtual void handleRequest(AsyncWebServerRequest* request) override final; AsyncStaticWebHandler& setIsDir(bool isDir); AsyncStaticWebHandler& setDefaultFile(const char* filename); AsyncStaticWebHandler& setCacheControl(const char* cache_control); AsyncStaticWebHandler& setLastModified(const char* last_modified); AsyncStaticWebHandler& setLastModified(struct tm* last_modified); - #ifdef ESP8266 +#ifdef ESP8266 AsyncStaticWebHandler& setLastModified(time_t last_modified); - AsyncStaticWebHandler& setLastModified(); //sets to current time. Make sure sntp is runing and time is updated - #endif - AsyncStaticWebHandler& setTemplateProcessor(AwsTemplateProcessor newCallback) {_callback = newCallback; return *this;} + AsyncStaticWebHandler& setLastModified(); // sets to current time. Make sure sntp is runing and time is updated +#endif + AsyncStaticWebHandler& setTemplateProcessor(AwsTemplateProcessor newCallback) { + _callback = newCallback; + return *this; + } }; -class AsyncCallbackWebHandler: public AsyncWebHandler { +class AsyncCallbackWebHandler : public AsyncWebHandler { private: protected: String _uri; @@ -72,23 +78,24 @@ class AsyncCallbackWebHandler: public AsyncWebHandler { ArUploadHandlerFunction _onUpload; ArBodyHandlerFunction _onBody; bool _isRegex; + public: AsyncCallbackWebHandler() : _uri(), _method(HTTP_ANY), _onRequest(NULL), _onUpload(NULL), _onBody(NULL), _isRegex(false) {} - void setUri(const String& uri){ - _uri = uri; + void setUri(const String& uri) { + _uri = uri; _isRegex = uri.startsWith("^") && uri.endsWith("$"); } - void setMethod(WebRequestMethodComposite method){ _method = method; } - void onRequest(ArRequestHandlerFunction fn){ _onRequest = fn; } - void onUpload(ArUploadHandlerFunction fn){ _onUpload = fn; } - void onBody(ArBodyHandlerFunction fn){ _onBody = fn; } + void setMethod(WebRequestMethodComposite method) { _method = method; } + void onRequest(ArRequestHandlerFunction fn) { _onRequest = fn; } + void onUpload(ArUploadHandlerFunction fn) { _onUpload = fn; } + void onBody(ArBodyHandlerFunction fn) { _onBody = fn; } - virtual bool canHandle(AsyncWebServerRequest *request) override final{ + virtual bool canHandle(AsyncWebServerRequest* request) override final { - if(!_onRequest) + if (!_onRequest) return false; - if(!(_method & request->method())) + if (!(_method & request->method())) return false; #ifdef ASYNCWEBSERVER_REGEX @@ -96,56 +103,53 @@ class AsyncCallbackWebHandler: public AsyncWebHandler { std::regex pattern(_uri.c_str()); std::smatch matches; std::string s(request->url().c_str()); - if(std::regex_search(s, matches, pattern)) { + if (std::regex_search(s, matches, pattern)) { for (size_t i = 1; i < matches.size(); ++i) { // start from 1 request->_addPathParam(matches[i].str().c_str()); } } else { return false; } - } else + } else #endif - if (_uri.length() && _uri.startsWith("/*.")) { - String uriTemplate = String (_uri); - uriTemplate = uriTemplate.substring(uriTemplate.lastIndexOf(".")); - if (!request->url().endsWith(uriTemplate)) - return false; - } - else - if (_uri.length() && _uri.endsWith("*")) { + if (_uri.length() && _uri.startsWith("/*.")) { String uriTemplate = String(_uri); - uriTemplate = uriTemplate.substring(0, uriTemplate.length() - 1); + uriTemplate = uriTemplate.substring(uriTemplate.lastIndexOf(".")); + if (!request->url().endsWith(uriTemplate)) + return false; + } else if (_uri.length() && _uri.endsWith("*")) { + String uriTemplate = String(_uri); + uriTemplate = uriTemplate.substring(0, uriTemplate.length() - 1); if (!request->url().startsWith(uriTemplate)) return false; - } - else if(_uri.length() && (_uri != request->url() && !request->url().startsWith(_uri+"/"))) + } else if (_uri.length() && (_uri != request->url() && !request->url().startsWith(_uri + "/"))) return false; request->addInterestingHeader("ANY"); return true; } - - virtual void handleRequest(AsyncWebServerRequest *request) override final { - if((_username != "" && _password != "") && !request->authenticate(_username.c_str(), _password.c_str())) + + virtual void handleRequest(AsyncWebServerRequest* request) override final { + if ((_username != "" && _password != "") && !request->authenticate(_username.c_str(), _password.c_str())) return request->requestAuthentication(); - if(_onRequest) + if (_onRequest) _onRequest(request); else request->send(500); } - virtual void handleUpload(AsyncWebServerRequest *request, const String& filename, size_t index, uint8_t *data, size_t len, bool final) override final { - if((_username != "" && _password != "") && !request->authenticate(_username.c_str(), _password.c_str())) + virtual void handleUpload(AsyncWebServerRequest* request, const String& filename, size_t index, uint8_t* data, size_t len, bool final) override final { + if ((_username != "" && _password != "") && !request->authenticate(_username.c_str(), _password.c_str())) return request->requestAuthentication(); - if(_onUpload) + if (_onUpload) _onUpload(request, filename, index, data, len, final); } - virtual void handleBody(AsyncWebServerRequest *request, uint8_t *data, size_t len, size_t index, size_t total) override final { - if((_username != "" && _password != "") && !request->authenticate(_username.c_str(), _password.c_str())) + virtual void handleBody(AsyncWebServerRequest* request, uint8_t* data, size_t len, size_t index, size_t total) override final { + if ((_username != "" && _password != "") && !request->authenticate(_username.c_str(), _password.c_str())) return request->requestAuthentication(); - if(_onBody) + if (_onBody) _onBody(request, data, len, index, total); } - virtual bool isRequestHandlerTrivial() override final {return _onRequest ? false : true;} + virtual bool isRequestHandlerTrivial() override final { return _onRequest ? false : true; } }; #endif /* ASYNCWEBSERVERHANDLERIMPL_H_ */ diff --git a/src/WebHandlers.cpp b/src/WebHandlers.cpp index d3d82cdb2..40232dfd1 100644 --- a/src/WebHandlers.cpp +++ b/src/WebHandlers.cpp @@ -22,73 +22,73 @@ #include "WebHandlerImpl.h" AsyncStaticWebHandler::AsyncStaticWebHandler(const char* uri, FS& fs, const char* path, const char* cache_control) - : _fs(fs), _uri(uri), _path(path), _default_file(F("index.htm")), _cache_control(cache_control), _last_modified(), _callback(nullptr) -{ + : _fs(fs), _uri(uri), _path(path), _default_file(F("index.htm")), _cache_control(cache_control), _last_modified(), _callback(nullptr) { // Ensure leading '/' - if (_uri.length() == 0 || _uri[0] != '/') _uri = String('/') + _uri; - if (_path.length() == 0 || _path[0] != '/') _path = String('/') + _path; + if (_uri.length() == 0 || _uri[0] != '/') + _uri = String('/') + _uri; + if (_path.length() == 0 || _path[0] != '/') + _path = String('/') + _path; // If path ends with '/' we assume a hint that this is a directory to improve performance. // However - if it does not end with '/' we, can't assume a file, path can still be a directory. - _isDir = _path[_path.length()-1] == '/'; + _isDir = _path[_path.length() - 1] == '/'; // Remove the trailing '/' so we can handle default file // Notice that root will be "" not "/" - if (_uri[_uri.length()-1] == '/') _uri = _uri.substring(0, _uri.length()-1); - if (_path[_path.length()-1] == '/') _path = _path.substring(0, _path.length()-1); + if (_uri[_uri.length() - 1] == '/') + _uri = _uri.substring(0, _uri.length() - 1); + if (_path[_path.length() - 1] == '/') + _path = _path.substring(0, _path.length() - 1); // Reset stats _gzipFirst = false; _gzipStats = 0xF8; } -AsyncStaticWebHandler& AsyncStaticWebHandler::setIsDir(bool isDir){ +AsyncStaticWebHandler& AsyncStaticWebHandler::setIsDir(bool isDir) { _isDir = isDir; return *this; } -AsyncStaticWebHandler& AsyncStaticWebHandler::setDefaultFile(const char* filename){ +AsyncStaticWebHandler& AsyncStaticWebHandler::setDefaultFile(const char* filename) { _default_file = String(filename); return *this; } -AsyncStaticWebHandler& AsyncStaticWebHandler::setCacheControl(const char* cache_control){ +AsyncStaticWebHandler& AsyncStaticWebHandler::setCacheControl(const char* cache_control) { _cache_control = String(cache_control); return *this; } -AsyncStaticWebHandler& AsyncStaticWebHandler::setLastModified(const char* last_modified){ +AsyncStaticWebHandler& AsyncStaticWebHandler::setLastModified(const char* last_modified) { _last_modified = last_modified; return *this; } -AsyncStaticWebHandler& AsyncStaticWebHandler::setLastModified(struct tm* last_modified){ +AsyncStaticWebHandler& AsyncStaticWebHandler::setLastModified(struct tm* last_modified) { auto formatP = PSTR("%a, %d %b %Y %H:%M:%S %Z"); char format[strlen_P(formatP) + 1]; strcpy_P(format, formatP); char result[30]; strftime(result, sizeof(result), format, last_modified); - return setLastModified((const char *)result); + return setLastModified((const char*)result); } #ifdef ESP8266 -AsyncStaticWebHandler& AsyncStaticWebHandler::setLastModified(time_t last_modified){ - return setLastModified((struct tm *)gmtime(&last_modified)); +AsyncStaticWebHandler& AsyncStaticWebHandler::setLastModified(time_t last_modified) { + return setLastModified((struct tm*)gmtime(&last_modified)); } -AsyncStaticWebHandler& AsyncStaticWebHandler::setLastModified(){ +AsyncStaticWebHandler& AsyncStaticWebHandler::setLastModified() { time_t last_modified; - if(time(&last_modified) == 0) //time is not yet set + if (time(&last_modified) == 0) // time is not yet set return *this; return setLastModified(last_modified); } #endif -bool AsyncStaticWebHandler::canHandle(AsyncWebServerRequest *request){ - if(request->method() != HTTP_GET - || !request->url().startsWith(_uri) - || !request->isExpectedRequestedConnType(RCT_DEFAULT, RCT_HTTP) - ){ +bool AsyncStaticWebHandler::canHandle(AsyncWebServerRequest* request) { + if (request->method() != HTTP_GET || !request->url().startsWith(_uri) || !request->isExpectedRequestedConnType(RCT_DEFAULT, RCT_HTTP)) { return false; } if (_getFile(request)) { @@ -96,7 +96,7 @@ bool AsyncStaticWebHandler::canHandle(AsyncWebServerRequest *request){ if (_last_modified.length()) request->addInterestingHeader(F("If-Modified-Since")); - if(_cache_control.length()) + if (_cache_control.length()) request->addInterestingHeader(F("If-None-Match")); return true; @@ -105,13 +105,12 @@ bool AsyncStaticWebHandler::canHandle(AsyncWebServerRequest *request){ return false; } -bool AsyncStaticWebHandler::_getFile(AsyncWebServerRequest *request) -{ +bool AsyncStaticWebHandler::_getFile(AsyncWebServerRequest* request) { // Remove the found uri String path = request->url().substring(_uri.length()); // We can skip the file check and look for default if request is to the root of a directory or that request path ends with '/' - bool canSkipFileCheck = (_isDir && path.length() == 0) || (path.length() && path[path.length()-1] == '/'); + bool canSkipFileCheck = (_isDir && path.length() == 0) || (path.length() && path[path.length() - 1] == '/'); path = _path + path; @@ -124,7 +123,7 @@ bool AsyncStaticWebHandler::_getFile(AsyncWebServerRequest *request) return false; // Try to add default file, ensure there is a trailing '/' ot the path. - if (path.length() == 0 || path[path.length()-1] != '/') + if (path.length() == 0 || path[path.length() - 1] != '/') path += String('/'); path += _default_file; @@ -132,39 +131,38 @@ bool AsyncStaticWebHandler::_getFile(AsyncWebServerRequest *request) } #ifdef ESP32 -#define FILE_IS_REAL(f) (f == true && !f.isDirectory()) + #define FILE_IS_REAL(f) (f == true && !f.isDirectory()) #else -#define FILE_IS_REAL(f) (f == true) + #define FILE_IS_REAL(f) (f == true) #endif -bool AsyncStaticWebHandler::_fileExists(AsyncWebServerRequest *request, const String& path) -{ +bool AsyncStaticWebHandler::_fileExists(AsyncWebServerRequest* request, const String& path) { bool fileFound = false; bool gzipFound = false; String gzip = path + F(".gz"); if (_gzipFirst) { - if (_fs.exists(gzip)) { - request->_tempFile = _fs.open(gzip, fs::FileOpenMode::read); - gzipFound = FILE_IS_REAL(request->_tempFile); - } - if (!gzipFound){ - if (_fs.exists(path)) { - request->_tempFile = _fs.open(path, fs::FileOpenMode::read); - fileFound = FILE_IS_REAL(request->_tempFile); - } + if (_fs.exists(gzip)) { + request->_tempFile = _fs.open(gzip, fs::FileOpenMode::read); + gzipFound = FILE_IS_REAL(request->_tempFile); + } + if (!gzipFound) { + if (_fs.exists(path)) { + request->_tempFile = _fs.open(path, fs::FileOpenMode::read); + fileFound = FILE_IS_REAL(request->_tempFile); + } } } else { - if (_fs.exists(path)) { - request->_tempFile = _fs.open(path, fs::FileOpenMode::read); - fileFound = FILE_IS_REAL(request->_tempFile); + if (_fs.exists(path)) { + request->_tempFile = _fs.open(path, fs::FileOpenMode::read); + fileFound = FILE_IS_REAL(request->_tempFile); } - if (!fileFound){ - if (_fs.exists(gzip)) { - request->_tempFile = _fs.open(gzip, fs::FileOpenMode::read); - gzipFound = FILE_IS_REAL(request->_tempFile); - } + if (!fileFound) { + if (_fs.exists(gzip)) { + request->_tempFile = _fs.open(gzip, fs::FileOpenMode::read); + gzipFound = FILE_IS_REAL(request->_tempFile); + } } } @@ -173,39 +171,41 @@ bool AsyncStaticWebHandler::_fileExists(AsyncWebServerRequest *request, const St if (found) { // Extract the file name from the path and keep it in _tempObject size_t pathLen = path.length(); - char * _tempPath = (char*)malloc(pathLen+1); - snprintf_P(_tempPath, pathLen+1, PSTR("%s"), path.c_str()); + char* _tempPath = (char*)malloc(pathLen + 1); + snprintf_P(_tempPath, pathLen + 1, PSTR("%s"), path.c_str()); request->_tempObject = (void*)_tempPath; // Calculate gzip statistic _gzipStats = (_gzipStats << 1) + (gzipFound ? 1 : 0); - if (_gzipStats == 0x00) _gzipFirst = false; // All files are not gzip - else if (_gzipStats == 0xFF) _gzipFirst = true; // All files are gzip - else _gzipFirst = _countBits(_gzipStats) > 4; // IF we have more gzip files - try gzip first + if (_gzipStats == 0x00) + _gzipFirst = false; // All files are not gzip + else if (_gzipStats == 0xFF) + _gzipFirst = true; // All files are gzip + else + _gzipFirst = _countBits(_gzipStats) > 4; // IF we have more gzip files - try gzip first } return found; } -uint8_t AsyncStaticWebHandler::_countBits(const uint8_t value) const -{ +uint8_t AsyncStaticWebHandler::_countBits(const uint8_t value) const { uint8_t w = value; uint8_t n; - for (n=0; w!=0; n++) w&=w-1; + for (n = 0; w != 0; n++) + w &= w - 1; return n; } -void AsyncStaticWebHandler::handleRequest(AsyncWebServerRequest *request) -{ +void AsyncStaticWebHandler::handleRequest(AsyncWebServerRequest* request) { // Get the filename from request->_tempObject and free it String filename = String((char*)request->_tempObject); free(request->_tempObject); request->_tempObject = NULL; - if((_username.length() && _password.length()) && !request->authenticate(_username.c_str(), _password.c_str())) - return request->requestAuthentication(); + if ((_username.length() && _password.length()) && !request->authenticate(_username.c_str(), _password.c_str())) + return request->requestAuthentication(); if (request->_tempFile == true) { - time_t lw = request->_tempFile.getLastWrite(); // get last file mod time (if supported by FS) + time_t lw = request->_tempFile.getLastWrite(); // get last file mod time (if supported by FS) // set etag to lastmod timestamp if available, otherwise to size String etag; if (lw) { @@ -219,15 +219,15 @@ void AsyncStaticWebHandler::handleRequest(AsyncWebServerRequest *request) request->send(304); // Not modified } else if (_cache_control.length() && request->hasHeader(F("If-None-Match")) && request->header(F("If-None-Match")).equals(etag)) { request->_tempFile.close(); - AsyncWebServerResponse * response = new AsyncBasicResponse(304); // Not modified + AsyncWebServerResponse* response = new AsyncBasicResponse(304); // Not modified response->addHeader(F("Cache-Control"), _cache_control); response->addHeader(F("ETag"), etag); request->send(response); } else { - AsyncWebServerResponse * response = new AsyncFileResponse(request->_tempFile, filename, String(), false, _callback); + AsyncWebServerResponse* response = new AsyncFileResponse(request->_tempFile, filename, String(), false, _callback); if (_last_modified.length()) response->addHeader(F("Last-Modified"), _last_modified); - if (_cache_control.length()){ + if (_cache_control.length()) { response->addHeader(F("Cache-Control"), _cache_control); response->addHeader(F("ETag"), etag); } diff --git a/src/WebRequest.cpp b/src/WebRequest.cpp index bb5d14279..c31b9ef7d 100644 --- a/src/WebRequest.cpp +++ b/src/WebRequest.cpp @@ -19,185 +19,157 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "ESPAsyncWebServer.h" -#include "WebResponseImpl.h" #include "WebAuthentication.h" +#include "WebResponseImpl.h" #ifndef ESP8266 -#define os_strlen strlen + #define os_strlen strlen #endif #define __is_param_char(c) ((c) && ((c) != '{') && ((c) != '[') && ((c) != '&') && ((c) != '=')) -enum { PARSE_REQ_START, PARSE_REQ_HEADERS, PARSE_REQ_BODY, PARSE_REQ_END, PARSE_REQ_FAIL }; +enum { PARSE_REQ_START, + PARSE_REQ_HEADERS, + PARSE_REQ_BODY, + PARSE_REQ_END, + PARSE_REQ_FAIL }; AsyncWebServerRequest::AsyncWebServerRequest(AsyncWebServer* s, AsyncClient* c) - : _client(c) - , _server(s) - , _handler(NULL) - , _response(NULL) - , _temp() - , _parseState(0) - , _version(0) - , _method(HTTP_ANY) - , _url() - , _host() - , _contentType() - , _boundary() - , _authorization() - , _reqconntype(RCT_HTTP) - , _isDigest(false) - , _isMultipart(false) - , _isPlainPost(false) - , _expectingContinue(false) - , _contentLength(0) - , _parsedLength(0) - , _multiParseState(0) - , _boundaryPosition(0) - , _itemStartIndex(0) - , _itemSize(0) - , _itemName() - , _itemFilename() - , _itemType() - , _itemValue() - , _itemBuffer(0) - , _itemBufferIndex(0) - , _itemIsFile(false) - , _tempObject(NULL) -{ - c->onError([](void *r, AsyncClient* c, int8_t error){ (void)c; AsyncWebServerRequest *req = (AsyncWebServerRequest*)r; req->_onError(error); }, this); - c->onAck([](void *r, AsyncClient* c, size_t len, uint32_t time){ (void)c; AsyncWebServerRequest *req = (AsyncWebServerRequest*)r; req->_onAck(len, time); }, this); - c->onDisconnect([](void *r, AsyncClient* c){ AsyncWebServerRequest *req = (AsyncWebServerRequest*)r; req->_onDisconnect(); delete c; }, this); - c->onTimeout([](void *r, AsyncClient* c, uint32_t time){ (void)c; AsyncWebServerRequest *req = (AsyncWebServerRequest*)r; req->_onTimeout(time); }, this); - c->onData([](void *r, AsyncClient* c, void *buf, size_t len){ (void)c; AsyncWebServerRequest *req = (AsyncWebServerRequest*)r; req->_onData(buf, len); }, this); - c->onPoll([](void *r, AsyncClient* c){ (void)c; AsyncWebServerRequest *req = ( AsyncWebServerRequest*)r; req->_onPoll(); }, this); -} - -AsyncWebServerRequest::~AsyncWebServerRequest(){ + : _client(c), _server(s), _handler(NULL), _response(NULL), _temp(), _parseState(0), _version(0), _method(HTTP_ANY), _url(), _host(), _contentType(), _boundary(), _authorization(), _reqconntype(RCT_HTTP), _isDigest(false), _isMultipart(false), _isPlainPost(false), _expectingContinue(false), _contentLength(0), _parsedLength(0), _multiParseState(0), _boundaryPosition(0), _itemStartIndex(0), _itemSize(0), _itemName(), _itemFilename(), _itemType(), _itemValue(), _itemBuffer(0), _itemBufferIndex(0), _itemIsFile(false), _tempObject(NULL) { + c->onError([](void* r, AsyncClient* c, int8_t error) { (void)c; AsyncWebServerRequest *req = (AsyncWebServerRequest*)r; req->_onError(error); }, this); + c->onAck([](void* r, AsyncClient* c, size_t len, uint32_t time) { (void)c; AsyncWebServerRequest *req = (AsyncWebServerRequest*)r; req->_onAck(len, time); }, this); + c->onDisconnect([](void* r, AsyncClient* c) { AsyncWebServerRequest *req = (AsyncWebServerRequest*)r; req->_onDisconnect(); delete c; }, this); + c->onTimeout([](void* r, AsyncClient* c, uint32_t time) { (void)c; AsyncWebServerRequest *req = (AsyncWebServerRequest*)r; req->_onTimeout(time); }, this); + c->onData([](void* r, AsyncClient* c, void* buf, size_t len) { (void)c; AsyncWebServerRequest *req = (AsyncWebServerRequest*)r; req->_onData(buf, len); }, this); + c->onPoll([](void* r, AsyncClient* c) { (void)c; AsyncWebServerRequest *req = ( AsyncWebServerRequest*)r; req->_onPoll(); }, this); +} + +AsyncWebServerRequest::~AsyncWebServerRequest() { _headers.clear(); _pathParams.clear(); _interestingHeaders.clear(); - if(_response != NULL){ + if (_response != NULL) { delete _response; } - if(_tempObject != NULL){ + if (_tempObject != NULL) { free(_tempObject); } - if(_tempFile){ + if (_tempFile) { _tempFile.close(); } - - if(_itemBuffer){ + + if (_itemBuffer) { free(_itemBuffer); } - } -void AsyncWebServerRequest::_onData(void *buf, size_t len){ +void AsyncWebServerRequest::_onData(void* buf, size_t len) { size_t i = 0; while (true) { - if(_parseState < PARSE_REQ_BODY){ - // Find new line in buf - char *str = (char*)buf; - for (i = 0; i < len; i++) { - if (str[i] == '\n') { - break; - } - } - if (i == len) { // No new line, just add the buffer in _temp - char ch = str[len-1]; - str[len-1] = 0; - _temp.reserve(_temp.length()+len); - _temp.concat(str); - _temp.concat(ch); - } else { // Found new line - extract it and parse - str[i] = 0; // Terminate the string at the end of the line. - _temp.concat(str); - _temp.trim(); - _parseLine(); - if (++i < len) { - // Still have more buffer to process - buf = str+i; - len-= i; - continue; + if (_parseState < PARSE_REQ_BODY) { + // Find new line in buf + char* str = (char*)buf; + for (i = 0; i < len; i++) { + if (str[i] == '\n') { + break; + } } - } - } else if(_parseState == PARSE_REQ_BODY){ - // A handler should be already attached at this point in _parseLine function. - // If handler does nothing (_onRequest is NULL), we don't need to really parse the body. - const bool needParse = _handler && !_handler->isRequestHandlerTrivial(); - if(_isMultipart){ - if(needParse){ - size_t i; - for(i=0; iisRequestHandlerTrivial(); + if (_isMultipart) { + if (needParse) { + size_t i; + for (i = 0; i < len; i++) { + _parseMultipartPostByte(((uint8_t*)buf)[i], i == len - 1); + _parsedLength++; + } + } else _parsedLength += len; - } else { - if(_parsedLength == 0){ - if(_contentType.startsWith(F("application/x-www-form-urlencoded"))){ - _isPlainPost = true; - } else if(_contentType == F("text/plain") && __is_param_char(((char*)buf)[0])){ - size_t i = 0; - while (ihandleBody(this, (uint8_t*)buf, len, _parsedLength, _contentLength); - _parsedLength += len; - } else if(needParse) { - size_t i; - for(i=0; ihandleBody(this, (uint8_t*)buf, len, _parsedLength, _contentLength); + _parsedLength += len; + } else if (needParse) { + size_t i; + for (i = 0; i < len; i++) { + _parsedLength++; + _parsePlainPostChar(((uint8_t*)buf)[i]); + } + } else { + _parsedLength += len; } - } else { - _parsedLength += len; + } + if (_parsedLength == _contentLength) { + _parseState = PARSE_REQ_END; + // check if authenticated before calling handleRequest and request auth instead + if (_handler) + _handler->handleRequest(this); + else + send(501); } } - if(_parsedLength == _contentLength){ - _parseState = PARSE_REQ_END; - //check if authenticated before calling handleRequest and request auth instead - if(_handler) _handler->handleRequest(this); - else send(501); - } - } - break; + break; } } -void AsyncWebServerRequest::_removeNotInterestingHeaders(){ - if (std::any_of(std::begin(_interestingHeaders), std::end(_interestingHeaders), - [](const String &str){ return str.equalsIgnoreCase(F("ANY")); })) - return; // nothing to do +void AsyncWebServerRequest::_removeNotInterestingHeaders() { + if (std::any_of(std::begin(_interestingHeaders), std::end(_interestingHeaders), [](const String& str) { return str.equalsIgnoreCase(F("ANY")); })) + return; // nothing to do - for(auto iter = std::begin(_headers); iter != std::end(_headers); ) - { - const auto name = iter->name(); + for (auto iter = std::begin(_headers); iter != std::end(_headers);) { + const auto name = iter->name(); - if (std::none_of(std::begin(_interestingHeaders), std::end(_interestingHeaders), - [&name](const String &str){ return str.equalsIgnoreCase(name); })) - iter = _headers.erase(iter); - else - iter++; + if (std::none_of(std::begin(_interestingHeaders), std::end(_interestingHeaders), [&name](const String& str) { return str.equalsIgnoreCase(name); })) + iter = _headers.erase(iter); + else + iter++; } } -void AsyncWebServerRequest::_onPoll(){ - //os_printf("p\n"); - if(_response != NULL && _client != NULL && _client->canSend()){ - if(!_response->_finished()){ +void AsyncWebServerRequest::_onPoll() { + // os_printf("p\n"); + if (_response != NULL && _client != NULL && _client->canSend()) { + if (!_response->_finished()) { _response->_ack(this, 0, 0); } else { AsyncWebServerResponse* r = _response; @@ -209,12 +181,12 @@ void AsyncWebServerRequest::_onPoll(){ } } -void AsyncWebServerRequest::_onAck(size_t len, uint32_t time){ - //os_printf("a:%u:%u\n", len, time); - if(_response != NULL){ - if(!_response->_finished()){ +void AsyncWebServerRequest::_onAck(size_t len, uint32_t time) { + // os_printf("a:%u:%u\n", len, time); + if (_response != NULL) { + if (!_response->_finished()) { _response->_ack(this, len, time); - } else if(_response->_finished()){ + } else if (_response->_finished()) { AsyncWebServerResponse* r = _response; _response = NULL; delete r; @@ -224,138 +196,142 @@ void AsyncWebServerRequest::_onAck(size_t len, uint32_t time){ } } -void AsyncWebServerRequest::_onError(int8_t error){ +void AsyncWebServerRequest::_onError(int8_t error) { (void)error; } -void AsyncWebServerRequest::_onTimeout(uint32_t time){ +void AsyncWebServerRequest::_onTimeout(uint32_t time) { (void)time; - //os_printf("TIMEOUT: %u, state: %s\n", time, _client->stateToString()); + // os_printf("TIMEOUT: %u, state: %s\n", time, _client->stateToString()); _client->close(); } -void AsyncWebServerRequest::onDisconnect (ArDisconnectHandler fn){ - _onDisconnectfn=fn; +void AsyncWebServerRequest::onDisconnect(ArDisconnectHandler fn) { + _onDisconnectfn = fn; } -void AsyncWebServerRequest::_onDisconnect(){ - //os_printf("d\n"); - if(_onDisconnectfn) { - _onDisconnectfn(); - } +void AsyncWebServerRequest::_onDisconnect() { + // os_printf("d\n"); + if (_onDisconnectfn) { + _onDisconnectfn(); + } _server->_handleDisconnect(this); } -void AsyncWebServerRequest::_addPathParam(const char *p){ +void AsyncWebServerRequest::_addPathParam(const char* p) { _pathParams.emplace_back(p); } -void AsyncWebServerRequest::_addGetParams(const String& params){ +void AsyncWebServerRequest::_addGetParams(const String& params) { size_t start = 0; - while (start < params.length()){ + while (start < params.length()) { int end = params.indexOf('&', start); - if (end < 0) end = params.length(); + if (end < 0) + end = params.length(); int equal = params.indexOf('=', start); - if (equal < 0 || equal > end) equal = end; - String name( params.substring(start, equal) ); - String value( equal + 1 < end ? params.substring(equal + 1, end) : String() ); + if (equal < 0 || equal > end) + equal = end; + String name(params.substring(start, equal)); + String value(equal + 1 < end ? params.substring(equal + 1, end) : String()); _params.emplace_back(urlDecode(name), urlDecode(value)); start = end + 1; } } -bool AsyncWebServerRequest::_parseReqHead(){ +bool AsyncWebServerRequest::_parseReqHead() { // Split the head into method, url and version int index = _temp.indexOf(' '); String m = _temp.substring(0, index); - index = _temp.indexOf(' ', index+1); - String u = _temp.substring(m.length()+1, index); - _temp = _temp.substring(index+1); + index = _temp.indexOf(' ', index + 1); + String u = _temp.substring(m.length() + 1, index); + _temp = _temp.substring(index + 1); - if(m == F("GET")){ + if (m == F("GET")) { _method = HTTP_GET; - } else if(m == F("POST")){ + } else if (m == F("POST")) { _method = HTTP_POST; - } else if(m == F("DELETE")){ + } else if (m == F("DELETE")) { _method = HTTP_DELETE; - } else if(m == F("PUT")){ + } else if (m == F("PUT")) { _method = HTTP_PUT; - } else if(m == F("PATCH")){ + } else if (m == F("PATCH")) { _method = HTTP_PATCH; - } else if(m == F("HEAD")){ + } else if (m == F("HEAD")) { _method = HTTP_HEAD; - } else if(m == F("OPTIONS")){ + } else if (m == F("OPTIONS")) { _method = HTTP_OPTIONS; } String g; index = u.indexOf('?'); - if(index > 0){ - g = u.substring(index +1); + if (index > 0) { + g = u.substring(index + 1); u = u.substring(0, index); } _url = urlDecode(u); _addGetParams(g); - if(!_temp.startsWith(F("HTTP/1.0"))) + if (!_temp.startsWith(F("HTTP/1.0"))) _version = 1; _temp = String(); return true; } -bool strContains(const String &src, const String &find, bool mindcase = true) { - int pos=0, i=0; +bool strContains(const String& src, const String& find, bool mindcase = true) { + int pos = 0, i = 0; const int slen = src.length(); const int flen = find.length(); - if (slen < flen) return false; + if (slen < flen) + return false; while (pos <= (slen - flen)) { - for (i=0; i < flen; i++) { + for (i = 0; i < flen; i++) { if (mindcase) { - if (src[pos+i] != find[i]) i = flen + 1; // no match - } - else if (tolower(src[pos+i]) != tolower(find[i])) { + if (src[pos + i] != find[i]) + i = flen + 1; // no match + } else if (tolower(src[pos + i]) != tolower(find[i])) { i = flen + 1; // no match } } - if (i == flen) return true; + if (i == flen) + return true; pos++; } return false; } -bool AsyncWebServerRequest::_parseReqHeader(){ +bool AsyncWebServerRequest::_parseReqHeader() { int index = _temp.indexOf(':'); - if(index){ + if (index) { String name = _temp.substring(0, index); String value = _temp.substring(index + 2); - if(name.equalsIgnoreCase("Host")){ + if (name.equalsIgnoreCase("Host")) { _host = value; - } else if(name.equalsIgnoreCase(F("Content-Type"))){ - _contentType = value.substring(0, value.indexOf(';')); - if (value.startsWith(F("multipart/"))){ - _boundary = value.substring(value.indexOf('=')+1); + } else if (name.equalsIgnoreCase(F("Content-Type"))) { + _contentType = value.substring(0, value.indexOf(';')); + if (value.startsWith(F("multipart/"))) { + _boundary = value.substring(value.indexOf('=') + 1); _boundary.replace(String('"'), String()); _isMultipart = true; } - } else if(name.equalsIgnoreCase(F("Content-Length"))){ + } else if (name.equalsIgnoreCase(F("Content-Length"))) { _contentLength = atoi(value.c_str()); - } else if(name.equalsIgnoreCase(F("Expect")) && value == F("100-continue")){ + } else if (name.equalsIgnoreCase(F("Expect")) && value == F("100-continue")) { _expectingContinue = true; - } else if(name.equalsIgnoreCase(F("Authorization"))){ - if(value.length() > 5 && value.substring(0,5).equalsIgnoreCase(F("Basic"))){ + } else if (name.equalsIgnoreCase(F("Authorization"))) { + if (value.length() > 5 && value.substring(0, 5).equalsIgnoreCase(F("Basic"))) { _authorization = value.substring(6); - } else if(value.length() > 6 && value.substring(0,6).equalsIgnoreCase(F("Digest"))){ + } else if (value.length() > 6 && value.substring(0, 6).equalsIgnoreCase(F("Digest"))) { _isDigest = true; _authorization = value.substring(7); } } else { - if(name.equalsIgnoreCase(F("Upgrade")) && value.equalsIgnoreCase(F("websocket"))){ + if (name.equalsIgnoreCase(F("Upgrade")) && value.equalsIgnoreCase(F("websocket"))) { // WebSocket request can be uniquely identified by header: [Upgrade: websocket] _reqconntype = RCT_WS; } else { - if(name.equalsIgnoreCase(F("Accept")) && strContains(value, F("text/event-stream"), false)){ + if (name.equalsIgnoreCase(F("Accept")) && strContains(value, F("text/event-stream"), false)) { // WebEvent request can be uniquely identified by header: [Accept: text/event-stream] _reqconntype = RCT_EVENT; } @@ -367,13 +343,13 @@ bool AsyncWebServerRequest::_parseReqHeader(){ return true; } -void AsyncWebServerRequest::_parsePlainPostChar(uint8_t data){ - if(data && (char)data != '&') +void AsyncWebServerRequest::_parsePlainPostChar(uint8_t data) { + if (data && (char)data != '&') _temp += (char)data; - if(!data || (char)data == '&' || _parsedLength == _contentLength){ + if (!data || (char)data == '&' || _parsedLength == _contentLength) { String name = F("body"); String value = _temp; - if(!_temp.startsWith(String('{')) && !_temp.startsWith(String('[')) && _temp.indexOf('=') > 0){ + if (!_temp.startsWith(String('{')) && !_temp.startsWith(String('[')) && _temp.indexOf('=') > 0) { name = _temp.substring(0, _temp.indexOf('=')); value = _temp.substring(_temp.indexOf('=') + 1); } @@ -382,12 +358,12 @@ void AsyncWebServerRequest::_parsePlainPostChar(uint8_t data){ } } -void AsyncWebServerRequest::_handleUploadByte(uint8_t data, bool last){ +void AsyncWebServerRequest::_handleUploadByte(uint8_t data, bool last) { _itemBuffer[_itemBufferIndex++] = data; - if(last || _itemBufferIndex == 1460){ - //check if authenticated before calling the upload - if(_handler) + if (last || _itemBufferIndex == 1460) { + // check if authenticated before calling the upload + if (_handler) _handler->handleUpload(this, _itemFilename, _itemSize - _itemBufferIndex, _itemBuffer, _itemBufferIndex, false); _itemBufferIndex = 0; } @@ -407,10 +383,17 @@ enum { PARSE_ERROR }; -void AsyncWebServerRequest::_parseMultipartPostByte(uint8_t data, bool last){ -#define itemWriteByte(b) do { _itemSize++; if(_itemIsFile) _handleUploadByte(b, last); else _itemValue+=(char)(b); } while(0) - - if(!_parsedLength){ +void AsyncWebServerRequest::_parseMultipartPostByte(uint8_t data, bool last) { +#define itemWriteByte(b) \ + do { \ + _itemSize++; \ + if (_itemIsFile) \ + _handleUploadByte(b, last); \ + else \ + _itemValue += (char)(b); \ + } while (0) + + if (!_parsedLength) { _multiParseState = EXPECT_BOUNDARY; _temp = String(); _itemName = String(); @@ -418,46 +401,46 @@ void AsyncWebServerRequest::_parseMultipartPostByte(uint8_t data, bool last){ _itemType = String(); } - if(_multiParseState == WAIT_FOR_RETURN1){ - if(data != '\r'){ + if (_multiParseState == WAIT_FOR_RETURN1) { + if (data != '\r') { itemWriteByte(data); } else { _multiParseState = EXPECT_FEED1; } - } else if(_multiParseState == EXPECT_BOUNDARY){ - if(_parsedLength < 2 && data != '-'){ + } else if (_multiParseState == EXPECT_BOUNDARY) { + if (_parsedLength < 2 && data != '-') { _multiParseState = PARSE_ERROR; return; - } else if(_parsedLength - 2 < _boundary.length() && _boundary.c_str()[_parsedLength - 2] != data){ + } else if (_parsedLength - 2 < _boundary.length() && _boundary.c_str()[_parsedLength - 2] != data) { _multiParseState = PARSE_ERROR; return; - } else if(_parsedLength - 2 == _boundary.length() && data != '\r'){ + } else if (_parsedLength - 2 == _boundary.length() && data != '\r') { _multiParseState = PARSE_ERROR; return; - } else if(_parsedLength - 3 == _boundary.length()){ - if(data != '\n'){ + } else if (_parsedLength - 3 == _boundary.length()) { + if (data != '\n') { _multiParseState = PARSE_ERROR; return; } _multiParseState = PARSE_HEADERS; _itemIsFile = false; } - } else if(_multiParseState == PARSE_HEADERS){ - if((char)data != '\r' && (char)data != '\n') - _temp += (char)data; - if((char)data == '\n'){ - if(_temp.length()){ - if(_temp.length() > 12 && _temp.substring(0, 12).equalsIgnoreCase(F("Content-Type"))){ + } else if (_multiParseState == PARSE_HEADERS) { + if ((char)data != '\r' && (char)data != '\n') + _temp += (char)data; + if ((char)data == '\n') { + if (_temp.length()) { + if (_temp.length() > 12 && _temp.substring(0, 12).equalsIgnoreCase(F("Content-Type"))) { _itemType = _temp.substring(14); _itemIsFile = true; - } else if(_temp.length() > 19 && _temp.substring(0, 19).equalsIgnoreCase(F("Content-Disposition"))){ + } else if (_temp.length() > 19 && _temp.substring(0, 19).equalsIgnoreCase(F("Content-Disposition"))) { _temp = _temp.substring(_temp.indexOf(';') + 2); - while(_temp.indexOf(';') > 0){ + while (_temp.indexOf(';') > 0) { String name = _temp.substring(0, _temp.indexOf('=')); String nameVal = _temp.substring(_temp.indexOf('=') + 2, _temp.indexOf(';') - 1); - if(name == F("name")){ + if (name == F("name")) { _itemName = nameVal; - } else if(name == F("filename")){ + } else if (name == F("filename")) { _itemFilename = nameVal; _itemIsFile = true; } @@ -465,9 +448,9 @@ void AsyncWebServerRequest::_parseMultipartPostByte(uint8_t data, bool last){ } String name = _temp.substring(0, _temp.indexOf('=')); String nameVal = _temp.substring(_temp.indexOf('=') + 2, _temp.length() - 1); - if(name == F("name")){ + if (name == F("name")) { _itemName = nameVal; - } else if(name == F("filename")){ + } else if (name == F("filename")) { _itemFilename = nameVal; _itemIsFile = true; } @@ -475,15 +458,15 @@ void AsyncWebServerRequest::_parseMultipartPostByte(uint8_t data, bool last){ _temp = String(); } else { _multiParseState = WAIT_FOR_RETURN1; - //value starts from here + // value starts from here _itemSize = 0; _itemStartIndex = _parsedLength; _itemValue = String(); - if(_itemIsFile){ - if(_itemBuffer) + if (_itemIsFile) { + if (_itemBuffer) free(_itemBuffer); _itemBuffer = (uint8_t*)malloc(1460); - if(_itemBuffer == NULL){ + if (_itemBuffer == NULL) { _multiParseState = PARSE_ERROR; return; } @@ -491,44 +474,54 @@ void AsyncWebServerRequest::_parseMultipartPostByte(uint8_t data, bool last){ } } } - } else if(_multiParseState == EXPECT_FEED1){ - if(data != '\n'){ + } else if (_multiParseState == EXPECT_FEED1) { + if (data != '\n') { _multiParseState = WAIT_FOR_RETURN1; - itemWriteByte('\r'); _parseMultipartPostByte(data, last); + itemWriteByte('\r'); + _parseMultipartPostByte(data, last); } else { _multiParseState = EXPECT_DASH1; } - } else if(_multiParseState == EXPECT_DASH1){ - if(data != '-'){ + } else if (_multiParseState == EXPECT_DASH1) { + if (data != '-') { _multiParseState = WAIT_FOR_RETURN1; - itemWriteByte('\r'); itemWriteByte('\n'); _parseMultipartPostByte(data, last); + itemWriteByte('\r'); + itemWriteByte('\n'); + _parseMultipartPostByte(data, last); } else { _multiParseState = EXPECT_DASH2; } - } else if(_multiParseState == EXPECT_DASH2){ - if(data != '-'){ + } else if (_multiParseState == EXPECT_DASH2) { + if (data != '-') { _multiParseState = WAIT_FOR_RETURN1; - itemWriteByte('\r'); itemWriteByte('\n'); itemWriteByte('-'); _parseMultipartPostByte(data, last); + itemWriteByte('\r'); + itemWriteByte('\n'); + itemWriteByte('-'); + _parseMultipartPostByte(data, last); } else { _multiParseState = BOUNDARY_OR_DATA; _boundaryPosition = 0; } - } else if(_multiParseState == BOUNDARY_OR_DATA){ - if(_boundaryPosition < _boundary.length() && _boundary.c_str()[_boundaryPosition] != data){ + } else if (_multiParseState == BOUNDARY_OR_DATA) { + if (_boundaryPosition < _boundary.length() && _boundary.c_str()[_boundaryPosition] != data) { _multiParseState = WAIT_FOR_RETURN1; - itemWriteByte('\r'); itemWriteByte('\n'); itemWriteByte('-'); itemWriteByte('-'); + itemWriteByte('\r'); + itemWriteByte('\n'); + itemWriteByte('-'); + itemWriteByte('-'); uint8_t i; - for(i=0; i<_boundaryPosition; i++) + for (i = 0; i < _boundaryPosition; i++) itemWriteByte(_boundary.c_str()[i]); _parseMultipartPostByte(data, last); - } else if(_boundaryPosition == _boundary.length() - 1){ + } else if (_boundaryPosition == _boundary.length() - 1) { _multiParseState = DASH3_OR_RETURN2; - if(!_itemIsFile){ + if (!_itemIsFile) { _params.emplace_back(_itemName, _itemValue, true); } else { - if(_itemSize){ - //check if authenticated before calling the upload - if(_handler) _handler->handleUpload(this, _itemFilename, _itemSize - _itemBufferIndex, _itemBuffer, _itemBufferIndex, true); + if (_itemSize) { + // check if authenticated before calling the upload + if (_handler) + _handler->handleUpload(this, _itemFilename, _itemSize - _itemBufferIndex, _itemBuffer, _itemBufferIndex, true); _itemBufferIndex = 0; _params.emplace_back(_itemName, _itemFilename, true, true, _itemSize); } @@ -539,37 +532,48 @@ void AsyncWebServerRequest::_parseMultipartPostByte(uint8_t data, bool last){ } else { _boundaryPosition++; } - } else if(_multiParseState == DASH3_OR_RETURN2){ - if(data == '-' && (_contentLength - _parsedLength - 4) != 0){ - //os_printf("ERROR: The parser got to the end of the POST but is expecting %u bytes more!\nDrop an issue so we can have more info on the matter!\n", _contentLength - _parsedLength - 4); - _contentLength = _parsedLength + 4;//lets close the request gracefully + } else if (_multiParseState == DASH3_OR_RETURN2) { + if (data == '-' && (_contentLength - _parsedLength - 4) != 0) { + // os_printf("ERROR: The parser got to the end of the POST but is expecting %u bytes more!\nDrop an issue so we can have more info on the matter!\n", _contentLength - _parsedLength - 4); + _contentLength = _parsedLength + 4; // lets close the request gracefully } - if(data == '\r'){ + if (data == '\r') { _multiParseState = EXPECT_FEED2; - } else if(data == '-' && _contentLength == (_parsedLength + 4)){ + } else if (data == '-' && _contentLength == (_parsedLength + 4)) { _multiParseState = PARSING_FINISHED; } else { _multiParseState = WAIT_FOR_RETURN1; - itemWriteByte('\r'); itemWriteByte('\n'); itemWriteByte('-'); itemWriteByte('-'); - uint8_t i; for(i=0; i<_boundary.length(); i++) itemWriteByte(_boundary.c_str()[i]); + itemWriteByte('\r'); + itemWriteByte('\n'); + itemWriteByte('-'); + itemWriteByte('-'); + uint8_t i; + for (i = 0; i < _boundary.length(); i++) + itemWriteByte(_boundary.c_str()[i]); _parseMultipartPostByte(data, last); } - } else if(_multiParseState == EXPECT_FEED2){ - if(data == '\n'){ + } else if (_multiParseState == EXPECT_FEED2) { + if (data == '\n') { _multiParseState = PARSE_HEADERS; _itemIsFile = false; } else { _multiParseState = WAIT_FOR_RETURN1; - itemWriteByte('\r'); itemWriteByte('\n'); itemWriteByte('-'); itemWriteByte('-'); - uint8_t i; for(i=0; i<_boundary.length(); i++) itemWriteByte(_boundary.c_str()[i]); - itemWriteByte('\r'); _parseMultipartPostByte(data, last); + itemWriteByte('\r'); + itemWriteByte('\n'); + itemWriteByte('-'); + itemWriteByte('-'); + uint8_t i; + for (i = 0; i < _boundary.length(); i++) + itemWriteByte(_boundary.c_str()[i]); + itemWriteByte('\r'); + _parseMultipartPostByte(data, last); } } } -void AsyncWebServerRequest::_parseLine(){ - if(_parseState == PARSE_REQ_START){ - if(!_temp.length()){ +void AsyncWebServerRequest::_parseLine() { + if (_parseState == PARSE_REQ_START) { + if (!_temp.length()) { _parseState = PARSE_REQ_FAIL; _client->close(); } else { @@ -579,35 +583,38 @@ void AsyncWebServerRequest::_parseLine(){ return; } - if(_parseState == PARSE_REQ_HEADERS){ - if(!_temp.length()){ - //end of headers + if (_parseState == PARSE_REQ_HEADERS) { + if (!_temp.length()) { + // end of headers _server->_rewriteRequest(this); _server->_attachHandler(this); _removeNotInterestingHeaders(); - if(_expectingContinue){ + if (_expectingContinue) { String response = F("HTTP/1.1 100 Continue\r\n\r\n"); _client->write(response.c_str(), response.length()); } - //check handler for authentication - if(_contentLength){ + // check handler for authentication + if (_contentLength) { _parseState = PARSE_REQ_BODY; } else { _parseState = PARSE_REQ_END; - if(_handler) _handler->handleRequest(this); - else send(501); + if (_handler) + _handler->handleRequest(this); + else + send(501); } - } else _parseReqHeader(); + } else + _parseReqHeader(); } } -size_t AsyncWebServerRequest::headers() const{ +size_t AsyncWebServerRequest::headers() const { return _headers.size(); } bool AsyncWebServerRequest::hasHeader(const char* name) const { - for(const auto& h: _headers){ - if(h.name().equalsIgnoreCase(name)){ + for (const auto& h : _headers) { + if (h.name().equalsIgnoreCase(name)) { return true; } } @@ -615,26 +622,25 @@ bool AsyncWebServerRequest::hasHeader(const char* name) const { } #ifdef ESP8266 -bool AsyncWebServerRequest::hasHeader(const __FlashStringHelper * data) const { +bool AsyncWebServerRequest::hasHeader(const __FlashStringHelper* data) const { return hasHeader(String(data)); } #endif const AsyncWebHeader* AsyncWebServerRequest::getHeader(const char* name) const { - auto iter = std::find_if(std::begin(_headers), std::end(_headers), - [&name](const AsyncWebHeader &header){ return header.name().equalsIgnoreCase(name); }); + auto iter = std::find_if(std::begin(_headers), std::end(_headers), [&name](const AsyncWebHeader& header) { return header.name().equalsIgnoreCase(name); }); return (iter == std::end(_headers)) ? nullptr : &(*iter); } #ifdef ESP8266 -const AsyncWebHeader* AsyncWebServerRequest::getHeader(const __FlashStringHelper * data) const { +const AsyncWebHeader* AsyncWebServerRequest::getHeader(const __FlashStringHelper* data) const { PGM_P p = reinterpret_cast(data); size_t n = strlen_P(p); - char * name = (char*) malloc(n+1); + char* name = (char*)malloc(n + 1); if (name) { strcpy_P(name, p); - const AsyncWebHeader* result = getHeader( String(name)); + const AsyncWebHeader* result = getHeader(String(name)); free(name); return result; } else { @@ -645,7 +651,7 @@ const AsyncWebHeader* AsyncWebServerRequest::getHeader(const __FlashStringHelper const AsyncWebHeader* AsyncWebServerRequest::getHeader(size_t num) const { if (num >= _headers.size()) - return nullptr; + return nullptr; return &(*std::next(_headers.cbegin(), num)); } @@ -654,21 +660,21 @@ size_t AsyncWebServerRequest::params() const { } bool AsyncWebServerRequest::hasParam(const String& name, bool post, bool file) const { - for(const auto& p: _params){ - if(p.name() == name && p.isPost() == post && p.isFile() == file){ + for (const auto& p : _params) { + if (p.name() == name && p.isPost() == post && p.isFile() == file) { return true; } } return false; } -bool AsyncWebServerRequest::hasParam(const __FlashStringHelper * data, bool post, bool file) const { +bool AsyncWebServerRequest::hasParam(const __FlashStringHelper* data, bool post, bool file) const { return hasParam(String(data).c_str(), post, file); } const AsyncWebParameter* AsyncWebServerRequest::getParam(const char* name, bool post, bool file) const { - for(const auto &p: _params){ - if(p.name() == name && p.isPost() == post && p.isFile() == file){ + for (const auto& p : _params) { + if (p.name() == name && p.isPost() == post && p.isFile() == file) { return &p; } } @@ -676,134 +682,134 @@ const AsyncWebParameter* AsyncWebServerRequest::getParam(const char* name, bool } #ifdef ESP8266 -const AsyncWebParameter* AsyncWebServerRequest::getParam(const __FlashStringHelper * data, bool post, bool file) const { +const AsyncWebParameter* AsyncWebServerRequest::getParam(const __FlashStringHelper* data, bool post, bool file) const { return getParam(String(data), post, file); } #endif const AsyncWebParameter* AsyncWebServerRequest::getParam(size_t num) const { if (num >= _params.size()) - return nullptr; + return nullptr; return &(*std::next(_params.cbegin(), num)); } -void AsyncWebServerRequest::addInterestingHeader(const char* name){ - if(std::none_of(std::begin(_interestingHeaders), std::end(_interestingHeaders), - [&name](const String &str){ return str.equalsIgnoreCase(name); })) +void AsyncWebServerRequest::addInterestingHeader(const char* name) { + if (std::none_of(std::begin(_interestingHeaders), std::end(_interestingHeaders), [&name](const String& str) { return str.equalsIgnoreCase(name); })) _interestingHeaders.emplace_back(name); } -AsyncWebServerResponse * AsyncWebServerRequest::beginResponse(int code, const String& contentType, const String& content){ +AsyncWebServerResponse* AsyncWebServerRequest::beginResponse(int code, const String& contentType, const String& content) { return new AsyncBasicResponse(code, contentType, content); } -AsyncWebServerResponse * AsyncWebServerRequest::beginResponse(FS &fs, const String& path, const String& contentType, bool download, AwsTemplateProcessor callback){ - if(fs.exists(path) || (!download && fs.exists(path+F(".gz")))) +AsyncWebServerResponse* AsyncWebServerRequest::beginResponse(FS& fs, const String& path, const String& contentType, bool download, AwsTemplateProcessor callback) { + if (fs.exists(path) || (!download && fs.exists(path + F(".gz")))) return new AsyncFileResponse(fs, path, contentType, download, callback); return NULL; } -AsyncWebServerResponse * AsyncWebServerRequest::beginResponse(File content, const String& path, const String& contentType, bool download, AwsTemplateProcessor callback){ - if(content == true) +AsyncWebServerResponse* AsyncWebServerRequest::beginResponse(File content, const String& path, const String& contentType, bool download, AwsTemplateProcessor callback) { + if (content == true) return new AsyncFileResponse(content, path, contentType, download, callback); return NULL; } -AsyncWebServerResponse * AsyncWebServerRequest::beginResponse(Stream &stream, const String& contentType, size_t len, AwsTemplateProcessor callback){ +AsyncWebServerResponse* AsyncWebServerRequest::beginResponse(Stream& stream, const String& contentType, size_t len, AwsTemplateProcessor callback) { return new AsyncStreamResponse(stream, contentType, len, callback); } -AsyncWebServerResponse * AsyncWebServerRequest::beginResponse(const String& contentType, size_t len, AwsResponseFiller callback, AwsTemplateProcessor templateCallback){ +AsyncWebServerResponse* AsyncWebServerRequest::beginResponse(const String& contentType, size_t len, AwsResponseFiller callback, AwsTemplateProcessor templateCallback) { return new AsyncCallbackResponse(contentType, len, callback, templateCallback); } -AsyncWebServerResponse * AsyncWebServerRequest::beginChunkedResponse(const String& contentType, AwsResponseFiller callback, AwsTemplateProcessor templateCallback){ - if(_version) +AsyncWebServerResponse* AsyncWebServerRequest::beginChunkedResponse(const String& contentType, AwsResponseFiller callback, AwsTemplateProcessor templateCallback) { + if (_version) return new AsyncChunkedResponse(contentType, callback, templateCallback); return new AsyncCallbackResponse(contentType, 0, callback, templateCallback); } -AsyncResponseStream * AsyncWebServerRequest::beginResponseStream(const String& contentType, size_t bufferSize){ +AsyncResponseStream* AsyncWebServerRequest::beginResponseStream(const String& contentType, size_t bufferSize) { return new AsyncResponseStream(contentType, bufferSize); } #ifdef ESP8266 -AsyncWebServerResponse * AsyncWebServerRequest::beginResponse_P(int code, const String& contentType, const uint8_t * content, size_t len, AwsTemplateProcessor callback){ +AsyncWebServerResponse* AsyncWebServerRequest::beginResponse_P(int code, const String& contentType, const uint8_t* content, size_t len, AwsTemplateProcessor callback) { return new AsyncProgmemResponse(code, contentType, content, len, callback); } -AsyncWebServerResponse * AsyncWebServerRequest::beginResponse_P(int code, const String& contentType, PGM_P content, AwsTemplateProcessor callback){ - return beginResponse_P(code, contentType, (const uint8_t *)content, strlen_P(content), callback); +AsyncWebServerResponse* AsyncWebServerRequest::beginResponse_P(int code, const String& contentType, PGM_P content, AwsTemplateProcessor callback) { + return beginResponse_P(code, contentType, (const uint8_t*)content, strlen_P(content), callback); } #endif -void AsyncWebServerRequest::send(AsyncWebServerResponse *response){ +void AsyncWebServerRequest::send(AsyncWebServerResponse* response) { _response = response; - if(_response == NULL){ + if (_response == NULL) { _client->close(true); _onDisconnect(); return; } - if(!_response->_sourceValid()){ + if (!_response->_sourceValid()) { delete response; _response = NULL; send(500); - } - else { + } else { _client->setRxTimeout(0); _response->_respond(this); } } -void AsyncWebServerRequest::send(int code, const String& contentType, const String& content){ +void AsyncWebServerRequest::send(int code, const String& contentType, const String& content) { send(beginResponse(code, contentType, content)); } -void AsyncWebServerRequest::send(FS &fs, const String& path, const String& contentType, bool download, AwsTemplateProcessor callback){ - if(fs.exists(path) || (!download && fs.exists(path+F(".gz")))){ +void AsyncWebServerRequest::send(FS& fs, const String& path, const String& contentType, bool download, AwsTemplateProcessor callback) { + if (fs.exists(path) || (!download && fs.exists(path + F(".gz")))) { send(beginResponse(fs, path, contentType, download, callback)); - } else send(404); + } else + send(404); } -void AsyncWebServerRequest::send(File content, const String& path, const String& contentType, bool download, AwsTemplateProcessor callback){ - if(content == true){ +void AsyncWebServerRequest::send(File content, const String& path, const String& contentType, bool download, AwsTemplateProcessor callback) { + if (content == true) { send(beginResponse(content, path, contentType, download, callback)); - } else send(404); + } else + send(404); } -void AsyncWebServerRequest::send(Stream &stream, const String& contentType, size_t len, AwsTemplateProcessor callback){ +void AsyncWebServerRequest::send(Stream& stream, const String& contentType, size_t len, AwsTemplateProcessor callback) { send(beginResponse(stream, contentType, len, callback)); } -void AsyncWebServerRequest::send(const String& contentType, size_t len, AwsResponseFiller callback, AwsTemplateProcessor templateCallback){ +void AsyncWebServerRequest::send(const String& contentType, size_t len, AwsResponseFiller callback, AwsTemplateProcessor templateCallback) { send(beginResponse(contentType, len, callback, templateCallback)); } -void AsyncWebServerRequest::sendChunked(const String& contentType, AwsResponseFiller callback, AwsTemplateProcessor templateCallback){ +void AsyncWebServerRequest::sendChunked(const String& contentType, AwsResponseFiller callback, AwsTemplateProcessor templateCallback) { send(beginChunkedResponse(contentType, callback, templateCallback)); } #ifdef ESP8266 -void AsyncWebServerRequest::send_P(int code, const String& contentType, const uint8_t * content, size_t len, AwsTemplateProcessor callback){ +void AsyncWebServerRequest::send_P(int code, const String& contentType, const uint8_t* content, size_t len, AwsTemplateProcessor callback) { send(beginResponse_P(code, contentType, content, len, callback)); } -void AsyncWebServerRequest::send_P(int code, const String& contentType, PGM_P content, AwsTemplateProcessor callback){ +void AsyncWebServerRequest::send_P(int code, const String& contentType, PGM_P content, AwsTemplateProcessor callback) { send(beginResponse_P(code, contentType, content, callback)); } #endif -void AsyncWebServerRequest::redirect(const char* url){ - AsyncWebServerResponse * response = beginResponse(302); +void AsyncWebServerRequest::redirect(const char* url) { + AsyncWebServerResponse* response = beginResponse(302); response->addHeader(F("Location"), url); send(response); } -bool AsyncWebServerRequest::authenticate(const char * username, const char * password, const char * realm, bool passwordIsHash){ - if(_authorization.length()){ - if(_isDigest) +bool AsyncWebServerRequest::authenticate(const char* username, const char* password, const char* realm, bool passwordIsHash) { + if (_authorization.length()) { + if (_isDigest) return checkDigestAuthentication(_authorization.c_str(), methodToString(), username, password, realm, passwordIsHash, NULL, NULL, NULL); - else if(!passwordIsHash) + else if (!passwordIsHash) return checkBasicAuthentication(_authorization.c_str(), username, password); else return _authorization.equals(password); @@ -811,19 +817,19 @@ bool AsyncWebServerRequest::authenticate(const char * username, const char * pas return false; } -bool AsyncWebServerRequest::authenticate(const char * hash){ - if(!_authorization.length() || hash == NULL) +bool AsyncWebServerRequest::authenticate(const char* hash) { + if (!_authorization.length() || hash == NULL) return false; - if(_isDigest){ + if (_isDigest) { String hStr = String(hash); int separator = hStr.indexOf(':'); - if(separator <= 0) + if (separator <= 0) return false; String username = hStr.substring(0, separator); hStr = hStr.substring(separator + 1); separator = hStr.indexOf(':'); - if(separator <= 0) + if (separator <= 0) return false; String realm = hStr.substring(0, separator); hStr = hStr.substring(separator + 1); @@ -833,11 +839,11 @@ bool AsyncWebServerRequest::authenticate(const char * hash){ return (_authorization.equals(hash)); } -void AsyncWebServerRequest::requestAuthentication(const char * realm, bool isDigest){ - AsyncWebServerResponse * r = beginResponse(401); - if(!isDigest && realm == NULL){ +void AsyncWebServerRequest::requestAuthentication(const char* realm, bool isDigest) { + AsyncWebServerResponse* r = beginResponse(401); + if (!isDigest && realm == NULL) { r->addHeader(F("WWW-Authenticate"), F("Basic realm=\"Login Required\"")); - } else if(!isDigest){ + } else if (!isDigest) { String header = F("Basic realm=\""); header.concat(realm); header += '"'; @@ -851,8 +857,8 @@ void AsyncWebServerRequest::requestAuthentication(const char * realm, bool isDig } bool AsyncWebServerRequest::hasArg(const char* name) const { - for(const auto& arg: _params){ - if(arg.name() == name){ + for (const auto& arg : _params) { + if (arg.name() == name) { return true; } } @@ -860,14 +866,14 @@ bool AsyncWebServerRequest::hasArg(const char* name) const { } #ifdef ESP8266 -bool AsyncWebServerRequest::hasArg(const __FlashStringHelper * data) const { +bool AsyncWebServerRequest::hasArg(const __FlashStringHelper* data) const { return hasArg(String(data).c_str()); } #endif const String& AsyncWebServerRequest::arg(const char* name) const { - for(const auto& arg: _params){ - if(arg.name() == name){ + for (const auto& arg : _params) { + if (arg.name() == name) { return arg.value(); } } @@ -875,7 +881,7 @@ const String& AsyncWebServerRequest::arg(const char* name) const { } #ifdef ESP8266 -const String& AsyncWebServerRequest::arg(const __FlashStringHelper * data) const { +const String& AsyncWebServerRequest::arg(const __FlashStringHelper* data) const { return arg(String(data).c_str()); } #endif @@ -898,14 +904,14 @@ const String& AsyncWebServerRequest::header(const char* name) const { } #ifdef ESP8266 -const String& AsyncWebServerRequest::header(const __FlashStringHelper * data) const { +const String& AsyncWebServerRequest::header(const __FlashStringHelper* data) const { return header(String(data).c_str()); }; #endif const String& AsyncWebServerRequest::header(size_t i) const { const AsyncWebHeader* h = getHeader(i); - return h ? h->value() : emptyString; + return h ? h->value() : emptyString; } const String& AsyncWebServerRequest::headerName(size_t i) const { @@ -919,17 +925,17 @@ String AsyncWebServerRequest::urlDecode(const String& text) const { unsigned int i = 0; String decoded; decoded.reserve(len); // Allocate the string internal buffer - never longer from source text - while (i < len){ + while (i < len) { char decodedChar; char encodedChar = text.charAt(i++); - if ((encodedChar == '%') && (i + 1 < len)){ + if ((encodedChar == '%') && (i + 1 < len)) { temp[2] = text.charAt(i++); temp[3] = text.charAt(i++); decodedChar = strtol(temp, NULL, 16); } else if (encodedChar == '+') { decodedChar = ' '; } else { - decodedChar = encodedChar; // normal ascii char + decodedChar = encodedChar; // normal ascii char } decoded.concat(decodedChar); } @@ -938,58 +944,89 @@ String AsyncWebServerRequest::urlDecode(const String& text) const { #ifndef ESP8266 const char* AsyncWebServerRequest::methodToString() const { - if(_method == HTTP_ANY) return "ANY"; - if(_method & HTTP_GET) return "GET"; - if(_method & HTTP_POST) return "POST"; - if(_method & HTTP_DELETE) return "DELETE"; - if(_method & HTTP_PUT) return "PUT"; - if(_method & HTTP_PATCH) return "PATCH"; - if(_method & HTTP_HEAD) return "HEAD"; - if(_method & HTTP_OPTIONS) return "OPTIONS"; + if (_method == HTTP_ANY) + return "ANY"; + if (_method & HTTP_GET) + return "GET"; + if (_method & HTTP_POST) + return "POST"; + if (_method & HTTP_DELETE) + return "DELETE"; + if (_method & HTTP_PUT) + return "PUT"; + if (_method & HTTP_PATCH) + return "PATCH"; + if (_method & HTTP_HEAD) + return "HEAD"; + if (_method & HTTP_OPTIONS) + return "OPTIONS"; return "UNKNOWN"; } const char* AsyncWebServerRequest::requestedConnTypeToString() const { switch (_reqconntype) { - case RCT_NOT_USED: return "RCT_NOT_USED"; - case RCT_DEFAULT: return "RCT_DEFAULT"; - case RCT_HTTP: return "RCT_HTTP"; - case RCT_WS: return "RCT_WS"; - case RCT_EVENT: return "RCT_EVENT"; - default: return "ERROR"; + case RCT_NOT_USED: + return "RCT_NOT_USED"; + case RCT_DEFAULT: + return "RCT_DEFAULT"; + case RCT_HTTP: + return "RCT_HTTP"; + case RCT_WS: + return "RCT_WS"; + case RCT_EVENT: + return "RCT_EVENT"; + default: + return "ERROR"; } } #endif #ifdef ESP8266 -const __FlashStringHelper *AsyncWebServerRequest::methodToString() const { - if(_method == HTTP_ANY) return F("ANY"); - else if(_method & HTTP_GET) return F("GET"); - else if(_method & HTTP_POST) return F("POST"); - else if(_method & HTTP_DELETE) return F("DELETE"); - else if(_method & HTTP_PUT) return F("PUT"); - else if(_method & HTTP_PATCH) return F("PATCH"); - else if(_method & HTTP_HEAD) return F("HEAD"); - else if(_method & HTTP_OPTIONS) return F("OPTIONS"); +const __FlashStringHelper* AsyncWebServerRequest::methodToString() const { + if (_method == HTTP_ANY) + return F("ANY"); + else if (_method & HTTP_GET) + return F("GET"); + else if (_method & HTTP_POST) + return F("POST"); + else if (_method & HTTP_DELETE) + return F("DELETE"); + else if (_method & HTTP_PUT) + return F("PUT"); + else if (_method & HTTP_PATCH) + return F("PATCH"); + else if (_method & HTTP_HEAD) + return F("HEAD"); + else if (_method & HTTP_OPTIONS) + return F("OPTIONS"); return F("UNKNOWN"); } -const __FlashStringHelper *AsyncWebServerRequest::requestedConnTypeToString() const { +const __FlashStringHelper* AsyncWebServerRequest::requestedConnTypeToString() const { switch (_reqconntype) { - case RCT_NOT_USED: return F("RCT_NOT_USED"); - case RCT_DEFAULT: return F("RCT_DEFAULT"); - case RCT_HTTP: return F("RCT_HTTP"); - case RCT_WS: return F("RCT_WS"); - case RCT_EVENT: return F("RCT_EVENT"); - default: return F("ERROR"); + case RCT_NOT_USED: + return F("RCT_NOT_USED"); + case RCT_DEFAULT: + return F("RCT_DEFAULT"); + case RCT_HTTP: + return F("RCT_HTTP"); + case RCT_WS: + return F("RCT_WS"); + case RCT_EVENT: + return F("RCT_EVENT"); + default: + return F("ERROR"); } } #endif bool AsyncWebServerRequest::isExpectedRequestedConnType(RequestedConnectionType erct1, RequestedConnectionType erct2, RequestedConnectionType erct3) { - bool res = false; - if ((erct1 != RCT_NOT_USED) && (erct1 == _reqconntype)) res = true; - if ((erct2 != RCT_NOT_USED) && (erct2 == _reqconntype)) res = true; - if ((erct3 != RCT_NOT_USED) && (erct3 == _reqconntype)) res = true; - return res; + bool res = false; + if ((erct1 != RCT_NOT_USED) && (erct1 == _reqconntype)) + res = true; + if ((erct2 != RCT_NOT_USED) && (erct2 == _reqconntype)) + res = true; + if ((erct3 != RCT_NOT_USED) && (erct3 == _reqconntype)) + res = true; + return res; } diff --git a/src/WebResponseImpl.h b/src/WebResponseImpl.h index 4a472254b..26ec22365 100644 --- a/src/WebResponseImpl.h +++ b/src/WebResponseImpl.h @@ -22,115 +22,125 @@ #define ASYNCWEBSERVERRESPONSEIMPL_H_ #ifdef Arduino_h -// arduino is not compatible with std::vector -#undef min -#undef max + // arduino is not compatible with std::vector + #undef min + #undef max #endif -#include #include +#include // It is possible to restore these defines, but one can use _min and _max instead. Or std::min, std::max. -class AsyncBasicResponse: public AsyncWebServerResponse { +class AsyncBasicResponse : public AsyncWebServerResponse { private: String _content; + public: - AsyncBasicResponse(int code, const String& contentType=String(), const String& content=String()); - void _respond(AsyncWebServerRequest *request); - size_t _ack(AsyncWebServerRequest *request, size_t len, uint32_t time); + AsyncBasicResponse(int code, const String& contentType = String(), const String& content = String()); + void _respond(AsyncWebServerRequest* request); + size_t _ack(AsyncWebServerRequest* request, size_t len, uint32_t time); bool _sourceValid() const { return true; } }; -class AsyncAbstractResponse: public AsyncWebServerResponse { +class AsyncAbstractResponse : public AsyncWebServerResponse { private: String _head; - // Data is inserted into cache at begin(). - // This is inefficient with vector, but if we use some other container, + // Data is inserted into cache at begin(). + // This is inefficient with vector, but if we use some other container, // we won't be able to access it as contiguous array of bytes when reading from it, // so by gaining performance in one place, we'll lose it in another. std::vector _cache; size_t _readDataFromCacheOrContent(uint8_t* data, const size_t len); size_t _fillBufferAndProcessTemplates(uint8_t* buf, size_t maxLen); + protected: AwsTemplateProcessor _callback; + public: - AsyncAbstractResponse(AwsTemplateProcessor callback=nullptr); - void _respond(AsyncWebServerRequest *request); - size_t _ack(AsyncWebServerRequest *request, size_t len, uint32_t time); + AsyncAbstractResponse(AwsTemplateProcessor callback = nullptr); + void _respond(AsyncWebServerRequest* request); + size_t _ack(AsyncWebServerRequest* request, size_t len, uint32_t time); bool _sourceValid() const { return false; } - virtual size_t _fillBuffer(uint8_t *buf __attribute__((unused)), size_t maxLen __attribute__((unused))) { return 0; } + virtual size_t _fillBuffer(uint8_t* buf __attribute__((unused)), size_t maxLen __attribute__((unused))) { return 0; } }; #ifndef TEMPLATE_PLACEHOLDER -#define TEMPLATE_PLACEHOLDER '%' + #define TEMPLATE_PLACEHOLDER '%' #endif #define TEMPLATE_PARAM_NAME_LENGTH 32 -class AsyncFileResponse: public AsyncAbstractResponse { - using File = fs::File; - using FS = fs::FS; +class AsyncFileResponse : public AsyncAbstractResponse { + using File = fs::File; + using FS = fs::FS; + private: File _content; String _path; void _setContentType(const String& path); + public: - AsyncFileResponse(FS &fs, const String& path, const String& contentType=String(), bool download=false, AwsTemplateProcessor callback=nullptr); - AsyncFileResponse(File content, const String& path, const String& contentType=String(), bool download=false, AwsTemplateProcessor callback=nullptr); + AsyncFileResponse(FS& fs, const String& path, const String& contentType = String(), bool download = false, AwsTemplateProcessor callback = nullptr); + AsyncFileResponse(File content, const String& path, const String& contentType = String(), bool download = false, AwsTemplateProcessor callback = nullptr); ~AsyncFileResponse(); bool _sourceValid() const { return !!(_content); } - virtual size_t _fillBuffer(uint8_t *buf, size_t maxLen) override; + virtual size_t _fillBuffer(uint8_t* buf, size_t maxLen) override; }; -class AsyncStreamResponse: public AsyncAbstractResponse { +class AsyncStreamResponse : public AsyncAbstractResponse { private: - Stream *_content; + Stream* _content; + public: - AsyncStreamResponse(Stream &stream, const String& contentType, size_t len, AwsTemplateProcessor callback=nullptr); + AsyncStreamResponse(Stream& stream, const String& contentType, size_t len, AwsTemplateProcessor callback = nullptr); bool _sourceValid() const { return !!(_content); } - virtual size_t _fillBuffer(uint8_t *buf, size_t maxLen) override; + virtual size_t _fillBuffer(uint8_t* buf, size_t maxLen) override; }; -class AsyncCallbackResponse: public AsyncAbstractResponse { +class AsyncCallbackResponse : public AsyncAbstractResponse { private: AwsResponseFiller _content; size_t _filledLength; + public: - AsyncCallbackResponse(const String& contentType, size_t len, AwsResponseFiller callback, AwsTemplateProcessor templateCallback=nullptr); + AsyncCallbackResponse(const String& contentType, size_t len, AwsResponseFiller callback, AwsTemplateProcessor templateCallback = nullptr); bool _sourceValid() const { return !!(_content); } - virtual size_t _fillBuffer(uint8_t *buf, size_t maxLen) override; + virtual size_t _fillBuffer(uint8_t* buf, size_t maxLen) override; }; -class AsyncChunkedResponse: public AsyncAbstractResponse { +class AsyncChunkedResponse : public AsyncAbstractResponse { private: AwsResponseFiller _content; size_t _filledLength; + public: - AsyncChunkedResponse(const String& contentType, AwsResponseFiller callback, AwsTemplateProcessor templateCallback=nullptr); + AsyncChunkedResponse(const String& contentType, AwsResponseFiller callback, AwsTemplateProcessor templateCallback = nullptr); bool _sourceValid() const { return !!(_content); } - virtual size_t _fillBuffer(uint8_t *buf, size_t maxLen) override; + virtual size_t _fillBuffer(uint8_t* buf, size_t maxLen) override; }; -class AsyncProgmemResponse: public AsyncAbstractResponse { +class AsyncProgmemResponse : public AsyncAbstractResponse { private: - const uint8_t * _content; + const uint8_t* _content; size_t _readLength; + public: - AsyncProgmemResponse(int code, const String& contentType, const uint8_t * content, size_t len, AwsTemplateProcessor callback=nullptr); + AsyncProgmemResponse(int code, const String& contentType, const uint8_t* content, size_t len, AwsTemplateProcessor callback = nullptr); bool _sourceValid() const { return true; } - virtual size_t _fillBuffer(uint8_t *buf, size_t maxLen) override; + virtual size_t _fillBuffer(uint8_t* buf, size_t maxLen) override; }; class cbuf; -class AsyncResponseStream: public AsyncAbstractResponse, public Print { +class AsyncResponseStream : public AsyncAbstractResponse, public Print { private: std::unique_ptr _content; + public: AsyncResponseStream(const String& contentType, size_t bufferSize); ~AsyncResponseStream(); bool _sourceValid() const { return (_state < RESPONSE_END); } - virtual size_t _fillBuffer(uint8_t *buf, size_t maxLen) override; - size_t write(const uint8_t *data, size_t len); + virtual size_t _fillBuffer(uint8_t* buf, size_t maxLen) override; + size_t write(const uint8_t* data, size_t len); size_t write(uint8_t data); using Print::write; }; diff --git a/src/WebResponses.cpp b/src/WebResponses.cpp index a783de0f4..1fd41fa89 100644 --- a/src/WebResponses.cpp +++ b/src/WebResponses.cpp @@ -23,111 +23,140 @@ #include "cbuf.h" // Since ESP8266 does not link memchr by default, here's its implementation. -void* memchr(void* ptr, int ch, size_t count) -{ +void* memchr(void* ptr, int ch, size_t count) { unsigned char* p = static_cast(ptr); - while(count--) - if(*p++ == static_cast(ch)) + while (count--) + if (*p++ == static_cast(ch)) return --p; return nullptr; } - /* * Abstract Response * */ const char* AsyncWebServerResponse::_responseCodeToString(int code) { - return reinterpret_cast(responseCodeToString(code)); + return reinterpret_cast(responseCodeToString(code)); } -const __FlashStringHelper *AsyncWebServerResponse::responseCodeToString(int code) { +const __FlashStringHelper* AsyncWebServerResponse::responseCodeToString(int code) { switch (code) { - case 100: return F("Continue"); - case 101: return F("Switching Protocols"); - case 200: return F("OK"); - case 201: return F("Created"); - case 202: return F("Accepted"); - case 203: return F("Non-Authoritative Information"); - case 204: return F("No Content"); - case 205: return F("Reset Content"); - case 206: return F("Partial Content"); - case 300: return F("Multiple Choices"); - case 301: return F("Moved Permanently"); - case 302: return F("Found"); - case 303: return F("See Other"); - case 304: return F("Not Modified"); - case 305: return F("Use Proxy"); - case 307: return F("Temporary Redirect"); - case 400: return F("Bad Request"); - case 401: return F("Unauthorized"); - case 402: return F("Payment Required"); - case 403: return F("Forbidden"); - case 404: return F("Not Found"); - case 405: return F("Method Not Allowed"); - case 406: return F("Not Acceptable"); - case 407: return F("Proxy Authentication Required"); - case 408: return F("Request Time-out"); - case 409: return F("Conflict"); - case 410: return F("Gone"); - case 411: return F("Length Required"); - case 412: return F("Precondition Failed"); - case 413: return F("Request Entity Too Large"); - case 414: return F("Request-URI Too Large"); - case 415: return F("Unsupported Media Type"); - case 416: return F("Requested range not satisfiable"); - case 417: return F("Expectation Failed"); - case 500: return F("Internal Server Error"); - case 501: return F("Not Implemented"); - case 502: return F("Bad Gateway"); - case 503: return F("Service Unavailable"); - case 504: return F("Gateway Time-out"); - case 505: return F("HTTP Version not supported"); - default: return F(""); + case 100: + return F("Continue"); + case 101: + return F("Switching Protocols"); + case 200: + return F("OK"); + case 201: + return F("Created"); + case 202: + return F("Accepted"); + case 203: + return F("Non-Authoritative Information"); + case 204: + return F("No Content"); + case 205: + return F("Reset Content"); + case 206: + return F("Partial Content"); + case 300: + return F("Multiple Choices"); + case 301: + return F("Moved Permanently"); + case 302: + return F("Found"); + case 303: + return F("See Other"); + case 304: + return F("Not Modified"); + case 305: + return F("Use Proxy"); + case 307: + return F("Temporary Redirect"); + case 400: + return F("Bad Request"); + case 401: + return F("Unauthorized"); + case 402: + return F("Payment Required"); + case 403: + return F("Forbidden"); + case 404: + return F("Not Found"); + case 405: + return F("Method Not Allowed"); + case 406: + return F("Not Acceptable"); + case 407: + return F("Proxy Authentication Required"); + case 408: + return F("Request Time-out"); + case 409: + return F("Conflict"); + case 410: + return F("Gone"); + case 411: + return F("Length Required"); + case 412: + return F("Precondition Failed"); + case 413: + return F("Request Entity Too Large"); + case 414: + return F("Request-URI Too Large"); + case 415: + return F("Unsupported Media Type"); + case 416: + return F("Requested range not satisfiable"); + case 417: + return F("Expectation Failed"); + case 500: + return F("Internal Server Error"); + case 501: + return F("Not Implemented"); + case 502: + return F("Bad Gateway"); + case 503: + return F("Service Unavailable"); + case 504: + return F("Gateway Time-out"); + case 505: + return F("HTTP Version not supported"); + default: + return F(""); } } AsyncWebServerResponse::AsyncWebServerResponse() - : _code(0) - , _contentType() - , _contentLength(0) - , _sendContentLength(true) - , _chunked(false) - , _headLength(0) - , _sentLength(0) - , _ackedLength(0) - , _writtenLength(0) - , _state(RESPONSE_SETUP) -{ - for(const auto &header: DefaultHeaders::Instance()) { + : _code(0), _contentType(), _contentLength(0), _sendContentLength(true), _chunked(false), _headLength(0), _sentLength(0), _ackedLength(0), _writtenLength(0), _state(RESPONSE_SETUP) { + for (const auto& header : DefaultHeaders::Instance()) { _headers.emplace_back(header); } } AsyncWebServerResponse::~AsyncWebServerResponse() = default; -void AsyncWebServerResponse::setCode(int code){ - if(_state == RESPONSE_SETUP) +void AsyncWebServerResponse::setCode(int code) { + if (_state == RESPONSE_SETUP) _code = code; } -void AsyncWebServerResponse::setContentLength(size_t len){ - if(_state == RESPONSE_SETUP) +void AsyncWebServerResponse::setContentLength(size_t len) { + if (_state == RESPONSE_SETUP) _contentLength = len; } -void AsyncWebServerResponse::setContentType(const String& type){ - if(_state == RESPONSE_SETUP) +void AsyncWebServerResponse::setContentType(const String& type) { + if (_state == RESPONSE_SETUP) _contentType = type; } -void AsyncWebServerResponse::addHeader(const String& name, const String& value){ +void AsyncWebServerResponse::addHeader(const String& name, const String& value) { _headers.emplace_back(name, value); } -String AsyncWebServerResponse::_assembleHead(uint8_t version){ - if(version){ +String AsyncWebServerResponse::_assembleHead(uint8_t version) { + if (version) { addHeader(F("Accept-Ranges"), F("none")); - if(_chunked) + if (_chunked) addHeader(F("Transfer-Encoding"), F("chunked")); } String out = String(); @@ -137,16 +166,16 @@ String AsyncWebServerResponse::_assembleHead(uint8_t version){ snprintf_P(buf, bufSize, PSTR("HTTP/1.%d %d %s\r\n"), version, _code, _responseCodeToString(_code)); out.concat(buf); - if(_sendContentLength) { + if (_sendContentLength) { snprintf_P(buf, bufSize, PSTR("Content-Length: %d\r\n"), _contentLength); out.concat(buf); } - if(_contentType.length()) { + if (_contentType.length()) { snprintf_P(buf, bufSize, PSTR("Content-Type: %s\r\n"), _contentType.c_str()); out.concat(buf); } - for(const auto& header: _headers){ + for (const auto& header : _headers) { snprintf_P(buf, bufSize, PSTR("%s: %s\r\n"), header.name().c_str(), header.value().c_str()); out.concat(buf); } @@ -161,44 +190,52 @@ bool AsyncWebServerResponse::_started() const { return _state > RESPONSE_SETUP; bool AsyncWebServerResponse::_finished() const { return _state > RESPONSE_WAIT_ACK; } bool AsyncWebServerResponse::_failed() const { return _state == RESPONSE_FAILED; } bool AsyncWebServerResponse::_sourceValid() const { return false; } -void AsyncWebServerResponse::_respond(AsyncWebServerRequest *request){ _state = RESPONSE_END; request->client()->close(); } -size_t AsyncWebServerResponse::_ack(AsyncWebServerRequest *request, size_t len, uint32_t time){ (void)request; (void)len; (void)time; return 0; } +void AsyncWebServerResponse::_respond(AsyncWebServerRequest* request) { + _state = RESPONSE_END; + request->client()->close(); +} +size_t AsyncWebServerResponse::_ack(AsyncWebServerRequest* request, size_t len, uint32_t time) { + (void)request; + (void)len; + (void)time; + return 0; +} /* * String/Code Response * */ -AsyncBasicResponse::AsyncBasicResponse(int code, const String& contentType, const String& content){ +AsyncBasicResponse::AsyncBasicResponse(int code, const String& contentType, const String& content) { _code = code; _content = content; _contentType = contentType; - if(_content.length()){ + if (_content.length()) { _contentLength = _content.length(); - if(!_contentType.length()) + if (!_contentType.length()) _contentType = F("text/plain"); } addHeader(F("Connection"), F("close")); } -void AsyncBasicResponse::_respond(AsyncWebServerRequest *request){ +void AsyncBasicResponse::_respond(AsyncWebServerRequest* request) { _state = RESPONSE_HEADERS; String out = _assembleHead(request->version()); size_t outLen = out.length(); size_t space = request->client()->space(); - if(!_contentLength && space >= outLen){ + if (!_contentLength && space >= outLen) { _writtenLength += request->client()->write(out.c_str(), outLen); _state = RESPONSE_WAIT_ACK; - } else if(_contentLength && space >= outLen + _contentLength){ + } else if (_contentLength && space >= outLen + _contentLength) { out += _content; outLen += _contentLength; _writtenLength += request->client()->write(out.c_str(), outLen); _state = RESPONSE_WAIT_ACK; - } else if(space && space < outLen){ + } else if (space && space < outLen) { String partial = out.substring(0, space); _content = out.substring(space) + _content; _contentLength += outLen - space; _writtenLength += request->client()->write(partial.c_str(), partial.length()); _state = RESPONSE_CONTENT; - } else if(space > outLen && space < (outLen + _contentLength)){ + } else if (space > outLen && space < (outLen + _contentLength)) { size_t shift = space - outLen; outLen += shift; _sentLength += shift; @@ -213,58 +250,56 @@ void AsyncBasicResponse::_respond(AsyncWebServerRequest *request){ } } -size_t AsyncBasicResponse::_ack(AsyncWebServerRequest *request, size_t len, uint32_t time){ +size_t AsyncBasicResponse::_ack(AsyncWebServerRequest* request, size_t len, uint32_t time) { (void)time; _ackedLength += len; - if(_state == RESPONSE_CONTENT){ + if (_state == RESPONSE_CONTENT) { size_t available = _contentLength - _sentLength; size_t space = request->client()->space(); - //we can fit in this packet - if(space > available){ + // we can fit in this packet + if (space > available) { _writtenLength += request->client()->write(_content.c_str(), available); _content = String(); _state = RESPONSE_WAIT_ACK; return available; } - //send some data, the rest on ack + // send some data, the rest on ack String out = _content.substring(0, space); _content = _content.substring(space); _sentLength += space; _writtenLength += request->client()->write(out.c_str(), space); return space; - } else if(_state == RESPONSE_WAIT_ACK){ - if(_ackedLength >= _writtenLength){ + } else if (_state == RESPONSE_WAIT_ACK) { + if (_ackedLength >= _writtenLength) { _state = RESPONSE_END; } } return 0; } - /* * Abstract Response * */ -AsyncAbstractResponse::AsyncAbstractResponse(AwsTemplateProcessor callback): _callback(callback) -{ +AsyncAbstractResponse::AsyncAbstractResponse(AwsTemplateProcessor callback) : _callback(callback) { // In case of template processing, we're unable to determine real response size - if(callback) { + if (callback) { _contentLength = 0; _sendContentLength = false; _chunked = true; } } -void AsyncAbstractResponse::_respond(AsyncWebServerRequest *request){ +void AsyncAbstractResponse::_respond(AsyncWebServerRequest* request) { addHeader(F("Connection"), F("close")); _head = _assembleHead(request->version()); _state = RESPONSE_HEADERS; _ack(request, 0, 0); } -size_t AsyncAbstractResponse::_ack(AsyncWebServerRequest *request, size_t len, uint32_t time){ +size_t AsyncAbstractResponse::_ack(AsyncWebServerRequest* request, size_t len, uint32_t time) { (void)time; - if(!_sourceValid()){ + if (!_sourceValid()) { _state = RESPONSE_FAILED; request->client()->close(); return 0; @@ -273,8 +308,8 @@ size_t AsyncAbstractResponse::_ack(AsyncWebServerRequest *request, size_t len, u size_t space = request->client()->space(); size_t headLen = _head.length(); - if(_state == RESPONSE_HEADERS){ - if(space >= headLen){ + if (_state == RESPONSE_HEADERS) { + if (space >= headLen) { _state = RESPONSE_CONTENT; space -= headLen; } else { @@ -285,103 +320,102 @@ size_t AsyncAbstractResponse::_ack(AsyncWebServerRequest *request, size_t len, u } } - if(_state == RESPONSE_CONTENT){ + if (_state == RESPONSE_CONTENT) { size_t outLen; - if(_chunked){ - if(space <= 8){ + if (_chunked) { + if (space <= 8) { return 0; } outLen = space; - } else if(!_sendContentLength){ + } else if (!_sendContentLength) { outLen = space; } else { - outLen = ((_contentLength - _sentLength) > space)?space:(_contentLength - _sentLength); + outLen = ((_contentLength - _sentLength) > space) ? space : (_contentLength - _sentLength); } - uint8_t *buf = (uint8_t *)malloc(outLen+headLen); + uint8_t* buf = (uint8_t*)malloc(outLen + headLen); if (!buf) { // os_printf("_ack malloc %d failed\n", outLen+headLen); return 0; } - if(headLen){ + if (headLen) { memcpy(buf, _head.c_str(), _head.length()); } size_t readLen = 0; - if(_chunked){ + if (_chunked) { // HTTP 1.1 allows leading zeros in chunk length. Or spaces may be added. // See RFC2616 sections 2, 3.6.1. - readLen = _fillBufferAndProcessTemplates(buf+headLen+6, outLen - 8); - if(readLen == RESPONSE_TRY_AGAIN){ - free(buf); - return 0; + readLen = _fillBufferAndProcessTemplates(buf + headLen + 6, outLen - 8); + if (readLen == RESPONSE_TRY_AGAIN) { + free(buf); + return 0; } - outLen = sprintf_P((char*)buf+headLen, PSTR("%x"), readLen) + headLen; - while(outLen < headLen + 4) buf[outLen++] = ' '; + outLen = sprintf_P((char*)buf + headLen, PSTR("%x"), readLen) + headLen; + while (outLen < headLen + 4) + buf[outLen++] = ' '; buf[outLen++] = '\r'; buf[outLen++] = '\n'; outLen += readLen; buf[outLen++] = '\r'; buf[outLen++] = '\n'; } else { - readLen = _fillBufferAndProcessTemplates(buf+headLen, outLen); - if(readLen == RESPONSE_TRY_AGAIN){ - free(buf); - return 0; + readLen = _fillBufferAndProcessTemplates(buf + headLen, outLen); + if (readLen == RESPONSE_TRY_AGAIN) { + free(buf); + return 0; } outLen = readLen + headLen; } - if(headLen){ - _head = String(); + if (headLen) { + _head = String(); } - if(outLen){ - _writtenLength += request->client()->write((const char*)buf, outLen); + if (outLen) { + _writtenLength += request->client()->write((const char*)buf, outLen); } - if(_chunked){ - _sentLength += readLen; + if (_chunked) { + _sentLength += readLen; } else { - _sentLength += outLen - headLen; + _sentLength += outLen - headLen; } free(buf); - if((_chunked && readLen == 0) || (!_sendContentLength && outLen == 0) || (!_chunked && _sentLength == _contentLength)){ + if ((_chunked && readLen == 0) || (!_sendContentLength && outLen == 0) || (!_chunked && _sentLength == _contentLength)) { _state = RESPONSE_WAIT_ACK; } return outLen; - } else if(_state == RESPONSE_WAIT_ACK){ - if(!_sendContentLength || _ackedLength >= _writtenLength){ + } else if (_state == RESPONSE_WAIT_ACK) { + if (!_sendContentLength || _ackedLength >= _writtenLength) { _state = RESPONSE_END; - if(!_chunked && !_sendContentLength) + if (!_chunked && !_sendContentLength) request->client()->close(true); } } return 0; } -size_t AsyncAbstractResponse::_readDataFromCacheOrContent(uint8_t* data, const size_t len) -{ - // If we have something in cache, copy it to buffer - const size_t readFromCache = std::min(len, _cache.size()); - if(readFromCache) { - memcpy(data, _cache.data(), readFromCache); - _cache.erase(_cache.begin(), _cache.begin() + readFromCache); - } - // If we need to read more... - const size_t needFromFile = len - readFromCache; - const size_t readFromContent = _fillBuffer(data + readFromCache, needFromFile); - return readFromCache + readFromContent; +size_t AsyncAbstractResponse::_readDataFromCacheOrContent(uint8_t* data, const size_t len) { + // If we have something in cache, copy it to buffer + const size_t readFromCache = std::min(len, _cache.size()); + if (readFromCache) { + memcpy(data, _cache.data(), readFromCache); + _cache.erase(_cache.begin(), _cache.begin() + readFromCache); + } + // If we need to read more... + const size_t needFromFile = len - readFromCache; + const size_t readFromContent = _fillBuffer(data + readFromCache, needFromFile); + return readFromCache + readFromContent; } -size_t AsyncAbstractResponse::_fillBufferAndProcessTemplates(uint8_t* data, size_t len) -{ - if(!_callback) +size_t AsyncAbstractResponse::_fillBufferAndProcessTemplates(uint8_t* data, size_t len) { + if (!_callback) return _fillBuffer(data, len); const size_t originalLen = len; @@ -389,16 +423,16 @@ size_t AsyncAbstractResponse::_fillBufferAndProcessTemplates(uint8_t* data, size // Now we've read 'len' bytes, either from cache or from file // Search for template placeholders uint8_t* pTemplateStart = data; - while((pTemplateStart < &data[len]) && (pTemplateStart = (uint8_t*)memchr(pTemplateStart, TEMPLATE_PLACEHOLDER, &data[len - 1] - pTemplateStart + 1))) { // data[0] ... data[len - 1] + while ((pTemplateStart < &data[len]) && (pTemplateStart = (uint8_t*)memchr(pTemplateStart, TEMPLATE_PLACEHOLDER, &data[len - 1] - pTemplateStart + 1))) { // data[0] ... data[len - 1] uint8_t* pTemplateEnd = (pTemplateStart < &data[len - 1]) ? (uint8_t*)memchr(pTemplateStart + 1, TEMPLATE_PLACEHOLDER, &data[len - 1] - pTemplateStart) : nullptr; // temporary buffer to hold parameter name uint8_t buf[TEMPLATE_PARAM_NAME_LENGTH + 1]; String paramName; // If closing placeholder is found: - if(pTemplateEnd) { + if (pTemplateEnd) { // prepare argument to callback const size_t paramNameLength = std::min((size_t)sizeof(buf) - 1, (size_t)(pTemplateEnd - pTemplateStart - 1)); - if(paramNameLength) { + if (paramNameLength) { memcpy(buf, pTemplateStart + 1, paramNameLength); buf[paramNameLength] = 0; paramName = String(reinterpret_cast(buf)); @@ -408,32 +442,29 @@ size_t AsyncAbstractResponse::_fillBufferAndProcessTemplates(uint8_t* data, size len += _readDataFromCacheOrContent(&data[len - 1], 1) - 1; ++pTemplateStart; } - } else if(&data[len - 1] - pTemplateStart + 1 < TEMPLATE_PARAM_NAME_LENGTH + 2) { // closing placeholder not found, check if it's in the remaining file data + } else if (&data[len - 1] - pTemplateStart + 1 < TEMPLATE_PARAM_NAME_LENGTH + 2) { // closing placeholder not found, check if it's in the remaining file data memcpy(buf, pTemplateStart + 1, &data[len - 1] - pTemplateStart); const size_t readFromCacheOrContent = _readDataFromCacheOrContent(buf + (&data[len - 1] - pTemplateStart), TEMPLATE_PARAM_NAME_LENGTH + 2 - (&data[len - 1] - pTemplateStart + 1)); - if(readFromCacheOrContent) { + if (readFromCacheOrContent) { pTemplateEnd = (uint8_t*)memchr(buf + (&data[len - 1] - pTemplateStart), TEMPLATE_PLACEHOLDER, readFromCacheOrContent); - if(pTemplateEnd) { + if (pTemplateEnd) { // prepare argument to callback *pTemplateEnd = 0; paramName = String(reinterpret_cast(buf)); // Copy remaining read-ahead data into cache _cache.insert(_cache.begin(), pTemplateEnd + 1, buf + (&data[len - 1] - pTemplateStart) + readFromCacheOrContent); pTemplateEnd = &data[len - 1]; - } - else // closing placeholder not found in file data, store found percent symbol as is and advance to the next position + } else // closing placeholder not found in file data, store found percent symbol as is and advance to the next position { // but first, store read file data in cache _cache.insert(_cache.begin(), buf + (&data[len - 1] - pTemplateStart), buf + (&data[len - 1] - pTemplateStart) + readFromCacheOrContent); ++pTemplateStart; } - } - else // closing placeholder not found in content data, store found percent symbol as is and advance to the next position + } else // closing placeholder not found in content data, store found percent symbol as is and advance to the next position ++pTemplateStart; - } - else // closing placeholder not found in content data, store found percent symbol as is and advance to the next position + } else // closing placeholder not found in content data, store found percent symbol as is and advance to the next position ++pTemplateStart; - if(paramName.length()) { + if (paramName.length()) { // call callback and replace with result. // Everything in range [pTemplateStart, pTemplateEnd] can be safely replaced with parameter value. // Data after pTemplateEnd may need to be moved. @@ -445,21 +476,21 @@ size_t AsyncAbstractResponse::_fillBufferAndProcessTemplates(uint8_t* data, size const size_t numBytesCopied = std::min(pvlen, static_cast(&data[originalLen - 1] - pTemplateStart + 1)); // make room for param value // 1. move extra data to cache if parameter value is longer than placeholder AND if there is no room to store - if((pTemplateEnd + 1 < pTemplateStart + numBytesCopied) && (originalLen - (pTemplateStart + numBytesCopied - pTemplateEnd - 1) < len)) { + if ((pTemplateEnd + 1 < pTemplateStart + numBytesCopied) && (originalLen - (pTemplateStart + numBytesCopied - pTemplateEnd - 1) < len)) { _cache.insert(_cache.begin(), &data[originalLen - (pTemplateStart + numBytesCopied - pTemplateEnd - 1)], &data[len]); - //2. parameter value is longer than placeholder text, push the data after placeholder which not saved into cache further to the end + // 2. parameter value is longer than placeholder text, push the data after placeholder which not saved into cache further to the end memmove(pTemplateStart + numBytesCopied, pTemplateEnd + 1, &data[originalLen] - pTemplateStart - numBytesCopied); len = originalLen; // fix issue with truncated data, not sure if it has any side effects - } else if(pTemplateEnd + 1 != pTemplateStart + numBytesCopied) - //2. Either parameter value is shorter than placeholder text OR there is enough free space in buffer to fit. - // Move the entire data after the placeholder + } else if (pTemplateEnd + 1 != pTemplateStart + numBytesCopied) + // 2. Either parameter value is shorter than placeholder text OR there is enough free space in buffer to fit. + // Move the entire data after the placeholder memmove(pTemplateStart + numBytesCopied, pTemplateEnd + 1, &data[len] - pTemplateEnd - 1); // 3. replace placeholder with actual value memcpy(pTemplateStart, pvstr, numBytesCopied); // If result is longer than buffer, copy the remainder into cache (this could happen only if placeholder text itself did not fit entirely in buffer) - if(numBytesCopied < pvlen) { + if (numBytesCopied < pvlen) { _cache.insert(_cache.begin(), pvstr + numBytesCopied, pvstr + pvlen); - } else if(pTemplateStart + numBytesCopied < pTemplateEnd + 1) { // result is copied fully; if result is shorter than placeholder text... + } else if (pTemplateStart + numBytesCopied < pTemplateEnd + 1) { // result is copied fully; if result is shorter than placeholder text... // there is some free room, fill it from cache const size_t roomFreed = pTemplateEnd + 1 - pTemplateStart - numBytesCopied; const size_t totalFreeRoom = originalLen - len + roomFreed; @@ -473,48 +504,66 @@ size_t AsyncAbstractResponse::_fillBufferAndProcessTemplates(uint8_t* data, size return len; } - /* * File Response * */ -AsyncFileResponse::~AsyncFileResponse(){ - if(_content) +AsyncFileResponse::~AsyncFileResponse() { + if (_content) _content.close(); } -void AsyncFileResponse::_setContentType(const String& path){ +void AsyncFileResponse::_setContentType(const String& path) { #if HAVE_EXTERN_GET_CONTENT_TYPE_FUNCTION - extern const __FlashStringHelper *getContentType(const String &path); + extern const __FlashStringHelper* getContentType(const String& path); _contentType = getContentType(path); #else - if (path.endsWith(F(".html"))) _contentType = F("text/html"); - else if (path.endsWith(F(".htm"))) _contentType = F("text/html"); - else if (path.endsWith(F(".css"))) _contentType = F("text/css"); - else if (path.endsWith(F(".json"))) _contentType = F("application/json"); - else if (path.endsWith(F(".js"))) _contentType = F("application/javascript"); - else if (path.endsWith(F(".png"))) _contentType = F("image/png"); - else if (path.endsWith(F(".gif"))) _contentType = F("image/gif"); - else if (path.endsWith(F(".jpg"))) _contentType = F("image/jpeg"); - else if (path.endsWith(F(".ico"))) _contentType = F("image/x-icon"); - else if (path.endsWith(F(".svg"))) _contentType = F("image/svg+xml"); - else if (path.endsWith(F(".eot"))) _contentType = F("font/eot"); - else if (path.endsWith(F(".woff"))) _contentType = F("font/woff"); - else if (path.endsWith(F(".woff2"))) _contentType = F("font/woff2"); - else if (path.endsWith(F(".ttf"))) _contentType = F("font/ttf"); - else if (path.endsWith(F(".xml"))) _contentType = F("text/xml"); - else if (path.endsWith(F(".pdf"))) _contentType = F("application/pdf"); - else if (path.endsWith(F(".zip"))) _contentType = F("application/zip"); - else if(path.endsWith(F(".gz"))) _contentType = F("application/x-gzip"); - else _contentType = F("text/plain"); + if (path.endsWith(F(".html"))) + _contentType = F("text/html"); + else if (path.endsWith(F(".htm"))) + _contentType = F("text/html"); + else if (path.endsWith(F(".css"))) + _contentType = F("text/css"); + else if (path.endsWith(F(".json"))) + _contentType = F("application/json"); + else if (path.endsWith(F(".js"))) + _contentType = F("application/javascript"); + else if (path.endsWith(F(".png"))) + _contentType = F("image/png"); + else if (path.endsWith(F(".gif"))) + _contentType = F("image/gif"); + else if (path.endsWith(F(".jpg"))) + _contentType = F("image/jpeg"); + else if (path.endsWith(F(".ico"))) + _contentType = F("image/x-icon"); + else if (path.endsWith(F(".svg"))) + _contentType = F("image/svg+xml"); + else if (path.endsWith(F(".eot"))) + _contentType = F("font/eot"); + else if (path.endsWith(F(".woff"))) + _contentType = F("font/woff"); + else if (path.endsWith(F(".woff2"))) + _contentType = F("font/woff2"); + else if (path.endsWith(F(".ttf"))) + _contentType = F("font/ttf"); + else if (path.endsWith(F(".xml"))) + _contentType = F("text/xml"); + else if (path.endsWith(F(".pdf"))) + _contentType = F("application/pdf"); + else if (path.endsWith(F(".zip"))) + _contentType = F("application/zip"); + else if (path.endsWith(F(".gz"))) + _contentType = F("application/x-gzip"); + else + _contentType = F("text/plain"); #endif } -AsyncFileResponse::AsyncFileResponse(FS &fs, const String& path, const String& contentType, bool download, AwsTemplateProcessor callback): AsyncAbstractResponse(callback){ +AsyncFileResponse::AsyncFileResponse(FS& fs, const String& path, const String& contentType, bool download, AwsTemplateProcessor callback) : AsyncAbstractResponse(callback) { _code = 200; _path = path; - if(!download && !fs.exists(_path) && fs.exists(_path + F(".gz"))){ + if (!download && !fs.exists(_path) && fs.exists(_path + F(".gz"))) { _path = _path + F(".gz"); addHeader(F("Content-Encoding"), F("gzip")); _callback = nullptr; // Unable to process zipped templates @@ -525,30 +574,30 @@ AsyncFileResponse::AsyncFileResponse(FS &fs, const String& path, const String& c _content = fs.open(_path, fs::FileOpenMode::read); _contentLength = _content.size(); - if(contentType.length() == 0) + if (contentType.length() == 0) _setContentType(path); else _contentType = contentType; int filenameStart = path.lastIndexOf('/') + 1; - char buf[26+path.length()-filenameStart]; + char buf[26 + path.length() - filenameStart]; char* filename = (char*)path.c_str() + filenameStart; - if(download) { + if (download) { // set filename and force download - snprintf_P(buf, sizeof (buf), PSTR("attachment; filename=\"%s\""), filename); + snprintf_P(buf, sizeof(buf), PSTR("attachment; filename=\"%s\""), filename); } else { // set filename and force rendering - snprintf_P(buf, sizeof (buf), PSTR("inline")); + snprintf_P(buf, sizeof(buf), PSTR("inline")); } addHeader(F("Content-Disposition"), buf); } -AsyncFileResponse::AsyncFileResponse(File content, const String& path, const String& contentType, bool download, AwsTemplateProcessor callback): AsyncAbstractResponse(callback){ +AsyncFileResponse::AsyncFileResponse(File content, const String& path, const String& contentType, bool download, AwsTemplateProcessor callback) : AsyncAbstractResponse(callback) { _code = 200; _path = path; - if(!download && String(content.name()).endsWith(F(".gz")) && !path.endsWith(F(".gz"))){ + if (!download && String(content.name()).endsWith(F(".gz")) && !path.endsWith(F(".gz"))) { addHeader(F("Content-Encoding"), F("gzip")); _callback = nullptr; // Unable to process gzipped templates _sendContentLength = true; @@ -558,24 +607,24 @@ AsyncFileResponse::AsyncFileResponse(File content, const String& path, const Str _content = content; _contentLength = _content.size(); - if(contentType.length() == 0) + if (contentType.length() == 0) _setContentType(path); else _contentType = contentType; int filenameStart = path.lastIndexOf('/') + 1; - char buf[26+path.length()-filenameStart]; + char buf[26 + path.length() - filenameStart]; char* filename = (char*)path.c_str() + filenameStart; - if(download) { - snprintf_P(buf, sizeof (buf), PSTR("attachment; filename=\"%s\""), filename); + if (download) { + snprintf_P(buf, sizeof(buf), PSTR("attachment; filename=\"%s\""), filename); } else { - snprintf_P(buf, sizeof (buf), PSTR("inline")); + snprintf_P(buf, sizeof(buf), PSTR("inline")); } addHeader(F("Content-Disposition"), buf); } -size_t AsyncFileResponse::_fillBuffer(uint8_t *data, size_t len){ +size_t AsyncFileResponse::_fillBuffer(uint8_t* data, size_t len) { return _content.read(data, len); } @@ -583,18 +632,18 @@ size_t AsyncFileResponse::_fillBuffer(uint8_t *data, size_t len){ * Stream Response * */ -AsyncStreamResponse::AsyncStreamResponse(Stream &stream, const String& contentType, size_t len, AwsTemplateProcessor callback): AsyncAbstractResponse(callback) { +AsyncStreamResponse::AsyncStreamResponse(Stream& stream, const String& contentType, size_t len, AwsTemplateProcessor callback) : AsyncAbstractResponse(callback) { _code = 200; _content = &stream; _contentLength = len; _contentType = contentType; } -size_t AsyncStreamResponse::_fillBuffer(uint8_t *data, size_t len){ +size_t AsyncStreamResponse::_fillBuffer(uint8_t* data, size_t len) { size_t available = _content->available(); - size_t outLen = (available > len)?len:available; + size_t outLen = (available > len) ? len : available; size_t i; - for(i=0;iread(); return outLen; } @@ -603,20 +652,20 @@ size_t AsyncStreamResponse::_fillBuffer(uint8_t *data, size_t len){ * Callback Response * */ -AsyncCallbackResponse::AsyncCallbackResponse(const String& contentType, size_t len, AwsResponseFiller callback, AwsTemplateProcessor templateCallback): AsyncAbstractResponse(templateCallback) { +AsyncCallbackResponse::AsyncCallbackResponse(const String& contentType, size_t len, AwsResponseFiller callback, AwsTemplateProcessor templateCallback) : AsyncAbstractResponse(templateCallback) { _code = 200; _content = callback; _contentLength = len; - if(!len) + if (!len) _sendContentLength = false; _contentType = contentType; _filledLength = 0; } -size_t AsyncCallbackResponse::_fillBuffer(uint8_t *data, size_t len){ +size_t AsyncCallbackResponse::_fillBuffer(uint8_t* data, size_t len) { size_t ret = _content(data, len, _filledLength); - if(ret != RESPONSE_TRY_AGAIN){ - _filledLength += ret; + if (ret != RESPONSE_TRY_AGAIN) { + _filledLength += ret; } return ret; } @@ -625,7 +674,7 @@ size_t AsyncCallbackResponse::_fillBuffer(uint8_t *data, size_t len){ * Chunked Response * */ -AsyncChunkedResponse::AsyncChunkedResponse(const String& contentType, AwsResponseFiller callback, AwsTemplateProcessor processorCallback): AsyncAbstractResponse(processorCallback) { +AsyncChunkedResponse::AsyncChunkedResponse(const String& contentType, AwsResponseFiller callback, AwsTemplateProcessor processorCallback) : AsyncAbstractResponse(processorCallback) { _code = 200; _content = callback; _contentLength = 0; @@ -635,10 +684,10 @@ AsyncChunkedResponse::AsyncChunkedResponse(const String& contentType, AwsRespons _filledLength = 0; } -size_t AsyncChunkedResponse::_fillBuffer(uint8_t *data, size_t len){ +size_t AsyncChunkedResponse::_fillBuffer(uint8_t* data, size_t len) { size_t ret = _content(data, len, _filledLength); - if(ret != RESPONSE_TRY_AGAIN){ - _filledLength += ret; + if (ret != RESPONSE_TRY_AGAIN) { + _filledLength += ret; } return ret; } @@ -647,7 +696,7 @@ size_t AsyncChunkedResponse::_fillBuffer(uint8_t *data, size_t len){ * Progmem Response * */ -AsyncProgmemResponse::AsyncProgmemResponse(int code, const String& contentType, const uint8_t * content, size_t len, AwsTemplateProcessor callback): AsyncAbstractResponse(callback) { +AsyncProgmemResponse::AsyncProgmemResponse(int code, const String& contentType, const uint8_t* content, size_t len, AwsTemplateProcessor callback) : AsyncAbstractResponse(callback) { _code = code; _content = content; _contentType = contentType; @@ -655,7 +704,7 @@ AsyncProgmemResponse::AsyncProgmemResponse(int code, const String& contentType, _readLength = 0; } -size_t AsyncProgmemResponse::_fillBuffer(uint8_t *data, size_t len){ +size_t AsyncProgmemResponse::_fillBuffer(uint8_t* data, size_t len) { size_t left = _contentLength - _readLength; if (left > len) { memcpy_P(data, _content + _readLength, len); @@ -667,30 +716,28 @@ size_t AsyncProgmemResponse::_fillBuffer(uint8_t *data, size_t len){ return left; } - /* * Response Stream (You can print/write/printf to it, up to the contentLen bytes) * */ -AsyncResponseStream::AsyncResponseStream(const String& contentType, size_t bufferSize) -{ +AsyncResponseStream::AsyncResponseStream(const String& contentType, size_t bufferSize) { _code = 200; _contentLength = 0; _contentType = contentType; - _content = std::unique_ptr(new cbuf(bufferSize)); //std::make_unique(bufferSize); + _content = std::unique_ptr(new cbuf(bufferSize)); // std::make_unique(bufferSize); } AsyncResponseStream::~AsyncResponseStream() = default; -size_t AsyncResponseStream::_fillBuffer(uint8_t *buf, size_t maxLen){ +size_t AsyncResponseStream::_fillBuffer(uint8_t* buf, size_t maxLen) { return _content->read((char*)buf, maxLen); } -size_t AsyncResponseStream::write(const uint8_t *data, size_t len){ - if(_started()) +size_t AsyncResponseStream::write(const uint8_t* data, size_t len) { + if (_started()) return 0; - if(len > _content->room()){ + if (len > _content->room()) { size_t needed = len - _content->room(); _content->resizeAdd(needed); } @@ -699,6 +746,6 @@ size_t AsyncResponseStream::write(const uint8_t *data, size_t len){ return written; } -size_t AsyncResponseStream::write(uint8_t data){ +size_t AsyncResponseStream::write(uint8_t data) { return write(&data, 1); } diff --git a/src/WebServer.cpp b/src/WebServer.cpp index ebd464a90..9d78e027b 100644 --- a/src/WebServer.cpp +++ b/src/WebServer.cpp @@ -21,63 +21,63 @@ #include "ESPAsyncWebServer.h" #include "WebHandlerImpl.h" -bool ON_STA_FILTER(AsyncWebServerRequest *request) { +bool ON_STA_FILTER(AsyncWebServerRequest* request) { return WiFi.localIP() == request->client()->localIP(); } -bool ON_AP_FILTER(AsyncWebServerRequest *request) { +bool ON_AP_FILTER(AsyncWebServerRequest* request) { return WiFi.localIP() != request->client()->localIP(); } #ifndef HAVE_FS_FILE_OPEN_MODE -const char *fs::FileOpenMode::read = "r"; -const char *fs::FileOpenMode::write = "w"; -const char *fs::FileOpenMode::append = "a"; +const char* fs::FileOpenMode::read = "r"; +const char* fs::FileOpenMode::write = "w"; +const char* fs::FileOpenMode::append = "a"; #endif AsyncWebServer::AsyncWebServer(uint16_t port) - : _server(port) -{ + : _server(port) { _catchAllHandler = new AsyncCallbackWebHandler(); - if(_catchAllHandler == NULL) + if (_catchAllHandler == NULL) return; - _server.onClient([](void *s, AsyncClient* c){ - if(c == NULL) + _server.onClient([](void* s, AsyncClient* c) { + if (c == NULL) return; c->setRxTimeout(3); - AsyncWebServerRequest *r = new AsyncWebServerRequest((AsyncWebServer*)s, c); - if(r == NULL){ + AsyncWebServerRequest* r = new AsyncWebServerRequest((AsyncWebServer*)s, c); + if (r == NULL) { c->close(true); c->free(); delete c; } - }, this); + }, + this); } -AsyncWebServer::~AsyncWebServer(){ +AsyncWebServer::~AsyncWebServer() { reset(); end(); - if(_catchAllHandler) delete _catchAllHandler; + if (_catchAllHandler) + delete _catchAllHandler; } -AsyncWebRewrite& AsyncWebServer::addRewrite(std::shared_ptr rewrite){ +AsyncWebRewrite& AsyncWebServer::addRewrite(std::shared_ptr rewrite) { _rewrites.emplace_back(rewrite); return *_rewrites.back().get(); } - -AsyncWebRewrite& AsyncWebServer::addRewrite(AsyncWebRewrite* rewrite){ +AsyncWebRewrite& AsyncWebServer::addRewrite(AsyncWebRewrite* rewrite) { _rewrites.emplace_back(rewrite); return *_rewrites.back().get(); } -bool AsyncWebServer::removeRewrite(AsyncWebRewrite *rewrite){ +bool AsyncWebServer::removeRewrite(AsyncWebRewrite* rewrite) { return removeRewrite(rewrite->from().c_str(), rewrite->toUrl().c_str()); } -bool AsyncWebServer::removeRewrite(const char* from, const char* to){ - for(auto r = _rewrites.begin(); r != _rewrites.end(); ++r ){ - if (r->get()->from() == from && r->get()->toUrl() == to){ +bool AsyncWebServer::removeRewrite(const char* from, const char* to) { + for (auto r = _rewrites.begin(); r != _rewrites.end(); ++r) { + if (r->get()->from() == from && r->get()->toUrl() == to) { _rewrites.erase(r); return true; } @@ -85,19 +85,19 @@ bool AsyncWebServer::removeRewrite(const char* from, const char* to){ return false; } -AsyncWebRewrite& AsyncWebServer::rewrite(const char* from, const char* to){ +AsyncWebRewrite& AsyncWebServer::rewrite(const char* from, const char* to) { _rewrites.emplace_back(std::make_shared(from, to)); return *_rewrites.back().get(); } -AsyncWebHandler& AsyncWebServer::addHandler(AsyncWebHandler* handler){ +AsyncWebHandler& AsyncWebServer::addHandler(AsyncWebHandler* handler) { _handlers.emplace_back(handler); return *(_handlers.back().get()); } -bool AsyncWebServer::removeHandler(AsyncWebHandler *handler){ - for (auto i = _handlers.begin(); i != _handlers.end(); ++i){ - if (i->get() == handler ){ +bool AsyncWebServer::removeHandler(AsyncWebHandler* handler) { + for (auto i = _handlers.begin(); i != _handlers.end(); ++i) { + if (i->get() == handler) { _handlers.erase(i); return true; } @@ -105,41 +105,41 @@ bool AsyncWebServer::removeHandler(AsyncWebHandler *handler){ return false; } -void AsyncWebServer::begin(){ +void AsyncWebServer::begin() { _server.setNoDelay(true); _server.begin(); } -void AsyncWebServer::end(){ +void AsyncWebServer::end() { _server.end(); } #if ASYNC_TCP_SSL_ENABLED -void AsyncWebServer::onSslFileRequest(AcSSlFileHandler cb, void* arg){ +void AsyncWebServer::onSslFileRequest(AcSSlFileHandler cb, void* arg) { _server.onSslFileRequest(cb, arg); } -void AsyncWebServer::beginSecure(const char *cert, const char *key, const char *password){ +void AsyncWebServer::beginSecure(const char* cert, const char* key, const char* password) { _server.beginSecure(cert, key, password); } #endif -void AsyncWebServer::_handleDisconnect(AsyncWebServerRequest *request){ +void AsyncWebServer::_handleDisconnect(AsyncWebServerRequest* request) { delete request; } -void AsyncWebServer::_rewriteRequest(AsyncWebServerRequest *request){ - for(const auto& r: _rewrites){ - if (r->match(request)){ +void AsyncWebServer::_rewriteRequest(AsyncWebServerRequest* request) { + for (const auto& r : _rewrites) { + if (r->match(request)) { request->_url = r->toUrl(); request->_addGetParams(r->params()); } } } -void AsyncWebServer::_attachHandler(AsyncWebServerRequest *request){ - for(auto& h: _handlers){ - if (h->filter(request) && h->canHandle(request)){ +void AsyncWebServer::_attachHandler(AsyncWebServerRequest* request) { + for (auto& h : _handlers) { + if (h->filter(request) && h->canHandle(request)) { request->setHandler(h.get()); return; } @@ -149,8 +149,7 @@ void AsyncWebServer::_attachHandler(AsyncWebServerRequest *request){ request->setHandler(_catchAllHandler); } - -AsyncCallbackWebHandler& AsyncWebServer::on(const char* uri, WebRequestMethodComposite method, ArRequestHandlerFunction onRequest, ArUploadHandlerFunction onUpload, ArBodyHandlerFunction onBody){ +AsyncCallbackWebHandler& AsyncWebServer::on(const char* uri, WebRequestMethodComposite method, ArRequestHandlerFunction onRequest, ArUploadHandlerFunction onUpload, ArBodyHandlerFunction onBody) { AsyncCallbackWebHandler* handler = new AsyncCallbackWebHandler(); handler->setUri(uri); handler->setMethod(method); @@ -161,7 +160,7 @@ AsyncCallbackWebHandler& AsyncWebServer::on(const char* uri, WebRequestMethodCom return *handler; } -AsyncCallbackWebHandler& AsyncWebServer::on(const char* uri, WebRequestMethodComposite method, ArRequestHandlerFunction onRequest, ArUploadHandlerFunction onUpload){ +AsyncCallbackWebHandler& AsyncWebServer::on(const char* uri, WebRequestMethodComposite method, ArRequestHandlerFunction onRequest, ArUploadHandlerFunction onUpload) { AsyncCallbackWebHandler* handler = new AsyncCallbackWebHandler(); handler->setUri(uri); handler->setMethod(method); @@ -171,7 +170,7 @@ AsyncCallbackWebHandler& AsyncWebServer::on(const char* uri, WebRequestMethodCom return *handler; } -AsyncCallbackWebHandler& AsyncWebServer::on(const char* uri, WebRequestMethodComposite method, ArRequestHandlerFunction onRequest){ +AsyncCallbackWebHandler& AsyncWebServer::on(const char* uri, WebRequestMethodComposite method, ArRequestHandlerFunction onRequest) { AsyncCallbackWebHandler* handler = new AsyncCallbackWebHandler(); handler->setUri(uri); handler->setMethod(method); @@ -180,7 +179,7 @@ AsyncCallbackWebHandler& AsyncWebServer::on(const char* uri, WebRequestMethodCom return *handler; } -AsyncCallbackWebHandler& AsyncWebServer::on(const char* uri, ArRequestHandlerFunction onRequest){ +AsyncCallbackWebHandler& AsyncWebServer::on(const char* uri, ArRequestHandlerFunction onRequest) { AsyncCallbackWebHandler* handler = new AsyncCallbackWebHandler(); handler->setUri(uri); handler->onRequest(onRequest); @@ -188,32 +187,31 @@ AsyncCallbackWebHandler& AsyncWebServer::on(const char* uri, ArRequestHandlerFun return *handler; } -AsyncStaticWebHandler& AsyncWebServer::serveStatic(const char* uri, fs::FS& fs, const char* path, const char* cache_control){ +AsyncStaticWebHandler& AsyncWebServer::serveStatic(const char* uri, fs::FS& fs, const char* path, const char* cache_control) { AsyncStaticWebHandler* handler = new AsyncStaticWebHandler(uri, fs, path, cache_control); addHandler(handler); return *handler; } -void AsyncWebServer::onNotFound(ArRequestHandlerFunction fn){ +void AsyncWebServer::onNotFound(ArRequestHandlerFunction fn) { _catchAllHandler->onRequest(fn); } -void AsyncWebServer::onFileUpload(ArUploadHandlerFunction fn){ +void AsyncWebServer::onFileUpload(ArUploadHandlerFunction fn) { _catchAllHandler->onUpload(fn); } -void AsyncWebServer::onRequestBody(ArBodyHandlerFunction fn){ +void AsyncWebServer::onRequestBody(ArBodyHandlerFunction fn) { _catchAllHandler->onBody(fn); } -void AsyncWebServer::reset(){ +void AsyncWebServer::reset() { _rewrites.clear(); _handlers.clear(); - if (_catchAllHandler != NULL){ + if (_catchAllHandler != NULL) { _catchAllHandler->onRequest(NULL); _catchAllHandler->onUpload(NULL); _catchAllHandler->onBody(NULL); } } - From 5f208fbb21098908c8420b3ccd804ca4355ba069 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Thu, 27 Jun 2024 21:19:23 +0200 Subject: [PATCH 258/551] update site --- README.md | 1 + docs/index.md | 1 + 2 files changed, 2 insertions(+) diff --git a/README.md b/README.md index 6ac046985..dc87c0742 100644 --- a/README.md +++ b/README.md @@ -36,6 +36,7 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo - [@tueddy](https://github.com/tueddy): Compile with Arduino 3 (ESP-IDF 5.1) ([#13](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/13)) - [@vortigont](https://github.com/vortigont): Set real "Last-Modified" header based on file's LastWrite time ([#5](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/5)) - [@vortigont](https://github.com/vortigont): Some websocket code cleanup ([#29](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/29)) +- [@vortigont](https://github.com/vortigont): Refactor code - replace DYI structs with STL objects ([#39](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/39)) **In progress** diff --git a/docs/index.md b/docs/index.md index 6ac046985..dc87c0742 100644 --- a/docs/index.md +++ b/docs/index.md @@ -36,6 +36,7 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo - [@tueddy](https://github.com/tueddy): Compile with Arduino 3 (ESP-IDF 5.1) ([#13](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/13)) - [@vortigont](https://github.com/vortigont): Set real "Last-Modified" header based on file's LastWrite time ([#5](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/5)) - [@vortigont](https://github.com/vortigont): Some websocket code cleanup ([#29](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/29)) +- [@vortigont](https://github.com/vortigont): Refactor code - replace DYI structs with STL objects ([#39](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/39)) **In progress** From 3140341235aa3fa01eb669eb09d6651ef2ff7e53 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Thu, 27 Jun 2024 21:39:38 +0200 Subject: [PATCH 259/551] Reformated examples --- examples/CaptivePortal/CaptivePortal.ino | 56 ++++++++--------- examples/Draft/Draft.ino | 2 +- examples/Filters/Filters.ino | 8 +-- examples/SimpleServer/SimpleServer.ino | 80 ++++++++++++------------ examples/StreamFiles/StreamFiles.ino | 8 +-- 5 files changed, 77 insertions(+), 77 deletions(-) diff --git a/examples/CaptivePortal/CaptivePortal.ino b/examples/CaptivePortal/CaptivePortal.ino index c06dccd83..cb0b193aa 100644 --- a/examples/CaptivePortal/CaptivePortal.ino +++ b/examples/CaptivePortal/CaptivePortal.ino @@ -1,10 +1,10 @@ #include #ifdef ESP32 -#include -#include + #include + #include #elif defined(ESP8266) -#include -#include + #include + #include #endif #include "ESPAsyncWebServer.h" @@ -12,43 +12,43 @@ DNSServer dnsServer; AsyncWebServer server(80); class CaptiveRequestHandler : public AsyncWebHandler { -public: - CaptiveRequestHandler() {} - virtual ~CaptiveRequestHandler() {} - - bool canHandle(__unused AsyncWebServerRequest *request){ - //request->addInterestingHeader("ANY"); - return true; - } - - void handleRequest(AsyncWebServerRequest *request) { - AsyncResponseStream *response = request->beginResponseStream("text/html"); - response->print("Captive Portal"); - response->print("

This is out captive portal front page.

"); - response->printf("

You were trying to reach: http://%s%s

", request->host().c_str(), request->url().c_str()); - response->printf("

Try opening this link instead

", WiFi.softAPIP().toString().c_str()); - response->print(""); - request->send(response); - } + public: + CaptiveRequestHandler() {} + virtual ~CaptiveRequestHandler() {} + + bool canHandle(__unused AsyncWebServerRequest* request) { + // request->addInterestingHeader("ANY"); + return true; + } + + void handleRequest(AsyncWebServerRequest* request) { + AsyncResponseStream* response = request->beginResponseStream("text/html"); + response->print("Captive Portal"); + response->print("

This is out captive portal front page.

"); + response->printf("

You were trying to reach: http://%s%s

", request->host().c_str(), request->url().c_str()); + response->printf("

Try opening this link instead

", WiFi.softAPIP().toString().c_str()); + response->print(""); + request->send(response); + } }; - -void setup(){ +void setup() { Serial.begin(115200); Serial.println(); Serial.println("Configuring access point..."); if (!WiFi.softAP("esp-captive")) { Serial.println("Soft AP creation failed."); - while (1); + while (1) + ; } dnsServer.start(53, "*", WiFi.softAPIP()); - server.addHandler(new CaptiveRequestHandler()).setFilter(ON_AP_FILTER);//only when requested from AP - //more handlers... + server.addHandler(new CaptiveRequestHandler()).setFilter(ON_AP_FILTER); // only when requested from AP + // more handlers... server.begin(); } -void loop(){ +void loop() { dnsServer.processNextRequest(); } diff --git a/examples/Draft/Draft.ino b/examples/Draft/Draft.ino index 0a1cb1fe7..f10a9e7a5 100644 --- a/examples/Draft/Draft.ino +++ b/examples/Draft/Draft.ino @@ -1,6 +1,6 @@ +#include "mbedtls/md5.h" #include #include -#include "mbedtls/md5.h" void setup() { Serial.begin(115200); diff --git a/examples/Filters/Filters.ino b/examples/Filters/Filters.ino index 90b6f19a0..d26c59fb7 100644 --- a/examples/Filters/Filters.ino +++ b/examples/Filters/Filters.ino @@ -2,11 +2,11 @@ #include #ifdef ESP32 -#include -#include + #include + #include #elif defined(ESP8266) -#include -#include + #include + #include #endif #include "ESPAsyncWebServer.h" diff --git a/examples/SimpleServer/SimpleServer.ino b/examples/SimpleServer/SimpleServer.ino index bdbcf60dc..ed07401ed 100644 --- a/examples/SimpleServer/SimpleServer.ino +++ b/examples/SimpleServer/SimpleServer.ino @@ -7,11 +7,11 @@ #include #ifdef ESP32 -#include -#include + #include + #include #elif defined(ESP8266) -#include -#include + #include + #include #endif #include @@ -22,52 +22,52 @@ const char* password = "YOUR_PASSWORD"; const char* PARAM_MESSAGE = "message"; -void notFound(AsyncWebServerRequest *request) { - request->send(404, "text/plain", "Not found"); +void notFound(AsyncWebServerRequest* request) { + request->send(404, "text/plain", "Not found"); } void setup() { - Serial.begin(115200); - WiFi.mode(WIFI_STA); - WiFi.begin(ssid, password); - if (WiFi.waitForConnectResult() != WL_CONNECTED) { - Serial.printf("WiFi Failed!\n"); - return; - } + Serial.begin(115200); + WiFi.mode(WIFI_STA); + WiFi.begin(ssid, password); + if (WiFi.waitForConnectResult() != WL_CONNECTED) { + Serial.printf("WiFi Failed!\n"); + return; + } - Serial.print("IP Address: "); - Serial.println(WiFi.localIP()); + Serial.print("IP Address: "); + Serial.println(WiFi.localIP()); - server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){ - request->send(200, "text/plain", "Hello, world"); - }); + server.on("/", HTTP_GET, [](AsyncWebServerRequest* request) { + request->send(200, "text/plain", "Hello, world"); + }); - // Send a GET request to /get?message= - server.on("/get", HTTP_GET, [] (AsyncWebServerRequest *request) { - String message; - if (request->hasParam(PARAM_MESSAGE)) { - message = request->getParam(PARAM_MESSAGE)->value(); - } else { - message = "No message sent"; - } - request->send(200, "text/plain", "Hello, GET: " + message); - }); + // Send a GET request to /get?message= + server.on("/get", HTTP_GET, [](AsyncWebServerRequest* request) { + String message; + if (request->hasParam(PARAM_MESSAGE)) { + message = request->getParam(PARAM_MESSAGE)->value(); + } else { + message = "No message sent"; + } + request->send(200, "text/plain", "Hello, GET: " + message); + }); - // Send a POST request to /post with a form field message set to - server.on("/post", HTTP_POST, [](AsyncWebServerRequest *request){ - String message; - if (request->hasParam(PARAM_MESSAGE, true)) { - message = request->getParam(PARAM_MESSAGE, true)->value(); - } else { - message = "No message sent"; - } - request->send(200, "text/plain", "Hello, POST: " + message); - }); + // Send a POST request to /post with a form field message set to + server.on("/post", HTTP_POST, [](AsyncWebServerRequest* request) { + String message; + if (request->hasParam(PARAM_MESSAGE, true)) { + message = request->getParam(PARAM_MESSAGE, true)->value(); + } else { + message = "No message sent"; + } + request->send(200, "text/plain", "Hello, POST: " + message); + }); - server.onNotFound(notFound); + server.onNotFound(notFound); - server.begin(); + server.begin(); } void loop() { diff --git a/examples/StreamFiles/StreamFiles.ino b/examples/StreamFiles/StreamFiles.ino index d5621f574..424768ce3 100644 --- a/examples/StreamFiles/StreamFiles.ino +++ b/examples/StreamFiles/StreamFiles.ino @@ -1,11 +1,11 @@ #include #include #ifdef ESP32 -#include -#include + #include + #include #elif defined(ESP8266) -#include -#include + #include + #include #endif #include "StreamConcat.h" #include "StreamString.h" From e3eb2b1044dcff2e50dea1e1ed271802e6b90265 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Thu, 27 Jun 2024 21:47:58 +0200 Subject: [PATCH 260/551] Fix getParam delegate `const AsyncWebParameter* getParam(const String& name, bool post = false, bool file = false) const { return getParam(name.c_str(), post, file); };` --- src/ESPAsyncWebServer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index 20360c669..cfb829a6a 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -335,7 +335,7 @@ class AsyncWebServerRequest { */ const AsyncWebParameter* getParam(const char* name, bool post = false, bool file = false) const; - const AsyncWebParameter* getParam(const String& name, bool post = false, bool file = false) const { return getParam(name.c_str()); }; + const AsyncWebParameter* getParam(const String& name, bool post = false, bool file = false) const { return getParam(name.c_str(), post, file); }; #ifdef ESP8266 const AsyncWebParameter* getParam(const __FlashStringHelper* data, bool post, bool file) const; #endif From 1af677d88bb6507f5bf798a373b6f83a81fbde0a Mon Sep 17 00:00:00 2001 From: Ayush Sharma Date: Fri, 14 Jun 2024 01:34:29 +0530 Subject: [PATCH 261/551] feat: add rp2040 support --- .github/workflows/ci.yml | 9 ++++++- README.md | 3 ++- docs/_config.yml | 2 +- docs/index.md | 3 ++- examples/CaptivePortal/CaptivePortal.ino | 3 +++ examples/Filters/Filters.ino | 3 +++ examples/SimpleServer/SimpleServer.ino | 3 +++ examples/StreamFiles/StreamConcat.h | 4 +++ examples/StreamFiles/StreamFiles.ino | 11 +++++++++ examples/StreamFiles/StreamString.h | 4 +++ library.json | 11 +++++++-- library.properties | 4 +-- platformio.ini | 12 +++++++++ src/AsyncEventSource.cpp | 4 +-- src/AsyncEventSource.h | 7 +++++- src/AsyncWebSocket.cpp | 10 ++++---- src/AsyncWebSocket.h | 8 +++++- src/ESPAsyncWebServer.h | 31 +++++++++++++++--------- src/WebAuthentication.cpp | 4 +-- src/WebHandlers.cpp | 8 ++++++ 20 files changed, 114 insertions(+), 30 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c23d2ea8d..9b477bd94 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -28,7 +28,10 @@ jobs: - core: esp8266:esp8266 board: esp8266:esp8266:huzzah index_url: https://arduino.esp8266.com/stable/package_esp8266com_index.json - + - name: package_rp2040_index.json + core: rp2040:rp2040 + board: rp2040:rp2040:rpipicow + index_url: https://github.com/earlephilhower/arduino-pico/releases/download/global/package_rp2040_index.json steps: - name: Checkout uses: actions/checkout@v4 @@ -55,6 +58,10 @@ jobs: if: ${{ matrix.core == 'esp8266:esp8266' }} run: ARDUINO_LIBRARY_ENABLE_UNSAFE_INSTALL=true arduino-cli lib install --git-url https://github.com/mathieucarbou/esphome-ESPAsyncTCP#v2.0.0 + - name: Install AsyncTCP (RP2040) + if: ${{ matrix.core == 'rp2040:rp2040' }} + run: ARDUINO_LIBRARY_ENABLE_UNSAFE_INSTALL=true arduino-cli lib install --git-url https://github.com/khoih-prog/AsyncTCP_RP2040W#v1.2.0 + - name: Build CaptivePortal run: arduino-cli compile --library . --warnings none -b ${{ matrix.board }} "examples/CaptivePortal/CaptivePortal.ino" diff --git a/README.md b/README.md index dc87c0742..888ae66ce 100644 --- a/README.md +++ b/README.md @@ -4,13 +4,14 @@ [![Continuous Integration](https://github.com/mathieucarbou/ESPAsyncWebServer/actions/workflows/ci.yml/badge.svg)](https://github.com/mathieucarbou/ESPAsyncWebServer/actions/workflows/ci.yml) [![PlatformIO Registry](https://badges.registry.platformio.org/packages/mathieucarbou/library/ESP%20Async%20WebServer.svg)](https://registry.platformio.org/libraries/mathieucarbou/ESP%20Async%20WebServer) -Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 +Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 and RP2040 Supports: WebSocket, SSE, Authentication, Arduino Json 7, File Upload, Static File serving, URL Rewrite, URL Redirect, etc. This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubox-node-org/ESPAsyncWebServer) and includes all the concurrency fixes. ## Changes in this fork +- [@ayushsharma82](https://github.com/ayushsharma82) and [@mathieucarbou](https://github.com/mathieucarbou): Add RP2040 support ([#31](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/31)) - [@mathieucarbou](https://github.com/mathieucarbou): `SSE_MAX_QUEUED_MESSAGES` to control the maximum number of messages that can be queued for a SSE client - [@mathieucarbou](https://github.com/mathieucarbou): `write()` function public in `AsyncEventSource.h` - [@mathieucarbou](https://github.com/mathieucarbou): `WS_MAX_QUEUED_MESSAGES`: control the maximum number of messages that can be queued for a Websocket client diff --git a/docs/_config.yml b/docs/_config.yml index 95d65c287..e6d54d285 100644 --- a/docs/_config.yml +++ b/docs/_config.yml @@ -1,7 +1,7 @@ # bundle exec jekyll serve --host=0.0.0.0 title: ESP Async WebServer -description: "Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266" +description: "Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 and RP2040" remote_theme: pages-themes/cayman@v0.2.0 plugins: - jekyll-remote-theme diff --git a/docs/index.md b/docs/index.md index dc87c0742..888ae66ce 100644 --- a/docs/index.md +++ b/docs/index.md @@ -4,13 +4,14 @@ [![Continuous Integration](https://github.com/mathieucarbou/ESPAsyncWebServer/actions/workflows/ci.yml/badge.svg)](https://github.com/mathieucarbou/ESPAsyncWebServer/actions/workflows/ci.yml) [![PlatformIO Registry](https://badges.registry.platformio.org/packages/mathieucarbou/library/ESP%20Async%20WebServer.svg)](https://registry.platformio.org/libraries/mathieucarbou/ESP%20Async%20WebServer) -Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 +Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 and RP2040 Supports: WebSocket, SSE, Authentication, Arduino Json 7, File Upload, Static File serving, URL Rewrite, URL Redirect, etc. This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubox-node-org/ESPAsyncWebServer) and includes all the concurrency fixes. ## Changes in this fork +- [@ayushsharma82](https://github.com/ayushsharma82) and [@mathieucarbou](https://github.com/mathieucarbou): Add RP2040 support ([#31](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/31)) - [@mathieucarbou](https://github.com/mathieucarbou): `SSE_MAX_QUEUED_MESSAGES` to control the maximum number of messages that can be queued for a SSE client - [@mathieucarbou](https://github.com/mathieucarbou): `write()` function public in `AsyncEventSource.h` - [@mathieucarbou](https://github.com/mathieucarbou): `WS_MAX_QUEUED_MESSAGES`: control the maximum number of messages that can be queued for a Websocket client diff --git a/examples/CaptivePortal/CaptivePortal.ino b/examples/CaptivePortal/CaptivePortal.ino index cb0b193aa..2d0de89c2 100644 --- a/examples/CaptivePortal/CaptivePortal.ino +++ b/examples/CaptivePortal/CaptivePortal.ino @@ -5,6 +5,9 @@ #elif defined(ESP8266) #include #include +#elif defined(TARGET_RP2040) + #include + #include #endif #include "ESPAsyncWebServer.h" diff --git a/examples/Filters/Filters.ino b/examples/Filters/Filters.ino index d26c59fb7..f031a1f78 100644 --- a/examples/Filters/Filters.ino +++ b/examples/Filters/Filters.ino @@ -7,6 +7,9 @@ #elif defined(ESP8266) #include #include +#elif defined(TARGET_RP2040) + #include + #include #endif #include "ESPAsyncWebServer.h" diff --git a/examples/SimpleServer/SimpleServer.ino b/examples/SimpleServer/SimpleServer.ino index ed07401ed..247267435 100644 --- a/examples/SimpleServer/SimpleServer.ino +++ b/examples/SimpleServer/SimpleServer.ino @@ -12,6 +12,9 @@ #elif defined(ESP8266) #include #include +#elif defined(TARGET_RP2040) + #include + #include #endif #include diff --git a/examples/StreamFiles/StreamConcat.h b/examples/StreamFiles/StreamConcat.h index 1a53f2cd9..c1e192769 100644 --- a/examples/StreamFiles/StreamConcat.h +++ b/examples/StreamFiles/StreamConcat.h @@ -17,7 +17,11 @@ class StreamConcat : public Stream { return c != -1 ? c : _s2->read(); } +#if defined(TARGET_RP2040) + size_t readBytes(char* buffer, size_t length) { +#else size_t readBytes(char* buffer, size_t length) override { +#endif size_t count = _s1->readBytes(buffer, length); return count > 0 ? count : _s2->readBytes(buffer, length); } diff --git a/examples/StreamFiles/StreamFiles.ino b/examples/StreamFiles/StreamFiles.ino index 424768ce3..2a2c1b659 100644 --- a/examples/StreamFiles/StreamFiles.ino +++ b/examples/StreamFiles/StreamFiles.ino @@ -6,6 +6,9 @@ #elif defined(ESP8266) #include #include +#elif defined(TARGET_RP2040) + #include + #include #endif #include "StreamConcat.h" #include "StreamString.h" @@ -42,7 +45,11 @@ void setup() { StreamConcat stream1(&header, &body); StreamString content; +#if defined(TARGET_RP2040) + content.printf("FreeHeap: %d", rp2040.getFreeHeap()); +#else content.printf("FreeHeap: %" PRIu32, ESP.getFreeHeap()); +#endif StreamConcat stream2 = StreamConcat(&stream1, &content); File footer = LittleFS.open("/footer.html", "r"); @@ -67,7 +74,11 @@ void loop() { // dnsServer.processNextRequest(); if (millis() - last > 2000) { +#if defined(TARGET_RP2040) + Serial.printf("FreeHeap: %d", rp2040.getFreeHeap()); +#else Serial.printf("FreeHeap: %" PRIu32, ESP.getFreeHeap()); +#endif last = millis(); } } \ No newline at end of file diff --git a/examples/StreamFiles/StreamString.h b/examples/StreamFiles/StreamString.h index f392b4525..a6e0655e6 100644 --- a/examples/StreamFiles/StreamString.h +++ b/examples/StreamFiles/StreamString.h @@ -18,7 +18,11 @@ class StreamString : public Stream { return c; } +#if defined(TARGET_RP2040) + size_t readBytes(char* buffer, size_t length) { +#else size_t readBytes(char* buffer, size_t length) override { +#endif if (length > _buffer.length()) length = _buffer.length(); // Don't use _str.ToCharArray() because it inserts a terminator diff --git a/library.json b/library.json index acd320c53..c6442c986 100644 --- a/library.json +++ b/library.json @@ -1,7 +1,7 @@ { "name": "ESP Async WebServer", "version": "2.10.8", - "description": "Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266. Supports: WebSocket, SSE, Authentication, Arduino Json 7, File Upload, Static File serving, URL Rewrite, URL Redirect, etc.", + "description": "Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 and RP2040. Supports: WebSocket, SSE, Authentication, Arduino Json 7, File Upload, Static File serving, URL Rewrite, URL Redirect, etc.", "keywords": "http,async,websocket,webserver", "homepage": "https://github.com/mathieucarbou/ESPAsyncWebServer", "repository": { @@ -21,7 +21,8 @@ "frameworks": "arduino", "platforms": [ "espressif32", - "espressif8266" + "espressif8266", + "raspberrypi" ], "dependencies": [ { @@ -39,6 +40,12 @@ { "name": "Hash", "platforms": "espressif8266" + }, + { + "owner": "khoih-prog", + "name": "AsyncTCP_RP2040W", + "version": "^1.2.0", + "platforms": "raspberrypi" } ], "export": { diff --git a/library.properties b/library.properties index 3858af9c5..a147a7cb0 100644 --- a/library.properties +++ b/library.properties @@ -2,9 +2,9 @@ name=ESP Async WebServer version=2.10.8 author=Me-No-Dev maintainer=Mathieu Carbou -sentence=Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 +sentence=Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 and RP2040 paragraph=Supports: WebSocket, SSE, Authentication, Arduino Json 7, File Upload, Static File serving, URL Rewrite, URL Redirect, etc category=Other url=https://github.com/mathieucarbou/ESPAsyncWebServer -architectures=esp8266,esp32 +architectures=* license=LGPL-3.0 diff --git a/platformio.ini b/platformio.ini index 795b32db3..9535be427 100644 --- a/platformio.ini +++ b/platformio.ini @@ -46,3 +46,15 @@ board = huzzah lib_deps = bblanchon/ArduinoJson @ 7.0.4 esphome/ESPAsyncTCP-esphome @ 2.0.0 + +; PlatformIO support for Raspberry Pi Pico is not official +; https://github.com/platformio/platform-raspberrypi/pull/36 +; https://github.com/earlephilhower/arduino-pico/blob/master/docs/platformio.rst +; board settings: https://github.com/earlephilhower/arduino-pico/blob/master/tools/json/rpipico.json +[env:rpipicow] +upload_protocol = picotool +platform = https://github.com/maxgerhardt/platform-raspberrypi.git +board = rpipicow +lib_deps = + bblanchon/ArduinoJson @ 7.0.4 + khoih-prog/AsyncTCP_RP2040W @ 1.2.0 diff --git a/src/AsyncEventSource.cpp b/src/AsyncEventSource.cpp index 87d829383..4cafdae17 100644 --- a/src/AsyncEventSource.cpp +++ b/src/AsyncEventSource.cpp @@ -18,7 +18,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "Arduino.h" -#ifndef ESP8266 +#if defined(ESP32) #include #endif #include "AsyncEventSource.h" @@ -190,7 +190,7 @@ void AsyncEventSourceClient::_queueMessage(const char* message, size_t len) { if (_messageQueue.size() >= SSE_MAX_QUEUED_MESSAGES) { #ifdef ESP8266 ets_printf(String(F("ERROR: Too many messages queued\n")).c_str()); -#else +#elif defined(ESP32) log_e("Too many messages queued: deleting message"); #endif return; diff --git a/src/AsyncEventSource.h b/src/AsyncEventSource.h index 93a417664..0289ebf8f 100644 --- a/src/AsyncEventSource.h +++ b/src/AsyncEventSource.h @@ -28,11 +28,16 @@ #ifndef SSE_MAX_QUEUED_MESSAGES #define SSE_MAX_QUEUED_MESSAGES 32 #endif -#else // esp8266 +#elif defined(ESP8266) #include #ifndef SSE_MAX_QUEUED_MESSAGES #define SSE_MAX_QUEUED_MESSAGES 8 #endif +#elif defined(TARGET_RP2040) + #include + #ifndef SSE_MAX_QUEUED_MESSAGES + #define SSE_MAX_QUEUED_MESSAGES 32 + #endif #endif #include diff --git a/src/AsyncWebSocket.cpp b/src/AsyncWebSocket.cpp index 8f1e6a81f..e978afccd 100644 --- a/src/AsyncWebSocket.cpp +++ b/src/AsyncWebSocket.cpp @@ -25,14 +25,14 @@ #include -#ifndef ESP8266 +#if defined(ESP32) #if ESP_IDF_VERSION_MAJOR < 5 #include "./port/SHA1Builder.h" #else #include #endif #include -#else +#elif defined(TARGET_RP2040) || defined(ESP8266) #include #endif @@ -417,7 +417,7 @@ void AsyncWebSocketClient::_queueMessage(AsyncWebSocketSharedBuffer buffer, uint if (closeWhenFull) { #ifdef ESP8266 ets_printf("AsyncWebSocketClient::_queueMessage: Too many messages queued: closing connection\n"); -#else +#elif defined(ESP32) log_e("Too many messages queued: closing connection"); #endif _status = WS_DISCONNECTED; @@ -426,7 +426,7 @@ void AsyncWebSocketClient::_queueMessage(AsyncWebSocketSharedBuffer buffer, uint } else { #ifdef ESP8266 ets_printf("AsyncWebSocketClient::_queueMessage: Too many messages queued: discarding new message\n"); -#else +#elif defined(ESP32) log_e("Too many messages queued: discarding new message"); #endif } @@ -1155,7 +1155,7 @@ AsyncWebSocketResponse::AsyncWebSocketResponse(const String& key, AsyncWebSocket uint8_t hash[20]; char buffer[33]; -#ifdef ESP8266 +#if defined(ESP8266) || defined(TARGET_RP2040) sha1(key + WS_STR_UUID, hash); #else String k; diff --git a/src/AsyncWebSocket.h b/src/AsyncWebSocket.h index 10e9537fd..77bf7ee7e 100644 --- a/src/AsyncWebSocket.h +++ b/src/AsyncWebSocket.h @@ -28,12 +28,18 @@ #ifndef WS_MAX_QUEUED_MESSAGES #define WS_MAX_QUEUED_MESSAGES 32 #endif -#else +#elif defined(ESP8266) #include #ifndef WS_MAX_QUEUED_MESSAGES #define WS_MAX_QUEUED_MESSAGES 8 #endif +#elif defined(TARGET_RP2040) + #include + #ifndef WS_MAX_QUEUED_MESSAGES + #define WS_MAX_QUEUED_MESSAGES 32 + #endif #endif + #include #include diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index cfb829a6a..eae878c62 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -34,6 +34,11 @@ #elif defined(ESP8266) #include #include +#elif defined(TARGET_RP2040) + #include + #include + #include + #include #else #error Platform not supported #endif @@ -61,17 +66,21 @@ class AsyncStaticWebHandler; class AsyncCallbackWebHandler; class AsyncResponseStream; -#ifndef WEBSERVER_H -typedef enum { - HTTP_GET = 0b00000001, - HTTP_POST = 0b00000010, - HTTP_DELETE = 0b00000100, - HTTP_PUT = 0b00001000, - HTTP_PATCH = 0b00010000, - HTTP_HEAD = 0b00100000, - HTTP_OPTIONS = 0b01000000, - HTTP_ANY = 0b01111111, -} WebRequestMethod; +#if defined (TARGET_RP2040) + typedef enum http_method WebRequestMethod; +#else + #ifndef WEBSERVER_H + typedef enum { + HTTP_GET = 0b00000001, + HTTP_POST = 0b00000010, + HTTP_DELETE = 0b00000100, + HTTP_PUT = 0b00001000, + HTTP_PATCH = 0b00010000, + HTTP_HEAD = 0b00100000, + HTTP_OPTIONS = 0b01000000, + HTTP_ANY = 0b01111111, + } WebRequestMethod; + #endif #endif #ifndef HAVE_FS_FILE_OPEN_MODE diff --git a/src/WebAuthentication.cpp b/src/WebAuthentication.cpp index 57616163d..abd74b810 100644 --- a/src/WebAuthentication.cpp +++ b/src/WebAuthentication.cpp @@ -20,7 +20,7 @@ */ #include "WebAuthentication.h" #include -#ifdef ESP32 +#if defined(ESP32) || defined(TARGET_RP2040) #include #else #include "md5.h" @@ -64,7 +64,7 @@ bool checkBasicAuthentication(const char* hash, const char* username, const char } static bool getMD5(uint8_t* data, uint16_t len, char* output) { // 33 bytes or more -#ifdef ESP32 +#if defined(ESP32) || defined(TARGET_RP2040) MD5Builder md5; md5.begin(); md5.add(data, len); diff --git a/src/WebHandlers.cpp b/src/WebHandlers.cpp index 40232dfd1..d740d8627 100644 --- a/src/WebHandlers.cpp +++ b/src/WebHandlers.cpp @@ -210,7 +210,15 @@ void AsyncStaticWebHandler::handleRequest(AsyncWebServerRequest* request) { String etag; if (lw) { setLastModified(gmtime(&lw)); +#if defined(TARGET_RP2040) + // time_t == long long int + const size_t len = 1 + 8 * sizeof(time_t); + char buf[len]; + char* ret = lltoa(lw, buf, len, 10); + etag = ret ? String(ret) : String(request->_tempFile.size()); +#else etag = String(lw); +#endif } else { etag = String(request->_tempFile.size()); } From ff7a5e074f9c2f89a5a32f3221d517d4bf0ddaac Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Thu, 27 Jun 2024 21:58:32 +0200 Subject: [PATCH 262/551] Added doc about dependencies --- README.md | 8 ++++---- docs/index.md | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 888ae66ce..b14d36ceb 100644 --- a/README.md +++ b/README.md @@ -39,11 +39,11 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo - [@vortigont](https://github.com/vortigont): Some websocket code cleanup ([#29](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/29)) - [@vortigont](https://github.com/vortigont): Refactor code - replace DYI structs with STL objects ([#39](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/39)) -**In progress** +## Dependencies: -In `dev` branch (needs more testing) - -- [@ayushsharma82](https://github.com/ayushsharma82) and [@mathieucarbou](https://github.com/mathieucarbou): Add support for RP2040 ([#31](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/31)) +- **ESP32**: `mathieucarbou/Async TCP @ ^3.1.4` (Arduino IDE: [https://github.com/mathieucarbou/AsyncTCP#v3.1.4](https://github.com/mathieucarbou/AsyncTCP/releases/tag/v3.1.4)) +- **ESP8266**: `esphome/ESPAsyncTCP-esphome @ 2.0.0` (Arduino IDE: [https://github.com/mathieucarbou/esphome-ESPAsyncTCP#v2.0.0](https://github.com/mathieucarbou/esphome-ESPAsyncTCP/releases/tag/v2.0.0)) +- **RP2040**: `khoih-prog/AsyncTCP_RP2040W @ 1.2.0` (Arduino IDE: [https://github.com/khoih-prog/AsyncTCP_RP2040W#v1.2.0](https://github.com/khoih-prog/AsyncTCP_RP2040W/releases/tag/v1.2.0)) ## Documentation diff --git a/docs/index.md b/docs/index.md index 888ae66ce..b14d36ceb 100644 --- a/docs/index.md +++ b/docs/index.md @@ -39,11 +39,11 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo - [@vortigont](https://github.com/vortigont): Some websocket code cleanup ([#29](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/29)) - [@vortigont](https://github.com/vortigont): Refactor code - replace DYI structs with STL objects ([#39](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/39)) -**In progress** +## Dependencies: -In `dev` branch (needs more testing) - -- [@ayushsharma82](https://github.com/ayushsharma82) and [@mathieucarbou](https://github.com/mathieucarbou): Add support for RP2040 ([#31](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/31)) +- **ESP32**: `mathieucarbou/Async TCP @ ^3.1.4` (Arduino IDE: [https://github.com/mathieucarbou/AsyncTCP#v3.1.4](https://github.com/mathieucarbou/AsyncTCP/releases/tag/v3.1.4)) +- **ESP8266**: `esphome/ESPAsyncTCP-esphome @ 2.0.0` (Arduino IDE: [https://github.com/mathieucarbou/esphome-ESPAsyncTCP#v2.0.0](https://github.com/mathieucarbou/esphome-ESPAsyncTCP/releases/tag/v2.0.0)) +- **RP2040**: `khoih-prog/AsyncTCP_RP2040W @ 1.2.0` (Arduino IDE: [https://github.com/khoih-prog/AsyncTCP_RP2040W#v1.2.0](https://github.com/khoih-prog/AsyncTCP_RP2040W/releases/tag/v1.2.0)) ## Documentation From 29e5c68e7791b9a1c231faa0501b0f2ba2575d57 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Thu, 27 Jun 2024 22:00:07 +0200 Subject: [PATCH 263/551] v3.0.0 --- library.json | 2 +- library.properties | 2 +- src/ESPAsyncWebServer.h | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/library.json b/library.json index c6442c986..4148773db 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "ESP Async WebServer", - "version": "2.10.8", + "version": "3.0.0", "description": "Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 and RP2040. Supports: WebSocket, SSE, Authentication, Arduino Json 7, File Upload, Static File serving, URL Rewrite, URL Redirect, etc.", "keywords": "http,async,websocket,webserver", "homepage": "https://github.com/mathieucarbou/ESPAsyncWebServer", diff --git a/library.properties b/library.properties index a147a7cb0..72007dff3 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=ESP Async WebServer -version=2.10.8 +version=3.0.0 author=Me-No-Dev maintainer=Mathieu Carbou sentence=Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 and RP2040 diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index eae878c62..d579398c8 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -43,10 +43,10 @@ #error Platform not supported #endif -#define ASYNCWEBSERVER_VERSION "2.10.8" -#define ASYNCWEBSERVER_VERSION_MAJOR 2 -#define ASYNCWEBSERVER_VERSION_MINOR 10 -#define ASYNCWEBSERVER_VERSION_REVISION 8 +#define ASYNCWEBSERVER_VERSION "3.0.0" +#define ASYNCWEBSERVER_VERSION_MAJOR 3 +#define ASYNCWEBSERVER_VERSION_MINOR 0 +#define ASYNCWEBSERVER_VERSION_REVISION 0 #define ASYNCWEBSERVER_FORK_mathieucarbou #ifdef ASYNCWEBSERVER_REGEX From 7e0ae2f1f59e504115e947c637eca13514807548 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Thu, 27 Jun 2024 22:01:23 +0200 Subject: [PATCH 264/551] v3.0.1 --- library.json | 2 +- library.properties | 2 +- src/ESPAsyncWebServer.h | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/library.json b/library.json index 4148773db..7c4d849a6 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "ESP Async WebServer", - "version": "3.0.0", + "version": "3.0.1", "description": "Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 and RP2040. Supports: WebSocket, SSE, Authentication, Arduino Json 7, File Upload, Static File serving, URL Rewrite, URL Redirect, etc.", "keywords": "http,async,websocket,webserver", "homepage": "https://github.com/mathieucarbou/ESPAsyncWebServer", diff --git a/library.properties b/library.properties index 72007dff3..0518a5e47 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=ESP Async WebServer -version=3.0.0 +version=3.0.1 author=Me-No-Dev maintainer=Mathieu Carbou sentence=Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 and RP2040 diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index d579398c8..9b1fece23 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -43,10 +43,10 @@ #error Platform not supported #endif -#define ASYNCWEBSERVER_VERSION "3.0.0" +#define ASYNCWEBSERVER_VERSION "3.0.1" #define ASYNCWEBSERVER_VERSION_MAJOR 3 #define ASYNCWEBSERVER_VERSION_MINOR 0 -#define ASYNCWEBSERVER_VERSION_REVISION 0 +#define ASYNCWEBSERVER_VERSION_REVISION 1 #define ASYNCWEBSERVER_FORK_mathieucarbou #ifdef ASYNCWEBSERVER_REGEX From dc9e5bcf473cf3d570675b67f7ffdcf88a4c8e99 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Thu, 27 Jun 2024 22:26:07 +0200 Subject: [PATCH 265/551] Add ESP32 equivalent of beginResponse_P for embedded binary data. `AsyncWebServerResponse* beginResponse(int code, const String& contentType, const uint8_t* content, size_t len, AwsTemplateProcessor callback = nullptr);` Ref: https://docs.platformio.org/en/latest/platforms/espressif32.html#embedding-binary-data --- src/ESPAsyncWebServer.h | 1 + src/WebRequest.cpp | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index 9b1fece23..f2214e6a8 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -303,6 +303,7 @@ class AsyncWebServerRequest { #endif AsyncWebServerResponse* beginResponse(int code, const String& contentType = String(), const String& content = String()); + AsyncWebServerResponse* beginResponse(int code, const String& contentType, const uint8_t* content, size_t len, AwsTemplateProcessor callback = nullptr); AsyncWebServerResponse* beginResponse(FS& fs, const String& path, const String& contentType = String(), bool download = false, AwsTemplateProcessor callback = nullptr); AsyncWebServerResponse* beginResponse(File content, const String& path, const String& contentType = String(), bool download = false, AwsTemplateProcessor callback = nullptr); AsyncWebServerResponse* beginResponse(Stream& stream, const String& contentType, size_t len, AwsTemplateProcessor callback = nullptr); diff --git a/src/WebRequest.cpp b/src/WebRequest.cpp index c31b9ef7d..cc9c3eee9 100644 --- a/src/WebRequest.cpp +++ b/src/WebRequest.cpp @@ -702,6 +702,10 @@ AsyncWebServerResponse* AsyncWebServerRequest::beginResponse(int code, const Str return new AsyncBasicResponse(code, contentType, content); } +AsyncWebServerResponse* AsyncWebServerRequest::beginResponse(int code, const String& contentType, const uint8_t* content, size_t len, AwsTemplateProcessor callback) { + return new AsyncProgmemResponse(code, contentType, content, len, callback); +} + AsyncWebServerResponse* AsyncWebServerRequest::beginResponse(FS& fs, const String& path, const String& contentType, bool download, AwsTemplateProcessor callback) { if (fs.exists(path) || (!download && fs.exists(path + F(".gz")))) return new AsyncFileResponse(fs, path, contentType, download, callback); From 231dd6eb993eec8a63c98ca295086cfeb0602cc3 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Thu, 27 Jun 2024 22:31:02 +0200 Subject: [PATCH 266/551] v3.0.2 --- library.json | 2 +- library.properties | 2 +- src/ESPAsyncWebServer.h | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/library.json b/library.json index 7c4d849a6..92fae22c9 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "ESP Async WebServer", - "version": "3.0.1", + "version": "3.0.2", "description": "Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 and RP2040. Supports: WebSocket, SSE, Authentication, Arduino Json 7, File Upload, Static File serving, URL Rewrite, URL Redirect, etc.", "keywords": "http,async,websocket,webserver", "homepage": "https://github.com/mathieucarbou/ESPAsyncWebServer", diff --git a/library.properties b/library.properties index 0518a5e47..03715deac 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=ESP Async WebServer -version=3.0.1 +version=3.0.2 author=Me-No-Dev maintainer=Mathieu Carbou sentence=Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 and RP2040 diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index f2214e6a8..93c544d93 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -43,10 +43,10 @@ #error Platform not supported #endif -#define ASYNCWEBSERVER_VERSION "3.0.1" +#define ASYNCWEBSERVER_VERSION "3.0.2" #define ASYNCWEBSERVER_VERSION_MAJOR 3 #define ASYNCWEBSERVER_VERSION_MINOR 0 -#define ASYNCWEBSERVER_VERSION_REVISION 1 +#define ASYNCWEBSERVER_VERSION_REVISION 2 #define ASYNCWEBSERVER_FORK_mathieucarbou #ifdef ASYNCWEBSERVER_REGEX From 005c3f3b712e318887aea478d55024d98f5b2ae2 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Fri, 28 Jun 2024 00:47:14 +0200 Subject: [PATCH 267/551] Add "libCompatMode": "strict" to help pio dependency resolution --- library.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/library.json b/library.json index 92fae22c9..4df96655b 100644 --- a/library.json +++ b/library.json @@ -57,5 +57,8 @@ "LICENSE", "README.md" ] + }, + "build": { + "libCompatMode": "strict" } } \ No newline at end of file From b2a0136817d22eed221715d47cffe82a83c093e9 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Fri, 28 Jun 2024 08:56:16 +0200 Subject: [PATCH 268/551] bblanchon/ArduinoJson @ 7.1.0 --- platformio.ini | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/platformio.ini b/platformio.ini index 9535be427..0c85cfe6b 100644 --- a/platformio.ini +++ b/platformio.ini @@ -20,14 +20,14 @@ src_dir = examples/StreamFiles platform = espressif32 board = esp32dev lib_deps = - bblanchon/ArduinoJson @ 7.0.4 + bblanchon/ArduinoJson @ 7.1.0 mathieucarbou/Async TCP @ ^3.1.4 [env:arduino-2] platform = espressif32@6.7.0 board = esp32dev lib_deps = - bblanchon/ArduinoJson @ 7.0.4 + bblanchon/ArduinoJson @ 7.1.0 mathieucarbou/Async TCP @ ^3.1.4 [env:arduino-3] @@ -37,14 +37,14 @@ platform_packages= platformio/framework-arduinoespressif32-libs @ https://github.com/espressif/arduino-esp32/releases/download/3.0.2/esp32-arduino-libs-3.0.2.zip board = esp32dev lib_deps = - bblanchon/ArduinoJson @ 7.0.4 + bblanchon/ArduinoJson @ 7.1.0 mathieucarbou/Async TCP @ ^3.1.4 [env:esp8266] platform = espressif8266 board = huzzah lib_deps = - bblanchon/ArduinoJson @ 7.0.4 + bblanchon/ArduinoJson @ 7.1.0 esphome/ESPAsyncTCP-esphome @ 2.0.0 ; PlatformIO support for Raspberry Pi Pico is not official @@ -56,5 +56,5 @@ upload_protocol = picotool platform = https://github.com/maxgerhardt/platform-raspberrypi.git board = rpipicow lib_deps = - bblanchon/ArduinoJson @ 7.0.4 + bblanchon/ArduinoJson @ 7.1.0 khoih-prog/AsyncTCP_RP2040W @ 1.2.0 From d4ab0ff85d7f3018173e600e43c2984d7a1a3809 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Fri, 28 Jun 2024 14:12:44 +0200 Subject: [PATCH 269/551] Adding back beginResponse_P() and send_P() but with deprecation notices --- src/ESPAsyncWebServer.h | 30 ++++++++++++++++++++++-------- src/WebRequest.cpp | 32 ++++++++++++-------------------- 2 files changed, 34 insertions(+), 28 deletions(-) diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index 93c544d93..c92c8fdfc 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -292,28 +292,42 @@ class AsyncWebServerRequest { void send(AsyncWebServerResponse* response); void send(int code, const String& contentType = String(), const String& content = String()); + void send(int code, const String& contentType, const uint8_t* content, size_t len, AwsTemplateProcessor callback = nullptr); + void send(int code, const String& contentType, PGM_P content, AwsTemplateProcessor callback = nullptr); void send(FS& fs, const String& path, const String& contentType = String(), bool download = false, AwsTemplateProcessor callback = nullptr); void send(File content, const String& path, const String& contentType = String(), bool download = false, AwsTemplateProcessor callback = nullptr); void send(Stream& stream, const String& contentType, size_t len, AwsTemplateProcessor callback = nullptr); void send(const String& contentType, size_t len, AwsResponseFiller callback, AwsTemplateProcessor templateCallback = nullptr); void sendChunked(const String& contentType, AwsResponseFiller callback, AwsTemplateProcessor templateCallback = nullptr); -#ifdef ESP8266 - void send_P(int code, const String& contentType, const uint8_t* content, size_t len, AwsTemplateProcessor callback = nullptr); - void send_P(int code, const String& contentType, PGM_P content, AwsTemplateProcessor callback = nullptr); -#endif + + [[deprecated("Replaced by send(...)")]] + void send_P(int code, const String& contentType, const uint8_t* content, size_t len, AwsTemplateProcessor callback = nullptr) { + send(code, contentType, content, len, callback); + } + [[deprecated("Replaced by send(...)")]] + void send_P(int code, const String& contentType, PGM_P content, AwsTemplateProcessor callback = nullptr) { + send(code, contentType, content, callback); + } AsyncWebServerResponse* beginResponse(int code, const String& contentType = String(), const String& content = String()); AsyncWebServerResponse* beginResponse(int code, const String& contentType, const uint8_t* content, size_t len, AwsTemplateProcessor callback = nullptr); + AsyncWebServerResponse* beginResponse(int code, const String& contentType, PGM_P content, AwsTemplateProcessor callback = nullptr); AsyncWebServerResponse* beginResponse(FS& fs, const String& path, const String& contentType = String(), bool download = false, AwsTemplateProcessor callback = nullptr); AsyncWebServerResponse* beginResponse(File content, const String& path, const String& contentType = String(), bool download = false, AwsTemplateProcessor callback = nullptr); AsyncWebServerResponse* beginResponse(Stream& stream, const String& contentType, size_t len, AwsTemplateProcessor callback = nullptr); AsyncWebServerResponse* beginResponse(const String& contentType, size_t len, AwsResponseFiller callback, AwsTemplateProcessor templateCallback = nullptr); AsyncWebServerResponse* beginChunkedResponse(const String& contentType, AwsResponseFiller callback, AwsTemplateProcessor templateCallback = nullptr); AsyncResponseStream* beginResponseStream(const String& contentType, size_t bufferSize = 1460); -#ifdef ESP8266 - AsyncWebServerResponse* beginResponse_P(int code, const String& contentType, const uint8_t* content, size_t len, AwsTemplateProcessor callback = nullptr); - AsyncWebServerResponse* beginResponse_P(int code, const String& contentType, PGM_P content, AwsTemplateProcessor callback = nullptr); -#endif + + + [[deprecated("Replaced by beginResponse(...)")]] + AsyncWebServerResponse* beginResponse_P(int code, const String& contentType, const uint8_t* content, size_t len, AwsTemplateProcessor callback = nullptr) { + return beginResponse(code, contentType, content, len, callback); + } + [[deprecated("Replaced by beginResponse(...)")]] + AsyncWebServerResponse* beginResponse_P(int code, const String& contentType, PGM_P content, AwsTemplateProcessor callback = nullptr) { + return beginResponse(code, contentType, content, callback); + } size_t headers() const; // get header count diff --git a/src/WebRequest.cpp b/src/WebRequest.cpp index cc9c3eee9..2331b133c 100644 --- a/src/WebRequest.cpp +++ b/src/WebRequest.cpp @@ -706,6 +706,10 @@ AsyncWebServerResponse* AsyncWebServerRequest::beginResponse(int code, const Str return new AsyncProgmemResponse(code, contentType, content, len, callback); } +AsyncWebServerResponse* AsyncWebServerRequest::beginResponse(int code, const String& contentType, PGM_P content, AwsTemplateProcessor callback) { + return new AsyncProgmemResponse(code, contentType, (const uint8_t*)content, strlen_P(content), callback); +} + AsyncWebServerResponse* AsyncWebServerRequest::beginResponse(FS& fs, const String& path, const String& contentType, bool download, AwsTemplateProcessor callback) { if (fs.exists(path) || (!download && fs.exists(path + F(".gz")))) return new AsyncFileResponse(fs, path, contentType, download, callback); @@ -736,16 +740,6 @@ AsyncResponseStream* AsyncWebServerRequest::beginResponseStream(const String& co return new AsyncResponseStream(contentType, bufferSize); } -#ifdef ESP8266 -AsyncWebServerResponse* AsyncWebServerRequest::beginResponse_P(int code, const String& contentType, const uint8_t* content, size_t len, AwsTemplateProcessor callback) { - return new AsyncProgmemResponse(code, contentType, content, len, callback); -} - -AsyncWebServerResponse* AsyncWebServerRequest::beginResponse_P(int code, const String& contentType, PGM_P content, AwsTemplateProcessor callback) { - return beginResponse_P(code, contentType, (const uint8_t*)content, strlen_P(content), callback); -} -#endif - void AsyncWebServerRequest::send(AsyncWebServerResponse* response) { _response = response; if (_response == NULL) { @@ -767,6 +761,14 @@ void AsyncWebServerRequest::send(int code, const String& contentType, const Stri send(beginResponse(code, contentType, content)); } +void AsyncWebServerRequest::send(int code, const String& contentType, const uint8_t* content, size_t len, AwsTemplateProcessor callback) { + send(beginResponse(code, contentType, content, len, callback)); +} + +void AsyncWebServerRequest::send(int code, const String& contentType, PGM_P content, AwsTemplateProcessor callback) { + send(beginResponse(code, contentType, content, callback)); +} + void AsyncWebServerRequest::send(FS& fs, const String& path, const String& contentType, bool download, AwsTemplateProcessor callback) { if (fs.exists(path) || (!download && fs.exists(path + F(".gz")))) { send(beginResponse(fs, path, contentType, download, callback)); @@ -793,16 +795,6 @@ void AsyncWebServerRequest::sendChunked(const String& contentType, AwsResponseFi send(beginChunkedResponse(contentType, callback, templateCallback)); } -#ifdef ESP8266 -void AsyncWebServerRequest::send_P(int code, const String& contentType, const uint8_t* content, size_t len, AwsTemplateProcessor callback) { - send(beginResponse_P(code, contentType, content, len, callback)); -} - -void AsyncWebServerRequest::send_P(int code, const String& contentType, PGM_P content, AwsTemplateProcessor callback) { - send(beginResponse_P(code, contentType, content, callback)); -} -#endif - void AsyncWebServerRequest::redirect(const char* url) { AsyncWebServerResponse* response = beginResponse(302); response->addHeader(F("Location"), url); From 372544cf0386043259f738d600e50737144cf936 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Fri, 28 Jun 2024 16:28:58 +0200 Subject: [PATCH 270/551] v3.0.3 --- library.json | 2 +- library.properties | 2 +- src/ESPAsyncWebServer.h | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/library.json b/library.json index 4df96655b..ee2b883cb 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "ESP Async WebServer", - "version": "3.0.2", + "version": "3.0.3", "description": "Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 and RP2040. Supports: WebSocket, SSE, Authentication, Arduino Json 7, File Upload, Static File serving, URL Rewrite, URL Redirect, etc.", "keywords": "http,async,websocket,webserver", "homepage": "https://github.com/mathieucarbou/ESPAsyncWebServer", diff --git a/library.properties b/library.properties index 03715deac..513821676 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=ESP Async WebServer -version=3.0.2 +version=3.0.3 author=Me-No-Dev maintainer=Mathieu Carbou sentence=Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 and RP2040 diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index c92c8fdfc..f0abefad9 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -43,10 +43,10 @@ #error Platform not supported #endif -#define ASYNCWEBSERVER_VERSION "3.0.2" +#define ASYNCWEBSERVER_VERSION "3.0.3" #define ASYNCWEBSERVER_VERSION_MAJOR 3 #define ASYNCWEBSERVER_VERSION_MINOR 0 -#define ASYNCWEBSERVER_VERSION_REVISION 2 +#define ASYNCWEBSERVER_VERSION_REVISION 3 #define ASYNCWEBSERVER_FORK_mathieucarbou #ifdef ASYNCWEBSERVER_REGEX From b62eca011e7a51cbb0beca0b6a003448607e1a4b Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Sun, 30 Jun 2024 10:38:01 +0200 Subject: [PATCH 271/551] Issue templates --- .github/ISSUE_TEMPLATE/bug_report.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index b35e87633..d9cf490b7 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -28,6 +28,8 @@ If yes, please specify which one Please provide the stack trace here taken with `monitor_filters = esp32_exception_decoder`. **Any issue opened with a non readable stack trace will be ignored because not helpful at all.** +As an alternative, you can use [https://maximeborges.github.io/esp-stacktrace-decoder/](https://maximeborges.github.io/esp-stacktrace-decoder/). + **Additional notes** Add any other context about the problem here. From fd6b9ebdf031f5f6e8e7d7748f6b309c56db265b Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Sun, 30 Jun 2024 10:48:33 +0200 Subject: [PATCH 272/551] Removing weirdly placed destructor --- src/AsyncJson.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/AsyncJson.h b/src/AsyncJson.h index ce89301a3..b85a93827 100644 --- a/src/AsyncJson.h +++ b/src/AsyncJson.h @@ -120,7 +120,6 @@ class AsyncJsonResponse : public AsyncAbstractResponse { } #endif - ~AsyncJsonResponse() {} JsonVariant& getRoot() { return _root; } bool _sourceValid() const { return _isValid; } size_t setLength() { From 1b4fa7e81a38cb758ba96698daacd7d549b7c5c4 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Sun, 30 Jun 2024 10:49:17 +0200 Subject: [PATCH 273/551] v3.0.4 --- library.json | 2 +- library.properties | 2 +- src/ESPAsyncWebServer.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/library.json b/library.json index ee2b883cb..84ddfe02c 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "ESP Async WebServer", - "version": "3.0.3", + "version": "3.0.4", "description": "Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 and RP2040. Supports: WebSocket, SSE, Authentication, Arduino Json 7, File Upload, Static File serving, URL Rewrite, URL Redirect, etc.", "keywords": "http,async,websocket,webserver", "homepage": "https://github.com/mathieucarbou/ESPAsyncWebServer", diff --git a/library.properties b/library.properties index 513821676..58774a19e 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=ESP Async WebServer -version=3.0.3 +version=3.0.4 author=Me-No-Dev maintainer=Mathieu Carbou sentence=Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 and RP2040 diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index f0abefad9..c2ad9c51b 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -43,7 +43,7 @@ #error Platform not supported #endif -#define ASYNCWEBSERVER_VERSION "3.0.3" +#define ASYNCWEBSERVER_VERSION "3.0.4" #define ASYNCWEBSERVER_VERSION_MAJOR 3 #define ASYNCWEBSERVER_VERSION_MINOR 0 #define ASYNCWEBSERVER_VERSION_REVISION 3 From abcd2df5e087ef712cb7e5145a60812c473423f4 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Sun, 30 Jun 2024 12:15:25 +0200 Subject: [PATCH 274/551] v3.0.5 --- library.json | 2 +- library.properties | 2 +- src/ESPAsyncWebServer.h | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/library.json b/library.json index 84ddfe02c..15cbb9e6f 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "ESP Async WebServer", - "version": "3.0.4", + "version": "3.0.5", "description": "Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 and RP2040. Supports: WebSocket, SSE, Authentication, Arduino Json 7, File Upload, Static File serving, URL Rewrite, URL Redirect, etc.", "keywords": "http,async,websocket,webserver", "homepage": "https://github.com/mathieucarbou/ESPAsyncWebServer", diff --git a/library.properties b/library.properties index 58774a19e..694f0e428 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=ESP Async WebServer -version=3.0.4 +version=3.0.5 author=Me-No-Dev maintainer=Mathieu Carbou sentence=Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 and RP2040 diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index c2ad9c51b..e7979dbd0 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -43,10 +43,10 @@ #error Platform not supported #endif -#define ASYNCWEBSERVER_VERSION "3.0.4" +#define ASYNCWEBSERVER_VERSION "3.0.5" #define ASYNCWEBSERVER_VERSION_MAJOR 3 #define ASYNCWEBSERVER_VERSION_MINOR 0 -#define ASYNCWEBSERVER_VERSION_REVISION 3 +#define ASYNCWEBSERVER_VERSION_REVISION 5 #define ASYNCWEBSERVER_FORK_mathieucarbou #ifdef ASYNCWEBSERVER_REGEX From 3d2f6add60f44f551f3be3caf53c7e80a56ec082 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Mon, 1 Jul 2024 14:10:37 +0200 Subject: [PATCH 275/551] Add: `bool hasArg(const String& name) const { return hasArg(name.c_str()); };` --- src/ESPAsyncWebServer.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index e7979dbd0..ae759b9a8 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -384,6 +384,7 @@ class AsyncWebServerRequest { const String& arg(size_t i) const; // get request argument value by number const String& argName(size_t i) const; // get request argument name by number bool hasArg(const char* name) const; // check if argument exists + bool hasArg(const String& name) const { return hasArg(name.c_str()); }; #ifdef ESP8266 bool hasArg(const __FlashStringHelper* data) const; // check if F(argument) exists #endif From 6dad5f657c404fa6bc33ddd09ab06d5af98e5d20 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Mon, 1 Jul 2024 14:11:22 +0200 Subject: [PATCH 276/551] v3.0.6 --- library.json | 2 +- library.properties | 2 +- src/ESPAsyncWebServer.h | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/library.json b/library.json index 15cbb9e6f..4e089ba81 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "ESP Async WebServer", - "version": "3.0.5", + "version": "3.0.6", "description": "Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 and RP2040. Supports: WebSocket, SSE, Authentication, Arduino Json 7, File Upload, Static File serving, URL Rewrite, URL Redirect, etc.", "keywords": "http,async,websocket,webserver", "homepage": "https://github.com/mathieucarbou/ESPAsyncWebServer", diff --git a/library.properties b/library.properties index 694f0e428..e0265c367 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=ESP Async WebServer -version=3.0.5 +version=3.0.6 author=Me-No-Dev maintainer=Mathieu Carbou sentence=Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 and RP2040 diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index ae759b9a8..77c5de772 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -43,10 +43,10 @@ #error Platform not supported #endif -#define ASYNCWEBSERVER_VERSION "3.0.5" +#define ASYNCWEBSERVER_VERSION "3.0.6" #define ASYNCWEBSERVER_VERSION_MAJOR 3 #define ASYNCWEBSERVER_VERSION_MINOR 0 -#define ASYNCWEBSERVER_VERSION_REVISION 5 +#define ASYNCWEBSERVER_VERSION_REVISION 6 #define ASYNCWEBSERVER_FORK_mathieucarbou #ifdef ASYNCWEBSERVER_REGEX From 6ed7ed55d65c04cc8e944ca2dbc3200b8121930a Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Tue, 16 Jul 2024 18:17:13 +0200 Subject: [PATCH 277/551] Issue14 --- examples/issues/Issue14/Issue14.ino | 140 ++++++++++++++++++++++++++++ platformio.ini | 8 +- 2 files changed, 147 insertions(+), 1 deletion(-) create mode 100644 examples/issues/Issue14/Issue14.ino diff --git a/examples/issues/Issue14/Issue14.ino b/examples/issues/Issue14/Issue14.ino new file mode 100644 index 000000000..d7af52e57 --- /dev/null +++ b/examples/issues/Issue14/Issue14.ino @@ -0,0 +1,140 @@ +#include +#ifdef ESP32 + #include + #include +#elif defined(ESP8266) + #include + #include +#elif defined(TARGET_RP2040) + #include + #include +#endif +#include "ESPAsyncWebServer.h" + +#include + +const char appWebPage[] PROGMEM = R"rawliteral( + + + + +)rawliteral"; + +void sendState(); + +// const char* ssid = "test_esp32"; +// const char* password = "123456789"; + +//========================================================== + +// Настройки IP адреса +// IPAddress local_IP(192, 168, 111, 111); +// IPAddress gateway(192, 168, 111, 1); +// IPAddress subnet(255, 255, 255, 0); + +// AsyncWebServer server(22222); +AsyncWebServer server(80); + +AsyncEventSource events("/events"); + +unsigned long currentMillis = 0; +unsigned long previousMillis = 0; +const uint16_t interval = 1000; + +const int button1Pin = 4; +bool button1 = false; + +char json[512]; + +void prepareJson() { + snprintf(json, 511, "{\"button1\":%d,\"1234567890abcdefghij1234567890abcdefghij1234567890abcdefghij1234567890abcdefghij1234567890abcdefghij1234567890abcdefghij\":%ld}", button1, random(0, 999999999)); +} + +void handleRoot(AsyncWebServerRequest* request) { + request->send(200, "text/html", appWebPage); +} + +void button1off() { + button1 = false; + digitalWrite(button1Pin, HIGH); +} + +void button1on() { + digitalWrite(button1Pin, LOW); + button1 = true; +} + +void sendState() { + prepareJson(); + events.send(json, "state", millis()); +} + +//========================================================= +void setup() { + + Serial.begin(115200); + delay(100); + randomSeed(micros()); + + pinMode(button1Pin, OUTPUT); + button1off(); + + // WiFi.softAPConfig(local_IP, gateway, subnet); + // WiFi.softAP(ssid, password, 11); + WiFi.softAP("esp-captive"); + + // WiFi.setTxPower(WIFI_POWER_21dBm); + // esp_wifi_set_protocol(WIFI_IF_AP, WIFI_PROTOCOL_11B); + + server.on("/", HTTP_GET, handleRoot); + + server.on("/button1", HTTP_GET, [](AsyncWebServerRequest* request) { + request->send(200, "text/plain", "OK"); + if (button1) { + button1off(); + } else { + button1on(); + } + sendState(); + }); + + events.onConnect([](AsyncEventSourceClient* client) { + prepareJson(); + client->send(json, "state", millis(), 5000); + }); + + server.addHandler(&events); + DefaultHeaders::Instance().addHeader("Access-Control-Allow-Origin", "*"); + + server.begin(); +} + +void loop() { + + currentMillis = millis(); + if (currentMillis - previousMillis >= interval) { + previousMillis = currentMillis; + sendState(); + } +} \ No newline at end of file diff --git a/platformio.ini b/platformio.ini index 0c85cfe6b..ea7acf29b 100644 --- a/platformio.ini +++ b/platformio.ini @@ -4,6 +4,11 @@ build_flags = -Wall -Wextra -D CONFIG_ARDUHAL_LOG_COLORS -D CORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_VERBOSE + -D CONFIG_ASYNC_TCP_MAX_ACK_TIME=3000 + -D CONFIG_ASYNC_TCP_PRIORITY=10 + -D CONFIG_ASYNC_TCP_QUEUE_SIZE=128 + -D CONFIG_ASYNC_TCP_RUNNING_CORE=1 + -D CONFIG_ASYNC_TCP_STACK_SIZE=4096 upload_protocol = esptool monitor_speed = 115200 monitor_filters = esp32_exception_decoder, log2file @@ -12,9 +17,10 @@ monitor_filters = esp32_exception_decoder, log2file lib_dir = . ; src_dir = examples/CaptivePortal ; src_dir = examples/SimpleServer -src_dir = examples/StreamFiles +; src_dir = examples/StreamFiles ; src_dir = examples/Filters ; src_dir = examples/Draft +src_dir = examples/issues/Issue14 [env:arduino] platform = espressif32 From 18ed8fbe2af0ae99cb622238fa9bb845c3984cdd Mon Sep 17 00:00:00 2001 From: Emil Muratov Date: Tue, 2 Jul 2024 00:52:01 +0900 Subject: [PATCH 278/551] string literals for ESP32 and ESP8266 segregate definitions for string literals - const char* for anything no 8266, PROGMEM otherwise --- src/AsyncEventSource.cpp | 41 ++--- src/AsyncWebSocket.cpp | 4 +- src/ESPAsyncWebServer.h | 9 +- src/WebAuthentication.cpp | 32 ++-- src/WebHandlers.cpp | 14 +- src/WebRequest.cpp | 163 ++++++++---------- src/WebResponses.cpp | 205 ++++++++++++----------- src/WebServer.cpp | 2 +- src/literals.h | 338 ++++++++++++++++++++++++++++++++++++++ 9 files changed, 566 insertions(+), 242 deletions(-) create mode 100644 src/literals.h diff --git a/src/AsyncEventSource.cpp b/src/AsyncEventSource.cpp index 4cafdae17..66daa77ac 100644 --- a/src/AsyncEventSource.cpp +++ b/src/AsyncEventSource.cpp @@ -22,26 +22,27 @@ #include #endif #include "AsyncEventSource.h" +#include "literals.h" static String generateEventMessage(const char* message, const char* event, uint32_t id, uint32_t reconnect) { String ev; if (reconnect) { - ev += F("retry: "); + ev += T_retry_; ev += reconnect; - ev += F("\r\n"); + ev += T_rn; } if (id) { - ev += F("id: "); - ev += String(id); - ev += F("\r\n"); + ev += T_id__; + ev += id; + ev += T_rn; } if (event != NULL) { - ev += F("event: "); - ev += String(event); - ev += F("\r\n"); + ev += T_event_; + ev += event; + ev += T_rn; } if (message != NULL) { @@ -57,9 +58,9 @@ static String generateEventMessage(const char* message, const char* event, uint3 if (ldata != NULL) { memcpy(ldata, lineStart, llen); ldata[llen] = 0; - ev += F("data: "); + ev += T_data_; ev += ldata; - ev += F("\r\n\r\n"); + ev += T_rnrn; free(ldata); } lineStart = (char*)message + messageLen; @@ -92,14 +93,14 @@ static String generateEventMessage(const char* message, const char* event, uint3 if (ldata != NULL) { memcpy(ldata, lineStart, llen); ldata[llen] = 0; - ev += F("data: "); + ev += T_data_; ev += ldata; - ev += F("\r\n"); + ev += T_rn; free(ldata); } lineStart = nextLine; if (lineStart == ((char*)message + messageLen)) - ev += F("\r\n"); + ev += T_rn; } } while (lineStart < ((char*)message + messageLen)); } @@ -158,8 +159,8 @@ AsyncEventSourceClient::AsyncEventSourceClient(AsyncWebServerRequest* request, A _client = request->client(); _server = server; _lastId = 0; - if (request->hasHeader(F("Last-Event-ID"))) - _lastId = atoi(request->getHeader(F("Last-Event-ID"))->value().c_str()); + if (request->hasHeader(T_Last_Event_ID)) + _lastId = atoi(request->getHeader(T_Last_Event_ID)->value().c_str()); _client->setRxTimeout(0); _client->onError(NULL, NULL); @@ -360,8 +361,8 @@ bool AsyncEventSource::canHandle(AsyncWebServerRequest* request) { if (request->method() != HTTP_GET || !request->url().equals(_url)) { return false; } - request->addInterestingHeader(F("Last-Event-ID")); - request->addInterestingHeader("Cookie"); + request->addInterestingHeader(T_Last_Event_ID); + request->addInterestingHeader(T_Cookie); return true; } @@ -382,10 +383,10 @@ void AsyncEventSource::handleRequest(AsyncWebServerRequest* request) { AsyncEventSourceResponse::AsyncEventSourceResponse(AsyncEventSource* server) { _server = server; _code = 200; - _contentType = F("text/event-stream"); + _contentType = T_text_event_stream; _sendContentLength = false; - addHeader(F("Cache-Control"), F("no-cache")); - addHeader(F("Connection"), F("keep-alive")); + addHeader(T_Cache_Control, T_no_cache); + addHeader(T_Connection, T_keep_alive); } void AsyncEventSourceResponse::_respond(AsyncWebServerRequest* request) { diff --git a/src/AsyncWebSocket.cpp b/src/AsyncWebSocket.cpp index e978afccd..fa7c22dda 100644 --- a/src/AsyncWebSocket.cpp +++ b/src/AsyncWebSocket.cpp @@ -1108,7 +1108,7 @@ void AsyncWebSocket::handleRequest(AsyncWebServerRequest* request) { const AsyncWebHeader* version = request->getHeader(WS_STR_VERSION); if (version->value().toInt() != 13) { AsyncWebServerResponse* response = request->beginResponse(400); - response->addHeader(WS_STR_VERSION, F("13")); + response->addHeader(WS_STR_VERSION, T_13); request->send(response); return; } @@ -1173,7 +1173,7 @@ AsyncWebSocketResponse::AsyncWebSocketResponse(const String& key, AsyncWebSocket int len = base64_encode_block((const char*)hash, 20, buffer, &_state); len = base64_encode_blockend((buffer + len), &_state); addHeader(WS_STR_CONNECTION, WS_STR_UPGRADE); - addHeader(WS_STR_UPGRADE, F("websocket")); + addHeader(WS_STR_UPGRADE, T_WS); addHeader(WS_STR_ACCEPT, buffer); } diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index 77c5de772..ef94ab30f 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -43,6 +43,8 @@ #error Platform not supported #endif +#include "literals.h" + #define ASYNCWEBSERVER_VERSION "3.0.6" #define ASYNCWEBSERVER_VERSION_MAJOR 3 #define ASYNCWEBSERVER_VERSION_MINOR 0 @@ -151,7 +153,7 @@ class AsyncWebHeader { const String& name() const { return _name; } const String& value() const { return _value; } - String toString() const { return _name + F(": ") + _value + F("\r\n"); } + String toString() const { return _name + (char)0x3a + (char)0x20 /*": "*/ + _value + T_rn; } }; /* @@ -509,10 +511,13 @@ class AsyncWebServerResponse { size_t _ackedLength; size_t _writtenLength; WebResponseState _state; - const char* _responseCodeToString(int code); public: +#ifndef ESP8266 + static const char* responseCodeToString(int code); +#else static const __FlashStringHelper* responseCodeToString(int code); +#endif public: AsyncWebServerResponse(); diff --git a/src/WebAuthentication.cpp b/src/WebAuthentication.cpp index abd74b810..14a772902 100644 --- a/src/WebAuthentication.cpp +++ b/src/WebAuthentication.cpp @@ -25,6 +25,7 @@ #else #include "md5.h" #endif +#include "literals.h" // Basic Auth hash = base64("username:password") @@ -133,16 +134,16 @@ String generateDigestHash(const char* username, const char* password, const char } String requestDigestAuthentication(const char* realm) { - String header = F("realm=\""); + String header(T_realm__); if (realm == NULL) - header.concat(F("asyncesp")); + header.concat(T_asyncesp); else header.concat(realm); - header.concat(F("\", qop=\"auth\", nonce=\"")); + header.concat(T_auth_nonce); header.concat(genRandomMD5()); - header.concat(F("\", opaque=\"")); + header.concat(T__opaque); header.concat(genRandomMD5()); - header += '"'; + header += (char)0x22; // '"' return header; } @@ -173,7 +174,8 @@ bool checkDigestAuthentication(const char* header, const __FlashStringHelper* me String myNc; String myCnonce; - myHeader += F(", "); + myHeader += (char)0x2c; // ',' + myHeader += (char)0x20; // ' ' do { String avLine(myHeader.substring(0, nextBreak)); avLine.trim(); @@ -191,42 +193,42 @@ bool checkDigestAuthentication(const char* header, const __FlashStringHelper* me avLine = avLine.substring(1, avLine.length() - 1); } - if (varName.equals(F("username"))) { + if (varName.equals(T_username)) { if (!avLine.equals(username)) { // os_printf("AUTH FAIL: username\n"); return false; } myUsername = avLine; - } else if (varName.equals(F("realm"))) { + } else if (varName.equals(T_realm)) { if (realm != NULL && !avLine.equals(realm)) { // os_printf("AUTH FAIL: realm\n"); return false; } myRealm = avLine; - } else if (varName.equals(F("nonce"))) { + } else if (varName.equals(T_nonce)) { if (nonce != NULL && !avLine.equals(nonce)) { // os_printf("AUTH FAIL: nonce\n"); return false; } myNonce = avLine; - } else if (varName.equals(F("opaque"))) { + } else if (varName.equals(T_opaque)) { if (opaque != NULL && !avLine.equals(opaque)) { // os_printf("AUTH FAIL: opaque\n"); return false; } - } else if (varName.equals(F("uri"))) { + } else if (varName.equals(T_uri)) { if (uri != NULL && !avLine.equals(uri)) { // os_printf("AUTH FAIL: uri\n"); return false; } myUri = avLine; - } else if (varName.equals(F("response"))) { + } else if (varName.equals(T_response)) { myResponse = avLine; - } else if (varName.equals(F("qop"))) { + } else if (varName.equals(T_qop)) { myQop = avLine; - } else if (varName.equals(F("nc"))) { + } else if (varName.equals(T_nc)) { myNc = avLine; - } else if (varName.equals(F("cnonce"))) { + } else if (varName.equals(T_cnonce)) { myCnonce = avLine; } } while (nextBreak > 0); diff --git a/src/WebHandlers.cpp b/src/WebHandlers.cpp index d740d8627..41399b89d 100644 --- a/src/WebHandlers.cpp +++ b/src/WebHandlers.cpp @@ -222,22 +222,22 @@ void AsyncStaticWebHandler::handleRequest(AsyncWebServerRequest* request) { } else { etag = String(request->_tempFile.size()); } - if (_last_modified.length() && _last_modified == request->header(F("If-Modified-Since"))) { + if (_last_modified.length() && _last_modified == request->header(T_IMS)) { request->_tempFile.close(); request->send(304); // Not modified - } else if (_cache_control.length() && request->hasHeader(F("If-None-Match")) && request->header(F("If-None-Match")).equals(etag)) { + } else if (_cache_control.length() && request->hasHeader(T_INM) && request->header(T_INM).equals(etag)) { request->_tempFile.close(); AsyncWebServerResponse* response = new AsyncBasicResponse(304); // Not modified - response->addHeader(F("Cache-Control"), _cache_control); - response->addHeader(F("ETag"), etag); + response->addHeader(T_Cache_Control, _cache_control); + response->addHeader(T_ETag, etag); request->send(response); } else { AsyncWebServerResponse* response = new AsyncFileResponse(request->_tempFile, filename, String(), false, _callback); if (_last_modified.length()) - response->addHeader(F("Last-Modified"), _last_modified); + response->addHeader(T_Last_Modified, _last_modified); if (_cache_control.length()) { - response->addHeader(F("Cache-Control"), _cache_control); - response->addHeader(F("ETag"), etag); + response->addHeader(T_Cache_Control, _cache_control); + response->addHeader(T_ETag, etag); } request->send(response); } diff --git a/src/WebRequest.cpp b/src/WebRequest.cpp index 2331b133c..a1e758ebb 100644 --- a/src/WebRequest.cpp +++ b/src/WebRequest.cpp @@ -21,6 +21,7 @@ #include "ESPAsyncWebServer.h" #include "WebAuthentication.h" #include "WebResponseImpl.h" +#include "literals.h" #ifndef ESP8266 #define os_strlen strlen @@ -113,9 +114,9 @@ void AsyncWebServerRequest::_onData(void* buf, size_t len) { _parsedLength += len; } else { if (_parsedLength == 0) { - if (_contentType.startsWith(F("application/x-www-form-urlencoded"))) { + if (_contentType.startsWith(T_app_xform_urlencoded)) { _isPlainPost = true; - } else if (_contentType == F("text/plain") && __is_param_char(((char*)buf)[0])) { + } else if (_contentType == T_text_plain && __is_param_char(((char*)buf)[0])) { size_t i = 0; while (i < len && __is_param_char(((char*)buf)[i++])) ; @@ -153,7 +154,7 @@ void AsyncWebServerRequest::_onData(void* buf, size_t len) { } void AsyncWebServerRequest::_removeNotInterestingHeaders() { - if (std::any_of(std::begin(_interestingHeaders), std::end(_interestingHeaders), [](const String& str) { return str.equalsIgnoreCase(F("ANY")); })) + if (std::any_of(std::begin(_interestingHeaders), std::end(_interestingHeaders), [](const String& str) { return str.equalsIgnoreCase(T_ANY); })) return; // nothing to do for (auto iter = std::begin(_headers); iter != std::end(_headers);) { @@ -246,19 +247,19 @@ bool AsyncWebServerRequest::_parseReqHead() { String u = _temp.substring(m.length() + 1, index); _temp = _temp.substring(index + 1); - if (m == F("GET")) { + if (m == T_GET) { _method = HTTP_GET; - } else if (m == F("POST")) { + } else if (m == T_POST) { _method = HTTP_POST; - } else if (m == F("DELETE")) { + } else if (m == T_DELETE) { _method = HTTP_DELETE; - } else if (m == F("PUT")) { + } else if (m == T_PUT) { _method = HTTP_PUT; - } else if (m == F("PATCH")) { + } else if (m == T_PATCH) { _method = HTTP_PATCH; - } else if (m == F("HEAD")) { + } else if (m == T_HEAD) { _method = HTTP_HEAD; - } else if (m == F("OPTIONS")) { + } else if (m == T_OPTIONS) { _method = HTTP_OPTIONS; } @@ -271,7 +272,7 @@ bool AsyncWebServerRequest::_parseReqHead() { _url = urlDecode(u); _addGetParams(g); - if (!_temp.startsWith(F("HTTP/1.0"))) + if (!_temp.startsWith(T_HTTP_1_0)) _version = 1; _temp = String(); @@ -304,34 +305,34 @@ bool strContains(const String& src, const String& find, bool mindcase = true) { bool AsyncWebServerRequest::_parseReqHeader() { int index = _temp.indexOf(':'); if (index) { - String name = _temp.substring(0, index); - String value = _temp.substring(index + 2); - if (name.equalsIgnoreCase("Host")) { + String name(_temp.substring(0, index)); + String value(_temp.substring(index + 2)); + if (name.equalsIgnoreCase(T_Host)) { _host = value; - } else if (name.equalsIgnoreCase(F("Content-Type"))) { + } else if (name.equalsIgnoreCase(T_Content_Type)) { _contentType = value.substring(0, value.indexOf(';')); - if (value.startsWith(F("multipart/"))) { + if (value.startsWith(T_MULTIPART_)) { _boundary = value.substring(value.indexOf('=') + 1); _boundary.replace(String('"'), String()); _isMultipart = true; } - } else if (name.equalsIgnoreCase(F("Content-Length"))) { + } else if (name.equalsIgnoreCase(T_Content_Length)) { _contentLength = atoi(value.c_str()); - } else if (name.equalsIgnoreCase(F("Expect")) && value == F("100-continue")) { + } else if (name.equalsIgnoreCase(T_EXPECT) && value == T_100_CONTINUE) { _expectingContinue = true; - } else if (name.equalsIgnoreCase(F("Authorization"))) { - if (value.length() > 5 && value.substring(0, 5).equalsIgnoreCase(F("Basic"))) { + } else if (name.equalsIgnoreCase(T_AUTH)) { + if (value.length() > 5 && value.substring(0, 5).equalsIgnoreCase(T_BASIC)) { _authorization = value.substring(6); - } else if (value.length() > 6 && value.substring(0, 6).equalsIgnoreCase(F("Digest"))) { + } else if (value.length() > 6 && value.substring(0, 6).equalsIgnoreCase(T_DIGEST)) { _isDigest = true; _authorization = value.substring(7); } } else { - if (name.equalsIgnoreCase(F("Upgrade")) && value.equalsIgnoreCase(F("websocket"))) { + if (name.equalsIgnoreCase(T_UPGRADE) && value.equalsIgnoreCase(T_WS)) { // WebSocket request can be uniquely identified by header: [Upgrade: websocket] _reqconntype = RCT_WS; } else { - if (name.equalsIgnoreCase(F("Accept")) && strContains(value, F("text/event-stream"), false)) { + if (name.equalsIgnoreCase(T_ACCEPT) && strContains(value, F(T_text_event_stream), false)) { // WebEvent request can be uniquely identified by header: [Accept: text/event-stream] _reqconntype = RCT_EVENT; } @@ -347,9 +348,9 @@ void AsyncWebServerRequest::_parsePlainPostChar(uint8_t data) { if (data && (char)data != '&') _temp += (char)data; if (!data || (char)data == '&' || _parsedLength == _contentLength) { - String name = F("body"); - String value = _temp; - if (!_temp.startsWith(String('{')) && !_temp.startsWith(String('[')) && _temp.indexOf('=') > 0) { + String name(T_BODY); + String value(_temp); + if (!(_temp.charAt(0) == '{') && !(_temp.charAt(0) == '[') && _temp.indexOf('=') > 0) { name = _temp.substring(0, _temp.indexOf('=')); value = _temp.substring(_temp.indexOf('=') + 1); } @@ -430,17 +431,17 @@ void AsyncWebServerRequest::_parseMultipartPostByte(uint8_t data, bool last) { _temp += (char)data; if ((char)data == '\n') { if (_temp.length()) { - if (_temp.length() > 12 && _temp.substring(0, 12).equalsIgnoreCase(F("Content-Type"))) { + if (_temp.length() > 12 && _temp.substring(0, 12).equalsIgnoreCase(T_Content_Type)) { _itemType = _temp.substring(14); _itemIsFile = true; - } else if (_temp.length() > 19 && _temp.substring(0, 19).equalsIgnoreCase(F("Content-Disposition"))) { + } else if (_temp.length() > 19 && _temp.substring(0, 19).equalsIgnoreCase(T_Content_Disposition)) { _temp = _temp.substring(_temp.indexOf(';') + 2); while (_temp.indexOf(';') > 0) { String name = _temp.substring(0, _temp.indexOf('=')); String nameVal = _temp.substring(_temp.indexOf('=') + 2, _temp.indexOf(';') - 1); - if (name == F("name")) { + if (name == T_name) { _itemName = nameVal; - } else if (name == F("filename")) { + } else if (name == T_filename) { _itemFilename = nameVal; _itemIsFile = true; } @@ -448,9 +449,9 @@ void AsyncWebServerRequest::_parseMultipartPostByte(uint8_t data, bool last) { } String name = _temp.substring(0, _temp.indexOf('=')); String nameVal = _temp.substring(_temp.indexOf('=') + 2, _temp.length() - 1); - if (name == F("name")) { + if (name == T_name) { _itemName = nameVal; - } else if (name == F("filename")) { + } else if (name == T_filename) { _itemFilename = nameVal; _itemIsFile = true; } @@ -590,7 +591,7 @@ void AsyncWebServerRequest::_parseLine() { _server->_attachHandler(this); _removeNotInterestingHeaders(); if (_expectingContinue) { - String response = F("HTTP/1.1 100 Continue\r\n\r\n"); + String response(T_HTTP_100_CONT); _client->write(response.c_str(), response.length()); } // check handler for authentication @@ -711,7 +712,7 @@ AsyncWebServerResponse* AsyncWebServerRequest::beginResponse(int code, const Str } AsyncWebServerResponse* AsyncWebServerRequest::beginResponse(FS& fs, const String& path, const String& contentType, bool download, AwsTemplateProcessor callback) { - if (fs.exists(path) || (!download && fs.exists(path + F(".gz")))) + if (fs.exists(path) || (!download && fs.exists(path + T__gz))) return new AsyncFileResponse(fs, path, contentType, download, callback); return NULL; } @@ -770,7 +771,7 @@ void AsyncWebServerRequest::send(int code, const String& contentType, PGM_P cont } void AsyncWebServerRequest::send(FS& fs, const String& path, const String& contentType, bool download, AwsTemplateProcessor callback) { - if (fs.exists(path) || (!download && fs.exists(path + F(".gz")))) { + if (fs.exists(path) || (!download && fs.exists(path + T__gz))) { send(beginResponse(fs, path, contentType, download, callback)); } else send(404); @@ -797,7 +798,7 @@ void AsyncWebServerRequest::sendChunked(const String& contentType, AwsResponseFi void AsyncWebServerRequest::redirect(const char* url) { AsyncWebServerResponse* response = beginResponse(302); - response->addHeader(F("Location"), url); + response->addHeader(T_LOCATION, url); send(response); } @@ -838,16 +839,16 @@ bool AsyncWebServerRequest::authenticate(const char* hash) { void AsyncWebServerRequest::requestAuthentication(const char* realm, bool isDigest) { AsyncWebServerResponse* r = beginResponse(401); if (!isDigest && realm == NULL) { - r->addHeader(F("WWW-Authenticate"), F("Basic realm=\"Login Required\"")); + r->addHeader(T_WWW_AUTH, T_BASIC_REALM_LOGIN_REQ); } else if (!isDigest) { - String header = F("Basic realm=\""); + String header(T_BASIC_REALM); header.concat(realm); header += '"'; - r->addHeader(F("WWW-Authenticate"), header); + r->addHeader(T_WWW_AUTH, header); } else { - String header = F("Digest "); + String header(T_DIGEST_); header.concat(requestDigestAuthentication(realm)); - r->addHeader(F("WWW-Authenticate"), header); + r->addHeader(T_WWW_AUTH, header); } send(r); } @@ -939,82 +940,52 @@ String AsyncWebServerRequest::urlDecode(const String& text) const { } #ifndef ESP8266 -const char* AsyncWebServerRequest::methodToString() const { +const char* AsyncWebServerRequest::methodToString() const +#else +const __FlashStringHelper* AsyncWebServerRequest::methodToString() const +#endif +{ if (_method == HTTP_ANY) - return "ANY"; + return T_ANY; if (_method & HTTP_GET) - return "GET"; + return T_GET; if (_method & HTTP_POST) - return "POST"; + return T_POST; if (_method & HTTP_DELETE) - return "DELETE"; + return T_DELETE; if (_method & HTTP_PUT) - return "PUT"; + return T_PUT; if (_method & HTTP_PATCH) - return "PATCH"; + return T_PATCH; if (_method & HTTP_HEAD) - return "HEAD"; + return T_HEAD; if (_method & HTTP_OPTIONS) - return "OPTIONS"; - return "UNKNOWN"; + return T_OPTIONS; + return T_UNKNOWN; } -const char* AsyncWebServerRequest::requestedConnTypeToString() const { - switch (_reqconntype) { - case RCT_NOT_USED: - return "RCT_NOT_USED"; - case RCT_DEFAULT: - return "RCT_DEFAULT"; - case RCT_HTTP: - return "RCT_HTTP"; - case RCT_WS: - return "RCT_WS"; - case RCT_EVENT: - return "RCT_EVENT"; - default: - return "ERROR"; - } -} +#ifndef ESP8266 +const char* AsyncWebServerRequest::requestedConnTypeToString() const +#else +const __FlashStringHelper* AsyncWebServerRequest::requestedConnTypeToString() const #endif +{ -#ifdef ESP8266 -const __FlashStringHelper* AsyncWebServerRequest::methodToString() const { - if (_method == HTTP_ANY) - return F("ANY"); - else if (_method & HTTP_GET) - return F("GET"); - else if (_method & HTTP_POST) - return F("POST"); - else if (_method & HTTP_DELETE) - return F("DELETE"); - else if (_method & HTTP_PUT) - return F("PUT"); - else if (_method & HTTP_PATCH) - return F("PATCH"); - else if (_method & HTTP_HEAD) - return F("HEAD"); - else if (_method & HTTP_OPTIONS) - return F("OPTIONS"); - return F("UNKNOWN"); -} - -const __FlashStringHelper* AsyncWebServerRequest::requestedConnTypeToString() const { switch (_reqconntype) { case RCT_NOT_USED: - return F("RCT_NOT_USED"); + return T_RCT_NOT_USED; case RCT_DEFAULT: - return F("RCT_DEFAULT"); + return T_RCT_DEFAULT; case RCT_HTTP: - return F("RCT_HTTP"); + return T_RCT_HTTP; case RCT_WS: - return F("RCT_WS"); + return T_RCT_WS; case RCT_EVENT: - return F("RCT_EVENT"); + return T_RCT_EVENT; default: - return F("ERROR"); + return T_ERROR; } } -#endif bool AsyncWebServerRequest::isExpectedRequestedConnType(RequestedConnectionType erct1, RequestedConnectionType erct2, RequestedConnectionType erct3) { bool res = false; diff --git a/src/WebResponses.cpp b/src/WebResponses.cpp index 1fd41fa89..c21a97118 100644 --- a/src/WebResponses.cpp +++ b/src/WebResponses.cpp @@ -33,95 +33,98 @@ void* memchr(void* ptr, int ch, size_t count) { /* * Abstract Response - * */ -const char* AsyncWebServerResponse::_responseCodeToString(int code) { - return reinterpret_cast(responseCodeToString(code)); -} + * + */ -const __FlashStringHelper* AsyncWebServerResponse::responseCodeToString(int code) { +#ifndef ESP8266 +const char* AsyncWebServerResponse::responseCodeToString(int code) +#else +const __FlashStringHelper* AsyncWebServerResponse::responseCodeToString(int code) +#endif +{ switch (code) { case 100: - return F("Continue"); + return T_HTTP_CODE_100; case 101: - return F("Switching Protocols"); + return T_HTTP_CODE_101; case 200: - return F("OK"); + return T_HTTP_CODE_200; case 201: - return F("Created"); + return T_HTTP_CODE_201; case 202: - return F("Accepted"); + return T_HTTP_CODE_202; case 203: - return F("Non-Authoritative Information"); + return T_HTTP_CODE_203; case 204: - return F("No Content"); + return T_HTTP_CODE_204; case 205: - return F("Reset Content"); + return T_HTTP_CODE_205; case 206: - return F("Partial Content"); + return T_HTTP_CODE_206; case 300: - return F("Multiple Choices"); + return T_HTTP_CODE_300; case 301: - return F("Moved Permanently"); + return T_HTTP_CODE_301; case 302: - return F("Found"); + return T_HTTP_CODE_302; case 303: - return F("See Other"); + return T_HTTP_CODE_303; case 304: - return F("Not Modified"); + return T_HTTP_CODE_304; case 305: - return F("Use Proxy"); + return T_HTTP_CODE_305; case 307: - return F("Temporary Redirect"); + return T_HTTP_CODE_307; case 400: - return F("Bad Request"); + return T_HTTP_CODE_400; case 401: - return F("Unauthorized"); + return T_HTTP_CODE_401; case 402: - return F("Payment Required"); + return T_HTTP_CODE_402; case 403: - return F("Forbidden"); + return T_HTTP_CODE_403; case 404: - return F("Not Found"); + return T_HTTP_CODE_404; case 405: - return F("Method Not Allowed"); + return T_HTTP_CODE_405; case 406: - return F("Not Acceptable"); + return T_HTTP_CODE_406; case 407: - return F("Proxy Authentication Required"); + return T_HTTP_CODE_407; case 408: - return F("Request Time-out"); + return T_HTTP_CODE_408; case 409: - return F("Conflict"); + return T_HTTP_CODE_409; case 410: - return F("Gone"); + return T_HTTP_CODE_410; case 411: - return F("Length Required"); + return T_HTTP_CODE_411; case 412: - return F("Precondition Failed"); + return T_HTTP_CODE_412; case 413: - return F("Request Entity Too Large"); + return T_HTTP_CODE_413; case 414: - return F("Request-URI Too Large"); + return T_HTTP_CODE_414; case 415: - return F("Unsupported Media Type"); + return T_HTTP_CODE_415; case 416: - return F("Requested range not satisfiable"); + return T_HTTP_CODE_416; case 417: - return F("Expectation Failed"); + return T_HTTP_CODE_417; case 500: - return F("Internal Server Error"); + return T_HTTP_CODE_500; case 501: - return F("Not Implemented"); + return T_HTTP_CODE_501; case 502: - return F("Bad Gateway"); + return T_HTTP_CODE_502; case 503: - return F("Service Unavailable"); + return T_HTTP_CODE_503; case 504: - return F("Gateway Time-out"); + return T_HTTP_CODE_504; case 505: - return F("HTTP Version not supported"); + return T_HTTP_CODE_505; default: - return F(""); + return T_HTTP_CODE_ANY; } } @@ -155,15 +158,19 @@ void AsyncWebServerResponse::addHeader(const String& name, const String& value) String AsyncWebServerResponse::_assembleHead(uint8_t version) { if (version) { - addHeader(F("Accept-Ranges"), F("none")); + addHeader(T_Accept_Ranges, T_none); if (_chunked) - addHeader(F("Transfer-Encoding"), F("chunked")); + addHeader(Transfer_Encoding, T_chunked); } - String out = String(); + String out; int bufSize = 300; char buf[bufSize]; - snprintf_P(buf, bufSize, PSTR("HTTP/1.%d %d %s\r\n"), version, _code, _responseCodeToString(_code)); +#ifndef ESP8266 + snprintf(buf, bufSize, "HTTP/1.%d %d %s\r\n", version, _code, responseCodeToString(_code)); +#else + snprintf_P(buf, bufSize, PSTR("HTTP/1.%d %d %s\r\n"), version, _code, String(responseCodeToString(_code)).c_str()); +#endif out.concat(buf); if (_sendContentLength) { @@ -181,7 +188,7 @@ String AsyncWebServerResponse::_assembleHead(uint8_t version) { } _headers.clear(); - out.concat(F("\r\n")); + out.concat(T_rn); _headLength = out.length(); return out; } @@ -211,9 +218,9 @@ AsyncBasicResponse::AsyncBasicResponse(int code, const String& contentType, cons if (_content.length()) { _contentLength = _content.length(); if (!_contentType.length()) - _contentType = F("text/plain"); + _contentType = T_text_plain; } - addHeader(F("Connection"), F("close")); + addHeader(T_Connection, T_close); } void AsyncBasicResponse::_respond(AsyncWebServerRequest* request) { @@ -291,7 +298,7 @@ AsyncAbstractResponse::AsyncAbstractResponse(AwsTemplateProcessor callback) : _c } void AsyncAbstractResponse::_respond(AsyncWebServerRequest* request) { - addHeader(F("Connection"), F("close")); + addHeader(T_Connection, T_close); _head = _assembleHead(request->version()); _state = RESPONSE_HEADERS; _ack(request, 0, 0); @@ -514,48 +521,48 @@ AsyncFileResponse::~AsyncFileResponse() { } void AsyncFileResponse::_setContentType(const String& path) { -#if HAVE_EXTERN_GET_CONTENT_TYPE_FUNCTION +#if HAVE_EXTERN_GET_Content_Type_FUNCTION extern const __FlashStringHelper* getContentType(const String& path); _contentType = getContentType(path); #else - if (path.endsWith(F(".html"))) - _contentType = F("text/html"); - else if (path.endsWith(F(".htm"))) - _contentType = F("text/html"); - else if (path.endsWith(F(".css"))) - _contentType = F("text/css"); - else if (path.endsWith(F(".json"))) - _contentType = F("application/json"); - else if (path.endsWith(F(".js"))) - _contentType = F("application/javascript"); - else if (path.endsWith(F(".png"))) - _contentType = F("image/png"); - else if (path.endsWith(F(".gif"))) - _contentType = F("image/gif"); - else if (path.endsWith(F(".jpg"))) - _contentType = F("image/jpeg"); - else if (path.endsWith(F(".ico"))) - _contentType = F("image/x-icon"); - else if (path.endsWith(F(".svg"))) - _contentType = F("image/svg+xml"); - else if (path.endsWith(F(".eot"))) - _contentType = F("font/eot"); - else if (path.endsWith(F(".woff"))) - _contentType = F("font/woff"); - else if (path.endsWith(F(".woff2"))) - _contentType = F("font/woff2"); - else if (path.endsWith(F(".ttf"))) - _contentType = F("font/ttf"); - else if (path.endsWith(F(".xml"))) - _contentType = F("text/xml"); - else if (path.endsWith(F(".pdf"))) - _contentType = F("application/pdf"); - else if (path.endsWith(F(".zip"))) - _contentType = F("application/zip"); - else if (path.endsWith(F(".gz"))) - _contentType = F("application/x-gzip"); + if (path.endsWith(T__html)) + _contentType = T_text_html; + else if (path.endsWith(T__htm)) + _contentType = T_text_html; + else if (path.endsWith(T__css)) + _contentType = T_text_css; + else if (path.endsWith(T__json)) + _contentType = T_application_json; + else if (path.endsWith(T__js)) + _contentType = T_application_javascript; + else if (path.endsWith(T__png)) + _contentType = T_image_png; + else if (path.endsWith(T__gif)) + _contentType = T_image_gif; + else if (path.endsWith(T__jpg)) + _contentType = T_image_jpeg; + else if (path.endsWith(T__ico)) + _contentType = T_image_x_icon; + else if (path.endsWith(T__svg)) + _contentType = T_image_svg_xml; + else if (path.endsWith(T__eot)) + _contentType = T_font_eot; + else if (path.endsWith(T__woff)) + _contentType = T_font_woff; + else if (path.endsWith(T__woff2)) + _contentType = T_font_woff2; + else if (path.endsWith(T__ttf)) + _contentType = T_font_ttf; + else if (path.endsWith(T__xml)) + _contentType = T_text_xml; + else if (path.endsWith(T__pdf)) + _contentType = T_application_pdf; + else if (path.endsWith(T__zip)) + _contentType = T_application_zip; + else if (path.endsWith(T__gz)) + _contentType = T_application_x_gzip; else - _contentType = F("text/plain"); + _contentType = T_text_plain; #endif } @@ -563,9 +570,9 @@ AsyncFileResponse::AsyncFileResponse(FS& fs, const String& path, const String& c _code = 200; _path = path; - if (!download && !fs.exists(_path) && fs.exists(_path + F(".gz"))) { - _path = _path + F(".gz"); - addHeader(F("Content-Encoding"), F("gzip")); + if (!download && !fs.exists(_path) && fs.exists(_path + T__gz)) { + _path = _path + T__gz; + addHeader(T_Content_Encoding, T_gzip); _callback = nullptr; // Unable to process zipped templates _sendContentLength = true; _chunked = false; @@ -590,15 +597,15 @@ AsyncFileResponse::AsyncFileResponse(FS& fs, const String& path, const String& c // set filename and force rendering snprintf_P(buf, sizeof(buf), PSTR("inline")); } - addHeader(F("Content-Disposition"), buf); + addHeader(T_Content_Disposition, buf); } AsyncFileResponse::AsyncFileResponse(File content, const String& path, const String& contentType, bool download, AwsTemplateProcessor callback) : AsyncAbstractResponse(callback) { _code = 200; _path = path; - if (!download && String(content.name()).endsWith(F(".gz")) && !path.endsWith(F(".gz"))) { - addHeader(F("Content-Encoding"), F("gzip")); + if (!download && String(content.name()).endsWith(T__gz) && !path.endsWith(T__gz)) { + addHeader(T_Content_Encoding, T_gzip); _callback = nullptr; // Unable to process gzipped templates _sendContentLength = true; _chunked = false; @@ -621,7 +628,7 @@ AsyncFileResponse::AsyncFileResponse(File content, const String& path, const Str } else { snprintf_P(buf, sizeof(buf), PSTR("inline")); } - addHeader(F("Content-Disposition"), buf); + addHeader(T_Content_Disposition, buf); } size_t AsyncFileResponse::_fillBuffer(uint8_t* data, size_t len) { diff --git a/src/WebServer.cpp b/src/WebServer.cpp index 9d78e027b..bc48b460e 100644 --- a/src/WebServer.cpp +++ b/src/WebServer.cpp @@ -145,7 +145,7 @@ void AsyncWebServer::_attachHandler(AsyncWebServerRequest* request) { } } - request->addInterestingHeader(F("ANY")); + request->addInterestingHeader(T_ANY); request->setHandler(_catchAllHandler); } diff --git a/src/literals.h b/src/literals.h new file mode 100644 index 000000000..50bd03aa0 --- /dev/null +++ b/src/literals.h @@ -0,0 +1,338 @@ +#pragma once + + +#ifndef ESP8622 +static constexpr const char* T_100_CONTINUE = "100-continue"; +static constexpr const char* T_ACCEPT = "Accept"; +static constexpr const char* T_Accept_Ranges = "Accept-Ranges"; +static constexpr const char* T_app_xform_urlencoded = "application/x-www-form-urlencoded"; +static constexpr const char* T_AUTH = "Authorization"; +static constexpr const char* T_BASIC = "Basic"; +static constexpr const char* T_BASIC_REALM = "Basic realm=\""; +static constexpr const char* T_BASIC_REALM_LOGIN_REQ = "Basic realm=\"Login Required\""; +static constexpr const char* T_BODY = "body"; +static constexpr const char* T_Cache_Control = "Cache-Control"; +static constexpr const char* T_chunked = "chunked"; +static constexpr const char* T_close = "close"; +static constexpr const char* T_Connection = "Connection"; +static constexpr const char* T_Content_Disposition = "Content-Disposition"; +static constexpr const char* T_Content_Encoding = "Content-Encoding"; +static constexpr const char* T_Content_Length = "Content-Length"; +static constexpr const char* T_Content_Type = "Content-Type"; +static constexpr const char* T_Cookie = "Cookie"; +static constexpr const char* T_DIGEST = "Digest"; +static constexpr const char* T_DIGEST_ = "Digest "; +static constexpr const char* T_ETag = "ETag"; +static constexpr const char* T_EXPECT = "Expect"; +static constexpr const char* T_HTTP_1_0 = "HTTP/1.0"; +static constexpr const char* T_HTTP_100_CONT = "HTTP/1.1 100 Continue\r\n\r\n"; +static constexpr const char* T_IMS = "If-Modified-Since"; +static constexpr const char* T_INM = "If-None-Match"; +static constexpr const char* T_keep_alive = "keep-alive"; +static constexpr const char* T_Last_Event_ID = "Last-Event-ID"; +static constexpr const char* T_Last_Modified = "Last-Modified"; +static constexpr const char* T_LOCATION = "Location"; +static constexpr const char* T_MULTIPART_ = "multipart/"; +static constexpr const char* T_no_cache = "no-cache"; +static constexpr const char* T_none = "none"; +static constexpr const char* T_UPGRADE = "Upgrade"; +static constexpr const char* T_WS = "websocket"; +static constexpr const char* T_WWW_AUTH = "WWW-Authenticate"; +static constexpr const char* Transfer_Encoding = "Transfer-Encoding"; + +// HTTP Methods +static constexpr const char* T_ANY = "ANY"; +static constexpr const char* T_GET = "GET"; +static constexpr const char* T_POST = "POST"; +static constexpr const char* T_PUT = "PUT"; +static constexpr const char* T_DELETE = "DELETE"; +static constexpr const char* T_PATCH = "PATCH"; +static constexpr const char* T_HEAD = "HEAD"; +static constexpr const char* T_OPTIONS = "OPTIONS"; +static constexpr const char* T_UNKNOWN = "UNKNOWN"; + +// Req content types +static constexpr const char* T_RCT_NOT_USED = "RCT_NOT_USED"; +static constexpr const char* T_RCT_DEFAULT = "RCT_DEFAULT"; +static constexpr const char* T_RCT_HTTP = "RCT_HTTP"; +static constexpr const char* T_RCT_WS = "RCT_WS"; +static constexpr const char* T_RCT_EVENT = "RCT_EVENT"; +static constexpr const char* T_ERROR = "ERROR"; + +// extentions & MIME-Types +static constexpr const char* T__css = ".css"; +static constexpr const char* T__eot = ".eot"; +static constexpr const char* T__gif = ".gif"; +static constexpr const char* T__gz = ".gz"; +static constexpr const char* T__htm = ".htm"; +static constexpr const char* T__html = ".html"; +static constexpr const char* T__ico = ".ico"; +static constexpr const char* T__jpg = ".jpg"; +static constexpr const char* T__js = ".js"; +static constexpr const char* T__json = ".json"; +static constexpr const char* T__pdf = ".pdf"; +static constexpr const char* T__png = ".png"; +static constexpr const char* T__svg = ".svg"; +static constexpr const char* T__ttf = ".ttf"; +static constexpr const char* T__woff = ".woff"; +static constexpr const char* T__woff2 = ".woff2"; +static constexpr const char* T__xml = ".xml"; +static constexpr const char* T__zip = ".zip"; +static constexpr const char* T_application_javascript = "application/javascript"; +static constexpr const char* T_application_json = "application/json"; +static constexpr const char* T_application_pdf = "application/pdf"; +static constexpr const char* T_application_x_gzip = "application/x-gzip"; +static constexpr const char* T_application_zip = "application/zip"; +static constexpr const char* T_font_eot = "font/eot"; +static constexpr const char* T_font_ttf = "font/ttf"; +static constexpr const char* T_font_woff = "font/woff"; +static constexpr const char* T_font_woff2 = "font/woff2"; +static constexpr const char* T_image_gif = "image/gif"; +static constexpr const char* T_image_jpeg = "image/jpeg"; +static constexpr const char* T_image_png = "image/png"; +static constexpr const char* T_image_svg_xml = "image/svg+xml"; +static constexpr const char* T_image_x_icon = "image/x-icon"; +static constexpr const char* T_text_css = "text/css"; +static constexpr const char* T_text_event_stream = "text/event-stream"; +static constexpr const char* T_text_html = "text/html"; +static constexpr const char* T_text_plain = "text/plain"; +static constexpr const char* T_text_xml = "text/xml"; + +// Responce codes +static constexpr const char* T_HTTP_CODE_100 = "Continue"; +static constexpr const char* T_HTTP_CODE_101 = "Switching Protocols"; +static constexpr const char* T_HTTP_CODE_200 = "OK"; +static constexpr const char* T_HTTP_CODE_201 = "Created"; +static constexpr const char* T_HTTP_CODE_202 = "Accepted"; +static constexpr const char* T_HTTP_CODE_203 = "Non-Authoritative Information"; +static constexpr const char* T_HTTP_CODE_204 = "No Content"; +static constexpr const char* T_HTTP_CODE_205 = "Reset Content"; +static constexpr const char* T_HTTP_CODE_206 = "Partial Content"; +static constexpr const char* T_HTTP_CODE_300 = "Multiple Choices"; +static constexpr const char* T_HTTP_CODE_301 = "Moved Permanently"; +static constexpr const char* T_HTTP_CODE_302 = "Found"; +static constexpr const char* T_HTTP_CODE_303 = "See Other"; +static constexpr const char* T_HTTP_CODE_304 = "Not Modified"; +static constexpr const char* T_HTTP_CODE_305 = "Use Proxy"; +static constexpr const char* T_HTTP_CODE_307 = "Temporary Redirect"; +static constexpr const char* T_HTTP_CODE_400 = "Bad Request"; +static constexpr const char* T_HTTP_CODE_401 = "Unauthorized"; +static constexpr const char* T_HTTP_CODE_402 = "Payment Required"; +static constexpr const char* T_HTTP_CODE_403 = "Forbidden"; +static constexpr const char* T_HTTP_CODE_404 = "Not Found"; +static constexpr const char* T_HTTP_CODE_405 = "Method Not Allowed"; +static constexpr const char* T_HTTP_CODE_406 = "Not Acceptable"; +static constexpr const char* T_HTTP_CODE_407 = "Proxy Authentication Required"; +static constexpr const char* T_HTTP_CODE_408 = "Request Time-out"; +static constexpr const char* T_HTTP_CODE_409 = "Conflict"; +static constexpr const char* T_HTTP_CODE_410 = "Gone"; +static constexpr const char* T_HTTP_CODE_411 = "Length Required"; +static constexpr const char* T_HTTP_CODE_412 = "Precondition Failed"; +static constexpr const char* T_HTTP_CODE_413 = "Request Entity Too Large"; +static constexpr const char* T_HTTP_CODE_414 = "Request-URI Too Large"; +static constexpr const char* T_HTTP_CODE_415 = "Unsupported Media Type"; +static constexpr const char* T_HTTP_CODE_416 = "Requested range not satisfiable"; +static constexpr const char* T_HTTP_CODE_417 = "Expectation Failed"; +static constexpr const char* T_HTTP_CODE_500 = "Internal Server Error"; +static constexpr const char* T_HTTP_CODE_501 = "Not Implemented"; +static constexpr const char* T_HTTP_CODE_502 = "Bad Gateway"; +static constexpr const char* T_HTTP_CODE_503 = "Service Unavailable"; +static constexpr const char* T_HTTP_CODE_504 = "Gateway Time-out"; +static constexpr const char* T_HTTP_CODE_505 = "HTTP Version not supported"; +static constexpr const char* T_HTTP_CODE_ANY = "Unknown code"; + +// other +static constexpr const char* T__opaque = "\", opaque=\""; +static constexpr const char* T_13 = "13"; +static constexpr const char* T_asyncesp = "asyncesp"; +static constexpr const char* T_auth_nonce = "\", qop=\"auth\", nonce=\""; +static constexpr const char* T_cnonce = "cnonce"; +static constexpr const char* T_data_ = "data: "; +static constexpr const char* T_event_ = "event: "; +static constexpr const char* T_filename = "filename"; +static constexpr const char* T_gzip = "gzip"; +static constexpr const char* T_Host = "Host"; +static constexpr const char* T_id__ = "id: "; +static constexpr const char* T_name = "name"; +static constexpr const char* T_nc = "nc"; +static constexpr const char* T_nonce = "nonce"; +static constexpr const char* T_opaque = "opaque"; +static constexpr const char* T_qop = "qop"; +static constexpr const char* T_realm = "realm"; +static constexpr const char* T_realm__ = "realm=\""; +static constexpr const char* T_response = "response"; +static constexpr const char* T_retry_ = "retry: "; +static constexpr const char* T_rn = "\r\n"; +static constexpr const char* T_rnrn = "\r\n\r\n"; +static constexpr const char* T_uri = "uri"; +static constexpr const char* T_username = "username"; + + +#else // ESP8622 + +static const char T_100_CONTINUE[] PROGMEM = "100-continue"; +static const char T_ACCEPT[] PROGMEM = "Accept"; +static const char T_Accept_Ranges[] PROGMEM = "Accept-Ranges"; +static const char T_app_xform_urlencoded[] PROGMEM = "application/x-www-form-urlencoded"; +static const char T_AUTH[] PROGMEM = "Authorization"; +static const char T_BASIC[] PROGMEM = "Basic"; +static const char T_BASIC_REALM[] PROGMEM = "Basic realm=\""; +static const char T_BASIC_REALM_LOGIN_REQ[] PROGMEM = "Basic realm=\"Login Required\""; +static const char T_BODY[] PROGMEM = "body"; +static const char T_Cache_Control[] PROGMEM = "Cache-Control"; +static const char T_chunked[] PROGMEM = "chunked"; +static const char T_close[] PROGMEM = "close"; +static const char T_Connection[] PROGMEM = "Connection"; +static const char T_Content_Disposition[] PROGMEM = "Content-Disposition"; +static const char T_Content_Encoding[] PROGMEM = "Content-Encoding"; +static const char T_Content_Length[] PROGMEM = "Content-Length"; +static const char T_Content_Type[] PROGMEM = "Content-Type"; +static const char T_Cookie[] PROGMEM = "Cookie"; +static const char T_DIGEST[] PROGMEM = "Digest"; +static const char T_DIGEST_[] PROGMEM = "Digest "; +static const char T_ETag[] PROGMEM = "ETag"; +static const char T_EXPECT[] PROGMEM = "Expect"; +static const char T_HTTP_1_0[] PROGMEM = "HTTP/1.0"; +static const char T_HTTP_100_CONT[] PROGMEM = "HTTP/1.1 100 Continue\r\n\r\n"; +static const char T_IMS[] PROGMEM = "If-Modified-Since"; +static const char T_INM[] PROGMEM = "If-None-Match"; +static const char T_keep_alive[] PROGMEM = "keep-alive"; +static const char T_Last_Event_ID[] PROGMEM = "Last-Event-ID"; +static const char T_Last_Modified[] PROGMEM = "Last-Modified"; +static const char T_LOCATION[] PROGMEM = "Location"; +static const char T_MULTIPART_[] PROGMEM = "multipart/"; +static const char T_no_cache[] PROGMEM = "no-cache"; +static const char T_none[] PROGMEM = "none"; +static const char T_UPGRADE[] PROGMEM = "Upgrade"; +static const char T_WS[] PROGMEM = "websocket"; +static const char T_WWW_AUTH[] PROGMEM = "WWW-Authenticate"; +static const char Transfer_Encoding[] PROGMEM = "Transfer-Encoding"; + +// HTTP Methods +static const char T_ANY[] PROGMEM = "ANY"; +static const char T_GET[] PROGMEM = "GET"; +static const char T_POST[] PROGMEM = "POST"; +static const char T_PUT[] PROGMEM = "PUT"; +static const char T_DELETE[] PROGMEM = "DELETE"; +static const char T_PATCH[] PROGMEM = "PATCH"; +static const char T_HEAD[] PROGMEM = "HEAD"; +static const char T_OPTIONS[] PROGMEM = "OPTIONS"; +static const char T_UNKNOWN[] PROGMEM = "UNKNOWN"; + +// Req content types +static const char T_RCT_NOT_USED[] PROGMEM = "RCT_NOT_USED"; +static const char T_RCT_DEFAULT[] PROGMEM = "RCT_DEFAULT"; +static const char T_RCT_HTTP[] PROGMEM = "RCT_HTTP"; +static const char T_RCT_WS[] PROGMEM = "RCT_WS"; +static const char T_RCT_EVENT[] PROGMEM = "RCT_EVENT"; +static const char T_ERROR[] PROGMEM = "ERROR"; + +// extentions & MIME-Types +static const char T__css[] PROGMEM = ".css"; +static const char T__eot[] PROGMEM = ".eot"; +static const char T__gif[] PROGMEM = ".gif"; +static const char T__gz[] PROGMEM = ".gz"; +static const char T__htm[] PROGMEM = ".htm"; +static const char T__html[] PROGMEM = ".html"; +static const char T__ico[] PROGMEM = ".ico"; +static const char T__jpg[] PROGMEM = ".jpg"; +static const char T__js[] PROGMEM = ".js"; +static const char T__json[] PROGMEM = ".json"; +static const char T__pdf[] PROGMEM = ".pdf"; +static const char T__png[] PROGMEM = ".png"; +static const char T__svg[] PROGMEM = ".svg"; +static const char T__ttf[] PROGMEM = ".ttf"; +static const char T__woff[] PROGMEM = ".woff"; +static const char T__woff2[] PROGMEM = ".woff2"; +static const char T__xml[] PROGMEM = ".xml"; +static const char T__zip[] PROGMEM = ".zip"; +static const char T_application_javascript[] PROGMEM = "application/javascript"; +static const char T_application_json[] PROGMEM = "application/json"; +static const char T_application_pdf[] PROGMEM = "application/pdf"; +static const char T_application_x_gzip[] PROGMEM = "application/x-gzip"; +static const char T_application_zip[] PROGMEM = "application/zip"; +static const char T_font_eot[] PROGMEM = "font/eot"; +static const char T_font_ttf[] PROGMEM = "font/ttf"; +static const char T_font_woff[] PROGMEM = "font/woff"; +static const char T_font_woff2[] PROGMEM = "font/woff2"; +static const char T_image_gif[] PROGMEM = "image/gif"; +static const char T_image_jpeg[] PROGMEM = "image/jpeg"; +static const char T_image_png[] PROGMEM = "image/png"; +static const char T_image_svg_xml[] PROGMEM = "image/svg+xml"; +static const char T_image_x_icon[] PROGMEM = "image/x-icon"; +static const char T_text_css[] PROGMEM = "text/css"; +static const char T_text_event_stream[] PROGMEM = "text/event-stream"; +static const char T_text_html[] PROGMEM = "text/html"; +static const char T_text_plain[] PROGMEM = "text/plain"; +static const char T_text_xml[] PROGMEM = "text/xml"; + +// Responce codes +static const char T_HTTP_CODE_100[] PROGMEM = "Continue"; +static const char T_HTTP_CODE_101[] PROGMEM = "Switching Protocols"; +static const char T_HTTP_CODE_200[] PROGMEM = "OK"; +static const char T_HTTP_CODE_201[] PROGMEM = "Created"; +static const char T_HTTP_CODE_202[] PROGMEM = "Accepted"; +static const char T_HTTP_CODE_203[] PROGMEM = "Non-Authoritative Information"; +static const char T_HTTP_CODE_204[] PROGMEM = "No Content"; +static const char T_HTTP_CODE_205[] PROGMEM = "Reset Content"; +static const char T_HTTP_CODE_206[] PROGMEM = "Partial Content"; +static const char T_HTTP_CODE_300[] PROGMEM = "Multiple Choices"; +static const char T_HTTP_CODE_301[] PROGMEM = "Moved Permanently"; +static const char T_HTTP_CODE_302[] PROGMEM = "Found"; +static const char T_HTTP_CODE_303[] PROGMEM = "See Other"; +static const char T_HTTP_CODE_304[] PROGMEM = "Not Modified"; +static const char T_HTTP_CODE_305[] PROGMEM = "Use Proxy"; +static const char T_HTTP_CODE_307[] PROGMEM = "Temporary Redirect"; +static const char T_HTTP_CODE_400[] PROGMEM = "Bad Request"; +static const char T_HTTP_CODE_401[] PROGMEM = "Unauthorized"; +static const char T_HTTP_CODE_402[] PROGMEM = "Payment Required"; +static const char T_HTTP_CODE_403[] PROGMEM = "Forbidden"; +static const char T_HTTP_CODE_404[] PROGMEM = "Not Found"; +static const char T_HTTP_CODE_405[] PROGMEM = "Method Not Allowed"; +static const char T_HTTP_CODE_406[] PROGMEM = "Not Acceptable"; +static const char T_HTTP_CODE_407[] PROGMEM = "Proxy Authentication Required"; +static const char T_HTTP_CODE_408[] PROGMEM = "Request Time-out"; +static const char T_HTTP_CODE_409[] PROGMEM = "Conflict"; +static const char T_HTTP_CODE_410[] PROGMEM = "Gone"; +static const char T_HTTP_CODE_411[] PROGMEM = "Length Required"; +static const char T_HTTP_CODE_412[] PROGMEM = "Precondition Failed"; +static const char T_HTTP_CODE_413[] PROGMEM = "Request Entity Too Large"; +static const char T_HTTP_CODE_414[] PROGMEM = "Request-URI Too Large"; +static const char T_HTTP_CODE_415[] PROGMEM = "Unsupported Media Type"; +static const char T_HTTP_CODE_416[] PROGMEM = "Requested range not satisfiable"; +static const char T_HTTP_CODE_417[] PROGMEM = "Expectation Failed"; +static const char T_HTTP_CODE_500[] PROGMEM = "Internal Server Error"; +static const char T_HTTP_CODE_501[] PROGMEM = "Not Implemented"; +static const char T_HTTP_CODE_502[] PROGMEM = "Bad Gateway"; +static const char T_HTTP_CODE_503[] PROGMEM = "Service Unavailable"; +static const char T_HTTP_CODE_504[] PROGMEM = "Gateway Time-out"; +static const char T_HTTP_CODE_505[] PROGMEM = "HTTP Version not supported"; +static const char T_HTTP_CODE_ANY[] PROGMEM = "Unknown code"; + +// other +static const char T__opaque[] PROGMEM = "\", opaque=\""; +static const char T_13[] PROGMEM = "13"; +static const char T_asyncesp[] PROGMEM = "asyncesp"; +static const char T_auth_nonce[] PROGMEM = "\", qop=\"auth\", nonce=\""; +static const char T_cnonce[] PROGMEM = "cnonce"; +static const char T_data_[] PROGMEM = "data: "; +static const char T_event_[] PROGMEM = "event: "; +static const char T_filename[] PROGMEM = "filename"; +static const char T_gzip[] PROGMEM = "gzip"; +static const char T_Host[] PROGMEM = "Host"; +static const char T_id__[] PROGMEM = "id: "; +static const char T_name[] PROGMEM = "name"; +static const char T_nc[] PROGMEM = "nc"; +static const char T_nonce[] PROGMEM = "nonce"; +static const char T_opaque[] PROGMEM = "opaque"; +static const char T_qop[] PROGMEM = "qop"; +static const char T_realm[] PROGMEM = "realm"; +static const char T_realm__[] PROGMEM = "realm=\""; +static const char T_response[] PROGMEM = "response"; +static const char T_retry_[] PROGMEM = "retry: "; +static const char T_rn[] PROGMEM = "\r\n"; +static const char T_rnrn[] PROGMEM = "\r\n\r\n"; +static const char T_uri[] PROGMEM = "uri"; +static const char T_username[] PROGMEM = "username"; + +#endif // ESP8622 From d82039352af461327f8c6f2ec5e8929208966853 Mon Sep 17 00:00:00 2001 From: Emil Muratov Date: Tue, 2 Jul 2024 12:20:00 +0900 Subject: [PATCH 279/551] segregate 8266 FPSTR's --- src/WebRequest.cpp | 88 +++++++++++++++++++++++----------------- src/WebResponses.cpp | 95 +++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 141 insertions(+), 42 deletions(-) diff --git a/src/WebRequest.cpp b/src/WebRequest.cpp index a1e758ebb..b1d4c276f 100644 --- a/src/WebRequest.cpp +++ b/src/WebRequest.cpp @@ -279,29 +279,6 @@ bool AsyncWebServerRequest::_parseReqHead() { return true; } -bool strContains(const String& src, const String& find, bool mindcase = true) { - int pos = 0, i = 0; - const int slen = src.length(); - const int flen = find.length(); - - if (slen < flen) - return false; - while (pos <= (slen - flen)) { - for (i = 0; i < flen; i++) { - if (mindcase) { - if (src[pos + i] != find[i]) - i = flen + 1; // no match - } else if (tolower(src[pos + i]) != tolower(find[i])) { - i = flen + 1; // no match - } - } - if (i == flen) - return true; - pos++; - } - return false; -} - bool AsyncWebServerRequest::_parseReqHeader() { int index = _temp.indexOf(':'); if (index) { @@ -331,8 +308,15 @@ bool AsyncWebServerRequest::_parseReqHeader() { if (name.equalsIgnoreCase(T_UPGRADE) && value.equalsIgnoreCase(T_WS)) { // WebSocket request can be uniquely identified by header: [Upgrade: websocket] _reqconntype = RCT_WS; - } else { - if (name.equalsIgnoreCase(T_ACCEPT) && strContains(value, F(T_text_event_stream), false)) { + } else if (name.equalsIgnoreCase(T_ACCEPT)){ + String lowcase(value); + lowcase.toLowerCase(); +#ifndef ESP8266 + const char* substr = std::strstr(lowcase.c_str(), T_text_event_stream); +#else + const char* substr = std::strstr(lowcase.c_str(), String(T_text_event_stream).c_str()); +#endif + if (substr != NULL) { // WebEvent request can be uniquely identified by header: [Accept: text/event-stream] _reqconntype = RCT_EVENT; } @@ -340,7 +324,7 @@ bool AsyncWebServerRequest::_parseReqHeader() { } _headers.emplace_back(name, value); } - _temp = String(); + _temp.clear(); return true; } @@ -940,11 +924,7 @@ String AsyncWebServerRequest::urlDecode(const String& text) const { } #ifndef ESP8266 -const char* AsyncWebServerRequest::methodToString() const -#else -const __FlashStringHelper* AsyncWebServerRequest::methodToString() const -#endif -{ +const char* AsyncWebServerRequest::methodToString() const { if (_method == HTTP_ANY) return T_ANY; if (_method & HTTP_GET) @@ -963,14 +943,30 @@ const __FlashStringHelper* AsyncWebServerRequest::methodToString() const return T_OPTIONS; return T_UNKNOWN; } +#else // ESP8266 +const __FlashStringHelper* AsyncWebServerRequest::methodToString() const { + if (_method == HTTP_ANY) + return FPSTR(T_ANY); + if (_method & HTTP_GET) + return FPSTR(T_GET); + if (_method & HTTP_POST) + return FPSTR(T_POST); + if (_method & HTTP_DELETE) + return FPSTR(T_DELETE); + if (_method & HTTP_PUT) + return FPSTR(T_PUT); + if (_method & HTTP_PATCH) + return FPSTR(T_PATCH); + if (_method & HTTP_HEAD) + return FPSTR(T_HEAD); + if (_method & HTTP_OPTIONS) + return FPSTR(T_OPTIONS); + return FPSTR(T_UNKNOWN); +} +#endif // ESP8266 #ifndef ESP8266 -const char* AsyncWebServerRequest::requestedConnTypeToString() const -#else -const __FlashStringHelper* AsyncWebServerRequest::requestedConnTypeToString() const -#endif -{ - +const char* AsyncWebServerRequest::requestedConnTypeToString() const { switch (_reqconntype) { case RCT_NOT_USED: return T_RCT_NOT_USED; @@ -986,6 +982,24 @@ const __FlashStringHelper* AsyncWebServerRequest::requestedConnTypeToString() co return T_ERROR; } } +#else // ESP8266 +const __FlashStringHelper* AsyncWebServerRequest::requestedConnTypeToString() const { + switch (_reqconntype) { + case RCT_NOT_USED: + return FPSTR(T_RCT_NOT_USED); + case RCT_DEFAULT: + return FPSTR(T_RCT_DEFAULT); + case RCT_HTTP: + return FPSTR(T_RCT_HTTP); + case RCT_WS: + return FPSTR(T_RCT_WS); + case RCT_EVENT: + return FPSTR(T_RCT_EVENT); + default: + return FPSTR(T_ERROR); + } +} +#endif // ESP8266 bool AsyncWebServerRequest::isExpectedRequestedConnType(RequestedConnectionType erct1, RequestedConnectionType erct2, RequestedConnectionType erct3) { bool res = false; diff --git a/src/WebResponses.cpp b/src/WebResponses.cpp index c21a97118..fa1067e4a 100644 --- a/src/WebResponses.cpp +++ b/src/WebResponses.cpp @@ -37,11 +37,7 @@ void* memchr(void* ptr, int ch, size_t count) { */ #ifndef ESP8266 -const char* AsyncWebServerResponse::responseCodeToString(int code) -#else -const __FlashStringHelper* AsyncWebServerResponse::responseCodeToString(int code) -#endif -{ +const char* AsyncWebServerResponse::responseCodeToString(int code) { switch (code) { case 100: return T_HTTP_CODE_100; @@ -127,6 +123,95 @@ const __FlashStringHelper* AsyncWebServerResponse::responseCodeToString(int code return T_HTTP_CODE_ANY; } } +#else // ESP8266 +const __FlashStringHelper* AsyncWebServerResponse::responseCodeToString(int code) +{ + switch (code) { + case 100: + return FPSTR(T_HTTP_CODE_100); + case 101: + return FPSTR(T_HTTP_CODE_101); + case 200: + return FPSTR(T_HTTP_CODE_200); + case 201: + return FPSTR(T_HTTP_CODE_201); + case 202: + return FPSTR(T_HTTP_CODE_202); + case 203: + return FPSTR(T_HTTP_CODE_203); + case 204: + return FPSTR(T_HTTP_CODE_204); + case 205: + return FPSTR(T_HTTP_CODE_205); + case 206: + return FPSTR(T_HTTP_CODE_206); + case 300: + return FPSTR(T_HTTP_CODE_300); + case 301: + return FPSTR(T_HTTP_CODE_301); + case 302: + return FPSTR(T_HTTP_CODE_302); + case 303: + return FPSTR(T_HTTP_CODE_303); + case 304: + return FPSTR(T_HTTP_CODE_304); + case 305: + return FPSTR(T_HTTP_CODE_305); + case 307: + return FPSTR(T_HTTP_CODE_307); + case 400: + return FPSTR(T_HTTP_CODE_400); + case 401: + return FPSTR(T_HTTP_CODE_401); + case 402: + return FPSTR(T_HTTP_CODE_402); + case 403: + return FPSTR(T_HTTP_CODE_403); + case 404: + return FPSTR(T_HTTP_CODE_404); + case 405: + return FPSTR(T_HTTP_CODE_405); + case 406: + return FPSTR(T_HTTP_CODE_406); + case 407: + return FPSTR(T_HTTP_CODE_407); + case 408: + return FPSTR(T_HTTP_CODE_408); + case 409: + return FPSTR(T_HTTP_CODE_409); + case 410: + return FPSTR(T_HTTP_CODE_410); + case 411: + return FPSTR(T_HTTP_CODE_411); + case 412: + return FPSTR(T_HTTP_CODE_412); + case 413: + return FPSTR(T_HTTP_CODE_413); + case 414: + return FPSTR(T_HTTP_CODE_414); + case 415: + return FPSTR(T_HTTP_CODE_415); + case 416: + return FPSTR(T_HTTP_CODE_416); + case 417: + return FPSTR(T_HTTP_CODE_417); + case 500: + return FPSTR(T_HTTP_CODE_500); + case 501: + return FPSTR(T_HTTP_CODE_501); + case 502: + return FPSTR(T_HTTP_CODE_502); + case 503: + return FPSTR(T_HTTP_CODE_503); + case 504: + return FPSTR(T_HTTP_CODE_504); + case 505: + return FPSTR(T_HTTP_CODE_505); + default: + return FPSTR(T_HTTP_CODE_ANY); + } +} +#endif // ESP8266 AsyncWebServerResponse::AsyncWebServerResponse() : _code(0), _contentType(), _contentLength(0), _sendContentLength(true), _chunked(false), _headLength(0), _sentLength(0), _ackedLength(0), _writtenLength(0), _state(RESPONSE_SETUP) { From 5a6556317c91d70efa7fb8190ac1d7da8fed1a9b Mon Sep 17 00:00:00 2001 From: Emil Muratov Date: Tue, 2 Jul 2024 12:35:58 +0900 Subject: [PATCH 280/551] add include --- src/WebRequest.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/WebRequest.cpp b/src/WebRequest.cpp index b1d4c276f..28ba48395 100644 --- a/src/WebRequest.cpp +++ b/src/WebRequest.cpp @@ -22,10 +22,7 @@ #include "WebAuthentication.h" #include "WebResponseImpl.h" #include "literals.h" - -#ifndef ESP8266 - #define os_strlen strlen -#endif +#include #define __is_param_char(c) ((c) && ((c) != '{') && ((c) != '[') && ((c) != '&') && ((c) != '=')) From 4240b337d50a09dd7e7b432253cfb27570d08caf Mon Sep 17 00:00:00 2001 From: Emil Muratov Date: Tue, 2 Jul 2024 14:18:51 +0900 Subject: [PATCH 281/551] replace String::clear() with copy contructor for PRI --- src/WebRequest.cpp | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/WebRequest.cpp b/src/WebRequest.cpp index 28ba48395..181f177d3 100644 --- a/src/WebRequest.cpp +++ b/src/WebRequest.cpp @@ -321,7 +321,12 @@ bool AsyncWebServerRequest::_parseReqHeader() { } _headers.emplace_back(name, value); } +#ifndef TARGET_RP2040 _temp.clear(); +#else + // Ancient PRI core does not have String::clear() method 8-() + _temp = String(); +#endif return true; } @@ -336,7 +341,13 @@ void AsyncWebServerRequest::_parsePlainPostChar(uint8_t data) { value = _temp.substring(_temp.indexOf('=') + 1); } _params.emplace_back(urlDecode(name), urlDecode(value), true); - _temp = String(); + +#ifndef TARGET_RP2040 + _temp.clear(); +#else + // Ancient PRI core does not have String::clear() method 8-() + _temp = String(); +#endif } } From e4d9cf2d3f5adf0d36b47a9d587db5f66cb06e5e Mon Sep 17 00:00:00 2001 From: Emil Muratov Date: Tue, 2 Jul 2024 21:49:18 +0900 Subject: [PATCH 282/551] minor fixes in ESP32/ESP8266 code diffs --- src/AsyncWebSocket.cpp | 6 ++++-- src/AsyncWebSocket.h | 16 ++++++++-------- src/ESPAsyncWebServer.h | 4 +++- src/WebRequest.cpp | 4 ---- src/WebResponses.cpp | 6 +++++- 5 files changed, 20 insertions(+), 16 deletions(-) diff --git a/src/AsyncWebSocket.cpp b/src/AsyncWebSocket.cpp index fa7c22dda..2d171138a 100644 --- a/src/AsyncWebSocket.cpp +++ b/src/AsyncWebSocket.cpp @@ -838,7 +838,8 @@ void AsyncWebSocket::text(uint32_t id, const char* message) { void AsyncWebSocket::text(uint32_t id, const String& message) { text(id, message.c_str(), message.length()); } -#ifndef ESP32 + +#ifndef ESP8266 void AsyncWebSocket::text(uint32_t id, const __FlashStringHelper* data) { PGM_P p = reinterpret_cast(data); @@ -857,7 +858,8 @@ void AsyncWebSocket::text(uint32_t id, const __FlashStringHelper* data) { free(message); } } -#endif // ESP32 +#endif // ESP8266 + void AsyncWebSocket::text(uint32_t id, AsyncWebSocketMessageBuffer* buffer) { if (buffer) { text(id, std::move(buffer->_buffer)); diff --git a/src/AsyncWebSocket.h b/src/AsyncWebSocket.h index 77bf7ee7e..f4685d187 100644 --- a/src/AsyncWebSocket.h +++ b/src/AsyncWebSocket.h @@ -306,19 +306,19 @@ class AsyncWebSocket : public AsyncWebHandler { void text(uint32_t id, const char* message, size_t len); void text(uint32_t id, const char* message); void text(uint32_t id, const String& message); -#ifndef ESP32 - void text(uint32_t id, const __FlashStringHelper* message); -#endif // ESP32 void text(uint32_t id, AsyncWebSocketMessageBuffer* buffer); void text(uint32_t id, AsyncWebSocketSharedBuffer buffer); +#ifdef ESP8266 + void text(uint32_t id, const __FlashStringHelper* message); +#endif // ESP8266 void textAll(const uint8_t* message, size_t len); void textAll(const char* message, size_t len); void textAll(const char* message); void textAll(const String& message); -#ifndef ESP32 +#ifdef ESP8266 void textAll(const __FlashStringHelper* message); -#endif // ESP32 +#endif // ESP8266 void textAll(AsyncWebSocketMessageBuffer* buffer); void textAll(AsyncWebSocketSharedBuffer buffer); @@ -326,9 +326,9 @@ class AsyncWebSocket : public AsyncWebHandler { void binary(uint32_t id, const char* message, size_t len); void binary(uint32_t id, const char* message); void binary(uint32_t id, const String& message); -#ifndef ESP32 +#ifdef ESP8266 void binary(uint32_t id, const __FlashStringHelper* message, size_t len); -#endif // ESP32 +#endif // ESP8266 void binary(uint32_t id, AsyncWebSocketMessageBuffer* buffer); void binary(uint32_t id, AsyncWebSocketSharedBuffer buffer); @@ -345,7 +345,7 @@ class AsyncWebSocket : public AsyncWebHandler { size_t printf(uint32_t id, const char* format, ...) __attribute__((format(printf, 3, 4))); size_t printfAll(const char* format, ...) __attribute__((format(printf, 2, 3))); -#ifndef ESP32 +#ifdef ESP8266 size_t printf_P(uint32_t id, PGM_P formatP, ...) __attribute__((format(printf, 3, 4))); size_t printfAll_P(PGM_P formatP, ...) __attribute__((format(printf, 2, 3))); #endif diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index ef94ab30f..ec5311cf7 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -349,7 +349,9 @@ class AsyncWebServerRequest { size_t params() const; // get arguments count bool hasParam(const String& name, bool post = false, bool file = false) const; - bool hasParam(const __FlashStringHelper* data, bool post = false, bool file = false) const; +#ifdef ESP8266 + bool hasParam(const __FlashStringHelper* data, bool post = false, bool file = false) const { return hasParam(String(data).c_str(), post, file); }; +#endif /** * @brief Get the Request parameter by name diff --git a/src/WebRequest.cpp b/src/WebRequest.cpp index 181f177d3..92920009f 100644 --- a/src/WebRequest.cpp +++ b/src/WebRequest.cpp @@ -661,10 +661,6 @@ bool AsyncWebServerRequest::hasParam(const String& name, bool post, bool file) c return false; } -bool AsyncWebServerRequest::hasParam(const __FlashStringHelper* data, bool post, bool file) const { - return hasParam(String(data).c_str(), post, file); -} - const AsyncWebParameter* AsyncWebServerRequest::getParam(const char* name, bool post, bool file) const { for (const auto& p : _params) { if (p.name() == name && p.isPost() == post && p.isFile() == file) { diff --git a/src/WebResponses.cpp b/src/WebResponses.cpp index fa1067e4a..a06ae7816 100644 --- a/src/WebResponses.cpp +++ b/src/WebResponses.cpp @@ -607,7 +607,11 @@ AsyncFileResponse::~AsyncFileResponse() { void AsyncFileResponse::_setContentType(const String& path) { #if HAVE_EXTERN_GET_Content_Type_FUNCTION - extern const __FlashStringHelper* getContentType(const String& path); + #ifndef ESP8266 + extern const char* getContentType(const String& path); + #else + extern const __FlashStringHelper* getContentType(const String& path); + #endif _contentType = getContentType(path); #else if (path.endsWith(T__html)) From c004ca8cd36fdbc456fc7414214e9402e967544f Mon Sep 17 00:00:00 2001 From: Emil Muratov Date: Tue, 2 Jul 2024 22:23:41 +0900 Subject: [PATCH 283/551] minor fixes in ESP32/ESP8266 code diffs --- src/AsyncWebSocket.cpp | 29 +++++++++++++++++------------ src/AsyncWebSocket.h | 4 ++-- 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/src/AsyncWebSocket.cpp b/src/AsyncWebSocket.cpp index 2d171138a..fab986fe2 100644 --- a/src/AsyncWebSocket.cpp +++ b/src/AsyncWebSocket.cpp @@ -613,7 +613,7 @@ size_t AsyncWebSocketClient::printf(const char* format, ...) { return len; } -#ifndef ESP32 +#ifdef ESP8266 size_t AsyncWebSocketClient::printf_P(PGM_P formatP, ...) { va_list arg; va_start(arg, formatP); @@ -680,7 +680,7 @@ void AsyncWebSocketClient::text(const String& message) { text(message.c_str(), message.length()); } -#ifndef ESP32 +#ifdef ESP8266 void AsyncWebSocketClient::text(const __FlashStringHelper* data) { PGM_P p = reinterpret_cast(data); @@ -699,7 +699,7 @@ void AsyncWebSocketClient::text(const __FlashStringHelper* data) { free(message); } } -#endif // ESP32 +#endif // ESP8266 void AsyncWebSocketClient::binary(AsyncWebSocketMessageBuffer* buffer) { if (buffer) { @@ -728,7 +728,7 @@ void AsyncWebSocketClient::binary(const String& message) { binary(message.c_str(), message.length()); } -#ifndef ESP32 +#ifdef ESP8266 void AsyncWebSocketClient::binary(const __FlashStringHelper* data, size_t len) { PGM_P p = reinterpret_cast(data); char* message = (char*)malloc(len); @@ -739,6 +739,7 @@ void AsyncWebSocketClient::binary(const __FlashStringHelper* data, size_t len) { } } #endif + IPAddress AsyncWebSocketClient::remoteIP() const { if (!_client) return IPAddress((uint32_t)0U); @@ -839,7 +840,7 @@ void AsyncWebSocket::text(uint32_t id, const String& message) { text(id, message.c_str(), message.length()); } -#ifndef ESP8266 +#ifdef ESP8266 void AsyncWebSocket::text(uint32_t id, const __FlashStringHelper* data) { PGM_P p = reinterpret_cast(data); @@ -883,7 +884,7 @@ void AsyncWebSocket::textAll(const char* message) { void AsyncWebSocket::textAll(const String& message) { textAll(message.c_str(), message.length()); } -#ifndef ESP32 +#ifdef ESP8266 void AsyncWebSocket::textAll(const __FlashStringHelper* data) { PGM_P p = reinterpret_cast(data); @@ -902,7 +903,7 @@ void AsyncWebSocket::textAll(const __FlashStringHelper* data) { free(message); } } -#endif // ESP32 +#endif // ESP8266 void AsyncWebSocket::textAll(AsyncWebSocketMessageBuffer* buffer) { if (buffer) { textAll(std::move(buffer->_buffer)); @@ -929,7 +930,8 @@ void AsyncWebSocket::binary(uint32_t id, const char* message) { void AsyncWebSocket::binary(uint32_t id, const String& message) { binary(id, message.c_str(), message.length()); } -#ifndef ESP32 + +#ifdef ESP8266 void AsyncWebSocket::binary(uint32_t id, const __FlashStringHelper* data, size_t len) { PGM_P p = reinterpret_cast(data); char* message = (char*)malloc(len); @@ -939,7 +941,8 @@ void AsyncWebSocket::binary(uint32_t id, const __FlashStringHelper* data, size_t free(message); } } -#endif // ESP32 +#endif // ESP8266 + void AsyncWebSocket::binary(uint32_t id, AsyncWebSocketMessageBuffer* buffer) { if (buffer) { binary(id, std::move(buffer->_buffer)); @@ -963,7 +966,8 @@ void AsyncWebSocket::binaryAll(const char* message) { void AsyncWebSocket::binaryAll(const String& message) { binaryAll(message.c_str(), message.length()); } -#ifndef ESP32 + +#ifdef ESP8266 void AsyncWebSocket::binaryAll(const __FlashStringHelper* data, size_t len) { PGM_P p = reinterpret_cast(data); char* message = (char*)malloc(len); @@ -973,7 +977,8 @@ void AsyncWebSocket::binaryAll(const __FlashStringHelper* data, size_t len) { free(message); } } -#endif // ESP32 +#endif // ESP8266 + void AsyncWebSocket::binaryAll(AsyncWebSocketMessageBuffer* buffer) { if (buffer) { binaryAll(std::move(buffer->_buffer)); @@ -1019,7 +1024,7 @@ size_t AsyncWebSocket::printfAll(const char* format, ...) { return len; } -#ifndef ESP32 +#ifdef ESP8266 size_t AsyncWebSocket::printf_P(uint32_t id, PGM_P formatP, ...) { AsyncWebSocketClient* c = client(id); if (c != NULL) { diff --git a/src/AsyncWebSocket.h b/src/AsyncWebSocket.h index f4685d187..ee7bde199 100644 --- a/src/AsyncWebSocket.h +++ b/src/AsyncWebSocket.h @@ -336,9 +336,9 @@ class AsyncWebSocket : public AsyncWebHandler { void binaryAll(const char* message, size_t len); void binaryAll(const char* message); void binaryAll(const String& message); -#ifndef ESP32 +#ifdef ESP8266 void binaryAll(const __FlashStringHelper* message, size_t len); -#endif // ESP32 +#endif // ESP8266 void binaryAll(AsyncWebSocketMessageBuffer* buffer); void binaryAll(AsyncWebSocketSharedBuffer buffer); From bc8cadbcb4f0883c21a92acd6f564582eaea2201 Mon Sep 17 00:00:00 2001 From: Emil Muratov Date: Thu, 4 Jul 2024 11:45:31 +0900 Subject: [PATCH 284/551] wrap string literals in namespace --- src/AsyncEventSource.cpp | 2 ++ src/AsyncWebSocket.cpp | 3 +++ src/ESPAsyncWebServer.h | 2 +- src/WebAuthentication.cpp | 2 ++ src/WebHandlers.cpp | 3 +++ src/WebRequest.cpp | 2 ++ src/WebResponses.cpp | 2 ++ src/WebServer.cpp | 2 ++ src/literals.h | 3 +++ 9 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/AsyncEventSource.cpp b/src/AsyncEventSource.cpp index 66daa77ac..639fd56d0 100644 --- a/src/AsyncEventSource.cpp +++ b/src/AsyncEventSource.cpp @@ -24,6 +24,8 @@ #include "AsyncEventSource.h" #include "literals.h" +using namespace asyncsrv; + static String generateEventMessage(const char* message, const char* event, uint32_t id, uint32_t reconnect) { String ev; diff --git a/src/AsyncWebSocket.cpp b/src/AsyncWebSocket.cpp index fab986fe2..88d88ec85 100644 --- a/src/AsyncWebSocket.cpp +++ b/src/AsyncWebSocket.cpp @@ -38,6 +38,9 @@ #define MAX_PRINTF_LEN 64 +using namespace asyncsrv; + + size_t webSocketSendFrameWindow(AsyncClient* client) { if (!client->canSend()) return 0; diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index ec5311cf7..8499c5090 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -153,7 +153,7 @@ class AsyncWebHeader { const String& name() const { return _name; } const String& value() const { return _value; } - String toString() const { return _name + (char)0x3a + (char)0x20 /*": "*/ + _value + T_rn; } + String toString() const { return _name + (char)0x3a + (char)0x20 /*": "*/ + _value + asyncsrv::T_rn; } }; /* diff --git a/src/WebAuthentication.cpp b/src/WebAuthentication.cpp index 14a772902..b5962fce2 100644 --- a/src/WebAuthentication.cpp +++ b/src/WebAuthentication.cpp @@ -27,6 +27,8 @@ #endif #include "literals.h" +using namespace asyncsrv; + // Basic Auth hash = base64("username:password") bool checkBasicAuthentication(const char* hash, const char* username, const char* password) { diff --git a/src/WebHandlers.cpp b/src/WebHandlers.cpp index 41399b89d..580cebab3 100644 --- a/src/WebHandlers.cpp +++ b/src/WebHandlers.cpp @@ -21,6 +21,9 @@ #include "ESPAsyncWebServer.h" #include "WebHandlerImpl.h" +using namespace asyncsrv; + + AsyncStaticWebHandler::AsyncStaticWebHandler(const char* uri, FS& fs, const char* path, const char* cache_control) : _fs(fs), _uri(uri), _path(path), _default_file(F("index.htm")), _cache_control(cache_control), _last_modified(), _callback(nullptr) { // Ensure leading '/' diff --git a/src/WebRequest.cpp b/src/WebRequest.cpp index 92920009f..f0d6bdf8a 100644 --- a/src/WebRequest.cpp +++ b/src/WebRequest.cpp @@ -26,6 +26,8 @@ #define __is_param_char(c) ((c) && ((c) != '{') && ((c) != '[') && ((c) != '&') && ((c) != '=')) +using namespace asyncsrv; + enum { PARSE_REQ_START, PARSE_REQ_HEADERS, PARSE_REQ_BODY, diff --git a/src/WebResponses.cpp b/src/WebResponses.cpp index a06ae7816..86aa9479b 100644 --- a/src/WebResponses.cpp +++ b/src/WebResponses.cpp @@ -22,6 +22,8 @@ #include "WebResponseImpl.h" #include "cbuf.h" +using namespace asyncsrv; + // Since ESP8266 does not link memchr by default, here's its implementation. void* memchr(void* ptr, int ch, size_t count) { unsigned char* p = static_cast(ptr); diff --git a/src/WebServer.cpp b/src/WebServer.cpp index bc48b460e..0e29a549a 100644 --- a/src/WebServer.cpp +++ b/src/WebServer.cpp @@ -21,6 +21,8 @@ #include "ESPAsyncWebServer.h" #include "WebHandlerImpl.h" +using namespace asyncsrv; + bool ON_STA_FILTER(AsyncWebServerRequest* request) { return WiFi.localIP() == request->client()->localIP(); } diff --git a/src/literals.h b/src/literals.h index 50bd03aa0..145d69bed 100644 --- a/src/literals.h +++ b/src/literals.h @@ -1,5 +1,6 @@ #pragma once +namespace asyncsrv { #ifndef ESP8622 static constexpr const char* T_100_CONTINUE = "100-continue"; @@ -336,3 +337,5 @@ static const char T_uri[] PROGMEM = "uri"; static const char T_username[] PROGMEM = "username"; #endif // ESP8622 + +} // namespace asyncsrv {} From 43981c160abd80a45e695d81ac414d6f71ef9442 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Tue, 16 Jul 2024 23:04:04 +0200 Subject: [PATCH 285/551] mathieucarbou/AsyncTCP @ 3.2.1 --- .github/workflows/ci.yml | 2 +- README.md | 4 ++-- docs/index.md | 4 ++-- library.json | 4 ++-- platformio.ini | 6 +++--- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9b477bd94..a9fbc0ad6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -52,7 +52,7 @@ jobs: - name: Install AsyncTCP (ESP32) if: ${{ matrix.core == 'esp32:esp32' }} - run: ARDUINO_LIBRARY_ENABLE_UNSAFE_INSTALL=true arduino-cli lib install --git-url https://github.com/mathieucarbou/AsyncTCP#v3.1.4 + run: ARDUINO_LIBRARY_ENABLE_UNSAFE_INSTALL=true arduino-cli lib install --git-url https://github.com/mathieucarbou/AsyncTCP#v3.2.1 - name: Install ESPAsyncTCP (ESP8266) if: ${{ matrix.core == 'esp8266:esp8266' }} diff --git a/README.md b/README.md index b14d36ceb..8a663284d 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo - [@mathieucarbou](https://github.com/mathieucarbou): Arduino 3 / ESP-IDF 5.1 compatibility - [@mathieucarbou](https://github.com/mathieucarbou): Arduino Json 7 compatibility and backward compatible with 6 and 6 (changes in `AsyncJson.h`). The API to use Json has not changed. These are only internal changes. - [@mathieucarbou](https://github.com/mathieucarbou): CI -- [@mathieucarbou](https://github.com/mathieucarbou): Depends on `mathieucarbou/Async TCP @ ^3.1.4` +- [@mathieucarbou](https://github.com/mathieucarbou): Depends on `mathieucarbou/AsyncTCP @ 3.2.1` - [@mathieucarbou](https://github.com/mathieucarbou): Deployed in PlatformIO registry and Arduino IDE library manager - [@mathieucarbou](https://github.com/mathieucarbou): Firmware size optimization: remove mbedtls dependency (accounts for 33KB in firmware) - [@mathieucarbou](https://github.com/mathieucarbou): Made DEFAULT_MAX_SSE_CLIENTS customizable @@ -41,7 +41,7 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo ## Dependencies: -- **ESP32**: `mathieucarbou/Async TCP @ ^3.1.4` (Arduino IDE: [https://github.com/mathieucarbou/AsyncTCP#v3.1.4](https://github.com/mathieucarbou/AsyncTCP/releases/tag/v3.1.4)) +- **ESP32**: `mathieucarbou/AsyncTCP @ 3.2.1` (Arduino IDE: [https://github.com/mathieucarbou/AsyncTCP#v3.2.1](https://github.com/mathieucarbou/AsyncTCP/releases/tag/v3.2.0)) - **ESP8266**: `esphome/ESPAsyncTCP-esphome @ 2.0.0` (Arduino IDE: [https://github.com/mathieucarbou/esphome-ESPAsyncTCP#v2.0.0](https://github.com/mathieucarbou/esphome-ESPAsyncTCP/releases/tag/v2.0.0)) - **RP2040**: `khoih-prog/AsyncTCP_RP2040W @ 1.2.0` (Arduino IDE: [https://github.com/khoih-prog/AsyncTCP_RP2040W#v1.2.0](https://github.com/khoih-prog/AsyncTCP_RP2040W/releases/tag/v1.2.0)) diff --git a/docs/index.md b/docs/index.md index b14d36ceb..8a663284d 100644 --- a/docs/index.md +++ b/docs/index.md @@ -22,7 +22,7 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo - [@mathieucarbou](https://github.com/mathieucarbou): Arduino 3 / ESP-IDF 5.1 compatibility - [@mathieucarbou](https://github.com/mathieucarbou): Arduino Json 7 compatibility and backward compatible with 6 and 6 (changes in `AsyncJson.h`). The API to use Json has not changed. These are only internal changes. - [@mathieucarbou](https://github.com/mathieucarbou): CI -- [@mathieucarbou](https://github.com/mathieucarbou): Depends on `mathieucarbou/Async TCP @ ^3.1.4` +- [@mathieucarbou](https://github.com/mathieucarbou): Depends on `mathieucarbou/AsyncTCP @ 3.2.1` - [@mathieucarbou](https://github.com/mathieucarbou): Deployed in PlatformIO registry and Arduino IDE library manager - [@mathieucarbou](https://github.com/mathieucarbou): Firmware size optimization: remove mbedtls dependency (accounts for 33KB in firmware) - [@mathieucarbou](https://github.com/mathieucarbou): Made DEFAULT_MAX_SSE_CLIENTS customizable @@ -41,7 +41,7 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo ## Dependencies: -- **ESP32**: `mathieucarbou/Async TCP @ ^3.1.4` (Arduino IDE: [https://github.com/mathieucarbou/AsyncTCP#v3.1.4](https://github.com/mathieucarbou/AsyncTCP/releases/tag/v3.1.4)) +- **ESP32**: `mathieucarbou/AsyncTCP @ 3.2.1` (Arduino IDE: [https://github.com/mathieucarbou/AsyncTCP#v3.2.1](https://github.com/mathieucarbou/AsyncTCP/releases/tag/v3.2.0)) - **ESP8266**: `esphome/ESPAsyncTCP-esphome @ 2.0.0` (Arduino IDE: [https://github.com/mathieucarbou/esphome-ESPAsyncTCP#v2.0.0](https://github.com/mathieucarbou/esphome-ESPAsyncTCP/releases/tag/v2.0.0)) - **RP2040**: `khoih-prog/AsyncTCP_RP2040W @ 1.2.0` (Arduino IDE: [https://github.com/khoih-prog/AsyncTCP_RP2040W#v1.2.0](https://github.com/khoih-prog/AsyncTCP_RP2040W/releases/tag/v1.2.0)) diff --git a/library.json b/library.json index 4e089ba81..83ee9c144 100644 --- a/library.json +++ b/library.json @@ -27,8 +27,8 @@ "dependencies": [ { "owner": "mathieucarbou", - "name": "Async TCP", - "version": "^3.1.4", + "name": "AsyncTCP", + "version": "^3.2.1", "platforms": "espressif32" }, { diff --git a/platformio.ini b/platformio.ini index ea7acf29b..9c4027b5f 100644 --- a/platformio.ini +++ b/platformio.ini @@ -27,14 +27,14 @@ platform = espressif32 board = esp32dev lib_deps = bblanchon/ArduinoJson @ 7.1.0 - mathieucarbou/Async TCP @ ^3.1.4 + mathieucarbou/AsyncTCP @ 3.2.1 [env:arduino-2] platform = espressif32@6.7.0 board = esp32dev lib_deps = bblanchon/ArduinoJson @ 7.1.0 - mathieucarbou/Async TCP @ ^3.1.4 + mathieucarbou/AsyncTCP @ 3.2.1 [env:arduino-3] platform = espressif32 @@ -44,7 +44,7 @@ platform_packages= board = esp32dev lib_deps = bblanchon/ArduinoJson @ 7.1.0 - mathieucarbou/Async TCP @ ^3.1.4 + mathieucarbou/AsyncTCP @ 3.2.1 [env:esp8266] platform = espressif8266 From 3f88acef3bb41c22e9aa66f2c5d43ad0184fc449 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Tue, 16 Jul 2024 23:05:37 +0200 Subject: [PATCH 286/551] Name change (removing spaces to match Arduino lib convention) --- README.md | 4 ++-- docs/_config.yml | 2 +- docs/index.md | 4 ++-- library.json | 2 +- library.properties | 2 +- src/ESP_Async_WebServer.h | 2 -- 6 files changed, 7 insertions(+), 9 deletions(-) delete mode 100644 src/ESP_Async_WebServer.h diff --git a/README.md b/README.md index 8a663284d..47fb361f0 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ -# ESP Async WebServer +# ESPAsyncWebServer [![License: LGPL 3.0](https://img.shields.io/badge/License-LGPL%203.0-yellow.svg)](https://opensource.org/license/lgpl-3-0/) [![Continuous Integration](https://github.com/mathieucarbou/ESPAsyncWebServer/actions/workflows/ci.yml/badge.svg)](https://github.com/mathieucarbou/ESPAsyncWebServer/actions/workflows/ci.yml) -[![PlatformIO Registry](https://badges.registry.platformio.org/packages/mathieucarbou/library/ESP%20Async%20WebServer.svg)](https://registry.platformio.org/libraries/mathieucarbou/ESP%20Async%20WebServer) +[![PlatformIO Registry](https://badges.registry.platformio.org/packages/mathieucarbou/library/ESPAsyncWebServer.svg)](https://registry.platformio.org/libraries/mathieucarbou/ESPAsyncWebServer) Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 and RP2040 Supports: WebSocket, SSE, Authentication, Arduino Json 7, File Upload, Static File serving, URL Rewrite, URL Redirect, etc. diff --git a/docs/_config.yml b/docs/_config.yml index e6d54d285..363659743 100644 --- a/docs/_config.yml +++ b/docs/_config.yml @@ -1,6 +1,6 @@ # bundle exec jekyll serve --host=0.0.0.0 -title: ESP Async WebServer +title: ESPAsyncWebServer description: "Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 and RP2040" remote_theme: pages-themes/cayman@v0.2.0 plugins: diff --git a/docs/index.md b/docs/index.md index 8a663284d..47fb361f0 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,8 +1,8 @@ -# ESP Async WebServer +# ESPAsyncWebServer [![License: LGPL 3.0](https://img.shields.io/badge/License-LGPL%203.0-yellow.svg)](https://opensource.org/license/lgpl-3-0/) [![Continuous Integration](https://github.com/mathieucarbou/ESPAsyncWebServer/actions/workflows/ci.yml/badge.svg)](https://github.com/mathieucarbou/ESPAsyncWebServer/actions/workflows/ci.yml) -[![PlatformIO Registry](https://badges.registry.platformio.org/packages/mathieucarbou/library/ESP%20Async%20WebServer.svg)](https://registry.platformio.org/libraries/mathieucarbou/ESP%20Async%20WebServer) +[![PlatformIO Registry](https://badges.registry.platformio.org/packages/mathieucarbou/library/ESPAsyncWebServer.svg)](https://registry.platformio.org/libraries/mathieucarbou/ESPAsyncWebServer) Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 and RP2040 Supports: WebSocket, SSE, Authentication, Arduino Json 7, File Upload, Static File serving, URL Rewrite, URL Redirect, etc. diff --git a/library.json b/library.json index 83ee9c144..3b5a7022e 100644 --- a/library.json +++ b/library.json @@ -1,5 +1,5 @@ { - "name": "ESP Async WebServer", + "name": "ESPAsyncWebServer", "version": "3.0.6", "description": "Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 and RP2040. Supports: WebSocket, SSE, Authentication, Arduino Json 7, File Upload, Static File serving, URL Rewrite, URL Redirect, etc.", "keywords": "http,async,websocket,webserver", diff --git a/library.properties b/library.properties index e0265c367..5d1ff5d13 100644 --- a/library.properties +++ b/library.properties @@ -1,4 +1,4 @@ -name=ESP Async WebServer +name=ESPAsyncWebServer version=3.0.6 author=Me-No-Dev maintainer=Mathieu Carbou diff --git a/src/ESP_Async_WebServer.h b/src/ESP_Async_WebServer.h deleted file mode 100644 index ca6a11262..000000000 --- a/src/ESP_Async_WebServer.h +++ /dev/null @@ -1,2 +0,0 @@ -// to please Arduino Lint -#include "ESPAsyncWebServer.h" From 6b98ada46f1108ec54bc98de38bea69b931295ce Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Tue, 16 Jul 2024 23:07:37 +0200 Subject: [PATCH 287/551] v3.1.0 --- library.json | 2 +- library.properties | 2 +- src/ESPAsyncWebServer.h | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/library.json b/library.json index 3b5a7022e..6ec156be2 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "ESPAsyncWebServer", - "version": "3.0.6", + "version": "3.1.0", "description": "Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 and RP2040. Supports: WebSocket, SSE, Authentication, Arduino Json 7, File Upload, Static File serving, URL Rewrite, URL Redirect, etc.", "keywords": "http,async,websocket,webserver", "homepage": "https://github.com/mathieucarbou/ESPAsyncWebServer", diff --git a/library.properties b/library.properties index 5d1ff5d13..8da8a1489 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=ESPAsyncWebServer -version=3.0.6 +version=3.1.0 author=Me-No-Dev maintainer=Mathieu Carbou sentence=Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 and RP2040 diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index 8499c5090..5731afb25 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -45,10 +45,10 @@ #include "literals.h" -#define ASYNCWEBSERVER_VERSION "3.0.6" +#define ASYNCWEBSERVER_VERSION "3.1.0" #define ASYNCWEBSERVER_VERSION_MAJOR 3 -#define ASYNCWEBSERVER_VERSION_MINOR 0 -#define ASYNCWEBSERVER_VERSION_REVISION 6 +#define ASYNCWEBSERVER_VERSION_MINOR 1 +#define ASYNCWEBSERVER_VERSION_REVISION 0 #define ASYNCWEBSERVER_FORK_mathieucarbou #ifdef ASYNCWEBSERVER_REGEX From bd9e47cbab432351d06d3f5ca7be5f1d36b81aa0 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Wed, 17 Jul 2024 15:23:04 +0200 Subject: [PATCH 288/551] update sample --- examples/issues/Issue14/Issue14.ino | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/examples/issues/Issue14/Issue14.ino b/examples/issues/Issue14/Issue14.ino index d7af52e57..f6a6442c2 100644 --- a/examples/issues/Issue14/Issue14.ino +++ b/examples/issues/Issue14/Issue14.ino @@ -60,7 +60,7 @@ AsyncEventSource events("/events"); unsigned long currentMillis = 0; unsigned long previousMillis = 0; -const uint16_t interval = 1000; +const uint16_t interval = 500; const int button1Pin = 4; bool button1 = false; @@ -102,7 +102,16 @@ void setup() { // WiFi.softAPConfig(local_IP, gateway, subnet); // WiFi.softAP(ssid, password, 11); + WiFi.softAP("esp-captive"); + + // WiFi.mode(WIFI_STA); + // WiFi.begin("IoT"); + // while (WiFi.status() != WL_CONNECTED) { + // delay(1000); + // Serial.println("Connecting to WiFi.."); + // } + // Serial.println(WiFi.localIP()); // WiFi.setTxPower(WIFI_POWER_21dBm); // esp_wifi_set_protocol(WIFI_IF_AP, WIFI_PROTOCOL_11B); From 207cd493914ff775c329264ecc03c1cd188d8742 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Wed, 17 Jul 2024 15:43:05 +0200 Subject: [PATCH 289/551] Arduino 3.0.3 --- platformio.ini | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platformio.ini b/platformio.ini index 9c4027b5f..9ec386f62 100644 --- a/platformio.ini +++ b/platformio.ini @@ -39,8 +39,8 @@ lib_deps = [env:arduino-3] platform = espressif32 platform_packages= - platformio/framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#3.0.2 - platformio/framework-arduinoespressif32-libs @ https://github.com/espressif/arduino-esp32/releases/download/3.0.2/esp32-arduino-libs-3.0.2.zip + platformio/framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#3.0.3 + platformio/framework-arduinoespressif32-libs @ https://github.com/espressif/arduino-esp32/releases/download/3.0.3/esp32-arduino-libs-3.0.3.zip board = esp32dev lib_deps = bblanchon/ArduinoJson @ 7.1.0 From 56abfa52706d64f77950ac56217e5dc658f04525 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Wed, 17 Jul 2024 16:06:23 +0200 Subject: [PATCH 290/551] mathieucarbou/AsyncTCP @ 3.2.2 --- .github/workflows/ci.yml | 2 +- README.md | 4 ++-- docs/index.md | 4 ++-- library.json | 2 +- platformio.ini | 6 +++--- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a9fbc0ad6..238c3c43f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -52,7 +52,7 @@ jobs: - name: Install AsyncTCP (ESP32) if: ${{ matrix.core == 'esp32:esp32' }} - run: ARDUINO_LIBRARY_ENABLE_UNSAFE_INSTALL=true arduino-cli lib install --git-url https://github.com/mathieucarbou/AsyncTCP#v3.2.1 + run: ARDUINO_LIBRARY_ENABLE_UNSAFE_INSTALL=true arduino-cli lib install --git-url https://github.com/mathieucarbou/AsyncTCP#v3.2.2 - name: Install ESPAsyncTCP (ESP8266) if: ${{ matrix.core == 'esp8266:esp8266' }} diff --git a/README.md b/README.md index 47fb361f0..b9a132ee7 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo - [@mathieucarbou](https://github.com/mathieucarbou): Arduino 3 / ESP-IDF 5.1 compatibility - [@mathieucarbou](https://github.com/mathieucarbou): Arduino Json 7 compatibility and backward compatible with 6 and 6 (changes in `AsyncJson.h`). The API to use Json has not changed. These are only internal changes. - [@mathieucarbou](https://github.com/mathieucarbou): CI -- [@mathieucarbou](https://github.com/mathieucarbou): Depends on `mathieucarbou/AsyncTCP @ 3.2.1` +- [@mathieucarbou](https://github.com/mathieucarbou): Depends on `mathieucarbou/AsyncTCP @ 3.2.2` - [@mathieucarbou](https://github.com/mathieucarbou): Deployed in PlatformIO registry and Arduino IDE library manager - [@mathieucarbou](https://github.com/mathieucarbou): Firmware size optimization: remove mbedtls dependency (accounts for 33KB in firmware) - [@mathieucarbou](https://github.com/mathieucarbou): Made DEFAULT_MAX_SSE_CLIENTS customizable @@ -41,7 +41,7 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo ## Dependencies: -- **ESP32**: `mathieucarbou/AsyncTCP @ 3.2.1` (Arduino IDE: [https://github.com/mathieucarbou/AsyncTCP#v3.2.1](https://github.com/mathieucarbou/AsyncTCP/releases/tag/v3.2.0)) +- **ESP32**: `mathieucarbou/AsyncTCP @ 3.2.2` (Arduino IDE: [https://github.com/mathieucarbou/AsyncTCP#v3.2.2](https://github.com/mathieucarbou/AsyncTCP/releases/tag/v3.2.0)) - **ESP8266**: `esphome/ESPAsyncTCP-esphome @ 2.0.0` (Arduino IDE: [https://github.com/mathieucarbou/esphome-ESPAsyncTCP#v2.0.0](https://github.com/mathieucarbou/esphome-ESPAsyncTCP/releases/tag/v2.0.0)) - **RP2040**: `khoih-prog/AsyncTCP_RP2040W @ 1.2.0` (Arduino IDE: [https://github.com/khoih-prog/AsyncTCP_RP2040W#v1.2.0](https://github.com/khoih-prog/AsyncTCP_RP2040W/releases/tag/v1.2.0)) diff --git a/docs/index.md b/docs/index.md index 47fb361f0..b9a132ee7 100644 --- a/docs/index.md +++ b/docs/index.md @@ -22,7 +22,7 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo - [@mathieucarbou](https://github.com/mathieucarbou): Arduino 3 / ESP-IDF 5.1 compatibility - [@mathieucarbou](https://github.com/mathieucarbou): Arduino Json 7 compatibility and backward compatible with 6 and 6 (changes in `AsyncJson.h`). The API to use Json has not changed. These are only internal changes. - [@mathieucarbou](https://github.com/mathieucarbou): CI -- [@mathieucarbou](https://github.com/mathieucarbou): Depends on `mathieucarbou/AsyncTCP @ 3.2.1` +- [@mathieucarbou](https://github.com/mathieucarbou): Depends on `mathieucarbou/AsyncTCP @ 3.2.2` - [@mathieucarbou](https://github.com/mathieucarbou): Deployed in PlatformIO registry and Arduino IDE library manager - [@mathieucarbou](https://github.com/mathieucarbou): Firmware size optimization: remove mbedtls dependency (accounts for 33KB in firmware) - [@mathieucarbou](https://github.com/mathieucarbou): Made DEFAULT_MAX_SSE_CLIENTS customizable @@ -41,7 +41,7 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo ## Dependencies: -- **ESP32**: `mathieucarbou/AsyncTCP @ 3.2.1` (Arduino IDE: [https://github.com/mathieucarbou/AsyncTCP#v3.2.1](https://github.com/mathieucarbou/AsyncTCP/releases/tag/v3.2.0)) +- **ESP32**: `mathieucarbou/AsyncTCP @ 3.2.2` (Arduino IDE: [https://github.com/mathieucarbou/AsyncTCP#v3.2.2](https://github.com/mathieucarbou/AsyncTCP/releases/tag/v3.2.0)) - **ESP8266**: `esphome/ESPAsyncTCP-esphome @ 2.0.0` (Arduino IDE: [https://github.com/mathieucarbou/esphome-ESPAsyncTCP#v2.0.0](https://github.com/mathieucarbou/esphome-ESPAsyncTCP/releases/tag/v2.0.0)) - **RP2040**: `khoih-prog/AsyncTCP_RP2040W @ 1.2.0` (Arduino IDE: [https://github.com/khoih-prog/AsyncTCP_RP2040W#v1.2.0](https://github.com/khoih-prog/AsyncTCP_RP2040W/releases/tag/v1.2.0)) diff --git a/library.json b/library.json index 6ec156be2..e8388a1ae 100644 --- a/library.json +++ b/library.json @@ -28,7 +28,7 @@ { "owner": "mathieucarbou", "name": "AsyncTCP", - "version": "^3.2.1", + "version": "^3.2.2", "platforms": "espressif32" }, { diff --git a/platformio.ini b/platformio.ini index 9ec386f62..c722c1e2e 100644 --- a/platformio.ini +++ b/platformio.ini @@ -27,14 +27,14 @@ platform = espressif32 board = esp32dev lib_deps = bblanchon/ArduinoJson @ 7.1.0 - mathieucarbou/AsyncTCP @ 3.2.1 + mathieucarbou/AsyncTCP @ 3.2.2 [env:arduino-2] platform = espressif32@6.7.0 board = esp32dev lib_deps = bblanchon/ArduinoJson @ 7.1.0 - mathieucarbou/AsyncTCP @ 3.2.1 + mathieucarbou/AsyncTCP @ 3.2.2 [env:arduino-3] platform = espressif32 @@ -44,7 +44,7 @@ platform_packages= board = esp32dev lib_deps = bblanchon/ArduinoJson @ 7.1.0 - mathieucarbou/AsyncTCP @ 3.2.1 + mathieucarbou/AsyncTCP @ 3.2.2 [env:esp8266] platform = espressif8266 From e9c71ad7d80c92f194a70f299df22ab24b351126 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Wed, 17 Jul 2024 19:18:39 +0200 Subject: [PATCH 291/551] example update --- examples/issues/Issue14/Issue14.ino | 124 +++++++++------------------- 1 file changed, 41 insertions(+), 83 deletions(-) diff --git a/examples/issues/Issue14/Issue14.ino b/examples/issues/Issue14/Issue14.ino index f6a6442c2..f62084a6b 100644 --- a/examples/issues/Issue14/Issue14.ino +++ b/examples/issues/Issue14/Issue14.ino @@ -9,128 +9,84 @@ #include #include #endif -#include "ESPAsyncWebServer.h" -#include +#include "ESPAsyncWebServer.h" const char appWebPage[] PROGMEM = R"rawliteral( )rawliteral"; -void sendState(); - -// const char* ssid = "test_esp32"; -// const char* password = "123456789"; - -//========================================================== - -// Настройки IP адреса -// IPAddress local_IP(192, 168, 111, 111); -// IPAddress gateway(192, 168, 111, 1); -// IPAddress subnet(255, 255, 255, 0); - -// AsyncWebServer server(22222); AsyncWebServer server(80); - AsyncEventSource events("/events"); -unsigned long currentMillis = 0; -unsigned long previousMillis = 0; -const uint16_t interval = 500; - +const uint32_t interval = 1000; const int button1Pin = 4; -bool button1 = false; - -char json[512]; -void prepareJson() { - snprintf(json, 511, "{\"button1\":%d,\"1234567890abcdefghij1234567890abcdefghij1234567890abcdefghij1234567890abcdefghij1234567890abcdefghij1234567890abcdefghij\":%ld}", button1, random(0, 999999999)); -} +uint32_t lastSend = 0; -void handleRoot(AsyncWebServerRequest* request) { - request->send(200, "text/html", appWebPage); +void prepareJson(String& buffer) { + buffer.reserve(512); + buffer.concat("{\"button1\":"); + buffer.concat(digitalRead(button1Pin) == LOW); + buffer.concat(",\"1234567890abcdefghij1234567890abcdefghij1234567890abcdefghij1234567890abcdefghij1234567890abcdefghij1234567890abcdefghij\":"); + buffer.concat(random(0, 999999999)); + buffer.concat("}"); } -void button1off() { - button1 = false; - digitalWrite(button1Pin, HIGH); -} - -void button1on() { - digitalWrite(button1Pin, LOW); - button1 = true; -} - -void sendState() { - prepareJson(); - events.send(json, "state", millis()); -} - -//========================================================= void setup() { - Serial.begin(115200); +#if ARDUINO_USB_CDC_ON_BOOT + Serial.setTxTimeoutMs(0); delay(100); +#else + while (!Serial) + yield(); +#endif + randomSeed(micros()); pinMode(button1Pin, OUTPUT); - button1off(); + digitalWrite(button1Pin, HIGH); - // WiFi.softAPConfig(local_IP, gateway, subnet); - // WiFi.softAP(ssid, password, 11); - WiFi.softAP("esp-captive"); - - // WiFi.mode(WIFI_STA); - // WiFi.begin("IoT"); - // while (WiFi.status() != WL_CONNECTED) { - // delay(1000); - // Serial.println("Connecting to WiFi.."); - // } - // Serial.println(WiFi.localIP()); - - // WiFi.setTxPower(WIFI_POWER_21dBm); - // esp_wifi_set_protocol(WIFI_IF_AP, WIFI_PROTOCOL_11B); - server.on("/", HTTP_GET, handleRoot); + server.on("/", HTTP_GET, [](AsyncWebServerRequest* request) { + request->send(200, "text/html", appWebPage); + }); server.on("/button1", HTTP_GET, [](AsyncWebServerRequest* request) { request->send(200, "text/plain", "OK"); - if (button1) { - button1off(); - } else { - button1on(); - } - sendState(); + digitalWrite(button1Pin, digitalRead(button1Pin) == LOW ? HIGH : LOW); + + String buffer; + prepareJson(buffer); + ESP_LOGI("async_tcp", "Sending from handler..."); + events.send(buffer.c_str(), "state", millis()); + ESP_LOGI("async_tcp", "Sent from handler!"); }); events.onConnect([](AsyncEventSourceClient* client) { - prepareJson(); - client->send(json, "state", millis(), 5000); + String buffer; + prepareJson(buffer); + ESP_LOGI("async_tcp", "Sending from onConnect..."); + client->send(buffer.c_str(), "state", millis(), 5000); + ESP_LOGI("async_tcp", "Sent from onConnect!"); }); server.addHandler(&events); @@ -140,10 +96,12 @@ void setup() { } void loop() { - - currentMillis = millis(); - if (currentMillis - previousMillis >= interval) { - previousMillis = currentMillis; - sendState(); + if (millis() - lastSend >= interval) { + String buffer; + prepareJson(buffer); + ESP_LOGI("loop", "Sending..."); + events.send(buffer.c_str(), "state", millis()); + ESP_LOGI("loop", "Sent!"); + lastSend = millis(); } -} \ No newline at end of file +} From dcfcf21bf4f47ada5dd3746381f0479285534ed5 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Wed, 17 Jul 2024 21:54:11 +0200 Subject: [PATCH 292/551] Update dependency --- .github/workflows/ci.yml | 2 +- README.md | 4 ++-- docs/index.md | 4 ++-- library.json | 2 +- platformio.ini | 6 +++--- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 238c3c43f..1090bb8e5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -52,7 +52,7 @@ jobs: - name: Install AsyncTCP (ESP32) if: ${{ matrix.core == 'esp32:esp32' }} - run: ARDUINO_LIBRARY_ENABLE_UNSAFE_INSTALL=true arduino-cli lib install --git-url https://github.com/mathieucarbou/AsyncTCP#v3.2.2 + run: ARDUINO_LIBRARY_ENABLE_UNSAFE_INSTALL=true arduino-cli lib install --git-url https://github.com/mathieucarbou/AsyncTCP#v3.2.3 - name: Install ESPAsyncTCP (ESP8266) if: ${{ matrix.core == 'esp8266:esp8266' }} diff --git a/README.md b/README.md index b9a132ee7..029def86b 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo - [@mathieucarbou](https://github.com/mathieucarbou): Arduino 3 / ESP-IDF 5.1 compatibility - [@mathieucarbou](https://github.com/mathieucarbou): Arduino Json 7 compatibility and backward compatible with 6 and 6 (changes in `AsyncJson.h`). The API to use Json has not changed. These are only internal changes. - [@mathieucarbou](https://github.com/mathieucarbou): CI -- [@mathieucarbou](https://github.com/mathieucarbou): Depends on `mathieucarbou/AsyncTCP @ 3.2.2` +- [@mathieucarbou](https://github.com/mathieucarbou): Depends on `mathieucarbou/AsyncTCP @ 3.2.3` - [@mathieucarbou](https://github.com/mathieucarbou): Deployed in PlatformIO registry and Arduino IDE library manager - [@mathieucarbou](https://github.com/mathieucarbou): Firmware size optimization: remove mbedtls dependency (accounts for 33KB in firmware) - [@mathieucarbou](https://github.com/mathieucarbou): Made DEFAULT_MAX_SSE_CLIENTS customizable @@ -41,7 +41,7 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo ## Dependencies: -- **ESP32**: `mathieucarbou/AsyncTCP @ 3.2.2` (Arduino IDE: [https://github.com/mathieucarbou/AsyncTCP#v3.2.2](https://github.com/mathieucarbou/AsyncTCP/releases/tag/v3.2.0)) +- **ESP32**: `mathieucarbou/AsyncTCP @ 3.2.3` (Arduino IDE: [https://github.com/mathieucarbou/AsyncTCP#v3.2.3](https://github.com/mathieucarbou/AsyncTCP/releases/tag/v3.2.0)) - **ESP8266**: `esphome/ESPAsyncTCP-esphome @ 2.0.0` (Arduino IDE: [https://github.com/mathieucarbou/esphome-ESPAsyncTCP#v2.0.0](https://github.com/mathieucarbou/esphome-ESPAsyncTCP/releases/tag/v2.0.0)) - **RP2040**: `khoih-prog/AsyncTCP_RP2040W @ 1.2.0` (Arduino IDE: [https://github.com/khoih-prog/AsyncTCP_RP2040W#v1.2.0](https://github.com/khoih-prog/AsyncTCP_RP2040W/releases/tag/v1.2.0)) diff --git a/docs/index.md b/docs/index.md index b9a132ee7..029def86b 100644 --- a/docs/index.md +++ b/docs/index.md @@ -22,7 +22,7 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo - [@mathieucarbou](https://github.com/mathieucarbou): Arduino 3 / ESP-IDF 5.1 compatibility - [@mathieucarbou](https://github.com/mathieucarbou): Arduino Json 7 compatibility and backward compatible with 6 and 6 (changes in `AsyncJson.h`). The API to use Json has not changed. These are only internal changes. - [@mathieucarbou](https://github.com/mathieucarbou): CI -- [@mathieucarbou](https://github.com/mathieucarbou): Depends on `mathieucarbou/AsyncTCP @ 3.2.2` +- [@mathieucarbou](https://github.com/mathieucarbou): Depends on `mathieucarbou/AsyncTCP @ 3.2.3` - [@mathieucarbou](https://github.com/mathieucarbou): Deployed in PlatformIO registry and Arduino IDE library manager - [@mathieucarbou](https://github.com/mathieucarbou): Firmware size optimization: remove mbedtls dependency (accounts for 33KB in firmware) - [@mathieucarbou](https://github.com/mathieucarbou): Made DEFAULT_MAX_SSE_CLIENTS customizable @@ -41,7 +41,7 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo ## Dependencies: -- **ESP32**: `mathieucarbou/AsyncTCP @ 3.2.2` (Arduino IDE: [https://github.com/mathieucarbou/AsyncTCP#v3.2.2](https://github.com/mathieucarbou/AsyncTCP/releases/tag/v3.2.0)) +- **ESP32**: `mathieucarbou/AsyncTCP @ 3.2.3` (Arduino IDE: [https://github.com/mathieucarbou/AsyncTCP#v3.2.3](https://github.com/mathieucarbou/AsyncTCP/releases/tag/v3.2.0)) - **ESP8266**: `esphome/ESPAsyncTCP-esphome @ 2.0.0` (Arduino IDE: [https://github.com/mathieucarbou/esphome-ESPAsyncTCP#v2.0.0](https://github.com/mathieucarbou/esphome-ESPAsyncTCP/releases/tag/v2.0.0)) - **RP2040**: `khoih-prog/AsyncTCP_RP2040W @ 1.2.0` (Arduino IDE: [https://github.com/khoih-prog/AsyncTCP_RP2040W#v1.2.0](https://github.com/khoih-prog/AsyncTCP_RP2040W/releases/tag/v1.2.0)) diff --git a/library.json b/library.json index e8388a1ae..fd109ffde 100644 --- a/library.json +++ b/library.json @@ -28,7 +28,7 @@ { "owner": "mathieucarbou", "name": "AsyncTCP", - "version": "^3.2.2", + "version": "^3.2.3", "platforms": "espressif32" }, { diff --git a/platformio.ini b/platformio.ini index c722c1e2e..01110bf8b 100644 --- a/platformio.ini +++ b/platformio.ini @@ -27,14 +27,14 @@ platform = espressif32 board = esp32dev lib_deps = bblanchon/ArduinoJson @ 7.1.0 - mathieucarbou/AsyncTCP @ 3.2.2 + mathieucarbou/AsyncTCP @ 3.2.3 [env:arduino-2] platform = espressif32@6.7.0 board = esp32dev lib_deps = bblanchon/ArduinoJson @ 7.1.0 - mathieucarbou/AsyncTCP @ 3.2.2 + mathieucarbou/AsyncTCP @ 3.2.3 [env:arduino-3] platform = espressif32 @@ -44,7 +44,7 @@ platform_packages= board = esp32dev lib_deps = bblanchon/ArduinoJson @ 7.1.0 - mathieucarbou/AsyncTCP @ 3.2.2 + mathieucarbou/AsyncTCP @ 3.2.3 [env:esp8266] platform = espressif8266 From 840dc3b27c6bc8a2267cf92cd7bbd00ee650782c Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Wed, 17 Jul 2024 21:57:13 +0200 Subject: [PATCH 293/551] v3.1.1 --- library.json | 2 +- library.properties | 2 +- src/ESPAsyncWebServer.h | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/library.json b/library.json index fd109ffde..4d322f23f 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "ESPAsyncWebServer", - "version": "3.1.0", + "version": "3.1.1", "description": "Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 and RP2040. Supports: WebSocket, SSE, Authentication, Arduino Json 7, File Upload, Static File serving, URL Rewrite, URL Redirect, etc.", "keywords": "http,async,websocket,webserver", "homepage": "https://github.com/mathieucarbou/ESPAsyncWebServer", diff --git a/library.properties b/library.properties index 8da8a1489..f3647ad69 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=ESPAsyncWebServer -version=3.1.0 +version=3.1.1 author=Me-No-Dev maintainer=Mathieu Carbou sentence=Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 and RP2040 diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index 5731afb25..73a2c366f 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -45,10 +45,10 @@ #include "literals.h" -#define ASYNCWEBSERVER_VERSION "3.1.0" +#define ASYNCWEBSERVER_VERSION "3.1.1" #define ASYNCWEBSERVER_VERSION_MAJOR 3 #define ASYNCWEBSERVER_VERSION_MINOR 1 -#define ASYNCWEBSERVER_VERSION_REVISION 0 +#define ASYNCWEBSERVER_VERSION_REVISION 1 #define ASYNCWEBSERVER_FORK_mathieucarbou #ifdef ASYNCWEBSERVER_REGEX From 78b46f0587cf050a8627b7af4b8246841f0287fa Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Thu, 18 Jul 2024 12:46:00 +0200 Subject: [PATCH 294/551] Added esp32-c6-devkitc-1 --- platformio.ini | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/platformio.ini b/platformio.ini index 01110bf8b..183e20b2c 100644 --- a/platformio.ini +++ b/platformio.ini @@ -64,3 +64,10 @@ board = rpipicow lib_deps = bblanchon/ArduinoJson @ 7.1.0 khoih-prog/AsyncTCP_RP2040W @ 1.2.0 + +[env:pioarduino] +platform = https://github.com/pioarduino/platform-espressif32/releases/download/51.03.03/platform-espressif32.zip +board = esp32-c6-devkitc-1 +lib_deps = + bblanchon/ArduinoJson @ 7.1.0 + mathieucarbou/AsyncTCP @ 3.2.3 From 7f3f5bf6d915188f72f1a001c81e1a7a3492968e Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Fri, 19 Jul 2024 09:28:12 +0200 Subject: [PATCH 295/551] doc update --- README.md | 20 ++++++++++++++------ docs/index.md | 20 ++++++++++++++------ 2 files changed, 28 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 029def86b..c65853b47 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,20 @@ Supports: WebSocket, SSE, Authentication, Arduino Json 7, File Upload, Static Fi This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubox-node-org/ESPAsyncWebServer) and includes all the concurrency fixes. +## Coordinate and dependencies: + +**WARNING** The library name was changed from `ESP Async WebServer` to `ESPAsyncWebServer` as per the Arduino Lint recommendations. + +``` +mathieucarbou/ESPAsyncWebServer @ 3.1.1 +``` + +Dependency: + +- **ESP32**: `mathieucarbou/AsyncTCP @ 3.2.3` (Arduino IDE: [https://github.com/mathieucarbou/AsyncTCP#v3.2.3](https://github.com/mathieucarbou/AsyncTCP/releases/tag/v3.2.0)) +- **ESP8266**: `esphome/ESPAsyncTCP-esphome @ 2.0.0` (Arduino IDE: [https://github.com/mathieucarbou/esphome-ESPAsyncTCP#v2.0.0](https://github.com/mathieucarbou/esphome-ESPAsyncTCP/releases/tag/v2.0.0)) +- **RP2040**: `khoih-prog/AsyncTCP_RP2040W @ 1.2.0` (Arduino IDE: [https://github.com/khoih-prog/AsyncTCP_RP2040W#v1.2.0](https://github.com/khoih-prog/AsyncTCP_RP2040W/releases/tag/v1.2.0)) + ## Changes in this fork - [@ayushsharma82](https://github.com/ayushsharma82) and [@mathieucarbou](https://github.com/mathieucarbou): Add RP2040 support ([#31](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/31)) @@ -39,12 +53,6 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo - [@vortigont](https://github.com/vortigont): Some websocket code cleanup ([#29](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/29)) - [@vortigont](https://github.com/vortigont): Refactor code - replace DYI structs with STL objects ([#39](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/39)) -## Dependencies: - -- **ESP32**: `mathieucarbou/AsyncTCP @ 3.2.3` (Arduino IDE: [https://github.com/mathieucarbou/AsyncTCP#v3.2.3](https://github.com/mathieucarbou/AsyncTCP/releases/tag/v3.2.0)) -- **ESP8266**: `esphome/ESPAsyncTCP-esphome @ 2.0.0` (Arduino IDE: [https://github.com/mathieucarbou/esphome-ESPAsyncTCP#v2.0.0](https://github.com/mathieucarbou/esphome-ESPAsyncTCP/releases/tag/v2.0.0)) -- **RP2040**: `khoih-prog/AsyncTCP_RP2040W @ 1.2.0` (Arduino IDE: [https://github.com/khoih-prog/AsyncTCP_RP2040W#v1.2.0](https://github.com/khoih-prog/AsyncTCP_RP2040W/releases/tag/v1.2.0)) - ## Documentation Usage and API stays the same as the original library. diff --git a/docs/index.md b/docs/index.md index 029def86b..c65853b47 100644 --- a/docs/index.md +++ b/docs/index.md @@ -9,6 +9,20 @@ Supports: WebSocket, SSE, Authentication, Arduino Json 7, File Upload, Static Fi This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubox-node-org/ESPAsyncWebServer) and includes all the concurrency fixes. +## Coordinate and dependencies: + +**WARNING** The library name was changed from `ESP Async WebServer` to `ESPAsyncWebServer` as per the Arduino Lint recommendations. + +``` +mathieucarbou/ESPAsyncWebServer @ 3.1.1 +``` + +Dependency: + +- **ESP32**: `mathieucarbou/AsyncTCP @ 3.2.3` (Arduino IDE: [https://github.com/mathieucarbou/AsyncTCP#v3.2.3](https://github.com/mathieucarbou/AsyncTCP/releases/tag/v3.2.0)) +- **ESP8266**: `esphome/ESPAsyncTCP-esphome @ 2.0.0` (Arduino IDE: [https://github.com/mathieucarbou/esphome-ESPAsyncTCP#v2.0.0](https://github.com/mathieucarbou/esphome-ESPAsyncTCP/releases/tag/v2.0.0)) +- **RP2040**: `khoih-prog/AsyncTCP_RP2040W @ 1.2.0` (Arduino IDE: [https://github.com/khoih-prog/AsyncTCP_RP2040W#v1.2.0](https://github.com/khoih-prog/AsyncTCP_RP2040W/releases/tag/v1.2.0)) + ## Changes in this fork - [@ayushsharma82](https://github.com/ayushsharma82) and [@mathieucarbou](https://github.com/mathieucarbou): Add RP2040 support ([#31](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/31)) @@ -39,12 +53,6 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo - [@vortigont](https://github.com/vortigont): Some websocket code cleanup ([#29](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/29)) - [@vortigont](https://github.com/vortigont): Refactor code - replace DYI structs with STL objects ([#39](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/39)) -## Dependencies: - -- **ESP32**: `mathieucarbou/AsyncTCP @ 3.2.3` (Arduino IDE: [https://github.com/mathieucarbou/AsyncTCP#v3.2.3](https://github.com/mathieucarbou/AsyncTCP/releases/tag/v3.2.0)) -- **ESP8266**: `esphome/ESPAsyncTCP-esphome @ 2.0.0` (Arduino IDE: [https://github.com/mathieucarbou/esphome-ESPAsyncTCP#v2.0.0](https://github.com/mathieucarbou/esphome-ESPAsyncTCP/releases/tag/v2.0.0)) -- **RP2040**: `khoih-prog/AsyncTCP_RP2040W @ 1.2.0` (Arduino IDE: [https://github.com/khoih-prog/AsyncTCP_RP2040W#v1.2.0](https://github.com/khoih-prog/AsyncTCP_RP2040W/releases/tag/v1.2.0)) - ## Documentation Usage and API stays the same as the original library. From df45d59faa8d8f0edc3fddf8106d4678ae49e205 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Sun, 21 Jul 2024 17:31:43 +0200 Subject: [PATCH 296/551] Code cleanup --- src/AsyncJson.h | 36 +++++------------------------------- src/ChunkPrint.h | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 31 deletions(-) create mode 100644 src/ChunkPrint.h diff --git a/src/AsyncJson.h b/src/AsyncJson.h index b85a93827..bca3f24c7 100644 --- a/src/AsyncJson.h +++ b/src/AsyncJson.h @@ -26,7 +26,7 @@ AsyncCallbackJsonWebHandler* handler = new AsyncCallbackJsonWebHandler("/rest/endpoint"); handler->onRequest([](AsyncWebServerRequest *request, JsonVariant &json) { - JsonObject& jsonObj = json.as(); + JsonObject jsonObj = json.as(); // ... }); server.addHandler(handler); @@ -36,7 +36,8 @@ #define ASYNC_JSON_H_ #include #include -#include + +#include "ChunkPrint.h" #if ARDUINOJSON_VERSION_MAJOR == 6 #ifndef DYNAMIC_JSON_DOCUMENT_SIZE @@ -50,33 +51,6 @@ constexpr const char* JSON_MIMETYPE = "application/json"; * Json Response * */ -class ChunkPrint : public Print { - private: - uint8_t* _destination; - size_t _to_skip; - size_t _to_write; - size_t _pos; - - public: - ChunkPrint(uint8_t* destination, size_t from, size_t len) - : _destination(destination), _to_skip(from), _to_write(len), _pos{0} {} - virtual ~ChunkPrint() {} - size_t write(uint8_t c) { - if (_to_skip > 0) { - _to_skip--; - return 1; - } else if (_to_write > 0) { - _to_write--; - _destination[_pos++] = c; - return 1; - } - return 0; - } - size_t write(const uint8_t* buffer, size_t size) { - return this->Print::write(buffer, size); - } -}; - class AsyncJsonResponse : public AsyncAbstractResponse { protected: #if ARDUINOJSON_VERSION_MAJOR == 5 @@ -199,10 +173,10 @@ class AsyncCallbackJsonWebHandler : public AsyncWebHandler { public: #if ARDUINOJSON_VERSION_MAJOR == 6 - AsyncCallbackJsonWebHandler(const String& uri, ArJsonRequestHandlerFunction onRequest, size_t maxJsonBufferSize = DYNAMIC_JSON_DOCUMENT_SIZE) + AsyncCallbackJsonWebHandler(const String& uri, ArJsonRequestHandlerFunction onRequest = nullptr, size_t maxJsonBufferSize = DYNAMIC_JSON_DOCUMENT_SIZE) : _uri(uri), _method(HTTP_GET | HTTP_POST | HTTP_PUT | HTTP_PATCH), _onRequest(onRequest), maxJsonBufferSize(maxJsonBufferSize), _maxContentLength(16384) {} #else - AsyncCallbackJsonWebHandler(const String& uri, ArJsonRequestHandlerFunction onRequest) + AsyncCallbackJsonWebHandler(const String& uri, ArJsonRequestHandlerFunction onRequest = nullptr) : _uri(uri), _method(HTTP_GET | HTTP_POST | HTTP_PUT | HTTP_PATCH), _onRequest(onRequest), _maxContentLength(16384) {} #endif diff --git a/src/ChunkPrint.h b/src/ChunkPrint.h new file mode 100644 index 000000000..2f4074116 --- /dev/null +++ b/src/ChunkPrint.h @@ -0,0 +1,32 @@ +#ifndef CHUNKPRINT_H +#define CHUNKPRINT_H + +#include + +class ChunkPrint : public Print { + private: + uint8_t* _destination; + size_t _to_skip; + size_t _to_write; + size_t _pos; + + public: + ChunkPrint(uint8_t* destination, size_t from, size_t len) + : _destination(destination), _to_skip(from), _to_write(len), _pos{0} {} + virtual ~ChunkPrint() {} + size_t write(uint8_t c) { + if (_to_skip > 0) { + _to_skip--; + return 1; + } else if (_to_write > 0) { + _to_write--; + _destination[_pos++] = c; + return 1; + } + return 0; + } + size_t write(const uint8_t* buffer, size_t size) { + return this->Print::write(buffer, size); + } +}; +#endif From 961cc4d1a12f5371a04804e7092fea6b2807e2da Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Sun, 21 Jul 2024 17:30:16 +0200 Subject: [PATCH 297/551] MessagePack Support (Fix #59) --- .github/workflows/ci.yml | 3 + examples/SimpleServer/SimpleServer.ino | 79 ++++++++++++-- platformio.ini | 13 ++- src/AsyncMessagePack.h | 145 +++++++++++++++++++++++++ src/literals.h | 2 + 5 files changed, 228 insertions(+), 14 deletions(-) create mode 100644 src/AsyncMessagePack.h diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1090bb8e5..dd446734d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -50,6 +50,9 @@ jobs: - name: Install core run: arduino-cli core install --additional-urls "${{ matrix.index_url }}" ${{ matrix.core }} + - name: Install ArduinoJson + run: arduino-cli lib install ArduinoJson + - name: Install AsyncTCP (ESP32) if: ${{ matrix.core == 'esp32:esp32' }} run: ARDUINO_LIBRARY_ENABLE_UNSAFE_INSTALL=true arduino-cli lib install --git-url https://github.com/mathieucarbou/AsyncTCP#v3.2.3 diff --git a/examples/SimpleServer/SimpleServer.ino b/examples/SimpleServer/SimpleServer.ino index 247267435..f3a160502 100644 --- a/examples/SimpleServer/SimpleServer.ino +++ b/examples/SimpleServer/SimpleServer.ino @@ -16,12 +16,14 @@ #include #include #endif + #include -AsyncWebServer server(80); +#include +#include +#include -const char* ssid = "YOUR_SSID"; -const char* password = "YOUR_PASSWORD"; +AsyncWebServer server(80); const char* PARAM_MESSAGE = "message"; @@ -29,18 +31,24 @@ void notFound(AsyncWebServerRequest* request) { request->send(404, "text/plain", "Not found"); } +AsyncCallbackJsonWebHandler* jsonHandler = new AsyncCallbackJsonWebHandler("/json2"); +AsyncCallbackMessagePackWebHandler* msgPackHandler = new AsyncCallbackMessagePackWebHandler("/msgpack2"); + void setup() { Serial.begin(115200); - WiFi.mode(WIFI_STA); - WiFi.begin(ssid, password); - if (WiFi.waitForConnectResult() != WL_CONNECTED) { - Serial.printf("WiFi Failed!\n"); - return; - } - Serial.print("IP Address: "); - Serial.println(WiFi.localIP()); + // WiFi.mode(WIFI_STA); + // WiFi.begin("YOUR_SSID", "YOUR_PASSWORD"); + // if (WiFi.waitForConnectResult() != WL_CONNECTED) { + // Serial.printf("WiFi Failed!\n"); + // return; + // } + // Serial.print("IP Address: "); + // Serial.println(WiFi.localIP()); + + WiFi.mode(WIFI_AP); + WiFi.softAP("esp-captive"); server.on("/", HTTP_GET, [](AsyncWebServerRequest* request) { request->send(200, "text/plain", "Hello, world"); @@ -68,6 +76,55 @@ void setup() { request->send(200, "text/plain", "Hello, POST: " + message); }); + // JSON + + // receives JSON and sends JSON + jsonHandler->onRequest([](AsyncWebServerRequest* request, JsonVariant& json) { + JsonObject jsonObj = json.as(); + // ... + + AsyncJsonResponse* response = new AsyncJsonResponse(); + JsonObject root = response->getRoot().to(); + root["hello"] = "world"; + response->setLength(); + request->send(response); + }); + + // sends JSON + server.on("/json1", HTTP_GET, [](AsyncWebServerRequest* request) { + AsyncJsonResponse* response = new AsyncJsonResponse(); + JsonObject root = response->getRoot().to(); + root["hello"] = "world"; + response->setLength(); + request->send(response); + }); + + // MessagePack + + // receives MessagePack and sends MessagePack + msgPackHandler->onRequest([](AsyncWebServerRequest* request, JsonVariant& json) { + JsonObject jsonObj = json.as(); + // ... + + AsyncMessagePackResponse* response = new AsyncMessagePackResponse(); + JsonObject root = response->getRoot().to(); + root["hello"] = "world"; + response->setLength(); + request->send(response); + }); + + // sends MessagePack + server.on("/msgpack1", HTTP_GET, [](AsyncWebServerRequest* request) { + AsyncMessagePackResponse* response = new AsyncMessagePackResponse(); + JsonObject root = response->getRoot().to(); + root["hello"] = "world"; + response->setLength(); + request->send(response); + }); + + server.addHandler(jsonHandler); + server.addHandler(msgPackHandler); + server.onNotFound(notFound); server.begin(); diff --git a/platformio.ini b/platformio.ini index 183e20b2c..f84a95abc 100644 --- a/platformio.ini +++ b/platformio.ini @@ -16,11 +16,11 @@ monitor_filters = esp32_exception_decoder, log2file [platformio] lib_dir = . ; src_dir = examples/CaptivePortal -; src_dir = examples/SimpleServer +src_dir = examples/SimpleServer ; src_dir = examples/StreamFiles ; src_dir = examples/Filters ; src_dir = examples/Draft -src_dir = examples/issues/Issue14 +; src_dir = examples/issues/Issue14 [env:arduino] platform = espressif32 @@ -65,7 +65,14 @@ lib_deps = bblanchon/ArduinoJson @ 7.1.0 khoih-prog/AsyncTCP_RP2040W @ 1.2.0 -[env:pioarduino] +[env:pioarduino-esp32dev] +platform = https://github.com/pioarduino/platform-espressif32/releases/download/51.03.03/platform-espressif32.zip +board = esp32dev +lib_deps = + bblanchon/ArduinoJson @ 7.1.0 + mathieucarbou/AsyncTCP @ 3.2.3 + +[env:pioarduino-c6] platform = https://github.com/pioarduino/platform-espressif32/releases/download/51.03.03/platform-espressif32.zip board = esp32-c6-devkitc-1 lib_deps = diff --git a/src/AsyncMessagePack.h b/src/AsyncMessagePack.h new file mode 100644 index 000000000..57a882404 --- /dev/null +++ b/src/AsyncMessagePack.h @@ -0,0 +1,145 @@ +#pragma once + +/* + server.on("/msg_pack", HTTP_ANY, [](AsyncWebServerRequest * request) { + AsyncMessagePackResponse * response = new AsyncMessagePackResponse(); + JsonObject& root = response->getRoot(); + root["key1"] = "key number one"; + JsonObject& nested = root.createNestedObject("nested"); + nested["key1"] = "key number one"; + response->setLength(); + request->send(response); + }); + + -------------------- + + AsyncCallbackMessagePackWebHandler* handler = new AsyncCallbackMessagePackWebHandler("/msg_pack/endpoint"); + handler->onRequest([](AsyncWebServerRequest *request, JsonVariant &json) { + JsonObject jsonObj = json.as(); + // ... + }); + server.addHandler(handler); +*/ + +#include +#include + +#include "ChunkPrint.h" +#include "literals.h" + +class AsyncMessagePackResponse : public AsyncAbstractResponse { + protected: + JsonDocument _jsonBuffer; + JsonVariant _root; + bool _isValid; + + public: + AsyncMessagePackResponse(bool isArray = false) : _isValid{false} { + _code = 200; + _contentType = asyncsrv::T_application_msgpack; + if (isArray) + _root = _jsonBuffer.add(); + else + _root = _jsonBuffer.add(); + } + + JsonVariant& getRoot() { return _root; } + + bool _sourceValid() const { return _isValid; } + + size_t setLength() { + _contentLength = measureMsgPack(_root); + if (_contentLength) { + _isValid = true; + } + return _contentLength; + } + + size_t getSize() const { return _jsonBuffer.size(); } + + size_t _fillBuffer(uint8_t* data, size_t len) { + ChunkPrint dest(data, _sentLength, len); + serializeMsgPack(_root, dest); + return len; + } +}; + +class AsyncCallbackMessagePackWebHandler : public AsyncWebHandler { + public: + typedef std::function ArJsonRequestHandlerFunction; + + protected: + const String _uri; + WebRequestMethodComposite _method; + ArJsonRequestHandlerFunction _onRequest; + size_t _contentLength; + size_t _maxContentLength; + + public: + AsyncCallbackMessagePackWebHandler(const String& uri, ArJsonRequestHandlerFunction onRequest = nullptr) + : _uri(uri), _method(HTTP_GET | HTTP_POST | HTTP_PUT | HTTP_PATCH), _onRequest(onRequest), _maxContentLength(16384) {} + + void setMethod(WebRequestMethodComposite method) { _method = method; } + void setMaxContentLength(int maxContentLength) { _maxContentLength = maxContentLength; } + void onRequest(ArJsonRequestHandlerFunction fn) { _onRequest = fn; } + + virtual bool canHandle(AsyncWebServerRequest* request) override final { + if (!_onRequest) + return false; + + WebRequestMethodComposite request_method = request->method(); + if (!(_method & request_method)) + return false; + + if (_uri.length() && (_uri != request->url() && !request->url().startsWith(_uri + "/"))) + return false; + + if (request_method != HTTP_GET && !request->contentType().equalsIgnoreCase(asyncsrv::T_application_msgpack)) + return false; + + request->addInterestingHeader("ANY"); + return true; + } + + virtual void handleRequest(AsyncWebServerRequest* request) override final { + if ((_username != "" && _password != "") && !request->authenticate(_username.c_str(), _password.c_str())) + return request->requestAuthentication(); + + if (_onRequest) { + if (request->method() == HTTP_GET) { + JsonVariant json; + _onRequest(request, json); + return; + + } else if (request->_tempObject != NULL) { + JsonDocument jsonBuffer; + DeserializationError error = deserializeMsgPack(jsonBuffer, (uint8_t*)(request->_tempObject)); + + if (!error) { + JsonVariant json = jsonBuffer.as(); + _onRequest(request, json); + return; + } + } + request->send(_contentLength > _maxContentLength ? 413 : 400); + } else { + request->send(500); + } + } + + virtual void handleUpload(__unused AsyncWebServerRequest* request, __unused const String& filename, __unused size_t index, __unused uint8_t* data, __unused size_t len, __unused bool final) override final {} + + virtual void handleBody(AsyncWebServerRequest* request, uint8_t* data, size_t len, size_t index, size_t total) override final { + if (_onRequest) { + _contentLength = total; + if (total > 0 && request->_tempObject == NULL && total < _maxContentLength) { + request->_tempObject = malloc(total); + } + if (request->_tempObject != NULL) { + memcpy((uint8_t*)(request->_tempObject) + index, data, len); + } + } + } + + virtual bool isRequestHandlerTrivial() override final { return _onRequest ? false : true; } +}; diff --git a/src/literals.h b/src/literals.h index 145d69bed..c60a3eb54 100644 --- a/src/literals.h +++ b/src/literals.h @@ -81,6 +81,7 @@ static constexpr const char* T__xml = ".xml"; static constexpr const char* T__zip = ".zip"; static constexpr const char* T_application_javascript = "application/javascript"; static constexpr const char* T_application_json = "application/json"; +static constexpr const char* T_application_msgpack = "application/msgpack"; static constexpr const char* T_application_pdf = "application/pdf"; static constexpr const char* T_application_x_gzip = "application/x-gzip"; static constexpr const char* T_application_zip = "application/zip"; @@ -249,6 +250,7 @@ static const char T__xml[] PROGMEM = ".xml"; static const char T__zip[] PROGMEM = ".zip"; static const char T_application_javascript[] PROGMEM = "application/javascript"; static const char T_application_json[] PROGMEM = "application/json"; +static const char T_application_msgpack[] PROGMEM = "application/msgpack"; static const char T_application_pdf[] PROGMEM = "application/pdf"; static const char T_application_x_gzip[] PROGMEM = "application/x-gzip"; static const char T_application_zip[] PROGMEM = "application/zip"; From 8eb9ae27c0a2c6e05a8d5b775dc9053c5fad0cdf Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Tue, 30 Jul 2024 08:41:34 +0200 Subject: [PATCH 298/551] mathieucarbou/AsyncTCP @ 3.2.4 --- .github/workflows/ci.yml | 2 +- README.md | 4 ++-- docs/index.md | 4 ++-- library.json | 2 +- platformio.ini | 8 ++++---- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index dd446734d..60472d0e9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -55,7 +55,7 @@ jobs: - name: Install AsyncTCP (ESP32) if: ${{ matrix.core == 'esp32:esp32' }} - run: ARDUINO_LIBRARY_ENABLE_UNSAFE_INSTALL=true arduino-cli lib install --git-url https://github.com/mathieucarbou/AsyncTCP#v3.2.3 + run: ARDUINO_LIBRARY_ENABLE_UNSAFE_INSTALL=true arduino-cli lib install --git-url https://github.com/mathieucarbou/AsyncTCP#v3.2.4 - name: Install ESPAsyncTCP (ESP8266) if: ${{ matrix.core == 'esp8266:esp8266' }} diff --git a/README.md b/README.md index c65853b47..394df4a40 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ mathieucarbou/ESPAsyncWebServer @ 3.1.1 Dependency: -- **ESP32**: `mathieucarbou/AsyncTCP @ 3.2.3` (Arduino IDE: [https://github.com/mathieucarbou/AsyncTCP#v3.2.3](https://github.com/mathieucarbou/AsyncTCP/releases/tag/v3.2.0)) +- **ESP32**: `mathieucarbou/AsyncTCP @ 3.2.4` (Arduino IDE: [https://github.com/mathieucarbou/AsyncTCP#v3.2.4](https://github.com/mathieucarbou/AsyncTCP/releases/tag/v3.2.0)) - **ESP8266**: `esphome/ESPAsyncTCP-esphome @ 2.0.0` (Arduino IDE: [https://github.com/mathieucarbou/esphome-ESPAsyncTCP#v2.0.0](https://github.com/mathieucarbou/esphome-ESPAsyncTCP/releases/tag/v2.0.0)) - **RP2040**: `khoih-prog/AsyncTCP_RP2040W @ 1.2.0` (Arduino IDE: [https://github.com/khoih-prog/AsyncTCP_RP2040W#v1.2.0](https://github.com/khoih-prog/AsyncTCP_RP2040W/releases/tag/v1.2.0)) @@ -36,7 +36,7 @@ Dependency: - [@mathieucarbou](https://github.com/mathieucarbou): Arduino 3 / ESP-IDF 5.1 compatibility - [@mathieucarbou](https://github.com/mathieucarbou): Arduino Json 7 compatibility and backward compatible with 6 and 6 (changes in `AsyncJson.h`). The API to use Json has not changed. These are only internal changes. - [@mathieucarbou](https://github.com/mathieucarbou): CI -- [@mathieucarbou](https://github.com/mathieucarbou): Depends on `mathieucarbou/AsyncTCP @ 3.2.3` +- [@mathieucarbou](https://github.com/mathieucarbou): Depends on `mathieucarbou/AsyncTCP @ 3.2.4` - [@mathieucarbou](https://github.com/mathieucarbou): Deployed in PlatformIO registry and Arduino IDE library manager - [@mathieucarbou](https://github.com/mathieucarbou): Firmware size optimization: remove mbedtls dependency (accounts for 33KB in firmware) - [@mathieucarbou](https://github.com/mathieucarbou): Made DEFAULT_MAX_SSE_CLIENTS customizable diff --git a/docs/index.md b/docs/index.md index c65853b47..394df4a40 100644 --- a/docs/index.md +++ b/docs/index.md @@ -19,7 +19,7 @@ mathieucarbou/ESPAsyncWebServer @ 3.1.1 Dependency: -- **ESP32**: `mathieucarbou/AsyncTCP @ 3.2.3` (Arduino IDE: [https://github.com/mathieucarbou/AsyncTCP#v3.2.3](https://github.com/mathieucarbou/AsyncTCP/releases/tag/v3.2.0)) +- **ESP32**: `mathieucarbou/AsyncTCP @ 3.2.4` (Arduino IDE: [https://github.com/mathieucarbou/AsyncTCP#v3.2.4](https://github.com/mathieucarbou/AsyncTCP/releases/tag/v3.2.0)) - **ESP8266**: `esphome/ESPAsyncTCP-esphome @ 2.0.0` (Arduino IDE: [https://github.com/mathieucarbou/esphome-ESPAsyncTCP#v2.0.0](https://github.com/mathieucarbou/esphome-ESPAsyncTCP/releases/tag/v2.0.0)) - **RP2040**: `khoih-prog/AsyncTCP_RP2040W @ 1.2.0` (Arduino IDE: [https://github.com/khoih-prog/AsyncTCP_RP2040W#v1.2.0](https://github.com/khoih-prog/AsyncTCP_RP2040W/releases/tag/v1.2.0)) @@ -36,7 +36,7 @@ Dependency: - [@mathieucarbou](https://github.com/mathieucarbou): Arduino 3 / ESP-IDF 5.1 compatibility - [@mathieucarbou](https://github.com/mathieucarbou): Arduino Json 7 compatibility and backward compatible with 6 and 6 (changes in `AsyncJson.h`). The API to use Json has not changed. These are only internal changes. - [@mathieucarbou](https://github.com/mathieucarbou): CI -- [@mathieucarbou](https://github.com/mathieucarbou): Depends on `mathieucarbou/AsyncTCP @ 3.2.3` +- [@mathieucarbou](https://github.com/mathieucarbou): Depends on `mathieucarbou/AsyncTCP @ 3.2.4` - [@mathieucarbou](https://github.com/mathieucarbou): Deployed in PlatformIO registry and Arduino IDE library manager - [@mathieucarbou](https://github.com/mathieucarbou): Firmware size optimization: remove mbedtls dependency (accounts for 33KB in firmware) - [@mathieucarbou](https://github.com/mathieucarbou): Made DEFAULT_MAX_SSE_CLIENTS customizable diff --git a/library.json b/library.json index 4d322f23f..4c0535fc4 100644 --- a/library.json +++ b/library.json @@ -28,7 +28,7 @@ { "owner": "mathieucarbou", "name": "AsyncTCP", - "version": "^3.2.3", + "version": "^3.2.4", "platforms": "espressif32" }, { diff --git a/platformio.ini b/platformio.ini index f84a95abc..e621af86e 100644 --- a/platformio.ini +++ b/platformio.ini @@ -27,14 +27,14 @@ platform = espressif32 board = esp32dev lib_deps = bblanchon/ArduinoJson @ 7.1.0 - mathieucarbou/AsyncTCP @ 3.2.3 + mathieucarbou/AsyncTCP @ 3.2.4 [env:arduino-2] platform = espressif32@6.7.0 board = esp32dev lib_deps = bblanchon/ArduinoJson @ 7.1.0 - mathieucarbou/AsyncTCP @ 3.2.3 + mathieucarbou/AsyncTCP @ 3.2.4 [env:arduino-3] platform = espressif32 @@ -44,7 +44,7 @@ platform_packages= board = esp32dev lib_deps = bblanchon/ArduinoJson @ 7.1.0 - mathieucarbou/AsyncTCP @ 3.2.3 + mathieucarbou/AsyncTCP @ 3.2.4 [env:esp8266] platform = espressif8266 @@ -77,4 +77,4 @@ platform = https://github.com/pioarduino/platform-espressif32/releases/download/ board = esp32-c6-devkitc-1 lib_deps = bblanchon/ArduinoJson @ 7.1.0 - mathieucarbou/AsyncTCP @ 3.2.3 + mathieucarbou/AsyncTCP @ 3.2.4 From 89187c48dc4850c45760b9766a59223649db8e11 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Tue, 30 Jul 2024 08:44:40 +0200 Subject: [PATCH 299/551] doc update --- README.md | 1 + docs/index.md | 1 + 2 files changed, 2 insertions(+) diff --git a/README.md b/README.md index 394df4a40..91089c4de 100644 --- a/README.md +++ b/README.md @@ -41,6 +41,7 @@ Dependency: - [@mathieucarbou](https://github.com/mathieucarbou): Firmware size optimization: remove mbedtls dependency (accounts for 33KB in firmware) - [@mathieucarbou](https://github.com/mathieucarbou): Made DEFAULT_MAX_SSE_CLIENTS customizable - [@mathieucarbou](https://github.com/mathieucarbou): Made DEFAULT_MAX_WS_CLIENTS customizable +- [@mathieucarbou](https://github.com/mathieucarbou): MessagePack Support ([#62](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/62)) - [@mathieucarbou](https://github.com/mathieucarbou): Remove filename after inline in Content-Disposition header according to RFC2183 - [@mathieucarbou](https://github.com/mathieucarbou): Removed SPIFFSEditor to reduce library size and maintainance. SPIFF si also deprecated. If you need it, please copy the files from the original repository in your project. This fork focus on maintaining the server part and the SPIFFEditor is an application which has nothing to do inside a server library. - [@mathieucarbou](https://github.com/mathieucarbou): Resurrected `AsyncWebSocketMessageBuffer` and `makeBuffer()` in order to make the fork API-compatible with the original library from me-no-dev regarding WebSocket. diff --git a/docs/index.md b/docs/index.md index 394df4a40..91089c4de 100644 --- a/docs/index.md +++ b/docs/index.md @@ -41,6 +41,7 @@ Dependency: - [@mathieucarbou](https://github.com/mathieucarbou): Firmware size optimization: remove mbedtls dependency (accounts for 33KB in firmware) - [@mathieucarbou](https://github.com/mathieucarbou): Made DEFAULT_MAX_SSE_CLIENTS customizable - [@mathieucarbou](https://github.com/mathieucarbou): Made DEFAULT_MAX_WS_CLIENTS customizable +- [@mathieucarbou](https://github.com/mathieucarbou): MessagePack Support ([#62](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/62)) - [@mathieucarbou](https://github.com/mathieucarbou): Remove filename after inline in Content-Disposition header according to RFC2183 - [@mathieucarbou](https://github.com/mathieucarbou): Removed SPIFFSEditor to reduce library size and maintainance. SPIFF si also deprecated. If you need it, please copy the files from the original repository in your project. This fork focus on maintaining the server part and the SPIFFEditor is an application which has nothing to do inside a server library. - [@mathieucarbou](https://github.com/mathieucarbou): Resurrected `AsyncWebSocketMessageBuffer` and `makeBuffer()` in order to make the fork API-compatible with the original library from me-no-dev regarding WebSocket. From a46cb67339d04aaa0e49488641f15452913b2291 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Tue, 30 Jul 2024 11:42:23 +0200 Subject: [PATCH 300/551] v3.1.2 --- README.md | 2 +- docs/index.md | 2 +- library.json | 2 +- library.properties | 2 +- src/ESPAsyncWebServer.h | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 91089c4de..19ab60203 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo **WARNING** The library name was changed from `ESP Async WebServer` to `ESPAsyncWebServer` as per the Arduino Lint recommendations. ``` -mathieucarbou/ESPAsyncWebServer @ 3.1.1 +mathieucarbou/ESPAsyncWebServer @ 3.1.2 ``` Dependency: diff --git a/docs/index.md b/docs/index.md index 91089c4de..19ab60203 100644 --- a/docs/index.md +++ b/docs/index.md @@ -14,7 +14,7 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo **WARNING** The library name was changed from `ESP Async WebServer` to `ESPAsyncWebServer` as per the Arduino Lint recommendations. ``` -mathieucarbou/ESPAsyncWebServer @ 3.1.1 +mathieucarbou/ESPAsyncWebServer @ 3.1.2 ``` Dependency: diff --git a/library.json b/library.json index 4c0535fc4..e2c795328 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "ESPAsyncWebServer", - "version": "3.1.1", + "version": "3.1.2", "description": "Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 and RP2040. Supports: WebSocket, SSE, Authentication, Arduino Json 7, File Upload, Static File serving, URL Rewrite, URL Redirect, etc.", "keywords": "http,async,websocket,webserver", "homepage": "https://github.com/mathieucarbou/ESPAsyncWebServer", diff --git a/library.properties b/library.properties index f3647ad69..8c610fda0 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=ESPAsyncWebServer -version=3.1.1 +version=3.1.2 author=Me-No-Dev maintainer=Mathieu Carbou sentence=Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 and RP2040 diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index 73a2c366f..f729f7e48 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -45,10 +45,10 @@ #include "literals.h" -#define ASYNCWEBSERVER_VERSION "3.1.1" +#define ASYNCWEBSERVER_VERSION "3.1.2" #define ASYNCWEBSERVER_VERSION_MAJOR 3 #define ASYNCWEBSERVER_VERSION_MINOR 1 -#define ASYNCWEBSERVER_VERSION_REVISION 1 +#define ASYNCWEBSERVER_VERSION_REVISION 2 #define ASYNCWEBSERVER_FORK_mathieucarbou #ifdef ASYNCWEBSERVER_REGEX From 72946008f2dd6aa67bf78b4f90bb0cb15a375f2e Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Wed, 31 Jul 2024 09:55:55 +0200 Subject: [PATCH 301/551] espressif32@6.8.1 --- platformio.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platformio.ini b/platformio.ini index e621af86e..0a0ea6981 100644 --- a/platformio.ini +++ b/platformio.ini @@ -30,7 +30,7 @@ lib_deps = mathieucarbou/AsyncTCP @ 3.2.4 [env:arduino-2] -platform = espressif32@6.7.0 +platform = espressif32@6.8.1 board = esp32dev lib_deps = bblanchon/ArduinoJson @ 7.1.0 From 4269b208990675bf1db8fb69c96d38ca89421827 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Fri, 2 Aug 2024 12:18:42 +0200 Subject: [PATCH 302/551] Arduino 3.0.4 --- platformio.ini | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platformio.ini b/platformio.ini index 0a0ea6981..4748525dc 100644 --- a/platformio.ini +++ b/platformio.ini @@ -39,8 +39,8 @@ lib_deps = [env:arduino-3] platform = espressif32 platform_packages= - platformio/framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#3.0.3 - platformio/framework-arduinoespressif32-libs @ https://github.com/espressif/arduino-esp32/releases/download/3.0.3/esp32-arduino-libs-3.0.3.zip + platformio/framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#3.0.4 + platformio/framework-arduinoespressif32-libs @ https://github.com/espressif/arduino-esp32/releases/download/3.0.4/esp32-arduino-libs-3.0.4.zip board = esp32dev lib_deps = bblanchon/ArduinoJson @ 7.1.0 From 429470f5009ecb14b13aad457c7f5ef63b2a8176 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Thu, 8 Aug 2024 09:45:54 +0200 Subject: [PATCH 303/551] vscode --- .vscode/settings.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 5af716e2e..9ebde9715 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -10,6 +10,9 @@ "files.associations": { "*.cps": "javascript", "*.config": "cpp", - "compare": "cpp" + "compare": "cpp", + "*.tcc": "cpp", + "deque": "cpp", + "vector": "cpp" } } \ No newline at end of file From 40a2fd71bf899825eb0a92ddf333068e7ebb4070 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Fri, 9 Aug 2024 07:34:57 +0200 Subject: [PATCH 304/551] mathieucarbou/AsyncTCP @ 3.2.4 --- .vscode/settings.json | 58 ++++++++++++++++++++++++++++++++++++++++++- platformio.ini | 2 +- 2 files changed, 58 insertions(+), 2 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 9ebde9715..83b1f1699 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -13,6 +13,62 @@ "compare": "cpp", "*.tcc": "cpp", "deque": "cpp", - "vector": "cpp" + "vector": "cpp", + "array": "cpp", + "atomic": "cpp", + "bit": "cpp", + "bitset": "cpp", + "cctype": "cpp", + "chrono": "cpp", + "clocale": "cpp", + "cmath": "cpp", + "concepts": "cpp", + "condition_variable": "cpp", + "cstdarg": "cpp", + "cstddef": "cpp", + "cstdint": "cpp", + "cstdio": "cpp", + "cstdlib": "cpp", + "cstring": "cpp", + "ctime": "cpp", + "cwchar": "cpp", + "cwctype": "cpp", + "list": "cpp", + "map": "cpp", + "set": "cpp", + "unordered_map": "cpp", + "exception": "cpp", + "algorithm": "cpp", + "functional": "cpp", + "iterator": "cpp", + "memory": "cpp", + "memory_resource": "cpp", + "numeric": "cpp", + "optional": "cpp", + "random": "cpp", + "ratio": "cpp", + "regex": "cpp", + "string": "cpp", + "string_view": "cpp", + "system_error": "cpp", + "tuple": "cpp", + "type_traits": "cpp", + "utility": "cpp", + "initializer_list": "cpp", + "iosfwd": "cpp", + "istream": "cpp", + "limits": "cpp", + "mutex": "cpp", + "new": "cpp", + "ostream": "cpp", + "ranges": "cpp", + "sstream": "cpp", + "stdexcept": "cpp", + "stop_token": "cpp", + "streambuf": "cpp", + "thread": "cpp", + "cinttypes": "cpp", + "typeinfo": "cpp", + "variant": "cpp" } } \ No newline at end of file diff --git a/platformio.ini b/platformio.ini index 4748525dc..5781fe11e 100644 --- a/platformio.ini +++ b/platformio.ini @@ -70,7 +70,7 @@ platform = https://github.com/pioarduino/platform-espressif32/releases/download/ board = esp32dev lib_deps = bblanchon/ArduinoJson @ 7.1.0 - mathieucarbou/AsyncTCP @ 3.2.3 + mathieucarbou/AsyncTCP @ 3.2.4 [env:pioarduino-c6] platform = https://github.com/pioarduino/platform-espressif32/releases/download/51.03.03/platform-espressif32.zip From 843f07334afa914cdbf3e96879903be6a1f58e55 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Thu, 8 Aug 2024 09:46:57 +0200 Subject: [PATCH 305/551] Using emptyString constant instead of String() --- src/ESPAsyncWebServer.h | 12 ++++++------ src/WebRequest.cpp | 18 +++++++++--------- src/WebResponseImpl.h | 6 +++--- src/WebResponses.cpp | 4 ++-- 4 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index f729f7e48..a12165b08 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -293,11 +293,11 @@ class AsyncWebServerRequest { void redirect(const String& url) { return redirect(url.c_str()); }; void send(AsyncWebServerResponse* response); - void send(int code, const String& contentType = String(), const String& content = String()); + void send(int code, const String& contentType = emptyString, const String& content = emptyString); void send(int code, const String& contentType, const uint8_t* content, size_t len, AwsTemplateProcessor callback = nullptr); void send(int code, const String& contentType, PGM_P content, AwsTemplateProcessor callback = nullptr); - void send(FS& fs, const String& path, const String& contentType = String(), bool download = false, AwsTemplateProcessor callback = nullptr); - void send(File content, const String& path, const String& contentType = String(), bool download = false, AwsTemplateProcessor callback = nullptr); + void send(FS& fs, const String& path, const String& contentType = emptyString, bool download = false, AwsTemplateProcessor callback = nullptr); + void send(File content, const String& path, const String& contentType = emptyString, bool download = false, AwsTemplateProcessor callback = nullptr); void send(Stream& stream, const String& contentType, size_t len, AwsTemplateProcessor callback = nullptr); void send(const String& contentType, size_t len, AwsResponseFiller callback, AwsTemplateProcessor templateCallback = nullptr); void sendChunked(const String& contentType, AwsResponseFiller callback, AwsTemplateProcessor templateCallback = nullptr); @@ -311,11 +311,11 @@ class AsyncWebServerRequest { send(code, contentType, content, callback); } - AsyncWebServerResponse* beginResponse(int code, const String& contentType = String(), const String& content = String()); + AsyncWebServerResponse* beginResponse(int code, const String& contentType = emptyString, const String& content = emptyString); AsyncWebServerResponse* beginResponse(int code, const String& contentType, const uint8_t* content, size_t len, AwsTemplateProcessor callback = nullptr); AsyncWebServerResponse* beginResponse(int code, const String& contentType, PGM_P content, AwsTemplateProcessor callback = nullptr); - AsyncWebServerResponse* beginResponse(FS& fs, const String& path, const String& contentType = String(), bool download = false, AwsTemplateProcessor callback = nullptr); - AsyncWebServerResponse* beginResponse(File content, const String& path, const String& contentType = String(), bool download = false, AwsTemplateProcessor callback = nullptr); + AsyncWebServerResponse* beginResponse(FS& fs, const String& path, const String& contentType = emptyString, bool download = false, AwsTemplateProcessor callback = nullptr); + AsyncWebServerResponse* beginResponse(File content, const String& path, const String& contentType = emptyString, bool download = false, AwsTemplateProcessor callback = nullptr); AsyncWebServerResponse* beginResponse(Stream& stream, const String& contentType, size_t len, AwsTemplateProcessor callback = nullptr); AsyncWebServerResponse* beginResponse(const String& contentType, size_t len, AwsResponseFiller callback, AwsTemplateProcessor templateCallback = nullptr); AsyncWebServerResponse* beginChunkedResponse(const String& contentType, AwsResponseFiller callback, AwsTemplateProcessor templateCallback = nullptr); diff --git a/src/WebRequest.cpp b/src/WebRequest.cpp index f0d6bdf8a..01549f0aa 100644 --- a/src/WebRequest.cpp +++ b/src/WebRequest.cpp @@ -274,7 +274,7 @@ bool AsyncWebServerRequest::_parseReqHead() { if (!_temp.startsWith(T_HTTP_1_0)) _version = 1; - _temp = String(); + _temp = emptyString; return true; } @@ -327,7 +327,7 @@ bool AsyncWebServerRequest::_parseReqHeader() { _temp.clear(); #else // Ancient PRI core does not have String::clear() method 8-() - _temp = String(); + _temp = emptyString; #endif return true; } @@ -348,7 +348,7 @@ void AsyncWebServerRequest::_parsePlainPostChar(uint8_t data) { _temp.clear(); #else // Ancient PRI core does not have String::clear() method 8-() - _temp = String(); + _temp = emptyString; #endif } } @@ -390,10 +390,10 @@ void AsyncWebServerRequest::_parseMultipartPostByte(uint8_t data, bool last) { if (!_parsedLength) { _multiParseState = EXPECT_BOUNDARY; - _temp = String(); - _itemName = String(); - _itemFilename = String(); - _itemType = String(); + _temp = emptyString; + _itemName = emptyString; + _itemFilename = emptyString; + _itemType = emptyString; } if (_multiParseState == WAIT_FOR_RETURN1) { @@ -450,13 +450,13 @@ void AsyncWebServerRequest::_parseMultipartPostByte(uint8_t data, bool last) { _itemIsFile = true; } } - _temp = String(); + _temp = emptyString; } else { _multiParseState = WAIT_FOR_RETURN1; // value starts from here _itemSize = 0; _itemStartIndex = _parsedLength; - _itemValue = String(); + _itemValue = emptyString; if (_itemIsFile) { if (_itemBuffer) free(_itemBuffer); diff --git a/src/WebResponseImpl.h b/src/WebResponseImpl.h index 26ec22365..ed7a55e48 100644 --- a/src/WebResponseImpl.h +++ b/src/WebResponseImpl.h @@ -36,7 +36,7 @@ class AsyncBasicResponse : public AsyncWebServerResponse { String _content; public: - AsyncBasicResponse(int code, const String& contentType = String(), const String& content = String()); + AsyncBasicResponse(int code, const String& contentType = emptyString, const String& content = emptyString); void _respond(AsyncWebServerRequest* request); size_t _ack(AsyncWebServerRequest* request, size_t len, uint32_t time); bool _sourceValid() const { return true; } @@ -79,8 +79,8 @@ class AsyncFileResponse : public AsyncAbstractResponse { void _setContentType(const String& path); public: - AsyncFileResponse(FS& fs, const String& path, const String& contentType = String(), bool download = false, AwsTemplateProcessor callback = nullptr); - AsyncFileResponse(File content, const String& path, const String& contentType = String(), bool download = false, AwsTemplateProcessor callback = nullptr); + AsyncFileResponse(FS& fs, const String& path, const String& contentType = emptyString, bool download = false, AwsTemplateProcessor callback = nullptr); + AsyncFileResponse(File content, const String& path, const String& contentType = emptyString, bool download = false, AwsTemplateProcessor callback = nullptr); ~AsyncFileResponse(); bool _sourceValid() const { return !!(_content); } virtual size_t _fillBuffer(uint8_t* buf, size_t maxLen) override; diff --git a/src/WebResponses.cpp b/src/WebResponses.cpp index 86aa9479b..ce05d6e0d 100644 --- a/src/WebResponses.cpp +++ b/src/WebResponses.cpp @@ -353,7 +353,7 @@ size_t AsyncBasicResponse::_ack(AsyncWebServerRequest* request, size_t len, uint // we can fit in this packet if (space > available) { _writtenLength += request->client()->write(_content.c_str(), available); - _content = String(); + _content = emptyString; _state = RESPONSE_WAIT_ACK; return available; } @@ -465,7 +465,7 @@ size_t AsyncAbstractResponse::_ack(AsyncWebServerRequest* request, size_t len, u } if (headLen) { - _head = String(); + _head = emptyString; } if (outLen) { From a9afafb4ade3464a28afb37b754b19b7604bd16d Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Thu, 8 Aug 2024 12:23:46 +0200 Subject: [PATCH 306/551] Added const char* flavors to reduce heap usage and fragmentation during String objects copy --- src/AsyncWebSocket.h | 31 ++++------- src/ESPAsyncWebServer.h | 114 ++++++++++++++++++++++++++++------------ src/WebHandlers.cpp | 10 ++-- src/WebRequest.cpp | 86 +++++++++--------------------- src/WebResponseImpl.h | 26 +++++---- src/WebResponses.cpp | 30 +++++------ 6 files changed, 154 insertions(+), 143 deletions(-) diff --git a/src/AsyncWebSocket.h b/src/AsyncWebSocket.h index ee7bde199..34256a781 100644 --- a/src/AsyncWebSocket.h +++ b/src/AsyncWebSocket.h @@ -230,18 +230,12 @@ class AsyncWebSocketClient { size_t queueLen() const; size_t printf(const char* format, ...) __attribute__((format(printf, 2, 3))); -#ifndef ESP32 - size_t printf_P(PGM_P formatP, ...) __attribute__((format(printf, 2, 3))); -#endif void text(AsyncWebSocketSharedBuffer buffer); void text(const uint8_t* message, size_t len); void text(const char* message, size_t len); void text(const char* message); void text(const String& message); -#ifndef ESP32 - void text(const __FlashStringHelper* message); -#endif // ESP32 void text(AsyncWebSocketMessageBuffer* buffer); void binary(AsyncWebSocketSharedBuffer buffer); @@ -249,9 +243,6 @@ class AsyncWebSocketClient { void binary(const char* message, size_t len); void binary(const char* message); void binary(const String& message); -#ifndef ESP32 - void binary(const __FlashStringHelper* message, size_t len); -#endif // ESP32 void binary(AsyncWebSocketMessageBuffer* buffer); bool canSend() const; @@ -263,6 +254,12 @@ class AsyncWebSocketClient { void _onTimeout(uint32_t time); void _onDisconnect(); void _onData(void* pbuf, size_t plen); + +#ifdef ESP8266 + size_t printf_P(PGM_P formatP, ...) __attribute__((format(printf, 2, 3))); + void text(const __FlashStringHelper* message); + void binary(const __FlashStringHelper* message, size_t len); +#endif }; using AwsHandshakeHandler = std::function; @@ -308,17 +305,11 @@ class AsyncWebSocket : public AsyncWebHandler { void text(uint32_t id, const String& message); void text(uint32_t id, AsyncWebSocketMessageBuffer* buffer); void text(uint32_t id, AsyncWebSocketSharedBuffer buffer); -#ifdef ESP8266 - void text(uint32_t id, const __FlashStringHelper* message); -#endif // ESP8266 void textAll(const uint8_t* message, size_t len); void textAll(const char* message, size_t len); void textAll(const char* message); void textAll(const String& message); -#ifdef ESP8266 - void textAll(const __FlashStringHelper* message); -#endif // ESP8266 void textAll(AsyncWebSocketMessageBuffer* buffer); void textAll(AsyncWebSocketSharedBuffer buffer); @@ -326,9 +317,6 @@ class AsyncWebSocket : public AsyncWebHandler { void binary(uint32_t id, const char* message, size_t len); void binary(uint32_t id, const char* message); void binary(uint32_t id, const String& message); -#ifdef ESP8266 - void binary(uint32_t id, const __FlashStringHelper* message, size_t len); -#endif // ESP8266 void binary(uint32_t id, AsyncWebSocketMessageBuffer* buffer); void binary(uint32_t id, AsyncWebSocketSharedBuffer buffer); @@ -336,9 +324,6 @@ class AsyncWebSocket : public AsyncWebHandler { void binaryAll(const char* message, size_t len); void binaryAll(const char* message); void binaryAll(const String& message); -#ifdef ESP8266 - void binaryAll(const __FlashStringHelper* message, size_t len); -#endif // ESP8266 void binaryAll(AsyncWebSocketMessageBuffer* buffer); void binaryAll(AsyncWebSocketSharedBuffer buffer); @@ -346,6 +331,10 @@ class AsyncWebSocket : public AsyncWebHandler { size_t printfAll(const char* format, ...) __attribute__((format(printf, 2, 3))); #ifdef ESP8266 + void text(uint32_t id, const __FlashStringHelper* message); + void textAll(const __FlashStringHelper* message); + void binary(uint32_t id, const __FlashStringHelper* message, size_t len); + void binaryAll(const __FlashStringHelper* message, size_t len); size_t printf_P(uint32_t id, PGM_P formatP, ...) __attribute__((format(printf, 3, 4))); size_t printfAll_P(PGM_P formatP, ...) __attribute__((format(printf, 2, 3))); #endif diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index a12165b08..781fdb028 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -35,10 +35,10 @@ #include #include #elif defined(TARGET_RP2040) - #include #include - #include #include + #include + #include #else #error Platform not supported #endif @@ -68,20 +68,20 @@ class AsyncStaticWebHandler; class AsyncCallbackWebHandler; class AsyncResponseStream; -#if defined (TARGET_RP2040) - typedef enum http_method WebRequestMethod; +#if defined(TARGET_RP2040) +typedef enum http_method WebRequestMethod; #else #ifndef WEBSERVER_H - typedef enum { - HTTP_GET = 0b00000001, - HTTP_POST = 0b00000010, - HTTP_DELETE = 0b00000100, - HTTP_PUT = 0b00001000, - HTTP_PATCH = 0b00010000, - HTTP_HEAD = 0b00100000, - HTTP_OPTIONS = 0b01000000, - HTTP_ANY = 0b01111111, - } WebRequestMethod; +typedef enum { + HTTP_GET = 0b00000001, + HTTP_POST = 0b00000010, + HTTP_DELETE = 0b00000100, + HTTP_PUT = 0b00001000, + HTTP_PATCH = 0b00010000, + HTTP_HEAD = 0b00100000, + HTTP_OPTIONS = 0b01000000, + HTTP_ANY = 0b01111111, +} WebRequestMethod; #endif #endif @@ -138,6 +138,7 @@ class AsyncWebHeader { AsyncWebHeader() = default; AsyncWebHeader(const AsyncWebHeader&) = default; + AsyncWebHeader(const char* name, const char* value) : _name(name), _value(value) {} AsyncWebHeader(const String& name, const String& value) : _name(name), _value(value) {} AsyncWebHeader(const String& data) { if (!data) @@ -293,14 +294,37 @@ class AsyncWebServerRequest { void redirect(const String& url) { return redirect(url.c_str()); }; void send(AsyncWebServerResponse* response); - void send(int code, const String& contentType = emptyString, const String& content = emptyString); - void send(int code, const String& contentType, const uint8_t* content, size_t len, AwsTemplateProcessor callback = nullptr); - void send(int code, const String& contentType, PGM_P content, AwsTemplateProcessor callback = nullptr); - void send(FS& fs, const String& path, const String& contentType = emptyString, bool download = false, AwsTemplateProcessor callback = nullptr); - void send(File content, const String& path, const String& contentType = emptyString, bool download = false, AwsTemplateProcessor callback = nullptr); - void send(Stream& stream, const String& contentType, size_t len, AwsTemplateProcessor callback = nullptr); - void send(const String& contentType, size_t len, AwsResponseFiller callback, AwsTemplateProcessor templateCallback = nullptr); - void sendChunked(const String& contentType, AwsResponseFiller callback, AwsTemplateProcessor templateCallback = nullptr); + + void send(int code, const char* contentType = "", const char* content = "", AwsTemplateProcessor callback = nullptr) { send(beginResponse(code, contentType, content, callback)); } + void send(int code, const String& contentType, const String& content = emptyString, AwsTemplateProcessor callback = nullptr) { send(beginResponse(code, contentType, content, callback)); } + + void send(int code, const char* contentType, const uint8_t* content, size_t len, AwsTemplateProcessor callback = nullptr) { send(beginResponse(code, contentType, content, len, callback)); } + void send(int code, const String& contentType, const uint8_t* content, size_t len, AwsTemplateProcessor callback = nullptr) { send(beginResponse(code, contentType, content, len, callback)); } + + void send(FS& fs, const String& path, const char* contentType = "", bool download = false, AwsTemplateProcessor callback = nullptr) { + if (fs.exists(path) || (!download && fs.exists(path + asyncsrv::T__gz))) { + send(beginResponse(fs, path, contentType, download, callback)); + } else + send(404); + } + void send(FS& fs, const String& path, const String& contentType = emptyString, bool download = false, AwsTemplateProcessor callback = nullptr) { send(fs, path, contentType.c_str(), download, callback); } + + void send(File content, const String& path, const char* contentType = "", bool download = false, AwsTemplateProcessor callback = nullptr) { + if (content) { + send(beginResponse(content, path, contentType, download, callback)); + } else + send(404); + } + void send(File content, const String& path, const String& contentType = emptyString, bool download = false, AwsTemplateProcessor callback = nullptr) { send(content, path, contentType.c_str(), download, callback); } + + void send(Stream& stream, const char* contentType, size_t len, AwsTemplateProcessor callback = nullptr) { send(beginResponse(stream, contentType, len, callback)); } + void send(Stream& stream, const String& contentType, size_t len, AwsTemplateProcessor callback = nullptr) { send(beginResponse(stream, contentType, len, callback)); } + + void send(const char* contentType, size_t len, AwsResponseFiller callback, AwsTemplateProcessor templateCallback = nullptr) { send(beginResponse(contentType, len, callback, templateCallback)); } + void send(const String& contentType, size_t len, AwsResponseFiller callback, AwsTemplateProcessor templateCallback = nullptr) { send(beginResponse(contentType, len, callback, templateCallback)); } + + void sendChunked(const char* contentType, AwsResponseFiller callback, AwsTemplateProcessor templateCallback = nullptr) { send(beginChunkedResponse(contentType, callback, templateCallback)); } + void sendChunked(const String& contentType, AwsResponseFiller callback, AwsTemplateProcessor templateCallback = nullptr) { send(beginChunkedResponse(contentType, callback, templateCallback)); } [[deprecated("Replaced by send(...)")]] void send_P(int code, const String& contentType, const uint8_t* content, size_t len, AwsTemplateProcessor callback = nullptr) { @@ -311,16 +335,33 @@ class AsyncWebServerRequest { send(code, contentType, content, callback); } - AsyncWebServerResponse* beginResponse(int code, const String& contentType = emptyString, const String& content = emptyString); - AsyncWebServerResponse* beginResponse(int code, const String& contentType, const uint8_t* content, size_t len, AwsTemplateProcessor callback = nullptr); - AsyncWebServerResponse* beginResponse(int code, const String& contentType, PGM_P content, AwsTemplateProcessor callback = nullptr); - AsyncWebServerResponse* beginResponse(FS& fs, const String& path, const String& contentType = emptyString, bool download = false, AwsTemplateProcessor callback = nullptr); - AsyncWebServerResponse* beginResponse(File content, const String& path, const String& contentType = emptyString, bool download = false, AwsTemplateProcessor callback = nullptr); - AsyncWebServerResponse* beginResponse(Stream& stream, const String& contentType, size_t len, AwsTemplateProcessor callback = nullptr); - AsyncWebServerResponse* beginResponse(const String& contentType, size_t len, AwsResponseFiller callback, AwsTemplateProcessor templateCallback = nullptr); +#ifdef ESP8266 + void send(int code, const String& contentType, PGM_P content, AwsTemplateProcessor callback = nullptr) { send(beginResponse(code, contentType, content, callback)); } +#endif + + AsyncWebServerResponse* beginResponse(int code, const char* contentType = "", const char* content = "", AwsTemplateProcessor callback = nullptr); + AsyncWebServerResponse* beginResponse(int code, const String& contentType, const String& content = emptyString, AwsTemplateProcessor callback = nullptr) { return beginResponse(code, contentType.c_str(), content.c_str(), callback); } + + AsyncWebServerResponse* beginResponse(int code, const char* contentType, const uint8_t* content, size_t len, AwsTemplateProcessor callback = nullptr); + AsyncWebServerResponse* beginResponse(int code, const String& contentType, const uint8_t* content, size_t len, AwsTemplateProcessor callback = nullptr) { return beginResponse(code, contentType.c_str(), content, len, callback); } + + AsyncWebServerResponse* beginResponse(FS& fs, const String& path, const char* contentType = "", bool download = false, AwsTemplateProcessor callback = nullptr); + AsyncWebServerResponse* beginResponse(FS& fs, const String& path, const String& contentType = emptyString, bool download = false, AwsTemplateProcessor callback = nullptr) { return beginResponse(fs, path, contentType.c_str(), download, callback); } + + AsyncWebServerResponse* beginResponse(File content, const String& path, const char* contentType = "", bool download = false, AwsTemplateProcessor callback = nullptr); + AsyncWebServerResponse* beginResponse(File content, const String& path, const String& contentType = emptyString, bool download = false, AwsTemplateProcessor callback = nullptr) { return beginResponse(content, path, contentType.c_str(), download, callback); } + + AsyncWebServerResponse* beginResponse(Stream& stream, const char* contentType, size_t len, AwsTemplateProcessor callback = nullptr); + AsyncWebServerResponse* beginResponse(Stream& stream, const String& contentType, size_t len, AwsTemplateProcessor callback = nullptr) { return beginResponse(stream, contentType.c_str(), len, callback); } + + AsyncWebServerResponse* beginResponse(const char* contentType, size_t len, AwsResponseFiller callback, AwsTemplateProcessor templateCallback = nullptr); + AsyncWebServerResponse* beginResponse(const String& contentType, size_t len, AwsResponseFiller callback, AwsTemplateProcessor templateCallback = nullptr) { return beginResponse(contentType.c_str(), len, callback, templateCallback); } + + AsyncWebServerResponse* beginChunkedResponse(const char* contentType, AwsResponseFiller callback, AwsTemplateProcessor templateCallback = nullptr); AsyncWebServerResponse* beginChunkedResponse(const String& contentType, AwsResponseFiller callback, AwsTemplateProcessor templateCallback = nullptr); - AsyncResponseStream* beginResponseStream(const String& contentType, size_t bufferSize = 1460); + AsyncResponseStream* beginResponseStream(const char* contentType, size_t bufferSize = 1460); + AsyncResponseStream* beginResponseStream(const String& contentType, size_t bufferSize = 1460) { return beginResponseStream(contentType.c_str(), bufferSize); } [[deprecated("Replaced by beginResponse(...)")]] AsyncWebServerResponse* beginResponse_P(int code, const String& contentType, const uint8_t* content, size_t len, AwsTemplateProcessor callback = nullptr) { @@ -331,6 +372,10 @@ class AsyncWebServerRequest { return beginResponse(code, contentType, content, callback); } +#ifdef ESP8266 + AsyncWebServerResponse* beginResponse(int code, const String& contentType, PGM_P content, AwsTemplateProcessor callback = nullptr); +#endif + size_t headers() const; // get header count // check if header exists @@ -348,7 +393,8 @@ class AsyncWebServerRequest { const AsyncWebHeader* getHeader(size_t num) const; size_t params() const; // get arguments count - bool hasParam(const String& name, bool post = false, bool file = false) const; + bool hasParam(const char* name, bool post = false, bool file = false) const; + bool hasParam(const String& name, bool post = false, bool file = false) const { return hasParam(name.c_str(), post, file); }; #ifdef ESP8266 bool hasParam(const __FlashStringHelper* data, bool post = false, bool file = false) const { return hasParam(String(data).c_str(), post, file); }; #endif @@ -526,8 +572,10 @@ class AsyncWebServerResponse { virtual ~AsyncWebServerResponse(); virtual void setCode(int code); virtual void setContentLength(size_t len); - virtual void setContentType(const String& type); - virtual void addHeader(const String& name, const String& value); + void setContentType(const String& type) { setContentType(type.c_str()); } + virtual void setContentType(const char* type); + virtual void addHeader(const char* name, const char* value); + void addHeader(const String& name, const String& value) { addHeader(name.c_str(), value.c_str()); } virtual String _assembleHead(uint8_t version); virtual bool _started() const; virtual bool _finished() const; diff --git a/src/WebHandlers.cpp b/src/WebHandlers.cpp index 580cebab3..d904a399d 100644 --- a/src/WebHandlers.cpp +++ b/src/WebHandlers.cpp @@ -231,16 +231,16 @@ void AsyncStaticWebHandler::handleRequest(AsyncWebServerRequest* request) { } else if (_cache_control.length() && request->hasHeader(T_INM) && request->header(T_INM).equals(etag)) { request->_tempFile.close(); AsyncWebServerResponse* response = new AsyncBasicResponse(304); // Not modified - response->addHeader(T_Cache_Control, _cache_control); - response->addHeader(T_ETag, etag); + response->addHeader(T_Cache_Control, _cache_control.c_str()); + response->addHeader(T_ETag, etag.c_str()); request->send(response); } else { AsyncWebServerResponse* response = new AsyncFileResponse(request->_tempFile, filename, String(), false, _callback); if (_last_modified.length()) - response->addHeader(T_Last_Modified, _last_modified); + response->addHeader(T_Last_Modified, _last_modified.c_str()); if (_cache_control.length()) { - response->addHeader(T_Cache_Control, _cache_control); - response->addHeader(T_ETag, etag); + response->addHeader(T_Cache_Control, _cache_control.c_str()); + response->addHeader(T_ETag, etag.c_str()); } request->send(response); } diff --git a/src/WebRequest.cpp b/src/WebRequest.cpp index 01549f0aa..95fda7eb1 100644 --- a/src/WebRequest.cpp +++ b/src/WebRequest.cpp @@ -307,7 +307,7 @@ bool AsyncWebServerRequest::_parseReqHeader() { if (name.equalsIgnoreCase(T_UPGRADE) && value.equalsIgnoreCase(T_WS)) { // WebSocket request can be uniquely identified by header: [Upgrade: websocket] _reqconntype = RCT_WS; - } else if (name.equalsIgnoreCase(T_ACCEPT)){ + } else if (name.equalsIgnoreCase(T_ACCEPT)) { String lowcase(value); lowcase.toLowerCase(); #ifndef ESP8266 @@ -345,10 +345,10 @@ void AsyncWebServerRequest::_parsePlainPostChar(uint8_t data) { _params.emplace_back(urlDecode(name), urlDecode(value), true); #ifndef TARGET_RP2040 - _temp.clear(); + _temp.clear(); #else - // Ancient PRI core does not have String::clear() method 8-() - _temp = emptyString; + // Ancient PRI core does not have String::clear() method 8-() + _temp = emptyString; #endif } } @@ -654,9 +654,9 @@ size_t AsyncWebServerRequest::params() const { return _params.size(); } -bool AsyncWebServerRequest::hasParam(const String& name, bool post, bool file) const { +bool AsyncWebServerRequest::hasParam(const char* name, bool post, bool file) const { for (const auto& p : _params) { - if (p.name() == name && p.isPost() == post && p.isFile() == file) { + if (p.name().equals(name) && p.isPost() == post && p.isFile() == file) { return true; } } @@ -689,48 +689,52 @@ void AsyncWebServerRequest::addInterestingHeader(const char* name) { _interestingHeaders.emplace_back(name); } -AsyncWebServerResponse* AsyncWebServerRequest::beginResponse(int code, const String& contentType, const String& content) { +AsyncWebServerResponse* AsyncWebServerRequest::beginResponse(int code, const char* contentType, const char* content, AwsTemplateProcessor callback) { + if (callback) + return new AsyncProgmemResponse(code, contentType, (const uint8_t*)content, strlen(content), callback); return new AsyncBasicResponse(code, contentType, content); } -AsyncWebServerResponse* AsyncWebServerRequest::beginResponse(int code, const String& contentType, const uint8_t* content, size_t len, AwsTemplateProcessor callback) { +AsyncWebServerResponse* AsyncWebServerRequest::beginResponse(int code, const char* contentType, const uint8_t* content, size_t len, AwsTemplateProcessor callback) { return new AsyncProgmemResponse(code, contentType, content, len, callback); } -AsyncWebServerResponse* AsyncWebServerRequest::beginResponse(int code, const String& contentType, PGM_P content, AwsTemplateProcessor callback) { - return new AsyncProgmemResponse(code, contentType, (const uint8_t*)content, strlen_P(content), callback); -} - -AsyncWebServerResponse* AsyncWebServerRequest::beginResponse(FS& fs, const String& path, const String& contentType, bool download, AwsTemplateProcessor callback) { +AsyncWebServerResponse* AsyncWebServerRequest::beginResponse(FS& fs, const String& path, const char* contentType, bool download, AwsTemplateProcessor callback) { if (fs.exists(path) || (!download && fs.exists(path + T__gz))) return new AsyncFileResponse(fs, path, contentType, download, callback); return NULL; } -AsyncWebServerResponse* AsyncWebServerRequest::beginResponse(File content, const String& path, const String& contentType, bool download, AwsTemplateProcessor callback) { +AsyncWebServerResponse* AsyncWebServerRequest::beginResponse(File content, const String& path, const char* contentType, bool download, AwsTemplateProcessor callback) { if (content == true) return new AsyncFileResponse(content, path, contentType, download, callback); return NULL; } -AsyncWebServerResponse* AsyncWebServerRequest::beginResponse(Stream& stream, const String& contentType, size_t len, AwsTemplateProcessor callback) { +AsyncWebServerResponse* AsyncWebServerRequest::beginResponse(Stream& stream, const char* contentType, size_t len, AwsTemplateProcessor callback) { return new AsyncStreamResponse(stream, contentType, len, callback); } -AsyncWebServerResponse* AsyncWebServerRequest::beginResponse(const String& contentType, size_t len, AwsResponseFiller callback, AwsTemplateProcessor templateCallback) { +AsyncWebServerResponse* AsyncWebServerRequest::beginResponse(const char* contentType, size_t len, AwsResponseFiller callback, AwsTemplateProcessor templateCallback) { return new AsyncCallbackResponse(contentType, len, callback, templateCallback); } -AsyncWebServerResponse* AsyncWebServerRequest::beginChunkedResponse(const String& contentType, AwsResponseFiller callback, AwsTemplateProcessor templateCallback) { +AsyncWebServerResponse* AsyncWebServerRequest::beginChunkedResponse(const char* contentType, AwsResponseFiller callback, AwsTemplateProcessor templateCallback) { if (_version) return new AsyncChunkedResponse(contentType, callback, templateCallback); return new AsyncCallbackResponse(contentType, 0, callback, templateCallback); } -AsyncResponseStream* AsyncWebServerRequest::beginResponseStream(const String& contentType, size_t bufferSize) { +AsyncResponseStream* AsyncWebServerRequest::beginResponseStream(const char* contentType, size_t bufferSize) { return new AsyncResponseStream(contentType, bufferSize); } +#ifdef ESP8266 +AsyncWebServerResponse* AsyncWebServerRequest::beginResponse(int code, const String& contentType, PGM_P content, AwsTemplateProcessor callback) { + return new AsyncProgmemResponse(code, contentType, (const uint8_t*)content, strlen_P(content), callback); +} +#endif + void AsyncWebServerRequest::send(AsyncWebServerResponse* response) { _response = response; if (_response == NULL) { @@ -748,44 +752,6 @@ void AsyncWebServerRequest::send(AsyncWebServerResponse* response) { } } -void AsyncWebServerRequest::send(int code, const String& contentType, const String& content) { - send(beginResponse(code, contentType, content)); -} - -void AsyncWebServerRequest::send(int code, const String& contentType, const uint8_t* content, size_t len, AwsTemplateProcessor callback) { - send(beginResponse(code, contentType, content, len, callback)); -} - -void AsyncWebServerRequest::send(int code, const String& contentType, PGM_P content, AwsTemplateProcessor callback) { - send(beginResponse(code, contentType, content, callback)); -} - -void AsyncWebServerRequest::send(FS& fs, const String& path, const String& contentType, bool download, AwsTemplateProcessor callback) { - if (fs.exists(path) || (!download && fs.exists(path + T__gz))) { - send(beginResponse(fs, path, contentType, download, callback)); - } else - send(404); -} - -void AsyncWebServerRequest::send(File content, const String& path, const String& contentType, bool download, AwsTemplateProcessor callback) { - if (content == true) { - send(beginResponse(content, path, contentType, download, callback)); - } else - send(404); -} - -void AsyncWebServerRequest::send(Stream& stream, const String& contentType, size_t len, AwsTemplateProcessor callback) { - send(beginResponse(stream, contentType, len, callback)); -} - -void AsyncWebServerRequest::send(const String& contentType, size_t len, AwsResponseFiller callback, AwsTemplateProcessor templateCallback) { - send(beginResponse(contentType, len, callback, templateCallback)); -} - -void AsyncWebServerRequest::sendChunked(const String& contentType, AwsResponseFiller callback, AwsTemplateProcessor templateCallback) { - send(beginChunkedResponse(contentType, callback, templateCallback)); -} - void AsyncWebServerRequest::redirect(const char* url) { AsyncWebServerResponse* response = beginResponse(302); response->addHeader(T_LOCATION, url); @@ -834,11 +800,11 @@ void AsyncWebServerRequest::requestAuthentication(const char* realm, bool isDige String header(T_BASIC_REALM); header.concat(realm); header += '"'; - r->addHeader(T_WWW_AUTH, header); + r->addHeader(T_WWW_AUTH, header.c_str()); } else { String header(T_DIGEST_); header.concat(requestDigestAuthentication(realm)); - r->addHeader(T_WWW_AUTH, header); + r->addHeader(T_WWW_AUTH, header.c_str()); } send(r); } @@ -949,7 +915,7 @@ const char* AsyncWebServerRequest::methodToString() const { return T_OPTIONS; return T_UNKNOWN; } -#else // ESP8266 +#else // ESP8266 const __FlashStringHelper* AsyncWebServerRequest::methodToString() const { if (_method == HTTP_ANY) return FPSTR(T_ANY); @@ -988,7 +954,7 @@ const char* AsyncWebServerRequest::requestedConnTypeToString() const { return T_ERROR; } } -#else // ESP8266 +#else // ESP8266 const __FlashStringHelper* AsyncWebServerRequest::requestedConnTypeToString() const { switch (_reqconntype) { case RCT_NOT_USED: diff --git a/src/WebResponseImpl.h b/src/WebResponseImpl.h index ed7a55e48..21b90441b 100644 --- a/src/WebResponseImpl.h +++ b/src/WebResponseImpl.h @@ -36,7 +36,8 @@ class AsyncBasicResponse : public AsyncWebServerResponse { String _content; public: - AsyncBasicResponse(int code, const String& contentType = emptyString, const String& content = emptyString); + AsyncBasicResponse(int code, const char* contentType = "", const char* content = ""); + AsyncBasicResponse(int code, const String& contentType, const String& content = emptyString) : AsyncBasicResponse(code, contentType.c_str(), content.c_str()) {} void _respond(AsyncWebServerRequest* request); size_t _ack(AsyncWebServerRequest* request, size_t len, uint32_t time); bool _sourceValid() const { return true; } @@ -76,11 +77,13 @@ class AsyncFileResponse : public AsyncAbstractResponse { private: File _content; String _path; - void _setContentType(const String& path); + void _setContentTypeFromPath(const String& path); public: - AsyncFileResponse(FS& fs, const String& path, const String& contentType = emptyString, bool download = false, AwsTemplateProcessor callback = nullptr); - AsyncFileResponse(File content, const String& path, const String& contentType = emptyString, bool download = false, AwsTemplateProcessor callback = nullptr); + AsyncFileResponse(FS& fs, const String& path, const char* contentType = "", bool download = false, AwsTemplateProcessor callback = nullptr); + AsyncFileResponse(FS& fs, const String& path, const String& contentType, bool download = false, AwsTemplateProcessor callback = nullptr) : AsyncFileResponse(fs, path, contentType.c_str(), download, callback) {} + AsyncFileResponse(File content, const String& path, const char* contentType = "", bool download = false, AwsTemplateProcessor callback = nullptr); + AsyncFileResponse(File content, const String& path, const String& contentType, bool download = false, AwsTemplateProcessor callack = nullptr) : AsyncFileResponse(content, path, contentType.c_str(), download, callack) {} ~AsyncFileResponse(); bool _sourceValid() const { return !!(_content); } virtual size_t _fillBuffer(uint8_t* buf, size_t maxLen) override; @@ -91,7 +94,8 @@ class AsyncStreamResponse : public AsyncAbstractResponse { Stream* _content; public: - AsyncStreamResponse(Stream& stream, const String& contentType, size_t len, AwsTemplateProcessor callback = nullptr); + AsyncStreamResponse(Stream& stream, const char* contentType, size_t len, AwsTemplateProcessor callback = nullptr); + AsyncStreamResponse(Stream& stream, const String& contentType, size_t len, AwsTemplateProcessor callback = nullptr) : AsyncStreamResponse(stream, contentType.c_str(), len, callback) {} bool _sourceValid() const { return !!(_content); } virtual size_t _fillBuffer(uint8_t* buf, size_t maxLen) override; }; @@ -102,7 +106,8 @@ class AsyncCallbackResponse : public AsyncAbstractResponse { size_t _filledLength; public: - AsyncCallbackResponse(const String& contentType, size_t len, AwsResponseFiller callback, AwsTemplateProcessor templateCallback = nullptr); + AsyncCallbackResponse(const char* contentType, size_t len, AwsResponseFiller callback, AwsTemplateProcessor templateCallback = nullptr); + AsyncCallbackResponse(const String& contentType, size_t len, AwsResponseFiller callback, AwsTemplateProcessor templateCallback = nullptr) : AsyncCallbackResponse(contentType.c_str(), len, callback, templateCallback) {} bool _sourceValid() const { return !!(_content); } virtual size_t _fillBuffer(uint8_t* buf, size_t maxLen) override; }; @@ -113,7 +118,8 @@ class AsyncChunkedResponse : public AsyncAbstractResponse { size_t _filledLength; public: - AsyncChunkedResponse(const String& contentType, AwsResponseFiller callback, AwsTemplateProcessor templateCallback = nullptr); + AsyncChunkedResponse(const char* contentType, AwsResponseFiller callback, AwsTemplateProcessor templateCallback = nullptr); + AsyncChunkedResponse(const String& contentType, AwsResponseFiller callback, AwsTemplateProcessor templateCallback = nullptr) : AsyncChunkedResponse(contentType.c_str(), callback, templateCallback) {} bool _sourceValid() const { return !!(_content); } virtual size_t _fillBuffer(uint8_t* buf, size_t maxLen) override; }; @@ -124,7 +130,8 @@ class AsyncProgmemResponse : public AsyncAbstractResponse { size_t _readLength; public: - AsyncProgmemResponse(int code, const String& contentType, const uint8_t* content, size_t len, AwsTemplateProcessor callback = nullptr); + AsyncProgmemResponse(int code, const char* contentType, const uint8_t* content, size_t len, AwsTemplateProcessor callback = nullptr); + AsyncProgmemResponse(int code, const String& contentType, const uint8_t* content, size_t len, AwsTemplateProcessor callback = nullptr) : AsyncProgmemResponse(code, contentType.c_str(), content, len, callback) {} bool _sourceValid() const { return true; } virtual size_t _fillBuffer(uint8_t* buf, size_t maxLen) override; }; @@ -136,7 +143,8 @@ class AsyncResponseStream : public AsyncAbstractResponse, public Print { std::unique_ptr _content; public: - AsyncResponseStream(const String& contentType, size_t bufferSize); + AsyncResponseStream(const char* contentType, size_t bufferSize); + AsyncResponseStream(const String& contentType, size_t bufferSize) : AsyncResponseStream(contentType.c_str(), bufferSize) {} ~AsyncResponseStream(); bool _sourceValid() const { return (_state < RESPONSE_END); } virtual size_t _fillBuffer(uint8_t* buf, size_t maxLen) override; diff --git a/src/WebResponses.cpp b/src/WebResponses.cpp index ce05d6e0d..f1994b116 100644 --- a/src/WebResponses.cpp +++ b/src/WebResponses.cpp @@ -234,12 +234,12 @@ void AsyncWebServerResponse::setContentLength(size_t len) { _contentLength = len; } -void AsyncWebServerResponse::setContentType(const String& type) { +void AsyncWebServerResponse::setContentType(const char* type) { if (_state == RESPONSE_SETUP) _contentType = type; } -void AsyncWebServerResponse::addHeader(const String& name, const String& value) { +void AsyncWebServerResponse::addHeader(const char* name, const char* value) { _headers.emplace_back(name, value); } @@ -298,7 +298,7 @@ size_t AsyncWebServerResponse::_ack(AsyncWebServerRequest* request, size_t len, /* * String/Code Response * */ -AsyncBasicResponse::AsyncBasicResponse(int code, const String& contentType, const String& content) { +AsyncBasicResponse::AsyncBasicResponse(int code, const char* contentType, const char* content) { _code = code; _content = content; _contentType = contentType; @@ -607,7 +607,7 @@ AsyncFileResponse::~AsyncFileResponse() { _content.close(); } -void AsyncFileResponse::_setContentType(const String& path) { +void AsyncFileResponse::_setContentTypeFromPath(const String& path) { #if HAVE_EXTERN_GET_Content_Type_FUNCTION #ifndef ESP8266 extern const char* getContentType(const String& path); @@ -657,7 +657,7 @@ void AsyncFileResponse::_setContentType(const String& path) { #endif } -AsyncFileResponse::AsyncFileResponse(FS& fs, const String& path, const String& contentType, bool download, AwsTemplateProcessor callback) : AsyncAbstractResponse(callback) { +AsyncFileResponse::AsyncFileResponse(FS& fs, const String& path, const char* contentType, bool download, AwsTemplateProcessor callback) : AsyncAbstractResponse(callback) { _code = 200; _path = path; @@ -672,8 +672,8 @@ AsyncFileResponse::AsyncFileResponse(FS& fs, const String& path, const String& c _content = fs.open(_path, fs::FileOpenMode::read); _contentLength = _content.size(); - if (contentType.length() == 0) - _setContentType(path); + if (strlen(contentType) == 0) + _setContentTypeFromPath(path); else _contentType = contentType; @@ -691,7 +691,7 @@ AsyncFileResponse::AsyncFileResponse(FS& fs, const String& path, const String& c addHeader(T_Content_Disposition, buf); } -AsyncFileResponse::AsyncFileResponse(File content, const String& path, const String& contentType, bool download, AwsTemplateProcessor callback) : AsyncAbstractResponse(callback) { +AsyncFileResponse::AsyncFileResponse(File content, const String& path, const char* contentType, bool download, AwsTemplateProcessor callback) : AsyncAbstractResponse(callback) { _code = 200; _path = path; @@ -705,8 +705,8 @@ AsyncFileResponse::AsyncFileResponse(File content, const String& path, const Str _content = content; _contentLength = _content.size(); - if (contentType.length() == 0) - _setContentType(path); + if (strlen(contentType) == 0) + _setContentTypeFromPath(path); else _contentType = contentType; @@ -730,7 +730,7 @@ size_t AsyncFileResponse::_fillBuffer(uint8_t* data, size_t len) { * Stream Response * */ -AsyncStreamResponse::AsyncStreamResponse(Stream& stream, const String& contentType, size_t len, AwsTemplateProcessor callback) : AsyncAbstractResponse(callback) { +AsyncStreamResponse::AsyncStreamResponse(Stream& stream, const char* contentType, size_t len, AwsTemplateProcessor callback) : AsyncAbstractResponse(callback) { _code = 200; _content = &stream; _contentLength = len; @@ -750,7 +750,7 @@ size_t AsyncStreamResponse::_fillBuffer(uint8_t* data, size_t len) { * Callback Response * */ -AsyncCallbackResponse::AsyncCallbackResponse(const String& contentType, size_t len, AwsResponseFiller callback, AwsTemplateProcessor templateCallback) : AsyncAbstractResponse(templateCallback) { +AsyncCallbackResponse::AsyncCallbackResponse(const char* contentType, size_t len, AwsResponseFiller callback, AwsTemplateProcessor templateCallback) : AsyncAbstractResponse(templateCallback) { _code = 200; _content = callback; _contentLength = len; @@ -772,7 +772,7 @@ size_t AsyncCallbackResponse::_fillBuffer(uint8_t* data, size_t len) { * Chunked Response * */ -AsyncChunkedResponse::AsyncChunkedResponse(const String& contentType, AwsResponseFiller callback, AwsTemplateProcessor processorCallback) : AsyncAbstractResponse(processorCallback) { +AsyncChunkedResponse::AsyncChunkedResponse(const char* contentType, AwsResponseFiller callback, AwsTemplateProcessor processorCallback) : AsyncAbstractResponse(processorCallback) { _code = 200; _content = callback; _contentLength = 0; @@ -794,7 +794,7 @@ size_t AsyncChunkedResponse::_fillBuffer(uint8_t* data, size_t len) { * Progmem Response * */ -AsyncProgmemResponse::AsyncProgmemResponse(int code, const String& contentType, const uint8_t* content, size_t len, AwsTemplateProcessor callback) : AsyncAbstractResponse(callback) { +AsyncProgmemResponse::AsyncProgmemResponse(int code, const char* contentType, const uint8_t* content, size_t len, AwsTemplateProcessor callback) : AsyncAbstractResponse(callback) { _code = code; _content = content; _contentType = contentType; @@ -818,7 +818,7 @@ size_t AsyncProgmemResponse::_fillBuffer(uint8_t* data, size_t len) { * Response Stream (You can print/write/printf to it, up to the contentLen bytes) * */ -AsyncResponseStream::AsyncResponseStream(const String& contentType, size_t bufferSize) { +AsyncResponseStream::AsyncResponseStream(const char* contentType, size_t bufferSize) { _code = 200; _contentLength = 0; _contentType = contentType; From a4d5ca6d3bbbaf94600156f94953db9e02204645 Mon Sep 17 00:00:00 2001 From: Emil Muratov Date: Sat, 10 Aug 2024 21:26:44 +0900 Subject: [PATCH 307/551] replace inlined literals '""' with a shared constexpr --- src/ESPAsyncWebServer.h | 12 ++++++------ src/WebResponseImpl.h | 7 ++++--- src/literals.h | 2 ++ 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index 781fdb028..510fcacf8 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -295,13 +295,13 @@ class AsyncWebServerRequest { void send(AsyncWebServerResponse* response); - void send(int code, const char* contentType = "", const char* content = "", AwsTemplateProcessor callback = nullptr) { send(beginResponse(code, contentType, content, callback)); } + void send(int code, const char* contentType = asyncsrv::empty, const char* content = asyncsrv::empty, AwsTemplateProcessor callback = nullptr) { send(beginResponse(code, contentType, content, callback)); } void send(int code, const String& contentType, const String& content = emptyString, AwsTemplateProcessor callback = nullptr) { send(beginResponse(code, contentType, content, callback)); } void send(int code, const char* contentType, const uint8_t* content, size_t len, AwsTemplateProcessor callback = nullptr) { send(beginResponse(code, contentType, content, len, callback)); } void send(int code, const String& contentType, const uint8_t* content, size_t len, AwsTemplateProcessor callback = nullptr) { send(beginResponse(code, contentType, content, len, callback)); } - void send(FS& fs, const String& path, const char* contentType = "", bool download = false, AwsTemplateProcessor callback = nullptr) { + void send(FS& fs, const String& path, const char* contentType = asyncsrv::empty, bool download = false, AwsTemplateProcessor callback = nullptr) { if (fs.exists(path) || (!download && fs.exists(path + asyncsrv::T__gz))) { send(beginResponse(fs, path, contentType, download, callback)); } else @@ -309,7 +309,7 @@ class AsyncWebServerRequest { } void send(FS& fs, const String& path, const String& contentType = emptyString, bool download = false, AwsTemplateProcessor callback = nullptr) { send(fs, path, contentType.c_str(), download, callback); } - void send(File content, const String& path, const char* contentType = "", bool download = false, AwsTemplateProcessor callback = nullptr) { + void send(File content, const String& path, const char* contentType = asyncsrv::empty, bool download = false, AwsTemplateProcessor callback = nullptr) { if (content) { send(beginResponse(content, path, contentType, download, callback)); } else @@ -339,16 +339,16 @@ class AsyncWebServerRequest { void send(int code, const String& contentType, PGM_P content, AwsTemplateProcessor callback = nullptr) { send(beginResponse(code, contentType, content, callback)); } #endif - AsyncWebServerResponse* beginResponse(int code, const char* contentType = "", const char* content = "", AwsTemplateProcessor callback = nullptr); + AsyncWebServerResponse* beginResponse(int code, const char* contentType = asyncsrv::empty, const char* content = asyncsrv::empty, AwsTemplateProcessor callback = nullptr); AsyncWebServerResponse* beginResponse(int code, const String& contentType, const String& content = emptyString, AwsTemplateProcessor callback = nullptr) { return beginResponse(code, contentType.c_str(), content.c_str(), callback); } AsyncWebServerResponse* beginResponse(int code, const char* contentType, const uint8_t* content, size_t len, AwsTemplateProcessor callback = nullptr); AsyncWebServerResponse* beginResponse(int code, const String& contentType, const uint8_t* content, size_t len, AwsTemplateProcessor callback = nullptr) { return beginResponse(code, contentType.c_str(), content, len, callback); } - AsyncWebServerResponse* beginResponse(FS& fs, const String& path, const char* contentType = "", bool download = false, AwsTemplateProcessor callback = nullptr); + AsyncWebServerResponse* beginResponse(FS& fs, const String& path, const char* contentType = asyncsrv::empty, bool download = false, AwsTemplateProcessor callback = nullptr); AsyncWebServerResponse* beginResponse(FS& fs, const String& path, const String& contentType = emptyString, bool download = false, AwsTemplateProcessor callback = nullptr) { return beginResponse(fs, path, contentType.c_str(), download, callback); } - AsyncWebServerResponse* beginResponse(File content, const String& path, const char* contentType = "", bool download = false, AwsTemplateProcessor callback = nullptr); + AsyncWebServerResponse* beginResponse(File content, const String& path, const char* contentType = asyncsrv::empty, bool download = false, AwsTemplateProcessor callback = nullptr); AsyncWebServerResponse* beginResponse(File content, const String& path, const String& contentType = emptyString, bool download = false, AwsTemplateProcessor callback = nullptr) { return beginResponse(content, path, contentType.c_str(), download, callback); } AsyncWebServerResponse* beginResponse(Stream& stream, const char* contentType, size_t len, AwsTemplateProcessor callback = nullptr); diff --git a/src/WebResponseImpl.h b/src/WebResponseImpl.h index 21b90441b..a6f71bb55 100644 --- a/src/WebResponseImpl.h +++ b/src/WebResponseImpl.h @@ -28,6 +28,7 @@ #endif #include #include +#include "literals.h" // It is possible to restore these defines, but one can use _min and _max instead. Or std::min, std::max. @@ -36,7 +37,7 @@ class AsyncBasicResponse : public AsyncWebServerResponse { String _content; public: - AsyncBasicResponse(int code, const char* contentType = "", const char* content = ""); + explicit AsyncBasicResponse(int code, const char* contentType = asyncsrv::empty, const char* content = asyncsrv::empty); AsyncBasicResponse(int code, const String& contentType, const String& content = emptyString) : AsyncBasicResponse(code, contentType.c_str(), content.c_str()) {} void _respond(AsyncWebServerRequest* request); size_t _ack(AsyncWebServerRequest* request, size_t len, uint32_t time); @@ -80,9 +81,9 @@ class AsyncFileResponse : public AsyncAbstractResponse { void _setContentTypeFromPath(const String& path); public: - AsyncFileResponse(FS& fs, const String& path, const char* contentType = "", bool download = false, AwsTemplateProcessor callback = nullptr); + AsyncFileResponse(FS& fs, const String& path, const char* contentType = asyncsrv::empty, bool download = false, AwsTemplateProcessor callback = nullptr); AsyncFileResponse(FS& fs, const String& path, const String& contentType, bool download = false, AwsTemplateProcessor callback = nullptr) : AsyncFileResponse(fs, path, contentType.c_str(), download, callback) {} - AsyncFileResponse(File content, const String& path, const char* contentType = "", bool download = false, AwsTemplateProcessor callback = nullptr); + AsyncFileResponse(File content, const String& path, const char* contentType = asyncsrv::empty, bool download = false, AwsTemplateProcessor callback = nullptr); AsyncFileResponse(File content, const String& path, const String& contentType, bool download = false, AwsTemplateProcessor callack = nullptr) : AsyncFileResponse(content, path, contentType.c_str(), download, callack) {} ~AsyncFileResponse(); bool _sourceValid() const { return !!(_content); } diff --git a/src/literals.h b/src/literals.h index c60a3eb54..8a7293bc3 100644 --- a/src/literals.h +++ b/src/literals.h @@ -2,6 +2,8 @@ namespace asyncsrv { +static constexpr const char* empty = ""; + #ifndef ESP8622 static constexpr const char* T_100_CONTINUE = "100-continue"; static constexpr const char* T_ACCEPT = "Accept"; From 620a430a644e3b98913eaf86efec737283c3c6fa Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Sat, 10 Aug 2024 15:38:45 +0200 Subject: [PATCH 308/551] v3.1.3 --- README.md | 2 +- docs/index.md | 2 +- library.json | 2 +- library.properties | 2 +- src/ESPAsyncWebServer.h | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 19ab60203..8dfa36194 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo **WARNING** The library name was changed from `ESP Async WebServer` to `ESPAsyncWebServer` as per the Arduino Lint recommendations. ``` -mathieucarbou/ESPAsyncWebServer @ 3.1.2 +mathieucarbou/ESPAsyncWebServer @ 3.1.3 ``` Dependency: diff --git a/docs/index.md b/docs/index.md index 19ab60203..8dfa36194 100644 --- a/docs/index.md +++ b/docs/index.md @@ -14,7 +14,7 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo **WARNING** The library name was changed from `ESP Async WebServer` to `ESPAsyncWebServer` as per the Arduino Lint recommendations. ``` -mathieucarbou/ESPAsyncWebServer @ 3.1.2 +mathieucarbou/ESPAsyncWebServer @ 3.1.3 ``` Dependency: diff --git a/library.json b/library.json index e2c795328..8a3f9959c 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "ESPAsyncWebServer", - "version": "3.1.2", + "version": "3.1.3", "description": "Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 and RP2040. Supports: WebSocket, SSE, Authentication, Arduino Json 7, File Upload, Static File serving, URL Rewrite, URL Redirect, etc.", "keywords": "http,async,websocket,webserver", "homepage": "https://github.com/mathieucarbou/ESPAsyncWebServer", diff --git a/library.properties b/library.properties index 8c610fda0..2464a68f2 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=ESPAsyncWebServer -version=3.1.2 +version=3.1.3 author=Me-No-Dev maintainer=Mathieu Carbou sentence=Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 and RP2040 diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index 510fcacf8..c0ae3ebdf 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -45,10 +45,10 @@ #include "literals.h" -#define ASYNCWEBSERVER_VERSION "3.1.2" +#define ASYNCWEBSERVER_VERSION "3.1.3" #define ASYNCWEBSERVER_VERSION_MAJOR 3 #define ASYNCWEBSERVER_VERSION_MINOR 1 -#define ASYNCWEBSERVER_VERSION_REVISION 2 +#define ASYNCWEBSERVER_VERSION_REVISION 3 #define ASYNCWEBSERVER_FORK_mathieucarbou #ifdef ASYNCWEBSERVER_REGEX From 4cc9154d76fdef35819d7c8e42ef7c54cef37c9e Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Sat, 10 Aug 2024 22:39:04 +0200 Subject: [PATCH 309/551] pioarduino 51.03.04 --- platformio.ini | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platformio.ini b/platformio.ini index 5781fe11e..6f68d0def 100644 --- a/platformio.ini +++ b/platformio.ini @@ -66,14 +66,14 @@ lib_deps = khoih-prog/AsyncTCP_RP2040W @ 1.2.0 [env:pioarduino-esp32dev] -platform = https://github.com/pioarduino/platform-espressif32/releases/download/51.03.03/platform-espressif32.zip +platform = https://github.com/pioarduino/platform-espressif32/releases/download/51.03.04/platform-espressif32.zip board = esp32dev lib_deps = bblanchon/ArduinoJson @ 7.1.0 mathieucarbou/AsyncTCP @ 3.2.4 [env:pioarduino-c6] -platform = https://github.com/pioarduino/platform-espressif32/releases/download/51.03.03/platform-espressif32.zip +platform = https://github.com/pioarduino/platform-espressif32/releases/download/51.03.04/platform-espressif32.zip board = esp32-c6-devkitc-1 lib_deps = bblanchon/ArduinoJson @ 7.1.0 From a03a4914715fe6c0b0d1412372666281f39b1039 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Mon, 12 Aug 2024 15:47:36 +0200 Subject: [PATCH 310/551] Fix #73 --- src/ESPAsyncWebServer.h | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index c0ae3ebdf..6ddcbb659 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -154,7 +154,14 @@ class AsyncWebHeader { const String& name() const { return _name; } const String& value() const { return _value; } - String toString() const { return _name + (char)0x3a + (char)0x20 /*": "*/ + _value + asyncsrv::T_rn; } + String toString() const { + String str = _name; + str.concat((char)0x3a); + str.concat((char)0x20); + str.concat(_value); + str.concat(asyncsrv::T_rn); + return str; + } }; /* From 2fbf37d3bd6caed20eb02304251aff2bbdaa9ad4 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Mon, 12 Aug 2024 16:39:11 +0200 Subject: [PATCH 311/551] v3.1.4 --- README.md | 2 +- docs/index.md | 2 +- library.json | 2 +- library.properties | 2 +- src/ESPAsyncWebServer.h | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 8dfa36194..7c1616a67 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo **WARNING** The library name was changed from `ESP Async WebServer` to `ESPAsyncWebServer` as per the Arduino Lint recommendations. ``` -mathieucarbou/ESPAsyncWebServer @ 3.1.3 +mathieucarbou/ESPAsyncWebServer @ 3.1.4 ``` Dependency: diff --git a/docs/index.md b/docs/index.md index 8dfa36194..7c1616a67 100644 --- a/docs/index.md +++ b/docs/index.md @@ -14,7 +14,7 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo **WARNING** The library name was changed from `ESP Async WebServer` to `ESPAsyncWebServer` as per the Arduino Lint recommendations. ``` -mathieucarbou/ESPAsyncWebServer @ 3.1.3 +mathieucarbou/ESPAsyncWebServer @ 3.1.4 ``` Dependency: diff --git a/library.json b/library.json index 8a3f9959c..c44279637 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "ESPAsyncWebServer", - "version": "3.1.3", + "version": "3.1.4", "description": "Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 and RP2040. Supports: WebSocket, SSE, Authentication, Arduino Json 7, File Upload, Static File serving, URL Rewrite, URL Redirect, etc.", "keywords": "http,async,websocket,webserver", "homepage": "https://github.com/mathieucarbou/ESPAsyncWebServer", diff --git a/library.properties b/library.properties index 2464a68f2..16d93e84c 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=ESPAsyncWebServer -version=3.1.3 +version=3.1.4 author=Me-No-Dev maintainer=Mathieu Carbou sentence=Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 and RP2040 diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index 6ddcbb659..08eb34556 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -45,10 +45,10 @@ #include "literals.h" -#define ASYNCWEBSERVER_VERSION "3.1.3" +#define ASYNCWEBSERVER_VERSION "3.1.4" #define ASYNCWEBSERVER_VERSION_MAJOR 3 #define ASYNCWEBSERVER_VERSION_MINOR 1 -#define ASYNCWEBSERVER_VERSION_REVISION 3 +#define ASYNCWEBSERVER_VERSION_REVISION 4 #define ASYNCWEBSERVER_FORK_mathieucarbou #ifdef ASYNCWEBSERVER_REGEX From 74647b2c68f0a5f0819daf8748b4efbfd5c368bc Mon Sep 17 00:00:00 2001 From: iranl Date: Fri, 16 Aug 2024 00:06:11 +0200 Subject: [PATCH 312/551] Add H2 support --- src/WebServer.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/WebServer.cpp b/src/WebServer.cpp index 0e29a549a..d7c9a0219 100644 --- a/src/WebServer.cpp +++ b/src/WebServer.cpp @@ -24,11 +24,19 @@ using namespace asyncsrv; bool ON_STA_FILTER(AsyncWebServerRequest* request) { + #ifndef CONFIG_IDF_TARGET_ESP32H2 return WiFi.localIP() == request->client()->localIP(); + #else + return false; + #endif } bool ON_AP_FILTER(AsyncWebServerRequest* request) { + #ifndef CONFIG_IDF_TARGET_ESP32H2 return WiFi.localIP() != request->client()->localIP(); + #else + return false; + #endif } #ifndef HAVE_FS_FILE_OPEN_MODE From f9d70ce9c7d53e98e1d966fca8a5f586f07e40cc Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Fri, 16 Aug 2024 00:53:34 +0200 Subject: [PATCH 313/551] v3.1.5 --- README.md | 2 +- docs/index.md | 2 +- library.json | 2 +- library.properties | 2 +- src/ESPAsyncWebServer.h | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 7c1616a67..6ca1d1e36 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo **WARNING** The library name was changed from `ESP Async WebServer` to `ESPAsyncWebServer` as per the Arduino Lint recommendations. ``` -mathieucarbou/ESPAsyncWebServer @ 3.1.4 +mathieucarbou/ESPAsyncWebServer @ 3.1.5 ``` Dependency: diff --git a/docs/index.md b/docs/index.md index 7c1616a67..6ca1d1e36 100644 --- a/docs/index.md +++ b/docs/index.md @@ -14,7 +14,7 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo **WARNING** The library name was changed from `ESP Async WebServer` to `ESPAsyncWebServer` as per the Arduino Lint recommendations. ``` -mathieucarbou/ESPAsyncWebServer @ 3.1.4 +mathieucarbou/ESPAsyncWebServer @ 3.1.5 ``` Dependency: diff --git a/library.json b/library.json index c44279637..eb946c67c 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "ESPAsyncWebServer", - "version": "3.1.4", + "version": "3.1.5", "description": "Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 and RP2040. Supports: WebSocket, SSE, Authentication, Arduino Json 7, File Upload, Static File serving, URL Rewrite, URL Redirect, etc.", "keywords": "http,async,websocket,webserver", "homepage": "https://github.com/mathieucarbou/ESPAsyncWebServer", diff --git a/library.properties b/library.properties index 16d93e84c..3036044c6 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=ESPAsyncWebServer -version=3.1.4 +version=3.1.5 author=Me-No-Dev maintainer=Mathieu Carbou sentence=Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 and RP2040 diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index 08eb34556..de08bc082 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -45,10 +45,10 @@ #include "literals.h" -#define ASYNCWEBSERVER_VERSION "3.1.4" +#define ASYNCWEBSERVER_VERSION "3.1.5" #define ASYNCWEBSERVER_VERSION_MAJOR 3 #define ASYNCWEBSERVER_VERSION_MINOR 1 -#define ASYNCWEBSERVER_VERSION_REVISION 4 +#define ASYNCWEBSERVER_VERSION_REVISION 5 #define ASYNCWEBSERVER_FORK_mathieucarbou #ifdef ASYNCWEBSERVER_REGEX From 02e233f9a15dc9cd8615b9cac22ecaca15a5d408 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Fri, 16 Aug 2024 00:56:47 +0200 Subject: [PATCH 314/551] Added CI for H2 --- examples/CaptivePortal/CaptivePortal.ino | 5 +++++ examples/Filters/Filters.ino | 17 +++++++++++++++++ examples/SimpleServer/SimpleServer.ino | 2 ++ examples/StreamFiles/StreamFiles.ino | 3 +++ platformio.ini | 11 +++++++++-- 5 files changed, 36 insertions(+), 2 deletions(-) diff --git a/examples/CaptivePortal/CaptivePortal.ino b/examples/CaptivePortal/CaptivePortal.ino index 2d0de89c2..2cc585110 100644 --- a/examples/CaptivePortal/CaptivePortal.ino +++ b/examples/CaptivePortal/CaptivePortal.ino @@ -29,7 +29,9 @@ class CaptiveRequestHandler : public AsyncWebHandler { response->print("Captive Portal"); response->print("

This is out captive portal front page.

"); response->printf("

You were trying to reach: http://%s%s

", request->host().c_str(), request->url().c_str()); +#ifndef CONFIG_IDF_TARGET_ESP32H2 response->printf("

Try opening this link instead

", WiFi.softAPIP().toString().c_str()); +#endif response->print(""); request->send(response); } @@ -40,6 +42,7 @@ void setup() { Serial.println(); Serial.println("Configuring access point..."); +#ifndef CONFIG_IDF_TARGET_ESP32H2 if (!WiFi.softAP("esp-captive")) { Serial.println("Soft AP creation failed."); while (1) @@ -47,6 +50,8 @@ void setup() { } dnsServer.start(53, "*", WiFi.softAPIP()); +#endif + server.addHandler(new CaptiveRequestHandler()).setFilter(ON_AP_FILTER); // only when requested from AP // more handlers... server.begin(); diff --git a/examples/Filters/Filters.ino b/examples/Filters/Filters.ino index f031a1f78..b7bbcff15 100644 --- a/examples/Filters/Filters.ino +++ b/examples/Filters/Filters.ino @@ -31,7 +31,9 @@ class CaptiveRequestHandler : public AsyncWebHandler { response->print("Captive Portal"); response->print("

This is out captive portal front page.

"); response->printf("

You were trying to reach: http://%s%s

", request->host().c_str(), request->url().c_str()); +#ifndef CONFIG_IDF_TARGET_ESP32H2 response->printf("

Try opening this link instead

", WiFi.softAPIP().toString().c_str()); +#endif response->print(""); request->send(response); } @@ -46,15 +48,21 @@ void setup() { server .on("/", HTTP_GET, [](AsyncWebServerRequest* request) { Serial.println("Captive portal request..."); +#ifndef CONFIG_IDF_TARGET_ESP32H2 Serial.println("WiFi.localIP(): " + WiFi.localIP().toString()); +#endif Serial.println("request->client()->localIP(): " + request->client()->localIP().toString()); #if ESP_IDF_VERSION_MAJOR >= 5 + #ifndef CONFIG_IDF_TARGET_ESP32H2 Serial.println("WiFi.type(): " + String((int)WiFi.localIP().type())); + #endif Serial.println("request->client()->type(): " + String((int)request->client()->localIP().type())); #endif +#ifndef CONFIG_IDF_TARGET_ESP32H2 Serial.println(WiFi.localIP() == request->client()->localIP() ? "should be: ON_STA_FILTER" : "should be: ON_AP_FILTER"); Serial.println(WiFi.localIP() == request->client()->localIP()); Serial.println(WiFi.localIP().toString() == request->client()->localIP().toString()); +#endif request->send(200, "text/plain", "This is the captive portal"); hit1 = true; }) @@ -63,15 +71,21 @@ void setup() { server .on("/", HTTP_GET, [](AsyncWebServerRequest* request) { Serial.println("Website request..."); +#ifndef CONFIG_IDF_TARGET_ESP32H2 Serial.println("WiFi.localIP(): " + WiFi.localIP().toString()); +#endif Serial.println("request->client()->localIP(): " + request->client()->localIP().toString()); #if ESP_IDF_VERSION_MAJOR >= 5 + #ifndef CONFIG_IDF_TARGET_ESP32H2 Serial.println("WiFi.type(): " + String((int)WiFi.localIP().type())); + #endif Serial.println("request->client()->type(): " + String((int)request->client()->localIP().type())); #endif +#ifndef CONFIG_IDF_TARGET_ESP32H2 Serial.println(WiFi.localIP() == request->client()->localIP() ? "should be: ON_STA_FILTER" : "should be: ON_AP_FILTER"); Serial.println(WiFi.localIP() == request->client()->localIP()); Serial.println(WiFi.localIP().toString() == request->client()->localIP().toString()); +#endif request->send(200, "text/plain", "This is the website"); hit2 = true; }) @@ -92,12 +106,15 @@ void setup() { // dnsServer.stop(); // WiFi.softAPdisconnect(); +#ifndef CONFIG_IDF_TARGET_ESP32H2 WiFi.persistent(false); WiFi.begin("IoT"); while (WiFi.status() != WL_CONNECTED) { delay(500); } Serial.println("Connected to WiFi with IP address: " + WiFi.localIP().toString()); +#endif + server.begin(); // while (!hit2) { diff --git a/examples/SimpleServer/SimpleServer.ino b/examples/SimpleServer/SimpleServer.ino index f3a160502..081541c66 100644 --- a/examples/SimpleServer/SimpleServer.ino +++ b/examples/SimpleServer/SimpleServer.ino @@ -38,6 +38,7 @@ void setup() { Serial.begin(115200); +#ifndef CONFIG_IDF_TARGET_ESP32H2 // WiFi.mode(WIFI_STA); // WiFi.begin("YOUR_SSID", "YOUR_PASSWORD"); // if (WiFi.waitForConnectResult() != WL_CONNECTED) { @@ -49,6 +50,7 @@ void setup() { WiFi.mode(WIFI_AP); WiFi.softAP("esp-captive"); +#endif server.on("/", HTTP_GET, [](AsyncWebServerRequest* request) { request->send(200, "text/plain", "Hello, world"); diff --git a/examples/StreamFiles/StreamFiles.ino b/examples/StreamFiles/StreamFiles.ino index 2a2c1b659..508298d79 100644 --- a/examples/StreamFiles/StreamFiles.ino +++ b/examples/StreamFiles/StreamFiles.ino @@ -23,9 +23,12 @@ void setup() { LittleFS.begin(); +#ifndef CONFIG_IDF_TARGET_ESP32H2 WiFi.mode(WIFI_AP); WiFi.softAP("esp-captive"); + dnsServer.start(53, "*", WiFi.softAPIP()); +#endif File file1 = LittleFS.open("/header.html", "w"); file1.print("ESP Captive Portal"); diff --git a/platformio.ini b/platformio.ini index 6f68d0def..397539b93 100644 --- a/platformio.ini +++ b/platformio.ini @@ -15,8 +15,8 @@ monitor_filters = esp32_exception_decoder, log2file [platformio] lib_dir = . -; src_dir = examples/CaptivePortal -src_dir = examples/SimpleServer +src_dir = examples/CaptivePortal +; src_dir = examples/SimpleServer ; src_dir = examples/StreamFiles ; src_dir = examples/Filters ; src_dir = examples/Draft @@ -78,3 +78,10 @@ board = esp32-c6-devkitc-1 lib_deps = bblanchon/ArduinoJson @ 7.1.0 mathieucarbou/AsyncTCP @ 3.2.4 + +[env:pioarduino-h2] +platform = https://github.com/pioarduino/platform-espressif32/releases/download/51.03.04/platform-espressif32.zip +board = esp32-h2-devkitm-1 +lib_deps = + bblanchon/ArduinoJson @ 7.1.0 + mathieucarbou/AsyncTCP @ 3.2.4 From dc60ea821f7774ca80addd408cd40e2c0c7a435b Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Sat, 31 Aug 2024 15:24:50 +0200 Subject: [PATCH 315/551] Fix #79: wrong overload leading to ambiguous method call error during compilation --- src/ESPAsyncWebServer.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index de08bc082..3d6359aa8 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -314,7 +314,7 @@ class AsyncWebServerRequest { } else send(404); } - void send(FS& fs, const String& path, const String& contentType = emptyString, bool download = false, AwsTemplateProcessor callback = nullptr) { send(fs, path, contentType.c_str(), download, callback); } + void send(FS& fs, const String& path, const String& contentType, bool download = false, AwsTemplateProcessor callback = nullptr) { send(fs, path, contentType.c_str(), download, callback); } void send(File content, const String& path, const char* contentType = asyncsrv::empty, bool download = false, AwsTemplateProcessor callback = nullptr) { if (content) { @@ -322,7 +322,7 @@ class AsyncWebServerRequest { } else send(404); } - void send(File content, const String& path, const String& contentType = emptyString, bool download = false, AwsTemplateProcessor callback = nullptr) { send(content, path, contentType.c_str(), download, callback); } + void send(File content, const String& path, const String& contentType, bool download = false, AwsTemplateProcessor callback = nullptr) { send(content, path, contentType.c_str(), download, callback); } void send(Stream& stream, const char* contentType, size_t len, AwsTemplateProcessor callback = nullptr) { send(beginResponse(stream, contentType, len, callback)); } void send(Stream& stream, const String& contentType, size_t len, AwsTemplateProcessor callback = nullptr) { send(beginResponse(stream, contentType, len, callback)); } From 199f91375efe69edeb495c6bbba1edc3e5fb83ba Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Sat, 31 Aug 2024 14:44:55 +0000 Subject: [PATCH 316/551] Update examples --- .vscode/settings.json | 7 ++++++- examples/SimpleServer/SimpleServer.ino | 5 +++++ platformio.ini | 4 ++-- 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 83b1f1699..308506b50 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -70,5 +70,10 @@ "cinttypes": "cpp", "typeinfo": "cpp", "variant": "cpp" - } + }, + "git.enableCommitSigning": true, + "git.alwaysSignOff": false, + "git-graph.repository.sign.tags": true, + "git-graph.repository.commits.showSignatureStatus": true, + "git-graph.repository.sign.commits": true } \ No newline at end of file diff --git a/examples/SimpleServer/SimpleServer.ino b/examples/SimpleServer/SimpleServer.ino index 081541c66..68cf5effb 100644 --- a/examples/SimpleServer/SimpleServer.ino +++ b/examples/SimpleServer/SimpleServer.ino @@ -22,6 +22,7 @@ #include #include #include +#include AsyncWebServer server(80); @@ -56,6 +57,10 @@ void setup() { request->send(200, "text/plain", "Hello, world"); }); + server.on("/file", HTTP_GET, [](AsyncWebServerRequest* request) { + request->send(LittleFS, "/index.html"); + }); + // Send a GET request to /get?message= server.on("/get", HTTP_GET, [](AsyncWebServerRequest* request) { String message; diff --git a/platformio.ini b/platformio.ini index 397539b93..6ac85dda7 100644 --- a/platformio.ini +++ b/platformio.ini @@ -15,8 +15,8 @@ monitor_filters = esp32_exception_decoder, log2file [platformio] lib_dir = . -src_dir = examples/CaptivePortal -; src_dir = examples/SimpleServer +; src_dir = examples/CaptivePortal +src_dir = examples/SimpleServer ; src_dir = examples/StreamFiles ; src_dir = examples/Filters ; src_dir = examples/Draft From a9ebd31dd3d6991093c7ac6f17d4a9779b49dd7a Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Sat, 31 Aug 2024 15:16:16 +0000 Subject: [PATCH 317/551] diable signing --- .vscode/settings.json | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 308506b50..83b1f1699 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -70,10 +70,5 @@ "cinttypes": "cpp", "typeinfo": "cpp", "variant": "cpp" - }, - "git.enableCommitSigning": true, - "git.alwaysSignOff": false, - "git-graph.repository.sign.tags": true, - "git-graph.repository.commits.showSignatureStatus": true, - "git-graph.repository.sign.commits": true + } } \ No newline at end of file From a8cc43dae1d9d17eec7c5cd3dcf12b296a7bf07b Mon Sep 17 00:00:00 2001 From: Mathieu CArbou Date: Sat, 31 Aug 2024 20:49:34 +0000 Subject: [PATCH 318/551] try gitpod... --- .gitpod.Dockerfile | 2 + .gitpod.yml | 9 +++ .vscode/settings.json | 144 +++++++++++++++++++++--------------------- 3 files changed, 83 insertions(+), 72 deletions(-) create mode 100644 .gitpod.Dockerfile create mode 100644 .gitpod.yml diff --git a/.gitpod.Dockerfile b/.gitpod.Dockerfile new file mode 100644 index 000000000..29eeb4357 --- /dev/null +++ b/.gitpod.Dockerfile @@ -0,0 +1,2 @@ +FROM gitpod/workspace-python-3.11 +USER gitpod diff --git a/.gitpod.yml b/.gitpod.yml new file mode 100644 index 000000000..29092a33d --- /dev/null +++ b/.gitpod.yml @@ -0,0 +1,9 @@ +tasks: + - command: pip install --upgrade pip && pip install -U platformio && platformio run -t clean -e arduino-3 + +image: + file: .gitpod.Dockerfile + +vscode: + extensions: + - shardulm94.trailing-spaces diff --git a/.vscode/settings.json b/.vscode/settings.json index 83b1f1699..1e48fc2af 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,74 +1,74 @@ { - "C_Cpp.clang_format_fallbackStyle": "{ BasedOnStyle: LLVM, UseTab: Never, IndentWidth: 2, TabWidth: 2, AllowShortIfStatementsOnASingleLine: false, IndentCaseLabels: true, ColumnLimit: 0, AccessModifierOffset: -2, NamespaceIndentation: All, FixNamespaceComments: false, IndentAccessModifiers: true, PointerAlignment: Left, ReferenceAlignment: Left, ContinuationIndentWidth: 2}", - "files.exclude": { - "**/.lh": true - }, - "cSpell.words": [ - "YASOLR" - ], - "cmake.configureOnOpen": false, - "files.associations": { - "*.cps": "javascript", - "*.config": "cpp", - "compare": "cpp", - "*.tcc": "cpp", - "deque": "cpp", - "vector": "cpp", - "array": "cpp", - "atomic": "cpp", - "bit": "cpp", - "bitset": "cpp", - "cctype": "cpp", - "chrono": "cpp", - "clocale": "cpp", - "cmath": "cpp", - "concepts": "cpp", - "condition_variable": "cpp", - "cstdarg": "cpp", - "cstddef": "cpp", - "cstdint": "cpp", - "cstdio": "cpp", - "cstdlib": "cpp", - "cstring": "cpp", - "ctime": "cpp", - "cwchar": "cpp", - "cwctype": "cpp", - "list": "cpp", - "map": "cpp", - "set": "cpp", - "unordered_map": "cpp", - "exception": "cpp", - "algorithm": "cpp", - "functional": "cpp", - "iterator": "cpp", - "memory": "cpp", - "memory_resource": "cpp", - "numeric": "cpp", - "optional": "cpp", - "random": "cpp", - "ratio": "cpp", - "regex": "cpp", - "string": "cpp", - "string_view": "cpp", - "system_error": "cpp", - "tuple": "cpp", - "type_traits": "cpp", - "utility": "cpp", - "initializer_list": "cpp", - "iosfwd": "cpp", - "istream": "cpp", - "limits": "cpp", - "mutex": "cpp", - "new": "cpp", - "ostream": "cpp", - "ranges": "cpp", - "sstream": "cpp", - "stdexcept": "cpp", - "stop_token": "cpp", - "streambuf": "cpp", - "thread": "cpp", - "cinttypes": "cpp", - "typeinfo": "cpp", - "variant": "cpp" - } + "platformio-ide.toolbar": [ + { + "text": "$(home)", + "tooltip": "PlatformIO: Home", + "commands": "platformio-ide.showHome" + }, + { + "text": "$(trash)", + "tooltip": "PlatformIO: Clean", + "commands": "platformio-ide.clean" + }, + { + "text": "$(check)", + "tooltip": "PlatformIO: Build", + "commands": "platformio-ide.build" + }, + { + "text": "Upload", + "tooltip": "PlatformIO: Flash firmware (NO build run)", + "commands": [ + { + "id": "platformio-ide.runPIOCoreCommand", + "args": "pio run -t nobuild -t factory_flash -e ${command:platformio-ide.activeEnvironment}" + } + ] + }, + { + "text": "$(zap)", + "tooltip": "PlatformIO: Build and Upload", + "commands": "platformio-ide.upload" + }, + { + "text": "$(flame)", + "tooltip": "PlatformIO: Build, Erase and Upload", + "commands": [ + { + "id": "platformio-ide.runPIOCoreCommand", + "args": "pio run -t erase_upload -e ${command:platformio-ide.activeEnvironment}" + } + ] + }, + { + "text": "$(error)", + "tooltip": "PlatformIO: Erase Flash", + "commands": [ + { + "id": "platformio-ide.runPIOCoreCommand", + "args": "pio run -t nobuild -t erase -e ${command:platformio-ide.activeEnvironment}" + } + ] + }, + { + "text": "$(arrow-right)", + "tooltip": "PlatformIO: Build, Upload and Monitor", + "commands": "platformio-ide.uploadAndMonitor" + }, + { + "text": "$(device-desktop)", + "tooltip": "PlatformIO: Serial Monitor", + "commands": "platformio-ide.serialMonitor" + }, + { + "text": "$(terminal)", + "tooltip": "PlatformIO: New Terminal", + "commands": "platformio-ide.newTerminal" + }, + { + "text": "$(refresh)", + "tooltip": "PlatformIO: Rebuild IntelliSense Index", + "commands": "platformio-ide.rebuildProjectIndex" + } + ] } \ No newline at end of file From 03edd53bfb42449c1e6a7752eb0ab6e578c09bd8 Mon Sep 17 00:00:00 2001 From: Mathieu CArbou Date: Sat, 31 Aug 2024 21:06:06 +0000 Subject: [PATCH 319/551] try gitpod... --- CODE_OF_CONDUCT.md | 129 +++++++++++++++++++++++++++++++++++++++++++++ README.md | 1 + docs/index.md | 1 + 3 files changed, 131 insertions(+) create mode 100644 CODE_OF_CONDUCT.md diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 000000000..0a5f91417 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,129 @@ + +# Contributor Covenant Code of Conduct + +## Our Pledge + +We as members, contributors, and leaders pledge to make participation in our +community a harassment-free experience for everyone, regardless of age, body +size, visible or invisible disability, ethnicity, sex characteristics, gender +identity and expression, level of experience, education, socio-economic status, +nationality, personal appearance, race, religion, or sexual identity +and orientation. + +We pledge to act and interact in ways that contribute to an open, welcoming, +diverse, inclusive, and healthy community. + +## Our Standards + +Examples of behavior that contributes to a positive environment for our +community include: + +* Demonstrating empathy and kindness toward other people +* Being respectful of differing opinions, viewpoints, and experiences +* Giving and gracefully accepting constructive feedback +* Accepting responsibility and apologizing to those affected by our mistakes, + and learning from the experience +* Focusing on what is best not just for us as individuals, but for the + overall community + +Examples of unacceptable behavior include: + +* The use of sexualized language or imagery, and sexual attention or + advances of any kind +* Trolling, insulting or derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or email + address, without their explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Enforcement Responsibilities + +Community leaders are responsible for clarifying and enforcing our standards of +acceptable behavior and will take appropriate and fair corrective action in +response to any behavior that they deem inappropriate, threatening, offensive, +or harmful. + +Community leaders have the right and responsibility to remove, edit, or reject +comments, commits, code, wiki edits, issues, and other contributions that are +not aligned to this Code of Conduct, and will communicate reasons for moderation +decisions when appropriate. + +## Scope + +This Code of Conduct applies within all community spaces, and also applies when +an individual is officially representing the community in public spaces. +Examples of representing our community include using an official e-mail address, +posting via an official social media account, or acting as an appointed +representative at an online or offline event. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported to the community leaders responsible for enforcement at +https://sidweb.nl/cms3/en/contact. +All complaints will be reviewed and investigated promptly and fairly. + +All community leaders are obligated to respect the privacy and security of the +reporter of any incident. + +## Enforcement Guidelines + +Community leaders will follow these Community Impact Guidelines in determining +the consequences for any action they deem in violation of this Code of Conduct: + +### 1. Correction + +**Community Impact**: Use of inappropriate language or other behavior deemed +unprofessional or unwelcome in the community. + +**Consequence**: A private, written warning from community leaders, providing +clarity around the nature of the violation and an explanation of why the +behavior was inappropriate. A public apology may be requested. + +### 2. Warning + +**Community Impact**: A violation through a single incident or series +of actions. + +**Consequence**: A warning with consequences for continued behavior. No +interaction with the people involved, including unsolicited interaction with +those enforcing the Code of Conduct, for a specified period of time. This +includes avoiding interactions in community spaces as well as external channels +like social media. Violating these terms may lead to a temporary or +permanent ban. + +### 3. Temporary Ban + +**Community Impact**: A serious violation of community standards, including +sustained inappropriate behavior. + +**Consequence**: A temporary ban from any sort of interaction or public +communication with the community for a specified period of time. No public or +private interaction with the people involved, including unsolicited interaction +with those enforcing the Code of Conduct, is allowed during this period. +Violating these terms may lead to a permanent ban. + +### 4. Permanent Ban + +**Community Impact**: Demonstrating a pattern of violation of community +standards, including sustained inappropriate behavior, harassment of an +individual, or aggression toward or disparagement of classes of individuals. + +**Consequence**: A permanent ban from any sort of public interaction within +the community. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], +version 2.0, available at +https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. + +Community Impact Guidelines were inspired by [Mozilla's code of conduct +enforcement ladder](https://github.com/mozilla/diversity). + +[homepage]: https://www.contributor-covenant.org + +For answers to common questions about this code of conduct, see the FAQ at +https://www.contributor-covenant.org/faq. Translations are available at +https://www.contributor-covenant.org/translations. diff --git a/README.md b/README.md index 6ca1d1e36..715671240 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,7 @@ [![License: LGPL 3.0](https://img.shields.io/badge/License-LGPL%203.0-yellow.svg)](https://opensource.org/license/lgpl-3-0/) [![Continuous Integration](https://github.com/mathieucarbou/ESPAsyncWebServer/actions/workflows/ci.yml/badge.svg)](https://github.com/mathieucarbou/ESPAsyncWebServer/actions/workflows/ci.yml) [![PlatformIO Registry](https://badges.registry.platformio.org/packages/mathieucarbou/library/ESPAsyncWebServer.svg)](https://registry.platformio.org/libraries/mathieucarbou/ESPAsyncWebServer) +[![Gitpod Ready-to-Code](https://img.shields.io/badge/Gitpod-Ready--to--Code-blue?logo=gitpod)](https://gitpod.io/#https://github.com/mathieucarbou/ESPAsyncWebServer) Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 and RP2040 Supports: WebSocket, SSE, Authentication, Arduino Json 7, File Upload, Static File serving, URL Rewrite, URL Redirect, etc. diff --git a/docs/index.md b/docs/index.md index 6ca1d1e36..715671240 100644 --- a/docs/index.md +++ b/docs/index.md @@ -3,6 +3,7 @@ [![License: LGPL 3.0](https://img.shields.io/badge/License-LGPL%203.0-yellow.svg)](https://opensource.org/license/lgpl-3-0/) [![Continuous Integration](https://github.com/mathieucarbou/ESPAsyncWebServer/actions/workflows/ci.yml/badge.svg)](https://github.com/mathieucarbou/ESPAsyncWebServer/actions/workflows/ci.yml) [![PlatformIO Registry](https://badges.registry.platformio.org/packages/mathieucarbou/library/ESPAsyncWebServer.svg)](https://registry.platformio.org/libraries/mathieucarbou/ESPAsyncWebServer) +[![Gitpod Ready-to-Code](https://img.shields.io/badge/Gitpod-Ready--to--Code-blue?logo=gitpod)](https://gitpod.io/#https://github.com/mathieucarbou/ESPAsyncWebServer) Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 and RP2040 Supports: WebSocket, SSE, Authentication, Arduino Json 7, File Upload, Static File serving, URL Rewrite, URL Redirect, etc. From ba0b0af776301b2da5782b5c89b8f49357d0b435 Mon Sep 17 00:00:00 2001 From: Mathieu CArbou Date: Sat, 31 Aug 2024 21:12:49 +0000 Subject: [PATCH 320/551] gitpod --- README.md | 3 +++ docs/index.md | 3 +++ 2 files changed, 6 insertions(+) diff --git a/README.md b/README.md index 715671240..42b9e27e4 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,10 @@ [![License: LGPL 3.0](https://img.shields.io/badge/License-LGPL%203.0-yellow.svg)](https://opensource.org/license/lgpl-3-0/) [![Continuous Integration](https://github.com/mathieucarbou/ESPAsyncWebServer/actions/workflows/ci.yml/badge.svg)](https://github.com/mathieucarbou/ESPAsyncWebServer/actions/workflows/ci.yml) + +[![Latest Release](https://img.shields.io/github/release/mathieucarbou/ESPAsyncWebServer.svg)](https://GitHub.com/mathieucarbou/ESPAsyncWebServer/releases/) [![PlatformIO Registry](https://badges.registry.platformio.org/packages/mathieucarbou/library/ESPAsyncWebServer.svg)](https://registry.platformio.org/libraries/mathieucarbou/ESPAsyncWebServer) + [![Gitpod Ready-to-Code](https://img.shields.io/badge/Gitpod-Ready--to--Code-blue?logo=gitpod)](https://gitpod.io/#https://github.com/mathieucarbou/ESPAsyncWebServer) Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 and RP2040 diff --git a/docs/index.md b/docs/index.md index 715671240..42b9e27e4 100644 --- a/docs/index.md +++ b/docs/index.md @@ -2,7 +2,10 @@ [![License: LGPL 3.0](https://img.shields.io/badge/License-LGPL%203.0-yellow.svg)](https://opensource.org/license/lgpl-3-0/) [![Continuous Integration](https://github.com/mathieucarbou/ESPAsyncWebServer/actions/workflows/ci.yml/badge.svg)](https://github.com/mathieucarbou/ESPAsyncWebServer/actions/workflows/ci.yml) + +[![Latest Release](https://img.shields.io/github/release/mathieucarbou/ESPAsyncWebServer.svg)](https://GitHub.com/mathieucarbou/ESPAsyncWebServer/releases/) [![PlatformIO Registry](https://badges.registry.platformio.org/packages/mathieucarbou/library/ESPAsyncWebServer.svg)](https://registry.platformio.org/libraries/mathieucarbou/ESPAsyncWebServer) + [![Gitpod Ready-to-Code](https://img.shields.io/badge/Gitpod-Ready--to--Code-blue?logo=gitpod)](https://gitpod.io/#https://github.com/mathieucarbou/ESPAsyncWebServer) Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 and RP2040 From 0f7c4b85d56146491fcc9a5fd9956a61c63e9755 Mon Sep 17 00:00:00 2001 From: Mathieu CArbou Date: Sat, 31 Aug 2024 21:40:32 +0000 Subject: [PATCH 321/551] extensions --- .gitignore | 1 + .vscode/extensions.json | 10 ++++++++++ 2 files changed, 11 insertions(+) create mode 100644 .vscode/extensions.json diff --git a/.gitignore b/.gitignore index 4ac15a42d..ac811d1cd 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,5 @@ /.pio /.vscode/* !/.vscode/settings.json +!/.vscode/extensions.json /logs diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 000000000..e29ee0f18 --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,10 @@ +{ + // See http://go.microsoft.com/fwlink/?LinkId=827846 + // for the documentation about the extensions.json format + "recommendations": [ + "platformio.platformio-ide" + ], + "unwantedRecommendations": [ + "ms-vscode.cpptools-extension-pack" + ] +} \ No newline at end of file From 504231c96ff4e9640165f0b3388852eba0b985f3 Mon Sep 17 00:00:00 2001 From: Mathieu CArbou Date: Sat, 31 Aug 2024 21:57:01 +0000 Subject: [PATCH 322/551] Update gitpod files --- .gitpod.yml | 2 +- .vscode/settings.json | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.gitpod.yml b/.gitpod.yml index 29092a33d..74917c2c7 100644 --- a/.gitpod.yml +++ b/.gitpod.yml @@ -1,5 +1,5 @@ tasks: - - command: pip install --upgrade pip && pip install -U platformio && platformio run -t clean -e arduino-3 + - command: pip install --upgrade pip && pip install -U platformio && platformio run -e arduino-3 image: file: .gitpod.Dockerfile diff --git a/.vscode/settings.json b/.vscode/settings.json index 1e48fc2af..ccaf07fdc 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -70,5 +70,6 @@ "tooltip": "PlatformIO: Rebuild IntelliSense Index", "commands": "platformio-ide.rebuildProjectIndex" } - ] + ], + "git.allowForcePush": true } \ No newline at end of file From f0402e5a6e6abdb4e540bdbd5a992bdc12785eb3 Mon Sep 17 00:00:00 2001 From: Mathieu CArbou Date: Sat, 31 Aug 2024 21:39:27 +0000 Subject: [PATCH 323/551] Close #77: Allow modification of hardcoded headers --- examples/SimpleServer/SimpleServer.ino | 21 ++++++++++++ src/ESPAsyncWebServer.h | 5 +-- src/WebResponses.cpp | 45 ++++++++++++++++++++------ src/literals.h | 4 +-- 4 files changed, 61 insertions(+), 14 deletions(-) diff --git a/examples/SimpleServer/SimpleServer.ino b/examples/SimpleServer/SimpleServer.ino index 68cf5effb..21192429d 100644 --- a/examples/SimpleServer/SimpleServer.ino +++ b/examples/SimpleServer/SimpleServer.ino @@ -61,6 +61,27 @@ void setup() { request->send(LittleFS, "/index.html"); }); + /* + ❯ curl -I -X HEAD http://192.168.4.1/download + HTTP/1.1 200 OK + Content-Length: 1024 + Content-Type: application/octet-stream + Connection: close + Accept-Ranges: bytes + */ + // Ref: https://github.com/mathieucarbou/ESPAsyncWebServer/pull/80 + server.on("/download", HTTP_HEAD | HTTP_GET, [](AsyncWebServerRequest* request) { + if (request->method() == HTTP_HEAD) { + AsyncWebServerResponse* response = request->beginResponse(200, "application/octet-stream"); + response->setContentLength(1024); // myFile.getSize() + response->addHeader("Accept-Ranges", "bytes"); + // ... + request->send(response); + } else { + // ... + } + }); + // Send a GET request to /get?message= server.on("/get", HTTP_GET, [](AsyncWebServerRequest* request) { String message; diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index 3d6359aa8..54ba1b2c5 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -581,8 +581,9 @@ class AsyncWebServerResponse { virtual void setContentLength(size_t len); void setContentType(const String& type) { setContentType(type.c_str()); } virtual void setContentType(const char* type); - virtual void addHeader(const char* name, const char* value); - void addHeader(const String& name, const String& value) { addHeader(name.c_str(), value.c_str()); } + virtual bool addHeader(const char* name, const char* value, bool replaceExisting = true); + bool addHeader(const String& name, const String& value, bool replaceExisting = true) { return addHeader(name.c_str(), value.c_str(), replaceExisting); } + virtual bool removeHeader(const char* name); virtual String _assembleHead(uint8_t version); virtual bool _started() const; virtual bool _finished() const; diff --git a/src/WebResponses.cpp b/src/WebResponses.cpp index f1994b116..af9c349ef 100644 --- a/src/WebResponses.cpp +++ b/src/WebResponses.cpp @@ -239,18 +239,43 @@ void AsyncWebServerResponse::setContentType(const char* type) { _contentType = type; } -void AsyncWebServerResponse::addHeader(const char* name, const char* value) { +bool AsyncWebServerResponse::removeHeader(const char* name) { + for (auto i = _headers.begin(); i != _headers.end(); ++i) { + if (i->name().equalsIgnoreCase(name)) { + _headers.erase(i); + return true; + } + } + return false; +} + +bool AsyncWebServerResponse::addHeader(const char* name, const char* value, bool replaceExisting) { + for (auto i = _headers.begin(); i != _headers.end(); ++i) { + if (i->name().equalsIgnoreCase(name)) { + // header already set + if (replaceExisting) { + // remove, break and add the new one + _headers.erase(i); + break; + } else { + // do not update + return false; + } + } + } + // header was not found found, or existing one was removed _headers.emplace_back(name, value); + return true; } String AsyncWebServerResponse::_assembleHead(uint8_t version) { if (version) { - addHeader(T_Accept_Ranges, T_none); + addHeader(T_Accept_Ranges, T_none, false); if (_chunked) - addHeader(Transfer_Encoding, T_chunked); + addHeader(T_Transfer_Encoding, T_chunked, false); } String out; - int bufSize = 300; + constexpr size_t bufSize = 300; char buf[bufSize]; #ifndef ESP8266 @@ -307,7 +332,7 @@ AsyncBasicResponse::AsyncBasicResponse(int code, const char* contentType, const if (!_contentType.length()) _contentType = T_text_plain; } - addHeader(T_Connection, T_close); + addHeader(T_Connection, T_close, false); } void AsyncBasicResponse::_respond(AsyncWebServerRequest* request) { @@ -385,7 +410,7 @@ AsyncAbstractResponse::AsyncAbstractResponse(AwsTemplateProcessor callback) : _c } void AsyncAbstractResponse::_respond(AsyncWebServerRequest* request) { - addHeader(T_Connection, T_close); + addHeader(T_Connection, T_close, false); _head = _assembleHead(request->version()); _state = RESPONSE_HEADERS; _ack(request, 0, 0); @@ -663,7 +688,7 @@ AsyncFileResponse::AsyncFileResponse(FS& fs, const String& path, const char* con if (!download && !fs.exists(_path) && fs.exists(_path + T__gz)) { _path = _path + T__gz; - addHeader(T_Content_Encoding, T_gzip); + addHeader(T_Content_Encoding, T_gzip, false); _callback = nullptr; // Unable to process zipped templates _sendContentLength = true; _chunked = false; @@ -688,7 +713,7 @@ AsyncFileResponse::AsyncFileResponse(FS& fs, const String& path, const char* con // set filename and force rendering snprintf_P(buf, sizeof(buf), PSTR("inline")); } - addHeader(T_Content_Disposition, buf); + addHeader(T_Content_Disposition, buf, false); } AsyncFileResponse::AsyncFileResponse(File content, const String& path, const char* contentType, bool download, AwsTemplateProcessor callback) : AsyncAbstractResponse(callback) { @@ -696,7 +721,7 @@ AsyncFileResponse::AsyncFileResponse(File content, const String& path, const cha _path = path; if (!download && String(content.name()).endsWith(T__gz) && !path.endsWith(T__gz)) { - addHeader(T_Content_Encoding, T_gzip); + addHeader(T_Content_Encoding, T_gzip, false); _callback = nullptr; // Unable to process gzipped templates _sendContentLength = true; _chunked = false; @@ -719,7 +744,7 @@ AsyncFileResponse::AsyncFileResponse(File content, const String& path, const cha } else { snprintf_P(buf, sizeof(buf), PSTR("inline")); } - addHeader(T_Content_Disposition, buf); + addHeader(T_Content_Disposition, buf, false); } size_t AsyncFileResponse::_fillBuffer(uint8_t* data, size_t len) { diff --git a/src/literals.h b/src/literals.h index 8a7293bc3..40b596ae3 100644 --- a/src/literals.h +++ b/src/literals.h @@ -41,7 +41,7 @@ static constexpr const char* T_none = "none"; static constexpr const char* T_UPGRADE = "Upgrade"; static constexpr const char* T_WS = "websocket"; static constexpr const char* T_WWW_AUTH = "WWW-Authenticate"; -static constexpr const char* Transfer_Encoding = "Transfer-Encoding"; +static constexpr const char* T_Transfer_Encoding = "Transfer-Encoding"; // HTTP Methods static constexpr const char* T_ANY = "ANY"; @@ -210,7 +210,7 @@ static const char T_none[] PROGMEM = "none"; static const char T_UPGRADE[] PROGMEM = "Upgrade"; static const char T_WS[] PROGMEM = "websocket"; static const char T_WWW_AUTH[] PROGMEM = "WWW-Authenticate"; -static const char Transfer_Encoding[] PROGMEM = "Transfer-Encoding"; +static const char T_Transfer_Encoding[] PROGMEM = "Transfer-Encoding"; // HTTP Methods static const char T_ANY[] PROGMEM = "ANY"; From e719d74e1d512c82bb16658dd051279a1dd4fb26 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Sun, 1 Sep 2024 23:01:15 +0200 Subject: [PATCH 324/551] v3.2.0 --- .vscode/extensions.json | 2 +- README.md | 2 +- docs/index.md | 2 +- library.json | 2 +- library.properties | 2 +- src/ESPAsyncWebServer.h | 6 +++--- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.vscode/extensions.json b/.vscode/extensions.json index e29ee0f18..080e70d08 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -7,4 +7,4 @@ "unwantedRecommendations": [ "ms-vscode.cpptools-extension-pack" ] -} \ No newline at end of file +} diff --git a/README.md b/README.md index 42b9e27e4..6618c7485 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo **WARNING** The library name was changed from `ESP Async WebServer` to `ESPAsyncWebServer` as per the Arduino Lint recommendations. ``` -mathieucarbou/ESPAsyncWebServer @ 3.1.5 +mathieucarbou/ESPAsyncWebServer @ 3.2.0 ``` Dependency: diff --git a/docs/index.md b/docs/index.md index 42b9e27e4..6618c7485 100644 --- a/docs/index.md +++ b/docs/index.md @@ -18,7 +18,7 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo **WARNING** The library name was changed from `ESP Async WebServer` to `ESPAsyncWebServer` as per the Arduino Lint recommendations. ``` -mathieucarbou/ESPAsyncWebServer @ 3.1.5 +mathieucarbou/ESPAsyncWebServer @ 3.2.0 ``` Dependency: diff --git a/library.json b/library.json index eb946c67c..f2a6ed068 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "ESPAsyncWebServer", - "version": "3.1.5", + "version": "3.2.0", "description": "Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 and RP2040. Supports: WebSocket, SSE, Authentication, Arduino Json 7, File Upload, Static File serving, URL Rewrite, URL Redirect, etc.", "keywords": "http,async,websocket,webserver", "homepage": "https://github.com/mathieucarbou/ESPAsyncWebServer", diff --git a/library.properties b/library.properties index 3036044c6..46dac8670 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=ESPAsyncWebServer -version=3.1.5 +version=3.2.0 author=Me-No-Dev maintainer=Mathieu Carbou sentence=Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 and RP2040 diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index 54ba1b2c5..d0790d5bc 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -45,10 +45,10 @@ #include "literals.h" -#define ASYNCWEBSERVER_VERSION "3.1.5" +#define ASYNCWEBSERVER_VERSION "3.2.0" #define ASYNCWEBSERVER_VERSION_MAJOR 3 -#define ASYNCWEBSERVER_VERSION_MINOR 1 -#define ASYNCWEBSERVER_VERSION_REVISION 5 +#define ASYNCWEBSERVER_VERSION_MINOR 2 +#define ASYNCWEBSERVER_VERSION_REVISION 0 #define ASYNCWEBSERVER_FORK_mathieucarbou #ifdef ASYNCWEBSERVER_REGEX From 062a521c309c3ea59e91ee834340a877abdf8c2b Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Sun, 1 Sep 2024 23:23:51 +0200 Subject: [PATCH 325/551] update vscode file --- .vscode/settings.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index ccaf07fdc..1e48fc2af 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -70,6 +70,5 @@ "tooltip": "PlatformIO: Rebuild IntelliSense Index", "commands": "platformio-ide.rebuildProjectIndex" } - ], - "git.allowForcePush": true + ] } \ No newline at end of file From 837a38b7e7415b54330713c3f796dfd3a9b5d11c Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Sun, 1 Sep 2024 23:27:13 +0200 Subject: [PATCH 326/551] doc update --- README.md | 7 ++++--- docs/index.md | 7 ++++--- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 6618c7485..e0ff7f997 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,12 @@ # ESPAsyncWebServer -[![License: LGPL 3.0](https://img.shields.io/badge/License-LGPL%203.0-yellow.svg)](https://opensource.org/license/lgpl-3-0/) -[![Continuous Integration](https://github.com/mathieucarbou/ESPAsyncWebServer/actions/workflows/ci.yml/badge.svg)](https://github.com/mathieucarbou/ESPAsyncWebServer/actions/workflows/ci.yml) - [![Latest Release](https://img.shields.io/github/release/mathieucarbou/ESPAsyncWebServer.svg)](https://GitHub.com/mathieucarbou/ESPAsyncWebServer/releases/) [![PlatformIO Registry](https://badges.registry.platformio.org/packages/mathieucarbou/library/ESPAsyncWebServer.svg)](https://registry.platformio.org/libraries/mathieucarbou/ESPAsyncWebServer) +[![License: LGPL 3.0](https://img.shields.io/badge/License-LGPL%203.0-yellow.svg)](https://opensource.org/license/lgpl-3-0/) +[![Contributor Covenant](https://img.shields.io/badge/Contributor%20Covenant-2.1-4baaaa.svg)](code_of_conduct.md) + +[![Continuous Integration](https://github.com/mathieucarbou/ESPAsyncWebServer/actions/workflows/ci.yml/badge.svg)](https://github.com/mathieucarbou/ESPAsyncWebServer/actions/workflows/ci.yml) [![Gitpod Ready-to-Code](https://img.shields.io/badge/Gitpod-Ready--to--Code-blue?logo=gitpod)](https://gitpod.io/#https://github.com/mathieucarbou/ESPAsyncWebServer) Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 and RP2040 diff --git a/docs/index.md b/docs/index.md index 6618c7485..e0ff7f997 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,11 +1,12 @@ # ESPAsyncWebServer -[![License: LGPL 3.0](https://img.shields.io/badge/License-LGPL%203.0-yellow.svg)](https://opensource.org/license/lgpl-3-0/) -[![Continuous Integration](https://github.com/mathieucarbou/ESPAsyncWebServer/actions/workflows/ci.yml/badge.svg)](https://github.com/mathieucarbou/ESPAsyncWebServer/actions/workflows/ci.yml) - [![Latest Release](https://img.shields.io/github/release/mathieucarbou/ESPAsyncWebServer.svg)](https://GitHub.com/mathieucarbou/ESPAsyncWebServer/releases/) [![PlatformIO Registry](https://badges.registry.platformio.org/packages/mathieucarbou/library/ESPAsyncWebServer.svg)](https://registry.platformio.org/libraries/mathieucarbou/ESPAsyncWebServer) +[![License: LGPL 3.0](https://img.shields.io/badge/License-LGPL%203.0-yellow.svg)](https://opensource.org/license/lgpl-3-0/) +[![Contributor Covenant](https://img.shields.io/badge/Contributor%20Covenant-2.1-4baaaa.svg)](code_of_conduct.md) + +[![Continuous Integration](https://github.com/mathieucarbou/ESPAsyncWebServer/actions/workflows/ci.yml/badge.svg)](https://github.com/mathieucarbou/ESPAsyncWebServer/actions/workflows/ci.yml) [![Gitpod Ready-to-Code](https://img.shields.io/badge/Gitpod-Ready--to--Code-blue?logo=gitpod)](https://gitpod.io/#https://github.com/mathieucarbou/ESPAsyncWebServer) Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 and RP2040 From 71c0fa7a0caed563a4656267f75849b405151723 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Sun, 1 Sep 2024 23:30:38 +0200 Subject: [PATCH 327/551] doc update --- .github/workflows/ci.yml | 2 +- README.md | 3 ++- docs/index.md | 3 ++- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 60472d0e9..e4979d7b9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,6 +1,6 @@ # yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json -name: Continuous Integration +name: Build on: workflow_dispatch: diff --git a/README.md b/README.md index e0ff7f997..33580c6df 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,8 @@ [![License: LGPL 3.0](https://img.shields.io/badge/License-LGPL%203.0-yellow.svg)](https://opensource.org/license/lgpl-3-0/) [![Contributor Covenant](https://img.shields.io/badge/Contributor%20Covenant-2.1-4baaaa.svg)](code_of_conduct.md) -[![Continuous Integration](https://github.com/mathieucarbou/ESPAsyncWebServer/actions/workflows/ci.yml/badge.svg)](https://github.com/mathieucarbou/ESPAsyncWebServer/actions/workflows/ci.yml) +[![Build](https://github.com/mathieucarbou/ESPAsyncWebServer/actions/workflows/ci.yml/badge.svg)](https://github.com/mathieucarbou/ESPAsyncWebServer/actions/workflows/ci.yml) +[![GitHub latest commit](https://badgen.net/github/last-commit/mathieucarbou/YaSolR)](https://GitHub.com/mathieucarbou/YaSolR/commit/) [![Gitpod Ready-to-Code](https://img.shields.io/badge/Gitpod-Ready--to--Code-blue?logo=gitpod)](https://gitpod.io/#https://github.com/mathieucarbou/ESPAsyncWebServer) Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 and RP2040 diff --git a/docs/index.md b/docs/index.md index e0ff7f997..33580c6df 100644 --- a/docs/index.md +++ b/docs/index.md @@ -6,7 +6,8 @@ [![License: LGPL 3.0](https://img.shields.io/badge/License-LGPL%203.0-yellow.svg)](https://opensource.org/license/lgpl-3-0/) [![Contributor Covenant](https://img.shields.io/badge/Contributor%20Covenant-2.1-4baaaa.svg)](code_of_conduct.md) -[![Continuous Integration](https://github.com/mathieucarbou/ESPAsyncWebServer/actions/workflows/ci.yml/badge.svg)](https://github.com/mathieucarbou/ESPAsyncWebServer/actions/workflows/ci.yml) +[![Build](https://github.com/mathieucarbou/ESPAsyncWebServer/actions/workflows/ci.yml/badge.svg)](https://github.com/mathieucarbou/ESPAsyncWebServer/actions/workflows/ci.yml) +[![GitHub latest commit](https://badgen.net/github/last-commit/mathieucarbou/YaSolR)](https://GitHub.com/mathieucarbou/YaSolR/commit/) [![Gitpod Ready-to-Code](https://img.shields.io/badge/Gitpod-Ready--to--Code-blue?logo=gitpod)](https://gitpod.io/#https://github.com/mathieucarbou/ESPAsyncWebServer) Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 and RP2040 From e9583133ee2755a80787109016cfba08e996e1c3 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Mon, 2 Sep 2024 18:11:53 +0200 Subject: [PATCH 328/551] avoid another redirect --- src/ESPAsyncWebServer.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index d0790d5bc..2d1f100ec 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -372,11 +372,11 @@ class AsyncWebServerRequest { [[deprecated("Replaced by beginResponse(...)")]] AsyncWebServerResponse* beginResponse_P(int code, const String& contentType, const uint8_t* content, size_t len, AwsTemplateProcessor callback = nullptr) { - return beginResponse(code, contentType, content, len, callback); + return beginResponse(code, contentType.c_str(), content, len, callback); } [[deprecated("Replaced by beginResponse(...)")]] AsyncWebServerResponse* beginResponse_P(int code, const String& contentType, PGM_P content, AwsTemplateProcessor callback = nullptr) { - return beginResponse(code, contentType, content, callback); + return beginResponse(code, contentType.c_str(), content, callback); } #ifdef ESP8266 From 4f25782aa36858956bf80b1431af0618d1126f12 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Mon, 2 Sep 2024 21:41:05 +0200 Subject: [PATCH 329/551] cleanup vscode files --- .vscode/extensions.json | 10 ------ .vscode/settings.json | 74 ----------------------------------------- 2 files changed, 84 deletions(-) delete mode 100644 .vscode/extensions.json delete mode 100644 .vscode/settings.json diff --git a/.vscode/extensions.json b/.vscode/extensions.json deleted file mode 100644 index 080e70d08..000000000 --- a/.vscode/extensions.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - // See http://go.microsoft.com/fwlink/?LinkId=827846 - // for the documentation about the extensions.json format - "recommendations": [ - "platformio.platformio-ide" - ], - "unwantedRecommendations": [ - "ms-vscode.cpptools-extension-pack" - ] -} diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index 1e48fc2af..000000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,74 +0,0 @@ -{ - "platformio-ide.toolbar": [ - { - "text": "$(home)", - "tooltip": "PlatformIO: Home", - "commands": "platformio-ide.showHome" - }, - { - "text": "$(trash)", - "tooltip": "PlatformIO: Clean", - "commands": "platformio-ide.clean" - }, - { - "text": "$(check)", - "tooltip": "PlatformIO: Build", - "commands": "platformio-ide.build" - }, - { - "text": "Upload", - "tooltip": "PlatformIO: Flash firmware (NO build run)", - "commands": [ - { - "id": "platformio-ide.runPIOCoreCommand", - "args": "pio run -t nobuild -t factory_flash -e ${command:platformio-ide.activeEnvironment}" - } - ] - }, - { - "text": "$(zap)", - "tooltip": "PlatformIO: Build and Upload", - "commands": "platformio-ide.upload" - }, - { - "text": "$(flame)", - "tooltip": "PlatformIO: Build, Erase and Upload", - "commands": [ - { - "id": "platformio-ide.runPIOCoreCommand", - "args": "pio run -t erase_upload -e ${command:platformio-ide.activeEnvironment}" - } - ] - }, - { - "text": "$(error)", - "tooltip": "PlatformIO: Erase Flash", - "commands": [ - { - "id": "platformio-ide.runPIOCoreCommand", - "args": "pio run -t nobuild -t erase -e ${command:platformio-ide.activeEnvironment}" - } - ] - }, - { - "text": "$(arrow-right)", - "tooltip": "PlatformIO: Build, Upload and Monitor", - "commands": "platformio-ide.uploadAndMonitor" - }, - { - "text": "$(device-desktop)", - "tooltip": "PlatformIO: Serial Monitor", - "commands": "platformio-ide.serialMonitor" - }, - { - "text": "$(terminal)", - "tooltip": "PlatformIO: New Terminal", - "commands": "platformio-ide.newTerminal" - }, - { - "text": "$(refresh)", - "tooltip": "PlatformIO: Rebuild IntelliSense Index", - "commands": "platformio-ide.rebuildProjectIndex" - } - ] -} \ No newline at end of file From f9cfba335189ab797b596219399e36abfd8201d6 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Mon, 2 Sep 2024 22:39:49 +0200 Subject: [PATCH 330/551] Fix header handling versus internal handling of content-type and content-length (Fix #86) --- examples/SimpleServer/SimpleServer.ino | 7 ++- src/AsyncEventSource.cpp | 3 +- src/AsyncWebSocket.cpp | 3 +- src/ESPAsyncWebServer.h | 17 +++++- src/WebRequest.cpp | 1 - src/WebResponses.cpp | 84 ++++++++++++++++---------- 6 files changed, 76 insertions(+), 39 deletions(-) diff --git a/examples/SimpleServer/SimpleServer.ino b/examples/SimpleServer/SimpleServer.ino index 21192429d..fd53639ef 100644 --- a/examples/SimpleServer/SimpleServer.ino +++ b/examples/SimpleServer/SimpleServer.ino @@ -73,8 +73,11 @@ void setup() { server.on("/download", HTTP_HEAD | HTTP_GET, [](AsyncWebServerRequest* request) { if (request->method() == HTTP_HEAD) { AsyncWebServerResponse* response = request->beginResponse(200, "application/octet-stream"); - response->setContentLength(1024); // myFile.getSize() - response->addHeader("Accept-Ranges", "bytes"); + response->addHeader(asyncsrv::T_Accept_Ranges, "bytes"); + response->addHeader(asyncsrv::T_Content_Length, 10); + response->setContentLength(1024); // overrides previous one + response->addHeader(asyncsrv::T_Content_Type, "foo"); + response->setContentType("application/octet-stream"); // overrides previous one // ... request->send(response); } else { diff --git a/src/AsyncEventSource.cpp b/src/AsyncEventSource.cpp index 639fd56d0..30ad27194 100644 --- a/src/AsyncEventSource.cpp +++ b/src/AsyncEventSource.cpp @@ -392,7 +392,8 @@ AsyncEventSourceResponse::AsyncEventSourceResponse(AsyncEventSource* server) { } void AsyncEventSourceResponse::_respond(AsyncWebServerRequest* request) { - String out = _assembleHead(request->version()); + String out; + _assembleHead(out, request->version()); request->client()->write(out.c_str(), _headLength); _state = RESPONSE_WAIT_ACK; } diff --git a/src/AsyncWebSocket.cpp b/src/AsyncWebSocket.cpp index 88d88ec85..a5c8d7b4f 100644 --- a/src/AsyncWebSocket.cpp +++ b/src/AsyncWebSocket.cpp @@ -1192,7 +1192,8 @@ void AsyncWebSocketResponse::_respond(AsyncWebServerRequest* request) { request->client()->close(true); return; } - String out(_assembleHead(request->version())); + String out; + _assembleHead(out, request->version()); request->client()->write(out.c_str(), _headLength); _state = RESPONSE_WAIT_ACK; } diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index 2d1f100ec..ff6b2fbcf 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -155,7 +155,9 @@ class AsyncWebHeader { const String& name() const { return _name; } const String& value() const { return _value; } String toString() const { - String str = _name; + String str; + str.reserve(_name.length() + _value.length() + 2); + str.concat(_name); str.concat((char)0x3a); str.concat((char)0x20); str.concat(_value); @@ -583,8 +585,19 @@ class AsyncWebServerResponse { virtual void setContentType(const char* type); virtual bool addHeader(const char* name, const char* value, bool replaceExisting = true); bool addHeader(const String& name, const String& value, bool replaceExisting = true) { return addHeader(name.c_str(), value.c_str(), replaceExisting); } + bool addHeader(const char* name, long value, bool replaceExisting = true) { return addHeader(name, String(value), replaceExisting); } + bool addHeader(const String& name, long value, bool replaceExisting = true) { return addHeader(name.c_str(), value, replaceExisting); } virtual bool removeHeader(const char* name); - virtual String _assembleHead(uint8_t version); + virtual const AsyncWebHeader* getHeader(const char* name) const; + + [[deprecated("Use instead: _assembleHead(String& buffer, uint8_t version)")]] + String _assembleHead(uint8_t version) { + String buffer; + _assembleHead(buffer, version); + return buffer; + } + virtual void _assembleHead(String& buffer, uint8_t version); + virtual bool _started() const; virtual bool _finished() const; virtual bool _failed() const; diff --git a/src/WebRequest.cpp b/src/WebRequest.cpp index 95fda7eb1..022911e85 100644 --- a/src/WebRequest.cpp +++ b/src/WebRequest.cpp @@ -624,7 +624,6 @@ bool AsyncWebServerRequest::hasHeader(const __FlashStringHelper* data) const { const AsyncWebHeader* AsyncWebServerRequest::getHeader(const char* name) const { auto iter = std::find_if(std::begin(_headers), std::end(_headers), [&name](const AsyncWebHeader& header) { return header.name().equalsIgnoreCase(name); }); - return (iter == std::end(_headers)) ? nullptr : &(*iter); } diff --git a/src/WebResponses.cpp b/src/WebResponses.cpp index af9c349ef..e3fbfd16d 100644 --- a/src/WebResponses.cpp +++ b/src/WebResponses.cpp @@ -125,9 +125,8 @@ const char* AsyncWebServerResponse::responseCodeToString(int code) { return T_HTTP_CODE_ANY; } } -#else // ESP8266 -const __FlashStringHelper* AsyncWebServerResponse::responseCodeToString(int code) -{ +#else // ESP8266 +const __FlashStringHelper* AsyncWebServerResponse::responseCodeToString(int code) { switch (code) { case 100: return FPSTR(T_HTTP_CODE_100); @@ -230,12 +229,12 @@ void AsyncWebServerResponse::setCode(int code) { } void AsyncWebServerResponse::setContentLength(size_t len) { - if (_state == RESPONSE_SETUP) + if (_state == RESPONSE_SETUP && addHeader(T_Content_Length, len, true)) _contentLength = len; } void AsyncWebServerResponse::setContentType(const char* type) { - if (_state == RESPONSE_SETUP) + if (_state == RESPONSE_SETUP && addHeader(T_Content_Type, type, true)) _contentType = type; } @@ -249,6 +248,11 @@ bool AsyncWebServerResponse::removeHeader(const char* name) { return false; } +const AsyncWebHeader* AsyncWebServerResponse::getHeader(const char* name) const { + auto iter = std::find_if(std::begin(_headers), std::end(_headers), [&name](const AsyncWebHeader& header) { return header.name().equalsIgnoreCase(name); }); + return (iter == std::end(_headers)) ? nullptr : &(*iter); +} + bool AsyncWebServerResponse::addHeader(const char* name, const char* value, bool replaceExisting) { for (auto i = _headers.begin(); i != _headers.end(); ++i) { if (i->name().equalsIgnoreCase(name)) { @@ -268,41 +272,56 @@ bool AsyncWebServerResponse::addHeader(const char* name, const char* value, bool return true; } -String AsyncWebServerResponse::_assembleHead(uint8_t version) { +void AsyncWebServerResponse::_assembleHead(String& buffer, uint8_t version) { if (version) { addHeader(T_Accept_Ranges, T_none, false); if (_chunked) addHeader(T_Transfer_Encoding, T_chunked, false); } - String out; - constexpr size_t bufSize = 300; - char buf[bufSize]; -#ifndef ESP8266 - snprintf(buf, bufSize, "HTTP/1.%d %d %s\r\n", version, _code, responseCodeToString(_code)); -#else - snprintf_P(buf, bufSize, PSTR("HTTP/1.%d %d %s\r\n"), version, _code, String(responseCodeToString(_code)).c_str()); -#endif - out.concat(buf); + if (_sendContentLength) + addHeader(T_Content_Length, String(_contentLength), false); - if (_sendContentLength) { - snprintf_P(buf, bufSize, PSTR("Content-Length: %d\r\n"), _contentLength); - out.concat(buf); - } - if (_contentType.length()) { - snprintf_P(buf, bufSize, PSTR("Content-Type: %s\r\n"), _contentType.c_str()); - out.concat(buf); - } + if (_contentType.length()) + addHeader(T_Content_Type, _contentType.c_str(), false); + + // precompute buffer size to avoid reallocations by String class + size_t len = 0; + len += 50; // HTTP/1.1 200 \r\n + for (const auto& header : _headers) + len += header.name().length() + header.value().length() + 4; + // prepare buffer + buffer.reserve(len); + + // HTTP header +#ifdef ESP8266 + buffer.concat(PSTR("HTTP/1.")); +#else + buffer.concat("HTTP/1."); +#endif + buffer.concat(version); + buffer.concat(' '); + buffer.concat(_code); + buffer.concat(' '); + buffer.concat(responseCodeToString(_code)); + buffer.concat(T_rn); + + // Add headers for (const auto& header : _headers) { - snprintf_P(buf, bufSize, PSTR("%s: %s\r\n"), header.name().c_str(), header.value().c_str()); - out.concat(buf); + buffer.concat(header.name()); +#ifdef ESP8266 + buffer.concat(PSTR(": ")); +#else + buffer.concat(": "); +#endif + buffer.concat(header.value()); + buffer.concat(T_rn); } _headers.clear(); - out.concat(T_rn); - _headLength = out.length(); - return out; + buffer.concat(T_rn); + _headLength = buffer.length(); } bool AsyncWebServerResponse::_started() const { return _state > RESPONSE_SETUP; } @@ -337,7 +356,8 @@ AsyncBasicResponse::AsyncBasicResponse(int code, const char* contentType, const void AsyncBasicResponse::_respond(AsyncWebServerRequest* request) { _state = RESPONSE_HEADERS; - String out = _assembleHead(request->version()); + String out; + _assembleHead(out, request->version()); size_t outLen = out.length(); size_t space = request->client()->space(); if (!_contentLength && space >= outLen) { @@ -411,7 +431,7 @@ AsyncAbstractResponse::AsyncAbstractResponse(AwsTemplateProcessor callback) : _c void AsyncAbstractResponse::_respond(AsyncWebServerRequest* request) { addHeader(T_Connection, T_close, false); - _head = _assembleHead(request->version()); + _assembleHead(_head, request->version()); _state = RESPONSE_HEADERS; _ack(request, 0, 0); } @@ -635,9 +655,9 @@ AsyncFileResponse::~AsyncFileResponse() { void AsyncFileResponse::_setContentTypeFromPath(const String& path) { #if HAVE_EXTERN_GET_Content_Type_FUNCTION #ifndef ESP8266 - extern const char* getContentType(const String& path); + extern const char* getContentType(const String& path); #else - extern const __FlashStringHelper* getContentType(const String& path); + extern const __FlashStringHelper* getContentType(const String& path); #endif _contentType = getContentType(path); #else From 0f71c519a73f869364f373eae2ca24af9dcd18a0 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Tue, 3 Sep 2024 11:48:19 +0200 Subject: [PATCH 331/551] v3.2.1 --- .gitignore | 2 -- README.md | 4 ++-- docs/index.md | 4 ++-- library.json | 2 +- library.properties | 2 +- src/ESPAsyncWebServer.h | 4 ++-- 6 files changed, 8 insertions(+), 10 deletions(-) diff --git a/.gitignore b/.gitignore index ac811d1cd..5a252ab80 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,4 @@ .lh /.pio /.vscode/* -!/.vscode/settings.json -!/.vscode/extensions.json /logs diff --git a/README.md b/README.md index 33580c6df..dda295b6a 100644 --- a/README.md +++ b/README.md @@ -20,12 +20,12 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo **WARNING** The library name was changed from `ESP Async WebServer` to `ESPAsyncWebServer` as per the Arduino Lint recommendations. ``` -mathieucarbou/ESPAsyncWebServer @ 3.2.0 +mathieucarbou/ESPAsyncWebServer @ 3.2.1 ``` Dependency: -- **ESP32**: `mathieucarbou/AsyncTCP @ 3.2.4` (Arduino IDE: [https://github.com/mathieucarbou/AsyncTCP#v3.2.4](https://github.com/mathieucarbou/AsyncTCP/releases/tag/v3.2.0)) +- **ESP32**: `mathieucarbou/AsyncTCP @ 3.2.4` (Arduino IDE: [https://github.com/mathieucarbou/AsyncTCP#v3.2.4](https://github.com/mathieucarbou/AsyncTCP/releases)) - **ESP8266**: `esphome/ESPAsyncTCP-esphome @ 2.0.0` (Arduino IDE: [https://github.com/mathieucarbou/esphome-ESPAsyncTCP#v2.0.0](https://github.com/mathieucarbou/esphome-ESPAsyncTCP/releases/tag/v2.0.0)) - **RP2040**: `khoih-prog/AsyncTCP_RP2040W @ 1.2.0` (Arduino IDE: [https://github.com/khoih-prog/AsyncTCP_RP2040W#v1.2.0](https://github.com/khoih-prog/AsyncTCP_RP2040W/releases/tag/v1.2.0)) diff --git a/docs/index.md b/docs/index.md index 33580c6df..dda295b6a 100644 --- a/docs/index.md +++ b/docs/index.md @@ -20,12 +20,12 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo **WARNING** The library name was changed from `ESP Async WebServer` to `ESPAsyncWebServer` as per the Arduino Lint recommendations. ``` -mathieucarbou/ESPAsyncWebServer @ 3.2.0 +mathieucarbou/ESPAsyncWebServer @ 3.2.1 ``` Dependency: -- **ESP32**: `mathieucarbou/AsyncTCP @ 3.2.4` (Arduino IDE: [https://github.com/mathieucarbou/AsyncTCP#v3.2.4](https://github.com/mathieucarbou/AsyncTCP/releases/tag/v3.2.0)) +- **ESP32**: `mathieucarbou/AsyncTCP @ 3.2.4` (Arduino IDE: [https://github.com/mathieucarbou/AsyncTCP#v3.2.4](https://github.com/mathieucarbou/AsyncTCP/releases)) - **ESP8266**: `esphome/ESPAsyncTCP-esphome @ 2.0.0` (Arduino IDE: [https://github.com/mathieucarbou/esphome-ESPAsyncTCP#v2.0.0](https://github.com/mathieucarbou/esphome-ESPAsyncTCP/releases/tag/v2.0.0)) - **RP2040**: `khoih-prog/AsyncTCP_RP2040W @ 1.2.0` (Arduino IDE: [https://github.com/khoih-prog/AsyncTCP_RP2040W#v1.2.0](https://github.com/khoih-prog/AsyncTCP_RP2040W/releases/tag/v1.2.0)) diff --git a/library.json b/library.json index f2a6ed068..07df74310 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "ESPAsyncWebServer", - "version": "3.2.0", + "version": "3.2.1", "description": "Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 and RP2040. Supports: WebSocket, SSE, Authentication, Arduino Json 7, File Upload, Static File serving, URL Rewrite, URL Redirect, etc.", "keywords": "http,async,websocket,webserver", "homepage": "https://github.com/mathieucarbou/ESPAsyncWebServer", diff --git a/library.properties b/library.properties index 46dac8670..df037ca8f 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=ESPAsyncWebServer -version=3.2.0 +version=3.2.1 author=Me-No-Dev maintainer=Mathieu Carbou sentence=Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 and RP2040 diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index ff6b2fbcf..a6085e832 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -45,10 +45,10 @@ #include "literals.h" -#define ASYNCWEBSERVER_VERSION "3.2.0" +#define ASYNCWEBSERVER_VERSION "3.2.1" #define ASYNCWEBSERVER_VERSION_MAJOR 3 #define ASYNCWEBSERVER_VERSION_MINOR 2 -#define ASYNCWEBSERVER_VERSION_REVISION 0 +#define ASYNCWEBSERVER_VERSION_REVISION 1 #define ASYNCWEBSERVER_FORK_mathieucarbou #ifdef ASYNCWEBSERVER_REGEX From 9c0fb7a98a100b016e9752df0d24eddf3c6bea69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=97=D0=B0=20=D0=9B=D1=83=D0=BF=D0=BE=D0=B9?= <130570371+zalupoi@users.noreply.github.com> Date: Wed, 12 Apr 2023 17:31:27 +0000 Subject: [PATCH 332/551] Fix RFC 7230 violation See https://github.com/nodejs/node/issues/47528 for more details See https://github.com/me-no-dev/ESPAsyncWebServer/pull/1301 for original PR from @zalupoi --- src/WebResponses.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/WebResponses.cpp b/src/WebResponses.cpp index e3fbfd16d..1fb6188ec 100644 --- a/src/WebResponses.cpp +++ b/src/WebResponses.cpp @@ -492,9 +492,7 @@ size_t AsyncAbstractResponse::_ack(AsyncWebServerRequest* request, size_t len, u free(buf); return 0; } - outLen = sprintf_P((char*)buf + headLen, PSTR("%x"), readLen) + headLen; - while (outLen < headLen + 4) - buf[outLen++] = ' '; + outLen = sprintf((char*)buf+headLen, "%04x", readLen) + headLen; buf[outLen++] = '\r'; buf[outLen++] = '\n'; outLen += readLen; From 7b2c732a3f9ba65426593cf088ea35149203bf0e Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Tue, 3 Sep 2024 12:12:46 +0200 Subject: [PATCH 333/551] v3.2.2 --- README.md | 2 +- docs/index.md | 2 +- library.json | 2 +- library.properties | 2 +- src/ESPAsyncWebServer.h | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index dda295b6a..541c362da 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo **WARNING** The library name was changed from `ESP Async WebServer` to `ESPAsyncWebServer` as per the Arduino Lint recommendations. ``` -mathieucarbou/ESPAsyncWebServer @ 3.2.1 +mathieucarbou/ESPAsyncWebServer @ 3.2.2 ``` Dependency: diff --git a/docs/index.md b/docs/index.md index dda295b6a..541c362da 100644 --- a/docs/index.md +++ b/docs/index.md @@ -20,7 +20,7 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo **WARNING** The library name was changed from `ESP Async WebServer` to `ESPAsyncWebServer` as per the Arduino Lint recommendations. ``` -mathieucarbou/ESPAsyncWebServer @ 3.2.1 +mathieucarbou/ESPAsyncWebServer @ 3.2.2 ``` Dependency: diff --git a/library.json b/library.json index 07df74310..f48b52e34 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "ESPAsyncWebServer", - "version": "3.2.1", + "version": "3.2.2", "description": "Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 and RP2040. Supports: WebSocket, SSE, Authentication, Arduino Json 7, File Upload, Static File serving, URL Rewrite, URL Redirect, etc.", "keywords": "http,async,websocket,webserver", "homepage": "https://github.com/mathieucarbou/ESPAsyncWebServer", diff --git a/library.properties b/library.properties index df037ca8f..727e92576 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=ESPAsyncWebServer -version=3.2.1 +version=3.2.2 author=Me-No-Dev maintainer=Mathieu Carbou sentence=Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 and RP2040 diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index a6085e832..697f31f93 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -45,10 +45,10 @@ #include "literals.h" -#define ASYNCWEBSERVER_VERSION "3.2.1" +#define ASYNCWEBSERVER_VERSION "3.2.2" #define ASYNCWEBSERVER_VERSION_MAJOR 3 #define ASYNCWEBSERVER_VERSION_MINOR 2 -#define ASYNCWEBSERVER_VERSION_REVISION 1 +#define ASYNCWEBSERVER_VERSION_REVISION 2 #define ASYNCWEBSERVER_FORK_mathieucarbou #ifdef ASYNCWEBSERVER_REGEX From c8f7c316bb15039ac9c2c15de9e538cf8cf6008a Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Tue, 3 Sep 2024 12:27:51 +0200 Subject: [PATCH 334/551] libs update --- .github/workflows/ci.yml | 2 +- README.md | 4 ++-- docs/index.md | 4 ++-- library.json | 2 +- platformio.ini | 12 ++++++------ 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e4979d7b9..e1e3c2752 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -55,7 +55,7 @@ jobs: - name: Install AsyncTCP (ESP32) if: ${{ matrix.core == 'esp32:esp32' }} - run: ARDUINO_LIBRARY_ENABLE_UNSAFE_INSTALL=true arduino-cli lib install --git-url https://github.com/mathieucarbou/AsyncTCP#v3.2.4 + run: ARDUINO_LIBRARY_ENABLE_UNSAFE_INSTALL=true arduino-cli lib install --git-url https://github.com/mathieucarbou/AsyncTCP#v3.2.5 - name: Install ESPAsyncTCP (ESP8266) if: ${{ matrix.core == 'esp8266:esp8266' }} diff --git a/README.md b/README.md index 541c362da..c4aaceec4 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ mathieucarbou/ESPAsyncWebServer @ 3.2.2 Dependency: -- **ESP32**: `mathieucarbou/AsyncTCP @ 3.2.4` (Arduino IDE: [https://github.com/mathieucarbou/AsyncTCP#v3.2.4](https://github.com/mathieucarbou/AsyncTCP/releases)) +- **ESP32**: `mathieucarbou/AsyncTCP @ 3.2.5` (Arduino IDE: [https://github.com/mathieucarbou/AsyncTCP#v3.2.5](https://github.com/mathieucarbou/AsyncTCP/releases)) - **ESP8266**: `esphome/ESPAsyncTCP-esphome @ 2.0.0` (Arduino IDE: [https://github.com/mathieucarbou/esphome-ESPAsyncTCP#v2.0.0](https://github.com/mathieucarbou/esphome-ESPAsyncTCP/releases/tag/v2.0.0)) - **RP2040**: `khoih-prog/AsyncTCP_RP2040W @ 1.2.0` (Arduino IDE: [https://github.com/khoih-prog/AsyncTCP_RP2040W#v1.2.0](https://github.com/khoih-prog/AsyncTCP_RP2040W/releases/tag/v1.2.0)) @@ -42,7 +42,7 @@ Dependency: - [@mathieucarbou](https://github.com/mathieucarbou): Arduino 3 / ESP-IDF 5.1 compatibility - [@mathieucarbou](https://github.com/mathieucarbou): Arduino Json 7 compatibility and backward compatible with 6 and 6 (changes in `AsyncJson.h`). The API to use Json has not changed. These are only internal changes. - [@mathieucarbou](https://github.com/mathieucarbou): CI -- [@mathieucarbou](https://github.com/mathieucarbou): Depends on `mathieucarbou/AsyncTCP @ 3.2.4` +- [@mathieucarbou](https://github.com/mathieucarbou): Depends on `mathieucarbou/AsyncTCP @ 3.2.5` - [@mathieucarbou](https://github.com/mathieucarbou): Deployed in PlatformIO registry and Arduino IDE library manager - [@mathieucarbou](https://github.com/mathieucarbou): Firmware size optimization: remove mbedtls dependency (accounts for 33KB in firmware) - [@mathieucarbou](https://github.com/mathieucarbou): Made DEFAULT_MAX_SSE_CLIENTS customizable diff --git a/docs/index.md b/docs/index.md index 541c362da..c4aaceec4 100644 --- a/docs/index.md +++ b/docs/index.md @@ -25,7 +25,7 @@ mathieucarbou/ESPAsyncWebServer @ 3.2.2 Dependency: -- **ESP32**: `mathieucarbou/AsyncTCP @ 3.2.4` (Arduino IDE: [https://github.com/mathieucarbou/AsyncTCP#v3.2.4](https://github.com/mathieucarbou/AsyncTCP/releases)) +- **ESP32**: `mathieucarbou/AsyncTCP @ 3.2.5` (Arduino IDE: [https://github.com/mathieucarbou/AsyncTCP#v3.2.5](https://github.com/mathieucarbou/AsyncTCP/releases)) - **ESP8266**: `esphome/ESPAsyncTCP-esphome @ 2.0.0` (Arduino IDE: [https://github.com/mathieucarbou/esphome-ESPAsyncTCP#v2.0.0](https://github.com/mathieucarbou/esphome-ESPAsyncTCP/releases/tag/v2.0.0)) - **RP2040**: `khoih-prog/AsyncTCP_RP2040W @ 1.2.0` (Arduino IDE: [https://github.com/khoih-prog/AsyncTCP_RP2040W#v1.2.0](https://github.com/khoih-prog/AsyncTCP_RP2040W/releases/tag/v1.2.0)) @@ -42,7 +42,7 @@ Dependency: - [@mathieucarbou](https://github.com/mathieucarbou): Arduino 3 / ESP-IDF 5.1 compatibility - [@mathieucarbou](https://github.com/mathieucarbou): Arduino Json 7 compatibility and backward compatible with 6 and 6 (changes in `AsyncJson.h`). The API to use Json has not changed. These are only internal changes. - [@mathieucarbou](https://github.com/mathieucarbou): CI -- [@mathieucarbou](https://github.com/mathieucarbou): Depends on `mathieucarbou/AsyncTCP @ 3.2.4` +- [@mathieucarbou](https://github.com/mathieucarbou): Depends on `mathieucarbou/AsyncTCP @ 3.2.5` - [@mathieucarbou](https://github.com/mathieucarbou): Deployed in PlatformIO registry and Arduino IDE library manager - [@mathieucarbou](https://github.com/mathieucarbou): Firmware size optimization: remove mbedtls dependency (accounts for 33KB in firmware) - [@mathieucarbou](https://github.com/mathieucarbou): Made DEFAULT_MAX_SSE_CLIENTS customizable diff --git a/library.json b/library.json index f48b52e34..7bfb727df 100644 --- a/library.json +++ b/library.json @@ -28,7 +28,7 @@ { "owner": "mathieucarbou", "name": "AsyncTCP", - "version": "^3.2.4", + "version": "^3.2.5", "platforms": "espressif32" }, { diff --git a/platformio.ini b/platformio.ini index 6ac85dda7..dd6527188 100644 --- a/platformio.ini +++ b/platformio.ini @@ -27,14 +27,14 @@ platform = espressif32 board = esp32dev lib_deps = bblanchon/ArduinoJson @ 7.1.0 - mathieucarbou/AsyncTCP @ 3.2.4 + mathieucarbou/AsyncTCP @ 3.2.5 [env:arduino-2] platform = espressif32@6.8.1 board = esp32dev lib_deps = bblanchon/ArduinoJson @ 7.1.0 - mathieucarbou/AsyncTCP @ 3.2.4 + mathieucarbou/AsyncTCP @ 3.2.5 [env:arduino-3] platform = espressif32 @@ -44,7 +44,7 @@ platform_packages= board = esp32dev lib_deps = bblanchon/ArduinoJson @ 7.1.0 - mathieucarbou/AsyncTCP @ 3.2.4 + mathieucarbou/AsyncTCP @ 3.2.5 [env:esp8266] platform = espressif8266 @@ -70,18 +70,18 @@ platform = https://github.com/pioarduino/platform-espressif32/releases/download/ board = esp32dev lib_deps = bblanchon/ArduinoJson @ 7.1.0 - mathieucarbou/AsyncTCP @ 3.2.4 + mathieucarbou/AsyncTCP @ 3.2.5 [env:pioarduino-c6] platform = https://github.com/pioarduino/platform-espressif32/releases/download/51.03.04/platform-espressif32.zip board = esp32-c6-devkitc-1 lib_deps = bblanchon/ArduinoJson @ 7.1.0 - mathieucarbou/AsyncTCP @ 3.2.4 + mathieucarbou/AsyncTCP @ 3.2.5 [env:pioarduino-h2] platform = https://github.com/pioarduino/platform-espressif32/releases/download/51.03.04/platform-espressif32.zip board = esp32-h2-devkitm-1 lib_deps = bblanchon/ArduinoJson @ 7.1.0 - mathieucarbou/AsyncTCP @ 3.2.4 + mathieucarbou/AsyncTCP @ 3.2.5 From bea255224ec120f0bd3f48cbdd349e61655670e7 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Tue, 3 Sep 2024 23:12:30 +0200 Subject: [PATCH 335/551] Cleanup unused code --- README.md | 1 - docs/index.md | 1 - src/AsyncEventSource.h | 8 -------- 3 files changed, 10 deletions(-) diff --git a/README.md b/README.md index c4aaceec4..853d8bd5c 100644 --- a/README.md +++ b/README.md @@ -45,7 +45,6 @@ Dependency: - [@mathieucarbou](https://github.com/mathieucarbou): Depends on `mathieucarbou/AsyncTCP @ 3.2.5` - [@mathieucarbou](https://github.com/mathieucarbou): Deployed in PlatformIO registry and Arduino IDE library manager - [@mathieucarbou](https://github.com/mathieucarbou): Firmware size optimization: remove mbedtls dependency (accounts for 33KB in firmware) -- [@mathieucarbou](https://github.com/mathieucarbou): Made DEFAULT_MAX_SSE_CLIENTS customizable - [@mathieucarbou](https://github.com/mathieucarbou): Made DEFAULT_MAX_WS_CLIENTS customizable - [@mathieucarbou](https://github.com/mathieucarbou): MessagePack Support ([#62](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/62)) - [@mathieucarbou](https://github.com/mathieucarbou): Remove filename after inline in Content-Disposition header according to RFC2183 diff --git a/docs/index.md b/docs/index.md index c4aaceec4..853d8bd5c 100644 --- a/docs/index.md +++ b/docs/index.md @@ -45,7 +45,6 @@ Dependency: - [@mathieucarbou](https://github.com/mathieucarbou): Depends on `mathieucarbou/AsyncTCP @ 3.2.5` - [@mathieucarbou](https://github.com/mathieucarbou): Deployed in PlatformIO registry and Arduino IDE library manager - [@mathieucarbou](https://github.com/mathieucarbou): Firmware size optimization: remove mbedtls dependency (accounts for 33KB in firmware) -- [@mathieucarbou](https://github.com/mathieucarbou): Made DEFAULT_MAX_SSE_CLIENTS customizable - [@mathieucarbou](https://github.com/mathieucarbou): Made DEFAULT_MAX_WS_CLIENTS customizable - [@mathieucarbou](https://github.com/mathieucarbou): MessagePack Support ([#62](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/62)) - [@mathieucarbou](https://github.com/mathieucarbou): Remove filename after inline in Content-Disposition header according to RFC2183 diff --git a/src/AsyncEventSource.h b/src/AsyncEventSource.h index 0289ebf8f..7a784d80d 100644 --- a/src/AsyncEventSource.h +++ b/src/AsyncEventSource.h @@ -49,14 +49,6 @@ #endif #endif -#ifndef DEFAULT_MAX_SSE_CLIENTS - #ifdef ESP32 - #define DEFAULT_MAX_SSE_CLIENTS 8 - #else - #define DEFAULT_MAX_SSE_CLIENTS 4 - #endif -#endif - class AsyncEventSource; class AsyncEventSourceResponse; class AsyncEventSourceClient; From c0ba0555ee563ed5f36f63ddbf16350878920596 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Wed, 4 Sep 2024 09:41:22 +0200 Subject: [PATCH 336/551] fix doc --- README.md | 2 +- docs/index.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 853d8bd5c..0b359f38b 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ [![Contributor Covenant](https://img.shields.io/badge/Contributor%20Covenant-2.1-4baaaa.svg)](code_of_conduct.md) [![Build](https://github.com/mathieucarbou/ESPAsyncWebServer/actions/workflows/ci.yml/badge.svg)](https://github.com/mathieucarbou/ESPAsyncWebServer/actions/workflows/ci.yml) -[![GitHub latest commit](https://badgen.net/github/last-commit/mathieucarbou/YaSolR)](https://GitHub.com/mathieucarbou/YaSolR/commit/) +[![GitHub latest commit](https://badgen.net/github/last-commit/mathieucarbou/ESPAsyncWebServer)](https://GitHub.com/mathieucarbou/ESPAsyncWebServer/commit/) [![Gitpod Ready-to-Code](https://img.shields.io/badge/Gitpod-Ready--to--Code-blue?logo=gitpod)](https://gitpod.io/#https://github.com/mathieucarbou/ESPAsyncWebServer) Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 and RP2040 diff --git a/docs/index.md b/docs/index.md index 853d8bd5c..0b359f38b 100644 --- a/docs/index.md +++ b/docs/index.md @@ -7,7 +7,7 @@ [![Contributor Covenant](https://img.shields.io/badge/Contributor%20Covenant-2.1-4baaaa.svg)](code_of_conduct.md) [![Build](https://github.com/mathieucarbou/ESPAsyncWebServer/actions/workflows/ci.yml/badge.svg)](https://github.com/mathieucarbou/ESPAsyncWebServer/actions/workflows/ci.yml) -[![GitHub latest commit](https://badgen.net/github/last-commit/mathieucarbou/YaSolR)](https://GitHub.com/mathieucarbou/YaSolR/commit/) +[![GitHub latest commit](https://badgen.net/github/last-commit/mathieucarbou/ESPAsyncWebServer)](https://GitHub.com/mathieucarbou/ESPAsyncWebServer/commit/) [![Gitpod Ready-to-Code](https://img.shields.io/badge/Gitpod-Ready--to--Code-blue?logo=gitpod)](https://gitpod.io/#https://github.com/mathieucarbou/ESPAsyncWebServer) Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 and RP2040 From 5f26351296914b50d6f43cd8e2d892a837c76fe8 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Wed, 4 Sep 2024 11:31:52 +0200 Subject: [PATCH 337/551] Add SSE event example --- examples/SimpleServer/SimpleServer.ino | 56 ++++++++++++++++++++++++-- src/AsyncEventSource.h | 6 ++- 2 files changed, 58 insertions(+), 4 deletions(-) diff --git a/examples/SimpleServer/SimpleServer.ino b/examples/SimpleServer/SimpleServer.ino index fd53639ef..739a7da21 100644 --- a/examples/SimpleServer/SimpleServer.ino +++ b/examples/SimpleServer/SimpleServer.ino @@ -25,8 +25,39 @@ #include AsyncWebServer server(80); - -const char* PARAM_MESSAGE = "message"; +AsyncEventSource events("/events"); + +const char* PARAM_MESSAGE PROGMEM = "message"; +const char* SSE_HTLM PROGMEM = R"( + + + + Server-Sent Events + + + +

Open your browser console!

+ + +)"; void notFound(AsyncWebServerRequest* request) { request->send(404, "text/plain", "Not found"); @@ -69,7 +100,7 @@ void setup() { Connection: close Accept-Ranges: bytes */ - // Ref: https://github.com/mathieucarbou/ESPAsyncWebServer/pull/80 + // Ref: https://github.com/mathieucarbou/ESPAsyncWebServer/pull/80 server.on("/download", HTTP_HEAD | HTTP_GET, [](AsyncWebServerRequest* request) { if (request->method() == HTTP_HEAD) { AsyncWebServerResponse* response = request->beginResponse(200, "application/octet-stream"); @@ -153,6 +184,18 @@ void setup() { request->send(response); }); + events.onConnect([](AsyncEventSourceClient* client) { + if (client->lastId()) { + Serial.printf("SSE Client reconnected! Last message ID that it gat is: %" PRIu32 "\n", client->lastId()); + } + client->send("hello!", NULL, millis(), 1000); + }); + + server.on("/sse", HTTP_GET, [](AsyncWebServerRequest* request) { + request->send(200, "text/html", SSE_HTLM); + }); + + server.addHandler(&events); server.addHandler(jsonHandler); server.addHandler(msgPackHandler); @@ -161,5 +204,12 @@ void setup() { server.begin(); } +uint32_t lastSSE = 0; + void loop() { + uint32_t now = millis(); + if (now - lastSSE > 2000) { + events.send(String("ping-") + now, "heartbeat", now); + lastSSE = millis(); + } } \ No newline at end of file diff --git a/src/AsyncEventSource.h b/src/AsyncEventSource.h index 7a784d80d..df28d2107 100644 --- a/src/AsyncEventSource.h +++ b/src/AsyncEventSource.h @@ -91,6 +91,8 @@ class AsyncEventSourceClient { AsyncClient* client() { return _client; } void close(); void write(const char* message, size_t len); + void send(const String& message, const String& event, uint32_t id = 0, uint32_t reconnect = 0) { send(message.c_str(), event.c_str(), id, reconnect); } + void send(const String& message, const char* event, uint32_t id = 0, uint32_t reconnect = 0) { send(message.c_str(), event, id, reconnect); } void send(const char* message, const char* event = NULL, uint32_t id = 0, uint32_t reconnect = 0); bool connected() const { return (_client != NULL) && _client->connected(); } uint32_t lastId() const { return _lastId; } @@ -116,13 +118,15 @@ class AsyncEventSource : public AsyncWebHandler { ArAuthorizeConnectHandler _authorizeConnectHandler; public: - AsyncEventSource(const String& url) : _url(url){}; + AsyncEventSource(const String& url) : _url(url) {}; ~AsyncEventSource() { close(); }; const char* url() const { return _url.c_str(); } void close(); void onConnect(ArEventHandlerFunction cb); void authorizeConnect(ArAuthorizeConnectHandler cb); + void send(const String& message, const String& event, uint32_t id = 0, uint32_t reconnect = 0) { send(message.c_str(), event.c_str(), id, reconnect); } + void send(const String& message, const char* event, uint32_t id = 0, uint32_t reconnect = 0) { send(message.c_str(), event, id, reconnect); } void send(const char* message, const char* event = NULL, uint32_t id = 0, uint32_t reconnect = 0); // number of clients connected size_t count() const; From 933aac8d3ed2edb30c1ddc12cc3a91a502a163c9 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Wed, 4 Sep 2024 12:11:11 +0200 Subject: [PATCH 338/551] Deprecate ack(size_t len, uint32_t time) --- src/AsyncEventSource.cpp | 3 +-- src/AsyncEventSource.h | 5 +++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/AsyncEventSource.cpp b/src/AsyncEventSource.cpp index 30ad27194..4705f490e 100644 --- a/src/AsyncEventSource.cpp +++ b/src/AsyncEventSource.cpp @@ -128,8 +128,7 @@ AsyncEventSourceMessage::~AsyncEventSourceMessage() { free(_data); } -size_t AsyncEventSourceMessage::ack(size_t len, uint32_t time) { - (void)time; +size_t AsyncEventSourceMessage::ack(size_t len) { // If the whole message is now acked... if (_acked + len > _len) { // Return the number of extra bytes acked (they will be carried on to the next message) diff --git a/src/AsyncEventSource.h b/src/AsyncEventSource.h index df28d2107..b1d07dca0 100644 --- a/src/AsyncEventSource.h +++ b/src/AsyncEventSource.h @@ -60,13 +60,14 @@ class AsyncEventSourceMessage { uint8_t* _data; size_t _len; size_t _sent; - // size_t _ack; size_t _acked; public: AsyncEventSourceMessage(const char* data, size_t len); ~AsyncEventSourceMessage(); - size_t ack(size_t len, uint32_t time __attribute__((unused))); + [[deprecated("This function is deprecated and will be removed in future releases. Use ack(size_t len) instead")]] + size_t ack(size_t len, uint32_t time __attribute__((unused))) { return ack(len); } + size_t ack(size_t len); size_t send(AsyncClient* client); bool finished() { return _acked == _len; } bool sent() { return _sent == _len; } From 706e5107e083097294fb9b526a04c62c1ed8c5ff Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Wed, 4 Sep 2024 12:16:00 +0200 Subject: [PATCH 339/551] Revert "Deprecate ack(size_t len, uint32_t time)" This reverts commit 933aac8d3ed2edb30c1ddc12cc3a91a502a163c9. --- src/AsyncEventSource.cpp | 3 ++- src/AsyncEventSource.h | 5 ++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/AsyncEventSource.cpp b/src/AsyncEventSource.cpp index 4705f490e..30ad27194 100644 --- a/src/AsyncEventSource.cpp +++ b/src/AsyncEventSource.cpp @@ -128,7 +128,8 @@ AsyncEventSourceMessage::~AsyncEventSourceMessage() { free(_data); } -size_t AsyncEventSourceMessage::ack(size_t len) { +size_t AsyncEventSourceMessage::ack(size_t len, uint32_t time) { + (void)time; // If the whole message is now acked... if (_acked + len > _len) { // Return the number of extra bytes acked (they will be carried on to the next message) diff --git a/src/AsyncEventSource.h b/src/AsyncEventSource.h index b1d07dca0..df28d2107 100644 --- a/src/AsyncEventSource.h +++ b/src/AsyncEventSource.h @@ -60,14 +60,13 @@ class AsyncEventSourceMessage { uint8_t* _data; size_t _len; size_t _sent; + // size_t _ack; size_t _acked; public: AsyncEventSourceMessage(const char* data, size_t len); ~AsyncEventSourceMessage(); - [[deprecated("This function is deprecated and will be removed in future releases. Use ack(size_t len) instead")]] - size_t ack(size_t len, uint32_t time __attribute__((unused))) { return ack(len); } - size_t ack(size_t len); + size_t ack(size_t len, uint32_t time __attribute__((unused))); size_t send(AsyncClient* client); bool finished() { return _acked == _len; } bool sent() { return _sent == _len; } From d3f99ba2fabd4c2a64a939bc270cc4296c4285e6 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Wed, 4 Sep 2024 12:18:27 +0200 Subject: [PATCH 340/551] update sample --- examples/SimpleServer/SimpleServer.ino | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/SimpleServer/SimpleServer.ino b/examples/SimpleServer/SimpleServer.ino index 739a7da21..5e74474ac 100644 --- a/examples/SimpleServer/SimpleServer.ino +++ b/examples/SimpleServer/SimpleServer.ino @@ -205,10 +205,11 @@ void setup() { } uint32_t lastSSE = 0; +uint32_t delta = 1; void loop() { uint32_t now = millis(); - if (now - lastSSE > 2000) { + if (now - lastSSE >= delta) { events.send(String("ping-") + now, "heartbeat", now); lastSSE = millis(); } From 4c4c97ecb7f057fed0c3dc252a9a8a0920d1dd76 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Wed, 4 Sep 2024 12:36:35 +0200 Subject: [PATCH 341/551] Set delta to 5 ms in example --- examples/SimpleServer/SimpleServer.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/SimpleServer/SimpleServer.ino b/examples/SimpleServer/SimpleServer.ino index 5e74474ac..778484bdf 100644 --- a/examples/SimpleServer/SimpleServer.ino +++ b/examples/SimpleServer/SimpleServer.ino @@ -205,7 +205,7 @@ void setup() { } uint32_t lastSSE = 0; -uint32_t delta = 1; +uint32_t delta = 5; void loop() { uint32_t now = millis(); From 675aba89e415a60d4f28cfa8f5bafadb1308f746 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Wed, 4 Sep 2024 13:06:21 +0200 Subject: [PATCH 342/551] Updated to ack(size_t len, uint32_t time = 0); --- src/AsyncEventSource.cpp | 3 +-- src/AsyncEventSource.h | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/AsyncEventSource.cpp b/src/AsyncEventSource.cpp index 30ad27194..e09c0581d 100644 --- a/src/AsyncEventSource.cpp +++ b/src/AsyncEventSource.cpp @@ -128,8 +128,7 @@ AsyncEventSourceMessage::~AsyncEventSourceMessage() { free(_data); } -size_t AsyncEventSourceMessage::ack(size_t len, uint32_t time) { - (void)time; +size_t AsyncEventSourceMessage::ack(size_t len, __attribute__((unused)) uint32_t time) { // If the whole message is now acked... if (_acked + len > _len) { // Return the number of extra bytes acked (they will be carried on to the next message) diff --git a/src/AsyncEventSource.h b/src/AsyncEventSource.h index df28d2107..986f83ac2 100644 --- a/src/AsyncEventSource.h +++ b/src/AsyncEventSource.h @@ -66,7 +66,7 @@ class AsyncEventSourceMessage { public: AsyncEventSourceMessage(const char* data, size_t len); ~AsyncEventSourceMessage(); - size_t ack(size_t len, uint32_t time __attribute__((unused))); + size_t ack(size_t len, uint32_t time = 0); size_t send(AsyncClient* client); bool finished() { return _acked == _len; } bool sent() { return _sent == _len; } From ac748ef4912d65c3988ab82ad1a0d1a5b484cedc Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Wed, 4 Sep 2024 13:08:58 +0200 Subject: [PATCH 343/551] Bugfix: AsyncEventSource writes multiple events per tcp send, including partial events that straddle buffers; Improvement: don't hold onto event items until ack, immediately remove them from queue Copy of https://github.com/esphome/ESPAsyncWebServer/pull/41 --- src/AsyncEventSource.cpp | 50 +++++++++++++++++++++++++--------------- src/AsyncEventSource.h | 1 + 2 files changed, 32 insertions(+), 19 deletions(-) diff --git a/src/AsyncEventSource.cpp b/src/AsyncEventSource.cpp index e09c0581d..6a290e127 100644 --- a/src/AsyncEventSource.cpp +++ b/src/AsyncEventSource.cpp @@ -141,17 +141,19 @@ size_t AsyncEventSourceMessage::ack(size_t len, __attribute__((unused)) uint32_t return 0; } -// This could also return void as the return value is not used. -// Leaving as-is for compatibility... -size_t AsyncEventSourceMessage::send(AsyncClient* client) { - if (_sent >= _len) { +size_t AsyncEventSourceMessage::write(AsyncClient* client) { + if (_sent >= _len || !client->canSend()) { return 0; } - const size_t len_to_send = _len - _sent; - auto position = reinterpret_cast(_data + _sent); - const size_t sent_now = client->write(position, len_to_send); - _sent += sent_now; - return sent_now; + size_t len = min(_len - _sent, client->space()); + size_t sent = client->add((const char*)_data + _sent, len); + _sent += sent; + return sent; +} + +size_t AsyncEventSourceMessage::send(AsyncClient* client) { + size_t sent = write(client); + return sent && client->send() ? sent : 0; } // Client @@ -173,6 +175,8 @@ AsyncEventSourceClient::AsyncEventSourceClient(AsyncWebServerRequest* request, A _server->_addClient(this); delete request; + + _client->setNoDelay(true); } AsyncEventSourceClient::~AsyncEventSourceClient() { @@ -210,11 +214,6 @@ void AsyncEventSourceClient::_onAck(size_t len, uint32_t time) { // Same here, acquiring the lock early std::lock_guard lock(_lockmq); #endif - while (len && _messageQueue.size()) { - len = _messageQueue.front().ack(len, time); - if (_messageQueue.front().finished()) - _messageQueue.pop_front(); - } _runQueue(); } @@ -263,11 +262,24 @@ size_t AsyncEventSourceClient::packetsWaiting() const { } void AsyncEventSourceClient::_runQueue() { - // Calls to this private method now already protected by _lockmq acquisition - // so no extra call of _lockmq.lock() here.. - for (auto& i : _messageQueue) { - if (!i.sent()) - i.send(_client); + size_t total_bytes_written = 0; + for (auto i = _messageQueue.begin(); i != _messageQueue.end(); ++i) { + if (!i->sent()) { + const size_t bytes_written = i->write(_client); + total_bytes_written += bytes_written; + if (bytes_written == 0) + break; + } + } + if (total_bytes_written > 0) + _client->send(); + + size_t len = total_bytes_written; + while (len && _messageQueue.size()) { + len = _messageQueue.front().ack(len); + if (_messageQueue.front().finished()) { + _messageQueue.pop_front(); + } } } diff --git a/src/AsyncEventSource.h b/src/AsyncEventSource.h index 986f83ac2..2eae21131 100644 --- a/src/AsyncEventSource.h +++ b/src/AsyncEventSource.h @@ -67,6 +67,7 @@ class AsyncEventSourceMessage { AsyncEventSourceMessage(const char* data, size_t len); ~AsyncEventSourceMessage(); size_t ack(size_t len, uint32_t time = 0); + size_t write(AsyncClient* client); size_t send(AsyncClient* client); bool finished() { return _acked == _len; } bool sent() { return _sent == _len; } From 3e84cf27c2fde39f03815e94cbe265174f4c2e22 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Wed, 4 Sep 2024 13:45:56 +0200 Subject: [PATCH 344/551] v3.2.3 --- README.md | 2 +- docs/index.md | 2 +- library.json | 2 +- library.properties | 2 +- src/ESPAsyncWebServer.h | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 0b359f38b..fbe231ab0 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo **WARNING** The library name was changed from `ESP Async WebServer` to `ESPAsyncWebServer` as per the Arduino Lint recommendations. ``` -mathieucarbou/ESPAsyncWebServer @ 3.2.2 +mathieucarbou/ESPAsyncWebServer @ 3.2.3 ``` Dependency: diff --git a/docs/index.md b/docs/index.md index 0b359f38b..fbe231ab0 100644 --- a/docs/index.md +++ b/docs/index.md @@ -20,7 +20,7 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo **WARNING** The library name was changed from `ESP Async WebServer` to `ESPAsyncWebServer` as per the Arduino Lint recommendations. ``` -mathieucarbou/ESPAsyncWebServer @ 3.2.2 +mathieucarbou/ESPAsyncWebServer @ 3.2.3 ``` Dependency: diff --git a/library.json b/library.json index 7bfb727df..427b8b923 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "ESPAsyncWebServer", - "version": "3.2.2", + "version": "3.2.3", "description": "Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 and RP2040. Supports: WebSocket, SSE, Authentication, Arduino Json 7, File Upload, Static File serving, URL Rewrite, URL Redirect, etc.", "keywords": "http,async,websocket,webserver", "homepage": "https://github.com/mathieucarbou/ESPAsyncWebServer", diff --git a/library.properties b/library.properties index 727e92576..3131635ad 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=ESPAsyncWebServer -version=3.2.2 +version=3.2.3 author=Me-No-Dev maintainer=Mathieu Carbou sentence=Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 and RP2040 diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index 697f31f93..d5812646a 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -45,10 +45,10 @@ #include "literals.h" -#define ASYNCWEBSERVER_VERSION "3.2.2" +#define ASYNCWEBSERVER_VERSION "3.2.3" #define ASYNCWEBSERVER_VERSION_MAJOR 3 #define ASYNCWEBSERVER_VERSION_MINOR 2 -#define ASYNCWEBSERVER_VERSION_REVISION 2 +#define ASYNCWEBSERVER_VERSION_REVISION 3 #define ASYNCWEBSERVER_FORK_mathieucarbou #ifdef ASYNCWEBSERVER_REGEX From d5eac05df58391297f7af1b0ea53fa97fafe4148 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Wed, 4 Sep 2024 22:29:20 +0200 Subject: [PATCH 345/551] Fix warnings --- examples/SimpleServer/SimpleServer.ino | 4 ++-- platformio.ini | 1 + src/ESPAsyncWebServer.h | 12 +++++++++++- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/examples/SimpleServer/SimpleServer.ino b/examples/SimpleServer/SimpleServer.ino index 778484bdf..9a8b07696 100644 --- a/examples/SimpleServer/SimpleServer.ino +++ b/examples/SimpleServer/SimpleServer.ino @@ -142,7 +142,7 @@ void setup() { // receives JSON and sends JSON jsonHandler->onRequest([](AsyncWebServerRequest* request, JsonVariant& json) { - JsonObject jsonObj = json.as(); + // JsonObject jsonObj = json.as(); // ... AsyncJsonResponse* response = new AsyncJsonResponse(); @@ -165,7 +165,7 @@ void setup() { // receives MessagePack and sends MessagePack msgPackHandler->onRequest([](AsyncWebServerRequest* request, JsonVariant& json) { - JsonObject jsonObj = json.as(); + // JsonObject jsonObj = json.as(); // ... AsyncMessagePackResponse* response = new AsyncMessagePackResponse(); diff --git a/platformio.ini b/platformio.ini index dd6527188..48e1ba08d 100644 --- a/platformio.ini +++ b/platformio.ini @@ -2,6 +2,7 @@ framework = arduino build_flags = -Wall -Wextra + -Wno-unused-parameter -D CONFIG_ARDUHAL_LOG_COLORS -D CORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_VERBOSE -D CONFIG_ASYNC_TCP_MAX_ACK_TIME=3000 diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index d5812646a..0e405160c 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -335,11 +335,15 @@ class AsyncWebServerRequest { void sendChunked(const char* contentType, AwsResponseFiller callback, AwsTemplateProcessor templateCallback = nullptr) { send(beginChunkedResponse(contentType, callback, templateCallback)); } void sendChunked(const String& contentType, AwsResponseFiller callback, AwsTemplateProcessor templateCallback = nullptr) { send(beginChunkedResponse(contentType, callback, templateCallback)); } +#ifndef ESP8266 [[deprecated("Replaced by send(...)")]] +#endif void send_P(int code, const String& contentType, const uint8_t* content, size_t len, AwsTemplateProcessor callback = nullptr) { send(code, contentType, content, len, callback); } +#ifndef ESP8266 [[deprecated("Replaced by send(...)")]] +#endif void send_P(int code, const String& contentType, PGM_P content, AwsTemplateProcessor callback = nullptr) { send(code, contentType, content, callback); } @@ -372,11 +376,15 @@ class AsyncWebServerRequest { AsyncResponseStream* beginResponseStream(const char* contentType, size_t bufferSize = 1460); AsyncResponseStream* beginResponseStream(const String& contentType, size_t bufferSize = 1460) { return beginResponseStream(contentType.c_str(), bufferSize); } +#ifndef ESP8266 [[deprecated("Replaced by beginResponse(...)")]] +#endif AsyncWebServerResponse* beginResponse_P(int code, const String& contentType, const uint8_t* content, size_t len, AwsTemplateProcessor callback = nullptr) { return beginResponse(code, contentType.c_str(), content, len, callback); } +#ifndef ESP8266 [[deprecated("Replaced by beginResponse(...)")]] +#endif AsyncWebServerResponse* beginResponse_P(int code, const String& contentType, PGM_P content, AwsTemplateProcessor callback = nullptr) { return beginResponse(code, contentType.c_str(), content, callback); } @@ -589,8 +597,10 @@ class AsyncWebServerResponse { bool addHeader(const String& name, long value, bool replaceExisting = true) { return addHeader(name.c_str(), value, replaceExisting); } virtual bool removeHeader(const char* name); virtual const AsyncWebHeader* getHeader(const char* name) const; - + +#ifndef ESP8266 [[deprecated("Use instead: _assembleHead(String& buffer, uint8_t version)")]] +#endif String _assembleHead(uint8_t version) { String buffer; _assembleHead(buffer, version); From 688ea40f2f725f8b4522421161f17f6a1c0f5656 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Wed, 4 Sep 2024 22:50:41 +0200 Subject: [PATCH 346/551] moved backported files --- platformio.ini | 7 ------- src/AsyncWebSocket.cpp | 2 +- src/{port/SHA1Builder.cpp => BackPort_SHA1Builder.cpp} | 4 ++-- src/{port/SHA1Builder.h => BackPort_SHA1Builder.h} | 5 +++++ 4 files changed, 8 insertions(+), 10 deletions(-) rename src/{port/SHA1Builder.cpp => BackPort_SHA1Builder.cpp} (99%) rename src/{port/SHA1Builder.h => BackPort_SHA1Builder.h} (93%) diff --git a/platformio.ini b/platformio.ini index 48e1ba08d..b72ac6513 100644 --- a/platformio.ini +++ b/platformio.ini @@ -23,13 +23,6 @@ src_dir = examples/SimpleServer ; src_dir = examples/Draft ; src_dir = examples/issues/Issue14 -[env:arduino] -platform = espressif32 -board = esp32dev -lib_deps = - bblanchon/ArduinoJson @ 7.1.0 - mathieucarbou/AsyncTCP @ 3.2.5 - [env:arduino-2] platform = espressif32@6.8.1 board = esp32dev diff --git a/src/AsyncWebSocket.cpp b/src/AsyncWebSocket.cpp index a5c8d7b4f..859fcc8ea 100644 --- a/src/AsyncWebSocket.cpp +++ b/src/AsyncWebSocket.cpp @@ -27,7 +27,7 @@ #if defined(ESP32) #if ESP_IDF_VERSION_MAJOR < 5 - #include "./port/SHA1Builder.h" + #include "BackPort_SHA1Builder.h" #else #include #endif diff --git a/src/port/SHA1Builder.cpp b/src/BackPort_SHA1Builder.cpp similarity index 99% rename from src/port/SHA1Builder.cpp rename to src/BackPort_SHA1Builder.cpp index 901fb8021..08ba32ca2 100644 --- a/src/port/SHA1Builder.cpp +++ b/src/BackPort_SHA1Builder.cpp @@ -23,7 +23,7 @@ #include #if ESP_IDF_VERSION_MAJOR < 5 -#include "SHA1Builder.h" +#include "BackPort_SHA1Builder.h" // 32-bit integer manipulation macros (big endian) @@ -202,7 +202,7 @@ void SHA1Builder::process(const uint8_t *data) { // Public methods -void SHA1Builder::begin(void) { +void SHA1Builder::begin() { total[0] = 0; total[1] = 0; diff --git a/src/port/SHA1Builder.h b/src/BackPort_SHA1Builder.h similarity index 93% rename from src/port/SHA1Builder.h rename to src/BackPort_SHA1Builder.h index da9a77a7b..8f518259b 100644 --- a/src/port/SHA1Builder.h +++ b/src/BackPort_SHA1Builder.h @@ -12,6 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include +#if ESP_IDF_VERSION_MAJOR < 5 + #ifndef SHA1Builder_h #define SHA1Builder_h @@ -37,3 +40,5 @@ class SHA1Builder { }; #endif // SHA1Builder_h + +#endif // ESP_IDF_VERSION_MAJOR < 5 From dc746aee314d08503d2758bf0939816890e14a69 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Wed, 4 Sep 2024 22:21:50 +0200 Subject: [PATCH 347/551] (fix #94) Remove MAX_PRINTF_LEN limitation and fixed wrong usage of vsnprintf --- examples/SimpleServer/SimpleServer.ino | 39 ++++++++- src/AsyncWebSocket.cpp | 109 +++++++++++-------------- 2 files changed, 84 insertions(+), 64 deletions(-) diff --git a/examples/SimpleServer/SimpleServer.ino b/examples/SimpleServer/SimpleServer.ino index 9a8b07696..2a2079a6b 100644 --- a/examples/SimpleServer/SimpleServer.ino +++ b/examples/SimpleServer/SimpleServer.ino @@ -26,6 +26,7 @@ AsyncWebServer server(80); AsyncEventSource events("/events"); +AsyncWebSocket ws("/ws"); const char* PARAM_MESSAGE PROGMEM = "message"; const char* SSE_HTLM PROGMEM = R"( @@ -195,7 +196,32 @@ void setup() { request->send(200, "text/html", SSE_HTLM); }); + ws.onEvent([](AsyncWebSocket* server, AsyncWebSocketClient* client, AwsEventType type, void* arg, uint8_t* data, size_t len) { + (void) len; + if (type == WS_EVT_CONNECT) { + Serial.println("ws connect"); + client->setCloseClientOnQueueFull(false); + client->ping(); + } else if (type == WS_EVT_DISCONNECT) { + Serial.println("ws disconnect"); + } else if (type == WS_EVT_ERROR) { + Serial.println("ws error"); + } else if (type == WS_EVT_PONG) { + Serial.println("ws pong"); + } else if (type == WS_EVT_DATA) { + AwsFrameInfo* info = (AwsFrameInfo*)arg; + String msg = ""; + if (info->final && info->index == 0 && info->len == len) { + if (info->opcode == WS_TEXT) { + data[len] = 0; + Serial.printf("ws text: %s\n", (char*)data); + } + } + } + }); + server.addHandler(&events); + server.addHandler(&ws); server.addHandler(jsonHandler); server.addHandler(msgPackHandler); @@ -205,12 +231,19 @@ void setup() { } uint32_t lastSSE = 0; -uint32_t delta = 5; +uint32_t deltaSSE = 5; + +uint32_t lastWS = 0; +uint32_t deltaWS = 100; void loop() { uint32_t now = millis(); - if (now - lastSSE >= delta) { + if (now - lastSSE >= deltaSSE) { events.send(String("ping-") + now, "heartbeat", now); lastSSE = millis(); } -} \ No newline at end of file + if (now - lastWS >= deltaWS) { + ws.printfAll("kp%.4f", (10.0 / 3.0)); + lastWS = millis(); + } +} diff --git a/src/AsyncWebSocket.cpp b/src/AsyncWebSocket.cpp index 859fcc8ea..0b87cef1e 100644 --- a/src/AsyncWebSocket.cpp +++ b/src/AsyncWebSocket.cpp @@ -36,11 +36,8 @@ #include #endif -#define MAX_PRINTF_LEN 64 - using namespace asyncsrv; - size_t webSocketSendFrameWindow(AsyncClient* client) { if (!client->canSend()) return 0; @@ -589,30 +586,23 @@ void AsyncWebSocketClient::_onData(void* pbuf, size_t plen) { size_t AsyncWebSocketClient::printf(const char* format, ...) { va_list arg; va_start(arg, format); - char* temp = new char[MAX_PRINTF_LEN]; - if (!temp) { - va_end(arg); + size_t len = vsnprintf(nullptr, 0, format, arg); + va_end(arg); + + if (len == 0) return 0; - } - char* buffer = temp; - size_t len = vsnprintf(temp, MAX_PRINTF_LEN, format, arg); + + char* buffer = new char[len + 1]; + + if (!buffer) + return 0; + + va_start(arg, format); + len = vsnprintf(buffer, len + 1, format, arg); va_end(arg); - if (len > (MAX_PRINTF_LEN - 1)) { - buffer = new char[len + 1]; - if (!buffer) { - delete[] temp; - return 0; - } - va_start(arg, format); - vsnprintf(buffer, len + 1, format, arg); - va_end(arg); - } text(buffer, len); - if (buffer != temp) { - delete[] buffer; - } - delete[] temp; + delete[] buffer; return len; } @@ -620,30 +610,23 @@ size_t AsyncWebSocketClient::printf(const char* format, ...) { size_t AsyncWebSocketClient::printf_P(PGM_P formatP, ...) { va_list arg; va_start(arg, formatP); - char* temp = new char[MAX_PRINTF_LEN]; - if (!temp) { - va_end(arg); + size_t len = vsnprintf_P(nullptr, 0, formatP, arg); + va_end(arg); + + if (len == 0) return 0; - } - char* buffer = temp; - size_t len = vsnprintf_P(temp, MAX_PRINTF_LEN, formatP, arg); + + char* buffer = new char[len + 1]; + + if (!buffer) + return 0; + + va_start(arg, formatP); + len = vsnprintf_P(buffer, len + 1, formatP, arg); va_end(arg); - if (len > (MAX_PRINTF_LEN - 1)) { - buffer = new char[len + 1]; - if (!buffer) { - delete[] temp; - return 0; - } - va_start(arg, formatP); - vsnprintf_P(buffer, len + 1, formatP, arg); - va_end(arg); - } text(buffer, len); - if (buffer != temp) { - delete[] buffer; - } - delete[] temp; + delete[] buffer; return len; } #endif @@ -1008,22 +991,24 @@ size_t AsyncWebSocket::printf(uint32_t id, const char* format, ...) { size_t AsyncWebSocket::printfAll(const char* format, ...) { va_list arg; - char* temp = new char[MAX_PRINTF_LEN]; - if (!temp) - return 0; - va_start(arg, format); - size_t len = vsnprintf(temp, MAX_PRINTF_LEN, format, arg); + size_t len = vsnprintf(nullptr, 0, format, arg); va_end(arg); - delete[] temp; - AsyncWebSocketSharedBuffer buffer = std::make_shared>(len); + if (len == 0) + return 0; + + char* buffer = new char[len + 1]; + + if (!buffer) + return 0; va_start(arg, format); - vsnprintf((char*)buffer->data(), len + 1, format, arg); + len = vsnprintf(buffer, len + 1, format, arg); va_end(arg); - textAll(buffer); + textAll(buffer, len); + delete[] buffer; return len; } @@ -1042,22 +1027,24 @@ size_t AsyncWebSocket::printf_P(uint32_t id, PGM_P formatP, ...) { size_t AsyncWebSocket::printfAll_P(PGM_P formatP, ...) { va_list arg; - char* temp = new char[MAX_PRINTF_LEN]; - if (!temp) - return 0; - va_start(arg, formatP); - size_t len = vsnprintf_P(temp, MAX_PRINTF_LEN, formatP, arg); + size_t len = vsnprintf_P(nullptr, 0, formatP, arg); va_end(arg); - delete[] temp; - AsyncWebSocketSharedBuffer buffer = std::make_shared>(len + 1); + if (len == 0) + return 0; + + char* buffer = new char[len + 1]; + + if (!buffer) + return 0; va_start(arg, formatP); - vsnprintf_P((char*)buffer->data(), len + 1, formatP, arg); + len = vsnprintf_P(buffer, len + 1, formatP, arg); va_end(arg); - textAll(buffer); + textAll(buffer, len); + delete[] buffer; return len; } #endif From cec5afbc29f4fde246248281905cdf4cea963af4 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Wed, 4 Sep 2024 23:00:01 +0200 Subject: [PATCH 348/551] v3.2.4 --- README.md | 2 +- docs/index.md | 2 +- library.json | 2 +- library.properties | 2 +- src/ESPAsyncWebServer.h | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index fbe231ab0..70b21430b 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo **WARNING** The library name was changed from `ESP Async WebServer` to `ESPAsyncWebServer` as per the Arduino Lint recommendations. ``` -mathieucarbou/ESPAsyncWebServer @ 3.2.3 +mathieucarbou/ESPAsyncWebServer @ 3.2.4 ``` Dependency: diff --git a/docs/index.md b/docs/index.md index fbe231ab0..70b21430b 100644 --- a/docs/index.md +++ b/docs/index.md @@ -20,7 +20,7 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo **WARNING** The library name was changed from `ESP Async WebServer` to `ESPAsyncWebServer` as per the Arduino Lint recommendations. ``` -mathieucarbou/ESPAsyncWebServer @ 3.2.3 +mathieucarbou/ESPAsyncWebServer @ 3.2.4 ``` Dependency: diff --git a/library.json b/library.json index 427b8b923..db3d040f5 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "ESPAsyncWebServer", - "version": "3.2.3", + "version": "3.2.4", "description": "Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 and RP2040. Supports: WebSocket, SSE, Authentication, Arduino Json 7, File Upload, Static File serving, URL Rewrite, URL Redirect, etc.", "keywords": "http,async,websocket,webserver", "homepage": "https://github.com/mathieucarbou/ESPAsyncWebServer", diff --git a/library.properties b/library.properties index 3131635ad..bc5ba6d6f 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=ESPAsyncWebServer -version=3.2.3 +version=3.2.4 author=Me-No-Dev maintainer=Mathieu Carbou sentence=Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 and RP2040 diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index 0e405160c..df578f5f7 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -45,10 +45,10 @@ #include "literals.h" -#define ASYNCWEBSERVER_VERSION "3.2.3" +#define ASYNCWEBSERVER_VERSION "3.2.4" #define ASYNCWEBSERVER_VERSION_MAJOR 3 #define ASYNCWEBSERVER_VERSION_MINOR 2 -#define ASYNCWEBSERVER_VERSION_REVISION 3 +#define ASYNCWEBSERVER_VERSION_REVISION 4 #define ASYNCWEBSERVER_FORK_mathieucarbou #ifdef ASYNCWEBSERVER_REGEX From e3813b8747ca1bee7a5301f0532ca4d5e8f17678 Mon Sep 17 00:00:00 2001 From: David Refoua Date: Thu, 5 Sep 2024 10:36:27 +0330 Subject: [PATCH 349/551] fix typos --- src/ESPAsyncWebServer.h | 2 +- src/WebHandlerImpl.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index df578f5f7..5292010e8 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -647,7 +647,7 @@ class AsyncWebServer { /** * @brief (compat) Add url rewrite rule by pointer - * a deep copy of the pounter object will be created, + * a deep copy of the pointer object will be created, * it is up to user to manage further lifetime of the object in argument * * @param rewrite pointer to rewrite object to copy setting from diff --git a/src/WebHandlerImpl.h b/src/WebHandlerImpl.h index 22757d7e4..b07e013f4 100644 --- a/src/WebHandlerImpl.h +++ b/src/WebHandlerImpl.h @@ -112,7 +112,7 @@ class AsyncCallbackWebHandler : public AsyncWebHandler { } } else #endif - if (_uri.length() && _uri.startsWith("/*.")) { + if (_uri.length() && _uri.startsWith("/*.")) { String uriTemplate = String(_uri); uriTemplate = uriTemplate.substring(uriTemplate.lastIndexOf(".")); if (!request->url().endsWith(uriTemplate)) From fed1a4200828519a307e3f597141d4bf97b015f5 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Thu, 5 Sep 2024 23:10:34 +0200 Subject: [PATCH 350/551] Update gitignore --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 5a252ab80..1efbc8ec8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,5 @@ .DS_Store .lh /.pio -/.vscode/* +/.vscode /logs From a63694b33f3c8bf22a8854f75dc9fc39eb33f068 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Fri, 6 Sep 2024 11:50:04 +0200 Subject: [PATCH 351/551] update CI --- .github/workflows/ci.yml | 101 +++++++++++++++++++++++---------------- .gitpod.yml | 2 +- platformio.ini | 81 +++++++++++++++++-------------- 3 files changed, 107 insertions(+), 77 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e1e3c2752..45ff7f393 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -77,58 +77,77 @@ jobs: - name: Build StreamFiles run: arduino-cli compile --library . --warnings none -b ${{ matrix.board }} "examples/StreamFiles/StreamFiles.ino" - pio_envs: - name: Get PlatformIO Envs - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: actions/cache@v4 - with: - key: pip - path: ~/.cache/pip - - uses: actions/setup-python@v5 - with: - python-version: "3.x" - - name: Install PlatformIO - run: | - python -m pip install --upgrade pip - pip install --upgrade platformio - - name: Get Envs - id: envs - run: | - echo "pio_default_envs=$(pio project config --json-output | jq -cr '[ .[][0] | select(startswith("env:") and (endswith("-debug")|not)) | .[4:] ]')" >> $GITHUB_OUTPUT - - outputs: - pio_default_envs: ${{ steps.envs.outputs.pio_default_envs }} - platformio: - name: "pio:${{ matrix.environment }}" - needs: [pio_envs] + name: "pio:${{ matrix.env }}:${{ matrix.board }}" runs-on: ubuntu-latest strategy: - fail-fast: false matrix: - environment: ${{ fromJSON(needs.pio_envs.outputs.pio_default_envs) }} - + include: + - env: ci-arduino-2 + board: esp32dev + - env: ci-arduino-2 + board: esp32-s2-saola-1 + - env: ci-arduino-2 + board: esp32-s3-devkitc-1 + - env: ci-arduino-2 + board: esp32-c3-devkitc-02 + + - env: ci-arduino-3 + board: esp32dev + - env: ci-arduino-3 + board: esp32-s2-saola-1 + - env: ci-arduino-3 + board: esp32-s3-devkitc-1 + - env: ci-arduino-3 + board: esp32-c3-devkitc-02 + - env: ci-arduino-3 + board: esp32-c6-devkitc-1 + - env: ci-arduino-3 + board: esp32-h2-devkitm-1 + + - env: ci-arduino-310rc1 + board: esp32dev + - env: ci-arduino-310rc1 + board: esp32-s2-saola-1 + - env: ci-arduino-310rc1 + board: esp32-s3-devkitc-1 + - env: ci-arduino-310rc1 + board: esp32-c3-devkitc-02 + - env: ci-arduino-310rc1 + board: esp32-c6-devkitc-1 + - env: ci-arduino-310rc1 + board: esp32-h2-devkitm-1 + + - env: ci-esp8266 + board: huzzah + - env: ci-esp8266 + board: d1_mini + + - env: ci-raspberrypi + board: rpipicow steps: - - uses: actions/checkout@v4 - - uses: actions/cache@v4 + - name: Checkout + uses: actions/checkout@v4 + + - name: Cache PlatformIO + uses: actions/cache@v4 with: + key: ${{ runner.os }}-pio path: | - ~/.platformio ~/.cache/pip - key: pio - - uses: actions/setup-python@v5 + ~/.platformio + + - name: Python + uses: actions/setup-python@v5 with: python-version: "3.x" - - run: pip install platformio - - name: Install platformio + - name: Build run: | python -m pip install --upgrade pip pip install --upgrade platformio - - - run: PLATFORMIO_SRC_DIR=examples/CaptivePortal pio run -e ${{ matrix.environment }} - - run: PLATFORMIO_SRC_DIR=examples/SimpleServer pio run -e ${{ matrix.environment }} - - run: PLATFORMIO_SRC_DIR=examples/Filters pio run -e ${{ matrix.environment }} - - run: PLATFORMIO_SRC_DIR=examples/StreamFiles pio run -e ${{ matrix.environment }} + + - run: PLATFORMIO_SRC_DIR=examples/CaptivePortal PIO_BOARD=${{ matrix.board }} pio run -e ${{ matrix.env }} + - run: PLATFORMIO_SRC_DIR=examples/SimpleServer PIO_BOARD=${{ matrix.board }} pio run -e ${{ matrix.env }} + - run: PLATFORMIO_SRC_DIR=examples/Filters PIO_BOARD=${{ matrix.board }} pio run -e ${{ matrix.env }} + - run: PLATFORMIO_SRC_DIR=examples/StreamFiles PIO_BOARD=${{ matrix.board }} pio run -e ${{ matrix.env }} diff --git a/.gitpod.yml b/.gitpod.yml index 74917c2c7..2f8a4431c 100644 --- a/.gitpod.yml +++ b/.gitpod.yml @@ -1,5 +1,5 @@ tasks: - - command: pip install --upgrade pip && pip install -U platformio && platformio run -e arduino-3 + - command: pip install --upgrade pip && pip install -U platformio && platformio run image: file: .gitpod.Dockerfile diff --git a/platformio.ini b/platformio.ini index b72ac6513..051c4ca11 100644 --- a/platformio.ini +++ b/platformio.ini @@ -1,3 +1,13 @@ +[platformio] +default_envs = arduino-2, arduino-3, arduino-310rc1, esp8266, raspberrypi +lib_dir = . +; src_dir = examples/CaptivePortal +src_dir = examples/SimpleServer +; src_dir = examples/StreamFiles +; src_dir = examples/Filters +; src_dir = examples/Draft +; src_dir = examples/issues/Issue14 + [env] framework = arduino build_flags = @@ -13,36 +23,30 @@ build_flags = upload_protocol = esptool monitor_speed = 115200 monitor_filters = esp32_exception_decoder, log2file - -[platformio] -lib_dir = . -; src_dir = examples/CaptivePortal -src_dir = examples/SimpleServer -; src_dir = examples/StreamFiles -; src_dir = examples/Filters -; src_dir = examples/Draft -; src_dir = examples/issues/Issue14 - -[env:arduino-2] -platform = espressif32@6.8.1 -board = esp32dev lib_deps = bblanchon/ArduinoJson @ 7.1.0 mathieucarbou/AsyncTCP @ 3.2.5 +lib_compat_mode = strict +lib_ldf_mode = chain +board = esp32dev + +[env:arduino-2] +platform = espressif32@6.8.1 [env:arduino-3] -platform = espressif32 -platform_packages= - platformio/framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#3.0.4 - platformio/framework-arduinoespressif32-libs @ https://github.com/espressif/arduino-esp32/releases/download/3.0.4/esp32-arduino-libs-3.0.4.zip -board = esp32dev -lib_deps = - bblanchon/ArduinoJson @ 7.1.0 - mathieucarbou/AsyncTCP @ 3.2.5 +platform = https://github.com/pioarduino/platform-espressif32/releases/download/51.03.04/platform-espressif32.zip +; board = esp32-s3-devkitc-1 +; board = esp32-c6-devkitc-1 + +[env:arduino-310rc1] +platform = https://github.com/pioarduino/platform-espressif32/releases/download/53.03.10%%2Brc1/platform-espressif32.zip +; board = esp32-s3-devkitc-1 +; board = esp32-c6-devkitc-1 [env:esp8266] platform = espressif8266 board = huzzah +; board = d1_mini lib_deps = bblanchon/ArduinoJson @ 7.1.0 esphome/ESPAsyncTCP-esphome @ 2.0.0 @@ -51,7 +55,7 @@ lib_deps = ; https://github.com/platformio/platform-raspberrypi/pull/36 ; https://github.com/earlephilhower/arduino-pico/blob/master/docs/platformio.rst ; board settings: https://github.com/earlephilhower/arduino-pico/blob/master/tools/json/rpipico.json -[env:rpipicow] +[env:raspberrypi] upload_protocol = picotool platform = https://github.com/maxgerhardt/platform-raspberrypi.git board = rpipicow @@ -59,23 +63,30 @@ lib_deps = bblanchon/ArduinoJson @ 7.1.0 khoih-prog/AsyncTCP_RP2040W @ 1.2.0 -[env:pioarduino-esp32dev] -platform = https://github.com/pioarduino/platform-espressif32/releases/download/51.03.04/platform-espressif32.zip -board = esp32dev -lib_deps = - bblanchon/ArduinoJson @ 7.1.0 - mathieucarbou/AsyncTCP @ 3.2.5 +; CI + +[env:ci-arduino-2] +platform = espressif32@6.8.1 +board = ${sysenv.PIO_BOARD} -[env:pioarduino-c6] +[env:ci-arduino-3] platform = https://github.com/pioarduino/platform-espressif32/releases/download/51.03.04/platform-espressif32.zip -board = esp32-c6-devkitc-1 +board = ${sysenv.PIO_BOARD} + +[env:ci-arduino-310rc1] +platform = https://github.com/pioarduino/platform-espressif32/releases/download/53.03.10%%2Brc1/platform-espressif32.zip +board = ${sysenv.PIO_BOARD} + +[env:ci-esp8266] +platform = espressif8266 +board = ${sysenv.PIO_BOARD} lib_deps = bblanchon/ArduinoJson @ 7.1.0 - mathieucarbou/AsyncTCP @ 3.2.5 + esphome/ESPAsyncTCP-esphome @ 2.0.0 -[env:pioarduino-h2] -platform = https://github.com/pioarduino/platform-espressif32/releases/download/51.03.04/platform-espressif32.zip -board = esp32-h2-devkitm-1 +[env:ci-raspberrypi] +platform = https://github.com/maxgerhardt/platform-raspberrypi.git +board = ${sysenv.PIO_BOARD} lib_deps = bblanchon/ArduinoJson @ 7.1.0 - mathieucarbou/AsyncTCP @ 3.2.5 + khoih-prog/AsyncTCP_RP2040W @ 1.2.0 From 5e15b9330c1be5a345a8ff274dc66f95f8939908 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Fri, 6 Sep 2024 12:16:17 +0200 Subject: [PATCH 352/551] update CI --- platformio.ini | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/platformio.ini b/platformio.ini index 051c4ca11..2655dd638 100644 --- a/platformio.ini +++ b/platformio.ini @@ -26,8 +26,6 @@ monitor_filters = esp32_exception_decoder, log2file lib_deps = bblanchon/ArduinoJson @ 7.1.0 mathieucarbou/AsyncTCP @ 3.2.5 -lib_compat_mode = strict -lib_ldf_mode = chain board = esp32dev [env:arduino-2] @@ -57,7 +55,8 @@ lib_deps = ; board settings: https://github.com/earlephilhower/arduino-pico/blob/master/tools/json/rpipico.json [env:raspberrypi] upload_protocol = picotool -platform = https://github.com/maxgerhardt/platform-raspberrypi.git +platform = raspberrypi +; platform = https://github.com/maxgerhardt/platform-raspberrypi.git board = rpipicow lib_deps = bblanchon/ArduinoJson @ 7.1.0 @@ -85,7 +84,8 @@ lib_deps = esphome/ESPAsyncTCP-esphome @ 2.0.0 [env:ci-raspberrypi] -platform = https://github.com/maxgerhardt/platform-raspberrypi.git +platform = raspberrypi +; platform = https://github.com/maxgerhardt/platform-raspberrypi.git board = ${sysenv.PIO_BOARD} lib_deps = bblanchon/ArduinoJson @ 7.1.0 From 343cd3d4c36e565f4f58c20b2b996bc0cd9b4e78 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Fri, 6 Sep 2024 12:17:56 +0200 Subject: [PATCH 353/551] Fix CI --- platformio.ini | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/platformio.ini b/platformio.ini index 2655dd638..53173ad21 100644 --- a/platformio.ini +++ b/platformio.ini @@ -55,8 +55,8 @@ lib_deps = ; board settings: https://github.com/earlephilhower/arduino-pico/blob/master/tools/json/rpipico.json [env:raspberrypi] upload_protocol = picotool -platform = raspberrypi -; platform = https://github.com/maxgerhardt/platform-raspberrypi.git +; platform = raspberrypi +platform = https://github.com/maxgerhardt/platform-raspberrypi.git board = rpipicow lib_deps = bblanchon/ArduinoJson @ 7.1.0 @@ -84,8 +84,8 @@ lib_deps = esphome/ESPAsyncTCP-esphome @ 2.0.0 [env:ci-raspberrypi] -platform = raspberrypi -; platform = https://github.com/maxgerhardt/platform-raspberrypi.git +; platform = raspberrypi +platform = https://github.com/maxgerhardt/platform-raspberrypi.git board = ${sysenv.PIO_BOARD} lib_deps = bblanchon/ArduinoJson @ 7.1.0 From 5173a00d3a6ae995c31dc44b997ffc7797b8e7a3 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Fri, 6 Sep 2024 12:20:28 +0200 Subject: [PATCH 354/551] fail-fast: false --- .github/workflows/ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 45ff7f393..8089c6a0c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -81,6 +81,7 @@ jobs: name: "pio:${{ matrix.env }}:${{ matrix.board }}" runs-on: ubuntu-latest strategy: + fail-fast: false matrix: include: - env: ci-arduino-2 From d37e0500068dc7fff16a25ede92ed755d4d022c2 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Fri, 6 Sep 2024 13:11:00 +0200 Subject: [PATCH 355/551] Add __attribute__((unused)) --- src/AsyncEventSource.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/AsyncEventSource.cpp b/src/AsyncEventSource.cpp index 6a290e127..7e370ec93 100644 --- a/src/AsyncEventSource.cpp +++ b/src/AsyncEventSource.cpp @@ -209,7 +209,7 @@ void AsyncEventSourceClient::_queueMessage(const char* message, size_t len) { } } -void AsyncEventSourceClient::_onAck(size_t len, uint32_t time) { +void AsyncEventSourceClient::_onAck(size_t len __attribute__((unused)), uint32_t time __attribute__((unused))) { #ifdef ESP32 // Same here, acquiring the lock early std::lock_guard lock(_lockmq); From 0c5e8dab3a10dbc601e4aad6259caf0190f3f24f Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Fri, 6 Sep 2024 23:50:47 +0200 Subject: [PATCH 356/551] doc update --- README.md | 44 +++++++++++++++++--------------------------- docs/index.md | 44 +++++++++++++++++--------------------------- 2 files changed, 34 insertions(+), 54 deletions(-) diff --git a/README.md b/README.md index 70b21430b..502a84f18 100644 --- a/README.md +++ b/README.md @@ -31,33 +31,23 @@ Dependency: ## Changes in this fork -- [@ayushsharma82](https://github.com/ayushsharma82) and [@mathieucarbou](https://github.com/mathieucarbou): Add RP2040 support ([#31](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/31)) -- [@mathieucarbou](https://github.com/mathieucarbou): `SSE_MAX_QUEUED_MESSAGES` to control the maximum number of messages that can be queued for a SSE client -- [@mathieucarbou](https://github.com/mathieucarbou): `write()` function public in `AsyncEventSource.h` -- [@mathieucarbou](https://github.com/mathieucarbou): `WS_MAX_QUEUED_MESSAGES`: control the maximum number of messages that can be queued for a Websocket client -- [@mathieucarbou](https://github.com/mathieucarbou): Added `setAuthentication(const String& username, const String& password)` -- [@mathieucarbou](https://github.com/mathieucarbou): Added `setCloseClientOnQueueFull(bool)` which can be set on a client to either close the connection or discard messages but not close the connection when the queue is full -- [@mathieucarbou](https://github.com/mathieucarbou): Added `StreamConcat` example to show how to stream multiple files in one response -- [@mathieucarbou](https://github.com/mathieucarbou): Added all flavors of `binary()`, `text()`, `binaryAll()` and `textAll()` in `AsyncWebSocket` -- [@mathieucarbou](https://github.com/mathieucarbou): Arduino 3 / ESP-IDF 5.1 compatibility -- [@mathieucarbou](https://github.com/mathieucarbou): Arduino Json 7 compatibility and backward compatible with 6 and 6 (changes in `AsyncJson.h`). The API to use Json has not changed. These are only internal changes. -- [@mathieucarbou](https://github.com/mathieucarbou): CI -- [@mathieucarbou](https://github.com/mathieucarbou): Depends on `mathieucarbou/AsyncTCP @ 3.2.5` -- [@mathieucarbou](https://github.com/mathieucarbou): Deployed in PlatformIO registry and Arduino IDE library manager -- [@mathieucarbou](https://github.com/mathieucarbou): Firmware size optimization: remove mbedtls dependency (accounts for 33KB in firmware) -- [@mathieucarbou](https://github.com/mathieucarbou): Made DEFAULT_MAX_WS_CLIENTS customizable -- [@mathieucarbou](https://github.com/mathieucarbou): MessagePack Support ([#62](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/62)) -- [@mathieucarbou](https://github.com/mathieucarbou): Remove filename after inline in Content-Disposition header according to RFC2183 -- [@mathieucarbou](https://github.com/mathieucarbou): Removed SPIFFSEditor to reduce library size and maintainance. SPIFF si also deprecated. If you need it, please copy the files from the original repository in your project. This fork focus on maintaining the server part and the SPIFFEditor is an application which has nothing to do inside a server library. -- [@mathieucarbou](https://github.com/mathieucarbou): Resurrected `AsyncWebSocketMessageBuffer` and `makeBuffer()` in order to make the fork API-compatible with the original library from me-no-dev regarding WebSocket. -- [@mathieucarbou](https://github.com/mathieucarbou): Some code cleanup -- [@mathieucarbou](https://github.com/mathieucarbou): Use `-D DEFAULT_MAX_WS_CLIENTS` to change the number of allows WebSocket clients and use `cleanupClients()` to help cleanup resources about dead clients -- [@nilo85](https://github.com/nilo85): Add support for Auth & GET requests in AsyncCallbackJsonWebHandler ([#14](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/14)) -- [@p0p-x](https://github.com/p0p-x): ESP IDF Compatibility (added back CMakeLists.txt) ([#32](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/32)) -- [@tueddy](https://github.com/tueddy): Compile with Arduino 3 (ESP-IDF 5.1) ([#13](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/13)) -- [@vortigont](https://github.com/vortigont): Set real "Last-Modified" header based on file's LastWrite time ([#5](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/5)) -- [@vortigont](https://github.com/vortigont): Some websocket code cleanup ([#29](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/29)) -- [@vortigont](https://github.com/vortigont): Refactor code - replace DYI structs with STL objects ([#39](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/39)) +- `char*` overloads to avoid using `String` +- `DEFAULT_MAX_WS_CLIENTS` to change the number of allows WebSocket clients and use `cleanupClients()` to help cleanup resources about dead clients +- `setCloseClientOnQueueFull(bool)` which can be set on a client to either close the connection or discard messages but not close the connection when the queue is full +- `SSE_MAX_QUEUED_MESSAGES` to control the maximum number of messages that can be queued for a SSE client +- `StreamConcat` example to show how to stream multiple files in one response +- `WS_MAX_QUEUED_MESSAGES`: control the maximum number of messages that can be queued for a Websocket client +- A lot of bug fixes +- Arduino 3 / ESP-IDF 5 compatibility +- Arduino Json 7 compatibility and backward compatible with 6 +- Better CI with a complete matrix of Arduino versions and boards +- Code size improvements +- Deployed in PlatformIO registry and Arduino IDE library manager +- ESP32 / ESP8266 / RP2040 support +- Lot of code cleanup and optimizations +- Performance improvements in terms of memory, speed and size +- Support overriding default response headers +- Support resumable downloads using HEAD and bytes range ## Documentation diff --git a/docs/index.md b/docs/index.md index 70b21430b..502a84f18 100644 --- a/docs/index.md +++ b/docs/index.md @@ -31,33 +31,23 @@ Dependency: ## Changes in this fork -- [@ayushsharma82](https://github.com/ayushsharma82) and [@mathieucarbou](https://github.com/mathieucarbou): Add RP2040 support ([#31](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/31)) -- [@mathieucarbou](https://github.com/mathieucarbou): `SSE_MAX_QUEUED_MESSAGES` to control the maximum number of messages that can be queued for a SSE client -- [@mathieucarbou](https://github.com/mathieucarbou): `write()` function public in `AsyncEventSource.h` -- [@mathieucarbou](https://github.com/mathieucarbou): `WS_MAX_QUEUED_MESSAGES`: control the maximum number of messages that can be queued for a Websocket client -- [@mathieucarbou](https://github.com/mathieucarbou): Added `setAuthentication(const String& username, const String& password)` -- [@mathieucarbou](https://github.com/mathieucarbou): Added `setCloseClientOnQueueFull(bool)` which can be set on a client to either close the connection or discard messages but not close the connection when the queue is full -- [@mathieucarbou](https://github.com/mathieucarbou): Added `StreamConcat` example to show how to stream multiple files in one response -- [@mathieucarbou](https://github.com/mathieucarbou): Added all flavors of `binary()`, `text()`, `binaryAll()` and `textAll()` in `AsyncWebSocket` -- [@mathieucarbou](https://github.com/mathieucarbou): Arduino 3 / ESP-IDF 5.1 compatibility -- [@mathieucarbou](https://github.com/mathieucarbou): Arduino Json 7 compatibility and backward compatible with 6 and 6 (changes in `AsyncJson.h`). The API to use Json has not changed. These are only internal changes. -- [@mathieucarbou](https://github.com/mathieucarbou): CI -- [@mathieucarbou](https://github.com/mathieucarbou): Depends on `mathieucarbou/AsyncTCP @ 3.2.5` -- [@mathieucarbou](https://github.com/mathieucarbou): Deployed in PlatformIO registry and Arduino IDE library manager -- [@mathieucarbou](https://github.com/mathieucarbou): Firmware size optimization: remove mbedtls dependency (accounts for 33KB in firmware) -- [@mathieucarbou](https://github.com/mathieucarbou): Made DEFAULT_MAX_WS_CLIENTS customizable -- [@mathieucarbou](https://github.com/mathieucarbou): MessagePack Support ([#62](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/62)) -- [@mathieucarbou](https://github.com/mathieucarbou): Remove filename after inline in Content-Disposition header according to RFC2183 -- [@mathieucarbou](https://github.com/mathieucarbou): Removed SPIFFSEditor to reduce library size and maintainance. SPIFF si also deprecated. If you need it, please copy the files from the original repository in your project. This fork focus on maintaining the server part and the SPIFFEditor is an application which has nothing to do inside a server library. -- [@mathieucarbou](https://github.com/mathieucarbou): Resurrected `AsyncWebSocketMessageBuffer` and `makeBuffer()` in order to make the fork API-compatible with the original library from me-no-dev regarding WebSocket. -- [@mathieucarbou](https://github.com/mathieucarbou): Some code cleanup -- [@mathieucarbou](https://github.com/mathieucarbou): Use `-D DEFAULT_MAX_WS_CLIENTS` to change the number of allows WebSocket clients and use `cleanupClients()` to help cleanup resources about dead clients -- [@nilo85](https://github.com/nilo85): Add support for Auth & GET requests in AsyncCallbackJsonWebHandler ([#14](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/14)) -- [@p0p-x](https://github.com/p0p-x): ESP IDF Compatibility (added back CMakeLists.txt) ([#32](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/32)) -- [@tueddy](https://github.com/tueddy): Compile with Arduino 3 (ESP-IDF 5.1) ([#13](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/13)) -- [@vortigont](https://github.com/vortigont): Set real "Last-Modified" header based on file's LastWrite time ([#5](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/5)) -- [@vortigont](https://github.com/vortigont): Some websocket code cleanup ([#29](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/29)) -- [@vortigont](https://github.com/vortigont): Refactor code - replace DYI structs with STL objects ([#39](https://github.com/mathieucarbou/ESPAsyncWebServer/pull/39)) +- `char*` overloads to avoid using `String` +- `DEFAULT_MAX_WS_CLIENTS` to change the number of allows WebSocket clients and use `cleanupClients()` to help cleanup resources about dead clients +- `setCloseClientOnQueueFull(bool)` which can be set on a client to either close the connection or discard messages but not close the connection when the queue is full +- `SSE_MAX_QUEUED_MESSAGES` to control the maximum number of messages that can be queued for a SSE client +- `StreamConcat` example to show how to stream multiple files in one response +- `WS_MAX_QUEUED_MESSAGES`: control the maximum number of messages that can be queued for a Websocket client +- A lot of bug fixes +- Arduino 3 / ESP-IDF 5 compatibility +- Arduino Json 7 compatibility and backward compatible with 6 +- Better CI with a complete matrix of Arduino versions and boards +- Code size improvements +- Deployed in PlatformIO registry and Arduino IDE library manager +- ESP32 / ESP8266 / RP2040 support +- Lot of code cleanup and optimizations +- Performance improvements in terms of memory, speed and size +- Support overriding default response headers +- Support resumable downloads using HEAD and bytes range ## Documentation From e45082fe86a671e6b43ee83559c2d67bdcd81865 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Sat, 7 Sep 2024 20:50:36 +0200 Subject: [PATCH 357/551] doc --- README.md | 2 ++ docs/index.md | 2 ++ 2 files changed, 4 insertions(+) diff --git a/README.md b/README.md index 502a84f18..55292c815 100644 --- a/README.md +++ b/README.md @@ -45,7 +45,9 @@ Dependency: - Deployed in PlatformIO registry and Arduino IDE library manager - ESP32 / ESP8266 / RP2040 support - Lot of code cleanup and optimizations +- MessagePack support - Performance improvements in terms of memory, speed and size +- Removed ESPIDF Editor (this is not the role of a web server library to do that - get the source files from the original repos if required) - Support overriding default response headers - Support resumable downloads using HEAD and bytes range diff --git a/docs/index.md b/docs/index.md index 502a84f18..55292c815 100644 --- a/docs/index.md +++ b/docs/index.md @@ -45,7 +45,9 @@ Dependency: - Deployed in PlatformIO registry and Arduino IDE library manager - ESP32 / ESP8266 / RP2040 support - Lot of code cleanup and optimizations +- MessagePack support - Performance improvements in terms of memory, speed and size +- Removed ESPIDF Editor (this is not the role of a web server library to do that - get the source files from the original repos if required) - Support overriding default response headers - Support resumable downloads using HEAD and bytes range From 244e592de3d7d31faf84136182ae13ee6e5cbf0b Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Sun, 8 Sep 2024 12:11:03 +0200 Subject: [PATCH 358/551] typos --- src/WebServer.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/WebServer.cpp b/src/WebServer.cpp index d7c9a0219..58fdf6069 100644 --- a/src/WebServer.cpp +++ b/src/WebServer.cpp @@ -24,19 +24,19 @@ using namespace asyncsrv; bool ON_STA_FILTER(AsyncWebServerRequest* request) { - #ifndef CONFIG_IDF_TARGET_ESP32H2 +#ifndef CONFIG_IDF_TARGET_ESP32H2 return WiFi.localIP() == request->client()->localIP(); - #else +#else return false; - #endif +#endif } bool ON_AP_FILTER(AsyncWebServerRequest* request) { - #ifndef CONFIG_IDF_TARGET_ESP32H2 +#ifndef CONFIG_IDF_TARGET_ESP32H2 return WiFi.localIP() != request->client()->localIP(); - #else +#else return false; - #endif +#endif } #ifndef HAVE_FS_FILE_OPEN_MODE From 3bdd6a9ada6401e534990daa6af1556aa9351512 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Sun, 8 Sep 2024 22:35:01 +0200 Subject: [PATCH 359/551] Code cleanup --- src/ESPAsyncWebServer.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index 5292010e8..39bf285c4 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -544,9 +544,9 @@ class AsyncWebHandler { virtual bool canHandle(AsyncWebServerRequest* request __attribute__((unused))) { return false; } - virtual void handleRequest(AsyncWebServerRequest* request __attribute__((unused))) {} - virtual void handleUpload(AsyncWebServerRequest* request __attribute__((unused)), const String& filename __attribute__((unused)), size_t index __attribute__((unused)), uint8_t* data __attribute__((unused)), size_t len __attribute__((unused)), bool final __attribute__((unused))) {} - virtual void handleBody(AsyncWebServerRequest* request __attribute__((unused)), uint8_t* data __attribute__((unused)), size_t len __attribute__((unused)), size_t index __attribute__((unused)), size_t total __attribute__((unused))) {} + virtual void handleRequest(AsyncWebServerRequest* request) {} + virtual void handleUpload(AsyncWebServerRequest* request, const String& filename, size_t index, uint8_t* data, size_t len, bool final) {} + virtual void handleBody(AsyncWebServerRequest* request, uint8_t* data, size_t len, size_t index, size_t total) {} virtual bool isRequestHandlerTrivial() { return true; } }; From 7b560ec7c50fb7fa5a7108645fa6517d36d2d074 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Mon, 9 Sep 2024 17:10:49 +0200 Subject: [PATCH 360/551] Update deprecation notices --- src/ESPAsyncWebServer.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index 39bf285c4..6cfec3333 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -336,13 +336,13 @@ class AsyncWebServerRequest { void sendChunked(const String& contentType, AwsResponseFiller callback, AwsTemplateProcessor templateCallback = nullptr) { send(beginChunkedResponse(contentType, callback, templateCallback)); } #ifndef ESP8266 - [[deprecated("Replaced by send(...)")]] + [[deprecated("Replaced by send(...). Will be removed in version 4.")]] #endif void send_P(int code, const String& contentType, const uint8_t* content, size_t len, AwsTemplateProcessor callback = nullptr) { send(code, contentType, content, len, callback); } #ifndef ESP8266 - [[deprecated("Replaced by send(...)")]] + [[deprecated("Replaced by send(...). Will be removed in version 4.")]] #endif void send_P(int code, const String& contentType, PGM_P content, AwsTemplateProcessor callback = nullptr) { send(code, contentType, content, callback); @@ -377,13 +377,13 @@ class AsyncWebServerRequest { AsyncResponseStream* beginResponseStream(const String& contentType, size_t bufferSize = 1460) { return beginResponseStream(contentType.c_str(), bufferSize); } #ifndef ESP8266 - [[deprecated("Replaced by beginResponse(...)")]] + [[deprecated("Replaced by beginResponse(...). Will be removed in version 4.")]] #endif AsyncWebServerResponse* beginResponse_P(int code, const String& contentType, const uint8_t* content, size_t len, AwsTemplateProcessor callback = nullptr) { return beginResponse(code, contentType.c_str(), content, len, callback); } #ifndef ESP8266 - [[deprecated("Replaced by beginResponse(...)")]] + [[deprecated("Replaced by beginResponse(...). Will be removed in version 4.")]] #endif AsyncWebServerResponse* beginResponse_P(int code, const String& contentType, PGM_P content, AwsTemplateProcessor callback = nullptr) { return beginResponse(code, contentType.c_str(), content, callback); @@ -599,7 +599,7 @@ class AsyncWebServerResponse { virtual const AsyncWebHeader* getHeader(const char* name) const; #ifndef ESP8266 - [[deprecated("Use instead: _assembleHead(String& buffer, uint8_t version)")]] + [[deprecated("Use instead: _assembleHead(String& buffer, uint8_t version). Will be removed in version 4.")]] #endif String _assembleHead(uint8_t version) { String buffer; From 88cb670d93fdd0d740a1c6e31f6f841cc2724ba5 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Tue, 10 Sep 2024 00:05:07 +0200 Subject: [PATCH 361/551] Revert "Update deprecation notices" This reverts commit 7b560ec7c50fb7fa5a7108645fa6517d36d2d074. --- src/ESPAsyncWebServer.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index 6cfec3333..39bf285c4 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -336,13 +336,13 @@ class AsyncWebServerRequest { void sendChunked(const String& contentType, AwsResponseFiller callback, AwsTemplateProcessor templateCallback = nullptr) { send(beginChunkedResponse(contentType, callback, templateCallback)); } #ifndef ESP8266 - [[deprecated("Replaced by send(...). Will be removed in version 4.")]] + [[deprecated("Replaced by send(...)")]] #endif void send_P(int code, const String& contentType, const uint8_t* content, size_t len, AwsTemplateProcessor callback = nullptr) { send(code, contentType, content, len, callback); } #ifndef ESP8266 - [[deprecated("Replaced by send(...). Will be removed in version 4.")]] + [[deprecated("Replaced by send(...)")]] #endif void send_P(int code, const String& contentType, PGM_P content, AwsTemplateProcessor callback = nullptr) { send(code, contentType, content, callback); @@ -377,13 +377,13 @@ class AsyncWebServerRequest { AsyncResponseStream* beginResponseStream(const String& contentType, size_t bufferSize = 1460) { return beginResponseStream(contentType.c_str(), bufferSize); } #ifndef ESP8266 - [[deprecated("Replaced by beginResponse(...). Will be removed in version 4.")]] + [[deprecated("Replaced by beginResponse(...)")]] #endif AsyncWebServerResponse* beginResponse_P(int code, const String& contentType, const uint8_t* content, size_t len, AwsTemplateProcessor callback = nullptr) { return beginResponse(code, contentType.c_str(), content, len, callback); } #ifndef ESP8266 - [[deprecated("Replaced by beginResponse(...). Will be removed in version 4.")]] + [[deprecated("Replaced by beginResponse(...)")]] #endif AsyncWebServerResponse* beginResponse_P(int code, const String& contentType, PGM_P content, AwsTemplateProcessor callback = nullptr) { return beginResponse(code, contentType.c_str(), content, callback); @@ -599,7 +599,7 @@ class AsyncWebServerResponse { virtual const AsyncWebHeader* getHeader(const char* name) const; #ifndef ESP8266 - [[deprecated("Use instead: _assembleHead(String& buffer, uint8_t version). Will be removed in version 4.")]] + [[deprecated("Use instead: _assembleHead(String& buffer, uint8_t version)")]] #endif String _assembleHead(uint8_t version) { String buffer; From d5a09d2ee92a83cfa426bd7ab808dea1645f8ae2 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Mon, 9 Sep 2024 00:31:51 +0200 Subject: [PATCH 362/551] (feat) Add support for request attributes - request->setAttribute(name, val) - request->hasAttribute(name) - request->getAttribute(name, defaultValue) --- src/ESPAsyncWebServer.h | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index 39bf285c4..fe8e4c952 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -26,6 +26,7 @@ #include "FS.h" #include #include +#include #include #ifdef ESP32 @@ -217,6 +218,8 @@ class AsyncWebServerRequest { std::list _params; std::vector _pathParams; + std::unordered_map, std::equal_to> _attributes; + uint8_t _multiParseState; uint8_t _boundaryPosition; size_t _itemStartIndex; @@ -469,6 +472,37 @@ class AsyncWebServerRequest { const String& header(size_t i) const; // get request header value by number const String& headerName(size_t i) const; // get request header name by number + // REQUEST ATTRIBUTES + + void setAttribute(const char* name, const char* value) { _attributes[name] = value; } + void setAttribute(const char* name, bool value) { _attributes[name] = value ? "1" : emptyString; } + void setAttribute(const char* name, long value) { _attributes[name] = String(value); } + void setAttribute(const char* name, float value, unsigned int decimalPlaces = 2) { _attributes[name] = String(value, decimalPlaces); } + void setAttribute(const char* name, double value, unsigned int decimalPlaces = 2) { _attributes[name] = String(value, decimalPlaces); } + + bool hasAttribute(const char* name) const { return _attributes.find(name) != _attributes.end(); } + + const String& getAttribute(const char* name, const String& defaultValue = emptyString) const { + auto it = _attributes.find(name); + return it != _attributes.end() ? it->second : defaultValue; + } + bool getAttribute(const char* name, bool defaultValue) const { + auto it = _attributes.find(name); + return it != _attributes.end() ? it->second == "1" : defaultValue; + } + long getAttribute(const char* name, long defaultValue) const { + auto it = _attributes.find(name); + return it != _attributes.end() ? it->second.toInt() : defaultValue; + } + float getAttribute(const char* name, float defaultValue) const { + auto it = _attributes.find(name); + return it != _attributes.end() ? it->second.toFloat() : defaultValue; + } + double getAttribute(const char* name, double defaultValue) const { + auto it = _attributes.find(name); + return it != _attributes.end() ? it->second.toDouble() : defaultValue; + } + String urlDecode(const String& text) const; }; From b4460a2a706ec4ec2a5bacb872d5603c4fa5009a Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Mon, 9 Sep 2024 17:03:27 +0200 Subject: [PATCH 363/551] (perf) Remove interesting headers to fasten request processing All headers are already parsed: interesting headers allowed to cleanup parsed headers to only keep interesting ones during request processing. Removing "interesting headers" support will keep these parsed headers in heap memory during request processing before being freed at the end of the request. If you really need to cleanup some headers to get more heap space during request processing, use a middleware and removeHeadersExcept(names) to remove some. --- examples/CaptivePortal/CaptivePortal.ino | 1 - examples/Filters/Filters.ino | 1 - src/AsyncEventSource.cpp | 2 - src/AsyncJson.h | 1 - src/AsyncMessagePack.h | 1 - src/AsyncWebSocket.cpp | 7 --- src/ESPAsyncWebServer.h | 67 ++++++++++++++++++++---- src/WebHandlerImpl.h | 1 - src/WebHandlers.cpp | 14 +---- src/WebRequest.cpp | 22 -------- src/WebServer.cpp | 1 - 11 files changed, 59 insertions(+), 59 deletions(-) diff --git a/examples/CaptivePortal/CaptivePortal.ino b/examples/CaptivePortal/CaptivePortal.ino index 2cc585110..ed9dfffea 100644 --- a/examples/CaptivePortal/CaptivePortal.ino +++ b/examples/CaptivePortal/CaptivePortal.ino @@ -20,7 +20,6 @@ class CaptiveRequestHandler : public AsyncWebHandler { virtual ~CaptiveRequestHandler() {} bool canHandle(__unused AsyncWebServerRequest* request) { - // request->addInterestingHeader("ANY"); return true; } diff --git a/examples/Filters/Filters.ino b/examples/Filters/Filters.ino index b7bbcff15..de5129a16 100644 --- a/examples/Filters/Filters.ino +++ b/examples/Filters/Filters.ino @@ -22,7 +22,6 @@ class CaptiveRequestHandler : public AsyncWebHandler { virtual ~CaptiveRequestHandler() {} bool canHandle(__unused AsyncWebServerRequest* request) { - // request->addInterestingHeader("ANY"); return true; } diff --git a/src/AsyncEventSource.cpp b/src/AsyncEventSource.cpp index 7e370ec93..60c742944 100644 --- a/src/AsyncEventSource.cpp +++ b/src/AsyncEventSource.cpp @@ -374,8 +374,6 @@ bool AsyncEventSource::canHandle(AsyncWebServerRequest* request) { if (request->method() != HTTP_GET || !request->url().equals(_url)) { return false; } - request->addInterestingHeader(T_Last_Event_ID); - request->addInterestingHeader(T_Cookie); return true; } diff --git a/src/AsyncJson.h b/src/AsyncJson.h index bca3f24c7..42a2dc1a2 100644 --- a/src/AsyncJson.h +++ b/src/AsyncJson.h @@ -198,7 +198,6 @@ class AsyncCallbackJsonWebHandler : public AsyncWebHandler { if (request_method != HTTP_GET && !request->contentType().equalsIgnoreCase(JSON_MIMETYPE)) return false; - request->addInterestingHeader("ANY"); return true; } diff --git a/src/AsyncMessagePack.h b/src/AsyncMessagePack.h index 57a882404..7fe727896 100644 --- a/src/AsyncMessagePack.h +++ b/src/AsyncMessagePack.h @@ -97,7 +97,6 @@ class AsyncCallbackMessagePackWebHandler : public AsyncWebHandler { if (request_method != HTTP_GET && !request->contentType().equalsIgnoreCase(asyncsrv::T_application_msgpack)) return false; - request->addInterestingHeader("ANY"); return true; } diff --git a/src/AsyncWebSocket.cpp b/src/AsyncWebSocket.cpp index 0b87cef1e..9ef0b5f8d 100644 --- a/src/AsyncWebSocket.cpp +++ b/src/AsyncWebSocket.cpp @@ -1078,13 +1078,6 @@ bool AsyncWebSocket::canHandle(AsyncWebServerRequest* request) { if (request->method() != HTTP_GET || !request->url().equals(_url) || !request->isExpectedRequestedConnType(RCT_WS)) return false; - request->addInterestingHeader(WS_STR_CONNECTION); - request->addInterestingHeader(WS_STR_UPGRADE); - request->addInterestingHeader(WS_STR_ORIGIN); - request->addInterestingHeader(WS_STR_COOKIE); - request->addInterestingHeader(WS_STR_VERSION); - request->addInterestingHeader(WS_STR_KEY); - request->addInterestingHeader(WS_STR_PROTOCOL); return true; } diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index fe8e4c952..0fce8639f 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -192,7 +192,6 @@ class AsyncWebServerRequest { AsyncWebServer* _server; AsyncWebHandler* _handler; AsyncWebServerResponse* _response; - std::vector _interestingHeaders; ArDisconnectHandler _onDisconnectfn; String _temp; @@ -206,7 +205,6 @@ class AsyncWebServerRequest { String _boundary; String _authorization; RequestedConnectionType _reqconntype; - void _removeNotInterestingHeaders(); bool _isDigest; bool _isMultipart; bool _isPlainPost; @@ -289,13 +287,16 @@ class AsyncWebServerRequest { void setHandler(AsyncWebHandler* handler) { _handler = handler; } - /** - * @brief add header to collect from a response - * - * @param name - */ - void addInterestingHeader(const char* name); - void addInterestingHeader(const String& name) { return addInterestingHeader(name.c_str()); }; +#ifndef ESP8266 + [[deprecated("All headers are now collected. Use removeHeadersExcept(name) if you really need to free some headers.")]] +#endif + void addInterestingHeader(__unused const char* name) { + } +#ifndef ESP8266 + [[deprecated("All headers are now collected. Use removeHeadersExcept(name) if you really need to free some headers.")]] +#endif + void addInterestingHeader(__unused const String& name) { + } /** * @brief issue 302 redirect response @@ -411,6 +412,54 @@ class AsyncWebServerRequest { const AsyncWebHeader* getHeader(const __FlashStringHelper* data) const; #endif const AsyncWebHeader* getHeader(size_t num) const; + size_t getHeaderNames(std::vector& names) const { + names.clear(); + const size_t size = _headers.size(); + names.reserve(size); + for (const auto& h : _headers) { + names.push_back(h.name().c_str()); + } + return size; + } + const std::list& getHeaders() const { return _headers; } + // Remove a header from the request. + // It will free the memory and prevent the header to be seen during request processing. + bool removeHeader(const char* name) { + const size_t size = _headers.size(); + _headers.remove_if([&name](const AsyncWebHeader& header) { return header.name().equalsIgnoreCase(name); }); + return size != _headers.size(); + } + // Remove all request headers. + void removeHeaders() { _headers.clear(); } + // Remove all request headers with the given names. + void removeHeaders(std::vector& namesToRemove) { + for (const char* name : namesToRemove) + removeHeader(name); + } + void removeHeaders(const char* names...) { + va_list args; + va_start(args, names); + for (const char* name = names; name != NULL; name = va_arg(args, const char*)) + removeHeader(name); + va_end(args); + } + void removeHeadersExcept(std::vector& namesToKeep) { + _headers.remove_if([&namesToKeep](const AsyncWebHeader& header) { + for (const char* name : namesToKeep) + if (header.name().equalsIgnoreCase(name)) + return false; + return true; + }); + } + void removeHeadersExcept(const char* names...) { + va_list args; + va_start(args, names); + std::vector namesToKeep; + for (const char* name = names; name != NULL; name = va_arg(args, const char*)) + namesToKeep.push_back(name); + va_end(args); + removeHeadersExcept(namesToKeep); + } size_t params() const; // get arguments count bool hasParam(const char* name, bool post = false, bool file = false) const; diff --git a/src/WebHandlerImpl.h b/src/WebHandlerImpl.h index b07e013f4..8ee2a6541 100644 --- a/src/WebHandlerImpl.h +++ b/src/WebHandlerImpl.h @@ -125,7 +125,6 @@ class AsyncCallbackWebHandler : public AsyncWebHandler { } else if (_uri.length() && (_uri != request->url() && !request->url().startsWith(_uri + "/"))) return false; - request->addInterestingHeader("ANY"); return true; } diff --git a/src/WebHandlers.cpp b/src/WebHandlers.cpp index d904a399d..b87db7f1e 100644 --- a/src/WebHandlers.cpp +++ b/src/WebHandlers.cpp @@ -23,7 +23,6 @@ using namespace asyncsrv; - AsyncStaticWebHandler::AsyncStaticWebHandler(const char* uri, FS& fs, const char* path, const char* cache_control) : _fs(fs), _uri(uri), _path(path), _default_file(F("index.htm")), _cache_control(cache_control), _last_modified(), _callback(nullptr) { // Ensure leading '/' @@ -94,18 +93,7 @@ bool AsyncStaticWebHandler::canHandle(AsyncWebServerRequest* request) { if (request->method() != HTTP_GET || !request->url().startsWith(_uri) || !request->isExpectedRequestedConnType(RCT_DEFAULT, RCT_HTTP)) { return false; } - if (_getFile(request)) { - // We interested in "If-Modified-Since" header to check if file was modified - if (_last_modified.length()) - request->addInterestingHeader(F("If-Modified-Since")); - - if (_cache_control.length()) - request->addInterestingHeader(F("If-None-Match")); - - return true; - } - - return false; + return _getFile(request); } bool AsyncStaticWebHandler::_getFile(AsyncWebServerRequest* request) { diff --git a/src/WebRequest.cpp b/src/WebRequest.cpp index 022911e85..da17d7a8c 100644 --- a/src/WebRequest.cpp +++ b/src/WebRequest.cpp @@ -49,8 +49,6 @@ AsyncWebServerRequest::~AsyncWebServerRequest() { _pathParams.clear(); - _interestingHeaders.clear(); - if (_response != NULL) { delete _response; } @@ -152,20 +150,6 @@ void AsyncWebServerRequest::_onData(void* buf, size_t len) { } } -void AsyncWebServerRequest::_removeNotInterestingHeaders() { - if (std::any_of(std::begin(_interestingHeaders), std::end(_interestingHeaders), [](const String& str) { return str.equalsIgnoreCase(T_ANY); })) - return; // nothing to do - - for (auto iter = std::begin(_headers); iter != std::end(_headers);) { - const auto name = iter->name(); - - if (std::none_of(std::begin(_interestingHeaders), std::end(_interestingHeaders), [&name](const String& str) { return str.equalsIgnoreCase(name); })) - iter = _headers.erase(iter); - else - iter++; - } -} - void AsyncWebServerRequest::_onPoll() { // os_printf("p\n"); if (_response != NULL && _client != NULL && _client->canSend()) { @@ -583,7 +567,6 @@ void AsyncWebServerRequest::_parseLine() { // end of headers _server->_rewriteRequest(this); _server->_attachHandler(this); - _removeNotInterestingHeaders(); if (_expectingContinue) { String response(T_HTTP_100_CONT); _client->write(response.c_str(), response.length()); @@ -683,11 +666,6 @@ const AsyncWebParameter* AsyncWebServerRequest::getParam(size_t num) const { return &(*std::next(_params.cbegin(), num)); } -void AsyncWebServerRequest::addInterestingHeader(const char* name) { - if (std::none_of(std::begin(_interestingHeaders), std::end(_interestingHeaders), [&name](const String& str) { return str.equalsIgnoreCase(name); })) - _interestingHeaders.emplace_back(name); -} - AsyncWebServerResponse* AsyncWebServerRequest::beginResponse(int code, const char* contentType, const char* content, AwsTemplateProcessor callback) { if (callback) return new AsyncProgmemResponse(code, contentType, (const uint8_t*)content, strlen(content), callback); diff --git a/src/WebServer.cpp b/src/WebServer.cpp index 58fdf6069..06fad781a 100644 --- a/src/WebServer.cpp +++ b/src/WebServer.cpp @@ -155,7 +155,6 @@ void AsyncWebServer::_attachHandler(AsyncWebServerRequest* request) { } } - request->addInterestingHeader(T_ANY); request->setHandler(_catchAllHandler); } From e28aa5e3fc0e19c7844ea9e322e1ae5a2beced22 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Wed, 11 Sep 2024 21:56:23 +0200 Subject: [PATCH 364/551] #define RESPONSE_STREAM_BUFFER_SIZE 1460 --- src/ESPAsyncWebServer.h | 5 +++-- src/WebRequest.cpp | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index 0fce8639f..3b4e17535 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -101,6 +101,7 @@ namespace fs { // if this value is returned when asked for data, packet will not be sent and you will be asked for data again #define RESPONSE_TRY_AGAIN 0xFFFFFFFF +#define RESPONSE_STREAM_BUFFER_SIZE 1460 typedef uint8_t WebRequestMethodComposite; typedef std::function ArDisconnectHandler; @@ -377,8 +378,8 @@ class AsyncWebServerRequest { AsyncWebServerResponse* beginChunkedResponse(const char* contentType, AwsResponseFiller callback, AwsTemplateProcessor templateCallback = nullptr); AsyncWebServerResponse* beginChunkedResponse(const String& contentType, AwsResponseFiller callback, AwsTemplateProcessor templateCallback = nullptr); - AsyncResponseStream* beginResponseStream(const char* contentType, size_t bufferSize = 1460); - AsyncResponseStream* beginResponseStream(const String& contentType, size_t bufferSize = 1460) { return beginResponseStream(contentType.c_str(), bufferSize); } + AsyncResponseStream* beginResponseStream(const char* contentType, size_t bufferSize = RESPONSE_STREAM_BUFFER_SIZE); + AsyncResponseStream* beginResponseStream(const String& contentType, size_t bufferSize = RESPONSE_STREAM_BUFFER_SIZE) { return beginResponseStream(contentType.c_str(), bufferSize); } #ifndef ESP8266 [[deprecated("Replaced by beginResponse(...)")]] diff --git a/src/WebRequest.cpp b/src/WebRequest.cpp index da17d7a8c..0dd0d2131 100644 --- a/src/WebRequest.cpp +++ b/src/WebRequest.cpp @@ -340,7 +340,7 @@ void AsyncWebServerRequest::_parsePlainPostChar(uint8_t data) { void AsyncWebServerRequest::_handleUploadByte(uint8_t data, bool last) { _itemBuffer[_itemBufferIndex++] = data; - if (last || _itemBufferIndex == 1460) { + if (last || _itemBufferIndex == RESPONSE_STREAM_BUFFER_SIZE) { // check if authenticated before calling the upload if (_handler) _handler->handleUpload(this, _itemFilename, _itemSize - _itemBufferIndex, _itemBuffer, _itemBufferIndex, false); @@ -444,7 +444,7 @@ void AsyncWebServerRequest::_parseMultipartPostByte(uint8_t data, bool last) { if (_itemIsFile) { if (_itemBuffer) free(_itemBuffer); - _itemBuffer = (uint8_t*)malloc(1460); + _itemBuffer = (uint8_t*)malloc(RESPONSE_STREAM_BUFFER_SIZE); if (_itemBuffer == NULL) { _multiParseState = PARSE_ERROR; return; From f7371c870d01e4e7c1cc29d9d201b597f3849f6f Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Thu, 12 Sep 2024 00:04:55 +0200 Subject: [PATCH 365/551] Code simplification --- src/ESPAsyncWebServer.h | 17 ++++++++++++----- src/WebServer.cpp | 38 -------------------------------------- 2 files changed, 12 insertions(+), 43 deletions(-) diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index 3b4e17535..00386faad 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -100,7 +100,7 @@ namespace fs { #endif // if this value is returned when asked for data, packet will not be sent and you will be asked for data again -#define RESPONSE_TRY_AGAIN 0xFFFFFFFF +#define RESPONSE_TRY_AGAIN 0xFFFFFFFF #define RESPONSE_STREAM_BUFFER_SIZE 1460 typedef uint8_t WebRequestMethodComposite; @@ -771,10 +771,17 @@ class AsyncWebServer { AsyncWebHandler& addHandler(AsyncWebHandler* handler); bool removeHandler(AsyncWebHandler* handler); - AsyncCallbackWebHandler& on(const char* uri, ArRequestHandlerFunction onRequest); - AsyncCallbackWebHandler& on(const char* uri, WebRequestMethodComposite method, ArRequestHandlerFunction onRequest); - AsyncCallbackWebHandler& on(const char* uri, WebRequestMethodComposite method, ArRequestHandlerFunction onRequest, ArUploadHandlerFunction onUpload); - AsyncCallbackWebHandler& on(const char* uri, WebRequestMethodComposite method, ArRequestHandlerFunction onRequest, ArUploadHandlerFunction onUpload, ArBodyHandlerFunction onBody); + AsyncCallbackWebHandler& on(const char* uri, ArRequestHandlerFunction onRequest) { return on(uri, HTTP_ANY, onRequest); } + AsyncCallbackWebHandler& on(const char* uri, WebRequestMethodComposite method, ArRequestHandlerFunction onRequest, ArUploadHandlerFunction onUpload = nullptr, ArBodyHandlerFunction onBody = nullptr) { + AsyncCallbackWebHandler* handler = new AsyncCallbackWebHandler(); + handler->setUri(uri); + handler->setMethod(method); + handler->onRequest(onRequest); + handler->onUpload(onUpload); + handler->onBody(onBody); + addHandler(handler); + return *handler; + } AsyncStaticWebHandler& serveStatic(const char* uri, fs::FS& fs, const char* path, const char* cache_control = NULL); diff --git a/src/WebServer.cpp b/src/WebServer.cpp index 06fad781a..f2ea0a2be 100644 --- a/src/WebServer.cpp +++ b/src/WebServer.cpp @@ -158,44 +158,6 @@ void AsyncWebServer::_attachHandler(AsyncWebServerRequest* request) { request->setHandler(_catchAllHandler); } -AsyncCallbackWebHandler& AsyncWebServer::on(const char* uri, WebRequestMethodComposite method, ArRequestHandlerFunction onRequest, ArUploadHandlerFunction onUpload, ArBodyHandlerFunction onBody) { - AsyncCallbackWebHandler* handler = new AsyncCallbackWebHandler(); - handler->setUri(uri); - handler->setMethod(method); - handler->onRequest(onRequest); - handler->onUpload(onUpload); - handler->onBody(onBody); - addHandler(handler); - return *handler; -} - -AsyncCallbackWebHandler& AsyncWebServer::on(const char* uri, WebRequestMethodComposite method, ArRequestHandlerFunction onRequest, ArUploadHandlerFunction onUpload) { - AsyncCallbackWebHandler* handler = new AsyncCallbackWebHandler(); - handler->setUri(uri); - handler->setMethod(method); - handler->onRequest(onRequest); - handler->onUpload(onUpload); - addHandler(handler); - return *handler; -} - -AsyncCallbackWebHandler& AsyncWebServer::on(const char* uri, WebRequestMethodComposite method, ArRequestHandlerFunction onRequest) { - AsyncCallbackWebHandler* handler = new AsyncCallbackWebHandler(); - handler->setUri(uri); - handler->setMethod(method); - handler->onRequest(onRequest); - addHandler(handler); - return *handler; -} - -AsyncCallbackWebHandler& AsyncWebServer::on(const char* uri, ArRequestHandlerFunction onRequest) { - AsyncCallbackWebHandler* handler = new AsyncCallbackWebHandler(); - handler->setUri(uri); - handler->onRequest(onRequest); - addHandler(handler); - return *handler; -} - AsyncStaticWebHandler& AsyncWebServer::serveStatic(const char* uri, fs::FS& fs, const char* path, const char* cache_control) { AsyncStaticWebHandler* handler = new AsyncStaticWebHandler(uri, fs, path, cache_control); addHandler(handler); From 072b7f82b5970c8d31d58bb4ea280c3d8f9002f9 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Thu, 12 Sep 2024 00:08:01 +0200 Subject: [PATCH 366/551] Fix last commit --- src/ESPAsyncWebServer.h | 11 +---------- src/WebServer.cpp | 11 +++++++++++ 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index 00386faad..4f75c0600 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -772,16 +772,7 @@ class AsyncWebServer { bool removeHandler(AsyncWebHandler* handler); AsyncCallbackWebHandler& on(const char* uri, ArRequestHandlerFunction onRequest) { return on(uri, HTTP_ANY, onRequest); } - AsyncCallbackWebHandler& on(const char* uri, WebRequestMethodComposite method, ArRequestHandlerFunction onRequest, ArUploadHandlerFunction onUpload = nullptr, ArBodyHandlerFunction onBody = nullptr) { - AsyncCallbackWebHandler* handler = new AsyncCallbackWebHandler(); - handler->setUri(uri); - handler->setMethod(method); - handler->onRequest(onRequest); - handler->onUpload(onUpload); - handler->onBody(onBody); - addHandler(handler); - return *handler; - } + AsyncCallbackWebHandler& on(const char* uri, WebRequestMethodComposite method, ArRequestHandlerFunction onRequest, ArUploadHandlerFunction onUpload = nullptr, ArBodyHandlerFunction onBody = nullptr); AsyncStaticWebHandler& serveStatic(const char* uri, fs::FS& fs, const char* path, const char* cache_control = NULL); diff --git a/src/WebServer.cpp b/src/WebServer.cpp index f2ea0a2be..588bd01f8 100644 --- a/src/WebServer.cpp +++ b/src/WebServer.cpp @@ -158,6 +158,17 @@ void AsyncWebServer::_attachHandler(AsyncWebServerRequest* request) { request->setHandler(_catchAllHandler); } +AsyncCallbackWebHandler& AsyncWebServer::on(const char* uri, WebRequestMethodComposite method, ArRequestHandlerFunction onRequest, ArUploadHandlerFunction onUpload, ArBodyHandlerFunction onBody) { + AsyncCallbackWebHandler* handler = new AsyncCallbackWebHandler(); + handler->setUri(uri); + handler->setMethod(method); + handler->onRequest(onRequest); + handler->onUpload(onUpload); + handler->onBody(onBody); + addHandler(handler); + return *handler; +} + AsyncStaticWebHandler& AsyncWebServer::serveStatic(const char* uri, fs::FS& fs, const char* path, const char* cache_control) { AsyncStaticWebHandler* handler = new AsyncStaticWebHandler(uri, fs, path, cache_control); addHandler(handler); From 4166d9002f260798a819b1c138ab7e2bdbe7cd14 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Fri, 13 Sep 2024 16:46:41 +0200 Subject: [PATCH 367/551] Fix header removal logic --- examples/SimpleServer/SimpleServer.ino | 23 ++++- src/ESPAsyncWebServer.h | 121 ++++++++++--------------- 2 files changed, 70 insertions(+), 74 deletions(-) diff --git a/examples/SimpleServer/SimpleServer.ino b/examples/SimpleServer/SimpleServer.ino index 2a2079a6b..16f1a7190 100644 --- a/examples/SimpleServer/SimpleServer.ino +++ b/examples/SimpleServer/SimpleServer.ino @@ -85,6 +85,27 @@ void setup() { WiFi.softAP("esp-captive"); #endif + // Request header manipulations + // curl -v -X GET -H "x-remove-me: value" http://192.168.4.1/headers + server.on("/headers", HTTP_GET, [](AsyncWebServerRequest* request) { + Serial.printf("Request Headers:\n"); + for (auto& h : request->getHeaders()) + Serial.printf("Request Header: %s = %s\n", h.name().c_str(), h.value().c_str()); + + // remove x-remove-me header + request->removeHeader("x-remove-me"); + Serial.printf("Request Headers:\n"); + for (auto& h : request->getHeaders()) + Serial.printf("Request Header: %s = %s\n", h.name().c_str(), h.value().c_str()); + + std::vector headers; + request->getHeaderNames(headers); + for (auto& h : headers) + Serial.printf("Request Header Name: %s\n", h); + + request->send(200); + }); + server.on("/", HTTP_GET, [](AsyncWebServerRequest* request) { request->send(200, "text/plain", "Hello, world"); }); @@ -197,7 +218,7 @@ void setup() { }); ws.onEvent([](AsyncWebSocket* server, AsyncWebSocketClient* client, AwsEventType type, void* arg, uint8_t* data, size_t len) { - (void) len; + (void)len; if (type == WS_EVT_CONNECT) { Serial.println("ws connect"); client->setCloseClientOnQueueFull(false); diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index 4f75c0600..afb598217 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -289,12 +289,12 @@ class AsyncWebServerRequest { void setHandler(AsyncWebHandler* handler) { _handler = handler; } #ifndef ESP8266 - [[deprecated("All headers are now collected. Use removeHeadersExcept(name) if you really need to free some headers.")]] + [[deprecated("All headers are now collected. Use removeHeader(name) or HeaderFreeMiddleware if you really need to free some headers.")]] #endif void addInterestingHeader(__unused const char* name) { } #ifndef ESP8266 - [[deprecated("All headers are now collected. Use removeHeadersExcept(name) if you really need to free some headers.")]] + [[deprecated("All headers are now collected. Use removeHeader(name) or HeaderFreeMiddleware if you really need to free some headers.")]] #endif void addInterestingHeader(__unused const String& name) { } @@ -398,77 +398,6 @@ class AsyncWebServerRequest { AsyncWebServerResponse* beginResponse(int code, const String& contentType, PGM_P content, AwsTemplateProcessor callback = nullptr); #endif - size_t headers() const; // get header count - - // check if header exists - bool hasHeader(const char* name) const; - bool hasHeader(const String& name) const { return hasHeader(name.c_str()); }; -#ifdef ESP8266 - bool hasHeader(const __FlashStringHelper* data) const; // check if header exists -#endif - - const AsyncWebHeader* getHeader(const char* name) const; - const AsyncWebHeader* getHeader(const String& name) const { return getHeader(name.c_str()); }; -#ifdef ESP8266 - const AsyncWebHeader* getHeader(const __FlashStringHelper* data) const; -#endif - const AsyncWebHeader* getHeader(size_t num) const; - size_t getHeaderNames(std::vector& names) const { - names.clear(); - const size_t size = _headers.size(); - names.reserve(size); - for (const auto& h : _headers) { - names.push_back(h.name().c_str()); - } - return size; - } - const std::list& getHeaders() const { return _headers; } - // Remove a header from the request. - // It will free the memory and prevent the header to be seen during request processing. - bool removeHeader(const char* name) { - const size_t size = _headers.size(); - _headers.remove_if([&name](const AsyncWebHeader& header) { return header.name().equalsIgnoreCase(name); }); - return size != _headers.size(); - } - // Remove all request headers. - void removeHeaders() { _headers.clear(); } - // Remove all request headers with the given names. - void removeHeaders(std::vector& namesToRemove) { - for (const char* name : namesToRemove) - removeHeader(name); - } - void removeHeaders(const char* names...) { - va_list args; - va_start(args, names); - for (const char* name = names; name != NULL; name = va_arg(args, const char*)) - removeHeader(name); - va_end(args); - } - void removeHeadersExcept(std::vector& namesToKeep) { - _headers.remove_if([&namesToKeep](const AsyncWebHeader& header) { - for (const char* name : namesToKeep) - if (header.name().equalsIgnoreCase(name)) - return false; - return true; - }); - } - void removeHeadersExcept(const char* names...) { - va_list args; - va_start(args, names); - std::vector namesToKeep; - for (const char* name = names; name != NULL; name = va_arg(args, const char*)) - namesToKeep.push_back(name); - va_end(args); - removeHeadersExcept(namesToKeep); - } - - size_t params() const; // get arguments count - bool hasParam(const char* name, bool post = false, bool file = false) const; - bool hasParam(const String& name, bool post = false, bool file = false) const { return hasParam(name.c_str(), post, file); }; -#ifdef ESP8266 - bool hasParam(const __FlashStringHelper* data, bool post = false, bool file = false) const { return hasParam(String(data).c_str(), post, file); }; -#endif - /** * @brief Get the Request parameter by name * @@ -522,6 +451,52 @@ class AsyncWebServerRequest { const String& header(size_t i) const; // get request header value by number const String& headerName(size_t i) const; // get request header name by number + size_t headers() const; // get header count + + // check if header exists + bool hasHeader(const char* name) const; + bool hasHeader(const String& name) const { return hasHeader(name.c_str()); }; +#ifdef ESP8266 + bool hasHeader(const __FlashStringHelper* data) const; // check if header exists +#endif + + const AsyncWebHeader* getHeader(const char* name) const; + const AsyncWebHeader* getHeader(const String& name) const { return getHeader(name.c_str()); }; +#ifdef ESP8266 + const AsyncWebHeader* getHeader(const __FlashStringHelper* data) const; +#endif + + const AsyncWebHeader* getHeader(size_t num) const; + + const std::list& getHeaders() const { return _headers; } + + size_t getHeaderNames(std::vector& names) const { + names.clear(); + const size_t size = _headers.size(); + names.reserve(size); + for (const auto& h : _headers) { + names.push_back(h.name().c_str()); + } + return size; + } + + // Remove a header from the request. + // It will free the memory and prevent the header to be seen during request processing. + bool removeHeader(const char* name) { + const size_t size = _headers.size(); + _headers.remove_if([name](const AsyncWebHeader& header) { return header.name().equalsIgnoreCase(name); }); + return size != _headers.size(); + } + // Remove all request headers. + void removeHeaders() { _headers.clear(); } + + size_t params() const; // get arguments count + bool hasParam(const char* name, bool post = false, bool file = false) const; + bool hasParam(const String& name, bool post = false, bool file = false) const { return hasParam(name.c_str(), post, file); }; +#ifdef ESP8266 + bool hasParam(const __FlashStringHelper* data, bool post = false, bool file = false) const { return hasParam(String(data).c_str(), post, file); }; +#endif + // REQUEST ATTRIBUTES void setAttribute(const char* name, const char* value) { _attributes[name] = value; } From cadd61898b9b169ae7ed73e9d41fe5d82d4fada2 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Fri, 13 Sep 2024 16:49:47 +0200 Subject: [PATCH 368/551] pioarduino update --- platformio.ini | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platformio.ini b/platformio.ini index 53173ad21..c9515aeb3 100644 --- a/platformio.ini +++ b/platformio.ini @@ -37,7 +37,7 @@ platform = https://github.com/pioarduino/platform-espressif32/releases/download/ ; board = esp32-c6-devkitc-1 [env:arduino-310rc1] -platform = https://github.com/pioarduino/platform-espressif32/releases/download/53.03.10%%2Brc1/platform-espressif32.zip +platform = https://github.com/pioarduino/platform-espressif32/releases/download/53.03.10-rc1/platform-espressif32.zip ; board = esp32-s3-devkitc-1 ; board = esp32-c6-devkitc-1 @@ -73,7 +73,7 @@ platform = https://github.com/pioarduino/platform-espressif32/releases/download/ board = ${sysenv.PIO_BOARD} [env:ci-arduino-310rc1] -platform = https://github.com/pioarduino/platform-espressif32/releases/download/53.03.10%%2Brc1/platform-espressif32.zip +platform = https://github.com/pioarduino/platform-espressif32/releases/download/53.03.10-rc1/platform-espressif32.zip board = ${sysenv.PIO_BOARD} [env:ci-esp8266] From 4b03e071b42eb0a5eee0d20bdf289310ff455b0c Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Fri, 13 Sep 2024 23:33:50 +0200 Subject: [PATCH 369/551] Exposing new methods: - sent response from request - response code - response headers And fixed missing response when a handler forget to respond (501) --- examples/SimpleServer/SimpleServer.ino | 10 ++++++++++ src/ESPAsyncWebServer.h | 6 ++++++ src/WebRequest.cpp | 14 ++++++-------- 3 files changed, 22 insertions(+), 8 deletions(-) diff --git a/examples/SimpleServer/SimpleServer.ino b/examples/SimpleServer/SimpleServer.ino index 16f1a7190..aec811069 100644 --- a/examples/SimpleServer/SimpleServer.ino +++ b/examples/SimpleServer/SimpleServer.ino @@ -85,7 +85,15 @@ void setup() { WiFi.softAP("esp-captive"); #endif + // curl -v -X GET http://192.168.4.1/handler-not-sending-response + server.on("/handler-not-sending-response", HTTP_GET, [](AsyncWebServerRequest* request) { + // handler forgot to send a response to the client => 501 Not Implemented + }); + + /////////////////////////////////////////////////////////////////////// // Request header manipulations + /////////////////////////////////////////////////////////////////////// + // curl -v -X GET -H "x-remove-me: value" http://192.168.4.1/headers server.on("/headers", HTTP_GET, [](AsyncWebServerRequest* request) { Serial.printf("Request Headers:\n"); @@ -106,6 +114,8 @@ void setup() { request->send(200); }); + /////////////////////////////////////////////////////////////////////// + server.on("/", HTTP_GET, [](AsyncWebServerRequest* request) { request->send(200, "text/plain", "Hello, world"); }); diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index afb598217..b2274b5b2 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -195,6 +195,9 @@ class AsyncWebServerRequest { AsyncWebServerResponse* _response; ArDisconnectHandler _onDisconnectfn; + // response is sent + bool _sent = false; + String _temp; uint8_t _parseState; @@ -308,6 +311,7 @@ class AsyncWebServerRequest { void redirect(const String& url) { return redirect(url.c_str()); }; void send(AsyncWebServerResponse* response); + const AsyncWebServerResponse* sentResponse() const { return _response; } void send(int code, const char* contentType = asyncsrv::empty, const char* content = asyncsrv::empty, AwsTemplateProcessor callback = nullptr) { send(beginResponse(code, contentType, content, callback)); } void send(int code, const String& contentType, const String& content = emptyString, AwsTemplateProcessor callback = nullptr) { send(beginResponse(code, contentType, content, callback)); } @@ -647,6 +651,7 @@ class AsyncWebServerResponse { AsyncWebServerResponse(); virtual ~AsyncWebServerResponse(); virtual void setCode(int code); + int code() const { return _code; } virtual void setContentLength(size_t len); void setContentType(const String& type) { setContentType(type.c_str()); } virtual void setContentType(const char* type); @@ -656,6 +661,7 @@ class AsyncWebServerResponse { bool addHeader(const String& name, long value, bool replaceExisting = true) { return addHeader(name.c_str(), value, replaceExisting); } virtual bool removeHeader(const char* name); virtual const AsyncWebHeader* getHeader(const char* name) const; + const std::list& getHeaders() const { return _headers; } #ifndef ESP8266 [[deprecated("Use instead: _assembleHead(String& buffer, uint8_t version)")]] diff --git a/src/WebRequest.cpp b/src/WebRequest.cpp index 0dd0d2131..ad2a96f6e 100644 --- a/src/WebRequest.cpp +++ b/src/WebRequest.cpp @@ -123,7 +123,6 @@ void AsyncWebServerRequest::_onData(void* buf, size_t len) { } } if (!_isPlainPost) { - // check if authenticated before calling the body if (_handler) _handler->handleBody(this, (uint8_t*)buf, len, _parsedLength, _contentLength); _parsedLength += len; @@ -139,11 +138,10 @@ void AsyncWebServerRequest::_onData(void* buf, size_t len) { } if (_parsedLength == _contentLength) { _parseState = PARSE_REQ_END; - // check if authenticated before calling handleRequest and request auth instead if (_handler) _handler->handleRequest(this); - else - send(501); + if (!_sent) + send(501, T_text_plain, "Handler did not handle the request"); } } break; @@ -498,7 +496,6 @@ void AsyncWebServerRequest::_parseMultipartPostByte(uint8_t data, bool last) { _params.emplace_back(_itemName, _itemValue, true); } else { if (_itemSize) { - // check if authenticated before calling the upload if (_handler) _handler->handleUpload(this, _itemFilename, _itemSize - _itemBufferIndex, _itemBuffer, _itemBufferIndex, true); _itemBufferIndex = 0; @@ -571,15 +568,14 @@ void AsyncWebServerRequest::_parseLine() { String response(T_HTTP_100_CONT); _client->write(response.c_str(), response.length()); } - // check handler for authentication if (_contentLength) { _parseState = PARSE_REQ_BODY; } else { _parseState = PARSE_REQ_END; if (_handler) _handler->handleRequest(this); - else - send(501); + if (!_sent) + send(501, T_text_plain, "Handler did not handle the request"); } } else _parseReqHeader(); @@ -717,6 +713,7 @@ void AsyncWebServerRequest::send(AsyncWebServerResponse* response) { if (_response == NULL) { _client->close(true); _onDisconnect(); + _sent = true; return; } if (!_response->_sourceValid()) { @@ -726,6 +723,7 @@ void AsyncWebServerRequest::send(AsyncWebServerResponse* response) { } else { _client->setRxTimeout(0); _response->_respond(this); + _sent = true; } } From 741841a078069e8bbeb6b27bde11e5c543710993 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Sat, 14 Sep 2024 00:46:38 +0200 Subject: [PATCH 370/551] not needed to clear response headers: they will be freed once response will be deleted --- src/WebResponses.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/WebResponses.cpp b/src/WebResponses.cpp index 1fb6188ec..2705fd373 100644 --- a/src/WebResponses.cpp +++ b/src/WebResponses.cpp @@ -318,7 +318,6 @@ void AsyncWebServerResponse::_assembleHead(String& buffer, uint8_t version) { buffer.concat(header.value()); buffer.concat(T_rn); } - _headers.clear(); buffer.concat(T_rn); _headLength = buffer.length(); From 571eac4d0093dc51f1cf592788f24a6e20f84f40 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Sat, 14 Sep 2024 00:56:47 +0200 Subject: [PATCH 371/551] Support for replacing a response by a new one --- README.md | 15 +++++++++++++ docs/index.md | 15 +++++++++++++ examples/SimpleServer/SimpleServer.ino | 13 +++++++++++ src/ESPAsyncWebServer.h | 2 +- src/WebRequest.cpp | 31 ++++++++++++++++---------- 5 files changed, 63 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 55292c815..b39a55f5e 100644 --- a/README.md +++ b/README.md @@ -121,3 +121,18 @@ If you have smaller messages, you can increase `WS_MAX_QUEUED_MESSAGES` to 128. -D CONFIG_ASYNC_TCP_STACK_SIZE=4096 -D WS_MAX_QUEUED_MESSAGES=64 ``` + +## Replace response + +```c++ + // It is possible to replace a response. + // The previous one will be deleted. + // Response sending happens when the handler returns. + server.on("/replace", HTTP_GET, [](AsyncWebServerRequest* request) { + request->send(200, "text/plain", "Hello, world"); + // oups! finally we want to send a different response + request->send(400, "text/plain", "validation error"); + }); +``` + +This will send error 400 instead of 200. diff --git a/docs/index.md b/docs/index.md index 55292c815..b39a55f5e 100644 --- a/docs/index.md +++ b/docs/index.md @@ -121,3 +121,18 @@ If you have smaller messages, you can increase `WS_MAX_QUEUED_MESSAGES` to 128. -D CONFIG_ASYNC_TCP_STACK_SIZE=4096 -D WS_MAX_QUEUED_MESSAGES=64 ``` + +## Replace response + +```c++ + // It is possible to replace a response. + // The previous one will be deleted. + // Response sending happens when the handler returns. + server.on("/replace", HTTP_GET, [](AsyncWebServerRequest* request) { + request->send(200, "text/plain", "Hello, world"); + // oups! finally we want to send a different response + request->send(400, "text/plain", "validation error"); + }); +``` + +This will send error 400 instead of 200. diff --git a/examples/SimpleServer/SimpleServer.ino b/examples/SimpleServer/SimpleServer.ino index aec811069..b14b47398 100644 --- a/examples/SimpleServer/SimpleServer.ino +++ b/examples/SimpleServer/SimpleServer.ino @@ -90,6 +90,19 @@ void setup() { // handler forgot to send a response to the client => 501 Not Implemented }); + // This is possible to replace a response. + // the previous one will be deleted. + // response sending happens when the handler returns. + // curl -v -X GET http://192.168.4.1/replace + server.on("/replace", HTTP_GET, [](AsyncWebServerRequest* request) { + request->send(200, "text/plain", "Hello, world"); + // oups! finally we want to send a different response + request->send(400, "text/plain", "validation error"); +#ifndef TARGET_RP2040 + Serial.printf("Free heap: %" PRIu32 "\n", ESP.getFreeHeap()); +#endif + }); + /////////////////////////////////////////////////////////////////////// // Request header manipulations /////////////////////////////////////////////////////////////////////// diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index b2274b5b2..a55a60864 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -311,7 +311,7 @@ class AsyncWebServerRequest { void redirect(const String& url) { return redirect(url.c_str()); }; void send(AsyncWebServerResponse* response); - const AsyncWebServerResponse* sentResponse() const { return _response; } + AsyncWebServerResponse* getResponse() const { return _response; } void send(int code, const char* contentType = asyncsrv::empty, const char* content = asyncsrv::empty, AwsTemplateProcessor callback = nullptr) { send(beginResponse(code, contentType, content, callback)); } void send(int code, const String& contentType, const String& content = emptyString, AwsTemplateProcessor callback = nullptr) { send(beginResponse(code, contentType, content, callback)); } diff --git a/src/WebRequest.cpp b/src/WebRequest.cpp index ad2a96f6e..c901e94e9 100644 --- a/src/WebRequest.cpp +++ b/src/WebRequest.cpp @@ -140,8 +140,13 @@ void AsyncWebServerRequest::_onData(void* buf, size_t len) { _parseState = PARSE_REQ_END; if (_handler) _handler->handleRequest(this); - if (!_sent) - send(501, T_text_plain, "Handler did not handle the request"); + if (!_sent) { + if (!_response) + send(501, T_text_plain, "Handler did not handle the request"); + _client->setRxTimeout(0); + _response->_respond(this); + _sent = true; + } } } break; @@ -574,8 +579,13 @@ void AsyncWebServerRequest::_parseLine() { _parseState = PARSE_REQ_END; if (_handler) _handler->handleRequest(this); - if (!_sent) - send(501, T_text_plain, "Handler did not handle the request"); + if (!_sent) { + if (!_response) + send(501, T_text_plain, "Handler did not handle the request"); + _client->setRxTimeout(0); + _response->_respond(this); + _sent = true; + } } } else _parseReqHeader(); @@ -709,6 +719,10 @@ AsyncWebServerResponse* AsyncWebServerRequest::beginResponse(int code, const Str #endif void AsyncWebServerRequest::send(AsyncWebServerResponse* response) { + if (_sent) + return; + if (_response) + delete _response; _response = response; if (_response == NULL) { _client->close(true); @@ -716,15 +730,8 @@ void AsyncWebServerRequest::send(AsyncWebServerResponse* response) { _sent = true; return; } - if (!_response->_sourceValid()) { - delete response; - _response = NULL; + if (!_response->_sourceValid()) send(500); - } else { - _client->setRxTimeout(0); - _response->_respond(this); - _sent = true; - } } void AsyncWebServerRequest::redirect(const char* url) { From fa20cdf7a30813a31f62a7a69a736e306206774d Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Sat, 14 Sep 2024 09:05:25 +0200 Subject: [PATCH 372/551] update CI --- .github/workflows/dependabot.yml | 19 ------------------- 1 file changed, 19 deletions(-) delete mode 100644 .github/workflows/dependabot.yml diff --git a/.github/workflows/dependabot.yml b/.github/workflows/dependabot.yml deleted file mode 100644 index da098fd7a..000000000 --- a/.github/workflows/dependabot.yml +++ /dev/null @@ -1,19 +0,0 @@ -name: PlatformIO Dependabot - -on: - workflow_dispatch: - schedule: - # Runs every day at 01:00 - - cron: "0 1 * * *" - -jobs: - dependabot: - runs-on: ubuntu-latest - name: PlatformIO Dependabot - steps: - - name: Checkout - uses: actions/checkout@v4 - - name: run PlatformIO Dependabot - uses: peterus/platformio_dependabot@v1 - with: - github_token: ${{ secrets.GITHUB_TOKEN }} From f959bb91dd472c8e70094251ad63b8769623ba78 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Sat, 14 Sep 2024 12:53:18 +0200 Subject: [PATCH 373/551] Fix method overload issue with ESP8266. ESP8266 has to use send_P() and beginResponse_p() variants --- src/ESPAsyncWebServer.h | 36 ++++++++++++++++-------------------- src/WebRequest.cpp | 4 +--- 2 files changed, 17 insertions(+), 23 deletions(-) diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index a55a60864..bca9c375e 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -314,7 +314,8 @@ class AsyncWebServerRequest { AsyncWebServerResponse* getResponse() const { return _response; } void send(int code, const char* contentType = asyncsrv::empty, const char* content = asyncsrv::empty, AwsTemplateProcessor callback = nullptr) { send(beginResponse(code, contentType, content, callback)); } - void send(int code, const String& contentType, const String& content = emptyString, AwsTemplateProcessor callback = nullptr) { send(beginResponse(code, contentType, content, callback)); } + void send(int code, const String& contentType, const char* content = asyncsrv::empty, AwsTemplateProcessor callback = nullptr) { send(beginResponse(code, contentType.c_str(), content, callback)); } + void send(int code, const String& contentType, const String& content, AwsTemplateProcessor callback = nullptr) { send(beginResponse(code, contentType.c_str(), content.c_str(), callback)); } void send(int code, const char* contentType, const uint8_t* content, size_t len, AwsTemplateProcessor callback = nullptr) { send(beginResponse(code, contentType, content, len, callback)); } void send(int code, const String& contentType, const uint8_t* content, size_t len, AwsTemplateProcessor callback = nullptr) { send(beginResponse(code, contentType, content, len, callback)); } @@ -345,24 +346,25 @@ class AsyncWebServerRequest { void sendChunked(const String& contentType, AwsResponseFiller callback, AwsTemplateProcessor templateCallback = nullptr) { send(beginChunkedResponse(contentType, callback, templateCallback)); } #ifndef ESP8266 - [[deprecated("Replaced by send(...)")]] + [[deprecated("Replaced by send(int code, const String& contentType, const uint8_t* content, size_t len, AwsTemplateProcessor callback = nullptr)")]] #endif void send_P(int code, const String& contentType, const uint8_t* content, size_t len, AwsTemplateProcessor callback = nullptr) { send(code, contentType, content, len, callback); } #ifndef ESP8266 - [[deprecated("Replaced by send(...)")]] -#endif + [[deprecated("Replaced by send(int code, const String& contentType, const char* content = asyncsrv::empty, AwsTemplateProcessor callback = nullptr)")]] void send_P(int code, const String& contentType, PGM_P content, AwsTemplateProcessor callback = nullptr) { send(code, contentType, content, callback); } - -#ifdef ESP8266 - void send(int code, const String& contentType, PGM_P content, AwsTemplateProcessor callback = nullptr) { send(beginResponse(code, contentType, content, callback)); } +#else + void send_P(int code, const String& contentType, PGM_P content, AwsTemplateProcessor callback = nullptr) { + send(beginResponse_P(code, contentType, content, callback)); + } #endif AsyncWebServerResponse* beginResponse(int code, const char* contentType = asyncsrv::empty, const char* content = asyncsrv::empty, AwsTemplateProcessor callback = nullptr); - AsyncWebServerResponse* beginResponse(int code, const String& contentType, const String& content = emptyString, AwsTemplateProcessor callback = nullptr) { return beginResponse(code, contentType.c_str(), content.c_str(), callback); } + AsyncWebServerResponse* beginResponse(int code, const String& contentType, const char* content = asyncsrv::empty, AwsTemplateProcessor callback = nullptr) { return beginResponse(code, contentType.c_str(), content, callback); } + AsyncWebServerResponse* beginResponse(int code, const String& contentType, const String& content, AwsTemplateProcessor callback = nullptr) { return beginResponse(code, contentType.c_str(), content.c_str(), callback); } AsyncWebServerResponse* beginResponse(int code, const char* contentType, const uint8_t* content, size_t len, AwsTemplateProcessor callback = nullptr); AsyncWebServerResponse* beginResponse(int code, const String& contentType, const uint8_t* content, size_t len, AwsTemplateProcessor callback = nullptr) { return beginResponse(code, contentType.c_str(), content, len, callback); } @@ -386,21 +388,15 @@ class AsyncWebServerRequest { AsyncResponseStream* beginResponseStream(const String& contentType, size_t bufferSize = RESPONSE_STREAM_BUFFER_SIZE) { return beginResponseStream(contentType.c_str(), bufferSize); } #ifndef ESP8266 - [[deprecated("Replaced by beginResponse(...)")]] + [[deprecated("Replaced by beginResponse(int code, const String& contentType, const uint8_t* content, size_t len, AwsTemplateProcessor callback = nullptr)")]] #endif AsyncWebServerResponse* beginResponse_P(int code, const String& contentType, const uint8_t* content, size_t len, AwsTemplateProcessor callback = nullptr) { return beginResponse(code, contentType.c_str(), content, len, callback); } #ifndef ESP8266 - [[deprecated("Replaced by beginResponse(...)")]] -#endif - AsyncWebServerResponse* beginResponse_P(int code, const String& contentType, PGM_P content, AwsTemplateProcessor callback = nullptr) { - return beginResponse(code, contentType.c_str(), content, callback); - } - -#ifdef ESP8266 - AsyncWebServerResponse* beginResponse(int code, const String& contentType, PGM_P content, AwsTemplateProcessor callback = nullptr); + [[deprecated("Replaced by beginResponse(int code, const String& contentType, const char* content = asyncsrv::empty, AwsTemplateProcessor callback = nullptr)")]] #endif + AsyncWebServerResponse* beginResponse_P(int code, const String& contentType, PGM_P content, AwsTemplateProcessor callback = nullptr); /** * @brief Get the Request parameter by name @@ -607,9 +603,9 @@ class AsyncWebHandler { virtual bool canHandle(AsyncWebServerRequest* request __attribute__((unused))) { return false; } - virtual void handleRequest(AsyncWebServerRequest* request) {} - virtual void handleUpload(AsyncWebServerRequest* request, const String& filename, size_t index, uint8_t* data, size_t len, bool final) {} - virtual void handleBody(AsyncWebServerRequest* request, uint8_t* data, size_t len, size_t index, size_t total) {} + virtual void handleRequest(__unused AsyncWebServerRequest* request) {} + virtual void handleUpload(__unused AsyncWebServerRequest* request, __unused const String& filename, __unused size_t index, __unused uint8_t* data, __unused size_t len, __unused bool final) {} + virtual void handleBody(__unused AsyncWebServerRequest* request, __unused uint8_t* data, __unused size_t len, __unused size_t index, __unused size_t total) {} virtual bool isRequestHandlerTrivial() { return true; } }; diff --git a/src/WebRequest.cpp b/src/WebRequest.cpp index c901e94e9..61ec25d84 100644 --- a/src/WebRequest.cpp +++ b/src/WebRequest.cpp @@ -712,11 +712,9 @@ AsyncResponseStream* AsyncWebServerRequest::beginResponseStream(const char* cont return new AsyncResponseStream(contentType, bufferSize); } -#ifdef ESP8266 -AsyncWebServerResponse* AsyncWebServerRequest::beginResponse(int code, const String& contentType, PGM_P content, AwsTemplateProcessor callback) { +AsyncWebServerResponse* AsyncWebServerRequest::beginResponse_P(int code, const String& contentType, PGM_P content, AwsTemplateProcessor callback) { return new AsyncProgmemResponse(code, contentType, (const uint8_t*)content, strlen_P(content), callback); } -#endif void AsyncWebServerRequest::send(AsyncWebServerResponse* response) { if (_sent) From e6aea01dd3fa235b6d1a995183b7713d8e396ffb Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Sun, 8 Sep 2024 00:48:02 +0200 Subject: [PATCH 374/551] Add Middleware support in ESPAsyncWebServer --- README.md | 76 ++++++- docs/index.md | 76 ++++++- examples/SimpleServer/SimpleServer.ino | 110 +++++++++++ src/AsyncEventSource.cpp | 12 -- src/AsyncEventSource.h | 9 +- src/AsyncJson.h | 2 - src/AsyncMessagePack.h | 3 - src/AsyncWebSocket.cpp | 3 - src/ESPAsyncWebServer.h | 264 +++++++++++++++++++++++-- src/Middlewares.cpp | 84 ++++++++ src/WebHandlerImpl.h | 6 - src/WebHandlers.cpp | 2 - src/WebRequest.cpp | 6 +- src/WebResponses.cpp | 6 +- src/literals.h | 2 + 15 files changed, 612 insertions(+), 49 deletions(-) create mode 100644 src/Middlewares.cpp diff --git a/README.md b/README.md index b39a55f5e..2f7d1b81e 100644 --- a/README.md +++ b/README.md @@ -50,8 +50,9 @@ Dependency: - Removed ESPIDF Editor (this is not the role of a web server library to do that - get the source files from the original repos if required) - Support overriding default response headers - Support resumable downloads using HEAD and bytes range +- **Support for middleware** -## Documentation +## Original Documentation Usage and API stays the same as the original library. Please look at the original libraries for more examples and documentation. @@ -136,3 +137,76 @@ If you have smaller messages, you can increase `WS_MAX_QUEUED_MESSAGES` to 128. ``` This will send error 400 instead of 200. + +## Middleware + +Middleware is a way to intercept requests to perform some operations on them, like authentication, authorization, logging, etc and also act on the response headers. + +Middleware can either be attached to individual handlers, attached at the server level (thus applied to all handlers), or both. +They will be executed in the order they are attached, and they can stop the request processing by sending a response themselves. + +You can have a look at the [SimpleServer.ino](https://github.com/mathieucarbou/ESPAsyncWebServer/blob/main/examples/SimpleServer/SimpleServer.ino) example for some use cases. + +For example, such middleware would handle authentication and set some attributes on the request to make them available for the next middleware and for the handler which will process the request. + +```c++ +AsyncMiddlewareFunction complexAuth([](AsyncWebServerRequest* request, ArMiddlewareNext next) { + if (!request->authenticate("user", "password")) { + return request->requestAuthentication(); + } + + request->setAttribute("user", "Mathieu"); + request->setAttribute("role", "staff"); + + next(); // continue processing + + // you can act one the response object + request->getResponse()->addHeader("X-Rate-Limit", "200"); +}); +``` + +**Here are the list of available middlewares:** + +- `AsyncMiddlewareFunction`: can convert a lambda function (`ArMiddlewareCallback`) to a middleware +- `AuthenticationMiddleware`: to handle basic/digest authentication globally or per handler +- `AuthorizationMiddleware`: to handle authorization globally or per handler +- `CorsMiddleware`: to handle CORS preflight request globally or per handler +- `HeaderFilterMiddleware`: to filter out headers from the request +- `HeaderFreeMiddleware`: to only keep some headers from the request, and remove the others +- `LoggerMiddleware`: to log requests globally or per handler with the same pattern as curl. Will also record request processing time +- `RateLimitMiddleware`: to limit the number of requests on a windows of time globally or per handler + +## How to use authentication with AuthenticationMiddleware + +Do not use the `setUsername()` and `setPassword()` methods on the hanlders anymore. +They are deprecated. +These methods were causing a copy of the username and password for each handler, which is not efficient. + +Now, you can use the `AuthenticationMiddleware` to handle authentication globally or per handler. + +```c++ +AuthenticationMiddleware authMiddleware; + +// [...] + +authMiddleware.setAuthType(AuthenticationMiddleware::AuthType::AUTH_DIGEST); +authMiddleware.setRealm("My app name"); +authMiddleware.setUsername("admin"); +authMiddleware.setPassword("admin"); + +// [...] + +server.addMiddleware(&authMiddleware); // globally add authentication to the server + +// [...] + +myHandler.addMiddleware(&authMiddleware); // add authentication to a specific handler +``` + +## Migration to Middleware to improve performance and memory usage + +- `AsyncEventSource.authorizeConnect(...)` => do not use this method anymore: add a common `AuthorizationMiddleware` to the handler or server, and make sure to add it AFTER the `AuthenticationMiddleware` if you use authentication. +- `AsyncWebHandler.setAuthentication(...)` => do not use this method anymore: add a common `AuthenticationMiddleware` to the handler or server +- `ArUploadHandlerFunction` and `ArBodyHandlerFunction` => these callbacks receiving body data and upload and not calling anymore the authentication code for performance reasons. + These callbacks can be called multiple times, so this is up to the user to now call the `AuthenticationMiddleware` if needed and ideally when the method is called for the first time. + These callbacks are also not triggering the whole middleware chain since they are not part of the request processing workflow (they are not the final handler). diff --git a/docs/index.md b/docs/index.md index b39a55f5e..2f7d1b81e 100644 --- a/docs/index.md +++ b/docs/index.md @@ -50,8 +50,9 @@ Dependency: - Removed ESPIDF Editor (this is not the role of a web server library to do that - get the source files from the original repos if required) - Support overriding default response headers - Support resumable downloads using HEAD and bytes range +- **Support for middleware** -## Documentation +## Original Documentation Usage and API stays the same as the original library. Please look at the original libraries for more examples and documentation. @@ -136,3 +137,76 @@ If you have smaller messages, you can increase `WS_MAX_QUEUED_MESSAGES` to 128. ``` This will send error 400 instead of 200. + +## Middleware + +Middleware is a way to intercept requests to perform some operations on them, like authentication, authorization, logging, etc and also act on the response headers. + +Middleware can either be attached to individual handlers, attached at the server level (thus applied to all handlers), or both. +They will be executed in the order they are attached, and they can stop the request processing by sending a response themselves. + +You can have a look at the [SimpleServer.ino](https://github.com/mathieucarbou/ESPAsyncWebServer/blob/main/examples/SimpleServer/SimpleServer.ino) example for some use cases. + +For example, such middleware would handle authentication and set some attributes on the request to make them available for the next middleware and for the handler which will process the request. + +```c++ +AsyncMiddlewareFunction complexAuth([](AsyncWebServerRequest* request, ArMiddlewareNext next) { + if (!request->authenticate("user", "password")) { + return request->requestAuthentication(); + } + + request->setAttribute("user", "Mathieu"); + request->setAttribute("role", "staff"); + + next(); // continue processing + + // you can act one the response object + request->getResponse()->addHeader("X-Rate-Limit", "200"); +}); +``` + +**Here are the list of available middlewares:** + +- `AsyncMiddlewareFunction`: can convert a lambda function (`ArMiddlewareCallback`) to a middleware +- `AuthenticationMiddleware`: to handle basic/digest authentication globally or per handler +- `AuthorizationMiddleware`: to handle authorization globally or per handler +- `CorsMiddleware`: to handle CORS preflight request globally or per handler +- `HeaderFilterMiddleware`: to filter out headers from the request +- `HeaderFreeMiddleware`: to only keep some headers from the request, and remove the others +- `LoggerMiddleware`: to log requests globally or per handler with the same pattern as curl. Will also record request processing time +- `RateLimitMiddleware`: to limit the number of requests on a windows of time globally or per handler + +## How to use authentication with AuthenticationMiddleware + +Do not use the `setUsername()` and `setPassword()` methods on the hanlders anymore. +They are deprecated. +These methods were causing a copy of the username and password for each handler, which is not efficient. + +Now, you can use the `AuthenticationMiddleware` to handle authentication globally or per handler. + +```c++ +AuthenticationMiddleware authMiddleware; + +// [...] + +authMiddleware.setAuthType(AuthenticationMiddleware::AuthType::AUTH_DIGEST); +authMiddleware.setRealm("My app name"); +authMiddleware.setUsername("admin"); +authMiddleware.setPassword("admin"); + +// [...] + +server.addMiddleware(&authMiddleware); // globally add authentication to the server + +// [...] + +myHandler.addMiddleware(&authMiddleware); // add authentication to a specific handler +``` + +## Migration to Middleware to improve performance and memory usage + +- `AsyncEventSource.authorizeConnect(...)` => do not use this method anymore: add a common `AuthorizationMiddleware` to the handler or server, and make sure to add it AFTER the `AuthenticationMiddleware` if you use authentication. +- `AsyncWebHandler.setAuthentication(...)` => do not use this method anymore: add a common `AuthenticationMiddleware` to the handler or server +- `ArUploadHandlerFunction` and `ArBodyHandlerFunction` => these callbacks receiving body data and upload and not calling anymore the authentication code for performance reasons. + These callbacks can be called multiple times, so this is up to the user to now call the `AuthenticationMiddleware` if needed and ideally when the method is called for the first time. + These callbacks are also not triggering the whole middleware chain since they are not part of the request processing workflow (they are not the final handler). diff --git a/examples/SimpleServer/SimpleServer.ino b/examples/SimpleServer/SimpleServer.ino index b14b47398..b37ba6aab 100644 --- a/examples/SimpleServer/SimpleServer.ino +++ b/examples/SimpleServer/SimpleServer.ino @@ -28,6 +28,45 @@ AsyncWebServer server(80); AsyncEventSource events("/events"); AsyncWebSocket ws("/ws"); +///////////////////////////////////////////////////////////////////////////////////////////////////// +// Middlewares +///////////////////////////////////////////////////////////////////////////////////////////////////// + +// log incoming requests +LoggingMiddleware requestLogger; + +// CORS +CorsMiddleware cors; + +// maximum 5 requests per 10 seconds +RateLimitMiddleware rateLimit; + +// filter out specific headers from the incoming request +HeaderFilterMiddleware headerFilter; + +// remove all headers from the incoming request except the ones provided in the constructor +HeaderFreeMiddleware headerFree; + +// simple digest authentication +AuthenticationMiddleware simpleDigestAuth; + +// complex authentication which adds request attributes for the next middlewares and handler +AsyncMiddlewareFunction complexAuth([](AsyncWebServerRequest* request, ArMiddlewareNext next) { + if (!request->authenticate("user", "password")) { + return request->requestAuthentication(); + } + request->setAttribute("user", "Mathieu"); + request->setAttribute("role", "staff"); + + next(); + + request->getResponse()->addHeader("X-Rate-Limit", "200"); +}); + +AuthorizationMiddleware authz([](AsyncWebServerRequest* request) { return request->getAttribute("role") == "staff"; }); + +///////////////////////////////////////////////////////////////////////////////////////////////////// + const char* PARAM_MESSAGE PROGMEM = "message"; const char* SSE_HTLM PROGMEM = R"( @@ -127,6 +166,77 @@ void setup() { request->send(200); }); + /////////////////////////////////////////////////////////////////////// + // Middlewares at server level (will apply to all requests) + /////////////////////////////////////////////////////////////////////// + + requestLogger.setOutput(Serial); + + simpleDigestAuth.setUsername("admin"); + simpleDigestAuth.setPassword("admin"); + simpleDigestAuth.setRealm("MyApp"); + + rateLimit.setMaxRequests(5); + rateLimit.setWindowSize(10); + + headerFilter.filter("X-Remove-Me"); + headerFree.keep("X-Keep-Me"); + headerFree.keep("host"); + + // global middleware + server.addMiddleware(&requestLogger); + server.addMiddlewares({&rateLimit, &cors, &headerFilter}); + + cors.setOrigin("http://192.168.4.1"); + cors.setMethods("POST, GET, OPTIONS, DELETE"); + cors.setHeaders("X-Custom-Header"); + cors.setAllowCredentials(false); + cors.setMaxAge(600); + + // Test CORS preflight request + // curl -v -X OPTIONS -H "origin: http://192.168.4.1" http://192.168.4.1/middleware/cors + server.on("/middleware/cors", HTTP_GET, [](AsyncWebServerRequest* request) { + request->send(200, "text/plain", "Hello, world!"); + }); + + // curl -v -X GET -H "x-remove-me: value" http://192.168.4.1/middleware/test-header-filter + // - requestLogger will log the incoming headers (including x-remove-me) + // - headerFilter will remove x-remove-me header + // - handler will log the remaining headers + server.on("/middleware/test-header-filter", HTTP_GET, [](AsyncWebServerRequest* request) { + for (auto& h : request->getHeaders()) + Serial.printf("Request Header: %s = %s\n", h.name().c_str(), h.value().c_str()); + request->send(200); + }); + + // curl -v -X GET -H "x-keep-me: value" http://192.168.4.1/middleware/test-header-free + // - requestLogger will log the incoming headers (including x-keep-me) + // - headerFree will remove all headers except x-keep-me and host + // - handler will log the remaining headers (x-keep-me and host) + server.on("/middleware/test-header-free", HTTP_GET, [](AsyncWebServerRequest* request) { + for (auto& h : request->getHeaders()) + Serial.printf("Request Header: %s = %s\n", h.name().c_str(), h.value().c_str()); + request->send(200); + }) + .addMiddleware(&headerFree); + + // simple digest authentication + // curl -v -X GET -H "x-remove-me: value" --digest -u admin:admin http://192.168.4.1/middleware/auth-simple + server.on("/middleware/auth-simple", HTTP_GET, [](AsyncWebServerRequest* request) { + request->send(200, "text/plain", "Hello, world!"); + }) + .addMiddleware(&simpleDigestAuth); + + // curl -v -X GET -H "x-remove-me: value" --digest -u user:password http://192.168.4.1/middleware/auth-complex + server.on("/middleware/auth-complex", HTTP_GET, [](AsyncWebServerRequest* request) { + String buffer = "Hello "; + buffer.concat(request->getAttribute("user")); + buffer.concat(" with role: "); + buffer.concat(request->getAttribute("role")); + request->send(200, "text/plain", buffer); + }) + .addMiddlewares({&complexAuth, &authz}); + /////////////////////////////////////////////////////////////////////// server.on("/", HTTP_GET, [](AsyncWebServerRequest* request) { diff --git a/src/AsyncEventSource.cpp b/src/AsyncEventSource.cpp index 60c742944..09839f47e 100644 --- a/src/AsyncEventSource.cpp +++ b/src/AsyncEventSource.cpp @@ -288,10 +288,6 @@ void AsyncEventSource::onConnect(ArEventHandlerFunction cb) { _connectcb = cb; } -void AsyncEventSource::authorizeConnect(ArAuthorizeConnectHandler cb) { - _authorizeConnectHandler = cb; -} - void AsyncEventSource::_addClient(AsyncEventSourceClient* client) { if (!client) return; @@ -378,14 +374,6 @@ bool AsyncEventSource::canHandle(AsyncWebServerRequest* request) { } void AsyncEventSource::handleRequest(AsyncWebServerRequest* request) { - if ((_username.length() && _password.length()) && !request->authenticate(_username.c_str(), _password.c_str())) { - return request->requestAuthentication(); - } - if (_authorizeConnectHandler != NULL) { - if (!_authorizeConnectHandler(request)) { - return request->send(401); - } - } request->send(new AsyncEventSourceResponse(this)); } diff --git a/src/AsyncEventSource.h b/src/AsyncEventSource.h index 2eae21131..302f869a7 100644 --- a/src/AsyncEventSource.h +++ b/src/AsyncEventSource.h @@ -53,7 +53,7 @@ class AsyncEventSource; class AsyncEventSourceResponse; class AsyncEventSourceClient; using ArEventHandlerFunction = std::function; -using ArAuthorizeConnectHandler = std::function; +using ArAuthorizeConnectHandler = ArAuthorizeFunction; class AsyncEventSourceMessage { private: @@ -116,7 +116,6 @@ class AsyncEventSource : public AsyncWebHandler { mutable std::mutex _client_queue_lock; #endif ArEventHandlerFunction _connectcb{nullptr}; - ArAuthorizeConnectHandler _authorizeConnectHandler; public: AsyncEventSource(const String& url) : _url(url) {}; @@ -125,7 +124,11 @@ class AsyncEventSource : public AsyncWebHandler { const char* url() const { return _url.c_str(); } void close(); void onConnect(ArEventHandlerFunction cb); - void authorizeConnect(ArAuthorizeConnectHandler cb); + void authorizeConnect(ArAuthorizeConnectHandler cb) { + AuthorizationMiddleware* m = new AuthorizationMiddleware(401, cb); + m->_freeOnRemoval = true; + addMiddleware(m); + } void send(const String& message, const String& event, uint32_t id = 0, uint32_t reconnect = 0) { send(message.c_str(), event.c_str(), id, reconnect); } void send(const String& message, const char* event, uint32_t id = 0, uint32_t reconnect = 0) { send(message.c_str(), event, id, reconnect); } void send(const char* message, const char* event = NULL, uint32_t id = 0, uint32_t reconnect = 0); diff --git a/src/AsyncJson.h b/src/AsyncJson.h index 42a2dc1a2..5426f4110 100644 --- a/src/AsyncJson.h +++ b/src/AsyncJson.h @@ -202,8 +202,6 @@ class AsyncCallbackJsonWebHandler : public AsyncWebHandler { } virtual void handleRequest(AsyncWebServerRequest* request) override final { - if ((_username != "" && _password != "") && !request->authenticate(_username.c_str(), _password.c_str())) - return request->requestAuthentication(); if (_onRequest) { if (request->method() == HTTP_GET) { JsonVariant json; diff --git a/src/AsyncMessagePack.h b/src/AsyncMessagePack.h index 7fe727896..9a6b6ba69 100644 --- a/src/AsyncMessagePack.h +++ b/src/AsyncMessagePack.h @@ -101,9 +101,6 @@ class AsyncCallbackMessagePackWebHandler : public AsyncWebHandler { } virtual void handleRequest(AsyncWebServerRequest* request) override final { - if ((_username != "" && _password != "") && !request->authenticate(_username.c_str(), _password.c_str())) - return request->requestAuthentication(); - if (_onRequest) { if (request->method() == HTTP_GET) { JsonVariant json; diff --git a/src/AsyncWebSocket.cpp b/src/AsyncWebSocket.cpp index 9ef0b5f8d..4f2925eb2 100644 --- a/src/AsyncWebSocket.cpp +++ b/src/AsyncWebSocket.cpp @@ -1086,9 +1086,6 @@ void AsyncWebSocket::handleRequest(AsyncWebServerRequest* request) { request->send(400); return; } - if ((_username.length() && _password.length()) && !request->authenticate(_username.c_str(), _password.c_str())) { - return request->requestAuthentication(); - } if (_handshakeHandler != nullptr) { if (!_handshakeHandler(request)) { request->send(401); diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index bca9c375e..2970490cc 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -24,6 +24,7 @@ #include "Arduino.h" #include "FS.h" +#include #include #include #include @@ -68,6 +69,7 @@ class AsyncWebHandler; class AsyncStaticWebHandler; class AsyncCallbackWebHandler; class AsyncResponseStream; +class AsyncMiddlewareChain; #if defined(TARGET_RP2040) typedef enum http_method WebRequestMethod; @@ -541,6 +543,247 @@ bool ON_STA_FILTER(AsyncWebServerRequest* request); bool ON_AP_FILTER(AsyncWebServerRequest* request); +/* + * MIDDLEWARE :: Request interceptor, assigned to a AsyncWebHandler (or the server), which can be used: + * 1. to run some code before the final handler is executed (e.g. check authentication) + * 2. decide whether to proceed or not with the next handler + * */ + +using ArMiddlewareNext = std::function; +using ArMiddlewareCallback = std::function; + +// Middleware is a base class for all middleware +class AsyncMiddleware { + public: + virtual ~AsyncMiddleware() {} + virtual void run(AsyncWebServerRequest* request, ArMiddlewareNext next) { + return next(); + }; + + private: + friend class AsyncWebHandler; + friend class AsyncEventSource; + friend class AsyncMiddlewareChain; + bool _freeOnRemoval = false; +}; + +// Create a custom middleware by providing an anonymous callback function +class AsyncMiddlewareFunction : public AsyncMiddleware { + public: + AsyncMiddlewareFunction(ArMiddlewareCallback fn) : _fn(fn) {} + void run(AsyncWebServerRequest* request, ArMiddlewareNext next) override { return _fn(request, next); }; + + private: + ArMiddlewareCallback _fn; +}; + +// For internal use only: super class to add/remove middleware to server or handlers +class AsyncMiddlewareChain { + public: + virtual ~AsyncMiddlewareChain() { + for (AsyncMiddleware* m : _middlewares) + if (m->_freeOnRemoval) + delete m; + } + void addMiddleware(ArMiddlewareCallback fn) { + AsyncMiddlewareFunction* m = new AsyncMiddlewareFunction(fn); + m->_freeOnRemoval = true; + _middlewares.emplace_back(m); + } + void addMiddleware(AsyncMiddleware* middleware) { _middlewares.emplace_back(middleware); } + void addMiddlewares(std::vector middlewares) { + for (AsyncMiddleware* m : middlewares) + addMiddleware(m); + } + bool removeMiddleware(AsyncMiddleware* middleware) { + // remove all middlewares from _middlewares vector being equal to middleware, delete them having _freeOnRemoval flag to true and resize the vector. + const size_t size = _middlewares.size(); + _middlewares.erase(std::remove_if(_middlewares.begin(), _middlewares.end(), [middleware](AsyncMiddleware* m) { + if (m == middleware) { + if (m->_freeOnRemoval) + delete m; + return true; + } + return false; + }), + _middlewares.end()); + return size != _middlewares.size(); + } + // For internal use only + void _runChain(AsyncWebServerRequest* request, ArMiddlewareNext finalizer) { + if (!_middlewares.size()) + return finalizer(); + ArMiddlewareNext next; + std::list::iterator it = _middlewares.begin(); + next = [this, &next, &it, request, finalizer]() { + if (it == _middlewares.end()) + return finalizer(); + AsyncMiddleware* m = *it; + it++; + return m->run(request, next); + }; + return next(); + } + + protected: + std::list _middlewares; +}; + +// AuthenticationMiddleware is a middleware that checks if the request is authenticated +class AuthenticationMiddleware : public AsyncMiddleware { + public: + typedef enum { + AUTH_NONE, + AUTH_BASIC, + AUTH_DIGEST + } AuthType; + + void setUsername(const char* username) { _username = username; } + void setPassword(const char* password) { _password = password; } + void setRealm(const char* realm) { _realm = realm; } + void setPasswordIsHash(bool passwordIsHash) { _hash = passwordIsHash; } + void setAuthType(AuthType authType) { _authType = authType; } + + bool allowed(AsyncWebServerRequest* request) { + return _authType == AUTH_NONE || !_username.length() || !_password.length() || request->authenticate(_username.c_str(), _password.c_str(), _realm, _hash); + } + + void run(AsyncWebServerRequest* request, ArMiddlewareNext next) { + return allowed(request) ? next() : request->requestAuthentication(_realm, _authType == AUTH_DIGEST); + } + + private: + String _username; + String _password; + const char* _realm = nullptr; + bool _hash = false; + AuthType _authType = AUTH_DIGEST; +}; + +using ArAuthorizeFunction = std::function; +// AuthorizationMiddleware is a middleware that checks if the request is authorized +class AuthorizationMiddleware : public AsyncMiddleware { + public: + AuthorizationMiddleware(ArAuthorizeFunction authorizeConnectHandler) : _code(403), _authz(authorizeConnectHandler) {} + AuthorizationMiddleware(int code, ArAuthorizeFunction authorizeConnectHandler) : _code(code), _authz(authorizeConnectHandler) {} + void run(AsyncWebServerRequest* request, ArMiddlewareNext next) { + if (_authz && !_authz(request)) + return request->send(_code); + return next(); + } + + private: + int _code; + ArAuthorizeFunction _authz; +}; + +// remove all headers from the incoming request except the ones provided in the constructor +class HeaderFreeMiddleware : public AsyncMiddleware { + public: + void keep(const char* name) { _toKeep.push_back(name); } + void unKeep(const char* name) { _toKeep.erase(std::remove(_toKeep.begin(), _toKeep.end(), name), _toKeep.end()); } + void run(AsyncWebServerRequest* request, ArMiddlewareNext next) { + std::vector reqHeaders; + request->getHeaderNames(reqHeaders); + for (const char* h : reqHeaders) { + bool keep = false; + for (const char* k : _toKeep) { + if (strcasecmp(h, k) == 0) { + keep = true; + break; + } + } + if (!keep) { + request->removeHeader(h); + } + } + next(); + } + + private: + std::vector _toKeep; +}; + +// filter out specific headers from the incoming request +class HeaderFilterMiddleware : public AsyncMiddleware { + public: + void filter(const char* name) { _toRemove.push_back(name); } + void unFilter(const char* name) { _toRemove.erase(std::remove(_toRemove.begin(), _toRemove.end(), name), _toRemove.end()); } + void run(AsyncWebServerRequest* request, ArMiddlewareNext next) { + for (auto it = _toRemove.begin(); it != _toRemove.end(); ++it) + request->removeHeader(*it); + next(); + } + + private: + std::vector _toRemove; +}; + +// curl-like logging of incoming requests +class LoggingMiddleware : public AsyncMiddleware { + public: + void setOutput(Print& output) { _out = &output; } + void setEnabled(bool enabled) { _enabled = enabled; } + bool isEnabled() { return _enabled && _out; } + + void run(AsyncWebServerRequest* request, ArMiddlewareNext next); + + private: + Print* _out = nullptr; + bool _enabled = true; +}; + +// CORS Middleware +class CorsMiddleware : public AsyncMiddleware { + public: + void setOrigin(const char* origin) { _origin = origin; } + void setMethods(const char* methods) { _methods = methods; } + void setHeaders(const char* headers) { _headers = headers; } + void setAllowCredentials(bool credentials) { _credentials = credentials; } + void setMaxAge(uint32_t seconds) { _maxAge = seconds; } + + void run(AsyncWebServerRequest* request, ArMiddlewareNext next); + + private: + String _origin = "*"; + String _methods = "*"; + String _headers = "*"; + bool _credentials = true; + uint32_t _maxAge = 86400; +}; + +// Rate limit Middleware +class RateLimitMiddleware : public AsyncMiddleware { + public: + void setMaxRequests(size_t maxRequests) { _maxRequests = maxRequests; } + void setWindowSize(uint32_t seconds) { _windowSizeMillis = seconds * 1000; } + + bool isRequestAllowed(uint32_t& retryAfterSeconds) { + uint32_t now = millis(); + + while (!_requestTimes.empty() && _requestTimes.front() <= now - _windowSizeMillis) + _requestTimes.pop_front(); + + _requestTimes.push_back(now); + + if (_requestTimes.size() > _maxRequests) { + _requestTimes.pop_front(); + retryAfterSeconds = (_windowSizeMillis - (now - _requestTimes.front())) / 1000 + 1; + return false; + } + + retryAfterSeconds = 0; + return true; + } + + void run(AsyncWebServerRequest* request, ArMiddlewareNext next); + + private: + size_t _maxRequests = 0; + uint32_t _windowSizeMillis = 0; + std::list _requestTimes; +}; + /* * REWRITE :: One instance can be handle any Request (done by the Server) * */ @@ -576,11 +819,9 @@ class AsyncWebRewrite { * HANDLER :: One instance can be attached to any Request (done by the Server) * */ -class AsyncWebHandler { +class AsyncWebHandler : public AsyncMiddlewareChain { protected: ArRequestFilterFunction _filter{nullptr}; - String _username; - String _password; public: AsyncWebHandler() {} @@ -589,15 +830,16 @@ class AsyncWebHandler { return *this; } AsyncWebHandler& setAuthentication(const char* username, const char* password) { - _username = username; - _password = password; - return *this; - }; - AsyncWebHandler& setAuthentication(const String& username, const String& password) { - _username = username; - _password = password; + if (username == nullptr || password == nullptr || strlen(username) == 0 || strlen(password) == 0) + return *this; + AuthenticationMiddleware* m = new AuthenticationMiddleware(); + m->setUsername(username); + m->setPassword(password); + m->_freeOnRemoval = true; + addMiddleware(m); return *this; }; + AsyncWebHandler& setAuthentication(const String& username, const String& password) { return setAuthentication(username.c_str(), password.c_str()); }; bool filter(AsyncWebServerRequest* request) { return _filter == NULL || _filter(request); } virtual ~AsyncWebHandler() {} virtual bool canHandle(AsyncWebServerRequest* request __attribute__((unused))) { @@ -685,7 +927,7 @@ typedef std::function ArRequestHandlerFunc typedef std::function ArUploadHandlerFunction; typedef std::function ArBodyHandlerFunction; -class AsyncWebServer { +class AsyncWebServer : public AsyncMiddlewareChain { protected: AsyncServer _server; std::list> _rewrites; diff --git a/src/Middlewares.cpp b/src/Middlewares.cpp new file mode 100644 index 000000000..6f8dc2c61 --- /dev/null +++ b/src/Middlewares.cpp @@ -0,0 +1,84 @@ +#include "ESPAsyncWebServer.h" + +void LoggingMiddleware::run(AsyncWebServerRequest* request, ArMiddlewareNext next) { + if (!isEnabled()) { + next(); + return; + } + _out->print(F("* Connection from ")); + _out->print(request->client()->remoteIP().toString()); + _out->print(':'); + _out->println(request->client()->remotePort()); + _out->print('>'); + _out->print(' '); + _out->print(request->methodToString()); + _out->print(' '); + _out->print(request->url().c_str()); + _out->print(F(" HTTP/1.")); + _out->println(request->version()); + for (auto& h : request->getHeaders()) { + if (h.value().length()) { + _out->print('>'); + _out->print(' '); + _out->print(h.name()); + _out->print(':'); + _out->print(' '); + _out->println(h.value()); + } + } + _out->println(F(">")); + uint32_t elapsed = millis(); + next(); + elapsed = millis() - elapsed; + AsyncWebServerResponse* response = request->getResponse(); + if (response) { + _out->print(F("* Processed in ")); + _out->print(elapsed); + _out->println(F(" ms")); + _out->print('<'); + _out->print(F(" HTTP/1.")); + _out->print(request->version()); + _out->print(' '); + _out->print(response->code()); + _out->print(' '); + _out->println(AsyncWebServerResponse::responseCodeToString(response->code())); + for (auto& h : response->getHeaders()) { + if (h.value().length()) { + _out->print('<'); + _out->print(' '); + _out->print(h.name()); + _out->print(':'); + _out->print(' '); + _out->println(h.value()); + } + } + _out->println('<'); + } else { + _out->println(F("* Connection closed!")); + } +} + +void CorsMiddleware::run(AsyncWebServerRequest* request, ArMiddlewareNext next) { + if (request->method() == HTTP_OPTIONS && request->hasHeader(F("Origin"))) { + AsyncWebServerResponse* response = request->beginResponse(200); + response->addHeader(F("Access-Control-Allow-Origin"), _origin.c_str()); + response->addHeader(F("Access-Control-Allow-Methods"), _methods.c_str()); + response->addHeader(F("Access-Control-Allow-Headers"), _headers.c_str()); + response->addHeader(F("Access-Control-Allow-Credentials"), _credentials ? F("true") : F("false")); + response->addHeader(F("Access-Control-Max-Age"), String(_maxAge).c_str()); + request->send(response); + } else { + next(); + } +} + +void RateLimitMiddleware::run(AsyncWebServerRequest* request, ArMiddlewareNext next) { + uint32_t retryAfterSeconds; + if (isRequestAllowed(retryAfterSeconds)) { + next(); + } else { + AsyncWebServerResponse* response = request->beginResponse(429); + response->addHeader(F("Retry-After"), retryAfterSeconds); + request->send(response); + } +} diff --git a/src/WebHandlerImpl.h b/src/WebHandlerImpl.h index 8ee2a6541..2838a8ef9 100644 --- a/src/WebHandlerImpl.h +++ b/src/WebHandlerImpl.h @@ -129,22 +129,16 @@ class AsyncCallbackWebHandler : public AsyncWebHandler { } virtual void handleRequest(AsyncWebServerRequest* request) override final { - if ((_username != "" && _password != "") && !request->authenticate(_username.c_str(), _password.c_str())) - return request->requestAuthentication(); if (_onRequest) _onRequest(request); else request->send(500); } virtual void handleUpload(AsyncWebServerRequest* request, const String& filename, size_t index, uint8_t* data, size_t len, bool final) override final { - if ((_username != "" && _password != "") && !request->authenticate(_username.c_str(), _password.c_str())) - return request->requestAuthentication(); if (_onUpload) _onUpload(request, filename, index, data, len, final); } virtual void handleBody(AsyncWebServerRequest* request, uint8_t* data, size_t len, size_t index, size_t total) override final { - if ((_username != "" && _password != "") && !request->authenticate(_username.c_str(), _password.c_str())) - return request->requestAuthentication(); if (_onBody) _onBody(request, data, len, index, total); } diff --git a/src/WebHandlers.cpp b/src/WebHandlers.cpp index b87db7f1e..37ce2fa6c 100644 --- a/src/WebHandlers.cpp +++ b/src/WebHandlers.cpp @@ -192,8 +192,6 @@ void AsyncStaticWebHandler::handleRequest(AsyncWebServerRequest* request) { String filename = String((char*)request->_tempObject); free(request->_tempObject); request->_tempObject = NULL; - if ((_username.length() && _password.length()) && !request->authenticate(_username.c_str(), _password.c_str())) - return request->requestAuthentication(); if (request->_tempFile == true) { time_t lw = request->_tempFile.getLastWrite(); // get last file mod time (if supported by FS) diff --git a/src/WebRequest.cpp b/src/WebRequest.cpp index 61ec25d84..67453e11c 100644 --- a/src/WebRequest.cpp +++ b/src/WebRequest.cpp @@ -138,8 +138,7 @@ void AsyncWebServerRequest::_onData(void* buf, size_t len) { } if (_parsedLength == _contentLength) { _parseState = PARSE_REQ_END; - if (_handler) - _handler->handleRequest(this); + _server->_runChain(this, [this]() { return _handler ? _handler->_runChain(this, [this]() { _handler->handleRequest(this); }) : send(501); }); if (!_sent) { if (!_response) send(501, T_text_plain, "Handler did not handle the request"); @@ -577,8 +576,7 @@ void AsyncWebServerRequest::_parseLine() { _parseState = PARSE_REQ_BODY; } else { _parseState = PARSE_REQ_END; - if (_handler) - _handler->handleRequest(this); + _server->_runChain(this, [this]() { return _handler ? _handler->_runChain(this, [this]() { _handler->handleRequest(this); }) : send(501); }); if (!_sent) { if (!_response) send(501, T_text_plain, "Handler did not handle the request"); diff --git a/src/WebResponses.cpp b/src/WebResponses.cpp index 2705fd373..e7edf5e91 100644 --- a/src/WebResponses.cpp +++ b/src/WebResponses.cpp @@ -109,6 +109,8 @@ const char* AsyncWebServerResponse::responseCodeToString(int code) { return T_HTTP_CODE_416; case 417: return T_HTTP_CODE_417; + case 429: + return T_HTTP_CODE_429; case 500: return T_HTTP_CODE_500; case 501: @@ -196,6 +198,8 @@ const __FlashStringHelper* AsyncWebServerResponse::responseCodeToString(int code return FPSTR(T_HTTP_CODE_416); case 417: return FPSTR(T_HTTP_CODE_417); + case 429: + return FPSTR(T_HTTP_CODE_429); case 500: return FPSTR(T_HTTP_CODE_500); case 501: @@ -491,7 +495,7 @@ size_t AsyncAbstractResponse::_ack(AsyncWebServerRequest* request, size_t len, u free(buf); return 0; } - outLen = sprintf((char*)buf+headLen, "%04x", readLen) + headLen; + outLen = sprintf((char*)buf + headLen, "%04x", readLen) + headLen; buf[outLen++] = '\r'; buf[outLen++] = '\n'; outLen += readLen; diff --git a/src/literals.h b/src/literals.h index 40b596ae3..15bf47ef0 100644 --- a/src/literals.h +++ b/src/literals.h @@ -137,6 +137,7 @@ static constexpr const char* T_HTTP_CODE_414 = "Request-URI Too Large"; static constexpr const char* T_HTTP_CODE_415 = "Unsupported Media Type"; static constexpr const char* T_HTTP_CODE_416 = "Requested range not satisfiable"; static constexpr const char* T_HTTP_CODE_417 = "Expectation Failed"; +static constexpr const char* T_HTTP_CODE_429 = "Too Many Requests"; static constexpr const char* T_HTTP_CODE_500 = "Internal Server Error"; static constexpr const char* T_HTTP_CODE_501 = "Not Implemented"; static constexpr const char* T_HTTP_CODE_502 = "Bad Gateway"; @@ -306,6 +307,7 @@ static const char T_HTTP_CODE_414[] PROGMEM = "Request-URI Too Large"; static const char T_HTTP_CODE_415[] PROGMEM = "Unsupported Media Type"; static const char T_HTTP_CODE_416[] PROGMEM = "Requested range not satisfiable"; static const char T_HTTP_CODE_417[] PROGMEM = "Expectation Failed"; +static const char T_HTTP_CODE_429[] PROGMEM = "Too Many Requests"; static const char T_HTTP_CODE_500[] PROGMEM = "Internal Server Error"; static const char T_HTTP_CODE_501[] PROGMEM = "Not Implemented"; static const char T_HTTP_CODE_502[] PROGMEM = "Bad Gateway"; From b40373998577f673c020e4eb6e3bb6e018931e9b Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Sat, 14 Sep 2024 16:43:53 +0200 Subject: [PATCH 375/551] v3.3.0 --- README.md | 2 +- docs/index.md | 2 +- library.json | 2 +- library.properties | 2 +- src/ESPAsyncWebServer.h | 6 +++--- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 2f7d1b81e..e2f653184 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo **WARNING** The library name was changed from `ESP Async WebServer` to `ESPAsyncWebServer` as per the Arduino Lint recommendations. ``` -mathieucarbou/ESPAsyncWebServer @ 3.2.4 +mathieucarbou/ESPAsyncWebServer @ 3.3.0 ``` Dependency: diff --git a/docs/index.md b/docs/index.md index 2f7d1b81e..e2f653184 100644 --- a/docs/index.md +++ b/docs/index.md @@ -20,7 +20,7 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo **WARNING** The library name was changed from `ESP Async WebServer` to `ESPAsyncWebServer` as per the Arduino Lint recommendations. ``` -mathieucarbou/ESPAsyncWebServer @ 3.2.4 +mathieucarbou/ESPAsyncWebServer @ 3.3.0 ``` Dependency: diff --git a/library.json b/library.json index db3d040f5..85f08ef47 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "ESPAsyncWebServer", - "version": "3.2.4", + "version": "3.3.0", "description": "Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 and RP2040. Supports: WebSocket, SSE, Authentication, Arduino Json 7, File Upload, Static File serving, URL Rewrite, URL Redirect, etc.", "keywords": "http,async,websocket,webserver", "homepage": "https://github.com/mathieucarbou/ESPAsyncWebServer", diff --git a/library.properties b/library.properties index bc5ba6d6f..18ba2d084 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=ESPAsyncWebServer -version=3.2.4 +version=3.3.0 author=Me-No-Dev maintainer=Mathieu Carbou sentence=Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 and RP2040 diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index 2970490cc..62db448d0 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -47,10 +47,10 @@ #include "literals.h" -#define ASYNCWEBSERVER_VERSION "3.2.4" +#define ASYNCWEBSERVER_VERSION "3.3.0" #define ASYNCWEBSERVER_VERSION_MAJOR 3 -#define ASYNCWEBSERVER_VERSION_MINOR 2 -#define ASYNCWEBSERVER_VERSION_REVISION 4 +#define ASYNCWEBSERVER_VERSION_MINOR 3 +#define ASYNCWEBSERVER_VERSION_REVISION 0 #define ASYNCWEBSERVER_FORK_mathieucarbou #ifdef ASYNCWEBSERVER_REGEX From d39aba4d8a6f28ddee5bd627387f47e6be9e751a Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Sat, 14 Sep 2024 16:55:02 +0200 Subject: [PATCH 376/551] update doc --- README.md | 2 +- docs/index.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index e2f653184..70066e8b9 100644 --- a/README.md +++ b/README.md @@ -208,5 +208,5 @@ myHandler.addMiddleware(&authMiddleware); // add authentication to a specific ha - `AsyncEventSource.authorizeConnect(...)` => do not use this method anymore: add a common `AuthorizationMiddleware` to the handler or server, and make sure to add it AFTER the `AuthenticationMiddleware` if you use authentication. - `AsyncWebHandler.setAuthentication(...)` => do not use this method anymore: add a common `AuthenticationMiddleware` to the handler or server - `ArUploadHandlerFunction` and `ArBodyHandlerFunction` => these callbacks receiving body data and upload and not calling anymore the authentication code for performance reasons. - These callbacks can be called multiple times, so this is up to the user to now call the `AuthenticationMiddleware` if needed and ideally when the method is called for the first time. + These callbacks can be called multiple times during request parsing, so this is up to the user to now call the `AuthenticationMiddleware.allowed(request)` if needed and ideally when the method is called for the first time. These callbacks are also not triggering the whole middleware chain since they are not part of the request processing workflow (they are not the final handler). diff --git a/docs/index.md b/docs/index.md index e2f653184..70066e8b9 100644 --- a/docs/index.md +++ b/docs/index.md @@ -208,5 +208,5 @@ myHandler.addMiddleware(&authMiddleware); // add authentication to a specific ha - `AsyncEventSource.authorizeConnect(...)` => do not use this method anymore: add a common `AuthorizationMiddleware` to the handler or server, and make sure to add it AFTER the `AuthenticationMiddleware` if you use authentication. - `AsyncWebHandler.setAuthentication(...)` => do not use this method anymore: add a common `AuthenticationMiddleware` to the handler or server - `ArUploadHandlerFunction` and `ArBodyHandlerFunction` => these callbacks receiving body data and upload and not calling anymore the authentication code for performance reasons. - These callbacks can be called multiple times, so this is up to the user to now call the `AuthenticationMiddleware` if needed and ideally when the method is called for the first time. + These callbacks can be called multiple times during request parsing, so this is up to the user to now call the `AuthenticationMiddleware.allowed(request)` if needed and ideally when the method is called for the first time. These callbacks are also not triggering the whole middleware chain since they are not part of the request processing workflow (they are not the final handler). From 9e6cc52bbcd1aac3846269c1d99a7d8c894c43f4 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Sun, 15 Sep 2024 11:31:18 +0200 Subject: [PATCH 377/551] Fix warning on ESP8266 --- src/ESPAsyncWebServer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index 62db448d0..26614ee7f 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -556,7 +556,7 @@ using ArMiddlewareCallback = std::function Date: Sun, 15 Sep 2024 11:32:54 +0200 Subject: [PATCH 378/551] v3.3.1 --- README.md | 2 +- docs/index.md | 2 +- library.json | 2 +- library.properties | 2 +- src/ESPAsyncWebServer.h | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 70066e8b9..65f06eaa9 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo **WARNING** The library name was changed from `ESP Async WebServer` to `ESPAsyncWebServer` as per the Arduino Lint recommendations. ``` -mathieucarbou/ESPAsyncWebServer @ 3.3.0 +mathieucarbou/ESPAsyncWebServer @ 3.3.1 ``` Dependency: diff --git a/docs/index.md b/docs/index.md index 70066e8b9..65f06eaa9 100644 --- a/docs/index.md +++ b/docs/index.md @@ -20,7 +20,7 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo **WARNING** The library name was changed from `ESP Async WebServer` to `ESPAsyncWebServer` as per the Arduino Lint recommendations. ``` -mathieucarbou/ESPAsyncWebServer @ 3.3.0 +mathieucarbou/ESPAsyncWebServer @ 3.3.1 ``` Dependency: diff --git a/library.json b/library.json index 85f08ef47..527a17a33 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "ESPAsyncWebServer", - "version": "3.3.0", + "version": "3.3.1", "description": "Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 and RP2040. Supports: WebSocket, SSE, Authentication, Arduino Json 7, File Upload, Static File serving, URL Rewrite, URL Redirect, etc.", "keywords": "http,async,websocket,webserver", "homepage": "https://github.com/mathieucarbou/ESPAsyncWebServer", diff --git a/library.properties b/library.properties index 18ba2d084..02de7c436 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=ESPAsyncWebServer -version=3.3.0 +version=3.3.1 author=Me-No-Dev maintainer=Mathieu Carbou sentence=Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 and RP2040 diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index 26614ee7f..ad2038af8 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -47,7 +47,7 @@ #include "literals.h" -#define ASYNCWEBSERVER_VERSION "3.3.0" +#define ASYNCWEBSERVER_VERSION "3.3.1" #define ASYNCWEBSERVER_VERSION_MAJOR 3 #define ASYNCWEBSERVER_VERSION_MINOR 3 #define ASYNCWEBSERVER_VERSION_REVISION 0 From 9bad612a693d25b5c9142f83571d65b3dec7f8b2 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Sun, 15 Sep 2024 11:59:19 +0200 Subject: [PATCH 379/551] Check for null --- src/ESPAsyncWebServer.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index ad2038af8..311680db9 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -590,7 +590,10 @@ class AsyncMiddlewareChain { m->_freeOnRemoval = true; _middlewares.emplace_back(m); } - void addMiddleware(AsyncMiddleware* middleware) { _middlewares.emplace_back(middleware); } + void addMiddleware(AsyncMiddleware* middleware) { + if (middleware) + _middlewares.emplace_back(middleware); + } void addMiddlewares(std::vector middlewares) { for (AsyncMiddleware* m : middlewares) addMiddleware(m); From 7c57b0cd6bf8ff36c17677cffc85e702bdcec896 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Sun, 15 Sep 2024 22:16:09 +0200 Subject: [PATCH 380/551] update doc --- README.md | 42 ++++++++++++++++++++++-------------------- docs/index.md | 42 ++++++++++++++++++++++-------------------- 2 files changed, 44 insertions(+), 40 deletions(-) diff --git a/README.md b/README.md index 65f06eaa9..550c0a85c 100644 --- a/README.md +++ b/README.md @@ -31,26 +31,28 @@ Dependency: ## Changes in this fork -- `char*` overloads to avoid using `String` -- `DEFAULT_MAX_WS_CLIENTS` to change the number of allows WebSocket clients and use `cleanupClients()` to help cleanup resources about dead clients -- `setCloseClientOnQueueFull(bool)` which can be set on a client to either close the connection or discard messages but not close the connection when the queue is full -- `SSE_MAX_QUEUED_MESSAGES` to control the maximum number of messages that can be queued for a SSE client -- `StreamConcat` example to show how to stream multiple files in one response -- `WS_MAX_QUEUED_MESSAGES`: control the maximum number of messages that can be queued for a Websocket client -- A lot of bug fixes -- Arduino 3 / ESP-IDF 5 compatibility -- Arduino Json 7 compatibility and backward compatible with 6 -- Better CI with a complete matrix of Arduino versions and boards -- Code size improvements -- Deployed in PlatformIO registry and Arduino IDE library manager -- ESP32 / ESP8266 / RP2040 support -- Lot of code cleanup and optimizations -- MessagePack support -- Performance improvements in terms of memory, speed and size -- Removed ESPIDF Editor (this is not the role of a web server library to do that - get the source files from the original repos if required) -- Support overriding default response headers -- Support resumable downloads using HEAD and bytes range -- **Support for middleware** +- (bug) A lot of bug fixes +- (ci) Better CI with a complete matrix of Arduino versions and boards +- (ci) Deployed in PlatformIO registry and Arduino IDE library manager +- (feat) **Arduino 3 / ESP-IDF 5** compatibility +- (feat) **ArduinoJson 7** compatibility +- (feat) **ESP32 / ESP8266 / RP2040** support +- (feat) **MessagePack** support +- (feat) **Middleware** support with pre-built middlewares for authentication, authorization, rate limiting, logging, cors, etc. +- (feat) **Request attributes** to store data on the request object +- (feat) **Response header** control and override +- (feat) **Response override**: support the ability to replace a previously sent response by another one +- (feat) **Resumable download** support using HEAD and bytes range +- (feat) `StreamConcat` example to show how to stream multiple files in one response +- (feat) Removed ESPIDF Editor (this is not the role of a web server library to do that - get the source files from the original repos if required) +- (perf) `char*` overloads to avoid using `String` +- (perf) `DEFAULT_MAX_WS_CLIENTS` to change the number of allows WebSocket clients and use `cleanupClients()` to help cleanup resources about dead clients +- (perf) `setCloseClientOnQueueFull(bool)` which can be set on a client to either close the connection or discard messages but not close the connection when the queue is full +- (perf) `SSE_MAX_QUEUED_MESSAGES` to control the maximum number of messages that can be queued for a SSE client +- (perf) `WS_MAX_QUEUED_MESSAGES`: control the maximum number of messages that can be queued for a Websocket client +- (perf) Code size improvements +- (perf) Lot of code cleanup and optimizations +- (perf) Performance improvements in terms of memory, speed and size ## Original Documentation diff --git a/docs/index.md b/docs/index.md index 65f06eaa9..550c0a85c 100644 --- a/docs/index.md +++ b/docs/index.md @@ -31,26 +31,28 @@ Dependency: ## Changes in this fork -- `char*` overloads to avoid using `String` -- `DEFAULT_MAX_WS_CLIENTS` to change the number of allows WebSocket clients and use `cleanupClients()` to help cleanup resources about dead clients -- `setCloseClientOnQueueFull(bool)` which can be set on a client to either close the connection or discard messages but not close the connection when the queue is full -- `SSE_MAX_QUEUED_MESSAGES` to control the maximum number of messages that can be queued for a SSE client -- `StreamConcat` example to show how to stream multiple files in one response -- `WS_MAX_QUEUED_MESSAGES`: control the maximum number of messages that can be queued for a Websocket client -- A lot of bug fixes -- Arduino 3 / ESP-IDF 5 compatibility -- Arduino Json 7 compatibility and backward compatible with 6 -- Better CI with a complete matrix of Arduino versions and boards -- Code size improvements -- Deployed in PlatformIO registry and Arduino IDE library manager -- ESP32 / ESP8266 / RP2040 support -- Lot of code cleanup and optimizations -- MessagePack support -- Performance improvements in terms of memory, speed and size -- Removed ESPIDF Editor (this is not the role of a web server library to do that - get the source files from the original repos if required) -- Support overriding default response headers -- Support resumable downloads using HEAD and bytes range -- **Support for middleware** +- (bug) A lot of bug fixes +- (ci) Better CI with a complete matrix of Arduino versions and boards +- (ci) Deployed in PlatformIO registry and Arduino IDE library manager +- (feat) **Arduino 3 / ESP-IDF 5** compatibility +- (feat) **ArduinoJson 7** compatibility +- (feat) **ESP32 / ESP8266 / RP2040** support +- (feat) **MessagePack** support +- (feat) **Middleware** support with pre-built middlewares for authentication, authorization, rate limiting, logging, cors, etc. +- (feat) **Request attributes** to store data on the request object +- (feat) **Response header** control and override +- (feat) **Response override**: support the ability to replace a previously sent response by another one +- (feat) **Resumable download** support using HEAD and bytes range +- (feat) `StreamConcat` example to show how to stream multiple files in one response +- (feat) Removed ESPIDF Editor (this is not the role of a web server library to do that - get the source files from the original repos if required) +- (perf) `char*` overloads to avoid using `String` +- (perf) `DEFAULT_MAX_WS_CLIENTS` to change the number of allows WebSocket clients and use `cleanupClients()` to help cleanup resources about dead clients +- (perf) `setCloseClientOnQueueFull(bool)` which can be set on a client to either close the connection or discard messages but not close the connection when the queue is full +- (perf) `SSE_MAX_QUEUED_MESSAGES` to control the maximum number of messages that can be queued for a SSE client +- (perf) `WS_MAX_QUEUED_MESSAGES`: control the maximum number of messages that can be queued for a Websocket client +- (perf) Code size improvements +- (perf) Lot of code cleanup and optimizations +- (perf) Performance improvements in terms of memory, speed and size ## Original Documentation From 35230ba83c716b1045ac23994088de31bdd8c9bb Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Sun, 15 Sep 2024 23:47:08 +0200 Subject: [PATCH 381/551] update doc --- README.md | 1741 ++++++++++++++++++++++++++++++++++++++++++++++++- docs/index.md | 1741 ++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 3410 insertions(+), 72 deletions(-) diff --git a/README.md b/README.md index 550c0a85c..95181419a 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,17 @@ Supports: WebSocket, SSE, Authentication, Arduino Json 7, File Upload, Static Fi This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubox-node-org/ESPAsyncWebServer) and includes all the concurrency fixes. -## Coordinate and dependencies: +- [Coordinate and dependencies](#coordinate-and-dependencies) +- [Changes in this fork](#changes-in-this-fork) +- [Important recommendations](#important-recommendations) +- [`AsyncWebSocketMessageBuffer` and `makeBuffer()`](#asyncwebsocketmessagebuffer-and-makebuffer) +- [How to replace a response](#how-to-replace-a-response) +- [How to use Middleware](#how-to-use-middleware) +- [How to use authentication with AuthenticationMiddleware](#how-to-use-authentication-with-authenticationmiddleware) +- [Migration to Middleware to improve performance and memory usage](#migration-to-middleware-to-improve-performance-and-memory-usage) +- [Original Documentation](#original-documentation) + +## Coordinate and dependencies **WARNING** The library name was changed from `ESP Async WebServer` to `ESPAsyncWebServer` as per the Arduino Lint recommendations. @@ -54,13 +64,33 @@ Dependency: - (perf) Lot of code cleanup and optimizations - (perf) Performance improvements in terms of memory, speed and size -## Original Documentation +## Important recommendations + +Most of the crashes are caused by improper configuration of the library for the project. +Here are some recommendations to avoid them. + +1. Set the running core to be on the same core of your application (usually core 1) `-D CONFIG_ASYNC_TCP_RUNNING_CORE=1` +2. Set the stack size appropriately with `-D CONFIG_ASYNC_TCP_STACK_SIZE=16384`. + The default value of `16384` might be too much for your project. + You can look at the [MycilaTaskMonitor](https://oss.carbou.me/MycilaTaskMonitor) project to monitor the stack usage. +3. You can change **if you know what you are doing** the task priority with `-D CONFIG_ASYNC_TCP_PRIORITY=10`. + Default is `10`. +4. You can increase the queue size with `-D CONFIG_ASYNC_TCP_QUEUE_SIZE=128`. + Default is `64`. +5. You can decrease the maximum ack time `-D CONFIG_ASYNC_TCP_MAX_ACK_TIME=3000`. + Default is `5000`. -Usage and API stays the same as the original library. -Please look at the original libraries for more examples and documentation. +I personally use the following configuration in my projects because my WS messages can be big (up to 4k). +If you have smaller messages, you can increase `WS_MAX_QUEUED_MESSAGES` to 128. -- [https://github.com/me-no-dev/ESPAsyncWebServer](https://github.com/me-no-dev/ESPAsyncWebServer) (original library) -- [https://github.com/yubox-node-org/ESPAsyncWebServer](https://github.com/yubox-node-org/ESPAsyncWebServer) (fork of the original library) +```c++ + -D CONFIG_ASYNC_TCP_MAX_ACK_TIME=3000 + -D CONFIG_ASYNC_TCP_PRIORITY=10 + -D CONFIG_ASYNC_TCP_QUEUE_SIZE=128 + -D CONFIG_ASYNC_TCP_RUNNING_CORE=1 + -D CONFIG_ASYNC_TCP_STACK_SIZE=4096 + -D WS_MAX_QUEUED_MESSAGES=64 +``` ## `AsyncWebSocketMessageBuffer` and `makeBuffer()` @@ -97,35 +127,7 @@ void send(JsonDocument& doc) { I recommend to use the official API `AsyncWebSocketMessageBuffer` to retain further compatibility. -## Important recommendations - -Most of the crashes are caused by improper configuration of the library for the project. -Here are some recommendations to avoid them. - -1. Set the running core to be on the same core of your application (usually core 1) `-D CONFIG_ASYNC_TCP_RUNNING_CORE=1` -2. Set the stack size appropriately with `-D CONFIG_ASYNC_TCP_STACK_SIZE=16384`. - The default value of `16384` might be too much for your project. - You can look at the [MycilaTaskMonitor](https://oss.carbou.me/MycilaTaskMonitor) project to monitor the stack usage. -3. You can change **if you know what you are doing** the task priority with `-D CONFIG_ASYNC_TCP_PRIORITY=10`. - Default is `10`. -4. You can increase the queue size with `-D CONFIG_ASYNC_TCP_QUEUE_SIZE=128`. - Default is `64`. -5. You can decrease the maximum ack time `-D CONFIG_ASYNC_TCP_MAX_ACK_TIME=3000`. - Default is `5000`. - -I personally use the following configuration in my projects because my WS messages can be big (up to 4k). -If you have smaller messages, you can increase `WS_MAX_QUEUED_MESSAGES` to 128. - -```c++ - -D CONFIG_ASYNC_TCP_MAX_ACK_TIME=3000 - -D CONFIG_ASYNC_TCP_PRIORITY=10 - -D CONFIG_ASYNC_TCP_QUEUE_SIZE=128 - -D CONFIG_ASYNC_TCP_RUNNING_CORE=1 - -D CONFIG_ASYNC_TCP_STACK_SIZE=4096 - -D WS_MAX_QUEUED_MESSAGES=64 -``` - -## Replace response +## How to replace a response ```c++ // It is possible to replace a response. @@ -140,7 +142,7 @@ If you have smaller messages, you can increase `WS_MAX_QUEUED_MESSAGES` to 128. This will send error 400 instead of 200. -## Middleware +## How to use Middleware Middleware is a way to intercept requests to perform some operations on them, like authentication, authorization, logging, etc and also act on the response headers. @@ -212,3 +214,1670 @@ myHandler.addMiddleware(&authMiddleware); // add authentication to a specific ha - `ArUploadHandlerFunction` and `ArBodyHandlerFunction` => these callbacks receiving body data and upload and not calling anymore the authentication code for performance reasons. These callbacks can be called multiple times during request parsing, so this is up to the user to now call the `AuthenticationMiddleware.allowed(request)` if needed and ideally when the method is called for the first time. These callbacks are also not triggering the whole middleware chain since they are not part of the request processing workflow (they are not the final handler). + +## Original Documentation + +- [Why should you care](#why-should-you-care) +- [Important things to remember](#important-things-to-remember) +- [Principles of operation](#principles-of-operation) + - [The Async Web server](#the-async-web-server) + - [Request Life Cycle](#request-life-cycle) + - [Rewrites and how do they work](#rewrites-and-how-do-they-work) + - [Handlers and how do they work](#handlers-and-how-do-they-work) + - [Responses and how do they work](#responses-and-how-do-they-work) + - [Template processing](#template-processing) +- [Libraries and projects that use AsyncWebServer](#libraries-and-projects-that-use-asyncwebserver) +- [Request Variables](#request-variables) + - [Common Variables](#common-variables) + - [Headers](#headers) + - [GET, POST and FILE parameters](#get-post-and-file-parameters) + - [FILE Upload handling](#file-upload-handling) + - [Body data handling](#body-data-handling) + - [JSON body handling with ArduinoJson](#json-body-handling-with-arduinojson) +- [Responses](#responses) + - [Redirect to another URL](#redirect-to-another-url) + - [Basic response with HTTP Code](#basic-response-with-http-code) + - [Basic response with HTTP Code and extra headers](#basic-response-with-http-code-and-extra-headers) + - [Basic response with string content](#basic-response-with-string-content) + - [Basic response with string content and extra headers](#basic-response-with-string-content-and-extra-headers) + - [Send large webpage from PROGMEM](#send-large-webpage-from-progmem) + - [Send large webpage from PROGMEM and extra headers](#send-large-webpage-from-progmem-and-extra-headers) + - [Send large webpage from PROGMEM containing templates](#send-large-webpage-from-progmem-containing-templates) + - [Send large webpage from PROGMEM containing templates and extra headers](#send-large-webpage-from-progmem-containing-templates-and-extra-headers) + - [Send binary content from PROGMEM](#send-binary-content-from-progmem) + - [Respond with content coming from a Stream](#respond-with-content-coming-from-a-stream) + - [Respond with content coming from a Stream and extra headers](#respond-with-content-coming-from-a-stream-and-extra-headers) + - [Respond with content coming from a Stream containing templates](#respond-with-content-coming-from-a-stream-containing-templates) + - [Respond with content coming from a Stream containing templates and extra headers](#respond-with-content-coming-from-a-stream-containing-templates-and-extra-headers) + - [Respond with content coming from a File](#respond-with-content-coming-from-a-file) + - [Respond with content coming from a File and extra headers](#respond-with-content-coming-from-a-file-and-extra-headers) + - [Respond with content coming from a File containing templates](#respond-with-content-coming-from-a-file-containing-templates) + - [Respond with content using a callback](#respond-with-content-using-a-callback) + - [Respond with content using a callback and extra headers](#respond-with-content-using-a-callback-and-extra-headers) + - [Respond with file content using a callback and extra headers](#respond-with-file-content-using-a-callback-and-extra-headers) + - [Respond with content using a callback containing templates](#respond-with-content-using-a-callback-containing-templates) + - [Respond with content using a callback containing templates and extra headers](#respond-with-content-using-a-callback-containing-templates-and-extra-headers) + - [Chunked Response](#chunked-response) + - [Chunked Response containing templates](#chunked-response-containing-templates) + - [Print to response](#print-to-response) + - [ArduinoJson Basic Response](#arduinojson-basic-response) + - [ArduinoJson Advanced Response](#arduinojson-advanced-response) +- [Serving static files](#serving-static-files) + - [Serving specific file by name](#serving-specific-file-by-name) + - [Serving files in directory](#serving-files-in-directory) + - [Serving static files with authentication](#serving-static-files-with-authentication) + - [Specifying Cache-Control header](#specifying-cache-control-header) + - [Specifying Date-Modified header](#specifying-date-modified-header) + - [Specifying Template Processor callback](#specifying-template-processor-callback) + - [Serving static files by custom handling](#serving-static-files-by-custom-handling) +- [Param Rewrite With Matching](#param-rewrite-with-matching) +- [Using filters](#using-filters) + - [Serve different site files in AP mode](#serve-different-site-files-in-ap-mode) + - [Rewrite to different index on AP](#rewrite-to-different-index-on-ap) + - [Serving different hosts](#serving-different-hosts) + - [Determine interface inside callbacks](#determine-interface-inside-callbacks) +- [Bad Responses](#bad-responses) + - [Respond with content using a callback without content length to HTTP/1.0 clients](#respond-with-content-using-a-callback-without-content-length-to-http10-clients) +- [Async WebSocket Plugin](#async-websocket-plugin) + - [Async WebSocket Event](#async-websocket-event) + - [Methods for sending data to a socket client](#methods-for-sending-data-to-a-socket-client) + - [Direct access to web socket message buffer](#direct-access-to-web-socket-message-buffer) + - [Limiting the number of web socket clients](#limiting-the-number-of-web-socket-clients) +- [Async Event Source Plugin](#async-event-source-plugin) + - [Setup Event Source on the server](#setup-event-source-on-the-server) + - [Setup Event Source in the browser](#setup-event-source-in-the-browser) +- [Scanning for available WiFi Networks](#scanning-for-available-wifi-networks) +- [Remove handlers and rewrites](#remove-handlers-and-rewrites) +- [Setting up the server](#setting-up-the-server) + - [Setup global and class functions as request handlers](#setup-global-and-class-functions-as-request-handlers) + - [Methods for controlling websocket connections](#methods-for-controlling-websocket-connections) + - [Adding Default Headers](#adding-default-headers) + - [Path variable](#path-variable) + +### Why should you care + +- Using asynchronous network means that you can handle more than one connection at the same time +- You are called once the request is ready and parsed +- When you send the response, you are immediately ready to handle other connections + while the server is taking care of sending the response in the background +- Speed is OMG +- Easy to use API, HTTP Basic and Digest MD5 Authentication (default), ChunkedResponse +- Easily extendible to handle any type of content +- Supports Continue 100 +- Async WebSocket plugin offering different locations without extra servers or ports +- Async EventSource (Server-Sent Events) plugin to send events to the browser +- URL Rewrite plugin for conditional and permanent url rewrites +- ServeStatic plugin that supports cache, Last-Modified, default index and more +- Simple template processing engine to handle templates + +### Important things to remember + +- This is fully asynchronous server and as such does not run on the loop thread. +- You can not use yield or delay or any function that uses them inside the callbacks +- The server is smart enough to know when to close the connection and free resources +- You can not send more than one response to a single request + +### Principles of operation + +#### The Async Web server + +- Listens for connections +- Wraps the new clients into `Request` +- Keeps track of clients and cleans memory +- Manages `Rewrites` and apply them on the request url +- Manages `Handlers` and attaches them to Requests + +#### Request Life Cycle + +- TCP connection is received by the server +- The connection is wrapped inside `Request` object +- When the request head is received (type, url, get params, http version and host), + the server goes through all `Rewrites` (in the order they were added) to rewrite the url and inject query parameters, + next, it goes through all attached `Handlers`(in the order they were added) trying to find one + that `canHandle` the given request. If none are found, the default(catch-all) handler is attached. +- The rest of the request is received, calling the `handleUpload` or `handleBody` methods of the `Handler` if they are needed (POST+File/Body) +- When the whole request is parsed, the result is given to the `handleRequest` method of the `Handler` and is ready to be responded to +- In the `handleRequest` method, to the `Request` is attached a `Response` object (see below) that will serve the response data back to the client +- When the `Response` is sent, the client is closed and freed from the memory + +#### Rewrites and how do they work + +- The `Rewrites` are used to rewrite the request url and/or inject get parameters for a specific request url path. +- All `Rewrites` are evaluated on the request in the order they have been added to the server. +- The `Rewrite` will change the request url only if the request url (excluding get parameters) is fully match + the rewrite url, and when the optional `Filter` callback return true. +- Setting a `Filter` to the `Rewrite` enables to control when to apply the rewrite, decision can be based on + request url, http version, request host/port/target host, get parameters or the request client's localIP or remoteIP. +- Two filter callbacks are provided: `ON_AP_FILTER` to execute the rewrite when request is made to the AP interface, + `ON_STA_FILTER` to execute the rewrite when request is made to the STA interface. +- The `Rewrite` can specify a target url with optional get parameters, e.g. `/to-url?with=params` + +#### Handlers and how do they work + +- The `Handlers` are used for executing specific actions to particular requests +- One `Handler` instance can be attached to any request and lives together with the server +- Setting a `Filter` to the `Handler` enables to control when to apply the handler, decision can be based on + request url, http version, request host/port/target host, get parameters or the request client's localIP or remoteIP. +- Two filter callbacks are provided: `ON_AP_FILTER` to execute the rewrite when request is made to the AP interface, + `ON_STA_FILTER` to execute the rewrite when request is made to the STA interface. +- The `canHandle` method is used for handler specific control on whether the requests can be handled + and for declaring any interesting headers that the `Request` should parse. Decision can be based on request + method, request url, http version, request host/port/target host and get parameters +- Once a `Handler` is attached to given `Request` (`canHandle` returned true) + that `Handler` takes care to receive any file/data upload and attach a `Response` + once the `Request` has been fully parsed +- `Handlers` are evaluated in the order they are attached to the server. The `canHandle` is called only + if the `Filter` that was set to the `Handler` return true. +- The first `Handler` that can handle the request is selected, not further `Filter` and `canHandle` are called. + +#### Responses and how do they work + +- The `Response` objects are used to send the response data back to the client +- The `Response` object lives with the `Request` and is freed on end or disconnect +- Different techniques are used depending on the response type to send the data in packets + returning back almost immediately and sending the next packet when this one is received. + Any time in between is spent to run the user loop and handle other network packets +- Responding asynchronously is probably the most difficult thing for most to understand +- Many different options exist for the user to make responding a background task + +#### Template processing + +- ESPAsyncWebserver contains simple template processing engine. +- Template processing can be added to most response types. +- Currently it supports only replacing template placeholders with actual values. No conditional processing, cycles, etc. +- Placeholders are delimited with `%` symbols. Like this: `%TEMPLATE_PLACEHOLDER%`. +- It works by extracting placeholder name from response text and passing it to user provided function which should return actual value to be used instead of placeholder. +- Since it's user provided function, it is possible for library users to implement conditional processing and cycles themselves. +- Since it's impossible to know the actual response size after template processing step in advance (and, therefore, to include it in response headers), the response becomes [chunked](#chunked-response). + +### Libraries and projects that use AsyncWebServer + +- [WebSocketToSerial](https://github.com/hallard/WebSocketToSerial) - Debug serial devices through the web browser +- [Sattrack](https://github.com/Hopperpop/Sattrack) - Track the ISS with ESP8266 +- [ESP Radio](https://github.com/Edzelf/Esp-radio) - Icecast radio based on ESP8266 and VS1053 +- [VZero](https://github.com/andig/vzero) - the Wireless zero-config controller for volkszaehler.org +- [ESPurna](https://bitbucket.org/xoseperez/espurna) - ESPurna ("spark" in Catalan) is a custom C firmware for ESP8266 based smart switches. It was originally developed with the ITead Sonoff in mind. +- [fauxmoESP](https://bitbucket.org/xoseperez/fauxmoesp) - Belkin WeMo emulator library for ESP8266. +- [ESP-RFID](https://github.com/omersiar/esp-rfid) - MFRC522 RFID Access Control Management project for ESP8266. + +### Request Variables + +#### Common Variables + +```cpp +request->version(); // uint8_t: 0 = HTTP/1.0, 1 = HTTP/1.1 +request->method(); // enum: HTTP_GET, HTTP_POST, HTTP_DELETE, HTTP_PUT, HTTP_PATCH, HTTP_HEAD, HTTP_OPTIONS +request->url(); // String: URL of the request (not including host, port or GET parameters) +request->host(); // String: The requested host (can be used for virtual hosting) +request->contentType(); // String: ContentType of the request (not avaiable in Handler::canHandle) +request->contentLength(); // size_t: ContentLength of the request (not avaiable in Handler::canHandle) +request->multipart(); // bool: True if the request has content type "multipart" +``` + +#### Headers + +```cpp +//List all collected headers +int headers = request->headers(); +int i; +for(i=0;igetHeader(i); + Serial.printf("HEADER[%s]: %s\n", h->name().c_str(), h->value().c_str()); +} + +//get specific header by name +if(request->hasHeader("MyHeader")){ + AsyncWebHeader* h = request->getHeader("MyHeader"); + Serial.printf("MyHeader: %s\n", h->value().c_str()); +} + +//List all collected headers (Compatibility) +int headers = request->headers(); +int i; +for(i=0;iheaderName(i).c_str(), request->header(i).c_str()); +} + +//get specific header by name (Compatibility) +if(request->hasHeader("MyHeader")){ + Serial.printf("MyHeader: %s\n", request->header("MyHeader").c_str()); +} +``` + +#### GET, POST and FILE parameters + +```cpp +//List all parameters +int params = request->params(); +for(int i=0;igetParam(i); + if(p->isFile()){ //p->isPost() is also true + Serial.printf("FILE[%s]: %s, size: %u\n", p->name().c_str(), p->value().c_str(), p->size()); + } else if(p->isPost()){ + Serial.printf("POST[%s]: %s\n", p->name().c_str(), p->value().c_str()); + } else { + Serial.printf("GET[%s]: %s\n", p->name().c_str(), p->value().c_str()); + } +} + +//Check if GET parameter exists +if(request->hasParam("download")) + AsyncWebParameter* p = request->getParam("download"); + +//Check if POST (but not File) parameter exists +if(request->hasParam("download", true)) + AsyncWebParameter* p = request->getParam("download", true); + +//Check if FILE was uploaded +if(request->hasParam("download", true, true)) + AsyncWebParameter* p = request->getParam("download", true, true); + +//List all parameters (Compatibility) +int args = request->args(); +for(int i=0;iargName(i).c_str(), request->arg(i).c_str()); +} + +//Check if parameter exists (Compatibility) +if(request->hasArg("download")) + String arg = request->arg("download"); +``` + +#### FILE Upload handling + +```cpp +void handleUpload(AsyncWebServerRequest *request, String filename, size_t index, uint8_t *data, size_t len, bool final){ + if(!index){ + Serial.printf("UploadStart: %s\n", filename.c_str()); + } + for(size_t i=0; i(); + // ... +}); +server.addHandler(handler); +``` + +### Responses + +#### Redirect to another URL + +```cpp +//to local url +request->redirect("/login"); + +//to external url +request->redirect("http://esp8266.com"); +``` + +#### Basic response with HTTP Code + +```cpp +request->send(404); //Sends 404 File Not Found +``` + +#### Basic response with HTTP Code and extra headers + +```cpp +AsyncWebServerResponse *response = request->beginResponse(404); //Sends 404 File Not Found +response->addHeader("Server","ESP Async Web Server"); +request->send(response); +``` + +#### Basic response with string content + +```cpp +request->send(200, "text/plain", "Hello World!"); +``` + +#### Basic response with string content and extra headers + +```cpp +AsyncWebServerResponse *response = request->beginResponse(200, "text/plain", "Hello World!"); +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 large webpage from PROGMEM containing templates + +```cpp +String processor(const String& var) +{ + if(var == "HELLO_FROM_TEMPLATE") + return F("Hello world!"); + return String(); +} + +// ... + +const char index_html[] PROGMEM = "..."; // large char array, tested with 14k +request->send_P(200, "text/html", index_html, processor); +``` + +#### Send large webpage from PROGMEM containing templates and extra headers + +```cpp +String processor(const String& var) +{ + if(var == "HELLO_FROM_TEMPLATE") + return F("Hello world!"); + return String(); +} + +// ... + +const char index_html[] PROGMEM = "..."; // large char array, tested with 14k +AsyncWebServerResponse *response = request->beginResponse_P(200, "text/html", index_html, processor); +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 +request->send(Serial, "text/plain", 12); +``` + +#### Respond with content coming from a Stream and extra headers + +```cpp +//read 12 bytes from Serial and send them as Content Type text/plain +AsyncWebServerResponse *response = request->beginResponse(Serial, "text/plain", 12); +response->addHeader("Server","ESP Async Web Server"); +request->send(response); +``` + +#### Respond with content coming from a Stream containing templates + +```cpp +String processor(const String& var) +{ + if(var == "HELLO_FROM_TEMPLATE") + return F("Hello world!"); + return String(); +} + +// ... + +//read 12 bytes from Serial and send them as Content Type text/plain +request->send(Serial, "text/plain", 12, processor); +``` + +#### Respond with content coming from a Stream containing templates and extra headers + +```cpp +String processor(const String& var) +{ + if(var == "HELLO_FROM_TEMPLATE") + return F("Hello world!"); + return String(); +} + +// ... + +//read 12 bytes from Serial and send them as Content Type text/plain +AsyncWebServerResponse *response = request->beginResponse(Serial, "text/plain", 12, processor); +response->addHeader("Server","ESP Async Web Server"); +request->send(response); +``` + +#### Respond with content coming from a File + +```cpp +//Send index.htm with default content type +request->send(SPIFFS, "/index.htm"); + +//Send index.htm as text +request->send(SPIFFS, "/index.htm", "text/plain"); + +//Download index.htm +request->send(SPIFFS, "/index.htm", String(), true); +``` + +#### Respond with content coming from a File and extra headers + +```cpp +//Send index.htm with default content type +AsyncWebServerResponse *response = request->beginResponse(SPIFFS, "/index.htm"); + +//Send index.htm as text +AsyncWebServerResponse *response = request->beginResponse(SPIFFS, "/index.htm", "text/plain"); + +//Download index.htm +AsyncWebServerResponse *response = request->beginResponse(SPIFFS, "/index.htm", String(), true); + +response->addHeader("Server","ESP Async Web Server"); +request->send(response); +``` + +#### Respond with content coming from a File containing templates + +Internally uses [Chunked Response](#chunked-response). + +Index.htm contents: + +``` +%HELLO_FROM_TEMPLATE% +``` + +Somewhere in source files: + +```cpp +String processor(const String& var) +{ + if(var == "HELLO_FROM_TEMPLATE") + return F("Hello world!"); + return String(); +} + +// ... + +//Send index.htm with template processor function +request->send(SPIFFS, "/index.htm", String(), false, processor); +``` + +#### Respond with content using a callback + +```cpp +//send 128 bytes as plain text +request->send("text/plain", 128, [](uint8_t *buffer, size_t maxLen, size_t index) -> size_t { + //Write up to "maxLen" bytes into "buffer" and return the amount written. + //index equals the amount of bytes that have been already sent + //You will not be asked for more bytes once the content length has been reached. + //Keep in mind that you can not delay or yield waiting for more data! + //Send what you currently have and you will be asked for more again + return mySource.read(buffer, maxLen); +}); +``` + +#### Respond with content using a callback and extra headers + +```cpp +//send 128 bytes as plain text +AsyncWebServerResponse *response = request->beginResponse("text/plain", 128, [](uint8_t *buffer, size_t maxLen, size_t index) -> size_t { + //Write up to "maxLen" bytes into "buffer" and return the amount written. + //index equals the amount of bytes that have been already sent + //You will not be asked for more bytes once the content length has been reached. + //Keep in mind that you can not delay or yield waiting for more data! + //Send what you currently have and you will be asked for more again + return mySource.read(buffer, maxLen); +}); +response->addHeader("Server","ESP Async Web Server"); +request->send(response); +``` + +#### Respond with file content using a callback and extra headers + +With this code your ESP is able to serve even large (large in terms of ESP, e.g. 100kB) files +without memory problems. + +You need to create a file handler in outer function (to have a single one for request) but use +it in a lambda. The catch is that the lambda has it's own lifecycle which may/will cause it's +called after the original function is over thus the original file handle is destroyed. Using the +captured `&file` in the lambda then causes segfault (Hello, Exception 9!) and the whole ESP crashes. +By using this code, you tell the compiler to move the handle into the lambda so it won't be +destroyed when outer function (that one where you call `request->send(response)`) ends. + +```cpp +const File file = ... // e.g. SPIFFS.open(path, "r"); + +const contentType = "application/javascript"; + +AsyncWebServerResponse *response = request->beginResponse( + contentType, + file.size(), + [file](uint8_t *buffer, size_t maxLen, size_t total) mutable -> size_t { + int bytes = file.read(buffer, maxLen); + + // close file at the end + if (bytes + total == file.size()) file.close(); + + return max(0, bytes); // return 0 even when no bytes were loaded + } +); + +if (gzipped) { + response->addHeader(F("Content-Encoding"), F("gzip")); +} + +request->send(response); +``` + +#### Respond with content using a callback containing templates + +```cpp +String processor(const String& var) +{ + if(var == "HELLO_FROM_TEMPLATE") + return F("Hello world!"); + return String(); +} + +// ... + +//send 128 bytes as plain text +request->send("text/plain", 128, [](uint8_t *buffer, size_t maxLen, size_t index) -> size_t { + //Write up to "maxLen" bytes into "buffer" and return the amount written. + //index equals the amount of bytes that have been already sent + //You will not be asked for more bytes once the content length has been reached. + //Keep in mind that you can not delay or yield waiting for more data! + //Send what you currently have and you will be asked for more again + return mySource.read(buffer, maxLen); +}, processor); +``` + +#### Respond with content using a callback containing templates and extra headers + +```cpp +String processor(const String& var) +{ + if(var == "HELLO_FROM_TEMPLATE") + return F("Hello world!"); + return String(); +} + +// ... + +//send 128 bytes as plain text +AsyncWebServerResponse *response = request->beginResponse("text/plain", 128, [](uint8_t *buffer, size_t maxLen, size_t index) -> size_t { + //Write up to "maxLen" bytes into "buffer" and return the amount written. + //index equals the amount of bytes that have been already sent + //You will not be asked for more bytes once the content length has been reached. + //Keep in mind that you can not delay or yield waiting for more data! + //Send what you currently have and you will be asked for more again + return mySource.read(buffer, maxLen); +}, processor); +response->addHeader("Server","ESP Async Web Server"); +request->send(response); +``` + +#### Chunked Response + +Used when content length is unknown. Works best if the client supports HTTP/1.1 + +```cpp +AsyncWebServerResponse *response = request->beginChunkedResponse("text/plain", [](uint8_t *buffer, size_t maxLen, size_t index) -> size_t { + //Write up to "maxLen" bytes into "buffer" and return the amount written. + //index equals the amount of bytes that have been already sent + //You will be asked for more data until 0 is returned + //Keep in mind that you can not delay or yield waiting for more data! + return mySource.read(buffer, maxLen); +}); +response->addHeader("Server","ESP Async Web Server"); +request->send(response); +``` + +#### Chunked Response containing templates + +Used when content length is unknown. Works best if the client supports HTTP/1.1 + +```cpp +String processor(const String& var) +{ + if(var == "HELLO_FROM_TEMPLATE") + return F("Hello world!"); + return String(); +} + +// ... + +AsyncWebServerResponse *response = request->beginChunkedResponse("text/plain", [](uint8_t *buffer, size_t maxLen, size_t index) -> size_t { + //Write up to "maxLen" bytes into "buffer" and return the amount written. + //index equals the amount of bytes that have been already sent + //You will be asked for more data until 0 is returned + //Keep in mind that you can not delay or yield waiting for more data! + return mySource.read(buffer, maxLen); +}, processor); +response->addHeader("Server","ESP Async Web Server"); +request->send(response); +``` + +#### Print to response + +```cpp +AsyncResponseStream *response = request->beginResponseStream("text/html"); +response->addHeader("Server","ESP Async Web Server"); +response->printf("Webpage at %s", request->url().c_str()); + +response->print("

Hello "); +response->print(request->client()->remoteIP()); +response->print("

"); + +response->print("

General

"); +response->print("
    "); +response->printf("
  • Version: HTTP/1.%u
  • ", request->version()); +response->printf("
  • Method: %s
  • ", request->methodToString()); +response->printf("
  • URL: %s
  • ", request->url().c_str()); +response->printf("
  • Host: %s
  • ", request->host().c_str()); +response->printf("
  • ContentType: %s
  • ", request->contentType().c_str()); +response->printf("
  • ContentLength: %u
  • ", request->contentLength()); +response->printf("
  • Multipart: %s
  • ", request->multipart()?"true":"false"); +response->print("
"); + +response->print("

Headers

"); +response->print("
    "); +int headers = request->headers(); +for(int i=0;igetHeader(i); + response->printf("
  • %s: %s
  • ", h->name().c_str(), h->value().c_str()); +} +response->print("
"); + +response->print("

Parameters

"); +response->print("
    "); +int params = request->params(); +for(int i=0;igetParam(i); + if(p->isFile()){ + response->printf("
  • FILE[%s]: %s, size: %u
  • ", p->name().c_str(), p->value().c_str(), p->size()); + } else if(p->isPost()){ + response->printf("
  • POST[%s]: %s
  • ", p->name().c_str(), p->value().c_str()); + } else { + response->printf("
  • GET[%s]: %s
  • ", p->name().c_str(), p->value().c_str()); + } +} +response->print("
"); + +response->print(""); +//send the response last +request->send(response); +``` + +#### ArduinoJson Basic Response + +This way of sending Json is great for when the result is below 4KB + +```cpp +#include "AsyncJson.h" +#include "ArduinoJson.h" + + +AsyncResponseStream *response = request->beginResponseStream("application/json"); +DynamicJsonBuffer jsonBuffer; +JsonObject &root = jsonBuffer.createObject(); +root["heap"] = ESP.getFreeHeap(); +root["ssid"] = WiFi.SSID(); +root.printTo(*response); +request->send(response); +``` + +#### ArduinoJson Advanced Response + +This response can handle really large Json objects (tested to 40KB) +There isn't any noticeable speed decrease for small results with the method above +Since ArduinoJson does not allow reading parts of the string, the whole Json has to +be passed every time a chunks needs to be sent, which shows speed decrease proportional +to the resulting json packets + +```cpp +#include "AsyncJson.h" +#include "ArduinoJson.h" + + +AsyncJsonResponse * response = new AsyncJsonResponse(); +response->addHeader("Server","ESP Async Web Server"); +JsonObject& root = response->getRoot(); +root["heap"] = ESP.getFreeHeap(); +root["ssid"] = WiFi.SSID(); +response->setLength(); +request->send(response); +``` + +### Serving static files + +In addition to serving files from SPIFFS as described above, the server provide a dedicated handler that optimize the +performance of serving files from SPIFFS - `AsyncStaticWebHandler`. Use `server.serveStatic()` function to +initialize and add a new instance of `AsyncStaticWebHandler` to the server. +The Handler will not handle the request if the file does not exists, e.g. the server will continue to look for another +handler that can handle the request. +Notice that you can chain setter functions to setup the handler, or keep a pointer to change it at a later time. + +#### Serving specific file by name + +```cpp +// Serve the file "/www/page.htm" when request url is "/page.htm" +server.serveStatic("/page.htm", SPIFFS, "/www/page.htm"); +``` + +#### Serving files in directory + +To serve files in a directory, the path to the files should specify a directory in SPIFFS and ends with "/". + +```cpp +// Serve files in directory "/www/" when request url starts with "/" +// Request to the root or none existing files will try to server the defualt +// file name "index.htm" if exists +server.serveStatic("/", SPIFFS, "/www/"); + +// Server with different default file +server.serveStatic("/", SPIFFS, "/www/").setDefaultFile("default.html"); +``` + +#### Serving static files with authentication + +```cpp +server + .serveStatic("/", SPIFFS, "/www/") + .setDefaultFile("default.html") + .setAuthentication("user", "pass"); +``` + +#### Specifying Cache-Control header + +It is possible to specify Cache-Control header value to reduce the number of calls to the server once the client loaded +the files. For more information on Cache-Control values see [Cache-Control](https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9) + +```cpp +// Cache responses for 10 minutes (600 seconds) +server.serveStatic("/", SPIFFS, "/www/").setCacheControl("max-age=600"); + +//*** Change Cache-Control after server setup *** + +// During setup - keep a pointer to the handler +AsyncStaticWebHandler* handler = &server.serveStatic("/", SPIFFS, "/www/").setCacheControl("max-age=600"); + +// At a later event - change Cache-Control +handler->setCacheControl("max-age=30"); +``` + +#### Specifying Date-Modified header + +It is possible to specify Date-Modified header to enable the server to return Not-Modified (304) response for requests +with "If-Modified-Since" header with the same value, instead of responding with the actual file content. + +```cpp +// Update the date modified string every time files are updated +server.serveStatic("/", SPIFFS, "/www/").setLastModified("Mon, 20 Jun 2016 14:00:00 GMT"); + +//*** Chage last modified value at a later stage *** + +// During setup - read last modified value from config or EEPROM +String date_modified = loadDateModified(); +AsyncStaticWebHandler* handler = &server.serveStatic("/", SPIFFS, "/www/"); +handler->setLastModified(date_modified); + +// At a later event when files are updated +String date_modified = getNewDateModfied(); +saveDateModified(date_modified); // Save for next reset +handler->setLastModified(date_modified); +``` + +#### Specifying Template Processor callback + +It is possible to specify template processor for static files. For information on template processor see +[Respond with content coming from a File containing templates](#respond-with-content-coming-from-a-file-containing-templates). + +```cpp +String processor(const String& var) +{ + if(var == "HELLO_FROM_TEMPLATE") + return F("Hello world!"); + return String(); +} + +// ... + +server.serveStatic("/", SPIFFS, "/www/").setTemplateProcessor(processor); +``` + +#### Serving static files by custom handling + +It may happen your static files are too big and the ESP will crash the request before it sends the whole file. +In that case, you can handle static files with custom file serving through not found handler. + +This code below is more-or-less equivalent to this: + +```cpp +webServer.serveStatic("/", SPIFFS, STATIC_FILES_PREFIX).setDefaultFile("index.html") +``` + +First, declare the handling function: + +```cpp +bool handleStaticFile(AsyncWebServerRequest *request) { + String path = STATIC_FILES_PREFIX + request->url(); + + if (path.endsWith("/")) path += F("index.html"); + + String contentType = getContentType(path); + String pathWithGz = path + ".gz"; + + if (SPIFFS.exists(pathWithGz) || SPIFFS.exists(path)) { + bool gzipped = false; + if (SPIFFS.exists(pathWithGz)) { + gzipped = true; + path += ".gz"; + } + + // TODO serve the file + + return true; + } + + return false; +} +``` + +And then configure your webserver: + +```cpp +webServer.onNotFound([](AsyncWebServerRequest *request) { + if (handleStaticFile(request)) return; + + request->send(404); +}); +``` + +You may want to try [Respond with file content using a callback and extra headers](#respond-with-file-content-using-a-callback-and-extra-headers) +For actual serving the file. + +### Param Rewrite With Matching + +It is possible to rewrite the request url with parameter matchg. Here is an example with one parameter: +Rewrite for example "/radio/{frequence}" -> "/radio?f={frequence}" + +```cpp +class OneParamRewrite : public AsyncWebRewrite +{ + protected: + String _urlPrefix; + int _paramIndex; + String _paramsBackup; + + public: + OneParamRewrite(const char* from, const char* to) + : AsyncWebRewrite(from, to) { + + _paramIndex = _from.indexOf('{'); + + if( _paramIndex >=0 && _from.endsWith("}")) { + _urlPrefix = _from.substring(0, _paramIndex); + int index = _params.indexOf('{'); + if(index >= 0) { + _params = _params.substring(0, index); + } + } else { + _urlPrefix = _from; + } + _paramsBackup = _params; + } + + bool match(AsyncWebServerRequest *request) override { + if(request->url().startsWith(_urlPrefix)) { + if(_paramIndex >= 0) { + _params = _paramsBackup + request->url().substring(_paramIndex); + } else { + _params = _paramsBackup; + } + return true; + + } else { + return false; + } + } +}; +``` + +Usage: + +```cpp + server.addRewrite( new OneParamRewrite("/radio/{frequence}", "/radio?f={frequence}") ); +``` + +### Using filters + +Filters can be set to `Rewrite` or `Handler` in order to control when to apply the rewrite and consider the handler. +A filter is a callback function that evaluates the request and return a boolean `true` to include the item +or `false` to exclude it. +Two filter callback are provided for convince: + +- `ON_STA_FILTER` - return true when requests are made to the STA (station mode) interface. +- `ON_AP_FILTER` - return true when requests are made to the AP (access point) interface. + +#### Serve different site files in AP mode + +```cpp +server.serveStatic("/", SPIFFS, "/www/").setFilter(ON_STA_FILTER); +server.serveStatic("/", SPIFFS, "/ap/").setFilter(ON_AP_FILTER); +``` + +#### Rewrite to different index on AP + +```cpp +// Serve the file "/www/index-ap.htm" in AP, and the file "/www/index.htm" on STA +server.rewrite("/", "index.htm"); +server.rewrite("/index.htm", "index-ap.htm").setFilter(ON_AP_FILTER); +server.serveStatic("/", SPIFFS, "/www/"); +``` + +#### Serving different hosts + +```cpp +// Filter callback using request host +bool filterOnHost1(AsyncWebServerRequest *request) { return request->host() == "host1"; } + +// Server setup: server files in "/host1/" to requests for "host1", and files in "/www/" otherwise. +server.serveStatic("/", SPIFFS, "/host1/").setFilter(filterOnHost1); +server.serveStatic("/", SPIFFS, "/www/"); +``` + +#### Determine interface inside callbacks + +```cpp + String RedirectUrl = "http://"; + if (ON_STA_FILTER(request)) { + RedirectUrl += WiFi.localIP().toString(); + } else { + RedirectUrl += WiFi.softAPIP().toString(); + } + RedirectUrl += "/index.htm"; + request->redirect(RedirectUrl); +``` + +### Bad Responses + +Some responses are implemented, but you should not use them, because they do not conform to HTTP. +The following example will lead to unclean close of the connection and more time wasted +than providing the length of the content + +#### Respond with content using a callback without content length to HTTP/1.0 clients + +```cpp +//This is used as fallback for chunked responses to HTTP/1.0 Clients +request->send("text/plain", 0, [](uint8_t *buffer, size_t maxLen, size_t index) -> size_t { + //Write up to "maxLen" bytes into "buffer" and return the amount written. + //You will be asked for more data until 0 is returned + //Keep in mind that you can not delay or yield waiting for more data! + return mySource.read(buffer, maxLen); +}); +``` + +### Async WebSocket Plugin + +The server includes a web socket plugin which lets you define different WebSocket locations to connect to +without starting another listening service or using different port + +#### Async WebSocket Event + +```cpp + +void onEvent(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventType type, void * arg, uint8_t *data, size_t len){ + if(type == WS_EVT_CONNECT){ + //client connected + os_printf("ws[%s][%u] connect\n", server->url(), client->id()); + client->printf("Hello Client %u :)", client->id()); + client->ping(); + } else if(type == WS_EVT_DISCONNECT){ + //client disconnected + os_printf("ws[%s][%u] disconnect: %u\n", server->url(), client->id()); + } else if(type == WS_EVT_ERROR){ + //error was received from the other end + os_printf("ws[%s][%u] error(%u): %s\n", server->url(), client->id(), *((uint16_t*)arg), (char*)data); + } else if(type == WS_EVT_PONG){ + //pong message was received (in response to a ping request maybe) + os_printf("ws[%s][%u] pong[%u]: %s\n", server->url(), client->id(), len, (len)?(char*)data:""); + } else if(type == WS_EVT_DATA){ + //data packet + AwsFrameInfo * info = (AwsFrameInfo*)arg; + if(info->final && info->index == 0 && info->len == len){ + //the whole message is in a single frame and we got all of it's data + os_printf("ws[%s][%u] %s-message[%llu]: ", server->url(), client->id(), (info->opcode == WS_TEXT)?"text":"binary", info->len); + if(info->opcode == WS_TEXT){ + data[len] = 0; + os_printf("%s\n", (char*)data); + } else { + for(size_t i=0; i < info->len; i++){ + os_printf("%02x ", data[i]); + } + os_printf("\n"); + } + if(info->opcode == WS_TEXT) + client->text("I got your text message"); + else + client->binary("I got your binary message"); + } else { + //message is comprised of multiple frames or the frame is split into multiple packets + if(info->index == 0){ + if(info->num == 0) + os_printf("ws[%s][%u] %s-message start\n", server->url(), client->id(), (info->message_opcode == WS_TEXT)?"text":"binary"); + os_printf("ws[%s][%u] frame[%u] start[%llu]\n", server->url(), client->id(), info->num, info->len); + } + + 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->message_opcode == WS_TEXT){ + data[len] = 0; + os_printf("%s\n", (char*)data); + } else { + for(size_t i=0; i < len; i++){ + os_printf("%02x ", data[i]); + } + os_printf("\n"); + } + + if((info->index + len) == info->len){ + os_printf("ws[%s][%u] frame[%u] end[%llu]\n", server->url(), client->id(), info->num, info->len); + if(info->final){ + os_printf("ws[%s][%u] %s-message end\n", server->url(), client->id(), (info->message_opcode == WS_TEXT)?"text":"binary"); + if(info->message_opcode == WS_TEXT) + client->text("I got your text message"); + else + client->binary("I got your binary message"); + } + } + } + } +} +``` + +#### Methods for sending data to a socket client + +```cpp + + + +//Server methods +AsyncWebSocket ws("/ws"); +//printf to a client +ws.printf((uint32_t)client_id, arguments...); +//printf to all clients +ws.printfAll(arguments...); +//printf_P to a client +ws.printf_P((uint32_t)client_id, PSTR(format), arguments...); +//printfAll_P to all clients +ws.printfAll_P(PSTR(format), arguments...); +//send text to a client +ws.text((uint32_t)client_id, (char*)text); +ws.text((uint32_t)client_id, (uint8_t*)text, (size_t)len); +//send text from PROGMEM to a client +ws.text((uint32_t)client_id, PSTR("text")); +const char flash_text[] PROGMEM = "Text to send" +ws.text((uint32_t)client_id, FPSTR(flash_text)); +//send text to all clients +ws.textAll((char*)text); +ws.textAll((uint8_t*)text, (size_t)len); +//send binary to a client +ws.binary((uint32_t)client_id, (char*)binary); +ws.binary((uint32_t)client_id, (uint8_t*)binary, (size_t)len); +//send binary from PROGMEM to a client +const uint8_t flash_binary[] PROGMEM = { 0x01, 0x02, 0x03, 0x04 }; +ws.binary((uint32_t)client_id, flash_binary, 4); +//send binary to all clients +ws.binaryAll((char*)binary); +ws.binaryAll((uint8_t*)binary, (size_t)len); +//HTTP Authenticate before switch to Websocket protocol +ws.setAuthentication("user", "pass"); + +//client methods +AsyncWebSocketClient * client; +//printf +client->printf(arguments...); +//printf_P +client->printf_P(PSTR(format), arguments...); +//send text +client->text((char*)text); +client->text((uint8_t*)text, (size_t)len); +//send text from PROGMEM +client->text(PSTR("text")); +const char flash_text[] PROGMEM = "Text to send"; +client->text(FPSTR(flash_text)); +//send binary +client->binary((char*)binary); +client->binary((uint8_t*)binary, (size_t)len); +//send binary from PROGMEM +const uint8_t flash_binary[] PROGMEM = { 0x01, 0x02, 0x03, 0x04 }; +client->binary(flash_binary, 4); +``` + +#### Direct access to web socket message buffer + +When sending a web socket message using the above methods a buffer is created. Under certain circumstances you might want to manipulate or populate this buffer directly from your application, for example to prevent unnecessary duplications of the data. This example below shows how to create a buffer and print data to it from an ArduinoJson object then send it. + +```cpp +void sendDataWs(AsyncWebSocketClient * client) +{ + DynamicJsonBuffer jsonBuffer; + JsonObject& root = jsonBuffer.createObject(); + root["a"] = "abc"; + root["b"] = "abcd"; + root["c"] = "abcde"; + root["d"] = "abcdef"; + root["e"] = "abcdefg"; + size_t len = root.measureLength(); + AsyncWebSocketMessageBuffer * buffer = ws.makeBuffer(len); // creates a buffer (len + 1) for you. + if (buffer) { + root.printTo((char *)buffer->get(), len + 1); + if (client) { + client->text(buffer); + } else { + ws.textAll(buffer); + } + } +} +``` + +#### Limiting the number of web socket clients + +Browsers sometimes do not correctly close the websocket connection, even when the close() function is called in javascript. This will eventually exhaust the web server's resources and will cause the server to crash. Periodically calling the cleanClients() function from the main loop() function limits the number of clients by closing the oldest client when the maximum number of clients has been exceeded. This can called be every cycle, however, if you wish to use less power, then calling as infrequently as once per second is sufficient. + +```cpp +void loop(){ + ws.cleanupClients(); +} +``` + +### Async Event Source Plugin + +The server includes EventSource (Server-Sent Events) plugin which can be used to send short text events to the browser. +Difference between EventSource and WebSockets is that EventSource is single direction, text-only protocol. + +#### Setup Event Source on the server + +```cpp +AsyncWebServer server(80); +AsyncEventSource events("/events"); + +void setup(){ + // setup ...... + events.onConnect([](AsyncEventSourceClient *client){ + if(client->lastId()){ + Serial.printf("Client reconnected! Last message ID that it gat is: %u\n", client->lastId()); + } + //send event with message "hello!", id current millis + // and set reconnect delay to 1 second + client->send("hello!",NULL,millis(),1000); + }); + //HTTP Basic authentication + events.setAuthentication("user", "pass"); + server.addHandler(&events); + // setup ...... +} + +void loop(){ + if(eventTriggered){ // your logic here + //send event "myevent" + events.send("my event content","myevent",millis()); + } +} +``` + +#### Setup Event Source in the browser + +```javascript +if (!!window.EventSource) { + var source = new EventSource("/events"); + + source.addEventListener( + "open", + function (e) { + console.log("Events Connected"); + }, + false + ); + + source.addEventListener( + "error", + function (e) { + if (e.target.readyState != EventSource.OPEN) { + console.log("Events Disconnected"); + } + }, + false + ); + + source.addEventListener( + "message", + function (e) { + console.log("message", e.data); + }, + false + ); + + source.addEventListener( + "myevent", + function (e) { + console.log("myevent", e.data); + }, + false + ); +} +``` + +### Scanning for available WiFi Networks + +```cpp +//First request will return 0 results unless you start scan from somewhere else (loop/setup) +//Do not request more often than 3-5 seconds +server.on("/scan", HTTP_GET, [](AsyncWebServerRequest *request){ + String json = "["; + int n = WiFi.scanComplete(); + if(n == -2){ + WiFi.scanNetworks(true); + } else if(n){ + for (int i = 0; i < n; ++i){ + if(i) json += ","; + json += "{"; + json += "\"rssi\":"+String(WiFi.RSSI(i)); + json += ",\"ssid\":\""+WiFi.SSID(i)+"\""; + json += ",\"bssid\":\""+WiFi.BSSIDstr(i)+"\""; + json += ",\"channel\":"+String(WiFi.channel(i)); + json += ",\"secure\":"+String(WiFi.encryptionType(i)); + json += ",\"hidden\":"+String(WiFi.isHidden(i)?"true":"false"); + json += "}"; + } + WiFi.scanDelete(); + if(WiFi.scanComplete() == -2){ + WiFi.scanNetworks(true); + } + } + json += "]"; + request->send(200, "application/json", json); + json = String(); +}); +``` + +### Remove handlers and rewrites + +Server goes through handlers in same order as they were added. You can't simple add handler with same path to override them. +To remove handler: + +```arduino +// save callback for particular URL path +auto handler = server.on("/some/path", [](AsyncWebServerRequest *request){ + //do something useful +}); +// when you don't need handler anymore remove it +server.removeHandler(&handler); + +// same with rewrites +server.removeRewrite(&someRewrite); + +server.onNotFound([](AsyncWebServerRequest *request){ + request->send(404); +}); + +// remove server.onNotFound handler +server.onNotFound(NULL); + +// remove all rewrites, handlers and onNotFound/onFileUpload/onRequestBody callbacks +server.reset(); +``` + +### Setting up the server + +```cpp +#include "ESPAsyncTCP.h" +#include "ESPAsyncWebServer.h" + +AsyncWebServer server(80); +AsyncWebSocket ws("/ws"); // access at ws://[esp ip]/ws +AsyncEventSource events("/events"); // event source (Server-Sent events) + +const char* ssid = "your-ssid"; +const char* password = "your-pass"; +const char* http_username = "admin"; +const char* http_password = "admin"; + +//flag to use from web update to reboot the ESP +bool shouldReboot = false; + +void onRequest(AsyncWebServerRequest *request){ + //Handle Unknown Request + request->send(404); +} + +void onBody(AsyncWebServerRequest *request, uint8_t *data, size_t len, size_t index, size_t total){ + //Handle body +} + +void onUpload(AsyncWebServerRequest *request, String filename, size_t index, uint8_t *data, size_t len, bool final){ + //Handle upload +} + +void onEvent(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventType type, void * arg, uint8_t *data, size_t len){ + //Handle WebSocket event +} + +void setup(){ + Serial.begin(115200); + WiFi.mode(WIFI_STA); + WiFi.begin(ssid, password); + if (WiFi.waitForConnectResult() != WL_CONNECTED) { + Serial.printf("WiFi Failed!\n"); + return; + } + + // attach AsyncWebSocket + ws.onEvent(onEvent); + server.addHandler(&ws); + + // attach AsyncEventSource + server.addHandler(&events); + + // respond to GET requests on URL /heap + server.on("/heap", HTTP_GET, [](AsyncWebServerRequest *request){ + request->send(200, "text/plain", String(ESP.getFreeHeap())); + }); + + // upload a file to /upload + server.on("/upload", HTTP_POST, [](AsyncWebServerRequest *request){ + request->send(200); + }, onUpload); + + // send a file when /index is requested + server.on("/index", HTTP_ANY, [](AsyncWebServerRequest *request){ + request->send(SPIFFS, "/index.htm"); + }); + + // HTTP basic authentication + server.on("/login", HTTP_GET, [](AsyncWebServerRequest *request){ + if(!request->authenticate(http_username, http_password)) + return request->requestAuthentication(); + request->send(200, "text/plain", "Login Success!"); + }); + + // Simple Firmware Update Form + server.on("/update", HTTP_GET, [](AsyncWebServerRequest *request){ + request->send(200, "text/html", "
"); + }); + server.on("/update", HTTP_POST, [](AsyncWebServerRequest *request){ + shouldReboot = !Update.hasError(); + AsyncWebServerResponse *response = request->beginResponse(200, "text/plain", shouldReboot?"OK":"FAIL"); + response->addHeader("Connection", "close"); + request->send(response); + },[](AsyncWebServerRequest *request, String filename, size_t index, uint8_t *data, size_t len, bool final){ + if(!index){ + Serial.printf("Update Start: %s\n", filename.c_str()); + Update.runAsync(true); + if(!Update.begin((ESP.getFreeSketchSpace() - 0x1000) & 0xFFFFF000)){ + Update.printError(Serial); + } + } + if(!Update.hasError()){ + if(Update.write(data, len) != len){ + Update.printError(Serial); + } + } + if(final){ + if(Update.end(true)){ + Serial.printf("Update Success: %uB\n", index+len); + } else { + Update.printError(Serial); + } + } + }); + + // attach filesystem root at URL /fs + server.serveStatic("/fs", SPIFFS, "/"); + + // Catch-All Handlers + // Any request that can not find a Handler that canHandle it + // ends in the callbacks below. + server.onNotFound(onRequest); + server.onFileUpload(onUpload); + server.onRequestBody(onBody); + + server.begin(); +} + +void loop(){ + if(shouldReboot){ + Serial.println("Rebooting..."); + delay(100); + ESP.restart(); + } + static char temp[128]; + sprintf(temp, "Seconds since boot: %u", millis()/1000); + events.send(temp, "time"); //send event "time" +} +``` + +#### Setup global and class functions as request handlers + +```cpp +#include +#include +#include +#include + +void handleRequest(AsyncWebServerRequest *request){} + +class WebClass { +public : + AsyncWebServer classWebServer = AsyncWebServer(81); + + WebClass(){}; + + void classRequest (AsyncWebServerRequest *request){} + + void begin(){ + // attach global request handler + classWebServer.on("/example", HTTP_ANY, handleRequest); + + // attach class request handler + classWebServer.on("/example", HTTP_ANY, std::bind(&WebClass::classRequest, this, std::placeholders::_1)); + } +}; + +AsyncWebServer globalWebServer(80); +WebClass webClassInstance; + +void setup() { + // attach global request handler + globalWebServer.on("/example", HTTP_ANY, handleRequest); + + // attach class request handler + globalWebServer.on("/example", HTTP_ANY, std::bind(&WebClass::classRequest, webClassInstance, std::placeholders::_1)); +} + +void loop() { + +} +``` + +#### Methods for controlling websocket connections + +```cpp + // Disable client connections if it was activated + if ( ws.enabled() ) + ws.enable(false); + + // enable client connections if it was disabled + if ( !ws.enabled() ) + ws.enable(true); +``` + +Example of OTA code + +```cpp + // OTA callbacks + ArduinoOTA.onStart([]() { + // Clean SPIFFS + SPIFFS.end(); + + // Disable client connections + ws.enable(false); + + // Advertise connected clients what's going on + ws.textAll("OTA Update Started"); + + // Close them + ws.closeAll(); + + }); + +``` + +#### Adding Default Headers + +In some cases, such as when working with CORS, or with some sort of custom authentication system, +you might need to define a header that should get added to all responses (including static, websocket and EventSource). +The DefaultHeaders singleton allows you to do this. + +Example: + +```cpp +DefaultHeaders::Instance().addHeader("Access-Control-Allow-Origin", "*"); +webServer.begin(); +``` + +_NOTE_: You will still need to respond to the OPTIONS method for CORS pre-flight in most cases. (unless you are only using GET) + +This is one option: + +```cpp +webServer.onNotFound([](AsyncWebServerRequest *request) { + if (request->method() == HTTP_OPTIONS) { + request->send(200); + } else { + request->send(404); + } +}); +``` + +#### Path variable + +With path variable you can create a custom regex rule for a specific parameter in a route. +For example we want a `sensorId` parameter in a route rule to match only a integer. + +```cpp + server.on("^\\/sensor\\/([0-9]+)$", HTTP_GET, [] (AsyncWebServerRequest *request) { + String sensorId = request->pathArg(0); + }); +``` + +_NOTE_: All regex patterns starts with `^` and ends with `$` + +To enable the `Path variable` support, you have to define the buildflag `-DASYNCWEBSERVER_REGEX`. + +For Arduino IDE create/update `platform.local.txt`: + +`Windows`: C:\Users\(username)\AppData\Local\Arduino15\packages\\`{espxxxx}`\hardware\\`espxxxx`\\`{version}`\platform.local.txt + +`Linux`: ~/.arduino15/packages/`{espxxxx}`/hardware/`{espxxxx}`/`{version}`/platform.local.txt + +Add/Update the following line: + +``` + compiler.cpp.extra_flags=-DDASYNCWEBSERVER_REGEX +``` + +For platformio modify `platformio.ini`: + +```ini +[env:myboard] +build_flags = + -DASYNCWEBSERVER_REGEX +``` + +_NOTE_: By enabling `ASYNCWEBSERVER_REGEX`, `` will be included. This will add an 100k to your binary. diff --git a/docs/index.md b/docs/index.md index 550c0a85c..95181419a 100644 --- a/docs/index.md +++ b/docs/index.md @@ -15,7 +15,17 @@ Supports: WebSocket, SSE, Authentication, Arduino Json 7, File Upload, Static Fi This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubox-node-org/ESPAsyncWebServer) and includes all the concurrency fixes. -## Coordinate and dependencies: +- [Coordinate and dependencies](#coordinate-and-dependencies) +- [Changes in this fork](#changes-in-this-fork) +- [Important recommendations](#important-recommendations) +- [`AsyncWebSocketMessageBuffer` and `makeBuffer()`](#asyncwebsocketmessagebuffer-and-makebuffer) +- [How to replace a response](#how-to-replace-a-response) +- [How to use Middleware](#how-to-use-middleware) +- [How to use authentication with AuthenticationMiddleware](#how-to-use-authentication-with-authenticationmiddleware) +- [Migration to Middleware to improve performance and memory usage](#migration-to-middleware-to-improve-performance-and-memory-usage) +- [Original Documentation](#original-documentation) + +## Coordinate and dependencies **WARNING** The library name was changed from `ESP Async WebServer` to `ESPAsyncWebServer` as per the Arduino Lint recommendations. @@ -54,13 +64,33 @@ Dependency: - (perf) Lot of code cleanup and optimizations - (perf) Performance improvements in terms of memory, speed and size -## Original Documentation +## Important recommendations + +Most of the crashes are caused by improper configuration of the library for the project. +Here are some recommendations to avoid them. + +1. Set the running core to be on the same core of your application (usually core 1) `-D CONFIG_ASYNC_TCP_RUNNING_CORE=1` +2. Set the stack size appropriately with `-D CONFIG_ASYNC_TCP_STACK_SIZE=16384`. + The default value of `16384` might be too much for your project. + You can look at the [MycilaTaskMonitor](https://oss.carbou.me/MycilaTaskMonitor) project to monitor the stack usage. +3. You can change **if you know what you are doing** the task priority with `-D CONFIG_ASYNC_TCP_PRIORITY=10`. + Default is `10`. +4. You can increase the queue size with `-D CONFIG_ASYNC_TCP_QUEUE_SIZE=128`. + Default is `64`. +5. You can decrease the maximum ack time `-D CONFIG_ASYNC_TCP_MAX_ACK_TIME=3000`. + Default is `5000`. -Usage and API stays the same as the original library. -Please look at the original libraries for more examples and documentation. +I personally use the following configuration in my projects because my WS messages can be big (up to 4k). +If you have smaller messages, you can increase `WS_MAX_QUEUED_MESSAGES` to 128. -- [https://github.com/me-no-dev/ESPAsyncWebServer](https://github.com/me-no-dev/ESPAsyncWebServer) (original library) -- [https://github.com/yubox-node-org/ESPAsyncWebServer](https://github.com/yubox-node-org/ESPAsyncWebServer) (fork of the original library) +```c++ + -D CONFIG_ASYNC_TCP_MAX_ACK_TIME=3000 + -D CONFIG_ASYNC_TCP_PRIORITY=10 + -D CONFIG_ASYNC_TCP_QUEUE_SIZE=128 + -D CONFIG_ASYNC_TCP_RUNNING_CORE=1 + -D CONFIG_ASYNC_TCP_STACK_SIZE=4096 + -D WS_MAX_QUEUED_MESSAGES=64 +``` ## `AsyncWebSocketMessageBuffer` and `makeBuffer()` @@ -97,35 +127,7 @@ void send(JsonDocument& doc) { I recommend to use the official API `AsyncWebSocketMessageBuffer` to retain further compatibility. -## Important recommendations - -Most of the crashes are caused by improper configuration of the library for the project. -Here are some recommendations to avoid them. - -1. Set the running core to be on the same core of your application (usually core 1) `-D CONFIG_ASYNC_TCP_RUNNING_CORE=1` -2. Set the stack size appropriately with `-D CONFIG_ASYNC_TCP_STACK_SIZE=16384`. - The default value of `16384` might be too much for your project. - You can look at the [MycilaTaskMonitor](https://oss.carbou.me/MycilaTaskMonitor) project to monitor the stack usage. -3. You can change **if you know what you are doing** the task priority with `-D CONFIG_ASYNC_TCP_PRIORITY=10`. - Default is `10`. -4. You can increase the queue size with `-D CONFIG_ASYNC_TCP_QUEUE_SIZE=128`. - Default is `64`. -5. You can decrease the maximum ack time `-D CONFIG_ASYNC_TCP_MAX_ACK_TIME=3000`. - Default is `5000`. - -I personally use the following configuration in my projects because my WS messages can be big (up to 4k). -If you have smaller messages, you can increase `WS_MAX_QUEUED_MESSAGES` to 128. - -```c++ - -D CONFIG_ASYNC_TCP_MAX_ACK_TIME=3000 - -D CONFIG_ASYNC_TCP_PRIORITY=10 - -D CONFIG_ASYNC_TCP_QUEUE_SIZE=128 - -D CONFIG_ASYNC_TCP_RUNNING_CORE=1 - -D CONFIG_ASYNC_TCP_STACK_SIZE=4096 - -D WS_MAX_QUEUED_MESSAGES=64 -``` - -## Replace response +## How to replace a response ```c++ // It is possible to replace a response. @@ -140,7 +142,7 @@ If you have smaller messages, you can increase `WS_MAX_QUEUED_MESSAGES` to 128. This will send error 400 instead of 200. -## Middleware +## How to use Middleware Middleware is a way to intercept requests to perform some operations on them, like authentication, authorization, logging, etc and also act on the response headers. @@ -212,3 +214,1670 @@ myHandler.addMiddleware(&authMiddleware); // add authentication to a specific ha - `ArUploadHandlerFunction` and `ArBodyHandlerFunction` => these callbacks receiving body data and upload and not calling anymore the authentication code for performance reasons. These callbacks can be called multiple times during request parsing, so this is up to the user to now call the `AuthenticationMiddleware.allowed(request)` if needed and ideally when the method is called for the first time. These callbacks are also not triggering the whole middleware chain since they are not part of the request processing workflow (they are not the final handler). + +## Original Documentation + +- [Why should you care](#why-should-you-care) +- [Important things to remember](#important-things-to-remember) +- [Principles of operation](#principles-of-operation) + - [The Async Web server](#the-async-web-server) + - [Request Life Cycle](#request-life-cycle) + - [Rewrites and how do they work](#rewrites-and-how-do-they-work) + - [Handlers and how do they work](#handlers-and-how-do-they-work) + - [Responses and how do they work](#responses-and-how-do-they-work) + - [Template processing](#template-processing) +- [Libraries and projects that use AsyncWebServer](#libraries-and-projects-that-use-asyncwebserver) +- [Request Variables](#request-variables) + - [Common Variables](#common-variables) + - [Headers](#headers) + - [GET, POST and FILE parameters](#get-post-and-file-parameters) + - [FILE Upload handling](#file-upload-handling) + - [Body data handling](#body-data-handling) + - [JSON body handling with ArduinoJson](#json-body-handling-with-arduinojson) +- [Responses](#responses) + - [Redirect to another URL](#redirect-to-another-url) + - [Basic response with HTTP Code](#basic-response-with-http-code) + - [Basic response with HTTP Code and extra headers](#basic-response-with-http-code-and-extra-headers) + - [Basic response with string content](#basic-response-with-string-content) + - [Basic response with string content and extra headers](#basic-response-with-string-content-and-extra-headers) + - [Send large webpage from PROGMEM](#send-large-webpage-from-progmem) + - [Send large webpage from PROGMEM and extra headers](#send-large-webpage-from-progmem-and-extra-headers) + - [Send large webpage from PROGMEM containing templates](#send-large-webpage-from-progmem-containing-templates) + - [Send large webpage from PROGMEM containing templates and extra headers](#send-large-webpage-from-progmem-containing-templates-and-extra-headers) + - [Send binary content from PROGMEM](#send-binary-content-from-progmem) + - [Respond with content coming from a Stream](#respond-with-content-coming-from-a-stream) + - [Respond with content coming from a Stream and extra headers](#respond-with-content-coming-from-a-stream-and-extra-headers) + - [Respond with content coming from a Stream containing templates](#respond-with-content-coming-from-a-stream-containing-templates) + - [Respond with content coming from a Stream containing templates and extra headers](#respond-with-content-coming-from-a-stream-containing-templates-and-extra-headers) + - [Respond with content coming from a File](#respond-with-content-coming-from-a-file) + - [Respond with content coming from a File and extra headers](#respond-with-content-coming-from-a-file-and-extra-headers) + - [Respond with content coming from a File containing templates](#respond-with-content-coming-from-a-file-containing-templates) + - [Respond with content using a callback](#respond-with-content-using-a-callback) + - [Respond with content using a callback and extra headers](#respond-with-content-using-a-callback-and-extra-headers) + - [Respond with file content using a callback and extra headers](#respond-with-file-content-using-a-callback-and-extra-headers) + - [Respond with content using a callback containing templates](#respond-with-content-using-a-callback-containing-templates) + - [Respond with content using a callback containing templates and extra headers](#respond-with-content-using-a-callback-containing-templates-and-extra-headers) + - [Chunked Response](#chunked-response) + - [Chunked Response containing templates](#chunked-response-containing-templates) + - [Print to response](#print-to-response) + - [ArduinoJson Basic Response](#arduinojson-basic-response) + - [ArduinoJson Advanced Response](#arduinojson-advanced-response) +- [Serving static files](#serving-static-files) + - [Serving specific file by name](#serving-specific-file-by-name) + - [Serving files in directory](#serving-files-in-directory) + - [Serving static files with authentication](#serving-static-files-with-authentication) + - [Specifying Cache-Control header](#specifying-cache-control-header) + - [Specifying Date-Modified header](#specifying-date-modified-header) + - [Specifying Template Processor callback](#specifying-template-processor-callback) + - [Serving static files by custom handling](#serving-static-files-by-custom-handling) +- [Param Rewrite With Matching](#param-rewrite-with-matching) +- [Using filters](#using-filters) + - [Serve different site files in AP mode](#serve-different-site-files-in-ap-mode) + - [Rewrite to different index on AP](#rewrite-to-different-index-on-ap) + - [Serving different hosts](#serving-different-hosts) + - [Determine interface inside callbacks](#determine-interface-inside-callbacks) +- [Bad Responses](#bad-responses) + - [Respond with content using a callback without content length to HTTP/1.0 clients](#respond-with-content-using-a-callback-without-content-length-to-http10-clients) +- [Async WebSocket Plugin](#async-websocket-plugin) + - [Async WebSocket Event](#async-websocket-event) + - [Methods for sending data to a socket client](#methods-for-sending-data-to-a-socket-client) + - [Direct access to web socket message buffer](#direct-access-to-web-socket-message-buffer) + - [Limiting the number of web socket clients](#limiting-the-number-of-web-socket-clients) +- [Async Event Source Plugin](#async-event-source-plugin) + - [Setup Event Source on the server](#setup-event-source-on-the-server) + - [Setup Event Source in the browser](#setup-event-source-in-the-browser) +- [Scanning for available WiFi Networks](#scanning-for-available-wifi-networks) +- [Remove handlers and rewrites](#remove-handlers-and-rewrites) +- [Setting up the server](#setting-up-the-server) + - [Setup global and class functions as request handlers](#setup-global-and-class-functions-as-request-handlers) + - [Methods for controlling websocket connections](#methods-for-controlling-websocket-connections) + - [Adding Default Headers](#adding-default-headers) + - [Path variable](#path-variable) + +### Why should you care + +- Using asynchronous network means that you can handle more than one connection at the same time +- You are called once the request is ready and parsed +- When you send the response, you are immediately ready to handle other connections + while the server is taking care of sending the response in the background +- Speed is OMG +- Easy to use API, HTTP Basic and Digest MD5 Authentication (default), ChunkedResponse +- Easily extendible to handle any type of content +- Supports Continue 100 +- Async WebSocket plugin offering different locations without extra servers or ports +- Async EventSource (Server-Sent Events) plugin to send events to the browser +- URL Rewrite plugin for conditional and permanent url rewrites +- ServeStatic plugin that supports cache, Last-Modified, default index and more +- Simple template processing engine to handle templates + +### Important things to remember + +- This is fully asynchronous server and as such does not run on the loop thread. +- You can not use yield or delay or any function that uses them inside the callbacks +- The server is smart enough to know when to close the connection and free resources +- You can not send more than one response to a single request + +### Principles of operation + +#### The Async Web server + +- Listens for connections +- Wraps the new clients into `Request` +- Keeps track of clients and cleans memory +- Manages `Rewrites` and apply them on the request url +- Manages `Handlers` and attaches them to Requests + +#### Request Life Cycle + +- TCP connection is received by the server +- The connection is wrapped inside `Request` object +- When the request head is received (type, url, get params, http version and host), + the server goes through all `Rewrites` (in the order they were added) to rewrite the url and inject query parameters, + next, it goes through all attached `Handlers`(in the order they were added) trying to find one + that `canHandle` the given request. If none are found, the default(catch-all) handler is attached. +- The rest of the request is received, calling the `handleUpload` or `handleBody` methods of the `Handler` if they are needed (POST+File/Body) +- When the whole request is parsed, the result is given to the `handleRequest` method of the `Handler` and is ready to be responded to +- In the `handleRequest` method, to the `Request` is attached a `Response` object (see below) that will serve the response data back to the client +- When the `Response` is sent, the client is closed and freed from the memory + +#### Rewrites and how do they work + +- The `Rewrites` are used to rewrite the request url and/or inject get parameters for a specific request url path. +- All `Rewrites` are evaluated on the request in the order they have been added to the server. +- The `Rewrite` will change the request url only if the request url (excluding get parameters) is fully match + the rewrite url, and when the optional `Filter` callback return true. +- Setting a `Filter` to the `Rewrite` enables to control when to apply the rewrite, decision can be based on + request url, http version, request host/port/target host, get parameters or the request client's localIP or remoteIP. +- Two filter callbacks are provided: `ON_AP_FILTER` to execute the rewrite when request is made to the AP interface, + `ON_STA_FILTER` to execute the rewrite when request is made to the STA interface. +- The `Rewrite` can specify a target url with optional get parameters, e.g. `/to-url?with=params` + +#### Handlers and how do they work + +- The `Handlers` are used for executing specific actions to particular requests +- One `Handler` instance can be attached to any request and lives together with the server +- Setting a `Filter` to the `Handler` enables to control when to apply the handler, decision can be based on + request url, http version, request host/port/target host, get parameters or the request client's localIP or remoteIP. +- Two filter callbacks are provided: `ON_AP_FILTER` to execute the rewrite when request is made to the AP interface, + `ON_STA_FILTER` to execute the rewrite when request is made to the STA interface. +- The `canHandle` method is used for handler specific control on whether the requests can be handled + and for declaring any interesting headers that the `Request` should parse. Decision can be based on request + method, request url, http version, request host/port/target host and get parameters +- Once a `Handler` is attached to given `Request` (`canHandle` returned true) + that `Handler` takes care to receive any file/data upload and attach a `Response` + once the `Request` has been fully parsed +- `Handlers` are evaluated in the order they are attached to the server. The `canHandle` is called only + if the `Filter` that was set to the `Handler` return true. +- The first `Handler` that can handle the request is selected, not further `Filter` and `canHandle` are called. + +#### Responses and how do they work + +- The `Response` objects are used to send the response data back to the client +- The `Response` object lives with the `Request` and is freed on end or disconnect +- Different techniques are used depending on the response type to send the data in packets + returning back almost immediately and sending the next packet when this one is received. + Any time in between is spent to run the user loop and handle other network packets +- Responding asynchronously is probably the most difficult thing for most to understand +- Many different options exist for the user to make responding a background task + +#### Template processing + +- ESPAsyncWebserver contains simple template processing engine. +- Template processing can be added to most response types. +- Currently it supports only replacing template placeholders with actual values. No conditional processing, cycles, etc. +- Placeholders are delimited with `%` symbols. Like this: `%TEMPLATE_PLACEHOLDER%`. +- It works by extracting placeholder name from response text and passing it to user provided function which should return actual value to be used instead of placeholder. +- Since it's user provided function, it is possible for library users to implement conditional processing and cycles themselves. +- Since it's impossible to know the actual response size after template processing step in advance (and, therefore, to include it in response headers), the response becomes [chunked](#chunked-response). + +### Libraries and projects that use AsyncWebServer + +- [WebSocketToSerial](https://github.com/hallard/WebSocketToSerial) - Debug serial devices through the web browser +- [Sattrack](https://github.com/Hopperpop/Sattrack) - Track the ISS with ESP8266 +- [ESP Radio](https://github.com/Edzelf/Esp-radio) - Icecast radio based on ESP8266 and VS1053 +- [VZero](https://github.com/andig/vzero) - the Wireless zero-config controller for volkszaehler.org +- [ESPurna](https://bitbucket.org/xoseperez/espurna) - ESPurna ("spark" in Catalan) is a custom C firmware for ESP8266 based smart switches. It was originally developed with the ITead Sonoff in mind. +- [fauxmoESP](https://bitbucket.org/xoseperez/fauxmoesp) - Belkin WeMo emulator library for ESP8266. +- [ESP-RFID](https://github.com/omersiar/esp-rfid) - MFRC522 RFID Access Control Management project for ESP8266. + +### Request Variables + +#### Common Variables + +```cpp +request->version(); // uint8_t: 0 = HTTP/1.0, 1 = HTTP/1.1 +request->method(); // enum: HTTP_GET, HTTP_POST, HTTP_DELETE, HTTP_PUT, HTTP_PATCH, HTTP_HEAD, HTTP_OPTIONS +request->url(); // String: URL of the request (not including host, port or GET parameters) +request->host(); // String: The requested host (can be used for virtual hosting) +request->contentType(); // String: ContentType of the request (not avaiable in Handler::canHandle) +request->contentLength(); // size_t: ContentLength of the request (not avaiable in Handler::canHandle) +request->multipart(); // bool: True if the request has content type "multipart" +``` + +#### Headers + +```cpp +//List all collected headers +int headers = request->headers(); +int i; +for(i=0;igetHeader(i); + Serial.printf("HEADER[%s]: %s\n", h->name().c_str(), h->value().c_str()); +} + +//get specific header by name +if(request->hasHeader("MyHeader")){ + AsyncWebHeader* h = request->getHeader("MyHeader"); + Serial.printf("MyHeader: %s\n", h->value().c_str()); +} + +//List all collected headers (Compatibility) +int headers = request->headers(); +int i; +for(i=0;iheaderName(i).c_str(), request->header(i).c_str()); +} + +//get specific header by name (Compatibility) +if(request->hasHeader("MyHeader")){ + Serial.printf("MyHeader: %s\n", request->header("MyHeader").c_str()); +} +``` + +#### GET, POST and FILE parameters + +```cpp +//List all parameters +int params = request->params(); +for(int i=0;igetParam(i); + if(p->isFile()){ //p->isPost() is also true + Serial.printf("FILE[%s]: %s, size: %u\n", p->name().c_str(), p->value().c_str(), p->size()); + } else if(p->isPost()){ + Serial.printf("POST[%s]: %s\n", p->name().c_str(), p->value().c_str()); + } else { + Serial.printf("GET[%s]: %s\n", p->name().c_str(), p->value().c_str()); + } +} + +//Check if GET parameter exists +if(request->hasParam("download")) + AsyncWebParameter* p = request->getParam("download"); + +//Check if POST (but not File) parameter exists +if(request->hasParam("download", true)) + AsyncWebParameter* p = request->getParam("download", true); + +//Check if FILE was uploaded +if(request->hasParam("download", true, true)) + AsyncWebParameter* p = request->getParam("download", true, true); + +//List all parameters (Compatibility) +int args = request->args(); +for(int i=0;iargName(i).c_str(), request->arg(i).c_str()); +} + +//Check if parameter exists (Compatibility) +if(request->hasArg("download")) + String arg = request->arg("download"); +``` + +#### FILE Upload handling + +```cpp +void handleUpload(AsyncWebServerRequest *request, String filename, size_t index, uint8_t *data, size_t len, bool final){ + if(!index){ + Serial.printf("UploadStart: %s\n", filename.c_str()); + } + for(size_t i=0; i(); + // ... +}); +server.addHandler(handler); +``` + +### Responses + +#### Redirect to another URL + +```cpp +//to local url +request->redirect("/login"); + +//to external url +request->redirect("http://esp8266.com"); +``` + +#### Basic response with HTTP Code + +```cpp +request->send(404); //Sends 404 File Not Found +``` + +#### Basic response with HTTP Code and extra headers + +```cpp +AsyncWebServerResponse *response = request->beginResponse(404); //Sends 404 File Not Found +response->addHeader("Server","ESP Async Web Server"); +request->send(response); +``` + +#### Basic response with string content + +```cpp +request->send(200, "text/plain", "Hello World!"); +``` + +#### Basic response with string content and extra headers + +```cpp +AsyncWebServerResponse *response = request->beginResponse(200, "text/plain", "Hello World!"); +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 large webpage from PROGMEM containing templates + +```cpp +String processor(const String& var) +{ + if(var == "HELLO_FROM_TEMPLATE") + return F("Hello world!"); + return String(); +} + +// ... + +const char index_html[] PROGMEM = "..."; // large char array, tested with 14k +request->send_P(200, "text/html", index_html, processor); +``` + +#### Send large webpage from PROGMEM containing templates and extra headers + +```cpp +String processor(const String& var) +{ + if(var == "HELLO_FROM_TEMPLATE") + return F("Hello world!"); + return String(); +} + +// ... + +const char index_html[] PROGMEM = "..."; // large char array, tested with 14k +AsyncWebServerResponse *response = request->beginResponse_P(200, "text/html", index_html, processor); +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 +request->send(Serial, "text/plain", 12); +``` + +#### Respond with content coming from a Stream and extra headers + +```cpp +//read 12 bytes from Serial and send them as Content Type text/plain +AsyncWebServerResponse *response = request->beginResponse(Serial, "text/plain", 12); +response->addHeader("Server","ESP Async Web Server"); +request->send(response); +``` + +#### Respond with content coming from a Stream containing templates + +```cpp +String processor(const String& var) +{ + if(var == "HELLO_FROM_TEMPLATE") + return F("Hello world!"); + return String(); +} + +// ... + +//read 12 bytes from Serial and send them as Content Type text/plain +request->send(Serial, "text/plain", 12, processor); +``` + +#### Respond with content coming from a Stream containing templates and extra headers + +```cpp +String processor(const String& var) +{ + if(var == "HELLO_FROM_TEMPLATE") + return F("Hello world!"); + return String(); +} + +// ... + +//read 12 bytes from Serial and send them as Content Type text/plain +AsyncWebServerResponse *response = request->beginResponse(Serial, "text/plain", 12, processor); +response->addHeader("Server","ESP Async Web Server"); +request->send(response); +``` + +#### Respond with content coming from a File + +```cpp +//Send index.htm with default content type +request->send(SPIFFS, "/index.htm"); + +//Send index.htm as text +request->send(SPIFFS, "/index.htm", "text/plain"); + +//Download index.htm +request->send(SPIFFS, "/index.htm", String(), true); +``` + +#### Respond with content coming from a File and extra headers + +```cpp +//Send index.htm with default content type +AsyncWebServerResponse *response = request->beginResponse(SPIFFS, "/index.htm"); + +//Send index.htm as text +AsyncWebServerResponse *response = request->beginResponse(SPIFFS, "/index.htm", "text/plain"); + +//Download index.htm +AsyncWebServerResponse *response = request->beginResponse(SPIFFS, "/index.htm", String(), true); + +response->addHeader("Server","ESP Async Web Server"); +request->send(response); +``` + +#### Respond with content coming from a File containing templates + +Internally uses [Chunked Response](#chunked-response). + +Index.htm contents: + +``` +%HELLO_FROM_TEMPLATE% +``` + +Somewhere in source files: + +```cpp +String processor(const String& var) +{ + if(var == "HELLO_FROM_TEMPLATE") + return F("Hello world!"); + return String(); +} + +// ... + +//Send index.htm with template processor function +request->send(SPIFFS, "/index.htm", String(), false, processor); +``` + +#### Respond with content using a callback + +```cpp +//send 128 bytes as plain text +request->send("text/plain", 128, [](uint8_t *buffer, size_t maxLen, size_t index) -> size_t { + //Write up to "maxLen" bytes into "buffer" and return the amount written. + //index equals the amount of bytes that have been already sent + //You will not be asked for more bytes once the content length has been reached. + //Keep in mind that you can not delay or yield waiting for more data! + //Send what you currently have and you will be asked for more again + return mySource.read(buffer, maxLen); +}); +``` + +#### Respond with content using a callback and extra headers + +```cpp +//send 128 bytes as plain text +AsyncWebServerResponse *response = request->beginResponse("text/plain", 128, [](uint8_t *buffer, size_t maxLen, size_t index) -> size_t { + //Write up to "maxLen" bytes into "buffer" and return the amount written. + //index equals the amount of bytes that have been already sent + //You will not be asked for more bytes once the content length has been reached. + //Keep in mind that you can not delay or yield waiting for more data! + //Send what you currently have and you will be asked for more again + return mySource.read(buffer, maxLen); +}); +response->addHeader("Server","ESP Async Web Server"); +request->send(response); +``` + +#### Respond with file content using a callback and extra headers + +With this code your ESP is able to serve even large (large in terms of ESP, e.g. 100kB) files +without memory problems. + +You need to create a file handler in outer function (to have a single one for request) but use +it in a lambda. The catch is that the lambda has it's own lifecycle which may/will cause it's +called after the original function is over thus the original file handle is destroyed. Using the +captured `&file` in the lambda then causes segfault (Hello, Exception 9!) and the whole ESP crashes. +By using this code, you tell the compiler to move the handle into the lambda so it won't be +destroyed when outer function (that one where you call `request->send(response)`) ends. + +```cpp +const File file = ... // e.g. SPIFFS.open(path, "r"); + +const contentType = "application/javascript"; + +AsyncWebServerResponse *response = request->beginResponse( + contentType, + file.size(), + [file](uint8_t *buffer, size_t maxLen, size_t total) mutable -> size_t { + int bytes = file.read(buffer, maxLen); + + // close file at the end + if (bytes + total == file.size()) file.close(); + + return max(0, bytes); // return 0 even when no bytes were loaded + } +); + +if (gzipped) { + response->addHeader(F("Content-Encoding"), F("gzip")); +} + +request->send(response); +``` + +#### Respond with content using a callback containing templates + +```cpp +String processor(const String& var) +{ + if(var == "HELLO_FROM_TEMPLATE") + return F("Hello world!"); + return String(); +} + +// ... + +//send 128 bytes as plain text +request->send("text/plain", 128, [](uint8_t *buffer, size_t maxLen, size_t index) -> size_t { + //Write up to "maxLen" bytes into "buffer" and return the amount written. + //index equals the amount of bytes that have been already sent + //You will not be asked for more bytes once the content length has been reached. + //Keep in mind that you can not delay or yield waiting for more data! + //Send what you currently have and you will be asked for more again + return mySource.read(buffer, maxLen); +}, processor); +``` + +#### Respond with content using a callback containing templates and extra headers + +```cpp +String processor(const String& var) +{ + if(var == "HELLO_FROM_TEMPLATE") + return F("Hello world!"); + return String(); +} + +// ... + +//send 128 bytes as plain text +AsyncWebServerResponse *response = request->beginResponse("text/plain", 128, [](uint8_t *buffer, size_t maxLen, size_t index) -> size_t { + //Write up to "maxLen" bytes into "buffer" and return the amount written. + //index equals the amount of bytes that have been already sent + //You will not be asked for more bytes once the content length has been reached. + //Keep in mind that you can not delay or yield waiting for more data! + //Send what you currently have and you will be asked for more again + return mySource.read(buffer, maxLen); +}, processor); +response->addHeader("Server","ESP Async Web Server"); +request->send(response); +``` + +#### Chunked Response + +Used when content length is unknown. Works best if the client supports HTTP/1.1 + +```cpp +AsyncWebServerResponse *response = request->beginChunkedResponse("text/plain", [](uint8_t *buffer, size_t maxLen, size_t index) -> size_t { + //Write up to "maxLen" bytes into "buffer" and return the amount written. + //index equals the amount of bytes that have been already sent + //You will be asked for more data until 0 is returned + //Keep in mind that you can not delay or yield waiting for more data! + return mySource.read(buffer, maxLen); +}); +response->addHeader("Server","ESP Async Web Server"); +request->send(response); +``` + +#### Chunked Response containing templates + +Used when content length is unknown. Works best if the client supports HTTP/1.1 + +```cpp +String processor(const String& var) +{ + if(var == "HELLO_FROM_TEMPLATE") + return F("Hello world!"); + return String(); +} + +// ... + +AsyncWebServerResponse *response = request->beginChunkedResponse("text/plain", [](uint8_t *buffer, size_t maxLen, size_t index) -> size_t { + //Write up to "maxLen" bytes into "buffer" and return the amount written. + //index equals the amount of bytes that have been already sent + //You will be asked for more data until 0 is returned + //Keep in mind that you can not delay or yield waiting for more data! + return mySource.read(buffer, maxLen); +}, processor); +response->addHeader("Server","ESP Async Web Server"); +request->send(response); +``` + +#### Print to response + +```cpp +AsyncResponseStream *response = request->beginResponseStream("text/html"); +response->addHeader("Server","ESP Async Web Server"); +response->printf("Webpage at %s", request->url().c_str()); + +response->print("

Hello "); +response->print(request->client()->remoteIP()); +response->print("

"); + +response->print("

General

"); +response->print("
    "); +response->printf("
  • Version: HTTP/1.%u
  • ", request->version()); +response->printf("
  • Method: %s
  • ", request->methodToString()); +response->printf("
  • URL: %s
  • ", request->url().c_str()); +response->printf("
  • Host: %s
  • ", request->host().c_str()); +response->printf("
  • ContentType: %s
  • ", request->contentType().c_str()); +response->printf("
  • ContentLength: %u
  • ", request->contentLength()); +response->printf("
  • Multipart: %s
  • ", request->multipart()?"true":"false"); +response->print("
"); + +response->print("

Headers

"); +response->print("
    "); +int headers = request->headers(); +for(int i=0;igetHeader(i); + response->printf("
  • %s: %s
  • ", h->name().c_str(), h->value().c_str()); +} +response->print("
"); + +response->print("

Parameters

"); +response->print("
    "); +int params = request->params(); +for(int i=0;igetParam(i); + if(p->isFile()){ + response->printf("
  • FILE[%s]: %s, size: %u
  • ", p->name().c_str(), p->value().c_str(), p->size()); + } else if(p->isPost()){ + response->printf("
  • POST[%s]: %s
  • ", p->name().c_str(), p->value().c_str()); + } else { + response->printf("
  • GET[%s]: %s
  • ", p->name().c_str(), p->value().c_str()); + } +} +response->print("
"); + +response->print(""); +//send the response last +request->send(response); +``` + +#### ArduinoJson Basic Response + +This way of sending Json is great for when the result is below 4KB + +```cpp +#include "AsyncJson.h" +#include "ArduinoJson.h" + + +AsyncResponseStream *response = request->beginResponseStream("application/json"); +DynamicJsonBuffer jsonBuffer; +JsonObject &root = jsonBuffer.createObject(); +root["heap"] = ESP.getFreeHeap(); +root["ssid"] = WiFi.SSID(); +root.printTo(*response); +request->send(response); +``` + +#### ArduinoJson Advanced Response + +This response can handle really large Json objects (tested to 40KB) +There isn't any noticeable speed decrease for small results with the method above +Since ArduinoJson does not allow reading parts of the string, the whole Json has to +be passed every time a chunks needs to be sent, which shows speed decrease proportional +to the resulting json packets + +```cpp +#include "AsyncJson.h" +#include "ArduinoJson.h" + + +AsyncJsonResponse * response = new AsyncJsonResponse(); +response->addHeader("Server","ESP Async Web Server"); +JsonObject& root = response->getRoot(); +root["heap"] = ESP.getFreeHeap(); +root["ssid"] = WiFi.SSID(); +response->setLength(); +request->send(response); +``` + +### Serving static files + +In addition to serving files from SPIFFS as described above, the server provide a dedicated handler that optimize the +performance of serving files from SPIFFS - `AsyncStaticWebHandler`. Use `server.serveStatic()` function to +initialize and add a new instance of `AsyncStaticWebHandler` to the server. +The Handler will not handle the request if the file does not exists, e.g. the server will continue to look for another +handler that can handle the request. +Notice that you can chain setter functions to setup the handler, or keep a pointer to change it at a later time. + +#### Serving specific file by name + +```cpp +// Serve the file "/www/page.htm" when request url is "/page.htm" +server.serveStatic("/page.htm", SPIFFS, "/www/page.htm"); +``` + +#### Serving files in directory + +To serve files in a directory, the path to the files should specify a directory in SPIFFS and ends with "/". + +```cpp +// Serve files in directory "/www/" when request url starts with "/" +// Request to the root or none existing files will try to server the defualt +// file name "index.htm" if exists +server.serveStatic("/", SPIFFS, "/www/"); + +// Server with different default file +server.serveStatic("/", SPIFFS, "/www/").setDefaultFile("default.html"); +``` + +#### Serving static files with authentication + +```cpp +server + .serveStatic("/", SPIFFS, "/www/") + .setDefaultFile("default.html") + .setAuthentication("user", "pass"); +``` + +#### Specifying Cache-Control header + +It is possible to specify Cache-Control header value to reduce the number of calls to the server once the client loaded +the files. For more information on Cache-Control values see [Cache-Control](https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9) + +```cpp +// Cache responses for 10 minutes (600 seconds) +server.serveStatic("/", SPIFFS, "/www/").setCacheControl("max-age=600"); + +//*** Change Cache-Control after server setup *** + +// During setup - keep a pointer to the handler +AsyncStaticWebHandler* handler = &server.serveStatic("/", SPIFFS, "/www/").setCacheControl("max-age=600"); + +// At a later event - change Cache-Control +handler->setCacheControl("max-age=30"); +``` + +#### Specifying Date-Modified header + +It is possible to specify Date-Modified header to enable the server to return Not-Modified (304) response for requests +with "If-Modified-Since" header with the same value, instead of responding with the actual file content. + +```cpp +// Update the date modified string every time files are updated +server.serveStatic("/", SPIFFS, "/www/").setLastModified("Mon, 20 Jun 2016 14:00:00 GMT"); + +//*** Chage last modified value at a later stage *** + +// During setup - read last modified value from config or EEPROM +String date_modified = loadDateModified(); +AsyncStaticWebHandler* handler = &server.serveStatic("/", SPIFFS, "/www/"); +handler->setLastModified(date_modified); + +// At a later event when files are updated +String date_modified = getNewDateModfied(); +saveDateModified(date_modified); // Save for next reset +handler->setLastModified(date_modified); +``` + +#### Specifying Template Processor callback + +It is possible to specify template processor for static files. For information on template processor see +[Respond with content coming from a File containing templates](#respond-with-content-coming-from-a-file-containing-templates). + +```cpp +String processor(const String& var) +{ + if(var == "HELLO_FROM_TEMPLATE") + return F("Hello world!"); + return String(); +} + +// ... + +server.serveStatic("/", SPIFFS, "/www/").setTemplateProcessor(processor); +``` + +#### Serving static files by custom handling + +It may happen your static files are too big and the ESP will crash the request before it sends the whole file. +In that case, you can handle static files with custom file serving through not found handler. + +This code below is more-or-less equivalent to this: + +```cpp +webServer.serveStatic("/", SPIFFS, STATIC_FILES_PREFIX).setDefaultFile("index.html") +``` + +First, declare the handling function: + +```cpp +bool handleStaticFile(AsyncWebServerRequest *request) { + String path = STATIC_FILES_PREFIX + request->url(); + + if (path.endsWith("/")) path += F("index.html"); + + String contentType = getContentType(path); + String pathWithGz = path + ".gz"; + + if (SPIFFS.exists(pathWithGz) || SPIFFS.exists(path)) { + bool gzipped = false; + if (SPIFFS.exists(pathWithGz)) { + gzipped = true; + path += ".gz"; + } + + // TODO serve the file + + return true; + } + + return false; +} +``` + +And then configure your webserver: + +```cpp +webServer.onNotFound([](AsyncWebServerRequest *request) { + if (handleStaticFile(request)) return; + + request->send(404); +}); +``` + +You may want to try [Respond with file content using a callback and extra headers](#respond-with-file-content-using-a-callback-and-extra-headers) +For actual serving the file. + +### Param Rewrite With Matching + +It is possible to rewrite the request url with parameter matchg. Here is an example with one parameter: +Rewrite for example "/radio/{frequence}" -> "/radio?f={frequence}" + +```cpp +class OneParamRewrite : public AsyncWebRewrite +{ + protected: + String _urlPrefix; + int _paramIndex; + String _paramsBackup; + + public: + OneParamRewrite(const char* from, const char* to) + : AsyncWebRewrite(from, to) { + + _paramIndex = _from.indexOf('{'); + + if( _paramIndex >=0 && _from.endsWith("}")) { + _urlPrefix = _from.substring(0, _paramIndex); + int index = _params.indexOf('{'); + if(index >= 0) { + _params = _params.substring(0, index); + } + } else { + _urlPrefix = _from; + } + _paramsBackup = _params; + } + + bool match(AsyncWebServerRequest *request) override { + if(request->url().startsWith(_urlPrefix)) { + if(_paramIndex >= 0) { + _params = _paramsBackup + request->url().substring(_paramIndex); + } else { + _params = _paramsBackup; + } + return true; + + } else { + return false; + } + } +}; +``` + +Usage: + +```cpp + server.addRewrite( new OneParamRewrite("/radio/{frequence}", "/radio?f={frequence}") ); +``` + +### Using filters + +Filters can be set to `Rewrite` or `Handler` in order to control when to apply the rewrite and consider the handler. +A filter is a callback function that evaluates the request and return a boolean `true` to include the item +or `false` to exclude it. +Two filter callback are provided for convince: + +- `ON_STA_FILTER` - return true when requests are made to the STA (station mode) interface. +- `ON_AP_FILTER` - return true when requests are made to the AP (access point) interface. + +#### Serve different site files in AP mode + +```cpp +server.serveStatic("/", SPIFFS, "/www/").setFilter(ON_STA_FILTER); +server.serveStatic("/", SPIFFS, "/ap/").setFilter(ON_AP_FILTER); +``` + +#### Rewrite to different index on AP + +```cpp +// Serve the file "/www/index-ap.htm" in AP, and the file "/www/index.htm" on STA +server.rewrite("/", "index.htm"); +server.rewrite("/index.htm", "index-ap.htm").setFilter(ON_AP_FILTER); +server.serveStatic("/", SPIFFS, "/www/"); +``` + +#### Serving different hosts + +```cpp +// Filter callback using request host +bool filterOnHost1(AsyncWebServerRequest *request) { return request->host() == "host1"; } + +// Server setup: server files in "/host1/" to requests for "host1", and files in "/www/" otherwise. +server.serveStatic("/", SPIFFS, "/host1/").setFilter(filterOnHost1); +server.serveStatic("/", SPIFFS, "/www/"); +``` + +#### Determine interface inside callbacks + +```cpp + String RedirectUrl = "http://"; + if (ON_STA_FILTER(request)) { + RedirectUrl += WiFi.localIP().toString(); + } else { + RedirectUrl += WiFi.softAPIP().toString(); + } + RedirectUrl += "/index.htm"; + request->redirect(RedirectUrl); +``` + +### Bad Responses + +Some responses are implemented, but you should not use them, because they do not conform to HTTP. +The following example will lead to unclean close of the connection and more time wasted +than providing the length of the content + +#### Respond with content using a callback without content length to HTTP/1.0 clients + +```cpp +//This is used as fallback for chunked responses to HTTP/1.0 Clients +request->send("text/plain", 0, [](uint8_t *buffer, size_t maxLen, size_t index) -> size_t { + //Write up to "maxLen" bytes into "buffer" and return the amount written. + //You will be asked for more data until 0 is returned + //Keep in mind that you can not delay or yield waiting for more data! + return mySource.read(buffer, maxLen); +}); +``` + +### Async WebSocket Plugin + +The server includes a web socket plugin which lets you define different WebSocket locations to connect to +without starting another listening service or using different port + +#### Async WebSocket Event + +```cpp + +void onEvent(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventType type, void * arg, uint8_t *data, size_t len){ + if(type == WS_EVT_CONNECT){ + //client connected + os_printf("ws[%s][%u] connect\n", server->url(), client->id()); + client->printf("Hello Client %u :)", client->id()); + client->ping(); + } else if(type == WS_EVT_DISCONNECT){ + //client disconnected + os_printf("ws[%s][%u] disconnect: %u\n", server->url(), client->id()); + } else if(type == WS_EVT_ERROR){ + //error was received from the other end + os_printf("ws[%s][%u] error(%u): %s\n", server->url(), client->id(), *((uint16_t*)arg), (char*)data); + } else if(type == WS_EVT_PONG){ + //pong message was received (in response to a ping request maybe) + os_printf("ws[%s][%u] pong[%u]: %s\n", server->url(), client->id(), len, (len)?(char*)data:""); + } else if(type == WS_EVT_DATA){ + //data packet + AwsFrameInfo * info = (AwsFrameInfo*)arg; + if(info->final && info->index == 0 && info->len == len){ + //the whole message is in a single frame and we got all of it's data + os_printf("ws[%s][%u] %s-message[%llu]: ", server->url(), client->id(), (info->opcode == WS_TEXT)?"text":"binary", info->len); + if(info->opcode == WS_TEXT){ + data[len] = 0; + os_printf("%s\n", (char*)data); + } else { + for(size_t i=0; i < info->len; i++){ + os_printf("%02x ", data[i]); + } + os_printf("\n"); + } + if(info->opcode == WS_TEXT) + client->text("I got your text message"); + else + client->binary("I got your binary message"); + } else { + //message is comprised of multiple frames or the frame is split into multiple packets + if(info->index == 0){ + if(info->num == 0) + os_printf("ws[%s][%u] %s-message start\n", server->url(), client->id(), (info->message_opcode == WS_TEXT)?"text":"binary"); + os_printf("ws[%s][%u] frame[%u] start[%llu]\n", server->url(), client->id(), info->num, info->len); + } + + 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->message_opcode == WS_TEXT){ + data[len] = 0; + os_printf("%s\n", (char*)data); + } else { + for(size_t i=0; i < len; i++){ + os_printf("%02x ", data[i]); + } + os_printf("\n"); + } + + if((info->index + len) == info->len){ + os_printf("ws[%s][%u] frame[%u] end[%llu]\n", server->url(), client->id(), info->num, info->len); + if(info->final){ + os_printf("ws[%s][%u] %s-message end\n", server->url(), client->id(), (info->message_opcode == WS_TEXT)?"text":"binary"); + if(info->message_opcode == WS_TEXT) + client->text("I got your text message"); + else + client->binary("I got your binary message"); + } + } + } + } +} +``` + +#### Methods for sending data to a socket client + +```cpp + + + +//Server methods +AsyncWebSocket ws("/ws"); +//printf to a client +ws.printf((uint32_t)client_id, arguments...); +//printf to all clients +ws.printfAll(arguments...); +//printf_P to a client +ws.printf_P((uint32_t)client_id, PSTR(format), arguments...); +//printfAll_P to all clients +ws.printfAll_P(PSTR(format), arguments...); +//send text to a client +ws.text((uint32_t)client_id, (char*)text); +ws.text((uint32_t)client_id, (uint8_t*)text, (size_t)len); +//send text from PROGMEM to a client +ws.text((uint32_t)client_id, PSTR("text")); +const char flash_text[] PROGMEM = "Text to send" +ws.text((uint32_t)client_id, FPSTR(flash_text)); +//send text to all clients +ws.textAll((char*)text); +ws.textAll((uint8_t*)text, (size_t)len); +//send binary to a client +ws.binary((uint32_t)client_id, (char*)binary); +ws.binary((uint32_t)client_id, (uint8_t*)binary, (size_t)len); +//send binary from PROGMEM to a client +const uint8_t flash_binary[] PROGMEM = { 0x01, 0x02, 0x03, 0x04 }; +ws.binary((uint32_t)client_id, flash_binary, 4); +//send binary to all clients +ws.binaryAll((char*)binary); +ws.binaryAll((uint8_t*)binary, (size_t)len); +//HTTP Authenticate before switch to Websocket protocol +ws.setAuthentication("user", "pass"); + +//client methods +AsyncWebSocketClient * client; +//printf +client->printf(arguments...); +//printf_P +client->printf_P(PSTR(format), arguments...); +//send text +client->text((char*)text); +client->text((uint8_t*)text, (size_t)len); +//send text from PROGMEM +client->text(PSTR("text")); +const char flash_text[] PROGMEM = "Text to send"; +client->text(FPSTR(flash_text)); +//send binary +client->binary((char*)binary); +client->binary((uint8_t*)binary, (size_t)len); +//send binary from PROGMEM +const uint8_t flash_binary[] PROGMEM = { 0x01, 0x02, 0x03, 0x04 }; +client->binary(flash_binary, 4); +``` + +#### Direct access to web socket message buffer + +When sending a web socket message using the above methods a buffer is created. Under certain circumstances you might want to manipulate or populate this buffer directly from your application, for example to prevent unnecessary duplications of the data. This example below shows how to create a buffer and print data to it from an ArduinoJson object then send it. + +```cpp +void sendDataWs(AsyncWebSocketClient * client) +{ + DynamicJsonBuffer jsonBuffer; + JsonObject& root = jsonBuffer.createObject(); + root["a"] = "abc"; + root["b"] = "abcd"; + root["c"] = "abcde"; + root["d"] = "abcdef"; + root["e"] = "abcdefg"; + size_t len = root.measureLength(); + AsyncWebSocketMessageBuffer * buffer = ws.makeBuffer(len); // creates a buffer (len + 1) for you. + if (buffer) { + root.printTo((char *)buffer->get(), len + 1); + if (client) { + client->text(buffer); + } else { + ws.textAll(buffer); + } + } +} +``` + +#### Limiting the number of web socket clients + +Browsers sometimes do not correctly close the websocket connection, even when the close() function is called in javascript. This will eventually exhaust the web server's resources and will cause the server to crash. Periodically calling the cleanClients() function from the main loop() function limits the number of clients by closing the oldest client when the maximum number of clients has been exceeded. This can called be every cycle, however, if you wish to use less power, then calling as infrequently as once per second is sufficient. + +```cpp +void loop(){ + ws.cleanupClients(); +} +``` + +### Async Event Source Plugin + +The server includes EventSource (Server-Sent Events) plugin which can be used to send short text events to the browser. +Difference between EventSource and WebSockets is that EventSource is single direction, text-only protocol. + +#### Setup Event Source on the server + +```cpp +AsyncWebServer server(80); +AsyncEventSource events("/events"); + +void setup(){ + // setup ...... + events.onConnect([](AsyncEventSourceClient *client){ + if(client->lastId()){ + Serial.printf("Client reconnected! Last message ID that it gat is: %u\n", client->lastId()); + } + //send event with message "hello!", id current millis + // and set reconnect delay to 1 second + client->send("hello!",NULL,millis(),1000); + }); + //HTTP Basic authentication + events.setAuthentication("user", "pass"); + server.addHandler(&events); + // setup ...... +} + +void loop(){ + if(eventTriggered){ // your logic here + //send event "myevent" + events.send("my event content","myevent",millis()); + } +} +``` + +#### Setup Event Source in the browser + +```javascript +if (!!window.EventSource) { + var source = new EventSource("/events"); + + source.addEventListener( + "open", + function (e) { + console.log("Events Connected"); + }, + false + ); + + source.addEventListener( + "error", + function (e) { + if (e.target.readyState != EventSource.OPEN) { + console.log("Events Disconnected"); + } + }, + false + ); + + source.addEventListener( + "message", + function (e) { + console.log("message", e.data); + }, + false + ); + + source.addEventListener( + "myevent", + function (e) { + console.log("myevent", e.data); + }, + false + ); +} +``` + +### Scanning for available WiFi Networks + +```cpp +//First request will return 0 results unless you start scan from somewhere else (loop/setup) +//Do not request more often than 3-5 seconds +server.on("/scan", HTTP_GET, [](AsyncWebServerRequest *request){ + String json = "["; + int n = WiFi.scanComplete(); + if(n == -2){ + WiFi.scanNetworks(true); + } else if(n){ + for (int i = 0; i < n; ++i){ + if(i) json += ","; + json += "{"; + json += "\"rssi\":"+String(WiFi.RSSI(i)); + json += ",\"ssid\":\""+WiFi.SSID(i)+"\""; + json += ",\"bssid\":\""+WiFi.BSSIDstr(i)+"\""; + json += ",\"channel\":"+String(WiFi.channel(i)); + json += ",\"secure\":"+String(WiFi.encryptionType(i)); + json += ",\"hidden\":"+String(WiFi.isHidden(i)?"true":"false"); + json += "}"; + } + WiFi.scanDelete(); + if(WiFi.scanComplete() == -2){ + WiFi.scanNetworks(true); + } + } + json += "]"; + request->send(200, "application/json", json); + json = String(); +}); +``` + +### Remove handlers and rewrites + +Server goes through handlers in same order as they were added. You can't simple add handler with same path to override them. +To remove handler: + +```arduino +// save callback for particular URL path +auto handler = server.on("/some/path", [](AsyncWebServerRequest *request){ + //do something useful +}); +// when you don't need handler anymore remove it +server.removeHandler(&handler); + +// same with rewrites +server.removeRewrite(&someRewrite); + +server.onNotFound([](AsyncWebServerRequest *request){ + request->send(404); +}); + +// remove server.onNotFound handler +server.onNotFound(NULL); + +// remove all rewrites, handlers and onNotFound/onFileUpload/onRequestBody callbacks +server.reset(); +``` + +### Setting up the server + +```cpp +#include "ESPAsyncTCP.h" +#include "ESPAsyncWebServer.h" + +AsyncWebServer server(80); +AsyncWebSocket ws("/ws"); // access at ws://[esp ip]/ws +AsyncEventSource events("/events"); // event source (Server-Sent events) + +const char* ssid = "your-ssid"; +const char* password = "your-pass"; +const char* http_username = "admin"; +const char* http_password = "admin"; + +//flag to use from web update to reboot the ESP +bool shouldReboot = false; + +void onRequest(AsyncWebServerRequest *request){ + //Handle Unknown Request + request->send(404); +} + +void onBody(AsyncWebServerRequest *request, uint8_t *data, size_t len, size_t index, size_t total){ + //Handle body +} + +void onUpload(AsyncWebServerRequest *request, String filename, size_t index, uint8_t *data, size_t len, bool final){ + //Handle upload +} + +void onEvent(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventType type, void * arg, uint8_t *data, size_t len){ + //Handle WebSocket event +} + +void setup(){ + Serial.begin(115200); + WiFi.mode(WIFI_STA); + WiFi.begin(ssid, password); + if (WiFi.waitForConnectResult() != WL_CONNECTED) { + Serial.printf("WiFi Failed!\n"); + return; + } + + // attach AsyncWebSocket + ws.onEvent(onEvent); + server.addHandler(&ws); + + // attach AsyncEventSource + server.addHandler(&events); + + // respond to GET requests on URL /heap + server.on("/heap", HTTP_GET, [](AsyncWebServerRequest *request){ + request->send(200, "text/plain", String(ESP.getFreeHeap())); + }); + + // upload a file to /upload + server.on("/upload", HTTP_POST, [](AsyncWebServerRequest *request){ + request->send(200); + }, onUpload); + + // send a file when /index is requested + server.on("/index", HTTP_ANY, [](AsyncWebServerRequest *request){ + request->send(SPIFFS, "/index.htm"); + }); + + // HTTP basic authentication + server.on("/login", HTTP_GET, [](AsyncWebServerRequest *request){ + if(!request->authenticate(http_username, http_password)) + return request->requestAuthentication(); + request->send(200, "text/plain", "Login Success!"); + }); + + // Simple Firmware Update Form + server.on("/update", HTTP_GET, [](AsyncWebServerRequest *request){ + request->send(200, "text/html", "
"); + }); + server.on("/update", HTTP_POST, [](AsyncWebServerRequest *request){ + shouldReboot = !Update.hasError(); + AsyncWebServerResponse *response = request->beginResponse(200, "text/plain", shouldReboot?"OK":"FAIL"); + response->addHeader("Connection", "close"); + request->send(response); + },[](AsyncWebServerRequest *request, String filename, size_t index, uint8_t *data, size_t len, bool final){ + if(!index){ + Serial.printf("Update Start: %s\n", filename.c_str()); + Update.runAsync(true); + if(!Update.begin((ESP.getFreeSketchSpace() - 0x1000) & 0xFFFFF000)){ + Update.printError(Serial); + } + } + if(!Update.hasError()){ + if(Update.write(data, len) != len){ + Update.printError(Serial); + } + } + if(final){ + if(Update.end(true)){ + Serial.printf("Update Success: %uB\n", index+len); + } else { + Update.printError(Serial); + } + } + }); + + // attach filesystem root at URL /fs + server.serveStatic("/fs", SPIFFS, "/"); + + // Catch-All Handlers + // Any request that can not find a Handler that canHandle it + // ends in the callbacks below. + server.onNotFound(onRequest); + server.onFileUpload(onUpload); + server.onRequestBody(onBody); + + server.begin(); +} + +void loop(){ + if(shouldReboot){ + Serial.println("Rebooting..."); + delay(100); + ESP.restart(); + } + static char temp[128]; + sprintf(temp, "Seconds since boot: %u", millis()/1000); + events.send(temp, "time"); //send event "time" +} +``` + +#### Setup global and class functions as request handlers + +```cpp +#include +#include +#include +#include + +void handleRequest(AsyncWebServerRequest *request){} + +class WebClass { +public : + AsyncWebServer classWebServer = AsyncWebServer(81); + + WebClass(){}; + + void classRequest (AsyncWebServerRequest *request){} + + void begin(){ + // attach global request handler + classWebServer.on("/example", HTTP_ANY, handleRequest); + + // attach class request handler + classWebServer.on("/example", HTTP_ANY, std::bind(&WebClass::classRequest, this, std::placeholders::_1)); + } +}; + +AsyncWebServer globalWebServer(80); +WebClass webClassInstance; + +void setup() { + // attach global request handler + globalWebServer.on("/example", HTTP_ANY, handleRequest); + + // attach class request handler + globalWebServer.on("/example", HTTP_ANY, std::bind(&WebClass::classRequest, webClassInstance, std::placeholders::_1)); +} + +void loop() { + +} +``` + +#### Methods for controlling websocket connections + +```cpp + // Disable client connections if it was activated + if ( ws.enabled() ) + ws.enable(false); + + // enable client connections if it was disabled + if ( !ws.enabled() ) + ws.enable(true); +``` + +Example of OTA code + +```cpp + // OTA callbacks + ArduinoOTA.onStart([]() { + // Clean SPIFFS + SPIFFS.end(); + + // Disable client connections + ws.enable(false); + + // Advertise connected clients what's going on + ws.textAll("OTA Update Started"); + + // Close them + ws.closeAll(); + + }); + +``` + +#### Adding Default Headers + +In some cases, such as when working with CORS, or with some sort of custom authentication system, +you might need to define a header that should get added to all responses (including static, websocket and EventSource). +The DefaultHeaders singleton allows you to do this. + +Example: + +```cpp +DefaultHeaders::Instance().addHeader("Access-Control-Allow-Origin", "*"); +webServer.begin(); +``` + +_NOTE_: You will still need to respond to the OPTIONS method for CORS pre-flight in most cases. (unless you are only using GET) + +This is one option: + +```cpp +webServer.onNotFound([](AsyncWebServerRequest *request) { + if (request->method() == HTTP_OPTIONS) { + request->send(200); + } else { + request->send(404); + } +}); +``` + +#### Path variable + +With path variable you can create a custom regex rule for a specific parameter in a route. +For example we want a `sensorId` parameter in a route rule to match only a integer. + +```cpp + server.on("^\\/sensor\\/([0-9]+)$", HTTP_GET, [] (AsyncWebServerRequest *request) { + String sensorId = request->pathArg(0); + }); +``` + +_NOTE_: All regex patterns starts with `^` and ends with `$` + +To enable the `Path variable` support, you have to define the buildflag `-DASYNCWEBSERVER_REGEX`. + +For Arduino IDE create/update `platform.local.txt`: + +`Windows`: C:\Users\(username)\AppData\Local\Arduino15\packages\\`{espxxxx}`\hardware\\`espxxxx`\\`{version}`\platform.local.txt + +`Linux`: ~/.arduino15/packages/`{espxxxx}`/hardware/`{espxxxx}`/`{version}`/platform.local.txt + +Add/Update the following line: + +``` + compiler.cpp.extra_flags=-DDASYNCWEBSERVER_REGEX +``` + +For platformio modify `platformio.ini`: + +```ini +[env:myboard] +build_flags = + -DASYNCWEBSERVER_REGEX +``` + +_NOTE_: By enabling `ASYNCWEBSERVER_REGEX`, `` will be included. This will add an 100k to your binary. From e61280367306d6235255072c577774b10c62d69c Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Wed, 18 Sep 2024 11:15:50 +0200 Subject: [PATCH 382/551] bblanchon/ArduinoJson @ 7.2.0 --- platformio.ini | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/platformio.ini b/platformio.ini index c9515aeb3..70c0d87e6 100644 --- a/platformio.ini +++ b/platformio.ini @@ -24,7 +24,7 @@ upload_protocol = esptool monitor_speed = 115200 monitor_filters = esp32_exception_decoder, log2file lib_deps = - bblanchon/ArduinoJson @ 7.1.0 + bblanchon/ArduinoJson @ 7.2.0 mathieucarbou/AsyncTCP @ 3.2.5 board = esp32dev @@ -46,7 +46,7 @@ platform = espressif8266 board = huzzah ; board = d1_mini lib_deps = - bblanchon/ArduinoJson @ 7.1.0 + bblanchon/ArduinoJson @ 7.2.0 esphome/ESPAsyncTCP-esphome @ 2.0.0 ; PlatformIO support for Raspberry Pi Pico is not official @@ -59,7 +59,7 @@ upload_protocol = picotool platform = https://github.com/maxgerhardt/platform-raspberrypi.git board = rpipicow lib_deps = - bblanchon/ArduinoJson @ 7.1.0 + bblanchon/ArduinoJson @ 7.2.0 khoih-prog/AsyncTCP_RP2040W @ 1.2.0 ; CI @@ -80,7 +80,7 @@ board = ${sysenv.PIO_BOARD} platform = espressif8266 board = ${sysenv.PIO_BOARD} lib_deps = - bblanchon/ArduinoJson @ 7.1.0 + bblanchon/ArduinoJson @ 7.2.0 esphome/ESPAsyncTCP-esphome @ 2.0.0 [env:ci-raspberrypi] @@ -88,5 +88,5 @@ lib_deps = platform = https://github.com/maxgerhardt/platform-raspberrypi.git board = ${sysenv.PIO_BOARD} lib_deps = - bblanchon/ArduinoJson @ 7.1.0 + bblanchon/ArduinoJson @ 7.2.0 khoih-prog/AsyncTCP_RP2040W @ 1.2.0 From eacf0eb47435c538d5ffdf87c3b499ef26a02a55 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Wed, 18 Sep 2024 15:45:20 +0200 Subject: [PATCH 383/551] Arduino Release v3.0.5 based on ESP-IDF v5.1.4+ --- platformio.ini | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platformio.ini b/platformio.ini index 70c0d87e6..9752ef63c 100644 --- a/platformio.ini +++ b/platformio.ini @@ -32,7 +32,7 @@ board = esp32dev platform = espressif32@6.8.1 [env:arduino-3] -platform = https://github.com/pioarduino/platform-espressif32/releases/download/51.03.04/platform-espressif32.zip +platform = https://github.com/pioarduino/platform-espressif32/releases/download/51.03.05/platform-espressif32.zip ; board = esp32-s3-devkitc-1 ; board = esp32-c6-devkitc-1 @@ -69,7 +69,7 @@ platform = espressif32@6.8.1 board = ${sysenv.PIO_BOARD} [env:ci-arduino-3] -platform = https://github.com/pioarduino/platform-espressif32/releases/download/51.03.04/platform-espressif32.zip +platform = https://github.com/pioarduino/platform-espressif32/releases/download/51.03.05/platform-espressif32.zip board = ${sysenv.PIO_BOARD} [env:ci-arduino-310rc1] From 2e65ee60df093dad4caf2c05c93ae4f897e19b9d Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Wed, 25 Sep 2024 01:33:22 +0200 Subject: [PATCH 384/551] Fix CORS Middleware --- src/ESPAsyncWebServer.h | 2 ++ src/Middlewares.cpp | 34 ++++++++++++++++++++++++++-------- 2 files changed, 28 insertions(+), 8 deletions(-) diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index 311680db9..8922ea712 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -745,6 +745,8 @@ class CorsMiddleware : public AsyncMiddleware { void setAllowCredentials(bool credentials) { _credentials = credentials; } void setMaxAge(uint32_t seconds) { _maxAge = seconds; } + void addCORSHeaders(AsyncWebServerResponse* response); + void run(AsyncWebServerRequest* request, ArMiddlewareNext next); private: diff --git a/src/Middlewares.cpp b/src/Middlewares.cpp index 6f8dc2c61..1f0252a94 100644 --- a/src/Middlewares.cpp +++ b/src/Middlewares.cpp @@ -58,16 +58,34 @@ void LoggingMiddleware::run(AsyncWebServerRequest* request, ArMiddlewareNext nex } } +void CorsMiddleware::addCORSHeaders(AsyncWebServerResponse* response) { + response->addHeader(F("Access-Control-Allow-Origin"), _origin.c_str()); + response->addHeader(F("Access-Control-Allow-Methods"), _methods.c_str()); + response->addHeader(F("Access-Control-Allow-Headers"), _headers.c_str()); + response->addHeader(F("Access-Control-Allow-Credentials"), _credentials ? F("true") : F("false")); + response->addHeader(F("Access-Control-Max-Age"), String(_maxAge).c_str()); +} + void CorsMiddleware::run(AsyncWebServerRequest* request, ArMiddlewareNext next) { - if (request->method() == HTTP_OPTIONS && request->hasHeader(F("Origin"))) { - AsyncWebServerResponse* response = request->beginResponse(200); - response->addHeader(F("Access-Control-Allow-Origin"), _origin.c_str()); - response->addHeader(F("Access-Control-Allow-Methods"), _methods.c_str()); - response->addHeader(F("Access-Control-Allow-Headers"), _headers.c_str()); - response->addHeader(F("Access-Control-Allow-Credentials"), _credentials ? F("true") : F("false")); - response->addHeader(F("Access-Control-Max-Age"), String(_maxAge).c_str()); - request->send(response); + // Origin header ? => CORS handling + if (request->hasHeader(F("Origin"))) { + // check if this is a preflight request => handle it and return + if (request->method() == HTTP_OPTIONS) { + AsyncWebServerResponse* response = request->beginResponse(200); + addCORSHeaders(response); + request->send(response); + return; + } + + // CORS request, no options => let the request pass and add CORS headers after + next(); + AsyncWebServerResponse* response = request->getResponse(); + if (response) { + addCORSHeaders(response); + } + } else { + // NO Origin header => no CORS handling next(); } } From 546f9ed1c4d89065661a2aeb0e98b6195f91b84a Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Thu, 26 Sep 2024 14:53:44 +0200 Subject: [PATCH 385/551] espressif32@6.9.0 --- platformio.ini | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platformio.ini b/platformio.ini index 9752ef63c..d2632763d 100644 --- a/platformio.ini +++ b/platformio.ini @@ -29,7 +29,7 @@ lib_deps = board = esp32dev [env:arduino-2] -platform = espressif32@6.8.1 +platform = espressif32@6.9.0 [env:arduino-3] platform = https://github.com/pioarduino/platform-espressif32/releases/download/51.03.05/platform-espressif32.zip @@ -65,7 +65,7 @@ lib_deps = ; CI [env:ci-arduino-2] -platform = espressif32@6.8.1 +platform = espressif32@6.9.0 board = ${sysenv.PIO_BOARD} [env:ci-arduino-3] From b473625d1d20523d6c35293450d93ab9cccc7656 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Sun, 29 Sep 2024 21:29:59 +0200 Subject: [PATCH 386/551] Moved implementations in cpp files --- platformio.ini | 4 + src/AsyncEventSource.cpp | 7 +- src/AsyncEventSource.h | 6 +- src/AsyncJson.cpp | 151 ++++++++++++++++++ src/AsyncJson.h | 160 ++------------------ src/AsyncMessagePack.cpp | 79 ++++++++++ src/AsyncMessagePack.h | 88 +---------- src/AsyncWebHeader.cpp | 22 +++ src/AsyncWebSocket.h | 13 +- src/ChunkPrint.cpp | 16 ++ src/ChunkPrint.h | 19 +-- src/ESPAsyncWebServer.h | 193 ++++-------------------- src/{Middlewares.cpp => Middleware.cpp} | 96 +++++++++++- src/WebHandlerImpl.h | 68 +-------- src/WebHandlers.cpp | 77 ++++++++++ src/WebRequest.cpp | 37 +++++ 16 files changed, 553 insertions(+), 483 deletions(-) create mode 100644 src/AsyncJson.cpp create mode 100644 src/AsyncMessagePack.cpp create mode 100644 src/AsyncWebHeader.cpp create mode 100644 src/ChunkPrint.cpp rename src/{Middlewares.cpp => Middleware.cpp} (52%) diff --git a/platformio.ini b/platformio.ini index d2632763d..661e4a645 100644 --- a/platformio.ini +++ b/platformio.ini @@ -61,6 +61,8 @@ board = rpipicow lib_deps = bblanchon/ArduinoJson @ 7.2.0 khoih-prog/AsyncTCP_RP2040W @ 1.2.0 +build_flags = ${env.build_flags} + -Wno-missing-field-initializers ; CI @@ -90,3 +92,5 @@ board = ${sysenv.PIO_BOARD} lib_deps = bblanchon/ArduinoJson @ 7.2.0 khoih-prog/AsyncTCP_RP2040W @ 1.2.0 +build_flags = ${env.build_flags} + -Wno-missing-field-initializers diff --git a/src/AsyncEventSource.cpp b/src/AsyncEventSource.cpp index 09839f47e..2d6ab7b1b 100644 --- a/src/AsyncEventSource.cpp +++ b/src/AsyncEventSource.cpp @@ -22,7 +22,6 @@ #include #endif #include "AsyncEventSource.h" -#include "literals.h" using namespace asyncsrv; @@ -288,6 +287,12 @@ void AsyncEventSource::onConnect(ArEventHandlerFunction cb) { _connectcb = cb; } +void AsyncEventSource::authorizeConnect(ArAuthorizeConnectHandler cb) { + AuthorizationMiddleware* m = new AuthorizationMiddleware(401, cb); + m->_freeOnRemoval = true; + addMiddleware(m); +} + void AsyncEventSource::_addClient(AsyncEventSourceClient* client) { if (!client) return; diff --git a/src/AsyncEventSource.h b/src/AsyncEventSource.h index 302f869a7..1c688b0c6 100644 --- a/src/AsyncEventSource.h +++ b/src/AsyncEventSource.h @@ -124,11 +124,7 @@ class AsyncEventSource : public AsyncWebHandler { const char* url() const { return _url.c_str(); } void close(); void onConnect(ArEventHandlerFunction cb); - void authorizeConnect(ArAuthorizeConnectHandler cb) { - AuthorizationMiddleware* m = new AuthorizationMiddleware(401, cb); - m->_freeOnRemoval = true; - addMiddleware(m); - } + void authorizeConnect(ArAuthorizeConnectHandler cb); void send(const String& message, const String& event, uint32_t id = 0, uint32_t reconnect = 0) { send(message.c_str(), event.c_str(), id, reconnect); } void send(const String& message, const char* event, uint32_t id = 0, uint32_t reconnect = 0) { send(message.c_str(), event, id, reconnect); } void send(const char* message, const char* event = NULL, uint32_t id = 0, uint32_t reconnect = 0); diff --git a/src/AsyncJson.cpp b/src/AsyncJson.cpp new file mode 100644 index 000000000..511f2ecc4 --- /dev/null +++ b/src/AsyncJson.cpp @@ -0,0 +1,151 @@ +#include "AsyncJson.h" + +#if ARDUINOJSON_VERSION_MAJOR == 5 +AsyncJsonResponse::AsyncJsonResponse(bool isArray) : _isValid{false} { + _code = 200; + _contentType = JSON_MIMETYPE; + if (isArray) + _root = _jsonBuffer.createArray(); + else + _root = _jsonBuffer.createObject(); +} +#elif ARDUINOJSON_VERSION_MAJOR == 6 +AsyncJsonResponse::AsyncJsonResponse(bool isArray, size_t maxJsonBufferSize) : _jsonBuffer(maxJsonBufferSize), _isValid{false} { + _code = 200; + _contentType = JSON_MIMETYPE; + if (isArray) + _root = _jsonBuffer.createNestedArray(); + else + _root = _jsonBuffer.createNestedObject(); +} +#else +AsyncJsonResponse::AsyncJsonResponse(bool isArray) : _isValid{false} { + _code = 200; + _contentType = JSON_MIMETYPE; + if (isArray) + _root = _jsonBuffer.add(); + else + _root = _jsonBuffer.add(); +} +#endif + +size_t AsyncJsonResponse::setLength() { +#if ARDUINOJSON_VERSION_MAJOR == 5 + _contentLength = _root.measureLength(); +#else + _contentLength = measureJson(_root); +#endif + if (_contentLength) { + _isValid = true; + } + return _contentLength; +} + +size_t AsyncJsonResponse::_fillBuffer(uint8_t* data, size_t len) { + ChunkPrint dest(data, _sentLength, len); +#if ARDUINOJSON_VERSION_MAJOR == 5 + _root.printTo(dest); +#else + serializeJson(_root, dest); +#endif + return len; +} + +#if ARDUINOJSON_VERSION_MAJOR == 6 +PrettyAsyncJsonResponse::PrettyAsyncJsonResponse(bool isArray, size_t maxJsonBufferSize) : AsyncJsonResponse{isArray, maxJsonBufferSize} {} +#else +PrettyAsyncJsonResponse::PrettyAsyncJsonResponse(bool isArray) : AsyncJsonResponse{isArray} {} +#endif + +size_t PrettyAsyncJsonResponse::setLength() { +#if ARDUINOJSON_VERSION_MAJOR == 5 + _contentLength = _root.measurePrettyLength(); +#else + _contentLength = measureJsonPretty(_root); +#endif + if (_contentLength) { + _isValid = true; + } + return _contentLength; +} + +size_t PrettyAsyncJsonResponse::_fillBuffer(uint8_t* data, size_t len) { + ChunkPrint dest(data, _sentLength, len); +#if ARDUINOJSON_VERSION_MAJOR == 5 + _root.prettyPrintTo(dest); +#else + serializeJsonPretty(_root, dest); +#endif + return len; +} + +#if ARDUINOJSON_VERSION_MAJOR == 6 +AsyncCallbackJsonWebHandler::AsyncCallbackJsonWebHandler(const String& uri, ArJsonRequestHandlerFunction onRequest, size_t maxJsonBufferSize) + : _uri(uri), _method(HTTP_GET | HTTP_POST | HTTP_PUT | HTTP_PATCH), _onRequest(onRequest), maxJsonBufferSize(maxJsonBufferSize), _maxContentLength(16384) {} +#else +AsyncCallbackJsonWebHandler::AsyncCallbackJsonWebHandler(const String& uri, ArJsonRequestHandlerFunction onRequest) + : _uri(uri), _method(HTTP_GET | HTTP_POST | HTTP_PUT | HTTP_PATCH), _onRequest(onRequest), _maxContentLength(16384) {} +#endif + +bool AsyncCallbackJsonWebHandler::canHandle(AsyncWebServerRequest* request) { + if (!_onRequest) + return false; + + WebRequestMethodComposite request_method = request->method(); + if (!(_method & request_method)) + return false; + + if (_uri.length() && (_uri != request->url() && !request->url().startsWith(_uri + "/"))) + return false; + + if (request_method != HTTP_GET && !request->contentType().equalsIgnoreCase(JSON_MIMETYPE)) + return false; + + return true; +} + +void AsyncCallbackJsonWebHandler::handleRequest(AsyncWebServerRequest* request) { + if (_onRequest) { + if (request->method() == HTTP_GET) { + JsonVariant json; + _onRequest(request, json); + return; + } else if (request->_tempObject != NULL) { + +#if ARDUINOJSON_VERSION_MAJOR == 5 + DynamicJsonBuffer jsonBuffer; + JsonVariant json = jsonBuffer.parse((uint8_t*)(request->_tempObject)); + if (json.success()) { +#elif ARDUINOJSON_VERSION_MAJOR == 6 + DynamicJsonDocument jsonBuffer(this->maxJsonBufferSize); + DeserializationError error = deserializeJson(jsonBuffer, (uint8_t*)(request->_tempObject)); + if (!error) { + JsonVariant json = jsonBuffer.as(); +#else + JsonDocument jsonBuffer; + DeserializationError error = deserializeJson(jsonBuffer, (uint8_t*)(request->_tempObject)); + if (!error) { + JsonVariant json = jsonBuffer.as(); +#endif + + _onRequest(request, json); + return; + } + } + request->send(_contentLength > _maxContentLength ? 413 : 400); + } else { + request->send(500); + } +} + +void AsyncCallbackJsonWebHandler::handleBody(AsyncWebServerRequest* request, uint8_t* data, size_t len, size_t index, size_t total) { + if (_onRequest) { + _contentLength = total; + if (total > 0 && request->_tempObject == NULL && total < _maxContentLength) { + request->_tempObject = malloc(total); + } + if (request->_tempObject != NULL) { + memcpy((uint8_t*)(request->_tempObject) + index, data, len); + } + } +} \ No newline at end of file diff --git a/src/AsyncJson.h b/src/AsyncJson.h index 5426f4110..0e7e61d93 100644 --- a/src/AsyncJson.h +++ b/src/AsyncJson.h @@ -65,102 +65,35 @@ class AsyncJsonResponse : public AsyncAbstractResponse { bool _isValid; public: -#if ARDUINOJSON_VERSION_MAJOR == 5 - AsyncJsonResponse(bool isArray = false) : _isValid{false} { - _code = 200; - _contentType = JSON_MIMETYPE; - if (isArray) - _root = _jsonBuffer.createArray(); - else - _root = _jsonBuffer.createObject(); - } -#elif ARDUINOJSON_VERSION_MAJOR == 6 - AsyncJsonResponse(bool isArray = false, size_t maxJsonBufferSize = DYNAMIC_JSON_DOCUMENT_SIZE) : _jsonBuffer(maxJsonBufferSize), _isValid{false} { - _code = 200; - _contentType = JSON_MIMETYPE; - if (isArray) - _root = _jsonBuffer.createNestedArray(); - else - _root = _jsonBuffer.createNestedObject(); - } +#if ARDUINOJSON_VERSION_MAJOR == 6 + AsyncJsonResponse(bool isArray = false, size_t maxJsonBufferSize = DYNAMIC_JSON_DOCUMENT_SIZE); #else - AsyncJsonResponse(bool isArray = false) : _isValid{false} { - _code = 200; - _contentType = JSON_MIMETYPE; - if (isArray) - _root = _jsonBuffer.add(); - else - _root = _jsonBuffer.add(); - } + AsyncJsonResponse(bool isArray = false); #endif - JsonVariant& getRoot() { return _root; } bool _sourceValid() const { return _isValid; } - size_t setLength() { - -#if ARDUINOJSON_VERSION_MAJOR == 5 - _contentLength = _root.measureLength(); -#else - _contentLength = measureJson(_root); -#endif - - if (_contentLength) { - _isValid = true; - } - return _contentLength; - } - + size_t setLength(); size_t getSize() const { return _jsonBuffer.size(); } - + size_t _fillBuffer(uint8_t* data, size_t len); #if ARDUINOJSON_VERSION_MAJOR >= 6 bool overflowed() const { return _jsonBuffer.overflowed(); } #endif - - size_t _fillBuffer(uint8_t* data, size_t len) { - ChunkPrint dest(data, _sentLength, len); - -#if ARDUINOJSON_VERSION_MAJOR == 5 - _root.printTo(dest); -#else - serializeJson(_root, dest); -#endif - return len; - } }; class PrettyAsyncJsonResponse : public AsyncJsonResponse { public: #if ARDUINOJSON_VERSION_MAJOR == 6 - PrettyAsyncJsonResponse(bool isArray = false, size_t maxJsonBufferSize = DYNAMIC_JSON_DOCUMENT_SIZE) : AsyncJsonResponse{isArray, maxJsonBufferSize} {} + PrettyAsyncJsonResponse(bool isArray = false, size_t maxJsonBufferSize = DYNAMIC_JSON_DOCUMENT_SIZE); #else - PrettyAsyncJsonResponse(bool isArray = false) : AsyncJsonResponse{isArray} {} + PrettyAsyncJsonResponse(bool isArray = false); #endif - size_t setLength() { -#if ARDUINOJSON_VERSION_MAJOR == 5 - _contentLength = _root.measurePrettyLength(); -#else - _contentLength = measureJsonPretty(_root); -#endif - if (_contentLength) { - _isValid = true; - } - return _contentLength; - } - size_t _fillBuffer(uint8_t* data, size_t len) { - ChunkPrint dest(data, _sentLength, len); -#if ARDUINOJSON_VERSION_MAJOR == 5 - _root.prettyPrintTo(dest); -#else - serializeJsonPretty(_root, dest); -#endif - return len; - } + size_t setLength(); + size_t _fillBuffer(uint8_t* data, size_t len); }; typedef std::function ArJsonRequestHandlerFunction; class AsyncCallbackJsonWebHandler : public AsyncWebHandler { - private: protected: const String _uri; WebRequestMethodComposite _method; @@ -173,80 +106,19 @@ class AsyncCallbackJsonWebHandler : public AsyncWebHandler { public: #if ARDUINOJSON_VERSION_MAJOR == 6 - AsyncCallbackJsonWebHandler(const String& uri, ArJsonRequestHandlerFunction onRequest = nullptr, size_t maxJsonBufferSize = DYNAMIC_JSON_DOCUMENT_SIZE) - : _uri(uri), _method(HTTP_GET | HTTP_POST | HTTP_PUT | HTTP_PATCH), _onRequest(onRequest), maxJsonBufferSize(maxJsonBufferSize), _maxContentLength(16384) {} + AsyncCallbackJsonWebHandler(const String& uri, ArJsonRequestHandlerFunction onRequest = nullptr, size_t maxJsonBufferSize = DYNAMIC_JSON_DOCUMENT_SIZE); #else - AsyncCallbackJsonWebHandler(const String& uri, ArJsonRequestHandlerFunction onRequest = nullptr) - : _uri(uri), _method(HTTP_GET | HTTP_POST | HTTP_PUT | HTTP_PATCH), _onRequest(onRequest), _maxContentLength(16384) {} + AsyncCallbackJsonWebHandler(const String& uri, ArJsonRequestHandlerFunction onRequest = nullptr); #endif void setMethod(WebRequestMethodComposite method) { _method = method; } void setMaxContentLength(int maxContentLength) { _maxContentLength = maxContentLength; } void onRequest(ArJsonRequestHandlerFunction fn) { _onRequest = fn; } - virtual bool canHandle(AsyncWebServerRequest* request) override final { - if (!_onRequest) - return false; - - WebRequestMethodComposite request_method = request->method(); - if (!(_method & request_method)) - return false; - - if (_uri.length() && (_uri != request->url() && !request->url().startsWith(_uri + "/"))) - return false; - - if (request_method != HTTP_GET && !request->contentType().equalsIgnoreCase(JSON_MIMETYPE)) - return false; - - return true; - } - - virtual void handleRequest(AsyncWebServerRequest* request) override final { - if (_onRequest) { - if (request->method() == HTTP_GET) { - JsonVariant json; - _onRequest(request, json); - return; - } else if (request->_tempObject != NULL) { - -#if ARDUINOJSON_VERSION_MAJOR == 5 - DynamicJsonBuffer jsonBuffer; - JsonVariant json = jsonBuffer.parse((uint8_t*)(request->_tempObject)); - if (json.success()) { -#elif ARDUINOJSON_VERSION_MAJOR == 6 - DynamicJsonDocument jsonBuffer(this->maxJsonBufferSize); - DeserializationError error = deserializeJson(jsonBuffer, (uint8_t*)(request->_tempObject)); - if (!error) { - JsonVariant json = jsonBuffer.as(); -#else - JsonDocument jsonBuffer; - DeserializationError error = deserializeJson(jsonBuffer, (uint8_t*)(request->_tempObject)); - if (!error) { - JsonVariant json = jsonBuffer.as(); -#endif - - _onRequest(request, json); - return; - } - } - request->send(_contentLength > _maxContentLength ? 413 : 400); - } else { - request->send(500); - } - } - virtual void handleUpload(__unused AsyncWebServerRequest* request, __unused const String& filename, __unused size_t index, __unused uint8_t* data, __unused size_t len, __unused bool final) override final { - } - virtual void handleBody(AsyncWebServerRequest* request, uint8_t* data, size_t len, size_t index, size_t total) override final { - if (_onRequest) { - _contentLength = total; - if (total > 0 && request->_tempObject == NULL && total < _maxContentLength) { - request->_tempObject = malloc(total); - } - if (request->_tempObject != NULL) { - memcpy((uint8_t*)(request->_tempObject) + index, data, len); - } - } - } - virtual bool isRequestHandlerTrivial() override final { return _onRequest ? false : true; } + virtual bool canHandle(AsyncWebServerRequest* request) override final; + virtual void handleRequest(AsyncWebServerRequest* request) override final; + virtual void handleUpload(__unused AsyncWebServerRequest* request, __unused const String& filename, __unused size_t index, __unused uint8_t* data, __unused size_t len, __unused bool final) override final {} + virtual void handleBody(AsyncWebServerRequest* request, uint8_t* data, size_t len, size_t index, size_t total) override final; + virtual bool isRequestHandlerTrivial() override final { return !_onRequest; } }; #endif diff --git a/src/AsyncMessagePack.cpp b/src/AsyncMessagePack.cpp new file mode 100644 index 000000000..65827d7c9 --- /dev/null +++ b/src/AsyncMessagePack.cpp @@ -0,0 +1,79 @@ +#include "AsyncMessagePack.h" + +AsyncMessagePackResponse::AsyncMessagePackResponse(bool isArray) : _isValid{false} { + _code = 200; + _contentType = asyncsrv::T_application_msgpack; + if (isArray) + _root = _jsonBuffer.add(); + else + _root = _jsonBuffer.add(); +} + +size_t AsyncMessagePackResponse::setLength() { + _contentLength = measureMsgPack(_root); + if (_contentLength) { + _isValid = true; + } + return _contentLength; +} + +size_t AsyncMessagePackResponse::_fillBuffer(uint8_t* data, size_t len) { + ChunkPrint dest(data, _sentLength, len); + serializeMsgPack(_root, dest); + return len; +} + +AsyncCallbackMessagePackWebHandler::AsyncCallbackMessagePackWebHandler(const String& uri, ArJsonRequestHandlerFunction onRequest) + : _uri(uri), _method(HTTP_GET | HTTP_POST | HTTP_PUT | HTTP_PATCH), _onRequest(onRequest), _maxContentLength(16384) {} + +bool AsyncCallbackMessagePackWebHandler::canHandle(AsyncWebServerRequest* request) { + if (!_onRequest) + return false; + + WebRequestMethodComposite request_method = request->method(); + if (!(_method & request_method)) + return false; + + if (_uri.length() && (_uri != request->url() && !request->url().startsWith(_uri + "/"))) + return false; + + if (request_method != HTTP_GET && !request->contentType().equalsIgnoreCase(asyncsrv::T_application_msgpack)) + return false; + + return true; +} + +void AsyncCallbackMessagePackWebHandler::handleRequest(AsyncWebServerRequest* request) { + if (_onRequest) { + if (request->method() == HTTP_GET) { + JsonVariant json; + _onRequest(request, json); + return; + + } else if (request->_tempObject != NULL) { + JsonDocument jsonBuffer; + DeserializationError error = deserializeMsgPack(jsonBuffer, (uint8_t*)(request->_tempObject)); + + if (!error) { + JsonVariant json = jsonBuffer.as(); + _onRequest(request, json); + return; + } + } + request->send(_contentLength > _maxContentLength ? 413 : 400); + } else { + request->send(500); + } +} + +void AsyncCallbackMessagePackWebHandler::handleBody(AsyncWebServerRequest* request, uint8_t* data, size_t len, size_t index, size_t total) { + if (_onRequest) { + _contentLength = total; + if (total > 0 && request->_tempObject == NULL && total < _maxContentLength) { + request->_tempObject = malloc(total); + } + if (request->_tempObject != NULL) { + memcpy((uint8_t*)(request->_tempObject) + index, data, len); + } + } +} diff --git a/src/AsyncMessagePack.h b/src/AsyncMessagePack.h index 9a6b6ba69..16104ef6e 100644 --- a/src/AsyncMessagePack.h +++ b/src/AsyncMessagePack.h @@ -25,7 +25,6 @@ #include #include "ChunkPrint.h" -#include "literals.h" class AsyncMessagePackResponse : public AsyncAbstractResponse { protected: @@ -34,34 +33,13 @@ class AsyncMessagePackResponse : public AsyncAbstractResponse { bool _isValid; public: - AsyncMessagePackResponse(bool isArray = false) : _isValid{false} { - _code = 200; - _contentType = asyncsrv::T_application_msgpack; - if (isArray) - _root = _jsonBuffer.add(); - else - _root = _jsonBuffer.add(); - } + AsyncMessagePackResponse(bool isArray = false); JsonVariant& getRoot() { return _root; } - bool _sourceValid() const { return _isValid; } - - size_t setLength() { - _contentLength = measureMsgPack(_root); - if (_contentLength) { - _isValid = true; - } - return _contentLength; - } - + size_t setLength(); size_t getSize() const { return _jsonBuffer.size(); } - - size_t _fillBuffer(uint8_t* data, size_t len) { - ChunkPrint dest(data, _sentLength, len); - serializeMsgPack(_root, dest); - return len; - } + size_t _fillBuffer(uint8_t* data, size_t len); }; class AsyncCallbackMessagePackWebHandler : public AsyncWebHandler { @@ -76,66 +54,14 @@ class AsyncCallbackMessagePackWebHandler : public AsyncWebHandler { size_t _maxContentLength; public: - AsyncCallbackMessagePackWebHandler(const String& uri, ArJsonRequestHandlerFunction onRequest = nullptr) - : _uri(uri), _method(HTTP_GET | HTTP_POST | HTTP_PUT | HTTP_PATCH), _onRequest(onRequest), _maxContentLength(16384) {} + AsyncCallbackMessagePackWebHandler(const String& uri, ArJsonRequestHandlerFunction onRequest = nullptr); void setMethod(WebRequestMethodComposite method) { _method = method; } void setMaxContentLength(int maxContentLength) { _maxContentLength = maxContentLength; } void onRequest(ArJsonRequestHandlerFunction fn) { _onRequest = fn; } - - virtual bool canHandle(AsyncWebServerRequest* request) override final { - if (!_onRequest) - return false; - - WebRequestMethodComposite request_method = request->method(); - if (!(_method & request_method)) - return false; - - if (_uri.length() && (_uri != request->url() && !request->url().startsWith(_uri + "/"))) - return false; - - if (request_method != HTTP_GET && !request->contentType().equalsIgnoreCase(asyncsrv::T_application_msgpack)) - return false; - - return true; - } - - virtual void handleRequest(AsyncWebServerRequest* request) override final { - if (_onRequest) { - if (request->method() == HTTP_GET) { - JsonVariant json; - _onRequest(request, json); - return; - - } else if (request->_tempObject != NULL) { - JsonDocument jsonBuffer; - DeserializationError error = deserializeMsgPack(jsonBuffer, (uint8_t*)(request->_tempObject)); - - if (!error) { - JsonVariant json = jsonBuffer.as(); - _onRequest(request, json); - return; - } - } - request->send(_contentLength > _maxContentLength ? 413 : 400); - } else { - request->send(500); - } - } - + virtual bool canHandle(AsyncWebServerRequest* request) override final; + virtual void handleRequest(AsyncWebServerRequest* request) override final; virtual void handleUpload(__unused AsyncWebServerRequest* request, __unused const String& filename, __unused size_t index, __unused uint8_t* data, __unused size_t len, __unused bool final) override final {} - - virtual void handleBody(AsyncWebServerRequest* request, uint8_t* data, size_t len, size_t index, size_t total) override final { - if (_onRequest) { - _contentLength = total; - if (total > 0 && request->_tempObject == NULL && total < _maxContentLength) { - request->_tempObject = malloc(total); - } - if (request->_tempObject != NULL) { - memcpy((uint8_t*)(request->_tempObject) + index, data, len); - } - } - } - + virtual void handleBody(AsyncWebServerRequest* request, uint8_t* data, size_t len, size_t index, size_t total) override final; virtual bool isRequestHandlerTrivial() override final { return _onRequest ? false : true; } }; diff --git a/src/AsyncWebHeader.cpp b/src/AsyncWebHeader.cpp new file mode 100644 index 000000000..ba271a3b6 --- /dev/null +++ b/src/AsyncWebHeader.cpp @@ -0,0 +1,22 @@ +#include + +AsyncWebHeader::AsyncWebHeader(const String& data) { + if (!data) + return; + int index = data.indexOf(':'); + if (index < 0) + return; + _name = data.substring(0, index); + _value = data.substring(index + 2); +} + +String AsyncWebHeader::toString() const { + String str; + str.reserve(_name.length() + _value.length() + 2); + str.concat(_name); + str.concat((char)0x3a); + str.concat((char)0x20); + str.concat(_value); + str.concat(asyncsrv::T_rn); + return str; +} diff --git a/src/AsyncWebSocket.h b/src/AsyncWebSocket.h index 34256a781..a832a2d3d 100644 --- a/src/AsyncWebSocket.h +++ b/src/AsyncWebSocket.h @@ -281,7 +281,7 @@ class AsyncWebSocket : public AsyncWebHandler { public: explicit AsyncWebSocket(const char* url) : _url(url), _cNextId(1), _enabled(true) {} AsyncWebSocket(const String& url) : _url(url), _cNextId(1), _enabled(true) {} - ~AsyncWebSocket(){}; + ~AsyncWebSocket() {}; const char* url() const { return _url.c_str(); } void enable(bool e) { _enabled = e; } bool enabled() const { return _enabled; } @@ -339,15 +339,8 @@ class AsyncWebSocket : public AsyncWebHandler { size_t printfAll_P(PGM_P formatP, ...) __attribute__((format(printf, 2, 3))); #endif - // event listener - void onEvent(AwsEventHandler handler) { - _eventHandler = handler; - } - - // Handshake Handler - void handleHandshake(AwsHandshakeHandler handler) { - _handshakeHandler = handler; - } + void onEvent(AwsEventHandler handler) { _eventHandler = handler; } + void handleHandshake(AwsHandshakeHandler handler) { _handshakeHandler = handler; } // system callbacks (do not call) uint32_t _getNextId() { return _cNextId++; } diff --git a/src/ChunkPrint.cpp b/src/ChunkPrint.cpp new file mode 100644 index 000000000..8c9717a56 --- /dev/null +++ b/src/ChunkPrint.cpp @@ -0,0 +1,16 @@ +#include + +ChunkPrint::ChunkPrint(uint8_t* destination, size_t from, size_t len) + : _destination(destination), _to_skip(from), _to_write(len), _pos{0} {} + +size_t ChunkPrint::write(uint8_t c) { + if (_to_skip > 0) { + _to_skip--; + return 1; + } else if (_to_write > 0) { + _to_write--; + _destination[_pos++] = c; + return 1; + } + return 0; +} \ No newline at end of file diff --git a/src/ChunkPrint.h b/src/ChunkPrint.h index 2f4074116..103d21e1c 100644 --- a/src/ChunkPrint.h +++ b/src/ChunkPrint.h @@ -11,22 +11,9 @@ class ChunkPrint : public Print { size_t _pos; public: - ChunkPrint(uint8_t* destination, size_t from, size_t len) - : _destination(destination), _to_skip(from), _to_write(len), _pos{0} {} + ChunkPrint(uint8_t* destination, size_t from, size_t len); virtual ~ChunkPrint() {} - size_t write(uint8_t c) { - if (_to_skip > 0) { - _to_skip--; - return 1; - } else if (_to_write > 0) { - _to_write--; - _destination[_pos++] = c; - return 1; - } - return 0; - } - size_t write(const uint8_t* buffer, size_t size) { - return this->Print::write(buffer, size); - } + size_t write(uint8_t c); + size_t write(const uint8_t* buffer, size_t size) { return this->Print::write(buffer, size); } }; #endif diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index 8922ea712..621a9c814 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -24,6 +24,7 @@ #include "Arduino.h" #include "FS.h" +#include #include #include #include @@ -141,33 +142,15 @@ class AsyncWebHeader { public: AsyncWebHeader() = default; AsyncWebHeader(const AsyncWebHeader&) = default; - AsyncWebHeader(const char* name, const char* value) : _name(name), _value(value) {} AsyncWebHeader(const String& name, const String& value) : _name(name), _value(value) {} - AsyncWebHeader(const String& data) { - if (!data) - return; - int index = data.indexOf(':'); - if (index < 0) - return; - _name = data.substring(0, index); - _value = data.substring(index + 2); - } + AsyncWebHeader(const String& data); AsyncWebHeader& operator=(const AsyncWebHeader&) = default; const String& name() const { return _name; } const String& value() const { return _value; } - String toString() const { - String str; - str.reserve(_name.length() + _value.length() + 2); - str.concat(_name); - str.concat((char)0x3a); - str.concat((char)0x20); - str.concat(_value); - str.concat(asyncsrv::T_rn); - return str; - } + String toString() const; }; /* @@ -472,23 +455,11 @@ class AsyncWebServerRequest { const std::list& getHeaders() const { return _headers; } - size_t getHeaderNames(std::vector& names) const { - names.clear(); - const size_t size = _headers.size(); - names.reserve(size); - for (const auto& h : _headers) { - names.push_back(h.name().c_str()); - } - return size; - } + size_t getHeaderNames(std::vector& names) const; // Remove a header from the request. // It will free the memory and prevent the header to be seen during request processing. - bool removeHeader(const char* name) { - const size_t size = _headers.size(); - _headers.remove_if([name](const AsyncWebHeader& header) { return header.name().equalsIgnoreCase(name); }); - return size != _headers.size(); - } + bool removeHeader(const char* name); // Remove all request headers. void removeHeaders() { _headers.clear(); } @@ -509,26 +480,11 @@ class AsyncWebServerRequest { bool hasAttribute(const char* name) const { return _attributes.find(name) != _attributes.end(); } - const String& getAttribute(const char* name, const String& defaultValue = emptyString) const { - auto it = _attributes.find(name); - return it != _attributes.end() ? it->second : defaultValue; - } - bool getAttribute(const char* name, bool defaultValue) const { - auto it = _attributes.find(name); - return it != _attributes.end() ? it->second == "1" : defaultValue; - } - long getAttribute(const char* name, long defaultValue) const { - auto it = _attributes.find(name); - return it != _attributes.end() ? it->second.toInt() : defaultValue; - } - float getAttribute(const char* name, float defaultValue) const { - auto it = _attributes.find(name); - return it != _attributes.end() ? it->second.toFloat() : defaultValue; - } - double getAttribute(const char* name, double defaultValue) const { - auto it = _attributes.find(name); - return it != _attributes.end() ? it->second.toDouble() : defaultValue; - } + const String& getAttribute(const char* name, const String& defaultValue = emptyString) const; + bool getAttribute(const char* name, bool defaultValue) const; + long getAttribute(const char* name, long defaultValue) const; + float getAttribute(const char* name, float defaultValue) const; + double getAttribute(const char* name, double defaultValue) const; String urlDecode(const String& text) const; }; @@ -580,53 +536,15 @@ class AsyncMiddlewareFunction : public AsyncMiddleware { // For internal use only: super class to add/remove middleware to server or handlers class AsyncMiddlewareChain { public: - virtual ~AsyncMiddlewareChain() { - for (AsyncMiddleware* m : _middlewares) - if (m->_freeOnRemoval) - delete m; - } - void addMiddleware(ArMiddlewareCallback fn) { - AsyncMiddlewareFunction* m = new AsyncMiddlewareFunction(fn); - m->_freeOnRemoval = true; - _middlewares.emplace_back(m); - } - void addMiddleware(AsyncMiddleware* middleware) { - if (middleware) - _middlewares.emplace_back(middleware); - } - void addMiddlewares(std::vector middlewares) { - for (AsyncMiddleware* m : middlewares) - addMiddleware(m); - } - bool removeMiddleware(AsyncMiddleware* middleware) { - // remove all middlewares from _middlewares vector being equal to middleware, delete them having _freeOnRemoval flag to true and resize the vector. - const size_t size = _middlewares.size(); - _middlewares.erase(std::remove_if(_middlewares.begin(), _middlewares.end(), [middleware](AsyncMiddleware* m) { - if (m == middleware) { - if (m->_freeOnRemoval) - delete m; - return true; - } - return false; - }), - _middlewares.end()); - return size != _middlewares.size(); - } + virtual ~AsyncMiddlewareChain(); + + void addMiddleware(ArMiddlewareCallback fn); + void addMiddleware(AsyncMiddleware* middleware); + void addMiddlewares(std::vector middlewares); + bool removeMiddleware(AsyncMiddleware* middleware); + // For internal use only - void _runChain(AsyncWebServerRequest* request, ArMiddlewareNext finalizer) { - if (!_middlewares.size()) - return finalizer(); - ArMiddlewareNext next; - std::list::iterator it = _middlewares.begin(); - next = [this, &next, &it, request, finalizer]() { - if (it == _middlewares.end()) - return finalizer(); - AsyncMiddleware* m = *it; - it++; - return m->run(request, next); - }; - return next(); - } + void _runChain(AsyncWebServerRequest* request, ArMiddlewareNext finalizer); protected: std::list _middlewares; @@ -647,13 +565,9 @@ class AuthenticationMiddleware : public AsyncMiddleware { void setPasswordIsHash(bool passwordIsHash) { _hash = passwordIsHash; } void setAuthType(AuthType authType) { _authType = authType; } - bool allowed(AsyncWebServerRequest* request) { - return _authType == AUTH_NONE || !_username.length() || !_password.length() || request->authenticate(_username.c_str(), _password.c_str(), _realm, _hash); - } + bool allowed(AsyncWebServerRequest* request) { return _authType == AUTH_NONE || !_username.length() || !_password.length() || request->authenticate(_username.c_str(), _password.c_str(), _realm, _hash); } - void run(AsyncWebServerRequest* request, ArMiddlewareNext next) { - return allowed(request) ? next() : request->requestAuthentication(_realm, _authType == AUTH_DIGEST); - } + void run(AsyncWebServerRequest* request, ArMiddlewareNext next) { return allowed(request) ? next() : request->requestAuthentication(_realm, _authType == AUTH_DIGEST); } private: String _username; @@ -669,11 +583,8 @@ class AuthorizationMiddleware : public AsyncMiddleware { public: AuthorizationMiddleware(ArAuthorizeFunction authorizeConnectHandler) : _code(403), _authz(authorizeConnectHandler) {} AuthorizationMiddleware(int code, ArAuthorizeFunction authorizeConnectHandler) : _code(code), _authz(authorizeConnectHandler) {} - void run(AsyncWebServerRequest* request, ArMiddlewareNext next) { - if (_authz && !_authz(request)) - return request->send(_code); - return next(); - } + + void run(AsyncWebServerRequest* request, ArMiddlewareNext next) { return _authz && !_authz(request) ? request->send(_code) : next(); } private: int _code; @@ -685,23 +596,8 @@ class HeaderFreeMiddleware : public AsyncMiddleware { public: void keep(const char* name) { _toKeep.push_back(name); } void unKeep(const char* name) { _toKeep.erase(std::remove(_toKeep.begin(), _toKeep.end(), name), _toKeep.end()); } - void run(AsyncWebServerRequest* request, ArMiddlewareNext next) { - std::vector reqHeaders; - request->getHeaderNames(reqHeaders); - for (const char* h : reqHeaders) { - bool keep = false; - for (const char* k : _toKeep) { - if (strcasecmp(h, k) == 0) { - keep = true; - break; - } - } - if (!keep) { - request->removeHeader(h); - } - } - next(); - } + + void run(AsyncWebServerRequest* request, ArMiddlewareNext next); private: std::vector _toKeep; @@ -712,11 +608,8 @@ class HeaderFilterMiddleware : public AsyncMiddleware { public: void filter(const char* name) { _toRemove.push_back(name); } void unFilter(const char* name) { _toRemove.erase(std::remove(_toRemove.begin(), _toRemove.end(), name), _toRemove.end()); } - void run(AsyncWebServerRequest* request, ArMiddlewareNext next) { - for (auto it = _toRemove.begin(); it != _toRemove.end(); ++it) - request->removeHeader(*it); - next(); - } + + void run(AsyncWebServerRequest* request, ArMiddlewareNext next); private: std::vector _toRemove; @@ -763,23 +656,7 @@ class RateLimitMiddleware : public AsyncMiddleware { void setMaxRequests(size_t maxRequests) { _maxRequests = maxRequests; } void setWindowSize(uint32_t seconds) { _windowSizeMillis = seconds * 1000; } - bool isRequestAllowed(uint32_t& retryAfterSeconds) { - uint32_t now = millis(); - - while (!_requestTimes.empty() && _requestTimes.front() <= now - _windowSizeMillis) - _requestTimes.pop_front(); - - _requestTimes.push_back(now); - - if (_requestTimes.size() > _maxRequests) { - _requestTimes.pop_front(); - retryAfterSeconds = (_windowSizeMillis - (now - _requestTimes.front())) / 1000 + 1; - return false; - } - - retryAfterSeconds = 0; - return true; - } + bool isRequestAllowed(uint32_t& retryAfterSeconds); void run(AsyncWebServerRequest* request, ArMiddlewareNext next); @@ -830,20 +707,8 @@ class AsyncWebHandler : public AsyncMiddlewareChain { public: AsyncWebHandler() {} - AsyncWebHandler& setFilter(ArRequestFilterFunction fn) { - _filter = fn; - return *this; - } - AsyncWebHandler& setAuthentication(const char* username, const char* password) { - if (username == nullptr || password == nullptr || strlen(username) == 0 || strlen(password) == 0) - return *this; - AuthenticationMiddleware* m = new AuthenticationMiddleware(); - m->setUsername(username); - m->setPassword(password); - m->_freeOnRemoval = true; - addMiddleware(m); - return *this; - }; + AsyncWebHandler& setFilter(ArRequestFilterFunction fn); + AsyncWebHandler& setAuthentication(const char* username, const char* password); AsyncWebHandler& setAuthentication(const String& username, const String& password) { return setAuthentication(username.c_str(), password.c_str()); }; bool filter(AsyncWebServerRequest* request) { return _filter == NULL || _filter(request); } virtual ~AsyncWebHandler() {} diff --git a/src/Middlewares.cpp b/src/Middleware.cpp similarity index 52% rename from src/Middlewares.cpp rename to src/Middleware.cpp index 1f0252a94..5dc3d0532 100644 --- a/src/Middlewares.cpp +++ b/src/Middleware.cpp @@ -1,4 +1,80 @@ -#include "ESPAsyncWebServer.h" +#include + +AsyncMiddlewareChain::~AsyncMiddlewareChain() { + for (AsyncMiddleware* m : _middlewares) + if (m->_freeOnRemoval) + delete m; +} + +void AsyncMiddlewareChain::addMiddleware(ArMiddlewareCallback fn) { + AsyncMiddlewareFunction* m = new AsyncMiddlewareFunction(fn); + m->_freeOnRemoval = true; + _middlewares.emplace_back(m); +} + +void AsyncMiddlewareChain::addMiddleware(AsyncMiddleware* middleware) { + if (middleware) + _middlewares.emplace_back(middleware); +} + +void AsyncMiddlewareChain::addMiddlewares(std::vector middlewares) { + for (AsyncMiddleware* m : middlewares) + addMiddleware(m); +} + +bool AsyncMiddlewareChain::removeMiddleware(AsyncMiddleware* middleware) { + // remove all middlewares from _middlewares vector being equal to middleware, delete them having _freeOnRemoval flag to true and resize the vector. + const size_t size = _middlewares.size(); + _middlewares.erase(std::remove_if(_middlewares.begin(), _middlewares.end(), [middleware](AsyncMiddleware* m) { + if (m == middleware) { + if (m->_freeOnRemoval) + delete m; + return true; + } + return false; + }), + _middlewares.end()); + return size != _middlewares.size(); +} + +void AsyncMiddlewareChain::_runChain(AsyncWebServerRequest* request, ArMiddlewareNext finalizer) { + if (!_middlewares.size()) + return finalizer(); + ArMiddlewareNext next; + std::list::iterator it = _middlewares.begin(); + next = [this, &next, &it, request, finalizer]() { + if (it == _middlewares.end()) + return finalizer(); + AsyncMiddleware* m = *it; + it++; + return m->run(request, next); + }; + return next(); +} + +void HeaderFreeMiddleware::run(AsyncWebServerRequest* request, ArMiddlewareNext next) { + std::vector reqHeaders; + request->getHeaderNames(reqHeaders); + for (const char* h : reqHeaders) { + bool keep = false; + for (const char* k : _toKeep) { + if (strcasecmp(h, k) == 0) { + keep = true; + break; + } + } + if (!keep) { + request->removeHeader(h); + } + } + next(); +} + +void HeaderFilterMiddleware::run(AsyncWebServerRequest* request, ArMiddlewareNext next) { + for (auto it = _toRemove.begin(); it != _toRemove.end(); ++it) + request->removeHeader(*it); + next(); +} void LoggingMiddleware::run(AsyncWebServerRequest* request, ArMiddlewareNext next) { if (!isEnabled()) { @@ -90,6 +166,24 @@ void CorsMiddleware::run(AsyncWebServerRequest* request, ArMiddlewareNext next) } } +bool RateLimitMiddleware::isRequestAllowed(uint32_t& retryAfterSeconds) { + uint32_t now = millis(); + + while (!_requestTimes.empty() && _requestTimes.front() <= now - _windowSizeMillis) + _requestTimes.pop_front(); + + _requestTimes.push_back(now); + + if (_requestTimes.size() > _maxRequests) { + _requestTimes.pop_front(); + retryAfterSeconds = (_windowSizeMillis - (now - _requestTimes.front())) / 1000 + 1; + return false; + } + + retryAfterSeconds = 0; + return true; +} + void RateLimitMiddleware::run(AsyncWebServerRequest* request, ArMiddlewareNext next) { uint32_t retryAfterSeconds; if (isRequestAllowed(retryAfterSeconds)) { diff --git a/src/WebHandlerImpl.h b/src/WebHandlerImpl.h index 2838a8ef9..cb43f809a 100644 --- a/src/WebHandlerImpl.h +++ b/src/WebHandlerImpl.h @@ -63,10 +63,7 @@ class AsyncStaticWebHandler : public AsyncWebHandler { AsyncStaticWebHandler& setLastModified(time_t last_modified); AsyncStaticWebHandler& setLastModified(); // sets to current time. Make sure sntp is runing and time is updated #endif - AsyncStaticWebHandler& setTemplateProcessor(AwsTemplateProcessor newCallback) { - _callback = newCallback; - return *this; - } + AsyncStaticWebHandler& setTemplateProcessor(AwsTemplateProcessor newCallback); }; class AsyncCallbackWebHandler : public AsyncWebHandler { @@ -81,68 +78,17 @@ class AsyncCallbackWebHandler : public AsyncWebHandler { public: AsyncCallbackWebHandler() : _uri(), _method(HTTP_ANY), _onRequest(NULL), _onUpload(NULL), _onBody(NULL), _isRegex(false) {} - void setUri(const String& uri) { - _uri = uri; - _isRegex = uri.startsWith("^") && uri.endsWith("$"); - } + void setUri(const String& uri); void setMethod(WebRequestMethodComposite method) { _method = method; } void onRequest(ArRequestHandlerFunction fn) { _onRequest = fn; } void onUpload(ArUploadHandlerFunction fn) { _onUpload = fn; } void onBody(ArBodyHandlerFunction fn) { _onBody = fn; } - virtual bool canHandle(AsyncWebServerRequest* request) override final { - - if (!_onRequest) - return false; - - if (!(_method & request->method())) - return false; - -#ifdef ASYNCWEBSERVER_REGEX - if (_isRegex) { - std::regex pattern(_uri.c_str()); - std::smatch matches; - std::string s(request->url().c_str()); - if (std::regex_search(s, matches, pattern)) { - for (size_t i = 1; i < matches.size(); ++i) { // start from 1 - request->_addPathParam(matches[i].str().c_str()); - } - } else { - return false; - } - } else -#endif - if (_uri.length() && _uri.startsWith("/*.")) { - String uriTemplate = String(_uri); - uriTemplate = uriTemplate.substring(uriTemplate.lastIndexOf(".")); - if (!request->url().endsWith(uriTemplate)) - return false; - } else if (_uri.length() && _uri.endsWith("*")) { - String uriTemplate = String(_uri); - uriTemplate = uriTemplate.substring(0, uriTemplate.length() - 1); - if (!request->url().startsWith(uriTemplate)) - return false; - } else if (_uri.length() && (_uri != request->url() && !request->url().startsWith(_uri + "/"))) - return false; - - return true; - } - - virtual void handleRequest(AsyncWebServerRequest* request) override final { - if (_onRequest) - _onRequest(request); - else - request->send(500); - } - virtual void handleUpload(AsyncWebServerRequest* request, const String& filename, size_t index, uint8_t* data, size_t len, bool final) override final { - if (_onUpload) - _onUpload(request, filename, index, data, len, final); - } - virtual void handleBody(AsyncWebServerRequest* request, uint8_t* data, size_t len, size_t index, size_t total) override final { - if (_onBody) - _onBody(request, data, len, index, total); - } - virtual bool isRequestHandlerTrivial() override final { return _onRequest ? false : true; } + virtual bool canHandle(AsyncWebServerRequest* request) override final; + virtual void handleRequest(AsyncWebServerRequest* request) override final; + virtual void handleUpload(AsyncWebServerRequest* request, const String& filename, size_t index, uint8_t* data, size_t len, bool final) override final; + virtual void handleBody(AsyncWebServerRequest* request, uint8_t* data, size_t len, size_t index, size_t total) override final; + virtual bool isRequestHandlerTrivial() override final { return !_onRequest; } }; #endif /* ASYNCWEBSERVERHANDLERIMPL_H_ */ diff --git a/src/WebHandlers.cpp b/src/WebHandlers.cpp index 37ce2fa6c..ef976e5bd 100644 --- a/src/WebHandlers.cpp +++ b/src/WebHandlers.cpp @@ -23,6 +23,21 @@ using namespace asyncsrv; +AsyncWebHandler& AsyncWebHandler::setFilter(ArRequestFilterFunction fn) { + _filter = fn; + return *this; +} +AsyncWebHandler& AsyncWebHandler::setAuthentication(const char* username, const char* password) { + if (username == nullptr || password == nullptr || strlen(username) == 0 || strlen(password) == 0) + return *this; + AuthenticationMiddleware* m = new AuthenticationMiddleware(); + m->setUsername(username); + m->setPassword(password); + m->_freeOnRemoval = true; + addMiddleware(m); + return *this; +}; + AsyncStaticWebHandler::AsyncStaticWebHandler(const char* uri, FS& fs, const char* path, const char* cache_control) : _fs(fs), _uri(uri), _path(path), _default_file(F("index.htm")), _cache_control(cache_control), _last_modified(), _callback(nullptr) { // Ensure leading '/' @@ -234,3 +249,65 @@ void AsyncStaticWebHandler::handleRequest(AsyncWebServerRequest* request) { request->send(404); } } + +AsyncStaticWebHandler& AsyncStaticWebHandler::setTemplateProcessor(AwsTemplateProcessor newCallback) { + _callback = newCallback; + return *this; +} + +void AsyncCallbackWebHandler::setUri(const String& uri) { + _uri = uri; + _isRegex = uri.startsWith("^") && uri.endsWith("$"); +} + +bool AsyncCallbackWebHandler::canHandle(AsyncWebServerRequest* request) { + if (!_onRequest) + return false; + + if (!(_method & request->method())) + return false; + +#ifdef ASYNCWEBSERVER_REGEX + if (_isRegex) { + std::regex pattern(_uri.c_str()); + std::smatch matches; + std::string s(request->url().c_str()); + if (std::regex_search(s, matches, pattern)) { + for (size_t i = 1; i < matches.size(); ++i) { // start from 1 + request->_addPathParam(matches[i].str().c_str()); + } + } else { + return false; + } + } else +#endif + if (_uri.length() && _uri.startsWith("/*.")) { + String uriTemplate = String(_uri); + uriTemplate = uriTemplate.substring(uriTemplate.lastIndexOf(".")); + if (!request->url().endsWith(uriTemplate)) + return false; + } else if (_uri.length() && _uri.endsWith("*")) { + String uriTemplate = String(_uri); + uriTemplate = uriTemplate.substring(0, uriTemplate.length() - 1); + if (!request->url().startsWith(uriTemplate)) + return false; + } else if (_uri.length() && (_uri != request->url() && !request->url().startsWith(_uri + "/"))) + return false; + + return true; +} + +void AsyncCallbackWebHandler::handleRequest(AsyncWebServerRequest* request) { + if (_onRequest) + _onRequest(request); + else + request->send(500); +} +void AsyncCallbackWebHandler::handleUpload(AsyncWebServerRequest* request, const String& filename, size_t index, uint8_t* data, size_t len, bool final) { + if (_onUpload) + _onUpload(request, filename, index, data, len, final); +} +void AsyncCallbackWebHandler::handleBody(AsyncWebServerRequest* request, uint8_t* data, size_t len, size_t index, size_t total) { + if (_onBody) + _onBody(request, data, len, index, total); +} \ No newline at end of file diff --git a/src/WebRequest.cpp b/src/WebRequest.cpp index 67453e11c..ff369b2cf 100644 --- a/src/WebRequest.cpp +++ b/src/WebRequest.cpp @@ -636,6 +636,22 @@ const AsyncWebHeader* AsyncWebServerRequest::getHeader(size_t num) const { return &(*std::next(_headers.cbegin(), num)); } +size_t AsyncWebServerRequest::getHeaderNames(std::vector& names) const { + names.clear(); + const size_t size = _headers.size(); + names.reserve(size); + for (const auto& h : _headers) { + names.push_back(h.name().c_str()); + } + return size; +} + +bool AsyncWebServerRequest::removeHeader(const char* name) { + const size_t size = _headers.size(); + _headers.remove_if([name](const AsyncWebHeader& header) { return header.name().equalsIgnoreCase(name); }); + return size != _headers.size(); +} + size_t AsyncWebServerRequest::params() const { return _params.size(); } @@ -670,6 +686,27 @@ const AsyncWebParameter* AsyncWebServerRequest::getParam(size_t num) const { return &(*std::next(_params.cbegin(), num)); } +const String& AsyncWebServerRequest::getAttribute(const char* name, const String& defaultValue) const { + auto it = _attributes.find(name); + return it != _attributes.end() ? it->second : defaultValue; +} +bool AsyncWebServerRequest::getAttribute(const char* name, bool defaultValue) const { + auto it = _attributes.find(name); + return it != _attributes.end() ? it->second == "1" : defaultValue; +} +long AsyncWebServerRequest::getAttribute(const char* name, long defaultValue) const { + auto it = _attributes.find(name); + return it != _attributes.end() ? it->second.toInt() : defaultValue; +} +float AsyncWebServerRequest::getAttribute(const char* name, float defaultValue) const { + auto it = _attributes.find(name); + return it != _attributes.end() ? it->second.toFloat() : defaultValue; +} +double AsyncWebServerRequest::getAttribute(const char* name, double defaultValue) const { + auto it = _attributes.find(name); + return it != _attributes.end() ? it->second.toDouble() : defaultValue; +} + AsyncWebServerResponse* AsyncWebServerRequest::beginResponse(int code, const char* contentType, const char* content, AwsTemplateProcessor callback) { if (callback) return new AsyncProgmemResponse(code, contentType, (const uint8_t*)content, strlen(content), callback); From 319e10c210eb299dc1fd9e03c0cd10d280a577c3 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Sun, 29 Sep 2024 21:52:30 +0200 Subject: [PATCH 387/551] AsyncWebSocketClient: Fix inconsistent queueLen() in relation to canSend() amd queueIsFull() --- src/AsyncWebSocket.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/AsyncWebSocket.cpp b/src/AsyncWebSocket.cpp index 4f2925eb2..b040a9f2c 100644 --- a/src/AsyncWebSocket.cpp +++ b/src/AsyncWebSocket.cpp @@ -381,7 +381,7 @@ size_t AsyncWebSocketClient::queueLen() const { std::lock_guard lock(_lock); #endif - return _messageQueue.size() + _controlQueue.size(); + return _messageQueue.size(); } bool AsyncWebSocketClient::canSend() const { From 6a247c1967651c9c3ce2c5be0d29f6ebf35352a5 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Sun, 29 Sep 2024 22:57:54 +0200 Subject: [PATCH 388/551] Cleanups --- src/AsyncEventSource.h | 1 - src/AsyncWebSocket.h | 2 -- src/WebRequest.cpp | 1 - 3 files changed, 4 deletions(-) diff --git a/src/AsyncEventSource.h b/src/AsyncEventSource.h index 1c688b0c6..9fc4b7add 100644 --- a/src/AsyncEventSource.h +++ b/src/AsyncEventSource.h @@ -21,7 +21,6 @@ #define ASYNCEVENTSOURCE_H_ #include -#include #ifdef ESP32 #include #include diff --git a/src/AsyncWebSocket.h b/src/AsyncWebSocket.h index a832a2d3d..2fe14d18d 100644 --- a/src/AsyncWebSocket.h +++ b/src/AsyncWebSocket.h @@ -42,8 +42,6 @@ #include -#include -#include #include #ifdef ESP8266 diff --git a/src/WebRequest.cpp b/src/WebRequest.cpp index ff369b2cf..daa9e0780 100644 --- a/src/WebRequest.cpp +++ b/src/WebRequest.cpp @@ -637,7 +637,6 @@ const AsyncWebHeader* AsyncWebServerRequest::getHeader(size_t num) const { } size_t AsyncWebServerRequest::getHeaderNames(std::vector& names) const { - names.clear(); const size_t size = _headers.size(); names.reserve(size); for (const auto& h : _headers) { From 3bd4eb82a4eb07fe000894ac21c19cfdac396f56 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Sun, 29 Sep 2024 23:16:18 +0200 Subject: [PATCH 389/551] Fix include directives to make ArduinoJson optional and fix CI --- .github/workflows/ci.yml | 3 ++ examples/SimpleServer/SimpleServer.ino | 16 +++++-- platformio.ini | 13 ++++++ src/AsyncJson.cpp | 58 ++++++++++++++------------ src/AsyncJson.h | 58 +++++++++++++++----------- src/AsyncMessagePack.cpp | 4 ++ src/AsyncMessagePack.h | 14 +++++-- 7 files changed, 109 insertions(+), 57 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8089c6a0c..ef80fafd1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -106,6 +106,9 @@ jobs: - env: ci-arduino-3 board: esp32-h2-devkitm-1 + - env: ci-arduino-3-no-json + board: esp32dev + - env: ci-arduino-310rc1 board: esp32dev - env: ci-arduino-310rc1 diff --git a/examples/SimpleServer/SimpleServer.ino b/examples/SimpleServer/SimpleServer.ino index b37ba6aab..67419d590 100644 --- a/examples/SimpleServer/SimpleServer.ino +++ b/examples/SimpleServer/SimpleServer.ino @@ -19,9 +19,12 @@ #include -#include -#include -#include +#if ASYNC_JSON_SUPPORT == 1 + #include + #include + #include +#endif + #include AsyncWebServer server(80); @@ -103,8 +106,10 @@ void notFound(AsyncWebServerRequest* request) { request->send(404, "text/plain", "Not found"); } +#if ASYNC_JSON_SUPPORT == 1 AsyncCallbackJsonWebHandler* jsonHandler = new AsyncCallbackJsonWebHandler("/json2"); AsyncCallbackMessagePackWebHandler* msgPackHandler = new AsyncCallbackMessagePackWebHandler("/msgpack2"); +#endif void setup() { @@ -293,6 +298,7 @@ void setup() { request->send(200, "text/plain", "Hello, POST: " + message); }); +#if ASYNC_JSON_SUPPORT == 1 // JSON // receives JSON and sends JSON @@ -338,6 +344,7 @@ void setup() { response->setLength(); request->send(response); }); +#endif events.onConnect([](AsyncEventSourceClient* client) { if (client->lastId()) { @@ -376,8 +383,11 @@ void setup() { server.addHandler(&events); server.addHandler(&ws); + +#if ASYNC_JSON_SUPPORT == 1 server.addHandler(jsonHandler); server.addHandler(msgPackHandler); +#endif server.onNotFound(notFound); diff --git a/platformio.ini b/platformio.ini index 661e4a645..d242032b9 100644 --- a/platformio.ini +++ b/platformio.ini @@ -36,6 +36,13 @@ platform = https://github.com/pioarduino/platform-espressif32/releases/download/ ; board = esp32-s3-devkitc-1 ; board = esp32-c6-devkitc-1 +[env:arduino-3-no-json] +platform = https://github.com/pioarduino/platform-espressif32/releases/download/51.03.05/platform-espressif32.zip +; board = esp32-s3-devkitc-1 +; board = esp32-c6-devkitc-1 +lib_deps = + mathieucarbou/AsyncTCP @ 3.2.5 + [env:arduino-310rc1] platform = https://github.com/pioarduino/platform-espressif32/releases/download/53.03.10-rc1/platform-espressif32.zip ; board = esp32-s3-devkitc-1 @@ -74,6 +81,12 @@ board = ${sysenv.PIO_BOARD} platform = https://github.com/pioarduino/platform-espressif32/releases/download/51.03.05/platform-espressif32.zip board = ${sysenv.PIO_BOARD} +[env:ci-arduino-3-no-json] +platform = https://github.com/pioarduino/platform-espressif32/releases/download/51.03.05/platform-espressif32.zip +board = ${sysenv.PIO_BOARD} +lib_deps = + mathieucarbou/AsyncTCP @ 3.2.5 + [env:ci-arduino-310rc1] platform = https://github.com/pioarduino/platform-espressif32/releases/download/53.03.10-rc1/platform-espressif32.zip board = ${sysenv.PIO_BOARD} diff --git a/src/AsyncJson.cpp b/src/AsyncJson.cpp index 511f2ecc4..ec464d131 100644 --- a/src/AsyncJson.cpp +++ b/src/AsyncJson.cpp @@ -1,6 +1,8 @@ #include "AsyncJson.h" -#if ARDUINOJSON_VERSION_MAJOR == 5 +#if ASYNC_JSON_SUPPORT == 1 + + #if ARDUINOJSON_VERSION_MAJOR == 5 AsyncJsonResponse::AsyncJsonResponse(bool isArray) : _isValid{false} { _code = 200; _contentType = JSON_MIMETYPE; @@ -9,7 +11,7 @@ AsyncJsonResponse::AsyncJsonResponse(bool isArray) : _isValid{false} { else _root = _jsonBuffer.createObject(); } -#elif ARDUINOJSON_VERSION_MAJOR == 6 + #elif ARDUINOJSON_VERSION_MAJOR == 6 AsyncJsonResponse::AsyncJsonResponse(bool isArray, size_t maxJsonBufferSize) : _jsonBuffer(maxJsonBufferSize), _isValid{false} { _code = 200; _contentType = JSON_MIMETYPE; @@ -18,7 +20,7 @@ AsyncJsonResponse::AsyncJsonResponse(bool isArray, size_t maxJsonBufferSize) : _ else _root = _jsonBuffer.createNestedObject(); } -#else + #else AsyncJsonResponse::AsyncJsonResponse(bool isArray) : _isValid{false} { _code = 200; _contentType = JSON_MIMETYPE; @@ -27,14 +29,14 @@ AsyncJsonResponse::AsyncJsonResponse(bool isArray) : _isValid{false} { else _root = _jsonBuffer.add(); } -#endif + #endif size_t AsyncJsonResponse::setLength() { -#if ARDUINOJSON_VERSION_MAJOR == 5 + #if ARDUINOJSON_VERSION_MAJOR == 5 _contentLength = _root.measureLength(); -#else + #else _contentLength = measureJson(_root); -#endif + #endif if (_contentLength) { _isValid = true; } @@ -43,26 +45,26 @@ size_t AsyncJsonResponse::setLength() { size_t AsyncJsonResponse::_fillBuffer(uint8_t* data, size_t len) { ChunkPrint dest(data, _sentLength, len); -#if ARDUINOJSON_VERSION_MAJOR == 5 + #if ARDUINOJSON_VERSION_MAJOR == 5 _root.printTo(dest); -#else + #else serializeJson(_root, dest); -#endif + #endif return len; } -#if ARDUINOJSON_VERSION_MAJOR == 6 + #if ARDUINOJSON_VERSION_MAJOR == 6 PrettyAsyncJsonResponse::PrettyAsyncJsonResponse(bool isArray, size_t maxJsonBufferSize) : AsyncJsonResponse{isArray, maxJsonBufferSize} {} -#else + #else PrettyAsyncJsonResponse::PrettyAsyncJsonResponse(bool isArray) : AsyncJsonResponse{isArray} {} -#endif + #endif size_t PrettyAsyncJsonResponse::setLength() { -#if ARDUINOJSON_VERSION_MAJOR == 5 + #if ARDUINOJSON_VERSION_MAJOR == 5 _contentLength = _root.measurePrettyLength(); -#else + #else _contentLength = measureJsonPretty(_root); -#endif + #endif if (_contentLength) { _isValid = true; } @@ -71,21 +73,21 @@ size_t PrettyAsyncJsonResponse::setLength() { size_t PrettyAsyncJsonResponse::_fillBuffer(uint8_t* data, size_t len) { ChunkPrint dest(data, _sentLength, len); -#if ARDUINOJSON_VERSION_MAJOR == 5 + #if ARDUINOJSON_VERSION_MAJOR == 5 _root.prettyPrintTo(dest); -#else + #else serializeJsonPretty(_root, dest); -#endif + #endif return len; } -#if ARDUINOJSON_VERSION_MAJOR == 6 + #if ARDUINOJSON_VERSION_MAJOR == 6 AsyncCallbackJsonWebHandler::AsyncCallbackJsonWebHandler(const String& uri, ArJsonRequestHandlerFunction onRequest, size_t maxJsonBufferSize) : _uri(uri), _method(HTTP_GET | HTTP_POST | HTTP_PUT | HTTP_PATCH), _onRequest(onRequest), maxJsonBufferSize(maxJsonBufferSize), _maxContentLength(16384) {} -#else + #else AsyncCallbackJsonWebHandler::AsyncCallbackJsonWebHandler(const String& uri, ArJsonRequestHandlerFunction onRequest) : _uri(uri), _method(HTTP_GET | HTTP_POST | HTTP_PUT | HTTP_PATCH), _onRequest(onRequest), _maxContentLength(16384) {} -#endif + #endif bool AsyncCallbackJsonWebHandler::canHandle(AsyncWebServerRequest* request) { if (!_onRequest) @@ -112,21 +114,21 @@ void AsyncCallbackJsonWebHandler::handleRequest(AsyncWebServerRequest* request) return; } else if (request->_tempObject != NULL) { -#if ARDUINOJSON_VERSION_MAJOR == 5 + #if ARDUINOJSON_VERSION_MAJOR == 5 DynamicJsonBuffer jsonBuffer; JsonVariant json = jsonBuffer.parse((uint8_t*)(request->_tempObject)); if (json.success()) { -#elif ARDUINOJSON_VERSION_MAJOR == 6 + #elif ARDUINOJSON_VERSION_MAJOR == 6 DynamicJsonDocument jsonBuffer(this->maxJsonBufferSize); DeserializationError error = deserializeJson(jsonBuffer, (uint8_t*)(request->_tempObject)); if (!error) { JsonVariant json = jsonBuffer.as(); -#else + #else JsonDocument jsonBuffer; DeserializationError error = deserializeJson(jsonBuffer, (uint8_t*)(request->_tempObject)); if (!error) { JsonVariant json = jsonBuffer.as(); -#endif + #endif _onRequest(request, json); return; @@ -148,4 +150,6 @@ void AsyncCallbackJsonWebHandler::handleBody(AsyncWebServerRequest* request, uin memcpy((uint8_t*)(request->_tempObject) + index, data, len); } } -} \ No newline at end of file +} + +#endif // ASYNC_JSON_SUPPORT diff --git a/src/AsyncJson.h b/src/AsyncJson.h index 0e7e61d93..e0d88f0d6 100644 --- a/src/AsyncJson.h +++ b/src/AsyncJson.h @@ -34,16 +34,21 @@ */ #ifndef ASYNC_JSON_H_ #define ASYNC_JSON_H_ -#include -#include -#include "ChunkPrint.h" +#if __has_include("ArduinoJson.h") -#if ARDUINOJSON_VERSION_MAJOR == 6 - #ifndef DYNAMIC_JSON_DOCUMENT_SIZE - #define DYNAMIC_JSON_DOCUMENT_SIZE 1024 + #define ASYNC_JSON_SUPPORT 1 + + #include + #include + + #include "ChunkPrint.h" + + #if ARDUINOJSON_VERSION_MAJOR == 6 + #ifndef DYNAMIC_JSON_DOCUMENT_SIZE + #define DYNAMIC_JSON_DOCUMENT_SIZE 1024 + #endif #endif -#endif constexpr const char* JSON_MIMETYPE = "application/json"; @@ -53,40 +58,40 @@ constexpr const char* JSON_MIMETYPE = "application/json"; class AsyncJsonResponse : public AsyncAbstractResponse { protected: -#if ARDUINOJSON_VERSION_MAJOR == 5 + #if ARDUINOJSON_VERSION_MAJOR == 5 DynamicJsonBuffer _jsonBuffer; -#elif ARDUINOJSON_VERSION_MAJOR == 6 + #elif ARDUINOJSON_VERSION_MAJOR == 6 DynamicJsonDocument _jsonBuffer; -#else + #else JsonDocument _jsonBuffer; -#endif + #endif JsonVariant _root; bool _isValid; public: -#if ARDUINOJSON_VERSION_MAJOR == 6 + #if ARDUINOJSON_VERSION_MAJOR == 6 AsyncJsonResponse(bool isArray = false, size_t maxJsonBufferSize = DYNAMIC_JSON_DOCUMENT_SIZE); -#else + #else AsyncJsonResponse(bool isArray = false); -#endif + #endif JsonVariant& getRoot() { return _root; } bool _sourceValid() const { return _isValid; } size_t setLength(); size_t getSize() const { return _jsonBuffer.size(); } size_t _fillBuffer(uint8_t* data, size_t len); -#if ARDUINOJSON_VERSION_MAJOR >= 6 + #if ARDUINOJSON_VERSION_MAJOR >= 6 bool overflowed() const { return _jsonBuffer.overflowed(); } -#endif + #endif }; class PrettyAsyncJsonResponse : public AsyncJsonResponse { public: -#if ARDUINOJSON_VERSION_MAJOR == 6 + #if ARDUINOJSON_VERSION_MAJOR == 6 PrettyAsyncJsonResponse(bool isArray = false, size_t maxJsonBufferSize = DYNAMIC_JSON_DOCUMENT_SIZE); -#else + #else PrettyAsyncJsonResponse(bool isArray = false); -#endif + #endif size_t setLength(); size_t _fillBuffer(uint8_t* data, size_t len); }; @@ -99,17 +104,17 @@ class AsyncCallbackJsonWebHandler : public AsyncWebHandler { WebRequestMethodComposite _method; ArJsonRequestHandlerFunction _onRequest; size_t _contentLength; -#if ARDUINOJSON_VERSION_MAJOR == 6 + #if ARDUINOJSON_VERSION_MAJOR == 6 const size_t maxJsonBufferSize; -#endif + #endif size_t _maxContentLength; public: -#if ARDUINOJSON_VERSION_MAJOR == 6 + #if ARDUINOJSON_VERSION_MAJOR == 6 AsyncCallbackJsonWebHandler(const String& uri, ArJsonRequestHandlerFunction onRequest = nullptr, size_t maxJsonBufferSize = DYNAMIC_JSON_DOCUMENT_SIZE); -#else + #else AsyncCallbackJsonWebHandler(const String& uri, ArJsonRequestHandlerFunction onRequest = nullptr); -#endif + #endif void setMethod(WebRequestMethodComposite method) { _method = method; } void setMaxContentLength(int maxContentLength) { _maxContentLength = maxContentLength; } @@ -121,4 +126,9 @@ class AsyncCallbackJsonWebHandler : public AsyncWebHandler { virtual void handleBody(AsyncWebServerRequest* request, uint8_t* data, size_t len, size_t index, size_t total) override final; virtual bool isRequestHandlerTrivial() override final { return !_onRequest; } }; + +#else // __has_include("ArduinoJson.h") + #define ASYNC_JSON_SUPPORT 0 +#endif // __has_include("ArduinoJson.h") + #endif diff --git a/src/AsyncMessagePack.cpp b/src/AsyncMessagePack.cpp index 65827d7c9..27e078684 100644 --- a/src/AsyncMessagePack.cpp +++ b/src/AsyncMessagePack.cpp @@ -1,5 +1,7 @@ #include "AsyncMessagePack.h" +#if ASYNC_MSG_PACK_SUPPORT == 1 + AsyncMessagePackResponse::AsyncMessagePackResponse(bool isArray) : _isValid{false} { _code = 200; _contentType = asyncsrv::T_application_msgpack; @@ -77,3 +79,5 @@ void AsyncCallbackMessagePackWebHandler::handleBody(AsyncWebServerRequest* reque } } } + +#endif // ASYNC_MSG_PACK_SUPPORT diff --git a/src/AsyncMessagePack.h b/src/AsyncMessagePack.h index 16104ef6e..cfb990259 100644 --- a/src/AsyncMessagePack.h +++ b/src/AsyncMessagePack.h @@ -21,10 +21,14 @@ server.addHandler(handler); */ -#include -#include +#if __has_include("ArduinoJson.h") -#include "ChunkPrint.h" + #define ASYNC_MSG_PACK_SUPPORT 1 + + #include + #include + + #include "ChunkPrint.h" class AsyncMessagePackResponse : public AsyncAbstractResponse { protected: @@ -65,3 +69,7 @@ class AsyncCallbackMessagePackWebHandler : public AsyncWebHandler { virtual void handleBody(AsyncWebServerRequest* request, uint8_t* data, size_t len, size_t index, size_t total) override final; virtual bool isRequestHandlerTrivial() override final { return _onRequest ? false : true; } }; + +#else // __has_include("ArduinoJson.h") + #define ASYNC_MSG_PACK_SUPPORT 0 +#endif // __has_include("ArduinoJson.h") From 5fbab6ce0c97a0b9f9fddb4c2eeaca02484788b6 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Sun, 29 Sep 2024 23:01:17 +0200 Subject: [PATCH 390/551] v3.3.2 --- README.md | 2 +- docs/index.md | 2 +- library.json | 2 +- library.properties | 2 +- src/ESPAsyncWebServer.h | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 95181419a..4c9d32f0e 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo **WARNING** The library name was changed from `ESP Async WebServer` to `ESPAsyncWebServer` as per the Arduino Lint recommendations. ``` -mathieucarbou/ESPAsyncWebServer @ 3.3.1 +mathieucarbou/ESPAsyncWebServer @ 3.3.2 ``` Dependency: diff --git a/docs/index.md b/docs/index.md index 95181419a..4c9d32f0e 100644 --- a/docs/index.md +++ b/docs/index.md @@ -30,7 +30,7 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo **WARNING** The library name was changed from `ESP Async WebServer` to `ESPAsyncWebServer` as per the Arduino Lint recommendations. ``` -mathieucarbou/ESPAsyncWebServer @ 3.3.1 +mathieucarbou/ESPAsyncWebServer @ 3.3.2 ``` Dependency: diff --git a/library.json b/library.json index 527a17a33..2f67fc03a 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "ESPAsyncWebServer", - "version": "3.3.1", + "version": "3.3.2", "description": "Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 and RP2040. Supports: WebSocket, SSE, Authentication, Arduino Json 7, File Upload, Static File serving, URL Rewrite, URL Redirect, etc.", "keywords": "http,async,websocket,webserver", "homepage": "https://github.com/mathieucarbou/ESPAsyncWebServer", diff --git a/library.properties b/library.properties index 02de7c436..402beb28e 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=ESPAsyncWebServer -version=3.3.1 +version=3.3.2 author=Me-No-Dev maintainer=Mathieu Carbou sentence=Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 and RP2040 diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index 621a9c814..96a129e95 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -48,10 +48,10 @@ #include "literals.h" -#define ASYNCWEBSERVER_VERSION "3.3.1" +#define ASYNCWEBSERVER_VERSION "3.3.2" #define ASYNCWEBSERVER_VERSION_MAJOR 3 #define ASYNCWEBSERVER_VERSION_MINOR 3 -#define ASYNCWEBSERVER_VERSION_REVISION 0 +#define ASYNCWEBSERVER_VERSION_REVISION 2 #define ASYNCWEBSERVER_FORK_mathieucarbou #ifdef ASYNCWEBSERVER_REGEX From e75dd5b02d29eaaeaa2127d41c05726cde737484 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Mon, 30 Sep 2024 00:51:36 +0200 Subject: [PATCH 391/551] Fix compilation issue with ArduinoJson 5 and 6 (closes #108) --- platformio.ini | 2 ++ src/AsyncJson.cpp | 8 +++--- src/AsyncJson.h | 23 ++++++++--------- src/AsyncMessagePack.cpp | 29 ++++++++++++++++++--- src/AsyncMessagePack.h | 55 ++++++++++++++++++++++++++++++---------- 5 files changed, 83 insertions(+), 34 deletions(-) diff --git a/platformio.ini b/platformio.ini index d242032b9..c65037645 100644 --- a/platformio.ini +++ b/platformio.ini @@ -24,6 +24,8 @@ upload_protocol = esptool monitor_speed = 115200 monitor_filters = esp32_exception_decoder, log2file lib_deps = + ; bblanchon/ArduinoJson @ 5.13.4 + ; bblanchon/ArduinoJson @ 6.21.5 bblanchon/ArduinoJson @ 7.2.0 mathieucarbou/AsyncTCP @ 3.2.5 board = esp32dev diff --git a/src/AsyncJson.cpp b/src/AsyncJson.cpp index ec464d131..7117a707e 100644 --- a/src/AsyncJson.cpp +++ b/src/AsyncJson.cpp @@ -5,7 +5,7 @@ #if ARDUINOJSON_VERSION_MAJOR == 5 AsyncJsonResponse::AsyncJsonResponse(bool isArray) : _isValid{false} { _code = 200; - _contentType = JSON_MIMETYPE; + _contentType = asyncsrv::T_application_json; if (isArray) _root = _jsonBuffer.createArray(); else @@ -14,7 +14,7 @@ AsyncJsonResponse::AsyncJsonResponse(bool isArray) : _isValid{false} { #elif ARDUINOJSON_VERSION_MAJOR == 6 AsyncJsonResponse::AsyncJsonResponse(bool isArray, size_t maxJsonBufferSize) : _jsonBuffer(maxJsonBufferSize), _isValid{false} { _code = 200; - _contentType = JSON_MIMETYPE; + _contentType = asyncsrv::T_application_json; if (isArray) _root = _jsonBuffer.createNestedArray(); else @@ -23,7 +23,7 @@ AsyncJsonResponse::AsyncJsonResponse(bool isArray, size_t maxJsonBufferSize) : _ #else AsyncJsonResponse::AsyncJsonResponse(bool isArray) : _isValid{false} { _code = 200; - _contentType = JSON_MIMETYPE; + _contentType = asyncsrv::T_application_json; if (isArray) _root = _jsonBuffer.add(); else @@ -100,7 +100,7 @@ bool AsyncCallbackJsonWebHandler::canHandle(AsyncWebServerRequest* request) { if (_uri.length() && (_uri != request->url() && !request->url().startsWith(_uri + "/"))) return false; - if (request_method != HTTP_GET && !request->contentType().equalsIgnoreCase(JSON_MIMETYPE)) + if (request_method != HTTP_GET && !request->contentType().equalsIgnoreCase(asyncsrv::T_application_json)) return false; return true; diff --git a/src/AsyncJson.h b/src/AsyncJson.h index e0d88f0d6..6fc5eb771 100644 --- a/src/AsyncJson.h +++ b/src/AsyncJson.h @@ -36,10 +36,15 @@ #define ASYNC_JSON_H_ #if __has_include("ArduinoJson.h") - - #define ASYNC_JSON_SUPPORT 1 - #include + #if ARDUINOJSON_VERSION_MAJOR >= 5 + #define ASYNC_JSON_SUPPORT 1 + #else + #define ASYNC_JSON_SUPPORT 0 + #endif // ARDUINOJSON_VERSION_MAJOR >= 5 +#endif // __has_include("ArduinoJson.h") + +#if ASYNC_JSON_SUPPORT == 1 #include #include "ChunkPrint.h" @@ -50,12 +55,6 @@ #endif #endif -constexpr const char* JSON_MIMETYPE = "application/json"; - -/* - * Json Response - * */ - class AsyncJsonResponse : public AsyncAbstractResponse { protected: #if ARDUINOJSON_VERSION_MAJOR == 5 @@ -127,8 +126,6 @@ class AsyncCallbackJsonWebHandler : public AsyncWebHandler { virtual bool isRequestHandlerTrivial() override final { return !_onRequest; } }; -#else // __has_include("ArduinoJson.h") - #define ASYNC_JSON_SUPPORT 0 -#endif // __has_include("ArduinoJson.h") +#endif // ASYNC_JSON_SUPPORT == 1 -#endif +#endif // ASYNC_JSON_H_ diff --git a/src/AsyncMessagePack.cpp b/src/AsyncMessagePack.cpp index 27e078684..076f55867 100644 --- a/src/AsyncMessagePack.cpp +++ b/src/AsyncMessagePack.cpp @@ -2,6 +2,16 @@ #if ASYNC_MSG_PACK_SUPPORT == 1 + #if ARDUINOJSON_VERSION_MAJOR == 6 +AsyncMessagePackResponse::AsyncMessagePackResponse(bool isArray, size_t maxJsonBufferSize) : _jsonBuffer(maxJsonBufferSize), _isValid{false} { + _code = 200; + _contentType = asyncsrv::T_application_msgpack; + if (isArray) + _root = _jsonBuffer.createNestedArray(); + else + _root = _jsonBuffer.createNestedObject(); +} + #else AsyncMessagePackResponse::AsyncMessagePackResponse(bool isArray) : _isValid{false} { _code = 200; _contentType = asyncsrv::T_application_msgpack; @@ -10,6 +20,7 @@ AsyncMessagePackResponse::AsyncMessagePackResponse(bool isArray) : _isValid{fals else _root = _jsonBuffer.add(); } + #endif size_t AsyncMessagePackResponse::setLength() { _contentLength = measureMsgPack(_root); @@ -25,8 +36,13 @@ size_t AsyncMessagePackResponse::_fillBuffer(uint8_t* data, size_t len) { return len; } -AsyncCallbackMessagePackWebHandler::AsyncCallbackMessagePackWebHandler(const String& uri, ArJsonRequestHandlerFunction onRequest) + #if ARDUINOJSON_VERSION_MAJOR == 6 +AsyncCallbackMessagePackWebHandler::AsyncCallbackMessagePackWebHandler(const String& uri, ArMessagePackRequestHandlerFunction onRequest, size_t maxJsonBufferSize) + : _uri(uri), _method(HTTP_GET | HTTP_POST | HTTP_PUT | HTTP_PATCH), _onRequest(onRequest), maxJsonBufferSize(maxJsonBufferSize), _maxContentLength(16384) {} + #else +AsyncCallbackMessagePackWebHandler::AsyncCallbackMessagePackWebHandler(const String& uri, ArMessagePackRequestHandlerFunction onRequest) : _uri(uri), _method(HTTP_GET | HTTP_POST | HTTP_PUT | HTTP_PATCH), _onRequest(onRequest), _maxContentLength(16384) {} + #endif bool AsyncCallbackMessagePackWebHandler::canHandle(AsyncWebServerRequest* request) { if (!_onRequest) @@ -51,13 +67,20 @@ void AsyncCallbackMessagePackWebHandler::handleRequest(AsyncWebServerRequest* re JsonVariant json; _onRequest(request, json); return; - } else if (request->_tempObject != NULL) { + + #if ARDUINOJSON_VERSION_MAJOR == 6 + DynamicJsonDocument jsonBuffer(this->maxJsonBufferSize); + DeserializationError error = deserializeMsgPack(jsonBuffer, (uint8_t*)(request->_tempObject)); + if (!error) { + JsonVariant json = jsonBuffer.as(); + #else JsonDocument jsonBuffer; DeserializationError error = deserializeMsgPack(jsonBuffer, (uint8_t*)(request->_tempObject)); - if (!error) { JsonVariant json = jsonBuffer.as(); + #endif + _onRequest(request, json); return; } diff --git a/src/AsyncMessagePack.h b/src/AsyncMessagePack.h index cfb990259..3194b5af0 100644 --- a/src/AsyncMessagePack.h +++ b/src/AsyncMessagePack.h @@ -22,54 +22,81 @@ */ #if __has_include("ArduinoJson.h") - - #define ASYNC_MSG_PACK_SUPPORT 1 - #include + #if ARDUINOJSON_VERSION_MAJOR >= 6 + #define ASYNC_MSG_PACK_SUPPORT 1 + #else + #define ASYNC_MSG_PACK_SUPPORT 0 + #endif // ARDUINOJSON_VERSION_MAJOR >= 6 +#endif // __has_include("ArduinoJson.h") + +#if ASYNC_MSG_PACK_SUPPORT == 1 #include #include "ChunkPrint.h" + #if ARDUINOJSON_VERSION_MAJOR == 6 + #ifndef DYNAMIC_JSON_DOCUMENT_SIZE + #define DYNAMIC_JSON_DOCUMENT_SIZE 1024 + #endif + #endif + class AsyncMessagePackResponse : public AsyncAbstractResponse { protected: + #if ARDUINOJSON_VERSION_MAJOR == 6 + DynamicJsonDocument _jsonBuffer; + #else JsonDocument _jsonBuffer; + #endif + JsonVariant _root; bool _isValid; public: + #if ARDUINOJSON_VERSION_MAJOR == 6 + AsyncMessagePackResponse(bool isArray = false, size_t maxJsonBufferSize = DYNAMIC_JSON_DOCUMENT_SIZE); + #else AsyncMessagePackResponse(bool isArray = false); - + #endif JsonVariant& getRoot() { return _root; } bool _sourceValid() const { return _isValid; } size_t setLength(); size_t getSize() const { return _jsonBuffer.size(); } size_t _fillBuffer(uint8_t* data, size_t len); + #if ARDUINOJSON_VERSION_MAJOR >= 6 + bool overflowed() const { return _jsonBuffer.overflowed(); } + #endif }; -class AsyncCallbackMessagePackWebHandler : public AsyncWebHandler { - public: - typedef std::function ArJsonRequestHandlerFunction; +typedef std::function ArMessagePackRequestHandlerFunction; +class AsyncCallbackMessagePackWebHandler : public AsyncWebHandler { protected: const String _uri; WebRequestMethodComposite _method; - ArJsonRequestHandlerFunction _onRequest; + ArMessagePackRequestHandlerFunction _onRequest; size_t _contentLength; + #if ARDUINOJSON_VERSION_MAJOR == 6 + const size_t maxJsonBufferSize; + #endif size_t _maxContentLength; public: - AsyncCallbackMessagePackWebHandler(const String& uri, ArJsonRequestHandlerFunction onRequest = nullptr); + #if ARDUINOJSON_VERSION_MAJOR == 6 + AsyncCallbackMessagePackWebHandler(const String& uri, ArMessagePackRequestHandlerFunction onRequest = nullptr, size_t maxJsonBufferSize = DYNAMIC_JSON_DOCUMENT_SIZE); + #else + AsyncCallbackMessagePackWebHandler(const String& uri, ArMessagePackRequestHandlerFunction onRequest = nullptr); + #endif void setMethod(WebRequestMethodComposite method) { _method = method; } void setMaxContentLength(int maxContentLength) { _maxContentLength = maxContentLength; } - void onRequest(ArJsonRequestHandlerFunction fn) { _onRequest = fn; } + void onRequest(ArMessagePackRequestHandlerFunction fn) { _onRequest = fn; } + virtual bool canHandle(AsyncWebServerRequest* request) override final; virtual void handleRequest(AsyncWebServerRequest* request) override final; virtual void handleUpload(__unused AsyncWebServerRequest* request, __unused const String& filename, __unused size_t index, __unused uint8_t* data, __unused size_t len, __unused bool final) override final {} virtual void handleBody(AsyncWebServerRequest* request, uint8_t* data, size_t len, size_t index, size_t total) override final; - virtual bool isRequestHandlerTrivial() override final { return _onRequest ? false : true; } + virtual bool isRequestHandlerTrivial() override final { return !_onRequest; } }; -#else // __has_include("ArduinoJson.h") - #define ASYNC_MSG_PACK_SUPPORT 0 -#endif // __has_include("ArduinoJson.h") +#endif // ASYNC_MSG_PACK_SUPPORT == 1 From 786f7b924bb1065dd935f977d2d82433eb7847e8 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Mon, 30 Sep 2024 00:53:38 +0200 Subject: [PATCH 392/551] v3.3.3 --- README.md | 2 +- docs/index.md | 2 +- library.json | 2 +- library.properties | 2 +- src/ESPAsyncWebServer.h | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 4c9d32f0e..eb373f5b0 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo **WARNING** The library name was changed from `ESP Async WebServer` to `ESPAsyncWebServer` as per the Arduino Lint recommendations. ``` -mathieucarbou/ESPAsyncWebServer @ 3.3.2 +mathieucarbou/ESPAsyncWebServer @ 3.3.3 ``` Dependency: diff --git a/docs/index.md b/docs/index.md index 4c9d32f0e..eb373f5b0 100644 --- a/docs/index.md +++ b/docs/index.md @@ -30,7 +30,7 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo **WARNING** The library name was changed from `ESP Async WebServer` to `ESPAsyncWebServer` as per the Arduino Lint recommendations. ``` -mathieucarbou/ESPAsyncWebServer @ 3.3.2 +mathieucarbou/ESPAsyncWebServer @ 3.3.3 ``` Dependency: diff --git a/library.json b/library.json index 2f67fc03a..2d3c57068 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "ESPAsyncWebServer", - "version": "3.3.2", + "version": "3.3.3", "description": "Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 and RP2040. Supports: WebSocket, SSE, Authentication, Arduino Json 7, File Upload, Static File serving, URL Rewrite, URL Redirect, etc.", "keywords": "http,async,websocket,webserver", "homepage": "https://github.com/mathieucarbou/ESPAsyncWebServer", diff --git a/library.properties b/library.properties index 402beb28e..6e2e94962 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=ESPAsyncWebServer -version=3.3.2 +version=3.3.3 author=Me-No-Dev maintainer=Mathieu Carbou sentence=Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 and RP2040 diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index 96a129e95..28578842c 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -48,10 +48,10 @@ #include "literals.h" -#define ASYNCWEBSERVER_VERSION "3.3.2" +#define ASYNCWEBSERVER_VERSION "3.3.3" #define ASYNCWEBSERVER_VERSION_MAJOR 3 #define ASYNCWEBSERVER_VERSION_MINOR 3 -#define ASYNCWEBSERVER_VERSION_REVISION 2 +#define ASYNCWEBSERVER_VERSION_REVISION 3 #define ASYNCWEBSERVER_FORK_mathieucarbou #ifdef ASYNCWEBSERVER_REGEX From 2706a62299e0825d585784b7f64e518e4449af4c Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Mon, 30 Sep 2024 01:02:38 +0200 Subject: [PATCH 393/551] Fix CI issue with RPI platform repo --- platformio.ini | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platformio.ini b/platformio.ini index c65037645..b0a28f197 100644 --- a/platformio.ini +++ b/platformio.ini @@ -65,7 +65,7 @@ lib_deps = [env:raspberrypi] upload_protocol = picotool ; platform = raspberrypi -platform = https://github.com/maxgerhardt/platform-raspberrypi.git +platform = https://github.com/maxgerhardt/platform-raspberrypi.git#f2687073f73d554c9db41f29b4769fd9703f4e55 board = rpipicow lib_deps = bblanchon/ArduinoJson @ 7.2.0 @@ -102,7 +102,7 @@ lib_deps = [env:ci-raspberrypi] ; platform = raspberrypi -platform = https://github.com/maxgerhardt/platform-raspberrypi.git +platform = https://github.com/maxgerhardt/platform-raspberrypi.git#f2687073f73d554c9db41f29b4769fd9703f4e55 board = ${sysenv.PIO_BOARD} lib_deps = bblanchon/ArduinoJson @ 7.2.0 From cf9ae09db8db47eb09c95dde99794ebce94dc0ba Mon Sep 17 00:00:00 2001 From: Emil Muratov Date: Mon, 30 Sep 2024 12:07:45 +0900 Subject: [PATCH 394/551] add optional responce code to AsyncWebServerRequest::redirect() method Allows to specify differents redirect codes to use, i.e. 301/302, 307/308 --- src/ESPAsyncWebServer.h | 9 +++++---- src/WebRequest.cpp | 4 ++-- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index 28578842c..ebe0edf3d 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -288,12 +288,13 @@ class AsyncWebServerRequest { } /** - * @brief issue 302 redirect response + * @brief issue HTTP redirect responce with Location header * - * @param url + * @param url - url to redirect to + * @param code - responce code, default is 302 : temporary redirect */ - void redirect(const char* url); - void redirect(const String& url) { return redirect(url.c_str()); }; + void redirect(const char* url, int code = 302); + void redirect(const String& url, int code = 302) { return redirect(url.c_str(), code); }; void send(AsyncWebServerResponse* response); AsyncWebServerResponse* getResponse() const { return _response; } diff --git a/src/WebRequest.cpp b/src/WebRequest.cpp index daa9e0780..1ef83e54d 100644 --- a/src/WebRequest.cpp +++ b/src/WebRequest.cpp @@ -766,8 +766,8 @@ void AsyncWebServerRequest::send(AsyncWebServerResponse* response) { send(500); } -void AsyncWebServerRequest::redirect(const char* url) { - AsyncWebServerResponse* response = beginResponse(302); +void AsyncWebServerRequest::redirect(const char* url, int code) { + AsyncWebServerResponse* response = beginResponse(code); response->addHeader(T_LOCATION, url); send(response); } From c295c7b676e112b4fa1413469aaa10776ca880f7 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Mon, 30 Sep 2024 08:45:53 +0200 Subject: [PATCH 395/551] v3.3.4 --- README.md | 2 +- docs/index.md | 2 +- library.json | 2 +- library.properties | 2 +- src/ESPAsyncWebServer.h | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index eb373f5b0..54e3cb0e3 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo **WARNING** The library name was changed from `ESP Async WebServer` to `ESPAsyncWebServer` as per the Arduino Lint recommendations. ``` -mathieucarbou/ESPAsyncWebServer @ 3.3.3 +mathieucarbou/ESPAsyncWebServer @ 3.3.4 ``` Dependency: diff --git a/docs/index.md b/docs/index.md index eb373f5b0..54e3cb0e3 100644 --- a/docs/index.md +++ b/docs/index.md @@ -30,7 +30,7 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo **WARNING** The library name was changed from `ESP Async WebServer` to `ESPAsyncWebServer` as per the Arduino Lint recommendations. ``` -mathieucarbou/ESPAsyncWebServer @ 3.3.3 +mathieucarbou/ESPAsyncWebServer @ 3.3.4 ``` Dependency: diff --git a/library.json b/library.json index 2d3c57068..f05cad6ee 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "ESPAsyncWebServer", - "version": "3.3.3", + "version": "3.3.4", "description": "Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 and RP2040. Supports: WebSocket, SSE, Authentication, Arduino Json 7, File Upload, Static File serving, URL Rewrite, URL Redirect, etc.", "keywords": "http,async,websocket,webserver", "homepage": "https://github.com/mathieucarbou/ESPAsyncWebServer", diff --git a/library.properties b/library.properties index 6e2e94962..7d690f03c 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=ESPAsyncWebServer -version=3.3.3 +version=3.3.4 author=Me-No-Dev maintainer=Mathieu Carbou sentence=Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 and RP2040 diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index ebe0edf3d..6b6cb8465 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -48,10 +48,10 @@ #include "literals.h" -#define ASYNCWEBSERVER_VERSION "3.3.3" +#define ASYNCWEBSERVER_VERSION "3.3.4" #define ASYNCWEBSERVER_VERSION_MAJOR 3 #define ASYNCWEBSERVER_VERSION_MINOR 3 -#define ASYNCWEBSERVER_VERSION_REVISION 3 +#define ASYNCWEBSERVER_VERSION_REVISION 4 #define ASYNCWEBSERVER_FORK_mathieucarbou #ifdef ASYNCWEBSERVER_REGEX From 3e416accbd17bcc9697d06efaf033cb4d274162f Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Tue, 1 Oct 2024 01:48:17 +0200 Subject: [PATCH 396/551] Complete rework of AuthenticationMiddleware... - to align methods and enum with PsychicHttp and Arduino WebServer - to support hash - to pre-compute base64 / digest hash to speed up requests Closes #111 --- README.md | 4 +- docs/index.md | 4 +- examples/SimpleServer/SimpleServer.ino | 75 ++++++++++++++++++++++---- src/ESPAsyncWebServer.h | 49 ++++++++++------- src/Middleware.cpp | 57 ++++++++++++++++++++ src/WebAuthentication.cpp | 66 ++++++++++------------- src/WebAuthentication.h | 5 +- src/WebRequest.cpp | 63 ++++++++++++++++------ src/literals.h | 8 +-- 9 files changed, 240 insertions(+), 91 deletions(-) diff --git a/README.md b/README.md index 54e3cb0e3..28af01df7 100644 --- a/README.md +++ b/README.md @@ -193,10 +193,12 @@ AuthenticationMiddleware authMiddleware; // [...] -authMiddleware.setAuthType(AuthenticationMiddleware::AuthType::AUTH_DIGEST); +authMiddleware.setAuthType(AsyncAuthType::AUTH_DIGEST); authMiddleware.setRealm("My app name"); authMiddleware.setUsername("admin"); authMiddleware.setPassword("admin"); +authMiddleware.setAuthFailureMessage("Authentication failed"); +authMiddleware.generateHash(); // optimization to avoid generating the hash at each request // [...] diff --git a/docs/index.md b/docs/index.md index 54e3cb0e3..28af01df7 100644 --- a/docs/index.md +++ b/docs/index.md @@ -193,10 +193,12 @@ AuthenticationMiddleware authMiddleware; // [...] -authMiddleware.setAuthType(AuthenticationMiddleware::AuthType::AUTH_DIGEST); +authMiddleware.setAuthType(AsyncAuthType::AUTH_DIGEST); authMiddleware.setRealm("My app name"); authMiddleware.setUsername("admin"); authMiddleware.setPassword("admin"); +authMiddleware.setAuthFailureMessage("Authentication failed"); +authMiddleware.generateHash(); // optimization to avoid generating the hash at each request // [...] diff --git a/examples/SimpleServer/SimpleServer.ino b/examples/SimpleServer/SimpleServer.ino index 67419d590..b3e328159 100644 --- a/examples/SimpleServer/SimpleServer.ino +++ b/examples/SimpleServer/SimpleServer.ino @@ -50,8 +50,13 @@ HeaderFilterMiddleware headerFilter; // remove all headers from the incoming request except the ones provided in the constructor HeaderFreeMiddleware headerFree; +// basicAuth +AuthenticationMiddleware basicAuth; +AuthenticationMiddleware basicAuthHash; + // simple digest authentication -AuthenticationMiddleware simpleDigestAuth; +AuthenticationMiddleware digestAuth; +AuthenticationMiddleware digestAuthHash; // complex authentication which adds request attributes for the next middlewares and handler AsyncMiddlewareFunction complexAuth([](AsyncWebServerRequest* request, ArMiddlewareNext next) { @@ -177,9 +182,31 @@ void setup() { requestLogger.setOutput(Serial); - simpleDigestAuth.setUsername("admin"); - simpleDigestAuth.setPassword("admin"); - simpleDigestAuth.setRealm("MyApp"); + basicAuth.setUsername("admin"); + basicAuth.setPassword("admin"); + basicAuth.setRealm("MyApp"); + basicAuth.setAuthFailureMessage("Authentication failed"); + basicAuth.setAuthType(AsyncAuthType::AUTH_BASIC); + basicAuth.generateHash(); + + basicAuthHash.setUsername("admin"); + basicAuthHash.setPasswordHash("YWRtaW46YWRtaW4="); // BASE64(admin:admin) + basicAuthHash.setRealm("MyApp"); + basicAuthHash.setAuthFailureMessage("Authentication failed"); + basicAuthHash.setAuthType(AsyncAuthType::AUTH_BASIC); + + digestAuth.setUsername("admin"); + digestAuth.setPassword("admin"); + digestAuth.setRealm("MyApp"); + digestAuth.setAuthFailureMessage("Authentication failed"); + digestAuth.setAuthType(AsyncAuthType::AUTH_DIGEST); + digestAuth.generateHash(); + + digestAuthHash.setUsername("admin"); + digestAuthHash.setPasswordHash("f499b71f9a36d838b79268e145e132f7"); // MD5(user:realm:pass) + digestAuthHash.setRealm("MyApp"); + digestAuthHash.setAuthFailureMessage("Authentication failed"); + digestAuthHash.setAuthType(AsyncAuthType::AUTH_DIGEST); rateLimit.setMaxRequests(5); rateLimit.setWindowSize(10); @@ -225,15 +252,37 @@ void setup() { }) .addMiddleware(&headerFree); - // simple digest authentication - // curl -v -X GET -H "x-remove-me: value" --digest -u admin:admin http://192.168.4.1/middleware/auth-simple - server.on("/middleware/auth-simple", HTTP_GET, [](AsyncWebServerRequest* request) { + // basic authentication method + // curl -v -X GET -H "origin: http://192.168.4.1" -u admin:admin http://192.168.4.1/middleware/auth-basic + server.on("/middleware/auth-basic", HTTP_GET, [](AsyncWebServerRequest* request) { + request->send(200, "text/plain", "Hello, world!"); + }) + .addMiddleware(&basicAuth); + + // basic authentication method with hash + // curl -v -X GET -H "origin: http://192.168.4.1" -u admin:admin http://192.168.4.1/middleware/auth-basic-hash + server.on("/middleware/auth-basic-hash", HTTP_GET, [](AsyncWebServerRequest* request) { + request->send(200, "text/plain", "Hello, world!"); + }) + .addMiddleware(&basicAuthHash); + + // digest authentication + // curl -v -X GET -H "origin: http://192.168.4.1" -u admin:admin --digest http://192.168.4.1/middleware/auth-digest + server.on("/middleware/auth-digest", HTTP_GET, [](AsyncWebServerRequest* request) { + request->send(200, "text/plain", "Hello, world!"); + }) + .addMiddleware(&digestAuth); + + // digest authentication with hash + // curl -v -X GET -H "origin: http://192.168.4.1" -u admin:admin --digest http://192.168.4.1/middleware/auth-digest-hash + server.on("/middleware/auth-digest-hash", HTTP_GET, [](AsyncWebServerRequest* request) { request->send(200, "text/plain", "Hello, world!"); }) - .addMiddleware(&simpleDigestAuth); + .addMiddleware(&digestAuthHash); - // curl -v -X GET -H "x-remove-me: value" --digest -u user:password http://192.168.4.1/middleware/auth-complex - server.on("/middleware/auth-complex", HTTP_GET, [](AsyncWebServerRequest* request) { + // test digest auth with cors + // curl -v -X GET -H "origin: http://192.168.4.1" --digest -u user:password http://192.168.4.1/middleware/auth-custom + server.on("/middleware/auth-custom", HTTP_GET, [](AsyncWebServerRequest* request) { String buffer = "Hello "; buffer.concat(request->getAttribute("user")); buffer.concat(" with role: "); @@ -244,6 +293,12 @@ void setup() { /////////////////////////////////////////////////////////////////////// + // curl -v -X GET -H "origin: http://192.168.4.1" http://192.168.4.1/redirect + // curl -v -X POST -H "origin: http://192.168.4.1" http://192.168.4.1/redirect + server.on("/redirect", HTTP_GET | HTTP_POST, [](AsyncWebServerRequest* request) { + request->redirect("/"); + }); + server.on("/", HTTP_GET, [](AsyncWebServerRequest* request) { request->send(200, "text/plain", "Hello, world"); }); diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index 6b6cb8465..d3a1257c8 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -164,6 +164,15 @@ typedef enum { RCT_NOT_USED = -1, RCT_EVENT, RCT_MAX } RequestedConnectionType; +// this enum is similar to Arduino WebServer's AsyncAuthType and PsychicHttp +typedef enum { + AUTH_NONE = 0, + AUTH_BASIC, + AUTH_DIGEST, + AUTH_BEARER, + AUTH_OTHER, +} AsyncAuthType; + typedef std::function AwsResponseFiller; typedef std::function AwsTemplateProcessor; @@ -194,7 +203,7 @@ class AsyncWebServerRequest { String _boundary; String _authorization; RequestedConnectionType _reqconntype; - bool _isDigest; + AsyncAuthType _authMethod = AsyncAuthType::AUTH_NONE; bool _isMultipart; bool _isPlainPost; bool _expectingContinue; @@ -271,8 +280,9 @@ class AsyncWebServerRequest { // base64(user:pass) for basic or // user:realm:md5(user:realm:pass) for digest bool authenticate(const char* hash); - bool authenticate(const char* username, const char* password, const char* realm = NULL, bool passwordIsHash = false); - void requestAuthentication(const char* realm = NULL, bool isDigest = true); + bool authenticate(const char* username, const char* credentials, const char* realm = NULL, bool isHash = false); + void requestAuthentication(const char* realm = nullptr, bool isDigest = true) { requestAuthentication(isDigest ? AsyncAuthType::AUTH_DIGEST : AsyncAuthType::AUTH_BASIC, realm); } + void requestAuthentication(AsyncAuthType method, const char* realm = nullptr, const char* _authFailMsg = nullptr); void setHandler(AsyncWebHandler* handler) { _handler = handler; } @@ -554,28 +564,31 @@ class AsyncMiddlewareChain { // AuthenticationMiddleware is a middleware that checks if the request is authenticated class AuthenticationMiddleware : public AsyncMiddleware { public: - typedef enum { - AUTH_NONE, - AUTH_BASIC, - AUTH_DIGEST - } AuthType; - - void setUsername(const char* username) { _username = username; } - void setPassword(const char* password) { _password = password; } + void setUsername(const char* username); + void setPassword(const char* password); + void setPasswordHash(const char* hash); + void setRealm(const char* realm) { _realm = realm; } - void setPasswordIsHash(bool passwordIsHash) { _hash = passwordIsHash; } - void setAuthType(AuthType authType) { _authType = authType; } + void setAuthFailureMessage(const char* message) { _authFailMsg = message; } + void setAuthType(AsyncAuthType authMethod) { _authMethod = authMethod; } - bool allowed(AsyncWebServerRequest* request) { return _authType == AUTH_NONE || !_username.length() || !_password.length() || request->authenticate(_username.c_str(), _password.c_str(), _realm, _hash); } + // precompute and store the hash value based on the username, realm, and authMethod + // returns true if the hash was successfully generated and replaced + bool generateHash(); - void run(AsyncWebServerRequest* request, ArMiddlewareNext next) { return allowed(request) ? next() : request->requestAuthentication(_realm, _authType == AUTH_DIGEST); } + bool allowed(AsyncWebServerRequest* request); + + void run(AsyncWebServerRequest* request, ArMiddlewareNext next); private: String _username; - String _password; - const char* _realm = nullptr; + String _credentials; bool _hash = false; - AuthType _authType = AUTH_DIGEST; + + String _realm = asyncsrv::T_LOGIN_REQ; + AsyncAuthType _authMethod = AsyncAuthType::AUTH_NONE; + String _authFailMsg; + bool _hasCreds = false; }; using ArAuthorizeFunction = std::function; diff --git a/src/Middleware.cpp b/src/Middleware.cpp index 5dc3d0532..1c36ef66f 100644 --- a/src/Middleware.cpp +++ b/src/Middleware.cpp @@ -1,3 +1,4 @@ +#include "WebAuthentication.h" #include AsyncMiddlewareChain::~AsyncMiddlewareChain() { @@ -52,6 +53,62 @@ void AsyncMiddlewareChain::_runChain(AsyncWebServerRequest* request, ArMiddlewar return next(); } +void AuthenticationMiddleware::setUsername(const char* username) { + _username = username; + _hasCreds = _username.length() && _credentials.length(); +} + +void AuthenticationMiddleware::setPassword(const char* password) { + _credentials = password; + _hash = false; + _hasCreds = _username.length() && _credentials.length(); +} + +void AuthenticationMiddleware::setPasswordHash(const char* hash) { + _credentials = hash; + _hash = true; + _hasCreds = _username.length() && _credentials.length(); +} + +bool AuthenticationMiddleware::generateHash() { + // ensure we have all the necessary data + if (!_hasCreds) + return false; + + // if we already have a hash, do nothing + if (_hash) + return false; + + switch (_authMethod) { + case AsyncAuthType::AUTH_DIGEST: + _credentials = generateDigestHash(_username.c_str(), _credentials.c_str(), _realm.c_str()); + _hash = true; + return true; + + case AsyncAuthType::AUTH_BASIC: + _credentials = generateBasicHash(_username.c_str(), _credentials.c_str()); + _hash = true; + return true; + + default: + return false; + } +} + +bool AuthenticationMiddleware::allowed(AsyncWebServerRequest* request) { + if (_authMethod == AsyncAuthType::AUTH_NONE) + return true; + + if (!_hasCreds) + return false; + + return request->authenticate(_username.c_str(), _credentials.c_str(), _realm.c_str(), _hash); +} + +void AuthenticationMiddleware::run(AsyncWebServerRequest* request, ArMiddlewareNext next) { + return allowed(request) ? next() : request->requestAuthentication(_authMethod, _realm.c_str(), _authFailMsg.c_str()); +} + void HeaderFreeMiddleware::run(AsyncWebServerRequest* request, ArMiddlewareNext next) { std::vector reqHeaders; request->getHeaderNames(reqHeaders); diff --git a/src/WebAuthentication.cpp b/src/WebAuthentication.cpp index b5962fce2..304f25808 100644 --- a/src/WebAuthentication.cpp +++ b/src/WebAuthentication.cpp @@ -34,36 +34,34 @@ using namespace asyncsrv; bool checkBasicAuthentication(const char* hash, const char* username, const char* password) { if (username == NULL || password == NULL || hash == NULL) return false; + return generateBasicHash(username, password).equalsIgnoreCase(hash); +} + +String generateBasicHash(const char* username, const char* password) { + if (username == NULL || password == NULL) + return emptyString; size_t toencodeLen = strlen(username) + strlen(password) + 1; - size_t encodedLen = base64_encode_expected_len(toencodeLen); - if (strlen(hash) != encodedLen) -// Fix from https://github.com/me-no-dev/ESPAsyncWebServer/issues/667 -#ifdef ARDUINO_ARCH_ESP32 - if (strlen(hash) != encodedLen) -#else - if (strlen(hash) != encodedLen - 1) -#endif - return false; char* toencode = new char[toencodeLen + 1]; if (toencode == NULL) { - return false; + return emptyString; } char* encoded = new char[base64_encode_expected_len(toencodeLen) + 1]; if (encoded == NULL) { delete[] toencode; - return false; + return emptyString; } sprintf_P(toencode, PSTR("%s:%s"), username, password); - if (base64_encode_chars(toencode, toencodeLen, encoded) > 0 && memcmp(hash, encoded, encodedLen) == 0) { + if (base64_encode_chars(toencode, toencodeLen, encoded) > 0) { + String res = String(encoded); delete[] toencode; delete[] encoded; - return true; + return res; } delete[] toencode; delete[] encoded; - return false; + return emptyString; } static bool getMD5(uint8_t* data, uint16_t len, char* output) { // 33 bytes or more @@ -94,7 +92,7 @@ static bool getMD5(uint8_t* data, uint16_t len, char* output) { // 33 bytes or m return true; } -static String genRandomMD5() { +String genRandomMD5() { #ifdef ESP8266 uint32_t r = RANDOM_REG32; #else @@ -122,31 +120,21 @@ String generateDigestHash(const char* username, const char* password, const char return emptyString; } char* out = (char*)malloc(33); - String res = String(username); - res += ':'; - res.concat(realm); - res += ':'; - String in = res; + + String in; + in.reserve(strlen(username) + strlen(realm) + strlen(password) + 2); + in.concat(username); + in.concat(':'); + in.concat(realm); + in.concat(':'); in.concat(password); + if (out == NULL || !getMD5((uint8_t*)(in.c_str()), in.length(), out)) return emptyString; - res.concat(out); - free(out); - return res; -} -String requestDigestAuthentication(const char* realm) { - String header(T_realm__); - if (realm == NULL) - header.concat(T_asyncesp); - else - header.concat(realm); - header.concat(T_auth_nonce); - header.concat(genRandomMD5()); - header.concat(T__opaque); - header.concat(genRandomMD5()); - header += (char)0x22; // '"' - return header; + in = String(out); + free(out); + return in; } #ifndef ESP8266 @@ -235,9 +223,9 @@ bool checkDigestAuthentication(const char* header, const __FlashStringHelper* me } } while (nextBreak > 0); - String ha1 = (passwordIsHash) ? String(password) : stringMD5(myUsername + ':' + myRealm + ':' + password); - String ha2 = String(method) + ':' + myUri; - String response = ha1 + ':' + myNonce + ':' + myNc + ':' + myCnonce + ':' + myQop + ':' + stringMD5(ha2); + String ha1 = passwordIsHash ? password : stringMD5(myUsername + ':' + myRealm + ':' + password).c_str(); + String ha2 = stringMD5(String(method) + ':' + myUri); + String response = ha1 + ':' + myNonce + ':' + myNc + ':' + myCnonce + ':' + myQop + ':' + ha2; if (myResponse.equals(stringMD5(response))) { // os_printf("AUTH SUCCESS\n"); diff --git a/src/WebAuthentication.h b/src/WebAuthentication.h index d519777ca..a35d551be 100644 --- a/src/WebAuthentication.h +++ b/src/WebAuthentication.h @@ -25,7 +25,6 @@ #include "Arduino.h" bool checkBasicAuthentication(const char* header, const char* username, const char* password); -String requestDigestAuthentication(const char* realm); bool checkDigestAuthentication(const char* header, const char* method, const char* username, const char* password, const char* realm, bool passwordIsHash, const char* nonce, const char* opaque, const char* uri); @@ -36,4 +35,8 @@ bool checkDigestAuthentication(const char* header, const __FlashStringHelper* me // for storing hashed versions on the device that can be authenticated against String generateDigestHash(const char* username, const char* password, const char* realm); +String generateBasicHash(const char* username, const char* password); + +String genRandomMD5(); + #endif diff --git a/src/WebRequest.cpp b/src/WebRequest.cpp index 1ef83e54d..242a11171 100644 --- a/src/WebRequest.cpp +++ b/src/WebRequest.cpp @@ -35,7 +35,7 @@ enum { PARSE_REQ_START, PARSE_REQ_FAIL }; AsyncWebServerRequest::AsyncWebServerRequest(AsyncWebServer* s, AsyncClient* c) - : _client(c), _server(s), _handler(NULL), _response(NULL), _temp(), _parseState(0), _version(0), _method(HTTP_ANY), _url(), _host(), _contentType(), _boundary(), _authorization(), _reqconntype(RCT_HTTP), _isDigest(false), _isMultipart(false), _isPlainPost(false), _expectingContinue(false), _contentLength(0), _parsedLength(0), _multiParseState(0), _boundaryPosition(0), _itemStartIndex(0), _itemSize(0), _itemName(), _itemFilename(), _itemType(), _itemValue(), _itemBuffer(0), _itemBufferIndex(0), _itemIsFile(false), _tempObject(NULL) { + : _client(c), _server(s), _handler(NULL), _response(NULL), _temp(), _parseState(0), _version(0), _method(HTTP_ANY), _url(), _host(), _contentType(), _boundary(), _authorization(), _reqconntype(RCT_HTTP), _authMethod(AsyncAuthType::AUTH_NONE), _isMultipart(false), _isPlainPost(false), _expectingContinue(false), _contentLength(0), _parsedLength(0), _multiParseState(0), _boundaryPosition(0), _itemStartIndex(0), _itemSize(0), _itemName(), _itemFilename(), _itemType(), _itemValue(), _itemBuffer(0), _itemBufferIndex(0), _itemIsFile(false), _tempObject(NULL) { c->onError([](void* r, AsyncClient* c, int8_t error) { (void)c; AsyncWebServerRequest *req = (AsyncWebServerRequest*)r; req->_onError(error); }, this); c->onAck([](void* r, AsyncClient* c, size_t len, uint32_t time) { (void)c; AsyncWebServerRequest *req = (AsyncWebServerRequest*)r; req->_onAck(len, time); }, this); c->onDisconnect([](void* r, AsyncClient* c) { AsyncWebServerRequest *req = (AsyncWebServerRequest*)r; req->_onDisconnect(); delete c; }, this); @@ -285,9 +285,16 @@ bool AsyncWebServerRequest::_parseReqHeader() { } else if (name.equalsIgnoreCase(T_AUTH)) { if (value.length() > 5 && value.substring(0, 5).equalsIgnoreCase(T_BASIC)) { _authorization = value.substring(6); + _authMethod = AsyncAuthType::AUTH_BASIC; } else if (value.length() > 6 && value.substring(0, 6).equalsIgnoreCase(T_DIGEST)) { - _isDigest = true; + _authMethod = AsyncAuthType::AUTH_DIGEST; _authorization = value.substring(7); + } else if (value.length() > 6 && value.substring(0, 6).equalsIgnoreCase(T_BEARER)) { + _authMethod = AsyncAuthType::AUTH_BEARER; + _authorization = value.substring(7); + } else { + _authorization = value; + _authMethod = AsyncAuthType::AUTH_OTHER; } } else { if (name.equalsIgnoreCase(T_UPGRADE) && value.equalsIgnoreCase(T_WS)) { @@ -774,7 +781,7 @@ void AsyncWebServerRequest::redirect(const char* url, int code) { bool AsyncWebServerRequest::authenticate(const char* username, const char* password, const char* realm, bool passwordIsHash) { if (_authorization.length()) { - if (_isDigest) + if (_authMethod == AsyncAuthType::AUTH_DIGEST) return checkDigestAuthentication(_authorization.c_str(), methodToString(), username, password, realm, passwordIsHash, NULL, NULL, NULL); else if (!passwordIsHash) return checkBasicAuthentication(_authorization.c_str(), username, password); @@ -788,7 +795,7 @@ bool AsyncWebServerRequest::authenticate(const char* hash) { if (!_authorization.length() || hash == NULL) return false; - if (_isDigest) { + if (_authMethod == AsyncAuthType::AUTH_DIGEST) { String hStr = String(hash); int separator = hStr.indexOf(':'); if (separator <= 0) @@ -803,23 +810,45 @@ bool AsyncWebServerRequest::authenticate(const char* hash) { return checkDigestAuthentication(_authorization.c_str(), methodToString(), username.c_str(), hStr.c_str(), realm.c_str(), true, NULL, NULL, NULL); } + // Basic Auth, Bearer Auth, or other return (_authorization.equals(hash)); } -void AsyncWebServerRequest::requestAuthentication(const char* realm, bool isDigest) { - AsyncWebServerResponse* r = beginResponse(401); - if (!isDigest && realm == NULL) { - r->addHeader(T_WWW_AUTH, T_BASIC_REALM_LOGIN_REQ); - } else if (!isDigest) { - String header(T_BASIC_REALM); - header.concat(realm); - header += '"'; - r->addHeader(T_WWW_AUTH, header.c_str()); - } else { - String header(T_DIGEST_); - header.concat(requestDigestAuthentication(realm)); - r->addHeader(T_WWW_AUTH, header.c_str()); +void AsyncWebServerRequest::requestAuthentication(AsyncAuthType method, const char* realm, const char* _authFailMsg) { + if (!realm) + realm = T_LOGIN_REQ; + + AsyncWebServerResponse* r = _authFailMsg ? beginResponse(401, T_text_html, _authFailMsg) : beginResponse(401); + + switch (method) { + case AsyncAuthType::AUTH_BASIC: { + String header; + header.reserve(strlen(T_BASIC_REALM) + strlen(realm) + 1); + header.concat(T_BASIC_REALM); + header.concat(realm); + header.concat('"'); + r->addHeader(T_WWW_AUTH, header.c_str()); + break; + } + case AsyncAuthType::AUTH_DIGEST: { + constexpr size_t len = strlen(T_DIGEST_) + strlen(T_realm__) + strlen(T_auth_nonce) + 32 + strlen(T__opaque) + 32 + 1; + String header; + header.reserve(len + strlen(realm)); + header.concat(T_DIGEST_); + header.concat(T_realm__); + header.concat(realm); + header.concat(T_auth_nonce); + header.concat(genRandomMD5()); + header.concat(T__opaque); + header.concat(genRandomMD5()); + header.concat((char)0x22); // '"' + r->addHeader(T_WWW_AUTH, header.c_str()); + break; + } + default: + break; } + send(r); } diff --git a/src/literals.h b/src/literals.h index 15bf47ef0..2300b4af7 100644 --- a/src/literals.h +++ b/src/literals.h @@ -12,7 +12,7 @@ static constexpr const char* T_app_xform_urlencoded = "application/x-www-form-ur static constexpr const char* T_AUTH = "Authorization"; static constexpr const char* T_BASIC = "Basic"; static constexpr const char* T_BASIC_REALM = "Basic realm=\""; -static constexpr const char* T_BASIC_REALM_LOGIN_REQ = "Basic realm=\"Login Required\""; +static constexpr const char* T_LOGIN_REQ = "Login Required"; static constexpr const char* T_BODY = "body"; static constexpr const char* T_Cache_Control = "Cache-Control"; static constexpr const char* T_chunked = "chunked"; @@ -25,6 +25,7 @@ static constexpr const char* T_Content_Type = "Content-Type"; static constexpr const char* T_Cookie = "Cookie"; static constexpr const char* T_DIGEST = "Digest"; static constexpr const char* T_DIGEST_ = "Digest "; +static constexpr const char* T_BEARER = "Bearer"; static constexpr const char* T_ETag = "ETag"; static constexpr const char* T_EXPECT = "Expect"; static constexpr const char* T_HTTP_1_0 = "HTTP/1.0"; @@ -149,7 +150,6 @@ static constexpr const char* T_HTTP_CODE_ANY = "Unknown code"; // other static constexpr const char* T__opaque = "\", opaque=\""; static constexpr const char* T_13 = "13"; -static constexpr const char* T_asyncesp = "asyncesp"; static constexpr const char* T_auth_nonce = "\", qop=\"auth\", nonce=\""; static constexpr const char* T_cnonce = "cnonce"; static constexpr const char* T_data_ = "data: "; @@ -182,7 +182,7 @@ static const char T_app_xform_urlencoded[] PROGMEM = "application/x-www-form-url static const char T_AUTH[] PROGMEM = "Authorization"; static const char T_BASIC[] PROGMEM = "Basic"; static const char T_BASIC_REALM[] PROGMEM = "Basic realm=\""; -static const char T_BASIC_REALM_LOGIN_REQ[] PROGMEM = "Basic realm=\"Login Required\""; +static const char T_LOGIN_REQ[] PROGMEM = "Login Required"; static const char T_BODY[] PROGMEM = "body"; static const char T_Cache_Control[] PROGMEM = "Cache-Control"; static const char T_chunked[] PROGMEM = "chunked"; @@ -195,6 +195,7 @@ static const char T_Content_Type[] PROGMEM = "Content-Type"; static const char T_Cookie[] PROGMEM = "Cookie"; static const char T_DIGEST[] PROGMEM = "Digest"; static const char T_DIGEST_[] PROGMEM = "Digest "; +static const char T_BEARER[] PROGMEM = "Bearer"; static const char T_ETag[] PROGMEM = "ETag"; static const char T_EXPECT[] PROGMEM = "Expect"; static const char T_HTTP_1_0[] PROGMEM = "HTTP/1.0"; @@ -319,7 +320,6 @@ static const char T_HTTP_CODE_ANY[] PROGMEM = "Unknown code"; // other static const char T__opaque[] PROGMEM = "\", opaque=\""; static const char T_13[] PROGMEM = "13"; -static const char T_asyncesp[] PROGMEM = "asyncesp"; static const char T_auth_nonce[] PROGMEM = "\", qop=\"auth\", nonce=\""; static const char T_cnonce[] PROGMEM = "cnonce"; static const char T_data_[] PROGMEM = "data: "; From 0856ea6a62e4a2164f53f52dc060b27233547132 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Tue, 1 Oct 2024 02:40:58 +0200 Subject: [PATCH 397/551] v3.3.5 --- README.md | 2 +- docs/index.md | 2 +- library.json | 2 +- library.properties | 2 +- src/ESPAsyncWebServer.h | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 28af01df7..c6eae24ac 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo **WARNING** The library name was changed from `ESP Async WebServer` to `ESPAsyncWebServer` as per the Arduino Lint recommendations. ``` -mathieucarbou/ESPAsyncWebServer @ 3.3.4 +mathieucarbou/ESPAsyncWebServer @ 3.3.5 ``` Dependency: diff --git a/docs/index.md b/docs/index.md index 28af01df7..c6eae24ac 100644 --- a/docs/index.md +++ b/docs/index.md @@ -30,7 +30,7 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo **WARNING** The library name was changed from `ESP Async WebServer` to `ESPAsyncWebServer` as per the Arduino Lint recommendations. ``` -mathieucarbou/ESPAsyncWebServer @ 3.3.4 +mathieucarbou/ESPAsyncWebServer @ 3.3.5 ``` Dependency: diff --git a/library.json b/library.json index f05cad6ee..dfec6295b 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "ESPAsyncWebServer", - "version": "3.3.4", + "version": "3.3.5", "description": "Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 and RP2040. Supports: WebSocket, SSE, Authentication, Arduino Json 7, File Upload, Static File serving, URL Rewrite, URL Redirect, etc.", "keywords": "http,async,websocket,webserver", "homepage": "https://github.com/mathieucarbou/ESPAsyncWebServer", diff --git a/library.properties b/library.properties index 7d690f03c..b627d088e 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=ESPAsyncWebServer -version=3.3.4 +version=3.3.5 author=Me-No-Dev maintainer=Mathieu Carbou sentence=Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 and RP2040 diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index d3a1257c8..76fc12947 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -48,10 +48,10 @@ #include "literals.h" -#define ASYNCWEBSERVER_VERSION "3.3.4" +#define ASYNCWEBSERVER_VERSION "3.3.5" #define ASYNCWEBSERVER_VERSION_MAJOR 3 #define ASYNCWEBSERVER_VERSION_MINOR 3 -#define ASYNCWEBSERVER_VERSION_REVISION 4 +#define ASYNCWEBSERVER_VERSION_REVISION 5 #define ASYNCWEBSERVER_FORK_mathieucarbou #ifdef ASYNCWEBSERVER_REGEX From 3971bbd4422276cf530362e265511b5516af0640 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Tue, 1 Oct 2024 10:45:53 +0200 Subject: [PATCH 398/551] Removed const keywords --- src/AsyncJson.h | 4 ++-- src/AsyncMessagePack.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/AsyncJson.h b/src/AsyncJson.h index 6fc5eb771..167364a69 100644 --- a/src/AsyncJson.h +++ b/src/AsyncJson.h @@ -99,12 +99,12 @@ typedef std::function A class AsyncCallbackJsonWebHandler : public AsyncWebHandler { protected: - const String _uri; + String _uri; WebRequestMethodComposite _method; ArJsonRequestHandlerFunction _onRequest; size_t _contentLength; #if ARDUINOJSON_VERSION_MAJOR == 6 - const size_t maxJsonBufferSize; + size_t maxJsonBufferSize; #endif size_t _maxContentLength; diff --git a/src/AsyncMessagePack.h b/src/AsyncMessagePack.h index 3194b5af0..9ac5ee5c8 100644 --- a/src/AsyncMessagePack.h +++ b/src/AsyncMessagePack.h @@ -72,12 +72,12 @@ typedef std::function A class AsyncCallbackMessagePackWebHandler : public AsyncWebHandler { protected: - const String _uri; + String _uri; WebRequestMethodComposite _method; ArMessagePackRequestHandlerFunction _onRequest; size_t _contentLength; #if ARDUINOJSON_VERSION_MAJOR == 6 - const size_t maxJsonBufferSize; + size_t maxJsonBufferSize; #endif size_t _maxContentLength; From a0ff86e76d56188221f362dac0cd4e8354de65ca Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Tue, 1 Oct 2024 10:55:14 +0200 Subject: [PATCH 399/551] Fixed const getter which should be non const to access client api --- examples/SimpleServer/SimpleServer.ino | 4 ++++ src/AsyncWebSocket.h | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/examples/SimpleServer/SimpleServer.ino b/examples/SimpleServer/SimpleServer.ino index b3e328159..899c77db7 100644 --- a/examples/SimpleServer/SimpleServer.ino +++ b/examples/SimpleServer/SimpleServer.ino @@ -463,6 +463,10 @@ void loop() { } if (now - lastWS >= deltaWS) { ws.printfAll("kp%.4f", (10.0 / 3.0)); + // ws.getClients + for (auto& client : ws.getClients()) { + client.text("kp%.4f", (10.0 / 3.0)); + } lastWS = millis(); } } diff --git a/src/AsyncWebSocket.h b/src/AsyncWebSocket.h index 2fe14d18d..1da3d159c 100644 --- a/src/AsyncWebSocket.h +++ b/src/AsyncWebSocket.h @@ -351,7 +351,7 @@ class AsyncWebSocket : public AsyncWebHandler { AsyncWebSocketMessageBuffer* makeBuffer(size_t size = 0); AsyncWebSocketMessageBuffer* makeBuffer(const uint8_t* data, size_t size); - const std::list& getClients() const { return _clients; } + std::list& getClients() { return _clients; } }; // WebServer response to authenticate the socket and detach the tcp client from the web server request From 6fb4067f8e50fd4cfb107d934a263885ca7134d4 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Tue, 1 Oct 2024 10:58:46 +0200 Subject: [PATCH 400/551] v3.3.6 --- README.md | 2 +- docs/index.md | 2 +- library.json | 2 +- library.properties | 2 +- src/ESPAsyncWebServer.h | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index c6eae24ac..99b01bade 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo **WARNING** The library name was changed from `ESP Async WebServer` to `ESPAsyncWebServer` as per the Arduino Lint recommendations. ``` -mathieucarbou/ESPAsyncWebServer @ 3.3.5 +mathieucarbou/ESPAsyncWebServer @ 3.3.6 ``` Dependency: diff --git a/docs/index.md b/docs/index.md index c6eae24ac..99b01bade 100644 --- a/docs/index.md +++ b/docs/index.md @@ -30,7 +30,7 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo **WARNING** The library name was changed from `ESP Async WebServer` to `ESPAsyncWebServer` as per the Arduino Lint recommendations. ``` -mathieucarbou/ESPAsyncWebServer @ 3.3.5 +mathieucarbou/ESPAsyncWebServer @ 3.3.6 ``` Dependency: diff --git a/library.json b/library.json index dfec6295b..a6772b8f6 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "ESPAsyncWebServer", - "version": "3.3.5", + "version": "3.3.6", "description": "Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 and RP2040. Supports: WebSocket, SSE, Authentication, Arduino Json 7, File Upload, Static File serving, URL Rewrite, URL Redirect, etc.", "keywords": "http,async,websocket,webserver", "homepage": "https://github.com/mathieucarbou/ESPAsyncWebServer", diff --git a/library.properties b/library.properties index b627d088e..6ca1b38c9 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=ESPAsyncWebServer -version=3.3.5 +version=3.3.6 author=Me-No-Dev maintainer=Mathieu Carbou sentence=Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 and RP2040 diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index 76fc12947..b37cf9851 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -48,10 +48,10 @@ #include "literals.h" -#define ASYNCWEBSERVER_VERSION "3.3.5" +#define ASYNCWEBSERVER_VERSION "3.3.6" #define ASYNCWEBSERVER_VERSION_MAJOR 3 #define ASYNCWEBSERVER_VERSION_MINOR 3 -#define ASYNCWEBSERVER_VERSION_REVISION 5 +#define ASYNCWEBSERVER_VERSION_REVISION 6 #define ASYNCWEBSERVER_FORK_mathieucarbou #ifdef ASYNCWEBSERVER_REGEX From 041565a7d7d1ece5e8615f247f613e33591256c7 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Tue, 1 Oct 2024 11:11:27 +0200 Subject: [PATCH 401/551] Fix memory leak on successive call to setAuthentication (as reported in https://github.com/tbnobody/OpenDTU/pull/2320) --- src/ESPAsyncWebServer.h | 3 ++- src/WebHandlers.cpp | 14 +++++++------- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index b37cf9851..eb28473f8 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -717,7 +717,8 @@ class AsyncWebRewrite { class AsyncWebHandler : public AsyncMiddlewareChain { protected: - ArRequestFilterFunction _filter{nullptr}; + ArRequestFilterFunction _filter = nullptr; + AuthenticationMiddleware* _authMiddleware = nullptr; public: AsyncWebHandler() {} diff --git a/src/WebHandlers.cpp b/src/WebHandlers.cpp index ef976e5bd..7c3a7dc37 100644 --- a/src/WebHandlers.cpp +++ b/src/WebHandlers.cpp @@ -28,13 +28,13 @@ AsyncWebHandler& AsyncWebHandler::setFilter(ArRequestFilterFunction fn) { return *this; } AsyncWebHandler& AsyncWebHandler::setAuthentication(const char* username, const char* password) { - if (username == nullptr || password == nullptr || strlen(username) == 0 || strlen(password) == 0) - return *this; - AuthenticationMiddleware* m = new AuthenticationMiddleware(); - m->setUsername(username); - m->setPassword(password); - m->_freeOnRemoval = true; - addMiddleware(m); + if (!_authMiddleware) { + _authMiddleware = new AuthenticationMiddleware(); + _authMiddleware->_freeOnRemoval = true; + addMiddleware(_authMiddleware); + } + _authMiddleware->setUsername(username); + _authMiddleware->setPassword(password); return *this; }; From a60e0cac7359fd8835ccd0fa1f2a9e5faf763213 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Tue, 1 Oct 2024 11:14:21 +0200 Subject: [PATCH 402/551] v3.3.7 --- README.md | 2 +- docs/index.md | 2 +- library.json | 2 +- library.properties | 2 +- src/ESPAsyncWebServer.h | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 99b01bade..55efb4bf3 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo **WARNING** The library name was changed from `ESP Async WebServer` to `ESPAsyncWebServer` as per the Arduino Lint recommendations. ``` -mathieucarbou/ESPAsyncWebServer @ 3.3.6 +mathieucarbou/ESPAsyncWebServer @ 3.3.7 ``` Dependency: diff --git a/docs/index.md b/docs/index.md index 99b01bade..55efb4bf3 100644 --- a/docs/index.md +++ b/docs/index.md @@ -30,7 +30,7 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo **WARNING** The library name was changed from `ESP Async WebServer` to `ESPAsyncWebServer` as per the Arduino Lint recommendations. ``` -mathieucarbou/ESPAsyncWebServer @ 3.3.6 +mathieucarbou/ESPAsyncWebServer @ 3.3.7 ``` Dependency: diff --git a/library.json b/library.json index a6772b8f6..d22884244 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "ESPAsyncWebServer", - "version": "3.3.6", + "version": "3.3.7", "description": "Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 and RP2040. Supports: WebSocket, SSE, Authentication, Arduino Json 7, File Upload, Static File serving, URL Rewrite, URL Redirect, etc.", "keywords": "http,async,websocket,webserver", "homepage": "https://github.com/mathieucarbou/ESPAsyncWebServer", diff --git a/library.properties b/library.properties index 6ca1b38c9..bb170b95e 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=ESPAsyncWebServer -version=3.3.6 +version=3.3.7 author=Me-No-Dev maintainer=Mathieu Carbou sentence=Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 and RP2040 diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index eb28473f8..dfaef9ca9 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -48,10 +48,10 @@ #include "literals.h" -#define ASYNCWEBSERVER_VERSION "3.3.6" +#define ASYNCWEBSERVER_VERSION "3.3.7" #define ASYNCWEBSERVER_VERSION_MAJOR 3 #define ASYNCWEBSERVER_VERSION_MINOR 3 -#define ASYNCWEBSERVER_VERSION_REVISION 6 +#define ASYNCWEBSERVER_VERSION_REVISION 7 #define ASYNCWEBSERVER_FORK_mathieucarbou #ifdef ASYNCWEBSERVER_REGEX From 20a022b3f787a9bac097395f5db8c534491cebee Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Wed, 2 Oct 2024 10:18:35 +0200 Subject: [PATCH 403/551] Added chunk example --- examples/SimpleServer/SimpleServer.ino | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/examples/SimpleServer/SimpleServer.ino b/examples/SimpleServer/SimpleServer.ino index 899c77db7..3edd6d564 100644 --- a/examples/SimpleServer/SimpleServer.ino +++ b/examples/SimpleServer/SimpleServer.ino @@ -307,6 +307,23 @@ void setup() { request->send(LittleFS, "/index.html"); }); + /* + Chunked encoding test: sends 16k of characters. + ❯ curl -N -v -X GET -H "origin: http://192.168.4.1" http://192.168.4.1/chunk + */ + static const char characters[] = "1234567890"; + static size_t charactersIndex = 0; + server.on("/chunk", HTTP_HEAD | HTTP_GET, [](AsyncWebServerRequest* request) { + AsyncWebServerResponse* response = request->beginChunkedResponse("text/html", [](uint8_t* buffer, size_t maxLen, size_t index) -> size_t { + if (index >= 16384) + return 0; + memset(buffer, characters[charactersIndex], maxLen); + charactersIndex = (charactersIndex + 1) % 10; + return maxLen; + }); + request->send(response); + }); + /* ❯ curl -I -X HEAD http://192.168.4.1/download HTTP/1.1 200 OK From 2b5324b8ce020aa1cb355ef8565b40a5dec2bcb9 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Wed, 2 Oct 2024 10:32:32 +0200 Subject: [PATCH 404/551] fixed issue template --- .github/ISSUE_TEMPLATE/bug_report.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index d9cf490b7..de20b90bd 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -2,7 +2,7 @@ name: Bug report about: Create a report to help us improve title: "[BUG]" -labels: bug +labels: triage assignees: '' --- From 657010d5199d31759a2b3ea8beda38d79718fddb Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Wed, 2 Oct 2024 12:50:43 +0200 Subject: [PATCH 405/551] update doc --- README.md | 10 +++++++--- docs/index.md | 10 +++++++--- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 55efb4bf3..4008c2103 100644 --- a/README.md +++ b/README.md @@ -29,11 +29,15 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo **WARNING** The library name was changed from `ESP Async WebServer` to `ESPAsyncWebServer` as per the Arduino Lint recommendations. -``` -mathieucarbou/ESPAsyncWebServer @ 3.3.7 +**PlatformIO / pioarduino:** + +```ini +lib_compat_mode = strict +lib_ldf_mode = chain +lib_deps = mathieucarbou/ESPAsyncWebServer @ 3.3.7 ``` -Dependency: +**Dependencies:** - **ESP32**: `mathieucarbou/AsyncTCP @ 3.2.5` (Arduino IDE: [https://github.com/mathieucarbou/AsyncTCP#v3.2.5](https://github.com/mathieucarbou/AsyncTCP/releases)) - **ESP8266**: `esphome/ESPAsyncTCP-esphome @ 2.0.0` (Arduino IDE: [https://github.com/mathieucarbou/esphome-ESPAsyncTCP#v2.0.0](https://github.com/mathieucarbou/esphome-ESPAsyncTCP/releases/tag/v2.0.0)) diff --git a/docs/index.md b/docs/index.md index 55efb4bf3..4008c2103 100644 --- a/docs/index.md +++ b/docs/index.md @@ -29,11 +29,15 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo **WARNING** The library name was changed from `ESP Async WebServer` to `ESPAsyncWebServer` as per the Arduino Lint recommendations. -``` -mathieucarbou/ESPAsyncWebServer @ 3.3.7 +**PlatformIO / pioarduino:** + +```ini +lib_compat_mode = strict +lib_ldf_mode = chain +lib_deps = mathieucarbou/ESPAsyncWebServer @ 3.3.7 ``` -Dependency: +**Dependencies:** - **ESP32**: `mathieucarbou/AsyncTCP @ 3.2.5` (Arduino IDE: [https://github.com/mathieucarbou/AsyncTCP#v3.2.5](https://github.com/mathieucarbou/AsyncTCP/releases)) - **ESP8266**: `esphome/ESPAsyncTCP-esphome @ 2.0.0` (Arduino IDE: [https://github.com/mathieucarbou/esphome-ESPAsyncTCP#v2.0.0](https://github.com/mathieucarbou/esphome-ESPAsyncTCP/releases/tag/v2.0.0)) From 161db0049e8a8a8f26e222cd8be0f04420f636d4 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Thu, 3 Oct 2024 00:06:56 +0200 Subject: [PATCH 406/551] Code cleanup --- examples/Draft/Draft.ino | 37 --------- examples/SimpleServer/SimpleServer.ino | 35 ++++++-- examples/issues/Issue14/Issue14.ino | 107 ------------------------- platformio.ini | 2 - 4 files changed, 30 insertions(+), 151 deletions(-) delete mode 100644 examples/Draft/Draft.ino delete mode 100644 examples/issues/Issue14/Issue14.ino diff --git a/examples/Draft/Draft.ino b/examples/Draft/Draft.ino deleted file mode 100644 index f10a9e7a5..000000000 --- a/examples/Draft/Draft.ino +++ /dev/null @@ -1,37 +0,0 @@ -#include "mbedtls/md5.h" -#include -#include - -void setup() { - Serial.begin(115200); - delay(2000); - - const char* data = "Hello World"; - - { - uint8_t md5[16]; - mbedtls_md5_context _ctx; - mbedtls_md5_init(&_ctx); - mbedtls_md5_starts(&_ctx); - mbedtls_md5_update(&_ctx, (const unsigned char*)data, strlen(data)); - mbedtls_md5_finish(&_ctx, md5); - char output[33]; - for (int i = 0; i < 16; i++) { - sprintf_P(output + (i * 2), PSTR("%02x"), md5[i]); - } - Serial.println(String(output)); - } - - { - MD5Builder md5; - md5.begin(); - md5.add(data, strlen(data); - md5.calculate(); - char output[33]; - md5.getChars(output); - Serial.println(String(output)); - } -} - -void loop() { -} diff --git a/examples/SimpleServer/SimpleServer.ino b/examples/SimpleServer/SimpleServer.ino index 3edd6d564..da58072e8 100644 --- a/examples/SimpleServer/SimpleServer.ino +++ b/examples/SimpleServer/SimpleServer.ino @@ -116,10 +116,27 @@ AsyncCallbackJsonWebHandler* jsonHandler = new AsyncCallbackJsonWebHandler("/jso AsyncCallbackMessagePackWebHandler* msgPackHandler = new AsyncCallbackMessagePackWebHandler("/msgpack2"); #endif +static const char characters[] = "0123456789ABCDEF"; +static size_t charactersIndex = 0; + void setup() { Serial.begin(115200); + assert(LittleFS.begin()); + + if (!LittleFS.exists("/index.txt")) { + File f = LittleFS.open("/index.txt", "w"); + if (f) { + for (size_t c = 0; c < sizeof(characters); c++) { + for (size_t i = 0; i < 1024; i++) { + f.print(characters[c]); + } + } + f.close(); + } + } + #ifndef CONFIG_IDF_TARGET_ESP32H2 // WiFi.mode(WIFI_STA); // WiFi.begin("YOUR_SSID", "YOUR_PASSWORD"); @@ -217,7 +234,7 @@ void setup() { // global middleware server.addMiddleware(&requestLogger); - server.addMiddlewares({&rateLimit, &cors, &headerFilter}); + // server.addMiddlewares({&rateLimit, &cors, &headerFilter}); cors.setOrigin("http://192.168.4.1"); cors.setMethods("POST, GET, OPTIONS, DELETE"); @@ -304,21 +321,29 @@ void setup() { }); server.on("/file", HTTP_GET, [](AsyncWebServerRequest* request) { - request->send(LittleFS, "/index.html"); + request->send(LittleFS, "/index.txt"); + }); + + // Issue #14: assert failed: tcp_update_rcv_ann_wnd (needs help to test fix) + // > curl -v http://192.168.4.1/issue-14 + pinMode(4, OUTPUT); + server.on("/issue-14", HTTP_GET, [](AsyncWebServerRequest* request) { + digitalWrite(4, HIGH); + request->send(LittleFS, "/index.txt", "text/pain"); + delay(500); + digitalWrite(4, LOW); }); /* Chunked encoding test: sends 16k of characters. ❯ curl -N -v -X GET -H "origin: http://192.168.4.1" http://192.168.4.1/chunk */ - static const char characters[] = "1234567890"; - static size_t charactersIndex = 0; server.on("/chunk", HTTP_HEAD | HTTP_GET, [](AsyncWebServerRequest* request) { AsyncWebServerResponse* response = request->beginChunkedResponse("text/html", [](uint8_t* buffer, size_t maxLen, size_t index) -> size_t { if (index >= 16384) return 0; memset(buffer, characters[charactersIndex], maxLen); - charactersIndex = (charactersIndex + 1) % 10; + charactersIndex = (charactersIndex + 1) % sizeof(characters); return maxLen; }); request->send(response); diff --git a/examples/issues/Issue14/Issue14.ino b/examples/issues/Issue14/Issue14.ino deleted file mode 100644 index f62084a6b..000000000 --- a/examples/issues/Issue14/Issue14.ino +++ /dev/null @@ -1,107 +0,0 @@ -#include -#ifdef ESP32 - #include - #include -#elif defined(ESP8266) - #include - #include -#elif defined(TARGET_RP2040) - #include - #include -#endif - -#include "ESPAsyncWebServer.h" - -const char appWebPage[] PROGMEM = R"rawliteral( - - - - -)rawliteral"; - -AsyncWebServer server(80); -AsyncEventSource events("/events"); - -const uint32_t interval = 1000; -const int button1Pin = 4; - -uint32_t lastSend = 0; - -void prepareJson(String& buffer) { - buffer.reserve(512); - buffer.concat("{\"button1\":"); - buffer.concat(digitalRead(button1Pin) == LOW); - buffer.concat(",\"1234567890abcdefghij1234567890abcdefghij1234567890abcdefghij1234567890abcdefghij1234567890abcdefghij1234567890abcdefghij\":"); - buffer.concat(random(0, 999999999)); - buffer.concat("}"); -} - -void setup() { - Serial.begin(115200); -#if ARDUINO_USB_CDC_ON_BOOT - Serial.setTxTimeoutMs(0); - delay(100); -#else - while (!Serial) - yield(); -#endif - - randomSeed(micros()); - - pinMode(button1Pin, OUTPUT); - digitalWrite(button1Pin, HIGH); - - WiFi.softAP("esp-captive"); - - server.on("/", HTTP_GET, [](AsyncWebServerRequest* request) { - request->send(200, "text/html", appWebPage); - }); - - server.on("/button1", HTTP_GET, [](AsyncWebServerRequest* request) { - request->send(200, "text/plain", "OK"); - digitalWrite(button1Pin, digitalRead(button1Pin) == LOW ? HIGH : LOW); - - String buffer; - prepareJson(buffer); - ESP_LOGI("async_tcp", "Sending from handler..."); - events.send(buffer.c_str(), "state", millis()); - ESP_LOGI("async_tcp", "Sent from handler!"); - }); - - events.onConnect([](AsyncEventSourceClient* client) { - String buffer; - prepareJson(buffer); - ESP_LOGI("async_tcp", "Sending from onConnect..."); - client->send(buffer.c_str(), "state", millis(), 5000); - ESP_LOGI("async_tcp", "Sent from onConnect!"); - }); - - server.addHandler(&events); - DefaultHeaders::Instance().addHeader("Access-Control-Allow-Origin", "*"); - - server.begin(); -} - -void loop() { - if (millis() - lastSend >= interval) { - String buffer; - prepareJson(buffer); - ESP_LOGI("loop", "Sending..."); - events.send(buffer.c_str(), "state", millis()); - ESP_LOGI("loop", "Sent!"); - lastSend = millis(); - } -} diff --git a/platformio.ini b/platformio.ini index b0a28f197..7c9cad9bd 100644 --- a/platformio.ini +++ b/platformio.ini @@ -5,8 +5,6 @@ lib_dir = . src_dir = examples/SimpleServer ; src_dir = examples/StreamFiles ; src_dir = examples/Filters -; src_dir = examples/Draft -; src_dir = examples/issues/Issue14 [env] framework = arduino From fb555c99dd083861352e5cc6fb431f6619202aa1 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Thu, 3 Oct 2024 00:45:00 +0200 Subject: [PATCH 407/551] mathieucarbou/AsyncTCP @ 3.2.6 --- .github/workflows/ci.yml | 2 +- README.md | 2 +- docs/index.md | 2 +- library.json | 2 +- platformio.ini | 6 +++--- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ef80fafd1..c08191b75 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -55,7 +55,7 @@ jobs: - name: Install AsyncTCP (ESP32) if: ${{ matrix.core == 'esp32:esp32' }} - run: ARDUINO_LIBRARY_ENABLE_UNSAFE_INSTALL=true arduino-cli lib install --git-url https://github.com/mathieucarbou/AsyncTCP#v3.2.5 + run: ARDUINO_LIBRARY_ENABLE_UNSAFE_INSTALL=true arduino-cli lib install --git-url https://github.com/mathieucarbou/AsyncTCP#v3.2.6 - name: Install ESPAsyncTCP (ESP8266) if: ${{ matrix.core == 'esp8266:esp8266' }} diff --git a/README.md b/README.md index 4008c2103..a5e25d4ea 100644 --- a/README.md +++ b/README.md @@ -39,7 +39,7 @@ lib_deps = mathieucarbou/ESPAsyncWebServer @ 3.3.7 **Dependencies:** -- **ESP32**: `mathieucarbou/AsyncTCP @ 3.2.5` (Arduino IDE: [https://github.com/mathieucarbou/AsyncTCP#v3.2.5](https://github.com/mathieucarbou/AsyncTCP/releases)) +- **ESP32**: `mathieucarbou/AsyncTCP @ 3.2.6` (Arduino IDE: [https://github.com/mathieucarbou/AsyncTCP#v3.2.6](https://github.com/mathieucarbou/AsyncTCP/releases)) - **ESP8266**: `esphome/ESPAsyncTCP-esphome @ 2.0.0` (Arduino IDE: [https://github.com/mathieucarbou/esphome-ESPAsyncTCP#v2.0.0](https://github.com/mathieucarbou/esphome-ESPAsyncTCP/releases/tag/v2.0.0)) - **RP2040**: `khoih-prog/AsyncTCP_RP2040W @ 1.2.0` (Arduino IDE: [https://github.com/khoih-prog/AsyncTCP_RP2040W#v1.2.0](https://github.com/khoih-prog/AsyncTCP_RP2040W/releases/tag/v1.2.0)) diff --git a/docs/index.md b/docs/index.md index 4008c2103..a5e25d4ea 100644 --- a/docs/index.md +++ b/docs/index.md @@ -39,7 +39,7 @@ lib_deps = mathieucarbou/ESPAsyncWebServer @ 3.3.7 **Dependencies:** -- **ESP32**: `mathieucarbou/AsyncTCP @ 3.2.5` (Arduino IDE: [https://github.com/mathieucarbou/AsyncTCP#v3.2.5](https://github.com/mathieucarbou/AsyncTCP/releases)) +- **ESP32**: `mathieucarbou/AsyncTCP @ 3.2.6` (Arduino IDE: [https://github.com/mathieucarbou/AsyncTCP#v3.2.6](https://github.com/mathieucarbou/AsyncTCP/releases)) - **ESP8266**: `esphome/ESPAsyncTCP-esphome @ 2.0.0` (Arduino IDE: [https://github.com/mathieucarbou/esphome-ESPAsyncTCP#v2.0.0](https://github.com/mathieucarbou/esphome-ESPAsyncTCP/releases/tag/v2.0.0)) - **RP2040**: `khoih-prog/AsyncTCP_RP2040W @ 1.2.0` (Arduino IDE: [https://github.com/khoih-prog/AsyncTCP_RP2040W#v1.2.0](https://github.com/khoih-prog/AsyncTCP_RP2040W/releases/tag/v1.2.0)) diff --git a/library.json b/library.json index d22884244..804890d41 100644 --- a/library.json +++ b/library.json @@ -28,7 +28,7 @@ { "owner": "mathieucarbou", "name": "AsyncTCP", - "version": "^3.2.5", + "version": "^3.2.6", "platforms": "espressif32" }, { diff --git a/platformio.ini b/platformio.ini index 7c9cad9bd..80166a3f5 100644 --- a/platformio.ini +++ b/platformio.ini @@ -25,7 +25,7 @@ lib_deps = ; bblanchon/ArduinoJson @ 5.13.4 ; bblanchon/ArduinoJson @ 6.21.5 bblanchon/ArduinoJson @ 7.2.0 - mathieucarbou/AsyncTCP @ 3.2.5 + mathieucarbou/AsyncTCP @ 3.2.6 board = esp32dev [env:arduino-2] @@ -41,7 +41,7 @@ platform = https://github.com/pioarduino/platform-espressif32/releases/download/ ; board = esp32-s3-devkitc-1 ; board = esp32-c6-devkitc-1 lib_deps = - mathieucarbou/AsyncTCP @ 3.2.5 + mathieucarbou/AsyncTCP @ 3.2.6 [env:arduino-310rc1] platform = https://github.com/pioarduino/platform-espressif32/releases/download/53.03.10-rc1/platform-espressif32.zip @@ -85,7 +85,7 @@ board = ${sysenv.PIO_BOARD} platform = https://github.com/pioarduino/platform-espressif32/releases/download/51.03.05/platform-espressif32.zip board = ${sysenv.PIO_BOARD} lib_deps = - mathieucarbou/AsyncTCP @ 3.2.5 + mathieucarbou/AsyncTCP @ 3.2.6 [env:ci-arduino-310rc1] platform = https://github.com/pioarduino/platform-espressif32/releases/download/53.03.10-rc1/platform-espressif32.zip From 6884bb74a613631af65dd2293fdbad7b2864bb1e Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Thu, 3 Oct 2024 00:47:39 +0200 Subject: [PATCH 408/551] v3.3.8 --- README.md | 2 +- docs/index.md | 2 +- library.json | 2 +- library.properties | 2 +- src/ESPAsyncWebServer.h | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index a5e25d4ea..a02f5efc9 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo ```ini lib_compat_mode = strict lib_ldf_mode = chain -lib_deps = mathieucarbou/ESPAsyncWebServer @ 3.3.7 +lib_deps = mathieucarbou/ESPAsyncWebServer @ 3.3.8 ``` **Dependencies:** diff --git a/docs/index.md b/docs/index.md index a5e25d4ea..a02f5efc9 100644 --- a/docs/index.md +++ b/docs/index.md @@ -34,7 +34,7 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo ```ini lib_compat_mode = strict lib_ldf_mode = chain -lib_deps = mathieucarbou/ESPAsyncWebServer @ 3.3.7 +lib_deps = mathieucarbou/ESPAsyncWebServer @ 3.3.8 ``` **Dependencies:** diff --git a/library.json b/library.json index 804890d41..c8d0e4cd2 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "ESPAsyncWebServer", - "version": "3.3.7", + "version": "3.3.8", "description": "Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 and RP2040. Supports: WebSocket, SSE, Authentication, Arduino Json 7, File Upload, Static File serving, URL Rewrite, URL Redirect, etc.", "keywords": "http,async,websocket,webserver", "homepage": "https://github.com/mathieucarbou/ESPAsyncWebServer", diff --git a/library.properties b/library.properties index bb170b95e..92f6229af 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=ESPAsyncWebServer -version=3.3.7 +version=3.3.8 author=Me-No-Dev maintainer=Mathieu Carbou sentence=Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 and RP2040 diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index dfaef9ca9..3c231378c 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -48,10 +48,10 @@ #include "literals.h" -#define ASYNCWEBSERVER_VERSION "3.3.7" +#define ASYNCWEBSERVER_VERSION "3.3.8" #define ASYNCWEBSERVER_VERSION_MAJOR 3 #define ASYNCWEBSERVER_VERSION_MINOR 3 -#define ASYNCWEBSERVER_VERSION_REVISION 7 +#define ASYNCWEBSERVER_VERSION_REVISION 8 #define ASYNCWEBSERVER_FORK_mathieucarbou #ifdef ASYNCWEBSERVER_REGEX From 4843a55e59c41236db9ac284d309d0c218e0e7b1 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Thu, 3 Oct 2024 01:05:19 +0200 Subject: [PATCH 409/551] AuthenticationMiddleware bug fixes --- src/ESPAsyncWebServer.h | 26 ++++++++++++++++++++------ src/Middleware.cpp | 7 +++++-- 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index 3c231378c..d58e94883 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -166,11 +166,12 @@ typedef enum { RCT_NOT_USED = -1, // this enum is similar to Arduino WebServer's AsyncAuthType and PsychicHttp typedef enum { - AUTH_NONE = 0, - AUTH_BASIC, - AUTH_DIGEST, - AUTH_BEARER, - AUTH_OTHER, + AUTH_NONE = 0, // always allow + AUTH_BASIC = 1, + AUTH_DIGEST = 2, + AUTH_BEARER = 3, + AUTH_OTHER = 4, + AUTH_DENIED = 255, // always returns 401 } AsyncAuthType; typedef std::function AwsResponseFiller; @@ -570,12 +571,25 @@ class AuthenticationMiddleware : public AsyncMiddleware { void setRealm(const char* realm) { _realm = realm; } void setAuthFailureMessage(const char* message) { _authFailMsg = message; } + + // set the authentication method to use + // default is AUTH_NONE: no authentication required + // AUTH_BASIC: basic authentication + // AUTH_DIGEST: digest authentication + // AUTH_BEARER: bearer token authentication + // AUTH_OTHER: other authentication method + // AUTH_DENIED: always return 401 Unauthorized + // if a method is set but no username or password is set, authentication will be ignored void setAuthType(AsyncAuthType authMethod) { _authMethod = authMethod; } - // precompute and store the hash value based on the username, realm, and authMethod + // precompute and store the hash value based on the username, password, realm. + // can be used for DIGEST and BASIC to avoid recomputing the hash for each request. // returns true if the hash was successfully generated and replaced bool generateHash(); + // returns true if the username and password (or hash) are set + bool hasCredentials() { return _hasCreds; } + bool allowed(AsyncWebServerRequest* request); void run(AsyncWebServerRequest* request, ArMiddlewareNext next); diff --git a/src/Middleware.cpp b/src/Middleware.cpp index 1c36ef66f..c7e507be5 100644 --- a/src/Middleware.cpp +++ b/src/Middleware.cpp @@ -66,7 +66,7 @@ void AuthenticationMiddleware::setPassword(const char* password) { void AuthenticationMiddleware::setPasswordHash(const char* hash) { _credentials = hash; - _hash = true; + _hash = _credentials.length(); _hasCreds = _username.length() && _credentials.length(); } @@ -99,8 +99,11 @@ bool AuthenticationMiddleware::allowed(AsyncWebServerRequest* request) { if (_authMethod == AsyncAuthType::AUTH_NONE) return true; + if (_authMethod == AsyncAuthType::AUTH_DENIED) + return true; + if (!_hasCreds) - return false; + return true; return request->authenticate(_username.c_str(), _credentials.c_str(), _realm.c_str(), _hash); } From 13cf6e223ce2c3d92c90e31ed6df0ec915a5cdc2 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Thu, 3 Oct 2024 01:25:29 +0200 Subject: [PATCH 410/551] v3.3.9 --- README.md | 2 +- docs/index.md | 2 +- library.json | 2 +- library.properties | 2 +- src/ESPAsyncWebServer.h | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index a02f5efc9..c3080d1d9 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo ```ini lib_compat_mode = strict lib_ldf_mode = chain -lib_deps = mathieucarbou/ESPAsyncWebServer @ 3.3.8 +lib_deps = mathieucarbou/ESPAsyncWebServer @ 3.3.9 ``` **Dependencies:** diff --git a/docs/index.md b/docs/index.md index a02f5efc9..c3080d1d9 100644 --- a/docs/index.md +++ b/docs/index.md @@ -34,7 +34,7 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo ```ini lib_compat_mode = strict lib_ldf_mode = chain -lib_deps = mathieucarbou/ESPAsyncWebServer @ 3.3.8 +lib_deps = mathieucarbou/ESPAsyncWebServer @ 3.3.9 ``` **Dependencies:** diff --git a/library.json b/library.json index c8d0e4cd2..4e32b3726 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "ESPAsyncWebServer", - "version": "3.3.8", + "version": "3.3.9", "description": "Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 and RP2040. Supports: WebSocket, SSE, Authentication, Arduino Json 7, File Upload, Static File serving, URL Rewrite, URL Redirect, etc.", "keywords": "http,async,websocket,webserver", "homepage": "https://github.com/mathieucarbou/ESPAsyncWebServer", diff --git a/library.properties b/library.properties index 92f6229af..b86a1da34 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=ESPAsyncWebServer -version=3.3.8 +version=3.3.9 author=Me-No-Dev maintainer=Mathieu Carbou sentence=Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 and RP2040 diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index d58e94883..850990772 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -48,10 +48,10 @@ #include "literals.h" -#define ASYNCWEBSERVER_VERSION "3.3.8" +#define ASYNCWEBSERVER_VERSION "3.3.9" #define ASYNCWEBSERVER_VERSION_MAJOR 3 #define ASYNCWEBSERVER_VERSION_MINOR 3 -#define ASYNCWEBSERVER_VERSION_REVISION 8 +#define ASYNCWEBSERVER_VERSION_REVISION 9 #define ASYNCWEBSERVER_FORK_mathieucarbou #ifdef ASYNCWEBSERVER_REGEX From 77456a184b95692396fe9d2ca88db23517c4d6c4 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Thu, 3 Oct 2024 01:28:02 +0200 Subject: [PATCH 411/551] AuthenticationMiddleware fix --- src/Middleware.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Middleware.cpp b/src/Middleware.cpp index c7e507be5..bfc4e7b1f 100644 --- a/src/Middleware.cpp +++ b/src/Middleware.cpp @@ -100,7 +100,7 @@ bool AuthenticationMiddleware::allowed(AsyncWebServerRequest* request) { return true; if (_authMethod == AsyncAuthType::AUTH_DENIED) - return true; + return false; if (!_hasCreds) return true; From 8e86039fee9649e51861e6a742a3045824cd5a17 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Thu, 3 Oct 2024 01:28:28 +0200 Subject: [PATCH 412/551] v3.3.10 --- README.md | 2 +- docs/index.md | 2 +- library.json | 2 +- library.properties | 2 +- src/ESPAsyncWebServer.h | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index c3080d1d9..ee0fa52dc 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo ```ini lib_compat_mode = strict lib_ldf_mode = chain -lib_deps = mathieucarbou/ESPAsyncWebServer @ 3.3.9 +lib_deps = mathieucarbou/ESPAsyncWebServer @ 3.3.10 ``` **Dependencies:** diff --git a/docs/index.md b/docs/index.md index c3080d1d9..ee0fa52dc 100644 --- a/docs/index.md +++ b/docs/index.md @@ -34,7 +34,7 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo ```ini lib_compat_mode = strict lib_ldf_mode = chain -lib_deps = mathieucarbou/ESPAsyncWebServer @ 3.3.9 +lib_deps = mathieucarbou/ESPAsyncWebServer @ 3.3.10 ``` **Dependencies:** diff --git a/library.json b/library.json index 4e32b3726..cbe666f03 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "ESPAsyncWebServer", - "version": "3.3.9", + "version": "3.3.10", "description": "Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 and RP2040. Supports: WebSocket, SSE, Authentication, Arduino Json 7, File Upload, Static File serving, URL Rewrite, URL Redirect, etc.", "keywords": "http,async,websocket,webserver", "homepage": "https://github.com/mathieucarbou/ESPAsyncWebServer", diff --git a/library.properties b/library.properties index b86a1da34..66c9417ad 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=ESPAsyncWebServer -version=3.3.9 +version=3.3.10 author=Me-No-Dev maintainer=Mathieu Carbou sentence=Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 and RP2040 diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index 850990772..4d3adaa96 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -48,10 +48,10 @@ #include "literals.h" -#define ASYNCWEBSERVER_VERSION "3.3.9" +#define ASYNCWEBSERVER_VERSION "3.3.10" #define ASYNCWEBSERVER_VERSION_MAJOR 3 #define ASYNCWEBSERVER_VERSION_MINOR 3 -#define ASYNCWEBSERVER_VERSION_REVISION 9 +#define ASYNCWEBSERVER_VERSION_REVISION 10 #define ASYNCWEBSERVER_FORK_mathieucarbou #ifdef ASYNCWEBSERVER_REGEX From 3fbbef421352d7794bea9694a5e24ea629955cb1 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Thu, 3 Oct 2024 20:49:22 +0200 Subject: [PATCH 413/551] Little cleanups and added partition file --- .github/ISSUE_TEMPLATE/bug_report.md | 13 +++++-------- .github/ISSUE_TEMPLATE/question.md | 5 +---- examples/SimpleServer/SimpleServer.ino | 11 +++++++++-- partitions-4MB.csv | 7 +++++++ platformio.ini | 2 ++ 5 files changed, 24 insertions(+), 14 deletions(-) create mode 100644 partitions-4MB.csv diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index de20b90bd..19fe4793f 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -3,8 +3,7 @@ name: Bug report about: Create a report to help us improve title: "[BUG]" labels: triage -assignees: '' - +assignees: "" --- **Please make sure to go through the recommendations before opening a bug report:** @@ -13,15 +12,13 @@ assignees: '' **Description** -A clear and concise description of what the bug is. - -**Board** +_A clear and concise description of what the bug is._ -esp32dev, esp32s3, etc +**Link:** _A link to your source code where the issue happens_ -**Ethernet adapter used ?** +**Board**: _esp32dev, esp32s3, ?_ -If yes, please specify which one +**Ethernet adapter used ?** _If yes, please specify which one_ **Stack trace** diff --git a/.github/ISSUE_TEMPLATE/question.md b/.github/ISSUE_TEMPLATE/question.md index 634179ca6..7f628456b 100644 --- a/.github/ISSUE_TEMPLATE/question.md +++ b/.github/ISSUE_TEMPLATE/question.md @@ -3,8 +3,5 @@ name: Question about: Describe your question title: "[Q]" labels: question -assignees: '' - +assignees: "" --- - - diff --git a/examples/SimpleServer/SimpleServer.ino b/examples/SimpleServer/SimpleServer.ino index da58072e8..dbb1e2f7c 100644 --- a/examples/SimpleServer/SimpleServer.ino +++ b/examples/SimpleServer/SimpleServer.ino @@ -123,7 +123,11 @@ void setup() { Serial.begin(115200); - assert(LittleFS.begin()); +#ifdef ESP32 + LittleFS.begin(true); +#else + LittleFS.begin(); +#endif if (!LittleFS.exists("/index.txt")) { File f = LittleFS.open("/index.txt", "w"); @@ -478,7 +482,10 @@ void setup() { } }); + // go to http://192.168.4.1/sse server.addHandler(&events); + + // Run: websocat ws://192.168.4.1/ws server.addHandler(&ws); #if ASYNC_JSON_SUPPORT == 1 @@ -507,7 +514,7 @@ void loop() { ws.printfAll("kp%.4f", (10.0 / 3.0)); // ws.getClients for (auto& client : ws.getClients()) { - client.text("kp%.4f", (10.0 / 3.0)); + client.printf("kp%.4f", (10.0 / 3.0)); } lastWS = millis(); } diff --git a/partitions-4MB.csv b/partitions-4MB.csv new file mode 100644 index 000000000..75efc35ce --- /dev/null +++ b/partitions-4MB.csv @@ -0,0 +1,7 @@ +# Name ,Type ,SubType ,Offset ,Size ,Flags +nvs ,data ,nvs ,36K ,20K , +otadata ,data ,ota ,56K ,8K , +app0 ,app ,ota_0 ,64K ,1856K , +app1 ,app ,ota_1 ,1920K ,1856K , +spiffs ,data ,spiffs ,3776K ,256K , +coredump ,data ,coredump ,4032K ,64K , diff --git a/platformio.ini b/platformio.ini index 80166a3f5..6fc704602 100644 --- a/platformio.ini +++ b/platformio.ini @@ -27,6 +27,8 @@ lib_deps = bblanchon/ArduinoJson @ 7.2.0 mathieucarbou/AsyncTCP @ 3.2.6 board = esp32dev +board_build.partitions = partitions-4MB.csv +board_build.filesystem = littlefs [env:arduino-2] platform = espressif32@6.9.0 From a0c37a65ab4a4eb5f7f8bf90e7e0b12ff6579a92 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Fri, 4 Oct 2024 10:13:13 +0200 Subject: [PATCH 414/551] Improved SSE API to get feedback whether message is enqueued and also on client disconnect Idea taken from PR https://github.com/esphome/ESPAsyncWebServer/pull/43 by @nkinnan - Now returns bool on client send() / write() methods - Now returns SendStatus on AsyncEventSource send() methods - Added AsyncEventSource.onDisconnect() --- src/AsyncEventSource.cpp | 37 +++++++++++++++++++------------------ src/AsyncEventSource.h | 28 ++++++++++++++++++---------- 2 files changed, 37 insertions(+), 28 deletions(-) diff --git a/src/AsyncEventSource.cpp b/src/AsyncEventSource.cpp index 2d6ab7b1b..21c2da48c 100644 --- a/src/AsyncEventSource.cpp +++ b/src/AsyncEventSource.cpp @@ -186,7 +186,7 @@ AsyncEventSourceClient::~AsyncEventSourceClient() { close(); } -void AsyncEventSourceClient::_queueMessage(const char* message, size_t len) { +bool AsyncEventSourceClient::_queueMessage(const char* message, size_t len) { #ifdef ESP32 // length() is not thread-safe, thus acquiring the lock before this call.. std::lock_guard lock(_lockmq); @@ -198,7 +198,7 @@ void AsyncEventSourceClient::_queueMessage(const char* message, size_t len) { #elif defined(ESP32) log_e("Too many messages queued: deleting message"); #endif - return; + return false; } _messageQueue.emplace_back(message, len); @@ -206,6 +206,8 @@ void AsyncEventSourceClient::_queueMessage(const char* message, size_t len) { if (_client->canSend()) { _runQueue(); } + + return true; } void AsyncEventSourceClient::_onAck(size_t len __attribute__((unused)), uint32_t time __attribute__((unused))) { @@ -240,17 +242,15 @@ void AsyncEventSourceClient::close() { _client->close(); } -void AsyncEventSourceClient::write(const char* message, size_t len) { - if (!connected()) - return; - _queueMessage(message, len); +bool AsyncEventSourceClient::write(const char* message, size_t len) { + return connected() && _queueMessage(message, len); } -void AsyncEventSourceClient::send(const char* message, const char* event, uint32_t id, uint32_t reconnect) { +bool AsyncEventSourceClient::send(const char* message, const char* event, uint32_t id, uint32_t reconnect) { if (!connected()) - return; + return false; String ev = generateEventMessage(message, event, id, reconnect); - _queueMessage(ev.c_str(), ev.length()); + return _queueMessage(ev.c_str(), ev.length()); } size_t AsyncEventSourceClient::packetsWaiting() const { @@ -282,11 +282,6 @@ void AsyncEventSourceClient::_runQueue() { } } -// Handler -void AsyncEventSource::onConnect(ArEventHandlerFunction cb) { - _connectcb = cb; -} - void AsyncEventSource::authorizeConnect(ArAuthorizeConnectHandler cb) { AuthorizationMiddleware* m = new AuthorizationMiddleware(401, cb); m->_freeOnRemoval = true; @@ -308,6 +303,8 @@ void AsyncEventSource::_handleDisconnect(AsyncEventSourceClient* client) { #ifdef ESP32 std::lock_guard lock(_client_queue_lock); #endif + if (_disconnectcb) + _disconnectcb(client); for (auto i = _clients.begin(); i != _clients.end(); ++i) { if (i->get() == client) _clients.erase(i); @@ -346,17 +343,21 @@ size_t AsyncEventSource::avgPacketsWaiting() const { return ((aql) + (nConnectedClients / 2)) / (nConnectedClients); // round up } -void AsyncEventSource::send( +AsyncEventSource::SendStatus AsyncEventSource::send( const char* message, const char* event, uint32_t id, uint32_t reconnect) { String ev = generateEventMessage(message, event, id, reconnect); #ifdef ESP32 std::lock_guard lock(_client_queue_lock); #endif + size_t hits = 0; + size_t miss = 0; for (const auto& c : _clients) { - if (c->connected()) { - c->write(ev.c_str(), ev.length()); - } + if (c->write(ev.c_str(), ev.length())) + ++hits; + else + ++miss; } + return hits == 0 ? NOT_SENT : (miss == 0 ? FULLY_SENT : PARTIALLY_SEND); } size_t AsyncEventSource::count() const { diff --git a/src/AsyncEventSource.h b/src/AsyncEventSource.h index 9fc4b7add..b64877106 100644 --- a/src/AsyncEventSource.h +++ b/src/AsyncEventSource.h @@ -81,7 +81,7 @@ class AsyncEventSourceClient { #ifdef ESP32 mutable std::mutex _lockmq; #endif - void _queueMessage(const char* message, size_t len); + bool _queueMessage(const char* message, size_t len); void _runQueue(); public: @@ -90,10 +90,10 @@ class AsyncEventSourceClient { AsyncClient* client() { return _client; } void close(); - void write(const char* message, size_t len); - void send(const String& message, const String& event, uint32_t id = 0, uint32_t reconnect = 0) { send(message.c_str(), event.c_str(), id, reconnect); } - void send(const String& message, const char* event, uint32_t id = 0, uint32_t reconnect = 0) { send(message.c_str(), event, id, reconnect); } - void send(const char* message, const char* event = NULL, uint32_t id = 0, uint32_t reconnect = 0); + bool write(const char* message, size_t len); + bool send(const String& message, const String& event, uint32_t id = 0, uint32_t reconnect = 0) { return send(message.c_str(), event.c_str(), id, reconnect); } + bool send(const String& message, const char* event, uint32_t id = 0, uint32_t reconnect = 0) { return send(message.c_str(), event, id, reconnect); } + bool send(const char* message, const char* event = NULL, uint32_t id = 0, uint32_t reconnect = 0); bool connected() const { return (_client != NULL) && _client->connected(); } uint32_t lastId() const { return _lastId; } size_t packetsWaiting() const; @@ -114,19 +114,27 @@ class AsyncEventSource : public AsyncWebHandler { // since simultaneous access from different tasks is possible mutable std::mutex _client_queue_lock; #endif - ArEventHandlerFunction _connectcb{nullptr}; + ArEventHandlerFunction _connectcb = nullptr; + ArEventHandlerFunction _disconnectcb = nullptr; public: + typedef enum { + NOT_SENT = 0, // sent to no client + FULLY_SENT = 1, // sent to all clients + PARTIALLY_SEND = 2, // sent to some clients + } SendStatus; + AsyncEventSource(const String& url) : _url(url) {}; ~AsyncEventSource() { close(); }; const char* url() const { return _url.c_str(); } void close(); - void onConnect(ArEventHandlerFunction cb); + void onConnect(ArEventHandlerFunction cb) { _connectcb = cb; } + void onDisconnect(ArEventHandlerFunction cb) { _disconnectcb = cb; } void authorizeConnect(ArAuthorizeConnectHandler cb); - void send(const String& message, const String& event, uint32_t id = 0, uint32_t reconnect = 0) { send(message.c_str(), event.c_str(), id, reconnect); } - void send(const String& message, const char* event, uint32_t id = 0, uint32_t reconnect = 0) { send(message.c_str(), event, id, reconnect); } - void send(const char* message, const char* event = NULL, uint32_t id = 0, uint32_t reconnect = 0); + SendStatus send(const String& message, const String& event, uint32_t id = 0, uint32_t reconnect = 0) { return send(message.c_str(), event.c_str(), id, reconnect); } + SendStatus send(const String& message, const char* event, uint32_t id = 0, uint32_t reconnect = 0) { return send(message.c_str(), event, id, reconnect); } + SendStatus send(const char* message, const char* event = NULL, uint32_t id = 0, uint32_t reconnect = 0); // number of clients connected size_t count() const; size_t avgPacketsWaiting() const; From a3b67f1031f5f195ea10606aee72ac4630085e3e Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Fri, 4 Oct 2024 11:25:38 +0200 Subject: [PATCH 415/551] Code cleanup --- src/AsyncWebSocket.cpp | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/src/AsyncWebSocket.cpp b/src/AsyncWebSocket.cpp index b040a9f2c..0c43d779b 100644 --- a/src/AsyncWebSocket.cpp +++ b/src/AsyncWebSocket.cpp @@ -371,16 +371,13 @@ bool AsyncWebSocketClient::queueIsFull() const { #ifdef ESP32 std::lock_guard lock(_lock); #endif - size_t size = _messageQueue.size(); - ; - return (size >= WS_MAX_QUEUED_MESSAGES) || (_status != WS_CONNECTED); + return (_messageQueue.size() >= WS_MAX_QUEUED_MESSAGES) || (_status != WS_CONNECTED); } size_t AsyncWebSocketClient::queueLen() const { #ifdef ESP32 std::lock_guard lock(_lock); #endif - return _messageQueue.size(); } @@ -395,12 +392,11 @@ void AsyncWebSocketClient::_queueControl(uint8_t opcode, const uint8_t* data, si if (!_client) return; - { #ifdef ESP32 - std::lock_guard lock(_lock); + std::lock_guard lock(_lock); #endif - _controlQueue.emplace_back(opcode, data, len, mask); - } + + _controlQueue.emplace_back(opcode, data, len, mask); if (_client && _client->canSend()) _runQueue(); @@ -413,16 +409,20 @@ void AsyncWebSocketClient::_queueMessage(AsyncWebSocketSharedBuffer buffer, uint #ifdef ESP32 std::lock_guard lock(_lock); #endif + if (_messageQueue.size() >= WS_MAX_QUEUED_MESSAGES) { if (closeWhenFull) { + _status = WS_DISCONNECTED; + + if (_client) + _client->close(true); + #ifdef ESP8266 ets_printf("AsyncWebSocketClient::_queueMessage: Too many messages queued: closing connection\n"); #elif defined(ESP32) log_e("Too many messages queued: closing connection"); #endif - _status = WS_DISCONNECTED; - if (_client) - _client->close(true); + } else { #ifdef ESP8266 ets_printf("AsyncWebSocketClient::_queueMessage: Too many messages queued: discarding new message\n"); @@ -430,7 +430,9 @@ void AsyncWebSocketClient::_queueMessage(AsyncWebSocketSharedBuffer buffer, uint log_e("Too many messages queued: discarding new message"); #endif } + return; + } else { _messageQueue.emplace_back(buffer, opcode, mask); } From fadb0d37b89819cea0ec479d0e4f13057489567c Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Fri, 4 Oct 2024 11:33:51 +0200 Subject: [PATCH 416/551] Protect against null _client --- src/AsyncEventSource.cpp | 19 ++++++++++++++++--- src/AsyncEventSource.h | 2 +- src/AsyncWebSocket.cpp | 19 +++++++++++++------ 3 files changed, 30 insertions(+), 10 deletions(-) diff --git a/src/AsyncEventSource.cpp b/src/AsyncEventSource.cpp index 21c2da48c..0f1ffa601 100644 --- a/src/AsyncEventSource.cpp +++ b/src/AsyncEventSource.cpp @@ -141,6 +141,9 @@ size_t AsyncEventSourceMessage::ack(size_t len, __attribute__((unused)) uint32_t } size_t AsyncEventSourceMessage::write(AsyncClient* client) { + if(!client) + return 0; + if (_sent >= _len || !client->canSend()) { return 0; } @@ -187,6 +190,9 @@ AsyncEventSourceClient::~AsyncEventSourceClient() { } bool AsyncEventSourceClient::_queueMessage(const char* message, size_t len) { + if (!_client) + return false; + #ifdef ESP32 // length() is not thread-safe, thus acquiring the lock before this call.. std::lock_guard lock(_lockmq); @@ -229,16 +235,19 @@ void AsyncEventSourceClient::_onPoll() { } void AsyncEventSourceClient::_onTimeout(uint32_t time __attribute__((unused))) { - _client->close(true); + if (_client) + _client->close(true); } void AsyncEventSourceClient::_onDisconnect() { - _client = NULL; + if (!_client) + return; + _client = nullptr; _server->_handleDisconnect(this); } void AsyncEventSourceClient::close() { - if (_client != NULL) + if (_client) _client->close(); } @@ -261,6 +270,9 @@ size_t AsyncEventSourceClient::packetsWaiting() const { } void AsyncEventSourceClient::_runQueue() { + if(!_client) + return; + size_t total_bytes_written = 0; for (auto i = _messageQueue.begin(); i != _messageQueue.end(); ++i) { if (!i->sent()) { @@ -270,6 +282,7 @@ void AsyncEventSourceClient::_runQueue() { break; } } + if (total_bytes_written > 0) _client->send(); diff --git a/src/AsyncEventSource.h b/src/AsyncEventSource.h index b64877106..cd7c70ca3 100644 --- a/src/AsyncEventSource.h +++ b/src/AsyncEventSource.h @@ -94,7 +94,7 @@ class AsyncEventSourceClient { bool send(const String& message, const String& event, uint32_t id = 0, uint32_t reconnect = 0) { return send(message.c_str(), event.c_str(), id, reconnect); } bool send(const String& message, const char* event, uint32_t id = 0, uint32_t reconnect = 0) { return send(message.c_str(), event, id, reconnect); } bool send(const char* message, const char* event = NULL, uint32_t id = 0, uint32_t reconnect = 0); - bool connected() const { return (_client != NULL) && _client->connected(); } + bool connected() const { return _client && _client->connected(); } uint32_t lastId() const { return _lastId; } size_t packetsWaiting() const; diff --git a/src/AsyncWebSocket.cpp b/src/AsyncWebSocket.cpp index 0c43d779b..dafe7906b 100644 --- a/src/AsyncWebSocket.cpp +++ b/src/AsyncWebSocket.cpp @@ -39,7 +39,7 @@ using namespace asyncsrv; size_t webSocketSendFrameWindow(AsyncClient* client) { - if (!client->canSend()) + if (!client || !client->canSend()) return 0; size_t space = client->space(); if (space < 9) @@ -48,7 +48,7 @@ size_t webSocketSendFrameWindow(AsyncClient* client) { } size_t webSocketSendFrame(AsyncClient* client, bool final, uint8_t opcode, bool mask, uint8_t* data, size_t len) { - if (!client->canSend()) { + if (!client || !client->canSend()) { // Serial.println("SF 1"); return 0; } @@ -219,6 +219,9 @@ void AsyncWebSocketMessage::ack(size_t len, uint32_t time) { } size_t AsyncWebSocketMessage::send(AsyncClient* client) { + if (!client) + return 0; + if (_status != WS_MSG_SENDING) return 0; if (_acked < _ack) { @@ -343,7 +346,7 @@ void AsyncWebSocketClient::_onPoll() { #ifdef ESP32 std::unique_lock lock(_lock); #endif - if (_client->canSend() && (!_controlQueue.empty() || !_messageQueue.empty())) { + if (_client && _client->canSend() && (!_controlQueue.empty() || !_messageQueue.empty())) { _runQueue(); } else if (_keepAlivePeriod > 0 && (millis() - _lastMessageTime) >= _keepAlivePeriod && (_controlQueue.empty() && _messageQueue.empty())) { #ifdef ESP32 @@ -478,6 +481,8 @@ void AsyncWebSocketClient::_onError(int8_t) { } void AsyncWebSocketClient::_onTimeout(uint32_t time) { + if (!_client) + return; // Serial.println("onTime"); (void)time; _client->close(true); @@ -485,7 +490,7 @@ void AsyncWebSocketClient::_onTimeout(uint32_t time) { void AsyncWebSocketClient::_onDisconnect() { // Serial.println("onDis"); - _client = NULL; + _client = nullptr; } void AsyncWebSocketClient::_onData(void* pbuf, size_t plen) { @@ -552,10 +557,12 @@ void AsyncWebSocketClient::_onData(void* pbuf, size_t plen) { } if (_status == WS_DISCONNECTING) { _status = WS_DISCONNECTED; - _client->close(true); + if (_client) + _client->close(true); } else { _status = WS_DISCONNECTING; - _client->ackLater(); + if (_client) + _client->ackLater(); _queueControl(WS_DISCONNECT, data, datalen); } } else if (_pinfo.opcode == WS_PING) { From c2ac7b251841e6a6097780ae708bf537a7fac6e5 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Fri, 4 Oct 2024 12:44:17 +0200 Subject: [PATCH 417/551] Updated enum constants --- src/AsyncEventSource.cpp | 2 +- src/AsyncEventSource.h | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/AsyncEventSource.cpp b/src/AsyncEventSource.cpp index 0f1ffa601..5e028fa20 100644 --- a/src/AsyncEventSource.cpp +++ b/src/AsyncEventSource.cpp @@ -370,7 +370,7 @@ AsyncEventSource::SendStatus AsyncEventSource::send( else ++miss; } - return hits == 0 ? NOT_SENT : (miss == 0 ? FULLY_SENT : PARTIALLY_SEND); + return hits == 0 ? DISCARDED : (miss == 0 ? ENQUEUED : PARTIALLY_ENQUEUED); } size_t AsyncEventSource::count() const { diff --git a/src/AsyncEventSource.h b/src/AsyncEventSource.h index cd7c70ca3..24a4312ad 100644 --- a/src/AsyncEventSource.h +++ b/src/AsyncEventSource.h @@ -119,9 +119,9 @@ class AsyncEventSource : public AsyncWebHandler { public: typedef enum { - NOT_SENT = 0, // sent to no client - FULLY_SENT = 1, // sent to all clients - PARTIALLY_SEND = 2, // sent to some clients + DISCARDED = 0, // sent to no client + ENQUEUED = 1, // sent to all clients + PARTIALLY_ENQUEUED = 2, // sent to some clients } SendStatus; AsyncEventSource(const String& url) : _url(url) {}; From afe9e1f82d929f6d05c08dbe5b26c4129b791eac Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Fri, 4 Oct 2024 12:45:15 +0200 Subject: [PATCH 418/551] Improved WebSocket API to get feedback whether message is enqueued - Now returns bool on client send() methods - Now returns SendStatus on global send() methods --- src/AsyncEventSource.h | 1 + src/AsyncWebSocket.cpp | 271 ++++++++++++++++++++++++----------------- src/AsyncWebSocket.h | 108 ++++++++-------- 3 files changed, 214 insertions(+), 166 deletions(-) diff --git a/src/AsyncEventSource.h b/src/AsyncEventSource.h index 24a4312ad..f04da18ac 100644 --- a/src/AsyncEventSource.h +++ b/src/AsyncEventSource.h @@ -130,6 +130,7 @@ class AsyncEventSource : public AsyncWebHandler { const char* url() const { return _url.c_str(); } void close(); void onConnect(ArEventHandlerFunction cb) { _connectcb = cb; } + // The client pointer sent to the callback is only for reference purposes. DO NOT CALL ANY METHOD ON IT ! void onDisconnect(ArEventHandlerFunction cb) { _disconnectcb = cb; } void authorizeConnect(ArAuthorizeConnectHandler cb); SendStatus send(const String& message, const String& event, uint32_t id = 0, uint32_t reconnect = 0) { return send(message.c_str(), event.c_str(), id, reconnect); } diff --git a/src/AsyncWebSocket.cpp b/src/AsyncWebSocket.cpp index dafe7906b..8dd624443 100644 --- a/src/AsyncWebSocket.cpp +++ b/src/AsyncWebSocket.cpp @@ -391,9 +391,9 @@ bool AsyncWebSocketClient::canSend() const { return _messageQueue.size() < WS_MAX_QUEUED_MESSAGES; } -void AsyncWebSocketClient::_queueControl(uint8_t opcode, const uint8_t* data, size_t len, bool mask) { +bool AsyncWebSocketClient::_queueControl(uint8_t opcode, const uint8_t* data, size_t len, bool mask) { if (!_client) - return; + return false; #ifdef ESP32 std::lock_guard lock(_lock); @@ -403,11 +403,13 @@ void AsyncWebSocketClient::_queueControl(uint8_t opcode, const uint8_t* data, si if (_client && _client->canSend()) _runQueue(); + + return true; } -void AsyncWebSocketClient::_queueMessage(AsyncWebSocketSharedBuffer buffer, uint8_t opcode, bool mask) { +bool AsyncWebSocketClient::_queueMessage(AsyncWebSocketSharedBuffer buffer, uint8_t opcode, bool mask) { if (!_client || buffer->size() == 0 || _status != WS_CONNECTED) - return; + return false; #ifdef ESP32 std::lock_guard lock(_lock); @@ -434,14 +436,15 @@ void AsyncWebSocketClient::_queueMessage(AsyncWebSocketSharedBuffer buffer, uint #endif } - return; - - } else { - _messageQueue.emplace_back(buffer, opcode, mask); + return false; } + _messageQueue.emplace_back(buffer, opcode, mask); + if (_client && _client->canSend()) _runQueue(); + + return true; } void AsyncWebSocketClient::close(uint16_t code, const char* message) { @@ -471,9 +474,8 @@ void AsyncWebSocketClient::close(uint16_t code, const char* message) { _queueControl(WS_DISCONNECT); } -void AsyncWebSocketClient::ping(const uint8_t* data, size_t len) { - if (_status == WS_CONNECTED) - _queueControl(WS_PING, data, len); +bool AsyncWebSocketClient::ping(const uint8_t* data, size_t len) { + return _status == WS_CONNECTED && _queueControl(WS_PING, data, len); } void AsyncWebSocketClient::_onError(int8_t) { @@ -610,9 +612,9 @@ size_t AsyncWebSocketClient::printf(const char* format, ...) { len = vsnprintf(buffer, len + 1, format, arg); va_end(arg); - text(buffer, len); + bool enqueued = text(buffer, len); delete[] buffer; - return len; + return enqueued ? len : 0; } #ifdef ESP8266 @@ -634,9 +636,9 @@ size_t AsyncWebSocketClient::printf_P(PGM_P formatP, ...) { len = vsnprintf_P(buffer, len + 1, formatP, arg); va_end(arg); - text(buffer, len); + bool enqueued = text(buffer, len); delete[] buffer; - return len; + return enqueued ? len : 0; } #endif @@ -648,35 +650,37 @@ namespace { } } -void AsyncWebSocketClient::text(AsyncWebSocketMessageBuffer* buffer) { +bool AsyncWebSocketClient::text(AsyncWebSocketMessageBuffer* buffer) { + bool enqueued = false; if (buffer) { - text(std::move(buffer->_buffer)); + enqueued = text(std::move(buffer->_buffer)); delete buffer; } + return enqueued; } -void AsyncWebSocketClient::text(AsyncWebSocketSharedBuffer buffer) { - _queueMessage(buffer); +bool AsyncWebSocketClient::text(AsyncWebSocketSharedBuffer buffer) { + return _queueMessage(buffer); } -void AsyncWebSocketClient::text(const uint8_t* message, size_t len) { - text(makeSharedBuffer(message, len)); +bool AsyncWebSocketClient::text(const uint8_t* message, size_t len) { + return text(makeSharedBuffer(message, len)); } -void AsyncWebSocketClient::text(const char* message, size_t len) { - text((const uint8_t*)message, len); +bool AsyncWebSocketClient::text(const char* message, size_t len) { + return text((const uint8_t*)message, len); } -void AsyncWebSocketClient::text(const char* message) { - text(message, strlen(message)); +bool AsyncWebSocketClient::text(const char* message) { + return text(message, strlen(message)); } -void AsyncWebSocketClient::text(const String& message) { - text(message.c_str(), message.length()); +bool AsyncWebSocketClient::text(const String& message) { + return text(message.c_str(), message.length()); } #ifdef ESP8266 -void AsyncWebSocketClient::text(const __FlashStringHelper* data) { +bool AsyncWebSocketClient::text(const __FlashStringHelper* data) { PGM_P p = reinterpret_cast(data); size_t n = 0; @@ -687,51 +691,57 @@ void AsyncWebSocketClient::text(const __FlashStringHelper* data) { } char* message = (char*)malloc(n + 1); + bool enqueued = false; if (message) { memcpy_P(message, p, n); message[n] = 0; - text(message, n); + enqueued = text(message, n); free(message); } + return enqueued; } #endif // ESP8266 -void AsyncWebSocketClient::binary(AsyncWebSocketMessageBuffer* buffer) { +bool AsyncWebSocketClient::binary(AsyncWebSocketMessageBuffer* buffer) { + bool enqueued = false; if (buffer) { - binary(std::move(buffer->_buffer)); + enqueued = binary(std::move(buffer->_buffer)); delete buffer; } + return enqueued; } -void AsyncWebSocketClient::binary(AsyncWebSocketSharedBuffer buffer) { - _queueMessage(buffer, WS_BINARY); +bool AsyncWebSocketClient::binary(AsyncWebSocketSharedBuffer buffer) { + return _queueMessage(buffer, WS_BINARY); } -void AsyncWebSocketClient::binary(const uint8_t* message, size_t len) { - binary(makeSharedBuffer(message, len)); +bool AsyncWebSocketClient::binary(const uint8_t* message, size_t len) { + return binary(makeSharedBuffer(message, len)); } -void AsyncWebSocketClient::binary(const char* message, size_t len) { - binary((const uint8_t*)message, len); +bool AsyncWebSocketClient::binary(const char* message, size_t len) { + return binary((const uint8_t*)message, len); } -void AsyncWebSocketClient::binary(const char* message) { - binary(message, strlen(message)); +bool AsyncWebSocketClient::binary(const char* message) { + return binary(message, strlen(message)); } -void AsyncWebSocketClient::binary(const String& message) { - binary(message.c_str(), message.length()); +bool AsyncWebSocketClient::binary(const String& message) { + return binary(message.c_str(), message.length()); } #ifdef ESP8266 -void AsyncWebSocketClient::binary(const __FlashStringHelper* data, size_t len) { +bool AsyncWebSocketClient::binary(const __FlashStringHelper* data, size_t len) { PGM_P p = reinterpret_cast(data); char* message = (char*)malloc(len); + bool enqueued = false; if (message) { memcpy_P(message, p, len); - binary(message, len); + enqueued = binary(message, len); free(message); } + return enqueued; } #endif @@ -810,33 +820,38 @@ void AsyncWebSocket::cleanupClients(uint16_t maxClients) { } } -void AsyncWebSocket::ping(uint32_t id, const uint8_t* data, size_t len) { - if (AsyncWebSocketClient* c = client(id)) - c->ping(data, len); +bool AsyncWebSocket::ping(uint32_t id, const uint8_t* data, size_t len) { + AsyncWebSocketClient* c = client(id); + return c && c->ping(data, len); } -void AsyncWebSocket::pingAll(const uint8_t* data, size_t len) { +AsyncWebSocket::SendStatus AsyncWebSocket::pingAll(const uint8_t* data, size_t len) { + size_t hit = 0; + size_t miss = 0; for (auto& c : _clients) - if (c.status() == WS_CONNECTED) - c.ping(data, len); + if (c.status() == WS_CONNECTED && c.ping(data, len)) + hit++; + else + miss++; + return hit == 0 ? DISCARDED : (miss == 0 ? ENQUEUED : PARTIALLY_ENQUEUED); } -void AsyncWebSocket::text(uint32_t id, const uint8_t* message, size_t len) { - if (AsyncWebSocketClient* c = client(id)) - c->text(makeSharedBuffer(message, len)); +bool AsyncWebSocket::text(uint32_t id, const uint8_t* message, size_t len) { + AsyncWebSocketClient* c = client(id); + return c && c->text(makeSharedBuffer(message, len)); } -void AsyncWebSocket::text(uint32_t id, const char* message, size_t len) { - text(id, (const uint8_t*)message, len); +bool AsyncWebSocket::text(uint32_t id, const char* message, size_t len) { + return text(id, (const uint8_t*)message, len); } -void AsyncWebSocket::text(uint32_t id, const char* message) { - text(id, message, strlen(message)); +bool AsyncWebSocket::text(uint32_t id, const char* message) { + return text(id, message, strlen(message)); } -void AsyncWebSocket::text(uint32_t id, const String& message) { - text(id, message.c_str(), message.length()); +bool AsyncWebSocket::text(uint32_t id, const String& message) { + return text(id, message.c_str(), message.length()); } #ifdef ESP8266 -void AsyncWebSocket::text(uint32_t id, const __FlashStringHelper* data) { +bool AsyncWebSocket::text(uint32_t id, const __FlashStringHelper* data) { PGM_P p = reinterpret_cast(data); size_t n = 0; @@ -847,40 +862,44 @@ void AsyncWebSocket::text(uint32_t id, const __FlashStringHelper* data) { } char* message = (char*)malloc(n + 1); + bool enqueued = false; if (message) { memcpy_P(message, p, n); message[n] = 0; - text(id, message, n); + enqueued = text(id, message, n); free(message); } + return enqueued; } #endif // ESP8266 -void AsyncWebSocket::text(uint32_t id, AsyncWebSocketMessageBuffer* buffer) { +bool AsyncWebSocket::text(uint32_t id, AsyncWebSocketMessageBuffer* buffer) { + bool enqueued = false; if (buffer) { - text(id, std::move(buffer->_buffer)); + enqueued = text(id, std::move(buffer->_buffer)); delete buffer; } + return enqueued; } -void AsyncWebSocket::text(uint32_t id, AsyncWebSocketSharedBuffer buffer) { - if (AsyncWebSocketClient* c = client(id)) - c->text(buffer); +bool AsyncWebSocket::text(uint32_t id, AsyncWebSocketSharedBuffer buffer) { + AsyncWebSocketClient* c = client(id); + return c && c->text(buffer); } -void AsyncWebSocket::textAll(const uint8_t* message, size_t len) { - textAll(makeSharedBuffer(message, len)); +AsyncWebSocket::SendStatus AsyncWebSocket::textAll(const uint8_t* message, size_t len) { + return textAll(makeSharedBuffer(message, len)); } -void AsyncWebSocket::textAll(const char* message, size_t len) { - textAll((const uint8_t*)message, len); +AsyncWebSocket::SendStatus AsyncWebSocket::textAll(const char* message, size_t len) { + return textAll((const uint8_t*)message, len); } -void AsyncWebSocket::textAll(const char* message) { - textAll(message, strlen(message)); +AsyncWebSocket::SendStatus AsyncWebSocket::textAll(const char* message) { + return textAll(message, strlen(message)); } -void AsyncWebSocket::textAll(const String& message) { - textAll(message.c_str(), message.length()); +AsyncWebSocket::SendStatus AsyncWebSocket::textAll(const String& message) { + return textAll(message.c_str(), message.length()); } #ifdef ESP8266 -void AsyncWebSocket::textAll(const __FlashStringHelper* data) { +AsyncWebSocket::SendStatus AsyncWebSocket::textAll(const __FlashStringHelper* data) { PGM_P p = reinterpret_cast(data); size_t n = 0; @@ -891,99 +910,121 @@ void AsyncWebSocket::textAll(const __FlashStringHelper* data) { } char* message = (char*)malloc(n + 1); + AsyncWebSocket::SendStatus status = DISCARDED; if (message) { memcpy_P(message, p, n); message[n] = 0; - textAll(message, n); + status = textAll(message, n); free(message); } + return status; } #endif // ESP8266 -void AsyncWebSocket::textAll(AsyncWebSocketMessageBuffer* buffer) { +AsyncWebSocket::SendStatus AsyncWebSocket::textAll(AsyncWebSocketMessageBuffer* buffer) { + AsyncWebSocket::SendStatus status = DISCARDED; if (buffer) { - textAll(std::move(buffer->_buffer)); + status = textAll(std::move(buffer->_buffer)); delete buffer; } + return status; } -void AsyncWebSocket::textAll(AsyncWebSocketSharedBuffer buffer) { +AsyncWebSocket::SendStatus AsyncWebSocket::textAll(AsyncWebSocketSharedBuffer buffer) { + size_t hit = 0; + size_t miss = 0; for (auto& c : _clients) - if (c.status() == WS_CONNECTED) - c.text(buffer); + if (c.status() == WS_CONNECTED && c.text(buffer)) + hit++; + else + miss++; + return hit == 0 ? DISCARDED : (miss == 0 ? ENQUEUED : PARTIALLY_ENQUEUED); } -void AsyncWebSocket::binary(uint32_t id, const uint8_t* message, size_t len) { - if (AsyncWebSocketClient* c = client(id)) - c->binary(makeSharedBuffer(message, len)); +bool AsyncWebSocket::binary(uint32_t id, const uint8_t* message, size_t len) { + AsyncWebSocketClient* c = client(id); + return c && c->binary(makeSharedBuffer(message, len)); } -void AsyncWebSocket::binary(uint32_t id, const char* message, size_t len) { - binary(id, (const uint8_t*)message, len); +bool AsyncWebSocket::binary(uint32_t id, const char* message, size_t len) { + return binary(id, (const uint8_t*)message, len); } -void AsyncWebSocket::binary(uint32_t id, const char* message) { - binary(id, message, strlen(message)); +bool AsyncWebSocket::binary(uint32_t id, const char* message) { + return binary(id, message, strlen(message)); } -void AsyncWebSocket::binary(uint32_t id, const String& message) { - binary(id, message.c_str(), message.length()); +bool AsyncWebSocket::binary(uint32_t id, const String& message) { + return binary(id, message.c_str(), message.length()); } #ifdef ESP8266 -void AsyncWebSocket::binary(uint32_t id, const __FlashStringHelper* data, size_t len) { +bool AsyncWebSocket::binary(uint32_t id, const __FlashStringHelper* data, size_t len) { PGM_P p = reinterpret_cast(data); char* message = (char*)malloc(len); + bool enqueued = false; if (message) { memcpy_P(message, p, len); - binary(id, message, len); + enqueued = binary(id, message, len); free(message); } + return enqueued; } #endif // ESP8266 -void AsyncWebSocket::binary(uint32_t id, AsyncWebSocketMessageBuffer* buffer) { +bool AsyncWebSocket::binary(uint32_t id, AsyncWebSocketMessageBuffer* buffer) { + bool enqueued = false; if (buffer) { - binary(id, std::move(buffer->_buffer)); + enqueued = binary(id, std::move(buffer->_buffer)); delete buffer; } + return enqueued; } -void AsyncWebSocket::binary(uint32_t id, AsyncWebSocketSharedBuffer buffer) { - if (AsyncWebSocketClient* c = client(id)) - c->binary(buffer); +bool AsyncWebSocket::binary(uint32_t id, AsyncWebSocketSharedBuffer buffer) { + AsyncWebSocketClient* c = client(id); + return c && c->binary(buffer); } -void AsyncWebSocket::binaryAll(const uint8_t* message, size_t len) { - binaryAll(makeSharedBuffer(message, len)); +AsyncWebSocket::SendStatus AsyncWebSocket::binaryAll(const uint8_t* message, size_t len) { + return binaryAll(makeSharedBuffer(message, len)); } -void AsyncWebSocket::binaryAll(const char* message, size_t len) { - binaryAll((const uint8_t*)message, len); +AsyncWebSocket::SendStatus AsyncWebSocket::binaryAll(const char* message, size_t len) { + return binaryAll((const uint8_t*)message, len); } -void AsyncWebSocket::binaryAll(const char* message) { - binaryAll(message, strlen(message)); +AsyncWebSocket::SendStatus AsyncWebSocket::binaryAll(const char* message) { + return binaryAll(message, strlen(message)); } -void AsyncWebSocket::binaryAll(const String& message) { - binaryAll(message.c_str(), message.length()); +AsyncWebSocket::SendStatus AsyncWebSocket::binaryAll(const String& message) { + return binaryAll(message.c_str(), message.length()); } #ifdef ESP8266 -void AsyncWebSocket::binaryAll(const __FlashStringHelper* data, size_t len) { +AsyncWebSocket::SendStatus AsyncWebSocket::binaryAll(const __FlashStringHelper* data, size_t len) { PGM_P p = reinterpret_cast(data); char* message = (char*)malloc(len); + AsyncWebSocket::SendStatus status = DISCARDED; if (message) { memcpy_P(message, p, len); - binaryAll(message, len); + status = binaryAll(message, len); free(message); } + return status; } #endif // ESP8266 -void AsyncWebSocket::binaryAll(AsyncWebSocketMessageBuffer* buffer) { +AsyncWebSocket::SendStatus AsyncWebSocket::binaryAll(AsyncWebSocketMessageBuffer* buffer) { + AsyncWebSocket::SendStatus status = DISCARDED; if (buffer) { - binaryAll(std::move(buffer->_buffer)); + status = binaryAll(std::move(buffer->_buffer)); delete buffer; } + return status; } -void AsyncWebSocket::binaryAll(AsyncWebSocketSharedBuffer buffer) { +AsyncWebSocket::SendStatus AsyncWebSocket::binaryAll(AsyncWebSocketSharedBuffer buffer) { + size_t hit = 0; + size_t miss = 0; for (auto& c : _clients) - if (c.status() == WS_CONNECTED) - c.binary(buffer); + if (c.status() == WS_CONNECTED && c.binary(buffer)) + hit++; + else + miss++; + return hit == 0 ? DISCARDED : (miss == 0 ? ENQUEUED : PARTIALLY_ENQUEUED); } size_t AsyncWebSocket::printf(uint32_t id, const char* format, ...) { @@ -1016,9 +1057,9 @@ size_t AsyncWebSocket::printfAll(const char* format, ...) { len = vsnprintf(buffer, len + 1, format, arg); va_end(arg); - textAll(buffer, len); + AsyncWebSocket::SendStatus status = textAll(buffer, len); delete[] buffer; - return len; + return status == DISCARDED ? 0 : len; } #ifdef ESP8266 @@ -1052,9 +1093,9 @@ size_t AsyncWebSocket::printfAll_P(PGM_P formatP, ...) { len = vsnprintf_P(buffer, len + 1, formatP, arg); va_end(arg); - textAll(buffer, len); + AsyncWebSocket::SendStatus status = textAll(buffer, len); delete[] buffer; - return len; + return status == DISCARDED ? 0 : len; } #endif diff --git a/src/AsyncWebSocket.h b/src/AsyncWebSocket.h index 1da3d159c..f139e4514 100644 --- a/src/AsyncWebSocket.h +++ b/src/AsyncWebSocket.h @@ -164,8 +164,8 @@ class AsyncWebSocketClient { uint32_t _lastMessageTime; uint32_t _keepAlivePeriod; - void _queueControl(uint8_t opcode, const uint8_t* data = NULL, size_t len = 0, bool mask = false); - void _queueMessage(AsyncWebSocketSharedBuffer buffer, uint8_t opcode = WS_TEXT, bool mask = false); + bool _queueControl(uint8_t opcode, const uint8_t* data = NULL, size_t len = 0, bool mask = false); + bool _queueMessage(AsyncWebSocketSharedBuffer buffer, uint8_t opcode = WS_TEXT, bool mask = false); void _runQueue(); void _clearQueue(); @@ -212,7 +212,7 @@ class AsyncWebSocketClient { // control frames void close(uint16_t code = 0, const char* message = NULL); - void ping(const uint8_t* data = NULL, size_t len = 0); + bool ping(const uint8_t* data = NULL, size_t len = 0); // set auto-ping period in seconds. disabled if zero (default) void keepAlivePeriod(uint16_t seconds) { @@ -229,19 +229,19 @@ class AsyncWebSocketClient { size_t printf(const char* format, ...) __attribute__((format(printf, 2, 3))); - void text(AsyncWebSocketSharedBuffer buffer); - void text(const uint8_t* message, size_t len); - void text(const char* message, size_t len); - void text(const char* message); - void text(const String& message); - void text(AsyncWebSocketMessageBuffer* buffer); + bool text(AsyncWebSocketSharedBuffer buffer); + bool text(const uint8_t* message, size_t len); + bool text(const char* message, size_t len); + bool text(const char* message); + bool text(const String& message); + bool text(AsyncWebSocketMessageBuffer* buffer); - void binary(AsyncWebSocketSharedBuffer buffer); - void binary(const uint8_t* message, size_t len); - void binary(const char* message, size_t len); - void binary(const char* message); - void binary(const String& message); - void binary(AsyncWebSocketMessageBuffer* buffer); + bool binary(AsyncWebSocketSharedBuffer buffer); + bool binary(const uint8_t* message, size_t len); + bool binary(const char* message, size_t len); + bool binary(const char* message); + bool binary(const String& message); + bool binary(AsyncWebSocketMessageBuffer* buffer); bool canSend() const; @@ -255,8 +255,8 @@ class AsyncWebSocketClient { #ifdef ESP8266 size_t printf_P(PGM_P formatP, ...) __attribute__((format(printf, 2, 3))); - void text(const __FlashStringHelper* message); - void binary(const __FlashStringHelper* message, size_t len); + bool text(const __FlashStringHelper* message); + bool binary(const __FlashStringHelper* message, size_t len); #endif }; @@ -277,6 +277,12 @@ class AsyncWebSocket : public AsyncWebHandler { #endif public: + typedef enum { + DISCARDED = 0, // sent to no client + ENQUEUED = 1, // sent to all clients + PARTIALLY_ENQUEUED = 2, // sent to some clients + } SendStatus; + explicit AsyncWebSocket(const char* url) : _url(url), _cNextId(1), _enabled(true) {} AsyncWebSocket(const String& url) : _url(url), _cNextId(1), _enabled(true) {} ~AsyncWebSocket() {}; @@ -294,45 +300,45 @@ class AsyncWebSocket : public AsyncWebHandler { void closeAll(uint16_t code = 0, const char* message = NULL); void cleanupClients(uint16_t maxClients = DEFAULT_MAX_WS_CLIENTS); - void ping(uint32_t id, const uint8_t* data = NULL, size_t len = 0); - void pingAll(const uint8_t* data = NULL, size_t len = 0); // done - - void text(uint32_t id, const uint8_t* message, size_t len); - void text(uint32_t id, const char* message, size_t len); - void text(uint32_t id, const char* message); - void text(uint32_t id, const String& message); - void text(uint32_t id, AsyncWebSocketMessageBuffer* buffer); - void text(uint32_t id, AsyncWebSocketSharedBuffer buffer); - - void textAll(const uint8_t* message, size_t len); - void textAll(const char* message, size_t len); - void textAll(const char* message); - void textAll(const String& message); - void textAll(AsyncWebSocketMessageBuffer* buffer); - void textAll(AsyncWebSocketSharedBuffer buffer); - - void binary(uint32_t id, const uint8_t* message, size_t len); - void binary(uint32_t id, const char* message, size_t len); - void binary(uint32_t id, const char* message); - void binary(uint32_t id, const String& message); - void binary(uint32_t id, AsyncWebSocketMessageBuffer* buffer); - void binary(uint32_t id, AsyncWebSocketSharedBuffer buffer); - - void binaryAll(const uint8_t* message, size_t len); - void binaryAll(const char* message, size_t len); - void binaryAll(const char* message); - void binaryAll(const String& message); - void binaryAll(AsyncWebSocketMessageBuffer* buffer); - void binaryAll(AsyncWebSocketSharedBuffer buffer); + bool ping(uint32_t id, const uint8_t* data = NULL, size_t len = 0); + SendStatus pingAll(const uint8_t* data = NULL, size_t len = 0); // done + + bool text(uint32_t id, const uint8_t* message, size_t len); + bool text(uint32_t id, const char* message, size_t len); + bool text(uint32_t id, const char* message); + bool text(uint32_t id, const String& message); + bool text(uint32_t id, AsyncWebSocketMessageBuffer* buffer); + bool text(uint32_t id, AsyncWebSocketSharedBuffer buffer); + + SendStatus textAll(const uint8_t* message, size_t len); + SendStatus textAll(const char* message, size_t len); + SendStatus textAll(const char* message); + SendStatus textAll(const String& message); + SendStatus textAll(AsyncWebSocketMessageBuffer* buffer); + SendStatus textAll(AsyncWebSocketSharedBuffer buffer); + + bool binary(uint32_t id, const uint8_t* message, size_t len); + bool binary(uint32_t id, const char* message, size_t len); + bool binary(uint32_t id, const char* message); + bool binary(uint32_t id, const String& message); + bool binary(uint32_t id, AsyncWebSocketMessageBuffer* buffer); + bool binary(uint32_t id, AsyncWebSocketSharedBuffer buffer); + + SendStatus binaryAll(const uint8_t* message, size_t len); + SendStatus binaryAll(const char* message, size_t len); + SendStatus binaryAll(const char* message); + SendStatus binaryAll(const String& message); + SendStatus binaryAll(AsyncWebSocketMessageBuffer* buffer); + SendStatus binaryAll(AsyncWebSocketSharedBuffer buffer); size_t printf(uint32_t id, const char* format, ...) __attribute__((format(printf, 3, 4))); size_t printfAll(const char* format, ...) __attribute__((format(printf, 2, 3))); #ifdef ESP8266 - void text(uint32_t id, const __FlashStringHelper* message); - void textAll(const __FlashStringHelper* message); - void binary(uint32_t id, const __FlashStringHelper* message, size_t len); - void binaryAll(const __FlashStringHelper* message, size_t len); + bool text(uint32_t id, const __FlashStringHelper* message); + SendStatus textAll(const __FlashStringHelper* message); + bool binary(uint32_t id, const __FlashStringHelper* message, size_t len); + SendStatus binaryAll(const __FlashStringHelper* message, size_t len); size_t printf_P(uint32_t id, PGM_P formatP, ...) __attribute__((format(printf, 3, 4))); size_t printfAll_P(PGM_P formatP, ...) __attribute__((format(printf, 2, 3))); #endif From a8a314427be6a81126d9b1d43a5fa1716c4d53a3 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Fri, 4 Oct 2024 13:28:48 +0200 Subject: [PATCH 419/551] v3.3.11 --- README.md | 2 +- docs/index.md | 2 +- library.json | 2 +- library.properties | 2 +- src/ESPAsyncWebServer.h | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index ee0fa52dc..2151d0717 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo ```ini lib_compat_mode = strict lib_ldf_mode = chain -lib_deps = mathieucarbou/ESPAsyncWebServer @ 3.3.10 +lib_deps = mathieucarbou/ESPAsyncWebServer @ 3.3.11 ``` **Dependencies:** diff --git a/docs/index.md b/docs/index.md index ee0fa52dc..2151d0717 100644 --- a/docs/index.md +++ b/docs/index.md @@ -34,7 +34,7 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo ```ini lib_compat_mode = strict lib_ldf_mode = chain -lib_deps = mathieucarbou/ESPAsyncWebServer @ 3.3.10 +lib_deps = mathieucarbou/ESPAsyncWebServer @ 3.3.11 ``` **Dependencies:** diff --git a/library.json b/library.json index cbe666f03..10b527518 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "ESPAsyncWebServer", - "version": "3.3.10", + "version": "3.3.11", "description": "Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 and RP2040. Supports: WebSocket, SSE, Authentication, Arduino Json 7, File Upload, Static File serving, URL Rewrite, URL Redirect, etc.", "keywords": "http,async,websocket,webserver", "homepage": "https://github.com/mathieucarbou/ESPAsyncWebServer", diff --git a/library.properties b/library.properties index 66c9417ad..aecdeb0f7 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=ESPAsyncWebServer -version=3.3.10 +version=3.3.11 author=Me-No-Dev maintainer=Mathieu Carbou sentence=Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 and RP2040 diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index 4d3adaa96..2bb910556 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -48,10 +48,10 @@ #include "literals.h" -#define ASYNCWEBSERVER_VERSION "3.3.10" +#define ASYNCWEBSERVER_VERSION "3.3.11" #define ASYNCWEBSERVER_VERSION_MAJOR 3 #define ASYNCWEBSERVER_VERSION_MINOR 3 -#define ASYNCWEBSERVER_VERSION_REVISION 10 +#define ASYNCWEBSERVER_VERSION_REVISION 11 #define ASYNCWEBSERVER_FORK_mathieucarbou #ifdef ASYNCWEBSERVER_REGEX From 2bae2a8086ca88ceed664ad2c10cb3023ecf7986 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Sat, 5 Oct 2024 23:16:55 +0200 Subject: [PATCH 420/551] v3.3.12 --- README.md | 2 +- docs/index.md | 2 +- library.json | 2 +- library.properties | 7 ++++--- src/ESPAsyncWebServer.h | 4 ++-- 5 files changed, 9 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 2151d0717..81f360713 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo ```ini lib_compat_mode = strict lib_ldf_mode = chain -lib_deps = mathieucarbou/ESPAsyncWebServer @ 3.3.11 +lib_deps = mathieucarbou/ESPAsyncWebServer @ 3.3.12 ``` **Dependencies:** diff --git a/docs/index.md b/docs/index.md index 2151d0717..81f360713 100644 --- a/docs/index.md +++ b/docs/index.md @@ -34,7 +34,7 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo ```ini lib_compat_mode = strict lib_ldf_mode = chain -lib_deps = mathieucarbou/ESPAsyncWebServer @ 3.3.11 +lib_deps = mathieucarbou/ESPAsyncWebServer @ 3.3.12 ``` **Dependencies:** diff --git a/library.json b/library.json index 10b527518..0fe40b53a 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "ESPAsyncWebServer", - "version": "3.3.11", + "version": "3.3.12", "description": "Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 and RP2040. Supports: WebSocket, SSE, Authentication, Arduino Json 7, File Upload, Static File serving, URL Rewrite, URL Redirect, etc.", "keywords": "http,async,websocket,webserver", "homepage": "https://github.com/mathieucarbou/ESPAsyncWebServer", diff --git a/library.properties b/library.properties index aecdeb0f7..751a36363 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,6 @@ -name=ESPAsyncWebServer -version=3.3.11 +name=ESP Async WebServer +includes=ESPAsyncWebServer.h +version=3.3.12 author=Me-No-Dev maintainer=Mathieu Carbou sentence=Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 and RP2040 @@ -7,4 +8,4 @@ paragraph=Supports: WebSocket, SSE, Authentication, Arduino Json 7, File Upload, category=Other url=https://github.com/mathieucarbou/ESPAsyncWebServer architectures=* -license=LGPL-3.0 +license=LGPL-3.0 \ No newline at end of file diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index 2bb910556..bd6800273 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -48,10 +48,10 @@ #include "literals.h" -#define ASYNCWEBSERVER_VERSION "3.3.11" +#define ASYNCWEBSERVER_VERSION "3.3.12" #define ASYNCWEBSERVER_VERSION_MAJOR 3 #define ASYNCWEBSERVER_VERSION_MINOR 3 -#define ASYNCWEBSERVER_VERSION_REVISION 11 +#define ASYNCWEBSERVER_VERSION_REVISION 12 #define ASYNCWEBSERVER_FORK_mathieucarbou #ifdef ASYNCWEBSERVER_REGEX From 523edc16ef66d86e5ef6413b5ebf1d55c4a4274a Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Mon, 7 Oct 2024 14:24:25 +0200 Subject: [PATCH 421/551] mathieucarbou/AsyncTCP @ 3.2.7 --- .github/workflows/ci.yml | 2 +- README.md | 2 +- docs/index.md | 2 +- library.json | 2 +- platformio.ini | 6 +++--- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c08191b75..f8bf4c7e1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -55,7 +55,7 @@ jobs: - name: Install AsyncTCP (ESP32) if: ${{ matrix.core == 'esp32:esp32' }} - run: ARDUINO_LIBRARY_ENABLE_UNSAFE_INSTALL=true arduino-cli lib install --git-url https://github.com/mathieucarbou/AsyncTCP#v3.2.6 + run: ARDUINO_LIBRARY_ENABLE_UNSAFE_INSTALL=true arduino-cli lib install --git-url https://github.com/mathieucarbou/AsyncTCP#v3.2.7 - name: Install ESPAsyncTCP (ESP8266) if: ${{ matrix.core == 'esp8266:esp8266' }} diff --git a/README.md b/README.md index 81f360713..cb6a04c06 100644 --- a/README.md +++ b/README.md @@ -39,7 +39,7 @@ lib_deps = mathieucarbou/ESPAsyncWebServer @ 3.3.12 **Dependencies:** -- **ESP32**: `mathieucarbou/AsyncTCP @ 3.2.6` (Arduino IDE: [https://github.com/mathieucarbou/AsyncTCP#v3.2.6](https://github.com/mathieucarbou/AsyncTCP/releases)) +- **ESP32**: `mathieucarbou/AsyncTCP @ 3.2.7` (Arduino IDE: [https://github.com/mathieucarbou/AsyncTCP#v3.2.7](https://github.com/mathieucarbou/AsyncTCP/releases)) - **ESP8266**: `esphome/ESPAsyncTCP-esphome @ 2.0.0` (Arduino IDE: [https://github.com/mathieucarbou/esphome-ESPAsyncTCP#v2.0.0](https://github.com/mathieucarbou/esphome-ESPAsyncTCP/releases/tag/v2.0.0)) - **RP2040**: `khoih-prog/AsyncTCP_RP2040W @ 1.2.0` (Arduino IDE: [https://github.com/khoih-prog/AsyncTCP_RP2040W#v1.2.0](https://github.com/khoih-prog/AsyncTCP_RP2040W/releases/tag/v1.2.0)) diff --git a/docs/index.md b/docs/index.md index 81f360713..cb6a04c06 100644 --- a/docs/index.md +++ b/docs/index.md @@ -39,7 +39,7 @@ lib_deps = mathieucarbou/ESPAsyncWebServer @ 3.3.12 **Dependencies:** -- **ESP32**: `mathieucarbou/AsyncTCP @ 3.2.6` (Arduino IDE: [https://github.com/mathieucarbou/AsyncTCP#v3.2.6](https://github.com/mathieucarbou/AsyncTCP/releases)) +- **ESP32**: `mathieucarbou/AsyncTCP @ 3.2.7` (Arduino IDE: [https://github.com/mathieucarbou/AsyncTCP#v3.2.7](https://github.com/mathieucarbou/AsyncTCP/releases)) - **ESP8266**: `esphome/ESPAsyncTCP-esphome @ 2.0.0` (Arduino IDE: [https://github.com/mathieucarbou/esphome-ESPAsyncTCP#v2.0.0](https://github.com/mathieucarbou/esphome-ESPAsyncTCP/releases/tag/v2.0.0)) - **RP2040**: `khoih-prog/AsyncTCP_RP2040W @ 1.2.0` (Arduino IDE: [https://github.com/khoih-prog/AsyncTCP_RP2040W#v1.2.0](https://github.com/khoih-prog/AsyncTCP_RP2040W/releases/tag/v1.2.0)) diff --git a/library.json b/library.json index 0fe40b53a..17242e5b4 100644 --- a/library.json +++ b/library.json @@ -28,7 +28,7 @@ { "owner": "mathieucarbou", "name": "AsyncTCP", - "version": "^3.2.6", + "version": "^3.2.7", "platforms": "espressif32" }, { diff --git a/platformio.ini b/platformio.ini index 6fc704602..860e773a7 100644 --- a/platformio.ini +++ b/platformio.ini @@ -25,7 +25,7 @@ lib_deps = ; bblanchon/ArduinoJson @ 5.13.4 ; bblanchon/ArduinoJson @ 6.21.5 bblanchon/ArduinoJson @ 7.2.0 - mathieucarbou/AsyncTCP @ 3.2.6 + mathieucarbou/AsyncTCP @ 3.2.7 board = esp32dev board_build.partitions = partitions-4MB.csv board_build.filesystem = littlefs @@ -43,7 +43,7 @@ platform = https://github.com/pioarduino/platform-espressif32/releases/download/ ; board = esp32-s3-devkitc-1 ; board = esp32-c6-devkitc-1 lib_deps = - mathieucarbou/AsyncTCP @ 3.2.6 + mathieucarbou/AsyncTCP @ 3.2.7 [env:arduino-310rc1] platform = https://github.com/pioarduino/platform-espressif32/releases/download/53.03.10-rc1/platform-espressif32.zip @@ -87,7 +87,7 @@ board = ${sysenv.PIO_BOARD} platform = https://github.com/pioarduino/platform-espressif32/releases/download/51.03.05/platform-espressif32.zip board = ${sysenv.PIO_BOARD} lib_deps = - mathieucarbou/AsyncTCP @ 3.2.6 + mathieucarbou/AsyncTCP @ 3.2.7 [env:ci-arduino-310rc1] platform = https://github.com/pioarduino/platform-espressif32/releases/download/53.03.10-rc1/platform-espressif32.zip From dcd50e6320c81dd64f3bd257d577c4f5d2e6a036 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Mon, 7 Oct 2024 14:36:16 +0200 Subject: [PATCH 422/551] mathieucarbou/AsyncTCP @ 3.2.8 --- .github/workflows/ci.yml | 2 +- README.md | 2 +- docs/index.md | 2 +- library.json | 2 +- platformio.ini | 6 +++--- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f8bf4c7e1..4122271e1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -55,7 +55,7 @@ jobs: - name: Install AsyncTCP (ESP32) if: ${{ matrix.core == 'esp32:esp32' }} - run: ARDUINO_LIBRARY_ENABLE_UNSAFE_INSTALL=true arduino-cli lib install --git-url https://github.com/mathieucarbou/AsyncTCP#v3.2.7 + run: ARDUINO_LIBRARY_ENABLE_UNSAFE_INSTALL=true arduino-cli lib install --git-url https://github.com/mathieucarbou/AsyncTCP#v3.2.8 - name: Install ESPAsyncTCP (ESP8266) if: ${{ matrix.core == 'esp8266:esp8266' }} diff --git a/README.md b/README.md index cb6a04c06..c39850ba0 100644 --- a/README.md +++ b/README.md @@ -39,7 +39,7 @@ lib_deps = mathieucarbou/ESPAsyncWebServer @ 3.3.12 **Dependencies:** -- **ESP32**: `mathieucarbou/AsyncTCP @ 3.2.7` (Arduino IDE: [https://github.com/mathieucarbou/AsyncTCP#v3.2.7](https://github.com/mathieucarbou/AsyncTCP/releases)) +- **ESP32**: `mathieucarbou/AsyncTCP @ 3.2.8` (Arduino IDE: [https://github.com/mathieucarbou/AsyncTCP#v3.2.8](https://github.com/mathieucarbou/AsyncTCP/releases)) - **ESP8266**: `esphome/ESPAsyncTCP-esphome @ 2.0.0` (Arduino IDE: [https://github.com/mathieucarbou/esphome-ESPAsyncTCP#v2.0.0](https://github.com/mathieucarbou/esphome-ESPAsyncTCP/releases/tag/v2.0.0)) - **RP2040**: `khoih-prog/AsyncTCP_RP2040W @ 1.2.0` (Arduino IDE: [https://github.com/khoih-prog/AsyncTCP_RP2040W#v1.2.0](https://github.com/khoih-prog/AsyncTCP_RP2040W/releases/tag/v1.2.0)) diff --git a/docs/index.md b/docs/index.md index cb6a04c06..c39850ba0 100644 --- a/docs/index.md +++ b/docs/index.md @@ -39,7 +39,7 @@ lib_deps = mathieucarbou/ESPAsyncWebServer @ 3.3.12 **Dependencies:** -- **ESP32**: `mathieucarbou/AsyncTCP @ 3.2.7` (Arduino IDE: [https://github.com/mathieucarbou/AsyncTCP#v3.2.7](https://github.com/mathieucarbou/AsyncTCP/releases)) +- **ESP32**: `mathieucarbou/AsyncTCP @ 3.2.8` (Arduino IDE: [https://github.com/mathieucarbou/AsyncTCP#v3.2.8](https://github.com/mathieucarbou/AsyncTCP/releases)) - **ESP8266**: `esphome/ESPAsyncTCP-esphome @ 2.0.0` (Arduino IDE: [https://github.com/mathieucarbou/esphome-ESPAsyncTCP#v2.0.0](https://github.com/mathieucarbou/esphome-ESPAsyncTCP/releases/tag/v2.0.0)) - **RP2040**: `khoih-prog/AsyncTCP_RP2040W @ 1.2.0` (Arduino IDE: [https://github.com/khoih-prog/AsyncTCP_RP2040W#v1.2.0](https://github.com/khoih-prog/AsyncTCP_RP2040W/releases/tag/v1.2.0)) diff --git a/library.json b/library.json index 17242e5b4..3310ee2bb 100644 --- a/library.json +++ b/library.json @@ -28,7 +28,7 @@ { "owner": "mathieucarbou", "name": "AsyncTCP", - "version": "^3.2.7", + "version": "^3.2.8", "platforms": "espressif32" }, { diff --git a/platformio.ini b/platformio.ini index 860e773a7..60b112791 100644 --- a/platformio.ini +++ b/platformio.ini @@ -25,7 +25,7 @@ lib_deps = ; bblanchon/ArduinoJson @ 5.13.4 ; bblanchon/ArduinoJson @ 6.21.5 bblanchon/ArduinoJson @ 7.2.0 - mathieucarbou/AsyncTCP @ 3.2.7 + mathieucarbou/AsyncTCP @ 3.2.8 board = esp32dev board_build.partitions = partitions-4MB.csv board_build.filesystem = littlefs @@ -43,7 +43,7 @@ platform = https://github.com/pioarduino/platform-espressif32/releases/download/ ; board = esp32-s3-devkitc-1 ; board = esp32-c6-devkitc-1 lib_deps = - mathieucarbou/AsyncTCP @ 3.2.7 + mathieucarbou/AsyncTCP @ 3.2.8 [env:arduino-310rc1] platform = https://github.com/pioarduino/platform-espressif32/releases/download/53.03.10-rc1/platform-espressif32.zip @@ -87,7 +87,7 @@ board = ${sysenv.PIO_BOARD} platform = https://github.com/pioarduino/platform-espressif32/releases/download/51.03.05/platform-espressif32.zip board = ${sysenv.PIO_BOARD} lib_deps = - mathieucarbou/AsyncTCP @ 3.2.7 + mathieucarbou/AsyncTCP @ 3.2.8 [env:ci-arduino-310rc1] platform = https://github.com/pioarduino/platform-espressif32/releases/download/53.03.10-rc1/platform-espressif32.zip From a2fde75b8bca0e7f69ff9b7cac9cf02747a20c47 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Tue, 8 Oct 2024 11:53:51 +0200 Subject: [PATCH 423/551] Domain move --- README.md | 2 +- docs/index.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index c39850ba0..8e5baeb87 100644 --- a/README.md +++ b/README.md @@ -76,7 +76,7 @@ Here are some recommendations to avoid them. 1. Set the running core to be on the same core of your application (usually core 1) `-D CONFIG_ASYNC_TCP_RUNNING_CORE=1` 2. Set the stack size appropriately with `-D CONFIG_ASYNC_TCP_STACK_SIZE=16384`. The default value of `16384` might be too much for your project. - You can look at the [MycilaTaskMonitor](https://oss.carbou.me/MycilaTaskMonitor) project to monitor the stack usage. + You can look at the [MycilaTaskMonitor](https://mathieu.carbou.me/MycilaTaskMonitor) project to monitor the stack usage. 3. You can change **if you know what you are doing** the task priority with `-D CONFIG_ASYNC_TCP_PRIORITY=10`. Default is `10`. 4. You can increase the queue size with `-D CONFIG_ASYNC_TCP_QUEUE_SIZE=128`. diff --git a/docs/index.md b/docs/index.md index c39850ba0..8e5baeb87 100644 --- a/docs/index.md +++ b/docs/index.md @@ -76,7 +76,7 @@ Here are some recommendations to avoid them. 1. Set the running core to be on the same core of your application (usually core 1) `-D CONFIG_ASYNC_TCP_RUNNING_CORE=1` 2. Set the stack size appropriately with `-D CONFIG_ASYNC_TCP_STACK_SIZE=16384`. The default value of `16384` might be too much for your project. - You can look at the [MycilaTaskMonitor](https://oss.carbou.me/MycilaTaskMonitor) project to monitor the stack usage. + You can look at the [MycilaTaskMonitor](https://mathieu.carbou.me/MycilaTaskMonitor) project to monitor the stack usage. 3. You can change **if you know what you are doing** the task priority with `-D CONFIG_ASYNC_TCP_PRIORITY=10`. Default is `10`. 4. You can increase the queue size with `-D CONFIG_ASYNC_TCP_QUEUE_SIZE=128`. From 7b39f0e050970a63544aed8f0ca84a95f161d366 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Fri, 11 Oct 2024 08:40:16 +0200 Subject: [PATCH 424/551] Removed wrong comments --- src/AsyncEventSource.h | 6 +++--- src/AsyncWebSocket.h | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/AsyncEventSource.h b/src/AsyncEventSource.h index f04da18ac..b0bd24967 100644 --- a/src/AsyncEventSource.h +++ b/src/AsyncEventSource.h @@ -119,9 +119,9 @@ class AsyncEventSource : public AsyncWebHandler { public: typedef enum { - DISCARDED = 0, // sent to no client - ENQUEUED = 1, // sent to all clients - PARTIALLY_ENQUEUED = 2, // sent to some clients + DISCARDED = 0, + ENQUEUED = 1, + PARTIALLY_ENQUEUED = 2, } SendStatus; AsyncEventSource(const String& url) : _url(url) {}; diff --git a/src/AsyncWebSocket.h b/src/AsyncWebSocket.h index f139e4514..f489aca29 100644 --- a/src/AsyncWebSocket.h +++ b/src/AsyncWebSocket.h @@ -278,9 +278,9 @@ class AsyncWebSocket : public AsyncWebHandler { public: typedef enum { - DISCARDED = 0, // sent to no client - ENQUEUED = 1, // sent to all clients - PARTIALLY_ENQUEUED = 2, // sent to some clients + DISCARDED = 0, + ENQUEUED = 1, + PARTIALLY_ENQUEUED = 2, } SendStatus; explicit AsyncWebSocket(const char* url) : _url(url), _cNextId(1), _enabled(true) {} From 1a9aba2349585167b1f6e1eec89b23477dc7c83d Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Sat, 12 Oct 2024 21:04:37 +0200 Subject: [PATCH 425/551] mathieucarbou/AsyncTCP @ 3.2.9 --- .github/workflows/ci.yml | 2 +- README.md | 2 +- docs/index.md | 2 +- library.json | 2 +- platformio.ini | 6 +++--- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4122271e1..890c0b28d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -55,7 +55,7 @@ jobs: - name: Install AsyncTCP (ESP32) if: ${{ matrix.core == 'esp32:esp32' }} - run: ARDUINO_LIBRARY_ENABLE_UNSAFE_INSTALL=true arduino-cli lib install --git-url https://github.com/mathieucarbou/AsyncTCP#v3.2.8 + run: ARDUINO_LIBRARY_ENABLE_UNSAFE_INSTALL=true arduino-cli lib install --git-url https://github.com/mathieucarbou/AsyncTCP#v3.2.9 - name: Install ESPAsyncTCP (ESP8266) if: ${{ matrix.core == 'esp8266:esp8266' }} diff --git a/README.md b/README.md index 8e5baeb87..753804414 100644 --- a/README.md +++ b/README.md @@ -39,7 +39,7 @@ lib_deps = mathieucarbou/ESPAsyncWebServer @ 3.3.12 **Dependencies:** -- **ESP32**: `mathieucarbou/AsyncTCP @ 3.2.8` (Arduino IDE: [https://github.com/mathieucarbou/AsyncTCP#v3.2.8](https://github.com/mathieucarbou/AsyncTCP/releases)) +- **ESP32**: `mathieucarbou/AsyncTCP @ 3.2.9` (Arduino IDE: [https://github.com/mathieucarbou/AsyncTCP#v3.2.9](https://github.com/mathieucarbou/AsyncTCP/releases)) - **ESP8266**: `esphome/ESPAsyncTCP-esphome @ 2.0.0` (Arduino IDE: [https://github.com/mathieucarbou/esphome-ESPAsyncTCP#v2.0.0](https://github.com/mathieucarbou/esphome-ESPAsyncTCP/releases/tag/v2.0.0)) - **RP2040**: `khoih-prog/AsyncTCP_RP2040W @ 1.2.0` (Arduino IDE: [https://github.com/khoih-prog/AsyncTCP_RP2040W#v1.2.0](https://github.com/khoih-prog/AsyncTCP_RP2040W/releases/tag/v1.2.0)) diff --git a/docs/index.md b/docs/index.md index 8e5baeb87..753804414 100644 --- a/docs/index.md +++ b/docs/index.md @@ -39,7 +39,7 @@ lib_deps = mathieucarbou/ESPAsyncWebServer @ 3.3.12 **Dependencies:** -- **ESP32**: `mathieucarbou/AsyncTCP @ 3.2.8` (Arduino IDE: [https://github.com/mathieucarbou/AsyncTCP#v3.2.8](https://github.com/mathieucarbou/AsyncTCP/releases)) +- **ESP32**: `mathieucarbou/AsyncTCP @ 3.2.9` (Arduino IDE: [https://github.com/mathieucarbou/AsyncTCP#v3.2.9](https://github.com/mathieucarbou/AsyncTCP/releases)) - **ESP8266**: `esphome/ESPAsyncTCP-esphome @ 2.0.0` (Arduino IDE: [https://github.com/mathieucarbou/esphome-ESPAsyncTCP#v2.0.0](https://github.com/mathieucarbou/esphome-ESPAsyncTCP/releases/tag/v2.0.0)) - **RP2040**: `khoih-prog/AsyncTCP_RP2040W @ 1.2.0` (Arduino IDE: [https://github.com/khoih-prog/AsyncTCP_RP2040W#v1.2.0](https://github.com/khoih-prog/AsyncTCP_RP2040W/releases/tag/v1.2.0)) diff --git a/library.json b/library.json index 3310ee2bb..73d5b1104 100644 --- a/library.json +++ b/library.json @@ -28,7 +28,7 @@ { "owner": "mathieucarbou", "name": "AsyncTCP", - "version": "^3.2.8", + "version": "^3.2.9", "platforms": "espressif32" }, { diff --git a/platformio.ini b/platformio.ini index 60b112791..c31140b6f 100644 --- a/platformio.ini +++ b/platformio.ini @@ -25,7 +25,7 @@ lib_deps = ; bblanchon/ArduinoJson @ 5.13.4 ; bblanchon/ArduinoJson @ 6.21.5 bblanchon/ArduinoJson @ 7.2.0 - mathieucarbou/AsyncTCP @ 3.2.8 + mathieucarbou/AsyncTCP @ 3.2.9 board = esp32dev board_build.partitions = partitions-4MB.csv board_build.filesystem = littlefs @@ -43,7 +43,7 @@ platform = https://github.com/pioarduino/platform-espressif32/releases/download/ ; board = esp32-s3-devkitc-1 ; board = esp32-c6-devkitc-1 lib_deps = - mathieucarbou/AsyncTCP @ 3.2.8 + mathieucarbou/AsyncTCP @ 3.2.9 [env:arduino-310rc1] platform = https://github.com/pioarduino/platform-espressif32/releases/download/53.03.10-rc1/platform-espressif32.zip @@ -87,7 +87,7 @@ board = ${sysenv.PIO_BOARD} platform = https://github.com/pioarduino/platform-espressif32/releases/download/51.03.05/platform-espressif32.zip board = ${sysenv.PIO_BOARD} lib_deps = - mathieucarbou/AsyncTCP @ 3.2.8 + mathieucarbou/AsyncTCP @ 3.2.9 [env:ci-arduino-310rc1] platform = https://github.com/pioarduino/platform-espressif32/releases/download/53.03.10-rc1/platform-espressif32.zip From 69748e40356d77925295a4f290a7d8731ce84c19 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Sat, 12 Oct 2024 21:08:53 +0200 Subject: [PATCH 426/551] v3.3.13 --- README.md | 2 +- docs/index.md | 2 +- library.json | 2 +- library.properties | 2 +- src/ESPAsyncWebServer.h | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 753804414..8c118bbb5 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo ```ini lib_compat_mode = strict lib_ldf_mode = chain -lib_deps = mathieucarbou/ESPAsyncWebServer @ 3.3.12 +lib_deps = mathieucarbou/ESPAsyncWebServer @ 3.3.13 ``` **Dependencies:** diff --git a/docs/index.md b/docs/index.md index 753804414..8c118bbb5 100644 --- a/docs/index.md +++ b/docs/index.md @@ -34,7 +34,7 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo ```ini lib_compat_mode = strict lib_ldf_mode = chain -lib_deps = mathieucarbou/ESPAsyncWebServer @ 3.3.12 +lib_deps = mathieucarbou/ESPAsyncWebServer @ 3.3.13 ``` **Dependencies:** diff --git a/library.json b/library.json index 73d5b1104..472e74257 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "ESPAsyncWebServer", - "version": "3.3.12", + "version": "3.3.13", "description": "Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 and RP2040. Supports: WebSocket, SSE, Authentication, Arduino Json 7, File Upload, Static File serving, URL Rewrite, URL Redirect, etc.", "keywords": "http,async,websocket,webserver", "homepage": "https://github.com/mathieucarbou/ESPAsyncWebServer", diff --git a/library.properties b/library.properties index 751a36363..8a105c743 100644 --- a/library.properties +++ b/library.properties @@ -1,6 +1,6 @@ name=ESP Async WebServer includes=ESPAsyncWebServer.h -version=3.3.12 +version=3.3.13 author=Me-No-Dev maintainer=Mathieu Carbou sentence=Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 and RP2040 diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index bd6800273..4a72a05a9 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -48,10 +48,10 @@ #include "literals.h" -#define ASYNCWEBSERVER_VERSION "3.3.12" +#define ASYNCWEBSERVER_VERSION "3.3.13" #define ASYNCWEBSERVER_VERSION_MAJOR 3 #define ASYNCWEBSERVER_VERSION_MINOR 3 -#define ASYNCWEBSERVER_VERSION_REVISION 12 +#define ASYNCWEBSERVER_VERSION_REVISION 13 #define ASYNCWEBSERVER_FORK_mathieucarbou #ifdef ASYNCWEBSERVER_REGEX From b2cf63066abf27b92a4569d7509ef947ad583799 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Sun, 13 Oct 2024 11:47:13 +0200 Subject: [PATCH 427/551] mathieucarbou/AsyncTCP @ 3.2.10 --- .github/workflows/ci.yml | 2 +- README.md | 2 +- docs/index.md | 2 +- library.json | 2 +- platformio.ini | 6 +++--- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 890c0b28d..6082bb0eb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -55,7 +55,7 @@ jobs: - name: Install AsyncTCP (ESP32) if: ${{ matrix.core == 'esp32:esp32' }} - run: ARDUINO_LIBRARY_ENABLE_UNSAFE_INSTALL=true arduino-cli lib install --git-url https://github.com/mathieucarbou/AsyncTCP#v3.2.9 + run: ARDUINO_LIBRARY_ENABLE_UNSAFE_INSTALL=true arduino-cli lib install --git-url https://github.com/mathieucarbou/AsyncTCP#v3.2.10 - name: Install ESPAsyncTCP (ESP8266) if: ${{ matrix.core == 'esp8266:esp8266' }} diff --git a/README.md b/README.md index 8c118bbb5..117b3e5ba 100644 --- a/README.md +++ b/README.md @@ -39,7 +39,7 @@ lib_deps = mathieucarbou/ESPAsyncWebServer @ 3.3.13 **Dependencies:** -- **ESP32**: `mathieucarbou/AsyncTCP @ 3.2.9` (Arduino IDE: [https://github.com/mathieucarbou/AsyncTCP#v3.2.9](https://github.com/mathieucarbou/AsyncTCP/releases)) +- **ESP32**: `mathieucarbou/AsyncTCP @ 3.2.10` (Arduino IDE: [https://github.com/mathieucarbou/AsyncTCP#v3.2.10](https://github.com/mathieucarbou/AsyncTCP/releases)) - **ESP8266**: `esphome/ESPAsyncTCP-esphome @ 2.0.0` (Arduino IDE: [https://github.com/mathieucarbou/esphome-ESPAsyncTCP#v2.0.0](https://github.com/mathieucarbou/esphome-ESPAsyncTCP/releases/tag/v2.0.0)) - **RP2040**: `khoih-prog/AsyncTCP_RP2040W @ 1.2.0` (Arduino IDE: [https://github.com/khoih-prog/AsyncTCP_RP2040W#v1.2.0](https://github.com/khoih-prog/AsyncTCP_RP2040W/releases/tag/v1.2.0)) diff --git a/docs/index.md b/docs/index.md index 8c118bbb5..117b3e5ba 100644 --- a/docs/index.md +++ b/docs/index.md @@ -39,7 +39,7 @@ lib_deps = mathieucarbou/ESPAsyncWebServer @ 3.3.13 **Dependencies:** -- **ESP32**: `mathieucarbou/AsyncTCP @ 3.2.9` (Arduino IDE: [https://github.com/mathieucarbou/AsyncTCP#v3.2.9](https://github.com/mathieucarbou/AsyncTCP/releases)) +- **ESP32**: `mathieucarbou/AsyncTCP @ 3.2.10` (Arduino IDE: [https://github.com/mathieucarbou/AsyncTCP#v3.2.10](https://github.com/mathieucarbou/AsyncTCP/releases)) - **ESP8266**: `esphome/ESPAsyncTCP-esphome @ 2.0.0` (Arduino IDE: [https://github.com/mathieucarbou/esphome-ESPAsyncTCP#v2.0.0](https://github.com/mathieucarbou/esphome-ESPAsyncTCP/releases/tag/v2.0.0)) - **RP2040**: `khoih-prog/AsyncTCP_RP2040W @ 1.2.0` (Arduino IDE: [https://github.com/khoih-prog/AsyncTCP_RP2040W#v1.2.0](https://github.com/khoih-prog/AsyncTCP_RP2040W/releases/tag/v1.2.0)) diff --git a/library.json b/library.json index 472e74257..eb3013f30 100644 --- a/library.json +++ b/library.json @@ -28,7 +28,7 @@ { "owner": "mathieucarbou", "name": "AsyncTCP", - "version": "^3.2.9", + "version": "^3.2.10", "platforms": "espressif32" }, { diff --git a/platformio.ini b/platformio.ini index c31140b6f..d4643279b 100644 --- a/platformio.ini +++ b/platformio.ini @@ -25,7 +25,7 @@ lib_deps = ; bblanchon/ArduinoJson @ 5.13.4 ; bblanchon/ArduinoJson @ 6.21.5 bblanchon/ArduinoJson @ 7.2.0 - mathieucarbou/AsyncTCP @ 3.2.9 + mathieucarbou/AsyncTCP @ 3.2.10 board = esp32dev board_build.partitions = partitions-4MB.csv board_build.filesystem = littlefs @@ -43,7 +43,7 @@ platform = https://github.com/pioarduino/platform-espressif32/releases/download/ ; board = esp32-s3-devkitc-1 ; board = esp32-c6-devkitc-1 lib_deps = - mathieucarbou/AsyncTCP @ 3.2.9 + mathieucarbou/AsyncTCP @ 3.2.10 [env:arduino-310rc1] platform = https://github.com/pioarduino/platform-espressif32/releases/download/53.03.10-rc1/platform-espressif32.zip @@ -87,7 +87,7 @@ board = ${sysenv.PIO_BOARD} platform = https://github.com/pioarduino/platform-espressif32/releases/download/51.03.05/platform-espressif32.zip board = ${sysenv.PIO_BOARD} lib_deps = - mathieucarbou/AsyncTCP @ 3.2.9 + mathieucarbou/AsyncTCP @ 3.2.10 [env:ci-arduino-310rc1] platform = https://github.com/pioarduino/platform-espressif32/releases/download/53.03.10-rc1/platform-espressif32.zip From 40e5e7bcc24b06507aa68db98a9cb22db0a4cf8c Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Sun, 13 Oct 2024 12:09:40 +0200 Subject: [PATCH 428/551] v3.3.14 --- README.md | 2 +- docs/index.md | 2 +- library.json | 2 +- library.properties | 2 +- src/ESPAsyncWebServer.h | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 117b3e5ba..88564023c 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo ```ini lib_compat_mode = strict lib_ldf_mode = chain -lib_deps = mathieucarbou/ESPAsyncWebServer @ 3.3.13 +lib_deps = mathieucarbou/ESPAsyncWebServer @ 3.3.14 ``` **Dependencies:** diff --git a/docs/index.md b/docs/index.md index 117b3e5ba..88564023c 100644 --- a/docs/index.md +++ b/docs/index.md @@ -34,7 +34,7 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo ```ini lib_compat_mode = strict lib_ldf_mode = chain -lib_deps = mathieucarbou/ESPAsyncWebServer @ 3.3.13 +lib_deps = mathieucarbou/ESPAsyncWebServer @ 3.3.14 ``` **Dependencies:** diff --git a/library.json b/library.json index eb3013f30..0b14de368 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "ESPAsyncWebServer", - "version": "3.3.13", + "version": "3.3.14", "description": "Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 and RP2040. Supports: WebSocket, SSE, Authentication, Arduino Json 7, File Upload, Static File serving, URL Rewrite, URL Redirect, etc.", "keywords": "http,async,websocket,webserver", "homepage": "https://github.com/mathieucarbou/ESPAsyncWebServer", diff --git a/library.properties b/library.properties index 8a105c743..824b3a377 100644 --- a/library.properties +++ b/library.properties @@ -1,6 +1,6 @@ name=ESP Async WebServer includes=ESPAsyncWebServer.h -version=3.3.13 +version=3.3.14 author=Me-No-Dev maintainer=Mathieu Carbou sentence=Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 and RP2040 diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index 4a72a05a9..fe3ff10cb 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -48,10 +48,10 @@ #include "literals.h" -#define ASYNCWEBSERVER_VERSION "3.3.13" +#define ASYNCWEBSERVER_VERSION "3.3.14" #define ASYNCWEBSERVER_VERSION_MAJOR 3 #define ASYNCWEBSERVER_VERSION_MINOR 3 -#define ASYNCWEBSERVER_VERSION_REVISION 13 +#define ASYNCWEBSERVER_VERSION_REVISION 14 #define ASYNCWEBSERVER_FORK_mathieucarbou #ifdef ASYNCWEBSERVER_REGEX From 77f90b640738305ef8c679ed99ca20271856dfbe Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Sun, 13 Oct 2024 15:45:25 +0200 Subject: [PATCH 429/551] Added perf tests --- README.md | 12 ++++ docs/index.md | 12 ++++ docs/perf-c10.png | Bin 0 -> 302299 bytes examples/SimpleServer/SimpleServer.ino | 75 +++++++++++++++++++++++-- platformio.ini | 5 ++ 5 files changed, 99 insertions(+), 5 deletions(-) create mode 100644 docs/perf-c10.png diff --git a/README.md b/README.md index 88564023c..e1bfd338e 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,7 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo - [How to use Middleware](#how-to-use-middleware) - [How to use authentication with AuthenticationMiddleware](#how-to-use-authentication-with-authenticationmiddleware) - [Migration to Middleware to improve performance and memory usage](#migration-to-middleware-to-improve-performance-and-memory-usage) +- [Performance](#performance) - [Original Documentation](#original-documentation) ## Coordinate and dependencies @@ -221,6 +222,17 @@ myHandler.addMiddleware(&authMiddleware); // add authentication to a specific ha These callbacks can be called multiple times during request parsing, so this is up to the user to now call the `AuthenticationMiddleware.allowed(request)` if needed and ideally when the method is called for the first time. These callbacks are also not triggering the whole middleware chain since they are not part of the request processing workflow (they are not the final handler). +## Performance + +With the `perf-test` PIO environment: + +```bash +> brew install autocannon +> autocannon -c 10 -w 10 -d 20 http://192.168.4.1 +``` + +[![](https://mathieu.carbou.me/ESPAsyncWebServer/perf-c10.png)](https://mathieu.carbou.me/ESPAsyncWebServer/perf-c10.png) + ## Original Documentation - [Why should you care](#why-should-you-care) diff --git a/docs/index.md b/docs/index.md index 88564023c..e1bfd338e 100644 --- a/docs/index.md +++ b/docs/index.md @@ -23,6 +23,7 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo - [How to use Middleware](#how-to-use-middleware) - [How to use authentication with AuthenticationMiddleware](#how-to-use-authentication-with-authenticationmiddleware) - [Migration to Middleware to improve performance and memory usage](#migration-to-middleware-to-improve-performance-and-memory-usage) +- [Performance](#performance) - [Original Documentation](#original-documentation) ## Coordinate and dependencies @@ -221,6 +222,17 @@ myHandler.addMiddleware(&authMiddleware); // add authentication to a specific ha These callbacks can be called multiple times during request parsing, so this is up to the user to now call the `AuthenticationMiddleware.allowed(request)` if needed and ideally when the method is called for the first time. These callbacks are also not triggering the whole middleware chain since they are not part of the request processing workflow (they are not the final handler). +## Performance + +With the `perf-test` PIO environment: + +```bash +> brew install autocannon +> autocannon -c 10 -w 10 -d 20 http://192.168.4.1 +``` + +[![](https://mathieu.carbou.me/ESPAsyncWebServer/perf-c10.png)](https://mathieu.carbou.me/ESPAsyncWebServer/perf-c10.png) + ## Original Documentation - [Why should you care](#why-should-you-care) diff --git a/docs/perf-c10.png b/docs/perf-c10.png new file mode 100644 index 0000000000000000000000000000000000000000..e63e71a8834d384781efac9b65dcd4bc792b69e9 GIT binary patch literal 302299 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
C!JF|6 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%0A%o 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�&;2Mh13yMPaPwcIvEhzxcDfE{d=GuMc9 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 +const char* htmlContent = R"( + + + + Sample HTML + + +

Hello, World!

+

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod, purus a euismod + rhoncus, urna ipsum cursus massa, eu dictum tellus justo ac justo. Quisque ullamcorper + arcu nec tortor ullamcorper, vel fermentum justo fermentum. Vivamus sed velit ut elit + accumsan congue ut ut enim. Ut eu justo eu lacus varius gravida ut a tellus. Nulla facilisi. + Integer auctor consectetur ultricies. Fusce feugiat, mi sit amet bibendum viverra, orci leo + dapibus elit, id varius sem dui id lacus.

+

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod, purus a euismod + rhoncus, urna ipsum cursus massa, eu dictum tellus justo ac justo. Quisque ullamcorper + arcu nec tortor ullamcorper, vel fermentum justo fermentum. Vivamus sed velit ut elit + accumsan congue ut ut enim. Ut eu justo eu lacus varius gravida ut a tellus. Nulla facilisi. + Integer auctor consectetur ultricies. Fusce feugiat, mi sit amet bibendum viverra, orci leo + dapibus elit, id varius sem dui id lacus.

+

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod, purus a euismod + rhoncus, urna ipsum cursus massa, eu dictum tellus justo ac justo. Quisque ullamcorper + arcu nec tortor ullamcorper, vel fermentum justo fermentum. Vivamus sed velit ut elit + accumsan congue ut ut enim. Ut eu justo eu lacus varius gravida ut a tellus. Nulla facilisi. + Integer auctor consectetur ultricies. Fusce feugiat, mi sit amet bibendum viverra, orci leo + dapibus elit, id varius sem dui id lacus.

+

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod, purus a euismod + rhoncus, urna ipsum cursus massa, eu dictum tellus justo ac justo. Quisque ullamcorper + arcu nec tortor ullamcorper, vel fermentum justo fermentum. Vivamus sed velit ut elit + accumsan congue ut ut enim. Ut eu justo eu lacus varius gravida ut a tellus. Nulla facilisi. + Integer auctor consectetur ultricies. Fusce feugiat, mi sit amet bibendum viverra, orci leo + dapibus elit, id varius sem dui id lacus.

+

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod, purus a euismod + rhoncus, urna ipsum cursus massa, eu dictum tellus justo ac justo. Quisque ullamcorper + arcu nec tortor ullamcorper, vel fermentum justo fermentum. Vivamus sed velit ut elit + accumsan congue ut ut enim. Ut eu justo eu lacus varius gravida ut a tellus. Nulla facilisi. + Integer auctor consectetur ultricies. Fusce feugiat, mi sit amet bibendum viverra, orci leo + dapibus elit, id varius sem dui id lacus.

+

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod, purus a euismod + rhoncus, urna ipsum cursus massa, eu dictum tellus justo ac justo. Quisque ullamcorper + arcu nec tortor ullamcorper, vel fermentum justo fermentum. Vivamus sed velit ut elit + accumsan congue ut ut enim. Ut eu justo eu lacus varius gravida ut a tellus. Nulla facilisi. + Integer auctor consectetur ultricies. Fusce feugiat, mi sit amet bibendum viverra, orci leo + dapibus elit, id varius sem dui id lacus.

+

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod, purus a euismod + rhoncus, urna ipsum cursus massa, eu dictum tellus justo ac justo. Quisque ullamcorper + arcu nec tortor ullamcorper, vel fermentum justo fermentum. Vivamus sed velit ut elit + accumsan congue ut ut enim. Ut eu justo eu lacus varius gravida ut a tellus. Nulla facilisi. + Integer auctor consectetur ultricies. Fusce feugiat, mi sit amet bibendum viverra, orci leo + dapibus elit, id varius sem dui id lacus.

+

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod, purus a euismod + rhoncus, urna ipsum cursus massa, eu dictum tellus justo ac justo. Quisque ullamcorper + arcu nec tortor ullamcorper, vel fermentum justo fermentum. Vivamus sed velit ut elit + accumsan congue ut ut enim. Ut eu justo eu lacus varius gravida ut a tellus. Nulla facilisi. + Integer auctor consectetur ultricies. Fusce feugiat, mi sit amet bibendum viverra, orci leo + dapibus elit, id varius sem dui id lacus.

+ + +)"; + AsyncWebServer server(80); AsyncEventSource events("/events"); AsyncWebSocket ws("/ws"); @@ -236,16 +296,18 @@ void setup() { headerFree.keep("X-Keep-Me"); headerFree.keep("host"); - // global middleware - server.addMiddleware(&requestLogger); - // server.addMiddlewares({&rateLimit, &cors, &headerFilter}); - cors.setOrigin("http://192.168.4.1"); cors.setMethods("POST, GET, OPTIONS, DELETE"); cors.setHeaders("X-Custom-Header"); cors.setAllowCredentials(false); cors.setMaxAge(600); +#ifndef PERF_TEST + // global middleware + server.addMiddleware(&requestLogger); + server.addMiddlewares({&rateLimit, &cors, &headerFilter}); +#endif + // Test CORS preflight request // curl -v -X OPTIONS -H "origin: http://192.168.4.1" http://192.168.4.1/middleware/cors server.on("/middleware/cors", HTTP_GET, [](AsyncWebServerRequest* request) { @@ -320,8 +382,11 @@ void setup() { request->redirect("/"); }); + // PERF TEST: + // > brew install autocannon + // > autocannon -c 10 -w 10 -d 20 http://192.168.4.1 server.on("/", HTTP_GET, [](AsyncWebServerRequest* request) { - request->send(200, "text/plain", "Hello, world"); + request->send(200, "text/html", htmlContent); }); server.on("/file", HTTP_GET, [](AsyncWebServerRequest* request) { diff --git a/platformio.ini b/platformio.ini index d4643279b..62adf025e 100644 --- a/platformio.ini +++ b/platformio.ini @@ -50,6 +50,11 @@ platform = https://github.com/pioarduino/platform-espressif32/releases/download/ ; board = esp32-s3-devkitc-1 ; board = esp32-c6-devkitc-1 +[env:perf-test] +platform = https://github.com/pioarduino/platform-espressif32/releases/download/53.03.10-rc1/platform-espressif32.zip +build_flags = ${env.build_flags} + -D PERF_TEST=1 + [env:esp8266] platform = espressif8266 board = huzzah From 01c691b36a7df8616fa9647364b759dfdb696999 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Mon, 14 Oct 2024 00:05:31 +0200 Subject: [PATCH 430/551] AsyncTCPSock support --- README.md | 32 ++++++++++++++++++-------------- docs/index.md | 32 ++++++++++++++++++-------------- docs/perf-c10-asynctcpsock.png | Bin 0 -> 310017 bytes platformio.ini | 9 ++++++++- 4 files changed, 44 insertions(+), 29 deletions(-) create mode 100644 docs/perf-c10-asynctcpsock.png diff --git a/README.md b/README.md index e1bfd338e..4336c1040 100644 --- a/README.md +++ b/README.md @@ -17,18 +17,18 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo - [Coordinate and dependencies](#coordinate-and-dependencies) - [Changes in this fork](#changes-in-this-fork) +- [Performance](#performance) - [Important recommendations](#important-recommendations) - [`AsyncWebSocketMessageBuffer` and `makeBuffer()`](#asyncwebsocketmessagebuffer-and-makebuffer) - [How to replace a response](#how-to-replace-a-response) - [How to use Middleware](#how-to-use-middleware) - [How to use authentication with AuthenticationMiddleware](#how-to-use-authentication-with-authenticationmiddleware) - [Migration to Middleware to improve performance and memory usage](#migration-to-middleware-to-improve-performance-and-memory-usage) -- [Performance](#performance) - [Original Documentation](#original-documentation) ## Coordinate and dependencies -**WARNING** The library name was changed from `ESP Async WebServer` to `ESPAsyncWebServer` as per the Arduino Lint recommendations. +**WARNING** The library name was changed from `ESP Async WebServer` to `ESPAsyncWebServer` as per the Arduino Lint recommendations, but its name had to stay `ESP Async WebServer` in Arduino Registry. **PlatformIO / pioarduino:** @@ -40,7 +40,7 @@ lib_deps = mathieucarbou/ESPAsyncWebServer @ 3.3.14 **Dependencies:** -- **ESP32**: `mathieucarbou/AsyncTCP @ 3.2.10` (Arduino IDE: [https://github.com/mathieucarbou/AsyncTCP#v3.2.10](https://github.com/mathieucarbou/AsyncTCP/releases)) +- **ESP32 with AsyncTCP**: `mathieucarbou/AsyncTCP @ 3.2.10` (Arduino IDE: [https://github.com/mathieucarbou/AsyncTCP#v3.2.10](https://github.com/mathieucarbou/AsyncTCP/releases)) - **ESP8266**: `esphome/ESPAsyncTCP-esphome @ 2.0.0` (Arduino IDE: [https://github.com/mathieucarbou/esphome-ESPAsyncTCP#v2.0.0](https://github.com/mathieucarbou/esphome-ESPAsyncTCP/releases/tag/v2.0.0)) - **RP2040**: `khoih-prog/AsyncTCP_RP2040W @ 1.2.0` (Arduino IDE: [https://github.com/khoih-prog/AsyncTCP_RP2040W#v1.2.0](https://github.com/khoih-prog/AsyncTCP_RP2040W/releases/tag/v1.2.0)) @@ -69,6 +69,21 @@ lib_deps = mathieucarbou/ESPAsyncWebServer @ 3.3.14 - (perf) Lot of code cleanup and optimizations - (perf) Performance improvements in terms of memory, speed and size +## Performance + +```bash +> brew install autocannon +> autocannon -c 10 -w 10 -d 20 http://192.168.4.1 +``` + +Here is a capture of the `perf-test-AsyncTCP` PIO environment running with `mathieucarbou/AsyncTCP @ 3.2.10` and `mathieucarbou/ESPAsyncWebServer @ 3.3.14`: + +[![](https://mathieu.carbou.me/ESPAsyncWebServer/perf-c10.png)](https://mathieu.carbou.me/ESPAsyncWebServer/perf-c10.png) + +Here is a capture of the `perf-test-AsyncTCPSock` PIO environment running with `https://github.com/mathieucarbou/AsyncTCPSock/archive/refs/tags/v1.0.1-dev.zip` and `mathieucarbou/ESPAsyncWebServer @ 3.3.14`: + +[![](https://mathieu.carbou.me/ESPAsyncWebServer/perf-c10-asynctcpsock.png)](https://mathieu.carbou.me/ESPAsyncWebServer/perf-c10-asynctcpsock.png) + ## Important recommendations Most of the crashes are caused by improper configuration of the library for the project. @@ -222,17 +237,6 @@ myHandler.addMiddleware(&authMiddleware); // add authentication to a specific ha These callbacks can be called multiple times during request parsing, so this is up to the user to now call the `AuthenticationMiddleware.allowed(request)` if needed and ideally when the method is called for the first time. These callbacks are also not triggering the whole middleware chain since they are not part of the request processing workflow (they are not the final handler). -## Performance - -With the `perf-test` PIO environment: - -```bash -> brew install autocannon -> autocannon -c 10 -w 10 -d 20 http://192.168.4.1 -``` - -[![](https://mathieu.carbou.me/ESPAsyncWebServer/perf-c10.png)](https://mathieu.carbou.me/ESPAsyncWebServer/perf-c10.png) - ## Original Documentation - [Why should you care](#why-should-you-care) diff --git a/docs/index.md b/docs/index.md index e1bfd338e..4336c1040 100644 --- a/docs/index.md +++ b/docs/index.md @@ -17,18 +17,18 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo - [Coordinate and dependencies](#coordinate-and-dependencies) - [Changes in this fork](#changes-in-this-fork) +- [Performance](#performance) - [Important recommendations](#important-recommendations) - [`AsyncWebSocketMessageBuffer` and `makeBuffer()`](#asyncwebsocketmessagebuffer-and-makebuffer) - [How to replace a response](#how-to-replace-a-response) - [How to use Middleware](#how-to-use-middleware) - [How to use authentication with AuthenticationMiddleware](#how-to-use-authentication-with-authenticationmiddleware) - [Migration to Middleware to improve performance and memory usage](#migration-to-middleware-to-improve-performance-and-memory-usage) -- [Performance](#performance) - [Original Documentation](#original-documentation) ## Coordinate and dependencies -**WARNING** The library name was changed from `ESP Async WebServer` to `ESPAsyncWebServer` as per the Arduino Lint recommendations. +**WARNING** The library name was changed from `ESP Async WebServer` to `ESPAsyncWebServer` as per the Arduino Lint recommendations, but its name had to stay `ESP Async WebServer` in Arduino Registry. **PlatformIO / pioarduino:** @@ -40,7 +40,7 @@ lib_deps = mathieucarbou/ESPAsyncWebServer @ 3.3.14 **Dependencies:** -- **ESP32**: `mathieucarbou/AsyncTCP @ 3.2.10` (Arduino IDE: [https://github.com/mathieucarbou/AsyncTCP#v3.2.10](https://github.com/mathieucarbou/AsyncTCP/releases)) +- **ESP32 with AsyncTCP**: `mathieucarbou/AsyncTCP @ 3.2.10` (Arduino IDE: [https://github.com/mathieucarbou/AsyncTCP#v3.2.10](https://github.com/mathieucarbou/AsyncTCP/releases)) - **ESP8266**: `esphome/ESPAsyncTCP-esphome @ 2.0.0` (Arduino IDE: [https://github.com/mathieucarbou/esphome-ESPAsyncTCP#v2.0.0](https://github.com/mathieucarbou/esphome-ESPAsyncTCP/releases/tag/v2.0.0)) - **RP2040**: `khoih-prog/AsyncTCP_RP2040W @ 1.2.0` (Arduino IDE: [https://github.com/khoih-prog/AsyncTCP_RP2040W#v1.2.0](https://github.com/khoih-prog/AsyncTCP_RP2040W/releases/tag/v1.2.0)) @@ -69,6 +69,21 @@ lib_deps = mathieucarbou/ESPAsyncWebServer @ 3.3.14 - (perf) Lot of code cleanup and optimizations - (perf) Performance improvements in terms of memory, speed and size +## Performance + +```bash +> brew install autocannon +> autocannon -c 10 -w 10 -d 20 http://192.168.4.1 +``` + +Here is a capture of the `perf-test-AsyncTCP` PIO environment running with `mathieucarbou/AsyncTCP @ 3.2.10` and `mathieucarbou/ESPAsyncWebServer @ 3.3.14`: + +[![](https://mathieu.carbou.me/ESPAsyncWebServer/perf-c10.png)](https://mathieu.carbou.me/ESPAsyncWebServer/perf-c10.png) + +Here is a capture of the `perf-test-AsyncTCPSock` PIO environment running with `https://github.com/mathieucarbou/AsyncTCPSock/archive/refs/tags/v1.0.1-dev.zip` and `mathieucarbou/ESPAsyncWebServer @ 3.3.14`: + +[![](https://mathieu.carbou.me/ESPAsyncWebServer/perf-c10-asynctcpsock.png)](https://mathieu.carbou.me/ESPAsyncWebServer/perf-c10-asynctcpsock.png) + ## Important recommendations Most of the crashes are caused by improper configuration of the library for the project. @@ -222,17 +237,6 @@ myHandler.addMiddleware(&authMiddleware); // add authentication to a specific ha These callbacks can be called multiple times during request parsing, so this is up to the user to now call the `AuthenticationMiddleware.allowed(request)` if needed and ideally when the method is called for the first time. These callbacks are also not triggering the whole middleware chain since they are not part of the request processing workflow (they are not the final handler). -## Performance - -With the `perf-test` PIO environment: - -```bash -> brew install autocannon -> autocannon -c 10 -w 10 -d 20 http://192.168.4.1 -``` - -[![](https://mathieu.carbou.me/ESPAsyncWebServer/perf-c10.png)](https://mathieu.carbou.me/ESPAsyncWebServer/perf-c10.png) - ## Original Documentation - [Why should you care](#why-should-you-care) diff --git a/docs/perf-c10-asynctcpsock.png b/docs/perf-c10-asynctcpsock.png new file mode 100644 index 0000000000000000000000000000000000000000..136b54562341a70414076c693c21ecbf567b6e48 GIT binary patch literal 310017 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

5lH^d1>{bCRs-YaEnvze3u3%=7BI~Zz1h{;s{ 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%0DqPmzMVqxGp%)sq6^M(Tw^lsvbMV~V)}1i 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 z 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%0A@Jh{gOPgp|`Z* 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 literal 0 HcmV?d00001 diff --git a/platformio.ini b/platformio.ini index 62adf025e..bf9326e6e 100644 --- a/platformio.ini +++ b/platformio.ini @@ -50,11 +50,18 @@ platform = https://github.com/pioarduino/platform-espressif32/releases/download/ ; board = esp32-s3-devkitc-1 ; board = esp32-c6-devkitc-1 -[env:perf-test] +[env:perf-test-AsyncTCP] platform = https://github.com/pioarduino/platform-espressif32/releases/download/53.03.10-rc1/platform-espressif32.zip build_flags = ${env.build_flags} -D PERF_TEST=1 +[env:perf-test-AsyncTCPSock] +platform = https://github.com/pioarduino/platform-espressif32/releases/download/53.03.10-rc1/platform-espressif32.zip +lib_deps = + https://github.com/mathieucarbou/AsyncTCPSock/archive/refs/tags/v1.0.1-dev.zip +build_flags = ${env.build_flags} + -D PERF_TEST=1 + [env:esp8266] platform = espressif8266 board = huzzah From 7e1bc0c63c564492f203004d8a08f36bb5e29fbd Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Mon, 14 Oct 2024 00:22:31 +0200 Subject: [PATCH 431/551] doc update --- README.md | 58 +++++++++++++++++++++++++++++++++----------------- docs/index.md | 58 +++++++++++++++++++++++++++++++++----------------- platformio.ini | 2 +- 3 files changed, 77 insertions(+), 41 deletions(-) diff --git a/README.md b/README.md index 4336c1040..2bd2255e8 100644 --- a/README.md +++ b/README.md @@ -15,8 +15,8 @@ Supports: WebSocket, SSE, Authentication, Arduino Json 7, File Upload, Static Fi This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubox-node-org/ESPAsyncWebServer) and includes all the concurrency fixes. -- [Coordinate and dependencies](#coordinate-and-dependencies) - [Changes in this fork](#changes-in-this-fork) +- [Dependencies](#dependencies) - [Performance](#performance) - [Important recommendations](#important-recommendations) - [`AsyncWebSocketMessageBuffer` and `makeBuffer()`](#asyncwebsocketmessagebuffer-and-makebuffer) @@ -26,24 +26,6 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo - [Migration to Middleware to improve performance and memory usage](#migration-to-middleware-to-improve-performance-and-memory-usage) - [Original Documentation](#original-documentation) -## Coordinate and dependencies - -**WARNING** The library name was changed from `ESP Async WebServer` to `ESPAsyncWebServer` as per the Arduino Lint recommendations, but its name had to stay `ESP Async WebServer` in Arduino Registry. - -**PlatformIO / pioarduino:** - -```ini -lib_compat_mode = strict -lib_ldf_mode = chain -lib_deps = mathieucarbou/ESPAsyncWebServer @ 3.3.14 -``` - -**Dependencies:** - -- **ESP32 with AsyncTCP**: `mathieucarbou/AsyncTCP @ 3.2.10` (Arduino IDE: [https://github.com/mathieucarbou/AsyncTCP#v3.2.10](https://github.com/mathieucarbou/AsyncTCP/releases)) -- **ESP8266**: `esphome/ESPAsyncTCP-esphome @ 2.0.0` (Arduino IDE: [https://github.com/mathieucarbou/esphome-ESPAsyncTCP#v2.0.0](https://github.com/mathieucarbou/esphome-ESPAsyncTCP/releases/tag/v2.0.0)) -- **RP2040**: `khoih-prog/AsyncTCP_RP2040W @ 1.2.0` (Arduino IDE: [https://github.com/khoih-prog/AsyncTCP_RP2040W#v1.2.0](https://github.com/khoih-prog/AsyncTCP_RP2040W/releases/tag/v1.2.0)) - ## Changes in this fork - (bug) A lot of bug fixes @@ -60,6 +42,7 @@ lib_deps = mathieucarbou/ESPAsyncWebServer @ 3.3.14 - (feat) **Resumable download** support using HEAD and bytes range - (feat) `StreamConcat` example to show how to stream multiple files in one response - (feat) Removed ESPIDF Editor (this is not the role of a web server library to do that - get the source files from the original repos if required) +- (perf) [AsyncTCPSock](https://github.com/mathieucarbou/AsyncTCPSock) support: AsyncTCP can be ignored and AsyncTCPSock used instead - (perf) `char*` overloads to avoid using `String` - (perf) `DEFAULT_MAX_WS_CLIENTS` to change the number of allows WebSocket clients and use `cleanupClients()` to help cleanup resources about dead clients - (perf) `setCloseClientOnQueueFull(bool)` which can be set on a client to either close the connection or discard messages but not close the connection when the queue is full @@ -69,6 +52,41 @@ lib_deps = mathieucarbou/ESPAsyncWebServer @ 3.3.14 - (perf) Lot of code cleanup and optimizations - (perf) Performance improvements in terms of memory, speed and size +## Dependencies + +**WARNING** The library name was changed from `ESP Async WebServer` to `ESPAsyncWebServer` as per the Arduino Lint recommendations, but its name had to stay `ESP Async WebServer` in Arduino Registry. + +**PlatformIO / pioarduino:** + +```ini +lib_compat_mode = strict +lib_ldf_mode = chain +lib_deps = mathieucarbou/ESPAsyncWebServer @ 3.3.14 +``` + +**Dependencies:** + +- **ESP32 with AsyncTCP**: `mathieucarbou/AsyncTCP @ 3.2.10` (Arduino IDE: [https://github.com/mathieucarbou/AsyncTCP#v3.2.10](https://github.com/mathieucarbou/AsyncTCP/releases)) +- **ESP32 with AsyncTCPSock**: `https://github.com/mathieucarbou/AsyncTCPSock/archive/refs/tags/v1.0.2-dev.zip` +- **ESP8266**: `esphome/ESPAsyncTCP-esphome @ 2.0.0` (Arduino IDE: [https://github.com/mathieucarbou/esphome-ESPAsyncTCP#v2.0.0](https://github.com/mathieucarbou/esphome-ESPAsyncTCP/releases/tag/v2.0.0)) +- **RP2040**: `khoih-prog/AsyncTCP_RP2040W @ 1.2.0` (Arduino IDE: [https://github.com/khoih-prog/AsyncTCP_RP2040W#v1.2.0](https://github.com/khoih-prog/AsyncTCP_RP2040W/releases/tag/v1.2.0)) + +**AsyncTCPSock** + +AsyncTCPSock can be used instead of AsyncTCP by excluding AsyncTCP from the library dependencies and adding AsyncTCPSock instead: + +```ini +lib_compat_mode = strict +lib_ldf_mode = chain +lib_deps = + ; mathieucarbou/AsyncTCP @ 3.2.10 + https://github.com/mathieucarbou/AsyncTCPSock/archive/refs/tags/v1.0.2-dev.zip + mathieucarbou/ESPAsyncWebServer @ 3.3.14 +lib_ignore = + AsyncTCP + mathieucarbou/AsyncTCP +``` + ## Performance ```bash @@ -80,7 +98,7 @@ Here is a capture of the `perf-test-AsyncTCP` PIO environment running with `math [![](https://mathieu.carbou.me/ESPAsyncWebServer/perf-c10.png)](https://mathieu.carbou.me/ESPAsyncWebServer/perf-c10.png) -Here is a capture of the `perf-test-AsyncTCPSock` PIO environment running with `https://github.com/mathieucarbou/AsyncTCPSock/archive/refs/tags/v1.0.1-dev.zip` and `mathieucarbou/ESPAsyncWebServer @ 3.3.14`: +Here is a capture of the `perf-test-AsyncTCPSock` PIO environment running with `mathieucarbou/AsyncTCPSock @ v1.0.2-dev` and `mathieucarbou/ESPAsyncWebServer @ 3.3.14`: [![](https://mathieu.carbou.me/ESPAsyncWebServer/perf-c10-asynctcpsock.png)](https://mathieu.carbou.me/ESPAsyncWebServer/perf-c10-asynctcpsock.png) diff --git a/docs/index.md b/docs/index.md index 4336c1040..2bd2255e8 100644 --- a/docs/index.md +++ b/docs/index.md @@ -15,8 +15,8 @@ Supports: WebSocket, SSE, Authentication, Arduino Json 7, File Upload, Static Fi This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubox-node-org/ESPAsyncWebServer) and includes all the concurrency fixes. -- [Coordinate and dependencies](#coordinate-and-dependencies) - [Changes in this fork](#changes-in-this-fork) +- [Dependencies](#dependencies) - [Performance](#performance) - [Important recommendations](#important-recommendations) - [`AsyncWebSocketMessageBuffer` and `makeBuffer()`](#asyncwebsocketmessagebuffer-and-makebuffer) @@ -26,24 +26,6 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo - [Migration to Middleware to improve performance and memory usage](#migration-to-middleware-to-improve-performance-and-memory-usage) - [Original Documentation](#original-documentation) -## Coordinate and dependencies - -**WARNING** The library name was changed from `ESP Async WebServer` to `ESPAsyncWebServer` as per the Arduino Lint recommendations, but its name had to stay `ESP Async WebServer` in Arduino Registry. - -**PlatformIO / pioarduino:** - -```ini -lib_compat_mode = strict -lib_ldf_mode = chain -lib_deps = mathieucarbou/ESPAsyncWebServer @ 3.3.14 -``` - -**Dependencies:** - -- **ESP32 with AsyncTCP**: `mathieucarbou/AsyncTCP @ 3.2.10` (Arduino IDE: [https://github.com/mathieucarbou/AsyncTCP#v3.2.10](https://github.com/mathieucarbou/AsyncTCP/releases)) -- **ESP8266**: `esphome/ESPAsyncTCP-esphome @ 2.0.0` (Arduino IDE: [https://github.com/mathieucarbou/esphome-ESPAsyncTCP#v2.0.0](https://github.com/mathieucarbou/esphome-ESPAsyncTCP/releases/tag/v2.0.0)) -- **RP2040**: `khoih-prog/AsyncTCP_RP2040W @ 1.2.0` (Arduino IDE: [https://github.com/khoih-prog/AsyncTCP_RP2040W#v1.2.0](https://github.com/khoih-prog/AsyncTCP_RP2040W/releases/tag/v1.2.0)) - ## Changes in this fork - (bug) A lot of bug fixes @@ -60,6 +42,7 @@ lib_deps = mathieucarbou/ESPAsyncWebServer @ 3.3.14 - (feat) **Resumable download** support using HEAD and bytes range - (feat) `StreamConcat` example to show how to stream multiple files in one response - (feat) Removed ESPIDF Editor (this is not the role of a web server library to do that - get the source files from the original repos if required) +- (perf) [AsyncTCPSock](https://github.com/mathieucarbou/AsyncTCPSock) support: AsyncTCP can be ignored and AsyncTCPSock used instead - (perf) `char*` overloads to avoid using `String` - (perf) `DEFAULT_MAX_WS_CLIENTS` to change the number of allows WebSocket clients and use `cleanupClients()` to help cleanup resources about dead clients - (perf) `setCloseClientOnQueueFull(bool)` which can be set on a client to either close the connection or discard messages but not close the connection when the queue is full @@ -69,6 +52,41 @@ lib_deps = mathieucarbou/ESPAsyncWebServer @ 3.3.14 - (perf) Lot of code cleanup and optimizations - (perf) Performance improvements in terms of memory, speed and size +## Dependencies + +**WARNING** The library name was changed from `ESP Async WebServer` to `ESPAsyncWebServer` as per the Arduino Lint recommendations, but its name had to stay `ESP Async WebServer` in Arduino Registry. + +**PlatformIO / pioarduino:** + +```ini +lib_compat_mode = strict +lib_ldf_mode = chain +lib_deps = mathieucarbou/ESPAsyncWebServer @ 3.3.14 +``` + +**Dependencies:** + +- **ESP32 with AsyncTCP**: `mathieucarbou/AsyncTCP @ 3.2.10` (Arduino IDE: [https://github.com/mathieucarbou/AsyncTCP#v3.2.10](https://github.com/mathieucarbou/AsyncTCP/releases)) +- **ESP32 with AsyncTCPSock**: `https://github.com/mathieucarbou/AsyncTCPSock/archive/refs/tags/v1.0.2-dev.zip` +- **ESP8266**: `esphome/ESPAsyncTCP-esphome @ 2.0.0` (Arduino IDE: [https://github.com/mathieucarbou/esphome-ESPAsyncTCP#v2.0.0](https://github.com/mathieucarbou/esphome-ESPAsyncTCP/releases/tag/v2.0.0)) +- **RP2040**: `khoih-prog/AsyncTCP_RP2040W @ 1.2.0` (Arduino IDE: [https://github.com/khoih-prog/AsyncTCP_RP2040W#v1.2.0](https://github.com/khoih-prog/AsyncTCP_RP2040W/releases/tag/v1.2.0)) + +**AsyncTCPSock** + +AsyncTCPSock can be used instead of AsyncTCP by excluding AsyncTCP from the library dependencies and adding AsyncTCPSock instead: + +```ini +lib_compat_mode = strict +lib_ldf_mode = chain +lib_deps = + ; mathieucarbou/AsyncTCP @ 3.2.10 + https://github.com/mathieucarbou/AsyncTCPSock/archive/refs/tags/v1.0.2-dev.zip + mathieucarbou/ESPAsyncWebServer @ 3.3.14 +lib_ignore = + AsyncTCP + mathieucarbou/AsyncTCP +``` + ## Performance ```bash @@ -80,7 +98,7 @@ Here is a capture of the `perf-test-AsyncTCP` PIO environment running with `math [![](https://mathieu.carbou.me/ESPAsyncWebServer/perf-c10.png)](https://mathieu.carbou.me/ESPAsyncWebServer/perf-c10.png) -Here is a capture of the `perf-test-AsyncTCPSock` PIO environment running with `https://github.com/mathieucarbou/AsyncTCPSock/archive/refs/tags/v1.0.1-dev.zip` and `mathieucarbou/ESPAsyncWebServer @ 3.3.14`: +Here is a capture of the `perf-test-AsyncTCPSock` PIO environment running with `mathieucarbou/AsyncTCPSock @ v1.0.2-dev` and `mathieucarbou/ESPAsyncWebServer @ 3.3.14`: [![](https://mathieu.carbou.me/ESPAsyncWebServer/perf-c10-asynctcpsock.png)](https://mathieu.carbou.me/ESPAsyncWebServer/perf-c10-asynctcpsock.png) diff --git a/platformio.ini b/platformio.ini index bf9326e6e..f7a9f519a 100644 --- a/platformio.ini +++ b/platformio.ini @@ -58,7 +58,7 @@ build_flags = ${env.build_flags} [env:perf-test-AsyncTCPSock] platform = https://github.com/pioarduino/platform-espressif32/releases/download/53.03.10-rc1/platform-espressif32.zip lib_deps = - https://github.com/mathieucarbou/AsyncTCPSock/archive/refs/tags/v1.0.1-dev.zip + https://github.com/mathieucarbou/AsyncTCPSock/archive/refs/tags/v1.0.2-dev.zip build_flags = ${env.build_flags} -D PERF_TEST=1 From f3265e3105f6ee728225328967464d62c0b03762 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Mon, 14 Oct 2024 00:32:26 +0200 Subject: [PATCH 432/551] doc update --- README.md | 18 ++++++++++++------ docs/index.md | 18 ++++++++++++------ platformio.ini | 2 +- 3 files changed, 25 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 2bd2255e8..5257d5801 100644 --- a/README.md +++ b/README.md @@ -66,10 +66,16 @@ lib_deps = mathieucarbou/ESPAsyncWebServer @ 3.3.14 **Dependencies:** -- **ESP32 with AsyncTCP**: `mathieucarbou/AsyncTCP @ 3.2.10` (Arduino IDE: [https://github.com/mathieucarbou/AsyncTCP#v3.2.10](https://github.com/mathieucarbou/AsyncTCP/releases)) -- **ESP32 with AsyncTCPSock**: `https://github.com/mathieucarbou/AsyncTCPSock/archive/refs/tags/v1.0.2-dev.zip` -- **ESP8266**: `esphome/ESPAsyncTCP-esphome @ 2.0.0` (Arduino IDE: [https://github.com/mathieucarbou/esphome-ESPAsyncTCP#v2.0.0](https://github.com/mathieucarbou/esphome-ESPAsyncTCP/releases/tag/v2.0.0)) -- **RP2040**: `khoih-prog/AsyncTCP_RP2040W @ 1.2.0` (Arduino IDE: [https://github.com/khoih-prog/AsyncTCP_RP2040W#v1.2.0](https://github.com/khoih-prog/AsyncTCP_RP2040W/releases/tag/v1.2.0)) +- **ESP32 with AsyncTCP**: `mathieucarbou/AsyncTCP @ 3.2.10` + Arduino IDE: [https://github.com/mathieucarbou/AsyncTCP#v3.2.10](https://github.com/mathieucarbou/AsyncTCP/releases) + +- **ESP32 with AsyncTCPSock**: `https://github.com/mathieucarbou/AsyncTCPSock/archive/refs/tags/v1.0.3-dev.zip` + +- **ESP8266**: `esphome/ESPAsyncTCP-esphome @ 2.0.0` + Arduino IDE: [https://github.com/mathieucarbou/esphome-ESPAsyncTCP#v2.0.0](https://github.com/mathieucarbou/esphome-ESPAsyncTCP/releases/tag/v2.0.0) + +- **RP2040**: `khoih-prog/AsyncTCP_RP2040W @ 1.2.0` + Arduino IDE: [https://github.com/khoih-prog/AsyncTCP_RP2040W#v1.2.0](https://github.com/khoih-prog/AsyncTCP_RP2040W/releases/tag/v1.2.0) **AsyncTCPSock** @@ -80,7 +86,7 @@ lib_compat_mode = strict lib_ldf_mode = chain lib_deps = ; mathieucarbou/AsyncTCP @ 3.2.10 - https://github.com/mathieucarbou/AsyncTCPSock/archive/refs/tags/v1.0.2-dev.zip + https://github.com/mathieucarbou/AsyncTCPSock/archive/refs/tags/v1.0.3-dev.zip mathieucarbou/ESPAsyncWebServer @ 3.3.14 lib_ignore = AsyncTCP @@ -98,7 +104,7 @@ Here is a capture of the `perf-test-AsyncTCP` PIO environment running with `math [![](https://mathieu.carbou.me/ESPAsyncWebServer/perf-c10.png)](https://mathieu.carbou.me/ESPAsyncWebServer/perf-c10.png) -Here is a capture of the `perf-test-AsyncTCPSock` PIO environment running with `mathieucarbou/AsyncTCPSock @ v1.0.2-dev` and `mathieucarbou/ESPAsyncWebServer @ 3.3.14`: +Here is a capture of the `perf-test-AsyncTCPSock` PIO environment running with `mathieucarbou/AsyncTCPSock @ v1.0.3-dev` and `mathieucarbou/ESPAsyncWebServer @ 3.3.14`: [![](https://mathieu.carbou.me/ESPAsyncWebServer/perf-c10-asynctcpsock.png)](https://mathieu.carbou.me/ESPAsyncWebServer/perf-c10-asynctcpsock.png) diff --git a/docs/index.md b/docs/index.md index 2bd2255e8..5257d5801 100644 --- a/docs/index.md +++ b/docs/index.md @@ -66,10 +66,16 @@ lib_deps = mathieucarbou/ESPAsyncWebServer @ 3.3.14 **Dependencies:** -- **ESP32 with AsyncTCP**: `mathieucarbou/AsyncTCP @ 3.2.10` (Arduino IDE: [https://github.com/mathieucarbou/AsyncTCP#v3.2.10](https://github.com/mathieucarbou/AsyncTCP/releases)) -- **ESP32 with AsyncTCPSock**: `https://github.com/mathieucarbou/AsyncTCPSock/archive/refs/tags/v1.0.2-dev.zip` -- **ESP8266**: `esphome/ESPAsyncTCP-esphome @ 2.0.0` (Arduino IDE: [https://github.com/mathieucarbou/esphome-ESPAsyncTCP#v2.0.0](https://github.com/mathieucarbou/esphome-ESPAsyncTCP/releases/tag/v2.0.0)) -- **RP2040**: `khoih-prog/AsyncTCP_RP2040W @ 1.2.0` (Arduino IDE: [https://github.com/khoih-prog/AsyncTCP_RP2040W#v1.2.0](https://github.com/khoih-prog/AsyncTCP_RP2040W/releases/tag/v1.2.0)) +- **ESP32 with AsyncTCP**: `mathieucarbou/AsyncTCP @ 3.2.10` + Arduino IDE: [https://github.com/mathieucarbou/AsyncTCP#v3.2.10](https://github.com/mathieucarbou/AsyncTCP/releases) + +- **ESP32 with AsyncTCPSock**: `https://github.com/mathieucarbou/AsyncTCPSock/archive/refs/tags/v1.0.3-dev.zip` + +- **ESP8266**: `esphome/ESPAsyncTCP-esphome @ 2.0.0` + Arduino IDE: [https://github.com/mathieucarbou/esphome-ESPAsyncTCP#v2.0.0](https://github.com/mathieucarbou/esphome-ESPAsyncTCP/releases/tag/v2.0.0) + +- **RP2040**: `khoih-prog/AsyncTCP_RP2040W @ 1.2.0` + Arduino IDE: [https://github.com/khoih-prog/AsyncTCP_RP2040W#v1.2.0](https://github.com/khoih-prog/AsyncTCP_RP2040W/releases/tag/v1.2.0) **AsyncTCPSock** @@ -80,7 +86,7 @@ lib_compat_mode = strict lib_ldf_mode = chain lib_deps = ; mathieucarbou/AsyncTCP @ 3.2.10 - https://github.com/mathieucarbou/AsyncTCPSock/archive/refs/tags/v1.0.2-dev.zip + https://github.com/mathieucarbou/AsyncTCPSock/archive/refs/tags/v1.0.3-dev.zip mathieucarbou/ESPAsyncWebServer @ 3.3.14 lib_ignore = AsyncTCP @@ -98,7 +104,7 @@ Here is a capture of the `perf-test-AsyncTCP` PIO environment running with `math [![](https://mathieu.carbou.me/ESPAsyncWebServer/perf-c10.png)](https://mathieu.carbou.me/ESPAsyncWebServer/perf-c10.png) -Here is a capture of the `perf-test-AsyncTCPSock` PIO environment running with `mathieucarbou/AsyncTCPSock @ v1.0.2-dev` and `mathieucarbou/ESPAsyncWebServer @ 3.3.14`: +Here is a capture of the `perf-test-AsyncTCPSock` PIO environment running with `mathieucarbou/AsyncTCPSock @ v1.0.3-dev` and `mathieucarbou/ESPAsyncWebServer @ 3.3.14`: [![](https://mathieu.carbou.me/ESPAsyncWebServer/perf-c10-asynctcpsock.png)](https://mathieu.carbou.me/ESPAsyncWebServer/perf-c10-asynctcpsock.png) diff --git a/platformio.ini b/platformio.ini index f7a9f519a..1611a79c1 100644 --- a/platformio.ini +++ b/platformio.ini @@ -58,7 +58,7 @@ build_flags = ${env.build_flags} [env:perf-test-AsyncTCPSock] platform = https://github.com/pioarduino/platform-espressif32/releases/download/53.03.10-rc1/platform-espressif32.zip lib_deps = - https://github.com/mathieucarbou/AsyncTCPSock/archive/refs/tags/v1.0.2-dev.zip + https://github.com/mathieucarbou/AsyncTCPSock/archive/refs/tags/v1.0.3-dev.zip build_flags = ${env.build_flags} -D PERF_TEST=1 From fd3786108d653c18c68cf79367613f909a24dbe4 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Mon, 14 Oct 2024 00:37:21 +0200 Subject: [PATCH 433/551] doc update --- README.md | 6 ++++-- docs/index.md | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 5257d5801..82ed7f7d5 100644 --- a/README.md +++ b/README.md @@ -95,16 +95,18 @@ lib_ignore = ## Performance +Performance of `mathieucarbou/ESPAsyncWebServer @ 3.3.14`: + ```bash > brew install autocannon > autocannon -c 10 -w 10 -d 20 http://192.168.4.1 ``` -Here is a capture of the `perf-test-AsyncTCP` PIO environment running with `mathieucarbou/AsyncTCP @ 3.2.10` and `mathieucarbou/ESPAsyncWebServer @ 3.3.14`: +With `mathieucarbou/AsyncTCP @ 3.2.10` [![](https://mathieu.carbou.me/ESPAsyncWebServer/perf-c10.png)](https://mathieu.carbou.me/ESPAsyncWebServer/perf-c10.png) -Here is a capture of the `perf-test-AsyncTCPSock` PIO environment running with `mathieucarbou/AsyncTCPSock @ v1.0.3-dev` and `mathieucarbou/ESPAsyncWebServer @ 3.3.14`: +With `https://github.com/mathieucarbou/AsyncTCPSock/archive/refs/tags/v1.0.3-dev.zip`: [![](https://mathieu.carbou.me/ESPAsyncWebServer/perf-c10-asynctcpsock.png)](https://mathieu.carbou.me/ESPAsyncWebServer/perf-c10-asynctcpsock.png) diff --git a/docs/index.md b/docs/index.md index 5257d5801..82ed7f7d5 100644 --- a/docs/index.md +++ b/docs/index.md @@ -95,16 +95,18 @@ lib_ignore = ## Performance +Performance of `mathieucarbou/ESPAsyncWebServer @ 3.3.14`: + ```bash > brew install autocannon > autocannon -c 10 -w 10 -d 20 http://192.168.4.1 ``` -Here is a capture of the `perf-test-AsyncTCP` PIO environment running with `mathieucarbou/AsyncTCP @ 3.2.10` and `mathieucarbou/ESPAsyncWebServer @ 3.3.14`: +With `mathieucarbou/AsyncTCP @ 3.2.10` [![](https://mathieu.carbou.me/ESPAsyncWebServer/perf-c10.png)](https://mathieu.carbou.me/ESPAsyncWebServer/perf-c10.png) -Here is a capture of the `perf-test-AsyncTCPSock` PIO environment running with `mathieucarbou/AsyncTCPSock @ v1.0.3-dev` and `mathieucarbou/ESPAsyncWebServer @ 3.3.14`: +With `https://github.com/mathieucarbou/AsyncTCPSock/archive/refs/tags/v1.0.3-dev.zip`: [![](https://mathieu.carbou.me/ESPAsyncWebServer/perf-c10-asynctcpsock.png)](https://mathieu.carbou.me/ESPAsyncWebServer/perf-c10-asynctcpsock.png) From 865f1e852a401e2922a9d0affbf098a1ee6924d4 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Mon, 14 Oct 2024 08:56:40 +0200 Subject: [PATCH 434/551] arduino/arduino-lint-action@v2 --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6082bb0eb..39d770236 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -37,7 +37,7 @@ jobs: uses: actions/checkout@v4 - name: Arduino Lint - uses: arduino/arduino-lint-action@v1 + uses: arduino/arduino-lint-action@v2 with: library-manager: update From 5b9469073b87b67abceee2d281cdc28b9443b19c Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Mon, 14 Oct 2024 09:21:59 +0200 Subject: [PATCH 435/551] code cleanup --- src/Middleware.cpp | 14 +-- src/WebHandlers.cpp | 2 +- src/WebRequest.cpp | 52 ++++++----- src/literals.h | 220 +++++++++++++++++++++++--------------------- 4 files changed, 152 insertions(+), 136 deletions(-) diff --git a/src/Middleware.cpp b/src/Middleware.cpp index bfc4e7b1f..d5e18c54d 100644 --- a/src/Middleware.cpp +++ b/src/Middleware.cpp @@ -195,16 +195,16 @@ void LoggingMiddleware::run(AsyncWebServerRequest* request, ArMiddlewareNext nex } void CorsMiddleware::addCORSHeaders(AsyncWebServerResponse* response) { - response->addHeader(F("Access-Control-Allow-Origin"), _origin.c_str()); - response->addHeader(F("Access-Control-Allow-Methods"), _methods.c_str()); - response->addHeader(F("Access-Control-Allow-Headers"), _headers.c_str()); - response->addHeader(F("Access-Control-Allow-Credentials"), _credentials ? F("true") : F("false")); - response->addHeader(F("Access-Control-Max-Age"), String(_maxAge).c_str()); + response->addHeader(asyncsrv::T_CORS_ACAO, _origin.c_str()); + response->addHeader(asyncsrv::T_CORS_ACAM, _methods.c_str()); + response->addHeader(asyncsrv::T_CORS_ACAH, _headers.c_str()); + response->addHeader(asyncsrv::T_CORS_ACAC, _credentials ? asyncsrv::T_TRUE : asyncsrv::T_FALSE); + response->addHeader(asyncsrv::T_CORS_ACMA, String(_maxAge).c_str()); } void CorsMiddleware::run(AsyncWebServerRequest* request, ArMiddlewareNext next) { // Origin header ? => CORS handling - if (request->hasHeader(F("Origin"))) { + if (request->hasHeader(asyncsrv::T_CORS_O)) { // check if this is a preflight request => handle it and return if (request->method() == HTTP_OPTIONS) { AsyncWebServerResponse* response = request->beginResponse(200); @@ -250,7 +250,7 @@ void RateLimitMiddleware::run(AsyncWebServerRequest* request, ArMiddlewareNext n next(); } else { AsyncWebServerResponse* response = request->beginResponse(429); - response->addHeader(F("Retry-After"), retryAfterSeconds); + response->addHeader(asyncsrv::T_retry_after, retryAfterSeconds); request->send(response); } } diff --git a/src/WebHandlers.cpp b/src/WebHandlers.cpp index 7c3a7dc37..ae0be51ec 100644 --- a/src/WebHandlers.cpp +++ b/src/WebHandlers.cpp @@ -146,7 +146,7 @@ bool AsyncStaticWebHandler::_fileExists(AsyncWebServerRequest* request, const St bool fileFound = false; bool gzipFound = false; - String gzip = path + F(".gz"); + String gzip = path + T__gz; if (_gzipFirst) { if (_fs.exists(gzip)) { diff --git a/src/WebRequest.cpp b/src/WebRequest.cpp index 242a11171..845210697 100644 --- a/src/WebRequest.cpp +++ b/src/WebRequest.cpp @@ -280,38 +280,40 @@ bool AsyncWebServerRequest::_parseReqHeader() { } } else if (name.equalsIgnoreCase(T_Content_Length)) { _contentLength = atoi(value.c_str()); - } else if (name.equalsIgnoreCase(T_EXPECT) && value == T_100_CONTINUE) { + } else if (name.equalsIgnoreCase(T_EXPECT) && value.equalsIgnoreCase(T_100_CONTINUE)) { _expectingContinue = true; } else if (name.equalsIgnoreCase(T_AUTH)) { - if (value.length() > 5 && value.substring(0, 5).equalsIgnoreCase(T_BASIC)) { - _authorization = value.substring(6); - _authMethod = AsyncAuthType::AUTH_BASIC; - } else if (value.length() > 6 && value.substring(0, 6).equalsIgnoreCase(T_DIGEST)) { - _authMethod = AsyncAuthType::AUTH_DIGEST; - _authorization = value.substring(7); - } else if (value.length() > 6 && value.substring(0, 6).equalsIgnoreCase(T_BEARER)) { - _authMethod = AsyncAuthType::AUTH_BEARER; - _authorization = value.substring(7); - } else { + int space = value.indexOf(' '); + if (space == -1) { _authorization = value; _authMethod = AsyncAuthType::AUTH_OTHER; + } else { + String method = value.substring(0, space); + if (method.equalsIgnoreCase(T_BASIC)) { + _authMethod = AsyncAuthType::AUTH_BASIC; + } else if (method.equalsIgnoreCase(T_DIGEST)) { + _authMethod = AsyncAuthType::AUTH_DIGEST; + } else if (method.equalsIgnoreCase(T_BEARER)) { + _authMethod = AsyncAuthType::AUTH_BEARER; + } else { + _authMethod = AsyncAuthType::AUTH_OTHER; + } + _authorization = value.substring(space + 1); } - } else { - if (name.equalsIgnoreCase(T_UPGRADE) && value.equalsIgnoreCase(T_WS)) { - // WebSocket request can be uniquely identified by header: [Upgrade: websocket] - _reqconntype = RCT_WS; - } else if (name.equalsIgnoreCase(T_ACCEPT)) { - String lowcase(value); - lowcase.toLowerCase(); + } else if (name.equalsIgnoreCase(T_UPGRADE) && value.equalsIgnoreCase(T_WS)) { + // WebSocket request can be uniquely identified by header: [Upgrade: websocket] + _reqconntype = RCT_WS; + } else if (name.equalsIgnoreCase(T_ACCEPT)) { + String lowcase(value); + lowcase.toLowerCase(); #ifndef ESP8266 - const char* substr = std::strstr(lowcase.c_str(), T_text_event_stream); + const char* substr = std::strstr(lowcase.c_str(), T_text_event_stream); #else - const char* substr = std::strstr(lowcase.c_str(), String(T_text_event_stream).c_str()); + const char* substr = std::strstr(lowcase.c_str(), String(T_text_event_stream).c_str()); #endif - if (substr != NULL) { - // WebEvent request can be uniquely identified by header: [Accept: text/event-stream] - _reqconntype = RCT_EVENT; - } + if (substr != NULL) { + // WebEvent request can be uniquely identified by header: [Accept: text/event-stream] + _reqconntype = RCT_EVENT; } } _headers.emplace_back(name, value); @@ -831,7 +833,7 @@ void AsyncWebServerRequest::requestAuthentication(AsyncAuthType method, const ch break; } case AsyncAuthType::AUTH_DIGEST: { - constexpr size_t len = strlen(T_DIGEST_) + strlen(T_realm__) + strlen(T_auth_nonce) + 32 + strlen(T__opaque) + 32 + 1; + size_t len = strlen(T_DIGEST_) + strlen(T_realm__) + strlen(T_auth_nonce) + 32 + strlen(T__opaque) + 32 + 1; String header; header.reserve(len + strlen(realm)); header.concat(T_DIGEST_); diff --git a/src/literals.h b/src/literals.h index 2300b4af7..778e3dbc9 100644 --- a/src/literals.h +++ b/src/literals.h @@ -5,46 +5,79 @@ namespace asyncsrv { static constexpr const char* empty = ""; #ifndef ESP8622 +static constexpr const char* T__opaque = "\", opaque=\""; static constexpr const char* T_100_CONTINUE = "100-continue"; -static constexpr const char* T_ACCEPT = "Accept"; -static constexpr const char* T_Accept_Ranges = "Accept-Ranges"; +static constexpr const char* T_13 = "13"; +static constexpr const char* T_ACCEPT = "accept"; +static constexpr const char* T_Accept_Ranges = "accept-ranges"; static constexpr const char* T_app_xform_urlencoded = "application/x-www-form-urlencoded"; -static constexpr const char* T_AUTH = "Authorization"; -static constexpr const char* T_BASIC = "Basic"; -static constexpr const char* T_BASIC_REALM = "Basic realm=\""; -static constexpr const char* T_LOGIN_REQ = "Login Required"; +static constexpr const char* T_AUTH = "authorization"; +static constexpr const char* T_auth_nonce = "\", qop=\"auth\", nonce=\""; +static constexpr const char* T_BASIC = "basic"; +static constexpr const char* T_BASIC_REALM = "basic realm=\""; +static constexpr const char* T_BEARER = "bearer"; static constexpr const char* T_BODY = "body"; -static constexpr const char* T_Cache_Control = "Cache-Control"; +static constexpr const char* T_Cache_Control = "cache-control"; static constexpr const char* T_chunked = "chunked"; static constexpr const char* T_close = "close"; -static constexpr const char* T_Connection = "Connection"; -static constexpr const char* T_Content_Disposition = "Content-Disposition"; -static constexpr const char* T_Content_Encoding = "Content-Encoding"; -static constexpr const char* T_Content_Length = "Content-Length"; -static constexpr const char* T_Content_Type = "Content-Type"; -static constexpr const char* T_Cookie = "Cookie"; -static constexpr const char* T_DIGEST = "Digest"; -static constexpr const char* T_DIGEST_ = "Digest "; -static constexpr const char* T_BEARER = "Bearer"; -static constexpr const char* T_ETag = "ETag"; -static constexpr const char* T_EXPECT = "Expect"; +static constexpr const char* T_cnonce = "cnonce"; +static constexpr const char* T_Connection = "connection"; +static constexpr const char* T_Content_Disposition = "content-disposition"; +static constexpr const char* T_Content_Encoding = "content-encoding"; +static constexpr const char* T_Content_Length = "content-length"; +static constexpr const char* T_Content_Type = "content-type"; +static constexpr const char* T_Cookie = "cookie"; +static constexpr const char* T_CORS_ACAC = "access-control-allow-credentials"; +static constexpr const char* T_CORS_ACAH = "access-control-allow-headers"; +static constexpr const char* T_CORS_ACAM = "access-control-allow-methods"; +static constexpr const char* T_CORS_ACAO = "access-control-allow-origin"; +static constexpr const char* T_CORS_ACMA = "access-control-max-age"; +static constexpr const char* T_CORS_O = "origin"; +static constexpr const char* T_data_ = "data: "; +static constexpr const char* T_DIGEST = "digest"; +static constexpr const char* T_DIGEST_ = "digest "; +static constexpr const char* T_ETag = "etag"; +static constexpr const char* T_event_ = "event: "; +static constexpr const char* T_EXPECT = "expect"; +static constexpr const char* T_FALSE = "false"; +static constexpr const char* T_filename = "filename"; +static constexpr const char* T_gzip = "gzip"; +static constexpr const char* T_Host = "host"; static constexpr const char* T_HTTP_1_0 = "HTTP/1.0"; static constexpr const char* T_HTTP_100_CONT = "HTTP/1.1 100 Continue\r\n\r\n"; -static constexpr const char* T_IMS = "If-Modified-Since"; -static constexpr const char* T_INM = "If-None-Match"; +static constexpr const char* T_id__ = "id: "; +static constexpr const char* T_IMS = "if-modified-since"; +static constexpr const char* T_INM = "if-none-match"; static constexpr const char* T_keep_alive = "keep-alive"; -static constexpr const char* T_Last_Event_ID = "Last-Event-ID"; -static constexpr const char* T_Last_Modified = "Last-Modified"; -static constexpr const char* T_LOCATION = "Location"; +static constexpr const char* T_Last_Event_ID = "last-event-id"; +static constexpr const char* T_Last_Modified = "last-modified"; +static constexpr const char* T_LOCATION = "location"; +static constexpr const char* T_LOGIN_REQ = "Login Required"; static constexpr const char* T_MULTIPART_ = "multipart/"; +static constexpr const char* T_name = "name"; +static constexpr const char* T_nc = "nc"; static constexpr const char* T_no_cache = "no-cache"; +static constexpr const char* T_nonce = "nonce"; static constexpr const char* T_none = "none"; -static constexpr const char* T_UPGRADE = "Upgrade"; +static constexpr const char* T_opaque = "opaque"; +static constexpr const char* T_qop = "qop"; +static constexpr const char* T_realm = "realm"; +static constexpr const char* T_realm__ = "realm=\""; +static constexpr const char* T_response = "response"; +static constexpr const char* T_retry_ = "retry: "; +static constexpr const char* T_retry_after = "retry-after"; +static constexpr const char* T_rn = "\r\n"; +static constexpr const char* T_rnrn = "\r\n\r\n"; +static constexpr const char* T_Transfer_Encoding = "transfer-encoding"; +static constexpr const char* T_TRUE = "true"; +static constexpr const char* T_UPGRADE = "upgrade"; +static constexpr const char* T_uri = "uri"; +static constexpr const char* T_username = "username"; static constexpr const char* T_WS = "websocket"; -static constexpr const char* T_WWW_AUTH = "WWW-Authenticate"; -static constexpr const char* T_Transfer_Encoding = "Transfer-Encoding"; +static constexpr const char* T_WWW_AUTH = "www-authenticate"; // HTTP Methods + static constexpr const char* T_ANY = "ANY"; static constexpr const char* T_GET = "GET"; static constexpr const char* T_POST = "POST"; @@ -147,72 +180,78 @@ static constexpr const char* T_HTTP_CODE_504 = "Gateway Time-out"; static constexpr const char* T_HTTP_CODE_505 = "HTTP Version not supported"; static constexpr const char* T_HTTP_CODE_ANY = "Unknown code"; -// other -static constexpr const char* T__opaque = "\", opaque=\""; -static constexpr const char* T_13 = "13"; -static constexpr const char* T_auth_nonce = "\", qop=\"auth\", nonce=\""; -static constexpr const char* T_cnonce = "cnonce"; -static constexpr const char* T_data_ = "data: "; -static constexpr const char* T_event_ = "event: "; -static constexpr const char* T_filename = "filename"; -static constexpr const char* T_gzip = "gzip"; -static constexpr const char* T_Host = "Host"; -static constexpr const char* T_id__ = "id: "; -static constexpr const char* T_name = "name"; -static constexpr const char* T_nc = "nc"; -static constexpr const char* T_nonce = "nonce"; -static constexpr const char* T_opaque = "opaque"; -static constexpr const char* T_qop = "qop"; -static constexpr const char* T_realm = "realm"; -static constexpr const char* T_realm__ = "realm=\""; -static constexpr const char* T_response = "response"; -static constexpr const char* T_retry_ = "retry: "; -static constexpr const char* T_rn = "\r\n"; -static constexpr const char* T_rnrn = "\r\n\r\n"; -static constexpr const char* T_uri = "uri"; -static constexpr const char* T_username = "username"; - - #else // ESP8622 +static const char T__opaque[] PROGMEM = "\", opaque=\""; static const char T_100_CONTINUE[] PROGMEM = "100-continue"; -static const char T_ACCEPT[] PROGMEM = "Accept"; -static const char T_Accept_Ranges[] PROGMEM = "Accept-Ranges"; +static const char T_13[] PROGMEM = "13"; +static const char T_Accept_Ranges[] PROGMEM = "accept-ranges"; +static const char T_ACCEPT[] PROGMEM = "accept"; static const char T_app_xform_urlencoded[] PROGMEM = "application/x-www-form-urlencoded"; -static const char T_AUTH[] PROGMEM = "Authorization"; -static const char T_BASIC[] PROGMEM = "Basic"; -static const char T_BASIC_REALM[] PROGMEM = "Basic realm=\""; -static const char T_LOGIN_REQ[] PROGMEM = "Login Required"; +static const char T_auth_nonce[] PROGMEM = "\", qop=\"auth\", nonce=\""; +static const char T_AUTH[] PROGMEM = "authorization"; +static const char T_BASIC_REALM[] PROGMEM = "basic realm=\""; +static const char T_BASIC[] PROGMEM = "basic"; +static const char T_BEARER[] PROGMEM = "bearer"; static const char T_BODY[] PROGMEM = "body"; -static const char T_Cache_Control[] PROGMEM = "Cache-Control"; +static const char T_Cache_Control[] PROGMEM = "cache-control"; static const char T_chunked[] PROGMEM = "chunked"; static const char T_close[] PROGMEM = "close"; -static const char T_Connection[] PROGMEM = "Connection"; -static const char T_Content_Disposition[] PROGMEM = "Content-Disposition"; -static const char T_Content_Encoding[] PROGMEM = "Content-Encoding"; -static const char T_Content_Length[] PROGMEM = "Content-Length"; -static const char T_Content_Type[] PROGMEM = "Content-Type"; -static const char T_Cookie[] PROGMEM = "Cookie"; -static const char T_DIGEST[] PROGMEM = "Digest"; -static const char T_DIGEST_[] PROGMEM = "Digest "; -static const char T_BEARER[] PROGMEM = "Bearer"; -static const char T_ETag[] PROGMEM = "ETag"; -static const char T_EXPECT[] PROGMEM = "Expect"; +static const char T_cnonce[] PROGMEM = "cnonce"; +static const char T_Connection[] PROGMEM = "connection"; +static const char T_Content_Disposition[] PROGMEM = "content-disposition"; +static const char T_Content_Encoding[] PROGMEM = "content-encoding"; +static const char T_Content_Length[] PROGMEM = "content-length"; +static const char T_Content_Type[] PROGMEM = "content-type"; +static const char T_Cookie[] PROGMEM = "cookie"; +static const char T_CORS_ACAC[] PROGMEM = "access-control-allow-credentials"; +static const char T_CORS_ACAH[] PROGMEM = "access-control-allow-headers"; +static const char T_CORS_ACAM[] PROGMEM = "access-control-allow-methods"; +static const char T_CORS_ACAO[] PROGMEM = "access-control-allow-origin"; +static const char T_CORS_ACMA[] PROGMEM = "access-control-max-age"; +static const char T_CORS_O[] PROGMEM = "origin"; +static const char T_data_[] PROGMEM = "data: "; +static const char T_DIGEST_[] PROGMEM = "digest "; +static const char T_DIGEST[] PROGMEM = "digest"; +static const char T_ETag[] PROGMEM = "etag"; +static const char T_event_[] PROGMEM = "event: "; +static const char T_EXPECT[] PROGMEM = "expect"; +static const char T_FALSE[] PROGMEM = "false"; +static const char T_filename[] PROGMEM = "filename"; +static const char T_gzip[] PROGMEM = "gzip"; +static const char T_Host[] PROGMEM = "host"; static const char T_HTTP_1_0[] PROGMEM = "HTTP/1.0"; static const char T_HTTP_100_CONT[] PROGMEM = "HTTP/1.1 100 Continue\r\n\r\n"; -static const char T_IMS[] PROGMEM = "If-Modified-Since"; -static const char T_INM[] PROGMEM = "If-None-Match"; +static const char T_id__[] PROGMEM = "id: "; +static const char T_IMS[] PROGMEM = "if-modified-since"; +static const char T_INM[] PROGMEM = "if-none-match"; static const char T_keep_alive[] PROGMEM = "keep-alive"; -static const char T_Last_Event_ID[] PROGMEM = "Last-Event-ID"; -static const char T_Last_Modified[] PROGMEM = "Last-Modified"; -static const char T_LOCATION[] PROGMEM = "Location"; +static const char T_Last_Event_ID[] PROGMEM = "last-event-id"; +static const char T_Last_Modified[] PROGMEM = "last-modified"; +static const char T_LOCATION[] PROGMEM = "location"; +static const char T_LOGIN_REQ[] PROGMEM = "Login Required"; static const char T_MULTIPART_[] PROGMEM = "multipart/"; +static const char T_name[] PROGMEM = "name"; +static const char T_nc[] PROGMEM = "nc"; static const char T_no_cache[] PROGMEM = "no-cache"; +static const char T_nonce[] PROGMEM = "nonce"; static const char T_none[] PROGMEM = "none"; -static const char T_UPGRADE[] PROGMEM = "Upgrade"; +static const char T_opaque[] PROGMEM = "opaque"; +static const char T_qop[] PROGMEM = "qop"; +static const char T_realm__[] PROGMEM = "realm=\""; +static const char T_realm[] PROGMEM = "realm"; +static const char T_response[] PROGMEM = "response"; +static const char T_retry_[] PROGMEM = "retry: "; +static const char T_retry_after[] PROGMEM = "retry-after"; +static const char T_rn[] PROGMEM = "\r\n"; +static const char T_rnrn[] PROGMEM = "\r\n\r\n"; +static const char T_Transfer_Encoding[] PROGMEM = "transfer-encoding"; +static const char T_TRUE[] PROGMEM = "true"; +static const char T_UPGRADE[] PROGMEM = "upgrade"; +static const char T_uri[] PROGMEM = "uri"; +static const char T_username[] PROGMEM = "username"; static const char T_WS[] PROGMEM = "websocket"; -static const char T_WWW_AUTH[] PROGMEM = "WWW-Authenticate"; -static const char T_Transfer_Encoding[] PROGMEM = "Transfer-Encoding"; +static const char T_WWW_AUTH[] PROGMEM = "www-authenticate"; // HTTP Methods static const char T_ANY[] PROGMEM = "ANY"; @@ -317,31 +356,6 @@ static const char T_HTTP_CODE_504[] PROGMEM = "Gateway Time-out"; static const char T_HTTP_CODE_505[] PROGMEM = "HTTP Version not supported"; static const char T_HTTP_CODE_ANY[] PROGMEM = "Unknown code"; -// other -static const char T__opaque[] PROGMEM = "\", opaque=\""; -static const char T_13[] PROGMEM = "13"; -static const char T_auth_nonce[] PROGMEM = "\", qop=\"auth\", nonce=\""; -static const char T_cnonce[] PROGMEM = "cnonce"; -static const char T_data_[] PROGMEM = "data: "; -static const char T_event_[] PROGMEM = "event: "; -static const char T_filename[] PROGMEM = "filename"; -static const char T_gzip[] PROGMEM = "gzip"; -static const char T_Host[] PROGMEM = "Host"; -static const char T_id__[] PROGMEM = "id: "; -static const char T_name[] PROGMEM = "name"; -static const char T_nc[] PROGMEM = "nc"; -static const char T_nonce[] PROGMEM = "nonce"; -static const char T_opaque[] PROGMEM = "opaque"; -static const char T_qop[] PROGMEM = "qop"; -static const char T_realm[] PROGMEM = "realm"; -static const char T_realm__[] PROGMEM = "realm=\""; -static const char T_response[] PROGMEM = "response"; -static const char T_retry_[] PROGMEM = "retry: "; -static const char T_rn[] PROGMEM = "\r\n"; -static const char T_rnrn[] PROGMEM = "\r\n\r\n"; -static const char T_uri[] PROGMEM = "uri"; -static const char T_username[] PROGMEM = "username"; - #endif // ESP8622 } // namespace asyncsrv {} From b788fafc9cba86b216953f998c2dd93905a25bc6 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Mon, 14 Oct 2024 11:36:17 +0200 Subject: [PATCH 436/551] v3.3.15 --- README.md | 6 +++--- docs/index.md | 6 +++--- library.json | 2 +- library.properties | 2 +- src/ESPAsyncWebServer.h | 4 ++-- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 82ed7f7d5..00bb45b45 100644 --- a/README.md +++ b/README.md @@ -61,7 +61,7 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo ```ini lib_compat_mode = strict lib_ldf_mode = chain -lib_deps = mathieucarbou/ESPAsyncWebServer @ 3.3.14 +lib_deps = mathieucarbou/ESPAsyncWebServer @ 3.3.15 ``` **Dependencies:** @@ -87,7 +87,7 @@ lib_ldf_mode = chain lib_deps = ; mathieucarbou/AsyncTCP @ 3.2.10 https://github.com/mathieucarbou/AsyncTCPSock/archive/refs/tags/v1.0.3-dev.zip - mathieucarbou/ESPAsyncWebServer @ 3.3.14 + mathieucarbou/ESPAsyncWebServer @ 3.3.15 lib_ignore = AsyncTCP mathieucarbou/AsyncTCP @@ -95,7 +95,7 @@ lib_ignore = ## Performance -Performance of `mathieucarbou/ESPAsyncWebServer @ 3.3.14`: +Performance of `mathieucarbou/ESPAsyncWebServer @ 3.3.15`: ```bash > brew install autocannon diff --git a/docs/index.md b/docs/index.md index 82ed7f7d5..00bb45b45 100644 --- a/docs/index.md +++ b/docs/index.md @@ -61,7 +61,7 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo ```ini lib_compat_mode = strict lib_ldf_mode = chain -lib_deps = mathieucarbou/ESPAsyncWebServer @ 3.3.14 +lib_deps = mathieucarbou/ESPAsyncWebServer @ 3.3.15 ``` **Dependencies:** @@ -87,7 +87,7 @@ lib_ldf_mode = chain lib_deps = ; mathieucarbou/AsyncTCP @ 3.2.10 https://github.com/mathieucarbou/AsyncTCPSock/archive/refs/tags/v1.0.3-dev.zip - mathieucarbou/ESPAsyncWebServer @ 3.3.14 + mathieucarbou/ESPAsyncWebServer @ 3.3.15 lib_ignore = AsyncTCP mathieucarbou/AsyncTCP @@ -95,7 +95,7 @@ lib_ignore = ## Performance -Performance of `mathieucarbou/ESPAsyncWebServer @ 3.3.14`: +Performance of `mathieucarbou/ESPAsyncWebServer @ 3.3.15`: ```bash > brew install autocannon diff --git a/library.json b/library.json index 0b14de368..987dba178 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "ESPAsyncWebServer", - "version": "3.3.14", + "version": "3.3.15", "description": "Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 and RP2040. Supports: WebSocket, SSE, Authentication, Arduino Json 7, File Upload, Static File serving, URL Rewrite, URL Redirect, etc.", "keywords": "http,async,websocket,webserver", "homepage": "https://github.com/mathieucarbou/ESPAsyncWebServer", diff --git a/library.properties b/library.properties index 824b3a377..31fdbb616 100644 --- a/library.properties +++ b/library.properties @@ -1,6 +1,6 @@ name=ESP Async WebServer includes=ESPAsyncWebServer.h -version=3.3.14 +version=3.3.15 author=Me-No-Dev maintainer=Mathieu Carbou sentence=Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 and RP2040 diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index fe3ff10cb..37c54de16 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -48,10 +48,10 @@ #include "literals.h" -#define ASYNCWEBSERVER_VERSION "3.3.14" +#define ASYNCWEBSERVER_VERSION "3.3.15" #define ASYNCWEBSERVER_VERSION_MAJOR 3 #define ASYNCWEBSERVER_VERSION_MINOR 3 -#define ASYNCWEBSERVER_VERSION_REVISION 14 +#define ASYNCWEBSERVER_VERSION_REVISION 15 #define ASYNCWEBSERVER_FORK_mathieucarbou #ifdef ASYNCWEBSERVER_REGEX From 272bd65c198b05ad35d4c5872d43ab8220c3ddde Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Mon, 14 Oct 2024 11:38:40 +0200 Subject: [PATCH 437/551] updated perf tests --- docs/perf-c10-asynctcpsock.png | Bin 310017 -> 317493 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/docs/perf-c10-asynctcpsock.png b/docs/perf-c10-asynctcpsock.png index 136b54562341a70414076c693c21ecbf567b6e48..b1d4d7aa615b9069124878e295750747b53b1ada 100644 GIT binary patch literal 317493 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

5lH^d1>{bCRs-YaEnvze3u3%=7BI~Zz1h{;s{ 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%0DqPmzMVqxGp%)sq6^M(Tw^lsvbMV~V)}1i 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 z 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%0A@Jh{gOPgp|`Z* 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 From 65906f7419442b7bd4764e9703f7401fd303e92d Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Tue, 15 Oct 2024 10:18:15 +0200 Subject: [PATCH 438/551] Fixed literals for ESP8266 --- src/literals.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/literals.h b/src/literals.h index 778e3dbc9..fb2af7448 100644 --- a/src/literals.h +++ b/src/literals.h @@ -4,7 +4,7 @@ namespace asyncsrv { static constexpr const char* empty = ""; -#ifndef ESP8622 +#ifndef ESP8266 static constexpr const char* T__opaque = "\", opaque=\""; static constexpr const char* T_100_CONTINUE = "100-continue"; static constexpr const char* T_13 = "13"; @@ -180,7 +180,7 @@ static constexpr const char* T_HTTP_CODE_504 = "Gateway Time-out"; static constexpr const char* T_HTTP_CODE_505 = "HTTP Version not supported"; static constexpr const char* T_HTTP_CODE_ANY = "Unknown code"; -#else // ESP8622 +#else // ESP8266 static const char T__opaque[] PROGMEM = "\", opaque=\""; static const char T_100_CONTINUE[] PROGMEM = "100-continue"; @@ -356,6 +356,6 @@ static const char T_HTTP_CODE_504[] PROGMEM = "Gateway Time-out"; static const char T_HTTP_CODE_505[] PROGMEM = "HTTP Version not supported"; static const char T_HTTP_CODE_ANY[] PROGMEM = "Unknown code"; -#endif // ESP8622 +#endif // ESP8266 } // namespace asyncsrv {} From 139099ebd9282cb4d4d7301006ee96de280d9768 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Tue, 15 Oct 2024 10:18:52 +0200 Subject: [PATCH 439/551] v3.3.16 --- README.md | 6 +++--- docs/index.md | 6 +++--- library.json | 2 +- library.properties | 2 +- src/ESPAsyncWebServer.h | 4 ++-- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 00bb45b45..d45316a9c 100644 --- a/README.md +++ b/README.md @@ -61,7 +61,7 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo ```ini lib_compat_mode = strict lib_ldf_mode = chain -lib_deps = mathieucarbou/ESPAsyncWebServer @ 3.3.15 +lib_deps = mathieucarbou/ESPAsyncWebServer @ 3.3.16 ``` **Dependencies:** @@ -87,7 +87,7 @@ lib_ldf_mode = chain lib_deps = ; mathieucarbou/AsyncTCP @ 3.2.10 https://github.com/mathieucarbou/AsyncTCPSock/archive/refs/tags/v1.0.3-dev.zip - mathieucarbou/ESPAsyncWebServer @ 3.3.15 + mathieucarbou/ESPAsyncWebServer @ 3.3.16 lib_ignore = AsyncTCP mathieucarbou/AsyncTCP @@ -95,7 +95,7 @@ lib_ignore = ## Performance -Performance of `mathieucarbou/ESPAsyncWebServer @ 3.3.15`: +Performance of `mathieucarbou/ESPAsyncWebServer @ 3.3.16`: ```bash > brew install autocannon diff --git a/docs/index.md b/docs/index.md index 00bb45b45..d45316a9c 100644 --- a/docs/index.md +++ b/docs/index.md @@ -61,7 +61,7 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo ```ini lib_compat_mode = strict lib_ldf_mode = chain -lib_deps = mathieucarbou/ESPAsyncWebServer @ 3.3.15 +lib_deps = mathieucarbou/ESPAsyncWebServer @ 3.3.16 ``` **Dependencies:** @@ -87,7 +87,7 @@ lib_ldf_mode = chain lib_deps = ; mathieucarbou/AsyncTCP @ 3.2.10 https://github.com/mathieucarbou/AsyncTCPSock/archive/refs/tags/v1.0.3-dev.zip - mathieucarbou/ESPAsyncWebServer @ 3.3.15 + mathieucarbou/ESPAsyncWebServer @ 3.3.16 lib_ignore = AsyncTCP mathieucarbou/AsyncTCP @@ -95,7 +95,7 @@ lib_ignore = ## Performance -Performance of `mathieucarbou/ESPAsyncWebServer @ 3.3.15`: +Performance of `mathieucarbou/ESPAsyncWebServer @ 3.3.16`: ```bash > brew install autocannon diff --git a/library.json b/library.json index 987dba178..63968f4a1 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "ESPAsyncWebServer", - "version": "3.3.15", + "version": "3.3.16", "description": "Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 and RP2040. Supports: WebSocket, SSE, Authentication, Arduino Json 7, File Upload, Static File serving, URL Rewrite, URL Redirect, etc.", "keywords": "http,async,websocket,webserver", "homepage": "https://github.com/mathieucarbou/ESPAsyncWebServer", diff --git a/library.properties b/library.properties index 31fdbb616..b712c1a1a 100644 --- a/library.properties +++ b/library.properties @@ -1,6 +1,6 @@ name=ESP Async WebServer includes=ESPAsyncWebServer.h -version=3.3.15 +version=3.3.16 author=Me-No-Dev maintainer=Mathieu Carbou sentence=Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 and RP2040 diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index 37c54de16..0474c7f78 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -48,10 +48,10 @@ #include "literals.h" -#define ASYNCWEBSERVER_VERSION "3.3.15" +#define ASYNCWEBSERVER_VERSION "3.3.16" #define ASYNCWEBSERVER_VERSION_MAJOR 3 #define ASYNCWEBSERVER_VERSION_MINOR 3 -#define ASYNCWEBSERVER_VERSION_REVISION 15 +#define ASYNCWEBSERVER_VERSION_REVISION 16 #define ASYNCWEBSERVER_FORK_mathieucarbou #ifdef ASYNCWEBSERVER_REGEX From d6ce30f2b79d9c3c02d9f0001421639eea741ad2 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Tue, 15 Oct 2024 11:22:07 +0200 Subject: [PATCH 440/551] update example --- examples/SimpleServer/SimpleServer.ino | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/examples/SimpleServer/SimpleServer.ino b/examples/SimpleServer/SimpleServer.ino index baf5f82c4..0f4256815 100644 --- a/examples/SimpleServer/SimpleServer.ino +++ b/examples/SimpleServer/SimpleServer.ino @@ -27,7 +27,7 @@ #include -const char* htmlContent = R"( +const char* htmlContent PROGMEM = R"( @@ -87,6 +87,8 @@ const char* htmlContent = R"( )"; +const size_t htmlContentLen = strlen_P(htmlContent); + AsyncWebServer server(80); AsyncEventSource events("/events"); AsyncWebSocket ws("/ws"); @@ -386,7 +388,7 @@ void setup() { // > brew install autocannon // > autocannon -c 10 -w 10 -d 20 http://192.168.4.1 server.on("/", HTTP_GET, [](AsyncWebServerRequest* request) { - request->send(200, "text/html", htmlContent); + request->send(200, "text/html", (uint8_t*)htmlContent, htmlContentLen); }); server.on("/file", HTTP_GET, [](AsyncWebServerRequest* request) { From 07788ecd088539140e1cf0fce8516f603043622e Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Tue, 15 Oct 2024 21:16:46 +0200 Subject: [PATCH 441/551] pio file update --- platformio.ini | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/platformio.ini b/platformio.ini index 1611a79c1..7a36c11b5 100644 --- a/platformio.ini +++ b/platformio.ini @@ -9,6 +9,7 @@ src_dir = examples/SimpleServer [env] framework = arduino build_flags = + -Og -Wall -Wextra -Wno-unused-parameter -D CONFIG_ARDUHAL_LOG_COLORS @@ -20,7 +21,8 @@ build_flags = -D CONFIG_ASYNC_TCP_STACK_SIZE=4096 upload_protocol = esptool monitor_speed = 115200 -monitor_filters = esp32_exception_decoder, log2file +; monitor_filters = esp32_exception_decoder, log2file +monitor_filters = esp8266_exception_decoder, log2file lib_deps = ; bblanchon/ArduinoJson @ 5.13.4 ; bblanchon/ArduinoJson @ 6.21.5 @@ -64,8 +66,8 @@ build_flags = ${env.build_flags} [env:esp8266] platform = espressif8266 -board = huzzah -; board = d1_mini +; board = huzzah +board = d1_mini lib_deps = bblanchon/ArduinoJson @ 7.2.0 esphome/ESPAsyncTCP-esphome @ 2.0.0 From 7fa622b3dc779ef8ba1bbd2046be79fba39deacd Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Tue, 15 Oct 2024 21:17:13 +0200 Subject: [PATCH 442/551] Revert "Fixed literals for ESP8266" This reverts commit 65906f7419442b7bd4764e9703f7401fd303e92d. --- src/literals.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/literals.h b/src/literals.h index fb2af7448..778e3dbc9 100644 --- a/src/literals.h +++ b/src/literals.h @@ -4,7 +4,7 @@ namespace asyncsrv { static constexpr const char* empty = ""; -#ifndef ESP8266 +#ifndef ESP8622 static constexpr const char* T__opaque = "\", opaque=\""; static constexpr const char* T_100_CONTINUE = "100-continue"; static constexpr const char* T_13 = "13"; @@ -180,7 +180,7 @@ static constexpr const char* T_HTTP_CODE_504 = "Gateway Time-out"; static constexpr const char* T_HTTP_CODE_505 = "HTTP Version not supported"; static constexpr const char* T_HTTP_CODE_ANY = "Unknown code"; -#else // ESP8266 +#else // ESP8622 static const char T__opaque[] PROGMEM = "\", opaque=\""; static const char T_100_CONTINUE[] PROGMEM = "100-continue"; @@ -356,6 +356,6 @@ static const char T_HTTP_CODE_504[] PROGMEM = "Gateway Time-out"; static const char T_HTTP_CODE_505[] PROGMEM = "HTTP Version not supported"; static const char T_HTTP_CODE_ANY[] PROGMEM = "Unknown code"; -#endif // ESP8266 +#endif // ESP8622 } // namespace asyncsrv {} From a4237ae5e4bb4b600ef3f010f77870829e51788f Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Tue, 15 Oct 2024 21:18:55 +0200 Subject: [PATCH 443/551] Wether 8266 or ESP32, `static constexpr const char*` ws used for literals --- src/literals.h | 535 ++++++++++++++++--------------------------------- 1 file changed, 178 insertions(+), 357 deletions(-) diff --git a/src/literals.h b/src/literals.h index 778e3dbc9..67823907b 100644 --- a/src/literals.h +++ b/src/literals.h @@ -2,360 +2,181 @@ namespace asyncsrv { -static constexpr const char* empty = ""; - -#ifndef ESP8622 -static constexpr const char* T__opaque = "\", opaque=\""; -static constexpr const char* T_100_CONTINUE = "100-continue"; -static constexpr const char* T_13 = "13"; -static constexpr const char* T_ACCEPT = "accept"; -static constexpr const char* T_Accept_Ranges = "accept-ranges"; -static constexpr const char* T_app_xform_urlencoded = "application/x-www-form-urlencoded"; -static constexpr const char* T_AUTH = "authorization"; -static constexpr const char* T_auth_nonce = "\", qop=\"auth\", nonce=\""; -static constexpr const char* T_BASIC = "basic"; -static constexpr const char* T_BASIC_REALM = "basic realm=\""; -static constexpr const char* T_BEARER = "bearer"; -static constexpr const char* T_BODY = "body"; -static constexpr const char* T_Cache_Control = "cache-control"; -static constexpr const char* T_chunked = "chunked"; -static constexpr const char* T_close = "close"; -static constexpr const char* T_cnonce = "cnonce"; -static constexpr const char* T_Connection = "connection"; -static constexpr const char* T_Content_Disposition = "content-disposition"; -static constexpr const char* T_Content_Encoding = "content-encoding"; -static constexpr const char* T_Content_Length = "content-length"; -static constexpr const char* T_Content_Type = "content-type"; -static constexpr const char* T_Cookie = "cookie"; -static constexpr const char* T_CORS_ACAC = "access-control-allow-credentials"; -static constexpr const char* T_CORS_ACAH = "access-control-allow-headers"; -static constexpr const char* T_CORS_ACAM = "access-control-allow-methods"; -static constexpr const char* T_CORS_ACAO = "access-control-allow-origin"; -static constexpr const char* T_CORS_ACMA = "access-control-max-age"; -static constexpr const char* T_CORS_O = "origin"; -static constexpr const char* T_data_ = "data: "; -static constexpr const char* T_DIGEST = "digest"; -static constexpr const char* T_DIGEST_ = "digest "; -static constexpr const char* T_ETag = "etag"; -static constexpr const char* T_event_ = "event: "; -static constexpr const char* T_EXPECT = "expect"; -static constexpr const char* T_FALSE = "false"; -static constexpr const char* T_filename = "filename"; -static constexpr const char* T_gzip = "gzip"; -static constexpr const char* T_Host = "host"; -static constexpr const char* T_HTTP_1_0 = "HTTP/1.0"; -static constexpr const char* T_HTTP_100_CONT = "HTTP/1.1 100 Continue\r\n\r\n"; -static constexpr const char* T_id__ = "id: "; -static constexpr const char* T_IMS = "if-modified-since"; -static constexpr const char* T_INM = "if-none-match"; -static constexpr const char* T_keep_alive = "keep-alive"; -static constexpr const char* T_Last_Event_ID = "last-event-id"; -static constexpr const char* T_Last_Modified = "last-modified"; -static constexpr const char* T_LOCATION = "location"; -static constexpr const char* T_LOGIN_REQ = "Login Required"; -static constexpr const char* T_MULTIPART_ = "multipart/"; -static constexpr const char* T_name = "name"; -static constexpr const char* T_nc = "nc"; -static constexpr const char* T_no_cache = "no-cache"; -static constexpr const char* T_nonce = "nonce"; -static constexpr const char* T_none = "none"; -static constexpr const char* T_opaque = "opaque"; -static constexpr const char* T_qop = "qop"; -static constexpr const char* T_realm = "realm"; -static constexpr const char* T_realm__ = "realm=\""; -static constexpr const char* T_response = "response"; -static constexpr const char* T_retry_ = "retry: "; -static constexpr const char* T_retry_after = "retry-after"; -static constexpr const char* T_rn = "\r\n"; -static constexpr const char* T_rnrn = "\r\n\r\n"; -static constexpr const char* T_Transfer_Encoding = "transfer-encoding"; -static constexpr const char* T_TRUE = "true"; -static constexpr const char* T_UPGRADE = "upgrade"; -static constexpr const char* T_uri = "uri"; -static constexpr const char* T_username = "username"; -static constexpr const char* T_WS = "websocket"; -static constexpr const char* T_WWW_AUTH = "www-authenticate"; - -// HTTP Methods - -static constexpr const char* T_ANY = "ANY"; -static constexpr const char* T_GET = "GET"; -static constexpr const char* T_POST = "POST"; -static constexpr const char* T_PUT = "PUT"; -static constexpr const char* T_DELETE = "DELETE"; -static constexpr const char* T_PATCH = "PATCH"; -static constexpr const char* T_HEAD = "HEAD"; -static constexpr const char* T_OPTIONS = "OPTIONS"; -static constexpr const char* T_UNKNOWN = "UNKNOWN"; - -// Req content types -static constexpr const char* T_RCT_NOT_USED = "RCT_NOT_USED"; -static constexpr const char* T_RCT_DEFAULT = "RCT_DEFAULT"; -static constexpr const char* T_RCT_HTTP = "RCT_HTTP"; -static constexpr const char* T_RCT_WS = "RCT_WS"; -static constexpr const char* T_RCT_EVENT = "RCT_EVENT"; -static constexpr const char* T_ERROR = "ERROR"; - -// extentions & MIME-Types -static constexpr const char* T__css = ".css"; -static constexpr const char* T__eot = ".eot"; -static constexpr const char* T__gif = ".gif"; -static constexpr const char* T__gz = ".gz"; -static constexpr const char* T__htm = ".htm"; -static constexpr const char* T__html = ".html"; -static constexpr const char* T__ico = ".ico"; -static constexpr const char* T__jpg = ".jpg"; -static constexpr const char* T__js = ".js"; -static constexpr const char* T__json = ".json"; -static constexpr const char* T__pdf = ".pdf"; -static constexpr const char* T__png = ".png"; -static constexpr const char* T__svg = ".svg"; -static constexpr const char* T__ttf = ".ttf"; -static constexpr const char* T__woff = ".woff"; -static constexpr const char* T__woff2 = ".woff2"; -static constexpr const char* T__xml = ".xml"; -static constexpr const char* T__zip = ".zip"; -static constexpr const char* T_application_javascript = "application/javascript"; -static constexpr const char* T_application_json = "application/json"; -static constexpr const char* T_application_msgpack = "application/msgpack"; -static constexpr const char* T_application_pdf = "application/pdf"; -static constexpr const char* T_application_x_gzip = "application/x-gzip"; -static constexpr const char* T_application_zip = "application/zip"; -static constexpr const char* T_font_eot = "font/eot"; -static constexpr const char* T_font_ttf = "font/ttf"; -static constexpr const char* T_font_woff = "font/woff"; -static constexpr const char* T_font_woff2 = "font/woff2"; -static constexpr const char* T_image_gif = "image/gif"; -static constexpr const char* T_image_jpeg = "image/jpeg"; -static constexpr const char* T_image_png = "image/png"; -static constexpr const char* T_image_svg_xml = "image/svg+xml"; -static constexpr const char* T_image_x_icon = "image/x-icon"; -static constexpr const char* T_text_css = "text/css"; -static constexpr const char* T_text_event_stream = "text/event-stream"; -static constexpr const char* T_text_html = "text/html"; -static constexpr const char* T_text_plain = "text/plain"; -static constexpr const char* T_text_xml = "text/xml"; - -// Responce codes -static constexpr const char* T_HTTP_CODE_100 = "Continue"; -static constexpr const char* T_HTTP_CODE_101 = "Switching Protocols"; -static constexpr const char* T_HTTP_CODE_200 = "OK"; -static constexpr const char* T_HTTP_CODE_201 = "Created"; -static constexpr const char* T_HTTP_CODE_202 = "Accepted"; -static constexpr const char* T_HTTP_CODE_203 = "Non-Authoritative Information"; -static constexpr const char* T_HTTP_CODE_204 = "No Content"; -static constexpr const char* T_HTTP_CODE_205 = "Reset Content"; -static constexpr const char* T_HTTP_CODE_206 = "Partial Content"; -static constexpr const char* T_HTTP_CODE_300 = "Multiple Choices"; -static constexpr const char* T_HTTP_CODE_301 = "Moved Permanently"; -static constexpr const char* T_HTTP_CODE_302 = "Found"; -static constexpr const char* T_HTTP_CODE_303 = "See Other"; -static constexpr const char* T_HTTP_CODE_304 = "Not Modified"; -static constexpr const char* T_HTTP_CODE_305 = "Use Proxy"; -static constexpr const char* T_HTTP_CODE_307 = "Temporary Redirect"; -static constexpr const char* T_HTTP_CODE_400 = "Bad Request"; -static constexpr const char* T_HTTP_CODE_401 = "Unauthorized"; -static constexpr const char* T_HTTP_CODE_402 = "Payment Required"; -static constexpr const char* T_HTTP_CODE_403 = "Forbidden"; -static constexpr const char* T_HTTP_CODE_404 = "Not Found"; -static constexpr const char* T_HTTP_CODE_405 = "Method Not Allowed"; -static constexpr const char* T_HTTP_CODE_406 = "Not Acceptable"; -static constexpr const char* T_HTTP_CODE_407 = "Proxy Authentication Required"; -static constexpr const char* T_HTTP_CODE_408 = "Request Time-out"; -static constexpr const char* T_HTTP_CODE_409 = "Conflict"; -static constexpr const char* T_HTTP_CODE_410 = "Gone"; -static constexpr const char* T_HTTP_CODE_411 = "Length Required"; -static constexpr const char* T_HTTP_CODE_412 = "Precondition Failed"; -static constexpr const char* T_HTTP_CODE_413 = "Request Entity Too Large"; -static constexpr const char* T_HTTP_CODE_414 = "Request-URI Too Large"; -static constexpr const char* T_HTTP_CODE_415 = "Unsupported Media Type"; -static constexpr const char* T_HTTP_CODE_416 = "Requested range not satisfiable"; -static constexpr const char* T_HTTP_CODE_417 = "Expectation Failed"; -static constexpr const char* T_HTTP_CODE_429 = "Too Many Requests"; -static constexpr const char* T_HTTP_CODE_500 = "Internal Server Error"; -static constexpr const char* T_HTTP_CODE_501 = "Not Implemented"; -static constexpr const char* T_HTTP_CODE_502 = "Bad Gateway"; -static constexpr const char* T_HTTP_CODE_503 = "Service Unavailable"; -static constexpr const char* T_HTTP_CODE_504 = "Gateway Time-out"; -static constexpr const char* T_HTTP_CODE_505 = "HTTP Version not supported"; -static constexpr const char* T_HTTP_CODE_ANY = "Unknown code"; - -#else // ESP8622 - -static const char T__opaque[] PROGMEM = "\", opaque=\""; -static const char T_100_CONTINUE[] PROGMEM = "100-continue"; -static const char T_13[] PROGMEM = "13"; -static const char T_Accept_Ranges[] PROGMEM = "accept-ranges"; -static const char T_ACCEPT[] PROGMEM = "accept"; -static const char T_app_xform_urlencoded[] PROGMEM = "application/x-www-form-urlencoded"; -static const char T_auth_nonce[] PROGMEM = "\", qop=\"auth\", nonce=\""; -static const char T_AUTH[] PROGMEM = "authorization"; -static const char T_BASIC_REALM[] PROGMEM = "basic realm=\""; -static const char T_BASIC[] PROGMEM = "basic"; -static const char T_BEARER[] PROGMEM = "bearer"; -static const char T_BODY[] PROGMEM = "body"; -static const char T_Cache_Control[] PROGMEM = "cache-control"; -static const char T_chunked[] PROGMEM = "chunked"; -static const char T_close[] PROGMEM = "close"; -static const char T_cnonce[] PROGMEM = "cnonce"; -static const char T_Connection[] PROGMEM = "connection"; -static const char T_Content_Disposition[] PROGMEM = "content-disposition"; -static const char T_Content_Encoding[] PROGMEM = "content-encoding"; -static const char T_Content_Length[] PROGMEM = "content-length"; -static const char T_Content_Type[] PROGMEM = "content-type"; -static const char T_Cookie[] PROGMEM = "cookie"; -static const char T_CORS_ACAC[] PROGMEM = "access-control-allow-credentials"; -static const char T_CORS_ACAH[] PROGMEM = "access-control-allow-headers"; -static const char T_CORS_ACAM[] PROGMEM = "access-control-allow-methods"; -static const char T_CORS_ACAO[] PROGMEM = "access-control-allow-origin"; -static const char T_CORS_ACMA[] PROGMEM = "access-control-max-age"; -static const char T_CORS_O[] PROGMEM = "origin"; -static const char T_data_[] PROGMEM = "data: "; -static const char T_DIGEST_[] PROGMEM = "digest "; -static const char T_DIGEST[] PROGMEM = "digest"; -static const char T_ETag[] PROGMEM = "etag"; -static const char T_event_[] PROGMEM = "event: "; -static const char T_EXPECT[] PROGMEM = "expect"; -static const char T_FALSE[] PROGMEM = "false"; -static const char T_filename[] PROGMEM = "filename"; -static const char T_gzip[] PROGMEM = "gzip"; -static const char T_Host[] PROGMEM = "host"; -static const char T_HTTP_1_0[] PROGMEM = "HTTP/1.0"; -static const char T_HTTP_100_CONT[] PROGMEM = "HTTP/1.1 100 Continue\r\n\r\n"; -static const char T_id__[] PROGMEM = "id: "; -static const char T_IMS[] PROGMEM = "if-modified-since"; -static const char T_INM[] PROGMEM = "if-none-match"; -static const char T_keep_alive[] PROGMEM = "keep-alive"; -static const char T_Last_Event_ID[] PROGMEM = "last-event-id"; -static const char T_Last_Modified[] PROGMEM = "last-modified"; -static const char T_LOCATION[] PROGMEM = "location"; -static const char T_LOGIN_REQ[] PROGMEM = "Login Required"; -static const char T_MULTIPART_[] PROGMEM = "multipart/"; -static const char T_name[] PROGMEM = "name"; -static const char T_nc[] PROGMEM = "nc"; -static const char T_no_cache[] PROGMEM = "no-cache"; -static const char T_nonce[] PROGMEM = "nonce"; -static const char T_none[] PROGMEM = "none"; -static const char T_opaque[] PROGMEM = "opaque"; -static const char T_qop[] PROGMEM = "qop"; -static const char T_realm__[] PROGMEM = "realm=\""; -static const char T_realm[] PROGMEM = "realm"; -static const char T_response[] PROGMEM = "response"; -static const char T_retry_[] PROGMEM = "retry: "; -static const char T_retry_after[] PROGMEM = "retry-after"; -static const char T_rn[] PROGMEM = "\r\n"; -static const char T_rnrn[] PROGMEM = "\r\n\r\n"; -static const char T_Transfer_Encoding[] PROGMEM = "transfer-encoding"; -static const char T_TRUE[] PROGMEM = "true"; -static const char T_UPGRADE[] PROGMEM = "upgrade"; -static const char T_uri[] PROGMEM = "uri"; -static const char T_username[] PROGMEM = "username"; -static const char T_WS[] PROGMEM = "websocket"; -static const char T_WWW_AUTH[] PROGMEM = "www-authenticate"; - -// HTTP Methods -static const char T_ANY[] PROGMEM = "ANY"; -static const char T_GET[] PROGMEM = "GET"; -static const char T_POST[] PROGMEM = "POST"; -static const char T_PUT[] PROGMEM = "PUT"; -static const char T_DELETE[] PROGMEM = "DELETE"; -static const char T_PATCH[] PROGMEM = "PATCH"; -static const char T_HEAD[] PROGMEM = "HEAD"; -static const char T_OPTIONS[] PROGMEM = "OPTIONS"; -static const char T_UNKNOWN[] PROGMEM = "UNKNOWN"; - -// Req content types -static const char T_RCT_NOT_USED[] PROGMEM = "RCT_NOT_USED"; -static const char T_RCT_DEFAULT[] PROGMEM = "RCT_DEFAULT"; -static const char T_RCT_HTTP[] PROGMEM = "RCT_HTTP"; -static const char T_RCT_WS[] PROGMEM = "RCT_WS"; -static const char T_RCT_EVENT[] PROGMEM = "RCT_EVENT"; -static const char T_ERROR[] PROGMEM = "ERROR"; - -// extentions & MIME-Types -static const char T__css[] PROGMEM = ".css"; -static const char T__eot[] PROGMEM = ".eot"; -static const char T__gif[] PROGMEM = ".gif"; -static const char T__gz[] PROGMEM = ".gz"; -static const char T__htm[] PROGMEM = ".htm"; -static const char T__html[] PROGMEM = ".html"; -static const char T__ico[] PROGMEM = ".ico"; -static const char T__jpg[] PROGMEM = ".jpg"; -static const char T__js[] PROGMEM = ".js"; -static const char T__json[] PROGMEM = ".json"; -static const char T__pdf[] PROGMEM = ".pdf"; -static const char T__png[] PROGMEM = ".png"; -static const char T__svg[] PROGMEM = ".svg"; -static const char T__ttf[] PROGMEM = ".ttf"; -static const char T__woff[] PROGMEM = ".woff"; -static const char T__woff2[] PROGMEM = ".woff2"; -static const char T__xml[] PROGMEM = ".xml"; -static const char T__zip[] PROGMEM = ".zip"; -static const char T_application_javascript[] PROGMEM = "application/javascript"; -static const char T_application_json[] PROGMEM = "application/json"; -static const char T_application_msgpack[] PROGMEM = "application/msgpack"; -static const char T_application_pdf[] PROGMEM = "application/pdf"; -static const char T_application_x_gzip[] PROGMEM = "application/x-gzip"; -static const char T_application_zip[] PROGMEM = "application/zip"; -static const char T_font_eot[] PROGMEM = "font/eot"; -static const char T_font_ttf[] PROGMEM = "font/ttf"; -static const char T_font_woff[] PROGMEM = "font/woff"; -static const char T_font_woff2[] PROGMEM = "font/woff2"; -static const char T_image_gif[] PROGMEM = "image/gif"; -static const char T_image_jpeg[] PROGMEM = "image/jpeg"; -static const char T_image_png[] PROGMEM = "image/png"; -static const char T_image_svg_xml[] PROGMEM = "image/svg+xml"; -static const char T_image_x_icon[] PROGMEM = "image/x-icon"; -static const char T_text_css[] PROGMEM = "text/css"; -static const char T_text_event_stream[] PROGMEM = "text/event-stream"; -static const char T_text_html[] PROGMEM = "text/html"; -static const char T_text_plain[] PROGMEM = "text/plain"; -static const char T_text_xml[] PROGMEM = "text/xml"; - -// Responce codes -static const char T_HTTP_CODE_100[] PROGMEM = "Continue"; -static const char T_HTTP_CODE_101[] PROGMEM = "Switching Protocols"; -static const char T_HTTP_CODE_200[] PROGMEM = "OK"; -static const char T_HTTP_CODE_201[] PROGMEM = "Created"; -static const char T_HTTP_CODE_202[] PROGMEM = "Accepted"; -static const char T_HTTP_CODE_203[] PROGMEM = "Non-Authoritative Information"; -static const char T_HTTP_CODE_204[] PROGMEM = "No Content"; -static const char T_HTTP_CODE_205[] PROGMEM = "Reset Content"; -static const char T_HTTP_CODE_206[] PROGMEM = "Partial Content"; -static const char T_HTTP_CODE_300[] PROGMEM = "Multiple Choices"; -static const char T_HTTP_CODE_301[] PROGMEM = "Moved Permanently"; -static const char T_HTTP_CODE_302[] PROGMEM = "Found"; -static const char T_HTTP_CODE_303[] PROGMEM = "See Other"; -static const char T_HTTP_CODE_304[] PROGMEM = "Not Modified"; -static const char T_HTTP_CODE_305[] PROGMEM = "Use Proxy"; -static const char T_HTTP_CODE_307[] PROGMEM = "Temporary Redirect"; -static const char T_HTTP_CODE_400[] PROGMEM = "Bad Request"; -static const char T_HTTP_CODE_401[] PROGMEM = "Unauthorized"; -static const char T_HTTP_CODE_402[] PROGMEM = "Payment Required"; -static const char T_HTTP_CODE_403[] PROGMEM = "Forbidden"; -static const char T_HTTP_CODE_404[] PROGMEM = "Not Found"; -static const char T_HTTP_CODE_405[] PROGMEM = "Method Not Allowed"; -static const char T_HTTP_CODE_406[] PROGMEM = "Not Acceptable"; -static const char T_HTTP_CODE_407[] PROGMEM = "Proxy Authentication Required"; -static const char T_HTTP_CODE_408[] PROGMEM = "Request Time-out"; -static const char T_HTTP_CODE_409[] PROGMEM = "Conflict"; -static const char T_HTTP_CODE_410[] PROGMEM = "Gone"; -static const char T_HTTP_CODE_411[] PROGMEM = "Length Required"; -static const char T_HTTP_CODE_412[] PROGMEM = "Precondition Failed"; -static const char T_HTTP_CODE_413[] PROGMEM = "Request Entity Too Large"; -static const char T_HTTP_CODE_414[] PROGMEM = "Request-URI Too Large"; -static const char T_HTTP_CODE_415[] PROGMEM = "Unsupported Media Type"; -static const char T_HTTP_CODE_416[] PROGMEM = "Requested range not satisfiable"; -static const char T_HTTP_CODE_417[] PROGMEM = "Expectation Failed"; -static const char T_HTTP_CODE_429[] PROGMEM = "Too Many Requests"; -static const char T_HTTP_CODE_500[] PROGMEM = "Internal Server Error"; -static const char T_HTTP_CODE_501[] PROGMEM = "Not Implemented"; -static const char T_HTTP_CODE_502[] PROGMEM = "Bad Gateway"; -static const char T_HTTP_CODE_503[] PROGMEM = "Service Unavailable"; -static const char T_HTTP_CODE_504[] PROGMEM = "Gateway Time-out"; -static const char T_HTTP_CODE_505[] PROGMEM = "HTTP Version not supported"; -static const char T_HTTP_CODE_ANY[] PROGMEM = "Unknown code"; - -#endif // ESP8622 - -} // namespace asyncsrv {} + static constexpr const char* empty = ""; + + static constexpr const char* T__opaque = "\", opaque=\""; + static constexpr const char* T_100_CONTINUE = "100-continue"; + static constexpr const char* T_13 = "13"; + static constexpr const char* T_ACCEPT = "accept"; + static constexpr const char* T_Accept_Ranges = "accept-ranges"; + static constexpr const char* T_app_xform_urlencoded = "application/x-www-form-urlencoded"; + static constexpr const char* T_AUTH = "authorization"; + static constexpr const char* T_auth_nonce = "\", qop=\"auth\", nonce=\""; + static constexpr const char* T_BASIC = "basic"; + static constexpr const char* T_BASIC_REALM = "basic realm=\""; + static constexpr const char* T_BEARER = "bearer"; + static constexpr const char* T_BODY = "body"; + static constexpr const char* T_Cache_Control = "cache-control"; + static constexpr const char* T_chunked = "chunked"; + static constexpr const char* T_close = "close"; + static constexpr const char* T_cnonce = "cnonce"; + static constexpr const char* T_Connection = "connection"; + static constexpr const char* T_Content_Disposition = "content-disposition"; + static constexpr const char* T_Content_Encoding = "content-encoding"; + static constexpr const char* T_Content_Length = "content-length"; + static constexpr const char* T_Content_Type = "content-type"; + static constexpr const char* T_Cookie = "cookie"; + static constexpr const char* T_CORS_ACAC = "access-control-allow-credentials"; + static constexpr const char* T_CORS_ACAH = "access-control-allow-headers"; + static constexpr const char* T_CORS_ACAM = "access-control-allow-methods"; + static constexpr const char* T_CORS_ACAO = "access-control-allow-origin"; + static constexpr const char* T_CORS_ACMA = "access-control-max-age"; + static constexpr const char* T_CORS_O = "origin"; + static constexpr const char* T_data_ = "data: "; + static constexpr const char* T_DIGEST = "digest"; + static constexpr const char* T_DIGEST_ = "digest "; + static constexpr const char* T_ETag = "etag"; + static constexpr const char* T_event_ = "event: "; + static constexpr const char* T_EXPECT = "expect"; + static constexpr const char* T_FALSE = "false"; + static constexpr const char* T_filename = "filename"; + static constexpr const char* T_gzip = "gzip"; + static constexpr const char* T_Host = "host"; + static constexpr const char* T_HTTP_1_0 = "HTTP/1.0"; + static constexpr const char* T_HTTP_100_CONT = "HTTP/1.1 100 Continue\r\n\r\n"; + static constexpr const char* T_id__ = "id: "; + static constexpr const char* T_IMS = "if-modified-since"; + static constexpr const char* T_INM = "if-none-match"; + static constexpr const char* T_keep_alive = "keep-alive"; + static constexpr const char* T_Last_Event_ID = "last-event-id"; + static constexpr const char* T_Last_Modified = "last-modified"; + static constexpr const char* T_LOCATION = "location"; + static constexpr const char* T_LOGIN_REQ = "Login Required"; + static constexpr const char* T_MULTIPART_ = "multipart/"; + static constexpr const char* T_name = "name"; + static constexpr const char* T_nc = "nc"; + static constexpr const char* T_no_cache = "no-cache"; + static constexpr const char* T_nonce = "nonce"; + static constexpr const char* T_none = "none"; + static constexpr const char* T_opaque = "opaque"; + static constexpr const char* T_qop = "qop"; + static constexpr const char* T_realm = "realm"; + static constexpr const char* T_realm__ = "realm=\""; + static constexpr const char* T_response = "response"; + static constexpr const char* T_retry_ = "retry: "; + static constexpr const char* T_retry_after = "retry-after"; + static constexpr const char* T_rn = "\r\n"; + static constexpr const char* T_rnrn = "\r\n\r\n"; + static constexpr const char* T_Transfer_Encoding = "transfer-encoding"; + static constexpr const char* T_TRUE = "true"; + static constexpr const char* T_UPGRADE = "upgrade"; + static constexpr const char* T_uri = "uri"; + static constexpr const char* T_username = "username"; + static constexpr const char* T_WS = "websocket"; + static constexpr const char* T_WWW_AUTH = "www-authenticate"; + + // HTTP Methods + + static constexpr const char* T_ANY = "ANY"; + static constexpr const char* T_GET = "GET"; + static constexpr const char* T_POST = "POST"; + static constexpr const char* T_PUT = "PUT"; + static constexpr const char* T_DELETE = "DELETE"; + static constexpr const char* T_PATCH = "PATCH"; + static constexpr const char* T_HEAD = "HEAD"; + static constexpr const char* T_OPTIONS = "OPTIONS"; + static constexpr const char* T_UNKNOWN = "UNKNOWN"; + + // Req content types + static constexpr const char* T_RCT_NOT_USED = "RCT_NOT_USED"; + static constexpr const char* T_RCT_DEFAULT = "RCT_DEFAULT"; + static constexpr const char* T_RCT_HTTP = "RCT_HTTP"; + static constexpr const char* T_RCT_WS = "RCT_WS"; + static constexpr const char* T_RCT_EVENT = "RCT_EVENT"; + static constexpr const char* T_ERROR = "ERROR"; + + // extentions & MIME-Types + static constexpr const char* T__css = ".css"; + static constexpr const char* T__eot = ".eot"; + static constexpr const char* T__gif = ".gif"; + static constexpr const char* T__gz = ".gz"; + static constexpr const char* T__htm = ".htm"; + static constexpr const char* T__html = ".html"; + static constexpr const char* T__ico = ".ico"; + static constexpr const char* T__jpg = ".jpg"; + static constexpr const char* T__js = ".js"; + static constexpr const char* T__json = ".json"; + static constexpr const char* T__pdf = ".pdf"; + static constexpr const char* T__png = ".png"; + static constexpr const char* T__svg = ".svg"; + static constexpr const char* T__ttf = ".ttf"; + static constexpr const char* T__woff = ".woff"; + static constexpr const char* T__woff2 = ".woff2"; + static constexpr const char* T__xml = ".xml"; + static constexpr const char* T__zip = ".zip"; + static constexpr const char* T_application_javascript = "application/javascript"; + static constexpr const char* T_application_json = "application/json"; + static constexpr const char* T_application_msgpack = "application/msgpack"; + static constexpr const char* T_application_pdf = "application/pdf"; + static constexpr const char* T_application_x_gzip = "application/x-gzip"; + static constexpr const char* T_application_zip = "application/zip"; + static constexpr const char* T_font_eot = "font/eot"; + static constexpr const char* T_font_ttf = "font/ttf"; + static constexpr const char* T_font_woff = "font/woff"; + static constexpr const char* T_font_woff2 = "font/woff2"; + static constexpr const char* T_image_gif = "image/gif"; + static constexpr const char* T_image_jpeg = "image/jpeg"; + static constexpr const char* T_image_png = "image/png"; + static constexpr const char* T_image_svg_xml = "image/svg+xml"; + static constexpr const char* T_image_x_icon = "image/x-icon"; + static constexpr const char* T_text_css = "text/css"; + static constexpr const char* T_text_event_stream = "text/event-stream"; + static constexpr const char* T_text_html = "text/html"; + static constexpr const char* T_text_plain = "text/plain"; + static constexpr const char* T_text_xml = "text/xml"; + + // Responce codes + static constexpr const char* T_HTTP_CODE_100 = "Continue"; + static constexpr const char* T_HTTP_CODE_101 = "Switching Protocols"; + static constexpr const char* T_HTTP_CODE_200 = "OK"; + static constexpr const char* T_HTTP_CODE_201 = "Created"; + static constexpr const char* T_HTTP_CODE_202 = "Accepted"; + static constexpr const char* T_HTTP_CODE_203 = "Non-Authoritative Information"; + static constexpr const char* T_HTTP_CODE_204 = "No Content"; + static constexpr const char* T_HTTP_CODE_205 = "Reset Content"; + static constexpr const char* T_HTTP_CODE_206 = "Partial Content"; + static constexpr const char* T_HTTP_CODE_300 = "Multiple Choices"; + static constexpr const char* T_HTTP_CODE_301 = "Moved Permanently"; + static constexpr const char* T_HTTP_CODE_302 = "Found"; + static constexpr const char* T_HTTP_CODE_303 = "See Other"; + static constexpr const char* T_HTTP_CODE_304 = "Not Modified"; + static constexpr const char* T_HTTP_CODE_305 = "Use Proxy"; + static constexpr const char* T_HTTP_CODE_307 = "Temporary Redirect"; + static constexpr const char* T_HTTP_CODE_400 = "Bad Request"; + static constexpr const char* T_HTTP_CODE_401 = "Unauthorized"; + static constexpr const char* T_HTTP_CODE_402 = "Payment Required"; + static constexpr const char* T_HTTP_CODE_403 = "Forbidden"; + static constexpr const char* T_HTTP_CODE_404 = "Not Found"; + static constexpr const char* T_HTTP_CODE_405 = "Method Not Allowed"; + static constexpr const char* T_HTTP_CODE_406 = "Not Acceptable"; + static constexpr const char* T_HTTP_CODE_407 = "Proxy Authentication Required"; + static constexpr const char* T_HTTP_CODE_408 = "Request Time-out"; + static constexpr const char* T_HTTP_CODE_409 = "Conflict"; + static constexpr const char* T_HTTP_CODE_410 = "Gone"; + static constexpr const char* T_HTTP_CODE_411 = "Length Required"; + static constexpr const char* T_HTTP_CODE_412 = "Precondition Failed"; + static constexpr const char* T_HTTP_CODE_413 = "Request Entity Too Large"; + static constexpr const char* T_HTTP_CODE_414 = "Request-URI Too Large"; + static constexpr const char* T_HTTP_CODE_415 = "Unsupported Media Type"; + static constexpr const char* T_HTTP_CODE_416 = "Requested range not satisfiable"; + static constexpr const char* T_HTTP_CODE_417 = "Expectation Failed"; + static constexpr const char* T_HTTP_CODE_429 = "Too Many Requests"; + static constexpr const char* T_HTTP_CODE_500 = "Internal Server Error"; + static constexpr const char* T_HTTP_CODE_501 = "Not Implemented"; + static constexpr const char* T_HTTP_CODE_502 = "Bad Gateway"; + static constexpr const char* T_HTTP_CODE_503 = "Service Unavailable"; + static constexpr const char* T_HTTP_CODE_504 = "Gateway Time-out"; + static constexpr const char* T_HTTP_CODE_505 = "HTTP Version not supported"; + static constexpr const char* T_HTTP_CODE_ANY = "Unknown code"; + +} // namespace asyncsrv {} From 58c4c64dfdeca80f3bbd04d9ffb772a4b9911cae Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Tue, 15 Oct 2024 21:22:52 +0200 Subject: [PATCH 444/551] update example --- examples/SimpleServer/SimpleServer.ino | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/examples/SimpleServer/SimpleServer.ino b/examples/SimpleServer/SimpleServer.ino index 0f4256815..2c934ea68 100644 --- a/examples/SimpleServer/SimpleServer.ino +++ b/examples/SimpleServer/SimpleServer.ino @@ -87,8 +87,6 @@ const char* htmlContent PROGMEM = R"( )"; -const size_t htmlContentLen = strlen_P(htmlContent); - AsyncWebServer server(80); AsyncEventSource events("/events"); AsyncWebSocket ws("/ws"); @@ -388,7 +386,7 @@ void setup() { // > brew install autocannon // > autocannon -c 10 -w 10 -d 20 http://192.168.4.1 server.on("/", HTTP_GET, [](AsyncWebServerRequest* request) { - request->send(200, "text/html", (uint8_t*)htmlContent, htmlContentLen); + request->send(200, "text/html", htmlContent); }); server.on("/file", HTTP_GET, [](AsyncWebServerRequest* request) { @@ -579,7 +577,6 @@ void loop() { } if (now - lastWS >= deltaWS) { ws.printfAll("kp%.4f", (10.0 / 3.0)); - // ws.getClients for (auto& client : ws.getClients()) { client.printf("kp%.4f", (10.0 / 3.0)); } From cb4b4de36acd6abd04cf072c8b5b200e448e6054 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Tue, 15 Oct 2024 21:33:22 +0200 Subject: [PATCH 445/551] v3.3.17 --- README.md | 6 +++--- docs/index.md | 6 +++--- library.json | 2 +- library.properties | 2 +- src/ESPAsyncWebServer.h | 4 ++-- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index d45316a9c..460daba58 100644 --- a/README.md +++ b/README.md @@ -61,7 +61,7 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo ```ini lib_compat_mode = strict lib_ldf_mode = chain -lib_deps = mathieucarbou/ESPAsyncWebServer @ 3.3.16 +lib_deps = mathieucarbou/ESPAsyncWebServer @ 3.3.17 ``` **Dependencies:** @@ -87,7 +87,7 @@ lib_ldf_mode = chain lib_deps = ; mathieucarbou/AsyncTCP @ 3.2.10 https://github.com/mathieucarbou/AsyncTCPSock/archive/refs/tags/v1.0.3-dev.zip - mathieucarbou/ESPAsyncWebServer @ 3.3.16 + mathieucarbou/ESPAsyncWebServer @ 3.3.17 lib_ignore = AsyncTCP mathieucarbou/AsyncTCP @@ -95,7 +95,7 @@ lib_ignore = ## Performance -Performance of `mathieucarbou/ESPAsyncWebServer @ 3.3.16`: +Performance of `mathieucarbou/ESPAsyncWebServer @ 3.3.17`: ```bash > brew install autocannon diff --git a/docs/index.md b/docs/index.md index d45316a9c..460daba58 100644 --- a/docs/index.md +++ b/docs/index.md @@ -61,7 +61,7 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo ```ini lib_compat_mode = strict lib_ldf_mode = chain -lib_deps = mathieucarbou/ESPAsyncWebServer @ 3.3.16 +lib_deps = mathieucarbou/ESPAsyncWebServer @ 3.3.17 ``` **Dependencies:** @@ -87,7 +87,7 @@ lib_ldf_mode = chain lib_deps = ; mathieucarbou/AsyncTCP @ 3.2.10 https://github.com/mathieucarbou/AsyncTCPSock/archive/refs/tags/v1.0.3-dev.zip - mathieucarbou/ESPAsyncWebServer @ 3.3.16 + mathieucarbou/ESPAsyncWebServer @ 3.3.17 lib_ignore = AsyncTCP mathieucarbou/AsyncTCP @@ -95,7 +95,7 @@ lib_ignore = ## Performance -Performance of `mathieucarbou/ESPAsyncWebServer @ 3.3.16`: +Performance of `mathieucarbou/ESPAsyncWebServer @ 3.3.17`: ```bash > brew install autocannon diff --git a/library.json b/library.json index 63968f4a1..03b800d5a 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "ESPAsyncWebServer", - "version": "3.3.16", + "version": "3.3.17", "description": "Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 and RP2040. Supports: WebSocket, SSE, Authentication, Arduino Json 7, File Upload, Static File serving, URL Rewrite, URL Redirect, etc.", "keywords": "http,async,websocket,webserver", "homepage": "https://github.com/mathieucarbou/ESPAsyncWebServer", diff --git a/library.properties b/library.properties index b712c1a1a..d16d77e0b 100644 --- a/library.properties +++ b/library.properties @@ -1,6 +1,6 @@ name=ESP Async WebServer includes=ESPAsyncWebServer.h -version=3.3.16 +version=3.3.17 author=Me-No-Dev maintainer=Mathieu Carbou sentence=Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 and RP2040 diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index 0474c7f78..be4741f1f 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -48,10 +48,10 @@ #include "literals.h" -#define ASYNCWEBSERVER_VERSION "3.3.16" +#define ASYNCWEBSERVER_VERSION "3.3.17" #define ASYNCWEBSERVER_VERSION_MAJOR 3 #define ASYNCWEBSERVER_VERSION_MINOR 3 -#define ASYNCWEBSERVER_VERSION_REVISION 16 +#define ASYNCWEBSERVER_VERSION_REVISION 17 #define ASYNCWEBSERVER_FORK_mathieucarbou #ifdef ASYNCWEBSERVER_REGEX From 7923d93336a40a31fb2028fcaa2216f975b1bacf Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Wed, 16 Oct 2024 11:52:34 +0200 Subject: [PATCH 446/551] Added test case --- examples/Issue85/Issue85.ino | 108 +++++++++++++++++++++++++++++++++++ platformio.ini | 3 +- 2 files changed, 110 insertions(+), 1 deletion(-) create mode 100644 examples/Issue85/Issue85.ino diff --git a/examples/Issue85/Issue85.ino b/examples/Issue85/Issue85.ino new file mode 100644 index 000000000..3aac35fb9 --- /dev/null +++ b/examples/Issue85/Issue85.ino @@ -0,0 +1,108 @@ +#include +#ifdef ESP8266 + #include +#endif +#ifdef ESP32 + #include +#endif +#include + +void connect_wifi() { + WiFi.mode(WIFI_AP); + WiFi.softAP("esp-captive"); + + // Serial.print("Connecting"); + // while (WiFi.status() != WL_CONNECTED) { + // delay(500); + // Serial.print("."); + // } + // Serial.println(); + + // Serial.print("Connected, IP address: "); + // Serial.println(WiFi.localIP()); +} + +void notFound(AsyncWebServerRequest* request) { + request->send(404, "text/plain", "Not found"); +} + +AsyncWebServer server(80); +AsyncWebSocket ws("/ws"); + +// initial stack +char* stack_start; + +void printStackSize() { + char stack; + Serial.print(F("stack size ")); + Serial.print(stack_start - &stack); + Serial.print(F(" | Heap free:")); + Serial.print(ESP.getFreeHeap()); +#ifdef ESP8266 + Serial.print(F(" frag:")); + Serial.print(ESP.getHeapFragmentation()); + Serial.print(F(" maxFreeBlock:")); + Serial.print(ESP.getMaxFreeBlockSize()); +#endif + Serial.println(); +} + +void onWsEventEmpty(AsyncWebSocket* server, AsyncWebSocketClient* client, AwsEventType type, void* arg, uint8_t* data, size_t len) { + printStackSize(); + // Just answer + client->text("PONGTEST"); +} + +void serve_upload(AsyncWebServerRequest* request, const String& filename, size_t index, uint8_t* data, size_t len, bool final) { + Serial.print("> onUpload "); + Serial.print("index: "); + Serial.print(index); + Serial.print(" len:"); + Serial.print(len); + Serial.print(" final:"); + Serial.print(final); + Serial.println(); +} + +void setup() { + char stack; + stack_start = &stack; + + Serial.begin(115200); + Serial.println("\n\n\nStart"); + Serial.printf("stack_start: %p\n", stack_start); + + connect_wifi(); + + server.onNotFound(notFound); + + ws.onEvent(onWsEventEmpty); + server.addHandler(&ws); + + server.on("/upload", HTTP_POST, [](AsyncWebServerRequest* request) { request->send(200); }, serve_upload); + + server.begin(); + Serial.println("Server started"); +} + +String msg = ""; +uint32_t count = 0; +void loop() { + + ws.cleanupClients(); + + count += 1; + + // Concatenate some string, and clear it after some time + static unsigned long millis_string = millis(); + if (millis() - millis_string > 1) { + millis_string += 100; + if (count % 100 == 0) { + // printStackSize(); + // Serial.print(msg); + msg = String(); + } else { + msg += 'T'; + } + } +} \ No newline at end of file diff --git a/platformio.ini b/platformio.ini index 7a36c11b5..2fd60e728 100644 --- a/platformio.ini +++ b/platformio.ini @@ -2,9 +2,10 @@ default_envs = arduino-2, arduino-3, arduino-310rc1, esp8266, raspberrypi lib_dir = . ; src_dir = examples/CaptivePortal -src_dir = examples/SimpleServer +; src_dir = examples/SimpleServer ; src_dir = examples/StreamFiles ; src_dir = examples/Filters +src_dir = examples/Issue85 [env] framework = arduino From 5aba428151f8e184791a0e65963abe57942a789f Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Wed, 16 Oct 2024 22:21:29 +0200 Subject: [PATCH 447/551] Update example --- examples/Issue85/Issue85.ino | 57 ++++++++++++++++++++++++------------ 1 file changed, 38 insertions(+), 19 deletions(-) diff --git a/examples/Issue85/Issue85.ino b/examples/Issue85/Issue85.ino index 3aac35fb9..fa2aa5547 100644 --- a/examples/Issue85/Issue85.ino +++ b/examples/Issue85/Issue85.ino @@ -1,3 +1,10 @@ +/** + * + * Connect to AP and run in bash: + * + * > while true; do echo "PING"; sleep 0.1; done | websocat ws://192.168.4.1/ws + * + */ #include #ifdef ESP8266 #include @@ -7,6 +14,12 @@ #endif #include +#include + +size_t msgCount = 0; +size_t window = 100; +std::list times; + void connect_wifi() { WiFi.mode(WIFI_AP); WiFi.softAP("esp-captive"); @@ -48,9 +61,18 @@ void printStackSize() { } void onWsEventEmpty(AsyncWebSocket* server, AsyncWebSocketClient* client, AwsEventType type, void* arg, uint8_t* data, size_t len) { + msgCount++; + Serial.printf("count: %d\n", msgCount); + + times.push_back(millis()); + while (times.size() > window) + times.pop_front(); + if (times.size() == window) + Serial.printf("%f req/s\n", 1000.0 * window / (times.back() - times.front())); + printStackSize(); - // Just answer - client->text("PONGTEST"); + + client->text("PONG"); } void serve_upload(AsyncWebServerRequest* request, const String& filename, size_t index, uint8_t* data, size_t len, bool final) { @@ -88,21 +110,18 @@ void setup() { String msg = ""; uint32_t count = 0; void loop() { - - ws.cleanupClients(); - - count += 1; - - // Concatenate some string, and clear it after some time - static unsigned long millis_string = millis(); - if (millis() - millis_string > 1) { - millis_string += 100; - if (count % 100 == 0) { - // printStackSize(); - // Serial.print(msg); - msg = String(); - } else { - msg += 'T'; - } - } + // ws.cleanupClients(); + // count += 1; + // // Concatenate some string, and clear it after some time + // static unsigned long millis_string = millis(); + // if (millis() - millis_string > 1) { + // millis_string += 100; + // if (count % 100 == 0) { + // // printStackSize(); + // // Serial.print(msg); + // msg = String(); + // } else { + // msg += 'T'; + // } + // } } \ No newline at end of file From 4603a1ecbfa3b821f4d9204bea6a387b18ab76d3 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Wed, 16 Oct 2024 22:51:08 +0200 Subject: [PATCH 448/551] updated templates --- .github/ISSUE_TEMPLATE/bug_report.md | 6 ++++-- .github/ISSUE_TEMPLATE/question.md | 4 +++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 19fe4793f..881310788 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -1,11 +1,13 @@ --- name: Bug report -about: Create a report to help us improve +about: Only for bugs founds in the library! Otherwise, please go to the discussions section! title: "[BUG]" labels: triage assignees: "" --- +**Only for bugs found in the library! Otherwise, please go to the [discussions section](https://github.com/mathieucarbou/ESPAsyncWebServer/discussions)!** + **Please make sure to go through the recommendations before opening a bug report:** [https://github.com/mathieucarbou/ESPAsyncWebServer?tab=readme-ov-file#important-recommendations](https://github.com/mathieucarbou/ESPAsyncWebServer?tab=readme-ov-file#important-recommendations) @@ -22,7 +24,7 @@ _A clear and concise description of what the bug is._ **Stack trace** -Please provide the stack trace here taken with `monitor_filters = esp32_exception_decoder`. +Please provide a **decoded stack trace** taken with `monitor_filters = esp32_exception_decoder`. **Any issue opened with a non readable stack trace will be ignored because not helpful at all.** As an alternative, you can use [https://maximeborges.github.io/esp-stacktrace-decoder/](https://maximeborges.github.io/esp-stacktrace-decoder/). diff --git a/.github/ISSUE_TEMPLATE/question.md b/.github/ISSUE_TEMPLATE/question.md index 7f628456b..a0f41e515 100644 --- a/.github/ISSUE_TEMPLATE/question.md +++ b/.github/ISSUE_TEMPLATE/question.md @@ -1,7 +1,9 @@ --- name: Question -about: Describe your question +about: "For questions: please go to the discussions section!" title: "[Q]" labels: question assignees: "" --- + +**For questions: please go to the [discussions section](https://github.com/mathieucarbou/ESPAsyncWebServer/discussions)!** \ No newline at end of file From ab682fd8387374dfa6f47c870b3961f9f8e96bc9 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Wed, 23 Oct 2024 10:13:10 +0200 Subject: [PATCH 449/551] Code cleanup: adding missing const keyword --- src/AsyncEventSource.cpp | 6 +++--- src/AsyncEventSource.h | 2 +- src/AsyncJson.cpp | 2 +- src/AsyncJson.h | 4 ++-- src/AsyncMessagePack.cpp | 2 +- src/AsyncMessagePack.h | 4 ++-- src/AsyncWebSocket.cpp | 2 +- src/AsyncWebSocket.h | 2 +- src/ESPAsyncWebServer.h | 18 +++++++++--------- src/Middleware.cpp | 2 +- src/WebHandlerImpl.h | 8 ++++---- src/WebHandlers.cpp | 10 +++++----- src/WebRequest.cpp | 17 ++++++----------- 13 files changed, 37 insertions(+), 42 deletions(-) diff --git a/src/AsyncEventSource.cpp b/src/AsyncEventSource.cpp index 5e028fa20..2d81dbcb9 100644 --- a/src/AsyncEventSource.cpp +++ b/src/AsyncEventSource.cpp @@ -141,7 +141,7 @@ size_t AsyncEventSourceMessage::ack(size_t len, __attribute__((unused)) uint32_t } size_t AsyncEventSourceMessage::write(AsyncClient* client) { - if(!client) + if (!client) return 0; if (_sent >= _len || !client->canSend()) { @@ -270,7 +270,7 @@ size_t AsyncEventSourceClient::packetsWaiting() const { } void AsyncEventSourceClient::_runQueue() { - if(!_client) + if (!_client) return; size_t total_bytes_written = 0; @@ -385,7 +385,7 @@ size_t AsyncEventSource::count() const { return n_clients; } -bool AsyncEventSource::canHandle(AsyncWebServerRequest* request) { +bool AsyncEventSource::canHandle(AsyncWebServerRequest* request) const { if (request->method() != HTTP_GET || !request->url().equals(_url)) { return false; } diff --git a/src/AsyncEventSource.h b/src/AsyncEventSource.h index b0bd24967..35ae31999 100644 --- a/src/AsyncEventSource.h +++ b/src/AsyncEventSource.h @@ -143,7 +143,7 @@ class AsyncEventSource : public AsyncWebHandler { // system callbacks (do not call) void _addClient(AsyncEventSourceClient* client); void _handleDisconnect(AsyncEventSourceClient* client); - virtual bool canHandle(AsyncWebServerRequest* request) override final; + virtual bool canHandle(AsyncWebServerRequest* request) const override final; virtual void handleRequest(AsyncWebServerRequest* request) override final; }; diff --git a/src/AsyncJson.cpp b/src/AsyncJson.cpp index 7117a707e..ee69f91f3 100644 --- a/src/AsyncJson.cpp +++ b/src/AsyncJson.cpp @@ -89,7 +89,7 @@ AsyncCallbackJsonWebHandler::AsyncCallbackJsonWebHandler(const String& uri, ArJs : _uri(uri), _method(HTTP_GET | HTTP_POST | HTTP_PUT | HTTP_PATCH), _onRequest(onRequest), _maxContentLength(16384) {} #endif -bool AsyncCallbackJsonWebHandler::canHandle(AsyncWebServerRequest* request) { +bool AsyncCallbackJsonWebHandler::canHandle(AsyncWebServerRequest* request) const { if (!_onRequest) return false; diff --git a/src/AsyncJson.h b/src/AsyncJson.h index 167364a69..a3db8b62b 100644 --- a/src/AsyncJson.h +++ b/src/AsyncJson.h @@ -119,11 +119,11 @@ class AsyncCallbackJsonWebHandler : public AsyncWebHandler { void setMaxContentLength(int maxContentLength) { _maxContentLength = maxContentLength; } void onRequest(ArJsonRequestHandlerFunction fn) { _onRequest = fn; } - virtual bool canHandle(AsyncWebServerRequest* request) override final; + virtual bool canHandle(AsyncWebServerRequest* request) const override final; virtual void handleRequest(AsyncWebServerRequest* request) override final; virtual void handleUpload(__unused AsyncWebServerRequest* request, __unused const String& filename, __unused size_t index, __unused uint8_t* data, __unused size_t len, __unused bool final) override final {} virtual void handleBody(AsyncWebServerRequest* request, uint8_t* data, size_t len, size_t index, size_t total) override final; - virtual bool isRequestHandlerTrivial() override final { return !_onRequest; } + virtual bool isRequestHandlerTrivial() const override final { return !_onRequest; } }; #endif // ASYNC_JSON_SUPPORT == 1 diff --git a/src/AsyncMessagePack.cpp b/src/AsyncMessagePack.cpp index 076f55867..db995ed7a 100644 --- a/src/AsyncMessagePack.cpp +++ b/src/AsyncMessagePack.cpp @@ -44,7 +44,7 @@ AsyncCallbackMessagePackWebHandler::AsyncCallbackMessagePackWebHandler(const Str : _uri(uri), _method(HTTP_GET | HTTP_POST | HTTP_PUT | HTTP_PATCH), _onRequest(onRequest), _maxContentLength(16384) {} #endif -bool AsyncCallbackMessagePackWebHandler::canHandle(AsyncWebServerRequest* request) { +bool AsyncCallbackMessagePackWebHandler::canHandle(AsyncWebServerRequest* request) const { if (!_onRequest) return false; diff --git a/src/AsyncMessagePack.h b/src/AsyncMessagePack.h index 9ac5ee5c8..210e0a62c 100644 --- a/src/AsyncMessagePack.h +++ b/src/AsyncMessagePack.h @@ -92,11 +92,11 @@ class AsyncCallbackMessagePackWebHandler : public AsyncWebHandler { void setMaxContentLength(int maxContentLength) { _maxContentLength = maxContentLength; } void onRequest(ArMessagePackRequestHandlerFunction fn) { _onRequest = fn; } - virtual bool canHandle(AsyncWebServerRequest* request) override final; + virtual bool canHandle(AsyncWebServerRequest* request) const override final; virtual void handleRequest(AsyncWebServerRequest* request) override final; virtual void handleUpload(__unused AsyncWebServerRequest* request, __unused const String& filename, __unused size_t index, __unused uint8_t* data, __unused size_t len, __unused bool final) override final {} virtual void handleBody(AsyncWebServerRequest* request, uint8_t* data, size_t len, size_t index, size_t total) override final; - virtual bool isRequestHandlerTrivial() override final { return !_onRequest; } + virtual bool isRequestHandlerTrivial() const override final { return !_onRequest; } }; #endif // ASYNC_MSG_PACK_SUPPORT == 1 diff --git a/src/AsyncWebSocket.cpp b/src/AsyncWebSocket.cpp index 8dd624443..0bb40e4a2 100644 --- a/src/AsyncWebSocket.cpp +++ b/src/AsyncWebSocket.cpp @@ -1121,7 +1121,7 @@ const char __WS_STR_UUID[] PROGMEM = {"258EAFA5-E914-47DA-95CA-C5AB0DC85B11"}; #define WS_STR_ACCEPT FPSTR(__WS_STR_ACCEPT) #define WS_STR_UUID FPSTR(__WS_STR_UUID) -bool AsyncWebSocket::canHandle(AsyncWebServerRequest* request) { +bool AsyncWebSocket::canHandle(AsyncWebServerRequest* request) const { if (!_enabled) return false; diff --git a/src/AsyncWebSocket.h b/src/AsyncWebSocket.h index f489aca29..5f134b951 100644 --- a/src/AsyncWebSocket.h +++ b/src/AsyncWebSocket.h @@ -350,7 +350,7 @@ class AsyncWebSocket : public AsyncWebHandler { uint32_t _getNextId() { return _cNextId++; } AsyncWebSocketClient* _newClient(AsyncWebServerRequest* request); void _handleEvent(AsyncWebSocketClient* client, AwsEventType type, void* arg, uint8_t* data, size_t len); - virtual bool canHandle(AsyncWebServerRequest* request) override final; + virtual bool canHandle(AsyncWebServerRequest* request) const override final; virtual void handleRequest(AsyncWebServerRequest* request) override final; // messagebuffer functions/objects. diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index be4741f1f..538fd1122 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -274,14 +274,14 @@ class AsyncWebServerRequest { #endif RequestedConnectionType requestedConnType() const { return _reqconntype; } - bool isExpectedRequestedConnType(RequestedConnectionType erct1, RequestedConnectionType erct2 = RCT_NOT_USED, RequestedConnectionType erct3 = RCT_NOT_USED); + bool isExpectedRequestedConnType(RequestedConnectionType erct1, RequestedConnectionType erct2 = RCT_NOT_USED, RequestedConnectionType erct3 = RCT_NOT_USED) const; void onDisconnect(ArDisconnectHandler fn); // hash is the string representation of: // base64(user:pass) for basic or // user:realm:md5(user:realm:pass) for digest - bool authenticate(const char* hash); - bool authenticate(const char* username, const char* credentials, const char* realm = NULL, bool isHash = false); + bool authenticate(const char* hash) const; + bool authenticate(const char* username, const char* credentials, const char* realm = NULL, bool isHash = false) const; void requestAuthentication(const char* realm = nullptr, bool isDigest = true) { requestAuthentication(isDigest ? AsyncAuthType::AUTH_DIGEST : AsyncAuthType::AUTH_BASIC, realm); } void requestAuthentication(AsyncAuthType method, const char* realm = nullptr, const char* _authFailMsg = nullptr); @@ -588,9 +588,9 @@ class AuthenticationMiddleware : public AsyncMiddleware { bool generateHash(); // returns true if the username and password (or hash) are set - bool hasCredentials() { return _hasCreds; } + bool hasCredentials() const { return _hasCreds; } - bool allowed(AsyncWebServerRequest* request); + bool allowed(AsyncWebServerRequest* request) const; void run(AsyncWebServerRequest* request, ArMiddlewareNext next); @@ -648,7 +648,7 @@ class LoggingMiddleware : public AsyncMiddleware { public: void setOutput(Print& output) { _out = &output; } void setEnabled(bool enabled) { _enabled = enabled; } - bool isEnabled() { return _enabled && _out; } + bool isEnabled() const { return _enabled && _out; } void run(AsyncWebServerRequest* request, ArMiddlewareNext next); @@ -722,7 +722,7 @@ class AsyncWebRewrite { const String& from(void) const { return _from; } const String& toUrl(void) const { return _toUrl; } const String& params(void) const { return _params; } - virtual bool match(AsyncWebServerRequest* request) { return from() == request->url() && filter(request); } + virtual bool match(AsyncWebServerRequest* request) const { return from() == request->url() && filter(request); } }; /* @@ -741,13 +741,13 @@ class AsyncWebHandler : public AsyncMiddlewareChain { AsyncWebHandler& setAuthentication(const String& username, const String& password) { return setAuthentication(username.c_str(), password.c_str()); }; bool filter(AsyncWebServerRequest* request) { return _filter == NULL || _filter(request); } virtual ~AsyncWebHandler() {} - virtual bool canHandle(AsyncWebServerRequest* request __attribute__((unused))) { + virtual bool canHandle(AsyncWebServerRequest* request __attribute__((unused))) const { return false; } virtual void handleRequest(__unused AsyncWebServerRequest* request) {} virtual void handleUpload(__unused AsyncWebServerRequest* request, __unused const String& filename, __unused size_t index, __unused uint8_t* data, __unused size_t len, __unused bool final) {} virtual void handleBody(__unused AsyncWebServerRequest* request, __unused uint8_t* data, __unused size_t len, __unused size_t index, __unused size_t total) {} - virtual bool isRequestHandlerTrivial() { return true; } + virtual bool isRequestHandlerTrivial() const { return true; } }; /* diff --git a/src/Middleware.cpp b/src/Middleware.cpp index d5e18c54d..78cdfc87b 100644 --- a/src/Middleware.cpp +++ b/src/Middleware.cpp @@ -95,7 +95,7 @@ bool AuthenticationMiddleware::generateHash() { } } -bool AuthenticationMiddleware::allowed(AsyncWebServerRequest* request) { +bool AuthenticationMiddleware::allowed(AsyncWebServerRequest* request) const { if (_authMethod == AsyncAuthType::AUTH_NONE) return true; diff --git a/src/WebHandlerImpl.h b/src/WebHandlerImpl.h index cb43f809a..c92290d1a 100644 --- a/src/WebHandlerImpl.h +++ b/src/WebHandlerImpl.h @@ -34,7 +34,7 @@ class AsyncStaticWebHandler : public AsyncWebHandler { using FS = fs::FS; private: - bool _getFile(AsyncWebServerRequest* request); + bool _getFile(AsyncWebServerRequest* request) const; bool _fileExists(AsyncWebServerRequest* request, const String& path); uint8_t _countBits(const uint8_t value) const; @@ -52,7 +52,7 @@ class AsyncStaticWebHandler : public AsyncWebHandler { public: AsyncStaticWebHandler(const char* uri, FS& fs, const char* path, const char* cache_control); - virtual bool canHandle(AsyncWebServerRequest* request) override final; + virtual bool canHandle(AsyncWebServerRequest* request) const override final; virtual void handleRequest(AsyncWebServerRequest* request) override final; AsyncStaticWebHandler& setIsDir(bool isDir); AsyncStaticWebHandler& setDefaultFile(const char* filename); @@ -84,11 +84,11 @@ class AsyncCallbackWebHandler : public AsyncWebHandler { void onUpload(ArUploadHandlerFunction fn) { _onUpload = fn; } void onBody(ArBodyHandlerFunction fn) { _onBody = fn; } - virtual bool canHandle(AsyncWebServerRequest* request) override final; + virtual bool canHandle(AsyncWebServerRequest* request) const override final; virtual void handleRequest(AsyncWebServerRequest* request) override final; virtual void handleUpload(AsyncWebServerRequest* request, const String& filename, size_t index, uint8_t* data, size_t len, bool final) override final; virtual void handleBody(AsyncWebServerRequest* request, uint8_t* data, size_t len, size_t index, size_t total) override final; - virtual bool isRequestHandlerTrivial() override final { return !_onRequest; } + virtual bool isRequestHandlerTrivial() const override final { return !_onRequest; } }; #endif /* ASYNCWEBSERVERHANDLERIMPL_H_ */ diff --git a/src/WebHandlers.cpp b/src/WebHandlers.cpp index ae0be51ec..ad0716adc 100644 --- a/src/WebHandlers.cpp +++ b/src/WebHandlers.cpp @@ -104,14 +104,14 @@ AsyncStaticWebHandler& AsyncStaticWebHandler::setLastModified() { return setLastModified(last_modified); } #endif -bool AsyncStaticWebHandler::canHandle(AsyncWebServerRequest* request) { +bool AsyncStaticWebHandler::canHandle(AsyncWebServerRequest* request) const { if (request->method() != HTTP_GET || !request->url().startsWith(_uri) || !request->isExpectedRequestedConnType(RCT_DEFAULT, RCT_HTTP)) { return false; } return _getFile(request); } -bool AsyncStaticWebHandler::_getFile(AsyncWebServerRequest* request) { +bool AsyncStaticWebHandler::_getFile(AsyncWebServerRequest* request) const { // Remove the found uri String path = request->url().substring(_uri.length()); @@ -121,7 +121,7 @@ bool AsyncStaticWebHandler::_getFile(AsyncWebServerRequest* request) { path = _path + path; // Do we have a file or .gz file - if (!canSkipFileCheck && _fileExists(request, path)) + if (!canSkipFileCheck && const_cast(this)->_fileExists(request, path)) return true; // Can't handle if not default file @@ -133,7 +133,7 @@ bool AsyncStaticWebHandler::_getFile(AsyncWebServerRequest* request) { path += String('/'); path += _default_file; - return _fileExists(request, path); + return const_cast(this)->_fileExists(request, path); } #ifdef ESP32 @@ -260,7 +260,7 @@ void AsyncCallbackWebHandler::setUri(const String& uri) { _isRegex = uri.startsWith("^") && uri.endsWith("$"); } -bool AsyncCallbackWebHandler::canHandle(AsyncWebServerRequest* request) { +bool AsyncCallbackWebHandler::canHandle(AsyncWebServerRequest* request) const { if (!_onRequest) return false; diff --git a/src/WebRequest.cpp b/src/WebRequest.cpp index 845210697..99555765b 100644 --- a/src/WebRequest.cpp +++ b/src/WebRequest.cpp @@ -781,7 +781,7 @@ void AsyncWebServerRequest::redirect(const char* url, int code) { send(response); } -bool AsyncWebServerRequest::authenticate(const char* username, const char* password, const char* realm, bool passwordIsHash) { +bool AsyncWebServerRequest::authenticate(const char* username, const char* password, const char* realm, bool passwordIsHash) const { if (_authorization.length()) { if (_authMethod == AsyncAuthType::AUTH_DIGEST) return checkDigestAuthentication(_authorization.c_str(), methodToString(), username, password, realm, passwordIsHash, NULL, NULL, NULL); @@ -793,7 +793,7 @@ bool AsyncWebServerRequest::authenticate(const char* username, const char* passw return false; } -bool AsyncWebServerRequest::authenticate(const char* hash) { +bool AsyncWebServerRequest::authenticate(const char* hash) const { if (!_authorization.length() || hash == NULL) return false; @@ -1018,13 +1018,8 @@ const __FlashStringHelper* AsyncWebServerRequest::requestedConnTypeToString() co } #endif // ESP8266 -bool AsyncWebServerRequest::isExpectedRequestedConnType(RequestedConnectionType erct1, RequestedConnectionType erct2, RequestedConnectionType erct3) { - bool res = false; - if ((erct1 != RCT_NOT_USED) && (erct1 == _reqconntype)) - res = true; - if ((erct2 != RCT_NOT_USED) && (erct2 == _reqconntype)) - res = true; - if ((erct3 != RCT_NOT_USED) && (erct3 == _reqconntype)) - res = true; - return res; +bool AsyncWebServerRequest::isExpectedRequestedConnType(RequestedConnectionType erct1, RequestedConnectionType erct2, RequestedConnectionType erct3) const { + return ((erct1 != RCT_NOT_USED) && (erct1 == _reqconntype)) || + ((erct2 != RCT_NOT_USED) && (erct2 == _reqconntype)) || + ((erct3 != RCT_NOT_USED) && (erct3 == _reqconntype)); } From 147f342e8470a89797dfc7599096ff7384acb103 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Wed, 23 Oct 2024 10:13:58 +0200 Subject: [PATCH 450/551] added isWebSocketUpgrade(), isSSE(), isHTTP() methods --- src/ESPAsyncWebServer.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index 538fd1122..2d41d9f1d 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -275,6 +275,9 @@ class AsyncWebServerRequest { RequestedConnectionType requestedConnType() const { return _reqconntype; } bool isExpectedRequestedConnType(RequestedConnectionType erct1, RequestedConnectionType erct2 = RCT_NOT_USED, RequestedConnectionType erct3 = RCT_NOT_USED) const; + bool isWebSocketUpgrade() const { return _method == HTTP_GET && isExpectedRequestedConnType(RCT_WS); } + bool isSSE() const { return _method == HTTP_GET && isExpectedRequestedConnType(RCT_EVENT); } + bool isHTTP() const { return isExpectedRequestedConnType(RCT_DEFAULT, RCT_HTTP); } void onDisconnect(ArDisconnectHandler fn); // hash is the string representation of: From ea7a593b4eaea72838d55e671de5a30e7cb87a2e Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Wed, 23 Oct 2024 10:27:55 +0200 Subject: [PATCH 451/551] Fix AsyncStaticWebHandler to remove the wrong gzip stat feature which is not taking in consideration the frequency of each request. Expose instead a boolean flag to let the user control that. --- src/WebHandlerImpl.h | 4 ++-- src/WebHandlers.cpp | 18 +++++------------- 2 files changed, 7 insertions(+), 15 deletions(-) diff --git a/src/WebHandlerImpl.h b/src/WebHandlerImpl.h index c92290d1a..5b1868785 100644 --- a/src/WebHandlerImpl.h +++ b/src/WebHandlerImpl.h @@ -47,13 +47,13 @@ class AsyncStaticWebHandler : public AsyncWebHandler { String _last_modified; AwsTemplateProcessor _callback; bool _isDir; - bool _gzipFirst; - uint8_t _gzipStats; + bool _tryGzipFirst = true; public: AsyncStaticWebHandler(const char* uri, FS& fs, const char* path, const char* cache_control); virtual bool canHandle(AsyncWebServerRequest* request) const override final; virtual void handleRequest(AsyncWebServerRequest* request) override final; + AsyncStaticWebHandler& setTryGzipFirst(bool value); AsyncStaticWebHandler& setIsDir(bool isDir); AsyncStaticWebHandler& setDefaultFile(const char* filename); AsyncStaticWebHandler& setCacheControl(const char* cache_control); diff --git a/src/WebHandlers.cpp b/src/WebHandlers.cpp index ad0716adc..bd3be200c 100644 --- a/src/WebHandlers.cpp +++ b/src/WebHandlers.cpp @@ -56,10 +56,11 @@ AsyncStaticWebHandler::AsyncStaticWebHandler(const char* uri, FS& fs, const char _uri = _uri.substring(0, _uri.length() - 1); if (_path[_path.length() - 1] == '/') _path = _path.substring(0, _path.length() - 1); +} - // Reset stats - _gzipFirst = false; - _gzipStats = 0xF8; +AsyncStaticWebHandler& AsyncStaticWebHandler::setTryGzipFirst(bool value) { + _tryGzipFirst = value; + return *this; } AsyncStaticWebHandler& AsyncStaticWebHandler::setIsDir(bool isDir) { @@ -148,7 +149,7 @@ bool AsyncStaticWebHandler::_fileExists(AsyncWebServerRequest* request, const St String gzip = path + T__gz; - if (_gzipFirst) { + if (_tryGzipFirst) { if (_fs.exists(gzip)) { request->_tempFile = _fs.open(gzip, fs::FileOpenMode::read); gzipFound = FILE_IS_REAL(request->_tempFile); @@ -180,15 +181,6 @@ bool AsyncStaticWebHandler::_fileExists(AsyncWebServerRequest* request, const St char* _tempPath = (char*)malloc(pathLen + 1); snprintf_P(_tempPath, pathLen + 1, PSTR("%s"), path.c_str()); request->_tempObject = (void*)_tempPath; - - // Calculate gzip statistic - _gzipStats = (_gzipStats << 1) + (gzipFound ? 1 : 0); - if (_gzipStats == 0x00) - _gzipFirst = false; // All files are not gzip - else if (_gzipStats == 0xFF) - _gzipFirst = true; // All files are gzip - else - _gzipFirst = _countBits(_gzipStats) > 4; // IF we have more gzip files - try gzip first } return found; From c8f263eeb5c2aa6fbfcf1a2816f129f3b8a56cab Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Wed, 23 Oct 2024 10:29:46 +0200 Subject: [PATCH 452/551] Renamed _fielExists into _searchFile --- src/WebHandlerImpl.h | 2 +- src/WebHandlers.cpp | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/WebHandlerImpl.h b/src/WebHandlerImpl.h index 5b1868785..d03b19fbc 100644 --- a/src/WebHandlerImpl.h +++ b/src/WebHandlerImpl.h @@ -35,7 +35,7 @@ class AsyncStaticWebHandler : public AsyncWebHandler { private: bool _getFile(AsyncWebServerRequest* request) const; - bool _fileExists(AsyncWebServerRequest* request, const String& path); + bool _searchFile(AsyncWebServerRequest* request, const String& path); uint8_t _countBits(const uint8_t value) const; protected: diff --git a/src/WebHandlers.cpp b/src/WebHandlers.cpp index bd3be200c..0e18ed039 100644 --- a/src/WebHandlers.cpp +++ b/src/WebHandlers.cpp @@ -122,7 +122,7 @@ bool AsyncStaticWebHandler::_getFile(AsyncWebServerRequest* request) const { path = _path + path; // Do we have a file or .gz file - if (!canSkipFileCheck && const_cast(this)->_fileExists(request, path)) + if (!canSkipFileCheck && const_cast(this)->_searchFile(request, path)) return true; // Can't handle if not default file @@ -134,7 +134,7 @@ bool AsyncStaticWebHandler::_getFile(AsyncWebServerRequest* request) const { path += String('/'); path += _default_file; - return const_cast(this)->_fileExists(request, path); + return const_cast(this)->_searchFile(request, path); } #ifdef ESP32 @@ -143,7 +143,7 @@ bool AsyncStaticWebHandler::_getFile(AsyncWebServerRequest* request) const { #define FILE_IS_REAL(f) (f == true) #endif -bool AsyncStaticWebHandler::_fileExists(AsyncWebServerRequest* request, const String& path) { +bool AsyncStaticWebHandler::_searchFile(AsyncWebServerRequest* request, const String& path) { bool fileFound = false; bool gzipFound = false; From 724f6c304532b1941bfca4bd3a5bf4e5075584c2 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Wed, 23 Oct 2024 10:50:03 +0200 Subject: [PATCH 453/551] Fix #142: canHandle implementations should check for the request type (http, websocket, sse) --- src/AsyncEventSource.cpp | 5 +---- src/AsyncJson.cpp | 8 ++------ src/AsyncMessagePack.cpp | 8 ++------ src/AsyncWebSocket.cpp | 8 +------- src/WebHandlers.cpp | 10 ++-------- 5 files changed, 8 insertions(+), 31 deletions(-) diff --git a/src/AsyncEventSource.cpp b/src/AsyncEventSource.cpp index 2d81dbcb9..1c0ff2a6b 100644 --- a/src/AsyncEventSource.cpp +++ b/src/AsyncEventSource.cpp @@ -386,10 +386,7 @@ size_t AsyncEventSource::count() const { } bool AsyncEventSource::canHandle(AsyncWebServerRequest* request) const { - if (request->method() != HTTP_GET || !request->url().equals(_url)) { - return false; - } - return true; + return request->isSSE() && request->url().equals(_url); } void AsyncEventSource::handleRequest(AsyncWebServerRequest* request) { diff --git a/src/AsyncJson.cpp b/src/AsyncJson.cpp index ee69f91f3..42956537d 100644 --- a/src/AsyncJson.cpp +++ b/src/AsyncJson.cpp @@ -90,17 +90,13 @@ AsyncCallbackJsonWebHandler::AsyncCallbackJsonWebHandler(const String& uri, ArJs #endif bool AsyncCallbackJsonWebHandler::canHandle(AsyncWebServerRequest* request) const { - if (!_onRequest) - return false; - - WebRequestMethodComposite request_method = request->method(); - if (!(_method & request_method)) + if (!_onRequest || !request->isHTTP() || !(_method & request->method())) return false; if (_uri.length() && (_uri != request->url() && !request->url().startsWith(_uri + "/"))) return false; - if (request_method != HTTP_GET && !request->contentType().equalsIgnoreCase(asyncsrv::T_application_json)) + if (request->method() != HTTP_GET && !request->contentType().equalsIgnoreCase(asyncsrv::T_application_json)) return false; return true; diff --git a/src/AsyncMessagePack.cpp b/src/AsyncMessagePack.cpp index db995ed7a..85af67148 100644 --- a/src/AsyncMessagePack.cpp +++ b/src/AsyncMessagePack.cpp @@ -45,17 +45,13 @@ AsyncCallbackMessagePackWebHandler::AsyncCallbackMessagePackWebHandler(const Str #endif bool AsyncCallbackMessagePackWebHandler::canHandle(AsyncWebServerRequest* request) const { - if (!_onRequest) - return false; - - WebRequestMethodComposite request_method = request->method(); - if (!(_method & request_method)) + if (!_onRequest || !request->isHTTP() || !(_method & request->method())) return false; if (_uri.length() && (_uri != request->url() && !request->url().startsWith(_uri + "/"))) return false; - if (request_method != HTTP_GET && !request->contentType().equalsIgnoreCase(asyncsrv::T_application_msgpack)) + if (request->method() != HTTP_GET && !request->contentType().equalsIgnoreCase(asyncsrv::T_application_msgpack)) return false; return true; diff --git a/src/AsyncWebSocket.cpp b/src/AsyncWebSocket.cpp index 0bb40e4a2..24db0525f 100644 --- a/src/AsyncWebSocket.cpp +++ b/src/AsyncWebSocket.cpp @@ -1122,13 +1122,7 @@ const char __WS_STR_UUID[] PROGMEM = {"258EAFA5-E914-47DA-95CA-C5AB0DC85B11"}; #define WS_STR_UUID FPSTR(__WS_STR_UUID) bool AsyncWebSocket::canHandle(AsyncWebServerRequest* request) const { - if (!_enabled) - return false; - - if (request->method() != HTTP_GET || !request->url().equals(_url) || !request->isExpectedRequestedConnType(RCT_WS)) - return false; - - return true; + return _enabled && request->isWebSocketUpgrade() && request->url().equals(_url); } void AsyncWebSocket::handleRequest(AsyncWebServerRequest* request) { diff --git a/src/WebHandlers.cpp b/src/WebHandlers.cpp index 0e18ed039..a1183186f 100644 --- a/src/WebHandlers.cpp +++ b/src/WebHandlers.cpp @@ -106,10 +106,7 @@ AsyncStaticWebHandler& AsyncStaticWebHandler::setLastModified() { } #endif bool AsyncStaticWebHandler::canHandle(AsyncWebServerRequest* request) const { - if (request->method() != HTTP_GET || !request->url().startsWith(_uri) || !request->isExpectedRequestedConnType(RCT_DEFAULT, RCT_HTTP)) { - return false; - } - return _getFile(request); + return request->isHTTP() && request->method() == HTTP_GET && request->url().startsWith(_uri) && _getFile(request); } bool AsyncStaticWebHandler::_getFile(AsyncWebServerRequest* request) const { @@ -253,10 +250,7 @@ void AsyncCallbackWebHandler::setUri(const String& uri) { } bool AsyncCallbackWebHandler::canHandle(AsyncWebServerRequest* request) const { - if (!_onRequest) - return false; - - if (!(_method & request->method())) + if (!_onRequest || !request->isHTTP() || !(_method & request->method())) return false; #ifdef ASYNCWEBSERVER_REGEX From 24cc3deba827316ef902d1dda02776f578f54027 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Wed, 23 Oct 2024 10:48:54 +0200 Subject: [PATCH 454/551] update sample --- examples/SimpleServer/SimpleServer.ino | 33 +++++++++++++------------- platformio.ini | 4 ++-- 2 files changed, 18 insertions(+), 19 deletions(-) diff --git a/examples/SimpleServer/SimpleServer.ino b/examples/SimpleServer/SimpleServer.ino index 2c934ea68..dc30cfd33 100644 --- a/examples/SimpleServer/SimpleServer.ino +++ b/examples/SimpleServer/SimpleServer.ino @@ -183,6 +183,20 @@ void setup() { Serial.begin(115200); +#ifndef CONFIG_IDF_TARGET_ESP32H2 + // WiFi.mode(WIFI_STA); + // WiFi.begin("YOUR_SSID", "YOUR_PASSWORD"); + // if (WiFi.waitForConnectResult() != WL_CONNECTED) { + // Serial.printf("WiFi Failed!\n"); + // return; + // } + // Serial.print("IP Address: "); + // Serial.println(WiFi.localIP()); + + WiFi.mode(WIFI_AP); + WiFi.softAP("esp-captive"); +#endif + #ifdef ESP32 LittleFS.begin(true); #else @@ -201,20 +215,6 @@ void setup() { } } -#ifndef CONFIG_IDF_TARGET_ESP32H2 - // WiFi.mode(WIFI_STA); - // WiFi.begin("YOUR_SSID", "YOUR_PASSWORD"); - // if (WiFi.waitForConnectResult() != WL_CONNECTED) { - // Serial.printf("WiFi Failed!\n"); - // return; - // } - // Serial.print("IP Address: "); - // Serial.println(WiFi.localIP()); - - WiFi.mode(WIFI_AP); - WiFi.softAP("esp-captive"); -#endif - // curl -v -X GET http://192.168.4.1/handler-not-sending-response server.on("/handler-not-sending-response", HTTP_GET, [](AsyncWebServerRequest* request) { // handler forgot to send a response to the client => 501 Not Implemented @@ -389,9 +389,8 @@ void setup() { request->send(200, "text/html", htmlContent); }); - server.on("/file", HTTP_GET, [](AsyncWebServerRequest* request) { - request->send(LittleFS, "/index.txt"); - }); + // curl -v -X GET http://192.168.4.1/index.txt + server.serveStatic("/index.txt", LittleFS, "/index.txt"); // Issue #14: assert failed: tcp_update_rcv_ann_wnd (needs help to test fix) // > curl -v http://192.168.4.1/issue-14 diff --git a/platformio.ini b/platformio.ini index 2fd60e728..046bf57e5 100644 --- a/platformio.ini +++ b/platformio.ini @@ -2,10 +2,10 @@ default_envs = arduino-2, arduino-3, arduino-310rc1, esp8266, raspberrypi lib_dir = . ; src_dir = examples/CaptivePortal -; src_dir = examples/SimpleServer +src_dir = examples/SimpleServer ; src_dir = examples/StreamFiles ; src_dir = examples/Filters -src_dir = examples/Issue85 +; src_dir = examples/Issue85 [env] framework = arduino From 85b1cee264ab2a3750d89fdeb0a4669630c06846 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Wed, 23 Oct 2024 11:03:09 +0200 Subject: [PATCH 455/551] v3.3.18 --- README.md | 6 +++--- docs/index.md | 6 +++--- library.json | 2 +- library.properties | 2 +- src/ESPAsyncWebServer.h | 4 ++-- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 460daba58..71bd065a8 100644 --- a/README.md +++ b/README.md @@ -61,7 +61,7 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo ```ini lib_compat_mode = strict lib_ldf_mode = chain -lib_deps = mathieucarbou/ESPAsyncWebServer @ 3.3.17 +lib_deps = mathieucarbou/ESPAsyncWebServer @ 3.3.18 ``` **Dependencies:** @@ -87,7 +87,7 @@ lib_ldf_mode = chain lib_deps = ; mathieucarbou/AsyncTCP @ 3.2.10 https://github.com/mathieucarbou/AsyncTCPSock/archive/refs/tags/v1.0.3-dev.zip - mathieucarbou/ESPAsyncWebServer @ 3.3.17 + mathieucarbou/ESPAsyncWebServer @ 3.3.18 lib_ignore = AsyncTCP mathieucarbou/AsyncTCP @@ -95,7 +95,7 @@ lib_ignore = ## Performance -Performance of `mathieucarbou/ESPAsyncWebServer @ 3.3.17`: +Performance of `mathieucarbou/ESPAsyncWebServer @ 3.3.18`: ```bash > brew install autocannon diff --git a/docs/index.md b/docs/index.md index 460daba58..71bd065a8 100644 --- a/docs/index.md +++ b/docs/index.md @@ -61,7 +61,7 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo ```ini lib_compat_mode = strict lib_ldf_mode = chain -lib_deps = mathieucarbou/ESPAsyncWebServer @ 3.3.17 +lib_deps = mathieucarbou/ESPAsyncWebServer @ 3.3.18 ``` **Dependencies:** @@ -87,7 +87,7 @@ lib_ldf_mode = chain lib_deps = ; mathieucarbou/AsyncTCP @ 3.2.10 https://github.com/mathieucarbou/AsyncTCPSock/archive/refs/tags/v1.0.3-dev.zip - mathieucarbou/ESPAsyncWebServer @ 3.3.17 + mathieucarbou/ESPAsyncWebServer @ 3.3.18 lib_ignore = AsyncTCP mathieucarbou/AsyncTCP @@ -95,7 +95,7 @@ lib_ignore = ## Performance -Performance of `mathieucarbou/ESPAsyncWebServer @ 3.3.17`: +Performance of `mathieucarbou/ESPAsyncWebServer @ 3.3.18`: ```bash > brew install autocannon diff --git a/library.json b/library.json index 03b800d5a..fc92824eb 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "ESPAsyncWebServer", - "version": "3.3.17", + "version": "3.3.18", "description": "Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 and RP2040. Supports: WebSocket, SSE, Authentication, Arduino Json 7, File Upload, Static File serving, URL Rewrite, URL Redirect, etc.", "keywords": "http,async,websocket,webserver", "homepage": "https://github.com/mathieucarbou/ESPAsyncWebServer", diff --git a/library.properties b/library.properties index d16d77e0b..5a7e22763 100644 --- a/library.properties +++ b/library.properties @@ -1,6 +1,6 @@ name=ESP Async WebServer includes=ESPAsyncWebServer.h -version=3.3.17 +version=3.3.18 author=Me-No-Dev maintainer=Mathieu Carbou sentence=Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 and RP2040 diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index 2d41d9f1d..d5d55a113 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -48,10 +48,10 @@ #include "literals.h" -#define ASYNCWEBSERVER_VERSION "3.3.17" +#define ASYNCWEBSERVER_VERSION "3.3.18" #define ASYNCWEBSERVER_VERSION_MAJOR 3 #define ASYNCWEBSERVER_VERSION_MINOR 3 -#define ASYNCWEBSERVER_VERSION_REVISION 17 +#define ASYNCWEBSERVER_VERSION_REVISION 18 #define ASYNCWEBSERVER_FORK_mathieucarbou #ifdef ASYNCWEBSERVER_REGEX From b1527198516715a6a13234bfc2d879394a5b888c Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Wed, 23 Oct 2024 13:11:53 +0200 Subject: [PATCH 456/551] Set response to NULL after delete --- src/WebRequest.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/WebRequest.cpp b/src/WebRequest.cpp index 99555765b..7b745abae 100644 --- a/src/WebRequest.cpp +++ b/src/WebRequest.cpp @@ -49,9 +49,9 @@ AsyncWebServerRequest::~AsyncWebServerRequest() { _pathParams.clear(); - if (_response != NULL) { - delete _response; - } + AsyncWebServerResponse* r = _response + _response = NULL; + delete r; if (_tempObject != NULL) { free(_tempObject); From 7aea91bd423065cb6eefd4581f383444e4b66cfc Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Wed, 23 Oct 2024 14:36:10 +0200 Subject: [PATCH 457/551] Code cleanup --- src/ESPAsyncWebServer.h | 23 ++++++++++------------- src/WebRequest.cpp | 2 +- src/WebResponses.cpp | 4 +--- 3 files changed, 12 insertions(+), 17 deletions(-) diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index d5d55a113..15a60d1d5 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -140,7 +140,6 @@ class AsyncWebHeader { String _value; public: - AsyncWebHeader() = default; AsyncWebHeader(const AsyncWebHeader&) = default; AsyncWebHeader(const char* name, const char* value) : _name(name), _value(value) {} AsyncWebHeader(const String& name, const String& value) : _name(name), _value(value) {} @@ -739,14 +738,12 @@ class AsyncWebHandler : public AsyncMiddlewareChain { public: AsyncWebHandler() {} + virtual ~AsyncWebHandler() {} AsyncWebHandler& setFilter(ArRequestFilterFunction fn); AsyncWebHandler& setAuthentication(const char* username, const char* password); AsyncWebHandler& setAuthentication(const String& username, const String& password) { return setAuthentication(username.c_str(), password.c_str()); }; bool filter(AsyncWebServerRequest* request) { return _filter == NULL || _filter(request); } - virtual ~AsyncWebHandler() {} - virtual bool canHandle(AsyncWebServerRequest* request __attribute__((unused))) const { - return false; - } + virtual bool canHandle(AsyncWebServerRequest* request __attribute__((unused))) const { return false; } virtual void handleRequest(__unused AsyncWebServerRequest* request) {} virtual void handleUpload(__unused AsyncWebServerRequest* request, __unused const String& filename, __unused size_t index, __unused uint8_t* data, __unused size_t len, __unused bool final) {} virtual void handleBody(__unused AsyncWebServerRequest* request, __unused uint8_t* data, __unused size_t len, __unused size_t index, __unused size_t total) {} @@ -789,18 +786,18 @@ class AsyncWebServerResponse { public: AsyncWebServerResponse(); - virtual ~AsyncWebServerResponse(); - virtual void setCode(int code); + virtual ~AsyncWebServerResponse() {} + void setCode(int code); int code() const { return _code; } - virtual void setContentLength(size_t len); + void setContentLength(size_t len); void setContentType(const String& type) { setContentType(type.c_str()); } - virtual void setContentType(const char* type); - virtual bool addHeader(const char* name, const char* value, bool replaceExisting = true); + void setContentType(const char* type); + bool addHeader(const char* name, const char* value, bool replaceExisting = true); bool addHeader(const String& name, const String& value, bool replaceExisting = true) { return addHeader(name.c_str(), value.c_str(), replaceExisting); } bool addHeader(const char* name, long value, bool replaceExisting = true) { return addHeader(name, String(value), replaceExisting); } bool addHeader(const String& name, long value, bool replaceExisting = true) { return addHeader(name.c_str(), value, replaceExisting); } - virtual bool removeHeader(const char* name); - virtual const AsyncWebHeader* getHeader(const char* name) const; + bool removeHeader(const char* name); + const AsyncWebHeader* getHeader(const char* name) const; const std::list& getHeaders() const { return _headers; } #ifndef ESP8266 @@ -811,7 +808,7 @@ class AsyncWebServerResponse { _assembleHead(buffer, version); return buffer; } - virtual void _assembleHead(String& buffer, uint8_t version); + void _assembleHead(String& buffer, uint8_t version); virtual bool _started() const; virtual bool _finished() const; diff --git a/src/WebRequest.cpp b/src/WebRequest.cpp index 7b745abae..f399dc3e5 100644 --- a/src/WebRequest.cpp +++ b/src/WebRequest.cpp @@ -49,7 +49,7 @@ AsyncWebServerRequest::~AsyncWebServerRequest() { _pathParams.clear(); - AsyncWebServerResponse* r = _response + AsyncWebServerResponse* r = _response; _response = NULL; delete r; diff --git a/src/WebResponses.cpp b/src/WebResponses.cpp index e7edf5e91..e683176ab 100644 --- a/src/WebResponses.cpp +++ b/src/WebResponses.cpp @@ -225,8 +225,6 @@ AsyncWebServerResponse::AsyncWebServerResponse() } } -AsyncWebServerResponse::~AsyncWebServerResponse() = default; - void AsyncWebServerResponse::setCode(int code) { if (_state == RESPONSE_SETUP) _code = code; @@ -871,7 +869,7 @@ AsyncResponseStream::AsyncResponseStream(const char* contentType, size_t bufferS _content = std::unique_ptr(new cbuf(bufferSize)); // std::make_unique(bufferSize); } -AsyncResponseStream::~AsyncResponseStream() = default; +AsyncResponseStream::~AsyncResponseStream() {}; size_t AsyncResponseStream::_fillBuffer(uint8_t* buf, size_t maxLen) { return _content->read((char*)buf, maxLen); From bfd688c346d9876c3369b4a950ef57bbcf67354e Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Wed, 23 Oct 2024 14:49:28 +0200 Subject: [PATCH 458/551] Code cleanup around virtual destructor's hierarchy --- src/AsyncEventSource.h | 1 + src/AsyncJson.h | 1 + src/AsyncMessagePack.h | 1 + src/AsyncWebSocket.h | 1 + src/WebResponseImpl.h | 10 ++++++++-- src/WebResponses.cpp | 5 +---- 6 files changed, 13 insertions(+), 6 deletions(-) diff --git a/src/AsyncEventSource.h b/src/AsyncEventSource.h index 35ae31999..9baa04c03 100644 --- a/src/AsyncEventSource.h +++ b/src/AsyncEventSource.h @@ -154,6 +154,7 @@ class AsyncEventSourceResponse : public AsyncWebServerResponse { public: AsyncEventSourceResponse(AsyncEventSource* server); + virtual ~AsyncEventSourceResponse() {}; void _respond(AsyncWebServerRequest* request); size_t _ack(AsyncWebServerRequest* request, size_t len, uint32_t time); bool _sourceValid() const { return true; } diff --git a/src/AsyncJson.h b/src/AsyncJson.h index a3db8b62b..198ac4bef 100644 --- a/src/AsyncJson.h +++ b/src/AsyncJson.h @@ -74,6 +74,7 @@ class AsyncJsonResponse : public AsyncAbstractResponse { #else AsyncJsonResponse(bool isArray = false); #endif + virtual ~AsyncJsonResponse() {} JsonVariant& getRoot() { return _root; } bool _sourceValid() const { return _isValid; } size_t setLength(); diff --git a/src/AsyncMessagePack.h b/src/AsyncMessagePack.h index 210e0a62c..7548f1d64 100644 --- a/src/AsyncMessagePack.h +++ b/src/AsyncMessagePack.h @@ -58,6 +58,7 @@ class AsyncMessagePackResponse : public AsyncAbstractResponse { #else AsyncMessagePackResponse(bool isArray = false); #endif + virtual ~AsyncMessagePackResponse() {} JsonVariant& getRoot() { return _root; } bool _sourceValid() const { return _isValid; } size_t setLength(); diff --git a/src/AsyncWebSocket.h b/src/AsyncWebSocket.h index 5f134b951..8a7f7b384 100644 --- a/src/AsyncWebSocket.h +++ b/src/AsyncWebSocket.h @@ -368,6 +368,7 @@ class AsyncWebSocketResponse : public AsyncWebServerResponse { public: AsyncWebSocketResponse(const String& key, AsyncWebSocket* server); + virtual ~AsyncWebSocketResponse() {} void _respond(AsyncWebServerRequest* request); size_t _ack(AsyncWebServerRequest* request, size_t len, uint32_t time); bool _sourceValid() const { return true; } diff --git a/src/WebResponseImpl.h b/src/WebResponseImpl.h index a6f71bb55..d8b91355c 100644 --- a/src/WebResponseImpl.h +++ b/src/WebResponseImpl.h @@ -38,6 +38,7 @@ class AsyncBasicResponse : public AsyncWebServerResponse { public: explicit AsyncBasicResponse(int code, const char* contentType = asyncsrv::empty, const char* content = asyncsrv::empty); + virtual ~AsyncBasicResponse() {} AsyncBasicResponse(int code, const String& contentType, const String& content = emptyString) : AsyncBasicResponse(code, contentType.c_str(), content.c_str()) {} void _respond(AsyncWebServerRequest* request); size_t _ack(AsyncWebServerRequest* request, size_t len, uint32_t time); @@ -60,6 +61,7 @@ class AsyncAbstractResponse : public AsyncWebServerResponse { public: AsyncAbstractResponse(AwsTemplateProcessor callback = nullptr); + virtual ~AsyncAbstractResponse() {} void _respond(AsyncWebServerRequest* request); size_t _ack(AsyncWebServerRequest* request, size_t len, uint32_t time); bool _sourceValid() const { return false; } @@ -85,7 +87,7 @@ class AsyncFileResponse : public AsyncAbstractResponse { AsyncFileResponse(FS& fs, const String& path, const String& contentType, bool download = false, AwsTemplateProcessor callback = nullptr) : AsyncFileResponse(fs, path, contentType.c_str(), download, callback) {} AsyncFileResponse(File content, const String& path, const char* contentType = asyncsrv::empty, bool download = false, AwsTemplateProcessor callback = nullptr); AsyncFileResponse(File content, const String& path, const String& contentType, bool download = false, AwsTemplateProcessor callack = nullptr) : AsyncFileResponse(content, path, contentType.c_str(), download, callack) {} - ~AsyncFileResponse(); + virtual ~AsyncFileResponse(); bool _sourceValid() const { return !!(_content); } virtual size_t _fillBuffer(uint8_t* buf, size_t maxLen) override; }; @@ -97,6 +99,7 @@ class AsyncStreamResponse : public AsyncAbstractResponse { public: AsyncStreamResponse(Stream& stream, const char* contentType, size_t len, AwsTemplateProcessor callback = nullptr); AsyncStreamResponse(Stream& stream, const String& contentType, size_t len, AwsTemplateProcessor callback = nullptr) : AsyncStreamResponse(stream, contentType.c_str(), len, callback) {} + virtual ~AsyncStreamResponse() {} bool _sourceValid() const { return !!(_content); } virtual size_t _fillBuffer(uint8_t* buf, size_t maxLen) override; }; @@ -109,6 +112,7 @@ class AsyncCallbackResponse : public AsyncAbstractResponse { public: AsyncCallbackResponse(const char* contentType, size_t len, AwsResponseFiller callback, AwsTemplateProcessor templateCallback = nullptr); AsyncCallbackResponse(const String& contentType, size_t len, AwsResponseFiller callback, AwsTemplateProcessor templateCallback = nullptr) : AsyncCallbackResponse(contentType.c_str(), len, callback, templateCallback) {} + virtual ~AsyncCallbackResponse() {} bool _sourceValid() const { return !!(_content); } virtual size_t _fillBuffer(uint8_t* buf, size_t maxLen) override; }; @@ -121,6 +125,7 @@ class AsyncChunkedResponse : public AsyncAbstractResponse { public: AsyncChunkedResponse(const char* contentType, AwsResponseFiller callback, AwsTemplateProcessor templateCallback = nullptr); AsyncChunkedResponse(const String& contentType, AwsResponseFiller callback, AwsTemplateProcessor templateCallback = nullptr) : AsyncChunkedResponse(contentType.c_str(), callback, templateCallback) {} + virtual ~AsyncChunkedResponse() {} bool _sourceValid() const { return !!(_content); } virtual size_t _fillBuffer(uint8_t* buf, size_t maxLen) override; }; @@ -133,6 +138,7 @@ class AsyncProgmemResponse : public AsyncAbstractResponse { public: AsyncProgmemResponse(int code, const char* contentType, const uint8_t* content, size_t len, AwsTemplateProcessor callback = nullptr); AsyncProgmemResponse(int code, const String& contentType, const uint8_t* content, size_t len, AwsTemplateProcessor callback = nullptr) : AsyncProgmemResponse(code, contentType.c_str(), content, len, callback) {} + virtual ~AsyncProgmemResponse() {} bool _sourceValid() const { return true; } virtual size_t _fillBuffer(uint8_t* buf, size_t maxLen) override; }; @@ -146,7 +152,7 @@ class AsyncResponseStream : public AsyncAbstractResponse, public Print { public: AsyncResponseStream(const char* contentType, size_t bufferSize); AsyncResponseStream(const String& contentType, size_t bufferSize) : AsyncResponseStream(contentType.c_str(), bufferSize) {} - ~AsyncResponseStream(); + virtual ~AsyncResponseStream() {} bool _sourceValid() const { return (_state < RESPONSE_END); } virtual size_t _fillBuffer(uint8_t* buf, size_t maxLen) override; size_t write(const uint8_t* data, size_t len); diff --git a/src/WebResponses.cpp b/src/WebResponses.cpp index e683176ab..23f929a5d 100644 --- a/src/WebResponses.cpp +++ b/src/WebResponses.cpp @@ -647,8 +647,7 @@ size_t AsyncAbstractResponse::_fillBufferAndProcessTemplates(uint8_t* data, size * */ AsyncFileResponse::~AsyncFileResponse() { - if (_content) - _content.close(); + _content.close(); } void AsyncFileResponse::_setContentTypeFromPath(const String& path) { @@ -869,8 +868,6 @@ AsyncResponseStream::AsyncResponseStream(const char* contentType, size_t bufferS _content = std::unique_ptr(new cbuf(bufferSize)); // std::make_unique(bufferSize); } -AsyncResponseStream::~AsyncResponseStream() {}; - size_t AsyncResponseStream::_fillBuffer(uint8_t* buf, size_t maxLen) { return _content->read((char*)buf, maxLen); } From 996a1bffa9c5463a1510620d423ccaa56af7e44f Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Wed, 23 Oct 2024 15:59:50 +0200 Subject: [PATCH 459/551] Code cleanup: virtual destructors, hierarchy, AsyncResponseStream, etc --- examples/CaptivePortal/CaptivePortal.ino | 3 - examples/Filters/Filters.ino | 3 - examples/SimpleServer/SimpleServer.ino | 19 +++- platformio.ini | 7 +- src/AsyncEventSource.h | 5 +- src/AsyncJson.h | 11 ++- src/AsyncMessagePack.h | 11 ++- src/AsyncWebSocket.cpp | 4 +- src/AsyncWebSocket.h | 5 +- src/ChunkPrint.h | 1 - src/ESPAsyncWebServer.h | 15 +--- src/WebAuthentication.cpp | 4 - src/WebAuthentication.h | 4 - src/WebHandlerImpl.h | 14 +-- src/WebRequest.cpp | 41 --------- src/WebResponseImpl.h | 51 +++++------ src/WebResponses.cpp | 107 +---------------------- 17 files changed, 70 insertions(+), 235 deletions(-) diff --git a/examples/CaptivePortal/CaptivePortal.ino b/examples/CaptivePortal/CaptivePortal.ino index ed9dfffea..d44e7e6bf 100644 --- a/examples/CaptivePortal/CaptivePortal.ino +++ b/examples/CaptivePortal/CaptivePortal.ino @@ -16,9 +16,6 @@ AsyncWebServer server(80); class CaptiveRequestHandler : public AsyncWebHandler { public: - CaptiveRequestHandler() {} - virtual ~CaptiveRequestHandler() {} - bool canHandle(__unused AsyncWebServerRequest* request) { return true; } diff --git a/examples/Filters/Filters.ino b/examples/Filters/Filters.ino index de5129a16..6479c155d 100644 --- a/examples/Filters/Filters.ino +++ b/examples/Filters/Filters.ino @@ -18,9 +18,6 @@ AsyncWebServer server(80); class CaptiveRequestHandler : public AsyncWebHandler { public: - CaptiveRequestHandler() {} - virtual ~CaptiveRequestHandler() {} - bool canHandle(__unused AsyncWebServerRequest* request) { return true; } diff --git a/examples/SimpleServer/SimpleServer.ino b/examples/SimpleServer/SimpleServer.ino index dc30cfd33..1328f1a34 100644 --- a/examples/SimpleServer/SimpleServer.ino +++ b/examples/SimpleServer/SimpleServer.ino @@ -19,7 +19,7 @@ #include -#if ASYNC_JSON_SUPPORT == 1 +#if __has_include("ArduinoJson.h") #include #include #include @@ -171,7 +171,7 @@ void notFound(AsyncWebServerRequest* request) { request->send(404, "text/plain", "Not found"); } -#if ASYNC_JSON_SUPPORT == 1 +#if __has_include("ArduinoJson.h") AsyncCallbackJsonWebHandler* jsonHandler = new AsyncCallbackJsonWebHandler("/json2"); AsyncCallbackMessagePackWebHandler* msgPackHandler = new AsyncCallbackMessagePackWebHandler("/msgpack2"); #endif @@ -463,7 +463,7 @@ void setup() { request->send(200, "text/plain", "Hello, POST: " + message); }); -#if ASYNC_JSON_SUPPORT == 1 +#if __has_include("ArduinoJson.h") // JSON // receives JSON and sends JSON @@ -479,6 +479,7 @@ void setup() { }); // sends JSON + // curl -v -X GET http://192.168.4.1/json1 server.on("/json1", HTTP_GET, [](AsyncWebServerRequest* request) { AsyncJsonResponse* response = new AsyncJsonResponse(); JsonObject root = response->getRoot().to(); @@ -487,6 +488,16 @@ void setup() { request->send(response); }); + // curl -v -X GET http://192.168.4.1/json2 + server.on("/json2", HTTP_GET, [](AsyncWebServerRequest* request) { + AsyncResponseStream* response = request->beginResponseStream("application/json"); + JsonDocument doc; + JsonObject root = doc.to(); + root["hello"] = "world"; + serializeJson(root, *response); + request->send(response); + }); + // MessagePack // receives MessagePack and sends MessagePack @@ -552,7 +563,7 @@ void setup() { // Run: websocat ws://192.168.4.1/ws server.addHandler(&ws); -#if ASYNC_JSON_SUPPORT == 1 +#if __has_include("ArduinoJson.h") server.addHandler(jsonHandler); server.addHandler(msgPackHandler); #endif diff --git a/platformio.ini b/platformio.ini index 046bf57e5..d6ab05c76 100644 --- a/platformio.ini +++ b/platformio.ini @@ -22,8 +22,10 @@ build_flags = -D CONFIG_ASYNC_TCP_STACK_SIZE=4096 upload_protocol = esptool monitor_speed = 115200 -; monitor_filters = esp32_exception_decoder, log2file -monitor_filters = esp8266_exception_decoder, log2file +monitor_filters = esp32_exception_decoder, log2file +; monitor_filters = esp8266_exception_decoder, log2file +lib_compat_mode = strict +lib_ldf_mode = chain lib_deps = ; bblanchon/ArduinoJson @ 5.13.4 ; bblanchon/ArduinoJson @ 6.21.5 @@ -52,6 +54,7 @@ lib_deps = platform = https://github.com/pioarduino/platform-espressif32/releases/download/53.03.10-rc1/platform-espressif32.zip ; board = esp32-s3-devkitc-1 ; board = esp32-c6-devkitc-1 +; board = esp32-h2-devkitm-1 [env:perf-test-AsyncTCP] platform = https://github.com/pioarduino/platform-espressif32/releases/download/53.03.10-rc1/platform-espressif32.zip diff --git a/src/AsyncEventSource.h b/src/AsyncEventSource.h index 9baa04c03..10d79012b 100644 --- a/src/AsyncEventSource.h +++ b/src/AsyncEventSource.h @@ -143,8 +143,8 @@ class AsyncEventSource : public AsyncWebHandler { // system callbacks (do not call) void _addClient(AsyncEventSourceClient* client); void _handleDisconnect(AsyncEventSourceClient* client); - virtual bool canHandle(AsyncWebServerRequest* request) const override final; - virtual void handleRequest(AsyncWebServerRequest* request) override final; + bool canHandle(AsyncWebServerRequest* request) const override final; + void handleRequest(AsyncWebServerRequest* request) override final; }; class AsyncEventSourceResponse : public AsyncWebServerResponse { @@ -154,7 +154,6 @@ class AsyncEventSourceResponse : public AsyncWebServerResponse { public: AsyncEventSourceResponse(AsyncEventSource* server); - virtual ~AsyncEventSourceResponse() {}; void _respond(AsyncWebServerRequest* request); size_t _ack(AsyncWebServerRequest* request, size_t len, uint32_t time); bool _sourceValid() const { return true; } diff --git a/src/AsyncJson.h b/src/AsyncJson.h index 198ac4bef..a54935adb 100644 --- a/src/AsyncJson.h +++ b/src/AsyncJson.h @@ -74,7 +74,6 @@ class AsyncJsonResponse : public AsyncAbstractResponse { #else AsyncJsonResponse(bool isArray = false); #endif - virtual ~AsyncJsonResponse() {} JsonVariant& getRoot() { return _root; } bool _sourceValid() const { return _isValid; } size_t setLength(); @@ -120,11 +119,11 @@ class AsyncCallbackJsonWebHandler : public AsyncWebHandler { void setMaxContentLength(int maxContentLength) { _maxContentLength = maxContentLength; } void onRequest(ArJsonRequestHandlerFunction fn) { _onRequest = fn; } - virtual bool canHandle(AsyncWebServerRequest* request) const override final; - virtual void handleRequest(AsyncWebServerRequest* request) override final; - virtual void handleUpload(__unused AsyncWebServerRequest* request, __unused const String& filename, __unused size_t index, __unused uint8_t* data, __unused size_t len, __unused bool final) override final {} - virtual void handleBody(AsyncWebServerRequest* request, uint8_t* data, size_t len, size_t index, size_t total) override final; - virtual bool isRequestHandlerTrivial() const override final { return !_onRequest; } + bool canHandle(AsyncWebServerRequest* request) const override final; + void handleRequest(AsyncWebServerRequest* request) override final; + void handleUpload(__unused AsyncWebServerRequest* request, __unused const String& filename, __unused size_t index, __unused uint8_t* data, __unused size_t len, __unused bool final) override final {} + void handleBody(AsyncWebServerRequest* request, uint8_t* data, size_t len, size_t index, size_t total) override final; + bool isRequestHandlerTrivial() const override final { return !_onRequest; } }; #endif // ASYNC_JSON_SUPPORT == 1 diff --git a/src/AsyncMessagePack.h b/src/AsyncMessagePack.h index 7548f1d64..78fde92fc 100644 --- a/src/AsyncMessagePack.h +++ b/src/AsyncMessagePack.h @@ -58,7 +58,6 @@ class AsyncMessagePackResponse : public AsyncAbstractResponse { #else AsyncMessagePackResponse(bool isArray = false); #endif - virtual ~AsyncMessagePackResponse() {} JsonVariant& getRoot() { return _root; } bool _sourceValid() const { return _isValid; } size_t setLength(); @@ -93,11 +92,11 @@ class AsyncCallbackMessagePackWebHandler : public AsyncWebHandler { void setMaxContentLength(int maxContentLength) { _maxContentLength = maxContentLength; } void onRequest(ArMessagePackRequestHandlerFunction fn) { _onRequest = fn; } - virtual bool canHandle(AsyncWebServerRequest* request) const override final; - virtual void handleRequest(AsyncWebServerRequest* request) override final; - virtual void handleUpload(__unused AsyncWebServerRequest* request, __unused const String& filename, __unused size_t index, __unused uint8_t* data, __unused size_t len, __unused bool final) override final {} - virtual void handleBody(AsyncWebServerRequest* request, uint8_t* data, size_t len, size_t index, size_t total) override final; - virtual bool isRequestHandlerTrivial() const override final { return !_onRequest; } + bool canHandle(AsyncWebServerRequest* request) const override final; + void handleRequest(AsyncWebServerRequest* request) override final; + void handleUpload(__unused AsyncWebServerRequest* request, __unused const String& filename, __unused size_t index, __unused uint8_t* data, __unused size_t len, __unused bool final) override final {} + void handleBody(AsyncWebServerRequest* request, uint8_t* data, size_t len, size_t index, size_t total) override final; + bool isRequestHandlerTrivial() const override final { return !_onRequest; } }; #endif // ASYNC_MSG_PACK_SUPPORT == 1 diff --git a/src/AsyncWebSocket.cpp b/src/AsyncWebSocket.cpp index 24db0525f..9efb6dbd0 100644 --- a/src/AsyncWebSocket.cpp +++ b/src/AsyncWebSocket.cpp @@ -185,12 +185,12 @@ class AsyncWebSocketControl { _data = NULL; } - virtual ~AsyncWebSocketControl() { + ~AsyncWebSocketControl() { if (_data != NULL) free(_data); } - virtual bool finished() const { return _finished; } + bool finished() const { return _finished; } uint8_t opcode() { return _opcode; } uint8_t len() { return _len + 2; } size_t send(AsyncClient* client) { diff --git a/src/AsyncWebSocket.h b/src/AsyncWebSocket.h index 8a7f7b384..8ad06ea84 100644 --- a/src/AsyncWebSocket.h +++ b/src/AsyncWebSocket.h @@ -350,8 +350,8 @@ class AsyncWebSocket : public AsyncWebHandler { uint32_t _getNextId() { return _cNextId++; } AsyncWebSocketClient* _newClient(AsyncWebServerRequest* request); void _handleEvent(AsyncWebSocketClient* client, AwsEventType type, void* arg, uint8_t* data, size_t len); - virtual bool canHandle(AsyncWebServerRequest* request) const override final; - virtual void handleRequest(AsyncWebServerRequest* request) override final; + bool canHandle(AsyncWebServerRequest* request) const override final; + void handleRequest(AsyncWebServerRequest* request) override final; // messagebuffer functions/objects. AsyncWebSocketMessageBuffer* makeBuffer(size_t size = 0); @@ -368,7 +368,6 @@ class AsyncWebSocketResponse : public AsyncWebServerResponse { public: AsyncWebSocketResponse(const String& key, AsyncWebSocket* server); - virtual ~AsyncWebSocketResponse() {} void _respond(AsyncWebServerRequest* request); size_t _ack(AsyncWebServerRequest* request, size_t len, uint32_t time); bool _sourceValid() const { return true; } diff --git a/src/ChunkPrint.h b/src/ChunkPrint.h index 103d21e1c..47988e17c 100644 --- a/src/ChunkPrint.h +++ b/src/ChunkPrint.h @@ -12,7 +12,6 @@ class ChunkPrint : public Print { public: ChunkPrint(uint8_t* destination, size_t from, size_t len); - virtual ~ChunkPrint() {} size_t write(uint8_t c); size_t write(const uint8_t* buffer, size_t size) { return this->Print::write(buffer, size); } }; diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index 15a60d1d5..b7b22ec1f 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -264,13 +264,8 @@ class AsyncWebServerRequest { size_t contentLength() const { return _contentLength; } bool multipart() const { return _isMultipart; } -#ifndef ESP8266 const char* methodToString() const; const char* requestedConnTypeToString() const; -#else - const __FlashStringHelper* methodToString() const; - const __FlashStringHelper* requestedConnTypeToString() const; -#endif RequestedConnectionType requestedConnType() const { return _reqconntype; } bool isExpectedRequestedConnType(RequestedConnectionType erct1, RequestedConnectionType erct2 = RCT_NOT_USED, RequestedConnectionType erct3 = RCT_NOT_USED) const; @@ -526,9 +521,7 @@ using ArMiddlewareCallback = std::function #include #include -#include "literals.h" // It is possible to restore these defines, but one can use _min and _max instead. Or std::min, std::max. @@ -38,11 +39,10 @@ class AsyncBasicResponse : public AsyncWebServerResponse { public: explicit AsyncBasicResponse(int code, const char* contentType = asyncsrv::empty, const char* content = asyncsrv::empty); - virtual ~AsyncBasicResponse() {} AsyncBasicResponse(int code, const String& contentType, const String& content = emptyString) : AsyncBasicResponse(code, contentType.c_str(), content.c_str()) {} - void _respond(AsyncWebServerRequest* request); - size_t _ack(AsyncWebServerRequest* request, size_t len, uint32_t time); - bool _sourceValid() const { return true; } + void _respond(AsyncWebServerRequest* request) override final; + size_t _ack(AsyncWebServerRequest* request, size_t len, uint32_t time) override final; + bool _sourceValid() const override final { return true; } }; class AsyncAbstractResponse : public AsyncWebServerResponse { @@ -62,9 +62,9 @@ class AsyncAbstractResponse : public AsyncWebServerResponse { public: AsyncAbstractResponse(AwsTemplateProcessor callback = nullptr); virtual ~AsyncAbstractResponse() {} - void _respond(AsyncWebServerRequest* request); - size_t _ack(AsyncWebServerRequest* request, size_t len, uint32_t time); - bool _sourceValid() const { return false; } + void _respond(AsyncWebServerRequest* request) override final; + size_t _ack(AsyncWebServerRequest* request, size_t len, uint32_t time) override final; + virtual bool _sourceValid() const { return false; } virtual size_t _fillBuffer(uint8_t* buf __attribute__((unused)), size_t maxLen __attribute__((unused))) { return 0; } }; @@ -87,9 +87,9 @@ class AsyncFileResponse : public AsyncAbstractResponse { AsyncFileResponse(FS& fs, const String& path, const String& contentType, bool download = false, AwsTemplateProcessor callback = nullptr) : AsyncFileResponse(fs, path, contentType.c_str(), download, callback) {} AsyncFileResponse(File content, const String& path, const char* contentType = asyncsrv::empty, bool download = false, AwsTemplateProcessor callback = nullptr); AsyncFileResponse(File content, const String& path, const String& contentType, bool download = false, AwsTemplateProcessor callack = nullptr) : AsyncFileResponse(content, path, contentType.c_str(), download, callack) {} - virtual ~AsyncFileResponse(); - bool _sourceValid() const { return !!(_content); } - virtual size_t _fillBuffer(uint8_t* buf, size_t maxLen) override; + ~AsyncFileResponse() { _content.close(); } + bool _sourceValid() const override final { return !!(_content); } + size_t _fillBuffer(uint8_t* buf, size_t maxLen) override final; }; class AsyncStreamResponse : public AsyncAbstractResponse { @@ -99,9 +99,8 @@ class AsyncStreamResponse : public AsyncAbstractResponse { public: AsyncStreamResponse(Stream& stream, const char* contentType, size_t len, AwsTemplateProcessor callback = nullptr); AsyncStreamResponse(Stream& stream, const String& contentType, size_t len, AwsTemplateProcessor callback = nullptr) : AsyncStreamResponse(stream, contentType.c_str(), len, callback) {} - virtual ~AsyncStreamResponse() {} - bool _sourceValid() const { return !!(_content); } - virtual size_t _fillBuffer(uint8_t* buf, size_t maxLen) override; + bool _sourceValid() const override final { return !!(_content); } + size_t _fillBuffer(uint8_t* buf, size_t maxLen) override final; }; class AsyncCallbackResponse : public AsyncAbstractResponse { @@ -112,9 +111,8 @@ class AsyncCallbackResponse : public AsyncAbstractResponse { public: AsyncCallbackResponse(const char* contentType, size_t len, AwsResponseFiller callback, AwsTemplateProcessor templateCallback = nullptr); AsyncCallbackResponse(const String& contentType, size_t len, AwsResponseFiller callback, AwsTemplateProcessor templateCallback = nullptr) : AsyncCallbackResponse(contentType.c_str(), len, callback, templateCallback) {} - virtual ~AsyncCallbackResponse() {} - bool _sourceValid() const { return !!(_content); } - virtual size_t _fillBuffer(uint8_t* buf, size_t maxLen) override; + bool _sourceValid() const override final { return !!(_content); } + size_t _fillBuffer(uint8_t* buf, size_t maxLen) override final; }; class AsyncChunkedResponse : public AsyncAbstractResponse { @@ -125,9 +123,8 @@ class AsyncChunkedResponse : public AsyncAbstractResponse { public: AsyncChunkedResponse(const char* contentType, AwsResponseFiller callback, AwsTemplateProcessor templateCallback = nullptr); AsyncChunkedResponse(const String& contentType, AwsResponseFiller callback, AwsTemplateProcessor templateCallback = nullptr) : AsyncChunkedResponse(contentType.c_str(), callback, templateCallback) {} - virtual ~AsyncChunkedResponse() {} - bool _sourceValid() const { return !!(_content); } - virtual size_t _fillBuffer(uint8_t* buf, size_t maxLen) override; + bool _sourceValid() const override final { return !!(_content); } + size_t _fillBuffer(uint8_t* buf, size_t maxLen) override final; }; class AsyncProgmemResponse : public AsyncAbstractResponse { @@ -138,23 +135,19 @@ class AsyncProgmemResponse : public AsyncAbstractResponse { public: AsyncProgmemResponse(int code, const char* contentType, const uint8_t* content, size_t len, AwsTemplateProcessor callback = nullptr); AsyncProgmemResponse(int code, const String& contentType, const uint8_t* content, size_t len, AwsTemplateProcessor callback = nullptr) : AsyncProgmemResponse(code, contentType.c_str(), content, len, callback) {} - virtual ~AsyncProgmemResponse() {} - bool _sourceValid() const { return true; } - virtual size_t _fillBuffer(uint8_t* buf, size_t maxLen) override; + bool _sourceValid() const override final { return true; } + size_t _fillBuffer(uint8_t* buf, size_t maxLen) override final; }; -class cbuf; - class AsyncResponseStream : public AsyncAbstractResponse, public Print { private: - std::unique_ptr _content; + StreamString _content; public: AsyncResponseStream(const char* contentType, size_t bufferSize); AsyncResponseStream(const String& contentType, size_t bufferSize) : AsyncResponseStream(contentType.c_str(), bufferSize) {} - virtual ~AsyncResponseStream() {} - bool _sourceValid() const { return (_state < RESPONSE_END); } - virtual size_t _fillBuffer(uint8_t* buf, size_t maxLen) override; + bool _sourceValid() const override final { return (_state < RESPONSE_END); } + size_t _fillBuffer(uint8_t* buf, size_t maxLen) override final; size_t write(const uint8_t* data, size_t len); size_t write(uint8_t data); using Print::write; diff --git a/src/WebResponses.cpp b/src/WebResponses.cpp index 23f929a5d..7a26e9233 100644 --- a/src/WebResponses.cpp +++ b/src/WebResponses.cpp @@ -20,7 +20,6 @@ */ #include "ESPAsyncWebServer.h" #include "WebResponseImpl.h" -#include "cbuf.h" using namespace asyncsrv; @@ -38,7 +37,6 @@ void* memchr(void* ptr, int ch, size_t count) { * */ -#ifndef ESP8266 const char* AsyncWebServerResponse::responseCodeToString(int code) { switch (code) { case 100: @@ -127,96 +125,6 @@ const char* AsyncWebServerResponse::responseCodeToString(int code) { return T_HTTP_CODE_ANY; } } -#else // ESP8266 -const __FlashStringHelper* AsyncWebServerResponse::responseCodeToString(int code) { - switch (code) { - case 100: - return FPSTR(T_HTTP_CODE_100); - case 101: - return FPSTR(T_HTTP_CODE_101); - case 200: - return FPSTR(T_HTTP_CODE_200); - case 201: - return FPSTR(T_HTTP_CODE_201); - case 202: - return FPSTR(T_HTTP_CODE_202); - case 203: - return FPSTR(T_HTTP_CODE_203); - case 204: - return FPSTR(T_HTTP_CODE_204); - case 205: - return FPSTR(T_HTTP_CODE_205); - case 206: - return FPSTR(T_HTTP_CODE_206); - case 300: - return FPSTR(T_HTTP_CODE_300); - case 301: - return FPSTR(T_HTTP_CODE_301); - case 302: - return FPSTR(T_HTTP_CODE_302); - case 303: - return FPSTR(T_HTTP_CODE_303); - case 304: - return FPSTR(T_HTTP_CODE_304); - case 305: - return FPSTR(T_HTTP_CODE_305); - case 307: - return FPSTR(T_HTTP_CODE_307); - case 400: - return FPSTR(T_HTTP_CODE_400); - case 401: - return FPSTR(T_HTTP_CODE_401); - case 402: - return FPSTR(T_HTTP_CODE_402); - case 403: - return FPSTR(T_HTTP_CODE_403); - case 404: - return FPSTR(T_HTTP_CODE_404); - case 405: - return FPSTR(T_HTTP_CODE_405); - case 406: - return FPSTR(T_HTTP_CODE_406); - case 407: - return FPSTR(T_HTTP_CODE_407); - case 408: - return FPSTR(T_HTTP_CODE_408); - case 409: - return FPSTR(T_HTTP_CODE_409); - case 410: - return FPSTR(T_HTTP_CODE_410); - case 411: - return FPSTR(T_HTTP_CODE_411); - case 412: - return FPSTR(T_HTTP_CODE_412); - case 413: - return FPSTR(T_HTTP_CODE_413); - case 414: - return FPSTR(T_HTTP_CODE_414); - case 415: - return FPSTR(T_HTTP_CODE_415); - case 416: - return FPSTR(T_HTTP_CODE_416); - case 417: - return FPSTR(T_HTTP_CODE_417); - case 429: - return FPSTR(T_HTTP_CODE_429); - case 500: - return FPSTR(T_HTTP_CODE_500); - case 501: - return FPSTR(T_HTTP_CODE_501); - case 502: - return FPSTR(T_HTTP_CODE_502); - case 503: - return FPSTR(T_HTTP_CODE_503); - case 504: - return FPSTR(T_HTTP_CODE_504); - case 505: - return FPSTR(T_HTTP_CODE_505); - default: - return FPSTR(T_HTTP_CODE_ANY); - } -} -#endif // ESP8266 AsyncWebServerResponse::AsyncWebServerResponse() : _code(0), _contentType(), _contentLength(0), _sendContentLength(true), _chunked(false), _headLength(0), _sentLength(0), _ackedLength(0), _writtenLength(0), _state(RESPONSE_SETUP) { @@ -646,10 +554,6 @@ size_t AsyncAbstractResponse::_fillBufferAndProcessTemplates(uint8_t* data, size * File Response * */ -AsyncFileResponse::~AsyncFileResponse() { - _content.close(); -} - void AsyncFileResponse::_setContentTypeFromPath(const String& path) { #if HAVE_EXTERN_GET_Content_Type_FUNCTION #ifndef ESP8266 @@ -865,22 +769,17 @@ AsyncResponseStream::AsyncResponseStream(const char* contentType, size_t bufferS _code = 200; _contentLength = 0; _contentType = contentType; - _content = std::unique_ptr(new cbuf(bufferSize)); // std::make_unique(bufferSize); + _content.reserve(bufferSize); } size_t AsyncResponseStream::_fillBuffer(uint8_t* buf, size_t maxLen) { - return _content->read((char*)buf, maxLen); + return _content.readBytes((char*)buf, maxLen); } size_t AsyncResponseStream::write(const uint8_t* data, size_t len) { if (_started()) return 0; - - if (len > _content->room()) { - size_t needed = len - _content->room(); - _content->resizeAdd(needed); - } - size_t written = _content->write((const char*)data, len); + size_t written = _content.write(data, len); _contentLength += written; return written; } From e0a13c8383e908638ef66a07ea3f5865d627057f Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Wed, 23 Oct 2024 16:13:13 +0200 Subject: [PATCH 460/551] Fix CI --- examples/StreamFiles/StreamFiles.ino | 6 +++-- examples/StreamFiles/StreamString.h | 40 ---------------------------- 2 files changed, 4 insertions(+), 42 deletions(-) delete mode 100644 examples/StreamFiles/StreamString.h diff --git a/examples/StreamFiles/StreamFiles.ino b/examples/StreamFiles/StreamFiles.ino index 508298d79..a0d6b9f60 100644 --- a/examples/StreamFiles/StreamFiles.ino +++ b/examples/StreamFiles/StreamFiles.ino @@ -10,11 +10,13 @@ #include #include #endif -#include "StreamConcat.h" -#include "StreamString.h" + +#include #include #include +#include "StreamConcat.h" + DNSServer dnsServer; AsyncWebServer server(80); diff --git a/examples/StreamFiles/StreamString.h b/examples/StreamFiles/StreamString.h deleted file mode 100644 index a6e0655e6..000000000 --- a/examples/StreamFiles/StreamString.h +++ /dev/null @@ -1,40 +0,0 @@ -#pragma once - -#include - -class StreamString : public Stream { - public: - size_t write(const uint8_t* p, size_t n) override { return _buffer.concat(reinterpret_cast(p), n) ? n : 0; } - size_t write(uint8_t c) override { return _buffer.concat(static_cast(c)) ? 1 : 0; } - void flush() override {} - - int available() override { return static_cast(_buffer.length()); } - - int read() override { - if (_buffer.length() == 0) - return -1; - char c = _buffer[0]; - _buffer.remove(0, 1); - return c; - } - -#if defined(TARGET_RP2040) - size_t readBytes(char* buffer, size_t length) { -#else - size_t readBytes(char* buffer, size_t length) override { -#endif - if (length > _buffer.length()) - length = _buffer.length(); - // Don't use _str.ToCharArray() because it inserts a terminator - memcpy(buffer, _buffer.c_str(), length); - _buffer.remove(0, static_cast(length)); - return length; - } - - int peek() override { return _buffer.length() > 0 ? _buffer[0] : -1; } - - const String& buffer() const { return _buffer; } - - private: - String _buffer; -}; From dbf00e302f1498dd789ff7f003ed19732f0a1b2a Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Wed, 23 Oct 2024 16:24:14 +0200 Subject: [PATCH 461/551] Try fix ci --- platformio.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platformio.ini b/platformio.ini index d6ab05c76..0c0cca6db 100644 --- a/platformio.ini +++ b/platformio.ini @@ -83,7 +83,7 @@ lib_deps = [env:raspberrypi] upload_protocol = picotool ; platform = raspberrypi -platform = https://github.com/maxgerhardt/platform-raspberrypi.git#f2687073f73d554c9db41f29b4769fd9703f4e55 +platform = https://github.com/maxgerhardt/platform-raspberrypi#v1.2.0-gcc12 board = rpipicow lib_deps = bblanchon/ArduinoJson @ 7.2.0 From 50ea5eedb7f146805b1ff070478b171159a3e746 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Wed, 23 Oct 2024 16:32:51 +0200 Subject: [PATCH 462/551] Disabling RPI in CI. Issue: https://github.com/maxgerhardt/platform-raspberrypi/issues/83 --- .github/workflows/ci.yml | 4 ++-- platformio.ini | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 39d770236..c7b10432f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -127,8 +127,8 @@ jobs: - env: ci-esp8266 board: d1_mini - - env: ci-raspberrypi - board: rpipicow + # - env: ci-raspberrypi + # board: rpipicow steps: - name: Checkout uses: actions/checkout@v4 diff --git a/platformio.ini b/platformio.ini index 0c0cca6db..c03107661 100644 --- a/platformio.ini +++ b/platformio.ini @@ -82,8 +82,8 @@ lib_deps = ; board settings: https://github.com/earlephilhower/arduino-pico/blob/master/tools/json/rpipico.json [env:raspberrypi] upload_protocol = picotool -; platform = raspberrypi -platform = https://github.com/maxgerhardt/platform-raspberrypi#v1.2.0-gcc12 +platform = raspberrypi +; platform = https://github.com/maxgerhardt/platform-raspberrypi#v1.2.0-gcc12 board = rpipicow lib_deps = bblanchon/ArduinoJson @ 7.2.0 From 97fbadf2f4553610750b718312f108d6eace47e8 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Wed, 23 Oct 2024 16:33:47 +0200 Subject: [PATCH 463/551] v3.3.19 --- README.md | 6 +++--- docs/index.md | 6 +++--- library.json | 2 +- library.properties | 2 +- src/ESPAsyncWebServer.h | 4 ++-- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 71bd065a8..0a94524c0 100644 --- a/README.md +++ b/README.md @@ -61,7 +61,7 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo ```ini lib_compat_mode = strict lib_ldf_mode = chain -lib_deps = mathieucarbou/ESPAsyncWebServer @ 3.3.18 +lib_deps = mathieucarbou/ESPAsyncWebServer @ 3.3.19 ``` **Dependencies:** @@ -87,7 +87,7 @@ lib_ldf_mode = chain lib_deps = ; mathieucarbou/AsyncTCP @ 3.2.10 https://github.com/mathieucarbou/AsyncTCPSock/archive/refs/tags/v1.0.3-dev.zip - mathieucarbou/ESPAsyncWebServer @ 3.3.18 + mathieucarbou/ESPAsyncWebServer @ 3.3.19 lib_ignore = AsyncTCP mathieucarbou/AsyncTCP @@ -95,7 +95,7 @@ lib_ignore = ## Performance -Performance of `mathieucarbou/ESPAsyncWebServer @ 3.3.18`: +Performance of `mathieucarbou/ESPAsyncWebServer @ 3.3.19`: ```bash > brew install autocannon diff --git a/docs/index.md b/docs/index.md index 71bd065a8..0a94524c0 100644 --- a/docs/index.md +++ b/docs/index.md @@ -61,7 +61,7 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo ```ini lib_compat_mode = strict lib_ldf_mode = chain -lib_deps = mathieucarbou/ESPAsyncWebServer @ 3.3.18 +lib_deps = mathieucarbou/ESPAsyncWebServer @ 3.3.19 ``` **Dependencies:** @@ -87,7 +87,7 @@ lib_ldf_mode = chain lib_deps = ; mathieucarbou/AsyncTCP @ 3.2.10 https://github.com/mathieucarbou/AsyncTCPSock/archive/refs/tags/v1.0.3-dev.zip - mathieucarbou/ESPAsyncWebServer @ 3.3.18 + mathieucarbou/ESPAsyncWebServer @ 3.3.19 lib_ignore = AsyncTCP mathieucarbou/AsyncTCP @@ -95,7 +95,7 @@ lib_ignore = ## Performance -Performance of `mathieucarbou/ESPAsyncWebServer @ 3.3.18`: +Performance of `mathieucarbou/ESPAsyncWebServer @ 3.3.19`: ```bash > brew install autocannon diff --git a/library.json b/library.json index fc92824eb..99303b213 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "ESPAsyncWebServer", - "version": "3.3.18", + "version": "3.3.19", "description": "Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 and RP2040. Supports: WebSocket, SSE, Authentication, Arduino Json 7, File Upload, Static File serving, URL Rewrite, URL Redirect, etc.", "keywords": "http,async,websocket,webserver", "homepage": "https://github.com/mathieucarbou/ESPAsyncWebServer", diff --git a/library.properties b/library.properties index 5a7e22763..a08010d7f 100644 --- a/library.properties +++ b/library.properties @@ -1,6 +1,6 @@ name=ESP Async WebServer includes=ESPAsyncWebServer.h -version=3.3.18 +version=3.3.19 author=Me-No-Dev maintainer=Mathieu Carbou sentence=Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 and RP2040 diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index b7b22ec1f..d27880706 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -48,10 +48,10 @@ #include "literals.h" -#define ASYNCWEBSERVER_VERSION "3.3.18" +#define ASYNCWEBSERVER_VERSION "3.3.19" #define ASYNCWEBSERVER_VERSION_MAJOR 3 #define ASYNCWEBSERVER_VERSION_MINOR 3 -#define ASYNCWEBSERVER_VERSION_REVISION 18 +#define ASYNCWEBSERVER_VERSION_REVISION 19 #define ASYNCWEBSERVER_FORK_mathieucarbou #ifdef ASYNCWEBSERVER_REGEX From a7c9effc856cb33cf8a2ccf82870e31d6769dc74 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Thu, 24 Oct 2024 10:11:39 +0200 Subject: [PATCH 464/551] Fix #143: doc updated --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0a94524c0..1a4acbd16 100644 --- a/README.md +++ b/README.md @@ -1261,7 +1261,7 @@ class OneParamRewrite : public AsyncWebRewrite _paramsBackup = _params; } - bool match(AsyncWebServerRequest *request) override { + bool match(AsyncWebServerRequest *request) const override { if(request->url().startsWith(_urlPrefix)) { if(_paramIndex >= 0) { _params = _paramsBackup + request->url().substring(_paramIndex); From 41d6ccb97c0852968a099a6d290885ec3653eab1 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Thu, 24 Oct 2024 10:21:17 +0200 Subject: [PATCH 465/551] Fix #143: doc re-updated and const removed --- README.md | 4 ++-- src/ESPAsyncWebServer.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 1a4acbd16..b56315021 100644 --- a/README.md +++ b/README.md @@ -1232,7 +1232,7 @@ For actual serving the file. ### Param Rewrite With Matching -It is possible to rewrite the request url with parameter matchg. Here is an example with one parameter: +It is possible to rewrite the request url with parameter match. Here is an example with one parameter: Rewrite for example "/radio/{frequence}" -> "/radio?f={frequence}" ```cpp @@ -1261,7 +1261,7 @@ class OneParamRewrite : public AsyncWebRewrite _paramsBackup = _params; } - bool match(AsyncWebServerRequest *request) const override { + bool match(AsyncWebServerRequest *request) override { if(request->url().startsWith(_urlPrefix)) { if(_paramIndex >= 0) { _params = _paramsBackup + request->url().substring(_paramIndex); diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index d27880706..9c915e2de 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -717,7 +717,7 @@ class AsyncWebRewrite { const String& from(void) const { return _from; } const String& toUrl(void) const { return _toUrl; } const String& params(void) const { return _params; } - virtual bool match(AsyncWebServerRequest* request) const { return from() == request->url() && filter(request); } + virtual bool match(AsyncWebServerRequest* request) { return from() == request->url() && filter(request); } }; /* From cf641d2aafd7a57d2969ab2cfb282e761a5998f6 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Thu, 24 Oct 2024 10:22:08 +0200 Subject: [PATCH 466/551] v3.3.20 --- README.md | 6 +++--- docs/index.md | 6 +++--- library.json | 2 +- library.properties | 2 +- src/ESPAsyncWebServer.h | 4 ++-- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index b56315021..514b4edc7 100644 --- a/README.md +++ b/README.md @@ -61,7 +61,7 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo ```ini lib_compat_mode = strict lib_ldf_mode = chain -lib_deps = mathieucarbou/ESPAsyncWebServer @ 3.3.19 +lib_deps = mathieucarbou/ESPAsyncWebServer @ 3.3.20 ``` **Dependencies:** @@ -87,7 +87,7 @@ lib_ldf_mode = chain lib_deps = ; mathieucarbou/AsyncTCP @ 3.2.10 https://github.com/mathieucarbou/AsyncTCPSock/archive/refs/tags/v1.0.3-dev.zip - mathieucarbou/ESPAsyncWebServer @ 3.3.19 + mathieucarbou/ESPAsyncWebServer @ 3.3.20 lib_ignore = AsyncTCP mathieucarbou/AsyncTCP @@ -95,7 +95,7 @@ lib_ignore = ## Performance -Performance of `mathieucarbou/ESPAsyncWebServer @ 3.3.19`: +Performance of `mathieucarbou/ESPAsyncWebServer @ 3.3.20`: ```bash > brew install autocannon diff --git a/docs/index.md b/docs/index.md index 0a94524c0..01dc78c0a 100644 --- a/docs/index.md +++ b/docs/index.md @@ -61,7 +61,7 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo ```ini lib_compat_mode = strict lib_ldf_mode = chain -lib_deps = mathieucarbou/ESPAsyncWebServer @ 3.3.19 +lib_deps = mathieucarbou/ESPAsyncWebServer @ 3.3.20 ``` **Dependencies:** @@ -87,7 +87,7 @@ lib_ldf_mode = chain lib_deps = ; mathieucarbou/AsyncTCP @ 3.2.10 https://github.com/mathieucarbou/AsyncTCPSock/archive/refs/tags/v1.0.3-dev.zip - mathieucarbou/ESPAsyncWebServer @ 3.3.19 + mathieucarbou/ESPAsyncWebServer @ 3.3.20 lib_ignore = AsyncTCP mathieucarbou/AsyncTCP @@ -95,7 +95,7 @@ lib_ignore = ## Performance -Performance of `mathieucarbou/ESPAsyncWebServer @ 3.3.19`: +Performance of `mathieucarbou/ESPAsyncWebServer @ 3.3.20`: ```bash > brew install autocannon diff --git a/library.json b/library.json index 99303b213..f14d82116 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "ESPAsyncWebServer", - "version": "3.3.19", + "version": "3.3.20", "description": "Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 and RP2040. Supports: WebSocket, SSE, Authentication, Arduino Json 7, File Upload, Static File serving, URL Rewrite, URL Redirect, etc.", "keywords": "http,async,websocket,webserver", "homepage": "https://github.com/mathieucarbou/ESPAsyncWebServer", diff --git a/library.properties b/library.properties index a08010d7f..fb9234043 100644 --- a/library.properties +++ b/library.properties @@ -1,6 +1,6 @@ name=ESP Async WebServer includes=ESPAsyncWebServer.h -version=3.3.19 +version=3.3.20 author=Me-No-Dev maintainer=Mathieu Carbou sentence=Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 and RP2040 diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index 9c915e2de..510367210 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -48,10 +48,10 @@ #include "literals.h" -#define ASYNCWEBSERVER_VERSION "3.3.19" +#define ASYNCWEBSERVER_VERSION "3.3.20" #define ASYNCWEBSERVER_VERSION_MAJOR 3 #define ASYNCWEBSERVER_VERSION_MINOR 3 -#define ASYNCWEBSERVER_VERSION_REVISION 19 +#define ASYNCWEBSERVER_VERSION_REVISION 20 #define ASYNCWEBSERVER_FORK_mathieucarbou #ifdef ASYNCWEBSERVER_REGEX From 67de9cddbbf0d024c61a314bacd204ba6101fac8 Mon Sep 17 00:00:00 2001 From: dl9rdz Date: Fri, 25 Oct 2024 07:46:40 +0000 Subject: [PATCH 467/551] tentative fix (#1436) Co-authored-by: Hans P. Reiser --- src/WebResponses.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/WebResponses.cpp b/src/WebResponses.cpp index a22e991aa..3000c7201 100644 --- a/src/WebResponses.cpp +++ b/src/WebResponses.cpp @@ -312,13 +312,14 @@ size_t AsyncAbstractResponse::_ack(AsyncWebServerRequest *request, size_t len, u if(_chunked){ // HTTP 1.1 allows leading zeros in chunk length. Or spaces may be added. // See RFC2616 sections 2, 3.6.1. + // -- OR NOT: There is nothing about spaces there, and it breaks Webkit browsers on iOS! readLen = _fillBufferAndProcessTemplates(buf+headLen+6, outLen - 8); if(readLen == RESPONSE_TRY_AGAIN){ free(buf); return 0; } - outLen = sprintf((char*)buf+headLen, "%x", readLen) + headLen; - while(outLen < headLen + 4) buf[outLen++] = ' '; + outLen = sprintf((char*)buf+headLen, "%04x", readLen) + headLen; + // while(outLen < headLen + 4) buf[outLen++] = ' '; buf[outLen++] = '\r'; buf[outLen++] = '\n'; outLen += readLen; From fc59baaffd44a8a6665d03709a687db930461429 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Fri, 25 Oct 2024 22:51:23 +0200 Subject: [PATCH 468/551] pioardiono 53.03.10-rc2 --- .github/workflows/ci.yml | 12 ++++++------ platformio.ini | 14 +++++++------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c7b10432f..6621b622c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -109,17 +109,17 @@ jobs: - env: ci-arduino-3-no-json board: esp32dev - - env: ci-arduino-310rc1 + - env: ci-arduino-310 board: esp32dev - - env: ci-arduino-310rc1 + - env: ci-arduino-310 board: esp32-s2-saola-1 - - env: ci-arduino-310rc1 + - env: ci-arduino-310 board: esp32-s3-devkitc-1 - - env: ci-arduino-310rc1 + - env: ci-arduino-310 board: esp32-c3-devkitc-02 - - env: ci-arduino-310rc1 + - env: ci-arduino-310 board: esp32-c6-devkitc-1 - - env: ci-arduino-310rc1 + - env: ci-arduino-310 board: esp32-h2-devkitm-1 - env: ci-esp8266 diff --git a/platformio.ini b/platformio.ini index c03107661..ba40955ee 100644 --- a/platformio.ini +++ b/platformio.ini @@ -1,5 +1,5 @@ [platformio] -default_envs = arduino-2, arduino-3, arduino-310rc1, esp8266, raspberrypi +default_envs = arduino-2, arduino-3, arduino-310, esp8266, raspberrypi lib_dir = . ; src_dir = examples/CaptivePortal src_dir = examples/SimpleServer @@ -50,19 +50,19 @@ platform = https://github.com/pioarduino/platform-espressif32/releases/download/ lib_deps = mathieucarbou/AsyncTCP @ 3.2.10 -[env:arduino-310rc1] -platform = https://github.com/pioarduino/platform-espressif32/releases/download/53.03.10-rc1/platform-espressif32.zip +[env:arduino-310] +platform = https://github.com/pioarduino/platform-espressif32/releases/download/53.03.10-rc2/platform-espressif32.zip ; board = esp32-s3-devkitc-1 ; board = esp32-c6-devkitc-1 ; board = esp32-h2-devkitm-1 [env:perf-test-AsyncTCP] -platform = https://github.com/pioarduino/platform-espressif32/releases/download/53.03.10-rc1/platform-espressif32.zip +platform = https://github.com/pioarduino/platform-espressif32/releases/download/53.03.10-rc2/platform-espressif32.zip build_flags = ${env.build_flags} -D PERF_TEST=1 [env:perf-test-AsyncTCPSock] -platform = https://github.com/pioarduino/platform-espressif32/releases/download/53.03.10-rc1/platform-espressif32.zip +platform = https://github.com/pioarduino/platform-espressif32/releases/download/53.03.10-rc2/platform-espressif32.zip lib_deps = https://github.com/mathieucarbou/AsyncTCPSock/archive/refs/tags/v1.0.3-dev.zip build_flags = ${env.build_flags} @@ -107,8 +107,8 @@ board = ${sysenv.PIO_BOARD} lib_deps = mathieucarbou/AsyncTCP @ 3.2.10 -[env:ci-arduino-310rc1] -platform = https://github.com/pioarduino/platform-espressif32/releases/download/53.03.10-rc1/platform-espressif32.zip +[env:ci-arduino-310] +platform = https://github.com/pioarduino/platform-espressif32/releases/download/53.03.10-rc2/platform-espressif32.zip board = ${sysenv.PIO_BOARD} [env:ci-esp8266] From 481f8f748ea6bda6aa328823e7fc94a208e8bbdc Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Sat, 26 Oct 2024 12:36:15 +0200 Subject: [PATCH 469/551] mathieucarbou/AsyncTCP @ 3.2.11 --- .github/workflows/ci.yml | 2 +- README.md | 8 ++++---- docs/index.md | 8 ++++---- library.json | 2 +- platformio.ini | 6 +++--- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6621b622c..a1222ea70 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -55,7 +55,7 @@ jobs: - name: Install AsyncTCP (ESP32) if: ${{ matrix.core == 'esp32:esp32' }} - run: ARDUINO_LIBRARY_ENABLE_UNSAFE_INSTALL=true arduino-cli lib install --git-url https://github.com/mathieucarbou/AsyncTCP#v3.2.10 + run: ARDUINO_LIBRARY_ENABLE_UNSAFE_INSTALL=true arduino-cli lib install --git-url https://github.com/mathieucarbou/AsyncTCP#v3.2.11 - name: Install ESPAsyncTCP (ESP8266) if: ${{ matrix.core == 'esp8266:esp8266' }} diff --git a/README.md b/README.md index 514b4edc7..d6687b69d 100644 --- a/README.md +++ b/README.md @@ -66,8 +66,8 @@ lib_deps = mathieucarbou/ESPAsyncWebServer @ 3.3.20 **Dependencies:** -- **ESP32 with AsyncTCP**: `mathieucarbou/AsyncTCP @ 3.2.10` - Arduino IDE: [https://github.com/mathieucarbou/AsyncTCP#v3.2.10](https://github.com/mathieucarbou/AsyncTCP/releases) +- **ESP32 with AsyncTCP**: `mathieucarbou/AsyncTCP @ 3.2.11` + Arduino IDE: [https://github.com/mathieucarbou/AsyncTCP#v3.2.11](https://github.com/mathieucarbou/AsyncTCP/releases) - **ESP32 with AsyncTCPSock**: `https://github.com/mathieucarbou/AsyncTCPSock/archive/refs/tags/v1.0.3-dev.zip` @@ -85,7 +85,7 @@ AsyncTCPSock can be used instead of AsyncTCP by excluding AsyncTCP from the libr lib_compat_mode = strict lib_ldf_mode = chain lib_deps = - ; mathieucarbou/AsyncTCP @ 3.2.10 + ; mathieucarbou/AsyncTCP @ 3.2.11 https://github.com/mathieucarbou/AsyncTCPSock/archive/refs/tags/v1.0.3-dev.zip mathieucarbou/ESPAsyncWebServer @ 3.3.20 lib_ignore = @@ -102,7 +102,7 @@ Performance of `mathieucarbou/ESPAsyncWebServer @ 3.3.20`: > autocannon -c 10 -w 10 -d 20 http://192.168.4.1 ``` -With `mathieucarbou/AsyncTCP @ 3.2.10` +With `mathieucarbou/AsyncTCP @ 3.2.11` [![](https://mathieu.carbou.me/ESPAsyncWebServer/perf-c10.png)](https://mathieu.carbou.me/ESPAsyncWebServer/perf-c10.png) diff --git a/docs/index.md b/docs/index.md index 01dc78c0a..c52425e36 100644 --- a/docs/index.md +++ b/docs/index.md @@ -66,8 +66,8 @@ lib_deps = mathieucarbou/ESPAsyncWebServer @ 3.3.20 **Dependencies:** -- **ESP32 with AsyncTCP**: `mathieucarbou/AsyncTCP @ 3.2.10` - Arduino IDE: [https://github.com/mathieucarbou/AsyncTCP#v3.2.10](https://github.com/mathieucarbou/AsyncTCP/releases) +- **ESP32 with AsyncTCP**: `mathieucarbou/AsyncTCP @ 3.2.11` + Arduino IDE: [https://github.com/mathieucarbou/AsyncTCP#v3.2.11](https://github.com/mathieucarbou/AsyncTCP/releases) - **ESP32 with AsyncTCPSock**: `https://github.com/mathieucarbou/AsyncTCPSock/archive/refs/tags/v1.0.3-dev.zip` @@ -85,7 +85,7 @@ AsyncTCPSock can be used instead of AsyncTCP by excluding AsyncTCP from the libr lib_compat_mode = strict lib_ldf_mode = chain lib_deps = - ; mathieucarbou/AsyncTCP @ 3.2.10 + ; mathieucarbou/AsyncTCP @ 3.2.11 https://github.com/mathieucarbou/AsyncTCPSock/archive/refs/tags/v1.0.3-dev.zip mathieucarbou/ESPAsyncWebServer @ 3.3.20 lib_ignore = @@ -102,7 +102,7 @@ Performance of `mathieucarbou/ESPAsyncWebServer @ 3.3.20`: > autocannon -c 10 -w 10 -d 20 http://192.168.4.1 ``` -With `mathieucarbou/AsyncTCP @ 3.2.10` +With `mathieucarbou/AsyncTCP @ 3.2.11` [![](https://mathieu.carbou.me/ESPAsyncWebServer/perf-c10.png)](https://mathieu.carbou.me/ESPAsyncWebServer/perf-c10.png) diff --git a/library.json b/library.json index f14d82116..3b3d4ffbe 100644 --- a/library.json +++ b/library.json @@ -28,7 +28,7 @@ { "owner": "mathieucarbou", "name": "AsyncTCP", - "version": "^3.2.10", + "version": "^3.2.11", "platforms": "espressif32" }, { diff --git a/platformio.ini b/platformio.ini index ba40955ee..d9740c503 100644 --- a/platformio.ini +++ b/platformio.ini @@ -30,7 +30,7 @@ lib_deps = ; bblanchon/ArduinoJson @ 5.13.4 ; bblanchon/ArduinoJson @ 6.21.5 bblanchon/ArduinoJson @ 7.2.0 - mathieucarbou/AsyncTCP @ 3.2.10 + mathieucarbou/AsyncTCP @ 3.2.11 board = esp32dev board_build.partitions = partitions-4MB.csv board_build.filesystem = littlefs @@ -48,7 +48,7 @@ platform = https://github.com/pioarduino/platform-espressif32/releases/download/ ; board = esp32-s3-devkitc-1 ; board = esp32-c6-devkitc-1 lib_deps = - mathieucarbou/AsyncTCP @ 3.2.10 + mathieucarbou/AsyncTCP @ 3.2.11 [env:arduino-310] platform = https://github.com/pioarduino/platform-espressif32/releases/download/53.03.10-rc2/platform-espressif32.zip @@ -105,7 +105,7 @@ board = ${sysenv.PIO_BOARD} platform = https://github.com/pioarduino/platform-espressif32/releases/download/51.03.05/platform-espressif32.zip board = ${sysenv.PIO_BOARD} lib_deps = - mathieucarbou/AsyncTCP @ 3.2.10 + mathieucarbou/AsyncTCP @ 3.2.11 [env:ci-arduino-310] platform = https://github.com/pioarduino/platform-espressif32/releases/download/53.03.10-rc2/platform-espressif32.zip From 665dbc4a865caa9e25dfc1f08de5954116b7fdc3 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Sun, 27 Oct 2024 08:49:06 +0100 Subject: [PATCH 470/551] mathieucarbou/AsyncTCP @ 3.2.12 --- .github/workflows/ci.yml | 2 +- README.md | 8 ++++---- docs/index.md | 8 ++++---- library.json | 2 +- platformio.ini | 6 +++--- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a1222ea70..7e712f11a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -55,7 +55,7 @@ jobs: - name: Install AsyncTCP (ESP32) if: ${{ matrix.core == 'esp32:esp32' }} - run: ARDUINO_LIBRARY_ENABLE_UNSAFE_INSTALL=true arduino-cli lib install --git-url https://github.com/mathieucarbou/AsyncTCP#v3.2.11 + run: ARDUINO_LIBRARY_ENABLE_UNSAFE_INSTALL=true arduino-cli lib install --git-url https://github.com/mathieucarbou/AsyncTCP#v3.2.12 - name: Install ESPAsyncTCP (ESP8266) if: ${{ matrix.core == 'esp8266:esp8266' }} diff --git a/README.md b/README.md index d6687b69d..e454d276c 100644 --- a/README.md +++ b/README.md @@ -66,8 +66,8 @@ lib_deps = mathieucarbou/ESPAsyncWebServer @ 3.3.20 **Dependencies:** -- **ESP32 with AsyncTCP**: `mathieucarbou/AsyncTCP @ 3.2.11` - Arduino IDE: [https://github.com/mathieucarbou/AsyncTCP#v3.2.11](https://github.com/mathieucarbou/AsyncTCP/releases) +- **ESP32 with AsyncTCP**: `mathieucarbou/AsyncTCP @ 3.2.12` + Arduino IDE: [https://github.com/mathieucarbou/AsyncTCP#v3.2.12](https://github.com/mathieucarbou/AsyncTCP/releases) - **ESP32 with AsyncTCPSock**: `https://github.com/mathieucarbou/AsyncTCPSock/archive/refs/tags/v1.0.3-dev.zip` @@ -85,7 +85,7 @@ AsyncTCPSock can be used instead of AsyncTCP by excluding AsyncTCP from the libr lib_compat_mode = strict lib_ldf_mode = chain lib_deps = - ; mathieucarbou/AsyncTCP @ 3.2.11 + ; mathieucarbou/AsyncTCP @ 3.2.12 https://github.com/mathieucarbou/AsyncTCPSock/archive/refs/tags/v1.0.3-dev.zip mathieucarbou/ESPAsyncWebServer @ 3.3.20 lib_ignore = @@ -102,7 +102,7 @@ Performance of `mathieucarbou/ESPAsyncWebServer @ 3.3.20`: > autocannon -c 10 -w 10 -d 20 http://192.168.4.1 ``` -With `mathieucarbou/AsyncTCP @ 3.2.11` +With `mathieucarbou/AsyncTCP @ 3.2.12` [![](https://mathieu.carbou.me/ESPAsyncWebServer/perf-c10.png)](https://mathieu.carbou.me/ESPAsyncWebServer/perf-c10.png) diff --git a/docs/index.md b/docs/index.md index c52425e36..f43e36124 100644 --- a/docs/index.md +++ b/docs/index.md @@ -66,8 +66,8 @@ lib_deps = mathieucarbou/ESPAsyncWebServer @ 3.3.20 **Dependencies:** -- **ESP32 with AsyncTCP**: `mathieucarbou/AsyncTCP @ 3.2.11` - Arduino IDE: [https://github.com/mathieucarbou/AsyncTCP#v3.2.11](https://github.com/mathieucarbou/AsyncTCP/releases) +- **ESP32 with AsyncTCP**: `mathieucarbou/AsyncTCP @ 3.2.12` + Arduino IDE: [https://github.com/mathieucarbou/AsyncTCP#v3.2.12](https://github.com/mathieucarbou/AsyncTCP/releases) - **ESP32 with AsyncTCPSock**: `https://github.com/mathieucarbou/AsyncTCPSock/archive/refs/tags/v1.0.3-dev.zip` @@ -85,7 +85,7 @@ AsyncTCPSock can be used instead of AsyncTCP by excluding AsyncTCP from the libr lib_compat_mode = strict lib_ldf_mode = chain lib_deps = - ; mathieucarbou/AsyncTCP @ 3.2.11 + ; mathieucarbou/AsyncTCP @ 3.2.12 https://github.com/mathieucarbou/AsyncTCPSock/archive/refs/tags/v1.0.3-dev.zip mathieucarbou/ESPAsyncWebServer @ 3.3.20 lib_ignore = @@ -102,7 +102,7 @@ Performance of `mathieucarbou/ESPAsyncWebServer @ 3.3.20`: > autocannon -c 10 -w 10 -d 20 http://192.168.4.1 ``` -With `mathieucarbou/AsyncTCP @ 3.2.11` +With `mathieucarbou/AsyncTCP @ 3.2.12` [![](https://mathieu.carbou.me/ESPAsyncWebServer/perf-c10.png)](https://mathieu.carbou.me/ESPAsyncWebServer/perf-c10.png) diff --git a/library.json b/library.json index 3b3d4ffbe..e51896de3 100644 --- a/library.json +++ b/library.json @@ -28,7 +28,7 @@ { "owner": "mathieucarbou", "name": "AsyncTCP", - "version": "^3.2.11", + "version": "^3.2.12", "platforms": "espressif32" }, { diff --git a/platformio.ini b/platformio.ini index d9740c503..317fb0047 100644 --- a/platformio.ini +++ b/platformio.ini @@ -30,7 +30,7 @@ lib_deps = ; bblanchon/ArduinoJson @ 5.13.4 ; bblanchon/ArduinoJson @ 6.21.5 bblanchon/ArduinoJson @ 7.2.0 - mathieucarbou/AsyncTCP @ 3.2.11 + mathieucarbou/AsyncTCP @ 3.2.12 board = esp32dev board_build.partitions = partitions-4MB.csv board_build.filesystem = littlefs @@ -48,7 +48,7 @@ platform = https://github.com/pioarduino/platform-espressif32/releases/download/ ; board = esp32-s3-devkitc-1 ; board = esp32-c6-devkitc-1 lib_deps = - mathieucarbou/AsyncTCP @ 3.2.11 + mathieucarbou/AsyncTCP @ 3.2.12 [env:arduino-310] platform = https://github.com/pioarduino/platform-espressif32/releases/download/53.03.10-rc2/platform-espressif32.zip @@ -105,7 +105,7 @@ board = ${sysenv.PIO_BOARD} platform = https://github.com/pioarduino/platform-espressif32/releases/download/51.03.05/platform-espressif32.zip board = ${sysenv.PIO_BOARD} lib_deps = - mathieucarbou/AsyncTCP @ 3.2.11 + mathieucarbou/AsyncTCP @ 3.2.12 [env:ci-arduino-310] platform = https://github.com/pioarduino/platform-espressif32/releases/download/53.03.10-rc2/platform-espressif32.zip From 5021dd0b7d216941685f02df6ca418e3fbdcc928 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Sun, 27 Oct 2024 08:51:40 +0100 Subject: [PATCH 471/551] v3.3.21 --- README.md | 6 +++--- docs/index.md | 6 +++--- library.json | 2 +- library.properties | 2 +- src/ESPAsyncWebServer.h | 4 ++-- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index e454d276c..de2cde5ff 100644 --- a/README.md +++ b/README.md @@ -61,7 +61,7 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo ```ini lib_compat_mode = strict lib_ldf_mode = chain -lib_deps = mathieucarbou/ESPAsyncWebServer @ 3.3.20 +lib_deps = mathieucarbou/ESPAsyncWebServer @ 3.3.21 ``` **Dependencies:** @@ -87,7 +87,7 @@ lib_ldf_mode = chain lib_deps = ; mathieucarbou/AsyncTCP @ 3.2.12 https://github.com/mathieucarbou/AsyncTCPSock/archive/refs/tags/v1.0.3-dev.zip - mathieucarbou/ESPAsyncWebServer @ 3.3.20 + mathieucarbou/ESPAsyncWebServer @ 3.3.21 lib_ignore = AsyncTCP mathieucarbou/AsyncTCP @@ -95,7 +95,7 @@ lib_ignore = ## Performance -Performance of `mathieucarbou/ESPAsyncWebServer @ 3.3.20`: +Performance of `mathieucarbou/ESPAsyncWebServer @ 3.3.21`: ```bash > brew install autocannon diff --git a/docs/index.md b/docs/index.md index f43e36124..ac0547df4 100644 --- a/docs/index.md +++ b/docs/index.md @@ -61,7 +61,7 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo ```ini lib_compat_mode = strict lib_ldf_mode = chain -lib_deps = mathieucarbou/ESPAsyncWebServer @ 3.3.20 +lib_deps = mathieucarbou/ESPAsyncWebServer @ 3.3.21 ``` **Dependencies:** @@ -87,7 +87,7 @@ lib_ldf_mode = chain lib_deps = ; mathieucarbou/AsyncTCP @ 3.2.12 https://github.com/mathieucarbou/AsyncTCPSock/archive/refs/tags/v1.0.3-dev.zip - mathieucarbou/ESPAsyncWebServer @ 3.3.20 + mathieucarbou/ESPAsyncWebServer @ 3.3.21 lib_ignore = AsyncTCP mathieucarbou/AsyncTCP @@ -95,7 +95,7 @@ lib_ignore = ## Performance -Performance of `mathieucarbou/ESPAsyncWebServer @ 3.3.20`: +Performance of `mathieucarbou/ESPAsyncWebServer @ 3.3.21`: ```bash > brew install autocannon diff --git a/library.json b/library.json index e51896de3..c0e428f54 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "ESPAsyncWebServer", - "version": "3.3.20", + "version": "3.3.21", "description": "Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 and RP2040. Supports: WebSocket, SSE, Authentication, Arduino Json 7, File Upload, Static File serving, URL Rewrite, URL Redirect, etc.", "keywords": "http,async,websocket,webserver", "homepage": "https://github.com/mathieucarbou/ESPAsyncWebServer", diff --git a/library.properties b/library.properties index fb9234043..b33948e96 100644 --- a/library.properties +++ b/library.properties @@ -1,6 +1,6 @@ name=ESP Async WebServer includes=ESPAsyncWebServer.h -version=3.3.20 +version=3.3.21 author=Me-No-Dev maintainer=Mathieu Carbou sentence=Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 and RP2040 diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index 510367210..5a64179da 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -48,10 +48,10 @@ #include "literals.h" -#define ASYNCWEBSERVER_VERSION "3.3.20" +#define ASYNCWEBSERVER_VERSION "3.3.21" #define ASYNCWEBSERVER_VERSION_MAJOR 3 #define ASYNCWEBSERVER_VERSION_MINOR 3 -#define ASYNCWEBSERVER_VERSION_REVISION 20 +#define ASYNCWEBSERVER_VERSION_REVISION 21 #define ASYNCWEBSERVER_FORK_mathieucarbou #ifdef ASYNCWEBSERVER_REGEX From 96b60370d3f00643778c4831b6f8d3c92ecfb98d Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Mon, 28 Oct 2024 22:14:18 +0100 Subject: [PATCH 472/551] Try re-activate RPI --- .github/workflows/ci.yml | 4 ++-- platformio.ini | 15 ++++++--------- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7e712f11a..c062a23ef 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -127,8 +127,8 @@ jobs: - env: ci-esp8266 board: d1_mini - # - env: ci-raspberrypi - # board: rpipicow + - env: ci-raspberrypi + board: rpipicow steps: - name: Checkout uses: actions/checkout@v4 diff --git a/platformio.ini b/platformio.ini index 317fb0047..cb76487bb 100644 --- a/platformio.ini +++ b/platformio.ini @@ -76,15 +76,11 @@ lib_deps = bblanchon/ArduinoJson @ 7.2.0 esphome/ESPAsyncTCP-esphome @ 2.0.0 -; PlatformIO support for Raspberry Pi Pico is not official -; https://github.com/platformio/platform-raspberrypi/pull/36 -; https://github.com/earlephilhower/arduino-pico/blob/master/docs/platformio.rst -; board settings: https://github.com/earlephilhower/arduino-pico/blob/master/tools/json/rpipico.json [env:raspberrypi] -upload_protocol = picotool -platform = raspberrypi -; platform = https://github.com/maxgerhardt/platform-raspberrypi#v1.2.0-gcc12 +platform = https://github.com/maxgerhardt/platform-raspberrypi.git board = rpipicow +lib_ldf_mode = chain +lib_compat_mode = soft lib_deps = bblanchon/ArduinoJson @ 7.2.0 khoih-prog/AsyncTCP_RP2040W @ 1.2.0 @@ -119,9 +115,10 @@ lib_deps = esphome/ESPAsyncTCP-esphome @ 2.0.0 [env:ci-raspberrypi] -; platform = raspberrypi -platform = https://github.com/maxgerhardt/platform-raspberrypi.git#f2687073f73d554c9db41f29b4769fd9703f4e55 +platform = https://github.com/maxgerhardt/platform-raspberrypi.git board = ${sysenv.PIO_BOARD} +lib_ldf_mode = chain +lib_compat_mode = soft lib_deps = bblanchon/ArduinoJson @ 7.2.0 khoih-prog/AsyncTCP_RP2040W @ 1.2.0 From 05c09e2f11cbb9d34c6f3694a970e1a24f97d248 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Mon, 28 Oct 2024 22:16:24 +0100 Subject: [PATCH 473/551] lib_ldf_mode = deep+ lib_compat_mode = strict --- platformio.ini | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/platformio.ini b/platformio.ini index cb76487bb..d28a48371 100644 --- a/platformio.ini +++ b/platformio.ini @@ -79,8 +79,8 @@ lib_deps = [env:raspberrypi] platform = https://github.com/maxgerhardt/platform-raspberrypi.git board = rpipicow -lib_ldf_mode = chain -lib_compat_mode = soft +lib_ldf_mode = deep+ +lib_compat_mode = strict lib_deps = bblanchon/ArduinoJson @ 7.2.0 khoih-prog/AsyncTCP_RP2040W @ 1.2.0 @@ -117,8 +117,8 @@ lib_deps = [env:ci-raspberrypi] platform = https://github.com/maxgerhardt/platform-raspberrypi.git board = ${sysenv.PIO_BOARD} -lib_ldf_mode = chain -lib_compat_mode = soft +lib_ldf_mode = deep+ +lib_compat_mode = strict lib_deps = bblanchon/ArduinoJson @ 7.2.0 khoih-prog/AsyncTCP_RP2040W @ 1.2.0 From 8ce30ac7e6a591c928fba95ea73556f38e6fef06 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Mon, 28 Oct 2024 22:25:50 +0100 Subject: [PATCH 474/551] lib_ignore = lwIP_ESPHost --- platformio.ini | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/platformio.ini b/platformio.ini index d28a48371..0b8794235 100644 --- a/platformio.ini +++ b/platformio.ini @@ -79,11 +79,11 @@ lib_deps = [env:raspberrypi] platform = https://github.com/maxgerhardt/platform-raspberrypi.git board = rpipicow -lib_ldf_mode = deep+ -lib_compat_mode = strict lib_deps = bblanchon/ArduinoJson @ 7.2.0 khoih-prog/AsyncTCP_RP2040W @ 1.2.0 +lib_ignore = + lwIP_ESPHost build_flags = ${env.build_flags} -Wno-missing-field-initializers @@ -117,10 +117,10 @@ lib_deps = [env:ci-raspberrypi] platform = https://github.com/maxgerhardt/platform-raspberrypi.git board = ${sysenv.PIO_BOARD} -lib_ldf_mode = deep+ -lib_compat_mode = strict lib_deps = bblanchon/ArduinoJson @ 7.2.0 khoih-prog/AsyncTCP_RP2040W @ 1.2.0 +lib_ignore = + lwIP_ESPHost build_flags = ${env.build_flags} -Wno-missing-field-initializers From 5a60a3de6c7ecb5be800255fa288c435297e61cd Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Wed, 30 Oct 2024 09:55:34 +0100 Subject: [PATCH 475/551] Added serveStatic example with template --- examples/SimpleServer/SimpleServer.ino | 45 +++++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/examples/SimpleServer/SimpleServer.ino b/examples/SimpleServer/SimpleServer.ino index 1328f1a34..fae23386b 100644 --- a/examples/SimpleServer/SimpleServer.ino +++ b/examples/SimpleServer/SimpleServer.ino @@ -87,6 +87,18 @@ const char* htmlContent PROGMEM = R"( )"; +const char* staticContent PROGMEM = R"( + + + + Sample HTML + + +

Hello, %IP%

+ + +)"; + AsyncWebServer server(80); AsyncEventSource events("/events"); AsyncWebSocket ws("/ws"); @@ -203,7 +215,7 @@ void setup() { LittleFS.begin(); #endif - if (!LittleFS.exists("/index.txt")) { + { File f = LittleFS.open("/index.txt", "w"); if (f) { for (size_t c = 0; c < sizeof(characters); c++) { @@ -215,6 +227,14 @@ void setup() { } } + { + File f = LittleFS.open("/index.html", "w"); + if (f) { + f.print(staticContent); + f.close(); + } + } + // curl -v -X GET http://192.168.4.1/handler-not-sending-response server.on("/handler-not-sending-response", HTTP_GET, [](AsyncWebServerRequest* request) { // handler forgot to send a response to the client => 501 Not Implemented @@ -392,6 +412,29 @@ void setup() { // curl -v -X GET http://192.168.4.1/index.txt server.serveStatic("/index.txt", LittleFS, "/index.txt"); + // ServeStatic static is used to serve static output which never changes over time. + // This special endpoints automatyically adds caching headers. + // If a template processor is used, it must enure that the outputed content will always be the ame over time and never changes. + // Otherwise, do not use serveStatic. + // Example below: IP never changes. + // curl -v -X GET http://192.168.4.1/index-static.html + server.serveStatic("/index-static.html", LittleFS, "/index.html").setTemplateProcessor([](const String& var) -> String { + if (var == "IP") + return WiFi.localIP().toString(); + return emptyString; + }); + + // to serve a template with dynamic content (output changes over time), use normal + // Example below: content changes over tinme do not use serveStatic. + // curl -v -X GET http://192.168.4.1/index-dynamic.html + server.on("/index-dynamic.html", HTTP_GET, [](AsyncWebServerRequest* request) { + request->send(LittleFS, "/index.html", "text/html", false, [](const String& var) -> String { + if (var == "IP") + return String(random(0, 1000)); + return emptyString; + }); + }); + // Issue #14: assert failed: tcp_update_rcv_ann_wnd (needs help to test fix) // > curl -v http://192.168.4.1/issue-14 pinMode(4, OUTPUT); From 4290bb2e4a91f78bab1296a3959da057b8901a7a Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Wed, 30 Oct 2024 10:07:44 +0100 Subject: [PATCH 476/551] Fix CI --- examples/SimpleServer/SimpleServer.ino | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/examples/SimpleServer/SimpleServer.ino b/examples/SimpleServer/SimpleServer.ino index fae23386b..31ad9e883 100644 --- a/examples/SimpleServer/SimpleServer.ino +++ b/examples/SimpleServer/SimpleServer.ino @@ -419,8 +419,12 @@ void setup() { // Example below: IP never changes. // curl -v -X GET http://192.168.4.1/index-static.html server.serveStatic("/index-static.html", LittleFS, "/index.html").setTemplateProcessor([](const String& var) -> String { - if (var == "IP") - return WiFi.localIP().toString(); + if (var == "IP") { + // for CI, commented out since H2 board doesn ot support WiFi + // return WiFi.localIP().toString(); + // return WiFi.softAPIP().toString(); + return "127.0.0..1"; + } return emptyString; }); From 7cf5de6eed7ee037f84bdd55f08e4aed03099d61 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Mon, 4 Nov 2024 14:02:14 +0100 Subject: [PATCH 477/551] Fix #151: setAuthentication() was not authenticating: the middleware was setup with `AUTH_NONE` (default) instead of `AUTH_DIGEST` (to keep backward compatibility) --- examples/SimpleServer/SimpleServer.ino | 3 +++ src/ESPAsyncWebServer.h | 4 ++-- src/WebHandlers.cpp | 3 ++- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/examples/SimpleServer/SimpleServer.ino b/examples/SimpleServer/SimpleServer.ino index 31ad9e883..1084528de 100644 --- a/examples/SimpleServer/SimpleServer.ino +++ b/examples/SimpleServer/SimpleServer.ino @@ -412,6 +412,9 @@ void setup() { // curl -v -X GET http://192.168.4.1/index.txt server.serveStatic("/index.txt", LittleFS, "/index.txt"); + // curl -v -X GET http://192.168.4.1/index-private.txt + server.serveStatic("/index-private.txt", LittleFS, "/index.txt").setAuthentication("admin", "admin"); + // ServeStatic static is used to serve static output which never changes over time. // This special endpoints automatyically adds caching headers. // If a template processor is used, it must enure that the outputed content will always be the ame over time and never changes. diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index 5a64179da..c744d4802 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -733,8 +733,8 @@ class AsyncWebHandler : public AsyncMiddlewareChain { AsyncWebHandler() {} virtual ~AsyncWebHandler() {} AsyncWebHandler& setFilter(ArRequestFilterFunction fn); - AsyncWebHandler& setAuthentication(const char* username, const char* password); - AsyncWebHandler& setAuthentication(const String& username, const String& password) { return setAuthentication(username.c_str(), password.c_str()); }; + AsyncWebHandler& setAuthentication(const char* username, const char* password, AsyncAuthType authMethod = AsyncAuthType::AUTH_DIGEST); + AsyncWebHandler& setAuthentication(const String& username, const String& password, AsyncAuthType authMethod = AsyncAuthType::AUTH_DIGEST) { return setAuthentication(username.c_str(), password.c_str(), authMethod); }; bool filter(AsyncWebServerRequest* request) { return _filter == NULL || _filter(request); } virtual bool canHandle(AsyncWebServerRequest* request __attribute__((unused))) const { return false; } virtual void handleRequest(__unused AsyncWebServerRequest* request) {} diff --git a/src/WebHandlers.cpp b/src/WebHandlers.cpp index a1183186f..335e1f2a1 100644 --- a/src/WebHandlers.cpp +++ b/src/WebHandlers.cpp @@ -27,7 +27,7 @@ AsyncWebHandler& AsyncWebHandler::setFilter(ArRequestFilterFunction fn) { _filter = fn; return *this; } -AsyncWebHandler& AsyncWebHandler::setAuthentication(const char* username, const char* password) { +AsyncWebHandler& AsyncWebHandler::setAuthentication(const char* username, const char* password, AsyncAuthType authMethod) { if (!_authMiddleware) { _authMiddleware = new AuthenticationMiddleware(); _authMiddleware->_freeOnRemoval = true; @@ -35,6 +35,7 @@ AsyncWebHandler& AsyncWebHandler::setAuthentication(const char* username, const } _authMiddleware->setUsername(username); _authMiddleware->setPassword(password); + _authMiddleware->setAuthType(authMethod); return *this; }; From d86e0906bde658162a2d1c5f7444dc0f19fabc2f Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Mon, 4 Nov 2024 14:08:10 +0100 Subject: [PATCH 478/551] v3.3.22 --- README.md | 6 +++--- docs/index.md | 6 +++--- library.json | 2 +- library.properties | 2 +- src/ESPAsyncWebServer.h | 4 ++-- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index de2cde5ff..a40260b08 100644 --- a/README.md +++ b/README.md @@ -61,7 +61,7 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo ```ini lib_compat_mode = strict lib_ldf_mode = chain -lib_deps = mathieucarbou/ESPAsyncWebServer @ 3.3.21 +lib_deps = mathieucarbou/ESPAsyncWebServer @ 3.3.22 ``` **Dependencies:** @@ -87,7 +87,7 @@ lib_ldf_mode = chain lib_deps = ; mathieucarbou/AsyncTCP @ 3.2.12 https://github.com/mathieucarbou/AsyncTCPSock/archive/refs/tags/v1.0.3-dev.zip - mathieucarbou/ESPAsyncWebServer @ 3.3.21 + mathieucarbou/ESPAsyncWebServer @ 3.3.22 lib_ignore = AsyncTCP mathieucarbou/AsyncTCP @@ -95,7 +95,7 @@ lib_ignore = ## Performance -Performance of `mathieucarbou/ESPAsyncWebServer @ 3.3.21`: +Performance of `mathieucarbou/ESPAsyncWebServer @ 3.3.22`: ```bash > brew install autocannon diff --git a/docs/index.md b/docs/index.md index ac0547df4..4af119cbf 100644 --- a/docs/index.md +++ b/docs/index.md @@ -61,7 +61,7 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo ```ini lib_compat_mode = strict lib_ldf_mode = chain -lib_deps = mathieucarbou/ESPAsyncWebServer @ 3.3.21 +lib_deps = mathieucarbou/ESPAsyncWebServer @ 3.3.22 ``` **Dependencies:** @@ -87,7 +87,7 @@ lib_ldf_mode = chain lib_deps = ; mathieucarbou/AsyncTCP @ 3.2.12 https://github.com/mathieucarbou/AsyncTCPSock/archive/refs/tags/v1.0.3-dev.zip - mathieucarbou/ESPAsyncWebServer @ 3.3.21 + mathieucarbou/ESPAsyncWebServer @ 3.3.22 lib_ignore = AsyncTCP mathieucarbou/AsyncTCP @@ -95,7 +95,7 @@ lib_ignore = ## Performance -Performance of `mathieucarbou/ESPAsyncWebServer @ 3.3.21`: +Performance of `mathieucarbou/ESPAsyncWebServer @ 3.3.22`: ```bash > brew install autocannon diff --git a/library.json b/library.json index c0e428f54..509358206 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "ESPAsyncWebServer", - "version": "3.3.21", + "version": "3.3.22", "description": "Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 and RP2040. Supports: WebSocket, SSE, Authentication, Arduino Json 7, File Upload, Static File serving, URL Rewrite, URL Redirect, etc.", "keywords": "http,async,websocket,webserver", "homepage": "https://github.com/mathieucarbou/ESPAsyncWebServer", diff --git a/library.properties b/library.properties index b33948e96..41908ca2f 100644 --- a/library.properties +++ b/library.properties @@ -1,6 +1,6 @@ name=ESP Async WebServer includes=ESPAsyncWebServer.h -version=3.3.21 +version=3.3.22 author=Me-No-Dev maintainer=Mathieu Carbou sentence=Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 and RP2040 diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index c744d4802..c77102e74 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -48,10 +48,10 @@ #include "literals.h" -#define ASYNCWEBSERVER_VERSION "3.3.21" +#define ASYNCWEBSERVER_VERSION "3.3.22" #define ASYNCWEBSERVER_VERSION_MAJOR 3 #define ASYNCWEBSERVER_VERSION_MINOR 3 -#define ASYNCWEBSERVER_VERSION_REVISION 21 +#define ASYNCWEBSERVER_VERSION_REVISION 22 #define ASYNCWEBSERVER_FORK_mathieucarbou #ifdef ASYNCWEBSERVER_REGEX From cb19a82668fb26d9be8db546806ced6f9c7d44fb Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Fri, 8 Nov 2024 08:34:48 +0100 Subject: [PATCH 479/551] update doc --- README.md | 14 ++++++++++++++ docs/index.md | 16 +++++++++++++++- 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index a40260b08..6cf43afd5 100644 --- a/README.md +++ b/README.md @@ -52,6 +52,20 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo - (perf) Lot of code cleanup and optimizations - (perf) Performance improvements in terms of memory, speed and size +----- +WARNING: Important notes about future version 4.x +----- + +This ESPAsyncWebServer fork is now at version 3.x. + +Next version 4.x will: + +1. Drop support for ESP8266, which goes EOL in a few years. All ESP8266 boards can be replaced by equivalent ESP32 boards. +2. Drop support for Arduino 2.x and ESP-IDF 4.x. The library will be compatible with Arduino 3.x and ESP-IDF 5.x. +3. Drop support for ArduinoJson 5.x and 6.x. The library will be compatible with ArduinoJson 7.x. + +So if you need one of these feature, you will have to stick with 3.x or another fork. + ## Dependencies **WARNING** The library name was changed from `ESP Async WebServer` to `ESPAsyncWebServer` as per the Arduino Lint recommendations, but its name had to stay `ESP Async WebServer` in Arduino Registry. diff --git a/docs/index.md b/docs/index.md index 4af119cbf..6cf43afd5 100644 --- a/docs/index.md +++ b/docs/index.md @@ -52,6 +52,20 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo - (perf) Lot of code cleanup and optimizations - (perf) Performance improvements in terms of memory, speed and size +----- +WARNING: Important notes about future version 4.x +----- + +This ESPAsyncWebServer fork is now at version 3.x. + +Next version 4.x will: + +1. Drop support for ESP8266, which goes EOL in a few years. All ESP8266 boards can be replaced by equivalent ESP32 boards. +2. Drop support for Arduino 2.x and ESP-IDF 4.x. The library will be compatible with Arduino 3.x and ESP-IDF 5.x. +3. Drop support for ArduinoJson 5.x and 6.x. The library will be compatible with ArduinoJson 7.x. + +So if you need one of these feature, you will have to stick with 3.x or another fork. + ## Dependencies **WARNING** The library name was changed from `ESP Async WebServer` to `ESPAsyncWebServer` as per the Arduino Lint recommendations, but its name had to stay `ESP Async WebServer` in Arduino Registry. @@ -1232,7 +1246,7 @@ For actual serving the file. ### Param Rewrite With Matching -It is possible to rewrite the request url with parameter matchg. Here is an example with one parameter: +It is possible to rewrite the request url with parameter match. Here is an example with one parameter: Rewrite for example "/radio/{frequence}" -> "/radio?f={frequence}" ```cpp From 29ba81039d06b07ac44984221cc895e2d25768c2 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Tue, 12 Nov 2024 01:08:29 +0100 Subject: [PATCH 480/551] Added SSE perf tests --- examples/SimpleServer/SimpleServer.ino | 58 +++++++++++++++++++++++++- 1 file changed, 57 insertions(+), 1 deletion(-) diff --git a/examples/SimpleServer/SimpleServer.ino b/examples/SimpleServer/SimpleServer.ino index 1084528de..a35daf541 100644 --- a/examples/SimpleServer/SimpleServer.ino +++ b/examples/SimpleServer/SimpleServer.ino @@ -607,7 +607,63 @@ void setup() { } }); + // SSS endpoints + // sends a message every 10 ms + // // go to http://192.168.4.1/sse + // > curl -v -N -H "Accept: text/event-stream" http://192.168.4.1/events + // + // some perf tests: + // launch 16 concurrent workers for 30 seconds + // > for i in {1..16}; do ( count=$(gtimeout 30 curl -s -N -H "Accept: text/event-stream" http://192.168.4.1/events 2>&1 | grep -c "^data:"); echo "Total: $count events, $(echo "$count / 4" | bc -l) events / second" ) & done; + // + // With AsyncTCP, with 16 workers: a lot of Too many messages queued: deleting message + // + // Total: 119 events, 29.75000000000000000000 events / second + // Total: 727 events, 181.75000000000000000000 events / second + // Total: 1386 events, 346.50000000000000000000 events / second + // Total: 1385 events, 346.25000000000000000000 events / second + // Total: 1276 events, 319.00000000000000000000 events / second + // Total: 1411 events, 352.75000000000000000000 events / second + // Total: 1276 events, 319.00000000000000000000 events / second + // Total: 1333 events, 333.25000000000000000000 events / second + // Total: 1250 events, 312.50000000000000000000 events / second + // Total: 1275 events, 318.75000000000000000000 events / second + // Total: 1271 events, 317.75000000000000000000 events / second + // Total: 1271 events, 317.75000000000000000000 events / second + // Total: 1254 events, 313.50000000000000000000 events / second + // Total: 1251 events, 312.75000000000000000000 events / second + // Total: 1254 events, 313.50000000000000000000 events / second + // Total: 1262 events, 315.50000000000000000000 events / second + // + // With AsyncTCP, with 10 workers: + // + // Total: 1875 events, 468.75000000000000000000 events / second + // Total: 1870 events, 467.50000000000000000000 events / second + // Total: 1871 events, 467.75000000000000000000 events / second + // Total: 1875 events, 468.75000000000000000000 events / second + // Total: 1871 events, 467.75000000000000000000 events / second + // Total: 1805 events, 451.25000000000000000000 events / second + // Total: 1803 events, 450.75000000000000000000 events / second + // Total: 1873 events, 468.25000000000000000000 events / second + // Total: 1872 events, 468.00000000000000000000 events / second + // Total: 1805 events, 451.25000000000000000000 events / second + // + // With AsyncTCPSock, with 16 workers: ESP32 CRASH !!! + // + // With AsyncTCPSock, with 10 workers: + // + // Total: 1242 events, 310.50000000000000000000 events / second + // Total: 1242 events, 310.50000000000000000000 events / second + // Total: 1242 events, 310.50000000000000000000 events / second + // Total: 1242 events, 310.50000000000000000000 events / second + // Total: 1181 events, 295.25000000000000000000 events / second + // Total: 1182 events, 295.50000000000000000000 events / second + // Total: 1240 events, 310.00000000000000000000 events / second + // Total: 1181 events, 295.25000000000000000000 events / second + // Total: 1181 events, 295.25000000000000000000 events / second + // Total: 1183 events, 295.75000000000000000000 events / second + // server.addHandler(&events); // Run: websocat ws://192.168.4.1/ws @@ -624,7 +680,7 @@ void setup() { } uint32_t lastSSE = 0; -uint32_t deltaSSE = 5; +uint32_t deltaSSE = 10; uint32_t lastWS = 0; uint32_t deltaWS = 100; From 02f7b4f65dc1f9859d69196272471c094d4cd779 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Tue, 12 Nov 2024 01:46:16 +0100 Subject: [PATCH 481/551] update doc --- README.md | 40 +++++++++++++++++++++++++++++++++++++--- docs/index.md | 40 +++++++++++++++++++++++++++++++++++++--- 2 files changed, 74 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 6cf43afd5..65dc478cb 100644 --- a/README.md +++ b/README.md @@ -52,9 +52,9 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo - (perf) Lot of code cleanup and optimizations - (perf) Performance improvements in terms of memory, speed and size ------ -WARNING: Important notes about future version 4.x ------ +--- + +## WARNING: Important notes about future version 4.x This ESPAsyncWebServer fork is now at version 3.x. @@ -124,6 +124,40 @@ With `https://github.com/mathieucarbou/AsyncTCPSock/archive/refs/tags/v1.0.3-dev [![](https://mathieu.carbou.me/ESPAsyncWebServer/perf-c10-asynctcpsock.png)](https://mathieu.carbou.me/ESPAsyncWebServer/perf-c10-asynctcpsock.png) +**SSE performance** + +In the example, there is an endpoint `/events` with some comments showing how these metrics are calculated. + +Test is running for 20 seconds with 10 connections. + +``` +// With AsyncTCP, with 10 workers: no message discarded from the queue +// +// Total: 1875 events, 468.75000000000000000000 events / second +// Total: 1870 events, 467.50000000000000000000 events / second +// Total: 1871 events, 467.75000000000000000000 events / second +// Total: 1875 events, 468.75000000000000000000 events / second +// Total: 1871 events, 467.75000000000000000000 events / second +// Total: 1805 events, 451.25000000000000000000 events / second +// Total: 1803 events, 450.75000000000000000000 events / second +// Total: 1873 events, 468.25000000000000000000 events / second +// Total: 1872 events, 468.00000000000000000000 events / second +// Total: 1805 events, 451.25000000000000000000 events / second +// +// With AsyncTCPSock, with 10 workers: no message discarded from the queue +// +// Total: 1242 events, 310.50000000000000000000 events / second +// Total: 1242 events, 310.50000000000000000000 events / second +// Total: 1242 events, 310.50000000000000000000 events / second +// Total: 1242 events, 310.50000000000000000000 events / second +// Total: 1181 events, 295.25000000000000000000 events / second +// Total: 1182 events, 295.50000000000000000000 events / second +// Total: 1240 events, 310.00000000000000000000 events / second +// Total: 1181 events, 295.25000000000000000000 events / second +// Total: 1181 events, 295.25000000000000000000 events / second +// Total: 1183 events, 295.75000000000000000000 events / second +``` + ## Important recommendations Most of the crashes are caused by improper configuration of the library for the project. diff --git a/docs/index.md b/docs/index.md index 6cf43afd5..65dc478cb 100644 --- a/docs/index.md +++ b/docs/index.md @@ -52,9 +52,9 @@ This fork is based on [yubox-node-org/ESPAsyncWebServer](https://github.com/yubo - (perf) Lot of code cleanup and optimizations - (perf) Performance improvements in terms of memory, speed and size ------ -WARNING: Important notes about future version 4.x ------ +--- + +## WARNING: Important notes about future version 4.x This ESPAsyncWebServer fork is now at version 3.x. @@ -124,6 +124,40 @@ With `https://github.com/mathieucarbou/AsyncTCPSock/archive/refs/tags/v1.0.3-dev [![](https://mathieu.carbou.me/ESPAsyncWebServer/perf-c10-asynctcpsock.png)](https://mathieu.carbou.me/ESPAsyncWebServer/perf-c10-asynctcpsock.png) +**SSE performance** + +In the example, there is an endpoint `/events` with some comments showing how these metrics are calculated. + +Test is running for 20 seconds with 10 connections. + +``` +// With AsyncTCP, with 10 workers: no message discarded from the queue +// +// Total: 1875 events, 468.75000000000000000000 events / second +// Total: 1870 events, 467.50000000000000000000 events / second +// Total: 1871 events, 467.75000000000000000000 events / second +// Total: 1875 events, 468.75000000000000000000 events / second +// Total: 1871 events, 467.75000000000000000000 events / second +// Total: 1805 events, 451.25000000000000000000 events / second +// Total: 1803 events, 450.75000000000000000000 events / second +// Total: 1873 events, 468.25000000000000000000 events / second +// Total: 1872 events, 468.00000000000000000000 events / second +// Total: 1805 events, 451.25000000000000000000 events / second +// +// With AsyncTCPSock, with 10 workers: no message discarded from the queue +// +// Total: 1242 events, 310.50000000000000000000 events / second +// Total: 1242 events, 310.50000000000000000000 events / second +// Total: 1242 events, 310.50000000000000000000 events / second +// Total: 1242 events, 310.50000000000000000000 events / second +// Total: 1181 events, 295.25000000000000000000 events / second +// Total: 1182 events, 295.50000000000000000000 events / second +// Total: 1240 events, 310.00000000000000000000 events / second +// Total: 1181 events, 295.25000000000000000000 events / second +// Total: 1181 events, 295.25000000000000000000 events / second +// Total: 1183 events, 295.75000000000000000000 events / second +``` + ## Important recommendations Most of the crashes are caused by improper configuration of the library for the project. From 43e0b5c5a654268b40bb79c37f8a77c469d6ee10 Mon Sep 17 00:00:00 2001 From: Emil Muratov Date: Sat, 9 Nov 2024 00:31:01 +0900 Subject: [PATCH 482/551] rework SSE handling implement AsyncEventSourceMessage using shared std::string container one message instance could be shared for multiple connected clients add zero-copy overloads for message queue in AsyncEventSourceClient message queue for the client consists of possibly shared instances of AsyncEventSourceMessage, adding a message to the queue won't create deep-copy object AsyncEventSource will create a single instance of data message and populate connected clients queues with a shared pointer --- examples/SSE_perftest/SSE_perftest.ino | 257 ++++++++++++++++++++ src/AsyncEventSource.cpp | 322 ++++++++++++++----------- src/AsyncEventSource.h | 169 +++++++++++-- src/literals.h | 1 + 4 files changed, 590 insertions(+), 159 deletions(-) create mode 100644 examples/SSE_perftest/SSE_perftest.ino diff --git a/examples/SSE_perftest/SSE_perftest.ino b/examples/SSE_perftest/SSE_perftest.ino new file mode 100644 index 000000000..ecabd019c --- /dev/null +++ b/examples/SSE_perftest/SSE_perftest.ino @@ -0,0 +1,257 @@ +// +// SSE server with a load generator +// it will auto adjust message push rate to minimize discards across all connected clients +// per second stats is printed to a serial console and also published as SSE ping message +// open /sse URL to start events generator + +#include +#ifdef ESP32 + #include + #include +#elif defined(ESP8266) + #include + #include +#elif defined(TARGET_RP2040) + #include + #include +#endif + +#include + +#if __has_include("ArduinoJson.h") + #include + #include + #include +#endif + +#include + +const char* htmlContent PROGMEM = R"( + + + + Sample HTML + + +

Hello, World!

+

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod, purus a euismod + rhoncus, urna ipsum cursus massa, eu dictum tellus justo ac justo. Quisque ullamcorper + arcu nec tortor ullamcorper, vel fermentum justo fermentum. Vivamus sed velit ut elit + accumsan congue ut ut enim. Ut eu justo eu lacus varius gravida ut a tellus. Nulla facilisi. + Integer auctor consectetur ultricies. Fusce feugiat, mi sit amet bibendum viverra, orci leo + dapibus elit, id varius sem dui id lacus.

+

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod, purus a euismod + rhoncus, urna ipsum cursus massa, eu dictum tellus justo ac justo. Quisque ullamcorper + arcu nec tortor ullamcorper, vel fermentum justo fermentum. Vivamus sed velit ut elit + accumsan congue ut ut enim. Ut eu justo eu lacus varius gravida ut a tellus. Nulla facilisi. + Integer auctor consectetur ultricies. Fusce feugiat, mi sit amet bibendum viverra, orci leo + dapibus elit, id varius sem dui id lacus.

+

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod, purus a euismod + rhoncus, urna ipsum cursus massa, eu dictum tellus justo ac justo. Quisque ullamcorper + arcu nec tortor ullamcorper, vel fermentum justo fermentum. Vivamus sed velit ut elit + accumsan congue ut ut enim. Ut eu justo eu lacus varius gravida ut a tellus. Nulla facilisi. + Integer auctor consectetur ultricies. Fusce feugiat, mi sit amet bibendum viverra, orci leo + dapibus elit, id varius sem dui id lacus.

+

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod, purus a euismod + rhoncus, urna ipsum cursus massa, eu dictum tellus justo ac justo. Quisque ullamcorper + arcu nec tortor ullamcorper, vel fermentum justo fermentum. Vivamus sed velit ut elit + accumsan congue ut ut enim. Ut eu justo eu lacus varius gravida ut a tellus. Nulla facilisi. + Integer auctor consectetur ultricies. Fusce feugiat, mi sit amet bibendum viverra, orci leo + dapibus elit, id varius sem dui id lacus.

+

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod, purus a euismod + rhoncus, urna ipsum cursus massa, eu dictum tellus justo ac justo. Quisque ullamcorper + arcu nec tortor ullamcorper, vel fermentum justo fermentum. Vivamus sed velit ut elit + accumsan congue ut ut enim. Ut eu justo eu lacus varius gravida ut a tellus. Nulla facilisi. + Integer auctor consectetur ultricies. Fusce feugiat, mi sit amet bibendum viverra, orci leo + dapibus elit, id varius sem dui id lacus.

+

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod, purus a euismod + rhoncus, urna ipsum cursus massa, eu dictum tellus justo ac justo. Quisque ullamcorper + arcu nec tortor ullamcorper, vel fermentum justo fermentum. Vivamus sed velit ut elit + accumsan congue ut ut enim. Ut eu justo eu lacus varius gravida ut a tellus. Nulla facilisi. + Integer auctor consectetur ultricies. Fusce feugiat, mi sit amet bibendum viverra, orci leo + dapibus elit, id varius sem dui id lacus.

+

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod, purus a euismod + rhoncus, urna ipsum cursus massa, eu dictum tellus justo ac justo. Quisque ullamcorper + arcu nec tortor ullamcorper, vel fermentum justo fermentum. Vivamus sed velit ut elit + accumsan congue ut ut enim. Ut eu justo eu lacus varius gravida ut a tellus. Nulla facilisi. + Integer auctor consectetur ultricies. Fusce feugiat, mi sit amet bibendum viverra, orci leo + dapibus elit, id varius sem dui id lacus.

+

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin euismod, purus a euismod + rhoncus, urna ipsum cursus massa, eu dictum tellus justo ac justo. Quisque ullamcorper + arcu nec tortor ullamcorper, vel fermentum justo fermentum. Vivamus sed velit ut elit + accumsan congue ut ut enim. Ut eu justo eu lacus varius gravida ut a tellus. Nulla facilisi. + Integer auctor consectetur ultricies. Fusce feugiat, mi sit amet bibendum viverra, orci leo + dapibus elit, id varius sem dui id lacus.

+ + +)"; + +const char* staticContent PROGMEM = R"( + + + + Sample HTML + + +

Hello, %IP%

+ + +)"; + +AsyncWebServer server(80); +AsyncEventSource events("/events"); + +///////////////////////////////////////////////////////////////////////////////////////////////////// + +const char* PARAM_MESSAGE PROGMEM = "message"; +const char* SSE_HTLM PROGMEM = R"( + + + + Server-Sent Events + + + +

Open your browser console!

+ + +)"; + +static const char* SSE_MSG = R"(Alice felt that this could not be denied, so she tried another question. 'What sort of people live about here?' 'In THAT direction,' the Cat said, waving its right paw round, 'lives a Hatter: and in THAT direction,' waving the other paw, 'lives a March Hare. Visit either you like: they're both mad.' +'But I don't want to go among mad people,' Alice remarked. 'Oh, you can't help that,' said the Cat: 'we're all mad here. I'm mad. You're mad.' 'How do you know I'm mad?' said Alice. +'You must be,' said the Cat, `or you wouldn't have come here.' Alice didn't think that proved it at all; however, she went on 'And how do you know that you're mad?' 'To begin with,' said the Cat, 'a dog's not mad. You grant that?' +)"; + +void notFound(AsyncWebServerRequest* request) { + request->send(404, "text/plain", "Not found"); +} + +static const char characters[] = "0123456789ABCDEF"; +static size_t charactersIndex = 0; + +void setup() { + + Serial.begin(115200); + +#ifndef CONFIG_IDF_TARGET_ESP32H2 + /* + WiFi.mode(WIFI_STA); + WiFi.begin("SSID", "passwd"); + if (WiFi.waitForConnectResult() != WL_CONNECTED) { + Serial.printf("WiFi Failed!\n"); + return; + } + Serial.print("IP Address: "); + Serial.println(WiFi.localIP()); + */ + + WiFi.mode(WIFI_AP); + WiFi.softAP("esp-captive"); +#endif + + server.on("/", HTTP_GET, [](AsyncWebServerRequest* request) { + request->send(200, "text/html", staticContent); + }); + + events.onConnect([](AsyncEventSourceClient* client) { + if (client->lastId()) { + Serial.printf("SSE Client reconnected! Last message ID that it gat is: %" PRIu32 "\n", client->lastId()); + } + client->send("hello!", NULL, millis(), 1000); + }); + + server.on("/sse", HTTP_GET, [](AsyncWebServerRequest* request) { + request->send(200, "text/html", SSE_HTLM); + }); + + // go to http://192.168.4.1/sse + server.addHandler(&events); + + server.onNotFound(notFound); + + server.begin(); +} + +uint32_t lastSSE = 0; +uint32_t deltaSSE = 25; +uint32_t messagesSSE = 4; // how many messages to q each time +uint32_t sse_disc{0}, sse_enq{0}, sse_penq{0}, sse_second{0}; + +AsyncEventSource::SendStatus enqueue() { + AsyncEventSource::SendStatus state = events.send(SSE_MSG, "message"); + if (state == AsyncEventSource::SendStatus::DISCARDED) + ++sse_disc; + else if (state == AsyncEventSource::SendStatus::ENQUEUED) { + ++sse_enq; + } else + ++sse_penq; + + return state; +} + +void loop() { + uint32_t now = millis(); + if (now - lastSSE >= deltaSSE) { + // enqueue messages + for (uint32_t i = 0; i != messagesSSE; ++i) { + auto err = enqueue(); + if (err == AsyncEventSource::SendStatus::DISCARDED || err == AsyncEventSource::SendStatus::PARTIALLY_ENQUEUED) { + // throttle messaging a bit + lastSSE = now + deltaSSE; + break; + } + } + + lastSSE = millis(); + } + + if (now - sse_second > 1000) { + String s; + s.reserve(100); + s = "Ping:"; + s += now / 1000; + s += " clients:"; + s += events.count(); + s += " disc:"; + s += sse_disc; + s += " enq:"; + s += sse_enq; + s += " partial:"; + s += sse_penq; + s += " avg wait:"; + s += events.avgPacketsWaiting(); + s += " heap:"; + s += ESP.getFreeHeap() / 1024; + + events.send(s, "heartbeat", now); + Serial.println(); + Serial.println(s); + + // if we see discards or partial enqueues, let's decrease message rate, else - increase. So that we can come to a max sustained message rate + if (sse_disc || sse_penq) + ++deltaSSE; + else if (deltaSSE > 5) + --deltaSSE; + + sse_disc = sse_enq = sse_penq = 0; + sse_second = now; + } +} diff --git a/src/AsyncEventSource.cpp b/src/AsyncEventSource.cpp index 1c0ff2a6b..2a3b04c99 100644 --- a/src/AsyncEventSource.cpp +++ b/src/AsyncEventSource.cpp @@ -25,114 +25,97 @@ using namespace asyncsrv; -static String generateEventMessage(const char* message, const char* event, uint32_t id, uint32_t reconnect) { - String ev; +static std::string generateEventMessage(const char* message, const char* event, uint32_t id, uint32_t reconnect) { + std::string str; + size_t len{0}; + if (message) + len += strlen(message); + + if (event) + len += strlen(event); + + len += 42; // give it some overhead + + str.reserve(len); if (reconnect) { - ev += T_retry_; - ev += reconnect; - ev += T_rn; + str += T_retry_; + str += reconnect; + str += 0xa; // '\n' } if (id) { - ev += T_id__; - ev += id; - ev += T_rn; + str += T_id__; + char buff[16]; + snprintf ( buff, 16, "%u", id ); + str += buff; + str += 0xa; // '\n' } if (event != NULL) { - ev += T_event_; - ev += event; - ev += T_rn; + str += T_event_; + str += event; + str += 0xa; // '\n' } - if (message != NULL) { - size_t messageLen = strlen(message); - char* lineStart = (char*)message; - char* lineEnd; - do { - char* nextN = strchr(lineStart, '\n'); - char* nextR = strchr(lineStart, '\r'); - if (nextN == NULL && nextR == NULL) { - size_t llen = ((char*)message + messageLen) - lineStart; - char* ldata = (char*)malloc(llen + 1); - if (ldata != NULL) { - memcpy(ldata, lineStart, llen); - ldata[llen] = 0; - ev += T_data_; - ev += ldata; - ev += T_rnrn; - free(ldata); - } - lineStart = (char*)message + messageLen; + if (!message) + return str; + + size_t messageLen = strlen(message); + char* lineStart = (char*)message; + char* lineEnd; + do { + char* nextN = strchr(lineStart, '\n'); + char* nextR = strchr(lineStart, '\r'); + if (nextN == NULL && nextR == NULL) { + // a message is a single-line string + str += T_data_; + str += message; + str += T_nn; + return str; + } + + // a message is a multi-line string + char* nextLine = NULL; + if (nextN != NULL && nextR != NULL) { // windows line-ending \r\n + if (nextR + 1 == nextN) { + // normal \r\n sequense + lineEnd = nextR; + nextLine = nextN + 1; } else { - char* nextLine = NULL; - if (nextN != NULL && nextR != NULL) { - if (nextR < nextN) { - lineEnd = nextR; - if (nextN == (nextR + 1)) - nextLine = nextN + 1; - else - nextLine = nextR + 1; - } else { - lineEnd = nextN; - if (nextR == (nextN + 1)) - nextLine = nextR + 1; - else - nextLine = nextN + 1; - } - } else if (nextN != NULL) { - lineEnd = nextN; - nextLine = nextN + 1; - } else { - lineEnd = nextR; - nextLine = nextR + 1; - } - - size_t llen = lineEnd - lineStart; - char* ldata = (char*)malloc(llen + 1); - if (ldata != NULL) { - memcpy(ldata, lineStart, llen); - ldata[llen] = 0; - ev += T_data_; - ev += ldata; - ev += T_rn; - free(ldata); - } - lineStart = nextLine; - if (lineStart == ((char*)message + messageLen)) - ev += T_rn; + // some abnormal \n \r mixed sequence + lineEnd = std::min(nextR, nextN); + nextLine = lineEnd + 1; } - } while (lineStart < ((char*)message + messageLen)); - } + } else if (nextN != NULL) { // Unix/Mac OS X LF + lineEnd = nextN; + nextLine = nextN + 1; + } else { // some ancient garbage + lineEnd = nextR; + nextLine = nextR + 1; + } - return ev; -} + str += T_data_; + str.append(lineStart, lineEnd - lineStart); + str += 0xa; // \n -// Message + lineStart = nextLine; + } while (lineStart < ((char*)message + messageLen)); -AsyncEventSourceMessage::AsyncEventSourceMessage(const char* data, size_t len) - : _data(nullptr), _len(len), _sent(0), _acked(0) { - _data = (uint8_t*)malloc(_len + 1); - if (_data == nullptr) { - _len = 0; - } else { - memcpy(_data, data, len); - _data[_len] = 0; - } -} + // append another \n to terminate message + str += 0xa; // '\n' -AsyncEventSourceMessage::~AsyncEventSourceMessage() { - if (_data != NULL) - free(_data); + return str; } +// Message + size_t AsyncEventSourceMessage::ack(size_t len, __attribute__((unused)) uint32_t time) { // If the whole message is now acked... - if (_acked + len > _len) { + if (_acked + len > _data->size()) { // Return the number of extra bytes acked (they will be carried on to the next message) - const size_t extra = _acked + len - _len; - _acked = _len; + const size_t extra = _acked + len - _data->size(); + _acked = _data->size(); return extra; } // Return that no extra bytes left. @@ -144,13 +127,25 @@ size_t AsyncEventSourceMessage::write(AsyncClient* client) { if (!client) return 0; - if (_sent >= _len || !client->canSend()) { + if (_sent >= _data->size() || !client->canSend()) { return 0; } - size_t len = min(_len - _sent, client->space()); - size_t sent = client->add((const char*)_data + _sent, len); - _sent += sent; - return sent; + + size_t len = std::min(_data->size() - _sent, client->space()); + /* + add() would call lwip's tcp_write() under the AsyncTCP hood with apiflags argument. + By default apiflags=ASYNC_WRITE_FLAG_COPY + we could have used apiflags with this flag unset to pass data by reference and avoid copy to socket buffer, + but looks like it does not work for Arduino's lwip in ESP32/IDF + it is enforced in https://github.com/espressif/esp-lwip/blob/0606eed9d8b98a797514fdf6eabb4daf1c8c8cd9/src/core/tcp_out.c#L422C5-L422C30 + if LWIP_NETIF_TX_SINGLE_PBUF is set, and it is set indeed in IDF + https://github.com/espressif/esp-idf/blob/a0f798cfc4bbd624aab52b2c194d219e242d80c1/components/lwip/port/include/lwipopts.h#L744 + + So let's just keep it enforced ASYNC_WRITE_FLAG_COPY and keep in mind that there is no zero-copy + */ + size_t written = client->add(_data->data() + _sent, len, ASYNC_WRITE_FLAG_COPY); // ASYNC_WRITE_FLAG_MORE + _sent += written; + return written; } size_t AsyncEventSourceMessage::send(AsyncClient* client) { @@ -160,20 +155,19 @@ size_t AsyncEventSourceMessage::send(AsyncClient* client) { // Client -AsyncEventSourceClient::AsyncEventSourceClient(AsyncWebServerRequest* request, AsyncEventSource* server) { - _client = request->client(); - _server = server; - _lastId = 0; +AsyncEventSourceClient::AsyncEventSourceClient(AsyncWebServerRequest* request, AsyncEventSource* server) + : _client(request->client()), _server(server) { + if (request->hasHeader(T_Last_Event_ID)) _lastId = atoi(request->getHeader(T_Last_Event_ID)->value().c_str()); _client->setRxTimeout(0); _client->onError(NULL, NULL); - _client->onAck([](void* r, AsyncClient* c, size_t len, uint32_t time) { (void)c; ((AsyncEventSourceClient*)(r))->_onAck(len, time); }, this); - _client->onPoll([](void* r, AsyncClient* c) { (void)c; ((AsyncEventSourceClient*)(r))->_onPoll(); }, this); + _client->onAck([](void* r, AsyncClient* c, size_t len, uint32_t time) { (void)c; static_cast(r)->_onAck(len, time); }, this); + _client->onPoll([](void* r, AsyncClient* c) { (void)c; static_cast(r)->_onPoll(); }, this); _client->onData(NULL, NULL); - _client->onTimeout([this](void* r, AsyncClient* c __attribute__((unused)), uint32_t time) { ((AsyncEventSourceClient*)(r))->_onTimeout(time); }, this); - _client->onDisconnect([this](void* r, AsyncClient* c) { ((AsyncEventSourceClient*)(r))->_onDisconnect(); delete c; }, this); + _client->onTimeout([this](void* r, AsyncClient* c __attribute__((unused)), uint32_t time) { static_cast(r)->_onTimeout(time); }, this); + _client->onDisconnect([this](void* r, AsyncClient* c) { static_cast(r)->_onDisconnect(); delete c; }, this); _server->_addClient(this); delete request; @@ -190,29 +184,61 @@ AsyncEventSourceClient::~AsyncEventSourceClient() { } bool AsyncEventSourceClient::_queueMessage(const char* message, size_t len) { - if (!_client) + if (_messageQueue.size() >= SSE_MAX_QUEUED_MESSAGES) { +#ifdef ESP8266 + ets_printf(String(F("ERROR: Too many messages queued\n")).c_str()); +#elif defined(ESP32) + log_e("Event message queue overflow: discard message"); +#endif return false; + } #ifdef ESP32 // length() is not thread-safe, thus acquiring the lock before this call.. std::lock_guard lock(_lockmq); #endif + _messageQueue.emplace_back(message, len); + + /* + throttle queue run + if Q is filled for >25% then network/CPU is congested, since there is no zero-copy mode for socket buff + forcing Q run will only eat more heap ram and blow the buffer, let's just keep data in our own queue + the queue will be processed at least on each onAck()/onPoll() call from AsyncTCP + */ + if (_messageQueue.size() < SSE_MAX_QUEUED_MESSAGES >> 2 && _client->canSend()) { + _runQueue(); + } + + return true; +} + +bool AsyncEventSourceClient::_queueMessage(AsyncEvent_SharedData_t&& msg) { if (_messageQueue.size() >= SSE_MAX_QUEUED_MESSAGES) { #ifdef ESP8266 ets_printf(String(F("ERROR: Too many messages queued\n")).c_str()); #elif defined(ESP32) - log_e("Too many messages queued: deleting message"); + log_e("Event message queue overflow: discard message"); #endif return false; } - _messageQueue.emplace_back(message, len); - // runqueue trigger when new messages added - if (_client->canSend()) { +#ifdef ESP32 + // length() is not thread-safe, thus acquiring the lock before this call.. + std::lock_guard lock(_lockmq); +#endif + + _messageQueue.emplace_back(std::move(msg)); + + /* + throttle queue run + if Q is filled for >25% then network/CPU is congested, since there is no zero-copy mode for socket buff + forcing Q run will only eat more heap ram and blow the buffer, let's just keep data in our own queue + the queue will be processed at least on each onAck()/onPoll() call from AsyncTCP + */ + if (_messageQueue.size() < SSE_MAX_QUEUED_MESSAGES >> 2 && _client->canSend()) { _runQueue(); } - return true; } @@ -221,15 +247,33 @@ void AsyncEventSourceClient::_onAck(size_t len __attribute__((unused)), uint32_t // Same here, acquiring the lock early std::lock_guard lock(_lockmq); #endif - _runQueue(); + + // adjust in-flight len + if (len < _inflight) + _inflight -= len; + else + _inflight = 0; + + // acknowledge as much messages's data as we got confirmed len from a AsyncTCP + while (len && _messageQueue.size()) { + len = _messageQueue.front().ack(len); + if (_messageQueue.front().finished()) { + // now we could release full ack'ed messages, we were keeping it unless send confirmed from AsyncTCP + _messageQueue.pop_front(); + } + } + + // try to send another batch of data + if (_messageQueue.size()) + _runQueue(); } void AsyncEventSourceClient::_onPoll() { + if (_messageQueue.size()) { #ifdef ESP32 - // Same here, acquiring the lock early - std::lock_guard lock(_lockmq); + // Same here, acquiring the lock early + std::lock_guard lock(_lockmq); #endif - if (_messageQueue.size()) { _runQueue(); } } @@ -251,50 +295,42 @@ void AsyncEventSourceClient::close() { _client->close(); } -bool AsyncEventSourceClient::write(const char* message, size_t len) { - return connected() && _queueMessage(message, len); -} - bool AsyncEventSourceClient::send(const char* message, const char* event, uint32_t id, uint32_t reconnect) { if (!connected()) return false; - String ev = generateEventMessage(message, event, id, reconnect); - return _queueMessage(ev.c_str(), ev.length()); -} - -size_t AsyncEventSourceClient::packetsWaiting() const { -#ifdef ESP32 - std::lock_guard lock(_lockmq); -#endif - return _messageQueue.size(); + return _queueMessage(std::make_shared(generateEventMessage(message, event, id, reconnect))); } void AsyncEventSourceClient::_runQueue() { if (!_client) return; + // there is no need to lock the mutex here, 'cause all the calls to this method must be already lock'ed size_t total_bytes_written = 0; for (auto i = _messageQueue.begin(); i != _messageQueue.end(); ++i) { if (!i->sent()) { const size_t bytes_written = i->write(_client); total_bytes_written += bytes_written; - if (bytes_written == 0) + _inflight += bytes_written; + if (bytes_written == 0 || _inflight > _max_inflight) { + // Serial.print("_"); break; + } } } - if (total_bytes_written > 0) + // flush socket + if (total_bytes_written) _client->send(); +} - size_t len = total_bytes_written; - while (len && _messageQueue.size()) { - len = _messageQueue.front().ack(len); - if (_messageQueue.front().finished()) { - _messageQueue.pop_front(); - } - } +void AsyncEventSourceClient::set_max_inflight_bytes(size_t value) { + if (value >= SSE_MIN_INFLIGH && value <= SSE_MAX_INFLIGH) + _max_inflight = value; } +/* AsyncEventSource */ + void AsyncEventSource::authorizeConnect(ArAuthorizeConnectHandler cb) { AuthorizationMiddleware* m = new AuthorizationMiddleware(401, cb); m->_freeOnRemoval = true; @@ -310,18 +346,21 @@ void AsyncEventSource::_addClient(AsyncEventSourceClient* client) { _clients.emplace_back(client); if (_connectcb) _connectcb(client); + + _adjust_inflight_window(); } void AsyncEventSource::_handleDisconnect(AsyncEventSourceClient* client) { + if (_disconnectcb) + _disconnectcb(client); #ifdef ESP32 std::lock_guard lock(_client_queue_lock); #endif - if (_disconnectcb) - _disconnectcb(client); for (auto i = _clients.begin(); i != _clients.end(); ++i) { if (i->get() == client) _clients.erase(i); } + _adjust_inflight_window(); } void AsyncEventSource::close() { @@ -358,14 +397,14 @@ size_t AsyncEventSource::avgPacketsWaiting() const { AsyncEventSource::SendStatus AsyncEventSource::send( const char* message, const char* event, uint32_t id, uint32_t reconnect) { - String ev = generateEventMessage(message, event, id, reconnect); + AsyncEvent_SharedData_t shared_msg = std::make_shared(generateEventMessage(message, event, id, reconnect)); #ifdef ESP32 std::lock_guard lock(_client_queue_lock); #endif size_t hits = 0; size_t miss = 0; for (const auto& c : _clients) { - if (c->write(ev.c_str(), ev.length())) + if (c->write(shared_msg)) ++hits; else ++miss; @@ -393,7 +432,16 @@ void AsyncEventSource::handleRequest(AsyncWebServerRequest* request) { request->send(new AsyncEventSourceResponse(this)); } -// Response +void AsyncEventSource::_adjust_inflight_window() { + if (_clients.size()) { + size_t inflight = SSE_MAX_INFLIGH / _clients.size(); + for (const auto& c : _clients) + c->set_max_inflight_bytes(inflight); + // Serial.printf("adjusted inflight to: %u\n", inflight); + } +} + +/* Response */ AsyncEventSourceResponse::AsyncEventSourceResponse(AsyncEventSource* server) { _server = server; diff --git a/src/AsyncEventSource.h b/src/AsyncEventSource.h index 10d79012b..eb9ceb26f 100644 --- a/src/AsyncEventSource.h +++ b/src/AsyncEventSource.h @@ -21,22 +21,29 @@ #define ASYNCEVENTSOURCE_H_ #include +#include #ifdef ESP32 #include #include #ifndef SSE_MAX_QUEUED_MESSAGES #define SSE_MAX_QUEUED_MESSAGES 32 #endif + #define SSE_MIN_INFLIGH 2 * 1460 // allow 2 MSS packets + #define SSE_MAX_INFLIGH 16 * 1024 // but no more than 16k, no need to blow it, since same data is kept in local Q #elif defined(ESP8266) #include #ifndef SSE_MAX_QUEUED_MESSAGES #define SSE_MAX_QUEUED_MESSAGES 8 #endif + #define SSE_MIN_INFLIGH 2 * 1460 // allow 2 MSS packets + #define SSE_MAX_INFLIGH 8 * 1024 // but no more than 8k, no need to blow it, since same data is kept in local Q #elif defined(TARGET_RP2040) #include #ifndef SSE_MAX_QUEUED_MESSAGES #define SSE_MAX_QUEUED_MESSAGES 32 #endif + #define SSE_MIN_INFLIGH 2 * 1460 // allow 2 MSS packets + #define SSE_MAX_INFLIGH 16 * 1024 // but no more than 16k, no need to blow it, since same data is kept in local Q #endif #include @@ -53,58 +60,150 @@ class AsyncEventSourceResponse; class AsyncEventSourceClient; using ArEventHandlerFunction = std::function; using ArAuthorizeConnectHandler = ArAuthorizeFunction; +// shared message object container +using AsyncEvent_SharedData_t = std::shared_ptr; +/** + * @brief Async Event Message container with shared message content data + * + */ class AsyncEventSourceMessage { + private: - uint8_t* _data; - size_t _len; - size_t _sent; - // size_t _ack; - size_t _acked; + const AsyncEvent_SharedData_t _data; + size_t _sent{0}; // num of bytes already sent + size_t _acked{0}; // num of bytes acked public: - AsyncEventSourceMessage(const char* data, size_t len); - ~AsyncEventSourceMessage(); + AsyncEventSourceMessage(AsyncEvent_SharedData_t data) : _data(data) {}; + AsyncEventSourceMessage(const char* data, size_t len) : _data(std::make_shared(data, len)) {}; + + /** + * @brief acknowledge sending len bytes of data + * @note if num of bytes to ack is larger then the unacknowledged message length the number of carried over bytes are returned + * + * @param len bytes to acknowlegde + * @param time + * @return size_t number of extra bytes carried over + */ size_t ack(size_t len, uint32_t time = 0); + + /** + * @brief write message data to client's buffer + * @note this method does NOT call client's send + * + * @param client + * @return size_t number of bytes written + */ size_t write(AsyncClient* client); + + /** + * @brief writes message data to client's buffer and calls client's send method + * + * @param client + * @return size_t returns num of bytes the clien was able to send() + */ size_t send(AsyncClient* client); - bool finished() { return _acked == _len; } - bool sent() { return _sent == _len; } + + // returns true if full message's length were acked + bool finished() { return _acked == _data->length(); } + + /** + * @brief returns true if all data has been sent already + * + */ + bool sent() { return _sent == _data->length(); } }; +/** + * @brief class holds a sse messages queue for a particular client's connection + * + */ class AsyncEventSourceClient { private: AsyncClient* _client; AsyncEventSource* _server; - uint32_t _lastId; + uint32_t _lastId{0}; + size_t _inflight{0}; // num of unacknowledged bytes that has been written to socket buffer + size_t _max_inflight{SSE_MAX_INFLIGH}; // max num of unacknowledged bytes that could be written to socket buffer std::list _messageQueue; #ifdef ESP32 mutable std::mutex _lockmq; #endif bool _queueMessage(const char* message, size_t len); + bool _queueMessage(AsyncEvent_SharedData_t&& msg); void _runQueue(); public: AsyncEventSourceClient(AsyncWebServerRequest* request, AsyncEventSource* server); ~AsyncEventSourceClient(); - AsyncClient* client() { return _client; } - void close(); - bool write(const char* message, size_t len); + /** + * @brief Send an SSE message to client + * it will craft an SSE message and place it to client's message queue + * + * @param message body string, could be single or multi-line string sepprated by \n, \r, \r\n + * @param event body string, a sinle line string + * @param id sequence id + * @param reconnect client's reconnect timeout + * @return true if message was placed in a queue + * @return false if queue is full + */ + bool send(const char* message, const char* event = NULL, uint32_t id = 0, uint32_t reconnect = 0); bool send(const String& message, const String& event, uint32_t id = 0, uint32_t reconnect = 0) { return send(message.c_str(), event.c_str(), id, reconnect); } bool send(const String& message, const char* event, uint32_t id = 0, uint32_t reconnect = 0) { return send(message.c_str(), event, id, reconnect); } - bool send(const char* message, const char* event = NULL, uint32_t id = 0, uint32_t reconnect = 0); + + /** + * @brief place supplied preformatted SSE message to the message queue + * @note message must a properly formatted SSE string according to https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events + * + * @param message data + * @return true on success + * @return false on queue overflow or no client connected + */ + bool write(AsyncEvent_SharedData_t message) { return connected() && _queueMessage(std::move(message)); }; + + [[deprecated("Use _write(AsyncEvent_SharedData_t message) instead to share same data with multiple SSE clients")]] + bool write(const char* message, size_t len) { return connected() && _queueMessage(message, len); }; + + // close client's connection + void close(); + + // getters + + AsyncClient* client() { return _client; } bool connected() const { return _client && _client->connected(); } uint32_t lastId() const { return _lastId; } - size_t packetsWaiting() const; + size_t packetsWaiting() const { return _messageQueue.size(); }; + + /** + * @brief Sets max amount of bytes that could be written to client's socket while awaiting delivery acknowledge + * used to throttle message delivery length to tradeoff memory consumption + * @note actual amount of data written could possible be a bit larger but no more than available socket buff space + * + * @param value + */ + void set_max_inflight_bytes(size_t value); - // system callbacks (do not call) + /** + * @brief Get current max inflight bytes value + * + * @return size_t + */ + size_t get_max_inflight_bytes() const { return _max_inflight; } + + // system callbacks (do not call if from user code!) void _onAck(size_t len, uint32_t time); void _onPoll(); void _onTimeout(uint32_t time); void _onDisconnect(); }; +/** + * @brief a class that maintains all connected HTTP clients subscribed to SSE delivery + * dispatches supplied messages to the client's queues + * + */ class AsyncEventSource : public AsyncWebHandler { private: String _url; @@ -117,6 +216,9 @@ class AsyncEventSource : public AsyncWebHandler { ArEventHandlerFunction _connectcb = nullptr; ArEventHandlerFunction _disconnectcb = nullptr; + // this method manipulates in-fligh data size for connected client depending on number of active connections + void _adjust_inflight_window(); + public: typedef enum { DISCARDED = 0, @@ -124,23 +226,47 @@ class AsyncEventSource : public AsyncWebHandler { PARTIALLY_ENQUEUED = 2, } SendStatus; + AsyncEventSource(const char* url) : _url(url) {}; AsyncEventSource(const String& url) : _url(url) {}; ~AsyncEventSource() { close(); }; const char* url() const { return _url.c_str(); } + // close all connected clients void close(); + + /** + * @brief set on-connect callback for the client + * used to deliver messages to client on first connect + * + * @param cb + */ void onConnect(ArEventHandlerFunction cb) { _connectcb = cb; } + + /** + * @brief Send an SSE message to client + * it will craft an SSE message and place it to all connected client's message queues + * + * @param message body string, could be single or multi-line string sepprated by \n, \r, \r\n + * @param event body string, a sinle line string + * @param id sequence id + * @param reconnect client's reconnect timeout + * @return SendStatus if message was placed in any/all/part of the client's queues + */ + SendStatus send(const char* message, const char* event = NULL, uint32_t id = 0, uint32_t reconnect = 0); + SendStatus send(const String& message, const String& event, uint32_t id = 0, uint32_t reconnect = 0) { return send(message.c_str(), event.c_str(), id, reconnect); } + SendStatus send(const String& message, const char* event, uint32_t id = 0, uint32_t reconnect = 0) { return send(message.c_str(), event, id, reconnect); } + // The client pointer sent to the callback is only for reference purposes. DO NOT CALL ANY METHOD ON IT ! void onDisconnect(ArEventHandlerFunction cb) { _disconnectcb = cb; } void authorizeConnect(ArAuthorizeConnectHandler cb); - SendStatus send(const String& message, const String& event, uint32_t id = 0, uint32_t reconnect = 0) { return send(message.c_str(), event.c_str(), id, reconnect); } - SendStatus send(const String& message, const char* event, uint32_t id = 0, uint32_t reconnect = 0) { return send(message.c_str(), event, id, reconnect); } - SendStatus send(const char* message, const char* event = NULL, uint32_t id = 0, uint32_t reconnect = 0); - // number of clients connected + + // returns number of connected clients size_t count() const; + + // returns average number of messages pending in all client's queues size_t avgPacketsWaiting() const; - // system callbacks (do not call) + // system callbacks (do not call from user code!) void _addClient(AsyncEventSourceClient* client); void _handleDisconnect(AsyncEventSourceClient* client); bool canHandle(AsyncWebServerRequest* request) const override final; @@ -149,7 +275,6 @@ class AsyncEventSource : public AsyncWebHandler { class AsyncEventSourceResponse : public AsyncWebServerResponse { private: - String _content; AsyncEventSource* _server; public: diff --git a/src/literals.h b/src/literals.h index 67823907b..e9244836e 100644 --- a/src/literals.h +++ b/src/literals.h @@ -65,6 +65,7 @@ namespace asyncsrv { static constexpr const char* T_response = "response"; static constexpr const char* T_retry_ = "retry: "; static constexpr const char* T_retry_after = "retry-after"; + static constexpr const char* T_nn = "\n\n"; static constexpr const char* T_rn = "\r\n"; static constexpr const char* T_rnrn = "\r\n\r\n"; static constexpr const char* T_Transfer_Encoding = "transfer-encoding"; From 116fe43eecb28a20de5230cfed3b3bbb43ff4cab Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Tue, 12 Nov 2024 10:10:10 +0100 Subject: [PATCH 483/551] Added chunk response from PROGMEM content example --- examples/SimpleServer/SimpleServer.ino | 36 ++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/examples/SimpleServer/SimpleServer.ino b/examples/SimpleServer/SimpleServer.ino index a35daf541..67e41acae 100644 --- a/examples/SimpleServer/SimpleServer.ino +++ b/examples/SimpleServer/SimpleServer.ino @@ -87,6 +87,8 @@ const char* htmlContent PROGMEM = R"( )"; +const size_t htmlContentLength = strlen_P(htmlContent); + const char* staticContent PROGMEM = R"( @@ -467,6 +469,40 @@ void setup() { request->send(response); }); + // curl -N -v -X GET http://192.168.4.1/chunked.html --output - + // curl -N -v -X GET -H "if-none-match: 4272" http://192.168.4.1/chunked.html --output - + server.on("/chunked.html", HTTP_GET, [](AsyncWebServerRequest* request) { + String len = String(htmlContentLength); + + if (request->header(asyncsrv::T_INM) == len) { + request->send(304); + return; + } + + AsyncWebServerResponse* response = request->beginChunkedResponse("text/html", [](uint8_t* buffer, size_t maxLen, size_t index) -> size_t { + Serial.printf("%u / %u\n", index, htmlContentLength); + + // finished ? + if (htmlContentLength <= index) { + Serial.println("finished"); + return 0; + } + + // serve a maximum of 1024 or maxLen bytes of the remaining content + const int chunkSize = min((size_t)1024, min(maxLen, htmlContentLength - index)); + Serial.printf("sending: %u\n", chunkSize); + + memcpy(buffer, htmlContent + index, chunkSize); + + return chunkSize; + }); + + response->addHeader(asyncsrv::T_Cache_Control, "public,max-age=60"); + response->addHeader(asyncsrv::T_ETag, len); + + request->send(response); + }); + /* ❯ curl -I -X HEAD http://192.168.4.1/download HTTP/1.1 200 OK From 17a69afa6e73cf78ddae98dc184a712eb30f333b Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Tue, 12 Nov 2024 18:30:40 +0100 Subject: [PATCH 484/551] mathieucarbou/AsyncTCP @ 3.2.13 --- .github/workflows/ci.yml | 2 +- README.md | 8 ++++---- docs/index.md | 8 ++++---- library.json | 2 +- platformio.ini | 6 +++--- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c062a23ef..0c49ad26a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -55,7 +55,7 @@ jobs: - name: Install AsyncTCP (ESP32) if: ${{ matrix.core == 'esp32:esp32' }} - run: ARDUINO_LIBRARY_ENABLE_UNSAFE_INSTALL=true arduino-cli lib install --git-url https://github.com/mathieucarbou/AsyncTCP#v3.2.12 + run: ARDUINO_LIBRARY_ENABLE_UNSAFE_INSTALL=true arduino-cli lib install --git-url https://github.com/mathieucarbou/AsyncTCP#v3.2.13 - name: Install ESPAsyncTCP (ESP8266) if: ${{ matrix.core == 'esp8266:esp8266' }} diff --git a/README.md b/README.md index 65dc478cb..954dfa551 100644 --- a/README.md +++ b/README.md @@ -80,8 +80,8 @@ lib_deps = mathieucarbou/ESPAsyncWebServer @ 3.3.22 **Dependencies:** -- **ESP32 with AsyncTCP**: `mathieucarbou/AsyncTCP @ 3.2.12` - Arduino IDE: [https://github.com/mathieucarbou/AsyncTCP#v3.2.12](https://github.com/mathieucarbou/AsyncTCP/releases) +- **ESP32 with AsyncTCP**: `mathieucarbou/AsyncTCP @ 3.2.13` + Arduino IDE: [https://github.com/mathieucarbou/AsyncTCP#v3.2.13](https://github.com/mathieucarbou/AsyncTCP/releases) - **ESP32 with AsyncTCPSock**: `https://github.com/mathieucarbou/AsyncTCPSock/archive/refs/tags/v1.0.3-dev.zip` @@ -99,7 +99,7 @@ AsyncTCPSock can be used instead of AsyncTCP by excluding AsyncTCP from the libr lib_compat_mode = strict lib_ldf_mode = chain lib_deps = - ; mathieucarbou/AsyncTCP @ 3.2.12 + ; mathieucarbou/AsyncTCP @ 3.2.13 https://github.com/mathieucarbou/AsyncTCPSock/archive/refs/tags/v1.0.3-dev.zip mathieucarbou/ESPAsyncWebServer @ 3.3.22 lib_ignore = @@ -116,7 +116,7 @@ Performance of `mathieucarbou/ESPAsyncWebServer @ 3.3.22`: > autocannon -c 10 -w 10 -d 20 http://192.168.4.1 ``` -With `mathieucarbou/AsyncTCP @ 3.2.12` +With `mathieucarbou/AsyncTCP @ 3.2.13` [![](https://mathieu.carbou.me/ESPAsyncWebServer/perf-c10.png)](https://mathieu.carbou.me/ESPAsyncWebServer/perf-c10.png) diff --git a/docs/index.md b/docs/index.md index 65dc478cb..954dfa551 100644 --- a/docs/index.md +++ b/docs/index.md @@ -80,8 +80,8 @@ lib_deps = mathieucarbou/ESPAsyncWebServer @ 3.3.22 **Dependencies:** -- **ESP32 with AsyncTCP**: `mathieucarbou/AsyncTCP @ 3.2.12` - Arduino IDE: [https://github.com/mathieucarbou/AsyncTCP#v3.2.12](https://github.com/mathieucarbou/AsyncTCP/releases) +- **ESP32 with AsyncTCP**: `mathieucarbou/AsyncTCP @ 3.2.13` + Arduino IDE: [https://github.com/mathieucarbou/AsyncTCP#v3.2.13](https://github.com/mathieucarbou/AsyncTCP/releases) - **ESP32 with AsyncTCPSock**: `https://github.com/mathieucarbou/AsyncTCPSock/archive/refs/tags/v1.0.3-dev.zip` @@ -99,7 +99,7 @@ AsyncTCPSock can be used instead of AsyncTCP by excluding AsyncTCP from the libr lib_compat_mode = strict lib_ldf_mode = chain lib_deps = - ; mathieucarbou/AsyncTCP @ 3.2.12 + ; mathieucarbou/AsyncTCP @ 3.2.13 https://github.com/mathieucarbou/AsyncTCPSock/archive/refs/tags/v1.0.3-dev.zip mathieucarbou/ESPAsyncWebServer @ 3.3.22 lib_ignore = @@ -116,7 +116,7 @@ Performance of `mathieucarbou/ESPAsyncWebServer @ 3.3.22`: > autocannon -c 10 -w 10 -d 20 http://192.168.4.1 ``` -With `mathieucarbou/AsyncTCP @ 3.2.12` +With `mathieucarbou/AsyncTCP @ 3.2.13` [![](https://mathieu.carbou.me/ESPAsyncWebServer/perf-c10.png)](https://mathieu.carbou.me/ESPAsyncWebServer/perf-c10.png) diff --git a/library.json b/library.json index 509358206..e49efcbac 100644 --- a/library.json +++ b/library.json @@ -28,7 +28,7 @@ { "owner": "mathieucarbou", "name": "AsyncTCP", - "version": "^3.2.12", + "version": "^3.2.13", "platforms": "espressif32" }, { diff --git a/platformio.ini b/platformio.ini index 0b8794235..dca86cc87 100644 --- a/platformio.ini +++ b/platformio.ini @@ -30,7 +30,7 @@ lib_deps = ; bblanchon/ArduinoJson @ 5.13.4 ; bblanchon/ArduinoJson @ 6.21.5 bblanchon/ArduinoJson @ 7.2.0 - mathieucarbou/AsyncTCP @ 3.2.12 + mathieucarbou/AsyncTCP @ 3.2.13 board = esp32dev board_build.partitions = partitions-4MB.csv board_build.filesystem = littlefs @@ -48,7 +48,7 @@ platform = https://github.com/pioarduino/platform-espressif32/releases/download/ ; board = esp32-s3-devkitc-1 ; board = esp32-c6-devkitc-1 lib_deps = - mathieucarbou/AsyncTCP @ 3.2.12 + mathieucarbou/AsyncTCP @ 3.2.13 [env:arduino-310] platform = https://github.com/pioarduino/platform-espressif32/releases/download/53.03.10-rc2/platform-espressif32.zip @@ -101,7 +101,7 @@ board = ${sysenv.PIO_BOARD} platform = https://github.com/pioarduino/platform-espressif32/releases/download/51.03.05/platform-espressif32.zip board = ${sysenv.PIO_BOARD} lib_deps = - mathieucarbou/AsyncTCP @ 3.2.12 + mathieucarbou/AsyncTCP @ 3.2.13 [env:ci-arduino-310] platform = https://github.com/pioarduino/platform-espressif32/releases/download/53.03.10-rc2/platform-espressif32.zip From 9d9c22fec033e9feaa42202e6f08d39230bf5d7b Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Tue, 12 Nov 2024 18:48:14 +0100 Subject: [PATCH 485/551] mathieucarbou/AsyncTCP @ 3.2.14 --- .github/workflows/ci.yml | 2 +- README.md | 8 ++++---- docs/index.md | 8 ++++---- library.json | 2 +- platformio.ini | 6 +++--- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0c49ad26a..34a5e361d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -55,7 +55,7 @@ jobs: - name: Install AsyncTCP (ESP32) if: ${{ matrix.core == 'esp32:esp32' }} - run: ARDUINO_LIBRARY_ENABLE_UNSAFE_INSTALL=true arduino-cli lib install --git-url https://github.com/mathieucarbou/AsyncTCP#v3.2.13 + run: ARDUINO_LIBRARY_ENABLE_UNSAFE_INSTALL=true arduino-cli lib install --git-url https://github.com/mathieucarbou/AsyncTCP#v3.2.14 - name: Install ESPAsyncTCP (ESP8266) if: ${{ matrix.core == 'esp8266:esp8266' }} diff --git a/README.md b/README.md index 954dfa551..0f7b6a1b0 100644 --- a/README.md +++ b/README.md @@ -80,8 +80,8 @@ lib_deps = mathieucarbou/ESPAsyncWebServer @ 3.3.22 **Dependencies:** -- **ESP32 with AsyncTCP**: `mathieucarbou/AsyncTCP @ 3.2.13` - Arduino IDE: [https://github.com/mathieucarbou/AsyncTCP#v3.2.13](https://github.com/mathieucarbou/AsyncTCP/releases) +- **ESP32 with AsyncTCP**: `mathieucarbou/AsyncTCP @ 3.2.14` + Arduino IDE: [https://github.com/mathieucarbou/AsyncTCP#v3.2.14](https://github.com/mathieucarbou/AsyncTCP/releases) - **ESP32 with AsyncTCPSock**: `https://github.com/mathieucarbou/AsyncTCPSock/archive/refs/tags/v1.0.3-dev.zip` @@ -99,7 +99,7 @@ AsyncTCPSock can be used instead of AsyncTCP by excluding AsyncTCP from the libr lib_compat_mode = strict lib_ldf_mode = chain lib_deps = - ; mathieucarbou/AsyncTCP @ 3.2.13 + ; mathieucarbou/AsyncTCP @ 3.2.14 https://github.com/mathieucarbou/AsyncTCPSock/archive/refs/tags/v1.0.3-dev.zip mathieucarbou/ESPAsyncWebServer @ 3.3.22 lib_ignore = @@ -116,7 +116,7 @@ Performance of `mathieucarbou/ESPAsyncWebServer @ 3.3.22`: > autocannon -c 10 -w 10 -d 20 http://192.168.4.1 ``` -With `mathieucarbou/AsyncTCP @ 3.2.13` +With `mathieucarbou/AsyncTCP @ 3.2.14` [![](https://mathieu.carbou.me/ESPAsyncWebServer/perf-c10.png)](https://mathieu.carbou.me/ESPAsyncWebServer/perf-c10.png) diff --git a/docs/index.md b/docs/index.md index 954dfa551..0f7b6a1b0 100644 --- a/docs/index.md +++ b/docs/index.md @@ -80,8 +80,8 @@ lib_deps = mathieucarbou/ESPAsyncWebServer @ 3.3.22 **Dependencies:** -- **ESP32 with AsyncTCP**: `mathieucarbou/AsyncTCP @ 3.2.13` - Arduino IDE: [https://github.com/mathieucarbou/AsyncTCP#v3.2.13](https://github.com/mathieucarbou/AsyncTCP/releases) +- **ESP32 with AsyncTCP**: `mathieucarbou/AsyncTCP @ 3.2.14` + Arduino IDE: [https://github.com/mathieucarbou/AsyncTCP#v3.2.14](https://github.com/mathieucarbou/AsyncTCP/releases) - **ESP32 with AsyncTCPSock**: `https://github.com/mathieucarbou/AsyncTCPSock/archive/refs/tags/v1.0.3-dev.zip` @@ -99,7 +99,7 @@ AsyncTCPSock can be used instead of AsyncTCP by excluding AsyncTCP from the libr lib_compat_mode = strict lib_ldf_mode = chain lib_deps = - ; mathieucarbou/AsyncTCP @ 3.2.13 + ; mathieucarbou/AsyncTCP @ 3.2.14 https://github.com/mathieucarbou/AsyncTCPSock/archive/refs/tags/v1.0.3-dev.zip mathieucarbou/ESPAsyncWebServer @ 3.3.22 lib_ignore = @@ -116,7 +116,7 @@ Performance of `mathieucarbou/ESPAsyncWebServer @ 3.3.22`: > autocannon -c 10 -w 10 -d 20 http://192.168.4.1 ``` -With `mathieucarbou/AsyncTCP @ 3.2.13` +With `mathieucarbou/AsyncTCP @ 3.2.14` [![](https://mathieu.carbou.me/ESPAsyncWebServer/perf-c10.png)](https://mathieu.carbou.me/ESPAsyncWebServer/perf-c10.png) diff --git a/library.json b/library.json index e49efcbac..d1c6004f7 100644 --- a/library.json +++ b/library.json @@ -28,7 +28,7 @@ { "owner": "mathieucarbou", "name": "AsyncTCP", - "version": "^3.2.13", + "version": "^3.2.14", "platforms": "espressif32" }, { diff --git a/platformio.ini b/platformio.ini index dca86cc87..478e067b7 100644 --- a/platformio.ini +++ b/platformio.ini @@ -30,7 +30,7 @@ lib_deps = ; bblanchon/ArduinoJson @ 5.13.4 ; bblanchon/ArduinoJson @ 6.21.5 bblanchon/ArduinoJson @ 7.2.0 - mathieucarbou/AsyncTCP @ 3.2.13 + mathieucarbou/AsyncTCP @ 3.2.14 board = esp32dev board_build.partitions = partitions-4MB.csv board_build.filesystem = littlefs @@ -48,7 +48,7 @@ platform = https://github.com/pioarduino/platform-espressif32/releases/download/ ; board = esp32-s3-devkitc-1 ; board = esp32-c6-devkitc-1 lib_deps = - mathieucarbou/AsyncTCP @ 3.2.13 + mathieucarbou/AsyncTCP @ 3.2.14 [env:arduino-310] platform = https://github.com/pioarduino/platform-espressif32/releases/download/53.03.10-rc2/platform-espressif32.zip @@ -101,7 +101,7 @@ board = ${sysenv.PIO_BOARD} platform = https://github.com/pioarduino/platform-espressif32/releases/download/51.03.05/platform-espressif32.zip board = ${sysenv.PIO_BOARD} lib_deps = - mathieucarbou/AsyncTCP @ 3.2.13 + mathieucarbou/AsyncTCP @ 3.2.14 [env:ci-arduino-310] platform = https://github.com/pioarduino/platform-espressif32/releases/download/53.03.10-rc2/platform-espressif32.zip From eee6094ef7aeb8c39a5e0347c73186836a05142f Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Fri, 15 Nov 2024 09:25:45 +0100 Subject: [PATCH 486/551] bblanchon/ArduinoJson @ 7.2.1 --- platformio.ini | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/platformio.ini b/platformio.ini index 478e067b7..aff0e4ec9 100644 --- a/platformio.ini +++ b/platformio.ini @@ -29,7 +29,7 @@ lib_ldf_mode = chain lib_deps = ; bblanchon/ArduinoJson @ 5.13.4 ; bblanchon/ArduinoJson @ 6.21.5 - bblanchon/ArduinoJson @ 7.2.0 + bblanchon/ArduinoJson @ 7.2.1 mathieucarbou/AsyncTCP @ 3.2.14 board = esp32dev board_build.partitions = partitions-4MB.csv @@ -73,14 +73,14 @@ platform = espressif8266 ; board = huzzah board = d1_mini lib_deps = - bblanchon/ArduinoJson @ 7.2.0 + bblanchon/ArduinoJson @ 7.2.1 esphome/ESPAsyncTCP-esphome @ 2.0.0 [env:raspberrypi] platform = https://github.com/maxgerhardt/platform-raspberrypi.git board = rpipicow lib_deps = - bblanchon/ArduinoJson @ 7.2.0 + bblanchon/ArduinoJson @ 7.2.1 khoih-prog/AsyncTCP_RP2040W @ 1.2.0 lib_ignore = lwIP_ESPHost @@ -111,14 +111,14 @@ board = ${sysenv.PIO_BOARD} platform = espressif8266 board = ${sysenv.PIO_BOARD} lib_deps = - bblanchon/ArduinoJson @ 7.2.0 + bblanchon/ArduinoJson @ 7.2.1 esphome/ESPAsyncTCP-esphome @ 2.0.0 [env:ci-raspberrypi] platform = https://github.com/maxgerhardt/platform-raspberrypi.git board = ${sysenv.PIO_BOARD} lib_deps = - bblanchon/ArduinoJson @ 7.2.0 + bblanchon/ArduinoJson @ 7.2.1 khoih-prog/AsyncTCP_RP2040W @ 1.2.0 lib_ignore = lwIP_ESPHost From c38d615de592750ea3ee6e9d7b3c576ce4bae924 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Fri, 15 Nov 2024 09:31:40 +0100 Subject: [PATCH 487/551] Fix CI --- .github/workflows/ci.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 34a5e361d..6864061ae 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -22,9 +22,9 @@ jobs: - core: esp32:esp32 board: esp32:esp32:esp32 index_url: https://espressif.github.io/arduino-esp32/package_esp32_index.json - - core: esp32:esp32 - board: esp32:esp32:esp32 - index_url: https://espressif.github.io/arduino-esp32/package_esp32_dev_index.json + # - core: esp32:esp32 + # board: esp32:esp32:esp32 + # index_url: https://espressif.github.io/arduino-esp32/package_esp32_dev_index.json - core: esp8266:esp8266 board: esp8266:esp8266:huzzah index_url: https://arduino.esp8266.com/stable/package_esp8266com_index.json From 60f9b47bee9d6a5ded0c21fe72d436c5035e9fbc Mon Sep 17 00:00:00 2001 From: Julien Jet Date: Fri, 15 Nov 2024 15:49:16 +0100 Subject: [PATCH 488/551] update doc according to ArduinoJson upgrade From information found on the following [issue](https://github.com/me-no-dev/ESPAsyncWebServer/edit/master/README.md) and [ArduinoJson upgrade note](https://arduinojson.org/v6/doc/upgrade/) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0f7b6a1b0..2ab2e4f78 100644 --- a/README.md +++ b/README.md @@ -622,7 +622,7 @@ Endpoints which consume JSON can use a special handler to get ready to use JSON #include "ArduinoJson.h" AsyncCallbackJsonWebHandler* handler = new AsyncCallbackJsonWebHandler("/rest/endpoint", [](AsyncWebServerRequest *request, JsonVariant &json) { - JsonObject& jsonObj = json.as(); + JsonObject jsonObj = json.as(); // ... }); server.addHandler(handler); From 071785ae506beeae621af89c736dac1ef64d2839 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Fri, 15 Nov 2024 20:06:18 +0100 Subject: [PATCH 489/551] add josn example --- examples/SimpleServer/SimpleServer.ino | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/examples/SimpleServer/SimpleServer.ino b/examples/SimpleServer/SimpleServer.ino index 67e41acae..6d2863f1a 100644 --- a/examples/SimpleServer/SimpleServer.ino +++ b/examples/SimpleServer/SimpleServer.ino @@ -552,18 +552,6 @@ void setup() { #if __has_include("ArduinoJson.h") // JSON - // receives JSON and sends JSON - jsonHandler->onRequest([](AsyncWebServerRequest* request, JsonVariant& json) { - // JsonObject jsonObj = json.as(); - // ... - - AsyncJsonResponse* response = new AsyncJsonResponse(); - JsonObject root = response->getRoot().to(); - root["hello"] = "world"; - response->setLength(); - request->send(response); - }); - // sends JSON // curl -v -X GET http://192.168.4.1/json1 server.on("/json1", HTTP_GET, [](AsyncWebServerRequest* request) { @@ -579,11 +567,23 @@ void setup() { AsyncResponseStream* response = request->beginResponseStream("application/json"); JsonDocument doc; JsonObject root = doc.to(); - root["hello"] = "world"; + root["foo"] = "bar"; serializeJson(root, *response); request->send(response); }); + // curl -v -X POST -H 'Content-Type: application/json' -d '{"name":"You"}' http://192.168.4.1/json2 + // curl -v -X PUT -H 'Content-Type: application/json' -d '{"name":"You"}' http://192.168.4.1/json2 + jsonHandler->setMethod(HTTP_POST | HTTP_PUT); + jsonHandler->onRequest([](AsyncWebServerRequest* request, JsonVariant& json) { + serializeJson(json, Serial); + AsyncJsonResponse* response = new AsyncJsonResponse(); + JsonObject root = response->getRoot().to(); + root["hello"] = json.as()["name"]; + response->setLength(); + request->send(response); + }); + // MessagePack // receives MessagePack and sends MessagePack From 4a37169a0413dcee444b3e9dc18363941d73d053 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Fri, 15 Nov 2024 20:38:39 +0100 Subject: [PATCH 490/551] Arduino Core 3.1.0 RC3 / ESP-IDF 5.3 --- platformio.ini | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/platformio.ini b/platformio.ini index aff0e4ec9..ea07818d4 100644 --- a/platformio.ini +++ b/platformio.ini @@ -51,18 +51,18 @@ lib_deps = mathieucarbou/AsyncTCP @ 3.2.14 [env:arduino-310] -platform = https://github.com/pioarduino/platform-espressif32/releases/download/53.03.10-rc2/platform-espressif32.zip +platform = https://github.com/pioarduino/platform-espressif32/releases/download/53.03.10-rc3/platform-espressif32.zip ; board = esp32-s3-devkitc-1 ; board = esp32-c6-devkitc-1 ; board = esp32-h2-devkitm-1 [env:perf-test-AsyncTCP] -platform = https://github.com/pioarduino/platform-espressif32/releases/download/53.03.10-rc2/platform-espressif32.zip +platform = https://github.com/pioarduino/platform-espressif32/releases/download/53.03.10-rc3/platform-espressif32.zip build_flags = ${env.build_flags} -D PERF_TEST=1 [env:perf-test-AsyncTCPSock] -platform = https://github.com/pioarduino/platform-espressif32/releases/download/53.03.10-rc2/platform-espressif32.zip +platform = https://github.com/pioarduino/platform-espressif32/releases/download/53.03.10-rc3/platform-espressif32.zip lib_deps = https://github.com/mathieucarbou/AsyncTCPSock/archive/refs/tags/v1.0.3-dev.zip build_flags = ${env.build_flags} @@ -104,7 +104,7 @@ lib_deps = mathieucarbou/AsyncTCP @ 3.2.14 [env:ci-arduino-310] -platform = https://github.com/pioarduino/platform-espressif32/releases/download/53.03.10-rc2/platform-espressif32.zip +platform = https://github.com/pioarduino/platform-espressif32/releases/download/53.03.10-rc3/platform-espressif32.zip board = ${sysenv.PIO_BOARD} [env:ci-esp8266] From 33611e8c0afd00f2ad4d115fe0ac65e3785851de Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Tue, 19 Nov 2024 00:18:05 +0100 Subject: [PATCH 491/551] Fix samples --- examples/CaptivePortal/CaptivePortal.ino | 2 +- examples/Filters/Filters.ino | 4 ++-- platformio.ini | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/examples/CaptivePortal/CaptivePortal.ino b/examples/CaptivePortal/CaptivePortal.ino index d44e7e6bf..69232d875 100644 --- a/examples/CaptivePortal/CaptivePortal.ino +++ b/examples/CaptivePortal/CaptivePortal.ino @@ -16,7 +16,7 @@ AsyncWebServer server(80); class CaptiveRequestHandler : public AsyncWebHandler { public: - bool canHandle(__unused AsyncWebServerRequest* request) { + bool canHandle(__unused AsyncWebServerRequest* request) const override { return true; } diff --git a/examples/Filters/Filters.ino b/examples/Filters/Filters.ino index 6479c155d..23353640b 100644 --- a/examples/Filters/Filters.ino +++ b/examples/Filters/Filters.ino @@ -18,11 +18,11 @@ AsyncWebServer server(80); class CaptiveRequestHandler : public AsyncWebHandler { public: - bool canHandle(__unused AsyncWebServerRequest* request) { + bool canHandle(__unused AsyncWebServerRequest* request) const override { return true; } - void handleRequest(AsyncWebServerRequest* request) { + void handleRequest(AsyncWebServerRequest* request) override { AsyncResponseStream* response = request->beginResponseStream("text/html"); response->print("Captive Portal"); response->print("

This is out captive portal front page.

"); diff --git a/platformio.ini b/platformio.ini index ea07818d4..14a2b37b1 100644 --- a/platformio.ini +++ b/platformio.ini @@ -1,8 +1,8 @@ [platformio] default_envs = arduino-2, arduino-3, arduino-310, esp8266, raspberrypi lib_dir = . -; src_dir = examples/CaptivePortal -src_dir = examples/SimpleServer +src_dir = examples/CaptivePortal +; src_dir = examples/SimpleServer ; src_dir = examples/StreamFiles ; src_dir = examples/Filters ; src_dir = examples/Issue85 From ac2fb65cb5c2793b9a12db634a53123328e0d899 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Wed, 20 Nov 2024 20:25:44 +0100 Subject: [PATCH 492/551] Add sample --- examples/Issue162/Issue162.ino | 76 ++++++++++++++++++++++++++++++++++ platformio.ini | 3 +- 2 files changed, 78 insertions(+), 1 deletion(-) create mode 100644 examples/Issue162/Issue162.ino diff --git a/examples/Issue162/Issue162.ino b/examples/Issue162/Issue162.ino new file mode 100644 index 000000000..59232b290 --- /dev/null +++ b/examples/Issue162/Issue162.ino @@ -0,0 +1,76 @@ +/** + * + * Connect to AP and run in bash: + * + * > while true; do echo "PING"; sleep 0.1; done | websocat ws://192.168.4.1/ws + * + */ +#include +#ifdef ESP8266 + #include +#endif +#ifdef ESP32 + #include +#endif +#include + +#include +AsyncWebServer server(80); +AsyncWebSocket ws("/ws"); + +void onWsEvent(AsyncWebSocket* server, AsyncWebSocketClient* client, AwsEventType type, void* arg, uint8_t* data, size_t len) { + if (type == WS_EVT_CONNECT) { + Serial.printf("Client #%" PRIu32 " connected.\n", client->id()); + } else if (type == WS_EVT_DISCONNECT) { + Serial.printf("Client #%" PRIu32 " disconnected.\n", client->id()); + } +} + +void setup() { + Serial.begin(115200); + + WiFi.mode(WIFI_AP); + WiFi.softAP("esp-captive"); + + ws.onEvent(onWsEvent); + server.addHandler(&ws); + + server.on("/close_all_ws_clients", HTTP_GET | HTTP_POST, [](AsyncWebServerRequest* request) { + Serial.println("Closing all WebSocket clients..."); + ws.closeAll(); + request->send(200, "application/json", "{\"status\":\"all clients closed\"}"); + }); + + server.on("/", HTTP_GET, [](AsyncWebServerRequest* request) { + request->send(200, "text/html", R"rawliteral( + + + + + +

+ + + )rawliteral"); + }); + + server.begin(); +} + +void loop() { + vTaskDelete(NULL); +} diff --git a/platformio.ini b/platformio.ini index 14a2b37b1..328f427b6 100644 --- a/platformio.ini +++ b/platformio.ini @@ -1,11 +1,12 @@ [platformio] default_envs = arduino-2, arduino-3, arduino-310, esp8266, raspberrypi lib_dir = . -src_dir = examples/CaptivePortal +; src_dir = examples/CaptivePortal ; src_dir = examples/SimpleServer ; src_dir = examples/StreamFiles ; src_dir = examples/Filters ; src_dir = examples/Issue85 +src_dir = examples/Issue162 [env] framework = arduino From d60573bd4dd3a84149c2cc7d9f1602bdcf7bdd17 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Wed, 20 Nov 2024 20:41:16 +0100 Subject: [PATCH 493/551] updated example --- examples/Issue162/Issue162.ino | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/examples/Issue162/Issue162.ino b/examples/Issue162/Issue162.ino index 59232b290..3647b5d4e 100644 --- a/examples/Issue162/Issue162.ino +++ b/examples/Issue162/Issue162.ino @@ -23,6 +23,10 @@ void onWsEvent(AsyncWebSocket* server, AsyncWebSocketClient* client, AwsEventTyp Serial.printf("Client #%" PRIu32 " connected.\n", client->id()); } else if (type == WS_EVT_DISCONNECT) { Serial.printf("Client #%" PRIu32 " disconnected.\n", client->id()); + } else if (type == WS_EVT_ERROR) { + Serial.printf("Client #%" PRIu32 " error.\n", client->id()); + } else if (type == WS_EVT_DATA) { + Serial.printf("Client #%" PRIu32 " data: %.*s\n", client->id(), len, data); } } From d7c23e8417f505d9db93150dc2b66167a9190dd2 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Wed, 20 Nov 2024 20:51:57 +0100 Subject: [PATCH 494/551] Fix CI --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6864061ae..ca274027c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -127,8 +127,8 @@ jobs: - env: ci-esp8266 board: d1_mini - - env: ci-raspberrypi - board: rpipicow + # - env: ci-raspberrypi + # board: rpipicow steps: - name: Checkout uses: actions/checkout@v4 From 29198a24365759dafa839a14b0cde8546595b8ff Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Wed, 20 Nov 2024 23:18:51 +0100 Subject: [PATCH 495/551] Fix sample --- examples/Issue162/Issue162.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/Issue162/Issue162.ino b/examples/Issue162/Issue162.ino index 3647b5d4e..3d8a163e4 100644 --- a/examples/Issue162/Issue162.ino +++ b/examples/Issue162/Issue162.ino @@ -26,7 +26,7 @@ void onWsEvent(AsyncWebSocket* server, AsyncWebSocketClient* client, AwsEventTyp } else if (type == WS_EVT_ERROR) { Serial.printf("Client #%" PRIu32 " error.\n", client->id()); } else if (type == WS_EVT_DATA) { - Serial.printf("Client #%" PRIu32 " data: %.*s\n", client->id(), len, data); + Serial.printf("Client #%" PRIu32 " len: %u\n", client->id(), len); } } From 0cc6dd2a0c94c2a6c629df8087be53a9e1fedc1a Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Wed, 20 Nov 2024 23:43:45 +0100 Subject: [PATCH 496/551] code cleanup --- src/AsyncWebSocket.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/AsyncWebSocket.cpp b/src/AsyncWebSocket.cpp index 9efb6dbd0..f92dbc9b4 100644 --- a/src/AsyncWebSocket.cpp +++ b/src/AsyncWebSocket.cpp @@ -544,7 +544,7 @@ void AsyncWebSocketClient::_onData(void* pbuf, size_t plen) { } } if (datalen > 0) - _server->_handleEvent(this, WS_EVT_DATA, (void*)&_pinfo, (uint8_t*)data, datalen); + _server->_handleEvent(this, WS_EVT_DATA, (void*)&_pinfo, data, datalen); _pinfo.index += datalen; } else if ((datalen + _pinfo.index) == _pinfo.len) { @@ -572,7 +572,7 @@ void AsyncWebSocketClient::_onData(void* pbuf, size_t plen) { } else if (_pinfo.opcode == WS_PONG) { if (datalen != AWSC_PING_PAYLOAD_LEN || memcmp(AWSC_PING_PAYLOAD, data, AWSC_PING_PAYLOAD_LEN) != 0) _server->_handleEvent(this, WS_EVT_PONG, NULL, data, datalen); - } else if (_pinfo.opcode < 8) { // continuation or text/binary frame + } else if (_pinfo.opcode < WS_DISCONNECT) { // continuation or text/binary frame _server->_handleEvent(this, WS_EVT_DATA, (void*)&_pinfo, data, datalen); if (_pinfo.final) _pinfo.num = 0; @@ -586,7 +586,7 @@ void AsyncWebSocketClient::_onData(void* pbuf, size_t plen) { } // restore byte as _handleEvent may have added a null terminator i.e., data[len] = 0; - if (datalen > 0) + if (datalen) data[datalen] = datalast; data += datalen; From 0eba19d8bf3ac1a8afffede027e1cc171d9baec4 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Thu, 21 Nov 2024 00:30:41 +0100 Subject: [PATCH 497/551] Updated example --- examples/Issue162/Issue162.ino | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/examples/Issue162/Issue162.ino b/examples/Issue162/Issue162.ino index 3d8a163e4..9f7312fd4 100644 --- a/examples/Issue162/Issue162.ino +++ b/examples/Issue162/Issue162.ino @@ -27,6 +27,10 @@ void onWsEvent(AsyncWebSocket* server, AsyncWebSocketClient* client, AwsEventTyp Serial.printf("Client #%" PRIu32 " error.\n", client->id()); } else if (type == WS_EVT_DATA) { Serial.printf("Client #%" PRIu32 " len: %u\n", client->id(), len); + } else if (type == WS_EVT_PONG) { + Serial.printf("Client #%" PRIu32 " pong.\n", client->id()); + } else if (type == WS_EVT_PING) { + Serial.printf("Client #%" PRIu32 " ping.\n", client->id()); } } From f0eb0acb2fd61fd0cd04b5bc0021877ff8e0b14c Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Thu, 21 Nov 2024 00:36:45 +0100 Subject: [PATCH 498/551] Added WS_PING event --- src/AsyncWebSocket.cpp | 3 ++- src/AsyncWebSocket.h | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/AsyncWebSocket.cpp b/src/AsyncWebSocket.cpp index f92dbc9b4..b89c0d5f1 100644 --- a/src/AsyncWebSocket.cpp +++ b/src/AsyncWebSocket.cpp @@ -568,10 +568,11 @@ void AsyncWebSocketClient::_onData(void* pbuf, size_t plen) { _queueControl(WS_DISCONNECT, data, datalen); } } else if (_pinfo.opcode == WS_PING) { + _server->_handleEvent(this, WS_EVT_PING, NULL, NULL, 0); _queueControl(WS_PONG, data, datalen); } else if (_pinfo.opcode == WS_PONG) { if (datalen != AWSC_PING_PAYLOAD_LEN || memcmp(AWSC_PING_PAYLOAD, data, AWSC_PING_PAYLOAD_LEN) != 0) - _server->_handleEvent(this, WS_EVT_PONG, NULL, data, datalen); + _server->_handleEvent(this, WS_EVT_PONG, NULL, NULL, 0); } else if (_pinfo.opcode < WS_DISCONNECT) { // continuation or text/binary frame _server->_handleEvent(this, WS_EVT_DATA, (void*)&_pinfo, data, datalen); if (_pinfo.final) diff --git a/src/AsyncWebSocket.h b/src/AsyncWebSocket.h index 8ad06ea84..671c8664f 100644 --- a/src/AsyncWebSocket.h +++ b/src/AsyncWebSocket.h @@ -104,6 +104,7 @@ typedef enum { WS_MSG_SENDING, WS_MSG_ERROR } AwsMessageStatus; typedef enum { WS_EVT_CONNECT, WS_EVT_DISCONNECT, + WS_EVT_PING, WS_EVT_PONG, WS_EVT_ERROR, WS_EVT_DATA } AwsEventType; From bccee27d2ba4dbba39a670274ad4b4fcd537ece5 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Mon, 25 Nov 2024 13:26:03 +0100 Subject: [PATCH 499/551] v3.3.23 --- README.md | 6 +++--- docs/index.md | 6 +++--- library.json | 2 +- library.properties | 2 +- src/ESPAsyncWebServer.h | 4 ++-- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 2ab2e4f78..b4a3442c4 100644 --- a/README.md +++ b/README.md @@ -75,7 +75,7 @@ So if you need one of these feature, you will have to stick with 3.x or another ```ini lib_compat_mode = strict lib_ldf_mode = chain -lib_deps = mathieucarbou/ESPAsyncWebServer @ 3.3.22 +lib_deps = mathieucarbou/ESPAsyncWebServer @ 3.3.23 ``` **Dependencies:** @@ -101,7 +101,7 @@ lib_ldf_mode = chain lib_deps = ; mathieucarbou/AsyncTCP @ 3.2.14 https://github.com/mathieucarbou/AsyncTCPSock/archive/refs/tags/v1.0.3-dev.zip - mathieucarbou/ESPAsyncWebServer @ 3.3.22 + mathieucarbou/ESPAsyncWebServer @ 3.3.23 lib_ignore = AsyncTCP mathieucarbou/AsyncTCP @@ -109,7 +109,7 @@ lib_ignore = ## Performance -Performance of `mathieucarbou/ESPAsyncWebServer @ 3.3.22`: +Performance of `mathieucarbou/ESPAsyncWebServer @ 3.3.23`: ```bash > brew install autocannon diff --git a/docs/index.md b/docs/index.md index 0f7b6a1b0..d47c640f9 100644 --- a/docs/index.md +++ b/docs/index.md @@ -75,7 +75,7 @@ So if you need one of these feature, you will have to stick with 3.x or another ```ini lib_compat_mode = strict lib_ldf_mode = chain -lib_deps = mathieucarbou/ESPAsyncWebServer @ 3.3.22 +lib_deps = mathieucarbou/ESPAsyncWebServer @ 3.3.23 ``` **Dependencies:** @@ -101,7 +101,7 @@ lib_ldf_mode = chain lib_deps = ; mathieucarbou/AsyncTCP @ 3.2.14 https://github.com/mathieucarbou/AsyncTCPSock/archive/refs/tags/v1.0.3-dev.zip - mathieucarbou/ESPAsyncWebServer @ 3.3.22 + mathieucarbou/ESPAsyncWebServer @ 3.3.23 lib_ignore = AsyncTCP mathieucarbou/AsyncTCP @@ -109,7 +109,7 @@ lib_ignore = ## Performance -Performance of `mathieucarbou/ESPAsyncWebServer @ 3.3.22`: +Performance of `mathieucarbou/ESPAsyncWebServer @ 3.3.23`: ```bash > brew install autocannon diff --git a/library.json b/library.json index d1c6004f7..f7e219cd8 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "ESPAsyncWebServer", - "version": "3.3.22", + "version": "3.3.23", "description": "Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 and RP2040. Supports: WebSocket, SSE, Authentication, Arduino Json 7, File Upload, Static File serving, URL Rewrite, URL Redirect, etc.", "keywords": "http,async,websocket,webserver", "homepage": "https://github.com/mathieucarbou/ESPAsyncWebServer", diff --git a/library.properties b/library.properties index 41908ca2f..865e91112 100644 --- a/library.properties +++ b/library.properties @@ -1,6 +1,6 @@ name=ESP Async WebServer includes=ESPAsyncWebServer.h -version=3.3.22 +version=3.3.23 author=Me-No-Dev maintainer=Mathieu Carbou sentence=Asynchronous HTTP and WebSocket Server Library for ESP32, ESP8266 and RP2040 diff --git a/src/ESPAsyncWebServer.h b/src/ESPAsyncWebServer.h index c77102e74..e58a155df 100644 --- a/src/ESPAsyncWebServer.h +++ b/src/ESPAsyncWebServer.h @@ -48,10 +48,10 @@ #include "literals.h" -#define ASYNCWEBSERVER_VERSION "3.3.22" +#define ASYNCWEBSERVER_VERSION "3.3.23" #define ASYNCWEBSERVER_VERSION_MAJOR 3 #define ASYNCWEBSERVER_VERSION_MINOR 3 -#define ASYNCWEBSERVER_VERSION_REVISION 22 +#define ASYNCWEBSERVER_VERSION_REVISION 23 #define ASYNCWEBSERVER_FORK_mathieucarbou #ifdef ASYNCWEBSERVER_REGEX From d9041fc9c4eafafaa212812f1dbe0cc85aee3840 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Sat, 30 Nov 2024 16:07:11 +0100 Subject: [PATCH 500/551] Add example to prevent WS connection if too many clients --- examples/SimpleServer/SimpleServer.ino | 25 ++++++++++++++++++++----- platformio.ini | 4 ++-- 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/examples/SimpleServer/SimpleServer.ino b/examples/SimpleServer/SimpleServer.ino index 6d2863f1a..8d347654d 100644 --- a/examples/SimpleServer/SimpleServer.ino +++ b/examples/SimpleServer/SimpleServer.ino @@ -702,8 +702,23 @@ void setup() { // server.addHandler(&events); - // Run: websocat ws://192.168.4.1/ws - server.addHandler(&ws); + // Run in terminal 1: websocat ws://192.168.4.1/ws => stream data + // Run in terminal 2: websocat ws://192.168.4.1/ws => stream data + // Run in terminal 3: websocat ws://192.168.4.1/ws => should fail: + /* +❯ websocat ws://192.168.4.1/ws +websocat: WebSocketError: WebSocketError: Received unexpected status code (503 Service Unavailable) +websocat: error running + */ + server.addHandler(&ws).addMiddleware([](AsyncWebServerRequest* request, ArMiddlewareNext next) { + if (ws.count() > 2) { + // too many clients - answer back immediately and stop processing next middlewares and handler + request->send(503, "text/plain", "Server is busy"); + } else { + // process next middleware and at the end the handler + next(); + } + }); #if __has_include("ArduinoJson.h") server.addHandler(jsonHandler); @@ -729,9 +744,9 @@ void loop() { } if (now - lastWS >= deltaWS) { ws.printfAll("kp%.4f", (10.0 / 3.0)); - for (auto& client : ws.getClients()) { - client.printf("kp%.4f", (10.0 / 3.0)); - } + // for (auto& client : ws.getClients()) { + // client.printf("kp%.4f", (10.0 / 3.0)); + // } lastWS = millis(); } } diff --git a/platformio.ini b/platformio.ini index 328f427b6..485f48bfd 100644 --- a/platformio.ini +++ b/platformio.ini @@ -2,11 +2,11 @@ default_envs = arduino-2, arduino-3, arduino-310, esp8266, raspberrypi lib_dir = . ; src_dir = examples/CaptivePortal -; src_dir = examples/SimpleServer +src_dir = examples/SimpleServer ; src_dir = examples/StreamFiles ; src_dir = examples/Filters ; src_dir = examples/Issue85 -src_dir = examples/Issue162 +; src_dir = examples/Issue162 [env] framework = arduino From b09ad98fdd1f531423d37913ced8d5740564d23d Mon Sep 17 00:00:00 2001 From: Emil Muratov Date: Sun, 1 Dec 2024 22:32:53 +0900 Subject: [PATCH 501/551] rework SSE for String's instead of std::string --- src/AsyncEventSource.cpp | 22 +++++++++++----------- src/AsyncEventSource.h | 11 ++++++++--- 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/src/AsyncEventSource.cpp b/src/AsyncEventSource.cpp index 2a3b04c99..b8413e2f2 100644 --- a/src/AsyncEventSource.cpp +++ b/src/AsyncEventSource.cpp @@ -25,8 +25,8 @@ using namespace asyncsrv; -static std::string generateEventMessage(const char* message, const char* event, uint32_t id, uint32_t reconnect) { - std::string str; +static String generateEventMessage(const char* message, const char* event, uint32_t id, uint32_t reconnect) { + String str; size_t len{0}; if (message) len += strlen(message); @@ -96,7 +96,7 @@ static std::string generateEventMessage(const char* message, const char* event, } str += T_data_; - str.append(lineStart, lineEnd - lineStart); + str.concat(lineStart, lineEnd - lineStart); str += 0xa; // \n lineStart = nextLine; @@ -112,10 +112,10 @@ static std::string generateEventMessage(const char* message, const char* event, size_t AsyncEventSourceMessage::ack(size_t len, __attribute__((unused)) uint32_t time) { // If the whole message is now acked... - if (_acked + len > _data->size()) { + if (_acked + len > _data->length()) { // Return the number of extra bytes acked (they will be carried on to the next message) - const size_t extra = _acked + len - _data->size(); - _acked = _data->size(); + const size_t extra = _acked + len - _data->length(); + _acked = _data->length(); return extra; } // Return that no extra bytes left. @@ -127,11 +127,11 @@ size_t AsyncEventSourceMessage::write(AsyncClient* client) { if (!client) return 0; - if (_sent >= _data->size() || !client->canSend()) { + if (_sent >= _data->length() || !client->canSend()) { return 0; } - size_t len = std::min(_data->size() - _sent, client->space()); + size_t len = std::min(_data->length() - _sent, client->space()); /* add() would call lwip's tcp_write() under the AsyncTCP hood with apiflags argument. By default apiflags=ASYNC_WRITE_FLAG_COPY @@ -143,7 +143,7 @@ size_t AsyncEventSourceMessage::write(AsyncClient* client) { So let's just keep it enforced ASYNC_WRITE_FLAG_COPY and keep in mind that there is no zero-copy */ - size_t written = client->add(_data->data() + _sent, len, ASYNC_WRITE_FLAG_COPY); // ASYNC_WRITE_FLAG_MORE + size_t written = client->add(_data->c_str() + _sent, len, ASYNC_WRITE_FLAG_COPY); // ASYNC_WRITE_FLAG_MORE _sent += written; return written; } @@ -298,7 +298,7 @@ void AsyncEventSourceClient::close() { bool AsyncEventSourceClient::send(const char* message, const char* event, uint32_t id, uint32_t reconnect) { if (!connected()) return false; - return _queueMessage(std::make_shared(generateEventMessage(message, event, id, reconnect))); + return _queueMessage(std::make_shared(generateEventMessage(message, event, id, reconnect))); } void AsyncEventSourceClient::_runQueue() { @@ -397,7 +397,7 @@ size_t AsyncEventSource::avgPacketsWaiting() const { AsyncEventSource::SendStatus AsyncEventSource::send( const char* message, const char* event, uint32_t id, uint32_t reconnect) { - AsyncEvent_SharedData_t shared_msg = std::make_shared(generateEventMessage(message, event, id, reconnect)); + AsyncEvent_SharedData_t shared_msg = std::make_shared(generateEventMessage(message, event, id, reconnect)); #ifdef ESP32 std::lock_guard lock(_client_queue_lock); #endif diff --git a/src/AsyncEventSource.h b/src/AsyncEventSource.h index eb9ceb26f..0796faedc 100644 --- a/src/AsyncEventSource.h +++ b/src/AsyncEventSource.h @@ -21,7 +21,7 @@ #define ASYNCEVENTSOURCE_H_ #include -#include + #ifdef ESP32 #include #include @@ -61,7 +61,7 @@ class AsyncEventSourceClient; using ArEventHandlerFunction = std::function; using ArAuthorizeConnectHandler = ArAuthorizeFunction; // shared message object container -using AsyncEvent_SharedData_t = std::shared_ptr; +using AsyncEvent_SharedData_t = std::shared_ptr; /** * @brief Async Event Message container with shared message content data @@ -76,7 +76,12 @@ class AsyncEventSourceMessage { public: AsyncEventSourceMessage(AsyncEvent_SharedData_t data) : _data(data) {}; - AsyncEventSourceMessage(const char* data, size_t len) : _data(std::make_shared(data, len)) {}; +#ifdef ESP32 + AsyncEventSourceMessage(const char* data, size_t len) : _data(std::make_shared(data, len)) {}; +#else + // esp8266's String does not have constructor with data/length arguments. Use a concat method here + AsyncEventSourceMessage(const char* data, size_t len) { _data->concat(data, len); }; +#endif /** * @brief acknowledge sending len bytes of data From 8a7d2d1944a72c107e7eef541e344b53cafb4cac Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Mon, 9 Dec 2024 09:18:13 +0100 Subject: [PATCH 502/551] add slow chunk example --- examples/SimpleServer/SimpleServer.ino | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/examples/SimpleServer/SimpleServer.ino b/examples/SimpleServer/SimpleServer.ino index 8d347654d..05756f81f 100644 --- a/examples/SimpleServer/SimpleServer.ino +++ b/examples/SimpleServer/SimpleServer.ino @@ -503,6 +503,27 @@ void setup() { request->send(response); }); + // time curl -N -v -X GET http://192.168.4.1/slow.html --output - + server.on("/slow.html", HTTP_GET, [](AsyncWebServerRequest* request) { + request->client()->setRxTimeout(2000); + AsyncWebServerResponse* response = request->beginChunkedResponse("text/html", [](uint8_t* buffer, size_t maxLen, size_t index) -> size_t { + Serial.printf("%u\n", index); + // finished ? + if (index >= 160000) + return 0; + + // slow down the task by 2 seconds + // to simulate some heavy processing, like SD card reading + delay(100); + + memset(buffer, characters[charactersIndex], 256); + charactersIndex = (charactersIndex + 1) % sizeof(characters); + return 256; + }); + + request->send(response); + }); + /* ❯ curl -I -X HEAD http://192.168.4.1/download HTTP/1.1 200 OK From 050448165b98c72bf6c5c1b6e72e0ecc6293b00b Mon Sep 17 00:00:00 2001 From: Emil Muratov Date: Tue, 10 Dec 2024 16:45:43 +0900 Subject: [PATCH 503/551] SSE: fix '\n' for String's message container Closes #166 --- src/AsyncEventSource.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/AsyncEventSource.cpp b/src/AsyncEventSource.cpp index b8413e2f2..3801fcf40 100644 --- a/src/AsyncEventSource.cpp +++ b/src/AsyncEventSource.cpp @@ -41,7 +41,7 @@ static String generateEventMessage(const char* message, const char* event, uint3 if (reconnect) { str += T_retry_; str += reconnect; - str += 0xa; // '\n' + str += (char)0xa; // '\n' } if (id) { @@ -49,13 +49,13 @@ static String generateEventMessage(const char* message, const char* event, uint3 char buff[16]; snprintf ( buff, 16, "%u", id ); str += buff; - str += 0xa; // '\n' + str += (char)0xa; // '\n' } if (event != NULL) { str += T_event_; str += event; - str += 0xa; // '\n' + str += (char)0xa; // '\n' } if (!message) From ee9d406190500f0a8931e763425925793ee72e47 Mon Sep 17 00:00:00 2001 From: Mathieu Carbou Date: Tue, 10 Dec 2024 13:37:12 +0100 Subject: [PATCH 504/551] Fix 162: closing websocket from ESP32 with Safari crashes the ESP32. This happens when Safari sends a WS frame with masked bit set and length 2. --- examples/Issue162/Issue162.ino | 29 ++++++++++++++++++++++------- src/AsyncWebSocket.cpp | 17 +++++++++++++---- 2 files changed, 35 insertions(+), 11 deletions(-) diff --git a/examples/Issue162/Issue162.ino b/examples/Issue162/Issue162.ino index 9f7312fd4..adc82d951 100644 --- a/examples/Issue162/Issue162.ino +++ b/examples/Issue162/Issue162.ino @@ -56,13 +56,23 @@ void setup() {

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�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

-

-

Login - Logout

-
-

-

- -
-
Back -