From 5f3acfadd24fcf8f0ef31a75c36180585b1c88c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Fran=C3=A7ois=20Milants?= Date: Sat, 24 Jun 2023 16:00:10 +0200 Subject: [PATCH 01/19] Set version to 1.13.0 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 57a9c32f04..83c6e98db8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.10) set(CMAKE_BUILD_TYPE Release CACHE STRING "Choose Debug or Release") -project(pinetime VERSION 1.12.0 LANGUAGES C CXX ASM) +project(pinetime VERSION 1.13.0 LANGUAGES C CXX ASM) set(CMAKE_C_STANDARD 99) set(CMAKE_CXX_STANDARD 14) From 39d5b5c3a2e71696acb3cb639ee8de1b480eb5b8 Mon Sep 17 00:00:00 2001 From: Max Friedrich Date: Sun, 9 Jul 2023 14:39:38 +0200 Subject: [PATCH 02/19] NotificationManager.h: Reorder notification struct fields to allow easier creation. (#1774) This commit changes the order for the notification struct fields to allow the creation of notifications using a string literal. ```cpp NotificationManager::Notifiation notification { "String literal with notification text", 42, NotificationManager::Categories::SimpleAlert }; ``` Co-authored-by: minacode --- src/components/ble/NotificationManager.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/components/ble/NotificationManager.h b/src/components/ble/NotificationManager.h index 09b5a5610e..189a7e1355 100644 --- a/src/components/ble/NotificationManager.h +++ b/src/components/ble/NotificationManager.h @@ -27,11 +27,12 @@ namespace Pinetime { struct Notification { using Id = uint8_t; using Idx = uint8_t; - Id id = 0; - bool valid = false; - uint8_t size; + std::array message; + uint8_t size; Categories category = Categories::Unknown; + Id id = 0; + bool valid = false; const char* Message() const; const char* Title() const; From 782ef7902f6576a7f5c2855e8cd13ab0ef650f6f Mon Sep 17 00:00:00 2001 From: TailyFair Date: Thu, 10 Aug 2023 22:32:19 +0300 Subject: [PATCH 03/19] Include repository initialization in docker build docs --- doc/buildWithDocker.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/doc/buildWithDocker.md b/doc/buildWithDocker.md index c0d425e540..670590a645 100644 --- a/doc/buildWithDocker.md +++ b/doc/buildWithDocker.md @@ -11,6 +11,16 @@ Based on Ubuntu 22.04 with the following build dependencies: - adafruit-nrfutil - lv_font_conv +## Clone the repository + +Before building, local repository must be fully initialized. + +``` +git clone https://github.com/InfiniTimeOrg/InfiniTime.git +cd InfiniTime +git submodule update --init +``` + ## Run a container to build the project The `infinitime-build` image contains all the dependencies you need. From 6d0d8c7d6373062cd084c170d2e50e1535c9e95d Mon Sep 17 00:00:00 2001 From: Max Friedrich Date: Tue, 15 Aug 2023 13:01:17 +0200 Subject: [PATCH 04/19] watchfaceanalog: Background in lvgl (#1824) * change background image to widgets This commit removes the background image for the WatchFaceAnalog and replaces it with lvgl widgets. It aims to keep the original look. * remove comments and background image --------- Co-authored-by: minacode --- src/CMakeLists.txt | 1 - src/displayapp/icons/bg_clock.c | 272 --------------------- src/displayapp/screens/WatchFaceAnalog.cpp | 40 ++- src/displayapp/screens/WatchFaceAnalog.h | 5 + 4 files changed, 40 insertions(+), 278 deletions(-) delete mode 100644 src/displayapp/icons/bg_clock.c diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d903629b17..1c6e8e6332 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -427,7 +427,6 @@ list(APPEND SOURCE_FILES displayapp/screens/settings/SettingBluetooth.cpp ## Watch faces - displayapp/icons/bg_clock.c displayapp/screens/WatchFaceAnalog.cpp displayapp/screens/WatchFaceDigital.cpp displayapp/screens/WatchFaceInfineat.cpp diff --git a/src/displayapp/icons/bg_clock.c b/src/displayapp/icons/bg_clock.c deleted file mode 100644 index a9de414609..0000000000 --- a/src/displayapp/icons/bg_clock.c +++ /dev/null @@ -1,272 +0,0 @@ -#if defined(LV_LVGL_H_INCLUDE_SIMPLE) -#include "lvgl.h" -#else -#include "lvgl/lvgl.h" -#endif - - -#ifndef LV_ATTRIBUTE_MEM_ALIGN -#define LV_ATTRIBUTE_MEM_ALIGN -#endif - -#ifndef LV_ATTRIBUTE_IMG_BG_CLOCK -#define LV_ATTRIBUTE_IMG_BG_CLOCK -#endif - -const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_LARGE_CONST LV_ATTRIBUTE_IMG_BG_CLOCK uint8_t bg_clock_map[] = { - 0x00, 0x00, 0x00, 0xff, /*Color of index 0*/ - 0x68, 0x5b, 0x44, 0xff, /*Color of index 1*/ - 0xde, 0xa5, 0x33, 0xff, /*Color of index 2*/ - 0xff, 0xff, 0xff, 0xff, /*Color of index 3*/ - - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xa4, 0x02, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0xa8, 0x0a, 0xaa, 0xaa, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6a, 0xa8, 0x0a, 0x40, 0x0a, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0xa8, 0x04, 0x00, 0x02, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0xa8, 0x00, 0x00, 0x01, 0xa4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x00, 0x00, 0x01, 0xa4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x00, 0x00, 0x01, 0xa4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x00, 0x00, 0x02, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x00, 0x00, 0x06, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x00, 0x00, 0x0a, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x00, 0x00, 0x2a, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x00, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x00, 0x01, 0xa8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x00, 0x06, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x00, 0x1a, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x00, 0x2a, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xd0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x00, 0xa9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x02, 0xa4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xf4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x0a, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xd0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x1a, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xf4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x1a, 0xaa, 0xaa, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xf0, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x1a, 0xaa, 0xaa, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x05, 0x55, 0x55, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x07, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xd0, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x0f, 0xf4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xf0, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xf4, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xf4, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x40, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x05, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x50, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, - 0x00, 0x00, 0x15, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x54, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x15, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x54, 0x00, - 0x00, 0x01, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x40, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x55, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x55, 0x40, - 0x00, 0x15, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x50, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xf4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xa4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1a, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xa4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1a, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xa4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1a, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, - 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xf4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x55, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x55, 0x40, - 0x01, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x40, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, - 0x00, 0x15, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x54, 0x00, - 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x05, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x50, 0x00, 0x00, - 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x55, 0x00, 0x00, - 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x55, 0x52, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xaa, 0xa8, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0xaa, 0xa1, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x01, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x40, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x15, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x06, 0x45, 0x01, 0x45, 0x40, 0x00, 0x54, 0x00, 0x60, 0x01, 0x40, 0x45, 0x50, 0x15, 0x00, 0x05, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x54, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x02, 0x46, 0x02, 0xaa, 0xa4, 0x06, 0x9a, 0x40, 0x60, 0x01, 0x80, 0xaa, 0xa9, 0xaa, 0x80, 0x1a, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x02, 0x46, 0x02, 0x90, 0x28, 0x19, 0x01, 0x80, 0x60, 0x01, 0x80, 0xa0, 0x1a, 0x40, 0x90, 0x64, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x0a, 0x06, 0x02, 0x80, 0x18, 0x18, 0x00, 0x90, 0x60, 0x01, 0x80, 0x90, 0x0a, 0x00, 0xa0, 0xa0, 0x02, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xaa, 0xa9, 0x06, 0x02, 0x40, 0x18, 0x2a, 0xaa, 0x90, 0x60, 0x01, 0x80, 0x90, 0x09, 0x00, 0x60, 0xaa, 0xaa, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x95, 0x50, 0x06, 0x02, 0x40, 0x18, 0x28, 0x00, 0x00, 0x60, 0x01, 0x80, 0x90, 0x09, 0x00, 0x60, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x06, 0x02, 0x40, 0x18, 0x19, 0x00, 0x00, 0x60, 0x01, 0x80, 0x90, 0x09, 0x00, 0x60, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x06, 0x02, 0x40, 0x18, 0x0a, 0x56, 0x80, 0x60, 0x01, 0x80, 0x90, 0x09, 0x00, 0x60, 0x29, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x06, 0x02, 0x40, 0x18, 0x01, 0xa9, 0x00, 0x60, 0x01, 0x80, 0x90, 0x09, 0x00, 0x60, 0x06, 0xa4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xd0, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x1f, 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xf4, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x0f, 0xd0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xf0, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xf4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xf4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xf4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0xf4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x0a, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x0a, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x40, 0x00, 0x01, 0x40, 0x00, 0x0a, 0xa0, 0x00, 0x01, 0x00, 0x00, 0x01, 0x40, 0x00, 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x01, 0x40, 0x00, 0x0a, 0xa0, 0x00, 0x01, 0x40, 0x00, 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x01, 0x40, 0x00, 0x0a, 0xa0, 0x00, 0x01, 0x40, 0x00, 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x40, 0x00, 0x0a, 0xa0, 0x00, 0x01, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x0a, 0xa0, 0x00, 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x0a, 0xa0, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -}; - -const lv_img_dsc_t bg_clock = { - .header.always_zero = 0, - .header.w = 240, - .header.h = 240, - .data_size = 14416, - .header.cf = LV_IMG_CF_INDEXED_2BIT, - .data = bg_clock_map, -}; - diff --git a/src/displayapp/screens/WatchFaceAnalog.cpp b/src/displayapp/screens/WatchFaceAnalog.cpp index 76d01cf1e0..2b27ad6402 100644 --- a/src/displayapp/screens/WatchFaceAnalog.cpp +++ b/src/displayapp/screens/WatchFaceAnalog.cpp @@ -8,8 +8,6 @@ #include "components/settings/Settings.h" #include "displayapp/InfiniTimeTheme.h" -LV_IMG_DECLARE(bg_clock); - using namespace Pinetime::Applications::Screens; namespace { @@ -60,9 +58,41 @@ WatchFaceAnalog::WatchFaceAnalog(Controllers::DateTime& dateTimeController, sMinute = 99; sSecond = 99; - lv_obj_t* bg_clock_img = lv_img_create(lv_scr_act(), nullptr); - lv_img_set_src(bg_clock_img, &bg_clock); - lv_obj_align(bg_clock_img, nullptr, LV_ALIGN_CENTER, 0, 0); + minor_scales = lv_linemeter_create(lv_scr_act(), nullptr); + lv_linemeter_set_scale(minor_scales, 300, 51); + lv_linemeter_set_angle_offset(minor_scales, 180); + lv_obj_set_size(minor_scales, 240, 240); + lv_obj_align(minor_scales, nullptr, LV_ALIGN_CENTER, 0, 0); + lv_obj_set_style_local_bg_opa(minor_scales, LV_LINEMETER_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_TRANSP); + lv_obj_set_style_local_scale_width(minor_scales, LV_LINEMETER_PART_MAIN, LV_STATE_DEFAULT, 4); + lv_obj_set_style_local_scale_end_line_width(minor_scales, LV_LINEMETER_PART_MAIN, LV_STATE_DEFAULT, 1); + lv_obj_set_style_local_scale_end_color(minor_scales, LV_LINEMETER_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_GRAY); + + major_scales = lv_linemeter_create(lv_scr_act(), nullptr); + lv_linemeter_set_scale(major_scales, 300, 11); + lv_linemeter_set_angle_offset(major_scales, 180); + lv_obj_set_size(major_scales, 240, 240); + lv_obj_align(major_scales, nullptr, LV_ALIGN_CENTER, 0, 0); + lv_obj_set_style_local_bg_opa(major_scales, LV_LINEMETER_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_TRANSP); + lv_obj_set_style_local_scale_width(major_scales, LV_LINEMETER_PART_MAIN, LV_STATE_DEFAULT, 6); + lv_obj_set_style_local_scale_end_line_width(major_scales, LV_LINEMETER_PART_MAIN, LV_STATE_DEFAULT, 4); + lv_obj_set_style_local_scale_end_color(major_scales, LV_LINEMETER_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_WHITE); + + large_scales = lv_linemeter_create(lv_scr_act(), nullptr); + lv_linemeter_set_scale(large_scales, 180, 3); + lv_linemeter_set_angle_offset(large_scales, 180); + lv_obj_set_size(large_scales, 240, 240); + lv_obj_align(large_scales, nullptr, LV_ALIGN_CENTER, 0, 0); + lv_obj_set_style_local_bg_opa(large_scales, LV_LINEMETER_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_TRANSP); + lv_obj_set_style_local_scale_width(large_scales, LV_LINEMETER_PART_MAIN, LV_STATE_DEFAULT, 20); + lv_obj_set_style_local_scale_end_line_width(large_scales, LV_LINEMETER_PART_MAIN, LV_STATE_DEFAULT, 4); + lv_obj_set_style_local_scale_end_color(large_scales, LV_LINEMETER_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_AQUA); + + twelve = lv_label_create(lv_scr_act(), nullptr); + lv_label_set_align(twelve, LV_LABEL_ALIGN_CENTER); + lv_label_set_text_static(twelve, "12"); + lv_obj_set_pos(twelve, 110, 10); + lv_obj_set_style_local_text_color(twelve, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_AQUA); batteryIcon.Create(lv_scr_act()); lv_obj_align(batteryIcon.GetObject(), nullptr, LV_ALIGN_IN_TOP_RIGHT, 0, 0); diff --git a/src/displayapp/screens/WatchFaceAnalog.h b/src/displayapp/screens/WatchFaceAnalog.h index 501de11570..7e83cfcb14 100644 --- a/src/displayapp/screens/WatchFaceAnalog.h +++ b/src/displayapp/screens/WatchFaceAnalog.h @@ -46,6 +46,11 @@ namespace Pinetime { using days = std::chrono::duration>; // TODO: days is standard in c++20 Utility::DirtyValue> currentDate; + lv_obj_t* minor_scales; + lv_obj_t* major_scales; + lv_obj_t* large_scales; + lv_obj_t* twelve; + lv_obj_t* hour_body; lv_obj_t* hour_body_trace; lv_obj_t* minute_body; From 9196c18d376d4f18c686bcfec8550f9c8659d5ea Mon Sep 17 00:00:00 2001 From: SteveAmor Date: Fri, 21 Jul 2023 18:59:34 +0100 Subject: [PATCH 05/19] check closed bugs --- .github/ISSUE_TEMPLATE/bug-report.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/bug-report.yaml b/.github/ISSUE_TEMPLATE/bug-report.yaml index f032d0348e..8bf4a4268f 100644 --- a/.github/ISSUE_TEMPLATE/bug-report.yaml +++ b/.github/ISSUE_TEMPLATE/bug-report.yaml @@ -7,7 +7,7 @@ body: label: Verification description: Before submitting a bug report, check if similar issues already exist and use those issues to provide your feedback instead. options: - - label: I searched for similar bug reports and found none was relevant. + - label: I searched for similar bug reports (including closed issues) and found none was relevant. required: true - type: input id: desc-brief From cf782bb6158b6ea4a63d2239c3b1a49df138a911 Mon Sep 17 00:00:00 2001 From: SteveAmor Date: Fri, 21 Jul 2023 18:50:58 +0100 Subject: [PATCH 06/19] check closed issues --- .github/ISSUE_TEMPLATE/issue-report.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/issue-report.yaml b/.github/ISSUE_TEMPLATE/issue-report.yaml index 05cca32c4c..add6b7d5b1 100644 --- a/.github/ISSUE_TEMPLATE/issue-report.yaml +++ b/.github/ISSUE_TEMPLATE/issue-report.yaml @@ -6,7 +6,7 @@ body: label: Verification description: Before submitting an issue, check if similar issues already exist and use those issues to provide your feedback instead. options: - - label: I searched for similar issues and found none was relevant. + - label: I searched for similar issues (including closed issues) and found none was relevant. required: true - type: textarea attributes: From 6d5847e0467863addbbb1d8e85905dd5e682d145 Mon Sep 17 00:00:00 2001 From: Finlay Davidson Date: Fri, 17 Mar 2023 22:14:19 +0100 Subject: [PATCH 07/19] circularbuffer: Add circular buffer utility struct --- src/utility/CircularBuffer.h | 51 ++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 src/utility/CircularBuffer.h diff --git a/src/utility/CircularBuffer.h b/src/utility/CircularBuffer.h new file mode 100644 index 0000000000..c8abe92e4e --- /dev/null +++ b/src/utility/CircularBuffer.h @@ -0,0 +1,51 @@ +#pragma once + +#include +#include + +namespace Pinetime { + namespace Utility { + template + struct CircularBuffer { + constexpr size_t Size() const { + return S; + } + + size_t Idx() const { + return idx; + } + + T& operator[](size_t n) { + return data[(idx + n) % S]; + } + + const T& operator[](size_t n) const { + return data[(idx + n) % S]; + } + + void operator++() { + idx++; + idx %= S; + } + + void operator++(int) { + operator++(); + } + + void operator--() { + if (idx > 0) { + idx--; + } else { + idx = S - 1; + } + } + + void operator--(int) { + operator--(); + } + + std::array data; + size_t idx = 0; + }; + } +} From 47ca403857a06e6432f36b7e1f722dd9acbfd5af Mon Sep 17 00:00:00 2001 From: Finlay Davidson Date: Wed, 5 Apr 2023 10:32:27 +0200 Subject: [PATCH 08/19] shakewake: Slightly improve accuracy The accumulated speed was calculated by dividing first and multiplying after, which results in more rounding errors than if you multiply first and then divide. The values aren't big enough to overflow. --- src/components/motion/MotionController.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/components/motion/MotionController.cpp b/src/components/motion/MotionController.cpp index ef3cf81188..3572195b33 100644 --- a/src/components/motion/MotionController.cpp +++ b/src/components/motion/MotionController.cpp @@ -54,10 +54,9 @@ bool MotionController::ShouldRaiseWake(bool isSleeping) { bool MotionController::ShouldShakeWake(uint16_t thresh) { /* Currently Polling at 10hz, If this ever goes faster scalar and EMA might need adjusting */ - int32_t speed = std::abs(z - lastZ + (y / 2) - (lastY / 2) + (x / 4) - (lastX / 4)) / (time - lastTime) * 100; - //(.2 * speed) + ((1 - .2) * accumulatedSpeed); - // implemented without floats as .25Alpha - accumulatedSpeed = (speed / 5) + ((accumulatedSpeed / 5) * 4); + int32_t speed = std::abs(z - lastZ + (y - lastY) / 2 + (x - lastX) / 4) * 100 / (time - lastTime); + // (.2 * speed) + ((1 - .2) * accumulatedSpeed); + accumulatedSpeed = speed / 5 + accumulatedSpeed * 4 / 5; return accumulatedSpeed > thresh; } From 3085bb39901cd71c4e2fe006ad0c0967a66f7a80 Mon Sep 17 00:00:00 2001 From: Finlay Davidson Date: Sun, 25 Jun 2023 15:55:24 +0200 Subject: [PATCH 09/19] motioncontroller: Store acceleration history Store history of acceleration values for the y and z axes. --- src/components/motion/MotionController.cpp | 23 +++++++++++----------- src/components/motion/MotionController.h | 12 +++++------ 2 files changed, 18 insertions(+), 17 deletions(-) diff --git a/src/components/motion/MotionController.cpp b/src/components/motion/MotionController.cpp index 3572195b33..b2643a7c33 100644 --- a/src/components/motion/MotionController.cpp +++ b/src/components/motion/MotionController.cpp @@ -9,7 +9,7 @@ void MotionController::Update(int16_t x, int16_t y, int16_t z, uint32_t nbSteps) service->OnNewStepCountValue(nbSteps); } - if (service != nullptr && (this->x != x || this->y != y || this->z != z)) { + if (service != nullptr && (this->x != x || yHistory[0] != y || zHistory[0] != z)) { service->OnNewMotionValues(x, y, z); } @@ -18,10 +18,10 @@ void MotionController::Update(int16_t x, int16_t y, int16_t z, uint32_t nbSteps) lastX = this->x; this->x = x; - lastY = this->y; - this->y = y; - lastZ = this->z; - this->z = z; + yHistory++; + yHistory[0] = y; + zHistory++; + zHistory[0] = z; int32_t deltaSteps = nbSteps - this->nbSteps; if (deltaSteps > 0) { @@ -31,21 +31,21 @@ void MotionController::Update(int16_t x, int16_t y, int16_t z, uint32_t nbSteps) } bool MotionController::ShouldRaiseWake(bool isSleeping) { - if ((x + 335) <= 670 && z < 0) { + if ((x + 335) <= 670 && zHistory[0] < 0) { if (!isSleeping) { - if (y <= 0) { + if (yHistory[0] <= 0) { return false; } lastYForRaiseWake = 0; return false; } - if (y >= 0) { + if (yHistory[0] >= 0) { lastYForRaiseWake = 0; return false; } - if (y + 230 < lastYForRaiseWake) { - lastYForRaiseWake = y; + if (yHistory[0] + 230 < lastYForRaiseWake) { + lastYForRaiseWake = yHistory[0]; return true; } } @@ -54,7 +54,8 @@ bool MotionController::ShouldRaiseWake(bool isSleeping) { bool MotionController::ShouldShakeWake(uint16_t thresh) { /* Currently Polling at 10hz, If this ever goes faster scalar and EMA might need adjusting */ - int32_t speed = std::abs(z - lastZ + (y - lastY) / 2 + (x - lastX) / 4) * 100 / (time - lastTime); + int32_t speed = + std::abs(zHistory[0] - zHistory[histSize - 1] + (yHistory[0] - yHistory[histSize - 1]) / 2 + (x - lastX) / 4) * 100 / (time - lastTime); // (.2 * speed) + ((1 - .2) * accumulatedSpeed); accumulatedSpeed = speed / 5 + accumulatedSpeed * 4 / 5; diff --git a/src/components/motion/MotionController.h b/src/components/motion/MotionController.h index c524fef33f..c967530b51 100644 --- a/src/components/motion/MotionController.h +++ b/src/components/motion/MotionController.h @@ -6,6 +6,7 @@ #include "drivers/Bma421.h" #include "components/ble/MotionService.h" +#include "utility/CircularBuffer.h" namespace Pinetime { namespace Controllers { @@ -24,11 +25,11 @@ namespace Pinetime { } int16_t Y() const { - return y; + return yHistory[0]; } int16_t Z() const { - return z; + return zHistory[0]; } uint32_t NbSteps() const { @@ -70,10 +71,9 @@ namespace Pinetime { int16_t lastX = 0; int16_t x = 0; int16_t lastYForRaiseWake = 0; - int16_t lastY = 0; - int16_t y = 0; - int16_t lastZ = 0; - int16_t z = 0; + static constexpr uint8_t histSize = 8; + Utility::CircularBuffer yHistory = {}; + Utility::CircularBuffer zHistory = {}; int32_t accumulatedSpeed = 0; DeviceTypes deviceType = DeviceTypes::Unknown; From cfe21103ea197f98555d5002d389d0c24e7b5544 Mon Sep 17 00:00:00 2001 From: Finlay Davidson Date: Sun, 25 Jun 2023 15:59:34 +0200 Subject: [PATCH 10/19] motioncontroller: Add functions for analysis These are functions for converting acceleration due to gravity to angles in degrees, and some statistical analysis including the mean and variance. --- src/CMakeLists.txt | 5 ++ src/components/motion/MotionController.cpp | 57 ++++++++++++++++++++++ src/components/motion/MotionController.h | 16 ++++++ src/utility/Math.cpp | 49 +++++++++++++++++++ src/utility/Math.h | 10 ++++ 5 files changed, 137 insertions(+) create mode 100644 src/utility/Math.cpp create mode 100644 src/utility/Math.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 1c6e8e6332..8e8e96863b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -493,6 +493,8 @@ list(APPEND SOURCE_FILES buttonhandler/ButtonHandler.cpp touchhandler/TouchHandler.cpp + + utility/Math.cpp ) list(APPEND RECOVERY_SOURCE_FILES @@ -558,6 +560,8 @@ list(APPEND RECOVERY_SOURCE_FILES components/fs/FS.cpp buttonhandler/ButtonHandler.cpp touchhandler/TouchHandler.cpp + + utility/Math.cpp ) list(APPEND RECOVERYLOADER_SOURCE_FILES @@ -677,6 +681,7 @@ set(INCLUDE_FILES components/motor/MotorController.h buttonhandler/ButtonHandler.h touchhandler/TouchHandler.h + utility/Math.h ) include_directories( diff --git a/src/components/motion/MotionController.cpp b/src/components/motion/MotionController.cpp index b2643a7c33..69e418ce58 100644 --- a/src/components/motion/MotionController.cpp +++ b/src/components/motion/MotionController.cpp @@ -2,8 +2,39 @@ #include +#include "utility/Math.h" + using namespace Pinetime::Controllers; +namespace { + constexpr inline int32_t Clamp(int32_t val, int32_t min, int32_t max) { + return val < min ? min : (val > max ? max : val); + } + + // only returns meaningful values if inputs are acceleration due to gravity + int16_t DegreesRolled(int16_t y, int16_t z, int16_t prevY, int16_t prevZ) { + int16_t prevYAngle = Pinetime::Utility::Asin(Clamp(prevY * 32, -32767, 32767)); + int16_t yAngle = Pinetime::Utility::Asin(Clamp(y * 32, -32767, 32767)); + + if (z < 0 && prevZ < 0) { + return yAngle - prevYAngle; + } + if (prevZ < 0) { + if (y < 0) { + return -prevYAngle - yAngle - 180; + } + return -prevYAngle - yAngle + 180; + } + if (z < 0) { + if (y < 0) { + return prevYAngle + yAngle + 180; + } + return prevYAngle + yAngle - 180; + } + return prevYAngle - yAngle; + } +} + void MotionController::Update(int16_t x, int16_t y, int16_t z, uint32_t nbSteps) { if (this->nbSteps != nbSteps && service != nullptr) { service->OnNewStepCountValue(nbSteps); @@ -23,6 +54,8 @@ void MotionController::Update(int16_t x, int16_t y, int16_t z, uint32_t nbSteps) zHistory++; zHistory[0] = z; + stats = GetAccelStats(); + int32_t deltaSteps = nbSteps - this->nbSteps; if (deltaSteps > 0) { currentTripSteps += deltaSteps; @@ -30,6 +63,30 @@ void MotionController::Update(int16_t x, int16_t y, int16_t z, uint32_t nbSteps) this->nbSteps = nbSteps; } +MotionController::AccelStats MotionController::GetAccelStats() const { + AccelStats stats; + + for (uint8_t i = 0; i < AccelStats::numHistory; i++) { + stats.yMean += yHistory[histSize - i]; + stats.zMean += zHistory[histSize - i]; + stats.prevYMean += yHistory[1 + i]; + stats.prevZMean += zHistory[1 + i]; + } + stats.yMean /= AccelStats::numHistory; + stats.zMean /= AccelStats::numHistory; + stats.prevYMean /= AccelStats::numHistory; + stats.prevZMean /= AccelStats::numHistory; + + for (uint8_t i = 0; i < AccelStats::numHistory; i++) { + stats.yVariance += (yHistory[histSize - i] - stats.yMean) * (yHistory[histSize - i] - stats.yMean); + stats.zVariance += (zHistory[histSize - i] - stats.zMean) * (zHistory[histSize - i] - stats.zMean); + } + stats.yVariance /= AccelStats::numHistory; + stats.zVariance /= AccelStats::numHistory; + + return stats; +} + bool MotionController::ShouldRaiseWake(bool isSleeping) { if ((x + 335) <= 670 && zHistory[0] < 0) { if (!isSleeping) { diff --git a/src/components/motion/MotionController.h b/src/components/motion/MotionController.h index c967530b51..de86d44c3e 100644 --- a/src/components/motion/MotionController.h +++ b/src/components/motion/MotionController.h @@ -68,6 +68,22 @@ namespace Pinetime { TickType_t lastTime = 0; TickType_t time = 0; + struct AccelStats { + static constexpr uint8_t numHistory = 2; + + int16_t yMean = 0; + int16_t zMean = 0; + int16_t prevYMean = 0; + int16_t prevZMean = 0; + + uint32_t yVariance = 0; + uint32_t zVariance = 0; + }; + + AccelStats GetAccelStats() const; + + AccelStats stats = {}; + int16_t lastX = 0; int16_t x = 0; int16_t lastYForRaiseWake = 0; diff --git a/src/utility/Math.cpp b/src/utility/Math.cpp new file mode 100644 index 0000000000..fee4f64af3 --- /dev/null +++ b/src/utility/Math.cpp @@ -0,0 +1,49 @@ +#include "utility/Math.h" + +#include + +using namespace Pinetime::Utility; + +#ifndef PINETIME_IS_RECOVERY + +int16_t Pinetime::Utility::Asin(int16_t arg) { + int16_t a = arg < 0 ? -arg : arg; + + int16_t angle = 45; + int16_t low = 0; + int16_t high = 90; + while (low <= high) { + int16_t sinAngle = _lv_trigo_sin(angle); + int16_t sinAngleSub = _lv_trigo_sin(angle - 1); + int16_t sinAngleAdd = _lv_trigo_sin(angle + 1); + + if (a >= sinAngleSub && a <= sinAngleAdd) { + if (a <= (sinAngleSub + sinAngle) / 2) { + angle--; + } else if (a > (sinAngle + sinAngleAdd) / 2) { + angle++; + } + break; + } + + if (a < sinAngle) { + high = angle - 1; + } + + else { + low = angle + 1; + } + + angle = (low + high) / 2; + } + + return arg < 0 ? -angle : angle; +} + +#else + +int16_t Pinetime::Utility::Asin(int16_t /*arg*/) { + return 0; +} + +#endif diff --git a/src/utility/Math.h b/src/utility/Math.h new file mode 100644 index 0000000000..e8d190c72d --- /dev/null +++ b/src/utility/Math.h @@ -0,0 +1,10 @@ +#pragma once + +#include + +namespace Pinetime { + namespace Utility { + // returns the arcsin of `arg`. asin(-32767) = -90, asin(32767) = 90 + int16_t Asin(int16_t arg); + } +} From 2b1eae7f597ea6c210b4c15a73ab5ba116fc5d2a Mon Sep 17 00:00:00 2001 From: Finlay Davidson Date: Sat, 20 May 2023 01:27:00 +0200 Subject: [PATCH 11/19] raisewake: Improve raise to wake algorithm This new algorithm calculates the number of degrees that the wrist has rolled, and checks if that is above a threshold. First it checks if the wrist is still enough for the acceleration values to be considered mostly from gravity. It does this by calculating the mean over the past 2 SystemTask loops, and checking that the variance from that mean is below a threshold. Then it calculates the angle the wrist is being held at, and calculates the difference from the angle some time ago. If this difference is above the threshold, it wakes the watch. --- src/components/motion/MotionController.cpp | 32 ++++++++++------------ src/components/motion/MotionController.h | 3 +- src/systemtask/SystemTask.cpp | 2 +- 3 files changed, 16 insertions(+), 21 deletions(-) diff --git a/src/components/motion/MotionController.cpp b/src/components/motion/MotionController.cpp index 69e418ce58..feb9ead015 100644 --- a/src/components/motion/MotionController.cpp +++ b/src/components/motion/MotionController.cpp @@ -87,26 +87,22 @@ MotionController::AccelStats MotionController::GetAccelStats() const { return stats; } -bool MotionController::ShouldRaiseWake(bool isSleeping) { - if ((x + 335) <= 670 && zHistory[0] < 0) { - if (!isSleeping) { - if (yHistory[0] <= 0) { - return false; - } - lastYForRaiseWake = 0; - return false; - } +bool MotionController::ShouldRaiseWake() const { + constexpr uint32_t varianceThresh = 56 * 56; + constexpr int16_t xThresh = 384; + constexpr int16_t yThresh = -64; + constexpr int16_t rollDegreesThresh = -45; + + if (x < -xThresh || x > xThresh) { + return false; + } - if (yHistory[0] >= 0) { - lastYForRaiseWake = 0; - return false; - } - if (yHistory[0] + 230 < lastYForRaiseWake) { - lastYForRaiseWake = yHistory[0]; - return true; - } + // if the variance is below the threshold, the accelerometer values can be considered to be from acceleration due to gravity + if (stats.yVariance > varianceThresh || (stats.yMean < -724 && stats.zVariance > varianceThresh) || stats.yMean > yThresh) { + return false; } - return false; + + return DegreesRolled(stats.yMean, stats.zMean, stats.prevYMean, stats.prevZMean) < rollDegreesThresh; } bool MotionController::ShouldShakeWake(uint16_t thresh) { diff --git a/src/components/motion/MotionController.h b/src/components/motion/MotionController.h index de86d44c3e..1ad032b83f 100644 --- a/src/components/motion/MotionController.h +++ b/src/components/motion/MotionController.h @@ -45,7 +45,7 @@ namespace Pinetime { } bool ShouldShakeWake(uint16_t thresh); - bool ShouldRaiseWake(bool isSleeping); + bool ShouldRaiseWake() const; int32_t CurrentShakeSpeed() const { return accumulatedSpeed; @@ -86,7 +86,6 @@ namespace Pinetime { int16_t lastX = 0; int16_t x = 0; - int16_t lastYForRaiseWake = 0; static constexpr uint8_t histSize = 8; Utility::CircularBuffer yHistory = {}; Utility::CircularBuffer zHistory = {}; diff --git a/src/systemtask/SystemTask.cpp b/src/systemtask/SystemTask.cpp index b199d53f02..4719bb50ae 100644 --- a/src/systemtask/SystemTask.cpp +++ b/src/systemtask/SystemTask.cpp @@ -430,7 +430,7 @@ void SystemTask::UpdateMotion() { if (settingsController.GetNotificationStatus() != Controllers::Settings::Notification::Sleep) { if ((settingsController.isWakeUpModeOn(Pinetime::Controllers::Settings::WakeUpMode::RaiseWrist) && - motionController.ShouldRaiseWake(state == SystemTaskState::Sleeping)) || + motionController.ShouldRaiseWake()) || (settingsController.isWakeUpModeOn(Pinetime::Controllers::Settings::WakeUpMode::Shake) && motionController.ShouldShakeWake(settingsController.GetShakeThreshold()))) { GoToRunning(); From 0f9f606b78ffbb93b1365156d8492bbf4ee4995d Mon Sep 17 00:00:00 2001 From: FintasticMan Date: Sun, 27 Aug 2023 18:15:21 +0200 Subject: [PATCH 12/19] lowersleep: Implement Lower to Sleep functionality (#827) --- src/components/motion/MotionController.cpp | 14 ++++++++++++++ src/components/motion/MotionController.h | 1 + src/components/settings/Settings.h | 14 +++++--------- src/displayapp/screens/settings/SettingWakeUp.cpp | 6 +++--- src/displayapp/screens/settings/SettingWakeUp.h | 3 ++- src/systemtask/SystemTask.cpp | 4 ++++ 6 files changed, 29 insertions(+), 13 deletions(-) diff --git a/src/components/motion/MotionController.cpp b/src/components/motion/MotionController.cpp index feb9ead015..d28378d542 100644 --- a/src/components/motion/MotionController.cpp +++ b/src/components/motion/MotionController.cpp @@ -115,6 +115,20 @@ bool MotionController::ShouldShakeWake(uint16_t thresh) { return accumulatedSpeed > thresh; } +bool MotionController::ShouldLowerSleep() const { + if (stats.yMean < 724 || DegreesRolled(stats.yMean, stats.zMean, stats.prevYMean, stats.prevZMean) < 30) { + return false; + } + + for (uint8_t i = AccelStats::numHistory + 1; i < yHistory.Size(); i++) { + if (yHistory[i] < 265) { + return false; + } + } + + return true; +} + void MotionController::Init(Pinetime::Drivers::Bma421::DeviceTypes types) { switch (types) { case Drivers::Bma421::DeviceTypes::BMA421: diff --git a/src/components/motion/MotionController.h b/src/components/motion/MotionController.h index 1ad032b83f..0aa7823e05 100644 --- a/src/components/motion/MotionController.h +++ b/src/components/motion/MotionController.h @@ -46,6 +46,7 @@ namespace Pinetime { bool ShouldShakeWake(uint16_t thresh); bool ShouldRaiseWake() const; + bool ShouldLowerSleep() const; int32_t CurrentShakeSpeed() const { return accumulatedSpeed; diff --git a/src/components/settings/Settings.h b/src/components/settings/Settings.h index efa44fdee4..81cf492332 100644 --- a/src/components/settings/Settings.h +++ b/src/components/settings/Settings.h @@ -12,12 +12,7 @@ namespace Pinetime { enum class ClockType : uint8_t { H24, H12 }; enum class Notification : uint8_t { On, Off, Sleep }; enum class ChimesOption : uint8_t { None, Hours, HalfHours }; - enum class WakeUpMode : uint8_t { - SingleTap = 0, - DoubleTap = 1, - RaiseWrist = 2, - Shake = 3, - }; + enum class WakeUpMode : uint8_t { SingleTap = 0, DoubleTap = 1, RaiseWrist = 2, Shake = 3, LowerWrist = 4 }; enum class Colors : uint8_t { White, Silver, @@ -238,7 +233,7 @@ namespace Pinetime { } }; - std::bitset<4> getWakeUpModes() const { + std::bitset<5> getWakeUpModes() const { return settings.wakeUpMode; } @@ -279,7 +274,7 @@ namespace Pinetime { private: Pinetime::Controllers::FS& fs; - static constexpr uint32_t settingsVersion = 0x0005; + static constexpr uint32_t settingsVersion = 0x0006; struct SettingsData { uint32_t version = settingsVersion; @@ -296,8 +291,9 @@ namespace Pinetime { WatchFaceInfineat watchFaceInfineat; - std::bitset<4> wakeUpMode {0}; + std::bitset<5> wakeUpMode {0}; uint16_t shakeWakeThreshold = 150; + Controllers::BrightnessController::Levels brightLevel = Controllers::BrightnessController::Levels::Medium; }; diff --git a/src/displayapp/screens/settings/SettingWakeUp.cpp b/src/displayapp/screens/settings/SettingWakeUp.cpp index 8df34c2084..4649dc82e2 100644 --- a/src/displayapp/screens/settings/SettingWakeUp.cpp +++ b/src/displayapp/screens/settings/SettingWakeUp.cpp @@ -8,7 +8,7 @@ using namespace Pinetime::Applications::Screens; -constexpr std::array SettingWakeUp::options; +constexpr std::array SettingWakeUp::options; namespace { void event_handler(lv_obj_t* obj, lv_event_t event) { @@ -27,9 +27,9 @@ SettingWakeUp::SettingWakeUp(Pinetime::Controllers::Settings& settingsController lv_obj_set_style_local_pad_inner(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 5); lv_obj_set_style_local_border_width(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 0); - lv_obj_set_pos(container1, 10, 60); + lv_obj_set_pos(container1, 10, 35); lv_obj_set_width(container1, LV_HOR_RES - 20); - lv_obj_set_height(container1, LV_VER_RES - 50); + lv_obj_set_height(container1, LV_VER_RES - 20); lv_cont_set_layout(container1, LV_LAYOUT_COLUMN_LEFT); lv_obj_t* title = lv_label_create(lv_scr_act(), nullptr); diff --git a/src/displayapp/screens/settings/SettingWakeUp.h b/src/displayapp/screens/settings/SettingWakeUp.h index 28219ca1c4..61edabce34 100644 --- a/src/displayapp/screens/settings/SettingWakeUp.h +++ b/src/displayapp/screens/settings/SettingWakeUp.h @@ -25,11 +25,12 @@ namespace Pinetime { }; Controllers::Settings& settingsController; - static constexpr std::array options = {{ + static constexpr std::array options = {{ {Controllers::Settings::WakeUpMode::SingleTap, "Single Tap"}, {Controllers::Settings::WakeUpMode::DoubleTap, "Double Tap"}, {Controllers::Settings::WakeUpMode::RaiseWrist, "Raise Wrist"}, {Controllers::Settings::WakeUpMode::Shake, "Shake Wake"}, + {Controllers::Settings::WakeUpMode::LowerWrist, "Lower Wrist"}, }}; lv_obj_t* cbOption[options.size()]; diff --git a/src/systemtask/SystemTask.cpp b/src/systemtask/SystemTask.cpp index 4719bb50ae..e59a0ff7a4 100644 --- a/src/systemtask/SystemTask.cpp +++ b/src/systemtask/SystemTask.cpp @@ -436,6 +436,10 @@ void SystemTask::UpdateMotion() { GoToRunning(); } } + if (settingsController.isWakeUpModeOn(Pinetime::Controllers::Settings::WakeUpMode::LowerWrist) && state == SystemTaskState::Running && + motionController.ShouldLowerSleep()) { + PushMessage(Messages::GoToSleep); + } } void SystemTask::HandleButtonAction(Controllers::ButtonActions action) { From 44d1798f4f20ac4bf9f66690e49c4bd0b2d863ff Mon Sep 17 00:00:00 2001 From: JF Date: Sat, 2 Sep 2023 19:41:51 +0200 Subject: [PATCH 13/19] navigation: Move font to external memory (#1838) The TTF font used by the navigation app is ~20KB and is stored in internal flash memory. To free this space, the TTF font is now converted in 2 "atlas pictures" (pictures that contain multiple concatenated images) stored in the external flash memory. The navigation app now accesses one of those 2 files and apply an offset to display the desired picture. The corresponding documentation has also been updated. Add comments about the layout of the pictures that contain the icon and about the indexing of those icons. In documentation (buildAndProgram.md), edit the section about the debug compilation mode. Remove the part about removing the Navigation app to free some memory (since it's not relevant anymore) and explain how to selectively build parts of the firmware in Debug mode. --- doc/buildAndProgram.md | 12 +- src/displayapp/fonts/CMakeLists.txt | 2 +- src/displayapp/fonts/README.md | 14 ++ src/displayapp/fonts/fonts.json | 11 -- src/displayapp/screens/Navigation.cpp | 265 ++++++++++++++++---------- src/displayapp/screens/Navigation.h | 4 +- src/resources/images.json | 14 ++ src/resources/images/navigation0.png | Bin 0 -> 22487 bytes src/resources/images/navigation1.png | Bin 0 -> 17794 bytes 9 files changed, 209 insertions(+), 113 deletions(-) create mode 100644 src/resources/images/navigation0.png create mode 100644 src/resources/images/navigation1.png diff --git a/doc/buildAndProgram.md b/doc/buildAndProgram.md index 7909c59ccf..ea1ddae1b8 100644 --- a/doc/buildAndProgram.md +++ b/doc/buildAndProgram.md @@ -48,7 +48,17 @@ CMake configures the project according to variables you specify the command line #### (\*) Note about **CMAKE_BUILD_TYPE** By default, this variable is set to *Release*. It compiles the code with size and speed optimizations. We use this value for all the binaries we publish when we [release](https://github.com/InfiniTimeOrg/InfiniTime/releases) new versions of InfiniTime. -The *Debug* mode disables all optimizations, which makes the code easier to debug. However, the binary size will likely be too big to fit in the internal flash memory. If you want to build and debug a *Debug* binary, you'll need to disable some parts of the code. For example, the icons for the **Navigation** app use a lot of memory space. You can comment the content of `m_iconMap` in the [Navigation](https://github.com/InfiniTimeOrg/InfiniTime/blob/main/src/displayapp/screens/Navigation.h#L148) application to free some memory. +The *Debug* mode disables all optimizations, which makes the code easier to debug. However, the binary size will likely be too big to fit in the internal flash memory. If you want to build and debug a *Debug* binary, you can disable some parts of the code that are not needed for the test you want to achieve. You can also apply the *Debug* mode selectively on parts of the application by applying the `DEBUG_FLAGS` only for the part (CMake target) you want to debug. For example, let's say you want to debug code related to LittleFS, simply set the compilation options for the RELEASE configuration of the target to `DEBUG_FLAGS` (in `src/CMakeLists.txt`). This will force the compilation of that target in *Debug* mode while the rest of the project will be built in *Release* mode. Example: + +``` +target_compile_options(littlefs PRIVATE + ${COMMON_FLAGS} + $<$: ${DEBUG_FLAGS}> + $<$: ${DEBUG_FLAGS}> # Change from RELEASE_FLAGS to DEBUG_FLAGS + $<$: ${CXX_FLAGS}> + $<$: ${ASM_FLAGS}> + ) +``` #### (\*\*) Note about **BUILD_DFU** DFU files are the files you'll need to install your build of InfiniTime using OTA (over-the-air) mechanism. To generate the DFU file, the Python tool [adafruit-nrfutil](https://github.com/adafruit/Adafruit_nRF52_nrfutil) is needed on your system. Check that this tool is properly installed before enabling this option. diff --git a/src/displayapp/fonts/CMakeLists.txt b/src/displayapp/fonts/CMakeLists.txt index 5a32151ec4..22627efcad 100644 --- a/src/displayapp/fonts/CMakeLists.txt +++ b/src/displayapp/fonts/CMakeLists.txt @@ -1,5 +1,5 @@ set(FONTS jetbrains_mono_42 jetbrains_mono_76 jetbrains_mono_bold_20 - jetbrains_mono_extrabold_compressed lv_font_navi_80 lv_font_sys_48 + jetbrains_mono_extrabold_compressed lv_font_sys_48 open_sans_light fontawesome_weathericons) find_program(LV_FONT_CONV "lv_font_conv" NO_CACHE REQUIRED HINTS "${CMAKE_SOURCE_DIR}/node_modules/.bin") diff --git a/src/displayapp/fonts/README.md b/src/displayapp/fonts/README.md index b2669a788c..bcc2d49c1c 100644 --- a/src/displayapp/fonts/README.md +++ b/src/displayapp/fonts/README.md @@ -33,3 +33,17 @@ and for each font there is: ### Navigation font `navigtion.ttf` is created with the web app [icomoon](https://icomoon.io/app) by importing the svg files from `src/displayapp/icons/navigation/unique` and generating the font. `lv_font_navi_80.json` is a project file for the site, which you can import to add or remove icons. + +To save space in the internal flash memory, the navigation icons are now moved into the external flash memory. To do this, the TTF font is converted into pictures (1 for each symbol). Those pictures are then concatenated into 2 big pictures (we need two files since LVGL supports maximum 2048px width/height). At runtime, a map is used to locate the desired icon in the corresponding file at a specific offset. + +Here is the command to convert the TTF font in PNG picture: + +```shell +convert -background none -fill white -font navigation.ttf -pointsize 80 -gravity center label:"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n" navigation0.png + +convert -background none -fill white -font navigation.ttf -pointsize 80 -gravity center label:"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n" navigation1.png +``` + +*Please note that the characters after `label:` are UTF-8 characters and might not be displayed correctly in this document.* + +The characters in the TTF font range from `0xEEA480` to `0xEEA4A9`. Characters from `0xEEA480` to `0xEEA498` are stored in `navigation0.png` and the others in `navigation1.png`. Each character is 80px height so displaying a specific character consists in multiplying its index in the file by -80 and use this value as the offset when calling `lv_img_set_offset_y()`. diff --git a/src/displayapp/fonts/fonts.json b/src/displayapp/fonts/fonts.json index e65f6dd44a..bcfc365f03 100644 --- a/src/displayapp/fonts/fonts.json +++ b/src/displayapp/fonts/fonts.json @@ -64,17 +64,6 @@ "bpp": 1, "size": 48 }, - "lv_font_navi_80": { - "sources": [ - { - "file": "navigation.ttf", - "range": "0xe900-0xe929" - } - ], - "bpp": 2, - "size": 80, - "compress": true - }, "fontawesome_weathericons": { "sources": [ { diff --git a/src/displayapp/screens/Navigation.cpp b/src/displayapp/screens/Navigation.cpp index 7baea09d8e..fe2f1eb6a0 100644 --- a/src/displayapp/screens/Navigation.cpp +++ b/src/displayapp/screens/Navigation.cpp @@ -23,105 +23,166 @@ using namespace Pinetime::Applications::Screens; -LV_FONT_DECLARE(lv_font_navi_80) +/* Notes about the navigation icons : + * - Icons are generated from a TTF font converted in PNG images. Those images are all appended + * vertically into a single PNG images. Since LVGL support images width and height up to + * 2048 px, the icons needs to be split into 2 separate PNG pictures. More info in + * src/displayapp/fonts/README.md + * - To make the handling of those icons easier, they must all have the same width and height + * - Those PNG are then converted into BINARY format using the classical image generator + * (in src/resources/generate-img.py) + * - The array `iconMap` maps each icon with an index. This index corresponds to the position of + * the icon in the file. All index lower than 25 (`maxIconsPerFile`) represent icons located + * in the first file (navigation0.bin). All the other icons are located in the second file + * (navigation1.bin). Since all icons have the same height, this index must be multiplied by + * 80px (`iconHeight`) to get the actual position (in pixels) of the icon in the image. + * - This is how the images are laid out in the PNG files : + * *---------------* + * | ICON 0 | + * | FILE 0 | + * | INDEX = 0 | + * | PIXEL# = 0 | + * *---------------* + * | ICON 1 | + * | FILE 0 | + * | INDEX = 1 | + * | PIXEL# = -80 | + * *---------------* + * | ICON 2 | + * | FILE 0 | + * | INDEX = 2 | + * | PIXEL# = -160 | + * *---------------* + * | ... | + * *---------------* + * | ICON 25 | + * | FILE 1 | + * | INDEX = 25 | + * | PIXEL# = 0 | + * *---------------* + * | ICON 26 | + * | FILE 1 | + * | INDEX = 26 | + * | PIXEL# = -80 | + * *---------------* + * - The source images are located in `src/resources/navigation0.png` and `src/resources/navigation1.png` + */ namespace { - constexpr std::array, 86> m_iconMap = {{ - {"arrive-left", "\xEE\xA4\x81"}, - {"arrive-right", "\xEE\xA4\x82"}, - {"arrive-straight", "\xEE\xA4\x80"}, - {"arrive", "\xEE\xA4\x80"}, - {"close", "\xEE\xA4\x83"}, - {"continue-left", "\xEE\xA4\x85"}, - {"continue-right", "\xEE\xA4\x86"}, - {"continue-slight-left", "\xEE\xA4\x87"}, - {"continue-slight-right", "\xEE\xA4\x88"}, - {"continue-straight", "\xEE\xA4\x84"}, - {"continue-uturn", "\xEE\xA4\x89"}, - {"continue", "\xEE\xA4\x84"}, - {"depart-left", "\xEE\xA4\x8B"}, - {"depart-right", "\xEE\xA4\x8C"}, - {"depart-straight", "\xEE\xA4\x8A"}, - {"end-of-road-left", "\xEE\xA4\x8D"}, - {"end-of-road-right", "\xEE\xA4\x8E"}, - {"ferry", "\xEE\xA4\x8F"}, - {"flag", "\xEE\xA4\x90"}, - {"fork-left", "\xEE\xA4\x92"}, - {"fork-right", "\xEE\xA4\x93"}, - {"fork-slight-left", "\xEE\xA4\x94"}, - {"fork-slight-right", "\xEE\xA4\x95"}, - {"fork-straight", "\xEE\xA4\x96"}, - {"invalid", "\xEE\xA4\x84"}, - {"invalid-left", "\xEE\xA4\x85"}, - {"invalid-right", "\xEE\xA4\x86"}, - {"invalid-slight-left", "\xEE\xA4\x87"}, - {"invalid-slight-right", "\xEE\xA4\x88"}, - {"invalid-straight", "\xEE\xA4\x84"}, - {"invalid-uturn", "\xEE\xA4\x89"}, - {"merge-left", "\xEE\xA4\x97"}, - {"merge-right", "\xEE\xA4\x98"}, - {"merge-slight-left", "\xEE\xA4\x99"}, - {"merge-slight-right", "\xEE\xA4\x9A"}, - {"merge-straight", "\xEE\xA4\x84"}, - {"new-name-left", "\xEE\xA4\x85"}, - {"new-name-right", "\xEE\xA4\x86"}, - {"new-name-sharp-left", "\xEE\xA4\x9B"}, - {"new-name-sharp-right", "\xEE\xA4\x9C"}, - {"new-name-slight-left", "\xEE\xA4\x87"}, - {"new-name-slight-right", "\xEE\xA4\x88"}, - {"new-name-straight", "\xEE\xA4\x84"}, - {"notification-left", "\xEE\xA4\x85"}, - {"notification-right", "\xEE\xA4\x86"}, - {"notification-sharp-left", "\xEE\xA4\x9B"}, - {"notification-sharp-right", "\xEE\xA4\xA5"}, - {"notification-slight-left", "\xEE\xA4\x87"}, - {"notification-slight-right", "\xEE\xA4\x88"}, - {"notification-straight", "\xEE\xA4\x84"}, - {"off-ramp-left", "\xEE\xA4\x9D"}, - {"off-ramp-right", "\xEE\xA4\x9E"}, - {"off-ramp-slight-left", "\xEE\xA4\x9F"}, - {"off-ramp-slight-right", "\xEE\xA4\xA0"}, - {"on-ramp-left", "\xEE\xA4\x85"}, - {"on-ramp-right", "\xEE\xA4\x86"}, - {"on-ramp-sharp-left", "\xEE\xA4\x9B"}, - {"on-ramp-sharp-right", "\xEE\xA4\xA5"}, - {"on-ramp-slight-left", "\xEE\xA4\x87"}, - {"on-ramp-slight-right", "\xEE\xA4\x88"}, - {"on-ramp-straight", "\xEE\xA4\x84"}, - {"rotary", "\xEE\xA4\xA1"}, - {"rotary-left", "\xEE\xA4\xA2"}, - {"rotary-right", "\xEE\xA4\xA3"}, - {"rotary-sharp-left", "\xEE\xA4\xA4"}, - {"rotary-sharp-right", "\xEE\xA4\xA5"}, - {"rotary-slight-left", "\xEE\xA4\xA6"}, - {"rotary-slight-right", "\xEE\xA4\xA7"}, - {"rotary-straight", "\xEE\xA4\xA8"}, - {"roundabout", "\xEE\xA4\xA1"}, - {"roundabout-left", "\xEE\xA4\xA2"}, - {"roundabout-right", "\xEE\xA4\xA3"}, - {"roundabout-sharp-left", "\xEE\xA4\xA4"}, - {"roundabout-sharp-right", "\xEE\xA4\xA5"}, - {"roundabout-slight-left", "\xEE\xA4\xA6"}, - {"roundabout-slight-right", "\xEE\xA4\xA7"}, - {"roundabout-straight", "\xEE\xA4\xA8"}, - {"turn-left", "\xEE\xA4\x85"}, - {"turn-right", "\xEE\xA4\x86"}, - {"turn-sharp-left", "\xEE\xA4\x9B"}, - {"turn-sharp-right", "\xEE\xA4\xA5"}, - {"turn-slight-left", "\xEE\xA4\x87"}, - {"turn-slight-right", "\xEE\xA4\x88"}, - {"turn-straight", "\xEE\xA4\x84"}, - {"updown", "\xEE\xA4\xA9"}, - {"uturn", "\xEE\xA4\x89"}, + struct Icon { + const char* fileName; + int16_t offset; + }; + + constexpr uint16_t iconHeight = -80; + constexpr uint8_t flagIndex = 18; + constexpr uint8_t maxIconsPerFile = 25; + const char* iconsFile0 = "F:/images/navigation0.bin"; + const char* iconsFile1 = "F:/images/navigation1.bin"; + + constexpr std::array, 86> iconMap = {{ + {"arrive-left", 1}, + {"arrive-right", 2}, + {"arrive-straight", 0}, + {"arrive", 0}, + {"close", 3}, + {"continue-left", 5}, + {"continue-right", 6}, + {"continue-slight-left", 7}, + {"continue-slight-right", 8}, + {"continue-straight", 4}, + {"continue-uturn", 9}, + {"continue", 4}, + {"depart-left", 11}, + {"depart-right", 12}, + {"depart-straight", 10}, + {"end-of-road-left", 13}, + {"end-of-road-right", 14}, + {"ferry", 15}, + {"flag", 16}, + {"fork-left", 18}, + {"fork-right", 19}, + {"fork-slight-left", 20}, + {"fork-slight-right", 21}, + {"fork-straight", 22}, + {"invalid", 4}, + {"invalid-left", 5}, + {"invalid-right", 6}, + {"invalid-slight-left", 7}, + {"invalid-slight-right", 8}, + {"invalid-straight", 4}, + {"invalid-uturn", 9}, + {"merge-left", 23}, + {"merge-right", 24}, + {"merge-slight-left", 25}, + {"merge-slight-right", 26}, + {"merge-straight", 4}, + {"new-name-left", 5}, + {"new-name-right", 6}, + {"new-name-sharp-left", 27}, + {"new-name-sharp-right", 28}, + {"new-name-slight-left", 7}, + {"new-name-slight-right", 8}, + {"new-name-straight", 4}, + {"notification-left", 5}, + {"notification-right", 6}, + {"notification-sharp-left", 27}, + {"notification-sharp-right", 37}, + {"notification-slight-left", 7}, + {"notification-slight-right", 8}, + {"notification-straight", 4}, + {"off-ramp-left", 29}, + {"off-ramp-right", 30}, + {"off-ramp-slight-left", 31}, + {"off-ramp-slight-right", 32}, + {"on-ramp-left", 5}, + {"on-ramp-right", 6}, + {"on-ramp-sharp-left", 27}, + {"on-ramp-sharp-right", 37}, + {"on-ramp-slight-left", 7}, + {"on-ramp-slight-right", 8}, + {"on-ramp-straight", 4}, + {"rotary", 33}, + {"rotary-left", 34}, + {"rotary-right", 35}, + {"rotary-sharp-left", 36}, + {"rotary-sharp-right", 37}, + {"rotary-slight-left", 38}, + {"rotary-slight-right", 39}, + {"rotary-straight", 40}, + {"roundabout", 33}, + {"roundabout-left", 34}, + {"roundabout-right", 35}, + {"roundabout-sharp-left", 36}, + {"roundabout-sharp-right", 37}, + {"roundabout-slight-left", 38}, + {"roundabout-slight-right", 39}, + {"roundabout-straight", 40}, + {"turn-left", 5}, + {"turn-right", 6}, + {"turn-sharp-left", 27}, + {"turn-sharp-right", 37}, + {"turn-slight-left", 7}, + {"turn-slight-right", 8}, + {"turn-straight", 4}, + {"updown", 41}, + {"uturn", 9}, }}; - const char* iconForName(const std::string& icon) { - for (auto iter : m_iconMap) { + Icon GetIcon(uint8_t index) { + if (index < maxIconsPerFile) { + return {iconsFile0, static_cast(iconHeight * index)}; + } + return {iconsFile1, static_cast(iconHeight * (index - maxIconsPerFile))}; + } + + Icon GetIcon(const std::string& icon) { + for (const auto& iter : iconMap) { if (iter.first == icon) { - return iter.second; + return GetIcon(iter.second); } } - return "\xEE\xA4\x90"; + return GetIcon(flagIndex); } } @@ -130,11 +191,15 @@ namespace { * */ Navigation::Navigation(Pinetime::Controllers::NavigationService& nav) : navService(nav) { - - imgFlag = lv_label_create(lv_scr_act(), nullptr); - lv_obj_set_style_local_text_font(imgFlag, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &lv_font_navi_80); - lv_obj_set_style_local_text_color(imgFlag, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_CYAN); - lv_label_set_text_static(imgFlag, iconForName("flag")); + const auto& image = GetIcon("flag"); + imgFlag = lv_img_create(lv_scr_act(), nullptr); + lv_img_set_auto_size(imgFlag, false); + lv_obj_set_size(imgFlag, 80, 80); + lv_img_set_src(imgFlag, image.fileName); + lv_img_set_offset_x(imgFlag, 0); + lv_img_set_offset_y(imgFlag, image.offset); + lv_obj_set_style_local_image_recolor_opa(imgFlag, LV_IMG_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_COVER); + lv_obj_set_style_local_image_recolor(imgFlag, LV_IMG_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_CYAN); lv_obj_align(imgFlag, nullptr, LV_ALIGN_CENTER, 0, -60); txtNarrative = lv_label_create(lv_scr_act(), nullptr); @@ -173,7 +238,11 @@ Navigation::~Navigation() { void Navigation::Refresh() { if (flag != navService.getFlag()) { flag = navService.getFlag(); - lv_label_set_text_static(imgFlag, iconForName(flag)); + const auto& image = GetIcon(flag); + lv_img_set_src(imgFlag, image.fileName); + lv_obj_set_style_local_image_recolor_opa(imgFlag, LV_IMG_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_COVER); + lv_obj_set_style_local_image_recolor(imgFlag, LV_IMG_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_CYAN); + lv_img_set_offset_y(imgFlag, image.offset); } if (narrative != navService.getNarrative()) { diff --git a/src/displayapp/screens/Navigation.h b/src/displayapp/screens/Navigation.h index 6495edb2c3..ab81d48c73 100644 --- a/src/displayapp/screens/Navigation.h +++ b/src/displayapp/screens/Navigation.h @@ -32,7 +32,7 @@ namespace Pinetime { namespace Screens { class Navigation : public Screen { public: - Navigation(Pinetime::Controllers::NavigationService& nav); + explicit Navigation(Pinetime::Controllers::NavigationService& nav); ~Navigation() override; void Refresh() override; @@ -48,7 +48,7 @@ namespace Pinetime { std::string flag; std::string narrative; std::string manDist; - int progress; + int progress = 0; lv_task_t* taskRefresh; }; diff --git a/src/resources/images.json b/src/resources/images.json index db2ccab088..e424718808 100644 --- a/src/resources/images.json +++ b/src/resources/images.json @@ -5,5 +5,19 @@ "output_format": "bin", "binary_format": "ARGB8565_RBSWAP", "target_path": "/images/" + }, + "navigation0" : { + "sources": "images/navigation0.png", + "color_format": "CF_INDEXED_1_BIT", + "output_format": "bin", + "binary_format": "ARGB8565_RBSWAP", + "target_path": "/images/" + }, + "navigation1" : { + "sources": "images/navigation1.png", + "color_format": "CF_INDEXED_1_BIT", + "output_format": "bin", + "binary_format": "ARGB8565_RBSWAP", + "target_path": "/images/" } } diff --git a/src/resources/images/navigation0.png b/src/resources/images/navigation0.png new file mode 100644 index 0000000000000000000000000000000000000000..37d7abd842da080551e7c01ef1121b22cdd00f54 GIT binary patch literal 22487 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

qRboH=+coB;?@ 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 W5U=F?F7zB|D1)b~pUXO@geCwnKVmol literal 0 HcmV?d00001 From 0aead42fdf5137becefb11f056fe8e567e2f454a Mon Sep 17 00:00:00 2001 From: JF Date: Sat, 2 Sep 2023 19:43:39 +0200 Subject: [PATCH 14/19] navigation: Add is available (#1847) Navigation app now needs 2 images to be loaded from the resources on the external filesystem. This PR adds an 'enabled' field to the Applications struct. This field is true for all applications expect for Navigation which calls Navigation::IsAvailable(). This methods returns true if the 2 files are available in the resources. The application list disables the application (draws it in grey, disables the touch callback) if the enable flag is not set. --- src/displayapp/DisplayApp.cpp | 2 +- src/displayapp/screens/ApplicationList.cpp | 6 ++-- src/displayapp/screens/ApplicationList.h | 33 ++++++++++++---------- src/displayapp/screens/Navigation.cpp | 16 +++++++++++ src/displayapp/screens/Navigation.h | 2 ++ src/displayapp/screens/Tile.cpp | 2 +- src/displayapp/screens/Tile.h | 1 + 7 files changed, 42 insertions(+), 20 deletions(-) diff --git a/src/displayapp/DisplayApp.cpp b/src/displayapp/DisplayApp.cpp index a930fe961c..cd941f16cc 100644 --- a/src/displayapp/DisplayApp.cpp +++ b/src/displayapp/DisplayApp.cpp @@ -404,7 +404,7 @@ void DisplayApp::LoadScreen(Apps app, DisplayApp::FullRefreshDirections directio switch (app) { case Apps::Launcher: currentScreen = - std::make_unique(this, settingsController, batteryController, bleController, dateTimeController); + std::make_unique(this, settingsController, batteryController, bleController, dateTimeController, filesystem); break; case Apps::Motion: // currentScreen = std::make_unique(motionController); diff --git a/src/displayapp/screens/ApplicationList.cpp b/src/displayapp/screens/ApplicationList.cpp index 0a65a5d472..6014cf53e0 100644 --- a/src/displayapp/screens/ApplicationList.cpp +++ b/src/displayapp/screens/ApplicationList.cpp @@ -6,8 +6,6 @@ using namespace Pinetime::Applications::Screens; -constexpr std::array ApplicationList::applications; - auto ApplicationList::CreateScreenList() const { std::array()>, nScreens> screens; for (size_t i = 0; i < screens.size(); i++) { @@ -22,12 +20,14 @@ ApplicationList::ApplicationList(Pinetime::Applications::DisplayApp* app, Pinetime::Controllers::Settings& settingsController, const Pinetime::Controllers::Battery& batteryController, const Pinetime::Controllers::Ble& bleController, - Controllers::DateTime& dateTimeController) + Controllers::DateTime& dateTimeController, + Pinetime::Controllers::FS& filesystem) : app {app}, settingsController {settingsController}, batteryController {batteryController}, bleController {bleController}, dateTimeController {dateTimeController}, + filesystem{filesystem}, screens {app, settingsController.GetAppMenu(), CreateScreenList(), Screens::ScreenListModes::UpDown} { } diff --git a/src/displayapp/screens/ApplicationList.h b/src/displayapp/screens/ApplicationList.h index 7bdd115408..371ee710b5 100644 --- a/src/displayapp/screens/ApplicationList.h +++ b/src/displayapp/screens/ApplicationList.h @@ -10,6 +10,7 @@ #include "components/battery/BatteryController.h" #include "displayapp/screens/Symbols.h" #include "displayapp/screens/Tile.h" +#include "displayapp/screens/Navigation.h" namespace Pinetime { namespace Applications { @@ -20,7 +21,8 @@ namespace Pinetime { Pinetime::Controllers::Settings& settingsController, const Pinetime::Controllers::Battery& batteryController, const Pinetime::Controllers::Ble& bleController, - Controllers::DateTime& dateTimeController); + Controllers::DateTime& dateTimeController, + Pinetime::Controllers::FS& filesystem); ~ApplicationList() override; bool OnTouchEvent(TouchEvents event) override; @@ -33,26 +35,27 @@ namespace Pinetime { const Pinetime::Controllers::Battery& batteryController; const Pinetime::Controllers::Ble& bleController; Controllers::DateTime& dateTimeController; + Pinetime::Controllers::FS& filesystem; static constexpr int appsPerScreen = 6; // Increment this when more space is needed static constexpr int nScreens = 2; - static constexpr std::array applications {{ - {Symbols::stopWatch, Apps::StopWatch}, - {Symbols::clock, Apps::Alarm}, - {Symbols::hourGlass, Apps::Timer}, - {Symbols::shoe, Apps::Steps}, - {Symbols::heartBeat, Apps::HeartRate}, - {Symbols::music, Apps::Music}, - - {Symbols::paintbrush, Apps::Paint}, - {Symbols::paddle, Apps::Paddle}, - {"2", Apps::Twos}, - {Symbols::drum, Apps::Metronome}, - {Symbols::map, Apps::Navigation}, - {Symbols::none, Apps::None}, + std::array applications {{ + {Symbols::stopWatch, Apps::StopWatch, true}, + {Symbols::clock, Apps::Alarm, true}, + {Symbols::hourGlass, Apps::Timer, true}, + {Symbols::shoe, Apps::Steps, true}, + {Symbols::heartBeat, Apps::HeartRate, true}, + {Symbols::music, Apps::Music, true}, + + {Symbols::paintbrush, Apps::Paint, true}, + {Symbols::paddle, Apps::Paddle, true}, + {"2", Apps::Twos, true}, + {Symbols::drum, Apps::Metronome, true}, + {Symbols::map, Apps::Navigation, Applications::Screens::Navigation::IsAvailable(filesystem)}, + {Symbols::none, Apps::None, false}, // {"M", Apps::Motion}, }}; diff --git a/src/displayapp/screens/Navigation.cpp b/src/displayapp/screens/Navigation.cpp index fe2f1eb6a0..799ac8a9fa 100644 --- a/src/displayapp/screens/Navigation.cpp +++ b/src/displayapp/screens/Navigation.cpp @@ -265,3 +265,19 @@ void Navigation::Refresh() { } } } + +bool Navigation::IsAvailable(Pinetime::Controllers::FS& filesystem) { + lfs_file file = {}; + + if (filesystem.FileOpen(&file, "/images/navigation0.bin", LFS_O_RDONLY) < 0) { + return false; + } + filesystem.FileClose(&file); + + if (filesystem.FileOpen(&file, "/images/navigation1.bin", LFS_O_RDONLY) < 0) { + return false; + } + filesystem.FileClose(&file); + + return true; +} diff --git a/src/displayapp/screens/Navigation.h b/src/displayapp/screens/Navigation.h index ab81d48c73..eb243b011a 100644 --- a/src/displayapp/screens/Navigation.h +++ b/src/displayapp/screens/Navigation.h @@ -26,6 +26,7 @@ namespace Pinetime { namespace Controllers { class NavigationService; + class FS; } namespace Applications { @@ -36,6 +37,7 @@ namespace Pinetime { ~Navigation() override; void Refresh() override; + static bool IsAvailable(Pinetime::Controllers::FS& filesystem); private: lv_obj_t* imgFlag; diff --git a/src/displayapp/screens/Tile.cpp b/src/displayapp/screens/Tile.cpp index 1266f379f8..343755e3f0 100644 --- a/src/displayapp/screens/Tile.cpp +++ b/src/displayapp/screens/Tile.cpp @@ -76,7 +76,7 @@ Tile::Tile(uint8_t screenID, for (uint8_t i = 0; i < 6; i++) { lv_btnmatrix_set_btn_ctrl(btnm1, i, LV_BTNMATRIX_CTRL_CLICK_TRIG); - if (applications[i].application == Apps::None) { + if (applications[i].application == Apps::None || !applications[i].enabled) { lv_btnmatrix_set_btn_ctrl(btnm1, i, LV_BTNMATRIX_CTRL_DISABLED); } } diff --git a/src/displayapp/screens/Tile.h b/src/displayapp/screens/Tile.h index 91acb26c7b..8c1cd12cdc 100644 --- a/src/displayapp/screens/Tile.h +++ b/src/displayapp/screens/Tile.h @@ -19,6 +19,7 @@ namespace Pinetime { struct Applications { const char* icon; Pinetime::Applications::Apps application; + bool enabled; }; explicit Tile(uint8_t screenID, From 3a7dfdba8e5da4202155fef53673240fa0f22f5a Mon Sep 17 00:00:00 2001 From: FintasticMan Date: Mon, 18 Sep 2023 14:22:40 +0200 Subject: [PATCH 15/19] workflows: Fix InfiniSim CI build InfiniSim has removed the libpng submodule and moved it to a system dependency. --- .github/workflows/main.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 89c1b2764d..fc0f042df4 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -61,10 +61,10 @@ jobs: build-simulator: runs-on: ubuntu-22.04 steps: - - name: Install SDL2 development package + - name: Install SDL2 and libpng development package run: | sudo apt-get update - sudo apt-get -y install libsdl2-dev + sudo apt-get -y install libsdl2-dev libpng-dev - name: Install Ninja run: | @@ -82,7 +82,7 @@ jobs: - name: Get InfiniSim repo run: | git clone https://github.com/InfiniTimeOrg/InfiniSim.git --depth 1 --branch main - git -C InfiniSim submodule update --init lv_drivers libpng + git -C InfiniSim submodule update --init lv_drivers - name: CMake # disable BUILD_RESOURCES as this is already done when building the firmware From 46b664b5289f7ce7c4170d6d8a65cfd770dc855b Mon Sep 17 00:00:00 2001 From: Steve Amor Date: Mon, 28 Aug 2023 07:18:48 +0100 Subject: [PATCH 16/19] Corrects typo for make option for recovery-loader --- doc/buildAndProgram.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/buildAndProgram.md b/doc/buildAndProgram.md index ea1ddae1b8..29b9107619 100644 --- a/doc/buildAndProgram.md +++ b/doc/buildAndProgram.md @@ -98,4 +98,4 @@ Binary files are generated into the folder `src`: - **pinetime-mcuboot-app-image** : MCUBoot image of the firmware - **pinetime-mcuboot-app-dfu** : DFU file of the firmware -The same files are generated for **pinetime-recovery** and **pinetime-recoveryloader** +The same files are generated for **pinetime-recovery** and **pinetime-recovery-loader** From eac460f03094a357c679c5dede7295aa8b2e1fb1 Mon Sep 17 00:00:00 2001 From: FintasticMan Date: Fri, 6 Oct 2023 19:54:20 +0200 Subject: [PATCH 17/19] weather: Fix GetCurrent* functions returning future events (#1879) --- src/components/ble/weather/WeatherService.cpp | 27 ++++++++++++------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/src/components/ble/weather/WeatherService.cpp b/src/components/ble/weather/WeatherService.cpp index 513bb2a16b..b9a6af556c 100644 --- a/src/components/ble/weather/WeatherService.cpp +++ b/src/components/ble/weather/WeatherService.cpp @@ -404,7 +404,8 @@ namespace Pinetime { std::unique_ptr& WeatherService::GetCurrentClouds() { uint64_t currentTimestamp = GetCurrentUnixTimestamp(); for (auto&& header : this->timeline) { - if (header->eventType == WeatherData::eventtype::Clouds && IsEventStillValid(header, currentTimestamp)) { + if (header->eventType == WeatherData::eventtype::Clouds && currentTimestamp >= header->timestamp && + IsEventStillValid(header, currentTimestamp)) { return reinterpret_cast&>(header); } } @@ -415,7 +416,8 @@ namespace Pinetime { std::unique_ptr& WeatherService::GetCurrentObscuration() { uint64_t currentTimestamp = GetCurrentUnixTimestamp(); for (auto&& header : this->timeline) { - if (header->eventType == WeatherData::eventtype::Obscuration && IsEventStillValid(header, currentTimestamp)) { + if (header->eventType == WeatherData::eventtype::Obscuration && currentTimestamp >= header->timestamp && + IsEventStillValid(header, currentTimestamp)) { return reinterpret_cast&>(header); } } @@ -426,7 +428,8 @@ namespace Pinetime { std::unique_ptr& WeatherService::GetCurrentPrecipitation() { uint64_t currentTimestamp = GetCurrentUnixTimestamp(); for (auto&& header : this->timeline) { - if (header->eventType == WeatherData::eventtype::Precipitation && IsEventStillValid(header, currentTimestamp)) { + if (header->eventType == WeatherData::eventtype::Precipitation && currentTimestamp >= header->timestamp && + IsEventStillValid(header, currentTimestamp)) { return reinterpret_cast&>(header); } } @@ -437,7 +440,8 @@ namespace Pinetime { std::unique_ptr& WeatherService::GetCurrentWind() { uint64_t currentTimestamp = GetCurrentUnixTimestamp(); for (auto&& header : this->timeline) { - if (header->eventType == WeatherData::eventtype::Wind && IsEventStillValid(header, currentTimestamp)) { + if (header->eventType == WeatherData::eventtype::Wind && currentTimestamp >= header->timestamp && + IsEventStillValid(header, currentTimestamp)) { return reinterpret_cast&>(header); } } @@ -448,7 +452,8 @@ namespace Pinetime { std::unique_ptr& WeatherService::GetCurrentTemperature() { uint64_t currentTimestamp = GetCurrentUnixTimestamp(); for (auto&& header : this->timeline) { - if (header->eventType == WeatherData::eventtype::Temperature && IsEventStillValid(header, currentTimestamp)) { + if (header->eventType == WeatherData::eventtype::Temperature && currentTimestamp >= header->timestamp && + IsEventStillValid(header, currentTimestamp)) { return reinterpret_cast&>(header); } } @@ -459,7 +464,8 @@ namespace Pinetime { std::unique_ptr& WeatherService::GetCurrentHumidity() { uint64_t currentTimestamp = GetCurrentUnixTimestamp(); for (auto&& header : this->timeline) { - if (header->eventType == WeatherData::eventtype::Humidity && IsEventStillValid(header, currentTimestamp)) { + if (header->eventType == WeatherData::eventtype::Humidity && currentTimestamp >= header->timestamp && + IsEventStillValid(header, currentTimestamp)) { return reinterpret_cast&>(header); } } @@ -470,7 +476,8 @@ namespace Pinetime { std::unique_ptr& WeatherService::GetCurrentPressure() { uint64_t currentTimestamp = GetCurrentUnixTimestamp(); for (auto&& header : this->timeline) { - if (header->eventType == WeatherData::eventtype::Pressure && IsEventStillValid(header, currentTimestamp)) { + if (header->eventType == WeatherData::eventtype::Pressure && currentTimestamp >= header->timestamp && + IsEventStillValid(header, currentTimestamp)) { return reinterpret_cast&>(header); } } @@ -481,7 +488,8 @@ namespace Pinetime { std::unique_ptr& WeatherService::GetCurrentLocation() { uint64_t currentTimestamp = GetCurrentUnixTimestamp(); for (auto&& header : this->timeline) { - if (header->eventType == WeatherData::eventtype::Location && IsEventStillValid(header, currentTimestamp)) { + if (header->eventType == WeatherData::eventtype::Location && currentTimestamp >= header->timestamp && + IsEventStillValid(header, currentTimestamp)) { return reinterpret_cast&>(header); } } @@ -492,7 +500,8 @@ namespace Pinetime { std::unique_ptr& WeatherService::GetCurrentQuality() { uint64_t currentTimestamp = GetCurrentUnixTimestamp(); for (auto&& header : this->timeline) { - if (header->eventType == WeatherData::eventtype::AirQuality && IsEventStillValid(header, currentTimestamp)) { + if (header->eventType == WeatherData::eventtype::AirQuality && currentTimestamp >= header->timestamp && + IsEventStillValid(header, currentTimestamp)) { return reinterpret_cast&>(header); } } From 77546c9fe2ea22af6989dccf2f600d7f4cf8f549 Mon Sep 17 00:00:00 2001 From: Reinhold Gschweicher Date: Wed, 20 Sep 2023 21:39:09 +0200 Subject: [PATCH 18/19] lv_img_conv_py: minimal python port of node module Create a minimal python port of the node.js module `lv_img_conv`. Only the currently in use color formats `CF_INDEXED_1_BIT` and `CF_TRUE_COLOR_ALPHA` are implemented. Output only as binary with format `ARGB8565_RBSWAP`. This is enough to create the `resources-1.13.0.zip`. Python3 implements "propper" "banker's rounding" by rounding to the nearest even number. Javascript rounds to the nearest integer. To have the same output as the original JavaScript implementation add a custom rounding function, which does "school" rounding (to the nearest integer) Update CMake file in `resources` folder to call `lv_img_conf.py` instead of node module. For docker-files install `python3-pil` package for `lv_img_conv.py` script. And remove the `lv_img_conv` node installation. --- gen_img: special handling for python lv_img_conv script Not needed on Linux systems, as the shebang of the python script is read and used. But just to be sure use the python interpreter found by CMake. Also helps if tried to run on Windows host. --- doc: buildAndProgram: remove node script lv_img_conv mention Remove node script `lv_img_conv` mention and replace it for runtime-depency `python3-pil` of python script `lv_img_conv.py`. --- .devcontainer/Dockerfile | 1 + doc/buildAndProgram.md | 2 +- docker/Dockerfile | 5 +- src/resources/CMakeLists.txt | 4 +- src/resources/generate-img.py | 3 + src/resources/lv_img_conv.py | 193 ++++++++++++++++++++++++++++++++++ 6 files changed, 201 insertions(+), 7 deletions(-) create mode 100755 src/resources/lv_img_conv.py diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index 46e2facbde..e4ad5c4fa8 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -11,6 +11,7 @@ RUN apt-get update -qq \ make \ python3 \ python3-pip \ + python3-pil \ tar \ unzip \ wget \ diff --git a/doc/buildAndProgram.md b/doc/buildAndProgram.md index 29b9107619..3b4ed22c0d 100644 --- a/doc/buildAndProgram.md +++ b/doc/buildAndProgram.md @@ -42,7 +42,7 @@ CMake configures the project according to variables you specify the command line **NRF5_SDK_PATH**|path to the NRF52 SDK|`-DNRF5_SDK_PATH=/home/jf/nrf52/Pinetime/sdk`| **CMAKE_BUILD_TYPE (\*)**| Build type (Release or Debug). Release is applied by default if this variable is not specified.|`-DCMAKE_BUILD_TYPE=Debug` **BUILD_DFU (\*\*)**|Build DFU files while building (needs [adafruit-nrfutil](https://github.com/adafruit/Adafruit_nRF52_nrfutil)).|`-DBUILD_DFU=1` -**BUILD_RESOURCES (\*\*)**| Generate external resource while building (needs [lv_font_conv](https://github.com/lvgl/lv_font_conv) and [lv_img_conv](https://github.com/lvgl/lv_img_conv). |`-DBUILD_RESOURCES=1` +**BUILD_RESOURCES (\*\*)**| Generate external resource while building (needs [lv_font_conv](https://github.com/lvgl/lv_font_conv) and [python3-pil/pillow](https://pillow.readthedocs.io) module). |`-DBUILD_RESOURCES=1` **TARGET_DEVICE**|Target device, used for hardware configuration. Allowed: `PINETIME, MOY-TFK5, MOY-TIN5, MOY-TON5, MOY-UNK`|`-DTARGET_DEVICE=PINETIME` (Default) #### (\*) Note about **CMAKE_BUILD_TYPE** diff --git a/docker/Dockerfile b/docker/Dockerfile index 927160dbeb..6055659407 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -11,6 +11,7 @@ RUN apt-get update -qq \ make \ python3 \ python3-pip \ + python3-pil \ python-is-python3 \ tar \ unzip \ @@ -39,10 +40,6 @@ RUN pip3 install -Iv cryptography==3.3 RUN pip3 install cbor RUN npm i lv_font_conv@1.5.2 -g -RUN npm i ts-node@10.9.1 -g -RUN npm i @swc/core -g -RUN npm i lv_img_conv@0.3.0 -g - # build.sh knows how to compile COPY build.sh /opt/ diff --git a/src/resources/CMakeLists.txt b/src/resources/CMakeLists.txt index 0983aaffe6..3834e854fe 100644 --- a/src/resources/CMakeLists.txt +++ b/src/resources/CMakeLists.txt @@ -3,8 +3,8 @@ find_program(LV_FONT_CONV "lv_font_conv" NO_CACHE REQUIRED HINTS "${CMAKE_SOURCE_DIR}/node_modules/.bin") message(STATUS "Using ${LV_FONT_CONV} to generate font files") -find_program(LV_IMG_CONV "lv_img_conv" NO_CACHE REQUIRED - HINTS "${CMAKE_SOURCE_DIR}/node_modules/.bin") +find_program(LV_IMG_CONV "lv_img_conv.py" NO_CACHE REQUIRED + HINTS "${CMAKE_CURRENT_SOURCE_DIR}") message(STATUS "Using ${LV_IMG_CONV} to generate font files") if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.12) diff --git a/src/resources/generate-img.py b/src/resources/generate-img.py index cdbfc03048..518d22062e 100755 --- a/src/resources/generate-img.py +++ b/src/resources/generate-img.py @@ -11,6 +11,9 @@ def gen_lvconv_line(lv_img_conv: str, dest: str, color_format: str, output_format: str, binary_format: str, sources: str): args = [lv_img_conv, sources, '--force', '--output-file', dest, '--color-format', color_format, '--output-format', output_format, '--binary-format', binary_format] + if lv_img_conv.endswith(".py"): + # lv_img_conv is a python script, call with current python executable + args = [sys.executable] + args return args diff --git a/src/resources/lv_img_conv.py b/src/resources/lv_img_conv.py new file mode 100755 index 0000000000..04765462ee --- /dev/null +++ b/src/resources/lv_img_conv.py @@ -0,0 +1,193 @@ +#!/usr/bin/env python3 +import argparse +import pathlib +import sys +import decimal +from PIL import Image + + +def classify_pixel(value, bits): + def round_half_up(v): + """python3 implements "propper" "banker's rounding" by rounding to the nearest + even number. Javascript rounds to the nearest integer. + To have the same output as the original JavaScript implementation add a custom + rounding function, which does "school" rounding (to the nearest integer). + + see: https://stackoverflow.com/questions/43851273/how-to-round-float-0-5-up-to-1-0-while-still-rounding-0-45-to-0-0-as-the-usual + """ + return int(decimal.Decimal(v).quantize(decimal.Decimal('1'), rounding=decimal.ROUND_HALF_UP)) + tmp = 1 << (8 - bits) + val = round_half_up(value / tmp) * tmp + if val < 0: + val = 0 + return val + + +def test_classify_pixel(): + # test difference between round() and round_half_up() + assert classify_pixel(18, 5) == 16 + # school rounding 4.5 to 5, but banker's rounding 4.5 to 4 + assert classify_pixel(18, 6) == 20 + + +def main(): + parser = argparse.ArgumentParser() + + parser.add_argument("img", + help="Path to image to convert to C header file") + parser.add_argument("-o", "--output-file", + help="output file path (for single-image conversion)", + required=True) + parser.add_argument("-f", "--force", + help="allow overwriting the output file", + action="store_true") + parser.add_argument("-i", "--image-name", + help="name of image structure (not implemented)") + parser.add_argument("-c", "--color-format", + help="color format of image", + default="CF_TRUE_COLOR_ALPHA", + choices=[ + "CF_ALPHA_1_BIT", "CF_ALPHA_2_BIT", "CF_ALPHA_4_BIT", + "CF_ALPHA_8_BIT", "CF_INDEXED_1_BIT", "CF_INDEXED_2_BIT", "CF_INDEXED_4_BIT", + "CF_INDEXED_8_BIT", "CF_RAW", "CF_RAW_CHROMA", "CF_RAW_ALPHA", + "CF_TRUE_COLOR", "CF_TRUE_COLOR_ALPHA", "CF_TRUE_COLOR_CHROMA", "CF_RGB565A8", + ], + required=True) + parser.add_argument("-t", "--output-format", + help="output format of image", + default="bin", # default in original is 'c' + choices=["c", "bin"]) + parser.add_argument("--binary-format", + help="binary color format (needed if output-format is binary)", + default="ARGB8565_RBSWAP", + choices=["ARGB8332", "ARGB8565", "ARGB8565_RBSWAP", "ARGB8888"]) + parser.add_argument("-s", "--swap-endian", + help="swap endian of image (not implemented)", + action="store_true") + parser.add_argument("-d", "--dither", + help="enable dither (not implemented)", + action="store_true") + args = parser.parse_args() + + img_path = pathlib.Path(args.img) + out = pathlib.Path(args.output_file) + if not img_path.is_file(): + print(f"Input file is missing: '{args.img}'") + return 1 + print(f"Beginning conversion of {args.img}") + if out.exists(): + if args.force: + print(f"overwriting {args.output_file}") + else: + pritn(f"Error: refusing to overwrite {args.output_file} without -f specified.") + return 1 + out.touch() + + # only implemented the bare minimum, everything else is not implemented + if args.color_format not in ["CF_INDEXED_1_BIT", "CF_TRUE_COLOR_ALPHA"]: + raise NotImplementedError(f"argument --color-format '{args.color_format}' not implemented") + if args.output_format != "bin": + raise NotImplementedError(f"argument --output-format '{args.output_format}' not implemented") + if args.binary_format not in ["ARGB8565_RBSWAP", "ARGB8888"]: + raise NotImplementedError(f"argument --binary-format '{args.binary_format}' not implemented") + if args.image_name: + raise NotImplementedError(f"argument --image-name not implemented") + if args.swap_endian: + raise NotImplementedError(f"argument --swap-endian not implemented") + if args.dither: + raise NotImplementedError(f"argument --dither not implemented") + + # open image using Pillow + img = Image.open(img_path) + img_height = img.height + img_width = img.width + if args.color_format == "CF_TRUE_COLOR_ALPHA" and args.binary_format == "ARGB8888": + buf = bytearray(img_height*img_width*4) # 4 bytes (32 bit) per pixel + for y in range(img_height): + for x in range(img_width): + i = (y*img_width + x)*4 # buffer-index + pixel = img.getpixel((x,y)) + r, g, b, a = pixel + buf[i + 0] = r + buf[i + 1] = g + buf[i + 2] = b + buf[i + 3] = a + + elif args.color_format == "CF_TRUE_COLOR_ALPHA" and args.binary_format == "ARGB8565_RBSWAP": + buf = bytearray(img_height*img_width*3) # 3 bytes (24 bit) per pixel + for y in range(img_height): + for x in range(img_width): + i = (y*img_width + x)*3 # buffer-index + pixel = img.getpixel((x,y)) + r_act = classify_pixel(pixel[0], 5) + g_act = classify_pixel(pixel[1], 6) + b_act = classify_pixel(pixel[2], 5) + a = pixel[3] + r_act = min(r_act, 0xF8) + g_act = min(g_act, 0xFC) + b_act = min(b_act, 0xF8) + c16 = ((r_act) << 8) | ((g_act) << 3) | ((b_act) >> 3) # RGR565 + buf[i + 0] = (c16 >> 8) & 0xFF + buf[i + 1] = c16 & 0xFF + buf[i + 2] = a + + elif args.color_format == "CF_INDEXED_1_BIT": # ignore binary format, use color format as binary format + w = img_width >> 3 + if img_width & 0x07: + w+=1 + max_p = w * (img_height-1) + ((img_width-1) >> 3) + 8 # +8 for the palette + buf = bytearray(max_p+1) + + for y in range(img_height): + for x in range(img_width): + c, a = img.getpixel((x,y)) + p = w * y + (x >> 3) + 8 # +8 for the palette + buf[p] |= (c & 0x1) << (7 - (x & 0x7)) + # write palette information, for indexed-1-bit we need palette with two values + # write 8 palette bytes + buf[0] = 0 + buf[1] = 0 + buf[2] = 0 + buf[3] = 0 + # Normally there is much math behind this, but for the current use case this is close enough + # only needs to be more complicated if we have more than 2 colors in the palette + buf[4] = 255 + buf[5] = 255 + buf[6] = 255 + buf[7] = 255 + else: + # raise just to be sure + raise NotImplementedError(f"args.color_format '{args.color_format}' with args.binary_format '{args.binary_format}' not implemented") + + # write header + match args.color_format: + case "CF_TRUE_COLOR_ALPHA": + lv_cf = 5 + case "CF_INDEXED_1_BIT": + lv_cf = 7 + case _: + # raise just to be sure + raise NotImplementedError(f"args.color_format '{args.color_format}' not implemented") + header_32bit = lv_cf | (img_width << 10) | (img_height << 21) + buf_out = bytearray(4 + len(buf)) + buf_out[0] = header_32bit & 0xFF + buf_out[1] = (header_32bit & 0xFF00) >> 8 + buf_out[2] = (header_32bit & 0xFF0000) >> 16 + buf_out[3] = (header_32bit & 0xFF000000) >> 24 + buf_out[4:] = buf + + # write byte buffer to file + with open(out, "wb") as f: + f.write(buf_out) + return 0 + + +if __name__ == '__main__': + if "--test" in sys.argv: + # run small set of tests and exit + print("running tests") + test_classify_pixel() + print("success!") + sys.exit(0) + # run normal program + sys.exit(main()) From e6b96c286376454b0aeab3c1444f4d106d755b94 Mon Sep 17 00:00:00 2001 From: Reinhold Gschweicher Date: Thu, 21 Sep 2023 23:10:38 +0200 Subject: [PATCH 19/19] CI: install build resource dependency python3-pil package Used by script `lv_img_conv.py`, should be provided by docker image, but until then explicitly install in workflow. --- .github/workflows/main.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index fc0f042df4..c24e23748f 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -31,6 +31,10 @@ jobs: uses: actions/checkout@v3 with: submodules: recursive + - name: Install resource build dependencies + run: | + apt-get update + apt-get -y install --no-install-recommends python3-pil - name: Build shell: bash run: /opt/build.sh all