From ae5d12b3a27e445037c56265d188c203dea47d0d Mon Sep 17 00:00:00 2001 From: matt_ed Date: Tue, 4 Aug 2026 19:38:58 -0700 Subject: [PATCH] next iteration on display, still some artifacting issues, and ux with buttons states and updating --- README.md | 20 +- TODO.md | 34 +- main/api/ha_config.h | 12 +- main/api/ha_data.c | 114 +++++ main/api/ha_data.h | 46 ++ main/drivers/display/display_rgb.c | 47 +- main/drivers/display/display_rgb.h | 19 +- main/main.c | 55 ++- main/ui/icon_font.c | 695 +++++++++++++++-------------- main/ui/lvgl_port.h | 2 +- main/ui/ui_icons.h | 3 + main/ui/ui_manager.c | 188 +++++++- sim/sim_main.c | 18 + tools/make_icon_font.py | 5 + 14 files changed, 860 insertions(+), 398 deletions(-) diff --git a/README.md b/README.md index 535a2be..91de73b 100644 --- a/README.md +++ b/README.md @@ -225,10 +225,14 @@ about PSRAM bandwidth or panel timing. - **`lv_label_set_text()` invalidates unconditionally**, even when the text is identical — so setting an unchanged value still forces a repaint. All label updates go through `label_set_if_changed()`. -- **WiFi must be brought up before `display_init()`.** The bounce refill ISR - reads PSRAM, which shares the cache with flash; an NVS write while the panel - is running faults it with *"Cache disabled but cached memory region - accessed"*. +- **Display bring-up is two-phase, and both orderings are load-bearing.** + `display_alloc()` runs *before* WiFi: the bounce buffers need two contiguous + 25.6KB internal DMA blocks, and WiFi's RX buffer churn fragments the heap + within seconds — observed as a boot-loop with 84KB free and no block big + enough. `display_start()` runs *after* WiFi: once scan-out begins, the + bounce refill ISR reads PSRAM, which shares the cache with flash, and an + NVS/PHY write would fault it with *"Cache disabled but cached memory region + accessed"*. Allocate early, scan late. ## Partitions @@ -256,5 +260,9 @@ enabled (the panel cannot stream straight from PSRAM), which is exactly why flash writes are dangerous while the panel runs: the refill ISR reads PSRAM, which shares the cache with flash on the S3, so an NVS write faults it with *"Cache disabled but cached memory region accessed"*. All flash writes happen -before `display_init()` and `CONFIG_ESP_WIFI_NVS_ENABLED` is off to keep the -WiFi stack from writing later. +before `display_start()` and `CONFIG_ESP_WIFI_NVS_ENABLED` is off to keep the +WiFi stack from writing later. Static buffers beware: `.bss` lives in the +same internal RAM the bounce buffers come from, with only ~33KB of slack +after the panel is up — a few KB of new static array is enough to matter +(the trend ring is deliberately time-bucketed down to ~720 bytes for this +reason). diff --git a/TODO.md b/TODO.md index a3f4306..f7c5c18 100644 --- a/TODO.md +++ b/TODO.md @@ -2,20 +2,22 @@ ## Not yet verified on hardware -Flashed and booting clean (icons on, first poll ~8s, no errors), but eyes and -fingers haven't confirmed: +Flashed and booting clean (two-phase display init, icons on, first poll ~9s, +no errors), but eyes and fingers haven't confirmed: -1. Touch actually toggling a light end-to-end. Tiles are now **optimistic**: - they flip on tap immediately and hold that state up to 5s until HA - confirms (see `light_hold_t` in ui_manager.c). If a tile flips then snaps - back 5s later, the command failed — check `ha_client` on serial. -2. Whether the full-screen invalidate after each poll actually bounds the - left-edge artefacts (it repaints them away; it cannot prevent them). If - lines still persist for longer than one poll interval, that mechanism is - not working and the next lever is pausing only around LVGL's flush. -3. That the six light tiles are comfortable finger targets at ~125px, and - that sliders track the finger without jumping (poll updates skip pressed - sliders by design). +1. Slider feel: press sends one command at the touch position immediately, + drag is display-only tracking the finger, lift sends the final level. + Poll data never moves a pressed knob. +2. Trend arrows appear ~5 minutes after boot (indoor big card, outdoor and + pressure cells) once the local ring has history. They are local-history + based and reset on reboot — that is by design, not a bug. +3. Artefact lifetime: interactions schedule a one-shot full repaint 600ms + after the last touch, and every poll repaints too. Artefacts should now + visibly self-clean in under a second after touching, and within a poll + otherwise. If they *persist* beyond that, the repaint isn't reaching + them; if they merely *recur* during interaction, that is the PSRAM + bandwidth ceiling (README) and the honest remaining levers are fewer + redraws or 120MHz PSRAM on a newer IDF. ## Done @@ -95,8 +97,10 @@ hosts the thermostat before building it twice. - The `°` glyph exists in LVGL's built-in Montserrat fonts; the `·` separator that does not appears only in log strings, never on screen. - LVGL recursive-mutex locking is consistent across all UI entry points. -- Init order in `main.c` is deliberate and load-bearing: WiFi/NVS before - `display_init()`, `backlight_init()` before `touch_init()`. Never reorder. +- Init order in `main.c` is deliberate and load-bearing: + `display_alloc()` before WiFi (contiguous bounce buffers from a virgin + heap), WiFi/NVS before `display_start()` (flash writes finished before + scan-out), `backlight_init()` before `touch_init()`. Never reorder. - The bounce buffer is enabled and load-bearing. - Board is N16R8 (16MB flash / 8MB octal PSRAM). - `touch_get_indev()`, `display_get_panel()` and `lvgl_port_is_paused()` are diff --git a/main/api/ha_config.h b/main/api/ha_config.h index c492163..4c93a8f 100644 --- a/main/api/ha_config.h +++ b/main/api/ha_config.h @@ -63,15 +63,19 @@ * put the sofa icon on the patio. Only ui_manager.c expands it; the api-layer * consumers ignore the argument, so this header does not include ui_icons.h. * - * Note light.main_room is a GROUP containing blue_lamp, brown_lamp and - * landing_chandelier. Toggling it changes three of the other tiles; that is - * expected, and the UI reflects it on the next poll. + * light.main_room used to be here and was removed deliberately: it is a + * GROUP of blue_lamp, brown_lamp and landing_chandelier -- three of the + * other tiles. One tap restyled four tiles at once, which both confused the + * optimistic-hold logic and triggered a redraw storm big enough to glitch + * the panel (see README on PSRAM bandwidth). Groups spanning other tiles do + * not belong in this list. light.tv_room is also a group (of 2), but of + * lights that have no tile of their own, which is fine. */ /* Labels must fit one line of Montserrat 16 in a ~125px tile -- roughly 11 * characters. Longer ones are truncated with an ellipsis, which reads as a * mistake. "Dining Room" is one character too wide, hence "Dining". */ #define HA_LIGHT_LIST(X) \ - X("light.main_room", "Main Room", true, ICON_SOFA) \ + X("light.tv_room", "TV Room", true, ICON_TV) \ X("light.dining_room", "Dining", true, ICON_DINING) \ X("light.blue_lamp", "Blue Lamp", true, ICON_FLOOR_LAMP) \ X("light.brown_lamp", "Brown Lamp", true, ICON_DESK_LAMP) \ diff --git a/main/api/ha_data.c b/main/api/ha_data.c index d584cdc..ac18dad 100644 --- a/main/api/ha_data.c +++ b/main/api/ha_data.c @@ -305,6 +305,120 @@ const char *ha_condition_short(const char *slug) return (c != NULL) ? c->shrt : (slug != NULL ? slug : "--"); } +/* ------------------------------------------------------------------ trends */ + +/* + * 20 slots, one kept per ~4 minutes, covers ~80 minutes. Feeding faster than + * that overwrites the newest slot instead of consuming a new one, so a 60s + * poll cadence still fills the ring at 4-minute spacing. + * + * Size matters here more than it looks: this array is .bss, which lives in + * internal RAM on the S3 -- the same internal RAM the RGB panel's bounce + * buffers come from, with only a few KB of slack (README, memory notes). A + * naive 72-slot-per-poll ring cost 2.6KB and was enough to tip display_init + * into "no mem for bounce buffer" on an unlucky boot. Keep this structure + * small; if it ever needs to grow, it must move to PSRAM instead. + * + * Static per channel; a reboot forgets history, and the display shows no + * arrow until enough accumulates again (see ha_data.h). + */ +#define TREND_SLOTS 20 +#define TREND_BUCKET_MS (4u * 60u * 1000u) + +typedef struct { + float value; + uint32_t ms; + bool used; +} trend_sample_t; + +static trend_sample_t trend_ring[HA_TREND_CHANNELS][TREND_SLOTS]; +static int trend_head[HA_TREND_CHANNELS]; /* slot most recently written */ + +void ha_trend_feed(int channel, float value, uint32_t now_ms) +{ + if (channel < 0 || channel >= HA_TREND_CHANNELS) { + return; + } + + trend_sample_t *newest = &trend_ring[channel][trend_head[channel]]; + + /* Inside the current bucket: refresh the newest sample in place, so + * compute always sees the latest reading without spending a slot. */ + if (newest->used && (now_ms - newest->ms) < TREND_BUCKET_MS) { + newest->value = value; + return; + } + + const int next = newest->used ? (trend_head[channel] + 1) % TREND_SLOTS + : trend_head[channel]; + trend_ring[channel][next] = (trend_sample_t){ value, now_ms, true }; + trend_head[channel] = next; +} + +ha_trend_t ha_trend_compute(int channel, float threshold_per_hour, uint32_t now_ms) +{ + if (channel < 0 || channel >= HA_TREND_CHANNELS) { + return HA_TREND_UNKNOWN; + } + + /* The newest sample is the one just fed; find the usable sample whose + * age is closest to the window. Unsigned subtraction keeps this correct + * across tick wrap. */ + const trend_sample_t *newest = NULL; + const trend_sample_t *anchor = NULL; + uint32_t best_dist = UINT32_MAX; + + for (int i = 0; i < TREND_SLOTS; i++) { + const trend_sample_t *s = &trend_ring[channel][i]; + if (!s->used) { + continue; + } + + const uint32_t age = now_ms - s->ms; + if (age > HA_TREND_WINDOW_MS + HA_TREND_MIN_AGE_MS) { + continue; /* too old even for a sparse ring; ignore */ + } + + if (newest == NULL || age < (now_ms - newest->ms)) { + newest = s; + } + + if (age >= HA_TREND_MIN_AGE_MS) { + const uint32_t dist = (age > HA_TREND_WINDOW_MS) + ? age - HA_TREND_WINDOW_MS + : HA_TREND_WINDOW_MS - age; + if (dist < best_dist) { + best_dist = dist; + anchor = s; + } + } + } + + if (newest == NULL || anchor == NULL || newest == anchor) { + return HA_TREND_UNKNOWN; + } + + /* + * Scale the threshold to the actual span so a 20-minute-old anchor uses + * a proportionally smaller bar than a full hour would. Without this the + * first hour after boot under-reports every trend. + */ + const uint32_t span_ms = anchor->ms == newest->ms + ? 1 + : newest->ms - anchor->ms; + const float threshold = threshold_per_hour * + ((float)span_ms / (float)HA_TREND_WINDOW_MS); + + const float delta = newest->value - anchor->value; + if (delta > threshold) { + return HA_TREND_RISING; + } + if (delta < -threshold) { + return HA_TREND_FALLING; + } + return HA_TREND_FLAT; +} + const char *ha_wind_cardinal(float degrees) { static const char *const points[16] = { diff --git a/main/api/ha_data.h b/main/api/ha_data.h index 14678ab..8e90aa3 100644 --- a/main/api/ha_data.h +++ b/main/api/ha_data.h @@ -56,6 +56,27 @@ typedef struct { bool dimmable; } ha_light_cfg_t; +/* + * Which way a reading has moved over the last hour. + * + * UNKNOWN is deliberately 0 so a freshly wiped ha_data_t renders no arrow -- + * after boot there is no history, and "no arrow" is the honest display until + * at least HA_TREND_MIN_AGE_MS of samples exist. + */ +typedef enum { + HA_TREND_UNKNOWN = 0, + HA_TREND_FLAT, + HA_TREND_RISING, + HA_TREND_FALLING, +} ha_trend_t; + +enum { + HA_TREND_CH_INDOOR = 0, + HA_TREND_CH_OUTDOOR, + HA_TREND_CH_PRESSURE, + HA_TREND_CHANNELS, +}; + /* Generated from HA_LIGHT_LIST; index-aligned with ha_data_t.lights. */ extern const ha_light_cfg_t HA_LIGHTS[HA_LIGHT_COUNT]; @@ -93,6 +114,16 @@ typedef struct { ha_forecast_day_t forecast[HA_FORECAST_DAYS]; uint8_t forecast_count; /* 0 when no forecast has been fetched yet */ + + /* + * Filled by the CALLER after parsing, from ha_trend_feed/compute -- + * the parser wipes them to UNKNOWN. Local ring-buffer history, not an HA + * query: an /api/history call returns hundreds of points per entity, + * which is silly when the device already sees every reading each poll. + */ + ha_trend_t trend_indoor; + ha_trend_t trend_outdoor; + ha_trend_t trend_pressure; } ha_data_t; /* @@ -133,4 +164,19 @@ const char *ha_condition_short(const char *slug); /* Compass point for a bearing in degrees ("NNE"). */ const char *ha_wind_cardinal(float degrees); +/* + * Trend tracking. Feed one sample per poll; compute compares the newest + * sample against the one closest to an hour old. Timestamps come from the + * caller (lv_tick_get() or xTaskGetTickCount-derived ms) so this file stays + * free of LVGL and FreeRTOS. Wrap-safe on uint32 ms. + * + * compute returns UNKNOWN until the oldest usable sample is at least + * HA_TREND_MIN_AGE_MS old -- "trending" over 90 seconds is noise. + */ +#define HA_TREND_WINDOW_MS (60u * 60u * 1000u) +#define HA_TREND_MIN_AGE_MS (5u * 60u * 1000u) + +void ha_trend_feed(int channel, float value, uint32_t now_ms); +ha_trend_t ha_trend_compute(int channel, float threshold_per_hour, uint32_t now_ms); + #endif diff --git a/main/drivers/display/display_rgb.c b/main/drivers/display/display_rgb.c index e2605ec..da75590 100644 --- a/main/drivers/display/display_rgb.c +++ b/main/drivers/display/display_rgb.c @@ -108,14 +108,24 @@ static void rgb_flush_cb(lv_display_t *display, const lv_area_t *area, uint8_t * lv_display_flush_ready(display); } -esp_err_t display_init(void) +/* + * Phase 1: allocate everything, scan nothing. + * + * Called BEFORE wifi_init_sta(), on a heap nothing else has touched. The + * bounce buffers need two contiguous 25.6KB DMA-capable internal blocks, and + * WiFi's dynamic RX buffers churn that same pool hard enough to fragment it: + * observed on hardware (2026-08-04) as "no mem for bounce buffer" with 84KB + * of total free heap -- plenty of bytes, no block big enough, and retries + * useless because the fragmentation is not transient. + * + * Allocating first is deterministic where retrying was a dice roll. The + * panel is NOT scanning after this returns -- scan-out (and with it the + * PSRAM-reading refill ISR that flash writes would fault) starts only in + * display_start(). + */ +esp_err_t display_alloc(void) { - ESP_LOGI(TAG, "Initializing 800x480 RGB panel (CrowPanel Advance)"); - - /* lv_display_create() below allocates from LVGL's heap. Without lv_init() - * that heap is a null pool and the call faults with LoadProhibited. */ - ESP_RETURN_ON_FALSE(lv_is_initialized(), ESP_ERR_INVALID_STATE, TAG, - "lv_init() must run before display_init()"); + ESP_LOGI(TAG, "Allocating 800x480 RGB panel (CrowPanel Advance)"); const esp_lcd_rgb_panel_config_t panel_config = { .clk_src = LCD_CLK_SRC_DEFAULT, @@ -175,6 +185,29 @@ esp_err_t display_init(void) ESP_RETURN_ON_ERROR(esp_lcd_new_rgb_panel(&panel_config, &panel), TAG, "esp_lcd_new_rgb_panel failed"); + + ESP_LOGI(TAG, "Panel buffers allocated; free internal heap: %u KB", + (unsigned)(heap_caps_get_free_size(MALLOC_CAP_INTERNAL) / 1024)); + return ESP_OK; +} + +/* + * Phase 2: start scan-out and hand the framebuffers to LVGL. + * + * From esp_lcd_panel_init() onward the bounce-refill ISR is reading PSRAM + * continuously, so every flash write (NVS, WiFi PHY calibration) must already + * be done -- see the init-order comment in main.c. + */ +esp_err_t display_start(void) +{ + ESP_RETURN_ON_FALSE(panel != NULL, ESP_ERR_INVALID_STATE, TAG, + "display_alloc() must run before display_start()"); + + /* lv_display_create() below allocates from LVGL's heap. Without lv_init() + * that heap is a null pool and the call faults with LoadProhibited. */ + ESP_RETURN_ON_FALSE(lv_is_initialized(), ESP_ERR_INVALID_STATE, TAG, + "lv_init() must run before display_start()"); + ESP_RETURN_ON_ERROR(esp_lcd_panel_reset(panel), TAG, "panel reset failed"); ESP_RETURN_ON_ERROR(esp_lcd_panel_init(panel), TAG, "panel init failed"); diff --git a/main/drivers/display/display_rgb.h b/main/drivers/display/display_rgb.h index 0cd40a1..c904313 100644 --- a/main/drivers/display/display_rgb.h +++ b/main/drivers/display/display_rgb.h @@ -9,9 +9,22 @@ #define DISPLAY_H_RES 800 #define DISPLAY_V_RES 480 -/* Requires lv_init() to have already run -- call lvgl_port_init() first. - * Backlight is NOT owned here on the Advance; see drivers/backlight. */ -esp_err_t display_init(void); +/* + * Two-phase bring-up, and the order is load-bearing: + * + * display_alloc() -- BEFORE wifi_init_sta(). Grabs the framebuffers and + * the two contiguous bounce buffers while the internal + * heap is still unfragmented; WiFi's RX buffer churn + * destroys the needed contiguity within seconds. + * The panel is not scanning after this. + * display_start() -- AFTER WiFi (all flash writes done) and after + * lvgl_port_init(). Starts scan-out and registers the + * display with LVGL. + * + * Backlight is NOT owned here on the Advance; see drivers/backlight. + */ +esp_err_t display_alloc(void); +esp_err_t display_start(void); lv_display_t *display_get_default(void); diff --git a/main/main.c b/main/main.c index 943a7da..4401ce6 100644 --- a/main/main.c +++ b/main/main.c @@ -38,6 +38,14 @@ static const char *TAG = "main"; /* Consecutive failed polls before the displayed reading is treated as stale. */ #define STALE_AFTER_POLLS 2 +/* + * Trend arrow thresholds, per hour. Below these a reading renders as flat: + * a thermostat's indoor temp wobbles a couple of tenths continuously, and an + * arrow that flickers on noise is worse than none. + */ +#define TREND_TEMP_PER_HOUR_F 0.5f +#define TREND_PRESS_PER_HOUR_INHG 0.02f + /* Depth 8: a burst of taps while the network is slow should queue rather than * be dropped, but a user cannot meaningfully get more than a few ahead. */ #define CMD_QUEUE_DEPTH 8 @@ -190,6 +198,29 @@ static void ha_task(void *arg) consecutive_failures = 0; have_reading = true; + /* + * Trend history is local: the device sees every reading anyway, + * so an /api/history query would be hundreds of JSON points to + * answer a question one ring buffer answers for free. History is + * lost on reboot; arrows reappear ~5 minutes later. + */ + const uint32_t now_ms = xTaskGetTickCount() * portTICK_PERIOD_MS; + if (ha_data.indoor_temp_f.valid) { + ha_trend_feed(HA_TREND_CH_INDOOR, ha_data.indoor_temp_f.value, now_ms); + } + if (ha_data.outdoor_temp_f.valid) { + ha_trend_feed(HA_TREND_CH_OUTDOOR, ha_data.outdoor_temp_f.value, now_ms); + } + if (ha_data.pressure_inhg.valid) { + ha_trend_feed(HA_TREND_CH_PRESSURE, ha_data.pressure_inhg.value, now_ms); + } + ha_data.trend_indoor = + ha_trend_compute(HA_TREND_CH_INDOOR, TREND_TEMP_PER_HOUR_F, now_ms); + ha_data.trend_outdoor = + ha_trend_compute(HA_TREND_CH_OUTDOOR, TREND_TEMP_PER_HOUR_F, now_ms); + ha_data.trend_pressure = + ha_trend_compute(HA_TREND_CH_PRESSURE, TREND_PRESS_PER_HOUR_INHG, now_ms); + ui_update(&ha_data); ui_set_stale(false); @@ -227,14 +258,23 @@ void app_main(void) ESP_LOGI(TAG, "Thermostat HMI -- CrowPanel 7.0\" ESP32-S3 (800x480)"); /* - * WiFi comes up FIRST, before the RGB panel exists. + * Panel BUFFERS first, WiFi second, panel SCAN-OUT third. Both orderings + * are load-bearing: * - * The panel's bounce-buffer ISR reads the framebuffer out of PSRAM, and - * PSRAM shares the cache with flash on the ESP32-S3. Bringing up NVS and - * the WiFi PHY writes calibration data to flash, which disables the cache - * and faults that ISR. Doing it here means every flash write is finished - * before the panel starts scanning. + * - display_alloc() before WiFi: the bounce buffers need two contiguous + * 25.6KB internal DMA blocks, and WiFi's RX buffer churn fragments + * the internal heap within seconds of association. Allocating from + * the virgin heap is deterministic; observed otherwise as a + * boot-loop with 84KB free and no block big enough. + * + * - display_start() after WiFi: from the moment scan-out begins, the + * bounce-refill ISR reads PSRAM continuously, and PSRAM shares the + * cache with flash on the S3. NVS and WiFi PHY calibration write + * flash; doing all of that before the first scan means the ISR can + * never hit "Cache disabled but cached memory region accessed". */ + ESP_ERROR_CHECK(display_alloc()); + const esp_err_t wifi_err = wifi_init_sta(); if (wifi_err != ESP_OK) { ESP_LOGE(TAG, "WiFi not up yet -- polling starts when it connects"); @@ -254,7 +294,8 @@ void app_main(void) } i2c_bus_scan(TAG); - ESP_ERROR_CHECK(display_init()); + /* Buffers were allocated before WiFi; this only starts scan-out. */ + ESP_ERROR_CHECK(display_start()); if (touch_init() != ESP_OK) { /* A dead touch panel should not stop the display from working -- but diff --git a/main/ui/icon_font.c b/main/ui/icon_font.c index 45be838..f0aebd1 100644 --- a/main/ui/icon_font.c +++ b/main/ui/icon_font.c @@ -6,27 +6,27 @@ #include -const size_t icon_font_data_size = 5972; +const size_t icon_font_data_size = 6192; const unsigned char icon_font_data[] = { 0x00, 0x01, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x80, 0x00, 0x03, 0x00, 0x30, 0x47, 0x53, 0x55, 0x42, - 0xb8, 0xfa, 0xb8, 0xf4, 0x00, 0x00, 0x17, 0x28, 0x00, 0x00, 0x00, 0x2a, 0x4f, 0x53, 0x2f, 0x32, + 0xb8, 0xfa, 0xb8, 0xf4, 0x00, 0x00, 0x18, 0x04, 0x00, 0x00, 0x00, 0x2a, 0x4f, 0x53, 0x2f, 0x32, 0x4f, 0xb3, 0x5b, 0xd3, 0x00, 0x00, 0x01, 0x38, 0x00, 0x00, 0x00, 0x56, 0x63, 0x6d, 0x61, 0x70, - 0x01, 0xb4, 0x33, 0xcc, 0x00, 0x00, 0x01, 0xcc, 0x00, 0x00, 0x00, 0xcc, 0x67, 0x6c, 0x79, 0x66, - 0x07, 0x29, 0x77, 0x5e, 0x00, 0x00, 0x02, 0xd0, 0x00, 0x00, 0x13, 0x74, 0x68, 0x65, 0x61, 0x64, + 0x02, 0x0e, 0x52, 0xf7, 0x00, 0x00, 0x01, 0xd0, 0x00, 0x00, 0x00, 0xf0, 0x67, 0x6c, 0x79, 0x66, + 0x7b, 0x20, 0xfe, 0x3a, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x14, 0x20, 0x68, 0x65, 0x61, 0x64, 0x59, 0x6d, 0x7c, 0x00, 0x00, 0x00, 0x00, 0xbc, 0x00, 0x00, 0x00, 0x36, 0x68, 0x68, 0x65, 0x61, 0x03, 0xc6, 0x01, 0xbf, 0x00, 0x00, 0x00, 0xf4, 0x00, 0x00, 0x00, 0x24, 0x68, 0x6d, 0x74, 0x78, - 0x02, 0x00, 0xff, 0xff, 0x00, 0x00, 0x01, 0x90, 0x00, 0x00, 0x00, 0x3a, 0x6c, 0x6f, 0x63, 0x61, - 0x3f, 0xd5, 0x44, 0xe9, 0x00, 0x00, 0x02, 0x98, 0x00, 0x00, 0x00, 0x38, 0x6d, 0x61, 0x78, 0x70, - 0x01, 0x52, 0x01, 0x85, 0x00, 0x00, 0x01, 0x18, 0x00, 0x00, 0x00, 0x20, 0x6e, 0x61, 0x6d, 0x65, - 0x0b, 0xcc, 0x24, 0x14, 0x00, 0x00, 0x16, 0x44, 0x00, 0x00, 0x00, 0xc2, 0x70, 0x6f, 0x73, 0x74, - 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x17, 0x08, 0x00, 0x00, 0x00, 0x20, 0x00, 0x01, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x00, 0xe2, 0xcc, 0x9f, 0xb1, 0x5f, 0x0f, 0x3c, 0xf5, 0x00, 0x0b, 0x02, 0x00, + 0x01, 0xff, 0x00, 0x00, 0x00, 0x00, 0x01, 0x90, 0x00, 0x00, 0x00, 0x40, 0x6c, 0x6f, 0x63, 0x61, + 0x4a, 0x8f, 0x44, 0xe6, 0x00, 0x00, 0x02, 0xc0, 0x00, 0x00, 0x00, 0x3e, 0x6d, 0x61, 0x78, 0x70, + 0x01, 0x55, 0x01, 0x85, 0x00, 0x00, 0x01, 0x18, 0x00, 0x00, 0x00, 0x20, 0x6e, 0x61, 0x6d, 0x65, + 0x0b, 0xcc, 0x24, 0x14, 0x00, 0x00, 0x17, 0x20, 0x00, 0x00, 0x00, 0xc2, 0x70, 0x6f, 0x73, 0x74, + 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x17, 0xe4, 0x00, 0x00, 0x00, 0x20, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0xe4, 0xb3, 0x4f, 0xdb, 0x5f, 0x0f, 0x3c, 0xf5, 0x00, 0x0b, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x25, 0x9d, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x25, 0x9d, 0xc0, 0xff, 0xff, 0xff, 0xbe, 0x02, 0x04, 0x01, 0xc5, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0xc0, 0xff, 0xc0, 0x00, 0x00, 0x02, 0x00, 0xff, 0xff, 0xff, 0xfc, 0x02, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1b, 0x01, 0x79, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1e, 0x01, 0x79, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x01, 0x90, 0x00, 0x05, 0x00, 0x00, 0x01, 0x44, 0x01, 0x66, 0x00, 0x00, 0x00, 0x47, 0x01, 0x44, 0x01, 0x66, 0x00, 0x00, @@ -37,23 +37,26 @@ const unsigned char icon_font_data[] = { 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, - 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x03, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x14, - 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, - 0x00, 0x0f, 0x02, 0x9a, 0x00, 0x0f, 0x02, 0x9a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x0f, 0x05, 0x0f, - 0x00, 0x0f, 0x05, 0x0f, 0x00, 0x00, 0x00, 0x02, 0x00, 0x0f, 0x05, 0x90, 0x00, 0x0f, 0x05, 0x99, - 0x00, 0x00, 0x00, 0x03, 0x00, 0x0f, 0x05, 0x9b, 0x00, 0x0f, 0x05, 0x9d, 0x00, 0x00, 0x00, 0x0d, - 0x00, 0x0f, 0x05, 0xd6, 0x00, 0x0f, 0x05, 0xd6, 0x00, 0x00, 0x00, 0x10, 0x00, 0x0f, 0x06, 0x7e, - 0x00, 0x0f, 0x06, 0x7f, 0x00, 0x00, 0x00, 0x11, 0x00, 0x0f, 0x08, 0xdd, 0x00, 0x0f, 0x08, 0xdd, - 0x00, 0x00, 0x00, 0x13, 0x00, 0x0f, 0x09, 0x5f, 0x00, 0x0f, 0x09, 0x5f, 0x00, 0x00, 0x00, 0x14, - 0x00, 0x0f, 0x0a, 0x70, 0x00, 0x0f, 0x0a, 0x70, 0x00, 0x00, 0x00, 0x15, 0x00, 0x0f, 0x0e, 0x0a, - 0x00, 0x0f, 0x0e, 0x0a, 0x00, 0x00, 0x00, 0x16, 0x00, 0x0f, 0x0f, 0x55, 0x00, 0x0f, 0x0f, 0x55, - 0x00, 0x00, 0x00, 0x17, 0x00, 0x0f, 0x12, 0xba, 0x00, 0x0f, 0x12, 0xba, 0x00, 0x00, 0x00, 0x18, - 0x00, 0x0f, 0x15, 0x6d, 0x00, 0x0f, 0x15, 0x6d, 0x00, 0x00, 0x00, 0x19, 0x00, 0x0f, 0x17, 0x93, - 0x00, 0x0f, 0x17, 0x93, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7d, 0x00, 0xa5, - 0x00, 0xe3, 0x01, 0x58, 0x01, 0xc6, 0x02, 0x1b, 0x02, 0x78, 0x02, 0xfb, 0x03, 0x88, 0x03, 0xfd, - 0x04, 0x84, 0x04, 0xdd, 0x05, 0x38, 0x05, 0x92, 0x05, 0xf4, 0x06, 0x2e, 0x06, 0x96, 0x07, 0x30, - 0x07, 0x47, 0x07, 0x80, 0x07, 0xac, 0x07, 0xf1, 0x08, 0x29, 0x08, 0xe1, 0x09, 0x4d, 0x09, 0xba, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x03, 0x00, 0x0a, + 0x00, 0x00, 0x00, 0x14, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x11, 0x00, 0x0f, 0x02, 0x9a, 0x00, 0x0f, 0x02, 0x9a, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x0f, 0x05, 0x02, 0x00, 0x0f, 0x05, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x0f, 0x05, 0x0f, + 0x00, 0x0f, 0x05, 0x0f, 0x00, 0x00, 0x00, 0x03, 0x00, 0x0f, 0x05, 0x33, 0x00, 0x0f, 0x05, 0x33, + 0x00, 0x00, 0x00, 0x04, 0x00, 0x0f, 0x05, 0x35, 0x00, 0x0f, 0x05, 0x35, 0x00, 0x00, 0x00, 0x05, + 0x00, 0x0f, 0x05, 0x90, 0x00, 0x0f, 0x05, 0x99, 0x00, 0x00, 0x00, 0x06, 0x00, 0x0f, 0x05, 0x9b, + 0x00, 0x0f, 0x05, 0x9d, 0x00, 0x00, 0x00, 0x10, 0x00, 0x0f, 0x05, 0xd6, 0x00, 0x0f, 0x05, 0xd6, + 0x00, 0x00, 0x00, 0x13, 0x00, 0x0f, 0x06, 0x7e, 0x00, 0x0f, 0x06, 0x7f, 0x00, 0x00, 0x00, 0x14, + 0x00, 0x0f, 0x08, 0xdd, 0x00, 0x0f, 0x08, 0xdd, 0x00, 0x00, 0x00, 0x16, 0x00, 0x0f, 0x09, 0x5f, + 0x00, 0x0f, 0x09, 0x5f, 0x00, 0x00, 0x00, 0x17, 0x00, 0x0f, 0x0a, 0x70, 0x00, 0x0f, 0x0a, 0x70, + 0x00, 0x00, 0x00, 0x18, 0x00, 0x0f, 0x0e, 0x0a, 0x00, 0x0f, 0x0e, 0x0a, 0x00, 0x00, 0x00, 0x19, + 0x00, 0x0f, 0x0f, 0x55, 0x00, 0x0f, 0x0f, 0x55, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x0f, 0x12, 0xba, + 0x00, 0x0f, 0x12, 0xba, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x0f, 0x15, 0x6d, 0x00, 0x0f, 0x15, 0x6d, + 0x00, 0x00, 0x00, 0x1c, 0x00, 0x0f, 0x17, 0x93, 0x00, 0x0f, 0x17, 0x93, 0x00, 0x00, 0x00, 0x1d, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7d, 0x00, 0xa3, 0x00, 0xcb, 0x00, 0xe3, 0x00, 0xfb, 0x01, 0x39, + 0x01, 0xae, 0x02, 0x1c, 0x02, 0x71, 0x02, 0xce, 0x03, 0x51, 0x03, 0xde, 0x04, 0x53, 0x04, 0xda, + 0x05, 0x33, 0x05, 0x8e, 0x05, 0xe8, 0x06, 0x4a, 0x06, 0x84, 0x06, 0xec, 0x07, 0x86, 0x07, 0x9d, + 0x07, 0xd6, 0x08, 0x02, 0x08, 0x47, 0x08, 0x7f, 0x09, 0x37, 0x09, 0xa3, 0x0a, 0x10, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0xff, 0xea, 0x01, 0xd6, 0x01, 0x96, 0x00, 0x10, 0x00, 0x23, 0x00, 0x38, 0x00, 0x41, 0x00, 0x4a, 0x00, 0x53, 0x00, 0x00, 0x01, 0x22, 0x0e, 0x02, 0x14, 0x1e, 0x02, 0x32, 0x3e, 0x02, 0x34, 0x2e, 0x02, 0x07, 0x32, 0x1e, 0x01, 0x15, 0x14, 0x06, 0x07, 0x2e, 0x01, 0x23, @@ -69,318 +72,328 @@ const unsigned char icon_font_data[] = { 0x20, 0x2a, 0x2e, 0x4f, 0x2e, 0x26, 0x42, 0x18, 0x15, 0x16, 0x2b, 0x18, 0x42, 0x26, 0x2e, 0x4f, 0x2e, 0x29, 0x07, 0x07, 0x49, 0x02, 0x0f, 0x0a, 0x11, 0x20, 0x0d, 0x0e, 0x10, 0x0b, 0x16, 0x09, 0x4b, 0x08, 0x10, 0x04, 0x01, 0x02, 0x0c, 0x12, 0x0d, 0x0d, 0x12, 0x0c, 0x40, 0x0c, 0x12, 0x0d, - 0x0d, 0x12, 0x0c, 0x0c, 0x12, 0x0d, 0x0d, 0x12, 0x0c, 0x00, 0x00, 0x02, 0x00, 0x00, 0xff, 0xea, - 0x01, 0x71, 0x01, 0x96, 0x00, 0x0f, 0x00, 0x18, 0x00, 0x00, 0x25, 0x35, 0x34, 0x26, 0x22, 0x06, - 0x1d, 0x01, 0x0e, 0x01, 0x1e, 0x01, 0x32, 0x3e, 0x01, 0x26, 0x27, 0x32, 0x16, 0x1d, 0x01, 0x23, - 0x35, 0x34, 0x36, 0x01, 0x40, 0x25, 0x36, 0x25, 0x1c, 0x14, 0x16, 0x38, 0x44, 0x38, 0x16, 0x14, - 0x5c, 0x09, 0x0c, 0x2a, 0x0c, 0xab, 0xaa, 0x1b, 0x25, 0x25, 0x1b, 0xaa, 0x15, 0x42, 0x41, 0x28, - 0x28, 0x41, 0x42, 0xd5, 0x0d, 0x09, 0x40, 0x40, 0x09, 0x0d, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, - 0x01, 0xeb, 0x01, 0x56, 0x00, 0x14, 0x00, 0x2a, 0x00, 0x00, 0x37, 0x22, 0x2e, 0x01, 0x34, 0x3e, - 0x01, 0x33, 0x3e, 0x01, 0x33, 0x32, 0x1e, 0x01, 0x17, 0x33, 0x32, 0x16, 0x14, 0x06, 0x23, 0x35, - 0x23, 0x35, 0x34, 0x2e, 0x01, 0x23, 0x22, 0x06, 0x07, 0x26, 0x23, 0x22, 0x06, 0x14, 0x16, 0x33, - 0x21, 0x32, 0x36, 0x34, 0x26, 0x80, 0x1d, 0x31, 0x1d, 0x1d, 0x31, 0x1d, 0x10, 0x45, 0x2b, 0x24, - 0x3e, 0x26, 0x03, 0x0a, 0x24, 0x32, 0x32, 0x24, 0x2a, 0x1d, 0x31, 0x1d, 0x28, 0x3b, 0x06, 0x0c, - 0x0b, 0x1b, 0x25, 0x25, 0x1b, 0x01, 0x15, 0x12, 0x19, 0x19, 0x2b, 0x1c, 0x31, 0x3a, 0x31, 0x1d, - 0x26, 0x2f, 0x22, 0x3b, 0x23, 0x32, 0x46, 0x32, 0x80, 0x15, 0x1d, 0x31, 0x1d, 0x33, 0x27, 0x04, - 0x25, 0x35, 0x26, 0x19, 0x24, 0x19, 0x00, 0x05, 0x00, 0x00, 0xff, 0xff, 0x01, 0xeb, 0x01, 0x81, - 0x00, 0x0b, 0x00, 0x17, 0x00, 0x3c, 0x00, 0x48, 0x00, 0x54, 0x00, 0x00, 0x37, 0x33, 0x32, 0x16, - 0x14, 0x06, 0x2b, 0x01, 0x22, 0x26, 0x34, 0x36, 0x21, 0x33, 0x32, 0x16, 0x14, 0x06, 0x2b, 0x01, - 0x22, 0x26, 0x34, 0x36, 0x25, 0x34, 0x3e, 0x01, 0x33, 0x3e, 0x01, 0x33, 0x32, 0x1e, 0x01, 0x17, - 0x37, 0x32, 0x16, 0x17, 0x23, 0x34, 0x26, 0x2b, 0x01, 0x35, 0x34, 0x2e, 0x01, 0x23, 0x22, 0x06, - 0x07, 0x26, 0x23, 0x22, 0x06, 0x15, 0x14, 0x17, 0x23, 0x17, 0x33, 0x32, 0x16, 0x14, 0x06, 0x2b, - 0x01, 0x22, 0x26, 0x34, 0x36, 0x33, 0x21, 0x32, 0x16, 0x14, 0x06, 0x23, 0x21, 0x22, 0x26, 0x34, - 0x36, 0x40, 0xd5, 0x09, 0x0d, 0x0d, 0x09, 0xd5, 0x09, 0x0c, 0x0c, 0x01, 0x1e, 0x6b, 0x09, 0x0c, - 0x0c, 0x09, 0x6b, 0x09, 0x0c, 0x0c, 0xfe, 0xc9, 0x1d, 0x31, 0x1d, 0x10, 0x45, 0x2b, 0x24, 0x3e, - 0x26, 0x03, 0x0a, 0x23, 0x32, 0x01, 0x2b, 0x19, 0x12, 0x2a, 0x1d, 0x31, 0x1d, 0x28, 0x3b, 0x06, - 0x0c, 0x0b, 0x1b, 0x25, 0x04, 0x2d, 0x29, 0x2b, 0x09, 0x0c, 0x0c, 0x09, 0x2b, 0x09, 0x0c, 0x0c, - 0x74, 0x01, 0x15, 0x09, 0x0c, 0x0c, 0x09, 0xfe, 0xeb, 0x09, 0x0d, 0x0d, 0x80, 0x0c, 0x12, 0x0d, - 0x0d, 0x12, 0x0c, 0x0c, 0x12, 0x0d, 0x0d, 0x12, 0x0c, 0x40, 0x1d, 0x31, 0x1d, 0x26, 0x2f, 0x22, - 0x3b, 0x24, 0x01, 0x32, 0x23, 0x11, 0x19, 0x16, 0x1d, 0x31, 0x1c, 0x33, 0x26, 0x04, 0x25, 0x1b, - 0x0b, 0x0a, 0x80, 0x0d, 0x12, 0x0c, 0x0c, 0x12, 0x0d, 0x0d, 0x12, 0x0c, 0x0c, 0x12, 0x0d, 0x00, - 0x00, 0x04, 0x00, 0x00, 0xff, 0xea, 0x01, 0xeb, 0x01, 0x96, 0x00, 0x34, 0x00, 0x3d, 0x00, 0x46, - 0x00, 0x4f, 0x00, 0x00, 0x37, 0x32, 0x16, 0x14, 0x06, 0x23, 0x22, 0x2e, 0x01, 0x34, 0x3e, 0x01, - 0x33, 0x3e, 0x01, 0x33, 0x32, 0x1e, 0x01, 0x17, 0x33, 0x32, 0x16, 0x14, 0x06, 0x2b, 0x01, 0x22, - 0x26, 0x34, 0x36, 0x3b, 0x01, 0x32, 0x36, 0x34, 0x26, 0x2b, 0x01, 0x35, 0x34, 0x2e, 0x01, 0x23, - 0x22, 0x06, 0x07, 0x26, 0x23, 0x22, 0x06, 0x14, 0x16, 0x17, 0x32, 0x16, 0x14, 0x06, 0x22, 0x26, - 0x34, 0x36, 0x37, 0x32, 0x16, 0x14, 0x06, 0x22, 0x26, 0x34, 0x36, 0x27, 0x32, 0x16, 0x14, 0x06, - 0x22, 0x26, 0x34, 0x36, 0x80, 0x09, 0x0c, 0x0c, 0x09, 0x1d, 0x31, 0x1d, 0x1d, 0x31, 0x1d, 0x10, - 0x45, 0x2b, 0x24, 0x3e, 0x26, 0x03, 0x0a, 0x24, 0x32, 0x32, 0x24, 0x15, 0x09, 0x0c, 0x0c, 0x09, - 0x15, 0x12, 0x19, 0x19, 0x12, 0x2a, 0x1d, 0x31, 0x1d, 0x28, 0x3b, 0x06, 0x0c, 0x0b, 0x1b, 0x25, - 0x25, 0x70, 0x12, 0x19, 0x19, 0x23, 0x19, 0x19, 0x71, 0x0e, 0x12, 0x12, 0x1b, 0x13, 0x13, 0x48, - 0x0d, 0x13, 0x13, 0x1a, 0x13, 0x13, 0x95, 0x0c, 0x12, 0x0c, 0x1c, 0x31, 0x3a, 0x31, 0x1d, 0x26, - 0x2f, 0x22, 0x3b, 0x23, 0x32, 0x46, 0x32, 0x0c, 0x12, 0x0c, 0x19, 0x24, 0x19, 0x15, 0x1d, 0x31, - 0x1d, 0x33, 0x27, 0x04, 0x25, 0x35, 0x26, 0x55, 0x19, 0x23, 0x19, 0x19, 0x23, 0x19, 0x2b, 0x13, - 0x1b, 0x12, 0x12, 0x1b, 0x13, 0x55, 0x13, 0x1a, 0x13, 0x13, 0x1a, 0x13, 0x00, 0x02, 0x00, 0x00, - 0xff, 0xea, 0x01, 0xeb, 0x01, 0x96, 0x00, 0x36, 0x00, 0x3d, 0x00, 0x00, 0x37, 0x22, 0x2e, 0x01, - 0x34, 0x3e, 0x01, 0x33, 0x3e, 0x01, 0x33, 0x32, 0x1e, 0x01, 0x17, 0x33, 0x32, 0x16, 0x14, 0x06, - 0x2b, 0x01, 0x22, 0x26, 0x34, 0x36, 0x3b, 0x01, 0x32, 0x36, 0x34, 0x26, 0x2b, 0x01, 0x35, 0x34, - 0x2e, 0x01, 0x23, 0x22, 0x06, 0x07, 0x26, 0x23, 0x22, 0x06, 0x14, 0x16, 0x3b, 0x01, 0x32, 0x16, - 0x14, 0x06, 0x23, 0x37, 0x33, 0x07, 0x33, 0x07, 0x37, 0x23, 0x80, 0x1d, 0x31, 0x1d, 0x1d, 0x31, - 0x1d, 0x10, 0x45, 0x2b, 0x24, 0x3e, 0x26, 0x03, 0x0a, 0x24, 0x32, 0x32, 0x24, 0x15, 0x09, 0x0c, - 0x0c, 0x09, 0x15, 0x12, 0x19, 0x19, 0x12, 0x2a, 0x1d, 0x31, 0x1d, 0x28, 0x3b, 0x06, 0x0c, 0x0b, - 0x1b, 0x25, 0x25, 0x1b, 0x15, 0x09, 0x0d, 0x0d, 0x09, 0x6b, 0x40, 0x2b, 0x2b, 0x50, 0x10, 0x35, - 0x6b, 0x1c, 0x31, 0x3a, 0x31, 0x1d, 0x26, 0x2f, 0x22, 0x3b, 0x23, 0x32, 0x46, 0x32, 0x0c, 0x12, - 0x0c, 0x19, 0x24, 0x19, 0x15, 0x1d, 0x31, 0x1d, 0x33, 0x27, 0x04, 0x25, 0x35, 0x26, 0x0c, 0x12, - 0x0c, 0x6a, 0x55, 0x95, 0x6a, 0x00, 0x00, 0x04, 0x00, 0x00, 0xff, 0xe3, 0x01, 0xc6, 0x01, 0xab, - 0x00, 0x09, 0x00, 0x13, 0x00, 0x2b, 0x00, 0x37, 0x00, 0x00, 0x01, 0x07, 0x17, 0x27, 0x07, 0x37, - 0x27, 0x3f, 0x01, 0x1f, 0x01, 0x07, 0x17, 0x27, 0x07, 0x37, 0x27, 0x3f, 0x01, 0x17, 0x07, 0x36, - 0x1e, 0x01, 0x07, 0x06, 0x07, 0x0e, 0x01, 0x2e, 0x02, 0x36, 0x37, 0x36, 0x37, 0x36, 0x1e, 0x01, - 0x07, 0x06, 0x1e, 0x02, 0x17, 0x2e, 0x03, 0x27, 0x0e, 0x01, 0x1e, 0x02, 0x36, 0x01, 0x7b, 0x36, - 0x13, 0x38, 0x38, 0x13, 0x36, 0x44, 0x17, 0x17, 0x8e, 0x23, 0x0d, 0x24, 0x25, 0x0d, 0x23, 0x2c, - 0x0f, 0x0e, 0x04, 0x08, 0x11, 0x05, 0x05, 0x0b, 0x0c, 0x29, 0x6e, 0x6e, 0x52, 0x1c, 0x1c, 0x29, - 0x0d, 0x0e, 0x08, 0x14, 0x0d, 0x01, 0x04, 0x1f, 0x45, 0x5a, 0x0c, 0x2e, 0x57, 0x44, 0x26, 0x02, - 0x1e, 0x13, 0x18, 0x3f, 0x54, 0x56, 0x01, 0x69, 0x2a, 0x41, 0x27, 0x27, 0x41, 0x2a, 0x02, 0x40, - 0x40, 0x96, 0x1a, 0x2b, 0x19, 0x19, 0x2b, 0x1a, 0x01, 0x2a, 0x2a, 0x6a, 0x01, 0x0e, 0x13, 0x08, - 0x10, 0x0b, 0x29, 0x1d, 0x1d, 0x52, 0x6e, 0x6e, 0x29, 0x0d, 0x0a, 0x05, 0x06, 0x10, 0x09, 0x2e, - 0x5a, 0x45, 0x20, 0x26, 0x02, 0x26, 0x44, 0x56, 0x2e, 0x21, 0x55, 0x54, 0x3f, 0x18, 0x13, 0x00, - 0x00, 0x07, 0x00, 0x00, 0xff, 0xea, 0x01, 0xd6, 0x01, 0x9a, 0x00, 0x1b, 0x00, 0x29, 0x00, 0x2f, - 0x00, 0x35, 0x00, 0x3b, 0x00, 0x41, 0x00, 0x54, 0x00, 0x00, 0x01, 0x1e, 0x01, 0x07, 0x1e, 0x01, - 0x1d, 0x01, 0x36, 0x33, 0x32, 0x16, 0x14, 0x06, 0x23, 0x21, 0x22, 0x26, 0x34, 0x36, 0x3b, 0x01, - 0x2e, 0x01, 0x37, 0x3e, 0x02, 0x17, 0x26, 0x06, 0x07, 0x06, 0x16, 0x17, 0x3e, 0x01, 0x33, 0x32, - 0x17, 0x2e, 0x01, 0x37, 0x26, 0x27, 0x37, 0x17, 0x26, 0x07, 0x06, 0x07, 0x37, 0x17, 0x06, 0x17, - 0x26, 0x27, 0x17, 0x07, 0x36, 0x05, 0x16, 0x17, 0x27, 0x37, 0x06, 0x05, 0x23, 0x35, 0x34, 0x26, - 0x22, 0x06, 0x15, 0x23, 0x22, 0x06, 0x14, 0x16, 0x33, 0x21, 0x32, 0x36, 0x34, 0x26, 0x01, 0x10, - 0x25, 0x26, 0x07, 0x14, 0x18, 0x0a, 0x0b, 0x1b, 0x25, 0x25, 0x1b, 0xfe, 0xeb, 0x23, 0x32, 0x32, - 0x23, 0x06, 0x15, 0x0a, 0x0e, 0x0d, 0x33, 0x3e, 0x0c, 0x1d, 0x3a, 0x0c, 0x07, 0x01, 0x08, 0x12, - 0x33, 0x1d, 0x16, 0x15, 0x01, 0x18, 0x0f, 0x11, 0x13, 0x36, 0x13, 0x11, 0xb3, 0x10, 0x0c, 0x03, - 0x3f, 0x14, 0xec, 0x03, 0x06, 0x33, 0x2c, 0x04, 0xfe, 0xbf, 0x02, 0x06, 0x32, 0x2b, 0x03, 0x01, - 0x56, 0x40, 0x32, 0x46, 0x32, 0x2b, 0x12, 0x19, 0x19, 0x12, 0x01, 0x15, 0x09, 0x0d, 0x0d, 0x01, - 0x4b, 0x10, 0x48, 0x27, 0x12, 0x33, 0x1c, 0x04, 0x04, 0x26, 0x35, 0x25, 0x32, 0x46, 0x32, 0x1a, - 0x42, 0x1f, 0x1d, 0x24, 0x07, 0x34, 0x0d, 0x16, 0x1c, 0x10, 0x23, 0x0f, 0x15, 0x19, 0x08, 0x15, - 0x23, 0x57, 0x08, 0x03, 0x1c, 0x3d, 0x0d, 0x08, 0x0b, 0x0e, 0x3c, 0x0f, 0x06, 0x7e, 0x14, 0x10, - 0x20, 0x2f, 0x14, 0x0b, 0x13, 0x11, 0x20, 0x2f, 0x16, 0xa4, 0x2b, 0x23, 0x32, 0x32, 0x23, 0x19, - 0x24, 0x19, 0x0d, 0x12, 0x0c, 0x00, 0x00, 0x04, 0x00, 0x00, 0xff, 0xef, 0x01, 0xeb, 0x01, 0x96, - 0x00, 0x0c, 0x00, 0x19, 0x00, 0x26, 0x00, 0x5f, 0x00, 0x00, 0x37, 0x1e, 0x01, 0x0f, 0x01, 0x0e, - 0x01, 0x2e, 0x01, 0x3f, 0x01, 0x3e, 0x01, 0x17, 0x1e, 0x01, 0x0f, 0x01, 0x0e, 0x01, 0x2e, 0x01, - 0x3f, 0x01, 0x3e, 0x01, 0x17, 0x1e, 0x01, 0x0f, 0x01, 0x0e, 0x01, 0x2e, 0x01, 0x3f, 0x01, 0x3e, - 0x01, 0x37, 0x35, 0x34, 0x2e, 0x01, 0x23, 0x22, 0x06, 0x07, 0x26, 0x23, 0x22, 0x06, 0x15, 0x14, - 0x16, 0x17, 0x31, 0x1e, 0x01, 0x0e, 0x01, 0x27, 0x31, 0x2e, 0x01, 0x34, 0x3e, 0x01, 0x33, 0x3e, - 0x01, 0x33, 0x32, 0x1e, 0x01, 0x17, 0x33, 0x32, 0x16, 0x15, 0x14, 0x06, 0x07, 0x31, 0x06, 0x2e, - 0x01, 0x36, 0x37, 0x31, 0x3e, 0x01, 0x35, 0x34, 0x26, 0x23, 0xc0, 0x08, 0x09, 0x02, 0x1c, 0x02, - 0x0f, 0x11, 0x09, 0x03, 0x1b, 0x02, 0x0f, 0x5e, 0x09, 0x09, 0x03, 0x2c, 0x02, 0x0f, 0x11, 0x09, - 0x02, 0x2c, 0x03, 0x0f, 0x5e, 0x08, 0x09, 0x02, 0x1c, 0x02, 0x0f, 0x12, 0x08, 0x02, 0x1c, 0x02, - 0x0f, 0x09, 0x1d, 0x31, 0x1d, 0x28, 0x3b, 0x06, 0x0c, 0x0b, 0x1b, 0x25, 0x11, 0x0f, 0x08, 0x04, - 0x09, 0x10, 0x08, 0x19, 0x1d, 0x1d, 0x31, 0x1d, 0x10, 0x45, 0x2b, 0x24, 0x3e, 0x26, 0x03, 0x0a, - 0x24, 0x32, 0x17, 0x14, 0x08, 0x11, 0x09, 0x05, 0x08, 0x09, 0x0c, 0x19, 0x12, 0xc0, 0x02, 0x10, - 0x08, 0x67, 0x09, 0x08, 0x04, 0x0f, 0x09, 0x67, 0x08, 0x09, 0x02, 0x02, 0x10, 0x08, 0xa5, 0x09, - 0x08, 0x04, 0x10, 0x08, 0xa5, 0x08, 0x09, 0x02, 0x02, 0x10, 0x08, 0x67, 0x09, 0x08, 0x04, 0x0f, - 0x09, 0x67, 0x08, 0x09, 0x29, 0x15, 0x1d, 0x31, 0x1d, 0x33, 0x27, 0x04, 0x25, 0x1b, 0x11, 0x1e, - 0x08, 0x04, 0x12, 0x0f, 0x04, 0x04, 0x0e, 0x31, 0x3a, 0x31, 0x1d, 0x26, 0x2f, 0x22, 0x3b, 0x23, - 0x32, 0x23, 0x18, 0x27, 0x0b, 0x04, 0x04, 0x10, 0x11, 0x04, 0x06, 0x13, 0x0c, 0x12, 0x19, 0x00, - 0x00, 0x03, 0x00, 0x00, 0xff, 0xea, 0x01, 0xeb, 0x01, 0x95, 0x00, 0x34, 0x00, 0x40, 0x00, 0x54, - 0x00, 0x00, 0x37, 0x32, 0x16, 0x14, 0x06, 0x23, 0x22, 0x2e, 0x01, 0x34, 0x3e, 0x01, 0x33, 0x3e, - 0x01, 0x33, 0x32, 0x1e, 0x01, 0x17, 0x37, 0x32, 0x16, 0x14, 0x06, 0x2b, 0x01, 0x22, 0x26, 0x34, - 0x36, 0x3b, 0x01, 0x32, 0x36, 0x34, 0x26, 0x2b, 0x01, 0x35, 0x34, 0x2e, 0x01, 0x23, 0x22, 0x06, - 0x07, 0x26, 0x23, 0x22, 0x06, 0x14, 0x16, 0x17, 0x16, 0x17, 0x16, 0x15, 0x14, 0x06, 0x22, 0x26, - 0x35, 0x34, 0x3f, 0x01, 0x0f, 0x01, 0x06, 0x07, 0x06, 0x07, 0x06, 0x15, 0x14, 0x16, 0x32, 0x36, - 0x35, 0x34, 0x27, 0x2e, 0x01, 0x27, 0x31, 0x80, 0x09, 0x0c, 0x0c, 0x09, 0x1d, 0x31, 0x1d, 0x1d, - 0x31, 0x1d, 0x10, 0x45, 0x2b, 0x24, 0x3e, 0x26, 0x03, 0x0a, 0x24, 0x32, 0x32, 0x24, 0x15, 0x09, - 0x0c, 0x0c, 0x09, 0x15, 0x12, 0x19, 0x19, 0x12, 0x2a, 0x1d, 0x31, 0x1d, 0x28, 0x3b, 0x06, 0x0b, - 0x0c, 0x1b, 0x25, 0x25, 0x9b, 0x05, 0x07, 0x1f, 0x19, 0x24, 0x19, 0x1f, 0x0c, 0x0b, 0x0b, 0x0e, - 0x0b, 0x12, 0x08, 0x0c, 0x32, 0x46, 0x32, 0x0c, 0x08, 0x24, 0x12, 0x95, 0x0d, 0x11, 0x0d, 0x1d, - 0x31, 0x3a, 0x31, 0x1c, 0x27, 0x2f, 0x23, 0x3a, 0x24, 0x01, 0x32, 0x47, 0x32, 0x0d, 0x11, 0x0d, - 0x19, 0x23, 0x19, 0x15, 0x1d, 0x31, 0x1d, 0x33, 0x26, 0x04, 0x26, 0x35, 0x25, 0x03, 0x07, 0x0a, - 0x2b, 0x16, 0x12, 0x19, 0x19, 0x12, 0x16, 0x2b, 0x54, 0x0c, 0x0e, 0x11, 0x11, 0x19, 0x12, 0x19, - 0x15, 0x23, 0x32, 0x32, 0x23, 0x15, 0x19, 0x12, 0x34, 0x15, 0x00, 0x02, 0x00, 0x00, 0xff, 0xd6, - 0x01, 0xeb, 0x01, 0x96, 0x00, 0x34, 0x00, 0x5e, 0x00, 0x00, 0x37, 0x32, 0x16, 0x14, 0x06, 0x23, - 0x22, 0x2e, 0x01, 0x34, 0x3e, 0x01, 0x33, 0x3e, 0x01, 0x33, 0x32, 0x1e, 0x01, 0x17, 0x33, 0x32, - 0x16, 0x14, 0x06, 0x2b, 0x01, 0x22, 0x26, 0x34, 0x36, 0x3b, 0x01, 0x32, 0x36, 0x34, 0x26, 0x2b, - 0x01, 0x35, 0x34, 0x2e, 0x01, 0x23, 0x22, 0x06, 0x07, 0x26, 0x23, 0x22, 0x06, 0x14, 0x16, 0x17, - 0x37, 0x27, 0x26, 0x34, 0x36, 0x32, 0x1f, 0x01, 0x37, 0x3e, 0x01, 0x1e, 0x01, 0x0f, 0x01, 0x37, - 0x36, 0x1e, 0x01, 0x06, 0x0f, 0x01, 0x17, 0x16, 0x14, 0x06, 0x22, 0x2f, 0x01, 0x07, 0x0e, 0x01, - 0x2e, 0x01, 0x3f, 0x01, 0x07, 0x06, 0x2e, 0x01, 0x36, 0x80, 0x09, 0x0c, 0x0c, 0x09, 0x1d, 0x31, - 0x1d, 0x1d, 0x31, 0x1d, 0x10, 0x45, 0x2b, 0x24, 0x3e, 0x26, 0x03, 0x0a, 0x24, 0x32, 0x32, 0x24, - 0x15, 0x09, 0x0c, 0x0c, 0x09, 0x15, 0x12, 0x19, 0x19, 0x12, 0x2a, 0x1d, 0x31, 0x1d, 0x28, 0x3b, - 0x06, 0x0c, 0x0b, 0x1b, 0x25, 0x25, 0x43, 0x2f, 0x23, 0x06, 0x0d, 0x12, 0x06, 0x22, 0x0c, 0x03, - 0x0f, 0x11, 0x09, 0x02, 0x0d, 0x2f, 0x08, 0x10, 0x04, 0x09, 0x08, 0x2f, 0x23, 0x06, 0x0d, 0x12, - 0x06, 0x22, 0x0c, 0x03, 0x0f, 0x11, 0x09, 0x02, 0x0d, 0x2f, 0x08, 0x10, 0x04, 0x09, 0x95, 0x0c, - 0x12, 0x0c, 0x1c, 0x31, 0x3a, 0x31, 0x1d, 0x26, 0x2f, 0x22, 0x3b, 0x23, 0x32, 0x46, 0x32, 0x0c, - 0x12, 0x0c, 0x19, 0x24, 0x19, 0x15, 0x1d, 0x31, 0x1d, 0x33, 0x27, 0x04, 0x25, 0x35, 0x26, 0x56, - 0x0c, 0x22, 0x06, 0x12, 0x0d, 0x06, 0x23, 0x2f, 0x08, 0x09, 0x04, 0x10, 0x08, 0x2f, 0x0d, 0x02, - 0x09, 0x11, 0x0f, 0x03, 0x0c, 0x22, 0x06, 0x12, 0x0d, 0x06, 0x23, 0x2f, 0x08, 0x09, 0x04, 0x10, - 0x08, 0x2f, 0x0d, 0x02, 0x09, 0x11, 0x0f, 0x00, 0x00, 0x08, 0x00, 0x00, 0xff, 0xea, 0x01, 0xb9, - 0x01, 0x96, 0x00, 0x0c, 0x00, 0x15, 0x00, 0x1a, 0x00, 0x1f, 0x00, 0x24, 0x00, 0x29, 0x00, 0x2e, - 0x00, 0x33, 0x00, 0x00, 0x01, 0x32, 0x1e, 0x01, 0x14, 0x0e, 0x01, 0x22, 0x2e, 0x01, 0x34, 0x3e, - 0x01, 0x17, 0x22, 0x06, 0x14, 0x16, 0x32, 0x36, 0x34, 0x26, 0x27, 0x17, 0x26, 0x22, 0x0f, 0x01, - 0x37, 0x0e, 0x01, 0x0f, 0x01, 0x37, 0x1e, 0x01, 0x17, 0x25, 0x07, 0x2e, 0x01, 0x27, 0x17, 0x07, - 0x3e, 0x01, 0x37, 0x07, 0x27, 0x16, 0x32, 0x37, 0x01, 0x00, 0x1d, 0x31, 0x1d, 0x1d, 0x31, 0x3a, - 0x31, 0x1d, 0x1d, 0x31, 0x1d, 0x1b, 0x25, 0x25, 0x36, 0x25, 0x25, 0x1b, 0x33, 0x19, 0x34, 0x19, - 0x86, 0x59, 0x14, 0x1a, 0x05, 0x25, 0x25, 0x05, 0x1a, 0x14, 0x01, 0x19, 0x26, 0x05, 0x1a, 0x14, - 0x58, 0x58, 0x14, 0x1a, 0x05, 0x93, 0x33, 0x19, 0x33, 0x1a, 0x01, 0x2b, 0x1d, 0x31, 0x3a, 0x31, - 0x1d, 0x1d, 0x31, 0x3a, 0x31, 0x1d, 0x2b, 0x25, 0x36, 0x25, 0x25, 0x36, 0x25, 0x95, 0x49, 0x09, - 0x09, 0x21, 0x07, 0x11, 0x2c, 0x1b, 0x85, 0x51, 0x1a, 0x2d, 0x12, 0xde, 0x51, 0x1a, 0x2e, 0x10, - 0xdd, 0x07, 0x11, 0x2d, 0x1a, 0xbb, 0x49, 0x09, 0x09, 0x00, 0x00, 0x06, 0x00, 0x00, 0xff, 0xff, - 0x01, 0xd6, 0x01, 0x96, 0x00, 0x13, 0x00, 0x19, 0x00, 0x1e, 0x00, 0x23, 0x00, 0x28, 0x00, 0x39, - 0x00, 0x00, 0x37, 0x33, 0x34, 0x3e, 0x01, 0x32, 0x1e, 0x01, 0x15, 0x33, 0x32, 0x16, 0x14, 0x06, - 0x23, 0x21, 0x22, 0x26, 0x34, 0x36, 0x21, 0x34, 0x26, 0x22, 0x06, 0x15, 0x37, 0x17, 0x26, 0x22, - 0x0f, 0x01, 0x37, 0x0e, 0x01, 0x07, 0x25, 0x07, 0x2e, 0x01, 0x27, 0x03, 0x37, 0x36, 0x34, 0x26, - 0x22, 0x0f, 0x01, 0x27, 0x26, 0x22, 0x06, 0x14, 0x1f, 0x01, 0x16, 0x32, 0x40, 0x55, 0x1d, 0x31, - 0x3a, 0x31, 0x1d, 0x55, 0x09, 0x0c, 0x0c, 0x09, 0xfe, 0x80, 0x09, 0x0c, 0x0c, 0x01, 0x09, 0x25, - 0x36, 0x25, 0x40, 0x33, 0x19, 0x34, 0x19, 0x86, 0x59, 0x14, 0x1a, 0x05, 0x01, 0x4c, 0x26, 0x05, - 0x1a, 0x14, 0x51, 0x42, 0x07, 0x0d, 0x11, 0x07, 0x33, 0x33, 0x07, 0x11, 0x0d, 0x07, 0x42, 0x07, - 0x10, 0xc0, 0x1d, 0x31, 0x1d, 0x1d, 0x31, 0x1d, 0x0c, 0x12, 0x0d, 0x0d, 0x12, 0x0c, 0x1b, 0x25, - 0x25, 0x1b, 0xd5, 0x49, 0x09, 0x09, 0x21, 0x07, 0x11, 0x2c, 0x1b, 0x51, 0x51, 0x1a, 0x2e, 0x10, - 0xfe, 0xd4, 0x43, 0x06, 0x12, 0x0c, 0x06, 0x34, 0x34, 0x06, 0x0c, 0x12, 0x06, 0x43, 0x06, 0x00, - 0x00, 0x06, 0x00, 0x00, 0xff, 0xfd, 0x01, 0xd6, 0x01, 0x96, 0x00, 0x13, 0x00, 0x19, 0x00, 0x1e, - 0x00, 0x23, 0x00, 0x28, 0x00, 0x39, 0x00, 0x00, 0x37, 0x33, 0x34, 0x3e, 0x01, 0x32, 0x1e, 0x01, - 0x15, 0x33, 0x32, 0x16, 0x14, 0x06, 0x23, 0x21, 0x22, 0x26, 0x34, 0x36, 0x21, 0x34, 0x26, 0x22, - 0x06, 0x15, 0x37, 0x17, 0x26, 0x22, 0x0f, 0x01, 0x37, 0x0e, 0x01, 0x07, 0x25, 0x07, 0x2e, 0x01, - 0x27, 0x07, 0x17, 0x16, 0x14, 0x06, 0x22, 0x2f, 0x01, 0x07, 0x06, 0x22, 0x26, 0x34, 0x3f, 0x01, - 0x36, 0x32, 0x40, 0x55, 0x1d, 0x31, 0x3a, 0x31, 0x1d, 0x55, 0x09, 0x0c, 0x0c, 0x09, 0xfe, 0x80, - 0x09, 0x0c, 0x0c, 0x01, 0x09, 0x25, 0x36, 0x25, 0x40, 0x33, 0x19, 0x34, 0x19, 0x86, 0x59, 0x14, - 0x1a, 0x05, 0x01, 0x4c, 0x26, 0x05, 0x1a, 0x14, 0x51, 0x42, 0x07, 0x0d, 0x11, 0x07, 0x33, 0x33, - 0x07, 0x11, 0x0d, 0x07, 0x42, 0x07, 0x10, 0xc0, 0x1d, 0x31, 0x1d, 0x1d, 0x31, 0x1d, 0x0c, 0x12, - 0x0d, 0x0d, 0x12, 0x0c, 0x1b, 0x25, 0x25, 0x1b, 0xd5, 0x49, 0x09, 0x09, 0x21, 0x07, 0x11, 0x2c, - 0x1b, 0x51, 0x51, 0x1a, 0x2e, 0x10, 0xce, 0x42, 0x06, 0x12, 0x0c, 0x06, 0x33, 0x33, 0x06, 0x0c, - 0x12, 0x06, 0x42, 0x07, 0x00, 0x03, 0x00, 0x00, 0xff, 0xea, 0x01, 0xd6, 0x01, 0x96, 0x00, 0x17, - 0x00, 0x2e, 0x00, 0x45, 0x00, 0x00, 0x37, 0x22, 0x26, 0x34, 0x36, 0x3b, 0x01, 0x32, 0x36, 0x34, - 0x26, 0x22, 0x07, 0x06, 0x22, 0x26, 0x34, 0x37, 0x36, 0x32, 0x16, 0x14, 0x06, 0x23, 0x17, 0x32, - 0x36, 0x34, 0x26, 0x22, 0x06, 0x22, 0x26, 0x34, 0x37, 0x36, 0x32, 0x16, 0x14, 0x06, 0x23, 0x21, - 0x22, 0x26, 0x34, 0x36, 0x33, 0x05, 0x21, 0x22, 0x26, 0x34, 0x36, 0x33, 0x21, 0x32, 0x16, 0x14, - 0x06, 0x22, 0x27, 0x26, 0x34, 0x36, 0x32, 0x16, 0x32, 0x36, 0x34, 0x26, 0x55, 0x09, 0x0c, 0x0c, - 0x09, 0xab, 0x12, 0x19, 0x19, 0x24, 0x0c, 0x06, 0x12, 0x0d, 0x07, 0x19, 0x46, 0x32, 0x32, 0x23, - 0x95, 0x09, 0x0d, 0x0d, 0x12, 0x0c, 0x12, 0x0c, 0x06, 0x13, 0x35, 0x25, 0x25, 0x1b, 0xfe, 0xd6, - 0x09, 0x0d, 0x0d, 0x09, 0x01, 0x15, 0xfe, 0xd5, 0x09, 0x0c, 0x0c, 0x09, 0x01, 0x2b, 0x1b, 0x25, - 0x25, 0x35, 0x13, 0x06, 0x0c, 0x12, 0x0c, 0x12, 0x0c, 0x0c, 0xeb, 0x0c, 0x12, 0x0c, 0x19, 0x24, - 0x19, 0x0d, 0x06, 0x0c, 0x12, 0x06, 0x19, 0x32, 0x46, 0x32, 0x2b, 0x0c, 0x12, 0x0d, 0x0d, 0x0d, - 0x11, 0x07, 0x12, 0x25, 0x35, 0x26, 0x0d, 0x12, 0x0c, 0x80, 0x0c, 0x12, 0x0d, 0x26, 0x35, 0x25, - 0x12, 0x07, 0x11, 0x0d, 0x0d, 0x0d, 0x12, 0x0c, 0x00, 0x04, 0x00, 0x00, 0xff, 0xea, 0x01, 0xd6, - 0x01, 0x96, 0x00, 0x03, 0x00, 0x07, 0x00, 0x18, 0x00, 0x25, 0x00, 0x00, 0x37, 0x33, 0x15, 0x23, - 0x35, 0x33, 0x15, 0x23, 0x37, 0x22, 0x0e, 0x01, 0x15, 0x14, 0x1e, 0x02, 0x32, 0x3e, 0x02, 0x34, - 0x2e, 0x02, 0x03, 0x22, 0x2e, 0x01, 0x34, 0x3e, 0x01, 0x32, 0x1e, 0x01, 0x14, 0x0e, 0x01, 0xeb, - 0x2a, 0x2a, 0x2a, 0x2a, 0x15, 0x3a, 0x62, 0x39, 0x20, 0x3c, 0x4f, 0x54, 0x4f, 0x3c, 0x20, 0x20, - 0x3c, 0x4f, 0x2a, 0x2e, 0x4f, 0x2e, 0x2e, 0x4f, 0x5c, 0x4f, 0x2e, 0x2e, 0x4f, 0x80, 0x2b, 0xd6, - 0x80, 0xea, 0x39, 0x62, 0x3a, 0x2a, 0x4f, 0x3c, 0x20, 0x20, 0x3c, 0x4f, 0x54, 0x4f, 0x3c, 0x20, - 0xfe, 0x80, 0x2e, 0x4f, 0x5c, 0x4f, 0x2e, 0x2e, 0x4f, 0x5c, 0x4f, 0x2e, 0x00, 0x03, 0x00, 0x00, - 0xff, 0xea, 0x01, 0xeb, 0x01, 0x96, 0x00, 0x34, 0x00, 0x3b, 0x00, 0x49, 0x00, 0x00, 0x37, 0x1e, - 0x01, 0x0e, 0x01, 0x27, 0x31, 0x2e, 0x01, 0x34, 0x3e, 0x01, 0x33, 0x3e, 0x01, 0x33, 0x32, 0x1e, - 0x01, 0x17, 0x33, 0x32, 0x16, 0x14, 0x06, 0x23, 0x22, 0x26, 0x34, 0x36, 0x33, 0x32, 0x36, 0x34, - 0x26, 0x2b, 0x01, 0x35, 0x34, 0x2e, 0x01, 0x23, 0x22, 0x06, 0x07, 0x26, 0x23, 0x22, 0x06, 0x15, - 0x14, 0x16, 0x17, 0x37, 0x33, 0x07, 0x33, 0x07, 0x37, 0x23, 0x17, 0x14, 0x06, 0x22, 0x26, 0x34, - 0x37, 0x36, 0x37, 0x31, 0x17, 0x16, 0x17, 0x16, 0x60, 0x08, 0x04, 0x09, 0x10, 0x08, 0x19, 0x1d, - 0x1d, 0x31, 0x1d, 0x10, 0x45, 0x2b, 0x24, 0x3e, 0x26, 0x03, 0x0a, 0x24, 0x32, 0x32, 0x24, 0x09, - 0x0c, 0x0c, 0x09, 0x12, 0x19, 0x19, 0x12, 0x2a, 0x1d, 0x31, 0x1d, 0x28, 0x3b, 0x06, 0x0c, 0x0b, - 0x1b, 0x25, 0x11, 0x0f, 0x6b, 0x40, 0x2b, 0x2b, 0x50, 0x10, 0x36, 0xe0, 0x1c, 0x28, 0x1c, 0x18, - 0x0c, 0x0c, 0x0d, 0x0e, 0x09, 0x0c, 0x9e, 0x04, 0x12, 0x0f, 0x04, 0x04, 0x0e, 0x31, 0x3a, 0x31, - 0x1d, 0x26, 0x2f, 0x22, 0x3b, 0x23, 0x32, 0x46, 0x32, 0x0c, 0x12, 0x0c, 0x19, 0x24, 0x19, 0x15, - 0x1d, 0x31, 0x1d, 0x33, 0x27, 0x04, 0x25, 0x1b, 0x11, 0x1e, 0x08, 0x37, 0x55, 0x95, 0x6a, 0x23, - 0x15, 0x1d, 0x1d, 0x29, 0x25, 0x12, 0x0e, 0x10, 0x13, 0x11, 0x17, 0x00, 0x00, 0x03, 0x00, 0x00, - 0xff, 0xfd, 0x01, 0xeb, 0x01, 0x96, 0x00, 0x0d, 0x00, 0x38, 0x00, 0x6a, 0x00, 0x00, 0x25, 0x14, - 0x06, 0x22, 0x26, 0x34, 0x37, 0x36, 0x37, 0x31, 0x17, 0x16, 0x17, 0x16, 0x25, 0x26, 0x36, 0x3f, - 0x01, 0x27, 0x26, 0x34, 0x36, 0x32, 0x1f, 0x01, 0x37, 0x3e, 0x01, 0x1e, 0x01, 0x0f, 0x01, 0x37, - 0x36, 0x1e, 0x01, 0x06, 0x0f, 0x01, 0x17, 0x16, 0x14, 0x06, 0x22, 0x2f, 0x01, 0x07, 0x0e, 0x01, - 0x2e, 0x01, 0x3f, 0x01, 0x07, 0x06, 0x26, 0x27, 0x34, 0x3e, 0x01, 0x33, 0x3e, 0x01, 0x33, 0x32, - 0x1e, 0x01, 0x17, 0x33, 0x32, 0x16, 0x14, 0x06, 0x23, 0x22, 0x26, 0x34, 0x36, 0x33, 0x32, 0x36, - 0x34, 0x26, 0x2b, 0x01, 0x35, 0x34, 0x2e, 0x01, 0x23, 0x22, 0x06, 0x07, 0x26, 0x23, 0x22, 0x06, - 0x14, 0x17, 0x16, 0x14, 0x06, 0x22, 0x27, 0x2e, 0x01, 0x01, 0x8b, 0x1c, 0x28, 0x1c, 0x18, 0x0c, - 0x0c, 0x0c, 0x0e, 0x09, 0x0d, 0xfe, 0xca, 0x02, 0x09, 0x09, 0x30, 0x23, 0x07, 0x0d, 0x13, 0x06, - 0x23, 0x0d, 0x02, 0x10, 0x11, 0x09, 0x02, 0x0d, 0x30, 0x09, 0x10, 0x05, 0x09, 0x09, 0x30, 0x23, - 0x06, 0x0d, 0x12, 0x06, 0x23, 0x0d, 0x03, 0x0f, 0x12, 0x09, 0x02, 0x0d, 0x30, 0x09, 0x0f, 0x43, - 0x1d, 0x31, 0x1d, 0x10, 0x45, 0x2b, 0x24, 0x3e, 0x26, 0x03, 0x0a, 0x24, 0x32, 0x32, 0x24, 0x09, - 0x0c, 0x0c, 0x09, 0x12, 0x19, 0x19, 0x12, 0x2a, 0x1d, 0x31, 0x1d, 0x28, 0x3b, 0x06, 0x0c, 0x0b, - 0x1b, 0x25, 0x13, 0x06, 0x0c, 0x12, 0x06, 0x0f, 0x11, 0x32, 0x15, 0x1d, 0x1d, 0x29, 0x25, 0x12, - 0x0e, 0x10, 0x13, 0x11, 0x17, 0x0e, 0x08, 0x10, 0x02, 0x0d, 0x23, 0x07, 0x12, 0x0d, 0x07, 0x23, - 0x30, 0x09, 0x09, 0x04, 0x10, 0x09, 0x30, 0x0c, 0x03, 0x09, 0x12, 0x0f, 0x02, 0x0d, 0x23, 0x07, - 0x12, 0x0d, 0x06, 0x24, 0x30, 0x09, 0x09, 0x04, 0x10, 0x09, 0x30, 0x0d, 0x02, 0x09, 0x90, 0x1d, + 0x0d, 0x12, 0x0c, 0x0c, 0x12, 0x0d, 0x0d, 0x12, 0x0c, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x01, 0xeb, 0x01, 0x81, 0x00, 0x03, 0x00, 0x17, 0x00, 0x00, 0x25, 0x21, 0x11, 0x21, 0x35, 0x21, + 0x22, 0x06, 0x15, 0x11, 0x14, 0x16, 0x3b, 0x01, 0x15, 0x33, 0x35, 0x33, 0x32, 0x36, 0x35, 0x11, + 0x34, 0x26, 0x01, 0xc0, 0xfe, 0x80, 0x01, 0x80, 0xfe, 0x80, 0x12, 0x19, 0x19, 0x12, 0x6b, 0xaa, + 0x6b, 0x12, 0x19, 0x19, 0x55, 0x01, 0x00, 0x2b, 0x19, 0x12, 0xff, 0x00, 0x11, 0x19, 0x2b, 0x2b, + 0x19, 0x11, 0x01, 0x00, 0x12, 0x19, 0x00, 0x02, 0x00, 0x00, 0xff, 0xea, 0x01, 0x71, 0x01, 0x96, + 0x00, 0x0f, 0x00, 0x18, 0x00, 0x00, 0x25, 0x35, 0x34, 0x26, 0x22, 0x06, 0x1d, 0x01, 0x0e, 0x01, + 0x1e, 0x01, 0x32, 0x3e, 0x01, 0x26, 0x27, 0x32, 0x16, 0x1d, 0x01, 0x23, 0x35, 0x34, 0x36, 0x01, + 0x40, 0x25, 0x36, 0x25, 0x1c, 0x14, 0x16, 0x38, 0x44, 0x38, 0x16, 0x14, 0x5c, 0x09, 0x0c, 0x2a, + 0x0c, 0xab, 0xaa, 0x1b, 0x25, 0x25, 0x1b, 0xaa, 0x15, 0x42, 0x41, 0x28, 0x28, 0x41, 0x42, 0xd5, + 0x0d, 0x09, 0x40, 0x40, 0x09, 0x0d, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0xd6, 0x01, 0x40, + 0x00, 0x0a, 0x00, 0x00, 0x25, 0x37, 0x27, 0x07, 0x27, 0x37, 0x17, 0x37, 0x17, 0x37, 0x15, 0x01, + 0x55, 0x31, 0x68, 0x55, 0x9e, 0x1e, 0x80, 0x55, 0x86, 0x31, 0x40, 0x31, 0x68, 0x55, 0x9e, 0x1e, + 0x80, 0x55, 0x86, 0x31, 0x80, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0xd6, 0x01, 0x40, + 0x00, 0x0a, 0x00, 0x00, 0x01, 0x17, 0x07, 0x27, 0x07, 0x17, 0x37, 0x17, 0x37, 0x17, 0x35, 0x01, + 0x55, 0x31, 0x68, 0x55, 0x9e, 0x1e, 0x80, 0x55, 0x86, 0x31, 0x01, 0x40, 0x31, 0x68, 0x55, 0x9e, + 0x1e, 0x80, 0x55, 0x86, 0x31, 0x80, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x01, 0xeb, 0x01, 0x56, + 0x00, 0x14, 0x00, 0x2a, 0x00, 0x00, 0x37, 0x22, 0x2e, 0x01, 0x34, 0x3e, 0x01, 0x33, 0x3e, 0x01, + 0x33, 0x32, 0x1e, 0x01, 0x17, 0x33, 0x32, 0x16, 0x14, 0x06, 0x23, 0x35, 0x23, 0x35, 0x34, 0x2e, + 0x01, 0x23, 0x22, 0x06, 0x07, 0x26, 0x23, 0x22, 0x06, 0x14, 0x16, 0x33, 0x21, 0x32, 0x36, 0x34, + 0x26, 0x80, 0x1d, 0x31, 0x1d, 0x1d, 0x31, 0x1d, 0x10, 0x45, 0x2b, 0x24, 0x3e, 0x26, 0x03, 0x0a, + 0x24, 0x32, 0x32, 0x24, 0x2a, 0x1d, 0x31, 0x1d, 0x28, 0x3b, 0x06, 0x0c, 0x0b, 0x1b, 0x25, 0x25, + 0x1b, 0x01, 0x15, 0x12, 0x19, 0x19, 0x2b, 0x1c, 0x31, 0x3a, 0x31, 0x1d, 0x26, 0x2f, 0x22, 0x3b, + 0x23, 0x32, 0x46, 0x32, 0x80, 0x15, 0x1d, 0x31, 0x1d, 0x33, 0x27, 0x04, 0x25, 0x35, 0x26, 0x19, + 0x24, 0x19, 0x00, 0x05, 0x00, 0x00, 0xff, 0xff, 0x01, 0xeb, 0x01, 0x81, 0x00, 0x0b, 0x00, 0x17, + 0x00, 0x3c, 0x00, 0x48, 0x00, 0x54, 0x00, 0x00, 0x37, 0x33, 0x32, 0x16, 0x14, 0x06, 0x2b, 0x01, + 0x22, 0x26, 0x34, 0x36, 0x21, 0x33, 0x32, 0x16, 0x14, 0x06, 0x2b, 0x01, 0x22, 0x26, 0x34, 0x36, + 0x25, 0x34, 0x3e, 0x01, 0x33, 0x3e, 0x01, 0x33, 0x32, 0x1e, 0x01, 0x17, 0x37, 0x32, 0x16, 0x17, + 0x23, 0x34, 0x26, 0x2b, 0x01, 0x35, 0x34, 0x2e, 0x01, 0x23, 0x22, 0x06, 0x07, 0x26, 0x23, 0x22, + 0x06, 0x15, 0x14, 0x17, 0x23, 0x17, 0x33, 0x32, 0x16, 0x14, 0x06, 0x2b, 0x01, 0x22, 0x26, 0x34, + 0x36, 0x33, 0x21, 0x32, 0x16, 0x14, 0x06, 0x23, 0x21, 0x22, 0x26, 0x34, 0x36, 0x40, 0xd5, 0x09, + 0x0d, 0x0d, 0x09, 0xd5, 0x09, 0x0c, 0x0c, 0x01, 0x1e, 0x6b, 0x09, 0x0c, 0x0c, 0x09, 0x6b, 0x09, + 0x0c, 0x0c, 0xfe, 0xc9, 0x1d, 0x31, 0x1d, 0x10, 0x45, 0x2b, 0x24, 0x3e, 0x26, 0x03, 0x0a, 0x23, + 0x32, 0x01, 0x2b, 0x19, 0x12, 0x2a, 0x1d, 0x31, 0x1d, 0x28, 0x3b, 0x06, 0x0c, 0x0b, 0x1b, 0x25, + 0x04, 0x2d, 0x29, 0x2b, 0x09, 0x0c, 0x0c, 0x09, 0x2b, 0x09, 0x0c, 0x0c, 0x74, 0x01, 0x15, 0x09, + 0x0c, 0x0c, 0x09, 0xfe, 0xeb, 0x09, 0x0d, 0x0d, 0x80, 0x0c, 0x12, 0x0d, 0x0d, 0x12, 0x0c, 0x0c, + 0x12, 0x0d, 0x0d, 0x12, 0x0c, 0x40, 0x1d, 0x31, 0x1d, 0x26, 0x2f, 0x22, 0x3b, 0x24, 0x01, 0x32, + 0x23, 0x11, 0x19, 0x16, 0x1d, 0x31, 0x1c, 0x33, 0x26, 0x04, 0x25, 0x1b, 0x0b, 0x0a, 0x80, 0x0d, + 0x12, 0x0c, 0x0c, 0x12, 0x0d, 0x0d, 0x12, 0x0c, 0x0c, 0x12, 0x0d, 0x00, 0x00, 0x04, 0x00, 0x00, + 0xff, 0xea, 0x01, 0xeb, 0x01, 0x96, 0x00, 0x34, 0x00, 0x3d, 0x00, 0x46, 0x00, 0x4f, 0x00, 0x00, + 0x37, 0x32, 0x16, 0x14, 0x06, 0x23, 0x22, 0x2e, 0x01, 0x34, 0x3e, 0x01, 0x33, 0x3e, 0x01, 0x33, + 0x32, 0x1e, 0x01, 0x17, 0x33, 0x32, 0x16, 0x14, 0x06, 0x2b, 0x01, 0x22, 0x26, 0x34, 0x36, 0x3b, + 0x01, 0x32, 0x36, 0x34, 0x26, 0x2b, 0x01, 0x35, 0x34, 0x2e, 0x01, 0x23, 0x22, 0x06, 0x07, 0x26, + 0x23, 0x22, 0x06, 0x14, 0x16, 0x17, 0x32, 0x16, 0x14, 0x06, 0x22, 0x26, 0x34, 0x36, 0x37, 0x32, + 0x16, 0x14, 0x06, 0x22, 0x26, 0x34, 0x36, 0x27, 0x32, 0x16, 0x14, 0x06, 0x22, 0x26, 0x34, 0x36, + 0x80, 0x09, 0x0c, 0x0c, 0x09, 0x1d, 0x31, 0x1d, 0x1d, 0x31, 0x1d, 0x10, 0x45, 0x2b, 0x24, 0x3e, + 0x26, 0x03, 0x0a, 0x24, 0x32, 0x32, 0x24, 0x15, 0x09, 0x0c, 0x0c, 0x09, 0x15, 0x12, 0x19, 0x19, + 0x12, 0x2a, 0x1d, 0x31, 0x1d, 0x28, 0x3b, 0x06, 0x0c, 0x0b, 0x1b, 0x25, 0x25, 0x70, 0x12, 0x19, + 0x19, 0x23, 0x19, 0x19, 0x71, 0x0e, 0x12, 0x12, 0x1b, 0x13, 0x13, 0x48, 0x0d, 0x13, 0x13, 0x1a, + 0x13, 0x13, 0x95, 0x0c, 0x12, 0x0c, 0x1c, 0x31, 0x3a, 0x31, 0x1d, 0x26, 0x2f, 0x22, 0x3b, 0x23, + 0x32, 0x46, 0x32, 0x0c, 0x12, 0x0c, 0x19, 0x24, 0x19, 0x15, 0x1d, 0x31, 0x1d, 0x33, 0x27, 0x04, + 0x25, 0x35, 0x26, 0x55, 0x19, 0x23, 0x19, 0x19, 0x23, 0x19, 0x2b, 0x13, 0x1b, 0x12, 0x12, 0x1b, + 0x13, 0x55, 0x13, 0x1a, 0x13, 0x13, 0x1a, 0x13, 0x00, 0x02, 0x00, 0x00, 0xff, 0xea, 0x01, 0xeb, + 0x01, 0x96, 0x00, 0x36, 0x00, 0x3d, 0x00, 0x00, 0x37, 0x22, 0x2e, 0x01, 0x34, 0x3e, 0x01, 0x33, + 0x3e, 0x01, 0x33, 0x32, 0x1e, 0x01, 0x17, 0x33, 0x32, 0x16, 0x14, 0x06, 0x2b, 0x01, 0x22, 0x26, + 0x34, 0x36, 0x3b, 0x01, 0x32, 0x36, 0x34, 0x26, 0x2b, 0x01, 0x35, 0x34, 0x2e, 0x01, 0x23, 0x22, + 0x06, 0x07, 0x26, 0x23, 0x22, 0x06, 0x14, 0x16, 0x3b, 0x01, 0x32, 0x16, 0x14, 0x06, 0x23, 0x37, + 0x33, 0x07, 0x33, 0x07, 0x37, 0x23, 0x80, 0x1d, 0x31, 0x1d, 0x1d, 0x31, 0x1d, 0x10, 0x45, 0x2b, + 0x24, 0x3e, 0x26, 0x03, 0x0a, 0x24, 0x32, 0x32, 0x24, 0x15, 0x09, 0x0c, 0x0c, 0x09, 0x15, 0x12, + 0x19, 0x19, 0x12, 0x2a, 0x1d, 0x31, 0x1d, 0x28, 0x3b, 0x06, 0x0c, 0x0b, 0x1b, 0x25, 0x25, 0x1b, + 0x15, 0x09, 0x0d, 0x0d, 0x09, 0x6b, 0x40, 0x2b, 0x2b, 0x50, 0x10, 0x35, 0x6b, 0x1c, 0x31, 0x3a, 0x31, 0x1d, 0x26, 0x2f, 0x22, 0x3b, 0x23, 0x32, 0x46, 0x32, 0x0c, 0x12, 0x0c, 0x19, 0x24, 0x19, - 0x15, 0x1d, 0x31, 0x1d, 0x33, 0x27, 0x04, 0x25, 0x36, 0x13, 0x06, 0x11, 0x0c, 0x06, 0x0f, 0x27, - 0x00, 0x02, 0x00, 0x00, 0xff, 0xea, 0x01, 0x6b, 0x01, 0x96, 0x00, 0x03, 0x00, 0x0b, 0x00, 0x00, - 0x01, 0x17, 0x23, 0x37, 0x17, 0x33, 0x15, 0x33, 0x15, 0x23, 0x35, 0x33, 0x01, 0x40, 0x2b, 0xd6, - 0x2b, 0x2b, 0x2a, 0x40, 0xaa, 0x40, 0x01, 0x95, 0x95, 0x95, 0xaa, 0xd6, 0x2a, 0x2a, 0x00, 0x02, - 0x00, 0x00, 0xff, 0xea, 0x01, 0x98, 0x01, 0x96, 0x00, 0x1d, 0x00, 0x23, 0x00, 0x00, 0x13, 0x07, - 0x17, 0x07, 0x23, 0x22, 0x06, 0x15, 0x14, 0x16, 0x1f, 0x01, 0x23, 0x15, 0x33, 0x35, 0x23, 0x27, - 0x36, 0x35, 0x34, 0x27, 0x37, 0x06, 0x16, 0x17, 0x37, 0x2e, 0x01, 0x07, 0x17, 0x07, 0x16, 0x3e, - 0x01, 0x26, 0xe7, 0x23, 0x18, 0x44, 0x03, 0x11, 0x19, 0x13, 0x0e, 0x57, 0x4e, 0xd6, 0x56, 0x5f, - 0x0a, 0x04, 0x44, 0x04, 0x1d, 0x1b, 0x5f, 0x1b, 0x3d, 0x18, 0x64, 0x23, 0x0b, 0x1a, 0x0e, 0x05, - 0x01, 0x95, 0x35, 0x10, 0x65, 0x19, 0x12, 0x0f, 0x17, 0x04, 0x81, 0x2a, 0x2a, 0x90, 0x0c, 0x0f, - 0x0a, 0x09, 0x65, 0x1b, 0x36, 0x12, 0x8e, 0x12, 0x06, 0x0e, 0x42, 0x36, 0x07, 0x05, 0x16, 0x1a, - 0x00, 0x02, 0x00, 0x00, 0xff, 0xea, 0x01, 0xc0, 0x01, 0x96, 0x00, 0x13, 0x00, 0x1d, 0x00, 0x00, - 0x13, 0x23, 0x35, 0x23, 0x15, 0x23, 0x35, 0x23, 0x15, 0x14, 0x16, 0x17, 0x15, 0x33, 0x35, 0x3e, - 0x01, 0x3d, 0x01, 0x23, 0x17, 0x15, 0x33, 0x15, 0x33, 0x11, 0x22, 0x07, 0x0e, 0x01, 0xeb, 0x2b, - 0x2b, 0x2a, 0x2b, 0x2e, 0x22, 0x35, 0x22, 0x2e, 0x2a, 0x6a, 0x36, 0x35, 0x1c, 0x1a, 0x17, 0x1e, - 0x01, 0x00, 0x95, 0x95, 0x95, 0x95, 0x22, 0x31, 0x02, 0xc0, 0xc0, 0x02, 0x31, 0x22, 0x95, 0x55, - 0xab, 0xaa, 0x01, 0xaa, 0x0d, 0x0d, 0x28, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x01, 0x81, - 0x01, 0x70, 0x00, 0x16, 0x00, 0x2a, 0x00, 0x00, 0x01, 0x0f, 0x01, 0x06, 0x07, 0x06, 0x07, 0x06, - 0x15, 0x14, 0x1e, 0x01, 0x32, 0x3e, 0x01, 0x35, 0x34, 0x27, 0x26, 0x27, 0x26, 0x2f, 0x01, 0x07, - 0x16, 0x17, 0x16, 0x17, 0x16, 0x17, 0x16, 0x15, 0x14, 0x06, 0x22, 0x26, 0x35, 0x34, 0x37, 0x36, - 0x37, 0x36, 0x37, 0x01, 0x00, 0x10, 0x11, 0x15, 0x11, 0x1a, 0x0d, 0x12, 0x22, 0x3b, 0x46, 0x3b, - 0x22, 0x12, 0x0d, 0x1a, 0x11, 0x15, 0x11, 0x10, 0x01, 0x03, 0x10, 0x10, 0x14, 0x0e, 0x0f, 0x31, - 0x48, 0x31, 0x0f, 0x0e, 0x14, 0x10, 0x10, 0x01, 0x70, 0x12, 0x15, 0x19, 0x19, 0x27, 0x1a, 0x27, - 0x1f, 0x22, 0x3b, 0x23, 0x23, 0x3b, 0x22, 0x1f, 0x27, 0x1a, 0x27, 0x19, 0x19, 0x15, 0x31, 0x02, - 0x03, 0x13, 0x16, 0x1e, 0x1e, 0x21, 0x12, 0x23, 0x32, 0x32, 0x23, 0x12, 0x21, 0x1e, 0x1e, 0x16, - 0x13, 0x00, 0x00, 0x03, 0x00, 0x00, 0xff, 0xea, 0x01, 0xd6, 0x01, 0x80, 0x00, 0x0e, 0x00, 0x17, - 0x00, 0x24, 0x00, 0x00, 0x01, 0x32, 0x16, 0x1d, 0x01, 0x16, 0x14, 0x06, 0x22, 0x26, 0x34, 0x37, - 0x35, 0x34, 0x36, 0x17, 0x22, 0x06, 0x1d, 0x01, 0x33, 0x35, 0x34, 0x26, 0x27, 0x07, 0x15, 0x33, - 0x07, 0x17, 0x23, 0x35, 0x23, 0x37, 0x17, 0x06, 0x07, 0x01, 0x95, 0x12, 0x19, 0x15, 0x25, 0x35, - 0x26, 0x16, 0x19, 0x11, 0x08, 0x0d, 0x2b, 0x0d, 0x9e, 0x6b, 0x98, 0x02, 0x02, 0xc2, 0x40, 0xd5, - 0x5e, 0x10, 0x09, 0x01, 0x15, 0x19, 0x11, 0x91, 0x13, 0x37, 0x25, 0x25, 0x37, 0x13, 0x91, 0x11, - 0x19, 0x15, 0x0d, 0x08, 0x16, 0x16, 0x08, 0x0d, 0x47, 0x60, 0xa7, 0x15, 0x16, 0xab, 0xc0, 0x54, - 0x0f, 0x15, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01, 0xee, 0x01, 0x56, 0x00, 0x3e, 0x00, 0x52, - 0x00, 0x65, 0x00, 0x77, 0x00, 0x00, 0x25, 0x2e, 0x01, 0x2f, 0x01, 0x36, 0x37, 0x35, 0x06, 0x07, - 0x06, 0x22, 0x27, 0x26, 0x27, 0x15, 0x16, 0x17, 0x07, 0x0e, 0x01, 0x07, 0x06, 0x17, 0x16, 0x17, - 0x16, 0x37, 0x36, 0x37, 0x36, 0x27, 0x37, 0x16, 0x17, 0x15, 0x0e, 0x01, 0x15, 0x14, 0x17, 0x16, - 0x33, 0x32, 0x37, 0x36, 0x35, 0x34, 0x26, 0x27, 0x35, 0x36, 0x37, 0x17, 0x06, 0x17, 0x16, 0x17, - 0x16, 0x37, 0x36, 0x37, 0x36, 0x25, 0x06, 0x07, 0x06, 0x07, 0x06, 0x27, 0x26, 0x37, 0x36, 0x3f, - 0x01, 0x36, 0x37, 0x36, 0x17, 0x16, 0x17, 0x16, 0x07, 0x17, 0x22, 0x27, 0x26, 0x2f, 0x01, 0x37, - 0x36, 0x37, 0x36, 0x32, 0x17, 0x16, 0x1f, 0x01, 0x07, 0x06, 0x07, 0x06, 0x37, 0x06, 0x27, 0x26, - 0x2f, 0x01, 0x34, 0x37, 0x36, 0x37, 0x36, 0x17, 0x16, 0x1f, 0x01, 0x16, 0x07, 0x06, 0x01, 0xe1, - 0x03, 0x11, 0x0c, 0x09, 0x10, 0x0d, 0x23, 0x33, 0x3b, 0x88, 0x3b, 0x33, 0x23, 0x0d, 0x10, 0x09, - 0x0c, 0x11, 0x03, 0x0c, 0x03, 0x04, 0x24, 0x18, 0x15, 0x1e, 0x12, 0x07, 0x10, 0x09, 0x1a, 0x20, - 0x0a, 0x0b, 0x0b, 0x10, 0x25, 0x19, 0x10, 0x17, 0x0b, 0x0a, 0x20, 0x1a, 0x09, 0x10, 0x07, 0x12, - 0x1e, 0x15, 0x18, 0x23, 0x05, 0x03, 0xfe, 0x8f, 0x04, 0x03, 0x09, 0x0a, 0x0e, 0x0e, 0x13, 0x03, - 0x02, 0x06, 0x03, 0x05, 0x07, 0x0a, 0x0d, 0x14, 0x04, 0x02, 0x02, 0x84, 0x0e, 0x09, 0x05, 0x03, - 0x01, 0x01, 0x03, 0x05, 0x09, 0x1c, 0x09, 0x05, 0x03, 0x01, 0x01, 0x03, 0x05, 0x09, 0xac, 0x13, - 0x14, 0x09, 0x06, 0x01, 0x05, 0x06, 0x0e, 0x13, 0x0c, 0x05, 0x02, 0x05, 0x04, 0x01, 0x02, 0xcd, - 0x0d, 0x16, 0x07, 0x24, 0x05, 0x06, 0x2f, 0x13, 0x0b, 0x0d, 0x0d, 0x0b, 0x13, 0x2f, 0x06, 0x05, - 0x24, 0x07, 0x16, 0x0d, 0x31, 0x21, 0x31, 0x09, 0x06, 0x12, 0x1a, 0x48, 0x1c, 0x17, 0x25, 0x04, - 0x02, 0x26, 0x09, 0x1a, 0x0d, 0x32, 0x20, 0x2e, 0x16, 0x20, 0x4a, 0x0d, 0x1a, 0x09, 0x26, 0x02, - 0x04, 0x25, 0x17, 0x1c, 0x48, 0x1a, 0x12, 0x06, 0x09, 0x31, 0x21, 0x1a, 0x0c, 0x0c, 0x1b, 0x10, - 0x16, 0x03, 0x05, 0x31, 0x18, 0x17, 0x08, 0x09, 0x04, 0x06, 0x03, 0x05, 0x11, 0x09, 0x08, 0x6b, - 0x19, 0x11, 0x1d, 0x19, 0x08, 0x09, 0x06, 0x09, 0x09, 0x06, 0x09, 0x08, 0x19, 0x1d, 0x11, 0x19, - 0x15, 0x05, 0x2d, 0x17, 0x17, 0x08, 0x0a, 0x07, 0x0a, 0x04, 0x04, 0x0d, 0x07, 0x08, 0x18, 0x1c, - 0x13, 0x1a, 0x00, 0x04, 0xff, 0xff, 0xff, 0xea, 0x02, 0x00, 0x01, 0x6b, 0x00, 0x22, 0x00, 0x2f, - 0x00, 0x3c, 0x00, 0x52, 0x00, 0x00, 0x01, 0x35, 0x34, 0x26, 0x2b, 0x01, 0x22, 0x07, 0x26, 0x2b, - 0x01, 0x22, 0x06, 0x1d, 0x01, 0x22, 0x06, 0x1d, 0x01, 0x14, 0x16, 0x33, 0x15, 0x33, 0x35, 0x21, - 0x15, 0x33, 0x35, 0x32, 0x36, 0x3d, 0x01, 0x34, 0x26, 0x27, 0x33, 0x32, 0x16, 0x1d, 0x01, 0x06, - 0x1d, 0x01, 0x23, 0x35, 0x34, 0x36, 0x07, 0x34, 0x36, 0x3b, 0x01, 0x32, 0x16, 0x1d, 0x01, 0x23, - 0x35, 0x34, 0x27, 0x05, 0x14, 0x06, 0x23, 0x21, 0x22, 0x26, 0x3d, 0x01, 0x34, 0x36, 0x32, 0x16, - 0x1d, 0x01, 0x21, 0x35, 0x34, 0x36, 0x32, 0x16, 0x15, 0x01, 0xc0, 0x26, 0x1a, 0x55, 0x19, 0x12, - 0x12, 0x19, 0x55, 0x1a, 0x26, 0x1a, 0x26, 0x26, 0x1a, 0x2b, 0x01, 0x2a, 0x2b, 0x1a, 0x26, 0x26, - 0xaf, 0x55, 0x09, 0x0c, 0x15, 0x6b, 0x0d, 0xb7, 0x0c, 0x09, 0x55, 0x09, 0x0d, 0x6b, 0x15, 0x01, - 0x6a, 0x0c, 0x09, 0xfe, 0x80, 0x09, 0x0c, 0x0c, 0x12, 0x0c, 0x01, 0x56, 0x0c, 0x12, 0x0c, 0x01, - 0x00, 0x2b, 0x1a, 0x26, 0x11, 0x11, 0x26, 0x1a, 0x2b, 0x26, 0x1a, 0x6b, 0x1a, 0x26, 0x2a, 0x2a, - 0x2a, 0x2a, 0x26, 0x1a, 0x6b, 0x1a, 0x26, 0x40, 0x0d, 0x08, 0x3c, 0x13, 0x1c, 0x2b, 0x96, 0x08, - 0x0d, 0x15, 0x08, 0x0d, 0x0d, 0x08, 0x96, 0x2b, 0x1c, 0x13, 0x9a, 0x08, 0x0d, 0x0d, 0x08, 0x6b, - 0x09, 0x0c, 0x0c, 0x09, 0x55, 0x55, 0x09, 0x0c, 0x0c, 0x09, 0x00, 0x05, 0x00, 0x00, 0xff, 0xe8, - 0x01, 0xeb, 0x01, 0x96, 0x00, 0x08, 0x00, 0x16, 0x00, 0x1f, 0x00, 0x28, 0x00, 0x4c, 0x00, 0x00, - 0x25, 0x14, 0x06, 0x22, 0x26, 0x34, 0x36, 0x32, 0x16, 0x27, 0x15, 0x14, 0x16, 0x33, 0x15, 0x36, - 0x32, 0x17, 0x35, 0x32, 0x36, 0x3d, 0x01, 0x07, 0x22, 0x06, 0x14, 0x16, 0x32, 0x36, 0x34, 0x26, - 0x21, 0x22, 0x06, 0x14, 0x16, 0x32, 0x36, 0x34, 0x26, 0x07, 0x22, 0x27, 0x06, 0x22, 0x26, 0x27, - 0x06, 0x22, 0x27, 0x0e, 0x01, 0x22, 0x27, 0x06, 0x23, 0x22, 0x27, 0x1e, 0x01, 0x33, 0x32, 0x37, - 0x15, 0x14, 0x16, 0x32, 0x36, 0x3d, 0x01, 0x16, 0x33, 0x32, 0x36, 0x37, 0x06, 0x01, 0x40, 0x25, - 0x36, 0x25, 0x25, 0x36, 0x25, 0x80, 0x19, 0x12, 0x0b, 0x14, 0x0b, 0x12, 0x19, 0xeb, 0x1a, 0x26, - 0x26, 0x35, 0x25, 0x25, 0x01, 0x3b, 0x1b, 0x25, 0x25, 0x35, 0x26, 0x26, 0x1a, 0x16, 0x13, 0x11, - 0x22, 0x1f, 0x0a, 0x11, 0x2a, 0x11, 0x0a, 0x1f, 0x22, 0x11, 0x13, 0x16, 0x07, 0x0a, 0x11, 0x30, - 0x1b, 0x2a, 0x21, 0x0c, 0x12, 0x0c, 0x21, 0x2a, 0x1b, 0x30, 0x11, 0x0a, 0xa9, 0x1b, 0x25, 0x25, - 0x35, 0x26, 0x26, 0xd2, 0x15, 0x12, 0x19, 0x57, 0x02, 0x02, 0x57, 0x19, 0x12, 0x15, 0xc2, 0x25, - 0x35, 0x26, 0x26, 0x35, 0x25, 0x25, 0x35, 0x26, 0x26, 0x35, 0x25, 0x95, 0x08, 0x08, 0x0f, 0x0d, - 0x07, 0x07, 0x0d, 0x0f, 0x08, 0x08, 0x02, 0x15, 0x18, 0x1b, 0x30, 0x09, 0x0c, 0x0c, 0x09, 0x30, - 0x1b, 0x18, 0x15, 0x02, 0x00, 0x00, 0x00, 0x06, 0x00, 0x4e, 0x00, 0x03, 0x00, 0x01, 0x04, 0x09, - 0x00, 0x01, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x03, 0x00, 0x01, 0x04, 0x09, 0x00, 0x02, 0x00, 0x0e, - 0x00, 0x2a, 0x00, 0x03, 0x00, 0x01, 0x04, 0x09, 0x00, 0x03, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x03, - 0x00, 0x01, 0x04, 0x09, 0x00, 0x04, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x03, 0x00, 0x01, 0x04, 0x09, - 0x00, 0x05, 0x00, 0x16, 0x00, 0x38, 0x00, 0x03, 0x00, 0x01, 0x04, 0x09, 0x00, 0x06, 0x00, 0x26, - 0x00, 0x4e, 0x00, 0x4d, 0x00, 0x61, 0x00, 0x74, 0x00, 0x65, 0x00, 0x72, 0x00, 0x69, 0x00, 0x61, - 0x00, 0x6c, 0x00, 0x20, 0x00, 0x44, 0x00, 0x65, 0x00, 0x73, 0x00, 0x69, 0x00, 0x67, 0x00, 0x6e, - 0x00, 0x20, 0x00, 0x49, 0x00, 0x63, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x73, 0x00, 0x52, 0x00, 0x65, - 0x00, 0x67, 0x00, 0x75, 0x00, 0x6c, 0x00, 0x61, 0x00, 0x72, 0x00, 0x56, 0x00, 0x65, 0x00, 0x72, - 0x00, 0x73, 0x00, 0x69, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x20, 0x00, 0x31, 0x00, 0x2e, 0x00, 0x30, - 0x00, 0x4d, 0x00, 0x61, 0x00, 0x74, 0x00, 0x65, 0x00, 0x72, 0x00, 0x69, 0x00, 0x61, 0x00, 0x6c, - 0x00, 0x44, 0x00, 0x65, 0x00, 0x73, 0x00, 0x69, 0x00, 0x67, 0x00, 0x6e, 0x00, 0x49, 0x00, 0x63, - 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x73, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x26, - 0x00, 0x28, 0x00, 0x02, 0x44, 0x46, 0x4c, 0x54, 0x00, 0x0e, 0x6c, 0x61, 0x74, 0x6e, 0x00, 0x18, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, + 0x15, 0x1d, 0x31, 0x1d, 0x33, 0x27, 0x04, 0x25, 0x35, 0x26, 0x0c, 0x12, 0x0c, 0x6a, 0x55, 0x95, + 0x6a, 0x00, 0x00, 0x04, 0x00, 0x00, 0xff, 0xe3, 0x01, 0xc6, 0x01, 0xab, 0x00, 0x09, 0x00, 0x13, + 0x00, 0x2b, 0x00, 0x37, 0x00, 0x00, 0x01, 0x07, 0x17, 0x27, 0x07, 0x37, 0x27, 0x3f, 0x01, 0x1f, + 0x01, 0x07, 0x17, 0x27, 0x07, 0x37, 0x27, 0x3f, 0x01, 0x17, 0x07, 0x36, 0x1e, 0x01, 0x07, 0x06, + 0x07, 0x0e, 0x01, 0x2e, 0x02, 0x36, 0x37, 0x36, 0x37, 0x36, 0x1e, 0x01, 0x07, 0x06, 0x1e, 0x02, + 0x17, 0x2e, 0x03, 0x27, 0x0e, 0x01, 0x1e, 0x02, 0x36, 0x01, 0x7b, 0x36, 0x13, 0x38, 0x38, 0x13, + 0x36, 0x44, 0x17, 0x17, 0x8e, 0x23, 0x0d, 0x24, 0x25, 0x0d, 0x23, 0x2c, 0x0f, 0x0e, 0x04, 0x08, + 0x11, 0x05, 0x05, 0x0b, 0x0c, 0x29, 0x6e, 0x6e, 0x52, 0x1c, 0x1c, 0x29, 0x0d, 0x0e, 0x08, 0x14, + 0x0d, 0x01, 0x04, 0x1f, 0x45, 0x5a, 0x0c, 0x2e, 0x57, 0x44, 0x26, 0x02, 0x1e, 0x13, 0x18, 0x3f, + 0x54, 0x56, 0x01, 0x69, 0x2a, 0x41, 0x27, 0x27, 0x41, 0x2a, 0x02, 0x40, 0x40, 0x96, 0x1a, 0x2b, + 0x19, 0x19, 0x2b, 0x1a, 0x01, 0x2a, 0x2a, 0x6a, 0x01, 0x0e, 0x13, 0x08, 0x10, 0x0b, 0x29, 0x1d, + 0x1d, 0x52, 0x6e, 0x6e, 0x29, 0x0d, 0x0a, 0x05, 0x06, 0x10, 0x09, 0x2e, 0x5a, 0x45, 0x20, 0x26, + 0x02, 0x26, 0x44, 0x56, 0x2e, 0x21, 0x55, 0x54, 0x3f, 0x18, 0x13, 0x00, 0x00, 0x07, 0x00, 0x00, + 0xff, 0xea, 0x01, 0xd6, 0x01, 0x9a, 0x00, 0x1b, 0x00, 0x29, 0x00, 0x2f, 0x00, 0x35, 0x00, 0x3b, + 0x00, 0x41, 0x00, 0x54, 0x00, 0x00, 0x01, 0x1e, 0x01, 0x07, 0x1e, 0x01, 0x1d, 0x01, 0x36, 0x33, + 0x32, 0x16, 0x14, 0x06, 0x23, 0x21, 0x22, 0x26, 0x34, 0x36, 0x3b, 0x01, 0x2e, 0x01, 0x37, 0x3e, + 0x02, 0x17, 0x26, 0x06, 0x07, 0x06, 0x16, 0x17, 0x3e, 0x01, 0x33, 0x32, 0x17, 0x2e, 0x01, 0x37, + 0x26, 0x27, 0x37, 0x17, 0x26, 0x07, 0x06, 0x07, 0x37, 0x17, 0x06, 0x17, 0x26, 0x27, 0x17, 0x07, + 0x36, 0x05, 0x16, 0x17, 0x27, 0x37, 0x06, 0x05, 0x23, 0x35, 0x34, 0x26, 0x22, 0x06, 0x15, 0x23, + 0x22, 0x06, 0x14, 0x16, 0x33, 0x21, 0x32, 0x36, 0x34, 0x26, 0x01, 0x10, 0x25, 0x26, 0x07, 0x14, + 0x18, 0x0a, 0x0b, 0x1b, 0x25, 0x25, 0x1b, 0xfe, 0xeb, 0x23, 0x32, 0x32, 0x23, 0x06, 0x15, 0x0a, + 0x0e, 0x0d, 0x33, 0x3e, 0x0c, 0x1d, 0x3a, 0x0c, 0x07, 0x01, 0x08, 0x12, 0x33, 0x1d, 0x16, 0x15, + 0x01, 0x18, 0x0f, 0x11, 0x13, 0x36, 0x13, 0x11, 0xb3, 0x10, 0x0c, 0x03, 0x3f, 0x14, 0xec, 0x03, + 0x06, 0x33, 0x2c, 0x04, 0xfe, 0xbf, 0x02, 0x06, 0x32, 0x2b, 0x03, 0x01, 0x56, 0x40, 0x32, 0x46, + 0x32, 0x2b, 0x12, 0x19, 0x19, 0x12, 0x01, 0x15, 0x09, 0x0d, 0x0d, 0x01, 0x4b, 0x10, 0x48, 0x27, + 0x12, 0x33, 0x1c, 0x04, 0x04, 0x26, 0x35, 0x25, 0x32, 0x46, 0x32, 0x1a, 0x42, 0x1f, 0x1d, 0x24, + 0x07, 0x34, 0x0d, 0x16, 0x1c, 0x10, 0x23, 0x0f, 0x15, 0x19, 0x08, 0x15, 0x23, 0x57, 0x08, 0x03, + 0x1c, 0x3d, 0x0d, 0x08, 0x0b, 0x0e, 0x3c, 0x0f, 0x06, 0x7e, 0x14, 0x10, 0x20, 0x2f, 0x14, 0x0b, + 0x13, 0x11, 0x20, 0x2f, 0x16, 0xa4, 0x2b, 0x23, 0x32, 0x32, 0x23, 0x19, 0x24, 0x19, 0x0d, 0x12, + 0x0c, 0x00, 0x00, 0x04, 0x00, 0x00, 0xff, 0xef, 0x01, 0xeb, 0x01, 0x96, 0x00, 0x0c, 0x00, 0x19, + 0x00, 0x26, 0x00, 0x5f, 0x00, 0x00, 0x37, 0x1e, 0x01, 0x0f, 0x01, 0x0e, 0x01, 0x2e, 0x01, 0x3f, + 0x01, 0x3e, 0x01, 0x17, 0x1e, 0x01, 0x0f, 0x01, 0x0e, 0x01, 0x2e, 0x01, 0x3f, 0x01, 0x3e, 0x01, + 0x17, 0x1e, 0x01, 0x0f, 0x01, 0x0e, 0x01, 0x2e, 0x01, 0x3f, 0x01, 0x3e, 0x01, 0x37, 0x35, 0x34, + 0x2e, 0x01, 0x23, 0x22, 0x06, 0x07, 0x26, 0x23, 0x22, 0x06, 0x15, 0x14, 0x16, 0x17, 0x31, 0x1e, + 0x01, 0x0e, 0x01, 0x27, 0x31, 0x2e, 0x01, 0x34, 0x3e, 0x01, 0x33, 0x3e, 0x01, 0x33, 0x32, 0x1e, + 0x01, 0x17, 0x33, 0x32, 0x16, 0x15, 0x14, 0x06, 0x07, 0x31, 0x06, 0x2e, 0x01, 0x36, 0x37, 0x31, + 0x3e, 0x01, 0x35, 0x34, 0x26, 0x23, 0xc0, 0x08, 0x09, 0x02, 0x1c, 0x02, 0x0f, 0x11, 0x09, 0x03, + 0x1b, 0x02, 0x0f, 0x5e, 0x09, 0x09, 0x03, 0x2c, 0x02, 0x0f, 0x11, 0x09, 0x02, 0x2c, 0x03, 0x0f, + 0x5e, 0x08, 0x09, 0x02, 0x1c, 0x02, 0x0f, 0x12, 0x08, 0x02, 0x1c, 0x02, 0x0f, 0x09, 0x1d, 0x31, + 0x1d, 0x28, 0x3b, 0x06, 0x0c, 0x0b, 0x1b, 0x25, 0x11, 0x0f, 0x08, 0x04, 0x09, 0x10, 0x08, 0x19, + 0x1d, 0x1d, 0x31, 0x1d, 0x10, 0x45, 0x2b, 0x24, 0x3e, 0x26, 0x03, 0x0a, 0x24, 0x32, 0x17, 0x14, + 0x08, 0x11, 0x09, 0x05, 0x08, 0x09, 0x0c, 0x19, 0x12, 0xc0, 0x02, 0x10, 0x08, 0x67, 0x09, 0x08, + 0x04, 0x0f, 0x09, 0x67, 0x08, 0x09, 0x02, 0x02, 0x10, 0x08, 0xa5, 0x09, 0x08, 0x04, 0x10, 0x08, + 0xa5, 0x08, 0x09, 0x02, 0x02, 0x10, 0x08, 0x67, 0x09, 0x08, 0x04, 0x0f, 0x09, 0x67, 0x08, 0x09, + 0x29, 0x15, 0x1d, 0x31, 0x1d, 0x33, 0x27, 0x04, 0x25, 0x1b, 0x11, 0x1e, 0x08, 0x04, 0x12, 0x0f, + 0x04, 0x04, 0x0e, 0x31, 0x3a, 0x31, 0x1d, 0x26, 0x2f, 0x22, 0x3b, 0x23, 0x32, 0x23, 0x18, 0x27, + 0x0b, 0x04, 0x04, 0x10, 0x11, 0x04, 0x06, 0x13, 0x0c, 0x12, 0x19, 0x00, 0x00, 0x03, 0x00, 0x00, + 0xff, 0xea, 0x01, 0xeb, 0x01, 0x95, 0x00, 0x34, 0x00, 0x40, 0x00, 0x54, 0x00, 0x00, 0x37, 0x32, + 0x16, 0x14, 0x06, 0x23, 0x22, 0x2e, 0x01, 0x34, 0x3e, 0x01, 0x33, 0x3e, 0x01, 0x33, 0x32, 0x1e, + 0x01, 0x17, 0x37, 0x32, 0x16, 0x14, 0x06, 0x2b, 0x01, 0x22, 0x26, 0x34, 0x36, 0x3b, 0x01, 0x32, + 0x36, 0x34, 0x26, 0x2b, 0x01, 0x35, 0x34, 0x2e, 0x01, 0x23, 0x22, 0x06, 0x07, 0x26, 0x23, 0x22, + 0x06, 0x14, 0x16, 0x17, 0x16, 0x17, 0x16, 0x15, 0x14, 0x06, 0x22, 0x26, 0x35, 0x34, 0x3f, 0x01, + 0x0f, 0x01, 0x06, 0x07, 0x06, 0x07, 0x06, 0x15, 0x14, 0x16, 0x32, 0x36, 0x35, 0x34, 0x27, 0x2e, + 0x01, 0x27, 0x31, 0x80, 0x09, 0x0c, 0x0c, 0x09, 0x1d, 0x31, 0x1d, 0x1d, 0x31, 0x1d, 0x10, 0x45, + 0x2b, 0x24, 0x3e, 0x26, 0x03, 0x0a, 0x24, 0x32, 0x32, 0x24, 0x15, 0x09, 0x0c, 0x0c, 0x09, 0x15, + 0x12, 0x19, 0x19, 0x12, 0x2a, 0x1d, 0x31, 0x1d, 0x28, 0x3b, 0x06, 0x0b, 0x0c, 0x1b, 0x25, 0x25, + 0x9b, 0x05, 0x07, 0x1f, 0x19, 0x24, 0x19, 0x1f, 0x0c, 0x0b, 0x0b, 0x0e, 0x0b, 0x12, 0x08, 0x0c, + 0x32, 0x46, 0x32, 0x0c, 0x08, 0x24, 0x12, 0x95, 0x0d, 0x11, 0x0d, 0x1d, 0x31, 0x3a, 0x31, 0x1c, + 0x27, 0x2f, 0x23, 0x3a, 0x24, 0x01, 0x32, 0x47, 0x32, 0x0d, 0x11, 0x0d, 0x19, 0x23, 0x19, 0x15, + 0x1d, 0x31, 0x1d, 0x33, 0x26, 0x04, 0x26, 0x35, 0x25, 0x03, 0x07, 0x0a, 0x2b, 0x16, 0x12, 0x19, + 0x19, 0x12, 0x16, 0x2b, 0x54, 0x0c, 0x0e, 0x11, 0x11, 0x19, 0x12, 0x19, 0x15, 0x23, 0x32, 0x32, + 0x23, 0x15, 0x19, 0x12, 0x34, 0x15, 0x00, 0x02, 0x00, 0x00, 0xff, 0xd6, 0x01, 0xeb, 0x01, 0x96, + 0x00, 0x34, 0x00, 0x5e, 0x00, 0x00, 0x37, 0x32, 0x16, 0x14, 0x06, 0x23, 0x22, 0x2e, 0x01, 0x34, + 0x3e, 0x01, 0x33, 0x3e, 0x01, 0x33, 0x32, 0x1e, 0x01, 0x17, 0x33, 0x32, 0x16, 0x14, 0x06, 0x2b, + 0x01, 0x22, 0x26, 0x34, 0x36, 0x3b, 0x01, 0x32, 0x36, 0x34, 0x26, 0x2b, 0x01, 0x35, 0x34, 0x2e, + 0x01, 0x23, 0x22, 0x06, 0x07, 0x26, 0x23, 0x22, 0x06, 0x14, 0x16, 0x17, 0x37, 0x27, 0x26, 0x34, + 0x36, 0x32, 0x1f, 0x01, 0x37, 0x3e, 0x01, 0x1e, 0x01, 0x0f, 0x01, 0x37, 0x36, 0x1e, 0x01, 0x06, + 0x0f, 0x01, 0x17, 0x16, 0x14, 0x06, 0x22, 0x2f, 0x01, 0x07, 0x0e, 0x01, 0x2e, 0x01, 0x3f, 0x01, + 0x07, 0x06, 0x2e, 0x01, 0x36, 0x80, 0x09, 0x0c, 0x0c, 0x09, 0x1d, 0x31, 0x1d, 0x1d, 0x31, 0x1d, + 0x10, 0x45, 0x2b, 0x24, 0x3e, 0x26, 0x03, 0x0a, 0x24, 0x32, 0x32, 0x24, 0x15, 0x09, 0x0c, 0x0c, + 0x09, 0x15, 0x12, 0x19, 0x19, 0x12, 0x2a, 0x1d, 0x31, 0x1d, 0x28, 0x3b, 0x06, 0x0c, 0x0b, 0x1b, + 0x25, 0x25, 0x43, 0x2f, 0x23, 0x06, 0x0d, 0x12, 0x06, 0x22, 0x0c, 0x03, 0x0f, 0x11, 0x09, 0x02, + 0x0d, 0x2f, 0x08, 0x10, 0x04, 0x09, 0x08, 0x2f, 0x23, 0x06, 0x0d, 0x12, 0x06, 0x22, 0x0c, 0x03, + 0x0f, 0x11, 0x09, 0x02, 0x0d, 0x2f, 0x08, 0x10, 0x04, 0x09, 0x95, 0x0c, 0x12, 0x0c, 0x1c, 0x31, + 0x3a, 0x31, 0x1d, 0x26, 0x2f, 0x22, 0x3b, 0x23, 0x32, 0x46, 0x32, 0x0c, 0x12, 0x0c, 0x19, 0x24, + 0x19, 0x15, 0x1d, 0x31, 0x1d, 0x33, 0x27, 0x04, 0x25, 0x35, 0x26, 0x56, 0x0c, 0x22, 0x06, 0x12, + 0x0d, 0x06, 0x23, 0x2f, 0x08, 0x09, 0x04, 0x10, 0x08, 0x2f, 0x0d, 0x02, 0x09, 0x11, 0x0f, 0x03, + 0x0c, 0x22, 0x06, 0x12, 0x0d, 0x06, 0x23, 0x2f, 0x08, 0x09, 0x04, 0x10, 0x08, 0x2f, 0x0d, 0x02, + 0x09, 0x11, 0x0f, 0x00, 0x00, 0x08, 0x00, 0x00, 0xff, 0xea, 0x01, 0xb9, 0x01, 0x96, 0x00, 0x0c, + 0x00, 0x15, 0x00, 0x1a, 0x00, 0x1f, 0x00, 0x24, 0x00, 0x29, 0x00, 0x2e, 0x00, 0x33, 0x00, 0x00, + 0x01, 0x32, 0x1e, 0x01, 0x14, 0x0e, 0x01, 0x22, 0x2e, 0x01, 0x34, 0x3e, 0x01, 0x17, 0x22, 0x06, + 0x14, 0x16, 0x32, 0x36, 0x34, 0x26, 0x27, 0x17, 0x26, 0x22, 0x0f, 0x01, 0x37, 0x0e, 0x01, 0x0f, + 0x01, 0x37, 0x1e, 0x01, 0x17, 0x25, 0x07, 0x2e, 0x01, 0x27, 0x17, 0x07, 0x3e, 0x01, 0x37, 0x07, + 0x27, 0x16, 0x32, 0x37, 0x01, 0x00, 0x1d, 0x31, 0x1d, 0x1d, 0x31, 0x3a, 0x31, 0x1d, 0x1d, 0x31, + 0x1d, 0x1b, 0x25, 0x25, 0x36, 0x25, 0x25, 0x1b, 0x33, 0x19, 0x34, 0x19, 0x86, 0x59, 0x14, 0x1a, + 0x05, 0x25, 0x25, 0x05, 0x1a, 0x14, 0x01, 0x19, 0x26, 0x05, 0x1a, 0x14, 0x58, 0x58, 0x14, 0x1a, + 0x05, 0x93, 0x33, 0x19, 0x33, 0x1a, 0x01, 0x2b, 0x1d, 0x31, 0x3a, 0x31, 0x1d, 0x1d, 0x31, 0x3a, + 0x31, 0x1d, 0x2b, 0x25, 0x36, 0x25, 0x25, 0x36, 0x25, 0x95, 0x49, 0x09, 0x09, 0x21, 0x07, 0x11, + 0x2c, 0x1b, 0x85, 0x51, 0x1a, 0x2d, 0x12, 0xde, 0x51, 0x1a, 0x2e, 0x10, 0xdd, 0x07, 0x11, 0x2d, + 0x1a, 0xbb, 0x49, 0x09, 0x09, 0x00, 0x00, 0x06, 0x00, 0x00, 0xff, 0xff, 0x01, 0xd6, 0x01, 0x96, + 0x00, 0x13, 0x00, 0x19, 0x00, 0x1e, 0x00, 0x23, 0x00, 0x28, 0x00, 0x39, 0x00, 0x00, 0x37, 0x33, + 0x34, 0x3e, 0x01, 0x32, 0x1e, 0x01, 0x15, 0x33, 0x32, 0x16, 0x14, 0x06, 0x23, 0x21, 0x22, 0x26, + 0x34, 0x36, 0x21, 0x34, 0x26, 0x22, 0x06, 0x15, 0x37, 0x17, 0x26, 0x22, 0x0f, 0x01, 0x37, 0x0e, + 0x01, 0x07, 0x25, 0x07, 0x2e, 0x01, 0x27, 0x03, 0x37, 0x36, 0x34, 0x26, 0x22, 0x0f, 0x01, 0x27, + 0x26, 0x22, 0x06, 0x14, 0x1f, 0x01, 0x16, 0x32, 0x40, 0x55, 0x1d, 0x31, 0x3a, 0x31, 0x1d, 0x55, + 0x09, 0x0c, 0x0c, 0x09, 0xfe, 0x80, 0x09, 0x0c, 0x0c, 0x01, 0x09, 0x25, 0x36, 0x25, 0x40, 0x33, + 0x19, 0x34, 0x19, 0x86, 0x59, 0x14, 0x1a, 0x05, 0x01, 0x4c, 0x26, 0x05, 0x1a, 0x14, 0x51, 0x42, + 0x07, 0x0d, 0x11, 0x07, 0x33, 0x33, 0x07, 0x11, 0x0d, 0x07, 0x42, 0x07, 0x10, 0xc0, 0x1d, 0x31, + 0x1d, 0x1d, 0x31, 0x1d, 0x0c, 0x12, 0x0d, 0x0d, 0x12, 0x0c, 0x1b, 0x25, 0x25, 0x1b, 0xd5, 0x49, + 0x09, 0x09, 0x21, 0x07, 0x11, 0x2c, 0x1b, 0x51, 0x51, 0x1a, 0x2e, 0x10, 0xfe, 0xd4, 0x43, 0x06, + 0x12, 0x0c, 0x06, 0x34, 0x34, 0x06, 0x0c, 0x12, 0x06, 0x43, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, + 0xff, 0xfd, 0x01, 0xd6, 0x01, 0x96, 0x00, 0x13, 0x00, 0x19, 0x00, 0x1e, 0x00, 0x23, 0x00, 0x28, + 0x00, 0x39, 0x00, 0x00, 0x37, 0x33, 0x34, 0x3e, 0x01, 0x32, 0x1e, 0x01, 0x15, 0x33, 0x32, 0x16, + 0x14, 0x06, 0x23, 0x21, 0x22, 0x26, 0x34, 0x36, 0x21, 0x34, 0x26, 0x22, 0x06, 0x15, 0x37, 0x17, + 0x26, 0x22, 0x0f, 0x01, 0x37, 0x0e, 0x01, 0x07, 0x25, 0x07, 0x2e, 0x01, 0x27, 0x07, 0x17, 0x16, + 0x14, 0x06, 0x22, 0x2f, 0x01, 0x07, 0x06, 0x22, 0x26, 0x34, 0x3f, 0x01, 0x36, 0x32, 0x40, 0x55, + 0x1d, 0x31, 0x3a, 0x31, 0x1d, 0x55, 0x09, 0x0c, 0x0c, 0x09, 0xfe, 0x80, 0x09, 0x0c, 0x0c, 0x01, + 0x09, 0x25, 0x36, 0x25, 0x40, 0x33, 0x19, 0x34, 0x19, 0x86, 0x59, 0x14, 0x1a, 0x05, 0x01, 0x4c, + 0x26, 0x05, 0x1a, 0x14, 0x51, 0x42, 0x07, 0x0d, 0x11, 0x07, 0x33, 0x33, 0x07, 0x11, 0x0d, 0x07, + 0x42, 0x07, 0x10, 0xc0, 0x1d, 0x31, 0x1d, 0x1d, 0x31, 0x1d, 0x0c, 0x12, 0x0d, 0x0d, 0x12, 0x0c, + 0x1b, 0x25, 0x25, 0x1b, 0xd5, 0x49, 0x09, 0x09, 0x21, 0x07, 0x11, 0x2c, 0x1b, 0x51, 0x51, 0x1a, + 0x2e, 0x10, 0xce, 0x42, 0x06, 0x12, 0x0c, 0x06, 0x33, 0x33, 0x06, 0x0c, 0x12, 0x06, 0x42, 0x07, + 0x00, 0x03, 0x00, 0x00, 0xff, 0xea, 0x01, 0xd6, 0x01, 0x96, 0x00, 0x17, 0x00, 0x2e, 0x00, 0x45, + 0x00, 0x00, 0x37, 0x22, 0x26, 0x34, 0x36, 0x3b, 0x01, 0x32, 0x36, 0x34, 0x26, 0x22, 0x07, 0x06, + 0x22, 0x26, 0x34, 0x37, 0x36, 0x32, 0x16, 0x14, 0x06, 0x23, 0x17, 0x32, 0x36, 0x34, 0x26, 0x22, + 0x06, 0x22, 0x26, 0x34, 0x37, 0x36, 0x32, 0x16, 0x14, 0x06, 0x23, 0x21, 0x22, 0x26, 0x34, 0x36, + 0x33, 0x05, 0x21, 0x22, 0x26, 0x34, 0x36, 0x33, 0x21, 0x32, 0x16, 0x14, 0x06, 0x22, 0x27, 0x26, + 0x34, 0x36, 0x32, 0x16, 0x32, 0x36, 0x34, 0x26, 0x55, 0x09, 0x0c, 0x0c, 0x09, 0xab, 0x12, 0x19, + 0x19, 0x24, 0x0c, 0x06, 0x12, 0x0d, 0x07, 0x19, 0x46, 0x32, 0x32, 0x23, 0x95, 0x09, 0x0d, 0x0d, + 0x12, 0x0c, 0x12, 0x0c, 0x06, 0x13, 0x35, 0x25, 0x25, 0x1b, 0xfe, 0xd6, 0x09, 0x0d, 0x0d, 0x09, + 0x01, 0x15, 0xfe, 0xd5, 0x09, 0x0c, 0x0c, 0x09, 0x01, 0x2b, 0x1b, 0x25, 0x25, 0x35, 0x13, 0x06, + 0x0c, 0x12, 0x0c, 0x12, 0x0c, 0x0c, 0xeb, 0x0c, 0x12, 0x0c, 0x19, 0x24, 0x19, 0x0d, 0x06, 0x0c, + 0x12, 0x06, 0x19, 0x32, 0x46, 0x32, 0x2b, 0x0c, 0x12, 0x0d, 0x0d, 0x0d, 0x11, 0x07, 0x12, 0x25, + 0x35, 0x26, 0x0d, 0x12, 0x0c, 0x80, 0x0c, 0x12, 0x0d, 0x26, 0x35, 0x25, 0x12, 0x07, 0x11, 0x0d, + 0x0d, 0x0d, 0x12, 0x0c, 0x00, 0x04, 0x00, 0x00, 0xff, 0xea, 0x01, 0xd6, 0x01, 0x96, 0x00, 0x03, + 0x00, 0x07, 0x00, 0x18, 0x00, 0x25, 0x00, 0x00, 0x37, 0x33, 0x15, 0x23, 0x35, 0x33, 0x15, 0x23, + 0x37, 0x22, 0x0e, 0x01, 0x15, 0x14, 0x1e, 0x02, 0x32, 0x3e, 0x02, 0x34, 0x2e, 0x02, 0x03, 0x22, + 0x2e, 0x01, 0x34, 0x3e, 0x01, 0x32, 0x1e, 0x01, 0x14, 0x0e, 0x01, 0xeb, 0x2a, 0x2a, 0x2a, 0x2a, + 0x15, 0x3a, 0x62, 0x39, 0x20, 0x3c, 0x4f, 0x54, 0x4f, 0x3c, 0x20, 0x20, 0x3c, 0x4f, 0x2a, 0x2e, + 0x4f, 0x2e, 0x2e, 0x4f, 0x5c, 0x4f, 0x2e, 0x2e, 0x4f, 0x80, 0x2b, 0xd6, 0x80, 0xea, 0x39, 0x62, + 0x3a, 0x2a, 0x4f, 0x3c, 0x20, 0x20, 0x3c, 0x4f, 0x54, 0x4f, 0x3c, 0x20, 0xfe, 0x80, 0x2e, 0x4f, + 0x5c, 0x4f, 0x2e, 0x2e, 0x4f, 0x5c, 0x4f, 0x2e, 0x00, 0x03, 0x00, 0x00, 0xff, 0xea, 0x01, 0xeb, + 0x01, 0x96, 0x00, 0x34, 0x00, 0x3b, 0x00, 0x49, 0x00, 0x00, 0x37, 0x1e, 0x01, 0x0e, 0x01, 0x27, + 0x31, 0x2e, 0x01, 0x34, 0x3e, 0x01, 0x33, 0x3e, 0x01, 0x33, 0x32, 0x1e, 0x01, 0x17, 0x33, 0x32, + 0x16, 0x14, 0x06, 0x23, 0x22, 0x26, 0x34, 0x36, 0x33, 0x32, 0x36, 0x34, 0x26, 0x2b, 0x01, 0x35, + 0x34, 0x2e, 0x01, 0x23, 0x22, 0x06, 0x07, 0x26, 0x23, 0x22, 0x06, 0x15, 0x14, 0x16, 0x17, 0x37, + 0x33, 0x07, 0x33, 0x07, 0x37, 0x23, 0x17, 0x14, 0x06, 0x22, 0x26, 0x34, 0x37, 0x36, 0x37, 0x31, + 0x17, 0x16, 0x17, 0x16, 0x60, 0x08, 0x04, 0x09, 0x10, 0x08, 0x19, 0x1d, 0x1d, 0x31, 0x1d, 0x10, + 0x45, 0x2b, 0x24, 0x3e, 0x26, 0x03, 0x0a, 0x24, 0x32, 0x32, 0x24, 0x09, 0x0c, 0x0c, 0x09, 0x12, + 0x19, 0x19, 0x12, 0x2a, 0x1d, 0x31, 0x1d, 0x28, 0x3b, 0x06, 0x0c, 0x0b, 0x1b, 0x25, 0x11, 0x0f, + 0x6b, 0x40, 0x2b, 0x2b, 0x50, 0x10, 0x36, 0xe0, 0x1c, 0x28, 0x1c, 0x18, 0x0c, 0x0c, 0x0d, 0x0e, + 0x09, 0x0c, 0x9e, 0x04, 0x12, 0x0f, 0x04, 0x04, 0x0e, 0x31, 0x3a, 0x31, 0x1d, 0x26, 0x2f, 0x22, + 0x3b, 0x23, 0x32, 0x46, 0x32, 0x0c, 0x12, 0x0c, 0x19, 0x24, 0x19, 0x15, 0x1d, 0x31, 0x1d, 0x33, + 0x27, 0x04, 0x25, 0x1b, 0x11, 0x1e, 0x08, 0x37, 0x55, 0x95, 0x6a, 0x23, 0x15, 0x1d, 0x1d, 0x29, + 0x25, 0x12, 0x0e, 0x10, 0x13, 0x11, 0x17, 0x00, 0x00, 0x03, 0x00, 0x00, 0xff, 0xfd, 0x01, 0xeb, + 0x01, 0x96, 0x00, 0x0d, 0x00, 0x38, 0x00, 0x6a, 0x00, 0x00, 0x25, 0x14, 0x06, 0x22, 0x26, 0x34, + 0x37, 0x36, 0x37, 0x31, 0x17, 0x16, 0x17, 0x16, 0x25, 0x26, 0x36, 0x3f, 0x01, 0x27, 0x26, 0x34, + 0x36, 0x32, 0x1f, 0x01, 0x37, 0x3e, 0x01, 0x1e, 0x01, 0x0f, 0x01, 0x37, 0x36, 0x1e, 0x01, 0x06, + 0x0f, 0x01, 0x17, 0x16, 0x14, 0x06, 0x22, 0x2f, 0x01, 0x07, 0x0e, 0x01, 0x2e, 0x01, 0x3f, 0x01, + 0x07, 0x06, 0x26, 0x27, 0x34, 0x3e, 0x01, 0x33, 0x3e, 0x01, 0x33, 0x32, 0x1e, 0x01, 0x17, 0x33, + 0x32, 0x16, 0x14, 0x06, 0x23, 0x22, 0x26, 0x34, 0x36, 0x33, 0x32, 0x36, 0x34, 0x26, 0x2b, 0x01, + 0x35, 0x34, 0x2e, 0x01, 0x23, 0x22, 0x06, 0x07, 0x26, 0x23, 0x22, 0x06, 0x14, 0x17, 0x16, 0x14, + 0x06, 0x22, 0x27, 0x2e, 0x01, 0x01, 0x8b, 0x1c, 0x28, 0x1c, 0x18, 0x0c, 0x0c, 0x0c, 0x0e, 0x09, + 0x0d, 0xfe, 0xca, 0x02, 0x09, 0x09, 0x30, 0x23, 0x07, 0x0d, 0x13, 0x06, 0x23, 0x0d, 0x02, 0x10, + 0x11, 0x09, 0x02, 0x0d, 0x30, 0x09, 0x10, 0x05, 0x09, 0x09, 0x30, 0x23, 0x06, 0x0d, 0x12, 0x06, + 0x23, 0x0d, 0x03, 0x0f, 0x12, 0x09, 0x02, 0x0d, 0x30, 0x09, 0x0f, 0x43, 0x1d, 0x31, 0x1d, 0x10, + 0x45, 0x2b, 0x24, 0x3e, 0x26, 0x03, 0x0a, 0x24, 0x32, 0x32, 0x24, 0x09, 0x0c, 0x0c, 0x09, 0x12, + 0x19, 0x19, 0x12, 0x2a, 0x1d, 0x31, 0x1d, 0x28, 0x3b, 0x06, 0x0c, 0x0b, 0x1b, 0x25, 0x13, 0x06, + 0x0c, 0x12, 0x06, 0x0f, 0x11, 0x32, 0x15, 0x1d, 0x1d, 0x29, 0x25, 0x12, 0x0e, 0x10, 0x13, 0x11, + 0x17, 0x0e, 0x08, 0x10, 0x02, 0x0d, 0x23, 0x07, 0x12, 0x0d, 0x07, 0x23, 0x30, 0x09, 0x09, 0x04, + 0x10, 0x09, 0x30, 0x0c, 0x03, 0x09, 0x12, 0x0f, 0x02, 0x0d, 0x23, 0x07, 0x12, 0x0d, 0x06, 0x24, + 0x30, 0x09, 0x09, 0x04, 0x10, 0x09, 0x30, 0x0d, 0x02, 0x09, 0x90, 0x1d, 0x31, 0x1d, 0x26, 0x2f, + 0x22, 0x3b, 0x23, 0x32, 0x46, 0x32, 0x0c, 0x12, 0x0c, 0x19, 0x24, 0x19, 0x15, 0x1d, 0x31, 0x1d, + 0x33, 0x27, 0x04, 0x25, 0x36, 0x13, 0x06, 0x11, 0x0c, 0x06, 0x0f, 0x27, 0x00, 0x02, 0x00, 0x00, + 0xff, 0xea, 0x01, 0x6b, 0x01, 0x96, 0x00, 0x03, 0x00, 0x0b, 0x00, 0x00, 0x01, 0x17, 0x23, 0x37, + 0x17, 0x33, 0x15, 0x33, 0x15, 0x23, 0x35, 0x33, 0x01, 0x40, 0x2b, 0xd6, 0x2b, 0x2b, 0x2a, 0x40, + 0xaa, 0x40, 0x01, 0x95, 0x95, 0x95, 0xaa, 0xd6, 0x2a, 0x2a, 0x00, 0x02, 0x00, 0x00, 0xff, 0xea, + 0x01, 0x98, 0x01, 0x96, 0x00, 0x1d, 0x00, 0x23, 0x00, 0x00, 0x13, 0x07, 0x17, 0x07, 0x23, 0x22, + 0x06, 0x15, 0x14, 0x16, 0x1f, 0x01, 0x23, 0x15, 0x33, 0x35, 0x23, 0x27, 0x36, 0x35, 0x34, 0x27, + 0x37, 0x06, 0x16, 0x17, 0x37, 0x2e, 0x01, 0x07, 0x17, 0x07, 0x16, 0x3e, 0x01, 0x26, 0xe7, 0x23, + 0x18, 0x44, 0x03, 0x11, 0x19, 0x13, 0x0e, 0x57, 0x4e, 0xd6, 0x56, 0x5f, 0x0a, 0x04, 0x44, 0x04, + 0x1d, 0x1b, 0x5f, 0x1b, 0x3d, 0x18, 0x64, 0x23, 0x0b, 0x1a, 0x0e, 0x05, 0x01, 0x95, 0x35, 0x10, + 0x65, 0x19, 0x12, 0x0f, 0x17, 0x04, 0x81, 0x2a, 0x2a, 0x90, 0x0c, 0x0f, 0x0a, 0x09, 0x65, 0x1b, + 0x36, 0x12, 0x8e, 0x12, 0x06, 0x0e, 0x42, 0x36, 0x07, 0x05, 0x16, 0x1a, 0x00, 0x02, 0x00, 0x00, + 0xff, 0xea, 0x01, 0xc0, 0x01, 0x96, 0x00, 0x13, 0x00, 0x1d, 0x00, 0x00, 0x13, 0x23, 0x35, 0x23, + 0x15, 0x23, 0x35, 0x23, 0x15, 0x14, 0x16, 0x17, 0x15, 0x33, 0x35, 0x3e, 0x01, 0x3d, 0x01, 0x23, + 0x17, 0x15, 0x33, 0x15, 0x33, 0x11, 0x22, 0x07, 0x0e, 0x01, 0xeb, 0x2b, 0x2b, 0x2a, 0x2b, 0x2e, + 0x22, 0x35, 0x22, 0x2e, 0x2a, 0x6a, 0x36, 0x35, 0x1c, 0x1a, 0x17, 0x1e, 0x01, 0x00, 0x95, 0x95, + 0x95, 0x95, 0x22, 0x31, 0x02, 0xc0, 0xc0, 0x02, 0x31, 0x22, 0x95, 0x55, 0xab, 0xaa, 0x01, 0xaa, + 0x0d, 0x0d, 0x28, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x01, 0x81, 0x01, 0x70, 0x00, 0x16, + 0x00, 0x2a, 0x00, 0x00, 0x01, 0x0f, 0x01, 0x06, 0x07, 0x06, 0x07, 0x06, 0x15, 0x14, 0x1e, 0x01, + 0x32, 0x3e, 0x01, 0x35, 0x34, 0x27, 0x26, 0x27, 0x26, 0x2f, 0x01, 0x07, 0x16, 0x17, 0x16, 0x17, + 0x16, 0x17, 0x16, 0x15, 0x14, 0x06, 0x22, 0x26, 0x35, 0x34, 0x37, 0x36, 0x37, 0x36, 0x37, 0x01, + 0x00, 0x10, 0x11, 0x15, 0x11, 0x1a, 0x0d, 0x12, 0x22, 0x3b, 0x46, 0x3b, 0x22, 0x12, 0x0d, 0x1a, + 0x11, 0x15, 0x11, 0x10, 0x01, 0x03, 0x10, 0x10, 0x14, 0x0e, 0x0f, 0x31, 0x48, 0x31, 0x0f, 0x0e, + 0x14, 0x10, 0x10, 0x01, 0x70, 0x12, 0x15, 0x19, 0x19, 0x27, 0x1a, 0x27, 0x1f, 0x22, 0x3b, 0x23, + 0x23, 0x3b, 0x22, 0x1f, 0x27, 0x1a, 0x27, 0x19, 0x19, 0x15, 0x31, 0x02, 0x03, 0x13, 0x16, 0x1e, + 0x1e, 0x21, 0x12, 0x23, 0x32, 0x32, 0x23, 0x12, 0x21, 0x1e, 0x1e, 0x16, 0x13, 0x00, 0x00, 0x03, + 0x00, 0x00, 0xff, 0xea, 0x01, 0xd6, 0x01, 0x80, 0x00, 0x0e, 0x00, 0x17, 0x00, 0x24, 0x00, 0x00, + 0x01, 0x32, 0x16, 0x1d, 0x01, 0x16, 0x14, 0x06, 0x22, 0x26, 0x34, 0x37, 0x35, 0x34, 0x36, 0x17, + 0x22, 0x06, 0x1d, 0x01, 0x33, 0x35, 0x34, 0x26, 0x27, 0x07, 0x15, 0x33, 0x07, 0x17, 0x23, 0x35, + 0x23, 0x37, 0x17, 0x06, 0x07, 0x01, 0x95, 0x12, 0x19, 0x15, 0x25, 0x35, 0x26, 0x16, 0x19, 0x11, + 0x08, 0x0d, 0x2b, 0x0d, 0x9e, 0x6b, 0x98, 0x02, 0x02, 0xc2, 0x40, 0xd5, 0x5e, 0x10, 0x09, 0x01, + 0x15, 0x19, 0x11, 0x91, 0x13, 0x37, 0x25, 0x25, 0x37, 0x13, 0x91, 0x11, 0x19, 0x15, 0x0d, 0x08, + 0x16, 0x16, 0x08, 0x0d, 0x47, 0x60, 0xa7, 0x15, 0x16, 0xab, 0xc0, 0x54, 0x0f, 0x15, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x01, 0xee, 0x01, 0x56, 0x00, 0x3e, 0x00, 0x52, 0x00, 0x65, 0x00, 0x77, + 0x00, 0x00, 0x25, 0x2e, 0x01, 0x2f, 0x01, 0x36, 0x37, 0x35, 0x06, 0x07, 0x06, 0x22, 0x27, 0x26, + 0x27, 0x15, 0x16, 0x17, 0x07, 0x0e, 0x01, 0x07, 0x06, 0x17, 0x16, 0x17, 0x16, 0x37, 0x36, 0x37, + 0x36, 0x27, 0x37, 0x16, 0x17, 0x15, 0x0e, 0x01, 0x15, 0x14, 0x17, 0x16, 0x33, 0x32, 0x37, 0x36, + 0x35, 0x34, 0x26, 0x27, 0x35, 0x36, 0x37, 0x17, 0x06, 0x17, 0x16, 0x17, 0x16, 0x37, 0x36, 0x37, + 0x36, 0x25, 0x06, 0x07, 0x06, 0x07, 0x06, 0x27, 0x26, 0x37, 0x36, 0x3f, 0x01, 0x36, 0x37, 0x36, + 0x17, 0x16, 0x17, 0x16, 0x07, 0x17, 0x22, 0x27, 0x26, 0x2f, 0x01, 0x37, 0x36, 0x37, 0x36, 0x32, + 0x17, 0x16, 0x1f, 0x01, 0x07, 0x06, 0x07, 0x06, 0x37, 0x06, 0x27, 0x26, 0x2f, 0x01, 0x34, 0x37, + 0x36, 0x37, 0x36, 0x17, 0x16, 0x1f, 0x01, 0x16, 0x07, 0x06, 0x01, 0xe1, 0x03, 0x11, 0x0c, 0x09, + 0x10, 0x0d, 0x23, 0x33, 0x3b, 0x88, 0x3b, 0x33, 0x23, 0x0d, 0x10, 0x09, 0x0c, 0x11, 0x03, 0x0c, + 0x03, 0x04, 0x24, 0x18, 0x15, 0x1e, 0x12, 0x07, 0x10, 0x09, 0x1a, 0x20, 0x0a, 0x0b, 0x0b, 0x10, + 0x25, 0x19, 0x10, 0x17, 0x0b, 0x0a, 0x20, 0x1a, 0x09, 0x10, 0x07, 0x12, 0x1e, 0x15, 0x18, 0x23, + 0x05, 0x03, 0xfe, 0x8f, 0x04, 0x03, 0x09, 0x0a, 0x0e, 0x0e, 0x13, 0x03, 0x02, 0x06, 0x03, 0x05, + 0x07, 0x0a, 0x0d, 0x14, 0x04, 0x02, 0x02, 0x84, 0x0e, 0x09, 0x05, 0x03, 0x01, 0x01, 0x03, 0x05, + 0x09, 0x1c, 0x09, 0x05, 0x03, 0x01, 0x01, 0x03, 0x05, 0x09, 0xac, 0x13, 0x14, 0x09, 0x06, 0x01, + 0x05, 0x06, 0x0e, 0x13, 0x0c, 0x05, 0x02, 0x05, 0x04, 0x01, 0x02, 0xcd, 0x0d, 0x16, 0x07, 0x24, + 0x05, 0x06, 0x2f, 0x13, 0x0b, 0x0d, 0x0d, 0x0b, 0x13, 0x2f, 0x06, 0x05, 0x24, 0x07, 0x16, 0x0d, + 0x31, 0x21, 0x31, 0x09, 0x06, 0x12, 0x1a, 0x48, 0x1c, 0x17, 0x25, 0x04, 0x02, 0x26, 0x09, 0x1a, + 0x0d, 0x32, 0x20, 0x2e, 0x16, 0x20, 0x4a, 0x0d, 0x1a, 0x09, 0x26, 0x02, 0x04, 0x25, 0x17, 0x1c, + 0x48, 0x1a, 0x12, 0x06, 0x09, 0x31, 0x21, 0x1a, 0x0c, 0x0c, 0x1b, 0x10, 0x16, 0x03, 0x05, 0x31, + 0x18, 0x17, 0x08, 0x09, 0x04, 0x06, 0x03, 0x05, 0x11, 0x09, 0x08, 0x6b, 0x19, 0x11, 0x1d, 0x19, + 0x08, 0x09, 0x06, 0x09, 0x09, 0x06, 0x09, 0x08, 0x19, 0x1d, 0x11, 0x19, 0x15, 0x05, 0x2d, 0x17, + 0x17, 0x08, 0x0a, 0x07, 0x0a, 0x04, 0x04, 0x0d, 0x07, 0x08, 0x18, 0x1c, 0x13, 0x1a, 0x00, 0x04, + 0xff, 0xff, 0xff, 0xea, 0x02, 0x00, 0x01, 0x6b, 0x00, 0x22, 0x00, 0x2f, 0x00, 0x3c, 0x00, 0x52, + 0x00, 0x00, 0x01, 0x35, 0x34, 0x26, 0x2b, 0x01, 0x22, 0x07, 0x26, 0x2b, 0x01, 0x22, 0x06, 0x1d, + 0x01, 0x22, 0x06, 0x1d, 0x01, 0x14, 0x16, 0x33, 0x15, 0x33, 0x35, 0x21, 0x15, 0x33, 0x35, 0x32, + 0x36, 0x3d, 0x01, 0x34, 0x26, 0x27, 0x33, 0x32, 0x16, 0x1d, 0x01, 0x06, 0x1d, 0x01, 0x23, 0x35, + 0x34, 0x36, 0x07, 0x34, 0x36, 0x3b, 0x01, 0x32, 0x16, 0x1d, 0x01, 0x23, 0x35, 0x34, 0x27, 0x05, + 0x14, 0x06, 0x23, 0x21, 0x22, 0x26, 0x3d, 0x01, 0x34, 0x36, 0x32, 0x16, 0x1d, 0x01, 0x21, 0x35, + 0x34, 0x36, 0x32, 0x16, 0x15, 0x01, 0xc0, 0x26, 0x1a, 0x55, 0x19, 0x12, 0x12, 0x19, 0x55, 0x1a, + 0x26, 0x1a, 0x26, 0x26, 0x1a, 0x2b, 0x01, 0x2a, 0x2b, 0x1a, 0x26, 0x26, 0xaf, 0x55, 0x09, 0x0c, + 0x15, 0x6b, 0x0d, 0xb7, 0x0c, 0x09, 0x55, 0x09, 0x0d, 0x6b, 0x15, 0x01, 0x6a, 0x0c, 0x09, 0xfe, + 0x80, 0x09, 0x0c, 0x0c, 0x12, 0x0c, 0x01, 0x56, 0x0c, 0x12, 0x0c, 0x01, 0x00, 0x2b, 0x1a, 0x26, + 0x11, 0x11, 0x26, 0x1a, 0x2b, 0x26, 0x1a, 0x6b, 0x1a, 0x26, 0x2a, 0x2a, 0x2a, 0x2a, 0x26, 0x1a, + 0x6b, 0x1a, 0x26, 0x40, 0x0d, 0x08, 0x3c, 0x13, 0x1c, 0x2b, 0x96, 0x08, 0x0d, 0x15, 0x08, 0x0d, + 0x0d, 0x08, 0x96, 0x2b, 0x1c, 0x13, 0x9a, 0x08, 0x0d, 0x0d, 0x08, 0x6b, 0x09, 0x0c, 0x0c, 0x09, + 0x55, 0x55, 0x09, 0x0c, 0x0c, 0x09, 0x00, 0x05, 0x00, 0x00, 0xff, 0xe8, 0x01, 0xeb, 0x01, 0x96, + 0x00, 0x08, 0x00, 0x16, 0x00, 0x1f, 0x00, 0x28, 0x00, 0x4c, 0x00, 0x00, 0x25, 0x14, 0x06, 0x22, + 0x26, 0x34, 0x36, 0x32, 0x16, 0x27, 0x15, 0x14, 0x16, 0x33, 0x15, 0x36, 0x32, 0x17, 0x35, 0x32, + 0x36, 0x3d, 0x01, 0x07, 0x22, 0x06, 0x14, 0x16, 0x32, 0x36, 0x34, 0x26, 0x21, 0x22, 0x06, 0x14, + 0x16, 0x32, 0x36, 0x34, 0x26, 0x07, 0x22, 0x27, 0x06, 0x22, 0x26, 0x27, 0x06, 0x22, 0x27, 0x0e, + 0x01, 0x22, 0x27, 0x06, 0x23, 0x22, 0x27, 0x1e, 0x01, 0x33, 0x32, 0x37, 0x15, 0x14, 0x16, 0x32, + 0x36, 0x3d, 0x01, 0x16, 0x33, 0x32, 0x36, 0x37, 0x06, 0x01, 0x40, 0x25, 0x36, 0x25, 0x25, 0x36, + 0x25, 0x80, 0x19, 0x12, 0x0b, 0x14, 0x0b, 0x12, 0x19, 0xeb, 0x1a, 0x26, 0x26, 0x35, 0x25, 0x25, + 0x01, 0x3b, 0x1b, 0x25, 0x25, 0x35, 0x26, 0x26, 0x1a, 0x16, 0x13, 0x11, 0x22, 0x1f, 0x0a, 0x11, + 0x2a, 0x11, 0x0a, 0x1f, 0x22, 0x11, 0x13, 0x16, 0x07, 0x0a, 0x11, 0x30, 0x1b, 0x2a, 0x21, 0x0c, + 0x12, 0x0c, 0x21, 0x2a, 0x1b, 0x30, 0x11, 0x0a, 0xa9, 0x1b, 0x25, 0x25, 0x35, 0x26, 0x26, 0xd2, + 0x15, 0x12, 0x19, 0x57, 0x02, 0x02, 0x57, 0x19, 0x12, 0x15, 0xc2, 0x25, 0x35, 0x26, 0x26, 0x35, + 0x25, 0x25, 0x35, 0x26, 0x26, 0x35, 0x25, 0x95, 0x08, 0x08, 0x0f, 0x0d, 0x07, 0x07, 0x0d, 0x0f, + 0x08, 0x08, 0x02, 0x15, 0x18, 0x1b, 0x30, 0x09, 0x0c, 0x0c, 0x09, 0x30, 0x1b, 0x18, 0x15, 0x02, + 0x00, 0x00, 0x00, 0x06, 0x00, 0x4e, 0x00, 0x03, 0x00, 0x01, 0x04, 0x09, 0x00, 0x01, 0x00, 0x2a, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x01, 0x04, 0x09, 0x00, 0x02, 0x00, 0x0e, 0x00, 0x2a, 0x00, 0x03, + 0x00, 0x01, 0x04, 0x09, 0x00, 0x03, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x03, 0x00, 0x01, 0x04, 0x09, + 0x00, 0x04, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x03, 0x00, 0x01, 0x04, 0x09, 0x00, 0x05, 0x00, 0x16, + 0x00, 0x38, 0x00, 0x03, 0x00, 0x01, 0x04, 0x09, 0x00, 0x06, 0x00, 0x26, 0x00, 0x4e, 0x00, 0x4d, + 0x00, 0x61, 0x00, 0x74, 0x00, 0x65, 0x00, 0x72, 0x00, 0x69, 0x00, 0x61, 0x00, 0x6c, 0x00, 0x20, + 0x00, 0x44, 0x00, 0x65, 0x00, 0x73, 0x00, 0x69, 0x00, 0x67, 0x00, 0x6e, 0x00, 0x20, 0x00, 0x49, + 0x00, 0x63, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x73, 0x00, 0x52, 0x00, 0x65, 0x00, 0x67, 0x00, 0x75, + 0x00, 0x6c, 0x00, 0x61, 0x00, 0x72, 0x00, 0x56, 0x00, 0x65, 0x00, 0x72, 0x00, 0x73, 0x00, 0x69, + 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x20, 0x00, 0x31, 0x00, 0x2e, 0x00, 0x30, 0x00, 0x4d, 0x00, 0x61, + 0x00, 0x74, 0x00, 0x65, 0x00, 0x72, 0x00, 0x69, 0x00, 0x61, 0x00, 0x6c, 0x00, 0x44, 0x00, 0x65, + 0x00, 0x73, 0x00, 0x69, 0x00, 0x67, 0x00, 0x6e, 0x00, 0x49, 0x00, 0x63, 0x00, 0x6f, 0x00, 0x6e, + 0x00, 0x73, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x26, 0x00, 0x28, 0x00, 0x02, + 0x44, 0x46, 0x4c, 0x54, 0x00, 0x0e, 0x6c, 0x61, 0x74, 0x6e, 0x00, 0x18, 0x00, 0x04, 0x00, 0x00, + 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; diff --git a/main/ui/lvgl_port.h b/main/ui/lvgl_port.h index c6f5eb2..c077414 100644 --- a/main/ui/lvgl_port.h +++ b/main/ui/lvgl_port.h @@ -4,7 +4,7 @@ #include #include "esp_err.h" -/* Calls lv_init() and creates the LVGL mutex. Must run before display_init() +/* Calls lv_init() and creates the LVGL mutex. Must run before display_start() * and touch_init(), which register themselves with LVGL. */ esp_err_t lvgl_port_init(void); diff --git a/main/ui/ui_icons.h b/main/ui/ui_icons.h index 893a38d..28fbedd 100644 --- a/main/ui/ui_icons.h +++ b/main/ui/ui_icons.h @@ -35,6 +35,9 @@ extern const size_t icon_font_data_size; #define ICON_SUNRISE "\xf3\xb0\x96\x9c" /* U+F059C */ #define ICON_SUNSET "\xf3\xb0\x96\x9b" /* U+F059B */ #define ICON_GAUGE "\xf3\xb0\x8a\x9a" /* U+F029A */ +#define ICON_TREND_UP "\xf3\xb0\x94\xb5" /* U+F0535 */ +#define ICON_TREND_DOWN "\xf3\xb0\x94\xb3" /* U+F0533 */ +#define ICON_TV "\xf3\xb0\x94\x82" /* U+F0502 */ #define ICON_SOFA "\xf3\xb1\x95\xad" /* U+F156D */ #define ICON_DINING "\xf3\xb0\xa9\xb0" /* U+F0A70 */ #define ICON_FLOOR_LAMP "\xf3\xb0\xa3\x9d" /* U+F08DD */ diff --git a/main/ui/ui_manager.c b/main/ui/ui_manager.c index d0f9be3..bb75000 100644 --- a/main/ui/ui_manager.c +++ b/main/ui/ui_manager.c @@ -109,6 +109,7 @@ static lv_obj_t *cond_icon; static lv_obj_t *temp_label; static lv_obj_t *temp_unit_label; static lv_obj_t *indoor_detail_label; +static lv_obj_t *trend_indoor_icon; /* 3x2 reading grid: value and caption per cell. */ enum { @@ -122,6 +123,8 @@ enum { }; static lv_obj_t *cell_value[CELL_COUNT]; static lv_obj_t *cell_sub[CELL_COUNT]; +/* Trend arrows; only the outdoor and pressure slots are created. */ +static lv_obj_t *cell_trend[CELL_COUNT]; static lv_obj_t *light_tile[HA_LIGHT_COUNT]; static lv_obj_t *light_icon[HA_LIGHT_COUNT]; @@ -170,6 +173,41 @@ typedef struct { } light_hold_t; static light_hold_t light_hold[HA_LIGHT_COUNT]; +/* Slider press bookkeeping: whether the press-down command has been sent for + * the current touch, and at what percentage, so the release command can be + * skipped when the finger never moved. */ +static bool slider_touched[HA_LIGHT_COUNT]; +static int32_t slider_sent_pct[HA_LIGHT_COUNT]; + +/* + * One-shot "repair" repaint, rescheduled by every interaction to fire 600ms + * after the last one. + * + * Redrawing is itself what glitches the panel: the flush's PSRAM writes + * contend with the LCD's scan-out, and a burst of interactive redraws is the + * most likely moment for the bounce ISR to lose (README, PSRAM bandwidth). + * The glitched lines then persist because LVGL believes those pixels are + * fine. One full repaint after the burst settles cleans them up within + * ~0.6s instead of leaving them until the next poll's repaint, up to 60s + * away. It runs once per burst, not periodically -- a constant repaint loop + * would be a constant supply of fresh glitch opportunities. + */ +static lv_timer_t *repair_timer; + +static void repair_timer_cb(lv_timer_t *t) +{ + lv_obj_invalidate(lv_screen_active()); + lv_timer_pause(t); +} + +static void schedule_repair(void) +{ + if (repair_timer != NULL) { + lv_timer_reset(repair_timer); + lv_timer_resume(repair_timer); + } +} + /* --------------------------------------------------------- condition icons */ typedef struct { @@ -284,6 +322,32 @@ static lv_obj_t *icon_create(lv_obj_t *parent, const char *glyph, return l; } +/* + * Trend arrow: up warm, down blue, nothing for flat or unknown. "No arrow" + * covers both "steady" and "not enough history yet" -- a reading that is + * going nowhere and a reading we cannot judge should both look calm. + */ +static void trend_render(lv_obj_t *icon, ha_trend_t t) +{ + if (icon == NULL || icon_font_16 == NULL) { + return; + } + + switch (t) { + case HA_TREND_RISING: + label_set_if_changed(icon, ICON_TREND_UP); + lv_obj_set_style_text_color(icon, lv_color_hex(COL_ACCENT_WARM), LV_PART_MAIN); + break; + case HA_TREND_FALLING: + label_set_if_changed(icon, ICON_TREND_DOWN); + lv_obj_set_style_text_color(icon, lv_color_hex(COL_ACCENT), LV_PART_MAIN); + break; + default: + label_set_if_changed(icon, ""); + break; + } +} + /* ------------------------------------------------------------ light tiles */ static void light_tile_update(int idx, const ha_light_status_t *st); @@ -341,6 +405,7 @@ static void light_tile_clicked(lv_event_t *e) : -1, }; light_apply_optimistic(idx, expect); + schedule_repair(); /* -1: a tap is on/off only. Brightness is the slider's job, and sending * the current brightness here would fight a user who dimmed the light @@ -348,6 +413,68 @@ static void light_tile_clicked(lv_event_t *e) light_cb(idx, turn_on, -1); } +/* One command for a slider position. Dragging to zero means off, not "on at + * zero brightness" -- HA accepts brightness 0 but leaves the light on, which + * looks like a bug. */ +static void light_send_pct(int idx, int32_t pct) +{ + if (pct <= 0) { + light_apply_optimistic(idx, (ha_light_status_t){ HA_LIGHT_OFF, -1 }); + light_cb(idx, false, -1); + } else { + const int16_t brightness = (int16_t)((pct * 255) / 100); + light_apply_optimistic(idx, (ha_light_status_t){ HA_LIGHT_ON, brightness }); + light_cb(idx, true, brightness); + } + slider_sent_pct[idx] = pct; +} + +/* + * Fires as the knob moves under a finger (programmatic set_value does not + * raise VALUE_CHANGED, so this is user input only). Two jobs: + * + * - keep the tile's readout live under the finger ("On 43%" tracks the + * drag), because the screen must follow the finger, never the light; + * - send ONE command at the first touch position, so the light comes on + * at the level the finger landed on without waiting for the lift. + * + * Everything between first touch and lift is display-only. + */ +static void light_slider_changed(lv_event_t *e) +{ + const int idx = (int)(intptr_t)lv_event_get_user_data(e); + if (idx < 0 || idx >= HA_LIGHT_COUNT) { + return; + } + + lv_obj_t *slider = lv_event_get_target_obj(e); + const int32_t pct = lv_slider_get_value(slider); + + char buf[24]; + if (pct <= 0) { + snprintf(buf, sizeof(buf), "Off"); + } else { + snprintf(buf, sizeof(buf), "On %d%%", (int)pct); + } + label_set_if_changed(light_state[idx], buf); + lv_obj_set_style_text_color(light_state[idx], + lv_color_hex(pct > 0 ? COL_ON : COL_TEXT_DIM), + LV_PART_MAIN); + + schedule_repair(); + + if (light_cb == NULL || !lv_obj_has_state(slider, LV_STATE_PRESSED)) { + return; + } + + if (!slider_touched[idx]) { + slider_touched[idx] = true; + light_send_pct(idx, pct); + } +} + +/* Finger lifted: send the final position -- unless the finger never moved + * from where the press-down command already put it. */ static void light_slider_released(lv_event_t *e) { const int idx = (int)(intptr_t)lv_event_get_user_data(e); @@ -358,17 +485,16 @@ static void light_slider_released(lv_event_t *e) lv_obj_t *slider = lv_event_get_target_obj(e); const int32_t pct = lv_slider_get_value(slider); - /* Dragging to zero means off, not "on at zero brightness" -- HA accepts - * brightness 0 but leaves the light on, which looks like a bug. */ - if (pct <= 0) { - light_apply_optimistic(idx, (ha_light_status_t){ HA_LIGHT_OFF, -1 }); - light_cb(idx, false, -1); - return; + const bool touched = slider_touched[idx]; + slider_touched[idx] = false; + + schedule_repair(); + + if (touched && pct == slider_sent_pct[idx]) { + return; /* tap without drag: the press command already said this */ } - const int16_t brightness = (int16_t)((pct * 255) / 100); - light_apply_optimistic(idx, (ha_light_status_t){ HA_LIGHT_ON, brightness }); - light_cb(idx, true, brightness); + light_send_pct(idx, pct); } static void light_tile_build(lv_obj_t *parent, int idx, int32_t w, int32_t h) @@ -430,11 +556,15 @@ static void light_tile_build(lv_obj_t *parent, int idx, int32_t w, int32_t h) lv_obj_set_style_pad_all(s, 2, LV_PART_KNOB); /* - * RELEASED only: the command is sent when the finger lifts, once. - * VALUE_CHANGED fires per pixel of drag and would queue a command - * storm; it is also why ui_update never writes to a pressed slider - * -- nothing may move the knob out from under the finger. + * Two commands per touch, not per pixel: VALUE_CHANGED sends one at + * the first touch position (light responds immediately where the + * finger lands), RELEASED sends the final position. In between, the + * drag only updates the display -- and ui_update never writes to a + * pressed slider, so nothing moves the knob out from under the + * finger. */ + lv_obj_add_event_cb(s, light_slider_changed, LV_EVENT_VALUE_CHANGED, + (void *)(intptr_t)idx); lv_obj_add_event_cb(s, light_slider_released, LV_EVENT_RELEASED, (void *)(intptr_t)idx); light_slider[idx] = s; @@ -492,7 +622,11 @@ static void light_tile_update(int idx, const ha_light_status_t *st) const int32_t pct = (on && st->brightness >= 0) ? (st->brightness * 100 + 127) / 255 : 0; - lv_slider_set_value(light_slider[idx], pct, LV_ANIM_OFF); + /* Never move a knob a finger is holding -- the optimistic apply on + * press-down lands here while the drag is still in progress. */ + if (!lv_obj_has_state(light_slider[idx], LV_STATE_PRESSED)) { + lv_slider_set_value(light_slider[idx], pct, LV_ANIM_OFF); + } /* Bright knob only while the light is on, so the lit tiles are what * draw the eye along the row. */ @@ -601,6 +735,11 @@ static void build_body(lv_obj_t *scr) temp_unit_label = label_create(card, "°F", &lv_font_montserrat_20, COL_TEXT_DIM); lv_obj_align_to(temp_unit_label, temp_label, LV_ALIGN_OUT_RIGHT_TOP, 4, 8); + /* Unit sits high beside the number; the trend arrow sits low, so the + * pair reads as one annotated figure. */ + trend_indoor_icon = icon_create(card, "", icon_font_26, COL_TEXT_DIM); + lv_obj_align_to(trend_indoor_icon, temp_label, LV_ALIGN_OUT_RIGHT_BOTTOM, 8, -4); + indoor_detail_label = label_create(card, "--", &lv_font_montserrat_16, COL_TEXT_DIM); lv_obj_align(indoor_detail_label, LV_ALIGN_BOTTOM_LEFT, 0, 0); @@ -641,6 +780,12 @@ static void build_body(lv_obj_t *scr) cell_value[i] = label_create(cell, NO_VALUE, &lv_font_montserrat_24, COL_TEXT); lv_obj_align(cell_value[i], LV_ALIGN_LEFT_MID, 0, 4); + /* Only readings with a meaningful hourly drift get an arrow slot. */ + if (i == CELL_OUTDOOR || i == CELL_PRESSURE) { + cell_trend[i] = icon_create(cell, "", icon_font_16, COL_TEXT_DIM); + lv_obj_align_to(cell_trend[i], cell_value[i], LV_ALIGN_OUT_RIGHT_MID, 6, 0); + } + cell_sub[i] = label_create(cell, "", &lv_font_montserrat_12, COL_TEXT_DIM); lv_obj_align(cell_sub[i], LV_ALIGN_BOTTOM_LEFT, 0, 0); } @@ -709,7 +854,10 @@ static void update_body(const ha_data_t *d) snprintf(buf, sizeof(buf), NO_VALUE); } label_set_if_changed(temp_label, buf); + /* Both hang off the number, whose width just changed with its digits. */ lv_obj_align_to(temp_unit_label, temp_label, LV_ALIGN_OUT_RIGHT_TOP, 4, 8); + trend_render(trend_indoor_icon, d->trend_indoor); + lv_obj_align_to(trend_indoor_icon, temp_label, LV_ALIGN_OUT_RIGHT_BOTTOM, 8, -4); if (d->indoor_humidity.valid) { snprintf(buf, sizeof(buf), "%.0f%% humidity", d->indoor_humidity.value); @@ -725,6 +873,9 @@ static void update_body(const ha_data_t *d) snprintf(buf, sizeof(buf), NO_VALUE); } label_set_if_changed(cell_value[CELL_OUTDOOR], buf); + trend_render(cell_trend[CELL_OUTDOOR], d->trend_outdoor); + lv_obj_align_to(cell_trend[CELL_OUTDOOR], cell_value[CELL_OUTDOOR], + LV_ALIGN_OUT_RIGHT_MID, 6, 0); if (d->outdoor_humidity.valid && d->dew_point_f.valid) { snprintf(sub, sizeof(sub), "%.0f%% dew %.0f°", @@ -783,6 +934,9 @@ static void update_body(const ha_data_t *d) /* Pressure */ format_value(&d->pressure_inhg, "%.2f", buf, sizeof(buf)); label_set_if_changed(cell_value[CELL_PRESSURE], buf); + trend_render(cell_trend[CELL_PRESSURE], d->trend_pressure); + lv_obj_align_to(cell_trend[CELL_PRESSURE], cell_value[CELL_PRESSURE], + LV_ALIGN_OUT_RIGHT_MID, 6, 0); label_set_if_changed(cell_sub[CELL_PRESSURE], "inHg"); } @@ -936,6 +1090,12 @@ void ui_init(void) lv_obj_set_flex_flow(scr, LV_FLEX_FLOW_COLUMN); lv_obj_remove_flag(scr, LV_OBJ_FLAG_SCROLLABLE); + /* Created paused; interactions reset-and-resume it. See schedule_repair. */ + repair_timer = lv_timer_create(repair_timer_cb, 600, NULL); + if (repair_timer != NULL) { + lv_timer_pause(repair_timer); + } + build_header(scr); build_body(scr); build_lights(scr); diff --git a/sim/sim_main.c b/sim/sim_main.c index a307361..da37e1e 100644 --- a/sim/sim_main.c +++ b/sim/sim_main.c @@ -233,6 +233,24 @@ static void apply_mock_data(void) sim_data.lights[0].brightness = 178; /* 70% */ sim_data.lights[4].state = HA_LIGHT_UNAVAILABLE; + /* + * Synthetic trend history: an "hour-old" anchor per channel so the + * arrows render in the mock. Unsigned tick arithmetic makes now-55min + * safe even seconds after boot. Snapshot mode gets no history and shows + * no arrows -- which is exactly what a freshly booted device does. + */ + const uint32_t now = lv_tick_get(); + const uint32_t hour_ago = now - 55u * 60u * 1000u; + ha_trend_feed(HA_TREND_CH_INDOOR, 77.1f, hour_ago); /* -> rising */ + ha_trend_feed(HA_TREND_CH_INDOOR, 78.1f, now); + ha_trend_feed(HA_TREND_CH_OUTDOOR, 74.6f, hour_ago); /* -> falling */ + ha_trend_feed(HA_TREND_CH_OUTDOOR, 73.0f, now); + ha_trend_feed(HA_TREND_CH_PRESSURE, 29.95f, hour_ago); /* -> falling */ + ha_trend_feed(HA_TREND_CH_PRESSURE, 29.89f, now); + sim_data.trend_indoor = ha_trend_compute(HA_TREND_CH_INDOOR, 0.5f, now); + sim_data.trend_outdoor = ha_trend_compute(HA_TREND_CH_OUTDOOR, 0.5f, now); + sim_data.trend_pressure = ha_trend_compute(HA_TREND_CH_PRESSURE, 0.02f, now); + static const char *const days[HA_FORECAST_DAYS] = { "Tue", "Wed", "Thu", "Fri", "Sat" }; static const char *const cond[HA_FORECAST_DAYS] = { "partlycloudy", "sunny", "sunny", "clear-night", "rainy" diff --git a/tools/make_icon_font.py b/tools/make_icon_font.py index 0693dac..d19ce36 100644 --- a/tools/make_icon_font.py +++ b/tools/make_icon_font.py @@ -67,7 +67,12 @@ ICONS = { "ICON_SUNSET": ["weather-sunset-down"], "ICON_GAUGE": ["gauge"], + # trend arrows for temperature / pressure readings + "ICON_TREND_UP": ["trending-up"], + "ICON_TREND_DOWN": ["trending-down"], + # light tiles (order-independent; ha_config.h references these by name) + "ICON_TV": ["television"], "ICON_SOFA": ["sofa-outline", "sofa"], "ICON_DINING": ["silverware-fork-knife", "silverware"], "ICON_FLOOR_LAMP": ["floor-lamp"],