diff --git a/PCB/Remote.kicad_pcb b/PCB/Remote.kicad_pcb index 86f336c..d606f9b 100644 --- a/PCB/Remote.kicad_pcb +++ b/PCB/Remote.kicad_pcb @@ -1029,7 +1029,7 @@ (property "ki_keywords" "cap capacitor") (path "/5d818a81-71ff-4f40-8854-04efda688b48") (attr smd) - (fp_text reference "C13" (at -3.25 -1.68) (layer "F.SilkS") + (fp_text reference "C13" (at -3.238895 0.068182) (layer "F.SilkS") (effects (font (size 1 1) (thickness 0.15))) (tstamp 15439bba-04d4-4528-ad0e-855324eb39a5) ) @@ -6445,7 +6445,7 @@ (property "ki_keywords" "cap capacitor") (path "/a888a00f-5496-4d09-af9f-455dba2d8767") (attr smd) - (fp_text reference "C14" (at 3.5 -1.85) (layer "F.SilkS") + (fp_text reference "C14" (at 3.488895 -0.14998) (layer "F.SilkS") (effects (font (size 1 1) (thickness 0.15))) (tstamp 5ecdc16d-4df0-4830-8429-f936a2864918) ) diff --git a/PCB/production/gerber.zip b/PCB/production/gerber.zip index 9d44031..9aae989 100644 Binary files a/PCB/production/gerber.zip and b/PCB/production/gerber.zip differ diff --git a/Platformio/.vscode/settings.json b/Platformio/.vscode/settings.json index df05048..0745d47 100644 --- a/Platformio/.vscode/settings.json +++ b/Platformio/.vscode/settings.json @@ -1,6 +1,7 @@ { "cmake.configureOnOpen": false, "files.associations": { + "*.json": "jsonc", "random": "cpp", "array": "cpp", "atomic": "cpp", @@ -50,7 +51,34 @@ "stdexcept": "cpp", "streambuf": "cpp", "cinttypes": "cpp", - "typeinfo": "cpp" + "typeinfo": "cpp", + "bit": "cpp", + "compare": "cpp", + "concepts": "cpp", + "numbers": "cpp", + "any": "cpp", + "hash_map": "cpp", + "strstream": "cpp", + "bitset": "cpp", + "charconv": "cpp", + "chrono": "cpp", + "complex": "cpp", + "condition_variable": "cpp", + "forward_list": "cpp", + "list": "cpp", + "ratio": "cpp", + "format": "cpp", + "future": "cpp", + "mutex": "cpp", + "semaphore": "cpp", + "shared_mutex": "cpp", + "span": "cpp", + "stop_token": "cpp", + "thread": "cpp", + "cfenv": "cpp", + "typeindex": "cpp", + "valarray": "cpp", + "variant": "cpp" }, "cmake.sourceDirectory": "${workspaceFolder}/.pio/libdeps/esp32/Adafruit BusIO", "editor.formatOnSave": false, diff --git a/Platformio/HAL/Architecture.png b/Platformio/HAL/Architecture.png new file mode 100644 index 0000000..88deb45 Binary files /dev/null and b/Platformio/HAL/Architecture.png differ diff --git a/Platformio/HAL/Architecture.puml b/Platformio/HAL/Architecture.puml new file mode 100644 index 0000000..11696e8 --- /dev/null +++ b/Platformio/HAL/Architecture.puml @@ -0,0 +1,40 @@ +@startuml +' KEY +' --> : is a +' *-- : must have +' o-- : should have + +namespace HAL{ + interface BatteryInterface + interface WifiInterface + interface OtherHWInterface + + abstract HardwareAbstract + + HardwareAbstract o-- BatteryInterface + HardwareAbstract o-- WifiInterface + HardwareAbstract o-- OtherHWInterface +} + +namespace Simulator{ + class BatterySimulator + class WifiSimulator + BatterySimulator --> HAL.BatteryInterface + WifiSimulator --> HAL.WifiInterface +} + +namespace ESP32{ + class Battery + class WifiHandler + Battery --> HAL.BatteryInterface + WifiHandler --> HAL.WifiInterface +} + + +namespace UI { + class OmoteUI + OmoteUI *-- HAL.HardwareAbstract +} + + +@enduml \ No newline at end of file diff --git a/Platformio/HAL/HardwareAbstract.cpp b/Platformio/HAL/HardwareAbstract.cpp new file mode 100644 index 0000000..ee40bcc --- /dev/null +++ b/Platformio/HAL/HardwareAbstract.cpp @@ -0,0 +1,5 @@ +#include "HardwareAbstract.hpp" + +HardwareAbstract::HardwareAbstract(){ + +} diff --git a/Platformio/HAL/HardwareAbstract.hpp b/Platformio/HAL/HardwareAbstract.hpp new file mode 100644 index 0000000..b8f8e84 --- /dev/null +++ b/Platformio/HAL/HardwareAbstract.hpp @@ -0,0 +1,30 @@ +// OMOTE Hardware Abstraction +// 2023 Matthew Colvin +#pragma once +#include "BatteryInterface.h" +#include "DisplayAbstract.h" +#include "wifiHandlerInterface.h" + +#include "Notification.hpp" + +#include + +class HardwareAbstract { +public: + HardwareAbstract(); + + /// @brief Override in order to do setup of hardware devices post construction + virtual void init() = 0; + + + /// @brief Override to allow printing of a message for debugging + /// @param message - Debug message + virtual void debugPrint(const char* fmt, ...) = 0; + + virtual std::shared_ptr battery() = 0; + virtual std::shared_ptr display() = 0; + virtual std::shared_ptr wifi() = 0; + + protected: + +}; \ No newline at end of file diff --git a/Platformio/HAL/HardwareModules/BatteryInterface.h b/Platformio/HAL/HardwareModules/BatteryInterface.h new file mode 100644 index 0000000..1fd8e86 --- /dev/null +++ b/Platformio/HAL/HardwareModules/BatteryInterface.h @@ -0,0 +1,9 @@ +#pragma once +#include "Notification.hpp" + +class BatteryInterface { +public: + BatteryInterface() = default; + virtual int getPercentage() = 0; + virtual bool isCharging() = 0; +}; \ No newline at end of file diff --git a/Platformio/HAL/HardwareModules/DisplayAbstract.cpp b/Platformio/HAL/HardwareModules/DisplayAbstract.cpp new file mode 100644 index 0000000..48d0e3a --- /dev/null +++ b/Platformio/HAL/HardwareModules/DisplayAbstract.cpp @@ -0,0 +1,35 @@ +#include "DisplayAbstract.h" + +std::shared_ptr DisplayAbstract::mInstance = nullptr; + +DisplayAbstract::DisplayAbstract(){ + lv_init(); + + lv_disp_draw_buf_init(&mdraw_buf, mbufA, mbufB, + SCREEN_WIDTH * SCREEN_HEIGHT / 10); + + // Initialize the display driver + static lv_disp_drv_t disp_drv; + lv_disp_drv_init(&disp_drv); + disp_drv.hor_res = SCREEN_WIDTH; + disp_drv.ver_res = SCREEN_HEIGHT; + disp_drv.flush_cb = &DisplayAbstract::flushDisplayImpl; + disp_drv.draw_buf = &mdraw_buf; + lv_disp_drv_register(&disp_drv); + + // Initialize the touchscreen driver + static lv_indev_drv_t indev_drv; + lv_indev_drv_init(&indev_drv); + indev_drv.type = LV_INDEV_TYPE_POINTER; + indev_drv.read_cb = &DisplayAbstract::screenInputImpl; + lv_indev_drv_register(&indev_drv); + +} + +void DisplayAbstract::flushDisplayImpl(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p) { + mInstance->flushDisplay(disp, area, color_p); +} + +void DisplayAbstract::screenInputImpl(lv_indev_drv_t *indev_driver, lv_indev_data_t *data) { + mInstance->screenInput(indev_driver, data); +} \ No newline at end of file diff --git a/Platformio/HAL/HardwareModules/DisplayAbstract.h b/Platformio/HAL/HardwareModules/DisplayAbstract.h new file mode 100644 index 0000000..a15e88c --- /dev/null +++ b/Platformio/HAL/HardwareModules/DisplayAbstract.h @@ -0,0 +1,28 @@ +#pragma once +#include +#include "lvgl.h" +class DisplayAbstract +{ + public: + DisplayAbstract(); + virtual void setBrightness(uint8_t brightness) = 0; + virtual uint8_t getBrightness() = 0; + virtual void turnOff() = 0; + + protected: + // Set this with a getInstance method in the Child Class + static std::shared_ptr mInstance; + + virtual void flushDisplay(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p) = 0; + virtual void screenInput(lv_indev_drv_t *indev_driver, lv_indev_data_t *data) = 0; + private: + + // Used to satisfy LVGL APIs + static void flushDisplayImpl(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p); + static void screenInputImpl(lv_indev_drv_t *indev_driver, lv_indev_data_t *data); + + // LVGL Screen Buffers + lv_disp_draw_buf_t mdraw_buf; + lv_color_t mbufA[SCREEN_WIDTH * SCREEN_HEIGHT / 10]; + lv_color_t mbufB[SCREEN_WIDTH * SCREEN_HEIGHT / 10]; +}; \ No newline at end of file diff --git a/Platformio/HAL/HardwareModules/UIInterface.h b/Platformio/HAL/HardwareModules/UIInterface.h new file mode 100644 index 0000000..a1c6ba9 --- /dev/null +++ b/Platformio/HAL/HardwareModules/UIInterface.h @@ -0,0 +1,17 @@ +#pragma once + +class UIInterface +{ + public: + virtual void setup() = 0; + virtual void setup_ui() = 0; + virtual void wifi_scan_complete(unsigned int size) = 0; + virtual void clear_wifi_networks() = 0; + virtual void update_wifi(bool connected) = 0; + virtual void hide_keyboard() = 0; + virtual void show_keyboard() = 0; + virtual void update() = 0; + virtual void reset_settings_menu() = 0; + virtual void update_battery(int percentage, bool isCharging, bool isConnected) = 0; + virtual void turnOff() = 0; +}; \ No newline at end of file diff --git a/Platformio/HAL/HardwareModules/wifiHandlerInterface.h b/Platformio/HAL/HardwareModules/wifiHandlerInterface.h new file mode 100644 index 0000000..f6c2f80 --- /dev/null +++ b/Platformio/HAL/HardwareModules/wifiHandlerInterface.h @@ -0,0 +1,25 @@ +#pragma once +#include +#include +#include + +typedef struct { + std::string ssid; + int rssi; +} WifiInfo; + +typedef struct { + bool isConnected; + std::string IP; + std::string ssid; +}wifiStatus; + +class wifiHandlerInterface{ + public: + virtual bool isAvailable() = 0; + virtual void scan() = 0; + virtual void connect(std::shared_ptr ssid, std::shared_ptr password) = 0; + virtual void onScanDone(std::function>)> function) = 0; + virtual void onStatusUpdate(std::function)> function) = 0; + virtual void begin() = 0; +}; \ No newline at end of file diff --git a/Platformio/HAL/MPMCQueueInterface.hpp b/Platformio/HAL/MPMCQueueInterface.hpp new file mode 100644 index 0000000..d3d396e --- /dev/null +++ b/Platformio/HAL/MPMCQueueInterface.hpp @@ -0,0 +1,9 @@ +#pragma once +#include "SPSCQueueInterface.hpp" + +template +class MPMCQueueInterface: public SPSCQueueInterface +{ + public: + bool push(T obj, bool overwrite = false); +}; \ No newline at end of file diff --git a/Platformio/HAL/Notification.hpp b/Platformio/HAL/Notification.hpp new file mode 100644 index 0000000..6b8920f --- /dev/null +++ b/Platformio/HAL/Notification.hpp @@ -0,0 +1,29 @@ +#pragma once +#include +#include + +template +class Notification{ + public: + typedef std::function HandlerTy; + + Notification() = default; + void onNotify(HandlerTy aHandler); + void notify(notifyData... notifySendData); + + private: + std::vector mFunctionHandlers; +}; + + +template +void Notification::onNotify(HandlerTy aHandler){ + mFunctionHandlers.push_back(std::move(aHandler)); +} + +template +void Notification::notify(outboundData... notifySendData){ + for (auto handler : mFunctionHandlers){ + handler(notifySendData...); + } +} \ No newline at end of file diff --git a/Platformio/HAL/SPSCQueueInterface.hpp b/Platformio/HAL/SPSCQueueInterface.hpp new file mode 100644 index 0000000..9efe787 --- /dev/null +++ b/Platformio/HAL/SPSCQueueInterface.hpp @@ -0,0 +1,12 @@ +#pragma once +#include + +template +class SPSCQueueInterface { + public: + virtual bool push(T obj) = 0; + virtual std::optional pop() = 0; + virtual std::optional peek() = 0; + virtual bool isFull() = 0; + virtual bool isEmpty() = 0; +}; \ No newline at end of file diff --git a/Platformio/HAL/Targets/ESP32/HardwareRevX.cpp b/Platformio/HAL/Targets/ESP32/HardwareRevX.cpp index 161163a..aa08903 100644 --- a/Platformio/HAL/Targets/ESP32/HardwareRevX.cpp +++ b/Platformio/HAL/Targets/ESP32/HardwareRevX.cpp @@ -1,5 +1,6 @@ #include "HardwareRevX.hpp" -#include "driver/ledc.h" +#include "display.hpp" +#include "wifihandler.hpp" std::shared_ptr HardwareRevX::mInstance = nullptr; @@ -49,6 +50,10 @@ void HardwareRevX::initIO() { gpio_deep_sleep_hold_dis(); } +HardwareRevX::HardwareRevX(): + HardwareAbstract(){ + } + HardwareRevX::WakeReason getWakeReason() { // Find out wakeup cause if (esp_sleep_get_wakeup_cause() == ESP_SLEEP_WAKEUP_EXT1) { @@ -64,110 +69,53 @@ HardwareRevX::WakeReason getWakeReason() { void HardwareRevX::init() { // Make sure ESP32 is running at full speed setCpuFrequencyMhz(240); - wakeup_reason = getWakeReason(); initIO(); - setupBacklight(); Serial.begin(115200); + + mDisplay = Display::getInstance(); + mBattery = std::make_shared(ADC_BAT,CRG_STAT); + mWifiHandler = wifiHandler::getInstance(); restorePreferences(); - slowDisplayWakeup(); - setupTFT(); - setupTouchScreen(); - initLVGL(); - setupWifi(); + + mDisplay->onTouch([this]([[maybe_unused]] auto touchPoint){ standbyTimer = SLEEP_TIMEOUT;}); + setupIMU(); setupIR(); - debugPrint(std::string("Finished Hardware Setup in %d", millis())); + debugPrint("Finished Hardware Setup in %d", millis()); } -void HardwareRevX::debugPrint(std::string aDebugMessage) { - Serial.print(aDebugMessage.c_str()); +void HardwareRevX::debugPrint(const char* fmt, ...) +{ + char result[100]; + va_list arguments; + + va_start(arguments, fmt); + vsnprintf(result, 100, fmt, arguments); + va_end (arguments); + + Serial.print(result); } -void HardwareRevX::sendIR() {} - -void HardwareRevX::MQTTPublish(const char *topic, const char *payload) { -#ifdef ENABLE_WIFI - if (client.connected()) { - client.publish(topic, payload); - } else { - debugPrint("MQTT Client Not Connected When Attempting Publish."); +std::shared_ptr HardwareRevX::getInstance(){ + if (!mInstance) { + mInstance = std::shared_ptr(new HardwareRevX()); } -#else - debugPrint("Attempting To Publish MQTT with wifi Disabled!"); -#endif + return mInstance; } -HardwareInterface::batteryStatus HardwareRevX::getBatteryPercentage() { - return battery; +std::shared_ptr HardwareRevX::wifi() +{ + return mWifiHandler; } -void HardwareRevX::initLVGL() { - lv_init(); - - lv_disp_draw_buf_init(&mdraw_buf, mbufA, mbufB, - SCREEN_WIDTH * SCREEN_HEIGHT / 10); - - // Initialize the display driver - static lv_disp_drv_t disp_drv; - lv_disp_drv_init(&disp_drv); - disp_drv.hor_res = SCREEN_WIDTH; - disp_drv.ver_res = SCREEN_HEIGHT; - disp_drv.flush_cb = &HardwareRevX::displayFlushImpl; - disp_drv.draw_buf = &mdraw_buf; - lv_disp_drv_register(&disp_drv); - - // Initialize the touchscreen driver - static lv_indev_drv_t indev_drv; - lv_indev_drv_init(&indev_drv); - indev_drv.type = LV_INDEV_TYPE_POINTER; - indev_drv.read_cb = &HardwareRevX::touchPadReadImpl; - lv_indev_drv_register(&indev_drv); +std::shared_ptr HardwareRevX::battery(){ + return mBattery; } -void HardwareRevX::handleDisplayFlush(lv_disp_drv_t *disp, - const lv_area_t *area, - lv_color_t *color_p) { - uint32_t w = (area->x2 - area->x1 + 1); - uint32_t h = (area->y2 - area->y1 + 1); - - tft.startWrite(); - tft.setAddrWindow(area->x1, area->y1, w, h); - tft.pushPixelsDMA((uint16_t *)&color_p->full, w * h); - tft.endWrite(); - - lv_disp_flush_ready(disp); -} - -void HardwareRevX::handleTouchPadRead(lv_indev_drv_t *indev_driver, - lv_indev_data_t *data) { - // int16_t touchX, touchY; - touchPoint = touch.getPoint(); - int16_t touchX = touchPoint.x; - int16_t touchY = touchPoint.y; - bool touched = false; - if ((touchX > 0) || (touchY > 0)) { - touched = true; - standbyTimer = SLEEP_TIMEOUT; - } - - if (!touched) { - data->state = LV_INDEV_STATE_REL; - } else { - data->state = LV_INDEV_STATE_PR; - - // Set the coordinates - data->point.x = SCREEN_WIDTH - touchX; - data->point.y = SCREEN_HEIGHT - touchY; - - // Serial.print( "touchpoint: x" ); - // Serial.print( touchX ); - // Serial.print( " y" ); - // Serial.println( touchY ); - // tft.drawFastHLine(0, screenHeight - touchY, screenWidth, TFT_RED); - // tft.drawFastVLine(screenWidth - touchX, 0, screenHeight, TFT_RED); - } +std::shared_ptr HardwareRevX::display(){ + return mDisplay; } void HardwareRevX::activityDetection() { @@ -197,7 +145,7 @@ void HardwareRevX::activityDetection() { void HardwareRevX::enterSleep() { // Save settings to internal flash memory preferences.putBool("wkpByIMU", wakeupByIMUEnabled); - preferences.putUChar("blBrightness", backlight_brightness); + preferences.putUChar("blBrightness", mDisplay->getBrightness()); preferences.putUChar("currentDevice", currentDevice); if (!preferences.getBool("alreadySetUp")) preferences.putBool("alreadySetUp", true); @@ -210,12 +158,6 @@ void HardwareRevX::enterSleep() { IMU.readRegister(&intDataRead, LIS3DH_INT1_SRC); // really clear interrupt -#ifdef ENABLE_WIFI - // Power down modem - WiFi.disconnect(); - WiFi.mode(WIFI_OFF); -#endif - // Prepare IO states digitalWrite(LCD_DC, LOW); // LCD control signals off digitalWrite(LCD_CS, LOW); @@ -309,51 +251,16 @@ void HardwareRevX::configIMUInterrupts() { IMU.writeRegister(LIS3DH_CTRL_REG3, dataToWrite); } -void HardwareRevX::setupBacklight() { - // Configure the backlight PWM - // Manual setup because ledcSetup() briefly turns on the backlight - ledc_channel_config_t ledc_channel_left; - ledc_channel_left.gpio_num = (gpio_num_t)LCD_BL; - ledc_channel_left.speed_mode = LEDC_HIGH_SPEED_MODE; - ledc_channel_left.channel = LEDC_CHANNEL_5; - ledc_channel_left.intr_type = LEDC_INTR_DISABLE; - ledc_channel_left.timer_sel = LEDC_TIMER_1; - ledc_channel_left.flags.output_invert = 1; // Can't do this with ledcSetup() - ledc_channel_left.duty = 0; - - ledc_timer_config_t ledc_timer; - ledc_timer.speed_mode = LEDC_HIGH_SPEED_MODE; - ledc_timer.duty_resolution = LEDC_TIMER_8_BIT; - ledc_timer.timer_num = LEDC_TIMER_1; - ledc_timer.freq_hz = 640; - - ledc_channel_config(&ledc_channel_left); - ledc_timer_config(&ledc_timer); -} - void HardwareRevX::restorePreferences() { // Restore settings from internal flash memory + int backlight_brightness = 255; preferences.begin("settings", false); if (preferences.getBool("alreadySetUp")) { wakeupByIMUEnabled = preferences.getBool("wkpByIMU"); backlight_brightness = preferences.getUChar("blBrightness"); currentDevice = preferences.getUChar("currentDevice"); } -} - -void HardwareRevX::setupTFT() { - // Setup TFT - tft.init(); - tft.initDMA(); - tft.setRotation(0); - tft.fillScreen(TFT_BLACK); - tft.setSwapBytes(true); -} - -void HardwareRevX::setupTouchScreen() { - // Configure i2c pins and set frequency to 400kHz - Wire.begin(SDA, SCL, 400000); - touch.begin(128); // Initialize touchscreen and set sensitivity threshold + mDisplay->setBrightness(backlight_brightness); } void HardwareRevX::setupIMU() { @@ -371,37 +278,6 @@ void HardwareRevX::setupIMU() { IMU.readRegister(&intDataRead, LIS3DH_INT1_SRC); // clear interrupt } -void HardwareRevX::slowDisplayWakeup() { - // Slowly charge the VSW voltage to prevent a brownout - // Workaround for hardware rev 1! - for (int i = 0; i < 100; i++) { - digitalWrite(LCD_EN, HIGH); // LCD Logic off - delayMicroseconds(1); - digitalWrite(LCD_EN, LOW); // LCD Logic on - } - - delay(100); // Wait for the LCD driver to power on -} - -void HardwareRevX::handleWifiEvent(WiFiEvent_t event) { -#ifdef ENABLE_WIFI - // Serial.printf("[WiFi-event] event: %d\n", event); - if (event == ARDUINO_EVENT_WIFI_STA_GOT_IP) { - client.setServer(MQTT_SERVER, 1883); // MQTT initialization - client.connect("OMOTE"); // Connect using a client id - } - // Set status bar icon based on WiFi status - // TODO allow UI to register a Handler for these events - - // if (event == ARDUINO_EVENT_WIFI_STA_GOT_IP || - // event == ARDUINO_EVENT_WIFI_STA_GOT_IP6) { - // lv_label_set_text(WifiLabel, LV_SYMBOL_WIFI); - // } else { - // lv_label_set_text(WifiLabel, ""); - // } -#endif -} - void HardwareRevX::setupIR() { // Setup IR IrSender.begin(); @@ -409,52 +285,11 @@ void HardwareRevX::setupIR() { IrReceiver.enableIRIn(); // Start the receiver } -void HardwareRevX::setupWifi() { -#ifdef ENABLE_WIFI - // Setup WiFi - WiFi.setHostname("OMOTE"); // define hostname - WiFi.onEvent(wiFiEventImpl); - WiFi.begin(WIFI_SSID, WIFI_PASSWORD); - WiFi.setSleep(true); -#endif -} - -void HardwareRevX::startTasks() { - if (xTaskCreate(&HardwareRevX::updateBatteryTask, "Battery Percent Update", - 1024, nullptr, 5, &batteryUpdateTskHndl) != pdPASS) { - debugPrint("ERROR Could not Create Battery Update Task!"); - } -} - -void HardwareRevX::updateBatteryTask([[maybe_unused]] void *aData) { - while (true) { - mInstance->battery.voltage = - analogRead(ADC_BAT) * 2 * 3300 / 4095 + 350; // 350mV ADC offset - mInstance->battery.percentage = - constrain(map(mInstance->battery.voltage, 3700, 4200, 0, 100), 0, 100); - mInstance->battery.isCharging = !digitalRead(CRG_STAT); - // Check if battery is charging, fully charged or disconnected - vTaskDelay(1000 / portTICK_PERIOD_MS); - // Update battery at 1Hz - } -} +void HardwareRevX::startTasks() {} void HardwareRevX::loopHandler() { - - // TODO Move the backlight handling into task that spawns when the backlight - // setting changes and then gets deleted when the setting is achieved. - // Update Backlight brightness - static int fadeInTimer = millis(); // fadeInTimer = time after setup - if (millis() < - fadeInTimer + backlight_brightness) { // Fade in the backlight brightness - ledcWrite(5, millis() - fadeInTimer); - } else { // Dim Backlight before entering standby - if (standbyTimer < 2000) - ledcWrite(5, 85); // Backlight dim - else - ledcWrite(5, backlight_brightness); // Backlight on - } - + standbyTimer < 2000 ? mDisplay->sleep() : mDisplay->wake(); + // TODO move to debug task // Blink debug LED at 1 Hz digitalWrite(USER_LED, millis() % 1000 > 500); @@ -470,30 +305,6 @@ void HardwareRevX::loopHandler() { IMUTaskTimer = millis(); } - // TODO Convert to free RTOS task - - // TODO Create batter change notification for UI - - // if (battery_ischarging || (!battery_ischarging && battery_voltage > - // 4350)) { - // lv_label_set_text(objBattPercentage, ""); - // lv_label_set_text(objBattIcon, LV_SYMBOL_USB); - // } else { - // // Update status bar battery indicator - // // lv_label_set_text_fmt(objBattPercentage, "%d%%", - // battery_percentage); if (battery_percentage > 95) - // lv_label_set_text(objBattIcon, LV_SYMBOL_BATTERY_FULL); - // else if (battery_percentage > 75) - // lv_label_set_text(objBattIcon, LV_SYMBOL_BATTERY_3); - // else if (battery_percentage > 50) - // lv_label_set_text(objBattIcon, LV_SYMBOL_BATTERY_2); - // else if (battery_percentage > 25) - // lv_label_set_text(objBattIcon, LV_SYMBOL_BATTERY_1); - // else - // lv_label_set_text(objBattIcon, LV_SYMBOL_BATTERY_EMPTY); - // } - // } - // Keypad Handling customKeypad.getKey(); // Populate key list for (int i = 0; i < LIST_MAX; diff --git a/Platformio/HAL/Targets/ESP32/HardwareRevX.hpp b/Platformio/HAL/Targets/ESP32/HardwareRevX.hpp index 0ff2c68..249f8ad 100644 --- a/Platformio/HAL/Targets/ESP32/HardwareRevX.hpp +++ b/Platformio/HAL/Targets/ESP32/HardwareRevX.hpp @@ -1,11 +1,9 @@ #pragma once #include "SparkFunLIS3DH.h" -#include "HardwareInterface.h" -#include -#include "Wire.h" +#include "HardwareAbstract.hpp" #include "lvgl.h" -#include +#include "battery.hpp" #include #include #include @@ -13,90 +11,56 @@ #include // modified for inverted logic #include #include -#include // Hardware-specific library #include #include +#include "wifihandler.hpp" + #include "omoteconfig.h" +#include "BatteryInterface.h" +#include "wifiHandlerInterface.h" +#include "display.hpp" -class HardwareRevX : public HardwareInterface { +class HardwareRevX : public HardwareAbstract { public: enum class WakeReason { RESET, IMU, KEYPAD }; - static std::shared_ptr getInstance() { - if (!mInstance) { - mInstance = std::make_shared(); - } - return mInstance; - } + static std::shared_ptr getInstance(); static std::weak_ptr getRefrence() { return getInstance(); } - HardwareRevX() : HardwareInterface(){}; - // HardwareInterface + // HardwareAbstract virtual void init() override; - virtual void sendIR() override; - virtual void MQTTPublish(const char *topic, const char *payload) override; - virtual batteryStatus getBatteryPercentage() override; - virtual void debugPrint(std::string aDebugMessage) override; + virtual void debugPrint(const char* fmt, ...) override; + virtual std::shared_ptr battery() override; + virtual std::shared_ptr display() override; + virtual std::shared_ptr wifi() override; + + /// @brief To be ran in loop out in main + // TODO move to a freertos task void loopHandler(); - protected: // Init Functions to setup hardware void initIO(); - void setupBacklight(); void restorePreferences(); void slowDisplayWakeup(); - void setupTFT(); - void setupTouchScreen(); - void initLVGL(); void setupIMU(); void setupIR(); - void setupWifi(); void activityDetection(); void enterSleep(); void configIMUInterrupts(); - // UI/UX Handlers - void handleDisplayFlush(lv_disp_drv_t *disp, const lv_area_t *area, - lv_color_t *color_p); - void handleTouchPadRead(lv_indev_drv_t *indev_driver, lv_indev_data_t *data); - - void handleWifiEvent(WiFiEvent_t event); - // Tasks void startTasks(); - static void updateBatteryTask([[maybe_unused]] void *aData); - TaskHandle_t batteryUpdateTskHndl = nullptr; - private: - // Static Wrappers Needed to Satisfy C APIs - static void wiFiEventImpl(WiFiEvent_t event) { - mInstance->handleWifiEvent(event); - } - static void displayFlushImpl(lv_disp_drv_t *disp, const lv_area_t *area, - lv_color_t *color_p) { - mInstance->handleDisplayFlush(disp, area, color_p); - } - static void touchPadReadImpl(lv_indev_drv_t *indev_driver, - lv_indev_data_t *data) { - mInstance->handleTouchPadRead(indev_driver, data); - } - -#ifdef ENABLE_WIFI - WiFiClient espClient; - PubSubClient client = PubSubClient(espClient); -#endif - - Adafruit_FT6206 touch = Adafruit_FT6206(); - TS_Point touchPoint; - TS_Point oldPoint; - - TFT_eSPI tft = TFT_eSPI(); + HardwareRevX(); + std::shared_ptr mBattery; + std::shared_ptr mDisplay; + std::shared_ptr mWifiHandler; // IMU Motion Detection LIS3DH IMU = LIS3DH(I2C_MODE, 0x19); // Default constructor is I2C, addr 0x19. int standbyTimer = SLEEP_TIMEOUT; @@ -105,7 +69,6 @@ private: Preferences preferences; bool wakeupByIMUEnabled = true; - int backlight_brightness = 255; byte currentDevice = 1; // Current Device to control (allows switching // mappings between devices) @@ -113,14 +76,6 @@ private: IRsend IrSender = IRsend(IR_LED, true); IRrecv IrReceiver = IRrecv(IR_RX); - HardwareInterface::batteryStatus battery; - - // LVGL Screen Buffers - lv_disp_draw_buf_t mdraw_buf; - lv_color_t mbufA[SCREEN_WIDTH * SCREEN_HEIGHT / 10]; - lv_color_t mbufB[SCREEN_WIDTH * SCREEN_HEIGHT / 10]; - - lv_color_t color_primary = lv_color_hex(0x303030); // gray // Keypad declarations static const byte ROWS = 5; // four rows diff --git a/Platformio/HAL/Targets/ESP32/battery/battery.cpp b/Platformio/HAL/Targets/ESP32/battery/battery.cpp new file mode 100644 index 0000000..8bc621d --- /dev/null +++ b/Platformio/HAL/Targets/ESP32/battery/battery.cpp @@ -0,0 +1,33 @@ +#include "battery.hpp" +#include + +Battery::Battery(int adc_pin, int charging_pin): BatteryInterface(), + mAdcPin(adc_pin), + mChargingPin(charging_pin) +{ + mAdcPin = adc_pin; + mChargingPin = charging_pin; + // Power Pin Definition + pinMode(mChargingPin, INPUT_PULLUP); + pinMode(mAdcPin, INPUT); +} + +int Battery::getPercentage() +{ + return constrain(map(this->getVoltage(), 3700, 4200, 0, 100), 0, 100); +} + +bool Battery::isCharging() +{ + return !digitalRead(mChargingPin); +} + +bool Battery::isConnected() +{ + return ((!isCharging()) && (getVoltage() < 4350)); +} + +int Battery::getVoltage() +{ + return analogRead(mAdcPin)*2*3300/4095 + 350; +} \ No newline at end of file diff --git a/Platformio/HAL/Targets/ESP32/battery/battery.hpp b/Platformio/HAL/Targets/ESP32/battery/battery.hpp new file mode 100644 index 0000000..bdeece6 --- /dev/null +++ b/Platformio/HAL/Targets/ESP32/battery/battery.hpp @@ -0,0 +1,58 @@ +#pragma once +#include "BatteryInterface.h" +#include "DisplayAbstract.h" + +class Battery: public BatteryInterface { + public: + + /** + * @brief Get the Percentage of the battery + * + * @return int Percentage of the battery + */ + virtual int getPercentage() override; + + /** + * @brief Function to determine if the battery is charging or not + * + * @return true Battery is currently charging + * @return false Battery is currently not charging + */ + virtual bool isCharging() override; + + /** + * @brief Function to determine if the battery is connected + * + * @return true Battery is connected + * @return false Battery is not connected + */ + bool isConnected(); + + Battery(int adc_pin, int charging_pin); + + // Not sure why this is needed but shared_ptr seems to really + // need it possibly a compiler template handling limitation + // none the less we really should not use it. + Battery() = default; + private: + + /** + * @brief Function to get the current voltage of the battery + * + * @return int Voltage of the battery in mV + */ + int getVoltage(); + + /** + * @brief Variable to store which pin should be used for ADC + * + */ + int mAdcPin; + + /** + * @brief Variable to store which pin is used to indicate if the battery is currently charging or not + * + */ + int mChargingPin; + +}; \ No newline at end of file diff --git a/Platformio/HAL/Targets/ESP32/display/display.cpp b/Platformio/HAL/Targets/ESP32/display/display.cpp new file mode 100644 index 0000000..a8941cc --- /dev/null +++ b/Platformio/HAL/Targets/ESP32/display/display.cpp @@ -0,0 +1,194 @@ + +#include "display.hpp" +#include "omoteconfig.h" +#include "Wire.h" +#include "driver/ledc.h" + +std::shared_ptr Display::getInstance() +{ + if (DisplayAbstract::mInstance == nullptr) + { + DisplayAbstract::mInstance = std::shared_ptr(new Display(LCD_BL, LCD_EN)); + } + return std::static_pointer_cast(mInstance); +} + +Display::Display(int backlight_pin, int enable_pin): DisplayAbstract(), + mBacklightPin(backlight_pin), + mEnablePin(enable_pin), + tft(TFT_eSPI()), + touch(Adafruit_FT6206()) +{ + pinMode(mEnablePin, OUTPUT); + digitalWrite(mEnablePin, HIGH); + pinMode(mBacklightPin, OUTPUT); + digitalWrite(mBacklightPin, HIGH); + + setupBacklight(); // This eliminates the flash of the backlight + + // Slowly charge the VSW voltage to prevent a brownout + // Workaround for hardware rev 1! + for(int i = 0; i < 100; i++){ + digitalWrite(this->mEnablePin, HIGH); // LCD Logic off + delayMicroseconds(1); + digitalWrite(this->mEnablePin, LOW); // LCD Logic on + } + + setupTFT(); + setupTouchScreen(); + mFadeTaskMutex = xSemaphoreCreateBinary(); + xSemaphoreGive(mFadeTaskMutex); +} + +void Display::setupBacklight() { + // Configure the backlight PWM + // Manual setup because ledcSetup() briefly turns on the backlight + ledc_channel_config_t ledc_channel_left; + ledc_channel_left.gpio_num = (gpio_num_t)mBacklightPin; + ledc_channel_left.speed_mode = LEDC_HIGH_SPEED_MODE; + ledc_channel_left.channel = LEDC_CHANNEL_5; + ledc_channel_left.intr_type = LEDC_INTR_DISABLE; + ledc_channel_left.timer_sel = LEDC_TIMER_1; + ledc_channel_left.flags.output_invert = 1; // Can't do this with ledcSetup() + ledc_channel_left.duty = 0; + ledc_channel_left.hpoint = 0; + ledc_timer_config_t ledc_timer; + ledc_timer.speed_mode = LEDC_HIGH_SPEED_MODE; + ledc_timer.duty_resolution = LEDC_TIMER_8_BIT; + ledc_timer.timer_num = LEDC_TIMER_1; + ledc_timer.clk_cfg = LEDC_AUTO_CLK; + ledc_timer.freq_hz = 640; + ledc_channel_config(&ledc_channel_left); + ledc_timer_config(&ledc_timer); +} + +void Display::onTouch(Notification::HandlerTy aTouchHandler){ + mTouchEvent.onNotify(std::move(aTouchHandler)); +} + +void Display::setupTFT() { + delay(100); + tft.init(); + tft.initDMA(); + tft.setRotation(0); + tft.fillScreen(TFT_BLACK); + tft.setSwapBytes(true); +} + +void Display::setupTouchScreen(){ + // Configure i2c pins and set frequency to 400kHz + Wire.begin(SDA, SCL, 400000); + touch.begin(128); // Initialize touchscreen and set sensitivity threshold +} + +void Display::setBrightness(uint8_t brightness) +{ + mAwakeBrightness = brightness; + Serial.print("Set Brightness:"); + Serial.println(mAwakeBrightness); + startFade(); +} + +uint8_t Display::getBrightness(){ + return mAwakeBrightness; +} + +void Display::setCurrentBrightness(uint8_t brightness){ + mBrightness = brightness; + auto duty = static_cast(mBrightness); + ledcWrite(LCD_BACKLIGHT_LEDC_CHANNEL, duty); + // Serial.print("Current Brightness:"); + // Serial.println(mBrightness); +} + +void Display::turnOff() +{ + digitalWrite(this->mBacklightPin, HIGH); + digitalWrite(this->mEnablePin, HIGH); + pinMode(this->mBacklightPin, INPUT); + pinMode(this->mEnablePin, INPUT); + gpio_hold_en((gpio_num_t) mBacklightPin); + gpio_hold_en((gpio_num_t) mEnablePin); +} + +void Display::screenInput(lv_indev_drv_t *indev_driver, lv_indev_data_t *data){ + // int16_t touchX, touchY; + touchPoint = touch.getPoint(); + int16_t touchX = touchPoint.x; + int16_t touchY = touchPoint.y; + bool touched = false; + if ((touchX > 0) || (touchY > 0)) { + touched = true; + mTouchEvent.notify(touchPoint); + } + + if (!touched) { + data->state = LV_INDEV_STATE_REL; + } else { + data->state = LV_INDEV_STATE_PR; + + // Set the coordinates + data->point.x = SCREEN_WIDTH - touchX; + data->point.y = SCREEN_HEIGHT - touchY; + + // Serial.print( "touchpoint: x" ); + // Serial.print( touchX ); + // Serial.print( " y" ); + // Serial.println( touchY ); + // tft.drawFastHLine(0, screenHeight - touchY, screenWidth, TFT_RED); + // tft.drawFastVLine(screenWidth - touchX, 0, screenHeight, TFT_RED); + } +} + +void Display::fadeImpl(void* ){ + bool fadeDone = false; + while(!fadeDone){ + fadeDone = getInstance()->fade(); + vTaskDelay(3 / portTICK_PERIOD_MS); // 3 miliseconds between steps + // 0 - 255 will take about .75 seconds to fade up. + } + + xSemaphoreTake(getInstance()->mFadeTaskMutex,portMAX_DELAY); + getInstance()->mDisplayFadeTask = nullptr; + xSemaphoreGive(getInstance()->mFadeTaskMutex); + + vTaskDelete(nullptr); // Delete Fade Task +} + +bool Display::fade(){ + //Early return no fade needed. + if (mBrightness == mAwakeBrightness || + isAsleep && mBrightness == 0){return true;} + + bool fadeDown = isAsleep || mBrightness > mAwakeBrightness; + if (fadeDown){ + setCurrentBrightness(mBrightness - 1); + auto setPoint = isAsleep ? 0 : mAwakeBrightness; + return mBrightness == setPoint; + }else{ + setCurrentBrightness(mBrightness + 1); + return mBrightness == mAwakeBrightness; + } +} + +void Display::startFade(){ + xSemaphoreTake(mFadeTaskMutex,portMAX_DELAY); + // Only Create Task if it is needed + if(mDisplayFadeTask == nullptr){ + xTaskCreate(&Display::fadeImpl, "Display Fade Task", + 1024, nullptr, 5, &mDisplayFadeTask); + } + xSemaphoreGive(mFadeTaskMutex); +} + +void Display::flushDisplay(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p) { + uint32_t w = (area->x2 - area->x1 + 1); + uint32_t h = (area->y2 - area->y1 + 1); + + tft.startWrite(); + tft.setAddrWindow(area->x1, area->y1, w, h); + tft.pushPixelsDMA((uint16_t *)&color_p->full, w * h); + tft.endWrite(); + + lv_disp_flush_ready(disp); +} diff --git a/Platformio/HAL/Targets/ESP32/display/display.hpp b/Platformio/HAL/Targets/ESP32/display/display.hpp new file mode 100644 index 0000000..214c8b8 --- /dev/null +++ b/Platformio/HAL/Targets/ESP32/display/display.hpp @@ -0,0 +1,73 @@ +#pragma once +#include "DisplayAbstract.h" +#include "HardwareAbstract.hpp" +#include "Notification.hpp" +#include +#include +#include +#include "driver/ledc.h" + +/*LEDC Channel to use for the LCD backlight*/ +#define LCD_BACKLIGHT_LEDC_CHANNEL LEDC_CHANNEL_5 + +#define LCD_BACKLIGHT_LEDC_FREQUENCY 640 + +#define LCD_BACKLIGHT_LEDC_BIT_RESOLUTION 8 + +#define DEFAULT_BACKLIGHT_BRIGHTNESS 128 + + +class Display: public DisplayAbstract +{ + public: + static std::shared_ptr getInstance(); + + /// @brief Set brightness setting and fade to it + /// @param brightness + virtual void setBrightness(uint8_t brightness) override; + virtual uint8_t getBrightness() override; + virtual void turnOff() override; + + void onTouch(Notification::HandlerTy aTouchHandler); + + inline void wake() {if(isAsleep) {isAsleep = false; startFade();}} + inline void sleep() {if(!isAsleep){isAsleep = true; startFade();}} + + protected: + virtual void flushDisplay(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p); + virtual void screenInput(lv_indev_drv_t *indev_driver, lv_indev_data_t *data) override; + + /// @brief Fade toward brightness based on isAwake + /// @return True - Fade complete + /// False - Fade set point not reached + bool fade(); + /// @brief Start the Fade task + void startFade(); + + /// @brief Set the actual display brightness right now + /// @param brightness + void setCurrentBrightness(uint8_t brightness); + + private: + Display(int backlight_pin, int enable_pin); + void setupTFT(); + void setupTouchScreen(); + void setupBacklight(); + + int mEnablePin; + int mBacklightPin; + TFT_eSPI tft; + + Adafruit_FT6206 touch; + TS_Point touchPoint; + TS_Point oldPoint; + Notification mTouchEvent; + + TaskHandle_t mDisplayFadeTask = nullptr; + SemaphoreHandle_t mFadeTaskMutex = nullptr; + static void fadeImpl(void* aBrightness); + + uint8_t mBrightness = 0; // Current display brightness + uint8_t mAwakeBrightness = 100; // Current setting for brightness when awake + bool isAsleep = false; +}; \ No newline at end of file diff --git a/Platformio/HAL/Targets/ESP32/freeRTOSMPMCQueue.cpp b/Platformio/HAL/Targets/ESP32/freeRTOSMPMCQueue.cpp new file mode 100644 index 0000000..f302ed7 --- /dev/null +++ b/Platformio/HAL/Targets/ESP32/freeRTOSMPMCQueue.cpp @@ -0,0 +1,70 @@ +#include "freeRTOSMPMCQueue.hpp" + +template +freeRTOSMPMCQueue::freeRTOSMPMCQueue(uint32_t size) +{ + this->queue = xQueueCreate(size, sizeof(T)); +} + +template +freeRTOSMPMCQueue::~freeRTOSMPMCQueue() +{ + vQueueDelete(this->queue); +} + +template +bool freeRTOSMPMCQueue::push(T obj) +{ + return xQueueSendToBack(this->queue, &obj, 0) == pdTRUE; +} + +template +bool freeRTOSMPMCQueue::push(T obj, bool overwrite) +{ + if (overwrite == true) + { + xQueueOverwrite(this->queue, obj); + return true; + } + else + { + return this->push(obj); + } +} + +template +std::optional freeRTOSMPMCQueue::pop() +{ + T retval; + + if (xQueueReceive(this->queue, &retval, 0) == pdTRUE) + { + return retval; + } + + return std::nullopt; +} + +template +std::optional freeRTOSMPMCQueue::peek() +{ + T retval; + + if (xQueuePeek(this->queue, &retval, 0) == pdTRUE) + { + return retval; + } + return std::nullopt; +} + +template +bool freeRTOSMPMCQueue::isFull() +{ + return (xQueueIsQueueFullFromISR(this->queue) == pdTRUE); +} + +template +bool freeRTOSMPMCQueue::isEmpty() +{ + return (xQueueIsQueueEmptyFromISR(this->queue) == pdTRUE); +} \ No newline at end of file diff --git a/Platformio/HAL/Targets/ESP32/freeRTOSMPMCQueue.hpp b/Platformio/HAL/Targets/ESP32/freeRTOSMPMCQueue.hpp new file mode 100644 index 0000000..013bfc5 --- /dev/null +++ b/Platformio/HAL/Targets/ESP32/freeRTOSMPMCQueue.hpp @@ -0,0 +1,18 @@ +#pragma once +#include "MPMCQueueInterface.hpp" +#include "Arduino.h" +template +class freeRTOSMPMCQueue: public MPMCQueueInterface +{ + public: + freeRTOSMPMCQueue(uint32_t size); + ~freeRTOSMPMCQueue(); + bool push (T obj); + bool push (T obj, bool overwrite); + std::optional pop(); + std::optional peek(); + bool isFull(); + bool isEmpty(); + private: + QueueHandle_t queue; +}; \ No newline at end of file diff --git a/Platformio/HAL/Targets/ESP32/wifiHandler/wifihandler.cpp b/Platformio/HAL/Targets/ESP32/wifiHandler/wifihandler.cpp new file mode 100644 index 0000000..7b55a67 --- /dev/null +++ b/Platformio/HAL/Targets/ESP32/wifiHandler/wifihandler.cpp @@ -0,0 +1,230 @@ +#include "wifihandler.hpp" +#include +#include +#include "HardwareAbstract.hpp" +#include "WiFi.h" + +std::shared_ptr wifiHandler::mInstance = nullptr; + +// WiFi status event +void wifiHandler::WiFiEvent(WiFiEvent_t event){ + int no_networks = 0; + switch (event) + { + case ARDUINO_EVENT_WIFI_SCAN_DONE: + { + Serial.println("WIFI scan done\n"); + no_networks = WiFi.scanComplete(); + std::vector *vec = new std::vector(); + std::shared_ptr> info = std::shared_ptr>(vec); + + for (int i = 0; i < no_networks; i++) + { + info->push_back(WifiInfo { + .ssid = std::string(WiFi.SSID(i).c_str()), + .rssi = WiFi.RSSI(i) + }); + } + if (no_networks < 0) + { + Serial.println("Scan failed"); + } + else + { + // TODO Convert To callbacks + //this->display.clear_wifi_networks(); + Serial.print(no_networks); + Serial.print(" found\n"); + //this->display.wifi_scan_complete( no_networks); + } + this->scan_notification.notify(info); + if (WiFi.isConnected() == false) + { + WiFi.reconnect(); + } + break; + } + case ARDUINO_EVENT_WIFI_STA_GOT_IP: + case ARDUINO_EVENT_WIFI_STA_GOT_IP6: + this->update_credentials(); + case ARDUINO_EVENT_WIFI_STA_DISCONNECTED: + case ARDUINO_EVENT_WIFI_STA_LOST_IP: + case ARDUINO_EVENT_WIFI_STA_STOP: + this->update_status(); + default: + Serial.print("Wifi Status: "); + Serial.println(WiFi.status()); + break; + } + if (WiFi.status() == WL_CONNECT_FAILED) + { + Serial.println("connection failed."); + WiFi.disconnect(); + } + Serial.println(WiFi.status()); +} + +bool wifiHandler::isAvailable(){ + return true; +} +std::shared_ptr wifiHandler::getInstance() +{ + if(mInstance) + { + return mInstance; + } + mInstance = std::shared_ptr(new wifiHandler()); + return mInstance; +}; + +wifiHandler::wifiHandler() +{ + this->password = ""; + this->SSID = ""; +} + +void wifiHandler::update_status() +{ + Serial.println("update_status"); + std::shared_ptr status = std::make_shared(wifiStatus()); + //wifiStatus *status = new wifiStatus(); + status->isConnected = WiFi.isConnected(); + //status->IP = WiFi.localIP(); + IPAddress ip = WiFi.localIP(); + String ip_str = ip.toString(); + status->IP = ip.toString().c_str(); + + //ip.copy(status->IP, ip.length()); + String ssid = WiFi.SSID(); + status->ssid = WiFi.SSID().c_str(); + + //this->wifi_status.isConnected = WiFi.isConnected(); + //this->wifi_status.IP = WiFi.localIP(); + //this->wifi_status.isConnected = true; + + + //Serial.println(WiFi.localIP()); + this->status_update.notify(status); +} + +void wifiHandler::update_credentials() +{ + // No connection was attempted so don't try to to save the creds + if(!this->connect_attempt) return; +#if 0 + if (strcmp(temporary_password, wifiHandler::password) != 0 || strcmp(temporary_ssid, wifiHandler::SSID) != 0) + { + strcpy(wifiHandler::password, temporary_password); + strcpy(wifiHandler::SSID, temporary_ssid); + + Preferences preferences; + preferences.begin("wifiSettings", false); + String tempString = wifiHandler::password; + preferences.putString("password", tempString); + tempString = wifiHandler::SSID; + preferences.putString("SSID", tempString); + preferences.end(); + } +#else + if (this->temporary_password->compare(this->password) != 0 || this->temporary_ssid->compare(this->SSID)) + { + this->password = *(this->temporary_password); + this->SSID = *(this->temporary_ssid); + + Preferences preferences; + preferences.begin("wifiSettings", false); + String tempString = this->temporary_password->c_str(); + preferences.putString("password", tempString); + tempString = this->temporary_ssid->c_str(); + preferences.putString("SSID", tempString); + preferences.end(); + } +#endif +this->connect_attempt = false; +} + +void wifiHandler::scan() +{ + Serial.println("scan called"); + /* If the */ + WiFi.status(); + if (WiFi.isConnected() != true) + { + WiFi.disconnect(); + } + WiFi.scanNetworks(true); +} + + +void wifiHandler::begin() +{ + //this->display = display; + WiFi.setHostname("OMOTE"); + WiFi.mode(WIFI_STA); + //WiFi.onEvent([this] (WiFiEvent_t event) {mInstance->WiFiEvent(event);}); + WiFi.onEvent([] (WiFiEvent_t event) {mInstance->WiFiEvent(event);}); + + Preferences preferences; + preferences.begin("wifiSettings",false); + String ssid = preferences.getString("SSID"); + String password = preferences.getString("password"); + preferences.end(); + + /* If the SSID is not empty, there was a value stored in the preferences and we try to use it.*/ + if (!ssid.isEmpty()) + { + Serial.print("Connecting to wifi "); + Serial.println(ssid); + //strcpy(this->SSID, ssid.c_str()); + //strcpy(this->password, password.c_str()); + this->SSID = ssid.c_str(); + this->password = password.c_str(); + this->connect(std::make_shared(std::string(this->SSID)), std::make_shared(std::string(this->password))); + } + else + { + Serial.println("no SSID or password stored"); + /*Set first character to \0 indicates an empty string*/ + this->SSID[0] = '\0'; + this->password[0] = '\0'; + WiFi.disconnect(); + } + + WiFi.setSleep(true); +} + +void wifiHandler::onScanDone(std::function>)> function){ + this->scan_notification.onNotify(std::move(function)); +} + +void wifiHandler::onStatusUpdate(std::function)> function){ + this->status_update.onNotify(std::move(function)); +} + +void wifiHandler::connect(std::shared_ptr ssid, std::shared_ptr password) +{ + this->connect_attempt = true; + this->temporary_password = password; + this->temporary_ssid = ssid; + WiFi.begin(ssid->c_str(), password->c_str()); +} + +void wifiHandler::turnOff() +{ + WiFi.disconnect(); + WiFi.mode(WIFI_OFF); +} + +void wifiHandler::disconnect(){ + WiFi.disconnect(); +} + +bool wifiHandler::isConnected() +{ + return WiFi.isConnected(); +} + +std::string wifiHandler::getIP() +{ + return std::string(WiFi.localIP().toString().c_str()); +} \ No newline at end of file diff --git a/Platformio/HAL/Targets/ESP32/wifiHandler/wifihandler.hpp b/Platformio/HAL/Targets/ESP32/wifiHandler/wifihandler.hpp new file mode 100644 index 0000000..b9a855f --- /dev/null +++ b/Platformio/HAL/Targets/ESP32/wifiHandler/wifihandler.hpp @@ -0,0 +1,99 @@ +#pragma once +#include "wifiHandlerInterface.h" +#include "Notification.hpp" +#include "memory.h" +#include + +#define STRING_SIZE 50 + +class wifiHandler: public wifiHandlerInterface { + public: + wifiHandler(); + static std::shared_ptr getInstance(); + /** + * @brief Function to initialize the wifi handler + * + */ + void begin(); + + /** + * @brief Connect to the wifi using the provided credetials + * + * @param SSID + * @param password + */ + void connect(std::shared_ptr ssid, std::shared_ptr password); + //void connect(const char* SSID, const char* password); + + + + /** + * @brief function to trigger asynchronous scan for wifi networks + * + */ + void scan(); + bool isAvailable(); + void onScanDone(std::function>)> function); + void onStatusUpdate(std::function)> function); + + + private: + + Notification>> scan_notification; + Notification> status_update; + /** + * @brief Function to update the wifi credentials. This function is called in the wifi event callback function + * after a connection is established. Only then is the new credentials stored and the old stored credentials + * overwritten. + * + * @param temporary_ssid + * @param temporary_password + */ + void update_credentials(); + + void WiFiEvent(WiFiEvent_t event); + + /** + * @brief Function to turn off wifi + * + */ + void turnOff(); + /** + * @brief Function to get the IP address of this device + * + * @return String IP Address of the device + */ + std::string getIP(); + wifiStatus wifi_status; + static std::shared_ptr mInstance; + bool connect_attempt = false; + std::shared_ptr temporary_password; + std::shared_ptr temporary_ssid; + + void update_status(); + /** + * @brief Internal variable to store the wifi password + * + */ + std::string password; + + /** + * @brief Function to disconnect from the network + * + */ + void disconnect(); + + /** + * @brief Function to determine wether or not we are connected to a network + * + * @return true Device is connected to wifi network + * @return false Device is not connected to wifi network + */ + bool isConnected(); + /** + * @brief Internal variable to store the wifi SSID + * + */ + std::string SSID; + +}; \ No newline at end of file diff --git a/Platformio/HAL/Targets/Simulator/HardwareSimulator.cpp b/Platformio/HAL/Targets/Simulator/HardwareSimulator.cpp index 27f64a2..a47bfb5 100644 --- a/Platformio/HAL/Targets/Simulator/HardwareSimulator.cpp +++ b/Platformio/HAL/Targets/Simulator/HardwareSimulator.cpp @@ -1,70 +1,48 @@ #include "HardwareSimulator.hpp" -#include -#include "SDL2/SDL.h" -#include "display/monitor.h" -#include "indev/mouse.h" -#include "indev/mousewheel.h" -#include "indev/keyboard.h" -#include "sdl/sdl.h" -/** - * A task to measure the elapsed time for LittlevGL - * @param data unused - * @return never return - */ -static int tick_thread(void * data) +#include "SDLDisplay.hpp" +#include + +HardwareSimulator::HardwareSimulator(): HardwareAbstract(), + mTickThread([](){ + while(true){ + std::this_thread::sleep_for(std::chrono::milliseconds(2)); + lv_tick_inc(2); /*Tell lvgl that 2 milliseconds were elapsed*/ + }}), + mBattery(std::make_shared()), + mDisplay(SDLDisplay::getInstance()), + mWifiHandler(std::make_shared()) { - (void)data; - - while(1) { - SDL_Delay(5); /*Sleep for 5 millisecond*/ - lv_tick_inc(5); /*Tell LittelvGL that 5 milliseconds were elapsed*/ - } - - return 0; + mHardwareStatusTitleUpdate = std::thread([this] { + int dataToShow = 0; + while (true) + { + std::stringstream title; + switch (dataToShow){ + case 0: + title << "Batt:" << mBattery->getPercentage() << "%" << std::endl; + break; + case 1: + title << "BKLght: " << static_cast(mDisplay->getBrightness()) << std::endl; + dataToShow = -1; + break; + default: + dataToShow = -1; + } + dataToShow++; + + mDisplay->setTitle(title.str()); + std::this_thread::sleep_for(std::chrono::seconds(2)); + } + }); } - - - -void HardwareSimulator::init() { - lv_init(); - // Workaround for sdl2 `-m32` crash - // https://bugs.launchpad.net/ubuntu/+source/libsdl2/+bug/1775067/comments/7 - #ifndef WIN32 - setenv("DBUS_FATAL_WARNINGS", "0", 1); - #endif - - /* Add a display - * Use the 'monitor' driver which creates window on PC's monitor to simulate a display*/ - - static lv_disp_draw_buf_t disp_buf; - static lv_color_t buf[SDL_HOR_RES * 10]; /*Declare a buffer for 10 lines*/ - lv_disp_draw_buf_init(&disp_buf, buf, NULL, SDL_HOR_RES * 10); /*Initialize the display buffer*/ - - static lv_disp_drv_t disp_drv; - lv_disp_drv_init(&disp_drv); /*Basic initialization*/ - disp_drv.flush_cb = sdl_display_flush; /*Used when `LV_VDB_SIZE != 0` in lv_conf.h (buffered drawing)*/ - disp_drv.draw_buf = &disp_buf; - disp_drv.hor_res = SDL_HOR_RES; - disp_drv.ver_res = SDL_VER_RES; - //disp_drv.disp_fill = monitor_fill; /*Used when `LV_VDB_SIZE == 0` in lv_conf.h (unbuffered drawing)*/ - //disp_drv.disp_map = monitor_map; /*Used when `LV_VDB_SIZE == 0` in lv_conf.h (unbuffered drawing)*/ - lv_disp_drv_register(&disp_drv); - - /* Add the mouse as input device - * Use the 'mouse' driver which reads the PC's mouse*/ - static lv_indev_drv_t indev_drv; - lv_indev_drv_init(&indev_drv); /*Basic initialization*/ - indev_drv.type = LV_INDEV_TYPE_POINTER; - indev_drv.read_cb = sdl_mouse_read; /*This function will be called periodically (by the library) to get the mouse position and state*/ - lv_indev_drv_register(&indev_drv); - - sdl_init(); - - /* Tick init. - * You have to call 'lv_tick_inc()' in periodically to inform LittelvGL about how much time were elapsed - * Create an SDL thread to do this*/ - SDL_CreateThread(tick_thread, "tick", NULL); - +std::shared_ptr HardwareSimulator::battery(){ + return mBattery; +} +std::shared_ptr HardwareSimulator::display(){ + return mDisplay; +} +std::shared_ptr HardwareSimulator::wifi(){ + return mWifiHandler; } \ No newline at end of file diff --git a/Platformio/HAL/Targets/Simulator/HardwareSimulator.hpp b/Platformio/HAL/Targets/Simulator/HardwareSimulator.hpp index d7cd0db..f66caf4 100644 --- a/Platformio/HAL/Targets/Simulator/HardwareSimulator.hpp +++ b/Platformio/HAL/Targets/Simulator/HardwareSimulator.hpp @@ -1,29 +1,34 @@ #pragma once -#include "HardwareInterface.h" -#include -#include +#include "HardwareAbstract.hpp" -class HardwareSimulator : public HardwareInterface { +#include "batterySimulator.hpp" +#include "SDLDisplay.hpp" +#include "wifiHandlerSim.hpp" + +#include + +class HardwareSimulator : public HardwareAbstract { public: - HardwareSimulator() = default; + HardwareSimulator(); + + virtual void init() override {}; - virtual void debugPrint(std::string message) override { - std::cout << message; + virtual void debugPrint(const char* fmt, ...) override { + va_list arguments; + va_start(arguments, fmt); + vprintf(fmt, arguments); + va_end(arguments); } - virtual void sendIR() override {} + virtual std::shared_ptr battery() override; + virtual std::shared_ptr display() override; + virtual std::shared_ptr wifi() override; - virtual void MQTTPublish(const char *topic, const char *payload) override{ +private: + std::thread mTickThread; + std::thread mHardwareStatusTitleUpdate; - }; - - virtual void init() override; - - virtual batteryStatus getBatteryPercentage() { - batteryStatus fakeStatus; - fakeStatus.isCharging = false; - fakeStatus.percentage = 100; - fakeStatus.voltage = 4200; - return fakeStatus; - } + std::shared_ptr mBattery; + std::shared_ptr mDisplay; + std::shared_ptr mWifiHandler; }; diff --git a/Platformio/HAL/Targets/Simulator/SDLDisplay.cpp b/Platformio/HAL/Targets/Simulator/SDLDisplay.cpp new file mode 100644 index 0000000..461cf61 --- /dev/null +++ b/Platformio/HAL/Targets/Simulator/SDLDisplay.cpp @@ -0,0 +1,39 @@ +#include "SDLDisplay.hpp" +#include "sdl/sdl.h" +#include + +std::shared_ptr SDLDisplay::getInstance(){ + if (!DisplayAbstract::mInstance){ + DisplayAbstract::mInstance = std::shared_ptr(new SDLDisplay()); + } + return std::static_pointer_cast(mInstance); +} + +void SDLDisplay::setBrightness(uint8_t brightness){ + mBrightness = brightness; +} + +uint8_t SDLDisplay::getBrightness(){ + return mBrightness; +} + +void SDLDisplay::turnOff(){ + +} + +void SDLDisplay::flushDisplay(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p){ + sdl_display_flush(disp,area,color_p); +} + +void SDLDisplay::screenInput(lv_indev_drv_t *indev_driver, lv_indev_data_t *data){ + sdl_mouse_read(indev_driver,data); +} + +void SDLDisplay::setTitle(std::string aNewTitle){ + SDL_SetWindowTitle(mSimWindow,aNewTitle.c_str()); +} + +SDLDisplay::SDLDisplay(): DisplayAbstract() { + sdl_init(); + mSimWindow = SDL_GetWindowFromID(1); // Get the SDL window via ID hopefully it is always 1... +} \ No newline at end of file diff --git a/Platformio/HAL/Targets/Simulator/SDLDisplay.hpp b/Platformio/HAL/Targets/Simulator/SDLDisplay.hpp new file mode 100644 index 0000000..98f58b2 --- /dev/null +++ b/Platformio/HAL/Targets/Simulator/SDLDisplay.hpp @@ -0,0 +1,25 @@ +#pragma once +#include +#include "SDL2/SDL.h" +#include "DisplayAbstract.h" + +class SDLDisplay : public DisplayAbstract{ + +public: + static std::shared_ptr getInstance(); + + virtual void setBrightness(uint8_t brightness) override; + virtual uint8_t getBrightness() override; + virtual void turnOff() override; + + void setTitle(std::string aNewTitle); + +protected: + virtual void flushDisplay(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p) override; + virtual void screenInput(lv_indev_drv_t *indev_driver, lv_indev_data_t *data) override; + +private: + SDLDisplay(); + uint8_t mBrightness; + SDL_Window* mSimWindow; +}; \ No newline at end of file diff --git a/Platformio/HAL/Targets/Simulator/SimulatorMPMCQueue.cpp b/Platformio/HAL/Targets/Simulator/SimulatorMPMCQueue.cpp new file mode 100644 index 0000000..2d6e207 --- /dev/null +++ b/Platformio/HAL/Targets/Simulator/SimulatorMPMCQueue.cpp @@ -0,0 +1,77 @@ +#include "SimulatorMPMCQueue.hpp" + +template +bool SimulatorMPMCQueue::push(T obj) +{ + return this->push(obj, false); +} + +template +bool SimulatorMPMCQueue::push(T obj, bool overwrite) +{ + bool retval = false; + if (this->mtx.try_lock()) + { + if (this->isFull() && overwrite) + { + /* If we should overwrite already written data and the buffer is full, we increment the rd_index as well. + This has to be done in the mutex so we do not overwrite data which is already being read*/ + this->rd_index = this->incrementIndex(this->rd_index); + } + + /* If the buffer is full, we can not write to the buffer. If overwrite is set to true, this check will never + fail as we move the rd_index if the buffer would otherwise be full*/ + if (!this->isFull()) + { + retval = true; + this->data[this->wr_index] = obj; + this->wr_index = this->incrementIndex(this->wr_index); + } + this->mtx.unlock(); + } + return retval; +} + +template +std::optional SimulatorMPMCQueue::pop() +{ + T retval; + if (this->mtx.try_lock()){ + + if (this->isEmpty()) + { + return std::nullopt; + } + + retval = this->data[this->rd_index]; + this->rd_index = this->incrementIndex(this->rd_index); + this->mtx.unlock(); + return retval; + + } + return std::nullopt; +} + +template +std::optional SimulatorMPMCQueue::peek() +{ + T retval; + if (this->mtx.try_lock()) + { + if (this->isEmpty()) + { + return std::nullopt; + } + + retval = this->data[this->rd_index]; + this->mtx.unlock(); + return retval; + } + return std::nullopt; +} + +template +uint32_t SimulatorMPMCQueue::incrementIndex(uint32_t index) +{ + return (index + 1) % this->size; +} \ No newline at end of file diff --git a/Platformio/HAL/Targets/Simulator/SimulatorMPMCQueue.hpp b/Platformio/HAL/Targets/Simulator/SimulatorMPMCQueue.hpp new file mode 100644 index 0000000..947c742 --- /dev/null +++ b/Platformio/HAL/Targets/Simulator/SimulatorMPMCQueue.hpp @@ -0,0 +1,24 @@ +#pragma once +#include "MPMCQueueInterface.hpp" +#include "SimulatorSPSCQueue.hpp" +#include + +template +class SimulatorMPMCQueue: public SimulatorSPSCQueue, public MPMCQueueInterface +{ + public: + SimulatorMPMCQueue(uint32_t size): SimulatorSPSCQueue(size){}; + bool push (T obj); + bool push (T obj, bool overwrite); + std::optional pop(); + std::optional peek(); + bool isFull(); + bool isEmpty(); + private: + T* data; + uint32_t size; + uint32_t rd_index; + uint32_t wr_index; + uint32_t incrementIndex(uint32_t index); + std::mutex mtx; +}; \ No newline at end of file diff --git a/Platformio/HAL/Targets/Simulator/SimulatorSPSCQueue.cpp b/Platformio/HAL/Targets/Simulator/SimulatorSPSCQueue.cpp new file mode 100644 index 0000000..4f8bcd2 --- /dev/null +++ b/Platformio/HAL/Targets/Simulator/SimulatorSPSCQueue.cpp @@ -0,0 +1,68 @@ +#include "SimulatorSPSCQueue.hpp" + +template +SimulatorSPSCQueue::SimulatorSPSCQueue(uint32_t size) +{ + this->size = size; + this->data = new T[](this->size + 1); + this->rd_index = 0; + this->wr_index = 0; +} + +template +SimulatorSPSCQueue::~SimulatorSPSCQueue() +{ + free(this->data); +} + +template +bool SimulatorSPSCQueue::isFull() +{ + return ((this->wr_index + 1) % this->size) == this->rd_index; +} + +template +bool SimulatorSPSCQueue::isEmpty() +{ + return this->rd_index == this->wr_index; +} + +template +bool SimulatorSPSCQueue::push(T obj) +{ + bool retval = false; + if (!this->isFull()) + { + retval = true; + this->data[this->wr_index] = obj; + this->wr_index = this->incrementIndex(this->wr_index); + } + return retval; +} + +template +std::optional SimulatorSPSCQueue::pop() +{ + std::optional retval; + + retval = this->peek(); + + this->rd_index = this->incrementIndex(this->rd_index); + return retval; +} + +template +std::optional SimulatorSPSCQueue::peek() +{ + if (this->isEmpty()) + { + return std::nullopt; + } + return this->data[this->rd_index]; +} + +template +uint32_t SimulatorSPSCQueue::incrementIndex(uint32_t index) +{ + return (index + 1) % this->size; +} \ No newline at end of file diff --git a/Platformio/HAL/Targets/Simulator/SimulatorSPSCQueue.hpp b/Platformio/HAL/Targets/Simulator/SimulatorSPSCQueue.hpp new file mode 100644 index 0000000..21b94e0 --- /dev/null +++ b/Platformio/HAL/Targets/Simulator/SimulatorSPSCQueue.hpp @@ -0,0 +1,22 @@ +#pragma once +#include "SPSCQueueInterface.hpp" +#include + +template +class SimulatorSPSCQueue: public SPSCQueueInterface +{ + public: + SimulatorSPSCQueue(uint32_t size); + ~SimulatorSPSCQueue(); + bool push (T obj); + std::optional pop(); + std::optional peek(); + bool isFull(); + bool isEmpty(); + private: + T* data; + uint32_t size; + uint32_t rd_index; + uint32_t wr_index; + uint32_t incrementIndex(uint32_t index); +}; \ No newline at end of file diff --git a/Platformio/HAL/Targets/Simulator/batterySimulator.hpp b/Platformio/HAL/Targets/Simulator/batterySimulator.hpp new file mode 100644 index 0000000..dea050a --- /dev/null +++ b/Platformio/HAL/Targets/Simulator/batterySimulator.hpp @@ -0,0 +1,23 @@ +#include "BatteryInterface.h" +#include +#include +class BatterySimulator: public BatteryInterface{ + public: + BatterySimulator() : + mCreationTime(std::chrono::high_resolution_clock::now()) + {}; + ~BatterySimulator(){} + + virtual int getPercentage() override { + auto now = std::chrono::high_resolution_clock::now(); + auto batteryRunTime = std::chrono::duration_cast(now - mCreationTime); + constexpr auto minToBatteryZero = 3; + auto fakeBattPercentage = 100 - ((batteryRunTime / std::chrono::duration>(minToBatteryZero)) * 100); + return std::floor(fakeBattPercentage < 100 ? fakeBattPercentage : 0); + } + + virtual bool isCharging() override { return false; } + + private: + std::chrono::_V2::system_clock::time_point mCreationTime; +}; \ No newline at end of file diff --git a/Platformio/HAL/Targets/Simulator/omoteconfig.h b/Platformio/HAL/Targets/Simulator/omoteconfig.h index 4f8b2f6..0838bbe 100644 --- a/Platformio/HAL/Targets/Simulator/omoteconfig.h +++ b/Platformio/HAL/Targets/Simulator/omoteconfig.h @@ -1,6 +1,3 @@ #pragma once #define IS_SIMULATOR true - -#define SCREEN_WIDTH 240 -#define SCREEN_HEIGHT 360 diff --git a/Platformio/HAL/Targets/Simulator/wifiHandlerSim/wifiHandlerSim.cpp b/Platformio/HAL/Targets/Simulator/wifiHandlerSim/wifiHandlerSim.cpp new file mode 100644 index 0000000..7534534 --- /dev/null +++ b/Platformio/HAL/Targets/Simulator/wifiHandlerSim/wifiHandlerSim.cpp @@ -0,0 +1,68 @@ +#include "wifiHandlerSim.hpp" + +std::shared_ptr mInstance; + +std::shared_ptr wifiHandlerSim::getInstance() +{ + if(mInstance) + { + return mInstance; + } + mInstance = std::make_shared(wifiHandlerSim()); + return mInstance; +}; + +wifiHandlerSim::wifiHandlerSim(){ + +} + +void wifiHandlerSim::begin(){ + +} + +static wifiStatus status = { + .isConnected = true + , .IP = "172.0.0.1" +}; + +void wifiHandlerSim::connect(std::shared_ptr ssid, std::shared_ptr password){ + status.ssid = *ssid; + std::shared_ptr new_status = std::make_shared (wifiStatus(std::move(status))); + this->status_update.notify(new_status); +} + +static const WifiInfo wifis[] = { + { + .ssid = "High Signal Wifi" + , .rssi = -49 + } + , { + .ssid = "Mid Signal Wifi" + , .rssi = -55 + } + , { + .ssid = "Low Signal Wifi" + , .rssi = -65 + } + , { + .ssid = "No Signal Wifi" + , .rssi = -90 + } +}; + +void wifiHandlerSim::scan(){ + std::shared_ptr> info = std::make_shared>(std::vector(std::begin(wifis), std::end(wifis))); + this->scan_notification.notify(info); +} + +bool wifiHandlerSim::isAvailable(){ + return false; +} + +void wifiHandlerSim::onScanDone(std::function>)> function){ + this->scan_notification.onNotify(std::move(function)); +} + +void wifiHandlerSim::onStatusUpdate(std::function)> function){ + this->status_update.onNotify(std::move(function)); +} \ No newline at end of file diff --git a/Platformio/HAL/Targets/Simulator/wifiHandlerSim/wifiHandlerSim.hpp b/Platformio/HAL/Targets/Simulator/wifiHandlerSim/wifiHandlerSim.hpp new file mode 100644 index 0000000..e994450 --- /dev/null +++ b/Platformio/HAL/Targets/Simulator/wifiHandlerSim/wifiHandlerSim.hpp @@ -0,0 +1,35 @@ +#pragma once +#include "wifiHandlerInterface.h" +#include "Notification.hpp" +#include + +class wifiHandlerSim: public wifiHandlerInterface { + public: + wifiHandlerSim(); + static std::shared_ptr getInstance(); + + + /** + * @brief Connect to the wifi using the provided credetials + * + * @param SSID + * @param password + */ + void connect(std::shared_ptr ssid, std::shared_ptr password); + //void connect(const char* SSID, const char* password); + + + + /** + * @brief function to trigger asynchronous scan for wifi networks + * + */ + void scan(); + bool isAvailable(); + void begin(); + void onScanDone(std::function>)> function); + void onStatusUpdate(std::function)> function); + private: + Notification>> scan_notification; + Notification> status_update; +}; \ No newline at end of file diff --git a/Platformio/OmoteUI/Images.cpp b/Platformio/OmoteUI/Images.cpp new file mode 100644 index 0000000..0a32e1a --- /dev/null +++ b/Platformio/OmoteUI/Images.cpp @@ -0,0 +1,1154 @@ +#include "Images.hpp" + +static void update_default_image_color(lv_obj_t* image) +{ + lv_obj_set_style_img_recolor(image, lv_color_white(), LV_PART_MAIN); + lv_obj_set_style_img_recolor_opa(image, LV_OPA_COVER, LV_PART_MAIN); +} + +Images::Images(){ + setupImageDescriptions(); +} + +lv_obj_t* Images::addAppleTVIcon(lv_obj_t* parent) { + return this->addImg(parent, &this->appleTvIcon); +} +lv_obj_t* Images::addAppleDisplayImage(lv_obj_t* parent) { + lv_obj_t* appleImg = this->addImg(parent, &this->appleDisplayIcon); + lv_obj_set_style_img_recolor(appleImg, lv_color_white(), LV_PART_MAIN); + lv_obj_set_style_img_recolor_opa(appleImg, LV_OPA_COVER, LV_PART_MAIN); + return appleImg; +} +lv_obj_t* Images::addAppleBackIcon(lv_obj_t* parent) { + return this->addImg(parent, &this->appleBackIcon); +} + +lv_obj_t* Images::addLowBrightnessIcon(lv_obj_t* parent) { + lv_obj_t* lowBrightnessIcon = this->addImg(parent, &this->low_brightness); + lv_obj_set_style_img_recolor(lowBrightnessIcon, lv_color_white(), LV_PART_MAIN); + lv_obj_set_style_img_recolor_opa(lowBrightnessIcon, LV_OPA_COVER, LV_PART_MAIN); + return lowBrightnessIcon; +} +lv_obj_t* Images::addHighBrightnessIcon(lv_obj_t* parent) { + lv_obj_t* highBrightnessIcon = this->addImg(parent, &this->high_brightness); + lv_obj_set_style_img_recolor(highBrightnessIcon, lv_color_white(), LV_PART_MAIN); + lv_obj_set_style_img_recolor_opa(highBrightnessIcon, LV_OPA_COVER, LV_PART_MAIN); + return highBrightnessIcon; +} +lv_obj_t* Images::addLightBulbIcon(lv_obj_t* parent){ + lv_obj_t* bulbIcon = this->addImg(parent, &this->lightbulb_icon); + lv_obj_set_style_img_recolor(bulbIcon, lv_color_white(), LV_PART_MAIN); + return bulbIcon; +} + +lv_obj_t* Images::addWifiNoSignal(lv_obj_t* parent){ + lv_obj_t* noSignal = this->addImg(parent, &this->wifiNoSignal); + update_default_image_color(noSignal); + return noSignal; +} +lv_obj_t* Images::addWifiLowSignal(lv_obj_t* parent){ + lv_obj_t* lowSignal = this->addImg(parent, &this->wifiLowSignal); + update_default_image_color(lowSignal); + return lowSignal; +} +lv_obj_t* Images::addWifiMidSignal(lv_obj_t* parent){ + lv_obj_t* lowSignal = this->addImg(parent, &this->wifiMidSignal); + update_default_image_color(lowSignal); + return lowSignal; +} +lv_obj_t* Images::addWifiHighSignal(lv_obj_t* parent){ + lv_obj_t* lowSignal = this->addImg(parent, &this->wifiHighSignal); + update_default_image_color(lowSignal); + return lowSignal; +} + +lv_obj_t* Images::addLeftGradiant(lv_obj_t* parent){ + return this->addImg(parent, &this->gradientLeft); +} + +lv_obj_t* Images::addRightGradiant(lv_obj_t* parent){ + return this->addImg(parent, &this->gradientRight); +} + +lv_obj_t* Images::addImg(lv_obj_t* parent, lv_img_dsc_t* anImgDesc) { + lv_obj_t* img = lv_img_create(parent); + lv_img_set_src(img, anImgDesc); + return img; +} + +inline static const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_LARGE_CONST uint8_t + gradientLeft_map[] = { + 0xfa, 0xf2, 0xea, 0xe2, 0xda, 0xd1, 0xc7, 0xbe, 0xb7, 0xae, + 0xa6, 0x9e, 0x95, 0x8d, 0x84, 0x7d, 0x74, 0x6c, 0x62, 0x5a, + 0x51, 0x48, 0x41, 0x38, 0x2f, 0x28, 0x1f, 0x17, 0x0f, 0x07, +}; + +inline static const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_LARGE_CONST uint8_t + gradientRight_map[] = { + 0x07, 0x0f, 0x17, 0x1f, 0x28, 0x2f, 0x38, 0x41, 0x48, 0x51, + 0x5a, 0x62, 0x6c, 0x74, 0x7d, 0x84, 0x8d, 0x95, 0x9e, 0xa6, + 0xae, 0xb7, 0xbe, 0xc7, 0xd1, 0xda, 0xe2, 0xea, 0xf2, 0xfa, +}; + +inline static const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_LARGE_CONST uint8_t + appleTvIcon_map[] = { + /*Pixel format: Red: 5 bit, Green: 6 bit, Blue: 5 bit*/ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x42, 0x55, 0xad, 0xdb, 0xde, 0x1c, 0xe7, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x55, 0xad, 0xdf, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x5d, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79, 0xce, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdb, 0xde, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, + 0x21, 0x34, 0xa5, 0x55, 0xad, 0x55, 0xad, 0x55, 0xad, 0x55, 0xad, + 0x55, 0xad, 0x55, 0xad, 0xcf, 0x7b, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x18, 0xc6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x76, 0xb5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xe7, 0x39, 0xdf, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xb7, + 0xbd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x71, 0x8c, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x69, 0x4a, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe7, 0x39, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xb7, 0xbd, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x5d, 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xf7, 0xbd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe7, 0x39, 0xdf, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xb7, 0xbd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xcf, 0x7b, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x5d, 0xef, 0x65, 0x29, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xe7, 0x39, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xb7, 0xbd, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb6, + 0xb5, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7d, 0xef, + 0x8a, 0x52, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe7, 0x39, 0xdf, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xb7, 0xbd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x59, 0xce, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x9a, 0xd6, 0x08, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xe7, 0x39, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xb7, 0xbd, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x55, 0xad, 0x9a, 0xd6, 0xd7, 0xbd, 0x8e, 0x73, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe7, 0x39, 0xdf, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xb7, 0xbd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x73, 0xd7, + 0xbd, 0xbb, 0xde, 0x3c, 0xe7, 0xfc, 0xe6, 0x39, 0xce, 0x72, 0x94, + 0xa7, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa3, 0x18, 0x8e, 0x73, 0xd7, 0xbd, 0x1c, 0xe7, 0x9e, 0xf7, + 0xbe, 0xf7, 0x5d, 0xef, 0x9a, 0xd6, 0x34, 0xa5, 0x28, 0x42, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xe7, 0x39, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xb7, 0xbd, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, + 0x6b, 0xfb, 0xde, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, 0xff, 0x7a, 0xd6, 0x71, + 0x8c, 0xa6, 0x31, 0x2d, 0x6b, 0xb6, 0xb5, 0x7d, 0xef, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xdf, 0xff, 0xd7, 0xbd, 0xa3, 0x18, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa7, 0x39, + 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xb7, 0xbd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xb3, 0x9c, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x3c, 0xe7, 0x49, 0x4a, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0xe7, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x38, + 0xc6, 0x00, 0x00, 0x00, 0x00, 0x69, 0x4a, 0xdf, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x59, + 0xce, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xf7, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, 0xff, 0x14, + 0xa5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb3, 0x9c, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3d, + 0xef, 0x24, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x5d, 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x39, 0xce, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xdb, 0xde, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xbe, 0xf7, 0x45, 0x29, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xf0, 0x83, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x1c, 0xe7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0c, 0x63, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x5d, 0xef, 0xeb, 0x5a, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5d, + 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x39, 0xce, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb3, 0x9c, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x10, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xc6, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x14, 0xa5, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdb, 0xde, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdb, 0xde, + 0x86, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x5d, 0xef, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x39, 0xce, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x86, 0x31, 0xbf, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x39, 0xce, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x7e, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xdf, 0xff, 0xe7, 0x39, 0x00, 0x00, 0x00, 0x00, 0x8e, + 0x73, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x3d, 0xef, 0x86, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x5d, 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x39, 0xce, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x59, 0xce, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xbe, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x8e, 0x73, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x9a, 0xd6, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x79, 0xce, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x6d, 0x6b, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7a, 0xd6, 0x3c, 0xe7, 0x3c, + 0xe7, 0x3d, 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x9e, 0xf7, 0x3c, 0xe7, 0x3c, + 0xe7, 0x3c, 0xe7, 0x3c, 0xe7, 0x3c, 0xe7, 0x96, 0xb5, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x83, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xf0, 0x83, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xd7, 0xbd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x71, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x9e, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x7a, 0xd6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa7, 0x39, 0xdf, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xb7, 0xbd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x7e, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x18, 0xc6, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7d, 0xef, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x9e, 0xf7, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xec, 0x62, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x71, 0x8c, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xe7, 0x39, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xb7, 0xbd, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb7, 0xbd, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x7d, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, + 0x73, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xf8, 0xc5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, + 0x8c, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x49, 0x4a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe7, 0x39, 0xdf, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xb7, 0xbd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0c, 0x63, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x4d, 0x6b, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xd7, 0xbd, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x6e, 0x73, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xd3, 0x9c, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0xff, 0xe4, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xe7, 0x39, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xb7, 0xbd, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x1c, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xd7, 0xbd, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x3d, 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x5d, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x55, 0xad, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xbf, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe7, 0x39, + 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xb7, 0xbd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0xa5, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x5d, + 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xeb, 0x5a, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x76, 0xb5, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0xa5, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, 0xff, 0x28, 0x42, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xe7, 0x39, 0xdf, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xb7, 0xbd, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xa7, 0x39, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x2d, 0x6b, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x96, + 0xb5, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x29, 0x4a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x92, 0x94, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xae, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe7, + 0x39, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xb7, 0xbd, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9a, + 0xd6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x96, 0xb5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0xef, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbb, 0xde, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x83, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, + 0xc5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xe7, 0x39, 0xdf, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xb7, + 0xbd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x72, 0x94, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1c, 0xe7, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xeb, 0x5a, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xd3, 0x9c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x8a, 0x52, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0xff, 0x28, 0x42, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe7, 0x39, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xb7, 0xbd, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xbe, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x8a, 0x52, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x55, 0xad, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, 0xff, 0x45, 0x29, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9e, + 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x7a, 0xd6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe7, 0x39, 0xdf, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xb7, 0xbd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xc6, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x75, 0xad, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, + 0xe6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x59, 0xce, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x9a, 0xd6, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xb7, + 0xbd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xe7, 0x39, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xb7, 0xbd, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x6d, 0x6b, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0xe6, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x29, 0x4a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xcf, 0x7b, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xf4, 0xa4, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x59, 0xce, 0x86, 0x31, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe7, 0x39, 0xdf, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xb7, 0xbd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x3d, 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x49, 0x4a, 0x00, 0x00, 0x00, 0x00, 0x55, 0xad, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7d, + 0xef, 0xa3, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa6, 0x31, 0xdf, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x9e, 0xf7, 0xef, 0x7b, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xe7, 0x39, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xb7, 0xbd, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x96, 0xb5, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x14, 0xa5, + 0x00, 0x00, 0x00, 0x00, 0xfb, 0xde, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xd7, 0xbd, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x9a, 0xd6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x0c, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe7, 0x39, 0xdf, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xb7, 0xbd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x49, 0x4a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xdb, 0xde, 0x00, 0x00, 0x29, 0x4a, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xeb, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x8c, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xdb, 0xde, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xe7, 0x39, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x39, 0xce, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdb, 0xde, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xe7, 0x39, 0xf3, 0x9c, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xfc, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0xe7, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x10, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe7, 0x39, + 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x7d, 0xef, 0x24, 0x21, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x86, 0x31, 0x29, 0x4a, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xd3, 0x9c, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0x9c, 0xbb, 0xde, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x14, + 0xa5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x51, 0x8c, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xfc, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xa7, 0x39, 0xdf, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xfc, 0xe6, 0xd3, 0x9c, 0x51, 0x8c, 0x34, 0xa5, 0x9a, 0xd6, 0xdf, + 0xff, 0xf7, 0xbd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa6, + 0x31, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xdb, 0xde, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xdf, 0xff, 0x08, 0x42, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xe6, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xcf, + 0x7b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xbf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1c, 0xe7, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x59, 0xce, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x9a, 0xd6, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xec, 0x62, 0xdf, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x79, 0xce, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0xe7, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xdf, 0xff, 0xe7, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xcf, 0x7b, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x51, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x55, 0xad, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x9e, 0xf7, 0xe7, 0x39, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xb7, 0xbd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x30, + 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7d, + 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x9e, 0xf7, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x59, 0xce, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x10, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe8, 0x41, 0xdf, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xf7, 0xbd, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xd7, 0xbd, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x18, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9a, 0xd6, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xb2, 0x94, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x8c, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x39, 0xce, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0c, 0x63, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x8e, 0x73, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x18, 0xc6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x9e, 0xf7, 0x39, 0xce, 0x72, 0x94, 0xcb, + 0x5a, 0xa3, 0x18, 0x4d, 0x6b, 0x34, 0xa5, 0xfb, 0xde, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbe, 0xf7, 0x72, + 0x94, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xaf, 0x7b, 0x3c, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x7d, 0xef, 0xd7, 0xbd, 0xeb, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0xe7, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x5d, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x6e, 0x73, 0xf8, 0xc5, 0xba, 0xd6, 0xd7, 0xbd, 0xf0, 0x83, 0xa3, + 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x49, 0x4a, 0xf3, 0x9c, 0xf8, 0xc5, 0x59, + 0xce, 0x55, 0xad, 0x08, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xae, 0x73, 0x76, 0xb5, 0x39, 0xce, 0x7a, 0xd6, 0x39, 0xce, + 0xd7, 0xbd, 0xd3, 0x9c, 0xec, 0x62, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x29, 0x4a, 0x0c, 0x63, 0x0c, 0x63, 0x0c, 0x63, + 0x0c, 0x63, 0x0c, 0x63, 0x0c, 0x63, 0x0c, 0x63, 0x49, 0x4a, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + +inline static const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_LARGE_CONST uint8_t + appleDisplayIcon_map[] = { + 0x23, 0xc6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xd8, 0x3d, 0xaa, 0xfd, 0xad, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, + 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, + 0x9a, 0x9a, 0x9a, 0xa1, 0xf7, 0xd8, 0xd0, 0xd1, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa1, 0xff, 0xd2, 0xcb, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9a, + 0xff, 0xd2, 0xcb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x9a, 0xff, 0xd2, 0xcb, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x9a, 0xff, 0xd2, 0xcb, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9a, 0xff, 0xd2, + 0xcb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x9a, 0xff, 0xd2, 0xcb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x9a, 0xff, 0xd2, 0xcb, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9a, 0xff, 0xd2, 0xcb, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9a, 0xff, + 0xd2, 0xcb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x9a, 0xff, 0xd2, 0xcb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x9a, 0xff, 0xd2, 0xcb, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9a, 0xff, 0xc6, 0xea, + 0x2a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, + 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1f, 0xcc, + 0xf6, 0x6c, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x98, 0x00, 0x44, 0x7b, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x7d, 0x56, 0x03, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xb7, 0xc4, 0xc4, 0xc4, 0xc4, + 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc0, 0x2c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0xd3, 0xde, + 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xdb, 0x36, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +inline static const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_LARGE_CONST uint8_t + appleBackIcon_map[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x0f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x3d, 0xbe, 0x94, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x3b, 0xe7, 0xff, 0xf0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3b, 0xfa, 0xff, 0xf5, 0x31, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0xfc, 0xff, 0xea, 0x3e, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0xee, 0xff, 0xe6, + 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x50, 0xed, 0xff, + 0xe9, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0xfc, + 0xff, 0xe7, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x59, + 0xff, 0xff, 0xe0, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x5e, 0xf6, 0xff, 0xdb, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x64, 0xf4, 0xff, 0xd9, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x4d, 0xff, 0xff, 0xce, 0x1c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x6b, 0xff, 0xff, 0x9e, 0x07, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0xff, 0xff, 0xa8, + 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x8f, + 0xff, 0xff, 0xb5, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x03, 0x91, 0xff, 0xff, 0xba, 0x12, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x93, 0xff, 0xff, 0xbb, 0x0a, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x87, 0xfc, 0xff, + 0xbf, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x7c, 0xfb, 0xff, 0xc5, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x78, 0xff, 0xff, 0xca, 0x1e, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x75, 0xff, 0xff, 0xd0, 0x11, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x6e, 0xfb, + 0xff, 0xcc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x68, 0xea, 0xca, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x04, 0x28, 0x18, +}; + +inline static const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_LARGE_CONST uint8_t + high_brightness_map[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0xc1, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xd4, 0xd4, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x8e, 0x04, 0x00, 0x00, 0x00, + 0xc1, 0xc1, 0x00, 0x00, 0x00, 0x04, 0x8e, 0x5c, 0x00, 0x00, 0x00, + 0x00, 0x8c, 0xff, 0xa8, 0x01, 0x00, 0x00, 0x0c, 0x0c, 0x00, 0x00, + 0x01, 0xa8, 0xff, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x04, 0xa9, 0xf5, + 0x0d, 0x00, 0x00, 0x11, 0x11, 0x00, 0x00, 0x0d, 0xf5, 0xa9, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0a, 0x00, 0x42, 0xd4, 0xff, + 0xff, 0xd4, 0x41, 0x00, 0x0a, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x42, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xfd, 0x40, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd5, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xd3, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xbd, 0xcc, 0xbd, 0x0d, 0x11, 0xfe, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xfe, 0x12, 0x0d, 0xbd, 0xcc, 0xbd, 0xbd, 0xcc, 0xbd, + 0x0d, 0x11, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x10, + 0x0d, 0xbd, 0xcc, 0xbd, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd4, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xd2, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0xfd, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x0a, 0x00, 0x40, 0xd3, 0xff, 0xfe, 0xd2, 0x3f, 0x00, 0x0a, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xa9, 0xf5, 0x0d, 0x00, 0x00, + 0x10, 0x10, 0x00, 0x00, 0x0d, 0xf5, 0xa9, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x8c, 0xff, 0xa8, 0x01, 0x00, 0x00, 0x0c, 0x0c, 0x00, 0x00, + 0x01, 0xa8, 0xff, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x8e, 0x04, + 0x00, 0x00, 0x00, 0xc1, 0xc1, 0x00, 0x00, 0x00, 0x04, 0x8e, 0x5c, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd4, + 0xd4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0xc1, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +inline static const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_LARGE_CONST uint8_t + low_brightness_map[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x43, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xbd, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x27, 0x72, 0x01, 0x00, 0x00, 0x0c, 0x0c, 0x00, 0x00, 0x01, + 0x72, 0x28, 0x00, 0x00, 0x00, 0x00, 0x71, 0xf5, 0x0f, 0x00, 0x00, + 0x11, 0x11, 0x00, 0x00, 0x0d, 0xf5, 0x73, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x0b, 0x00, 0x42, 0xd4, 0xff, 0xff, 0xd4, 0x41, 0x00, 0x0a, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0xfd, 0xff, 0xff, + 0xff, 0xff, 0xfd, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xd5, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xd3, 0x00, 0x00, + 0x00, 0x00, 0x43, 0xbd, 0x0d, 0x11, 0xfe, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xfe, 0x12, 0x0d, 0xbc, 0x44, 0x43, 0xbd, 0x0d, 0x11, + 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x11, 0x0d, 0xbc, + 0x44, 0x00, 0x00, 0x00, 0x00, 0xd4, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xd2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, + 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x0b, 0x00, 0x40, 0xd3, 0xfe, 0xff, 0xd2, 0x3f, + 0x00, 0x0a, 0x01, 0x00, 0x00, 0x00, 0x00, 0x71, 0xf5, 0x0f, 0x00, + 0x00, 0x10, 0x10, 0x00, 0x00, 0x0d, 0xf5, 0x73, 0x00, 0x00, 0x00, + 0x00, 0x27, 0x72, 0x01, 0x00, 0x00, 0x0c, 0x0c, 0x00, 0x00, 0x01, + 0x72, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xbd, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x44, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, +}; + +inline static const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_LARGE_CONST uint8_t + lightbulb_map[] = { + 0x00, 0x00, 0x00, 0x00, 0x04, 0x1c, 0x1c, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x16, 0x95, 0xee, 0xff, 0xff, 0xee, 0x94, 0x15, + 0x00, 0x00, 0x00, 0x27, 0xe3, 0xff, 0xcc, 0x8d, 0x8d, 0xcd, 0xff, + 0xe1, 0x26, 0x00, 0x07, 0xd9, 0xfa, 0x5d, 0x00, 0x00, 0x00, 0x00, + 0x5f, 0xfa, 0xd7, 0x06, 0x65, 0xff, 0x77, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7a, 0xff, 0x63, 0xb1, 0xf8, 0x0c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0d, 0xf8, 0xaf, 0xcc, 0xdc, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xdb, 0xcd, 0xb1, 0xf5, 0x04, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xf1, 0xbd, 0x73, 0xff, 0x74, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x71, 0xff, 0x74, 0x0b, 0xd5, + 0xfb, 0x40, 0x00, 0x00, 0x00, 0x00, 0x41, 0xfb, 0xd9, 0x0b, 0x00, + 0x24, 0xef, 0xdc, 0x01, 0x00, 0x00, 0x01, 0xdd, 0xee, 0x24, 0x00, + 0x00, 0x00, 0x83, 0xff, 0x30, 0x00, 0x00, 0x30, 0xff, 0x81, 0x00, + 0x00, 0x00, 0x00, 0x12, 0x6c, 0x06, 0x00, 0x00, 0x06, 0x6c, 0x12, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x25, 0xc7, 0xcc, 0xcc, 0xcc, 0xcc, + 0xc7, 0x25, 0x00, 0x00, 0x00, 0x00, 0x25, 0xc7, 0xcc, 0xcc, 0xcc, + 0xcc, 0xc7, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x76, + 0x77, 0x77, 0x76, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x69, + 0xff, 0xff, 0xff, 0xff, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x21, 0x22, 0x22, 0x21, 0x01, 0x00, 0x00, 0x00, +}; + +inline static const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_LARGE_CONST uint8_t WiFi_No_Signal_map[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, + 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, + 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, + 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, + 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +inline static const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_LARGE_CONST uint8_t WiFi_Mid_Signal_map[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, + 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, + 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, + 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, + 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +inline static const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_LARGE_CONST uint8_t WiFi_Low_Signal_map[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, + 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, + 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, + 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, + 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +inline static const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_LARGE_CONST uint8_t WiFi_High_Signal_map[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, + 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +void Images::setupImageDescriptions(){ + this->low_brightness.header.cf = LV_IMG_CF_ALPHA_8BIT; + this->low_brightness.header.always_zero = 0; + this->low_brightness.header.reserved = 0; + this->low_brightness.header.w = 16; + this->low_brightness.header.h = 16; + this->low_brightness.data_size = 256; + this->low_brightness.data = low_brightness_map; + + this->high_brightness.header.cf = LV_IMG_CF_ALPHA_8BIT; + this->high_brightness.header.always_zero = 0; + this->high_brightness.header.reserved = 0; + this->high_brightness.header.w = 18; + this->high_brightness.header.h = 18; + this->high_brightness.data_size = 352; + this->high_brightness.data = high_brightness_map; + + this->appleTvIcon.header.cf = LV_IMG_CF_TRUE_COLOR; + this->appleTvIcon.header.always_zero = 0; + this->appleTvIcon.header.reserved = 0; + this->appleTvIcon.header.w = 91; + this->appleTvIcon.header.h = 42; + this->appleTvIcon.data_size = 3822 * LV_COLOR_SIZE / 8; + this->appleTvIcon.data = appleTvIcon_map; + + this->appleDisplayIcon.header.cf = LV_IMG_CF_ALPHA_8BIT; + this->appleDisplayIcon.header.always_zero = 0; + this->appleDisplayIcon.header.reserved = 0; + this->appleDisplayIcon.header.w = 25; + this->appleDisplayIcon.header.h = 20; + this->appleDisplayIcon.data_size = 500; + this->appleDisplayIcon.data = appleDisplayIcon_map; + + this->appleBackIcon.header.cf = LV_IMG_CF_ALPHA_8BIT; + this->appleBackIcon.header.always_zero = 0; + this->appleBackIcon.header.reserved = 0; + this->appleBackIcon.header.w = 13; + this->appleBackIcon.header.h = 25; + this->appleBackIcon.data_size = 325; + this->appleBackIcon.data = appleBackIcon_map; + + this->lightbulb_icon.header.cf = LV_IMG_CF_ALPHA_8BIT, lightbulb_icon.header.always_zero = 0, + this->lightbulb_icon.header.reserved = 0, lightbulb_icon.header.w = 12, + this->lightbulb_icon.header.h = 20, lightbulb_icon.data_size = 240, + this->lightbulb_icon.data = lightbulb_map; + + this->gradientLeft.header.cf = LV_IMG_CF_ALPHA_8BIT; + this->gradientLeft.header.always_zero = 0; + this->gradientLeft.header.reserved = 0; + this->gradientLeft.header.w = 30; + this->gradientLeft.header.h = 1; + this->gradientLeft.data_size = 30; + this->gradientLeft.data = gradientLeft_map; + + this->gradientRight.header.cf = LV_IMG_CF_ALPHA_8BIT; + this->gradientRight.header.always_zero = 0; + this->gradientRight.header.reserved = 0; + this->gradientRight.header.w = 30; + this->gradientRight.header.h = 1; + this->gradientRight.data_size = 30; + this->gradientRight.data = gradientRight_map; + + this->wifiNoSignal.header.cf = LV_IMG_CF_ALPHA_8BIT; + this->wifiNoSignal.header.always_zero = 0; + this->wifiNoSignal.header.reserved = 0; + this->wifiNoSignal.header.w = 25; + this->wifiNoSignal.header.h = 21; + this->wifiNoSignal.data_size = 525; + this->wifiNoSignal.data = WiFi_No_Signal_map; + + this->wifiLowSignal.header.cf = LV_IMG_CF_ALPHA_8BIT; + this->wifiLowSignal.header.always_zero = 0; + this->wifiLowSignal.header.reserved = 0; + this->wifiLowSignal.header.w = 25; + this->wifiLowSignal.header.h = 21; + this->wifiLowSignal.data_size = 525; + this->wifiLowSignal.data = WiFi_Low_Signal_map; + + this->wifiMidSignal.header.cf = LV_IMG_CF_ALPHA_8BIT; + this->wifiMidSignal.header.always_zero = 0; + this->wifiMidSignal.header.reserved = 0; + this->wifiMidSignal.header.w = 25; + this->wifiMidSignal.header.h = 21; + this->wifiMidSignal.data_size = 525; + this->wifiMidSignal.data = WiFi_Mid_Signal_map; + + this->wifiHighSignal.header.cf = LV_IMG_CF_ALPHA_8BIT; + this->wifiHighSignal.header.always_zero = 0; + this->wifiHighSignal.header.reserved = 0; + this->wifiHighSignal.header.w = 25; + this->wifiHighSignal.header.h = 21; + this->wifiHighSignal.data_size = 525; + this->wifiHighSignal.data = WiFi_High_Signal_map; + +} \ No newline at end of file diff --git a/Platformio/OmoteUI/Images.hpp b/Platformio/OmoteUI/Images.hpp index 53127d4..be23311 100644 --- a/Platformio/OmoteUI/Images.hpp +++ b/Platformio/OmoteUI/Images.hpp @@ -6,57 +6,30 @@ class Images{ public: - Images(){ - setupImageDescriptions(); - } + Images(); - lv_obj_t* addAppleTVIcon(lv_obj_t* parent) { - return addImg(parent, &appleTvIcon); - } - lv_obj_t* addAppleDisplayImage(lv_obj_t* parent) { - lv_obj_t* appleImg = addImg(parent, &appleDisplayIcon); - lv_obj_set_style_img_recolor(appleImg, lv_color_white(), LV_PART_MAIN); - lv_obj_set_style_img_recolor_opa(appleImg, LV_OPA_COVER, LV_PART_MAIN); - return appleImg; - } - lv_obj_t* addAppleBackIcon(lv_obj_t* parent) { - return addImg(parent, &appleBackIcon); - } + lv_obj_t* addAppleTVIcon(lv_obj_t* parent); + lv_obj_t* addAppleDisplayImage(lv_obj_t* parent); + lv_obj_t* addAppleBackIcon(lv_obj_t* parent); - lv_obj_t* addLowBrightnessIcon(lv_obj_t* parent) { - lv_obj_t* lowBrightnessIcon = addImg(parent, &low_brightness); - lv_obj_set_style_img_recolor(lowBrightnessIcon, lv_color_white(), LV_PART_MAIN); - lv_obj_set_style_img_recolor_opa(lowBrightnessIcon, LV_OPA_COVER, LV_PART_MAIN); - return lowBrightnessIcon; - } - lv_obj_t* addHighBrightnessIcon(lv_obj_t* parent) { - lv_obj_t* highBrightnessIcon = addImg(parent, &high_brightness); - lv_obj_set_style_img_recolor(highBrightnessIcon, lv_color_white(), LV_PART_MAIN); - lv_obj_set_style_img_recolor_opa(highBrightnessIcon, LV_OPA_COVER, LV_PART_MAIN); - return highBrightnessIcon; - } - lv_obj_t* addLightBulbIcon(lv_obj_t* parent){ - lv_obj_t* bulbIcon = addImg(parent, &lightbulb); - lv_obj_set_style_img_recolor(bulbIcon, lv_color_white(), LV_PART_MAIN); - lv_obj_set_style_img_recolor_opa(bulbIcon, LV_OPA_COVER, LV_PART_MAIN); - return bulbIcon; - } + lv_obj_t* addLowBrightnessIcon(lv_obj_t* parent); + lv_obj_t* addHighBrightnessIcon(lv_obj_t* parent); + lv_obj_t* addLightBulbIcon(lv_obj_t* parent); - lv_obj_t* addLeftGradiant(lv_obj_t* parent){ - return addImg(parent, &gradientLeft); - } - lv_obj_t* addRightGradiant(lv_obj_t* parent){ - return addImg(parent, &gradientRight); - } + lv_obj_t* addLeftGradiant(lv_obj_t* parent); + lv_obj_t* addRightGradiant(lv_obj_t* parent); + + lv_obj_t* addWifiNoSignal(lv_obj_t* parent); + lv_obj_t* addWifiLowSignal(lv_obj_t* parent); + lv_obj_t* addWifiMidSignal(lv_obj_t* parent); + lv_obj_t* addWifiHighSignal(lv_obj_t* parent); + private: // Make Image based on anImageDesc then // add that image to parent. - lv_obj_t* addImg(lv_obj_t* parent, lv_img_dsc_t* anImgDesc) { - lv_obj_t* img = lv_img_create(parent); - lv_img_set_src(img, anImgDesc); - return img; - } + lv_obj_t* addImg(lv_obj_t* parent, lv_img_dsc_t* anImgDesc); + void setupImageDescriptions(); lv_img_dsc_t appleTvIcon; lv_img_dsc_t appleDisplayIcon; @@ -64,957 +37,14 @@ private: lv_img_dsc_t low_brightness; lv_img_dsc_t high_brightness; - lv_img_dsc_t lightbulb; + lv_img_dsc_t lightbulb_icon; lv_img_dsc_t gradientLeft; lv_img_dsc_t gradientRight; - void setupImageDescriptions(){ - low_brightness.header.cf = LV_IMG_CF_ALPHA_8BIT; - low_brightness.header.always_zero = 0; - low_brightness.header.reserved = 0; - low_brightness.header.w = 16; - low_brightness.header.h = 16; - low_brightness.data_size = 256; - low_brightness.data = low_brightness_map; - - high_brightness.header.cf = LV_IMG_CF_ALPHA_8BIT; - high_brightness.header.always_zero = 0; - high_brightness.header.reserved = 0; - high_brightness.header.w = 18; - high_brightness.header.h = 18; - high_brightness.data_size = 352; - high_brightness.data = high_brightness_map; - - appleTvIcon.header.cf = LV_IMG_CF_TRUE_COLOR; - appleTvIcon.header.always_zero = 0; - appleTvIcon.header.reserved = 0; - appleTvIcon.header.w = 91; - appleTvIcon.header.h = 42; - appleTvIcon.data_size = 3822 * LV_COLOR_SIZE / 8; - appleTvIcon.data = appleTvIcon_map; - - appleDisplayIcon.header.cf = LV_IMG_CF_ALPHA_8BIT; - appleDisplayIcon.header.always_zero = 0; - appleDisplayIcon.header.reserved = 0; - appleDisplayIcon.header.w = 25; - appleDisplayIcon.header.h = 20; - appleDisplayIcon.data_size = 500; - appleDisplayIcon.data = appleDisplayIcon_map; - - appleBackIcon.header.cf = LV_IMG_CF_ALPHA_8BIT; - appleBackIcon.header.always_zero = 0; - appleBackIcon.header.reserved = 0; - appleBackIcon.header.w = 13; - appleBackIcon.header.h = 25; - appleBackIcon.data_size = 325; - appleBackIcon.data = appleBackIcon_map; - - lightbulb.header.cf = LV_IMG_CF_ALPHA_8BIT, lightbulb.header.always_zero = 0, - lightbulb.header.reserved = 0, lightbulb.header.w = 12, - lightbulb.header.h = 20, lightbulb.data_size = 240, - lightbulb.data = lightbulb_map; - - gradientLeft.header.cf = LV_IMG_CF_ALPHA_8BIT; - gradientLeft.header.always_zero = 0; - gradientLeft.header.reserved = 0; - gradientLeft.header.w = 30; - gradientLeft.header.h = 1; - gradientLeft.data_size = 30; - gradientLeft.data = gradientLeft_map; - - gradientRight.header.cf = LV_IMG_CF_ALPHA_8BIT; - gradientRight.header.always_zero = 0; - gradientRight.header.reserved = 0; - gradientRight.header.w = 30; - gradientRight.header.h = 1; - gradientRight.data_size = 30; - gradientRight.data = gradientRight_map; - } - - inline static const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_LARGE_CONST uint8_t - gradientLeft_map[] = { - 0xfa, 0xf2, 0xea, 0xe2, 0xda, 0xd1, 0xc7, 0xbe, 0xb7, 0xae, - 0xa6, 0x9e, 0x95, 0x8d, 0x84, 0x7d, 0x74, 0x6c, 0x62, 0x5a, - 0x51, 0x48, 0x41, 0x38, 0x2f, 0x28, 0x1f, 0x17, 0x0f, 0x07, - }; - - inline static const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_LARGE_CONST uint8_t - gradientRight_map[] = { - 0x07, 0x0f, 0x17, 0x1f, 0x28, 0x2f, 0x38, 0x41, 0x48, 0x51, - 0x5a, 0x62, 0x6c, 0x74, 0x7d, 0x84, 0x8d, 0x95, 0x9e, 0xa6, - 0xae, 0xb7, 0xbe, 0xc7, 0xd1, 0xda, 0xe2, 0xea, 0xf2, 0xfa, - }; - - inline static const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_LARGE_CONST uint8_t - appleTvIcon_map[] = { - /*Pixel format: Red: 5 bit, Green: 6 bit, Blue: 5 bit*/ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x08, 0x42, 0x55, 0xad, 0xdb, 0xde, 0x1c, 0xe7, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x55, 0xad, 0xdf, 0xff, 0xff, 0xff, 0xff, - 0xff, 0x5d, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79, 0xce, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdb, 0xde, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, - 0x21, 0x34, 0xa5, 0x55, 0xad, 0x55, 0xad, 0x55, 0xad, 0x55, 0xad, - 0x55, 0xad, 0x55, 0xad, 0xcf, 0x7b, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x18, 0xc6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0x76, 0xb5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xe7, 0x39, 0xdf, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xb7, - 0xbd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x71, 0x8c, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x69, 0x4a, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xe7, 0x39, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xb7, 0xbd, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x5d, 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xf7, 0xbd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe7, 0x39, 0xdf, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xb7, 0xbd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xcf, 0x7b, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0x5d, 0xef, 0x65, 0x29, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xe7, 0x39, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xb7, 0xbd, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb6, - 0xb5, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7d, 0xef, - 0x8a, 0x52, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe7, 0x39, 0xdf, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xb7, 0xbd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x59, 0xce, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0x9a, 0xd6, 0x08, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xe7, 0x39, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xb7, 0xbd, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x55, 0xad, 0x9a, 0xd6, 0xd7, 0xbd, 0x8e, 0x73, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe7, 0x39, 0xdf, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xb7, 0xbd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x73, 0xd7, - 0xbd, 0xbb, 0xde, 0x3c, 0xe7, 0xfc, 0xe6, 0x39, 0xce, 0x72, 0x94, - 0xa7, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xa3, 0x18, 0x8e, 0x73, 0xd7, 0xbd, 0x1c, 0xe7, 0x9e, 0xf7, - 0xbe, 0xf7, 0x5d, 0xef, 0x9a, 0xd6, 0x34, 0xa5, 0x28, 0x42, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xe7, 0x39, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xb7, 0xbd, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, - 0x6b, 0xfb, 0xde, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, 0xff, 0x7a, 0xd6, 0x71, - 0x8c, 0xa6, 0x31, 0x2d, 0x6b, 0xb6, 0xb5, 0x7d, 0xef, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xdf, 0xff, 0xd7, 0xbd, 0xa3, 0x18, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa7, 0x39, - 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xb7, 0xbd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xb3, 0x9c, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0x3c, 0xe7, 0x49, 0x4a, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0xe7, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x38, - 0xc6, 0x00, 0x00, 0x00, 0x00, 0x69, 0x4a, 0xdf, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x59, - 0xce, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xf7, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, 0xff, 0x14, - 0xa5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb3, 0x9c, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3d, - 0xef, 0x24, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x5d, 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0x39, 0xce, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xdb, 0xde, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xbe, 0xf7, 0x45, 0x29, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xf0, 0x83, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0x1c, 0xe7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0c, 0x63, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0x5d, 0xef, 0xeb, 0x5a, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5d, - 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x39, 0xce, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb3, 0x9c, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0x10, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xc6, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x14, 0xa5, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdb, 0xde, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdb, 0xde, - 0x86, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x5d, 0xef, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x39, 0xce, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x86, 0x31, 0xbf, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x39, 0xce, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x7e, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xdf, 0xff, 0xe7, 0x39, 0x00, 0x00, 0x00, 0x00, 0x8e, - 0x73, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0x3d, 0xef, 0x86, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x5d, 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0x39, 0xce, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x59, 0xce, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xbe, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x8e, 0x73, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x9a, 0xd6, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x79, 0xce, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x6d, 0x6b, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7a, 0xd6, 0x3c, 0xe7, 0x3c, - 0xe7, 0x3d, 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x9e, 0xf7, 0x3c, 0xe7, 0x3c, - 0xe7, 0x3c, 0xe7, 0x3c, 0xe7, 0x3c, 0xe7, 0x96, 0xb5, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x83, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xf0, 0x83, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xd7, 0xbd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0x71, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x9e, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0x7a, 0xd6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa7, 0x39, 0xdf, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xb7, 0xbd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x7e, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x18, 0xc6, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7d, 0xef, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x9e, 0xf7, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xec, 0x62, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x71, 0x8c, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xe7, 0x39, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xb7, 0xbd, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb7, 0xbd, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0x7d, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, - 0x73, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xf8, 0xc5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, - 0x8c, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0x49, 0x4a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe7, 0x39, 0xdf, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xb7, 0xbd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x0c, 0x63, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x4d, 0x6b, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xd7, 0xbd, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x6e, 0x73, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xd3, 0x9c, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0xff, 0xe4, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xe7, 0x39, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xb7, 0xbd, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x1c, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xd7, 0xbd, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x3d, 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0x5d, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x55, 0xad, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xbf, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe7, 0x39, - 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xb7, 0xbd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0xa5, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x5d, - 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xeb, 0x5a, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x76, 0xb5, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0xa5, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, 0xff, 0x28, 0x42, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xe7, 0x39, 0xdf, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xb7, 0xbd, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xa7, 0x39, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x2d, 0x6b, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x96, - 0xb5, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0x29, 0x4a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x92, 0x94, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xae, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe7, - 0x39, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xb7, 0xbd, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9a, - 0xd6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0x96, 0xb5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0xef, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbb, 0xde, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x83, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, - 0xc5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xe7, 0x39, 0xdf, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xb7, - 0xbd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x72, 0x94, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1c, 0xe7, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xeb, 0x5a, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xd3, 0x9c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x8a, 0x52, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0xff, 0x28, 0x42, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xe7, 0x39, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xb7, 0xbd, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xbe, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0x8a, 0x52, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x55, 0xad, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, 0xff, 0x45, 0x29, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9e, - 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0x7a, 0xd6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe7, 0x39, 0xdf, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xb7, 0xbd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xc6, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x75, 0xad, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, - 0xe6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x59, 0xce, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x9a, 0xd6, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xb7, - 0xbd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xe7, 0x39, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xb7, 0xbd, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x6d, 0x6b, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0xe6, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x29, 0x4a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xcf, 0x7b, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xf4, 0xa4, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x59, 0xce, 0x86, 0x31, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe7, 0x39, 0xdf, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xb7, 0xbd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x3d, 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0x49, 0x4a, 0x00, 0x00, 0x00, 0x00, 0x55, 0xad, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7d, - 0xef, 0xa3, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa6, 0x31, 0xdf, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0x9e, 0xf7, 0xef, 0x7b, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xe7, 0x39, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xb7, 0xbd, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x96, 0xb5, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x14, 0xa5, - 0x00, 0x00, 0x00, 0x00, 0xfb, 0xde, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xd7, 0xbd, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x9a, 0xd6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0x0c, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe7, 0x39, 0xdf, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xb7, 0xbd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x49, 0x4a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xdb, 0xde, 0x00, 0x00, 0x29, 0x4a, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xeb, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x8c, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xdb, 0xde, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xe7, 0x39, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x39, 0xce, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdb, 0xde, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xe7, 0x39, 0xf3, 0x9c, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xfc, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0xe7, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x10, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe7, 0x39, - 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0x7d, 0xef, 0x24, 0x21, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x86, 0x31, 0x29, 0x4a, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xd3, 0x9c, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0x9c, 0xbb, 0xde, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x14, - 0xa5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x51, 0x8c, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xfc, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xa7, 0x39, 0xdf, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xfc, 0xe6, 0xd3, 0x9c, 0x51, 0x8c, 0x34, 0xa5, 0x9a, 0xd6, 0xdf, - 0xff, 0xf7, 0xbd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa6, - 0x31, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xdb, 0xde, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xdf, 0xff, 0x08, 0x42, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xe6, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xcf, - 0x7b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xbf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1c, 0xe7, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x59, 0xce, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x9a, 0xd6, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xec, 0x62, 0xdf, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0x79, 0xce, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0xe7, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xdf, 0xff, 0xe7, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xcf, 0x7b, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0x51, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x55, 0xad, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x9e, 0xf7, 0xe7, 0x39, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xb7, 0xbd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x30, - 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7d, - 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x9e, 0xf7, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x59, 0xce, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0x10, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe8, 0x41, 0xdf, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xf7, 0xbd, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xd7, 0xbd, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0x18, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9a, 0xd6, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xb2, 0x94, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x8c, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x39, 0xce, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0c, 0x63, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x8e, 0x73, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x18, 0xc6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0x9e, 0xf7, 0x39, 0xce, 0x72, 0x94, 0xcb, - 0x5a, 0xa3, 0x18, 0x4d, 0x6b, 0x34, 0xa5, 0xfb, 0xde, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbe, 0xf7, 0x72, - 0x94, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xaf, 0x7b, 0x3c, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x7d, 0xef, 0xd7, 0xbd, 0xeb, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0xe7, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0x5d, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x6e, 0x73, 0xf8, 0xc5, 0xba, 0xd6, 0xd7, 0xbd, 0xf0, 0x83, 0xa3, - 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x49, 0x4a, 0xf3, 0x9c, 0xf8, 0xc5, 0x59, - 0xce, 0x55, 0xad, 0x08, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xae, 0x73, 0x76, 0xb5, 0x39, 0xce, 0x7a, 0xd6, 0x39, 0xce, - 0xd7, 0xbd, 0xd3, 0x9c, 0xec, 0x62, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x29, 0x4a, 0x0c, 0x63, 0x0c, 0x63, 0x0c, 0x63, - 0x0c, 0x63, 0x0c, 0x63, 0x0c, 0x63, 0x0c, 0x63, 0x49, 0x4a, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - - inline static const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_LARGE_CONST uint8_t - appleDisplayIcon_map[] = { - 0x23, 0xc6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xd8, 0x3d, 0xaa, 0xfd, 0xad, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, - 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, - 0x9a, 0x9a, 0x9a, 0xa1, 0xf7, 0xd8, 0xd0, 0xd1, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa1, 0xff, 0xd2, 0xcb, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9a, - 0xff, 0xd2, 0xcb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x9a, 0xff, 0xd2, 0xcb, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x9a, 0xff, 0xd2, 0xcb, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9a, 0xff, 0xd2, - 0xcb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x9a, 0xff, 0xd2, 0xcb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x9a, 0xff, 0xd2, 0xcb, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9a, 0xff, 0xd2, 0xcb, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9a, 0xff, - 0xd2, 0xcb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x9a, 0xff, 0xd2, 0xcb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x9a, 0xff, 0xd2, 0xcb, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9a, 0xff, 0xc6, 0xea, - 0x2a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, - 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1f, 0xcc, - 0xf6, 0x6c, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0x98, 0x00, 0x44, 0x7b, 0x80, 0x80, 0x80, 0x80, - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, - 0x80, 0x80, 0x80, 0x80, 0x7d, 0x56, 0x03, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xb7, 0xc4, 0xc4, 0xc4, 0xc4, - 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc0, 0x2c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0xd3, 0xde, - 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xdb, 0x36, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, - }; - - inline static const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_LARGE_CONST uint8_t - appleBackIcon_map[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x0f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x3d, 0xbe, 0x94, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x3b, 0xe7, 0xff, 0xf0, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x3b, 0xfa, 0xff, 0xf5, 0x31, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0xfc, 0xff, 0xea, 0x3e, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0xee, 0xff, 0xe6, - 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x50, 0xed, 0xff, - 0xe9, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0xfc, - 0xff, 0xe7, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x59, - 0xff, 0xff, 0xe0, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x5e, 0xf6, 0xff, 0xdb, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x64, 0xf4, 0xff, 0xd9, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x4d, 0xff, 0xff, 0xce, 0x1c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x6b, 0xff, 0xff, 0x9e, 0x07, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0xff, 0xff, 0xa8, - 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x8f, - 0xff, 0xff, 0xb5, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x03, 0x91, 0xff, 0xff, 0xba, 0x12, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x93, 0xff, 0xff, 0xbb, 0x0a, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x87, 0xfc, 0xff, - 0xbf, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x7c, 0xfb, 0xff, 0xc5, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x01, 0x78, 0xff, 0xff, 0xca, 0x1e, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x75, 0xff, 0xff, 0xd0, 0x11, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x6e, 0xfb, - 0xff, 0xcc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x68, 0xea, 0xca, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x04, 0x28, 0x18, - }; - - inline static const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_LARGE_CONST uint8_t - high_brightness_map[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0xc1, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xd4, 0xd4, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x8e, 0x04, 0x00, 0x00, 0x00, - 0xc1, 0xc1, 0x00, 0x00, 0x00, 0x04, 0x8e, 0x5c, 0x00, 0x00, 0x00, - 0x00, 0x8c, 0xff, 0xa8, 0x01, 0x00, 0x00, 0x0c, 0x0c, 0x00, 0x00, - 0x01, 0xa8, 0xff, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x04, 0xa9, 0xf5, - 0x0d, 0x00, 0x00, 0x11, 0x11, 0x00, 0x00, 0x0d, 0xf5, 0xa9, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0a, 0x00, 0x42, 0xd4, 0xff, - 0xff, 0xd4, 0x41, 0x00, 0x0a, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x42, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xfd, 0x40, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd5, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xd3, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xbd, 0xcc, 0xbd, 0x0d, 0x11, 0xfe, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xfe, 0x12, 0x0d, 0xbd, 0xcc, 0xbd, 0xbd, 0xcc, 0xbd, - 0x0d, 0x11, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x10, - 0x0d, 0xbd, 0xcc, 0xbd, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd4, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xd2, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0xfd, 0xff, 0xff, 0xff, 0xff, - 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x0a, 0x00, 0x40, 0xd3, 0xff, 0xfe, 0xd2, 0x3f, 0x00, 0x0a, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xa9, 0xf5, 0x0d, 0x00, 0x00, - 0x10, 0x10, 0x00, 0x00, 0x0d, 0xf5, 0xa9, 0x04, 0x00, 0x00, 0x00, - 0x00, 0x8c, 0xff, 0xa8, 0x01, 0x00, 0x00, 0x0c, 0x0c, 0x00, 0x00, - 0x01, 0xa8, 0xff, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x8e, 0x04, - 0x00, 0x00, 0x00, 0xc1, 0xc1, 0x00, 0x00, 0x00, 0x04, 0x8e, 0x5c, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd4, - 0xd4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0xc1, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, - }; - - inline static const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_LARGE_CONST uint8_t - low_brightness_map[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x43, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xbd, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x27, 0x72, 0x01, 0x00, 0x00, 0x0c, 0x0c, 0x00, 0x00, 0x01, - 0x72, 0x28, 0x00, 0x00, 0x00, 0x00, 0x71, 0xf5, 0x0f, 0x00, 0x00, - 0x11, 0x11, 0x00, 0x00, 0x0d, 0xf5, 0x73, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x0b, 0x00, 0x42, 0xd4, 0xff, 0xff, 0xd4, 0x41, 0x00, 0x0a, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0xfd, 0xff, 0xff, - 0xff, 0xff, 0xfd, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xd5, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xd3, 0x00, 0x00, - 0x00, 0x00, 0x43, 0xbd, 0x0d, 0x11, 0xfe, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xfe, 0x12, 0x0d, 0xbc, 0x44, 0x43, 0xbd, 0x0d, 0x11, - 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x11, 0x0d, 0xbc, - 0x44, 0x00, 0x00, 0x00, 0x00, 0xd4, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xd2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, - 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x01, 0x0b, 0x00, 0x40, 0xd3, 0xfe, 0xff, 0xd2, 0x3f, - 0x00, 0x0a, 0x01, 0x00, 0x00, 0x00, 0x00, 0x71, 0xf5, 0x0f, 0x00, - 0x00, 0x10, 0x10, 0x00, 0x00, 0x0d, 0xf5, 0x73, 0x00, 0x00, 0x00, - 0x00, 0x27, 0x72, 0x01, 0x00, 0x00, 0x0c, 0x0c, 0x00, 0x00, 0x01, - 0x72, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xbd, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x44, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, - }; - - inline static const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_LARGE_CONST uint8_t - lightbulb_map[] = { - 0x00, 0x00, 0x00, 0x00, 0x04, 0x1c, 0x1c, 0x04, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x16, 0x95, 0xee, 0xff, 0xff, 0xee, 0x94, 0x15, - 0x00, 0x00, 0x00, 0x27, 0xe3, 0xff, 0xcc, 0x8d, 0x8d, 0xcd, 0xff, - 0xe1, 0x26, 0x00, 0x07, 0xd9, 0xfa, 0x5d, 0x00, 0x00, 0x00, 0x00, - 0x5f, 0xfa, 0xd7, 0x06, 0x65, 0xff, 0x77, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7a, 0xff, 0x63, 0xb1, 0xf8, 0x0c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x0d, 0xf8, 0xaf, 0xcc, 0xdc, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xdb, 0xcd, 0xb1, 0xf5, 0x04, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xf1, 0xbd, 0x73, 0xff, 0x74, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x71, 0xff, 0x74, 0x0b, 0xd5, - 0xfb, 0x40, 0x00, 0x00, 0x00, 0x00, 0x41, 0xfb, 0xd9, 0x0b, 0x00, - 0x24, 0xef, 0xdc, 0x01, 0x00, 0x00, 0x01, 0xdd, 0xee, 0x24, 0x00, - 0x00, 0x00, 0x83, 0xff, 0x30, 0x00, 0x00, 0x30, 0xff, 0x81, 0x00, - 0x00, 0x00, 0x00, 0x12, 0x6c, 0x06, 0x00, 0x00, 0x06, 0x6c, 0x12, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x25, 0xc7, 0xcc, 0xcc, 0xcc, 0xcc, - 0xc7, 0x25, 0x00, 0x00, 0x00, 0x00, 0x25, 0xc7, 0xcc, 0xcc, 0xcc, - 0xcc, 0xc7, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x76, - 0x77, 0x77, 0x76, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x69, - 0xff, 0xff, 0xff, 0xff, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x21, 0x22, 0x22, 0x21, 0x01, 0x00, 0x00, 0x00, - }; + lv_img_dsc_t wifiNoSignal; + lv_img_dsc_t wifiLowSignal; + lv_img_dsc_t wifiMidSignal; + lv_img_dsc_t wifiHighSignal; }; \ No newline at end of file diff --git a/Platformio/OmoteUI/OmoteUI.cpp b/Platformio/OmoteUI/OmoteUI.cpp index 042febd..360dc71 100644 --- a/Platformio/OmoteUI/OmoteUI.cpp +++ b/Platformio/OmoteUI/OmoteUI.cpp @@ -9,6 +9,8 @@ std::shared_ptr OmoteUI::mInstance = nullptr; // #if defined(IS_SIMULATOR) && (IS_SIMULATOR == true) // #endif +OmoteUI::OmoteUI(std::shared_ptr aHardware) : mHardware(aHardware){} + // Set the page indicator scroll position relative to the tabview scroll // position void OmoteUI::store_scroll_value_event_cb(lv_event_t *e) { @@ -27,13 +29,13 @@ void OmoteUI::tabview_device_event_cb(lv_event_t *e) { // Slider Event handler void OmoteUI::bl_slider_event_cb(lv_event_t *e) { lv_obj_t *slider = lv_event_get_target(e); - backlight_brightness = std::clamp(lv_slider_get_value(slider), 60, 255); + auto newBrightness = std::clamp(lv_slider_get_value(slider), 60, 255); + mHardware->display()->setBrightness(newBrightness); } // Apple Key Event handler void OmoteUI::appleKey_event_cb(lv_event_t *e) { // Send IR command based on the event user data - mHardware->sendIR(); //mHardware->debugPrint(std::to_string(50 + (int)e->user_data)); } @@ -91,39 +93,146 @@ void OmoteUI::loopHandler(){ lv_timer_handler(); } +void OmoteUI::create_status_bar(){ + // Create a status bar + lv_obj_t* statusbar = lv_btn_create(lv_scr_act()); + lv_obj_set_size(statusbar, 240, 20); + lv_obj_set_style_shadow_width(statusbar, 0, LV_PART_MAIN); + lv_obj_set_style_bg_color(statusbar, lv_color_black(), LV_PART_MAIN); + lv_obj_set_style_radius(statusbar, 0, LV_PART_MAIN); + lv_obj_align(statusbar, LV_ALIGN_TOP_MID, 0, 0); + + this->WifiLabel = lv_label_create(statusbar); + lv_label_set_text(this->WifiLabel, ""); + lv_obj_align(this->WifiLabel, LV_ALIGN_LEFT_MID, -8, 0); + lv_obj_set_style_text_font(this->WifiLabel, &lv_font_montserrat_12, LV_PART_MAIN); + + this->objBattPercentage = lv_label_create(statusbar); + lv_label_set_text(this->objBattPercentage, ""); + lv_obj_align(this->objBattPercentage, LV_ALIGN_RIGHT_MID, -16, 0); + lv_obj_set_style_text_font(this->objBattPercentage, &lv_font_montserrat_12, LV_PART_MAIN); + + this->objBattIcon = lv_label_create(statusbar); + lv_label_set_text(this->objBattIcon, LV_SYMBOL_BATTERY_EMPTY); + lv_obj_align(this->objBattIcon, LV_ALIGN_RIGHT_MID, 8, 0); + lv_obj_set_style_text_font(this->objBattIcon, &lv_font_montserrat_16, LV_PART_MAIN); + + batteryPoller = std::make_unique([&batteryIcon = objBattIcon, battery = mHardware->battery()](){ + auto percent = battery->getPercentage(); + if(percent > 95) lv_label_set_text(batteryIcon, LV_SYMBOL_BATTERY_FULL); + else if(percent > 75) lv_label_set_text(batteryIcon, LV_SYMBOL_BATTERY_3); + else if(percent > 50) lv_label_set_text(batteryIcon, LV_SYMBOL_BATTERY_2); + else if(percent > 25) lv_label_set_text(batteryIcon, LV_SYMBOL_BATTERY_1); + else lv_label_set_text(batteryIcon, LV_SYMBOL_BATTERY_EMPTY); + }); +} + +void OmoteUI::setup_settings(lv_obj_t* parent) +{ + // Add content to the settings tab + // With a flex layout, setting groups/boxes will position themselves automatically + lv_obj_set_layout(parent, LV_LAYOUT_FLEX); + lv_obj_set_flex_flow(parent, LV_FLEX_FLOW_COLUMN); + lv_obj_set_scrollbar_mode(parent, LV_SCROLLBAR_MODE_ACTIVE); + // Add a label, then a box for the display settings + this->settingsMenu = lv_menu_create(parent); + lv_obj_set_width(this->settingsMenu, 210); + + /* Create main page for settings this->settingsMenu*/ + this->settingsMainPage = lv_menu_page_create(this->settingsMenu, NULL); + lv_obj_t* cont = lv_menu_cont_create(this->settingsMainPage); + lv_obj_set_layout(cont, LV_LAYOUT_FLEX); + lv_obj_set_flex_flow(cont, LV_FLEX_FLOW_COLUMN); + lv_obj_set_scrollbar_mode(cont, LV_SCROLLBAR_MODE_ACTIVE); + //lv_obj_set_width(cont, lv_obj_get_width(parent)); + this->display_settings(cont); + + this->create_wifi_settings(this->settingsMenu, cont); + + // Another setting for the battery + lv_obj_t* menuLabel = lv_label_create(cont); + lv_label_set_text(menuLabel, "Battery"); + lv_obj_t* menuBox = lv_obj_create(cont); + lv_obj_set_size(menuBox, lv_pct(100), 125); + lv_obj_set_style_bg_color(menuBox, color_primary, LV_PART_MAIN); + lv_obj_set_style_border_width(menuBox, 0, LV_PART_MAIN); + + lv_menu_set_page(this->settingsMenu, this->settingsMainPage); +} + +void OmoteUI::ta_kb_event_cb(lv_event_t* e) +{ + lv_event_code_t code = lv_event_get_code(e); + lv_obj_t * ta = lv_event_get_target(e); + lv_obj_t * kb = (lv_obj_t*) lv_event_get_user_data(e); + switch(code){ + case LV_EVENT_FOCUSED: + lv_keyboard_set_textarea(kb, ta); + lv_obj_clear_flag(kb, LV_OBJ_FLAG_HIDDEN); + lv_obj_move_foreground(kb); + break; + case LV_EVENT_DEFOCUSED: + lv_keyboard_set_textarea(kb, NULL); + lv_obj_add_flag(kb, LV_OBJ_FLAG_HIDDEN); + break; + default: + break; + } +} + +void OmoteUI::create_keyboard() +{ + this->kb = lv_keyboard_create(lv_scr_act()); + lv_obj_add_flag(this->kb, LV_OBJ_FLAG_HIDDEN); + lv_obj_set_y(this->kb, 0); +} + +void OmoteUI::hide_keyboard() +{ + lv_obj_add_flag(this->kb, LV_OBJ_FLAG_HIDDEN); +} + +void OmoteUI::reset_settings_menu() +{ + lv_menu_set_page(this->settingsMenu, this->settingsMainPage); +} + +void OmoteUI::attach_keyboard(lv_obj_t* textarea) +{ + if (this->kb == NULL) + { + this->create_keyboard(); + } + lv_keyboard_set_textarea(this->kb, textarea); + lv_obj_add_event_cb(textarea, [] (lv_event_t* e) {mInstance->ta_kb_event_cb(e);}, LV_EVENT_FOCUSED, this->kb); + lv_obj_add_event_cb(textarea, [] (lv_event_t* e) {mInstance->ta_kb_event_cb(e);}, LV_EVENT_DEFOCUSED, this->kb); +} + void OmoteUI::layout_UI() { - // --- LVGL UI Configuration --- - - // Set the background color +// Set the background color lv_obj_set_style_bg_color(lv_scr_act(), lv_color_black(), LV_PART_MAIN); - + this->create_keyboard(); // Setup a scrollable tabview for devices and settings - lv_obj_t *tabview; - tabview = - lv_tabview_create(lv_scr_act(), LV_DIR_TOP, - 0); // Hide tab labels by setting their height to 0 + lv_obj_t* tabview; + tabview = lv_tabview_create(lv_scr_act(), LV_DIR_TOP, 0); // Hide tab labels by setting their height to 0 lv_obj_set_style_bg_color(tabview, lv_color_black(), LV_PART_MAIN); - lv_obj_set_size(tabview, SCREEN_WIDTH, - 270); // 270 = screenHeight(320) - panel(30) - statusbar(20) + lv_obj_set_size(tabview, SCREEN_WIDTH, 270); // 270 = screenHeight(320) - panel(30) - statusbar(20) lv_obj_align(tabview, LV_ALIGN_TOP_MID, 0, 20); // Add 4 tabs (names are irrelevant since the labels are hidden) - lv_obj_t *tab1 = lv_tabview_add_tab(tabview, "Settings"); - lv_obj_t *tab2 = lv_tabview_add_tab(tabview, "Technisat"); - lv_obj_t *tab3 = lv_tabview_add_tab(tabview, "Apple TV"); - lv_obj_t *tab4 = lv_tabview_add_tab(tabview, "Smart Home"); + lv_obj_t* tab1 = lv_tabview_add_tab(tabview, "Settings"); + lv_obj_t* tab2 = lv_tabview_add_tab(tabview, "Technisat"); + lv_obj_t* tab3 = lv_tabview_add_tab(tabview, "Apple TV"); + lv_obj_t* tab4 = lv_tabview_add_tab(tabview, "Smart Home"); - // Configure number button grid - static lv_coord_t col_dsc[] = {LV_GRID_FR(1), LV_GRID_FR(1), LV_GRID_FR(1), - LV_GRID_TEMPLATE_LAST}; // equal x distribution - static lv_coord_t row_dsc[] = { - 52, 52, 52, 52, LV_GRID_TEMPLATE_LAST}; // manual y distribution to - // compress the grid a bit + // Configure number button grid + static lv_coord_t col_dsc[] = { LV_GRID_FR(1), LV_GRID_FR(1), LV_GRID_FR(1), LV_GRID_TEMPLATE_LAST }; // equal x distribution + static lv_coord_t row_dsc[] = { 52, 52, 52, 52, LV_GRID_TEMPLATE_LAST }; // manual y distribution to compress the grid a bit // Create a container with grid for tab2 lv_obj_set_style_pad_all(tab2, 0, LV_PART_MAIN); - lv_obj_t *cont = lv_obj_create(tab2); + lv_obj_t* cont = lv_obj_create(tab2); lv_obj_set_style_shadow_width(cont, 0, LV_PART_MAIN); lv_obj_set_style_bg_color(cont, lv_color_black(), LV_PART_MAIN); lv_obj_set_style_border_width(cont, 0, LV_PART_MAIN); @@ -134,61 +243,50 @@ void OmoteUI::layout_UI() { lv_obj_align(cont, LV_ALIGN_TOP_MID, 0, 0); lv_obj_set_style_radius(cont, 0, LV_PART_MAIN); - lv_obj_t *buttonLabel; - lv_obj_t *obj; + lv_obj_t* buttonLabel; + lv_obj_t* obj; - // Iterate through grid buttons and configure them + // Iterate through grid buttons configure them for (int i = 0; i < 12; i++) { uint8_t col = i % 3; uint8_t row = i / 3; // Create the button object - if ((row == 3) && ((col == 0) || (col == 2))) - continue; // Do not create a complete fourth row, only a 0 button + if ((row == 3) && ((col == 0) || (col == 2))) continue; // Do not create a complete fourth row, only a 0 button obj = lv_btn_create(cont); - lv_obj_set_grid_cell(obj, LV_GRID_ALIGN_STRETCH, col, 1, - LV_GRID_ALIGN_STRETCH, row, 1); - lv_obj_set_style_bg_color(obj, color_primary, LV_PART_MAIN); + lv_obj_set_grid_cell(obj, LV_GRID_ALIGN_STRETCH, col, 1, LV_GRID_ALIGN_STRETCH, row, 1); + lv_obj_set_style_bg_color(obj, this->color_primary, LV_PART_MAIN); lv_obj_set_style_radius(obj, 14, LV_PART_MAIN); - lv_obj_add_flag(obj, LV_OBJ_FLAG_EVENT_BUBBLE); // Clicking a button causes - // a event in its container + lv_obj_set_style_shadow_color(obj, lv_color_hex(0x404040), LV_PART_MAIN); + lv_obj_add_flag(obj, LV_OBJ_FLAG_EVENT_BUBBLE); // Clicking a button causes a event in its container // Create Labels for each button - buttonLabel = lv_label_create(obj); - if (i < 9) { - lv_label_set_text_fmt(buttonLabel, std::to_string(i + 1).c_str(), col, - row); - lv_obj_set_user_data(obj, - (void *)i); // Add user data so we can identify which - // button caused the container event - } else { - lv_label_set_text_fmt(buttonLabel, "0", col, row); - lv_obj_set_user_data(obj, (void *)9); + buttonLabel = lv_label_create(obj); + if(i < 9){ + lv_label_set_text_fmt(buttonLabel, std::to_string(i+1).c_str(), col, row); + lv_obj_set_user_data(obj, (void*)i); // Add user data so we can identify which button caused the container event } - lv_obj_set_style_text_font(buttonLabel, &lv_font_montserrat_24, - LV_PART_MAIN); + else{ + lv_label_set_text_fmt(buttonLabel, "0", col, row); + lv_obj_set_user_data(obj, (void*)9); + } + lv_obj_set_style_text_font(buttonLabel, &lv_font_montserrat_24, LV_PART_MAIN); lv_obj_center(buttonLabel); } // Create a shared event for all button inside container - lv_obj_add_event_cb( - cont, [](lv_event_t *e) { mInstance->virtualKeypad_event_cb(e); }, - LV_EVENT_CLICKED, NULL); + lv_obj_add_event_cb(cont, [] (lv_event_t* e) {mInstance->virtualKeypad_event_cb(e);}, LV_EVENT_CLICKED, NULL); + // Add content to the Apple TV tab (3) // Add a nice apple tv logo - lv_obj_t* appleImg = imgs.addAppleTVIcon(tab3); - lv_obj_align(appleImg, LV_ALIGN_CENTER, 0, -60); - // create two buttons and add their icons accordingly - lv_obj_t *button = lv_btn_create(tab3); + lv_obj_t* button = lv_btn_create(tab3); lv_obj_align(button, LV_ALIGN_BOTTOM_LEFT, 10, 0); lv_obj_set_size(button, 60, 60); lv_obj_set_style_radius(button, 30, LV_PART_MAIN); lv_obj_set_style_bg_color(button, color_primary, LV_PART_MAIN); - lv_obj_add_event_cb( - button, [](lv_event_t *e) { mInstance->appleKey_event_cb(e); }, - LV_EVENT_CLICKED, (void *)1); + lv_obj_add_event_cb(button, [] (lv_event_t* e) {mInstance->appleKey_event_cb(e);}, LV_EVENT_CLICKED, (void*)1); - appleImg = imgs.addAppleBackIcon(button); + appleImg = imgs.addAppleDisplayImage(button); lv_obj_align(appleImg, LV_ALIGN_CENTER, -3, 0); lv_obj_set_style_img_recolor(appleImg, lv_color_white(), LV_PART_MAIN); lv_obj_set_style_img_recolor_opa(appleImg, LV_OPA_COVER, LV_PART_MAIN); @@ -199,9 +297,7 @@ void OmoteUI::layout_UI() { lv_obj_set_size(button, 60, 60); lv_obj_set_style_radius(button, 30, LV_PART_MAIN); lv_obj_set_style_bg_color(button, color_primary, LV_PART_MAIN); - lv_obj_add_event_cb( - button, [](lv_event_t *e) { mInstance->appleKey_event_cb(e); }, - LV_EVENT_CLICKED, (void *)2); + lv_obj_add_event_cb(button, [] (lv_event_t* e) {mInstance->appleKey_event_cb(e);}, LV_EVENT_CLICKED, (void*)2); appleImg = imgs.addAppleDisplayImage(button); lv_obj_align(appleImg, LV_ALIGN_CENTER, 0, 0); @@ -209,157 +305,49 @@ void OmoteUI::layout_UI() { lv_obj_set_style_img_recolor_opa(appleImg, LV_OPA_COVER, LV_PART_MAIN); lv_obj_align(appleImg, LV_ALIGN_CENTER, 0, 0); - // Add content to the settings tab - // With a flex layout, setting groups/boxes will position themselves - // automatically - lv_obj_set_layout(tab1, LV_LAYOUT_FLEX); - lv_obj_set_flex_flow(tab1, LV_FLEX_FLOW_COLUMN); - lv_obj_set_scrollbar_mode(tab1, LV_SCROLLBAR_MODE_ACTIVE); - - - // Add a label, then a box for the display settings - lv_obj_t *menuLabel = lv_label_create(tab1); - lv_label_set_text(menuLabel, "Display"); - - lv_obj_t *menuBox = lv_obj_create(tab1); - lv_obj_set_size(menuBox, lv_pct(100), 109); - lv_obj_set_style_bg_color(menuBox, color_primary, LV_PART_MAIN); - lv_obj_set_style_border_width(menuBox, 0, LV_PART_MAIN); - - lv_obj_t *brightnessIcon = imgs.addLowBrightnessIcon(menuBox); - lv_obj_align(brightnessIcon, LV_ALIGN_TOP_LEFT, 0, 0); - - lv_obj_t *slider = lv_slider_create(menuBox); - lv_slider_set_range(slider, 60, 255); - lv_obj_set_style_bg_color(slider, lv_color_white(), LV_PART_KNOB); - lv_obj_set_style_bg_opa(slider, LV_OPA_COVER, LV_PART_MAIN); - lv_obj_set_style_bg_color(slider, lv_color_lighten(color_primary, 50), - LV_PART_MAIN); - lv_slider_set_value(slider, backlight_brightness, LV_ANIM_OFF); - lv_obj_set_size(slider, lv_pct(66), 10); - lv_obj_align(slider, LV_ALIGN_TOP_MID, 0, 3); - - brightnessIcon = imgs.addHighBrightnessIcon(menuBox); - lv_obj_align(brightnessIcon, LV_ALIGN_TOP_RIGHT, 0, -1); - - lv_obj_add_event_cb( - slider, [](lv_event_t *e) { mInstance->bl_slider_event_cb(e); }, - LV_EVENT_VALUE_CHANGED, NULL); - - menuLabel = lv_label_create(menuBox); - lv_label_set_text(menuLabel, "Lift to Wake"); - lv_obj_align(menuLabel, LV_ALIGN_TOP_LEFT, 0, 32); - lv_obj_t *wakeToggle = lv_switch_create(menuBox); - lv_obj_set_size(wakeToggle, 40, 22); - lv_obj_align(wakeToggle, LV_ALIGN_TOP_RIGHT, 0, 29); - lv_obj_set_style_bg_color(wakeToggle, lv_color_lighten(color_primary, 50), - LV_PART_MAIN); - lv_obj_add_event_cb( - wakeToggle, - [](lv_event_t *e) { mInstance->WakeEnableSetting_event_cb(e); }, - LV_EVENT_VALUE_CHANGED, NULL); - if (wakeupByIMUEnabled) - lv_obj_add_state(wakeToggle, LV_STATE_CHECKED); // set default state - - menuLabel = lv_label_create(menuBox); - lv_label_set_text(menuLabel, "Timeout"); - lv_obj_align(menuLabel, LV_ALIGN_TOP_LEFT, 0, 64); - lv_obj_t *drop = lv_dropdown_create(menuBox); - lv_dropdown_set_options(drop, "10s\n" - "30s\n" - "1m\n" - "3m"); - lv_obj_align(drop, LV_ALIGN_TOP_RIGHT, 0, 61); - lv_obj_set_size(drop, 70, 22); - lv_obj_set_style_pad_top(drop, 1, LV_PART_MAIN); - lv_obj_set_style_bg_color(drop, color_primary, LV_PART_MAIN); - lv_obj_set_style_border_width(drop, 0, LV_PART_MAIN); - lv_obj_set_style_bg_color(lv_dropdown_get_list(drop), color_primary, - LV_PART_MAIN); - lv_obj_set_style_border_width(lv_dropdown_get_list(drop), 1, LV_PART_MAIN); - lv_obj_set_style_border_color(lv_dropdown_get_list(drop), - lv_color_darken(color_primary, 40), - LV_PART_MAIN); - - // Add another label, then a settings box for WiFi - menuLabel = lv_label_create(tab1); - lv_label_set_text(menuLabel, "Wi-Fi"); - menuBox = lv_obj_create(tab1); - lv_obj_set_size(menuBox, lv_pct(100), 80); - lv_obj_set_style_bg_color(menuBox, color_primary, LV_PART_MAIN); - lv_obj_set_style_border_width(menuBox, 0, LV_PART_MAIN); - menuLabel = lv_label_create(menuBox); - lv_label_set_text(menuLabel, "Network"); - menuLabel = lv_label_create(menuBox); - lv_label_set_text(menuLabel, LV_SYMBOL_RIGHT); - lv_obj_align(menuLabel, LV_ALIGN_TOP_RIGHT, 0, 0); - menuLabel = lv_label_create(menuBox); - lv_label_set_text(menuLabel, "Password"); - lv_obj_align(menuLabel, LV_ALIGN_TOP_LEFT, 0, 32); - menuLabel = lv_label_create(menuBox); - lv_label_set_text(menuLabel, LV_SYMBOL_RIGHT); - lv_obj_align(menuLabel, LV_ALIGN_TOP_RIGHT, 0, 32); - - // Another setting for the battery - menuLabel = lv_label_create(tab1); - lv_label_set_text(menuLabel, "Battery"); - menuBox = lv_obj_create(tab1); - lv_obj_set_size(menuBox, lv_pct(100), 125); - lv_obj_set_style_bg_color(menuBox, color_primary, LV_PART_MAIN); - lv_obj_set_style_border_width(menuBox, 0, LV_PART_MAIN); + this->setup_settings(tab1); // Add content to the smart home tab (4) - lv_obj_set_layout(tab4, LV_LAYOUT_FLEX); lv_obj_set_flex_flow(tab4, LV_FLEX_FLOW_COLUMN); lv_obj_set_scrollbar_mode(tab4, LV_SCROLLBAR_MODE_ACTIVE); // Add a label, then a box for the light controls - menuLabel = lv_label_create(tab4); + lv_obj_t* menuLabel = lv_label_create(tab4); lv_label_set_text(menuLabel, "Living Room"); - menuBox = lv_obj_create(tab4); + lv_obj_t* menuBox = lv_obj_create(tab4); lv_obj_set_size(menuBox, lv_pct(100), 79); lv_obj_set_style_bg_color(menuBox, color_primary, LV_PART_MAIN); lv_obj_set_style_border_width(menuBox, 0, LV_PART_MAIN); - lv_obj_t *bulbIcon = imgs.addLightBulbIcon(menuBox); + lv_obj_t* bulbIcon = imgs.addLightBulbIcon(menuBox); lv_obj_align(bulbIcon, LV_ALIGN_TOP_LEFT, 0, 0); menuLabel = lv_label_create(menuBox); lv_label_set_text(menuLabel, "Floor Lamp"); lv_obj_align(menuLabel, LV_ALIGN_TOP_LEFT, 22, 3); - lv_obj_t *lightToggleA = lv_switch_create(menuBox); + lv_obj_t* lightToggleA = lv_switch_create(menuBox); lv_obj_set_size(lightToggleA, 40, 22); lv_obj_align(lightToggleA, LV_ALIGN_TOP_RIGHT, 0, 0); - lv_obj_set_style_bg_color(lightToggleA, lv_color_lighten(color_primary, 50), - LV_PART_MAIN); + lv_obj_set_style_bg_color(lightToggleA, lv_color_lighten(color_primary, 50), LV_PART_MAIN); lv_obj_set_style_bg_color(lightToggleA, color_primary, LV_PART_INDICATOR); - lv_obj_add_event_cb( - lightToggleA, - [](lv_event_t *e) { mInstance->smartHomeToggle_event_cb(e); }, - LV_EVENT_VALUE_CHANGED, (void *)1); + lv_obj_add_event_cb(lightToggleA, [] (lv_event_t* e) {mInstance->smartHomeToggle_event_cb(e);}, LV_EVENT_VALUE_CHANGED, (void*)1); - slider = lv_slider_create(menuBox); - lv_slider_set_range(slider, 60, 255); - lv_obj_set_style_bg_color(slider, lv_color_lighten(lv_color_black(), 30), - LV_PART_INDICATOR); - lv_obj_set_style_bg_grad_color( - slider, lv_color_lighten(lv_palette_main(LV_PALETTE_AMBER), 180), - LV_PART_INDICATOR); + lv_obj_t *slider = lv_slider_create(menuBox); + lv_slider_set_range(slider, 0, 100); + lv_obj_set_style_bg_color(slider, lv_color_lighten(lv_color_black(), 30), LV_PART_INDICATOR); + lv_obj_set_style_bg_grad_color(slider, lv_color_lighten(lv_palette_main(LV_PALETTE_AMBER), 180), LV_PART_INDICATOR); lv_obj_set_style_bg_grad_dir(slider, LV_GRAD_DIR_HOR, LV_PART_INDICATOR); lv_obj_set_style_bg_color(slider, lv_color_white(), LV_PART_KNOB); lv_obj_set_style_bg_opa(slider, 255, LV_PART_MAIN); - lv_obj_set_style_bg_color(slider, lv_color_lighten(color_primary, 50), - LV_PART_MAIN); + lv_obj_set_style_bg_color(slider, lv_color_lighten(color_primary, 50), LV_PART_MAIN); lv_slider_set_value(slider, 255, LV_ANIM_OFF); lv_obj_set_size(slider, lv_pct(90), 10); lv_obj_align(slider, LV_ALIGN_TOP_MID, 0, 37); - lv_obj_add_event_cb( - slider, [](lv_event_t *e) { mInstance->smartHomeSlider_event_cb(e); }, - LV_EVENT_VALUE_CHANGED, (void *)1); + lv_obj_add_event_cb(slider, [] (lv_event_t* e) {mInstance->smartHomeSlider_event_cb(e);}, LV_EVENT_VALUE_CHANGED, (void*)1); - // Add another menu box for a second appliance + // Add another this->settingsMenu box for a second appliance menuBox = lv_obj_create(tab4); lv_obj_set_size(menuBox, lv_pct(100), 79); lv_obj_set_style_bg_color(menuBox, color_primary, LV_PART_MAIN); @@ -371,35 +359,26 @@ void OmoteUI::layout_UI() { menuLabel = lv_label_create(menuBox); lv_label_set_text(menuLabel, "Ceiling Light"); lv_obj_align(menuLabel, LV_ALIGN_TOP_LEFT, 22, 3); - lv_obj_t *lightToggleB = lv_switch_create(menuBox); + lv_obj_t* lightToggleB = lv_switch_create(menuBox); lv_obj_set_size(lightToggleB, 40, 22); lv_obj_align(lightToggleB, LV_ALIGN_TOP_RIGHT, 0, 0); - lv_obj_set_style_bg_color(lightToggleB, lv_color_lighten(color_primary, 50), - LV_PART_MAIN); + lv_obj_set_style_bg_color(lightToggleB, lv_color_lighten(color_primary, 50), LV_PART_MAIN); lv_obj_set_style_bg_color(lightToggleB, color_primary, LV_PART_INDICATOR); - lv_obj_add_event_cb( - lightToggleB, - [](lv_event_t *e) { mInstance->smartHomeToggle_event_cb(e); }, - LV_EVENT_VALUE_CHANGED, (void *)2); + lv_obj_add_event_cb(lightToggleB, [] (lv_event_t* e) {mInstance->smartHomeToggle_event_cb(e);}, LV_EVENT_VALUE_CHANGED, (void*)2); slider = lv_slider_create(menuBox); - lv_slider_set_range(slider, 60, 255); - lv_obj_set_style_bg_color(slider, lv_color_lighten(lv_color_black(), 30), - LV_PART_INDICATOR); - lv_obj_set_style_bg_grad_color( - slider, lv_color_lighten(lv_palette_main(LV_PALETTE_AMBER), 180), - LV_PART_INDICATOR); + lv_slider_set_range(slider, 0, 100); + lv_obj_set_style_bg_color(slider, lv_color_lighten(lv_color_black(), 30), LV_PART_INDICATOR); + lv_obj_set_style_bg_grad_color(slider, lv_color_lighten(lv_palette_main(LV_PALETTE_AMBER), 180), LV_PART_INDICATOR); lv_obj_set_style_bg_grad_dir(slider, LV_GRAD_DIR_HOR, LV_PART_INDICATOR); lv_obj_set_style_bg_color(slider, lv_color_white(), LV_PART_KNOB); lv_obj_set_style_bg_opa(slider, 255, LV_PART_MAIN); - lv_obj_set_style_bg_color(slider, lv_color_lighten(color_primary, 50), - LV_PART_MAIN); + lv_obj_set_style_bg_color(slider, lv_color_lighten(color_primary, 50), LV_PART_MAIN); lv_slider_set_value(slider, 255, LV_ANIM_OFF); lv_obj_set_size(slider, lv_pct(90), 10); lv_obj_align(slider, LV_ALIGN_TOP_MID, 0, 37); - lv_obj_add_event_cb( - slider, [](lv_event_t *e) { mInstance->smartHomeSlider_event_cb(e); }, - LV_EVENT_VALUE_CHANGED, (void *)2); + lv_obj_add_event_cb(slider, [] (lv_event_t* e) {mInstance->smartHomeSlider_event_cb(e);}, LV_EVENT_VALUE_CHANGED, (void*)2); + // Add another room (empty for now) menuLabel = lv_label_create(tab4); @@ -410,19 +389,20 @@ void OmoteUI::layout_UI() { lv_obj_set_style_bg_color(menuBox, color_primary, LV_PART_MAIN); lv_obj_set_style_border_width(menuBox, 0, LV_PART_MAIN); + // Set current page according to the current Device - lv_tabview_set_act(tabview, currentDevice, LV_ANIM_OFF); + lv_tabview_set_act(tabview, 0, LV_ANIM_OFF); + // Create a page indicator panel = lv_obj_create(lv_scr_act()); - lv_obj_clear_flag( - panel, LV_OBJ_FLAG_CLICKABLE); // this indicator will not be clickable + lv_obj_clear_flag(panel, LV_OBJ_FLAG_CLICKABLE); // This indicator will not be clickable lv_obj_set_size(panel, SCREEN_WIDTH, 30); lv_obj_set_flex_flow(panel, LV_FLEX_FLOW_ROW); lv_obj_align(panel, LV_ALIGN_BOTTOM_MID, 0, 0); lv_obj_set_scrollbar_mode(panel, LV_SCROLLBAR_MODE_OFF); // This small hidden button enables the page indicator to scroll further - lv_obj_t *btn = lv_btn_create(panel); + lv_obj_t* btn = lv_btn_create(panel); lv_obj_set_size(btn, 50, lv_pct(100)); lv_obj_set_style_shadow_width(btn, 0, LV_PART_MAIN); lv_obj_set_style_opa(btn, LV_OPA_TRANSP, LV_PART_MAIN); @@ -430,7 +410,7 @@ void OmoteUI::layout_UI() { btn = lv_btn_create(panel); lv_obj_clear_flag(btn, LV_OBJ_FLAG_CLICKABLE); lv_obj_set_size(btn, 150, lv_pct(100)); - lv_obj_t *label = lv_label_create(btn); + lv_obj_t* label = lv_label_create(btn); lv_label_set_text_fmt(label, "Settings"); lv_obj_align(label, LV_ALIGN_CENTER, 0, 0); lv_obj_set_style_shadow_width(btn, 0, LV_PART_MAIN); @@ -467,15 +447,10 @@ void OmoteUI::layout_UI() { lv_obj_set_size(btn, 50, lv_pct(100)); lv_obj_set_style_shadow_width(btn, 0, LV_PART_MAIN); lv_obj_set_style_opa(btn, LV_OPA_TRANSP, LV_PART_MAIN); - + // Make the indicator scroll together with the tabs by creating a scroll event - lv_obj_add_event_cb( - lv_tabview_get_content(tabview), - [](lv_event_t *e) { mInstance->store_scroll_value_event_cb(e); }, - LV_EVENT_SCROLL, NULL); - lv_obj_add_event_cb( - tabview, [](lv_event_t *e) { mInstance->tabview_device_event_cb(e); }, - LV_EVENT_VALUE_CHANGED, NULL); + lv_obj_add_event_cb(lv_tabview_get_content(tabview), [] (lv_event_t* e) {mInstance->store_scroll_value_event_cb(e);}, LV_EVENT_SCROLL, NULL); + lv_obj_add_event_cb(tabview, [] (lv_event_t* e) {mInstance->tabview_device_event_cb(e);}, LV_EVENT_VALUE_CHANGED, NULL); // Initialize scroll position for the indicator lv_event_send(lv_tabview_get_content(tabview), LV_EVENT_SCROLL, NULL); @@ -488,35 +463,13 @@ void OmoteUI::layout_UI() { lv_obj_add_style(panel, &style_btn, 0); // Make the indicator fade out at the sides using gradient bitmaps - lv_obj_t *img1 = imgs.addLeftGradiant(lv_scr_act()); + lv_obj_t* img1 = imgs.addLeftGradiant(lv_scr_act()); lv_obj_align(img1, LV_ALIGN_BOTTOM_LEFT, 0, 0); lv_obj_set_size(img1, 30, 30); // stretch the 1-pixel high image to 30px - lv_obj_t* img2 = imgs.addRightGradiant(lv_scr_act()); lv_obj_align(img2, LV_ALIGN_BOTTOM_RIGHT, 0, 0); lv_obj_set_size(img2, 30, 30); - // Create a status bar - lv_obj_t *statusbar = lv_btn_create(lv_scr_act()); - lv_obj_set_size(statusbar, 240, 20); - lv_obj_set_style_shadow_width(statusbar, 0, LV_PART_MAIN); - lv_obj_set_style_bg_color(statusbar, lv_color_black(), LV_PART_MAIN); - lv_obj_set_style_radius(statusbar, 0, LV_PART_MAIN); - lv_obj_align(statusbar, LV_ALIGN_TOP_MID, 0, 0); - - lv_obj_t *WifiLabel = lv_label_create(statusbar); - lv_label_set_text(WifiLabel, LV_SYMBOL_WIFI); - lv_obj_align(WifiLabel, LV_ALIGN_LEFT_MID, -8, 0); - lv_obj_set_style_text_font(WifiLabel, &lv_font_montserrat_14, LV_PART_MAIN); - - lv_obj_t *objBattPercentage = lv_label_create(statusbar); - lv_label_set_text(objBattPercentage, ""); - lv_obj_align(objBattPercentage, LV_ALIGN_RIGHT_MID, -16, 0); - lv_obj_set_style_text_font(objBattPercentage, &lv_font_montserrat_14, - LV_PART_MAIN); - - lv_obj_t *objBattIcon = lv_label_create(statusbar); - lv_label_set_text(objBattIcon, LV_SYMBOL_BATTERY_EMPTY); - lv_obj_align(objBattIcon, LV_ALIGN_RIGHT_MID, 8, 0); - lv_obj_set_style_text_font(objBattIcon, &lv_font_montserrat_14, LV_PART_MAIN); + this->create_status_bar(); + this->mHardware->wifi()->begin(); } diff --git a/Platformio/OmoteUI/OmoteUI.hpp b/Platformio/OmoteUI/OmoteUI.hpp index 6d207e7..11c7873 100644 --- a/Platformio/OmoteUI/OmoteUI.hpp +++ b/Platformio/OmoteUI/OmoteUI.hpp @@ -2,25 +2,24 @@ // 2023 Matthew Colvin #pragma once -#include "HardwareInterface.h" +#include "HardwareAbstract.hpp" #include "Images.hpp" #include "lvgl.h" #include #include #include #include - +#include "poller.hpp" /// @brief Singleton to allow UI code to live separately from the Initialization /// of resources. class OmoteUI { public: - OmoteUI(std::shared_ptr aHardware) - : mHardware(aHardware){}; + OmoteUI(std::shared_ptr aHardware); static std::weak_ptr getRefrence() { return getInstance(); }; static std::shared_ptr - getInstance(std::shared_ptr aHardware = nullptr) { + getInstance(std::shared_ptr aHardware = nullptr) { if (mInstance) { return mInstance; } else if (aHardware) { @@ -46,23 +45,194 @@ public: void smartHomeSlider_event_cb(lv_event_t *e); // Virtual Keypad Event handler void virtualKeypad_event_cb(lv_event_t *e); + void wifi_settings_cb(lv_event_t* event); + void connect_btn_cb(lv_event_t* event); + + void password_field_event_cb(lv_event_t* e); // Use LVGL to layout the ui and register the callbacks void layout_UI(); + void ta_kb_event_cb(lv_event_t* e); + + void wifi_scan_done(std::shared_ptr> info); void loopHandler(); + /** + * @brief Function to hide the keyboard. If the keyboard is attached to a text area, it will be hidden when the + * text area is defocused. This function can be used if the keyboard need to be hidden due to some script event. + * + */ + void hide_keyboard(); + + /** + * @brief Function to show the keyboard. If a text area needs the keybaord, it should be attached to the text area + * using the approbiate function. The keyboard will then show up when the text area is focused. This function is + * needed if the keyboard should be shown due to some script or other trigger. + * + */ + void show_keyboard(); private: static std::shared_ptr mInstance; - std::shared_ptr mHardware; + std::shared_ptr mHardware; + + std::unique_ptr batteryPoller; + + void reset_settings_menu(); + void attach_keyboard(lv_obj_t* textarea); + std::shared_ptr> found_wifi_networks; + /** + * @brief Keyboard object used whenever a keyboard is needed. + * + */ +lv_obj_t* kb; + +/** + * @brief Function to create the keyboard object which can then be attached to different text areas. + * + */ +void create_keyboard(); + + /** + * @brief Set the up settings object + * + * @param parent + */ + void setup_settings(lv_obj_t* parent); + + /** + * @brief LVGL Menu for settings pages as needed. + * + */ + lv_obj_t* settingsMenu; + + /** + * @brief Main page of the settings menu + * + */ + lv_obj_t* settingsMainPage; + + /** + * @brief Battery percentage label + * + */ + lv_obj_t* objBattPercentage; + + /** + * @brief Battery icon object in the status bar + * + */ + lv_obj_t* objBattIcon; + + void create_status_bar(); lv_obj_t *panel = nullptr; Images imgs = Images(); uint_fast8_t currentDevice = 4; - int backlight_brightness = 255; lv_color_t color_primary = lv_color_hex(0x303030); // gray bool wakeupByIMUEnabled = true; inline static const uint_fast8_t virtualKeyMapTechnisat[10] = { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0x0}; + +/************************************** WIFI Settings Menu *******************************************************/ + /** + * @brief Container within the wifi selection page + */ + lv_obj_t* wifi_setting_cont; + + /** + * @brief Wifi settings entry point on the settings tab + * + */ + lv_obj_t* wifiOverview; + + /** + * @brief Label in the wifi password page. This label is updated with the selected SSID when the credentials for + * a wifi network is entered. + * + */ + lv_obj_t* wifi_password_label; + + /** + * @brief Menu Subpage for the wifi password + */ + lv_obj_t* wifi_password_page; + + /** + * @brief Menu Subpage for wifi selection + */ + lv_obj_t* wifi_selection_page; + + /** + * @brief Wifi Label shown in the top status bar + */ + lv_obj_t* WifiLabel; + + /** + * @brief Number of wifi subpage needed to display the found wifi networks + * + */ + unsigned int no_subpages; + + /** + * @brief number of wifi networks found + * + */ + unsigned int no_wifi_networks; + + + void wifi_status(std::shared_ptr status); + /** + * @brief callback function to get next wifi subpage. This callback can be used to get the next or previous page + * + * @param e lvgl event object + */ + void next_wifi_selection_subpage(lv_event_t* e); + + /** + * @brief Create a wifi selection sub page object + * + * @param menu LVGL Menu where the sub page should be added to + * @return lv_obj_t* Menu sub page object pointer + */ + lv_obj_t* create_wifi_selection_page(lv_obj_t* menu); + + /** + * @brief Method to create the wifi password sub page + * + * @param menu Menu where the sub page should be created + * @return lv_obj_t* menu sub page object pointer + */ + lv_obj_t* create_wifi_password_page(lv_obj_t* menu); + + /** + * @brief Method to create the wifi settings on the main page + * + * @param parent lv object parent where the main settings page should be added to + */ + void create_wifi_main_page(lv_obj_t* parent); + + /** + * @brief Method to create wifi settings. This method will call the create_wifi_selection_page, + * the create_wifi_password_page, and the create_wifi_main_page + * + * @param menu Settings menu where the sub pages should be added to + * @param parent lv object parent where the main settings page should be added to + */ + void create_wifi_settings(lv_obj_t* menu, lv_obj_t* parent); + + /** + * @brief Function to update the wifi selection sub page + * + * @param page index of the page to display + */ + void update_wifi_selection_subpage(int page); + + /** + * @brief Function to create the display settings page. + * + * @param parent LVGL object acting as a parent for the display settings page + */ + void display_settings(lv_obj_t* parent); }; diff --git a/Platformio/OmoteUI/displaySettings.cpp b/Platformio/OmoteUI/displaySettings.cpp new file mode 100644 index 0000000..2f9dd39 --- /dev/null +++ b/Platformio/OmoteUI/displaySettings.cpp @@ -0,0 +1,56 @@ +#include "OmoteUI.hpp" + +void OmoteUI::display_settings(lv_obj_t* parent) +{ + + lv_obj_t* menuLabel = lv_label_create(parent); + lv_label_set_text(menuLabel, "Display"); + + lv_obj_t* menuBox = lv_obj_create(parent); + lv_obj_set_size(menuBox, lv_pct(100), 109); + lv_obj_set_style_bg_color(menuBox, color_primary, LV_PART_MAIN); + lv_obj_set_style_border_width(menuBox, 0, LV_PART_MAIN); + + lv_obj_t* brightnessIcon = imgs.addLowBrightnessIcon(menuBox); + lv_obj_align(brightnessIcon, LV_ALIGN_TOP_LEFT, 0, 0); + lv_obj_t* slider = lv_slider_create(menuBox); + lv_slider_set_range(slider, 0, 255); + lv_obj_set_style_bg_color(slider, lv_color_white(), LV_PART_KNOB); + lv_obj_set_style_bg_opa(slider, LV_OPA_COVER, LV_PART_MAIN); + lv_obj_set_style_bg_color(slider, lv_color_lighten(color_primary, 50), LV_PART_MAIN); + lv_slider_set_value(slider, mHardware->display()->getBrightness() , LV_ANIM_OFF); + lv_obj_set_size(slider, lv_pct(66), 10); + lv_obj_align(slider, LV_ALIGN_TOP_MID, 0, 3); + brightnessIcon = imgs.addHighBrightnessIcon(menuBox); + lv_obj_align(brightnessIcon, LV_ALIGN_TOP_RIGHT, 0, -1); + lv_obj_add_event_cb(slider, [] (lv_event_t* e) {mInstance->bl_slider_event_cb(e);}, LV_EVENT_VALUE_CHANGED, nullptr); + + menuLabel = lv_label_create(menuBox); + lv_label_set_text(menuLabel, "Lift to Wake"); + lv_obj_align(menuLabel, LV_ALIGN_TOP_LEFT, 0, 32); + lv_obj_t* wakeToggle = lv_switch_create(menuBox); + lv_obj_set_size(wakeToggle, 40, 22); + lv_obj_align(wakeToggle, LV_ALIGN_TOP_RIGHT, 0, 29); + lv_obj_set_style_bg_color(wakeToggle, lv_color_hex(0x505050), LV_PART_MAIN); + lv_obj_add_event_cb(wakeToggle, [] (lv_event_t* e) {mInstance->WakeEnableSetting_event_cb(e);}, LV_EVENT_VALUE_CHANGED, NULL); + if(wakeupByIMUEnabled) lv_obj_add_state(wakeToggle, LV_STATE_CHECKED); // set default state + + menuLabel = lv_label_create(menuBox); + lv_label_set_text(menuLabel, "Timeout"); + lv_obj_align(menuLabel, LV_ALIGN_TOP_LEFT, 0, 64); + lv_obj_t* drop = lv_dropdown_create(menuBox); + lv_dropdown_set_options(drop, "10s\n" + "30s\n" + "1m\n" + "3m"); + lv_obj_align(drop, LV_ALIGN_TOP_RIGHT, 0, 61); + lv_obj_set_size(drop, 70, 22); + //lv_obj_set_style_text_font(drop, &lv_font_montserrat_12, LV_PART_MAIN); + //lv_obj_set_style_text_font(lv_dropdown_get_list(drop), &lv_font_montserrat_12, LV_PART_MAIN); + lv_obj_set_style_pad_top(drop, 1, LV_PART_MAIN); + lv_obj_set_style_bg_color(drop, color_primary, LV_PART_MAIN); + lv_obj_set_style_bg_color(lv_dropdown_get_list(drop), color_primary, LV_PART_MAIN); + lv_obj_set_style_border_width(lv_dropdown_get_list(drop), 1, LV_PART_MAIN); + lv_obj_set_style_border_color(lv_dropdown_get_list(drop), lv_color_hex(0x505050), LV_PART_MAIN); + +} \ No newline at end of file diff --git a/Platformio/OmoteUI/poller.cpp b/Platformio/OmoteUI/poller.cpp new file mode 100644 index 0000000..e49198d --- /dev/null +++ b/Platformio/OmoteUI/poller.cpp @@ -0,0 +1,26 @@ +#include "poller.hpp" + +#include +#include + +using namespace std::chrono; + +poller::poller(std::function aOnPollCb, milliseconds aPollTime):mIntermittentCallback(std::move(aOnPollCb)){ + mTimer = lv_timer_create(poller::onPoll,aPollTime.count(),this); + lv_timer_set_repeat_count(mTimer,-1); // Call forever +} + +poller::~poller(){ + if(mTimer){ + lv_timer_del(mTimer); + mTimer = nullptr; + } +} + +void poller::onPoll(_lv_timer_t* aTimer){ + poller* currentPoller = reinterpret_cast(aTimer->user_data); + + if(currentPoller->mIntermittentCallback){ + currentPoller->mIntermittentCallback(); + } +} \ No newline at end of file diff --git a/Platformio/OmoteUI/poller.hpp b/Platformio/OmoteUI/poller.hpp new file mode 100644 index 0000000..3e291a1 --- /dev/null +++ b/Platformio/OmoteUI/poller.hpp @@ -0,0 +1,23 @@ +#include +#include +#include +#include "lvgl.h" + +class poller{ +public: + poller(std::function aOnPollCb, std::chrono::milliseconds pollTime = std::chrono::seconds(5)); + virtual ~poller(); + + void setPollPeriod(std::chrono::milliseconds aPollPeriod){ lv_timer_set_period(mTimer, aPollPeriod.count());} + inline void pause() { lv_timer_pause(mTimer);} + inline void resume() { lv_timer_resume(mTimer);} + inline void reset() { lv_timer_reset(mTimer);} + inline void runNext() { lv_timer_ready(mTimer);} + +private: + lv_timer_t* mTimer = nullptr; + std::function mIntermittentCallback = nullptr; + + // Static function registered to every timers callback to pass this object as context + static void onPoll(_lv_timer_t* aTimer); +}; \ No newline at end of file diff --git a/Platformio/OmoteUI/wifiSettings.cpp b/Platformio/OmoteUI/wifiSettings.cpp new file mode 100644 index 0000000..d5f67eb --- /dev/null +++ b/Platformio/OmoteUI/wifiSettings.cpp @@ -0,0 +1,312 @@ +#include "OmoteUI.hpp" + +#define WIFI_SUBPAGE_SIZE 3 +static char* ssid; + +lv_obj_t* OmoteUI::create_wifi_selection_page(lv_obj_t* menu) +{ + /* Create sub page for wifi*/ + lv_obj_t* subpage = lv_menu_page_create(menu, NULL); + this->wifi_setting_cont = lv_menu_cont_create(subpage); + lv_obj_set_layout(this->wifi_setting_cont, LV_LAYOUT_FLEX); + lv_obj_set_flex_flow(this->wifi_setting_cont, LV_FLEX_FLOW_COLUMN); + lv_obj_set_scrollbar_mode(this->wifi_setting_cont, LV_SCROLLBAR_MODE_ACTIVE); + + lv_obj_t* menuLabel = lv_label_create(this->wifi_setting_cont); + lv_label_set_text(menuLabel, "Searching for wifi networks"); + + + return subpage; +} + +/** + * @brief Callback function for the show password checkbox. Checking the box will show the password while unchecked the + * password will be shown as dots. + * + * @param e Pointer to event object for the event where this callback is called + */ +static void show_password_cb(lv_event_t* e) +{ + lv_obj_t* password_field = (lv_obj_t*) e->user_data; + if (lv_obj_has_state(e->target, LV_STATE_CHECKED)){ + lv_textarea_set_password_mode(password_field, false); + } + else{ + lv_textarea_set_password_mode(password_field, true); + } + +} + +/** + * @brief Textarea callback function for the password field. In case the enter key is pressed in the text area, the + * function will try to connect to the network with the provided password. + * + * @param e Pointer to event object for the event where this callback is called + */ +void OmoteUI::password_field_event_cb(lv_event_t* e) +{ + lv_event_code_t code = lv_event_get_code(e); + lv_obj_t * ta = lv_event_get_target(e); + lv_obj_t * kb = (lv_obj_t*) lv_event_get_user_data(e); + + const char* password = lv_textarea_get_text(ta); + switch(code){ + case LV_EVENT_READY: + this->mHardware->wifi()->connect(std::make_shared(std::string(ssid)), std::make_shared(std::string(password))); + lv_obj_clear_state(ta, LV_STATE_FOCUSED); + this->hide_keyboard(); + this->reset_settings_menu(); + /* Fall through on purpose. Pressing enter should disable the keyboard as well*/ + default: + break; + + } +} + +/** + * @brief Callback which is triggered when clicking the connect button. It triggers the wifi connection. + * + * @param event Pointer to event object for the event where this callback is called + */ +void OmoteUI::connect_btn_cb(lv_event_t* event) +{ + lv_obj_t* ta = (lv_obj_t*) event->user_data; + const char* password = lv_textarea_get_text(ta); + + this->mHardware->wifi()->connect(std::make_shared(std::string(ssid)), std::make_shared(std::string(password))); +//Trigger wifi connection here + //wifihandler.connect(ssid, password); + lv_obj_clear_state(ta, LV_STATE_FOCUSED); + this->hide_keyboard(); + this->reset_settings_menu(); + +} + +void OmoteUI::create_wifi_main_page(lv_obj_t* parent) +{ + lv_obj_t* menuLabel = lv_label_create(parent); + lv_label_set_text(menuLabel, "Wi-Fi"); + this->wifiOverview = lv_obj_create(parent); + lv_obj_set_size(this->wifiOverview, lv_pct(100), 80); + lv_obj_set_style_bg_color(this->wifiOverview, color_primary, LV_PART_MAIN); + lv_obj_set_style_border_width(this->wifiOverview, 0, LV_PART_MAIN); + menuLabel = lv_label_create(this->wifiOverview); + + lv_obj_t* arrow = lv_label_create(this->wifiOverview); + lv_label_set_text(arrow, LV_SYMBOL_RIGHT); + lv_obj_align(arrow, LV_ALIGN_TOP_RIGHT, 0, 0); + + lv_obj_t* ip_label = lv_label_create(this->wifiOverview); + lv_label_set_text(ip_label, "IP:"); + lv_obj_align(ip_label, LV_ALIGN_BOTTOM_LEFT, 0, 0); + + lv_obj_t* ip = lv_label_create(this->wifiOverview); + lv_obj_align(ip, LV_ALIGN_BOTTOM_RIGHT, 0, 0); + + lv_label_set_text(menuLabel, "Disconnected"); + lv_label_set_text(ip, "-"); + + lv_menu_set_load_page_event(this->settingsMenu, this->wifiOverview, this->wifi_selection_page); + lv_obj_add_event_cb(this->wifiOverview, [] (lv_event_t* e) {mInstance->wifi_settings_cb(e);}, LV_EVENT_CLICKED, this->wifi_setting_cont); +} + +void OmoteUI::wifi_scan_done(std::shared_ptr> info) +{ + unsigned int size = info->size(); + this->no_subpages = (size + WIFI_SUBPAGE_SIZE - 1)/WIFI_SUBPAGE_SIZE; + this->no_wifi_networks = size; + this->found_wifi_networks = info; + + if (size == 0) + { + lv_obj_t* menuBox = lv_obj_create(this->wifi_setting_cont); + lv_obj_set_size(menuBox, lv_pct(100), 45); + lv_obj_set_scrollbar_mode(menuBox, LV_SCROLLBAR_MODE_OFF); + lv_obj_t* menuLabel = lv_label_create(menuBox); + lv_label_set_text(menuLabel, "no networks found"); + } + else + { + this->update_wifi_selection_subpage(0); + } +} +void OmoteUI::next_wifi_selection_subpage(lv_event_t* e) +{ + int subpage = (uintptr_t) lv_event_get_user_data(e); + this->update_wifi_selection_subpage(subpage); +} + + +/** + * @brief Callback function in case a wifi is selected. This callback function will change the label of the wifi password + * sub page to the selected wifi network. + * + * @param e Pointer to event object for the event where this callback is called + */ +static void wifi_selected_cb(lv_event_t* e) +{ + lv_obj_t* label = lv_obj_get_child(e->target, 0); + lv_label_set_text((lv_obj_t*) e->user_data, lv_label_get_text(label)); + ssid = lv_label_get_text(label); +} + + +void OmoteUI::update_wifi_selection_subpage(int page) +{ + if (page < this->no_subpages) + { + lv_obj_clean(this->wifi_setting_cont); + + lv_obj_t* pageLabel = lv_label_create(this->wifi_setting_cont); + lv_label_set_text_fmt(pageLabel, "Page %d/%d", page + 1, this->no_subpages); + if (page > 0) + { + lv_obj_t* menuBox = lv_obj_create(this->wifi_setting_cont); + lv_obj_set_size(menuBox, lv_pct(100), 45); + lv_obj_set_scrollbar_mode(menuBox, LV_SCROLLBAR_MODE_OFF); + + lv_obj_t* menuLabel = lv_label_create(menuBox); + lv_label_set_text(menuLabel, "Previous"); + lv_obj_align(menuLabel, LV_ALIGN_TOP_RIGHT, 0, 0); + lv_obj_add_event_cb(menuBox, [](lv_event_t* e) {mInstance->next_wifi_selection_subpage(e);},LV_EVENT_CLICKED, (void*)(page - 1)); + lv_obj_t* arrow = lv_label_create(menuBox); + lv_label_set_text(arrow, LV_SYMBOL_LEFT); + lv_obj_align(arrow, LV_ALIGN_TOP_LEFT, 0, 0); + } + + for (int i = 0; i < WIFI_SUBPAGE_SIZE && (page*WIFI_SUBPAGE_SIZE + i) < this->no_wifi_networks; i++) + { + lv_obj_t* menuBox = lv_obj_create(this->wifi_setting_cont); + lv_obj_set_size(menuBox, lv_pct(100), 45); + lv_obj_set_scrollbar_mode(menuBox, LV_SCROLLBAR_MODE_OFF); + + lv_obj_add_flag(menuBox, LV_OBJ_FLAG_EVENT_BUBBLE); + + lv_obj_t* menuLabel = lv_label_create(menuBox); + lv_label_set_text(menuLabel, this->found_wifi_networks->at(page*WIFI_SUBPAGE_SIZE + i).ssid.c_str()); + lv_obj_t* wifi_image; + + int RSSI = this->found_wifi_networks->at(page*WIFI_SUBPAGE_SIZE + i).rssi; + + if (RSSI > -50) + { + wifi_image = imgs.addWifiHighSignal(menuBox); + } + else if (RSSI > -60) + { + wifi_image = imgs.addWifiMidSignal(menuBox); + } + else if (RSSI > -70) + { + wifi_image = imgs.addWifiLowSignal(menuBox); + } + else + { + wifi_image = imgs.addWifiLowSignal(menuBox); + } + lv_obj_align(wifi_image, LV_ALIGN_TOP_RIGHT, 0, 0); + lv_menu_set_load_page_event(this->settingsMenu, menuBox, this->wifi_password_page); + lv_obj_add_event_cb(menuBox, wifi_selected_cb, LV_EVENT_CLICKED, this->wifi_password_label); + } + + if ((page + 1) < this->no_subpages) + { + lv_obj_t* menuBox = lv_obj_create(this->wifi_setting_cont); + lv_obj_set_size(menuBox, lv_pct(100), 45); + lv_obj_set_scrollbar_mode(menuBox, LV_SCROLLBAR_MODE_OFF); + + lv_obj_t* menuLabel = lv_label_create(menuBox); + lv_label_set_text(menuLabel, "Next"); + lv_obj_add_event_cb(menuBox, [](lv_event_t* e) {mInstance->next_wifi_selection_subpage(e);}, LV_EVENT_CLICKED, (void*)(page + 1)); + + lv_obj_t* arrow = lv_label_create(menuBox); + lv_label_set_text(arrow, LV_SYMBOL_RIGHT); + lv_obj_align(arrow, LV_ALIGN_TOP_RIGHT, 0, 0); + + } + lv_obj_scroll_to_y(this->wifi_setting_cont, 0, LV_ANIM_OFF); + } +} + +void OmoteUI::create_wifi_settings(lv_obj_t* menu, lv_obj_t* parent) +{ + this->wifi_selection_page = this->create_wifi_selection_page(menu); + this->wifi_password_page = this->create_wifi_password_page(this->settingsMenu); + this->create_wifi_main_page(parent); + this->mHardware->wifi()->onScanDone([] (std::shared_ptr> info) {mInstance->wifi_scan_done(info);}); + this->mHardware->wifi()->onStatusUpdate([] (std::shared_ptr status) {mInstance->wifi_status(status);}); +} + +void OmoteUI::wifi_status(std::shared_ptr status) +{ + this->mHardware->debugPrint("connected %d\n", status->isConnected); + this->mHardware->debugPrint("IP %s\n", status->IP); + this->mHardware->debugPrint("SSID %s\n", status->ssid); + + lv_obj_t* ip_label = lv_obj_get_child(this->wifiOverview, 3); + lv_obj_t* ssid_label = lv_obj_get_child(this->wifiOverview, 0); + + if (status->isConnected) + { + lv_label_set_text(this->WifiLabel, LV_SYMBOL_WIFI); + lv_label_set_text(ssid_label, status->ssid.c_str()); + lv_label_set_text(ip_label, status->IP.c_str()); + } + else + { + lv_label_set_text(this->WifiLabel, ""); + lv_label_set_text(ssid_label, "Disconnected"); + lv_label_set_text(ip_label, "-"); + } +} + +lv_obj_t* OmoteUI::create_wifi_password_page(lv_obj_t* menu) +{ + lv_obj_t* ret_val = lv_menu_page_create(menu, NULL); + lv_obj_t* cont = lv_menu_cont_create(ret_val); + lv_obj_set_layout(cont, LV_LAYOUT_FLEX); + lv_obj_set_flex_flow(cont, LV_FLEX_FLOW_COLUMN); + lv_obj_set_scrollbar_mode(cont, LV_SCROLLBAR_MODE_ACTIVE); + + this->wifi_password_label = lv_label_create(cont); + lv_label_set_text(this->wifi_password_label, "Password"); + lv_obj_t* password_input = lv_textarea_create(cont); + lv_obj_set_width(password_input, lv_pct(100)); + lv_textarea_set_password_mode(password_input, true); + lv_textarea_set_one_line(password_input, true); + lv_textarea_set_placeholder_text(password_input, "Password"); + lv_obj_add_event_cb(password_input, [] (lv_event_t* e) {mInstance->password_field_event_cb(e);} , LV_EVENT_READY, NULL ); + this->attach_keyboard(password_input); + + lv_obj_t* show_password = lv_checkbox_create(cont); + lv_checkbox_set_text(show_password, "Show password"); + lv_obj_add_event_cb(show_password, show_password_cb, LV_EVENT_VALUE_CHANGED, password_input); + + lv_obj_t* connect_button = lv_btn_create(cont); + lv_obj_t* label = lv_label_create(connect_button); + lv_label_set_text(label, "Connect"); + lv_obj_add_event_cb(connect_button,[] (lv_event_t* e) { mInstance->connect_btn_cb(e);}, LV_EVENT_CLICKED, password_input); + + return ret_val; +} + +/** + * @brief Callback which is triggered when the wifi settings are opened (the wifi settings are pressed in the settings + * main page). This function will trigger the asynchronous scan for wifi networks and update the label of the wifi + * selection page to indicate that wifi networks are being searched for. The wifi event callback function then has to + * call the API function to fill the page with the found networks. + * + * @param event Pointer to event object for the event where this callback is called + */ +void OmoteUI::wifi_settings_cb(lv_event_t* event) +{ + lv_obj_t* cont = (lv_obj_t*) lv_event_get_user_data(event); + lv_obj_clean(cont); + lv_obj_t* label = lv_label_create(cont); + lv_label_set_text(label, "Searching for wifi networks"); + mHardware->debugPrint("Wifi settings cb called\n"); + mHardware->wifi()->scan(); + //This will trigger an asynchronouse network scan + // We need to trigger wifi search via HAL + //wifihandler.scan(); +} \ No newline at end of file diff --git a/Platformio/platformio.ini b/Platformio/platformio.ini index 4e883c7..51ca044 100644 --- a/Platformio/platformio.ini +++ b/Platformio/platformio.ini @@ -40,13 +40,17 @@ build_flags = ; ------------- Includes ------------------------------------ -I OmoteUI -I HAL - -I HAL/Interface + -I HAL/HardwareModules lib_deps = - lvgl/lvgl@^8.3.9 + ;lvgl/lvgl@^8.3.9 + lvgl=https://github.com/lvgl/lvgl/archive/refs/tags/v8.3.9.zip + lib_archive = false build_src_filter = +<../OmoteUI/*> + +<../HAL/HardwareAbstract.cpp> + +<../HAL/HardwareModules/*.cpp> @@ -62,6 +66,7 @@ lib_deps = ${env.lib_deps} sparkfun/SparkFun LIS3DH Arduino Library@^1.0.3 crankyoldgit/IRremoteESP8266@^2.8.4 + adafruit/Adafruit BusIO @ 1.9.6 adafruit/Adafruit FT6206 Library@^1.0.6 bodmer/TFT_eSPI@^2.5.23 knolleary/PubSubClient@^2.8 @@ -95,6 +100,9 @@ build_flags = ; ------------- Includes -------------------------------------------- -I HAL/Targets/ESP32 + -I HAL/Targets/ESP32/battery + -I HAL/Targets/ESP32/display + -I HAL/Targets/ESP32/wifiHandler build_unflags = -std=gnu++11 @@ -116,6 +124,7 @@ build_flags = -D LV_LVGL_H_INCLUDE_SIMPLE -D LV_DRV_NO_CONF -D USE_SDL + -D SDL_MAIN_HANDLED -D SDL_HOR_RES=SCREEN_WIDTH -D SDL_VER_RES=SCREEN_HEIGHT -D SDL_ZOOM=1 @@ -123,6 +132,7 @@ build_flags = ; -------------- Sim Includes --------------------------- -I HAL/Targets/Simulator + -I HAL/Targets/Simulator/wifiHandlerSim debug_build_flags = -g ;Allow debugging in vscode @@ -135,6 +145,6 @@ lib_deps = build_src_filter = + +<../HAL/Targets/Simulator/*> - +<../OmoteUI/*> + ${env.build_src_filter} ; Force compile LVGL demo, remove when working on your own project diff --git a/README.md b/README.md index 5ac913e..9e6e08f 100644 --- a/README.md +++ b/README.md @@ -89,6 +89,8 @@ Distributed under the GPL v3 License. See [LICENSE](https://github.com/CoretechR ## Contact -Maximilian Kern - [kernm.de](kernm.de) +Maximilian Kern - [kernm.de](https://kernm.de) -Project Link: [https://hackaday.io/project/191752-omote-diy-universal-remote](https://hackaday.io/project/191752-omote-diy-universal-remote) +Omote Discord: [https://discord.gg/5PnYFAsKsG](https://discord.gg/5PnYFAsKsG) + +Project Page on Hackaday.io: [https://hackaday.io/project/191752-omote-diy-universal-remote](https://hackaday.io/project/191752-omote-diy-universal-remote)