From 569bec322fa983ec469c4dacc2920a02e05fd570 Mon Sep 17 00:00:00 2001 From: Matt Edholm Date: Wed, 13 May 2026 15:53:51 -0400 Subject: [PATCH] feat(13e6): bring up Waveshare 13.3" Spectra-6 end-to-end MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds a second panel target alongside the 7.3": - src/panels/waveshare13e6/v1/ — full epd.h impl with hardware SPI on FSPI, dual-CS dispatch (CS_M/CS_S split halves), PSRAM framebuffer for image/QR/setup-screen render paths - src/test_display_13e6.cpp + [env:test-display-13e6] — self-contained first-pixels color-bar smoke test, kept as a hardware diagnostic - [env:waveshare13e6-v1] — production env: ESP32-S3-WROOM-2 N32R16V with OPI flash + OPI PSRAM (the WROOM-2 is octal flash; QIO mode crashes at do_core_init startup.c:328) - scripts/gen_screens_13e6.py + data/waveshare13e6-v1/ — 1200x1600 portrait setup screens with QR overlay regions matching the driver - scripts/data_dir.py — extra_scripts shim that routes uploadfs to the right data/ tree based on $PIOENV (PlatformIO ignores per-env data_dir) - src/epd.h: epd_setup_pins() abstraction so each panel driver owns its own pinMode + SPI.begin; main/test_display/sim_border lose all panel-specific GPIO and call epd_setup_pins() once at boot - src/operation.h: report PANEL_ID via X-Panel-Id header on every poll so the server can auto-correct Device.model 7.3" production env stays byte-identical, all 43 native tests pass. Co-Authored-By: Claude Opus 4.7 (1M context) --- data/waveshare13e6-v1/ap_bg.bin | 1 + data/waveshare13e6-v1/ap_bg_preview.png | Bin 0 -> 16289 bytes data/waveshare13e6-v1/ap_bg_retry.bin | 1 + data/waveshare13e6-v1/ap_bg_retry_preview.png | Bin 0 -> 16162 bytes data/waveshare13e6-v1/setup_bg.bin | 1 + data/waveshare13e6-v1/setup_bg_preview.png | Bin 0 -> 18916 bytes platformio.ini | 70 +++- scripts/data_dir.py | 33 ++ scripts/gen_screens_13e6.py | 225 +++++++++++ src/epd.h | 7 + src/main.cpp | 13 +- src/operation.h | 7 + src/panels/waveshare13e6/v1/epd_driver.cpp | 382 ++++++++++++++++++ src/panels/waveshare13e6/v1/version.h | 6 + src/panels/waveshare73/v1/epd_driver.cpp | 9 + src/sim_border.cpp | 8 +- src/test_display.cpp | 7 +- src/test_display_13e6.cpp | 215 ++++++++++ test/mocks/epd_mock.h | 1 + 19 files changed, 958 insertions(+), 28 deletions(-) create mode 100644 data/waveshare13e6-v1/ap_bg.bin create mode 100644 data/waveshare13e6-v1/ap_bg_preview.png create mode 100644 data/waveshare13e6-v1/ap_bg_retry.bin create mode 100644 data/waveshare13e6-v1/ap_bg_retry_preview.png create mode 100644 data/waveshare13e6-v1/setup_bg.bin create mode 100644 data/waveshare13e6-v1/setup_bg_preview.png create mode 100644 scripts/data_dir.py create mode 100644 scripts/gen_screens_13e6.py create mode 100644 src/panels/waveshare13e6/v1/epd_driver.cpp create mode 100644 src/panels/waveshare13e6/v1/version.h create mode 100644 src/test_display_13e6.cpp diff --git a/data/waveshare13e6-v1/ap_bg.bin b/data/waveshare13e6-v1/ap_bg.bin new file mode 100644 index 0000000..13cc126 --- /dev/null +++ b/data/waveshare13e6-v1/ap_bg.bin @@ -0,0 +1 @@ +""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""03"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""32""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""#2"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""#0"""""""""""""""""""""""""""""""""#2""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""2""""""""#""""2""""""""""""" """""""""""""""""""""3""""""""" """"""""""""""""""""""""""""""""""""""""""""""""""""""""" 2"" " """ """""""""""""""""0"""""""""""""""""" 2"""""" """""""""""#"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""02""""2""""""""#"""""""""""""""" """"""#""""""""""""""""""" """"""""""""""""""""""""""""""""""""""""""""""""""""""""#"" " """ """"""""""""""0""""""""""""""""" 2""""" """"""""""#"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""#2""""2""""""""#""""""""""""""" 2""""" """""0""""""""""" """"""""""""""""""""""""""""""""""""""""""""""""""""""""0"" " """ """""""""""" """"""""""""""""#""""" """"""""""#"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""02""""2""""""""#""""""""""""""" """"" """"#"""""2""""" """""""""""""""""""""""""""""""""""""""""""""""""""""""#"" " """ """"""""""" """"""""""""""""0"""" """"""""""#""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""2""""2""""""""#"""""""""""""" """""""""0""""""""" """"""""""""""""""""""""""""""""""""""""""""""""""""""" "" " """ """"""""""" """""""""""""""#"""" """"""""""#""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""2"""32""""2""""""""#"""""""""""""" """""""""""0"""""""" """"""""""""""""""""""""""""""""""""""""""""""""""""""" """#0"" " """ """"""""""" """"""""""""""" ""#2""" """"""""""#""#"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""#""""""0""""""""""""""""""" """"""""""""#"""""""#"""""""""" """"#""" """""""""""#"""" """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""0""""""#""""""""""""""" """""""""" """0"""""""""" 20""""""""""""""""""" """ """""""""""""""""#2"""" """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" """""""""""""""""""""""""" """"""""""""#"""""""" """""""""" """ """ """"" 2"""""""#"""" """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" """""""""" """""""""""""" 2""0""""""""""""""""""""""" """""""""""""""""#2"""""#2"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" """""""""""""""""""""""""" """"""""""""#""""""""#"""""""""" """0""""""""""""""""" 2""" """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" """""""""" """"0""""""""""""""0"""""""""""""" 2""""" """ """""""""""""""""""""""""2"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" """""""""""""""""""""""""" """"""""""""#""""""""""""""""""" """0"""""""""0"""""""""""" """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" """""""""" """" """"""""""""""0"""""""""""""" """"""#""" """""""""""""""""""""""""2"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" 2""""""""""""""""""""""""" """"""""""""#"""""""""2""""""""" """ """2"""""" """""""""0""" """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" """""""""" """" """"""""""""""0"""""""""""""" """""""2"" """""""""""""""""""""""""2""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""#2""""""""""""""""""""""" """"""""""""#""""""""""""""""""" 2" ""#""""""" """"""""" """ """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""03"""""""""""""""""""" """""""""" """" """"""""""""""0""""""""""""""0""""""""" """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""2"""""""""""""" """"""""""""#""""""""#"""""""""" 0"  ""#"""""""#""""""""" """ 2""""""""""""""""""""""""""""""""""""""""""""""""""""""" """""""""""""""""" 2""" """"0""""""""""""""0""""""""""""""0"""""""0"" 2"""""""""""""""""#""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" """"""""""""#"""""""" """"""""""  "0 "" """""""#"""""""""#""" 2""""""""""""""""""""""""""""""""""""""""""""""""""""""" 2"""""""""""""""" 2""" """"""""""""""""""0"""""""""""""""""""""0"" 2""""""""""""""""" """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" """""""""""" """"""""""""#"""""""#"""""""""" #"2 "" """""""#"""""""""#""" 2"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" 2""" """0""""""""""""""0"""""""""""""""""""""0"" 2"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" """"""""""""#"""""""""""""" "#" "" """""""#""""""""""""" 2"""""""""""""""""""""""""""""""""""""""""""""""""""""""" """"""""""""""" 2""" """""""""""""""0"""""""""""""""""""""0"" 2"""""""""""""""" """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""#""""""""""" """"""""""""#"""""""""""""" "0" "" """""""#""""""""""""" 2"""""""""""""""""""""""""""""""""""""""""""""""""""""""""0""""""""""""""" 2""" """""""""""""""0"""""""""""""""""""""0"" 2""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" """"""""""""#""""""""""""""" " " "" """""""#"""""""""#""" 2""""""""""""""""" """""""""""""""""""" """""""""""""" 2""" """""""""""""""0"""""""""""""""""""""0"" 2""""""""""""""" """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""#"""""""""""""""""" """"""""""""#""""""""""""""" " " ""#"""""""#"""""""""#""" """""""""""""""""""""""" """"""""""""""""""""""0"""""""""""""" """""""""" """"""""""""""""0""""""""""""""0"""""""0"" """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""#"""""""""""""""""" """"""""""""#"""""""""""""""" "#"" ""#""""""" """"""""" """ """""""""""""""""""""""" """"""""""""""""""""""""0"""""""""""""" """""""""" """""""""""""""""0""""""""""""""0""""""""" """"""""""""""""""""" """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""#2""""""""""""""""" """""""2"""" """"2""""""""""""" """" """2"""""" """"""""" """ """""""""""""""""""""""" """""""""""""""""""""""""0"""""""""""""" """""""""" """"""""""""""""""0"""""""""""""" """""""2"" """"""""""""""""""""#"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""2""""""""""""""""" """""""2"""" """"""""""""""""""""""" """" """""""""0"""""""""0""" """""""""""""""""""""""" """"""""""""""""""""""""" """""""""""""" """""""""" """""""""""""""""""""""0"""""""""""""" """"""#2"" """"""""""""""""""""0""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""02""""""""""""""""" """""""0"""" """"""""""""""""""""""" "" "" """"""""""""""""""""" """""""""""""""""""""""" """""""""""""""""""""""""#"""""""""""""" """""""""" """""""""""""""""""""""0"""""""""""""" 2""""" """ """""""""""""""""""#2"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""#2""""""""""""""""""""""""" """""""0""""0""""""""""""""""""""""" "" 2"" """ """"" 2"""""""" """ """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""3""""""" """""""""""""" """""""""" """""""""""""""""""""""0""""""""""""""""""""""" """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""#"""""""""""""""""""""""" """"""" """"""""""""""""""""""""""" ""#""" """ """"""""""""#"""" """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""0"""""" """""""""""""" """""""""" """""""""""""""""""""""0""""""""""""""""""" """ """""""""""""""""" 2""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""#2"""0"""""""""""""""""" """"""" ""02""""""""""""""""""""""" """""" """"""0"""""""#"""" """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""0"""#"""""""""""""" """""""""" """""""""""""""""""""""0""""""""""""""" ""#2""" """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""#"""""""""" """""""""""""""""""""""""""""""" """"""""" """"0"""""""" """""""""""""""""""""""""""""""""""""""""""""""""""""""02"""""""""""""" """ """"""""""""""""""" """""""""""#"""" """""""""""""""""#""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""#"""""""""" """"""""0"""""""""""""""""""""""" """"""""" """"#"""""""""" """""""""""""""""""""""""""""""""""""""""""""""""""""""0""""""""""""""" """ """"""""""""""""""" """"""""""""0"""" """""""""""""""""#""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""#""""""""""" """""""" 2"""""""""""""""""""""""" """"""""" """""0"""""2""""" """""""""""""""""""""""""""""""""""""""""""""""""""""""0""""""""""""""" """ """"""""""""""""""" """"""""""""#""""" """""""""""""""""#""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""#""""""""""" """""""""0""""""""""""""""""""""""" """"""""" """""""""""""""""" """""""""""""""""""""""""""""""""""""""""""""""""""""""0"""""""""""""""" """ """"""""""""""""""" """"""""""""" 2""""" """""""""""""""""#"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""#"""""""""""" """""""""""""""""""""""""""""""""""" """"""""" """"""""""""""""""""" """"""""""""""""""""""""""""""""""""""""""""""""""""""""02"""""""""""""""" """ """"""""""""""""""" """""""""""""" 2"""""" """""""""""""""""#"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""#02""""""""""""" """""""""""#2""""""""""""""""""""""""""" """"""""" """"""""32""""""""3""""""""" """"""""""""""""""""""""""""""""""""""""""""""""""""""""""3"""""""""""""""""" """ """"""""""""""""""" """""""""""""""#0"""""""" """""""""""""""""#""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""`faf```a`aaa``aa```a`aaa`aaaa``aaaaa`a``a`a`a``a``aa`aa```a``a`aaf""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""`aaaa`a`a``aaaa``a`````aa```f`aa`a``a`a`a`a``aa`````aa``a```aa`aaa`a``aaa`aa```a`a`a```a``a``aaa`aa`a`````aaa````aa`aa`afa``aa`a`a``aa```aa`a```a`a``aa``a`f`aa`fa`a`a`faaaa````aa`a`a`aaaaafaaa`aaaaa`aaa```aaaa`a`aaaa`aa``aa`a``aaa`aaaa`aa``a```aa`a`a`a``a`f""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""!""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""!""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""!""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""!""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""!""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""!""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""!""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""!""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""!""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""!""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""!""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""!`a`af``afa``afaa``afaa`aaaa`a`aa`aa``aaaaa`a``a``aa`a`````a``aaaaa````aa`a````a`aaa`aaaaa`a``a`a`aaa`aa`aaa`a``aa``````a```a````a`a`a``a \ No newline at end of file diff --git a/data/waveshare13e6-v1/ap_bg_preview.png b/data/waveshare13e6-v1/ap_bg_preview.png new file mode 100644 index 0000000000000000000000000000000000000000..293004d5b08be3cb01cee5b32e4d444453e890c1 GIT binary patch literal 16289 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 literal 0 HcmV?d00001 diff --git a/data/waveshare13e6-v1/ap_bg_retry.bin b/data/waveshare13e6-v1/ap_bg_retry.bin new file mode 100644 index 0000000..496beed --- /dev/null +++ b/data/waveshare13e6-v1/ap_bg_retry.bin @@ -0,0 +1 @@ +33333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333303333333333333333333333333333333333333333333333333333333333333333330333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333303330333333333333333303333333333303333330333333333333333303333333033333330333033333333303330333333333333333333333333333333333333333333333333333333333333333333333333330333333333333303333333333303333333330333333303330333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333330333033333333333333303333333330333333033333333333333330333333303333333033303333333330333033333333333333333333333333333333333333333333333333333333333333330333333333333333333303333333333033333330333333303330333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333330333330333333333033303333333333333333333333333333303333333333333333033333333333333033303333333330333033333333333333333333333333333333333333333333333333333333333333303333333333333333333333333333033333333333333033303333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333330333333333033303333333333333303333333333330333333333333333303333333333333303330333333333033303333333333333333333333333333333333333333333333333333333333333333330333333333333333333333333333333333333303330333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333303333033333333033303333333333333333333333333033333333333333303333330333333033303333333330333033333333333333333333333333333333333333333333333333333333333330333333333333333330333333303333330333333033303333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333330333333333333330333033333333333303333333333033033303333333333333330333333033333303330333333333033303333333333333333333333333333333333333333333333333333333333333033333333333333333033333333333333333033333303330333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333330333333333033333333333033303333333333333333333333330333333033333333333333303330333333333333333033333333333330333333033303333333330333333333303333333333333333333333333333333333333333333333333333333333333330333333333303333330333333333333330333333033333303333330333333033303333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333303333333333033333033333303330333333333333333333333333333333333033333333333333333330333333333333333033333333333333333330333033333333303333333333033330333333333333333333333333333333333333333333333333333333333330333333333333333033333333333333333333330333333333333333333330333033333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333330333033333333333333333033333333333333033333333330333333033303333333333333303333333333333333333033303333333330333333333303333333333333333333333333333333333333333333333333333333333333333033333333333333303333333333333333333333333333333333333333333303330333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333033333303330333333333333333330333333333333333033333333330333333333303333333333333303333333333333033333303330333333333033333333330333330333333333333333333333333333333333333333333333333333333333330333333333330333330333333333333333033333333333333333333330333333033303333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333033333033303333333333333333303333333333333330333333333303333333330333333333333330333333333333003333303330333333333033333333330333330333333333333333333333333333333333333333333333333333333333330333333333330333333333333333333300333333333333333333330033333033303333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333303330330333033333333333333333033333333333333303333333333033333333303333333333333303333333333330033333033303333333330333333333303333333333333333333333333333333333333333333333333333333333333333033333333333333330333333333333330033333333333333333333300333330333033333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333303333333333303333333033303303330333333333333333333333333033333333333333333330333333333333303333333333330333033333333303330333333333333333333333333333333333333333333333333333333333333333303333333333333333333333333333333333333330333333333333333333333330333033333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333033333333333033333333333333033300333333333333333333333333033333333333333333033003333333333333033333333333303330333333333033303333333333333333333333333333333333333333333333333333333333333333033333333330333333333333333333333333333303333333333333333333333303330033333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333033333333333033333333333330333003333333333333333333333330333333333333333330330033333333333330333333333333033303333333330333033333303333333333333333333333333333333333333333333333333333333333033333333333333033333333333333333333303333033333333333303330033333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333033333333333033333333333303033303333333333333333333333330333333333333333330330333333333333303333033033330333033333333303330333333033333333333333333333333333333333333333333333333333333333330333333333333333333333333333333303303330333303333033033330333033333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333033333333333033333333333303033303333333333333333333333330333333333333333330330333333333333303333033033330333033333333303330333333033333333333333333333333333333333333333333333333333333333330333333333333333333333333333333330330333033330333303303333033303333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333303333333333303333333333333033303033333333333333333333333033333333333333333033030333333333333033330333333303330333333333033303333330333333333333333333333333333333333333330333333333333333330333333333333333033333303333033330333333303330303333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333033333333333033333330333330333030333333333333333333333333333333033333333333333333330303333333333330333333333333333333303330333333333033333333330333333333333333333333333333333333333333333330333333333333333333333333333333333333333303333033333333333303330303333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333330333330033303333333333333333033333333333333303333333333033333333303333333333333033333333333333333330333033333333303333333333033333333333333333333333333333333333333333333033333333333333333333333333333333333333333333303333333333330333033333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333303333300333033333333333333330333333333333333033333333330333333333033333333333330333333333303330333033333333303333333333033333333333333333333333333333333333333333333033333333303333333333333333333333330333333333333033303330333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333330333333333033033333333333333033333333333333303333333333033333333330330333333333330333333333303330333033333333303333333333033333033333333333333333333333333333333333333303333333333033333333333333333333333303333333333330333033303303333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333330330333333333333330333333333333330333333333303333330333033033333333333033333333330333033303333333330333333333303333303333333333333333333333333333333333333330333333333303333333333333333333333330333333333333033303330330333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333303333333333033333033333303330333333333333333333333333333333330333333333333333333303333333333333303333333333333033303333333330333333333303333333333333333333333333333333333333333333333333333333333333333033333333333333333333333333333333333330333333333330333033333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333330333333333033333333333333303330333333333333333333330333333033333333333333303330333033333333333033333333333330333033333333303333333333033330333333333333333333333333333333333333333333333333333333333330333333333333333333333333333333333333303333333333303330333033333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333033333333333333333033303333333333333330333333333033333333333033033303330333333333330333333333333303330333333333033333333330333333333333333333333333333333333333333333333333333333333333333033333333333033333333333333333333333333333333333330333033303333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333303333033333333033303333333333333333330333333333333333303333333333333330333333333033333303303330330333033333333333333333333333333333333333333333333333333333333333303333333333303333333333333333333333033333303330330333333033033303333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333303333333330333033333333333303333330333333333333333303333333333333330333333333033333303303330330333033333333333333333333333333333333333333333333333333333333333303333333333333333333333333333333330333333033333303333330330333033333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333330333330333333333333303333033333333333333303333333333333333330333303333333333303333333330333333033033303303330333333333333333333333333333333333333333333333333333333333333303333333333333333333333333333333330333333033330330333333033033303333033333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333303333033333333303333330333333333333303333330333303333333333303333333333333333333033303303330333333333333333333333333333333333333333333333333333333333333330333333333333033333333333333333333333333333333333333333333330333033330333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333033303333333333333330333333303333333333333303333330333333333333333303333333333333333333033303303330333333333333333333333333333333333333333333333333333333333333333033333333333303333333333333333333333333333333333333333333333333033303333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333033333333333333033303333333333333333303333333330333333333333333333333333033333333333333330333333330333333333033303303330333333333333333333333333333333333333333333333333333333333333333330333333333333333333333333333333330333333333333333333330333333333033303333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333`faf```a`aaa``aa```a`aaa`aaaa``aaaaa`a``a`a`a``a``aa`aa```a``a`aaf333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333``aaaaa`a`a`aa`aa````a``a`````a``a`a```a```a`aaa`aaa`aa``a```a`a````````a`a```a`a`a`a``a``a`a`a``a```a````a`aa`a`aa`a`a`a``a`a``aa````a`a`a``a`a`a`a``````a`a```aa```aa`aa`aa`aaa`````a`a`a```aa`a```fa`a`aa`f```a`a``af```fa`a`a`faaaa````aa`a`a`aaaaafaaa`aaaaa`aaa```aaaa`a`aaaa`aa``aa`a``aaa`aaaa`aa``a```aa`a`a`a``a`f333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333133333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333313333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333331333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333133333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333313333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331331333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333133333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333313333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333331333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333133333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333313333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333331`a`af``afa``afaa``afaa`aaaa`a`aa`aa``aaaaa`a``a``aa`a`````a``aaaaa````aa`a````a`aaa`aaaaa`a``a`a`aaa`aa`aaa`a``aa``````a```a````a`a`a``a \ No newline at end of file diff --git a/data/waveshare13e6-v1/ap_bg_retry_preview.png b/data/waveshare13e6-v1/ap_bg_retry_preview.png new file mode 100644 index 0000000000000000000000000000000000000000..f67a218c2a1179ee077413c3257a3bc3dce758df GIT binary patch literal 16162 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 literal 0 HcmV?d00001 diff --git a/data/waveshare13e6-v1/setup_bg.bin b/data/waveshare13e6-v1/setup_bg.bin new file mode 100644 index 0000000..4b597dc --- /dev/null +++ b/data/waveshare13e6-v1/setup_bg.bin @@ -0,0 +1 @@ +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffafffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffafffffffffffffffffffffffffffffffffffffffffffffffffffffaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffafffffffffffffffffffffffffffffffffffffffffffffffffffafffaffffffffffffffffafffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaffafafffaffffffffffffffafffffffffffffffffaffffffafffffffffffaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaffffafffffffffffffffffffffffffffffffffffffffffffffffafffafffffffffffffffafffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaffafafffaffffffffffffffffffffffffffffaffffffaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaffffafffffffffffffffffffffffffffffafffffafffffffffafffafffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffafafffaffffffffffffffffffffffffffffffffaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaffffffffaffffffffffffffffffffffffffffafffffffffafffaffffffffffffffafffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffafafffaffffffffffffffffffffffffffffafffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaffffffffafffffffffffffffffffffffaffffaffffffffafffafffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaffafafffaffffffffffffffffffffffffffffafffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaffffffffffffffffffffffffffaffffffffffffffafffaffffffffffffaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaffffffafafffafffffffffffffaffffffffffffaffafffafffffffffffffaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffafffffffffffffffffffffffffffffafffffffffafffffffffffafffaffffffffffffffffffffffffaffffffafffffffffffffffffffffaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaffffffffffafffaffffffffffffffaffffffffffffffffafffaffffffffffffffffffffffaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaffffffffffffffffffffffffffffffaffffffffffafffffaffffffafffafffffffffffffffffffffffffffffffffaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaffffffffffaffffffffffffffffffffffffffffffffffffffffaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaffffffffffffffffffffffffffffffffffffffffffffffffffffffffafffafffffffffffffffffaffffffffffffffafffffffffffffffffffffffaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaffffffffffaffffafffffffffffffffffffffffffffaffffffafffafffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffafffaffffffffffffffffffffffffffffffffffffffffffffffffffaffffffafffafffffffffffffffffafffffffffffffffaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaffffffffffaffffafffffffffffffffffffffffffffaffffffffffafffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaffafffffffffffffffffffffffffffffffffffffffffffffffffffafffffafffafffffffffffffffffafffffffffffffffafffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaffffffffffaffffaffffffffffffffffffffffffffffafffffffffaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaffafffffffffffffffffffffffffffffffffffffffffffffffffffffafffaffafffafffffffffffffffffafffffffffffffffaffffffffffffffffffffffffafffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaffffffffffaffffaffffffffffffffffffffffffffffafffffffffaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffafffffaffffffffffffffffffffffafffffffffffafffffffafffaffafffaffffffffffffffffffffffffafffffffffffffffffafffffffffffffffffffffffffffffffffffffffffffffffffffffffaffffffffffffffffffafffaffffafffffffffffffffffffffffffffffffffffffafffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaffaffffffffffffffffffffffafffffffffffaffffffffffffffafffaaffffffffffffffffffffffffafffffffffffffffffafffffffffffffffffffffffffffffffffffffffffffffffffffffffafffffffffffffffffafffaffffffffffffffffffffaffffffffffffffffffaffafffffffffffffffffafffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffafaffffffffffffffffffffffafffffffffffafffffffffffffafffaaffffffffffffffffffffffffaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffafffafffaffffffffffffffffffffffffffffffffffaffaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffafafffffffffffffffffffffffafffffffffffaffffffffffffafafffaffffffffffffffffffffffffaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffafffffffffffffffafffaffffffffffffffffafffffffffffffffffffaffaffffffffffffffffaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffafaffffffffffffffffffffffffafffffffffffaffffffffffffafafffaffffffffffffffffffffffffafffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffafffffffffffffffafffafffffffffffffffffffffffffffffffffffaffaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaffffffffffffffffffffffffffafffffffffffafffffffffffffafffafafffffffffffffffffffffffafffffffffffffffffffffffffffffffffffaffffffffffffffffffffaffffffffffffffafffafffffffffffffffaffffffffffffffffffffaffafffffffffffffffaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaafffffffffffffffffffffffffffffffffafffffffffffafffffffafffffafffafaffffffffffffffffffffffffffffffaffffffffffffffffffffffffafffffffffffffffffaffffffffffffffffffffffaffffffffffffffaffffffffffaffffffffffffffffffffffffffffffffffffffaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaaffffffffffffffffffffffffffffffffffffffffffffffffffffffafffffaafffaffffffffffffffffafffffffffffffffaffffffffffffffffffffffffafffffffffffffffffaffffffffffffffffffffffffaffffffffffffffaffffffffffaffffffffffffffffaffffffffffffffafffffffffafffffffffffffffffffffafffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffafffafffffffffffffffffffffffffffffffffffffffffffffffffafffffaafffaffffffffffffffffafffffffffffffffaffffffffffffffffffffffffafffffffffffffffffafffffffffffffffffffffffffaffffffffffffffaffffffffffafffffffffffffffffffffffffffffffafffffffffaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffafffaaffffffffffffffffffffffffffffffffffffffffffffffffafffffffffaffaffffffffffffffafffffffffffffffafffffffffffffffffffffffffffffffffffffffffafffffffffffffffffffffffffaffffffffffffffaffffffffffaffffffffffffffffffffffffffffffffffffaffffffffffaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffafffffffffffffffffffffffffffffffffffffffffffffffffffffffffaffaffffffffffffffaffffffffffffffafffffffffffffffffffffffffffffffffffffffffafffffffffffffffffffffffffaffffffffffffffaffffffffffaffffffffffffffffffffafffffffffffffffaffffffafffafffffffffffffffffffaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffafffffffffffffffffffffffffffffffaffffffffffafffffaffffffafffaffffffffffffffffffffffffffffffffafffffffffffffffffffffffafffffffffffffffffffffffffffffffffffffffffffffffffffffffafffffffaffffffffffffffaffffffffffafffffffffffffffffffffffffffffffffffffffffffffaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaffffffffffffffffffffffffffffffffafffffffffafffffffffffffffafffaffffffffffffffffffffaffffffafffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaffffffffffffffaffffffffffafffffffffffffffffffaffffffffffffffffffffffafffaffffffffffffffffffafffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffafffffffffffffffffafffafffffffffffffffafffffffffafffffffffffffffffffffafffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaffffffffffffffaffffffffffafffffffffffffffffffffffffffffffffffffaffafffafffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffafffffffffffffffffffffffffffffffffffffaffffaffffffffafffaffffffffffffffffffafffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffafffaffffffffffffffffffaffffffffffffffffafffffffffffffffffaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaffffffffffffffffffffffffffffffffffffffffffafffffffffafffaffffffffffffaffffffaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffafffaffffffffffffffffffaffffffffffffffffafffffffffffffffffaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffafffffffffffffffffffffffffffffffffffffffafffffafffffffffffffaffffafffffffffffffffaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffafffaffffffffffffffffffaffffffffffffffffffafffffffffffffffffaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaffffafffffffffaffffffaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaffffffffffffffffafffaffffffffffffffffffafffffffffffffaffffffafffffffffffffffffaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaffffffffffffffffffffffffffffffffffffffffffffffffffffffffafffafffffffffffffffafffffffaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaffffffffffffffffafffaffffffffffffffffffaffffffffffffffaffffffafffffffffffffffffaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaffffffffffffffffffffffffffffffffffffffffffffffffaffffffffffffffafffafffffffffffffffffafffffffffaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaffffffffffffffffffafffaffffffffffffffffffaffffffffffffffffffffffffafffffffffffffffffaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa`a`a`a`aa`aa`aaa`aa`aa`aa``aa`aaa`a`afa`faf`f`f`a`a`a``a``aaa````aaa`a`a`aa``a`aaaaa`a`aaaaa``aafa`f`aaa``aaa```a``aaaaf`aaaaaa`aaa`aa``aaaaafa`a`a`aa``aaaaaaaaaaa``aaaaaa`aaaaa`aaaa`aaaa``aaaaa`aaaaaa`aa`a``aaaa`aaaa`aaaa`a``a`a`aaf`aaaaaa```aaaa`a`aa``aaaa``a`aa`a``faf`f`fa`aa``aa``aa`a``aaa`a`f`aa``a```aaaa``a`aaa`aaaf`aaa`aaa``aaaa`````a`aa`aaa`aaaaaa``aaa`a`aaaaa`aaa`a`aaaaaaa`a`a``aaaaa`aa`a```aa`a`aaaaaa``a`a`a``a``aaaa`a``a`a`aa``a```a`a``aaa``a`aa`a``a`aa``a``aaa`afaa``a`aaa`aaffa`a``aaa`aa`a`a`a`aaaaaa``````a```aaaa`a````a`aaaa``a```aaaaa`a`a``aaaaa`a```a`aaaaa``aa`a```aaaaaa`a``a``aaaaaaaa``a````aa`aaaa`a`aaaaaaafa``aa`a``aaaaa```affaa``aa`aa``a``aa`aaaaa```aa``aaaa```a``aaaaa`a``aaa`a``aaa````aafafaa`aaaa`aaaaaaaa`a``a````aa`````aa``aa``aaa``a``a``a```a`a`aaafaa`fa`aaaa`a`a``a`a``aff``fafffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa```aa``aa`a`aaa`aa```aaa`aa`aaa`a`a`a``aa`aaa`a`a`aaaa`aaa``a```aa``aaa`aaa`````a`a`aaaa`a`aa`a```a``a``a`a`a``a`aaaa`a``a`a`a`````a``aa`aaaa`aaa`a``````a````aaaaaa`a`a``aaaaa``a````aaa`aa`````a``aa````aaaa```a`a`aa`a``a```aaa`aa````a```aaa`aaa`a```a````aa``a`aa```aaa`a```aa``a````a````a```aa`````aaaaa``a````aaa``a`a`a```aa`aaa``a`aa```aa`fa`a`aa`a`a`f` \ No newline at end of file diff --git a/data/waveshare13e6-v1/setup_bg_preview.png b/data/waveshare13e6-v1/setup_bg_preview.png new file mode 100644 index 0000000000000000000000000000000000000000..6bce5d7438a481a71e26f97e8249a4eb57adeb6d GIT binary patch literal 18916 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 N#mMY(rJ-}ge*tq>6n_8! literal 0 HcmV?d00001 diff --git a/platformio.ini b/platformio.ini index 5f33e27..26216f5 100644 --- a/platformio.ini +++ b/platformio.ini @@ -10,12 +10,13 @@ ; Old envs preserved as historical snapshots — re-flashing units in the ; field stays a one-line `pio run -e --target upload` command. -; data_dir lives at project level (PlatformIO ignores it inside [env:…] -; blocks — the silent ignore once led to a LittleFS upload that put every -; file under /waveshare73-v1/ instead of /, blanking the panel to the -; epd_fill yellow fallback). All current envs target the V1 panel; when -; a second panel ships, swap this via an extra_scripts shim that picks -; the dir from $PIOENV before uploadfs runs. +; data_dir is single project-wide in [platformio]; PlatformIO silently +; ignores it inside [env:…] blocks. To route uploadfs to the right +; LittleFS payload per panel (waveshare73-v1 vs waveshare13e6-v1), each +; env wires in scripts/data_dir.py via extra_scripts, which overrides +; PROJECT_DATA_DIR from $PIOENV before SCons evaluates uploadfs. +; The project-level default below keeps tooling that runs outside a +; specific env (e.g. raw `pio run`) pointed at the 7.3" payload. [platformio] data_dir = data/waveshare73-v1 @@ -28,6 +29,7 @@ upload_port = /dev/ttyUSB0 monitor_port = /dev/ttyUSB0 monitor_speed = 115200 board_build.filesystem = littlefs +extra_scripts = pre:scripts/data_dir.py build_src_filter = + + @@ -85,6 +87,62 @@ build_flags = -DSIM_BORDER -DSIM_BORDER_COLOR=COLOR_RED +; ── Production firmware: Waveshare 13.3" Spectra-6 + ESP32-S3-ePaper-13.3E6 ── +; All-in-one board: ESP32-S3-WROOM-2-N32R16V (32MB OPI flash, 16MB OPI PSRAM), +; CH343 USB-serial on USB-C. PIN_CS aliases CS_M only to satisfy config.h's +; required-pin check — the driver uses CS_M / CS_S explicitly, never PIN_CS. +[env:waveshare13e6-v1] +platform = espressif32 +board = esp32-s3-devkitc-1 +framework = arduino +monitor_speed = 115200 +board_build.flash_size = 32MB +board_build.flash_mode = opi +board_upload.flash_size = 32MB +board_build.arduino.memory_type = opi_opi +board_build.filesystem = littlefs +extra_scripts = pre:scripts/data_dir.py +build_src_filter = + + + + +build_flags = + -DEPD_WIDTH=1200 + -DEPD_HEIGHT=1600 + -DMAX_PANEL_WIDTH=1200 + -DPIN_SCK=9 + -DPIN_MOSI=46 + -DPIN_CS=10 + -DPIN_CS_M=10 + -DPIN_CS_S=3 + -DPIN_DC=11 + -DPIN_RST=2 + -DPIN_BUSY=12 + -DPIN_PWR=1 + -DPANEL_ID=\"waveshare-13.3-spectra6\" + -DBOARD_HAS_PSRAM +lib_deps = + ricmoo/QRCode@^0.0.1 + +; ── First-pixels smoke test for ESP32-S3-ePaper-13.3E6 ── +; Self-contained color-bar bringup, no LittleFS / no shared driver. Kept +; alongside the production env as a fallback for hardware diagnostics: +; if waveshare13e6-v1 misbehaves, this verifies the panel + SPI bus alone. +; pio run -e test-display-13e6 --target upload +[env:test-display-13e6] +platform = espressif32 +board = esp32-s3-devkitc-1 +framework = arduino +monitor_speed = 115200 +board_build.flash_size = 32MB +board_build.flash_mode = opi +board_upload.flash_size = 32MB +board_build.arduino.memory_type = opi_opi +build_src_filter = + + +build_flags = + -DENV_TEST_DISPLAY_13E6 + -DBOARD_HAS_PSRAM + ; ── Native unit tests — no hardware, uses test/mocks/ ── [env:native-test] platform = native diff --git a/scripts/data_dir.py b/scripts/data_dir.py new file mode 100644 index 0000000..cb58ddf --- /dev/null +++ b/scripts/data_dir.py @@ -0,0 +1,33 @@ +""" +Per-env data_dir multiplexer. + +PlatformIO's [platformio].data_dir is a single project-level setting — it +ignores `data_dir` inside [env:...] blocks. With more than one panel in the +tree (waveshare73-v1, waveshare13e6-v1), we need to route uploadfs to the +right LittleFS payload based on the active env. + +Wired into envs via: + extra_scripts = pre:scripts/data_dir.py + +The script runs before SCons evaluates uploadfs and overrides +PROJECT_DATA_DIR for the envs in `ENV_TO_DATA`. Envs not listed fall +through to the project default (set in [platformio]). +""" + +import os + +Import("env") # noqa: F821 — provided by PlatformIO's SCons context + +ENV_TO_DATA = { + "waveshare73-v1": "waveshare73-v1", + "test-display": "waveshare73-v1", + "sim-yellow": "waveshare73-v1", + "sim-red": "waveshare73-v1", + "waveshare13e6-v1": "waveshare13e6-v1", +} + +pioenv = env["PIOENV"] # noqa: F821 +if pioenv in ENV_TO_DATA: + data_dir = os.path.join(env["PROJECT_DIR"], "data", ENV_TO_DATA[pioenv]) # noqa: F821 + env.Replace(PROJECT_DATA_DIR=data_dir) # noqa: F821 + print(f"[data_dir] {pioenv} -> {data_dir}") diff --git a/scripts/gen_screens_13e6.py b/scripts/gen_screens_13e6.py new file mode 100644 index 0000000..1e272bb --- /dev/null +++ b/scripts/gen_screens_13e6.py @@ -0,0 +1,225 @@ +#!/usr/bin/env python3 +""" +Generate 1200×1600 portrait setup-screen backgrounds for the Waveshare +13.3" Spectra-6 panel. + +Layout is a single-column vertical stack — much simpler than the 800×480 +three-panel design in gen_screens.py — chosen for the end-to-end port +MVP. Polish the visual treatment later once the provisioning flow is +proven on real hardware. + +Run from the firmware/ directory: + python3 scripts/gen_screens_13e6.py + +Constants used by src/panels/waveshare13e6/v1/epd_driver.cpp: + AP_QR_X, AP_QR_Y, AP_QR_CELL + SETUP_QR_X, SETUP_QR_Y, SETUP_QR_CELL +""" + +from PIL import Image, ImageDraw, ImageFont +import qrcode +import os, sys + +MANUAL_URL = "https://pictureframe.edholm.me/help" + +W, H = 1200, 1600 + +# ── Spectra-6 palette ───────────────────────────────────────────────────────── +BLACK = 0x0; BK = (26, 26, 26 ) +WHITE = 0x1; WH = (245, 245, 240) +YELLOW = 0x2; YL = (240, 208, 0 ) +RED = 0x3; RD = (192, 48, 32 ) +BLUE = 0x5; BL = (24, 64, 192) +GREEN = 0x6; GR = (16, 160, 64 ) + +PALETTE_RGB = {BLACK: BK, WHITE: WH, YELLOW: YL, RED: RD, BLUE: BL, GREEN: GR} + + +def nearest(r, g, b): + best, best_d = WHITE, float("inf") + for n, (pr, pg, pb) in PALETTE_RGB.items(): + d = (r - pr) ** 2 + (g - pg) ** 2 + (b - pb) ** 2 + if d < best_d: + best, best_d = n, d + return best + + +def pack(img): + """RGB PIL → 4bpp packed bytearray, row-major panel-native order.""" + px = img.load() + out = bytearray() + for y in range(H): + for x in range(0, W, 2): + hi = nearest(*px[x, y]) + lo = nearest(*px[x + 1, y]) + out.append((hi << 4) | lo) + return out + + +# ── Fonts ──────────────────────────────────────────────────────────────────── +FONT_DIR = "/usr/share/fonts/truetype/dejavu" +def ttf(name, size): + try: + return ImageFont.truetype(os.path.join(FONT_DIR, name), size) + except Exception: + return ImageFont.load_default() + + +F_HEADER = ttf("DejaVuSans-Bold.ttf", 44) +F_TITLE = ttf("DejaVuSans-Bold.ttf", 60) +F_LABEL = ttf("DejaVuSans-Bold.ttf", 32) +F_STEP = ttf("DejaVuSans.ttf", 32) +F_STEP_B = ttf("DejaVuSans-Bold.ttf", 32) +F_FOOT = ttf("DejaVuSans.ttf", 28) +F_NUM = ttf("DejaVuSans-Bold.ttf", 30) +F_TINY = ttf("DejaVuSans-Bold.ttf", 20) + + +# ── QR overlay regions — must match the panel driver ────────────────────────── +# Cell sizes are chosen so each QR fits comfortably in its vertical band with +# room for label + caption. Centered horizontally on a 1200-wide canvas. +AP_QR_MODS = 37 # version 5, ECC_LOW +AP_QR_CELL = 16 # 37 × 16 = 592 px square +AP_QR_PX = AP_QR_MODS * AP_QR_CELL +AP_QR_X = (W - AP_QR_PX) // 2 # 304 +AP_QR_Y = 220 + +SETUP_QR_MODS = 41 # version 6, ECC_LOW +SETUP_QR_CELL = 14 # 41 × 14 = 574 px square +SETUP_QR_PX = SETUP_QR_MODS * SETUP_QR_CELL +SETUP_QR_X = (W - SETUP_QR_PX) // 2 # 313 +SETUP_QR_Y = 450 + +HEADER_H = 120 + + +def text_center(draw, cx, y, text, font, fill): + bb = draw.textbbox((0, 0), text, font=font) + tw = bb[2] - bb[0] + draw.text((cx - tw // 2, y), text, font=font, fill=fill) + + +def leave_qr_white(draw, qr_x, qr_y, qr_px): + draw.rectangle([qr_x, qr_y, qr_x + qr_px - 1, qr_y + qr_px - 1], fill=WH) + + +def draw_qr_frame(draw, qx, qy, qp, accent): + """Two-layer decorative border around a QR placeholder.""" + draw.rectangle([qx - 12, qy - 12, qx + qp + 11, qy + qp + 11], outline=accent, width=6) + draw.rectangle([qx - 4, qy - 4, qx + qp + 3, qy + qp + 3], outline=BK, width=4) + + +# ── AP SCREEN (Step 1/2 — WiFi join) ────────────────────────────────────────── +def gen_ap(accent=YL, header_text="SETUP MODE — STEP 1 OF 2", + qr_caption="Scan to join PictureFrame"): + img = Image.new("RGB", (W, H), WH) + draw = ImageDraw.Draw(img) + + # Status header band + draw.rectangle([0, 0, W - 1, HEADER_H - 1], fill=accent) + text_center(draw, W // 2, 38, header_text, F_HEADER, BK) + + # WiFi QR step + text_center(draw, W // 2, AP_QR_Y - 60, "STEP 1 — JOIN WIFI", F_LABEL, BK) + draw_qr_frame(draw, AP_QR_X, AP_QR_Y, AP_QR_PX, accent) + leave_qr_white(draw, AP_QR_X, AP_QR_Y, AP_QR_PX) + text_center(draw, W // 2, AP_QR_Y + AP_QR_PX + 16, qr_caption, F_FOOT, BK) + + # URL QR step — static, baked into the bg. Scanning it opens Safari, + # which forces iOS to render the captive portal. + url_qr = qrcode.QRCode( + version=None, + error_correction=qrcode.constants.ERROR_CORRECT_L, + box_size=10, + border=2, + ) + url_qr.add_data("http://192.168.4.1/") + url_qr.make(fit=True) + url_img = url_qr.make_image(fill_color=BK, back_color=WH).convert("RGB") + url_w, url_h = url_img.size + url_y = 1180 + url_x = (W - url_w) // 2 + + text_center(draw, W // 2, url_y - 60, "STEP 2 — OPEN PAGE", F_LABEL, BK) + draw.rectangle([url_x - 12, url_y - 12, url_x + url_w + 11, url_y + url_h + 11], + outline=accent, width=6) + draw.rectangle([url_x - 4, url_y - 4, url_x + url_w + 3, url_y + url_h + 3], + outline=BK, width=4) + img.paste(url_img, (url_x, url_y)) + text_center(draw, W // 2, url_y + url_h + 16, "http://192.168.4.1/", F_FOOT, BK) + + return img + + +def gen_ap_retry(): + """Step 1/2 with red accent + retry messaging.""" + return gen_ap( + accent=RD, + header_text="CONNECTION FAILED — TRY AGAIN", + qr_caption="Connection failed — try again", + ) + + +# ── SETUP SCREEN (post-WiFi, scan-to-claim) ─────────────────────────────────── +def gen_setup(): + img = Image.new("RGB", (W, H), WH) + draw = ImageDraw.Draw(img) + + draw.rectangle([0, 0, W - 1, HEADER_H - 1], fill=GR) + text_center(draw, W // 2, 38, "WIFI CONNECTED — STEP 2 OF 2", F_HEADER, WH) + + text_center(draw, W // 2, 200, "Almost ready", F_TITLE, BK) + text_center(draw, W // 2, 290, "Scan the QR to link this frame", F_STEP, BK) + text_center(draw, W // 2, 332, "to your pictureframe.edholm.me account.", F_STEP, BK) + + text_center(draw, W // 2, SETUP_QR_Y - 60, "SCAN TO FINISH", F_LABEL, BK) + draw_qr_frame(draw, SETUP_QR_X, SETUP_QR_Y, SETUP_QR_PX, GR) + leave_qr_white(draw, SETUP_QR_X, SETUP_QR_Y, SETUP_QR_PX) + + # MAC chip below QR — populated at runtime by the firmware would be nicer, + # but the firmware doesn't write text yet on this panel; the link-target + # URL is what the user actually scans, so the chip stays a static "your + # frame ID will appear in the QR" placeholder for now. + text_center(draw, W // 2, + SETUP_QR_Y + SETUP_QR_PX + 16, + "Your frame ID is encoded in the QR above.", + F_FOOT, BK) + + return img + + +# ── Save ────────────────────────────────────────────────────────────────────── +def save_bin(img, path, preview_path): + data = pack(img) + with open(path, "wb") as f: + f.write(data) + print(f"Written {len(data):,} bytes → {os.path.abspath(path)}") + + prev = Image.new("RGB", (W, H)) + px = prev.load() + for y in range(H): + for x in range(0, W, 2): + byte = data[y * (W // 2) + x // 2] + px[x, y] = PALETTE_RGB.get(byte >> 4, (128, 128, 128)) + px[x + 1, y] = PALETTE_RGB.get(byte & 0xF, (128, 128, 128)) + prev.save(preview_path) + print(f"Preview → {os.path.abspath(preview_path)}") + + +if __name__ == "__main__": + out_dir = os.path.join(os.path.dirname(__file__), "../data/waveshare13e6-v1") + os.makedirs(out_dir, exist_ok=True) + + print("Generating AP screen…") + save_bin(gen_ap(), f"{out_dir}/ap_bg.bin", f"{out_dir}/ap_bg_preview.png") + print() + print("Generating AP retry screen…") + save_bin(gen_ap_retry(), f"{out_dir}/ap_bg_retry.bin", f"{out_dir}/ap_bg_retry_preview.png") + print() + print("Generating setup screen…") + save_bin(gen_setup(), f"{out_dir}/setup_bg.bin", f"{out_dir}/setup_bg_preview.png") + print() + print("QR overlay constants — keep these in sync with epd_driver.cpp:") + print(f" AP_QR_X={AP_QR_X}, AP_QR_Y={AP_QR_Y}, AP_QR_CELL={AP_QR_CELL}, AP_QR_PX={AP_QR_PX}") + print(f" SETUP_QR_X={SETUP_QR_X}, SETUP_QR_Y={SETUP_QR_Y}, " + f"SETUP_QR_CELL={SETUP_QR_CELL}, SETUP_QR_PX={SETUP_QR_PX}") diff --git a/src/epd.h b/src/epd.h index ce26a01..2ae39f8 100644 --- a/src/epd.h +++ b/src/epd.h @@ -3,6 +3,13 @@ #include #include +// One-shot panel hardware init — pinModes for the panel's GPIO contract and +// SPI.begin() with the right bus/CS layout. Each panel driver implements +// this for its own pinout: single-CS for the 7.3", dual-CS + power-enable +// for the 13.3". Callers hit this once at boot, then use epd_init() per +// redraw cycle. +void epd_setup_pins(); + void epd_init(); void epd_sleep(); void epd_fill(uint8_t color); diff --git a/src/main.cpp b/src/main.cpp index cec123b..52652ef 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -300,15 +300,10 @@ void setup() { Serial.begin(115200); Serial.println("pictureFrame boot"); - // Init GPIO - pinMode(PIN_CS, OUTPUT); - pinMode(PIN_DC, OUTPUT); - pinMode(PIN_RST, OUTPUT); - pinMode(PIN_BUSY, INPUT); - pinMode(PIN_BTN_RESET, INPUT_PULLUP); - - SPI.begin(PIN_SCK, -1, PIN_MOSI, PIN_CS); - SPI.beginTransaction(SPISettings(4000000, MSBFIRST, SPI_MODE0)); + // BOOT button is panel-agnostic; everything else (CS/DC/RST/BUSY + SPI) + // is panel-private and lives in the active driver's epd_setup_pins(). + pinMode(PIN_BTN_RESET, INPUT_PULLUP); + epd_setup_pins(); LittleFS.begin(true); // format on first use diff --git a/src/operation.h b/src/operation.h index d369507..5f9a7ed 100644 --- a/src/operation.h +++ b/src/operation.h @@ -134,6 +134,13 @@ void normal_operation_impl(const String& mac, HTTP& http, const String& url, Pre http.addHeader("X-Current-Image-Id", String(currentImgId)); } + // Report the panel hardware so the server can route image-rendering + // dimensions to the right DeviceModel. Comes from -DPANEL_ID in the + // active env's build_flags (see config.h). Sent on every poll so the + // server can correct a mis-set Device.model lazily without needing + // a separate registration handshake. + http.addHeader("X-Panel-Id", PANEL_ID); + // Tell the server how we got here. The server uses this to honor a // power-cycle as a deliberate "force resync" — a poll that arrives with // X-Boot-Reason: cold gets a fresh rotation even outside configured wake diff --git a/src/panels/waveshare13e6/v1/epd_driver.cpp b/src/panels/waveshare13e6/v1/epd_driver.cpp new file mode 100644 index 0000000..93ecdeb --- /dev/null +++ b/src/panels/waveshare13e6/v1/epd_driver.cpp @@ -0,0 +1,382 @@ +// Waveshare 13.3" Spectra-6 (E6) panel driver — implements epd.h for the +// ESP32-S3-ePaper-13.3E6 board. +// +// Hardware: 1200 × 1600 pixels, 6 colors, 4 bits-per-pixel packed two +// pixels per byte (full framebuffer = 960 KB). Panel is internally split: +// the left 600 columns are driven via CS_M (master), the right 600 via +// CS_S (slave), both sharing SCK / MOSI / DC / BUSY. Init commands go to +// both halves with both CS lines asserted; framebuffer pushes go to one +// half at a time. +// +// .bin layout (server-rendered, panel-native): row-major, 600 bytes/row +// × 1600 rows. Within each row, bytes [0..300) are the left half and +// [300..600) are the right half. Server writes in this exact order; the +// driver streams the file into a PSRAM buffer then pushes each half's +// columns to its respective CS line. +// +// Init sequence + command set verified against: +// github.com/teatall/13.3inch_e-Paper_E-Frame (community photo-frame +// project on the same board) and Waveshare's stock 13in3e demo. + +#include "epd.h" +#include "config.h" +#include +#include +#include +#include + +static constexpr uint16_t W = 1200; +static constexpr uint16_t H = 1600; +static constexpr uint16_t BYTES_PER_ROW = W / 2; // 600 +static constexpr uint16_t HALF_BYTES_ROW = W / 4; // 300 per half +static constexpr size_t FB_BYTES = (size_t)BYTES_PER_ROW * H; // 960000 + +// Driver-level "is the panel awake?" flag. Useful for asserts; not load-bearing. +static bool s_initialized = false; + +// PSRAM framebuffer for image render paths. Allocated lazily on first use +// so a fill-only or QR-only path doesn't pay for it. Caller frees via +// release_fb() once the half-pushes are done. +static uint8_t* fb_alloc() { + return (uint8_t*)heap_caps_malloc(FB_BYTES, MALLOC_CAP_SPIRAM); +} +static void fb_release(uint8_t* fb) { if (fb) heap_caps_free(fb); } + +// ── BUSY ─────────────────────────────────────────────────────────────────────── +// Active-LOW: panel pulls BUSY low while working, releases high when idle. +// Full refresh on Spectra-6 takes ~25 s; bound the wait at 60 s so a +// hung panel doesn't strand the boot cycle. +static void wait_busy() { + uint32_t start = millis(); + while (digitalRead(PIN_BUSY) == LOW) { + if (millis() - start > 60000) return; + delay(5); + esp_task_wdt_reset(); + } +} + +// ── CS / cmd / data helpers ──────────────────────────────────────────────────── +// Pattern: assert one or both CS lines, send cmd byte with DC=LOW, then +// stream data with DC=HIGH, then deassert. Matches Waveshare's reference. + +static inline void cs(int pin, int v) { digitalWrite(pin, v); } +static inline void cs_both(int v) { cs(PIN_CS_M, v); cs(PIN_CS_S, v); } + +static void begin_cmd_both(uint8_t c) { + cs_both(LOW); + digitalWrite(PIN_DC, LOW); + SPI.transfer(c); + digitalWrite(PIN_DC, HIGH); +} + +static void begin_cmd(int cs_pin, uint8_t c) { + cs(cs_pin, LOW); + digitalWrite(PIN_DC, LOW); + SPI.transfer(c); + digitalWrite(PIN_DC, HIGH); +} + +static void send_data_n(const uint8_t* buf, size_t n) { + SPI.writeBytes(buf, n); +} + +static void send_cmd_with_data_both(uint8_t c, const uint8_t* buf, size_t n) { + begin_cmd_both(c); + if (buf && n) send_data_n(buf, n); + cs_both(HIGH); +} + +static void send_cmd_with_data_master(uint8_t c, const uint8_t* buf, size_t n) { + begin_cmd(PIN_CS_M, c); + if (buf && n) send_data_n(buf, n); + cs_both(HIGH); +} + +// ── Panel reset + init sequence ──────────────────────────────────────────────── + +static void panel_reset() { + digitalWrite(PIN_RST, HIGH); delay(30); + digitalWrite(PIN_RST, LOW); delay(30); + digitalWrite(PIN_RST, HIGH); delay(30); + digitalWrite(PIN_RST, LOW); delay(30); + digitalWrite(PIN_RST, HIGH); delay(30); +} + +void epd_setup_pins() { + pinMode(PIN_PWR, OUTPUT); + pinMode(PIN_RST, OUTPUT); + pinMode(PIN_DC, OUTPUT); + pinMode(PIN_BUSY, INPUT); + pinMode(PIN_CS_M, OUTPUT); + pinMode(PIN_CS_S, OUTPUT); + + digitalWrite(PIN_PWR, HIGH); + digitalWrite(PIN_CS_M, HIGH); + digitalWrite(PIN_CS_S, HIGH); + digitalWrite(PIN_RST, HIGH); + + // FSPI on S3, manual CS. 10 MHz is well under the panel's documented + // 20 MHz ceiling and gives plenty of margin on the long traces between + // the module and the connector. + SPI.begin(PIN_SCK, -1, PIN_MOSI, -1); + SPI.beginTransaction(SPISettings(10000000, MSBFIRST, SPI_MODE0)); +} + +void epd_init() { + panel_reset(); + + static const uint8_t AN_TM_V[] = {0xC0,0x1C,0x1C,0xCC,0xCC,0xCC,0x15,0x15,0x55}; + static const uint8_t CMD66_V[] = {0x49,0x55,0x13,0x5D,0x05,0x10}; + static const uint8_t PSR_V[] = {0xDF,0x69}; + static const uint8_t CDI_V[] = {0xF7}; + static const uint8_t TCON_V[] = {0x03,0x03}; + static const uint8_t AGID_V[] = {0x10}; + static const uint8_t PWS_V[] = {0x22}; + static const uint8_t CCSET_V[] = {0x01}; + static const uint8_t TRES_V[] = {0x04,0xB0,0x03,0x20}; + static const uint8_t PWR_V[] = {0x0F,0x00,0x28,0x2C,0x28,0x38}; + static const uint8_t EN_BUF_V[] = {0x07}; + static const uint8_t BTST_P_V[] = {0xE8,0x28}; + static const uint8_t BOOST_VDDP_EN_V[] = {0x01}; + static const uint8_t BTST_N_V[] = {0xE8,0x28}; + static const uint8_t BUCK_VDDN_V[] = {0x01}; + static const uint8_t TFT_VCOM_V[] = {0x02}; + + // AN_TM goes to master only first (per reference; not obvious why but + // matching exactly de-risks bringup), then a batch of commands to + // both halves, then a tail of master-only tuning commands. + send_cmd_with_data_master(0x74, AN_TM_V, sizeof(AN_TM_V)); + send_cmd_with_data_both (0xF0, CMD66_V, sizeof(CMD66_V)); + send_cmd_with_data_both (0x00, PSR_V, sizeof(PSR_V)); + send_cmd_with_data_both (0x50, CDI_V, sizeof(CDI_V)); + send_cmd_with_data_both (0x60, TCON_V, sizeof(TCON_V)); + send_cmd_with_data_both (0x86, AGID_V, sizeof(AGID_V)); + send_cmd_with_data_both (0xE3, PWS_V, sizeof(PWS_V)); + send_cmd_with_data_both (0xE0, CCSET_V, sizeof(CCSET_V)); + send_cmd_with_data_both (0x61, TRES_V, sizeof(TRES_V)); + send_cmd_with_data_master(0x01, PWR_V, sizeof(PWR_V)); + send_cmd_with_data_master(0xB6, EN_BUF_V, sizeof(EN_BUF_V)); + send_cmd_with_data_master(0x06, BTST_P_V, sizeof(BTST_P_V)); + send_cmd_with_data_master(0xB7, BOOST_VDDP_EN_V, sizeof(BOOST_VDDP_EN_V)); + send_cmd_with_data_master(0x05, BTST_N_V, sizeof(BTST_N_V)); + send_cmd_with_data_master(0xB0, BUCK_VDDN_V, sizeof(BUCK_VDDN_V)); + send_cmd_with_data_master(0xB1, TFT_VCOM_V, sizeof(TFT_VCOM_V)); + + s_initialized = true; +} + +// ── Refresh / sleep ──────────────────────────────────────────────────────────── + +static void epd_refresh() { + begin_cmd_both(0x04); // POWER_ON + cs_both(HIGH); + wait_busy(); + + delay(50); + begin_cmd_both(0x12); SPI.transfer(0x00); // DRF (full refresh) + cs_both(HIGH); + wait_busy(); + + begin_cmd_both(0x02); SPI.transfer(0x00); // POWER_OFF + cs_both(HIGH); +} + +void epd_sleep() { + cs_both(LOW); + digitalWrite(PIN_DC, LOW); + SPI.transfer(0x07); // DEEP_SLEEP + digitalWrite(PIN_DC, HIGH); + SPI.transfer(0xA5); // sentinel + cs_both(HIGH); + s_initialized = false; +} + +// ── Draw helpers ─────────────────────────────────────────────────────────────── + +// Push one half's framebuffer slice to its CS line. The slice is the +// HALF_BYTES_ROW × H bytes for that half, laid out row-major-contiguous. +static void push_half(int cs_pin, const uint8_t* half_fb) { + begin_cmd(cs_pin, 0x10); + send_data_n(half_fb, (size_t)HALF_BYTES_ROW * H); + cs(cs_pin, HIGH); +} + +// Take a full-frame row-major framebuffer (BYTES_PER_ROW × H) and push +// left-then-right halves. Needs a scratch buffer to deinterleave halves +// from the row-major layout — the SPI bus needs contiguous bytes per CS. +static void push_full_frame(const uint8_t* fb) { + // Allocate a half-slice scratch buffer in PSRAM. 300 × 1600 = 480 KB. + constexpr size_t HALF_BYTES = (size_t)HALF_BYTES_ROW * H; + uint8_t* slice = (uint8_t*)heap_caps_malloc(HALF_BYTES, MALLOC_CAP_SPIRAM); + if (!slice) return; + + for (uint16_t y = 0; y < H; y++) { + memcpy(slice + (size_t)y * HALF_BYTES_ROW, + fb + (size_t)y * BYTES_PER_ROW, + HALF_BYTES_ROW); + } + push_half(PIN_CS_M, slice); + + for (uint16_t y = 0; y < H; y++) { + memcpy(slice + (size_t)y * HALF_BYTES_ROW, + fb + (size_t)y * BYTES_PER_ROW + HALF_BYTES_ROW, + HALF_BYTES_ROW); + } + push_half(PIN_CS_S, slice); + + heap_caps_free(slice); +} + +// ── epd.h surface ────────────────────────────────────────────────────────────── + +void epd_fill(uint8_t color) { + const uint8_t byte = (color << 4) | color; + + // Solid fill needs no framebuffer — stream the byte directly per half. + for (int half = 0; half < 2; half++) { + const int p = (half == 0) ? PIN_CS_M : PIN_CS_S; + begin_cmd(p, 0x10); + for (size_t i = 0; i < (size_t)HALF_BYTES_ROW * H; i++) { + SPI.transfer(byte); + } + cs(p, HIGH); + } + epd_refresh(); +} + +void epd_draw_image_from_file(fs::File& f) { + uint8_t* fb = fb_alloc(); + if (!fb) { epd_fill(COLOR_WHITE); return; } + + size_t n = f.read(fb, FB_BYTES); + if (n != FB_BYTES) { + fb_release(fb); + epd_fill(COLOR_WHITE); + return; + } + + push_full_frame(fb); + fb_release(fb); + epd_refresh(); +} + +void epd_draw_image_with_border(fs::File& f, uint8_t color, int thickness) { + if (f.size() != FB_BYTES) { + epd_fill(color); + return; + } + uint8_t* fb = fb_alloc(); + if (!fb) { epd_fill(color); return; } + if (f.read(fb, FB_BYTES) != FB_BYTES) { fb_release(fb); epd_fill(color); return; } + + const uint8_t pair = (color << 4) | color; + + // Overlay border in-place. Same x/y orientation as the 7.3" driver: + // top/bottom solid stripes, plus left/right edges on the middle band. + for (int y = 0; y < H; y++) { + uint8_t* row = fb + (size_t)y * BYTES_PER_ROW; + if (y < thickness || y >= H - thickness) { + memset(row, pair, BYTES_PER_ROW); + } else { + for (int x = 0; x < thickness; x++) { + if (x & 1) row[x/2] = (row[x/2] & 0xF0) | color; + else row[x/2] = (row[x/2] & 0x0F) | (color << 4); + } + for (int x = W - thickness; x < W; x++) { + if (x & 1) row[x/2] = (row[x/2] & 0xF0) | color; + else row[x/2] = (row[x/2] & 0x0F) | (color << 4); + } + } + } + + push_full_frame(fb); + fb_release(fb); + epd_refresh(); +} + +void epd_draw_qr(QRCode* qr, uint8_t cellPx, uint8_t bg, uint8_t fg) { + uint8_t* fb = fb_alloc(); + if (!fb) { epd_fill(bg); return; } + + const uint8_t bg_pair = (bg << 4) | bg; + memset(fb, bg_pair, FB_BYTES); + + const int qrPx = qr->size * cellPx; + const int offX = (W - qrPx) / 2; + const int offY = (H - qrPx) / 2; + + for (int y = offY; y < offY + qrPx; y++) { + if (y < 0 || y >= H) continue; + uint8_t* row = fb + (size_t)y * BYTES_PER_ROW; + const int qy = (y - offY) / cellPx; + for (int x = offX; x < offX + qrPx; x++) { + if (x < 0 || x >= W) continue; + const int qx = (x - offX) / cellPx; + const uint8_t c = qrcode_getModule(qr, qx, qy) ? fg : bg; + if (x & 1) row[x/2] = (row[x/2] & 0xF0) | c; + else row[x/2] = (row[x/2] & 0x0F) | (c << 4); + } + } + + push_full_frame(fb); + fb_release(fb); + epd_refresh(); +} + +// Stream background from LittleFS into the PSRAM framebuffer, overlay the QR +// at (qr_x, qr_y) with the given cell size, then push the full frame in two +// halves. Falls back to a solid fill if the file is missing or wrong size. +static void draw_from_lfs(const char* path, uint8_t fallback_color, + QRCode* qr, int qr_x, int qr_y, int qr_cell) { + File f = LittleFS.open(path, "r"); + if (!f || f.size() != FB_BYTES) { + if (f) f.close(); + epd_fill(fallback_color); + return; + } + + uint8_t* fb = fb_alloc(); + if (!fb) { f.close(); epd_fill(fallback_color); return; } + + if (f.read(fb, FB_BYTES) != FB_BYTES) { + fb_release(fb); f.close(); epd_fill(fallback_color); return; + } + f.close(); + + const int qr_px = qr->size * qr_cell; + const int y0 = max(qr_y, 0); + const int y1 = min(qr_y + qr_px, (int)H); + const int x0 = max(qr_x, 0); + const int x1 = min(qr_x + qr_px, (int)W); + for (int y = y0; y < y1; y++) { + uint8_t* row = fb + (size_t)y * BYTES_PER_ROW; + const int qy = (y - qr_y) / qr_cell; + for (int x = x0; x < x1; x++) { + const int qx = (x - qr_x) / qr_cell; + const uint8_t c = qrcode_getModule(qr, qx, qy) ? COLOR_BLACK : COLOR_WHITE; + if (x & 1) row[x/2] = (row[x/2] & 0xF0) | c; + else row[x/2] = (row[x/2] & 0x0F) | (c << 4); + } + } + + push_full_frame(fb); + fb_release(fb); + epd_refresh(); +} + +// QR overlay coordinates for the 13.3" portrait setup screens. Must stay +// in sync with scripts/gen_screens_13e6.py — the bg .bin leaves a white +// rectangle exactly the size of QR_MODS × QR_CELL at (X, Y), and the +// firmware paints the live QR into it. Mismatch = the QR draws over +// decorative borders or the QR placeholder shows through. +void epd_draw_ap_screen(QRCode* qr) { + draw_from_lfs("/ap_bg.bin", COLOR_YELLOW, qr, 304, 220, 16); +} + +void epd_draw_ap_screen_retry(QRCode* qr) { + draw_from_lfs("/ap_bg_retry.bin", COLOR_RED, qr, 304, 220, 16); +} + +void epd_draw_setup_screen(QRCode* qr) { + draw_from_lfs("/setup_bg.bin", COLOR_GREEN, qr, 313, 450, 14); +} diff --git a/src/panels/waveshare13e6/v1/version.h b/src/panels/waveshare13e6/v1/version.h new file mode 100644 index 0000000..c5446cc --- /dev/null +++ b/src/panels/waveshare13e6/v1/version.h @@ -0,0 +1,6 @@ +#pragma once + +// Panel-specific firmware version for the Waveshare 13.3" Spectra-6 driver. +// Bump on each driver change worth correlating with server-side reports. +// Independent of the shared firmware version (HTTP / NVS / sleep / etc.). +#define PANEL_FW_VERSION "v1.0" diff --git a/src/panels/waveshare73/v1/epd_driver.cpp b/src/panels/waveshare73/v1/epd_driver.cpp index 5670d69..267c7e4 100644 --- a/src/panels/waveshare73/v1/epd_driver.cpp +++ b/src/panels/waveshare73/v1/epd_driver.cpp @@ -6,6 +6,15 @@ static uint8_t s_row[EPD_WIDTH / 2]; +void epd_setup_pins() { + pinMode(PIN_CS, OUTPUT); + pinMode(PIN_DC, OUTPUT); + pinMode(PIN_RST, OUTPUT); + pinMode(PIN_BUSY, INPUT); + SPI.begin(PIN_SCK, -1, PIN_MOSI, PIN_CS); + SPI.beginTransaction(SPISettings(4000000, MSBFIRST, SPI_MODE0)); +} + static void wait_busy() { uint32_t start = millis(); while (digitalRead(PIN_BUSY) == LOW) { diff --git a/src/sim_border.cpp b/src/sim_border.cpp index ecadd0d..59dd9cc 100644 --- a/src/sim_border.cpp +++ b/src/sim_border.cpp @@ -28,14 +28,8 @@ void setup() { Serial.begin(115200); Serial.println("[sim_border] boot"); - pinMode(PIN_CS, OUTPUT); - pinMode(PIN_DC, OUTPUT); - pinMode(PIN_RST, OUTPUT); - pinMode(PIN_BUSY, INPUT); pinMode(PIN_BTN_RESET, INPUT_PULLUP); - - SPI.begin(PIN_SCK, -1, PIN_MOSI, PIN_CS); - SPI.beginTransaction(SPISettings(4000000, MSBFIRST, SPI_MODE0)); + epd_setup_pins(); LittleFS.begin(true); epd_init(); diff --git a/src/test_display.cpp b/src/test_display.cpp index a4d7526..c2834c1 100644 --- a/src/test_display.cpp +++ b/src/test_display.cpp @@ -10,12 +10,7 @@ void setup() { Serial.begin(115200); Serial.println("display test boot"); - pinMode(PIN_CS, OUTPUT); - pinMode(PIN_DC, OUTPUT); - pinMode(PIN_RST, OUTPUT); - pinMode(PIN_BUSY, INPUT); - SPI.begin(PIN_SCK, -1, PIN_MOSI, PIN_CS); - SPI.beginTransaction(SPISettings(4000000, MSBFIRST, SPI_MODE0)); + epd_setup_pins(); LittleFS.begin(true); diff --git a/src/test_display_13e6.cpp b/src/test_display_13e6.cpp new file mode 100644 index 0000000..cdd063a --- /dev/null +++ b/src/test_display_13e6.cpp @@ -0,0 +1,215 @@ +// First-pixels bringup test for the Waveshare ESP32-S3-ePaper-13.3E6. +// +// Renders the panel's six color bars (BLACK/BLUE/GREEN/RED/YELLOW/WHITE) +// — same pattern as Waveshare's stock demo, ported to Arduino-on-S3. +// Self-contained on purpose: no LittleFS, no shared epd.h, no PSRAM +// framebuffer, no panels/ driver. Once pixels render, refactor into the +// existing panels/{vendor}/v{N}/ structure. +// +// Pin map verified against the ESP32-S3-ePaper-13.3E6 (all-in-one) board, +// not the separate ESP32 driver board (which uses different GPIOs). +// +// Source of init sequence + display protocol: +// github.com/teatall/13.3inch_e-Paper_E-Frame (community project for +// the same Waveshare board) and Waveshare's official 13in3e demo. + +#ifdef ENV_TEST_DISPLAY_13E6 + +#include + +static constexpr int PIN_SCK = 9; +static constexpr int PIN_MOSI = 46; +static constexpr int PIN_CS_M = 10; +static constexpr int PIN_CS_S = 3; +static constexpr int PIN_RST = 2; +static constexpr int PIN_DC = 11; +static constexpr int PIN_BUSY = 12; +static constexpr int PIN_PWR = 1; + +static constexpr uint16_t EPD_W = 1200; +static constexpr uint16_t EPD_H = 1600; + +static constexpr uint8_t C_BLACK = 0x0; +static constexpr uint8_t C_WHITE = 0x1; +static constexpr uint8_t C_YELLOW = 0x2; +static constexpr uint8_t C_RED = 0x3; +static constexpr uint8_t C_BLUE = 0x5; +static constexpr uint8_t C_GREEN = 0x6; + +static inline void cs_both(int v) { + digitalWrite(PIN_CS_M, v); + digitalWrite(PIN_CS_S, v); +} + +// Bit-banged MSB-first SPI matching Waveshare's reference timing exactly. +// DC and CS are handled by the caller. Cmd byte goes out while DC is low; +// data while DC is high. +static void spi_write_byte(uint8_t b) { + for (int i = 0; i < 8; i++) { + digitalWrite(PIN_MOSI, (b & 0x80) ? HIGH : LOW); + b <<= 1; + digitalWrite(PIN_SCK, HIGH); + digitalWrite(PIN_SCK, LOW); + } +} + +static void send_cmd(uint8_t cmd) { + digitalWrite(PIN_DC, LOW); + spi_write_byte(cmd); + digitalWrite(PIN_DC, HIGH); +} + +static void send_data(uint8_t d) { + spi_write_byte(d); +} + +static void send_cmd_with_data(uint8_t cmd, const uint8_t* buf, size_t len) { + send_cmd(cmd); + for (size_t i = 0; i < len; i++) spi_write_byte(buf[i]); +} + +// BUSY is active-LOW: panel pulls it low while working, releases high when idle. +static void wait_busy_idle() { + Serial.println("busy: wait"); + while (digitalRead(PIN_BUSY) == LOW) { + delay(10); + } + delay(20); + Serial.println("busy: idle"); +} + +static void panel_reset() { + digitalWrite(PIN_RST, HIGH); delay(30); + digitalWrite(PIN_RST, LOW); delay(30); + digitalWrite(PIN_RST, HIGH); delay(30); + digitalWrite(PIN_RST, LOW); delay(30); + digitalWrite(PIN_RST, HIGH); delay(30); +} + +static void panel_init() { + panel_reset(); + + static const uint8_t AN_TM_V[] = {0xC0,0x1C,0x1C,0xCC,0xCC,0xCC,0x15,0x15,0x55}; + static const uint8_t CMD66_V[] = {0x49,0x55,0x13,0x5D,0x05,0x10}; + static const uint8_t PSR_V[] = {0xDF,0x69}; + static const uint8_t CDI_V[] = {0xF7}; + static const uint8_t TCON_V[] = {0x03,0x03}; + static const uint8_t AGID_V[] = {0x10}; + static const uint8_t PWS_V[] = {0x22}; + static const uint8_t CCSET_V[] = {0x01}; + static const uint8_t TRES_V[] = {0x04,0xB0,0x03,0x20}; + static const uint8_t PWR_V[] = {0x0F,0x00,0x28,0x2C,0x28,0x38}; + static const uint8_t EN_BUF_V[] = {0x07}; + static const uint8_t BTST_P_V[] = {0xE8,0x28}; + static const uint8_t BOOST_VDDP_EN_V[] = {0x01}; + static const uint8_t BTST_N_V[] = {0xE8,0x28}; + static const uint8_t BUCK_VDDN_V[] = {0x01}; + static const uint8_t TFT_VCOM_V[] = {0x02}; + + // The first few commands go to BOTH halves of the panel (CS_M then CS_S + // released together). After that, several "tuning" commands are master- + // only — exactly as in the reference, even though it's not obvious why. + digitalWrite(PIN_CS_M, LOW); + send_cmd_with_data(0x74, AN_TM_V, sizeof(AN_TM_V)); + cs_both(HIGH); + + cs_both(LOW); send_cmd_with_data(0xF0, CMD66_V, sizeof(CMD66_V)); cs_both(HIGH); + cs_both(LOW); send_cmd_with_data(0x00, PSR_V, sizeof(PSR_V)); cs_both(HIGH); + cs_both(LOW); send_cmd_with_data(0x50, CDI_V, sizeof(CDI_V)); cs_both(HIGH); + cs_both(LOW); send_cmd_with_data(0x60, TCON_V, sizeof(TCON_V)); cs_both(HIGH); + cs_both(LOW); send_cmd_with_data(0x86, AGID_V, sizeof(AGID_V)); cs_both(HIGH); + cs_both(LOW); send_cmd_with_data(0xE3, PWS_V, sizeof(PWS_V)); cs_both(HIGH); + cs_both(LOW); send_cmd_with_data(0xE0, CCSET_V, sizeof(CCSET_V)); cs_both(HIGH); + cs_both(LOW); send_cmd_with_data(0x61, TRES_V, sizeof(TRES_V)); cs_both(HIGH); + + digitalWrite(PIN_CS_M, LOW); send_cmd_with_data(0x01, PWR_V, sizeof(PWR_V)); cs_both(HIGH); + digitalWrite(PIN_CS_M, LOW); send_cmd_with_data(0xB6, EN_BUF_V, sizeof(EN_BUF_V)); cs_both(HIGH); + digitalWrite(PIN_CS_M, LOW); send_cmd_with_data(0x06, BTST_P_V, sizeof(BTST_P_V)); cs_both(HIGH); + digitalWrite(PIN_CS_M, LOW); send_cmd_with_data(0xB7, BOOST_VDDP_EN_V, sizeof(BOOST_VDDP_EN_V)); cs_both(HIGH); + digitalWrite(PIN_CS_M, LOW); send_cmd_with_data(0x05, BTST_N_V, sizeof(BTST_N_V)); cs_both(HIGH); + digitalWrite(PIN_CS_M, LOW); send_cmd_with_data(0xB0, BUCK_VDDN_V, sizeof(BUCK_VDDN_V)); cs_both(HIGH); + digitalWrite(PIN_CS_M, LOW); send_cmd_with_data(0xB1, TFT_VCOM_V, sizeof(TFT_VCOM_V)); cs_both(HIGH); +} + +static void panel_turn_on() { + cs_both(LOW); send_cmd(0x04); cs_both(HIGH); // POWER_ON + wait_busy_idle(); + + delay(50); + cs_both(LOW); send_cmd(0x12); send_data(0x00); cs_both(HIGH); // DRF (refresh) + wait_busy_idle(); + + cs_both(LOW); send_cmd(0x02); send_data(0x00); cs_both(HIGH); // POWER_OFF +} + +static void panel_sleep() { + cs_both(LOW); + send_cmd(0x07); + send_data(0xA5); + cs_both(HIGH); +} + +// Six horizontal bars: BLACK, BLUE, GREEN, RED, YELLOW, WHITE — top to bottom. +// 4 bits/pixel packed 2-per-byte; each half-panel is 600 wide → 300 bytes/row. +static void draw_color_bars() { + static const uint8_t bars[6] = { C_BLACK, C_BLUE, C_GREEN, C_RED, C_YELLOW, C_WHITE }; + constexpr uint16_t bytes_per_row = EPD_W / 4; // 300 bytes per half + constexpr uint16_t rows_per_bar = EPD_H / 6; // ~266 rows per bar + + for (int half = 0; half < 2; half++) { + digitalWrite(half == 0 ? PIN_CS_M : PIN_CS_S, LOW); + send_cmd(0x10); + for (int k = 0; k < 6; k++) { + uint8_t byte = (bars[k] << 4) | bars[k]; + for (uint16_t row = 0; row < rows_per_bar; row++) { + for (uint16_t col = 0; col < bytes_per_row; col++) { + send_data(byte); + } + } + delay(1); + } + cs_both(HIGH); + Serial.printf("half %d: pushed\n", half); + } +} + +void setup() { + Serial.begin(115200); + delay(2000); + Serial.println("\n13.3E6 first-pixels test"); + Serial.printf("Free heap: %u, PSRAM: %u\n", + ESP.getFreeHeap(), + (unsigned)ESP.getPsramSize()); + + pinMode(PIN_PWR, OUTPUT); + pinMode(PIN_RST, OUTPUT); + pinMode(PIN_DC, OUTPUT); + pinMode(PIN_BUSY, INPUT); + pinMode(PIN_SCK, OUTPUT); + pinMode(PIN_MOSI, OUTPUT); + pinMode(PIN_CS_M, OUTPUT); + pinMode(PIN_CS_S, OUTPUT); + + digitalWrite(PIN_PWR, HIGH); + digitalWrite(PIN_CS_M, HIGH); + digitalWrite(PIN_CS_S, HIGH); + digitalWrite(PIN_SCK, LOW); + delay(100); + + Serial.println("init"); + panel_init(); + Serial.println("draw color bars"); + draw_color_bars(); + Serial.println("refresh"); + panel_turn_on(); + Serial.println("sleep"); + panel_sleep(); + + Serial.println("done"); +} + +void loop() { + delay(60000); +} + +#endif diff --git a/test/mocks/epd_mock.h b/test/mocks/epd_mock.h index b5e996d..20ce424 100644 --- a/test/mocks/epd_mock.h +++ b/test/mocks/epd_mock.h @@ -16,6 +16,7 @@ extern int g_epd_draw_border_count; extern int g_epd_draw_border_last_color; extern int g_epd_draw_border_last_thickness; +inline void epd_setup_pins() {} inline void epd_init() { g_epd_init_count++; } inline void epd_sleep() { g_epd_sleep_count++; } inline void epd_draw_image_from_file(File& f) {