From 5fda0f7c2f06e76e3d6c14e61e317ca6cf10fbf6 Mon Sep 17 00:00:00 2001 From: GuruSR Date: Mon, 4 Oct 2021 22:13:33 -0400 Subject: [PATCH] Add files via upload --- src/Bronova_Regular13pt7b.h | 302 +++++ src/Defines_GSR.h | 93 ++ src/GSR.ino | 9 + src/GxEPD2_154_D67-B.cpp | 378 ++++++ src/GxEPD2_154_D67-B.h | 83 ++ src/GxEPD2_BW-B.h | 586 ++++++++++ src/Olsen2POSIX.cpp | 21 + src/Olsen2POSIX.h | 12 + src/Watchy_GSR.cpp | 2170 +++++++++++++++++++++++++++++++++++ src/Watchy_GSR.h | 102 ++ src/Web-HTML.h | 282 +++++ src/aAntiCorona12pt7b.h | 281 +++++ src/aAntiCorona15pt7b.h | 373 ++++++ src/aAntiCorona16pt7b.h | 404 +++++++ src/aAntiCorona36pt7b.h | 202 ++++ src/icons.h | 302 +++++ 16 files changed, 5600 insertions(+) create mode 100644 src/Bronova_Regular13pt7b.h create mode 100644 src/Defines_GSR.h create mode 100644 src/GSR.ino create mode 100644 src/GxEPD2_154_D67-B.cpp create mode 100644 src/GxEPD2_154_D67-B.h create mode 100644 src/GxEPD2_BW-B.h create mode 100644 src/Olsen2POSIX.cpp create mode 100644 src/Olsen2POSIX.h create mode 100644 src/Watchy_GSR.cpp create mode 100644 src/Watchy_GSR.h create mode 100644 src/Web-HTML.h create mode 100644 src/aAntiCorona12pt7b.h create mode 100644 src/aAntiCorona15pt7b.h create mode 100644 src/aAntiCorona16pt7b.h create mode 100644 src/aAntiCorona36pt7b.h create mode 100644 src/icons.h diff --git a/src/Bronova_Regular13pt7b.h b/src/Bronova_Regular13pt7b.h new file mode 100644 index 0000000..f5e3ba2 --- /dev/null +++ b/src/Bronova_Regular13pt7b.h @@ -0,0 +1,302 @@ +const uint8_t Bronova_Regular13pt7bBitmaps[] PROGMEM = { + 0x00, 0xFF, 0xFF, 0xFF, 0xC0, 0xF0, 0xCE, 0x73, 0x9C, 0xE4, 0x04, 0x08, + 0x04, 0x18, 0x04, 0x18, 0x04, 0x18, 0x0C, 0x18, 0x7F, 0xFF, 0x0C, 0x10, + 0x08, 0x10, 0x08, 0x10, 0x08, 0x30, 0x08, 0x30, 0x08, 0x30, 0xFF, 0xFE, + 0x18, 0x20, 0x18, 0x20, 0x18, 0x20, 0x10, 0x20, 0x10, 0x60, 0x01, 0x00, + 0x02, 0x00, 0x04, 0x00, 0x7E, 0x03, 0xFF, 0x07, 0x27, 0x1C, 0x46, 0x30, + 0x86, 0x61, 0x00, 0xC2, 0x00, 0xE4, 0x00, 0x7C, 0x00, 0x1F, 0x00, 0x23, + 0x80, 0x41, 0x80, 0x83, 0xC1, 0x06, 0xC2, 0x1C, 0xE4, 0x70, 0xFF, 0xC0, + 0x7E, 0x00, 0x20, 0x00, 0x40, 0x00, 0x80, 0x3C, 0x02, 0x10, 0x81, 0x88, + 0x10, 0xC2, 0x04, 0x20, 0x81, 0x18, 0x20, 0x4C, 0x08, 0x12, 0x01, 0x09, + 0x80, 0x3C, 0x40, 0x00, 0x21, 0xC0, 0x18, 0x88, 0x04, 0x41, 0x03, 0x10, + 0x41, 0x84, 0x10, 0x41, 0x04, 0x30, 0x41, 0x18, 0x08, 0x8C, 0x01, 0xC0, + 0x0F, 0x80, 0x3F, 0x80, 0xC1, 0x81, 0x83, 0x03, 0x00, 0x02, 0x00, 0x06, + 0x00, 0x0E, 0x00, 0x3E, 0x00, 0xC6, 0x03, 0x86, 0x06, 0x04, 0x0C, 0x04, + 0x58, 0x05, 0xB8, 0x06, 0x38, 0x1E, 0x3F, 0xF6, 0x3F, 0x84, 0xFF, 0xF0, + 0x19, 0x8C, 0xC6, 0x23, 0x18, 0xC6, 0x31, 0x8C, 0x63, 0x08, 0x43, 0x18, + 0x63, 0x0C, 0xC2, 0x18, 0x43, 0x18, 0xC2, 0x10, 0xC6, 0x31, 0x88, 0x46, + 0x31, 0x88, 0xC4, 0x60, 0x11, 0x27, 0x5B, 0xE1, 0x0F, 0xB5, 0xC9, 0x10, + 0x06, 0x00, 0x60, 0x06, 0x00, 0x60, 0x06, 0x0F, 0xFF, 0xFF, 0xF0, 0x60, + 0x06, 0x00, 0x60, 0x06, 0x00, 0x60, 0xFD, 0xED, 0x00, 0xFF, 0xFC, 0xFF, + 0x80, 0x00, 0xC0, 0x20, 0x18, 0x06, 0x01, 0x00, 0xC0, 0x30, 0x08, 0x06, + 0x01, 0x80, 0xC0, 0x30, 0x0C, 0x06, 0x01, 0x80, 0x60, 0x30, 0x0C, 0x02, + 0x01, 0x80, 0x60, 0x10, 0x0C, 0x03, 0x00, 0x0F, 0xC0, 0x7F, 0x83, 0x87, + 0x18, 0x06, 0x60, 0x1B, 0x00, 0x3C, 0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x00, + 0x3C, 0x00, 0xF0, 0x03, 0xC0, 0x0D, 0x80, 0x66, 0x01, 0x8E, 0x1C, 0x1F, + 0xE0, 0x3F, 0x00, 0x37, 0xFB, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, + 0x1F, 0x83, 0xFC, 0x70, 0xEC, 0x06, 0xC0, 0x20, 0x03, 0x00, 0x20, 0x06, + 0x00, 0xE0, 0x1C, 0x03, 0x80, 0x60, 0x1C, 0x03, 0x80, 0x60, 0x0C, 0x00, + 0xFF, 0xFF, 0xFF, 0x0F, 0x81, 0xFF, 0x1C, 0x38, 0xC0, 0x68, 0x03, 0x00, + 0x18, 0x00, 0xC0, 0x0C, 0x07, 0xC0, 0x3F, 0x00, 0x1C, 0x00, 0x7C, 0x01, + 0xE0, 0x0F, 0x00, 0xEE, 0x0E, 0x3F, 0xE0, 0xFC, 0x00, 0x01, 0xC0, 0x18, + 0x03, 0x00, 0x70, 0x06, 0x00, 0xC0, 0x0C, 0x31, 0x83, 0x30, 0x33, 0x03, + 0x60, 0x3C, 0x03, 0xFF, 0xFF, 0xFF, 0x00, 0x30, 0x03, 0x00, 0x30, 0x03, + 0x7F, 0xF3, 0xFF, 0x98, 0x00, 0xC0, 0x06, 0x00, 0x30, 0x01, 0x80, 0x0F, + 0xF8, 0x7F, 0xE0, 0x03, 0x80, 0x0E, 0x00, 0x3C, 0x01, 0xE0, 0x0F, 0x80, + 0xEE, 0x0E, 0x3F, 0xE0, 0xFC, 0x00, 0x00, 0xE0, 0x3F, 0x07, 0x80, 0x70, + 0x03, 0x00, 0x30, 0x01, 0x80, 0x1D, 0xF8, 0xFF, 0xE7, 0x83, 0xB0, 0x0F, + 0x80, 0x3C, 0x01, 0xE0, 0x0F, 0x80, 0xEE, 0x0E, 0x3F, 0xE0, 0xFE, 0x00, + 0xFF, 0xFF, 0xFF, 0x00, 0x60, 0x06, 0x00, 0xC0, 0x0C, 0x01, 0x80, 0x18, + 0x03, 0x00, 0x30, 0x06, 0x00, 0x60, 0x0C, 0x00, 0xC0, 0x18, 0x01, 0x80, + 0x38, 0x03, 0x00, 0x0F, 0xC0, 0xFF, 0xC7, 0x03, 0x98, 0x06, 0x60, 0x19, + 0x80, 0x63, 0x03, 0x07, 0xF8, 0x3F, 0xF1, 0xC0, 0xEE, 0x01, 0xF0, 0x03, + 0xC0, 0x0F, 0x00, 0x3E, 0x01, 0xDC, 0x0E, 0x3F, 0xF0, 0x3F, 0x00, 0x0F, + 0xC0, 0xFF, 0xC7, 0x07, 0xB8, 0x06, 0xC0, 0x0F, 0x00, 0x3C, 0x00, 0xF0, + 0x03, 0xE0, 0x1D, 0xC0, 0xF3, 0xFE, 0x83, 0xF6, 0x00, 0x18, 0x00, 0xC0, + 0x06, 0x00, 0xF0, 0x3F, 0x80, 0xF0, 0x00, 0xFF, 0x80, 0x00, 0x00, 0x7F, + 0xC0, 0xFF, 0x80, 0x00, 0x00, 0x0F, 0xDE, 0xD0, 0x00, 0x20, 0x3C, 0x1E, + 0x0F, 0x0F, 0x01, 0x80, 0x3C, 0x00, 0xE0, 0x07, 0x80, 0x3C, 0x00, 0x80, + 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0x80, + 0x1E, 0x00, 0xF0, 0x07, 0x80, 0x1E, 0x00, 0xC0, 0x78, 0x38, 0x3C, 0x1E, + 0x02, 0x00, 0x00, 0x1F, 0x83, 0xFC, 0x70, 0xEE, 0x03, 0xC0, 0x30, 0x03, + 0x00, 0x70, 0x0E, 0x01, 0xC0, 0x38, 0x07, 0x00, 0x60, 0x06, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x06, 0x00, 0x60, 0x00, 0xFE, 0x00, 0x0F, 0xFF, 0x80, + 0x3C, 0x07, 0x80, 0xE0, 0x03, 0x83, 0x00, 0x01, 0x8E, 0x1F, 0x9B, 0x98, + 0x7F, 0xB3, 0x71, 0xC1, 0xE6, 0xC7, 0x01, 0xC7, 0x8C, 0x01, 0x8F, 0x18, + 0x03, 0x1E, 0x30, 0x06, 0x3C, 0x60, 0x0C, 0x78, 0xC0, 0x18, 0xF1, 0xC0, + 0x71, 0xB1, 0xC1, 0xE6, 0x61, 0xFE, 0xFC, 0x61, 0xF8, 0xF0, 0xC0, 0x00, + 0x00, 0xE0, 0x00, 0x00, 0xF0, 0x08, 0x00, 0xFF, 0xF0, 0x00, 0x3F, 0x80, + 0x00, 0x00, 0xC0, 0x00, 0x38, 0x00, 0x1E, 0x00, 0x07, 0x80, 0x03, 0x30, + 0x00, 0xCC, 0x00, 0x61, 0x80, 0x18, 0x60, 0x0C, 0x0C, 0x03, 0x03, 0x00, + 0x80, 0x60, 0x60, 0x18, 0x1F, 0xFF, 0x0F, 0xFF, 0xC3, 0x00, 0x31, 0x80, + 0x06, 0x60, 0x01, 0xB0, 0x00, 0x30, 0xFF, 0xE1, 0xFF, 0xF3, 0x00, 0x76, + 0x00, 0x6C, 0x00, 0xD8, 0x01, 0xB0, 0x03, 0x60, 0x0C, 0xFF, 0xF1, 0xFF, + 0xF3, 0x00, 0x36, 0x00, 0x3C, 0x00, 0x78, 0x00, 0xF0, 0x01, 0xE0, 0x07, + 0xFF, 0xFD, 0xFF, 0xE0, 0x03, 0xF0, 0x0F, 0xFE, 0x0F, 0x03, 0x8E, 0x00, + 0x66, 0x00, 0x1F, 0x00, 0x0F, 0x00, 0x01, 0x80, 0x00, 0xC0, 0x00, 0x60, + 0x00, 0x30, 0x00, 0x18, 0x00, 0x0E, 0x00, 0x1B, 0x00, 0x0D, 0xC0, 0x0C, + 0x78, 0x1C, 0x1F, 0xFC, 0x03, 0xF8, 0x00, 0xFF, 0xE0, 0xFF, 0xF8, 0xC0, + 0x3C, 0xC0, 0x0E, 0xC0, 0x06, 0xC0, 0x07, 0xC0, 0x03, 0xC0, 0x03, 0xC0, + 0x03, 0xC0, 0x03, 0xC0, 0x03, 0xC0, 0x03, 0xC0, 0x07, 0xC0, 0x06, 0xC0, + 0x0E, 0xC0, 0x3C, 0xFF, 0xF8, 0xFF, 0xE0, 0xFF, 0xF7, 0xFF, 0xB0, 0x01, + 0x80, 0x0C, 0x00, 0x60, 0x03, 0x00, 0x18, 0x00, 0xFF, 0xF7, 0xFF, 0xB0, + 0x01, 0x80, 0x0C, 0x00, 0x60, 0x03, 0x00, 0x18, 0x00, 0xFF, 0xFF, 0xFF, + 0xC0, 0xFF, 0xFF, 0xFF, 0xC0, 0x0C, 0x00, 0xC0, 0x0C, 0x00, 0xC0, 0x0C, + 0x00, 0xFF, 0xFF, 0xFF, 0xC0, 0x0C, 0x00, 0xC0, 0x0C, 0x00, 0xC0, 0x0C, + 0x00, 0xC0, 0x0C, 0x00, 0x03, 0xF0, 0x07, 0xFF, 0x03, 0xC0, 0xE1, 0xC0, + 0x0C, 0x60, 0x01, 0x98, 0x00, 0x6C, 0x00, 0x03, 0x00, 0x00, 0xC0, 0x00, + 0x30, 0x1F, 0xFC, 0x07, 0xFF, 0x00, 0x03, 0xE0, 0x00, 0xD8, 0x00, 0x67, + 0x00, 0x38, 0xF0, 0x3C, 0x1F, 0xFE, 0x01, 0xFE, 0x00, 0xC0, 0x07, 0x80, + 0x0F, 0x00, 0x1E, 0x00, 0x3C, 0x00, 0x78, 0x00, 0xF0, 0x01, 0xE0, 0x03, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x1E, 0x00, 0x3C, 0x00, 0x78, 0x00, 0xF0, + 0x01, 0xE0, 0x03, 0xC0, 0x07, 0x80, 0x0C, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, + 0x01, 0x80, 0xC0, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x03, 0x01, 0x80, 0xC0, + 0x60, 0x30, 0x18, 0x0C, 0x0F, 0x0E, 0xFE, 0x3E, 0x00, 0xC0, 0x1D, 0x80, + 0x33, 0x00, 0xC6, 0x03, 0x0C, 0x0C, 0x18, 0x30, 0x30, 0xC0, 0x63, 0x00, + 0xCE, 0x01, 0xBE, 0x03, 0xE6, 0x07, 0x8E, 0x0E, 0x0E, 0x18, 0x0E, 0x30, + 0x0C, 0x60, 0x0C, 0xC0, 0x0D, 0x80, 0x1C, 0xC0, 0x0C, 0x00, 0xC0, 0x0C, + 0x00, 0xC0, 0x0C, 0x00, 0xC0, 0x0C, 0x00, 0xC0, 0x0C, 0x00, 0xC0, 0x0C, + 0x00, 0xC0, 0x0C, 0x00, 0xC0, 0x0C, 0x00, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, + 0x7C, 0x00, 0x1F, 0x80, 0x03, 0xF8, 0x00, 0xFF, 0x00, 0x1F, 0xB0, 0x06, + 0xF6, 0x00, 0xDE, 0x60, 0x33, 0xCC, 0x06, 0x78, 0xC1, 0x8F, 0x18, 0x31, + 0xE1, 0x8C, 0x3C, 0x31, 0x87, 0x83, 0x60, 0xF0, 0x6C, 0x1E, 0x07, 0x03, + 0xC0, 0xE0, 0x78, 0x08, 0x0C, 0xC0, 0x07, 0xC0, 0x0F, 0x80, 0x1F, 0x80, + 0x3D, 0x80, 0x79, 0x80, 0xF1, 0x81, 0xE3, 0x03, 0xC3, 0x07, 0x83, 0x0F, + 0x03, 0x1E, 0x07, 0x3C, 0x06, 0x78, 0x06, 0xF0, 0x07, 0xE0, 0x07, 0xC0, + 0x0F, 0x80, 0x0C, 0x03, 0xF0, 0x07, 0xFF, 0x83, 0xC0, 0xF1, 0xC0, 0x0E, + 0x60, 0x01, 0xB8, 0x00, 0x6C, 0x00, 0x0F, 0x00, 0x03, 0xC0, 0x00, 0xF0, + 0x00, 0x3C, 0x00, 0x0F, 0x00, 0x03, 0xE0, 0x01, 0x98, 0x00, 0x67, 0x00, + 0x38, 0xF0, 0x3C, 0x1F, 0xFE, 0x01, 0xFE, 0x00, 0xFF, 0xE3, 0xFF, 0xCC, + 0x03, 0xB0, 0x07, 0xC0, 0x0F, 0x00, 0x3C, 0x00, 0xF0, 0x03, 0xC0, 0x1F, + 0x00, 0xEF, 0xFF, 0x3F, 0xF8, 0xC0, 0x03, 0x00, 0x0C, 0x00, 0x30, 0x00, + 0xC0, 0x03, 0x00, 0x00, 0x03, 0xF0, 0x07, 0xFF, 0x83, 0xC0, 0xF1, 0xC0, + 0x0E, 0x60, 0x01, 0xB8, 0x00, 0x7C, 0x00, 0x0F, 0x00, 0x03, 0xC0, 0x00, + 0xF0, 0x00, 0x3C, 0x00, 0x0F, 0x00, 0xE3, 0xE0, 0x0D, 0x98, 0x01, 0xE7, + 0x00, 0x30, 0xF0, 0x3E, 0x1F, 0xFF, 0xC0, 0xFC, 0x30, 0xFF, 0xE3, 0xFF, + 0xCC, 0x03, 0xB0, 0x07, 0xC0, 0x0F, 0x00, 0x3C, 0x00, 0xF0, 0x03, 0xC0, + 0x1F, 0x00, 0xEF, 0xFF, 0xBF, 0xF8, 0xC0, 0xC3, 0x01, 0x8C, 0x03, 0x30, + 0x0C, 0xC0, 0x1B, 0x00, 0x30, 0x0F, 0xC0, 0x7F, 0xE0, 0xE0, 0xE3, 0x00, + 0xE6, 0x00, 0xCC, 0x00, 0x1C, 0x00, 0x1C, 0x00, 0x1F, 0xC0, 0x07, 0xF0, + 0x00, 0x70, 0x00, 0x30, 0x00, 0x78, 0x00, 0xD8, 0x01, 0xBC, 0x0E, 0x1F, + 0xF8, 0x0F, 0xC0, 0xFF, 0xFF, 0xFF, 0xF0, 0x30, 0x00, 0xC0, 0x03, 0x00, + 0x0C, 0x00, 0x30, 0x00, 0xC0, 0x03, 0x00, 0x0C, 0x00, 0x30, 0x00, 0xC0, + 0x03, 0x00, 0x0C, 0x00, 0x30, 0x00, 0xC0, 0x03, 0x00, 0x0C, 0x00, 0xC0, + 0x07, 0x80, 0x0F, 0x00, 0x1E, 0x00, 0x3C, 0x00, 0x78, 0x00, 0xF0, 0x01, + 0xE0, 0x03, 0xC0, 0x07, 0x80, 0x0F, 0x00, 0x1E, 0x00, 0x3C, 0x00, 0x6C, + 0x01, 0x98, 0x03, 0x1C, 0x1C, 0x3F, 0xF0, 0x1F, 0xC0, 0xC0, 0x00, 0xD8, + 0x00, 0x66, 0x00, 0x18, 0xC0, 0x0C, 0x30, 0x03, 0x06, 0x00, 0xC1, 0x80, + 0x60, 0x20, 0x18, 0x0C, 0x0C, 0x03, 0x03, 0x00, 0x61, 0x80, 0x18, 0x60, + 0x03, 0x30, 0x00, 0xCC, 0x00, 0x1A, 0x00, 0x07, 0x80, 0x00, 0xE0, 0x00, + 0x30, 0x00, 0xC0, 0x0C, 0x01, 0xB0, 0x06, 0x00, 0xD8, 0x07, 0x00, 0x6C, + 0x03, 0xC0, 0x63, 0x01, 0x60, 0x31, 0x81, 0xB0, 0x18, 0xC0, 0xCC, 0x18, + 0x30, 0x46, 0x0C, 0x18, 0x63, 0x06, 0x0C, 0x30, 0xC6, 0x02, 0x10, 0x63, + 0x01, 0x98, 0x31, 0x80, 0xCC, 0x0D, 0x80, 0x24, 0x06, 0xC0, 0x1E, 0x03, + 0x60, 0x0F, 0x00, 0xE0, 0x03, 0x00, 0x70, 0x01, 0x80, 0x38, 0x00, 0x60, + 0x07, 0x30, 0x0C, 0x38, 0x0C, 0x18, 0x18, 0x0C, 0x30, 0x06, 0x70, 0x07, + 0x60, 0x03, 0xC0, 0x01, 0x80, 0x03, 0xC0, 0x03, 0xE0, 0x06, 0x60, 0x0C, + 0x30, 0x1C, 0x18, 0x18, 0x18, 0x30, 0x0C, 0x60, 0x06, 0xE0, 0x07, 0xC0, + 0x03, 0x60, 0x06, 0x30, 0x0C, 0x30, 0x0C, 0x18, 0x18, 0x1C, 0x38, 0x0C, + 0x30, 0x06, 0x60, 0x07, 0xE0, 0x03, 0xC0, 0x01, 0x80, 0x01, 0x80, 0x01, + 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0xFF, + 0xFD, 0xFF, 0xF8, 0x00, 0x60, 0x01, 0x80, 0x03, 0x00, 0x0C, 0x00, 0x30, + 0x00, 0xC0, 0x03, 0x00, 0x0E, 0x00, 0x18, 0x00, 0x60, 0x01, 0x80, 0x06, + 0x00, 0x18, 0x00, 0x70, 0x00, 0xFF, 0xFF, 0xFF, 0xFC, 0xFE, 0x31, 0x8C, + 0x63, 0x18, 0xC6, 0x31, 0x8C, 0x63, 0x18, 0xC6, 0x31, 0x8C, 0x7C, 0xC0, + 0x30, 0x04, 0x01, 0x80, 0x60, 0x08, 0x03, 0x00, 0xC0, 0x18, 0x06, 0x01, + 0x80, 0x30, 0x0C, 0x03, 0x00, 0x60, 0x18, 0x02, 0x00, 0xC0, 0x30, 0x04, + 0x01, 0x80, 0x60, 0x08, 0x03, 0xF8, 0xC6, 0x31, 0x8C, 0x63, 0x18, 0xC6, + 0x31, 0x8C, 0x63, 0x18, 0xC6, 0x31, 0xFC, 0x0C, 0x01, 0xC0, 0x28, 0x0D, + 0x81, 0x10, 0x63, 0x0C, 0x23, 0x04, 0x60, 0xC8, 0x0B, 0x01, 0x80, 0xFF, + 0xF8, 0xE0, 0xC1, 0xC0, 0x0F, 0xCC, 0xFF, 0xF7, 0x03, 0xD8, 0x07, 0xC0, + 0x0F, 0x00, 0x3C, 0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x36, 0x01, 0xDC, + 0x0F, 0x3F, 0xFC, 0x3F, 0x30, 0xC0, 0x03, 0x00, 0x0C, 0x00, 0x30, 0x00, + 0xC0, 0x03, 0x3F, 0x0F, 0xFF, 0x3C, 0x0E, 0xE0, 0x1B, 0x00, 0x3C, 0x00, + 0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x3C, 0x00, 0xF8, 0x06, 0xF0, 0x3B, 0xFF, + 0xCC, 0xFC, 0x00, 0x0F, 0xC1, 0xFF, 0x1C, 0x1C, 0xC0, 0x3C, 0x01, 0xE0, + 0x03, 0x00, 0x18, 0x00, 0xC0, 0x06, 0x00, 0xD8, 0x06, 0xE0, 0xE3, 0xFE, + 0x07, 0xE0, 0x00, 0x0C, 0x00, 0x30, 0x00, 0xC0, 0x03, 0x00, 0x0C, 0x3F, + 0x33, 0xFF, 0xDC, 0x0F, 0x60, 0x1F, 0x00, 0x3C, 0x00, 0xF0, 0x03, 0xC0, + 0x0F, 0x00, 0x3C, 0x00, 0xD8, 0x07, 0x70, 0x3C, 0xFF, 0xF0, 0xFC, 0xC0, + 0x0F, 0xC0, 0xFF, 0xC7, 0x87, 0x18, 0x06, 0xC0, 0x1B, 0x00, 0x2C, 0x00, + 0xBF, 0xFE, 0xC0, 0x03, 0x00, 0x06, 0x01, 0x1C, 0x0E, 0x3F, 0xF0, 0x3F, + 0x00, 0x3C, 0xFF, 0x96, 0x0C, 0x1F, 0xBF, 0x60, 0xC1, 0x83, 0x06, 0x0C, + 0x18, 0x30, 0x60, 0xC1, 0x83, 0x00, 0x00, 0x10, 0x00, 0xE0, 0xFF, 0x0F, + 0xFC, 0x70, 0x3B, 0x80, 0x7C, 0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x36, + 0x01, 0x9C, 0x0E, 0x1F, 0xE0, 0x0F, 0xC0, 0x03, 0x80, 0x03, 0xC0, 0x0F, + 0x80, 0x77, 0x03, 0x8F, 0xFC, 0x1F, 0xE0, 0xC0, 0x06, 0x00, 0x30, 0x01, + 0x80, 0x0C, 0x00, 0x67, 0xE3, 0x7F, 0xDE, 0x0E, 0xE0, 0x3E, 0x00, 0xF0, + 0x07, 0x80, 0x3C, 0x01, 0xE0, 0x0F, 0x00, 0x78, 0x03, 0xC0, 0x1E, 0x00, + 0xF0, 0x06, 0xF0, 0x3F, 0xFF, 0xFF, 0xFC, 0x0C, 0x30, 0x00, 0x00, 0x30, + 0xC3, 0x0C, 0x30, 0xC3, 0x0C, 0x30, 0xC3, 0x0C, 0x30, 0xC3, 0x0C, 0x7F, + 0xBC, 0xC0, 0x06, 0x00, 0x30, 0x01, 0x80, 0x0C, 0x00, 0x60, 0x1F, 0x01, + 0x98, 0x18, 0xC1, 0x86, 0x18, 0x31, 0x81, 0x9E, 0x0D, 0xB8, 0x78, 0xC3, + 0x83, 0x18, 0x1C, 0xC0, 0x66, 0x01, 0xB0, 0x0E, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFC, 0xCF, 0x83, 0xE3, 0xFF, 0xBF, 0xEF, 0x0F, 0xC3, 0xB8, 0x1E, 0x07, + 0xC0, 0x30, 0x0F, 0x00, 0xC0, 0x3C, 0x03, 0x00, 0xF0, 0x0C, 0x03, 0xC0, + 0x30, 0x0F, 0x00, 0xC0, 0x3C, 0x03, 0x00, 0xF0, 0x0C, 0x03, 0xC0, 0x30, + 0x0F, 0x00, 0xC0, 0x30, 0xCF, 0xC7, 0xFF, 0xBC, 0x1D, 0xC0, 0x7C, 0x01, + 0xE0, 0x0F, 0x00, 0x78, 0x03, 0xC0, 0x1E, 0x00, 0xF0, 0x07, 0x80, 0x3C, + 0x01, 0xE0, 0x0C, 0x0F, 0xC0, 0xFF, 0xC7, 0x03, 0x98, 0x06, 0xC0, 0x0F, + 0x00, 0x3C, 0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x36, 0x01, 0x9C, 0x0E, + 0x3F, 0xF0, 0x3F, 0x00, 0xCF, 0xC3, 0xFF, 0xCF, 0x03, 0xB8, 0x06, 0xC0, + 0x0F, 0x00, 0x3C, 0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x3E, 0x01, 0xBC, + 0x0E, 0xFF, 0xF3, 0x3F, 0x0C, 0x00, 0x30, 0x00, 0xC0, 0x03, 0x00, 0x0C, + 0x00, 0x00, 0x0F, 0xCC, 0xFF, 0xF7, 0x03, 0xD8, 0x07, 0xC0, 0x0F, 0x00, + 0x3C, 0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x36, 0x01, 0xDC, 0x0F, 0x3F, + 0xFC, 0x3F, 0x30, 0x00, 0xC0, 0x03, 0x00, 0x0C, 0x00, 0x30, 0x00, 0x80, + 0xCF, 0xFF, 0xC7, 0x0C, 0x18, 0x30, 0x60, 0xC1, 0x83, 0x06, 0x0C, 0x18, + 0x00, 0x3F, 0x07, 0xF8, 0xE0, 0xCC, 0x06, 0xC0, 0x66, 0x00, 0x3E, 0x00, + 0x3C, 0x00, 0x6C, 0x03, 0xC0, 0x37, 0x07, 0x3F, 0xE1, 0xF8, 0xC1, 0x83, + 0x07, 0xEF, 0xD8, 0x30, 0x60, 0xC1, 0x83, 0x06, 0x0C, 0x18, 0x39, 0x3F, + 0x3C, 0xC0, 0x1E, 0x00, 0xF0, 0x07, 0x80, 0x3C, 0x01, 0xE0, 0x0F, 0x00, + 0x78, 0x03, 0xC0, 0x1E, 0x00, 0xF8, 0x0E, 0xE0, 0xF7, 0xFD, 0x8F, 0xCC, + 0xC0, 0x0D, 0x80, 0x66, 0x01, 0x8C, 0x06, 0x30, 0x30, 0x40, 0xC1, 0x86, + 0x06, 0x18, 0x0C, 0xC0, 0x33, 0x00, 0x68, 0x01, 0xE0, 0x03, 0x80, 0x0C, + 0x00, 0xC0, 0x30, 0x1D, 0x80, 0xC0, 0x66, 0x07, 0x01, 0x98, 0x1E, 0x0C, + 0x30, 0x58, 0x30, 0xC3, 0x20, 0x81, 0x0C, 0xC6, 0x06, 0x23, 0x18, 0x19, + 0x84, 0xC0, 0x36, 0x1B, 0x00, 0xF0, 0x6C, 0x03, 0xC0, 0xE0, 0x06, 0x03, + 0x80, 0x18, 0x04, 0x00, 0xE0, 0x18, 0xC0, 0xC3, 0x86, 0x06, 0x38, 0x0D, + 0xC0, 0x1E, 0x00, 0x70, 0x01, 0xE0, 0x0F, 0x80, 0x33, 0x01, 0x86, 0x0C, + 0x1C, 0x60, 0x33, 0x80, 0x70, 0xE0, 0x0D, 0x80, 0x77, 0x01, 0x8C, 0x0E, + 0x38, 0x30, 0x61, 0xC0, 0xC6, 0x03, 0x30, 0x06, 0xC0, 0x1E, 0x00, 0x38, + 0x00, 0xC0, 0x03, 0x00, 0x18, 0x00, 0x60, 0x03, 0x00, 0x0C, 0x00, 0x60, + 0x01, 0x80, 0x00, 0xFF, 0xFF, 0xFC, 0x03, 0x00, 0xC0, 0x30, 0x06, 0x01, + 0x80, 0x60, 0x18, 0x06, 0x00, 0xC0, 0x30, 0x0F, 0xFF, 0xFF, 0xC0, 0x0E, + 0x70, 0xC1, 0x83, 0x06, 0x0C, 0x18, 0x30, 0x63, 0x81, 0x83, 0x06, 0x0C, + 0x18, 0x30, 0x60, 0xC1, 0x81, 0x81, 0xC0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xF0, 0xF0, 0xE1, 0x86, 0x18, 0x61, 0x86, 0x18, 0x60, 0xC6, 0x18, 0x61, + 0x86, 0x18, 0x61, 0x86, 0x33, 0x80, 0x78, 0x39, 0xCE, 0x0F, 0x00 }; + +const GFXglyph Bronova_Regular13pt7bGlyphs[] PROGMEM = { + { 0, 1, 1, 8, 0, 0 }, // 0x20 ' ' + { 1, 2, 18, 6, 2, -17 }, // 0x21 '!' + { 6, 5, 6, 7, 1, -17 }, // 0x22 '"' + { 10, 16, 18, 20, 2, -17 }, // 0x23 '#' + { 46, 15, 24, 19, 2, -20 }, // 0x24 '$' + { 91, 18, 18, 23, 2, -17 }, // 0x25 '%' + { 132, 15, 18, 19, 2, -17 }, // 0x26 '&' + { 166, 2, 6, 4, 1, -17 }, // 0x27 ''' + { 168, 5, 22, 8, 1, -17 }, // 0x28 '(' + { 182, 5, 22, 8, 2, -17 }, // 0x29 ')' + { 196, 7, 9, 12, 2, -18 }, // 0x2A '*' + { 204, 12, 12, 15, 1, -13 }, // 0x2B '+' + { 222, 3, 6, 6, 1, -1 }, // 0x2C ',' + { 225, 7, 2, 11, 2, -7 }, // 0x2D '-' + { 227, 3, 3, 6, 1, -2 }, // 0x2E '.' + { 229, 10, 24, 12, 1, -20 }, // 0x2F '/' + { 259, 14, 18, 16, 1, -17 }, // 0x30 '0' + { 291, 4, 18, 7, 1, -17 }, // 0x31 '1' + { 300, 12, 18, 15, 2, -17 }, // 0x32 '2' + { 327, 13, 18, 17, 2, -17 }, // 0x33 '3' + { 357, 12, 18, 15, 2, -17 }, // 0x34 '4' + { 384, 13, 18, 15, 1, -17 }, // 0x35 '5' + { 414, 13, 18, 17, 2, -17 }, // 0x36 '6' + { 444, 12, 18, 14, 1, -17 }, // 0x37 '7' + { 471, 14, 18, 18, 2, -17 }, // 0x38 '8' + { 503, 14, 18, 17, 1, -17 }, // 0x39 '9' + { 535, 3, 14, 6, 1, -13 }, // 0x3A ':' + { 541, 3, 18, 6, 1, -13 }, // 0x3B ';' + { 548, 11, 11, 15, 2, -11 }, // 0x3C '<' + { 564, 11, 8, 15, 2, -10 }, // 0x3D '=' + { 575, 11, 11, 15, 2, -11 }, // 0x3E '>' + { 591, 12, 18, 14, 1, -17 }, // 0x3F '?' + { 618, 23, 23, 26, 2, -18 }, // 0x40 '@' + { 685, 18, 18, 18, 0, -17 }, // 0x41 'A' + { 726, 15, 18, 18, 2, -17 }, // 0x42 'B' + { 760, 17, 18, 19, 1, -17 }, // 0x43 'C' + { 799, 16, 18, 19, 2, -17 }, // 0x44 'D' + { 835, 13, 18, 15, 2, -17 }, // 0x45 'E' + { 865, 12, 18, 16, 2, -17 }, // 0x46 'F' + { 892, 18, 18, 20, 1, -17 }, // 0x47 'G' + { 933, 15, 18, 19, 2, -17 }, // 0x48 'H' + { 967, 2, 18, 7, 3, -17 }, // 0x49 'I' + { 972, 9, 18, 11, 0, -17 }, // 0x4A 'J' + { 993, 15, 18, 18, 2, -17 }, // 0x4B 'K' + { 1027, 12, 18, 14, 2, -17 }, // 0x4C 'L' + { 1054, 19, 18, 23, 2, -17 }, // 0x4D 'M' + { 1097, 15, 18, 19, 2, -17 }, // 0x4E 'N' + { 1131, 18, 18, 20, 1, -17 }, // 0x4F 'O' + { 1172, 14, 18, 17, 2, -17 }, // 0x50 'P' + { 1204, 18, 18, 20, 1, -17 }, // 0x51 'Q' + { 1245, 14, 18, 17, 2, -17 }, // 0x52 'R' + { 1277, 15, 18, 17, 1, -17 }, // 0x53 'S' + { 1311, 14, 18, 15, 0, -17 }, // 0x54 'T' + { 1343, 15, 18, 19, 2, -17 }, // 0x55 'U' + { 1377, 18, 18, 18, 0, -17 }, // 0x56 'V' + { 1418, 25, 18, 25, 0, -17 }, // 0x57 'W' + { 1475, 16, 18, 16, 0, -17 }, // 0x58 'X' + { 1511, 16, 18, 16, 0, -17 }, // 0x59 'Y' + { 1547, 15, 18, 18, 2, -17 }, // 0x5A 'Z' + { 1581, 5, 22, 9, 2, -17 }, // 0x5B '[' + { 1595, 10, 24, 12, 1, -20 }, // 0x5C '\' + { 1625, 5, 22, 9, 1, -17 }, // 0x5D ']' + { 1639, 11, 11, 15, 2, -13 }, // 0x5E '^' + { 1655, 13, 1, 16, 2, 1 }, // 0x5F '_' + { 1657, 6, 3, 8, 1, -17 }, // 0x60 '`' + { 1660, 14, 14, 17, 1, -13 }, // 0x61 'a' + { 1685, 14, 19, 17, 2, -18 }, // 0x62 'b' + { 1719, 13, 14, 16, 1, -13 }, // 0x63 'c' + { 1742, 14, 19, 17, 1, -18 }, // 0x64 'd' + { 1776, 14, 14, 16, 1, -13 }, // 0x65 'e' + { 1801, 7, 19, 9, 2, -18 }, // 0x66 'f' + { 1818, 14, 21, 16, 1, -15 }, // 0x67 'g' + { 1855, 13, 19, 16, 2, -18 }, // 0x68 'h' + { 1886, 2, 19, 6, 2, -18 }, // 0x69 'i' + { 1891, 6, 24, 7, -1, -18 }, // 0x6A 'j' + { 1909, 13, 19, 15, 2, -18 }, // 0x6B 'k' + { 1940, 2, 19, 6, 2, -18 }, // 0x6C 'l' + { 1945, 22, 14, 26, 2, -13 }, // 0x6D 'm' + { 1984, 13, 14, 16, 2, -13 }, // 0x6E 'n' + { 2007, 14, 14, 16, 1, -13 }, // 0x6F 'o' + { 2032, 14, 19, 17, 2, -13 }, // 0x70 'p' + { 2066, 14, 19, 17, 1, -13 }, // 0x71 'q' + { 2100, 7, 14, 9, 2, -13 }, // 0x72 'r' + { 2113, 12, 14, 14, 1, -13 }, // 0x73 's' + { 2134, 7, 17, 9, 2, -16 }, // 0x74 't' + { 2149, 13, 14, 16, 2, -13 }, // 0x75 'u' + { 2172, 14, 14, 14, 0, -13 }, // 0x76 'v' + { 2197, 22, 14, 22, 0, -13 }, // 0x77 'w' + { 2236, 14, 14, 14, 0, -13 }, // 0x78 'x' + { 2261, 14, 19, 14, 0, -13 }, // 0x79 'y' + { 2295, 11, 14, 13, 1, -13 }, // 0x7A 'z' + { 2315, 7, 22, 10, 1, -17 }, // 0x7B '{' + { 2335, 2, 22, 6, 2, -17 }, // 0x7C '|' + { 2341, 6, 22, 10, 2, -17 }, // 0x7D '}' + { 2358, 11, 3, 16, 2, -9 } }; // 0x7E '~' + +const GFXfont Bronova_Regular13pt7b PROGMEM = { + (uint8_t *)Bronova_Regular13pt7bBitmaps, + (GFXglyph *)Bronova_Regular13pt7bGlyphs, + 0x20, 0x7E, 28 }; + +// Approx. 3035 bytes diff --git a/src/Defines_GSR.h b/src/Defines_GSR.h new file mode 100644 index 0000000..01e76ea --- /dev/null +++ b/src/Defines_GSR.h @@ -0,0 +1,93 @@ +#ifndef DEFINES_GSR_H +#define DEFINES_GSR_H + +//debug +#define USEDEBUG 1 // !0 is on, will not setup Serial OR print output if zero. + +//display +#define BLE_DEVICE_NAME "Watchy BLE OTA" +#define WATCHFACE_NAME "Watchy GSR" +#define SOFTWARE_VERSION_MAJOR 1 +#define SOFTWARE_VERSION_MINOR 0 +#define SOFTWARE_VERSION_PATCH 0 +#define HARDWARE_VERSION_MAJOR 1 +#define HARDWARE_VERSION_MINOR 0 + +// WiFi +#define WiFi_AP_SSID "Watchy Connect" +#define WiFi_AP_PSWD "Watchy123" +#define WiFi_AP_HIDE false + +// Battery +#define MinBattery 3.58 + +// functions +#define clamp(v,lo,hi) (((v)<(lo))?(lo):((v)>(hi))?(hi):(v)) +#define roller(v,lo,hi) (((v)<(lo))?(hi):((v)>(hi))?(lo):(v)) +#define gobig(v,lo) ((v)>(lo)?(v):(lo)) +#define golow(v,hi) ((v)<(hi)?(v):(hi)) + +// Watch face states. +#define WATCHON 0 +#define MENUON 1 + +// Nenu offset defines. +#define MenuTop 72 +#define MenuHeight 83 +#define HeaderY 97 +#define DataY 138 + +// Watchface offset defines. +#define TimeY 56 +#define DayY 101 +#define DateY 143 +#define YearY 186 + +// NTP & TZ Offset defines. +#define NTPY 193 +#define NTPX 5 + +// Menu offsets so I don't have to statically entere them everywhere. +#define MENU_STEPS 0 +#define MENU_ALARMS 1 +#define MENU_TIMERS 2 +#define MENU_OPTIONS 3 +#define MENU_ALARM1 4 +#define MENU_ALARM4 7 +#define MENU_TIMEDN 8 +#define MENU_TIMEUP 9 +#define MENU_DISP 10 +#define MENU_BRDR 11 +#define MENU_SIDE 12 +#define MENU_SWAP 13 +#define MENU_MODE 14 +#define MENU_FEED 15 +#define MENU_TRBO 16 +#define MENU_SCRN 17 +#define MENU_SYNC 18 +#define MENU_WIFI 19 +#define MENU_OTAU 20 +#define MENU_OTAM 21 +#define MENU_RSET 22 + +// Menu segments. +#define MENU_INNORMAL 0 +#define MENU_INALARMS 1 +#define MENU_INTIMERS 2 +#define MENU_INOPTIONS 3 + +// Button debounce. +#define KEYPAUSE 333 + +//ALARM flags. +#define ALARM_REPEAT 128 +#define ALARM_ACTIVE 256 +#define ALARM_NOTRIGGER 511 +#define ALARM_TRIGGERED 512 +#define ALARM_DAYS 127 +#define ALARM_ALL 1023 + +// Setup lengths. +#define AlarmSetup 1234567890 + +#endif diff --git a/src/GSR.ino b/src/GSR.ino new file mode 100644 index 0000000..9e248b8 --- /dev/null +++ b/src/GSR.ino @@ -0,0 +1,9 @@ +#include "Watchy_GSR.h" + +Watchy watchy; + +void setup(){ + watchy.init(); +} + +void loop(){} diff --git a/src/GxEPD2_154_D67-B.cpp b/src/GxEPD2_154_D67-B.cpp new file mode 100644 index 0000000..572ebd9 --- /dev/null +++ b/src/GxEPD2_154_D67-B.cpp @@ -0,0 +1,378 @@ +// Display Library for SPI e-paper panels from Dalian Good Display and boards from Waveshare. +// Requires HW SPI and Adafruit_GFX. Caution: the e-paper panels require 3.3V supply AND data lines! +// +// based on Demo Example from Good Display, available here: http://www.e-paper-display.com/download_detail/downloadsId=806.html +// Panel: GDEH0154D67 : http://www.e-paper-display.com/products_detail/productId=455.html +// Controller : SSD1681 : http://www.e-paper-display.com/download_detail/downloadsId=825.html +// +// Author: Jean-Marc Zingg +// +// Version: see library.properties +// +// Library: https://github.com/ZinggJM/GxEPD2 + +#include "GxEPD2_154_D67-B.h" // GuruSR: Changed for setDarkBorder + +GxEPD2_154_D67::GxEPD2_154_D67(int8_t cs, int8_t dc, int8_t rst, int8_t busy) : + GxEPD2_EPD(cs, dc, rst, busy, HIGH, 10000000, WIDTH, HEIGHT, panel, hasColor, hasPartialUpdate, hasFastPartialUpdate) +{ +} + +bool IsDark; // GuruSR: Changed for setDarkBorder +void GxEPD2_154_D67::setDarkBorder(bool Dark){ // GuruSR: Changed for setDarkBorder + IsDark=Dark; // GuruSR: Changed for setDarkBorder +} // GuruSR: Changed for setDarkBorder + +void GxEPD2_154_D67::clearScreen(uint8_t value) +{ + writeScreenBuffer(value); + refresh(true); + writeScreenBufferAgain(value); +} + +void GxEPD2_154_D67::writeScreenBuffer(uint8_t value) +{ + if (!_using_partial_mode) _Init_Part(); + if (_initial_write) _writeScreenBuffer(0x26, value); // set previous + _writeScreenBuffer(0x24, value); // set current + _initial_write = false; // initial full screen buffer clean done +} + +void GxEPD2_154_D67::writeScreenBufferAgain(uint8_t value) +{ + if (!_using_partial_mode) _Init_Part(); + _writeScreenBuffer(0x24, value); // set current +} + +void GxEPD2_154_D67::_writeScreenBuffer(uint8_t command, uint8_t value) +{ + _writeCommand(command); + for (uint32_t i = 0; i < uint32_t(WIDTH) * uint32_t(HEIGHT) / 8; i++) + { + _writeData(value); + } +} + +void GxEPD2_154_D67::writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm) +{ + _writeImage(0x24, bitmap, x, y, w, h, invert, mirror_y, pgm); +} + +void GxEPD2_154_D67::writeImageForFullRefresh(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm) +{ + _writeImage(0x26, bitmap, x, y, w, h, invert, mirror_y, pgm); + _writeImage(0x24, bitmap, x, y, w, h, invert, mirror_y, pgm); +} + +void GxEPD2_154_D67::writeImageAgain(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm) +{ + _writeImage(0x24, bitmap, x, y, w, h, invert, mirror_y, pgm); +} + +void GxEPD2_154_D67::_writeImage(uint8_t command, const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm) +{ + if (_initial_write) writeScreenBuffer(); // initial full screen buffer clean + delay(1); // yield() to avoid WDT on ESP8266 and ESP32 + int16_t wb = (w + 7) / 8; // width bytes, bitmaps are padded + x -= x % 8; // byte boundary + w = wb * 8; // byte boundary + int16_t x1 = x < 0 ? 0 : x; // limit + int16_t y1 = y < 0 ? 0 : y; // limit + int16_t w1 = x + w < int16_t(WIDTH) ? w : int16_t(WIDTH) - x; // limit + int16_t h1 = y + h < int16_t(HEIGHT) ? h : int16_t(HEIGHT) - y; // limit + int16_t dx = x1 - x; + int16_t dy = y1 - y; + w1 -= dx; + h1 -= dy; + if ((w1 <= 0) || (h1 <= 0)) return; + if (!_using_partial_mode) _Init_Part(); + _setPartialRamArea(x1, y1, w1, h1); + _writeCommand(command); + for (int16_t i = 0; i < h1; i++) + { + for (int16_t j = 0; j < w1 / 8; j++) + { + uint8_t data; + // use wb, h of bitmap for index! + int16_t idx = mirror_y ? j + dx / 8 + ((h - 1 - (i + dy))) * wb : j + dx / 8 + (i + dy) * wb; + if (pgm) + { +#if defined(__AVR) || defined(ESP8266) || defined(ESP32) + data = pgm_read_byte(&bitmap[idx]); +#else + data = bitmap[idx]; +#endif + } + else + { + data = bitmap[idx]; + } + if (invert) data = ~data; + _writeData(data); + } + } + delay(1); // yield() to avoid WDT on ESP8266 and ESP32 +} + +void GxEPD2_154_D67::writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap, + int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm) +{ + _writeImagePart(0x24, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm); +} + +void GxEPD2_154_D67::writeImagePartAgain(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap, + int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm) +{ + _writeImagePart(0x24, bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm); +} + +void GxEPD2_154_D67::_writeImagePart(uint8_t command, const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap, + int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm) +{ + if (_initial_write) writeScreenBuffer(); // initial full screen buffer clean + delay(1); // yield() to avoid WDT on ESP8266 and ESP32 + if ((w_bitmap < 0) || (h_bitmap < 0) || (w < 0) || (h < 0)) return; + if ((x_part < 0) || (x_part >= w_bitmap)) return; + if ((y_part < 0) || (y_part >= h_bitmap)) return; + int16_t wb_bitmap = (w_bitmap + 7) / 8; // width bytes, bitmaps are padded + x_part -= x_part % 8; // byte boundary + w = w_bitmap - x_part < w ? w_bitmap - x_part : w; // limit + h = h_bitmap - y_part < h ? h_bitmap - y_part : h; // limit + x -= x % 8; // byte boundary + w = 8 * ((w + 7) / 8); // byte boundary, bitmaps are padded + int16_t x1 = x < 0 ? 0 : x; // limit + int16_t y1 = y < 0 ? 0 : y; // limit + int16_t w1 = x + w < int16_t(WIDTH) ? w : int16_t(WIDTH) - x; // limit + int16_t h1 = y + h < int16_t(HEIGHT) ? h : int16_t(HEIGHT) - y; // limit + int16_t dx = x1 - x; + int16_t dy = y1 - y; + w1 -= dx; + h1 -= dy; + if ((w1 <= 0) || (h1 <= 0)) return; + if (!_using_partial_mode) _Init_Part(); + _setPartialRamArea(x1, y1, w1, h1); + _writeCommand(command); + for (int16_t i = 0; i < h1; i++) + { + for (int16_t j = 0; j < w1 / 8; j++) + { + uint8_t data; + // use wb_bitmap, h_bitmap of bitmap for index! + int16_t idx = mirror_y ? x_part / 8 + j + dx / 8 + ((h_bitmap - 1 - (y_part + i + dy))) * wb_bitmap : x_part / 8 + j + dx / 8 + (y_part + i + dy) * wb_bitmap; + if (pgm) + { +#if defined(__AVR) || defined(ESP8266) || defined(ESP32) + data = pgm_read_byte(&bitmap[idx]); +#else + data = bitmap[idx]; +#endif + } + else + { + data = bitmap[idx]; + } + if (invert) data = ~data; + _writeData(data); + } + } + delay(1); // yield() to avoid WDT on ESP8266 and ESP32 +} + +void GxEPD2_154_D67::writeImage(const uint8_t* black, const uint8_t* color, int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm) +{ + if (black) + { + writeImage(black, x, y, w, h, invert, mirror_y, pgm); + } +} + +void GxEPD2_154_D67::writeImagePart(const uint8_t* black, const uint8_t* color, int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap, + int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm) +{ + if (black) + { + writeImagePart(black, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm); + } +} + +void GxEPD2_154_D67::writeNative(const uint8_t* data1, const uint8_t* data2, int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm) +{ + if (data1) + { + writeImage(data1, x, y, w, h, invert, mirror_y, pgm); + } +} + +void GxEPD2_154_D67::drawImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm) +{ + writeImage(bitmap, x, y, w, h, invert, mirror_y, pgm); + refresh(x, y, w, h); + writeImageAgain(bitmap, x, y, w, h, invert, mirror_y, pgm); +} + +void GxEPD2_154_D67::drawImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap, + int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm) +{ + writeImagePart(bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm); + refresh(x, y, w, h); + writeImagePartAgain(bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm); +} + +void GxEPD2_154_D67::drawImage(const uint8_t* black, const uint8_t* color, int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm) +{ + if (black) + { + drawImage(black, x, y, w, h, invert, mirror_y, pgm); + } +} + +void GxEPD2_154_D67::drawImagePart(const uint8_t* black, const uint8_t* color, int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap, + int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm) +{ + if (black) + { + drawImagePart(black, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm); + } +} + +void GxEPD2_154_D67::drawNative(const uint8_t* data1, const uint8_t* data2, int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm) +{ + if (data1) + { + drawImage(data1, x, y, w, h, invert, mirror_y, pgm); + } +} + +void GxEPD2_154_D67::refresh(bool partial_update_mode) +{ + if (partial_update_mode) refresh(0, 0, WIDTH, HEIGHT); + else + { + if (_using_partial_mode) _Init_Full(); + _Update_Full(); + _initial_refresh = false; // initial full update done + } +} + +void GxEPD2_154_D67::refresh(int16_t x, int16_t y, int16_t w, int16_t h) +{ + if (_initial_refresh) return refresh(false); // initial update needs be full update + x -= x % 8; // byte boundary + w -= x % 8; // byte boundary + int16_t x1 = x < 0 ? 0 : x; // limit + int16_t y1 = y < 0 ? 0 : y; // limit + int16_t w1 = x + w < int16_t(WIDTH) ? w : int16_t(WIDTH) - x; // limit + int16_t h1 = y + h < int16_t(HEIGHT) ? h : int16_t(HEIGHT) - y; // limit + w1 -= x1 - x; + h1 -= y1 - y; + if (!_using_partial_mode) _Init_Part(); + _setPartialRamArea(x1, y1, w1, h1); + _Update_Part(); +} + +void GxEPD2_154_D67::powerOff() +{ + _PowerOff(); +} + +void GxEPD2_154_D67::hibernate() +{ + _PowerOff(); + if (_rst >= 0) + { + _writeCommand(0x10); // deep sleep mode + _writeData(0x1); // enter deep sleep + _hibernating = true; + } +} + +void GxEPD2_154_D67::_setPartialRamArea(uint16_t x, uint16_t y, uint16_t w, uint16_t h) +{ + _writeCommand(0x11); // set ram entry mode + _writeData(0x03); // x increase, y increase : normal mode + _writeCommand(0x44); + _writeData(x / 8); + _writeData((x + w - 1) / 8); + _writeCommand(0x45); + _writeData(y % 256); + _writeData(y / 256); + _writeData((y + h - 1) % 256); + _writeData((y + h - 1) / 256); + _writeCommand(0x4e); + _writeData(x / 8); + _writeCommand(0x4f); + _writeData(y % 256); + _writeData(y / 256); +} + +void GxEPD2_154_D67::_PowerOn() +{ + if (!_power_is_on) + { + _writeCommand(0x22); + _writeData(0xf8); + _writeCommand(0x20); + _waitWhileBusy("_PowerOn", power_on_time); + } + _power_is_on = true; +} + +void GxEPD2_154_D67::_PowerOff() +{ + if (_power_is_on) + { + _writeCommand(0x22); + _writeData(0x83); + _writeCommand(0x20); + _waitWhileBusy("_PowerOff", power_off_time); + } + _power_is_on = false; + _using_partial_mode = false; +} + +void GxEPD2_154_D67::_InitDisplay() +{ + if (_hibernating) _reset(); + delay(10); // 10ms according to specs + _writeCommand(0x12); // soft reset + delay(10); // 10ms according to specs + _writeCommand(0x01); // Driver output control + _writeData(0xC7); + _writeData(0x00); + _writeData(0x00); + _writeCommand(0x3C); // BorderWavefrom + _writeData(IsDark ? 0x02 : 0x05); // GuruSR: Changed for setDarkBorder + _writeCommand(0x18); // Read built-in temperature sensor + _writeData(0x80); + _setPartialRamArea(0, 0, WIDTH, HEIGHT); +} + +void GxEPD2_154_D67::_Init_Full() +{ + _InitDisplay(); + _PowerOn(); + _using_partial_mode = false; +} + +void GxEPD2_154_D67::_Init_Part() +{ + _InitDisplay(); + _PowerOn(); + _using_partial_mode = true; +} + +void GxEPD2_154_D67::_Update_Full() +{ + _writeCommand(0x22); + _writeData(0xf4); + _writeCommand(0x20); + _waitWhileBusy("_Update_Full", full_refresh_time); +} + +void GxEPD2_154_D67::_Update_Part() +{ + _writeCommand(0x22); + _writeData(0xfc); + _writeCommand(0x20); + _waitWhileBusy("_Update_Part", partial_refresh_time); +} diff --git a/src/GxEPD2_154_D67-B.h b/src/GxEPD2_154_D67-B.h new file mode 100644 index 0000000..cb623e6 --- /dev/null +++ b/src/GxEPD2_154_D67-B.h @@ -0,0 +1,83 @@ +// Display Library for SPI e-paper panels from Dalian Good Display and boards from Waveshare. +// Requires HW SPI and Adafruit_GFX. Caution: the e-paper panels require 3.3V supply AND data lines! +// +// based on Demo Example from Good Display, available here: http://www.e-paper-display.com/download_detail/downloadsId=806.html +// Panel: GDEH0154D67 : http://www.e-paper-display.com/products_detail/productId=455.html +// Controller : SSD1681 : http://www.e-paper-display.com/download_detail/downloadsId=825.html +// +// Author: Jean-Marc Zingg +// +// Version: see library.properties +// +// Library: https://github.com/ZinggJM/GxEPD2 + +#ifndef _GxEPD2_154_D67_H_ +#define _GxEPD2_154_D67_H_ + +#include "../../libraries/GxEPD2/src/GxEPD2_EPD.h" // GuruSR: Changed for setDarkBorder + +class GxEPD2_154_D67 : public GxEPD2_EPD +{ + public: + // attributes + static const uint16_t WIDTH = 200; + static const uint16_t HEIGHT = 200; + static const GxEPD2::Panel panel = GxEPD2::GDEH0154D67; + static const bool hasColor = false; + static const bool hasPartialUpdate = true; + static const bool hasFastPartialUpdate = true; + static const uint16_t power_on_time = 100; // ms, e.g. 95583us + static const uint16_t power_off_time = 150; // ms, e.g. 140621us + static const uint16_t full_refresh_time = 2600; // ms, e.g. 2509602us + static const uint16_t partial_refresh_time = 500; // ms, e.g. 457282us + // constructor + GxEPD2_154_D67(int8_t cs, int8_t dc, int8_t rst, int8_t busy); + // methods (virtual) + // Support for Bitmaps (Sprites) to Controller Buffer and to Screen + void clearScreen(uint8_t value = 0xFF); // init controller memory and screen (default white) + void writeScreenBuffer(uint8_t value = 0xFF); // init controller memory (default white) + void writeScreenBufferAgain(uint8_t value = 0xFF); // init previous buffer controller memory (default white) + // write to controller memory, without screen refresh; x and w should be multiple of 8 + void writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false); + void writeImageForFullRefresh(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false); + void writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap, + int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false); + void writeImage(const uint8_t* black, const uint8_t* color, int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false); + void writeImagePart(const uint8_t* black, const uint8_t* color, int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap, + int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false); + // for differential update: set current and previous buffers equal (for fast partial update to work correctly) + void writeImageAgain(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false); + void writeImagePartAgain(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap, + int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false); + // write sprite of native data to controller memory, without screen refresh; x and w should be multiple of 8 + void writeNative(const uint8_t* data1, const uint8_t* data2, int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false); + // write to controller memory, with screen refresh; x and w should be multiple of 8 + void drawImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false); + void drawImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap, + int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool Dark = false); + void drawImage(const uint8_t* black, const uint8_t* color, int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false); + void drawImagePart(const uint8_t* black, const uint8_t* color, int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap, + int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false); + // write sprite of native data to controller memory, with screen refresh; x and w should be multiple of 8 + void drawNative(const uint8_t* data1, const uint8_t* data2, int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false); + void refresh(bool partial_update_mode = false); // screen refresh from controller memory to full screen + void refresh(int16_t x, int16_t y, int16_t w, int16_t h); // screen refresh from controller memory, partial screen + void powerOff(); // turns off generation of panel driving voltages, avoids screen fading over time + void hibernate(); // turns powerOff() and sets controller to deep sleep for minimum power use, ONLY if wakeable by RST (rst >= 0) + void setDarkBorder(bool Dark); // GuruSR: Changed for setDarkBorder + private: + void _writeScreenBuffer(uint8_t command, uint8_t value); + void _writeImage(uint8_t command, const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false); + void _writeImagePart(uint8_t command, const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap, + int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false); + void _setPartialRamArea(uint16_t x, uint16_t y, uint16_t w, uint16_t h); + void _PowerOn(); + void _PowerOff(); + void _InitDisplay(); + void _Init_Full(); + void _Init_Part(); + void _Update_Full(); + void _Update_Part(); +}; + +#endif diff --git a/src/GxEPD2_BW-B.h b/src/GxEPD2_BW-B.h new file mode 100644 index 0000000..594cedf --- /dev/null +++ b/src/GxEPD2_BW-B.h @@ -0,0 +1,586 @@ +// Display Library for SPI e-paper panels from Dalian Good Display and boards from Waveshare. +// Requires HW SPI and Adafruit_GFX. Caution: these e-papers require 3.3V supply AND data lines! +// +// based on Demo Example from Good Display: http://www.e-paper-display.com/download_list/downloadcategoryid=34&isMode=false.html +// +// Author: Jean-Marc Zingg +// +// Version: see library.properties +// +// Library: https://github.com/ZinggJM/GxEPD2 + +#ifndef _GxEPD2_BW_H_ +#define _GxEPD2_BW_H_ + +// uncomment next line to use class GFX of library GFX_Root instead of Adafruit_GFX +//#include + +#ifndef ENABLE_GxEPD2_GFX +// default is off +#define ENABLE_GxEPD2_GFX 0 +#endif + +#if ENABLE_GxEPD2_GFX +#include "../../libraries/GxEPD2/src/GxEPD2_GFX.h" // GuruSR: Changed for setDarkBorder +#define GxEPD2_GFX_BASE_CLASS GxEPD2_GFX +#elif defined(_GFX_H_) +#define GxEPD2_GFX_BASE_CLASS GFX +#else +#include +#define GxEPD2_GFX_BASE_CLASS Adafruit_GFX +#endif + +#include "../../libraries/GxEPD2/src/GxEPD2_EPD.h" // GuruSR: Changed for setDarkBorder +#include "../../libraries/GxEPD2/src/epd/GxEPD2_102.h" // GuruSR: Changed for setDarkBorder +#include "../../libraries/GxEPD2/src/epd/GxEPD2_154.h" // GuruSR: Changed for setDarkBorder +#include "GxEPD2_154_D67-B.h" // GuruSR: Changed for setDarkBorder +#include "../../libraries/GxEPD2/src/epd/GxEPD2_154_T8.h" // GuruSR: Changed for setDarkBorder +#include "../../libraries/GxEPD2/src/epd/GxEPD2_154_M09.h" // GuruSR: Changed for setDarkBorder +#include "../../libraries/GxEPD2/src/epd/GxEPD2_154_M10.h" // GuruSR: Changed for setDarkBorder +#include "../../libraries/GxEPD2/src/epd/GxEPD2_213.h" // GuruSR: Changed for setDarkBorder +#include "../../libraries/GxEPD2/src/epd/GxEPD2_213_B72.h" // GuruSR: Changed for setDarkBorder +#include "../../libraries/GxEPD2/src/epd/GxEPD2_213_B73.h" // GuruSR: Changed for setDarkBorder +#include "../../libraries/GxEPD2/src/epd/GxEPD2_213_B74.h" // GuruSR: Changed for setDarkBorder +#include "../../libraries/GxEPD2/src/epd/GxEPD2_213_flex.h" // GuruSR: Changed for setDarkBorder +#include "../../libraries/GxEPD2/src/epd/GxEPD2_213_M21.h" // GuruSR: Changed for setDarkBorder +#include "../../libraries/GxEPD2/src/epd/GxEPD2_213_T5D.h" // GuruSR: Changed for setDarkBorder +#include "../../libraries/GxEPD2/src/epd/GxEPD2_260.h" // GuruSR: Changed for setDarkBorder +#include "../../libraries/GxEPD2/src/epd/GxEPD2_260_M01.h" // GuruSR: Changed for setDarkBorder +#include "../../libraries/GxEPD2/src/epd/GxEPD2_290.h" // GuruSR: Changed for setDarkBorder +#include "../../libraries/GxEPD2/src/epd/GxEPD2_290_T5.h" // GuruSR: Changed for setDarkBorder +#include "../../libraries/GxEPD2/src/epd/GxEPD2_290_T5D.h" // GuruSR: Changed for setDarkBorder +#include "../../libraries/GxEPD2/src/epd/GxEPD2_290_M06.h" // GuruSR: Changed for setDarkBorder +#include "../../libraries/GxEPD2/src/epd/GxEPD2_290_T94.h" // GuruSR: Changed for setDarkBorder +#include "../../libraries/GxEPD2/src/epd/GxEPD2_290_T94_V2.h" // GuruSR: Changed for setDarkBorder +#include "../../libraries/GxEPD2/src/epd/GxEPD2_270.h" // GuruSR: Changed for setDarkBorder +#include "../../libraries/GxEPD2/src/epd/GxEPD2_371.h" // GuruSR: Changed for setDarkBorder +#include "../../libraries/GxEPD2/src/epd/GxEPD2_420.h" // GuruSR: Changed for setDarkBorder +#include "../../libraries/GxEPD2/src/epd/GxEPD2_420_M01.h" // GuruSR: Changed for setDarkBorder +#include "../../libraries/GxEPD2/src/epd/GxEPD2_583.h" // GuruSR: Changed for setDarkBorder +#include "../../libraries/GxEPD2/src/epd/GxEPD2_583_T8.h" // GuruSR: Changed for setDarkBorder +#include "../../libraries/GxEPD2/src/epd/GxEPD2_750.h" // GuruSR: Changed for setDarkBorder +#include "../../libraries/GxEPD2/src/epd/GxEPD2_750_T7.h" // GuruSR: Changed for setDarkBorder +#include "../../libraries/GxEPD2/src/epd/GxEPD2_1160_T91.h" // GuruSR: Changed for setDarkBorder +#include "../../libraries/GxEPD2/src/epd/GxEPD2_1248.h" // GuruSR: Changed for setDarkBorder +#include "../../libraries/GxEPD2/src/it8951/GxEPD2_it60.h" // GuruSR: Changed for setDarkBorder +#include "../../libraries/GxEPD2/src/it8951/GxEPD2_it60_1448x1072.h" // GuruSR: Changed for setDarkBorder +#include "../../libraries/GxEPD2/src/it8951/GxEPD2_it78_1872x1404.h" // GuruSR: Changed for setDarkBorder + +template +class GxEPD2_BW : public GxEPD2_GFX_BASE_CLASS +{ + public: + GxEPD2_Type epd2; +#if ENABLE_GxEPD2_GFX + GxEPD2_BW(GxEPD2_Type epd2_instance) : GxEPD2_GFX_BASE_CLASS(epd2, GxEPD2_Type::WIDTH, GxEPD2_Type::HEIGHT), epd2(epd2_instance) +#else + GxEPD2_BW(GxEPD2_Type epd2_instance) : GxEPD2_GFX_BASE_CLASS(GxEPD2_Type::WIDTH, GxEPD2_Type::HEIGHT), epd2(epd2_instance) +#endif + { + _page_height = page_height; + _pages = (HEIGHT / _page_height) + ((HEIGHT % _page_height) > 0); + _reverse = (epd2_instance.panel == GxEPD2::GDE0213B1); + _mirror = false; + _using_partial_mode = false; + _current_page = 0; + setFullWindow(); + } + + uint16_t pages() + { + return _pages; + } + + uint16_t pageHeight() + { + return _page_height; + } + + bool mirror(bool m) + { + _swap_ (_mirror, m); + return m; + } + + void drawPixel(int16_t x, int16_t y, uint16_t color) + { + if ((x < 0) || (x >= width()) || (y < 0) || (y >= height())) return; + if (_mirror) x = width() - x - 1; + // check rotation, move pixel around if necessary + switch (getRotation()) + { + case 1: + _swap_(x, y); + x = WIDTH - x - 1; + break; + case 2: + x = WIDTH - x - 1; + y = HEIGHT - y - 1; + break; + case 3: + _swap_(x, y); + y = HEIGHT - y - 1; + break; + } + // transpose partial window to 0,0 + x -= _pw_x; + y -= _pw_y; + // clip to (partial) window + if ((x < 0) || (x >= _pw_w) || (y < 0) || (y >= _pw_h)) return; + // adjust for current page + y -= _current_page * _page_height; + if (_reverse) y = _page_height - y - 1; + // check if in current page + if ((y < 0) || (y >= _page_height)) return; + uint16_t i = x / 8 + y * (_pw_w / 8); + if (color) + _buffer[i] = (_buffer[i] | (1 << (7 - x % 8))); + else + _buffer[i] = (_buffer[i] & (0xFF ^ (1 << (7 - x % 8)))); + } + + void init(uint32_t serial_diag_bitrate = 0) // = 0 : disabled + { + epd2.init(serial_diag_bitrate); + _using_partial_mode = false; + _current_page = 0; + setFullWindow(); + } + + // init method with additional parameters: + // initial false for re-init after processor deep sleep wake up, if display power supply was kept + // this can be used to avoid the repeated initial full refresh on displays with fast partial update + // NOTE: garbage will result on fast partial update displays, if initial full update is omitted after power loss + // reset_duration = 20 is default; a value of 2 may help with "clever" reset circuit of newer boards from Waveshare + // pulldown_rst_mode true for alternate RST handling to avoid feeding 5V through RST pin + void init(uint32_t serial_diag_bitrate, bool initial, uint16_t reset_duration = 20, bool pulldown_rst_mode = false) + { + epd2.init(serial_diag_bitrate, initial, reset_duration, pulldown_rst_mode); + _using_partial_mode = false; + _current_page = 0; + setFullWindow(); + } + + void fillScreen(uint16_t color) // 0x0 black, >0x0 white, to buffer + { + uint8_t data = (color == GxEPD_BLACK) ? 0x00 : 0xFF; + for (uint16_t x = 0; x < sizeof(_buffer); x++) + { + _buffer[x] = data; + } + } + + // display buffer content to screen, useful for full screen buffer + void display(bool partial_update_mode = false) + { + if (partial_update_mode) epd2.writeImage(_buffer, 0, 0, WIDTH, _page_height); + else epd2.writeImageForFullRefresh(_buffer, 0, 0, WIDTH, _page_height); + epd2.refresh(partial_update_mode); + if (epd2.hasFastPartialUpdate) + { + epd2.writeImageAgain(_buffer, 0, 0, WIDTH, _page_height); + } + if (!partial_update_mode) epd2.powerOff(); + } + + // display part of buffer content to screen, useful for full screen buffer + // displayWindow, use parameters according to actual rotation. + // x and w should be multiple of 8, for rotation 0 or 2, + // y and h should be multiple of 8, for rotation 1 or 3, + // else window is increased as needed, + // this is an addressing limitation of the e-paper controllers + void displayWindow(uint16_t x, uint16_t y, uint16_t w, uint16_t h) + { + x = gx_uint16_min(x, width()); + y = gx_uint16_min(y, height()); + w = gx_uint16_min(w, width() - x); + h = gx_uint16_min(h, height() - y); + _rotate(x, y, w, h); + uint16_t y_part = _reverse ? HEIGHT - h - y : y; + epd2.writeImagePart(_buffer, x, y_part, WIDTH, _page_height, x, y, w, h); + epd2.refresh(x, y, w, h); + if (epd2.hasFastPartialUpdate) + { + epd2.writeImagePartAgain(_buffer, x, y_part, WIDTH, _page_height, x, y, w, h); + } + } + + void setFullWindow() + { + _using_partial_mode = false; + _pw_x = 0; + _pw_y = 0; + _pw_w = WIDTH; + _pw_h = HEIGHT; + } + + // setPartialWindow, use parameters according to actual rotation. + // x and w should be multiple of 8, for rotation 0 or 2, + // y and h should be multiple of 8, for rotation 1 or 3, + // else window is increased as needed, + // this is an addressing limitation of the e-paper controllers + void setPartialWindow(uint16_t x, uint16_t y, uint16_t w, uint16_t h) + { + _pw_x = gx_uint16_min(x, width()); + _pw_y = gx_uint16_min(y, height()); + _pw_w = gx_uint16_min(w, width() - _pw_x); + _pw_h = gx_uint16_min(h, height() - _pw_y); + _rotate(_pw_x, _pw_y, _pw_w, _pw_h); + _using_partial_mode = true; + // make _pw_x, _pw_w multiple of 8 + _pw_w += _pw_x % 8; + if (_pw_w % 8 > 0) _pw_w += 8 - _pw_w % 8; + _pw_x -= _pw_x % 8; + } + + void firstPage() + { + fillScreen(GxEPD_WHITE); + _current_page = 0; + _second_phase = false; + } + + bool nextPage() + { + if (1 == _pages) + { + if (_using_partial_mode) + { + uint32_t offset = _reverse ? (HEIGHT - _pw_h) * _pw_w / 8 : 0; + epd2.writeImage(_buffer + offset, _pw_x, _pw_y, _pw_w, _pw_h); + epd2.refresh(_pw_x, _pw_y, _pw_w, _pw_h); + if (epd2.hasFastPartialUpdate) + { + epd2.writeImageAgain(_buffer + offset, _pw_x, _pw_y, _pw_w, _pw_h); + //epd2.refresh(_pw_x, _pw_y, _pw_w, _pw_h); // not needed + } + } + else // full update + { + epd2.writeImageForFullRefresh(_buffer, 0, 0, WIDTH, HEIGHT); + epd2.refresh(false); + if (epd2.hasFastPartialUpdate) + { + epd2.writeImageAgain(_buffer, 0, 0, WIDTH, HEIGHT); + //epd2.refresh(true); // not needed + } + epd2.powerOff(); + } + return false; + } + uint16_t page_ys = _current_page * _page_height; + if (_using_partial_mode) + { + //Serial.print(" nextPage("); Serial.print(_pw_x); Serial.print(", "); Serial.print(_pw_y); Serial.print(", "); + //Serial.print(_pw_w); Serial.print(", "); Serial.print(_pw_h); Serial.print(") P"); Serial.println(_current_page); + uint16_t page_ye = _current_page < (_pages - 1) ? page_ys + _page_height : HEIGHT; + uint16_t dest_ys = _pw_y + page_ys; // transposed + uint16_t dest_ye = gx_uint16_min(_pw_y + _pw_h, _pw_y + page_ye); + if (dest_ye > dest_ys) + { + //Serial.print("writeImage("); Serial.print(_pw_x); Serial.print(", "); Serial.print(dest_ys); Serial.print(", "); + //Serial.print(_pw_w); Serial.print(", "); Serial.print(dest_ye - dest_ys); Serial.println(")"); + uint32_t offset = _reverse ? (_page_height - (dest_ye - dest_ys)) * _pw_w / 8 : 0; + if (!_second_phase) epd2.writeImage(_buffer + offset, _pw_x, dest_ys, _pw_w, dest_ye - dest_ys); + else epd2.writeImageAgain(_buffer + offset, _pw_x, dest_ys, _pw_w, dest_ye - dest_ys); + } + else + { + //Serial.print("writeImage("); Serial.print(_pw_x); Serial.print(", "); Serial.print(dest_ys); Serial.print(", "); + //Serial.print(_pw_w); Serial.print(", "); Serial.print(dest_ye - dest_ys); Serial.print(") skipped "); + //Serial.print(dest_ys); Serial.print(".."); Serial.println(dest_ye); + } + _current_page++; + if (_current_page == _pages) + { + _current_page = 0; + if (!_second_phase) + { + epd2.refresh(_pw_x, _pw_y, _pw_w, _pw_h); + if (epd2.hasFastPartialUpdate) + { + _second_phase = true; + fillScreen(GxEPD_WHITE); + return true; + } + } + return false; + } + fillScreen(GxEPD_WHITE); + return true; + } + else // full update + { + if (!_second_phase) epd2.writeImageForFullRefresh(_buffer, 0, page_ys, WIDTH, gx_uint16_min(_page_height, HEIGHT - page_ys)); + else epd2.writeImageAgain(_buffer, 0, page_ys, WIDTH, gx_uint16_min(_page_height, HEIGHT - page_ys)); + _current_page++; + if (_current_page == _pages) + { + _current_page = 0; + if (epd2.hasFastPartialUpdate) + { + if (!_second_phase) + { + epd2.refresh(false); // full update after first phase + _second_phase = true; + fillScreen(GxEPD_WHITE); + return true; + } + //else epd2.refresh(true); // partial update after second phase + } else epd2.refresh(false); // full update after only phase + epd2.powerOff(); + return false; + } + fillScreen(GxEPD_WHITE); + return true; + } + } + + // GxEPD style paged drawing; drawCallback() is called as many times as needed + void drawPaged(void (*drawCallback)(const void*), const void* pv) + { + if (1 == _pages) + { + fillScreen(GxEPD_WHITE); + drawCallback(pv); + if (_using_partial_mode) + { + uint32_t offset = _reverse ? (HEIGHT - _pw_h) * _pw_w / 8 : 0; + epd2.writeImage(_buffer + offset, _pw_x, _pw_y, _pw_w, _pw_h); + epd2.refresh(_pw_x, _pw_y, _pw_w, _pw_h); + if (epd2.hasFastPartialUpdate) + { + epd2.writeImageAgain(_buffer + offset, _pw_x, _pw_y, _pw_w, _pw_h); + //epd2.refresh(_pw_x, _pw_y, _pw_w, _pw_h); // not needed + } + } + else // full update + { + epd2.writeImageForFullRefresh(_buffer, 0, 0, WIDTH, HEIGHT); + epd2.refresh(false); + if (epd2.hasFastPartialUpdate) + { + epd2.writeImageAgain(_buffer, 0, 0, WIDTH, HEIGHT); + //epd2.refresh(true); // not needed + epd2.powerOff(); + } + } + return; + } + if (_using_partial_mode) + { + for (uint16_t phase = 1; phase <= 2; phase++) + { + for (_current_page = 0; _current_page < _pages; _current_page++) + { + uint16_t page_ys = _current_page * _page_height; + uint16_t page_ye = _current_page < (_pages - 1) ? page_ys + _page_height : HEIGHT; + uint16_t dest_ys = _pw_y + page_ys; // transposed + uint16_t dest_ye = gx_uint16_min(_pw_y + _pw_h, _pw_y + page_ye); + if (dest_ye > dest_ys) + { + fillScreen(GxEPD_WHITE); + drawCallback(pv); + uint32_t offset = _reverse ? (_page_height - (dest_ye - dest_ys)) * _pw_w / 8 : 0; + if (phase == 1) epd2.writeImage(_buffer + offset, _pw_x, dest_ys, _pw_w, dest_ye - dest_ys); + else epd2.writeImageAgain(_buffer + offset, _pw_x, dest_ys, _pw_w, dest_ye - dest_ys); + } + } + epd2.refresh(_pw_x, _pw_y, _pw_w, _pw_h); + if (!epd2.hasFastPartialUpdate) break; + // else make both controller buffers have equal content + } + } + else // full update + { + for (_current_page = 0; _current_page < _pages; _current_page++) + { + uint16_t page_ys = _current_page * _page_height; + fillScreen(GxEPD_WHITE); + drawCallback(pv); + epd2.writeImageForFullRefresh(_buffer, 0, page_ys, WIDTH, gx_uint16_min(_page_height, HEIGHT - page_ys)); + } + epd2.refresh(false); // full update after first phase + if (epd2.hasFastPartialUpdate) + { + // make both controller buffers have equal content + for (_current_page = 0; _current_page < _pages; _current_page++) + { + uint16_t page_ys = _current_page * _page_height; + fillScreen(GxEPD_WHITE); + drawCallback(pv); + epd2.writeImageAgain(_buffer, 0, page_ys, WIDTH, gx_uint16_min(_page_height, HEIGHT - page_ys)); + } + //epd2.refresh(true); // partial update after second phase // not needed + } + epd2.powerOff(); + } + _current_page = 0; + } + + void drawInvertedBitmap(int16_t x, int16_t y, const uint8_t bitmap[], int16_t w, int16_t h, uint16_t color) + { + // taken from Adafruit_GFX.cpp, modified + int16_t byteWidth = (w + 7) / 8; // Bitmap scanline pad = whole byte + uint8_t byte = 0; + for (int16_t j = 0; j < h; j++) + { + for (int16_t i = 0; i < w; i++ ) + { + if (i & 7) byte <<= 1; + else + { +#if defined(__AVR) || defined(ESP8266) || defined(ESP32) + byte = pgm_read_byte(&bitmap[j * byteWidth + i / 8]); +#else + byte = bitmap[j * byteWidth + i / 8]; +#endif + } + if (!(byte & 0x80)) + { + drawPixel(x + i, y + j, color); + } + } + } + } + + // Support for Bitmaps (Sprites) to Controller Buffer and to Screen + void clearScreen(uint8_t value = 0xFF) // init controller memory and screen (default white) + { + epd2.clearScreen(value); + } + void writeScreenBuffer(uint8_t value = 0xFF) // init controller memory (default white) + { + epd2.writeScreenBuffer(value); + } + // write to controller memory, without screen refresh; x and w should be multiple of 8 + void writeImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false) + { + epd2.writeImage(bitmap, x, y, w, h, invert, mirror_y, pgm); + } + void writeImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap, + int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false) + { + epd2.writeImagePart(bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm); + } + void writeImage(const uint8_t* black, const uint8_t* color, int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm) + { + epd2.writeImage(black, color, x, y, w, h, invert, mirror_y, pgm); + } + void writeImage(const uint8_t* black, const uint8_t* color, int16_t x, int16_t y, int16_t w, int16_t h) + { + epd2.writeImage(black, color, x, y, w, h, false, false, false); + } + void writeImagePart(const uint8_t* black, const uint8_t* color, int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap, + int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm) + { + epd2.writeImagePart(black, color, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm); + } + void writeImagePart(const uint8_t* black, const uint8_t* color, int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap, + int16_t x, int16_t y, int16_t w, int16_t h) + { + epd2.writeImagePart(black, color, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, false, false, false); + } + // write sprite of native data to controller memory, without screen refresh; x and w should be multiple of 8 + void writeNative(const uint8_t* data1, const uint8_t* data2, int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm) + { + epd2.writeNative(data1, data2, x, y, w, h, invert, mirror_y, pgm); + } + // write to controller memory, with screen refresh; x and w should be multiple of 8 + void drawImage(const uint8_t bitmap[], int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false) + { + epd2.drawImage(bitmap, x, y, w, h, invert, mirror_y, pgm); + } + void drawImagePart(const uint8_t bitmap[], int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap, + int16_t x, int16_t y, int16_t w, int16_t h, bool invert = false, bool mirror_y = false, bool pgm = false) + { + epd2.drawImagePart(bitmap, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm); + } + void drawImage(const uint8_t* black, const uint8_t* color, int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm) + { + epd2.drawImage(black, color, x, y, w, h, invert, mirror_y, pgm); + } + void drawImage(const uint8_t* black, const uint8_t* color, int16_t x, int16_t y, int16_t w, int16_t h) + { + epd2.drawImage(black, color, x, y, w, h, false, false, false); + } + void drawImagePart(const uint8_t* black, const uint8_t* color, int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap, + int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm) + { + epd2.drawImagePart(black, color, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, invert, mirror_y, pgm); + } + void drawImagePart(const uint8_t* black, const uint8_t* color, int16_t x_part, int16_t y_part, int16_t w_bitmap, int16_t h_bitmap, + int16_t x, int16_t y, int16_t w, int16_t h) + { + epd2.drawImagePart(black, color, x_part, y_part, w_bitmap, h_bitmap, x, y, w, h, false, false, false); + } + // write sprite of native data to controller memory, with screen refresh; x and w should be multiple of 8 + void drawNative(const uint8_t* data1, const uint8_t* data2, int16_t x, int16_t y, int16_t w, int16_t h, bool invert, bool mirror_y, bool pgm) + { + epd2.drawNative(data1, data2, x, y, w, h, invert, mirror_y, pgm); + } + void refresh(bool partial_update_mode = false) // screen refresh from controller memory to full screen + { + epd2.refresh(partial_update_mode); + if (!partial_update_mode) epd2.powerOff(); + } + void refresh(int16_t x, int16_t y, int16_t w, int16_t h) // screen refresh from controller memory, partial screen + { + epd2.refresh(x, y, w, h); + } + // turns off generation of panel driving voltages, avoids screen fading over time + void powerOff() + { + epd2.powerOff(); + } + // turns powerOff() and sets controller to deep sleep for minimum power use, ONLY if wakeable by RST (rst >= 0) + void hibernate() + { + epd2.hibernate(); + } + private: + template static inline void + _swap_(T & a, T & b) + { + T t = a; + a = b; + b = t; + }; + static inline uint16_t gx_uint16_min(uint16_t a, uint16_t b) + { + return (a < b ? a : b); + }; + static inline uint16_t gx_uint16_max(uint16_t a, uint16_t b) + { + return (a > b ? a : b); + }; + void _rotate(uint16_t& x, uint16_t& y, uint16_t& w, uint16_t& h) + { + switch (getRotation()) + { + case 1: + _swap_(x, y); + _swap_(w, h); + x = WIDTH - x - w; + break; + case 2: + x = WIDTH - x - w; + y = HEIGHT - y - h; + break; + case 3: + _swap_(x, y); + _swap_(w, h); + y = HEIGHT - y - h; + break; + } + } + private: + uint8_t _buffer[(GxEPD2_Type::WIDTH / 8) * page_height]; + bool _using_partial_mode, _second_phase, _mirror, _reverse; + uint16_t _width_bytes, _pixel_bytes; + int16_t _current_page; + uint16_t _pages, _page_height; + uint16_t _pw_x, _pw_y, _pw_w, _pw_h; +}; + +#endif diff --git a/src/Olsen2POSIX.cpp b/src/Olsen2POSIX.cpp new file mode 100644 index 0000000..c6e0e53 --- /dev/null +++ b/src/Olsen2POSIX.cpp @@ -0,0 +1,21 @@ +#include "Olsen2POSIX.h" + +//#define TZMISSING "--MISSING--" +#define MAX_ITEMS 946 +using namespace std; + +// Data from: https://github.com/pgurenko/tzinfo +static const char *sTZData[] = {"Atlantic/Canary", "WET0WEST,M3.5.0/1,M10.5.0", "Australia/Melbourne", "AEST-10AEDT,M10.1.0,M4.1.0/3", "Etc/GMT+9", "<-09>9", "Etc/GMT+8", "<-08>8", "Europe/Lisbon", "WET0WEST,M3.5.0/1,M10.5.0", "Etc/GMT+3", "<-03>3", "Etc/GMT+2", "<-02>2", "Etc/GMT+1", "<-01>1", "Etc/GMT+0", "GMT0", "America/Nipigon", "EST5EDT,M3.2.0,M11.1.0", "Etc/GMT+6", "<-06>6", "Etc/GMT+5", "<-05>5", "America/Miquelon", "<-03>3<-02>,M3.2.0,M11.1.0", "Pacific/Wallis", "<+12>-12", "America/Fort_Nelson", "MST7", "Antarctica/Davis", "<+07>-7", "Asia/Dhaka", "<+06>-6", "America/St_Lucia", "AST4", "America/Phoenix", "MST7", "Europe/Kaliningrad", "EET-2", "Etc/GMT+7", "<-07>7", "America/Mazatlan", "MST7MDT,M4.1.0,M10.5.0", "Arctic/Longyearbyen", "CET-1CEST,M3.5.0,M10.5.0/3", "Europe/Guernsey", "GMT0BST,M3.5.0/1,M10.5.0", "Antarctica/Rothera", "<-03>3", "Europe/Stockholm", "CET-1CEST,M3.5.0,M10.5.0/3", "Pacific/Fiji", "<+12>-12<+13>,M11.1.0,M1.3.0/3", "Pacific/Apia", "<+13>-13<+14>,M9.5.0/3,M4.1.0/4", "Etc/GMT+4", "<-04>4", "Pacific/Pago_Pago", "SST11", "America/Mexico_City", "CST6CDT,M4.1.0,M10.5.0", "America/Puerto_Rico", "AST4", "Indian/Mauritius", "<+04>-4", "Asia/Yangon", "<+0630>-6:30", "Europe/Berlin", "CET-1CEST,M3.5.0,M10.5.0/3", "Europe/Zurich", "CET-1CEST,M3.5.0,M10.5.0/3", "Africa/Casablanca", "WET0WEST,M3.5.0,M10.5.0/3", "Antarctica/Macquarie", "<+11>-11", "Europe/Warsaw", "CET-1CEST,M3.5.0,M10.5.0/3", "Asia/Krasnoyarsk", "<+07>-7", "Atlantic/Bermuda", "AST4ADT,M3.2.0,M11.1.0", "America/Araguaina", "<-03>3", "Asia/Tehran", "<+0330>-3:30<+0430>,J80/0,J264/0", "Asia/Baku", "<+04>-4", "America/St_Barthelemy", "AST4", "America/Santarem", "<-03>3", "America/Danmarkshavn", "GMT0", "America/Scoresbysund", "<-01>1<+00>,M3.5.0/0,M10.5.0/1", "America/Eirunepe", "<-05>5", "America/Caracas", "<-04>4", "Asia/Baghdad", "<+03>-3", "Africa/Monrovia", "GMT0", "America/St_Vincent", "AST4", "America/Vancouver", "PST8PDT,M3.2.0,M11.1.0", "Asia/Ho_Chi_Minh", "<+07>-7", "Europe/Busingen", "CET-1CEST,M3.5.0,M10.5.0/3", "Etc/GMT0", "GMT0", "Asia/Thimphu", "<+06>-6", "Africa/Ouagadougou", "GMT0", "America/Belize", "CST6", "America/Port_of_Spain", "AST4", "Asia/Famagusta", "<+03>-3", "Asia/Tashkent", "<+05>-5", "Asia/Tokyo", "JST-9", "Pacific/Kiritimati", "<+14>-14", "Australia/Sydney", "AEST-10AEDT,M10.1.0,M4.1.0/3", "Europe/Riga", "EET-2EEST,M3.5.0/3,M10.5.0/4", "Asia/Dili", "<+09>-9", "Africa/Mbabane", "SAST-2", "Asia/Oral", "<+05>-5", "Asia/Aden", "<+03>-3", "MST7MDT", "MST7MDT,M3.2.0,M11.1.0", "Europe/Istanbul", "<+03>-3", "Asia/Magadan", "<+11>-11", "Asia/Kabul", "<+0430>-4:30", "Australia/Lindeman", "AEST-10", "Pacific/Galapagos", "<-06>6", "America/Bogota", "<-05>5", "Africa/Asmara", "EAT-3", "America/Chicago", "CST6CDT,M3.2.0,M11.1.0", "Pacific/Kwajalein", "<+12>-12", "Australia/Broken_Hill", "ACST-9:30ACDT,M10.1.0,M4.1.0/3", "America/Cuiaba", "<-04>4<-03>,M10.3.0/0,M2.3.0/0", "Indian/Christmas", "<+07>-7", "Asia/Jayapura", "WIT-9", "Europe/Brussels", "CET-1CEST,M3.5.0,M10.5.0/3", "America/Argentina/Cordoba", "<-03>3", "America/Noronha", "<-02>2", "Europe/Podgorica", "CET-1CEST,M3.5.0,M10.5.0/3", "Africa/Algiers", "CET-1", "Africa/Harare", "CAT-2", "Africa/Ndjamena", "WAT-1", "America/Costa_Rica", "CST6", "Europe/Ljubljana", "CET-1CEST,M3.5.0,M10.5.0/3", "Indian/Mayotte", "EAT-3", "Asia/Phnom_Penh", "<+07>-7", "America/Managua", "CST6", "America/Pangnirtung", "EST5EDT,M3.2.0,M11.1.0", "Etc/GMT+12", "<-12>12", "America/Tijuana", "PST8PDT,M3.2.0,M11.1.0", "Pacific/Fakaofo", "<+13>-13", "America/Martinique", "AST4", "America/Antigua", "AST4", "America/Indiana/Indianapolis", "EST5EDT,M3.2.0,M11.1.0", "America/Argentina/La_Rioja", "<-03>3", "Pacific/Tahiti", "<-10>10", "Asia/Brunei", "<+08>-8", "Europe/Zagreb", "CET-1CEST,M3.5.0,M10.5.0/3", "America/Asuncion", "<-04>4<-03>,M10.1.0/0,M3.4.0/0", "Europe/Vienna", "CET-1CEST,M3.5.0,M10.5.0/3", "Australia/Hobart", "AEST-10AEDT,M10.1.0,M4.1.0/3", "America/Juneau", "AKST9AKDT,M3.2.0,M11.1.0", "America/Inuvik", "MST7MDT,M3.2.0,M11.1.0", "America/Ojinaga", "MST7MDT,M3.2.0,M11.1.0", "Europe/Astrakhan", "<+04>-4", "Europe/Saratov", "<+04>-4", "Asia/Seoul", "KST-9", "Indian/Comoro", "EAT-3", "Europe/Paris", "CET-1CEST,M3.5.0,M10.5.0/3", "Europe/Tallinn", "EET-2EEST,M3.5.0/3,M10.5.0/4", "Indian/Mahe", "<+04>-4", "America/Argentina/Jujuy", "<-03>3", "America/Creston", "MST7", "America/Adak", "HST10HDT,M3.2.0,M11.1.0", "Asia/Singapore", "<+08>-8", "Africa/Nairobi", "EAT-3", "America/Maceio", "<-03>3", "Africa/Cairo", "EET-2", "Europe/Moscow", "MSK-3", "Antarctica/Palmer", "<-03>3", "Asia/Ulaanbaatar", "<+08>-8", "America/Rainy_River", "CST6CDT,M3.2.0,M11.1.0", "Africa/Kampala", "EAT-3", "Asia/Colombo", "<+0530>-5:30", "Australia/Adelaide", "ACST-9:30ACDT,M10.1.0,M4.1.0/3", "America/Cambridge_Bay", "MST7MDT,M3.2.0,M11.1.0", "Africa/Luanda", "WAT-1", "Pacific/Chatham", "<+1245>-12:45<+1345>,M9.5.0/2:45,M4.1.0/3:45", "America/Indiana/Winamac", "EST5EDT,M3.2.0,M11.1.0", "Asia/Tbilisi", "<+04>-4", "Europe/Gibraltar", "CET-1CEST,M3.5.0,M10.5.0/3", "Asia/Karachi", "PKT-5", "Australia/Lord_Howe", "<+1030>-10:30<+11>-11,M10.1.0,M4.1.0", "Etc/GMT-9", "<+09>-9", "Etc/GMT-8", "<+08>-8", "America/Bahia_Banderas", "CST6CDT,M4.1.0,M10.5.0", "Etc/GMT-1", "<+01>-1", "Etc/GMT-0", "GMT0", "Etc/GMT-3", "<+03>-3", "Etc/GMT-2", "<+02>-2", "Etc/GMT-5", "<+05>-5", "Etc/GMT-4", "<+04>-4", "Etc/GMT-7", "<+07>-7", "Etc/GMT-6", "<+06>-6", "America/Boa_Vista", "<-04>4", "Africa/Tripoli", "EET-2", "Indian/Reunion", "<+04>-4", "Atlantic/Stanley", "<-03>3", "Asia/Srednekolymsk", "<+11>-11", "CET", "CET-1CEST,M3.5.0,M10.5.0/3", "Etc/GMT-13", "<+13>-13", "America/Blanc-Sablon", "AST4", "Antarctica/Syowa", "<+03>-3", "America/Jamaica", "EST5", "Europe/Kiev", "EET-2EEST,M3.5.0/3,M10.5.0/4", "Europe/Budapest", "CET-1CEST,M3.5.0,M10.5.0/3", "Pacific/Midway", "SST11", "America/Goose_Bay", "AST4ADT,M3.2.0,M11.1.0", "Asia/Amman", "EET-2EEST,M3.5.4/24,M10.5.5/1", "Asia/Sakhalin", "<+11>-11", "Africa/Windhoek", "WAT-1WAST,M9.1.0,M4.1.0", "America/Sitka", "AKST9AKDT,M3.2.0,M11.1.0", "America/Guyana", "<-04>4", "Pacific/Pohnpei", "<+11>-11", "America/Sao_Paulo", "<-03>3<-02>,M10.3.0/0,M2.3.0/0", "America/Lower_Princes", "AST4", "Australia/Perth", "AWST-8", "Africa/Djibouti", "EAT-3", "Asia/Jakarta", "WIB-7", "Asia/Pyongyang", "KST-8:30", "EST5EDT", "EST5EDT,M3.2.0,M11.1.0", "Africa/Johannesburg", "SAST-2", "Antarctica/Troll", "<+00>0<+02>-2,M3.5.0/1,M10.5.0/3", "Asia/Istanbul", "<+03>-3", "Asia/Irkutsk", "<+08>-8", "Africa/Niamey", "WAT-1", "America/Belem", "<-03>3", "America/Indiana/Marengo", "EST5EDT,M3.2.0,M11.1.0", "Africa/Nouakchott", "GMT0", "Europe/Vilnius", "EET-2EEST,M3.5.0/3,M10.5.0/4", "America/Cayenne", "<-03>3", "Africa/Mogadishu", "EAT-3", "America/Kentucky/Monticello", "EST5EDT,M3.2.0,M11.1.0", "America/Rio_Branco", "<-05>5", "America/Cancun", "EST5", "America/Havana", "CST5CDT,M3.2.0/0,M11.1.0/1", "Pacific/Guam", "ChST-10", "Pacific/Kosrae", "<+11>-11", "Atlantic/Azores", "<-01>1<+00>,M3.5.0/0,M10.5.0/1", "Australia/Eucla", "<+0845>-8:45", "Asia/Shanghai", "CST-8", "America/Rankin_Inlet", "CST6CDT,M3.2.0,M11.1.0", "Asia/Beirut", "EET-2EEST,M3.5.0/0,M10.5.0/0", "Africa/Maputo", "CAT-2", "Asia/Bahrain", "<+03>-3", "Asia/Ashgabat", "<+05>-5", "Asia/Riyadh", "<+03>-3", "Europe/London", "GMT0BST,M3.5.0/1,M10.5.0", "America/Montevideo", "<-03>3", "America/Anguilla", "AST4", "Asia/Damascus", "EET-2EEST,M3.5.5/0,M10.5.5/0", "America/North_Dakota/Center", "CST6CDT,M3.2.0,M11.1.0", "America/Indiana/Vevay", "EST5EDT,M3.2.0,M11.1.0", "Atlantic/St_Helena", "GMT0", "America/Barbados", "AST4", "Europe/Vatican", "CET-1CEST,M3.5.0,M10.5.0/3", "America/Indiana/Vincennes", "EST5EDT,M3.2.0,M11.1.0", "Asia/Almaty", "<+06>-6", "America/Santo_Domingo", "AST4", "Africa/Brazzaville", "WAT-1", "America/Nome", "AKST9AKDT,M3.2.0,M11.1.0", "Asia/Taipei", "CST-8", "America/Yakutat", "AKST9AKDT,M3.2.0,M11.1.0", "America/Argentina/Mendoza", "<-03>3", "Australia/Currie", "AEST-10AEDT,M10.1.0,M4.1.0/3", "Etc/UTC", "UTC0", "Europe/Vaduz", "CET-1CEST,M3.5.0,M10.5.0/3", "Africa/Asmera", "EAT-3", "Antarctica/Mawson", "<+05>-5", "Asia/Kolkata", "IST-5:30", "Africa/Maseru", "SAST-2", "America/Atikokan", "EST5", "Asia/Kuching", "<+08>-8", "Africa/Libreville", "WAT-1", "Africa/Freetown", "GMT0", "Africa/Bissau", "GMT0", "Europe/Samara", "<+04>-4", "Europe/Amsterdam", "CET-1CEST,M3.5.0,M10.5.0/3", "Europe/Tirane", "CET-1CEST,M3.5.0,M10.5.0/3", "Pacific/Saipan", "ChST-10", "Africa/Abidjan", "GMT0", "Europe/Zaporozhye", "EET-2EEST,M3.5.0/3,M10.5.0/4", "HST", "HST10", "America/El_Salvador", "CST6", "Europe/Madrid", "CET-1CEST,M3.5.0,M10.5.0/3", "Africa/Juba", "EAT-3", "America/Argentina/Buenos_Aires", "<-03>3", "America/Argentina/San_Luis", "<-03>3", "Europe/Skopje", "CET-1CEST,M3.5.0,M10.5.0/3", "WET", "WET0WEST,M3.5.0/1,M10.5.0", "Asia/Atyrau", "<+05>-5", "America/Aruba", "AST4", "America/Regina", "CST6", "Pacific/Chuuk", "<+10>-10", "Asia/Khandyga", "<+09>-9", "Pacific/Funafuti", "<+12>-12", "America/Merida", "CST6CDT,M4.1.0,M10.5.0", "America/Guatemala", "CST6", "Africa/Sao_Tome", "GMT0", "Asia/Tomsk", "<+07>-7", "Asia/Makassar", "WITA-8", "Africa/Bujumbura", "CAT-2", "Europe/Chisinau", "EET-2EEST,M3.5.0,M10.5.0/3", "America/Monterrey", "CST6CDT,M4.1.0,M10.5.0", "Asia/Yekaterinburg", "<+05>-5", "Antarctica/Casey", "<+11>-11", "Pacific/Enderbury", "<+13>-13", "America/Thule", "AST4ADT,M3.2.0,M11.1.0", "America/St_Johns", "NST3:30NDT,M3.2.0,M11.1.0", "America/Moncton", "AST4ADT,M3.2.0,M11.1.0", "Europe/Helsinki", "EET-2EEST,M3.5.0/3,M10.5.0/4", "Atlantic/Cape_Verde", "<-01>1", "America/Tegucigalpa", "CST6", "Indian/Cocos", "<+0630>-6:30", "America/Boise", "MST7MDT,M3.2.0,M11.1.0", "America/Guadeloupe", "AST4", "America/Nassau", "EST5EDT,M3.2.0,M11.1.0", "Europe/Prague", "CET-1CEST,M3.5.0,M10.5.0/3", "America/Halifax", "AST4ADT,M3.2.0,M11.1.0", "Asia/Hovd", "<+07>-7", "America/Manaus", "<-04>4", "Etc/UCT", "UCT0", "Etc/Greenwich", "GMT0", "America/North_Dakota/Beulah", "CST6CDT,M3.2.0,M11.1.0", "America/Chihuahua", "MST7MDT,M4.1.0,M10.5.0", "America/Iqaluit", "EST5EDT,M3.2.0,M11.1.0", "America/Argentina/Rio_Gallegos", "<-03>3", "Pacific/Gambier", "<-09>9", "Europe/Volgograd", "<+03>-3", "Africa/Bamako", "GMT0", "Asia/Novokuznetsk", "<+07>-7", "Europe/Uzhgorod", "EET-2EEST,M3.5.0/3,M10.5.0/4", "Africa/Banjul", "GMT0", "Asia/Aqtau", "<+05>-5", "Pacific/Palau", "<+09>-9", "Africa/Malabo", "WAT-1", "Europe/Minsk", "<+03>-3", "PST8PDT", "PST8PDT,M3.2.0,M11.1.0", "Atlantic/Madeira", "WET0WEST,M3.5.0/1,M10.5.0", "Pacific/Noumea", "<+11>-11", "Africa/Kinshasa", "WAT-1", "Europe/Malta", "CET-1CEST,M3.5.0,M10.5.0/3", "America/Argentina/Ushuaia", "<-03>3", "Asia/Bangkok", "<+07>-7", "Pacific/Niue", "<-11>11", "Australia/Brisbane", "AEST-10", "America/Recife", "<-03>3", "MST", "MST7", "Asia/Yerevan", "<+04>-4", "America/La_Paz", "<-04>4", "Asia/Urumqi", "<+06>-6", "Africa/Lusaka", "CAT-2", "Pacific/Guadalcanal", "<+11>-11", "America/Yellowknife", "MST7MDT,M3.2.0,M11.1.0", "Asia/Vientiane", "<+07>-7", "Asia/Kuwait", "<+03>-3", "Africa/Conakry", "GMT0", "America/Argentina/Tucuman", "<-03>3", "Asia/Chita", "<+09>-9", "Europe/Oslo", "CET-1CEST,M3.5.0,M10.5.0/3", "America/St_Kitts", "AST4", "America/Panama", "EST5", "Africa/Gaborone", "CAT-2", "Asia/Hebron", "EET-2EEST,M3.5.6/1,M10.5.6/1", "America/Guayaquil", "<-05>5", "Asia/Kuala_Lumpur", "<+08>-8", "America/Menominee", "CST6CDT,M3.2.0,M11.1.0", "Asia/Kamchatka", "<+12>-12", "Factory", "<-00>0", "Asia/Vladivostok", "<+10>-10", "America/Matamoros", "CST6CDT,M3.2.0,M11.1.0", "Asia/Qatar", "<+03>-3", "Asia/Dubai", "<+04>-4", "Asia/Yakutsk", "<+09>-9", "Asia/Omsk", "<+06>-6", "Africa/Bangui", "WAT-1", "America/Paramaribo", "<-03>3", "Etc/GMT-11", "<+11>-11", "Etc/GMT-10", "<+10>-10", "Africa/Lubumbashi", "CAT-2", "Etc/GMT-12", "<+12>-12", "Etc/GMT-14", "<+14>-14", "Pacific/Marquesas", "<-0930>9:30", "Europe/Bratislava", "CET-1CEST,M3.5.0,M10.5.0/3", "Asia/Anadyr", "<+12>-12", "America/New_York", "EST5EDT,M3.2.0,M11.1.0", "Pacific/Norfolk", "<+11>-11", "CST6CDT", "CST6CDT,M3.2.0,M11.1.0", "Pacific/Rarotonga", "<-10>10", "America/Dominica", "AST4", "Africa/Porto-Novo", "WAT-1", "Asia/Samarkand", "<+05>-5", "Asia/Dushanbe", "<+05>-5", "America/Kentucky/Louisville", "EST5EDT,M3.2.0,M11.1.0", "America/Toronto", "EST5EDT,M3.2.0,M11.1.0", "America/Bahia", "<-03>3", "Indian/Maldives", "<+05>-5", "Africa/Accra", "GMT0", "Asia/Muscat", "<+04>-4", "America/Edmonton", "MST7MDT,M3.2.0,M11.1.0", "Pacific/Wake", "<+12>-12", "America/Indiana/Tell_City", "CST6CDT,M3.2.0,M11.1.0", "Australia/Darwin", "ACST-9:30", "America/Whitehorse", "PST8PDT,M3.2.0,M11.1.0", "America/Swift_Current", "CST6", "Europe/Copenhagen", "CET-1CEST,M3.5.0,M10.5.0/3", "America/Argentina/Salta", "<-03>3", "America/Montserrat", "AST4", "Europe/Simferopol", "MSK-3", "Africa/Blantyre", "CAT-2", "America/Detroit", "EST5EDT,M3.2.0,M11.1.0", "America/Grenada", "AST4", "Atlantic/Faroe", "WET0WEST,M3.5.0/1,M10.5.0", "America/Indiana/Petersburg", "EST5EDT,M3.2.0,M11.1.0", "Asia/Kathmandu", "<+0545>-5:45", "Asia/Pontianak", "WIB-7", "Europe/Athens", "EET-2EEST,M3.5.0/3,M10.5.0/4", "America/Port-au-Prince", "EST5EDT,M3.2.0,M11.1.0", "America/Cayman", "EST5", "Etc/Universal", "UTC0", "Africa/Dar_es_Salaam", "EAT-3", "America/Curacao", "AST4", "Indian/Kerguelen", "<+05>-5", "Africa/Khartoum", "EAT-3", "Asia/Manila", "<+08>-8", "Africa/Lome", "GMT0", "Africa/Douala", "WAT-1", "EET", "EET-2EEST,M3.5.0/3,M10.5.0/4", "America/Argentina/San_Juan", "<-03>3", "America/North_Dakota/New_Salem", "CST6CDT,M3.2.0,M11.1.0", "America/Kralendijk", "AST4", "Pacific/Port_Moresby", "<+10>-10", "Europe/Jersey", "GMT0BST,M3.5.0/1,M10.5.0", "Europe/Andorra", "CET-1CEST,M3.5.0,M10.5.0/3", "Europe/Luxembourg", "CET-1CEST,M3.5.0,M10.5.0/3", "Pacific/Honolulu", "HST10", "America/St_Thomas", "AST4", "Pacific/Majuro", "<+12>-12", "Asia/Hong_Kong", "HKT-8", "Asia/Macau", "CST-8", "Europe/Isle_of_Man", "GMT0BST,M3.5.0/1,M10.5.0", "Europe/Belgrade", "CET-1CEST,M3.5.0,M10.5.0/3", "Asia/Choibalsan", "<+08>-8", "Europe/Mariehamn", "EET-2EEST,M3.5.0/3,M10.5.0/4", "Antarctica/McMurdo", "NZST-12NZDT,M9.5.0,M4.1.0/3", "America/Thunder_Bay", "EST5EDT,M3.2.0,M11.1.0", "America/Los_Angeles", "PST8PDT,M3.2.0,M11.1.0", "America/Punta_Arenas", "<-03>3", "Indian/Antananarivo", "EAT-3", "Europe/Sarajevo", "CET-1CEST,M3.5.0,M10.5.0/3", "Atlantic/Reykjavik", "GMT0", "Asia/Nicosia", "EET-2EEST,M3.5.0/3,M10.5.0/4", "Etc/GMT+11", "<-11>11", "Etc/GMT+10", "<-10>10", "Asia/Barnaul", "<+07>-7", "Pacific/Tongatapu", "<+13>-13<+14>,M11.1.0,M1.3.0/3", "America/Marigot", "AST4", "Pacific/Pitcairn", "<-08>8", "Atlantic/South_Georgia", "<-02>2", "Africa/El_Aaiun", "WET0WEST,M3.5.0,M10.5.0/3", "US/Pacific-New", "PST8PDT,M3.2.0,M11.1.0", "Europe/Kirov", "<+03>-3", "America/Campo_Grande", "<-04>4<-03>,M10.3.0/0,M2.3.0/0", "America/Dawson_Creek", "MST7", "Antarctica/Vostok", "<+06>-6", "Europe/Bucharest", "EET-2EEST,M3.5.0/3,M10.5.0/4", "America/Porto_Velho", "<-04>4", "Europe/Monaco", "CET-1CEST,M3.5.0,M10.5.0/3", "Asia/Bishkek", "<+06>-6", "Africa/Ceuta", "CET-1CEST,M3.5.0,M10.5.0/3", "Europe/Rome", "CET-1CEST,M3.5.0,M10.5.0/3", "America/Winnipeg", "CST6CDT,M3.2.0,M11.1.0", "Asia/Aqtobe", "<+05>-5", "Africa/Dakar", "GMT0", "America/Fortaleza", "<-03>3", "Pacific/Tarawa", "<+12>-12", "America/Dawson", "PST8PDT,M3.2.0,M11.1.0", "Africa/Addis_Ababa", "EAT-3", "Pacific/Efate", "<+11>-11", "GMT", "GMT0", "Asia/Qyzylorda", "<+06>-6", "Europe/San_Marino", "CET-1CEST,M3.5.0,M10.5.0/3", "MET", "MET-1MEST,M3.5.0,M10.5.0/3", "Pacific/Auckland", "NZST-12NZDT,M9.5.0,M4.1.0/3", "America/Metlakatla", "AKST9AKDT,M3.2.0,M11.1.0", "America/Tortola", "AST4", "Etc/Zulu", "UTC0", "America/Denver", "MST7MDT,M3.2.0,M11.1.0", "Indian/Chagos", "<+06>-6", "America/Glace_Bay", "AST4ADT,M3.2.0,M11.1.0", "Pacific/Bougainville", "<+11>-11", "America/Hermosillo", "MST7", "Africa/Tunis", "CET-1", "Europe/Ulyanovsk", "<+04>-4", "Asia/Ust-Nera", "<+10>-10", "America/Resolute", "CST6CDT,M3.2.0,M11.1.0", "Etc/GMT", "GMT0", "Asia/Gaza", "EET-2EEST,M3.5.6/1,M10.5.6/1", "Europe/Dublin", "GMT0IST,M3.5.0/1,M10.5.0", "Antarctica/DumontDUrville", "<+10>-10", "America/Argentina/Catamarca", "<-03>3", "America/Indiana/Knox", "CST6CDT,M3.2.0,M11.1.0", "Europe/Nicosia", "EET-2EEST,M3.5.0/3,M10.5.0/4", "Africa/Timbuktu", "GMT0", "Asia/Novosibirsk", "<+07>-7", "EST", "EST5", "Africa/Kigali", "CAT-2", "America/Grand_Turk", "AST4", "Africa/Lagos", "WAT-1", "Europe/Sofia", "EET-2EEST,M3.5.0/3,M10.5.0/4", "America/Lima", "<-05>5", "America/Anchorage", "AKST9AKDT,M3.2.0,M11.1.0", "Pacific/Nauru", "<+12>-12"}; + +int Pos; + +String Olsen2POSIX::getPOSIX(String Olsen){ + int C; + C = 50; + for (Pos = Pos; Pos < MAX_ITEMS && C > 0; Pos += 2){ + C--; if (String(sTZData[Pos]) == Olsen) return sTZData[1 + Pos]; // Return second item. + } + if (Pos < MAX_ITEMS) return ""; + Pos = 0; + return TZMISSING; +} diff --git a/src/Olsen2POSIX.h b/src/Olsen2POSIX.h new file mode 100644 index 0000000..821874c --- /dev/null +++ b/src/Olsen2POSIX.h @@ -0,0 +1,12 @@ +#ifndef WATCHY_OLSEN2POSIX_H +#define WATCHY_OLSEN2POSIX_H + +#include + +class Olsen2POSIX{ + public: + String getPOSIX(String Olsen); + const String TZMISSING = "--MISSING--"; +}; + +#endif diff --git a/src/Watchy_GSR.cpp b/src/Watchy_GSR.cpp new file mode 100644 index 0000000..b6a892a --- /dev/null +++ b/src/Watchy_GSR.cpp @@ -0,0 +1,2170 @@ +#include "Watchy_GSR.h" + +// Debug message code. +bool SerialSetup; + +//Timezone configuration +static const char TZURL[] PROGMEM = "http://ip-api.com/json"; +static const char UserAgent[] PROGMEM = "Watchy"; + +// AlarmVBs[] = {"0111111110", "0011001100", "0110110110", "0101001010"}; +int AlarmVBs[] = {0x01FE, 0x00CC, 0x01B6, 0x014A}; +// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 +const char *Headings[] = {"Steps", "Alarms", "Timers", "Options", "Alarm 1", "Alarm 2", "Alarm 3", "Alarm 4", "Countdown Timer", "Elapsed Timer", "Display Style", "Border Mode", "Dexterity", "Menu & Back", "Time Mode", "Feedback", "Turbo Time", "Reset Screen", "Sync Watchy", "Watchy Connect", "OTA Update", "OTA Website","Watchy Reboot"}; + +const uint16_t Bits[10] = {1,2,4,8,16,32,64,128,256,512}; + +RTC_DATA_ATTR struct Stepping { + uint8_t Hour; + uint8_t Minutes; + bool Reset; + uint32_t Yesterday; +} Steps; + +RTC_DATA_ATTR struct Optional { + bool TwentyFour; // If the face shows 24 hour or Am/Pm. + bool LiteMode; // Lite/Dark mode. + bool Feedback; // Hapatic Feedback on buttons. + bool Border; // True to set the border to black/white. + bool Lefty; // Swaps the buttons to the other side. + bool Swapped; // Menu and Back buttons swap ends (vertically). + uint8_t Turbo; // 0-10 seconds. +} Options; + +RTC_DATA_ATTR int GuiMode; +RTC_DATA_ATTR bool ScreenOn; // Screen needs to be on. +RTC_DATA_ATTR bool VibeMode; // Vibe Motor is On=True/Off=False, used for the Hapatic and Alarms. +RTC_DATA_ATTR String WatchyStatus; // Used for the indicator in the bottom left, so when it changes, it asks for a screen refresh, if not, it doesn't. + +RTC_DATA_ATTR struct TimeData { + time_t UTC_RAW; // Copy of the UTC on init. + tmElements_t UTC; // Copy of UTC only split up for usage. + tmElements_t Local; // Copy of the Local time on init. + String TimeZone; // The location timezone, not the actual POSIX. + char POSIX[64]; // The POSIX result. + String LastTime; // Used for determining if the time display changed. + String LastDay; + String LastDate; + String LastYear; +} WatchTime; + +RTC_DATA_ATTR struct Countdown { + bool Active; + uint8_t Hours; + uint8_t Mins; + uint8_t MaxHours; + uint8_t MaxMins; + uint8_t Tone; // 10 to start. + uint8_t ToneLeft; // 30 to start. + time_t LastUTC; +} TimerDown; + +RTC_DATA_ATTR struct CountUp { + bool Active; + time_t SetAt; + time_t StopAt; +} TimerUp; + +RTC_DATA_ATTR struct BatteryUse { + float Last; // Used to track battery changes, only updates past 0.01 in change. + int8_t Direction; // -1 for draining, 1 for charging. + int8_t UpCount; // Counts how many times the battery is in a direction to determine true charging. + int8_t DownCount; + int8_t LastState; // 0=not visible, 1= showing chargeme, 2=showing charging. +} Battery; + +RTC_DATA_ATTR struct MenuUse { + int8_t Style; // MENU_INNORMAL or MENU_INOPTIONS + int8_t Item; // What Menu Item is being viewed. + int8_t SubItem; // Used for menus that have sub items, like alarms and Sync Time. + int8_t SubSubItem; // Used mostly in the alarm to offset choice. + String LastHeader; // Used for checking menu state needing update. + String LastItem; +} Menu; + +RTC_DATA_ATTR struct NTPUse { + uint8_t State; // State = 0=Off, 1=Start WiFi, 2=Wait for WiFi, TZ, send NTP request, etc, Finish. See function ProcessNTP(); + uint8_t Wait; // Counts up to 3 minutes, then fails. + uint8_t Pause; // How many 50ms to pause for. + time_t Last; // Last time it worked. + bool TimeZone; // Update Timezone during ProcessNTP. + bool UpdateUTC; // Update UTC during ProcessNTP. +} NTPData; + +struct dispUpdate { + bool Time; + bool Day; + bool Date; + bool Header; + bool Item; + bool Status; + bool Year; + bool Charge; + bool Full; +} Updates; + +struct SpeedUp { + bool On; + time_t Last; +} Turbo; + +DS3232RTC Watchy::RTC(false); +GxEPD2_BW Watchy::display(GxEPD2_154_D67(CS, DC, RESET, BUSY)); + +volatile uint8_t Button; +RTC_DATA_ATTR BMA423 sensor; +RTC_DATA_ATTR bool WIFI_CONFIGURED; +RTC_DATA_ATTR bool BLE_CONFIGURED; + +//RTC_DATA_ATTR alignas(8) struct AlarmID { +RTC_DATA_ATTR uint8_t Alarms_Hour[4]; +RTC_DATA_ATTR uint8_t Alarms_Minutes[4]; +RTC_DATA_ATTR uint16_t Alarms_Active[4]; // Bits 0-6 (days of week), 7 Repeat, 8 Active, 9 Tripped (meaning if it isn't repeating, don't fire). +RTC_DATA_ATTR uint8_t Alarms_Times[4]; // Set to 10 to start, ends when zero. +RTC_DATA_ATTR uint8_t Alarms_Playing[4]; // Means the alarm tripped and it is to be played (goes to 0 when it finishes). +//} Alarms[4]; + +WiFiClient WiFiC; // Tz +WiFiManager wifiManager; +HTTPClient HTTP; // Tz +Olsen2POSIX OP; // Tz code. +WebServer server(80); +unsigned long OTATimer; +bool WatchyAPOn; // States Watchy's AP is on for connection. Puts in Active Mode until back happens. +bool ActiveMode; // Moved so it can be checked. +bool OTAUpdate; // Internet based OTA Update. +bool OTAEnd; // Means somewhere, it wants this to end, so end it. +int OTATry; // Tries to connect to WiFi. +bool DoHapatic; // Want it to happen after screen update. +bool UpdateDisp; // Display needs to be updated. +unsigned long LastButton, OTAFail; + +// nvs_handle hNVS; + +Watchy::Watchy(){} //constructor + +// Init Defaults after a reboot, setup all the variables here for defaults to avoid randomness. +void Watchy::setupDefaults(){ + Options.TwentyFour = false; + Options.LiteMode = true; + Options.Feedback = true; + Options.Border = false; + Options.Lefty = false; + Options.Turbo = 3; + Steps.Hour = 6; + Steps.Minutes = 0; +} + +void Watchy::init(){ + uint64_t wakeupBit; + time_t NTPWaiting, RightNOW, LastCheck; + int AlarmIndex, Pushed; // Alarm being played. + bool AlarmsOn, WaitForNext, AP, Pulse; + unsigned long Since, AlarmReset, APLoop; + + esp_sleep_wakeup_cause_t wakeup_reason; + Wire.begin(SDA, SCL); //init i2c + display.init(0, false); //_initial_refresh to false to prevent full update on init (moved here so it isn't done repeatedly during loops). + + pinMode(MENU_BTN_PIN, INPUT); // Prep these for the loop below. + pinMode(BACK_BTN_PIN, INPUT); + pinMode(UP_BTN_PIN, INPUT); + pinMode(DOWN_BTN_PIN, INPUT); + + wakeup_reason = esp_sleep_get_wakeup_cause(); //get wake up reason + wakeupBit = esp_sleep_get_ext1_wakeup_status(); + + switch (wakeup_reason) + { + case ESP_SLEEP_WAKEUP_EXT0: //RTC Alarm + RTC.alarm(ALARM_2); //resets the alarm flag in the RTC + UpdateUTC(); + UpdateClock(); + detectBattery(); + UpdateDisp=true; + break; + case ESP_SLEEP_WAKEUP_EXT1: //button Press + //if (wakeup_reason & ACC_INT_MASK) handleAccelerometer(); else + Pushed = getButtonMaskToID(wakeupBit); + if (Pushed > 0) { Button = Pushed; LastButton = millis(); } + break; + default: //reset + _rtcConfig(); + _bmaConfig(); + UpdateUTC(); + UpdateClock(); + setupDefaults(); + initZeros(); + AlarmIndex=0; + AlarmsOn=false; + WaitForNext=false; + Updates.Full=true; + UpdateDisp=true; + //Init interrupts. + attachInterrupt(digitalPinToInterrupt(MENU_BTN_PIN), std::bind(&Watchy::handleInterrupt,this), HIGH); + attachInterrupt(digitalPinToInterrupt(BACK_BTN_PIN), std::bind(&Watchy::handleInterrupt,this), HIGH); + attachInterrupt(digitalPinToInterrupt(UP_BTN_PIN), std::bind(&Watchy::handleInterrupt,this), HIGH); + attachInterrupt(digitalPinToInterrupt(DOWN_BTN_PIN), std::bind(&Watchy::handleInterrupt,this), HIGH); + break; + } + // Sometimes BMA crashes - simply try to reinitialize bma... + if (sensor.getErrorCode() != 0) { + sensor.shutDown(); + sensor.wakeUp(); + sensor.softReset(); + _bmaConfig(); + } + + // Detect NTP state, alarms playing and loop here until it is finished. + if (Button > 0) { handleButtonPress(Button); Button = 0; } + + CalculateTones(); monitorSteps(); + AlarmsOn =(Alarms_Times[0] > 0 || Alarms_Times[1] > 0 || Alarms_Times[2] > 0 || Alarms_Times[3] > 0 || TimerDown.ToneLeft > 0); + ActiveMode = (InTurbo() || NTPData.State > 0 || AlarmsOn || WatchyAPOn || OTAUpdate); + + if (UpdateDisp) showWatchFace(); //partial updates on tick + NTPWaiting = WatchTime.UTC_RAW; + RightNOW = WatchTime.UTC_RAW; + Since=millis(); + LastCheck = RightNOW; + AlarmReset = Since; + OTATimer = Since; + OTAFail = Since; + if (ActiveMode){ + while (ActiveMode == true) { // Here, we hijack the init and LOOP until the NTP is done, watching for the proper time when we *SHOULD* update the screen to keep time with everything. + if (!(OTAUpdate && Menu.SubItem == 3)){ + if (NTPData.State > 0 && !WatchyAPOn && !OTAUpdate){ + if (NTPData.Pause == 0) ProcessNTP(); else NTPData.Pause--; + if (RightNOW - NTPWaiting >= 60){ + NTPWaiting = WatchTime.UTC_RAW; + NTPData.Wait++; + UpdateDisp=true; + } + } + + // Here, make sure the clock updates on-screen. + if (WatchTime.UTC_RAW - LastCheck >= 60){ + LastCheck = WatchTime.UTC_RAW; + detectBattery(); + UpdateDisp = true; + } + + // Here, do the alarm buzzings by way of which one is running. + + if (AlarmsOn && !OTAUpdate){ + if (WaitForNext){ + // Wait for the next second to change between any alarms still to play. + if (millis() - AlarmReset > 999){ // Time changed. + AlarmReset = millis(); + WaitForNext = false; + AlarmIndex = roller(AlarmIndex + 1, 0, 4); + if (getToneTimes(AlarmIndex) == 0){ + AlarmIndex = roller(AlarmIndex + 1, 0, 4); + if (getToneTimes(AlarmIndex) == 0){ + AlarmIndex = roller(AlarmIndex + 1, 0, 4); + if (getToneTimes(AlarmIndex) == 0){ + AlarmIndex = roller(AlarmIndex + 1, 0, 4); + if (getToneTimes(AlarmIndex) == 0){ + AlarmIndex = roller(AlarmIndex + 1, 0, 4); + } + } + } + } + } + }else if(AlarmIndex == 4){ + if (TimerDown.ToneLeft > 0){ + if (TimerDown.Tone == 0){ + WaitForNext=true; + if (TimerDown.ToneLeft > 0){ + TimerDown.ToneLeft--; + TimerDown.Tone = 24; + } + }else{ + TimerDown.Tone--; + Pulse = (((TimerDown.Tone / 2) & 1) != 0); + if (!Pulse && TimerDown.Tone > 0) TimerDown.Tone--; + VibeTo(Pulse); // Turns Vibe on or off depending on bit state. + } + }else WaitForNext=true; + }else if (Alarms_Times[AlarmIndex] > 0){ + if (Alarms_Playing[AlarmIndex] > 0){ + Alarms_Playing[AlarmIndex]--; + if (Menu.SubItem > 0 && Menu.Item - MENU_ALARM1 == AlarmIndex){ + VibeTo(false); + DoHapatic = false; + Alarms_Playing[AlarmIndex]=0; + Alarms_Times[AlarmIndex]=0; + }else{ + Pulse = ((AlarmVBs[AlarmIndex] & Bits[Alarms_Playing[AlarmIndex] / 3]) != 0); + VibeTo(Pulse); // Turns Vibe on or off depending on bit state. + DoHapatic = false; + } + if (Alarms_Playing[AlarmIndex] == 0 && Alarms_Times[AlarmIndex] > 0){ + Alarms_Times[AlarmIndex]--; // Decrease count, eventually this will all stop on it's own. + WaitForNext = true; + if (Alarms_Times[AlarmIndex] > 0) Alarms_Playing[AlarmIndex] = 30; + } + }else WaitForNext = true; + }else WaitForNext = true; + } + + if (WatchyAPOn && !OTAUpdate){ + switch (Menu.SubItem){ + case 0: // Turn off AP. + OTAEnd = true; + break; + case 1: // Turn on AP. + if (WiFi.getMode() != WIFI_AP || (millis() - OTATimer > 4000 && OTATry < 3)){ + OTATimer=millis(); + OTATry++; + WiFi.setHostname(WiFi_AP_SSID); + wifiManager.setConfigPortalBlocking(false); + wifiManager.setWiFiAPHidden(WiFi_AP_HIDE); + AP = WiFi.softAP(WiFi_AP_SSID,WiFi_AP_PSWD,1,WiFi_AP_HIDE); + }else if (WiFi.getMode() == WIFI_AP){ + wifiManager.startWebPortal(); + Menu.SubItem++; + setStatus("AP"); + UpdateDisp=true; + APLoop=millis(); + }else Menu.SubItem = 0; // Fail, something is amiss. + break; + default: // 2 to 5 is here. + if (Menu.SubItem > 1){ + if(WiFi.getMode() == WIFI_STA){ + Menu.SubItem = 0; + break; + } + if (wifiManager.process() == WL_CONNECTED){ // Setting worked. + Menu.SubItem = 0; + break; + } + if (millis() - APLoop > 8000){ + Menu.SubItem = roller(Menu.SubItem + 1, 2,4); + UpdateDisp = true; + APLoop=millis(); + } + } + } + } + + } + if (OTAUpdate){ + switch (Menu.SubItem){ + case 1: // Turn on WiFi and connect. + if (WiFi.status() != WL_CONNECTED && OTATry < 3){ + if (millis() - OTATimer > 4000 || WiFi.getMode() != WIFI_STA){ + WiFi.disconnect(); + WiFi.setHostname(WiFi_AP_SSID); + WiFi.mode(WIFI_STA); + OTATimer = millis(); + OTATry++; + if(WiFi.begin() == WL_CONNECT_FAILED) OTAEnd=true; + } + }else if (WiFi.status() == WL_CONNECTED){ + setStatus("WiFi"); + Menu.SubItem++; + UpdateDisp = true; + }else OTAEnd=true; + break; + case 2: // Setup Arduino OTA and wait for it to either finish or fail by way of back button held for too long OR 2 minute with no upload. + if (Menu.Item == MENU_OTAU){ + ArduinoOTA.setHostname(WiFi_AP_SSID); + ArduinoOTA + .onStart([]() { + String Type; + if (ArduinoOTA.getCommand() == U_FLASH) + Type = "sketch"; + else // U_SPIFFS + Type = "filesystem"; + + // NOTE: if updating SPIFFS this would be the place to unmount SPIFFS using SPIFFS.end() + //Serial.println("Start updating " + Type); + }) + + .onEnd([]() { + OTAEnd = true; + //Serial.println("\nEnd"); + }) + .onProgress([](unsigned int progress, unsigned int total) { + OTATimer=millis(); + //Serial.printf("Progress: %u%%\n", (progress / (total / 100))); + }) + .onError([](ota_error_t error) { + /*Serial.printf("Error[%u]: ", error); + if (error == OTA_AUTH_ERROR) Serial.println("Auth Failed"); + else if (error == OTA_BEGIN_ERROR) Serial.println("Begin Failed"); + else if (error == OTA_CONNECT_ERROR) Serial.println("Connect Failed"); + else if (error == OTA_RECEIVE_ERROR) Serial.println("Receive Failed"); + else if (error == OTA_END_ERROR) Serial.println("End Failed"); + */ + }); + + ArduinoOTA.begin(); + }else if (Menu.Item == MENU_OTAM){ + /*return index page which is stored in basicIndex */ + server.on("/", HTTP_GET, [=, this]() { + server.sendHeader("Connection", "close"); + server.send(200, "text/html", basicIndex); + }); + server.on("/settings", HTTP_GET, [=, this]() { + String S = settingsA + GetSettings() + settingsB; + server.sendHeader("Connection", "close"); + server.send(200, "text/html", S); + }); + server.on("/update", HTTP_GET, [=, this]() { + server.sendHeader("Connection", "close"); + server.send(200, "text/html", updateIndex); + }); + server.on("/settings", HTTP_POST, [=, this](){ + if (server.argName(0) == "settings") StoreSettings(server.arg(0)); + server.sendHeader("Connection", "close"); + server.send(200, "text/html", settingsDone); + }); + server.on("/update", HTTP_POST, [](){ + server.sendHeader("Connection", "close"); + server.send(200, "text/plain", (Update.hasError()) ? "FAIL" : "OK"); + ESP.restart(); + }, []() { + HTTPUpload& upload = server.upload(); + if (upload.status == UPLOAD_FILE_START) { + OTATimer=millis(); + //Serial.printf("Update: %s\n", upload.filename.c_str()); + if (!Update.begin(UPDATE_SIZE_UNKNOWN)) { //start with max available size + Update.printError(Serial); + } + } else if (upload.status == UPLOAD_FILE_WRITE) { + /* flashing firmware to ESP*/ + delay(2); + if (Update.write(upload.buf, upload.currentSize) != upload.currentSize) Update.printError(Serial); + delay(2); + } else if (upload.status == UPLOAD_FILE_END) { + if (Update.end(true)) { //true to set the size to the current progress + OTAEnd=true; + //Serial.printf("Update Success: %u\nRebooting...\n", upload.totalSize); + } //else Update.printError(Serial); + } + }); + server.begin(); + } + Menu.SubItem++; + showWatchFace(); + break; + case 3: // Monitor back button and turn WiFi off if it happens, or if duration is longer than 2 minutes. + if (Menu.Item == MENU_OTAU) ArduinoOTA.handle(); + else if (Menu.Item == MENU_OTAM) server.handleClient(); + if (getButtonPins() != 2) OTATimer = millis(); // Not pressing "BACK". + if (millis() - OTATimer > 10000 || millis() - OTAFail > 600000) OTAEnd = true; // Fail if holding back for 10 seconds OR 120 seconds has passed. + } + } + + // OTAEnd code. + if (OTAEnd){ + //if (Menu.Item == MENU_OTAU) ArduinoOTA.stop(); // Why is there no stop/close??? + if (Menu.Item == MENU_OTAM) server.stop(); + if (WatchyAPOn) wifiManager.stopConfigPortal(); + VibeTo(false); + OTAEnd=false; + OTAUpdate=false; + WatchyAPOn = false; + WiFi.disconnect(); + WiFi.mode(WIFI_OFF); + btStop(); + Menu.SubItem=0; + setStatus(""); + UpdateDisp=true; + } + + // Don't do anything time sensitive while in OTA Update. + if (!(OTAUpdate && Menu.SubItem == 3)){ + + CalculateTones(); monitorSteps(); + AlarmsOn =(Alarms_Times[0] > 0 || Alarms_Times[1] > 0 || Alarms_Times[2] > 0 || Alarms_Times[3] > 0 || TimerDown.ToneLeft > 0); + ActiveMode = (InTurbo() || NTPData.State > 0 || AlarmsOn || WatchyAPOn || OTAUpdate); + + // Here, check for button presses and respond, done here to avoid turbo button presses. + + handleInterrupt(); + if (Button > 0) { handleButtonPress(Button); Button = 0; } + if (UpdateDisp) showWatchFace(); //partial updates on tick + + Since=50-(millis()-Since); + if (Since <= 50) delay(Since); + UpdateUTC(); + RightNOW = WatchTime.UTC_RAW; + Since=millis(); + } + } + } + + if (Button > 0) { handleButtonPress(Button); Button = 0; } + if (UpdateDisp) showWatchFace(); //partial updates on tick + deepSleep(); +} + +void Watchy::showWatchFace(){ + display.epd2.setDarkBorder(Options.Border); + drawWatchFace(); + if (Options.Feedback && DoHapatic){ + VibeTo(true); + delay(40); + VibeTo(false); + } + DoHapatic=false; + UpdateDisp=false; + ScreenRefresh(); +} + +void Watchy::drawWatchFace(){ + uint8_t Direction; + + Direction = sensor.getDirection(); // Directional screen on. == DIRECTION_DISP_UP + + display.fillScreen(Options.LiteMode ? GxEPD_WHITE : GxEPD_BLACK); + display.setTextColor(Options.LiteMode ? GxEPD_BLACK : GxEPD_WHITE); + + ScreenOn = (Direction == DIRECTION_DISP_UP || Direction == DIRECTION_TOP_EDGE || Battery.Direction == 1 || true); // True set due to bug. + + if (ScreenOn){ + if (!OTAUpdate){ + drawTime(); + drawDay(); + drawYear(); + } + if (GuiMode == WATCHON) drawDate(); + else if (GuiMode == MENUON) drawMenu(); + } + drawChargeMe(); + // Show WiFi/AP/TZ/NTP if in progress. + drawStatus(); + UpdateDisp = false; +} + +void Watchy::drawTime(){ + int16_t x1, y1; + uint16_t w, h, tw; + String O; + bool PM; + PM = false; + O = MakeTime(WatchTime.Local.Hour, WatchTime.Local.Minute, PM); + display.setFont(&aAntiCorona36pt7b); + display.setTextColor(Options.LiteMode ? GxEPD_BLACK : GxEPD_WHITE); + + display.getTextBounds(O, 0, TimeY, &x1, &y1, &w, &h); + tw = (200 - w) /2; + display.setCursor(tw, TimeY); + display.println(O); + + if (PM){ + tw=clamp(tw + w + 6, 0, 184); + display.drawBitmap(tw, TimeY - 45, PMIndicator, 6, 6, Options.LiteMode ? GxEPD_BLACK : GxEPD_WHITE); +// display.fillRect(tw, TimeY - 45 ,6 ,6, Options.LiteMode ? GxEPD_BLACK : GxEPD_WHITE); + } + Updates.Time = (O != WatchTime.LastTime); + WatchTime.LastTime = O; +} + +void Watchy::drawDay(){ + int16_t x1, y1; + uint16_t w, h, tw; + String O; + + O = dayStr(WatchTime.Local.Wday + 1); + display.setFont(&aAntiCorona16pt7b); + display.setTextColor(Options.LiteMode ? GxEPD_BLACK : GxEPD_WHITE); + display.getTextBounds(O, 0, DayY, &x1, &y1, &w, &h); + w = (200 - w) /2; + display.setCursor(w, DayY); + display.println(O); + Updates.Day = (O != WatchTime.LastDay); + WatchTime.LastDay = O; +} + +void Watchy::drawDate(){ + int16_t x1, y1; + uint16_t w, h, tw; + String O; + + display.setFont(&aAntiCorona15pt7b); //Shahd_Serif17pt7b); + display.setTextColor(Options.LiteMode ? GxEPD_BLACK : GxEPD_WHITE); + O = String(monthStr(WatchTime.Local.Month)) + " " + String(WatchTime.Local.Day); + //O="September 30"; + display.getTextBounds(O, 0, DateY, &x1, &y1, &w, &h); + w = (200 - w) /2; + display.setCursor(w, DateY); + display.print(O); + Updates.Date = (O != WatchTime.LastDate); + WatchTime.LastDate = O; +} + +void Watchy::drawYear(){ + int16_t x1, y1; + uint16_t w, h, tw; + String O; + + display.setFont(&aAntiCorona16pt7b); + display.setTextColor(Options.LiteMode ? GxEPD_BLACK : GxEPD_WHITE); + O = String(WatchTime.Local.Year + 1900); + display.getTextBounds(O, 0, YearY, &x1, &y1, &w, &h); + w = (200 - w) /2; + display.setCursor(w, YearY); + display.print(O); + Updates.Year = (O != WatchTime.LastYear); + WatchTime.LastYear = O; +} + +void Watchy::drawMenu(){ + int16_t x1, y1; + uint16_t w, h, tw; + String O, S; + + display.setFont(&aAntiCorona12pt7b); + display.fillRect(0, MenuTop, 200, MenuHeight, Options.LiteMode ? GxEPD_WHITE : GxEPD_BLACK); + display.drawBitmap(0, MenuTop, (Menu.Style == MENU_INOPTIONS) ? OptionsMenuBackground : MenuBackground, 200, MenuHeight, Options.LiteMode ? GxEPD_BLACK : GxEPD_WHITE); + display.setTextColor(Options.LiteMode && Menu.Style != MENU_INNORMAL ? GxEPD_WHITE : GxEPD_BLACK); + if ((Menu.Item == MENU_OTAU || Menu.Item == MENU_OTAM) && (Menu.SubItem == 2 || Menu.SubItem == 3)) O = "Upload Firmware"; else O = Headings[Menu.Item]; + display.getTextBounds(O, 0, HeaderY, &x1, &y1, &w, &h); + w = (196 - w) /2; + display.setCursor(w + 2, HeaderY); + display.print(O); + Updates.Header = (O != Menu.LastHeader); + Menu.LastHeader = O; + display.setTextColor(GxEPD_BLACK); // Only show menu in lite mode + if (Menu.Item == MENU_STEPS){ //Steps + switch (Menu.SubItem){ + case 0: // Steps. + S = ""; if (Steps.Yesterday > 0) S = " (" + MakeSteps(Steps.Yesterday) + ")"; + O = MakeSteps(sensor.getCounter()) + S; + break; + case 1: // Hour. + O="[" + MakeHour(Steps.Hour) + "]:" + MakeMinutes(Steps.Minutes) + (Steps.Hour > 11 ? " PM" : " AM") ; + break; + case 2: // x0 minutes. + S=MakeMinutes(Steps.Minutes); + O=MakeHour(Steps.Hour) + ":[" + S.charAt(0) + "]" + S.charAt(1) + (Steps.Hour > 11 ? " PM" : " AM") ; + break; + case 3: // 0x minutes. + S=MakeMinutes(Steps.Minutes); + O=MakeHour(Steps.Hour) + ":" + S.charAt(0) + "[" + S.charAt(1) + "]" + (Steps.Hour > 11 ? " PM" : " AM") ; + break; + case 4: // Sunday. + O = "MENU to Reset"; + } + }else if (Menu.Item == MENU_ALARMS){ + O = "MENU to Select"; + }else if (Menu.Item >= MENU_ALARM1 && Menu.Item <= MENU_ALARM4){ // Alarms + O = ""; + switch (Menu.SubItem){ + case 0: // Menu to Edit. + O="Menu to Edit"; + break; + case 1: // Hour. + O="[" + MakeHour(Alarms_Hour[Menu.Item - MENU_ALARM1]) + "]:" + MakeMinutes(Alarms_Minutes[Menu.Item - MENU_ALARM1]) + ((Alarms_Hour[Menu.Item - MENU_ALARM1] > 11) ? " PM" : " AM") ; + break; + case 2: // x0 minutes. + S=MakeMinutes(Alarms_Minutes[Menu.Item - MENU_ALARM1]); + O=MakeHour(Alarms_Hour[Menu.Item - MENU_ALARM1]) + ":[" + S.charAt(0) + "]" + S.charAt(1) + ((Alarms_Hour[Menu.Item - MENU_ALARM1] > 11) ? " PM" : " AM") ; + break; + case 3: // 0x minutes. + S=MakeMinutes(Alarms_Minutes[Menu.Item - MENU_ALARM1]); + O=MakeHour(Alarms_Hour[Menu.Item - MENU_ALARM1]) + ":" + S.charAt(0) + "[" + S.charAt(1) + "]" + ((Alarms_Hour[Menu.Item - MENU_ALARM1] > 11) ? " PM" : " AM") ; + break; + case 4: // Sunday. + display.setTextColor(((Alarms_Active[Menu.Item - MENU_ALARM1] & Bits[0]) == Bits[0]) ? GxEPD_WHITE : GxEPD_BLACK); + O=dayStr(1); + break; + case 5: // Monday. + display.setTextColor(((Alarms_Active[Menu.Item - MENU_ALARM1] & Bits[1]) == Bits[1]) ? GxEPD_WHITE : GxEPD_BLACK); + O=dayStr(2); + break; + case 6: // Tuesday. + display.setTextColor(((Alarms_Active[Menu.Item - MENU_ALARM1] & Bits[2]) == Bits[2]) ? GxEPD_WHITE : GxEPD_BLACK); + O=dayStr(3); + break; + case 7: // Wedmesday. + display.setTextColor(((Alarms_Active[Menu.Item - MENU_ALARM1] & Bits[3]) == Bits[3]) ? GxEPD_WHITE : GxEPD_BLACK); + O=dayStr(4); + break; + case 8: // Thursday. + display.setTextColor(((Alarms_Active[Menu.Item - MENU_ALARM1] & Bits[4]) == Bits[4]) ? GxEPD_WHITE : GxEPD_BLACK); + O=dayStr(5); + break; + case 9: // Friday. + display.setTextColor(((Alarms_Active[Menu.Item - MENU_ALARM1] & Bits[5]) == Bits[5]) ? GxEPD_WHITE : GxEPD_BLACK); + O=dayStr(6); + break; + case 10: // Saturday. + display.setTextColor(((Alarms_Active[Menu.Item - MENU_ALARM1] & Bits[6]) == Bits[6]) ? GxEPD_WHITE : GxEPD_BLACK); + O=dayStr(7); + break; + case 11: // Repeat + display.setTextColor(((Alarms_Active[Menu.Item - MENU_ALARM1] & ALARM_REPEAT) == ALARM_REPEAT) ? GxEPD_WHITE : GxEPD_BLACK); + O="Repeat"; + break; + case 12: // Active + display.setTextColor(((Alarms_Active[Menu.Item - MENU_ALARM1] & ALARM_ACTIVE) == ALARM_ACTIVE) ? GxEPD_WHITE : GxEPD_BLACK); + O="Active"; + } + }else if (Menu.Item == MENU_TIMERS){ // Timers + O = "MENU to Select"; + }else if (Menu.Item == MENU_TIMEDN){ // Countdown + switch (Menu.SubItem){ + case 0: + O = "MENU to Edit"; + break; + case 1: // Hours + S=MakeMinutes(TimerDown.Active ? TimerDown.Mins : TimerDown.MaxMins); + O="[" + String(TimerDown.Active ? TimerDown.Hours : TimerDown.MaxHours) + "]:" + S + (TimerDown.Active ? " Stop" : " Start"); + break; + case 2: // 1x minutes. + S=MakeMinutes(TimerDown.Active ? TimerDown.Mins : TimerDown.MaxMins); + O=String(TimerDown.Active ? TimerDown.Hours : TimerDown.MaxHours) + ":[" + S.charAt(0) + "]" + S.charAt(1) + (TimerDown.Active ? " Stop" : " Start"); + break; + case 3: // x1 minutes. + S=MakeMinutes(TimerDown.Active ? TimerDown.Mins : TimerDown.MaxMins); + O=String(TimerDown.Active ? TimerDown.Hours : TimerDown.MaxHours) + ":" + S.charAt(0) + "[" + S.charAt(1) + "]" + (TimerDown.Active ? " Stop" : " Start"); + break; + case 4: // Button. + S=MakeMinutes(TimerDown.Active ? TimerDown.Mins : TimerDown.MaxMins); + O=String(TimerDown.Active ? TimerDown.Hours : TimerDown.MaxHours) + ":" + S + (TimerDown.Active ? " [Stop]" : " [Start]"); + } + }else if (Menu.Item == MENU_TIMEUP){ // Elapsed + switch (Menu.SubItem){ + case 0: + O = "MENU to Edit"; + break; + case 1: + if (TimerUp.Active) { y1 = ((WatchTime.UTC_RAW - (TimerUp.SetAt + WatchTime.UTC.Second)) / 3600); x1 = (((WatchTime.UTC_RAW - (TimerUp.SetAt + WatchTime.UTC.Second)) + 3600 * y1) / 60); } + else { y1 = ((TimerUp.StopAt - TimerUp.SetAt) / 3600); x1 = (((TimerUp.StopAt - TimerUp.SetAt) + 3600 * y1) / 60); } + O=String(y1) + ":" + MakeMinutes(x1) + (TimerUp.Active ? " [Stop]" : " [Start]"); + } + }else if (Menu.Item == MENU_OPTIONS){ // Options Menu + O = "MENU to Enter"; + }else if (Menu.Item == MENU_DISP){ // Switch Mode + if (Options.LiteMode){ + O = "Lite"; + }else { + O = "Dark"; + } + }else if (Menu.Item == MENU_SIDE){ // Dexterity Mode + if (Options.Lefty){ + O = "Left-handed"; + }else { + O = "Right-handed"; + } + }else if (Menu.Item == MENU_SWAP){ // Swap Menu/Back Buttons + if (Options.Swapped){ + O = "Swapped"; + }else { + O = "Normal"; + } + }else if (Menu.Item == MENU_BRDR){ // Border Mode + if (Options.Border){ + O = "Hide"; + }else { + O = "Show"; + } + }else if (Menu.Item == MENU_MODE){ // 24hr Format Swap. + if (Options.TwentyFour){ + O = "24 Hour"; + }else { + O = "AM/PM"; + } + }else if (Menu.Item == MENU_FEED){ // Feedback + if (Options.Feedback){ + O = "Enabled"; + }else { + O = "Disabled"; + } + }else if (Menu.Item == MENU_TRBO){ // Turbo! + if (Options.Turbo > 0) O=String(Options.Turbo) + " seconds"; else O = "Off"; + }else if (Menu.Item == MENU_SCRN){ // Reset Screen. + O = "MENU to Reset"; + }else if (Menu.Item == MENU_SYNC){ // NTP + if (Menu.SubItem == 0){ + O = "MENU to Start"; + }else if (Menu.SubItem == 1){ + O = "Time"; + }else if (Menu.SubItem == 2){ + O = "TimeZone"; + }else if (Menu.SubItem == 3){ + O = "TimeZone & Time"; + } + }else if (Menu.Item == MENU_WIFI){ // Reset Steps. + if (Menu.SubItem == 0){ + O = "MENU to Begin"; + }else if (Menu.SubItem == 1){ + O = "Starting AP"; + }else if (Menu.SubItem == 2){ + O = WiFi_AP_SSID; + }else if (Menu.SubItem == 3){ + O = WiFi.softAPIP().toString(); + }else if (Menu.SubItem == 4){ + O = "BACK to End"; + } + }else if (Menu.Item == MENU_OTAU || Menu.Item == MENU_OTAM){ // OTA Update. + if (Menu.SubItem == 0){ + O = "MENU to Connect"; + }else if (Menu.SubItem == 1){ + O = "Connecting..."; + }else if (Menu.SubItem == 2 || Menu.SubItem == 3){ + O = WiFi.localIP().toString(); + } + }else if (Menu.Item == MENU_RSET){ // Reboot Watchy + O = "MENU to Reboot"; + } + if (O > ""){ + display.getTextBounds(O, 0, DataY, &x1, &y1, &w, &h); + w = (196 - w) /2; + display.setCursor(w + 2, DataY); + display.print(O); + } + Updates.Item = (O != Menu.LastItem); + Menu.LastItem = O; +} + +void Watchy::deepSleep(){ + //display.hibernate(); + + #ifndef ESP_RTC + esp_sleep_enable_ext0_wakeup(RTC_PIN, 0); //enable deep sleep wake on RTC interrupt + #endif + #ifdef ESP_RTC + esp_sleep_enable_timer_wakeup(60000000); + #endif + esp_sleep_enable_ext1_wakeup(BTN_PIN_MASK, ESP_EXT1_WAKEUP_ANY_HIGH); //enable deep sleep wake on button press + esp_deep_sleep_start(); +} + +void Watchy::detectBattery(){ + float CBAT, BATOff; + CBAT = getBatteryVoltage(); // Check battery against previous versions to determine which direction the battery is going. + BATOff = CBAT - Battery.Last; + //Detect Power direction + + if (BATOff > 0.02){ + Battery.UpCount++; + if (Battery.UpCount > 3){ Battery.Direction = 1; Battery.UpCount = 0; Battery.DownCount = 0; Battery.Last = CBAT; } + }else{ + if (BATOff < 0.00) Battery.DownCount++; + if (Battery.DownCount > 2){ Battery.Direction = -1; Battery.UpCount = 0; Battery.DownCount = 0; Battery.Last = CBAT; } + } +} + +void Watchy::ProcessNTP(){ + // Do ProgressNTP here. + switch (NTPData.State){ + // Start WiFi and Connect. + case 1:{ + HTTP.setUserAgent(UserAgent); + setStatus("WiFi"); + if (WiFi.status() != WL_CONNECTED){ + WiFi.disconnect(); + WiFi.setHostname(WiFi_AP_SSID); + WiFi.mode(WIFI_STA); + if(WiFi.begin() == WL_CONNECT_FAILED){ + NTPData.Pause = 0; + NTPData.State = 99; + break; + } + } + NTPData.Wait = 0; + NTPData.Pause = 80; + NTPData.State++; + break; + } + + // Am I Connected? If so, ask for NTP. + case 2:{ + if (WiFi.status() != WL_CONNECTED){ + WiFi.disconnect(); + if(WiFi.begin() == WL_CONNECT_FAILED){ + NTPData.Pause = 0; + NTPData.State = 99; + break; + } + NTPData.Pause = 80; + if (NTPData.Wait > 2){ + NTPData.Pause = 0; + NTPData.State = 99; + break; + } + break; + } + if (NTPData.TimeZone == false){ + NTPData.State = 5; + NTPData.Pause = 0; + break; + } + + NTPData.State++; + setStatus("TZ"); + // Do the next part. + HTTP.begin(WiFiC, TZURL); // Call it and leave. + NTPData.Wait = 0; + NTPData.Pause = 80; + break; + } + + case 3:{ + // Get GeoLocation + if (WiFi.status() == WL_DISCONNECTED){ + NTPData.Pause = 0; + NTPData.State = 99; + break; + } + if (HTTP.GET() == HTTP_CODE_OK) { + String payload = HTTP.getString(); + JSONVar root = JSON.parse(payload); + String S = JSON.stringify(root["timezone"]); + S.replace('"',' '); + S.trim(); + WatchTime.TimeZone = S; + HTTP.end(); + NTPData.Wait = 0; + NTPData.Pause = 0; + NTPData.State++; // Test + } + break; + } + + case 4:{ + // Process Timezone POSIX. + String NewTZ = OP.getPOSIX(WatchTime.TimeZone); + if(NewTZ == OP.TZMISSING){ + NTPData.Pause = 0; + NTPData.State = 99; + break; + }else if (NewTZ ==""){ + break; + } + strcpy(WatchTime.POSIX, NewTZ.c_str()); + NTPData.Wait = 0; + NTPData.Pause = 0; + NTPData.State++; + break; + } + + case 5:{ + if (NTPData.UpdateUTC == false || WiFi.status() == WL_DISCONNECTED){ + NTPData.State = 99; + NTPData.Pause = 0; + break; + } + setStatus("NTP"); + configTime(0,0,"132.246.11.237","132.246.11.227"); + NTPData.Wait = 0; + NTPData.Pause = 20; + NTPData.State++; + break; + } + + case 6:{ + if (time(nullptr) < 1000000000l){ + if (NTPData.Wait > 2){ + NTPData.Pause = 0; + NTPData.State = 99; + break; + } + break; + } + WatchTime.UTC_RAW = time(nullptr); + NTPData.Last = WatchTime.UTC_RAW; + tmElements_t TM; + breakTime(WatchTime.UTC_RAW,TM); + RTC.write(TM); + UpdateUTC(); + UpdateClock(); + NTPData.Pause = 0; + NTPData.State = 99; + break; + } + + case 99:{ + WiFi.disconnect(); + WiFi.mode(WIFI_OFF); + btStop(); + NTPData.Wait = 0; + NTPData.Pause = 0; + NTPData.State = 0; + NTPData.UpdateUTC = false; + NTPData.TimeZone = false; + setStatus(""); + } + } +} + +void Watchy::drawChargeMe(){ + // Shows Battery Direction indicators. + int8_t D = 0; + if (Battery.Direction == 1){ + // Show Battery charging bitmap. + display.drawBitmap(155, 178, Charging, 40, 17, Options.LiteMode ? GxEPD_BLACK : GxEPD_WHITE); + D = 2; + // Check if the NTP has been done. + if (WatchTime.UTC_RAW - NTPData.Last > 14400 && NTPData.State == 0){ + NTPData.State = 1; + NTPData.TimeZone = (WatchTime.POSIX[0] == 0); // No Timezone, go get one! + NTPData.UpdateUTC = true; + } + }else if (Battery.Direction == -1 && getBatteryVoltage() < MinBattery){ + // Show Battery needs charging bitmap. + display.drawBitmap(155, 178, ChargeMe, 40, 17, Options.LiteMode ? GxEPD_BLACK : GxEPD_WHITE); + D = 1; + } + Updates.Charge = (D != Battery.LastState); + Battery.LastState = D; +} + +void Watchy::drawStatus(){ + if (WatchyStatus > ""){ + display.fillRect(NTPX, NTPY - 19, 60, 20, Options.LiteMode ? GxEPD_WHITE : GxEPD_BLACK); + display.setFont(&Bronova_Regular13pt7b); + display.setCursor(NTPX, NTPY); + display.setTextColor(Options.LiteMode ? GxEPD_BLACK : GxEPD_WHITE); + display.print(WatchyStatus); + } +} + +void Watchy::setStatus(String Status){ + if (WatchyStatus != Status){ + WatchyStatus = Status; + Updates.Status=true; + UpdateDisp=true; + } +} + +void Watchy::VibeTo(bool Mode){ + if (Mode != VibeMode){ + if (Mode){ + sensor.enableFeature(BMA423_WAKEUP, false); + pinMode(VIB_MOTOR_PIN, OUTPUT); + digitalWrite(VIB_MOTOR_PIN, true); + }else{ + digitalWrite(VIB_MOTOR_PIN, false); + sensor.enableFeature(BMA423_WAKEUP, true); + } + VibeMode = Mode; + } +} + +/* +void Watchy::handleAccelerometer(){ + uint8_t Direction; + + //Serial.println("Accel int."); + if (sensor.isTilt()){ + DBug("Tilt!!!"); + Direction = sensor.getDirection(); // Directional screen on. == DIRECTION_DISP_UP + if ((Direction == DIRECTION_DISP_UP) != ScreenOn){ + UpdateDisp = true; // Update Screen to new state. + } + }else if (sensor.isDoubleClick()){ + DBug("Double Tap!"); + } +}*/ + +void Watchy::handleButtonPress(uint8_t Pressed){ + uint8_t Direction; + int ml, mh; + + // Check to see if screen is upward, if it is/isn't, make sure it matches. + Direction = sensor.getDirection(); // Directional screen on. == DIRECTION_DISP_UP + + /* Not sure if this Wrist wake is worth the effort or the battery abuse. + if (wakeupBit & ACC_INT_MASK){ // Movement caused this. + //Serial.println("Accel int."); + if ((Direction == DIRECTION_DISP_UP) != ScreenOn){ + UpdateDisp = true; // Update Screen to new state. + } + } + */ + + if (Direction != DIRECTION_DISP_UP && Direction != DIRECTION_TOP_EDGE) return; // Don't accept it. + + switch (Pressed){ + case 1: + if (GuiMode != MENUON){ + GuiMode = MENUON; + Menu.LastItem=""; + Menu.LastHeader=""; + DoHapatic = true; + UpdateDisp = true; // Quick Update. + SetTurbo(); + }else if (GuiMode == MENUON){ + if (Menu.Item == MENU_OPTIONS && Menu.SubItem == 0){ // Options + Menu.Item = MENU_DISP; + Menu.Style = MENU_INOPTIONS; + DoHapatic = true; + UpdateDisp = true; // Quick Update. + SetTurbo(); + }else if (Menu.Item == MENU_STEPS){ // Steps + if (Menu.SubItem == 4){ + sensor.resetStepCounter(); + Menu.SubItem = 0; + DoHapatic = true; + UpdateDisp = true; // Quick Update. + SetTurbo(); + }else if (Menu.SubItem < 4){ + Menu.SubItem++; + DoHapatic = true; + UpdateDisp = true; // Quick Update. + SetTurbo(); + } + }else if (Menu.Item == MENU_ALARMS){ // Alarms menu. + Menu.Style = MENU_INALARMS; + Menu.Item = MENU_ALARM1; + DoHapatic = true; + UpdateDisp = true; + SetTurbo(); + }else if (Menu.Item >= MENU_ALARM1 && Menu.Item <= MENU_ALARM4){ // Alarms + if (Menu.SubItem < 4){ + Menu.SubItem++; + if (Menu.SubItem == 4) Menu.SubItem += WatchTime.Local.Wday; // Jump ahead to the day. + DoHapatic = true; + UpdateDisp = true; // Quick Update. + SetTurbo(); + }else if (Menu.SubItem > 3 && Menu.SubItem < 11){ + Alarms_Active[Menu.Item - MENU_ALARM1] ^= Bits[Menu.SubItem - 4]; // Toggle day. + Menu.LastItem=""; // Forces a redraw. + DoHapatic = true; + UpdateDisp = true; // Quick Update. + SetTurbo(); + }else if (Menu.SubItem == 11){ + Alarms_Active[Menu.Item - MENU_ALARM1] ^= ALARM_REPEAT; // Toggle repeat. + Menu.LastItem=""; // Forces a redraw. + DoHapatic = true; + UpdateDisp = true; // Quick Update. + SetTurbo(); + }else if (Menu.SubItem == 12){ + Alarms_Active[Menu.Item - MENU_ALARM1] ^= ALARM_ACTIVE; // Toggle Active. + Menu.LastItem=""; // Forces a redraw. + DoHapatic = true; + UpdateDisp = true; // Quick Update. + SetTurbo(); + } + }else if (Menu.Item == MENU_TIMERS){ // Timers menu. + Menu.Style = MENU_INTIMERS; + Menu.Item = MENU_TIMEDN; + DoHapatic = true; + UpdateDisp = true; + SetTurbo(); + }else if (Menu.Item == MENU_TIMEDN){ + if (Menu.SubItem == 4){ + if (TimerDown.Active){ + TimerDown.Active=false; + DoHapatic = true; + UpdateDisp = true; // Quick Update. + SetTurbo(); + }else if ((TimerDown.MaxMins + TimerDown.MaxHours) > 0){ + TimerDown.Mins = TimerDown.MaxMins; + TimerDown.Hours = TimerDown.MaxHours; + TimerDown.LastUTC = WatchTime.UTC_RAW - WatchTime.UTC.Second; + TimerDown.Active = true; + DoHapatic = true; + UpdateDisp = true; // Quick Update. + SetTurbo(); + } + }else{ + Menu.SubItem++; + if (TimerDown.MaxMins + TimerDown.MaxHours == 0 && Menu.SubItem == 4) Menu.SubItem = 3; //Stop it from being startable. + if (TimerDown.Active) Menu.SubItem = 4; + DoHapatic = true; + UpdateDisp = true; // Quick Update. + SetTurbo(); + } + }else if (Menu.Item == MENU_TIMEUP){ + if (Menu.SubItem == 0){ + Menu.SubItem = 1; + DoHapatic = true; + UpdateDisp = true; // Quick Update. + SetTurbo(); + }else{ + if (TimerUp.Active){ + TimerUp.StopAt = WatchTime.UTC_RAW - WatchTime.UTC.Second; + TimerUp.Active = false; + }else{ + TimerUp.SetAt = WatchTime.UTC_RAW - WatchTime.UTC.Second; + TimerUp.StopAt = TimerUp.SetAt; + TimerUp.Active = true; + } + DoHapatic = true; + UpdateDisp = true; // Quick Update. + SetTurbo(); + } + }else if (Menu.Item == MENU_SYNC){ // Sync Time + if (Menu.SubItem == 0){ + Menu.SubItem++; + DoHapatic = true; + UpdateDisp = true; // Quick Update. + SetTurbo(); + }else{ + NTPData.State = 1; + switch (Menu.SubItem){ + case 1: + NTPData.UpdateUTC = true; + NTPData.TimeZone = false; + break; + case 2: + NTPData.UpdateUTC = false; + NTPData.TimeZone = true; + break; + case 3: + NTPData.TimeZone = true; + NTPData.UpdateUTC = true; + } + NTPData.TimeZone = (WatchTime.POSIX[0] == 0); // No Timezone, go get one! + GuiMode = WATCHON; + WatchTime.LastDay=""; + WatchTime.LastDate=""; + Menu.Item = MENU_STEPS; + Menu.SubItem = 0; + DoHapatic = true; + UpdateDisp = true; // Quick Update. + SetTurbo(); + } + }else if (Menu.Item == MENU_DISP){ // Switch Mode + Options.LiteMode = !Options.LiteMode; + Menu.LastItem=""; // Forces a redraw. + Updates.Full = true; + DoHapatic = true; + UpdateDisp = true; // Quick Update. + SetTurbo(); + }else if (Menu.Item == MENU_SIDE){ // Dexterity Mode + Options.Lefty = !Options.Lefty; + Menu.LastItem=""; // Forces a redraw. + DoHapatic = true; + UpdateDisp = true; // Quick Update. + SetTurbo(); + }else if (Menu.Item == MENU_SWAP){ // Swap Menu/Back Buttons + Options.Swapped = !Options.Swapped; + Menu.LastItem=""; // Forces a redraw. + DoHapatic = true; + UpdateDisp = true; // Quick Update. + SetTurbo(); + }else if (Menu.Item == MENU_BRDR){ // Border Mode + Options.Border = !Options.Border; + Menu.LastItem=""; // Forces a redraw. + display.init(0,false); // Force it here so it fixes the border. + DoHapatic = true; + UpdateDisp = true; // Quick Update. + SetTurbo(); + }else if (Menu.Item == MENU_MODE){ // Switch Time Mode + Options.TwentyFour = !Options.TwentyFour; + Menu.LastItem=""; // Forces a redraw. + DoHapatic = true; + UpdateDisp = true; // Quick Update. + SetTurbo(); + }else if (Menu.Item == MENU_FEED){ // Feedback. + Options.Feedback = !Options.Feedback; + Menu.LastItem=""; // Forces a redraw. + DoHapatic = true; + UpdateDisp = true; // Quick Update. + SetTurbo(); + }else if (Menu.Item == MENU_TRBO){ // Turbo + Options.Turbo = roller(Options.Turbo + 1, 0, 10); + DoHapatic = true; + UpdateDisp = true; // Quick Update. + SetTurbo(); + }else if (Menu.Item == MENU_SCRN){ // Reset Screen + GuiMode = WATCHON; + WatchTime.LastDay=""; + WatchTime.LastDate=""; + DoHapatic = true; + UpdateDisp = true; // Quick Update. + Updates.Full = true; + SetTurbo(); + }else if (Menu.Item == MENU_WIFI){ // Watchy Connect + Menu.SubItem++; + WatchyAPOn = true; + DoHapatic = true; + UpdateDisp = true; // Quick Update. + SetTurbo(); + }else if (Menu.Item == MENU_OTAU || Menu.Item == MENU_OTAM){ // Watchy OTA + Menu.SubItem++; + OTAUpdate=true; + DoHapatic = true; + UpdateDisp = true; // Quick Update. + SetTurbo(); + }else if (Menu.Item == MENU_RSET){ // Watchy Reboot + ESP.restart(); + } + } + break; + case 2: + if (GuiMode == MENUON){ // Back Button [SW2] + if (Menu.Item == MENU_STEPS && Menu.SubItem > 0) { // Exit for Steps, back to Steps. + if (Menu.SubItem == 4) Menu.SubItem = 2; // Go back to the Hour, so it is the same as the alarms. + Menu.SubItem--; + DoHapatic = true; + UpdateDisp = true; // Quick Update. + SetTurbo(); + }else if (Menu.Item >= MENU_ALARM1 && Menu.Item <= MENU_ALARM4 && Menu.SubItem > 0){ + if (Menu.SubItem < 4 && Menu.SubItem > 0){ + Menu.SubItem--; + }else if (Menu.SubItem > 3){ + Menu.SubItem = 1; + } + DoHapatic = true; + UpdateDisp = true; // Quick Update. + SetTurbo(); + }else if (Menu.Item == MENU_TIMEDN && Menu.SubItem > 0){ + Menu.SubItem--; + if (TimerDown.Active) Menu.SubItem = 0; + DoHapatic = true; + UpdateDisp = true; // Quick Update. + SetTurbo(); + }else if (Menu.Item == MENU_TIMEUP && Menu.SubItem > 0){ + Menu.SubItem = 0; + DoHapatic = true; + UpdateDisp = true; // Quick Update. + SetTurbo(); + }else if (Menu.Item == MENU_SYNC && Menu.SubItem > 0){ + Menu.SubItem = 0; + DoHapatic = true; + UpdateDisp = true; // Quick Update. + SetTurbo(); + }else if (Menu.Item == MENU_WIFI && Menu.SubItem > 0){ + Menu.SubItem = 0; + DoHapatic = true; + UpdateDisp = true; // Quick Update. + SetTurbo(); + }else if ((Menu.Item == MENU_OTAU || Menu.Item == MENU_OTAM) && Menu.SubItem > 0){ + break; // DO NOTHING! + }else if (Menu.Style == MENU_INALARMS){ // Alarms + Menu.Style = MENU_INNORMAL; + Menu.Item = MENU_ALARMS; + DoHapatic = true; + UpdateDisp = true; + SetTurbo(); + }else if (Menu.Style == MENU_INTIMERS){ // Timers + Menu.Style = MENU_INNORMAL; + Menu.Item = MENU_TIMERS; + DoHapatic = true; + UpdateDisp = true; + SetTurbo(); + }else if (Menu.Style == MENU_INOPTIONS){ // Options + Menu.SubItem = 0; + Menu.SubSubItem = 0; + Menu.Item=MENU_OPTIONS; + Menu.Style=MENU_INNORMAL; + DoHapatic = true; + UpdateDisp = true; // Quick Update. + SetTurbo(); + }else{ + GuiMode = WATCHON; + WatchTime.LastDay=""; + WatchTime.LastDate=""; + Menu.SubItem = 0; + Menu.SubSubItem = 0; + DoHapatic = true; + UpdateDisp = true; // Quick Update. + SetTurbo(); + } + } + break; + case 3: + if (GuiMode == MENUON){ // Up Button [SW3] + // Handle the sideways choices here. + if (Menu.Item == MENU_STEPS && Menu.SubItem > 0){ + switch (Menu.SubItem){ + case 1: // Hour + Steps.Hour=roller(Steps.Hour + 1, 0,23); + Steps.Reset = false; + DoHapatic = true; + UpdateDisp = true; // Quick Update. + SetTurbo(); + break; + case 2: // x0 Minutes + mh = (Steps.Minutes / 10); + ml = Steps.Minutes - (mh * 10); + mh = roller(mh + 1, 0, 5); + Steps.Minutes = (mh * 10) + ml; + Steps.Reset = false; + DoHapatic = true; + UpdateDisp = true; // Quick Update. + SetTurbo(); + break; + case 3: // x0 Minutes + mh = (Steps.Minutes / 10); + ml = Steps.Minutes - (mh * 10); + ml = roller(ml + 1, 0, 9); + Steps.Minutes = (mh * 10) + ml; + Steps.Reset = false; + DoHapatic = true; + UpdateDisp = true; // Quick Update. + SetTurbo(); + } + }else if (Menu.Item >= MENU_ALARM1 && Menu.Item <= MENU_ALARM4 && Menu.SubItem > 0){ + if (Menu.SubItem == 1){ // Hour + Alarms_Hour[Menu.Item - MENU_ALARM1]=roller(Alarms_Hour[Menu.Item - MENU_ALARM1] + 1, 0,23); + Alarms_Active[Menu.Item - MENU_ALARM1] &= ALARM_NOTRIGGER; + DoHapatic = true; + UpdateDisp = true; // Quick Update. + SetTurbo(); + }else if (Menu.SubItem == 2){ // x0 Minutes + mh = (Alarms_Minutes[Menu.Item - MENU_ALARM1] / 10); + ml = Alarms_Minutes[Menu.Item - MENU_ALARM1] - (mh * 10); + mh = roller(mh + 1, 0, 5); + Alarms_Minutes[Menu.Item - MENU_ALARM1] = (mh * 10) + ml; + Alarms_Active[Menu.Item - MENU_ALARM1] &= ALARM_NOTRIGGER; + DoHapatic = true; + UpdateDisp = true; // Quick Update. + SetTurbo(); + }else if (Menu.SubItem == 3){ // x0 Minutes + mh = (Alarms_Minutes[Menu.Item - MENU_ALARM1] / 10); + ml = Alarms_Minutes[Menu.Item - MENU_ALARM1] - (mh * 10); + ml = roller(ml + 1, 0, 9); + Alarms_Minutes[Menu.Item - MENU_ALARM1] = (mh * 10) + ml; + Alarms_Active[Menu.Item - MENU_ALARM1] &= ALARM_NOTRIGGER; + DoHapatic = true; + UpdateDisp = true; // Quick Update. + SetTurbo(); + }else if (Menu.SubItem > 3){ + Menu.SubItem = roller(Menu.SubItem + 1, 4, 12); + DoHapatic = true; + UpdateDisp = true; // Quick Update. + SetTurbo(); + } + } else if (Menu.Item == MENU_TIMEDN && Menu.SubItem > 0){ + switch (Menu.SubItem){ + case 1: // Hour + TimerDown.MaxHours=roller(TimerDown.MaxHours + 1, 0,23); + StopCD(); + DoHapatic = true; + UpdateDisp = true; // Quick Update. + SetTurbo(); + break; + case 2: // x0 Minutes + mh = (TimerDown.MaxMins / 10); + ml = TimerDown.MaxMins - (mh * 10); + mh = roller(mh + 1, 0, 5); + TimerDown.MaxMins = (mh * 10) + ml; + StopCD(); + DoHapatic = true; + UpdateDisp = true; // Quick Update. + SetTurbo(); + break; + case 3: // x0 Minutes + mh = (TimerDown.MaxMins / 10); + ml = TimerDown.MaxMins - (mh * 10); + ml = roller(ml + 1, 0, 9); + TimerDown.MaxMins = (mh * 10) + ml; + StopCD(); + DoHapatic = true; + UpdateDisp = true; // Quick Update. + SetTurbo(); + } + }else if (Menu.Item == MENU_SYNC && Menu.SubItem > 0){ + Menu.SubItem = roller(Menu.SubItem - 1, 1, 3); + DoHapatic = true; + UpdateDisp = true; // Quick Update. + SetTurbo(); + }else if (Menu.Item == MENU_WIFI && Menu.SubItem > 0){ + // Do nothing! + }else{ + if (Menu.Style == MENU_INOPTIONS){ + Menu.Item = roller(Menu.Item - 1, MENU_DISP, (NTPData.State > 0 || WatchyAPOn || OTAUpdate || getBatteryVoltage() < MinBattery) ? MENU_SCRN : MENU_RSET); + }else if (Menu.Style == MENU_INALARMS){ + Menu.Item = roller(Menu.Item - 1, MENU_ALARM1, MENU_ALARM4); + }else if (Menu.Style == MENU_INTIMERS){ + Menu.Item = roller(Menu.Item - 1, MENU_TIMEDN, MENU_TIMEUP); + }else{ + Menu.Item = roller(Menu.Item - 1, MENU_STEPS, MENU_OPTIONS); + } + Menu.SubItem=0; + Menu.SubSubItem=0; + DoHapatic = true; + UpdateDisp = true; // Quick Update. + SetTurbo(); + } + } + break; + case 4: + if (GuiMode == MENUON){ // Down Button [SW4] + // Handle the sideways choices here. + if (Menu.Item == MENU_STEPS && Menu.SubItem > 0){ + switch (Menu.SubItem){ + case 1: // Hour + Steps.Hour=roller(Steps.Hour - 1, 0,23); + Steps.Reset = false; + DoHapatic = true; + UpdateDisp = true; // Quick Update. + SetTurbo(); + break; + case 2: // x0 Minutes + mh = (Steps.Minutes / 10); + ml = Steps.Minutes - (mh * 10); + mh = roller(mh - 1, 0, 5); + Steps.Minutes = (mh * 10) + ml; + Steps.Reset = false; + DoHapatic = true; + UpdateDisp = true; // Quick Update. + SetTurbo(); + break; + case 3: // x0 Minutes + mh = (Steps.Minutes / 10); + ml = Steps.Minutes - (mh * 10); + ml = roller(ml - 1, 0, 9); + Steps.Minutes = (mh * 10) + ml; + Steps.Reset = false; + DoHapatic = true; + UpdateDisp = true; // Quick Update. + SetTurbo(); + } + }else if (Menu.Item >= MENU_ALARM1 && Menu.Item <= MENU_ALARM4 && Menu.SubItem > 0){ + if (Menu.SubItem == 1){ // Hour + Alarms_Hour[Menu.Item - MENU_ALARM1]=roller(Alarms_Hour[Menu.Item - MENU_ALARM1] - 1, 0,23); + Alarms_Active[Menu.Item - MENU_ALARM1] &= ALARM_NOTRIGGER; + DoHapatic = true; + UpdateDisp = true; // Quick Update. + SetTurbo(); + }else if (Menu.SubItem == 2){ // x0 Minutes + mh = (Alarms_Minutes[Menu.Item - MENU_ALARM1] / 10); + ml = Alarms_Minutes[Menu.Item - MENU_ALARM1] - (mh * 10); + mh = roller(mh - 1, 0, 5); + Alarms_Minutes[Menu.Item - MENU_ALARM1] = (mh * 10) + ml; + Alarms_Active[Menu.Item - MENU_ALARM1] &= ALARM_NOTRIGGER; + DoHapatic = true; + UpdateDisp = true; // Quick Update. + SetTurbo(); + }else if (Menu.SubItem == 3){ // x0 Minutes + mh = (Alarms_Minutes[Menu.Item - MENU_ALARM1] / 10); + ml = Alarms_Minutes[Menu.Item - MENU_ALARM1] - (mh * 10); + ml = roller(ml - 1, 0, 9); + Alarms_Minutes[Menu.Item - MENU_ALARM1] = (mh * 10) + ml; + Alarms_Active[Menu.Item - MENU_ALARM1] &= ALARM_NOTRIGGER; + DoHapatic = true; + UpdateDisp = true; // Quick Update. + SetTurbo(); + }else if (Menu.SubItem > 3){ + Menu.SubItem = roller(Menu.SubItem - 1, 4, 12); + DoHapatic = true; + UpdateDisp = true; // Quick Update. + SetTurbo(); + } + } else if (Menu.Item == MENU_TIMEDN && Menu.SubItem > 0){ + switch (Menu.SubItem){ + case 1: // Hour + TimerDown.MaxHours=roller(TimerDown.MaxHours - 1, 0,23); + StopCD(); + DoHapatic = true; + UpdateDisp = true; // Quick Update. + SetTurbo(); + break; + case 2: // x0 Minutes + mh = (TimerDown.MaxMins / 10); + ml = TimerDown.MaxMins - (mh * 10); + mh = roller(mh - 1, 0, 5); + TimerDown.MaxMins = (mh * 10) + ml; + StopCD(); + DoHapatic = true; + UpdateDisp = true; // Quick Update. + SetTurbo(); + break; + case 3: // x0 Minutes + mh = (TimerDown.MaxMins / 10); + ml = TimerDown.MaxMins - (mh * 10); + ml = roller(ml - 1, 0, 9); + TimerDown.MaxMins = (mh * 10) + ml; + StopCD(); + DoHapatic = true; + UpdateDisp = true; // Quick Update. + SetTurbo(); + } + }else if (Menu.Item == MENU_SYNC && Menu.SubItem > 0){ + Menu.SubItem = roller(Menu.SubItem + 1, 1, 3); + DoHapatic = true; + UpdateDisp = true; // Quick Update. + SetTurbo(); + }else if (Menu.Item == MENU_WIFI && Menu.SubItem > 0){ + // Do nothing! + }else{ + if (Menu.Style == MENU_INOPTIONS){ + Menu.Item = roller(Menu.Item + 1, MENU_DISP, (NTPData.State > 0 || WatchyAPOn || OTAUpdate || getBatteryVoltage() < MinBattery) ? MENU_SCRN : MENU_RSET); + }else if (Menu.Style == MENU_INALARMS){ + Menu.Item = roller(Menu.Item + 1, MENU_ALARM1, MENU_ALARM4); + }else if (Menu.Style == MENU_INTIMERS){ + Menu.Item = roller(Menu.Item + 1, MENU_TIMEDN, MENU_TIMEUP); + }else{ + Menu.Item = roller(Menu.Item + 1, MENU_STEPS, MENU_OPTIONS); + } + Menu.SubItem=0; + Menu.SubSubItem=0; + DoHapatic = true; + UpdateDisp = true; // Quick Update. + SetTurbo(); + } + } + } +} + +void Watchy::UpdateUTC(){ + tmElements_t TM; // struct tm * tm; + RTC.read(TM); + WatchTime.UTC = TM; + WatchTime.UTC_RAW = makeTime(TM); +} + +void Watchy::UpdateClock(){ + struct tm * tm; + setenv("TZ",WatchTime.POSIX,1); + tzset(); + tm = localtime(&WatchTime.UTC_RAW); + WatchTime.Local.Second = tm->tm_sec; + WatchTime.Local.Minute = tm->tm_min; + WatchTime.Local.Hour = tm->tm_hour; + WatchTime.Local.Wday = tm->tm_wday; + WatchTime.Local.Day = tm->tm_mday; + WatchTime.Local.Month = tm->tm_mon + 1; + WatchTime.Local.Year = tm->tm_year; +} + +void Watchy::_rtcConfig() { + tmElements_t TM; + //https://github.com/JChristensen/DS3232RTC + RTC.squareWave(SQWAVE_NONE); //disable square wave output + //RTC.set(compileTime()); //set RTC time to compile time + RTC.setAlarm(ALM2_EVERY_MINUTE, 0, 0, 0, 0); //alarm wakes up Watchy every minute + RTC.alarmInterrupt(ALARM_2, true); //enable alarm interrupt + RTC.read(TM); +} + +void Watchy::_bmaConfig() { + + if (sensor.begin(_readRegister, _writeRegister, delay) == false) { + //fail to init BMA + return; + } + + // Accel parameter structure + Acfg cfg; + /*! + Output data rate in Hz, Optional parameters: + - BMA4_OUTPUT_DATA_RATE_0_78HZ + - BMA4_OUTPUT_DATA_RATE_1_56HZ + - BMA4_OUTPUT_DATA_RATE_3_12HZ + - BMA4_OUTPUT_DATA_RATE_6_25HZ + - BMA4_OUTPUT_DATA_RATE_12_5HZ + - BMA4_OUTPUT_DATA_RATE_25HZ + - BMA4_OUTPUT_DATA_RATE_50HZ + - BMA4_OUTPUT_DATA_RATE_100HZ + - BMA4_OUTPUT_DATA_RATE_200HZ + - BMA4_OUTPUT_DATA_RATE_400HZ + - BMA4_OUTPUT_DATA_RATE_800HZ + - BMA4_OUTPUT_DATA_RATE_1600HZ + */ + cfg.odr = BMA4_OUTPUT_DATA_RATE_100HZ; + /*! + G-range, Optional parameters: + - BMA4_ACCEL_RANGE_2G + - BMA4_ACCEL_RANGE_4G + - BMA4_ACCEL_RANGE_8G + - BMA4_ACCEL_RANGE_16G + */ + cfg.range = BMA4_ACCEL_RANGE_2G; + /*! + Bandwidth parameter, determines filter configuration, Optional parameters: + - BMA4_ACCEL_OSR4_AVG1 + - BMA4_ACCEL_OSR2_AVG2 + - BMA4_ACCEL_NORMAL_AVG4 + - BMA4_ACCEL_CIC_AVG8 + - BMA4_ACCEL_RES_AVG16 + - BMA4_ACCEL_RES_AVG32 + - BMA4_ACCEL_RES_AVG64 + - BMA4_ACCEL_RES_AVG128 + */ + cfg.bandwidth = BMA4_ACCEL_NORMAL_AVG4; + + /*! Filter performance mode , Optional parameters: + - BMA4_CIC_AVG_MODE + - BMA4_CONTINUOUS_MODE + */ + cfg.perf_mode = BMA4_CONTINUOUS_MODE; + + // Configure the BMA423 accelerometer + sensor.setAccelConfig(cfg); + + // Enable BMA423 accelerometer + // Warning : Need to use feature, you must first enable the accelerometer + sensor.enableAccel(); + + struct bma4_int_pin_config config ; + config.edge_ctrl = BMA4_LEVEL_TRIGGER; + config.lvl = BMA4_ACTIVE_HIGH; + config.od = BMA4_PUSH_PULL; + config.output_en = BMA4_OUTPUT_ENABLE; + config.input_en = BMA4_INPUT_DISABLE; + // The correct trigger interrupt needs to be configured as needed + sensor.setINTPinConfig(config, BMA4_INTR1_MAP); + + struct bma423_axes_remap remap_data; + remap_data.x_axis = 1; + remap_data.x_axis_sign = 0xFF; + remap_data.y_axis = 0; + remap_data.y_axis_sign = 0xFF; + remap_data.z_axis = 2; + remap_data.z_axis_sign = 0xFF; + // Need to raise the wrist function, need to set the correct axis + sensor.setRemapAxes(&remap_data); + + // Enable BMA423 isStepCounter feature + sensor.enableFeature(BMA423_STEP_CNTR, true); + // Enable BMA423 isTilt feature + //sensor.enableFeature(BMA423_TILT, true); + // Enable BMA423 isDoubleClick feature + //sensor.enableFeature(BMA423_WAKEUP, true); + + // Reset steps + //sensor.resetStepCounter(); + + // Turn on feature interrupt + //sensor.enableStepCountInterrupt(); + //sensor.enableTiltInterrupt(); + // It corresponds to isDoubleClick interrupt + //sensor.enableWakeupInterrupt(); +} + +float Watchy::getBatteryVoltage(){ + float A, B, C, D; + A = analogRead(ADC_PIN) - 0.0125; + B = analogRead(ADC_PIN) - 0.0125; + C = analogRead(ADC_PIN) - 0.0125; + D = analogRead(ADC_PIN) - 0.0125; + return (((A + B + C + D) / 16384.0) * 7.23); +} + +uint16_t Watchy::_readRegister(uint8_t address, uint8_t reg, uint8_t *data, uint16_t len) { + Wire.beginTransmission(address); + Wire.write(reg); + Wire.endTransmission(); + Wire.requestFrom((uint8_t)address, (uint8_t)len); + uint8_t i = 0; + while (Wire.available()) { + data[i++] = Wire.read(); + } + return 0; +} + +uint16_t Watchy::_writeRegister(uint8_t address, uint8_t reg, uint8_t *data, uint16_t len) { + Wire.beginTransmission(address); + Wire.write(reg); + Wire.write(data, len); + return (0 != Wire.endTransmission()); +} + +String Watchy::MakeTime(int Hour, int Minutes, bool& Alarm) { // Use variable with Alarm, if set to False on the way in, returns PM indication. + int H; + String AP; + H = Hour; + if (!Options.TwentyFour){ + if (H > 11){ + AP = " PM"; + if (!Alarm){ + Alarm = true; // Tell the clock to use the PM indicator. + } + }else{ + AP = " AM"; + } + if (H > 12){ + H -= 12; + }else if (H == 0){ + H = 12; + } + } + return String(H) + (Minutes < 10 ? ":0" : ":") + String(Minutes) + (!Options.TwentyFour ? AP : ""); +} + +String Watchy::MakeHour(uint8_t Hour){ + int H; + H = Hour; + if (!Options.TwentyFour){ + if (H > 12){ + H -= 12; + } + if (H == 0){ + H = 12; + } + } + return String(H); +} + +String Watchy::MakeMinutes(uint8_t Minutes){ + return (Minutes < 10 ? "0" : "") + String(Minutes); +} + +String Watchy::MakeSteps(uint32_t uSteps){ + String S, T, X; + int I, C; + + S = String(uSteps); + I = S.length(); + C = 0; T = ""; + + while (I > 0){ + X = (I > 1 && C == 2) ? "," : ""; + T = X + S.charAt(I - 1) + T; + C = roller(C + 1, 0, 2); I--; + } + return T; +} + +void Watchy::CheckAlarm(int I){ + uint16_t B; + bool bA; + B = (ALARM_ACTIVE | Bits[WatchTime.Local.Wday]); + bA = (Alarms_Hour[I] == WatchTime.Local.Hour && Alarms_Minutes[I] == WatchTime.Local.Minute); + if (!bA && Alarms_Times[I] == 0 && (Alarms_Active[I] & ALARM_TRIGGERED) != 0){ + Alarms_Active[I] &= ALARM_NOTRIGGER; + }else if ((Alarms_Active[I] & B) == B){ // Active and Active Day. + if (bA && Alarms_Times[I] == 0 && (Alarms_Active[I] & ALARM_TRIGGERED) == 0){ + Alarms_Times[I] = 255; + Alarms_Playing[I] = 30; + Alarms_Active[I] |= ALARM_TRIGGERED; + if ((Alarms_Active[I] & ALARM_REPEAT) == 0){ + Alarms_Active[I] &= (ALARM_ALL - Bits[WatchTime.Local.Wday]); + if ((Alarms_Active[I] & ALARM_DAYS) == 0){ + Alarms_Active[I] ^= ALARM_ACTIVE; // Turn it off, not repeating. + } + } + } + } +} + +void Watchy::CheckCD(){ + uint16_t M = ((WatchTime.UTC_RAW - TimerDown.LastUTC) / 60); + uint16_t E; + + if ( M > 0){ + TimerDown.LastUTC = WatchTime.UTC_RAW; + E = TimerDown.Mins + (TimerDown.Hours * 60) - M; + TimerDown.Hours = (E / 60); + TimerDown.Mins = E - (TimerDown.Hours * 60); + } + if (TimerDown.Hours == 0 && TimerDown.Mins == 0 && TimerDown.Active){ + TimerDown.Tone = 24; + TimerDown.ToneLeft = 255; + TimerDown.Active = false; + UpdateDisp = true; // Quick Update. + } +} + +// Counts the active (255) alarms/timers and after 3, sets them to lower values. +void Watchy::CalculateTones(){ + uint8_t Count; + CheckAlarm(0); CheckAlarm(1); CheckAlarm(2); CheckAlarm(3); CheckCD(); + if (Alarms_Times[0] > 0) Count++; + if (Alarms_Times[1] > 0) Count++; + if (Alarms_Times[2] > 0) Count++; + if (Alarms_Times[3] > 0) Count++; + if (TimerDown.ToneLeft > 0) Count++; + if (Count == 5){ + if (Alarms_Times[0] == 255) Alarms_Times[0] = 7; + if (Alarms_Times[1] == 255) Alarms_Times[1] = 7; + if (Alarms_Times[2] == 255) Alarms_Times[2] = 7; + if (Alarms_Times[3] == 255) Alarms_Times[3] = 7; + if (TimerDown.ToneLeft == 255) TimerDown.ToneLeft = 10; + }else if (Count == 4){ + if (Alarms_Times[0] == 255) Alarms_Times[0] = 8; + if (Alarms_Times[1] == 255) Alarms_Times[1] = 8; + if (Alarms_Times[2] == 255) Alarms_Times[2] = 8; + if (Alarms_Times[3] == 255) Alarms_Times[3] = 8; + if (TimerDown.ToneLeft == 255) TimerDown.ToneLeft = 12; + }else{ + if (Alarms_Times[0] == 255) Alarms_Times[0] = 10; + if (Alarms_Times[1] == 255) Alarms_Times[1] = 10; + if (Alarms_Times[2] == 255) Alarms_Times[2] = 10; + if (Alarms_Times[3] == 255) Alarms_Times[3] = 10; + if (TimerDown.ToneLeft == 255) TimerDown.ToneLeft = 15; + } +} + +void Watchy::StopCD(){ + if (TimerDown.ToneLeft > 0){ + TimerDown.ToneLeft = 1; + TimerDown.Tone = 1; + } +} + +uint8_t Watchy::getToneTimes(uint8_t ToneIndex){ + if (ToneIndex > 3) return TimerDown.ToneLeft; + return Alarms_Times[ToneIndex]; +} + +// Catches Steps and moves "Yesterday" into the other setting. +void Watchy::monitorSteps(){ + if (Steps.Hour == WatchTime.Local.Hour && Steps.Minutes == WatchTime.Local.Minute){ + if (!Steps.Reset){ + Steps.Yesterday=sensor.getCounter(); + sensor.resetStepCounter(); + Steps.Reset=true; + } + }else if (Steps.Reset) Steps.Reset=false; +} + +/* +String Watchy::GetStoredTimezone(){ + esp_err_t err = nvs_flash_init(); + if (err == ESP_ERR_NVS_NO_FREE_PAGES) { + // NVS partition was truncated and needs to be erased + // Retry nvs_flash_init + ESP_ERROR_CHECK(nvs_flash_erase()); + err = nvs_flash_init(); + } + ESP_ERROR_CHECK( err ); + if (nvs_open("Clock",NVS_READWRITE,hNVS) == ESP_OK){ + size_t S; + nvs_get_str(hNVS, "TimeZone", NULL, &S); + if (S > 0){ + char* TZ = malloc(S); + nvs_get_str(hNVS, "TimeZone", TZ, &S); + nvs_close(hNVS); + return TZ; + } + nvs_close(hNVS); + } + return TZMISSING; +} + +bool Watchy::StoreTimezone(String Timezone){ + bool B; + esp_err_t err = nvs_flash_init(); + if (err == ESP_ERR_NVS_NO_FREE_PAGES) { + // NVS partition was truncated and needs to be erased + // Retry nvs_flash_init + ESP_ERROR_CHECK(nvs_flash_erase()); + err = nvs_flash_init(); + } + ESP_ERROR_CHECK( err ); + if (nvs_open("Clock",NVS_READWRITE,hNVS) == ESP_OK){ + B = (nvs_set_str(hNVS,"TimeZone",Timezone) == ESP_OK); + if (B){ + nvs_commit(hNVS); + } + nvs_close(hNVS); + }else{ + return false; + } +} +*/ + +IRAM_ATTR void Watchy::handleInterrupt(){ + uint8_t B = getButtonPins(); + if (B > 0 && (millis() - LastButton) > KEYPAUSE) { Button = B; LastButton = millis(); } +} + +IRAM_ATTR uint8_t Watchy::getButtonPins(){ + bool SW1 = (digitalRead(MENU_BTN_PIN) == 1); + bool SW2 = (digitalRead(BACK_BTN_PIN) == 1); + bool SW3 = (digitalRead(UP_BTN_PIN) == 1); + bool SW4 = (digitalRead(DOWN_BTN_PIN) == 1); + + if (SW1) return Options.Lefty ? 4 : getSwapped(1); + else if (SW2) return Options.Lefty ? 3 : getSwapped(2); + else if (SW3) return Options.Lefty ? getSwapped(2) : 3; + else if (SW4) return Options.Lefty ? getSwapped(1) : 4; + return 0; +} + +uint8_t Watchy::getButtonMaskToID(uint64_t HW){ + if (HW & MENU_BTN_MASK) return Options.Lefty ? 4 : getSwapped(1); // Menu Button [SW1] + else if (HW & BACK_BTN_MASK) return Options.Lefty ? 3 : getSwapped(2); // Back Button [SW2] + else if (HW & UP_BTN_MASK) return Options.Lefty ? getSwapped(2) : 3; // Up Button [SW3] + else if (HW & DOWN_BTN_MASK) return Options.Lefty ? getSwapped(1) : 4; // Down Button [SW4] + return 0; +} + +IRAM_ATTR uint8_t Watchy::getSwapped(uint8_t pIn){ + switch (pIn){ + case 1: + return Options.Swapped ? 2 : 1; + case 2: + return Options.Swapped ? 1 : 2; + } +} + +void Watchy::ScreenRefresh(){ + uint16_t XL, YL, XH, YH; + bool DoIt; + + XL = 200; YL = 200; XH = 0; YH = 0; + + if (!Updates.Full){ + DoIt = false; + if (Updates.Time) { XL = 0; YL = TimeY - 45; XH = 200; YH = TimeY; DoIt = true; } + if (Updates.Day) { XL = 0; YL = golow(DayY - 16, YL); XH = 200; YH = gobig(DayY, YH); DoIt = true; } + if (Updates.Date) { XL = 0; YL = golow(DateY - 16,YL); XH = 200; YH = gobig(DateY, YH); DoIt = true; } + if (Updates.Header) { XL = 0; YL = golow(MenuTop, YL); XH = 200; YH = gobig(MenuTop + (MenuHeight / 2), YH); DoIt = true; } + if (Updates.Item) { XL = 0; YL = golow(MenuTop + (MenuHeight / 2), YL); XH = 200; YH = gobig(MenuTop + (MenuHeight / 2), YH); DoIt = true; } + if (Updates.Status) { XL = golow(NTPX, XL); YL = golow(NTPY - 19, YL); XH = gobig(60, XH); YH = gobig(NTPY, YH); DoIt = true; } + if (Updates.Year) { XL = 0; YL = golow(YearY - 17, YL); XH = gobig(154, XH); YH = gobig(YearY, YH); DoIt = true; } + if (Updates.Charge) { XL = golow(155, XL); YL = golow(178, YL); XH = gobig(196, XH); YH = gobig(196, YH); DoIt = true; } + }else{ XL = 0; YL = 0; XH = 200; YH = 200; DoIt = true; } + if (DoIt){ + if(Updates.Full) display.setFullWindow(); else display.setFullWindow(); //init moved, can't do this: display.setPartialWindow(XL, YL, XH - XL, YH - YL); + display.display(!Updates.Full); //partial refresh + } + Updates.Time=false; + Updates.Day=false; + Updates.Date=false; + Updates.Header=false; + Updates.Item=false; + Updates.Status=false; + Updates.Year=false; + Updates.Charge=false; + Updates.Full=false; +} + +void Watchy::initZeros(){ + GuiMode = WATCHON; + ScreenOn = true; + VibeMode = 0; + WatchyStatus = ""; + WatchTime.TimeZone = ""; + Menu.Style = MENU_INNORMAL; + Menu.Item = 0; + Menu.SubItem = 0; + Menu.SubSubItem = 0; + NTPData.Pause = 0; + NTPData.Wait = 0; + Battery.Last = getBatteryVoltage() + 1; // Done for power spike after reboot from making the watch think it's charging. + Battery.UpCount = 0; + Battery.DownCount = 0; + ActiveMode = false; + OTATry = 0; + OTAEnd = false; + OTAUpdate = false; + OTATimer = millis(); + WatchyAPOn = false; + DoHapatic = false; + Steps.Reset=false; + Alarms_Active[1]=0; + Alarms_Active[2]=0; + Alarms_Active[3]=0; + Alarms_Active[4]=0; + Alarms_Times[1]=0; + Alarms_Times[2]=0; + Alarms_Times[3]=0; + Alarms_Times[4]=0; + Alarms_Playing[1]=0; + Alarms_Playing[2]=0; + Alarms_Playing[3]=0; + Alarms_Playing[4]=0; + NTPData.TimeZone=true; + NTPData.UpdateUTC=true; + NTPData.State=1; + TimerUp.SetAt = WatchTime.UTC_RAW; + TimerUp.StopAt = TimerUp.SetAt; + TimerDown.MaxMins = 0; + TimerDown.MaxHours = 0; + TimerDown.Mins = 0; + TimerDown.Hours = 0; + TimerDown.Active = false; +} + +// Settings Storage & Retrieval here. + +String Watchy::GetSettings(){ + unsigned char I[96]; + unsigned char O[96]; + int K = 0; + int J = 6; + uint16_t V; + String S; + size_t L; + + // Retrieve the settings from the current state into a base64 string. + + I[0] = (Steps.Hour); + I[1] = (Steps.Minutes); + K = Options.TwentyFour ? 1 : 0; + K |= Options.LiteMode ? 2 : 0; + K |= Options.Feedback ? 4 : 0; + K |= Options.Border ? 8 : 0; + K |= Options.Lefty ? 16 : 0; + K |= Options.Swapped ? 32 : 0; + I[2] = (K); I[3] = Options.Turbo; + + I[4] = (TimerDown.MaxHours); + I[5] = (TimerDown.MaxMins); + + for (K = 0; K < 4; K++){ + I[J] = (Alarms_Hour[K]); J++; + I[J] = (Alarms_Minutes[K]); J++; + V = (Alarms_Active[K] & ALARM_NOTRIGGER); + I[J] = (V & 255); J++; + I[J] = ((V >> 8) & 255); J++; + } + I[J] = 0; J++; + + mbedtls_base64_encode(&O[0], 96, &L, &I[0], J); + + O[L]=0; + S = reinterpret_cast(O); + return S; +} + +void Watchy::StoreSettings(String FromUser){ + unsigned char O[96], E[96]; + int K = 0; + int J = 0; + uint16_t V; + size_t L; + + J = FromUser.length(); for (K = 0; K < J; K++) E[K] = FromUser.charAt(K); + + mbedtls_base64_decode(&O[0], 96, &L, &E[0], J); L--; // Take dead zero off end. + + J = 0; if (L > J) Steps.Hour = clamp(O[J],0,23); + J++; if (L > J) Steps.Minutes = clamp(O[J],0,59); + J++; + if (L > J) { + V = O[J]; + Options.TwentyFour = (V & 1) ? true : false; + Options.LiteMode = (V & 2) ? true : false; + Options.Feedback = (V & 4) ? true : false; + Options.Border = (V & 8) ? true : false; + Options.Lefty = (V & 16) ? true : false; + Options.Swapped = (V & 32) ? true : false; + } + J++; if (L > J) Options.Turbo = clamp(O[J],0,10); + J++; if (L > J) TimerDown.MaxHours = clamp(O[J],0,23); + J++; if (L > J) TimerDown.MaxMins = clamp(O[J],0,59); + + for (K = 0; K < 4; K++){ + J++; if (L > J) Alarms_Hour[K] = clamp(O[J],0,23); + J++; if (L > J) Alarms_Minutes[K] = clamp(O[J],0,59); + J++; if (L > J + 1){ + V = ((O[J+1] & 255) << 8); + Alarms_Active[K] = ((O[J] | V) & ALARM_NOTRIGGER); J++; + } + } + OTAFail = millis() - 598000; +} + +// Turbo Mode! +void Watchy::SetTurbo(){ + Turbo.On=true; + Turbo.Last=millis(); + LastButton=millis(); // Here for speed. +} + +bool Watchy::InTurbo() { return (Turbo.On && millis() - Turbo.Last < (Options.Turbo * 1000)); } + +// Debugging here. + +void Watchy::DBug(String Value){ + if (USEDEBUG){ + if (!SerialSetup){ + Serial.begin(115200); + SerialSetup=true; + } + Serial.println(Value); + } +} + +String Watchy::ToHex(uint64_t Value){ + unsigned long long1 = (unsigned long)((Value & 0xFFFF0000) >> 16 ); + unsigned long long2 = (unsigned long)((Value & 0x0000FFFF)); + return String(long1, HEX) + String(long2, HEX); +} diff --git a/src/Watchy_GSR.h b/src/Watchy_GSR.h new file mode 100644 index 0000000..554901e --- /dev/null +++ b/src/Watchy_GSR.h @@ -0,0 +1,102 @@ +#ifndef WATCHY_GSR_H +#define WATCHY_GSR_H + +#include "config.h" +#include "Defines_GSR.h" +#include "Web-HTML.h" +#include +#include +#include +#include +#include +#include ; +#include +#include +#include +#include +#include +#include +#include "GxEPD2_BW-B.h" +#include "mbedtls/base64.h" +#include +#include "BLE.h" +#include "bma.h" + +#include "icons.h" +#include "Olsen2POSIX.h" + +//#include "esp_system.h" +//#include "nvs_flash.h" +//#include "nvs.h" +//#include "nvs_handle.hpp" + +#include "aAntiCorona15pt7b.h"; +#include "Bronova_Regular13pt7b.h" +#include "aAntiCorona16pt7b.h" +#include "aAntiCorona36pt7b.h" +#include "aAntiCorona12pt7b.h" + +class Watchy{ + public: + static DS3232RTC RTC; + static GxEPD2_BW display; + public: + Watchy(); + void init(); + void showWatchFace(); + void drawWatchFace(); //override this method for different watch faces + void drawTime(); + void drawDay(); + void drawDate(); + void drawYear(); + void handleButtonPress(uint8_t Pressed); + virtual void deepSleep(); + float getBatteryVoltage(); + bool IsDark(); + IRAM_ATTR void handleInterrupt(); + private: + void drawChargeMe(); + void drawStatus(); + void setStatus(String Status); + void drawMenu(); + void VibeTo(bool Mode); + //void handleAccelerometer(); + void detectBattery(); + void ProcessNTP(); + void UpdateUTC(); + void UpdateClock(); + void _rtcConfig(); + void _bmaConfig(); + static uint16_t _readRegister(uint8_t address, uint8_t reg, uint8_t *data, uint16_t len); + static uint16_t _writeRegister(uint8_t address, uint8_t reg, uint8_t *data, uint16_t len); + String MakeTime(int Hour, int Minutes, bool& Alarm); + String MakeHour(uint8_t Hour); + String MakeMinutes(uint8_t Minutes); + String MakeSteps(uint32_t uSteps); + void CheckAlarm(int I); + void CheckCD(); + void CalculateTones(); + void StopCD(); + uint8_t getToneTimes(uint8_t ToneIndex); + void monitorSteps(); +// String GetStoredTimezone(); +// virtual bool StoreTimezone(String Timezone); + uint8_t getButtonPins(); + uint8_t getButtonMaskToID(uint64_t HW); + uint8_t getSwapped(uint8_t pIn); + void ScreenRefresh(); + void setupDefaults(); + void initZeros(); + String GetSettings(); + void StoreSettings(String FromUser); + void SetTurbo(); + bool InTurbo(); + void DBug(String Value); + String ToHex(uint64_t Value); +}; + +extern RTC_DATA_ATTR BMA423 sensor; +extern RTC_DATA_ATTR bool WIFI_CONFIGURED; +extern RTC_DATA_ATTR bool BLE_CONFIGURED; + +#endif diff --git a/src/Web-HTML.h b/src/Web-HTML.h new file mode 100644 index 0000000..9841243 --- /dev/null +++ b/src/Web-HTML.h @@ -0,0 +1,282 @@ +//0x3e, 0x3f, 0x3f, 0x3c (separator for settings) +static const char basicIndex[] = { +0x3C, 0x68, 0x74, 0x6D, 0x6C, 0x3E, 0x3C, 0x62, 0x6F, 0x64, 0x79, 0x20, 0x62, 0x67, 0x63, 0x6F, +0x6C, 0x6F, 0x72, 0x3D, 0x22, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x22, 0x20, 0x66, 0x67, 0x63, +0x6F, 0x6C, 0x6F, 0x72, 0x20, 0x3D, 0x22, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x22, 0x3E, 0x3C, +0x73, 0x74, 0x79, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x61, +0x62, 0x6C, 0x65, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, +0x61, 0x64, 0x64, 0x69, 0x6E, 0x67, 0x3A, 0x20, 0x32, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, 0x3A, 0x20, 0x32, 0x70, +0x78, 0x20, 0x73, 0x6F, 0x6C, 0x69, 0x64, 0x20, 0x23, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x3B, +0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, +0x2D, 0x72, 0x61, 0x64, 0x69, 0x75, 0x73, 0x3A, 0x20, 0x35, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x61, 0x63, 0x6B, 0x67, 0x72, 0x6F, 0x75, 0x6E, +0x64, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x3A, 0x20, 0x23, 0x41, 0x30, 0x39, 0x46, 0x39, 0x46, +0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2D, +0x61, 0x6C, 0x69, 0x67, 0x6E, 0x3A, 0x20, 0x63, 0x65, 0x6E, 0x74, 0x65, 0x72, 0x3B, 0x0D, 0x0A, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, +0x64, 0x2C, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x68, 0x20, 0x7B, 0x0D, 0x0A, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6E, 0x67, 0x3A, +0x20, 0x32, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, +0x6F, 0x72, 0x64, 0x65, 0x72, 0x3A, 0x20, 0x30, 0x70, 0x78, 0x20, 0x73, 0x6F, 0x6C, 0x69, 0x64, +0x20, 0x23, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, 0x2D, 0x72, 0x61, 0x64, 0x69, 0x75, 0x73, +0x3A, 0x20, 0x35, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x62, 0x61, 0x63, 0x6B, 0x67, 0x72, 0x6F, 0x75, 0x6E, 0x64, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, +0x3A, 0x20, 0x23, 0x41, 0x30, 0x39, 0x46, 0x39, 0x46, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, 0x74, 0x79, 0x6C, 0x65, +0x3E, 0x0D, 0x0A, 0x3C, 0x74, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3D, +0x27, 0x32, 0x30, 0x25, 0x27, 0x20, 0x61, 0x6C, 0x69, 0x67, 0x6E, 0x3D, 0x27, 0x63, 0x65, 0x6E, +0x74, 0x65, 0x72, 0x27, 0x3E, 0x3C, 0x74, 0x72, 0x3E, 0x3C, 0x74, 0x64, 0x3E, 0x3C, 0x63, 0x65, +0x6E, 0x74, 0x65, 0x72, 0x3E, 0x3C, 0x66, 0x6F, 0x6E, 0x74, 0x20, 0x73, 0x69, 0x7A, 0x65, 0x3D, +0x34, 0x3E, 0x3C, 0x62, 0x3E, 0x3C, 0x75, 0x3E, 0x57, 0x61, 0x74, 0x63, 0x68, 0x79, 0x20, 0x43, +0x6F, 0x6E, 0x6E, 0x65, 0x63, 0x74, 0x20, 0x4F, 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x73, 0x3C, 0x2F, +0x75, 0x3E, 0x3C, 0x2F, 0x62, 0x3E, 0x3C, 0x2F, 0x66, 0x6F, 0x6E, 0x74, 0x3E, 0x3C, 0x2F, 0x63, +0x65, 0x6E, 0x74, 0x65, 0x72, 0x3E, 0x3C, 0x62, 0x72, 0x3E, 0x3C, 0x2F, 0x74, 0x64, 0x3E, 0x3C, +0x2F, 0x74, 0x72, 0x3E, 0x3C, 0x74, 0x64, 0x3E, 0x3C, 0x66, 0x6F, 0x6E, 0x74, 0x20, 0x73, 0x69, +0x7A, 0x65, 0x3D, 0x32, 0x3E, 0x3C, 0x66, 0x6F, 0x72, 0x6D, 0x20, 0x61, 0x63, 0x74, 0x69, 0x6F, +0x6E, 0x3D, 0x27, 0x2F, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6E, 0x67, 0x73, 0x27, 0x3E, 0x3C, 0x62, +0x75, 0x74, 0x74, 0x6F, 0x6E, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3D, 0x27, 0x73, 0x75, 0x62, 0x6D, +0x69, 0x74, 0x27, 0x3E, 0x42, 0x61, 0x63, 0x6B, 0x75, 0x70, 0x20, 0x26, 0x20, 0x52, 0x65, 0x73, +0x74, 0x6F, 0x72, 0x65, 0x20, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6E, 0x67, 0x73, 0x3C, 0x2F, 0x62, +0x75, 0x74, 0x74, 0x6F, 0x6E, 0x3E, 0x3C, 0x2F, 0x66, 0x6F, 0x72, 0x6D, 0x3E, 0x3C, 0x66, 0x6F, +0x72, 0x6D, 0x20, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3D, 0x27, 0x2F, 0x75, 0x70, 0x64, 0x61, +0x74, 0x65, 0x27, 0x3E, 0x3C, 0x62, 0x75, 0x74, 0x74, 0x6F, 0x6E, 0x20, 0x74, 0x79, 0x70, 0x65, +0x3D, 0x27, 0x73, 0x75, 0x62, 0x6D, 0x69, 0x74, 0x27, 0x3E, 0x55, 0x70, 0x6C, 0x6F, 0x61, 0x64, +0x20, 0x4E, 0x65, 0x77, 0x20, 0x46, 0x69, 0x72, 0x6D, 0x77, 0x61, 0x72, 0x65, 0x3C, 0x2F, 0x62, +0x75, 0x74, 0x74, 0x6F, 0x6E, 0x3E, 0x3C, 0x2F, 0x66, 0x6F, 0x72, 0x6D, 0x3E, 0x3C, 0x2F, 0x66, +0x6F, 0x6E, 0x74, 0x3E, 0x3C, 0x2F, 0x74, 0x64, 0x3E, 0x3C, 0x2F, 0x74, 0x72, 0x3E, 0x3C, 0x2F, +0x74, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x3C, 0x2F, 0x62, 0x6F, 0x64, 0x79, 0x3E, 0x3C, 0x2F, 0x68, +0x74, 0x6D, 0x6C, 0x3E, 0x00 +}; + +static const char settingsA[] = { +0x3C, 0x68, 0x74, 0x6D, 0x6C, 0x3E, 0x3C, 0x62, 0x6F, 0x64, 0x79, 0x20, 0x62, 0x67, 0x63, 0x6F, +0x6C, 0x6F, 0x72, 0x3D, 0x22, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x22, 0x20, 0x66, 0x67, 0x63, +0x6F, 0x6C, 0x6F, 0x72, 0x20, 0x3D, 0x22, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x22, 0x3E, 0x3C, +0x73, 0x74, 0x79, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x61, +0x62, 0x6C, 0x65, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, +0x61, 0x64, 0x64, 0x69, 0x6E, 0x67, 0x3A, 0x20, 0x32, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, 0x3A, 0x20, 0x32, 0x70, +0x78, 0x20, 0x73, 0x6F, 0x6C, 0x69, 0x64, 0x20, 0x23, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x3B, +0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, +0x2D, 0x72, 0x61, 0x64, 0x69, 0x75, 0x73, 0x3A, 0x20, 0x35, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x61, 0x63, 0x6B, 0x67, 0x72, 0x6F, 0x75, 0x6E, +0x64, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x3A, 0x20, 0x23, 0x41, 0x30, 0x39, 0x46, 0x39, 0x46, +0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2D, +0x61, 0x6C, 0x69, 0x67, 0x6E, 0x3A, 0x20, 0x63, 0x65, 0x6E, 0x74, 0x65, 0x72, 0x3B, 0x0D, 0x0A, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, +0x64, 0x2C, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x68, 0x20, 0x7B, 0x0D, 0x0A, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6E, 0x67, 0x3A, +0x20, 0x32, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, +0x6F, 0x72, 0x64, 0x65, 0x72, 0x3A, 0x20, 0x30, 0x70, 0x78, 0x20, 0x73, 0x6F, 0x6C, 0x69, 0x64, +0x20, 0x23, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, 0x2D, 0x72, 0x61, 0x64, 0x69, 0x75, 0x73, +0x3A, 0x20, 0x35, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x62, 0x61, 0x63, 0x6B, 0x67, 0x72, 0x6F, 0x75, 0x6E, 0x64, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, +0x3A, 0x20, 0x23, 0x41, 0x30, 0x39, 0x46, 0x39, 0x46, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x65, 0x78, 0x74, 0x61, +0x72, 0x65, 0x61, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, +0x65, 0x73, 0x69, 0x7A, 0x65, 0x3A, 0x20, 0x6E, 0x6F, 0x6E, 0x65, 0x3B, 0x0D, 0x0A, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x77, 0x68, 0x69, 0x74, 0x65, 0x2D, 0x73, 0x70, 0x61, 0x63, +0x65, 0x3A, 0x20, 0x6E, 0x6F, 0x77, 0x72, 0x61, 0x70, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x6F, 0x76, 0x65, 0x72, 0x66, 0x6C, 0x6F, 0x77, 0x2D, 0x78, 0x3A, 0x20, +0x61, 0x75, 0x74, 0x6F, 0x3B, 0x20, 0x2F, 0x2A, 0x20, 0x6F, 0x72, 0x20, 0x68, 0x69, 0x64, 0x64, +0x65, 0x6E, 0x20, 0x2A, 0x2F, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, +0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, 0x74, 0x79, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x3C, 0x66, +0x6F, 0x72, 0x6D, 0x20, 0x6D, 0x65, 0x74, 0x68, 0x6F, 0x64, 0x3D, 0x27, 0x50, 0x4F, 0x53, 0x54, +0x27, 0x20, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3D, 0x27, 0x2F, 0x73, 0x65, 0x74, 0x74, 0x69, +0x6E, 0x67, 0x73, 0x27, 0x20, 0x65, 0x6E, 0x63, 0x74, 0x79, 0x70, 0x65, 0x3D, 0x27, 0x6D, 0x75, +0x6C, 0x74, 0x69, 0x70, 0x61, 0x72, 0x74, 0x2F, 0x66, 0x6F, 0x72, 0x6D, 0x2D, 0x64, 0x61, 0x74, +0x61, 0x27, 0x20, 0x69, 0x64, 0x3D, 0x27, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6E, 0x67, 0x73, 0x5F, +0x66, 0x6F, 0x72, 0x6D, 0x27, 0x3E, 0x3C, 0x74, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x77, 0x69, 0x64, +0x74, 0x68, 0x3D, 0x27, 0x32, 0x30, 0x25, 0x27, 0x20, 0x61, 0x6C, 0x69, 0x67, 0x6E, 0x3D, 0x27, +0x63, 0x65, 0x6E, 0x74, 0x65, 0x72, 0x27, 0x3E, 0x3C, 0x74, 0x72, 0x3E, 0x3C, 0x74, 0x64, 0x20, +0x63, 0x6F, 0x6C, 0x73, 0x70, 0x61, 0x6E, 0x3D, 0x32, 0x3E, 0x3C, 0x63, 0x65, 0x6E, 0x74, 0x65, +0x72, 0x3E, 0x3C, 0x66, 0x6F, 0x6E, 0x74, 0x20, 0x73, 0x69, 0x7A, 0x65, 0x3D, 0x34, 0x3E, 0x3C, +0x62, 0x3E, 0x3C, 0x75, 0x3E, 0x57, 0x61, 0x74, 0x63, 0x68, 0x79, 0x20, 0x42, 0x61, 0x63, 0x6B, +0x75, 0x70, 0x20, 0x26, 0x20, 0x52, 0x65, 0x73, 0x74, 0x6F, 0x72, 0x65, 0x20, 0x53, 0x65, 0x74, +0x74, 0x69, 0x6E, 0x67, 0x73, 0x3C, 0x2F, 0x75, 0x3E, 0x3C, 0x2F, 0x62, 0x3E, 0x3C, 0x2F, 0x66, +0x6F, 0x6E, 0x74, 0x3E, 0x3C, 0x2F, 0x63, 0x65, 0x6E, 0x74, 0x65, 0x72, 0x3E, 0x3C, 0x62, 0x72, +0x3E, 0x3C, 0x2F, 0x74, 0x64, 0x3E, 0x3C, 0x2F, 0x74, 0x72, 0x3E, 0x3C, 0x74, 0x64, 0x3E, 0x3C, +0x66, 0x6F, 0x6E, 0x74, 0x20, 0x73, 0x69, 0x7A, 0x65, 0x3D, 0x32, 0x3E, 0x3C, 0x74, 0x65, 0x78, +0x74, 0x61, 0x72, 0x65, 0x61, 0x20, 0x69, 0x64, 0x3D, 0x27, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6E, +0x67, 0x73, 0x27, 0x20, 0x6E, 0x61, 0x6D, 0x65, 0x3D, 0x27, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6E, +0x67, 0x73, 0x27, 0x20, 0x63, 0x6F, 0x6C, 0x73, 0x3D, 0x27, 0x35, 0x30, 0x27, 0x20, 0x72, 0x6F, +0x77, 0x73, 0x3D, 0x27, 0x31, 0x27, 0x3E, 0x00 +}; + +static const char settingsB[] = { +0x3C, 0x2F, 0x74, 0x65, 0x78, 0x74, 0x61, 0x72, 0x65, 0x61, 0x3E, 0x3C, 0x2F, 0x66, 0x6F, 0x6E, 0x74, 0x3E, +0x3C, 0x2F, 0x74, 0x64, 0x3E, 0x3C, 0x74, 0x64, 0x20, 0x61, 0x6C, 0x69, 0x67, 0x6E, 0x3D, 0x22, +0x72, 0x69, 0x67, 0x68, 0x74, 0x22, 0x20, 0x76, 0x61, 0x6C, 0x69, 0x67, 0x6E, 0x3D, 0x27, 0x62, +0x6F, 0x74, 0x74, 0x6F, 0x6D, 0x27, 0x3E, 0x3C, 0x66, 0x6F, 0x6E, 0x74, 0x20, 0x73, 0x69, 0x7A, +0x65, 0x3D, 0x32, 0x3E, 0x3C, 0x69, 0x6E, 0x70, 0x75, 0x74, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3D, +0x27, 0x73, 0x75, 0x62, 0x6D, 0x69, 0x74, 0x27, 0x20, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x3D, 0x27, +0x53, 0x74, 0x6F, 0x72, 0x65, 0x27, 0x3E, 0x3C, 0x62, 0x72, 0x3E, 0x3C, 0x2F, 0x66, 0x6F, 0x6E, +0x74, 0x3E, 0x3C, 0x2F, 0x74, 0x64, 0x3E, 0x3C, 0x2F, 0x74, 0x72, 0x3E, 0x3C, 0x2F, 0x74, 0x61, +0x62, 0x6C, 0x65, 0x3E, 0x3C, 0x2F, 0x66, 0x6F, 0x72, 0x6D, 0x3E, 0x3C, 0x2F, 0x62, 0x6F, 0x64, +0x79, 0x3E, 0x3C, 0x2F, 0x68, 0x74, 0x6D, 0x6C, 0x3E, 0x00 +}; + +static const char settingsDone[] = { +0x3C, 0x68, 0x74, 0x6D, 0x6C, 0x3E, 0x3C, 0x62, 0x6F, 0x64, 0x79, 0x20, 0x62, 0x67, 0x63, 0x6F, +0x6C, 0x6F, 0x72, 0x3D, 0x22, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x22, 0x20, 0x66, 0x67, 0x63, +0x6F, 0x6C, 0x6F, 0x72, 0x20, 0x3D, 0x22, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x22, 0x3E, 0x3C, +0x73, 0x74, 0x79, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x61, +0x62, 0x6C, 0x65, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, +0x61, 0x64, 0x64, 0x69, 0x6E, 0x67, 0x3A, 0x20, 0x32, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, 0x3A, 0x20, 0x32, 0x70, +0x78, 0x20, 0x73, 0x6F, 0x6C, 0x69, 0x64, 0x20, 0x23, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x3B, +0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, +0x2D, 0x72, 0x61, 0x64, 0x69, 0x75, 0x73, 0x3A, 0x20, 0x35, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x61, 0x63, 0x6B, 0x67, 0x72, 0x6F, 0x75, 0x6E, +0x64, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x3A, 0x20, 0x23, 0x41, 0x30, 0x39, 0x46, 0x39, 0x46, +0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2D, +0x61, 0x6C, 0x69, 0x67, 0x6E, 0x3A, 0x20, 0x63, 0x65, 0x6E, 0x74, 0x65, 0x72, 0x3B, 0x0D, 0x0A, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, +0x64, 0x2C, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x68, 0x20, 0x7B, 0x0D, 0x0A, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6E, 0x67, 0x3A, +0x20, 0x32, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, +0x6F, 0x72, 0x64, 0x65, 0x72, 0x3A, 0x20, 0x30, 0x70, 0x78, 0x20, 0x73, 0x6F, 0x6C, 0x69, 0x64, +0x20, 0x23, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, 0x2D, 0x72, 0x61, 0x64, 0x69, 0x75, 0x73, +0x3A, 0x20, 0x35, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x62, 0x61, 0x63, 0x6B, 0x67, 0x72, 0x6F, 0x75, 0x6E, 0x64, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, +0x3A, 0x20, 0x23, 0x41, 0x30, 0x39, 0x46, 0x39, 0x46, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x7D, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x65, 0x78, 0x74, 0x61, +0x72, 0x65, 0x61, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, +0x65, 0x73, 0x69, 0x7A, 0x65, 0x3A, 0x20, 0x6E, 0x6F, 0x6E, 0x65, 0x3B, 0x0D, 0x0A, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x77, 0x68, 0x69, 0x74, 0x65, 0x2D, 0x73, 0x70, 0x61, 0x63, +0x65, 0x3A, 0x20, 0x6E, 0x6F, 0x77, 0x72, 0x61, 0x70, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x6F, 0x76, 0x65, 0x72, 0x66, 0x6C, 0x6F, 0x77, 0x2D, 0x78, 0x3A, 0x20, +0x73, 0x63, 0x72, 0x6F, 0x6C, 0x6C, 0x3B, 0x20, 0x2F, 0x2A, 0x20, 0x6F, 0x72, 0x20, 0x68, 0x69, +0x64, 0x64, 0x65, 0x6E, 0x20, 0x2A, 0x2F, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, +0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, 0x74, 0x79, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, +0x3C, 0x74, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3D, 0x27, 0x32, 0x30, +0x25, 0x27, 0x20, 0x61, 0x6C, 0x69, 0x67, 0x6E, 0x3D, 0x27, 0x63, 0x65, 0x6E, 0x74, 0x65, 0x72, +0x27, 0x3E, 0x3C, 0x74, 0x72, 0x3E, 0x3C, 0x74, 0x64, 0x3E, 0x3C, 0x63, 0x65, 0x6E, 0x74, 0x65, +0x72, 0x3E, 0x3C, 0x66, 0x6F, 0x6E, 0x74, 0x20, 0x73, 0x69, 0x7A, 0x65, 0x3D, 0x34, 0x3E, 0x3C, +0x62, 0x3E, 0x3C, 0x75, 0x3E, 0x57, 0x61, 0x74, 0x63, 0x68, 0x79, 0x20, 0x42, 0x61, 0x63, 0x6B, +0x75, 0x70, 0x20, 0x26, 0x20, 0x52, 0x65, 0x73, 0x74, 0x6F, 0x72, 0x65, 0x20, 0x53, 0x65, 0x74, +0x74, 0x69, 0x6E, 0x67, 0x73, 0x3C, 0x2F, 0x75, 0x3E, 0x3C, 0x2F, 0x62, 0x3E, 0x3C, 0x2F, 0x66, +0x6F, 0x6E, 0x74, 0x3E, 0x3C, 0x2F, 0x63, 0x65, 0x6E, 0x74, 0x65, 0x72, 0x3E, 0x3C, 0x62, 0x72, +0x3E, 0x3C, 0x2F, 0x74, 0x64, 0x3E, 0x3C, 0x2F, 0x74, 0x72, 0x3E, 0x3C, 0x74, 0x64, 0x3E, 0x3C, +0x66, 0x6F, 0x6E, 0x74, 0x20, 0x73, 0x69, 0x7A, 0x65, 0x3D, 0x33, 0x3E, 0x57, 0x61, 0x74, 0x63, +0x68, 0x79, 0x20, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6E, 0x67, 0x73, 0x20, 0x72, 0x65, 0x73, 0x74, +0x6F, 0x72, 0x65, 0x64, 0x21, 0x20, 0x20, 0x4F, 0x54, 0x41, 0x20, 0x57, 0x65, 0x62, 0x73, 0x69, +0x74, 0x65, 0x20, 0x4F, 0x66, 0x66, 0x2E, 0x3C, 0x62, 0x72, 0x3E, 0x3C, 0x2F, 0x66, 0x6F, 0x6E, +0x74, 0x3E, 0x3C, 0x2F, 0x74, 0x64, 0x3E, 0x3C, 0x2F, 0x74, 0x72, 0x3E, 0x3C, 0x2F, 0x74, 0x61, +0x62, 0x6C, 0x65, 0x3E, 0x3C, 0x2F, 0x62, 0x6F, 0x64, 0x79, 0x3E, 0x3C, 0x2F, 0x68, 0x74, 0x6D, +0x6C, 0x3E, 0x00 +}; +static const char updateIndex[] = { +0x3C, 0x68, 0x74, 0x6D, 0x6C, 0x3E, 0x3C, 0x62, 0x6F, 0x64, 0x79, 0x20, 0x62, 0x67, 0x63, 0x6F, +0x6C, 0x6F, 0x72, 0x3D, 0x22, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x22, 0x20, 0x66, 0x67, 0x63, +0x6F, 0x6C, 0x6F, 0x72, 0x20, 0x3D, 0x22, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x22, 0x3E, 0x3C, +0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x20, 0x73, 0x72, 0x63, 0x3D, 0x27, 0x68, 0x74, 0x74, 0x70, +0x73, 0x3A, 0x2F, 0x2F, 0x61, 0x6A, 0x61, 0x78, 0x2E, 0x67, 0x6F, 0x6F, 0x67, 0x6C, 0x65, 0x61, +0x70, 0x69, 0x73, 0x2E, 0x63, 0x6F, 0x6D, 0x2F, 0x61, 0x6A, 0x61, 0x78, 0x2F, 0x6C, 0x69, 0x62, +0x73, 0x2F, 0x6A, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2F, 0x33, 0x2E, 0x32, 0x2E, 0x31, 0x2F, 0x6A, +0x71, 0x75, 0x65, 0x72, 0x79, 0x2E, 0x6D, 0x69, 0x6E, 0x2E, 0x6A, 0x73, 0x27, 0x3E, 0x3C, 0x2F, +0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3E, 0x0D, 0x0A, 0x20, 0x3C, 0x73, 0x74, 0x79, 0x6C, 0x65, +0x3E, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x61, 0x62, 0x6C, 0x65, 0x20, 0x7B, +0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6E, +0x67, 0x3A, 0x20, 0x32, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, 0x3A, 0x20, 0x32, 0x70, 0x78, 0x20, 0x73, 0x6F, 0x6C, +0x69, 0x64, 0x20, 0x23, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, 0x2D, 0x72, 0x61, 0x64, 0x69, +0x75, 0x73, 0x3A, 0x20, 0x35, 0x70, 0x78, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x62, 0x61, 0x63, 0x6B, 0x67, 0x72, 0x6F, 0x75, 0x6E, 0x64, 0x2D, 0x63, 0x6F, 0x6C, +0x6F, 0x72, 0x3A, 0x20, 0x23, 0x41, 0x30, 0x39, 0x46, 0x39, 0x46, 0x3B, 0x0D, 0x0A, 0x20, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2D, 0x61, 0x6C, 0x69, 0x67, 0x6E, +0x3A, 0x20, 0x63, 0x65, 0x6E, 0x74, 0x65, 0x72, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x7D, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x64, 0x2C, 0x0D, 0x0A, 0x20, +0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x68, 0x20, 0x7B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, +0x20, 0x20, 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6E, 0x67, 0x3A, 0x20, 0x32, 0x70, 0x78, 0x3B, +0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x6F, 0x72, 0x64, 0x65, 0x72, +0x3A, 0x20, 0x30, 0x70, 0x78, 0x20, 0x73, 0x6F, 0x6C, 0x69, 0x64, 0x20, 0x23, 0x30, 0x30, 0x30, +0x30, 0x30, 0x30, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x6F, +0x72, 0x64, 0x65, 0x72, 0x2D, 0x72, 0x61, 0x64, 0x69, 0x75, 0x73, 0x3A, 0x20, 0x35, 0x70, 0x78, +0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x61, 0x63, 0x6B, 0x67, +0x72, 0x6F, 0x75, 0x6E, 0x64, 0x2D, 0x63, 0x6F, 0x6C, 0x6F, 0x72, 0x3A, 0x20, 0x23, 0x41, 0x30, +0x39, 0x46, 0x39, 0x46, 0x3B, 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x0D, 0x0A, +0x20, 0x20, 0x20, 0x20, 0x3C, 0x2F, 0x73, 0x74, 0x79, 0x6C, 0x65, 0x3E, 0x0D, 0x0A, 0x3C, 0x66, +0x6F, 0x72, 0x6D, 0x20, 0x6D, 0x65, 0x74, 0x68, 0x6F, 0x64, 0x3D, 0x27, 0x50, 0x4F, 0x53, 0x54, +0x27, 0x20, 0x61, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x3D, 0x27, 0x23, 0x27, 0x20, 0x65, 0x6E, 0x63, +0x74, 0x79, 0x70, 0x65, 0x3D, 0x27, 0x6D, 0x75, 0x6C, 0x74, 0x69, 0x70, 0x61, 0x72, 0x74, 0x2F, +0x66, 0x6F, 0x72, 0x6D, 0x2D, 0x64, 0x61, 0x74, 0x61, 0x27, 0x20, 0x69, 0x64, 0x3D, 0x27, 0x75, +0x70, 0x6C, 0x6F, 0x61, 0x64, 0x5F, 0x66, 0x6F, 0x72, 0x6D, 0x27, 0x3E, 0x0D, 0x0A, 0x3C, 0x74, +0x61, 0x62, 0x6C, 0x65, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3D, 0x27, 0x32, 0x30, 0x25, 0x27, +0x20, 0x61, 0x6C, 0x69, 0x67, 0x6E, 0x3D, 0x27, 0x63, 0x65, 0x6E, 0x74, 0x65, 0x72, 0x27, 0x3E, +0x3C, 0x74, 0x72, 0x3E, 0x3C, 0x74, 0x64, 0x20, 0x63, 0x6F, 0x6C, 0x73, 0x70, 0x61, 0x6E, 0x3D, +0x32, 0x3E, 0x0D, 0x0A, 0x3C, 0x63, 0x65, 0x6E, 0x74, 0x65, 0x72, 0x3E, 0x3C, 0x66, 0x6F, 0x6E, +0x74, 0x20, 0x73, 0x69, 0x7A, 0x65, 0x3D, 0x34, 0x3E, 0x3C, 0x62, 0x3E, 0x3C, 0x75, 0x3E, 0x57, +0x61, 0x74, 0x63, 0x68, 0x79, 0x20, 0x55, 0x70, 0x6C, 0x6F, 0x61, 0x64, 0x20, 0x4E, 0x65, 0x77, +0x20, 0x46, 0x69, 0x72, 0x6D, 0x77, 0x61, 0x72, 0x65, 0x3C, 0x2F, 0x75, 0x3E, 0x3C, 0x2F, 0x62, +0x3E, 0x3C, 0x2F, 0x66, 0x6F, 0x6E, 0x74, 0x3E, 0x3C, 0x2F, 0x63, 0x65, 0x6E, 0x74, 0x65, 0x72, +0x3E, 0x3C, 0x62, 0x72, 0x3E, 0x3C, 0x2F, 0x74, 0x64, 0x3E, 0x3C, 0x2F, 0x74, 0x72, 0x3E, 0x0D, +0x0A, 0x3C, 0x74, 0x64, 0x20, 0x61, 0x6C, 0x69, 0x67, 0x6E, 0x3D, 0x27, 0x6C, 0x65, 0x66, 0x74, +0x27, 0x3E, 0x3C, 0x66, 0x6F, 0x6E, 0x74, 0x20, 0x73, 0x69, 0x7A, 0x65, 0x20, 0x3D, 0x20, 0x32, +0x3E, 0x3C, 0x69, 0x6E, 0x70, 0x75, 0x74, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3D, 0x27, 0x66, 0x69, +0x6C, 0x65, 0x27, 0x20, 0x6E, 0x61, 0x6D, 0x65, 0x3D, 0x27, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, +0x27, 0x20, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x3D, 0x27, 0x2E, 0x62, 0x69, 0x6E, 0x27, 0x3E, +0x3C, 0x2F, 0x66, 0x6F, 0x6E, 0x74, 0x3E, 0x3C, 0x2F, 0x74, 0x64, 0x3E, 0x3C, 0x74, 0x64, 0x20, +0x61, 0x6C, 0x69, 0x67, 0x6E, 0x3D, 0x22, 0x72, 0x69, 0x67, 0x68, 0x74, 0x22, 0x3E, 0x3C, 0x66, +0x6F, 0x6E, 0x74, 0x20, 0x73, 0x69, 0x7A, 0x65, 0x20, 0x3D, 0x32, 0x3E, 0x3C, 0x69, 0x6E, 0x70, +0x75, 0x74, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3D, 0x27, 0x73, 0x75, 0x62, 0x6D, 0x69, 0x74, 0x27, +0x20, 0x76, 0x61, 0x6C, 0x75, 0x65, 0x3D, 0x27, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x27, 0x3E, +0x3C, 0x62, 0x72, 0x3E, 0x3C, 0x2F, 0x66, 0x6F, 0x6E, 0x74, 0x3E, 0x3C, 0x2F, 0x74, 0x64, 0x3E, +0x3C, 0x2F, 0x74, 0x72, 0x3E, 0x0D, 0x0A, 0x3C, 0x74, 0x72, 0x3E, 0x3C, 0x74, 0x64, 0x20, 0x63, +0x6F, 0x6C, 0x73, 0x70, 0x61, 0x6E, 0x3D, 0x32, 0x3E, 0x3C, 0x62, 0x72, 0x3E, 0x3C, 0x63, 0x65, +0x6E, 0x74, 0x65, 0x72, 0x3E, 0x3C, 0x64, 0x69, 0x76, 0x20, 0x69, 0x64, 0x3D, 0x27, 0x70, 0x72, +0x67, 0x27, 0x3E, 0x57, 0x61, 0x69, 0x74, 0x69, 0x6E, 0x67, 0x2E, 0x2E, 0x2E, 0x3C, 0x2F, 0x64, +0x69, 0x76, 0x3E, 0x3C, 0x2F, 0x63, 0x65, 0x6E, 0x74, 0x65, 0x72, 0x3E, 0x3C, 0x2F, 0x74, 0x64, +0x3E, 0x3C, 0x2F, 0x74, 0x72, 0x3E, 0x3C, 0x2F, 0x74, 0x61, 0x62, 0x6C, 0x65, 0x3E, 0x3C, 0x2F, +0x66, 0x6F, 0x72, 0x6D, 0x3E, 0x3C, 0x2F, 0x62, 0x6F, 0x64, 0x79, 0x3E, 0x0D, 0x0A, 0x3C, 0x73, +0x63, 0x72, 0x69, 0x70, 0x74, 0x3E, 0x0D, 0x0A, 0x24, 0x28, 0x27, 0x66, 0x6F, 0x72, 0x6D, 0x27, +0x29, 0x2E, 0x73, 0x75, 0x62, 0x6D, 0x69, 0x74, 0x28, 0x66, 0x75, 0x6E, 0x63, 0x74, 0x69, 0x6F, +0x6E, 0x28, 0x65, 0x29, 0x7B, 0x0D, 0x0A, 0x65, 0x2E, 0x70, 0x72, 0x65, 0x76, 0x65, 0x6E, 0x74, +0x44, 0x65, 0x66, 0x61, 0x75, 0x6C, 0x74, 0x28, 0x29, 0x3B, 0x0D, 0x0A, 0x69, 0x66, 0x28, 0x21, +0x24, 0x28, 0x27, 0x66, 0x6F, 0x72, 0x6D, 0x20, 0x69, 0x6E, 0x70, 0x75, 0x74, 0x5B, 0x74, 0x79, +0x70, 0x65, 0x3D, 0x66, 0x69, 0x6C, 0x65, 0x5D, 0x27, 0x29, 0x2E, 0x76, 0x61, 0x6C, 0x28, 0x29, +0x29, 0x20, 0x7B, 0x20, 0x61, 0x6C, 0x65, 0x72, 0x74, 0x28, 0x27, 0x59, 0x6F, 0x75, 0x20, 0x6D, +0x75, 0x73, 0x74, 0x20, 0x73, 0x65, 0x6C, 0x65, 0x63, 0x74, 0x20, 0x61, 0x20, 0x66, 0x69, 0x72, +0x6D, 0x77, 0x61, 0x72, 0x65, 0x20, 0x5B, 0x62, 0x69, 0x6E, 0x5D, 0x20, 0x74, 0x6F, 0x20, 0x75, +0x70, 0x6C, 0x6F, 0x61, 0x64, 0x21, 0x27, 0x29, 0x3B, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6E, +0x20, 0x66, 0x61, 0x6C, 0x73, 0x65, 0x3B, 0x20, 0x7D, 0x0D, 0x0A, 0x76, 0x61, 0x72, 0x20, 0x66, +0x6F, 0x72, 0x6D, 0x20, 0x3D, 0x20, 0x24, 0x28, 0x27, 0x23, 0x75, 0x70, 0x6C, 0x6F, 0x61, 0x64, +0x5F, 0x66, 0x6F, 0x72, 0x6D, 0x27, 0x29, 0x5B, 0x30, 0x5D, 0x3B, 0x0D, 0x0A, 0x76, 0x61, 0x72, +0x20, 0x64, 0x61, 0x74, 0x61, 0x20, 0x3D, 0x20, 0x6E, 0x65, 0x77, 0x20, 0x46, 0x6F, 0x72, 0x6D, +0x44, 0x61, 0x74, 0x61, 0x28, 0x66, 0x6F, 0x72, 0x6D, 0x29, 0x3B, 0x0D, 0x0A, 0x24, 0x2E, 0x61, +0x6A, 0x61, 0x78, 0x28, 0x7B, 0x0D, 0x0A, 0x75, 0x72, 0x6C, 0x3A, 0x20, 0x27, 0x2F, 0x75, 0x70, +0x64, 0x61, 0x74, 0x65, 0x27, 0x2C, 0x0D, 0x0A, 0x74, 0x79, 0x70, 0x65, 0x3A, 0x20, 0x27, 0x50, +0x4F, 0x53, 0x54, 0x27, 0x2C, 0x0D, 0x0A, 0x64, 0x61, 0x74, 0x61, 0x3A, 0x20, 0x64, 0x61, 0x74, +0x61, 0x2C, 0x0D, 0x0A, 0x63, 0x6F, 0x6E, 0x74, 0x65, 0x6E, 0x74, 0x54, 0x79, 0x70, 0x65, 0x3A, +0x20, 0x66, 0x61, 0x6C, 0x73, 0x65, 0x2C, 0x0D, 0x0A, 0x70, 0x72, 0x6F, 0x63, 0x65, 0x73, 0x73, +0x44, 0x61, 0x74, 0x61, 0x3A, 0x66, 0x61, 0x6C, 0x73, 0x65, 0x2C, 0x0D, 0x0A, 0x78, 0x68, 0x72, +0x3A, 0x20, 0x66, 0x75, 0x6E, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x28, 0x29, 0x20, 0x7B, 0x0D, 0x0A, +0x76, 0x61, 0x72, 0x20, 0x78, 0x68, 0x72, 0x20, 0x3D, 0x20, 0x6E, 0x65, 0x77, 0x20, 0x77, 0x69, +0x6E, 0x64, 0x6F, 0x77, 0x2E, 0x58, 0x4D, 0x4C, 0x48, 0x74, 0x74, 0x70, 0x52, 0x65, 0x71, 0x75, +0x65, 0x73, 0x74, 0x28, 0x29, 0x3B, 0x0D, 0x0A, 0x78, 0x68, 0x72, 0x2E, 0x75, 0x70, 0x6C, 0x6F, +0x61, 0x64, 0x2E, 0x61, 0x64, 0x64, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x4C, 0x69, 0x73, 0x74, 0x65, +0x6E, 0x65, 0x72, 0x28, 0x27, 0x70, 0x72, 0x6F, 0x67, 0x72, 0x65, 0x73, 0x73, 0x27, 0x2C, 0x20, +0x66, 0x75, 0x6E, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x28, 0x65, 0x76, 0x74, 0x29, 0x20, 0x7B, 0x0D, +0x0A, 0x69, 0x66, 0x20, 0x28, 0x65, 0x76, 0x74, 0x2E, 0x6C, 0x65, 0x6E, 0x67, 0x74, 0x68, 0x43, +0x6F, 0x6D, 0x70, 0x75, 0x74, 0x61, 0x62, 0x6C, 0x65, 0x29, 0x20, 0x7B, 0x0D, 0x0A, 0x76, 0x61, +0x72, 0x20, 0x70, 0x65, 0x72, 0x20, 0x3D, 0x20, 0x65, 0x76, 0x74, 0x2E, 0x6C, 0x6F, 0x61, 0x64, +0x65, 0x64, 0x20, 0x2F, 0x20, 0x65, 0x76, 0x74, 0x2E, 0x74, 0x6F, 0x74, 0x61, 0x6C, 0x3B, 0x0D, +0x0A, 0x24, 0x28, 0x27, 0x23, 0x70, 0x72, 0x67, 0x27, 0x29, 0x2E, 0x68, 0x74, 0x6D, 0x6C, 0x28, +0x27, 0x50, 0x72, 0x6F, 0x67, 0x72, 0x65, 0x73, 0x73, 0x3A, 0x20, 0x27, 0x20, 0x2B, 0x20, 0x4D, +0x61, 0x74, 0x68, 0x2E, 0x72, 0x6F, 0x75, 0x6E, 0x64, 0x28, 0x70, 0x65, 0x72, 0x2A, 0x31, 0x30, +0x30, 0x29, 0x20, 0x2B, 0x20, 0x27, 0x25, 0x27, 0x29, 0x3B, 0x0D, 0x0A, 0x7D, 0x0D, 0x0A, 0x7D, +0x2C, 0x20, 0x66, 0x61, 0x6C, 0x73, 0x65, 0x29, 0x3B, 0x0D, 0x0A, 0x72, 0x65, 0x74, 0x75, 0x72, +0x6E, 0x20, 0x78, 0x68, 0x72, 0x3B, 0x0D, 0x0A, 0x7D, 0x2C, 0x0D, 0x0A, 0x73, 0x75, 0x63, 0x63, +0x65, 0x73, 0x73, 0x3A, 0x66, 0x75, 0x6E, 0x63, 0x74, 0x69, 0x6F, 0x6E, 0x28, 0x64, 0x2C, 0x20, +0x73, 0x29, 0x20, 0x7B, 0x0D, 0x0A, 0x63, 0x6F, 0x6E, 0x73, 0x6F, 0x6C, 0x65, 0x2E, 0x6C, 0x6F, +0x67, 0x28, 0x27, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x21, 0x27, 0x29, 0x0D, 0x0A, 0x7D, +0x2C, 0x0D, 0x0A, 0x65, 0x72, 0x72, 0x6F, 0x72, 0x3A, 0x20, 0x66, 0x75, 0x6E, 0x63, 0x74, 0x69, +0x6F, 0x6E, 0x20, 0x28, 0x61, 0x2C, 0x20, 0x62, 0x2C, 0x20, 0x63, 0x29, 0x20, 0x7B, 0x0D, 0x0A, +0x7D, 0x0D, 0x0A, 0x7D, 0x29, 0x3B, 0x0D, 0x0A, 0x7D, 0x29, 0x3B, 0x0D, 0x0A, 0x3C, 0x2F, 0x73, +0x63, 0x72, 0x69, 0x70, 0x74, 0x3E, 0x3C, 0x2F, 0x68, 0x74, 0x6D, 0x6C, 0x3E, 0x00 +}; diff --git a/src/aAntiCorona12pt7b.h b/src/aAntiCorona12pt7b.h new file mode 100644 index 0000000..cd3e742 --- /dev/null +++ b/src/aAntiCorona12pt7b.h @@ -0,0 +1,281 @@ +const uint8_t aAntiCorona12pt7bBitmaps[] PROGMEM = { + 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFC, 0x07, 0xFF, 0x80, 0x67, 0xDF, 0xBF, + 0x7C, 0xC8, 0x80, 0x00, 0x00, 0x0C, 0x60, 0x73, 0x81, 0xCC, 0x06, 0x70, + 0xFF, 0xF7, 0xFF, 0xDF, 0xFE, 0x1C, 0xE0, 0x63, 0x07, 0xFF, 0xBF, 0xFE, + 0xFF, 0xF1, 0xCE, 0x07, 0x30, 0x19, 0xC0, 0x66, 0x00, 0x03, 0x00, 0xF8, + 0x1F, 0xE3, 0xFE, 0x77, 0xE7, 0x70, 0x7F, 0x07, 0xF8, 0x3F, 0xE1, 0xFF, + 0x07, 0xF0, 0x77, 0x07, 0x77, 0xF7, 0x7F, 0xE7, 0xFC, 0x1F, 0x80, 0x60, + 0x1E, 0x06, 0x03, 0xF0, 0xE0, 0x7F, 0x0E, 0x0E, 0x39, 0xC0, 0xC1, 0x9C, + 0x0C, 0x1B, 0x80, 0xC1, 0xB9, 0xCE, 0x3F, 0x3E, 0x7F, 0x77, 0xE7, 0xEE, + 0xE7, 0x3C, 0xEC, 0x30, 0x1C, 0xC3, 0x01, 0xCC, 0x30, 0x38, 0xC3, 0x03, + 0x0E, 0x70, 0x70, 0x7E, 0x06, 0x07, 0xC0, 0x60, 0x38, 0x0F, 0x00, 0xFC, + 0x0F, 0xF0, 0xE7, 0x87, 0x1C, 0x38, 0xE1, 0xEE, 0x0F, 0xF0, 0x3F, 0x01, + 0xF0, 0x1F, 0xD8, 0xFF, 0xCE, 0x7E, 0x71, 0xFB, 0xC7, 0xFF, 0xFF, 0x7F, + 0xB1, 0xF8, 0x00, 0x7F, 0xFC, 0x80, 0x0E, 0x3C, 0xF1, 0xC7, 0x0E, 0x18, + 0x70, 0xE1, 0xC3, 0x87, 0x0E, 0x1C, 0x38, 0x78, 0x70, 0xE1, 0xE1, 0xF3, + 0xE3, 0x80, 0x70, 0x78, 0x7C, 0x3E, 0x1E, 0x0E, 0x0F, 0x0F, 0x07, 0x07, + 0x07, 0x07, 0x07, 0x07, 0x07, 0x06, 0x0E, 0x0E, 0x1C, 0x7C, 0x78, 0x60, + 0x06, 0x01, 0xC0, 0x38, 0x3F, 0x0F, 0xFF, 0xFF, 0xC7, 0xE1, 0xF8, 0x77, + 0x0C, 0xE0, 0x08, 0x00, 0x06, 0x03, 0x80, 0xE1, 0xFF, 0xFF, 0xFF, 0xE0, + 0xE0, 0x38, 0x0E, 0x03, 0x00, 0xEE, 0xE6, 0x6C, 0x7F, 0xFF, 0xFF, 0xF8, + 0xFF, 0xF0, 0x03, 0x07, 0x07, 0x06, 0x0E, 0x0E, 0x0C, 0x1C, 0x1C, 0x38, + 0x38, 0x30, 0x70, 0x70, 0x60, 0xE0, 0xE0, 0xC0, 0x07, 0xC0, 0x3F, 0x81, + 0xFF, 0x0E, 0x3E, 0x70, 0x79, 0x80, 0xFE, 0x03, 0xF8, 0x07, 0xE0, 0x1F, + 0x80, 0x7E, 0x01, 0xFC, 0x07, 0xF0, 0x39, 0xE0, 0xE7, 0xC7, 0x0F, 0xF8, + 0x1F, 0xC0, 0x3E, 0x00, 0x19, 0xDF, 0xFF, 0x9C, 0xE7, 0x39, 0xCE, 0x73, + 0x9C, 0xE7, 0x39, 0x80, 0x3F, 0x0F, 0xF8, 0xFF, 0xCC, 0x3E, 0x01, 0xE0, + 0x0E, 0x00, 0xE0, 0x1C, 0x03, 0xC0, 0x78, 0x0F, 0x01, 0xE0, 0x3C, 0x03, + 0x80, 0x70, 0x07, 0xFE, 0xFF, 0xEF, 0xFE, 0x1F, 0x0F, 0xF1, 0xFF, 0x21, + 0xE0, 0x1C, 0x03, 0x80, 0x70, 0xFC, 0x3F, 0xC7, 0xF8, 0x0F, 0x80, 0xF0, + 0x0E, 0x01, 0xC8, 0x73, 0xFE, 0x7F, 0x8F, 0xC0, 0x01, 0x80, 0x70, 0x0E, + 0x03, 0x80, 0x66, 0x1D, 0xC7, 0x38, 0xE7, 0x38, 0xE6, 0x1D, 0xC3, 0xFF, + 0xFF, 0xFF, 0xFF, 0xC0, 0x38, 0x07, 0x00, 0xE0, 0x18, 0x3F, 0xCF, 0xF9, + 0xFF, 0x38, 0x07, 0x00, 0xE0, 0x1F, 0xC3, 0xFC, 0x7F, 0xC0, 0x7C, 0x07, + 0x80, 0x70, 0x0E, 0x01, 0xC8, 0x77, 0xFE, 0xFF, 0x0F, 0xC0, 0x07, 0xC0, + 0x7F, 0x07, 0xFC, 0x71, 0xE3, 0x06, 0x38, 0x01, 0xDF, 0x0F, 0xFE, 0x7F, + 0xF7, 0xC7, 0xDC, 0x1E, 0xE0, 0x77, 0x03, 0xBC, 0x1C, 0xF1, 0xC7, 0xFC, + 0x1F, 0xE0, 0x7C, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0x80, 0xE0, 0x1C, 0x03, + 0x00, 0xE0, 0x1C, 0x03, 0x00, 0xE0, 0x1C, 0x07, 0x00, 0xE0, 0x18, 0x07, + 0x00, 0xE0, 0x18, 0x02, 0x00, 0x1F, 0x07, 0xF1, 0xFF, 0x71, 0xEE, 0x1D, + 0xC3, 0xBE, 0x67, 0xFC, 0x7F, 0xCF, 0xFB, 0xDF, 0xF0, 0xFE, 0x0F, 0xC1, + 0xFC, 0x3F, 0xFE, 0x7F, 0x87, 0xC0, 0x0F, 0x80, 0xFE, 0x0F, 0xF8, 0xFF, + 0xC6, 0x0F, 0x70, 0x7B, 0x81, 0xDC, 0x0E, 0xF0, 0x7F, 0xC7, 0x9F, 0xFC, + 0x7F, 0xE1, 0xF7, 0x00, 0x30, 0xE3, 0x8F, 0xF8, 0x3F, 0x80, 0xF8, 0x00, + 0xFF, 0xF0, 0x00, 0xFF, 0xF0, 0xFF, 0xF0, 0x00, 0xFF, 0xB5, 0x80, 0x00, + 0x18, 0x07, 0xC1, 0xFC, 0x3F, 0x87, 0xF0, 0x7E, 0x03, 0xFE, 0x07, 0xFC, + 0x0F, 0xF8, 0x0F, 0xC0, 0x1C, 0x7F, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x1F, + 0xFF, 0xFF, 0xFE, 0x70, 0x07, 0xE0, 0x3F, 0xE0, 0x7F, 0xC0, 0xFF, 0x80, + 0xFC, 0x1F, 0xC3, 0xF8, 0x7F, 0x07, 0xC0, 0x30, 0x00, 0x3F, 0x0F, 0xFB, + 0xFF, 0x21, 0xF0, 0x0E, 0x01, 0xC0, 0x38, 0x0E, 0x03, 0x80, 0xE0, 0x38, + 0x07, 0x00, 0xC0, 0x00, 0x03, 0x00, 0xE0, 0x1C, 0x03, 0x80, 0x03, 0xF0, + 0x07, 0xFE, 0x07, 0xFF, 0x87, 0x87, 0xE7, 0x00, 0xF3, 0x8F, 0x3D, 0x8F, + 0x9F, 0xC7, 0xC7, 0xE7, 0x63, 0xF3, 0xF1, 0xF9, 0xF8, 0xFE, 0xFE, 0x6F, + 0x3F, 0xF3, 0xC3, 0xF1, 0xF8, 0xF0, 0x7F, 0x80, 0x1F, 0xC0, 0x03, 0xC0, + 0x00, 0x01, 0x80, 0x0E, 0x00, 0x38, 0x01, 0xF0, 0x07, 0xC0, 0x1F, 0x00, + 0xFE, 0x03, 0xF8, 0x1C, 0xE0, 0x73, 0xC1, 0xCF, 0x0F, 0xFE, 0x3F, 0xF8, + 0xFF, 0xE7, 0x03, 0xDC, 0x0F, 0x60, 0x1D, 0x80, 0x60, 0x7F, 0x0F, 0xFC, + 0xFF, 0xCE, 0x1E, 0xE0, 0xEE, 0x0E, 0xE0, 0xCF, 0xFC, 0xFF, 0xEF, 0xFE, + 0xE1, 0xFE, 0x0F, 0xE0, 0x7E, 0x07, 0xF0, 0xEF, 0xFE, 0xFF, 0x8F, 0xF0, + 0x03, 0xF0, 0x3F, 0xF1, 0xFF, 0xCF, 0x0E, 0x70, 0x01, 0xC0, 0x06, 0x00, + 0x38, 0x00, 0xE0, 0x03, 0x80, 0x0E, 0x00, 0x3C, 0x00, 0xF0, 0x01, 0xE0, + 0x07, 0xE0, 0xCF, 0xFF, 0x1F, 0xF8, 0x1F, 0x80, 0x7F, 0x83, 0xFF, 0x8F, + 0xFF, 0x38, 0x7E, 0xE0, 0x7B, 0x80, 0xFE, 0x03, 0xF8, 0x07, 0xE0, 0x1F, + 0x80, 0x7E, 0x01, 0xF8, 0x06, 0xE0, 0x3B, 0x80, 0xEF, 0x0F, 0x3F, 0xF8, + 0xFF, 0xC3, 0xFC, 0x00, 0x7F, 0xEF, 0xFE, 0xFF, 0xCE, 0x00, 0xE0, 0x0E, + 0x00, 0xE0, 0x0F, 0xE0, 0xFE, 0x0F, 0xC0, 0xE0, 0x0E, 0x00, 0xE0, 0x0E, + 0x00, 0xE0, 0x0F, 0xFF, 0xFF, 0xFF, 0xFE, 0x7F, 0xFF, 0xFF, 0xFB, 0x80, + 0xE0, 0x38, 0x0E, 0x03, 0xF0, 0xFC, 0x3F, 0x0E, 0x03, 0x80, 0xE0, 0x38, + 0x0E, 0x03, 0x80, 0xE0, 0x30, 0x00, 0x03, 0xF0, 0x3F, 0xF1, 0xFF, 0xCF, + 0x0E, 0x70, 0x01, 0xC0, 0x06, 0x00, 0x38, 0x00, 0xE0, 0x03, 0x81, 0xFE, + 0x0F, 0xFC, 0x3F, 0xF0, 0x1D, 0xE0, 0x77, 0xE1, 0xCF, 0xFF, 0x1F, 0xFC, + 0x1F, 0xE0, 0x60, 0x1F, 0x01, 0xF8, 0x0F, 0xC0, 0x7E, 0x03, 0xF0, 0x1F, + 0x80, 0xFC, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x7E, 0x03, 0xF0, + 0x1F, 0x80, 0xFC, 0x07, 0xE0, 0x3E, 0x01, 0x80, 0x7F, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xF8, 0x00, 0x60, 0x1C, 0x03, 0x80, 0x70, 0x0E, 0x01, 0xC0, + 0x38, 0x07, 0x00, 0xE0, 0x1C, 0x03, 0x80, 0x70, 0x0E, 0x01, 0x88, 0x73, + 0xFC, 0x7F, 0x07, 0xC0, 0x60, 0x27, 0x07, 0xB8, 0x79, 0xC7, 0x8E, 0x78, + 0x77, 0x83, 0xF8, 0x1F, 0x00, 0xF0, 0x07, 0xE0, 0x3F, 0x81, 0xFE, 0x0E, + 0xF8, 0x73, 0xE3, 0x8F, 0xDC, 0x3E, 0xE0, 0xF6, 0x01, 0x80, 0x60, 0x38, + 0x0E, 0x03, 0x80, 0xE0, 0x38, 0x0E, 0x03, 0x80, 0xE0, 0x38, 0x0E, 0x03, + 0x80, 0xE0, 0x38, 0x0E, 0x03, 0xFF, 0xFF, 0xFF, 0xE0, 0x60, 0x0F, 0x80, + 0x7F, 0x01, 0xFC, 0x0F, 0xF8, 0x3F, 0xE1, 0xFF, 0x87, 0xFF, 0x1F, 0xFC, + 0xFF, 0xFB, 0xFF, 0xFD, 0xFB, 0xF7, 0xEF, 0x9F, 0x9E, 0x7E, 0x71, 0xF8, + 0xC7, 0xE0, 0x1F, 0x00, 0x60, 0x60, 0x1F, 0x81, 0xFC, 0x0F, 0xF0, 0x7F, + 0xC3, 0xFF, 0x1F, 0xF8, 0xFD, 0xE7, 0xEF, 0xBF, 0x3F, 0xF8, 0xFF, 0xC3, + 0xFE, 0x1F, 0xF0, 0x7F, 0x81, 0xFC, 0x07, 0xE0, 0x3E, 0x01, 0x80, 0x03, + 0xF0, 0x07, 0xFE, 0x07, 0xFF, 0x87, 0x87, 0xE7, 0x00, 0xF3, 0x80, 0x3F, + 0x80, 0x1F, 0xC0, 0x07, 0xE0, 0x03, 0xF0, 0x01, 0xF8, 0x00, 0xFE, 0x00, + 0x6F, 0x00, 0x73, 0xC0, 0x39, 0xF8, 0x78, 0x7F, 0xF8, 0x1F, 0xF8, 0x03, + 0xF0, 0x00, 0x7F, 0x8F, 0xFC, 0xFF, 0xEE, 0x1F, 0xE0, 0xFE, 0x07, 0xE0, + 0x7E, 0x0E, 0xFF, 0xEF, 0xFC, 0xFF, 0x0E, 0x00, 0xE0, 0x0E, 0x00, 0xE0, + 0x0E, 0x00, 0xE0, 0x0C, 0x00, 0x03, 0xF0, 0x07, 0xFE, 0x07, 0xFF, 0x87, + 0x87, 0xE7, 0x00, 0xF3, 0x80, 0x3F, 0x80, 0x1F, 0xC0, 0x07, 0xE0, 0x03, + 0xF0, 0x01, 0xF8, 0x00, 0xFE, 0x00, 0x6F, 0x00, 0x73, 0xC0, 0x39, 0xF8, + 0x78, 0x7F, 0xF8, 0x1F, 0xF8, 0x03, 0xF0, 0x00, 0x7F, 0x8F, 0xFC, 0xFF, + 0xEE, 0x1F, 0xE0, 0xFE, 0x07, 0xE0, 0x7E, 0x3E, 0xFF, 0xCF, 0xF8, 0xFE, + 0x0F, 0xF0, 0xFF, 0x8E, 0x7C, 0xE3, 0xEE, 0x1F, 0xE0, 0xFC, 0x06, 0x07, + 0xC0, 0x7F, 0xE3, 0xFF, 0x9C, 0x3E, 0x70, 0x01, 0xE0, 0x07, 0xE0, 0x1F, + 0xF8, 0x3F, 0xF0, 0x7F, 0xE0, 0x1F, 0xC0, 0x0F, 0x00, 0x1C, 0x80, 0x77, + 0x83, 0xBF, 0xFE, 0x7F, 0xF0, 0x7F, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xE0, + 0xE0, 0x0E, 0x00, 0xE0, 0x0E, 0x00, 0xE0, 0x0E, 0x00, 0xE0, 0x0E, 0x00, + 0xE0, 0x0E, 0x00, 0xE0, 0x0E, 0x00, 0xE0, 0x0E, 0x00, 0xC0, 0x60, 0x3E, + 0x07, 0xE0, 0x7E, 0x07, 0xE0, 0x7E, 0x07, 0xE0, 0x7E, 0x07, 0xE0, 0x7E, + 0x07, 0xE0, 0x7E, 0x07, 0xE0, 0x7F, 0x06, 0xF8, 0xE7, 0xFC, 0x3F, 0x81, + 0xF0, 0x60, 0x1B, 0x80, 0x6F, 0x03, 0xBC, 0x0E, 0x70, 0x31, 0xE1, 0xC7, + 0x87, 0x0E, 0x18, 0x3C, 0xE0, 0x73, 0x81, 0xCC, 0x07, 0xF0, 0x0F, 0xC0, + 0x3E, 0x00, 0xF8, 0x01, 0xC0, 0x07, 0x00, 0x18, 0x00, 0x60, 0x00, 0x7C, + 0x00, 0x0F, 0x81, 0x83, 0xF8, 0x70, 0x77, 0x0F, 0x0C, 0xE1, 0xE3, 0x9C, + 0x7C, 0x73, 0xCF, 0xCE, 0x39, 0xB9, 0x87, 0x77, 0x70, 0xFE, 0xFE, 0x0F, + 0x8F, 0x81, 0xF1, 0xF0, 0x3E, 0x3E, 0x07, 0x87, 0xC0, 0x70, 0x70, 0x0E, + 0x0E, 0x01, 0x81, 0x80, 0x60, 0x0F, 0xC0, 0x7F, 0x03, 0x9E, 0x0E, 0x7C, + 0x70, 0xFB, 0x81, 0xFC, 0x03, 0xF0, 0x0F, 0x80, 0x1F, 0x00, 0xFC, 0x03, + 0xF8, 0x1D, 0xF0, 0xE3, 0xE7, 0x07, 0x9C, 0x0F, 0xE0, 0x3F, 0x00, 0x60, + 0x60, 0x0F, 0x80, 0x7F, 0x03, 0x9E, 0x1E, 0x7C, 0xF0, 0xF3, 0x81, 0xFC, + 0x07, 0xE0, 0x0F, 0x00, 0x1C, 0x00, 0x70, 0x01, 0xC0, 0x07, 0x00, 0x1C, + 0x00, 0x70, 0x01, 0xC0, 0x07, 0x00, 0x18, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, + 0xFC, 0x00, 0xE0, 0x0E, 0x00, 0xE0, 0x07, 0x00, 0x70, 0x07, 0x00, 0x38, + 0x03, 0x80, 0x38, 0x01, 0xC0, 0x1C, 0x01, 0xC0, 0x0F, 0xFF, 0xFF, 0xFF, + 0xFF, 0x80, 0x7F, 0xFF, 0xF8, 0xE3, 0x8E, 0x38, 0xE3, 0x8E, 0x38, 0xE3, + 0x8E, 0x38, 0xE3, 0x8E, 0x3F, 0xFF, 0xF0, 0x60, 0xE0, 0xE0, 0xF0, 0x70, + 0x70, 0x78, 0x38, 0x3C, 0x3C, 0x1C, 0x1E, 0x0E, 0x0E, 0x0F, 0x07, 0x07, + 0x06, 0xFF, 0xFF, 0xC7, 0x1C, 0x71, 0xC7, 0x1C, 0x71, 0xC7, 0x1C, 0x71, + 0xC7, 0x1C, 0x71, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0xC0, 0x3C, 0x0F, 0xC1, + 0xF8, 0x77, 0x8C, 0xF3, 0x8F, 0xE0, 0xF8, 0x18, 0x7F, 0xFF, 0xFF, 0xF8, + 0x03, 0x8F, 0x3E, 0x78, 0x70, 0xC0, 0x1F, 0x0F, 0xE7, 0xFD, 0x8F, 0x01, + 0xC7, 0xF3, 0xFD, 0xFF, 0xF1, 0xF8, 0x7F, 0x1F, 0xFF, 0x7F, 0xCF, 0xE0, + 0x60, 0x1C, 0x03, 0x80, 0x70, 0x0E, 0x01, 0xFE, 0x3F, 0xE7, 0xFE, 0xE3, + 0xDC, 0x3F, 0x83, 0xF0, 0x7E, 0x0F, 0xC1, 0xF8, 0x37, 0x8E, 0xFF, 0x9F, + 0xE3, 0xF8, 0x00, 0x07, 0xC3, 0xFC, 0xFF, 0xB8, 0x66, 0x01, 0xC0, 0x38, + 0x07, 0x00, 0xF0, 0x1E, 0x01, 0xE1, 0xBF, 0xF3, 0xFC, 0x1F, 0x00, 0x00, + 0x60, 0x1C, 0x03, 0x80, 0x70, 0x0E, 0x1F, 0xC7, 0xF9, 0xFF, 0x71, 0xEC, + 0x1F, 0x83, 0xF0, 0x7E, 0x0F, 0xC1, 0xFC, 0x3F, 0xC7, 0x7F, 0xE7, 0xFC, + 0x7F, 0x00, 0x07, 0xC3, 0xFC, 0xFF, 0xB8, 0x76, 0x0F, 0xC3, 0xFF, 0xF7, + 0xFC, 0xFF, 0x1F, 0x01, 0xE1, 0xBF, 0xF3, 0xFC, 0x3F, 0x00, 0x0F, 0x07, + 0xE3, 0xF8, 0xC6, 0x70, 0x1C, 0x07, 0x01, 0xF8, 0xFE, 0x3F, 0x07, 0x01, + 0xC0, 0x70, 0x1C, 0x07, 0x01, 0xC0, 0x70, 0x1C, 0x06, 0x00, 0x0F, 0xE3, + 0xFC, 0xFF, 0xB8, 0xF6, 0x0F, 0xC1, 0xF8, 0x3F, 0x07, 0xE0, 0xFE, 0x1F, + 0xE3, 0xBF, 0xF3, 0xFE, 0x3F, 0xC0, 0x31, 0x8E, 0x7F, 0x8F, 0xE0, 0xF8, + 0x00, 0x60, 0x1C, 0x03, 0x80, 0x70, 0x0E, 0x01, 0xDF, 0x3F, 0xF7, 0xFF, + 0xF1, 0xFC, 0x1F, 0x83, 0xF0, 0x7E, 0x0F, 0xC1, 0xF8, 0x3F, 0x07, 0xE0, + 0xFC, 0x1F, 0x03, 0x00, 0xFF, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, + 0x00, 0xC0, 0x70, 0x1C, 0x07, 0x00, 0x00, 0x30, 0x1C, 0x07, 0x01, 0xC0, + 0x70, 0x1C, 0x07, 0x01, 0xC0, 0x70, 0x1C, 0x07, 0x01, 0xC0, 0x70, 0x1C, + 0x06, 0x63, 0xBF, 0xCF, 0xE1, 0xF0, 0x60, 0x1C, 0x03, 0x80, 0x70, 0x0E, + 0x01, 0xC3, 0x39, 0xE7, 0x7C, 0xFE, 0x1F, 0x83, 0xE0, 0x7E, 0x0F, 0xE1, + 0xFE, 0x3B, 0xE7, 0x3E, 0xE3, 0xFC, 0x3F, 0x03, 0x00, 0x7F, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x6E, 0x39, 0xFF, 0xFB, 0xFF, 0xFF, 0xBE, + 0xFE, 0x38, 0xFC, 0x71, 0xF8, 0xE3, 0xF1, 0xC7, 0xE3, 0x8F, 0xC7, 0x1F, + 0x8E, 0x3F, 0x1C, 0x7E, 0x38, 0xF8, 0x61, 0x80, 0x6F, 0x9F, 0xFB, 0xFF, + 0xF8, 0xFE, 0x0F, 0xC1, 0xF8, 0x3F, 0x07, 0xE0, 0xFC, 0x1F, 0x83, 0xF0, + 0x7E, 0x0F, 0x81, 0x80, 0x07, 0x80, 0xFF, 0x0F, 0xFC, 0xE1, 0xE6, 0x07, + 0xF0, 0x1F, 0x80, 0xFC, 0x07, 0xE0, 0x3F, 0x81, 0x9E, 0x1C, 0xFF, 0xC3, + 0xFC, 0x07, 0x80, 0x7F, 0x1F, 0xF3, 0xFF, 0x71, 0xFE, 0x1F, 0xC1, 0xF8, + 0x3F, 0x07, 0xE0, 0xFC, 0x1B, 0xC7, 0x7F, 0xCF, 0xF1, 0xFC, 0x38, 0x07, + 0x00, 0xE0, 0x1C, 0x03, 0x00, 0x00, 0x0F, 0xE3, 0xFC, 0xFF, 0xBC, 0xF6, + 0x0F, 0xC1, 0xF8, 0x3F, 0x07, 0xF0, 0xFE, 0x1D, 0xF3, 0xBF, 0xF3, 0xFE, + 0x3F, 0xC0, 0x38, 0x07, 0x00, 0xE0, 0x1C, 0x03, 0x00, 0x0F, 0x9F, 0xEF, + 0xFB, 0xC6, 0xE0, 0x38, 0x0E, 0x03, 0x80, 0xE0, 0x38, 0x0E, 0x03, 0x80, + 0xE0, 0x30, 0x00, 0x1F, 0x07, 0xF8, 0xFF, 0x38, 0xC7, 0x80, 0xFF, 0x1F, + 0xF1, 0xFF, 0x07, 0xE0, 0x1D, 0xC3, 0xBF, 0xE7, 0xF8, 0x7E, 0x00, 0x30, + 0x1C, 0x07, 0x01, 0xC0, 0x70, 0x1C, 0x07, 0xFB, 0xFE, 0xFF, 0x1C, 0x07, + 0x01, 0xC0, 0x70, 0x1C, 0x07, 0x8C, 0xFF, 0x3F, 0x87, 0xC0, 0x60, 0x7C, + 0x1F, 0x83, 0xF0, 0x7E, 0x0F, 0xC1, 0xF8, 0x3F, 0x07, 0xE0, 0xFC, 0x1F, + 0xC7, 0xFF, 0xF7, 0xFE, 0x7D, 0x80, 0x60, 0x7C, 0x1F, 0xC3, 0x78, 0xE7, + 0x1C, 0xF7, 0x1E, 0xE1, 0xD8, 0x3F, 0x03, 0xE0, 0x78, 0x0F, 0x00, 0xE0, + 0x18, 0x00, 0x60, 0x07, 0xC3, 0x1F, 0x8E, 0x3F, 0x9C, 0x67, 0x3D, 0xCE, + 0xFB, 0x9D, 0xF6, 0x3F, 0xFC, 0x3E, 0xF8, 0x7D, 0xF0, 0xF3, 0xC0, 0xE7, + 0x81, 0xC7, 0x03, 0x0C, 0x00, 0x60, 0x7E, 0x1F, 0xC7, 0x3C, 0xE7, 0xF8, + 0x7E, 0x07, 0x80, 0x78, 0x1F, 0x87, 0xF9, 0xCF, 0x38, 0xFE, 0x1F, 0x81, + 0x80, 0x60, 0x6E, 0x1D, 0xC3, 0xB8, 0x67, 0x9C, 0x73, 0x8E, 0x61, 0xFC, + 0x1F, 0x03, 0xE0, 0x7C, 0x07, 0x00, 0xE0, 0x1C, 0x03, 0x03, 0xE0, 0xFC, + 0x1F, 0x01, 0xC0, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0x01, 0xE0, 0x38, 0x0E, + 0x03, 0x80, 0x70, 0x1C, 0x07, 0x01, 0xE0, 0x3F, 0xFF, 0xFF, 0xFF, 0x80, + 0x0C, 0x38, 0x71, 0xC3, 0x87, 0x0E, 0x1C, 0x38, 0x61, 0xC3, 0xC7, 0x87, + 0x0E, 0x1C, 0x38, 0x70, 0xF1, 0xE1, 0xC1, 0x80, 0x7F, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x61, 0xE3, 0xE3, 0xC3, 0x87, 0x0E, 0x1C, + 0x38, 0x78, 0xF0, 0xE1, 0xC7, 0x0E, 0x1C, 0x38, 0x70, 0xE3, 0x8F, 0x1C, + 0x00, 0x00, 0x3C, 0x0F, 0xFD, 0xFF, 0xF7, 0xE0, 0x38 }; + +const GFXglyph aAntiCorona12pt7bGlyphs[] PROGMEM = { + { 0, 1, 1, 6, 0, 0 }, // 0x20 ' ' + { 1, 3, 19, 5, 1, -16 }, // 0x21 '!' + { 9, 7, 6, 11, 2, -16 }, // 0x22 '"' + { 15, 14, 17, 16, 1, -14 }, // 0x23 '#' + { 45, 12, 18, 14, 1, -15 }, // 0x24 '$' + { 72, 20, 18, 21, 1, -15 }, // 0x25 '%' + { 117, 13, 18, 15, 1, -15 }, // 0x26 '&' + { 147, 3, 6, 7, 2, -16 }, // 0x27 ''' + { 150, 7, 22, 9, 1, -16 }, // 0x28 '(' + { 170, 8, 22, 9, 0, -16 }, // 0x29 ')' + { 192, 11, 11, 13, 1, -17 }, // 0x2A '*' + { 208, 10, 10, 12, 1, -11 }, // 0x2B '+' + { 221, 4, 6, 6, 1, -1 }, // 0x2C ',' + { 224, 10, 3, 12, 1, -5 }, // 0x2D '-' + { 228, 3, 4, 5, 1, -1 }, // 0x2E '.' + { 230, 8, 18, 10, 1, -15 }, // 0x2F '/' + { 248, 14, 18, 16, 1, -15 }, // 0x30 '0' + { 280, 5, 18, 6, 0, -15 }, // 0x31 '1' + { 292, 12, 18, 13, 1, -15 }, // 0x32 '2' + { 319, 11, 18, 12, 0, -15 }, // 0x33 '3' + { 344, 11, 18, 13, 1, -15 }, // 0x34 '4' + { 369, 11, 18, 13, 1, -15 }, // 0x35 '5' + { 394, 13, 18, 15, 1, -15 }, // 0x36 '6' + { 424, 11, 18, 11, 0, -15 }, // 0x37 '7' + { 449, 11, 18, 13, 1, -15 }, // 0x38 '8' + { 474, 13, 18, 14, 1, -15 }, // 0x39 '9' + { 504, 3, 12, 5, 1, -9 }, // 0x3A ':' + { 509, 3, 14, 5, 1, -9 }, // 0x3B ';' + { 515, 13, 11, 15, 1, -11 }, // 0x3C '<' + { 533, 10, 8, 13, 1, -10 }, // 0x3D '=' + { 543, 13, 11, 15, 1, -11 }, // 0x3E '>' + { 561, 11, 18, 12, 0, -15 }, // 0x3F '?' + { 586, 17, 18, 19, 1, -15 }, // 0x40 '@' + { 625, 14, 18, 14, -1, -15 }, // 0x41 'A' + { 657, 12, 18, 14, 1, -15 }, // 0x42 'B' + { 684, 14, 18, 16, 1, -15 }, // 0x43 'C' + { 716, 14, 18, 16, 1, -15 }, // 0x44 'D' + { 748, 12, 18, 14, 1, -15 }, // 0x45 'E' + { 775, 10, 18, 11, 1, -15 }, // 0x46 'F' + { 798, 14, 18, 16, 1, -15 }, // 0x47 'G' + { 830, 13, 18, 15, 1, -15 }, // 0x48 'H' + { 860, 3, 18, 5, 1, -15 }, // 0x49 'I' + { 867, 11, 18, 11, -1, -15 }, // 0x4A 'J' + { 892, 13, 18, 14, 1, -15 }, // 0x4B 'K' + { 922, 10, 18, 11, 1, -15 }, // 0x4C 'L' + { 945, 14, 18, 16, 1, -15 }, // 0x4D 'M' + { 977, 13, 18, 15, 1, -15 }, // 0x4E 'N' + { 1007, 17, 18, 19, 1, -15 }, // 0x4F 'O' + { 1046, 12, 18, 14, 1, -15 }, // 0x50 'P' + { 1073, 17, 18, 19, 1, -15 }, // 0x51 'Q' + { 1112, 12, 18, 14, 1, -15 }, // 0x52 'R' + { 1139, 14, 18, 15, 0, -15 }, // 0x53 'S' + { 1171, 12, 18, 14, 1, -15 }, // 0x54 'T' + { 1198, 12, 18, 14, 1, -15 }, // 0x55 'U' + { 1225, 14, 18, 14, 0, -15 }, // 0x56 'V' + { 1257, 19, 18, 20, 1, -15 }, // 0x57 'W' + { 1300, 14, 18, 16, 1, -15 }, // 0x58 'X' + { 1332, 14, 18, 16, 1, -15 }, // 0x59 'Y' + { 1364, 13, 18, 15, 1, -15 }, // 0x5A 'Z' + { 1394, 6, 22, 8, 1, -16 }, // 0x5B '[' + { 1411, 8, 18, 10, 1, -15 }, // 0x5C '\' + { 1429, 6, 22, 7, 0, -16 }, // 0x5D ']' + { 1446, 11, 10, 12, 0, -16 }, // 0x5E '^' + { 1460, 10, 3, 12, 1, 2 }, // 0x5F '_' + { 1464, 6, 7, 8, 1, -15 }, // 0x60 '`' + { 1470, 10, 14, 12, 1, -11 }, // 0x61 'a' + { 1488, 11, 19, 13, 1, -16 }, // 0x62 'b' + { 1515, 11, 14, 13, 1, -11 }, // 0x63 'c' + { 1535, 11, 19, 13, 1, -16 }, // 0x64 'd' + { 1562, 11, 14, 13, 1, -11 }, // 0x65 'e' + { 1582, 10, 19, 9, 1, -16 }, // 0x66 'f' + { 1606, 11, 19, 13, 1, -11 }, // 0x67 'g' + { 1633, 11, 19, 13, 1, -16 }, // 0x68 'h' + { 1660, 3, 19, 5, 1, -16 }, // 0x69 'i' + { 1668, 10, 24, 5, -6, -16 }, // 0x6A 'j' + { 1698, 11, 19, 13, 1, -16 }, // 0x6B 'k' + { 1725, 3, 19, 5, 1, -16 }, // 0x6C 'l' + { 1733, 15, 14, 17, 1, -11 }, // 0x6D 'm' + { 1760, 11, 14, 13, 1, -11 }, // 0x6E 'n' + { 1780, 13, 14, 15, 1, -11 }, // 0x6F 'o' + { 1803, 11, 19, 13, 1, -11 }, // 0x70 'p' + { 1830, 11, 19, 13, 1, -11 }, // 0x71 'q' + { 1857, 10, 14, 11, 1, -11 }, // 0x72 'r' + { 1875, 11, 14, 12, 0, -11 }, // 0x73 's' + { 1895, 10, 18, 12, 1, -15 }, // 0x74 't' + { 1918, 11, 14, 13, 1, -11 }, // 0x75 'u' + { 1938, 11, 14, 12, 1, -11 }, // 0x76 'v' + { 1958, 15, 14, 16, 1, -11 }, // 0x77 'w' + { 1985, 11, 14, 13, 1, -11 }, // 0x78 'x' + { 2005, 11, 19, 13, 1, -11 }, // 0x79 'y' + { 2032, 11, 14, 13, 1, -11 }, // 0x7A 'z' + { 2052, 7, 22, 7, 0, -16 }, // 0x7B '{' + { 2072, 3, 24, 5, 1, -16 }, // 0x7C '|' + { 2081, 7, 23, 8, 1, -16 }, // 0x7D '}' + { 2102, 11, 5, 13, 1, -7 } }; // 0x7E '~' + +const GFXfont aAntiCorona12pt7b PROGMEM = { + (uint8_t *)aAntiCorona12pt7bBitmaps, + (GFXglyph *)aAntiCorona12pt7bGlyphs, + 0x20, 0x7E, 26 }; + +// Approx. 2781 bytes diff --git a/src/aAntiCorona15pt7b.h b/src/aAntiCorona15pt7b.h new file mode 100644 index 0000000..0d3ee3a --- /dev/null +++ b/src/aAntiCorona15pt7b.h @@ -0,0 +1,373 @@ +const uint8_t aAntiCorona15pt7bBitmaps[] PROGMEM = { + 0x00, 0x37, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x60, 0x06, 0xFF, + 0x60, 0x61, 0xF1, 0xF9, 0xFC, 0x7E, 0x3F, 0x19, 0x8C, 0x86, 0x00, 0x00, + 0x00, 0x70, 0xE0, 0x1C, 0x78, 0x0F, 0x1C, 0x03, 0xC7, 0x00, 0xE3, 0xC3, + 0xFF, 0xFD, 0xFF, 0xFF, 0x7F, 0xFF, 0xDF, 0xFF, 0xE0, 0xE3, 0xC0, 0x78, + 0xE0, 0x7F, 0xFF, 0xBF, 0xFF, 0xEF, 0xFF, 0xFB, 0xFF, 0xFC, 0x78, 0xE0, + 0x1E, 0x78, 0x07, 0x1E, 0x03, 0xC7, 0x00, 0x61, 0x80, 0x00, 0x01, 0x80, + 0x0F, 0x80, 0x7F, 0xE1, 0xFF, 0xE3, 0xFF, 0xCF, 0xFF, 0x1F, 0xE4, 0x3F, + 0xC0, 0x7F, 0x80, 0xFF, 0xE0, 0xFF, 0xE0, 0xFF, 0xE0, 0x7F, 0xE0, 0xF7, + 0xC1, 0xE7, 0x93, 0xCF, 0x7F, 0xBE, 0xFF, 0xF9, 0xFF, 0xE1, 0xFF, 0x80, + 0xF8, 0x00, 0xE0, 0x00, 0x0F, 0x00, 0x60, 0x0F, 0xE0, 0x38, 0x07, 0xFC, + 0x1E, 0x01, 0xC7, 0x87, 0x80, 0xE1, 0xE3, 0xC0, 0x38, 0x38, 0xE0, 0x0E, + 0x0E, 0x78, 0x03, 0x83, 0x9C, 0x00, 0xF0, 0xEF, 0x1E, 0x3E, 0x73, 0x9F, + 0xC7, 0xFD, 0xE7, 0xF8, 0xFE, 0x73, 0x9E, 0x1E, 0x3D, 0xC3, 0xC0, 0x0E, + 0x70, 0x70, 0x07, 0x1C, 0x1C, 0x03, 0xC7, 0x07, 0x00, 0xE1, 0xC1, 0xC0, + 0x78, 0x78, 0x70, 0x1C, 0x0F, 0x38, 0x0F, 0x03, 0xFC, 0x03, 0x80, 0x7F, + 0x00, 0xC0, 0x0F, 0x00, 0x07, 0xC0, 0x1F, 0xE0, 0x3F, 0xF0, 0x3F, 0xF0, + 0x79, 0xF0, 0x78, 0xF0, 0x78, 0xF0, 0x7D, 0xE0, 0x7F, 0xE0, 0x3F, 0xC0, + 0x3F, 0x80, 0x1F, 0x00, 0x3F, 0x9C, 0x7F, 0xFC, 0xF3, 0xFC, 0xF1, 0xFC, + 0xF0, 0xFE, 0xF8, 0x7F, 0xFF, 0xFF, 0x7F, 0xFF, 0x3F, 0xEE, 0x1F, 0x80, + 0x7F, 0xFF, 0xDA, 0x03, 0x87, 0xC7, 0xE3, 0xE3, 0xC1, 0xC1, 0xE0, 0xF0, + 0x70, 0x78, 0x3C, 0x1E, 0x0F, 0x07, 0x83, 0xC1, 0xE0, 0xF0, 0x78, 0x3E, + 0x1F, 0x07, 0x83, 0xE1, 0xF0, 0x7C, 0x3F, 0x8F, 0xC7, 0xE0, 0xE0, 0x38, + 0x1F, 0x07, 0xE1, 0xFC, 0x1F, 0x03, 0xE0, 0xF8, 0x1E, 0x07, 0xC1, 0xF0, + 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x38, 0x1E, + 0x07, 0x81, 0xE0, 0xF0, 0x3C, 0x3E, 0x1F, 0x07, 0x81, 0xC0, 0x03, 0x80, + 0x3C, 0x01, 0xE0, 0xEF, 0x0F, 0xFF, 0xFF, 0xFD, 0xFF, 0xC3, 0xFC, 0x1F, + 0xC1, 0xFF, 0x0E, 0x78, 0x63, 0xC0, 0x0C, 0x00, 0x07, 0x00, 0x78, 0x03, + 0xC0, 0x1E, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x0F, 0x00, 0x78, + 0x03, 0xC0, 0x1E, 0x00, 0xE0, 0x00, 0x77, 0xBC, 0xE7, 0x31, 0x00, 0x7F, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x6F, 0xF6, 0x00, 0xC0, 0x70, 0x1C, + 0x0F, 0x03, 0x80, 0xE0, 0x78, 0x1C, 0x0F, 0x03, 0x80, 0xE0, 0x78, 0x1C, + 0x07, 0x03, 0xC0, 0xE0, 0x38, 0x1E, 0x07, 0x03, 0xC0, 0xE0, 0x38, 0x00, + 0x01, 0xF0, 0x01, 0xFF, 0x00, 0xFF, 0xE0, 0x7F, 0xFC, 0x3E, 0x3F, 0x9E, + 0x03, 0xE7, 0x80, 0xF9, 0xC0, 0x1F, 0xF0, 0x07, 0xFC, 0x00, 0xFF, 0x00, + 0x3F, 0xC0, 0x0F, 0xF0, 0x03, 0xFE, 0x00, 0xFF, 0x80, 0x39, 0xF0, 0x1E, + 0x7C, 0x07, 0x1F, 0xC7, 0xC3, 0xFF, 0xE0, 0x7F, 0xF0, 0x0F, 0xF8, 0x00, + 0xF8, 0x00, 0x0E, 0x3C, 0xFB, 0xFF, 0xFF, 0xD7, 0x8F, 0x1E, 0x3C, 0x78, + 0xF1, 0xE3, 0xC7, 0x8F, 0x1E, 0x3C, 0x78, 0xF1, 0xE3, 0x80, 0x0F, 0xC0, + 0xFF, 0xE1, 0xFF, 0xE7, 0xFF, 0xC6, 0x0F, 0xC0, 0x0F, 0x80, 0x0F, 0x00, + 0x1E, 0x00, 0x38, 0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x80, 0x3E, 0x00, 0xF0, + 0x03, 0xC0, 0x0F, 0x00, 0x3C, 0x00, 0x70, 0x01, 0xFF, 0xF3, 0xFF, 0xEF, + 0xFF, 0xCF, 0xFF, 0x00, 0x0F, 0x80, 0xFF, 0x87, 0xFF, 0x1F, 0xFE, 0x61, + 0xF8, 0x03, 0xE0, 0x07, 0x80, 0x1E, 0x00, 0xF0, 0x3F, 0x81, 0xFF, 0x07, + 0xFE, 0x1F, 0xF8, 0x03, 0xF0, 0x07, 0xC0, 0x0F, 0x00, 0x3C, 0xC1, 0xE7, + 0xFF, 0x9F, 0xFC, 0x7F, 0xE0, 0xFE, 0x00, 0x00, 0x60, 0x03, 0xC0, 0x0E, + 0x00, 0x78, 0x03, 0xC0, 0x0E, 0x00, 0x79, 0xC3, 0xCF, 0x0E, 0x3C, 0x78, + 0xF1, 0xC3, 0xCE, 0x0F, 0x78, 0x3D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFC, 0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x3C, 0x00, 0xE0, 0x3F, 0xF9, + 0xFF, 0xE7, 0xFF, 0x9F, 0xFC, 0x78, 0x01, 0xE0, 0x07, 0x80, 0x1F, 0xF0, + 0x7F, 0xF1, 0xFF, 0xE7, 0xFF, 0x80, 0x7F, 0x00, 0x7C, 0x00, 0xF0, 0x03, + 0xC0, 0x0F, 0x00, 0x3C, 0x81, 0xEF, 0xFF, 0x3F, 0xFC, 0xFF, 0xC0, 0xFC, + 0x00, 0x01, 0xF0, 0x07, 0xF8, 0x0F, 0xFC, 0x1F, 0xFC, 0x3C, 0x3C, 0x38, + 0x18, 0x78, 0x00, 0x71, 0xF0, 0x77, 0xFC, 0x7F, 0xFE, 0x7F, 0xFE, 0xFC, + 0x3F, 0x78, 0x1F, 0x78, 0x0F, 0x78, 0x0F, 0x78, 0x0F, 0x7C, 0x0E, 0x3E, + 0x1E, 0x3F, 0xFC, 0x1F, 0xFC, 0x0F, 0xF0, 0x03, 0xE0, 0x7F, 0xFF, 0xFF, + 0xFF, 0xFF, 0xBF, 0xFE, 0x00, 0x78, 0x01, 0xC0, 0x07, 0x00, 0x3C, 0x00, + 0xE0, 0x07, 0x80, 0x1C, 0x00, 0x70, 0x03, 0xC0, 0x0E, 0x00, 0x78, 0x01, + 0xC0, 0x07, 0x00, 0x3C, 0x00, 0xE0, 0x07, 0x80, 0x1C, 0x00, 0x70, 0x00, + 0x0F, 0x80, 0xFF, 0x87, 0xFE, 0x1F, 0xFC, 0xF1, 0xF3, 0xC3, 0xCF, 0x0F, + 0x3E, 0x3C, 0xFE, 0xE1, 0xFF, 0x87, 0xFF, 0x1F, 0xFE, 0x7F, 0xFF, 0xC3, + 0xFF, 0x03, 0xFC, 0x0F, 0xF0, 0x3F, 0xF0, 0xEF, 0xFF, 0x9F, 0xFC, 0x3F, + 0xE0, 0x7E, 0x00, 0x07, 0xC0, 0x0F, 0xF0, 0x3F, 0xF8, 0x3F, 0xFC, 0x78, + 0x7C, 0x70, 0x3E, 0xF0, 0x1E, 0xF0, 0x1E, 0xF0, 0x1E, 0xF8, 0x1E, 0xFC, + 0x3F, 0x7F, 0xFE, 0x7F, 0xFE, 0x3F, 0xEE, 0x0F, 0x8E, 0x00, 0x1E, 0x18, + 0x1C, 0x3C, 0x3C, 0x3F, 0xF8, 0x3F, 0xF0, 0x1F, 0xE0, 0x0F, 0x80, 0x6F, + 0xF6, 0x00, 0x00, 0x00, 0x06, 0xFF, 0x60, 0x6F, 0xF6, 0x00, 0x00, 0x00, + 0x6F, 0xF7, 0x66, 0xC0, 0x00, 0x03, 0x00, 0x0F, 0x80, 0x1F, 0xC0, 0x7F, + 0xC1, 0xFF, 0x83, 0xFE, 0x03, 0xFC, 0x01, 0xFF, 0x00, 0xFF, 0xF0, 0x1F, + 0xFE, 0x01, 0xFF, 0xC0, 0x3F, 0xE0, 0x03, 0xF0, 0x00, 0x70, 0x7F, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFC, 0x70, 0x00, 0x7F, 0x00, 0x3F, 0xE0, 0x1F, 0xFE, + 0x03, 0xFF, 0xC0, 0x3F, 0xF8, 0x07, 0xFC, 0x00, 0xFE, 0x03, 0xFE, 0x0F, + 0xFC, 0x1F, 0xF0, 0x1F, 0xE0, 0x0F, 0x80, 0x07, 0x00, 0x00, 0x0F, 0xC1, + 0xFF, 0xC7, 0xFF, 0xBF, 0xFE, 0x60, 0xFC, 0x01, 0xF0, 0x03, 0xC0, 0x0F, + 0x00, 0x38, 0x01, 0xE0, 0x0F, 0x00, 0x78, 0x03, 0xC0, 0x1E, 0x00, 0x70, + 0x03, 0xC0, 0x06, 0x00, 0x00, 0x00, 0x60, 0x03, 0xC0, 0x0F, 0x00, 0x18, + 0x00, 0x00, 0xFC, 0x00, 0x1F, 0xFC, 0x03, 0xFF, 0xF0, 0x3F, 0xFF, 0xC1, + 0xE0, 0xFF, 0x1E, 0x01, 0xF9, 0xE1, 0xF7, 0xEE, 0x1F, 0x9F, 0xF1, 0xFC, + 0xFF, 0x9F, 0xE3, 0xFC, 0xF7, 0x1F, 0xE7, 0xB8, 0xFF, 0x3F, 0xC7, 0xFD, + 0xFE, 0x3F, 0xE7, 0xF9, 0xCF, 0x9F, 0xFE, 0x7E, 0x1F, 0xE1, 0xFC, 0x7E, + 0x0F, 0xFD, 0xE0, 0x3F, 0xF0, 0x00, 0x7F, 0x00, 0x00, 0xF0, 0x00, 0x00, + 0xC0, 0x00, 0xF0, 0x00, 0x78, 0x00, 0x7C, 0x00, 0x3F, 0x00, 0x1F, 0x80, + 0x1F, 0xC0, 0x0F, 0xF0, 0x0F, 0x78, 0x07, 0xBE, 0x03, 0x9F, 0x03, 0xC7, + 0x81, 0xE3, 0xE0, 0xFF, 0xF0, 0xFF, 0xF8, 0x7F, 0xFE, 0x3F, 0xFF, 0x3C, + 0x07, 0x9C, 0x03, 0xFE, 0x00, 0xFE, 0x00, 0x7F, 0x00, 0x18, 0x7F, 0xC1, + 0xFF, 0xC3, 0xFF, 0xC7, 0xFF, 0xCF, 0x0F, 0x9E, 0x07, 0x3C, 0x0E, 0x78, + 0x1C, 0xF0, 0x39, 0xFF, 0xE3, 0xFF, 0xC7, 0xFF, 0xEF, 0xFF, 0xFE, 0x0F, + 0xFC, 0x0F, 0xF8, 0x0F, 0xF0, 0x1F, 0xF0, 0x7B, 0xFF, 0xF7, 0xFF, 0xCF, + 0xFF, 0x1F, 0xF0, 0x00, 0x00, 0xFC, 0x01, 0xFF, 0x83, 0xFF, 0xE3, 0xFF, + 0xF3, 0xE0, 0x71, 0xE0, 0x01, 0xE0, 0x00, 0xF0, 0x00, 0xF0, 0x00, 0x78, + 0x00, 0x3C, 0x00, 0x1E, 0x00, 0x0F, 0x00, 0x07, 0xC0, 0x03, 0xE0, 0x00, + 0xF8, 0x00, 0x7E, 0x00, 0x1F, 0xC1, 0xCF, 0xFF, 0xE3, 0xFF, 0xE0, 0x7F, + 0xE0, 0x0F, 0xC0, 0x77, 0xE0, 0x7F, 0xFC, 0x3F, 0xFF, 0x1F, 0xFF, 0xCF, + 0x0F, 0xF7, 0x81, 0xFB, 0xC0, 0x7F, 0xE0, 0x1F, 0xF0, 0x0F, 0xF8, 0x03, + 0xFC, 0x01, 0xFE, 0x00, 0xFF, 0x00, 0x7F, 0x80, 0x3F, 0xC0, 0x1D, 0xE0, + 0x1E, 0xF0, 0x1E, 0x7C, 0x1F, 0x3F, 0xFF, 0x1F, 0xFF, 0x0F, 0xFE, 0x07, + 0xFC, 0x00, 0x7F, 0xF9, 0xFF, 0xF3, 0xFF, 0xE7, 0xFF, 0x8F, 0x00, 0x1E, + 0x00, 0x3C, 0x00, 0x78, 0x00, 0xF0, 0x01, 0xFE, 0x03, 0xFC, 0x07, 0xF8, + 0x0F, 0xE0, 0x1E, 0x00, 0x3C, 0x00, 0x78, 0x00, 0xF0, 0x01, 0xE0, 0x03, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x7F, 0xF7, 0xFF, 0xBF, + 0xFD, 0xFF, 0xCF, 0x00, 0x78, 0x03, 0xC0, 0x1E, 0x00, 0xF0, 0x07, 0xF8, + 0x3F, 0xC1, 0xFE, 0x0F, 0xE0, 0x78, 0x03, 0xC0, 0x1E, 0x00, 0xF0, 0x07, + 0x80, 0x3C, 0x01, 0xE0, 0x0F, 0x00, 0x70, 0x00, 0x00, 0xFC, 0x01, 0xFF, + 0x83, 0xFF, 0xE3, 0xFF, 0xF1, 0xE0, 0xF1, 0xE0, 0x01, 0xE0, 0x00, 0xF0, + 0x00, 0xF0, 0x00, 0x78, 0x00, 0x3C, 0x00, 0x1E, 0x07, 0xFF, 0x03, 0xFF, + 0xC3, 0xFF, 0xE1, 0xFF, 0xF8, 0x0F, 0x7E, 0x07, 0xBF, 0xC3, 0xCF, 0xFF, + 0xE3, 0xFF, 0xF0, 0xFF, 0xF8, 0x0F, 0xB8, 0x70, 0x07, 0xF0, 0x0F, 0xF0, + 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, + 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x0F, 0xF0, + 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, + 0x0F, 0xE0, 0x0E, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFE, 0x00, 0x38, 0x03, 0xC0, 0x1E, 0x00, 0xF0, 0x07, 0x80, 0x3C, + 0x01, 0xE0, 0x0F, 0x00, 0x78, 0x03, 0xC0, 0x1E, 0x00, 0xF0, 0x07, 0x80, + 0x3C, 0x01, 0xE0, 0x0F, 0x00, 0xF3, 0x87, 0xBF, 0xF9, 0xFF, 0x8F, 0xF8, + 0x1F, 0x00, 0x70, 0x0C, 0xF0, 0x1C, 0xF0, 0x3C, 0xF0, 0x78, 0xF0, 0xF0, + 0xF1, 0xE0, 0xF7, 0xC0, 0xFF, 0x80, 0xFF, 0x00, 0xFE, 0x00, 0xFC, 0x00, + 0xFE, 0x00, 0xFF, 0x00, 0xFF, 0x80, 0xFF, 0xE0, 0xF7, 0xF0, 0xF3, 0xF8, + 0xF1, 0xFC, 0xF0, 0x7E, 0xF0, 0x3E, 0xF0, 0x1E, 0xE0, 0x0C, 0x70, 0x07, + 0x80, 0x3C, 0x01, 0xE0, 0x0F, 0x00, 0x78, 0x03, 0xC0, 0x1E, 0x00, 0xF0, + 0x07, 0x80, 0x3C, 0x01, 0xE0, 0x0F, 0x00, 0x78, 0x03, 0xC0, 0x1E, 0x00, + 0xF0, 0x07, 0x80, 0x3F, 0xFD, 0xFF, 0xEF, 0xFF, 0x7F, 0xF0, 0x60, 0x01, + 0xF8, 0x01, 0xFC, 0x01, 0xFF, 0x00, 0xFF, 0x80, 0xFF, 0xE0, 0x7F, 0xF0, + 0x3F, 0xF8, 0x3F, 0xFE, 0x1F, 0xFF, 0x1F, 0xFF, 0xCF, 0xFF, 0xEF, 0xFF, + 0xF7, 0x7F, 0xBF, 0xBF, 0xDF, 0x9F, 0xEF, 0xCF, 0xF3, 0xE7, 0xF9, 0xE3, + 0xFC, 0x71, 0xFE, 0x30, 0xFF, 0x00, 0x7F, 0x00, 0x38, 0x60, 0x07, 0xF0, + 0x0F, 0xF8, 0x0F, 0xFC, 0x0F, 0xFC, 0x0F, 0xFE, 0x0F, 0xFF, 0x0F, 0xFF, + 0x8F, 0xFF, 0x8F, 0xF7, 0xCF, 0xF3, 0xEF, 0xF3, 0xFF, 0xF1, 0xFF, 0xF0, + 0xFF, 0xF0, 0x7F, 0xF0, 0x7F, 0xF0, 0x3F, 0xF0, 0x1F, 0xF0, 0x1F, 0xF0, + 0x0F, 0xF0, 0x0F, 0xE0, 0x0E, 0x00, 0xFE, 0x00, 0x1F, 0xFC, 0x03, 0xFF, + 0xF0, 0x3F, 0xFF, 0xC3, 0xE0, 0xFF, 0x1E, 0x01, 0xF9, 0xE0, 0x07, 0xEF, + 0x00, 0x1F, 0xF0, 0x00, 0xFF, 0x80, 0x03, 0xFC, 0x00, 0x1F, 0xE0, 0x00, + 0xFF, 0x00, 0x07, 0xFC, 0x00, 0x3F, 0xE0, 0x03, 0xCF, 0x80, 0x1E, 0x7E, + 0x01, 0xE1, 0xFC, 0x1E, 0x0F, 0xFF, 0xF0, 0x3F, 0xFF, 0x00, 0x7F, 0xE0, + 0x00, 0xFC, 0x00, 0x77, 0xE1, 0xFF, 0xF3, 0xFF, 0xF7, 0xFF, 0xEF, 0x07, + 0xFE, 0x07, 0xFC, 0x07, 0xF8, 0x0F, 0xF0, 0x1F, 0xE0, 0x7B, 0xFF, 0xF7, + 0xFF, 0xCF, 0xFE, 0x1F, 0xF0, 0x3C, 0x00, 0x78, 0x00, 0xF0, 0x01, 0xE0, + 0x03, 0xC0, 0x07, 0x80, 0x0F, 0x00, 0x1C, 0x00, 0x00, 0x00, 0xFE, 0x00, + 0x1F, 0xFC, 0x03, 0xFF, 0xF0, 0x3F, 0xFF, 0xC3, 0xE0, 0xFF, 0x1E, 0x01, + 0xF9, 0xE0, 0x07, 0xEF, 0x00, 0x1F, 0xF0, 0x00, 0xFF, 0x80, 0x03, 0xFC, + 0x00, 0x1F, 0xE0, 0x00, 0xFF, 0x00, 0x07, 0xFC, 0x00, 0x3F, 0xE0, 0x03, + 0xCF, 0x80, 0x1E, 0x7E, 0x01, 0xE1, 0xFC, 0x1E, 0x0F, 0xFF, 0xF0, 0x3F, + 0xFF, 0x00, 0x7F, 0xE0, 0x00, 0xFC, 0x00, 0x77, 0xE0, 0xFF, 0xF8, 0xFF, + 0xFC, 0xFF, 0xFC, 0xF0, 0x7E, 0xF0, 0x3E, 0xF0, 0x1E, 0xF0, 0x1E, 0xF0, + 0x1C, 0xFF, 0xFC, 0xFF, 0xF8, 0xFF, 0xF0, 0xFF, 0xC0, 0xFF, 0x80, 0xFF, + 0xC0, 0xF7, 0xE0, 0xF3, 0xF8, 0xF1, 0xFC, 0xF0, 0xFE, 0xF0, 0x7E, 0xF0, + 0x3E, 0xE0, 0x0C, 0x03, 0xF0, 0x07, 0xFE, 0x07, 0xFF, 0xC7, 0xFF, 0xE7, + 0x83, 0xE3, 0xC0, 0x21, 0xE0, 0x00, 0xF8, 0x00, 0x7F, 0x80, 0x1F, 0xFC, + 0x07, 0xFF, 0x81, 0xFF, 0xE0, 0x1F, 0xF8, 0x00, 0xFC, 0x00, 0x3E, 0x00, + 0x0F, 0x60, 0x07, 0xFE, 0x07, 0xBF, 0xFF, 0xDF, 0xFF, 0xC7, 0xFF, 0xC0, + 0x7F, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x78, 0x00, + 0xF0, 0x01, 0xE0, 0x03, 0xC0, 0x07, 0x80, 0x0F, 0x00, 0x1E, 0x00, 0x3C, + 0x00, 0x78, 0x00, 0xF0, 0x01, 0xE0, 0x03, 0xC0, 0x07, 0x80, 0x0F, 0x00, + 0x1E, 0x00, 0x3C, 0x00, 0x78, 0x00, 0xE0, 0x00, 0x70, 0x0F, 0xE0, 0x3F, + 0xC0, 0x7F, 0x80, 0xFF, 0x01, 0xFE, 0x03, 0xFC, 0x07, 0xF8, 0x0F, 0xF0, + 0x1F, 0xE0, 0x3F, 0xC0, 0x7F, 0x80, 0xFF, 0x01, 0xFE, 0x03, 0xFC, 0x07, + 0xFC, 0x0F, 0xF8, 0x3D, 0xF8, 0x79, 0xFF, 0xE1, 0xFF, 0x81, 0xFE, 0x01, + 0xF0, 0x00, 0x60, 0x01, 0xF8, 0x01, 0xFC, 0x01, 0xFF, 0x00, 0xE7, 0x80, + 0xF3, 0xC0, 0x71, 0xF0, 0x38, 0x78, 0x3C, 0x3C, 0x1C, 0x1F, 0x0E, 0x07, + 0x8F, 0x03, 0xE7, 0x00, 0xF3, 0x80, 0x7B, 0xC0, 0x3F, 0xC0, 0x0F, 0xE0, + 0x07, 0xE0, 0x03, 0xF0, 0x00, 0xF8, 0x00, 0x78, 0x00, 0x3C, 0x00, 0x0C, + 0x00, 0x60, 0x00, 0x03, 0xF0, 0x00, 0x07, 0xF0, 0x0C, 0x07, 0xF0, 0x1C, + 0x0F, 0xF8, 0x3C, 0x0E, 0x78, 0x3E, 0x0E, 0x78, 0x3E, 0x1E, 0x78, 0x7E, + 0x1C, 0x3C, 0x7F, 0x1C, 0x3C, 0x7F, 0x1C, 0x3C, 0xFF, 0x3C, 0x3E, 0xEF, + 0xB8, 0x1E, 0xE7, 0xB8, 0x1F, 0xE7, 0xF8, 0x1F, 0xC7, 0xF0, 0x0F, 0xC3, + 0xF0, 0x0F, 0xC3, 0xF0, 0x0F, 0x83, 0xF0, 0x0F, 0x81, 0xE0, 0x07, 0x81, + 0xE0, 0x07, 0x01, 0xE0, 0x07, 0x00, 0xC0, 0x60, 0x01, 0xF8, 0x01, 0xFE, + 0x01, 0xFF, 0x81, 0xE7, 0xC1, 0xE1, 0xF0, 0xE0, 0xFC, 0xF0, 0x3F, 0xF0, + 0x0F, 0xF0, 0x03, 0xF0, 0x01, 0xF8, 0x00, 0x7E, 0x00, 0x7F, 0x00, 0x3F, + 0xC0, 0x3F, 0xF0, 0x3C, 0xFC, 0x3C, 0x3E, 0x1E, 0x0F, 0x9E, 0x07, 0xFE, + 0x01, 0xFE, 0x00, 0x7E, 0x00, 0x18, 0x60, 0x01, 0xF8, 0x01, 0xFE, 0x01, + 0xFF, 0x01, 0xE7, 0xC1, 0xE1, 0xF1, 0xE0, 0xFC, 0xF0, 0x3E, 0xF0, 0x0F, + 0xF0, 0x07, 0xF0, 0x01, 0xF0, 0x00, 0x78, 0x00, 0x3C, 0x00, 0x1E, 0x00, + 0x0F, 0x00, 0x07, 0x80, 0x03, 0xC0, 0x01, 0xE0, 0x00, 0xF0, 0x00, 0x78, + 0x00, 0x3C, 0x00, 0x1C, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xE0, 0x01, 0xE0, 0x00, 0xE0, 0x00, 0xF0, 0x00, 0xF0, 0x00, 0xF0, + 0x00, 0x70, 0x00, 0x78, 0x00, 0x78, 0x00, 0x78, 0x00, 0x3C, 0x00, 0x3C, + 0x00, 0x3C, 0x00, 0x1C, 0x00, 0x1E, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xF8, 0x7F, 0xFF, 0xFF, 0xFE, 0xF0, 0xF0, 0xF0, 0xF0, + 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, + 0xF0, 0xF0, 0xF0, 0xF0, 0xFF, 0xFF, 0xFF, 0xFE, 0x60, 0x3C, 0x0F, 0x03, + 0xC0, 0x78, 0x1E, 0x07, 0xC0, 0xF0, 0x3C, 0x0F, 0x81, 0xE0, 0x78, 0x1F, + 0x03, 0xC0, 0xF0, 0x3E, 0x07, 0x81, 0xE0, 0x3C, 0x0F, 0x03, 0xC0, 0x60, + 0x7F, 0xFF, 0xFF, 0xFF, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, + 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, + 0x7F, 0xFF, 0xFF, 0xFE, 0x03, 0x00, 0x1E, 0x00, 0x7C, 0x03, 0xF0, 0x1F, + 0xE0, 0x7F, 0x83, 0xDF, 0x0E, 0x3E, 0x78, 0xFB, 0xC1, 0xEE, 0x07, 0xB0, + 0x0C, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x60, 0xF0, 0xF8, 0xFC, + 0x7C, 0x1E, 0x0E, 0x06, 0x07, 0xC0, 0xFF, 0x8F, 0xFC, 0xFF, 0xF7, 0x0F, + 0x80, 0x3C, 0x1F, 0xE3, 0xFF, 0x3F, 0xFB, 0xFB, 0xFE, 0x1F, 0xE0, 0xFF, + 0x87, 0xFF, 0xFF, 0xFF, 0xEF, 0xFF, 0x1F, 0x70, 0x70, 0x03, 0xC0, 0x0F, + 0x00, 0x3C, 0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x7C, 0x3F, 0xF8, 0xFF, 0xF3, + 0xFF, 0xEF, 0x0F, 0xBC, 0x1F, 0xF0, 0x7F, 0xC0, 0xFF, 0x03, 0xFC, 0x0F, + 0xF0, 0x3F, 0xC1, 0xEF, 0x87, 0xBF, 0xFC, 0xFF, 0xE3, 0xFF, 0x0F, 0xF0, + 0x00, 0x03, 0xF0, 0x3F, 0xE1, 0xFF, 0x8F, 0xFE, 0x7C, 0x31, 0xE0, 0x0F, + 0x00, 0x3C, 0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x80, 0x3F, 0x00, 0x7E, 0x19, + 0xFF, 0xE3, 0xFF, 0x87, 0xFC, 0x07, 0xC0, 0x00, 0x1C, 0x00, 0xF0, 0x03, + 0xC0, 0x0F, 0x00, 0x3C, 0x00, 0xF0, 0x3F, 0xC3, 0xFF, 0x1F, 0xFC, 0xFF, + 0xF7, 0x87, 0xDC, 0x0F, 0xF0, 0x3F, 0xC0, 0xFF, 0x03, 0xFC, 0x0F, 0xF8, + 0x3F, 0xE0, 0xFF, 0xC3, 0xDF, 0xFF, 0x7F, 0xFC, 0xFF, 0xF0, 0xFB, 0x80, + 0x03, 0xF0, 0x3F, 0xE1, 0xFF, 0xCF, 0xFF, 0x7C, 0x3D, 0xE0, 0xFF, 0x07, + 0xBC, 0xFE, 0xFF, 0xF3, 0xFF, 0x8F, 0xF8, 0x3E, 0x00, 0x7E, 0x1D, 0xFF, + 0xF3, 0xFF, 0xC7, 0xFE, 0x07, 0xE0, 0x07, 0xC0, 0xFE, 0x1F, 0xE3, 0xFE, + 0x3C, 0xC7, 0x80, 0x78, 0x07, 0x80, 0x7F, 0x8F, 0xF8, 0xFF, 0x8F, 0xF0, + 0x78, 0x07, 0x80, 0x78, 0x07, 0x80, 0x78, 0x07, 0x80, 0x78, 0x07, 0x80, + 0x78, 0x07, 0x80, 0x70, 0x00, 0x00, 0x03, 0xFC, 0x3F, 0xF1, 0xFF, 0xCF, + 0xFF, 0x78, 0x7D, 0xC0, 0xFF, 0x03, 0xFC, 0x0F, 0xF0, 0x3F, 0xC0, 0xFF, + 0x83, 0xFE, 0x0F, 0xFC, 0x3D, 0xFF, 0xF7, 0xFF, 0xCF, 0xFF, 0x0F, 0xBC, + 0x00, 0xE3, 0x87, 0x9F, 0xFC, 0x7F, 0xE1, 0xFF, 0x01, 0xF0, 0x00, 0x70, + 0x03, 0xC0, 0x0F, 0x00, 0x3C, 0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x3E, 0x3F, + 0xFE, 0xFF, 0xFB, 0xFF, 0xFF, 0x87, 0xFE, 0x0F, 0xF0, 0x3F, 0xC0, 0xFF, + 0x03, 0xFC, 0x0F, 0xF0, 0x3F, 0xC0, 0xFF, 0x03, 0xFC, 0x0F, 0xF0, 0x3F, + 0xC0, 0xFE, 0x03, 0x80, 0x6F, 0xF6, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x30, 0x03, 0xC0, 0x1E, 0x00, 0x60, 0x00, + 0x00, 0x00, 0x00, 0xE0, 0x0F, 0x00, 0x78, 0x03, 0xC0, 0x1E, 0x00, 0xF0, + 0x07, 0x80, 0x3C, 0x01, 0xE0, 0x0F, 0x00, 0x78, 0x03, 0xC0, 0x1E, 0x00, + 0xF0, 0x07, 0x80, 0x3C, 0x01, 0xE0, 0x1E, 0x30, 0xF3, 0xFF, 0x1F, 0xF0, + 0xFF, 0x03, 0xF0, 0x00, 0x70, 0x03, 0xC0, 0x0F, 0x00, 0x3C, 0x00, 0xF0, + 0x03, 0xC0, 0x0F, 0x06, 0x3C, 0x78, 0xF3, 0xE3, 0xFF, 0x0F, 0xF8, 0x3F, + 0x80, 0xFC, 0x03, 0xF8, 0x0F, 0xF0, 0x3F, 0xE0, 0xFF, 0xC3, 0xDF, 0x8F, + 0x3F, 0x3C, 0x7E, 0xF0, 0xFB, 0xC1, 0xEE, 0x03, 0x00, 0x7F, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x77, 0x87, 0x8F, + 0xFE, 0xFE, 0xFF, 0xFF, 0xEF, 0xFF, 0xFF, 0xF9, 0xF9, 0xFF, 0x0F, 0x0F, + 0xF0, 0xF0, 0xFF, 0x0F, 0x0F, 0xF0, 0xF0, 0xFF, 0x0F, 0x0F, 0xF0, 0xF0, + 0xFF, 0x0F, 0x0F, 0xF0, 0xF0, 0xFF, 0x0F, 0x0F, 0xF0, 0xF0, 0xFF, 0x0F, + 0x0F, 0xE0, 0xE0, 0xE0, 0x73, 0xC7, 0xFF, 0xBF, 0xFD, 0xFF, 0xFF, 0x8F, + 0xF8, 0x3F, 0xC1, 0xFE, 0x0F, 0xF0, 0x7F, 0x83, 0xFC, 0x1F, 0xE0, 0xFF, + 0x07, 0xF8, 0x3F, 0xC1, 0xFE, 0x0F, 0xE0, 0x70, 0x03, 0xF0, 0x07, 0xFE, + 0x07, 0xFF, 0x87, 0xFF, 0xE7, 0xC3, 0xF3, 0xC0, 0xFF, 0xC0, 0x3F, 0xE0, + 0x0F, 0xF0, 0x07, 0xF8, 0x03, 0xFE, 0x01, 0xFF, 0x81, 0xE7, 0xE1, 0xF3, + 0xFF, 0xF0, 0xFF, 0xF0, 0x3F, 0xF0, 0x07, 0xE0, 0x00, 0x77, 0xC3, 0xFF, + 0xCF, 0xFF, 0xBF, 0xFE, 0xF0, 0xFF, 0xC1, 0xFF, 0x07, 0xFC, 0x0F, 0xF0, + 0x3F, 0xC0, 0xFF, 0x03, 0xFC, 0x0E, 0xF8, 0x7B, 0xFF, 0xCF, 0xFE, 0x3F, + 0xF0, 0xFF, 0x03, 0xC0, 0x0F, 0x00, 0x3C, 0x00, 0xF0, 0x03, 0xC0, 0x0E, + 0x00, 0x00, 0x03, 0xFC, 0x3F, 0xF1, 0xFF, 0xCF, 0xFF, 0x7C, 0x7D, 0xE0, + 0xFF, 0x03, 0xFC, 0x0F, 0xF0, 0x3F, 0xC0, 0xFF, 0x83, 0xFF, 0x0F, 0x7E, + 0x3D, 0xFF, 0xF3, 0xFF, 0xC7, 0xFF, 0x0F, 0xFC, 0x00, 0xF0, 0x03, 0xC0, + 0x0F, 0x00, 0x3C, 0x00, 0xF0, 0x03, 0x80, 0x03, 0xC7, 0xFF, 0xFF, 0xFF, + 0xFF, 0xF8, 0x6F, 0x00, 0xF0, 0x0F, 0x00, 0xF0, 0x0F, 0x00, 0xF0, 0x0F, + 0x00, 0xF0, 0x0F, 0x00, 0xF0, 0x0F, 0x00, 0xE0, 0x00, 0x07, 0xC0, 0x7F, + 0xE3, 0xFF, 0x9F, 0xFE, 0x78, 0xF1, 0xF0, 0x07, 0xF8, 0x1F, 0xFC, 0x3F, + 0xF8, 0x3F, 0xF0, 0x0F, 0xC0, 0x0F, 0x78, 0x3D, 0xFF, 0xEF, 0xFF, 0x9F, + 0xFC, 0x1F, 0xC0, 0x38, 0x03, 0xC0, 0x1E, 0x00, 0xF0, 0x07, 0x80, 0x3C, + 0x01, 0xFF, 0x9F, 0xFC, 0xFF, 0xE7, 0xFE, 0x1E, 0x00, 0xF0, 0x07, 0x80, + 0x3C, 0x01, 0xE0, 0x0F, 0x00, 0x7C, 0x03, 0xF1, 0x8F, 0xFC, 0x7F, 0xE1, + 0xFE, 0x07, 0xC0, 0x70, 0x3F, 0x83, 0xFC, 0x1F, 0xE0, 0xFF, 0x07, 0xF8, + 0x3F, 0xC1, 0xFE, 0x0F, 0xF0, 0x7F, 0x83, 0xFC, 0x1F, 0xE0, 0xFF, 0x8F, + 0xFF, 0xFD, 0xFF, 0xEF, 0xFF, 0x1E, 0x70, 0x60, 0x1F, 0x81, 0xFC, 0x0F, + 0xF0, 0xF7, 0x87, 0x3C, 0x79, 0xF3, 0xC7, 0x9C, 0x3D, 0xE1, 0xFE, 0x07, + 0xF0, 0x3F, 0x81, 0xF8, 0x07, 0xC0, 0x3E, 0x00, 0xE0, 0x06, 0x00, 0x60, + 0x00, 0xDE, 0x00, 0x3F, 0xC3, 0x87, 0x78, 0x70, 0xEF, 0x9F, 0x3C, 0xF3, + 0xE7, 0x1E, 0x7C, 0xE3, 0xDF, 0xDC, 0x3F, 0xFF, 0x87, 0xFF, 0xE0, 0xFF, + 0xFC, 0x1F, 0x9F, 0x81, 0xF3, 0xE0, 0x3E, 0x7C, 0x07, 0x87, 0x80, 0x70, + 0xF0, 0x0C, 0x1C, 0x00, 0x60, 0x1F, 0x81, 0xFE, 0x1F, 0xF9, 0xE7, 0xCE, + 0x1F, 0xE0, 0xFF, 0x03, 0xF0, 0x0F, 0x80, 0x7E, 0x07, 0xF8, 0x7F, 0xC3, + 0x9F, 0x3C, 0x7F, 0xC3, 0xFC, 0x0F, 0xC0, 0x30, 0x30, 0x1D, 0xC0, 0x7F, + 0x83, 0x9E, 0x0E, 0x78, 0x79, 0xF1, 0xC3, 0xC7, 0x0F, 0xBC, 0x1E, 0xE0, + 0x7F, 0x81, 0xFC, 0x03, 0xF0, 0x0F, 0xC0, 0x3E, 0x00, 0x78, 0x01, 0xE0, + 0x07, 0x00, 0x3C, 0x02, 0xF0, 0x3F, 0x80, 0xFE, 0x03, 0xF0, 0x07, 0x80, + 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x0E, 0x00, 0xE0, 0x0F, + 0x00, 0xF0, 0x07, 0x00, 0x78, 0x07, 0x80, 0x78, 0x03, 0x80, 0x3F, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x07, 0x0F, 0x1F, 0x1E, 0x3C, 0x3C, 0x3C, + 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x78, 0x78, 0x78, 0x7C, 0x7C, 0x3C, 0x3C, + 0x3C, 0x3C, 0x3C, 0x3C, 0x3E, 0x3F, 0x1F, 0x1F, 0x0E, 0x7F, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xE0, 0x60, 0xF0, 0xF8, 0xFC, 0x7C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, + 0x3C, 0x3E, 0x1E, 0x1E, 0x1E, 0x1C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, + 0x3C, 0x38, 0x78, 0xF0, 0xE0, 0x00, 0x1E, 0x03, 0xF9, 0xFF, 0xFF, 0xFF, + 0xFE, 0xFF, 0x61, 0xF0, 0x02, 0x00 }; + +const GFXglyph aAntiCorona15pt7bGlyphs[] PROGMEM = { + { 0, 1, 1, 8, 0, 0 }, // 0x20 ' ' + { 1, 4, 23, 7, 2, -20 }, // 0x21 '!' + { 13, 9, 8, 13, 2, -20 }, // 0x22 '"' + { 22, 18, 21, 20, 1, -18 }, // 0x23 '#' + { 70, 15, 22, 18, 2, -19 }, // 0x24 '$' + { 112, 26, 22, 27, 1, -19 }, // 0x25 '%' + { 184, 16, 22, 18, 1, -19 }, // 0x26 '&' + { 228, 3, 8, 8, 2, -20 }, // 0x27 ''' + { 231, 9, 28, 11, 1, -20 }, // 0x28 '(' + { 263, 10, 28, 11, 0, -20 }, // 0x29 ')' + { 298, 13, 13, 17, 2, -21 }, // 0x2A '*' + { 320, 13, 13, 16, 1, -14 }, // 0x2B '+' + { 342, 5, 7, 8, 2, -1 }, // 0x2C ',' + { 347, 13, 4, 17, 2, -6 }, // 0x2D '-' + { 354, 4, 4, 8, 2, -1 }, // 0x2E '.' + { 356, 10, 22, 12, 1, -19 }, // 0x2F '/' + { 384, 18, 22, 20, 1, -19 }, // 0x30 '0' + { 434, 7, 22, 9, 0, -19 }, // 0x31 '1' + { 454, 15, 22, 15, 0, -19 }, // 0x32 '2' + { 496, 14, 22, 15, 0, -19 }, // 0x33 '3' + { 535, 14, 22, 16, 1, -19 }, // 0x34 '4' + { 574, 14, 22, 16, 1, -19 }, // 0x35 '5' + { 613, 16, 22, 18, 1, -19 }, // 0x36 '6' + { 657, 14, 22, 14, 0, -19 }, // 0x37 '7' + { 696, 14, 22, 16, 1, -19 }, // 0x38 '8' + { 735, 16, 22, 17, 1, -19 }, // 0x39 '9' + { 779, 4, 15, 8, 2, -12 }, // 0x3A ':' + { 787, 4, 17, 8, 2, -11 }, // 0x3B ';' + { 796, 17, 14, 18, 1, -14 }, // 0x3C '<' + { 826, 13, 11, 16, 1, -13 }, // 0x3D '=' + { 844, 17, 14, 18, 1, -14 }, // 0x3E '>' + { 874, 14, 22, 16, 1, -19 }, // 0x3F '?' + { 913, 21, 22, 25, 2, -19 }, // 0x40 '@' + { 971, 17, 22, 17, 0, -19 }, // 0x41 'A' + { 1018, 15, 22, 18, 2, -19 }, // 0x42 'B' + { 1060, 17, 22, 19, 1, -19 }, // 0x43 'C' + { 1107, 17, 22, 20, 2, -19 }, // 0x44 'D' + { 1154, 15, 22, 18, 2, -19 }, // 0x45 'E' + { 1196, 13, 22, 15, 2, -19 }, // 0x46 'F' + { 1232, 17, 22, 20, 1, -19 }, // 0x47 'G' + { 1279, 16, 22, 20, 2, -19 }, // 0x48 'H' + { 1323, 4, 22, 8, 2, -19 }, // 0x49 'I' + { 1334, 13, 22, 14, -1, -19 }, // 0x4A 'J' + { 1370, 16, 22, 18, 2, -19 }, // 0x4B 'K' + { 1414, 13, 22, 15, 2, -19 }, // 0x4C 'L' + { 1450, 17, 22, 21, 2, -19 }, // 0x4D 'M' + { 1497, 16, 22, 20, 2, -19 }, // 0x4E 'N' + { 1541, 21, 22, 23, 1, -19 }, // 0x4F 'O' + { 1599, 15, 22, 18, 2, -19 }, // 0x50 'P' + { 1641, 21, 22, 23, 1, -19 }, // 0x51 'Q' + { 1699, 16, 22, 19, 2, -19 }, // 0x52 'R' + { 1743, 17, 22, 19, 1, -19 }, // 0x53 'S' + { 1790, 15, 22, 17, 1, -19 }, // 0x54 'T' + { 1832, 15, 22, 18, 1, -19 }, // 0x55 'U' + { 1874, 17, 22, 18, 1, -19 }, // 0x56 'V' + { 1921, 24, 22, 25, 1, -19 }, // 0x57 'W' + { 1987, 17, 22, 19, 1, -19 }, // 0x58 'X' + { 2034, 17, 22, 19, 1, -19 }, // 0x59 'Y' + { 2081, 17, 22, 19, 1, -19 }, // 0x5A 'Z' + { 2128, 8, 28, 11, 2, -20 }, // 0x5B '[' + { 2156, 10, 22, 12, 1, -19 }, // 0x5C '\' + { 2184, 8, 28, 10, 0, -20 }, // 0x5D ']' + { 2212, 14, 12, 15, 1, -20 }, // 0x5E '^' + { 2233, 13, 4, 16, 2, 2 }, // 0x5F '_' + { 2240, 8, 8, 9, 1, -18 }, // 0x60 '`' + { 2248, 13, 17, 15, 1, -14 }, // 0x61 'a' + { 2276, 14, 23, 17, 2, -20 }, // 0x62 'b' + { 2317, 14, 17, 16, 1, -14 }, // 0x63 'c' + { 2347, 14, 23, 17, 1, -20 }, // 0x64 'd' + { 2388, 14, 17, 16, 1, -14 }, // 0x65 'e' + { 2418, 12, 24, 11, 1, -20 }, // 0x66 'f' + { 2454, 14, 23, 17, 1, -14 }, // 0x67 'g' + { 2495, 14, 23, 17, 2, -20 }, // 0x68 'h' + { 2536, 4, 23, 6, 1, -20 }, // 0x69 'i' + { 2548, 13, 29, 6, -8, -20 }, // 0x6A 'j' + { 2596, 14, 23, 16, 2, -20 }, // 0x6B 'k' + { 2637, 4, 23, 8, 2, -20 }, // 0x6C 'l' + { 2649, 20, 17, 23, 2, -14 }, // 0x6D 'm' + { 2692, 13, 17, 16, 2, -14 }, // 0x6E 'n' + { 2720, 17, 17, 19, 1, -14 }, // 0x6F 'o' + { 2757, 14, 23, 17, 2, -14 }, // 0x70 'p' + { 2798, 14, 23, 17, 1, -14 }, // 0x71 'q' + { 2839, 12, 17, 15, 2, -14 }, // 0x72 'r' + { 2865, 14, 17, 15, 0, -14 }, // 0x73 's' + { 2895, 13, 22, 14, 1, -19 }, // 0x74 't' + { 2931, 13, 17, 16, 1, -14 }, // 0x75 'u' + { 2959, 13, 17, 15, 1, -14 }, // 0x76 'v' + { 2987, 19, 17, 20, 1, -14 }, // 0x77 'w' + { 3028, 13, 17, 15, 1, -14 }, // 0x78 'x' + { 3056, 14, 23, 15, 1, -14 }, // 0x79 'y' + { 3097, 13, 17, 15, 1, -14 }, // 0x7A 'z' + { 3125, 8, 28, 9, 0, -20 }, // 0x7B '{' + { 3153, 4, 31, 8, 2, -20 }, // 0x7C '|' + { 3169, 8, 29, 9, 1, -20 }, // 0x7D '}' + { 3198, 13, 7, 16, 2, -10 } }; // 0x7E '~' + +const GFXfont aAntiCorona15pt7b PROGMEM = { + (uint8_t *)aAntiCorona15pt7bBitmaps, + (GFXglyph *)aAntiCorona15pt7bGlyphs, + 0x20, 0x7E, 32 }; + +// Approx. 3882 bytes diff --git a/src/aAntiCorona16pt7b.h b/src/aAntiCorona16pt7b.h new file mode 100644 index 0000000..bd3edf4 --- /dev/null +++ b/src/aAntiCorona16pt7b.h @@ -0,0 +1,404 @@ +const uint8_t aAntiCorona16pt7bBitmaps[] PROGMEM = { + 0x00, 0x77, 0xBD, 0xEF, 0x7B, 0xDE, 0xF7, 0xBD, 0xEF, 0x7B, 0xDE, 0xF7, + 0x00, 0xEF, 0xFF, 0xEE, 0x71, 0xF9, 0xFD, 0xFE, 0x7F, 0x3F, 0x1D, 0x8E, + 0xC6, 0x00, 0xE1, 0xC0, 0x3C, 0x78, 0x07, 0x8F, 0x00, 0xE1, 0xC0, 0x3C, + 0x78, 0x07, 0x8F, 0x0F, 0xFF, 0xFB, 0xFF, 0xFF, 0x7F, 0xFF, 0xEF, 0xFF, + 0xF8, 0x3C, 0x78, 0x0F, 0x1E, 0x07, 0xFF, 0xFD, 0xFF, 0xFF, 0xBF, 0xFF, + 0xF7, 0xFF, 0xFC, 0x78, 0xF0, 0x0F, 0x1E, 0x01, 0xE3, 0x80, 0x38, 0xF0, + 0x0F, 0x1E, 0x00, 0xC3, 0x80, 0x00, 0x01, 0xC0, 0x03, 0xE0, 0x0F, 0xFC, + 0x1F, 0xFE, 0x3F, 0xFE, 0x7F, 0xFC, 0x7B, 0xDC, 0x7F, 0xC0, 0x7F, 0xC0, + 0x7F, 0xE0, 0x3F, 0xFC, 0x1F, 0xFE, 0x07, 0xFF, 0x03, 0xFF, 0x03, 0xDF, + 0x03, 0xCF, 0x73, 0xCF, 0xFF, 0xFE, 0xFF, 0xFE, 0xFF, 0xFC, 0x3F, 0xF8, + 0x0F, 0xC0, 0x03, 0x80, 0x0F, 0x80, 0x30, 0x03, 0xF8, 0x0E, 0x00, 0xFF, + 0x83, 0xC0, 0x38, 0xF0, 0x78, 0x06, 0x0F, 0x1E, 0x01, 0xC0, 0xE3, 0x80, + 0x38, 0x1C, 0xF0, 0x07, 0x03, 0x9C, 0x00, 0xE0, 0x77, 0x8F, 0x1E, 0x0D, + 0xE7, 0xF1, 0xE3, 0xBC, 0xFF, 0x3F, 0xEF, 0x39, 0xE3, 0xF9, 0xEE, 0x1E, + 0x3E, 0x79, 0xC1, 0xC0, 0x0F, 0x38, 0x38, 0x03, 0xC7, 0x07, 0x00, 0x70, + 0xE0, 0xE0, 0x1E, 0x1E, 0x1C, 0x07, 0x81, 0xE7, 0x00, 0xF0, 0x3F, 0xC0, + 0x3C, 0x03, 0xF8, 0x07, 0x80, 0x3C, 0x00, 0x60, 0x00, 0x00, 0x03, 0xE0, + 0x07, 0xF8, 0x07, 0xFE, 0x03, 0xFF, 0x03, 0xCF, 0x81, 0xE3, 0xC0, 0xF1, + 0xE0, 0x7C, 0xE0, 0x3F, 0xF0, 0x0F, 0xF0, 0x07, 0xF0, 0x03, 0xF0, 0x03, + 0xFC, 0xE3, 0xFF, 0xF1, 0xEF, 0xF9, 0xE3, 0xFC, 0xF0, 0xFE, 0x7C, 0x3F, + 0xBF, 0x0F, 0xFF, 0xFF, 0xF7, 0xFF, 0xF9, 0xFF, 0xB8, 0x3F, 0x00, 0x7F, + 0xFF, 0xFE, 0x66, 0x03, 0x81, 0xE0, 0xF8, 0x7C, 0x3C, 0x0F, 0x07, 0x81, + 0xE0, 0x78, 0x1C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, + 0x3C, 0x0F, 0x03, 0xC0, 0xF8, 0x1E, 0x07, 0x81, 0xF0, 0x7C, 0x0F, 0x83, + 0xF8, 0x7E, 0x0F, 0x81, 0xC0, 0x38, 0x1F, 0x07, 0xE1, 0xFC, 0x1F, 0x03, + 0xE0, 0xF8, 0x1E, 0x07, 0x81, 0xF0, 0x7C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, + 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0x81, 0xE0, 0x78, 0x1C, 0x0F, + 0x03, 0xC3, 0xE1, 0xF0, 0x78, 0x1C, 0x00, 0x03, 0x80, 0x1E, 0x00, 0x78, + 0x1D, 0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCF, 0xFE, 0x0F, 0xE0, 0x7F, + 0x83, 0xFF, 0x0E, 0x7C, 0x30, 0xF0, 0x03, 0x80, 0x03, 0x80, 0x3C, 0x01, + 0xE0, 0x0F, 0x00, 0x78, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x3C, + 0x01, 0xE0, 0x0F, 0x00, 0x78, 0x03, 0x80, 0x77, 0xFF, 0xF7, 0xB9, 0xCC, + 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x77, 0xFF, 0xF7, 0x00, 0x00, + 0x60, 0x1C, 0x07, 0x80, 0xE0, 0x3C, 0x07, 0x80, 0xE0, 0x3C, 0x07, 0x80, + 0xE0, 0x3C, 0x07, 0x01, 0xE0, 0x3C, 0x07, 0x01, 0xE0, 0x3C, 0x07, 0x01, + 0xE0, 0x38, 0x0F, 0x01, 0xE0, 0x38, 0x00, 0x00, 0xF8, 0x00, 0x7F, 0xC0, + 0x3F, 0xFC, 0x0F, 0xFF, 0xC3, 0xE1, 0xFC, 0x78, 0x1F, 0x9E, 0x01, 0xF3, + 0x80, 0x1F, 0xF0, 0x03, 0xFE, 0x00, 0x3F, 0xC0, 0x07, 0xF8, 0x00, 0xFF, + 0x00, 0x1F, 0xE0, 0x03, 0xFE, 0x00, 0x7F, 0xC0, 0x1E, 0x7C, 0x03, 0xCF, + 0xC0, 0xF0, 0xFC, 0x3E, 0x1F, 0xFF, 0x81, 0xFF, 0xE0, 0x1F, 0xF0, 0x00, + 0xF8, 0x00, 0x0E, 0x3C, 0xFB, 0xFF, 0xFF, 0xFF, 0x8F, 0x1E, 0x3C, 0x78, + 0xF1, 0xE3, 0xC7, 0x8F, 0x1E, 0x3C, 0x78, 0xF1, 0xE3, 0xC7, 0x00, 0x0F, + 0xE0, 0x3F, 0xF0, 0x7F, 0xFC, 0xFF, 0xFC, 0x60, 0xFE, 0x00, 0x3E, 0x00, + 0x1E, 0x00, 0x1E, 0x00, 0x1E, 0x00, 0x3C, 0x00, 0x7C, 0x00, 0xF8, 0x01, + 0xF0, 0x03, 0xE0, 0x07, 0xC0, 0x0F, 0x80, 0x1F, 0x00, 0x3E, 0x00, 0x3C, + 0x00, 0x7F, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0x7F, 0xFE, 0x0F, 0x80, 0xFF, + 0x87, 0xFF, 0x1F, 0xFE, 0x61, 0xF8, 0x03, 0xE0, 0x07, 0x80, 0x1E, 0x00, + 0xF0, 0x7F, 0x81, 0xFF, 0x0F, 0xFE, 0x3F, 0xF8, 0x03, 0xF0, 0x07, 0xC0, + 0x0F, 0x00, 0x3C, 0x00, 0xF3, 0x07, 0xBF, 0xFC, 0xFF, 0xF3, 0xFF, 0x03, + 0xF0, 0x00, 0x00, 0x30, 0x00, 0xF0, 0x03, 0xC0, 0x07, 0x80, 0x1E, 0x00, + 0x78, 0x00, 0xF3, 0x83, 0xCF, 0x0F, 0x1E, 0x1E, 0x3C, 0x78, 0x79, 0xE0, + 0xF3, 0x81, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x3C, + 0x00, 0x78, 0x00, 0xF0, 0x01, 0xE0, 0x03, 0xC0, 0x07, 0x00, 0x3F, 0xF9, + 0xFF, 0xE7, 0xFF, 0x9F, 0xFC, 0x78, 0x01, 0xE0, 0x07, 0x80, 0x1F, 0xF0, + 0x7F, 0xE1, 0xFF, 0xC7, 0xFF, 0x80, 0x7F, 0x00, 0x7C, 0x01, 0xF0, 0x03, + 0xC0, 0x0F, 0x00, 0x3C, 0x00, 0xE7, 0x07, 0xBF, 0xFC, 0xFF, 0xE3, 0xFF, + 0x03, 0xF0, 0x00, 0x01, 0xF0, 0x03, 0xFE, 0x03, 0xFF, 0x83, 0xFF, 0xC1, + 0xE3, 0xE1, 0xE0, 0x60, 0xE0, 0x00, 0xF3, 0xF0, 0x7F, 0xFE, 0x3F, 0xFF, + 0x1F, 0xFF, 0xDF, 0xC7, 0xFF, 0xC0, 0xFB, 0xC0, 0x3D, 0xE0, 0x1E, 0xF8, + 0x0F, 0x7C, 0x07, 0xBF, 0x07, 0x8F, 0xE7, 0xC7, 0xFF, 0xC1, 0xFF, 0xC0, + 0x7F, 0xC0, 0x0F, 0x80, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0xFF, 0xE0, + 0x03, 0xC0, 0x07, 0x00, 0x1E, 0x00, 0x38, 0x00, 0xF0, 0x01, 0xE0, 0x03, + 0x80, 0x0F, 0x00, 0x1C, 0x00, 0x78, 0x00, 0xF0, 0x01, 0xC0, 0x07, 0x80, + 0x0E, 0x00, 0x3C, 0x00, 0x78, 0x00, 0xE0, 0x03, 0xC0, 0x03, 0x00, 0x00, + 0x07, 0xC0, 0x3F, 0xE0, 0xFF, 0xC1, 0xFF, 0xC7, 0x8F, 0x8F, 0x0F, 0x1E, + 0x1E, 0x3E, 0x3C, 0x7E, 0x70, 0xFF, 0xE0, 0xFF, 0xC0, 0xFF, 0xE3, 0xFF, + 0xCF, 0x1F, 0xFC, 0x0F, 0xF8, 0x0F, 0xF0, 0x1F, 0xF0, 0x3F, 0xF0, 0xF7, + 0xFF, 0xE7, 0xFF, 0x87, 0xFE, 0x03, 0xF0, 0x00, 0x03, 0xE0, 0x07, 0xFC, + 0x07, 0xFF, 0x07, 0xFF, 0xC7, 0xCF, 0xE3, 0xC1, 0xFB, 0xC0, 0x7D, 0xE0, + 0x3E, 0xF0, 0x0F, 0x78, 0x07, 0xBE, 0x07, 0xDF, 0xC7, 0xE7, 0xFF, 0xF3, + 0xFF, 0xF8, 0xFF, 0xFC, 0x1F, 0x9E, 0x00, 0x0E, 0x0C, 0x0F, 0x0F, 0x8F, + 0x07, 0xFF, 0x83, 0xFF, 0x80, 0xFF, 0x80, 0x3F, 0x00, 0x77, 0xFF, 0xF7, + 0x00, 0x00, 0x00, 0x00, 0xEF, 0xFF, 0xEE, 0x77, 0xFF, 0xF7, 0x00, 0x00, + 0x00, 0x00, 0xEF, 0xFF, 0xEF, 0x73, 0x30, 0x00, 0x01, 0x80, 0x03, 0xE0, + 0x07, 0xF8, 0x07, 0xFC, 0x0F, 0xFC, 0x0F, 0xFC, 0x07, 0xF8, 0x03, 0xFE, + 0x00, 0xFF, 0xF0, 0x1F, 0xFF, 0x00, 0xFF, 0xF8, 0x07, 0xFE, 0x00, 0x7F, + 0x80, 0x03, 0xE0, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, + 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x70, + 0x00, 0x3F, 0x80, 0x0F, 0xFC, 0x03, 0xFF, 0xC0, 0x3F, 0xFE, 0x01, 0xFF, + 0xE0, 0x1F, 0xFC, 0x00, 0xFE, 0x01, 0xFF, 0x81, 0xFF, 0x83, 0xFF, 0x01, + 0xFE, 0x00, 0xFE, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xE0, 0x7F, + 0xF1, 0xFF, 0xF7, 0xFF, 0xE6, 0x0F, 0xE0, 0x07, 0xC0, 0x07, 0x80, 0x0F, + 0x00, 0x1C, 0x00, 0x78, 0x01, 0xE0, 0x07, 0x80, 0x1E, 0x00, 0x78, 0x01, + 0xE0, 0x03, 0xC0, 0x06, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x7C, 0x00, 0xF8, + 0x01, 0xF0, 0x01, 0xC0, 0x00, 0x00, 0x7F, 0x00, 0x03, 0xFF, 0x80, 0x1F, + 0xFF, 0xC0, 0x7F, 0xFF, 0xC1, 0xF0, 0x7F, 0x87, 0x80, 0x3F, 0x8E, 0x0F, + 0xBF, 0x3C, 0x7F, 0x3F, 0x71, 0xFE, 0x3F, 0xE3, 0xFC, 0x7F, 0xCF, 0x78, + 0x7F, 0x9E, 0xF0, 0xFF, 0x3F, 0xE1, 0xFF, 0x7F, 0xC3, 0xFE, 0xFF, 0x87, + 0x7E, 0xFF, 0x9E, 0x7C, 0xFF, 0xF8, 0xFE, 0x1F, 0xF0, 0xFE, 0x3F, 0xC0, + 0xFF, 0xDE, 0x00, 0xFF, 0x80, 0x00, 0xFF, 0x00, 0x00, 0x7C, 0x00, 0x00, + 0x00, 0xE0, 0x00, 0x78, 0x00, 0x1E, 0x00, 0x07, 0xC0, 0x03, 0xF0, 0x00, + 0xFE, 0x00, 0x3F, 0x80, 0x1F, 0xE0, 0x07, 0x7C, 0x03, 0xDF, 0x00, 0xF3, + 0xC0, 0x38, 0xF8, 0x1E, 0x1E, 0x07, 0xFF, 0xC3, 0xFF, 0xF0, 0xFF, 0xFC, + 0x3F, 0xFF, 0x9E, 0x01, 0xE7, 0x80, 0x79, 0xC0, 0x1F, 0xF0, 0x03, 0xF8, + 0x00, 0xFE, 0x00, 0x38, 0x7F, 0xE0, 0xFF, 0xF8, 0xFF, 0xFC, 0xFF, 0xFC, + 0xF0, 0x7E, 0xF0, 0x3E, 0xF0, 0x1E, 0xF0, 0x1E, 0xF0, 0x3C, 0xFF, 0xF8, + 0xFF, 0xFC, 0xFF, 0xFE, 0xFF, 0xFE, 0xF0, 0x7F, 0xF0, 0x1F, 0xF0, 0x0F, + 0xF0, 0x0F, 0xF0, 0x0F, 0xF8, 0x1E, 0xFF, 0xFC, 0xFF, 0xF8, 0xFF, 0xF0, + 0xFF, 0xC0, 0x00, 0x7F, 0x00, 0x7F, 0xF8, 0x1F, 0xFF, 0x07, 0xFF, 0xE1, + 0xF0, 0x7C, 0x78, 0x00, 0x1E, 0x00, 0x03, 0xC0, 0x00, 0x70, 0x00, 0x1E, + 0x00, 0x03, 0xC0, 0x00, 0x78, 0x00, 0x0F, 0x00, 0x01, 0xF0, 0x00, 0x3E, + 0x00, 0x07, 0xE0, 0x00, 0x7C, 0x00, 0x0F, 0xE0, 0x00, 0xFE, 0x07, 0x0F, + 0xFF, 0xE0, 0xFF, 0xFC, 0x0F, 0xFE, 0x00, 0x7F, 0x00, 0x77, 0xE0, 0x3F, + 0xFE, 0x0F, 0xFF, 0xE3, 0xFF, 0xFC, 0xF0, 0x7F, 0x3C, 0x07, 0xEF, 0x00, + 0xFB, 0xC0, 0x1F, 0xF0, 0x07, 0xFC, 0x00, 0xFF, 0x00, 0x3F, 0xC0, 0x0F, + 0xF0, 0x03, 0xFC, 0x00, 0xFF, 0x00, 0x3B, 0xC0, 0x1E, 0xF0, 0x07, 0xBC, + 0x03, 0xCF, 0x83, 0xE3, 0xFF, 0xF0, 0xFF, 0xF8, 0x3F, 0xFC, 0x0F, 0xF8, + 0x00, 0x7F, 0xFC, 0xFF, 0xFC, 0xFF, 0xFC, 0xFF, 0xF8, 0xF0, 0x00, 0xF0, + 0x00, 0xF0, 0x00, 0xF0, 0x00, 0xF0, 0x00, 0xFF, 0x80, 0xFF, 0x80, 0xFF, + 0x00, 0xFF, 0x00, 0xF0, 0x00, 0xF0, 0x00, 0xF0, 0x00, 0xF0, 0x00, 0xF0, + 0x00, 0xF0, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x7F, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEF, 0x00, 0x78, 0x03, 0xC0, 0x1E, 0x00, + 0xF0, 0x07, 0xFC, 0x3F, 0xE1, 0xFE, 0x0F, 0xF0, 0x78, 0x03, 0xC0, 0x1E, + 0x00, 0xF0, 0x07, 0x80, 0x3C, 0x01, 0xE0, 0x0F, 0x00, 0x78, 0x03, 0x80, + 0x00, 0x00, 0x7E, 0x00, 0xFF, 0xE0, 0x7F, 0xFC, 0x3F, 0xFF, 0x1F, 0x07, + 0x8F, 0x00, 0x07, 0x80, 0x01, 0xE0, 0x00, 0xF0, 0x00, 0x3C, 0x00, 0x0F, + 0x00, 0x03, 0xC0, 0x7F, 0xF0, 0x3F, 0xFC, 0x0F, 0xFF, 0x83, 0xFF, 0xE0, + 0x0F, 0x7C, 0x03, 0xDF, 0x80, 0xF3, 0xF8, 0x3C, 0x7F, 0xFF, 0x0F, 0xFF, + 0xC1, 0xFF, 0xF0, 0x1F, 0xB8, 0x70, 0x03, 0xF8, 0x03, 0xFC, 0x01, 0xFE, + 0x00, 0xFF, 0x00, 0x7F, 0x80, 0x3F, 0xC0, 0x1F, 0xE0, 0x0F, 0xF0, 0x07, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x3F, 0xC0, + 0x1F, 0xE0, 0x0F, 0xF0, 0x07, 0xF8, 0x03, 0xFC, 0x01, 0xFE, 0x00, 0xFF, + 0x00, 0x7F, 0x80, 0x3F, 0x80, 0x1C, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x1C, 0x00, 0xF0, 0x03, 0xC0, + 0x0F, 0x00, 0x3C, 0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x3C, 0x00, 0xF0, + 0x03, 0xC0, 0x0F, 0x00, 0x3C, 0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x38, + 0x01, 0xE3, 0x0F, 0x9F, 0xFC, 0xFF, 0xE1, 0xFF, 0x01, 0xF0, 0x00, 0x70, + 0x06, 0x78, 0x07, 0xBC, 0x07, 0x9E, 0x0F, 0x8F, 0x0F, 0x87, 0x8F, 0x83, + 0xCF, 0x81, 0xEF, 0x80, 0xFF, 0x80, 0x7F, 0x00, 0x3F, 0x00, 0x1F, 0xC0, + 0x0F, 0xF0, 0x07, 0xFC, 0x03, 0xFF, 0x01, 0xFF, 0xE0, 0xF7, 0xF8, 0x78, + 0xFE, 0x3C, 0x3F, 0x9E, 0x0F, 0xEF, 0x01, 0xF7, 0x80, 0x7B, 0x80, 0x18, + 0x70, 0x07, 0x80, 0x3C, 0x01, 0xE0, 0x0F, 0x00, 0x78, 0x03, 0xC0, 0x1E, + 0x00, 0xF0, 0x07, 0x80, 0x3C, 0x01, 0xE0, 0x0F, 0x00, 0x78, 0x03, 0xC0, + 0x1E, 0x00, 0xF0, 0x07, 0x80, 0x3C, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xC0, 0x70, 0x00, 0xFC, 0x00, 0x7F, 0x00, 0x3F, 0xE0, 0x0F, 0xF8, + 0x07, 0xFF, 0x01, 0xFF, 0xC0, 0xFF, 0xF8, 0x3F, 0xFE, 0x0F, 0xFF, 0x87, + 0xFF, 0xF1, 0xFF, 0xFC, 0xFF, 0xFF, 0xBB, 0xFD, 0xFE, 0xFF, 0x7F, 0xBF, + 0xDF, 0xCF, 0xF3, 0xF3, 0xFC, 0xF8, 0xFF, 0x1E, 0x3F, 0xC7, 0x0F, 0xF0, + 0x83, 0xFC, 0x00, 0xFE, 0x00, 0x38, 0x70, 0x03, 0xF8, 0x03, 0xFE, 0x01, + 0xFF, 0x80, 0xFF, 0xE0, 0x7F, 0xF8, 0x3F, 0xFC, 0x1F, 0xFF, 0x0F, 0xFF, + 0xC7, 0xFB, 0xF3, 0xFC, 0xF9, 0xFE, 0x7E, 0xFF, 0x1F, 0xFF, 0x87, 0xFF, + 0xC1, 0xFF, 0xE0, 0xFF, 0xF0, 0x3F, 0xF8, 0x0F, 0xFC, 0x03, 0xFE, 0x01, + 0xFF, 0x00, 0x7F, 0x80, 0x3F, 0x80, 0x1C, 0x00, 0x7F, 0x00, 0x03, 0xFF, + 0x80, 0x1F, 0xFF, 0xC0, 0x7F, 0xFF, 0xC1, 0xF0, 0x7F, 0x87, 0x80, 0x3F, + 0x9E, 0x00, 0x1F, 0x3C, 0x00, 0x3F, 0x70, 0x00, 0x3F, 0xE0, 0x00, 0x7F, + 0xC0, 0x00, 0x7F, 0x80, 0x00, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x03, 0xFE, + 0x00, 0x07, 0x7E, 0x00, 0x1E, 0x7C, 0x00, 0x38, 0xFE, 0x00, 0xF0, 0xFE, + 0x07, 0xC0, 0xFF, 0xFF, 0x00, 0xFF, 0xFC, 0x00, 0xFF, 0xF0, 0x00, 0x7F, + 0x00, 0x00, 0x7F, 0xE0, 0xFF, 0xF8, 0xFF, 0xFE, 0xFF, 0xFE, 0xF0, 0x7F, + 0xF0, 0x1F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x1E, 0xFF, 0xFC, + 0xFF, 0xFC, 0xFF, 0xF0, 0xFF, 0xC0, 0xF0, 0x00, 0xF0, 0x00, 0xF0, 0x00, + 0xF0, 0x00, 0xF0, 0x00, 0xF0, 0x00, 0xF0, 0x00, 0xF0, 0x00, 0xE0, 0x00, + 0x00, 0x7F, 0x00, 0x03, 0xFF, 0x80, 0x1F, 0xFF, 0xC0, 0x7F, 0xFF, 0xC1, + 0xF0, 0x7F, 0x87, 0x80, 0x3F, 0x9E, 0x00, 0x1F, 0x3C, 0x00, 0x3F, 0x70, + 0x00, 0x3F, 0xE0, 0x00, 0x7F, 0xC0, 0x00, 0x7F, 0x80, 0x00, 0xFF, 0x00, + 0x01, 0xFF, 0x00, 0x03, 0xFE, 0x00, 0x07, 0x7E, 0x00, 0x1E, 0x7C, 0x00, + 0x38, 0xFE, 0x00, 0xF0, 0xFE, 0x07, 0xC0, 0xFF, 0xFF, 0x00, 0xFF, 0xFC, + 0x00, 0xFF, 0xF0, 0x00, 0x7F, 0x00, 0x00, 0x7F, 0xE0, 0x7F, 0xFC, 0x3F, + 0xFF, 0x9F, 0xFF, 0xCF, 0x07, 0xF7, 0x80, 0xFB, 0xC0, 0x3D, 0xE0, 0x1E, + 0xF0, 0x0F, 0x78, 0x1F, 0x3F, 0xFF, 0x1F, 0xFF, 0x0F, 0xFF, 0x07, 0xFE, + 0x03, 0xFF, 0x01, 0xFF, 0xC0, 0xF7, 0xF8, 0x79, 0xFE, 0x3C, 0x3F, 0x9E, + 0x0F, 0xEF, 0x03, 0xF7, 0x80, 0xFB, 0x80, 0x18, 0x03, 0xF0, 0x03, 0xFF, + 0x81, 0xFF, 0xF8, 0xFF, 0xFE, 0x78, 0x3F, 0x1E, 0x01, 0x87, 0x80, 0x01, + 0xF0, 0x00, 0x7F, 0x80, 0x0F, 0xFE, 0x03, 0xFF, 0xE0, 0x7F, 0xFE, 0x07, + 0xFF, 0x80, 0x1F, 0xF0, 0x00, 0xFC, 0x00, 0x1F, 0x00, 0x03, 0xDC, 0x00, + 0xFF, 0xC0, 0x7B, 0xFF, 0xFE, 0xFF, 0xFF, 0x1F, 0xFF, 0x00, 0xFF, 0x00, + 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x03, 0xC0, 0x03, 0xC0, + 0x03, 0xC0, 0x03, 0xC0, 0x03, 0xC0, 0x03, 0xC0, 0x03, 0xC0, 0x03, 0xC0, + 0x03, 0xC0, 0x03, 0xC0, 0x03, 0xC0, 0x03, 0xC0, 0x03, 0xC0, 0x03, 0xC0, + 0x03, 0xC0, 0x03, 0xC0, 0x03, 0xC0, 0x03, 0xC0, 0x03, 0x80, 0x70, 0x07, + 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, + 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, + 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF8, 0x0E, 0xFC, 0x1E, 0x7E, 0x3E, + 0x7F, 0xFC, 0x3F, 0xF8, 0x1F, 0xF0, 0x07, 0xC0, 0x70, 0x01, 0xFC, 0x00, + 0x7F, 0x00, 0x3F, 0xE0, 0x0E, 0x78, 0x07, 0x9F, 0x01, 0xE7, 0xC0, 0x70, + 0xF0, 0x3C, 0x3E, 0x0F, 0x0F, 0x83, 0x81, 0xE1, 0xE0, 0x7C, 0x70, 0x0F, + 0x3C, 0x03, 0xEF, 0x00, 0xFB, 0x80, 0x1F, 0xE0, 0x07, 0xF0, 0x01, 0xFC, + 0x00, 0x3F, 0x00, 0x0F, 0x80, 0x01, 0xE0, 0x00, 0x78, 0x00, 0x1C, 0x00, + 0x70, 0x00, 0x01, 0xFC, 0x00, 0x00, 0xFF, 0x00, 0x40, 0x3F, 0xE0, 0x38, + 0x0E, 0xF8, 0x1E, 0x07, 0x9E, 0x07, 0xC1, 0xE7, 0x83, 0xF0, 0x71, 0xF0, + 0xFC, 0x3C, 0x3C, 0x3F, 0x8F, 0x0F, 0x1F, 0xE3, 0x83, 0xE7, 0xF8, 0xE0, + 0xF9, 0xDF, 0x78, 0x1E, 0xF7, 0xDE, 0x07, 0xBC, 0xF7, 0x01, 0xFE, 0x3F, + 0xC0, 0x3F, 0x8F, 0xF0, 0x0F, 0xE1, 0xF8, 0x03, 0xF0, 0x7E, 0x00, 0xFC, + 0x1F, 0x80, 0x1F, 0x03, 0xE0, 0x07, 0x80, 0xF0, 0x01, 0xE0, 0x3C, 0x00, + 0x30, 0x06, 0x00, 0x70, 0x00, 0xFC, 0x00, 0x7F, 0x80, 0x3F, 0xF0, 0x1E, + 0x7E, 0x0F, 0x0F, 0x83, 0x83, 0xF1, 0xE0, 0x7E, 0xF0, 0x0F, 0xF8, 0x01, + 0xFC, 0x00, 0x7F, 0x00, 0x0F, 0xC0, 0x03, 0xF8, 0x01, 0xFE, 0x00, 0x7F, + 0xC0, 0x3D, 0xF8, 0x1E, 0x3F, 0x0F, 0x07, 0xC3, 0xC1, 0xF9, 0xE0, 0x3F, + 0xF0, 0x07, 0xF8, 0x00, 0xFE, 0x00, 0x38, 0x70, 0x00, 0xFC, 0x00, 0x7F, + 0x80, 0x3F, 0xF0, 0x1E, 0x7E, 0x0F, 0x0F, 0x83, 0xC3, 0xF1, 0xE0, 0x7E, + 0xF0, 0x0F, 0xF8, 0x01, 0xFE, 0x00, 0x7F, 0x00, 0x0F, 0x80, 0x01, 0xE0, + 0x00, 0x78, 0x00, 0x1E, 0x00, 0x07, 0x80, 0x01, 0xE0, 0x00, 0x78, 0x00, + 0x1E, 0x00, 0x07, 0x80, 0x01, 0xE0, 0x00, 0x78, 0x00, 0x1C, 0x00, 0x7F, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x0F, 0x00, 0x07, + 0x80, 0x01, 0xE0, 0x00, 0xF0, 0x00, 0x78, 0x00, 0x3E, 0x00, 0x0F, 0x00, + 0x07, 0x80, 0x03, 0xC0, 0x01, 0xF0, 0x00, 0x78, 0x00, 0x3C, 0x00, 0x1E, + 0x00, 0x0F, 0x80, 0x03, 0xC0, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xF8, 0x7F, 0x7F, 0xFF, 0xDF, 0xCF, 0x07, 0x83, 0xC1, 0xE0, + 0xF0, 0x78, 0x3C, 0x1E, 0x0F, 0x07, 0x83, 0xC1, 0xE0, 0xF0, 0x78, 0x3C, + 0x1E, 0x0F, 0x07, 0x83, 0xC1, 0xE0, 0xF0, 0x78, 0x3F, 0xDF, 0xFF, 0xF7, + 0xF0, 0x70, 0x1E, 0x03, 0xC0, 0x7C, 0x0F, 0x80, 0xF8, 0x1F, 0x01, 0xE0, + 0x3E, 0x07, 0xC0, 0x78, 0x0F, 0x80, 0xF0, 0x1F, 0x03, 0xE0, 0x3C, 0x07, + 0xC0, 0xF8, 0x0F, 0x81, 0xF0, 0x1E, 0x03, 0xC0, 0x70, 0x3F, 0xBF, 0xFF, + 0xEF, 0xF0, 0x78, 0x3C, 0x1E, 0x0F, 0x07, 0x83, 0xC1, 0xE0, 0xF0, 0x78, + 0x3C, 0x1E, 0x0F, 0x07, 0x83, 0xC1, 0xE0, 0xF0, 0x78, 0x3C, 0x1E, 0x0F, + 0x07, 0x83, 0xCF, 0xEF, 0xFF, 0xFB, 0xF8, 0x03, 0x80, 0x0E, 0x00, 0x7C, + 0x03, 0xF0, 0x0F, 0xE0, 0x7F, 0xC1, 0xDF, 0x0F, 0x3E, 0x78, 0xF9, 0xE1, + 0xFF, 0x07, 0xF8, 0x0F, 0xE0, 0x38, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xE0, 0x00, 0x70, 0xF8, 0xFC, 0xFC, 0x3E, 0x1F, 0x0F, 0x06, 0x07, 0xE0, + 0x7F, 0xC3, 0xFF, 0x9F, 0xFF, 0x70, 0xFC, 0x01, 0xF0, 0x1F, 0xC3, 0xFF, + 0x3F, 0xFD, 0xFF, 0xF7, 0xF3, 0xFC, 0x0F, 0xF0, 0x3F, 0xE0, 0xFF, 0xFF, + 0xDF, 0xFF, 0x7F, 0xFC, 0x7E, 0xE0, 0x70, 0x01, 0xE0, 0x03, 0xC0, 0x07, + 0x80, 0x0F, 0x00, 0x1E, 0x00, 0x3D, 0xF0, 0x7F, 0xF8, 0xFF, 0xF9, 0xFF, + 0xFB, 0xC3, 0xF7, 0x83, 0xFF, 0x03, 0xFE, 0x03, 0xFC, 0x07, 0xF8, 0x0F, + 0xF0, 0x1F, 0xE0, 0x3B, 0xC0, 0xF7, 0xC3, 0xCF, 0xFF, 0x9F, 0xFE, 0x3F, + 0xF8, 0x7F, 0xC0, 0x01, 0xF0, 0x0F, 0xF8, 0x7F, 0xF1, 0xFF, 0xE3, 0xC3, + 0x8F, 0x00, 0x1C, 0x00, 0x78, 0x00, 0xF0, 0x01, 0xE0, 0x03, 0xC0, 0x07, + 0xC0, 0x0F, 0xC0, 0x0F, 0xC1, 0x9F, 0xFF, 0x1F, 0xFE, 0x1F, 0xF8, 0x0F, + 0xC0, 0x00, 0x1C, 0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x3C, 0x00, 0xF0, + 0x3F, 0xC3, 0xFF, 0x1F, 0xFC, 0xFF, 0xF7, 0x87, 0xDE, 0x0F, 0xF0, 0x3F, + 0xC0, 0xFF, 0x03, 0xFC, 0x0F, 0xF0, 0x3F, 0xE0, 0xFF, 0x83, 0xFF, 0x8F, + 0x7F, 0xFC, 0xFF, 0xF1, 0xFF, 0xC3, 0xEE, 0x01, 0xF8, 0x0F, 0xF8, 0x7F, + 0xF9, 0xFF, 0xF3, 0xC3, 0xEF, 0x03, 0xDC, 0x07, 0xF8, 0x7E, 0xFF, 0xF9, + 0xFF, 0xE3, 0xFF, 0x87, 0xFC, 0x0F, 0xC0, 0x0F, 0xC1, 0xDF, 0xFF, 0x9F, + 0xFF, 0x1F, 0xFC, 0x0F, 0xE0, 0x03, 0xC0, 0x7F, 0x87, 0xFE, 0x7F, 0xE3, + 0xCE, 0x1C, 0x01, 0xE0, 0x0F, 0x00, 0x78, 0x03, 0xFC, 0x3F, 0xE1, 0xFF, + 0x0F, 0xF0, 0x3C, 0x01, 0xE0, 0x0F, 0x00, 0x78, 0x03, 0xC0, 0x1E, 0x00, + 0xF0, 0x07, 0x80, 0x3C, 0x01, 0xE0, 0x0F, 0x00, 0x70, 0x00, 0x03, 0xFC, + 0x3F, 0xF1, 0xFF, 0xCF, 0xFF, 0x78, 0x7D, 0xE0, 0xFF, 0x03, 0xFC, 0x0F, + 0xF0, 0x3F, 0xC0, 0xFF, 0x03, 0xFE, 0x0F, 0xF8, 0x3F, 0xF8, 0xF7, 0xFF, + 0xCF, 0xFF, 0x1F, 0xFC, 0x3E, 0xF0, 0x03, 0x80, 0x1E, 0x38, 0x79, 0xFF, + 0xC7, 0xFE, 0x1F, 0xF0, 0x1F, 0x00, 0x70, 0x03, 0xC0, 0x0F, 0x00, 0x3C, + 0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x3E, 0x3F, 0xFC, 0xFF, 0xFB, 0xFF, 0xFF, + 0xC7, 0xFE, 0x0F, 0xF0, 0x3F, 0xC0, 0xFF, 0x03, 0xFC, 0x0F, 0xF0, 0x3F, + 0xC0, 0xFF, 0x03, 0xFC, 0x0F, 0xF0, 0x3F, 0xC0, 0xFF, 0x03, 0xF8, 0x0E, + 0x77, 0xFF, 0xF7, 0x01, 0xDE, 0xF7, 0xBD, 0xEF, 0x7B, 0xDE, 0xF7, 0xBD, + 0xEF, 0x7B, 0xDC, 0x00, 0x38, 0x01, 0xF0, 0x07, 0xC0, 0x1F, 0x00, 0x38, + 0x00, 0x00, 0x03, 0x80, 0x1E, 0x00, 0x78, 0x01, 0xE0, 0x07, 0x80, 0x1E, + 0x00, 0x78, 0x01, 0xE0, 0x07, 0x80, 0x1E, 0x00, 0x78, 0x01, 0xE0, 0x07, + 0x80, 0x1E, 0x00, 0x78, 0x01, 0xE0, 0x07, 0x80, 0x1E, 0x00, 0x78, 0x03, + 0xC7, 0x0F, 0x3F, 0xF8, 0xFF, 0xC3, 0xFE, 0x03, 0xE0, 0x00, 0x70, 0x01, + 0xE0, 0x03, 0xC0, 0x07, 0x80, 0x0F, 0x00, 0x1E, 0x00, 0x3C, 0x0C, 0x78, + 0x78, 0xF3, 0xF1, 0xFF, 0xC3, 0xFF, 0x07, 0xF8, 0x0F, 0xC0, 0x1F, 0xC0, + 0x3F, 0xC0, 0x7F, 0xC0, 0xFF, 0xC1, 0xFF, 0xC3, 0xDF, 0xC7, 0x9F, 0xCF, + 0x0F, 0xDE, 0x0F, 0xBC, 0x0F, 0x70, 0x0C, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x77, 0x87, 0x8F, 0xFE, 0xFE, + 0xFF, 0xFF, 0xEF, 0xFF, 0xFF, 0xF9, 0xF9, 0xFF, 0x0F, 0x0F, 0xF0, 0xF0, + 0xFF, 0x0F, 0x0F, 0xF0, 0xF0, 0xFF, 0x0F, 0x0F, 0xF0, 0xF0, 0xFF, 0x0F, + 0x0F, 0xF0, 0xF0, 0xFF, 0x0F, 0x0F, 0xF0, 0xF0, 0xFF, 0x0F, 0x0F, 0xF0, + 0xF0, 0xFE, 0x0E, 0x0E, 0x73, 0xE3, 0xFF, 0xCF, 0xFF, 0xBF, 0xFF, 0xFC, + 0x7F, 0xE0, 0xFF, 0x03, 0xFC, 0x0F, 0xF0, 0x3F, 0xC0, 0xFF, 0x03, 0xFC, + 0x0F, 0xF0, 0x3F, 0xC0, 0xFF, 0x03, 0xFC, 0x0F, 0xF0, 0x3F, 0x80, 0xE0, + 0x01, 0xF8, 0x01, 0xFF, 0x81, 0xFF, 0xF0, 0xFF, 0xFE, 0x3C, 0x1F, 0x9E, + 0x03, 0xF7, 0x00, 0x7F, 0xC0, 0x0F, 0xF0, 0x03, 0xFC, 0x00, 0xFF, 0x00, + 0x3F, 0xE0, 0x0E, 0xFC, 0x07, 0x9F, 0xC3, 0xC7, 0xFF, 0xF0, 0xFF, 0xF8, + 0x1F, 0xF8, 0x01, 0xF8, 0x00, 0x77, 0xE1, 0xFF, 0xE3, 0xFF, 0xE7, 0xFF, + 0xEF, 0x0F, 0xDE, 0x0F, 0xFC, 0x0F, 0xF8, 0x0F, 0xF0, 0x1F, 0xE0, 0x3F, + 0xC0, 0x7F, 0x80, 0xEF, 0x03, 0xDF, 0x0F, 0xBF, 0xFE, 0x7F, 0xF8, 0xFF, + 0xE1, 0xFF, 0x03, 0xC0, 0x07, 0x80, 0x0F, 0x00, 0x1E, 0x00, 0x3C, 0x00, + 0x78, 0x00, 0xE0, 0x00, 0x03, 0xFE, 0x1F, 0xFC, 0x7F, 0xF9, 0xFF, 0xF7, + 0xC7, 0xEF, 0x03, 0xFC, 0x07, 0xF8, 0x0F, 0xF0, 0x1F, 0xE0, 0x3F, 0xE0, + 0x7F, 0xC0, 0xFF, 0xC1, 0xEF, 0xE7, 0xDF, 0xFF, 0x9F, 0xFF, 0x1F, 0xFE, + 0x0F, 0xFC, 0x00, 0x78, 0x00, 0xF0, 0x01, 0xE0, 0x03, 0xC0, 0x07, 0x80, + 0x0F, 0x00, 0x1C, 0x03, 0xE3, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC7, 0x7C, + 0x03, 0xC0, 0x1E, 0x00, 0xF0, 0x07, 0x80, 0x3C, 0x01, 0xE0, 0x0F, 0x00, + 0x78, 0x03, 0xC0, 0x1E, 0x00, 0xF0, 0x07, 0x00, 0x00, 0x07, 0xC0, 0x7F, + 0xE3, 0xFF, 0x8F, 0xFE, 0x78, 0xF1, 0xF0, 0x07, 0xF0, 0x1F, 0xFC, 0x3F, + 0xF8, 0x7F, 0xF0, 0x7F, 0xC0, 0x3F, 0x00, 0x3D, 0xE0, 0xF7, 0xFF, 0x9F, + 0xFE, 0x7F, 0xE0, 0x7F, 0x00, 0x38, 0x03, 0xC0, 0x1E, 0x00, 0xF0, 0x07, + 0x80, 0x3C, 0x01, 0xFF, 0x9F, 0xFC, 0xFF, 0xE7, 0xFE, 0x1E, 0x00, 0xF0, + 0x07, 0x80, 0x3C, 0x01, 0xE0, 0x0F, 0x00, 0x7C, 0x03, 0xE0, 0x0F, 0x8E, + 0x7F, 0xF3, 0xFF, 0x8F, 0xF8, 0x3E, 0x00, 0x70, 0x1F, 0xC0, 0xFF, 0x03, + 0xFC, 0x0F, 0xF0, 0x3F, 0xC0, 0xFF, 0x03, 0xFC, 0x0F, 0xF0, 0x3F, 0xC0, + 0xFF, 0x03, 0xFC, 0x0F, 0xF0, 0x7F, 0xE1, 0xFF, 0xFF, 0xDF, 0xFF, 0x3F, + 0xFC, 0x7C, 0xE0, 0x70, 0x0F, 0xC0, 0x7F, 0x03, 0xFE, 0x0F, 0xF8, 0x39, + 0xF1, 0xE7, 0xC7, 0x0F, 0x3C, 0x3E, 0xF0, 0xFB, 0x81, 0xFE, 0x07, 0xF8, + 0x1F, 0xC0, 0x3F, 0x00, 0xF8, 0x01, 0xE0, 0x07, 0x80, 0x1C, 0x00, 0x70, + 0x00, 0x7F, 0x00, 0x0F, 0xF0, 0x70, 0xFF, 0x8F, 0x0E, 0xF8, 0xF1, 0xE7, + 0x8F, 0x9E, 0x79, 0xF9, 0xC7, 0xDF, 0x9C, 0x3D, 0xFF, 0xC3, 0xFF, 0xFC, + 0x3F, 0xBF, 0x83, 0xFB, 0xF8, 0x1F, 0x9F, 0x81, 0xF1, 0xF0, 0x1F, 0x1F, + 0x00, 0xF1, 0xF0, 0x0E, 0x0E, 0x00, 0xC0, 0xE0, 0x70, 0x1F, 0xC0, 0x7F, + 0x83, 0xFF, 0x1E, 0x7E, 0xF0, 0xFB, 0xC3, 0xFE, 0x07, 0xF0, 0x0F, 0xC0, + 0x1F, 0x00, 0xFE, 0x07, 0xFC, 0x3D, 0xF0, 0xF7, 0xE7, 0x8F, 0xFC, 0x1F, + 0xE0, 0x3F, 0x80, 0xE0, 0x30, 0x0E, 0xF0, 0x3D, 0xE0, 0x73, 0xC1, 0xE7, + 0xC3, 0xCF, 0x87, 0x0F, 0x1E, 0x1F, 0x3C, 0x3E, 0x70, 0x3F, 0xE0, 0x7F, + 0x80, 0x7F, 0x00, 0xFE, 0x01, 0xF8, 0x01, 0xF0, 0x03, 0xE0, 0x07, 0x80, + 0x0F, 0x00, 0x1E, 0x00, 0x38, 0x07, 0xF0, 0x1F, 0xE0, 0x3F, 0x80, 0x7E, + 0x00, 0x38, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0xF0, + 0x03, 0xC0, 0x1E, 0x00, 0xF0, 0x07, 0x80, 0x1E, 0x00, 0xF0, 0x07, 0x80, + 0x3C, 0x00, 0xF0, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x03, + 0x03, 0x83, 0xC3, 0xC1, 0xC1, 0xE0, 0xF0, 0x78, 0x3C, 0x1E, 0x0F, 0x07, + 0x83, 0x83, 0xC1, 0xE0, 0xF0, 0x7C, 0x3E, 0x0F, 0x07, 0x83, 0xC1, 0xE0, + 0xF0, 0x78, 0x3E, 0x1F, 0x07, 0xC3, 0xE0, 0xF0, 0x30, 0x7F, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xE0, 0x30, 0x3C, 0x1F, 0x0F, 0x83, 0xE1, 0xF0, 0x78, 0x3C, 0x1E, + 0x0F, 0x07, 0x83, 0xC1, 0xF0, 0xF8, 0x3C, 0x1E, 0x0F, 0x07, 0x07, 0x83, + 0xC1, 0xE0, 0xF0, 0x78, 0x3C, 0x1E, 0x0E, 0x0F, 0x0F, 0x0F, 0x03, 0x00, + 0x1E, 0x01, 0xFE, 0x77, 0xFF, 0xFF, 0xFF, 0xE7, 0xFB, 0x0F, 0xC0, 0x00, + 0x00 }; + +const GFXglyph aAntiCorona16pt7bGlyphs[] PROGMEM = { + { 0, 1, 1, 8, 0, 0 }, // 0x20 ' ' + { 1, 5, 24, 9, 2, -21 }, // 0x21 '!' + { 16, 9, 8, 14, 2, -21 }, // 0x22 '"' + { 25, 19, 22, 21, 1, -19 }, // 0x23 '#' + { 78, 16, 23, 20, 3, -20 }, // 0x24 '$' + { 124, 27, 23, 28, 1, -20 }, // 0x25 '%' + { 202, 17, 23, 21, 2, -20 }, // 0x26 '&' + { 251, 4, 8, 8, 2, -21 }, // 0x27 ''' + { 255, 10, 30, 11, 1, -21 }, // 0x28 '(' + { 293, 10, 30, 11, 0, -21 }, // 0x29 ')' + { 331, 14, 14, 18, 2, -22 }, // 0x2A '*' + { 356, 13, 14, 17, 2, -15 }, // 0x2B '+' + { 379, 5, 8, 9, 2, -2 }, // 0x2C ',' + { 384, 13, 4, 17, 2, -6 }, // 0x2D '-' + { 391, 5, 5, 9, 2, -2 }, // 0x2E '.' + { 395, 11, 23, 13, 1, -20 }, // 0x2F '/' + { 427, 19, 23, 21, 1, -20 }, // 0x30 '0' + { 482, 7, 23, 10, 1, -20 }, // 0x31 '1' + { 503, 16, 23, 17, 0, -20 }, // 0x32 '2' + { 549, 14, 23, 16, 1, -20 }, // 0x33 '3' + { 590, 15, 23, 17, 1, -20 }, // 0x34 '4' + { 634, 14, 23, 16, 1, -20 }, // 0x35 '5' + { 675, 17, 23, 19, 1, -20 }, // 0x36 '6' + { 724, 15, 23, 14, 0, -20 }, // 0x37 '7' + { 768, 15, 23, 17, 1, -20 }, // 0x38 '8' + { 812, 17, 23, 18, 1, -20 }, // 0x39 '9' + { 861, 5, 16, 9, 2, -13 }, // 0x3A ':' + { 871, 5, 19, 9, 2, -13 }, // 0x3B ';' + { 883, 18, 15, 19, 1, -15 }, // 0x3C '<' + { 917, 13, 11, 16, 1, -13 }, // 0x3D '=' + { 935, 18, 15, 19, 1, -15 }, // 0x3E '>' + { 969, 15, 23, 17, 1, -20 }, // 0x3F '?' + { 1013, 23, 23, 27, 2, -20 }, // 0x40 '@' + { 1080, 18, 23, 18, 0, -20 }, // 0x41 'A' + { 1132, 16, 23, 19, 2, -20 }, // 0x42 'B' + { 1178, 19, 23, 21, 1, -20 }, // 0x43 'C' + { 1233, 18, 23, 21, 2, -20 }, // 0x44 'D' + { 1285, 16, 23, 19, 2, -20 }, // 0x45 'E' + { 1331, 13, 23, 15, 2, -20 }, // 0x46 'F' + { 1369, 18, 23, 21, 1, -20 }, // 0x47 'G' + { 1421, 17, 23, 21, 2, -20 }, // 0x48 'H' + { 1470, 4, 23, 8, 2, -20 }, // 0x49 'I' + { 1482, 14, 23, 15, -1, -20 }, // 0x4A 'J' + { 1523, 17, 23, 19, 2, -20 }, // 0x4B 'K' + { 1572, 13, 23, 15, 2, -20 }, // 0x4C 'L' + { 1610, 18, 23, 22, 2, -20 }, // 0x4D 'M' + { 1662, 17, 23, 21, 2, -20 }, // 0x4E 'N' + { 1711, 23, 23, 25, 1, -20 }, // 0x4F 'O' + { 1778, 16, 23, 19, 2, -20 }, // 0x50 'P' + { 1824, 23, 23, 25, 1, -20 }, // 0x51 'Q' + { 1891, 17, 23, 20, 2, -20 }, // 0x52 'R' + { 1940, 18, 23, 20, 1, -20 }, // 0x53 'S' + { 1992, 16, 23, 18, 1, -20 }, // 0x54 'T' + { 2038, 16, 23, 20, 2, -20 }, // 0x55 'U' + { 2084, 18, 23, 19, 1, -20 }, // 0x56 'V' + { 2136, 26, 23, 27, 1, -20 }, // 0x57 'W' + { 2211, 18, 23, 20, 1, -20 }, // 0x58 'X' + { 2263, 18, 23, 20, 1, -20 }, // 0x59 'Y' + { 2315, 18, 23, 20, 1, -20 }, // 0x5A 'Z' + { 2367, 9, 30, 11, 2, -21 }, // 0x5B '[' + { 2401, 11, 23, 13, 1, -20 }, // 0x5C '\' + { 2433, 9, 30, 10, -1, -21 }, // 0x5D ']' + { 2467, 14, 13, 16, 1, -21 }, // 0x5E '^' + { 2490, 13, 4, 16, 2, 2 }, // 0x5F '_' + { 2497, 8, 9, 10, 1, -20 }, // 0x60 '`' + { 2506, 14, 18, 17, 1, -15 }, // 0x61 'a' + { 2538, 15, 24, 18, 2, -21 }, // 0x62 'b' + { 2583, 15, 18, 17, 1, -15 }, // 0x63 'c' + { 2617, 14, 24, 17, 1, -21 }, // 0x64 'd' + { 2659, 15, 18, 17, 1, -15 }, // 0x65 'e' + { 2693, 13, 25, 12, 1, -21 }, // 0x66 'f' + { 2734, 14, 25, 17, 1, -15 }, // 0x67 'g' + { 2778, 14, 24, 18, 2, -21 }, // 0x68 'h' + { 2820, 5, 24, 7, 1, -21 }, // 0x69 'i' + { 2835, 14, 31, 7, -8, -21 }, // 0x6A 'j' + { 2890, 15, 24, 17, 2, -21 }, // 0x6B 'k' + { 2935, 4, 24, 8, 2, -21 }, // 0x6C 'l' + { 2947, 20, 18, 24, 2, -15 }, // 0x6D 'm' + { 2992, 14, 18, 18, 2, -15 }, // 0x6E 'n' + { 3024, 18, 18, 20, 1, -15 }, // 0x6F 'o' + { 3065, 15, 25, 18, 2, -15 }, // 0x70 'p' + { 3112, 15, 25, 18, 1, -15 }, // 0x71 'q' + { 3159, 13, 18, 16, 2, -15 }, // 0x72 'r' + { 3189, 14, 18, 16, 1, -15 }, // 0x73 's' + { 3221, 13, 23, 15, 1, -20 }, // 0x74 't' + { 3259, 14, 18, 18, 2, -15 }, // 0x75 'u' + { 3291, 14, 18, 16, 1, -15 }, // 0x76 'v' + { 3323, 20, 18, 22, 1, -15 }, // 0x77 'w' + { 3368, 14, 18, 16, 1, -15 }, // 0x78 'x' + { 3400, 15, 25, 16, 1, -15 }, // 0x79 'y' + { 3447, 14, 18, 16, 1, -15 }, // 0x7A 'z' + { 3479, 9, 30, 9, 0, -21 }, // 0x7B '{' + { 3513, 4, 33, 8, 2, -21 }, // 0x7C '|' + { 3530, 9, 30, 9, 0, -21 }, // 0x7D '}' + { 3564, 14, 7, 17, 2, -10 } }; // 0x7E '~' + +const GFXfont aAntiCorona16pt7b PROGMEM = { + (uint8_t *)aAntiCorona16pt7bBitmaps, + (GFXglyph *)aAntiCorona16pt7bGlyphs, + 0x20, 0x7E, 34 }; + +// Approx. 4249 bytes diff --git a/src/aAntiCorona36pt7b.h b/src/aAntiCorona36pt7b.h new file mode 100644 index 0000000..e9a4531 --- /dev/null +++ b/src/aAntiCorona36pt7b.h @@ -0,0 +1,202 @@ +const uint8_t aAntiCorona36pt7bBitmaps[] PROGMEM = { + 0x00, 0x00, 0x1F, 0xE0, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0x00, 0x00, 0x00, + 0x3F, 0xFF, 0xE0, 0x00, 0x00, 0x3F, 0xFF, 0xFE, 0x00, 0x00, 0x1F, 0xFF, + 0xFF, 0xC0, 0x00, 0x1F, 0xFF, 0xFF, 0xF8, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, + 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xE0, 0x03, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, + 0xFF, 0xC0, 0xFF, 0xFF, 0x00, 0x7F, 0xE0, 0x07, 0xFF, 0xE0, 0x3F, 0xE0, + 0x00, 0xFF, 0xF8, 0x0F, 0xF0, 0x00, 0x1F, 0xFF, 0x07, 0xFC, 0x00, 0x03, + 0xFF, 0xC1, 0xFE, 0x00, 0x00, 0x7F, 0xF8, 0xFF, 0x80, 0x00, 0x0F, 0xFE, + 0x3F, 0xC0, 0x00, 0x03, 0xFF, 0x9F, 0xF0, 0x00, 0x00, 0x7F, 0xE7, 0xFC, + 0x00, 0x00, 0x1F, 0xFD, 0xFE, 0x00, 0x00, 0x03, 0xFF, 0x7F, 0x80, 0x00, + 0x00, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x3F, 0xFF, 0xF8, 0x00, 0x00, 0x07, + 0xFF, 0xFE, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x7F, 0xFF, + 0xE0, 0x00, 0x00, 0x1F, 0xFF, 0xF8, 0x00, 0x00, 0x07, 0xFF, 0xFE, 0x00, + 0x00, 0x01, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x7F, 0xFF, 0xF0, 0x00, 0x00, + 0x1F, 0xEF, 0xFC, 0x00, 0x00, 0x07, 0xFB, 0xFF, 0x00, 0x00, 0x01, 0xFE, + 0xFF, 0xE0, 0x00, 0x00, 0xFF, 0x9F, 0xF8, 0x00, 0x00, 0x3F, 0xC7, 0xFF, + 0x00, 0x00, 0x0F, 0xF1, 0xFF, 0xC0, 0x00, 0x07, 0xFC, 0x7F, 0xF8, 0x00, + 0x01, 0xFE, 0x0F, 0xFF, 0x00, 0x00, 0xFF, 0x83, 0xFF, 0xE0, 0x00, 0x3F, + 0xC0, 0x7F, 0xFC, 0x00, 0x1F, 0xF0, 0x1F, 0xFF, 0x80, 0x0F, 0xF8, 0x03, + 0xFF, 0xFC, 0x0F, 0xFC, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x1F, 0xFF, + 0xFF, 0xFF, 0x80, 0x03, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x7F, 0xFF, 0xFF, + 0xE0, 0x00, 0x0F, 0xFF, 0xFF, 0xE0, 0x00, 0x01, 0xFF, 0xFF, 0xF0, 0x00, + 0x00, 0x1F, 0xFF, 0xF0, 0x00, 0x00, 0x03, 0xFF, 0xF0, 0x00, 0x00, 0x00, + 0x1F, 0xE0, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x7F, 0x00, 0xFF, 0x01, 0xFF, + 0x03, 0xFF, 0x07, 0xFF, 0x0F, 0xFF, 0x1F, 0xFF, 0x3F, 0xFF, 0x7F, 0xFF, + 0x7F, 0xFF, 0x7F, 0xFF, 0x7F, 0xFF, 0x7F, 0xFF, 0x7D, 0xFF, 0x01, 0xFF, + 0x01, 0xFF, 0x01, 0xFF, 0x01, 0xFF, 0x01, 0xFF, 0x01, 0xFF, 0x01, 0xFF, + 0x01, 0xFF, 0x01, 0xFF, 0x01, 0xFF, 0x01, 0xFF, 0x01, 0xFF, 0x01, 0xFF, + 0x01, 0xFF, 0x01, 0xFF, 0x01, 0xFF, 0x01, 0xFF, 0x01, 0xFF, 0x01, 0xFF, + 0x01, 0xFF, 0x01, 0xFF, 0x01, 0xFF, 0x01, 0xFF, 0x01, 0xFF, 0x01, 0xFF, + 0x01, 0xFF, 0x01, 0xFF, 0x01, 0xFF, 0x01, 0xFF, 0x01, 0xFF, 0x01, 0xFF, + 0x01, 0xFF, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFC, 0x00, 0xF0, 0x00, 0x1F, + 0xF8, 0x00, 0x00, 0x3F, 0xFF, 0xE0, 0x00, 0x3F, 0xFF, 0xFF, 0x00, 0x0F, + 0xFF, 0xFF, 0xF8, 0x03, 0xFF, 0xFF, 0xFF, 0x80, 0xFF, 0xFF, 0xFF, 0xF8, + 0x1F, 0xFF, 0xFF, 0xFF, 0x87, 0xFF, 0xFF, 0xFF, 0xF0, 0x7F, 0xFF, 0xFF, + 0xFF, 0x0F, 0xE0, 0x0F, 0xFF, 0xE0, 0xE0, 0x00, 0x7F, 0xFE, 0x00, 0x00, + 0x03, 0xFF, 0xC0, 0x00, 0x00, 0x3F, 0xF8, 0x00, 0x00, 0x03, 0xFF, 0x00, + 0x00, 0x00, 0x7F, 0xE0, 0x00, 0x00, 0x07, 0xFC, 0x00, 0x00, 0x00, 0xFF, + 0x80, 0x00, 0x00, 0x1F, 0xF0, 0x00, 0x00, 0x03, 0xFC, 0x00, 0x00, 0x00, + 0xFF, 0x80, 0x00, 0x00, 0x1F, 0xE0, 0x00, 0x00, 0x07, 0xFC, 0x00, 0x00, + 0x01, 0xFF, 0x00, 0x00, 0x00, 0x7F, 0xE0, 0x00, 0x00, 0x1F, 0xF8, 0x00, + 0x00, 0x07, 0xFE, 0x00, 0x00, 0x01, 0xFF, 0x80, 0x00, 0x00, 0x7F, 0xE0, + 0x00, 0x00, 0x1F, 0xFC, 0x00, 0x00, 0x0F, 0xFE, 0x00, 0x00, 0x03, 0xFF, + 0x80, 0x00, 0x00, 0xFF, 0xE0, 0x00, 0x00, 0x3F, 0xF8, 0x00, 0x00, 0x0F, + 0xFE, 0x00, 0x00, 0x03, 0xFF, 0x80, 0x00, 0x00, 0x7F, 0xE0, 0x00, 0x00, + 0x1F, 0xF8, 0x00, 0x00, 0x07, 0xFE, 0x00, 0x00, 0x01, 0xFF, 0x80, 0x00, + 0x00, 0x3F, 0xE0, 0x00, 0x00, 0x0F, 0xF8, 0x00, 0x00, 0x03, 0xFE, 0x00, + 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0x1F, 0xFF, 0xFF, 0xFF, 0xF3, 0xFF, + 0xFF, 0xFF, 0xFE, 0x7F, 0xFF, 0xFF, 0xFF, 0xDF, 0xFF, 0xFF, 0xFF, 0xFB, + 0xFF, 0xFF, 0xFF, 0xFE, 0x7F, 0xFF, 0xFF, 0xFF, 0xCF, 0xFF, 0xFF, 0xFF, + 0xF0, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x3F, 0xE0, 0x00, 0x01, 0xFF, + 0xFC, 0x00, 0x07, 0xFF, 0xFE, 0x00, 0x1F, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, + 0xFF, 0xC0, 0x3F, 0xFF, 0xFF, 0xE0, 0x3F, 0xFF, 0xFF, 0xE0, 0x7F, 0xFF, + 0xFF, 0xF0, 0x7F, 0xFF, 0xFF, 0xF0, 0x3F, 0x03, 0xFF, 0xF8, 0x18, 0x00, + 0xFF, 0xF8, 0x00, 0x00, 0x3F, 0xF8, 0x00, 0x00, 0x1F, 0xF8, 0x00, 0x00, + 0x1F, 0xF8, 0x00, 0x00, 0x0F, 0xF8, 0x00, 0x00, 0x0F, 0xF8, 0x00, 0x00, + 0x0F, 0xF0, 0x00, 0x00, 0x0F, 0xF0, 0x00, 0x00, 0x1F, 0xF0, 0x00, 0x00, + 0x7F, 0xE0, 0x00, 0x7F, 0xFF, 0xC0, 0x01, 0xFF, 0xFF, 0xC0, 0x03, 0xFF, + 0xFF, 0x80, 0x03, 0xFF, 0xFF, 0xE0, 0x07, 0xFF, 0xFF, 0xF0, 0x07, 0xFF, + 0xFF, 0xF8, 0x07, 0xFF, 0xFF, 0xFC, 0x07, 0xFF, 0xFF, 0xFC, 0x03, 0xFF, + 0xFF, 0xFE, 0x00, 0x00, 0xFF, 0xFE, 0x00, 0x00, 0x3F, 0xFF, 0x00, 0x00, + 0x0F, 0xFF, 0x00, 0x00, 0x07, 0xFF, 0x00, 0x00, 0x03, 0xFF, 0x00, 0x00, + 0x03, 0xFF, 0x00, 0x00, 0x01, 0xFF, 0x00, 0x00, 0x01, 0xFF, 0x00, 0x00, + 0x01, 0xFF, 0x00, 0x00, 0x01, 0xFE, 0x00, 0x00, 0x03, 0xFE, 0x0E, 0x00, + 0x07, 0xFC, 0x1F, 0xC0, 0x1F, 0xFC, 0x3F, 0xFF, 0xFF, 0xF8, 0x7F, 0xFF, + 0xFF, 0xF0, 0xFF, 0xFF, 0xFF, 0xE0, 0xFF, 0xFF, 0xFF, 0xC0, 0xFF, 0xFF, + 0xFF, 0x80, 0xFF, 0xFF, 0xFF, 0x00, 0x7F, 0xFF, 0xFC, 0x00, 0x1F, 0xFF, + 0xF0, 0x00, 0x01, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, + 0x00, 0xFC, 0x00, 0x00, 0x00, 0x7F, 0x80, 0x00, 0x00, 0x1F, 0xE0, 0x00, + 0x00, 0x0F, 0xF0, 0x00, 0x00, 0x07, 0xFC, 0x00, 0x00, 0x01, 0xFE, 0x00, + 0x00, 0x00, 0xFF, 0x80, 0x00, 0x00, 0x7F, 0xC0, 0x00, 0x00, 0x1F, 0xE0, + 0x00, 0x00, 0x0F, 0xF8, 0x00, 0x00, 0x07, 0xFC, 0x00, 0x00, 0x01, 0xFE, + 0x00, 0x00, 0x00, 0xFF, 0x81, 0xE0, 0x00, 0x7F, 0xC1, 0xFC, 0x00, 0x1F, + 0xE0, 0xFF, 0x00, 0x0F, 0xF8, 0x3F, 0xC0, 0x07, 0xFC, 0x1F, 0xF0, 0x01, + 0xFE, 0x07, 0xFC, 0x00, 0xFF, 0x81, 0xFF, 0x00, 0x7F, 0xC0, 0x7F, 0xC0, + 0x1F, 0xE0, 0x1F, 0xF0, 0x0F, 0xF8, 0x07, 0xFC, 0x07, 0xFC, 0x01, 0xFF, + 0x01, 0xFE, 0x00, 0x7F, 0xC0, 0xFF, 0x80, 0x1F, 0xF0, 0x7F, 0xC0, 0x07, + 0xFC, 0x1F, 0xE0, 0x01, 0xFF, 0x0F, 0xF8, 0x00, 0x7F, 0xC7, 0xFC, 0x00, + 0x1F, 0xF1, 0xFF, 0xFF, 0xFF, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, + 0xFF, 0xFF, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, + 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x01, 0xFF, 0x00, 0x00, 0x00, 0x7F, + 0xC0, 0x00, 0x00, 0x1F, 0xF0, 0x00, 0x00, 0x07, 0xFC, 0x00, 0x00, 0x01, + 0xFF, 0x00, 0x00, 0x00, 0x7F, 0xC0, 0x00, 0x00, 0x1F, 0xF0, 0x00, 0x00, + 0x07, 0xFC, 0x00, 0x00, 0x01, 0xFE, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x00, + 0x00, 0x1F, 0x80, 0x00, 0x00, 0x03, 0xC0, 0x01, 0xFF, 0xFF, 0xFC, 0x03, + 0xFF, 0xFF, 0xFF, 0x03, 0xFF, 0xFF, 0xFF, 0x81, 0xFF, 0xFF, 0xFF, 0xC1, + 0xFF, 0xFF, 0xFF, 0xE0, 0xFF, 0xFF, 0xFF, 0xF0, 0x7F, 0xFF, 0xFF, 0xF0, + 0x3F, 0xFF, 0xFF, 0xF0, 0x1F, 0xFF, 0xFF, 0xF0, 0x0F, 0xF8, 0x00, 0x00, + 0x07, 0xFC, 0x00, 0x00, 0x03, 0xFE, 0x00, 0x00, 0x01, 0xFF, 0x00, 0x00, + 0x00, 0xFF, 0x80, 0x00, 0x00, 0x7F, 0xC0, 0x00, 0x00, 0x3F, 0xE0, 0x00, + 0x00, 0x1F, 0xF0, 0x00, 0x00, 0x0F, 0xFF, 0xFC, 0x00, 0x07, 0xFF, 0xFF, + 0xC0, 0x03, 0xFF, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0xFE, 0x00, 0xFF, 0xFF, + 0xFF, 0xC0, 0x7F, 0xFF, 0xFF, 0xE0, 0x3F, 0xFF, 0xFF, 0xF8, 0x1F, 0xFF, + 0xFF, 0xFE, 0x0F, 0xFF, 0xFF, 0xFF, 0x03, 0xC0, 0x3F, 0xFF, 0xC0, 0x00, + 0x03, 0xFF, 0xE0, 0x00, 0x00, 0xFF, 0xF8, 0x00, 0x00, 0x1F, 0xFC, 0x00, + 0x00, 0x0F, 0xFE, 0x00, 0x00, 0x03, 0xFF, 0x00, 0x00, 0x01, 0xFF, 0x80, + 0x00, 0x00, 0x7F, 0xC0, 0x00, 0x00, 0x3F, 0xE0, 0x00, 0x00, 0x1F, 0xF0, + 0x00, 0x00, 0x0F, 0xF0, 0x00, 0x00, 0x07, 0xF8, 0x00, 0x00, 0x07, 0xFC, + 0x00, 0x00, 0x03, 0xFC, 0x06, 0x00, 0x03, 0xFE, 0x0F, 0xF0, 0x07, 0xFE, + 0x0F, 0xFF, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xFF, 0x07, 0xFF, 0xFF, 0xFF, + 0x03, 0xFF, 0xFF, 0xFF, 0x01, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, + 0x00, 0x7F, 0xFF, 0xFE, 0x00, 0x0F, 0xFF, 0xFC, 0x00, 0x00, 0x7F, 0xF0, + 0x00, 0x00, 0x00, 0x00, 0x7F, 0x80, 0x00, 0x00, 0x1F, 0xFF, 0x80, 0x00, + 0x03, 0xFF, 0xFE, 0x00, 0x00, 0x3F, 0xFF, 0xFC, 0x00, 0x03, 0xFF, 0xFF, + 0xF0, 0x00, 0x7F, 0xFF, 0xFF, 0xC0, 0x07, 0xFF, 0xFF, 0xFE, 0x00, 0x3F, + 0xFF, 0xFF, 0xF0, 0x03, 0xFF, 0xFF, 0xFF, 0x80, 0x3F, 0xF0, 0x3F, 0xFC, + 0x03, 0xFE, 0x00, 0x7F, 0xC0, 0x1F, 0xE0, 0x01, 0xFC, 0x01, 0xFF, 0x00, + 0x07, 0xC0, 0x0F, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x07, + 0xF8, 0x00, 0x00, 0x00, 0x3F, 0xC0, 0x7F, 0x80, 0x03, 0xFC, 0x1F, 0xFF, + 0xC0, 0x1F, 0xE3, 0xFF, 0xFF, 0x00, 0xFF, 0x7F, 0xFF, 0xFE, 0x07, 0xFF, + 0xFF, 0xFF, 0xF8, 0x7F, 0xFF, 0xFF, 0xFF, 0xE3, 0xFF, 0xFF, 0xFF, 0xFF, + 0x1F, 0xFF, 0xFF, 0xFF, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0xFF, 0xF0, + 0x3F, 0xFF, 0xBF, 0xFE, 0x00, 0x7F, 0xFD, 0xFF, 0xE0, 0x00, 0xFF, 0xFF, + 0xFE, 0x00, 0x03, 0xFF, 0xFF, 0xF0, 0x00, 0x1F, 0xFF, 0xFF, 0x00, 0x00, + 0x7F, 0xFF, 0xF8, 0x00, 0x03, 0xFF, 0xFF, 0xC0, 0x00, 0x0F, 0xFB, 0xFF, + 0x00, 0x00, 0x7F, 0xDF, 0xF8, 0x00, 0x03, 0xFE, 0xFF, 0xE0, 0x00, 0x1F, + 0xF7, 0xFF, 0x00, 0x00, 0xFF, 0x1F, 0xFC, 0x00, 0x07, 0xF8, 0xFF, 0xF0, + 0x00, 0x7F, 0xC7, 0xFF, 0xC0, 0x07, 0xFC, 0x1F, 0xFF, 0x00, 0x7F, 0xE0, + 0xFF, 0xFF, 0x0F, 0xFE, 0x03, 0xFF, 0xFF, 0xFF, 0xE0, 0x0F, 0xFF, 0xFF, + 0xFF, 0x00, 0x7F, 0xFF, 0xFF, 0xF0, 0x01, 0xFF, 0xFF, 0xFF, 0x00, 0x07, + 0xFF, 0xFF, 0xF0, 0x00, 0x1F, 0xFF, 0xFE, 0x00, 0x00, 0x3F, 0xFF, 0xE0, + 0x00, 0x00, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x0F, 0xFF, + 0xFF, 0xFF, 0x1F, 0xFF, 0xFF, 0xFF, 0xDF, 0xFF, 0xFF, 0xFF, 0xEF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0xFF, + 0xFF, 0xFF, 0xFD, 0xFF, 0xFF, 0xFF, 0xFC, 0x7F, 0xFF, 0xFF, 0xFE, 0x00, + 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x7F, 0x80, + 0x00, 0x00, 0x7F, 0x80, 0x00, 0x00, 0x3F, 0xC0, 0x00, 0x00, 0x1F, 0xE0, + 0x00, 0x00, 0x1F, 0xE0, 0x00, 0x00, 0x0F, 0xF0, 0x00, 0x00, 0x0F, 0xF0, + 0x00, 0x00, 0x07, 0xF8, 0x00, 0x00, 0x03, 0xFC, 0x00, 0x00, 0x03, 0xFC, + 0x00, 0x00, 0x01, 0xFE, 0x00, 0x00, 0x01, 0xFE, 0x00, 0x00, 0x00, 0xFF, + 0x00, 0x00, 0x00, 0x7F, 0x80, 0x00, 0x00, 0x7F, 0x80, 0x00, 0x00, 0x3F, + 0xC0, 0x00, 0x00, 0x3F, 0xC0, 0x00, 0x00, 0x1F, 0xE0, 0x00, 0x00, 0x0F, + 0xF0, 0x00, 0x00, 0x0F, 0xF0, 0x00, 0x00, 0x07, 0xF8, 0x00, 0x00, 0x07, + 0xF8, 0x00, 0x00, 0x03, 0xFC, 0x00, 0x00, 0x01, 0xFE, 0x00, 0x00, 0x01, + 0xFE, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, + 0x7F, 0x80, 0x00, 0x00, 0x3F, 0xC0, 0x00, 0x00, 0x3F, 0xC0, 0x00, 0x00, + 0x1F, 0xE0, 0x00, 0x00, 0x1F, 0xE0, 0x00, 0x00, 0x0F, 0xF0, 0x00, 0x00, + 0x07, 0xF8, 0x00, 0x00, 0x07, 0xF8, 0x00, 0x00, 0x03, 0xFC, 0x00, 0x00, + 0x01, 0xFC, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x7E, 0x00, 0x00, + 0x00, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFC, 0x00, 0x00, 0x1F, 0xFF, + 0x80, 0x00, 0x3F, 0xFF, 0xF0, 0x00, 0x3F, 0xFF, 0xFC, 0x00, 0x3F, 0xFF, + 0xFF, 0x00, 0x3F, 0xFF, 0xFF, 0xC0, 0x3F, 0xFF, 0xFF, 0xE0, 0x3F, 0xFF, + 0xFF, 0xF0, 0x1F, 0xFF, 0xFF, 0xFC, 0x1F, 0xF0, 0x3F, 0xFE, 0x0F, 0xF0, + 0x07, 0xFF, 0x0F, 0xF8, 0x01, 0xFF, 0x87, 0xFC, 0x00, 0x7F, 0xC3, 0xFE, + 0x00, 0x3F, 0xE1, 0xFF, 0x00, 0x1F, 0xF0, 0xFF, 0xC0, 0x0F, 0xF0, 0x7F, + 0xF0, 0x07, 0xF8, 0x3F, 0xFC, 0x03, 0xFC, 0x1F, 0xFF, 0x03, 0xFC, 0x07, + 0xFF, 0xF1, 0xFE, 0x03, 0xFF, 0xFF, 0xFE, 0x01, 0xFF, 0xFF, 0xFF, 0x00, + 0x7F, 0xFF, 0xFF, 0x00, 0x1F, 0xFF, 0xFF, 0xE0, 0x0F, 0xFF, 0xFF, 0xF8, + 0x03, 0xFF, 0xFF, 0xFE, 0x03, 0xFF, 0xFF, 0xFF, 0x83, 0xFF, 0xFF, 0xFF, + 0xC3, 0xFF, 0xFF, 0xFF, 0xF1, 0xFF, 0x0F, 0xFF, 0xF9, 0xFF, 0x00, 0x7F, + 0xFE, 0xFF, 0x80, 0x0F, 0xFF, 0x7F, 0x80, 0x03, 0xFF, 0xFF, 0xC0, 0x00, + 0xFF, 0xFF, 0xE0, 0x00, 0x7F, 0xFF, 0xF0, 0x00, 0x1F, 0xFF, 0xF8, 0x00, + 0x0F, 0xFF, 0xFE, 0x00, 0x07, 0xFF, 0xFF, 0x00, 0x03, 0xFD, 0xFF, 0xC0, + 0x01, 0xFE, 0xFF, 0xF0, 0x01, 0xFF, 0x7F, 0xFE, 0x01, 0xFF, 0x1F, 0xFF, + 0xFF, 0xFF, 0x8F, 0xFF, 0xFF, 0xFF, 0x83, 0xFF, 0xFF, 0xFF, 0x81, 0xFF, + 0xFF, 0xFF, 0xC0, 0x7F, 0xFF, 0xFF, 0xC0, 0x1F, 0xFF, 0xFF, 0x80, 0x07, + 0xFF, 0xFF, 0x80, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x0F, 0xFC, 0x00, 0x00, + 0x00, 0x01, 0xFE, 0x00, 0x00, 0x00, 0x7F, 0xFE, 0x00, 0x00, 0x0F, 0xFF, + 0xFC, 0x00, 0x01, 0xFF, 0xFF, 0xF0, 0x00, 0x1F, 0xFF, 0xFF, 0xC0, 0x01, + 0xFF, 0xFF, 0xFF, 0x00, 0x1F, 0xFF, 0xFF, 0xFC, 0x01, 0xFF, 0xFF, 0xFF, + 0xF0, 0x0F, 0xFF, 0xFF, 0xFF, 0x80, 0xFF, 0xE1, 0xFF, 0xFE, 0x0F, 0xFC, + 0x01, 0xFF, 0xF0, 0x7F, 0xC0, 0x07, 0xFF, 0xC7, 0xFC, 0x00, 0x1F, 0xFE, + 0x3F, 0xC0, 0x00, 0x7F, 0xF1, 0xFE, 0x00, 0x01, 0xFF, 0xDF, 0xF0, 0x00, + 0x0F, 0xFE, 0xFF, 0x80, 0x00, 0x3F, 0xF7, 0xFC, 0x00, 0x01, 0xFF, 0xBF, + 0xE0, 0x00, 0x07, 0xFF, 0xFF, 0x00, 0x00, 0x3F, 0xFF, 0xFC, 0x00, 0x01, + 0xFF, 0xFF, 0xF0, 0x00, 0x1F, 0xFF, 0xFF, 0x80, 0x00, 0xFF, 0xFF, 0xFE, + 0x00, 0x0F, 0xFF, 0x7F, 0xFC, 0x00, 0xFF, 0xFB, 0xFF, 0xF8, 0x1F, 0xFF, + 0xDF, 0xFF, 0xFF, 0xFF, 0xFE, 0x7F, 0xFF, 0xFF, 0xFF, 0xF1, 0xFF, 0xFF, + 0xFF, 0xFF, 0x8F, 0xFF, 0xFF, 0xFF, 0xFC, 0x3F, 0xFF, 0xFF, 0xFF, 0xC0, + 0xFF, 0xFF, 0xF9, 0xFE, 0x01, 0xFF, 0xFF, 0x8F, 0xF0, 0x03, 0xFF, 0xF0, + 0x7F, 0x80, 0x07, 0xFC, 0x07, 0xF8, 0x00, 0x00, 0x00, 0x3F, 0xC0, 0x00, + 0x00, 0x01, 0xFE, 0x00, 0x00, 0x00, 0x1F, 0xE0, 0x07, 0xC0, 0x00, 0xFF, + 0x00, 0x7F, 0x00, 0x0F, 0xF0, 0x07, 0xFC, 0x00, 0xFF, 0x00, 0x7F, 0xF8, + 0x1F, 0xF8, 0x03, 0xFF, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, 0xFF, 0xF8, 0x00, + 0xFF, 0xFF, 0xFF, 0x80, 0x07, 0xFF, 0xFF, 0xF8, 0x00, 0x1F, 0xFF, 0xFF, + 0x80, 0x00, 0x7F, 0xFF, 0xF8, 0x00, 0x01, 0xFF, 0xFF, 0x80, 0x00, 0x03, + 0xFF, 0xF0, 0x00, 0x00, 0x03, 0xFC, 0x00, 0x00, 0x1F, 0x07, 0xF1, 0xFF, + 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xC7, 0xF0, 0x7C, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x07, 0xF1, 0xFF, 0x7F, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xC7, 0xF0, 0x7C, 0x00 }; + +const GFXglyph aAntiCorona36pt7bGlyphs[] PROGMEM = { + { 0, 42, 51, 47, 3, -45 }, // 0x30 '0' + { 268, 16, 51, 20, 0, -45 }, // 0x31 '1' + { 370, 35, 51, 37, 1, -45 }, // 0x32 '2' + { 594, 32, 51, 35, 1, -45 }, // 0x33 '3' + { 798, 34, 51, 38, 1, -45 }, // 0x34 '4' + { 1015, 33, 51, 36, 1, -45 }, // 0x35 '5' + { 1226, 37, 51, 42, 3, -45 }, // 0x36 '6' + { 1462, 33, 51, 33, 0, -45 }, // 0x37 '7' + { 1673, 33, 51, 38, 3, -45 }, // 0x38 '8' + { 1884, 37, 51, 41, 2, -45 }, // 0x39 '9' + { 2120, 11, 35, 19, 4, -29 } }; // 0x3A ':' + +const GFXfont aAntiCorona36pt7b PROGMEM = { + (uint8_t *)aAntiCorona36pt7bBitmaps, + (GFXglyph *)aAntiCorona36pt7bGlyphs, + 0x30, 0x3A, 77 }; + +// Approx. 2253 bytes diff --git a/src/icons.h b/src/icons.h new file mode 100644 index 0000000..663d23e --- /dev/null +++ b/src/icons.h @@ -0,0 +1,302 @@ +// 'steps', 19x23px +const unsigned char steps [] PROGMEM = { + 0x00, 0x03, 0xc0, 0x00, 0x07, 0xe0, 0x00, 0x07, 0xe0, 0x00, 0x0f, 0xe0, 0x78, 0x0f, 0xe0, 0xfc, + 0x0f, 0xe0, 0xfc, 0x0f, 0xe0, 0xfc, 0x0f, 0xe0, 0xfe, 0x0f, 0xe0, 0xfe, 0x07, 0xc0, 0xfe, 0x07, + 0xc0, 0xfe, 0x07, 0x80, 0xfe, 0x00, 0x00, 0x7c, 0x0e, 0x00, 0x7c, 0x0f, 0x80, 0x7c, 0x1f, 0x80, + 0x20, 0x1f, 0x00, 0x06, 0x0f, 0x00, 0x3e, 0x0e, 0x00, 0x3e, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x1e, + 0x00, 0x00, 0x1e, 0x00, 0x00 +}; + +// 'ChargeMe' 40x17px +const unsigned char ChargeMe[] PROGMEM = { + 0x00, 0x3F, 0xFF, 0xF8, 0x00, 0x00, 0x3F, 0xFF, 0xF8, 0x00, 0xFF, 0xF0, 0x00, 0x18, 0x00, + 0xFF, 0xF0, 0x00, 0x18, 0x00, 0xC0, 0x30, 0x00, 0x18, 0x00, 0xC0, 0x30, 0x00, 0x18, 0x00, + 0xCE, 0x30, 0x00, 0x18, 0x00, 0xCE, 0x30, 0x00, 0x18, 0x00, 0xC0, 0x30, 0x00, 0x1F, 0xFF, + 0xCE, 0x30, 0x00, 0x18, 0x00, 0xCE, 0x30, 0x00, 0x18, 0x00, 0xC0, 0x30, 0x00, 0x18, 0x00, + 0xC0, 0x30, 0x00, 0x18, 0x00, 0xFF, 0xF0, 0x00, 0x18, 0x00, 0xFF, 0xF0, 0x00, 0x18, 0x00, + 0x00, 0x3F, 0xFF, 0xF8, 0x00, 0x00, 0x3F, 0xFF, 0xF8, 0x00 +}; + +// 'Charging' 40x17px +const unsigned char Charging[] PROGMEM = { + 0x00, 0x3F, 0xFF, 0xF8, 0x00, 0x00, 0x3F, 0xFF, 0xF8, 0x00, 0xFF, 0xF0, 0x00, 0x18, 0x00, + 0xFF, 0xF0, 0x00, 0x18, 0x00, 0xC0, 0x30, 0x00, 0x18, 0x00, 0xC0, 0x37, 0xC0, 0x18, 0x00, + 0xCE, 0x30, 0xFE, 0x18, 0x00, 0xCE, 0x30, 0x1C, 0x18, 0x00, 0xC0, 0x30, 0x38, 0x1F, 0xFF, + 0xCE, 0x30, 0x78, 0x18, 0x00, 0xCE, 0x30, 0xFE, 0x18, 0x00, 0xC0, 0x30, 0x07, 0xD8, 0x00, + 0xC0, 0x30, 0x00, 0x18, 0x00, 0xFF, 0xF0, 0x00, 0x18, 0x00, 0xFF, 0xF0, 0x00, 0x18, 0x00, + 0x00, 0x3F, 0xFF, 0xF8, 0x00, 0x00, 0x3F, 0xFF, 0xF8, 0x00 +}; + +// Menu Background. +// 'Watchy-Menu', 200x83px +const unsigned char MenuBackground[] PROGMEM = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xae, 0xd5, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xae, 0xd5, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x54, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xae, 0xd5, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xae, 0xd5, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x54, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xae, 0xd5, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xae, 0xd5, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x54, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xae, 0xd5, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xae, + 0xd5, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x54, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xae, 0xd5, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xae, 0xd5, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x54, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xae, 0xd5, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xae, 0xd5, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x54, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xae, 0xd5, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xae, 0xd5, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x54, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xae, 0xd5, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xae, + 0xd5, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x54, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xae, 0xd5, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xae, 0xd5, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x54, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xae, 0xd5, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x80, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0xd5, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x54, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xae, 0xd5, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xae, 0xd5, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x54, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xae, 0xd5, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xae, + 0xd5, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x54, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xae, 0xd5, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xae, 0xd5, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x54, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xae, 0xd5, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xae, 0xd5, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x54, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xae, 0xd5, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xae, 0xd5, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x54, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xae, 0xd5, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xae, + 0xd5, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x54, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xae, 0xd5, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xae, 0xd5, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x54, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xae, 0xd5, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xae, 0xd5, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x54, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xae, 0xd5, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xae, 0xd5, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x54, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xae, 0xd5, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xae, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x56, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21 +}; + +// 'Watchy-Options-Menu', 200x83px +const unsigned char OptionsMenuBackground [] PROGMEM = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0xff, 0x80, 0x07, 0xff, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xae, 0xff, 0x80, 0x07, 0xff, 0xd5, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xff, 0x00, 0x07, 0xff, 0xea, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xae, 0xff, 0x00, 0x07, 0xff, 0xfd, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x54, 0xff, 0x00, 0x0f, + 0xff, 0xfe, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xae, 0xff, 0x00, 0x0f, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xfe, + 0x00, 0x0f, 0xff, 0xfe, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xae, 0xf8, 0x00, 0x0f, 0xff, 0xff, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x54, 0x80, 0x00, 0x0f, 0xff, 0xfe, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xae, 0x80, 0x00, 0x1f, 0xff, 0xfd, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x80, 0x00, 0x1f, 0xfe, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xae, 0x80, 0x00, 0x3f, 0xfd, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x54, 0x80, 0x00, 0x7f, 0xfa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xae, 0x80, 0x00, + 0x7f, 0xfd, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x80, 0x00, 0xff, 0xfa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xae, + 0x80, 0x01, 0xff, 0xf5, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x54, 0x80, 0x03, 0xff, 0xfa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xae, 0x80, 0x0f, 0xff, 0xfd, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x80, 0x1f, 0xff, 0xfe, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xae, 0x80, 0xff, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x54, 0xff, 0xff, 0xff, + 0xfe, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xae, 0xff, 0xff, 0xff, 0xff, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xff, + 0xff, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xae, 0xff, 0xff, 0xff, 0xff, 0xd5, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x54, 0xff, 0xff, 0xfb, 0xff, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xae, 0xff, 0xff, 0xf5, 0x7f, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0xff, 0xff, 0xea, 0xbe, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xae, 0xff, 0xff, 0xd5, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x54, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xae, 0xff, 0xff, + 0xd5, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xae, + 0xd5, 0xff, 0xd5, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x54, 0xaa, 0xff, 0xea, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xae, 0xd5, 0x7f, 0xd5, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xaa, 0xbf, 0xea, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xae, 0xd5, 0x5f, 0xd5, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x54, 0xaa, 0xbe, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xae, 0xd5, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x80, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0xd5, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x54, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xae, 0xd5, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xae, 0xd5, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x54, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xae, 0xd5, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xae, + 0xd5, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x54, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xae, 0xd5, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xae, 0xd5, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x54, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xae, 0xd5, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xae, 0xd5, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x54, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xae, 0xd5, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xae, 0xd5, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x54, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xae, 0xd5, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xae, + 0xd5, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x54, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xae, 0xd5, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xae, 0xd5, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x54, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xae, 0xd5, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xae, 0xd5, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x54, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xae, 0xd5, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xae, 0xd5, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x54, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xae, 0xd5, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xae, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x56, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21 +}; + +// 'Watchy-PM', 6x6px +const unsigned char PMIndicator [] PROGMEM = { + 0x78, 0xfc, 0xfc, 0xfc, 0xfc, 0x78 +};