diff --git a/.github/workflows/pr-build-check.yml b/.github/workflows/pr-build-check.yml index 898a3ed5..a2d9e05f 100644 --- a/.github/workflows/pr-build-check.yml +++ b/.github/workflows/pr-build-check.yml @@ -19,15 +19,52 @@ on: - '.github/workflows/pr-build-check.yml' jobs: + webui: + runs-on: ubuntu-latest + defaults: + run: + working-directory: examples/companion_radio/webui + + steps: + - name: Clone Repo + uses: actions/checkout@v6 + with: + ref: ${{ github.event.pull_request.head.sha || github.sha }} + + - name: Build and verify embedded WebUI + run: | + npm ci + npm test + git diff --exit-code -- . + build: + needs: webui runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + environment: + - heltec_rcc6_companion_radio_ble + - heltec_rcc6_companion_radio_web_ap steps: - name: Clone Repo uses: actions/checkout@v6 + with: + ref: ${{ github.event.pull_request.head.sha || github.sha }} - name: Setup Build Environment uses: ./.github/actions/setup-build-environment - name: Build RCC6 companion firmware - run: pio run -e heltec_rcc6_companion_radio_ble + run: pio run -e ${{ matrix.environment }} + + - name: Upload exact firmware candidate + uses: actions/upload-artifact@v4 + with: + name: ${{ matrix.environment }}-${{ github.event.pull_request.head.sha || github.sha }} + path: | + .pio/build/${{ matrix.environment }}/firmware.bin + .pio/build/${{ matrix.environment }}/firmware.elf + .pio/build/${{ matrix.environment }}/bootloader.bin + .pio/build/${{ matrix.environment }}/partitions.bin diff --git a/README.md b/README.md index 1459f898..2b140eac 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # RadioCore²-RCC6 -MeshCore Companion Bluetooth firmware for the **Heltec RadioCore RCC6** with its native **220×128 NV3001B TFT**. +MeshCore Companion firmware for the **Heltec RadioCore RCC6** with its native **220×128 NV3001B TFT**. Two firmware modes are provided: secure BLE companion mode, and Wi-Fi Web/AP mode with an offline WebUI plus raw TCP/5000 access for trusted private networks. [![Release](https://img.shields.io/github/v/release/n30nex/RadioCore2-RCC6?include_prereleases&label=firmware)](https://github.com/n30nex/RadioCore2-RCC6/releases) [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](license.txt) @@ -33,10 +33,13 @@ MeshCore Companion Bluetooth firmware for the **Heltec RadioCore RCC6** with its - BLE, battery, RF, unread, RX/TX, RSSI, and SNR status at a glance. - Recent nodes, radio settings, Bluetooth, Advert, Power, and message views. - Color-coded visual notifications for messages, nearby nodes, BLE state, adverts, and low battery. -- One-button Quick Menu and screen-off/wake behavior. +- One-button press/double-press/hold controls and screen-off/wake behavior. - Subtle page transitions and notification motion. - RGB565 framebuffer with 8-row delta flushing; measured RC1 delta frame: **121 ms** versus **342–360 ms** for a full frame. - Static BLE frame queues sized for companion synchronization bursts. +- Responsive iPhone-dark WebUI for phones and desktops, served directly by the RCC6. +- 2.4 GHz setup AP, local Wi-Fi setup wizard, DHCP address on the TFT, and automatic setup-AP fallback. +- One exclusive WebUI or raw TCP/5000 companion session at a time. - DIO flash mode for RCC6 compatibility. ## Controls @@ -44,10 +47,10 @@ MeshCore Companion Bluetooth firmware for the **Heltec RadioCore RCC6** with its | Action | Result | |---|---| | Press while screen is off | Wake the display; the press is consumed | -| Press while screen is on | Next page or next menu item | -| Hold | Open Quick Menu | -| Press in Quick Menu | Move the highlight | -| Hold in Quick Menu | Select the highlighted action | +| Press while screen is on | Next page or next message page | +| Double-press | Run the action shown on the current page | +| Hold | Open the Power confirmation page | +| Hold again within eight seconds | Power off after the button is released | Wait at least eight seconds after boot before using Hold; the early-boot hold remains MeshCore's CLI rescue gesture. @@ -56,7 +59,8 @@ Wait at least eight seconds after boot before using Hold; the early-boot hold re - Heltec **RadioCore RCC6** / ESP32-C6 - RCC6 LoRa module configuration used by the upstream `heltec_rcc6` target - Attached Heltec NV3001B **220×128 TFT** -- BLE companion mode +- BLE companion firmware mode +- Wi-Fi Web/AP companion firmware mode with HTTP/80 and TCP/5000 > [!CAUTION] > This build targets **RCC6 only**. Do not flash it onto RadioCore RC32, RC52, or unrelated ESP32 boards. @@ -75,14 +79,18 @@ This repository is based on MeshCore `v1.16.0` development source at upstream co git clone https://github.com/n30nex/RadioCore2-RCC6.git cd RadioCore2-RCC6 pio run -e heltec_rcc6_companion_radio_ble +pio run -e heltec_rcc6_companion_radio_web_ap ``` The application binary is produced under: ```text .pio/build/heltec_rcc6_companion_radio_ble/firmware.bin +.pio/build/heltec_rcc6_companion_radio_web_ap/firmware.bin ``` +The Web/AP image starts a WPA-protected setup network and serves its WebUI at `http://192.168.4.1`. After the Home-page setup wizard joins a local 2.4 GHz network, the TFT shows the DHCP address. Station-mode HTTP uses username `meshcore` and the eight-letter device key shown on the TFT. Raw TCP/5000 exposes the full MeshCore companion/admin protocol without application authentication, so use station mode only on a trusted private LAN. + ## RC1 validation Validated on physical hardware: @@ -94,7 +102,7 @@ Validated on physical hardware: - Stable USB enumeration across repeated observation windows and manual resets. - BLE advertisement as `MeshCore-` with Nordic UART service `6E400001-B5A3-F393-E0A9-E50E24DCCA9E`. - Secure six-digit PIN authentication, node load in the companion app, disconnect, re-advertise, and reconnect. -- Native landscape UI and Quick Menu opening on the device. +- Native landscape UI and one-button navigation on the device. - Battery-powered boot and display operation. Still to qualify before final 1.0: diff --git a/examples/companion_radio/MyMesh.cpp b/examples/companion_radio/MyMesh.cpp index 55d0cc87..05534bf8 100644 --- a/examples/companion_radio/MyMesh.cpp +++ b/examples/companion_radio/MyMesh.cpp @@ -3,6 +3,11 @@ #include // needed for PlatformIO #include +#ifdef RCC6_WEB_AP +#include +extern SerialWebInterface serial_interface; +#endif + #define CMD_APP_START 1 #define CMD_SEND_TXT_MSG 2 #define CMD_SEND_CHANNEL_TXT_MSG 3 @@ -240,20 +245,6 @@ void MyMesh::addToOfflineQueue(const uint8_t frame[], int len) { } } -int MyMesh::getFromOfflineQueue(uint8_t frame[]) { - if (offline_queue_len > 0) { // check offline queue - size_t len = offline_queue[0].len; // take from top of queue - memcpy(frame, offline_queue[0].buf, len); - - offline_queue_len--; - for (int i = 0; i < offline_queue_len; i++) { // delete top item from queue - offline_queue[i] = offline_queue[i + 1]; - } - return len; - } - return 0; // queue is empty -} - float MyMesh::getAirtimeBudgetFactor() const { return _prefs.airtime_factor; } @@ -304,14 +295,26 @@ void MyMesh::logRxRaw(float snr, float rssi, const uint8_t raw[], int len) { void MyMesh::logTx(mesh::Packet* packet, int len) { (void) len; - if (_ui) { +#ifdef HELTEC_RCC6_NEON_UI + const bool report = packet->getPayloadType() != PAYLOAD_TYPE_ADVERT || packet == _ui_advert_packet; + if (packet == _ui_advert_packet) _ui_advert_packet = nullptr; +#else + const bool report = true; +#endif + if (_ui && report) { _ui->onRadioEvent(UIRadioEvent::TxComplete, packet->getPayloadType()); } } void MyMesh::logTxFail(mesh::Packet* packet, int len) { (void) len; - if (_ui) { +#ifdef HELTEC_RCC6_NEON_UI + const bool report = packet->getPayloadType() != PAYLOAD_TYPE_ADVERT || packet == _ui_advert_packet; + if (packet == _ui_advert_packet) _ui_advert_packet = nullptr; +#else + const bool report = true; +#endif + if (_ui && report) { _ui->onRadioEvent(UIRadioEvent::TxFailed, packet->getPayloadType()); } } @@ -1152,7 +1155,7 @@ void MyMesh::handleCmdFrame(size_t len) { ? ERR_CODE_NOT_FOUND : ERR_CODE_UNSUPPORTED_CMD); // unknown recipient, or unsupported TXT_TYPE_* } - } else if (cmd_frame[0] == CMD_SEND_CHANNEL_TXT_MSG) { // send GroupChannel text msg + } else if (cmd_frame[0] == CMD_SEND_CHANNEL_TXT_MSG && len >= 7) { // send GroupChannel text msg int i = 1; uint8_t txt_type = cmd_frame[i++]; // should be TXT_TYPE_PLAIN uint8_t channel_idx = cmd_frame[i++]; @@ -1390,12 +1393,17 @@ void MyMesh::handleCmdFrame(size_t len) { writeErrFrame(ERR_CODE_ILLEGAL_ARG); } } else if (cmd_frame[0] == CMD_SYNC_NEXT_MESSAGE) { - int out_len; - if ((out_len = getFromOfflineQueue(out_frame)) > 0) { - _serial->writeFrame(out_frame, out_len); + if (offline_queue_len > 0) { + const size_t out_len = offline_queue[0].len; + if (_serial->writeFrame(offline_queue[0].buf, out_len) == out_len) { + offline_queue_len--; + for (int i = 0; i < offline_queue_len; i++) { + offline_queue[i] = offline_queue[i + 1]; + } #ifdef DISPLAY_CLASS - if (_ui) _ui->msgRead(offline_queue_len); + if (_ui) _ui->msgRead(offline_queue_len); #endif + } } else { out_frame[0] = RESP_CODE_NO_MORE_MESSAGES; _serial->writeFrame(out_frame, 1); @@ -1937,7 +1945,14 @@ void MyMesh::handleCmdFrame(size_t len) { } else { writeErrFrame(ERR_CODE_ILLEGAL_ARG); // invalid stats sub-type } - } else if (cmd_frame[0] == CMD_FACTORY_RESET && memcmp(&cmd_frame[1], "reset", 5) == 0) { + } else if (cmd_frame[0] == CMD_FACTORY_RESET && len >= 6 && + memcmp(&cmd_frame[1], "reset", 5) == 0) { +#ifdef RCC6_WEB_AP + if (!serial_interface.clearStoredNetworkConfig()) { + writeErrFrame(ERR_CODE_FILE_IO_ERROR); + return; + } +#endif if (_serial) { MESH_DEBUG_PRINTLN("Factory reset: disabling serial interface to prevent reconnects (BLE/WiFi)"); _serial->disable(); // Phone app disconnects before we can send OK frame so it's safe here @@ -2270,7 +2285,10 @@ void MyMesh::loop() { #endif } -bool MyMesh::advert() { +bool MyMesh::advert(bool flood) { +#ifdef HELTEC_RCC6_NEON_UI + if (_ui_advert_packet != nullptr) return false; +#endif mesh::Packet* pkt; if (_prefs.advert_loc_policy == ADVERT_LOC_NONE) { pkt = createSelfAdvert(_prefs.node_name); @@ -2278,7 +2296,25 @@ bool MyMesh::advert() { pkt = createSelfAdvert(_prefs.node_name, sensors.node_lat, sensors.node_lon); } if (pkt) { - sendZeroHop(pkt); + if (flood) { + TransportKey default_scope; + memcpy(&default_scope.key, _prefs.default_scope_key, sizeof(default_scope.key)); + sendFloodScoped(default_scope, pkt, 0); + } else { + sendZeroHop(pkt); + } +#ifdef HELTEC_RCC6_NEON_UI + bool queued = false; + const int outbound_count = _mgr->getOutboundTotal(); + for (int i = 0; i < outbound_count; i++) { + if (_mgr->getOutboundByIdx(i) == pkt) { + queued = true; + break; + } + } + if (!queued) return false; + _ui_advert_packet = pkt; +#endif return true; } else { return false; diff --git a/examples/companion_radio/MyMesh.h b/examples/companion_radio/MyMesh.h index dad70712..c990e39b 100644 --- a/examples/companion_radio/MyMesh.h +++ b/examples/companion_radio/MyMesh.h @@ -97,7 +97,10 @@ class MyMesh : public BaseChatMesh, public DataStoreHost { void loop(); void handleCmdFrame(size_t len); - bool advert(); + bool advert(bool flood = false); +#ifdef HELTEC_RCC6_NEON_UI + bool isAdvertPending() const { return _ui_advert_packet != nullptr; } +#endif void enterCLIRescue(); int getRecentlyHeard(AdvertPath dest[], int max_num); @@ -190,7 +193,6 @@ class MyMesh : public BaseChatMesh, public DataStoreHost { void writeContactRespFrame(uint8_t code, const ContactInfo &contact); void updateContactFromFrame(ContactInfo &contact, uint32_t& last_mod, const uint8_t *frame, int len); void addToOfflineQueue(const uint8_t frame[], int len); - int getFromOfflineQueue(uint8_t frame[]); int getBlobByKey(const uint8_t key[], int key_len, uint8_t dest_buf[]) override { return _store->getBlobByKey(key, key_len, dest_buf); } @@ -214,6 +216,9 @@ class MyMesh : public BaseChatMesh, public DataStoreHost { uint32_t pending_req; // pending _BINARY_REQ BaseSerialInterface *_serial; AbstractUITask* _ui; +#ifdef HELTEC_RCC6_NEON_UI + mesh::Packet* _ui_advert_packet = nullptr; +#endif ContactsIterator _iter; uint32_t _iter_filter_since; diff --git a/examples/companion_radio/main.cpp b/examples/companion_radio/main.cpp index d39aeef9..01dff151 100644 --- a/examples/companion_radio/main.cpp +++ b/examples/companion_radio/main.cpp @@ -35,7 +35,13 @@ static uint32_t _atoi(const char* sp) { #endif #ifdef ESP32 - #ifdef WIFI_SSID + #ifdef RCC6_WEB_AP + #include + SerialWebInterface serial_interface; + #ifndef TCP_PORT + #define TCP_PORT 5000 + #endif + #elif defined(WIFI_SSID) #include SerialWifiInterface serial_interface; #ifndef TCP_PORT @@ -105,7 +111,9 @@ MyMesh the_mesh(radio_driver, fast_rng, rtc_clock, tables, store /* END GLOBAL OBJECTS */ void halt() { - while (1) ; + while (1) { + delay(1000); + } } /* WIFI RECONNECT TRACKERS */ @@ -135,7 +143,21 @@ void setup() { } #endif - if (!radio_init()) { halt(); } + if (!radio_init()) { + Serial.println("ERROR: radio initialization failed"); +#ifdef DISPLAY_CLASS + if (disp != NULL) { + disp->startFrame(); + disp->setTextSize(1); + disp->setColor(DisplayDriver::RED); + disp->drawTextCentered(disp->width() / 2, disp->height() / 2 - 10, "RADIO INIT FAILED"); + disp->setColor(DisplayDriver::LIGHT); + disp->drawTextCentered(disp->width() / 2, disp->height() / 2 + 8, "Reset device"); + disp->endFrame(); + } +#endif + halt(); + } fast_rng.begin(radio_driver.getRngSeed()); @@ -208,7 +230,25 @@ void setup() { #endif the_mesh.startInterface(serial_interface); #elif defined(ESP32) +#ifdef HELTEC_RCC6_NEON_UI + if (!SPIFFS.begin(false)) { + Serial.println("ERROR: SPIFFS mount failed; settings were not formatted"); +#ifdef DISPLAY_CLASS + if (disp != NULL) { + disp->startFrame(); + disp->setTextSize(1); + disp->setColor(DisplayDriver::RED); + disp->drawTextCentered(disp->width() / 2, disp->height() / 2 - 10, "STORAGE ERROR"); + disp->setColor(DisplayDriver::LIGHT); + disp->drawTextCentered(disp->width() / 2, disp->height() / 2 + 8, "Settings preserved"); + disp->endFrame(); + } +#endif + halt(); + } +#else SPIFFS.begin(true); +#endif store.begin(); the_mesh.begin( #ifdef DISPLAY_CLASS @@ -218,7 +258,10 @@ void setup() { #endif ); -#ifdef WIFI_SSID +#ifdef RCC6_WEB_AP + board.setInhibitSleep(true); // prevent sleep while the access point is active + serial_interface.begin(the_mesh.getNodePrefs()->node_name, TCP_PORT); +#elif defined(WIFI_SSID) board.setInhibitSleep(true); // prevent sleep when WiFi is active WiFi.setAutoReconnect(true); diff --git a/examples/companion_radio/ui-new/UITask.cpp b/examples/companion_radio/ui-new/UITask.cpp index 4d975e26..7883bdf2 100644 --- a/examples/companion_radio/ui-new/UITask.cpp +++ b/examples/companion_radio/ui-new/UITask.cpp @@ -2,6 +2,10 @@ #include #include "../MyMesh.h" #include "target.h" +#ifdef RCC6_WEB_AP + #include + extern SerialWebInterface serial_interface; +#endif #ifdef WIFI_SSID #include #endif @@ -14,22 +18,7 @@ #ifdef HELTEC_RCC6_NEON_UI #define NEON_FRAME_MILLIS 125 #define NEON_TRANSITION_MILLIS 300 - -enum NeonMenuItem : uint8_t { - NEON_MENU_HOME, - NEON_MENU_NEARBY, - NEON_MENU_RADIO, - NEON_MENU_BLUETOOTH, - NEON_MENU_ADVERT, - NEON_MENU_SCREEN_OFF, - NEON_MENU_POWER, - NEON_MENU_COUNT -}; - -static const char* const neon_menu_labels[NEON_MENU_COUNT] = { - "HOME", "NEARBY", "RADIO", "BLUETOOTH TOGGLE", - "ADVERT NOW", "SCREEN OFF", "POWER / SLEEP" -}; + #define NEON_POWER_CONFIRM_MILLIS 8000 #endif #ifdef PIN_STATUS_LED @@ -43,6 +32,8 @@ static const char* const neon_menu_labels[NEON_MENU_COUNT] = { #ifndef UI_RECENT_LIST_SIZE #define UI_RECENT_LIST_SIZE 4 #endif +// ponytail: fixed RAM ring; at capacity the UI reports an honest lower bound. +static constexpr int UI_MAX_UNREAD_MSGS = 32; #if UI_HAS_JOYSTICK #define PRESS_LABEL "press Enter" @@ -252,7 +243,12 @@ class HomeScreen : public UIScreen { case HomePage::FIRST: return "HOME"; case HomePage::RECENT: return "NEARBY"; case HomePage::RADIO: return "RADIO"; - case HomePage::BLUETOOTH: return "BLUETOOTH"; + case HomePage::BLUETOOTH: +#ifdef RCC6_WEB_AP + return serial_interface.isStationMode() ? "LOCAL WIFI" : "SETUP AP"; +#else + return "BLUETOOTH"; +#endif case HomePage::ADVERT: return "ADVERTISE"; #if ENV_INCLUDE_GPS == 1 case HomePage::GPS: return "GPS"; @@ -266,7 +262,19 @@ class HomeScreen : public UIScreen { } const char* neonActionHint() const { - return "CLICK NEXT HOLD MENU"; + if (_page == HomePage::SHUTDOWN) { + return _task->isPowerConfirmArmed() ? "HOLD AGAIN TO CONFIRM" : "HOLD FOR POWER"; + } + if (_page == HomePage::FIRST && _task->getMsgCount() > 0) return "CLICK NEXT 2X INBOX"; + if (_page == HomePage::BLUETOOTH) { +#ifdef RCC6_WEB_AP + return serial_interface.isStationMode() ? "CLICK NEXT 2X SETUP AP" : "CLICK NEXT 2X TOGGLE"; +#else + return "CLICK NEXT 2X TOGGLE"; +#endif + } + if (_page == HomePage::ADVERT) return "CLICK NEXT 2X SEND"; + return "CLICK NEXT"; } void renderNeonHeader(DisplayDriver& display) { @@ -276,15 +284,19 @@ class HomeScreen : public UIScreen { display.translateUTF8ToBlocks(filtered_name, _node_prefs->node_name, sizeof(filtered_name)); display.drawTextEllipsized(4, 1, 130, filtered_name); - DisplayDriver::Color ble_color = DisplayDriver::RED; + DisplayDriver::Color link_color = DisplayDriver::RED; if (_task->isSerialEnabled()) { - ble_color = _task->hasConnection() ? DisplayDriver::GREEN : DisplayDriver::ORANGE; + link_color = _task->hasConnection() ? DisplayDriver::GREEN : DisplayDriver::ORANGE; } - display.setColor(ble_color); + display.setColor(link_color); display.fillRect(140, 5, 6, 6); display.setColor(DisplayDriver::LIGHT); display.setCursor(151, 1); +#ifdef RCC6_WEB_AP + display.print("WIFI"); +#else display.print("BLE"); +#endif renderBatteryIndicator(display, _task->getCachedBattMilliVolts()); display.setColor(DisplayDriver::BLUE); @@ -360,14 +372,15 @@ class HomeScreen : public UIScreen { display.setColor(DisplayDriver::BLUE); display.drawRect(4, 38, display.width() - 8, 40); display.setTextSize(1); - snprintf(tmp, sizeof(tmp), "%d UNREAD", _task->getMsgCount()); + snprintf(tmp, sizeof(tmp), "%d%s UNREAD", _task->getMsgCount(), + _task->hasUnreadOverflow() ? "+" : ""); display.setColor(_task->getMsgCount() ? DisplayDriver::YELLOW : DisplayDriver::GREEN); display.setCursor(8, 42); display.print(tmp); if (_task->hasLatestPreview()) { char filtered_sender[32]; display.translateUTF8ToBlocks(filtered_sender, _task->getLatestSender(), sizeof(filtered_sender)); - display.setColor(DisplayDriver::GREEN); + display.setColor(_task->getLatestSender()[0] == '#' ? DisplayDriver::BLUE : DisplayDriver::GREEN); display.drawTextEllipsized(88, 42, display.width() - 96, filtered_sender); char filtered_preview[48]; display.translateUTF8ToBlocks(filtered_preview, _task->getLatestPreview(), sizeof(filtered_preview)); @@ -478,6 +491,34 @@ class HomeScreen : public UIScreen { (unsigned long)radio_driver.getPacketsRecvErrors(), radio_driver.getNoiseFloor()); display.drawTextEllipsized(4, 99, display.width() - 8, tmp); } else if (_page == HomePage::BLUETOOTH) { +#ifdef RCC6_WEB_AP + const bool enabled = _task->isSerialEnabled(); + const bool station = serial_interface.isStationMode(); + display.setTextSize(1); + display.setColor(enabled ? DisplayDriver::GREEN : DisplayDriver::RED); + display.setCursor(8, 40); + display.print(enabled ? (station ? "LOCAL WIFI ON" : "SETUP AP ON") : "NETWORK OFF"); + display.setColor(_task->hasConnection() ? DisplayDriver::GREEN : DisplayDriver::ORANGE); + display.drawTextRightAlign(display.width() - 8, 40, + _task->hasConnection() ? "CLIENT READY" : "WAITING"); + + display.setColor(DisplayDriver::BLUE); + display.drawRect(4, 54, display.width() - 8, 55); + display.setColor(DisplayDriver::LIGHT); + snprintf(tmp, sizeof(tmp), "SSID %s", serial_interface.getCurrentSsid()); + display.drawTextEllipsized(8, 59, display.width() - 16, tmp); + if (station) { + snprintf(tmp, sizeof(tmp), "AUTH meshcore/%s", serial_interface.getApPassword()); + } else { + snprintf(tmp, sizeof(tmp), "PASS %s%s", serial_interface.getApPassword(), + serial_interface.isFallbackActive() ? " FALLBACK" : ""); + } + display.drawTextEllipsized(8, 75, display.width() - 16, tmp); + const IPAddress current_ip = serial_interface.getCurrentIP(); + snprintf(tmp, sizeof(tmp), "OPEN %u.%u.%u.%u", current_ip[0], current_ip[1], + current_ip[2], current_ip[3]); + display.drawTextEllipsized(8, 91, display.width() - 16, tmp); +#else const bool enabled = _task->isSerialEnabled(); display.setColor(enabled ? DisplayDriver::GREEN : DisplayDriver::RED); display.drawXbm(24, 50, enabled ? bluetooth_on : bluetooth_off, 32, 32); @@ -496,6 +537,7 @@ class HomeScreen : public UIScreen { display.drawTextCentered(146, 86, _task->hasConnection() ? "Companion ready" : "Radio only"); } +#endif } else if (_page == HomePage::ADVERT) { display.setColor(DisplayDriver::GREEN); display.drawXbm(24, 50, advert_icon, 32, 32); @@ -506,7 +548,7 @@ class HomeScreen : public UIScreen { display.setColor(DisplayDriver::LIGHT); display.drawTextCentered(146, 70, "Announce this node"); display.setColor(DisplayDriver::BLUE); - display.drawTextCentered(146, 90, "Use quick menu"); + display.drawTextCentered(146, 90, "Double to send"); #if ENV_INCLUDE_GPS == 1 } else if (_page == HomePage::GPS) { LocationProvider* nmea = _sensors->getLocationProvider(); @@ -547,9 +589,10 @@ class HomeScreen : public UIScreen { display.drawTextCentered(146, 40, "POWER OFF"); display.setTextSize(1); display.setColor(DisplayDriver::LIGHT); - display.drawTextCentered(146, 72, "Sleep until reset"); + display.drawTextCentered(146, 72, + _task->isPowerConfirmArmed() ? "Hold again" : "Hold button"); display.setColor(DisplayDriver::RED); - display.drawTextCentered(146, 91, "Use quick menu"); + display.drawTextCentered(146, 91, "to power off"); } } @@ -562,18 +605,20 @@ class HomeScreen : public UIScreen { public: #ifdef HELTEC_RCC6_NEON_UI - void neonGotoPage(uint8_t page) { - if (page >= HomePage::Count) return; - _page = page; + void neonRequestShutdown() { + _page = HomePage::SHUTDOWN; + _shutdown_init = true; + } + + void neonShowPowerConfirm() { + _page = HomePage::SHUTDOWN; + _shutdown_init = false; _transition_dir = 1; _transition_started = 0; _transition_pending = true; } - void neonRequestShutdown() { - _page = HomePage::SHUTDOWN; - _shutdown_init = true; - } + bool neonIsPowerPage() const { return _page == HomePage::SHUTDOWN; } #endif HomeScreen(UITask* task, mesh::RTCClock* rtc, SensorManager* sensors, NodePrefs* node_prefs) @@ -834,38 +879,64 @@ class HomeScreen : public UIScreen { _transition_pending = true; #endif if (_page == HomePage::RECENT) { -#ifdef HELTEC_RCC6_NEON_UI - _task->showAlert("Nearby nodes", 800, DisplayDriver::BLUE); -#else +#ifndef HELTEC_RCC6_NEON_UI _task->showAlert("Recent adverts", 800); #endif } return true; } +#ifdef HELTEC_RCC6_NEON_UI + if (c == KEY_ENTER && _page == HomePage::FIRST && _task->getMsgCount() > 0) { + _task->gotoMsgPreviewScreen(); + return true; + } +#endif if (c == KEY_ENTER && _page == HomePage::BLUETOOTH) { - if (_task->isSerialEnabled()) { // toggle Bluetooth on/off +#ifdef RCC6_WEB_AP + if (serial_interface.isStationMode()) { + const bool saved = serial_interface.selectSetupAp(); +#ifdef HELTEC_RCC6_NEON_UI + _task->showAlert(saved ? "Restarting setup AP" : "Setup AP save failed", 1000, + saved ? DisplayDriver::ORANGE : DisplayDriver::RED); +#endif + return true; + } +#endif + if (_task->isSerialEnabled()) { _task->disableSerial(); } else { _task->enableSerial(); } #ifdef HELTEC_RCC6_NEON_UI +#ifdef RCC6_WEB_AP + _task->showAlert(_task->isSerialEnabled() ? "Setup AP on" : "Setup AP off", 800, + _task->isSerialEnabled() ? DisplayDriver::GREEN : DisplayDriver::ORANGE); +#else _task->showAlert(_task->isSerialEnabled() ? "Bluetooth on" : "Bluetooth off", 800, _task->isSerialEnabled() ? DisplayDriver::GREEN : DisplayDriver::ORANGE); +#endif #endif return true; } if (c == KEY_ENTER && _page == HomePage::ADVERT) { +#ifdef HELTEC_RCC6_NEON_UI + const bool advert_queued = the_mesh.advert(true); +#else _task->notify(UIEventType::ack); - if (the_mesh.advert()) { + const bool advert_queued = the_mesh.advert(); +#endif + if (advert_queued) { #ifdef HELTEC_RCC6_NEON_UI _task->armManualAdvert(); - _task->showAlert("Advert queued", 1000, DisplayDriver::YELLOW); + _task->showAlert("Mesh advert queued", 1000, DisplayDriver::YELLOW); #else _task->showAlert("Advert sent!", 1000); #endif } else { #ifdef HELTEC_RCC6_NEON_UI - _task->showAlert("Advert failed", 1000, DisplayDriver::RED); + const bool busy = the_mesh.isAdvertPending(); + _task->showAlert(busy ? "Advert already queued" : "Advert failed", 1000, + busy ? DisplayDriver::ORANGE : DisplayDriver::RED); #else _task->showAlert("Advert failed..", 1000); #endif @@ -886,7 +957,12 @@ class HomeScreen : public UIScreen { } #endif if (c == KEY_ENTER && _page == HomePage::SHUTDOWN) { +#ifdef HELTEC_RCC6_NEON_UI + _task->showAlert(_task->isPowerConfirmArmed() ? "Hold again to confirm" : "Hold to power off", + 900, DisplayDriver::RED); +#else _shutdown_init = true; // need to wait for button to be released +#endif return true; } return false; @@ -899,31 +975,102 @@ class MsgPreviewScreen : public UIScreen { struct MsgEntry { uint32_t timestamp; - char origin[62]; + uint8_t path_len; + char source[32]; +#ifdef HELTEC_RCC6_NEON_UI + char msg[MAX_FRAME_SIZE]; +#else char msg[78]; +#endif }; - #define MAX_UNREAD_MSGS 32 int num_unread; - int head = MAX_UNREAD_MSGS - 1; // index of latest unread message - MsgEntry unread[MAX_UNREAD_MSGS]; + int head = UI_MAX_UNREAD_MSGS - 1; // index of latest unread message + MsgEntry unread[UI_MAX_UNREAD_MSGS]; +#ifdef HELTEC_RCC6_NEON_UI + bool overflowed = false; + int page_head = -1; + size_t page_offset = 0; + size_t next_page_offset = 0; + bool page_has_more = false; + + size_t renderMessagePage(DisplayDriver& display, const char* text, size_t offset) { + static constexpr size_t chars_per_line = 33; + static constexpr int lines_per_page = 7; + const size_t text_len = strlen(text); + size_t pos = offset > text_len ? 0 : offset; + + for (int line_num = 0; line_num < lines_per_page && pos < text_len; line_num++) { + while (pos < text_len && (text[pos] == ' ' || text[pos] == '\t' || text[pos] == '\r')) pos++; + if (pos >= text_len) break; + if (text[pos] == '\n') { + pos++; + continue; + } + + const size_t line_start = pos; + size_t line_end = line_start; + while (line_end < text_len && line_end - line_start < chars_per_line && + text[line_end] != '\n' && text[line_end] != '\r') line_end++; + + size_t next = line_end; + if (line_end < text_len && text[line_end] != '\n' && text[line_end] != '\r') { + size_t split = line_end; + while (split > line_start && text[split - 1] != ' ' && text[split - 1] != '\t') split--; + if (split > line_start) { + line_end = split - 1; + while (line_end > line_start && + (text[line_end - 1] == ' ' || text[line_end - 1] == '\t')) line_end--; + next = split; + } + } else if (line_end < text_len) { + next = line_end + 1; + } + + char line[chars_per_line + 1]; + const size_t line_len = line_end - line_start; + memcpy(line, text + line_start, line_len); + line[line_len] = 0; + display.setCursor(10, 49 + line_num * 8); + display.print(line); + pos = next; + } + return pos; + } +#endif + + void formatOrigin(char* dest, size_t dest_size, const MsgEntry& entry) const { + if (entry.path_len == 0xFF) { + snprintf(dest, dest_size, "(D) %s:", entry.source); + } else { + snprintf(dest, dest_size, "(%u) %s:", (unsigned)entry.path_len, entry.source); + } + } public: MsgPreviewScreen(UITask* task, mesh::RTCClock* rtc) : _task(task), _rtc(rtc) { num_unread = 0; } - void addPreview(uint8_t path_len, const char* from_name, const char* msg) { - head = (head + 1) % MAX_UNREAD_MSGS; - if (num_unread < MAX_UNREAD_MSGS) num_unread++; + int addPreview(uint8_t path_len, const char* from_name, const char* msg) { + head = (head + 1) % UI_MAX_UNREAD_MSGS; + if (num_unread < UI_MAX_UNREAD_MSGS) { + num_unread++; +#ifdef HELTEC_RCC6_NEON_UI + } else { + overflowed = true; +#endif + } auto p = &unread[head]; p->timestamp = _rtc->getCurrentTime(); - if (path_len == 0xFF) { - sprintf(p->origin, "(D) %s:", from_name); - } else { - sprintf(p->origin, "(%d) %s:", (uint32_t) path_len, from_name); - } + p->path_len = path_len; + StrHelper::strncpy(p->source, from_name, sizeof(p->source)); StrHelper::strncpy(p->msg, msg, sizeof(p->msg)); + return num_unread; } +#ifdef HELTEC_RCC6_NEON_UI + bool hasOverflowed() const { return overflowed; } +#endif + int render(DisplayDriver& display) override { #ifdef HELTEC_RCC6_NEON_UI char tmp[20]; @@ -944,15 +1091,17 @@ class MsgPreviewScreen : public UIScreen { display.print("INBOX"); display.setColor(DisplayDriver::YELLOW); char count[20]; - snprintf(count, sizeof(count), "%d unread", num_unread); + snprintf(count, sizeof(count), "%d%s unread", num_unread, overflowed ? "+" : ""); display.drawTextCentered(display.width() / 2, 1, count); display.setColor(DisplayDriver::LIGHT); display.drawTextRightAlign(display.width() - 4, 1, tmp); display.setColor(DisplayDriver::BLUE); display.fillRect(0, 17, display.width(), 2); - char filtered_origin[sizeof(p->origin)]; - display.translateUTF8ToBlocks(filtered_origin, p->origin, sizeof(filtered_origin)); + char origin[48]; + formatOrigin(origin, sizeof(origin), *p); + char filtered_origin[sizeof(origin)]; + display.translateUTF8ToBlocks(filtered_origin, origin, sizeof(filtered_origin)); display.setColor(DisplayDriver::YELLOW); display.drawTextEllipsized(5, 23, display.width() - 10, filtered_origin); @@ -962,12 +1111,17 @@ class MsgPreviewScreen : public UIScreen { display.setColor(DisplayDriver::LIGHT); char filtered_msg[sizeof(p->msg)]; display.translateUTF8ToBlocks(filtered_msg, p->msg, sizeof(filtered_msg)); - display.printWordWrap(filtered_msg, display.width() - 20); + if (page_head != head) { + page_head = head; + page_offset = 0; + } + next_page_offset = renderMessagePage(display, filtered_msg, page_offset); + page_has_more = filtered_msg[next_page_offset] != 0; display.setColor(DisplayDriver::BLUE); display.setCursor(4, 113); - display.print("CLICK NEXT"); - display.drawTextRightAlign(display.width() - 4, 113, "HOLD MENU"); + display.print(page_has_more ? "CLICK MORE" : "CLICK NEXT"); + display.drawTextRightAlign(display.width() - 4, 113, "2X CLEAR ALL"); return 1000; #else char tmp[16]; @@ -994,8 +1148,10 @@ class MsgPreviewScreen : public UIScreen { display.setCursor(0, 14); display.setColor(DisplayDriver::YELLOW); - char filtered_origin[sizeof(p->origin)]; - display.translateUTF8ToBlocks(filtered_origin, p->origin, sizeof(filtered_origin)); + char origin[48]; + formatOrigin(origin, sizeof(origin), *p); + char filtered_origin[sizeof(origin)]; + display.translateUTF8ToBlocks(filtered_origin, origin, sizeof(filtered_origin)); display.print(filtered_origin); display.setCursor(0, 25); @@ -1014,8 +1170,26 @@ class MsgPreviewScreen : public UIScreen { bool handleInput(char c) override { if (c == KEY_NEXT || c == KEY_RIGHT) { - head = (head + MAX_UNREAD_MSGS - 1) % MAX_UNREAD_MSGS; +#ifdef HELTEC_RCC6_NEON_UI + if (page_has_more) { + page_offset = next_page_offset; + return true; + } + page_offset = next_page_offset = 0; + page_head = -1; + page_has_more = false; +#endif + head = (head + UI_MAX_UNREAD_MSGS - 1) % UI_MAX_UNREAD_MSGS; num_unread--; +#ifdef HELTEC_RCC6_NEON_UI + if (num_unread > 0) { + const auto p = &unread[head]; + _task->setLocalUnread(num_unread, p->source, p->msg, overflowed); + } else { + overflowed = false; + _task->setLocalUnread(0); + } +#endif if (num_unread == 0) { _task->gotoHomeScreen(); } @@ -1023,6 +1197,13 @@ class MsgPreviewScreen : public UIScreen { } if (c == KEY_ENTER) { num_unread = 0; // clear unread queue +#ifdef HELTEC_RCC6_NEON_UI + overflowed = false; + page_offset = next_page_offset = 0; + page_head = -1; + page_has_more = false; + _task->setLocalUnread(0); +#endif _task->gotoHomeScreen(); return true; } @@ -1123,103 +1304,31 @@ void UITask::startNeonPulse(DisplayDriver::Color color, unsigned long duration_m _next_refresh = 0; } -bool UITask::handleNeonInput(char c) { - if (!_menu_open) { - if (c != KEY_ENTER) return false; - _menu_open = true; - _menu_index = 0; - _menu_started = millis(); - startNeonPulse(DisplayDriver::BLUE, NEON_TRANSITION_MILLIS); - return true; - } - - if (c == KEY_NEXT || c == KEY_RIGHT) { - _menu_index = (_menu_index + 1) % NEON_MENU_COUNT; - _next_refresh = 0; - return true; - } - if (c == KEY_PREV || c == KEY_LEFT) { - _menu_open = false; - _next_refresh = 0; - return true; - } - if (c == KEY_ENTER) { - selectNeonMenuItem(); - return true; - } - return true; +bool UITask::isPowerConfirmArmed() const { + return _power_confirm_until != 0 && + (int32_t)(_power_confirm_until - millis()) >= 0; } -void UITask::selectNeonMenuItem() { - const uint8_t item = _menu_index; - _menu_open = false; +bool UITask::handleNeonInput(char c) { + if (c != KEY_ENTER) { + _power_confirm_until = 0; + return false; + } - if (item == NEON_MENU_HOME || item == NEON_MENU_NEARBY || item == NEON_MENU_RADIO) { - gotoHomeScreen(); - static_cast(home)->neonGotoPage(item); - } else if (item == NEON_MENU_BLUETOOTH) { - if (isSerialEnabled()) disableSerial(); - else enableSerial(); - showAlert(isSerialEnabled() ? "Bluetooth on" : "Bluetooth off", 900, - isSerialEnabled() ? DisplayDriver::GREEN : DisplayDriver::ORANGE); - } else if (item == NEON_MENU_ADVERT) { - notify(UIEventType::ack); - if (the_mesh.advert()) { - armManualAdvert(); - showAlert("Advert queued", 1000, DisplayDriver::YELLOW); - } else { - showAlert("Advert failed", 1000, DisplayDriver::RED); - } - } else if (item == NEON_MENU_SCREEN_OFF) { - if (_display != NULL && _display->isOn()) _display->turnOff(); - } else if (item == NEON_MENU_POWER) { + const bool can_confirm = isPowerConfirmArmed() && _display != NULL && _display->isOn() && + curr == home && static_cast(home)->neonIsPowerPage(); + if (can_confirm) { + _power_confirm_until = 0; gotoHomeScreen(); static_cast(home)->neonRequestShutdown(); + } else { + _power_confirm_until = millis() + NEON_POWER_CONFIRM_MILLIS; + gotoHomeScreen(); + static_cast(home)->neonShowPowerConfirm(); + startNeonPulse(DisplayDriver::RED, NEON_TRANSITION_MILLIS); } _next_refresh = 0; -} - -void UITask::renderNeonMenu(DisplayDriver& display) { - const int x = 12; - const int y = 8; - const int w = display.width() - 24; - const int h = 112; - - display.setColor(DisplayDriver::DARK); - display.fillRect(x, y, w, h); - display.setColor(DisplayDriver::BLUE); - display.drawRect(x, y, w, h); - display.setTextSize(1); - display.setColor(DisplayDriver::GREEN); - display.setCursor(x + 6, y + 5); - display.print("QUICK MENU"); - char count[8]; - snprintf(count, sizeof(count), "%u/%u", (unsigned)_menu_index + 1, - (unsigned)NEON_MENU_COUNT); - display.setColor(DisplayDriver::LIGHT); - display.drawTextRightAlign(x + w - 6, y + 5, count); - display.setColor(DisplayDriver::BLUE); - display.fillRect(x + 5, y + 21, w - 10, 1); - - int first = _menu_index == 0 ? 0 : _menu_index - 1; - if (first > NEON_MENU_COUNT - 3) first = NEON_MENU_COUNT - 3; - for (int row = 0; row < 3; row++) { - const int item = first + row; - const int row_y = y + 27 + row * 20; - if (item == _menu_index) { - display.setColor(item == NEON_MENU_POWER ? DisplayDriver::RED : DisplayDriver::BLUE); - display.fillRect(x + 5, row_y - 2, w - 10, 18); - display.setColor(DisplayDriver::LIGHT); - } else { - display.setColor(item == NEON_MENU_POWER ? DisplayDriver::RED : DisplayDriver::GREEN); - } - display.setCursor(x + 11, row_y); - display.print(neon_menu_labels[item]); - } - - display.setColor(DisplayDriver::BLUE); - display.fillRect(x + 5, y + 88, w - 10, 1); - display.drawTextCentered(display.width() / 2, y + 94, "CLICK MOVE HOLD SELECT"); + return true; } #endif @@ -1285,27 +1394,50 @@ void UITask::onRadioEvent(UIRadioEvent event, uint8_t payload_type, #endif void UITask::msgRead(int msgcount) { +#ifdef HELTEC_RCC6_NEON_UI + // Companion sync means "delivered to the phone", not "read by the user". + // Keep the on-device unread count until it is acknowledged on the display. + (void) msgcount; +#else _msgcount = msgcount; if (msgcount == 0) { + gotoHomeScreen(); + } +#endif +} + #ifdef HELTEC_RCC6_NEON_UI +void UITask::setLocalUnread(int count, const char* sender, const char* preview, bool overflow) { + _msgcount = count; + _unread_overflow = overflow; + if (count == 0) { _latest_sender[0] = 0; _latest_preview[0] = 0; -#endif - gotoHomeScreen(); + } else if (sender != nullptr && preview != nullptr) { + StrHelper::strncpy(_latest_sender, sender, sizeof(_latest_sender)); + StrHelper::strncpy(_latest_preview, preview, sizeof(_latest_preview)); } + _next_refresh = 0; } -#ifdef HELTEC_RCC6_NEON_UI void UITask::newMsgWithEvent(uint8_t path_len, const char* from_name, const char* text, int msgcount, UIEventType type) { - _next_message_color = (type == UIEventType::channelMessage || type == UIEventType::roomMessage) - ? DisplayDriver::BLUE : DisplayDriver::YELLOW; - newMsg(path_len, from_name, text, msgcount); + const bool is_channel = type == UIEventType::channelMessage || type == UIEventType::roomMessage; + _next_message_color = is_channel ? DisplayDriver::BLUE : DisplayDriver::YELLOW; + if (is_channel && from_name[0] != '#') { + char channel_label[sizeof(_latest_sender)]; + snprintf(channel_label, sizeof(channel_label), "#%s", from_name); + newMsg(path_len, channel_label, text, msgcount); + } else { + newMsg(path_len, from_name, text, msgcount); + } } #endif void UITask::newMsg(uint8_t path_len, const char* from_name, const char* text, int msgcount) { +#ifndef HELTEC_RCC6_NEON_UI _msgcount = msgcount; +#endif #ifdef HELTEC_RCC6_NEON_UI StrHelper::strncpy(_latest_sender, from_name, sizeof(_latest_sender)); @@ -1315,7 +1447,11 @@ void UITask::newMsg(uint8_t path_len, const char* from_name, const char* text, i startNeonPulse(message_color); #endif - ((MsgPreviewScreen *) msg_preview)->addPreview(path_len, from_name, text); + const int local_unread = ((MsgPreviewScreen *) msg_preview)->addPreview(path_len, from_name, text); +#ifdef HELTEC_RCC6_NEON_UI + _msgcount = local_unread; + _unread_overflow = ((MsgPreviewScreen *) msg_preview)->hasOverflowed(); +#endif setCurrScreen(msg_preview); if (_display != NULL) { @@ -1395,6 +1531,10 @@ void UITask::loop() { char c = 0; #ifdef HELTEC_RCC6_NEON_UI const unsigned long event_now = millis(); + if (_power_confirm_until != 0 && (int32_t)(event_now - _power_confirm_until) >= 0) { + _power_confirm_until = 0; + _next_refresh = 0; + } if (_wake_pending && _display != NULL) { _wake_pending = false; if (!_display->isOn()) _display->turnOn(); @@ -1443,7 +1583,7 @@ void UITask::loop() { (int32_t)(_manual_advert_until - event_now) >= 0; _manual_advert_until = 0; if (armed) { - showAlert(ok ? "Advert transmitted" : "Advert failed", 1000, + showAlert(ok ? "Mesh advert sent" : "Advert failed", 1000, ok ? DisplayDriver::GREEN : DisplayDriver::RED); } } @@ -1454,7 +1594,11 @@ void UITask::loop() { _last_connection = connected; } else if (connected != _last_connection) { _last_connection = connected; +#ifdef RCC6_WEB_AP + showAlert(connected ? "Network client" : "Client disconnected", 900, +#else showAlert(connected ? "Phone connected" : "Phone disconnected", 900, +#endif connected ? DisplayDriver::GREEN : DisplayDriver::RED); } #endif @@ -1557,8 +1701,6 @@ void UITask::loop() { const bool alert_active = now < _alert_expiry; const bool alert_animating = alert_active && now - _alert_started < 300; const bool pulse_active = now < _pulse_until; - const bool menu_animating = _menu_open && now - _menu_started < NEON_TRANSITION_MILLIS; - if (_menu_open) renderNeonMenu(*_display); if (alert_active) { const unsigned long elapsed = now - _alert_started; const int slide = elapsed >= 300 ? 0 : (int)((300 - elapsed) * 16 / 300); @@ -1575,7 +1717,7 @@ void UITask::loop() { _display->fillRect(0, 0, _display->width(), 3); _display->fillRect(0, _display->height() - 3, _display->width(), 3); } - if (alert_animating || pulse_active || menu_animating) { + if (alert_animating || pulse_active) { _next_refresh = now + NEON_FRAME_MILLIS; } else if (alert_active) { const unsigned long page_refresh = now + delay_millis; @@ -1611,7 +1753,10 @@ void UITask::loop() { _auto_off = millis() + AUTO_OFF_MILLIS; } #endif - if (millis() > _auto_off) { + if ((int32_t)(millis() - _auto_off) >= 0) { +#ifdef HELTEC_RCC6_NEON_UI + _power_confirm_until = 0; +#endif _display->turnOff(); } #endif @@ -1692,7 +1837,10 @@ char UITask::handleLongPress(char c) { char UITask::handleDoubleClick(char c) { MESH_DEBUG_PRINTLN("UITask: double-click triggered"); #ifdef HELTEC_RCC6_NEON_UI - return checkDisplayOn(c); + _power_confirm_until = 0; + c = checkDisplayOn(KEY_ENTER); + if (c != 0 && curr) curr->handleInput(c); + return 0; #else checkDisplayOn(c); return c; diff --git a/examples/companion_radio/ui-new/UITask.h b/examples/companion_radio/ui-new/UITask.h index e4164aa7..a5f30a5c 100644 --- a/examples/companion_radio/ui-new/UITask.h +++ b/examples/companion_radio/ui-new/UITask.h @@ -47,9 +47,7 @@ class UITask : public AbstractUITask { bool _wake_pending = false; bool _connection_known = false; bool _last_connection = false; - bool _menu_open = false; - uint8_t _menu_index = 0; - unsigned long _menu_started = 0; + unsigned long _power_confirm_until = 0; char _latest_sender[32] = ""; char _latest_preview[48] = ""; bool _radio_rx_pending = false; @@ -65,11 +63,10 @@ class UITask : public AbstractUITask { bool _battery_low_warning = false; unsigned long _manual_advert_until = 0; DisplayDriver::Color _next_message_color = DisplayDriver::YELLOW; + bool _unread_overflow = false; void startNeonPulse(DisplayDriver::Color color, unsigned long duration_millis = 300); bool handleNeonInput(char c); - void selectNeonMenuItem(); - void renderNeonMenu(DisplayDriver& display); #endif unsigned long ui_started_at, next_batt_chck; int next_backlight_btn_check = 0; @@ -108,6 +105,9 @@ class UITask : public AbstractUITask { void begin(DisplayDriver* display, SensorManager* sensors, NodePrefs* node_prefs); void gotoHomeScreen() { setCurrScreen(home); } +#ifdef HELTEC_RCC6_NEON_UI + void gotoMsgPreviewScreen() { setCurrScreen(msg_preview); } +#endif void showAlert(const char* text, int duration_millis, DisplayDriver::Color color = DisplayDriver::LIGHT); int getMsgCount() const { return _msgcount; } @@ -115,6 +115,10 @@ class UITask : public AbstractUITask { const char* getLatestSender() const { return _latest_sender; } const char* getLatestPreview() const { return _latest_preview; } bool hasLatestPreview() const { return _latest_preview[0] != 0; } + bool hasUnreadOverflow() const { return _unread_overflow; } + void setLocalUnread(int count, const char* sender = nullptr, const char* preview = nullptr, + bool overflow = false); + bool isPowerConfirmArmed() const; uint16_t getCachedBattMilliVolts() const { return _cached_batt_millivolts; } bool hasCachedRadioSample() const { return _radio_sample_known; } int16_t getCachedRadioRSSI() const { return _radio_rssi_dbm; } diff --git a/examples/companion_radio/webui/.gitignore b/examples/companion_radio/webui/.gitignore new file mode 100644 index 00000000..444ae09c --- /dev/null +++ b/examples/companion_radio/webui/.gitignore @@ -0,0 +1,5 @@ +node_modules/ +.cache/ +.tmp/ +.build/ +.inspect/ diff --git a/examples/companion_radio/webui/README.md b/examples/companion_radio/webui/README.md new file mode 100644 index 00000000..1e8ff01d --- /dev/null +++ b/examples/companion_radio/webui/README.md @@ -0,0 +1,35 @@ +# RCC6 MeshCore WebUI + +Responsive, offline WebUI for the RCC6 companion radio. It starts on a 2.4 GHz setup AP and can save a local 2.4 GHz SSID/password, reboot into station mode, and show its DHCP address on the TFT. + +The browser uses the MeshCore companion protocol through a polling HTTP transport: + +- `POST /api/frame` accepts one raw companion payload as `application/octet-stream`. +- `GET /api/frame` returns one raw companion payload, or HTTP `204` when none is queued. +- Frames larger than 176 bytes are rejected by the browser transport. + +The generated UI is a single gzip-compressed HTML document. The firmware translation unit that owns the asset must define `RCC6_WEB_UI_ASSETS_IMPLEMENTATION` before including `Rcc6WebUiAssets.h`. Other translation units include the header normally. + +## Build + +Keep npm cache and temporary files on the F: worktree: + +```powershell +$env:npm_config_cache = "$PWD\.cache" +$env:TEMP = "$PWD\.tmp" +$env:TMP = "$PWD\.tmp" +npm ci +npm test +``` + +`npm test` bundles the app, creates `Rcc6WebUiAssets.h`, decompresses the generated byte array, and checks the endpoint and screen contract. The UI imports `Connection` and `Constants` directly from MeshCore.js so Node-only serial transports are not included. + +MeshCore.js 1.14.0 parses the current firmware's core-stats payload incorrectly, so this UI intentionally uses `getBatteryVoltage()`, `getStatsRadio()`, and `getStatsPackets()` and does not display core queue depth. + +## Security boundary + +This browser code exposes only query, sync, send, and self-advert actions. The HTTP transport must enforce the same command allowlist and one-controller policy server-side; browser validation is not a security boundary. + +Station-mode HTTP uses Basic authentication with username `meshcore` and the device key shown on the TFT. Raw TCP port 5000 remains the full, unauthenticated MeshCore companion/admin protocol for native clients. Only enable station mode on a trusted private LAN: any host on that LAN can control the radio over TCP, including administrative commands. + +See `THIRD_PARTY_NOTICES.md` for bundled software attribution. diff --git a/examples/companion_radio/webui/Rcc6WebUiAssets.h b/examples/companion_radio/webui/Rcc6WebUiAssets.h new file mode 100644 index 00000000..f5af7bc3 --- /dev/null +++ b/examples/companion_radio/webui/Rcc6WebUiAssets.h @@ -0,0 +1,2758 @@ +// Generated by examples/companion_radio/webui/build.mjs. Do not edit. +// gzip sha256: 26378715a14eccafbde5ebfb5bca42d33e7384c0f6ef605f738658223ed4b7e8 +#pragma once +#include + +extern const uint8_t RCC6_WEB_UI_INDEX_GZ[] PROGMEM; +extern const size_t RCC6_WEB_UI_INDEX_GZ_LEN; + +#ifdef RCC6_WEB_UI_ASSETS_IMPLEMENTATION +const uint8_t RCC6_WEB_UI_INDEX_GZ[] PROGMEM = { + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0xbd, 0xdb, 0x72, 0xdb, 0x48, + 0xb2, 0x28, 0xfa, 0x3e, 0x5f, 0x01, 0xb1, 0xdb, 0x1a, 0xc0, 0x2a, 0xd2, 0x00, 0x08, 0xf0, 0x02, + 0x0a, 0xf4, 0x96, 0x64, 0xc9, 0xf6, 0x6a, 0xb7, 0x64, 0x4b, 0x72, 0xfb, 0xa2, 0xd0, 0xb8, 0x71, + 0x29, 0x88, 0x68, 0x81, 0x00, 0x1b, 0x00, 0x29, 0xd1, 0x14, 0x77, 0xac, 0xa7, 0xf3, 0x01, 0x67, + 0x9f, 0x88, 0xf3, 0x07, 0x3b, 0xe2, 0x7c, 0xc1, 0x7e, 0x5f, 0xfb, 0x4f, 0xe6, 0x4b, 0x76, 0x64, + 0x55, 0x01, 0x28, 0x5c, 0x48, 0xc9, 0xd3, 0x13, 0x67, 0xf5, 0x1a, 0x8b, 0x2c, 0x14, 0xb2, 0xb2, + 0xb2, 0x32, 0xb3, 0xf2, 0x56, 0xc5, 0xfd, 0x1d, 0x37, 0x72, 0xd2, 0xe5, 0x0c, 0x0b, 0x93, 0x74, + 0x1a, 0x8c, 0xff, 0xb6, 0x0f, 0x7f, 0x84, 0xc0, 0x0a, 0x6f, 0xcc, 0x16, 0x0e, 0x5b, 0xd0, 0x80, + 0x2d, 0x77, 0xfc, 0x37, 0x41, 0xd8, 0x9f, 0xe2, 0xd4, 0x12, 0x9c, 0x89, 0x15, 0x27, 0x38, 0x35, + 0x5b, 0xf3, 0xd4, 0x6b, 0x0f, 0x5a, 0xc5, 0x83, 0xd0, 0x9a, 0x62, 0xb3, 0xb5, 0xf0, 0xf1, 0xdd, + 0x2c, 0x8a, 0xd3, 0x96, 0xe0, 0x44, 0x61, 0x8a, 0xc3, 0xd4, 0x6c, 0xdd, 0xf9, 0x6e, 0x3a, 0x31, + 0x5d, 0xbc, 0xf0, 0x1d, 0xdc, 0x26, 0x5f, 0x90, 0x1f, 0xfa, 0xa9, 0x6f, 0x05, 0xed, 0xc4, 0xb1, + 0x02, 0x6c, 0x2a, 0x28, 0x7b, 0xab, 0xed, 0xf9, 0xa9, 0xe9, 0x44, 0x0b, 0x1c, 0xd7, 0x00, 0xa7, + 0x13, 0x3c, 0xc5, 0x6d, 0x27, 0x0a, 0xa2, 0x98, 0x83, 0xfd, 0x93, 0xac, 0xcb, 0x3d, 0xb9, 0x8e, + 0x86, 0x35, 0x9b, 0x05, 0xb8, 0x3d, 0x8d, 0x6c, 0x3f, 0xc0, 0xed, 0x3b, 0x6c, 0xb7, 0xad, 0xd9, + 0xac, 0xed, 0x58, 0x33, 0xcb, 0x0e, 0x30, 0xf7, 0xfa, 0x12, 0x27, 0x4f, 0x7b, 0x35, 0x49, 0xad, + 0x74, 0x9e, 0xb4, 0x6d, 0x2b, 0x6e, 0x27, 0xe9, 0xb2, 0x04, 0xc3, 0x0e, 0x2c, 0xe7, 0xb6, 0x9d, + 0xc6, 0x56, 0x98, 0x04, 0x73, 0x07, 0x87, 0x29, 0x07, 0x71, 0x92, 0xa6, 0xb3, 0x36, 0xfe, 0x73, + 0xee, 0x2f, 0xcc, 0xd6, 0x11, 0x7d, 0xa1, 0x7d, 0x81, 0x9d, 0x79, 0xec, 0xa7, 0xcb, 0xf6, 0xfb, + 0x28, 0xf0, 0x9d, 0x25, 0x07, 0xc9, 0xc5, 0x9e, 0x35, 0x0f, 0xd2, 0x76, 0x12, 0x3b, 0xc2, 0xdf, + 0x13, 0x1c, 0x78, 0x7f, 0x1f, 0xc1, 0xc3, 0x10, 0x3b, 0xe5, 0x36, 0x7f, 0x7a, 0xc3, 0x7d, 0x17, + 0x5c, 0x2b, 0xb5, 0x8c, 0x91, 0x90, 0x38, 0xb1, 0x3f, 0x63, 0x1d, 0xe7, 0x61, 0x62, 0x79, 0xb8, + 0xed, 0x87, 0x81, 0x1f, 0xe2, 0xbf, 0x8f, 0x04, 0x82, 0x73, 0xf3, 0x23, 0xdb, 0x4a, 0x70, 0x7b, + 0x1e, 0xfb, 0xc2, 0xdf, 0xc3, 0x88, 0x34, 0x44, 0xf6, 0x1f, 0xf9, 0x80, 0xa4, 0x89, 0xce, 0x27, + 0xf5, 0xd3, 0x00, 0x8f, 0x7f, 0xc5, 0xc9, 0xe4, 0x28, 0x8a, 0xb1, 0xf0, 0x5f, 0xff, 0x4b, 0x38, + 0x3f, 0x3a, 0xea, 0xed, 0xbf, 0xa0, 0xed, 0xd0, 0x83, 0x0c, 0x32, 0x36, 0xe2, 0x28, 0x4a, 0x57, + 0x64, 0x9d, 0xda, 0x89, 0x03, 0x8b, 0x66, 0xb8, 0x56, 0x7c, 0x3b, 0x6a, 0xb7, 0xed, 0x1b, 0x43, + 0x60, 0xeb, 0x35, 0x6a, 0xb7, 0x67, 0x56, 0x88, 0x03, 0x68, 0x70, 0x64, 0x4f, 0xe9, 0x66, 0x0d, + 0x6d, 0xd5, 0x10, 0x7e, 0x52, 0x14, 0x45, 0x57, 0xec, 0x51, 0xbb, 0x0d, 0x28, 0x1a, 0xc2, 0x4f, + 0xaa, 0xaa, 0x0e, 0xbb, 0xda, 0xa8, 0xdd, 0x4e, 0xf1, 0x7d, 0x6a, 0x08, 0x3f, 0x79, 0xba, 0x37, + 0xf0, 0xe0, 0xf9, 0x74, 0x9e, 0x62, 0xd7, 0x10, 0x7e, 0x1a, 0xb8, 0xc3, 0x81, 0xd5, 0x1f, 0xb5, + 0xdb, 0x37, 0x31, 0xc6, 0xa1, 0x21, 0xfc, 0xa4, 0x69, 0x9e, 0x3c, 0xb0, 0x60, 0xcc, 0x60, 0x0e, + 0x10, 0x34, 0xd5, 0xd2, 0x3d, 0x6f, 0xd4, 0x6e, 0x2f, 0x71, 0x10, 0x44, 0x77, 0x00, 0xc3, 0x73, + 0x35, 0x0d, 0x5e, 0x89, 0x62, 0x2b, 0xbc, 0xc1, 0xa4, 0x65, 0x60, 0x75, 0xdd, 0x51, 0xbb, 0x1d, + 0x13, 0x98, 0x9e, 0xa7, 0x6b, 0x3d, 0x40, 0x34, 0xb6, 0x5c, 0x7f, 0x9e, 0x18, 0x82, 0xaa, 0xce, + 0xee, 0x47, 0xed, 0x76, 0x32, 0xb1, 0x5c, 0x80, 0x20, 0x0b, 0xaa, 0x3c, 0xbb, 0x17, 0xfa, 0xf0, + 0x4f, 0x7c, 0x63, 0x5b, 0xa2, 0x8c, 0x04, 0xfa, 0xff, 0x9d, 0xae, 0x2a, 0x8d, 0xbc, 0x28, 0x4c, + 0xdb, 0x9e, 0x35, 0xf5, 0x83, 0xa5, 0xd1, 0xa6, 0x2c, 0x95, 0x2c, 0x93, 0x14, 0x4f, 0xd1, 0x61, + 0xe0, 0x87, 0xb7, 0xbf, 0x5a, 0xce, 0x05, 0xf9, 0x7a, 0x12, 0x85, 0x29, 0xba, 0x38, 0x11, 0xde, + 0xc7, 0x91, 0xf0, 0xca, 0x4f, 0x66, 0x81, 0xb5, 0x44, 0x17, 0xf8, 0x26, 0xc2, 0xc2, 0xc7, 0xb7, + 0x28, 0xb1, 0xc2, 0xa4, 0x9d, 0xe0, 0xd8, 0xf7, 0x46, 0xb6, 0xe5, 0xdc, 0xde, 0xc4, 0xd1, 0x3c, + 0x74, 0x8d, 0x85, 0x15, 0x8b, 0x40, 0x4d, 0x69, 0x44, 0xa8, 0xcc, 0xbe, 0x03, 0x6d, 0xd8, 0xb0, + 0xc9, 0x32, 0x4c, 0x27, 0x38, 0xf1, 0x13, 0x03, 0xd6, 0x6f, 0xfd, 0x7c, 0x65, 0x47, 0xf7, 0xed, + 0xc4, 0xff, 0xee, 0x87, 0x37, 0x86, 0x1d, 0xc5, 0x2e, 0x8e, 0xdb, 0x76, 0x74, 0xbf, 0xbe, 0x9a, + 0xf8, 0xae, 0x8b, 0xc3, 0xeb, 0x95, 0x4b, 0xc7, 0x25, 0xbd, 0x77, 0xfc, 0x29, 0x08, 0xa2, 0x15, + 0xa6, 0x6b, 0x50, 0x04, 0xab, 0xa9, 0x1f, 0xb6, 0x27, 0xd8, 0xbf, 0x99, 0xa4, 0x86, 0x22, 0xcb, + 0xcf, 0x1a, 0xf1, 0x58, 0xdb, 0x91, 0xbb, 0x5c, 0x4d, 0xad, 0xf8, 0xc6, 0x0f, 0x0d, 0x79, 0x54, + 0x7e, 0x65, 0x31, 0xa9, 0x34, 0xb8, 0x8b, 0xc9, 0x08, 0x24, 0xdc, 0x0b, 0xa2, 0xbb, 0xf6, 0xbd, + 0x41, 0x91, 0xe0, 0xe1, 0x02, 0xc1, 0xad, 0xa0, 0x7d, 0x03, 0x7f, 0x71, 0x98, 0x8a, 0x8e, 0x1f, + 0x3b, 0x01, 0x16, 0xac, 0x54, 0xe8, 0xeb, 0xcf, 0x84, 0xb6, 0xa2, 0x3f, 0x43, 0x84, 0xe0, 0xbd, + 0x1e, 0x52, 0x7a, 0x3a, 0x52, 0x75, 0x1d, 0x75, 0x14, 0x55, 0x42, 0x44, 0x04, 0x67, 0x56, 0x8c, + 0xc3, 0x54, 0xe8, 0xaa, 0x31, 0x9e, 0x4a, 0x68, 0x33, 0x28, 0x55, 0x7e, 0x26, 0x28, 0x8a, 0x9c, + 0x81, 0x1a, 0x20, 0x55, 0x93, 0x91, 0xd2, 0x1d, 0xa0, 0x8e, 0x3c, 0xa8, 0x80, 0xd2, 0x09, 0x28, + 0x6e, 0xb6, 0xf3, 0x34, 0x8d, 0x42, 0x04, 0x04, 0xb7, 0x62, 0x6c, 0xa1, 0x04, 0x07, 0xd8, 0x49, + 0x57, 0x40, 0x7a, 0xc3, 0x0f, 0x27, 0x38, 0xf6, 0x53, 0xb6, 0x32, 0xec, 0x1b, 0x7b, 0x63, 0x45, + 0x69, 0x6f, 0xc8, 0x23, 0x67, 0x1e, 0x27, 0x51, 0x6c, 0xcc, 0x22, 0x3f, 0x4c, 0x71, 0xbc, 0xf6, + 0xc3, 0xd9, 0xfc, 0x09, 0xef, 0x1b, 0x5e, 0xe4, 0xcc, 0x93, 0xf6, 0xc2, 0x4f, 0x7c, 0x3b, 0xc0, + 0xf9, 0xf8, 0x95, 0x66, 0x8a, 0x4d, 0xb9, 0x71, 0x15, 0xcd, 0x53, 0x22, 0x4b, 0xea, 0xec, 0x5e, + 0x48, 0xa2, 0xc0, 0x77, 0x05, 0x36, 0x9d, 0x60, 0x8e, 0xa5, 0x11, 0x7b, 0xda, 0x8e, 0x3c, 0x2f, + 0xc1, 0x29, 0x74, 0xa2, 0x28, 0xfd, 0x55, 0x20, 0xc9, 0xe2, 0x66, 0x45, 0xf4, 0xbd, 0x41, 0x64, + 0x87, 0xb1, 0x00, 0xf9, 0xec, 0xf9, 0x41, 0x40, 0xf8, 0x6d, 0x94, 0xa4, 0x71, 0x74, 0x8b, 0x0d, + 0x67, 0x1e, 0x03, 0xb5, 0x8f, 0x60, 0xde, 0xac, 0x8d, 0xee, 0x15, 0x86, 0xd2, 0x19, 0x64, 0x0d, + 0x30, 0x80, 0x63, 0xcd, 0x0c, 0xc2, 0x27, 0x7c, 0xe3, 0x1f, 0x91, 0x1f, 0xd2, 0xd6, 0x75, 0x27, + 0x59, 0xdc, 0xb4, 0x5d, 0xec, 0x25, 0xab, 0x59, 0x94, 0xf8, 0xa9, 0x1f, 0x85, 0x86, 0x65, 0x27, + 0x51, 0x30, 0x4f, 0xf1, 0x88, 0x02, 0x94, 0x33, 0x4c, 0xe4, 0x75, 0x27, 0x89, 0xdb, 0x51, 0x18, + 0x2c, 0x37, 0xf6, 0x55, 0x0a, 0xbc, 0xe1, 0xe3, 0xcc, 0x72, 0x5d, 0x90, 0x22, 0x79, 0xc4, 0xb8, + 0xbd, 0x0d, 0xad, 0x19, 0x37, 0x67, 0xbc, 0xec, 0x04, 0xfe, 0xcc, 0x88, 0xb1, 0x93, 0x8a, 0x32, + 0x22, 0xff, 0x49, 0xa3, 0xbb, 0x89, 0x9f, 0xe2, 0x76, 0x32, 0xb3, 0x1c, 0x6c, 0x84, 0xd1, 0x5d, + 0x6c, 0xcd, 0x46, 0x19, 0x37, 0xac, 0x3b, 0xc9, 0x04, 0x07, 0x41, 0x2e, 0x85, 0x37, 0xb1, 0xef, + 0x8e, 0xe0, 0x9f, 0x76, 0x8a, 0xa7, 0xb3, 0xc0, 0x4a, 0xc9, 0xae, 0x37, 0x9f, 0x86, 0x89, 0xa1, + 0xaa, 0xda, 0xec, 0x5e, 0x98, 0xfa, 0xe1, 0xd4, 0xba, 0x17, 0x65, 0xa4, 0x78, 0xb1, 0xf4, 0x04, + 0x69, 0x5b, 0x77, 0x12, 0xdf, 0xc5, 0xb6, 0x15, 0x17, 0xb3, 0xf4, 0xfc, 0x7b, 0xec, 0x8e, 0xbe, + 0xb7, 0xfd, 0xd0, 0xc5, 0xf7, 0x86, 0x2a, 0x8f, 0xfc, 0x10, 0x16, 0x4d, 0x16, 0xac, 0x79, 0x1a, + 0x09, 0xb2, 0x20, 0x8f, 0xb2, 0x75, 0xd3, 0xb8, 0x59, 0xab, 0x83, 0xd9, 0xbd, 0xa0, 0xc0, 0x3f, + 0x64, 0x0d, 0x33, 0x84, 0xbd, 0x00, 0xdf, 0x8f, 0xe0, 0x9f, 0xb6, 0xeb, 0xc3, 0xac, 0x61, 0x00, + 0x8a, 0x31, 0x9b, 0x63, 0x3b, 0xce, 0x08, 0xc8, 0xf8, 0x86, 0xc8, 0x1c, 0xc8, 0x6d, 0xf6, 0xbf, + 0x8e, 0xac, 0xeb, 0x12, 0xaf, 0x03, 0x7e, 0x82, 0x5d, 0x42, 0xb6, 0xb1, 0x4c, 0x1a, 0xdd, 0x38, + 0x9a, 0xb5, 0x3d, 0x3f, 0x48, 0x71, 0x6c, 0xd8, 0xc1, 0x3c, 0x16, 0x61, 0x7c, 0x69, 0xdd, 0xb1, + 0x63, 0x2b, 0x74, 0x57, 0x25, 0x3c, 0xac, 0xc0, 0xbf, 0x09, 0xdb, 0x7e, 0x8a, 0xa7, 0x89, 0x01, + 0x9b, 0x31, 0x8e, 0x47, 0x37, 0xd6, 0xcc, 0x50, 0x54, 0x6e, 0x1e, 0x40, 0x44, 0x05, 0xf4, 0x76, + 0x97, 0xb0, 0x22, 0xa8, 0xcc, 0x3b, 0x4a, 0xb0, 0xbe, 0x26, 0x8f, 0x02, 0x9c, 0xa6, 0x38, 0x26, + 0x6b, 0x05, 0x9d, 0xdb, 0x1d, 0xb9, 0x8b, 0xa7, 0x4c, 0xb1, 0xfa, 0xdf, 0xb1, 0xa1, 0x0c, 0x67, + 0xf7, 0x6c, 0x68, 0x21, 0x99, 0x5a, 0xdc, 0xca, 0xd9, 0x41, 0xe4, 0xdc, 0x32, 0xce, 0x68, 0xa7, + 0xd1, 0xcc, 0xc8, 0xc1, 0x93, 0x17, 0x87, 0xb3, 0xfb, 0x2a, 0xf0, 0x8e, 0xd2, 0xc3, 0xd3, 0x92, + 0x1a, 0x27, 0x5b, 0x9a, 0x34, 0x02, 0xe1, 0xa6, 0x36, 0x85, 0x17, 0xc5, 0x53, 0x63, 0x3e, 0x9b, + 0xe1, 0xd8, 0xb1, 0x12, 0xcc, 0x06, 0x6e, 0x4f, 0xad, 0xf8, 0x96, 0xc9, 0x56, 0x57, 0x2e, 0x78, + 0x94, 0x7c, 0xce, 0x57, 0x39, 0xc6, 0x81, 0x95, 0xfa, 0x0b, 0x9c, 0xaf, 0x14, 0xdd, 0xf4, 0xdb, + 0x84, 0xc3, 0x66, 0x81, 0xe5, 0xe0, 0x32, 0xa1, 0x18, 0x47, 0x56, 0xe5, 0x9b, 0x6c, 0xaa, 0x52, + 0xbe, 0x96, 0x74, 0x3b, 0xd4, 0x61, 0x2f, 0x80, 0x6d, 0x85, 0x6e, 0x87, 0xb2, 0x20, 0x53, 0xce, + 0x60, 0x5b, 0xaf, 0xa6, 0x22, 0xc2, 0x52, 0x02, 0x79, 0xa0, 0x16, 0x0f, 0x14, 0x8f, 0x9f, 0x82, + 0x61, 0x63, 0x2f, 0x8a, 0x31, 0xe2, 0x9b, 0x2c, 0x2f, 0xc5, 0x31, 0xdf, 0x22, 0xf8, 0x2b, 0x66, + 0x22, 0x19, 0xad, 0xd6, 0xa8, 0x2e, 0xa9, 0x4d, 0x88, 0x91, 0x89, 0x54, 0x18, 0x8e, 0x57, 0xf2, + 0x7d, 0xa9, 0x01, 0x0d, 0x46, 0x50, 0x85, 0x23, 0x28, 0x7c, 0x5e, 0xd7, 0xb0, 0xcb, 0x28, 0xcf, + 0x11, 0x7e, 0x76, 0x5f, 0xdf, 0x1a, 0x4b, 0x84, 0x33, 0xe4, 0x1a, 0xbd, 0x80, 0x05, 0xf9, 0x9e, + 0xeb, 0xf2, 0xa4, 0x99, 0x08, 0x72, 0xd8, 0xf4, 0x60, 0x14, 0x3a, 0x5b, 0xca, 0x33, 0x8c, 0xa8, + 0x03, 0x87, 0x7f, 0xb5, 0x13, 0x58, 0xf1, 0x4d, 0x36, 0x19, 0x7d, 0x50, 0xbc, 0x4e, 0x3e, 0x57, + 0x90, 0xe8, 0xea, 0xc5, 0xda, 0xe8, 0xc3, 0x3a, 0x98, 0x32, 0x69, 0x78, 0x64, 0xd4, 0x0a, 0x69, + 0x68, 0xff, 0x1c, 0x6f, 0x8d, 0xa7, 0x22, 0xec, 0x06, 0x9d, 0xd0, 0x5a, 0x54, 0x94, 0x9c, 0x35, + 0x33, 0xfa, 0xec, 0x89, 0xc0, 0xf6, 0xc8, 0x3a, 0xf3, 0x72, 0xfa, 0x4c, 0x1b, 0xf2, 0x3a, 0x58, + 0x50, 0xba, 0x55, 0x2d, 0xb4, 0x49, 0xfa, 0xa1, 0x63, 0x83, 0x94, 0x95, 0x39, 0x47, 0xd1, 0xca, + 0x8b, 0xc8, 0x19, 0x01, 0x54, 0x1e, 0x09, 0x74, 0x23, 0xc0, 0x5e, 0x3a, 0x22, 0xcf, 0xfc, 0x4c, + 0xd5, 0x45, 0xb1, 0xd0, 0x51, 0x13, 0x01, 0x5b, 0x09, 0x46, 0x05, 0x80, 0xa2, 0x2d, 0x17, 0xe4, + 0xbc, 0x89, 0x9f, 0xb3, 0x31, 0x81, 0x0d, 0x64, 0x55, 0x37, 0xe6, 0x78, 0x7d, 0xe8, 0x91, 0xff, + 0x93, 0x6d, 0xfe, 0xc5, 0x8e, 0xe5, 0x00, 0x85, 0x4a, 0x6f, 0x66, 0x3c, 0x57, 0xbc, 0x0a, 0x22, + 0x6f, 0xc5, 0x85, 0x0d, 0x34, 0x94, 0x5d, 0x7c, 0x83, 0xd8, 0x92, 0xab, 0x4a, 0xf6, 0x49, 0x1e, + 0x4a, 0x3c, 0x6f, 0x50, 0xe9, 0x05, 0xc1, 0x95, 0x2b, 0x3c, 0xca, 0x21, 0xce, 0xc6, 0x2f, 0xf4, + 0x14, 0xf1, 0xe7, 0xc4, 0xce, 0x70, 0x50, 0xea, 0x27, 0x24, 0x33, 0x2b, 0x5c, 0x71, 0x1a, 0x54, + 0xab, 0xa8, 0xdd, 0x9e, 0x2e, 0x97, 0xfa, 0xdb, 0xcc, 0x98, 0x6c, 0x03, 0xad, 0x0d, 0xd8, 0x93, + 0x08, 0x17, 0x34, 0xf3, 0x20, 0xc7, 0x10, 0x3d, 0x8e, 0x1f, 0xb6, 0x2b, 0xb9, 0x7c, 0xcd, 0xe5, + 0x9c, 0x33, 0x7e, 0x52, 0x54, 0x19, 0xcb, 0x72, 0x5d, 0x8c, 0xa9, 0xcf, 0x20, 0xf1, 0x5b, 0x00, + 0x61, 0x7d, 0xb6, 0xab, 0xb6, 0x3d, 0x70, 0x78, 0x38, 0xad, 0x4f, 0xf0, 0xcd, 0x90, 0x52, 0xc8, + 0x66, 0x03, 0x9a, 0x48, 0x2e, 0xb3, 0x2a, 0xf0, 0x25, 0xc8, 0x63, 0x03, 0xcb, 0x36, 0x70, 0x2a, + 0x37, 0xb6, 0x42, 0xc6, 0xa6, 0xfe, 0xa8, 0x1b, 0xa5, 0x4c, 0xdc, 0x38, 0x31, 0x1f, 0x70, 0x54, + 0x60, 0x1a, 0x9f, 0xee, 0x4c, 0x30, 0x2e, 0x11, 0x7a, 0x82, 0x61, 0x83, 0xda, 0xdc, 0x34, 0xf3, + 0xaa, 0xe2, 0x02, 0xb6, 0xe0, 0x0d, 0xb6, 0x75, 0x87, 0xb9, 0xa9, 0xd8, 0x15, 0x38, 0xd4, 0x10, + 0xf7, 0xb9, 0xe8, 0xf1, 0x08, 0xbb, 0x96, 0x99, 0x2d, 0xc6, 0xec, 0x3d, 0x3f, 0xbc, 0xd9, 0x08, + 0x9a, 0xef, 0x84, 0x3a, 0xf6, 0x3c, 0x59, 0x6e, 0xec, 0x0a, 0x0f, 0x4b, 0x08, 0xe4, 0x53, 0xdc, + 0x30, 0xf7, 0x75, 0x27, 0xf2, 0x3c, 0xa0, 0xe1, 0x46, 0x90, 0xec, 0x79, 0x09, 0x6a, 0x4c, 0xb4, + 0x4b, 0x15, 0x24, 0xb4, 0xae, 0xa7, 0x96, 0x1f, 0xae, 0x88, 0x79, 0x47, 0x6d, 0x24, 0x43, 0x65, + 0xb6, 0xd6, 0xd4, 0x0f, 0x45, 0x70, 0xb1, 0x90, 0xd2, 0x05, 0xb6, 0x96, 0x32, 0x13, 0x93, 0x2d, + 0x57, 0x6e, 0x84, 0x01, 0x43, 0x39, 0x81, 0x35, 0x9d, 0x89, 0xf0, 0x11, 0x69, 0x8b, 0x3b, 0xd4, + 0x03, 0x73, 0x48, 0xd0, 0x35, 0xe0, 0x8c, 0x34, 0x9a, 0x81, 0xa9, 0xc7, 0x69, 0xcd, 0xbe, 0xfa, + 0x04, 0x35, 0xf9, 0xc7, 0x3c, 0x49, 0x7d, 0x6f, 0xd9, 0xce, 0x76, 0x5a, 0x62, 0xaa, 0xb6, 0x6d, + 0x9c, 0xde, 0x61, 0x1c, 0x12, 0x66, 0x25, 0xb2, 0xc6, 0xd8, 0xdc, 0x8e, 0xd2, 0x34, 0x9a, 0x12, + 0x53, 0x3e, 0x1b, 0x51, 0x98, 0x28, 0x99, 0x0b, 0x48, 0xb5, 0x86, 0xcc, 0x31, 0x2d, 0xc3, 0xb7, + 0x3f, 0xbb, 0x47, 0xdd, 0xc5, 0x1d, 0xea, 0x0e, 0x60, 0x7e, 0x84, 0x33, 0xb3, 0x1d, 0xa2, 0xc1, + 0xec, 0xd2, 0x74, 0x3c, 0x5d, 0x77, 0xf0, 0x12, 0xdb, 0x71, 0x74, 0x57, 0xb8, 0x97, 0x5b, 0xa5, + 0x83, 0xd8, 0x58, 0x3c, 0xdc, 0x8e, 0x5a, 0x36, 0xf0, 0x7a, 0x72, 0xdd, 0x06, 0x1b, 0xe0, 0xe9, + 0x16, 0x83, 0x2b, 0x8d, 0x66, 0x6d, 0x8b, 0x58, 0xb5, 0xc9, 0x93, 0x4c, 0x4d, 0x6a, 0x1e, 0x5a, + 0x30, 0xc6, 0x12, 0x75, 0xc0, 0xd9, 0x6f, 0x3b, 0x13, 0x7f, 0xb6, 0xca, 0x2c, 0x85, 0xc1, 0xe6, + 0x3d, 0x8c, 0x49, 0xeb, 0x36, 0xe8, 0x83, 0xdc, 0x04, 0xe0, 0xcc, 0x1b, 0x4a, 0x0c, 0x78, 0xb7, + 0xb6, 0xa7, 0x55, 0x0c, 0x93, 0x9f, 0x64, 0x57, 0x91, 0x15, 0xdd, 0x55, 0x1e, 0x57, 0x32, 0x65, + 0xba, 0xc9, 0x75, 0xba, 0x81, 0x5d, 0xbc, 0x2e, 0x26, 0xc8, 0xb6, 0xb1, 0xb2, 0x7d, 0xd2, 0x1d, + 0x6a, 0x5d, 0x5d, 0xa9, 0x07, 0x2a, 0xd6, 0x9d, 0xc4, 0x01, 0x11, 0x2f, 0xc5, 0x1e, 0x46, 0x56, + 0xe8, 0x4f, 0x2d, 0xb2, 0xa9, 0xd2, 0xa7, 0x6d, 0x3f, 0x14, 0x3a, 0xaa, 0x96, 0x08, 0xce, 0xdc, + 0xf6, 0x9d, 0xb6, 0x8d, 0xbf, 0xfb, 0x38, 0x16, 0x3b, 0x2a, 0xea, 0xf4, 0x75, 0xd4, 0x51, 0x75, + 0xa4, 0xe4, 0x80, 0xb2, 0xbd, 0xb0, 0x64, 0x8b, 0xaf, 0xff, 0xdb, 0x2d, 0x5e, 0x7a, 0xb1, 0x35, + 0xc5, 0x89, 0x90, 0x43, 0x5c, 0xc9, 0xcf, 0x56, 0x11, 0xcc, 0x21, 0x5d, 0x1a, 0xf2, 0xa8, 0x58, + 0x72, 0x1a, 0xc1, 0xb3, 0x52, 0xfc, 0x45, 0x04, 0xf6, 0x5c, 0xa7, 0x51, 0xde, 0x4d, 0xe1, 0xba, + 0x91, 0x90, 0xca, 0xba, 0xe3, 0x58, 0xb1, 0xdb, 0x60, 0xac, 0x34, 0x5b, 0x9e, 0x65, 0x57, 0xa7, + 0xaf, 0x56, 0x57, 0x89, 0xa9, 0x07, 0xf2, 0x65, 0xeb, 0xde, 0xad, 0x68, 0x3a, 0xd9, 0xbc, 0x15, + 0x55, 0xe9, 0x29, 0x8e, 0x27, 0xa3, 0x9f, 0x64, 0x4b, 0x76, 0x15, 0xc5, 0xd3, 0x4b, 0x4a, 0x9a, + 0xc2, 0xa3, 0x5f, 0xa4, 0xaa, 0x7b, 0x4a, 0x71, 0x67, 0x86, 0xec, 0x56, 0xc3, 0x9a, 0xc5, 0x27, + 0xda, 0x78, 0x81, 0xc3, 0x94, 0x06, 0x93, 0x32, 0x47, 0xb1, 0x32, 0x81, 0x2c, 0x6c, 0xb1, 0x0d, + 0xf5, 0x2e, 0xb1, 0x3b, 0x1a, 0xe8, 0xa1, 0xea, 0xd5, 0x80, 0xcb, 0x33, 0x89, 0x22, 0xd9, 0x86, + 0xd0, 0x33, 0xea, 0x24, 0xd4, 0xa9, 0x24, 0xdf, 0x56, 0x7f, 0x5d, 0x91, 0x29, 0x3d, 0x90, 0x50, + 0x80, 0x2f, 0x4c, 0xba, 0x65, 0xe8, 0xc2, 0x44, 0xcd, 0x14, 0x8d, 0xce, 0x94, 0x58, 0x5d, 0x2f, + 0xa9, 0x44, 0x2f, 0xb1, 0xf7, 0x79, 0xb3, 0x66, 0x00, 0x70, 0x27, 0x38, 0x8e, 0x78, 0xed, 0xab, + 0xf6, 0x78, 0x81, 0x67, 0x8a, 0xb0, 0xc7, 0x14, 0xb7, 0xd6, 0x05, 0x45, 0xf8, 0x04, 0xcf, 0x5f, + 0xe9, 0xa8, 0x5e, 0x2c, 0x74, 0x06, 0x5e, 0xdc, 0x34, 0xe7, 0xa7, 0x05, 0xcf, 0x06, 0xcf, 0x84, + 0x6e, 0x53, 0xc0, 0x4b, 0xa9, 0xd0, 0x5f, 0x19, 0x90, 0x80, 0xd7, 0x86, 0x05, 0xfc, 0x49, 0xd1, + 0x15, 0x47, 0xf1, 0x3c, 0x0b, 0x81, 0x8f, 0x6e, 0xc9, 0x8e, 0x67, 0x49, 0x74, 0xd6, 0x99, 0xab, + 0xb0, 0x95, 0xa7, 0x72, 0xfe, 0xc9, 0x51, 0x6e, 0xfb, 0x53, 0xeb, 0x06, 0xd7, 0xf8, 0xa5, 0x1e, + 0x97, 0x53, 0x75, 0x49, 0x50, 0x66, 0xf7, 0x65, 0x5c, 0x67, 0xf7, 0x75, 0x4c, 0x87, 0x05, 0xa7, + 0x3d, 0x09, 0x00, 0x8f, 0x0c, 0x59, 0x49, 0xb2, 0xc7, 0x92, 0xd0, 0xc7, 0xd4, 0x4a, 0x6e, 0x37, + 0x20, 0x48, 0x47, 0xe1, 0x60, 0xa1, 0x9f, 0x64, 0x59, 0x66, 0xb4, 0x68, 0x3b, 0xd1, 0x6c, 0x89, + 0xe8, 0x47, 0xb0, 0x15, 0x12, 0xd4, 0x99, 0xe2, 0x64, 0xd2, 0x8e, 0x62, 0xdb, 0x4f, 0x1b, 0xf4, + 0x46, 0x1e, 0x8a, 0xe1, 0x5e, 0xe7, 0x98, 0x71, 0x40, 0xec, 0xc7, 0xa9, 0x75, 0xcf, 0x6c, 0xe0, + 0x1e, 0xd9, 0x8c, 0xab, 0xfb, 0x6b, 0x77, 0x38, 0xbb, 0x47, 0xbd, 0xc5, 0x1d, 0x82, 0x1d, 0xbf, + 0xbc, 0xbf, 0x76, 0x86, 0x83, 0x06, 0x4e, 0xee, 0x11, 0x4e, 0xce, 0x07, 0x1c, 0xcf, 0x8c, 0xc0, + 0x4a, 0x52, 0xd0, 0xe6, 0x81, 0xfb, 0xf8, 0x86, 0xcb, 0xa2, 0xdb, 0x73, 0xbf, 0x3d, 0x8d, 0xc2, + 0x88, 0xc8, 0x19, 0xba, 0x38, 0xf9, 0x35, 0x0a, 0xa3, 0xf6, 0x39, 0xbe, 0x99, 0x07, 0x56, 0x8c, + 0x8e, 0xa2, 0x30, 0x89, 0x02, 0x2b, 0x41, 0x79, 0x8f, 0x9a, 0x25, 0x5b, 0x90, 0x68, 0x45, 0x39, + 0x1b, 0x92, 0x1a, 0x06, 0x0e, 0x99, 0x24, 0x30, 0x23, 0x49, 0x11, 0x5e, 0x08, 0x6d, 0xa5, 0x6e, + 0x41, 0x6b, 0x5a, 0x61, 0x94, 0x90, 0x88, 0xcb, 0xa0, 0x0c, 0x53, 0x70, 0xfd, 0x06, 0xa7, 0x53, + 0xaf, 0x74, 0xa2, 0x61, 0x9c, 0xad, 0x3b, 0xe2, 0xa0, 0xba, 0x21, 0xea, 0x72, 0x63, 0x30, 0xa7, + 0x0c, 0x37, 0x8d, 0xa3, 0xf0, 0x86, 0x57, 0x11, 0x5d, 0x18, 0x99, 0xe3, 0x84, 0x4c, 0x5b, 0x91, + 0x49, 0x33, 0x69, 0x66, 0x51, 0x08, 0x30, 0xe7, 0x46, 0x56, 0x32, 0x83, 0x64, 0x4c, 0x0c, 0xbb, + 0xa2, 0xa1, 0x3c, 0xd1, 0xb9, 0xd9, 0x16, 0xf8, 0x50, 0xd5, 0x27, 0x44, 0x72, 0x7a, 0x32, 0x17, + 0xb0, 0xe9, 0x73, 0x91, 0x1c, 0x8d, 0x7b, 0x20, 0x7b, 0xfc, 0x4c, 0xf2, 0x48, 0x0e, 0xd7, 0xf4, + 0x84, 0x2d, 0xe6, 0x5f, 0x89, 0xdd, 0x28, 0xe0, 0x5d, 0xd6, 0x46, 0x5e, 0x51, 0xcd, 0x42, 0xa3, + 0x12, 0x35, 0x24, 0xe8, 0x43, 0x6d, 0x50, 0xb1, 0x86, 0xd8, 0x14, 0x55, 0xfe, 0x0d, 0xea, 0xad, + 0xb2, 0x45, 0xe0, 0xe3, 0xbf, 0xf0, 0x39, 0x93, 0x53, 0xe5, 0x29, 0xee, 0x53, 0x1e, 0xff, 0x29, + 0x11, 0x17, 0x8c, 0xe6, 0x8a, 0x4b, 0xcd, 0x0d, 0xee, 0x6f, 0x0c, 0x45, 0xf7, 0x1a, 0xe3, 0x40, + 0xdb, 0xc6, 0xa7, 0x81, 0xf9, 0x26, 0xe7, 0x8d, 0x7b, 0x5e, 0x1e, 0xdd, 0x08, 0xd3, 0x09, 0x95, + 0x7f, 0x51, 0x91, 0x56, 0x20, 0x51, 0x8a, 0x4e, 0xc2, 0x96, 0x5e, 0x6a, 0xf4, 0x07, 0x65, 0xd2, + 0x96, 0x7a, 0xab, 0xd2, 0x2a, 0x2e, 0xc2, 0xfb, 0xcc, 0x3f, 0xe8, 0x36, 0x86, 0xc5, 0xb6, 0x79, + 0x95, 0x15, 0xdf, 0x6b, 0xc3, 0x60, 0x5d, 0x69, 0x45, 0x30, 0xa2, 0xd6, 0x2d, 0x1d, 0x4b, 0xd7, + 0x9a, 0xc6, 0xa2, 0xd9, 0xbd, 0x6d, 0x63, 0xb1, 0x1e, 0xeb, 0x8e, 0x6b, 0x25, 0x13, 0x3b, 0x02, + 0xab, 0x03, 0xa4, 0x8b, 0x77, 0xe8, 0x95, 0x41, 0x35, 0xae, 0xb0, 0x61, 0x93, 0xf6, 0x62, 0x41, + 0xf1, 0x58, 0xc8, 0x89, 0x10, 0x2b, 0xc4, 0xe9, 0x5d, 0x14, 0xdf, 0xb6, 0x6d, 0x2b, 0x0c, 0x71, + 0x5c, 0x49, 0xa6, 0x95, 0x35, 0x97, 0xc2, 0x9b, 0x09, 0x24, 0xb5, 0x58, 0x0a, 0xb2, 0x6f, 0x19, + 0x16, 0xb8, 0xba, 0x9c, 0x14, 0xa0, 0x1e, 0x63, 0x66, 0xeb, 0x34, 0x5a, 0x0c, 0xe5, 0x28, 0x22, + 0x49, 0x8f, 0x76, 0xbb, 0x5b, 0xed, 0x37, 0x95, 0x6d, 0xff, 0x9a, 0xea, 0x6a, 0x5d, 0xc7, 0x21, + 0xa6, 0xa7, 0xa7, 0xe8, 0x9e, 0x2e, 0x55, 0xe7, 0x09, 0x66, 0x51, 0xc9, 0x8a, 0xd2, 0xea, 0xb4, + 0x10, 0x66, 0x46, 0x18, 0xa5, 0x62, 0xe6, 0xde, 0x49, 0x4f, 0xf4, 0xef, 0x88, 0x10, 0x96, 0x1d, + 0x3c, 0x4d, 0x2f, 0x60, 0xfb, 0x4e, 0x94, 0x89, 0xae, 0xc6, 0x45, 0x44, 0xb4, 0xc1, 0x8f, 0x07, + 0x86, 0x7a, 0x95, 0x90, 0x21, 0x13, 0x26, 0x5e, 0x79, 0x10, 0xaa, 0x29, 0x5e, 0x3d, 0x6c, 0xc6, + 0x45, 0xc3, 0x69, 0x1f, 0x6d, 0xdd, 0xf1, 0xb0, 0x95, 0xce, 0x63, 0xdc, 0x26, 0x8e, 0x03, 0x6f, + 0x1f, 0x2a, 0x7c, 0x0c, 0x8b, 0x18, 0x1d, 0x8f, 0x27, 0x56, 0xca, 0xe0, 0x9e, 0x64, 0x78, 0x11, + 0x81, 0x91, 0x47, 0x64, 0x93, 0xe4, 0x44, 0x94, 0x7c, 0x2e, 0xc2, 0xd9, 0x65, 0x22, 0xc8, 0x42, + 0x17, 0xb2, 0x24, 0xc4, 0xf8, 0xa8, 0x89, 0x96, 0xe5, 0x00, 0xe1, 0xea, 0xa2, 0xd5, 0xcb, 0x45, + 0x8b, 0xf5, 0x58, 0x77, 0xe8, 0x07, 0x26, 0xd6, 0xab, 0xec, 0x81, 0x51, 0x95, 0x76, 0xd6, 0x8d, + 0x4a, 0x64, 0xad, 0x5b, 0x2e, 0xa8, 0x4e, 0x34, 0x0f, 0xd3, 0x55, 0x11, 0x10, 0xec, 0x0e, 0x2a, + 0x09, 0x90, 0x1f, 0xde, 0x25, 0x69, 0xb5, 0xc2, 0xd4, 0xbf, 0x17, 0xfd, 0x50, 0x48, 0xe2, 0x1b, + 0x1b, 0x95, 0x26, 0x50, 0x32, 0x18, 0x7b, 0xfa, 0xb3, 0x9a, 0x93, 0xad, 0x54, 0x78, 0x25, 0x27, + 0x4d, 0x41, 0xb3, 0x1f, 0x19, 0x62, 0xa8, 0x3c, 0x93, 0xaa, 0x51, 0x0b, 0x08, 0x37, 0xde, 0x84, + 0x56, 0x00, 0x25, 0x28, 0x5b, 0xe2, 0x10, 0xc4, 0x6e, 0xb2, 0x66, 0x7c, 0x6a, 0x82, 0xac, 0x70, + 0x03, 0x76, 0x25, 0x88, 0x79, 0xd8, 0xbe, 0xce, 0x04, 0x6a, 0x59, 0xaf, 0x96, 0x12, 0xb5, 0x95, + 0xb5, 0xef, 0xd7, 0xe2, 0x82, 0xa5, 0x21, 0xca, 0x9b, 0x4b, 0x16, 0x9d, 0xa2, 0xa1, 0xd4, 0xe6, + 0x6e, 0x6a, 0xde, 0x8d, 0x5a, 0x4e, 0x9b, 0xfa, 0x75, 0xf3, 0x7e, 0x74, 0xff, 0x9f, 0xc5, 0x18, + 0x4a, 0x8a, 0xf2, 0x80, 0x14, 0x8d, 0x48, 0x35, 0xe8, 0xf1, 0xcc, 0x18, 0x64, 0x2f, 0x34, 0x58, + 0x6c, 0xe5, 0xc7, 0x60, 0x1a, 0x6c, 0x57, 0x50, 0x6a, 0x83, 0x82, 0x6a, 0x4a, 0xff, 0x56, 0x93, + 0xc6, 0x24, 0x00, 0x95, 0x37, 0xe2, 0x20, 0xf0, 0x67, 0x89, 0x9f, 0xe4, 0x43, 0x77, 0xf0, 0x74, + 0x96, 0x2e, 0x1f, 0x1f, 0x7b, 0xdd, 0xa1, 0xa9, 0x0a, 0xa2, 0x2d, 0xb6, 0x39, 0x1a, 0xa5, 0xbc, + 0x4a, 0xc5, 0x8a, 0x2e, 0x47, 0xb0, 0x65, 0xe6, 0x09, 0x97, 0x98, 0x6e, 0xbb, 0x9b, 0xbd, 0xdd, + 0x47, 0xe5, 0x13, 0x2b, 0x9b, 0x4a, 0x58, 0x36, 0x45, 0xa1, 0x4a, 0xf3, 0xab, 0xaf, 0x07, 0xe5, + 0x6d, 0x54, 0xb2, 0xaf, 0x4a, 0x20, 0x41, 0xad, 0x73, 0xc9, 0x9b, 0x52, 0x66, 0xa6, 0x04, 0x9b, + 0x86, 0xb3, 0xe8, 0x08, 0x0d, 0x41, 0x22, 0xb1, 0x4b, 0x32, 0xd0, 0x20, 0x23, 0x60, 0xed, 0xc7, + 0xfe, 0x6c, 0xd5, 0xe0, 0xaf, 0xf0, 0x1b, 0x7e, 0x29, 0x05, 0x4d, 0x38, 0xb2, 0xa4, 0xec, 0xb7, + 0xd9, 0x15, 0x3a, 0x2c, 0x01, 0xb1, 0x2e, 0x86, 0xf2, 0x6c, 0x63, 0x68, 0x50, 0x25, 0xdb, 0x2c, + 0x87, 0xd1, 0xd8, 0xf5, 0x17, 0x86, 0xe7, 0xc7, 0xb9, 0x4b, 0xf7, 0x84, 0xb1, 0x48, 0x01, 0x80, + 0x52, 0x09, 0x33, 0x40, 0x8d, 0x18, 0xf0, 0x74, 0xa6, 0x5a, 0x84, 0x41, 0x65, 0x24, 0x21, 0x0f, + 0xd3, 0x36, 0x11, 0xa1, 0x14, 0x33, 0xd6, 0xab, 0xaf, 0xd6, 0x44, 0x4e, 0xed, 0xd6, 0x13, 0xe5, + 0x10, 0x0e, 0x06, 0xe7, 0xaa, 0xf4, 0xe2, 0xe3, 0xc2, 0x28, 0x17, 0x83, 0x4d, 0x31, 0xf8, 0x01, + 0x1b, 0x0d, 0xe8, 0x6a, 0x9c, 0x54, 0x55, 0xd4, 0x41, 0x57, 0xad, 0xc7, 0xce, 0x38, 0x60, 0x82, + 0x5f, 0xc9, 0xfc, 0x57, 0xca, 0x4b, 0x68, 0xbd, 0xd4, 0x8f, 0xc6, 0xc9, 0x68, 0x58, 0xa1, 0x48, + 0x18, 0xa0, 0xd2, 0x26, 0x89, 0xca, 0x8c, 0x5d, 0xdd, 0x7b, 0xf5, 0x8a, 0x6b, 0xc1, 0xb3, 0x3a, + 0xc1, 0x4e, 0xe8, 0x68, 0x59, 0x02, 0x32, 0x9f, 0x89, 0xb5, 0xda, 0x2a, 0xd9, 0xc4, 0x00, 0xc9, + 0xf6, 0x15, 0xa2, 0x42, 0xeb, 0x34, 0x27, 0x96, 0x7a, 0x62, 0xdd, 0xe0, 0xa4, 0x1d, 0x58, 0xcb, + 0x68, 0x9e, 0x66, 0x84, 0x76, 0xac, 0xc0, 0x11, 0x49, 0x5d, 0x8a, 0xd0, 0x16, 0x14, 0x8d, 0xc4, + 0x25, 0x38, 0xa1, 0xd0, 0x7b, 0xf2, 0xd3, 0x44, 0x80, 0x99, 0xb7, 0x2a, 0xec, 0xef, 0xa8, 0xab, + 0x3c, 0x93, 0x80, 0x47, 0xd7, 0x9d, 0x74, 0x12, 0x63, 0xcb, 0x4d, 0x68, 0xed, 0xe0, 0xaa, 0x94, + 0x22, 0x21, 0x7e, 0xcb, 0x86, 0xfa, 0x13, 0x3e, 0x5e, 0x5e, 0x5b, 0xe1, 0x12, 0x4c, 0xa1, 0x1c, + 0x7c, 0x2c, 0xe2, 0xf6, 0x43, 0x18, 0x82, 0xec, 0x5d, 0x5b, 0xfa, 0x3f, 0x85, 0x45, 0x15, 0x0e, + 0x46, 0x95, 0x6a, 0xcf, 0x84, 0x36, 0xf1, 0xc5, 0x0b, 0x2c, 0xdb, 0x4b, 0xaa, 0x9c, 0x13, 0x27, + 0x8e, 0x82, 0x00, 0xb2, 0x8f, 0x94, 0xe9, 0xd2, 0x89, 0x9f, 0xa3, 0x9e, 0x97, 0x31, 0xc8, 0xcf, + 0x0a, 0x25, 0xae, 0xb2, 0x9a, 0x97, 0xa7, 0x10, 0x1b, 0xe2, 0x48, 0x1b, 0x1d, 0x0a, 0x65, 0xab, + 0x43, 0xb1, 0x21, 0xed, 0xb0, 0x25, 0x95, 0x9e, 0x61, 0x9d, 0xa5, 0x0f, 0xea, 0x39, 0x6f, 0x2b, + 0xeb, 0x92, 0xc5, 0xf8, 0x1b, 0x8c, 0x70, 0x27, 0xeb, 0x23, 0x74, 0xac, 0x85, 0x95, 0x5a, 0x79, + 0x89, 0xc6, 0x90, 0xb3, 0x0d, 0x87, 0x05, 0xa9, 0x49, 0xbc, 0x8b, 0xb3, 0x21, 0xe5, 0xba, 0x5d, + 0xd0, 0xad, 0xf4, 0x66, 0x8a, 0x0a, 0x95, 0xdb, 0x48, 0xe4, 0xe8, 0x2f, 0x6c, 0xef, 0xf5, 0x01, + 0x56, 0xb5, 0x0d, 0xbd, 0x3a, 0x5e, 0x8e, 0x42, 0xea, 0x4f, 0xf1, 0x53, 0x34, 0x20, 0xeb, 0x6e, + 0x5b, 0xee, 0x0d, 0x5e, 0x3d, 0x29, 0x93, 0xae, 0xff, 0xb5, 0x4c, 0xba, 0xae, 0xc8, 0x4f, 0xcb, + 0xa4, 0x0f, 0x2b, 0x3b, 0xfc, 0x00, 0x76, 0x78, 0xb6, 0x82, 0x8f, 0x8d, 0xbf, 0x2d, 0x9d, 0x5d, + 0xab, 0xf8, 0xd8, 0xe8, 0xbe, 0x39, 0x55, 0xe3, 0xad, 0x86, 0x8e, 0x13, 0x85, 0x0b, 0x1c, 0x27, + 0x24, 0x31, 0xb5, 0x85, 0x65, 0x4a, 0xa2, 0x14, 0x47, 0x77, 0xc5, 0x5e, 0x4a, 0x10, 0x2c, 0xc3, + 0xa1, 0xea, 0x84, 0x4f, 0xd2, 0x76, 0x39, 0xfa, 0x93, 0xa2, 0x01, 0x55, 0x7d, 0x6a, 0x75, 0x8b, + 0x5a, 0x68, 0x3a, 0xb6, 0xc9, 0x36, 0xaa, 0xba, 0x06, 0x0c, 0x2a, 0xd2, 0xc2, 0xd7, 0xec, 0x68, + 0x84, 0x73, 0xea, 0x6f, 0x80, 0x4d, 0xc1, 0x47, 0x89, 0x1f, 0x15, 0xa1, 0x3a, 0x08, 0xc6, 0xe7, + 0xff, 0xb2, 0xd4, 0x8c, 0xaa, 0x01, 0xd5, 0x86, 0x21, 0x1e, 0x8f, 0xe8, 0x0e, 0x59, 0x34, 0x0b, + 0xb6, 0xad, 0x76, 0xe0, 0x27, 0xe9, 0x8a, 0x37, 0xce, 0x9e, 0x52, 0xdd, 0x48, 0x88, 0x2f, 0x73, + 0x05, 0xa0, 0x4c, 0x3b, 0xaf, 0x3b, 0x77, 0x38, 0x70, 0xa2, 0x29, 0x6e, 0xdb, 0x73, 0x1b, 0x6a, + 0x72, 0xa9, 0xf1, 0x4e, 0x82, 0xc2, 0x38, 0xf3, 0x49, 0x08, 0xd3, 0x6e, 0xaa, 0xfc, 0xa3, 0xea, + 0x31, 0xe3, 0xf3, 0x6d, 0xce, 0x85, 0xae, 0xaf, 0x3b, 0x74, 0x94, 0x55, 0x91, 0x1e, 0x80, 0x52, + 0x82, 0xfe, 0xe0, 0x19, 0xd2, 0x07, 0x64, 0xf3, 0xc8, 0xd9, 0x0a, 0xd8, 0x82, 0xf0, 0xd6, 0x26, + 0x47, 0x68, 0xc4, 0x85, 0xe0, 0xc9, 0x9c, 0x93, 0xd4, 0x8a, 0xd3, 0x1f, 0x4a, 0x38, 0xf7, 0xd9, + 0xc6, 0x48, 0xff, 0xd1, 0x2b, 0x66, 0x95, 0xa2, 0x2b, 0x96, 0xaa, 0x64, 0x28, 0x77, 0xc0, 0x52, + 0xa8, 0x0e, 0x09, 0xa6, 0x46, 0x53, 0x91, 0x1b, 0x84, 0xa7, 0x36, 0x0c, 0x55, 0x1b, 0x65, 0xa8, + 0x75, 0x55, 0xc7, 0xea, 0x65, 0xe3, 0x08, 0xb3, 0x22, 0xbc, 0x54, 0xe6, 0x9d, 0xba, 0xab, 0x96, + 0xaf, 0x25, 0x30, 0xa4, 0x61, 0x85, 0xcb, 0xbb, 0x09, 0x8e, 0x71, 0xc9, 0x83, 0x9b, 0xc5, 0x98, + 0x3c, 0xcd, 0xc1, 0x3f, 0x81, 0xdb, 0x58, 0x21, 0x61, 0x3e, 0x6d, 0xf6, 0x0e, 0xb7, 0xda, 0xc4, + 0x48, 0xc9, 0xbb, 0x78, 0x96, 0x1f, 0xe0, 0x26, 0x3e, 0x26, 0x45, 0x24, 0x1d, 0x27, 0x9a, 0xce, + 0xa2, 0x04, 0xc7, 0x39, 0xcf, 0xc2, 0x64, 0x68, 0xec, 0x05, 0x76, 0x6d, 0x58, 0x64, 0x84, 0xc3, + 0x85, 0x48, 0xce, 0x7a, 0x40, 0x95, 0x78, 0x9b, 0x44, 0xa6, 0x98, 0x7e, 0x90, 0xf2, 0x55, 0x23, + 0x91, 0xc7, 0xe6, 0x65, 0xe5, 0x8b, 0x06, 0xfa, 0xf2, 0x50, 0x76, 0xec, 0x6e, 0x31, 0xae, 0xc0, + 0x8a, 0xde, 0x39, 0x53, 0xa3, 0xc1, 0x97, 0x64, 0xda, 0xa8, 0x5f, 0xae, 0x78, 0x90, 0x8b, 0x12, + 0x06, 0xf9, 0xb1, 0x48, 0x4a, 0x56, 0xa8, 0xc7, 0x2f, 0xae, 0xa2, 0xf4, 0x14, 0xb7, 0xe6, 0xf6, + 0x32, 0xcc, 0x40, 0xf3, 0xae, 0x9e, 0x18, 0xab, 0x85, 0xec, 0x6b, 0x56, 0x54, 0xc1, 0x4d, 0x2d, + 0x2b, 0xac, 0xe7, 0x27, 0x57, 0x77, 0x96, 0xef, 0x0b, 0xc7, 0x8e, 0xdf, 0x3a, 0xa9, 0x8c, 0x01, + 0xe0, 0x18, 0x13, 0xec, 0x48, 0xd6, 0xfc, 0x47, 0x04, 0x08, 0xc0, 0x67, 0xa5, 0xf6, 0x72, 0x7d, + 0xe6, 0xce, 0x36, 0x7d, 0xa0, 0xca, 0x8d, 0x33, 0xa1, 0x85, 0xfc, 0xab, 0xa6, 0xa0, 0xef, 0x70, + 0xb8, 0xee, 0x24, 0x38, 0x74, 0xdb, 0xac, 0xfe, 0x92, 0x6d, 0x04, 0x1a, 0xb7, 0x11, 0x68, 0x3f, + 0x6e, 0x0b, 0x68, 0x85, 0x2d, 0x20, 0x77, 0x95, 0xae, 0x6c, 0x3d, 0x35, 0x39, 0xc2, 0xd7, 0x10, + 0x77, 0xbb, 0x25, 0xd4, 0x98, 0x81, 0x98, 0x95, 0x81, 0x13, 0x71, 0x09, 0x71, 0x92, 0x88, 0x0a, + 0x1c, 0xd9, 0x28, 0x77, 0x75, 0xfd, 0x04, 0x4e, 0x7a, 0xb9, 0x79, 0x05, 0x47, 0xa7, 0xab, 0x67, + 0xa7, 0x2e, 0xc2, 0x08, 0x24, 0x2e, 0x88, 0xee, 0xb0, 0x5b, 0x90, 0x6a, 0xbc, 0xb9, 0x92, 0x9b, + 0xc4, 0xb0, 0x69, 0x0c, 0xf4, 0x51, 0x09, 0x1f, 0xd5, 0xe5, 0x79, 0x06, 0xdb, 0x0b, 0xdd, 0xed, + 0xf9, 0x90, 0x38, 0x8b, 0x53, 0x65, 0x0f, 0x21, 0xd7, 0xcb, 0x79, 0xc0, 0x84, 0x21, 0x21, 0x98, + 0xfd, 0x6f, 0x59, 0x96, 0xa7, 0x57, 0x0a, 0x6d, 0x17, 0x3d, 0xda, 0x4e, 0xfc, 0x1c, 0xa9, 0x84, + 0x5e, 0x43, 0x05, 0x6b, 0xb9, 0x68, 0xbc, 0xa4, 0xc8, 0x35, 0x17, 0x02, 0xf6, 0x56, 0x6c, 0x2f, + 0x69, 0xa6, 0xe5, 0x09, 0xd2, 0x1a, 0xe3, 0x19, 0xb6, 0x52, 0x51, 0x45, 0x25, 0xaf, 0x44, 0xa2, + 0x3b, 0xb0, 0x4e, 0xb3, 0x0b, 0x04, 0x60, 0x35, 0xba, 0xae, 0xa8, 0xd5, 0xb4, 0xca, 0x93, 0x32, + 0x2a, 0x2a, 0x8b, 0xb7, 0x14, 0x6e, 0x4f, 0xb7, 0xe2, 0xf6, 0x90, 0x8d, 0xb1, 0x34, 0x6c, 0xd5, + 0x96, 0xe2, 0x8e, 0xbc, 0x68, 0xd5, 0x10, 0x6c, 0x9e, 0x96, 0x2a, 0x79, 0x3b, 0x70, 0xfe, 0x0c, + 0xea, 0xe3, 0x79, 0xa0, 0x45, 0x2a, 0x85, 0xb0, 0x20, 0x29, 0x71, 0xad, 0x54, 0xd2, 0xfe, 0x05, + 0xef, 0x83, 0x1f, 0x69, 0xf6, 0xaf, 0xa7, 0x60, 0xf4, 0x32, 0xa4, 0x9a, 0x5b, 0x92, 0x4d, 0xb7, + 0xba, 0x1d, 0x96, 0xa8, 0x07, 0xf1, 0x06, 0xcb, 0xc9, 0x43, 0x97, 0xa5, 0x12, 0xc9, 0x5a, 0x34, + 0x8d, 0x70, 0x7f, 0x29, 0x79, 0x4e, 0x2d, 0x95, 0x72, 0xd0, 0x72, 0xbb, 0x07, 0xc0, 0x3b, 0xa5, + 0x8f, 0x05, 0x1d, 0x69, 0xb0, 0xe4, 0xa9, 0xec, 0x5a, 0x70, 0x69, 0x47, 0xd3, 0xc1, 0x7d, 0xce, + 0xc2, 0x17, 0xe0, 0xcc, 0x43, 0xf1, 0x1a, 0x1c, 0xdc, 0x29, 0x4a, 0x91, 0x58, 0x54, 0x9b, 0xf0, + 0x2e, 0x01, 0x18, 0x47, 0x77, 0x10, 0x50, 0x0d, 0x05, 0xb5, 0x60, 0x5d, 0xc2, 0xe5, 0x81, 0xbf, + 0xc0, 0xed, 0x99, 0x1f, 0x14, 0xb1, 0x0e, 0x9d, 0x59, 0x73, 0x65, 0x61, 0xae, 0x46, 0x69, 0xea, + 0x65, 0xb6, 0x59, 0xea, 0xdb, 0xda, 0x52, 0xe3, 0x30, 0x68, 0x2a, 0xfa, 0x1b, 0x40, 0x18, 0x8e, + 0x61, 0x0c, 0x5e, 0x25, 0x98, 0x70, 0x59, 0x98, 0x9d, 0x94, 0xa9, 0x94, 0x7c, 0xc7, 0x9a, 0xdf, + 0x52, 0x0a, 0x25, 0xf2, 0xb1, 0x7f, 0x06, 0xab, 0xee, 0x04, 0xd3, 0xda, 0x16, 0x48, 0xe1, 0xa1, + 0x3e, 0xd4, 0xb6, 0x0c, 0xea, 0xb5, 0x2d, 0x0d, 0xd1, 0xc2, 0x7e, 0x1d, 0xcd, 0xa7, 0x44, 0x63, + 0xba, 0x4d, 0x18, 0x91, 0xad, 0xa1, 0x56, 0x91, 0xde, 0x40, 0xdf, 0xb2, 0x73, 0xf1, 0x53, 0xb6, + 0xae, 0x13, 0x2b, 0x6e, 0xb2, 0x94, 0x14, 0x8d, 0xa7, 0x14, 0x2d, 0x58, 0xec, 0x90, 0xce, 0xed, + 0x00, 0xdf, 0xe0, 0xea, 0xc9, 0x26, 0xc2, 0x2f, 0xfd, 0x66, 0x25, 0x5d, 0xf1, 0x6a, 0x78, 0x20, + 0x74, 0xd6, 0x4f, 0xf1, 0x23, 0x7b, 0xb5, 0x57, 0xb3, 0xa4, 0xd0, 0x8f, 0x94, 0x1e, 0x54, 0xea, + 0xc2, 0x79, 0x70, 0x1d, 0x42, 0xa6, 0x86, 0x6d, 0x02, 0xfc, 0xb0, 0x34, 0xf6, 0x9d, 0x27, 0x0b, + 0x58, 0x29, 0xd3, 0xae, 0x52, 0x47, 0x0e, 0x00, 0x94, 0x55, 0x7f, 0x6f, 0x93, 0xea, 0xdf, 0xe2, + 0xd3, 0x6d, 0x8a, 0x7e, 0x66, 0x23, 0x94, 0xb9, 0x81, 0x19, 0xb8, 0x9b, 0x7c, 0xb9, 0x8a, 0x71, + 0x50, 0xab, 0x17, 0x52, 0xb2, 0x83, 0x65, 0x45, 0x51, 0x51, 0x31, 0x4e, 0xb3, 0x1c, 0x90, 0x9a, + 0x6f, 0x52, 0x43, 0xad, 0x11, 0x39, 0xa8, 0x31, 0x3e, 0x29, 0xe9, 0xca, 0x60, 0xc0, 0xd2, 0x57, + 0xce, 0xa3, 0x3d, 0xce, 0x3d, 0x33, 0xcb, 0xb9, 0xc5, 0x29, 0x55, 0x47, 0x39, 0xf9, 0xba, 0x95, + 0x27, 0x42, 0xe7, 0xcf, 0xb9, 0x8f, 0xd3, 0xd5, 0x0f, 0x81, 0x13, 0x3a, 0x38, 0x8e, 0xa3, 0xb8, + 0xc1, 0x9f, 0x61, 0x9d, 0x68, 0x1d, 0x18, 0x8f, 0xf1, 0x13, 0x53, 0x24, 0xcc, 0x40, 0xd0, 0xe8, + 0x99, 0xc8, 0xcc, 0x31, 0x2f, 0xc3, 0x6d, 0xae, 0x05, 0xd3, 0x6a, 0xdd, 0xea, 0x09, 0x89, 0x3a, + 0xa8, 0x27, 0x7b, 0x7c, 0xd3, 0x28, 0xc6, 0x3f, 0xba, 0x6f, 0x64, 0xdb, 0x04, 0xb7, 0x73, 0xc0, + 0x56, 0xd2, 0x2d, 0xef, 0x1a, 0xec, 0x42, 0x85, 0xaa, 0xc5, 0xa3, 0x0d, 0xe4, 0xca, 0x91, 0xcd, + 0xa7, 0xb0, 0x7d, 0x83, 0x4a, 0xa8, 0x05, 0x22, 0xf2, 0x21, 0xb9, 0x2a, 0x0b, 0x45, 0x56, 0xf9, + 0xc3, 0x72, 0x6a, 0xee, 0xfb, 0x91, 0xf8, 0x11, 0xd8, 0xb9, 0x3f, 0x7e, 0x26, 0x87, 0xe4, 0xf0, + 0x1f, 0x2d, 0x69, 0xcd, 0x4f, 0x30, 0xf5, 0xb6, 0x9e, 0x60, 0x22, 0x67, 0xdc, 0x2a, 0x55, 0x6b, + 0xdc, 0x34, 0x84, 0xfa, 0x79, 0x4a, 0x9d, 0x0b, 0x82, 0xe9, 0x32, 0x47, 0xe9, 0x6a, 0xff, 0xca, + 0xa9, 0x41, 0xae, 0x0a, 0x81, 0x16, 0xff, 0x6c, 0x78, 0xad, 0x48, 0xb5, 0xeb, 0xd5, 0x73, 0x86, + 0xdc, 0x92, 0x72, 0xc5, 0x9f, 0x7c, 0xcc, 0xa2, 0xab, 0x34, 0xe6, 0xc6, 0x88, 0xd0, 0x73, 0x6f, + 0x8f, 0x37, 0x54, 0xd7, 0xf4, 0x59, 0x2a, 0xf7, 0x09, 0x29, 0x09, 0x1e, 0x17, 0x37, 0x28, 0xf9, + 0xc2, 0x45, 0x00, 0x0b, 0x80, 0x55, 0xbb, 0x12, 0x31, 0x2b, 0xe5, 0x1d, 0x7e, 0x28, 0x75, 0x9c, + 0x57, 0x2d, 0x3d, 0x1a, 0xa1, 0xa8, 0x8a, 0x5a, 0x09, 0x8d, 0x26, 0xcd, 0x54, 0xe9, 0xc2, 0x95, + 0xb8, 0xf2, 0x95, 0xb5, 0xcf, 0x46, 0x7f, 0x31, 0x30, 0xf9, 0x2f, 0xd5, 0xc5, 0x82, 0xff, 0x9a, + 0xc2, 0x01, 0xa6, 0x04, 0x34, 0x8c, 0x73, 0x5b, 0x57, 0x54, 0x54, 0xea, 0xa9, 0x75, 0x4c, 0x66, + 0x80, 0x3a, 0x96, 0x1d, 0xcd, 0xd3, 0xba, 0xcf, 0x43, 0xec, 0x0a, 0xde, 0x70, 0xfc, 0x8b, 0xa9, + 0x7b, 0x92, 0x5c, 0x56, 0x2b, 0xa3, 0x57, 0x0b, 0xb8, 0x78, 0x6c, 0x1a, 0x8a, 0xbb, 0x32, 0xfa, + 0x52, 0xf5, 0xc4, 0x97, 0x35, 0x0b, 0x3f, 0xee, 0x6f, 0xf4, 0xa0, 0x2c, 0xc2, 0x9f, 0x5a, 0xf1, + 0x92, 0x39, 0xa0, 0xa4, 0x8a, 0x3f, 0x0a, 0xdd, 0xa2, 0xe5, 0xd1, 0xd2, 0x87, 0xac, 0xc0, 0x93, + 0xa8, 0xac, 0x8a, 0x63, 0xc1, 0x05, 0xab, 0x88, 0xbf, 0xf5, 0x58, 0xa2, 0x61, 0x9b, 0xf7, 0x30, + 0x90, 0xab, 0xc8, 0xae, 0xb2, 0xc8, 0x48, 0x4f, 0xd1, 0x65, 0xfb, 0xc9, 0x65, 0xa3, 0x9c, 0x12, + 0x53, 0x09, 0xbb, 0x54, 0x26, 0xbc, 0xd5, 0xd7, 0xdf, 0x7e, 0xb8, 0x34, 0x8b, 0xca, 0xba, 0xe0, + 0xa6, 0xc5, 0x65, 0x34, 0xf9, 0x03, 0x6d, 0x25, 0x67, 0x9e, 0x5e, 0x90, 0xa2, 0xf5, 0xab, 0xd3, + 0xcb, 0x83, 0x2f, 0xf5, 0x45, 0x69, 0x88, 0xcb, 0x68, 0x79, 0x5c, 0xe6, 0xce, 0xf2, 0xd3, 0x9c, + 0xc3, 0x68, 0xff, 0x4a, 0xa1, 0x53, 0x79, 0x1d, 0xf2, 0xc0, 0x5d, 0x56, 0xfc, 0x07, 0xbb, 0x44, + 0x94, 0xdd, 0x38, 0x01, 0x21, 0x70, 0x1d, 0xf6, 0x20, 0x94, 0xa7, 0xa0, 0xef, 0x84, 0xb6, 0x00, + 0xfb, 0xa1, 0x24, 0xf1, 0xe1, 0x3b, 0x12, 0x2b, 0xef, 0xf1, 0x1d, 0x5d, 0x92, 0xac, 0x66, 0x3d, + 0x4b, 0x62, 0x54, 0xcd, 0xc2, 0xd6, 0x48, 0xfe, 0x93, 0x6a, 0x75, 0xbb, 0x5a, 0x35, 0xaa, 0xa9, + 0x6a, 0x15, 0xbb, 0xab, 0xb6, 0x02, 0x1b, 0xcf, 0xf9, 0x74, 0x95, 0x81, 0x0a, 0xa7, 0x7c, 0x86, + 0xb2, 0xa3, 0xc8, 0x15, 0x9e, 0x20, 0xdb, 0x1a, 0xa9, 0x23, 0x15, 0xe0, 0xe4, 0x81, 0x2c, 0xcb, + 0xf6, 0xa0, 0x4a, 0x0d, 0xc3, 0xc8, 0xee, 0x4f, 0x28, 0x65, 0x4d, 0xb3, 0xee, 0xcd, 0xb7, 0x2b, + 0x90, 0xe3, 0x4f, 0x1d, 0x0a, 0xe0, 0x91, 0x43, 0x37, 0xd4, 0xeb, 0x7e, 0xea, 0x99, 0x1b, 0x0e, + 0x64, 0xc3, 0x49, 0x1b, 0xce, 0xe0, 0xea, 0x6f, 0xae, 0x00, 0x61, 0x30, 0x9c, 0x20, 0x4a, 0xf0, + 0xa6, 0xb0, 0xd8, 0x56, 0x81, 0xd5, 0x9e, 0x10, 0x62, 0x1e, 0x2a, 0x9e, 0xda, 0xe7, 0x11, 0xd2, + 0xab, 0x3a, 0xa8, 0x20, 0x34, 0x73, 0x78, 0x72, 0x27, 0x98, 0x9e, 0xf5, 0xe5, 0x53, 0x79, 0x4f, + 0xcb, 0xe2, 0x29, 0x3f, 0x78, 0xb2, 0x4f, 0xab, 0x9f, 0xec, 0x53, 0x94, 0x7e, 0x0d, 0x2f, 0xb2, + 0x1d, 0x3f, 0x9e, 0xa5, 0xab, 0xbe, 0xf5, 0x44, 0x03, 0xb7, 0xee, 0xd3, 0xc0, 0x1a, 0xd5, 0x80, + 0xfd, 0x1b, 0x13, 0x7e, 0x6a, 0x5d, 0xe4, 0x05, 0x28, 0xcd, 0xaa, 0x6f, 0x98, 0xc3, 0x86, 0x9e, + 0x81, 0x65, 0xe3, 0x80, 0x77, 0x30, 0xb4, 0xb2, 0xfa, 0x56, 0x9b, 0x82, 0x3f, 0x15, 0x18, 0xf4, + 0xba, 0x9e, 0x0d, 0xc9, 0x81, 0x86, 0xd3, 0x9d, 0x7f, 0xf1, 0xb8, 0xa6, 0xa2, 0xf4, 0x2b, 0x05, + 0x6c, 0xe0, 0x8b, 0x24, 0xc9, 0x5d, 0x14, 0xbb, 0x3f, 0x92, 0xed, 0x28, 0x2b, 0x4d, 0x1e, 0x42, + 0x76, 0xf7, 0x42, 0xc1, 0x25, 0xbd, 0xea, 0xae, 0x58, 0x0f, 0x31, 0x3d, 0x3d, 0xc3, 0x6e, 0x6d, + 0x25, 0x30, 0xb8, 0xbc, 0x9e, 0x8f, 0x03, 0x38, 0xec, 0x17, 0xcc, 0xca, 0x47, 0x88, 0x7b, 0x8f, + 0xf9, 0xab, 0xcd, 0xb1, 0x48, 0xa6, 0x22, 0xb2, 0x43, 0xbb, 0xdc, 0x6a, 0xf7, 0x1f, 0xb3, 0x85, + 0x4a, 0xc5, 0x4e, 0xa5, 0xdd, 0x25, 0xc6, 0xc9, 0x3c, 0xc8, 0x73, 0xc4, 0x04, 0x9a, 0x5e, 0x7f, + 0xce, 0xc5, 0x6b, 0xa9, 0xad, 0xad, 0x94, 0x0f, 0x6a, 0xa9, 0x6a, 0xc3, 0x3b, 0x51, 0x1e, 0xce, + 0xa3, 0xe1, 0xa5, 0x5a, 0xc5, 0x6e, 0xad, 0x30, 0xb2, 0x9e, 0xb9, 0xec, 0xe9, 0x35, 0xb0, 0x55, + 0x23, 0xec, 0x47, 0xeb, 0x56, 0xf5, 0x1a, 0xc8, 0x71, 0x29, 0x1b, 0xc1, 0x39, 0x03, 0x84, 0x1c, + 0x03, 0x7a, 0x18, 0x1c, 0x6a, 0x03, 0xa8, 0x09, 0xbb, 0xe1, 0xba, 0xa1, 0x81, 0x3c, 0xa2, 0x05, + 0x59, 0x24, 0x53, 0x39, 0xd8, 0x90, 0xa9, 0x24, 0x5d, 0x48, 0xa2, 0x92, 0x84, 0x58, 0xb6, 0xf6, + 0xcd, 0xb3, 0x9a, 0xc5, 0xde, 0xdf, 0xad, 0xef, 0xfd, 0xdd, 0x1e, 0xd9, 0xd1, 0x9b, 0xf4, 0x44, + 0xd3, 0x51, 0x57, 0x36, 0x97, 0x4a, 0x86, 0x55, 0x7f, 0x5a, 0x3c, 0x62, 0x40, 0x13, 0x08, 0x4f, + 0x28, 0x99, 0x7a, 0x9a, 0x5e, 0xa8, 0x65, 0xb8, 0xe9, 0x01, 0x60, 0xbd, 0x6c, 0x11, 0x90, 0xdc, + 0xbe, 0xa6, 0x17, 0x06, 0x41, 0xbf, 0xdb, 0xbc, 0xc3, 0x03, 0x3c, 0x89, 0x3b, 0x6e, 0x4d, 0x57, + 0x8d, 0x9c, 0xb6, 0xd6, 0x69, 0x7d, 0xa0, 0x60, 0x47, 0xe9, 0xa4, 0x5e, 0xa7, 0x06, 0xfd, 0x72, + 0x07, 0xb6, 0x72, 0xe7, 0xc4, 0xbf, 0x7c, 0x22, 0xaa, 0xe1, 0x22, 0x1c, 0x32, 0x50, 0xe7, 0xce, + 0x8a, 0x43, 0xc1, 0x5f, 0x3d, 0xf9, 0x04, 0x91, 0x5c, 0x3f, 0x41, 0x44, 0x01, 0x91, 0xb0, 0x53, + 0x13, 0x24, 0x66, 0xd7, 0x6e, 0x02, 0x43, 0x83, 0x53, 0x14, 0x06, 0xa9, 0x55, 0xa8, 0x50, 0x0c, + 0xc2, 0xc3, 0xd9, 0x95, 0x2e, 0xb0, 0x0b, 0xdd, 0x59, 0xb1, 0x9b, 0xf0, 0xa7, 0xce, 0x33, 0xc2, + 0x3e, 0xf1, 0xd0, 0xb9, 0xc0, 0x5d, 0xa0, 0x52, 0x07, 0x03, 0x18, 0x70, 0xa7, 0xd2, 0x37, 0xc0, + 0x81, 0xa5, 0x5d, 0xaf, 0x3b, 0x36, 0xdc, 0x4a, 0xb2, 0x41, 0x02, 0x15, 0x39, 0xbf, 0xf1, 0xab, + 0x29, 0x36, 0x93, 0x29, 0xc3, 0xca, 0x89, 0xea, 0xba, 0xc9, 0x52, 0x33, 0x41, 0xe8, 0xe5, 0x8e, + 0x5c, 0xd1, 0x29, 0xc3, 0x55, 0xe8, 0x74, 0x19, 0x5f, 0x21, 0x72, 0x9b, 0x9c, 0x1f, 0x94, 0x1a, + 0x29, 0xb6, 0x1d, 0x6a, 0x03, 0x70, 0xf3, 0x2b, 0xfa, 0xe6, 0xd5, 0x99, 0xd0, 0x31, 0xb3, 0x27, + 0x38, 0xdd, 0x33, 0x2c, 0x6b, 0x59, 0x7d, 0xb3, 0xfd, 0x48, 0x01, 0x3c, 0xb9, 0x60, 0x23, 0x8a, + 0x52, 0x22, 0x91, 0xf9, 0x81, 0x40, 0xbe, 0x66, 0xae, 0x5c, 0x35, 0x3f, 0x68, 0xb8, 0x0a, 0x6e, + 0xeb, 0x51, 0x8a, 0x9f, 0xc0, 0xb8, 0x87, 0xd2, 0xc5, 0x7c, 0x94, 0x0d, 0x25, 0xc5, 0x9a, 0xfe, + 0x6c, 0xb4, 0xf5, 0x12, 0xc6, 0x0d, 0x72, 0x55, 0x3d, 0x69, 0xc8, 0x49, 0x3c, 0x19, 0x32, 0x71, + 0xac, 0x50, 0x50, 0x3a, 0x32, 0x5b, 0x86, 0xb6, 0x1f, 0x12, 0x8e, 0xf6, 0x43, 0x0f, 0x2e, 0x68, + 0xc5, 0x3c, 0x07, 0xe6, 0xfd, 0x81, 0x93, 0x9b, 0xea, 0xe1, 0xdb, 0x70, 0x9b, 0x22, 0xb9, 0x35, + 0xa1, 0xe9, 0xa9, 0xaa, 0xc1, 0xa1, 0xfe, 0xf5, 0x7f, 0x9b, 0x62, 0xd7, 0xb7, 0xc4, 0x22, 0x1c, + 0x30, 0x24, 0x15, 0x4a, 0x2b, 0x76, 0x05, 0xde, 0x06, 0xe3, 0x65, 0x50, 0xbb, 0xf5, 0xae, 0xb8, + 0xd2, 0x2e, 0x0b, 0xbe, 0x69, 0xf9, 0xd9, 0xfb, 0x2d, 0x19, 0x83, 0x01, 0x57, 0x0f, 0x4e, 0x62, + 0xb2, 0x1b, 0xfb, 0x6e, 0x48, 0xca, 0xd1, 0xea, 0x2e, 0x3e, 0x40, 0x5e, 0xaf, 0x77, 0x6f, 0x98, + 0x25, 0xf1, 0x2f, 0xa5, 0x15, 0xb9, 0x26, 0x33, 0xdb, 0xe9, 0xd9, 0xbe, 0x46, 0x76, 0xa8, 0x3e, + 0xd4, 0xed, 0xec, 0x09, 0xdb, 0xb6, 0xb6, 0xea, 0x2d, 0x81, 0x2c, 0x5d, 0x94, 0x91, 0x81, 0x4a, + 0x73, 0xe5, 0xf6, 0x3e, 0x62, 0xf1, 0xf1, 0x25, 0xc5, 0x3d, 0xfd, 0xd1, 0x71, 0x38, 0xe3, 0x15, + 0xf6, 0xb0, 0x2d, 0x5d, 0x6b, 0x35, 0x3c, 0xe5, 0x48, 0x5d, 0xc3, 0x45, 0x0f, 0x83, 0xa6, 0xaa, + 0x22, 0x6c, 0xb3, 0x4b, 0xc4, 0x50, 0xf9, 0x42, 0x25, 0xfe, 0x62, 0x10, 0x7a, 0x77, 0x58, 0x96, + 0x81, 0xfa, 0xb1, 0x94, 0x80, 0xce, 0xa5, 0x04, 0x2a, 0x77, 0x8d, 0xf1, 0x85, 0xe8, 0xbc, 0xdd, + 0xde, 0x67, 0x05, 0x1f, 0xfa, 0xec, 0xa9, 0x59, 0x22, 0x4e, 0x29, 0xd6, 0x0f, 0x50, 0x91, 0xfd, + 0xbf, 0x21, 0x9a, 0x5e, 0xbf, 0xc8, 0xab, 0x21, 0x7a, 0x5d, 0x13, 0xe1, 0x6d, 0x51, 0x83, 0x41, + 0xf3, 0xc5, 0x07, 0x4a, 0xe9, 0x78, 0xd9, 0xf6, 0xab, 0xb9, 0xe4, 0x32, 0x8d, 0x04, 0xee, 0x0e, + 0xcf, 0xda, 0xdd, 0x6f, 0xa5, 0x1b, 0xbb, 0xea, 0x27, 0x0e, 0x33, 0xf7, 0x8a, 0xd8, 0xb4, 0x84, + 0xff, 0x74, 0xf9, 0x99, 0xb0, 0x07, 0xa7, 0xc4, 0x24, 0x3e, 0x04, 0xd7, 0xe7, 0xc2, 0xe0, 0xe5, + 0x52, 0xb1, 0xb2, 0x73, 0x06, 0xf6, 0x25, 0xb9, 0x3d, 0xa9, 0xa1, 0xbe, 0x7d, 0xab, 0x79, 0x98, + 0x46, 0x33, 0x49, 0xa2, 0xc6, 0x91, 0xba, 0xe1, 0x8e, 0x24, 0xbd, 0x5e, 0xb5, 0xa6, 0x68, 0xe5, + 0xcb, 0x8d, 0xaa, 0xe5, 0x39, 0x9b, 0xaf, 0xf8, 0xa9, 0xc4, 0x10, 0xf9, 0x0b, 0x81, 0xaa, 0xa4, + 0x66, 0xa7, 0x05, 0xae, 0xe0, 0x0e, 0xe7, 0x36, 0xbd, 0xa2, 0xc6, 0x9c, 0x44, 0x53, 0x7c, 0x5d, + 0xbd, 0xcf, 0x66, 0xdb, 0x59, 0xd0, 0xda, 0x95, 0x23, 0xe5, 0x00, 0x30, 0x60, 0xb3, 0x45, 0x29, + 0xca, 0xc5, 0x6d, 0x08, 0xd9, 0xad, 0x13, 0xb5, 0x8b, 0x25, 0xe0, 0xbe, 0x12, 0x45, 0x5d, 0xdc, + 0x21, 0xbd, 0x47, 0x62, 0x43, 0xdc, 0x0d, 0x06, 0xf9, 0x62, 0x54, 0xce, 0xdd, 0x97, 0x4e, 0xe5, + 0x53, 0x5a, 0x6e, 0x38, 0x95, 0xdf, 0xed, 0x6e, 0x39, 0x57, 0xce, 0x4e, 0xa1, 0x0f, 0x33, 0x3e, + 0xd2, 0x86, 0x4f, 0x39, 0x84, 0xce, 0x1f, 0x0c, 0xaf, 0xde, 0x08, 0xd0, 0x78, 0x92, 0x7c, 0x50, + 0x3e, 0xb4, 0x5e, 0xba, 0x96, 0x82, 0x84, 0xbf, 0xf5, 0xfa, 0xe6, 0xfe, 0xc8, 0x55, 0x0f, 0x4a, + 0xc3, 0x01, 0xf0, 0x0d, 0xe5, 0x46, 0x1a, 0xf5, 0x16, 0x6a, 0x67, 0xa4, 0xab, 0x81, 0xe3, 0x86, + 0xc3, 0x55, 0x85, 0x2c, 0xd4, 0x4e, 0xb0, 0x53, 0xf5, 0x9c, 0x1f, 0xc0, 0xca, 0x4d, 0x82, 0xcd, + 0xcc, 0xc0, 0xe5, 0xd3, 0x37, 0x1d, 0x57, 0x56, 0x74, 0x3e, 0xab, 0x4e, 0x13, 0x5d, 0x7c, 0x5f, + 0xa1, 0x7a, 0xf6, 0x52, 0xc9, 0x5d, 0xf9, 0xcd, 0xa7, 0xe5, 0x68, 0x68, 0x62, 0x3b, 0x56, 0xdd, + 0xd2, 0x51, 0x2e, 0x6b, 0xd5, 0xe8, 0xb9, 0xb3, 0xaa, 0xac, 0x47, 0x0e, 0x23, 0xd1, 0x00, 0xaf, + 0xa2, 0x77, 0xab, 0xa7, 0x91, 0x88, 0x8a, 0xdb, 0x62, 0x13, 0x94, 0x8f, 0x1b, 0x95, 0x77, 0xa8, + 0xad, 0xd5, 0xfd, 0x3d, 0xfe, 0xf2, 0x60, 0xe2, 0x5f, 0xe4, 0x12, 0x51, 0x2f, 0x3f, 0x27, 0xa7, + 0xb8, 0xe8, 0x2a, 0xd4, 0x2a, 0xbb, 0x07, 0x83, 0x67, 0x0d, 0xc5, 0xbf, 0xc3, 0xec, 0x42, 0x5b, + 0xa2, 0x06, 0xe5, 0x47, 0xbc, 0xe4, 0x72, 0xf5, 0xdd, 0x96, 0xe9, 0x6e, 0xaa, 0xa9, 0xa3, 0xb8, + 0xf1, 0x66, 0x54, 0xce, 0x36, 0xbc, 0xd5, 0xc4, 0x97, 0x5e, 0x6c, 0x28, 0x19, 0xca, 0x73, 0xfc, + 0x8d, 0x05, 0x1c, 0xa5, 0x13, 0x93, 0x59, 0xe0, 0xab, 0x5e, 0x9b, 0xa0, 0x0c, 0xab, 0xe9, 0xf9, + 0xd5, 0x53, 0xef, 0x67, 0x28, 0xb2, 0xf3, 0x5b, 0xc8, 0xb0, 0x29, 0xd1, 0x4e, 0xf7, 0xca, 0x4d, + 0x09, 0x39, 0xde, 0xe1, 0xe7, 0x4a, 0xe9, 0x37, 0xa8, 0xf0, 0x4a, 0xda, 0x83, 0xdb, 0xe1, 0x36, + 0xbc, 0xf0, 0x68, 0xfe, 0x8b, 0x57, 0x0c, 0x7c, 0x50, 0xa6, 0x64, 0x77, 0x0e, 0x9e, 0x60, 0x77, + 0x56, 0xd2, 0x2b, 0xe5, 0x55, 0xad, 0x84, 0xda, 0x1a, 0x91, 0x6d, 0xc7, 0x18, 0x24, 0x03, 0x57, + 0x7b, 0x0b, 0x75, 0x4c, 0xeb, 0xa6, 0x73, 0x77, 0x48, 0x1d, 0x84, 0xed, 0xa6, 0x7d, 0x69, 0x47, + 0x2a, 0xcb, 0x25, 0xa7, 0xc8, 0x9f, 0x90, 0xa6, 0xe0, 0x6a, 0x89, 0x1e, 0xe1, 0x0b, 0x81, 0x0d, + 0xdb, 0x5c, 0xac, 0x43, 0xea, 0x65, 0xb2, 0xd9, 0xcc, 0x62, 0xec, 0xe1, 0x38, 0x81, 0x68, 0xc2, + 0xdc, 0xc1, 0x6e, 0x7b, 0x1a, 0xb1, 0xc4, 0x24, 0x7c, 0x95, 0x56, 0xcf, 0xd1, 0xf3, 0xec, 0xf6, + 0x9c, 0xe7, 0x6c, 0x63, 0xa4, 0xc7, 0xfb, 0xda, 0x36, 0x9e, 0x58, 0x0b, 0x3f, 0x8a, 0x89, 0x82, + 0x2c, 0x6e, 0xe6, 0x2f, 0xdc, 0xb8, 0xb6, 0x3b, 0x8f, 0xa9, 0x3f, 0xd7, 0x91, 0x95, 0x69, 0xd2, + 0xd8, 0xc5, 0x4f, 0x31, 0xed, 0xd3, 0x26, 0x17, 0x27, 0x18, 0x0a, 0xd7, 0xab, 0xf0, 0xd4, 0x37, + 0x42, 0x5a, 0xaf, 0xf7, 0x5f, 0xd0, 0x5f, 0x76, 0xf8, 0xdb, 0xfe, 0x0b, 0xfa, 0x53, 0x20, 0xfb, + 0xe0, 0xc8, 0xd0, 0x9f, 0x7c, 0x58, 0xdc, 0xc0, 0x5d, 0x94, 0x49, 0x62, 0xb6, 0xb2, 0x6b, 0xd7, + 0x5b, 0x82, 0x15, 0xfb, 0x56, 0x9b, 0x6e, 0x91, 0x66, 0x2b, 0x8d, 0xe7, 0x98, 0xfc, 0x80, 0x04, + 0xf4, 0x5e, 0x4e, 0xed, 0x28, 0x10, 0x7c, 0xd7, 0x6c, 0xf9, 0x6d, 0xb0, 0x72, 0x5a, 0x02, 0xec, + 0x14, 0x87, 0xd1, 0xbd, 0xd9, 0x22, 0x29, 0x4e, 0x4d, 0x50, 0xb5, 0xd6, 0x78, 0x7f, 0x66, 0xa5, + 0x13, 0xc1, 0x35, 0x5b, 0xbf, 0x76, 0x05, 0x45, 0xe9, 0xe8, 0x82, 0xa2, 0x0a, 0x5a, 0x30, 0x14, + 0xfa, 0x1d, 0x7d, 0x31, 0xb0, 0x14, 0x41, 0xa1, 0xf7, 0x6b, 0xb4, 0x15, 0x41, 0x99, 0xb4, 0xf5, + 0x45, 0xbb, 0xf7, 0x66, 0xb8, 0xe8, 0xbd, 0xd1, 0xf8, 0x27, 0x6d, 0xe5, 0x7b, 0xeb, 0xc5, 0x78, + 0xff, 0x05, 0x1d, 0xb1, 0x69, 0xf8, 0x69, 0x72, 0xf3, 0xd8, 0xe8, 0x9a, 0xa0, 0x77, 0xf4, 0x89, + 0xd2, 0x5b, 0x28, 0xca, 0x9b, 0x61, 0xd0, 0xd6, 0x85, 0xee, 0x63, 0x40, 0x41, 0x61, 0x6e, 0x80, + 0xca, 0xee, 0x61, 0x73, 0xee, 0xcd, 0x96, 0xa2, 0xb6, 0x04, 0x67, 0x49, 0xff, 0xc6, 0x66, 0x4b, + 0x05, 0xa0, 0xf9, 0xa0, 0xfd, 0xce, 0x40, 0xe8, 0x77, 0x06, 0x56, 0x4f, 0xe8, 0x91, 0xc9, 0xc0, + 0x7f, 0x83, 0x8e, 0x36, 0x1d, 0x74, 0xb4, 0xf6, 0xa0, 0xa3, 0xe5, 0xed, 0x0a, 0x6d, 0xff, 0x55, + 0xeb, 0xf4, 0x04, 0xad, 0xd3, 0xb3, 0x14, 0x19, 0x08, 0x05, 0xff, 0x64, 0x6f, 0x29, 0x5a, 0x67, + 0x30, 0x85, 0x7f, 0xda, 0xf0, 0x4f, 0xa5, 0x83, 0xc2, 0x3a, 0x3c, 0x32, 0x21, 0xa2, 0xe3, 0x1f, + 0xa3, 0x93, 0x2e, 0xa8, 0xf2, 0x6f, 0x8a, 0x3c, 0x05, 0xf0, 0xbf, 0xf5, 0xe0, 0x8f, 0xf6, 0xdb, + 0x10, 0xfe, 0x28, 0xbf, 0x75, 0x1f, 0x5b, 0x85, 0x28, 0xc6, 0x8f, 0x13, 0x4c, 0x2f, 0xd1, 0x4b, + 0xe9, 0x10, 0xa8, 0x9b, 0x09, 0xda, 0xd0, 0x61, 0xd8, 0xd4, 0x61, 0x0b, 0x5e, 0x70, 0x96, 0xe0, + 0x91, 0x69, 0x4f, 0xbb, 0x82, 0x26, 0x28, 0x03, 0x61, 0xd0, 0x86, 0x7f, 0x84, 0x6e, 0x7b, 0xf0, + 0xfd, 0xd7, 0x9e, 0xa0, 0xa8, 0x13, 0x45, 0x7f, 0x8c, 0xa8, 0xd8, 0x8b, 0x71, 0x32, 0x79, 0x8c, + 0xac, 0xaa, 0x2c, 0xf4, 0x17, 0xfa, 0xa4, 0xad, 0xff, 0xaa, 0x09, 0x4a, 0x7f, 0xd1, 0xd6, 0x27, + 0xfa, 0x74, 0xd8, 0xd1, 0xdb, 0xda, 0x01, 0x8c, 0x47, 0xd7, 0x58, 0x17, 0x86, 0xd3, 0x8e, 0x2e, + 0x0c, 0xb8, 0x26, 0x65, 0x28, 0xd4, 0x30, 0xd8, 0x7f, 0x91, 0x2c, 0x6e, 0xc6, 0x7f, 0x83, 0x4f, + 0xae, 0xbf, 0xc8, 0x25, 0x16, 0x02, 0x0a, 0x99, 0x6c, 0x5a, 0xe0, 0x7c, 0xe7, 0x4f, 0xa8, 0x23, + 0xce, 0x9e, 0x95, 0xdf, 0x22, 0xbe, 0x7a, 0x6b, 0xbc, 0x4f, 0xea, 0x93, 0xf9, 0x36, 0x52, 0xdc, + 0xd4, 0x1a, 0xef, 0xfb, 0xe3, 0xfd, 0x17, 0xf0, 0x3f, 0xe8, 0x40, 0xbb, 0xe5, 0xbf, 0x1a, 0xb3, + 0x4f, 0xe2, 0x6e, 0x63, 0xf8, 0xe1, 0x18, 0xe1, 0x13, 0xb6, 0xf7, 0x5f, 0xd0, 0xef, 0x59, 0xdf, + 0x17, 0xae, 0xbf, 0xc8, 0x87, 0x04, 0xe7, 0x92, 0x81, 0x0f, 0xad, 0x05, 0xd3, 0x2a, 0x24, 0x7d, + 0x67, 0xb6, 0xde, 0xd3, 0xcd, 0x2f, 0xc7, 0x4f, 0x10, 0xf6, 0x99, 0x1f, 0xca, 0xde, 0xa0, 0xce, + 0x53, 0x8b, 0xfc, 0x34, 0x4e, 0x1b, 0xc8, 0x6c, 0xb6, 0x88, 0xbe, 0x19, 0x83, 0xc6, 0x1a, 0xef, + 0xcf, 0x13, 0x2c, 0x4c, 0x62, 0xec, 0x99, 0xad, 0x9f, 0x98, 0x22, 0x22, 0xf4, 0x82, 0x47, 0x04, + 0x93, 0x37, 0xd1, 0x14, 0xe7, 0x48, 0x51, 0xc8, 0xf5, 0xa1, 0x38, 0xd8, 0x99, 0xbd, 0xd9, 0x08, + 0x1f, 0x34, 0x4d, 0x19, 0xfc, 0xaf, 0xac, 0x7b, 0x36, 0x84, 0x4d, 0x18, 0x23, 0xb4, 0x16, 0xed, + 0x79, 0x08, 0xf6, 0x51, 0x4b, 0xa0, 0xda, 0x73, 0x2c, 0xef, 0xbf, 0xb0, 0x9f, 0x86, 0x01, 0x35, + 0xd5, 0x1a, 0xc7, 0x27, 0x4a, 0xa9, 0x8c, 0xc0, 0x29, 0xe9, 0xfd, 0x23, 0x33, 0xa4, 0x8a, 0xa0, + 0x09, 0x3c, 0x7d, 0x52, 0x86, 0x7f, 0x0e, 0x6d, 0x3f, 0x44, 0x40, 0xd0, 0x03, 0x8d, 0xc4, 0x83, + 0x07, 0x15, 0xea, 0x01, 0x23, 0x35, 0xc3, 0xde, 0x7f, 0x11, 0x5a, 0x8b, 0x26, 0xa6, 0xe5, 0x23, + 0x4b, 0x15, 0xde, 0x2d, 0x6e, 0x72, 0x6e, 0x91, 0x65, 0x80, 0xae, 0xe4, 0x5b, 0x89, 0x85, 0x8b, + 0x47, 0xb4, 0x7f, 0x6b, 0x7c, 0x94, 0x5f, 0x39, 0x5d, 0x67, 0xdf, 0xfd, 0x17, 0x44, 0x9c, 0x88, + 0xc4, 0xc1, 0x4f, 0x41, 0x59, 0x7e, 0x81, 0x22, 0x6c, 0xa1, 0x38, 0xce, 0x46, 0xa7, 0xe1, 0x05, + 0x9e, 0x91, 0x01, 0xc8, 0xfe, 0x2c, 0x7b, 0xce, 0x92, 0x77, 0x0c, 0x35, 0x7a, 0x85, 0xed, 0xad, + 0xef, 0xdc, 0xc2, 0x0f, 0x64, 0x1d, 0x9d, 0xfd, 0xfa, 0xfe, 0xe0, 0xf4, 0xed, 0xd9, 0xe9, 0xfe, + 0x8b, 0xd9, 0x78, 0x7f, 0xa2, 0xf0, 0x7d, 0xc8, 0xaf, 0x32, 0xb5, 0x18, 0x23, 0x4f, 0x94, 0xb2, + 0x6c, 0x95, 0x69, 0xc3, 0xdd, 0x6f, 0xcc, 0xe1, 0x01, 0x4a, 0x8b, 0x97, 0x70, 0x1a, 0xbe, 0xa0, + 0x78, 0xb0, 0x2f, 0x24, 0xe6, 0xd1, 0x1a, 0xff, 0xf3, 0x3f, 0xff, 0x1f, 0xe1, 0x37, 0x46, 0x03, + 0xfe, 0xf5, 0xb2, 0x44, 0xe6, 0x41, 0x12, 0x0a, 0x22, 0xfb, 0x59, 0x2b, 0xda, 0x69, 0xf3, 0x92, + 0xd4, 0x17, 0x81, 0x00, 0x22, 0x7a, 0xa0, 0x71, 0x0d, 0x6a, 0xcc, 0x56, 0x52, 0x2a, 0x2f, 0x28, + 0xf5, 0xd9, 0xc2, 0xc0, 0x1c, 0xa9, 0xa5, 0x9a, 0x8f, 0x4c, 0xa8, 0x27, 0x94, 0xd4, 0x07, 0x8b, + 0xca, 0x30, 0x05, 0x52, 0x00, 0xb6, 0xe2, 0xd4, 0x27, 0x1b, 0x0c, 0x7d, 0x15, 0xec, 0x4c, 0x01, + 0x2c, 0xff, 0x32, 0x11, 0x39, 0x42, 0xe7, 0x21, 0x96, 0x52, 0x0f, 0x41, 0xa8, 0xaf, 0xf6, 0xf8, + 0xcb, 0xd9, 0xc7, 0x73, 0xe1, 0xd7, 0xe3, 0x8b, 0x37, 0xc2, 0xe9, 0xd9, 0xab, 0x63, 0x58, 0xdf, + 0xf2, 0x1b, 0x13, 0x95, 0xaa, 0x8c, 0xc8, 0xc5, 0x6d, 0xf8, 0xd5, 0xb2, 0xd6, 0x98, 0xfe, 0x18, + 0xd7, 0x44, 0xad, 0x81, 0xce, 0xfb, 0xf9, 0x6e, 0x6b, 0xfc, 0xc9, 0xf2, 0xc9, 0x4d, 0xea, 0x5e, + 0x14, 0x0b, 0xe0, 0x45, 0x5a, 0x21, 0x4c, 0x1e, 0x48, 0xfa, 0xcf, 0xff, 0xfc, 0x9f, 0x95, 0x61, + 0x2a, 0x2c, 0x53, 0x9e, 0x4b, 0x61, 0x6e, 0x37, 0xda, 0x7b, 0xd9, 0x26, 0x50, 0xfe, 0xc3, 0x96, + 0xa8, 0xae, 0xec, 0x1b, 0x29, 0x45, 0x6c, 0xf6, 0x2a, 0xa9, 0x88, 0x74, 0xd0, 0x5d, 0xe3, 0xdd, + 0xdb, 0xd3, 0x5f, 0xf2, 0x1d, 0x84, 0x1a, 0xe0, 0x64, 0xb2, 0xe4, 0x65, 0x98, 0x52, 0x6b, 0x7c, + 0x01, 0x2e, 0x17, 0xe5, 0x0e, 0xf2, 0xbc, 0x3e, 0x6a, 0x19, 0xe4, 0xd1, 0xd9, 0xe9, 0xe5, 0xc1, + 0xd1, 0xe5, 0xc5, 0x46, 0xb0, 0xec, 0x8c, 0x52, 0x42, 0xb8, 0xfe, 0xa9, 0x50, 0x2f, 0x8e, 0x2f, + 0x2e, 0x88, 0x94, 0x6e, 0x00, 0x3a, 0x9f, 0xc1, 0x81, 0xa9, 0x47, 0x40, 0x56, 0x05, 0xf8, 0x05, + 0x63, 0xbf, 0x9c, 0x95, 0xeb, 0x1c, 0x49, 0xc2, 0x31, 0xe5, 0x88, 0xd2, 0x46, 0xde, 0xe4, 0x2f, + 0xd0, 0x6b, 0x5e, 0xd1, 0xc7, 0x36, 0x96, 0xa6, 0xf5, 0x6c, 0x50, 0x64, 0xe3, 0x77, 0x67, 0x47, + 0x07, 0xef, 0x84, 0xa3, 0xb3, 0xd3, 0xd3, 0xe3, 0xa3, 0xcb, 0x5c, 0x79, 0x75, 0x29, 0x9f, 0x32, + 0x2c, 0x98, 0xf6, 0xba, 0xc0, 0xa9, 0x30, 0x9f, 0x09, 0x41, 0xe4, 0x58, 0x81, 0xf0, 0xc9, 0x6f, + 0x9f, 0xf8, 0xfb, 0x2f, 0x26, 0xdd, 0x71, 0xc6, 0xd4, 0xac, 0x73, 0x32, 0x9f, 0x52, 0x63, 0xe0, + 0x63, 0x82, 0x85, 0x65, 0x34, 0x8f, 0x05, 0xb5, 0xa3, 0x09, 0xaf, 0xdf, 0x7c, 0x17, 0x40, 0x62, + 0x33, 0x02, 0x08, 0x7e, 0x98, 0xa4, 0x50, 0x77, 0x16, 0x79, 0x42, 0x92, 0x5a, 0x4b, 0x90, 0x82, + 0x28, 0x14, 0xd2, 0x09, 0x26, 0xbf, 0x63, 0x27, 0x24, 0x38, 0x9d, 0xcf, 0x84, 0x49, 0x94, 0x26, + 0xb3, 0x28, 0xed, 0x10, 0xa4, 0x6a, 0x33, 0x2a, 0x6b, 0xb4, 0xb2, 0x07, 0xde, 0x2a, 0xe3, 0x04, + 0xd0, 0x72, 0xe5, 0xd6, 0x34, 0x8f, 0xba, 0x9e, 0x6a, 0x58, 0x50, 0x6e, 0x81, 0xca, 0xb1, 0xbd, + 0xf2, 0x3a, 0x36, 0xad, 0x7b, 0x29, 0x26, 0x57, 0xba, 0x7f, 0xaf, 0x41, 0xa4, 0xf8, 0x37, 0x49, + 0xec, 0xaa, 0x35, 0xde, 0xb4, 0x7c, 0x6f, 0x4f, 0x0f, 0xcf, 0x3e, 0xb3, 0x35, 0x1b, 0x7f, 0x24, + 0xe6, 0x8a, 0x30, 0xcd, 0xed, 0x19, 0x58, 0x9d, 0x17, 0x94, 0xf5, 0x39, 0x7d, 0x4e, 0xfc, 0x4e, + 0x4a, 0x20, 0x58, 0x92, 0xcc, 0xca, 0x01, 0xf3, 0xa6, 0x59, 0x17, 0x94, 0xb1, 0xca, 0x2e, 0x5f, + 0x23, 0x97, 0x28, 0x50, 0x30, 0x59, 0xdc, 0x8c, 0x3d, 0x6a, 0x8d, 0x4f, 0x23, 0x61, 0x5e, 0x45, + 0xa6, 0x0e, 0xb4, 0xbc, 0x80, 0xdc, 0x65, 0x5f, 0x4c, 0xd5, 0x47, 0x33, 0x60, 0xf8, 0xc2, 0x9a, + 0x3b, 0x9b, 0xe1, 0x30, 0x07, 0x48, 0x37, 0xc4, 0xf1, 0x3f, 0xff, 0xaf, 0xff, 0x7b, 0xe3, 0x66, + 0xd3, 0xbc, 0x8c, 0x3f, 0xb0, 0x42, 0xf4, 0xa0, 0xe4, 0x5f, 0x5b, 0x21, 0xb2, 0x6d, 0x1c, 0x1c, + 0x5d, 0xbe, 0xfd, 0xed, 0xed, 0xe5, 0x97, 0x6c, 0xa5, 0xce, 0x31, 0xc0, 0x0f, 0x96, 0x42, 0xc8, + 0x4c, 0xbf, 0xe6, 0x95, 0xe2, 0xee, 0xd7, 0xdb, 0xa4, 0xc4, 0xff, 0xd5, 0x25, 0x63, 0xc1, 0xc4, + 0x7c, 0xc5, 0xf8, 0xad, 0xc8, 0x72, 0x17, 0x38, 0x4e, 0xff, 0xc2, 0x92, 0x65, 0xe6, 0xef, 0x05, + 0xc6, 0x6c, 0x86, 0xff, 0xee, 0xd5, 0xe2, 0x42, 0xd7, 0x8d, 0x7b, 0x52, 0x83, 0xa2, 0x7b, 0xfb, + 0xdb, 0xb1, 0x70, 0x7e, 0xf0, 0xea, 0xed, 0x19, 0x59, 0x04, 0x5e, 0xeb, 0x83, 0x10, 0xc4, 0x49, + 0xe2, 0x53, 0xe3, 0xc9, 0x3d, 0x9c, 0x16, 0x7a, 0x3f, 0xb7, 0x73, 0x48, 0xa7, 0x24, 0x8c, 0x5b, + 0xe3, 0x8b, 0xd3, 0x73, 0x81, 0xee, 0x0d, 0x4f, 0xa0, 0x3c, 0x77, 0x3f, 0x19, 0xac, 0x20, 0x01, + 0xc5, 0xb5, 0x41, 0x15, 0x50, 0xd0, 0x62, 0x2b, 0xf9, 0x34, 0x40, 0x56, 0xab, 0x8a, 0x95, 0x17, + 0xe3, 0x3f, 0xe7, 0x38, 0x74, 0x96, 0x14, 0xff, 0x5f, 0xdf, 0x7c, 0xaf, 0x59, 0x69, 0xa4, 0x1f, + 0x0d, 0xc9, 0xd2, 0xcd, 0x52, 0x60, 0x5f, 0x36, 0x6e, 0xff, 0xc5, 0x52, 0x6c, 0x30, 0xdd, 0x98, + 0xa9, 0xf6, 0x88, 0xed, 0x56, 0x31, 0xda, 0x0a, 0x59, 0xfe, 0xdb, 0x06, 0x33, 0x86, 0x4f, 0x14, + 0x34, 0xd8, 0x6f, 0x25, 0xbf, 0xb8, 0x14, 0xff, 0xdf, 0x22, 0xa5, 0xfc, 0x1d, 0x60, 0x9b, 0x05, + 0xf5, 0xe8, 0xec, 0xf4, 0xb7, 0xe3, 0xf3, 0x8b, 0x03, 0xd8, 0x05, 0x2f, 0xa8, 0xa0, 0xaa, 0x9c, + 0x6f, 0x38, 0x51, 0x4b, 0x12, 0x0a, 0x54, 0xcd, 0x6f, 0x82, 0x02, 0x7d, 0xfa, 0x54, 0xf5, 0xc9, + 0x90, 0x6e, 0xf1, 0x10, 0x20, 0xdf, 0xd0, 0xe2, 0x71, 0x2a, 0xee, 0xa7, 0x21, 0x56, 0x35, 0x31, + 0x72, 0x04, 0xf8, 0x85, 0x3b, 0x67, 0x02, 0x86, 0x43, 0x90, 0x08, 0xd6, 0x6c, 0x86, 0xad, 0x58, + 0x20, 0xf1, 0x49, 0x21, 0x59, 0x86, 0xce, 0x86, 0x4d, 0x32, 0x73, 0x7d, 0x36, 0xe8, 0x2f, 0x2e, + 0x4b, 0xb2, 0x4d, 0xcd, 0x55, 0x93, 0x29, 0x95, 0xbe, 0xe5, 0xde, 0xf4, 0xdc, 0x7d, 0xee, 0x58, + 0x14, 0x6f, 0xb2, 0x07, 0xe3, 0x9f, 0x1a, 0x48, 0x94, 0xdb, 0x68, 0x85, 0x5c, 0x96, 0xde, 0x65, + 0x36, 0xc8, 0xd1, 0x24, 0x8a, 0x12, 0x2c, 0x58, 0x02, 0xff, 0x90, 0x13, 0x57, 0x30, 0xe9, 0xea, + 0x2f, 0x27, 0x73, 0x3b, 0x7f, 0x9f, 0xd0, 0x4f, 0x88, 0x62, 0x81, 0xc6, 0xc5, 0x05, 0x66, 0x43, + 0x16, 0xc1, 0x8f, 0xfa, 0xea, 0x6d, 0x5f, 0x50, 0x3e, 0x69, 0x54, 0xde, 0x0e, 0xd9, 0xb2, 0x72, + 0x7d, 0xcb, 0x17, 0x11, 0x81, 0x82, 0x84, 0x6b, 0x5b, 0x04, 0x2b, 0x5b, 0x57, 0x81, 0x38, 0x02, + 0x04, 0x21, 0x21, 0x8d, 0x04, 0x92, 0xa3, 0x10, 0x52, 0x2b, 0xb8, 0x05, 0xd5, 0x6c, 0x39, 0x71, + 0x94, 0x24, 0xc4, 0x46, 0x02, 0x7b, 0xbf, 0xc3, 0xd8, 0xb1, 0x01, 0x3b, 0x72, 0x83, 0x66, 0xbe, + 0x76, 0x34, 0x3b, 0x95, 0xad, 0x07, 0xfb, 0x56, 0xa3, 0x3e, 0xf1, 0xe1, 0x72, 0x89, 0xa1, 0xbf, + 0xc3, 0xd9, 0x82, 0xed, 0xc0, 0x6c, 0xa5, 0xf0, 0x4b, 0x72, 0x69, 0x9b, 0xde, 0x31, 0xd3, 0x82, + 0xcd, 0xcb, 0x9f, 0x41, 0x85, 0xc3, 0xfe, 0x0b, 0xf2, 0x52, 0x0d, 0x14, 0xed, 0x48, 0x19, 0xbc, + 0xf4, 0x6a, 0x29, 0x6a, 0x94, 0x83, 0x69, 0x8d, 0xf7, 0xa3, 0x19, 0x51, 0x1d, 0x0b, 0x2b, 0x98, + 0x63, 0xb3, 0x95, 0x2f, 0x73, 0x5c, 0x8c, 0x44, 0x7b, 0xc0, 0x7e, 0x47, 0x40, 0x6d, 0xe3, 0x3f, + 0xee, 0xea, 0x99, 0xda, 0x34, 0xb7, 0x4f, 0x34, 0x5b, 0x38, 0x52, 0x52, 0xde, 0xca, 0x84, 0x7f, + 0xc3, 0x34, 0xe1, 0x47, 0x98, 0xd9, 0x85, 0x2e, 0xa5, 0x55, 0xa7, 0x2f, 0x0b, 0x70, 0xe5, 0x98, + 0xd9, 0x52, 0x5a, 0x90, 0x04, 0x0c, 0x70, 0x78, 0x93, 0x4e, 0xcc, 0x96, 0xa2, 0xc9, 0x2d, 0x81, + 0x14, 0xf5, 0x4d, 0xa2, 0xc0, 0xc5, 0xb1, 0xd9, 0x62, 0x43, 0xe4, 0x8b, 0xfa, 0xcf, 0xff, 0xfc, + 0x9f, 0xb0, 0x1d, 0x64, 0x80, 0x1b, 0xc6, 0x64, 0x3b, 0x30, 0xfc, 0x44, 0xb8, 0xd9, 0x4a, 0xe6, + 0xf6, 0x14, 0x7c, 0xbe, 0x5c, 0xd1, 0xe5, 0x77, 0xae, 0x94, 0x69, 0x7d, 0x01, 0xe7, 0xbd, 0x19, + 0x82, 0x8d, 0xce, 0x03, 0x89, 0xb0, 0x16, 0xce, 0x43, 0x7d, 0x6f, 0xde, 0x20, 0x08, 0xb0, 0xda, + 0x9c, 0xcc, 0x51, 0xc2, 0x67, 0x0a, 0x51, 0x78, 0x21, 0x28, 0x9a, 0x2c, 0xd8, 0xcb, 0x94, 0x04, + 0xd7, 0x88, 0x7c, 0x55, 0x24, 0x0b, 0x38, 0x75, 0xab, 0x5f, 0xf5, 0xd7, 0xf7, 0x9c, 0xcc, 0x18, + 0xf9, 0xdb, 0x63, 0x5b, 0x83, 0x90, 0x5f, 0xff, 0xb2, 0x79, 0x93, 0x38, 0x3f, 0x3e, 0x3a, 0x3e, + 0xbd, 0x14, 0x0e, 0x5e, 0xfd, 0x76, 0x7c, 0x7e, 0x99, 0xef, 0x12, 0x34, 0x80, 0x47, 0x16, 0x90, + 0xdf, 0x28, 0xca, 0xc6, 0x12, 0x77, 0x41, 0x4b, 0xc9, 0x04, 0xcb, 0xe3, 0xcf, 0x65, 0xe1, 0x20, + 0x8d, 0x42, 0xe1, 0xe1, 0x36, 0xc5, 0xfa, 0xd8, 0x9b, 0xb5, 0x75, 0xdb, 0x12, 0x5e, 0xe2, 0x72, + 0xcd, 0x25, 0x2c, 0x98, 0xae, 0x6a, 0xb2, 0xb5, 0x4a, 0xbb, 0x11, 0x9b, 0x2a, 0x84, 0x30, 0x8a, + 0x4d, 0x28, 0xc9, 0x4c, 0x46, 0xc1, 0x8a, 0x63, 0x7f, 0x81, 0x3b, 0x85, 0xf9, 0xf0, 0xef, 0x58, + 0x41, 0x16, 0xed, 0xfc, 0xdb, 0x66, 0xbb, 0xe8, 0x69, 0x4e, 0x18, 0x97, 0x0d, 0xff, 0x6b, 0x36, + 0xfd, 0xc5, 0xdb, 0xd7, 0xa7, 0x07, 0xef, 0x84, 0x37, 0xc7, 0x07, 0xef, 0x2e, 0xdf, 0x64, 0x36, + 0xfd, 0x3b, 0x7f, 0x81, 0x85, 0xf3, 0x93, 0x4d, 0xb6, 0x7c, 0x7e, 0x57, 0x08, 0x35, 0x45, 0x9f, + 0x66, 0x2c, 0x94, 0xb3, 0xf4, 0xad, 0xd2, 0xf6, 0x48, 0x67, 0x9e, 0xdb, 0xad, 0x65, 0x9b, 0x75, + 0x4c, 0xad, 0x58, 0x6a, 0x05, 0xe6, 0x02, 0x4a, 0x5f, 0xf9, 0x73, 0x6e, 0x41, 0x0d, 0x6f, 0xd9, + 0xe6, 0x4f, 0xac, 0xe9, 0x2c, 0xc0, 0xdb, 0x76, 0x41, 0xc7, 0x0a, 0x17, 0x56, 0xc2, 0x22, 0xaf, + 0xc5, 0x4d, 0x1a, 0x2d, 0x81, 0x26, 0xe0, 0x21, 0x9d, 0xa3, 0xd5, 0x34, 0x3c, 0x1c, 0x37, 0x3a, + 0xbf, 0xb8, 0x78, 0xcb, 0x68, 0x2f, 0xd0, 0x57, 0xc6, 0xfb, 0x2f, 0x28, 0xb4, 0x2d, 0xab, 0xc0, + 0xdd, 0x54, 0xd1, 0xca, 0x62, 0x55, 0x7e, 0xf6, 0x94, 0x14, 0xdf, 0x51, 0xbb, 0x19, 0xa0, 0xd7, + 0xec, 0x5d, 0xe6, 0x1e, 0x34, 0x98, 0xeb, 0x95, 0x2e, 0x61, 0xe4, 0x27, 0xc0, 0xd5, 0xf0, 0x67, + 0x9b, 0x55, 0xdf, 0x60, 0x0f, 0x57, 0xad, 0x80, 0x3c, 0x49, 0x5d, 0xe5, 0xad, 0x26, 0x56, 0xa4, + 0xdd, 0x5b, 0x59, 0x4c, 0xea, 0xe4, 0xfc, 0xf8, 0xc3, 0xc7, 0xe3, 0xd3, 0xa3, 0x2f, 0x4d, 0x51, + 0x29, 0x8a, 0x69, 0xd9, 0xca, 0xaf, 0xac, 0x36, 0x67, 0xf3, 0x37, 0x21, 0xfa, 0x34, 0x24, 0x0e, + 0x0f, 0x4e, 0x5f, 0x7d, 0x7a, 0xfb, 0x0a, 0x38, 0x7a, 0x13, 0x12, 0xb6, 0x15, 0xba, 0xa4, 0x10, + 0xa0, 0x09, 0x89, 0xdb, 0x7f, 0x07, 0x12, 0x17, 0xef, 0xcf, 0x8f, 0x0f, 0x5e, 0xbd, 0x3d, 0x7d, + 0xbd, 0x19, 0x89, 0x64, 0x06, 0xf2, 0xe0, 0x87, 0x37, 0x0d, 0x48, 0x70, 0xdd, 0x9c, 0x88, 0xf6, + 0x39, 0x2a, 0xbb, 0x6b, 0xff, 0x32, 0x66, 0x97, 0x9f, 0x85, 0xf7, 0x67, 0x9f, 0x8e, 0xcf, 0x37, + 0x23, 0x36, 0x8b, 0xee, 0xc0, 0xb2, 0xda, 0x2a, 0x8c, 0x8d, 0x7c, 0x54, 0xe3, 0xb6, 0x26, 0x74, + 0xb8, 0x5a, 0x9b, 0xbf, 0xa6, 0xbd, 0xde, 0x1f, 0x1c, 0xfd, 0x72, 0x9c, 0x6d, 0x5e, 0xdd, 0xf1, + 0x59, 0xd8, 0xb6, 0x7c, 0x30, 0x3b, 0xe7, 0x50, 0x07, 0x5b, 0x8f, 0x1a, 0xc1, 0xfc, 0xd8, 0xd8, + 0xe4, 0xdc, 0x46, 0x92, 0x9b, 0x1b, 0xe4, 0xca, 0x11, 0xd8, 0xe7, 0x69, 0xfb, 0x13, 0x63, 0x11, + 0x5c, 0x61, 0x50, 0x86, 0x23, 0x47, 0x49, 0xf6, 0x38, 0xc6, 0x0e, 0xf6, 0x17, 0xd8, 0xad, 0x52, + 0x93, 0x26, 0x2c, 0xd9, 0xc3, 0xb2, 0xb6, 0xda, 0x04, 0x2a, 0x21, 0x26, 0x66, 0x03, 0x98, 0x0b, + 0x62, 0x58, 0x3e, 0x05, 0x04, 0x75, 0x15, 0x1a, 0x81, 0xbc, 0xa2, 0x5e, 0xc4, 0xf9, 0xe7, 0xa7, + 0x41, 0xf2, 0x82, 0x28, 0x6a, 0x9e, 0xd4, 0x09, 0x3c, 0xa9, 0xc3, 0xf9, 0xff, 0xcb, 0x31, 0x27, + 0x19, 0xbf, 0x66, 0xa7, 0x3c, 0x2b, 0xca, 0x7a, 0x7c, 0x83, 0xe5, 0x4a, 0xb3, 0x1e, 0x4f, 0xaa, + 0xbc, 0x3a, 0xfe, 0xed, 0xed, 0x11, 0x49, 0xa6, 0x94, 0x02, 0xab, 0xc5, 0x2d, 0x1d, 0x4f, 0xcf, + 0x6a, 0x37, 0x70, 0x1c, 0x4b, 0xc9, 0x10, 0xe4, 0x2b, 0x29, 0x19, 0x16, 0xb0, 0x26, 0x8f, 0xa6, + 0x91, 0x0b, 0xa1, 0x83, 0x2c, 0x23, 0x2e, 0x1c, 0x65, 0x59, 0x98, 0x7a, 0x92, 0xc7, 0x0d, 0xd8, + 0xaa, 0xba, 0xe9, 0xf8, 0xc4, 0x8f, 0xa7, 0x77, 0x16, 0x24, 0x3e, 0xdd, 0x74, 0xbc, 0xef, 0xba, + 0x05, 0x40, 0x8f, 0x3d, 0x61, 0x6b, 0xec, 0xba, 0x25, 0x86, 0x70, 0xd3, 0xf1, 0xe1, 0xdc, 0x0f, + 0xdc, 0xfa, 0x7b, 0x36, 0x34, 0x6f, 0x7c, 0xe9, 0xfd, 0xdc, 0x0e, 0x7c, 0x47, 0xb8, 0xc5, 0xcb, + 0xfa, 0x9b, 0xb7, 0x78, 0x59, 0x7b, 0xef, 0x85, 0x1b, 0xfc, 0xd0, 0xee, 0x55, 0xbe, 0xec, 0xe2, + 0x29, 0x1b, 0x18, 0x57, 0x67, 0xb7, 0x45, 0xd3, 0x9c, 0x1f, 0x5f, 0x1c, 0x9f, 0xb2, 0x45, 0x9e, + 0x74, 0xc7, 0x07, 0xc4, 0x4a, 0x84, 0xad, 0x36, 0x9d, 0xf8, 0x09, 0x31, 0x22, 0x59, 0x0a, 0x61, + 0xfc, 0x61, 0x8e, 0xe7, 0xe0, 0xd7, 0x13, 0x01, 0x61, 0xe6, 0xa4, 0x90, 0x44, 0x59, 0xf8, 0x30, + 0x5f, 0x20, 0x6a, 0x78, 0xc2, 0x41, 0x19, 0xd7, 0x4f, 0x1c, 0xf2, 0x9b, 0x10, 0xcb, 0x68, 0xce, + 0x05, 0x3f, 0x9e, 0x90, 0x16, 0xa0, 0xd0, 0xf3, 0x7c, 0x00, 0xc5, 0x4a, 0x08, 0xa3, 0x3b, 0xce, + 0x80, 0x7e, 0xfa, 0x36, 0xf1, 0x24, 0x4a, 0x34, 0x27, 0x58, 0x28, 0x77, 0x96, 0xb3, 0x2c, 0x5c, + 0xfa, 0xe3, 0xe0, 0x3d, 0x9f, 0x60, 0xb1, 0x66, 0x6d, 0xcb, 0x75, 0x63, 0x9c, 0x14, 0xd9, 0x6e, + 0xec, 0x0a, 0xe9, 0x24, 0x8e, 0xe6, 0x37, 0x13, 0x4a, 0x50, 0x2a, 0x3c, 0xf0, 0xeb, 0x92, 0xca, + 0x50, 0xed, 0x28, 0xbd, 0x41, 0x47, 0xeb, 0x28, 0x1c, 0x69, 0xf8, 0x20, 0x4d, 0xa9, 0xc2, 0xb1, + 0x55, 0x25, 0x5b, 0xb5, 0x7e, 0x91, 0x12, 0x8e, 0x39, 0x1c, 0x45, 0x26, 0x65, 0x19, 0x3a, 0x65, + 0xba, 0x6d, 0x87, 0x22, 0x94, 0x6e, 0xb4, 0xc8, 0x60, 0xa6, 0xf3, 0x38, 0x6c, 0x5b, 0x79, 0x7e, + 0x26, 0xab, 0xb6, 0x38, 0x27, 0x0f, 0x48, 0x18, 0x24, 0xa7, 0x46, 0xc9, 0xbf, 0xf9, 0xb7, 0x2f, + 0xd2, 0xfb, 0xf3, 0xb7, 0xbf, 0x1d, 0x1c, 0xe5, 0x41, 0xfa, 0x77, 0x24, 0x41, 0xc4, 0xbc, 0x66, + 0x61, 0xe2, 0x27, 0x69, 0x14, 0x2f, 0x33, 0x7e, 0xfd, 0x38, 0x03, 0xcc, 0x14, 0x55, 0x2e, 0x12, + 0x12, 0x56, 0x8c, 0x85, 0x5b, 0x3c, 0x83, 0x03, 0x5b, 0x74, 0x39, 0x00, 0x2a, 0xdc, 0xfb, 0x0a, + 0xf6, 0x75, 0xce, 0xf0, 0x1d, 0xe1, 0x28, 0x00, 0xa7, 0x29, 0x9d, 0xe0, 0xa9, 0x70, 0x37, 0xc1, + 0x21, 0x66, 0x3c, 0x2c, 0x04, 0xfe, 0x2d, 0xde, 0xcc, 0xc8, 0xcd, 0x2b, 0xe2, 0x00, 0xac, 0x36, + 0xc3, 0x2d, 0x5f, 0x17, 0x3a, 0x42, 0x8e, 0xf1, 0xbf, 0xc2, 0xd4, 0x79, 0xe5, 0xec, 0x66, 0x72, + 0x1d, 0x1c, 0x9e, 0x7d, 0xbc, 0xcc, 0x88, 0x95, 0x0b, 0x28, 0x29, 0x24, 0xa2, 0x34, 0x3a, 0x63, + 0x3f, 0xd5, 0x5d, 0xa4, 0xb6, 0x3f, 0xbe, 0x15, 0xfe, 0xeb, 0x7f, 0x09, 0x8b, 0xc2, 0xb0, 0xb0, + 0x66, 0xb3, 0x36, 0xc4, 0xe9, 0x48, 0xfc, 0x91, 0x33, 0xd3, 0xec, 0x78, 0xfc, 0x1e, 0xac, 0x29, + 0xec, 0x0a, 0x9c, 0xf4, 0x77, 0xfe, 0x60, 0x69, 0x1f, 0x56, 0x7a, 0x60, 0xc7, 0x40, 0x8f, 0x86, + 0xf7, 0x61, 0x94, 0x5f, 0xdf, 0x5e, 0x0a, 0xff, 0xf5, 0xff, 0x09, 0xef, 0x7c, 0x6b, 0x2a, 0x1c, + 0x45, 0x69, 0x0a, 0xde, 0xcd, 0x6c, 0x1b, 0xeb, 0x3c, 0x31, 0xf6, 0x40, 0xbf, 0x66, 0x45, 0x24, + 0xac, 0x17, 0xad, 0xe5, 0x22, 0xf7, 0x11, 0x54, 0x52, 0xb8, 0xb4, 0xb5, 0x9c, 0x8f, 0xcc, 0xda, + 0x0a, 0x67, 0x29, 0xc0, 0xae, 0xbd, 0xac, 0x76, 0xc8, 0x54, 0xc2, 0xdf, 0x6a, 0xd9, 0xc7, 0xe2, + 0xe2, 0x8e, 0x2d, 0xa1, 0x0a, 0x50, 0x24, 0xa7, 0xc7, 0x97, 0x9f, 0xce, 0xce, 0x7f, 0x61, 0x81, + 0x8a, 0x06, 0x24, 0xb6, 0x26, 0x77, 0xab, 0x91, 0x0c, 0x1a, 0x74, 0xca, 0xf8, 0xaf, 0x8c, 0x0c, + 0xb9, 0x01, 0xa4, 0x69, 0x9a, 0xd9, 0x13, 0xde, 0x33, 0x3c, 0x82, 0xa6, 0x3c, 0x17, 0x4c, 0xe4, + 0xbb, 0x35, 0xfe, 0xdf, 0xff, 0x6f, 0x53, 0x00, 0xa3, 0x29, 0x2d, 0xce, 0x2e, 0xb2, 0xd8, 0x58, + 0xa7, 0x22, 0xe4, 0xbf, 0x6e, 0x5f, 0x54, 0xac, 0xf0, 0x75, 0x05, 0x1f, 0xcf, 0xcf, 0x21, 0x8a, + 0xc3, 0x2b, 0xe5, 0xba, 0x4d, 0x5f, 0x1b, 0xec, 0x68, 0x82, 0x1d, 0x12, 0x88, 0x05, 0xca, 0x92, + 0x02, 0x8d, 0x52, 0x75, 0x00, 0x8f, 0x33, 0x09, 0xc0, 0xf2, 0x40, 0xa0, 0xa1, 0xa8, 0xdf, 0xa3, + 0x21, 0x48, 0x12, 0x72, 0xcc, 0x53, 0xd4, 0x09, 0x18, 0x58, 0x59, 0xaa, 0x9c, 0x2c, 0x80, 0x00, + 0x76, 0x4b, 0x25, 0xf8, 0xb8, 0x4f, 0xa2, 0x8b, 0xe5, 0xe4, 0x36, 0xbc, 0x49, 0xfa, 0x9a, 0x2d, + 0xfa, 0x99, 0x2e, 0x13, 0xc4, 0x10, 0x5b, 0x02, 0x78, 0x8d, 0x3e, 0x88, 0x11, 0x17, 0x86, 0xec, + 0xaa, 0x2d, 0x72, 0xfd, 0x04, 0xc8, 0x65, 0x80, 0x53, 0x6c, 0xb6, 0x22, 0xcf, 0xab, 0x04, 0x26, + 0xa1, 0x54, 0x89, 0xa2, 0xb1, 0x15, 0xed, 0xec, 0xde, 0x8a, 0xd6, 0x98, 0xa2, 0x9c, 0x7d, 0xaf, + 0xa2, 0x5d, 0x72, 0x00, 0x8a, 0xab, 0x2e, 0xc0, 0x92, 0xab, 0x4d, 0x28, 0x87, 0xc9, 0x26, 0x55, + 0x7c, 0xa7, 0x13, 0x2b, 0xbe, 0x73, 0x73, 0xea, 0x69, 0xd5, 0x39, 0x85, 0xf8, 0x8e, 0x03, 0x55, + 0x9a, 0xdc, 0x3b, 0x6c, 0x2d, 0x30, 0x8d, 0x6b, 0xd1, 0x84, 0x67, 0x28, 0x40, 0xe2, 0x32, 0x63, + 0xc8, 0xd6, 0x06, 0x86, 0xe7, 0x91, 0x84, 0x22, 0x7a, 0x2b, 0x60, 0x5c, 0x3d, 0x83, 0x5d, 0x19, + 0xbb, 0x66, 0xcb, 0xb3, 0x02, 0x08, 0x27, 0x5c, 0x4c, 0x4a, 0xb6, 0x04, 0xaf, 0x47, 0x72, 0x39, + 0x2d, 0x2e, 0xd9, 0x68, 0x8d, 0x2f, 0x2e, 0xde, 0xbe, 0x32, 0x04, 0xe5, 0x9f, 0xff, 0xf9, 0x3f, + 0xba, 0x2a, 0x0d, 0x97, 0x76, 0x84, 0xf7, 0x0c, 0x75, 0x83, 0xe2, 0x89, 0x20, 0x35, 0x30, 0xf8, + 0xe7, 0x7f, 0xfe, 0x8f, 0x9e, 0x46, 0x82, 0x28, 0x96, 0x03, 0xce, 0x5a, 0x87, 0x55, 0x4b, 0xcc, + 0x67, 0x50, 0x1e, 0x9e, 0xe4, 0xa5, 0x16, 0x0c, 0xcb, 0x44, 0x80, 0xe0, 0x76, 0x87, 0xb3, 0x65, + 0x1b, 0xb4, 0x48, 0x5e, 0x6c, 0xb6, 0x55, 0xca, 0x9b, 0xb7, 0x9f, 0x5c, 0x46, 0xac, 0xd0, 0x21, + 0x15, 0x60, 0xe4, 0x6f, 0xcd, 0x1c, 0x68, 0x0c, 0x56, 0x6f, 0x2d, 0xd8, 0xb0, 0x16, 0x40, 0x46, + 0x58, 0xa5, 0x5d, 0x21, 0xc6, 0x24, 0x0f, 0xd2, 0xa8, 0x1c, 0xb8, 0x00, 0x72, 0x93, 0xa2, 0xa0, + 0xf7, 0x64, 0x54, 0x57, 0x8e, 0xb6, 0x31, 0x33, 0xe3, 0x6f, 0x1b, 0x1d, 0x94, 0xd3, 0xe3, 0xcf, + 0x97, 0xc2, 0xc5, 0xe5, 0xf1, 0xfb, 0x8b, 0xa6, 0xa2, 0x18, 0x0a, 0x26, 0xb7, 0xda, 0x30, 0x53, + 0x39, 0x60, 0x15, 0x90, 0xaa, 0x97, 0x49, 0x2e, 0x40, 0x64, 0x3b, 0xcc, 0x86, 0x61, 0x65, 0xc7, + 0x15, 0x28, 0x49, 0x8a, 0x67, 0xb0, 0x02, 0x81, 0x4f, 0x82, 0x72, 0x84, 0x29, 0xc9, 0xca, 0xa6, + 0x51, 0x36, 0xfd, 0xce, 0xfe, 0x8b, 0xc0, 0x27, 0x3d, 0xb8, 0xb1, 0xc0, 0xa8, 0x98, 0x4d, 0xa2, + 0x10, 0x0b, 0xac, 0x82, 0x6c, 0x0e, 0xe9, 0xc0, 0x3a, 0x0a, 0xfc, 0xcb, 0x96, 0x4b, 0xb2, 0x0d, + 0x21, 0xbe, 0x13, 0x5e, 0xbd, 0x39, 0x7a, 0x2f, 0xbc, 0x7d, 0x5f, 0xaa, 0xbc, 0xb9, 0x3c, 0xb9, + 0x24, 0x99, 0x46, 0x22, 0x10, 0x3e, 0x31, 0x66, 0x08, 0x30, 0x66, 0xcc, 0x30, 0x48, 0x2f, 0xa2, + 0x80, 0xa3, 0x5c, 0xc3, 0x8c, 0xc2, 0x08, 0xa2, 0xc5, 0x6f, 0x43, 0xc8, 0x61, 0x11, 0xef, 0x13, + 0x3c, 0x2d, 0x44, 0x86, 0xc9, 0xcc, 0xa2, 0xa9, 0xb5, 0x24, 0xea, 0x09, 0x27, 0xa9, 0xf0, 0xe6, + 0xf2, 0xf2, 0xbd, 0x70, 0x68, 0x25, 0xbe, 0x03, 0x52, 0x3c, 0xc1, 0x61, 0xea, 0x3b, 0xe4, 0xbd, + 0x8e, 0x00, 0x75, 0x44, 0xf3, 0x04, 0xc7, 0xa0, 0x0c, 0x04, 0xa6, 0xa0, 0xc7, 0x10, 0x6a, 0x77, + 0x68, 0xe5, 0x29, 0x6d, 0x20, 0x38, 0x03, 0xf4, 0x41, 0x9b, 0xde, 0x34, 0x00, 0xce, 0x92, 0x90, + 0x4c, 0xa2, 0xbb, 0x30, 0x9b, 0x1e, 0x99, 0x19, 0xcd, 0x9f, 0x65, 0x7a, 0xa1, 0x24, 0x1a, 0xdb, + 0xd8, 0x7f, 0x1b, 0xb3, 0xba, 0x51, 0x88, 0x5b, 0xe3, 0xd7, 0x51, 0x2a, 0xf8, 0x69, 0x39, 0x75, + 0x92, 0x73, 0x2a, 0x7c, 0x00, 0x61, 0xab, 0x15, 0x7d, 0x73, 0x47, 0x81, 0x58, 0x46, 0x18, 0x1a, + 0xb2, 0x53, 0x1b, 0x10, 0x33, 0x36, 0x5b, 0xb3, 0x28, 0xf0, 0x81, 0x98, 0x05, 0x34, 0xbe, 0xfe, + 0x3b, 0xca, 0x2a, 0x65, 0xed, 0x7a, 0x31, 0x2d, 0x77, 0xcb, 0x65, 0x00, 0x89, 0xb8, 0x7a, 0x39, + 0x38, 0x25, 0x5e, 0x5e, 0x10, 0x5e, 0x89, 0x49, 0x14, 0x05, 0x9d, 0xc0, 0x53, 0xc5, 0xb6, 0x47, + 0xf7, 0xca, 0x0a, 0x16, 0xe4, 0xc6, 0x04, 0x6e, 0x84, 0xd2, 0x9e, 0xb8, 0x9f, 0x38, 0xb1, 0x3f, + 0x4b, 0xc7, 0xa2, 0x28, 0x99, 0xe3, 0xd5, 0xc2, 0x8a, 0x85, 0xf3, 0xc8, 0x3c, 0xb3, 0xff, 0xc0, + 0x4e, 0xda, 0x71, 0xb1, 0xe7, 0x87, 0xf8, 0x7d, 0x1c, 0xcd, 0x70, 0x9c, 0x2e, 0x47, 0xf0, 0x30, + 0xc5, 0xa6, 0x98, 0x20, 0x2c, 0x99, 0x63, 0xe8, 0x2f, 0x26, 0xbb, 0xbb, 0x22, 0x36, 0x13, 0x31, + 0x31, 0x65, 0x49, 0x42, 0x58, 0x22, 0x7d, 0x8e, 0xa3, 0xac, 0xcf, 0xca, 0x8b, 0x62, 0x91, 0xbc, + 0x06, 0xdc, 0x8a, 0xa5, 0xf3, 0x48, 0x4c, 0x50, 0x8a, 0x56, 0x37, 0x38, 0x35, 0xf0, 0x55, 0x7a, + 0x8d, 0x70, 0x38, 0x9f, 0xe2, 0x18, 0xae, 0xba, 0x33, 0x76, 0xe4, 0xb5, 0xb4, 0x26, 0xef, 0x5f, + 0x60, 0xf4, 0x3a, 0x31, 0x53, 0x4c, 0x51, 0xba, 0xc0, 0x26, 0x2c, 0x7c, 0xe4, 0x09, 0x37, 0x41, + 0x64, 0x5b, 0xc1, 0xe5, 0xc4, 0x4f, 0x4c, 0xb3, 0x15, 0x11, 0x14, 0x5b, 0xbb, 0xbb, 0x2d, 0x27, + 0x5e, 0xce, 0xd2, 0xa8, 0xe5, 0x87, 0x5c, 0x87, 0x97, 0xc5, 0xc7, 0x0e, 0x7d, 0x6e, 0x2c, 0x22, + 0xdf, 0x15, 0xe4, 0xb5, 0x34, 0xf2, 0xe6, 0x21, 0x0d, 0xbb, 0x04, 0x58, 0x4c, 0xa4, 0x15, 0x75, + 0x73, 0x84, 0x84, 0x14, 0xbe, 0x81, 0x96, 0x8c, 0x3c, 0xe1, 0xa3, 0x1f, 0xa6, 0x83, 0x83, 0x38, + 0xb6, 0x96, 0x0f, 0x0f, 0xe4, 0xcf, 0xe1, 0xdc, 0xf3, 0x70, 0xdc, 0xf1, 0x93, 0xdf, 0x7c, 0x7c, + 0x27, 0x26, 0xd2, 0xee, 0x6e, 0x02, 0x07, 0x19, 0x93, 0x34, 0x9e, 0x3b, 0x69, 0x14, 0x77, 0xc8, + 0x7e, 0x68, 0x9a, 0xad, 0xe2, 0xc5, 0xd6, 0x3a, 0x1f, 0xe7, 0x24, 0x85, 0x71, 0x7c, 0x4f, 0xdc, + 0x39, 0x9d, 0x4f, 0x6d, 0x02, 0xe6, 0xc2, 0xf2, 0xf0, 0xdb, 0x30, 0xc5, 0x37, 0x38, 0x16, 0x13, + 0xe9, 0xe1, 0x21, 0xd9, 0x97, 0x25, 0x70, 0x18, 0xef, 0x88, 0xf4, 0x1f, 0x43, 0xd4, 0x4e, 0x6c, + 0xd1, 0x93, 0xe2, 0x0b, 0x2c, 0xf8, 0xb4, 0xa7, 0x80, 0xef, 0x67, 0xc4, 0x76, 0x42, 0xc2, 0x4d, + 0x94, 0x0a, 0xad, 0xbd, 0x44, 0x2a, 0x06, 0xf9, 0x45, 0x4c, 0x50, 0xa7, 0xd3, 0xc1, 0x74, 0x20, + 0x32, 0xb5, 0x3a, 0xc4, 0x02, 0xbd, 0x1c, 0x56, 0x4b, 0x1a, 0xf9, 0x9e, 0x88, 0x3b, 0x74, 0xbb, + 0x1e, 0xcb, 0xbb, 0xbb, 0x3b, 0xb8, 0xe3, 0x87, 0x4e, 0x30, 0x77, 0x71, 0x22, 0x26, 0xac, 0xfd, + 0x69, 0xb0, 0xa0, 0x66, 0x90, 0xf6, 0x17, 0x5a, 0x7b, 0x78, 0xaf, 0x45, 0xf1, 0xcc, 0x0c, 0x81, + 0xbd, 0x1c, 0x58, 0x81, 0xf5, 0x9b, 0x14, 0x38, 0xc5, 0xdc, 0x91, 0x09, 0xda, 0x49, 0xc7, 0xc5, + 0xc0, 0xe7, 0x4b, 0xec, 0xd6, 0xc7, 0x7b, 0x63, 0x25, 0x93, 0x7c, 0x8d, 0x84, 0x89, 0x95, 0x08, + 0x36, 0x94, 0x20, 0xe7, 0x6f, 0xb0, 0x89, 0xc0, 0xca, 0xc0, 0xad, 0x1c, 0xc9, 0x64, 0x13, 0x90, + 0x9f, 0x5c, 0xff, 0x06, 0x27, 0xa9, 0x28, 0x11, 0x20, 0x56, 0x00, 0x31, 0xeb, 0x25, 0x05, 0xe6, + 0x58, 0x60, 0xef, 0xb7, 0x38, 0x04, 0x3f, 0x25, 0x84, 0x95, 0x57, 0xbf, 0x88, 0x09, 0xb9, 0x44, + 0x5a, 0x48, 0x4d, 0xf2, 0xb3, 0x34, 0xb3, 0x79, 0xfa, 0x0e, 0x87, 0x23, 0x82, 0x34, 0x9d, 0xd5, + 0x7e, 0x5a, 0x1f, 0x8e, 0x8e, 0xf4, 0x36, 0x4c, 0x23, 0x51, 0x62, 0x54, 0x4a, 0x04, 0xfa, 0xb6, + 0x60, 0x13, 0x96, 0xe2, 0x48, 0x66, 0x01, 0xa9, 0xe0, 0xda, 0xa0, 0xd6, 0x5e, 0xca, 0x61, 0xf0, + 0x33, 0x16, 0x3b, 0x9d, 0x4e, 0x22, 0x11, 0x59, 0x02, 0x0c, 0xb0, 0x29, 0x8f, 0xf0, 0x7e, 0x36, + 0xec, 0x08, 0xef, 0xed, 0x49, 0xc9, 0x15, 0xbe, 0xee, 0x40, 0xc5, 0x92, 0x28, 0x73, 0x6f, 0x46, + 0x29, 0xc7, 0xdf, 0x64, 0x57, 0xb1, 0x52, 0x8b, 0x32, 0x70, 0x87, 0x8e, 0x8e, 0x92, 0x0e, 0x18, + 0x35, 0x67, 0x9e, 0x97, 0xe0, 0x94, 0x7d, 0x79, 0x57, 0x5d, 0xa3, 0x43, 0xcc, 0xd8, 0x17, 0x68, + 0x80, 0x3e, 0x27, 0x52, 0x26, 0x31, 0x9d, 0x34, 0x7a, 0x83, 0xef, 0x45, 0x4a, 0x17, 0xa8, 0x0e, + 0x18, 0x65, 0x28, 0xa6, 0xa6, 0x3c, 0x4a, 0x0b, 0x14, 0xd3, 0xbd, 0x3d, 0x09, 0xef, 0x99, 0x76, + 0x74, 0x95, 0x5c, 0xa5, 0xd7, 0xd7, 0x23, 0x06, 0x00, 0x17, 0x63, 0x7c, 0x4d, 0xd8, 0x18, 0xc9, + 0xd8, 0x9c, 0xe0, 0xce, 0x37, 0x79, 0x77, 0x37, 0xd9, 0x27, 0x9f, 0x86, 0xf9, 0x70, 0x6d, 0xf2, + 0x60, 0x94, 0x77, 0x3a, 0xc8, 0xfa, 0x9c, 0x14, 0x5d, 0x44, 0x68, 0x6f, 0xc3, 0x0d, 0x90, 0x79, + 0x37, 0x2b, 0xeb, 0xe6, 0x95, 0xbb, 0x59, 0xd0, 0xad, 0xc0, 0x20, 0xce, 0x84, 0x94, 0x29, 0x9b, + 0x64, 0x07, 0xfc, 0x96, 0x18, 0x12, 0x15, 0xf5, 0x75, 0x9d, 0xe0, 0x7b, 0x81, 0x3e, 0xac, 0xc9, + 0x64, 0xf6, 0x3a, 0xc1, 0xa0, 0x20, 0x56, 0x21, 0x2d, 0x1d, 0x2f, 0x8e, 0xa6, 0x40, 0xb7, 0x24, + 0x23, 0x5c, 0x46, 0x27, 0x94, 0x9a, 0xf8, 0x85, 0x4a, 0xb8, 0xf8, 0x99, 0xfa, 0x03, 0x83, 0xce, + 0x43, 0x38, 0x6b, 0x8a, 0x5d, 0x01, 0x7a, 0x94, 0x44, 0x90, 0x8e, 0x10, 0x9a, 0x00, 0xa5, 0xc0, + 0x40, 0x24, 0x77, 0xa4, 0xd1, 0x95, 0x8a, 0x4c, 0x19, 0xc5, 0xa6, 0x3c, 0x8a, 0xf6, 0xd3, 0x51, + 0xb4, 0xb7, 0x87, 0xe2, 0x3d, 0x53, 0x85, 0xa3, 0xfe, 0xa9, 0xe0, 0x9b, 0xb0, 0x28, 0xe4, 0x62, + 0xfa, 0xa3, 0xc8, 0xc5, 0x07, 0xa9, 0x18, 0x4b, 0x12, 0x72, 0xeb, 0xad, 0x7b, 0x8a, 0x44, 0x26, + 0xeb, 0x9b, 0xa6, 0x49, 0x95, 0xec, 0xc3, 0x83, 0x9b, 0x7f, 0xa6, 0xc0, 0x1c, 0x33, 0xb9, 0x8a, + 0xaf, 0xf7, 0x92, 0xab, 0x78, 0x4f, 0xb9, 0x1e, 0x55, 0xa7, 0xf6, 0xf7, 0x8d, 0x53, 0x0b, 0x49, + 0x05, 0xc0, 0x7d, 0x61, 0x58, 0x0b, 0xad, 0xbf, 0xef, 0x39, 0x7b, 0x7f, 0x6f, 0x81, 0xb4, 0x90, + 0x3b, 0x9a, 0x84, 0xbf, 0xef, 0xc5, 0xd2, 0x3a, 0xbc, 0x8a, 0xae, 0x4d, 0xff, 0xb9, 0xd2, 0xdb, + 0x73, 0xd7, 0x19, 0xc3, 0x17, 0x6b, 0x3b, 0xc7, 0x3f, 0xb0, 0xb6, 0x15, 0x3c, 0x5a, 0xd2, 0x88, + 0x93, 0x20, 0x8e, 0x88, 0xf0, 0xf5, 0x12, 0xdf, 0xa7, 0xc7, 0xa1, 0x13, 0xb9, 0x38, 0x16, 0xa5, + 0x0e, 0x26, 0x9f, 0x40, 0xf1, 0x16, 0x43, 0xff, 0xc9, 0xcb, 0x60, 0x36, 0xbc, 0x99, 0x0f, 0xbf, + 0xbb, 0x2b, 0x26, 0x26, 0x41, 0x4f, 0x42, 0x44, 0xbc, 0x92, 0xe2, 0xd5, 0xff, 0x60, 0x72, 0x9f, + 0xc9, 0x7c, 0xb6, 0x64, 0xa1, 0x29, 0x8f, 0xc2, 0x42, 0xb8, 0xc2, 0xbd, 0x3d, 0xda, 0x27, 0x32, + 0x93, 0xab, 0xf0, 0x7a, 0xf4, 0x8b, 0x18, 0x49, 0x08, 0xef, 0x99, 0x11, 0xeb, 0xb0, 0xa6, 0x02, + 0x59, 0xc1, 0x1e, 0x4b, 0x3c, 0x3c, 0x14, 0x6d, 0x80, 0x19, 0x53, 0x98, 0x29, 0x5c, 0xba, 0x2c, + 0xc6, 0x28, 0x92, 0x50, 0xb4, 0x67, 0xc6, 0x19, 0xe4, 0x6c, 0x5a, 0x05, 0xce, 0xdf, 0x89, 0x1c, + 0x53, 0x8c, 0x43, 0x73, 0x9c, 0x88, 0x52, 0x67, 0x3e, 0x73, 0xe1, 0x62, 0xa3, 0x3f, 0x53, 0x31, + 0x94, 0xa4, 0x4e, 0xa6, 0x7b, 0x51, 0x6a, 0x26, 0x62, 0x4e, 0x5a, 0x4e, 0xa5, 0x9a, 0x69, 0xf1, + 0x19, 0xe1, 0x0e, 0xb9, 0xbe, 0x87, 0x36, 0x67, 0x1f, 0x11, 0xee, 0x38, 0x31, 0xb6, 0xc0, 0x12, + 0x91, 0xc8, 0x10, 0x88, 0x53, 0x24, 0xaf, 0xb1, 0x98, 0x98, 0x5d, 0x95, 0xac, 0xf6, 0x05, 0xde, + 0xdd, 0x65, 0x24, 0xbf, 0xc0, 0x9d, 0x1b, 0x9c, 0x9e, 0x5b, 0xa1, 0x1b, 0x4d, 0x7f, 0x83, 0x5a, + 0x26, 0x58, 0x83, 0xec, 0xa5, 0x56, 0x26, 0xa4, 0xf5, 0x5e, 0x62, 0x85, 0x6c, 0x09, 0x65, 0xf5, + 0x32, 0xe4, 0x98, 0xbc, 0x70, 0x08, 0xde, 0x61, 0x13, 0xd4, 0x8a, 0xe8, 0x8b, 0xe5, 0x37, 0x08, + 0xc8, 0x1a, 0x13, 0x52, 0x9b, 0xa5, 0x8a, 0x8d, 0x30, 0x9d, 0x27, 0xa9, 0x60, 0x63, 0x81, 0x1a, + 0x66, 0xb0, 0x51, 0x81, 0xbd, 0xf4, 0x39, 0x41, 0x76, 0x84, 0x26, 0x18, 0x85, 0x29, 0x3a, 0xc3, + 0xb9, 0xe1, 0xf4, 0x1a, 0x08, 0xfc, 0x39, 0xc9, 0xac, 0xa7, 0x2a, 0x1a, 0x57, 0xd7, 0x12, 0x55, + 0xe0, 0x3c, 0xce, 0xf9, 0xb4, 0xea, 0xfa, 0x8a, 0xef, 0x86, 0xec, 0xc8, 0xe4, 0x40, 0xad, 0x28, + 0x3f, 0x18, 0xaa, 0xde, 0x5b, 0x23, 0x66, 0xfa, 0xe1, 0x4e, 0x1a, 0x5d, 0x10, 0x26, 0x17, 0x95, + 0x9e, 0xd4, 0x99, 0x59, 0x2e, 0x39, 0x64, 0x22, 0xaa, 0xa8, 0x25, 0xb7, 0x24, 0x69, 0x34, 0xc1, + 0xe6, 0xea, 0x9b, 0x6c, 0x68, 0x03, 0xf4, 0x6d, 0x68, 0xe8, 0x7d, 0x74, 0x60, 0xf4, 0x74, 0x74, + 0x62, 0xf4, 0x65, 0x64, 0x19, 0xc3, 0x3e, 0xf2, 0xe0, 0x92, 0xfc, 0xf5, 0x28, 0x4c, 0x4d, 0x62, + 0xc8, 0xae, 0xd6, 0xbc, 0xe1, 0x76, 0x01, 0x66, 0x24, 0x46, 0x29, 0x0a, 0x4b, 0x52, 0x0d, 0x4c, + 0x7a, 0xe8, 0xdf, 0x00, 0xea, 0x3d, 0xad, 0x69, 0x25, 0xca, 0x3d, 0x44, 0x0a, 0x61, 0x44, 0x65, + 0xe7, 0xd0, 0xbf, 0x79, 0x1b, 0xa6, 0x62, 0x57, 0x95, 0x50, 0x9c, 0x7d, 0xd1, 0xd4, 0xa1, 0x36, + 0xec, 0xf5, 0xd5, 0xa1, 0x2e, 0x21, 0xdf, 0xa4, 0xc6, 0x9b, 0x98, 0x8e, 0xc7, 0xd1, 0x6e, 0x0c, + 0x9a, 0x30, 0x6b, 0x80, 0x6f, 0x8e, 0x19, 0xbe, 0xd4, 0x0c, 0x19, 0x4d, 0xcc, 0xf0, 0xa5, 0x6c, + 0x68, 0x23, 0x32, 0x14, 0x8c, 0xd3, 0x55, 0x45, 0xbc, 0xe7, 0x20, 0x1f, 0x85, 0x12, 0x2a, 0x37, + 0x4e, 0x90, 0x8b, 0x42, 0xba, 0x82, 0x56, 0x8a, 0x3e, 0xa3, 0x0f, 0x85, 0xcd, 0x7b, 0x86, 0x45, + 0x69, 0x64, 0xb1, 0xb9, 0x0b, 0xf8, 0x3e, 0xc5, 0xa1, 0x9b, 0x08, 0x21, 0xdc, 0xd5, 0x9e, 0xdb, + 0x9c, 0x14, 0x7d, 0x14, 0x49, 0xab, 0x64, 0x3e, 0x03, 0xfd, 0x83, 0xc0, 0xe9, 0xcc, 0x6d, 0x1f, + 0x73, 0x47, 0xa1, 0x0d, 0xcc, 0xfc, 0x92, 0xe9, 0xb7, 0x59, 0x94, 0x64, 0x1f, 0x73, 0xcb, 0x29, + 0xef, 0x9a, 0x0b, 0x1b, 0xa6, 0xdf, 0x39, 0xa1, 0x64, 0x6f, 0x5b, 0x2e, 0xb5, 0x15, 0xcc, 0x90, + 0x36, 0xf8, 0xc9, 0xbb, 0x63, 0x33, 0x62, 0x6f, 0x13, 0x93, 0xa2, 0xae, 0x68, 0xe8, 0x53, 0x72, + 0x7e, 0x31, 0x4a, 0x45, 0xae, 0xab, 0xb4, 0x66, 0xba, 0x01, 0x4b, 0xab, 0x37, 0xf4, 0x89, 0x84, + 0xb0, 0xf9, 0x67, 0x0a, 0x2f, 0xfd, 0x22, 0xd2, 0xdd, 0x6b, 0x05, 0x2f, 0x1a, 0x29, 0xa2, 0xaf, + 0x18, 0x21, 0xca, 0x90, 0x34, 0xa2, 0xb5, 0x09, 0xaf, 0xa0, 0xd8, 0xcc, 0xac, 0xd7, 0x5c, 0xa5, + 0xf9, 0xa6, 0x3c, 0xf2, 0xf7, 0xe3, 0x11, 0x55, 0x45, 0xae, 0xf9, 0xab, 0x95, 0x4e, 0x3a, 0x70, + 0xdb, 0x65, 0xd4, 0xce, 0xa8, 0x80, 0xe2, 0xb6, 0x4f, 0x64, 0x19, 0xb6, 0xaa, 0x28, 0xdb, 0xa5, + 0xa2, 0x34, 0xd3, 0x8c, 0xa3, 0x68, 0xdf, 0x8c, 0xdb, 0xfe, 0xc8, 0xdf, 0x33, 0x23, 0x89, 0xbe, + 0x14, 0x47, 0x0e, 0xfc, 0x8c, 0x9a, 0x83, 0x7c, 0xb8, 0x27, 0x3c, 0x4c, 0xfd, 0x70, 0x8e, 0xd7, + 0x21, 0x51, 0x8d, 0xb8, 0x93, 0xcc, 0x6d, 0x8b, 0x4c, 0xd8, 0x47, 0xfe, 0x9e, 0x2b, 0xe5, 0xd4, + 0x2e, 0x3e, 0xed, 0x99, 0x2e, 0xf2, 0xe1, 0x9f, 0x7c, 0x21, 0x4c, 0x33, 0xda, 0xdd, 0x15, 0x4b, + 0xc0, 0x53, 0x24, 0x4b, 0xdc, 0x4a, 0x49, 0xb9, 0x8e, 0x2d, 0x96, 0x72, 0x2f, 0x9f, 0x2f, 0xed, + 0x48, 0xee, 0xb8, 0x82, 0xc4, 0x42, 0xc8, 0x78, 0x60, 0xcd, 0x99, 0x9d, 0x3c, 0x69, 0x3f, 0x25, + 0x22, 0x5d, 0xd8, 0x1a, 0xab, 0x90, 0x9f, 0x2f, 0x5a, 0x31, 0x12, 0xa7, 0x88, 0x90, 0x9c, 0xa7, + 0x34, 0x82, 0x75, 0x36, 0x62, 0x46, 0x70, 0xb8, 0xc2, 0xca, 0xf0, 0xe9, 0x97, 0x51, 0x7a, 0xe5, + 0xef, 0xed, 0x5d, 0x9b, 0x8a, 0x3a, 0x40, 0x3f, 0x63, 0x7e, 0x75, 0x39, 0x8a, 0x48, 0x52, 0x85, + 0x7d, 0xc6, 0x51, 0xdb, 0xaf, 0xce, 0x3c, 0x84, 0x99, 0xfb, 0xa6, 0x5c, 0x6c, 0x4c, 0x73, 0xd3, + 0x1f, 0xcd, 0xf7, 0xa3, 0xd1, 0x7c, 0x6f, 0x4f, 0x4a, 0xaf, 0xe6, 0xd7, 0xa6, 0x3c, 0xba, 0x88, + 0xc4, 0x10, 0x45, 0xed, 0x01, 0x62, 0x12, 0xca, 0x91, 0xe5, 0xf9, 0x40, 0x42, 0x71, 0x36, 0x10, + 0x07, 0x73, 0x44, 0x59, 0x80, 0xac, 0x2c, 0x72, 0xcc, 0x32, 0x63, 0x03, 0x03, 0x38, 0xcf, 0xb4, + 0xba, 0x15, 0xf0, 0x2d, 0x99, 0x58, 0xaa, 0x21, 0xe4, 0x1d, 0x21, 0x60, 0x31, 0x0f, 0x5c, 0x50, + 0xbe, 0xe4, 0xc2, 0x12, 0x48, 0xf0, 0x45, 0x42, 0x57, 0x85, 0x83, 0x7d, 0x74, 0x88, 0x89, 0xe9, + 0xbc, 0xd0, 0x50, 0x40, 0x07, 0xb8, 0xc1, 0xa9, 0x48, 0xb8, 0x6b, 0x32, 0x0e, 0x32, 0xaf, 0xe7, + 0xf1, 0x31, 0x6c, 0xff, 0x06, 0xdc, 0xbc, 0x74, 0x62, 0xd1, 0xe8, 0x0c, 0x6e, 0xf1, 0xc4, 0x90, + 0x47, 0xf3, 0xfd, 0x09, 0x21, 0x86, 0xcb, 0xe9, 0x11, 0xed, 0xf9, 0x1c, 0x05, 0x57, 0xf3, 0x6b, + 0x14, 0x4b, 0xeb, 0x6c, 0x73, 0x5d, 0x71, 0xab, 0x89, 0x51, 0x0e, 0xdf, 0x48, 0xb3, 0x35, 0x23, + 0xe2, 0xcf, 0x33, 0x09, 0xb3, 0x13, 0x71, 0x27, 0x09, 0x7c, 0x07, 0x8b, 0x32, 0x4a, 0xf3, 0xbd, + 0x99, 0xd7, 0x15, 0xa2, 0x84, 0xc2, 0xf5, 0x37, 0x27, 0x88, 0x42, 0x9c, 0x71, 0x17, 0x7e, 0x78, + 0x10, 0x31, 0x11, 0x7a, 0xd2, 0x91, 0x53, 0x50, 0x12, 0xc2, 0x44, 0x36, 0x3a, 0x9d, 0x4e, 0x41, + 0x13, 0x2a, 0xd3, 0x39, 0x67, 0x71, 0x72, 0xcd, 0xf6, 0x90, 0x08, 0x65, 0x6c, 0x69, 0xc4, 0x28, + 0x57, 0x51, 0x86, 0x8f, 0x80, 0xe9, 0x5c, 0x36, 0x81, 0xdc, 0x6c, 0x28, 0x74, 0x98, 0x8f, 0x70, + 0xc1, 0xd0, 0x31, 0xca, 0x44, 0xc4, 0x8c, 0x10, 0x26, 0xa2, 0xe4, 0xa2, 0xe8, 0x59, 0xba, 0xbb, + 0x8b, 0x73, 0xee, 0xc4, 0x60, 0x90, 0x20, 0xbc, 0x26, 0xb3, 0x11, 0x0b, 0x1b, 0x0d, 0x50, 0xe5, + 0xa6, 0x28, 0xad, 0xd7, 0xe8, 0xb3, 0x49, 0x89, 0xcd, 0xef, 0x9e, 0x4a, 0xbf, 0x3f, 0x94, 0xbb, + 0xdd, 0xbe, 0xdc, 0x45, 0x9a, 0x3c, 0x18, 0xaa, 0x5d, 0xbd, 0xaf, 0xca, 0xa8, 0xab, 0x68, 0x9a, + 0xd2, 0xd5, 0xd4, 0x7e, 0x1f, 0xa9, 0xaa, 0xda, 0x1f, 0xf4, 0xbb, 0xfa, 0x50, 0x47, 0x8a, 0xac, + 0x74, 0x87, 0xb2, 0xa6, 0x6a, 0x2a, 0xd2, 0xd4, 0xbe, 0xa2, 0xf4, 0xf5, 0xbe, 0xda, 0x45, 0x6a, + 0xbf, 0xdf, 0xd5, 0x06, 0x72, 0xbf, 0xa7, 0x22, 0x45, 0x1f, 0xea, 0x7d, 0x5d, 0x56, 0xd4, 0x21, + 0x52, 0xba, 0xfa, 0x70, 0x30, 0xec, 0x2a, 0xca, 0x10, 0xa9, 0x43, 0xa5, 0xaf, 0xf7, 0x74, 0xa5, + 0xdb, 0x47, 0x6a, 0x4f, 0x96, 0x07, 0xaa, 0x3a, 0x54, 0x35, 0xd4, 0x57, 0x75, 0x5d, 0x51, 0x94, + 0xe1, 0x10, 0xe9, 0xea, 0xa0, 0xdf, 0xd5, 0x7a, 0x5d, 0x1d, 0x69, 0xaa, 0xa2, 0x77, 0x07, 0x43, + 0x5d, 0xeb, 0x23, 0x45, 0xd7, 0x14, 0x4d, 0x1f, 0xaa, 0xaa, 0x8e, 0xba, 0x6a, 0x5f, 0xee, 0x76, + 0x55, 0x79, 0x78, 0x2d, 0xf1, 0xbb, 0xe7, 0x61, 0x44, 0x7d, 0x6e, 0x25, 0x9f, 0x33, 0x7e, 0xb9, + 0x9a, 0x18, 0x6c, 0x37, 0x4b, 0x76, 0xfd, 0x54, 0x42, 0x41, 0xfe, 0x75, 0x3c, 0xfe, 0x83, 0x34, + 0xad, 0x0d, 0xae, 0x4f, 0xd6, 0xf8, 0x20, 0x73, 0x3d, 0x69, 0xc3, 0x9a, 0x33, 0x60, 0x93, 0x7c, + 0x20, 0x6a, 0x83, 0xe6, 0x8e, 0x4e, 0xe1, 0x91, 0x30, 0xa2, 0x8a, 0xa9, 0x84, 0xa2, 0x86, 0xc6, + 0x9c, 0xfd, 0xc1, 0x47, 0x89, 0xf7, 0xd3, 0x51, 0xcc, 0x2c, 0xd3, 0xd5, 0xc4, 0xf0, 0x51, 0x00, + 0x0c, 0x01, 0xd3, 0xb9, 0x8a, 0xaf, 0x21, 0xf8, 0x74, 0x15, 0xc2, 0x87, 0xe8, 0x2a, 0xbe, 0xbe, + 0x36, 0xaf, 0x7c, 0xe4, 0x5e, 0x33, 0xed, 0x79, 0x15, 0xa2, 0xe8, 0xba, 0xc0, 0x0b, 0x6c, 0xf4, + 0xcc, 0x7c, 0xa0, 0x9b, 0xbf, 0x88, 0xc7, 0xe3, 0xb1, 0x2c, 0xed, 0x89, 0x21, 0xf9, 0xcb, 0xf8, + 0x6b, 0x35, 0x31, 0x92, 0xbd, 0x74, 0x4f, 0x8c, 0x5e, 0xa8, 0xcf, 0x9f, 0x77, 0xd5, 0x07, 0x99, + 0xce, 0x37, 0x82, 0x49, 0xc2, 0xae, 0xed, 0xa7, 0xe8, 0x8f, 0x04, 0xfd, 0x96, 0xa2, 0x2f, 0x29, + 0x5a, 0x60, 0x74, 0x89, 0xd1, 0x57, 0x8c, 0x3e, 0x61, 0x84, 0x43, 0x94, 0x86, 0x28, 0x09, 0x51, + 0x18, 0xa2, 0x28, 0x44, 0x71, 0x88, 0xac, 0x30, 0xdf, 0xda, 0xfd, 0xb4, 0xc9, 0xba, 0xf8, 0x23, + 0xe1, 0x0c, 0x90, 0xd1, 0x6f, 0xa9, 0x49, 0x31, 0x04, 0xfb, 0x76, 0x3c, 0x1e, 0xc3, 0x08, 0x5c, + 0xcb, 0xfe, 0x7e, 0x57, 0x6d, 0xa7, 0x0f, 0x98, 0x3c, 0x59, 0xe0, 0x4a, 0xdf, 0x07, 0x4c, 0x9f, + 0xa3, 0x4b, 0xbc, 0xe9, 0x9d, 0xaf, 0xe5, 0x27, 0x3d, 0x2d, 0x7b, 0xd2, 0xee, 0xaa, 0xe8, 0x53, + 0x15, 0x60, 0xbb, 0xab, 0x02, 0x4c, 0xe8, 0x35, 0xc2, 0x61, 0xf1, 0x10, 0xd8, 0x80, 0x10, 0x2d, + 0x23, 0x5e, 0x4a, 0xfe, 0xa2, 0x34, 0xeb, 0x83, 0x42, 0xb0, 0x03, 0xf7, 0xd2, 0xbd, 0x70, 0x4f, + 0x4c, 0x78, 0x1a, 0x26, 0xa5, 0x1e, 0x1b, 0xe0, 0x64, 0x8b, 0x81, 0xc2, 0xa2, 0x37, 0x8a, 0x72, + 0x88, 0x51, 0x05, 0x66, 0x54, 0xe9, 0xf5, 0x08, 0xd4, 0x3d, 0x31, 0xa2, 0xd0, 0x63, 0xfe, 0x3d, + 0x14, 0x73, 0xf0, 0xe3, 0xf2, 0x08, 0x6b, 0x1a, 0xdc, 0x74, 0x42, 0x74, 0x19, 0xa1, 0x83, 0x08, + 0x1d, 0x61, 0x74, 0x8f, 0xd1, 0x2f, 0x29, 0x7a, 0x85, 0x91, 0x5b, 0xac, 0xef, 0x07, 0xb0, 0xba, + 0x61, 0x2b, 0x1e, 0x11, 0x23, 0xce, 0x09, 0xcd, 0xff, 0x48, 0xc4, 0xab, 0x96, 0x7c, 0xaf, 0xa9, + 0x03, 0x4b, 0xf5, 0x86, 0x03, 0xb7, 0xaf, 0x0e, 0x2c, 0xac, 0xaa, 0x2d, 0xd4, 0x92, 0xef, 0xfb, + 0x4a, 0xb7, 0xaf, 0x69, 0x43, 0x45, 0xed, 0x62, 0xaf, 0xa7, 0x3b, 0x2e, 0x69, 0xb4, 0x75, 0x47, + 0xf6, 0x6c, 0xc7, 0xc3, 0x8e, 0xe6, 0x76, 0x6d, 0xd5, 0x23, 0x8d, 0x78, 0x68, 0xeb, 0xae, 0x6d, + 0xe9, 0x03, 0x65, 0x30, 0x74, 0x6d, 0xdb, 0x21, 0x8d, 0xdd, 0xa1, 0xde, 0x73, 0x54, 0xdd, 0xf6, + 0xba, 0xda, 0xc0, 0xd6, 0xbb, 0x03, 0xd2, 0xa8, 0x0f, 0x3d, 0x45, 0x51, 0x3c, 0xc5, 0xee, 0xc9, + 0xba, 0x2b, 0x2b, 0x43, 0xd2, 0x38, 0x54, 0xbb, 0xde, 0x40, 0xb5, 0x34, 0xcb, 0x53, 0x86, 0x9a, + 0x37, 0xb4, 0x49, 0xa3, 0x65, 0x2b, 0x8e, 0x8e, 0x5d, 0xdd, 0xb5, 0x7a, 0xee, 0x40, 0x51, 0xe8, + 0xeb, 0xee, 0x40, 0xee, 0x5b, 0xd6, 0x70, 0x60, 0x75, 0xe5, 0xae, 0xac, 0x6a, 0x14, 0x4f, 0x45, + 0x1d, 0x74, 0x75, 0x5b, 0x56, 0x34, 0xbd, 0x2f, 0xf7, 0x3c, 0x1b, 0x93, 0x46, 0x55, 0xeb, 0x2a, + 0x03, 0xdd, 0xc6, 0x1a, 0xc6, 0x9a, 0xad, 0x0e, 0x28, 0x4a, 0xba, 0x2e, 0x3b, 0x7d, 0xd7, 0xe9, + 0xba, 0xba, 0xe7, 0xd9, 0x1a, 0x66, 0xd3, 0x54, 0x6d, 0xac, 0xbb, 0x7d, 0xcd, 0x53, 0xfb, 0xf6, + 0x60, 0xd8, 0xa3, 0x33, 0x82, 0x4b, 0x38, 0x6d, 0xc5, 0xc3, 0x5d, 0x5b, 0xe9, 0x0d, 0x7b, 0xb6, + 0x42, 0xf1, 0xb4, 0x5d, 0x47, 0xee, 0x59, 0x7d, 0x55, 0x77, 0xfa, 0x8a, 0xda, 0xd5, 0x49, 0xa3, + 0xa3, 0x0c, 0x6d, 0x4f, 0xe9, 0x6b, 0x8e, 0xd7, 0x1b, 0xaa, 0xbd, 0xa1, 0x46, 0x09, 0xa2, 0x0d, + 0xed, 0xde, 0xd0, 0x51, 0x86, 0xd8, 0x53, 0x34, 0xcb, 0xa5, 0x03, 0x61, 0xcf, 0xc6, 0x5a, 0x7f, + 0xd0, 0xeb, 0x0e, 0x34, 0x4f, 0xd5, 0x71, 0x97, 0x34, 0xca, 0x9e, 0xa3, 0x0c, 0x5d, 0xa7, 0x37, + 0xb0, 0x07, 0x8e, 0xab, 0xdb, 0x3a, 0x43, 0x5e, 0x76, 0x2c, 0xc5, 0x71, 0xfa, 0x7d, 0xcb, 0x19, + 0x3a, 0x3d, 0xd6, 0xe8, 0xe2, 0xa1, 0xea, 0xf4, 0x3c, 0x7d, 0xa8, 0xda, 0xb2, 0xda, 0xa7, 0x8d, + 0x9a, 0xd5, 0xd7, 0x06, 0x9a, 0x65, 0xf5, 0xb0, 0xd5, 0xc3, 0xda, 0x80, 0xc2, 0xd4, 0x1d, 0x5b, + 0xb6, 0x86, 0xae, 0x63, 0xbb, 0x9a, 0xe2, 0xd9, 0x2e, 0x45, 0xa9, 0xdf, 0xf3, 0x86, 0x83, 0x81, + 0x6b, 0x0d, 0xba, 0x8a, 0xa2, 0x77, 0xd9, 0x40, 0xc3, 0x41, 0x17, 0xeb, 0x8a, 0xae, 0x62, 0xdc, + 0xeb, 0xb9, 0x9e, 0xc5, 0x28, 0x3f, 0xe8, 0x2a, 0x4e, 0xaf, 0xe7, 0xaa, 0xae, 0xad, 0x75, 0x55, + 0x45, 0xa6, 0xeb, 0x2e, 0xcb, 0x5d, 0xb5, 0xef, 0x0c, 0x86, 0x03, 0xcf, 0x56, 0x95, 0x2e, 0xa5, + 0x92, 0xed, 0xe9, 0xc3, 0xbe, 0xe7, 0xf4, 0x6d, 0x8c, 0x3d, 0x19, 0x63, 0x3a, 0x90, 0xd3, 0xc3, + 0xb2, 0x6c, 0x7b, 0xdd, 0xae, 0x6b, 0x0d, 0x06, 0x9e, 0x43, 0xe7, 0xee, 0xea, 0x56, 0x7f, 0xa8, + 0x68, 0xfd, 0x61, 0x57, 0xb6, 0x80, 0x80, 0x74, 0xee, 0x3d, 0xc7, 0xea, 0x75, 0x75, 0x05, 0xcb, + 0x72, 0x77, 0xa0, 0x32, 0xca, 0x2b, 0x9a, 0x3a, 0x54, 0x87, 0xbd, 0xbe, 0x6c, 0xc9, 0xb8, 0x87, + 0xfb, 0x74, 0x74, 0xb5, 0x6f, 0xf7, 0x65, 0x6b, 0xa0, 0x6b, 0x3d, 0x57, 0x55, 0x3d, 0x8f, 0xae, + 0xa6, 0x8a, 0x15, 0x40, 0x65, 0xa0, 0x3b, 0x6a, 0xcf, 0x19, 0xaa, 0x3d, 0x4a, 0x10, 0x57, 0x75, + 0x7a, 0xae, 0xe7, 0xe8, 0x96, 0xa3, 0xa9, 0x16, 0xa6, 0x4c, 0xab, 0x77, 0xbb, 0x03, 0xd9, 0x55, + 0xba, 0x43, 0x77, 0xa8, 0xdb, 0x5d, 0x97, 0x0e, 0xd4, 0xd3, 0x65, 0xab, 0xdf, 0xd5, 0xb5, 0x81, + 0x6d, 0x79, 0xbd, 0xae, 0x8b, 0x19, 0x95, 0x7a, 0x96, 0x6c, 0xd9, 0x76, 0xd7, 0xe9, 0xf7, 0x6d, + 0xd5, 0xa2, 0x5c, 0x37, 0x50, 0x1c, 0xd5, 0x19, 0xaa, 0x58, 0xeb, 0x63, 0xd7, 0xc2, 0xb8, 0xc7, + 0x98, 0xb6, 0xaf, 0xaa, 0xce, 0x40, 0x57, 0xb4, 0x81, 0xda, 0xd5, 0xbb, 0x8c, 0x74, 0xaa, 0xed, + 0xe1, 0x81, 0xa5, 0x68, 0x8e, 0xa7, 0xc8, 0xdd, 0x9e, 0xc6, 0xe8, 0xa9, 0x58, 0xbd, 0x9e, 0x66, + 0xdb, 0x8e, 0xa6, 0x76, 0x65, 0x99, 0xf2, 0x92, 0xa3, 0x6a, 0xf6, 0xc0, 0xee, 0xcb, 0xae, 0xec, + 0x0d, 0x86, 0xfd, 0x21, 0x6b, 0xec, 0xf7, 0x1c, 0x5d, 0xb1, 0xba, 0x72, 0x4f, 0xd7, 0x6c, 0xdc, + 0xa5, 0x73, 0x77, 0x95, 0xa1, 0x8a, 0x07, 0xca, 0xd0, 0xed, 0x61, 0x4f, 0x57, 0x33, 0x41, 0xe8, + 0x0d, 0x87, 0x72, 0x4f, 0xd5, 0x74, 0xbd, 0xa7, 0x5b, 0x43, 0xb6, 0x46, 0x9e, 0x26, 0xe3, 0xae, + 0x3e, 0xd0, 0xf5, 0x7e, 0x5f, 0x51, 0x65, 0xd5, 0xa2, 0xf4, 0x94, 0x7b, 0x96, 0x25, 0xf7, 0xe5, + 0xae, 0x6a, 0xdb, 0xae, 0x62, 0xd3, 0xd7, 0x95, 0xa1, 0xa5, 0x39, 0x8a, 0xd2, 0xb3, 0x07, 0xae, + 0xea, 0xca, 0x0e, 0x6b, 0xc4, 0xdd, 0x7e, 0xcf, 0x91, 0x61, 0x4a, 0x8a, 0x65, 0xeb, 0x5d, 0x46, + 0x79, 0x6d, 0xd0, 0xef, 0x6b, 0x8e, 0xeb, 0x0d, 0x30, 0xb6, 0x87, 0x54, 0x60, 0xbb, 0x9a, 0x2d, + 0xdb, 0x8e, 0xad, 0x63, 0x65, 0x68, 0x6b, 0x03, 0x46, 0xa5, 0xee, 0x50, 0x71, 0xe0, 0xf7, 0xc5, + 0x1d, 0xdd, 0x19, 0xea, 0x56, 0x8f, 0xbe, 0xae, 0x61, 0x77, 0x60, 0x59, 0x9a, 0x85, 0xbb, 0x9a, + 0x32, 0xb0, 0x1c, 0x4a, 0x25, 0xdd, 0x1e, 0x3a, 0x8e, 0xa5, 0x79, 0xfd, 0x7e, 0xaf, 0x8b, 0xbb, + 0x7d, 0xda, 0xb3, 0x37, 0x50, 0x71, 0xcf, 0xf3, 0xba, 0x6e, 0xcf, 0x56, 0xed, 0x81, 0x45, 0x1b, + 0xfb, 0xda, 0xc0, 0x1b, 0xa8, 0x18, 0xeb, 0x2e, 0xf6, 0x6c, 0x95, 0xad, 0x7b, 0x7f, 0x60, 0xe9, + 0xbd, 0x6e, 0xcf, 0xd3, 0xba, 0x4a, 0x5f, 0xf5, 0x7a, 0x74, 0xee, 0x03, 0xcd, 0x19, 0xf4, 0x07, + 0x8a, 0x66, 0x29, 0x9e, 0x6c, 0xd9, 0x7d, 0xca, 0x75, 0x03, 0xc7, 0xe9, 0xcb, 0xaa, 0x0c, 0xf4, + 0xd7, 0xba, 0x43, 0x4c, 0x5f, 0x1f, 0xca, 0x36, 0xf6, 0x3c, 0xcf, 0x52, 0xbb, 0xbd, 0xae, 0x82, + 0x55, 0x8a, 0xbc, 0xa5, 0xe9, 0x72, 0xcf, 0xc1, 0xb6, 0x8b, 0x07, 0xaa, 0xed, 0x62, 0x3a, 0x4d, + 0x1b, 0x7b, 0x43, 0xab, 0xeb, 0xf5, 0x6d, 0xd5, 0xe9, 0xf5, 0x87, 0x0a, 0x93, 0xf7, 0x5e, 0x5f, + 0xe9, 0x0f, 0x3c, 0x15, 0x77, 0xfb, 0xaa, 0xde, 0x55, 0xe9, 0x8c, 0x1c, 0x4b, 0xed, 0x77, 0xb1, + 0x83, 0xb1, 0xa5, 0xf6, 0x7a, 0xca, 0xd0, 0x61, 0x0b, 0x37, 0xe8, 0xd9, 0x03, 0xa7, 0xaf, 0x02, + 0x5d, 0x54, 0xb9, 0x4f, 0x95, 0x80, 0xe5, 0x5a, 0x7d, 0xd7, 0xed, 0x39, 0x2e, 0x96, 0xb1, 0xad, + 0x50, 0xae, 0xf3, 0xf4, 0xbe, 0xab, 0x79, 0x7d, 0x0f, 0xe3, 0x1e, 0x76, 0x95, 0xfe, 0x80, 0x49, + 0x87, 0x27, 0xf7, 0xfa, 0x20, 0x2d, 0x4a, 0xbf, 0xe7, 0xd9, 0x74, 0x35, 0x65, 0xab, 0xd7, 0xed, + 0xbb, 0x8e, 0x6e, 0xa9, 0x20, 0x8a, 0x16, 0x65, 0x45, 0x45, 0xe9, 0x7a, 0xc3, 0x81, 0xac, 0x01, + 0xbe, 0xb2, 0x6b, 0x51, 0x98, 0x8a, 0xdd, 0x57, 0x64, 0xbb, 0xab, 0x2b, 0x5d, 0xc5, 0xd1, 0xfa, + 0x0a, 0xc5, 0x53, 0x1d, 0xb8, 0x76, 0xbf, 0xef, 0xe9, 0x6a, 0x57, 0xd6, 0xfa, 0xee, 0x80, 0xf2, + 0x67, 0x57, 0x75, 0x2c, 0xcb, 0xee, 0xdb, 0x9a, 0xec, 0xf4, 0x55, 0x6d, 0x48, 0x29, 0xdf, 0x75, + 0x86, 0xd8, 0xc6, 0xb2, 0xa5, 0xe8, 0xce, 0xd0, 0xc6, 0x4c, 0xa5, 0x6b, 0x5d, 0xc5, 0xed, 0xf5, + 0x1d, 0x6d, 0xe8, 0xc0, 0x05, 0x9c, 0x1a, 0x6b, 0x74, 0x1c, 0xdd, 0xd5, 0x6c, 0xec, 0xd8, 0x5d, + 0xac, 0xa9, 0x76, 0x8f, 0xe9, 0xf9, 0xbe, 0xa7, 0x0e, 0x87, 0x8e, 0xe7, 0xf4, 0xf4, 0x3e, 0x66, + 0xac, 0xa8, 0x7b, 0x8e, 0xdd, 0xf3, 0x2c, 0xbb, 0x6b, 0xb9, 0x3d, 0xcf, 0x62, 0xcb, 0xd1, 0x73, + 0x34, 0x4d, 0x19, 0x0e, 0x1c, 0xcd, 0xd2, 0xfa, 0xfa, 0x40, 0xe9, 0xb7, 0xae, 0x3b, 0x53, 0x6b, + 0x26, 0x26, 0xe6, 0x98, 0x19, 0x1d, 0x89, 0x24, 0x49, 0xe8, 0x32, 0x32, 0x9d, 0xf0, 0x4a, 0xbe, + 0x46, 0x07, 0xe4, 0x83, 0x72, 0x8d, 0x8e, 0x70, 0xcd, 0x24, 0x1b, 0xc8, 0x12, 0xba, 0x6f, 0x6e, + 0xfe, 0xa5, 0x1a, 0xaf, 0xb0, 0x2a, 0xf1, 0x0a, 0xb3, 0xa7, 0x65, 0xc1, 0x0a, 0x70, 0x17, 0x31, + 0x52, 0x7a, 0x68, 0x47, 0x61, 0x2e, 0xdb, 0xc1, 0xc4, 0xfc, 0x7c, 0x25, 0x5f, 0x3f, 0xb0, 0xe0, + 0xc4, 0x41, 0x60, 0x7e, 0xbe, 0x52, 0xf2, 0xaf, 0x87, 0xf0, 0x54, 0x2d, 0xbe, 0xc2, 0xd3, 0x6e, + 0xfe, 0xf5, 0x08, 0x9e, 0x6a, 0xc5, 0x57, 0x78, 0xaa, 0xe7, 0x5f, 0x5f, 0xc1, 0xd3, 0x5e, 0xf1, + 0x15, 0x9e, 0xf6, 0xf3, 0xaf, 0xc7, 0xf0, 0x74, 0x50, 0x7c, 0x85, 0xa7, 0xc3, 0xfc, 0xeb, 0x09, + 0x3c, 0x55, 0x0a, 0xb4, 0x4e, 0x08, 0x5a, 0x05, 0x5e, 0xaf, 0xc9, 0xf3, 0x02, 0xb1, 0xd7, 0xe4, + 0x79, 0x81, 0xd9, 0x1b, 0xf2, 0xbc, 0x40, 0xed, 0x0d, 0x79, 0x0e, 0xb8, 0xad, 0x89, 0x3b, 0x44, + 0x4c, 0xd9, 0x83, 0x89, 0x81, 0xd1, 0x41, 0x60, 0xa4, 0xe8, 0x70, 0x62, 0x84, 0xe8, 0x30, 0x30, + 0x22, 0x74, 0x34, 0x31, 0x62, 0x74, 0x14, 0x18, 0x3e, 0x7a, 0x35, 0x31, 0x5c, 0xf4, 0x2a, 0x30, + 0x1c, 0x74, 0x3c, 0x31, 0x26, 0xe8, 0x38, 0x30, 0x02, 0x74, 0x32, 0x31, 0xe6, 0xe8, 0x24, 0x30, + 0x3c, 0xf4, 0x7a, 0x62, 0x4c, 0xd1, 0xeb, 0xc0, 0x58, 0xa2, 0x37, 0x13, 0xc3, 0x46, 0x6f, 0x02, + 0xe3, 0xbc, 0xe4, 0x23, 0x5d, 0xe5, 0x96, 0x0d, 0xf2, 0x91, 0x8b, 0x1c, 0x34, 0x41, 0x01, 0x9a, + 0x23, 0x0f, 0x4d, 0xd1, 0x12, 0xd9, 0xe8, 0xfc, 0x7a, 0x4d, 0xc2, 0x17, 0xdb, 0x3b, 0x49, 0xab, + 0x6c, 0x89, 0x30, 0xb7, 0x3e, 0x29, 0xb7, 0x38, 0x21, 0xb7, 0x32, 0x11, 0xb7, 0x2c, 0x31, 0xb7, + 0x26, 0x3e, 0xb7, 0x20, 0x2e, 0xb7, 0x1a, 0x0e, 0xb7, 0x14, 0x13, 0x6e, 0x1d, 0x02, 0x6e, 0x11, + 0xe6, 0xdc, 0x02, 0x78, 0x1c, 0xf1, 0xa7, 0x1c, 0xe1, 0x97, 0x1c, 0xd1, 0x6d, 0x8e, 0xe0, 0xe7, + 0x0f, 0xf2, 0x3a, 0x0b, 0x08, 0x80, 0xe5, 0x9a, 0x27, 0xd2, 0x6e, 0x4c, 0x79, 0x74, 0xb3, 0xaf, + 0xf4, 0x46, 0x37, 0x7b, 0x7b, 0x28, 0xdd, 0x33, 0x35, 0xe9, 0x08, 0x5f, 0xdd, 0x5c, 0x9b, 0x24, + 0x0a, 0xcc, 0xdc, 0xeb, 0x14, 0xd8, 0xbd, 0xd6, 0x08, 0x7d, 0x47, 0x05, 0x18, 0x00, 0xb1, 0x3f, + 0x90, 0x01, 0x0e, 0xf5, 0x28, 0xbe, 0x99, 0x00, 0xa9, 0x4d, 0x16, 0x1a, 0xdd, 0x9a, 0xf7, 0xc5, + 0x97, 0x57, 0xe6, 0x02, 0x8b, 0xdf, 0xd0, 0x2d, 0x52, 0xa4, 0x7f, 0xb0, 0x4f, 0x03, 0xe9, 0x1f, + 0xbf, 0xa5, 0xe4, 0x53, 0x5f, 0x42, 0x27, 0xe6, 0x65, 0xfe, 0xfc, 0x32, 0x7f, 0xfe, 0x25, 0x7f, + 0x7e, 0x46, 0x21, 0x13, 0x8e, 0x3b, 0xa6, 0x80, 0xc9, 0xe7, 0x05, 0xc0, 0x3d, 0x43, 0xc7, 0x48, + 0x19, 0x4a, 0xff, 0xf8, 0x4a, 0x3f, 0xf6, 0x14, 0x02, 0x99, 0x7c, 0x94, 0xd0, 0x3b, 0x80, 0x9c, + 0xf5, 0xf8, 0x54, 0xf4, 0xf8, 0x92, 0xf7, 0x38, 0x35, 0x93, 0x50, 0x3c, 0x41, 0xef, 0xc8, 0x8c, + 0xdb, 0xfd, 0x6b, 0xfa, 0x57, 0xe9, 0x5d, 0x4b, 0xe8, 0xd2, 0x0c, 0x43, 0xf1, 0x14, 0xbd, 0x42, + 0x0b, 0x74, 0xc4, 0x1e, 0x1e, 0x65, 0x0f, 0x47, 0x94, 0x6a, 0x97, 0x0f, 0x32, 0x23, 0xd5, 0xe9, + 0x83, 0xbc, 0x66, 0x7c, 0x1d, 0x02, 0x5f, 0x47, 0xc0, 0xd7, 0x31, 0xf0, 0xb5, 0x0f, 0x7c, 0xed, + 0x02, 0x5f, 0x3b, 0xc0, 0xd7, 0x13, 0xe0, 0xeb, 0x00, 0xf8, 0x7a, 0x0e, 0x7c, 0xed, 0x01, 0x5f, + 0x4f, 0x81, 0xaf, 0x97, 0xc0, 0xd7, 0x36, 0xf0, 0xf5, 0x39, 0xf0, 0xf5, 0x1d, 0xf0, 0xf5, 0x21, + 0xe3, 0xeb, 0xf2, 0xea, 0x95, 0xa9, 0xbe, 0xc0, 0x22, 0xb0, 0xad, 0xa2, 0x11, 0xe2, 0x92, 0x8f, + 0x03, 0x42, 0x0e, 0xf8, 0xa8, 0x29, 0x12, 0xba, 0x05, 0x22, 0x64, 0x5d, 0x2e, 0x8b, 0x2e, 0x9f, + 0x8a, 0x2e, 0xaf, 0xcc, 0xf9, 0xee, 0xf4, 0x1f, 0xff, 0x7d, 0xbe, 0x6b, 0xa3, 0x13, 0xd3, 0xdb, + 0x5d, 0xfe, 0xe3, 0xbf, 0x7b, 0xbb, 0xe7, 0xe8, 0xcc, 0x8c, 0x42, 0xf1, 0x10, 0xdd, 0xa2, 0x13, + 0x74, 0x10, 0x5d, 0xdd, 0x50, 0xda, 0x5c, 0x4b, 0xe8, 0xd8, 0x8c, 0x43, 0xf1, 0x0c, 0xdd, 0xa1, + 0x6f, 0xe8, 0x15, 0xba, 0x24, 0x4f, 0x8e, 0xe8, 0x93, 0x85, 0x79, 0xf6, 0x20, 0xa3, 0x77, 0x80, + 0x13, 0x88, 0x96, 0x4a, 0x11, 0x81, 0x8f, 0x5d, 0xad, 0xf8, 0x38, 0x04, 0xb2, 0x5f, 0x16, 0x5d, + 0x3e, 0x15, 0x5d, 0x3e, 0x15, 0x5d, 0x2e, 0xcd, 0x70, 0x37, 0xfe, 0x47, 0xb8, 0xeb, 0xfe, 0x23, + 0xde, 0x75, 0xd1, 0x81, 0x19, 0xed, 0xfa, 0xff, 0x88, 0x76, 0x9d, 0x7f, 0xf8, 0xbb, 0xce, 0xe8, + 0x8e, 0x30, 0xfb, 0x21, 0xb0, 0x39, 0xb2, 0x89, 0x40, 0x9c, 0x13, 0x51, 0x98, 0x12, 0xa1, 0x59, + 0x12, 0x71, 0x59, 0x01, 0x85, 0x03, 0xc3, 0x5b, 0x9b, 0x2e, 0x16, 0x41, 0xc6, 0x40, 0xb6, 0x8e, + 0x81, 0x6d, 0x1e, 0x64, 0x09, 0x51, 0x71, 0xa4, 0x82, 0xe8, 0x12, 0x91, 0x75, 0x88, 0xb0, 0xc6, + 0x44, 0xac, 0x7d, 0x10, 0x68, 0x12, 0x1f, 0xfa, 0x68, 0xe2, 0x50, 0x5c, 0xa0, 0x53, 0x74, 0x20, + 0x8d, 0x42, 0x33, 0x0d, 0xc5, 0x8f, 0xe8, 0x18, 0xbd, 0x43, 0x97, 0xe0, 0xba, 0x7f, 0x7c, 0x90, + 0xd7, 0xe2, 0x0a, 0x16, 0x3c, 0x80, 0xc0, 0xac, 0xcb, 0x42, 0x81, 0x07, 0x93, 0x42, 0x61, 0x3c, + 0xc8, 0x08, 0xe0, 0x45, 0x0f, 0x50, 0x2a, 0xb2, 0x02, 0x8e, 0x08, 0x20, 0x8a, 0x98, 0x75, 0x3d, + 0x9c, 0x14, 0x3a, 0x04, 0x06, 0x87, 0xa1, 0x01, 0xbb, 0x15, 0x70, 0x4c, 0x60, 0x38, 0x45, 0xcf, + 0xa3, 0x49, 0xa1, 0x55, 0x00, 0x65, 0x40, 0x98, 0xf6, 0x44, 0x41, 0xd1, 0xeb, 0xd5, 0xa4, 0xd0, + 0x31, 0x0f, 0x32, 0x62, 0xb3, 0x96, 0xca, 0xb4, 0x60, 0x7a, 0xa7, 0xd0, 0x3a, 0x0f, 0x32, 0x02, + 0xb2, 0x79, 0xac, 0xe7, 0x14, 0x05, 0xc6, 0xb2, 0xe8, 0x79, 0x32, 0x29, 0xf4, 0x10, 0x90, 0x18, + 0x08, 0xcc, 0x7a, 0xda, 0x88, 0xa8, 0xde, 0xac, 0xe7, 0xeb, 0x49, 0xa1, 0x99, 0x60, 0x61, 0x60, + 0x59, 0x58, 0xcf, 0x3b, 0x44, 0x98, 0x39, 0xeb, 0xf9, 0x66, 0x52, 0xe8, 0xaa, 0x07, 0x19, 0xdd, + 0xc1, 0x62, 0x3e, 0x64, 0x41, 0x60, 0x12, 0xa5, 0xda, 0xac, 0x98, 0xd1, 0x1d, 0x3a, 0x94, 0xd6, + 0x7c, 0x00, 0x78, 0xf5, 0x33, 0x16, 0x89, 0x67, 0x2a, 0xad, 0xf3, 0x98, 0xdd, 0xaa, 0x1c, 0x98, + 0xe5, 0x40, 0xcb, 0x68, 0xeb, 0x7f, 0x10, 0xfb, 0x7a, 0x85, 0xcd, 0xef, 0x09, 0x71, 0x6d, 0x61, + 0xcf, 0xff, 0x25, 0x2d, 0x85, 0x92, 0x1c, 0x5a, 0xbe, 0xd1, 0x6a, 0x55, 0xb3, 0xab, 0x76, 0x14, + 0x01, 0x3e, 0xad, 0x2c, 0xf2, 0x83, 0x77, 0x77, 0x7f, 0x6f, 0xfd, 0xbc, 0xc2, 0xeb, 0xd6, 0xef, + 0xb5, 0x64, 0x57, 0xba, 0xd7, 0xca, 0x0b, 0x48, 0xd8, 0x7b, 0x34, 0xf9, 0x4b, 0xeb, 0xbd, 0x8a, + 0x8c, 0x7a, 0x16, 0x0b, 0xe7, 0x72, 0xa4, 0x9f, 0x59, 0x28, 0x87, 0xa0, 0x40, 0x63, 0x98, 0xa4, + 0xf4, 0x05, 0x45, 0x66, 0xf2, 0x32, 0x8b, 0x36, 0xc5, 0x26, 0xde, 0xc9, 0xd2, 0xd1, 0x10, 0x93, + 0xdd, 0x09, 0x1f, 0x1e, 0xe2, 0xdd, 0xdd, 0x68, 0xc7, 0x34, 0x71, 0x96, 0xeb, 0x4e, 0x29, 0x82, + 0xe9, 0xba, 0x25, 0xfc, 0x0e, 0x42, 0xf0, 0xf2, 0x77, 0x2e, 0x93, 0x0e, 0x88, 0xff, 0x6e, 0xb4, + 0x5a, 0x24, 0xcb, 0xf3, 0x3b, 0x0b, 0x2c, 0xfe, 0xbc, 0x8a, 0xd6, 0xbf, 0x1b, 0xbf, 0x13, 0x24, + 0x7f, 0x5e, 0x65, 0x48, 0xae, 0xeb, 0xf3, 0xf3, 0xb9, 0xf9, 0x71, 0xf5, 0x41, 0x7b, 0x6e, 0x56, + 0x20, 0xd3, 0xda, 0x73, 0x9a, 0xe6, 0xe6, 0x85, 0xff, 0xee, 0x8a, 0x84, 0x6c, 0x0c, 0xa8, 0x54, + 0x6a, 0xbd, 0xfc, 0x9a, 0x1a, 0xcc, 0xfc, 0x6b, 0xc9, 0xf7, 0xe5, 0x62, 0x22, 0x97, 0xcf, 0x5a, + 0x7b, 0xa1, 0x78, 0x58, 0xc9, 0x6a, 0x27, 0x7c, 0xe5, 0x14, 0xc9, 0x5b, 0xd3, 0x4e, 0xd5, 0x1c, + 0x63, 0x22, 0x75, 0xd8, 0x9d, 0xd6, 0xa2, 0xc4, 0xbf, 0xff, 0x29, 0xa5, 0x55, 0x35, 0x0c, 0x02, + 0xd4, 0x5e, 0x6c, 0x48, 0x17, 0xe2, 0xe7, 0x2c, 0x61, 0xc8, 0xd1, 0xa5, 0xfc, 0x32, 0x83, 0x55, + 0x0c, 0xc4, 0x95, 0xce, 0xb0, 0x58, 0x15, 0xe5, 0x8c, 0x51, 0x41, 0x4a, 0x6c, 0x72, 0xa4, 0x8c, + 0x97, 0xab, 0xd0, 0x84, 0xa1, 0xa4, 0xb5, 0x63, 0xa5, 0xce, 0x44, 0x8c, 0xc1, 0xde, 0x29, 0xd3, + 0x37, 0xd9, 0x6b, 0xe5, 0xc9, 0x57, 0x8e, 0xd4, 0x51, 0xcc, 0xad, 0x28, 0x12, 0x1c, 0x6b, 0x9e, + 0x60, 0x43, 0x68, 0x41, 0x45, 0x02, 0x0e, 0x12, 0x2c, 0xf8, 0x9e, 0x18, 0x40, 0x7a, 0x4b, 0x0a, + 0xcd, 0x2a, 0x69, 0xb0, 0x34, 0x22, 0x5d, 0xfe, 0x95, 0x91, 0x5a, 0x59, 0xd2, 0x32, 0xcc, 0x12, + 0x5f, 0xc5, 0xd4, 0x52, 0xd3, 0x6c, 0x85, 0x24, 0x22, 0xdb, 0xa2, 0x2c, 0x5e, 0x2f, 0x4b, 0x82, + 0x21, 0xf8, 0x32, 0x91, 0x74, 0xaf, 0x55, 0x63, 0x9a, 0xa8, 0x28, 0x7b, 0x28, 0xe8, 0x39, 0x09, + 0x29, 0xe5, 0xb9, 0xaa, 0x27, 0x90, 0xa1, 0x2c, 0xc1, 0x41, 0x5f, 0xd8, 0x51, 0x46, 0x59, 0x09, + 0xd0, 0x96, 0x8a, 0x85, 0xf4, 0x81, 0x54, 0x16, 0xfc, 0x03, 0x43, 0x79, 0x41, 0x16, 0x7a, 0x37, + 0x4d, 0x53, 0xe6, 0x64, 0x9b, 0x67, 0xc2, 0x3a, 0x67, 0x15, 0x1d, 0xdf, 0x47, 0xd9, 0x3a, 0xb3, + 0xce, 0x3f, 0xa7, 0xa4, 0x44, 0xef, 0x67, 0x58, 0x53, 0xf2, 0x27, 0x95, 0x76, 0x77, 0xf1, 0xbe, + 0x99, 0x40, 0x29, 0x10, 0x57, 0xad, 0xf0, 0x2b, 0x2e, 0xe5, 0x91, 0x77, 0xde, 0x47, 0x2c, 0x27, + 0x5c, 0x97, 0xaf, 0x5c, 0x82, 0x17, 0x16, 0xfc, 0x68, 0x4f, 0x6b, 0x2f, 0xd9, 0x6b, 0x19, 0x8c, + 0x76, 0xfb, 0xa6, 0x10, 0x0a, 0xfb, 0x42, 0x6b, 0x2f, 0x2c, 0x24, 0x1a, 0x73, 0xf8, 0x05, 0x61, + 0x5e, 0x14, 0x41, 0x48, 0x02, 0xc5, 0x1c, 0xc9, 0xf8, 0x6b, 0x3a, 0x4a, 0xc6, 0x63, 0xf3, 0x75, + 0x0a, 0xc5, 0x1a, 0x8a, 0xd4, 0x50, 0x14, 0x35, 0x0f, 0x9b, 0x6b, 0x47, 0xb8, 0x6c, 0x7d, 0x73, + 0x41, 0x61, 0x91, 0xdf, 0xe2, 0xb0, 0x98, 0x65, 0xaa, 0x72, 0xb5, 0xa6, 0xb3, 0x4d, 0x1e, 0x1e, + 0x38, 0xcd, 0xc2, 0xea, 0x29, 0x1f, 0x9d, 0x39, 0xbd, 0xee, 0x25, 0x11, 0xb2, 0xfe, 0xc5, 0x66, + 0x10, 0x8a, 0x64, 0x9f, 0xca, 0x72, 0xae, 0xc9, 0x55, 0x74, 0x4d, 0xca, 0x82, 0x76, 0x77, 0xb9, + 0x6a, 0x20, 0x3a, 0x9b, 0x11, 0xcd, 0xb6, 0xb2, 0xe1, 0x5d, 0x92, 0x85, 0xdb, 0x31, 0xcd, 0x98, + 0x16, 0x0e, 0x85, 0xf3, 0x20, 0xa8, 0xe1, 0xf1, 0xfb, 0xcc, 0x8a, 0xad, 0xa9, 0xd0, 0x02, 0xb5, + 0xdb, 0x12, 0x7c, 0x28, 0xd7, 0x24, 0x08, 0x19, 0x45, 0xf5, 0xe1, 0xcf, 0xab, 0x78, 0x4d, 0xe9, + 0xff, 0xf3, 0xca, 0x59, 0xff, 0x2e, 0xad, 0x59, 0x19, 0x2b, 0x0e, 0xd3, 0xd8, 0xc7, 0x89, 0x88, + 0xa5, 0x8e, 0x17, 0xc5, 0xc7, 0x96, 0x33, 0x11, 0xc5, 0xab, 0x08, 0xc5, 0xd7, 0xb0, 0xa9, 0x11, + 0xa4, 0x77, 0x14, 0x49, 0x42, 0x95, 0xde, 0xe9, 0xe6, 0xde, 0x32, 0xaf, 0x8e, 0x3e, 0xa4, 0x5c, + 0xc9, 0x0b, 0xbe, 0x13, 0x3e, 0x61, 0xeb, 0xf6, 0x57, 0x6b, 0xc6, 0xd6, 0x53, 0x4c, 0xa1, 0x2a, + 0x13, 0xc2, 0xdc, 0x2c, 0xd5, 0x40, 0xfc, 0x08, 0xc8, 0x6c, 0xf8, 0x9e, 0x18, 0xed, 0x54, 0xe8, + 0x22, 0x44, 0x23, 0x56, 0x75, 0x93, 0xbd, 0x57, 0xa4, 0xba, 0x60, 0xbf, 0x4e, 0x21, 0xc3, 0x19, + 0xd3, 0xec, 0xc3, 0xd7, 0x14, 0xbd, 0x4e, 0xd1, 0xcf, 0x29, 0xfa, 0x8e, 0xd1, 0xf7, 0x14, 0x1d, + 0xe0, 0x72, 0xf5, 0x00, 0xf9, 0xe7, 0x6b, 0x9e, 0x6c, 0x90, 0x25, 0xf4, 0x3a, 0xff, 0xa2, 0x48, + 0xa3, 0x9f, 0x53, 0x33, 0x31, 0xc7, 0x1c, 0x53, 0xd9, 0xfe, 0x8d, 0x1f, 0x42, 0x3d, 0xed, 0xd7, + 0x74, 0xdf, 0x4c, 0x46, 0xdf, 0x31, 0x3c, 0x17, 0x5f, 0xa7, 0xfb, 0xfb, 0x45, 0x8c, 0xa0, 0xfd, + 0x3a, 0x1d, 0x7d, 0x4f, 0x49, 0xd9, 0x4d, 0x4d, 0x43, 0xb6, 0x42, 0x28, 0xb3, 0x86, 0x23, 0x1e, + 0x53, 0xf8, 0xd9, 0x26, 0xa8, 0x4d, 0xe1, 0x2d, 0x85, 0x3f, 0xa9, 0xe6, 0x60, 0x79, 0xa0, 0x67, + 0x38, 0x97, 0xf9, 0xb1, 0xf9, 0xc7, 0xcb, 0xd4, 0xc0, 0x7b, 0x9c, 0x58, 0x86, 0xb8, 0xa4, 0xb7, + 0x4d, 0x6a, 0xf3, 0x8f, 0x70, 0xbb, 0x2d, 0x8c, 0xff, 0x18, 0x49, 0xe1, 0x73, 0x33, 0x44, 0xe1, + 0x33, 0x33, 0x6d, 0xd0, 0x50, 0x33, 0x4e, 0x43, 0x99, 0xa6, 0xf9, 0x47, 0x9d, 0x9d, 0x7d, 0xb8, + 0x7d, 0x2a, 0xe5, 0xb8, 0x06, 0x4a, 0xcc, 0xbe, 0xc3, 0x9d, 0xb4, 0x4c, 0x6b, 0xd2, 0x32, 0xd2, + 0xfd, 0x27, 0xbd, 0x9b, 0x57, 0xe8, 0x4e, 0x23, 0x77, 0x1e, 0xcc, 0x93, 0x42, 0xfa, 0x99, 0x0e, + 0xa4, 0xd3, 0x46, 0x50, 0x51, 0x11, 0x99, 0x7f, 0xa0, 0xd8, 0xfc, 0x80, 0x7c, 0xf3, 0x03, 0x72, + 0xcd, 0x3f, 0xe8, 0x9c, 0xd2, 0x1d, 0xd3, 0xfc, 0x83, 0x95, 0x29, 0x4c, 0xcc, 0xf0, 0x45, 0x8a, + 0x02, 0x33, 0x7c, 0x96, 0xa2, 0xb9, 0x19, 0xb5, 0xfd, 0xe7, 0x13, 0xe4, 0x99, 0x71, 0xdb, 0x7d, + 0x3e, 0x19, 0x91, 0x0a, 0x0c, 0x33, 0x40, 0x91, 0xe9, 0xa3, 0x18, 0xea, 0x08, 0xcc, 0x39, 0x72, + 0x4d, 0x6f, 0xed, 0x7b, 0x62, 0xb8, 0x63, 0x9a, 0x1f, 0x36, 0xe3, 0xea, 0x46, 0x18, 0x8e, 0x37, + 0xa6, 0x02, 0xbe, 0x87, 0x8b, 0x64, 0x72, 0x86, 0xfa, 0x53, 0x8c, 0x10, 0xaf, 0xa4, 0xfe, 0x48, + 0x33, 0xa2, 0x13, 0xdd, 0xd0, 0xc1, 0x7f, 0x06, 0x62, 0xd2, 0x49, 0xfe, 0x8c, 0x49, 0x05, 0x47, + 0x83, 0x46, 0x3c, 0xb2, 0x42, 0x00, 0xeb, 0xf9, 0xa1, 0x2b, 0x24, 0x7f, 0xce, 0xe1, 0x8c, 0x65, + 0x0c, 0x85, 0xee, 0x1c, 0xcc, 0xf3, 0x90, 0x5f, 0x75, 0x31, 0xe9, 0x9c, 0x9d, 0xbf, 0x3a, 0x3e, + 0xdf, 0xfb, 0x20, 0xbd, 0xb8, 0x0b, 0x51, 0x68, 0x42, 0x8d, 0xc3, 0x1d, 0x71, 0xc9, 0x33, 0xa4, + 0x08, 0x12, 0x21, 0xa1, 0x58, 0x01, 0xe5, 0x6d, 0xd4, 0x04, 0xa5, 0x7d, 0x13, 0x4a, 0x2f, 0x8e, + 0x28, 0x98, 0xe9, 0x3c, 0x10, 0x31, 0x7a, 0x8f, 0x89, 0xd9, 0x47, 0x80, 0x86, 0x28, 0x85, 0x3a, + 0x9e, 0xec, 0x51, 0x04, 0x95, 0x05, 0xf4, 0x0b, 0xfd, 0x37, 0xa6, 0xbd, 0xa1, 0x8a, 0x27, 0x6b, + 0x48, 0xa0, 0x60, 0x41, 0xf4, 0x51, 0xd2, 0x39, 0x3b, 0x3d, 0x96, 0xca, 0x28, 0xb9, 0x80, 0x92, + 0x5b, 0xa0, 0x74, 0x1b, 0x15, 0x32, 0xbf, 0x24, 0xf6, 0x66, 0x6a, 0x1e, 0x83, 0xb6, 0x46, 0xa1, + 0x09, 0xd1, 0x14, 0xdc, 0x09, 0xf1, 0x8d, 0x88, 0x29, 0x24, 0x14, 0x91, 0xb6, 0x10, 0x10, 0x2a, + 0x1e, 0x86, 0x12, 0xe0, 0x24, 0x26, 0x7b, 0xdf, 0x22, 0xe9, 0xc5, 0x7d, 0x98, 0xa9, 0x0b, 0x17, + 0x39, 0x99, 0xae, 0x98, 0x98, 0x2e, 0x99, 0x0b, 0xd4, 0x9b, 0xa0, 0xc0, 0x74, 0x09, 0x9e, 0x13, + 0x80, 0x33, 0xcf, 0xbf, 0x44, 0x12, 0xf2, 0xf2, 0x2f, 0xb1, 0x84, 0xa6, 0xa6, 0x4b, 0x56, 0xce, + 0x25, 0x2b, 0x17, 0x48, 0xc8, 0x91, 0xd0, 0xb2, 0xd4, 0x36, 0x87, 0xb6, 0x11, 0xc0, 0x76, 0xa6, + 0xd1, 0x42, 0x04, 0x87, 0x62, 0x4a, 0xc1, 0x93, 0xef, 0x1e, 0x9a, 0xa3, 0x25, 0xe5, 0x5e, 0xbb, + 0x01, 0xd6, 0x39, 0xff, 0x9e, 0xcd, 0x13, 0xc9, 0x45, 0xe7, 0xa4, 0x03, 0x97, 0xff, 0x3d, 0xce, + 0x0c, 0xd8, 0x64, 0x7f, 0x19, 0x36, 0x14, 0x5a, 0xfe, 0x19, 0xa7, 0x82, 0x4f, 0x99, 0x93, 0x15, + 0xb4, 0xd1, 0x0b, 0x6f, 0xc8, 0xad, 0x38, 0xe4, 0x14, 0x56, 0x2b, 0x2f, 0x91, 0x6d, 0x7f, 0x40, + 0x99, 0x45, 0x31, 0xc2, 0xcf, 0xde, 0x43, 0xb1, 0xfd, 0x1f, 0x23, 0x09, 0xbf, 0x30, 0xdf, 0x63, + 0x94, 0xee, 0xed, 0xb1, 0xfa, 0x85, 0xf7, 0x20, 0x66, 0x64, 0x41, 0x68, 0xcf, 0x29, 0x28, 0xec, + 0x50, 0x32, 0x4d, 0x53, 0x19, 0x49, 0x20, 0x2b, 0x7b, 0x7b, 0x63, 0x05, 0x77, 0x9f, 0xcc, 0xcc, + 0x86, 0x30, 0x8b, 0x23, 0xdb, 0xb2, 0xe1, 0x3e, 0xd0, 0x28, 0x6c, 0xc3, 0x59, 0x13, 0x2c, 0xbc, + 0xa7, 0x2a, 0x02, 0xac, 0x15, 0x25, 0xd3, 0xdb, 0xe7, 0x21, 0x53, 0xdc, 0x11, 0x63, 0x3f, 0x4c, + 0x56, 0x17, 0x03, 0xaf, 0xbf, 0xcf, 0x95, 0x5d, 0x46, 0x19, 0xd1, 0x41, 0x13, 0x42, 0x18, 0xa7, + 0xe3, 0x27, 0xb2, 0x38, 0x91, 0x32, 0x30, 0xc4, 0x90, 0x9b, 0xd2, 0xe7, 0x3b, 0x00, 0xfe, 0xe9, + 0x52, 0x47, 0xc6, 0x0f, 0x4c, 0x50, 0x1d, 0x0e, 0xe1, 0x07, 0x07, 0xb8, 0x0f, 0x78, 0xc2, 0x33, + 0x1d, 0x82, 0xd4, 0x04, 0x90, 0x9a, 0xe6, 0x5f, 0x7c, 0x46, 0xa3, 0x1d, 0x87, 0xac, 0xb2, 0x87, + 0xc8, 0x0b, 0xd2, 0x88, 0x43, 0xcc, 0xcb, 0x11, 0x73, 0x3a, 0x5f, 0x8f, 0xcf, 0xcf, 0xc8, 0x18, + 0x4b, 0x53, 0x41, 0xb6, 0xe9, 0x10, 0xa6, 0xf0, 0xca, 0x30, 0xec, 0x1c, 0x86, 0xef, 0x89, 0xcb, + 0xbd, 0xbd, 0xbc, 0x9f, 0x0d, 0x5c, 0x68, 0x9a, 0xc1, 0x8f, 0xce, 0xe7, 0xdc, 0xfc, 0x90, 0xef, + 0x3f, 0x41, 0x7b, 0xd9, 0x56, 0x24, 0x74, 0xc7, 0x26, 0x30, 0x47, 0xe7, 0xd2, 0x28, 0x30, 0x97, + 0x64, 0xbe, 0x30, 0xc6, 0x1d, 0x9d, 0x29, 0x4c, 0xdd, 0x43, 0x73, 0x3a, 0x53, 0xf8, 0x32, 0x45, + 0x77, 0xb9, 0x77, 0x35, 0xe5, 0xb8, 0xf3, 0x2c, 0xe2, 0x4f, 0x7f, 0x3c, 0xbb, 0x0b, 0x4d, 0xd3, + 0x5c, 0x86, 0x2f, 0xcf, 0x43, 0x23, 0x79, 0x76, 0x04, 0x5f, 0x6e, 0xc2, 0x97, 0x6f, 0x23, 0x23, + 0x79, 0x76, 0x0f, 0x5f, 0xde, 0x45, 0x2f, 0x89, 0xd0, 0x1b, 0x84, 0xa9, 0x0b, 0x28, 0x76, 0x61, + 0xdb, 0x99, 0x2b, 0xa2, 0x98, 0x8c, 0x6c, 0x2b, 0x45, 0xbf, 0x1e, 0x5c, 0xfc, 0x52, 0x7c, 0x3b, + 0xfc, 0x72, 0x79, 0x7c, 0x61, 0x64, 0xb6, 0x39, 0x3a, 0x7c, 0x7b, 0x59, 0x7c, 0x5b, 0xa3, 0xd4, + 0x7c, 0x15, 0x75, 0xe8, 0x0f, 0xdd, 0x88, 0x22, 0xcb, 0x60, 0x93, 0xa2, 0x66, 0xae, 0xe8, 0x32, + 0x24, 0x27, 0x6c, 0x18, 0xc6, 0xc4, 0x9c, 0x4b, 0x4b, 0x05, 0xc3, 0xbf, 0x46, 0x9c, 0x0a, 0x4f, + 0xf7, 0x9b, 0x37, 0x30, 0x62, 0xc4, 0xe1, 0xfb, 0x59, 0x14, 0xe2, 0x30, 0x45, 0x42, 0x88, 0x6f, + 0x2c, 0xd8, 0xc1, 0x12, 0x61, 0x1e, 0xb2, 0xc3, 0x8a, 0xd9, 0x51, 0x8a, 0x94, 0x6c, 0xa0, 0x79, + 0xe9, 0xe4, 0xd9, 0xe9, 0x71, 0xd6, 0xfa, 0x21, 0x6b, 0xc5, 0x4c, 0xee, 0xc8, 0x53, 0x14, 0x99, + 0x98, 0xed, 0x6a, 0xb0, 0x4d, 0xa7, 0xbb, 0x1f, 0x76, 0x77, 0xc5, 0x4c, 0x3d, 0xc3, 0x94, 0xa8, + 0x7a, 0x86, 0xb5, 0x8a, 0x24, 0x94, 0x8e, 0xc7, 0xe6, 0x87, 0x86, 0x1d, 0xfc, 0x34, 0x33, 0x53, + 0xb3, 0xb2, 0x11, 0x5a, 0x2b, 0xc2, 0x8a, 0x09, 0x33, 0x57, 0x83, 0x1e, 0x76, 0x48, 0x5f, 0x26, + 0x84, 0x2f, 0xd9, 0xd9, 0x1e, 0x80, 0x8f, 0x73, 0x22, 0x92, 0x80, 0x09, 0xd4, 0x30, 0x10, 0x56, + 0x76, 0xa5, 0x97, 0xbe, 0x21, 0x86, 0x57, 0xce, 0xb5, 0x09, 0x2a, 0x1e, 0x50, 0xf2, 0x91, 0x2b, + 0x49, 0x4c, 0xdd, 0x93, 0xbd, 0xc2, 0x0f, 0x17, 0x62, 0xc4, 0x59, 0x5c, 0x14, 0xd2, 0x39, 0xdc, + 0xa1, 0xb5, 0x05, 0x5c, 0x06, 0x0c, 0xbe, 0x48, 0x25, 0xd0, 0x71, 0x69, 0x1b, 0x9b, 0x36, 0x6e, + 0x86, 0x6d, 0xa2, 0x20, 0x4a, 0x9b, 0x21, 0xa1, 0x12, 0x88, 0x53, 0xc8, 0x23, 0x97, 0x35, 0xc0, + 0x7c, 0xe9, 0x6e, 0x96, 0xb5, 0xc0, 0x6e, 0x92, 0x6d, 0x5a, 0xb0, 0x77, 0x47, 0xbb, 0xbb, 0x3b, + 0xf1, 0xee, 0xee, 0x8e, 0xbf, 0x79, 0xfd, 0xdf, 0x91, 0xdb, 0xbb, 0x62, 0x2c, 0xb0, 0xdf, 0x5b, + 0x61, 0x27, 0x2f, 0xf3, 0xb9, 0x47, 0x2f, 0x15, 0x23, 0x7e, 0x29, 0x1b, 0x6d, 0xa5, 0xc0, 0xff, + 0x82, 0xe1, 0x5f, 0xc4, 0x52, 0x76, 0x77, 0x4f, 0x52, 0x31, 0x37, 0x75, 0x8a, 0xf6, 0x97, 0xd8, + 0xe0, 0xdc, 0x79, 0x55, 0x2a, 0xaa, 0x7e, 0x48, 0x1d, 0xa6, 0x83, 0xfd, 0x40, 0x4c, 0x5f, 0x0c, + 0xf2, 0x32, 0x9b, 0xf0, 0xd0, 0x4f, 0xe9, 0xa9, 0x13, 0x23, 0x45, 0xe1, 0x61, 0x7e, 0x06, 0xc5, + 0x08, 0x39, 0x71, 0x5d, 0x16, 0x7c, 0x81, 0xc2, 0xcc, 0x87, 0x49, 0x36, 0x99, 0x69, 0x64, 0x96, + 0x64, 0x0b, 0xe1, 0xac, 0x35, 0x42, 0x70, 0x61, 0x2c, 0xc8, 0xc5, 0xf9, 0x29, 0xea, 0x47, 0x83, + 0xdb, 0x02, 0x70, 0xdd, 0x4a, 0x88, 0x20, 0x3f, 0x63, 0x86, 0x77, 0xa8, 0x53, 0x02, 0x63, 0x86, + 0xc0, 0xc1, 0xe9, 0xc3, 0x43, 0xc3, 0x71, 0x1f, 0x87, 0x2a, 0xb3, 0x64, 0x86, 0x1d, 0xdf, 0x5b, + 0x82, 0xab, 0x94, 0x90, 0x2b, 0x27, 0xee, 0x22, 0xc1, 0x8a, 0x6f, 0xe6, 0x60, 0x18, 0x27, 0x4c, + 0xb3, 0x79, 0x20, 0x2b, 0x1d, 0x50, 0x02, 0xbb, 0xbb, 0x62, 0x64, 0xd2, 0x8f, 0x12, 0xf2, 0x08, + 0xf0, 0xdd, 0x5d, 0x31, 0x36, 0xe9, 0x47, 0x09, 0x31, 0x7c, 0x3c, 0x5a, 0x6b, 0x5b, 0x84, 0xd6, + 0xa0, 0x7e, 0xd2, 0xa4, 0xad, 0x5c, 0xa7, 0x69, 0xe4, 0x9e, 0xc4, 0x45, 0x31, 0x3a, 0xd7, 0xd9, + 0x37, 0xcb, 0x4f, 0xc1, 0xf6, 0xf1, 0x3a, 0x16, 0xdc, 0x74, 0x8e, 0x5d, 0x4a, 0xf0, 0x84, 0x46, + 0x2d, 0x38, 0x0a, 0xe4, 0x91, 0x04, 0x31, 0x32, 0xc1, 0x2a, 0x2b, 0xd0, 0xa3, 0x1f, 0x69, 0x39, + 0x1f, 0xb7, 0x80, 0x4e, 0x69, 0x01, 0x27, 0x6b, 0x93, 0xb0, 0x4d, 0xc4, 0x6a, 0x21, 0x55, 0x59, + 0x1b, 0xfc, 0xe8, 0x7a, 0x45, 0x1e, 0x38, 0xd8, 0xf0, 0x26, 0x3d, 0x80, 0x9d, 0x6d, 0x75, 0x68, + 0x9e, 0x1d, 0x53, 0xf4, 0x62, 0x8c, 0xbf, 0x63, 0x91, 0xa9, 0xdf, 0x84, 0x16, 0xab, 0xa6, 0x54, + 0xc3, 0x3a, 0x4c, 0xef, 0x4e, 0xa8, 0x36, 0xfe, 0x8e, 0x45, 0x47, 0x42, 0x44, 0x67, 0xfc, 0x81, + 0xce, 0x4e, 0x8f, 0x8d, 0x0f, 0xa8, 0x4c, 0x01, 0xc3, 0x45, 0xf4, 0x70, 0x81, 0xe1, 0x99, 0xe3, + 0x3f, 0x45, 0x0f, 0x25, 0x12, 0xf2, 0x93, 0xdf, 0x88, 0xa7, 0xe9, 0x41, 0xf9, 0x56, 0xce, 0x20, + 0xde, 0x4e, 0xee, 0x34, 0x3d, 0x32, 0x25, 0x01, 0x53, 0xa7, 0x88, 0x9b, 0x1a, 0x7d, 0xb1, 0x12, + 0xa1, 0xf3, 0x0a, 0x7b, 0x6a, 0xdf, 0xf4, 0x76, 0x77, 0xbd, 0xfd, 0x64, 0x8d, 0xfc, 0x44, 0x86, + 0x81, 0x3d, 0x50, 0xc6, 0x19, 0x26, 0xa7, 0x51, 0x4a, 0x1a, 0x77, 0xe6, 0x6c, 0x9b, 0xde, 0xdd, + 0x85, 0x4f, 0xe4, 0x99, 0xe8, 0x01, 0xc2, 0x67, 0x2e, 0x41, 0x57, 0xf4, 0x76, 0x3f, 0x80, 0xf5, + 0xf3, 0x01, 0x85, 0xf8, 0x86, 0xce, 0xa8, 0x4d, 0xa6, 0x84, 0xff, 0x0c, 0x0c, 0xd1, 0x43, 0x53, + 0x89, 0x42, 0x9e, 0xa2, 0xe4, 0xcf, 0x98, 0xcd, 0xf8, 0x39, 0xe9, 0x60, 0xb9, 0x6e, 0xd6, 0xe1, + 0x4f, 0xd1, 0xdb, 0x9b, 0x42, 0x5b, 0x32, 0xb7, 0xb9, 0xb6, 0x36, 0x69, 0x9b, 0xce, 0x03, 0xae, + 0xed, 0x39, 0x69, 0x9b, 0x45, 0x77, 0x59, 0xdb, 0xaf, 0x11, 0xc9, 0xab, 0x4c, 0x25, 0xe4, 0xfa, + 0x0b, 0xbe, 0xe3, 0x2c, 0x14, 0x29, 0x4c, 0x09, 0x86, 0x3e, 0x25, 0x53, 0x7c, 0xee, 0xc1, 0xb0, + 0xa7, 0x39, 0x62, 0x30, 0xea, 0xdc, 0x2e, 0xbe, 0xb7, 0xa7, 0x30, 0x5c, 0xf1, 0xfd, 0xf9, 0x14, + 0xf9, 0xe1, 0x02, 0x5e, 0x9d, 0x85, 0x74, 0xa5, 0x80, 0x25, 0x8d, 0xf8, 0xe1, 0x41, 0x84, 0xb9, + 0x07, 0x0f, 0x0f, 0x62, 0x60, 0x92, 0x6d, 0x5e, 0x42, 0x01, 0xe0, 0x01, 0x59, 0xee, 0x34, 0x22, + 0xdc, 0x0f, 0x6f, 0xa5, 0x2f, 0xbd, 0x54, 0xf4, 0xd0, 0x44, 0x32, 0x3e, 0xd1, 0xbf, 0xc8, 0xcb, + 0x84, 0x83, 0x8c, 0x01, 0xc7, 0x12, 0xe9, 0x92, 0xbb, 0xd4, 0x2b, 0x72, 0x8b, 0x83, 0x91, 0x5e, + 0xb6, 0x13, 0x3d, 0x3c, 0x64, 0x1f, 0xc7, 0x0d, 0x25, 0xbe, 0x27, 0xb0, 0xfe, 0x9d, 0x02, 0x6c, + 0xc1, 0x01, 0x24, 0xfe, 0x4b, 0x39, 0x3a, 0x63, 0x83, 0x1c, 0x26, 0x33, 0xbf, 0x2b, 0x95, 0xf4, + 0x13, 0x69, 0x64, 0x93, 0x28, 0x80, 0x87, 0xd2, 0x97, 0xb2, 0x61, 0xb3, 0xde, 0xed, 0xfc, 0x35, + 0xe4, 0x99, 0x36, 0x78, 0x84, 0x5e, 0x11, 0x9b, 0xfb, 0x41, 0x94, 0x26, 0xdb, 0x51, 0x5a, 0x9a, + 0xe9, 0xcb, 0x04, 0x8b, 0x9e, 0x64, 0xb8, 0x29, 0xd8, 0x7e, 0x34, 0xba, 0x23, 0x2e, 0xcd, 0x3f, + 0xc5, 0x25, 0x02, 0x2a, 0xef, 0x4c, 0x77, 0x77, 0x77, 0x0a, 0x56, 0x5c, 0x4a, 0x4f, 0x96, 0x8c, + 0x68, 0x9e, 0x92, 0x0b, 0xc4, 0x23, 0x4f, 0x20, 0x57, 0xfb, 0x0b, 0x72, 0x87, 0x6e, 0x90, 0xc5, + 0xa6, 0xb4, 0x5c, 0x23, 0xea, 0xd4, 0x1e, 0x42, 0x94, 0x16, 0x16, 0xf0, 0x94, 0x64, 0xed, 0x24, + 0x04, 0x1e, 0x09, 0x59, 0x31, 0xb4, 0x94, 0xcc, 0xf1, 0xf2, 0xe5, 0xd4, 0xf0, 0xd6, 0xf9, 0x6b, + 0x65, 0x25, 0x31, 0xe7, 0x0f, 0x36, 0x16, 0xc1, 0x82, 0x1d, 0xd8, 0xd6, 0xcf, 0x5c, 0x77, 0x03, + 0xb9, 0x88, 0x17, 0x1d, 0xfe, 0x3d, 0x15, 0x26, 0x70, 0xf1, 0x01, 0xe9, 0xd9, 0xca, 0xf6, 0x3d, + 0x62, 0xd1, 0x90, 0x7d, 0x30, 0x37, 0x95, 0x48, 0x07, 0x31, 0x95, 0x5e, 0xd2, 0xcd, 0x39, 0x95, + 0x8c, 0x94, 0x84, 0x6c, 0xfe, 0x40, 0x1f, 0xd0, 0x7b, 0x8c, 0x96, 0x21, 0xba, 0x0b, 0xd1, 0x4d, + 0x88, 0xbe, 0x45, 0xe8, 0x28, 0x44, 0xef, 0x22, 0x74, 0x1f, 0xa2, 0x29, 0x46, 0xaf, 0x22, 0xf4, + 0xb1, 0x88, 0xe2, 0x1c, 0x40, 0x00, 0xe7, 0x0f, 0x2e, 0x7e, 0xf3, 0xa1, 0x08, 0xdf, 0xa0, 0xf7, + 0x38, 0xfb, 0xa2, 0x4a, 0x68, 0x19, 0xe6, 0xc5, 0xa3, 0x12, 0xba, 0xcb, 0xbf, 0x68, 0x12, 0xba, + 0xc9, 0xbf, 0xe8, 0x12, 0xfa, 0x96, 0x1f, 0x72, 0xe9, 0x4b, 0xe8, 0x28, 0x7f, 0x32, 0x90, 0xd0, + 0xbb, 0xfc, 0xc9, 0x50, 0x42, 0xf7, 0xf9, 0x13, 0xa5, 0x27, 0x8d, 0xa6, 0xc5, 0x79, 0x6f, 0x1a, + 0xcb, 0xc8, 0x14, 0xca, 0xab, 0xc8, 0xbc, 0x6a, 0x51, 0x55, 0xd9, 0x42, 0x2d, 0xb6, 0xe2, 0xe4, + 0x13, 0x14, 0x0b, 0x85, 0xf8, 0x06, 0x3e, 0x87, 0x8b, 0x16, 0x22, 0x7e, 0x1e, 0xfd, 0xd3, 0x42, + 0x2d, 0xfc, 0x67, 0xd0, 0x42, 0x2d, 0xcb, 0x85, 0xae, 0xc9, 0x1c, 0x2a, 0x66, 0xa6, 0x73, 0x68, + 0x99, 0x45, 0x77, 0x2d, 0xd4, 0x72, 0xfd, 0x05, 0x7d, 0x7a, 0x4a, 0x1f, 0x9f, 0xd2, 0xe7, 0xa7, + 0xf4, 0xf5, 0xd3, 0xd6, 0x35, 0x1f, 0x52, 0x5a, 0x94, 0x0c, 0x2a, 0xe2, 0x55, 0xc3, 0x61, 0x92, + 0x62, 0x1d, 0x20, 0xae, 0xc4, 0xc5, 0xe9, 0x30, 0xdf, 0x1d, 0xcc, 0xcc, 0xce, 0xc9, 0x0c, 0x61, + 0x52, 0x09, 0x13, 0x9a, 0xe3, 0xb0, 0xf3, 0x55, 0xe2, 0x6c, 0x3f, 0x68, 0x65, 0x76, 0x78, 0x42, + 0x84, 0xe5, 0xc0, 0x03, 0x0f, 0x55, 0x0c, 0x3b, 0x69, 0xc4, 0x3e, 0xa6, 0x57, 0xd1, 0x75, 0x29, + 0xab, 0xf1, 0x8d, 0xe3, 0xa7, 0x2d, 0x27, 0xbd, 0x4d, 0xf9, 0xe1, 0x21, 0x19, 0xe3, 0xcd, 0xa2, + 0x71, 0xe7, 0x87, 0x6e, 0x74, 0x27, 0xc0, 0xef, 0x63, 0xa2, 0x42, 0x3a, 0xaf, 0x94, 0x4e, 0x87, + 0x9c, 0xaa, 0xbe, 0xa6, 0xc2, 0xf9, 0xc9, 0x2c, 0xe7, 0x6c, 0xfe, 0x83, 0xa5, 0x45, 0x18, 0x16, + 0x8c, 0x3b, 0x0b, 0x8b, 0x0b, 0xbf, 0x48, 0xa4, 0x3d, 0xb0, 0x9d, 0xd4, 0xe7, 0xcf, 0xc5, 0x04, + 0x5c, 0xa9, 0x08, 0x3e, 0xc2, 0xf9, 0x99, 0xef, 0x24, 0x84, 0xe1, 0x9b, 0x79, 0xa4, 0x2f, 0xb3, + 0xcc, 0x28, 0x26, 0x89, 0x91, 0x22, 0xfa, 0xe9, 0x02, 0x7e, 0xb2, 0x33, 0x44, 0x53, 0x2b, 0xb9, + 0x35, 0x62, 0x34, 0xb5, 0xee, 0xe9, 0x34, 0x8d, 0x08, 0x25, 0x13, 0xdf, 0x4b, 0x0f, 0x97, 0x86, + 0xcf, 0x99, 0x6c, 0x97, 0x21, 0x17, 0xc7, 0x5b, 0xd5, 0x21, 0x44, 0x1c, 0x84, 0x98, 0x83, 0x60, + 0xa6, 0xc5, 0xe1, 0xaa, 0x64, 0x37, 0x82, 0x53, 0x1b, 0xc9, 0x78, 0xec, 0x8f, 0xdc, 0x71, 0xb8, + 0xbb, 0x2b, 0xba, 0x6d, 0x33, 0x46, 0xce, 0x9e, 0x99, 0x24, 0xd9, 0xb9, 0x0b, 0xfc, 0x3c, 0x44, + 0x81, 0x39, 0xd9, 0x23, 0x73, 0xb5, 0xec, 0x44, 0x74, 0xa5, 0xb6, 0x02, 0x41, 0x12, 0xc8, 0x27, + 0x40, 0x7c, 0x64, 0x1f, 0xb2, 0xe1, 0xf8, 0x99, 0xba, 0x63, 0x42, 0x15, 0x39, 0x33, 0x3a, 0xf1, + 0x7d, 0x7a, 0x6a, 0x38, 0x28, 0x22, 0x07, 0x52, 0x8c, 0x00, 0xf9, 0xc9, 0x57, 0x1c, 0x47, 0xc6, + 0x1c, 0xf9, 0xc9, 0x29, 0x6c, 0x96, 0xf4, 0xef, 0x89, 0x31, 0x65, 0x5d, 0x4e, 0x8c, 0x09, 0x37, + 0xb7, 0xd3, 0xa8, 0x58, 0x6b, 0x9a, 0x96, 0xf0, 0x93, 0xfc, 0x88, 0x60, 0x6d, 0x65, 0xad, 0xea, + 0x91, 0xfb, 0xa4, 0x88, 0x2d, 0xd3, 0x22, 0x68, 0x02, 0x48, 0x4c, 0xf9, 0x4b, 0x08, 0xf0, 0x16, + 0xed, 0x39, 0x8b, 0xfc, 0x30, 0x2d, 0xce, 0xc0, 0xb6, 0xf6, 0x42, 0x69, 0xcd, 0xf1, 0xc2, 0xc7, + 0x7f, 0x01, 0x3b, 0x88, 0x03, 0x3b, 0x56, 0x60, 0xc5, 0xc9, 0xe3, 0x88, 0xe2, 0x5c, 0xc5, 0xa7, + 0x5b, 0x90, 0xa4, 0xe0, 0x36, 0x63, 0x99, 0x26, 0x9c, 0x07, 0xfe, 0x2e, 0x24, 0x81, 0x71, 0x10, + 0x11, 0xce, 0xe9, 0x38, 0xc8, 0x43, 0x48, 0xb0, 0x99, 0xa5, 0x5b, 0x64, 0xe6, 0xf4, 0xe0, 0x84, + 0x0f, 0x3d, 0xce, 0xd3, 0x22, 0xb5, 0x73, 0x1a, 0x89, 0x29, 0x58, 0x07, 0x1f, 0x23, 0x12, 0x98, + 0x61, 0xb9, 0xb3, 0xb4, 0x48, 0x0f, 0xf3, 0x69, 0x34, 0x88, 0xc9, 0xc7, 0x1b, 0x68, 0x94, 0x00, + 0x91, 0x08, 0xe9, 0xe9, 0x6f, 0x3e, 0x64, 0xf4, 0x22, 0xf9, 0x3a, 0xb2, 0x35, 0x60, 0xb8, 0xc2, + 0x99, 0x65, 0xd6, 0xd8, 0x0e, 0x01, 0xae, 0x1a, 0x18, 0x9c, 0xc8, 0x35, 0x83, 0x50, 0x64, 0x22, + 0x06, 0xce, 0xb0, 0x63, 0x2a, 0x23, 0x77, 0xac, 0xa8, 0x2f, 0x1d, 0xd3, 0x6d, 0x77, 0x0d, 0x77, + 0xac, 0x91, 0x4f, 0xaa, 0xe1, 0xc2, 0x2d, 0x0c, 0xa2, 0x63, 0xaa, 0x19, 0x83, 0x53, 0xab, 0x35, + 0xe0, 0x1c, 0x61, 0x26, 0x1d, 0x13, 0x69, 0x4f, 0x61, 0xbe, 0xb0, 0x0f, 0x61, 0x41, 0x22, 0x01, + 0x70, 0x51, 0x63, 0x2c, 0x8a, 0x98, 0xb8, 0x14, 0x6d, 0x45, 0x7a, 0xe1, 0x48, 0xcf, 0x1d, 0xe4, + 0x99, 0x7e, 0x9e, 0x8f, 0x9b, 0x9a, 0xf3, 0xd1, 0x74, 0x6c, 0xca, 0xa3, 0x69, 0xdb, 0x74, 0xa4, + 0x55, 0x90, 0x41, 0xc8, 0x3b, 0xd8, 0xa6, 0x3c, 0xb2, 0xf7, 0xe3, 0x91, 0x9d, 0x95, 0xd6, 0x9c, + 0x9b, 0xe1, 0x95, 0x7d, 0x8d, 0xee, 0x32, 0xb1, 0x3c, 0x1f, 0x67, 0xa5, 0x83, 0x53, 0x69, 0x17, + 0xac, 0x83, 0xab, 0xbb, 0x6b, 0x13, 0xfe, 0xe9, 0x58, 0xb0, 0xf3, 0x5d, 0xd9, 0xd7, 0xd2, 0x9a, + 0x5a, 0x0c, 0x3e, 0x07, 0x34, 0x3b, 0x0a, 0xd5, 0x56, 0xd0, 0xb9, 0xe9, 0x8f, 0xec, 0xb1, 0x3c, + 0xb2, 0xdb, 0x6d, 0xe9, 0xdc, 0x3c, 0x27, 0xaf, 0x05, 0xf0, 0x1a, 0x5a, 0x9a, 0x4b, 0xf2, 0xed, + 0x9c, 0xd8, 0x17, 0x1e, 0xf8, 0x28, 0x2e, 0x98, 0x12, 0x68, 0x0a, 0xe2, 0x2b, 0x95, 0x51, 0x74, + 0x08, 0x8a, 0xd0, 0xc9, 0x8d, 0xe6, 0x76, 0x00, 0xd9, 0xdf, 0x2c, 0xd6, 0xc6, 0xe5, 0x07, 0x43, + 0x2e, 0x2e, 0x42, 0xa5, 0x02, 0x53, 0xe3, 0x62, 0xc7, 0x34, 0x93, 0x4d, 0x16, 0x12, 0xf5, 0x3e, + 0xc8, 0xd2, 0x4e, 0xc1, 0xe0, 0x10, 0xe8, 0xcf, 0xc4, 0x0b, 0x27, 0x33, 0xc1, 0x34, 0x85, 0x19, + 0x12, 0x4e, 0x42, 0xf8, 0x10, 0x16, 0x06, 0x8a, 0x1d, 0x42, 0xac, 0x1c, 0x53, 0x27, 0x2a, 0x33, + 0x5a, 0x60, 0xd7, 0x59, 0x51, 0x8f, 0x84, 0xe7, 0xfd, 0xb7, 0x61, 0x9e, 0x8d, 0x63, 0xd9, 0xc7, + 0xd0, 0x2c, 0xfc, 0x6a, 0x08, 0x9b, 0x40, 0x92, 0x1e, 0xbb, 0x77, 0x56, 0xec, 0x26, 0x2d, 0x09, + 0xed, 0xe0, 0x3c, 0x5b, 0x87, 0xb7, 0x64, 0xeb, 0x7e, 0xaf, 0x64, 0xeb, 0x7e, 0x5e, 0x25, 0x6b, + 0xe1, 0xe8, 0xe3, 0xf9, 0x6f, 0xc7, 0x2c, 0x61, 0xf7, 0x7b, 0xb1, 0xc8, 0x8e, 0x10, 0x79, 0x57, + 0xad, 0x19, 0xec, 0xd6, 0x2d, 0xd4, 0x9a, 0xb4, 0xae, 0xb3, 0x34, 0x04, 0xbe, 0x72, 0x48, 0xe6, + 0x6e, 0x27, 0x73, 0x75, 0x26, 0x7c, 0x7e, 0x68, 0x32, 0x9e, 0x34, 0x08, 0xfd, 0xef, 0x64, 0x90, + 0x0e, 0x24, 0xde, 0xf2, 0xf4, 0x75, 0x9e, 0x1d, 0xa1, 0xef, 0xfe, 0x4e, 0x59, 0x22, 0x32, 0xdf, + 0x87, 0x22, 0xee, 0xcc, 0x50, 0x0a, 0xfb, 0x2f, 0x89, 0x8a, 0x93, 0x86, 0x10, 0x1a, 0x42, 0x68, + 0x70, 0xcd, 0xab, 0xd6, 0xeb, 0xfb, 0x16, 0x6a, 0xbd, 0x5e, 0x82, 0x35, 0xd0, 0x42, 0x84, 0x16, + 0x77, 0xd8, 0xc7, 0x71, 0x92, 0xc6, 0x56, 0x92, 0xb4, 0x5e, 0xb6, 0xec, 0x96, 0xd1, 0x72, 0x5b, + 0xd7, 0xa5, 0xc9, 0x08, 0xae, 0x44, 0xe2, 0x1f, 0xb9, 0x72, 0x82, 0x89, 0x3c, 0x0d, 0xd5, 0x06, + 0x9b, 0x14, 0x00, 0xd2, 0x9e, 0x27, 0xb3, 0xdf, 0x0b, 0xcb, 0xa0, 0xe2, 0x74, 0xb2, 0x6f, 0x56, + 0x02, 0xd7, 0xa8, 0x8b, 0xab, 0x35, 0xc2, 0x50, 0xdc, 0x44, 0xde, 0x33, 0x30, 0x3a, 0x99, 0x19, + 0x11, 0x3a, 0x09, 0x0d, 0x96, 0xb2, 0x9b, 0xa4, 0x28, 0x49, 0x10, 0x4e, 0xd0, 0xbb, 0x10, 0x05, + 0x29, 0x0a, 0x93, 0xb2, 0xb1, 0xf7, 0x11, 0xfe, 0x99, 0xf0, 0x29, 0xbb, 0x24, 0xe1, 0x52, 0x76, + 0x38, 0xe1, 0xf3, 0x8b, 0xe8, 0x5d, 0x58, 0x4a, 0x37, 0x06, 0xd9, 0x49, 0xe9, 0xca, 0x11, 0x61, + 0x56, 0xbb, 0x79, 0x78, 0x70, 0x71, 0x6c, 0x62, 0xf2, 0x87, 0x96, 0xff, 0x80, 0x4a, 0x32, 0x31, + 0xd5, 0x4c, 0xb4, 0xa2, 0x09, 0x8e, 0xff, 0x9d, 0xb0, 0x73, 0xbd, 0xb6, 0x9f, 0x26, 0x66, 0xba, + 0xfe, 0x36, 0x0f, 0xe1, 0xf7, 0xce, 0xdf, 0xc1, 0xf5, 0x12, 0xec, 0xc0, 0xb1, 0x99, 0xbf, 0x9d, + 0x1d, 0x9e, 0xca, 0x83, 0x7e, 0x93, 0x14, 0xa2, 0x7e, 0x49, 0x42, 0xf8, 0x37, 0x24, 0x62, 0x4b, + 0x83, 0x7e, 0x51, 0x2e, 0x9d, 0x24, 0xec, 0x97, 0x24, 0x45, 0xdc, 0x6f, 0x16, 0x63, 0x76, 0x3b, + 0xd6, 0x27, 0x62, 0x1f, 0x88, 0x15, 0x7b, 0x21, 0x31, 0x42, 0xde, 0xf6, 0x88, 0xd6, 0xe6, 0x7f, + 0x40, 0x1a, 0x34, 0x47, 0x12, 0xd8, 0xe7, 0xea, 0x1a, 0xf9, 0x26, 0x46, 0x2e, 0xa7, 0x6b, 0x1c, + 0x53, 0x1e, 0x39, 0xfb, 0xe1, 0xc8, 0x01, 0x05, 0x06, 0x87, 0x03, 0xe3, 0xce, 0x6c, 0x9e, 0x4c, + 0x44, 0xb7, 0x60, 0xff, 0x89, 0xa9, 0x8c, 0x26, 0xfb, 0xd1, 0x68, 0x02, 0x07, 0x2a, 0x4d, 0x97, + 0xa0, 0xeb, 0x4b, 0x5c, 0x47, 0xdf, 0x74, 0x6b, 0x5a, 0x25, 0x5e, 0xc3, 0x46, 0x23, 0x72, 0x35, + 0x03, 0x8c, 0x76, 0x39, 0xcf, 0x85, 0x8f, 0x6e, 0x88, 0x79, 0xf5, 0x46, 0x4e, 0x49, 0x48, 0x0c, + 0x65, 0x8b, 0x84, 0x7c, 0x98, 0x21, 0xe6, 0x66, 0x98, 0x63, 0xec, 0x9a, 0xf2, 0xc8, 0xdd, 0xf7, + 0x3b, 0x8c, 0x32, 0x23, 0x37, 0x3b, 0x0b, 0x57, 0xb1, 0x65, 0x26, 0x99, 0x2d, 0x13, 0x30, 0x5b, + 0x66, 0x9e, 0xd9, 0x32, 0x5e, 0x6e, 0xcb, 0x4c, 0xd7, 0xe6, 0x65, 0x28, 0x86, 0xc8, 0x85, 0x3c, + 0x40, 0x68, 0x3a, 0x28, 0x78, 0x19, 0x9b, 0x31, 0x21, 0xc2, 0x02, 0x9c, 0xe9, 0xf4, 0x6a, 0x7a, + 0x2d, 0x49, 0x06, 0xac, 0x1d, 0x6b, 0x9b, 0xa3, 0xf4, 0x6a, 0x72, 0x2d, 0xe5, 0xa4, 0x38, 0x08, + 0xe1, 0xfc, 0xe4, 0x0a, 0x38, 0xdc, 0x03, 0x06, 0x07, 0xc2, 0x7c, 0x24, 0xec, 0x92, 0x95, 0x13, + 0x57, 0x59, 0x25, 0xde, 0x38, 0x33, 0x76, 0x5e, 0x3b, 0x9b, 0xd9, 0xee, 0x6e, 0x48, 0xb6, 0xfb, + 0x91, 0x5f, 0x9e, 0xa1, 0x9b, 0xcd, 0xd0, 0xc9, 0x66, 0x38, 0x61, 0x33, 0x0c, 0xd8, 0x74, 0x7c, + 0x14, 0x93, 0x6d, 0x23, 0x34, 0x5d, 0xb4, 0x33, 0xa1, 0xc3, 0xce, 0xcd, 0x14, 0x14, 0x5a, 0x36, + 0x95, 0xe0, 0xe5, 0x3c, 0x77, 0x15, 0x8c, 0xb9, 0xb4, 0x2e, 0xcf, 0x27, 0x82, 0xba, 0xec, 0xf7, + 0x39, 0x53, 0x26, 0x62, 0xe9, 0x9c, 0x20, 0x4e, 0xb2, 0xec, 0x7d, 0x16, 0x28, 0x7d, 0x78, 0x10, + 0xd9, 0x3c, 0x6b, 0x9c, 0x9c, 0x42, 0xbe, 0x05, 0xa2, 0xa2, 0x0a, 0x84, 0xea, 0xa8, 0x26, 0x0d, + 0xcb, 0xe5, 0x1b, 0x62, 0x64, 0x86, 0x44, 0x46, 0x70, 0xc2, 0xf2, 0xfb, 0x11, 0xc4, 0x28, 0xa2, + 0xb5, 0x63, 0x39, 0x13, 0xec, 0x96, 0x07, 0x4f, 0x13, 0xce, 0xc9, 0x24, 0x43, 0x12, 0x5e, 0x64, + 0xa7, 0xef, 0x2b, 0x68, 0x47, 0x88, 0x64, 0x1c, 0x53, 0x69, 0x3d, 0x2f, 0xad, 0x49, 0xb6, 0x12, + 0x25, 0x60, 0x31, 0xa4, 0xb2, 0x5e, 0xd2, 0x93, 0xaf, 0x35, 0x89, 0x8f, 0x24, 0x23, 0x1f, 0x8c, + 0xad, 0x6f, 0xdc, 0x38, 0x64, 0xcc, 0x86, 0x44, 0x91, 0xb4, 0xa6, 0x8e, 0xe1, 0x11, 0xcc, 0x82, + 0x4a, 0xf4, 0xb7, 0xb0, 0x2c, 0xb5, 0xef, 0xd8, 0xb9, 0x79, 0x88, 0x77, 0x63, 0x38, 0x5f, 0x0c, + 0x57, 0x43, 0x42, 0x09, 0xd6, 0xc4, 0x4a, 0xd8, 0x6b, 0x45, 0xe9, 0x0b, 0xe0, 0x0a, 0x74, 0x5c, + 0x97, 0x4a, 0x0a, 0xde, 0x44, 0xd5, 0x63, 0x9c, 0x34, 0xb9, 0xc0, 0x32, 0xbf, 0xf0, 0x31, 0xa4, + 0x91, 0x72, 0x58, 0x76, 0x96, 0x0a, 0xee, 0x58, 0x90, 0x33, 0x8d, 0x69, 0xe2, 0x97, 0xb6, 0x43, + 0xea, 0x22, 0x7b, 0xea, 0xb2, 0x4f, 0x70, 0x12, 0x50, 0xe2, 0x3c, 0x7a, 0x88, 0xb5, 0x43, 0x50, + 0x9f, 0xbb, 0xd8, 0x85, 0x9e, 0xa2, 0x85, 0x40, 0x34, 0xf5, 0xb4, 0xde, 0x86, 0x62, 0xbe, 0x5f, + 0x23, 0x40, 0x0c, 0x77, 0x4e, 0x66, 0x27, 0x21, 0x44, 0x67, 0x57, 0x27, 0x33, 0x23, 0x84, 0x7d, + 0x00, 0xae, 0x2c, 0x00, 0x61, 0xef, 0x90, 0x0d, 0x02, 0x8a, 0x41, 0xfd, 0xb5, 0x19, 0x8f, 0x66, + 0x40, 0xa4, 0xd5, 0x1a, 0xad, 0xe6, 0x8b, 0x73, 0xb8, 0x5b, 0xcf, 0x28, 0x78, 0x64, 0x9d, 0x9f, + 0x5f, 0x4f, 0xf2, 0x4c, 0x58, 0xd4, 0x21, 0x31, 0xcd, 0xe7, 0x03, 0xa9, 0xfd, 0x1a, 0x39, 0xe6, + 0x39, 0x38, 0xaf, 0x94, 0xe0, 0xe2, 0x39, 0x54, 0xf3, 0xe2, 0x0e, 0x83, 0xf3, 0xf0, 0x20, 0x8a, + 0xe7, 0xe8, 0x8e, 0x94, 0x6b, 0xc4, 0x4b, 0x46, 0xce, 0x55, 0x16, 0xce, 0xdc, 0x91, 0x11, 0xf9, + 0x59, 0x27, 0x83, 0x86, 0x72, 0xc5, 0xb0, 0xe3, 0xfa, 0x0b, 0xd2, 0x5f, 0x5a, 0xd3, 0x4a, 0xb8, + 0xda, 0x1b, 0x0a, 0x7b, 0xe3, 0x1c, 0x93, 0xa5, 0x00, 0xfd, 0xf7, 0x06, 0x8c, 0xea, 0x18, 0xc5, + 0x9d, 0xd7, 0xf7, 0xf0, 0x4f, 0x53, 0xc8, 0xc7, 0xb6, 0x5c, 0xc1, 0x99, 0xc7, 0x0b, 0xb8, 0xdd, + 0x2f, 0xb6, 0xa6, 0x89, 0x21, 0xdc, 0xe0, 0x10, 0xc7, 0x56, 0x1a, 0xc5, 0xd4, 0x9a, 0xe6, 0xab, + 0x88, 0x02, 0x91, 0x54, 0xb5, 0xe6, 0xe9, 0x9f, 0x1b, 0xf3, 0xf0, 0xe5, 0x6b, 0xe3, 0x3c, 0xcf, + 0xa1, 0xfe, 0x8a, 0xc5, 0x96, 0x13, 0x45, 0xb1, 0xeb, 0x87, 0x56, 0x8a, 0x85, 0xd6, 0x1e, 0x74, + 0xbf, 0x41, 0xae, 0x84, 0xee, 0x38, 0xeb, 0x5f, 0x3c, 0xa7, 0xda, 0x59, 0x3c, 0xe7, 0x3d, 0xaa, + 0x26, 0xe4, 0x8e, 0xc9, 0x61, 0x15, 0xec, 0xbe, 0x27, 0x1e, 0x55, 0xe1, 0xf9, 0xac, 0x69, 0x94, + 0xfe, 0x43, 0x9a, 0x93, 0x10, 0xf4, 0xd0, 0x67, 0xe3, 0x10, 0x7d, 0x31, 0x6e, 0xd0, 0x57, 0xe3, + 0xdb, 0xda, 0x3c, 0x47, 0xb7, 0xe6, 0x39, 0x89, 0xc0, 0x4a, 0xa3, 0x3b, 0x5a, 0xb6, 0xb4, 0xbb, + 0x2b, 0xde, 0x99, 0xb7, 0x2f, 0x4f, 0x22, 0x23, 0x24, 0xe9, 0xa4, 0x6f, 0xf4, 0xc0, 0xbb, 0xf0, + 0xca, 0x74, 0xc4, 0xc3, 0xe7, 0x77, 0x50, 0xdf, 0xef, 0x88, 0x37, 0xf0, 0xe1, 0xcc, 0x0c, 0x09, + 0xa7, 0x7d, 0x43, 0x77, 0x84, 0x90, 0xb7, 0x2c, 0xa7, 0xb6, 0xba, 0x37, 0xce, 0x31, 0x5a, 0x1a, + 0xaf, 0xd7, 0xd0, 0x7a, 0xb6, 0x63, 0x9a, 0xaf, 0x1b, 0x37, 0x94, 0xaf, 0xc2, 0x9d, 0x95, 0x17, + 0x41, 0xe5, 0x36, 0xe8, 0xea, 0xde, 0x78, 0x85, 0x96, 0xc6, 0xc9, 0x7a, 0x0d, 0x09, 0xd0, 0x0f, + 0xa9, 0x78, 0xce, 0x10, 0xb7, 0x8c, 0x3b, 0xe4, 0x42, 0xd9, 0x71, 0x0c, 0x60, 0x19, 0xd6, 0xcd, + 0x4b, 0x45, 0x96, 0xc4, 0x10, 0x40, 0x6f, 0xd3, 0xad, 0x6a, 0xf5, 0xd9, 0xb8, 0x41, 0x5f, 0x8c, + 0x6f, 0xe8, 0xab, 0x71, 0x8b, 0x2e, 0x8d, 0x57, 0x30, 0x73, 0x3a, 0x8f, 0x1b, 0x98, 0x87, 0x23, + 0x7e, 0x7b, 0xfe, 0x0d, 0x2a, 0xe1, 0x1d, 0xf1, 0xf6, 0xf9, 0x2d, 0x14, 0xbe, 0x3b, 0xe2, 0xf1, + 0xf3, 0x63, 0x38, 0x71, 0xe0, 0x88, 0x27, 0x30, 0xd7, 0x53, 0xd2, 0xe2, 0x88, 0xef, 0xf6, 0xce, + 0xe0, 0x9c, 0x91, 0xe9, 0x88, 0x8b, 0x3d, 0xa0, 0x07, 0x3c, 0x3e, 0x93, 0x68, 0xda, 0xea, 0x74, + 0xc7, 0x34, 0x2f, 0xb7, 0x22, 0x04, 0xbe, 0x15, 0xbb, 0xb7, 0xcf, 0x4b, 0x85, 0x1d, 0x53, 0x88, + 0x21, 0x33, 0x27, 0x88, 0x8a, 0xc4, 0x76, 0xd4, 0x03, 0x82, 0xd3, 0x37, 0x09, 0x7d, 0x24, 0xa8, + 0xbc, 0x22, 0x70, 0x0f, 0x76, 0x4c, 0xf3, 0xe3, 0xbf, 0x04, 0x57, 0x95, 0x72, 0xb2, 0xc2, 0xdd, + 0x84, 0x23, 0x7a, 0xb8, 0x69, 0x59, 0x32, 0xb0, 0xee, 0xd0, 0x21, 0xba, 0x41, 0xdf, 0x98, 0x91, + 0xf5, 0xd9, 0x0c, 0xc4, 0xd6, 0x7d, 0x0b, 0xdd, 0xb1, 0x12, 0xeb, 0x2f, 0xf0, 0x7d, 0xd9, 0x42, + 0x87, 0xec, 0xfb, 0x57, 0xf8, 0xfe, 0xbd, 0x85, 0x6e, 0xa0, 0x84, 0x8c, 0x36, 0x5d, 0x42, 0x53, + 0xda, 0x42, 0xdf, 0xf2, 0xfa, 0x33, 0x66, 0x58, 0x92, 0x7b, 0x3a, 0xd6, 0xe4, 0x8e, 0x4e, 0x87, + 0xda, 0xa1, 0xc5, 0x1d, 0x05, 0x71, 0xd6, 0xce, 0x05, 0xa6, 0xee, 0x08, 0xc3, 0xdf, 0x95, 0xd9, + 0xbd, 0xa1, 0x98, 0x8f, 0x72, 0x3b, 0x0b, 0x20, 0x40, 0xb6, 0x8a, 0xe5, 0x3f, 0xd8, 0x52, 0xdf, + 0x1b, 0x87, 0x68, 0x69, 0xdc, 0xac, 0xcd, 0xbb, 0x87, 0x87, 0xd5, 0x3a, 0x13, 0x3a, 0x3a, 0xad, + 0x43, 0x08, 0xa3, 0xc3, 0x7c, 0x6e, 0x24, 0x04, 0x30, 0x97, 0x22, 0x4c, 0xfe, 0x35, 0x82, 0xa5, + 0xbc, 0x91, 0x24, 0x1e, 0x29, 0x7a, 0xb5, 0x51, 0x59, 0x8e, 0x43, 0xaa, 0xb6, 0xd0, 0xca, 0x32, + 0xbe, 0x21, 0xd7, 0xb8, 0x05, 0x5e, 0xbc, 0x33, 0x3f, 0xa7, 0xe2, 0x67, 0x2c, 0x82, 0x08, 0xb7, + 0x98, 0x2e, 0x90, 0x90, 0x93, 0x8a, 0x87, 0xa8, 0xf5, 0xdd, 0x9f, 0xa9, 0x8a, 0xde, 0xca, 0x04, + 0xe8, 0x73, 0x2a, 0x12, 0xf9, 0xb9, 0x83, 0x63, 0x27, 0xd7, 0xa3, 0x57, 0xe4, 0x8f, 0x79, 0xb2, + 0xdb, 0x56, 0xd4, 0x21, 0xe9, 0x72, 0x66, 0x26, 0x58, 0x7c, 0x05, 0x8c, 0x78, 0xf8, 0xd2, 0x35, + 0x42, 0xea, 0xc0, 0x8d, 0x40, 0x5f, 0x10, 0xc0, 0x9d, 0x65, 0x0b, 0x9d, 0xa1, 0x73, 0x8c, 0x8e, + 0x29, 0x44, 0x60, 0xd3, 0xb3, 0xe7, 0x67, 0x94, 0x4d, 0x17, 0xed, 0xd7, 0x94, 0x4d, 0x6f, 0x9f, + 0x2f, 0xda, 0xdf, 0x24, 0x94, 0xab, 0xbc, 0x4b, 0xa6, 0xf1, 0x0e, 0xd6, 0xe6, 0x44, 0x7c, 0x87, + 0x4e, 0xa9, 0xd2, 0xdb, 0xce, 0xa8, 0x99, 0xb9, 0xb7, 0x14, 0x0a, 0x45, 0xc5, 0xa6, 0xf1, 0xd1, + 0x14, 0x0f, 0x76, 0x5f, 0x43, 0x04, 0xf5, 0x35, 0xfa, 0x62, 0x8a, 0x27, 0xbb, 0x8a, 0x3a, 0x90, + 0x48, 0x58, 0x0a, 0xc0, 0x1e, 0xee, 0xee, 0x1e, 0x98, 0xa6, 0x79, 0x8e, 0x77, 0x77, 0xbf, 0x6c, + 0x1d, 0xe1, 0xde, 0x94, 0x49, 0x00, 0xe2, 0xfe, 0x9b, 0x6c, 0x2a, 0x85, 0x03, 0xfa, 0x05, 0x78, + 0x7d, 0x77, 0x57, 0x04, 0x41, 0x68, 0x1f, 0x48, 0x12, 0x5a, 0xf2, 0xa1, 0xcb, 0xd5, 0xbd, 0x71, + 0x80, 0x96, 0xc6, 0xd9, 0xba, 0xb4, 0x52, 0x70, 0x13, 0x5d, 0xb6, 0x4e, 0x99, 0xcf, 0x5a, 0x64, + 0x07, 0xc4, 0x9f, 0x19, 0xf5, 0x08, 0x53, 0x1f, 0x4a, 0x60, 0x1d, 0x09, 0xf7, 0x95, 0xdb, 0x32, + 0xf2, 0x88, 0xa8, 0xd4, 0xb9, 0x27, 0x1d, 0x96, 0x9b, 0x3b, 0x2c, 0x39, 0x8b, 0x5f, 0xbc, 0x33, + 0x07, 0x30, 0xb2, 0x9c, 0xf7, 0xb6, 0x3b, 0xbc, 0xe1, 0x40, 0x2e, 0x9b, 0x81, 0x61, 0x1f, 0x1e, + 0x08, 0x98, 0xe9, 0x3c, 0x48, 0xfd, 0x59, 0xb0, 0x14, 0xb3, 0x5b, 0x75, 0xd6, 0x56, 0x92, 0xe0, + 0x38, 0x25, 0x2b, 0xe5, 0xa7, 0x30, 0xea, 0x94, 0xc9, 0x0d, 0x89, 0xc3, 0x24, 0x20, 0x14, 0x73, + 0xf1, 0x2e, 0x53, 0x62, 0x9c, 0xea, 0xa6, 0xf7, 0xd8, 0x7c, 0x36, 0x6e, 0xd1, 0x17, 0xe3, 0x15, + 0xfa, 0x6a, 0x9c, 0xac, 0xcd, 0x3b, 0xa2, 0xca, 0x0e, 0x9f, 0x9f, 0x64, 0xaa, 0xec, 0x1b, 0x55, + 0x65, 0x37, 0xd0, 0x02, 0x3c, 0xf2, 0xea, 0xf9, 0xb7, 0x22, 0xa9, 0x60, 0x9a, 0xe6, 0xf1, 0xee, + 0xee, 0x02, 0x2a, 0x43, 0xd6, 0x44, 0x97, 0x96, 0x26, 0xcc, 0x86, 0x5f, 0x52, 0xe3, 0x77, 0x9d, + 0x99, 0x9b, 0xfc, 0x5d, 0x8c, 0x4b, 0xd1, 0x11, 0xe9, 0x65, 0x44, 0x9f, 0x33, 0x6d, 0xc1, 0x94, + 0x04, 0xca, 0x1e, 0x5c, 0x4a, 0xd2, 0x3a, 0x73, 0x40, 0x32, 0x25, 0xbe, 0x36, 0x63, 0xd4, 0x30, + 0x95, 0x5b, 0x82, 0xfa, 0x21, 0x9c, 0x5e, 0x62, 0x7a, 0x19, 0x14, 0x74, 0x94, 0x3c, 0xa7, 0xca, + 0x99, 0xaa, 0xe9, 0x3b, 0xd0, 0xce, 0xc7, 0xe6, 0xe1, 0xde, 0x0d, 0x99, 0x18, 0xd5, 0xd2, 0xed, + 0xdb, 0xf6, 0x2b, 0x98, 0xdf, 0xd9, 0xde, 0x2b, 0x74, 0x6a, 0xbe, 0x6b, 0x9f, 0xa0, 0x4b, 0xf3, + 0xac, 0xfd, 0x0a, 0x01, 0x0f, 0x2d, 0x9e, 0x9f, 0x52, 0x65, 0xfa, 0xee, 0xf9, 0xa5, 0x84, 0xbe, + 0x90, 0x96, 0x4b, 0x09, 0x7d, 0x35, 0x1d, 0xf1, 0xf4, 0xf9, 0xbb, 0xd2, 0xc5, 0x78, 0x4b, 0xf1, + 0x00, 0x7d, 0x44, 0x5f, 0xd1, 0x17, 0x69, 0x0d, 0x56, 0x15, 0x4f, 0x78, 0xcb, 0x38, 0x44, 0x2e, + 0xa8, 0x14, 0x82, 0xf9, 0x37, 0xf4, 0xc5, 0xb8, 0x45, 0x5f, 0x8d, 0x57, 0xe8, 0x12, 0xa8, 0x9e, + 0x2d, 0xc4, 0x19, 0xfa, 0x62, 0x1c, 0xa3, 0xaf, 0xc6, 0x02, 0x5d, 0x1a, 0xef, 0x60, 0x31, 0x4e, + 0xc9, 0xbe, 0x72, 0x46, 0xb7, 0x8b, 0x5b, 0xd8, 0x4e, 0x0e, 0xc8, 0x76, 0x72, 0xf3, 0xfc, 0x1d, + 0xc5, 0xe9, 0xd5, 0xf3, 0x05, 0xc5, 0x49, 0xfc, 0xb6, 0x77, 0x2b, 0x3d, 0x17, 0xcf, 0xf6, 0x8e, + 0xa5, 0xf6, 0x69, 0x9b, 0xe0, 0xf7, 0xb1, 0x7d, 0x80, 0xbe, 0x9b, 0x1f, 0xf7, 0x0e, 0xd0, 0x27, + 0xd3, 0x11, 0x2f, 0xdb, 0x87, 0x30, 0x11, 0x8c, 0x4d, 0x47, 0xfc, 0xf2, 0xfc, 0xab, 0x84, 0x62, + 0xf8, 0xf4, 0xfd, 0xf9, 0x27, 0x09, 0xfd, 0x42, 0xdb, 0x3e, 0x49, 0xe8, 0x16, 0x3e, 0x7d, 0x7d, + 0xfe, 0xbd, 0x32, 0x2b, 0x8c, 0x51, 0x8c, 0xd1, 0x2d, 0x46, 0xbf, 0x60, 0x69, 0x0d, 0xbf, 0x56, + 0x0a, 0xd7, 0x10, 0xc2, 0xf4, 0xf8, 0xe5, 0x26, 0x33, 0xce, 0x9d, 0x0a, 0x69, 0x9d, 0x33, 0x2a, + 0x55, 0xca, 0x45, 0x44, 0x02, 0x12, 0xb7, 0xe2, 0xdd, 0xa3, 0x1e, 0x22, 0x97, 0x93, 0x53, 0x20, + 0xf9, 0x9d, 0x38, 0xc2, 0x3e, 0xb5, 0xa0, 0x3a, 0x21, 0xd3, 0xd3, 0x33, 0xe3, 0x10, 0x79, 0x40, + 0x54, 0xbb, 0xc3, 0x7c, 0x05, 0x2a, 0x2d, 0xe8, 0x9b, 0x39, 0xfe, 0x80, 0xc5, 0x25, 0xfa, 0x56, + 0x98, 0xaf, 0xe4, 0xfb, 0xd5, 0x21, 0xba, 0xb9, 0x96, 0xae, 0xe4, 0xeb, 0x1c, 0x3b, 0x66, 0xcc, + 0x83, 0xf0, 0x33, 0x46, 0x2d, 0x23, 0xfb, 0x63, 0x88, 0xca, 0x0d, 0x88, 0xb2, 0xf1, 0xef, 0x88, + 0x4e, 0x7b, 0x49, 0x07, 0x31, 0xd8, 0xbd, 0x61, 0xb2, 0x28, 0x3d, 0x3c, 0xc0, 0x93, 0xd7, 0xc4, + 0xf1, 0x30, 0xec, 0x0e, 0x73, 0x54, 0xd8, 0x3c, 0x6e, 0xd8, 0x3c, 0x6e, 0x88, 0xda, 0xf1, 0x93, + 0x0b, 0xa8, 0x0a, 0x3c, 0x8b, 0xc9, 0x4d, 0x8b, 0x25, 0xe2, 0x57, 0xa6, 0xe3, 0x4b, 0x14, 0xf8, + 0xda, 0x4f, 0x2e, 0x23, 0xf2, 0xf3, 0x13, 0x27, 0x31, 0xe6, 0x64, 0xaf, 0x3c, 0x4e, 0xdc, 0x09, + 0xb3, 0xfe, 0xb9, 0x92, 0x2a, 0x16, 0xd7, 0xcb, 0x54, 0xd0, 0x9a, 0xfc, 0x9a, 0xc7, 0x51, 0xe4, + 0x59, 0x64, 0xd7, 0xcf, 0x3b, 0xf8, 0x05, 0xfe, 0xcd, 0xb8, 0xac, 0x59, 0xba, 0x99, 0x09, 0xf0, + 0xbd, 0x71, 0x87, 0x96, 0xd9, 0x49, 0x46, 0x4e, 0x2d, 0x22, 0xd8, 0x1d, 0xb3, 0xae, 0x87, 0x39, + 0xe1, 0x6e, 0xae, 0x6e, 0xf2, 0x88, 0xe9, 0xf5, 0x83, 0x79, 0xb7, 0xfb, 0xfa, 0xa5, 0xa2, 0x0e, + 0x0c, 0x19, 0xdd, 0xac, 0xd9, 0xd5, 0xab, 0x19, 0x22, 0x87, 0xec, 0x84, 0x57, 0x3e, 0x1c, 0x8c, + 0xcc, 0x0a, 0x70, 0xb2, 0x4e, 0xbf, 0xef, 0x53, 0x1b, 0xf7, 0xe7, 0x55, 0xb1, 0x04, 0x2f, 0x5b, + 0xc4, 0xcc, 0x33, 0xd8, 0xcb, 0x04, 0xe6, 0x7a, 0xfc, 0x3b, 0xd1, 0xe2, 0xb8, 0xaa, 0xe7, 0x3f, + 0xd3, 0xe6, 0xaa, 0x76, 0xff, 0x42, 0x9b, 0xbf, 0x57, 0x9a, 0xbf, 0xd2, 0xe6, 0xb4, 0xd2, 0x7c, + 0x99, 0x6d, 0x3e, 0x61, 0x14, 0x4f, 0xad, 0xc0, 0xff, 0x8e, 0xbf, 0x72, 0x14, 0x27, 0x4b, 0x7e, + 0x97, 0x6f, 0x50, 0xd3, 0x64, 0x0a, 0xfc, 0x99, 0x3f, 0x9e, 0xa7, 0xe2, 0x12, 0x45, 0xf4, 0xd4, + 0xdb, 0xb7, 0x04, 0xa7, 0x9f, 0xf2, 0xc8, 0x10, 0xc0, 0xa8, 0xb8, 0xe1, 0xe2, 0x1d, 0x10, 0xe1, + 0xdc, 0xba, 0xcb, 0x56, 0xa0, 0xbc, 0x25, 0xb1, 0xd6, 0xf5, 0x7a, 0x49, 0x83, 0x63, 0x54, 0xde, + 0x73, 0x3f, 0x86, 0xd8, 0x35, 0xf0, 0xed, 0x39, 0xf5, 0x6a, 0x10, 0x65, 0x5f, 0xd6, 0xed, 0x1c, + 0xa3, 0xd7, 0xe8, 0x35, 0x3a, 0xc7, 0xd0, 0x7e, 0x32, 0x33, 0x43, 0xf8, 0x13, 0x9a, 0x11, 0x97, + 0xb9, 0x0f, 0x08, 0xae, 0xb4, 0xae, 0x27, 0x4f, 0x61, 0x93, 0xa1, 0x78, 0x1c, 0x07, 0x12, 0x5a, + 0x16, 0x7e, 0xcb, 0x6f, 0x51, 0xf9, 0x8c, 0x06, 0x17, 0xf1, 0x2d, 0x2e, 0x33, 0xac, 0xdd, 0x9e, + 0xda, 0x9a, 0x58, 0xf0, 0x2b, 0xa5, 0x45, 0x11, 0x3c, 0x39, 0x29, 0xe1, 0x27, 0xf9, 0x4f, 0x4c, + 0xfc, 0x5d, 0x02, 0x17, 0x33, 0x25, 0x2e, 0xa6, 0xe5, 0xfe, 0x31, 0x4f, 0xd2, 0x0b, 0x22, 0xbe, + 0xb4, 0x00, 0x80, 0xab, 0x30, 0xe4, 0xee, 0xa5, 0xe4, 0x9b, 0xdd, 0x08, 0x7e, 0x54, 0x85, 0x6f, + 0x99, 0xc5, 0x18, 0x06, 0xe5, 0x9b, 0xa6, 0xd6, 0xec, 0x32, 0x3a, 0x02, 0xd9, 0xaf, 0xb9, 0xaf, + 0xab, 0xac, 0x7b, 0x08, 0xfe, 0xef, 0x0a, 0x68, 0x00, 0x71, 0xd1, 0x99, 0x11, 0x83, 0x53, 0xec, + 0xaf, 0xcd, 0x04, 0xb9, 0x66, 0xca, 0xdf, 0x8a, 0xf9, 0xf0, 0xf0, 0x1a, 0xc3, 0x65, 0x6d, 0x9d, + 0x1a, 0xba, 0x0f, 0x0f, 0xe2, 0xb1, 0x39, 0x3e, 0x06, 0x3f, 0x37, 0xed, 0x50, 0xc4, 0xc0, 0xcd, + 0x3d, 0x46, 0x0b, 0xf4, 0x8e, 0xa5, 0xa7, 0x9c, 0x54, 0x7c, 0x87, 0x5a, 0xb3, 0x89, 0x17, 0x58, + 0x37, 0x2d, 0x09, 0x2d, 0x98, 0x0c, 0x3d, 0x3c, 0xbc, 0x6b, 0xa8, 0x3f, 0x8d, 0x42, 0xf8, 0x39, + 0x8e, 0xe4, 0xc5, 0x2c, 0xc6, 0x6d, 0xc0, 0x91, 0xfc, 0x58, 0x10, 0xa9, 0xe2, 0xe2, 0xaa, 0x21, + 0xd9, 0xf2, 0x1d, 0x97, 0x6e, 0x0f, 0x17, 0x8f, 0x0b, 0x3d, 0x90, 0xf9, 0xdf, 0x09, 0x16, 0x8f, + 0xf9, 0x94, 0xf0, 0x1c, 0x3a, 0x51, 0x6b, 0xf3, 0xa6, 0x93, 0x60, 0x27, 0xc6, 0xe9, 0x2f, 0x78, + 0x39, 0x3a, 0x36, 0xc1, 0xae, 0x8a, 0xfd, 0x05, 0xb8, 0xb0, 0xf0, 0x33, 0x61, 0xe8, 0x18, 0x2d, + 0xa8, 0x85, 0xf8, 0x0e, 0x1e, 0x01, 0x22, 0x60, 0xa4, 0xf3, 0x3d, 0x00, 0x32, 0x52, 0x61, 0xd3, + 0x83, 0xad, 0xf1, 0x5d, 0x7e, 0x53, 0xdb, 0x82, 0xb8, 0x54, 0xd9, 0xf7, 0x05, 0xed, 0x72, 0x60, + 0x06, 0xe2, 0x69, 0x71, 0x8f, 0x15, 0xb6, 0x5c, 0xe3, 0x14, 0x16, 0xcd, 0xf3, 0xef, 0x8d, 0x4b, + 0xc4, 0x94, 0xf7, 0x01, 0x97, 0xcf, 0xf4, 0x18, 0xa2, 0xb4, 0xef, 0x22, 0xeb, 0xfb, 0x2e, 0xeb, + 0x7b, 0xba, 0x36, 0x61, 0x2e, 0xe8, 0xd2, 0x8c, 0x0a, 0x3b, 0xec, 0x14, 0x06, 0xba, 0x2c, 0x64, + 0xa9, 0x34, 0x5e, 0x03, 0x0c, 0x44, 0xcd, 0xd7, 0x4b, 0xfa, 0x97, 0xb2, 0x19, 0x8f, 0xc4, 0x94, + 0x23, 0x29, 0x20, 0xd4, 0x29, 0xfa, 0x71, 0x85, 0x80, 0xe2, 0x31, 0x7f, 0x98, 0x2e, 0xf2, 0x44, + 0x09, 0x8e, 0xca, 0x2c, 0x28, 0x9d, 0xdf, 0x99, 0xe4, 0xda, 0xdc, 0x85, 0x54, 0xb8, 0x2e, 0x58, + 0x04, 0xcb, 0xfd, 0x67, 0x08, 0x1b, 0x90, 0xb5, 0x6e, 0xa1, 0x63, 0x09, 0xed, 0xec, 0x84, 0xa5, + 0xdc, 0xbd, 0x4d, 0x39, 0x88, 0x08, 0x1e, 0x59, 0x9d, 0xec, 0x37, 0x99, 0xa1, 0x33, 0xa4, 0x9d, + 0x8f, 0xcd, 0x10, 0x96, 0x36, 0x63, 0x67, 0x98, 0xd8, 0x69, 0x36, 0xb1, 0xca, 0x84, 0x4c, 0x4f, + 0x5c, 0x80, 0x8d, 0xb2, 0x14, 0xdf, 0x75, 0xd8, 0x98, 0xe8, 0x14, 0xe0, 0x7c, 0xe1, 0x89, 0xf7, + 0x51, 0x2a, 0x08, 0x87, 0xbe, 0x96, 0x3a, 0x7f, 0x41, 0x07, 0xd0, 0xfd, 0xbb, 0x99, 0xf3, 0xd5, + 0xc7, 0xbd, 0xaf, 0xcf, 0x2f, 0xa9, 0xef, 0xe1, 0xe7, 0xfb, 0xf3, 0xf7, 0x86, 0xfd, 0x19, 0xd2, + 0x10, 0x82, 0x67, 0xf9, 0x01, 0x76, 0x0b, 0x47, 0x24, 0xab, 0x99, 0xfb, 0x64, 0xfe, 0x87, 0xf8, + 0x05, 0xf9, 0xf9, 0xb8, 0xdf, 0x0b, 0x1b, 0xe1, 0x33, 0x16, 0x3f, 0xa1, 0x9b, 0x0e, 0xf9, 0x31, + 0xd8, 0x74, 0x1e, 0x63, 0xd4, 0xca, 0x6a, 0x42, 0xd7, 0x34, 0xff, 0xb7, 0xa2, 0xee, 0x18, 0x5c, + 0xd3, 0x5f, 0xc8, 0xc0, 0x1d, 0xa5, 0x1a, 0x3a, 0x35, 0xcf, 0x29, 0xf7, 0xb0, 0x19, 0x18, 0x97, + 0x88, 0x75, 0x3f, 0x58, 0x9b, 0xa7, 0xe8, 0xa3, 0xc9, 0x41, 0xa6, 0xcc, 0x9f, 0x7f, 0x05, 0xd6, + 0xff, 0x08, 0x96, 0x36, 0x4f, 0xf3, 0x05, 0x58, 0xa4, 0x20, 0x22, 0xe4, 0xd7, 0xf5, 0x7e, 0x01, + 0xf6, 0x7f, 0x87, 0x6e, 0x3a, 0xf9, 0x57, 0x09, 0x1d, 0x70, 0x55, 0xa8, 0x4e, 0x2a, 0x1e, 0x14, + 0xee, 0x22, 0x59, 0xad, 0x85, 0x19, 0x8a, 0x0b, 0x16, 0x7b, 0xf9, 0x62, 0x7e, 0x7c, 0xa1, 0xa2, + 0xaf, 0xe6, 0x71, 0x71, 0x23, 0xa5, 0x8c, 0xbe, 0x00, 0x79, 0x41, 0x5a, 0x8b, 0xc6, 0x2f, 0xe8, + 0xa3, 0x24, 0xa1, 0x4f, 0x88, 0x98, 0x7c, 0x23, 0x08, 0x98, 0x7d, 0x32, 0x13, 0xce, 0x15, 0x7a, + 0x87, 0x0e, 0x88, 0x11, 0xc9, 0xb7, 0x7d, 0x85, 0xb6, 0x18, 0x73, 0xeb, 0xca, 0xb6, 0xfe, 0xef, + 0x52, 0x29, 0x84, 0xb6, 0xa3, 0xac, 0x49, 0x2e, 0x7e, 0x77, 0xf7, 0x53, 0xa7, 0x6c, 0xcb, 0x94, + 0x4f, 0x4d, 0xfe, 0x82, 0xcd, 0xa5, 0x78, 0x89, 0x30, 0xe6, 0x78, 0xe3, 0x13, 0xf7, 0xb9, 0xe0, + 0x6b, 0x8c, 0x89, 0xd9, 0xf9, 0xa9, 0x3a, 0xf0, 0x2f, 0x58, 0x92, 0x3a, 0xb9, 0xa1, 0x1a, 0x63, + 0xa9, 0x53, 0xb1, 0x5d, 0x98, 0xb9, 0x03, 0xa3, 0x1d, 0x9a, 0x31, 0xf3, 0xc9, 0x6f, 0xcc, 0x55, + 0xae, 0x9d, 0x8c, 0x43, 0x94, 0x13, 0xda, 0x38, 0x44, 0xf9, 0x4a, 0x19, 0xea, 0xf3, 0x43, 0x94, + 0x60, 0x0c, 0x61, 0xa4, 0x82, 0x05, 0xbe, 0x89, 0xc7, 0xa6, 0x2b, 0x82, 0x72, 0xc3, 0xae, 0x94, + 0x4b, 0xef, 0x67, 0x2c, 0x1e, 0x23, 0xda, 0x88, 0x5a, 0xf0, 0x2f, 0x9f, 0x9b, 0xbf, 0x2d, 0x94, + 0xe2, 0x19, 0x53, 0xfa, 0x17, 0xd9, 0xe0, 0xe2, 0x71, 0xae, 0x45, 0x0a, 0x84, 0x16, 0x1c, 0x42, + 0x53, 0x71, 0x21, 0x71, 0x2a, 0xe3, 0x15, 0xa7, 0x32, 0x02, 0x50, 0x91, 0xbb, 0xbb, 0xc7, 0xd9, + 0xd5, 0x8f, 0xa6, 0xe9, 0xd3, 0xe9, 0x71, 0x3f, 0xc5, 0x00, 0x0c, 0x2b, 0x71, 0xd1, 0xd0, 0x9d, + 0x1d, 0x7e, 0x39, 0xe1, 0x61, 0x75, 0xdd, 0xd6, 0x34, 0xb6, 0x00, 0xbf, 0x59, 0x91, 0xc7, 0x0a, + 0x73, 0x6c, 0x3c, 0x54, 0xc1, 0xdf, 0xf8, 0x96, 0x15, 0x69, 0x16, 0x4d, 0xaf, 0xb2, 0xa6, 0xe2, + 0xbd, 0x13, 0x94, 0x46, 0xbf, 0x46, 0x61, 0x7a, 0x13, 0x4d, 0xf1, 0xff, 0x69, 0xef, 0x5d, 0xb7, + 0xda, 0x46, 0xd6, 0x45, 0xd1, 0xff, 0xfb, 0x29, 0x1c, 0xad, 0x4c, 0xb6, 0x44, 0xca, 0x8e, 0xe5, + 0x1b, 0x20, 0x47, 0x78, 0x10, 0x42, 0x3a, 0x74, 0x87, 0xc0, 0x04, 0x92, 0x9e, 0x3d, 0x39, 0x2c, + 0x10, 0x52, 0x19, 0xab, 0x91, 0x25, 0xb7, 0xaa, 0xcc, 0xa5, 0x8d, 0xc7, 0x58, 0xbf, 0xf6, 0x03, + 0x9c, 0x7d, 0x9e, 0x61, 0xbf, 0xc2, 0xf9, 0x7f, 0x1e, 0x65, 0x3e, 0xc9, 0x19, 0x5f, 0xdd, 0x54, + 0xba, 0xd8, 0x86, 0x0e, 0xbd, 0x2e, 0x63, 0xcd, 0x1e, 0xa3, 0x89, 0x55, 0xf7, 0xfa, 0xaa, 0xea, + 0xab, 0xef, 0x5e, 0xe9, 0x83, 0xc4, 0xbd, 0x0f, 0xce, 0xed, 0x3c, 0xb7, 0xbd, 0x98, 0x10, 0x4d, + 0xdb, 0xf7, 0xc0, 0xa1, 0xb9, 0xae, 0xdb, 0x66, 0x41, 0xe2, 0x5f, 0x7d, 0x59, 0x5b, 0xfb, 0xfc, + 0xca, 0x75, 0xbb, 0x1b, 0x65, 0x34, 0x00, 0xaf, 0x0b, 0xe5, 0x9c, 0x6a, 0x20, 0x68, 0xe4, 0x16, + 0x93, 0x19, 0x74, 0x3a, 0x9b, 0x02, 0x1d, 0x9c, 0xba, 0x5f, 0x06, 0x29, 0x13, 0xfa, 0xfe, 0xf0, + 0xe6, 0x16, 0xfd, 0x50, 0xbf, 0xb5, 0x1c, 0xfe, 0x79, 0x5b, 0xff, 0x01, 0xdd, 0xbe, 0xf9, 0x21, + 0xd3, 0x0f, 0xa8, 0x1d, 0x78, 0x6a, 0xcd, 0x73, 0x23, 0xe7, 0x93, 0xac, 0xbe, 0xe4, 0xd8, 0x1e, + 0x50, 0xb7, 0x5a, 0xee, 0xa8, 0xb1, 0x5b, 0x4b, 0xb6, 0xee, 0x9b, 0x9f, 0xad, 0x7c, 0xd6, 0x5c, + 0x40, 0xf5, 0x88, 0xdf, 0x7f, 0x1c, 0xac, 0x1a, 0xd1, 0xb4, 0xe7, 0x6e, 0xa2, 0x5b, 0x97, 0xeb, + 0xcb, 0xd4, 0xea, 0xdf, 0xea, 0x64, 0xd5, 0x1e, 0xb8, 0x74, 0xce, 0xe7, 0xd5, 0x36, 0x80, 0xb3, + 0x1b, 0xfc, 0x70, 0x8d, 0x63, 0xe7, 0x06, 0x81, 0x06, 0x23, 0xdb, 0x59, 0x6c, 0xab, 0x3b, 0x57, + 0xe8, 0x16, 0xa7, 0xe1, 0xf0, 0xc1, 0xb9, 0x43, 0x53, 0x1a, 0x46, 0xc4, 0x39, 0x44, 0x8c, 0x6e, + 0x76, 0x88, 0x08, 0x51, 0x4a, 0x9c, 0x6b, 0x5d, 0x93, 0xff, 0x8b, 0xe6, 0x0b, 0x36, 0xf3, 0x1c, + 0xd2, 0xf0, 0x50, 0xe0, 0x90, 0x46, 0x80, 0x26, 0x0e, 0x58, 0x98, 0x71, 0x31, 0x14, 0x8a, 0x1d, + 0xd2, 0x88, 0xd1, 0xc8, 0x21, 0x8d, 0x11, 0xfa, 0xe1, 0xde, 0x21, 0x40, 0x66, 0xfe, 0xf0, 0x00, + 0xff, 0x3e, 0x80, 0xf3, 0x07, 0xb3, 0x45, 0x8b, 0xc1, 0x75, 0x09, 0x14, 0xe1, 0xa4, 0x91, 0x59, + 0x54, 0x33, 0x51, 0x61, 0xe2, 0x82, 0x0a, 0x81, 0x02, 0xb5, 0x14, 0x23, 0xa9, 0x24, 0x20, 0x52, + 0xcc, 0x3f, 0x47, 0xa9, 0x3b, 0xd3, 0x49, 0x37, 0xa2, 0x93, 0x52, 0xa8, 0x4c, 0xf1, 0x91, 0x32, + 0x59, 0x25, 0x69, 0x3c, 0x22, 0x68, 0x2a, 0x45, 0xe1, 0x31, 0x8a, 0x1a, 0x7e, 0xe9, 0x04, 0x1e, + 0x69, 0x64, 0x1f, 0x12, 0xc8, 0x4a, 0xe9, 0xcd, 0xf8, 0xbf, 0xc3, 0x09, 0x25, 0x4e, 0x82, 0x44, + 0x13, 0xac, 0x3e, 0x0e, 0x02, 0xe2, 0xb1, 0xf4, 0x54, 0x3b, 0xc0, 0x3f, 0x25, 0x79, 0x2b, 0x3e, + 0x06, 0xeb, 0xc2, 0xba, 0x69, 0xda, 0x75, 0x34, 0xcb, 0x09, 0xec, 0x1d, 0x8a, 0x78, 0xb7, 0x04, + 0xe9, 0x5e, 0x04, 0xa0, 0x90, 0x05, 0xc2, 0x3b, 0x67, 0x8c, 0xce, 0x53, 0x19, 0x3e, 0xd0, 0x96, + 0x6f, 0x2c, 0xdd, 0x77, 0x2b, 0xc6, 0x4f, 0xf9, 0xf8, 0x63, 0x6d, 0xe8, 0xc9, 0xdc, 0x65, 0x0b, + 0x8e, 0x52, 0xf7, 0xb7, 0x84, 0xab, 0xaf, 0x42, 0xf7, 0x5b, 0x62, 0xa6, 0x4c, 0xb9, 0x26, 0xc7, + 0xcd, 0x26, 0x15, 0xf2, 0xd8, 0xde, 0x8c, 0x55, 0x48, 0x08, 0xfa, 0x98, 0xa0, 0x09, 0x45, 0x37, + 0x71, 0x5e, 0xe7, 0x1f, 0x13, 0xa9, 0xf8, 0x3f, 0xc6, 0xba, 0xaf, 0xae, 0x66, 0xeb, 0x99, 0x10, + 0xcd, 0xd6, 0xf3, 0x63, 0x92, 0xd9, 0x6d, 0xf6, 0x27, 0x95, 0x3a, 0x7f, 0xc1, 0x08, 0xe1, 0x89, + 0x8b, 0xcb, 0x22, 0x59, 0x6c, 0xcd, 0x7e, 0xa7, 0x66, 0x49, 0x02, 0x28, 0x93, 0xbf, 0x5f, 0xbc, + 0xb7, 0x80, 0x53, 0xae, 0x16, 0xd7, 0x89, 0x81, 0x36, 0x8a, 0x19, 0x19, 0x33, 0x8e, 0x0b, 0x82, + 0xb5, 0x49, 0x43, 0xcb, 0xfa, 0x23, 0x5c, 0x70, 0x2d, 0xc7, 0xea, 0x56, 0x0b, 0x09, 0x5e, 0x35, + 0xab, 0x05, 0x0e, 0xaf, 0x6c, 0x26, 0xdc, 0x2a, 0x8c, 0x89, 0x0f, 0xfe, 0xc4, 0x1b, 0x63, 0x15, + 0xec, 0x3c, 0x8c, 0x43, 0x11, 0x9b, 0x1a, 0x26, 0x07, 0x55, 0x1a, 0x78, 0x62, 0x69, 0x02, 0xa4, + 0x67, 0x36, 0x91, 0xd5, 0xe3, 0xed, 0x28, 0x22, 0xb2, 0xd0, 0x4e, 0xae, 0x92, 0x56, 0xc8, 0x2a, + 0x0a, 0x7d, 0x9e, 0x52, 0x4f, 0x15, 0xd5, 0xa4, 0x90, 0x0b, 0x2b, 0xc9, 0x12, 0x65, 0x61, 0x67, + 0xb9, 0x6c, 0x26, 0x28, 0xd3, 0x30, 0xb6, 0x1e, 0xbf, 0xa1, 0x5c, 0xa5, 0x50, 0xf0, 0x69, 0x8c, + 0xbd, 0xce, 0xad, 0xed, 0x61, 0x65, 0x11, 0xf9, 0x2b, 0xb3, 0x76, 0xfd, 0x95, 0x81, 0x9a, 0xbc, + 0x63, 0xc6, 0xb8, 0xae, 0xfd, 0xee, 0xdd, 0xe6, 0xfa, 0x12, 0x93, 0xdc, 0xfd, 0xd6, 0xe1, 0xc9, + 0x51, 0x8d, 0xbd, 0x88, 0xe8, 0x64, 0x8e, 0x43, 0xb4, 0xea, 0x11, 0x04, 0x3c, 0xb7, 0xe4, 0x53, + 0x3c, 0x5a, 0x00, 0x0c, 0x5c, 0xb7, 0xfb, 0x31, 0x98, 0xdc, 0xc5, 0xf5, 0xba, 0x45, 0xcf, 0xe2, + 0x73, 0x97, 0xac, 0xb5, 0xba, 0x5d, 0x04, 0x51, 0x6a, 0xdd, 0xcd, 0x05, 0x4f, 0x8c, 0xe8, 0xcf, + 0x00, 0xfd, 0x90, 0xc3, 0x93, 0xc5, 0x67, 0x29, 0x94, 0x99, 0xfe, 0xb2, 0x90, 0x1b, 0xac, 0xd7, + 0x52, 0xd0, 0x0d, 0xcd, 0x05, 0x1c, 0xaf, 0x78, 0xa7, 0xaa, 0x0c, 0x1f, 0xee, 0x1f, 0xa4, 0xab, + 0x4d, 0x33, 0xff, 0x4a, 0x69, 0xba, 0xc9, 0x1f, 0xa3, 0x52, 0x2f, 0x4b, 0x2c, 0x0d, 0x63, 0xf3, + 0xe1, 0xe4, 0x54, 0xd9, 0x64, 0x69, 0x0f, 0x4c, 0x81, 0x57, 0xb0, 0xa8, 0xd2, 0x5f, 0xf8, 0x96, + 0xca, 0x80, 0xbd, 0xa3, 0xe2, 0xe8, 0xac, 0xa2, 0x66, 0x04, 0xfa, 0x93, 0x58, 0x74, 0xb0, 0x37, + 0x70, 0x0f, 0xb9, 0xa5, 0x9e, 0x74, 0xdc, 0x68, 0x75, 0xbb, 0xec, 0x1d, 0xb3, 0xd8, 0xfc, 0xd1, + 0x9c, 0x62, 0xd3, 0xf8, 0xd4, 0xda, 0xad, 0x1f, 0x7e, 0xdb, 0x3b, 0x3e, 0xd9, 0xff, 0xfb, 0x5e, + 0xfd, 0xc3, 0xc9, 0x69, 0xdd, 0x00, 0xcf, 0x4b, 0xc1, 0xfc, 0x65, 0xe1, 0xd4, 0x93, 0x2c, 0x42, + 0x7e, 0x3a, 0x77, 0x63, 0x14, 0xe6, 0xfc, 0xdb, 0xb8, 0xcf, 0x13, 0xdd, 0xee, 0x75, 0xbb, 0xed, + 0xee, 0xe3, 0x63, 0x08, 0xbd, 0x54, 0x46, 0xd7, 0xf0, 0xe2, 0xe0, 0x42, 0x70, 0x3e, 0x17, 0xf7, + 0x63, 0x8d, 0x6d, 0x8b, 0x70, 0xbc, 0xcf, 0x2e, 0x30, 0xc9, 0xbf, 0x05, 0xee, 0x8f, 0x26, 0x46, + 0x7b, 0x58, 0xf9, 0x41, 0x22, 0x9b, 0xd9, 0x91, 0xee, 0x81, 0x1c, 0x20, 0x05, 0x91, 0xc8, 0x1e, + 0x88, 0x79, 0x5a, 0x79, 0x5b, 0x51, 0x66, 0x19, 0x0a, 0x53, 0xf3, 0x11, 0x41, 0x23, 0xc4, 0x0a, + 0xdb, 0x16, 0x78, 0x28, 0xf6, 0xa3, 0xb3, 0xe6, 0x39, 0x9f, 0x35, 0x24, 0xdb, 0x32, 0x39, 0xb3, + 0x13, 0xb5, 0xfb, 0xe3, 0x77, 0x6e, 0xd8, 0x1f, 0x4b, 0x3b, 0xd0, 0x07, 0xf7, 0xec, 0x07, 0x70, + 0xe9, 0x89, 0xce, 0xc6, 0x75, 0x1b, 0xc2, 0x9f, 0x61, 0x73, 0xfc, 0x86, 0xd7, 0x3b, 0xef, 0x47, + 0x67, 0x63, 0xde, 0x5a, 0xa3, 0xd1, 0x78, 0xc8, 0x0c, 0x85, 0xd8, 0x77, 0x64, 0x69, 0xa1, 0xe5, + 0xb5, 0x77, 0x9f, 0x12, 0x2d, 0x68, 0xb3, 0x7a, 0x63, 0x6a, 0xf1, 0x32, 0x49, 0xf3, 0x95, 0x0c, + 0xd0, 0xad, 0xf5, 0x18, 0x5c, 0x09, 0x81, 0x05, 0x13, 0xbc, 0xf2, 0x2c, 0x10, 0x4b, 0xa2, 0xde, + 0x9e, 0x59, 0xb0, 0xa6, 0x2a, 0x1f, 0x67, 0xef, 0xd2, 0xcc, 0xf5, 0x35, 0xcb, 0xf5, 0xbc, 0x72, + 0xe9, 0x92, 0xe1, 0x82, 0xa5, 0x93, 0xb6, 0x42, 0x85, 0x01, 0xd2, 0x6c, 0x80, 0x44, 0xfd, 0x12, + 0x0b, 0xa8, 0x0f, 0x2d, 0xcb, 0xd1, 0x97, 0x3d, 0x1b, 0x71, 0xf6, 0x84, 0x15, 0x91, 0x76, 0xae, + 0x5c, 0xda, 0x37, 0xc9, 0x9c, 0x8f, 0xc7, 0x99, 0xe3, 0xf1, 0x4d, 0xf6, 0xb3, 0x20, 0xc2, 0x93, + 0xc2, 0x3a, 0x27, 0x46, 0xcc, 0x38, 0xdf, 0x49, 0x79, 0x89, 0x10, 0xf1, 0xa9, 0x42, 0x1c, 0xca, + 0x93, 0x53, 0x88, 0xc4, 0x46, 0x19, 0xff, 0x31, 0x8d, 0x4d, 0xca, 0x48, 0xbb, 0xd5, 0xf1, 0x72, + 0x98, 0x84, 0xd2, 0xea, 0xff, 0xa4, 0x30, 0xaf, 0xb0, 0x6c, 0x8e, 0xab, 0xfc, 0x44, 0x23, 0x6d, + 0x79, 0xcd, 0xd1, 0x9b, 0xc4, 0x7a, 0xbb, 0x09, 0x5b, 0x18, 0xaf, 0xa7, 0xeb, 0x11, 0x1a, 0xca, + 0x37, 0x3b, 0x8c, 0xfb, 0x71, 0x60, 0x58, 0x43, 0x97, 0x1d, 0x72, 0x1f, 0x4d, 0xc1, 0x90, 0x4d, + 0x06, 0x5d, 0xe2, 0xf9, 0xc9, 0x10, 0xf2, 0xd9, 0x16, 0x83, 0xfc, 0xa4, 0x54, 0xe2, 0x02, 0x1e, + 0xd6, 0x4b, 0x63, 0x2f, 0xba, 0x80, 0x67, 0x27, 0xa1, 0x30, 0xa9, 0x0e, 0xca, 0xf4, 0x3f, 0x39, + 0x00, 0x14, 0x6a, 0x62, 0x7d, 0x03, 0x56, 0x62, 0x9d, 0xfc, 0x4f, 0x3e, 0x9b, 0xb1, 0xee, 0xa8, + 0x9c, 0x1d, 0xa2, 0x07, 0xb7, 0xd9, 0x7f, 0x78, 0x87, 0xfb, 0x0f, 0xf2, 0x0c, 0x5d, 0x69, 0xe5, + 0xd2, 0xac, 0xdc, 0xb1, 0xdb, 0xec, 0x1f, 0xbf, 0x4b, 0xfb, 0xc7, 0xb2, 0xdc, 0x9d, 0x1b, 0xad, + 0x9b, 0xc7, 0x6f, 0x1e, 0xd6, 0x53, 0x0b, 0xbd, 0x07, 0x77, 0x50, 0xc9, 0x22, 0xdd, 0xa1, 0xbb, + 0x37, 0x91, 0xd5, 0xbf, 0x3a, 0x3b, 0x3e, 0x77, 0x7f, 0x33, 0x5f, 0x27, 0xe6, 0x7b, 0x0b, 0x1e, + 0x92, 0x19, 0x9f, 0x3d, 0x9c, 0xbb, 0x57, 0x99, 0xab, 0x7b, 0xc6, 0x23, 0xeb, 0xf6, 0xcf, 0x4f, + 0x12, 0x29, 0x1b, 0x19, 0x79, 0x6f, 0x5a, 0xe5, 0x57, 0x87, 0xf4, 0x98, 0x3f, 0x69, 0xe6, 0x43, + 0xaf, 0x2b, 0x9b, 0x31, 0xbc, 0x16, 0xa6, 0x3d, 0x45, 0x07, 0xe5, 0xb8, 0xa5, 0x5f, 0x5a, 0x14, + 0x48, 0xf4, 0x95, 0x10, 0x55, 0xa8, 0x4d, 0x85, 0xcd, 0xa0, 0x74, 0xee, 0x36, 0xc3, 0x12, 0x7d, + 0x08, 0xb4, 0xb5, 0xe0, 0x3a, 0x02, 0x3c, 0xf4, 0xa6, 0x91, 0x22, 0xd6, 0xe5, 0xa8, 0xb5, 0x40, + 0x44, 0x25, 0x26, 0x82, 0x42, 0x40, 0x0d, 0xdf, 0x4d, 0xc1, 0x64, 0xad, 0x05, 0x96, 0x43, 0x23, + 0x37, 0x36, 0xfd, 0xb3, 0xe6, 0x39, 0xc3, 0x9b, 0xa6, 0x7f, 0x66, 0x9f, 0x67, 0x87, 0xd6, 0x1c, + 0x71, 0xab, 0x41, 0xcb, 0x9a, 0x23, 0xfe, 0xc0, 0x57, 0x45, 0x17, 0x54, 0xbc, 0xfd, 0xf5, 0xe1, + 0xe4, 0x74, 0x30, 0x83, 0x33, 0xa2, 0x25, 0xcc, 0x9d, 0xd9, 0x1c, 0xf9, 0x55, 0xa3, 0x00, 0xdb, + 0x4b, 0x34, 0xe2, 0xe3, 0xb0, 0x11, 0xb7, 0xf0, 0x37, 0x47, 0x30, 0x8e, 0xac, 0xf7, 0xc8, 0x9a, + 0x6b, 0x8c, 0x17, 0x40, 0xb1, 0xec, 0xd3, 0x91, 0x2e, 0x3b, 0x7f, 0xca, 0xb9, 0x83, 0xa3, 0x02, + 0xa2, 0x3d, 0x29, 0x12, 0x32, 0x6f, 0x3b, 0x2b, 0xdb, 0x14, 0xe1, 0x32, 0x97, 0xd6, 0x65, 0x2d, + 0xaa, 0xe1, 0xc6, 0x6c, 0xd9, 0xc5, 0x4a, 0x70, 0xf6, 0x52, 0x87, 0x13, 0xb3, 0x94, 0xe5, 0x0c, + 0x71, 0x25, 0x44, 0x66, 0x13, 0x27, 0x40, 0x63, 0xc7, 0x66, 0x78, 0xc6, 0x03, 0xef, 0xd7, 0x4c, + 0x06, 0x21, 0xa1, 0x74, 0xd6, 0x3c, 0x07, 0x2d, 0x26, 0xb7, 0xa8, 0x7e, 0x9d, 0x20, 0x8f, 0xa0, + 0x83, 0xb8, 0xc2, 0x90, 0xfa, 0x75, 0xe2, 0x06, 0xb4, 0xef, 0xb1, 0xe7, 0xd5, 0xd8, 0xbb, 0x8f, + 0x72, 0x40, 0x75, 0x23, 0x17, 0xc3, 0xf0, 0x67, 0x3d, 0x0e, 0x04, 0x8b, 0xaa, 0xb0, 0x5c, 0x47, + 0x32, 0x49, 0xee, 0x8e, 0xc6, 0x61, 0x3c, 0x25, 0xad, 0x1c, 0xea, 0x2c, 0x98, 0xef, 0xcc, 0xe0, + 0xed, 0x36, 0x9d, 0xcf, 0xfc, 0xa2, 0x05, 0x8a, 0x60, 0x5d, 0xa2, 0xd9, 0x91, 0x43, 0x99, 0xe3, + 0xb6, 0x13, 0x57, 0xf0, 0xe8, 0x89, 0xde, 0x51, 0x9a, 0xd3, 0xcc, 0x84, 0x73, 0x66, 0xed, 0x1c, + 0x33, 0x24, 0xc7, 0x04, 0x3b, 0x06, 0xc3, 0xc7, 0x01, 0xb7, 0x9b, 0x35, 0xee, 0x99, 0x88, 0x67, + 0x21, 0x2d, 0x0b, 0x5d, 0x0a, 0x82, 0x02, 0xe2, 0x7c, 0x82, 0xa6, 0x65, 0xe4, 0x06, 0x83, 0x56, + 0xb7, 0xeb, 0x74, 0x3a, 0x9b, 0x10, 0x0a, 0x66, 0xd0, 0x6e, 0x39, 0xdd, 0x1e, 0x9a, 0x4a, 0x56, + 0x33, 0x18, 0x6c, 0x39, 0x5d, 0x70, 0x2f, 0x55, 0xdf, 0x76, 0xcb, 0xee, 0xf5, 0xba, 0x4e, 0x7b, + 0xab, 0xb9, 0x69, 0xb3, 0xa8, 0x33, 0x83, 0x3b, 0xba, 0xbe, 0x2e, 0xd9, 0xd4, 0x6e, 0xc7, 0x72, + 0xb4, 0xef, 0x4e, 0x67, 0x83, 0x45, 0xa1, 0x19, 0x28, 0xce, 0x75, 0x3d, 0x57, 0xda, 0xb6, 0xea, + 0x1f, 0xb1, 0xa3, 0xbc, 0x16, 0xd7, 0x73, 0x55, 0xbb, 0x90, 0x09, 0x81, 0x4d, 0xdf, 0x3c, 0xbc, + 0xf9, 0x88, 0xd1, 0xb1, 0x7b, 0x0a, 0x0e, 0xc4, 0xa7, 0xc0, 0x78, 0xdf, 0xb9, 0xef, 0xcd, 0xa9, + 0xfe, 0xb0, 0x89, 0x79, 0x9a, 0xa9, 0x0f, 0xa8, 0x79, 0x6c, 0x9e, 0x5a, 0x28, 0xd2, 0x96, 0xe0, + 0x1a, 0xf2, 0xb9, 0xa1, 0xd8, 0x6b, 0xd3, 0x98, 0xea, 0xd6, 0x39, 0xe8, 0x14, 0x45, 0x6a, 0xab, + 0x05, 0x60, 0x42, 0x73, 0xd6, 0xb6, 0xcf, 0xd7, 0x5c, 0xbb, 0xb5, 0x61, 0xa1, 0x63, 0x50, 0xeb, + 0xec, 0xe4, 0x3c, 0xfd, 0xb4, 0x9e, 0x08, 0x36, 0x13, 0x30, 0x93, 0x11, 0xc6, 0xdd, 0xac, 0x25, + 0x2b, 0x27, 0xed, 0x3c, 0x45, 0x3b, 0xbc, 0xdf, 0xaf, 0xee, 0xa1, 0x79, 0x6d, 0xee, 0x58, 0x08, + 0xea, 0x33, 0xf2, 0xf0, 0xab, 0xeb, 0xba, 0x3f, 0x2e, 0xe1, 0x3b, 0xa4, 0x06, 0x08, 0x2c, 0x25, + 0x99, 0xa0, 0x8a, 0x3d, 0x9e, 0x9c, 0x62, 0x1f, 0x87, 0xb7, 0xba, 0x66, 0xea, 0xbd, 0xf9, 0xd5, + 0xd2, 0x85, 0xa2, 0xd9, 0xf0, 0xa0, 0xfb, 0x3b, 0x4b, 0x97, 0x80, 0x9e, 0xa2, 0x1d, 0xf4, 0x95, + 0x0f, 0xe8, 0x17, 0xf7, 0xd8, 0x3c, 0x5d, 0x37, 0x77, 0xea, 0x5f, 0x33, 0x71, 0xdc, 0x8e, 0x7b, + 0x6c, 0xee, 0xd4, 0x7f, 0x01, 0x05, 0xc6, 0xb1, 0xf9, 0xf5, 0xcd, 0x2f, 0x16, 0x9a, 0xdd, 0x5f, + 0xb4, 0x9c, 0x1d, 0x74, 0x7f, 0xd1, 0x76, 0xbe, 0xea, 0x01, 0x54, 0xf8, 0xc4, 0xc0, 0xc0, 0x6a, + 0x0a, 0xd3, 0xfe, 0x91, 0x49, 0x43, 0xe0, 0x53, 0x82, 0x62, 0x07, 0x8d, 0x21, 0x48, 0x10, 0x9f, + 0xfa, 0x0e, 0xfa, 0xc5, 0x3d, 0x45, 0x7f, 0x77, 0x3f, 0x62, 0xf4, 0xbb, 0xfb, 0x23, 0x46, 0x3f, + 0xbb, 0x20, 0xe7, 0x86, 0xcf, 0x14, 0xbb, 0x3f, 0x62, 0x85, 0x95, 0x6e, 0x94, 0x1c, 0x64, 0x54, + 0xb7, 0xad, 0xfe, 0x0d, 0xde, 0x86, 0xdc, 0x1b, 0x5c, 0xaf, 0x8b, 0x28, 0xbf, 0xd4, 0xfd, 0xba, + 0xbd, 0x7d, 0x83, 0xd7, 0x3e, 0x82, 0x4d, 0xe8, 0xbf, 0xba, 0x17, 0x94, 0x0f, 0xf0, 0xef, 0x6c, + 0x80, 0x3f, 0xcf, 0xdd, 0x8f, 0x66, 0x8a, 0xd1, 0xdf, 0xd1, 0xcf, 0x62, 0xe0, 0xbf, 0xb3, 0x74, + 0x8c, 0x45, 0xc6, 0xef, 0x08, 0x63, 0x26, 0xb2, 0xbf, 0xa0, 0x5c, 0x32, 0x49, 0xdd, 0xbf, 0xbf, + 0xf9, 0x1d, 0xed, 0x53, 0xf7, 0xd8, 0xfc, 0x4c, 0xd7, 0x3f, 0x53, 0x0b, 0xdd, 0x50, 0xf7, 0xef, + 0xf5, 0xdf, 0xd1, 0x47, 0xe2, 0x1e, 0x9b, 0x37, 0x74, 0xfd, 0x86, 0x5a, 0xe8, 0x13, 0x71, 0xf7, + 0x69, 0xfd, 0x23, 0x41, 0xbb, 0x89, 0xfb, 0xf3, 0x1b, 0x8c, 0xd1, 0x7d, 0xe2, 0xfe, 0x5c, 0xc7, + 0x18, 0xfd, 0x06, 0x85, 0xee, 0x13, 0x56, 0xef, 0x1b, 0xfc, 0xde, 0x4d, 0x58, 0x85, 0x5f, 0x88, + 0xfb, 0x1b, 0x79, 0xf3, 0x8d, 0xa0, 0x9f, 0xe0, 0x47, 0xfd, 0x1b, 0xe9, 0xff, 0xec, 0x1e, 0x9b, + 0xbf, 0x90, 0xf5, 0x5f, 0x08, 0x53, 0x22, 0x1c, 0x9b, 0xbf, 0xac, 0x1f, 0x9b, 0x3f, 0x91, 0xf5, + 0x9f, 0xc0, 0x6f, 0xfa, 0xef, 0xee, 0xb1, 0xb9, 0x4f, 0xd7, 0x3f, 0x12, 0xd0, 0x4a, 0x1c, 0x9b, + 0x9f, 0xc8, 0xba, 0xb9, 0x4f, 0xdf, 0x1c, 0x9b, 0xc3, 0xf5, 0x4f, 0x10, 0x9a, 0x7d, 0x6e, 0x2e, + 0x98, 0xe1, 0x92, 0x29, 0x4a, 0x75, 0x42, 0x6a, 0x66, 0x26, 0x2d, 0xc7, 0xe6, 0xdf, 0xd7, 0xc1, + 0x8e, 0x05, 0xb2, 0xf6, 0x74, 0x89, 0x7f, 0xa4, 0x09, 0xd8, 0x23, 0x2e, 0xe3, 0x8f, 0xe6, 0xe8, + 0xd6, 0x35, 0xc1, 0xf8, 0x26, 0xb2, 0xc0, 0xfb, 0xf7, 0x27, 0xf3, 0x14, 0xed, 0x71, 0x29, 0x3f, + 0x3a, 0xd5, 0x0e, 0xdd, 0xe7, 0xec, 0x50, 0xdd, 0x9a, 0xa7, 0x15, 0xc2, 0xfb, 0x1d, 0xad, 0xed, + 0x0f, 0xe6, 0x8e, 0x32, 0xb8, 0x97, 0x52, 0xd8, 0xcf, 0x20, 0x85, 0x3d, 0x19, 0x79, 0x29, 0x16, + 0x22, 0x73, 0x87, 0xed, 0x2b, 0x77, 0x9b, 0x1f, 0x9c, 0xbc, 0x8c, 0xf6, 0xd4, 0xdd, 0x86, 0xcd, + 0x2d, 0x14, 0x6f, 0x07, 0xd3, 0x88, 0x3a, 0x37, 0xda, 0xc7, 0x7b, 0x8f, 0x60, 0xe7, 0x83, 0x90, + 0xdb, 0xce, 0x8a, 0xa2, 0xf9, 0xdb, 0xb2, 0x58, 0xf9, 0x76, 0x8e, 0x7e, 0x98, 0x72, 0xac, 0x7a, + 0x27, 0x18, 0x14, 0x4b, 0x89, 0x79, 0xf7, 0xf8, 0x1d, 0xf3, 0x23, 0x46, 0x1f, 0x31, 0xba, 0xa3, + 0xe8, 0x6b, 0xd5, 0x35, 0xf3, 0xa3, 0x2e, 0xb6, 0xfb, 0x88, 0x35, 0xb9, 0xdd, 0x1d, 0xcd, 0xe4, + 0x76, 0xe2, 0xf1, 0x98, 0xdf, 0x21, 0x72, 0x49, 0x7f, 0x2f, 0x31, 0x7f, 0x8f, 0xd1, 0x6c, 0xef, + 0x03, 0xc3, 0xdd, 0x17, 0xa7, 0x87, 0xc7, 0x27, 0xfb, 0x87, 0x5f, 0x2e, 0x4e, 0xbe, 0xbe, 0xff, + 0xe1, 0xf8, 0xf0, 0xeb, 0x91, 0x03, 0x3d, 0x0c, 0x53, 0x74, 0x1c, 0x12, 0x9a, 0x62, 0x4a, 0x13, + 0x2e, 0xe9, 0x84, 0xd4, 0x69, 0x8a, 0x70, 0xc0, 0x6a, 0xb1, 0x4f, 0x0f, 0xcb, 0xcf, 0x0b, 0xa6, + 0x31, 0x4e, 0x79, 0x21, 0x22, 0x53, 0x7d, 0x7a, 0xcf, 0x52, 0x7e, 0x4f, 0x64, 0xca, 0x64, 0xc4, + 0x12, 0xfe, 0x0a, 0x09, 0xcc, 0x54, 0xfd, 0x54, 0x13, 0xe6, 0xb3, 0xac, 0x51, 0x5a, 0x95, 0x05, + 0x20, 0x63, 0xd9, 0x51, 0x75, 0x36, 0x44, 0x86, 0xb0, 0xdc, 0xed, 0xbf, 0xc5, 0x79, 0x1a, 0x89, + 0x25, 0x8e, 0x53, 0x9d, 0x32, 0x63, 0x49, 0x13, 0x99, 0xa4, 0xe6, 0x08, 0xb7, 0x0f, 0xe4, 0x3c, + 0xf0, 0x9c, 0x0b, 0x9a, 0x5c, 0xa4, 0xc5, 0xbc, 0xbb, 0x14, 0x95, 0xd2, 0x82, 0x7c, 0x9a, 0x0e, + 0x87, 0x09, 0x41, 0xf7, 0x19, 0xac, 0x7e, 0x4d, 0xf4, 0x4b, 0xff, 0x27, 0xed, 0x36, 0x96, 0x2b, + 0x06, 0x26, 0xb9, 0x6a, 0xc5, 0xe0, 0xdd, 0x21, 0xe5, 0x48, 0xcf, 0x24, 0xf0, 0xf2, 0xf2, 0x82, + 0x37, 0x83, 0xdc, 0x3b, 0xb8, 0x80, 0xc9, 0x3a, 0xf9, 0x4b, 0x0a, 0xff, 0x43, 0x5c, 0x60, 0x6c, + 0x06, 0xe8, 0x1a, 0xe2, 0x33, 0xae, 0x07, 0x7f, 0x49, 0x81, 0xa2, 0xc4, 0xa6, 0x8f, 0x86, 0x18, + 0x12, 0xa0, 0x04, 0x30, 0xe4, 0xe6, 0x08, 0xfd, 0x12, 0x43, 0xc2, 0xe8, 0x2f, 0x29, 0xb0, 0xe4, + 0xd8, 0x8c, 0x10, 0x2b, 0x10, 0xfd, 0x25, 0x45, 0x43, 0xf8, 0x9e, 0x22, 0xd6, 0xc2, 0xf4, 0x2f, + 0x29, 0x02, 0x6e, 0xc2, 0x1c, 0x22, 0x56, 0x7e, 0xf8, 0x97, 0x14, 0x3d, 0xc0, 0xf7, 0x98, 0x3d, + 0x51, 0xb4, 0x3e, 0xfe, 0x4b, 0x8a, 0x80, 0x8b, 0x60, 0xc6, 0x30, 0xe2, 0xfb, 0x18, 0xbe, 0xaf, + 0x54, 0x7b, 0xf2, 0x1c, 0x4e, 0x92, 0xbb, 0x8b, 0xc9, 0x45, 0xf7, 0x62, 0xd3, 0x89, 0xb1, 0x79, + 0x2c, 0x46, 0x08, 0x03, 0xba, 0x6a, 0x39, 0x81, 0x86, 0xcc, 0x5f, 0xeb, 0xb1, 0x46, 0xc9, 0x59, + 0xf3, 0x7c, 0xcd, 0x6d, 0x75, 0x36, 0x11, 0x51, 0xd7, 0x20, 0xff, 0xf9, 0xe8, 0xf6, 0x3a, 0x7a, + 0xc8, 0xa9, 0x11, 0xd1, 0xa5, 0x52, 0x77, 0x10, 0xc8, 0xe8, 0x37, 0x13, 0xaf, 0xe3, 0x75, 0x11, + 0xc8, 0xe8, 0x37, 0x33, 0x5e, 0x8f, 0xf9, 0x47, 0xea, 0x02, 0xd0, 0xd7, 0x13, 0xd0, 0xea, 0x8b, + 0x31, 0xa1, 0x10, 0x02, 0x24, 0xae, 0xc7, 0xeb, 0x29, 0x14, 0x08, 0x58, 0xd5, 0x70, 0x3d, 0x84, + 0x0f, 0xdf, 0x0d, 0xd1, 0xc8, 0xfd, 0xcd, 0x0c, 0xd7, 0x43, 0x16, 0xe6, 0x2a, 0x62, 0xde, 0xdc, + 0x44, 0x78, 0x75, 0xff, 0x66, 0xd6, 0x59, 0xea, 0x50, 0x7d, 0xf1, 0x62, 0x4a, 0xe9, 0xcf, 0xe2, + 0xdd, 0xf8, 0x16, 0x32, 0xa7, 0x8f, 0x8f, 0x10, 0x1e, 0xc5, 0x0c, 0xdd, 0x91, 0x85, 0xc6, 0xd8, + 0x84, 0xc6, 0xd9, 0xe7, 0x6f, 0x66, 0x1d, 0x7e, 0x6b, 0xa6, 0xbe, 0xd1, 0xe3, 0xe3, 0x54, 0x58, + 0xfb, 0xea, 0x5e, 0xec, 0x7f, 0xcf, 0x79, 0x8f, 0x2e, 0x95, 0x08, 0x08, 0x63, 0x12, 0x30, 0xbd, + 0xa1, 0x49, 0x02, 0xf4, 0x71, 0x76, 0x43, 0x73, 0xc9, 0xd2, 0x49, 0x78, 0xbd, 0xc7, 0x4f, 0x62, + 0x2d, 0x4e, 0x6a, 0xf2, 0xa7, 0x9f, 0x44, 0x51, 0x08, 0x52, 0x68, 0xf0, 0xf4, 0x2c, 0x88, 0xf6, + 0xce, 0xe8, 0xc0, 0x76, 0x9a, 0x4a, 0x08, 0x72, 0x6e, 0x21, 0x8c, 0x74, 0xb7, 0x7f, 0x9a, 0x66, + 0x3b, 0xd9, 0xbc, 0xc3, 0xf5, 0x5f, 0x62, 0xeb, 0xed, 0x90, 0x64, 0x3b, 0xb9, 0xb3, 0xd9, 0xeb, + 0xf5, 0x5a, 0xb0, 0x9b, 0xef, 0x99, 0x4b, 0x0c, 0x01, 0x77, 0xaf, 0x7b, 0x11, 0x93, 0xeb, 0x9a, + 0x4a, 0x5f, 0xb4, 0x7b, 0xc6, 0xe5, 0xc4, 0xe8, 0x5e, 0x46, 0x9c, 0xba, 0x17, 0xa1, 0x2b, 0x50, + 0x28, 0x2a, 0xb2, 0x60, 0x89, 0xf7, 0x22, 0xbc, 0x15, 0x73, 0xca, 0x97, 0xad, 0x50, 0xab, 0x2f, + 0x3f, 0x7c, 0x94, 0xf2, 0x1c, 0x68, 0xcd, 0xe7, 0x7c, 0x56, 0x96, 0x23, 0x98, 0x7e, 0xde, 0x1e, + 0xf3, 0xb0, 0xe3, 0x3f, 0x47, 0xc0, 0x06, 0xdd, 0x8b, 0x28, 0x86, 0x81, 0xfe, 0xe1, 0xf3, 0xfe, + 0x79, 0xa7, 0x23, 0x19, 0xe4, 0xee, 0x9e, 0xc5, 0xca, 0x0a, 0x99, 0x2f, 0xb7, 0xc8, 0x8d, 0x64, + 0xee, 0x54, 0x25, 0x7c, 0x8c, 0xb3, 0x1e, 0x22, 0xbd, 0x9d, 0x40, 0x86, 0x60, 0xba, 0x17, 0x7e, + 0x3d, 0x3e, 0x90, 0xb0, 0xf7, 0x3c, 0xb0, 0xe1, 0x14, 0x45, 0x10, 0x52, 0xe4, 0x41, 0x94, 0x4e, + 0xc1, 0xa5, 0xe9, 0x4a, 0xb5, 0x49, 0xac, 0xbe, 0xfc, 0xb8, 0x42, 0x38, 0x95, 0x51, 0xea, 0x64, + 0xca, 0xc7, 0x18, 0xa8, 0x52, 0x39, 0x61, 0xad, 0xff, 0xab, 0x8a, 0xfe, 0xdf, 0xab, 0xfe, 0xef, + 0xc0, 0x00, 0x50, 0xf4, 0x7f, 0x8c, 0xae, 0xd0, 0xfb, 0xac, 0xe2, 0xb8, 0xa2, 0xe2, 0x85, 0x3e, + 0xf0, 0x1b, 0x59, 0xf1, 0x01, 0xa5, 0xe0, 0x45, 0xf0, 0x41, 0x7e, 0x5f, 0xa3, 0x31, 0x7c, 0x7f, + 0x74, 0xef, 0x45, 0x3c, 0x92, 0x0f, 0x6a, 0x2f, 0xaa, 0x32, 0x1f, 0x10, 0x5f, 0xe6, 0x0f, 0x16, + 0xba, 0x78, 0xe5, 0xba, 0x1f, 0x81, 0x9e, 0x38, 0x00, 0xc5, 0xe8, 0xfd, 0x41, 0xe0, 0x24, 0xe8, + 0xe1, 0x20, 0x06, 0x77, 0x92, 0x83, 0xc0, 0x19, 0x62, 0xed, 0x44, 0xc4, 0x72, 0xcb, 0xb1, 0xc2, + 0x98, 0x15, 0xa6, 0xac, 0x70, 0xcc, 0x0a, 0x83, 0x97, 0x53, 0xca, 0x75, 0x64, 0xf7, 0x2a, 0x00, + 0x67, 0x3f, 0x55, 0x10, 0x25, 0xa9, 0xf4, 0x8c, 0xe7, 0x29, 0x94, 0x3b, 0xfd, 0xde, 0xb3, 0x00, + 0x9c, 0x98, 0x9f, 0x7e, 0xbe, 0x83, 0xd8, 0xc7, 0x48, 0xcd, 0x9f, 0xb1, 0xc8, 0x7c, 0xee, 0x23, + 0x74, 0xcf, 0xa5, 0x04, 0xac, 0x5d, 0x36, 0x99, 0x54, 0x24, 0x21, 0xb1, 0xd8, 0x2c, 0x31, 0xe4, + 0x3b, 0x1a, 0xd2, 0x02, 0x99, 0x16, 0x64, 0x69, 0xbe, 0x4c, 0xf3, 0x55, 0x1a, 0x0c, 0xed, 0x6c, + 0x8a, 0x86, 0xe7, 0x10, 0x23, 0xe4, 0x1e, 0x9d, 0x85, 0xc8, 0x3f, 0x07, 0x25, 0x6c, 0xe6, 0x61, + 0x23, 0xe7, 0x31, 0xb5, 0xd0, 0x83, 0xf8, 0x08, 0xd0, 0x50, 0xb7, 0x4a, 0xf8, 0x4d, 0x5e, 0x2f, + 0xb3, 0xc0, 0xc1, 0x73, 0x17, 0x43, 0xf0, 0x56, 0x86, 0x1c, 0xef, 0xdc, 0xed, 0x7b, 0x29, 0x06, + 0xbc, 0x63, 0x4f, 0x1e, 0x9a, 0x3e, 0x59, 0x27, 0xeb, 0x0c, 0x58, 0xb1, 0x69, 0x26, 0x6f, 0x86, + 0xd8, 0x5a, 0xf7, 0x52, 0x2d, 0x1a, 0x07, 0x44, 0xea, 0x08, 0x20, 0x2f, 0xac, 0xe3, 0xf5, 0xc4, + 0x5a, 0x8f, 0xcd, 0xe4, 0x0d, 0xd6, 0xf1, 0x96, 0x2f, 0x90, 0xd6, 0x68, 0xee, 0x8e, 0x80, 0x49, + 0x0e, 0x84, 0x20, 0x61, 0x9d, 0x40, 0xf8, 0x16, 0x33, 0x42, 0xd4, 0x62, 0x91, 0x90, 0x62, 0xb3, + 0x1e, 0x81, 0xb8, 0xf8, 0xf1, 0xd1, 0x1c, 0xb9, 0x11, 0xff, 0x11, 0xba, 0x89, 0x3c, 0x36, 0xb1, + 0x19, 0xae, 0x9b, 0x49, 0x1d, 0xfa, 0x0f, 0xd3, 0x7a, 0x00, 0xc8, 0x75, 0xb4, 0x3e, 0x82, 0x7b, + 0x08, 0x84, 0x70, 0x23, 0x6b, 0x3d, 0x80, 0x53, 0x11, 0x9b, 0xd3, 0x75, 0x78, 0xda, 0xf3, 0xca, + 0x8d, 0xcd, 0x21, 0xae, 0x0f, 0x21, 0x24, 0x28, 0xfc, 0x7a, 0x33, 0xcc, 0x19, 0x4e, 0x7b, 0x42, + 0x91, 0x6b, 0xc6, 0xe6, 0x78, 0xfd, 0xd8, 0x42, 0xb1, 0x79, 0xb5, 0xfe, 0x00, 0xff, 0x3c, 0xf0, + 0xaf, 0xf1, 0xfa, 0x55, 0x2e, 0x1e, 0x3c, 0x83, 0xd7, 0x4f, 0x26, 0x41, 0xbd, 0x8e, 0x0c, 0xf9, + 0x19, 0x80, 0x20, 0x48, 0x33, 0x0b, 0x68, 0xb7, 0x20, 0x7a, 0x93, 0xfb, 0x1b, 0x93, 0x09, 0xc7, + 0x85, 0xec, 0x76, 0x0b, 0x6a, 0xb2, 0x1b, 0x07, 0xdc, 0x38, 0xf5, 0xa1, 0x84, 0xd8, 0xa4, 0xd2, + 0x17, 0x59, 0x0b, 0x2e, 0xae, 0xdf, 0x77, 0x1e, 0x6e, 0x30, 0x92, 0xb1, 0x91, 0x33, 0xca, 0xe0, + 0xf6, 0x47, 0x06, 0xca, 0x45, 0xbe, 0x8f, 0xd2, 0x55, 0xf5, 0x84, 0x49, 0x84, 0x5e, 0x9b, 0x3d, + 0xd2, 0x9d, 0x00, 0x35, 0x70, 0x4d, 0xd1, 0xb7, 0x18, 0xa8, 0x80, 0x21, 0x41, 0x77, 0x18, 0x61, + 0x8a, 0x42, 0x82, 0xee, 0xd1, 0x0f, 0x31, 0x8a, 0x08, 0xf2, 0x30, 0xfa, 0x3d, 0x41, 0x7f, 0x4d, + 0xd0, 0xaf, 0x09, 0xfa, 0x31, 0x41, 0x18, 0xac, 0x23, 0x11, 0x49, 0xd1, 0x94, 0x20, 0x9f, 0xa0, + 0x24, 0x45, 0x69, 0x8a, 0xbc, 0x14, 0x85, 0x29, 0xfa, 0x14, 0x23, 0x3f, 0x45, 0x01, 0x41, 0x21, + 0x46, 0x41, 0x8a, 0x26, 0x04, 0x0d, 0x53, 0x34, 0x4a, 0xd1, 0x34, 0x45, 0x93, 0x14, 0x8d, 0x53, + 0xf4, 0x90, 0xa2, 0xbb, 0x14, 0xfd, 0x35, 0x23, 0x58, 0x03, 0xf5, 0x22, 0x21, 0xd3, 0x38, 0xdf, + 0xc0, 0xe7, 0x41, 0x2c, 0x89, 0xd8, 0xaf, 0xf0, 0x8b, 0xd1, 0xb4, 0x7f, 0x4b, 0x34, 0x72, 0x76, + 0xa8, 0x93, 0xb3, 0xd7, 0x1a, 0x39, 0x8b, 0xbe, 0xe9, 0x21, 0x87, 0x7e, 0xd1, 0xa3, 0x0c, 0x0d, + 0x89, 0x16, 0x58, 0xe8, 0x4e, 0x35, 0x00, 0x6f, 0x8a, 0x0d, 0xbf, 0xe7, 0x3f, 0xe0, 0x76, 0x11, + 0xa6, 0xee, 0x6c, 0xe2, 0xc0, 0x49, 0xd2, 0x9e, 0x2e, 0xb0, 0x9b, 0xcb, 0xff, 0xb3, 0x3b, 0x01, + 0x1e, 0x6e, 0x05, 0xd8, 0x6b, 0x0d, 0x37, 0xb6, 0xfc, 0xa0, 0xd7, 0xdd, 0xb4, 0x5b, 0xbd, 0xb6, + 0xed, 0x75, 0xfd, 0x61, 0x37, 0x68, 0xb3, 0x76, 0x47, 0xce, 0x90, 0x20, 0xcf, 0x79, 0xb1, 0xb1, + 0xfa, 0x86, 0x05, 0xde, 0x76, 0xaa, 0xb9, 0x6e, 0xab, 0xd9, 0xee, 0xf9, 0x18, 0xb7, 0xae, 0x7a, + 0xc3, 0x21, 0xde, 0x68, 0xc3, 0xa3, 0x69, 0x9d, 0xe6, 0xc6, 0xd6, 0xc6, 0xc6, 0xc6, 0x16, 0xde, + 0xdc, 0xda, 0x6c, 0x36, 0x37, 0x9a, 0x4d, 0xaf, 0x13, 0x74, 0xec, 0x8e, 0x1d, 0x6c, 0x7a, 0x57, + 0x1b, 0x5d, 0x7c, 0xd5, 0x09, 0x7c, 0x0f, 0x1e, 0x83, 0xdd, 0x80, 0x87, 0xda, 0x2c, 0x30, 0x1a, + 0xc9, 0xda, 0x6b, 0xd9, 0xbd, 0xad, 0x76, 0x2f, 0x68, 0xfb, 0x41, 0x0f, 0x77, 0xdb, 0x43, 0xec, + 0x37, 0xbd, 0x0e, 0x6e, 0xb5, 0xed, 0x61, 0x10, 0xf4, 0x02, 0xbf, 0xeb, 0xf7, 0xb6, 0x5a, 0xbe, + 0xbf, 0xd1, 0x6b, 0x6e, 0x75, 0x5b, 0x5d, 0x0f, 0xde, 0x56, 0xdb, 0xea, 0xf6, 0x5a, 0x41, 0xaf, + 0xb9, 0x39, 0x6c, 0x75, 0x83, 0xae, 0xed, 0x41, 0x7b, 0x0f, 0x5a, 0x7b, 0xbd, 0xef, 0xfa, 0xaf, + 0xbb, 0x69, 0x58, 0xf3, 0x7e, 0xa8, 0x16, 0xde, 0xb0, 0xb7, 0x7a, 0x9b, 0xb6, 0xdd, 0xb3, 0xdb, + 0x1b, 0xbd, 0x8d, 0xe6, 0x46, 0xb7, 0xd9, 0xdd, 0xea, 0xf6, 0x36, 0x9b, 0x1b, 0x4d, 0x78, 0x9a, + 0xb0, 0xb3, 0xb5, 0xb9, 0xd9, 0xed, 0xb4, 0x9a, 0x76, 0xb7, 0xd3, 0xe9, 0x35, 0x7b, 0xbd, 0xae, + 0xdd, 0xdd, 0x6a, 0xb5, 0x37, 0xb7, 0x9a, 0x76, 0xaf, 0xb5, 0xd1, 0xe9, 0x34, 0x5b, 0x76, 0x73, + 0xa3, 0x6d, 0xb7, 0xda, 0x9b, 0xad, 0xad, 0x8d, 0xcd, 0xce, 0x46, 0xb7, 0x65, 0x58, 0xfd, 0x7b, + 0x66, 0x18, 0x43, 0x1b, 0x13, 0x11, 0x49, 0x03, 0xdc, 0xf1, 0xd0, 0x0f, 0xb1, 0x48, 0x8d, 0xf5, + 0xd4, 0x88, 0xb8, 0x20, 0x7a, 0xc3, 0x14, 0xcc, 0x8b, 0xef, 0xb9, 0xfe, 0xe2, 0x03, 0xae, 0x90, + 0xaf, 0xbd, 0xce, 0x0c, 0x69, 0x46, 0x64, 0x8e, 0x3c, 0xec, 0x8e, 0xa9, 0x19, 0x11, 0xab, 0xff, + 0x7b, 0x02, 0xbf, 0xa0, 0x91, 0x48, 0x59, 0xc5, 0xfc, 0x3d, 0x9e, 0x5b, 0xe8, 0xaf, 0x2c, 0xa3, + 0x24, 0xb5, 0x8c, 0x08, 0x9a, 0xa9, 0x62, 0xca, 0x6c, 0xe6, 0x03, 0x9e, 0x5b, 0x16, 0xfa, 0x35, + 0x71, 0xf9, 0xf1, 0x03, 0x94, 0x46, 0xdc, 0x7b, 0xe1, 0x93, 0x26, 0xd0, 0xc7, 0x97, 0xd8, 0x9c, + 0x1d, 0x39, 0x84, 0xcb, 0x00, 0xa5, 0x24, 0x4f, 0x17, 0xfb, 0x61, 0xe1, 0xbc, 0x99, 0x11, 0xf1, + 0x14, 0xe8, 0xf6, 0x78, 0x0e, 0xa4, 0x34, 0xd6, 0x42, 0x79, 0x43, 0x34, 0x2a, 0x40, 0x2c, 0xc4, + 0x5a, 0x87, 0x3f, 0xf3, 0xca, 0xf9, 0xce, 0xad, 0xb9, 0x65, 0x5a, 0xe8, 0xc7, 0x04, 0xe8, 0xc4, + 0x37, 0xdf, 0x38, 0x9d, 0x88, 0x53, 0x41, 0x4d, 0x5d, 0x53, 0xf4, 0x63, 0x62, 0xa1, 0x8f, 0x82, + 0x4e, 0xa4, 0x26, 0xa7, 0x0c, 0xee, 0x45, 0x60, 0x51, 0x92, 0xba, 0xef, 0x63, 0xf3, 0x5e, 0xd0, + 0x0b, 0x3a, 0x6d, 0xd9, 0x01, 0xc5, 0xe8, 0x94, 0xb8, 0x1f, 0x62, 0x53, 0x62, 0x7d, 0x44, 0xdc, + 0x6d, 0x20, 0x12, 0x98, 0x48, 0x9d, 0xc9, 0xc3, 0xa5, 0x67, 0x34, 0x67, 0x56, 0xff, 0x76, 0xf0, + 0xc1, 0x39, 0xf9, 0xb4, 0x53, 0xef, 0xda, 0xad, 0x8b, 0xbd, 0xcf, 0x9f, 0x5b, 0x17, 0xc7, 0x87, + 0x17, 0x06, 0x52, 0x12, 0xf3, 0x55, 0xa5, 0xbf, 0x7c, 0xbd, 0x30, 0x10, 0x43, 0x03, 0x20, 0x2a, + 0xbe, 0x71, 0xd8, 0x63, 0x72, 0x5c, 0x43, 0xc5, 0x14, 0x33, 0x48, 0xad, 0x00, 0xf2, 0x89, 0x1b, + 0x02, 0xea, 0x54, 0x5b, 0xb3, 0xd5, 0x6d, 0xf6, 0xda, 0xcd, 0xde, 0xe6, 0x16, 0xbc, 0x57, 0xd9, + 0xe9, 0xb5, 0xda, 0x9d, 0x8d, 0x8e, 0x6d, 0xdb, 0x70, 0xf0, 0xba, 0x9b, 0x1b, 0xcd, 0x96, 0xdd, + 0x6d, 0x6d, 0x34, 0xed, 0x56, 0xa7, 0xd3, 0x6d, 0xdb, 0xdd, 0x66, 0xab, 0xb3, 0xd5, 0xea, 0x75, + 0x7b, 0x9d, 0x5e, 0xb3, 0xb9, 0xb1, 0xd5, 0xb2, 0x9b, 0x9d, 0xcd, 0x56, 0xcf, 0x6e, 0x76, 0xda, + 0xb0, 0xa9, 0xe1, 0x71, 0x52, 0x0b, 0xa5, 0x59, 0xd3, 0xb0, 0xa1, 0xb7, 0xda, 0x70, 0x92, 0x37, + 0xb7, 0x9a, 0x5b, 0x6d, 0xbb, 0xb7, 0xd5, 0x6a, 0x6e, 0x6d, 0x75, 0x37, 0xed, 0xf6, 0x66, 0x6f, + 0x73, 0xa3, 0x03, 0x4f, 0x3e, 0xf6, 0x9a, 0xdd, 0xf6, 0x16, 0x9c, 0x69, 0x78, 0x7f, 0xb3, 0xb5, + 0xd1, 0xe9, 0xf6, 0xb6, 0x5a, 0x76, 0xab, 0xd9, 0x6d, 0xdb, 0xad, 0xcd, 0xad, 0x5e, 0xdb, 0xb6, + 0x37, 0x5a, 0x76, 0x13, 0x9e, 0x87, 0xde, 0x34, 0x2c, 0xe4, 0x65, 0x4d, 0xdb, 0x76, 0x77, 0x6b, + 0xb3, 0xd3, 0x6e, 0x82, 0xd4, 0x75, 0x73, 0x63, 0x63, 0x6b, 0x73, 0x63, 0xcb, 0xde, 0x6a, 0x6f, + 0x6c, 0x74, 0xe1, 0xb1, 0xca, 0x6e, 0xb7, 0xbb, 0xd9, 0xeb, 0xc1, 0xbb, 0x9f, 0x1b, 0xed, 0xee, + 0xc6, 0x46, 0x77, 0x6b, 0x03, 0xde, 0x80, 0xde, 0xe8, 0x75, 0x3b, 0x9d, 0x36, 0x94, 0xdc, 0x68, + 0x35, 0x37, 0x37, 0x7a, 0xb6, 0x6d, 0x6f, 0x36, 0x7b, 0x9b, 0x6d, 0x68, 0x39, 0xcc, 0x5a, 0xee, + 0x34, 0x3b, 0x9d, 0xe6, 0x66, 0xbb, 0x03, 0xef, 0x48, 0x37, 0x37, 0xbb, 0xed, 0xde, 0x66, 0x77, + 0xd3, 0x6e, 0xda, 0xf0, 0x58, 0x75, 0x6f, 0xab, 0xdd, 0x6a, 0xdb, 0x5b, 0xcd, 0xcd, 0x56, 0xaf, + 0xd5, 0xd9, 0x6c, 0x6f, 0x6d, 0xd9, 0x00, 0xaf, 0xcd, 0x8d, 0xe6, 0x66, 0xbb, 0xdb, 0x6a, 0x75, + 0x9a, 0x76, 0xbb, 0xdd, 0x6a, 0x35, 0x37, 0xd9, 0x03, 0xd5, 0xad, 0x5e, 0x77, 0x0b, 0x8e, 0x2a, + 0xfa, 0x04, 0x91, 0x6b, 0xb6, 0x47, 0xc4, 0x1c, 0x02, 0x9b, 0x82, 0xfc, 0xf4, 0xc5, 0x2e, 0x80, + 0xe1, 0x10, 0x90, 0x2a, 0x81, 0xe6, 0xe5, 0x3e, 0x03, 0xf3, 0xba, 0xcc, 0xf0, 0x9e, 0x58, 0x6b, + 0x3e, 0x44, 0x7f, 0xc0, 0xe2, 0x19, 0xc2, 0xec, 0x21, 0xc2, 0x09, 0x2d, 0x5a, 0x48, 0xf1, 0x57, + 0x08, 0xb1, 0x55, 0xe1, 0x48, 0x8b, 0x73, 0x6e, 0x7a, 0x44, 0x6d, 0xea, 0x9c, 0x76, 0xcb, 0xb2, + 0xe6, 0x39, 0x9b, 0x1d, 0xee, 0x6c, 0x8e, 0x75, 0xef, 0xdb, 0x2a, 0x73, 0x89, 0xbc, 0x48, 0x47, + 0x37, 0x9b, 0x60, 0xd6, 0x2e, 0xc5, 0xae, 0xb3, 0xf1, 0xe9, 0xaa, 0x2d, 0xed, 0xe9, 0x9b, 0x18, + 0xc8, 0x0c, 0x25, 0xff, 0x00, 0x25, 0x87, 0x81, 0x30, 0xa3, 0x84, 0x2a, 0x2d, 0xbf, 0x7e, 0x32, + 0x31, 0x90, 0x51, 0xc2, 0x2b, 0x8f, 0xa2, 0x00, 0x50, 0x09, 0xa6, 0x28, 0x01, 0xe2, 0x34, 0x75, + 0x2f, 0x34, 0xe2, 0xf4, 0x02, 0x28, 0xd0, 0x80, 0x05, 0x89, 0x80, 0xa9, 0x8d, 0x62, 0xf3, 0x5e, + 0x99, 0xd6, 0x84, 0x60, 0x0d, 0xf1, 0xf8, 0xc8, 0xb8, 0xe9, 0x64, 0x89, 0x8f, 0x98, 0x2e, 0x98, + 0xa9, 0xb1, 0xd3, 0x0d, 0x2f, 0xd9, 0xd8, 0xca, 0x98, 0x21, 0x05, 0xee, 0x9e, 0x69, 0xe2, 0x80, + 0x80, 0xa4, 0xeb, 0x8c, 0xf3, 0x83, 0xdf, 0x75, 0xf6, 0x3b, 0x72, 0x53, 0xd3, 0x5f, 0xf7, 0x41, + 0xf5, 0x9b, 0x9a, 0xa3, 0x75, 0x16, 0xdf, 0x32, 0x35, 0xe9, 0x7a, 0xbc, 0x1e, 0xd5, 0xa7, 0x1a, + 0xfd, 0x3b, 0x16, 0xf4, 0xef, 0xc3, 0xdc, 0xfd, 0x14, 0x9b, 0xa9, 0x39, 0x5c, 0x9f, 0x5a, 0x40, + 0xa0, 0xa6, 0xe6, 0x03, 0x54, 0x3a, 0x66, 0x3f, 0xae, 0xd6, 0x87, 0xc0, 0x9a, 0xa5, 0xa6, 0x19, + 0xbe, 0x09, 0xad, 0xf5, 0x2b, 0x46, 0x1a, 0xdf, 0xa1, 0xc4, 0x62, 0x1e, 0xfb, 0xa9, 0x59, 0xbf, + 0xb3, 0x24, 0x57, 0x06, 0xbd, 0x1e, 0x03, 0x47, 0x96, 0x9a, 0x77, 0xeb, 0xef, 0xf9, 0xfc, 0xc7, + 0x6c, 0xba, 0xd7, 0x28, 0xb1, 0x1e, 0x1f, 0xdf, 0xbb, 0xae, 0xfb, 0xb7, 0xe4, 0xb9, 0xd3, 0x6e, + 0x19, 0x39, 0xaa, 0x94, 0x98, 0x39, 0x32, 0x19, 0xfc, 0xc8, 0x81, 0x3c, 0xb4, 0xaa, 0x2c, 0xf3, + 0x72, 0xfa, 0x55, 0xe5, 0x96, 0x9b, 0x2d, 0x3b, 0xbe, 0x87, 0x55, 0x07, 0xfa, 0x58, 0xf7, 0x9b, + 0xd2, 0x0d, 0xaa, 0x58, 0x34, 0xb4, 0xec, 0xd4, 0xc4, 0x4c, 0x9e, 0x51, 0xf0, 0x4d, 0xfb, 0x9b, + 0x83, 0xd1, 0x2f, 0x0e, 0x45, 0x7f, 0x77, 0x62, 0x74, 0xca, 0x78, 0x38, 0x6e, 0x7b, 0xc5, 0xa5, + 0x5d, 0x21, 0x84, 0x99, 0xb8, 0xd7, 0xc2, 0x4c, 0x04, 0x6e, 0x68, 0x86, 0x66, 0xfc, 0x86, 0x5a, + 0xeb, 0xa1, 0x19, 0xd7, 0x29, 0x33, 0x44, 0x09, 0x4d, 0xbc, 0xce, 0x38, 0xb6, 0x90, 0xaf, 0xdc, + 0x8c, 0xaf, 0x4c, 0xc4, 0x56, 0x26, 0x34, 0x83, 0xf5, 0x91, 0x05, 0xcb, 0x19, 0x9a, 0xd1, 0x3a, + 0x63, 0x30, 0xe0, 0x07, 0x63, 0xbe, 0x43, 0x73, 0xba, 0x3e, 0x5c, 0x4f, 0x2c, 0xf4, 0xc0, 0x22, + 0xe0, 0x63, 0x33, 0x59, 0x1f, 0x43, 0x08, 0x0e, 0x11, 0x7c, 0x2c, 0x34, 0xe9, 0xba, 0x4f, 0x60, + 0x01, 0xa1, 0x07, 0x9f, 0x80, 0xbd, 0xc7, 0x31, 0xf0, 0x54, 0xe8, 0x81, 0x55, 0x4d, 0xe5, 0x83, + 0x4b, 0x0f, 0xee, 0x10, 0x16, 0x16, 0xb3, 0xda, 0x2c, 0x42, 0x72, 0x68, 0xc2, 0xd8, 0x84, 0x5f, + 0x56, 0x68, 0xb2, 0xa1, 0xae, 0x3f, 0xa8, 0xb5, 0x18, 0x83, 0xd0, 0x8c, 0x15, 0x85, 0xdc, 0xfa, + 0x95, 0x65, 0xa1, 0x6c, 0xa3, 0x5f, 0x29, 0x47, 0x62, 0x69, 0x54, 0x99, 0x3b, 0xf4, 0xc2, 0xad, + 0x98, 0xa2, 0x5f, 0x98, 0x63, 0x93, 0x00, 0xd7, 0xec, 0x6f, 0x4e, 0x82, 0x7e, 0x01, 0x8b, 0x20, + 0x30, 0xd6, 0x43, 0xa1, 0x3b, 0xd2, 0x00, 0x37, 0xe2, 0x80, 0xa3, 0xeb, 0x29, 0xf8, 0x80, 0x87, + 0x66, 0xbc, 0x9e, 0x70, 0xb8, 0xc5, 0x32, 0x85, 0xae, 0x67, 0x66, 0xa4, 0xc1, 0xe3, 0xa3, 0xbf, + 0xd8, 0xbb, 0x58, 0xa8, 0xc9, 0xe7, 0xf3, 0x7e, 0x88, 0x33, 0x17, 0xb6, 0x10, 0x67, 0x18, 0x8b, + 0xd9, 0x47, 0x43, 0xae, 0xf2, 0x5c, 0xd3, 0x73, 0x39, 0xfb, 0x1c, 0x42, 0x98, 0x12, 0xf7, 0x9e, + 0xfd, 0x1b, 0xbb, 0x3f, 0xc4, 0xfd, 0x20, 0x75, 0x67, 0x5c, 0xe2, 0x1c, 0xe2, 0x39, 0x9a, 0x10, + 0x77, 0xa6, 0x23, 0x1f, 0xdd, 0x56, 0x77, 0xd0, 0xf8, 0x70, 0x72, 0xfa, 0xf8, 0x68, 0xe4, 0x04, + 0xb0, 0xfa, 0x6d, 0x7d, 0xdc, 0xea, 0x76, 0x0f, 0x76, 0x8e, 0xf8, 0xf5, 0x1e, 0x73, 0x4b, 0x0d, + 0x8a, 0x7a, 0x1d, 0xf4, 0x21, 0x23, 0x5e, 0x7e, 0x06, 0x7e, 0xad, 0xa0, 0x31, 0x66, 0x81, 0x55, + 0x84, 0x0a, 0x58, 0xf6, 0xc6, 0x6d, 0xb9, 0xa0, 0xc7, 0x42, 0x03, 0x3f, 0xc4, 0xda, 0x1d, 0x00, + 0xa6, 0x81, 0x73, 0x34, 0x4c, 0xdd, 0x33, 0xa3, 0xb9, 0x8a, 0x2f, 0x58, 0xf1, 0x9f, 0x81, 0x0c, + 0x7f, 0xc3, 0xde, 0xe8, 0x79, 0x1b, 0xcd, 0x76, 0xd0, 0x09, 0x82, 0xcd, 0xce, 0xf0, 0xca, 0x6b, + 0xfb, 0xcd, 0xab, 0x8d, 0x5e, 0x33, 0xb0, 0x9b, 0xbd, 0x8d, 0xe6, 0xb0, 0xe5, 0xc1, 0xdd, 0x3d, + 0xf4, 0x5a, 0x7e, 0x7b, 0xcb, 0xf7, 0xfd, 0x5e, 0x07, 0xfb, 0x1b, 0xc3, 0x60, 0x63, 0x63, 0xab, + 0xe5, 0xf9, 0xcd, 0xf6, 0x06, 0x7b, 0x91, 0xf7, 0xbb, 0xfe, 0xdb, 0x84, 0x51, 0xb4, 0x7a, 0x78, + 0x73, 0xab, 0x0b, 0xcf, 0x7c, 0x5f, 0xb5, 0x5a, 0x1b, 0x57, 0xcd, 0x4e, 0xd7, 0x6f, 0x0f, 0x3b, + 0x9b, 0x5b, 0xc3, 0x16, 0x1e, 0x6e, 0x6d, 0x0e, 0x9b, 0x41, 0x37, 0x18, 0x7a, 0x7e, 0xb3, 0x1b, + 0xb4, 0xfd, 0x5e, 0xbb, 0xdd, 0xde, 0xba, 0xb2, 0xdb, 0x9b, 0xcd, 0xd6, 0xe6, 0x66, 0x2f, 0xe8, + 0xb6, 0x87, 0x7e, 0x13, 0x9e, 0x54, 0xc6, 0xfe, 0xf7, 0xdc, 0xbb, 0x1b, 0xc3, 0xef, 0x1e, 0xc5, + 0x66, 0xf7, 0xbb, 0x61, 0xf1, 0x02, 0x2b, 0x32, 0xf4, 0x8c, 0xf3, 0xfe, 0x28, 0x75, 0xff, 0x16, + 0xf7, 0xa7, 0xa9, 0x1b, 0x62, 0x34, 0x49, 0xdd, 0x29, 0xb7, 0x4e, 0x17, 0xfb, 0x1b, 0x8d, 0x59, + 0x4a, 0x4e, 0x89, 0x81, 0x1e, 0x52, 0x77, 0x92, 0x2f, 0x75, 0x57, 0x4c, 0x11, 0xfa, 0x9d, 0xc3, + 0x2a, 0x83, 0x6c, 0x81, 0x3a, 0xf8, 0xe3, 0x8b, 0xee, 0xd9, 0xb9, 0x86, 0x77, 0x17, 0x98, 0x7d, + 0x6a, 0x6f, 0x35, 0xce, 0xef, 0xd2, 0x90, 0x62, 0x75, 0x83, 0xe7, 0x5a, 0x6a, 0x34, 0x1a, 0xda, + 0x37, 0x38, 0xc1, 0xe1, 0xf3, 0xac, 0xbc, 0x2a, 0xae, 0xb5, 0x70, 0x86, 0xcf, 0x45, 0x8b, 0x5f, + 0xf7, 0x63, 0x6a, 0xf7, 0x3e, 0xef, 0x99, 0x8b, 0x4c, 0x4a, 0x5b, 0x56, 0x1f, 0x52, 0x3e, 0x78, + 0xd4, 0xfb, 0x16, 0xe2, 0x3b, 0x93, 0xca, 0x11, 0x41, 0xdc, 0x26, 0x28, 0x67, 0xf7, 0xcc, 0x26, + 0xc2, 0x59, 0x24, 0x13, 0xad, 0x1b, 0xaa, 0x75, 0xd2, 0x6e, 0x2d, 0xe9, 0xa4, 0xb3, 0xaa, 0x93, + 0x76, 0x6b, 0x65, 0x27, 0xdf, 0xd5, 0xc7, 0xfe, 0x93, 0xba, 0x10, 0x16, 0x6a, 0x15, 0x00, 0x85, + 0x96, 0x4f, 0xf1, 0x3d, 0xdd, 0x63, 0x1b, 0x06, 0xbc, 0xab, 0xf8, 0xd6, 0x61, 0x14, 0x22, 0x2b, + 0xb7, 0x2b, 0x2b, 0x67, 0xef, 0x59, 0x15, 0x06, 0xa8, 0xac, 0xc1, 0xde, 0xb3, 0x71, 0x01, 0x0e, + 0x03, 0xc1, 0xe0, 0xe2, 0x96, 0x99, 0xaa, 0x1c, 0xb6, 0x5b, 0x0a, 0xe1, 0x6c, 0xdf, 0xd1, 0xb5, + 0xb5, 0xf4, 0x5d, 0x22, 0x2d, 0x7d, 0xd3, 0x37, 0x6f, 0xac, 0xf8, 0x2c, 0x3d, 0x77, 0x93, 0xb3, + 0xf4, 0xbc, 0x1f, 0x9f, 0xc5, 0x99, 0x07, 0xb9, 0xdb, 0x2c, 0xcd, 0x30, 0x06, 0x74, 0x79, 0xe4, + 0x1e, 0x52, 0xb6, 0x7d, 0x3f, 0x2c, 0xf3, 0x27, 0x60, 0x2e, 0x8e, 0x38, 0x95, 0x8d, 0x88, 0x4d, + 0x58, 0x98, 0x0b, 0x66, 0x2e, 0x04, 0xc7, 0x18, 0xd8, 0xe1, 0x30, 0xbe, 0x66, 0x9d, 0xec, 0x26, + 0xd3, 0xb8, 0xe8, 0x05, 0xce, 0x6b, 0xcb, 0xa1, 0xe9, 0xed, 0xcf, 0x53, 0xec, 0x05, 0x6c, 0xff, + 0xe6, 0x6b, 0xc8, 0x64, 0x62, 0xda, 0x2c, 0x8a, 0x41, 0xf6, 0xad, 0x16, 0x5e, 0x6f, 0x99, 0xeb, + 0x72, 0xf5, 0x86, 0x91, 0xfe, 0xf1, 0xa6, 0x10, 0x49, 0x4d, 0x26, 0xbb, 0x18, 0x51, 0xd6, 0x74, + 0x7e, 0x0a, 0x0b, 0xc7, 0x22, 0xe3, 0xa0, 0x55, 0xce, 0xd8, 0x62, 0x2d, 0x15, 0xfd, 0x0f, 0xe4, + 0xc2, 0x7e, 0xc0, 0x72, 0x61, 0x03, 0xf6, 0xcb, 0x54, 0x4d, 0x17, 0xfb, 0xe6, 0xed, 0xec, 0x66, + 0xbb, 0x90, 0x4f, 0xf7, 0xec, 0x5c, 0x46, 0x63, 0xd4, 0x61, 0xa1, 0xec, 0x28, 0x12, 0x30, 0xd1, + 0xe2, 0x41, 0x0a, 0x13, 0x08, 0x84, 0x6c, 0xad, 0xea, 0xbf, 0x64, 0x7c, 0x6e, 0xf5, 0x29, 0x0f, + 0x86, 0x98, 0x30, 0xa5, 0xbd, 0x17, 0xec, 0xc7, 0x74, 0xd3, 0x94, 0xca, 0xa6, 0xd2, 0xaa, 0xe8, + 0xe4, 0xad, 0x3a, 0x6d, 0x58, 0x9d, 0xb6, 0x6b, 0x76, 0xda, 0x36, 0xcd, 0x26, 0x9f, 0xce, 0xd7, + 0xef, 0x6d, 0x8c, 0x0d, 0x55, 0x6f, 0x8d, 0xa1, 0xb3, 0x05, 0x0d, 0xb6, 0x9e, 0xd8, 0x20, 0x43, + 0x6a, 0xaf, 0x72, 0x8d, 0xbe, 0x7f, 0xa1, 0x46, 0xed, 0xac, 0x51, 0x86, 0xaf, 0x16, 0x34, 0xda, + 0x79, 0x62, 0xa3, 0x0c, 0x6d, 0xe9, 0x23, 0x6d, 0xb7, 0xde, 0xbf, 0x50, 0xa3, 0x62, 0xa4, 0x2f, + 0x00, 0xd2, 0xfd, 0x02, 0x44, 0x5f, 0x00, 0xa0, 0xfb, 0x05, 0x78, 0xbe, 0x00, 0x38, 0xf7, 0x0b, + 0xd0, 0xdc, 0x8f, 0x69, 0xab, 0xc3, 0x46, 0x09, 0x48, 0xb1, 0xd0, 0xa4, 0x69, 0xbd, 0x7b, 0x67, + 0xf7, 0x1e, 0x4b, 0x69, 0x9b, 0xc5, 0x24, 0xf9, 0xa2, 0x1b, 0x5e, 0xdb, 0x6c, 0x6f, 0x6e, 0xf6, + 0x9a, 0x3c, 0xce, 0x13, 0xf8, 0x19, 0xd4, 0x5d, 0xbb, 0xb7, 0xb1, 0xb1, 0xd1, 0xb2, 0x7b, 0x10, + 0x2d, 0x78, 0x8e, 0xbe, 0xb9, 0x1f, 0x38, 0xfe, 0x3d, 0x90, 0xf8, 0x57, 0xb0, 0x71, 0x27, 0x32, + 0x04, 0xc1, 0x6e, 0x32, 0x9e, 0x78, 0x71, 0x98, 0xc4, 0x47, 0x69, 0x42, 0x13, 0x3f, 0x89, 0xbe, + 0x61, 0xe6, 0xb5, 0xe4, 0xb6, 0xfb, 0xb2, 0x28, 0x4e, 0x43, 0x2f, 0xfa, 0x98, 0x7a, 0x63, 0x7c, + 0xfa, 0x30, 0xc1, 0xc4, 0x9d, 0xed, 0xc7, 0x7e, 0x32, 0x0e, 0xe3, 0x6b, 0xa7, 0xd7, 0x42, 0x87, + 0x53, 0x7a, 0x9d, 0xb0, 0xdf, 0xcd, 0xb9, 0xac, 0xf1, 0x3e, 0xc2, 0xee, 0xec, 0x04, 0xa7, 0xb7, + 0xa1, 0x8f, 0xbf, 0x4e, 0xc3, 0xc0, 0x31, 0x7a, 0x7b, 0x1d, 0x26, 0x2f, 0xaf, 0xbf, 0xef, 0xee, + 0xb4, 0xeb, 0x1f, 0xdb, 0x5b, 0xed, 0xfa, 0x5e, 0x73, 0x67, 0xab, 0xbe, 0xd7, 0x6d, 0xee, 0xb5, + 0x3a, 0x1f, 0x76, 0x77, 0x77, 0xb6, 0xf6, 0x0c, 0xb4, 0x3b, 0xf2, 0xc0, 0x15, 0x09, 0x03, 0xd5, + 0x1f, 0xfa, 0x50, 0xf3, 0xf8, 0x5e, 0xd5, 0x6d, 0x3d, 0xb7, 0xee, 0x69, 0x56, 0xb7, 0xbd, 0xb4, + 0xae, 0x1a, 0x37, 0xac, 0xa1, 0x98, 0xe2, 0x07, 0x7c, 0xeb, 0x30, 0x53, 0x7d, 0x95, 0x79, 0x42, + 0x3d, 0x4a, 0x44, 0xee, 0x6e, 0x92, 0x62, 0xa7, 0x89, 0x8e, 0xbd, 0x20, 0x4c, 0x1c, 0x1b, 0x1d, + 0x79, 0xfe, 0x0d, 0xa6, 0xc4, 0x69, 0xa9, 0xc2, 0xbb, 0xc9, 0x78, 0xec, 0xc5, 0xc1, 0x6e, 0x12, + 0x40, 0xf1, 0x9d, 0xc9, 0x84, 0x3d, 0x39, 0xec, 0xd8, 0xe8, 0x04, 0xc7, 0xc1, 0xe9, 0x3d, 0x3d, + 0x20, 0xd7, 0x4e, 0x8b, 0x7d, 0xec, 0x8e, 0xbc, 0x38, 0xc6, 0x91, 0x48, 0x6b, 0xa3, 0x1f, 0x30, + 0x05, 0x5d, 0xbf, 0xe7, 0x53, 0xe2, 0x74, 0xe0, 0xeb, 0x03, 0x06, 0x30, 0x9e, 0x86, 0x63, 0xec, + 0x74, 0xd1, 0x49, 0xee, 0xbb, 0xc7, 0x5a, 0x38, 0xc1, 0xd1, 0x70, 0x27, 0x60, 0x4f, 0x32, 0x6e, + 0x40, 0x01, 0xfe, 0xfb, 0x8b, 0x37, 0xc6, 0xce, 0x26, 0xda, 0x09, 0x82, 0xaf, 0xcc, 0xc8, 0x5f, + 0x34, 0xea, 0x6c, 0xa1, 0x93, 0x87, 0xd8, 0xff, 0x82, 0xef, 0xe9, 0x01, 0xf7, 0x2e, 0x70, 0xec, + 0x26, 0xd4, 0x62, 0x73, 0x39, 0xe2, 0x41, 0x14, 0x6d, 0x18, 0x27, 0x3d, 0xbd, 0x3f, 0x4a, 0xee, + 0x70, 0xea, 0xd8, 0x2d, 0x74, 0x8c, 0x09, 0xa6, 0x47, 0x1e, 0x1d, 0x39, 0x76, 0x3b, 0xeb, 0xe2, + 0xb3, 0x47, 0x3f, 0x27, 0xb1, 0x63, 0x77, 0xd0, 0x31, 0x1e, 0x27, 0xb7, 0xaa, 0x0b, 0xbb, 0x8b, + 0x98, 0xd1, 0x95, 0xfa, 0xee, 0xa1, 0xbd, 0x7b, 0xd8, 0x6d, 0x2a, 0x61, 0x03, 0xed, 0x8f, 0x73, + 0x09, 0x9b, 0xe8, 0x18, 0x5f, 0xc1, 0xab, 0x78, 0xf6, 0x16, 0xcc, 0xf9, 0xbd, 0x47, 0x29, 0x4e, + 0x1f, 0xbe, 0x25, 0x11, 0x85, 0x11, 0xb6, 0xd8, 0x08, 0x4f, 0xa7, 0x70, 0x71, 0x89, 0x21, 0xb6, + 0x6c, 0xc4, 0x01, 0xf1, 0xd7, 0x29, 0x98, 0x17, 0xb5, 0x5a, 0xa2, 0x0b, 0xcd, 0x00, 0xab, 0xd5, + 0x16, 0xbd, 0xe8, 0x69, 0x1d, 0x06, 0xb2, 0x63, 0xef, 0x0e, 0xd6, 0xda, 0x69, 0x75, 0xd9, 0xe7, + 0xe7, 0xe4, 0x3a, 0x8c, 0x9d, 0x96, 0x00, 0x27, 0xf5, 0xe8, 0x94, 0x1c, 0xe3, 0xdf, 0x9c, 0xd6, + 0x06, 0x5b, 0x0d, 0xbe, 0x40, 0x4e, 0x9b, 0x01, 0x45, 0x7d, 0xb5, 0xd0, 0x49, 0x78, 0x1d, 0xf3, + 0x65, 0x6d, 0xb7, 0xd9, 0x07, 0x6b, 0xb2, 0xdd, 0x61, 0xbf, 0x3f, 0x86, 0x71, 0x48, 0x46, 0x4e, + 0x9b, 0x77, 0x70, 0x9a, 0x7a, 0x3e, 0x66, 0xf0, 0x6b, 0x43, 0x27, 0xf4, 0x90, 0x8e, 0x70, 0x2a, + 0x66, 0xd2, 0xde, 0xe4, 0x45, 0x58, 0x6c, 0x68, 0x9a, 0x3e, 0x40, 0xcf, 0xed, 0x2d, 0x96, 0xf6, + 0x3e, 0x8c, 0x3d, 0x9e, 0xd0, 0x65, 0x10, 0xf8, 0x18, 0x25, 0x49, 0x70, 0xe2, 0x27, 0x13, 0xec, + 0x74, 0xd9, 0xde, 0x60, 0x7b, 0x12, 0xec, 0x69, 0xb5, 0x9d, 0xc4, 0x46, 0xd1, 0xcb, 0xb6, 0xe2, + 0x31, 0x26, 0x93, 0x24, 0x26, 0x58, 0xec, 0xc5, 0xc3, 0x1b, 0xa7, 0x89, 0xf6, 0xd2, 0xd4, 0xb1, + 0x91, 0xdc, 0x67, 0x7c, 0x12, 0x2d, 0xf9, 0xed, 0xb4, 0xd1, 0x5e, 0x1c, 0x1c, 0x0e, 0xb5, 0x6d, + 0x08, 0x5b, 0x6c, 0x3f, 0x1e, 0x26, 0x6c, 0x07, 0xc6, 0xd4, 0xe9, 0xc9, 0xb2, 0x07, 0xe4, 0xfa, + 0x18, 0xfb, 0xb7, 0xce, 0x06, 0x12, 0xbd, 0xcb, 0x84, 0x4d, 0xb4, 0x3b, 0x4d, 0x53, 0xb6, 0x4b, + 0xb7, 0xd0, 0x97, 0xe4, 0x20, 0x49, 0xb1, 0xd8, 0x6f, 0x04, 0x36, 0x5c, 0x61, 0x3f, 0xd8, 0xa8, + 0xb0, 0xe2, 0x76, 0x4b, 0x2c, 0x2f, 0xeb, 0xd5, 0x6e, 0x23, 0x6d, 0x0d, 0xed, 0x0e, 0xfa, 0x10, + 0x12, 0xef, 0x0a, 0xe2, 0x50, 0xd8, 0xdd, 0xc2, 0x48, 0xbe, 0xb5, 0x61, 0xbb, 0xe5, 0x07, 0x03, + 0x69, 0x6a, 0x80, 0xbc, 0xc1, 0x4d, 0x6d, 0xf5, 0xec, 0x2d, 0xf6, 0x21, 0x02, 0x11, 0x34, 0x11, + 0x07, 0x6a, 0xab, 0x83, 0x34, 0x80, 0xb2, 0x39, 0xb5, 0x36, 0x14, 0x50, 0x8f, 0xa6, 0x64, 0x24, + 0x0f, 0x37, 0x3f, 0x7a, 0xa0, 0x29, 0x80, 0x15, 0xe6, 0xa7, 0x2d, 0x70, 0xec, 0x16, 0x5f, 0xc3, + 0xdd, 0x24, 0x1e, 0x86, 0xe9, 0x18, 0x52, 0xda, 0x4d, 0x74, 0x40, 0xae, 0x7f, 0xf6, 0x42, 0x0a, + 0xf8, 0xd2, 0x6e, 0xdb, 0x48, 0xee, 0x43, 0xbb, 0xdd, 0x42, 0x6c, 0x13, 0x9e, 0x4c, 0x7d, 0x1f, + 0x13, 0xe2, 0xd8, 0xed, 0x36, 0x4f, 0xf8, 0xe8, 0x85, 0x91, 0x63, 0xc3, 0xa6, 0x12, 0xdb, 0x92, + 0x2f, 0xa6, 0x63, 0xb7, 0xbb, 0x50, 0xe0, 0xf8, 0x5e, 0xd4, 0xef, 0x21, 0xb6, 0xc7, 0xc4, 0xd7, + 0x06, 0xfa, 0x82, 0xef, 0xe4, 0xc0, 0xda, 0x9b, 0x48, 0xdb, 0x5c, 0xaa, 0xfe, 0x16, 0x92, 0xdb, + 0x4b, 0x26, 0x75, 0x32, 0x0c, 0xce, 0xe4, 0x8e, 0x62, 0x82, 0x5f, 0xb3, 0xd7, 0xfb, 0x76, 0xc7, + 0x81, 0x63, 0xa3, 0x2f, 0x09, 0xfd, 0x98, 0x4c, 0xe3, 0xc0, 0x69, 0xa1, 0x53, 0x58, 0x86, 0x8f, + 0xd3, 0x28, 0x72, 0xda, 0xe8, 0x3d, 0x7b, 0x58, 0x9d, 0x62, 0xa7, 0x83, 0x3e, 0x86, 0x11, 0xde, + 0x4f, 0x58, 0x23, 0x4e, 0x17, 0xed, 0x47, 0x11, 0xbe, 0xf6, 0xa2, 0x9d, 0xf4, 0xda, 0xe9, 0xa9, + 0x1e, 0x76, 0x82, 0x5b, 0x40, 0xa6, 0xee, 0xec, 0x4b, 0x12, 0x03, 0x2e, 0xdd, 0x1d, 0x79, 0x80, + 0x1f, 0x8f, 0xf1, 0x04, 0x04, 0x2e, 0xa9, 0xd3, 0x42, 0xc7, 0x49, 0x32, 0x76, 0xda, 0x19, 0xfe, + 0x55, 0x68, 0x4e, 0x20, 0x61, 0x88, 0xd2, 0xfc, 0x29, 0x99, 0x38, 0x4d, 0xc4, 0xce, 0x85, 0x63, + 0xab, 0xa2, 0xa7, 0xf7, 0xb2, 0xcc, 0x51, 0x04, 0xca, 0xb3, 0x26, 0xda, 0x8d, 0x42, 0x0e, 0x1a, + 0xb6, 0xd4, 0x38, 0xe0, 0xe9, 0xd9, 0x21, 0x51, 0x27, 0x6d, 0x8a, 0x89, 0xac, 0xfb, 0x03, 0xa6, + 0x0a, 0x6e, 0xfc, 0x68, 0xc3, 0x91, 0xdb, 0xb9, 0xbd, 0x3e, 0x08, 0xe3, 0x03, 0xef, 0x9e, 0x63, + 0xe7, 0x1d, 0xb6, 0x5e, 0x9f, 0x43, 0x42, 0x9d, 0x2e, 0x7c, 0x7f, 0xc1, 0xe1, 0xf5, 0xe8, 0x2a, + 0x99, 0xa6, 0xc4, 0xe9, 0xcd, 0xe7, 0xc8, 0x73, 0x0f, 0xf8, 0xfd, 0xfb, 0x65, 0x09, 0xfb, 0x8e, + 0x6f, 0x71, 0x4c, 0xa1, 0x09, 0x08, 0x5d, 0x4b, 0x0e, 0xbc, 0x09, 0x63, 0x7d, 0x0e, 0xbc, 0xc9, + 0x3c, 0x89, 0xb5, 0x38, 0xeb, 0xa5, 0x62, 0x20, 0x25, 0x30, 0x41, 0x5c, 0xbe, 0x20, 0x9b, 0x47, + 0x41, 0x3e, 0x3b, 0x17, 0xdc, 0x67, 0xb9, 0x00, 0x04, 0x9c, 0xc6, 0x16, 0x27, 0xc4, 0xa9, 0x35, + 0x4f, 0x86, 0x43, 0x53, 0xf9, 0xf2, 0x2c, 0xeb, 0x51, 0x72, 0x9b, 0xcb, 0x9b, 0x1d, 0x86, 0x11, + 0xc5, 0xa9, 0x99, 0xb8, 0xdb, 0xfc, 0xad, 0xf8, 0xfe, 0xd2, 0x61, 0x02, 0xbb, 0x98, 0xc4, 0x3e, + 0xd6, 0xb9, 0x59, 0xf0, 0xee, 0x4b, 0xf8, 0x8b, 0xd0, 0x21, 0x69, 0xf0, 0xe1, 0xc5, 0x16, 0x22, + 0x98, 0x02, 0x62, 0x49, 0xa6, 0x94, 0x69, 0x40, 0x29, 0x2f, 0x86, 0x9a, 0xd6, 0x9c, 0x77, 0xc1, + 0xa0, 0x16, 0x5b, 0x73, 0x3c, 0x06, 0xc5, 0x07, 0x08, 0x2f, 0x9e, 0x32, 0x27, 0xe5, 0xde, 0x0a, + 0xcc, 0xcd, 0xd2, 0x99, 0x59, 0x85, 0x01, 0xc4, 0x26, 0xeb, 0x02, 0x06, 0x30, 0x47, 0xaf, 0x89, + 0xfb, 0x85, 0x2f, 0xf9, 0xd7, 0x02, 0xc9, 0xc5, 0x5e, 0xbf, 0x3a, 0x4d, 0xf2, 0x92, 0x77, 0xcd, + 0xcb, 0x17, 0x5b, 0xec, 0x69, 0x20, 0xea, 0x6e, 0xd3, 0xcc, 0x75, 0xcd, 0xee, 0x59, 0x8d, 0x09, + 0x3b, 0x58, 0x29, 0x35, 0x5b, 0xc8, 0x68, 0x82, 0x6f, 0xe1, 0xaf, 0x49, 0x18, 0x9b, 0x86, 0x91, + 0xa9, 0x70, 0xf0, 0xfd, 0x69, 0xa2, 0x38, 0xd6, 0x05, 0xcf, 0xda, 0xc3, 0xc3, 0x43, 0xd4, 0x1f, + 0x99, 0x6f, 0x1b, 0x33, 0x1b, 0xb5, 0xe6, 0x6f, 0xaf, 0x55, 0x77, 0x13, 0x2f, 0x25, 0x20, 0xeb, + 0x30, 0x29, 0xb2, 0x7b, 0x56, 0x26, 0xea, 0xbf, 0xf2, 0x08, 0xee, 0x75, 0x56, 0xb7, 0xec, 0xd1, + 0xe4, 0x8a, 0x39, 0x97, 0xc3, 0xc8, 0xfd, 0x91, 0xc7, 0x10, 0xc7, 0x0e, 0x98, 0x79, 0xa8, 0xa6, + 0xbc, 0x14, 0x73, 0x11, 0x04, 0xd9, 0x03, 0x09, 0xb3, 0x59, 0x34, 0x7a, 0x84, 0x0d, 0x22, 0x1d, + 0x8d, 0x55, 0xd4, 0x9a, 0xbc, 0xc3, 0x31, 0xd6, 0x1d, 0x8e, 0xa1, 0xea, 0x59, 0x7c, 0x0e, 0xd5, + 0xce, 0xe2, 0xf3, 0xac, 0x8a, 0x72, 0xb2, 0x9f, 0xa3, 0x2b, 0xec, 0x7e, 0xe5, 0x0b, 0x31, 0x26, + 0x52, 0x6d, 0x27, 0x97, 0x62, 0xe7, 0xc3, 0xb7, 0x8b, 0xd3, 0x5f, 0x8e, 0xf6, 0x2e, 0xbe, 0x1c, + 0x7e, 0xd9, 0x73, 0x9b, 0xfd, 0x62, 0xf2, 0xee, 0xa7, 0x9d, 0x53, 0xd7, 0x2e, 0x25, 0x1f, 0xef, + 0x1d, 0xed, 0xed, 0x9c, 0xee, 0x1d, 0xbb, 0xad, 0x72, 0xd6, 0xe1, 0xe1, 0x41, 0x46, 0x32, 0xab, + 0xe4, 0x93, 0xbd, 0x2f, 0x27, 0x87, 0xc7, 0x6e, 0x47, 0xcf, 0xf8, 0xbc, 0x73, 0xfa, 0xf9, 0xf0, + 0xcb, 0x05, 0x3c, 0x1a, 0xe8, 0xda, 0x3d, 0x3d, 0xe7, 0xe3, 0xde, 0xce, 0xa9, 0xcd, 0x33, 0xda, + 0xad, 0x62, 0x46, 0x8b, 0x67, 0xf4, 0x72, 0x6d, 0x7d, 0xd9, 0x39, 0xd8, 0x13, 0x2d, 0xb5, 0x36, + 0xfb, 0x85, 0xf7, 0x19, 0xb8, 0xe7, 0x2b, 0x17, 0x42, 0x48, 0x33, 0x77, 0x57, 0x04, 0xc9, 0xa7, + 0xe1, 0x18, 0x13, 0xea, 0x8d, 0x27, 0xae, 0x88, 0x9d, 0xae, 0x62, 0xf1, 0xb8, 0xe2, 0x9d, 0x06, + 0x6f, 0x32, 0x01, 0xac, 0xe7, 0x8a, 0x20, 0xf0, 0x6c, 0x93, 0x04, 0x6e, 0xf6, 0x7b, 0x87, 0xe7, + 0x9b, 0xd5, 0xfa, 0xc0, 0x4c, 0x5e, 0xf6, 0x8d, 0x1b, 0x55, 0x51, 0x8d, 0x73, 0x6a, 0xb7, 0xd8, + 0xcb, 0xd5, 0x8d, 0x3c, 0xd3, 0xca, 0xa2, 0x97, 0x67, 0x85, 0x7a, 0x1d, 0xd0, 0x13, 0xd2, 0x4a, + 0xb1, 0x45, 0x41, 0xdd, 0x85, 0xd8, 0x33, 0x9b, 0x4c, 0x3e, 0xf4, 0x31, 0xf2, 0xae, 0x8b, 0x32, + 0x15, 0x31, 0x13, 0x10, 0xed, 0x5c, 0x63, 0x86, 0xdd, 0x0b, 0x05, 0xb2, 0x7a, 0x6b, 0x76, 0x57, + 0x96, 0x51, 0xc2, 0x15, 0x8d, 0xf9, 0x53, 0xd5, 0xb3, 0x37, 0x3b, 0x5c, 0x97, 0x34, 0x72, 0xdb, + 0x69, 0x60, 0xc0, 0x5f, 0xc3, 0x29, 0x64, 0xc1, 0x96, 0x1a, 0x18, 0xf0, 0xb7, 0x94, 0x25, 0xb7, + 0xd5, 0xc0, 0x90, 0xbf, 0xca, 0x45, 0x0e, 0x0f, 0x0f, 0x06, 0x06, 0xfc, 0x2d, 0x65, 0xf1, 0x2d, + 0x36, 0x30, 0xf8, 0xbf, 0x86, 0x03, 0xb1, 0xc2, 0xe7, 0x1e, 0x79, 0x88, 0xfd, 0x5a, 0x48, 0xbe, + 0x41, 0xbc, 0x99, 0x10, 0x07, 0x42, 0x11, 0x27, 0x2d, 0xfc, 0xf1, 0xdc, 0xf5, 0xee, 0xbc, 0x90, + 0xd6, 0x8e, 0xd2, 0x64, 0x1c, 0x12, 0x78, 0x8f, 0x96, 0x24, 0x11, 0x78, 0x64, 0x36, 0xe8, 0x08, + 0xc7, 0x0c, 0xab, 0x99, 0x7f, 0x8d, 0x4d, 0x0b, 0xfd, 0x1e, 0x33, 0xd3, 0x38, 0x00, 0xf4, 0x91, + 0x12, 0x6b, 0xe5, 0x04, 0x99, 0xb9, 0xed, 0x65, 0x21, 0x91, 0xa9, 0x96, 0x35, 0xbf, 0xdb, 0x54, + 0xbe, 0x56, 0x59, 0x2c, 0x0f, 0x78, 0x63, 0xf3, 0xf0, 0x38, 0x66, 0x7e, 0x43, 0x22, 0xaa, 0x45, + 0xa9, 0x2a, 0x74, 0x37, 0xcf, 0x6f, 0x45, 0xb1, 0x56, 0x7c, 0xdb, 0xe5, 0x1b, 0xa7, 0xec, 0xfd, + 0x5e, 0xc5, 0x41, 0x03, 0x5e, 0x88, 0x59, 0x5c, 0x75, 0x10, 0x88, 0x4e, 0xa3, 0xa8, 0x4f, 0xd7, + 0x38, 0x50, 0xb5, 0xe3, 0xc9, 0x5e, 0x1b, 0xe1, 0xd5, 0xb2, 0x5d, 0x9a, 0x14, 0x53, 0x78, 0x63, + 0x69, 0xbe, 0x95, 0xec, 0x28, 0xb3, 0x27, 0x4d, 0x71, 0x23, 0x2f, 0x4a, 0xe2, 0x75, 0xc2, 0x72, + 0x9d, 0x96, 0xac, 0x13, 0x2e, 0xa8, 0x13, 0xf0, 0x3a, 0x72, 0x29, 0x44, 0x55, 0x85, 0x07, 0xe0, + 0x15, 0x33, 0x51, 0x53, 0x6e, 0x60, 0x0b, 0xcd, 0x98, 0x19, 0x90, 0xbe, 0x83, 0x65, 0x1e, 0x8a, + 0x3c, 0xea, 0xc4, 0x28, 0x4a, 0x20, 0xe4, 0x40, 0x0c, 0x2c, 0x63, 0x80, 0x86, 0xd8, 0xa3, 0xb6, + 0x93, 0xb2, 0x7f, 0x5b, 0x60, 0xaf, 0x3e, 0x47, 0xbf, 0xc6, 0xee, 0x98, 0xb0, 0xee, 0x1f, 0xc8, + 0x9f, 0x7e, 0xa9, 0xcd, 0xd1, 0x8f, 0xb1, 0xfb, 0xc0, 0xbb, 0xbb, 0xcb, 0x50, 0x77, 0x09, 0xb9, + 0x49, 0xd4, 0xe6, 0xd1, 0x11, 0x98, 0x27, 0x40, 0xa8, 0x4e, 0x89, 0xdd, 0x64, 0x1a, 0x93, 0x96, + 0x4a, 0x0c, 0x07, 0x89, 0xfb, 0x14, 0x8f, 0x89, 0x1b, 0xeb, 0x28, 0x0b, 0x88, 0xf6, 0x9d, 0x58, + 0x3c, 0xd2, 0x9a, 0xd1, 0x3f, 0xae, 0xeb, 0x82, 0x21, 0xbe, 0x44, 0x34, 0x00, 0x73, 0x7e, 0x17, + 0x7d, 0xc2, 0x0d, 0x7c, 0xcf, 0x42, 0xa6, 0x1c, 0x69, 0x3d, 0x9b, 0xcc, 0x27, 0xa1, 0x9c, 0xc7, + 0xe5, 0xb5, 0xcc, 0x47, 0x21, 0x59, 0x87, 0x38, 0x0e, 0x58, 0x37, 0x3c, 0xe5, 0x2f, 0x8a, 0x84, + 0xe2, 0x66, 0x7b, 0x97, 0x96, 0xba, 0x0b, 0x40, 0x14, 0xeb, 0x8b, 0x0d, 0x1d, 0x66, 0xe2, 0xf9, + 0x91, 0xdb, 0xcc, 0x5e, 0x98, 0xe1, 0x04, 0x9c, 0xaf, 0xe1, 0xce, 0xd8, 0xaa, 0x40, 0x91, 0x81, + 0x08, 0x6a, 0x03, 0x43, 0xab, 0x8c, 0x5c, 0xa3, 0x00, 0xc4, 0x96, 0x0c, 0xbb, 0xdb, 0x3f, 0xc6, + 0x8d, 0xdc, 0xfa, 0xca, 0x45, 0x42, 0x6c, 0x95, 0x70, 0xe2, 0xde, 0xf1, 0x55, 0xba, 0x2e, 0x5d, + 0xb0, 0x47, 0x9f, 0x2e, 0x8e, 0x0f, 0xbf, 0x9e, 0x8a, 0xbb, 0x49, 0xdd, 0x8b, 0x47, 0x9f, 0x04, + 0xce, 0xfa, 0xb4, 0xff, 0xf1, 0x34, 0xbb, 0x45, 0x65, 0x32, 0xbf, 0xc8, 0xba, 0x5a, 0xf2, 0xb7, + 0xbd, 0x63, 0x51, 0xb8, 0x57, 0x48, 0xcd, 0x37, 0xcc, 0x3b, 0x63, 0x8d, 0x9c, 0x1e, 0xef, 0x7c, + 0x39, 0x39, 0x3a, 0x3c, 0x3e, 0xbd, 0xf8, 0xf8, 0xf9, 0xf0, 0xf0, 0x43, 0x76, 0xbb, 0x6b, 0x65, + 0x78, 0x8e, 0x5d, 0x91, 0xf3, 0x61, 0xff, 0x78, 0x6f, 0x57, 0x1b, 0x5a, 0x65, 0xc3, 0xa2, 0x50, + 0x36, 0xad, 0x9d, 0x5f, 0x3e, 0x1f, 0xee, 0x7c, 0x90, 0xd8, 0xfc, 0xaf, 0x59, 0x9f, 0x85, 0x9c, + 0x93, 0xa3, 0xc3, 0x2f, 0x27, 0x7b, 0x59, 0xc7, 0xb9, 0xec, 0xd3, 0xbf, 0x9d, 0x5e, 0x1c, 0x9c, + 0xfc, 0xa0, 0x81, 0x45, 0xcf, 0xdd, 0xd9, 0xfd, 0x69, 0x41, 0x87, 0x3b, 0x1f, 0xbe, 0xed, 0x1d, + 0x9f, 0x66, 0x34, 0x46, 0x2e, 0xf3, 0x87, 0xe3, 0x23, 0x68, 0xd8, 0xed, 0x2e, 0xcc, 0xfd, 0xb0, + 0x73, 0xba, 0xa3, 0x41, 0x37, 0xd7, 0xf2, 0x97, 0xc3, 0x2f, 0x6c, 0x3e, 0x1b, 0x95, 0xd9, 0x47, + 0x3b, 0xa7, 0x9f, 0xdc, 0xcd, 0xea, 0xb9, 0x1c, 0xef, 0xec, 0xee, 0xb9, 0x5b, 0xd5, 0x60, 0xd8, + 0xf9, 0xf9, 0x62, 0xf7, 0xeb, 0xc9, 0xe9, 0xe1, 0x01, 0xac, 0x75, 0x05, 0xcd, 0xc2, 0x2e, 0x73, + 0x7e, 0xb8, 0x21, 0xdc, 0x27, 0x4e, 0xf5, 0x63, 0xfd, 0x19, 0xc7, 0xfa, 0x81, 0x96, 0xd4, 0xca, + 0xc4, 0x7b, 0x88, 0x12, 0x2f, 0x90, 0xd4, 0x0a, 0x4d, 0xbd, 0x98, 0x70, 0x11, 0x43, 0x80, 0x6d, + 0x37, 0xad, 0x48, 0x6d, 0xb9, 0x21, 0x4f, 0x4d, 0x93, 0x29, 0xc5, 0x17, 0x80, 0x22, 0xd5, 0x25, + 0x7f, 0x0c, 0x49, 0xfc, 0xa6, 0x2f, 0x96, 0xb9, 0xe0, 0x21, 0x61, 0xca, 0x45, 0x15, 0x4a, 0xd5, + 0xc7, 0x93, 0x6f, 0xf6, 0x88, 0x27, 0xea, 0x0d, 0xeb, 0xe5, 0x8a, 0x4d, 0x6b, 0xc5, 0xab, 0x1b, + 0xbf, 0x15, 0xa2, 0xda, 0x42, 0x85, 0x6f, 0xa0, 0x7a, 0x11, 0xa1, 0x9e, 0xc8, 0xc5, 0xd8, 0x4b, + 0x6f, 0x70, 0x70, 0x11, 0x24, 0x17, 0x71, 0x42, 0x2f, 0x52, 0xcc, 0x80, 0x30, 0x0e, 0x85, 0x4e, + 0x2b, 0x24, 0x07, 0x2c, 0xff, 0x43, 0xf2, 0x25, 0xa1, 0xc7, 0x2a, 0xf3, 0xf9, 0x54, 0x1d, 0xbb, + 0x19, 0xe3, 0x35, 0xd2, 0xc8, 0x1d, 0x7d, 0x40, 0x7b, 0x8c, 0x5c, 0x59, 0x7c, 0x40, 0x1f, 0x1f, + 0x97, 0x94, 0xe0, 0x27, 0x4d, 0xbb, 0x2c, 0x91, 0xbc, 0xff, 0xd8, 0x15, 0x49, 0x0b, 0x57, 0x24, + 0x8f, 0xf5, 0x5b, 0xb8, 0x35, 0xb9, 0x37, 0x7a, 0x96, 0xbe, 0x69, 0x82, 0x19, 0x11, 0xa9, 0xc4, + 0xe2, 0xcc, 0x24, 0x8c, 0x54, 0x23, 0x71, 0xdf, 0x5a, 0x1f, 0xa1, 0x61, 0x8e, 0x46, 0x9d, 0x82, + 0x81, 0xd1, 0xd3, 0x48, 0x54, 0x1f, 0xde, 0xaa, 0x46, 0xec, 0xa1, 0x1f, 0x01, 0xd9, 0xaa, 0xfe, + 0xd5, 0x1d, 0x6a, 0xe2, 0xed, 0xed, 0x9e, 0xf5, 0xc6, 0x5e, 0x50, 0x98, 0x8f, 0x28, 0xbb, 0x71, + 0xf1, 0x5a, 0xaf, 0xcd, 0x9e, 0x97, 0xf2, 0xe8, 0x28, 0xc3, 0xea, 0x38, 0x69, 0x94, 0x6f, 0x38, + 0x75, 0x74, 0x72, 0x67, 0xca, 0x92, 0xb5, 0xd5, 0x50, 0x34, 0xe3, 0xb0, 0xca, 0xfb, 0x6e, 0x51, + 0xe5, 0x82, 0x4e, 0x76, 0x01, 0x30, 0x17, 0x56, 0x97, 0x46, 0x63, 0x35, 0x0c, 0x57, 0x1f, 0xd5, + 0x69, 0x39, 0x28, 0x9e, 0x5d, 0x81, 0x9c, 0x2b, 0xcc, 0xb6, 0x7e, 0xae, 0x77, 0xc6, 0x24, 0x62, + 0x21, 0xd9, 0xa8, 0x50, 0xaa, 0xe6, 0x67, 0xaa, 0xbd, 0xce, 0x3b, 0xcf, 0x9f, 0xfe, 0xdc, 0xfd, + 0xc8, 0x91, 0x51, 0x71, 0x8b, 0xcf, 0xab, 0x90, 0xc0, 0x8c, 0xdc, 0x85, 0xc0, 0x6c, 0x57, 0x20, + 0x14, 0x6b, 0xe6, 0x7b, 0x04, 0xd7, 0x72, 0x1b, 0x9e, 0x1d, 0x04, 0x87, 0xf7, 0x65, 0xb0, 0x0f, + 0xa3, 0x5f, 0x2e, 0xc5, 0x0f, 0x83, 0x2c, 0xc6, 0xbf, 0xaa, 0xca, 0x15, 0x0e, 0x98, 0xac, 0x50, + 0x48, 0x5e, 0x5e, 0x33, 0xdf, 0x57, 0x31, 0xdd, 0xe8, 0x8b, 0xd8, 0x28, 0x8e, 0x46, 0xb0, 0xcc, + 0xe7, 0x21, 0x61, 0xf3, 0x64, 0xe2, 0xb8, 0x32, 0x8b, 0xa5, 0xc1, 0xa0, 0x78, 0xe0, 0xd9, 0x80, + 0x64, 0xf5, 0x0f, 0x61, 0x8a, 0x7d, 0xfa, 0xac, 0xfa, 0x7c, 0x54, 0xf3, 0x22, 0x8a, 0xad, 0x58, + 0xbd, 0xed, 0x6d, 0xb6, 0x7c, 0x19, 0x15, 0xb2, 0x96, 0x7d, 0xcb, 0xd5, 0xac, 0xc0, 0xbb, 0xc5, + 0xf5, 0xcc, 0x75, 0xa3, 0x56, 0xb4, 0x48, 0x07, 0x48, 0xf0, 0x1d, 0xef, 0xfd, 0x55, 0x41, 0xbb, + 0x92, 0x22, 0xc8, 0x0a, 0xf2, 0xef, 0xea, 0xd2, 0x82, 0x40, 0x50, 0x8b, 0xc2, 0x3f, 0xab, 0xcb, + 0xee, 0xec, 0xfe, 0x24, 0xcb, 0xed, 0xec, 0xfe, 0xb4, 0xa0, 0x0c, 0x23, 0x1c, 0x54, 0x31, 0xf6, + 0x55, 0x5d, 0x52, 0x50, 0x11, 0xb2, 0xa8, 0xf8, 0x5c, 0x5c, 0x16, 0x68, 0x0a, 0xbd, 0x30, 0x7c, + 0x2f, 0x18, 0x83, 0x20, 0x31, 0xd4, 0x28, 0xc4, 0x77, 0x75, 0x69, 0xa0, 0x38, 0x64, 0x49, 0xf8, + 0xbd, 0x00, 0x4e, 0x40, 0x7c, 0x68, 0x5b, 0x77, 0x77, 0x01, 0x3c, 0x33, 0x42, 0x44, 0xc1, 0x5f, + 0xa5, 0x2c, 0xd8, 0xe1, 0x85, 0x4b, 0x76, 0xf1, 0x06, 0x53, 0x84, 0xeb, 0x9a, 0xfa, 0x64, 0xdb, + 0x0b, 0x6e, 0xe3, 0xd2, 0x5d, 0x9b, 0xa3, 0x75, 0x5a, 0xdd, 0xee, 0x7c, 0xe1, 0xad, 0x5c, 0xd1, + 0x21, 0x67, 0x54, 0x38, 0x23, 0x2c, 0xc6, 0xf6, 0x87, 0xf6, 0xab, 0x06, 0xdb, 0x5a, 0x26, 0xe5, + 0xd1, 0x2a, 0xf2, 0xbb, 0xa5, 0xbf, 0x7c, 0xaf, 0x57, 0x57, 0x3d, 0xc6, 0xbf, 0x2d, 0xac, 0x99, + 0x3b, 0x01, 0x8b, 0xaa, 0x73, 0x15, 0xc5, 0x82, 0x36, 0xf2, 0xe7, 0xa2, 0xba, 0x09, 0xae, 0x5f, + 0x5d, 0xd0, 0x40, 0x76, 0x58, 0xaa, 0x2b, 0xef, 0xf8, 0x37, 0x8b, 0x6a, 0xea, 0x47, 0x68, 0x41, + 0x65, 0xa6, 0xb3, 0x58, 0x54, 0x3f, 0xbf, 0xfd, 0x17, 0xb4, 0x10, 0x27, 0x31, 0x87, 0x60, 0xe5, + 0x9e, 0xac, 0x5e, 0xa7, 0xb2, 0x28, 0x44, 0x50, 0x8d, 0x25, 0x51, 0x88, 0x0c, 0xab, 0x91, 0xfa, + 0x8e, 0x9e, 0x8e, 0x02, 0x4c, 0xa8, 0x43, 0xcb, 0xed, 0xb3, 0xa1, 0x3c, 0xb9, 0x79, 0x14, 0xe7, + 0x3f, 0xa5, 0xf8, 0x64, 0x01, 0xbd, 0xc4, 0x86, 0x11, 0x8b, 0xbe, 0xc1, 0x6f, 0x27, 0x7d, 0x98, + 0x80, 0x3a, 0x2d, 0xa9, 0x1a, 0x87, 0xdc, 0x15, 0x7f, 0xde, 0x5c, 0xe5, 0xb6, 0xf9, 0xf3, 0x7a, + 0x60, 0x7b, 0x4b, 0xbe, 0x86, 0xe8, 0xf9, 0x37, 0x17, 0x60, 0x30, 0xe5, 0xe8, 0x5d, 0x54, 0xd4, + 0x11, 0x5b, 0x4a, 0x8c, 0xea, 0xd7, 0x58, 0x33, 0xdf, 0xcf, 0x0d, 0x4e, 0x85, 0x6a, 0x60, 0x02, + 0xb3, 0x8b, 0x1b, 0xfc, 0xe0, 0x60, 0x2d, 0xe4, 0xb7, 0x12, 0xcb, 0x39, 0x38, 0x13, 0xd1, 0x21, + 0x6f, 0x32, 0xb9, 0x08, 0x40, 0xdf, 0x85, 0x8b, 0x82, 0xde, 0xf9, 0xc2, 0x9d, 0xf9, 0x9d, 0xf0, + 0xe1, 0x22, 0x61, 0x09, 0xa2, 0x39, 0xfa, 0x84, 0xdd, 0x6b, 0x2e, 0x5a, 0xd8, 0x2d, 0xc8, 0x9b, + 0x80, 0x0e, 0x60, 0x91, 0x56, 0x40, 0x5f, 0xa1, 0xfb, 0x21, 0x60, 0x2d, 0xb2, 0x1f, 0xd3, 0x45, + 0x68, 0x0f, 0x96, 0x43, 0xec, 0xa0, 0xec, 0x8b, 0xfd, 0xe4, 0xe1, 0x5a, 0x4c, 0x6b, 0xdd, 0xa4, + 0x75, 0xfc, 0xc6, 0xb6, 0xac, 0x37, 0x60, 0x2e, 0x73, 0x4f, 0xdc, 0x5d, 0xde, 0xef, 0xb1, 0x14, + 0x69, 0x48, 0x47, 0x9f, 0xd7, 0x64, 0xc6, 0x85, 0xaa, 0x49, 0xbc, 0x9b, 0xc4, 0x31, 0x73, 0xae, + 0x31, 0x79, 0xb8, 0x77, 0x2e, 0x4a, 0x65, 0xb3, 0x0e, 0x32, 0x9b, 0x04, 0xd3, 0x6b, 0xac, 0x34, + 0xb2, 0x91, 0x11, 0xe1, 0xe7, 0x5c, 0xdf, 0x04, 0x28, 0x1e, 0x9e, 0x92, 0x88, 0xa5, 0xeb, 0x4e, + 0x12, 0x7f, 0x08, 0x89, 0xaf, 0x77, 0x97, 0x95, 0x0b, 0xb4, 0x1c, 0xc3, 0x12, 0x12, 0x5f, 0x3f, + 0x4a, 0xd8, 0x81, 0x28, 0x79, 0x90, 0x9c, 0x8e, 0x42, 0x52, 0x1b, 0x63, 0x3a, 0x4a, 0xb2, 0x50, + 0x83, 0xe1, 0x78, 0xc2, 0xdf, 0xa3, 0xc6, 0x41, 0xed, 0xea, 0xa1, 0x46, 0x47, 0xb8, 0x46, 0xa6, + 0x57, 0x6c, 0xda, 0x0d, 0xd5, 0x22, 0x01, 0xdb, 0x84, 0x84, 0x59, 0x87, 0x30, 0x13, 0x20, 0x6e, + 0xb4, 0xf9, 0x92, 0xad, 0x0b, 0x5b, 0x19, 0x69, 0x24, 0x93, 0xdb, 0x4c, 0x47, 0x7d, 0x9c, 0xc9, + 0x8b, 0x4d, 0xaf, 0xa1, 0xdb, 0xd5, 0x34, 0x64, 0x0d, 0x90, 0x1c, 0x67, 0x85, 0xec, 0xdc, 0x27, + 0x29, 0xda, 0x1e, 0xf6, 0x2c, 0x95, 0x2f, 0x88, 0x3b, 0x83, 0x62, 0x42, 0xc1, 0x29, 0x2e, 0x5b, + 0xc6, 0xf2, 0xa4, 0xf5, 0xc0, 0xcf, 0xa5, 0xa1, 0x67, 0x46, 0x3d, 0x99, 0x08, 0x43, 0xc6, 0x24, + 0xe4, 0xb3, 0x08, 0x17, 0xcf, 0x22, 0xab, 0x6c, 0x21, 0xbd, 0x18, 0xce, 0x7f, 0x52, 0xf5, 0xa9, + 0x44, 0xeb, 0x71, 0xae, 0x04, 0x31, 0x13, 0x15, 0x07, 0x15, 0x26, 0x19, 0xe6, 0x26, 0x99, 0x2e, + 0x9f, 0x5f, 0xb8, 0x72, 0x7e, 0x39, 0x3b, 0xa5, 0xe2, 0x93, 0xbf, 0x42, 0x3d, 0xb0, 0x7c, 0x92, + 0xb9, 0x16, 0xe0, 0x35, 0xec, 0xdc, 0x5c, 0xd3, 0xfc, 0x5c, 0xd3, 0xf2, 0x5c, 0xd3, 0xdc, 0x84, + 0x92, 0xe5, 0x13, 0x4a, 0x97, 0x4e, 0x48, 0x33, 0xb2, 0xca, 0x8b, 0x35, 0x8e, 0xfa, 0x74, 0xf1, + 0x24, 0xb4, 0x5a, 0x16, 0xc2, 0x6b, 0x6b, 0x45, 0x55, 0x07, 0x5e, 0x3e, 0x24, 0xba, 0x6a, 0x48, + 0x99, 0x65, 0xd7, 0xd3, 0xcf, 0x40, 0xae, 0xda, 0xf7, 0xed, 0x61, 0xbd, 0xff, 0xa7, 0x03, 0xe5, + 0x24, 0x3f, 0x80, 0x17, 0x85, 0x49, 0xde, 0xba, 0xed, 0x59, 0x83, 0xd2, 0x2b, 0xe6, 0x94, 0x4e, + 0xdf, 0x3b, 0x22, 0xcd, 0xbc, 0xee, 0x79, 0x50, 0xca, 0xea, 0xa9, 0xf1, 0x28, 0xb3, 0xeb, 0xef, + 0x18, 0x51, 0xd1, 0xc0, 0x4f, 0x17, 0xa2, 0xa2, 0x00, 0xf9, 0x48, 0x3c, 0x55, 0x1e, 0x89, 0x41, + 0x46, 0x4b, 0xf0, 0x69, 0xa1, 0x29, 0x0b, 0x45, 0x8d, 0x9c, 0x8f, 0x88, 0xfe, 0x6d, 0xe6, 0xb3, + 0xe1, 0x80, 0xea, 0x9f, 0x49, 0xa1, 0x72, 0xaa, 0xbe, 0xa5, 0xb1, 0x79, 0x08, 0x6e, 0x85, 0x32, + 0x51, 0xed, 0x97, 0x40, 0x25, 0xc9, 0x14, 0xbf, 0x94, 0x32, 0x5a, 0x0e, 0xaf, 0x68, 0xf9, 0x0a, + 0xe6, 0xad, 0x1f, 0x9f, 0x7e, 0xd2, 0x0a, 0x15, 0xbf, 0xf3, 0xac, 0x69, 0xe6, 0x96, 0x7f, 0x00, + 0x99, 0xea, 0xd5, 0xcb, 0xb8, 0x12, 0x97, 0x93, 0x68, 0x1e, 0xc1, 0xc6, 0xf9, 0xcf, 0xef, 0xc2, + 0xa5, 0x99, 0xa5, 0xe8, 0xf3, 0xce, 0x83, 0xa8, 0xf4, 0x82, 0x87, 0x53, 0x59, 0xa9, 0x3e, 0x63, + 0x20, 0xaa, 0x4e, 0x41, 0x33, 0xfd, 0x32, 0x58, 0x82, 0x5b, 0xc8, 0x16, 0x1d, 0x74, 0x8e, 0xfa, + 0xf1, 0x13, 0x30, 0x05, 0xaf, 0x6b, 0xa1, 0xb8, 0x51, 0xf0, 0x45, 0x2a, 0xa6, 0xd0, 0xe5, 0x43, + 0x8d, 0x57, 0xc0, 0x4c, 0xb3, 0xdc, 0x7d, 0x16, 0xdc, 0xb4, 0x7a, 0x2f, 0x0a, 0x3b, 0xcd, 0x72, + 0xf8, 0x39, 0x1b, 0x4a, 0xab, 0xf6, 0x92, 0xc3, 0xc9, 0x19, 0xaa, 0x42, 0x1c, 0xff, 0x69, 0x14, + 0x3d, 0x79, 0x50, 0xb9, 0xca, 0x3a, 0xc9, 0xf0, 0x02, 0x03, 0xcb, 0x19, 0x50, 0x3f, 0x03, 0x50, + 0xb9, 0x7a, 0x2f, 0x09, 0x29, 0x6e, 0xc0, 0xfd, 0x74, 0x7c, 0xca, 0xcb, 0x97, 0x88, 0xf1, 0x94, + 0x25, 0x7f, 0x17, 0x39, 0x5e, 0x32, 0x20, 0x7f, 0x16, 0x39, 0x95, 0xaf, 0xfa, 0x3d, 0xe3, 0xd0, + 0x0c, 0xd4, 0x9f, 0xb1, 0x40, 0x5a, 0xad, 0x17, 0xc4, 0x8d, 0x45, 0xeb, 0xf8, 0xa7, 0x83, 0xa4, + 0x58, 0xf3, 0x7b, 0x20, 0x52, 0xb4, 0xc7, 0x7f, 0xf6, 0xbe, 0xd5, 0x87, 0xf1, 0x92, 0xf8, 0x5a, + 0xb9, 0x04, 0x3c, 0x13, 0x57, 0xab, 0x7a, 0x0a, 0x2b, 0xf3, 0xa5, 0x92, 0xb6, 0x8c, 0x7a, 0x2a, + 0xd1, 0x70, 0xb7, 0x74, 0x02, 0xfd, 0x0e, 0xcc, 0xad, 0x1c, 0x17, 0x9e, 0x3d, 0x64, 0x56, 0x6b, + 0xe1, 0xd0, 0xc4, 0x41, 0xfc, 0xee, 0xb1, 0x29, 0x3f, 0x8a, 0xe7, 0xd2, 0xed, 0xb2, 0xde, 0x4b, + 0xaf, 0xb0, 0xee, 0x61, 0xf1, 0xcc, 0x31, 0xe9, 0x55, 0xf3, 0x87, 0xb2, 0xf9, 0x8c, 0xcf, 0x17, + 0x98, 0x83, 0xb2, 0x53, 0x7f, 0xf6, 0xa2, 0xab, 0x9a, 0x7f, 0xee, 0x9e, 0xd4, 0x7c, 0x54, 0x9e, + 0x47, 0x0e, 0x66, 0xf5, 0xfe, 0x44, 0x10, 0x4a, 0x97, 0x99, 0xe7, 0x31, 0xfd, 0xac, 0xca, 0x8b, + 0x32, 0x91, 0x39, 0x67, 0x9d, 0x3f, 0x28, 0x33, 0xd2, 0x5a, 0x78, 0xa2, 0xe0, 0x48, 0xda, 0x86, + 0xe9, 0x82, 0x24, 0x66, 0x24, 0x91, 0x14, 0x8a, 0x7c, 0x97, 0xb0, 0x28, 0x73, 0x99, 0x7a, 0xa6, + 0x68, 0x85, 0x57, 0x7a, 0x59, 0x66, 0x5d, 0x8d, 0x84, 0x1b, 0x0c, 0xf2, 0x80, 0xb4, 0x7c, 0x34, + 0xc9, 0xd2, 0xed, 0xa8, 0x46, 0x93, 0xe4, 0x47, 0x93, 0xe4, 0x99, 0x58, 0xca, 0x98, 0xd8, 0xa4, + 0x00, 0xdf, 0x65, 0x43, 0x4e, 0x96, 0x0f, 0x59, 0x7a, 0x25, 0x3d, 0x83, 0x2f, 0x95, 0x55, 0xbe, + 0x8b, 0x23, 0x15, 0xee, 0x6b, 0xcf, 0x39, 0xb3, 0xa2, 0xca, 0x8b, 0xa2, 0x38, 0xe5, 0x39, 0xf7, + 0xbc, 0xf9, 0xf3, 0x3a, 0xdf, 0x2d, 0xc2, 0x95, 0x5e, 0x7a, 0xcf, 0xde, 0x2e, 0x5a, 0x5d, 0xb5, + 0x1b, 0x74, 0x76, 0x3c, 0x29, 0xb3, 0xe3, 0x49, 0x1e, 0xc7, 0xbd, 0xe0, 0x16, 0xca, 0xb9, 0x17, + 0x3e, 0x0f, 0x09, 0x6b, 0x15, 0xff, 0xf8, 0x39, 0x84, 0x17, 0x0f, 0xbd, 0x31, 0x3e, 0x16, 0x2f, + 0x49, 0x64, 0xaf, 0x46, 0x32, 0xb5, 0x45, 0x0a, 0x11, 0xa5, 0xe4, 0x1b, 0x77, 0x0b, 0x2c, 0xc9, + 0xfa, 0xf0, 0xfe, 0x88, 0xd7, 0xc8, 0x79, 0x2e, 0x36, 0x0e, 0x6f, 0x06, 0xc2, 0xbb, 0xe7, 0xf0, + 0x46, 0xa9, 0xfe, 0xa8, 0xe5, 0x54, 0x95, 0xdd, 0x4b, 0x53, 0x59, 0x78, 0x2f, 0x4d, 0x57, 0x95, + 0x96, 0xde, 0x8d, 0xb2, 0x8a, 0xfc, 0x5e, 0x55, 0x4f, 0x7a, 0x38, 0xca, 0x7a, 0xf2, 0x7b, 0x55, + 0xbd, 0xbc, 0x3b, 0xa4, 0xac, 0x9d, 0x4f, 0x5d, 0xd9, 0x77, 0xce, 0xeb, 0x51, 0x8d, 0x20, 0x97, + 0x9a, 0xb5, 0x01, 0x2e, 0xed, 0xd5, 0xcd, 0xe4, 0x1c, 0x25, 0x55, 0x33, 0xb9, 0xd4, 0xa7, 0x34, + 0xa3, 0x7b, 0x92, 0x16, 0x06, 0xc3, 0x13, 0x9f, 0x38, 0x9f, 0x42, 0xdd, 0x95, 0xeb, 0xac, 0xfb, + 0xa9, 0xaa, 0x15, 0xd7, 0x13, 0x57, 0xaf, 0x7d, 0x4c, 0xb3, 0x75, 0x8f, 0x57, 0xf7, 0xa8, 0xb3, + 0xf4, 0xaa, 0x47, 0x3d, 0x71, 0x55, 0x0b, 0x79, 0xfe, 0x52, 0x36, 0x91, 0x4f, 0x5d, 0xd5, 0x46, + 0xe6, 0x1b, 0x2b, 0xeb, 0x67, 0x29, 0xab, 0xea, 0x66, 0x2c, 0x94, 0xac, 0x9b, 0xa5, 0xac, 0xec, + 0x57, 0xf8, 0xdd, 0xaa, 0x5e, 0xc5, 0xf7, 0xf3, 0x76, 0xeb, 0xb7, 0xf6, 0xea, 0xfd, 0xda, 0x7c, + 0xca, 0x7e, 0xd5, 0x1a, 0x5a, 0xb8, 0x63, 0x97, 0x37, 0xa4, 0x83, 0x50, 0x4b, 0x5a, 0xb9, 0x6b, + 0xe4, 0x9d, 0xab, 0xb6, 0x8e, 0x4c, 0x78, 0x4a, 0x4d, 0xe6, 0xd5, 0xa2, 0xd7, 0x64, 0x09, 0x2b, + 0x6b, 0x02, 0x15, 0xaa, 0x6a, 0xc1, 0xc7, 0x4a, 0xa8, 0xe7, 0xfd, 0x97, 0x0b, 0xf3, 0x94, 0xc9, + 0xe5, 0x56, 0x94, 0x73, 0x73, 0x83, 0x4b, 0x22, 0x65, 0x45, 0xfe, 0x75, 0xc4, 0xbd, 0x45, 0x4b, + 0x65, 0x35, 0xe7, 0x67, 0xb5, 0xb1, 0xb2, 0xa4, 0x45, 0xb5, 0x72, 0x2e, 0xd2, 0xda, 0x41, 0xcc, + 0x12, 0x17, 0xd5, 0xcc, 0x5c, 0xa9, 0x65, 0xb5, 0x2c, 0x65, 0x51, 0x1d, 0xc1, 0xac, 0xcb, 0x0a, + 0xe2, 0x73, 0x51, 0x69, 0xdd, 0x23, 0x5b, 0x56, 0xd1, 0xd3, 0x16, 0xce, 0x29, 0xe7, 0xaa, 0xad, + 0x2f, 0x59, 0x96, 0xba, 0xa4, 0x4f, 0xee, 0xd3, 0xad, 0x75, 0xc8, 0x13, 0x16, 0xd5, 0x28, 0xf9, + 0x76, 0xcb, 0x9a, 0xa5, 0x8c, 0x85, 0x2d, 0x48, 0xcf, 0x71, 0x55, 0x53, 0x26, 0x2c, 0xaa, 0xa1, + 0xbc, 0xcb, 0xd5, 0xe5, 0x25, 0x13, 0x16, 0xd5, 0xc8, 0xfb, 0x9a, 0x2b, 0xac, 0x97, 0x4b, 0x95, + 0x75, 0xc1, 0x25, 0x20, 0x89, 0x70, 0x23, 0x4a, 0xae, 0xcd, 0xcb, 0x69, 0x3c, 0xf2, 0xe2, 0x20, + 0x82, 0xb7, 0xe6, 0x81, 0xaa, 0x70, 0x6a, 0x60, 0x1f, 0xe3, 0xbe, 0x9e, 0xc5, 0xf3, 0x4b, 0x84, + 0x81, 0xd8, 0xd0, 0xfa, 0xcd, 0x51, 0x1a, 0xe5, 0x7d, 0x8c, 0x66, 0xd9, 0x73, 0x41, 0x05, 0xdb, + 0x93, 0x39, 0xb4, 0x54, 0xdc, 0xae, 0x0b, 0x9b, 0xd3, 0x0a, 0xae, 0x6a, 0xb3, 0xbc, 0x95, 0x17, + 0xb6, 0x9a, 0x2b, 0x8a, 0xc0, 0x16, 0x08, 0xd2, 0x1d, 0x5c, 0x72, 0x93, 0x04, 0xdf, 0xfb, 0xd3, + 0x34, 0x9c, 0x94, 0xb2, 0x58, 0x8f, 0x85, 0x53, 0xb0, 0xb0, 0xbb, 0xac, 0x1c, 0x9a, 0xb1, 0x8a, + 0xfa, 0x69, 0x58, 0x58, 0x4b, 0x14, 0x42, 0xb3, 0xc8, 0x23, 0xf4, 0x24, 0x4e, 0x1d, 0xe5, 0x0c, + 0xb7, 0x69, 0x5a, 0x6f, 0x3b, 0x08, 0x92, 0x8f, 0x09, 0x09, 0x73, 0xe9, 0x28, 0xc5, 0x04, 0xa7, + 0xb7, 0x38, 0xc8, 0x9b, 0x44, 0x09, 0x13, 0x21, 0xa7, 0xda, 0x20, 0x8c, 0x8d, 0xa9, 0x74, 0xdc, + 0x16, 0x0e, 0x4c, 0x2f, 0x89, 0x66, 0x0b, 0x3a, 0x9c, 0x5e, 0xfd, 0x84, 0x1f, 0x8e, 0x52, 0x3c, + 0x0c, 0xef, 0x73, 0xab, 0xd5, 0x13, 0x8b, 0x55, 0x3e, 0xa2, 0x8b, 0x57, 0x2b, 0x57, 0xf6, 0x0f, + 0xf4, 0x88, 0x08, 0x6b, 0xe1, 0x03, 0xb7, 0xb4, 0x5a, 0x06, 0x01, 0xed, 0xfc, 0x2f, 0x9b, 0x3e, + 0x2f, 0xf6, 0xdc, 0x95, 0xf1, 0xee, 0x96, 0xf5, 0x5e, 0x8d, 0x43, 0x16, 0x8e, 0xa2, 0x54, 0xfc, + 0x8f, 0xc0, 0x25, 0x9a, 0x4c, 0x4e, 0x70, 0x4c, 0x92, 0x74, 0x15, 0x68, 0x2a, 0xb0, 0xc7, 0xc2, + 0x91, 0xe5, 0xcb, 0x2e, 0x1a, 0x16, 0xf5, 0xae, 0x2b, 0xce, 0x9b, 0xa8, 0xb4, 0x6a, 0x38, 0x79, + 0xac, 0x99, 0xc5, 0x32, 0xad, 0x32, 0x86, 0x14, 0x7e, 0x28, 0xfd, 0x05, 0x60, 0x94, 0x2d, 0x69, + 0xe3, 0xa4, 0x48, 0x78, 0x4b, 0x38, 0x31, 0x1a, 0x82, 0xb3, 0xb2, 0x93, 0x6b, 0xa9, 0x7a, 0xe8, + 0xde, 0x94, 0x8e, 0xaa, 0x91, 0xc8, 0x44, 0xb9, 0x5b, 0xe4, 0xc0, 0x1f, 0xf3, 0x9c, 0x93, 0x38, + 0x2d, 0xa5, 0x57, 0x6f, 0x2b, 0x36, 0xf3, 0x3c, 0xf6, 0x5f, 0xb8, 0x06, 0xaa, 0xd8, 0x12, 0xa4, + 0xc9, 0x23, 0xd6, 0xe7, 0x60, 0xa6, 0xcf, 0x56, 0x1a, 0x91, 0x4e, 0x99, 0xce, 0x16, 0xa0, 0x91, + 0xdb, 0xcd, 0x22, 0x3d, 0xbf, 0xa3, 0x3a, 0x16, 0xf2, 0x82, 0x5b, 0x16, 0x0f, 0x89, 0xa7, 0x4b, + 0xe1, 0x0d, 0xb3, 0x3f, 0xf0, 0x88, 0xd0, 0xb7, 0x56, 0x40, 0x2f, 0xb8, 0xfd, 0xec, 0x51, 0xa7, + 0xe8, 0x00, 0x0c, 0xc9, 0x49, 0x5c, 0x4a, 0x86, 0x96, 0x0e, 0x92, 0xa0, 0x1a, 0x29, 0x6b, 0x2c, + 0x6b, 0x01, 0x3c, 0x45, 0x26, 0x57, 0x20, 0x63, 0x9d, 0x6d, 0xd5, 0xb6, 0xd2, 0xa2, 0x78, 0x80, + 0xdb, 0xcd, 0x81, 0x0e, 0x20, 0x87, 0xfb, 0x15, 0x2f, 0xec, 0x66, 0x2f, 0x4d, 0xd1, 0x0c, 0xa7, + 0x2c, 0x50, 0x03, 0x3c, 0x16, 0x3d, 0x5f, 0xc4, 0xad, 0x2d, 0x1d, 0x6c, 0xae, 0x0a, 0x9a, 0xf9, + 0x30, 0x94, 0xea, 0xe9, 0x17, 0x59, 0xa3, 0xa7, 0x34, 0xfb, 0xdf, 0x6f, 0x93, 0x54, 0x33, 0xae, + 0x4b, 0x61, 0x95, 0xab, 0x82, 0x66, 0xe3, 0x84, 0x50, 0x90, 0xbb, 0xc4, 0xf4, 0xb3, 0x47, 0xe8, + 0x78, 0x51, 0x47, 0x39, 0x46, 0x77, 0x69, 0xfb, 0x50, 0x92, 0x21, 0x21, 0xb0, 0x3a, 0xcf, 0x41, + 0x51, 0x06, 0x98, 0xdf, 0xf1, 0x6f, 0x76, 0x95, 0x2d, 0xaf, 0x06, 0x17, 0x88, 0xa3, 0xc3, 0x63, + 0xa4, 0x2c, 0x98, 0x6c, 0x25, 0xcf, 0xbc, 0x7c, 0xb2, 0x7a, 0x15, 0x78, 0x4a, 0x97, 0xa1, 0x1c, + 0x16, 0x7b, 0x8d, 0x3f, 0x44, 0xb1, 0xec, 0xae, 0xa8, 0xe6, 0xaf, 0x97, 0xf6, 0x97, 0xaf, 0x83, + 0x66, 0x57, 0xfc, 0xfb, 0x20, 0x8c, 0xa2, 0x10, 0x12, 0x75, 0x14, 0xcc, 0x9d, 0x0d, 0x59, 0x57, + 0x15, 0xac, 0xf8, 0xd2, 0x6e, 0xb2, 0xf2, 0x68, 0x06, 0xc4, 0xdf, 0x9d, 0x97, 0xe2, 0x6f, 0x38, + 0x5d, 0x49, 0x41, 0xb1, 0xcb, 0x52, 0x56, 0xb8, 0xb8, 0x9a, 0x86, 0x51, 0x00, 0x76, 0xdb, 0xc5, + 0x0d, 0x6c, 0xb7, 0x2c, 0x34, 0xf6, 0xe2, 0x29, 0xbc, 0x89, 0x3d, 0x4d, 0x71, 0x7a, 0x90, 0x04, + 0x38, 0x72, 0xf2, 0x21, 0x02, 0x38, 0xf9, 0x5b, 0x16, 0x03, 0x2c, 0x1d, 0x77, 0x56, 0x1e, 0xcd, + 0x26, 0x59, 0x78, 0xae, 0xc2, 0xb1, 0x9a, 0x0b, 0x2b, 0xe6, 0xbc, 0x9c, 0x60, 0x39, 0x40, 0x44, + 0x69, 0x81, 0x0a, 0xab, 0xf8, 0xf2, 0xc2, 0xed, 0x2a, 0x2f, 0x41, 0x79, 0xbd, 0xea, 0x87, 0x37, + 0x59, 0x82, 0x36, 0xfb, 0xe0, 0x7a, 0x6a, 0xf7, 0x06, 0x4b, 0x90, 0x51, 0xd6, 0x39, 0x9a, 0xf9, + 0xe2, 0x23, 0xb8, 0x77, 0x28, 0x8f, 0x96, 0x10, 0x23, 0xfe, 0x1a, 0x69, 0x6e, 0xd6, 0x89, 0x35, + 0x2f, 0x30, 0x31, 0x5a, 0x2b, 0xf0, 0xde, 0x42, 0x6d, 0x1a, 0xab, 0x27, 0xaf, 0xe1, 0xd1, 0x5d, + 0xae, 0x2c, 0x76, 0x6a, 0xaf, 0x67, 0xc9, 0xfc, 0x92, 0x1d, 0xd0, 0x92, 0x38, 0x61, 0xf9, 0x29, + 0x95, 0xc5, 0x17, 0xd1, 0x35, 0x63, 0xef, 0x5e, 0x8a, 0xeb, 0x33, 0x74, 0x58, 0x44, 0x0a, 0x25, + 0x41, 0xc4, 0xca, 0x3e, 0x79, 0x78, 0x8e, 0x99, 0x8a, 0xd4, 0x51, 0xb9, 0xf6, 0x79, 0x51, 0xc5, + 0x8a, 0x85, 0x2b, 0x9e, 0x5d, 0x11, 0xad, 0xf8, 0x1b, 0x3c, 0xbc, 0xc5, 0xa3, 0x6c, 0xcc, 0xe6, + 0x7d, 0xca, 0x78, 0xcb, 0x2c, 0x1e, 0x63, 0x03, 0xc2, 0x31, 0x0e, 0x52, 0xb7, 0xe2, 0x80, 0x26, + 0x45, 0x07, 0xe1, 0xe9, 0x04, 0x1c, 0x1d, 0x4e, 0xb0, 0xaf, 0xe7, 0x09, 0x94, 0xf5, 0xdb, 0x14, + 0x4f, 0x31, 0xc0, 0x27, 0xd1, 0xc7, 0x36, 0x77, 0x4a, 0xfd, 0x31, 0xc9, 0x37, 0x74, 0x18, 0x27, + 0x21, 0x61, 0xee, 0x8e, 0xa9, 0xa8, 0x93, 0x75, 0xa4, 0xc8, 0xed, 0x44, 0x3f, 0xc6, 0x92, 0x88, + 0x4a, 0xf2, 0xb4, 0x39, 0xbd, 0xdf, 0x09, 0xd3, 0xea, 0x41, 0xa5, 0x0b, 0xb3, 0x2a, 0x06, 0x26, + 0x02, 0x51, 0xb2, 0x90, 0x23, 0xb3, 0x14, 0x62, 0xd6, 0x95, 0xda, 0x23, 0x10, 0xbf, 0xaf, 0x94, + 0xca, 0xae, 0x04, 0x1e, 0x46, 0xad, 0x3a, 0x8f, 0x3b, 0x65, 0x56, 0x64, 0x82, 0x08, 0x69, 0x51, + 0x45, 0xc8, 0x5b, 0x5a, 0x91, 0xb9, 0x0f, 0xc0, 0xcc, 0x16, 0xd2, 0x35, 0x6e, 0x67, 0x50, 0xac, + 0xca, 0x23, 0xdc, 0xc8, 0xa0, 0x66, 0x95, 0x7b, 0x13, 0x20, 0x22, 0xa3, 0x9e, 0x30, 0x16, 0x27, + 0x46, 0xcc, 0xa3, 0x25, 0xd5, 0x11, 0x4a, 0x49, 0x00, 0x56, 0xd8, 0x9b, 0x6a, 0x75, 0x16, 0x78, + 0x30, 0x89, 0xcf, 0x34, 0x57, 0x1c, 0x85, 0xf9, 0xdc, 0xa0, 0x14, 0xc6, 0x05, 0xf9, 0x85, 0xbd, + 0x3f, 0x72, 0xf5, 0x63, 0xe3, 0x5b, 0xfd, 0x95, 0xd8, 0x48, 0x8e, 0x1c, 0xcd, 0x48, 0x9c, 0xc2, + 0x0c, 0xc5, 0xa1, 0xb7, 0x9d, 0x58, 0xfd, 0x6e, 0x39, 0x09, 0xd2, 0xf0, 0x55, 0xaa, 0xd8, 0x87, + 0x90, 0x81, 0x02, 0xf6, 0x8b, 0x13, 0xb0, 0x9f, 0x90, 0xe8, 0x73, 0xf8, 0x8c, 0x04, 0x79, 0x50, + 0xd0, 0x7f, 0xac, 0x20, 0x11, 0x78, 0x69, 0x01, 0xef, 0x3c, 0x3f, 0x25, 0x42, 0x88, 0x16, 0x91, + 0xd1, 0x69, 0x55, 0xfa, 0x62, 0x72, 0xef, 0x79, 0x34, 0x56, 0xe5, 0x55, 0xd9, 0xe6, 0x97, 0xa0, + 0x17, 0xed, 0x04, 0x81, 0x0a, 0x6c, 0x99, 0x5f, 0x47, 0xae, 0xce, 0xc2, 0xbf, 0x55, 0x70, 0x80, + 0x90, 0xf5, 0xfe, 0x6e, 0x41, 0xc6, 0xc9, 0xb0, 0xa2, 0xa1, 0xdd, 0xc2, 0xe4, 0xe2, 0x8c, 0xb2, + 0xcc, 0x5d, 0xba, 0x25, 0x9d, 0xd1, 0x72, 0xd2, 0x58, 0x94, 0x46, 0x33, 0x3c, 0x49, 0xfc, 0x11, + 0x43, 0x0b, 0x95, 0xc8, 0x7c, 0x81, 0x32, 0x69, 0x69, 0xe3, 0xf9, 0x3a, 0xf2, 0xf2, 0xad, 0x96, + 0xd0, 0x33, 0xeb, 0x93, 0x2c, 0x86, 0x12, 0x44, 0xb1, 0xa1, 0xd6, 0x2c, 0x2e, 0x9c, 0x1c, 0x86, + 0xb2, 0x17, 0x1c, 0x17, 0xfe, 0x39, 0x5f, 0xc9, 0x06, 0x88, 0x9e, 0x19, 0x37, 0xb0, 0x50, 0x64, + 0x30, 0xc9, 0xd1, 0xf9, 0x6a, 0xf3, 0xb1, 0x50, 0x47, 0xf9, 0x44, 0x50, 0x5d, 0x62, 0x06, 0x43, + 0xe9, 0xf8, 0x56, 0x58, 0x52, 0x78, 0x65, 0xb7, 0xb0, 0x50, 0x08, 0x4e, 0x59, 0xac, 0xa3, 0x8e, + 0xff, 0x08, 0x70, 0xe4, 0x7a, 0xce, 0xd1, 0x22, 0x39, 0xfc, 0xf3, 0xef, 0x04, 0x0a, 0x78, 0x58, + 0x5d, 0x1c, 0x7c, 0x65, 0x15, 0xab, 0x45, 0xbc, 0x10, 0x71, 0xc5, 0x4c, 0xa6, 0x9d, 0x66, 0xaf, + 0xb0, 0xaa, 0x28, 0x8e, 0x10, 0xe3, 0x71, 0x21, 0x0e, 0x49, 0xa0, 0x18, 0x23, 0xa0, 0x10, 0x7e, + 0xc5, 0x9a, 0x5d, 0x5b, 0xd3, 0xa2, 0x2d, 0xc6, 0xa8, 0xac, 0x88, 0x2e, 0xb9, 0x8f, 0xcd, 0x75, + 0xa5, 0x78, 0xe6, 0x3a, 0xb2, 0x72, 0x74, 0xe9, 0x83, 0x50, 0xf8, 0x9b, 0xb9, 0x90, 0x93, 0x15, + 0x2c, 0x7a, 0x22, 0x2e, 0x9f, 0xaa, 0x6c, 0x60, 0xad, 0xc1, 0xa8, 0xdd, 0xb4, 0xe6, 0x28, 0x7d, + 0x91, 0xa6, 0x62, 0x33, 0x0b, 0x6c, 0x59, 0x01, 0x3b, 0xbd, 0x91, 0xaa, 0x7c, 0xd1, 0x4a, 0x35, + 0xd4, 0x4a, 0x1e, 0x36, 0xdc, 0x21, 0xd1, 0x4c, 0xac, 0x59, 0xcc, 0x62, 0xf3, 0xeb, 0xb0, 0x64, + 0xd7, 0xbc, 0xf2, 0x3d, 0x95, 0x0f, 0x95, 0xe6, 0xdb, 0x15, 0xd9, 0x5e, 0xa3, 0x10, 0xae, 0xb5, + 0xc1, 0x2a, 0xeb, 0xad, 0x89, 0xf0, 0xad, 0x7f, 0xb4, 0x3d, 0x51, 0xdd, 0x9a, 0x93, 0xa2, 0x4b, + 0xce, 0x3f, 0x17, 0xba, 0x72, 0xa1, 0xf3, 0x50, 0x2a, 0xaf, 0x33, 0xc9, 0x3b, 0x1e, 0x5c, 0xe7, + 0xbc, 0x6b, 0xcb, 0xc0, 0x04, 0x87, 0x15, 0x0d, 0x98, 0x4f, 0x80, 0x40, 0xba, 0x02, 0x02, 0x21, + 0x87, 0x00, 0x0a, 0x5f, 0xa4, 0xa9, 0x64, 0x25, 0x30, 0xd3, 0x55, 0xc0, 0x0c, 0x57, 0x02, 0x53, + 0xf3, 0xef, 0x10, 0x00, 0x4d, 0xad, 0x59, 0x62, 0xa6, 0x12, 0xa0, 0x9a, 0x63, 0xcc, 0x3f, 0x77, + 0x65, 0x35, 0x20, 0x33, 0x10, 0x55, 0x6e, 0xc9, 0x4a, 0x3f, 0xa9, 0x85, 0xb0, 0x84, 0x35, 0xd3, + 0x60, 0x19, 0xac, 0x06, 0x40, 0xb0, 0x02, 0x00, 0xbe, 0x85, 0x52, 0x80, 0xa5, 0xff, 0x22, 0x4d, + 0x85, 0x2b, 0x61, 0x19, 0xac, 0x82, 0xa5, 0xbf, 0x04, 0x96, 0x55, 0xc0, 0x12, 0x50, 0x0d, 0xac, + 0x59, 0x68, 0x06, 0x0c, 0xaa, 0xd7, 0x9a, 0xf3, 0xeb, 0x12, 0x58, 0xc2, 0xa6, 0x16, 0xcf, 0xcb, + 0xc6, 0x10, 0x8a, 0x29, 0x71, 0x53, 0x77, 0x7b, 0x16, 0xf3, 0x98, 0x4a, 0xa9, 0x16, 0x6b, 0x79, + 0x91, 0xfc, 0x76, 0xf9, 0xb6, 0xc8, 0x09, 0x2e, 0x97, 0xc3, 0x56, 0x6b, 0x10, 0x5c, 0xd7, 0xe6, + 0x8b, 0x20, 0xa0, 0x7b, 0xf5, 0x66, 0x54, 0xc0, 0x30, 0x8c, 0x25, 0xc5, 0xff, 0xfe, 0x21, 0x7f, + 0x47, 0x98, 0x5a, 0x3b, 0x39, 0xa8, 0x40, 0xf0, 0xea, 0x38, 0x30, 0x63, 0x77, 0x3b, 0x6e, 0x08, + 0xb1, 0xb0, 0xeb, 0xba, 0xb8, 0xb2, 0xc9, 0x23, 0xc9, 0xb6, 0x70, 0xd2, 0xf4, 0x59, 0xad, 0x4b, + 0x0b, 0xc3, 0x2c, 0x26, 0x83, 0x1e, 0x1d, 0x52, 0x79, 0x11, 0xc8, 0xe8, 0x54, 0x57, 0xb8, 0x51, + 0x0e, 0xa4, 0x0c, 0xc4, 0xd2, 0x9c, 0x59, 0xe4, 0x69, 0x5e, 0x8d, 0xc2, 0x80, 0x71, 0xe1, 0xe2, + 0x82, 0xb1, 0xb1, 0x76, 0x50, 0x42, 0x77, 0xba, 0x6c, 0x01, 0x98, 0x14, 0x38, 0x5c, 0xb1, 0xbd, + 0x03, 0xc0, 0xb9, 0x53, 0x6b, 0x8e, 0x56, 0x9d, 0xba, 0xa7, 0xb6, 0x96, 0x2e, 0x3f, 0x2c, 0xf9, + 0x66, 0x16, 0x1d, 0x97, 0x40, 0xc6, 0x7f, 0x8b, 0x07, 0x03, 0xaf, 0x21, 0x03, 0xc3, 0x37, 0x58, + 0xfc, 0x77, 0x34, 0x72, 0x9b, 0x28, 0xd2, 0x03, 0x45, 0x7c, 0xf0, 0x28, 0x6e, 0xc4, 0xc9, 0x9d, + 0x69, 0xbd, 0xb5, 0x71, 0xdb, 0xea, 0x2f, 0x26, 0x9a, 0x84, 0x1f, 0xbc, 0x8f, 0x46, 0x28, 0x42, + 0x1a, 0xfe, 0x0f, 0xad, 0x59, 0x6a, 0x86, 0x02, 0x7b, 0x65, 0x3e, 0xef, 0xf9, 0xa5, 0xf9, 0xef, + 0x7e, 0xad, 0x8a, 0xd0, 0xa6, 0xa5, 0xf5, 0xf0, 0xff, 0xd8, 0x5a, 0xe4, 0x43, 0x13, 0x04, 0x08, + 0x23, 0xbf, 0xfa, 0x42, 0x2e, 0xb9, 0xfe, 0x3e, 0x0d, 0xf9, 0x05, 0x4f, 0x40, 0x4e, 0x92, 0x2f, + 0x8b, 0x97, 0x80, 0xb0, 0xc0, 0xc2, 0x25, 0xab, 0x8b, 0x2a, 0x41, 0xcf, 0xb2, 0x95, 0x29, 0xf0, + 0xed, 0xf0, 0x84, 0xae, 0x09, 0xd1, 0x72, 0xd9, 0xb0, 0xc4, 0x1b, 0x2f, 0xc1, 0xdc, 0x9a, 0xa3, + 0xe4, 0xbf, 0xe6, 0x4c, 0x44, 0x5f, 0xfa, 0x4c, 0xd2, 0xff, 0xca, 0x33, 0x61, 0x76, 0x04, 0x6c, + 0x1a, 0xab, 0x8e, 0xe4, 0x7f, 0xce, 0x79, 0x30, 0x66, 0x7f, 0x19, 0x12, 0x58, 0x34, 0xec, 0xca, + 0xb2, 0x0b, 0xc6, 0xbd, 0xa4, 0x6c, 0x79, 0xe0, 0x55, 0x85, 0xcb, 0x23, 0x5f, 0x80, 0x40, 0x8a, + 0x48, 0x41, 0x11, 0x0e, 0xd7, 0x98, 0x0a, 0x03, 0x29, 0xd9, 0x8a, 0x16, 0x99, 0x92, 0x85, 0xa1, + 0xec, 0xf7, 0xa5, 0xc4, 0x58, 0x6f, 0xbb, 0xd8, 0x20, 0x7b, 0xe5, 0x99, 0x5a, 0x57, 0x29, 0xf6, + 0x6e, 0xfa, 0x58, 0xbd, 0xb6, 0xa1, 0x47, 0x9c, 0xcc, 0x45, 0xfe, 0x58, 0x85, 0x94, 0xe4, 0xdd, + 0x10, 0x33, 0x82, 0x6c, 0xf1, 0x32, 0x4b, 0x59, 0x61, 0xbc, 0x02, 0xab, 0x33, 0xb2, 0x2a, 0x65, + 0xf8, 0x61, 0xc5, 0x76, 0x7c, 0x46, 0x8b, 0x74, 0xf9, 0x3d, 0x51, 0x6e, 0x6a, 0xd1, 0x6d, 0x91, + 0x2c, 0xa1, 0xf6, 0x74, 0xb0, 0x09, 0x74, 0x0f, 0x51, 0xc1, 0xd9, 0xd3, 0x93, 0x8c, 0x7b, 0xc8, + 0x47, 0x34, 0x79, 0x3a, 0x0b, 0x16, 0xbe, 0x04, 0x07, 0x16, 0xfe, 0x57, 0x61, 0xc1, 0x72, 0x50, + 0x5a, 0x28, 0x00, 0x7a, 0x88, 0xfd, 0xdc, 0x36, 0xcd, 0x35, 0xa7, 0xb7, 0xb1, 0xf8, 0x0e, 0xb7, + 0xe6, 0x61, 0xd1, 0x6b, 0xfd, 0x9f, 0x6b, 0x52, 0xb1, 0x26, 0x45, 0xdf, 0xfe, 0xf2, 0x9a, 0xe0, + 0xca, 0xb0, 0x04, 0x2f, 0x04, 0xcc, 0xbc, 0x9d, 0xc5, 0x8b, 0xc1, 0xf5, 0xd9, 0xcd, 0xae, 0x00, + 0xf1, 0x82, 0xf6, 0x9e, 0x0d, 0xed, 0x42, 0x88, 0x87, 0x2a, 0x39, 0x44, 0x21, 0x26, 0xc5, 0x3f, + 0x37, 0x6d, 0x15, 0x22, 0xc9, 0x03, 0xa9, 0x0c, 0xc5, 0xb4, 0x18, 0x6a, 0xe4, 0x9f, 0x22, 0xb1, + 0x0a, 0x30, 0x16, 0x03, 0xb2, 0x54, 0xe0, 0xe3, 0x20, 0x38, 0x4c, 0x57, 0xc6, 0x7c, 0x5a, 0x08, + 0xdc, 0x08, 0x4d, 0x75, 0xe0, 0x0e, 0x57, 0x43, 0x64, 0xb8, 0x02, 0x22, 0x63, 0x0b, 0x45, 0x00, + 0xdc, 0xf1, 0x8b, 0x34, 0x35, 0x5d, 0x09, 0xdc, 0xe1, 0x2a, 0xe0, 0x8e, 0x17, 0x2a, 0x89, 0x56, + 0x07, 0xcb, 0x12, 0xf0, 0x1e, 0x5a, 0xb3, 0xa9, 0x39, 0x94, 0x74, 0x84, 0x28, 0x2e, 0x7d, 0x43, + 0x9f, 0xce, 0xbf, 0x07, 0xc5, 0x57, 0xac, 0x7b, 0x9d, 0xd2, 0x1b, 0xdb, 0x42, 0xca, 0x03, 0x4f, + 0x6d, 0xf7, 0x3a, 0xec, 0x91, 0xed, 0x00, 0x1e, 0xd9, 0xa6, 0xf0, 0xc8, 0xb6, 0x24, 0x12, 0x1b, + 0x99, 0x31, 0xa3, 0x7a, 0x28, 0x0b, 0xa9, 0x54, 0x37, 0xd0, 0xe7, 0x5b, 0xb5, 0x3f, 0xb4, 0xa0, + 0x9f, 0xb8, 0x01, 0x7a, 0x7a, 0x84, 0x1b, 0xcc, 0x64, 0x12, 0xe9, 0x4d, 0x67, 0x1f, 0x08, 0x4b, + 0xb9, 0x17, 0x48, 0xa1, 0x94, 0xf9, 0x23, 0x4f, 0xfe, 0xec, 0xc9, 0x1f, 0x2a, 0x82, 0x25, 0xc8, + 0x3d, 0x12, 0x21, 0xf7, 0x48, 0xf5, 0x30, 0x4c, 0xff, 0x3c, 0xe3, 0x95, 0x67, 0x3c, 0x83, 0x50, + 0x15, 0x9e, 0x14, 0x81, 0x74, 0x9e, 0xce, 0x08, 0xac, 0xb8, 0x78, 0xd3, 0x94, 0xd1, 0xd9, 0x30, + 0xa3, 0xc2, 0xd3, 0x75, 0x2b, 0x2b, 0x01, 0x65, 0x8d, 0x80, 0x76, 0x5b, 0x31, 0xd7, 0x78, 0xf1, + 0x5c, 0xf9, 0x6c, 0xca, 0xf4, 0xf9, 0x75, 0x45, 0x98, 0x9e, 0x17, 0xe2, 0x7d, 0x0a, 0x96, 0x9b, + 0x2f, 0xc6, 0x01, 0x3d, 0xbf, 0xdd, 0x15, 0x7c, 0xd0, 0xa2, 0x06, 0xff, 0x08, 0x37, 0x54, 0x04, + 0x66, 0x19, 0xe2, 0x41, 0x3e, 0x20, 0xd1, 0x0b, 0x91, 0x31, 0x9a, 0xfd, 0xea, 0x8b, 0x91, 0x33, + 0xcf, 0x6b, 0x73, 0xc5, 0x59, 0xad, 0x6a, 0xec, 0xd9, 0x67, 0x36, 0x1f, 0xcc, 0x69, 0x11, 0x45, + 0x9e, 0x0b, 0xb0, 0xf4, 0xf4, 0xcd, 0xbc, 0x14, 0xbe, 0x9a, 0x9d, 0xed, 0x53, 0x36, 0xdc, 0x42, + 0x90, 0x4a, 0xab, 0xda, 0x14, 0x76, 0x7b, 0xf8, 0x84, 0xdd, 0xfe, 0x27, 0x74, 0xfc, 0x24, 0x04, + 0xfd, 0xa7, 0xf4, 0x0b, 0xf1, 0x92, 0xd9, 0xa7, 0xb1, 0x74, 0xaf, 0x54, 0xf5, 0xbd, 0xe4, 0x30, + 0x2e, 0xd9, 0x74, 0x5a, 0xef, 0xcb, 0xf8, 0x0e, 0x7d, 0xc7, 0x94, 0x4f, 0x6c, 0x58, 0x11, 0x30, + 0xeb, 0xe9, 0xc7, 0x36, 0x78, 0x81, 0x1b, 0x75, 0x25, 0x74, 0x41, 0x05, 0x03, 0x9a, 0xc5, 0x17, + 0xba, 0x77, 0x9f, 0xd4, 0xe1, 0x53, 0x15, 0x1a, 0x2f, 0xd7, 0xdf, 0x13, 0xb7, 0xcf, 0x13, 0xc9, + 0x82, 0x27, 0x6c, 0x9b, 0x70, 0xb9, 0x70, 0x20, 0xb7, 0x25, 0xca, 0xd8, 0x28, 0x92, 0x81, 0xc1, + 0x50, 0xec, 0xc2, 0xed, 0xfd, 0x64, 0x4d, 0x60, 0x90, 0x7f, 0xa0, 0xae, 0x97, 0x7b, 0xa8, 0x90, + 0x6b, 0xd2, 0xa6, 0xab, 0xc8, 0x86, 0x88, 0x2b, 0x78, 0x86, 0xee, 0xb4, 0x91, 0x79, 0x81, 0xbc, + 0x89, 0xfb, 0xa1, 0xfb, 0x2c, 0xea, 0x23, 0x5a, 0xb2, 0x38, 0x4c, 0xf9, 0xe7, 0xe7, 0x0a, 0x2c, + 0x70, 0x05, 0x1d, 0x81, 0x22, 0xd1, 0xa0, 0xbc, 0x57, 0xc3, 0x9a, 0xa3, 0xa1, 0x35, 0x47, 0x23, + 0x36, 0x09, 0x90, 0xcb, 0x56, 0xa8, 0x54, 0x03, 0x34, 0x6d, 0xe8, 0xc6, 0x86, 0xf0, 0x5e, 0x86, + 0x66, 0xcc, 0x6f, 0xe4, 0xbd, 0x52, 0x6b, 0x21, 0xa9, 0xc5, 0x09, 0xad, 0x0d, 0x93, 0x94, 0x2d, + 0x55, 0x8d, 0x81, 0xbe, 0x96, 0xf2, 0xa7, 0xa4, 0x51, 0x2d, 0xbc, 0x8e, 0x13, 0xb0, 0x9d, 0x6b, + 0x34, 0x1a, 0x86, 0x54, 0xe4, 0xce, 0xfd, 0x08, 0x7b, 0xa9, 0x84, 0xc4, 0x2a, 0x55, 0xe8, 0x8b, + 0xc1, 0x81, 0xab, 0x67, 0x23, 0x7e, 0x6c, 0xfe, 0x63, 0x86, 0xb0, 0x42, 0xa7, 0x9b, 0xeb, 0x6b, + 0xa1, 0xd2, 0xd7, 0xcf, 0x97, 0x58, 0xdc, 0xdb, 0x62, 0x95, 0x61, 0x16, 0x38, 0x2f, 0xb3, 0x8f, + 0x48, 0x33, 0xfb, 0x08, 0xee, 0xdc, 0x0b, 0xf9, 0x2b, 0x4e, 0x4f, 0x81, 0xdd, 0x0b, 0x2b, 0x4f, + 0x4f, 0xea, 0x6a, 0xef, 0x39, 0x46, 0xab, 0xb6, 0xfd, 0x88, 0x9f, 0x9e, 0xa9, 0x1b, 0xe9, 0xa7, + 0x87, 0xf6, 0xd3, 0xe7, 0x9d, 0x9e, 0xd1, 0xaa, 0x25, 0x0b, 0x16, 0x2c, 0x59, 0xc1, 0xb1, 0xd9, + 0x87, 0x7d, 0xa3, 0x9f, 0x9f, 0x29, 0xb3, 0x86, 0x89, 0x16, 0x9f, 0x9f, 0x10, 0x45, 0x2b, 0xce, + 0x4f, 0xd9, 0xcf, 0xba, 0x74, 0x8a, 0xb8, 0x73, 0xf4, 0x73, 0x8e, 0xd1, 0x2a, 0xe5, 0xf5, 0xcb, + 0x01, 0x44, 0xac, 0x0f, 0x77, 0x4c, 0x89, 0x1a, 0x99, 0x1f, 0xb7, 0x85, 0x86, 0xdc, 0x09, 0xe5, + 0x62, 0x0c, 0x2e, 0x28, 0x17, 0xb7, 0xcc, 0x07, 0x65, 0x5a, 0x72, 0x00, 0x98, 0xa6, 0xe9, 0x05, + 0xbd, 0xbf, 0x60, 0xfe, 0x26, 0x17, 0x11, 0x8e, 0xcb, 0x45, 0x98, 0x63, 0xc9, 0x05, 0x13, 0xa2, + 0x8b, 0xcc, 0xbc, 0x67, 0xc9, 0x45, 0x0a, 0xae, 0x25, 0xc5, 0x9c, 0xf8, 0x62, 0xc2, 0x1d, 0x40, + 0x2e, 0x98, 0xef, 0xc7, 0xb4, 0xe4, 0x73, 0xa1, 0xf2, 0x99, 0x17, 0x48, 0x29, 0x9f, 0x26, 0xd4, + 0x8b, 0x2e, 0xbc, 0x30, 0xbd, 0x80, 0xf5, 0xbe, 0x20, 0x60, 0x5e, 0xbe, 0xa0, 0xd0, 0x74, 0xb2, + 0xac, 0x4c, 0xcc, 0x3a, 0x60, 0xe3, 0x0f, 0x16, 0xe6, 0x06, 0xdc, 0x33, 0xa4, 0x22, 0x1b, 0x46, + 0xbf, 0xb8, 0x32, 0xcb, 0x5d, 0x54, 0x19, 0xa7, 0xe9, 0x05, 0x7b, 0xb7, 0xbd, 0x02, 0xee, 0x0c, + 0x70, 0x60, 0xc0, 0x5c, 0x86, 0x1b, 0x6f, 0xee, 0x22, 0x98, 0x4e, 0x2a, 0xea, 0xc5, 0x7c, 0x2c, + 0xd5, 0xb9, 0xf3, 0x7e, 0x6c, 0xf2, 0x2b, 0xa5, 0x8c, 0x56, 0xff, 0xfd, 0xb6, 0xe4, 0x2a, 0xbb, + 0x8c, 0x5c, 0x6f, 0x0b, 0x11, 0x6b, 0xb0, 0x08, 0xb1, 0x96, 0xfb, 0x5b, 0x62, 0x4e, 0xac, 0xc5, + 0xfd, 0x2c, 0x0b, 0x87, 0xe0, 0xfd, 0x61, 0x19, 0x24, 0xe0, 0xbf, 0x27, 0x7e, 0x2d, 0xc7, 0x48, + 0xf8, 0x33, 0x50, 0x6c, 0x65, 0xe0, 0x86, 0x12, 0x96, 0xa5, 0xb2, 0xd4, 0x7f, 0x0a, 0x44, 0x5b, + 0x09, 0x99, 0xd8, 0x8c, 0xfe, 0xbd, 0x4f, 0xd7, 0x82, 0x15, 0xfa, 0x33, 0x0f, 0x58, 0x65, 0x97, + 0x4b, 0xac, 0xcf, 0xf2, 0xa1, 0x6c, 0xcb, 0xc7, 0x8c, 0xe8, 0x11, 0x5f, 0x61, 0x61, 0x9f, 0xcb, + 0x0b, 0x94, 0x5f, 0x5c, 0xcd, 0x88, 0xff, 0x10, 0x08, 0xfb, 0x9c, 0xfb, 0x37, 0xfa, 0x43, 0xfc, + 0x40, 0xf0, 0xef, 0xc4, 0x0f, 0x14, 0x62, 0x7f, 0x2c, 0xe7, 0x08, 0xc2, 0x57, 0xae, 0x3b, 0x6d, + 0x50, 0xef, 0xba, 0x74, 0xa4, 0xf2, 0xcd, 0x94, 0xce, 0x92, 0x38, 0x41, 0x35, 0xea, 0x5d, 0x3f, + 0xe5, 0x14, 0x05, 0x7f, 0x16, 0xc9, 0x5d, 0x9e, 0x6d, 0x62, 0xc2, 0xa5, 0x95, 0x05, 0x31, 0x59, + 0xc0, 0x04, 0xfc, 0x3b, 0x8e, 0xe8, 0xcf, 0x65, 0x03, 0xca, 0xfd, 0x2d, 0x3e, 0x49, 0xf9, 0x80, + 0xca, 0xe2, 0x20, 0xf9, 0xc0, 0x0c, 0xf8, 0x52, 0xf9, 0x93, 0x8f, 0x68, 0xfc, 0x4f, 0xdd, 0x6f, + 0xb5, 0x11, 0x49, 0x0e, 0x4a, 0x65, 0x81, 0xc4, 0xb5, 0x16, 0x79, 0xf9, 0x79, 0x20, 0x0c, 0x99, + 0xbe, 0x0a, 0xcc, 0xaf, 0xd7, 0xd6, 0xcc, 0xc5, 0x1b, 0x90, 0xb9, 0xfc, 0x3e, 0x11, 0xa4, 0x4f, + 0x80, 0xe9, 0x93, 0xdb, 0x5b, 0x01, 0xd6, 0x42, 0x3b, 0xcf, 0x86, 0xac, 0x16, 0xb1, 0x7a, 0x31, + 0x50, 0xc1, 0xff, 0xbd, 0xfc, 0x5e, 0x2e, 0xaf, 0x57, 0x72, 0x94, 0xcf, 0xaa, 0x31, 0x77, 0x81, + 0x27, 0xd5, 0x63, 0x25, 0xb3, 0x8a, 0xc2, 0xcd, 0xfc, 0x49, 0x55, 0x45, 0xd9, 0x9c, 0x39, 0x74, + 0x31, 0xea, 0xf5, 0xc2, 0x0d, 0x01, 0xcf, 0x65, 0x6b, 0x1b, 0xc2, 0x5f, 0x4e, 0xdd, 0x1d, 0xde, + 0x14, 0x50, 0x50, 0xe5, 0x15, 0x1d, 0xea, 0x04, 0xc5, 0x77, 0xb6, 0x15, 0xac, 0x3c, 0x53, 0xfe, + 0xaa, 0x95, 0x5f, 0x8a, 0x9d, 0xaa, 0xe1, 0x95, 0x61, 0xa9, 0x40, 0x60, 0x29, 0x86, 0xc7, 0xb5, + 0x13, 0x98, 0x5f, 0x98, 0x3c, 0x0e, 0x3b, 0x3b, 0xb7, 0xe6, 0x93, 0x30, 0xbe, 0x3e, 0xc6, 0x13, + 0xec, 0x51, 0x9c, 0x0a, 0x47, 0xba, 0xe7, 0xe9, 0xb5, 0x0b, 0x31, 0xca, 0x15, 0x03, 0x96, 0x19, + 0x7c, 0x15, 0x42, 0x8a, 0x9f, 0xd9, 0x76, 0x0b, 0xd9, 0xcd, 0x2e, 0xb2, 0xed, 0x26, 0xb2, 0x9b, + 0xed, 0xf3, 0x42, 0x7e, 0x8e, 0xae, 0x6f, 0x59, 0xd2, 0x44, 0x5c, 0x0b, 0x35, 0x2e, 0x48, 0xfd, + 0xac, 0x87, 0x7e, 0xb6, 0x25, 0x38, 0x79, 0x91, 0x65, 0xd5, 0x53, 0x34, 0x76, 0x3f, 0x61, 0xed, + 0x59, 0xcc, 0xa8, 0x91, 0x7a, 0x77, 0x56, 0x7f, 0x2c, 0xdf, 0xa5, 0xbc, 0x10, 0x48, 0xe5, 0x13, + 0x5e, 0xf4, 0x26, 0xf0, 0xda, 0x5a, 0x05, 0xe1, 0xad, 0xea, 0xa3, 0xc0, 0x5a, 0x86, 0x8e, 0xca, + 0xf4, 0x67, 0x55, 0xa8, 0x36, 0x46, 0xde, 0xce, 0x52, 0x4a, 0x9d, 0x21, 0x73, 0xac, 0x8d, 0x1a, + 0x22, 0x3e, 0x04, 0x62, 0xec, 0x3d, 0xff, 0x84, 0x20, 0x12, 0x73, 0xeb, 0x09, 0x5b, 0xf6, 0xc9, + 0x7d, 0x3e, 0x8b, 0x94, 0x5d, 0xdc, 0x0c, 0xad, 0x70, 0xd0, 0x7d, 0xb1, 0x11, 0xea, 0xf4, 0x19, + 0x5d, 0x76, 0x44, 0xe4, 0xbb, 0x1d, 0x67, 0xb9, 0x1d, 0x64, 0x5b, 0xe7, 0x28, 0xa8, 0x66, 0x3f, + 0xb5, 0xe0, 0xf4, 0x2f, 0x74, 0x97, 0xeb, 0x31, 0x62, 0x5e, 0xec, 0x52, 0x7f, 0x66, 0xa3, 0x2b, + 0xae, 0xa1, 0xca, 0xd6, 0xfe, 0xc8, 0x65, 0x94, 0x41, 0xaf, 0xd2, 0x5d, 0xaf, 0x10, 0x6f, 0xff, + 0xe9, 0xfe, 0x47, 0x2b, 0xb1, 0xf1, 0x93, 0xdc, 0x8f, 0x9e, 0xe0, 0x7d, 0xf4, 0xb4, 0xa6, 0xd2, + 0x95, 0x88, 0xfd, 0x09, 0x9e, 0x47, 0x8b, 0x89, 0xa5, 0x3c, 0x98, 0xca, 0xae, 0x43, 0xdc, 0xe4, + 0x36, 0xc0, 0x11, 0xa6, 0xb8, 0xbc, 0x5f, 0xf3, 0x96, 0xb7, 0x59, 0x5b, 0x86, 0x81, 0x0a, 0xd6, + 0x46, 0x76, 0xcf, 0xd2, 0xf7, 0xfc, 0x53, 0xfc, 0xfd, 0x78, 0x14, 0x83, 0x66, 0x9f, 0xef, 0x7b, + 0xcd, 0xd0, 0x3d, 0x73, 0x49, 0x2a, 0xf8, 0xb5, 0x89, 0xfe, 0x63, 0xab, 0x9f, 0x28, 0xe7, 0x40, + 0xfe, 0xac, 0x2d, 0x33, 0x79, 0x9f, 0xc7, 0x6f, 0xde, 0x28, 0x63, 0x77, 0xe6, 0xda, 0xaf, 0x7b, + 0xd1, 0xf1, 0xca, 0xab, 0x1c, 0xf3, 0xd4, 0xf0, 0x75, 0xc7, 0xbc, 0xb8, 0xca, 0x2b, 0x4f, 0xb6, + 0x77, 0xc2, 0xc2, 0x32, 0x3d, 0xab, 0xc5, 0x4a, 0xef, 0xba, 0xb8, 0xc1, 0x03, 0x3c, 0x65, 0x91, + 0xf6, 0xc3, 0xeb, 0xf8, 0x39, 0xb8, 0x23, 0xcd, 0x82, 0xdc, 0x87, 0x2e, 0x2f, 0x21, 0xc1, 0x3c, + 0xed, 0xa7, 0x4b, 0x02, 0xdf, 0xd8, 0xad, 0xcd, 0xc1, 0xd4, 0x4d, 0xb5, 0x40, 0x17, 0x76, 0x6b, + 0xd3, 0x72, 0x64, 0x52, 0x29, 0x52, 0xd2, 0x82, 0xcd, 0x26, 0x1f, 0x76, 0xe0, 0x9e, 0x79, 0x7c, + 0x0e, 0x82, 0xd5, 0x5d, 0xd2, 0x7b, 0x53, 0xda, 0x77, 0x87, 0xea, 0xc9, 0xe6, 0xf9, 0xe2, 0x0e, + 0xe4, 0x93, 0x0d, 0x20, 0xb5, 0xca, 0xf5, 0xb0, 0x98, 0xbc, 0x56, 0x11, 0xab, 0xc0, 0xc1, 0x76, + 0xf1, 0x38, 0xa6, 0x8d, 0x7c, 0xe8, 0x2a, 0x6b, 0xf1, 0xc1, 0x4e, 0x96, 0x7b, 0xe0, 0xe2, 0x55, + 0x1c, 0xac, 0x3e, 0xa2, 0xa5, 0xa5, 0x78, 0xd4, 0xab, 0x11, 0xd7, 0x0a, 0x7b, 0xd4, 0xbb, 0xa0, + 0x49, 0x72, 0x11, 0x25, 0xf1, 0xb5, 0x51, 0x00, 0x15, 0x78, 0xfb, 0x0a, 0xc1, 0xc2, 0x7f, 0xa2, + 0x51, 0x53, 0x73, 0xda, 0x50, 0x11, 0xbb, 0x98, 0x28, 0xe0, 0x3f, 0xd9, 0x00, 0x63, 0xd8, 0xab, + 0x0b, 0xbd, 0x8b, 0x73, 0x3e, 0xd2, 0x4f, 0xe9, 0x2e, 0x5e, 0x01, 0x8e, 0x55, 0x52, 0x88, 0xc5, + 0xdb, 0x5e, 0xc6, 0x1b, 0x29, 0x5d, 0x84, 0x54, 0x7f, 0x48, 0xc4, 0x6d, 0x3e, 0x87, 0xac, 0xbe, + 0x67, 0xe8, 0x29, 0x7b, 0xe2, 0xbc, 0x89, 0x3a, 0xad, 0xad, 0xce, 0x56, 0x6f, 0xa3, 0xb5, 0xd5, + 0xfd, 0x0f, 0x92, 0x76, 0x2f, 0x97, 0x95, 0xaa, 0x50, 0xb5, 0x4f, 0x60, 0x97, 0x96, 0x48, 0xb9, + 0x23, 0x10, 0xb9, 0xbd, 0x72, 0xdd, 0xb0, 0x20, 0x76, 0x93, 0x82, 0xb4, 0x1a, 0x83, 0x69, 0x0d, + 0xce, 0x1b, 0x13, 0xb9, 0x79, 0xb5, 0x20, 0x04, 0x44, 0x8d, 0x63, 0x2a, 0xb2, 0x84, 0xfc, 0xed, + 0x0f, 0x08, 0xad, 0x5f, 0x6e, 0x82, 0x7f, 0x4c, 0x58, 0xfd, 0x92, 0x00, 0x5e, 0xed, 0x32, 0x1d, + 0x54, 0x93, 0xf6, 0x15, 0xfd, 0xfc, 0x21, 0x96, 0x35, 0x7b, 0x44, 0x27, 0x44, 0x4d, 0x54, 0x2d, + 0x9b, 0x2e, 0x3e, 0x50, 0xf3, 0x4f, 0x23, 0xe1, 0x6a, 0x32, 0x31, 0x0f, 0xa6, 0xc5, 0xa1, 0x79, + 0xe8, 0xce, 0x94, 0x26, 0x5a, 0x60, 0xb3, 0x05, 0xd1, 0x74, 0x72, 0xed, 0xbd, 0xb2, 0xb5, 0xfa, + 0x07, 0xc5, 0xd0, 0x68, 0x4f, 0x6a, 0xa1, 0xa9, 0x79, 0x4a, 0x7e, 0xc1, 0xe1, 0xf5, 0xe8, 0x2a, + 0x99, 0xa6, 0xc2, 0x6a, 0xa2, 0x89, 0x62, 0xb7, 0x89, 0x12, 0xb7, 0x89, 0x52, 0x77, 0x73, 0xd9, + 0xbb, 0x66, 0x39, 0x2d, 0x05, 0x17, 0x19, 0xfd, 0xa0, 0x37, 0x97, 0x7f, 0xcc, 0xac, 0xb9, 0xe8, + 0x6d, 0x33, 0xa5, 0x90, 0x8d, 0xf3, 0x25, 0xf2, 0x4f, 0x9b, 0xc1, 0x31, 0x2c, 0x8a, 0x2c, 0x96, + 0x62, 0x5c, 0xe5, 0xaa, 0x9e, 0x5f, 0xa2, 0xa2, 0x6a, 0x45, 0x7f, 0x11, 0x0d, 0xf9, 0x82, 0xe2, + 0x0b, 0x20, 0xb4, 0x9f, 0x5f, 0x52, 0x42, 0x97, 0x93, 0xa6, 0x92, 0xcc, 0x06, 0xf4, 0x3e, 0x74, + 0x9b, 0xfd, 0xe1, 0xbb, 0xa8, 0x3f, 0x7c, 0xf3, 0x86, 0x83, 0x6d, 0x2c, 0x2a, 0xa8, 0xa7, 0xd9, + 0x1e, 0xb4, 0x16, 0x84, 0xd6, 0xfb, 0x4a, 0x24, 0xa9, 0x48, 0x63, 0x53, 0x4e, 0x89, 0x67, 0x21, + 0x94, 0x45, 0xdc, 0xb4, 0x31, 0x1a, 0x61, 0x2f, 0x0d, 0x4e, 0xb0, 0x9f, 0xc4, 0x01, 0xd9, 0xb9, + 0x4e, 0x9c, 0x07, 0x26, 0x79, 0xb8, 0x9a, 0x4b, 0x87, 0xd4, 0x19, 0xd3, 0xef, 0x67, 0xf0, 0x67, + 0x94, 0x98, 0x33, 0x42, 0xb1, 0x4a, 0x71, 0xa6, 0xf3, 0xf9, 0x1c, 0xd1, 0xc4, 0x3d, 0x26, 0xec, + 0x42, 0x22, 0x89, 0x6b, 0x6f, 0xf4, 0xd0, 0x1e, 0x75, 0xed, 0x4e, 0x13, 0x51, 0xea, 0xda, 0xad, + 0x26, 0xba, 0x4e, 0xdd, 0xad, 0x26, 0xda, 0x4d, 0xdd, 0x36, 0xee, 0xa0, 0x3d, 0xe2, 0xb6, 0xd0, + 0x2e, 0x75, 0x8d, 0xd4, 0xf7, 0x7b, 0x75, 0x16, 0x1f, 0xaf, 0x9e, 0xdc, 0xc5, 0x38, 0x35, 0xd0, + 0x7d, 0xea, 0x6e, 0xe0, 0x36, 0x3a, 0x4e, 0xdd, 0x16, 0x6e, 0xa3, 0x5d, 0x97, 0xb8, 0xdb, 0x41, + 0xe2, 0x4f, 0xc7, 0x38, 0xa6, 0xb0, 0x2c, 0x7b, 0xa0, 0xe7, 0x8a, 0xe9, 0xfb, 0x87, 0xfd, 0xc0, + 0x24, 0x16, 0xfa, 0x0d, 0x43, 0x01, 0x1d, 0x4f, 0x60, 0x77, 0x5b, 0xbb, 0xc8, 0x30, 0x22, 0x96, + 0x85, 0xae, 0xf8, 0xc3, 0x52, 0x10, 0x74, 0x61, 0x2f, 0x86, 0xe7, 0x22, 0xd2, 0xfe, 0x70, 0x1a, + 0xfb, 0x34, 0x4c, 0xe2, 0xda, 0x89, 0x74, 0xe2, 0x25, 0x6e, 0x99, 0x57, 0x92, 0xee, 0x16, 0x7e, + 0xfa, 0x30, 0xa1, 0x49, 0xb6, 0x2d, 0xbe, 0x79, 0xd1, 0x14, 0x13, 0x18, 0xc0, 0x59, 0xa3, 0xd1, + 0x20, 0xe7, 0x8d, 0xb1, 0x37, 0x81, 0x9e, 0xe1, 0x49, 0x31, 0x19, 0x65, 0xb7, 0x67, 0x35, 0x26, + 0x10, 0x27, 0x0d, 0x48, 0x82, 0x16, 0x32, 0x9a, 0x86, 0x65, 0x35, 0x7e, 0x4d, 0xc2, 0xd8, 0x34, + 0x0c, 0x6b, 0x0e, 0x60, 0xba, 0xa7, 0x2e, 0x74, 0x9e, 0x0d, 0x65, 0x2f, 0x35, 0x33, 0xae, 0x8a, + 0xb8, 0x51, 0xe2, 0x7b, 0xd1, 0x09, 0x4d, 0x52, 0xef, 0x9a, 0x05, 0xac, 0xdd, 0xa7, 0x78, 0x6c, + 0x72, 0x88, 0x11, 0x4c, 0x48, 0x98, 0xc4, 0x06, 0x73, 0x25, 0x7e, 0xfb, 0xaf, 0x67, 0xcd, 0xfa, + 0x96, 0x57, 0x1f, 0x9e, 0xcf, 0xda, 0xad, 0xf9, 0xeb, 0xb7, 0x0d, 0x0a, 0x7b, 0x90, 0x3c, 0x3e, + 0x1a, 0x86, 0x65, 0x89, 0x09, 0x90, 0x3e, 0xf7, 0x53, 0x66, 0x1d, 0x8a, 0xb4, 0x5c, 0xfb, 0xa4, + 0xb2, 0x7d, 0x88, 0xae, 0x86, 0x05, 0xef, 0x26, 0x6a, 0x41, 0x0b, 0x73, 0x36, 0xfe, 0x13, 0xea, + 0xfa, 0x91, 0x47, 0x48, 0x0d, 0xdf, 0x53, 0x1c, 0x07, 0xa4, 0x46, 0x13, 0x76, 0x55, 0xd3, 0x74, + 0xea, 0xd3, 0x04, 0xe6, 0x42, 0xa6, 0x13, 0x9c, 0x9a, 0x02, 0xe1, 0xa5, 0xd3, 0x18, 0xa8, 0x79, + 0xf7, 0x95, 0xcd, 0xbf, 0x87, 0x5e, 0x18, 0x4d, 0x53, 0x4c, 0xdc, 0x26, 0xff, 0x0e, 0x63, 0x8a, + 0xd3, 0x74, 0x3a, 0xa1, 0x38, 0x50, 0x65, 0xc4, 0x38, 0xf6, 0x03, 0x77, 0x4f, 0xb5, 0x03, 0x22, + 0xb0, 0x0f, 0x21, 0x99, 0xc0, 0xa0, 0x70, 0x70, 0x02, 0x47, 0x2e, 0xf6, 0xb1, 0x6c, 0x65, 0x82, + 0xe3, 0x20, 0x8c, 0xaf, 0x77, 0xfc, 0x1b, 0x99, 0x02, 0xc7, 0xe0, 0x41, 0xb5, 0xe8, 0x27, 0x71, + 0x8c, 0x7d, 0xaa, 0x0f, 0x24, 0x48, 0xbd, 0x30, 0x3e, 0xf5, 0xc8, 0x0d, 0xd7, 0x6e, 0xf2, 0x4e, + 0xb0, 0x47, 0x98, 0xf3, 0x6a, 0xaa, 0x25, 0x12, 0x0e, 0xab, 0xcf, 0x21, 0xa1, 0x38, 0x37, 0x15, + 0x30, 0x60, 0x62, 0x59, 0x2e, 0x76, 0xb7, 0x67, 0xb8, 0x71, 0x83, 0x1f, 0x5c, 0xd7, 0xdd, 0xa5, + 0x6b, 0x6b, 0xfa, 0xcc, 0xd7, 0xd6, 0x5e, 0xf1, 0xd2, 0x77, 0x31, 0xf9, 0x0c, 0xed, 0x9b, 0x96, + 0x28, 0xc0, 0x1f, 0x34, 0x61, 0x69, 0x9f, 0x13, 0xc2, 0x00, 0xcc, 0xf1, 0xa8, 0x18, 0xad, 0x69, + 0x31, 0xbd, 0xbf, 0xa9, 0xb7, 0xf6, 0xf8, 0x58, 0x98, 0x8f, 0x25, 0x58, 0x21, 0x7d, 0x86, 0xcd, + 0x3e, 0x6c, 0x27, 0xc9, 0x77, 0x15, 0xc7, 0xff, 0xf8, 0x68, 0xde, 0x85, 0x71, 0x90, 0xdc, 0x81, + 0x87, 0xd0, 0x1e, 0xd8, 0xc8, 0xf0, 0x2c, 0x9c, 0x9a, 0x86, 0x28, 0x6b, 0x14, 0x26, 0x68, 0x2d, + 0x82, 0x44, 0xd3, 0x42, 0xaf, 0x34, 0x9c, 0xe8, 0x47, 0x5e, 0x38, 0x16, 0x93, 0xcc, 0xbd, 0xf6, + 0x46, 0x53, 0x2f, 0x26, 0x60, 0xaf, 0x5a, 0xbf, 0x9a, 0x92, 0x87, 0x8c, 0x36, 0x93, 0x63, 0x54, + 0xbb, 0xa4, 0x72, 0xf5, 0xbc, 0x2b, 0xe1, 0x98, 0x99, 0x26, 0x51, 0x84, 0x39, 0x27, 0xbd, 0x93, + 0x4f, 0x2b, 0xae, 0x69, 0xf6, 0x79, 0x8c, 0xa9, 0x17, 0xc6, 0x38, 0x60, 0x8f, 0xd1, 0x01, 0x83, + 0xac, 0x0f, 0x58, 0x55, 0x78, 0x7c, 0x7c, 0x95, 0x07, 0x73, 0x69, 0xd1, 0xc4, 0x99, 0xea, 0xeb, + 0xe3, 0x93, 0xbb, 0x2f, 0x89, 0xa2, 0xac, 0x57, 0xf8, 0x32, 0xf5, 0xb0, 0xb4, 0x86, 0x58, 0x1b, + 0x66, 0x34, 0x3c, 0x0c, 0x63, 0x2f, 0x8a, 0x1e, 0xca, 0x8b, 0x66, 0xcf, 0xd5, 0xf2, 0x47, 0x09, + 0xc9, 0xde, 0xaa, 0xce, 0xfa, 0xeb, 0x57, 0x1e, 0xa8, 0xa5, 0xa0, 0x1a, 0xf0, 0x04, 0x78, 0x61, + 0x22, 0x7d, 0x98, 0x55, 0x4d, 0x5c, 0x1c, 0xf3, 0x79, 0x21, 0x5f, 0x4e, 0x49, 0x66, 0x63, 0xb1, + 0x67, 0x59, 0x0c, 0x6f, 0x35, 0x1f, 0x75, 0xc8, 0x31, 0x3b, 0x39, 0x02, 0x52, 0xd5, 0x9b, 0x65, + 0x6d, 0x4d, 0xec, 0x3a, 0xee, 0xff, 0xf9, 0x9d, 0x1b, 0xcf, 0x9e, 0xc3, 0xbc, 0x45, 0x87, 0x0a, + 0x7b, 0x62, 0xf7, 0xc7, 0x93, 0xc3, 0x2f, 0x8d, 0x89, 0x97, 0x12, 0x6c, 0x56, 0x22, 0xd2, 0x5d, + 0x6a, 0x3d, 0x3e, 0x1a, 0x70, 0xb8, 0xd5, 0x26, 0xac, 0xc1, 0xdc, 0x1e, 0x26, 0x38, 0x19, 0x82, + 0x7f, 0x1d, 0x5c, 0x47, 0xae, 0x6b, 0x10, 0x86, 0xce, 0x8d, 0xb5, 0xb5, 0x2f, 0xd3, 0xf1, 0x15, + 0x4e, 0x1b, 0x21, 0x01, 0xe1, 0x06, 0x7b, 0xd2, 0x19, 0xdf, 0x4f, 0xc2, 0x14, 0x13, 0x6b, 0x80, + 0x79, 0x04, 0xe2, 0x1c, 0x9e, 0x64, 0x29, 0x73, 0x6d, 0xdb, 0x14, 0x57, 0x51, 0x24, 0xab, 0xbe, + 0x07, 0xb2, 0x4b, 0xf7, 0x9e, 0xae, 0xad, 0xa9, 0xd6, 0xb7, 0x33, 0x25, 0xc6, 0x9c, 0xd1, 0x29, + 0xfa, 0x54, 0x97, 0x61, 0xf2, 0x5d, 0x8a, 0x18, 0x0c, 0xf8, 0x04, 0xc2, 0xe1, 0x83, 0x39, 0x63, + 0x1d, 0x38, 0xf7, 0x14, 0x89, 0xb6, 0x9d, 0xac, 0xed, 0x37, 0xf7, 0xe9, 0xdc, 0x92, 0xa4, 0x69, + 0x36, 0xe8, 0xdc, 0x9c, 0x60, 0x67, 0xca, 0x8d, 0x99, 0x1d, 0xef, 0x55, 0xf3, 0x82, 0xb9, 0xb0, + 0x8e, 0x5f, 0x2d, 0x9e, 0x99, 0x3c, 0x65, 0xfa, 0x04, 0x1f, 0x1f, 0x85, 0x88, 0xee, 0x37, 0x6c, + 0x6e, 0x02, 0x7a, 0x29, 0x9d, 0xc3, 0xc1, 0x2b, 0xdb, 0x51, 0x98, 0x6d, 0xf2, 0x09, 0x7b, 0x29, + 0xbd, 0xc2, 0x1e, 0x55, 0x17, 0x45, 0x86, 0xc3, 0x01, 0x26, 0x70, 0xbd, 0xdc, 0x7a, 0x11, 0xe7, + 0x6d, 0xcd, 0x52, 0x6b, 0x55, 0x43, 0x58, 0x8c, 0x9f, 0xd1, 0x71, 0x6a, 0xc1, 0x53, 0x72, 0xf3, + 0x42, 0xcf, 0x9c, 0xc7, 0x53, 0x7d, 0x15, 0xc6, 0x61, 0x55, 0x5e, 0x2e, 0xf3, 0x52, 0xf3, 0xb3, + 0xc5, 0x93, 0x52, 0x77, 0x89, 0xf9, 0x1d, 0x38, 0x00, 0x2d, 0x41, 0xc8, 0x40, 0xf6, 0xe9, 0x67, + 0xb8, 0x72, 0x2c, 0x0c, 0x89, 0x14, 0x57, 0x3c, 0xbf, 0x81, 0x73, 0x7b, 0x92, 0x9f, 0x74, 0x79, + 0xee, 0x24, 0x2a, 0x99, 0x47, 0xd8, 0xbb, 0xc5, 0x47, 0xdc, 0xd1, 0xef, 0xbb, 0xa7, 0x93, 0x1f, + 0xb6, 0x16, 0x57, 0x34, 0xff, 0xe8, 0xab, 0x0a, 0xe9, 0x5d, 0x0b, 0x63, 0x42, 0xbd, 0xd8, 0x87, + 0xe3, 0x9e, 0x51, 0x7d, 0x70, 0x96, 0xf3, 0x64, 0x20, 0x16, 0xf1, 0x5a, 0x84, 0x93, 0xed, 0xe3, + 0xa3, 0xfc, 0xb5, 0x4d, 0x12, 0x8b, 0x8e, 0xd2, 0xe4, 0x8e, 0xf1, 0xa9, 0x2c, 0x72, 0xb9, 0x69, + 0xec, 0xc7, 0xb7, 0x5e, 0x14, 0x06, 0x35, 0x3f, 0x19, 0x4f, 0xbc, 0x18, 0xa8, 0x3a, 0xf6, 0x4a, + 0x59, 0x8d, 0x84, 0xbf, 0x63, 0x43, 0xb4, 0xa4, 0x66, 0x56, 0xae, 0x7e, 0xbc, 0xbb, 0xdb, 0xd3, + 0xea, 0x46, 0x61, 0x7c, 0x53, 0x63, 0xc6, 0xcf, 0x61, 0x14, 0xd5, 0x18, 0xaa, 0x0e, 0x99, 0x58, + 0x51, 0xb5, 0xa3, 0x9f, 0x07, 0xde, 0x5a, 0xf5, 0x8e, 0x45, 0x5a, 0x27, 0x3b, 0x71, 0x02, 0x5c, + 0x5b, 0x8d, 0x7a, 0x57, 0x35, 0xa8, 0x5f, 0xa3, 0x23, 0x5c, 0xab, 0xe8, 0xd9, 0xe0, 0xeb, 0xcc, + 0x3d, 0xd2, 0xf8, 0x59, 0x1c, 0x62, 0xe0, 0x38, 0x8d, 0xb7, 0xde, 0x24, 0x7c, 0xcb, 0x26, 0x66, + 0xa0, 0xd9, 0x18, 0xd3, 0x51, 0x12, 0x38, 0xc6, 0xd1, 0xe1, 0xc9, 0xa9, 0x01, 0xec, 0x44, 0x80, + 0x53, 0xe2, 0xcc, 0x0c, 0x58, 0x29, 0x1c, 0xd3, 0x3a, 0xf0, 0x70, 0x86, 0x63, 0x78, 0x93, 0x49, + 0x14, 0xfa, 0x1e, 0x50, 0xba, 0x6f, 0x13, 0x9f, 0x62, 0x5a, 0x27, 0x34, 0xc5, 0xde, 0xd8, 0x40, + 0xc6, 0xdf, 0xea, 0xd0, 0x7b, 0xfd, 0x44, 0x50, 0x9d, 0x4e, 0x9e, 0xf6, 0x9b, 0xa3, 0xab, 0x24, + 0x78, 0x70, 0x28, 0xf2, 0x3d, 0x7f, 0x84, 0x1d, 0x23, 0x4e, 0xea, 0x70, 0x0d, 0x60, 0x03, 0xf9, + 0x29, 0x0e, 0x70, 0x4c, 0x43, 0x2f, 0x22, 0x8e, 0x41, 0xbc, 0x31, 0xae, 0x27, 0x69, 0x78, 0x1d, + 0xc6, 0x06, 0x62, 0xf2, 0xcc, 0xc8, 0xa9, 0xda, 0x36, 0x5c, 0xd6, 0x19, 0xcd, 0x39, 0x10, 0xe3, + 0x46, 0x72, 0x53, 0x5a, 0x86, 0x4b, 0xb6, 0x57, 0x6a, 0x30, 0xa1, 0x1a, 0x90, 0xa9, 0x38, 0xa8, + 0x99, 0xaf, 0x67, 0xb1, 0x30, 0xec, 0x9e, 0x5b, 0x97, 0x22, 0x24, 0xfb, 0xd8, 0x4b, 0x6f, 0x3e, + 0x61, 0x2f, 0xa2, 0xa3, 0xbc, 0xaf, 0x16, 0x6f, 0x8e, 0xe9, 0x23, 0x5e, 0xb9, 0xae, 0xc1, 0x28, + 0x14, 0xd6, 0xb2, 0xb1, 0xb6, 0x66, 0xc6, 0x0d, 0x20, 0xb1, 0x4f, 0xe5, 0xb1, 0xfb, 0xc8, 0xc9, + 0x60, 0x45, 0x42, 0x40, 0x9b, 0x22, 0xcd, 0x8c, 0x2d, 0x0b, 0xc5, 0x12, 0xe7, 0x32, 0xd0, 0xf3, + 0x4d, 0x2c, 0x71, 0xee, 0x6c, 0xc7, 0xf7, 0xf1, 0x84, 0x7e, 0x0f, 0x6c, 0xfb, 0x05, 0xaa, 0x79, + 0x6d, 0xcd, 0xc4, 0x67, 0xb2, 0xd2, 0x8e, 0x7f, 0x63, 0x9c, 0xbb, 0xf2, 0x65, 0xeb, 0x7c, 0x41, + 0x4b, 0x3e, 0xd9, 0xbb, 0x78, 0x63, 0xc8, 0xad, 0x80, 0xff, 0x8c, 0x95, 0xa3, 0x62, 0x35, 0x5c, + 0xd7, 0x6d, 0x35, 0x3b, 0x96, 0x6e, 0xde, 0x50, 0xe6, 0x01, 0x72, 0x0b, 0x85, 0x5e, 0xd9, 0xe2, + 0x44, 0x2f, 0x5e, 0x7a, 0xa0, 0x7a, 0xb4, 0xa5, 0xa7, 0xfa, 0xd2, 0xf3, 0xf3, 0xc0, 0xc9, 0x01, + 0x93, 0x36, 0xc4, 0x2c, 0x81, 0xb0, 0x30, 0x33, 0x68, 0xff, 0x66, 0x58, 0x7c, 0x83, 0x29, 0xb2, + 0x01, 0x2e, 0x85, 0x6b, 0x9c, 0x9a, 0xb1, 0xf5, 0xf8, 0x18, 0xbf, 0xb3, 0x1f, 0x1f, 0xe3, 0x6d, + 0x4d, 0xae, 0xb0, 0x10, 0x91, 0x08, 0xf4, 0x21, 0xd8, 0x9c, 0x1a, 0x18, 0x30, 0xb0, 0xb3, 0x6a, + 0x58, 0xfd, 0xec, 0x35, 0x6a, 0x0d, 0x5d, 0x09, 0xd2, 0xad, 0xc1, 0x14, 0xdf, 0x5c, 0x77, 0x65, + 0x8a, 0xa1, 0x24, 0x0a, 0x85, 0x25, 0x4f, 0x41, 0x61, 0xbc, 0x67, 0xbd, 0x43, 0x49, 0xda, 0xbc, + 0x72, 0xdd, 0x25, 0xac, 0x98, 0x32, 0x83, 0x28, 0x3c, 0xfb, 0x9c, 0x2c, 0x67, 0xe0, 0x62, 0xa4, + 0xae, 0xfb, 0xa6, 0xa5, 0xff, 0xb6, 0x4a, 0x9c, 0x5d, 0x5c, 0xb9, 0xaa, 0x4d, 0xa9, 0x25, 0xad, + 0x22, 0xf6, 0x67, 0x4c, 0x6b, 0xa9, 0x5f, 0x32, 0x7d, 0xce, 0x54, 0x2d, 0xa0, 0xee, 0x17, 0xa1, + 0xd1, 0x57, 0xb6, 0x64, 0xa9, 0x74, 0xee, 0x41, 0x3f, 0x9b, 0xa2, 0x81, 0x57, 0x4d, 0x81, 0x10, + 0xb0, 0xd6, 0x8f, 0x62, 0x2a, 0xb0, 0x54, 0x56, 0xea, 0xc8, 0x41, 0xd6, 0xb4, 0xfb, 0x25, 0x4c, + 0x80, 0x35, 0x88, 0xb0, 0x70, 0x4a, 0xe3, 0x30, 0x36, 0x5b, 0xdd, 0xe6, 0x7a, 0x6b, 0x7d, 0x5d, + 0x7d, 0xe7, 0xd8, 0x6a, 0xd4, 0xb6, 0x50, 0x8b, 0x85, 0x58, 0x9a, 0x2b, 0xea, 0x8d, 0xc3, 0x87, + 0xb3, 0x25, 0x4f, 0x07, 0xc8, 0xac, 0x1a, 0x14, 0x7d, 0xae, 0xcc, 0x2d, 0xb0, 0x0b, 0x3a, 0x24, + 0x1e, 0x1f, 0xd5, 0x98, 0xaf, 0x95, 0x91, 0xd2, 0x33, 0xc0, 0xc1, 0x03, 0xa4, 0xbd, 0x2c, 0x2c, + 0xe6, 0xf9, 0x96, 0x66, 0xb9, 0x72, 0x6f, 0xdc, 0x82, 0x6c, 0x62, 0xdb, 0x6d, 0x4b, 0xae, 0x5d, + 0x13, 0x4f, 0xc8, 0x0d, 0x9e, 0x93, 0x58, 0x34, 0xab, 0x89, 0x2a, 0xc0, 0x1b, 0xd8, 0x40, 0x46, + 0x8a, 0x33, 0x16, 0x0f, 0xc4, 0x2a, 0xd6, 0x3c, 0xb7, 0x7b, 0x75, 0x22, 0x5a, 0x6b, 0xb6, 0xff, + 0x14, 0x49, 0x89, 0xe4, 0xc8, 0x18, 0x49, 0x21, 0x7e, 0x17, 0x87, 0x91, 0x62, 0x86, 0x78, 0x81, + 0xef, 0x9c, 0xa3, 0x89, 0x3b, 0x53, 0x8c, 0x9b, 0xf3, 0xca, 0x46, 0x70, 0xd7, 0x73, 0x27, 0x0d, + 0xa7, 0x30, 0x4e, 0x02, 0xd2, 0x2b, 0x1c, 0xec, 0x50, 0x8d, 0x53, 0x40, 0xb7, 0x21, 0xbe, 0x73, + 0x8c, 0x51, 0x02, 0x38, 0x9e, 0xe0, 0x68, 0xe8, 0x70, 0xa3, 0x70, 0xe6, 0x0e, 0xcf, 0x7f, 0x8b, + 0x67, 0x77, 0x9c, 0x26, 0xf2, 0xe5, 0xcb, 0x1a, 0x67, 0xe7, 0xf2, 0xf1, 0x11, 0xf6, 0x7b, 0x2c, + 0x02, 0xe8, 0xc1, 0xef, 0x18, 0x7b, 0xe9, 0xd5, 0x03, 0xfc, 0x22, 0x38, 0xe2, 0x83, 0x32, 0x0c, + 0xfe, 0x68, 0x06, 0x6f, 0x4e, 0xf8, 0x28, 0xf1, 0x8f, 0x74, 0x78, 0xe2, 0x8d, 0x27, 0x91, 0xac, + 0x4a, 0xef, 0x92, 0xf4, 0x86, 0xe7, 0x8c, 0x42, 0x98, 0xe3, 0xc3, 0x17, 0x78, 0xc2, 0xce, 0x30, + 0xe6, 0xe8, 0x13, 0x43, 0x8d, 0x27, 0x14, 0xc5, 0x89, 0x2b, 0xa4, 0x83, 0x60, 0xf5, 0x9c, 0x44, + 0xb7, 0xc0, 0x9a, 0x1e, 0x53, 0x80, 0xdd, 0x15, 0x81, 0xbf, 0x17, 0x20, 0x3e, 0x7a, 0x4f, 0x41, + 0xd0, 0x2a, 0x65, 0x71, 0x3e, 0x36, 0x89, 0x5c, 0x95, 0x38, 0x69, 0xd0, 0x11, 0x8e, 0x39, 0xe7, + 0xc0, 0x2e, 0x3d, 0x14, 0xbb, 0xba, 0xcc, 0x51, 0x59, 0xaf, 0x94, 0x74, 0x68, 0x99, 0x98, 0x5b, + 0x20, 0xd7, 0x5d, 0x45, 0x61, 0xf9, 0x5c, 0xaa, 0x5f, 0x03, 0x05, 0x58, 0x50, 0x63, 0x2a, 0xb0, + 0x7e, 0xc8, 0x68, 0x03, 0x21, 0xef, 0x17, 0x0d, 0xc1, 0xd6, 0x62, 0x66, 0x20, 0x68, 0x37, 0xb5, + 0xe6, 0x0a, 0x09, 0xab, 0x19, 0x79, 0x3e, 0x36, 0xcf, 0x4a, 0xf3, 0xe3, 0x23, 0x26, 0x16, 0x8a, + 0xcf, 0x99, 0x41, 0x03, 0x88, 0x1a, 0xd8, 0x90, 0x72, 0x4a, 0x28, 0xb0, 0x62, 0xc8, 0xd0, 0x3a, + 0xbc, 0x44, 0xc1, 0x0f, 0x29, 0x1b, 0x3b, 0x3c, 0xb9, 0x20, 0xbe, 0x29, 0xb0, 0x4c, 0x74, 0x50, + 0x31, 0xba, 0xc7, 0x47, 0x91, 0x5c, 0x24, 0x68, 0xac, 0xb5, 0xb5, 0x2b, 0x30, 0x9a, 0x01, 0x01, + 0xa2, 0x82, 0x2a, 0xa4, 0xc0, 0xf1, 0xbf, 0x22, 0x8f, 0x8f, 0x17, 0x78, 0xdb, 0xdd, 0x23, 0xd6, + 0x8c, 0xff, 0xbb, 0xb6, 0xb6, 0x6f, 0x1a, 0x8c, 0x4e, 0x67, 0x81, 0xe5, 0x80, 0xe8, 0x9d, 0x78, + 0x53, 0x82, 0x83, 0x46, 0xed, 0xd4, 0x9b, 0x30, 0x0a, 0x95, 0x11, 0xc3, 0xc2, 0x0d, 0x90, 0x26, + 0xb5, 0x14, 0xdc, 0x1d, 0x1a, 0x06, 0x32, 0x30, 0xc7, 0x16, 0x52, 0x92, 0x04, 0x4b, 0xda, 0x44, + 0x17, 0x18, 0x0e, 0xf3, 0x35, 0x36, 0xf3, 0x3b, 0xda, 0x42, 0xfb, 0xe6, 0xe5, 0x31, 0xf6, 0x93, + 0x5b, 0xcc, 0x94, 0x88, 0x05, 0x52, 0xdb, 0x7c, 0x3d, 0xbb, 0xc0, 0xf3, 0xb7, 0xaf, 0x67, 0x7b, + 0x70, 0xd5, 0x23, 0xe3, 0xce, 0x4b, 0x63, 0x03, 0x1e, 0xc6, 0x50, 0xab, 0x9a, 0x19, 0x6c, 0x70, + 0x21, 0xed, 0x27, 0x4d, 0x9e, 0x02, 0x62, 0x2f, 0x26, 0xb0, 0x11, 0x9b, 0x6b, 0x17, 0x3a, 0x1f, + 0xa6, 0x98, 0x8c, 0xea, 0x57, 0x53, 0x4a, 0x41, 0x5e, 0xdb, 0x90, 0x5e, 0xe3, 0x90, 0xaf, 0x36, + 0xe8, 0x75, 0x62, 0x7e, 0x92, 0x48, 0xed, 0x53, 0x43, 0x09, 0xfd, 0x04, 0x9f, 0x04, 0x93, 0x48, + 0x86, 0xc3, 0x28, 0x8c, 0x31, 0x1b, 0xbf, 0xb6, 0x87, 0x52, 0x3e, 0x93, 0x07, 0x41, 0xaa, 0x64, + 0xc0, 0x50, 0xd2, 0x25, 0xb6, 0xc1, 0xe7, 0x73, 0xd4, 0xb4, 0xb2, 0x55, 0x38, 0x31, 0x09, 0xc2, + 0xd6, 0x6c, 0xd7, 0x24, 0x56, 0x03, 0x9e, 0xf4, 0x10, 0x84, 0xba, 0x8b, 0x07, 0x03, 0xe3, 0x1f, + 0xff, 0xf6, 0xff, 0x18, 0x59, 0xc9, 0x04, 0x43, 0x51, 0x97, 0x0c, 0x04, 0xbd, 0x30, 0x18, 0x64, + 0xba, 0x6b, 0x32, 0x60, 0xb2, 0xef, 0x06, 0x89, 0x42, 0x1f, 0x43, 0x70, 0x6a, 0x8b, 0x8b, 0xc1, + 0xa9, 0xbb, 0x4d, 0x9f, 0x28, 0x06, 0x87, 0x63, 0x9a, 0x8d, 0x2a, 0xcd, 0x4e, 0x5c, 0xcb, 0xee, + 0xf5, 0xec, 0x76, 0xaf, 0xd5, 0xb3, 0x99, 0x1a, 0x84, 0x13, 0x9a, 0xcd, 0x3e, 0x7d, 0x47, 0xc4, + 0x40, 0xfa, 0xf4, 0x8d, 0x6b, 0x5b, 0x98, 0x87, 0x07, 0x0e, 0xc7, 0xd3, 0xc8, 0xc4, 0xff, 0x4a, + 0x1a, 0xfe, 0xc8, 0x63, 0x2f, 0x58, 0xee, 0xc0, 0xce, 0x46, 0x76, 0x6f, 0x63, 0x63, 0xa3, 0x67, + 0x6f, 0xc9, 0x9d, 0x61, 0xe2, 0xed, 0xed, 0xed, 0xa6, 0x95, 0x1b, 0x5b, 0xd6, 0xfd, 0x8e, 0xa6, + 0xe2, 0x9a, 0x34, 0x00, 0xaf, 0x0d, 0xb2, 0x18, 0x49, 0x83, 0x4b, 0x26, 0x16, 0x17, 0x18, 0xa6, + 0xfe, 0x7a, 0x96, 0x60, 0x93, 0x17, 0xca, 0xca, 0x58, 0xf3, 0xcb, 0xdc, 0x7c, 0xde, 0x67, 0x0d, + 0xe6, 0x6b, 0x0b, 0x42, 0xa6, 0xfe, 0x7a, 0xf6, 0x49, 0x23, 0xc4, 0x2f, 0x35, 0xa8, 0x27, 0x00, + 0x75, 0xdd, 0x60, 0xee, 0xf2, 0xf5, 0x8c, 0xcc, 0x9d, 0xd7, 0x33, 0x0c, 0x7f, 0x28, 0xfc, 0x39, + 0x01, 0x42, 0x52, 0xaf, 0xf4, 0x19, 0x2b, 0x3d, 0x06, 0x4c, 0xe5, 0xf1, 0x11, 0xfa, 0xe7, 0xfc, + 0x5b, 0x95, 0x74, 0x88, 0x14, 0x85, 0x43, 0x93, 0x86, 0xc4, 0xc9, 0x62, 0x45, 0xeb, 0x94, 0x5a, + 0x56, 0xc6, 0xab, 0xab, 0x8e, 0xd2, 0x04, 0xd6, 0xe9, 0xe9, 0x82, 0x36, 0x02, 0x72, 0xb6, 0xb3, + 0xf3, 0x8c, 0x7c, 0x64, 0x74, 0x6a, 0x23, 0x24, 0x92, 0xbd, 0x1e, 0xe0, 0xc6, 0x30, 0x8c, 0x28, + 0x10, 0xd3, 0xee, 0x36, 0x55, 0x22, 0x38, 0xda, 0x08, 0x03, 0x5d, 0xfe, 0xa6, 0x92, 0x99, 0x74, + 0xbd, 0x22, 0x1d, 0xb6, 0x72, 0x96, 0x61, 0x69, 0xd3, 0x90, 0xfb, 0xd2, 0x9c, 0x85, 0x81, 0x03, + 0xed, 0xaa, 0x4d, 0x6b, 0x83, 0x64, 0xe9, 0x06, 0x3f, 0x38, 0xac, 0xd9, 0x2c, 0xb9, 0xd9, 0x14, + 0xaf, 0xdd, 0xf0, 0x66, 0x55, 0xc6, 0x1e, 0x5d, 0x87, 0xd7, 0x46, 0xd5, 0x13, 0x39, 0x45, 0xa1, + 0x20, 0x6d, 0xa8, 0x3c, 0x6b, 0xa0, 0x7d, 0x38, 0x4d, 0xc4, 0x3d, 0x4a, 0xc3, 0x24, 0x76, 0x68, + 0x43, 0xfd, 0x06, 0x92, 0x07, 0x50, 0xff, 0x80, 0xfd, 0x75, 0x0c, 0xc6, 0x01, 0xf1, 0xab, 0x58, + 0xcd, 0x4b, 0xf2, 0x39, 0x72, 0x66, 0x03, 0x99, 0x94, 0x0d, 0xb7, 0x67, 0xb1, 0x9b, 0x9b, 0xd1, + 0xd9, 0x06, 0x9a, 0xc6, 0x40, 0x0a, 0x38, 0xaf, 0x5e, 0xd1, 0x06, 0xff, 0xc9, 0x34, 0x7a, 0xe5, + 0xa1, 0x92, 0x38, 0x85, 0x41, 0x42, 0xe6, 0x6d, 0x12, 0x06, 0xb5, 0x66, 0xf1, 0x0d, 0xcf, 0x12, + 0xef, 0x42, 0x0b, 0x6e, 0x5e, 0x50, 0xbd, 0x50, 0x87, 0xb7, 0x34, 0xb7, 0x2c, 0xe7, 0xec, 0x3c, + 0x27, 0x3d, 0x3c, 0x3b, 0xd7, 0x36, 0xd1, 0xfb, 0x34, 0xb7, 0x5b, 0x19, 0x7b, 0x42, 0x1e, 0x1f, + 0x27, 0x0d, 0xed, 0x12, 0x77, 0x5d, 0x97, 0x48, 0x59, 0x7b, 0x3e, 0x43, 0x6a, 0xb3, 0x00, 0x01, + 0xb1, 0xed, 0x88, 0xf8, 0x8f, 0xf7, 0x4c, 0xdd, 0xda, 0x68, 0x34, 0xb2, 0xcd, 0x7c, 0x8e, 0xb8, + 0xee, 0xef, 0x04, 0xd3, 0x7e, 0x96, 0xea, 0xaa, 0x2d, 0x17, 0xbb, 0xdb, 0xaf, 0x68, 0x63, 0xe4, + 0x11, 0x33, 0x6e, 0x84, 0x60, 0xc2, 0x4d, 0x41, 0x19, 0xc2, 0x3f, 0xf4, 0x2d, 0x54, 0x3e, 0x49, + 0x9a, 0x4c, 0x8b, 0xf5, 0x2b, 0x4f, 0x0a, 0x1c, 0xc4, 0x6c, 0xa2, 0xb7, 0x14, 0x4e, 0x8b, 0x38, + 0xc5, 0xfe, 0xc8, 0x79, 0x3d, 0x63, 0x68, 0x4a, 0xbc, 0xd4, 0xa4, 0x1f, 0xe0, 0x7d, 0xac, 0x95, + 0x0c, 0xc6, 0x0e, 0x43, 0x32, 0x24, 0x87, 0x5f, 0xb2, 0xc2, 0x47, 0xc4, 0x24, 0xae, 0x31, 0x30, + 0x32, 0x6c, 0xdc, 0xa0, 0x69, 0x38, 0x36, 0xad, 0x06, 0x99, 0x44, 0x21, 0x35, 0xdf, 0xfe, 0x5f, + 0xe4, 0xcd, 0x5b, 0x4b, 0x6d, 0x90, 0x96, 0xa5, 0x34, 0x94, 0x67, 0xcd, 0xf3, 0x0c, 0x01, 0x37, + 0x68, 0xf2, 0x75, 0x32, 0xc1, 0xe9, 0xae, 0x10, 0x81, 0x1a, 0x03, 0x0d, 0x81, 0x7d, 0xd3, 0x06, + 0x54, 0x2b, 0xee, 0x1e, 0x62, 0x0d, 0x48, 0x83, 0x26, 0x9f, 0x01, 0x22, 0x58, 0x3e, 0x06, 0xe5, + 0x14, 0xae, 0x0f, 0x2f, 0xd1, 0x5a, 0x20, 0x03, 0x58, 0x07, 0xa0, 0x23, 0x4d, 0xb2, 0x0e, 0x6e, + 0x87, 0xaa, 0x3a, 0xdc, 0xad, 0xa2, 0x89, 0xb3, 0x73, 0x34, 0x1b, 0x25, 0xd3, 0xd4, 0x31, 0xe2, + 0xe9, 0x18, 0xa7, 0xa1, 0x6f, 0xa0, 0x71, 0x18, 0x4f, 0x29, 0x76, 0x8c, 0x56, 0x3d, 0x08, 0xaf, + 0x43, 0x6a, 0xcc, 0x2d, 0x10, 0x24, 0xdc, 0x69, 0xdd, 0x84, 0xac, 0x1b, 0xb6, 0x85, 0xc4, 0x7e, + 0x31, 0x7e, 0x9d, 0x12, 0x5a, 0x83, 0x52, 0x62, 0xa7, 0x70, 0xbe, 0xc0, 0xbb, 0x37, 0x9b, 0x68, + 0x71, 0x34, 0xda, 0x3a, 0xc9, 0xa4, 0xd6, 0xef, 0x7a, 0xcd, 0xc1, 0x25, 0x20, 0x5c, 0x52, 0xf3, + 0xae, 0x93, 0x4b, 0x07, 0xbf, 0x6b, 0xf7, 0x9a, 0x2c, 0x49, 0xab, 0x8f, 0xdf, 0xf6, 0x9a, 0xd6, + 0x7c, 0x2c, 0x4b, 0x6c, 0xf6, 0x3a, 0x15, 0x45, 0xa0, 0x9e, 0x35, 0x1f, 0xf1, 0x42, 0xc5, 0x4c, + 0x56, 0xc5, 0x9a, 0x07, 0x2c, 0x37, 0x9b, 0x91, 0x9f, 0xa8, 0xe3, 0xa1, 0x15, 0xd7, 0xc6, 0x5b, + 0x9f, 0x34, 0x14, 0x6d, 0x6e, 0xbd, 0xed, 0xe1, 0x8e, 0x1a, 0x39, 0x79, 0x67, 0x0f, 0x8c, 0x2f, + 0xc9, 0x9d, 0xe1, 0x10, 0x31, 0x07, 0x32, 0x1f, 0x17, 0x3b, 0x26, 0x6c, 0xe0, 0xa3, 0xda, 0xeb, + 0x19, 0xf9, 0x4b, 0xaf, 0x39, 0x1f, 0x6b, 0x5d, 0x0f, 0x93, 0xe5, 0xab, 0x6e, 0x92, 0xb7, 0x36, + 0xee, 0xc1, 0xe2, 0x7d, 0x0c, 0xef, 0x71, 0x60, 0xb6, 0x4b, 0xab, 0x7e, 0x9b, 0x3e, 0xa1, 0x85, + 0x76, 0xd6, 0x02, 0xf9, 0x8b, 0x8d, 0xdb, 0x03, 0xdb, 0x69, 0x96, 0x5a, 0x3a, 0xd5, 0x5b, 0x22, + 0xdb, 0x6e, 0x7d, 0xb3, 0x39, 0x30, 0xf6, 0xee, 0x7d, 0x1c, 0x45, 0x38, 0xa6, 0x86, 0x03, 0x49, + 0x5b, 0xdd, 0x81, 0xf1, 0x43, 0x92, 0x04, 0xfc, 0xcb, 0xb6, 0x9b, 0x03, 0xe3, 0xa3, 0x17, 0xa6, + 0x86, 0x63, 0xfc, 0x8c, 0xbd, 0x1b, 0xad, 0xb1, 0x03, 0x7e, 0xa9, 0x5a, 0x32, 0x86, 0xbf, 0x34, + 0x2a, 0xf0, 0x53, 0xf0, 0x7a, 0x11, 0x76, 0x05, 0x26, 0xd1, 0x15, 0x17, 0x66, 0xdc, 0x60, 0x1a, + 0x6e, 0xf6, 0xdc, 0x07, 0xd6, 0x1c, 0x1c, 0xcc, 0x38, 0x47, 0x38, 0x51, 0x10, 0xd3, 0x65, 0x07, + 0x99, 0xd1, 0x4c, 0x46, 0x72, 0x63, 0x48, 0x59, 0xf3, 0x01, 0x44, 0x0b, 0xba, 0x35, 0xd0, 0x25, + 0x4d, 0x3c, 0x42, 0x6b, 0xb0, 0xad, 0x40, 0x84, 0xd8, 0xf0, 0x26, 0x40, 0x0b, 0x98, 0x07, 0xa6, + 0x11, 0x1a, 0x16, 0x3a, 0x30, 0x0d, 0x32, 0xf1, 0x62, 0x03, 0xcc, 0xb6, 0xc1, 0x6a, 0x61, 0xd7, + 0x34, 0x58, 0x79, 0x62, 0x58, 0xb2, 0x24, 0xcd, 0xd1, 0xa2, 0x40, 0x86, 0x52, 0x3e, 0x42, 0x50, + 0x88, 0x31, 0xc4, 0xc5, 0xee, 0x11, 0x0b, 0xb5, 0x5b, 0x70, 0x83, 0x95, 0xca, 0x72, 0x9c, 0x65, + 0x5a, 0xa8, 0xdd, 0x6d, 0xea, 0x14, 0xe1, 0xb5, 0xc6, 0xed, 0x80, 0x44, 0x4d, 0x53, 0x54, 0xf6, + 0x27, 0x0d, 0xf5, 0xe1, 0x62, 0x34, 0x69, 0x64, 0xdc, 0xa2, 0xc0, 0xc3, 0x40, 0x38, 0x82, 0xb0, + 0x57, 0x54, 0x70, 0x58, 0x03, 0x39, 0xaa, 0x7b, 0x60, 0x1c, 0xeb, 0x9f, 0xbc, 0x04, 0x53, 0x37, + 0x0c, 0x72, 0xc2, 0x68, 0xcf, 0xa7, 0xe1, 0x2d, 0xc8, 0x8a, 0x0f, 0x05, 0xb9, 0xdb, 0x3f, 0x31, + 0x0d, 0xe8, 0xaf, 0x1e, 0x79, 0x57, 0x38, 0x32, 0xc0, 0xf1, 0xe3, 0xc4, 0x34, 0x48, 0x18, 0xe0, + 0x3a, 0xbf, 0x02, 0x65, 0xd2, 0x08, 0xa7, 0x49, 0x9d, 0xc9, 0xac, 0x21, 0x61, 0x57, 0x69, 0x5a, + 0x33, 0xc2, 0x3b, 0x5b, 0xc8, 0x4b, 0xd6, 0xa2, 0x3f, 0x0a, 0x27, 0xb0, 0xff, 0xe7, 0x97, 0x50, + 0x9c, 0x35, 0x19, 0x24, 0x34, 0x5f, 0x90, 0xf7, 0x01, 0xe9, 0xbc, 0xa4, 0x46, 0x2d, 0x52, 0x81, + 0x72, 0x08, 0x3f, 0x87, 0xe4, 0xe7, 0x90, 0x8e, 0x4c, 0xc3, 0x1f, 0x39, 0x86, 0x25, 0x57, 0x7d, + 0x22, 0x11, 0x3d, 0x51, 0x16, 0xe5, 0xb7, 0x10, 0xc6, 0x8b, 0xdd, 0x6b, 0x72, 0x97, 0xd1, 0xc1, + 0x0c, 0xc8, 0x0f, 0xc2, 0xdf, 0x83, 0xbc, 0xfc, 0x17, 0x90, 0x35, 0xc2, 0xcf, 0xc7, 0x47, 0xf9, + 0x46, 0x70, 0x0d, 0x92, 0x72, 0x57, 0xc6, 0x25, 0x22, 0xd3, 0x2b, 0x1a, 0xd2, 0x08, 0x3b, 0xc6, + 0x01, 0x26, 0xa3, 0x9a, 0xc8, 0x35, 0x90, 0x77, 0xeb, 0x51, 0x2f, 0x75, 0x8c, 0x7f, 0x31, 0x24, + 0xb7, 0xed, 0xd0, 0x39, 0x57, 0x4e, 0xf2, 0xc5, 0x65, 0x8b, 0xc9, 0x38, 0x72, 0x3e, 0x26, 0xea, + 0x6e, 0xef, 0x83, 0xd5, 0x54, 0x6e, 0x4c, 0x38, 0x37, 0x26, 0x15, 0xf8, 0xf3, 0xf1, 0xd1, 0xf8, + 0x1a, 0x43, 0x12, 0x68, 0x37, 0x58, 0x23, 0x46, 0x36, 0x90, 0x4b, 0xfe, 0xac, 0x6b, 0xed, 0xff, + 0xfb, 0x7f, 0x6b, 0xec, 0xe2, 0xd2, 0x03, 0x8c, 0x76, 0xac, 0xf9, 0xa5, 0x1c, 0xda, 0x11, 0x78, + 0x76, 0x89, 0x06, 0x2d, 0x29, 0x1e, 0x70, 0xb0, 0x18, 0x64, 0x06, 0x5f, 0x8d, 0x19, 0xa8, 0x18, + 0x33, 0x69, 0x60, 0x60, 0x7b, 0x4c, 0x61, 0x2e, 0x4b, 0xb3, 0xce, 0xce, 0x92, 0x73, 0xd7, 0x75, + 0x63, 0x4b, 0x9b, 0xcc, 0x3e, 0x08, 0x7a, 0x9c, 0xcb, 0x60, 0x5c, 0x9f, 0x70, 0x9b, 0x27, 0x7e, + 0xb3, 0xe6, 0xee, 0xd3, 0x0b, 0x20, 0xd6, 0x19, 0x45, 0xcf, 0x36, 0xf1, 0xda, 0xda, 0x0e, 0x35, + 0xb3, 0x4f, 0xd0, 0x45, 0x66, 0x5f, 0xda, 0xc2, 0x9e, 0x35, 0xcf, 0x07, 0xb7, 0x50, 0x52, 0x4b, + 0xb0, 0x9c, 0x6c, 0xc0, 0x90, 0xbf, 0x0f, 0xac, 0x82, 0x96, 0x00, 0x5c, 0x8f, 0x4e, 0x20, 0x90, + 0x6c, 0xa6, 0x40, 0x9e, 0x5e, 0xbe, 0x9e, 0x69, 0x1a, 0xdf, 0xba, 0x40, 0xdb, 0x29, 0x33, 0x3b, + 0x32, 0x01, 0x90, 0xc0, 0x74, 0xcd, 0xfb, 0x8a, 0x53, 0xc9, 0xa8, 0xf6, 0x64, 0x8c, 0x39, 0xf3, + 0x05, 0x74, 0xb3, 0x8b, 0x81, 0x82, 0x19, 0x00, 0x54, 0x1d, 0x9d, 0xb6, 0x67, 0x56, 0x60, 0xd8, + 0x42, 0x5a, 0x92, 0x10, 0x05, 0x53, 0xba, 0xb6, 0xa6, 0x37, 0x37, 0x11, 0xb4, 0x43, 0xa9, 0x24, + 0x90, 0x43, 0xe8, 0x33, 0x7b, 0x30, 0x12, 0x94, 0x6f, 0x47, 0xf0, 0x07, 0x6b, 0x33, 0x3a, 0x25, + 0xea, 0x6c, 0xe4, 0x1f, 0x1d, 0x51, 0x18, 0xa6, 0x90, 0x8e, 0xa8, 0xbb, 0x93, 0xf2, 0x1d, 0x93, + 0x05, 0xb0, 0x90, 0x33, 0xbc, 0x25, 0x8c, 0x6a, 0x4f, 0x12, 0xd3, 0x08, 0xc6, 0x06, 0x92, 0x5b, + 0x2b, 0x2b, 0x88, 0x70, 0xa3, 0xf0, 0x70, 0x25, 0x44, 0xb4, 0xc5, 0xf7, 0x54, 0x10, 0xf6, 0xf2, + 0xd5, 0x4a, 0xf8, 0x47, 0xa3, 0xdc, 0xcb, 0xb5, 0x32, 0x02, 0x5d, 0x27, 0xc3, 0xcb, 0x74, 0xb5, + 0xba, 0x39, 0x46, 0x61, 0x10, 0xe0, 0x18, 0xa8, 0x56, 0x10, 0x89, 0x81, 0xa6, 0x47, 0x42, 0xca, + 0x80, 0x44, 0xb9, 0x5f, 0x40, 0x5a, 0xce, 0x28, 0x70, 0x0c, 0xa4, 0xf6, 0xdc, 0x82, 0xab, 0x6e, + 0xce, 0xc1, 0x93, 0x7b, 0xc9, 0x44, 0x03, 0x4f, 0x2e, 0x1d, 0x51, 0x97, 0x53, 0x8e, 0x38, 0x87, + 0x06, 0x2a, 0x00, 0xa4, 0xf0, 0x00, 0xfd, 0xaf, 0x09, 0x14, 0x31, 0xa3, 0x66, 0xb6, 0x97, 0x46, + 0x09, 0x3b, 0x97, 0x5c, 0x44, 0xc8, 0xe8, 0xfd, 0xec, 0x2c, 0x9d, 0x4b, 0x1a, 0x9e, 0x00, 0x42, + 0xc8, 0x62, 0x12, 0x5b, 0x0d, 0x02, 0x6a, 0x61, 0x26, 0xe4, 0x00, 0x93, 0xbc, 0x2c, 0xa7, 0x5e, + 0x28, 0x26, 0xa9, 0xe3, 0x8e, 0xf2, 0x18, 0x52, 0xdc, 0x74, 0x66, 0x15, 0x28, 0xc5, 0x32, 0xb9, + 0x17, 0xbb, 0xfa, 0xd9, 0x30, 0x5c, 0x22, 0xfa, 0xe3, 0xb6, 0xc9, 0x66, 0xac, 0xf5, 0xf1, 0xf8, + 0xd8, 0xb4, 0xea, 0x26, 0x2d, 0xa4, 0x58, 0x82, 0x28, 0x7d, 0xa5, 0x49, 0x37, 0x6a, 0xc9, 0x50, + 0x3b, 0xcc, 0x42, 0x46, 0xce, 0x79, 0x52, 0xed, 0x7e, 0xc9, 0x70, 0x98, 0x61, 0x59, 0x30, 0x80, + 0x30, 0x9e, 0x62, 0xa1, 0x90, 0xd2, 0x39, 0x58, 0xbb, 0x09, 0xaf, 0x52, 0x17, 0x11, 0x67, 0xea, + 0x6e, 0x27, 0xd8, 0x4c, 0x35, 0x96, 0x42, 0x6f, 0x1c, 0x70, 0x66, 0x02, 0xa2, 0x6d, 0xc6, 0x60, + 0xef, 0x33, 0x4b, 0x59, 0x50, 0x4b, 0x5a, 0x60, 0xf2, 0xc3, 0x8e, 0x3b, 0x2c, 0x06, 0x02, 0x4c, + 0x89, 0x7e, 0xc9, 0x34, 0xec, 0x19, 0xd9, 0x93, 0x81, 0xac, 0x99, 0x7b, 0x0c, 0x05, 0x2b, 0x10, + 0x56, 0xbf, 0x84, 0x82, 0x85, 0xa0, 0x9f, 0xbc, 0x71, 0x4f, 0x99, 0x59, 0x33, 0x79, 0xe3, 0xbe, + 0xa7, 0x4c, 0x1e, 0x8b, 0x98, 0x5c, 0x90, 0xd1, 0xb0, 0x4c, 0x43, 0x25, 0xe0, 0xf3, 0x7a, 0x06, + 0x14, 0x84, 0x3d, 0x30, 0x0c, 0xc7, 0x20, 0xc6, 0x5c, 0x09, 0xea, 0x8a, 0x43, 0xba, 0x21, 0x5c, + 0xdc, 0xa8, 0x91, 0x30, 0xba, 0x81, 0xa5, 0xb6, 0xb2, 0xc5, 0x50, 0xb9, 0xfd, 0x49, 0x43, 0x08, + 0xb1, 0x5d, 0xd2, 0x28, 0xbd, 0x22, 0xaf, 0x9b, 0x4a, 0x95, 0x9a, 0xd2, 0x3d, 0xe9, 0xfb, 0x93, + 0x06, 0x93, 0x63, 0xbb, 0xa4, 0x01, 0x8e, 0x0a, 0xa8, 0x48, 0x0d, 0x8b, 0x6c, 0xe5, 0xd6, 0x6b, + 0x01, 0x0a, 0x56, 0x12, 0x6e, 0x8e, 0xac, 0x4b, 0x65, 0x90, 0x56, 0xc4, 0xd5, 0x8b, 0x0b, 0x6e, + 0xb5, 0xdd, 0xb3, 0xf4, 0x01, 0x4e, 0x1a, 0x42, 0x7e, 0xee, 0x9a, 0xc5, 0x51, 0x2a, 0xb7, 0x7d, + 0x8b, 0x0d, 0x4f, 0xd6, 0x62, 0xab, 0x5b, 0x84, 0x65, 0x94, 0x98, 0x65, 0xd8, 0xe9, 0x5a, 0x5f, + 0x21, 0x8b, 0xd7, 0xf4, 0xbe, 0x95, 0xea, 0xe9, 0x5f, 0x09, 0xd8, 0x95, 0x96, 0xd4, 0xd2, 0xba, + 0x28, 0xec, 0x19, 0xea, 0x62, 0xa1, 0xc5, 0x27, 0x95, 0xaa, 0xdc, 0x2f, 0x7c, 0x44, 0x52, 0x66, + 0x9c, 0xa9, 0x73, 0x49, 0x51, 0x9d, 0x2b, 0xb7, 0x28, 0x69, 0xc0, 0xf0, 0xf8, 0xbe, 0xc4, 0x8d, + 0x71, 0x12, 0x30, 0xfd, 0xbd, 0x37, 0x31, 0xc0, 0x6c, 0x49, 0x7e, 0x42, 0x5d, 0x66, 0x7c, 0xbb, + 0x50, 0x73, 0x2a, 0x40, 0x51, 0x83, 0x1a, 0x06, 0x6c, 0x02, 0x91, 0xe0, 0xce, 0x20, 0xc5, 0xe1, + 0x4d, 0x21, 0x42, 0x40, 0x1a, 0x25, 0xed, 0xcd, 0xe0, 0x4b, 0x93, 0xf1, 0xf0, 0x04, 0x50, 0x84, + 0x84, 0x93, 0xac, 0x50, 0x38, 0xc9, 0x15, 0x09, 0x27, 0x50, 0x60, 0xe8, 0x45, 0xd1, 0x95, 0xe7, + 0xdf, 0x38, 0xaf, 0x5e, 0xe1, 0x86, 0xfc, 0x98, 0xcb, 0xc5, 0x3c, 0x20, 0xe5, 0xa3, 0x3a, 0x55, + 0x0c, 0xf3, 0x27, 0xae, 0x35, 0x7a, 0x7c, 0x7c, 0xf5, 0xa9, 0xc2, 0x94, 0x64, 0xb5, 0x61, 0x0a, + 0x04, 0xbc, 0x61, 0x2d, 0x18, 0x79, 0x40, 0x56, 0x6f, 0x8c, 0x3f, 0x60, 0x29, 0x72, 0x5f, 0xbf, + 0xbb, 0xbb, 0xab, 0x0f, 0x93, 0x74, 0x5c, 0x9f, 0xa6, 0x11, 0x66, 0xd6, 0xdb, 0xc1, 0xaa, 0xfd, + 0xc3, 0xec, 0x45, 0x98, 0x5e, 0xfc, 0xf8, 0xf3, 0x09, 0xf6, 0x52, 0x7f, 0x24, 0x3c, 0x14, 0x88, + 0xf5, 0xfc, 0xbd, 0x85, 0x97, 0xee, 0xad, 0x29, 0x0b, 0xab, 0xaf, 0xed, 0x2d, 0xac, 0xed, 0xad, + 0x22, 0xdc, 0x4f, 0xa5, 0x25, 0xef, 0x31, 0xb5, 0x66, 0xc7, 0x4c, 0xb3, 0xb3, 0x5c, 0x47, 0xd0, + 0xd4, 0xb4, 0x0b, 0x70, 0x00, 0xfb, 0xfc, 0x40, 0x73, 0x5d, 0x9b, 0x42, 0x3a, 0x7a, 0x14, 0x6f, + 0xaf, 0x71, 0x32, 0x9d, 0x80, 0x1a, 0x06, 0x07, 0x4a, 0x4d, 0x70, 0x94, 0x26, 0x34, 0xf1, 0x93, + 0xe8, 0x1b, 0x4e, 0x01, 0x42, 0x0a, 0x3b, 0x70, 0x09, 0x76, 0x0e, 0x77, 0xc9, 0x17, 0xbc, 0x7b, + 0x10, 0xe0, 0x1d, 0x84, 0x74, 0x42, 0x2b, 0xf1, 0x99, 0xa8, 0xce, 0x25, 0xa9, 0x9b, 0x43, 0x27, + 0x79, 0xf7, 0xd9, 0xec, 0x56, 0x06, 0x76, 0x41, 0xf6, 0xa7, 0x55, 0x3d, 0x3b, 0x9f, 0x5f, 0x64, + 0x2e, 0xaa, 0xfb, 0xd9, 0xcf, 0x1b, 0x75, 0xbb, 0x48, 0x05, 0xc6, 0x93, 0x54, 0x29, 0x73, 0x4d, + 0xb4, 0x08, 0xf4, 0xa8, 0x40, 0x52, 0x7c, 0x82, 0xc0, 0x44, 0xc6, 0x49, 0x80, 0xeb, 0x31, 0x33, + 0x4b, 0x21, 0x03, 0xc1, 0x60, 0x19, 0xdc, 0xaa, 0x01, 0xc9, 0xec, 0x30, 0x60, 0x99, 0x9a, 0xd0, + 0x7f, 0xff, 0x43, 0xad, 0x28, 0x85, 0x43, 0x9b, 0xd6, 0xfc, 0x1f, 0xff, 0xf6, 0x7f, 0x2e, 0x1d, + 0x43, 0x3c, 0x05, 0xc6, 0x9c, 0xcf, 0xb2, 0x83, 0x11, 0xb2, 0xbd, 0x44, 0x1f, 0xfe, 0xf1, 0x6f, + 0xff, 0xc7, 0xc8, 0x38, 0x53, 0x79, 0x0f, 0x1b, 0x48, 0xbb, 0x93, 0xa5, 0x31, 0x06, 0x13, 0x7a, + 0x64, 0x65, 0xa7, 0x13, 0xa0, 0xc7, 0x0c, 0x04, 0x32, 0x20, 0x79, 0xa8, 0x34, 0x1a, 0x5c, 0x40, + 0x37, 0x70, 0xb7, 0x03, 0x21, 0xdd, 0xb5, 0x60, 0x82, 0xa0, 0x8e, 0xad, 0xf3, 0x6f, 0x23, 0x7b, + 0x27, 0x94, 0xcd, 0xcd, 0xbb, 0xad, 0xc8, 0xd8, 0xcd, 0x65, 0x58, 0x82, 0x6c, 0x73, 0x5f, 0xc9, + 0x12, 0x92, 0xb3, 0x6f, 0x78, 0xd4, 0xac, 0xdb, 0x16, 0x8a, 0xdd, 0x5d, 0x53, 0x52, 0x72, 0x40, + 0x83, 0x00, 0x71, 0xc7, 0xed, 0xd0, 0xe2, 0x46, 0x8a, 0x27, 0x91, 0xe7, 0xe3, 0xdd, 0x51, 0x18, + 0x05, 0x29, 0x8e, 0xc1, 0x20, 0xcf, 0x12, 0xb1, 0x83, 0x41, 0x13, 0x03, 0xf4, 0x84, 0xd5, 0xd7, + 0x45, 0x29, 0x86, 0x6c, 0x00, 0xc5, 0x9a, 0x0c, 0x84, 0xd0, 0x14, 0x7c, 0x66, 0x41, 0xfc, 0x11, + 0xa8, 0x35, 0xfa, 0x92, 0xdd, 0xfa, 0x05, 0x11, 0x09, 0x97, 0xcc, 0x5b, 0xd6, 0x1c, 0x47, 0x04, + 0xd7, 0xaa, 0x9a, 0xaf, 0xe1, 0xf1, 0x84, 0x3e, 0x40, 0x27, 0xba, 0xb0, 0xc6, 0xf8, 0x92, 0xd4, + 0xf8, 0xb4, 0x6b, 0x8a, 0x32, 0x15, 0xa6, 0x34, 0x92, 0xd0, 0x3c, 0x6b, 0x9e, 0xa3, 0x14, 0x26, + 0xcc, 0x3f, 0xb5, 0xf9, 0xa6, 0x15, 0x93, 0x4d, 0x06, 0x66, 0x5a, 0x39, 0xb9, 0xb4, 0x7a, 0x72, + 0x49, 0x05, 0x43, 0x1d, 0xb3, 0x9b, 0x22, 0x37, 0xbf, 0xcb, 0xd7, 0xb3, 0x30, 0x31, 0x13, 0x9d, + 0x62, 0x9d, 0x2b, 0xf6, 0x3a, 0x29, 0xb0, 0xd7, 0x96, 0x65, 0x39, 0x95, 0xa3, 0x90, 0x30, 0x48, + 0xf3, 0x30, 0xd0, 0x37, 0xaf, 0xc7, 0x1a, 0x27, 0x02, 0x83, 0x87, 0xae, 0x20, 0x38, 0x06, 0x8a, + 0xe2, 0x50, 0xfb, 0x0b, 0x82, 0x90, 0x18, 0x25, 0x22, 0x26, 0xb4, 0x40, 0xca, 0x18, 0xce, 0x6b, + 0xc1, 0xfb, 0xf1, 0x25, 0x13, 0xe1, 0xc1, 0x2f, 0xb1, 0xa3, 0xa1, 0x1a, 0x89, 0x53, 0x63, 0x11, + 0xe9, 0x33, 0x90, 0x11, 0x4e, 0xac, 0xc1, 0xe5, 0xc9, 0x97, 0xe3, 0xda, 0xeb, 0x99, 0x4e, 0xef, + 0x9c, 0xc4, 0xa9, 0x12, 0x13, 0xda, 0x4c, 0xc1, 0x06, 0x65, 0xb2, 0xf3, 0x02, 0xad, 0x0f, 0x53, + 0x6e, 0x41, 0xf4, 0xc0, 0x4e, 0x6f, 0xca, 0x4d, 0x3d, 0xf1, 0x6f, 0x30, 0x26, 0x90, 0x65, 0x66, + 0x29, 0xd6, 0xbc, 0x76, 0xf0, 0xe9, 0x77, 0x31, 0xc2, 0x83, 0x4f, 0xbf, 0x6b, 0x6d, 0x08, 0x0a, + 0x09, 0x8e, 0xa7, 0xf8, 0x09, 0xd5, 0xbf, 0xc1, 0x28, 0xc5, 0x77, 0x03, 0x82, 0x8c, 0x5a, 0xf3, + 0x9a, 0xf8, 0x14, 0xad, 0xc8, 0x7a, 0xec, 0x3c, 0x71, 0x37, 0xa6, 0x31, 0xa6, 0x38, 0xad, 0x0f, + 0x43, 0xb0, 0x2b, 0x6f, 0x10, 0xfa, 0x10, 0xe1, 0xc6, 0x5d, 0x18, 0xd0, 0x91, 0x5b, 0x0d, 0x36, + 0x25, 0x98, 0xee, 0x20, 0x65, 0xbb, 0x62, 0x37, 0x9b, 0xc8, 0x0c, 0xdf, 0xd8, 0xad, 0xae, 0xb5, + 0xde, 0xb2, 0xac, 0xf9, 0x5f, 0x2e, 0x1d, 0xa3, 0xa9, 0x49, 0x32, 0x81, 0xed, 0x9e, 0x01, 0xfe, + 0xec, 0x73, 0x34, 0x27, 0xd8, 0x22, 0x29, 0x6c, 0x02, 0x49, 0x7f, 0x08, 0xca, 0x2e, 0xe0, 0xf4, + 0x6e, 0x59, 0x2c, 0x67, 0x25, 0x5c, 0x0a, 0xd9, 0xb9, 0xca, 0x49, 0x90, 0x76, 0xcb, 0xc2, 0xa3, + 0xb9, 0xd4, 0xa2, 0x28, 0x5c, 0x95, 0x6b, 0x73, 0x1f, 0xab, 0x36, 0xc3, 0x27, 0x09, 0x87, 0x0c, + 0x2e, 0x1c, 0x32, 0x34, 0x21, 0x90, 0xaa, 0x68, 0xcd, 0x2d, 0xeb, 0x1c, 0x76, 0x18, 0x1d, 0xc1, + 0x99, 0xac, 0xfb, 0xe0, 0x5e, 0x66, 0x20, 0xa2, 0x9e, 0x3a, 0xe6, 0x18, 0x70, 0x57, 0x15, 0x88, + 0x42, 0xe6, 0xd3, 0x8b, 0x2b, 0x4e, 0x62, 0x86, 0x53, 0xb1, 0x76, 0xf4, 0x26, 0xa0, 0x16, 0x87, + 0x53, 0xa0, 0x8c, 0x71, 0x24, 0x1f, 0x57, 0x03, 0xfb, 0x0b, 0x09, 0xb7, 0x1a, 0xd4, 0xf0, 0xd2, + 0x9a, 0x37, 0xa4, 0x38, 0x65, 0x46, 0x08, 0x0d, 0xb0, 0xe1, 0x93, 0x1c, 0x5a, 0x08, 0x1c, 0x1a, + 0x91, 0x78, 0xad, 0x8c, 0x90, 0x1f, 0xdc, 0xed, 0x07, 0xe1, 0xf8, 0x13, 0x32, 0x8c, 0x87, 0x7c, + 0x37, 0x90, 0xd8, 0x73, 0xe4, 0x06, 0xb9, 0x72, 0x02, 0x71, 0xcb, 0x77, 0x7b, 0x22, 0x90, 0x10, + 0x8b, 0x7b, 0x0d, 0x5d, 0xf2, 0x79, 0xbe, 0xd6, 0xc4, 0x51, 0xb2, 0xcd, 0x81, 0x91, 0x89, 0x48, + 0x0d, 0x10, 0x21, 0x47, 0x3c, 0x14, 0x9a, 0xac, 0x2b, 0x3c, 0xbb, 0x33, 0x2c, 0xc2, 0xe1, 0x6d, + 0xa0, 0xb0, 0xc1, 0x7f, 0x41, 0x3c, 0xe2, 0x2c, 0x57, 0x41, 0x7c, 0x02, 0xe4, 0xdb, 0xb0, 0x1a, + 0x5b, 0xf1, 0x1d, 0xc3, 0x51, 0xd3, 0xd8, 0x8b, 0x22, 0x96, 0xe8, 0x0f, 0x18, 0x3a, 0x79, 0x7c, + 0x0c, 0x1b, 0x72, 0x91, 0xc5, 0x5d, 0x35, 0x76, 0x47, 0x83, 0x52, 0x0f, 0x57, 0x5e, 0x00, 0x1e, + 0x1d, 0x23, 0xcb, 0x39, 0xe0, 0x0e, 0xdf, 0x59, 0x96, 0xb8, 0xeb, 0x06, 0x5e, 0x62, 0xfa, 0x9a, + 0xee, 0x14, 0x64, 0x64, 0xfd, 0x48, 0x8e, 0x68, 0x8a, 0x86, 0xec, 0x4d, 0xa9, 0x0a, 0x3f, 0x25, + 0x3f, 0x0a, 0xfd, 0x1b, 0x83, 0xbd, 0x17, 0x7e, 0x08, 0xbb, 0x0a, 0x20, 0x0f, 0x22, 0x21, 0x51, + 0x33, 0xb2, 0xe6, 0xfc, 0x22, 0x83, 0xfd, 0xe3, 0xa5, 0xd7, 0x60, 0x19, 0xcb, 0x80, 0x6a, 0x08, + 0x23, 0xd2, 0xe2, 0x26, 0x02, 0x12, 0xef, 0x70, 0x02, 0xc7, 0xcc, 0x34, 0x76, 0x47, 0x49, 0x42, + 0xc0, 0x8f, 0xdc, 0x0f, 0x27, 0x21, 0x28, 0x1c, 0x10, 0x78, 0xd4, 0x21, 0xed, 0xa8, 0x89, 0x3d, + 0x2a, 0xcc, 0x7c, 0x16, 0xa8, 0x14, 0x8c, 0x64, 0x42, 0xaf, 0xd3, 0x64, 0x3a, 0x61, 0x06, 0x3e, + 0x4c, 0x92, 0xed, 0xca, 0x53, 0x47, 0x0c, 0xb5, 0xc1, 0x02, 0x2e, 0x02, 0x90, 0x6d, 0x5b, 0xa1, + 0x9c, 0x83, 0x36, 0x24, 0x38, 0xc2, 0x81, 0x3c, 0xc2, 0xb7, 0x10, 0xa1, 0xd1, 0xd2, 0xf4, 0x08, + 0xa1, 0x35, 0x97, 0xcc, 0xae, 0x4e, 0x61, 0xfc, 0x91, 0xe1, 0x09, 0x69, 0xae, 0xa2, 0x5b, 0x4a, + 0xa3, 0x14, 0x19, 0x95, 0xa3, 0x0c, 0x96, 0x21, 0x85, 0x7d, 0x5c, 0x1e, 0x35, 0x6d, 0xdc, 0x82, + 0x43, 0xa5, 0x9b, 0xed, 0x78, 0x21, 0xd3, 0xc8, 0x4b, 0x61, 0x01, 0x4b, 0xf8, 0x49, 0x7c, 0x8b, + 0x53, 0xc2, 0x98, 0x83, 0x3a, 0xdb, 0x78, 0x06, 0x8a, 0x15, 0xb5, 0x20, 0x56, 0xcc, 0xab, 0xe9, + 0xc5, 0x38, 0x9e, 0xcf, 0x55, 0x94, 0x9b, 0x96, 0xd5, 0x95, 0x1f, 0xac, 0x3e, 0x17, 0xb9, 0x27, + 0x69, 0x2d, 0xc8, 0x41, 0xa0, 0xa2, 0x0d, 0x79, 0xb6, 0xe2, 0x81, 0x38, 0x5c, 0x8f, 0x8f, 0xc6, + 0xbf, 0x28, 0xab, 0x5c, 0x8d, 0x5a, 0x12, 0x08, 0x2b, 0x29, 0x23, 0xac, 0x3e, 0x8f, 0x07, 0x53, + 0x46, 0x26, 0xa1, 0xbb, 0x1d, 0x0a, 0x64, 0xa2, 0xcf, 0x3f, 0xd5, 0x0c, 0x78, 0xb3, 0xc3, 0xca, + 0x54, 0x4b, 0xc6, 0x1d, 0x8e, 0x7c, 0xb8, 0xca, 0xae, 0xa6, 0x57, 0x57, 0x7c, 0x62, 0x97, 0x5f, + 0x12, 0x45, 0xe1, 0xd4, 0xee, 0x42, 0x0a, 0xea, 0x3e, 0x6e, 0x94, 0x3e, 0xaf, 0x3d, 0x60, 0xda, + 0x80, 0xdb, 0x94, 0x35, 0x0d, 0xf0, 0xca, 0x26, 0x2e, 0x66, 0x0c, 0x26, 0x56, 0x4c, 0x3a, 0x54, + 0xa3, 0x5e, 0x74, 0x03, 0xb4, 0x82, 0xe7, 0xa7, 0x09, 0xe1, 0xce, 0x02, 0x63, 0x4c, 0x46, 0x65, + 0xec, 0x98, 0x4a, 0xec, 0x78, 0x60, 0x1a, 0x5e, 0x4a, 0x43, 0x1f, 0xc6, 0x71, 0xc9, 0x07, 0x54, + 0x83, 0xbb, 0x67, 0x99, 0xd9, 0xc3, 0x9c, 0x95, 0x50, 0x36, 0xdd, 0x86, 0xb0, 0x68, 0x1a, 0xc8, + 0x1f, 0x1c, 0xe3, 0x21, 0xdf, 0xad, 0x6a, 0xe6, 0x92, 0x13, 0x46, 0xb2, 0xfe, 0xfc, 0xb2, 0x64, + 0xed, 0x10, 0x72, 0x6b, 0x07, 0x56, 0x90, 0xd3, 0x19, 0x2c, 0xa5, 0x40, 0x5d, 0x18, 0xfd, 0xa0, + 0x70, 0x71, 0x00, 0x02, 0xe4, 0x72, 0xd3, 0x1c, 0x02, 0xbc, 0x7c, 0x3d, 0xf3, 0x12, 0x33, 0xd4, + 0x30, 0xd6, 0xfc, 0xf5, 0xcc, 0x07, 0x3a, 0x0c, 0xa9, 0xa5, 0x09, 0xc0, 0x95, 0x86, 0x39, 0x84, + 0xef, 0xc4, 0xe1, 0x98, 0x6d, 0x1a, 0x6e, 0x18, 0xcb, 0xcc, 0xc7, 0x92, 0x06, 0xf1, 0xc1, 0xac, + 0xfd, 0x34, 0x99, 0xb8, 0xf2, 0xf7, 0x27, 0x70, 0xa9, 0xa6, 0x73, 0x46, 0x4d, 0xc8, 0xdd, 0x13, + 0xc6, 0x13, 0xd0, 0xe8, 0x69, 0xdc, 0x4e, 0xfc, 0xf8, 0xf8, 0x4a, 0x93, 0x68, 0x71, 0x6d, 0xd7, + 0x78, 0x92, 0x10, 0x9c, 0x1a, 0x56, 0xe3, 0x37, 0x60, 0x03, 0xf9, 0xba, 0x02, 0xdf, 0x5e, 0xc1, + 0x2d, 0x15, 0xea, 0x67, 0x74, 0xc5, 0x21, 0x13, 0xdc, 0x6b, 0xd7, 0x0e, 0x51, 0xeb, 0x8b, 0x0b, + 0xf2, 0x49, 0xe9, 0xe3, 0x4a, 0xc0, 0x5f, 0x40, 0x5c, 0x67, 0xee, 0x2b, 0xdb, 0xea, 0xe7, 0xf5, + 0x02, 0x1a, 0x57, 0x96, 0x19, 0x7c, 0x64, 0x74, 0xb5, 0x38, 0x19, 0x4c, 0x16, 0x5e, 0xbe, 0xcd, + 0x5f, 0x49, 0x72, 0x5c, 0xe1, 0x31, 0xa2, 0x2d, 0x8e, 0xda, 0x60, 0x86, 0xef, 0xa5, 0x41, 0x2d, + 0x7f, 0xc1, 0x7f, 0x61, 0xf5, 0x18, 0x55, 0x9d, 0xdd, 0xeb, 0x44, 0x52, 0xba, 0x35, 0x2f, 0x4d, + 0xc3, 0x5b, 0xcc, 0x36, 0xb0, 0x30, 0x1a, 0x2c, 0xcc, 0x93, 0xf7, 0xab, 0xa9, 0x6f, 0x0b, 0xbd, + 0x89, 0xf1, 0xc3, 0x6f, 0x03, 0x78, 0xa3, 0xf2, 0x8d, 0x9b, 0xd3, 0x73, 0x81, 0x30, 0x56, 0x1c, + 0x54, 0xc0, 0x03, 0x05, 0xd2, 0xe4, 0x01, 0x5f, 0xa5, 0xc9, 0x9d, 0x21, 0xde, 0xe1, 0x03, 0x7f, + 0x86, 0x81, 0x71, 0xbc, 0x77, 0xb4, 0xb7, 0x73, 0xba, 0x77, 0x6c, 0x38, 0x2a, 0xb5, 0x3d, 0x30, + 0x8e, 0x0f, 0x0f, 0x0f, 0x0c, 0xc7, 0xd8, 0x3d, 0xfc, 0x72, 0xba, 0xb3, 0x7b, 0xca, 0xf9, 0x85, + 0x51, 0x9b, 0x6d, 0x48, 0xbc, 0x94, 0xa9, 0xe0, 0x3b, 0x59, 0xf1, 0xb3, 0xba, 0x72, 0xae, 0x2b, + 0xb9, 0x0a, 0xfd, 0xdd, 0xbf, 0x6d, 0x6e, 0xfc, 0xa0, 0xa5, 0xcc, 0x6b, 0xa3, 0x64, 0x52, 0x9b, + 0x78, 0x74, 0x74, 0xe9, 0x18, 0x2c, 0xfa, 0x3d, 0xfb, 0x80, 0x33, 0x29, 0xd1, 0x58, 0x76, 0xb7, + 0x1b, 0x28, 0x4c, 0x4c, 0x5d, 0xf0, 0x0e, 0xc1, 0x1f, 0x75, 0x1a, 0xc7, 0x10, 0x48, 0xa6, 0xee, + 0xb1, 0xdd, 0x61, 0x20, 0x43, 0x88, 0x84, 0x6b, 0xff, 0xf8, 0x5f, 0xff, 0x37, 0xbb, 0x87, 0x72, + 0x74, 0x0d, 0xd0, 0x2f, 0xcb, 0x6e, 0x7e, 0x7d, 0xcf, 0x32, 0x6d, 0x1f, 0xfa, 0x4a, 0xcc, 0x4c, + 0xef, 0x00, 0x46, 0xa8, 0xea, 0xba, 0x11, 0x8f, 0x3b, 0x02, 0xb1, 0xa8, 0x94, 0xea, 0x9a, 0xf4, + 0xe0, 0x03, 0x29, 0x48, 0x0f, 0x10, 0x96, 0x0c, 0x11, 0x02, 0x95, 0xae, 0xa0, 0xf8, 0xe1, 0x2a, + 0xe2, 0xf4, 0x7e, 0x35, 0x4f, 0x84, 0x33, 0xee, 0x09, 0xec, 0xdb, 0xe4, 0x6f, 0x27, 0xe3, 0xf5, + 0x79, 0x6d, 0x08, 0x2a, 0x16, 0x02, 0x7f, 0xb6, 0xb4, 0x81, 0xd3, 0xd4, 0xcc, 0xda, 0xb0, 0xf2, + 0xa2, 0x07, 0xc2, 0x84, 0xbf, 0x7a, 0x9b, 0x95, 0xec, 0x16, 0x2e, 0x33, 0x5a, 0xb8, 0x8a, 0xc5, + 0xaa, 0x05, 0xef, 0x8b, 0x5c, 0x16, 0x6f, 0x95, 0x3d, 0x40, 0x51, 0xd9, 0x2e, 0xcb, 0x81, 0x78, + 0xa2, 0xd0, 0xf4, 0x17, 0xf8, 0x60, 0x8d, 0x67, 0xc9, 0x92, 0x33, 0xe4, 0x79, 0x85, 0x76, 0x35, + 0xf6, 0x0d, 0xd8, 0x35, 0x8d, 0x83, 0xb3, 0xb4, 0x52, 0x57, 0x5e, 0x1c, 0x30, 0x36, 0xca, 0x40, + 0x60, 0x5e, 0x22, 0x4a, 0xbd, 0xbf, 0xd3, 0xcb, 0x90, 0x09, 0x60, 0x21, 0x6e, 0xb7, 0x2e, 0x0a, + 0x9c, 0x0c, 0x07, 0x97, 0x27, 0x1f, 0x41, 0xe0, 0x2b, 0x3e, 0xe7, 0x97, 0xa5, 0x25, 0xf0, 0x93, + 0x7c, 0x9d, 0xdd, 0x74, 0x70, 0xb9, 0x7b, 0x5c, 0xeb, 0xbc, 0x55, 0xd5, 0x76, 0x53, 0xa8, 0xb6, + 0x5b, 0x02, 0xc9, 0x24, 0xb9, 0xc3, 0x15, 0xa0, 0x26, 0x83, 0x06, 0xbd, 0x3f, 0x82, 0x3c, 0x66, + 0x23, 0xc5, 0x7f, 0x6a, 0xdd, 0xf2, 0x2d, 0x54, 0xcf, 0x54, 0x68, 0xdf, 0x30, 0xb3, 0xad, 0x06, + 0x06, 0x53, 0x2f, 0x40, 0x18, 0xc9, 0xc9, 0x33, 0xe1, 0x77, 0x2e, 0x33, 0x10, 0x1c, 0x15, 0xcf, + 0x8e, 0x8f, 0xb1, 0x7f, 0xcb, 0x69, 0xb6, 0x5c, 0x29, 0x76, 0x50, 0x73, 0x85, 0x58, 0xdc, 0x57, + 0x4b, 0x3a, 0x31, 0xc9, 0x54, 0x26, 0xd4, 0x24, 0x83, 0x41, 0xb3, 0x9f, 0xd5, 0x65, 0x96, 0xc4, + 0x84, 0x5d, 0x75, 0xdf, 0xc0, 0x15, 0x6d, 0x5e, 0x63, 0x29, 0xaf, 0x67, 0x71, 0x4e, 0xf7, 0xc2, + 0x2e, 0xab, 0x7c, 0x15, 0xdd, 0x86, 0x22, 0x1e, 0x08, 0x93, 0x64, 0xc7, 0xf8, 0x6d, 0x1a, 0x62, + 0x0a, 0x2c, 0x36, 0xc8, 0x25, 0x98, 0x8d, 0x08, 0x40, 0xd1, 0x58, 0x5b, 0xab, 0xbe, 0x25, 0x27, + 0x89, 0x76, 0x7d, 0x4c, 0x12, 0xfd, 0xfa, 0xe0, 0x7e, 0x60, 0x75, 0x30, 0xf7, 0x05, 0xca, 0x8c, + 0xa9, 0x4c, 0x23, 0xa0, 0xd0, 0x7f, 0x86, 0x2d, 0x82, 0xa8, 0xfa, 0xe6, 0x17, 0x2a, 0x93, 0xe6, + 0xbf, 0x6b, 0x35, 0x1f, 0x1f, 0xe9, 0xbb, 0x56, 0x53, 0x9a, 0x14, 0x72, 0x08, 0x28, 0xa6, 0x9b, + 0x0b, 0x51, 0x8f, 0xc2, 0x7b, 0x1c, 0x1d, 0xc3, 0x28, 0x1e, 0x1f, 0x6d, 0xd4, 0xb2, 0xfa, 0x44, + 0x70, 0xef, 0x5c, 0x0b, 0x9f, 0x4c, 0xe3, 0xc0, 0xc4, 0xeb, 0x31, 0x60, 0x8f, 0x11, 0x6b, 0x5b, + 0xcf, 0xa0, 0xeb, 0xb1, 0x24, 0xff, 0x88, 0x54, 0x17, 0xe2, 0x7b, 0x6a, 0x1a, 0xad, 0x80, 0xe1, + 0x7d, 0x02, 0xc6, 0x6e, 0x66, 0x0c, 0xef, 0xc8, 0x25, 0x0d, 0x66, 0x87, 0x7f, 0x0c, 0x76, 0xde, + 0x4d, 0x08, 0x8b, 0x04, 0x66, 0x2b, 0x09, 0x98, 0xe3, 0x26, 0x37, 0xf8, 0x04, 0xa4, 0x06, 0xae, + 0x91, 0x5e, 0x5f, 0x79, 0xa6, 0xdd, 0xb1, 0x91, 0xdd, 0x6d, 0x81, 0x31, 0x33, 0x6a, 0xd8, 0x2d, + 0x0b, 0xc4, 0x47, 0x60, 0x1a, 0xc3, 0x66, 0xea, 0x66, 0x0a, 0xc4, 0xd0, 0xb5, 0xfb, 0xe1, 0xbb, + 0x4e, 0x3f, 0x04, 0xbb, 0xe8, 0xa4, 0x71, 0x85, 0xaf, 0xc3, 0x98, 0x05, 0x5d, 0x82, 0x66, 0xc1, + 0xe8, 0xe7, 0x34, 0x31, 0x9b, 0x28, 0x5c, 0xa7, 0x6f, 0x3b, 0x96, 0x68, 0xe2, 0x34, 0x81, 0x40, + 0x35, 0x32, 0x85, 0x77, 0xad, 0xd1, 0xa4, 0x99, 0x5e, 0x49, 0x18, 0x08, 0xd8, 0x03, 0x2d, 0xd1, + 0x39, 0xab, 0x43, 0x54, 0x17, 0xf8, 0x73, 0xde, 0xcf, 0xf7, 0x97, 0x36, 0x86, 0x49, 0xba, 0xe7, + 0x81, 0x1b, 0x81, 0x08, 0xd7, 0xcc, 0xe3, 0xf2, 0x06, 0xeb, 0xf8, 0xad, 0x12, 0x77, 0xd8, 0x48, + 0x12, 0xb3, 0x9c, 0x3f, 0xa6, 0xf5, 0xa2, 0x89, 0x1e, 0x93, 0x84, 0x30, 0x39, 0x48, 0xbb, 0x69, + 0x81, 0xbd, 0x9a, 0xb5, 0x4e, 0xfb, 0xc1, 0x40, 0x8d, 0x1d, 0xde, 0xe6, 0x75, 0xd4, 0xdc, 0xd8, + 0x4b, 0xbd, 0x25, 0x10, 0xfe, 0x4b, 0xa7, 0x33, 0x6c, 0x6e, 0x7a, 0x79, 0xa0, 0xb5, 0xa0, 0xd4, + 0xc8, 0x0b, 0x92, 0xbb, 0xdd, 0x24, 0x4a, 0xd2, 0x5c, 0x29, 0x9e, 0xfe, 0x3e, 0x9a, 0xa6, 0xee, + 0xa6, 0x06, 0x14, 0xcd, 0x8a, 0x4c, 0xbf, 0x1f, 0x84, 0x66, 0x83, 0x5d, 0x11, 0x9a, 0x59, 0x94, + 0x34, 0x6e, 0xea, 0x93, 0x01, 0x61, 0xaa, 0x1e, 0x57, 0xd3, 0x1a, 0x0d, 0x4c, 0x90, 0xc9, 0xf2, + 0x8a, 0x92, 0x81, 0xb9, 0x54, 0xd6, 0x53, 0x40, 0x75, 0x33, 0xfd, 0x14, 0x09, 0x83, 0xc7, 0x47, + 0x83, 0x19, 0x9c, 0xd6, 0x7e, 0x0e, 0xeb, 0x1f, 0x43, 0x76, 0xd4, 0xb4, 0xaa, 0x64, 0x3a, 0x1e, + 0x7b, 0xe9, 0x03, 0x3b, 0x9f, 0xa4, 0x11, 0x4e, 0x1e, 0x1f, 0x8d, 0x0f, 0x9f, 0x76, 0x8f, 0x6a, + 0x5e, 0x10, 0xa4, 0xf0, 0x0a, 0x99, 0xb0, 0x32, 0x37, 0xe6, 0x90, 0x2d, 0xb5, 0x42, 0x03, 0x03, + 0xee, 0x7a, 0xf9, 0x95, 0x09, 0x13, 0x20, 0x95, 0xa9, 0x71, 0x6a, 0x49, 0x5c, 0x7b, 0x48, 0xa6, + 0x29, 0x0f, 0x29, 0x20, 0x15, 0x59, 0xc5, 0xbe, 0xe1, 0xbd, 0x22, 0x86, 0x9c, 0x2e, 0xb5, 0xb1, + 0x7e, 0xd6, 0xc7, 0xca, 0x49, 0x0a, 0x7d, 0x5c, 0x6a, 0x3c, 0xbc, 0xa9, 0x71, 0x92, 0xe2, 0x7a, + 0x01, 0x0c, 0xb9, 0x26, 0x58, 0x29, 0x6f, 0x52, 0x17, 0xf3, 0xc9, 0xf7, 0x75, 0xc2, 0x81, 0xc9, + 0x15, 0x6c, 0x2b, 0x3a, 0xdb, 0xd5, 0x60, 0x86, 0xe9, 0x74, 0x92, 0x29, 0x10, 0x72, 0x12, 0x51, + 0x60, 0xfd, 0xae, 0x71, 0x4d, 0x87, 0xb8, 0xe5, 0x54, 0xac, 0x95, 0x0e, 0x4c, 0x6d, 0xbc, 0xb5, + 0x18, 0xe3, 0x80, 0xd4, 0x40, 0x53, 0x1c, 0xb3, 0x75, 0x06, 0xe6, 0x8a, 0xd6, 0xa6, 0x93, 0x7c, + 0x8b, 0x8b, 0x57, 0x50, 0xcc, 0x8c, 0xe9, 0xd9, 0xd8, 0x38, 0x6b, 0x3b, 0x47, 0x85, 0xa9, 0xd9, + 0x5b, 0xad, 0x86, 0xdd, 0xdb, 0x6c, 0x74, 0x1a, 0x76, 0xd5, 0xb2, 0x8a, 0x1d, 0xa6, 0x96, 0x57, + 0xb2, 0x4c, 0xab, 0x16, 0xee, 0xc9, 0x5d, 0x2e, 0x5e, 0x39, 0x7d, 0x28, 0x1f, 0xe5, 0xee, 0x52, + 0x4d, 0x3a, 0x85, 0x2e, 0x96, 0x2f, 0x2d, 0x2b, 0x35, 0x4a, 0x28, 0x99, 0x24, 0x74, 0xc5, 0x68, + 0x9e, 0xb8, 0xb4, 0x55, 0x0b, 0x51, 0xb5, 0xb4, 0x4f, 0x5f, 0x31, 0xe3, 0x2b, 0xc1, 0xfc, 0x9c, + 0xb4, 0x1a, 0x9d, 0xda, 0x0f, 0x9f, 0x7e, 0xaf, 0x81, 0x18, 0x59, 0xe9, 0x7d, 0x21, 0xb2, 0x00, + 0xe8, 0x17, 0x40, 0x62, 0x48, 0xbd, 0x07, 0x20, 0xd5, 0x92, 0x38, 0xf3, 0xb2, 0x27, 0xfa, 0x14, + 0x1b, 0x46, 0xf5, 0x0a, 0x19, 0x05, 0xed, 0xf5, 0x34, 0xf6, 0x6e, 0xbd, 0x30, 0x02, 0x1e, 0xce, + 0x58, 0x7c, 0x82, 0x58, 0xfb, 0xf2, 0xd4, 0x96, 0xe0, 0x6c, 0xec, 0xf2, 0xd6, 0xd9, 0xb9, 0x61, + 0xc2, 0xcf, 0xfd, 0xa3, 0x9a, 0x97, 0xe2, 0x42, 0xe3, 0xdf, 0x01, 0xd6, 0x25, 0x75, 0x15, 0x03, + 0x8a, 0xb9, 0x36, 0x0f, 0x2e, 0xe1, 0xba, 0xa7, 0x15, 0x10, 0x2a, 0x28, 0x32, 0x28, 0x69, 0xda, + 0x17, 0x54, 0xc8, 0x5a, 0xcc, 0xf0, 0xf3, 0x18, 0x08, 0x05, 0x40, 0xd2, 0xfa, 0x48, 0x40, 0x7d, + 0xac, 0xe9, 0xb8, 0x6c, 0x3d, 0x2f, 0xc5, 0x64, 0x1a, 0x51, 0x2d, 0xb7, 0x99, 0x9b, 0x03, 0x09, + 0x41, 0x3b, 0x26, 0xc5, 0x53, 0x22, 0x79, 0x50, 0xc6, 0xea, 0x2a, 0x4f, 0xe9, 0xed, 0xb5, 0x56, + 0x26, 0x1e, 0x21, 0x77, 0x49, 0x9a, 0xb5, 0xb4, 0x30, 0x9b, 0xb3, 0x3d, 0x2a, 0x21, 0x3f, 0xd0, + 0x5b, 0xec, 0x45, 0xa5, 0x45, 0x18, 0x01, 0xeb, 0x58, 0x55, 0x0c, 0xa2, 0x00, 0x52, 0x9a, 0x86, + 0x57, 0x53, 0x8a, 0x81, 0x81, 0x0d, 0x3d, 0xd0, 0x63, 0x11, 0xc2, 0xd4, 0xe7, 0x43, 0x2f, 0x22, + 0xd8, 0x90, 0x0a, 0x04, 0xad, 0x7a, 0x10, 0x7a, 0x51, 0x02, 0x11, 0x26, 0x48, 0x83, 0x8c, 0x92, + 0xbb, 0x83, 0x24, 0xf0, 0xa2, 0x81, 0xf6, 0xdb, 0xb4, 0x1c, 0x52, 0x68, 0x3a, 0x99, 0x60, 0xa6, + 0xb1, 0xb2, 0x2a, 0x00, 0x37, 0x4c, 0xfc, 0x29, 0xd1, 0xef, 0xcf, 0x2f, 0x24, 0x2f, 0x07, 0x28, + 0xf5, 0xca, 0x5c, 0xe8, 0x06, 0xca, 0x95, 0xce, 0x21, 0xc2, 0x68, 0xb9, 0xd8, 0xa1, 0xd6, 0xe6, + 0x03, 0x33, 0x67, 0x58, 0xbc, 0xde, 0xcd, 0xa5, 0xeb, 0x6d, 0x67, 0x1a, 0x86, 0x7c, 0x99, 0x3a, + 0xa1, 0x78, 0x42, 0xaa, 0x55, 0x0d, 0x42, 0x3d, 0x4a, 0x72, 0x7b, 0xe0, 0x8c, 0x31, 0x66, 0x8c, + 0x2b, 0x63, 0xe7, 0x90, 0x39, 0x29, 0x32, 0x19, 0x1a, 0xb8, 0x29, 0x2a, 0x13, 0x68, 0xfe, 0x3a, + 0xd0, 0x64, 0x94, 0xc4, 0xb8, 0x26, 0x74, 0xc7, 0x53, 0x50, 0x39, 0xd0, 0x84, 0xa3, 0x14, 0x86, + 0x4a, 0xd8, 0x79, 0xe2, 0xd5, 0xbc, 0x80, 0xa1, 0x0e, 0xe6, 0x3d, 0x01, 0x97, 0xdb, 0xfe, 0x51, + 0x0e, 0x9b, 0x9c, 0x7e, 0x3c, 0x65, 0x47, 0x19, 0xa0, 0x52, 0x83, 0x20, 0xc3, 0xe2, 0x06, 0x07, + 0xa1, 0x02, 0xc1, 0x69, 0xc3, 0x38, 0x77, 0x16, 0x0f, 0x0c, 0x4a, 0x4b, 0xbc, 0xcc, 0xb0, 0xc2, + 0x53, 0x47, 0xaa, 0xba, 0xe7, 0xb7, 0x1f, 0xec, 0x8f, 0x58, 0x0e, 0xeb, 0xf4, 0xe3, 0x29, 0x34, + 0x73, 0x08, 0x03, 0xd2, 0x50, 0x76, 0xc5, 0xc8, 0x14, 0xf9, 0x9a, 0x00, 0xae, 0xa4, 0x96, 0xae, + 0xb6, 0x89, 0x42, 0xae, 0x2d, 0xb5, 0x98, 0xdc, 0xb7, 0xb0, 0x34, 0xf2, 0xde, 0xc9, 0xc1, 0x5f, + 0x1f, 0x78, 0x09, 0x96, 0x70, 0x0b, 0xe9, 0xd9, 0x05, 0x6c, 0x0c, 0xd7, 0x92, 0x60, 0x09, 0xca, + 0x1b, 0x21, 0x4e, 0x28, 0x1c, 0x96, 0x2a, 0x4d, 0x77, 0x7e, 0x04, 0x4a, 0x9d, 0x6d, 0xec, 0xc7, + 0xea, 0x3e, 0x66, 0xc6, 0x3e, 0xac, 0x3f, 0x31, 0xf1, 0xda, 0xd8, 0x53, 0xef, 0xab, 0xd5, 0x3e, + 0x9d, 0x9e, 0x1e, 0xd5, 0xde, 0x7b, 0x24, 0xf4, 0x6b, 0xde, 0x14, 0x9c, 0x76, 0xa9, 0x30, 0x7d, + 0x69, 0xd4, 0xe0, 0x92, 0x99, 0x12, 0x9c, 0x82, 0x34, 0xa7, 0x66, 0xa0, 0xbc, 0x5e, 0x06, 0xc4, + 0x1b, 0x23, 0x1f, 0x2c, 0x58, 0x2c, 0x64, 0xb0, 0x0d, 0x00, 0x3d, 0x6c, 0xd6, 0x23, 0x0c, 0xc6, + 0x6a, 0xb5, 0x1b, 0xfc, 0x50, 0x5a, 0x14, 0x10, 0x81, 0xc1, 0x4f, 0x89, 0x5e, 0x1a, 0x86, 0xe5, + 0x14, 0x74, 0xe3, 0xa7, 0xa2, 0x24, 0x54, 0xe5, 0x85, 0x39, 0x78, 0x04, 0x8d, 0x03, 0x03, 0x81, + 0xae, 0x64, 0x0b, 0x42, 0x59, 0xa6, 0x76, 0xb9, 0x66, 0x50, 0x9d, 0x56, 0xc9, 0x51, 0x38, 0x93, + 0xd5, 0x57, 0xb7, 0xd7, 0x42, 0x83, 0x0c, 0x96, 0x0d, 0x80, 0x8b, 0x0c, 0x84, 0x07, 0x8d, 0xb1, + 0x17, 0x4f, 0x87, 0x9e, 0x0f, 0x21, 0x9a, 0xd3, 0x03, 0x48, 0x7d, 0x7c, 0x64, 0x96, 0xef, 0xf0, + 0x7c, 0x4d, 0x4d, 0xd9, 0xb9, 0x68, 0x55, 0x87, 0x61, 0x3a, 0xbe, 0xf3, 0xc0, 0xbc, 0x07, 0x0f, + 0x1a, 0xf2, 0xe3, 0x1b, 0xc4, 0xa0, 0x02, 0x8b, 0xe8, 0xc1, 0xa5, 0x34, 0x89, 0x61, 0x92, 0x0a, + 0x2d, 0x3f, 0x27, 0x1f, 0x60, 0x2d, 0x5d, 0x4d, 0xc3, 0x28, 0xc8, 0x35, 0x73, 0xc1, 0x92, 0x2e, + 0xc0, 0xee, 0x47, 0x37, 0xde, 0x60, 0xa5, 0x6f, 0xf0, 0x43, 0xd1, 0x88, 0x64, 0xb1, 0x05, 0x89, + 0xaa, 0xea, 0x4d, 0x26, 0xf5, 0x5b, 0x6e, 0x9c, 0x63, 0x20, 0xc3, 0x6e, 0x34, 0x1b, 0x4d, 0x9e, + 0x11, 0x85, 0x57, 0xa9, 0x97, 0x3e, 0xe4, 0x32, 0xed, 0x0e, 0xcb, 0xdd, 0x35, 0x0d, 0x2e, 0xce, + 0xac, 0x32, 0x88, 0x29, 0x8a, 0x87, 0x81, 0xd7, 0x54, 0xfe, 0xa7, 0x95, 0xe5, 0x0b, 0x36, 0xde, + 0xd9, 0x42, 0x82, 0x31, 0x0e, 0xb7, 0xa1, 0x14, 0x66, 0x90, 0x72, 0x59, 0x2f, 0x5f, 0xcf, 0xb2, + 0xc4, 0xbc, 0x47, 0x4f, 0xcb, 0x9a, 0xd7, 0xbe, 0x5d, 0xc2, 0x32, 0x8b, 0x6c, 0xe6, 0x6d, 0x01, + 0x5e, 0x2d, 0x73, 0x66, 0x2d, 0xce, 0xe5, 0xc3, 0x60, 0x5d, 0x04, 0xe2, 0x36, 0xc4, 0xae, 0x6b, + 0xd8, 0x30, 0x59, 0xaf, 0x5f, 0x85, 0x28, 0x9a, 0x89, 0x0a, 0x08, 0x52, 0xaa, 0xab, 0x9c, 0x74, + 0x7b, 0x27, 0x8a, 0x4c, 0x03, 0x44, 0xe7, 0x18, 0xee, 0x03, 0xc5, 0x75, 0xb2, 0x38, 0x9c, 0x99, + 0x57, 0x0c, 0x4d, 0xae, 0xaf, 0x23, 0xb8, 0x01, 0x39, 0xb3, 0x83, 0x30, 0xb3, 0x75, 0x24, 0x98, + 0x8a, 0x9a, 0xcc, 0xf5, 0xc1, 0x5a, 0xda, 0x45, 0xec, 0xdd, 0xd6, 0x14, 0xd4, 0x9e, 0xdd, 0x8d, + 0x10, 0x77, 0x10, 0x2e, 0x99, 0xe1, 0x9d, 0x2a, 0x04, 0x76, 0xd6, 0x3c, 0xcf, 0x3b, 0xe1, 0xbd, + 0x91, 0x76, 0x9c, 0x76, 0xae, 0xfc, 0x4d, 0xe8, 0xdf, 0x80, 0xb0, 0x89, 0xe1, 0x1b, 0x16, 0x7b, + 0x61, 0x60, 0xec, 0x1e, 0x1e, 0x1c, 0xed, 0x7c, 0xd9, 0x3f, 0xfc, 0x22, 0x3c, 0x6a, 0x94, 0xc0, + 0x73, 0x60, 0x1c, 0xec, 0x9d, 0x7c, 0xaa, 0xed, 0x7e, 0xda, 0x39, 0x15, 0x59, 0x5c, 0x60, 0x6d, + 0x0c, 0x8c, 0x0f, 0xfb, 0x27, 0xbb, 0x87, 0xdf, 0xf6, 0x8e, 0x7f, 0x91, 0x7e, 0x3a, 0x4c, 0x06, + 0x33, 0x30, 0x8e, 0x3f, 0xd6, 0x3e, 0xed, 0xed, 0x7c, 0x3e, 0xfd, 0x64, 0x38, 0xc6, 0x87, 0xbd, + 0x6f, 0xfb, 0xbb, 0x7b, 0x86, 0x40, 0x6e, 0xaa, 0x55, 0xb0, 0x4d, 0xcd, 0x1c, 0x24, 0x0e, 0x89, + 0xae, 0x9a, 0x43, 0x44, 0x17, 0xe8, 0xb0, 0x55, 0x15, 0x41, 0xfe, 0xa4, 0x96, 0xc3, 0x9c, 0xd1, + 0x04, 0xdc, 0x60, 0xaf, 0xf0, 0xc8, 0xbb, 0x0d, 0x93, 0xd4, 0x31, 0xc8, 0x38, 0x49, 0x40, 0x82, + 0x5c, 0x36, 0xbe, 0x66, 0xce, 0x1f, 0xa4, 0x01, 0x26, 0x2c, 0x38, 0xa6, 0x1f, 0xf0, 0xd0, 0x9b, + 0x46, 0xd4, 0xd4, 0x4c, 0x01, 0x0a, 0xca, 0x11, 0x04, 0x86, 0x4a, 0x8c, 0xb2, 0x12, 0x5e, 0x90, + 0xa8, 0xa4, 0x3a, 0x64, 0xf6, 0xd4, 0x8f, 0x8f, 0xaf, 0x62, 0x29, 0xfe, 0x81, 0x28, 0x04, 0xb4, + 0xc1, 0x0d, 0x0a, 0x4d, 0x2a, 0x55, 0xf1, 0xdb, 0x7b, 0x54, 0x06, 0x80, 0xd9, 0x37, 0x95, 0x50, + 0x3a, 0x24, 0x35, 0x70, 0xb3, 0xaf, 0xd9, 0x9d, 0x66, 0xed, 0x0a, 0xa2, 0xee, 0x6a, 0x51, 0x07, + 0xb8, 0xbc, 0x07, 0x8c, 0xf0, 0xc1, 0x34, 0x22, 0xeb, 0x52, 0xb8, 0x0f, 0x6b, 0xc6, 0xf5, 0x8b, + 0x1d, 0x0f, 0x75, 0x2b, 0x7b, 0xd0, 0x67, 0x29, 0x33, 0x7b, 0x22, 0xf8, 0x58, 0xe5, 0xd2, 0x6b, + 0xcf, 0x81, 0x1c, 0x51, 0x44, 0xe4, 0x9d, 0xb4, 0x09, 0xd4, 0xdf, 0xe1, 0xf0, 0xb9, 0x86, 0x29, + 0x96, 0xaa, 0xe4, 0xc1, 0xa7, 0x86, 0xf6, 0xd4, 0xd6, 0xa9, 0x66, 0x7f, 0xad, 0x8a, 0x68, 0x8e, + 0x05, 0x88, 0x5a, 0x0e, 0xaf, 0x50, 0x28, 0xc9, 0x25, 0xf6, 0x1a, 0x1e, 0xa3, 0x16, 0x13, 0x6a, + 0x71, 0x99, 0x87, 0xc1, 0xde, 0x2e, 0x0e, 0x0c, 0xf4, 0x4a, 0x35, 0xaa, 0x85, 0x4c, 0x94, 0xfe, + 0xc3, 0xe9, 0xa0, 0xe8, 0x40, 0xbc, 0xb6, 0x66, 0x26, 0x85, 0x34, 0x37, 0x2d, 0x16, 0xe2, 0xde, + 0x26, 0xda, 0x82, 0x88, 0xce, 0xa4, 0x65, 0x61, 0x36, 0x0a, 0x19, 0x07, 0xa1, 0x58, 0xa1, 0x14, + 0x1f, 0x81, 0xe4, 0xb4, 0x53, 0x77, 0x99, 0x78, 0x31, 0xdb, 0x14, 0x15, 0x4a, 0x38, 0x06, 0x78, + 0xb9, 0x57, 0xb8, 0x3a, 0x9a, 0x29, 0xde, 0xa4, 0xd5, 0x0a, 0xb7, 0x54, 0x7f, 0x5b, 0x7b, 0x3d, + 0xdb, 0xa3, 0x73, 0xbe, 0x55, 0x2e, 0x2d, 0x4d, 0x41, 0x27, 0xca, 0xe9, 0x02, 0x52, 0xb2, 0xbd, + 0x47, 0x33, 0x19, 0xa9, 0x76, 0x83, 0x5e, 0x27, 0xfc, 0x14, 0x54, 0xbc, 0x57, 0x20, 0xec, 0x57, + 0x0e, 0xc8, 0x35, 0x08, 0x6f, 0x11, 0x04, 0x9d, 0x7d, 0x4f, 0x99, 0xf5, 0xfc, 0x2c, 0xef, 0x59, + 0xe3, 0xe0, 0x39, 0x48, 0xc5, 0xaa, 0x1b, 0x11, 0x4e, 0x26, 0x55, 0x8d, 0xe4, 0xfc, 0x4f, 0xf4, + 0x46, 0x34, 0xc7, 0x40, 0xae, 0x79, 0x79, 0x45, 0x94, 0x05, 0x71, 0x21, 0x9c, 0xa2, 0x09, 0x71, + 0x2b, 0xb4, 0x80, 0xa7, 0xb0, 0x1c, 0xc2, 0x8a, 0x38, 0x4b, 0x2b, 0x78, 0x28, 0xee, 0x9a, 0xc6, + 0x55, 0x92, 0x79, 0xe1, 0x65, 0x5e, 0x8d, 0x9c, 0x58, 0x37, 0x2c, 0xd4, 0x6a, 0x35, 0x2d, 0xe4, + 0x63, 0xf3, 0x94, 0x5a, 0x5a, 0x50, 0x16, 0x08, 0xe0, 0x32, 0xb7, 0xb4, 0xe0, 0x25, 0xfb, 0x40, + 0x81, 0x85, 0x60, 0xd4, 0xcb, 0xc3, 0x89, 0x14, 0xd7, 0xdf, 0xca, 0x66, 0x14, 0x68, 0x61, 0x4c, + 0xf9, 0xa4, 0x72, 0x01, 0x37, 0x64, 0xb1, 0x42, 0x9c, 0x44, 0x3e, 0x7b, 0x28, 0xc9, 0xc3, 0x26, + 0xa2, 0xd5, 0x43, 0xdf, 0xcf, 0x47, 0xde, 0xf3, 0x79, 0x5c, 0x33, 0x22, 0x1e, 0x0b, 0x65, 0x36, + 0x6f, 0xb5, 0x5d, 0xe0, 0x7a, 0x6a, 0x21, 0x65, 0xf4, 0x62, 0x5c, 0xa3, 0x2b, 0x42, 0x9f, 0x08, + 0xb7, 0x87, 0xf2, 0x18, 0x85, 0x22, 0x54, 0x0d, 0xb2, 0x14, 0x04, 0xc5, 0xf8, 0xcc, 0x2c, 0xb8, + 0xb3, 0x48, 0x42, 0xa0, 0xdc, 0xa8, 0xe5, 0xa3, 0xff, 0x2c, 0x6e, 0x5e, 0x85, 0x13, 0xca, 0x7a, + 0x28, 0xac, 0x34, 0x6b, 0x5e, 0x16, 0x13, 0x6d, 0xc3, 0x4a, 0xf0, 0xfe, 0x9f, 0xb4, 0x80, 0xc7, + 0xb8, 0x7a, 0xe9, 0xb2, 0x0d, 0x9d, 0x3d, 0x56, 0x70, 0x40, 0xae, 0x85, 0x52, 0x8c, 0x8f, 0x48, + 0x45, 0x43, 0xf2, 0xb1, 0xb9, 0x4f, 0x0a, 0x0d, 0x4b, 0xa4, 0xf0, 0xf4, 0xe6, 0xbf, 0xe0, 0x3b, + 0xae, 0xc8, 0x64, 0xc7, 0x44, 0xb9, 0x77, 0xea, 0xde, 0x35, 0xfb, 0x71, 0x80, 0xef, 0xc1, 0xc7, + 0x33, 0x01, 0x6c, 0x99, 0xb9, 0xd8, 0xb8, 0xae, 0x9b, 0xd7, 0xb8, 0x82, 0xed, 0xcb, 0xb6, 0xdb, + 0x1c, 0x68, 0x4e, 0x81, 0xf4, 0xdc, 0xc5, 0x9a, 0xd7, 0x60, 0x63, 0x1a, 0x93, 0x51, 0x38, 0x84, + 0xc7, 0x8a, 0xb8, 0xcf, 0xcd, 0x2f, 0x1c, 0x9b, 0x31, 0x95, 0x6c, 0xa6, 0xe6, 0xdd, 0xe1, 0x0a, + 0xde, 0x39, 0xb3, 0xc3, 0x67, 0xf7, 0xfb, 0x65, 0x71, 0xc9, 0xf4, 0x39, 0x88, 0x09, 0x94, 0xc0, + 0xf3, 0x39, 0x07, 0x9e, 0xd9, 0xbc, 0xb2, 0x32, 0x7b, 0x7b, 0x30, 0x89, 0x81, 0x04, 0xc6, 0x81, + 0x06, 0x84, 0xb3, 0x7c, 0xb0, 0x85, 0x06, 0xdc, 0xd8, 0x10, 0x09, 0x44, 0x7f, 0x96, 0xa9, 0x64, + 0xae, 0xb1, 0xb6, 0x16, 0x57, 0x78, 0x36, 0x39, 0x86, 0x05, 0x19, 0x99, 0x05, 0x88, 0x40, 0xf2, + 0x90, 0x58, 0xb8, 0x20, 0xc0, 0xbb, 0xd1, 0xf3, 0x6f, 0x60, 0x68, 0x56, 0x9f, 0x32, 0x9f, 0x25, + 0x79, 0x01, 0x04, 0x38, 0x0a, 0x6f, 0x71, 0xaa, 0xee, 0x00, 0x46, 0x6a, 0xee, 0x9b, 0xd2, 0xa0, + 0x49, 0x8c, 0xb4, 0x96, 0x15, 0xab, 0x5e, 0xf0, 0xec, 0xf1, 0x39, 0xcc, 0xd4, 0xcb, 0xdc, 0x8b, + 0x67, 0xc6, 0x66, 0xcb, 0x7e, 0x3f, 0x3e, 0xce, 0xe6, 0x48, 0xa9, 0x75, 0x33, 0xed, 0x2c, 0x12, + 0x3a, 0x55, 0x47, 0x69, 0x57, 0xe7, 0xa8, 0xe4, 0xd2, 0x83, 0x9f, 0xe5, 0xcc, 0xc3, 0x3d, 0x2c, + 0x81, 0xa6, 0x9a, 0x5b, 0xf3, 0x67, 0x93, 0xa9, 0xcc, 0x0c, 0x7f, 0xa9, 0xf6, 0x1c, 0x68, 0xed, + 0x1c, 0xb1, 0x0a, 0xe6, 0x59, 0x4b, 0xfa, 0x39, 0x83, 0xb2, 0x75, 0x10, 0x37, 0x9c, 0xff, 0xf1, + 0x7e, 0xa0, 0x3a, 0xf4, 0x53, 0xb6, 0xcb, 0xab, 0x6a, 0x84, 0xc9, 0xe6, 0x81, 0xf8, 0x05, 0x23, + 0x3f, 0xd2, 0xe0, 0x35, 0xc4, 0x6d, 0xcc, 0xda, 0xd0, 0x0c, 0x60, 0x2a, 0x62, 0x99, 0x4f, 0xaf, + 0xc6, 0x21, 0x35, 0xd0, 0xe7, 0x94, 0x95, 0x2d, 0x5e, 0xea, 0xe5, 0x0a, 0x3c, 0x07, 0xdd, 0x25, + 0xac, 0xbc, 0x30, 0xf6, 0x10, 0xfe, 0x07, 0xd5, 0x03, 0xcc, 0x66, 0x29, 0x4e, 0x94, 0x42, 0x6d, + 0xfb, 0xa6, 0xb4, 0x46, 0x11, 0x0d, 0xb0, 0x3d, 0x57, 0xc4, 0x74, 0x2c, 0xa7, 0xe2, 0x96, 0xea, + 0x57, 0x39, 0x3e, 0xac, 0xea, 0x3f, 0x87, 0x5a, 0xf7, 0x4d, 0xe3, 0x84, 0x87, 0x92, 0x87, 0x7d, + 0x05, 0x72, 0x8c, 0x42, 0xe7, 0x27, 0xd5, 0xf7, 0x63, 0xbf, 0x82, 0xc1, 0x5c, 0xd8, 0x71, 0x16, + 0x15, 0x6b, 0x29, 0x5b, 0xaa, 0xbb, 0xb3, 0x08, 0x2a, 0x95, 0x93, 0x9a, 0x4c, 0x2b, 0xcd, 0x11, + 0x14, 0x44, 0x70, 0x81, 0x9b, 0x92, 0x7d, 0x48, 0x42, 0x4f, 0xe1, 0x35, 0x4e, 0xef, 0x65, 0xf9, + 0x0b, 0xe3, 0x5e, 0x2d, 0x1d, 0x87, 0x3d, 0x9f, 0x8b, 0x5d, 0x53, 0x08, 0x12, 0xb0, 0x14, 0xb2, + 0x26, 0x0b, 0x13, 0xa7, 0xb1, 0xd6, 0x03, 0x01, 0xeb, 0x27, 0x80, 0xd3, 0xd1, 0xc2, 0x7a, 0xe5, + 0xcb, 0xef, 0x26, 0xd3, 0x28, 0x10, 0x7e, 0x54, 0xa2, 0x88, 0xbe, 0x0c, 0x62, 0x07, 0x56, 0x4a, + 0xd4, 0x17, 0x8e, 0x76, 0x9c, 0xe4, 0xaa, 0x71, 0xe9, 0x6a, 0x9d, 0x49, 0x54, 0x97, 0x55, 0xfb, + 0x42, 0x72, 0xd5, 0x7c, 0x08, 0x8e, 0x1c, 0x3d, 0xa3, 0x42, 0x90, 0xc4, 0xcf, 0x69, 0x5f, 0x49, + 0xaa, 0x97, 0xdb, 0xf6, 0x94, 0x84, 0xc5, 0x99, 0xb8, 0x9c, 0x69, 0xfe, 0x85, 0x79, 0x54, 0x26, + 0x34, 0xef, 0x8b, 0x34, 0x3c, 0x30, 0x80, 0x07, 0x33, 0x9c, 0x67, 0xc8, 0xd3, 0xf1, 0xc0, 0xf8, + 0x14, 0x06, 0xa0, 0x12, 0xfd, 0x63, 0x82, 0x75, 0x11, 0xc6, 0x06, 0xb3, 0xb8, 0x7a, 0x65, 0x89, + 0xf4, 0x62, 0xdc, 0x24, 0xc2, 0x55, 0xb3, 0xbb, 0x79, 0x31, 0xdf, 0x5b, 0xa5, 0x96, 0x40, 0xd4, + 0x5d, 0xa2, 0x6a, 0x40, 0xb1, 0xc6, 0xd1, 0x28, 0xd6, 0x05, 0x25, 0x6e, 0x05, 0xf3, 0xcb, 0xbc, + 0x79, 0x78, 0x64, 0xda, 0x76, 0x4b, 0x63, 0x83, 0x35, 0xe1, 0xdf, 0x18, 0xe2, 0xea, 0x5c, 0xe1, + 0x9a, 0xfd, 0x8f, 0x7f, 0xfb, 0xdf, 0xed, 0x56, 0x91, 0x19, 0x5e, 0xac, 0x00, 0x80, 0xa6, 0x93, + 0x57, 0xae, 0xdb, 0x04, 0x7e, 0xef, 0xdd, 0xe6, 0xe3, 0x63, 0xb2, 0xdd, 0xeb, 0x58, 0x5a, 0x1f, + 0x47, 0x52, 0xa2, 0x28, 0x7b, 0x60, 0x06, 0x7d, 0x20, 0x75, 0xde, 0xfc, 0xc7, 0xbf, 0xfd, 0xef, + 0x5e, 0x67, 0x59, 0x57, 0xda, 0x9c, 0x65, 0x77, 0xfa, 0x40, 0xbc, 0x5b, 0xbc, 0x10, 0x0b, 0x4d, + 0x13, 0x93, 0xfb, 0x64, 0x66, 0xba, 0x26, 0xa6, 0xbf, 0xc1, 0x48, 0x36, 0xea, 0x80, 0x3d, 0xe6, + 0x43, 0x62, 0x66, 0x6e, 0x9f, 0x8c, 0xbc, 0xd5, 0x34, 0xbf, 0xd0, 0x41, 0xd0, 0xe0, 0xc2, 0x64, + 0xa0, 0xe4, 0xb9, 0x30, 0x34, 0x8c, 0xaf, 0x1b, 0x15, 0x78, 0x2b, 0x3b, 0xee, 0x50, 0x4d, 0xb6, + 0x80, 0x29, 0x94, 0x27, 0xd5, 0x78, 0x6c, 0xe1, 0x44, 0x24, 0x1a, 0xab, 0x50, 0x8d, 0x3d, 0x01, + 0x53, 0x87, 0x43, 0xd3, 0xe7, 0x14, 0x1d, 0x5c, 0x40, 0x6c, 0x1d, 0xa4, 0x72, 0x20, 0xa7, 0x11, + 0x18, 0xd4, 0x40, 0x28, 0xcc, 0x25, 0xb7, 0xb5, 0x3b, 0x88, 0x43, 0xae, 0xc4, 0xbd, 0x16, 0xd3, + 0xba, 0x2c, 0xd3, 0xcc, 0x2d, 0x00, 0xb6, 0x37, 0x31, 0xe6, 0x16, 0x02, 0x5d, 0x1d, 0x03, 0xad, + 0x37, 0xe1, 0x50, 0x3d, 0x91, 0xfd, 0x0a, 0xe1, 0xf8, 0x1f, 0x01, 0xab, 0x8c, 0xab, 0x92, 0xcd, + 0xa2, 0x1a, 0xaa, 0x4b, 0x47, 0x0d, 0x0e, 0x85, 0xfc, 0x86, 0xa8, 0x96, 0x9c, 0x2e, 0xc7, 0x58, + 0xec, 0xad, 0x96, 0xb2, 0x4c, 0xf5, 0xf1, 0xf1, 0x95, 0x02, 0xf8, 0x2e, 0xb4, 0xcb, 0x55, 0xa7, + 0xd1, 0x43, 0x4d, 0x70, 0x49, 0x92, 0x38, 0x15, 0xdd, 0x31, 0x7d, 0x0d, 0x63, 0x0e, 0x81, 0xce, + 0x1f, 0xc0, 0x6d, 0x30, 0x5b, 0x16, 0x85, 0x6c, 0x47, 0x8f, 0x42, 0xa6, 0xc5, 0x3a, 0x3b, 0x3b, + 0x97, 0x0c, 0x84, 0xd8, 0xb6, 0xc5, 0x7e, 0xd8, 0x24, 0x79, 0x6c, 0x58, 0xab, 0xbf, 0xf0, 0x45, + 0x98, 0x14, 0xb3, 0x18, 0xf6, 0x6c, 0x8a, 0x65, 0x1b, 0xae, 0x09, 0xf3, 0x56, 0x54, 0x54, 0x63, + 0xb9, 0xfa, 0x6d, 0x48, 0xc2, 0xab, 0x10, 0x8c, 0x1d, 0x25, 0x35, 0xc7, 0xe5, 0x07, 0x85, 0xc0, + 0x11, 0x20, 0x64, 0x54, 0x17, 0x2c, 0xe3, 0x4f, 0xb2, 0x1d, 0x5b, 0xed, 0x2d, 0x9a, 0x79, 0xc7, + 0x16, 0x19, 0xc8, 0x8f, 0x49, 0x8a, 0xaf, 0x99, 0x69, 0xd6, 0x42, 0x56, 0x6f, 0xf1, 0x74, 0x27, + 0xde, 0x35, 0x1e, 0xc1, 0x55, 0x80, 0x38, 0x99, 0xa2, 0xbd, 0x55, 0xb0, 0xa2, 0x16, 0x61, 0x37, + 0x87, 0x40, 0xe5, 0x20, 0xb8, 0x27, 0x6c, 0x2a, 0xe0, 0x6b, 0xad, 0x1e, 0x6f, 0xa8, 0xe0, 0xc9, + 0xff, 0x28, 0x85, 0x30, 0xb7, 0xfa, 0x2c, 0x7e, 0x68, 0x1f, 0x16, 0xb9, 0x5f, 0x7a, 0xe9, 0xa2, + 0xd2, 0xad, 0x14, 0xad, 0x06, 0xfb, 0x4d, 0x89, 0x2d, 0x44, 0x6d, 0x08, 0x33, 0x56, 0x3d, 0xcc, + 0x42, 0x90, 0xd2, 0x27, 0x09, 0x43, 0xb2, 0x79, 0x31, 0xd5, 0x65, 0xe1, 0xed, 0x81, 0xec, 0xd0, + 0x5a, 0xfd, 0xb9, 0x65, 0x5a, 0xfd, 0x77, 0x6f, 0x89, 0x9f, 0x86, 0x13, 0xba, 0xfd, 0x3f, 0xde, + 0xbd, 0x05, 0x07, 0x6f, 0xf8, 0x77, 0x44, 0xc7, 0xd1, 0xf6, 0xff, 0xf8, 0xff, 0x01, 0x4c, 0x86, + 0x3d, 0xf2, 0x2e, 0x47, 0x02, 0x00, +}; +const size_t RCC6_WEB_UI_INDEX_GZ_LEN = sizeof(RCC6_WEB_UI_INDEX_GZ); +#endif diff --git a/examples/companion_radio/webui/THIRD_PARTY_NOTICES.md b/examples/companion_radio/webui/THIRD_PARTY_NOTICES.md new file mode 100644 index 00000000..4a98c13e --- /dev/null +++ b/examples/companion_radio/webui/THIRD_PARTY_NOTICES.md @@ -0,0 +1,13 @@ +# Third-party notices + +The compiled WebUI bundles [MeshCore.js](https://github.com/meshcore-dev/meshcore.js) 1.14.0. + +MIT License + +Copyright (c) 2025-2026 Liam Cottle + +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. diff --git a/examples/companion_radio/webui/build.mjs b/examples/companion_radio/webui/build.mjs new file mode 100644 index 00000000..54c425a0 --- /dev/null +++ b/examples/companion_radio/webui/build.mjs @@ -0,0 +1,58 @@ +import { build, transform } from "esbuild"; +import { createHash } from "node:crypto"; +import { gzipSync, gunzipSync } from "node:zlib"; +import { mkdir, readFile, writeFile } from "node:fs/promises"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; + +const root = path.dirname(fileURLToPath(import.meta.url)); +const source = path.join(root, "src"); +const output = path.join(root, ".build"); +const packageJson = JSON.parse(await readFile(path.join(root, "package.json"), "utf8")); + +const jsResult = await build({ + entryPoints: [path.join(source, "app.js")], + bundle: true, + write: false, + format: "iife", + platform: "browser", + target: ["safari15", "chrome100", "firefox100"], + minify: true, + charset: "utf8", + legalComments: "none", + define: { + __APP_VERSION__: JSON.stringify(packageJson.version), + __MESHCORE_JS_VERSION__: JSON.stringify(packageJson.dependencies["@liamcottle/meshcore.js"]), + }, +}); +const cssResult = await transform(await readFile(path.join(source, "styles.css"), "utf8"), { + loader: "css", + minify: true, +}); + +const template = await readFile(path.join(source, "index.html"), "utf8"); +const html = template + .replace("/*__RCC6_CSS__*/", cssResult.code.trim()) + .replace("/*__RCC6_JS__*/", jsResult.outputFiles[0].text.trim()); + +if (html.includes("/*__RCC6_")) throw new Error("Unreplaced WebUI build token"); +if (/]*src=|]*rel=[\"']stylesheet/i.test(html)) { + throw new Error("Runtime network asset reference detected"); +} + +const gzip = gzipSync(Buffer.from(html), { level: 9, mtime: 0 }); +gzip[9] = 0xff; // RFC 1952 OS=unknown keeps the asset identical across build hosts. +if (gunzipSync(gzip).toString("utf8") !== html) throw new Error("Gzip round-trip failed"); +const digest = createHash("sha256").update(gzip).digest("hex"); +const rows = []; +for (let offset = 0; offset < gzip.length; offset += 16) { + rows.push(` ${[...gzip.subarray(offset, offset + 16)].map((byte) => `0x${byte.toString(16).padStart(2, "0")}`).join(", ")},`); +} + +const header = `// Generated by examples/companion_radio/webui/build.mjs. Do not edit.\n// gzip sha256: ${digest}\n#pragma once\n#include \n\nextern const uint8_t RCC6_WEB_UI_INDEX_GZ[] PROGMEM;\nextern const size_t RCC6_WEB_UI_INDEX_GZ_LEN;\n\n#ifdef RCC6_WEB_UI_ASSETS_IMPLEMENTATION\nconst uint8_t RCC6_WEB_UI_INDEX_GZ[] PROGMEM = {\n${rows.join("\n")}\n};\nconst size_t RCC6_WEB_UI_INDEX_GZ_LEN = sizeof(RCC6_WEB_UI_INDEX_GZ);\n#endif\n`; + +await mkdir(output, { recursive: true }); +await writeFile(path.join(output, "index.html"), html); +await writeFile(path.join(output, "index.html.gz"), gzip); +await writeFile(path.join(root, "Rcc6WebUiAssets.h"), header); +console.log(`RCC6 WebUI: ${Buffer.byteLength(html)} bytes HTML, ${gzip.length} bytes gzip, sha256 ${digest}`); diff --git a/examples/companion_radio/webui/package-lock.json b/examples/companion_radio/webui/package-lock.json new file mode 100644 index 00000000..361a7676 --- /dev/null +++ b/examples/companion_radio/webui/package-lock.json @@ -0,0 +1,815 @@ +{ + "name": "rcc6-meshcore-webui", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "rcc6-meshcore-webui", + "version": "1.0.0", + "dependencies": { + "@liamcottle/meshcore.js": "1.14.0" + }, + "devDependencies": { + "esbuild": "0.27.2" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.2.tgz", + "integrity": "sha512-GZMB+a0mOMZs4MpDbj8RJp4cw+w1WV5NYD6xzgvzUJ5Ek2jerwfO2eADyI6ExDSUED+1X8aMbegahsJi+8mgpw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.2.tgz", + "integrity": "sha512-DVNI8jlPa7Ujbr1yjU2PfUSRtAUZPG9I1RwW4F4xFB1Imiu2on0ADiI/c3td+KmDtVKNbi+nffGDQMfcIMkwIA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.2.tgz", + "integrity": "sha512-pvz8ZZ7ot/RBphf8fv60ljmaoydPU12VuXHImtAs0XhLLw+EXBi2BLe3OYSBslR4rryHvweW5gmkKFwTiFy6KA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.2.tgz", + "integrity": "sha512-z8Ank4Byh4TJJOh4wpz8g2vDy75zFL0TlZlkUkEwYXuPSgX8yzep596n6mT7905kA9uHZsf/o2OJZubl2l3M7A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.2.tgz", + "integrity": "sha512-davCD2Zc80nzDVRwXTcQP/28fiJbcOwvdolL0sOiOsbwBa72kegmVU0Wrh1MYrbuCL98Omp5dVhQFWRKR2ZAlg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.2.tgz", + "integrity": "sha512-ZxtijOmlQCBWGwbVmwOF/UCzuGIbUkqB1faQRf5akQmxRJ1ujusWsb3CVfk/9iZKr2L5SMU5wPBi1UWbvL+VQA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.2.tgz", + "integrity": "sha512-lS/9CN+rgqQ9czogxlMcBMGd+l8Q3Nj1MFQwBZJyoEKI50XGxwuzznYdwcav6lpOGv5BqaZXqvBSiB/kJ5op+g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.2.tgz", + "integrity": "sha512-tAfqtNYb4YgPnJlEFu4c212HYjQWSO/w/h/lQaBK7RbwGIkBOuNKQI9tqWzx7Wtp7bTPaGC6MJvWI608P3wXYA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.2.tgz", + "integrity": "sha512-vWfq4GaIMP9AIe4yj1ZUW18RDhx6EPQKjwe7n8BbIecFtCQG4CfHGaHuh7fdfq+y3LIA2vGS/o9ZBGVxIDi9hw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.2.tgz", + "integrity": "sha512-hYxN8pr66NsCCiRFkHUAsxylNOcAQaxSSkHMMjcpx0si13t1LHFphxJZUiGwojB1a/Hd5OiPIqDdXONia6bhTw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.2.tgz", + "integrity": "sha512-MJt5BRRSScPDwG2hLelYhAAKh9imjHK5+NE/tvnRLbIqUWa+0E9N4WNMjmp/kXXPHZGqPLxggwVhz7QP8CTR8w==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.2.tgz", + "integrity": "sha512-lugyF1atnAT463aO6KPshVCJK5NgRnU4yb3FUumyVz+cGvZbontBgzeGFO1nF+dPueHD367a2ZXe1NtUkAjOtg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.2.tgz", + "integrity": "sha512-nlP2I6ArEBewvJ2gjrrkESEZkB5mIoaTswuqNFRv/WYd+ATtUpe9Y09RnJvgvdag7he0OWgEZWhviS1OTOKixw==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.2.tgz", + "integrity": "sha512-C92gnpey7tUQONqg1n6dKVbx3vphKtTHJaNG2Ok9lGwbZil6DrfyecMsp9CrmXGQJmZ7iiVXvvZH6Ml5hL6XdQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.2.tgz", + "integrity": "sha512-B5BOmojNtUyN8AXlK0QJyvjEZkWwy/FKvakkTDCziX95AowLZKR6aCDhG7LeF7uMCXEJqwa8Bejz5LTPYm8AvA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.2.tgz", + "integrity": "sha512-p4bm9+wsPwup5Z8f4EpfN63qNagQ47Ua2znaqGH6bqLlmJ4bx97Y9JdqxgGZ6Y8xVTixUnEkoKSHcpRlDnNr5w==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.2.tgz", + "integrity": "sha512-uwp2Tip5aPmH+NRUwTcfLb+W32WXjpFejTIOWZFw/v7/KnpCDKG66u4DLcurQpiYTiYwQ9B7KOeMJvLCu/OvbA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.2.tgz", + "integrity": "sha512-Kj6DiBlwXrPsCRDeRvGAUb/LNrBASrfqAIok+xB0LxK8CHqxZ037viF13ugfsIpePH93mX7xfJp97cyDuTZ3cw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.2.tgz", + "integrity": "sha512-HwGDZ0VLVBY3Y+Nw0JexZy9o/nUAWq9MlV7cahpaXKW6TOzfVno3y3/M8Ga8u8Yr7GldLOov27xiCnqRZf0tCA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.2.tgz", + "integrity": "sha512-DNIHH2BPQ5551A7oSHD0CKbwIA/Ox7+78/AWkbS5QoRzaqlev2uFayfSxq68EkonB+IKjiuxBFoV8ESJy8bOHA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.2.tgz", + "integrity": "sha512-/it7w9Nb7+0KFIzjalNJVR5bOzA9Vay+yIPLVHfIQYG/j+j9VTH84aNB8ExGKPU4AzfaEvN9/V4HV+F+vo8OEg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.2.tgz", + "integrity": "sha512-LRBbCmiU51IXfeXk59csuX/aSaToeG7w48nMwA6049Y4J4+VbWALAuXcs+qcD04rHDuSCSRKdmY63sruDS5qag==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.2.tgz", + "integrity": "sha512-kMtx1yqJHTmqaqHPAzKCAkDaKsffmXkPHThSfRwZGyuqyIeBvf08KSsYXl+abf5HDAPMJIPnbBfXvP2ZC2TfHg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.2.tgz", + "integrity": "sha512-Yaf78O/B3Kkh+nKABUF++bvJv5Ijoy9AN1ww904rOXZFLWVc5OLOfL56W+C8F9xn5JQZa3UX6m+IktJnIb1Jjg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.2.tgz", + "integrity": "sha512-Iuws0kxo4yusk7sw70Xa2E2imZU5HoixzxfGCdxwBdhiDgt9vX9VUCBhqcwY7/uh//78A1hMkkROMJq9l27oLQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.2.tgz", + "integrity": "sha512-sRdU18mcKf7F+YgheI/zGf5alZatMUTKj/jNS6l744f9u3WFu4v7twcUI9vu4mknF4Y9aDlblIie0IM+5xxaqQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@liamcottle/meshcore.js": { + "version": "1.14.0", + "resolved": "https://registry.npmjs.org/@liamcottle/meshcore.js/-/meshcore.js-1.14.0.tgz", + "integrity": "sha512-WOJppqrFMXN8gx+by0M6OAD5x4smus49C+ro61735TsyEM8vLhnv6ZIDDB8Y/9m/B7QUrHgdVBHM+chz+wH2Yw==", + "license": "MIT", + "dependencies": { + "@noble/curves": "^1.9.7", + "serialport": "^13.0.0" + } + }, + "node_modules/@noble/curves": { + "version": "1.9.7", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.9.7.tgz", + "integrity": "sha512-gbKGcRUYIjA3/zCCNaWDciTMFI0dCkvou3TL8Zmy5Nc7sJ47a0jtOeZoTaMxkuqRo9cRhjOdZJXegxYE5FN/xw==", + "license": "MIT", + "dependencies": { + "@noble/hashes": "1.8.0" + }, + "engines": { + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@noble/hashes": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz", + "integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==", + "license": "MIT", + "engines": { + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@serialport/binding-mock": { + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/@serialport/binding-mock/-/binding-mock-10.2.2.tgz", + "integrity": "sha512-HAFzGhk9OuFMpuor7aT5G1ChPgn5qSsklTFOTUX72Rl6p0xwcSVsRtG/xaGp6bxpN7fI9D/S8THLBWbBgS6ldw==", + "license": "MIT", + "dependencies": { + "@serialport/bindings-interface": "^1.2.1", + "debug": "^4.3.3" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@serialport/bindings-cpp": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/@serialport/bindings-cpp/-/bindings-cpp-13.0.0.tgz", + "integrity": "sha512-r25o4Bk/vaO1LyUfY/ulR6hCg/aWiN6Wo2ljVlb4Pj5bqWGcSRC4Vse4a9AcapuAu/FeBzHCbKMvRQeCuKjzIQ==", + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "@serialport/bindings-interface": "1.2.2", + "@serialport/parser-readline": "12.0.0", + "debug": "4.4.0", + "node-addon-api": "8.3.0", + "node-gyp-build": "4.8.4" + }, + "engines": { + "node": ">=18.0.0" + }, + "funding": { + "url": "https://opencollective.com/serialport/donate" + } + }, + "node_modules/@serialport/bindings-cpp/node_modules/@serialport/parser-delimiter": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/@serialport/parser-delimiter/-/parser-delimiter-12.0.0.tgz", + "integrity": "sha512-gu26tVt5lQoybhorLTPsH2j2LnX3AOP2x/34+DUSTNaUTzu2fBXw+isVjQJpUBFWu6aeQRZw5bJol5X9Gxjblw==", + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://opencollective.com/serialport/donate" + } + }, + "node_modules/@serialport/bindings-cpp/node_modules/@serialport/parser-readline": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/@serialport/parser-readline/-/parser-readline-12.0.0.tgz", + "integrity": "sha512-O7cywCWC8PiOMvo/gglEBfAkLjp/SENEML46BXDykfKP5mTPM46XMaX1L0waWU6DXJpBgjaL7+yX6VriVPbN4w==", + "license": "MIT", + "dependencies": { + "@serialport/parser-delimiter": "12.0.0" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://opencollective.com/serialport/donate" + } + }, + "node_modules/@serialport/bindings-interface": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@serialport/bindings-interface/-/bindings-interface-1.2.2.tgz", + "integrity": "sha512-CJaUd5bLvtM9c5dmO9rPBHPXTa9R2UwpkJ0wdh9JCYcbrPWsKz+ErvR0hBLeo7NPeiFdjFO4sonRljiw4d2XiA==", + "license": "MIT", + "engines": { + "node": "^12.22 || ^14.13 || >=16" + } + }, + "node_modules/@serialport/parser-byte-length": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/@serialport/parser-byte-length/-/parser-byte-length-13.0.0.tgz", + "integrity": "sha512-32yvqeTAqJzAEtX5zCrN1Mej56GJ5h/cVFsCDPbF9S1ZSC9FWjOqNAgtByseHfFTSTs/4ZBQZZcZBpolt8sUng==", + "license": "MIT", + "engines": { + "node": ">=20.0.0" + }, + "funding": { + "url": "https://opencollective.com/serialport/donate" + } + }, + "node_modules/@serialport/parser-cctalk": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/@serialport/parser-cctalk/-/parser-cctalk-13.0.0.tgz", + "integrity": "sha512-RErAe57g9gvnlieVYGIn1xymb1bzNXb2QtUQd14FpmbQQYlcrmuRnJwKa1BgTCujoCkhtaTtgHlbBWOxm8U2uA==", + "license": "MIT", + "engines": { + "node": ">=20.0.0" + }, + "funding": { + "url": "https://opencollective.com/serialport/donate" + } + }, + "node_modules/@serialport/parser-delimiter": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/@serialport/parser-delimiter/-/parser-delimiter-13.0.0.tgz", + "integrity": "sha512-Qqyb0FX1avs3XabQqNaZSivyVbl/yl0jywImp7ePvfZKLwx7jBZjvL+Hawt9wIG6tfq6zbFM24vzCCK7REMUig==", + "license": "MIT", + "engines": { + "node": ">=20.0.0" + }, + "funding": { + "url": "https://opencollective.com/serialport/donate" + } + }, + "node_modules/@serialport/parser-inter-byte-timeout": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/@serialport/parser-inter-byte-timeout/-/parser-inter-byte-timeout-13.0.0.tgz", + "integrity": "sha512-a0w0WecTW7bD2YHWrpTz1uyiWA2fDNym0kjmPeNSwZ2XCP+JbirZt31l43m2ey6qXItTYVuQBthm75sPVeHnGA==", + "license": "MIT", + "engines": { + "node": ">=20.0.0" + }, + "funding": { + "url": "https://opencollective.com/serialport/donate" + } + }, + "node_modules/@serialport/parser-packet-length": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/@serialport/parser-packet-length/-/parser-packet-length-13.0.0.tgz", + "integrity": "sha512-60ZDDIqYRi0Xs2SPZUo4Jr5LLIjtb+rvzPKMJCohrO6tAqSDponcNpcB1O4W21mKTxYjqInSz+eMrtk0LLfZIg==", + "license": "MIT", + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/@serialport/parser-readline": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/@serialport/parser-readline/-/parser-readline-13.0.0.tgz", + "integrity": "sha512-dov3zYoyf0dt1Sudd1q42VVYQ4WlliF0MYvAMA3MOyiU1IeG4hl0J6buBA2w4gl3DOCC05tGgLDN/3yIL81gsA==", + "license": "MIT", + "dependencies": { + "@serialport/parser-delimiter": "13.0.0" + }, + "engines": { + "node": ">=20.0.0" + }, + "funding": { + "url": "https://opencollective.com/serialport/donate" + } + }, + "node_modules/@serialport/parser-ready": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/@serialport/parser-ready/-/parser-ready-13.0.0.tgz", + "integrity": "sha512-JNUQA+y2Rfs4bU+cGYNqOPnNMAcayhhW+XJZihSLQXOHcZsFnOa2F9YtMg9VXRWIcnHldHYtisp62Etjlw24bw==", + "license": "MIT", + "engines": { + "node": ">=20.0.0" + }, + "funding": { + "url": "https://opencollective.com/serialport/donate" + } + }, + "node_modules/@serialport/parser-regex": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/@serialport/parser-regex/-/parser-regex-13.0.0.tgz", + "integrity": "sha512-m7HpIf56G5XcuDdA3DB34Z0pJiwxNRakThEHjSa4mG05OnWYv0IG8l2oUyYfuGMowQWaVnQ+8r+brlPxGVH+eA==", + "license": "MIT", + "engines": { + "node": ">=20.0.0" + }, + "funding": { + "url": "https://opencollective.com/serialport/donate" + } + }, + "node_modules/@serialport/parser-slip-encoder": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/@serialport/parser-slip-encoder/-/parser-slip-encoder-13.0.0.tgz", + "integrity": "sha512-fUHZEExm6izJ7rg0A1yjXwu4sOzeBkPAjDZPfb+XQoqgtKAk+s+HfICiYn7N2QU9gyaeCO8VKgWwi+b/DowYOg==", + "license": "MIT", + "engines": { + "node": ">=20.0.0" + }, + "funding": { + "url": "https://opencollective.com/serialport/donate" + } + }, + "node_modules/@serialport/parser-spacepacket": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/@serialport/parser-spacepacket/-/parser-spacepacket-13.0.0.tgz", + "integrity": "sha512-DoXJ3mFYmyD8X/8931agJvrBPxqTaYDsPoly9/cwQSeh/q4EjQND9ySXBxpWz5WcpyCU4jOuusqCSAPsbB30Eg==", + "license": "MIT", + "engines": { + "node": ">=20.0.0" + }, + "funding": { + "url": "https://opencollective.com/serialport/donate" + } + }, + "node_modules/@serialport/stream": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/@serialport/stream/-/stream-13.0.0.tgz", + "integrity": "sha512-F7xLJKsjGo2WuEWMSEO1SimRcOA+WtWICsY13r0ahx8s2SecPQH06338g28OT7cW7uRXI7oEQAk62qh5gHJW3g==", + "license": "MIT", + "dependencies": { + "@serialport/bindings-interface": "1.2.2", + "debug": "4.4.0" + }, + "engines": { + "node": ">=20.0.0" + }, + "funding": { + "url": "https://opencollective.com/serialport/donate" + } + }, + "node_modules/debug": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/esbuild": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.2.tgz", + "integrity": "sha512-HyNQImnsOC7X9PMNaCIeAm4ISCQXs5a5YasTXVliKv4uuBo1dKrG0A+uQS8M5eXjVMnLg3WgXaKvprHlFJQffw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.27.2", + "@esbuild/android-arm": "0.27.2", + "@esbuild/android-arm64": "0.27.2", + "@esbuild/android-x64": "0.27.2", + "@esbuild/darwin-arm64": "0.27.2", + "@esbuild/darwin-x64": "0.27.2", + "@esbuild/freebsd-arm64": "0.27.2", + "@esbuild/freebsd-x64": "0.27.2", + "@esbuild/linux-arm": "0.27.2", + "@esbuild/linux-arm64": "0.27.2", + "@esbuild/linux-ia32": "0.27.2", + "@esbuild/linux-loong64": "0.27.2", + "@esbuild/linux-mips64el": "0.27.2", + "@esbuild/linux-ppc64": "0.27.2", + "@esbuild/linux-riscv64": "0.27.2", + "@esbuild/linux-s390x": "0.27.2", + "@esbuild/linux-x64": "0.27.2", + "@esbuild/netbsd-arm64": "0.27.2", + "@esbuild/netbsd-x64": "0.27.2", + "@esbuild/openbsd-arm64": "0.27.2", + "@esbuild/openbsd-x64": "0.27.2", + "@esbuild/openharmony-arm64": "0.27.2", + "@esbuild/sunos-x64": "0.27.2", + "@esbuild/win32-arm64": "0.27.2", + "@esbuild/win32-ia32": "0.27.2", + "@esbuild/win32-x64": "0.27.2" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/node-addon-api": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-8.3.0.tgz", + "integrity": "sha512-8VOpLHFrOQlAH+qA0ZzuGRlALRA6/LVh8QJldbrC4DY0hXoMP0l4Acq8TzFC018HztWiRqyCEj2aTWY2UvnJUg==", + "license": "MIT", + "engines": { + "node": "^18 || ^20 || >= 21" + } + }, + "node_modules/node-gyp-build": { + "version": "4.8.4", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.4.tgz", + "integrity": "sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==", + "license": "MIT", + "bin": { + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" + } + }, + "node_modules/serialport": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/serialport/-/serialport-13.0.0.tgz", + "integrity": "sha512-PHpnTd8isMGPfFTZNCzOZp9m4mAJSNWle9Jxu6BPTcWq7YXl5qN7tp8Sgn0h+WIGcD6JFz5QDgixC2s4VW7vzg==", + "license": "MIT", + "dependencies": { + "@serialport/binding-mock": "10.2.2", + "@serialport/bindings-cpp": "13.0.0", + "@serialport/parser-byte-length": "13.0.0", + "@serialport/parser-cctalk": "13.0.0", + "@serialport/parser-delimiter": "13.0.0", + "@serialport/parser-inter-byte-timeout": "13.0.0", + "@serialport/parser-packet-length": "13.0.0", + "@serialport/parser-readline": "13.0.0", + "@serialport/parser-ready": "13.0.0", + "@serialport/parser-regex": "13.0.0", + "@serialport/parser-slip-encoder": "13.0.0", + "@serialport/parser-spacepacket": "13.0.0", + "@serialport/stream": "13.0.0", + "debug": "4.4.0" + }, + "engines": { + "node": ">=20.0.0" + }, + "funding": { + "url": "https://opencollective.com/serialport/donate" + } + } + } +} diff --git a/examples/companion_radio/webui/package.json b/examples/companion_radio/webui/package.json new file mode 100644 index 00000000..639e967c --- /dev/null +++ b/examples/companion_radio/webui/package.json @@ -0,0 +1,16 @@ +{ + "name": "rcc6-meshcore-webui", + "version": "1.0.0", + "private": true, + "type": "module", + "scripts": { + "build": "node build.mjs", + "test": "node build.mjs && node verify.mjs" + }, + "dependencies": { + "@liamcottle/meshcore.js": "1.14.0" + }, + "devDependencies": { + "esbuild": "0.27.2" + } +} diff --git a/examples/companion_radio/webui/src/app.js b/examples/companion_radio/webui/src/app.js new file mode 100644 index 00000000..5129ba5d --- /dev/null +++ b/examples/companion_radio/webui/src/app.js @@ -0,0 +1,985 @@ +import Connection from "@liamcottle/meshcore.js/src/connection/connection.js"; +import Constants from "@liamcottle/meshcore.js/src/constants.js"; + +const MAX_FRAME_BYTES = 176; +const MAX_MESSAGE_BYTES = 140; +const MAX_HISTORY_MESSAGES = 120; +const POLL_DELAY_MS = 90; +const COMMAND_TIMEOUT_MS = 30000; +const MAX_RECOVERY_ATTEMPTS = 2; +const RADIO_LEASE_KEY = "rcc6-radio-owner"; +const RADIO_LEASE_MS = 7000; +const RADIO_HEARTBEAT_MS = 2000; +const $ = (id) => document.getElementById(id); +const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms)); +const encoder = new TextEncoder(); + +function createSessionId() { + const bytes = new Uint8Array(16); + crypto.getRandomValues(bytes); + return [...bytes].map((value) => value.toString(16).padStart(2, "0")).join(""); +} + +const TAB_OWNER_ID = createSessionId(); + +function loadSessionId() { + try { + const saved = localStorage.getItem("rcc6-session"); + if (/^[0-9a-f]{32}$/.test(saved || "")) return saved; + const created = createSessionId(); + localStorage.setItem("rcc6-session", created); + return created; + } catch { + return createSessionId(); + } +} + +class HttpPollingConnection extends Connection { + constructor() { + super(); + this.running = false; + this.failures = 0; + this.interrupted = false; + this.sessionId = loadSessionId(); + this.lastDispatchedSequence = 0; + this.pendingAck = 0; + this.ready = false; + this.connecting = false; + this.drainTask = null; + this.leaseTimer = null; + this.storageListening = false; + this.onStorage = (event) => { + if (event.key === RADIO_LEASE_KEY && this.running && !this.ownsLease()) this.handleLeaseLoss(); + }; + } + + async connect() { + if (this.running || this.connecting) return; + this.connecting = true; + try { + if (!this.storageListening) { + window.addEventListener("storage", this.onStorage); + this.storageListening = true; + } + if (!await this.claimLease()) { + this.emit("transport-busy"); + return; + } + this.running = true; + this.ready = false; + this.abortController = new AbortController(); + this.drainTask = this.drainRetainedFrames(); + const drained = await this.drainTask; + if (!drained || !this.running || !this.ownsLease()) return; + this.ready = true; + this.pollTask = this.poll(); + this.emit("connected"); + } finally { + this.connecting = false; + } + } + + async close() { + const wasReady = this.ready; + this.running = false; + this.ready = false; + this.abortController?.abort(); + try { await this.drainTask; } catch { /* aborted */ } + try { await this.pollTask; } catch { /* aborted */ } + if (wasReady) this.onDisconnected(); + this.releaseLease(); + if (this.storageListening) window.removeEventListener("storage", this.onStorage); + this.storageListening = false; + } + + readLease() { + try { + const lease = JSON.parse(localStorage.getItem(RADIO_LEASE_KEY) || "null"); + return lease && typeof lease.owner === "string" && Number.isFinite(lease.expires) ? lease : null; + } catch { return null; } + } + + ownsLease() { + const lease = this.readLease(); + return lease?.owner === TAB_OWNER_ID && lease.expires > Date.now(); + } + + writeLease() { + try { + localStorage.setItem(RADIO_LEASE_KEY, JSON.stringify({ owner: TAB_OWNER_ID, expires: Date.now() + RADIO_LEASE_MS })); + return this.ownsLease(); + } catch { return false; } + } + + async claimLease() { + const current = this.readLease(); + if (current && current.owner !== TAB_OWNER_ID && current.expires > Date.now()) return false; + if (!this.writeLease()) return false; + await delay(80); + if (!this.ownsLease()) return false; + this.stopHeartbeat(); + this.leaseTimer = setInterval(() => { + if (!this.ownsLease() || !this.writeLease()) this.handleLeaseLoss(); + }, RADIO_HEARTBEAT_MS); + return true; + } + + stopHeartbeat() { + clearInterval(this.leaseTimer); + this.leaseTimer = null; + } + + handleLeaseLoss() { + this.stopHeartbeat(); + if (!this.running) return; + this.running = false; + this.ready = false; + this.abortController?.abort(); + this.emit("transport-busy"); + } + + releaseLease() { + this.stopHeartbeat(); + try { + if (this.readLease()?.owner === TAB_OWNER_ID) localStorage.removeItem(RADIO_LEASE_KEY); + } catch { /* storage unavailable */ } + } + + leavePage() { + this.running = false; + this.ready = false; + this.abortController?.abort(); + this.releaseLease(); + } + + async sendToRadioFrame(data) { + const frame = data instanceof Uint8Array ? data : new Uint8Array(data); + if (!frame.length || frame.length > MAX_FRAME_BYTES) throw new Error("Invalid companion frame size"); + if (!this.ready) throw new Error("RCC6 companion link is still draining"); + if (!this.ownsLease()) { + this.handleLeaseLoss(); + throw new Error("Another tab owns the RCC6 companion link"); + } + try { + const response = await fetch("/api/frame", { + method: "POST", + headers: { + "Content-Type": "application/octet-stream", + "X-RCC6-Session": this.sessionId, + }, + body: frame, + cache: "no-store", + credentials: "same-origin", + signal: this.abortController.signal, + }); + if (!response.ok) throw new Error(`Frame POST failed (${response.status})`); + this.markHealthy(); + } catch (error) { + if (error.name !== "AbortError") { + error.rcc6TransportFailure = true; + this.markFailure(error); + } + throw error; + } + } + + async fetchFrame() { + const headers = { Accept: "application/octet-stream", "X-RCC6-Session": this.sessionId }; + if (this.pendingAck) headers["X-RCC6-Ack"] = String(this.pendingAck); + const response = await fetch("/api/frame", { headers, cache: "no-store", credentials: "same-origin", signal: this.abortController.signal }); + if (response.status === 204) { + this.pendingAck = 0; + this.markHealthy(); + return false; + } + if (!response.ok) throw new Error(`Frame poll failed (${response.status})`); + const sequence = Number(response.headers.get("X-RCC6-Seq")); + if (!Number.isInteger(sequence) || sequence < 1 || sequence > 0xffffffff) throw new Error("Invalid frame sequence from RCC6"); + const frame = new Uint8Array(await response.arrayBuffer()); + if (!frame.length || frame.length > MAX_FRAME_BYTES) throw new Error("Invalid frame from RCC6"); + if (sequence !== this.lastDispatchedSequence) { + this.onFrameReceived(frame); + this.lastDispatchedSequence = sequence; + // MeshCore.js defers `once` handlers twice; let message persistence finish before ACK. + await delay(0); + await delay(0); + } + this.pendingAck = sequence; + this.markHealthy(); + return true; + } + + async drainRetainedFrames() { + while (this.running) { + if (!this.ownsLease()) { this.handleLeaseLoss(); return false; } + try { + if (!await this.fetchFrame()) return true; + } catch (error) { + if (!this.running || error.name === "AbortError") return false; + this.markFailure(error); + await delay(Math.min(250 * 2 ** Math.min(this.failures, 3), 2000)); + } + } + return false; + } + + async poll() { + while (this.running) { + if (!this.ownsLease()) { this.handleLeaseLoss(); break; } + try { + if (!await this.fetchFrame()) await delay(POLL_DELAY_MS); + } catch (error) { + if (!this.running || error.name === "AbortError") break; + this.markFailure(error); + await delay(Math.min(250 * 2 ** Math.min(this.failures, 3), 2000)); + } + } + } + + markFailure(error) { + this.failures += 1; + if (this.failures >= 3 && !this.interrupted) { + this.interrupted = true; + this.emit("transport-state", "reconnecting", error); + } + } + + markHealthy() { + const restored = this.interrupted; + this.failures = 0; + this.interrupted = false; + if (restored && this.ready) this.emit("transport-restored"); + } +} + +const state = { + connected: false, + linkStatus: "reconnecting", + startedAt: Date.now(), + view: "home", + self: null, + device: null, + battery: 0, + contacts: [], + channels: [], + messages: [], + nearby: [], + selected: "", + radio: null, + packets: null, + rfSamples: [], + network: null, + historyNode: "", +}; + +let connection = new HttpPollingConnection(); +let commandTail = Promise.resolve(); +let syncing = false; +let recovering = false; +let recoveryAttempts = 0; +let unannouncedMessages = 0; + +function exclusive(task) { + const result = commandTail.then(() => { + let timer; + const timeout = new Promise((_, reject) => { + timer = setTimeout(() => { + const error = new Error("Companion command timed out"); + error.rcc6CommandTimeout = true; + reject(error); + }, COMMAND_TIMEOUT_MS); + }); + return Promise.race([Promise.resolve().then(task), timeout]).finally(() => clearTimeout(timer)); + }); + commandTail = result.catch(() => {}); + result.catch((error) => { + if (error?.rcc6CommandTimeout || error?.rcc6TransportFailure) scheduleConnectionRecovery(); + }); + return result; +} + +function scheduleConnectionRecovery() { + if (recovering || recoveryAttempts >= MAX_RECOVERY_ATTEMPTS) { + if (recoveryAttempts >= MAX_RECOVERY_ATTEMPTS) toast("Radio sync is paused. Tap the link status to retry.", "error"); + return; + } + recovering = true; + recoveryAttempts += 1; + setLink("reconnecting"); + toast(`Recovering companion link (${recoveryAttempts}/${MAX_RECOVERY_ATTEMPTS})`, "warn"); + setTimeout(async () => { + const previous = connection; + try { + await previous.close(); + syncing = false; + $("refresh-button").disabled = false; + connection = new HttpPollingConnection(); + bindConnectionEvents(connection); + await connection.connect(); + } catch { + setLink("offline"); + toast("Companion recovery failed", "error"); + } finally { + recovering = false; + } + }, 0); +} + +function text(id, value) { $(id).textContent = value ?? "—"; } +function hex(bytes, length = bytes?.length ?? 0) { return bytes ? [...bytes.slice(0, length)].map((value) => value.toString(16).padStart(2, "0")).join("") : ""; } +function hashText(value) { + let hash = 2166136261; + for (let index = 0; index < value.length; index += 1) hash = Math.imul(hash ^ value.charCodeAt(index), 16777619); + return (hash >>> 0).toString(16); +} +function historyKey() { return state.self?.publicKey ? `rcc6-history-${hex(state.self.publicKey)}` : ""; } +function pendingHistoryKey() { return `rcc6-history-pending-${connection.sessionId}`; } +function messageId(kind, key, timestamp, value) { return `${kind}:${key}:${timestamp}:${hashText(value)}`; } +function persistHistory() { + const key = historyKey() || pendingHistoryKey(); + try { localStorage.setItem(key, JSON.stringify(state.messages.slice(-MAX_HISTORY_MESSAGES))); } catch { /* storage is optional */ } +} +function readHistory(key) { + try { + const saved = JSON.parse(localStorage.getItem(key) || "[]"); + if (!Array.isArray(saved)) return []; + return saved.filter((item) => item && typeof item.id === "string" && typeof item.key === "string" && typeof item.text === "string") + .slice(-MAX_HISTORY_MESSAGES) + .map((item) => ({ + id: item.id.slice(0, 180), key: item.key.slice(0, 100), text: item.text.slice(0, MAX_MESSAGE_BYTES * 2), + timestamp: Number.isFinite(item.timestamp) ? item.timestamp : 0, + direction: item.direction === "out" ? "out" : "in", + status: typeof item.status === "string" ? item.status.slice(0, 16) : "received", + unread: Boolean(item.unread), + snr: Number.isFinite(item.snr) ? item.snr : undefined, + expectedAckCrc: Number.isInteger(item.expectedAckCrc) ? item.expectedAckCrc : undefined, + })); + } catch { return []; } +} +function loadHistoryForNode() { + const key = historyKey(); + if (!key || state.historyNode === key) return; + state.historyNode = key; + const merged = [...readHistory(key), ...readHistory(pendingHistoryKey()), ...state.messages]; + const seen = new Set(); + state.messages = merged.filter((item) => !seen.has(item.id) && seen.add(item.id)).slice(-MAX_HISTORY_MESSAGES); + try { localStorage.removeItem(pendingHistoryKey()); } catch { /* storage is optional */ } + persistHistory(); +} +function channelKey(channel) { return `ch:${channel.channelIdx}`; } +function contactKey(contact) { return `dm:${hex(contact.publicKey)}`; } +function initials(name = "?") { return name.trim().split(/\s+/).slice(0, 2).map((part) => part[0]).join("").toUpperCase() || "?"; } +function formatNumber(value) { return Number.isFinite(value) ? value.toLocaleString() : "—"; } +function formatClock(epochSecs) { return epochSecs ? new Date(epochSecs * 1000).toLocaleTimeString([], { hour: "numeric", minute: "2-digit" }) : "now"; } +function formatAge(epochSecs) { + if (!epochSecs) return "just now"; + const seconds = Math.max(0, Math.floor(Date.now() / 1000) - epochSecs); + if (seconds < 60) return `${seconds}s ago`; + if (seconds < 3600) return `${Math.floor(seconds / 60)}m ago`; + if (seconds < 86400) return `${Math.floor(seconds / 3600)}h ago`; + return `${Math.floor(seconds / 86400)}d ago`; +} +function formatSession() { + const minutes = Math.floor((Date.now() - state.startedAt) / 60000); + return minutes < 1 ? "Now" : minutes < 60 ? `${minutes}m` : `${Math.floor(minutes / 60)}h ${minutes % 60}m`; +} +function radioFrequency(value) { return Number.isFinite(value) ? (value / 1e6).toFixed(3) : "—"; } +function radioBandwidth(value) { return Number.isFinite(value) ? (value / 1000).toFixed(value % 1000 ? 1 : 0) : "—"; } +function signalQuality(rssi) { return rssi >= -80 ? "Excellent" : rssi >= -95 ? "Good" : rssi >= -110 ? "Fair" : "Weak"; } + +function element(tag, className, content) { + const node = document.createElement(tag); + if (className) node.className = className; + if (content != null) node.textContent = content; + return node; +} + +function toast(message, kind = "ok") { + const item = element("div", `toast ${kind}`); + item.append(element("i"), element("span", "", message)); + $("toasts").append(item); + setTimeout(() => item.classList.add("out"), 3200); + setTimeout(() => item.remove(), 3500); +} + +function setLink(status) { + const online = status === "connected"; + state.connected = online; + state.linkStatus = status; + const label = online ? "Connected" : status === "reconnecting" ? "Reconnecting" : status === "busy" ? "Another tab active" : "Offline"; + text("link-label", label); + text("side-status", label); + text("hero-link", label); + $("connect-button").className = `link-chip ${status}`; + $("side-dot").className = `status-dot ${status}`; +} + +function targetInfo(key) { + if (key.startsWith("ch:")) { + const channel = state.channels.find((item) => channelKey(item) === key); + return channel ? { key, name: `#${channel.name || `Channel ${channel.channelIdx}`}`, subtitle: "Mesh channel", avatar: "#", channel } : null; + } + const contact = state.contacts.find((item) => contactKey(item) === key); + return contact ? { key, name: contact.advName || "Unnamed contact", subtitle: `Direct · ${hex(contact.publicKey, 4)}`, avatar: initials(contact.advName), contact } : null; +} + +function targetForContactPrefix(prefix) { + const contact = state.contacts.find((item) => prefix.every((byte, index) => item.publicKey[index] === byte)); + return contact ? contactKey(contact) : `dm-prefix:${hex(prefix)}`; +} + +function normalizeTargets() { + if (state.selected && targetInfo(state.selected)) return; + state.selected = state.channels[0] ? channelKey(state.channels[0]) : state.contacts[0] ? contactKey(state.contacts[0]) : ""; +} + +function addMessage(message) { + const item = { id: `${Date.now()}-${Math.random()}`, ...message }; + if (state.messages.some((existing) => existing.id === item.id)) return null; + state.messages.push(item); + if (state.messages.length > MAX_HISTORY_MESSAGES) state.messages.splice(0, state.messages.length - MAX_HISTORY_MESSAGES); + persistHistory(); + renderMessages(); + renderHome(); + return item; +} + +function ingestWaiting(item) { + if (item.contactMessage) { + const message = item.contactMessage; + const key = targetForContactPrefix(message.pubKeyPrefix); + return addMessage({ id: messageId("dm", hex(message.pubKeyPrefix), message.senderTimestamp, message.text), key, text: message.text, timestamp: message.senderTimestamp, direction: "in", status: "received", unread: document.hidden || state.view !== "messages" || state.selected !== key, snr: message.snr }) ? 1 : 0; + } + if (item.channelMessage) { + const message = item.channelMessage; + const key = `ch:${message.channelIdx}`; + return addMessage({ id: messageId("channel", key, message.senderTimestamp, message.text), key, text: message.text, timestamp: message.senderTimestamp, direction: "in", status: "received", unread: document.hidden || state.view !== "messages" || state.selected !== key, snr: message.snr }) ? 1 : 0; + } + return 0; +} + +function refreshNearbyFromContacts() { + state.nearby = [...state.contacts].filter((item) => item.lastAdvert).sort((a, b) => b.lastAdvert - a.lastAdvert).slice(0, 24); +} + +async function refreshContacts() { + const contacts = await connection.getContacts(); + state.contacts = contacts.sort((a, b) => (b.lastAdvert || 0) - (a.lastAdvert || 0)); + let historyChanged = false; + for (const message of state.messages) { + if (!message.key.startsWith("dm-prefix:")) continue; + const prefix = message.key.slice("dm-prefix:".length); + const contact = state.contacts.find((item) => hex(item.publicKey).startsWith(prefix)); + if (contact) { message.key = contactKey(contact); historyChanged = true; } + } + if (historyChanged) persistHistory(); + refreshNearbyFromContacts(); + normalizeTargets(); + renderAll(); +} + +async function syncMessages() { + let added = 0; + while (true) { + const waiting = await connection.syncNextMessage(); + if (!waiting) break; + added += ingestWaiting(waiting); + } + added += unannouncedMessages; + unannouncedMessages = 0; + if (added) toast(`${added} new message${added === 1 ? "" : "s"}`, "warn"); +} + +async function refreshStats() { + if (!state.connected) return; + try { + const battery = await connection.getBatteryVoltage(); + state.battery = battery.batteryMilliVolts; + } catch { /* optional */ } + try { + const radio = await connection.getStatsRadio(); + state.radio = radio.data; + if (Number.isFinite(state.radio.lastRssi)) state.rfSamples.push(state.radio.lastRssi); + state.rfSamples = state.rfSamples.slice(-36); + } catch { /* optional */ } + try { state.packets = (await connection.getStatsPackets()).data; } catch { /* optional */ } + renderAll(); +} + +async function refreshNetworkStatus() { + try { + const response = await fetch("/api/network", { + headers: { Accept: "application/json", "X-RCC6-Session": connection.sessionId }, + cache: "no-store", + credentials: "same-origin", + }); + if (!response.ok) throw new Error(`Network status failed (${response.status})`); + const data = await response.json(); + if (data.mode !== "ap" && data.mode !== "station") throw new Error("Invalid network mode"); + state.network = { + mode: data.mode, + ssid: typeof data.ssid === "string" ? data.ssid : "", + ip: typeof data.ip === "string" ? data.ip : "", + fallback: Boolean(data.fallback), + }; + } catch { /* network configuration endpoint is optional on older builds */ } + renderNetwork(); +} + +async function setNetwork(fields) { + if (!connection.ready || !connection.ownsLease()) throw new Error("RCC6 companion link is not ready"); + const response = await fetch("/api/network", { + method: "POST", + headers: { + "Content-Type": "application/x-www-form-urlencoded", + "X-RCC6-Session": connection.sessionId, + }, + body: new URLSearchParams(fields), + cache: "no-store", + credentials: "same-origin", + }); + if (!response.ok) throw new Error(`Network update failed (${response.status})`); +} + +async function syncAll() { + if (syncing) return; + syncing = true; + $("refresh-button").disabled = true; + try { + await refreshNetworkStatus(); + try { state.device = await connection.deviceQuery(Constants.SupportedCompanionProtocolVersion); } catch { /* older firmware */ } + state.self = await connection.getSelfInfo(6000); + loadHistoryForNode(); + await refreshContacts(); + try { state.channels = (await connection.getChannels()).filter((item) => item.name); } catch { state.channels = []; } + normalizeTargets(); + await syncMessages(); + await refreshStats(); + renderAll(); + } finally { + syncing = false; + $("refresh-button").disabled = false; + } +} + +function renderHome() { + const self = state.self; + text("node-name", self?.name || "RCC6"); + text("node-id", self?.publicKey ? `ID ${hex(self.publicKey, 8)}…` : "Waiting for companion identity…"); + text("hero-contacts", state.contacts.length || "—"); + text("hero-uptime", formatSession()); + const unread = state.messages.filter((item) => item.unread); + text("home-unread", unread.length); + text("nav-unread", unread.length); + $("nav-unread").hidden = !unread.length; + const latest = unread.at(-1); + const preview = $("message-preview"); + preview.replaceChildren(); + if (latest) { + const target = targetInfo(latest.key); + preview.className = "preview"; + preview.append(element("strong", "", target?.name || "New message"), element("span", "", latest.text)); + } else { + preview.className = "preview empty"; + preview.textContent = "No unread messages"; + } + const nearby = state.nearby[0]; + const nearbyPreview = $("nearby-preview"); + nearbyPreview.replaceChildren(); + if (nearby) { + nearbyPreview.className = "preview"; + nearbyPreview.append(element("strong", "", nearby.advName || "Unnamed node"), element("span", "", `${formatAge(nearby.lastAdvert)} · ${hex(nearby.publicKey, 4)}`)); + } else { + nearbyPreview.className = "preview empty"; + nearbyPreview.textContent = "Waiting for adverts"; + } + const rssi = state.radio?.lastRssi; + text("home-rssi", Number.isFinite(rssi) ? `${rssi} dBm` : "— dBm"); + text("home-snr", Number.isFinite(state.radio?.lastSnr) ? `SNR ${state.radio.lastSnr.toFixed(1)}` : "SNR —"); + text("home-frequency", self?.radioFreq ? `${radioFrequency(self.radioFreq)} MHz` : "— MHz"); + text("home-packets", state.packets ? `${formatNumber(state.packets.recv)} packets` : "— packets"); + $("radio-meter-fill").style.width = Number.isFinite(rssi) ? `${Math.max(4, Math.min(100, (rssi + 125) * 2))}%` : "0"; +} + +function renderMessages() { + normalizeTargets(); + const targets = [ + ...state.channels.map((channel) => ({ key: channelKey(channel), name: `#${channel.name}`, subtitle: "Channel", avatar: "#" })), + ...state.contacts.map((contact) => ({ key: contactKey(contact), name: contact.advName || "Unnamed contact", subtitle: "Direct", avatar: initials(contact.advName) })), + ]; + text("thread-count", targets.length); + const threadList = $("thread-list"); + threadList.replaceChildren(); + if (!targets.length) threadList.append(element("p", "empty-state", "Contacts and channels appear after sync.")); + for (const target of targets) { + const messages = state.messages.filter((item) => item.key === target.key); + const latest = messages.at(-1); + const unread = messages.filter((item) => item.unread).length; + const button = element("button", `thread${state.selected === target.key ? " active" : ""}`); + button.type = "button"; + const avatar = element("span", "avatar", target.avatar); + const copy = element("span", "thread-copy"); + copy.append(element("strong", "", target.name), element("small", "", latest?.text || target.subtitle)); + const meta = unread ? element("span", "thread-badge", unread) : element("time", "thread-time", latest ? formatClock(latest.timestamp) : ""); + button.append(avatar, copy, meta); + button.addEventListener("click", () => selectTarget(target.key)); + threadList.append(button); + } + + const select = $("target-select"); + select.replaceChildren(new Option("Choose recipient", "")); + if (state.channels.length) { + const group = document.createElement("optgroup"); group.label = "Channels"; + for (const channel of state.channels) group.append(new Option(`#${channel.name}`, channelKey(channel))); + select.append(group); + } + if (state.contacts.length) { + const group = document.createElement("optgroup"); group.label = "Direct contacts"; + for (const contact of state.contacts) group.append(new Option(contact.advName || "Unnamed contact", contactKey(contact))); + select.append(group); + } + select.value = state.selected; + const info = targetInfo(state.selected); + text("conversation-title", info?.name || "Choose a conversation"); + text("conversation-subtitle", info?.subtitle || "Channel or direct contact"); + text("conversation-avatar", info?.avatar || "#"); + const list = $("message-list"); + list.replaceChildren(); + const messages = state.messages.filter((item) => item.key === state.selected); + if (!messages.length) list.append(element("div", "welcome-bubble", info ? `No messages with ${info.name} yet.` : "Select a channel or contact to start talking across the mesh.")); + for (const message of messages) { + const bubble = element("article", `bubble ${message.direction === "out" ? "out" : "in"} ${message.status === "failed" ? "failed" : ""}`); + const status = message.direction === "out" ? ` · ${message.status}` : Number.isFinite(message.snr) ? ` · SNR ${message.snr.toFixed(1)}` : ""; + bubble.append(element("p", "", message.text), element("small", "", `${formatClock(message.timestamp)}${status}`)); + list.append(bubble); + } + requestAnimationFrame(() => { list.scrollTop = list.scrollHeight; }); + $("message-input").disabled = !info || !state.connected; + $("composer").querySelector("button").disabled = !info || !state.connected; +} + +function selectTarget(key) { + state.selected = key; + for (const message of state.messages) if (message.key === key) message.unread = false; + persistHistory(); + renderMessages(); + renderHome(); +} + +function renderNearby() { + const list = $("nearby-list"); + list.replaceChildren(); + if (!state.nearby.length) { + list.append(element("article", "card empty-state", "Nearby nodes appear as adverts arrive.")); + return; + } + for (const contact of state.nearby) { + const card = element("article", "card nearby-card"); + const avatar = element("span", "avatar", initials(contact.advName)); + const body = element("div"); + body.append(element("p", "eyebrow", contact.type === 2 ? "REPEATER" : contact.type === 3 ? "ROOM" : "CONTACT"), element("h3", "", contact.advName || "Unnamed node"), element("p", "", `ID ${hex(contact.publicKey, 5)} · ${contact.outPathLen > 0 ? `${contact.outPathLen} hop path` : "flood path"}`)); + const time = element("time", "", formatAge(contact.lastAdvert)); + const action = element("button", "contact-action", "Message →"); + action.type = "button"; + action.addEventListener("click", () => { state.selected = contactKey(contact); showView("messages"); }); + card.append(avatar, body, time, action); + list.append(card); + } +} + +function renderRadio() { + const self = state.self; + const radio = state.radio; + const packets = state.packets; + text("radio-rssi", Number.isFinite(radio?.lastRssi) ? radio.lastRssi : "—"); + text("radio-quality", Number.isFinite(radio?.lastRssi) ? signalQuality(radio.lastRssi) : "Waiting for sample"); + text("radio-snr", Number.isFinite(radio?.lastSnr) ? `SNR ${radio.lastSnr.toFixed(1)} dB` : "SNR —"); + text("radio-noise", Number.isFinite(radio?.noiseFloor) ? `Noise ${radio.noiseFloor} dBm` : "Noise —"); + text("radio-frequency", radioFrequency(self?.radioFreq)); + text("radio-bandwidth", radioBandwidth(self?.radioBw)); + text("radio-spreading", self?.radioSf ? `SF${self.radioSf}` : "—"); + text("radio-coding", self?.radioCr ? `CR 4/${self.radioCr}` : "CR —"); + text("radio-power", Number.isFinite(self?.txPower) ? self.txPower : "—"); + text("packet-received", formatNumber(packets?.recv)); + text("packet-sent", formatNumber(packets?.sent)); + text("packet-direct", formatNumber(packets?.nRecvDirect)); + text("packet-flood", formatNumber(packets?.nRecvFlood)); + const errors = packets?.nRecvErrors ?? 0; + text("packet-errors", `${formatNumber(errors)} error${errors === 1 ? "" : "s"}`); + $("packet-errors").className = errors ? "error" : "quiet"; + if (state.view === "radio") requestAnimationFrame(drawSignalChart); +} + +function drawSignalChart() { + const canvas = $("signal-chart"); + const width = canvas.clientWidth; + const height = canvas.clientHeight; + if (width < 20 || height < 20) return; + const ratio = Math.min(devicePixelRatio || 1, 2); + canvas.width = Math.round(width * ratio); canvas.height = Math.round(height * ratio); + const context = canvas.getContext("2d"); context.scale(ratio, ratio); + context.clearRect(0, 0, width, height); + context.strokeStyle = "rgba(141,152,167,.12)"; context.lineWidth = 1; + for (let row = 1; row < 4; row += 1) { context.beginPath(); context.moveTo(0, row * height / 4); context.lineTo(width, row * height / 4); context.stroke(); } + const samples = state.rfSamples.length > 1 ? state.rfSamples : [-120, -120]; + context.beginPath(); + samples.forEach((sample, index) => { + const x = index * width / Math.max(1, samples.length - 1); + const y = height - Math.max(0, Math.min(1, (sample + 130) / 60)) * height; + index ? context.lineTo(x, y) : context.moveTo(x, y); + }); + context.strokeStyle = "#44f08a"; context.lineWidth = 2; context.shadowColor = "#44f08a"; context.shadowBlur = 8; context.stroke(); +} + +function renderNetwork() { + const network = state.network; + const busy = state.linkStatus === "busy"; + if (!network) { + text("network-title", "Set up local Wi-Fi"); + text("network-summary", "Use your 2.4 GHz home network instead of staying on the RCC6 setup hotspot."); + text("network-current", "Network status unavailable"); + text("more-network-title", "RCC6 network"); + text("ap-address", "Current mode and IP are unavailable"); + $("network-setup-button").textContent = "Set up local Wi-Fi"; + } else if (network.mode === "station") { + text("network-title", `Connected to ${network.ssid || "local Wi-Fi"}`); + text("network-summary", `${network.ip || "DHCP address pending"}${network.fallback ? " · fallback active" : " · ready on your local network"}`); + text("network-current", `${network.ssid || "Local Wi-Fi"} · ${network.ip || "DHCP pending"}`); + text("more-network-title", "Local Wi-Fi"); + text("ap-address", `${network.ssid || "Station mode"} · ${network.ip || "DHCP pending"}`); + $("network-setup-button").textContent = "Change local Wi-Fi"; + } else { + text("network-title", network.fallback ? "Local Wi-Fi needs attention" : "Set up local Wi-Fi"); + text("network-summary", `${network.ssid || "RCC6 setup AP"} · ${network.ip || "192.168.4.1"}${network.fallback ? " · station fallback" : ""}`); + text("network-current", `${network.ssid || "RCC6 setup AP"} · ${network.ip || "192.168.4.1"}`); + text("more-network-title", network.fallback ? "Fallback setup AP" : "RCC6 setup AP"); + text("ap-address", `${network.ssid || "Setup hotspot"} · ${network.ip || "192.168.4.1"}`); + $("network-setup-button").textContent = "Set up local Wi-Fi"; + } + $("network-setup-button").disabled = busy; + $("return-ap-button").hidden = network?.mode !== "station"; + $("return-ap-button").disabled = busy; +} + +function openNetworkDialog() { + renderNetwork(); + $("network-form").hidden = false; + $("network-result").hidden = true; + $("network-ssid").value = state.network?.mode === "station" ? state.network.ssid : ""; + $("network-password").value = ""; + $("network-password").type = "password"; + $("network-reveal").textContent = "Show"; + $("network-reveal").setAttribute("aria-pressed", "false"); + const dialog = $("network-dialog"); + if (dialog.showModal) dialog.showModal(); else dialog.setAttribute("open", ""); + $("network-ssid").focus(); +} + +function closeNetworkDialog() { + const dialog = $("network-dialog"); + if (dialog.close) dialog.close(); else dialog.removeAttribute("open"); +} + +function showNetworkResult(mode) { + $("network-form").hidden = true; + $("network-result").hidden = false; + const steps = $("network-result-steps"); + steps.replaceChildren(); + const values = mode === "station" + ? ["Wait for RCC6 to restart.", "Reconnect this phone or computer to your home Wi-Fi.", "Read the new DHCP IP on the RCC6 TFT and open it in your browser."] + : ["Wait for RCC6 to restart in setup AP mode.", "Reconnect this phone or computer to the RCC6 Wi-Fi shown on the TFT.", "Open 192.168.4.1 in your browser."]; + for (const value of values) steps.append(element("li", "", value)); + text("network-result-title", mode === "station" ? "Reconnect to your home Wi-Fi" : "Reconnect to the RCC6 setup AP"); + const note = $("network-result-note"); + note.replaceChildren(); + if (mode === "station") { + note.append("In station mode, the browser may request HTTP Basic authentication. Use username ", element("strong", "", "meshcore"), " and the 8-letter key shown on the TFT as the password."); + } else { + note.textContent = "The TFT shows the setup Wi-Fi name and password after restart."; + } +} + +function renderMore() { + const self = state.self; + const device = state.device; + text("more-name", self?.name || "RCC6"); + text("more-model", device?.manufacturerModel || "MeshCore Companion"); + text("more-firmware", device?.firmwareVer != null ? `Protocol ${device.firmwareVer}` : "—"); + text("more-build", device?.firmware_build_date || "—"); + text("more-key", self?.publicKey ? `${hex(self.publicKey, 8)}…` : "—"); + text("app-version", __APP_VERSION__); + text("library-version", __MESHCORE_JS_VERSION__); + $("advert-button").disabled = !state.connected; + $("clear-history-button").disabled = !state.messages.length; +} + +function renderAll() { + if (state.battery) { + const volts = `${(state.battery / 1000).toFixed(2)} V`; + text("battery-chip", volts); + } + renderHome(); renderMessages(); renderNearby(); renderRadio(); renderNetwork(); renderMore(); +} + +function showView(view) { + state.view = view; + document.querySelectorAll(".screen").forEach((screen) => screen.classList.toggle("active", screen.dataset.screen === view)); + document.querySelectorAll(".nav button").forEach((button) => button.classList.toggle("active", button.dataset.view === view)); + text("screen-title", view[0].toUpperCase() + view.slice(1)); + text("screen-kicker", view === "home" ? "COMPANION" : view === "messages" ? "MESH CHAT" : view === "nearby" ? "DISCOVERY" : view === "radio" ? "RF HEALTH" : "DEVICE"); + if (view === "messages" && state.selected) selectTarget(state.selected); + if (view === "radio") renderRadio(); + window.scrollTo({ top: 0, behavior: "smooth" }); +} + +async function sendMessage(event) { + event.preventDefault(); + const input = $("message-input"); + const messageText = input.value.trim(); + const info = targetInfo(state.selected); + if (!messageText || !info) return; + if (encoder.encode(messageText).length > MAX_MESSAGE_BYTES) return toast("Message is over 140 bytes", "error"); + const outgoing = addMessage({ key: state.selected, text: messageText, timestamp: Math.floor(Date.now() / 1000), direction: "out", status: "sending", unread: false }); + input.value = ""; updateComposeCount(); + try { + const response = await exclusive(() => info.channel ? connection.sendChannelTextMessage(info.channel.channelIdx, messageText) : connection.sendTextMessage(info.contact.publicKey, messageText)); + outgoing.status = "queued"; + if (!info.channel && Number.isInteger(response?.expectedAckCrc)) outgoing.expectedAckCrc = response.expectedAckCrc; + persistHistory(); + toast("Message queued"); + } catch { + outgoing.status = "failed"; + persistHistory(); + toast("Message failed", "error"); + } + renderMessages(); +} + +function updateComposeCount() { + const count = encoder.encode($("message-input").value).length; + text("compose-count", `${count} / ${MAX_MESSAGE_BYTES} bytes`); + $("compose-count").className = count > MAX_MESSAGE_BYTES ? "error" : ""; +} + +function bindConnectionEvents(radio) { + radio.on(Constants.ResponseCodes.ContactMsgRecv, (message) => { unannouncedMessages += ingestWaiting({ contactMessage: message }); }); + radio.on(Constants.ResponseCodes.ChannelMsgRecv, (message) => { unannouncedMessages += ingestWaiting({ channelMessage: message }); }); + radio.on("connected", () => { + if (!radio.ready || !radio.ownsLease()) return; + setLink("connected"); + toast("RCC6 connected"); + setTimeout(() => $("boot").classList.add("hidden"), 220); + exclusive(syncAll).then(() => { recoveryAttempts = 0; }).catch(() => toast("Initial sync failed", "error")); + }); + radio.on("disconnected", () => setLink("offline")); + radio.on("transport-busy", () => { + setLink("busy"); + $("boot").classList.add("hidden"); + toast("Another tab controls this radio. Close it, then tap the link status to retry.", "warn"); + }); + radio.on("transport-state", () => { setLink("reconnecting"); toast("Link interrupted — reconnecting", "warn"); }); + radio.on("transport-restored", () => { + setLink("connected"); + toast("Link restored — resyncing"); + exclusive(syncAll).then(() => { recoveryAttempts = 0; }).catch(() => toast("Resync failed", "error")); + }); + radio.on(Constants.PushCodes.MsgWaiting, () => { if (radio.ready) exclusive(syncMessages).catch(() => toast("Message sync failed", "error")); }); + radio.on(Constants.PushCodes.NewAdvert, (advert) => { + const existing = state.contacts.findIndex((item) => hex(item.publicKey) === hex(advert.publicKey)); + if (existing >= 0) state.contacts[existing] = advert; else state.contacts.unshift(advert); + refreshNearbyFromContacts(); renderAll(); toast(`${advert.advName || "A node"} is nearby`, "warn"); + }); + radio.on(Constants.PushCodes.Advert, () => { if (radio.ready) exclusive(refreshContacts).catch(() => {}); }); + radio.on(Constants.PushCodes.SendConfirmed, (confirmation) => { + const pending = [...state.messages].reverse().find((item) => item.direction === "out" && item.key.startsWith("dm:") && item.status === "queued" && item.expectedAckCrc === confirmation.ackCode); + if (pending) { pending.status = "delivered"; persistHistory(); renderMessages(); toast("Direct message delivered"); } + }); + radio.on(Constants.PushCodes.LogRxData, (sample) => { + state.radio = { ...(state.radio || {}), lastRssi: sample.lastRssi, lastSnr: sample.lastSnr }; + state.rfSamples.push(sample.lastRssi); state.rfSamples = state.rfSamples.slice(-36); renderHome(); renderRadio(); + }); +} + +document.querySelectorAll(".nav button").forEach((button) => button.addEventListener("click", () => showView(button.dataset.view))); +document.querySelectorAll("[data-open]").forEach((button) => button.addEventListener("click", () => showView(button.dataset.open))); +$("target-select").addEventListener("change", (event) => selectTarget(event.target.value)); +$("composer").addEventListener("submit", sendMessage); +$("message-input").addEventListener("input", updateComposeCount); +$("nearby-refresh").addEventListener("click", () => exclusive(refreshContacts).then(() => toast("Nearby refreshed")).catch(() => toast("Refresh failed", "error"))); +$("refresh-button").addEventListener("click", () => exclusive(syncAll).then(() => toast("Sync complete")).catch(() => toast("Sync failed", "error"))); +$("advert-button").addEventListener("click", async () => { + $("advert-button").disabled = true; + try { await exclusive(() => connection.sendFloodAdvert()); toast("Advert queued", "warn"); } + catch { toast("Advert failed", "error"); } + finally { $("advert-button").disabled = false; } +}); +$("connect-button").addEventListener("click", () => { + recoveryAttempts = 0; + if (state.connected) return exclusive(syncAll).catch(() => toast("Sync failed", "error")); + return connection.connect().catch(() => toast("Could not reconnect", "error")); +}); +$("network-setup-button").addEventListener("click", openNetworkDialog); +$("network-dialog-close").addEventListener("click", closeNetworkDialog); +$("network-cancel").addEventListener("click", closeNetworkDialog); +$("network-done").addEventListener("click", closeNetworkDialog); +$("network-reveal").addEventListener("click", () => { + const password = $("network-password"); + const revealed = password.type === "password"; + password.type = revealed ? "text" : "password"; + $("network-reveal").textContent = revealed ? "Hide" : "Show"; + $("network-reveal").setAttribute("aria-pressed", String(revealed)); +}); +$("network-form").addEventListener("submit", async (event) => { + event.preventDefault(); + const ssid = $("network-ssid").value; + const password = $("network-password").value; + const ssidBytes = encoder.encode(ssid).length; + const passwordBytes = encoder.encode(password).length; + if (ssidBytes < 1 || ssidBytes > 32) { toast("Wi-Fi name must be 1–32 bytes", "error"); return $("network-ssid").focus(); } + if (passwordBytes !== 0 && (passwordBytes < 8 || passwordBytes > 64)) { toast("Password must be empty or 8–64 bytes", "error"); return $("network-password").focus(); } + $("network-save").disabled = true; + try { + await setNetwork({ mode: "station", ssid, password }); + showNetworkResult("station"); + toast("Local Wi-Fi saved. RCC6 is restarting.", "warn"); + } catch { toast("Could not save Wi-Fi settings", "error"); } + finally { $("network-save").disabled = false; } +}); +$("return-ap-button").addEventListener("click", async () => { + if (!confirm("Return RCC6 to setup AP mode? The device will restart.")) return; + $("return-ap-button").disabled = true; + try { + await setNetwork({ mode: "ap" }); + openNetworkDialog(); + showNetworkResult("ap"); + toast("Setup AP requested. RCC6 is restarting.", "warn"); + } catch { toast("Could not return to setup AP", "error"); } + finally { $("return-ap-button").disabled = false; } +}); +$("clear-history-button").addEventListener("click", () => { + if (!state.messages.length || !confirm("Clear locally stored message history for this node?")) return; + try { localStorage.removeItem(historyKey()); } catch { /* storage is optional */ } + state.messages = []; + renderAll(); + toast("Local message history cleared"); +}); +window.addEventListener("resize", () => state.view === "radio" && drawSignalChart()); +document.addEventListener("visibilitychange", () => { + if (!document.hidden && state.connected) exclusive(async () => { + await syncMessages(); + await refreshStats(); + await refreshNetworkStatus(); + }).catch(() => toast("Foreground sync failed", "error")); +}); +window.addEventListener("pagehide", () => connection.leavePage()); +window.addEventListener("pageshow", (event) => { + if (event.persisted && !connection.running) { + setLink("reconnecting"); + connection.connect().catch(() => toast("Could not reconnect", "error")); + } +}); + +bindConnectionEvents(connection); +renderAll(); +setInterval(() => { text("hero-uptime", formatSession()); if (!document.hidden && state.connected) exclusive(refreshStats).catch(() => {}); }, 30000); +connection.connect().catch(() => { setLink("offline"); $("boot").classList.add("hidden"); toast("Could not open companion link", "error"); }); diff --git a/examples/companion_radio/webui/src/index.html b/examples/companion_radio/webui/src/index.html new file mode 100644 index 00000000..12460042 --- /dev/null +++ b/examples/companion_radio/webui/src/index.html @@ -0,0 +1,181 @@ + + + + + + + + + + MeshCore · RCC6 + + + + + +
+ + +
+
+

COMPANION

Home

+
+ — V + +
+
+ +
+
+
+

YOUR MESH NODE

+

RCC6

+

Waiting for companion link…

+
+ +
+
LINKStarting
+
CONTACTS
+
SESSION
+
+
+ +
+ +

LOCAL CONNECTION

Set up local Wi-Fi

Use your 2.4 GHz home network instead of staying on the RCC6 setup hotspot.

+ +
+ +
+
+

INBOX

Unread messages

0
+
No unread messages
+ +
+ +
+

MESH ACTIVITY

Recently nearby

+
Waiting for adverts
+ +
+ +
+

LIVE RADIO

— dBmSNR —
+
+
— MHz— packets
+
+
+
+ +
+
+ +
+
+
#
+
Choose a conversationChannel or direct contact
+
+
Select a channel or contact to start talking across the mesh.
+
+ + +
+ + + +
+ 0 / 140 bytes +
+
+
+
+ +
+

RECENT ADVERTS

Nearby mesh

+
Nearby nodes appear as adverts arrive.
+
+ +
+
+
+

SIGNAL HEALTH

Live RF

LIVE
+
dBmWaiting for sample
+ +
RSSISNR —Noise —
+
+
+
FREQUENCYMHz
+
BANDWIDTHkHz
+
SPREADINGCR —
+
TX POWERdBm
+
+
+

PACKETS

On-air counters

0 errors
+
Received
Sent
Direct RX
Flood RX
+
+
+
+ +
+
+
+

DEVICE

+

RCC6

MeshCore Companion

+
Firmware
Build
Public key
+
+
+

PRESENCE

Advertise this node

Queue a flood advert so nearby MeshCore nodes can discover you.

+

CONNECTION

RCC6 setup AP

Connected through this device at 192.168.4.1

+

PRIVACY

Local message history

Up to 120 messages are kept in this browser for this node. Clear them whenever you like.

+

ABOUT

MeshCore Web

Offline companion UI · v
Powered by MeshCore.js · MIT © Liam Cottle

+
+
+
+
+
+ + +

RCC6 NETWORK

Set up local Wi-Fi

+
CURRENT CONNECTIONChecking RCC6…
+
+ + + +
+

SSID: 1–32 bytes. Password: empty, or 8–64 characters. RCC6 supports 2.4 GHz networks only.

+
+
+ +
+ +
+
MeshCoreConnecting to RCC6…
+ + + diff --git a/examples/companion_radio/webui/src/styles.css b/examples/companion_radio/webui/src/styles.css new file mode 100644 index 00000000..1e3c3550 --- /dev/null +++ b/examples/companion_radio/webui/src/styles.css @@ -0,0 +1,263 @@ +:root { + color-scheme: dark; + --bg: #050608; + --panel: #0c0f13; + --panel-2: #11151b; + --line: #222934; + --text: #f5f8fb; + --muted: #8d98a7; + --green: #44f08a; + --blue: #42a5ff; + --yellow: #ffd447; + --orange: #ff8a3d; + --red: #ff5468; + --radius: 22px; + --shadow: 0 20px 70px rgba(0, 0, 0, .32); + font-family: -apple-system, BlinkMacSystemFont, "SF Pro Display", "Segoe UI", sans-serif; + background: var(--bg); + color: var(--text); + font-synthesis: none; +} + +* { box-sizing: border-box; } +[hidden] { display: none !important; } +html { min-height: 100%; background: var(--bg); } +body { margin: 0; min-height: 100vh; min-height: 100dvh; overflow-x: hidden; background: + radial-gradient(circle at 75% -15%, rgba(66, 165, 255, .12), transparent 32rem), + radial-gradient(circle at 20% 110%, rgba(68, 240, 138, .08), transparent 35rem), var(--bg); } +button, textarea, select { font: inherit; color: inherit; } +button { border: 0; cursor: pointer; } +input { font: inherit; color: inherit; } +button:focus-visible, textarea:focus-visible, select:focus-visible { outline: 2px solid var(--blue); outline-offset: 2px; } +input:focus-visible { outline: 2px solid var(--blue); outline-offset: 2px; } +svg { width: 22px; height: 22px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; } +.svg-defs { position: absolute; width: 0; height: 0; } +.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0; } + +.shell { display: grid; grid-template-columns: 224px minmax(0, 1fr); min-height: 100vh; min-height: 100dvh; } +.sidebar { position: fixed; z-index: 20; inset: 0 auto 0 0; width: 224px; padding: 28px 18px 22px; display: flex; flex-direction: column; border-right: 1px solid rgba(255, 255, 255, .055); background: rgba(6, 8, 11, .88); backdrop-filter: blur(22px); } +.brand { display: flex; align-items: center; gap: 12px; padding: 4px 10px 32px; font-weight: 740; letter-spacing: -.03em; font-size: 19px; } +.brand small { display: block; margin-top: 2px; font-size: 9px; letter-spacing: .16em; color: var(--muted); text-transform: uppercase; } +.brand-mark { width: 30px; height: 30px; position: relative; display: inline-grid; place-items: center; border: 2px solid var(--green); border-radius: 50%; box-shadow: 0 0 18px rgba(68, 240, 138, .26), inset 0 0 12px rgba(68, 240, 138, .12); } +.brand-mark::before, .brand-mark::after, .brand-mark i { content: ""; position: absolute; border-radius: 50%; border: 1px solid rgba(68, 240, 138, .7); } +.brand-mark::before { width: 10px; height: 10px; } +.brand-mark::after { width: 3px; height: 3px; background: var(--green); border: 0; box-shadow: 0 0 10px var(--green); } +.brand-mark i { width: 20px; height: 6px; border-color: rgba(68, 240, 138, .55); } +.brand-mark.large { width: 58px; height: 58px; box-shadow: 0 0 35px rgba(68, 240, 138, .35); } +.brand-mark.large::before { width: 20px; height: 20px; } +.brand-mark.large i { width: 40px; height: 12px; } + +.nav { display: grid; gap: 7px; } +.nav button { position: relative; min-height: 49px; padding: 0 13px; display: flex; align-items: center; gap: 13px; color: var(--muted); border-radius: 14px; background: transparent; text-align: left; transition: color .2s ease, background .2s ease, transform .2s ease; } +.nav button:hover { color: var(--text); background: rgba(255, 255, 255, .045); } +.nav button.active { color: var(--green); background: linear-gradient(90deg, rgba(68, 240, 138, .13), rgba(68, 240, 138, .035)); box-shadow: inset 2px 0 var(--green); } +.nav button:active { transform: scale(.98); } +.nav button span { font-size: 14px; font-weight: 650; } +.nav button b { margin-left: auto; min-width: 20px; height: 20px; padding: 0 6px; display: grid; place-items: center; border-radius: 10px; color: #120e00; background: var(--yellow); font-size: 10px; } +.sidebar-foot { margin-top: auto; padding: 14px 11px 0; display: flex; gap: 8px; align-items: center; color: var(--muted); font-size: 11px; } +.status-dot { width: 8px; height: 8px; display: inline-block; flex: 0 0 auto; border-radius: 50%; background: var(--yellow); box-shadow: 0 0 12px currentColor; } +.connected .status-dot, .status-dot.connected { color: var(--green); background: var(--green); } +.reconnecting .status-dot, .status-dot.reconnecting { color: var(--yellow); background: var(--yellow); } +.busy .status-dot, .status-dot.busy { color: var(--yellow); background: var(--yellow); } +.offline .status-dot, .status-dot.offline { color: var(--red); background: var(--red); } + +main { grid-column: 2; width: min(100%, 1320px); margin: 0 auto; padding: 24px clamp(24px, 4vw, 62px) 54px; } +.topbar { min-height: 72px; display: flex; align-items: center; justify-content: space-between; gap: 20px; margin-bottom: 22px; } +.topbar h1 { margin: 2px 0 0; font-size: clamp(27px, 3vw, 38px); line-height: 1; letter-spacing: -.045em; } +.eyebrow { margin: 0; color: var(--muted); font-size: 9px; line-height: 1.2; font-weight: 760; letter-spacing: .18em; text-transform: uppercase; } +.top-actions { display: flex; align-items: center; gap: 9px; } +.battery, .link-chip { height: 38px; padding: 0 13px; display: inline-flex; align-items: center; gap: 8px; border: 1px solid var(--line); border-radius: 13px; background: rgba(13, 16, 21, .82); color: var(--muted); font-size: 11px; font-weight: 700; letter-spacing: .03em; } +.link-chip:hover { border-color: #394351; color: var(--text); } + +.screen { display: none; animation: screen-in .24s cubic-bezier(.2, .75, .25, 1); } +.screen.active { display: block; } +@keyframes screen-in { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } } +.card { position: relative; border: 1px solid rgba(255, 255, 255, .072); border-radius: var(--radius); background: linear-gradient(145deg, rgba(18, 22, 28, .94), rgba(10, 13, 17, .96)); box-shadow: var(--shadow); overflow: hidden; } +.card::after { content: ""; position: absolute; pointer-events: none; inset: 0; border-radius: inherit; background: linear-gradient(130deg, rgba(255, 255, 255, .025), transparent 35%); } +.card-head, .section-head { display: flex; align-items: center; justify-content: space-between; gap: 16px; } +.card h3, .section-head h2 { margin: 5px 0 0; letter-spacing: -.025em; } +.card h3 { font-size: 18px; } + +.hero { min-height: 268px; padding: clamp(26px, 4vw, 43px); display: grid; grid-template-columns: 1.2fr .8fr; align-items: center; background: + radial-gradient(circle at 78% 30%, rgba(68, 240, 138, .15), transparent 18rem), + linear-gradient(130deg, rgba(21, 28, 31, .98), rgba(6, 10, 12, .98)); } +.hero::before { content: ""; position: absolute; inset: 0; background-image: linear-gradient(rgba(68, 240, 138, .025) 1px, transparent 1px), linear-gradient(90deg, rgba(68, 240, 138, .025) 1px, transparent 1px); background-size: 24px 24px; mask-image: linear-gradient(90deg, transparent, #000); } +.hero-copy, .hero-stats, .mesh-orbit { position: relative; z-index: 2; } +.hero-copy h2 { margin: 8px 0 8px; max-width: 620px; font-size: clamp(39px, 6vw, 72px); line-height: .98; letter-spacing: -.065em; } +.hero-copy > p:last-child { margin: 0; color: var(--muted); font-family: ui-monospace, SFMono-Regular, Consolas, monospace; font-size: 11px; } +.hero-stats { align-self: end; grid-column: 1 / -1; display: flex; gap: 44px; margin-top: 28px; } +.hero-stats div { display: grid; gap: 5px; } +.hero-stats small { color: var(--muted); font-size: 8px; font-weight: 750; letter-spacing: .16em; } +.hero-stats strong { font-size: 13px; } +.mesh-orbit { justify-self: center; width: 154px; aspect-ratio: 1; display: grid; place-items: center; border: 1px solid rgba(68, 240, 138, .22); border-radius: 50%; box-shadow: 0 0 60px rgba(68, 240, 138, .09), inset 0 0 40px rgba(68, 240, 138, .06); } +.mesh-orbit::before, .mesh-orbit::after { content: ""; position: absolute; border-radius: 50%; border: 1px solid rgba(68, 240, 138, .18); } +.mesh-orbit::before { inset: 20px; } +.mesh-orbit::after { inset: 48px; background: rgba(68, 240, 138, .07); } +.mesh-orbit span { width: 11px; height: 11px; z-index: 1; border-radius: 50%; background: var(--green); box-shadow: 0 0 22px var(--green); } +.mesh-orbit i { position: absolute; width: 6px; height: 6px; border-radius: 50%; background: var(--blue); box-shadow: 0 0 12px var(--blue); } +.mesh-orbit i:nth-child(1) { top: 15px; left: 78px; } +.mesh-orbit i:nth-child(2) { right: 22px; bottom: 33px; background: var(--yellow); box-shadow: 0 0 12px var(--yellow); } +.mesh-orbit i:nth-child(3) { left: 13px; bottom: 54px; background: var(--orange); box-shadow: 0 0 12px var(--orange); } + +.dashboard-grid { margin-top: 18px; display: grid; grid-template-columns: 1fr 1fr; gap: 18px; } +.network-banner { min-height: 100px; margin-top: 18px; padding: 20px 22px; display: grid; grid-template-columns: 48px minmax(0, 1fr) auto; gap: 16px; align-items: center; border-color: rgba(66, 165, 255, .2); background: linear-gradient(120deg, rgba(20, 45, 67, .8), rgba(10, 15, 21, .96)); } +.network-banner h3 { margin: 5px 0 4px; }.network-banner p:not(.eyebrow) { margin: 0; color: var(--muted); font-size: 11px; line-height: 1.45; } +.network-icon { width: 48px; height: 48px; display: grid; place-items: center; border-radius: 16px; color: var(--blue); background: rgba(66, 165, 255, .12); box-shadow: inset 0 0 18px rgba(66, 165, 255, .08); } +.feature-card { min-height: 210px; padding: 24px; display: flex; flex-direction: column; } +.feature-card::before { content: ""; position: absolute; left: 0; top: 22px; bottom: 22px; width: 3px; border-radius: 0 3px 3px 0; background: var(--accent); box-shadow: 0 0 16px var(--accent); } +.accent-yellow { --accent: var(--yellow); } +.accent-orange { --accent: var(--orange); } +.count { min-width: 38px; height: 30px; display: grid; place-items: center; border: 1px solid color-mix(in srgb, var(--accent), transparent 65%); border-radius: 11px; color: var(--accent); background: color-mix(in srgb, var(--accent), transparent 91%); font-weight: 760; } +.signal-bars { display: flex; align-items: end; gap: 3px; height: 22px; color: var(--accent); } +.signal-bars i { width: 3px; border-radius: 2px; background: currentColor; box-shadow: 0 0 7px currentColor; } +.signal-bars i:nth-child(1) { height: 7px; }.signal-bars i:nth-child(2) { height: 13px; }.signal-bars i:nth-child(3) { height: 20px; } +.preview { margin: 22px 0 18px; display: grid; gap: 5px; } +.preview strong { font-size: 15px; } +.preview span { color: var(--muted); font-size: 12px; line-height: 1.45; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } +.preview.empty { color: var(--muted); font-size: 12px; } +.text-action { position: relative; z-index: 2; min-height: 44px; margin-top: auto; padding: 10px 0 0; display: flex; justify-content: space-between; align-items: center; background: transparent; color: var(--text); font-size: 11px; font-weight: 700; } +.text-action span { color: var(--accent, var(--green)); font-size: 16px; transition: transform .2s; } +.text-action:hover span { transform: translateX(3px); } +.radio-strip { grid-column: 1 / -1; min-height: 112px; padding: 22px 24px; display: grid; grid-template-columns: 150px 1fr 190px; align-items: center; gap: 24px; } +.radio-strip > div:first-child { display: grid; grid-template-columns: auto 1fr; align-items: baseline; gap: 3px 8px; } +.radio-strip .eyebrow { grid-column: 1 / -1; margin-bottom: 5px; } +.radio-strip strong { font-size: 23px; letter-spacing: -.04em; } +.radio-strip span { color: var(--muted); font-size: 10px; } +.radio-meter { height: 6px; border-radius: 3px; background: #212832; overflow: hidden; } +.radio-meter i { display: block; width: 0; height: 100%; border-radius: inherit; background: linear-gradient(90deg, var(--red), var(--yellow), var(--green)); box-shadow: 0 0 15px var(--green); transition: width .4s ease; } +.radio-meta { display: flex; justify-content: flex-end; gap: 18px; color: var(--muted); } + +.messages-layout { height: calc(100vh - 142px); min-height: 560px; display: grid; grid-template-columns: minmax(230px, 31%) 1fr; } +.threads-panel { padding: 24px 15px; border-right: 1px solid var(--line); overflow: hidden; } +.threads-panel .section-head { padding: 0 9px 17px; } +.threads-panel .section-head span { color: var(--muted); font-size: 11px; } +.threads { height: calc(100% - 60px); overflow-y: auto; scrollbar-width: thin; } +.thread { width: 100%; padding: 12px 10px; display: grid; grid-template-columns: 39px minmax(0, 1fr) auto; gap: 11px; align-items: center; border-radius: 13px; background: transparent; text-align: left; } +.thread:hover { background: rgba(255, 255, 255, .04); } +.thread.active { background: rgba(66, 165, 255, .11); } +.thread .avatar { width: 39px; height: 39px; } +.thread-copy { min-width: 0; display: grid; gap: 3px; } +.thread-copy strong, .thread-copy small { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } +.thread-copy strong { font-size: 12px; }.thread-copy small { color: var(--muted); font-size: 10px; } +.thread-time { color: var(--muted); font-size: 10px; } +.thread-badge { min-width: 20px; height: 20px; padding: 0 5px; display: grid; place-items: center; border-radius: 10px; color: #151000; background: var(--yellow); font-size: 9px; font-weight: 800; } +.avatar { display: grid; place-items: center; flex: 0 0 auto; border-radius: 13px; color: var(--blue); background: rgba(66, 165, 255, .11); font-size: 12px; font-weight: 800; } +.conversation { min-width: 0; display: grid; grid-template-rows: auto 1fr auto; } +.conversation-head { min-height: 73px; padding: 14px 22px; display: flex; align-items: center; gap: 12px; border-bottom: 1px solid var(--line); } +.conversation-head .avatar { width: 40px; height: 40px; } +.conversation-head div:last-child { min-width: 0; display: grid; gap: 3px; } +.conversation-head strong { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; font-size: 13px; } +.conversation-head small { color: var(--muted); font-size: 9px; } +.message-list { padding: 22px; display: flex; flex-direction: column; gap: 10px; overflow-y: auto; } +.welcome-bubble, .empty-state { margin: auto; color: var(--muted); text-align: center; font-size: 12px; line-height: 1.55; } +.bubble { max-width: min(78%, 580px); padding: 11px 14px 8px; display: grid; gap: 5px; align-self: flex-start; border: 1px solid var(--line); border-radius: 17px 17px 17px 5px; background: #151a21; } +.bubble.out { align-self: flex-end; border-color: rgba(68, 240, 138, .2); border-radius: 17px 17px 5px 17px; background: rgba(25, 67, 44, .65); } +.bubble p { margin: 0; font-size: 13px; line-height: 1.45; overflow-wrap: anywhere; white-space: pre-wrap; } +.bubble small { color: var(--muted); font-size: 10px; } +.bubble.out small { text-align: right; }.bubble.failed small { color: var(--red); } +.composer { padding: 13px 16px max(14px, env(safe-area-inset-bottom)); border-top: 1px solid var(--line); background: rgba(7, 9, 12, .7); } +.composer select { width: 100%; height: 44px; margin-bottom: 7px; padding: 0 10px; border: 0; border-radius: 11px; color: var(--muted); background: #11161d; font-size: 12px; } +.compose-row { display: grid; grid-template-columns: 1fr 43px; gap: 8px; } +.composer textarea { width: 100%; min-height: 44px; max-height: 110px; padding: 11px 13px; resize: none; border: 1px solid var(--line); border-radius: 14px; outline: 0; background: #11161c; font-size: 12px; line-height: 20px; } +.composer textarea:focus { border-color: rgba(66, 165, 255, .6); } +.send-button { width: 44px; height: 44px; display: grid; place-items: center; border-radius: 14px; color: #03130a; background: var(--green); box-shadow: 0 0 18px rgba(68, 240, 138, .2); } +.send-button:hover { filter: brightness(1.08); }.send-button:disabled { opacity: .35; cursor: not-allowed; } +.composer > small { display: block; margin: 5px 3px 0; color: var(--muted); font-size: 10px; text-align: right; } + +.page-head { margin: 5px 0 20px; }.page-head h2 { font-size: 28px; } +.icon-button { width: 44px; height: 44px; display: grid; place-items: center; border: 1px solid var(--line); border-radius: 13px; color: var(--muted); background: var(--panel); } +.icon-button:hover { color: var(--green); border-color: rgba(68, 240, 138, .3); } +.nearby-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 15px; } +.nearby-card { min-height: 128px; padding: 20px; display: grid; grid-template-columns: 42px 1fr auto; gap: 13px; align-items: start; } +.nearby-card .avatar { width: 42px; height: 42px; color: var(--orange); background: rgba(255, 138, 61, .12); } +.nearby-card h3 { margin: 3px 0 6px; font-size: 14px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } +.nearby-card p { margin: 0; color: var(--muted); font-size: 11px; line-height: 1.5; } +.nearby-card time { color: var(--orange); font-size: 10px; } +.nearby-card .contact-action { grid-column: 2 / -1; min-height: 44px; justify-self: start; padding: 10px 0; color: var(--blue); background: transparent; font-size: 11px; font-weight: 700; } + +.radio-grid { display: grid; grid-template-columns: minmax(0, 1.45fr) minmax(260px, .75fr); gap: 16px; } +.signal-card { grid-row: span 2; padding: 25px; } +.live-pill { padding: 5px 8px; border-radius: 8px; color: var(--green); background: rgba(68, 240, 138, .1); font-size: 8px; font-weight: 800; letter-spacing: .08em; } +.signal-readout { margin: 28px 0 5px; display: flex; align-items: baseline; gap: 7px; } +.signal-readout strong { font-size: clamp(48px, 7vw, 78px); line-height: .9; letter-spacing: -.07em; } +.signal-readout span { color: var(--muted); font-size: 13px; }.signal-readout small { margin-left: auto; color: var(--green); font-size: 9px; } +#signal-chart { width: 100%; height: 145px; display: block; } +.chart-legend { display: flex; gap: 17px; color: var(--muted); font-size: 9px; } +.chart-legend span { display: flex; align-items: center; gap: 6px; }.chart-legend i { width: 6px; height: 6px; border-radius: 50%; background: currentColor; }.chart-legend .green { color: var(--green); } +.metric-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; } +.metric { min-height: 126px; padding: 20px; display: flex; flex-direction: column; justify-content: flex-end; } +.metric small { margin-bottom: auto; color: var(--muted); font-size: 10px; letter-spacing: .11em; font-weight: 750; } +.metric strong { font-size: clamp(24px, 3vw, 34px); letter-spacing: -.05em; }.metric span { margin-top: 2px; color: var(--muted); font-size: 9px; } +.packet-card { padding: 23px; }.packet-card .quiet { color: var(--muted); font-size: 9px; } +.packet-card .error { color: var(--red); } +.packet-stats { margin-top: 24px; display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px; } +.packet-stats div { display: grid; gap: 4px; }.packet-stats strong { font-size: 20px; }.packet-stats small { color: var(--muted); font-size: 10px; } + +.more-grid { display: grid; grid-template-columns: minmax(260px, .7fr) minmax(0, 1.3fr); gap: 16px; } +.device-card { min-height: 480px; padding: 28px; display: flex; flex-direction: column; align-items: center; text-align: center; } +.device-icon { width: 102px; height: 102px; margin: 40px 0 26px; display: grid; place-items: center; border-radius: 30px; background: radial-gradient(circle, rgba(68, 240, 138, .15), rgba(68, 240, 138, .035)); box-shadow: inset 0 0 30px rgba(68, 240, 138, .06); } +.device-icon .brand-mark { width: 50px; height: 50px; }.device-icon .brand-mark::before { width: 18px; height: 18px; }.device-icon .brand-mark i { width: 35px; height: 10px; } +.device-card h2 { margin: 0; font-size: 31px; letter-spacing: -.05em; }.device-card > p:not(.eyebrow) { margin: 7px 0 0; color: var(--muted); font-size: 11px; } +.device-card dl { width: 100%; margin: auto 0 0; } +.device-card dl div { padding: 12px 0; display: flex; justify-content: space-between; gap: 16px; border-top: 1px solid var(--line); font-size: 10px; } +.device-card dt { color: var(--muted); }.device-card dd { margin: 0; max-width: 62%; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; font-family: ui-monospace, SFMono-Regular, Consolas, monospace; } +.settings-stack { display: grid; gap: 16px; } +.action-card, .about-card { min-height: 145px; padding: 25px; display: flex; justify-content: space-between; align-items: center; gap: 22px; } +.action-card p:not(.eyebrow), .about-card p:not(.eyebrow) { max-width: 480px; margin: 8px 0 0; color: var(--muted); font-size: 11px; line-height: 1.6; } +.primary-button, .secondary-button { position: relative; z-index: 2; min-width: 112px; min-height: 44px; padding: 0 16px; flex: 0 0 auto; border-radius: 13px; font-size: 11px; font-weight: 780; } +.primary-button { color: #06150b; background: var(--green); box-shadow: 0 0 20px rgba(68, 240, 138, .18); } +.secondary-button { border: 1px solid var(--line); color: var(--text); background: #151a21; } +.danger-button { color: var(--red); border-color: rgba(255, 84, 104, .28); } +.primary-button:disabled, .secondary-button:disabled { opacity: .45; cursor: wait; } +.action-buttons { display: flex; flex: 0 0 auto; gap: 8px; } + +.network-dialog { width: min(540px, calc(100vw - 28px)); max-height: min(760px, calc(100dvh - 28px)); padding: 25px; overflow-y: auto; border: 1px solid #2a3340; border-radius: 24px; color: var(--text); background: linear-gradient(145deg, #131820, #090c10); box-shadow: 0 30px 100px rgba(0, 0, 0, .72); } +.network-dialog::backdrop { background: rgba(0, 0, 0, .72); backdrop-filter: blur(8px); } +.dialog-head { display: flex; align-items: start; justify-content: space-between; gap: 16px; }.dialog-head h2 { margin: 5px 0 0; font-size: 27px; letter-spacing: -.04em; } +.dialog-close { width: 44px; height: 44px; flex: 0 0 auto; border-radius: 14px; color: var(--muted); background: #191f27; font-size: 25px; line-height: 1; } +.network-current { margin: 21px 0; padding: 14px; display: flex; align-items: center; gap: 11px; border: 1px solid var(--line); border-radius: 14px; background: #0d1117; }.network-current div { min-width: 0; display: grid; gap: 3px; }.network-current small { color: var(--muted); font-size: 10px; letter-spacing: .1em; }.network-current strong { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; font-size: 12px; } +.network-dialog form { display: grid; gap: 9px; }.network-dialog label { margin-top: 4px; font-size: 12px; font-weight: 700; }.network-dialog input { width: 100%; min-height: 48px; padding: 0 13px; border: 1px solid var(--line); border-radius: 13px; background: #0d1117; font-size: 16px; } +.password-row { display: grid; grid-template-columns: 1fr auto; gap: 8px; }.password-row button { min-width: 62px; min-height: 48px; border-radius: 13px; color: var(--blue); background: rgba(66, 165, 255, .1); font-size: 12px; font-weight: 750; } +.field-help { margin: 2px 0 6px; color: var(--muted); font-size: 11px; line-height: 1.5; }.dialog-actions { margin-top: 7px; display: flex; justify-content: flex-end; gap: 8px; } +.network-result { padding-top: 5px; }.network-result h3 { margin: 7px 0 10px; font-size: 22px; }.network-result ol { padding-left: 22px; color: var(--text); font-size: 13px; line-height: 1.65; }.network-result p:not(.eyebrow) { color: var(--muted); font-size: 12px; line-height: 1.55; }.network-result > button { width: 100%; margin-top: 8px; } + +.toast-stack { position: fixed; z-index: 80; right: max(18px, env(safe-area-inset-right)); bottom: max(18px, env(safe-area-inset-bottom)); width: min(340px, calc(100vw - 36px)); display: grid; gap: 9px; pointer-events: none; } +.toast { padding: 13px 15px; display: grid; grid-template-columns: 8px 1fr; gap: 11px; align-items: center; border: 1px solid var(--line); border-radius: 15px; background: rgba(18, 22, 28, .96); box-shadow: 0 14px 45px rgba(0, 0, 0, .45); backdrop-filter: blur(15px); animation: toast-in .25s ease both; font-size: 11px; } +.toast i { width: 8px; height: 8px; border-radius: 50%; background: var(--green); box-shadow: 0 0 10px var(--green); }.toast.warn i { background: var(--yellow); box-shadow: 0 0 10px var(--yellow); }.toast.error i { background: var(--red); box-shadow: 0 0 10px var(--red); } +.toast.out { animation: toast-out .2s ease forwards; } +@keyframes toast-in { from { opacity: 0; transform: translateY(8px) scale(.98); } } +@keyframes toast-out { to { opacity: 0; transform: translateY(5px); } } + +.boot { position: fixed; z-index: 100; inset: 0; display: grid; place-content: center; justify-items: center; gap: 14px; background: #050608; transition: opacity .35s ease, visibility .35s ease; } +.boot.hidden { opacity: 0; visibility: hidden; } +.boot strong { margin-top: 9px; font-size: 25px; letter-spacing: -.04em; }.boot small { color: var(--muted); font-size: 10px; } +.boot-line { width: 110px; height: 2px; margin-top: 8px; overflow: hidden; border-radius: 2px; background: #18201c; }.boot-line i { display: block; width: 45%; height: 100%; background: var(--green); box-shadow: 0 0 12px var(--green); animation: boot-scan 1.05s ease-in-out infinite; } +@keyframes boot-scan { from { transform: translateX(-110%); } to { transform: translateX(245%); } } + +@media (max-width: 980px) { + .shell { grid-template-columns: 184px minmax(0, 1fr); }.sidebar { width: 184px; }.hero { grid-template-columns: 1fr 180px; }.radio-grid { grid-template-columns: 1fr; }.signal-card { grid-row: auto; }.packet-card { grid-column: 1 / -1; } +} + +@media (max-width: 760px) { + body { padding-bottom: calc(76px + env(safe-area-inset-bottom)); } + .shell { display: block; }.sidebar { inset: auto 0 0; width: auto; height: calc(65px + env(safe-area-inset-bottom)); padding: 0 8px env(safe-area-inset-bottom); border: 0; border-top: 1px solid rgba(255, 255, 255, .08); background: rgba(7, 9, 12, .92); } + .brand, .sidebar-foot { display: none; }.nav { height: 64px; display: grid; grid-template-columns: repeat(5, 1fr); gap: 1px; } + .nav button { min-height: 58px; padding: 7px 3px 5px; flex-direction: column; justify-content: center; gap: 3px; border-radius: 11px; text-align: center; } + .nav button.active { box-shadow: inset 0 2px var(--green); background: linear-gradient(180deg, rgba(68, 240, 138, .1), transparent); }.nav button span { font-size: 10px; }.nav button svg { width: 20px; height: 20px; }.nav button b { position: absolute; top: 4px; left: calc(50% + 7px); min-width: 17px; height: 17px; padding: 0 4px; font-size: 8px; } + main { width: 100%; padding: max(18px, env(safe-area-inset-top)) 14px 24px; }.topbar { min-height: 54px; margin-bottom: 14px; }.topbar h1 { font-size: 28px; }.battery, .link-chip { height: 44px; padding: 0 9px; }.battery { font-size: 10px; } + section[data-screen="home"].active { display: flex; flex-direction: column; } + .hero { min-height: 245px; padding: 24px; grid-template-columns: 1fr 105px; }.hero-copy h2 { font-size: clamp(36px, 12vw, 56px); }.mesh-orbit { width: 100px; }.mesh-orbit::before { inset: 14px; }.mesh-orbit::after { inset: 33px; }.mesh-orbit i:nth-child(1) { top: 9px; left: 49px; }.mesh-orbit i:nth-child(2) { right: 13px; bottom: 20px; }.mesh-orbit i:nth-child(3) { left: 8px; bottom: 33px; }.hero-stats { gap: 25px; overflow: hidden; }.hero-stats strong { font-size: 11px; } + .network-banner { grid-template-columns: 44px 1fr; }.network-banner .primary-button { grid-column: 1 / -1; width: 100%; }.dashboard-grid { order: -1; margin: 0 0 12px; grid-template-columns: 1fr; gap: 12px; }.feature-card { min-height: 156px; padding: 18px; }.feature-card .preview { margin: 12px 0 6px; }.radio-strip { grid-column: auto; grid-template-columns: 1fr; gap: 13px; }.radio-meta { justify-content: flex-start; } + .messages-layout { height: calc(100dvh - 153px); min-height: 520px; grid-template-columns: 1fr; }.threads-panel { display: none; }.conversation-head { min-height: 61px; padding: 10px 14px; }.message-list { padding: 15px 12px; }.bubble { max-width: 88%; }.composer { padding: 9px 10px max(10px, env(safe-area-inset-bottom)); } + .nearby-grid { grid-template-columns: 1fr; }.nearby-card { min-height: 112px; } + .radio-grid { gap: 12px; }.signal-card { padding: 20px; }.signal-readout { margin-top: 24px; }.metric { min-height: 112px; padding: 16px; }.packet-card { padding: 19px; }.packet-stats { grid-template-columns: 1fr 1fr; gap: 18px; } + .more-grid { grid-template-columns: 1fr; }.device-card { min-height: 410px; }.action-card, .about-card { align-items: flex-start; flex-direction: column; }.action-buttons { width: 100%; flex-direction: column; }.primary-button, .secondary-button { width: 100%; }.toast-stack { bottom: calc(78px + env(safe-area-inset-bottom)); }.network-dialog { padding: 20px; }.dialog-actions { flex-direction: column-reverse; }.dialog-actions button { width: 100%; } +} + +@media (max-width: 390px) { + .hero { grid-template-columns: 1fr; }.mesh-orbit { display: none; }.hero-stats { justify-content: space-between; gap: 12px; }.metric-grid { grid-template-columns: 1fr 1fr; }.metric strong { font-size: 23px; } +} + +@media (prefers-reduced-motion: reduce) { + *, *::before, *::after { scroll-behavior: auto !important; animation-duration: .01ms !important; animation-iteration-count: 1 !important; transition-duration: .01ms !important; } +} diff --git a/examples/companion_radio/webui/verify.mjs b/examples/companion_radio/webui/verify.mjs new file mode 100644 index 00000000..dac499b0 --- /dev/null +++ b/examples/companion_radio/webui/verify.mjs @@ -0,0 +1,26 @@ +import { gunzipSync } from "node:zlib"; +import { readFile } from "node:fs/promises"; + +const header = await readFile(new URL("./Rcc6WebUiAssets.h", import.meta.url), "utf8"); +const appSource = await readFile(new URL("./src/app.js", import.meta.url), "utf8"); +const body = header.match(/RCC6_WEB_UI_INDEX_GZ\[\] PROGMEM = \{([\s\S]*?)\n\};/); +if (!body) throw new Error("Generated gzip array is missing"); +const bytes = Uint8Array.from([...body[1].matchAll(/0x([0-9a-f]{2})/g)], (match) => Number.parseInt(match[1], 16)); +const html = gunzipSync(bytes).toString("utf8"); + +for (const required of [ + "Home", "Messages", "Nearby", "Radio", "More", "/api/frame", "/api/network", + "X-RCC6-Session", "application/x-www-form-urlencoded", "Set up local Wi-Fi", + "meshcore", "localStorage", "rcc6-radio-owner", "rcc6-history-pending-", "syncNextMessage", "MeshCore.js", +]) { + if (!html.includes(required)) throw new Error(`Built UI is missing ${required}`); +} +if (!header.includes("extern const size_t RCC6_WEB_UI_INDEX_GZ_LEN;")) throw new Error("Length declaration is missing"); +if (/]*src=|]*rel=[\"']stylesheet/i.test(html)) throw new Error("External runtime asset detected"); +if (html.includes("location.reload")) throw new Error("Reload-based transport recovery detected"); +if (html.includes("navigator.locks")) throw new Error("Secure-context Web Locks dependency detected"); +if (appSource.includes(".getWaitingMessages(")) throw new Error("Destructive batch message drain detected"); +for (const required of ["this.drainTask = this.drainRetainedFrames()", "if (!this.ready) throw"]) { + if (!appSource.includes(required)) throw new Error(`Takeover drain guard is missing ${required}`); +} +console.log(`Verified ${bytes.length}-byte RCC6 WebUI gzip asset`); diff --git a/src/helpers/esp32/SerialBLEInterface.cpp b/src/helpers/esp32/SerialBLEInterface.cpp index 0a7e1f3f..0682afbc 100644 --- a/src/helpers/esp32/SerialBLEInterface.cpp +++ b/src/helpers/esp32/SerialBLEInterface.cpp @@ -26,7 +26,8 @@ void SerialBLEInterface::begin(const char* prefix, char* name, uint32_t pin_code // Create the BLE Device BLEDevice::init(dev_name); BLEDevice::setSecurityCallbacks(this); - BLEDevice::setMTU(MAX_FRAME_SIZE); + // ATT notifications use three bytes of the negotiated MTU for protocol overhead. + BLEDevice::setMTU(MAX_FRAME_SIZE + 3); BLESecurity sec; sec.setStaticPIN(pin_code); @@ -93,16 +94,19 @@ void SerialBLEInterface::onConnect(BLEServer* pServer) { } void SerialBLEInterface::onConnect(BLEServer* pServer, esp_ble_gatts_cb_param_t *param) { - BLE_DEBUG_PRINTLN("onConnect(), conn_id=%d, mtu=%d", param->connect.conn_id, pServer->getPeerMTU(param->connect.conn_id)); + BLE_DEBUG_PRINTLN("onConnect(), conn_id=%d", param->connect.conn_id); last_conn_id = param->connect.conn_id; + peer_mtu = 23; } void SerialBLEInterface::onMtuChanged(BLEServer* pServer, esp_ble_gatts_cb_param_t* param) { - BLE_DEBUG_PRINTLN("onMtuChanged(), mtu=%d", pServer->getPeerMTU(param->mtu.conn_id)); + peer_mtu = param->mtu.mtu; + BLE_DEBUG_PRINTLN("onMtuChanged(), mtu=%d", peer_mtu); } void SerialBLEInterface::onDisconnect(BLEServer* pServer) { BLE_DEBUG_PRINTLN("onDisconnect()"); + peer_mtu = 23; if (_isEnabled) { adv_restart_time = millis() + ADVERT_RESTART_DELAY; @@ -157,6 +161,7 @@ void SerialBLEInterface::disable() { pServer->disconnect(last_conn_id); pService->stop(); oldDeviceConnected = deviceConnected = false; + peer_mtu = 23; adv_restart_time = 0; } @@ -167,6 +172,11 @@ size_t SerialBLEInterface::writeFrame(const uint8_t src[], size_t len) { } if (deviceConnected && len > 0) { + if (peer_mtu < len + 3) { + BLE_DEBUG_PRINTLN("writeFrame(), peer MTU too small, mtu=%d, len=%d", + peer_mtu, len); + return 0; + } if (send_queue_len >= SERIAL_BLE_FRAME_QUEUE_SIZE) { BLE_DEBUG_PRINTLN("writeFrame(), send_queue is full!"); return 0; diff --git a/src/helpers/esp32/SerialBLEInterface.h b/src/helpers/esp32/SerialBLEInterface.h index a0236eb5..748cad70 100644 --- a/src/helpers/esp32/SerialBLEInterface.h +++ b/src/helpers/esp32/SerialBLEInterface.h @@ -16,6 +16,7 @@ class SerialBLEInterface : public BaseSerialInterface, BLESecurityCallbacks, BLE bool oldDeviceConnected; bool _isEnabled; uint16_t last_conn_id; + uint16_t peer_mtu; uint32_t _pin_code; unsigned long _last_write; unsigned long adv_restart_time; @@ -66,6 +67,7 @@ class SerialBLEInterface : public BaseSerialInterface, BLESecurityCallbacks, BLE _isEnabled = false; _last_write = 0; last_conn_id = 0; + peer_mtu = 23; recv_queue = xQueueCreateStatic(SERIAL_BLE_FRAME_QUEUE_SIZE, sizeof(Frame), recv_queue_storage, &recv_queue_struct); send_queue_len = 0; } diff --git a/src/helpers/esp32/SerialWebInterface.cpp b/src/helpers/esp32/SerialWebInterface.cpp new file mode 100644 index 00000000..291188c5 --- /dev/null +++ b/src/helpers/esp32/SerialWebInterface.cpp @@ -0,0 +1,761 @@ +#ifdef RCC6_WEB_AP + +#include "SerialWebInterface.h" +#include +#include +#include +#include +#define RCC6_WEB_UI_ASSETS_IMPLEMENTATION +#include + +#include +#include + +namespace { +constexpr char PASSWORD_ALPHABET[] = "abcdefghjkmnpqrstuvwxyz"; +constexpr char HTTP_SESSION_HEADER[] = "X-RCC6-Session"; +constexpr char HTTP_ACK_HEADER[] = "X-RCC6-Ack"; +constexpr char HTTP_SEQUENCE_HEADER[] = "X-RCC6-Seq"; +constexpr char HTTP_AUTH_USER[] = "meshcore"; + +bool isSafeSsidChar(char c) { + return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || + (c >= '0' && c <= '9') || c == '-' || c == '_'; +} + +bool isAllowedHttpOpcode(uint8_t opcode) { + switch (opcode) { + case 1: // AppStart + case 2: // SendTxtMsg + case 3: // SendChannelTxtMsg + case 4: // GetContacts + case 7: // SendSelfAdvert + case 10: // SyncNextMessage + case 20: // GetBatteryVoltage + case 22: // DeviceQuery + case 31: // GetChannel + case 56: // GetStats + return true; + default: + return false; + } +} + +String jsonEscape(const char* value) { + String escaped; + if (value == nullptr) return escaped; + escaped.reserve(strlen(value) + 8); + constexpr char HEX_DIGITS[] = "0123456789abcdef"; + for (const uint8_t* p = reinterpret_cast(value); *p != 0; p++) { + if (*p == '"' || *p == '\\') { + escaped += '\\'; + escaped += static_cast(*p); + } else if (*p < 0x20) { + escaped += "\\u00"; + escaped += HEX_DIGITS[*p >> 4]; + escaped += HEX_DIGITS[*p & 0x0f]; + } else { + escaped += static_cast(*p); + } + } + return escaped; +} +} + +void SerialWebInterface::FrameQueue::clear() { + head = 0; + count = 0; +} + +bool SerialWebInterface::FrameQueue::full() const { + return count == FRAME_QUEUE_SIZE; +} + +bool SerialWebInterface::FrameQueue::empty() const { + return count == 0; +} + +bool SerialWebInterface::FrameQueue::push(const uint8_t* data, size_t len) { + if (data == nullptr || len < 1 || len > MAX_FRAME_SIZE || full()) return false; + + Frame& frame = frames[(head + count) % FRAME_QUEUE_SIZE]; + frame.len = static_cast(len); + memcpy(frame.data, data, len); + count++; + return true; +} + +SerialWebInterface::Frame* SerialWebInterface::FrameQueue::front() { + return empty() ? nullptr : &frames[head]; +} + +void SerialWebInterface::FrameQueue::pop() { + if (empty()) return; + head = (head + 1) % FRAME_QUEUE_SIZE; + count--; +} + +size_t SerialWebInterface::FrameQueue::pop(uint8_t* dest) { + Frame* frame = front(); + if (frame == nullptr || dest == nullptr) return 0; + + const size_t len = frame->len; + memcpy(dest, frame->data, len); + pop(); + return len; +} + +SerialWebInterface::SerialWebInterface() + : _initialized(false), _enabled(false), _routes_registered(false), + _tcp_connected(false), _tcp_port(5000), _ap_ssid{}, _ap_password{}, + _prefer_station(false), _station_active(false), _fallback_active(false), + _station_ssid{}, _station_password{}, _current_ip(), _restart_at(0), + _tcp_server(), _tcp_client(), _http_server(80), _session(Session::NONE), + _http_remote(), _http_session_id{}, _http_last_activity(0), + _http_inflight_seq(0), _http_next_seq(1), _recv_queue{}, _send_queue{}, + _tcp_rx_state(TcpRxState::MARKER), _tcp_rx_length(0), _tcp_rx_offset(0), + _tcp_rx_data{}, _tcp_tx_data{}, _tcp_tx_length(0), _tcp_tx_offset(0), + _http_post_result(HttpPostResult::NONE), _http_post_expected(0), + _http_post_length(0), _http_post_data{} { + _recv_queue.clear(); + _send_queue.clear(); +} + +void SerialWebInterface::begin(const char* node_name, uint16_t tcp_port) { + _tcp_port = tcp_port == 0 ? 5000 : tcp_port; + configureIdentity(node_name); + registerHttpRoutes(); + _initialized = true; +} + +IPAddress SerialWebInterface::getApIP() const { + return IPAddress(192, 168, 4, 1); +} + +const char* SerialWebInterface::getCurrentSsid() const { + return _station_active ? _station_ssid : _ap_ssid; +} + +void SerialWebInterface::configureIdentity(const char* node_name) { + char suffix[24] = {}; + size_t out = 0; + bool last_was_separator = false; + + if (node_name != nullptr) { + for (size_t i = 0; node_name[i] != '\0' && out < sizeof(suffix) - 1; i++) { + const char c = node_name[i]; + if (isSafeSsidChar(c)) { + suffix[out++] = c; + last_was_separator = false; + } else if (out > 0 && !last_was_separator) { + suffix[out++] = '-'; + last_was_separator = true; + } + } + } + while (out > 0 && suffix[out - 1] == '-') out--; + suffix[out] = '\0'; + if (out == 0) strcpy(suffix, "RCC6"); + snprintf(_ap_ssid, sizeof(_ap_ssid), "MeshCore-%s", suffix); + + Preferences preferences; + String password; + String station_ssid; + String station_password; + const bool opened = preferences.begin("rcc6-web", false); + if (opened) { + if (preferences.isKey("ap-pass")) password = preferences.getString("ap-pass", ""); + if (preferences.isKey("sta-mode")) _prefer_station = preferences.getBool("sta-mode", false); + if (preferences.isKey("sta-ssid")) station_ssid = preferences.getString("sta-ssid", ""); + if (preferences.isKey("sta-pass")) station_password = preferences.getString("sta-pass", ""); + } + + if (password.length() != sizeof(_ap_password) - 1) { + for (size_t i = 0; i < sizeof(_ap_password) - 1; i++) { + _ap_password[i] = PASSWORD_ALPHABET[esp_random() % (sizeof(PASSWORD_ALPHABET) - 1)]; + } + _ap_password[sizeof(_ap_password) - 1] = '\0'; + if (opened) preferences.putString("ap-pass", _ap_password); + } else { + password.toCharArray(_ap_password, sizeof(_ap_password)); + } + + const bool valid_station = station_ssid.length() >= 1 && station_ssid.length() <= 32 && + (station_password.length() == 0 || + (station_password.length() >= 8 && station_password.length() <= 64)); + if (valid_station) { + station_ssid.toCharArray(_station_ssid, sizeof(_station_ssid)); + station_password.toCharArray(_station_password, sizeof(_station_password)); + } else { + _prefer_station = false; + _station_ssid[0] = '\0'; + _station_password[0] = '\0'; + } + + if (opened) preferences.end(); +} + +void SerialWebInterface::registerHttpRoutes() { + if (_routes_registered) return; + + static const char* collected_headers[] = { HTTP_SESSION_HEADER, HTTP_ACK_HEADER }; + _http_server.collectHeaders(collected_headers, + sizeof(collected_headers) / sizeof(collected_headers[0])); + _http_server.on("/", HTTP_GET, [this]() { handleIndex(); }); + _http_server.on("/index.html", HTTP_GET, [this]() { handleIndex(); }); + _http_server.on("/api/frame", HTTP_GET, [this]() { handleHttpGetFrame(); }); + _http_server.on("/api/frame", HTTP_POST, + [this]() { handleHttpPostFrame(); }, + [this]() { handleHttpPostRaw(); }); + _http_server.on("/api/network", HTTP_GET, [this]() { handleHttpGetNetwork(); }); + _http_server.on("/api/network", HTTP_POST, [this]() { handleHttpPostNetwork(); }); + _http_server.onNotFound([this]() { + if (httpAuthorized()) sendHttpStatus(404); + }); + _routes_registered = true; +} + +bool SerialWebInterface::startAccessPoint() { + WiFi.mode(WIFI_AP); + const IPAddress ap_ip = getApIP(); + if (!WiFi.softAPConfig(ap_ip, ap_ip, IPAddress(255, 255, 255, 0)) || + !WiFi.softAP(_ap_ssid, _ap_password, 1, false, 1)) { + WiFi.softAPdisconnect(true); + Serial.println("Web AP: failed to start"); + return false; + } + + _station_active = false; + _current_ip = ap_ip; + return true; +} + +void SerialWebInterface::startServers() { + _tcp_server.begin(_tcp_port); + _tcp_server.setNoDelay(true); + _http_server.begin(); + _enabled = true; +} + +void SerialWebInterface::enable() { + if (_enabled || !_initialized) return; + + clearSession(); + _station_active = false; + _fallback_active = false; + _current_ip = IPAddress(); + + if (_prefer_station && _station_ssid[0] != '\0') { + WiFi.mode(WIFI_STA); + WiFi.setAutoReconnect(true); + WiFi.begin(_station_ssid, _station_password); + const uint32_t started = millis(); + while (WiFi.status() != WL_CONNECTED && + static_cast(millis() - started) < STA_CONNECT_TIMEOUT_MS) { + delay(50); + } + + const IPAddress station_ip = WiFi.localIP(); + const bool has_ip = station_ip[0] != 0 || station_ip[1] != 0 || + station_ip[2] != 0 || station_ip[3] != 0; + if (WiFi.status() == WL_CONNECTED && has_ip) { + _station_active = true; + _current_ip = station_ip; + startServers(); + Serial.printf("Web WiFi: %s at %s (HTTP, TCP/%u)\n", + _station_ssid, station_ip.toString().c_str(), _tcp_port); + return; + } + + Serial.printf("Web WiFi: failed to join %s; starting setup AP\n", _station_ssid); + WiFi.disconnect(true, false); + if (!saveNetworkConfig(false, String(), String())) { + _prefer_station = false; + _station_ssid[0] = '\0'; + _station_password[0] = '\0'; + Serial.println("Web WiFi: failed to persist setup AP fallback"); + } + _fallback_active = true; + } + + if (!startAccessPoint()) return; + startServers(); + Serial.printf("Web AP: %s at %s (HTTP, TCP/%u)%s\n", + _ap_ssid, _current_ip.toString().c_str(), _tcp_port, + _fallback_active ? " [station fallback]" : ""); +} + +void SerialWebInterface::disable() { + if (!_enabled) return; + + _enabled = false; + _http_server.stop(); + _tcp_server.end(); + clearSession(); + if (_station_active) { + WiFi.disconnect(true, false); + } else { + WiFi.softAPdisconnect(true); + } + _station_active = false; + _fallback_active = false; + _current_ip = IPAddress(); +} + +bool SerialWebInterface::isConnected() const { + if (!_enabled) return false; + if (_session == Session::TCP) return _tcp_connected; + if (_session == Session::HTTP) { + return static_cast(millis() - _http_last_activity) < HTTP_SESSION_TIMEOUT_MS; + } + return false; +} + +bool SerialWebInterface::isWriteBusy() const { + return static_cast(_recv_queue.count) + _send_queue.count >= FRAME_QUEUE_SIZE; +} + +size_t SerialWebInterface::writeFrame(const uint8_t src[], size_t len) { + if (!isConnected() || isWriteBusy() || src == nullptr || len < 1 || len > MAX_FRAME_SIZE) return 0; + return _send_queue.push(src, len) ? len : 0; +} + +size_t SerialWebInterface::checkRecvFrame(uint8_t dest[]) { + if (_restart_at != 0 && static_cast(millis() - _restart_at) >= 0) { + ESP.restart(); + } + if (!_enabled) return 0; + if (_station_active && WiFi.status() == WL_CONNECTED) _current_ip = WiFi.localIP(); + + expireHttpSession(); + _http_server.handleClient(); + serviceTcp(); + return _recv_queue.pop(dest); +} + +bool SerialWebInterface::saveNetworkConfig(bool station, const String& ssid, + const String& password) { + Preferences preferences; + if (!preferences.begin("rcc6-web", false)) return false; + + // Disable station preference first so a partial NVS write always boots the setup AP. + bool saved = preferences.putBool("sta-mode", false) == sizeof(bool); + if (station && saved) { + saved = preferences.putString("sta-ssid", ssid) == ssid.length(); + if (password.length() == 0) { + if (preferences.isKey("sta-pass")) saved = preferences.remove("sta-pass") && saved; + } else { + saved = preferences.putString("sta-pass", password) == password.length() && saved; + } + } else if (!station && saved) { + if (preferences.isKey("sta-ssid")) saved = preferences.remove("sta-ssid") && saved; + if (preferences.isKey("sta-pass")) saved = preferences.remove("sta-pass") && saved; + } + if (station && saved) saved = preferences.putBool("sta-mode", true) == sizeof(bool); + preferences.end(); + + if (saved) { + _prefer_station = station; + if (station) { + ssid.toCharArray(_station_ssid, sizeof(_station_ssid)); + password.toCharArray(_station_password, sizeof(_station_password)); + } else { + _station_ssid[0] = '\0'; + _station_password[0] = '\0'; + } + } + return saved; +} + +void SerialWebInterface::scheduleRestart() { + _restart_at = millis() + RESTART_DELAY_MS; + if (_restart_at == 0) _restart_at = 1; +} + +bool SerialWebInterface::selectSetupAp() { + if (!saveNetworkConfig(false, String(), String())) return false; + scheduleRestart(); + return true; +} + +bool SerialWebInterface::clearStoredNetworkConfig() { + Preferences preferences; + if (!preferences.begin("rcc6-web", false)) return false; + const bool cleared = preferences.clear(); + preferences.end(); + if (cleared) { + WiFi.disconnect(true, true); + _prefer_station = false; + _station_ssid[0] = '\0'; + _station_password[0] = '\0'; + } + return cleared; +} + +void SerialWebInterface::clearSession() { + if (_tcp_client) _tcp_client.stop(); + _tcp_client = WiFiClient(); + _tcp_connected = false; + _session = Session::NONE; + _http_remote = IPAddress(); + _http_session_id[0] = '\0'; + _http_last_activity = 0; + _http_inflight_seq = 0; + _recv_queue.clear(); + _send_queue.clear(); + _tcp_tx_length = 0; + _tcp_tx_offset = 0; + _http_post_result = HttpPostResult::NONE; + _http_post_expected = 0; + _http_post_length = 0; + resetTcpParser(); +} + +void SerialWebInterface::resetTcpParser() { + _tcp_rx_state = TcpRxState::MARKER; + _tcp_rx_length = 0; + _tcp_rx_offset = 0; +} + +void SerialWebInterface::expireHttpSession() { + if (_session == Session::HTTP && + static_cast(millis() - _http_last_activity) >= HTTP_SESSION_TIMEOUT_MS && + _recv_queue.empty() && _send_queue.empty() && _http_inflight_seq == 0) { + clearSession(); + } +} + +bool SerialWebInterface::httpSessionTokenValid(const String& token) const { + if (token.length() != 32) return false; + for (size_t i = 0; i < 32; i++) { + const char c = token[i]; + if (!((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || + (c >= 'A' && c <= 'F'))) return false; + } + return true; +} + +bool SerialWebInterface::claimHttpSession() { + expireHttpSession(); + const IPAddress remote = _http_server.client().remoteIP(); + const String token = _http_server.header(HTTP_SESSION_HEADER); + + if (!httpSessionTokenValid(token)) return false; + + if (_session == Session::TCP) { + if (_tcp_client.connected()) return false; + clearSession(); + } + if (_session == Session::HTTP && + (_http_remote != remote || strncmp(_http_session_id, token.c_str(), 32) != 0)) { + if (static_cast(millis() - _http_last_activity) < HTTP_SESSION_TIMEOUT_MS) { + return false; + } + // The old controller is gone. Preserve outbound/in-flight responses for the + // new browser to drain, but discard commands the abandoned controller queued. + _recv_queue.clear(); + _http_post_result = HttpPostResult::NONE; + _http_post_expected = 0; + _http_post_length = 0; + _http_remote = remote; + token.toCharArray(_http_session_id, sizeof(_http_session_id)); + } + if (_session == Session::NONE) { + _session = Session::HTTP; + _http_remote = remote; + token.toCharArray(_http_session_id, sizeof(_http_session_id)); + } + _http_last_activity = millis(); + return true; +} + +bool SerialWebInterface::acknowledgeHttpFrame() { + if (_http_inflight_seq == 0) return false; + const String value = _http_server.header(HTTP_ACK_HEADER); + if (value.length() < 1 || value.length() > 10) return false; + + char* end = nullptr; + const unsigned long ack = strtoul(value.c_str(), &end, 10); + if (end == value.c_str() || *end != '\0' || ack != _http_inflight_seq) return false; + + _send_queue.pop(); + _http_inflight_seq = 0; + return true; +} + +uint32_t SerialWebInterface::nextHttpSequence() { + uint32_t sequence = _http_next_seq++; + if (sequence == 0) sequence = _http_next_seq++; + return sequence; +} + +void SerialWebInterface::rejectTcpClient(WiFiClient& client) { + client.stop(); +} + +void SerialWebInterface::serviceTcp() { + if (_session == Session::TCP && !_tcp_client.connected()) clearSession(); + + WiFiClient incoming = _tcp_server.accept(); + if (incoming) { + if (_session == Session::NONE) { + _tcp_client = incoming; + _tcp_client.setNoDelay(true); + _tcp_connected = true; + _session = Session::TCP; + resetTcpParser(); + } else { + rejectTcpClient(incoming); + } + } + + if (_session != Session::TCP) return; + + serviceTcpWrite(); + serviceTcpRead(); +} + +void SerialWebInterface::serviceTcpRead() { + size_t budget = TCP_READ_BUDGET; + while (budget-- > 0 && _tcp_client.available() > 0) { + if (_tcp_rx_state == TcpRxState::MARKER && isWriteBusy()) return; + + const int value = _tcp_client.read(); + if (value < 0) return; + const uint8_t byte = static_cast(value); + + switch (_tcp_rx_state) { + case TcpRxState::MARKER: + if (byte == '<') _tcp_rx_state = TcpRxState::LENGTH_LOW; + break; + case TcpRxState::LENGTH_LOW: + _tcp_rx_length = byte; + _tcp_rx_state = TcpRxState::LENGTH_HIGH; + break; + case TcpRxState::LENGTH_HIGH: + _tcp_rx_length |= static_cast(byte) << 8; + if (_tcp_rx_length < 1 || _tcp_rx_length > MAX_FRAME_SIZE) { + _tcp_client.stop(); + clearSession(); + return; + } + _tcp_rx_offset = 0; + _tcp_rx_state = TcpRxState::PAYLOAD; + break; + case TcpRxState::PAYLOAD: + _tcp_rx_data[_tcp_rx_offset++] = byte; + if (_tcp_rx_offset == _tcp_rx_length) { + _recv_queue.push(_tcp_rx_data, _tcp_rx_length); + resetTcpParser(); + } + break; + } + } +} + +void SerialWebInterface::serviceTcpWrite() { + if (_tcp_tx_length == 0) { + Frame* frame = _send_queue.front(); + if (frame == nullptr) return; + _tcp_tx_data[0] = '>'; + _tcp_tx_data[1] = frame->len & 0xff; + _tcp_tx_data[2] = frame->len >> 8; + memcpy(&_tcp_tx_data[3], frame->data, frame->len); + _tcp_tx_length = frame->len + 3; + _tcp_tx_offset = 0; + } + + const int fd = _tcp_client.fd(); + if (fd < 0) return; + const int sent = ::send(fd, _tcp_tx_data + _tcp_tx_offset, + _tcp_tx_length - _tcp_tx_offset, MSG_DONTWAIT); + if (sent > 0) { + _tcp_tx_offset += static_cast(sent); + if (_tcp_tx_offset == _tcp_tx_length) { + _send_queue.pop(); + _tcp_tx_length = 0; + _tcp_tx_offset = 0; + } + } else if (sent < 0 && errno != EAGAIN && errno != EWOULDBLOCK) { + _tcp_client.stop(); + clearSession(); + } +} + +bool SerialWebInterface::httpAuthorized() { + if (!_station_active || _http_server.authenticate(HTTP_AUTH_USER, _ap_password)) return true; + _http_server.requestAuthentication(); + return false; +} + +void SerialWebInterface::handleIndex() { + if (!httpAuthorized()) return; + _http_server.sendHeader("Content-Encoding", "gzip"); + _http_server.sendHeader("Cache-Control", "no-store"); + _http_server.sendHeader("X-Content-Type-Options", "nosniff"); + _http_server.send_P(200, PSTR("text/html; charset=utf-8"), + reinterpret_cast(RCC6_WEB_UI_INDEX_GZ), RCC6_WEB_UI_INDEX_GZ_LEN); +} + +void SerialWebInterface::handleHttpGetFrame() { + if (!httpAuthorized()) return; + if (!claimHttpSession()) { + sendHttpStatus(409); + return; + } + + acknowledgeHttpFrame(); + Frame* frame = _send_queue.front(); + if (frame == nullptr) { + sendHttpStatus(204); + return; + } + + if (_http_inflight_seq == 0) _http_inflight_seq = nextHttpSequence(); + _http_server.sendHeader("Cache-Control", "no-store"); + _http_server.sendHeader(HTTP_SEQUENCE_HEADER, String(_http_inflight_seq)); + _http_server.setContentLength(frame->len); + _http_server.send(200, "application/octet-stream", ""); + _http_server.sendContent(reinterpret_cast(frame->data), frame->len); +} + +void SerialWebInterface::handleHttpPostRaw() { + HTTPRaw& raw = _http_server.raw(); + switch (raw.status) { + case RAW_START: + _http_post_length = 0; + _http_post_expected = static_cast(_http_server.clientContentLength()); + _http_server.client().setTimeout(HTTP_BODY_TIMEOUT_MS); + if (_http_server.clientContentLength() < 1 || + _http_server.clientContentLength() > MAX_FRAME_SIZE) { + _http_post_result = HttpPostResult::INVALID; + _http_server.client().stop(); + } else if (_station_active && !_http_server.authenticate(HTTP_AUTH_USER, _ap_password)) { + _http_post_result = HttpPostResult::UNAUTHORIZED; + } else if (!claimHttpSession()) { + _http_post_result = HttpPostResult::CONFLICT; + } else if (isWriteBusy()) { + _http_post_result = HttpPostResult::FULL; + } else { + _http_post_result = HttpPostResult::PENDING; + } + break; + case RAW_WRITE: + if (_http_post_result == HttpPostResult::PENDING) { + if (_http_post_length + raw.currentSize > MAX_FRAME_SIZE) { + _http_post_result = HttpPostResult::INVALID; + } else { + memcpy(_http_post_data + _http_post_length, raw.buf, raw.currentSize); + _http_post_length += raw.currentSize; + } + } + break; + case RAW_END: + if (_http_post_result == HttpPostResult::PENDING) { + if (_http_post_length != _http_post_expected) { + _http_post_result = HttpPostResult::INVALID; + } else if (!isAllowedHttpOpcode(_http_post_data[0])) { + _http_post_result = HttpPostResult::FORBIDDEN; + } else if (_recv_queue.push(_http_post_data, _http_post_length)) { + _http_post_result = HttpPostResult::ACCEPTED; + } else { + _http_post_result = HttpPostResult::FULL; + } + } + break; + case RAW_ABORTED: + _http_post_result = HttpPostResult::ABORTED; + break; + } +} + +void SerialWebInterface::handleHttpPostFrame() { + switch (_http_post_result) { + case HttpPostResult::ACCEPTED: + sendHttpStatus(204); + break; + case HttpPostResult::UNAUTHORIZED: + _http_server.requestAuthentication(); + break; + case HttpPostResult::FORBIDDEN: + sendHttpStatus(403); + break; + case HttpPostResult::CONFLICT: + sendHttpStatus(409); + break; + case HttpPostResult::FULL: + sendHttpStatus(429); + break; + case HttpPostResult::INVALID: + case HttpPostResult::ABORTED: + case HttpPostResult::NONE: + case HttpPostResult::PENDING: + sendHttpStatus(400); + break; + } + _http_post_result = HttpPostResult::NONE; +} + +void SerialWebInterface::handleHttpGetNetwork() { + if (!httpAuthorized()) return; + if (!claimHttpSession()) { + sendHttpStatus(409); + return; + } + + String response; + response.reserve(128); + response += F("{\"mode\":\""); + response += _station_active ? F("station") : F("ap"); + response += F("\",\"ssid\":\""); + response += jsonEscape(getCurrentSsid()); + response += F("\",\"ip\":\""); + response += _current_ip.toString(); + response += F("\",\"fallback\":"); + response += _fallback_active ? F("true") : F("false"); + response += '}'; + _http_server.sendHeader("Cache-Control", "no-store"); + _http_server.send(200, "application/json", response); +} + +void SerialWebInterface::handleHttpPostNetwork() { + if (!httpAuthorized()) return; + if (!claimHttpSession()) { + sendHttpStatus(409); + return; + } + + const String mode = _http_server.arg("mode"); + if (mode == "ap") { + if (!saveNetworkConfig(false, String(), String())) { + sendHttpStatus(500); + return; + } + } else if (mode == "station") { + const String ssid = _http_server.arg("ssid"); + const String password = _http_server.arg("password"); + if (ssid.length() < 1 || ssid.length() > 32 || + (password.length() != 0 && (password.length() < 8 || password.length() > 64))) { + sendHttpStatus(400); + return; + } + if (!saveNetworkConfig(true, ssid, password)) { + sendHttpStatus(500); + return; + } + } else { + sendHttpStatus(400); + return; + } + + _http_server.sendHeader("Cache-Control", "no-store"); + _http_server.send(202, "application/json", "{\"ok\":true,\"restart\":true}"); + scheduleRestart(); +} + +void SerialWebInterface::sendHttpStatus(int status) { + _http_server.sendHeader("Cache-Control", "no-store"); + _http_server.send(status, "text/plain", ""); +} + +#endif diff --git a/src/helpers/esp32/SerialWebInterface.h b/src/helpers/esp32/SerialWebInterface.h new file mode 100644 index 00000000..2d31ea9e --- /dev/null +++ b/src/helpers/esp32/SerialWebInterface.h @@ -0,0 +1,131 @@ +#pragma once + +#include "../BaseSerialInterface.h" +#include +#include + +class SerialWebInterface : public BaseSerialInterface { +public: + SerialWebInterface(); + + void begin(const char* node_name, uint16_t tcp_port = 5000); + + void enable() override; + void disable() override; + bool isEnabled() const override { return _enabled; } + bool isConnected() const override; + bool isWriteBusy() const override; + size_t writeFrame(const uint8_t src[], size_t len) override; + size_t checkRecvFrame(uint8_t dest[]) override; + + const char* getApSsid() const { return _ap_ssid; } + const char* getApPassword() const { return _ap_password; } + IPAddress getApIP() const; + bool isStationMode() const { return _station_active; } + const char* getCurrentSsid() const; + IPAddress getCurrentIP() const { return _current_ip; } + bool isFallbackActive() const { return _fallback_active; } + bool selectSetupAp(); + bool clearStoredNetworkConfig(); + +private: + static constexpr uint8_t FRAME_QUEUE_SIZE = 8; + static constexpr uint32_t HTTP_SESSION_TIMEOUT_MS = 10000; + static constexpr uint32_t HTTP_BODY_TIMEOUT_MS = 250; + static constexpr uint32_t STA_CONNECT_TIMEOUT_MS = 15000; + static constexpr uint32_t RESTART_DELAY_MS = 750; + static constexpr size_t TCP_READ_BUDGET = 384; + + struct Frame { + uint16_t len; + uint8_t data[MAX_FRAME_SIZE]; + }; + + struct FrameQueue { + Frame frames[FRAME_QUEUE_SIZE]; + uint8_t head; + uint8_t count; + + void clear(); + bool full() const; + bool empty() const; + bool push(const uint8_t* data, size_t len); + Frame* front(); + void pop(); + size_t pop(uint8_t* dest); + }; + + enum class Session : uint8_t { NONE, TCP, HTTP }; + enum class TcpRxState : uint8_t { MARKER, LENGTH_LOW, LENGTH_HIGH, PAYLOAD }; + enum class HttpPostResult : uint8_t { + NONE, PENDING, ACCEPTED, INVALID, UNAUTHORIZED, FORBIDDEN, CONFLICT, FULL, ABORTED + }; + + bool _initialized; + bool _enabled; + bool _routes_registered; + bool _tcp_connected; + uint16_t _tcp_port; + char _ap_ssid[33]; + char _ap_password[9]; + bool _prefer_station; + bool _station_active; + bool _fallback_active; + char _station_ssid[33]; + char _station_password[65]; + IPAddress _current_ip; + uint32_t _restart_at; + + WiFiServer _tcp_server; + WiFiClient _tcp_client; + WebServer _http_server; + Session _session; + IPAddress _http_remote; + char _http_session_id[33]; + uint32_t _http_last_activity; + uint32_t _http_inflight_seq; + uint32_t _http_next_seq; + + FrameQueue _recv_queue; + FrameQueue _send_queue; + + TcpRxState _tcp_rx_state; + uint16_t _tcp_rx_length; + uint16_t _tcp_rx_offset; + uint8_t _tcp_rx_data[MAX_FRAME_SIZE]; + uint8_t _tcp_tx_data[MAX_FRAME_SIZE + 3]; + uint16_t _tcp_tx_length; + uint16_t _tcp_tx_offset; + + HttpPostResult _http_post_result; + uint16_t _http_post_expected; + uint16_t _http_post_length; + uint8_t _http_post_data[MAX_FRAME_SIZE]; + + void configureIdentity(const char* node_name); + void registerHttpRoutes(); + bool startAccessPoint(); + void startServers(); + bool httpAuthorized(); + bool saveNetworkConfig(bool station, const String& ssid, const String& password); + void scheduleRestart(); + void clearSession(); + void resetTcpParser(); + void expireHttpSession(); + bool claimHttpSession(); + bool httpSessionTokenValid(const String& token) const; + bool acknowledgeHttpFrame(); + uint32_t nextHttpSequence(); + void serviceTcp(); + void serviceTcpRead(); + void serviceTcpWrite(); + void rejectTcpClient(WiFiClient& client); + + void handleIndex(); + void handleHttpGetFrame(); + void handleHttpPostFrame(); + void handleHttpPostRaw(); + void handleHttpGetNetwork(); + void handleHttpPostNetwork(); + void sendHttpStatus(int status); +}; diff --git a/src/helpers/ui/NV3001BDisplay.cpp b/src/helpers/ui/NV3001BDisplay.cpp index c277548c..ab6175e7 100644 --- a/src/helpers/ui/NV3001BDisplay.cpp +++ b/src/helpers/ui/NV3001BDisplay.cpp @@ -527,11 +527,15 @@ void NV3001BDisplay::fillPhysicalRect(int x, int y, int w, int h) { } void NV3001BDisplay::drawChar(int x, int y, char ch) { - if (ch < 32 || ch > 127) ch = '?'; - - uint16_t index = (uint16_t)(ch - 32) * 5; int scale_x = textPixelScaleX(text_size); int scale_y = textPixelScaleY(text_size); + if ((uint8_t)ch == 0xDB) { + fillPhysicalRect(x, y, 5 * scale_x, 7 * scale_y); + return; + } + if ((uint8_t)ch < 32 || (uint8_t)ch > 127) ch = '?'; + + uint16_t index = (uint16_t)(ch - 32) * 5; for (int col = 0; col < 5; col++) { uint8_t line = pgm_read_byte(font5x7 + index + col); for (int row = 0; row < 7; row++) { diff --git a/variants/heltec_rcc6/platformio.ini b/variants/heltec_rcc6/platformio.ini index a0936f8c..30fecace 100644 --- a/variants/heltec_rcc6/platformio.ini +++ b/variants/heltec_rcc6/platformio.ini @@ -207,6 +207,33 @@ lib_deps = ${heltec_rcc6_with_display.lib_deps} densaugeo/base64 @ ~1.4.0 +[env:heltec_rcc6_companion_radio_web_ap] +extends = heltec_rcc6_with_display +build_flags = + ${heltec_rcc6_with_display.build_flags} + -D HELTEC_RCC6_NEON_UI=1 + -D NV3001B_USE_FRAMEBUFFER=1 + -D NV3001B_LOGICAL_WIDTH=220 + -D NV3001B_LOGICAL_HEIGHT=128 + -D NV3001B_SCREEN_WIDTH=220 + -D NV3001B_SCREEN_HEIGHT=128 + -D AUTO_OFF_MILLIS=60000 + -I examples/companion_radio/ui-new + -I examples/companion_radio/webui + -D MAX_CONTACTS=350 + -D MAX_GROUP_CHANNELS=40 + -D RCC6_WEB_AP=1 + -D TCP_PORT=5000 + -D OFFLINE_QUEUE_SIZE=256 +build_src_filter = ${heltec_rcc6_with_display.build_src_filter} + + + - + +<../examples/companion_radio/*.cpp> + +<../examples/companion_radio/ui-new/*.cpp> +lib_deps = + ${heltec_rcc6_with_display.lib_deps} + densaugeo/base64 @ ~1.4.0 + [env:heltec_rcc6_companion_radio_usb] extends = heltec_rcc6_with_display build_flags =