68 Commits
2.81 ... 2.85

Author SHA1 Message Date
atc1441
46c8b73fa0 Added V2 ATC_BLE_OEPL Advertising Handling 2026-01-18 14:53:44 +01:00
Steven Cooreman
c65c8b749e Merge pull request #518 from stevew817/master
Add boilerplate definitions for more now-known Solum BWRY tags
2025-12-14 20:06:22 +01:00
atc1441
f61c2e3d04 Update 4E.json 2025-12-11 16:21:05 +01:00
atc1441
0dc406b865 Added M3 2.6" BW 2025-12-11 12:37:56 +01:00
Steven
25b185da28 Use correct base templates for BWRY variants 2025-12-07 19:36:58 +01:00
atc1441
496d4d382f Update contentmanager.cpp 2025-12-03 21:34:48 +01:00
atc1441
d09e89c9dd Updated the WebFiles as well 2025-11-16 22:04:44 +01:00
atc1441
ce319bb499 Merge pull request #526 from urmuzov/master
Fixed the pin order for the display on the ESP32_S3_16_8_4inch_AP
2025-11-16 21:51:47 +01:00
atc1441
4dbcc753fd Merge pull request #505 from scanalyzer/patch-3
Update main.js - Support cased jpeg file extensions.
2025-11-16 21:50:40 +01:00
atc1441
6951cd79b7 Merge pull request #504 from scanalyzer/patch-2
Update painter.js - Added more font sizes to support large emojis on T-Panel and larger displays.
2025-11-16 21:49:50 +01:00
Alexander Urmuzov
eeb18f204d Fixed the pin order for the display on the ESP32_S3_16_8_4inch_AP 2025-11-16 21:47:48 +01:00
Skip Hansen
bfff2ef0b9 Added support for ts_option to provide finer control of time stamps.
1. Fixed time stamp overlap on weather forecast content on  2.9" tags.
2. Fixed time stamp overlap on AP info screen on 160x80 TFT displays.
3. Changed black on white to white on black on TFT displays.
2025-11-06 15:38:21 -05:00
atc1441
ef5ddac368 Added BWRY Preview 2025-10-30 22:59:37 +01:00
Steven
0e8e7b5b75 Add 11.6" BWRY and fix previous BWRY definitions 2025-10-28 23:18:15 +01:00
Steven
e8a92c4fcb Add definitions for more now-known Solum BWRY tags
https://github.com/OpenEPaperLink/Tag_FW_EFR32xG22/issues/11
2025-10-22 01:09:26 +02:00
BenV
299b8f300e Feat: dayahead fixes and improvements (#516) 2025-10-20 19:05:38 +02:00
Nic Limper
0b0802ad02 Update README.md 2025-10-08 14:40:36 +02:00
scanalyzer
f8ce3a51d2 Update main.js
Adding support for cased versions of jpg and jpeg.
2025-09-14 18:55:53 -07:00
scanalyzer
0e63e064fc Update painter.js
Added more font sizes to support things like a single emoji on T-Panel and larger displays.
2025-09-14 18:41:51 -07:00
atc1441
8d6c763aba Merge pull request #496 from 4rianton/Add-the-ability-to-update-time-without-NTP
Ability to update time without requiring Internet Access
2025-09-13 11:04:12 +02:00
atc1441
764747fb45 Also updated the .gz files 2025-09-12 11:32:01 +02:00
atc1441
6bb2e0362b Update main.js 2025-09-12 10:02:06 +02:00
atc1441
54dd05e698 Update main.js 2025-09-12 09:58:05 +02:00
atc1441
328f00a559 Update index.html 2025-09-12 09:54:20 +02:00
atc1441
14fda5c32a Update main.css 2025-09-12 09:19:15 +02:00
atc1441
624bf49ee3 Added DarkMode to AP Gui 2025-09-12 00:00:44 +02:00
4rianton
ab48cbe747 Ability to update time without requiring Internet Access 2025-09-06 14:59:49 +02:00
Skip Hansen
2a5094993c Don't delay content generate when shorten latency is enabled and user is connected. 2025-07-20 11:39:20 -04:00
Skip Hansen
49d981f006 Updated Chroma29 entry in tagotaversions.json. 2025-07-19 10:35:44 -04:00
Skip Hansen
fb2abf933d Chroma29 v0015: fix high battery current on some tags (#459). 2025-07-18 14:51:54 -07:00
atc1441
b78e4a6099 Create 6F.json 2025-07-04 13:47:46 +02:00
Frank Kunz
e0df4490b3 fix build of serialap module (#475)
wifimanager need to be used to read local IP address.

Signed-off-by: Frank Kunz <mailinglists@kunz-im-inter.net>
Co-authored-by: Frank Kunz <mailinglists@kunz-im-inter.net>
2025-06-14 17:45:45 +02:00
atc1441
7226793e41 Merge pull request #474 from VstudioLAB/2f
Update 2F.json
2025-06-14 10:06:51 +02:00
Vstudio LAB
934d33f950 Update 2F.json 2025-06-14 10:05:29 +02:00
Vstudio LAB
a143b49492 Button 3 (#473) 2025-06-14 09:38:03 +02:00
Skip Hansen
f048cfb296 Added Chroma 74 BWR binaries version 0014. 2025-06-05 07:58:32 -07:00
atc1441
89fec64e91 Merge branch 'master' of https://github.com/OpenEPaperLink/OpenEPaperLink 2025-05-29 21:56:12 +02:00
atc1441
bdb1e8af82 TagType Update 2025-05-29 21:56:09 +02:00
atc1441
f40238a49d Update 45.json 2025-05-29 09:36:40 +02:00
Jelmer
957b94469f Create 2A.json 2025-05-28 00:52:01 +02:00
Jelmer
c2255a3de7 Create 28.json 2025-05-28 00:50:15 +02:00
Jelmer
caf5e49595 Create 29.json
Added 2.4" BWRY definition
2025-05-28 00:48:35 +02:00
Jonas Niesner
7782a37c97 Update conditional-build-test.yml 2025-05-27 12:01:47 +02:00
atc1441
f86f2ce587 Update 6E.json 2025-05-27 11:55:26 +02:00
atc1441
7d1b81690b Added more advanced Json template demo 2025-05-26 16:23:44 +02:00
atc1441
ac6a46262a Update main.c 2025-05-22 10:40:49 +02:00
atc1441
bde464e8c1 Edited 800x480 Template 2025-05-19 15:23:29 +02:00
atc1441
b2e73c9360 Added more TagTypes 2025-05-18 16:35:38 +02:00
atc1441
863e18a4d7 Create SOL_M2_26_SSD_0028.bin 2025-05-12 19:46:18 +02:00
Marcin Juszkiewicz
d90f4e181a css: fallback to 'monospace' for AP log view (#461)
Log view on firmware update page was not printed using fixed width font on my system.

Now it is.

Closes: #460
2025-04-27 14:52:15 +02:00
atc1441
33c7053121 Update oepl-definitions.h 2025-04-18 11:38:11 +02:00
atc1441
5f06f5b0a9 Update 49.json 2025-04-15 18:36:14 +02:00
Skip Hansen
18baa45433 Enable zlib_compression support. 2025-04-15 08:13:24 -07:00
atc1441
43c9a69f88 Added 5.81" BWR V2 because of UC Variant needs rotated image 2025-04-14 17:08:03 +02:00
Nic Limper
b313d07669 added sunrise/sunset/moon phase to date display 2025-04-12 19:51:57 +02:00
atc1441
eb00a1d9c4 Update 61.json 2025-04-07 13:54:11 +02:00
atc1441
f1c9ac0a75 Update 62.json 2025-04-07 11:24:22 +02:00
atc1441
0b2a8b38ac Update 69.json 2025-04-06 02:47:56 +02:00
atc1441
561dd82236 Added a Clock mode as content type 2025-04-06 02:26:59 +02:00
atc1441
66e0b5d9f6 Merge pull request #453 from jonasniesner/master
Add OpenEPaperLink_Nano_TLSR_C6 and ESP32_S3_16_8_4inch_AP to automat…
2025-04-05 17:47:58 +02:00
Jonas Niesner
08329b89c5 Add OpenEPaperLink_Nano_TLSR_C6 and ESP32_S3_16_8_4inch_AP to automatic builds 2025-04-05 17:00:24 +02:00
Nic Limper
e8eb87e7c1 fixes crash when dayahead data is unavailable 2025-04-05 14:00:05 +02:00
atc1441
c621050f18 Create 6A.json 2025-04-04 14:03:58 +02:00
Nic Limper
2fc5c54b8e new tagtype M3 2.7" and M3 11.6" layouts and other tweaks 2025-04-03 22:31:07 +02:00
Jelmer
e2fb26c0ad Update 47.json 2025-03-31 03:01:54 +02:00
Jelmer
d53cc834c4 Delete resources/tagtypes/49.json
47 already exists
2025-03-31 02:42:16 +02:00
Jelmer
5755e4aad9 Added 2.7" tagtype 2025-03-31 02:18:41 +02:00
Nic Limper
87ce6d949d OTA update tweaks 2025-03-28 10:47:48 +01:00
87 changed files with 4606 additions and 2448 deletions

View File

@@ -5,7 +5,7 @@ on: [push, pull_request]
jobs: jobs:
determine-builds: determine-builds:
name: Evaluate Required Builds name: Evaluate Required Builds
runs-on: ubuntu-20.04 runs-on: ubuntu-latest
timeout-minutes: 1 timeout-minutes: 1
# Map a step output to job output # Map a step output to job output
outputs: outputs:
@@ -26,7 +26,7 @@ jobs:
tag-build: tag-build:
name: Build Tag FW name: Build Tag FW
needs: [determine-builds] needs: [determine-builds]
runs-on: ubuntu-22.04 runs-on: ubuntu-latest
steps: steps:
- name: Checkout Code (with submodules) - name: Checkout Code (with submodules)
uses: actions/checkout@v4 uses: actions/checkout@v4
@@ -71,7 +71,7 @@ jobs:
- ESP32_S3_16_8_YELLOW_AP - ESP32_S3_16_8_YELLOW_AP
- OpenEPaperLink_Mini_AP_v4 - OpenEPaperLink_Mini_AP_v4
- OpenEPaperLink_ESP32-PoE-ISO_AP - OpenEPaperLink_ESP32-PoE-ISO_AP
runs-on: ubuntu-22.04 runs-on: ubuntu-latest
steps: steps:
- name: Checkout Code - name: Checkout Code
uses: actions/checkout@v4 uses: actions/checkout@v4

View File

@@ -268,6 +268,42 @@ jobs:
cp BLE_ONLY_AP/firmware.bin espbinaries/BLE_ONLY_AP.bin cp BLE_ONLY_AP/firmware.bin espbinaries/BLE_ONLY_AP.bin
cp BLE_ONLY_AP/merged-firmware.bin espbinaries/BLE_ONLY_AP_full.bin cp BLE_ONLY_AP/merged-firmware.bin espbinaries/BLE_ONLY_AP_full.bin
- name: Build firmware for OpenEPaperLink_Nano_TLSR_C6
run: |
cd ESP32_AP-Flasher
export PLATFORMIO_BUILD_FLAGS="-D BUILD_VERSION=${{ github.ref_name }} -D SHA=$GITHUB_SHA"
pio run --environment OpenEPaperLink_Nano_TLSR_C6
pio run --target buildfs --environment OpenEPaperLink_Nano_TLSR_C6
mkdir /home/runner/work/OpenEPaperLink/OpenEPaperLink/OpenEPaperLink_Nano_TLSR_C6
cp ~/.platformio/packages/framework-arduinoespressif32/tools/partitions/boot_app0.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/OpenEPaperLink_Nano_TLSR_C6/boot_app0.bin
cp .pio/build/OpenEPaperLink_Nano_TLSR_C6/firmware.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/OpenEPaperLink_Nano_TLSR_C6/firmware.bin
cp .pio/build/OpenEPaperLink_Nano_TLSR_C6/bootloader.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/OpenEPaperLink_Nano_TLSR_C6/bootloader.bin
cp .pio/build/OpenEPaperLink_Nano_TLSR_C6/partitions.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/OpenEPaperLink_Nano_TLSR_C6/partitions.bin
cp .pio/build/OpenEPaperLink_Nano_TLSR_C6/littlefs.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/OpenEPaperLink_Nano_TLSR_C6/littlefs.bin
cd /home/runner/work/OpenEPaperLink/OpenEPaperLink/OpenEPaperLink_Nano_TLSR_C6
esptool.py --chip esp32-s3 merge_bin -o merged-firmware.bin --flash_mode dio --flash_freq 80m --flash_size 16MB 0x0000 bootloader.bin 0x8000 partitions.bin 0xe000 boot_app0.bin 0x10000 firmware.bin 0x00910000 littlefs.bin
cd /home/runner/work/OpenEPaperLink/OpenEPaperLink
cp OpenEPaperLink_Nano_TLSR_C6/firmware.bin espbinaries/OpenEPaperLink_Nano_TLSR_C6.bin
cp OpenEPaperLink_Nano_TLSR_C6/merged-firmware.bin espbinaries/OpenEPaperLink_Nano_TLSR_C6_full.bin
- name: Build firmware for ESP32_S3_16_8_4inch_AP
run: |
cd ESP32_AP-Flasher
export PLATFORMIO_BUILD_FLAGS="-D BUILD_VERSION=${{ github.ref_name }} -D SHA=$GITHUB_SHA"
pio run --environment ESP32_S3_16_8_4inch_AP
pio run --target buildfs --environment ESP32_S3_16_8_4inch_AP
mkdir /home/runner/work/OpenEPaperLink/OpenEPaperLink/ESP32_S3_16_8_4inch_AP
cp ~/.platformio/packages/framework-arduinoespressif32/tools/partitions/boot_app0.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/ESP32_S3_16_8_4inch_AP/boot_app0.bin
cp .pio/build/ESP32_S3_16_8_4inch_AP/firmware.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/ESP32_S3_16_8_4inch_AP/firmware.bin
cp .pio/build/ESP32_S3_16_8_4inch_AP/bootloader.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/ESP32_S3_16_8_4inch_AP/bootloader.bin
cp .pio/build/ESP32_S3_16_8_4inch_AP/partitions.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/ESP32_S3_16_8_4inch_AP/partitions.bin
cp .pio/build/ESP32_S3_16_8_4inch_AP/littlefs.bin /home/runner/work/OpenEPaperLink/OpenEPaperLink/ESP32_S3_16_8_4inch_AP/littlefs.bin
cd /home/runner/work/OpenEPaperLink/OpenEPaperLink/ESP32_S3_16_8_4inch_AP
esptool.py --chip esp32-s3 merge_bin -o merged-firmware.bin --flash_mode dio --flash_freq 80m --flash_size 16MB 0x0000 bootloader.bin 0x8000 partitions.bin 0xe000 boot_app0.bin 0x10000 firmware.bin 0x00910000 littlefs.bin
cd /home/runner/work/OpenEPaperLink/OpenEPaperLink
cp ESP32_S3_16_8_4inch_AP/firmware.bin espbinaries/ESP32_S3_16_8_4inch_AP.bin
cp ESP32_S3_16_8_4inch_AP/merged-firmware.bin espbinaries/ESP32_S3_16_8_4inch_AP_full.bin
- name: Build firmware for OpenEPaperLink_ESP32-PoE-ISO_AP - name: Build firmware for OpenEPaperLink_ESP32-PoE-ISO_AP
run: | run: |
cd ESP32_AP-Flasher cd ESP32_AP-Flasher

View File

@@ -149,7 +149,7 @@ uint8_t getBlockDataLength() {
} }
// pendingdata slot stuff // pendingdata slot stuff
int8_t findSlotForMac(const uint8_t *mac) { int32_t findSlotForMac(const uint8_t *mac) {
for (uint8_t c = 0; c < MAX_PENDING_MACS; c++) { for (uint8_t c = 0; c < MAX_PENDING_MACS; c++) {
if (memcmp(mac, ((uint8_t *) &(pendingDataArr[c].targetMac)), 8) == 0) { if (memcmp(mac, ((uint8_t *) &(pendingDataArr[c].targetMac)), 8) == 0) {
if (pendingDataArr[c].attemptsLeft != 0) { if (pendingDataArr[c].attemptsLeft != 0) {
@@ -159,7 +159,7 @@ int8_t findSlotForMac(const uint8_t *mac) {
} }
return -1; return -1;
} }
int8_t findFreeSlot() { int32_t findFreeSlot() {
for (uint8_t c = 0; c < MAX_PENDING_MACS; c++) { for (uint8_t c = 0; c < MAX_PENDING_MACS; c++) {
if (pendingDataArr[c].attemptsLeft == 0) { if (pendingDataArr[c].attemptsLeft == 0) {
return c; return c;
@@ -167,7 +167,7 @@ int8_t findFreeSlot() {
} }
return -1; return -1;
} }
int8_t findSlotForVer(const uint8_t *ver) { int32_t findSlotForVer(const uint8_t *ver) {
for (uint8_t c = 0; c < MAX_PENDING_MACS; c++) { for (uint8_t c = 0; c < MAX_PENDING_MACS; c++) {
if (memcmp(ver, ((uint8_t *) &(pendingDataArr[c].availdatainfo.dataVer)), 8) == 0) { if (memcmp(ver, ((uint8_t *) &(pendingDataArr[c].availdatainfo.dataVer)), 8) == 0) {
if (pendingDataArr[c].attemptsLeft != 0) return c; if (pendingDataArr[c].attemptsLeft != 0) return c;
@@ -176,14 +176,14 @@ int8_t findSlotForVer(const uint8_t *ver) {
return -1; return -1;
} }
void deleteAllPendingDataForVer(const uint8_t *ver) { void deleteAllPendingDataForVer(const uint8_t *ver) {
int8_t slot = -1; int32_t slot = -1;
do { do {
slot = findSlotForVer(ver); slot = findSlotForVer(ver);
if (slot != -1) pendingDataArr[slot].attemptsLeft = 0; if (slot != -1) pendingDataArr[slot].attemptsLeft = 0;
} while (slot != -1); } while (slot != -1);
} }
void deleteAllPendingDataForMac(const uint8_t *mac) { void deleteAllPendingDataForMac(const uint8_t *mac) {
int8_t slot = -1; int32_t slot = -1;
do { do {
slot = findSlotForMac(mac); slot = findSlotForMac(mac);
if (slot != -1) pendingDataArr[slot].attemptsLeft = 0; if (slot != -1) pendingDataArr[slot].attemptsLeft = 0;
@@ -314,7 +314,7 @@ void processSerial(uint8_t lastchar) {
if (bytesRemain == 0) { if (bytesRemain == 0) {
if (checkCRC(serialbuffer, sizeof(struct pendingData))) { if (checkCRC(serialbuffer, sizeof(struct pendingData))) {
struct pendingData *pd = (struct pendingData *) serialbuffer; struct pendingData *pd = (struct pendingData *) serialbuffer;
int8_t slot = findSlotForMac(pd->targetMac); int32_t slot = findSlotForMac(pd->targetMac);
if (slot == -1) slot = findFreeSlot(); if (slot == -1) slot = findFreeSlot();
if (slot != -1) { if (slot != -1) {
memcpy(&(pendingDataArr[slot]), serialbuffer, sizeof(struct pendingData)); memcpy(&(pendingDataArr[slot]), serialbuffer, sizeof(struct pendingData));
@@ -624,7 +624,7 @@ void processXferComplete(uint8_t *buffer) {
if (memcmp(lastAckMac, rxHeader->src, 8) != 0) { if (memcmp(lastAckMac, rxHeader->src, 8) != 0) {
memcpy((void *) lastAckMac, (void *) rxHeader->src, 8); memcpy((void *) lastAckMac, (void *) rxHeader->src, 8);
espNotifyXferComplete(rxHeader->src); espNotifyXferComplete(rxHeader->src);
int8_t slot = findSlotForMac(rxHeader->src); int32_t slot = findSlotForMac(rxHeader->src);
if (slot != -1) pendingDataArr[slot].attemptsLeft = 0; if (slot != -1) pendingDataArr[slot].attemptsLeft = 0;
} }
} }
@@ -788,7 +788,7 @@ void app_main(void) {
housekeepingTimer = getMillis(); housekeepingTimer = getMillis();
while (1) { while (1) {
while ((getMillis() - housekeepingTimer) < ((1000 * HOUSEKEEPING_INTERVAL) - 100)) { while ((getMillis() - housekeepingTimer) < ((1000 * HOUSEKEEPING_INTERVAL) - 100)) {
int8_t ret = commsRxUnencrypted(radiorxbuffer); int32_t ret = commsRxUnencrypted(radiorxbuffer);
if (ret > 1) { if (ret > 1) {
led_flash(0); led_flash(0);

View File

@@ -10,6 +10,7 @@
"/www/painter.js", "/www/painter.js",
"/www/setup.html", "/www/setup.html",
"/www/setup.js", "/www/setup.js",
"/www/flash.js",
"/www/upload-demo.html" "/www/upload-demo.html"
] ]
} }

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -1,6 +1,7 @@
#include <Arduino.h> #include <Arduino.h>
#include <LittleFS.h> #include <LittleFS.h>
#include <TFT_eSPI.h> #include <TFT_eSPI.h>
#include <time.h>
#include "makeimage.h" #include "makeimage.h"
#include "tag_db.h" #include "tag_db.h"
@@ -21,7 +22,7 @@ bool updateTagImage(String &filename, const uint8_t *dst, uint16_t nextCheckin,
void drawString(TFT_eSprite &spr, String content, int16_t posx, int16_t posy, String font, byte align = 0, uint16_t color = TFT_BLACK, uint16_t size = 30, uint16_t bgcolor = TFT_WHITE); void drawString(TFT_eSprite &spr, String content, int16_t posx, int16_t posy, String font, byte align = 0, uint16_t color = TFT_BLACK, uint16_t size = 30, uint16_t bgcolor = TFT_WHITE);
void drawTextBox(TFT_eSprite &spr, String &content, int16_t &posx, int16_t &posy, int16_t boxwidth, int16_t boxheight, String font, uint16_t color = TFT_BLACK, uint16_t bgcolor = TFT_WHITE, float lineheight = 1, byte align = TL_DATUM); void drawTextBox(TFT_eSprite &spr, String &content, int16_t &posx, int16_t &posy, int16_t boxwidth, int16_t boxheight, String font, uint16_t color = TFT_BLACK, uint16_t bgcolor = TFT_WHITE, float lineheight = 1, byte align = TL_DATUM);
void initSprite(TFT_eSprite &spr, int w, int h, imgParam &imageParams); void initSprite(TFT_eSprite &spr, int w, int h, imgParam &imageParams);
void drawDate(String &filename, tagRecord *&taginfo, imgParam &imageParams); void drawDate(String &filename, JsonObject &cfgobj, tagRecord *&taginfo, imgParam &imageParams);
void drawNumber(String &filename, int32_t count, int32_t thresholdred, tagRecord *&taginfo, imgParam &imageParams); void drawNumber(String &filename, int32_t count, int32_t thresholdred, tagRecord *&taginfo, imgParam &imageParams);
void drawWeather(String &filename, JsonObject &cfgobj, const tagRecord *taginfo, imgParam &imageParams); void drawWeather(String &filename, JsonObject &cfgobj, const tagRecord *taginfo, imgParam &imageParams);
void drawForecast(String &filename, JsonObject &cfgobj, const tagRecord *taginfo, imgParam &imageParams); void drawForecast(String &filename, JsonObject &cfgobj, const tagRecord *taginfo, imgParam &imageParams);
@@ -48,4 +49,5 @@ void getLocation(JsonObject &cfgobj);
void prepareNFCReq(const uint8_t *dst, const char *url); void prepareNFCReq(const uint8_t *dst, const char *url);
void prepareLUTreq(const uint8_t *dst, const String &input); void prepareLUTreq(const uint8_t *dst, const String &input);
void prepareConfigFile(const uint8_t *dst, const JsonObject &config); void prepareConfigFile(const uint8_t *dst, const JsonObject &config);
void prepareTIME_RAW(const uint8_t *dst, time_t now);
void getTemplate(JsonDocument &json, const uint8_t id, const uint8_t hwtype); void getTemplate(JsonDocument &json, const uint8_t id, const uint8_t hwtype);

View File

@@ -104,22 +104,22 @@ extern Arduino_RGB_Display *gfx;
#define LCD_VSYNC 17 #define LCD_VSYNC 17
#define LCD_HSYNC 16 #define LCD_HSYNC 16
#define LCD_PCLK 21 #define LCD_PCLK 21
#define LCD_R0 11 #define LCD_R0 0
#define LCD_R1 12 #define LCD_R1 11
#define LCD_R2 13 #define LCD_R2 12
#define LCD_R3 14 #define LCD_R3 13
#define LCD_R4 0 #define LCD_R4 14
#define LCD_G0 8 #define LCD_G0 8
#define LCD_G1 20 #define LCD_G1 20
#define LCD_G2 3 #define LCD_G2 3
#define LCD_G3 46 #define LCD_G3 46
#define LCD_G4 9 #define LCD_G4 9
#define LCD_G5 10 #define LCD_G5 10
#define LCD_B0 4 #define LCD_B0 15
#define LCD_B1 5 #define LCD_B1 4
#define LCD_B2 6 #define LCD_B2 5
#define LCD_B3 7 #define LCD_B3 6
#define LCD_B4 15 #define LCD_B4 7
#define LCD_BL 38 #define LCD_BL 38
#define LCD_DE 18 #define LCD_DE 18

View File

@@ -39,6 +39,7 @@ struct imgParam {
uint8_t zlib; uint8_t zlib;
uint8_t g5; uint8_t g5;
uint8_t ts_option;
}; };
void spr2buffer(TFT_eSprite &spr, String &fileout, imgParam &imageParams); void spr2buffer(TFT_eSprite &spr, String &fileout, imgParam &imageParams);

View File

@@ -6,6 +6,7 @@
#define WAKEUP_REASON_NFC 3 #define WAKEUP_REASON_NFC 3
#define WAKEUP_REASON_BUTTON1 4 #define WAKEUP_REASON_BUTTON1 4
#define WAKEUP_REASON_BUTTON2 5 #define WAKEUP_REASON_BUTTON2 5
#define WAKEUP_REASON_BUTTON3 6
#define WAKEUP_REASON_FAILED_OTA_FW 0xE0 #define WAKEUP_REASON_FAILED_OTA_FW 0xE0
#define WAKEUP_REASON_FIRSTBOOT 0xFC #define WAKEUP_REASON_FIRSTBOOT 0xFC
#define WAKEUP_REASON_NETWORK_SCAN 0xFD #define WAKEUP_REASON_NETWORK_SCAN 0xFD

View File

@@ -64,7 +64,7 @@ uint8_t gicToOEPLtype(uint8_t gicType) {
} }
} }
struct BleAdvDataStruct { struct BleAdvDataStructV1 {
uint16_t manu_id; // 0x1337 for us uint16_t manu_id; // 0x1337 for us
uint8_t version; uint8_t version;
uint16_t hw_type; uint16_t hw_type;
@@ -73,6 +73,16 @@ struct BleAdvDataStruct {
uint16_t battery_mv; uint16_t battery_mv;
uint8_t counter; uint8_t counter;
} __packed; } __packed;
struct BleAdvDataStructV2 {
uint16_t manu_id; // 0x1337 for us
uint8_t version;
uint16_t hw_type;
uint16_t fw_version;
uint16_t capabilities;
uint16_t battery_mv;
int8_t temperature;
uint8_t counter;
} __packed;
bool BLE_filter_add_device(BLEAdvertisedDevice advertisedDevice) { bool BLE_filter_add_device(BLEAdvertisedDevice advertisedDevice) {
Serial.print("BLE Advertised Device found: "); Serial.print("BLE Advertised Device found: ");
@@ -91,16 +101,16 @@ bool BLE_filter_add_device(BLEAdvertisedDevice advertisedDevice) {
uint8_t manuData[100]; uint8_t manuData[100];
if (manuDatalen > sizeof(manuData)) if (manuDatalen > sizeof(manuData))
return false; // Manu data too big, could never happen but better make sure here return false; // Manu data too big, could never happen but better make sure here
#if ESP_ARDUINO_VERSION_MAJOR == 2
memcpy(&manuData, (uint8_t*)advertisedDevice.getManufacturerData().data(), manuDatalen);
#else
// [Nic] suggested fix for arduino 3.x by copilot, but I cannot test it
memcpy(&manuData, (uint8_t*)advertisedDevice.getManufacturerData().c_str(), manuDatalen);
#endif
Serial.printf(" Address type: %02X Manu data: ", advertisedDevice.getAddressType()); Serial.printf(" Address type: %02X Manu data: ", advertisedDevice.getAddressType());
for (int i = 0; i < advertisedDevice.getManufacturerData().length(); i++) for (int i = 0; i < advertisedDevice.getManufacturerData().length(); i++)
Serial.printf("%02X", manuData[i]); Serial.printf("%02X", manuData[i]);
Serial.printf("\r\n"); Serial.printf("\r\n");
#if ESP_ARDUINO_VERSION_MAJOR == 2
memcpy(&manuData, (uint8_t*)advertisedDevice.getManufacturerData().data(), manuDatalen);
#else
// [Nic] suggested fix for arduino 3.x by copilot, but I cannot test it
memcpy(&manuData, (uint8_t*)advertisedDevice.getManufacturerData().c_str(), manuDatalen);
#endif
if (manuDatalen == 7 && manuData[0] == 0x53 && manuData[1] == 0x50) { // Lets check for a Gicisky E-Paper display if (manuDatalen == 7 && manuData[0] == 0x53 && manuData[1] == 0x50) { // Lets check for a Gicisky E-Paper display
struct espAvailDataReq theAdvData; struct espAvailDataReq theAdvData;
@@ -125,23 +135,63 @@ bool BLE_filter_add_device(BLEAdvertisedDevice advertisedDevice) {
processDataReq(&theAdvData, true); processDataReq(&theAdvData, true);
return true; return true;
} else if (manuDatalen >= sizeof(BleAdvDataStruct) && manuData[0] == 0x37 && manuData[1] == 0x13) { // Lets check for a Gicisky E-Paper display } else if (manuDatalen >= 3 && manuData[0] == 0x37 && manuData[1] == 0x13) { // Lets check for a Gicisky E-Paper display
Serial.printf("ATC BLE OEPL Detected\r\n"); Serial.printf("ATC BLE OEPL Detected\r\n");
struct espAvailDataReq theAdvData; struct espAvailDataReq theAdvData;
struct BleAdvDataStruct inAdvData;
memset((uint8_t*)&theAdvData, 0x00, sizeof(espAvailDataReq)); memset((uint8_t*)&theAdvData, 0x00, sizeof(espAvailDataReq));
memcpy(&inAdvData, manuData, sizeof(BleAdvDataStruct)); uint8_t versionAdvData = manuData[2];
/*Serial.printf("manu_id %04X\r\n", inAdvData.manu_id);
Serial.printf("version %04X\r\n", inAdvData.version); switch (versionAdvData) {
Serial.printf("hw_type %04X\r\n", inAdvData.hw_type); case 1: {
Serial.printf("fw_version %04X\r\n", inAdvData.fw_version); if (manuDatalen >= sizeof(BleAdvDataStructV1)) {
Serial.printf("capabilities %04X\r\n", inAdvData.capabilities); struct BleAdvDataStructV1 inAdvData;
Serial.printf("battery_mv %u\r\n", inAdvData.battery_mv); memcpy(&inAdvData, manuData, sizeof(BleAdvDataStructV1));
Serial.printf("counter %u\r\n", inAdvData.counter);*/ printf("Version 1 ATC_BLE_OEPL Received\r\n");
if (inAdvData.version != 1) { /*Serial.printf("manu_id %04X\r\n", inAdvData.manu_id);
printf("Version currently not supported!\r\n"); Serial.printf("version %02X\r\n", inAdvData.version);
return false; Serial.printf("hw_type %04X\r\n", inAdvData.hw_type);
Serial.printf("fw_version %04X\r\n", inAdvData.fw_version);
Serial.printf("capabilities %04X\r\n", inAdvData.capabilities);
Serial.printf("battery_mv %u\r\n", inAdvData.battery_mv);
Serial.printf("counter %u\r\n", inAdvData.counter);*/
theAdvData.adr.batteryMv = inAdvData.battery_mv;
theAdvData.adr.lastPacketRSSI = advertisedDevice.getRSSI();
theAdvData.adr.hwType = inAdvData.hw_type & 0xff;
theAdvData.adr.tagSoftwareVersion = inAdvData.fw_version;
theAdvData.adr.capabilities = inAdvData.capabilities & 0xff;
} else {
printf("Version 1 data length incorrect!\r\n");
return false;
}
} break;
case 2: {
if (manuDatalen >= sizeof(BleAdvDataStructV2)) {
struct BleAdvDataStructV2 inAdvData;
memcpy(&inAdvData, manuData, sizeof(BleAdvDataStructV2));
printf("Version 2 ATC_BLE_OEPL Received\r\n");
/*Serial.printf("manu_id %04X\r\n", inAdvData.manu_id);
Serial.printf("version %02X\r\n", inAdvData.version);
Serial.printf("hw_type %04X\r\n", inAdvData.hw_type);
Serial.printf("fw_version %04X\r\n", inAdvData.fw_version);
Serial.printf("capabilities %04X\r\n", inAdvData.capabilities);
Serial.printf("battery_mv %u\r\n", inAdvData.battery_mv);
Serial.printf("temperature %i\r\n", inAdvData.temperature);
Serial.printf("counter %u\r\n", inAdvData.counter);*/
theAdvData.adr.batteryMv = inAdvData.battery_mv;
theAdvData.adr.temperature = inAdvData.temperature;
theAdvData.adr.lastPacketRSSI = advertisedDevice.getRSSI();
theAdvData.adr.hwType = inAdvData.hw_type & 0xff;
theAdvData.adr.tagSoftwareVersion = inAdvData.fw_version;
theAdvData.adr.capabilities = inAdvData.capabilities & 0xff;
} else {
printf("Version 2 data length incorrect!\r\n");
return false;
}
} break;
default:
printf("Version %02X currently not supported!\r\n", versionAdvData);
return false;
break;
} }
uint8_t macReversed[6]; uint8_t macReversed[6];
memcpy(&macReversed, (uint8_t*)advertisedDevice.getAddress().getNative(), 6); memcpy(&macReversed, (uint8_t*)advertisedDevice.getAddress().getNative(), 6);
@@ -153,11 +203,6 @@ bool BLE_filter_add_device(BLEAdvertisedDevice advertisedDevice) {
theAdvData.src[5] = macReversed[0]; theAdvData.src[5] = macReversed[0];
theAdvData.src[6] = manuData[0]; // We use this do find out what type of display we got for compression^^ theAdvData.src[6] = manuData[0]; // We use this do find out what type of display we got for compression^^
theAdvData.src[7] = manuData[1]; theAdvData.src[7] = manuData[1];
theAdvData.adr.batteryMv = inAdvData.battery_mv;
theAdvData.adr.lastPacketRSSI = advertisedDevice.getRSSI();
theAdvData.adr.hwType = inAdvData.hw_type & 0xff;
theAdvData.adr.tagSoftwareVersion = inAdvData.fw_version;
theAdvData.adr.capabilities = inAdvData.capabilities & 0xff;
processDataReq(&theAdvData, true); processDataReq(&theAdvData, true);
return true; return true;
} }

View File

@@ -10,6 +10,7 @@
#define CONTENT_TIMESTAMP #define CONTENT_TIMESTAMP
#define CONTENT_BUIENRADAR #define CONTENT_BUIENRADAR
#define CONTENT_CAL #define CONTENT_CAL
#define CONTENT_TIME_RAWDATA
#endif #endif
#define CONTENT_TAGCFG #define CONTENT_TAGCFG
@@ -45,7 +46,7 @@
bool needRedraw(uint8_t contentMode, uint8_t wakeupReason) { bool needRedraw(uint8_t contentMode, uint8_t wakeupReason) {
// contentmode 26, timestamp // contentmode 26, timestamp
if ((wakeupReason == WAKEUP_REASON_BUTTON1 || wakeupReason == WAKEUP_REASON_BUTTON2) && contentMode == 26) return true; if ((wakeupReason == WAKEUP_REASON_BUTTON1 || wakeupReason == WAKEUP_REASON_BUTTON2 || wakeupReason == WAKEUP_REASON_BUTTON3) && contentMode == 26) return true;
return false; return false;
} }
@@ -63,10 +64,11 @@ void contentRunner() {
const bool isAp = memcmp(taginfo->mac, wifimac, 8) == 0; const bool isAp = memcmp(taginfo->mac, wifimac, 8) == 0;
if (taginfo->RSSI && if (taginfo->RSSI &&
(now >= taginfo->nextupdate || needRedraw(taginfo->contentMode, taginfo->wakeupReason)) && (now >= taginfo->nextupdate || needRedraw(taginfo->contentMode, taginfo->wakeupReason)) &&
config.runStatus == RUNSTATUS_RUN && (taginfo->expectedNextCheckin < now + 300 || isAp) && config.runStatus == RUNSTATUS_RUN &&
Storage.freeSpace() > 31000 && !util::isSleeping(config.sleepTime1, config.sleepTime2)) { (taginfo->expectedNextCheckin < now + 300 || isAp || (wsClientCount() && config.stopsleep == 1)) &&
drawNew(taginfo->mac, taginfo); Storage.freeSpace() > 31000 && !util::isSleeping(config.sleepTime1, config.sleepTime2)) {
taginfo->wakeupReason = 0; drawNew(taginfo->mac, taginfo);
taginfo->wakeupReason = 0;
} }
if (taginfo->expectedNextCheckin > now - 10 && taginfo->expectedNextCheckin < now + 30 && taginfo->pendingIdle == 0 && taginfo->pendingCount == 0 && !isAp) { if (taginfo->expectedNextCheckin > now - 10 && taginfo->expectedNextCheckin < now + 30 && taginfo->pendingIdle == 0 && taginfo->pendingCount == 0 && !isAp) {
@@ -257,6 +259,27 @@ void drawNew(const uint8_t mac[8], tagRecord *&taginfo) {
} else if (interval < 180) } else if (interval < 180)
interval = 60 * 60; interval = 60 * 60;
imageParams.ts_option = config.showtimestamp;
if(imageParams.ts_option) {
JsonDocument loc;
getTemplate(loc, taginfo->contentMode, taginfo->hwType);
if(loc["ts_option"].is<int>()) {
// Overide ts_option if present in template
imageParams.ts_option = loc["ts_option"];
}
else {
const JsonArray jsonArray = loc.as<JsonArray>();
for (const JsonVariant &elem : jsonArray) {
if(elem["ts_option"].is<int>()) {
// Overide ts_option if present in template
imageParams.ts_option = elem["ts_option"];
break;
}
}
}
}
switch (taginfo->contentMode) { switch (taginfo->contentMode) {
case 0: // Not configured case 0: // Not configured
case 22: // Static image case 22: // Static image
@@ -335,7 +358,7 @@ void drawNew(const uint8_t mac[8], tagRecord *&taginfo) {
case 1: // Today case 1: // Today
drawDate(filename, taginfo, imageParams); drawDate(filename, cfgobj, taginfo, imageParams);
taginfo->nextupdate = util::getMidnightTime(); taginfo->nextupdate = util::getMidnightTime();
updateTagImage(filename, mac, (taginfo->nextupdate - now) / 60 - 10, taginfo, imageParams); updateTagImage(filename, mac, (taginfo->nextupdate - now) / 60 - 10, taginfo, imageParams);
break; break;
@@ -558,10 +581,26 @@ void drawNew(const uint8_t mac[8], tagRecord *&taginfo) {
case 27: // Day Ahead: case 27: // Day Ahead:
if (getDayAheadFeed(filename, cfgobj, taginfo, imageParams)) { if (getDayAheadFeed(filename, cfgobj, taginfo, imageParams)) {
taginfo->nextupdate = now + (3600 - now % 3600); // Get user-configured update frequency in minutes, default to 15 minutes (matching 15-min data intervals)
int updateFreqMinutes = 15;
if (cfgobj["updatefreq"].is<String>()) {
String freqStr = cfgobj["updatefreq"].as<String>();
freqStr.trim();
if (freqStr.length() > 0) {
updateFreqMinutes = freqStr.toInt();
if (updateFreqMinutes < 1) {
wsErr("Invalid update frequency, defaulting to 15 minutes");
updateFreqMinutes = 15;
}
}
}
int updateInterval = updateFreqMinutes * 60; // Convert to seconds
// Schedule next update (align to interval boundary for consistent timing)
taginfo->nextupdate = now + (updateInterval - now % updateInterval);
updateTagImage(filename, mac, 0, taginfo, imageParams); updateTagImage(filename, mac, 0, taginfo, imageParams);
} else { } else {
taginfo->nextupdate = now + 300; taginfo->nextupdate = now + 300; // Retry in 5 minutes on failure
} }
break; break;
#endif #endif
@@ -573,6 +612,13 @@ void drawNew(const uint8_t mac[8], tagRecord *&taginfo) {
taginfo->nextupdate = 3216153600; taginfo->nextupdate = 3216153600;
break; break;
} }
#ifdef CONTENT_TIME_RAWDATA
case 29: // Time and raw data like strings etc. in the future
taginfo->nextupdate = now + 1800;
prepareTIME_RAW(mac, now);
break;
#endif
} }
taginfo->modeConfigJson = doc.as<String>(); taginfo->modeConfigJson = doc.as<String>();
@@ -782,7 +828,41 @@ void initSprite(TFT_eSprite &spr, int w, int h, imgParam &imageParams) {
spr.fillSprite(TFT_WHITE); spr.fillSprite(TFT_WHITE);
} }
void drawDate(String &filename, tagRecord *&taginfo, imgParam &imageParams) { String utf8FromCodepoint(uint16_t cp) {
char buf[4] = {0};
if (cp < 0x80) {
buf[0] = cp;
} else if (cp < 0x800) {
buf[0] = 0xC0 | (cp >> 6);
buf[1] = 0x80 | (cp & 0x3F);
} else {
buf[0] = 0xE0 | ((cp >> 12) & 0x0F);
buf[1] = 0x80 | ((cp >> 6) & 0x3F);
buf[2] = 0x80 | (cp & 0x3F);
}
return String(buf);
}
String formatUtcToLocal(const String &s) {
int h, m, ss = 0;
if (sscanf(s.c_str(), "%d:%d:%d", &h, &m, &ss) < 2 || h > 23 || m > 59 || ss > 59)
return "-";
time_t n = time(nullptr);
struct tm tm = *localtime(&n);
tm.tm_hour = h;
tm.tm_min = m;
tm.tm_sec = ss;
time_t utc = mktime(&tm) - _timezone + (tm.tm_isdst ? 3600 : 0);
localtime_r(&utc, &tm);
char buf[6];
snprintf(buf, 6, "%02d:%02d", tm.tm_hour, tm.tm_min);
return buf;
}
void drawDate(String &filename, JsonObject &cfgobj, tagRecord *&taginfo, imgParam &imageParams) {
time_t now; time_t now;
time(&now); time(&now);
struct tm timeinfo; struct tm timeinfo;
@@ -803,19 +883,48 @@ void drawDate(String &filename, tagRecord *&taginfo, imgParam &imageParams) {
TFT_eSprite spr = TFT_eSprite(&tft); TFT_eSprite spr = TFT_eSprite(&tft);
initSprite(spr, imageParams.width, imageParams.height, imageParams); initSprite(spr, imageParams.width, imageParams.height, imageParams);
const auto &date = loc["date"]; auto date = loc["date"];
const auto &weekday = loc["weekday"]; auto weekday = loc["weekday"];
if (date) { const auto &month = loc["month"];
const auto &day = loc["day"];
if (cfgobj["location"]) {
const String lat = cfgobj["#lat"];
const String lon = cfgobj["#lon"];
JsonDocument doc;
const bool success = util::httpGetJson("https://api.farmsense.net/v1/daylengths/?d=" + String(now) + "&lat=" + lat + "&lon=" + lon + "&tz=UTC", doc, 5000);
if (success && loc["sunrise"].is<JsonArray>()) {
String sunrise = formatUtcToLocal(doc[0]["Sunrise"]);
String sunset = formatUtcToLocal(doc[0]["Sunset"]);
const auto &sunriseicon = loc["sunrise"];
const auto &sunseticon = loc["sunset"];
drawString(spr, String("\uF046 "), sunriseicon[0], sunriseicon[1].as<int>(), "/fonts/weathericons.ttf", TR_DATUM, TFT_BLACK, sunriseicon[3]);
drawString(spr, String("\uF047 "), sunseticon[0], sunseticon[1].as<int>(), "/fonts/weathericons.ttf", TR_DATUM, TFT_BLACK, sunseticon[3]);
drawString(spr, sunrise, sunriseicon[0], sunriseicon[1], sunriseicon[2], TL_DATUM, TFT_BLACK, sunriseicon[3]);
drawString(spr, sunset, sunseticon[0], sunseticon[1], sunseticon[2], TL_DATUM, TFT_BLACK, sunseticon[3]);
const bool success = util::httpGetJson("https://api.farmsense.net/v1/moonphases/?d=" + String(now), doc, 5000);
if (success && loc["moonicon"].is<JsonArray>()) {
uint8_t moonage = doc[0]["Index"].as<int>();
const auto &moonicon = loc["moonicon"];
uint16_t moonIconId = 0xf095 + moonage;
String moonIcon = utf8FromCodepoint(moonIconId);
drawString(spr, moonIcon, moonicon[0], moonicon[1], "/fonts/weathericons.ttf", TC_DATUM, TFT_BLACK, moonicon[2]);
}
date = loc["altdate"];
weekday = loc["altweekday"];
}
}
if (date.is<JsonArray>()) {
drawString(spr, languageDays[timeinfo.tm_wday], weekday[0], weekday[1], weekday[2], TC_DATUM, imageParams.highlightColor, weekday[3]); drawString(spr, languageDays[timeinfo.tm_wday], weekday[0], weekday[1], weekday[2], TC_DATUM, imageParams.highlightColor, weekday[3]);
drawString(spr, String(timeinfo.tm_mday) + " " + languageMonth[timeinfo.tm_mon], date[0], date[1], date[2], TC_DATUM, TFT_BLACK, date[3]); drawString(spr, String(timeinfo.tm_mday) + " " + languageMonth[timeinfo.tm_mon], date[0], date[1], date[2], TC_DATUM, TFT_BLACK, date[3]);
} else { } else {
const auto &month = loc["month"];
const auto &day = loc["day"];
drawString(spr, languageDays[timeinfo.tm_wday], weekday[0], weekday[1], weekday[2], TC_DATUM, TFT_BLACK, weekday[3]); drawString(spr, languageDays[timeinfo.tm_wday], weekday[0], weekday[1], weekday[2], TC_DATUM, TFT_BLACK, weekday[3]);
drawString(spr, String(languageMonth[timeinfo.tm_mon]), month[0], month[1], month[2], TC_DATUM, TFT_BLACK, month[3]); drawString(spr, String(languageMonth[timeinfo.tm_mon]), month[0], month[1], month[2], TC_DATUM, TFT_BLACK, month[3]);
drawString(spr, String(timeinfo.tm_mday), day[0], day[1], day[2], TC_DATUM, imageParams.highlightColor, day[3]); drawString(spr, String(timeinfo.tm_mday), day[0], day[1], day[2], TC_DATUM, imageParams.highlightColor, day[3]);
} }
spr2buffer(spr, filename, imageParams); spr2buffer(spr, filename, imageParams);
spr.deleteSprite(); spr.deleteSprite();
} }
@@ -1573,9 +1682,277 @@ YAxisScale calculateYAxisScale(double priceMin, double priceMax, int divisions)
return {minY, maxY, roundedStepSize}; return {minY, maxY, roundedStepSize};
} }
bool getDayAheadFeed(String &filename, JsonObject &cfgobj, tagRecord *&taginfo, imgParam &imageParams) { // Helper function: calculate data range and align to interval boundaries
// Returns: DataRange struct
struct DataRange {
int startIndex;
int endIndex;
int numAveragedSamples;
int availableSamples;
};
DataRange calculateDataRangeAndAlignment(const JsonDocument& doc, int originalDataSize, time_t now,
int avgFactor, int targetIntervalMinutes, int barAreaWidth) {
DataRange result;
// Step 1: Find data range - start at now-1h, trim far future if needed
time_t targetStart = now - 3600; // 1 hour ago
// Find first data point at/before now-1h
result.startIndex = 0;
for (int i = originalDataSize - 1; i >= 0; i--) {
time_t dataTime = doc[i]["time"];
if (dataTime <= targetStart) {
result.startIndex = i;
break;
}
}
// Calculate maximum bars that can fit on display
int maxBars = barAreaWidth; // 1px per bar minimum
// Calculate how many samples we'll have after averaging
result.availableSamples = originalDataSize - result.startIndex;
result.numAveragedSamples = result.availableSamples / avgFactor;
// Step 2: Trim from far future if needed (prioritize now and near future)
result.endIndex = originalDataSize;
if (result.numAveragedSamples > maxBars) {
// Too many samples - limit the range
int maxSamplesNeeded = maxBars * avgFactor;
result.endIndex = result.startIndex + maxSamplesNeeded;
if (result.endIndex > originalDataSize) result.endIndex = originalDataSize;
result.availableSamples = result.endIndex - result.startIndex;
result.numAveragedSamples = result.availableSamples / avgFactor;
}
// Step 3: Align to interval boundary if averaging
if (avgFactor > 1) {
// Find first data point that aligns with target interval
for (int i = result.startIndex; i < result.endIndex; i++) {
time_t dataTime = doc[i]["time"];
struct tm dt;
localtime_r(&dataTime, &dt);
// Check if this timestamp aligns with target interval
if (targetIntervalMinutes == 30) {
if (dt.tm_min == 0 || dt.tm_min == 30) {
result.startIndex = i;
break;
}
} else if (targetIntervalMinutes == 60) {
if (dt.tm_min == 0) {
result.startIndex = i;
break;
}
}
}
// Recalculate after alignment
result.availableSamples = result.endIndex - result.startIndex;
result.numAveragedSamples = result.availableSamples / avgFactor;
}
return result;
}
// Helper function: Perform historic data backfill to optimize bar width
// Returns: BackfillResult struct
struct BackfillResult {
int startIndex;
int numAveragedSamples;
int availableSamples;
int addedHistoricCount;
double barwidthBefore;
double barwidthAfter;
};
BackfillResult performHistoricBackfill(int startIndex, int endIndex, int numAveragedSamples,
int avgFactor, int barAreaWidth, double targetBarwidth) {
BackfillResult result;
result.startIndex = startIndex;
result.numAveragedSamples = numAveragedSamples;
result.availableSamples = endIndex - startIndex;
result.addedHistoricCount = 0;
int futureRawCount = endIndex - startIndex; // Raw samples (before averaging)
int historicRawCount = startIndex; // Raw samples available before startIndex
// Calculate barwidth BEFORE backfill
result.barwidthBefore = (double)barAreaWidth / numAveragedSamples;
if (historicRawCount > 0) {
// Calculate current bar width
double pixelsPerBar = (double)barAreaWidth / numAveragedSamples;
int currentSpacing = (pixelsPerBar >= 3.0) ? 1 : 0;
double currentBarWidth = pixelsPerBar - currentSpacing;
// Scenario 2: Bars > 5px target - add data to reduce toward target
if (currentBarWidth > targetBarwidth) {
// Target: 5px bars with 1px spacing = 6px total per bar
int targetBars = barAreaWidth / (targetBarwidth + 1.0);
int barsToAdd = targetBars - numAveragedSamples;
if (barsToAdd > 0) {
int samplesToAdd = barsToAdd * avgFactor;
result.addedHistoricCount = std::min(samplesToAdd, historicRawCount);
result.startIndex -= result.addedHistoricCount;
// Bounds safety: ensure startIndex never goes negative
if (result.startIndex < 0) {
result.addedHistoricCount += result.startIndex; // Reduce by overflow amount
result.startIndex = 0;
}
result.availableSamples = endIndex - result.startIndex;
result.numAveragedSamples = result.availableSamples / avgFactor;
}
}
// Scenario 1: Bars <= 5px - fill empty space with historic data
else {
double currentPixelsPerBar = pixelsPerBar; // Use pixelsPerBar (not barwidth)
int currentPixelsInt = (int)currentPixelsPerBar; // e.g., 3 from 3.05px
// Keep adding bars as long as pixelsPerBar doesn't drop below next integer
while (historicRawCount > 0) {
// Try adding avgFactor more raw samples (= 1 more bar after averaging)
int testAveragedBars = result.numAveragedSamples + 1;
double testPixelsPerBar = (double)barAreaWidth / testAveragedBars;
int testPixelsInt = (int)testPixelsPerBar;
// Check if pixelsPerBar stays at or above current integer value
// This ensures bars don't shrink (e.g., stay at 3px, don't drop to 2px)
if (testPixelsInt >= currentPixelsInt) {
// Pixels per bar still >= current integer - add this bar
result.numAveragedSamples = testAveragedBars;
historicRawCount -= avgFactor; // Consume raw samples
result.addedHistoricCount += avgFactor;
result.startIndex -= avgFactor; // Move start backwards into historic data
// Bounds safety: ensure startIndex never goes negative
if (result.startIndex < 0) {
result.addedHistoricCount += result.startIndex; // Reduce by overflow amount
result.numAveragedSamples = (endIndex - 0) / avgFactor; // Recalculate with startIndex=0
result.startIndex = 0;
break; // Stop backfill
}
} else {
// Next bar would drop below current integer, done
break;
}
}
// Update availableSamples after backfill
if (result.addedHistoricCount > 0) {
result.availableSamples = endIndex - result.startIndex;
}
}
}
// Calculate barwidth after backfill
result.barwidthAfter = (double)barAreaWidth / result.numAveragedSamples;
return result;
}
// Data structure for averaged price points
struct AveragedDataPoint {
time_t time;
double price;
int hour;
int minute;
};
// Helper function: Find cheapest consecutive blocks for appliance scheduling
// Returns: CheapBlock struct
struct CheapBlock {
int start;
int end;
};
struct CheapBlocks {
CheapBlock block1;
CheapBlock block2;
};
CheapBlocks findCheapestConsecutiveBlocks(const AveragedDataPoint* avgData, int numSamples,
int blockSamples, time_t now) {
CheapBlocks result;
result.block1.start = -1;
result.block1.end = -1;
result.block2.start = -1;
result.block2.end = -1;
if (blockSamples <= 0 || blockSamples > numSamples) {
return result; // Invalid or disabled
}
// Find all candidate blocks (simple: sum all prices in each block)
struct BlockCandidate {
int start;
int end;
double sum;
};
std::vector<BlockCandidate> candidates;
// Scan through visible data to find all valid consecutive blocks
for (int i = 0; i <= numSamples - blockSamples; i++) {
const time_t block_start_time = avgData[i].time;
// Only consider future blocks (skip past data)
if (block_start_time < now) continue;
// Calculate sum for this block
double blockSum = 0;
for (int j = 0; j < blockSamples; j++) {
blockSum += avgData[i + j].price;
}
BlockCandidate candidate;
candidate.start = i;
candidate.end = i + blockSamples - 1;
candidate.sum = blockSum;
candidates.push_back(candidate);
}
// Sort candidates by sum (cheapest first)
std::sort(candidates.begin(), candidates.end(),
[](const BlockCandidate& a, const BlockCandidate& b) { return a.sum < b.sum; });
// Pick up to 2 non-overlapping cheap blocks
if (candidates.size() > 0) {
result.block1.start = candidates[0].start;
result.block1.end = candidates[0].end;
// Find second block that doesn't overlap with first
for (size_t i = 1; i < candidates.size(); i++) {
bool overlaps = (candidates[i].start <= result.block1.end && candidates[i].end >= result.block1.start);
if (!overlaps) {
result.block2.start = candidates[i].start;
result.block2.end = candidates[i].end;
break;
}
}
}
return result;
}
bool getDayAheadFeed(String& filename, JsonObject& cfgobj, tagRecord*& taginfo, imgParam& imageParams) {
wsLog("get dayahead prices"); wsLog("get dayahead prices");
// Magic number constants for bar width calculations
const double TARGET_BARWIDTH = 5.0; // Optimal bar width in pixels (good visibility)
const double MIN_BARWIDTH = 2.0; // Minimum bar width (below this, bars hard to see)
const int MIN_LABEL_SPACING = 30; // Minimum pixels between label centers
const int DASH_LENGTH = 3; // Dashed line segment length
const int GAP_LENGTH = 2; // Gap between dashed line segments
const int STEM_WIDTH = 3; // Current time arrow stem width
const int ARROW_WIDTH = 8; // Current time arrow head width
const int ARROW_HEIGHT = 6; // Current time arrow head height
const int STEM_HEIGHT = 10; // Current time arrow stem height
const int GAP_AFTER_ARROW = 2; // Gap between arrow tip and vertical line
JsonDocument loc; JsonDocument loc;
getTemplate(loc, 27, taginfo->hwType); getTemplate(loc, 27, taginfo->hwType);
@@ -1585,11 +1962,6 @@ bool getDayAheadFeed(String &filename, JsonObject &cfgobj, tagRecord *&taginfo,
time_t now; time_t now;
time(&now); time(&now);
struct tm timeinfo;
localtime_r(&now, &timeinfo);
char dateString[40];
strftime(dateString, sizeof(dateString), languageDateFormat[0].c_str(), &timeinfo);
HTTPClient http; HTTPClient http;
http.begin(URL); http.begin(URL);
@@ -1612,16 +1984,80 @@ bool getDayAheadFeed(String &filename, JsonObject &cfgobj, tagRecord *&taginfo,
initSprite(spr, imageParams.width, imageParams.height, imageParams); initSprite(spr, imageParams.width, imageParams.height, imageParams);
int n = doc.size(); int originalDataSize = doc.size();
if (originalDataSize == 0) {
wsErr("No data in dayahead feed");
return false;
}
// Detect native data interval (15-min, hourly, etc.)
int nativeIntervalMinutes = 15; // Default to 15 minutes (most common in Europe)
if (originalDataSize >= 2) {
time_t time0 = doc[0]["time"];
time_t time1 = doc[1]["time"];
nativeIntervalMinutes = (time1 - time0) / 60;
}
// Get user's preferred display interval (0 = native, 30 = 30 minutes, 60 = 1 hour)
int targetIntervalMinutes = cfgobj["interval"] ? cfgobj["interval"].as<int>() : 0;
if (targetIntervalMinutes == 0) {
targetIntervalMinutes = nativeIntervalMinutes; // Use native interval
}
// Calculate averaging factor (how many native samples per target interval)
int avgFactor = targetIntervalMinutes / nativeIntervalMinutes;
if (avgFactor < 1) avgFactor = 1; // Safety: no upsampling
// Get bar area width for calculations
int barAreaWidth = loc["bars"][1].as<int>();
// Store RAW current price BEFORE averaging (for accurate "now" display)
// We'll calculate this after we have units/tariff variables below
double rawCurrentPrice = std::numeric_limits<double>::quiet_NaN();
int rawCurrentIndex = -1;
int rawCurrentHour = 0; // Hour from the native interval containing "now"
int rawCurrentMinute = 0; // Minute from the native interval containing "now"
// Calculate data range and align to interval boundaries (Steps 1-3)
DataRange range = calculateDataRangeAndAlignment(doc, originalDataSize, now, avgFactor,
targetIntervalMinutes, barAreaWidth);
int startIndex = range.startIndex;
int endIndex = range.endIndex;
int numAveragedSamples = range.numAveragedSamples;
int availableSamples = range.availableSamples;
// Safety check
if (numAveragedSamples == 0) {
wsErr("Not enough data for selected interval");
return false;
}
// Perform historic data backfill to optimize bar width (Step 4)
BackfillResult backfill = performHistoricBackfill(startIndex, endIndex, numAveragedSamples,
avgFactor, barAreaWidth, TARGET_BARWIDTH);
startIndex = backfill.startIndex;
numAveragedSamples = backfill.numAveragedSamples;
availableSamples = backfill.availableSamples;
// Debug logging (always visible in web console)
int futureRawCount = endIndex - (startIndex + backfill.addedHistoricCount);
int historicRawCount = startIndex + backfill.addedHistoricCount;
wsLog("Day-ahead bar sizing: future_raw=" + String(futureRawCount) +
" (incl now), historic_raw=" + String(historicRawCount) +
", barwidth_before=" + String(backfill.barwidthBefore, 1) +
"px, added_historic=" + String(backfill.addedHistoricCount) +
", barwidth_after=" + String(backfill.barwidthAfter, 1) +
"px (target=" + String(TARGET_BARWIDTH, 1) + "px)");
int units = cfgobj["units"].as<int>(); int units = cfgobj["units"].as<int>();
if (units == 0) units = 1; if (units == 0) units = 1;
double tarifkwh; double tarifkwh;
double tariftax = cfgobj["tarifftax"].as<double>(); double tariftax = cfgobj["tarifftax"].as<double>();
double minPrice = std::numeric_limits<double>::max();
double maxPrice = std::numeric_limits<double>::lowest();
double prices[n];
// Create averaged data array
AveragedDataPoint avgData[numAveragedSamples];
// Parse tariff array if provided
JsonDocument doc2; JsonDocument doc2;
JsonArray tariffArray; JsonArray tariffArray;
std::string tariffString = cfgobj["tariffkwh"].as<std::string>(); std::string tariffString = cfgobj["tariffkwh"].as<std::string>();
@@ -1632,19 +2068,84 @@ bool getDayAheadFeed(String &filename, JsonObject &cfgobj, tagRecord *&taginfo,
Serial.println("Error in tariffkwh array"); Serial.println("Error in tariffkwh array");
} }
} }
for (int i = 0; i < n; i++) {
const JsonObject &obj = doc[i];
if (tariffArray.size() == 24) { // Average the data according to selected interval
for (int i = 0; i < numAveragedSamples; i++) {
double priceSum = 0;
time_t blockTime = doc[startIndex + i * avgFactor]["time"];
// Average prices across the interval
for (int j = 0; j < avgFactor; j++) {
int idx = startIndex + i * avgFactor + j;
if (idx >= endIndex) break; // Safety check - respect endIndex
const JsonObject& obj = doc[idx];
const time_t item_time = obj["time"]; const time_t item_time = obj["time"];
struct tm item_timeinfo; struct tm item_timeinfo;
localtime_r(&item_time, &item_timeinfo); localtime_r(&item_time, &item_timeinfo);
tarifkwh = tariffArray[item_timeinfo.tm_hour].as<double>(); if (tariffArray.size() == 24) {
} else { tarifkwh = tariffArray[item_timeinfo.tm_hour].as<double>();
tarifkwh = cfgobj["tariffkwh"].as<double>(); } else {
tarifkwh = cfgobj["tariffkwh"].as<double>();
}
double price = (obj["price"].as<double>() / 10 + tarifkwh) * (1 + tariftax / 100) / units;
priceSum += price;
} }
prices[i] = (obj["price"].as<double>() / 10 + tarifkwh) * (1 + tariftax / 100) / units;
// Store averaged data
avgData[i].price = priceSum / avgFactor;
avgData[i].time = blockTime;
struct tm blockTimeInfo;
localtime_r(&blockTime, &blockTimeInfo);
avgData[i].hour = blockTimeInfo.tm_hour;
avgData[i].minute = blockTimeInfo.tm_min;
}
// Now work with averaged data (n becomes numAveragedSamples)
int n = numAveragedSamples;
// Calculate RAW current price (find closest PAST/CURRENT data point, never future)
if (std::isnan(rawCurrentPrice)) {
time_t closestTimeDiff = std::numeric_limits<time_t>::max();
for (int i = 0; i < originalDataSize; i++) {
time_t dataTime = doc[i]["time"];
// Skip future timestamps - only consider past and current
if (dataTime > now) continue;
time_t diff = now - dataTime;
if (diff < closestTimeDiff) {
closestTimeDiff = diff;
rawCurrentIndex = i;
// Calculate raw price with tariff (same logic as averaging loop)
struct tm item_timeinfo;
localtime_r(&dataTime, &item_timeinfo);
if (tariffArray.size() == 24) {
tarifkwh = tariffArray[item_timeinfo.tm_hour].as<double>();
} else {
tarifkwh = cfgobj["tariffkwh"].as<double>();
}
rawCurrentPrice = (doc[i]["price"].as<double>() / 10 + tarifkwh) * (1 + tariftax / 100) / units;
rawCurrentHour = item_timeinfo.tm_hour; // Store the native interval's hour
rawCurrentMinute = item_timeinfo.tm_min; // Store the native interval's minute
}
}
}
// Calculate min/max and create sorted price array for percentiles
double minPrice = std::numeric_limits<double>::max();
double maxPrice = std::numeric_limits<double>::lowest();
double prices[n];
for (int i = 0; i < n; i++) {
prices[i] = avgData[i].price;
minPrice = std::min(minPrice, prices[i]); minPrice = std::min(minPrice, prices[i]);
maxPrice = std::max(maxPrice, prices[i]); maxPrice = std::max(maxPrice, prices[i]);
} }
@@ -1666,7 +2167,25 @@ bool getDayAheadFeed(String &filename, JsonObject &cfgobj, tagRecord *&taginfo,
} }
} }
uint16_t barwidth = loc["bars"][1].as<int>() / n; // Step 4: Calculate optimal bar width and spacing
// Goal: Fill entire width with bars, using spacing when room allows
int availableWidth = loc["bars"][1].as<int>();
int pixelsPerBar = availableWidth / n; // How many pixels each bar+spacing can use
int barwidth;
int barSpacing;
if (pixelsPerBar >= 3) {
// Room for spacing - use 1px gap between bars
barSpacing = 1;
barwidth = pixelsPerBar - barSpacing; // Remaining pixels for bar itself
} else {
// Tight fit - no room for spacing
barSpacing = 0;
barwidth = pixelsPerBar; // Use all available pixels for bar
}
// Result: n × (barwidth + barSpacing) ≈ availableWidth (within rounding)
uint16_t barheight = loc["bars"][2].as<int>() / (maxPrice - minPrice); uint16_t barheight = loc["bars"][2].as<int>() / (maxPrice - minPrice);
uint16_t arrowY = 0; uint16_t arrowY = 0;
if (loc["bars"].size() >= 5) arrowY = loc["bars"][4].as<int>(); if (loc["bars"].size() >= 5) arrowY = loc["bars"][4].as<int>();
@@ -1675,43 +2194,148 @@ bool getDayAheadFeed(String &filename, JsonObject &cfgobj, tagRecord *&taginfo,
bool showcurrent = true; bool showcurrent = true;
if (cfgobj["showcurr"] && cfgobj["showcurr"] == "0") showcurrent = false; if (cfgobj["showcurr"] && cfgobj["showcurr"] == "0") showcurrent = false;
// Calculate label interval based on display width and number of bars
// Goal: Space labels far enough apart to avoid overlap
// Note: availableWidth already declared above, reuse it here
int maxLabels = availableWidth / MIN_LABEL_SPACING;
int labelInterval = (n + maxLabels - 1) / maxLabels; // Round up division
// Ensure labelInterval is at least 1
if (labelInterval < 1) labelInterval = 1;
// For better aesthetics, round to nearest multiple based on target interval
int labelsPerHour = 60 / targetIntervalMinutes;
if (labelsPerHour > 0) {
// Try to show labels at nice intervals (every hour, every 2 hours, etc.)
int hoursPerLabel = (labelInterval + labelsPerHour - 1) / labelsPerHour; // Round up
if (hoursPerLabel < 1) hoursPerLabel = 1;
labelInterval = hoursPerLabel * labelsPerHour;
// But don't exceed our max labels constraint
if (n / labelInterval > maxLabels) {
// Fall back to spacing-based calculation
labelInterval = (n + maxLabels - 1) / maxLabels;
}
}
// Find cheapest consecutive block(s) for appliance scheduling (Step 5)
double cheapBlockHoursRaw = cfgobj["cheapblock"] ? cfgobj["cheapblock"].as<double>() : 3.0;
int blockSamples = (int)(cheapBlockHoursRaw * labelsPerHour); // Convert hours to sample count
CheapBlocks cheapBlocks = findCheapestConsecutiveBlocks(avgData, n, blockSamples, now);
int cheapBlockStart1 = cheapBlocks.block1.start;
int cheapBlockEnd1 = cheapBlocks.block1.end;
int cheapBlockStart2 = cheapBlocks.block2.start;
int cheapBlockEnd2 = cheapBlocks.block2.end;
// Store pointer position for drawing after all bars
int pointerX = -1; // -1 means no pointer to draw
int currentHour = 0; // Hour of the current interval
int currentMinute = 0; // Minute of the current interval
int currentBarHeight = 0; // Height of the current bar (for narrow bar line skipping)
// Draw light grey background for cheapest blocks (BEFORE labels/ticks so they draw on top)
int baselineY = spr.height() - barBottom;
int xAxisHeight = 20; // Height of X-axis area (ticks + labels)
if (cheapBlockStart1 >= 0 && cheapBlockEnd1 >= 0) {
int rectX = barX + cheapBlockStart1 * (barwidth + barSpacing);
int rectWidth = (cheapBlockEnd1 - cheapBlockStart1 + 1) * (barwidth + barSpacing);
spr.fillRect(rectX, baselineY + 1, rectWidth, xAxisHeight - 1, TFT_LIGHTGREY);
}
if (cheapBlockStart2 >= 0 && cheapBlockEnd2 >= 0) {
int rectX = barX + cheapBlockStart2 * (barwidth + barSpacing);
int rectWidth = (cheapBlockEnd2 - cheapBlockStart2 + 1) * (barwidth + barSpacing);
spr.fillRect(rectX, baselineY + 1, rectWidth, xAxisHeight - 1, TFT_LIGHTGREY);
}
for (int i = 0; i < n; i++) { for (int i = 0; i < n; i++) {
const JsonObject &obj = doc[i]; // Get data from avgData array (already trimmed to visible range)
const time_t item_time = obj["time"]; const time_t item_time = avgData[i].time;
struct tm item_timeinfo; const int item_hour = avgData[i].hour;
localtime_r(&item_time, &item_timeinfo); const int item_minute = avgData[i].minute;
const double price = avgData[i].price;
if (tariffArray.size() == 24) { uint16_t barcolor = getPercentileColor(prices, numAveragedSamples, price, imageParams.hwdata);
tarifkwh = tariffArray[item_timeinfo.tm_hour].as<double>();
} else {
tarifkwh = cfgobj["tariffkwh"].as<double>();
}
const double price = (obj["price"].as<double>() / 10 + tarifkwh) * (1 + tariftax / 100) / units;
uint16_t barcolor = getPercentileColor(prices, n, price, imageParams.hwdata);
uint16_t thisbarh = mapDouble(price, minPrice, maxPrice, 0, loc["bars"][2].as<int>()); uint16_t thisbarh = mapDouble(price, minPrice, maxPrice, 0, loc["bars"][2].as<int>());
spr.fillRect(barX + i * barwidth, spr.height() - barBottom - thisbarh, barwidth - 1, thisbarh, barcolor); spr.fillRect(barX + i * (barwidth + barSpacing), spr.height() - barBottom - thisbarh, barwidth, thisbarh, barcolor);
if (i % 2 == 0 && loc["time"][0]) {
drawString(spr, String(item_timeinfo.tm_hour), barX + i * barwidth + barwidth / 3 + 1, spr.height() - barBottom + 3, loc["time"][0], TC_DATUM, TFT_BLACK); // Draw tickmarks and labels at appropriate intervals
int labelX = barX + i * (barwidth + barSpacing) + barwidth / 2;
int tickY = spr.height() - barBottom;
// Check if this bar represents the start of an hour (minute = 0)
bool isHourStart = (item_minute == 0);
// Check if this bar represents a half-hour (minute = 30)
bool isHalfHour = (item_minute == 30);
// Skip tick marks on displays with limited vertical space (height < 150px)
// to prevent labels from being pushed off the bottom edge
bool skipTicks = (spr.height() < 150);
// Every 2 hours: Black tick (4px) + label
if (i % labelInterval == 0 && loc["time"][0]) {
if (!skipTicks) {
spr.drawLine(labelX, tickY, labelX, tickY + 4, TFT_BLACK);
}
drawString(spr, String(item_hour), labelX, tickY + (skipTicks ? 3 : 6), loc["time"][0], TC_DATUM, TFT_BLACK);
}
// Every hour (not already labeled): Dark grey tick (3px)
else if (isHourStart && !skipTicks) {
spr.drawLine(labelX, tickY, labelX, tickY + 3, getColor("darkgray"));
}
// Every half hour: Very short dark grey tick (1px)
else if (isHalfHour && !skipTicks) {
spr.drawPixel(labelX, tickY + 1, getColor("darkgray"));
} }
if (now - item_time < 3600 && std::isnan(pricenow) && showcurrent) { // Store pointer position for drawing after all bars
spr.fillRect(barX + i * barwidth + (barwidth > 6 ? 3 : 1), 5 + arrowY, (barwidth > 6 ? barwidth - 6 : barwidth - 2), 10, imageParams.highlightColor); // Use RAW current price (stored before averaging) for accurate display
spr.fillTriangle(barX + i * barwidth, 15 + arrowY, // Find the bar that contains "now" by checking if now falls within this bar's time interval
barX + i * barwidth + barwidth - 1, 15 + arrowY, // Important: Use targetIntervalMinutes (the actual bar interval after averaging/display)
barX + i * barwidth + (barwidth - 1) / 2, 15 + barwidth + arrowY, imageParams.highlightColor); if (std::isnan(pricenow) && showcurrent) {
spr.drawLine(barX + i * barwidth + (barwidth - 1) / 2, 20 + barwidth + arrowY, barX + i * barwidth + (barwidth - 1) / 2, spr.height(), TFT_BLACK); time_t barEndTime = item_time + (targetIntervalMinutes * 60); // End of this bar's time range
pricenow = price; if (now >= item_time && now < barEndTime) {
pointerX = barX + i * (barwidth + barSpacing) + barwidth / 2; // Center of the bar
pricenow = rawCurrentPrice; // Use raw price, not averaged
currentHour = rawCurrentHour; // Use native interval's hour (not averaged block)
currentMinute = rawCurrentMinute; // Use native interval's minute (not averaged block)
currentBarHeight = thisbarh; // Store bar height for line drawing
}
} }
} }
// Draw current hour pointer AFTER all bars (so it won't be chopped off)
// Use constant narrow stem with wider arrow head for a proper arrow shape
if (pointerX >= 0 && showcurrent) {
// Arrow stem (narrow rectangle)
spr.fillRect(pointerX - STEM_WIDTH / 2, 5 + arrowY, STEM_WIDTH, STEM_HEIGHT, imageParams.highlightColor);
// Arrow head (wider triangle)
spr.fillTriangle(pointerX - ARROW_WIDTH / 2, 15 + arrowY,
pointerX + ARROW_WIDTH / 2, 15 + arrowY,
pointerX, 15 + arrowY + ARROW_HEIGHT, imageParams.highlightColor);
// Vertical line: dashed from arrow to bar, solid from baseline to bottom
int lineStartY = 21 + arrowY + GAP_AFTER_ARROW;
int baselineY = spr.height() - barBottom;
int barTopY = baselineY - currentBarHeight;
// Draw DASHED line from arrow to top of bar (with gap) - for visual clarity
for (int y = lineStartY; y < barTopY - 2; y += DASH_LENGTH + GAP_LENGTH) {
int segmentEnd = min(y + DASH_LENGTH, barTopY - 2);
spr.drawLine(pointerX, y, pointerX, segmentEnd, TFT_BLACK);
}
// Draw solid line from baseline to bottom (for time indication in X-axis area)
spr.drawLine(pointerX, baselineY, pointerX, spr.height(), TFT_BLACK);
}
if (showcurrent) { if (showcurrent) {
if (barwidth < 5) { if (barwidth < 5) {
drawString(spr, String(timeinfo.tm_hour) + ":00", spr.width() / 2, 5, "calibrib16.vlw", TC_DATUM, TFT_BLACK, 30); drawString(spr, String(currentHour) + ":" + (currentMinute < 10 ? "0" : "") + String(currentMinute), spr.width() / 2, 5, "calibrib16.vlw", TC_DATUM, TFT_BLACK, 30);
drawString(spr, String(pricenow) + "/kWh", spr.width() / 2, 25, loc["head"][0], TC_DATUM, TFT_BLACK, 30); drawString(spr, String(pricenow) + "/kWh", spr.width() / 2, 25, loc["head"][0], TC_DATUM, TFT_BLACK, 30);
} else { } else {
drawString(spr, String(timeinfo.tm_hour) + ":00", barX, 5, loc["head"][0], TL_DATUM, TFT_BLACK, 30); drawString(spr, String(currentHour) + ":" + (currentMinute < 10 ? "0" : "") + String(currentMinute), barX, 5, loc["head"][0], TL_DATUM, TFT_BLACK, 30);
drawString(spr, String(pricenow) + "/kWh", spr.width() - barX, 5, loc["head"][0], TR_DATUM, TFT_BLACK, 30); drawString(spr, String(pricenow) + "/kWh", spr.width() - barX, 5, loc["head"][0], TR_DATUM, TFT_BLACK, 30);
} }
} }
@@ -2189,7 +2813,7 @@ int getJsonTemplateUrl(String &filename, String URL, time_t fetched, String MAC,
http.addHeader("If-Modified-Since", formatHttpDate(fetched)); http.addHeader("If-Modified-Since", formatHttpDate(fetched));
http.addHeader("X-ESL-MAC", MAC); http.addHeader("X-ESL-MAC", MAC);
http.setFollowRedirects(HTTPC_STRICT_FOLLOW_REDIRECTS); http.setFollowRedirects(HTTPC_STRICT_FOLLOW_REDIRECTS);
http.setTimeout(5000); http.setTimeout(20000);
const int httpCode = http.GET(); const int httpCode = http.GET();
if (httpCode == 200) { if (httpCode == 200) {
drawJsonStream(http.getStream(), filename, taginfo, imageParams); drawJsonStream(http.getStream(), filename, taginfo, imageParams);
@@ -2477,6 +3101,61 @@ void prepareConfigFile(const uint8_t *dst, const JsonObject &config) {
} }
#endif #endif
#ifdef CONTENT_TIME_RAWDATA
bool is_leap_year(int year) {// Somehow mktime did not return the local unix time so lets to it in a manual way
year += 1900;
return (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0));
}
int days_in_month(int month, int year) {
static const int days[] = { 31, 28, 31, 30, 31, 30,
31, 31, 30, 31, 30, 31 };
if (month == 1 && is_leap_year(year)) {
return 29;
}
return days[month];
}
uint32_t convert_tm_to_seconds(struct tm *t) {
const int SECONDS_PER_MINUTE = 60;
const int SECONDS_PER_HOUR = 3600;
const int SECONDS_PER_DAY = 86400;
long long total_days = 0;
for (int year = 70; year < t->tm_year; year++) {
total_days += is_leap_year(year) ? 366 : 365;
}
for (int month = 0; month < t->tm_mon; month++) {
total_days += days_in_month(month, t->tm_year);
}
total_days += (t->tm_mday - 1);
long long total_seconds = total_days * SECONDS_PER_DAY;
total_seconds += t->tm_hour * SECONDS_PER_HOUR;
total_seconds += t->tm_min * SECONDS_PER_MINUTE;
total_seconds += t->tm_sec;
return total_seconds;
}
void prepareTIME_RAW(const uint8_t *dst, time_t now) {
uint8_t *data;
size_t len = 1 + 4 + 4 + 1;
struct tm timeinfo;
localtime_r(&now, &timeinfo);
uint32_t local_time = convert_tm_to_seconds(&timeinfo) + 20;// Adding 20 seconds for the average of upload time
uint32_t unix_time = now + 20;
data = new uint8_t[len + 1];
data[0] = len;// Length all
data[1] = 0x01;// Version of Time and RAW
data[2] = ((uint8_t*)&local_time)[0];
data[3] = ((uint8_t*)&local_time)[1];
data[4] = ((uint8_t*)&local_time)[2];
data[5] = ((uint8_t*)&local_time)[3];
data[6] = ((uint8_t*)&unix_time)[0];
data[7] = ((uint8_t*)&unix_time)[1];
data[8] = ((uint8_t*)&unix_time)[2];
data[9] = ((uint8_t*)&unix_time)[3];
data[10] = 1; // Design, 1 = Full DateTime 2 = Just Time Segment Style
prepareDataAvail(data, len + 1, DATATYPE_TIME_RAW_DATA, dst);
}
#endif
void getTemplate(JsonDocument &json, const uint8_t id, const uint8_t hwtype) { void getTemplate(JsonDocument &json, const uint8_t id, const uint8_t hwtype) {
JsonDocument filter; JsonDocument filter;
JsonDocument doc; JsonDocument doc;

View File

@@ -365,23 +365,59 @@ uint8_t *g5Compress(uint16_t width, uint16_t height, uint8_t *buffer, uint16_t b
} }
#endif #endif
void doTimestamp(TFT_eSprite *spr) { // The "ts_option" is a bitmapped variable with a default value of 1
// which is black on white, long format @ bottom right.
//
// b2, b1, b0:
// 0 - no timestamp
// 1 - bottom right
// 2 - top right
// 3 - bottom left
// 4 - top left
// 5 -> 7 reserved
// b3:
// 0 - long format (year-month-day hr:min)
// 1 - short format (month-day hr:min)
// b4:
// 0 - black on white
// 1 - white on black
// b5 -> b7: reserved
//
void doTimestamp(TFT_eSprite *spr, uint8_t ts_option) {
time_t now = time(nullptr); time_t now = time(nullptr);
struct tm *timeinfo = localtime(&now); struct tm *timeinfo = localtime(&now);
char buffer[20]; char buffer[20];
strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M", timeinfo); strftime(buffer, sizeof(buffer),
(ts_option & 0x8) ? "%m-%d %H:%M" : "%Y-%m-%d %H:%M",timeinfo);
int ts_chars = strlen(buffer);
// spr->drawRect(spr->width() - 16 * 6 - 4, spr->height() - 10 - 2, 16 * 6 + 3, 11, TFT_BLACK); uint16_t char_color;
spr->drawRect(spr->width() - 16 * 6 - 3, spr->height() - 10 - 1, 16 * 6 + 1, 9, TFT_WHITE); uint16_t bg_color;
spr->setTextColor(TFT_BLACK, TFT_WHITE);
spr->setCursor(spr->width() - 16 * 6 - 2, spr->height() - 10, 1); if(ts_option & 0x10) {
char_color = TFT_WHITE;
bg_color= TFT_BLACK;
}
else {
char_color = TFT_BLACK;
bg_color = TFT_WHITE;
}
ts_option = (ts_option & 0x3) - 1;
int32_t ts_x = (ts_option & 2) ? 1 : spr->width() - ts_chars * 6 - 2;
int32_t ts_y = (ts_option & 1) ? 1 : spr->height() - 10;
spr->drawRect(ts_x - 1, ts_y - 1, ts_chars * 6 + 1, 9, bg_color);
spr->setTextColor(char_color, bg_color);
spr->setCursor(ts_x,ts_y);
spr->print(buffer); spr->print(buffer);
} }
void spr2buffer(TFT_eSprite &spr, String &fileout, imgParam &imageParams) { void spr2buffer(TFT_eSprite &spr, String &fileout, imgParam &imageParams) {
long t = millis(); long t = millis();
if (config.showtimestamp) doTimestamp(&spr); if (imageParams.ts_option) doTimestamp(&spr,imageParams.ts_option);
#ifdef HAS_TFT #ifdef HAS_TFT
extern uint8_t YellowSense; extern uint8_t YellowSense;
if (fileout == "direct") { if (fileout == "direct") {

View File

@@ -3,6 +3,7 @@
#include <Arduino.h> #include <Arduino.h>
#include <HardwareSerial.h> #include <HardwareSerial.h>
#include <system.h> #include <system.h>
#include <WiFi.h>
#include "commstructs.h" #include "commstructs.h"
#include "contentmanager.h" #include "contentmanager.h"
@@ -14,6 +15,7 @@
#include "storage.h" #include "storage.h"
#include "web.h" #include "web.h"
#include "zbs_interface.h" #include "zbs_interface.h"
#include "wifimanager.h"
#define LOG(format, ...) printf(format, ##__VA_ARGS__) #define LOG(format, ...) printf(format, ##__VA_ARGS__)
@@ -802,7 +804,7 @@ void checkWaitPowerCycle() {
#endif #endif
} }
void segmentedShowIp() { void segmentedShowIp() {
IPAddress IP = WiFi.localIP(); IPAddress IP = wm.localIP();
char temp[12]; char temp[12];
vTaskDelay(2000 / portTICK_PERIOD_MS); vTaskDelay(2000 / portTICK_PERIOD_MS);
sendAPSegmentedData(apInfo.mac, (String) "IP Addr", 0x0200, true, true); sendAPSegmentedData(apInfo.mac, (String) "IP Addr", 0x0200, true, true);

View File

@@ -26,6 +26,7 @@
#include "tag_db.h" #include "tag_db.h"
#include "udp.h" #include "udp.h"
#include "wifimanager.h" #include "wifimanager.h"
#include <sys/time.h>
#ifdef HAS_EXT_FLASHER #ifdef HAS_EXT_FLASHER
#include "webflasher.h" #include "webflasher.h"
@@ -648,6 +649,28 @@ void init_web() {
request->send(200, "text/plain", "Ok, saved"); request->send(200, "text/plain", "Ok, saved");
}); });
// Allow external time sync (e.g., from Home Assistant) without Internet
// Usage: POST /set_time with form field 'epoch' (UNIX time seconds)
server.on("/set_time", HTTP_POST, [](AsyncWebServerRequest *request) {
if (request->hasParam("epoch", true)) {
time_t epoch = static_cast<time_t>(request->getParam("epoch", true)->value().toInt());
if (epoch > 1600000000) { // basic sanity check (~2020-09-13)
struct timeval tv;
tv.tv_sec = epoch;
tv.tv_usec = 0;
settimeofday(&tv, nullptr);
logLine("Time set via /set_time");
wsSendSysteminfo();
request->send(200, "text/plain", "ok");
return;
} else {
request->send(400, "text/plain", "invalid epoch");
return;
}
}
request->send(400, "text/plain", "missing 'epoch'");
});
server.on("/set_var", HTTP_POST, [](AsyncWebServerRequest *request) { server.on("/set_var", HTTP_POST, [](AsyncWebServerRequest *request) {
if (request->hasParam("key", true) && request->hasParam("val", true)) { if (request->hasParam("key", true) && request->hasParam("val", true)) {
std::string key = request->getParam("key", true)->value().c_str(); std::string key = request->getParam("key", true)->value().c_str();

View File

@@ -44,8 +44,27 @@
{ {
"id": 1, "id": 1,
"name": "Current date", "name": "Current date",
"desc": "Shows the current date", "desc": "Shows the current date. In some templates, the sunrise and sunset times are shown as well, when you fill in your location.",
"param": [ ] "param": [
{
"key": "location",
"name": "Location",
"desc": "Name of the city. This is used to lookup the lat/long data, and to display as the title",
"type": "geoselect"
},
{
"key": "#lat",
"name": "Lat",
"desc": "Latitude (set automatic when generating image)",
"type": "ro"
},
{
"key": "#lon",
"name": "Lon",
"desc": "Longitude (set automatic when generating image)",
"type": "ro"
}
]
}, },
{ {
"id": 2, "id": 2,
@@ -432,6 +451,29 @@
"0": "No", "0": "No",
"1": "-Yes" "1": "-Yes"
} }
},
{
"key": "interval",
"name": "Display interval",
"desc": "Data averaging interval for better readability on smaller displays",
"type": "select",
"options": {
"0": "-Native (15-min or hourly)",
"30": "30 minutes",
"60": "1 hour"
}
},
{
"key": "cheapblock",
"name": "Cheap block hours",
"desc": "Number of hours for cheapest consecutive block (e.g., 3 for dishwasher, 2.5 for 2h30m). Set to 0 to disable. Shows up to 2 non-overlapping blocks.",
"type": "text"
},
{
"key": "updatefreq",
"name": "Update frequency",
"desc": "Tag refresh interval in minutes (e.g., 15, 30, 60). Default is 15 minutes to match 15-minute data intervals. Higher values save battery.",
"type": "text"
} }
] ]
}, },
@@ -742,5 +784,12 @@
"type": "binfile" "type": "binfile"
} }
] ]
},
{
"id": 29,
"name": "Current Time",
"desc": "Displays the current time on the tag, only rarely supported even if shown here! It uses a fast LUT when possible otherwise a full refresh which is not very battery friendly and will anoy by flickering every minute",
"param": [
]
} }
] ]

View File

@@ -777,8 +777,10 @@
if (typeof lang === "undefined") { if (typeof lang === "undefined") {
lang = getLangFromFilename(file); lang = getLangFromFilename(file);
} }
if (typeof theme === "undefined") {
if (typeof theme === "undefined") theme = "textmate"; const currentTheme = localStorage.getItem('theme') || (window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light');
theme = (currentTheme === 'dark') ? "tomorrow_night" : "textmate";
}
if (typeof type === "undefined") { if (typeof type === "undefined") {
type = "text/" + lang; type = "text/" + lang;

View File

@@ -25,11 +25,11 @@
<div class="tablinks material-symbols-outlined" data-target="hometab" title="Dashboard">home</div> <div class="tablinks material-symbols-outlined" data-target="hometab" title="Dashboard">home</div>
<div class="tablinks material-symbols-outlined" data-target="tagtab" title="Tags">sell</div> <div class="tablinks material-symbols-outlined" data-target="tagtab" title="Tags">sell</div>
<div class="tablinks material-symbols-outlined" data-target="aptab" title="Access Points">cell_tower</div> <div class="tablinks material-symbols-outlined" data-target="aptab" title="Access Points">cell_tower</div>
<!--<div class="tablinks material-symbols-outlined" data-target="templatetab" title="Templates">browse <!--<div class="tablinks material-symbols-outlined" data-target="templatetab" title="Templates">browse</div>-->
</div>-->
<div class="tablinks material-symbols-outlined" data-target="flashtab" title="Tag flasher" style="display:none;">flash_on</div> <div class="tablinks material-symbols-outlined" data-target="flashtab" title="Tag flasher" style="display:none;">flash_on</div>
<div class="tablinks material-symbols-outlined" data-target="configtab" title="Settings">settings</div> <div class="tablinks material-symbols-outlined" data-target="configtab" title="Settings">settings</div>
<div class="tablinks material-symbols-outlined" data-target="logtab" title="Logging">text_snippet</div> <div class="tablinks material-symbols-outlined" data-target="logtab" title="Logging">text_snippet</div>
<button id="theme-toggle" class="theme-toggle-btn material-symbols-outlined" title="Toggle Theme">light_mode</button>
</div> </div>
<!-- /tabs --> <!-- /tabs -->
<div><span id="runstate"></div> <div><span id="runstate"></div>
@@ -530,6 +530,9 @@ options:
<button id="confirmSelectRepo">Confirm</button><button id="cancelSelectRepo">Cancel</button> <button id="confirmSelectRepo">Confirm</button><button id="cancelSelectRepo">Cancel</button>
</div> </div>
<h4>Releases</h4> <h4>Releases</h4>
To update to the latest version, use the big 'update now' button if it is shown on top of this screen.<br>
To up/downgrade to other versions: for the smoothest experience, first update the ESP32 part and<br>
without rebooting, update the filesystem, then reboot the AP and reload the webpage.<br>
<div id="releasetable" class="releasetable"></div> <div id="releasetable" class="releasetable"></div>
<h4 id="radio_release_title"></h4> <h4 id="radio_release_title"></h4>
<div id="radio_releasetable" class="releasetable"></div> <div id="radio_releasetable" class="releasetable"></div>
@@ -620,8 +623,7 @@ options:
</p> </p>
</dialog> </dialog>
<ul id="context-menu" <ul id="context-menu" style="display: none; position: absolute;">
style="display: none; position: absolute; background: white; border: 1px solid gray; padding: 0; list-style: none;">
</ul> </ul>
</body> </body>

View File

@@ -0,0 +1,415 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>JSON Template Publisher - Flat Dark</title>
<style>
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
margin: 0;
padding: 20px;
background-color: #1e1e1e;
color: #dcdcdc;
display: flex;
justify-content: center;
min-height: 100vh;
}
.main-wrapper {
display: flex;
gap: 25px;
width: 100%;
max-width: 1200px;
padding: 20px;
}
.input-column, .preview-column {
flex: 1;
display: flex;
flex-direction: column;
}
.preview-column {
position: sticky;
top: 20px;
align-self: flex-start;
}
.container {
background-color: #2a2a2a;
padding: 25px;
border-radius: 8px;
border: 1px solid #383838;
width: 100%;
box-sizing: border-box;
}
.input-column .container {
}
h3 {
color: #4dabf7;
text-align: center;
margin-top: 0;
margin-bottom: 20px;
font-size: 1.6em;
font-weight: 600;
}
p, label {
line-height: 1.6;
}
a {
color: #4dabf7;
text-decoration: none;
}
a:hover {
text-decoration: underline;
color: #74c0fc;
}
input[type="text"], textarea, select {
width: 100%;
padding: 10px 12px;
margin-bottom: 15px;
border: 1px solid #4a4a4a;
border-radius: 4px;
box-sizing: border-box;
font-size: 0.95rem;
background-color: #303030;
color: #dcdcdc;
}
input[type="text"]:focus, textarea:focus, select:focus {
outline: none;
border-color: #4dabf7;
box-shadow: 0 0 0 2px rgba(77, 171, 247, 0.3);
}
textarea {
min-height: 140px;
resize: vertical;
}
input[type="submit"], button {
background-color: #0078d4;
color: white;
padding: 10px 20px;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 1rem;
font-weight: 500;
transition: background-color 0.15s ease-in-out;
}
input[type="submit"]:hover, button:hover {
background-color: #005a9e;
}
.form-group {
margin-bottom: 18px;
}
.form-group label {
display: block;
margin-bottom: 5px;
font-weight: 500;
color: #b0b0b0;
}
#previewArea {
margin-top: 0;
padding: 20px;
border: 1px solid #383838;
border-radius: 8px;
background-color: #2a2a2a;
text-align: center;
overflow: auto;
width: 100%;
box-sizing: border-box;
}
#previewArea h4 {
margin-top: 0;
color: #4dabf7;
}
#previewCanvas {
border: 1px solid #4f4f4f;
max-width: 100%;
max-height: 450px;
height: auto;
display: block;
margin: 12px auto;
transform-origin: center center;
background-color: #fff;
}
.info-text {
font-size: 0.85em;
color: #999;
margin-bottom: 15px;
}
.status-message {
margin-top: 10px;
padding: 8px 12px;
border-radius: 4px;
word-break: break-word;
border: 1px solid transparent;
font-size: 0.9em;
}
.error-message { color: #ffcdd2; background-color: #c62828; border-color: #b71c1c; }
.success-message { color: #c8e6c9; background-color: #2e7d32; border-color: #1b5e20; }
.warning-message { color: #fff9c4; background-color: #f9a825; border-color: #f57f17; }
.info-message { color: #bbdefb; background-color: #1565c0; border-color: #0d47a1; }
.flex-group { display: flex; gap: 12px; align-items: flex-end; flex-wrap: wrap; }
.flex-group > div { flex: 1; min-width: 180px; }
.flex-group > button { flex-shrink: 0; margin-bottom: 15px; padding: 10px 15px; }
#clearMacHistoryBtn { background-color: #d32f2f; }
#clearMacHistoryBtn:hover { background-color: #b71c1c; }
</style>
<script src="https://cdnjs.cloudflare.com/ajax/libs/pako/2.1.0/pako.min.js"></script>
<script>
const MAX_IMAGE_FLIPS=640,HORIZ_SHORT_SHORT=0,HORIZ_SHORT_LONG=1,HORIZ_LONG_SHORT=2,HORIZ_LONG_LONG=3,G5_SUCCESS=0,G5_INVALID_PARAMETER=1,G5_DECODE_ERROR=2,REGISTER_WIDTH=32;const code_table=[0x90,0,0x40,0,3,7,0x13,7,2,6,2,6,0x12,6,0x12,6,0x30,4,0x30,4,0x30,4,0x30,4,0x30,4,0x30,4,0x30,4,0x30,4,0x20,3,0x20,3,0x20,3,0x20,3,0x20,3,0x20,3,0x20,3,0x20,3,0x20,3,0x20,3,0x20,3,0x20,3,0x20,3,0x20,3,0x20,3,0x20,3,1,3,1,3,1,3,1,3,1,3,1,3,1,3,1,3,1,3,1,3,1,3,1,3,1,3,1,3,1,3,1,3,0x11,3,0x11,3,0x11,3,0x11,3,0x11,3,0x11,3,0x11,3,0x11,3,0x11,3,0x11,3,0x11,3,0x11,3,0x11,3,0x11,3,0x11,3,0x11,3];
function TIFFMOTOLONG(p,ix){let val=0;if(ix<p.length)val|=p[ix]<<24;if(ix+1<p.length)val|=p[ix+1]<<16;if(ix+2<p.length)val|=p[ix+2]<<8;if(ix+3<p.length)val|=p[ix+3];return val>>>0}
class G5DECIMAGE{constructor(){this.iWidth=0;this.iHeight=0;this.iError=0;this.y=0;this.iVLCSize=0;this.iHLen=0;this.iPitch=0;this.u32Accum=0;this.ulBitOff=0;this.ulBits=0;this.pSrc=null;this.pBuf=null;this.pBufIndex=0;this.pCur=new Int16Array(MAX_IMAGE_FLIPS);this.pRef=new Int16Array(MAX_IMAGE_FLIPS)}}
function g5_decode_init(pImage,iWidth,iHeight,pData,iDataSize){if(!pImage||iWidth<1||iHeight<1||!pData||iDataSize<1)return G5_INVALID_PARAMETER;pImage.iVLCSize=iDataSize;pImage.pSrc=pData;pImage.ulBitOff=0;pImage.y=0;pImage.ulBits=TIFFMOTOLONG(pData,0);pImage.iWidth=iWidth;pImage.iHeight=iHeight;return G5_SUCCESS}
function G5DrawLine(pPage,pCurFlips,pOut){const xright=pPage.iWidth;let pCurIndex=0;const len=(xright+7)>>3;pOut.fill(255,0,len);let x=0;while(x<xright){const startX=pCurFlips[pCurIndex++],run=pCurFlips[pCurIndex++]-startX;if(startX>=xright||run<=0)break;let visibleX=Math.max(0,startX),visibleRun=Math.min(xright,startX+run)-visibleX;if(visibleRun>0){const startByte=visibleX>>3,endByte=(visibleX+visibleRun-1)>>3,lBit=255<<8-(visibleX&7)&255,rBit=255>>(visibleX+visibleRun&7);if(endByte===startByte)pOut[startByte]&=lBit|rBit;else{pOut[startByte]&=lBit;for(let i=startByte+1;i<endByte;i++)pOut[i]=0;if(endByte>startByte)pOut[endByte]&=rBit}}x=startX+run}}
function Decode_Begin(pPage){const xsize=pPage.iWidth;for(let i=0;i<MAX_IMAGE_FLIPS-2;i++)pPage.pRef[i]=pPage.pCur[i]=xsize;pPage.pCur[MAX_IMAGE_FLIPS-2]=pPage.pRef[MAX_IMAGE_FLIPS-2]=32767;pPage.pCur[MAX_IMAGE_FLIPS-1]=pPage.pRef[MAX_IMAGE_FLIPS-1]=32767;pPage.pBuf=pPage.pSrc;pPage.pBufIndex=0;pPage.ulBits=TIFFMOTOLONG(pPage.pSrc,0);pPage.ulBitOff=0;pPage.iHLen=xsize>0?32-Math.clz32(xsize):0}
function DecodeLine(pPage){let a0=-1,a0_p,b1,pCurIndex=0,pRefIndex=0;const pCur=pPage.pCur,pRef=pPage.pRef;let ulBits=pPage.ulBits,ulBitOff=pPage.ulBitOff,pBufIndex=pPage.pBufIndex;const pBuf=pPage.pBuf,xsize=pPage.iWidth,u32HLen=pPage.iHLen,u32HMask=(1<<u32HLen)-1;let tot_run,tot_run1;while(a0<xsize){if(pBufIndex+(ulBitOff>>3)>=pPage.iVLCSize&&ulBitOff>REGISTER_WIDTH-8)return pPage.iError=G5_DECODE_ERROR;if(ulBitOff>REGISTER_WIDTH-8){pBufIndex+=ulBitOff>>3;ulBitOff&=7;ulBits=TIFFMOTOLONG(pBuf,pBufIndex)}if((ulBits<<ulBitOff&2147483648)!==0){a0=pRef[pRefIndex++];pCur[pCurIndex++]=a0;ulBitOff++}else{const lBits=ulBits>>(REGISTER_WIDTH-8-ulBitOff)&254,sCode=code_table[lBits];ulBitOff+=code_table[lBits+1];switch(sCode){case 1:case 2:case 3:a0=pRef[pRefIndex]-sCode;pCur[pCurIndex++]=a0;if(pRefIndex==0)pRefIndex+=2;pRefIndex--;while(a0>=pRef[pRefIndex])pRefIndex+=2;break;case 17:case 18:case 19:a0=pRef[pRefIndex++];b1=a0;a0+=sCode&7;if(b1!==xsize&&a0<xsize)while(a0>=pRef[pRefIndex])pRefIndex+=2;if(a0>xsize)a0=xsize;pCur[pCurIndex++]=a0;break;case 32:if(ulBitOff>REGISTER_WIDTH-16){pBufIndex+=ulBitOff>>3;ulBitOff&=7;ulBits=TIFFMOTOLONG(pBuf,pBufIndex)}a0_p=Math.max(0,a0);const lBitsH=ulBits>>(REGISTER_WIDTH-2-ulBitOff)&3;ulBitOff+=2;switch(lBitsH){case HORIZ_SHORT_SHORT:tot_run=ulBits>>(REGISTER_WIDTH-3-ulBitOff)&7;ulBitOff+=3;tot_run1=ulBits>>(REGISTER_WIDTH-3-ulBitOff)&7;ulBitOff+=3;break;case HORIZ_SHORT_LONG:tot_run=ulBits>>(REGISTER_WIDTH-3-ulBitOff)&7;ulBitOff+=3;tot_run1=ulBits>>(REGISTER_WIDTH-u32HLen-ulBitOff)&u32HMask;ulBitOff+=u32HLen;break;case HORIZ_LONG_SHORT:tot_run=ulBits>>(REGISTER_WIDTH-u32HLen-ulBitOff)&u32HMask;ulBitOff+=u32HLen;tot_run1=ulBits>>(REGISTER_WIDTH-3-ulBitOff)&7;ulBitOff+=3;break;case HORIZ_LONG_LONG:tot_run=ulBits>>(REGISTER_WIDTH-u32HLen-ulBitOff)&u32HMask;ulBitOff+=u32HLen;if(ulBitOff>REGISTER_WIDTH-u32HLen&&u32HLen>0){pBufIndex+=ulBitOff>>3;ulBitOff&=7;ulBits=TIFFMOTOLONG(pBuf,pBufIndex)}tot_run1=ulBits>>(REGISTER_WIDTH-u32HLen-ulBitOff)&u32HMask;ulBitOff+=u32HLen;break}a0=a0_p+tot_run;pCur[pCurIndex++]=a0;a0+=tot_run1;if(a0<xsize)while(a0>=pRef[pRefIndex])pRefIndex+=2;pCur[pCurIndex++]=a0;break;case 48:pRefIndex++;a0=pRef[pRefIndex++];break;default:return pPage.iError=G5_DECODE_ERROR}}}pCur[pCurIndex++]=xsize;pCur[pCurIndex++]=xsize;pPage.ulBits=ulBits;pPage.ulBitOff=ulBitOff;pPage.pBufIndex=pBufIndex;return pPage.iError}
function processG5(data,width,height){try{let decoder=new G5DECIMAGE,initResult=g5_decode_init(decoder,width,height,data,data.length);if(initResult!==G5_SUCCESS)throw new Error("G5 Init failed: "+initResult);Decode_Begin(decoder);let outputBuffer=new Uint8Array(height*((width+7)>>3));for(let y=0;y<height;y++){let lineBuffer=outputBuffer.subarray(y*((width+7)>>3),(y+1)*((width+7)>>3));decoder.y=y;let decodeResult=DecodeLine(decoder);if(decodeResult!==G5_SUCCESS)console.warn("G5 Decode error line "+y+": "+decoder.iError);G5DrawLine(decoder,decoder.pCur,lineBuffer);const temp=decoder.pRef;decoder.pRef=decoder.pCur;decoder.pCur=temp}return outputBuffer}catch(error){console.error("Error in processG5:",error.message);return new Uint8Array(0)}}
</script>
</head>
<body>
<div class="main-wrapper">
<div class="input-column">
<div class="container">
<h3>JSON Template Publisher</h3>
<p class="info-text">Use this form to push JSON templates to an E-Paper Tag. Ensure your JSON is valid. Check syntax at <a href="https://jsonlint.com/" target="_blank">jsonlint.com</a>.<br>
Documentation: <a href="https://github.com/OpenEPaperLink/OpenEPaperLink/wiki/Json-template" target="_blank">OpenEPaperLink JSON Template Wiki</a>
</p>
<form id="jsonUploadForm" method="POST" action="/jsonupload">
<div class="form-group flex-group">
<div>
<label for="macInput">MAC Address:</label>
<input type="text" id="macInput" name="mac" pattern="[0-9a-fA-F]{12,16}" title="12 or 16 Hex characters" required>
</div>
<button type="button" id="refreshTagDbBtn" title="Reload Tag Database from AP"></button>
</div>
<div class="form-group">
<label for="macSelect">Available Tags (grouped by type):</label>
<select id="macSelect" style="margin-bottom: 5px;"></select>
<button type="button" id="clearMacHistoryBtn" title="Clear locally stored MAC history">Clear History</button>
</div>
<div class="form-group">
<label for="jsonInput">JSON String:</label>
<textarea id="jsonInput" name="json">
[
{ "text": [5, 5, "Bahnschrift 20", "fonts/bahnschrift20", 1] },
{ "box": [10, 30, 20, 20, 2] }
]
</textarea>
</div>
<div class="form-group">
<input type="submit" value="Upload JSON & Generate Preview">
</div>
</form>
</div>
</div>
<div class="preview-column">
<div class="container">
<div id="globalStatus" class="status-message" style="display:none;"></div>
<div id="previewArea" style="display:none;">
<h4>Image Preview</h4>
<canvas id="previewCanvas"></canvas>
<p id="previewStatus" class="status-message" style="display:none;"></p>
</div>
</div>
</div>
</div>
<script>
const ge=id=>document.getElementById(id);
const macInputEl=ge('macInput'),macSelectEl=ge('macSelect'),jsonInputEl=ge('jsonInput'),previewAreaEl=ge('previewArea'),previewCanvasEl=ge('previewCanvas'),previewStatusEl=ge('previewStatus'),jsonUploadFormEl=ge('jsonUploadForm'),clearMacHistoryBtnEl=ge('clearMacHistoryBtn'),globalStatusEl=ge('globalStatus'),refreshTagDbBtnEl=ge('refreshTagDbBtn');
const MAX_HISTORY_ITEMS=10,BASE_SERVER_URL='';
let localTagDB={},localTagTypes={},currentPreviewMac=null,currentPreviewHwType=null,currentPreviewVersion=null,currentPreviewTagTypeDef=null;
let offscreenCanvas = document.createElement('canvas');
let offscreenCtx = offscreenCanvas.getContext('2d');
let socket;
if (typeof window.processZlib === 'undefined' && typeof pako !== 'undefined') {
window.processZlib = function(rawDataFromDotRawFile) {
try {
const EXTERNAL_HEADER_SIZE = 4;
if (rawDataFromDotRawFile.length <= EXTERNAL_HEADER_SIZE) {setStatus(previewStatusEl, `Zlib error: Raw data too short.`, 'error',true); return new Uint8ClampedArray(0);}
const zlibStream = rawDataFromDotRawFile.subarray(EXTERNAL_HEADER_SIZE);
const inflatedBuffer = pako.inflate(zlibStream);
if (!inflatedBuffer || inflatedBuffer.length === 0) {setStatus(previewStatusEl, 'Zlib error: Inflation resulted in empty data.', 'error',true); return new Uint8ClampedArray(0);}
const internalHeaderSize = inflatedBuffer[0];
if (internalHeaderSize >= 0 && inflatedBuffer.length > internalHeaderSize) {return inflatedBuffer.subarray(internalHeaderSize);}
else if (internalHeaderSize === 0) {return inflatedBuffer;}
else {console.warn("Zlib: Unusual internal header. Length:", inflatedBuffer.length, "Header byte:", internalHeaderSize); return inflatedBuffer;}
} catch (err) {
let msg = (err && err.message) ? err.message : (typeof err === 'string' ? err : 'Unknown Zlib error');
console.error('pako.inflate error:', err); setStatus(previewStatusEl, `Zlib error: ${msg}`, 'error',true); return new Uint8ClampedArray(0);
}
};
} else if (typeof window.processZlib === 'undefined') {
window.processZlib = function(data) {setStatus(previewStatusEl, "Zlib (pako) not loaded.",'warning',true); return data;};
}
function setStatus(element, message, type = 'info', append = false) {
element.classList.remove('error-message', 'success-message', 'warning-message', 'info-message');
element.classList.add(`${type}-message`, 'info-message');
if (append) {
let currentBaseHTML = element.innerHTML.split("<br>")[0];
element.innerHTML = `${currentBaseHTML}<br>${message}`;
} else {
element.innerHTML = message;
}
element.style.display = message ? 'block' : 'none';
}
function connectWebSocket() {
const protocol = location.protocol === "https:" ? "wss://" : "ws://";
let basePath = location.pathname;
if (basePath.includes('.')) { basePath = basePath.substring(0, basePath.lastIndexOf('/'));}
if (!basePath.endsWith('/')) { basePath += '/';}
if (basePath === '//') basePath = '/';
const wsUrl = `${protocol}${location.host}${basePath}ws`;
socket = new WebSocket(wsUrl);
socket.onopen = () => { console.log("WebSocket connected."); setStatus(globalStatusEl, "WebSocket connected.", 'success');};
socket.onmessage = event => {
try {
const msg = JSON.parse(event.data);
if (msg.logMsg && typeof msg.logMsg === 'string') {
const log = msg.logMsg;
if (log.startsWith("Updating ") && log.length === ("Updating ".length + 16) ) {
const macFromMsg = log.substring("Updating ".length).toUpperCase();
if (macFromMsg === currentPreviewMac) {
setStatus(previewStatusEl, `Server is updating tag ${macFromMsg}. Waiting for .pending file notification...`, 'info', false);
}
} else if (log.startsWith("new image: /current/") && log.endsWith(".pending")) {
const pendingFileWithPath = log.substring("new image: ".length);
const pendingFilename = pendingFileWithPath.substring(pendingFileWithPath.lastIndexOf('/') + 1);
const macInFilename = pendingFilename.substring(0, pendingFilename.indexOf('_'));
if (macInFilename.toUpperCase() === currentPreviewMac && currentPreviewTagTypeDef) {
console.log(`.pending file reported for ${currentPreviewMac}: ${pendingFilename}`);
const pendingImagePath = `${BASE_SERVER_URL}/current/${pendingFilename}`;
setStatus(previewStatusEl, `Loading pending image: ${pendingFilename}...`, 'info', false);
loadAndRenderImage(pendingImagePath, currentPreviewMac, currentPreviewHwType, currentPreviewVersion, currentPreviewTagTypeDef);
}
} else if (log === "new image is the same as current image. not updating tag.") {
if (currentPreviewMac && currentPreviewTagTypeDef) {
console.log("Image is the same. Loading .raw for " + currentPreviewMac);
setStatus(previewStatusEl, `Image is same as current. Loading existing .raw file for ${currentPreviewMac}...`, 'info', false);
const tagData = localTagDB[currentPreviewMac];
if (tagData) {
const cacheTag = tagData.hash !== '00000000000000000000000000000000' ? tagData.hash : Date.now();
let imagePath = '';
if(tagData.isexternal && tagData.apip && tagData.apip !== '0.0.0.0'){imagePath = `http://${tagData.apip}/current/${currentPreviewMac}.raw?${cacheTag}`}
else{imagePath = `${BASE_SERVER_URL}/current/${currentPreviewMac}.raw?${cacheTag}`}
loadAndRenderImage(imagePath, currentPreviewMac, currentPreviewHwType, currentPreviewVersion, currentPreviewTagTypeDef);
} else {
setStatus(previewStatusEl, `Cannot load .raw for ${currentPreviewMac}: Tag data not found.`, 'error', false);
}
}
}
}
} catch (e) { console.error("Error processing WebSocket message:", e, event.data); }
};
socket.onclose = event => { console.log("WebSocket disconnected. Code:", event.code); setStatus(globalStatusEl, "WebSocket disconnected. Reconnecting in 5s...", 'warning'); setTimeout(connectWebSocket, 5000);};
socket.onerror = error => { console.error("WebSocket error:", error); setStatus(globalStatusEl, "WebSocket connection error.", 'error');};
}
async function fetchTagDB(pos=0){if(pos===0)localTagDB={};setStatus(globalStatusEl,'Loading Tag Database...','info');try{const response=await fetch(`${BASE_SERVER_URL}/get_db?pos=${pos}`);if(!response.ok)throw new Error(`Failed to load Tag DB: ${response.status}`);const data=await response.json();(data.tags||[]).forEach(tag=>{localTagDB[tag.mac.toUpperCase()]={hwType:tag.hwType,ver:tag.ver,alias:tag.alias,hash:tag.hash,isexternal:tag.isexternal||false,apip:tag.apip||'0.0.0.0'}});if(data.continu&&data.continu>pos){await fetchTagDB(data.continu)}else{setStatus(globalStatusEl,`Tag DB loaded. ${Object.keys(localTagDB).length} tags. Refreshing types...`,'success');await refreshTagTypeDefinitionsForDropdown();populateMacDropdown()}}catch(error){console.error("Error fetchTagDB:",error);setStatus(globalStatusEl,`Error Tag DB: ${error.message}`,'error')}}
async function getTagTypeDefinition(hwType){if(localTagTypes[hwType]&&!localTagTypes[hwType].busy)return localTagTypes[hwType];if(localTagTypes[hwType]?.busy){await new Promise(resolve=>{const interval=setInterval(()=>{if(!localTagTypes[hwType]?.busy){clearInterval(interval);resolve(localTagTypes[hwType])}},100)});return localTagTypes[hwType]}localTagTypes[hwType]={busy:true};try{let response;try{response=await fetch(`${BASE_SERVER_URL}/tagtypes/${Number(hwType).toString(16).padStart(2,'0').toUpperCase()}.json`)}catch(e){}if(!response||!response.ok){const repo='OpenEPaperLink/OpenEPaperLink',ghUrl=`https://raw.githubusercontent.com/${repo}/master/resources/tagtypes/${Number(hwType).toString(16).padStart(2,'0').toUpperCase()}.json`;response=await fetch(ghUrl)}if(!response.ok)throw new Error(`Def for ${hwType} not found (Status: ${response.status})`);const jsonData=await response.json();const definition={name:jsonData.name,width:parseInt(jsonData.width),height:parseInt(jsonData.height),bpp:parseInt(jsonData.bpp),rotatebuffer:jsonData.rotatebuffer||0,colortable:Object.values(jsonData.perceptual??jsonData.colortable??[]),zlib:parseInt(jsonData.zlib_compression||"0",16),g5:parseInt(jsonData.g5_compression||"0",16),busy:false};localTagTypes[hwType]=definition;localStorage.setItem("localTagTypesCache",JSON.stringify(localTagTypes));return definition}catch(error){console.error(`Error getTagTypeDef ${hwType}:`,error);localTagTypes[hwType]={busy:false,name:`Unknown (${hwType})`,width:0,height:0,bpp:0,colortable:[]};return localTagTypes[hwType]}}
function loadCachedTagTypeDefinitions(){try{const cached=localStorage.getItem("localTagTypesCache");if(cached)localTagTypes=JSON.parse(cached)}catch(e){console.warn("Error loading Tag Type Defs from cache:",e)}}
async function refreshTagTypeDefinitionsForDropdown(){const hwTypesInDb=new Set(Object.values(localTagDB).map(tag=>tag.hwType));for(const hwType of hwTypesInDb){if(!localTagTypes[hwType]||localTagTypes[hwType].name?.startsWith("Unknown")){await getTagTypeDefinition(hwType)}}}
function populateMacDropdown(){macSelectEl.innerHTML='<option value="">Select a Tag...</option>';const groupedByHwType={};for(const mac in localTagDB){const tag=localTagDB[mac];if(!groupedByHwType[tag.hwType])groupedByHwType[tag.hwType]=[];groupedByHwType[tag.hwType].push({mac,alias:tag.alias})}const sortedHwTypes=Object.keys(groupedByHwType).sort((a,b)=>{const nameA=localTagTypes[a]?.name||`Type ${a}`;const nameB=localTagTypes[b]?.name||`Type ${b}`;return nameA.localeCompare(nameB)});for(const hwType of sortedHwTypes){const group=document.createElement('optgroup');const typeDef=localTagTypes[hwType];group.label=typeDef?.name?`${typeDef.name} (${typeDef.width}x${typeDef.height}, Type ${hwType})`:`Type ${hwType}`;groupedByHwType[hwType].sort((a,b)=>(a.alias||a.mac).localeCompare(b.alias||b.mac));groupedByHwType[hwType].forEach(tag=>{const option=document.createElement('option');option.value=tag.mac;option.textContent=tag.alias?`${tag.alias} (${tag.mac})`:tag.mac;group.appendChild(option)});macSelectEl.appendChild(group)}}
function saveToMacHistory(mac){if(!mac||!/^[0-9a-fA-F]{12,16}$/.test(mac))return;let history=JSON.parse(localStorage.getItem('macStorageHistory'))||[];const upperMac=mac.toUpperCase();history=history.filter(item=>item.toUpperCase()!==upperMac);history.unshift(upperMac);if(history.length>MAX_HISTORY_ITEMS)history=history.slice(0,MAX_HISTORY_ITEMS);localStorage.setItem('macStorageHistory',JSON.stringify(history))}
macSelectEl.addEventListener('change',()=>{if(macSelectEl.value){macInputEl.value=macSelectEl.value;const tagInfo=localTagDB[macSelectEl.value.toUpperCase()];if(tagInfo)setStatus(globalStatusEl,`Selected: ${tagInfo.alias||macSelectEl.value}, HW: ${tagInfo.hwType}, FW: ${tagInfo.ver}`,'info')}});
macInputEl.addEventListener('change',()=>{const mac=macInputEl.value.toUpperCase();const tagInfo=localTagDB[mac];if(tagInfo)setStatus(globalStatusEl,`Tag: ${tagInfo.alias||mac}, HW: ${tagInfo.hwType}, FW: ${tagInfo.ver}`,'info');else if(mac.length===12||mac.length===16)setStatus(globalStatusEl,`Details for ${mac} not in local DB.`,'warning');else setStatus(globalStatusEl,'','info');macSelectEl.value=mac});
clearMacHistoryBtnEl.addEventListener('click',()=>{if(confirm("Clear MAC history from browser storage?")){localStorage.removeItem('macStorageHistory');macInputEl.value='';setStatus(globalStatusEl,'Local MAC history cleared.','info')}});
function loadLastMacUsed(){const lastMac=localStorage.getItem('lastMacUsed');if(lastMac)macInputEl.value=lastMac}
function saveLastMacUsed(mac){if(mac&&/^[0-9a-fA-F]{12,16}$/.test(mac)){localStorage.setItem('lastMacUsed',mac.toUpperCase());saveToMacHistory(mac.toUpperCase())}}
jsonUploadFormEl.addEventListener('submit',async event=>{event.preventDefault();const mac=macInputEl.value.trim().toUpperCase();if(!mac||!/^[0-9a-fA-F]{12,16}$/.test(mac)){alert("Please enter a valid MAC address.");return}saveLastMacUsed(mac);let tagInfo=localTagDB[mac];if(!tagInfo){setStatus(globalStatusEl,`Info for MAC ${mac} not in local DB. Reloading...`,'warning');await fetchTagDB();tagInfo=localTagDB[mac];if(!tagInfo){setStatus(previewStatusEl,`Could not load hardware info for MAC ${mac}.`,'error',false);previewAreaEl.style.display='block';previewCanvasEl.style.display='none';return}}currentPreviewMac=mac;currentPreviewHwType=tagInfo.hwType;currentPreviewVersion=tagInfo.ver;currentPreviewTagTypeDef=await getTagTypeDefinition(currentPreviewHwType);if(!currentPreviewTagTypeDef||currentPreviewTagTypeDef.width===0){setStatus(previewStatusEl,`Could not load Tag Type Definition for hwType ${currentPreviewHwType}.`,'error',false);previewAreaEl.style.display='block';previewCanvasEl.style.display='none';return}previewAreaEl.style.display='block';setStatus(previewStatusEl,'Sending JSON... Waiting for image update status via WebSocket...','info',false);previewCanvasEl.style.display='none';if(offscreenCanvas)offscreenCtx.clearRect(0,0,offscreenCanvas.width,offscreenCanvas.height);else{const ctx=previewCanvasEl.getContext('2d');if(ctx)ctx.clearRect(0,0,previewCanvasEl.width,previewCanvasEl.height)}try{const formData=new FormData(jsonUploadFormEl);formData.set('mac',mac);const response=await fetch(jsonUploadFormEl.action,{method:'POST',body:formData});if(!response.ok){const errorText=await response.text();throw new Error(`JSON Upload Error: ${response.status} ${errorText}`)}setStatus(previewStatusEl,'JSON sent. Waiting for image update notification via WebSocket...','success', false);
}catch(error){console.error("Error JSON submission:",error);setStatus(previewStatusEl,`Error: ${error.message}`,'error',false);}});
refreshTagDbBtnEl.addEventListener('click',()=>fetchTagDB());
async function loadAndRenderImage(path,mac,hwType,ver,tagTypeDef){
setStatus(previewStatusEl,`Loading image: ${path.substring(path.lastIndexOf('/')+1)}...`,'info', false);
if(!tagTypeDef||tagTypeDef.width===0){setStatus(previewStatusEl,`Error: Tag Type Def for hwType '${hwType}' invalid.`,'error', false);return false}
let offscreenDrawWidth = tagTypeDef.width; let offscreenDrawHeight = tagTypeDef.height;
const rotateBuffer = tagTypeDef.rotatebuffer || 0;
if (rotateBuffer % 2 !== 0) {[offscreenDrawWidth, offscreenDrawHeight] = [tagTypeDef.height, tagTypeDef.width];}
if (offscreenCanvas.width !== offscreenDrawWidth || offscreenCanvas.height !== offscreenDrawHeight) {
offscreenCanvas.width = offscreenDrawWidth; offscreenCanvas.height = offscreenDrawHeight;
}
offscreenCtx.clearRect(0, 0, offscreenCanvas.width, offscreenCanvas.height);
try{const response=await fetch(path);
if(!response.ok){throw new Error(`Image not found or server error: ${response.status} on ${path}`);}
const buffer=await response.arrayBuffer();let data=new Uint8ClampedArray(buffer);
if(data.length===0){setStatus(previewStatusEl,"Received image data empty.",'error', true);previewCanvasEl.style.display='none';return false}
let originalDataLength = data.length;
if(tagTypeDef.zlib>0&&ver>=tagTypeDef.zlib){
let decompressedZlib = window.processZlib(new Uint8Array(data.buffer, data.byteOffset, data.byteLength));
if (decompressedZlib && decompressedZlib.length > 0 && decompressedZlib.length !== originalDataLength) {
data = new Uint8ClampedArray(decompressedZlib.buffer, decompressedZlib.byteOffset, decompressedZlib.byteLength);
} else if (decompressedZlib && decompressedZlib.length === originalDataLength && originalDataLength > 0) {
} else { setStatus(previewStatusEl,"Zlib error: Empty result.",'error', true); return false; }
}
originalDataLength = data.length;
if(data.length>0&&tagTypeDef.g5>0&&ver>=tagTypeDef.g5){
const headerSize=data[0];
if (data.length > headerSize) {
let bufw=(data[2]<<8)|data[1],bufh=(data[4]<<8)|data[3];
if((bufw==tagTypeDef.width||bufw==tagTypeDef.height)&&(bufh==tagTypeDef.width||bufh==tagTypeDef.height)&&(data[5]<=3)){
if(data[5]==2)bufh*=2; let g5Stream = data.subarray(headerSize);
let decompressedG5 = window.processG5(g5Stream, bufw, bufh);
if (decompressedG5 && decompressedG5.length > 0 && decompressedG5.length !== originalDataLength) {
data = new Uint8ClampedArray(decompressedG5.buffer, decompressedG5.byteOffset, decompressedG5.byteLength);
} else if (decompressedG5 && decompressedG5.length === originalDataLength && originalDataLength > 0) {
} else { setStatus(previewStatusEl,"G5 error: Empty result.",'error', true); return false; }
} else { }
} else { }
}
if(data.length===0){setStatus(previewStatusEl,"Image data empty post-decompression.",'error', true);previewCanvasEl.style.display='none';return false}
const offscreenImageData = offscreenCtx.createImageData(offscreenCanvas.width, offscreenCanvas.height);
const bpp=tagTypeDef.bpp,colorTable=tagTypeDef.colortable;
if(!colorTable||colorTable.length===0){setStatus(previewStatusEl,`Error: No color table for hwType ${hwType}.`,'error', true);return false}
if(bpp==16){const is16Bit=data.length===offscreenCanvas.width*offscreenCanvas.height*2;for(let i=0;i<Math.min(offscreenCanvas.width*offscreenCanvas.height,data.length/(is16Bit?2:1));i++){const dIdx=is16Bit?i*2:i,rgb=is16Bit?(data[dIdx]<<8)|data[dIdx+1]:data[dIdx];offscreenImageData.data[i*4]=is16Bit?((rgb>>11)&31)<<3:(((rgb>>5)&7)<<5)*1.13;offscreenImageData.data[i*4+1]=is16Bit?((rgb>>5)&63)<<2:(((rgb>>2)&7)<<5)*1.13;offscreenImageData.data[i*4+2]=is16Bit?(rgb&31)<<3:((rgb&3)<<6)*1.3;offscreenImageData.data[i*4+3]=255}}
else if([3,4].includes(bpp)){let pxIdx=0,bitOff=0,totalPx=offscreenCanvas.width*offscreenCanvas.height;while(bitOff<data.length*8&&pxIdx<totalPx){let byteIdx=bitOff>>3,startBit=bitOff&7,pxVal=0;if(startBit+bpp<=8)pxVal=(data[byteIdx]>>(8-startBit-bpp))&((1<<bpp)-1);else{let bitsFirst=8-startBit;pxVal=(data[byteIdx]&((1<<bitsFirst)-1))<<(bpp-bitsFirst);if(byteIdx+1<data.length)pxVal|=data[byteIdx+1]>>(8-(bpp-bitsFirst))}if(pxVal<colorTable.length){let c=colorTable[pxVal];offscreenImageData.data[pxIdx*4]=c[0];offscreenImageData.data[pxIdx*4+1]=c[1];offscreenImageData.data[pxIdx*4+2]=c[2];offscreenImageData.data[pxIdx*4+3]=255}else{offscreenImageData.data[pxIdx*4]=255;offscreenImageData.data[pxIdx*4+1]=0;offscreenImageData.data[pxIdx*4+2]=0;offscreenImageData.data[pxIdx*4+3]=255}pxIdx++;bitOff+=bpp}}
else{const offsetR=(bpp>=2&&data.length>=(offscreenCanvas.width*offscreenCanvas.height/8)*2)?offscreenCanvas.width*offscreenCanvas.height/8:0;let pxVal=0,totalPx=offscreenCanvas.width*offscreenCanvas.height,currPxIdx=0;let bytesIter=offsetR?offsetR:Math.ceil(totalPx/8);for(let i=0;i<bytesIter&&i<data.length;i++){for(let j=0;j<8;j++){if(currPxIdx>=totalPx)break;if(offsetR&&(i+offsetR>=data.length))pxVal=(data[i]&(1<<(7-j)))?1:0;else if(offsetR)pxVal=((data[i]&(1<<(7-j)))?1:0)|(((data[i+offsetR]&(1<<(7-j)))?1:0)<<1);else pxVal=(data[i]&(1<<(7-j)))?1:0;if(pxVal<colorTable.length){offscreenImageData.data[currPxIdx*4]=colorTable[pxVal][0];offscreenImageData.data[currPxIdx*4+1]=colorTable[pxVal][1];offscreenImageData.data[currPxIdx*4+2]=colorTable[pxVal][2];offscreenImageData.data[currPxIdx*4+3]=255}else{offscreenImageData.data[currPxIdx*4]=0;offscreenImageData.data[currPxIdx*4+1]=255;offscreenImageData.data[currPxIdx*4+2]=0;offscreenImageData.data[currPxIdx*4+3]=255}currPxIdx++}if(currPxIdx>=totalPx)break}}
offscreenCtx.putImageData(offscreenImageData,0,0);
previewCanvasEl.width = offscreenCanvas.width;
previewCanvasEl.height = offscreenCanvas.height;
previewCanvasEl.style.transform = (rotateBuffer >= 2) ? 'rotate(180deg)' : 'none';
const visibleCtx=previewCanvasEl.getContext('2d');
visibleCtx.drawImage(offscreenCanvas,0,0);
previewCanvasEl.style.display='block';
setStatus(previewStatusEl,`Image ${path.substring(path.lastIndexOf('/')+1)} rendered.`,'success', true);
return true;
}catch(error){
console.error("Error loading/rendering image:",error);
setStatus(previewStatusEl,`Error loading ${path.substring(path.lastIndexOf('/')+1)}: ${error.message}`,'error', true);
previewCanvasEl.style.display='none';
return false;
}
}
document.addEventListener('DOMContentLoaded',async()=>{loadCachedTagTypeDefinitions();await fetchTagDB();loadLastMacUsed(); connectWebSocket();});
</script>
</body>
</html>

View File

@@ -1,3 +1,112 @@
/* CSS Variables for Theming */
:root {
--color-background: #e4e4e0;
--color-text: #000000;
--color-module-bg: #ffffff;
--color-text-light: #444;
--color-text-error: red;
--color-header-bg: #646260;
--color-header-text: #ffffff;
--color-nav-bg: #ffffff;
--color-tab-bg: #f2f2f2;
--color-tab-hover-bg: #ddd;
--color-tab-active-bg: #ccc;
--color-tab-border: #ccc;
--color-card-bg: #ffffff;
--color-card-border: #cccccc;
--color-card-hover-shadow: rgba(0, 0, 0, 0.63);
--color-dialog-bg: #f0e6d3;
--color-button-bg: #ccc;
--color-button-text: black;
--color-button-hover-bg: #aaaaaa;
--color-input-bg: #ffffff;
--color-input-text: #000000;
--color-input-border: #cccccc;
--color-console-bg: black;
--color-console-text: white;
--color-console-mono-bg: #666;
--color-console-mono-text: #ccc;
--color-console-quote-text: white;
--color-tag-pending-anim-bg: #d4d4f5;
--color-tag-group-bg: #6d6e6e;
--color-tag-group-text: white;
--color-tag-group-border: #c0c0c0;
--color-context-menu-bg: white;
--color-context-menu-border: gray;
--color-context-menu-hover-bg: #e0e0e0;
--color-link: #0000ee;
--color-readonly-bg: #ccc;
--color-tag-deepsleep-bg: #e4e4e0;
--color-tag-boot-bg: #b0d0b0;
--color-tag-wakeup-bg: #c8f1bb;
--color-tag-scan-bg: #c0c0d0;
--color-tag-reset-bg: #d0a0a0;
--color-tag-failed-ota-bg: #f0a0a0;
--color-tag-timeout-bg: #e0e0a0;
--color-log-new-bg-start: rgba(255, 255, 204, 1);
--color-log-new-bg-mid: rgba(255, 255, 204, 0.5);
--color-log-new-bg-end: rgba(255, 255, 204, 0);
}
body.dark-mode {
--color-background: #1c1c1e;
--color-text: #f0f0f0;
--color-module-bg: #3a3a3c;
--color-text-light: #cccccc;
--color-text-error: #ff8a8a;
--color-header-bg: #2a2a2d;
--color-header-text: #f0f0f0;
--color-nav-bg: #1f1f22;
--color-tab-bg: #3a3a3c;
--color-tab-hover-bg: #4a4a4c;
--color-tab-active-bg: #5a5a5c;
--color-tab-border: #5a5a5c;
--color-card-bg: #2c2c2e;
--color-card-border: #444444;
--color-card-hover-shadow: rgba(255, 255, 255, 0.2);
--color-dialog-bg: #3a3a3c;
--color-button-bg: #5a5a5c;
--color-button-text: #f0f0f0;
--color-button-hover-bg: #6a6a6c;
--color-input-bg: #3a3a3c;
--color-input-text: #f0f0f0;
--color-input-border: #555555;
--color-console-bg: #3a3a3c;
--color-console-text: #f0f0f0;
--color-console-mono-bg: #444;
--color-console-mono-text: #ddd;
--color-console-quote-text: #ffffff;
--color-tag-pending-anim-bg: #3c3c5c;
--color-tag-group-bg: #4a4a4c;
--color-tag-group-text: #f0f0f0;
--color-tag-group-border: #555555;
--color-context-menu-bg: #2c2c2e;
--color-context-menu-border: #555;
--color-context-menu-hover-bg: #4a4a4c;
--color-link: #58a6ff;
--color-readonly-bg: #4a4a4c;
--color-tag-deepsleep-bg: #3a3a3c;
--color-tag-boot-bg: #3a5c3a;
--color-tag-wakeup-bg: #4a6c4a;
--color-tag-scan-bg: #4c4c5c;
--color-tag-reset-bg: #6c4c4c;
--color-tag-failed-ota-bg: #7c4c4c;
--color-tag-timeout-bg: #6c6c4c;
--color-log-new-bg-start: rgba(88, 166, 255, 0.3);
--color-log-new-bg-mid: rgba(88, 166, 255, 0.15);
--color-log-new-bg-end: rgba(88, 166, 255, 0);
}
/* Tag State Classes */
.tagcard.state-deepsleep { background-color: var(--color-tag-deepsleep-bg); }
.tagcard.state-boot { background-color: var(--color-tag-boot-bg); }
.tagcard.state-wakeup { background-color: var(--color-tag-wakeup-bg); }
.tagcard.state-scan { background-color: var(--color-tag-scan-bg); }
.tagcard.state-reset { background-color: var(--color-tag-reset-bg); }
.tagcard.state-failed-ota { background-color: var(--color-tag-failed-ota-bg); }
.tagcard.state-timeout { background-color: var(--color-tag-timeout-bg); }
* { * {
margin: 0; margin: 0;
padding: 0; padding: 0;
@@ -16,11 +125,12 @@ body {
font-size: 12px; font-size: 12px;
font-family: Helvetica, Arial, Verdana, sans-serif; font-family: Helvetica, Arial, Verdana, sans-serif;
line-height: 1.5; line-height: 1.5;
background-color: #e4e4e0; background-color: var(--color-background);
color: var(--color-text);
} }
header { header {
background-color: #646260; background-color: var(--color-header-bg);
z-index: 999; z-index: 999;
position: sticky; position: sticky;
top: 0px; top: 0px;
@@ -35,7 +145,7 @@ nav>div {
display: flex; display: flex;
gap: 20px; gap: 20px;
padding: 10px; padding: 10px;
background-color: white; background-color: var(--color-nav-bg);
} }
nav label { nav label {
@@ -50,11 +160,13 @@ footer {
position: fixed; position: fixed;
bottom: 0; bottom: 0;
width: 100%; width: 100%;
background-color: white; background-color: var(--color-nav-bg);
border-top: 1px solid var(--color-card-border);
color: var(--color-text);
}
#sysinfo { footer #sysinfo {
float: right; float: right;
}
} }
.logo { .logo {
@@ -63,12 +175,13 @@ footer {
text-indent: 12px; text-indent: 12px;
overflow: hidden; overflow: hidden;
font-size: 2.5em; font-size: 2.5em;
color: white; color: var(--color-header-text);
} }
h3 { h3 {
padding-bottom: 10px; padding-bottom: 10px;
font-size: 1.5em; font-size: 1.5em;
color: var(--color-text);
} }
/* tabs */ /* tabs */
@@ -79,7 +192,8 @@ h3 {
} }
.tablinks { .tablinks {
background-color: #f2f2f2; background-color: var(--color-tab-bg);
color: var(--color-text);
padding: 5px 10px; padding: 5px 10px;
border: none; border: none;
cursor: pointer; cursor: pointer;
@@ -87,12 +201,12 @@ h3 {
transition: all 0.2s ease-in-out; transition: all 0.2s ease-in-out;
&:hover { &:hover {
background-color: #ddd; background-color: var(--color-tab-hover-bg);
} }
} }
.tab-container .active { .tab-container .active {
background-color: #ccc; background-color: var(--color-tab-active-bg);
margin-top: 10px; margin-top: 10px;
margin-bottom: -10px; margin-bottom: -10px;
padding-bottom: 0px; padding-bottom: 0px;
@@ -100,7 +214,7 @@ h3 {
.tabcontent { .tabcontent {
display: none; display: none;
border-top: 1px solid #ccc; border-top: 1px solid var(--color-tab-border);
} }
@@ -109,11 +223,11 @@ label {
display: inline-block; display: inline-block;
vertical-align: top; vertical-align: top;
padding: 4px 20px; padding: 4px 20px;
color: var(--color-text);
} }
.container { .container {
padding-bottom: 20px; padding-bottom: 20px;
;
} }
#hometab { #hometab {
@@ -121,9 +235,10 @@ label {
& table { & table {
margin: 20px; margin: 20px;
background: #fff; background: var(--color-card-bg);
padding: 5px 20px; padding: 5px 20px;
border-spacing: 0px; border-spacing: 0px;
color: var(--color-text);
} }
& td { & td {
@@ -136,7 +251,7 @@ label {
} }
& tr:hover { & tr:hover {
background-color: #ccc; background-color: var(--color-tab-active-bg);
cursor: pointer; cursor: pointer;
} }
@@ -167,14 +282,14 @@ label {
} }
.tabheader { .tabheader {
background-color: white; background-color: var(--color-nav-bg);
padding: 5px 10px; padding: 5px 10px;
display: flex; display: flex;
gap: 2em; gap: 2em;
} }
#filterOptions { #filterOptions {
background-color: white; background-color: var(--color-nav-bg);
max-height: 0; max-height: 0;
padding: 0px 10px; padding: 0px 10px;
overflow: hidden; overflow: hidden;
@@ -205,6 +320,9 @@ label {
& p { & p {
padding: 3px; padding: 3px;
} }
& a:not(#downloadDBbutton):not(.wifibutton) {
color: var(--color-link);
}
} }
#updatetab, #flashtab { #updatetab, #flashtab {
@@ -226,7 +344,7 @@ label {
margin: 0px 5px; margin: 0px 5px;
} }
& input:read-only { & input:read-only {
background-color: #ccc; background-color: var(--color-readonly-bg);
} }
& .warning { & .warning {
padding: 5px; padding: 5px;
@@ -243,10 +361,15 @@ label {
} }
.apcard { .apcard {
background-color: #fff; background-color: var(--color-card-bg);
border: 1px solid #ccc; border: 1px solid var(--color-card-border);
padding: 10px; padding: 10px;
width: 300px; width: 300px;
color: var(--color-text);
& .apip a {
color: var(--color-link);
}
& .apalias { & .apalias {
font-size: 1.5em; font-size: 1.5em;
@@ -278,15 +401,15 @@ label {
padding: 5px 10px; padding: 5px 10px;
margin-bottom: 0px; margin-bottom: 0px;
margin-top: -1px; margin-top: -1px;
background-color: #ccc; background-color: var(--color-button-bg);
text-decoration: none; text-decoration: none;
color: black; color: var(--color-button-text);
cursor: pointer; cursor: pointer;
white-space: nowrap; white-space: nowrap;
text-align: center; text-align: center;
&:hover { &:hover {
background-color: #aaa; background-color: var(--color-button-hover-bg);
} }
} }
@@ -296,18 +419,19 @@ label {
#uploadButton, #uploadButton,
.wifibutton { .wifibutton {
padding: 4px 5px; padding: 4px 5px;
background-color: #ccc; background-color: var(--color-button-bg);
text-decoration: none; text-decoration: none;
color: black; color: var(--color-button-text);
cursor: pointer; cursor: pointer;
white-space: nowrap; white-space: nowrap;
width: 120px; width: 120px;
margin: 2px 5px 2px 20px; margin: 2px 5px 2px 20px;
display: inline-block; display: inline-block;
text-align: center; text-align: center;
transition: none;
&:hover { &:hover {
background-color: #aaa; background-color: var(--color-button-hover-bg);
} }
} }
@@ -327,10 +451,13 @@ input[type="submit"],
button { button {
appearance: none; appearance: none;
border-radius: 0; border-radius: 0;
color: var(--color-input-text);
} }
input { input, textarea, select {
border: solid 1px #cccccc; border: solid 1px var(--color-input-border);
background-color: var(--color-input-bg);
color: var(--color-input-text);
padding: 4px; padding: 4px;
border-radius: 0px; border-radius: 0px;
} }
@@ -340,18 +467,21 @@ button {
border: 0px; border: 0px;
padding: 4px 10px; padding: 4px 10px;
cursor: pointer; cursor: pointer;
background-color: #ccc; background-color: var(--color-button-bg);
color: var(--color-button-text);
} }
input[type=button]:hover, input[type=button]:hover,
button:hover { button:hover {
background-color: #aaaaaa; background-color: var(--color-button-hover-bg);
} }
input[type=file] { input[type=file] {
padding: 0px; padding: 0px;
margin-left: 20px; margin-left: 20px;
width: 200px; width: 200px;
background: none;
border: none;
} }
input[type=checkbox] { input[type=checkbox] {
@@ -361,7 +491,6 @@ input[type=checkbox] {
select { select {
padding: 3px 4px; padding: 3px 4px;
border-radius: 0px; border-radius: 0px;
border: solid 1px #cccccc;
max-width: 180px; max-width: 180px;
} }
@@ -375,7 +504,7 @@ select {
padding: 15px; padding: 15px;
background-color: #f0e6d3; background-color: #f0e6d3;
z-index: 999; z-index: 999;
box-shadow: 7px 10px 52px -19px rgba(0, 0, 0, 0.63); box-shadow: 7px 10px 52px -19px var(--color-card-hover-shadow);
overflow: auto; overflow: auto;
max-height: calc(100vh - 75px); max-height: calc(100vh - 75px);
} }
@@ -384,11 +513,12 @@ select {
margin: auto; margin: auto;
min-width: 380px; min-width: 380px;
padding: 15px; padding: 15px;
background-color: #f0e6d3; background-color: var(--color-dialog-bg);
z-index: 999; z-index: 999;
box-shadow: 7px 10px 52px -19px rgba(0, 0, 0, 0.63); box-shadow: 7px 10px 52px -19px var(--color-card-hover-shadow);
overflow: auto; overflow: auto;
max-height: calc(100vh - 75px); max-height: calc(100vh - 75px);
color: var(--color-text);
& label { & label {
width: 150px; width: 150px;
@@ -414,7 +544,7 @@ select {
#configbox input, #configbox input,
#apconfigbox input { #apconfigbox input {
border: solid 1px #cccccc; border: solid 1px var(--color-input-border);
} }
#configbox input[type=number] { #configbox input[type=number] {
@@ -475,7 +605,7 @@ select {
.closebtn, .closebtn,
.closebtn2 { .closebtn2 {
border: 1px solid black; border: 1px solid var(--color-text);
float: right; float: right;
width: 19px; width: 19px;
height: 20px; height: 20px;
@@ -483,6 +613,7 @@ select {
text-align: center; text-align: center;
margin: 5px; margin: 5px;
cursor: pointer; cursor: pointer;
color: var(--color-text);
} }
#logtab { #logtab {
@@ -523,13 +654,14 @@ select {
min-height: 170px; min-height: 170px;
margin: 3px; margin: 3px;
padding: 4px 5px 5px 8px; padding: 4px 5px 5px 8px;
background-color: #ffffff; background-color: var(--color-card-bg);
border: 1px solid #cccccc; border: 1px solid var(--color-card-border);
transition: box-shadow 0.3s ease; transition: box-shadow 0.3s ease, background-color 0.3s ease;
color: var(--color-text);
&:hover { &:hover {
cursor: pointer; cursor: pointer;
box-shadow: 7px 10px 52px -19px rgba(0, 0, 0, 0.63); box-shadow: 7px 10px 52px -19px var(--color-card-hover-shadow);
filter: brightness(1.02); filter: brightness(1.02);
} }
} }
@@ -549,10 +681,10 @@ select {
} }
.taggroup { .taggroup {
border: 1px solid #c0c0c0; border: 1px solid var(--color-tag-group-border);
width: 100%; width: 100%;
background-color: #6d6e6e; background-color: var(--color-tag-group-bg);
color: white; color: var(--color-tag-group-text);
padding: 5px; padding: 5px;
margin: 0px 3px; margin: 0px 3px;
} }
@@ -564,7 +696,7 @@ select {
.currimg img, .currimg img,
.currimg canvas { .currimg canvas {
max-width: 50px; max-width: 50px;
border: 1px solid #c0c0c0; border: 1px solid var(--color-tag-group-border);
} }
.mac { .mac {
@@ -621,6 +753,15 @@ select {
display: inline-block; display: inline-block;
} }
.lastseen {
color: var(--color-text);
}
.lastseen.error {
color: var(--color-text-error);
}
.corner { .corner {
position: absolute; position: absolute;
right: 0px; right: 0px;
@@ -667,6 +808,7 @@ ul.messages {
ul.messages li { ul.messages li {
position: relative; position: relative;
color: var(--color-text);
} }
ul.messages li.new { ul.messages li.new {
@@ -677,40 +819,41 @@ ul.messages li.new {
} }
.error { .error {
color: red; color: var(--color-text-error);
} }
.mono { .mono {
font-family: monospace; font-family: monospace;
word-break: break-all; word-break: break-all;
background-color: #666; background-color: var(--color-console-mono-bg);
color: #ccc; color: var(--color-console-mono-text);
padding: 2px; padding: 2px;
} }
.quote { .quote {
color: white; color: var(--color-console-quote-text);
} }
#georesults { #georesults {
position: absolute; position: absolute;
background: white; background: var(--color-nav-bg);
cursor: pointer; cursor: pointer;
width: 240px; width: 240px;
max-height: 115px; max-height: 115px;
overflow-y: scroll; overflow-y: scroll;
padding: 0px 2px 0px 2px; padding: 0px 2px 0px 2px;
border: 1px solid var(--color-card-border);
& div { & div {
display:flex; display:flex;
} }
& div:hover { & div:hover {
background-color: #e0e0e0; background-color: var(--color-tab-hover-bg);
} }
} }
#paintbutton { #paintbutton {
padding: 1px 3px; padding: 1px 3px;
border: 1px solid black; border: 1px solid var(--color-text);
font-size: 1.3em; font-size: 1.3em;
vertical-align: top; vertical-align: top;
margin-left: 12px; margin-left: 12px;
@@ -719,7 +862,7 @@ ul.messages li.new {
} }
#paintbutton:hover { #paintbutton:hover {
background-color: #aaaaaa; background-color: var(--color-button-hover-bg);
} }
.drophighlight { .drophighlight {
@@ -730,8 +873,8 @@ ul.messages li.new {
#context-menu { #context-menu {
display: none; display: none;
position: absolute; position: absolute;
background: white; background: var(--color-context-menu-bg);
border: 1px solid gray; border: 1px solid var(--color-context-menu-border);
list-style: none; list-style: none;
z-index: 999; z-index: 999;
padding: 2px 5px; padding: 2px 5px;
@@ -740,10 +883,11 @@ ul.messages li.new {
#context-menu li { #context-menu li {
cursor: pointer; cursor: pointer;
padding: 1px 5px; padding: 1px 5px;
color: var(--color-text);
} }
#context-menu li:hover { #context-menu li:hover {
background-color: #e0e0e0; background-color: var(--color-context-menu-hover-bg);
} }
/* painter */ /* painter */
@@ -753,7 +897,7 @@ ul.messages li.new {
} }
#canvasdiv canvas { #canvasdiv canvas {
border: 1px solid black; border: 1px solid var(--color-text);
} }
#buttonbar { #buttonbar {
@@ -765,8 +909,8 @@ ul.messages li.new {
#buttonbar button, #buttonbar button,
#layersdiv button { #layersdiv button {
padding: 1px 2px; padding: 1px 2px;
border: 1px solid #cccccc; border: 1px solid var(--color-input-border);
background-color: #dddddd; background-color: var(--color-button-bg);
width: 40px; width: 40px;
} }
@@ -776,13 +920,13 @@ ul.messages li.new {
} }
#buttonbar .active { #buttonbar .active {
background-color: #ffffff; background-color: var(--color-input-bg);
cursor: pointer; cursor: pointer;
} }
#buttonbar button:hover, #buttonbar button:hover,
#layersdiv button:hover { #layersdiv button:hover {
background-color: #cccccc; background-color: var(--color-button-hover-bg);
cursor: pointer; cursor: pointer;
} }
@@ -806,14 +950,14 @@ ul.messages li.new {
} }
#savebar button { #savebar button {
border: solid 1px #666666; border: solid 1px var(--color-text-light);
} }
/* updatescreens */ /* updatescreens */
#easyupdate { #easyupdate {
padding: 10px; padding: 10px;
background-color: white; background-color: var(--color-module-bg);
width: 400px; width: 400px;
margin-bottom: 20px; margin-bottom: 20px;
} }
@@ -845,12 +989,12 @@ h4 {
.releasetable th { .releasetable th {
text-align: left; text-align: left;
background-color: #ffffff; background-color: var(--color-module-bg);
padding: 1px 5px; padding: 1px 5px;
} }
.releasetable td { .releasetable td {
background-color: #ffffff; background-color: var(--color-module-bg);
padding: 1px 5px; padding: 1px 5px;
min-width: 70px; min-width: 70px;
vertical-align: baseline; vertical-align: baseline;
@@ -862,11 +1006,11 @@ h4 {
.releasetable button { .releasetable button {
padding: 3px 10px; padding: 3px 10px;
background-color: #e0e0e0; background-color: var(--color-button-bg);
} }
.releasetable button:hover { .releasetable button:hover {
background-color: #a0a0a0; background-color: var(--color-button-hover-bg);
} }
.updateCol1, .flashCol1 { .updateCol1, .flashCol1 {
@@ -875,9 +1019,9 @@ h4 {
.console { .console {
width: 450px; width: 450px;
background-color: black; background-color: var(--color-console-bg);
font-family: 'lucida console', 'ui-monospace'; font-family: 'lucida console', 'ui-monospace', 'monospace';
color: white; color: var(--color-console-text);
padding: 5px 10px; padding: 5px 10px;
padding-bottom: 25px; padding-bottom: 25px;
height: calc(100vh - 200px); height: calc(100vh - 200px);
@@ -916,15 +1060,15 @@ h4 {
@keyframes new { @keyframes new {
0% { 0% {
background-color: rgba(255, 255, 204, 1); background-color: var(--color-log-new-bg-start);
} }
50% { 50% {
background-color: rgba(255, 255, 204, .5); background-color: var(--color-log-new-bg-mid);
} }
100% { 100% {
background-color: rgba(255, 255, 204, 0); background-color: var(--color-log-new-bg-end);
} }
} }
@@ -946,14 +1090,13 @@ h4 {
0% {} 0% {}
50% { 50% {
background-color: #d4d4f5; background-color: var(--color-tag-pending-anim-bg);
} }
100% {} 100% {}
} }
@media screen and (max-width: 480px) { @media screen and (max-width: 480px) {
/* styles for mobile devices in portrait mode */
body { body {
font-size: 13px; font-size: 13px;
@@ -1008,4 +1151,22 @@ h4 {
padding: 1px 1px; padding: 1px 1px;
} }
.theme-toggle-btn {
background-color: transparent;
border: none;
color: var(--color-header-text);
cursor: pointer;
align-self: center;
transition: background-color 0.2s ease-in-out, color 0.2s ease-in-out;
margin-left: auto;
border-left: 1px solid var(--color-tab-border);
padding: 6px 1rem;
border-radius: 4px;
margin-right: 1rem;
}
.theme-toggle-btn:hover {
background-color: var(--color-tab-hover-bg);
}
} }

View File

@@ -6,6 +6,7 @@ const WAKEUP_REASON_GPIO = 2;
const WAKEUP_REASON_NFC = 3; const WAKEUP_REASON_NFC = 3;
const WAKEUP_REASON_BUTTON1 = 4; const WAKEUP_REASON_BUTTON1 = 4;
const WAKEUP_REASON_BUTTON2 = 5; const WAKEUP_REASON_BUTTON2 = 5;
const WAKEUP_REASON_BUTTON3 = 6;
const WAKEUP_REASON_FAILED_OTA_FW = 0xE0; const WAKEUP_REASON_FAILED_OTA_FW = 0xE0;
const WAKEUP_REASON_FIRSTBOOT = 0xFC; const WAKEUP_REASON_FIRSTBOOT = 0xFC;
const WAKEUP_REASON_NETWORK_SCAN = 0xFD; const WAKEUP_REASON_NETWORK_SCAN = 0xFD;
@@ -82,6 +83,34 @@ window.addEventListener("loadConfig", function () {
}); });
window.addEventListener("load", function () { window.addEventListener("load", function () {
const themeToggle = $('#theme-toggle');
if (themeToggle) {
const prefersDarkScheme = window.matchMedia('(prefers-color-scheme: dark)');
const setTheme = (theme) => {
if (theme === 'dark') {
document.body.classList.add('dark-mode');
themeToggle.innerHTML = 'dark_mode';
localStorage.setItem('theme', 'dark');
} else {
document.body.classList.remove('dark-mode');
themeToggle.innerHTML = 'light_mode';
localStorage.setItem('theme', 'light');
}
};
themeToggle.addEventListener('click', () => {
const isDarkMode = document.body.classList.contains('dark-mode');
setTheme(isDarkMode ? 'light' : 'dark');
});
const savedTheme = localStorage.getItem('theme');
if (savedTheme) {
setTheme(savedTheme);
} else {
setTheme(prefersDarkScheme.matches ? 'dark' : 'light');
}
}
window.dispatchEvent(loadConfig); window.dispatchEvent(loadConfig);
initTabs(); initTabs();
fetch('content_cards.json') fetch('content_cards.json')
@@ -124,6 +153,18 @@ function initTabs() {
tabLink.addEventListener("click", function (event) { tabLink.addEventListener("click", function (event) {
event.preventDefault(); event.preventDefault();
const targetId = this.getAttribute("data-target"); const targetId = this.getAttribute("data-target");
const url = new URL(window.location);
if (targetId === 'tagtab') {
if (url.searchParams.get('tab') !== 'tagtab') {
url.searchParams.set('tab', 'tagtab');
history.replaceState(null, '', url);
}
} else {
if (url.searchParams.has('tab')) {
url.searchParams.delete('tab');
history.replaceState(null, '', url);
}
}
const loadTabEvent = new CustomEvent('loadTab', { detail: targetId }); const loadTabEvent = new CustomEvent('loadTab', { detail: targetId });
document.dispatchEvent(loadTabEvent); document.dispatchEvent(loadTabEvent);
tabContents.forEach(tabContent => { tabContents.forEach(tabContent => {
@@ -137,7 +178,15 @@ function initTabs() {
this.classList.add("active"); this.classList.add("active");
}); });
}); });
tabLinks[0].click();
const urlParams = new URLSearchParams(window.location.search);
const tabToOpen = urlParams.get('tab');
const targetTabLink = document.querySelector(`.tablinks[data-target="${tabToOpen}"]`);
if (targetTabLink) {
targetTabLink.click();
} else {
tabLinks[0].click();
}
}; };
function loadTags(pos) { function loadTags(pos) {
@@ -266,6 +315,17 @@ function convertSize(bytes) {
return bytes; return bytes;
} }
function clearTagStateClasses(tagElement) {
tagElement.classList.remove(
'state-deepsleep',
'state-boot',
'state-wakeup',
'state-scan',
'state-reset',
'state-failed-ota'
);
}
function processTags(tagArray) { function processTags(tagArray) {
for (const element of tagArray) { for (const element of tagArray) {
const tagmac = element.mac; const tagmac = element.mac;
@@ -384,7 +444,7 @@ function processTags(tagArray) {
} }
div.style.opacity = '1'; div.style.opacity = '1';
$('#tag' + tagmac + ' .lastseen').style.color = "black"; $('#tag' + tagmac + ' .lastseen').style.color = "";
div.classList.remove("tagpending"); div.classList.remove("tagpending");
div.dataset.lastseen = element.lastseen; div.dataset.lastseen = element.lastseen;
div.dataset.wakeupreason = element.wakeupReason; div.dataset.wakeupreason = element.wakeupReason;
@@ -392,45 +452,56 @@ function processTags(tagArray) {
div.dataset.channel = element.ch; div.dataset.channel = element.ch;
div.dataset.isexternal = element.isexternal; div.dataset.isexternal = element.isexternal;
$('#tag' + tagmac + ' .warningicon').style.display = 'none'; $('#tag' + tagmac + ' .warningicon').style.display = 'none';
$('#tag' + tagmac).style.background = "#ffffff";
if (element.contentMode == 12 || element.nextcheckin == 3216153600) $('#tag' + tagmac).style.background = "#e4e4e0"; div.style.background = '';
div.classList.remove('state-timeout');
clearTagStateClasses(div);
let stateClassSet = false;
switch (parseInt(element.wakeupReason)) { switch (parseInt(element.wakeupReason)) {
case WAKEUP_REASON_TIMED: case WAKEUP_REASON_TIMED:
break; break;
case WAKEUP_REASON_BOOT: case WAKEUP_REASON_BOOT:
case WAKEUP_REASON_FIRSTBOOT: case WAKEUP_REASON_FIRSTBOOT:
$('#tag' + tagmac + ' .nextcheckin').innerHTML = "<font color=yellow>First boot</font>" $('#tag' + tagmac + ' .nextcheckin').innerHTML = "<font color=yellow>First boot</font>"
$('#tag' + tagmac).style.background = "#b0d0b0"; div.classList.add("state-boot");
stateClassSet = true;
break; break;
case WAKEUP_REASON_GPIO: case WAKEUP_REASON_GPIO:
$('#tag' + tagmac + ' .nextcheckin').innerHTML = "GPIO wakeup"
$('#tag' + tagmac).style.background = "#c8f1bb";
break;
case WAKEUP_REASON_BUTTON1: case WAKEUP_REASON_BUTTON1:
$('#tag' + tagmac + ' .nextcheckin').innerHTML = "Button 1 pressed"
$('#tag' + tagmac).style.background = "#c8f1bb";
break;
case WAKEUP_REASON_BUTTON2: case WAKEUP_REASON_BUTTON2:
$('#tag' + tagmac + ' .nextcheckin').innerHTML = "Button 2 pressed" case WAKEUP_REASON_BUTTON3:
$('#tag' + tagmac).style.background = "#c8f1bb";
break;
case WAKEUP_REASON_NFC: case WAKEUP_REASON_NFC:
$('#tag' + tagmac + ' .nextcheckin').innerHTML = "NFC wakeup" let reasonText = {
$('#tag' + tagmac).style.background = "#c8f1bb"; [WAKEUP_REASON_GPIO]: "GPIO wakeup",
[WAKEUP_REASON_BUTTON1]: "Button 1 pressed",
[WAKEUP_REASON_BUTTON2]: "Button 2 pressed",
[WAKEUP_REASON_BUTTON3]: "Button 3 pressed",
[WAKEUP_REASON_NFC]: "NFC wakeup"
}[parseInt(element.wakeupReason)];
$('#tag' + tagmac + ' .nextcheckin').innerHTML = reasonText;
div.classList.add("state-wakeup");
stateClassSet = true;
break; break;
case WAKEUP_REASON_NETWORK_SCAN: case WAKEUP_REASON_NETWORK_SCAN:
$('#tag' + tagmac + ' .nextcheckin').innerHTML = "<font color=yellow>Network scan</font>" $('#tag' + tagmac + ' .nextcheckin').innerHTML = "<font color=yellow>Network scan</font>"
$('#tag' + tagmac).style.background = "#c0c0d0"; div.classList.add("state-scan");
stateClassSet = true;
break; break;
case WAKEUP_REASON_WDT_RESET: case WAKEUP_REASON_WDT_RESET:
$('#tag' + tagmac + ' .nextcheckin').innerHTML = "Watchdog reset!" $('#tag' + tagmac + ' .nextcheckin').innerHTML = "Watchdog reset!"
$('#tag' + tagmac).style.background = "#d0a0a0"; div.classList.add("state-reset");
stateClassSet = true;
break; break;
case WAKEUP_REASON_FAILED_OTA_FW: case WAKEUP_REASON_FAILED_OTA_FW:
$('#tag' + tagmac + ' .nextcheckin').innerHTML = "Firmware update rejected!" $('#tag' + tagmac + ' .nextcheckin').innerHTML = "Firmware update rejected!"
$('#tag' + tagmac).style.background = "#f0a0a0"; div.classList.add("state-failed-ota");
stateClassSet = true;
break; break;
} }
if (!stateClassSet && (element.contentMode == 12 || element.nextcheckin == 3216153600)) {
div.classList.add("state-deepsleep");
}
$('#tag' + tagmac + ' .pendingicon').style.display = (element.pending ? 'inline-block' : 'none'); $('#tag' + tagmac + ' .pendingicon').style.display = (element.pending ? 'inline-block' : 'none');
$('#tag' + tagmac + ' .pendingicon').innerHTML = element.pending; $('#tag' + tagmac + ' .pendingicon').innerHTML = element.pending;
div.classList.add("tagflash"); div.classList.add("tagflash");
@@ -465,18 +536,24 @@ function updatecards() {
if (tagDB[tagmac].batteryMv < 2400 && tagDB[tagmac].batteryMv != 0 && tagDB[tagmac].batteryMv != 1337) lowbattcount++; if (tagDB[tagmac].batteryMv < 2400 && tagDB[tagmac].batteryMv != 0 && tagDB[tagmac].batteryMv != 1337) lowbattcount++;
if (item.dataset.lastseen && item.dataset.lastseen > (Date.now() / 1000) - servertimediff - 30 * 24 * 3600 * 60) { if (item.dataset.lastseen && item.dataset.lastseen > (Date.now() / 1000) - servertimediff - 30 * 24 * 3600 * 60) {
let idletime = (Date.now() / 1000) - servertimediff - item.dataset.lastseen; let idletime = (Date.now() / 1000) - servertimediff - item.dataset.lastseen;
$('#tag' + tagmac + ' .lastseen').innerHTML = "<span>last seen</span>" + displayTime(Math.floor(idletime)) + " ago"; $('#tag' + tagmac + ' .lastseen').innerHTML = "<span>last seen</span>" + displayTime(Math.floor(idletime)) + " ago";
if ((Date.now() / 1000) - servertimediff - apConfig.maxsleep * 60 - 300 > item.dataset.nextcheckin) { if ((Date.now() / 1000) - servertimediff - apConfig.maxsleep * 60 - 300 > item.dataset.nextcheckin) {
$('#tag' + tagmac + ' .warningicon').style.display = 'inline-block'; item.querySelector('.warningicon').style.display = 'inline-block';
$('#tag' + tagmac).classList.remove("tagpending") item.classList.remove("tagpending");
$('#tag' + tagmac).style.background = '#e0e0a0'; item.classList.add('state-timeout');
timeoutcount++; timeoutcount++;
} else { } else {
item.classList.remove('state-timeout');
if (tagDB[tagmac].pending) pendingcount++; if (tagDB[tagmac].pending) pendingcount++;
} }
const lastseenEl = item.querySelector('.lastseen');
if (idletime > 24 * 3600) { if (idletime > 24 * 3600) {
$('#tag' + tagmac).style.opacity = '.5'; item.style.opacity = '.5';
$('#tag' + tagmac + ' .lastseen').style.color = "red"; lastseenEl.classList.add('error');
} else {
item.style.opacity = '1';
lastseenEl.classList.remove('error');
} }
} else { } else {
if ($('#tag' + tagmac + ' .lastseen')) { if ($('#tag' + tagmac + ' .lastseen')) {
@@ -494,6 +571,12 @@ function updatecards() {
} else { } else {
// $('#tag' + tagmac + ' .nextcheckin').innerHTML = ""; // $('#tag' + tagmac + ' .nextcheckin').innerHTML = "";
} }
if (item.dataset.nextupdate < (Date.now() / 1000) - servertimediff) {
$('#tag' + tagmac + ' .waitingicon').style.display = 'inline-block';
} else {
$('#tag' + tagmac + ' .waitingicon').style.display = 'none';
}
}) })
$('#dashboardTagCount').innerHTML = tagcount; $('#dashboardTagCount').innerHTML = tagcount;
@@ -1001,7 +1084,7 @@ function contentselected() {
fetch('edit?list=%2F&recursive=1') fetch('edit?list=%2F&recursive=1')
.then(response => response.json()) .then(response => response.json())
.then(data => { .then(data => {
let files = data.filter(item => item.type === "file" && item.name.endsWith(".jpg")); let files = data.filter(item => item.type === "file" && (item.name.toLowerCase().endsWith(".jpg") || item.name.toLowerCase().endsWith(".jpeg")));
if (element.type == 'binfile') files = data.filter(item => item.type === "file" && item.name.endsWith(".bin")); if (element.type == 'binfile') files = data.filter(item => item.type === "file" && item.name.endsWith(".bin"));
if (element.type == 'jsonfile') files = data.filter(item => item.type === "file" && item.name.endsWith(".json")); if (element.type == 'jsonfile') files = data.filter(item => item.type === "file" && item.name.endsWith(".json"));
const optionElement = document.createElement("option"); const optionElement = document.createElement("option");

View File

@@ -19,7 +19,7 @@ export async function initUpdate() {
gModuleType = "ESP32-C6"; gModuleType = "ESP32-C6";
gShortName = "C6"; gShortName = "C6";
} }
else if(apConfig?.H2 && apConfig.H2 == 1) { else if (apConfig?.H2 && apConfig.H2 == 1) {
gIsH2 = true; gIsH2 = true;
gModuleType = "ESP32-H2"; gModuleType = "ESP32-H2";
gShortName = "H2"; gShortName = "H2";
@@ -71,13 +71,15 @@ export async function initUpdate() {
print(`current env: ${sdata.env}`); print(`current env: ${sdata.env}`);
print(`build date: ${formatEpoch(sdata.buildtime)}`); print(`build date: ${formatEpoch(sdata.buildtime)}`);
print(`esp32 version: ${sdata.buildversion}`); print(`esp32 version: ${sdata.buildversion}`);
if(gModuleType != '') {
var hex_ver = '0000' + sdata.ap_version.toString(16);
print(`${gModuleType} version: ${hex_ver.slice(-4)}`);
}
print(`filesystem version: ${filesystemversion}`); print(`filesystem version: ${filesystemversion}`);
print(`psram size: ${sdata.psramsize}`); print(`psram size: ${sdata.psramsize}`);
print(`flash size: ${sdata.flashsize}`); print(`flash size: ${sdata.flashsize}`);
if (gModuleType !== '') {
let hex_ver = sdata.ap_version && !isNaN(sdata.ap_version)
? ('0000' + sdata.ap_version.toString(16)).slice(-4)
: 'unknown';
print(`${gModuleType} version: ${hex_ver}`);
}
print("--------------------------", "gray"); print("--------------------------", "gray");
env = apConfig.env || sdata.env; env = apConfig.env || sdata.env;
if (sdata.env != env) { if (sdata.env != env) {
@@ -90,7 +92,7 @@ export async function initUpdate() {
$('#environment').value = env; $('#environment').value = env;
} }
const rdata = await fetch(repoUrl).then(response => response.json()) const rdata = await fetch(repoUrl).then(response => response.json())
const JsonName = 'firmware_' + gShortName + '.json'; const JsonName = 'firmware_' + gShortName + '.json';
const releaseDetails = rdata.map(release => { const releaseDetails = rdata.map(release => {
const assets = release.assets; const assets = release.assets;
@@ -137,7 +139,7 @@ export async function initUpdate() {
releaseDetails.forEach(release => { releaseDetails.forEach(release => {
if (rowCounter < 4 && release?.html_url) { if (rowCounter < 4 && release?.html_url) {
const tableRow = document.createElement('tr'); const tableRow = document.createElement('tr');
let tablerow = `<td><a href="${release.html_url}" target="_new">${release.tag_name}</a></td><td>${release.date}</td><td>${release.name}</td><td><button type="button" onclick="otamodule.updateWebpage('${release.file_url}','${release.tag_name}', true)">Filesystem</button></td><td><button type="button" onclick="otamodule.updateESP('${release.bin_url}', true)">ESP32</button></td>`; let tablerow = `<td><a href="${release.html_url}" target="_new">${release.tag_name}</a></td><td>${release.date}</td><td>${release.name}</td><td><button type="button" onclick="otamodule.updateESP('${release.bin_url}', true)">ESP32</button></td><td><button type="button" onclick="otamodule.updateWebpage('${release.file_url}','${release.tag_name}', true)">Filesystem</button></td>`;
if (release.tag_name == currentVer) { if (release.tag_name == currentVer) {
tablerow += "<td>current version</td>"; tablerow += "<td>current version</td>";
} else if (release.date < formatEpoch(currentBuildtime)) { } else if (release.date < formatEpoch(currentBuildtime)) {
@@ -150,85 +152,86 @@ export async function initUpdate() {
rowCounter++; rowCounter++;
} }
if (release?.firmware_url) { if (release?.firmware_url) {
radioFwCounter++; radioFwCounter++;
} }
}); });
$('#releasetable').innerHTML = ""; $('#releasetable').innerHTML = "";
$('#releasetable').appendChild(table); $('#releasetable').appendChild(table);
if(radioFwCounter > 0) { if (radioFwCounter > 0) {
const table1 = document.createElement('table'); const table1 = document.createElement('table');
const tableHeader1 = document.createElement('tr'); const tableHeader1 = document.createElement('tr');
tableHeader1.innerHTML = '<th>Release</th><th>Date</th><th>Name</th><th><center>Update</center></th><th>Version</th><th>Remark</th>'; tableHeader1.innerHTML = '<th>Release</th><th>Date</th><th>Name</th><th><center>Update</center></th><th>Version</th><th>Remark</th>';
table1.appendChild(tableHeader1); table1.appendChild(tableHeader1);
rowCounter = 0; rowCounter = 0;
for (const release of releaseDetails) { for (const release of releaseDetails) {
if (rowCounter < 4 && release?.firmware_url) { if (rowCounter < 4 && release?.firmware_url) {
const tableRow = document.createElement('tr'); const tableRow = document.createElement('tr');
var tablerow; var tablerow;
var firmwareVer = "unknown"; var firmwareVer = "unknown";
var release_url = release.firmware_url; var release_url = release.firmware_url;
tablerow = `<td><a href="${release.html_url}" target="_new">${release.tag_name}</a></td><td>${release.date}</td><td>${release.name}</td>`; tablerow = `<td><a href="${release.html_url}" target="_new">${release.tag_name}</a></td><td>${release.date}</td><td>${release.name}</td>`;
tablerow += `<td><button type="button" onclick="otamodule.updateC6H2('${release_url}')">${gModuleType}</button></td>`; tablerow += `<td><button type="button" onclick="otamodule.updateC6H2('${release_url}')">${gModuleType}</button></td>`;
const firmwareUrl = 'http://proxy.openepaperlink.org/proxy.php?url=' + release.firmware_url; const firmwareUrl = 'http://proxy.openepaperlink.org/proxy.php?url=' + release.firmware_url;
firmwareVer = await fetch(firmwareUrl, { method: 'GET'}) firmwareVer = await fetch(firmwareUrl, { method: 'GET' })
.then(function (response) { return response.json(); }) .then(function (response) { return response.json(); })
.then(function (response) { .then(function (response) {
return response[2]['version']; }) return response[2]['version'];
.catch(error => { })
print('Error fetching releases:' + error, "red"); .catch(error => {
}); print('Error fetching releases:' + error, "red");
tablerow += '<td>' + firmwareVer + '</td><td>'; });
if(firmwareVer != 'unknown') { tablerow += '<td>' + firmwareVer + '</td><td>';
let Ver = Number('0x' + firmwareVer); if (firmwareVer != 'unknown') {
if(Ver > gCurrentRfVer) { let Ver = Number('0x' + firmwareVer);
tablerow += 'newer'; if (Ver > gCurrentRfVer) {
} tablerow += 'newer';
else if (Ver < gCurrentRfVer) { }
tablerow += 'older'; else if (Ver < gCurrentRfVer) {
} tablerow += 'older';
else if(!Number.isNaN(Ver)){ }
tablerow += 'current version'; else if (!Number.isNaN(Ver)) {
} tablerow += 'current version';
} }
tablerow += '</td>'; }
tableRow.innerHTML = tablerow; tablerow += '</td>';
table1.appendChild(tableRow); tableRow.innerHTML = tablerow;
rowCounter++; table1.appendChild(tableRow);
} rowCounter++;
}; }
};
$('#radio_releasetable').innerHTML = ""; $('#radio_releasetable').innerHTML = "";
$('#radio_releasetable').appendChild(table1); $('#radio_releasetable').appendChild(table1);
} }
const table2 = document.createElement('table'); const table2 = document.createElement('table');
{ {
const tableHeader2 = document.createElement('tr'); const tableHeader2 = document.createElement('tr');
tableHeader2.innerHTML = '<th>Firmware</th><th><center>Update</center></th>'; tableHeader2.innerHTML = '<th>Firmware</th><th><center>Update</center></th>';
table2.appendChild(tableHeader2); table2.appendChild(tableHeader2);
const tableRow = document.createElement('tr'); const tableRow = document.createElement('tr');
tablerow = '<td title="manual upload, make sure all four files are present">Binaries from <a href="/edit" target="littlefs">file system</a></td>'; tablerow = '<td title="manual upload, make sure all four files are present">Binaries from <a href="/edit" target="littlefs">file system</a></td>';
tablerow += `<td><button type="button" onclick="otamodule.updateC6H2('')">${gModuleType}</button></td>`; tablerow += `<td><button type="button" onclick="otamodule.updateC6H2('')">${gModuleType}</button></td>`;
tableRow.innerHTML = tablerow; tableRow.innerHTML = tablerow;
table2.appendChild(tableRow); table2.appendChild(tableRow);
} }
{ {
const tableRow = document.createElement('tr'); const tableRow = document.createElement('tr');
const Url = "https://raw.githubusercontent.com/" + repo + const Url = "https://raw.githubusercontent.com/" + repo +
"/master/binaries/ESP32-" + gShortName + "/master/binaries/ESP32-" + gShortName +
"/firmware_" + gShortName + ".json"; "/firmware_" + gShortName + ".json";
tablerow = `<td><a href="https://github.com/${repo}/tree/master/binaries/ESP32-${gShortName}/" target="_new">Latest version from repo</a></td>`; tablerow = `<td><a href="https://github.com/${repo}/tree/master/binaries/ESP32-${gShortName}/" target="_new">Latest version from repo</a></td>`;
tablerow += `<td><button type="button" onclick="otamodule.updateC6H2('${Url}')">${gModuleType}</button></td>`; tablerow += `<td><button type="button" onclick="otamodule.updateC6H2('${Url}')">${gModuleType}</button></td>`;
tableRow.innerHTML = tablerow; tableRow.innerHTML = tablerow;
table2.appendChild(tableRow); table2.appendChild(tableRow);
} }
$('#radio_releasetable1').innerHTML = ""; $('#radio_releasetable1').innerHTML = "";
$('#radio_releasetable1').appendChild(table2); $('#radio_releasetable1').appendChild(table2);
disableButtons(buttonState); disableButtons(buttonState);
} }
@@ -454,7 +457,7 @@ export async function updateC6H2(Url) {
disableButtons(true); disableButtons(true);
running = true; running = true;
errors = 0; errors = 0;
const ReleaseUrl = Url.substring(0,Url.lastIndexOf('/')); const ReleaseUrl = Url.substring(0, Url.lastIndexOf('/'));
const consoleDiv = document.getElementById('updateconsole'); const consoleDiv = document.getElementById('updateconsole');
consoleDiv.scrollTop = consoleDiv.scrollHeight; consoleDiv.scrollTop = consoleDiv.scrollHeight;
const formData = new FormData(); const formData = new FormData();
@@ -495,7 +498,7 @@ $('#selectRepo').onclick = function (event) {
return fetch(updateUrl); return fetch(updateUrl);
} else { } else {
throw new Error("Json file binaries.json and/or filesystem.json not found in the release assets"); throw new Error("Json file binaries.json and/or filesystem.json not found in the release assets");
} }
}; };
}) })
.then(updateResponse => { .then(updateResponse => {
@@ -529,7 +532,7 @@ $('#selectRepo').onclick = function (event) {
}) })
.catch(error => { .catch(error => {
print('Error fetching releases:' + error, "red"); print('Error fetching releases:' + error, "red");
}); });
} }
$('#cancelSelectRepo').onclick = function (event) { $('#cancelSelectRepo').onclick = function (event) {
@@ -708,7 +711,7 @@ async function fetchAndCheckTagtypes(cleanup) {
check = false; check = false;
} }
} }
if (check) { if (check) {
let githubUrl = "https://raw.githubusercontent.com/" + repo + "/master/resources/tagtypes/" + filename; let githubUrl = "https://raw.githubusercontent.com/" + repo + "/master/resources/tagtypes/" + filename;

View File

@@ -215,7 +215,7 @@ function startPainter(mac, width, height, tagtype) {
canvas.addEventListener('touchend', handleTouchEnd); canvas.addEventListener('touchend', handleTouchEnd);
canvas.addEventListener('touchmove', handleTouchMove, { passive: true }); canvas.addEventListener('touchmove', handleTouchMove, { passive: true });
var sizes = [10,11,12,13,14,16,18,20,24,28,32,36,40,48,56,64,72,84]; var sizes = [10,11,12,13,14,16,18,20,24,28,32,36,40,48,56,64,72,84,96,108,120,144,168,192,256,320,384,480,512];
const fontSelect = document.createElement('select'); const fontSelect = document.createElement('select');
fontSelect.id = 'font-select'; fontSelect.id = 'font-select';

Binary file not shown.

Binary file not shown.

View File

@@ -1,990 +0,0 @@
:040000000200833245
:01000B0032C2
:0100130032BA
:01001B0032B2
:0100230032AA
:03002B000249CABD
:01003300329A
:01003B003292
:03004300024F8CDD
:03004B000248E781
:01005300327A
:01005B003272
:01006300326A
:01006B003262
:01007300325A
:03007B00025AAF77
:0300FA0002007E83
:03007E0002050672
:2000FD00E58620E0FB225390FD00225380FB0022E58620E0FB004390020022E58620E0FBA6
:20011D00004380040022AF8290F090E4F090F091F08F061FEE60767E0090F95AE0FDBD024E
:20013D000BEE90624393FDBDC800405990F95AE0FDBD010BEE90624393FDBDC8005046EE81
:20015D002443FCE43462FD8C828D83E493F582C007C006C005C004121C10E582D004D00538
:20017D00D006D007601F90F090E0FB90F0BFE0FAC3EB9A501090F090EAF08C828D83E4930B
:20019D00FC90F091F00EBE0C005086808C90F091E0FFE06013BFC800400890F95A7402F030
:2001BD00800690F95A7401F090F091E0F5822290F0EDE0FEA3E0FFC3742C9E74019F40099F
:2001DD0090F0E3E0700330015E300A0920020690F0C6E0700930031E90F0C7E0601890FC37
:2001FD0063E0FFBFFF02800B7824E4F28F821227338003123C81121DDCAD82AE83AFF0907A
:20021D00F092EDF0EEA3F0EFA3F0ED4E602D90F0EDE4F0A3F010010090F0E3E06002D2013A
:20023D0090F0E3E4F08014121EC7AD82AE83AFF090F092EDF0EEA3F0EFA3F012187090F0D4
:20025D0092E0FDA3E0FEA3E0FFED4E700990F0E1E4F0A3F08059740F2DFAE43EFB8F048AD6
:20027D00828B838CF0126223FAA3126223FB90F0E1EAF0EBA3F0740D2DFAE43EFB8F048AF4
:20029D00828B838CF012622360168D828E838FF0123108E582701890F0E1E4F0A3F0800FF8
:2002BD007454C0E07462C0E01259A9158115811218BBAE82AF8390F0EDE0FCA3E0FD90F073
:2002DD00EDEE2CF0EF3DA3F0BE580CBF020990F0C5E06003C2002290FA5BE0600E90FA5BDB
:2002FD00E4F0900064E4F5F00217BB90F0E1E0FEA3E0FF4E603BEF30E71F8E048F0553052F
:20031D007F7877ECF2ED08F2E408F208F29003E8E4F5F0125ED50217BB7877EEF2EF08F2A0
:20033D00E408F208F290EA60E4F5F0125ED50217BB1218BBAE82AF837877EEF2EF08F2E429
:20035D0008F208F29003E8E4F5F0125ED50217BB90F0CEE0FF600D8F82121C10E58290F956
:20037D0059F0800C758202120123E58290F959F090F959E0700920030690F0C7E0701430E4
:20039D000A0920020690F0C6E0700890F0E4E0FFBF233690FC63E0FFBFFF02801A758202EB
:2003BD00123E21E582702290FC63E0FF7824E4F28F82122733801290F0E4E0FFBF23004002
:2003DD0005123DC28003123D7F90F959E0604890F0E4E4F090F0CEE0700F758204121776B0
:2003FD001214C77582041217AF90F0E374FDF09000281217531218BBAE82AF837877EEF212
:20041D00EF08F2E408F208F29003E8E4F5F0125ED51217BBD20022758201121836AC82AD6A
:20043D0083AEF0FF7877ECF2ED08F2EE08F2EF08F29003E8E4F5F0125ED50217BBE582FF37
:20045D0024FA50030204EEEF2F2F90046B730248E302047D0204940204C40204EE0204D07D
:20047D00745FC0E07462C0E01259A915811581C20090F959E4F02290F959E0FE746CC0E05C
:20049D007462C0E01259A915811581758204C0061217761213811214C77582041217AFD0F3
:2004BD000690F959EEF0221239A0900000E4F5F00217BB747CC0E07462C0E01259A915816F
:2004DD00158175820412177612271F7582040217AF7E00C007C006748CC0E07462C0E01281
:2004FD0059A9E58124FCF5812275820112177675820F124C2590FAB2E0FEA3E0FF7423C0AC
:20051D00E08E828F8312482D15817404C0E0124376AC82AD83158190F0E5ECF0EDA3F09077
:20053D00624FE493C0E0740193C0E0906251E493C0E0740193C0E0740293C0E0749EC0E0D1
:20055D007462C0E01259A9E58124F9F5811252A212195412190C90F0E374FCF0AEBE5306B7
:20057D00187F00BE1009BF000690F0E374FEF0301B0C123E1B900000E4F5F01217BB7436BD
:20059D00C0E074FCC0E0E4C0E074CDC0E07462C0E01259A9E58124FBF5811236D590019066
:2005BD00E4F5F01217BB7582041217761213F31236BC90F0C2E0601174D5C0E07462C0E0C9
:2005DD001259A915811581801B74E6C0E07462C0E01259A915811581123A4F902710E4F538
:2005FD00F01217BB90F959E0FFE0601F8F82121C10E582702574F3C0E07462C0E01259A90E
:20061D001581158190F959E4F0800F7411C0E07463C0E01259A91581158190F959E070033B
:20063D0012036D90F959E06007123C81D2008005123D7FC2007582041217761214C7300085
:20065D00067E287F0080047E587F028E828F8312175330000A7C887D137E007F0080087C0A
:1E067D00C07DD47E017F008C828D838EF0EF1217BB3000051201CC80F812036D80F360
:20624300C864C965CA66CB67CC68CD6907002363804E6F207570646174650A00434D445F6B
:20626300444F5F5343414E0A0052657365742073657474696E67730A0045726173696E6793
:2062830020696D616765730A00436D6420307825782069676E6F7265640A000A2573204FBF
:2062A30045504C2076253034782C20636F6D70696C6564204A756C203139203230323420ED
:2062C30031353A33363A32380A004D41432025730A00446F696E67206661737420626F6F52
:2062E300740A004E6F726D616C20626F6F740A004E6F20415020666F756E64206F6E20739C
:2063030061766564206368616E6E656C0A004E6F207361766564206368616E6E656C0A00E4
:096323004368726F6D61323900AC
:0175F1000198
:20069B00E58620E0FB225390FD00225380FB0022E58620E0FB004390020022E58620E0FB02
:2006BB00004380040022AC82AD83AEF0FF00C2A0007582031242E38E821242E38D821242FE
:2006DB00E38C820242E3C007C006C005C004C003C002C001C000AC82AD83AEF0FFE5812446
:2006FB00F5F8860208860300C2A0007582031242E38E821242E38D821242E38C821242E374
:20071B008A068B07E58124F3F886040886058C028D031CBCFF011DEA4B6015758200124202
:20073B00E3AB828E828F83EBF0A3AE82AF8380DE00D2A000D000D001D002D003D004D005CD
:20075B00D006D00722AF8200C2A0008F821242E300D2A0002200C2A0007582051242E37536
:20077B0082001242E3E58220E0F500D2A00022AC82AD83AEF0FF7803E2FA08E2FBC007C0F7
:20079B0006C005C004C003C002120770758206120760D002D003D004D005D006D00700C26E
:2007BB00A0007582021242E38E821242E38D821242E38C821242E38A068B077805E2FC08F7
:2007DB00E2FD8C028D031CBCFF011DEA4B60128E828F83E0FBA3AE82AF838B821242E3809F
:2007FB00E100D2A000221207707582B9120760C20C227582AB12076075F034D5F0FDD20C73
:20081B0022C007C006C005C004C003C002C001C000C082C083C0F0C0E005810581E5812414
:20083B00EFF88605088604E58124EDF8E608467003020915C005C004E58124F9F8860208CF
:20085B007B00E58124FDF8E4C39AF674019B08F6E58124FDF8E58124EBF9C3E79609E70819
:20087B0096D004D005500EE58124EDF8A98119E6F708E609F77803EDF2EC08F2A881187949
:20089B0005E6F308E609F3E58124FBF886820886830886F008E6C007C006C005C004C0039A
:2008BB00C002C001C000C02512078AD025D000D001D002D003D004D005D006D007A8811880
:2008DB008602088603E4FEFFE58124FBF8EA26F6EB0836F6EE0836F6EF0836F6A88118E6F5
:2008FB002DFD08E63CFCE58124EDF8A98119E6C397F608E60997F6020842E58124FAF581DB
:20091B00D000D001D002D003D004D005D006D00722C007C006C005C004C003C002C001C0E2
:20093B0000C082C083C0F0C0E0E58124FDF88602088603EA7005EB540F6006758200020A19
:20095B002FE58124F1F8E608467003020A2C758206C007C006C005C004C003C002C001C0E2
:20097B0000C025120760D025D000D001D002D003D004D005D006D00700C2A000E58124F190
:20099B00F886020886037582201242E3E58124FDF8080886821242E3E58124FDF808868280
:2009BB001242E3E58124FDF886821242E300D2A000C007C006C005C004C003C002C001C099
:2009DB0000C025120770D025D000D001D002D003D004D005D006D0077401C0E09010001236
:2009FB004376AC82AD83AEF0FF1581E58124FDF8EC26F6ED0836F6EE0836F6EF0836F61A8B
:200A1B00BAFF011BE58124F1F8A60208A60302095C758201E58124FCF581D000D001D0024C
:0B0A3B00D003D004D005D006D0072265
:200A4600E58620E0FB225390FD00225380FB0022E58620E0FB004390020022E58620E0FB53
:200A6600004380040022C007C006C005C004AF82AE83ADF0FC90F0BBEFF0EEA3F0EDA3F05B
:200A8600ECA3F0C202C203D208758204C007C006C005C004C003C002C001C000C025121749
:200AA60076D025D000D001D002D003D004D005D006D00790F0BBE0FCA3E0FDA3E0FEA3E08E
:200AC600FF7416C0E0E4C0E074F3C0E074F0C0E08C828D838EF0EF1206E1E58124FCF581D8
:200AE60090F0BBE0FCA3E0FDA3E0FEA3E0FF90F0BB74162CF0E43DA3F0E43EA3F0E43FA346
:200B0600F090F103E0FFBF2004C207806A90F103E0FFBF2104D207805E90F103E0FF7E0007
:200B2600C007C0067414C0E07469C0E01259A9E58124FCF58190FA6E7416F0E4A3F090F004
:200B4600F375F000C007C006C005C004C003C002C001C000C025121AC3D025758204C02572
:200B66001217AFD025D000D001D002D003D004D005D006D0078051C220C007C006C005C041
:200B860004C003C002C001C000C025125C09D025C025120BD7D025D220C025125C09D025E3
:200BA600C025120BD7D025758204C0251217AFD025C025125C4DD025D000D001D002D003D9
:200BC600D004D005D006D007D004D005D006D007227F807E0090F0ABE4F0A3F090F0A5F01D
:200BE600A3F05390FD007D00200803020C6A30201D20071A74A0C0E07404C0E0E4C0E090CE
:200C0600F0F312451F158115811581020CBAC00590F0BBE0FAA3E0FBA3E0FCA3E0FD74A080
:200C2600C0E07404C0E074F3C0E074F0C0E08A828B838CF0ED1206E1E58124FCF58190F0F3
:200C4600BBE0FAA3E0FBA3E0FCA3E0FD90F0BB74A02AF074043BA3F0E43CA3F0E43DA3F066
:200C6600D005805074A0C0E07404C0E0E4C0E090F0F312451F1581158115817B4A7C00C0CD
:200C860007C006C005C004C0037807E2F58208E2F583120081D003D004D005D006D00790AF
:200CA600F0A5E02401F0A3E03400F01BBBFF011CEB4C70CB7B007C00EF60503020238E0200
:200CC600EA2AFEEB24F3F582EC34F0F583E0FAEF5A7003430601EF30E02B8E82125C3F80B4
:200CE600248E02EA2A25E0FEEB24F3F582EC34F0F583E0FAEF5A6003430603EF5411600597
:200D06008E82125C3FEFC313FF80AD7F800BBB00010CC3EB94A0EC9404409D90F0ABE0FB04
:200D2600A3E0FC744A2BFBE43CFC90F0ABEBF0ECA3F00DBD04005003020BEEE58620E0FB27
:200D4600004390020022AE82AF83C202C203C208D207C2207807EEF2EF08F2125C09120B4A
:200D6600D7D220125C09120BD7025C4DC007C006C005C004C003C002C001C000AD82AE8312
:200D8600AFF0A204202001B3505090F09FE0F508A3E0F50974012DFAE43EFB8F048A828B14
:200DA600838CF0126223FA780CF2E408F2850882850983C007C006C005C004C003C002C0CE
:200DC60001C000121003E582D000D001D002D003D004D005D006D0076003020FA98D828E6A
:200DE600838FF07809126223F290F0A1E0F508A3E0F5097809E2F50A750B00780EE50AF219
:200E0600E50B08F2850882850983C007C006C005C004C003C002C001C00012107AD000D06A
:200E260001D002D003D00490F0ADE0F508A3E0F50990F0B1E0FBA3E0FCEBC39508F582EC6E
:200E46009509F5837875E50AF2E50B08F2C002C001C000125EB5AB82AC83D000D001D00287
:200E6600D005D006D007ECC423CBC423541F6BCB541FCB6BCBFC90F0B7EBF0ECA3F0740245
:200E86002BFBE43CFCEB2DFDEC3EFE90F0A7E0FBA3E0FCEB5407700A7809E2540770030259
:200EA6000F5D5303078BF005F07B80E4FC3392D28008A2D2EC13FCEB13FBD5F0F5780AEB6A
:200EC600F2780B7480F28D828E838FF0126223FA74012DF50CE43EF50D8F0E7809E2F50ABB
:200EE600AC0A150AEC7003020FA9780BE25A6025C00290F0B5E0FAA3E0FCEA24F3FAEC344F
:200F0600F0FC8A828C83E0FB780AE242038A828C83EBF0D002780BE2C313F2780BE270195D
:200F2600850C82850D83850EF0126223FAA385820C85830D780B7480F2780AE2C313F27897
:200F46000AE2709C780A7480F290F0B5E02401F0A3E03400F080897809E2604790F0B5E032
:200F6600FBA3E0FCEB24F3FBEC34F0FC8B828C83E0F50C8D828E838FF0126223FAA3AD82E9
:200F8600AE83E50C42028B828C83EAF090F0B5E02401F0A3E03400F07809E2FC780924F822
:200FA600F280B4D000D001D002D003D004D005D006D0072290F0A7E0FEA3E0C423CEC42323
:200FC600541F6ECE541FCE6ECE30E40244E0FF90F0ABE0FCA3E0FD90F0B1E0FAA3E0FBEAAC
:200FE600C39CFCEB9DC454F0CCC4CC6CCC54F0CC6CFD90F0B5EC2EF0ED3FA3F022AE82AFF4
:201006008390F095EEF0EFA3F090F0AFEEF0EFA3F07427C39EFE74019FFF90F0A9EEF0EF40
:20102600A3F090F0A5E0FCA3E0FD90F0B1ECF0EDA3F0C3EE9CEF64808DF063F08095F040D4
:201046002F780CE22CFC08E23DFDC3EE9CEF9D501F780CD3E29EF4B3FEB308E29FF4FF0EA8
:20106600BE00010F90F0ADEEF0EFA3F07582002275820122AE82AF8390F0A7EEF0EFA3F0F3
:20108600780E90F097E22EF008E23FA3F0120FBA75820022C007C006C005C004C003C00262
:2010A600C001C000AC82AD83AEF0FF058105810581BF2000502C8F82C007C006C005C0049A
:2010C600C003C002C001C000C02512422ED025D000D001D002D003D004D005D006D007020A
:2010E60013447E00EF24E0FFEE34FFFEEF2FFFEE33FEEF242CF582EE3463F583E493FEA3FD
:20110600E493FF90F0B7EEF0EFA3F0EFC4540FFE90F0B3F0300507EE2EFE90F0B3F090F08C
:2011260099E0FEA3E0FF90F0B9EEF0EFA3F090F0B3E0FDFB3395E0FC0BBB00010CEB2EFB81
:20114600EC3FFC90F099EBF0ECA3F0A204202001B3504190F0B9E0FEA3E0FF780CEDF2EDDB
:201166003395E008F28E828F83C007C006C005C004C003C002C001C000C025121003E58218
:20118600D025D000D001D002D003D004D005D006D007600302134490F09BE0FEA3E0FF90F1
:2011A600F0B4E0FD780EF2ED3395E008F28E828F83C007C006C005C004C003C002C001C063
:2011C60000C02512107AD025D000D001D002D003D004D005D006D00790F0B7E0FEA3E0FF60
:2011E60053070F90F0B7EEF0EFA3F0A8811818760008768090F0A7E0FCA3E05304078CF0BC
:2012060005F07C80E4FD3392D28008A2D2ED13FDEC13FCD5F0F5A881A60490F0B3E0FD903E
:20122600F0ADE0FAA3E0FB90F0A5E0FCA3E0FFECC39AFAEF9BFBED3395E0FFEDC39AFAEFA1
:201246009BFB1ABAFF011B90F0B9EAF0EBA3F030050FEBC313CA13CAFB90F0B9EAF0EBA32A
:20126600F090F0B9E0FEA3E0FF90F0B7E0FCA3E0FD90F0B7EE2CF0EF3DA3F090F0B7E0FE37
:20128600A3E0FFEE2EFEEF33FFEE24ECF582EF3463F583E493FEA3E493FF90F0B9E4F0A3DA
:2012A600F090F0B9E0FCA3E0FD90F0B4E0FB3395E0FAC3EC9BED9A4003021344A88118182C
:2012C600E65EFC08E65FFD4C602190F0B5E0FCA3E0FDEC24F3FCED34F0FD8C828D83E0FB1A
:2012E600A881E642038C828D83EBF030051A90F0B9E0FCA3E0FDEC30E01AA88118E618C39F
:2013060013C613C608F6800CA88118E618C313C613C608F6A881E6C313F6A881E6701090DF
:20132600F0B5E02401F0A3E03400F0A881768090F0B9E02401F0A3E03400F00212A7158121
:1513460015811581D000D001D002D003D004D005D006D00722A8
:20632C000070071008500D9016601CA026A03010316037603D7044904D204F60552057808C
:20634C005F7066706D6073507880805085708C7093709A70A120A320A570AC80B470BB7022
:20636C00C2A0CCA0D670DD80E570EC70F370FA8002710971105115811D7124812C713381AA
:20638C003B7142814A7151715891617168A172A17CA186A1908198519D81A551AA81B2A15E
:2063AC00BC21BE71C571CC71D371DA71E181E971F071F741FB51007207420B9214721B72B7
:2063CC0022722972306236623C724362499252A25C8264A26E8276627C127D6283A28D72F9
:2063EC000000000000000000000000000000D87F0078000000000000007880009804E00549
:20640C00801E9864E005801E80648004183808640842FCFF8841F040083810442044C044F5
:20642C0000397002880C881088207040E0001001083A08468845C84C38381800680080014E
:20644C000078E00718180C300420024002400240024004200C301818E00700100018000F8B
:20646C000072000F001800104000400040004000F807400040004000400019001E008000B1
:20648C00800080008000800080001800180002000C003000C0000003000C00300040C00FF4
:2064AC0030300840084008403030C00F082008200820F87F080008000800186028404840FA
:2064CC0088400843083C0840084208420842F03DC0004003400440184020F87F4000400010
:2064EC00087C084408441042E041E00F10320844084408441042E00100401840E0400043BE
:20650C00004C00500060F038084508420842084590456038001E08218840884088403021C0
:20652C00C01F1806180619061E06C000C0002001200110021002080420012001200120017B
:20654C00200120012001200108041002100220012001C000C00000700040D840004100426E
:20656C0000640038C00F30181820C84728486850D851E03F2000200008007000C001400EDE
:20658C004018400C4003C00030000800F81F08110811081108118812700CC003300C100868
:2065AC0008100810081008100818F81F08100810081008101008E007F81F881088108810FA
:2065CC00881088100810F81F801080108010801080100010C003300C100808100810881091
:2065EC008810F818F81F80008000800080008000F81F081008100810F81F08100810081092
:20660C000800081008100810F01FF81F0001800140022004200810100800F81F0800080099
:20662C000800080008000800F81F001C8007E00060008003001CF81FF81F000800068001D8
:20664C0060001000F81FE007100808100810081008101008E007F81F8010801080108010F2
:20666C000011000EE00710080810081008100C101208E207F81F80108010C0102011100E33
:20668C000800180E0812081108118810901070180010001000100010F81F0010001000102D
:2066AC000010E01F18000800080008001000E01F0010000C8003600018001800E00000036E
:2066CC00000C00100018C0073800F0000007800370003800C00700180810100820044002E4
:2066EC008001800140022004100808100010000800060001F80000010002000400080010C0
:20670C0018102810481088100811081208140818FE7F024002400240024000400030000CAD
:20672C000003C00030000C0002000240024002400240FE7F2000C0000007001C0070000E46
:20674C00C001200004000400040004000400040004000400040004000080004030004804E8
:20676C00880488049004F8030800F87F10020804080408041006E001E001100208040804AF
:20678C00080408040804E00118020804080408041002F87FE001900288048804880488047E
:2067AC00880300040004F83F00240044004400440044E00119020904090409041202FC0795
:2067CC00F87F00010002000400040004F803000400040064F8670100010401040164FE678C
:2067EC00F87F8000C0002001200210020804004000400040F87FF807000200040004F8033A
:20680C00000200040004F803F80700030002000400040004F803E001100208040804080445
:20682C001002E001FF0710020804080408041006E001E00118020804080408041002FF07EF
:20684C00F8070001000200040004000718038804880448044804300400040004F01F0804F9
:20686C00080408040804F0070800080008001000F807000480036000180008003000C000D3
:20688C00000300040006E001180070008003800170001800E0010006080410022001C00004
:2068AC00C00020011002080401040103C10062001C0018006000800000030004080418045E
:2068CC00280448048804080508060804800080007C3F024002400240FE7F024002400240BD
:2068EC007C3F80008000C000000100010001800080004000400040008001F80108030804BD
:20690C00080808040803F80164617461547970652030782578206E6F7420737570706F7270
:05692C007465640A001F
:20135B00E58620E0FB225390FD00225380FB0022E58620E0FB004390020022E58620E0FB35
:20137B0000438004002290F0C17401F090F0C2E4F090F0C3F090F0C4F090F0C5F090F0C6CB
:20139B0004F090F0C7F090F0C9E4F090F0C8F090F0CC7428F0E4A3F090F0CEF090F0CA7467
:2013BB0028F0740AA3F090F959E4F090F95AF022AD82AE83126223FCBC011C7BC17CF08B3F
:2013DB00828C83740EC0E0C005C0061245B71581158115810214C7227480C0E0E4C0E07459
:2013FB00A2C0E074FDC0E0906000E4F5F01206E1E58124FCF581740EC0E07414C0E074FE15
:20141B00C0E090F0C11245B715811581158190FDA2E0FCA3E0FDA3E0FEA3E0FFBCA513BD41
:20143B005A10BEBA0DBFAB0A90FDA6E0FFBF0102803590FDA2E0FCA3E0FDA3E0FEA3E0FF17
:20145B0090FDA6E0FB7A00C004C005C006C007C003C0027431C0E07469C0E01259A9E58112
:20147B0024F8F58102138190FDA7E090F959F090FDA8E090F95AF0745FC0E07469C0E01259
:20149B0059A91581158112161990FDA2E4F004C0E0E4C0E074A2C0E074FDC0E0906000E4FC
:2014BB00F5F012081CE58124FCF581227480C0E0E4C0E074A2C0E074FDC0E0906000E4F530
:2014DB00F01206E1E58124FCF58190FDA2E0FCA3E0FDA3E0FEA3E0FFBCA53EBD5A3BBEBA15
:2014FB0038BFAB35788574C1F274F008F2E408F27888740EF2E408F290FE1475F0001260CF
:20151B00A4E5828583F045F0700F90FDA7E0FF90F959E0FEEFB506012290FE21E0FF90F04B
:20153B00CEE0FEEFB50602803EEE603BBE6400502390FE21E0FF7D00C007C0057471C0E040
:20155B007469C0E01259A9E58124FCF58190F0CEE4F08013BEC800400890F95A7402F08097
:20157B000690F95A7401F07480C0E0E4C0E0C0E090FDA212451F158115811581740EC0E0C1
:20159B0074C1C0E074F0C0E090FE141245B715811581158190FDA274A5F0F4A3F074BAA355
:2015BB00F0C4A3F090FDA67401F090F959E090FDA7F090F95AE090FDA8F07401C0E0E4C0AA
:2015DB00E0906000E4F5F012092C158115817480C0E0E4C0E074A2C0E074FDC0E090600015
:2015FB00E4F5F012081CE58124FCF581748AC0E07469C0E01259A91581158102161990F0C9
:20161B00C5E0FF7E00C007C006749BC0E07469C0E01259A9E58124FCF58190F0CEE0FF7E19
:20163B0000C007C00674B4C0E07469C0E01259A9E58124FCF58190F0CAE0FEA3E0FFC0063D
:20165B00C00774C7C0E07469C0E01259A9E58124FCF58190F0C2E0FF7E00C007C00674DBC5
:20167B00C0E07469C0E01259A9E58124FCF58190F959E0FF7E00C007C00674F0C0E0746975
:0C169B00C0E01259A9E58124FCF5812271
:206931004C6F616465642064656661756C74732073657474696E6773566572203078257862
:20695100204D61676963203078256C780A004C6F616465642073657474696E67733A0A002C
:2069710049676E6F7265642066697865644368616E6E656C2025640A00536176656420731C
:20699100657474696E67733A0A0020205363616E2041667465722054696D656F7574202581
:2069B100640A00202066697865644368616E6E656C2025640A0020206261744C6F77566F2E
:2069D1006C746167652025640A002020656E61626C6546617374426F6F742025640A00204A
:0D69F100204C6173742063682025640A0047
:2016A700E58620E0FB225390FD00225380FB0022E58620E0FB004390020022E58620E0FBE6
:2016C70000438004002275F10175805875FDDD75F33875904075FE6E75F4E875A00175FF76
:2016E7000122C00775E40075FC0075F70075FE0290F953E0FF54F06002800DD291758F00F9
:2017070075F60075FD008012758F8175F62F75FD8175FE2F53807E5390D075F30075F400CA
:0617270075F500D0072259
:20172D00E58620E0FB225390FD00225380FB0022E58620E0FB004390020022E58620E0FB5F
:20174D00004380040022AE82AF837D00BD08005017ED75F002A424CFF58274F035F0F58325
:20176D00EEF0EFA3F00D80E422E582FF30E0251255BAC007124950D2AF1216CD1242DF1280
:20178D004DF6D00775820A124E3590F959E0FEF582124D81EF30E20912430C200C030208D1
:2017AD000D22E58230E206300C0302080122AF82AE83ADF0FC90F0EFEFF0EEA3F0EDA3F0B8
:2017CD00ECA3F090F0EFE0FCA3E0FDA3E0FEA3E0FFC004C005C006C00774FEC0E07469C0EA
:2017ED00E01259A9E58124FAF581300C16758204C007C006C005C0041217AFD004D005D03A
:20180D0006D007C007C006C005C004125BF6D004D005D006D0071216E98C828D838EF0EF73
:20182D001249D8758201021776E582FF601090F0E4E0FFBFFF00500690F0E4EF04F090F0ED
:20184D00E4E0FFBF18005007900E10E4F5F022BF24005007901C20E4F5F02290518075F03A
:20186D0001E42290F0E0E07875F2E408F2900230125EB57862740EF2E408F2125CDEAE82C8
:20188D00AF8374282EFEE43FFF90F0DFE054077D0025E0FCED33FDEC24CFF582ED34F0F58E
:2018AD0083EEF0EFA3F090F0DFE02401F0227E007F007D00BD0800501DED75F002A424CF2B
:2018CD00F58274F035F0F583E0FBA3E0FCEB2EFEEC3FFF0D80DEEFC423CEC423541F6ECE43
:2018ED00541FCE6ECEFF90F0CCE0FCA3E0FDC3EE9CEF9D50058C828D83228E828F83229075
:20190D00FAB4E0FF3395E0FEC007C0067413C0E0746AC0E01259A9E58124FCF58190F0BF06
:20192D00E0FF7E0090F0C0E0FD3395E0FCC007C006C005C004741EC0E0746AC0E01259A9A2
:20194D00E58124FAF5812275820E124C25124C5175820F124C2590FAB2E0FEA3E0FF74236B
:20196D00C0E08E828F8312482D15817404C0E0124376AC82AD83158190F0EBECF0EDA3F0DD
:20198D00C20A90F0CAE0FEA3E0FFC3EC9EED9F5004D20A803A90F0E7E0FCA3E0FD4C60137F
:2019AD00C3EC9EED9F500C90F0EBECF0EDA3F0D20A801C90F0E9E0FCA3E0FD4C6011C3EC75
:2019CD009EED9F500A90F0EBECF0EDA3F0D20A90F0E9E0C0E0A3E0C0E090F0E7E0C0E0A33D
:2019ED00E0C0E090F0EBE0C0E0A3E0C0E090F0E5E0C0E0A3E0C0E0742FC0E0746AC0E01271
:091A0D0059A9E58124F6F58122B6
:2069FE00536C656570696E6720666F7220256C64206D730A0054656D7020256420430A0010
:206A1E00525353492025642C204C51492025640A00426174745620426F6F742025642C20FF
:1A6A3E006E6F772025642C2054782025642C207570646174652025640A00FE
:0500DC00781074FFF232
:201A1600E58620E0FB225390FD00225380FB0022E58620E0FB004390020022E58620E0FB73
:201A3600004380040022121A92E582600790F96CE0F58222121A5CE582600790F970E0F589
:201A560082227582002290F95BE05407FFBF012890F95CE003035403FFBF031C90F95CE0E9
:201A760023235403FFBF031090F95BE023235401FFBF0104758201227582002290F95BE0C9
:201A96005407FFBF012390F95CE003035403FFBF021790F95CE023235403FFBF030B90F943
:201AB6005BE020E6047582012275820022AFF0AE83E58290FA70F0EEA3F0EFA3F090FA707A
:201AD600E0FDA3E0FEA3E0FF90FA6EE0FBA3E0FC79007A00C3E99BEA9C5052E94A6016E9CA
:201AF600540F6002800F7458C0E0746AC0E01259A915811581C003C004E92DF8EA3EFB8F0B
:201B16000488828B838CF0126223F87C00C000C004745AC0E0746AC0E01259A9E58124FC02
:201B3600F58109B900010AD004D00380A77458C0E0746AC0E01259A91581158122AFF0AEE5
:201B560083E5827812F2EE08F2EF08F27815E4F27B017811C3E2F5F0EB95F050227812E2F8
:201B7600FA08E2FC08E2FFEB2AFAE43CFC8A828C838FF0126223FA7815E22AF20B80D378CF
:201B960012E2FD08E2FE08E2FF8D828E838FF0126223FD7815E2B50503D38001C3E433F5EB
:201BB6008222AFF0AE83E5827817F2EE08F2EF08F2781AE4F27B017816C3E2F5F0EB95F076
:201BD60050227817E2FA08E2FC08E2FFEB2AFAE43CFC8A828C838FF0126223FA781AE22A4F
:201BF600F20B80D37817E2FD08E2FE08E2FF8D828E838FF0781AE2025E9AE5812404F5812F
:201C1600AF82C218C00712501FD0078F82124D81C0071250D4D21812501FD0077E01EE24C3
:201C3600FC5003021D3A90F9DB7414F0C007C00612371C90F9ED74EDF090F9DB124F1BD0A1
:201C560006D007124908AA82AB83ACF0FD90FA7374A62AF0740E3BA3F0E43CA3F0E43DA343
:201C7600F0C006124908AA82AB83ACF0FD90FA73E58124FCF8E0F6A3E008F6A3E008F6A34C
:201C9600E008F6E58124FCF8C3EA96EB0896EC0896ED0896D0064003021D36C007C00612E4
:201CB6005031AD82D006D007C374818DF063F08095F050AD90F971E0FDB507A5C007C00662
:201CD600121A3CAD82D006D007BDEE95C007C006121A5CE582D006D00760867408C0E074CB
:201CF60068C0E074F9C0E090F9461245B715811581158190F95EE0FCA3E0FD90F94EECF024
:201D1600EDA3F08F047D00C004C0057460C0E0746AC0E01259A9E58124FCF5818F828020E1
:201D36000E021C348F057E00C005C006746AC0E0746AC0E01259A9E58124FCF5817582008D
:201D5600E58124FCF5812290F9DB742AF012371C90F9ED74E5F090F9F47482F090F0E3E093
:201D760090F9F5F090F0C0E090F9F0F090F0BFE090F9EFF090FAB4E090F9F1F090F0EBE0FC
:201D9600FEA3E0FF90F9F2EEF0EFA3F090F9F6E4F090624F93FE740193FF90F9F7EEF0EF59
:201DB600A3F090F959E090F9F9F090F0C9E090F9FAF078167415F290F9EE75F000121BB8E0
:201DD60090F9DB024F1BD21812501F12195412190C7F00781BE4F2781BE2B40E0040030298
:201DF6001EBAC007121D5DD007124908AA82AB83ACF0FD74882AF52674133BF527E43CF541
:201E160028E43DF529C007124908AC82AD83AEF0FFC3EC9526ED9527EE9528EF9529D007DE
:201E36004003021EADC007125031AE82D007C374818EF063F08095F050CBC007121A3CAE95
:201E560082D007BEE6BF78117411F290F97175F000C007121B53E582D00760A97408C0E0A7
:201E76007468C0E074F9C0E090F9461245B715811581158190F95E75F000126223FDA3128F
:201E96006223FE90F94EEDF0EEA3F090F0E0EFF090F97175F00022781BE22401F2781BE2B3
:201EB600FF021DED90F0E0740EF090000075F00022D21812501F7F00781CE4F2781CE2B49A
:201ED6000E004003021FAE90F9DB7414F090F9ED74E3F0C00712371C90F9DB124F1BD00750
:201EF600124908AA82AB83ACF0FD74882AF52A74133BF52BE43CF52CE43DF52DC0071249A9
:201F160008AC82AD83AEF0FFC3EC952AED952BEE952CEF952DD0075072C007125031AE820A
:201F3600D007C374818EF063F08095F050CEC007121A3CAE82D007BEE6C278117411F290DC
:201F5600F97175F000C007121B53E582D00760AC7408C0E07468C0E074F9C0E090F9461285
:201F760045B715811581158190F95E75F000126223FDA3126223FE90F94EEDF0EEA3F090B0
:201F9600F0E0EFF090F97175F00022781CE22401F2781CE2FF021ED290F0E0740EF09000A5
:201FB6000075F00022AFF0AE83E582781DF2EE08F2EF08F2781DE22402FA08E23400FB083D
:201FD600E2FC8A828B838CF0126223F52E852E2F75300090FA5CE0F531AE317F00E52FC315
:201FF6009EFEE5309FFF7875EEF2EF08F2900063C004C003C002125EB5AE82AF83D002D061
:2020160003D0048E2F8F3090FA77E52FF0E530A3F0781DE22401FD08E23400FE08E2FF8D7F
:20203600828E838FF0126223FD90F91FE0FFEDB50702800122E52E24D5500122C3E52E9525
:20205600315001227463252FFEE43530FFC374239E74089F500122781DE2FD08E2FE08E289
:20207600FF78117466F28D828E838FF0C004C003C002121B53E582D002D003D00470030239
:20209600212F781DE22403FD08E23400FE08E28D2F8E3090FA77E0FEA3E0FFEE24F3FEEF6C
:2020B60034F0FF8E828F837463C0E0E4C0E0C02FC03012457DE58124FCF5818A828B838C75
:2020D600F0126223FA7F00788A7408F2E408F28A828F83C007C00212615EAD82AE83D002F2
:2020F600D007ED2421FDEE34F9FE5302078AF005F07401800225E0D5F0FBF4FA8D828E8316
:20211600E052028D828E83EAF07477C0E0746AC0E01259A915811581227479C0E0746AC0E5
:20213600E01259A91581158122AF82AE83ADF0FC7820EFF2EE08F2ED08F2EC08F290FA5C38
:20215600E0FB7A0090F91FE0FF7E00C003C002C007C006748AC0E0746AC0E01259A9E58167
:2021760024FAF581D21812501F12490885823285833385F034F53578207977E22414F30803
:20219600E2340009F308E2340009F308E2340009F3900019E4F5F0125ED5AA82AB83AEF034
:2021B600FFEA2532F532EB3533F533EE3534F534EF3535F535124908AA82AB83AEF0FFC307
:2021D600EA9532EB9533EE9534EF9535503C125031AF82C374818FF063F08095F050D612FE
:2021F6001A3CAF82BFE8CE90F97175F000121FBB7F00EF2421FDE434F9FE8D828E83E07053
:20221600060FBF060040EBBF06AB7458C0E0746AC0E01259A915811581C21812501F02505C
:20223600D490F972E4F0A3F090F97175F00022742AC0E0E4C0E0C0E090F9DB12451F1581FF
:202256001581158190F9DB742AF090F940E0600890F9F174E4F0800690F9F174E7F07408B0
:20227600C0E07450C0E074F9C0E090F9E91245B71581158115817408C0E07446C0E074F912
:20229600C0E090F9E11245B715811581158190F9DCE054F84401F090F9DCE054C74440F0B4
:2022B60090F9DDE0440C54CF44C0F090F958E0FF04F090F9DEEFF090F94EE0FEA3E0FF909A
:2022D600F9DFEEF0EFA3F07DF27EF98D828E837411C0E07416C0E074F9C0E01245B71581AA
:2022F600158115817DF27EF97F0078167411F28D828E838FF0121BB890F9DB024F1BE58178
:202316002404F581D21812501F1250D47F00BF1E0040030223F7C007122245D00712490833
:20233600AB82AC83ADF0FE90FA7974642BF0749F3CA3F0740B3DA3F0E43EA3F0C00712508B
:2023560031AE82D007C374818EF063F08095F05051C007121A3CAE82D007BEE8028028BEBC
:20237600E9028005BEEC33802978117403F290F97175F000C007121B53E582D00760239068
:20239600F97175F0008063122237AC82AD83AEF0805890000075F000805090000075F0007C
:2023B6008048C007124908C8E58124FCC8A68208A68308A6F008F690FA79E0FAA3E0FDA30A
:2023D600E0FEA3E0FFE58124FCF8C3E69A08E69D08E69E08E69FD00750030223520F02234D
:2023F60024122237AD82AE83AFF0E58124FCF58122741BC0E0E4C0E0C0E090F9DB12451FEE
:2024160015811581158190F9DB7419F090F9F174EAF07408C0E07450C0E074F9C0E090F925
:20243600E91245B71581158115817408C0E07446C0E074F9C0E090F9E11245B715811581A6
:20245600158190F9DCE054F84401F090F9DCE054C74440F090F9DDE0440C54CF44C0F090F9
:20247600F94EE0FEA3E0FF90F9DFEEF0EFA3F090F958E0FF04F090F9DEEFF090F9DB024F28
:202496001BD21812501F7F00BF1000506CC007122407D00712490885823A85833B85F03C23
:2024B600F53D12490885823685833785F038F539E536C3953AFAE537953BFCE538953CFDA0
:2024D600E539953DFEC3EA94A6EC940EED9400EE94005022C007125031AE82D007C37481F5
:2024F6008EF063F08095F050B9C007121A3CAE82D007BEEBAD220F808F22AF82E4FDCD54C6
:2025160003A2E0CD13CD13A2E0CD13CD13CDFCEF0303543F4DFDEF030354C0FE7F00740188
:202536002DFDE43C8F828E838DF022AD82AE83AFF07C007B00BB040040030225D0C0048B3C
:2025560082C007C006C005C003122510A882A983AAF0FCD003D005D006D0077416C0E0E438
:20257600C0E074F3C0E074F0C0E0888289838AF0EC1206E1E58124FCF5817464C0E074FC41
:20259600C0E090F0FB12488A15811581920ED004300E218D008E018F027408C0E0C000C0DE
:2025B6000190F0F312454B158115811581920E50038C82220B8B0402254B7582FF22AF82B5
:2025D6005307F87E007D00BD0400400302265CC0068D82C007C005122510AA82AB83ACF072
:2025F600FED005D0077416C0E0E4C0E074F3C0E074F0C0E08A828B838CF0EE1206E1E5817F
:2026160024FCF5817464C0E074FCC0E090F0FB12488A158115819228D006302823C006909A
:20263600F108E0FC5304F87B008F027E00ECB50206EBB506028004D0068005D0068E82229E
:202656000D8D060225DD7582FF22122510AC82AD83AEF0FF7416C0E0E4C0E074F3C0E0743D
:20267600F0C0E08C828D838EF0EF1206E1E58124FCF58190F108E0F58222AF828F060EEE70
:2026960024FB50027E00EEB507038E82228E82C007C006122510AA82AB83ACF0FDD006D0D9
:2026B600077416C0E0E4C0E074F3C0E074F0C0E08A828B838CF0ED1206E1E58124FCF581CC
:2026D6007464C0E074FCC0E090F0FB12488A15811581922850A890F108E0FD5305F87C00ED
:2026F600BD789BBC00988E8222122510AC82AD83AEF0FF7404C0E0E4C0E08C828D838EF0F4
:20271600EF12092C15811581227F00BF0400500C8F82C0071226FFD0070F80EF22AF828F3B
:20273600057E00C005C0067499C0E0746AC0E01259A9E58124FCF5818F82122510020A6C6A
:202756007825E4F208F208F208F27B00BB040040030227F58B82C00312251085823E858303
:202776003F85F040F541D0037416C0E0E4C0E074F3C0E074F0C0E0853E82853F838540F04C
:20279600E5411206E1E58124FCF5817464C0E074FCC0E090F0FB12488A15811581920F5004
:2027B6003AC00390F104E0FAA3E0FBA3E0FEA3E0FF7825C3E29A08E29B08E29E08E29FD0E4
:2027D60003501890F1047825E0F2A3E008F2A3E008F2A3E008F290F945EBF00B0227627856
:2027F60025E2F58208E2F58308E2F5F008E222AF82AE83D21090F91FE0FD7C007B007A00CE
:202816008C44EBC454F0C544C4C5446544C54454F0C5446544F545EDC4540F4544F544ED64
:20283600C454F0F543754200300D17782FE542F27470254308F2E4354408F2E4354508F282
:2028560080497810E2F582C007C00612251085824685834785F048F549D006D007741625F1
:2028760046F546E43547F547E43548F548E43549F549782FE5462542F2E547354308F2E539
:2028960048354408F2E549354508F290FA807405F090FA5CE4F090F94004F07829EFF20851
:2028B600EEF27406C0E0E4C0E0C0E090F92112451F15811581158190FA80E0FB14F0EB70BE
:2028D60003022C481010030229977829E2FA08E2FB8A828B8378627463F2E408F2125CDE3B
:2028F600AA8290FA7DEAF07829E2FB08E2FF8B828F8378837463F2E408F2C002126021E553
:20291600828583F0D00245F0600690FA7DEA04F090FA7DE024EA500690FA7D7415F090FA80
:202936005CE0FB7A0090FA7DE0FFC3EA9F50528B067F00788A7408F2E408F28E828F83C0BC
:2029560007C006C003C00212615EAC82AD83D002D003D006D007EC2421FCED34F9FD5306F1
:20297600078EF005F07401800225E0D5F0FBFE8C828D83E0FF42068C828D83EEF00B0A8037
:20299600A4122314AA82AB83AFF0EA4B7003F582220ABA00010B8A828B838FF0126223FEFC
:2029B600A3126223FF4E60428E048F05C3EC9423ED9400501A7877EEF2EF08F2E408F208C3
:2029D600F2900019E4F5F0125ED5124969801BEC24F6FCED34FFFD7F007E008C828D838F10
:2029F600F0EE1217BBD21812501F900122E4F5F012213F78337401F290FA5CE0FF7E0090C1
:202A1600FA7DE0FDC3EE9D505E8F047D00788A7408F2E408F28C828D83C007C006C005C0C2
:202A36000412615EAA82AB83D004D005D006D007EA2421F582EB34F9F5835304078CF005E6
:202A5600F07C017D008006EC2CFCED33FDD5F0F7E0FB7A005204EA5205EC4D60067833E4E9
:202A7600F280040F0E80987833E27003022C0D90FA7DE07875F2E408F2900063125EB5AEF0
:202A960082AF83782DEEF2EF08F290FA8174F3F074F0A3F0E4A3F090FA5CE0704B90F0F33A
:202AB600E0FCA3E0FD7829ECF208EDF290F0F5E0FCA3E0FD782BECF208EDF290FA7EE4F029
:202AD600A3F0782DE2FC08E2FDEC24FCFCED34FFFD782DECF2ED08F290FA81740424F3F0CA
:202AF600E434F0A3F0E4A3F07829E2FC08E2FD782DC3E2F5F0EC95F008E2F5F0ED95F05017
:202B16000A7829792DE2F308E209F37829E2FC08E2FD782DD3E29CF4B3FCB308E29DF4FD69
:202B36007829ECF208EDF275820412177690FA81E0F546A3E0F547A3E0F548AA46AF47787C
:202B56002DE2C0E008E2C0E0C002C007782FE2F58208E2F58308E2F5F008E212081CE581E6
:202B760024FCF5817582041217AF782DE2FA08E2FD7E007F00782FE22AF208E23DF208E2C9
:202B96003EF208E23FF2AD46AE47AF48782DE2F54608E2F547AA46AC47154674FFB546025F
:202BB6001547EA4C60368D828E838FF0126223FCA3AD82AE838C4275430090FA7EE0FAA397
:202BD600E0FC8A4A8C4BAB42AC43EB254AFBEC354BFC90FA7EEBF0ECA3F080B990FA7DE03D
:202BF600FF90FA5CE02FF07829E2FE08E2FF4E60067833E4F2D21090F940E4F07833E270C0
:202C1600030228CD782BE2FE08E2FF90FA7EE0FCA3E0FDEEB50406EFB50502801174B3C004
:202C3600E0746AC0E01259A91581158180047582012275820022AFF0AE83E58290FA88F0F0
:202C5600EEA3F0EFA3F090FA88E0FDA3E0FEA3E00DBD00010E8D828E837408C0E07430C0EF
:202C7600E074F9C0E012454B1581158115819211501490F938E0FCA3E0FDA3E0FEA3E0FFC6
:202C9600EC4D4E4F707490F91FE4F090FA88E0FDA3E0FEA3E0FF74012DFAE43EFBC002C0BB
:202CB6000390F91712444D15811581740D2DFAE43EFB8F048A828B838CF0126223FA90F984
:202CD60020F07411C0E0C005C00690F92F1245B71581158115817408C0E0E4C0E0907000F6
:202CF600E4F5F012092C1581158190F938E0FEA3E0FF90FA86EEF0EFA3F090F938E0FCA3B1
:202D1600E0FDA3E0FEA3E0FFEC4D4E4F7003022DA5C3E49C74109DE49EE49F500B90FA84CE
:202D3600E4F07410A3F0800890FA84ECF0EDA3F0D20D90FA84E0FEA3E0FF8E828F831228F7
:202D560005E582604690F91FE0FF0F90F91FEFF090F938E0FCA3E0FDA3E0FEA3E0FF90FA84
:202D760084E0FAA3E0FB8A008B01E4FAFBECC398FCED99FDEE9AFEEF9BFF90F938ECF0ED13
:202D9600A3F0EEA3F0EFA3F0022D107582002275820122AFF0AE83E58290FA8DF0EEA3F056
:202DB600EFA3F090FA8DE0FDA3E0FEA3E0FF74012DFAE43EFB8F048A828B837408C0E0748E
:202DD60030C0E074F9C0E012454B1581158115819212504090F93DE0FC740E2DFDE43EFEFA
:202DF6008D828E838FF0126223FDECB5052690F938E0FCA3E0FDA3E0FEA3E0FFEC4D4E4FC8
:202E1600601274CBC0E0746AC0E01259A915811581022FB375820412177690F9457834E0B5
:202E3600F290FA8DE0FCA3E0FDA3E0FE740E2CFAE43DFB8E078A828B838FF0126223FA54BF
:202E5600FC60317834E2FB7F00C003C00774DEC0E0746AC0E01259A9E58124FCF58190FA33
:202E76006E7411F0E4A3F08C828D838EF0121AC37834E4F290F945E02401F0FFBF04004010
:202E96000590F945E4F090F945E0FF7834E2B507197582041217AF7402C0E0746BC0E012EB
:202EB60059A915811581758201228F82122510AC82AD83AEF0FF7416C0E0E4C0E074F3C08C
:202ED600E074F0C0E08C828D838EF0EF1206E1E58124FCF5817464C0E074FCC0E090F0FB75
:202EF60012488A158115819212500890F108E054F8708190F945E0FF7810F28F821225108B
:202F1600AC82AD83AEF0FF7404C0E0E4C0E08C828D838EF0EF12092C1581158175820412F9
:202F360017AF7810E2FE7F00C006C007740CC0E0746BC0E01259A9E58124FCF58190F91FEA
:202F5600E4F090FA8DE0FDA3E0FEA3E0FF74012DFAE43EFBC002C00390F91712444D158179
:202F76001581740D2DFAE43EFB8F048A828B838CF0126223FA90F920F07411C0E0C005C0E3
:202F96000690F92F1245B715811581158190F938E0FEA3E0FF90FA8BEEF0EFA3F090F93836
:202FB600E0FCA3E0FDA3E0FEA3E0FFEC4D4E4F700302304AC3E49C74109DE49EE49F500B13
:202FD60090FA84E4F07410A3F0800890FA84ECF0EDA3F090FA84E0FEA3E0FF8E828F83124E
:202FF6002805E582604A90F91FE0FF0F90F91FEFF090F938E0F54CA3E0F54DA3E0F54EA350
:20301600E0F54F90FA84E0FAA3E0FBE4FEFFE54CC39AFAE54D9BFBE54E9EFEE54F9FFF90AE
:20303600F938EAF0EBA3F0EEA3F0EFA3F0022FB3758200227582041217767430C0E074F9A6
:20305600C0E090F0F312444D1581158190F0FB7421F07447A3F0744DA3F07447A3F090F9FF
:2030760041E02401F0A3E03400F0A3E03400F0A3E03400F090F941E0FCA3E0FDA3E0FEA3C5
:20309600E0FF90F104ECF0EDA3F0EEA3F0EFA3F090FA8BE0FEA3E0FF7D007C0090F0FFEE7C
:2030B600F0EFA3F0EDA3F0ECA3F090F93CE090F103F090F93DE090F108F07810E2F582125E
:2030D6002510AC82AD83AEF0FF7416C0E0E4C0E074F3C0E074F0C0E08C828D838EF0EF1254
:2030F600081CE58124FCF5817582041217AF75820122AFF0AE83E58290FA91F0EEA3F0EFFB
:20311600A3F0C20D90FA91E0F553A3E0F554A3E0F555740D2553FAE43554FBAC558A828B68
:20313600838CF0126223FCBC02028024BC0303023490BC10028019BC20028014BC210280C3
:203156000FBCA803023383BCAF0302347002350590FA91E0FFA3E0FEA3E0FD7550907551C5
:20317600FA755200740E2FF553E43EF5548D558553828554838555F0126223FB8550828544
:2031960051838552F0125E9A90FA90E020E203023267758204C007C006C005121776D00519
:2031B600D006D00790FA90E0C423541FFB603CBB0F02806C8553828554838555F012622392
:2031D600F582C007C006C0051225D4AB82D005D006D007BBFF0280488B82C007C006C00573
:2031F6001226FFD005D006D007803574012FF553E43EF5548D558553828554838555F0C0D2
:2032160007C006C005122541AB82D005D006D007BBFF02800B12249778357401F202337D05
:20323600758204C007C006C0051217AFD005D006D0078F828E838DF0122DA9E582600B1266
:20325600249778357401F202337D7835E4F202337D74012FF553E43EF5548D5585535085BC
:2032760054518555528550828551837408C0E07427C0E074F9C0E012454B158115811581EF
:203296009213500B12249778357401F202337D758204C007C006C005121776855382855466
:2032B600838555F0122541AC82758204C0041217AFD004D005D006D007BCFF028051C007C3
:2032D600C006C005C004122497D004D005D006D0078F538E548D55AA53AB547411C0E0C0DF
:2032F60002C00390F92F1245B715811581158190F938E4F0A3F0A3F0A3F090FC63ECF090C2
:20331600FA90E054037824F28C82122733803D741AC0E0746BC0E01259A9158115818F8213
:203336008E838DF0122DA9E582601B1224977810E2FB90FC63F090FA90E054037824F28BA4
:203356008212273380067835E4F2801B90F930E0FAA3E0FBC002C00390F92712444D158146
:20337600158178357401F27835E2F5822290F938E0FAA3E0FBA3E0FEA3E0FFEA4B4E4F7007
:203396002F74012553FDE43554FEAF558D828E837408C0E07430C0E074F9C0E012454B154B
:2033B6008115811581921350071224977582012290F91FE4F090FA91E0F550A3E0F551A33F
:2033D600E0F55274012550FAE43551FBC002C00390F91712444D15811581740D2550FDE49C
:2033F6003551FEAF528D828E838FF012622390F920F0AD50AE517411C0E0C005C00690F92E
:203416002F1245B715811581158174092550FDE43551FEAF528D828E838FF0126223FDA369
:20343600126223FE8D828E83122805E582602790F938E4F0A3F0A3F0A3F0758204121776AC
:2034560090F0F775F0001213CB7582041217AF1224977582012275820022122497740E2543
:2034760053FDE43554FEAF558D828E838FF0126223F58212045A75820122758204121776A6
:203496008553828554838555F0122C4CE582605B122497758204121776123520300D1112BC
:2034B6003A8A907019E4F5F01206C112557980567422C0E0746BC0E01259A9158115817557
:2034D60082041217AF90FA5B7401F090F0E374E0F0123B037408C0E0E4C0E0C0E090F92747
:2034F60012451F158115811581801B758200227F00C004C007743FC0E0746BC0E01259A9DA
:20351600E58124FCF58175820022783AE4F208F208F208F2C20D7419C0E0E4C0E074A2C0B4
:20353600E074FDC0E0907000E4F5F01206E1E58124FCF58178367419F2747008F2E408F2DD
:2035560008F290FDAAE0FFBF0102800790F08F7401F022906251E493FD740193FE740293A0
:203576007409C0E0C005C00690FDAB12454B1581158115819214500790F08F7402F02290CD
:20359600FDA8E0FEA3E0FFC3E49E74809F500790F08F7403F02290FDA8E0FEA3E0FF4E70F6
:2035B6000302366890FDA8E0FEA3E0FFC374239E74089F50047E237F08C006C00774F3C07A
:2035D600E074F0C0E07836E2F58208E2F58308E2F5F008E21206E1E58124FCF58190FA94BC
:2035F60074F3F074F0A3F0E4A3F090FA97EEF0EFA3F0783AE2F58208E2F58308E2F5F0082B
:20361600E2C007C006123741783AC0E0E582F2E58308F2E5F008F2D0E008F2D006D0078EDA
:20363600028F037C007D007836E22AF208E23BF208E23CF208E23DF290FDA8E0FCA3E0FD62
:20365600ECC39EFEED9FFF90FDA8EEF0EFA3F00235AC90FDA2E0FCA3E0FDA3E0FEA3E0FF78
:20367600783AE2B5041108E2B5050C08E2B5060708E2B50702800790F08F7404F02290FD25
:20369600A6E0FEA3E0FF90F08DEEF0EFA3F0C006C007745FC0E0746BC0E01259A9E5812484
:2036B600FCF581D20D22122756AC82AD83AEF0FF90F941ECF0EDA3F0EEA3F0EFA3F0227438
:2036D60008C0E07450C0E074F9C0E090FA661245B715811581158190FA5DE054F84421F093
:2036F60090FA5EE054F344C8F090FA607437F07413A3F090FA6274FFF0A3F090FA6474378F
:20371600F07413A3F0227411C0E0745DC0E074FAC0E090F9DC1245B715811581158190F905
:2037360058E0FF04F090F9DEEFF022AC82AD83AEF0FF783EECF4F2EDF408F2EEF408F2EFB7
:20375600F408F290FA94E0F55EA3E0F55FA3E0F56090FA97E0F55AA3E0F55B855A5C855B27
:203776005D155A74FFB55A02155BE55C455D700302383F855E82855F838560F0126223FE6E
:20379600A385825E85835F8E047D007E007B00783EE26CF208E26DF208E26EF208E26BF2CC
:2037B6007846E4F208F27846C3E2940808E26480948050A7783EE25401FA08E25400FB0865
:2037D600E25400FC08E25400FE7842C3E49AF2E49B08F2E49C08F2E49E08F27841E2C31398
:2037F600F56418E213F56318E213F56218E213F5617842E25420FC08E25483FD08E254B86E
:20381600FE08E254EDFA783EEC6561F2ED656208F2EE656308F2EA656408F27846E2240145
:20383600F208E23400F20237BC783EE2F4FB08E2F4FC08E2F4FD08E2F48B828C838DF022A6
:206A58000A002530327820004150206F6E2025640A004E6F204150206F6E2025640A002E68
:206A780000636865636B435243206661696C65640A00524551202564207061727420256488
:206A98000044726177696E6720696D61676520696E20736C6F742025640A00626C6B2066A4
:206AB80061696C65642076616C69646174696F6E210A0072657374617274696E6720696D10
:206AD8006720646C0A004368616E67696E67207374617274696E67536C6F742066726F6D1C
:206AF80020256420746F20300A004E6F20736C6F74730A006E657720646C20746F20256476
:206B18000A00646C20696D670A004F544120696D6167652076616C69646174696F6E206644
:206B380061696C65640A00646174615479706520307825782069676E6F7265640A004368D6
:206B5800726F6D613239004F54412076616C6964617465642C207570646174696E67207415
:0F6B78006F2076657273696F6E202530780A0082
:0575F200FF21474D4799
:20385600E58620E0FB225390FD00225380FB0022E58620E0FB004390020022E58620E0FB15
:2038760000438004002290F09B7438F0E4A3F030050990F09B7430F0E4A3F02290F959E0D3
:20389600704590F0C7E0603FC20490F09F7410F0C4A3F090F0A17406F0E4A3F09071597516
:2038B600F080120D72D20490F09F7418F07401A3F090F0A1740DF0E4A3F090717B75F0800E
:2038D600120D72D2038002C203300A2690F0C6E06020C20490F09F7410F0C4A3F090F0A14E
:2038F6007470F0E4A3F090718575F080120D72D20222C20222123E4474ACC0E07471C0E0B6
:203916001240F31581158174BFC0E07471C0E01240F31581158190F09BE0FEA3E0FF740860
:203936002EFEE43FFF90F09BEEF0EFA3F074D2C0E07471C0E01240F31581158174F5C0E0C3
:203956007471C0E01240F3158115817417C0E07472C0E01240F31581158190F09BE0FEA39D
:20397600E0FF74082EFEE43FFF90F09BEEF0EFA3F090F09DE4F0A3F074A7C0E07471C0E049
:203996001240F3158115810239C0758205123E21E5826001227435C0E07472C0E01259A96B
:2039B6001581158190390B020D4C7436C0E074FCC0E0E4C0E07441C0E07472C0E01240F398
:2039D600E58124FBF5812290624FE493C0E0740193C0E0744DC0E07472C0E01240F3E58122
:2039F60024FCF58122123E44123E60745CC0E07472C0E01240F3158115811239DD90F0E5C1
:203A1600E0C0E0A3E0C0E0746DC0E07472C0E01240F3E58124FCF58190FAB4E0FF3395E0E0
:203A3600FEC007C006747BC0E07472C0E01240F3E58124FCF5810239C0758201123E21E546
:203A5600826001221219549039FB020D4C123E44123E60C20512387C90F08DE0C0E0A3E0CC
:203A7600C0E0748EC0E07472C0E01240F3E58124FCF58122903A63020D4C123E44123E6039
:203A9600D20574A4C0E07472C0E01240F315811581D20490F08FE0FFBF02028018BF0402A6
:203AB6008023BF053074B5C0E07472C0E01240F3158115812274C4C0E07472C0E01240F3D4
:203AD600158115812274D5C0E07472C0E01240F315811581227E00C007C00674E0C0E0740D
:203AF60072C0E01240F3E58124FCF58122903A90020D4C123E44123E6074EFC0E07472C099
:203B1600E01240F3158115817407C0E07473C0E01240F31581158190F09BE0FEA3E0FF9020
:203B3600F0A1EEF0EFA3F090F94CE0FF7E0090F94DE0FD7C00C007C006C005C0047420C0B3
:203B5600E07473C0E01240F3E58124FAF58190F94AE0FF7E0090F94BE0FD7C00C007C006BF
:203B7600C005C0047432C0E07473C0E01240F3E58124FAF58190F948E0FF7E0090F949E0BA
:203B9600FD7C00C007C006C005C0047432C0E07473C0E01240F3E58124FAF58190F946E0C5
:203BB600FF7E0090F947E0FD7C00C007C006C005C0047432C0E07473C0E01240F3E5812497
:203BD600FAF58190F099E0FEA3E0FF8E02EFFB3395E0FCFD7428C39AF50F74019BF510E4D5
:203BF6009CF511E49DF512906EADE493FDE4FC3395E0FBFAE50FC39DFDE5109CFCE5119B7A
:203C1600FBE5129AFA78647402F2E408F208F208F28D828C838BF0EAC007C006125D29AAA0
:203C360082AB83D006D00790F09FEA2EF0EB3FA3F090F0BFE0FF7E0090F0C0E0FD3395E0CC
:203C5600FC90F959E0FB7A00C007C006C005C004C003C002743BC0E07473C0E01240F3E580
:203C76008124F8F581123EE10239DD758203123E21E582600122121954903B09020D4C12BD
:203C96003E44123E607455C0E07473C0E01240F3158115817468C0E07473C0E01240F3151E
:203CB60081158190F099E0FEA3E0FF90FA99EEF0EFA3F090F09BE0FEA3E0FF90F0A1EEF061
:203CD600EFA3F0747DC0E07473C0E01240F31581158190FA99E0FEA3E0FF8E02EFFB3395FE
:203CF600E0FCFD74F0C39AFAE49BFBE49CFCE49DFD78647402F2E408F208F208F28A828BF9
:203D1600838CF0EDC007C006125D29AA82AB83D006D007EA2EFEEB3FFF90F09FEEF0EFA3A7
:203D3600F0EE5407601574075EFC7D00EEC39CFEEF9DFF90F09FEEF0EFA3F0906EAD75F008
:203D560080120D7290F0A1E0FEA3E0FF74082EFEE43FFF90F0A1EEF0EFA3F0D20490703763
:203D760075F080120D72023892758204123E21E582600122903C95020D4C123E44123E6095
:203D960090F09BE0FEA3E0FF74102EFEE43FFF90F09BEEF0EFA3F07491C0E07473C0E01207
:203DB60040F315811581123EE1023892758205123E21E582600122903D90020D4C123E44EE
:203DD600123E6074A1C0E07473C0E01240F31581158174B5C0E07473C0E01240F315811530
:203DF6008190F09F747CF0E4A3F090F09BE0FEA3E0FF90F0A1EEF0EFA3F0D2049070377538
:203E1600F080020D72903DD3020D4CE582C40354F8F5821225D4AF82BFFF02800D7824E4A6
:203E3600F28F821227337582012275820022C206C204C20590F099E4F0A3F090F09DF0A345
:203E5600F090F09BF0A3F0C20922D20490F0A1E4F0A3F0906D2A93FF7E007428C39FFF74CB
:203E7600019EFE90F09FEFF0EEA3F0906D2975F080120D72C204906B88E493FF7E0090F0B7
:203E96009FE0FCA3E0FDECC39FFFED9EFE90F09FEFF0EEA3F0906B8775F080120D72906DC7
:203EB600ECE493FF7E0090F09FE0FCA3E0FDECC39FFFED9EFE90F09FEFF0EEA3F0D20490D6
:203ED6006DEB75F080120D72C2042290F0E9E0FEA3E0FF4E601190F0E7E0FCA3E0FDC3EE1A
:203EF6009CEF9D5002800890F0E7E0FEA3E0FFC006C00774CFC0E07473C0E01240F3E58141
:053F160024FCF58122EE
:206B8700801AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000000064
:206BA7000000000000000000000000000000000000000000000000000000000000000000CE
:206BC7000000000000000000000000000000000000001C000000001F9F80000000003870AC
:206BE70001C07F000000001F9FC000000000387001C07F000000001F9FE0000000003870A2
:206C070001C0F7800000001C1CE000000000380001C0E3800000001C1CE000000000380071
:206C270001C0E39DC1C7701F9CE773B871D03873B9C7E39FE3E7F81F9FEFF3FCF9F0387367
:206C4700FDCEE39FE777F81F9FCFF3FDDDF03873FDDCE39CE7F7381C1F8E739DFDC03873E6
:206C67009DF8E39CE7F7381C1C0E739DFDC038739DF8F79CE707381C1C0E739DC1C0387355
:206C87009DDC7F1FE7F7381F9C0FF3FDFDC03F739DDC7F1FE3E7381F9C0FF3FCF9C03F735A
:206CA7009DCE1E1DC1C7381F9C0773B871C03F739DC7001C00000000000003800000000094
:206CC7000000001C0000000000000380000000000000001C0000000000000380000000006F
:206CE7000000001C00000000000003800000000000000000000000000000000000000000EE
:206D0700000000000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFF7A
:206D2700FFFF800C000882A2AB55BFFFFFFF7DB4622800000010101176FF7BFFFF7FB7A921
:206D470055505100002922966FF7BFFFFFFFEAE622AA08000002542ABF3F7FFFFFFFFD593F
:206D6700B4102000002423B5B5DFFFFFFFFFF6AE48551000008890546AEFFFFFFFFFFBF59A
:206D8700A382000000012DA3B3FFFFFFFFFFF6BE4E5209000490020D55DFFFFFFFFFFDDD3E
:206DA70068A9001000490CFBAB6FFFFFFFFFFEEB955A002000129122BFDFFFFFFFFFFFF5FA
:206DC700658140400028127DEFFFFFFFFFFFFFEFAB28000000420A9775FFFFFFFFFFFFF79B
:206DE7004AC20400800C0008029CDFFFFFFFFFFFFF6A6A8D002000044D72AAFFFFFFFFFF88
:206E0700FFD5D57480000240128EDFFDFFFFFFFFFFAEAA0A11200020525FF57FFFFFFFFF41
:206E2700FF7294AA240000010AAB6F77FFFFFFFFFDAF545488000004804D95EBFFFFFFFFB7
:206E47005B58B5514000000808A6B3F77FFFFFFFFFAD4AA0100000029641DCAEFFFFFFFF51
:206E6700FDBFEA4802000000093EAB75EFFFFFFFFFD4B121080000000AC35DFF7FFFFFFF76
:206E8700EFEF444A64800000A152A6EFEFFFFFFFD6CAF5101800000002154BD5DFFFFFF75F
:206EA700EBD4D885000038380000000000000000000000000000000000000000000000003F
:206EC7000000000000000000000000000000000007C00000000001FFF0000000000FFFF0F6
:206EE700000000007FFFF000000001FFFFF000000007FFFFC00000001FFF80000000007F4C
:206F0700F80000000000FFE00000000001FF000000000007FE00000000000FF80000000087
:206F2700001FE000000000003FC00003E000007F80007FF00000FE0003FFF00001FC000FFF
:206F4700FFF00001F8003FFFF00003F800FFFF800007F001FFE000000FE003FF0000000FC4
:206F6700C00FF80000001F801FF00000001F803FC00000003F003F800000003F007F00003B
:206F870000007E00FE0007E0007E01FC001FF000FC01F8007FF000FC03F001FFF000F803BF
:206FA700F003FFF001F807E007FF0001F807E00FF00001F00FC01FE00001F00FC03F8000E5
:206FC70003F00F803F000003F01F807E000003E01F807E000003E01F00FC01E003E01F00F8
:206FE700FC07F803E01F00F80FFC03E03F00F80FFC03E03F01F81FFE03E03F01F81FFE03F2
:20700700E03F01F81FFE03C03E01F01FFE01C01E00F00FFC00000000000FFC000000000040
:2070270007F8000000000001E000000000000000303000001FF800000000FFFF00000003F1
:20704700FFFFE000000FFFFFF000003FFFFFFC00007FF00FFE0000FF8001FF0001FE00001B
:207067007F8003F800001FC007F000003FE00FE000007FF00FC00000FFF01F800001FFF867
:207087001F000003FFF83F000007FEFC3E00000FFC7C7E00001FF87E7C00003FF03E7C0053
:2070A700007FE03EFC0000FFC03FF80001FF801FF80003FF001FF80007FE001FF8000FFC63
:2070C700001FF8001FF8001FF8003FF0001FF8007FE0001FF800FFC0001FFC01FF80003F0F
:2070E7007C03FF00003E7C07FE00003E7E0FFC00007E3E1FF800007C3F3FF00000FC3F7F0E
:20710700E00000FC1FFFC00001F80FFF800003F00FFF000007F007FE00000FE003FC00003C
:207127001FC001FE00007F8000FF8001FF00007FF00FFE00003FFFFFFC00000FFFFFF0003A
:207147000003FFFFE0000000FFFF000000001FF800001010000000000000000000007C0096
:207167008200000038004407007903811C0103810079000708080063773E1C3E7763101069
:20718700000003C00FF0081008100810081008100810081008100BD00BD008100FF0000099
:2071A7000A000A0A0009084F70656E4550617065724C696E6B0A08006F70656E65706170D2
:2071C70065726C696E6B2E64650A0049276D0920666173742061736C656570202E202E2018
:2071E7002E20746F2077616B65206D653A000A52656D6F7665206261747465726965732CDC
:207207002073686F727420626174746572790A00636F6E74616374732C207265696E7365C1
:207227007274206261747465726965732E004465657020736C6565700A00546167204D41C5
:20724700433A202573004368726F6D613239207625303458005374617274696E67202E20FC
:207267002E202E0A0A000A564261743A202564206D560A0054656D70657261747572653A68
:20728700202564430A0A000C466C617368696E67207625303478202E202E202E000C4F547F
:2072A70041204641494C4544203A280A0A000C4E6F74204F544120696D616765000C5772F2
:2072C7006F6E67204F544120696D616765000C435243206572726F72000C4572726F7220D8
:2072E700436F64652025640057616974696E6720666F722064617461202E202E202E0A007B
:207307000A466F756E642074686520666F6C6C6F77696E672041503A000A4150204D414397
:207327003A202530325825303258002530325825303258000A43683A202564205253534977
:207347003A202564204C51493A2025640A00084E6F20415020666F756E64203A280A080A00
:20736700005765276C6C2074727920616761696E20696E2061000A6C6974746C652077689D
:20738700696C65202E202E202E00087A7A5A5A5A202E202E202E0A080A000C454550524F2B
:2073A7004D204641494C4544203A280A0A000C536C656570696E6720666F726576657220A2
:1573C7002E202E202E0A0A00564261743A202564206D560A0096
:203F1B00C007C006C005C004C00390FAA2E0600302400F90FAA3E0FF24FB500302400CEF32
:203F3B002F2F903F4173023F50023F6E023FEF02400602400C90FAA0744BF0E4A3F090FAA5
:203F5B00A2740BF090FAA37401F090FAA47468F002400F90FA9D124837E582FF6045EF2482
:203F7B00E0FFBF600040027F1F90FAA5E0FE0E90FAA5EEF0C0078E82124361AD82AE83151E
:203F9B008190FAA4E0FC7B002DFDEB3EFE8D828E837467C0E0124832AE82158190FAA4EEA6
:203FBB00F0800B90FAA37402F090FAA4E0FFEF75F002A424DCF582747335F0F583E493FE61
:203FDB00A3E493FF90FAA0EEF0EFA3F090FAA2740BF0802090FAA37403F090FAA074E3F0E3
:203FFB00741AA3F090FAA203F0800990FAA37404F0C3802D90FAA0E0FEA3E0FFEE540124E7
:20401B00FFE433FDEFC313CE13CEFF90FAA0EEF0EFA3F090FAA2E0FF1F90FAA2EFF0ED242F
:0C403B00FFD003D004D005D006D007222F
:2073DC009B01B3013303C90089019101990019013101930013012301CD01D90199039D0194
:2073FC00B90139037302D30193033B017301B7039701A7012703370167016702DB001B03C6
:20741C006303C500D10011038D00B10031028B00A3002302ED008D03B103DD001D037103DA
:20743C0077038B03A303BB003B02BB03D70017034703B7003702C702F70213028F026500D4
:20745C00850169000903A10121034D000D01590019026101610243025300EF024301F102FB
:20747C00E501E901C9033D01790179022F014F014F02DB037B036F03F500C503D103BD0034
:0E749C003D02AF002F02DD03BD03D703AF0397
:20404700C007C006C005C004C001C000AC82AD83AEF0FFBF20005031BF0A030240E68F8262
:20406700C007C006C005C004C003C002C001C000C02512422ED025D000D001D002D003D0AB
:2040870004D005D006D00780567E00EF24E0FFEE34FFFEEF2FFFEE33FEEF242CF582EE341A
:2040A70063F583E493A3E493C4540FFE90F0B3EEF0300507EE2EFE90F0B3F090F0B3E0FFCC
:2040C7003395E0FE0FBF00010E90F099E0FCA3E0FDEF2CFFEE3DFE90F099EFF0EEA3F0D055
:2040E70000D001D004D005D006D00722C007C006C005C004C003C001C000E58124F6FFC0D7
:2041070007C006C005C004C003C002C001C000C0251241E1D025D000D001D002D003D00414
:20412700D005D006D007E58124F6F886050886068D828E83E493FCBC0C7290F099E4F0A302
:20414700F0C007C005C006C0E0C0E0904047125658E58124FBF58190F099E0FDA3E0FE335A
:2041670095E0FCFB7428C39DFD74019EFEE49CFCE49BFB78647402F2E408F208F208F28D29
:20418700828E838CF0EBC007C002C001C000C025125D29AB82AC83ADF0FED025D000D0010A
:2041A700D002D00790F099EBF0ECA3F0C007E58124F5F8E6C0E008E6C0E0E4C0E0C0E090D6
:2041C700109A125658E58124FBF581D000D001D003D004D005D006D00722300625300506F1
:2041E7007E147F0080047E0A7F0090F0B4EEF03005067E207F0080047E107F0090F0B3EE00
:20420700F0223005067E207F0080047E107F0090F0B4EEF03005067E147F0080047E0A7FB3
:204227000090F0B3EEF022AF82BF08028018BF0902804EBF0A028013BF0B028055BF0C014F
:2042470022BF0D568038B2050241E11241E190F0B4E0FE3395E0FD90F09BE0FBA3E0FCEE32
:204267002BFEED3CFD90F09BEEF0EDA3F090F09DE0FDA3E0FE90F099EDF0EEA3F022B204A5
:204287002290F099E0FDA3E0FE90F09DEDF0EEA3F02290F09DE4F0A3F0227E00C007C00630
:1242A70074AAC0E07474C0E01259A9E58124FCF581228D
:1574AA00496E76616C69642063686172203078253032780A0077
:2042B900E58620E0FB225390FD00225380FB0022E58620E0FB004390020022E58620E0FBA8
:2042D90000438004002275FB02228582F9E5F830E1FB53F8FDE5F820E0FB85F9822253F3D7
:2042F900C775FA2275FC0C75F8C043F4C043F102D20B2253F1FD53F43F75FA0075FC31752A
:08431900F84043F338C20B2207
:20432100858283D0F0D0E0D082C082C0E0C0F022C00074FB2581F8E58286820886830886A1
:20434100F0D0002275F008C58213C58233D5F0F7C58222E583A2E713F583E58213F5822285
:20436100D083D0E0D0F0C0F0C0E0C083E582A4F58285F08322C000E58124FDF8E6F8858226
:20438100F0A4F582E8A8F08583F0A428F583E5F03400F5F0E4D00022C000C001C0E0C0F0C0
:2043A10074FA2581F88600E58288F0A4F582A9F0E58388F0A429F583E5F03400F9D0E08878
:2043C100F0A429C5F03400F9D0E0C0F088F0A429D0F0D001D00022C000C001C002E5812448
:2043E100FBF8E6F918E6F88582F0A4C0E0AAF0E58388F0A42AF8E5F03400FAE98582F0A4F2
:2044010028C0E0E5F03AFA74003400F8E98583F0A42AFAE5F0388AF0D083D082D002D001B2
:20442100D00022D0E0D0F0C000C001C002C0F0C0E074F82581F9E7F809E7F922D002D001EE
:20444100D00022C9C583C9C8C582C82212442475F008124444E0A3124444F0A3D5F0F302AB
:20446100443D12442475F008124444E493A3124444F0A3D5F0F202443D124424C375F0080E
:20448100124444E0A3F502124444E03AF0A3D5F0EF02443D12442475F008124444E0A3F590
:2044A10002124444E05AF0A3D5F0EF02443D124424C375F008124444E0A3F502124444E023
:2044C1009AF0A3D5F0EF02443D124424C375F008124444E0A3F502124444E0A39AD5F0F04D
:2044E10002443D12442475F008124444E0A3F502124444E0A36A7007D5F0EED302443DC373
:2045010002443DC8C0E075F008E038F0A3D5F0F9D00022D3E4024504C374FF024504C000A4
:20452100C00174FA2581F8E6F5F0088601496015088600E8F0A374FF25F0F5F074FF39F57E
:204541000145F070EED001D00022C000C001C00274F92581F9E7D3601CF5F0098700098779
:2045610001C3E0F502A3124444E0A31244446A7004D5F0EED3D002D001D00022C000C001CB
:20458100C00274F82581F9E7F5F00987024A601F098700098701124444E0A3124444F0A3BB
:2045A10074FF25F0F5F074FF3AF50245F070E7D002D001D00022C000C001C00274F9258172
:2045C100F9E76015F5F0098700098701124444E0A3124444F0A3D5F0F3D002D001D00022E8
:2045E100C083C082E06003A380FAC3E582D0F095F0F582E583D0F095F0F58322C003C00223
:20460100C001C000C0E0C0F0C083C082A98174F62581F886F0188600750201750300758216
:2046210011A2F74014C3E833F8E5F033F5F0C3EA33FAEB33FB058280E8E4C003C002C0E0CD
:20464100C0E0AA81C0F0C000C0E0C0E0A881C0E0C0E0C0E0C0E0AB81C000C001C3758304C9
:2046610086F018E71995F0D583F6D001D000402BC000C001C375830486F018E795F0F71982
:20468100D583F585020085030175830486F018E745F0F719D583F5D001D00074FC28F8C3C5
:2046A10075830408E613F6D583F9C00074FC2AF8C375830408E613F6D583F9D000D582989D
:2046C10020D508D082D083D0F0D00074F42581F58130D508D082D083D0F0D000E8D000D059
:2046E10001D002D00322C2D50245FDD2D50245FDC003C002C001C000C0E0C0F0C083C08250
:20470100A98174F62581F886F07401758219A2F7400A23C5F023C5F0058280F2C0E0E4C09B
:20472100E0C0E0C0E0AA81C0F0C0E0C0E0C0E0A881C0E0C0E0C0E0C0E0AB81C000C001C384
:2047410075830486F018E71995F0D583F6D001D000402BC000C001C375830486F018E795A5
:20476100F0F719D583F585020085030175830486F018E745F0F719D583F5D001D00074FCC7
:2047810028F8C375830408E613F6D583F9C00074FC2AF8C375830408E613F6D583F9D000C8
:2047A100D58298D082D083D0F0D00074F42581F581E8D000D001D002D00322C006C005C0B5
:2047C10004C003C002C001C00074F72581F886F074017C09A2F7400923C5F023C5F00C8037
:2047E100F3FBE4FAA9F0F88582F0FDFEC3E58298E583994011C3E58298F582E58399F583A3
:20480100EA4DFDEB4EFEC3E913F9E813F8C3EB13FBEA13FADCD620D5048D828E83D000D063
:2048210001D002D003D004D005D00622C2D50247BCD2D50247BCE0C0E02401F0A3E0C0E030
:204841003400F0A3E0D083D0826014B4600AC000A882E2D000F582224009E493F58222E00B
:20486100F58222C000A882E6D000F5822212442475F004D3124444E0FA3400F0EAA3124434
:2048810044F0A3D5F0EE02443D12442475F004C3124444E0FAA3124444E0A36A7004D5F08D
:2048A100EFD302443D124424C3E0A398E0A399E0A39400E0A3940002443D124424C3E0A3CD
:2048C10038E0A339E0A33400E0A3340002443D75F004E07004A3D5F0F9F58222A3A3A3E072
:0248E100332280
:0448E30075C90B2266
:2048E700C0E0C007C006C0D075D000AEDAAFDB74012EF5DAE43FF5DBD0D0D006D007D0E03B
:2049070032C007C006C005C004C000AEDAAFDB784AEEF208EFF27848E5E2F27849E5E3F2F7
:20492700EEB5DAE7EFB5DBE37848E2FC08E2FD08E2FE08E28C828D838EF0D000D004D0053E
:20494700D006D0072285E28222E4F5DAF5DBF5E4F5E5F5E6F5E7F5E275E40543D84043B8FE
:204967000222AF82AE83ADF0FC784CEFF2EE08F2ED08F2EC08F21249087850C0E0E582F293
:20498700E58308F2E5F008F2D0E008F2124908AA82AB83AEF0FF7850D3E29AF4B3FAB30868
:2049A700E29BF4B3FBB308E29EF4B3FEB308E29FF4FF784CC3E29A08E29B08E29E08E29F29
:0349C70050CA22B1
:2049CA0053C07F53A1FE53BEFC3243870122AF82AE83ADF0FC7854EFF2EE08F2ED08F2ECBA
:2049EA0008F290FAA6E4F090FAA7F090FAA874DFF090FAA974BEF090FAAAE054E0F090FA02
:204A0A00AAE0541FF090FAAB7407F090FAACE054E0F090FAACE0549F4420F090FAACE054FE
:204A2A007FF090FAADE054FC4402F090FAADE054FBF090FAADE054F7F090FAADE054CFF08E
:204A4A0090FAADE0543F4440F07854E2F5F008E242F008E242F008E245F0701B7B017513B5
:204A6A006F7514FC85141590FAA6E515F07A6F90FAA7EAF0024B0C7854C3E2943F08E29461
:204A8A000008E2940008E29400500C7854743FF2E408F208F208F27854E225E0F51608E2C9
:204AAA0033F51708E233F51808E233F519E5162516F516E51733F517E51833F518E519336E
:204ACA00F519747DC0E0E4C0E08516828517838518F0E5191246E77854C0E0E582F2E58376
:204AEA0008F2E5F008F2D0E008F2158115817B007D687EFC8E0590FAA6EDF07E6890FAA77C
:204B0A00EEF053C07F53A1FE43A11075A8A0EB70147854E2F5F008E242F008E242F008E254
:204B2A0045F070012253BEFBE5BE30E5FBE5C654384441F5C6E5C630E6FB43BE0453C67F14
:204B4A007854C3E2F5F074F095F008E2F5F074FF95F008E2F5F0E495F008E2F5F0E495F0D5
:204B6A00501B7DF07EFF7854E22410F208E23400F208E234FFF208E234FFF280117854E295
:204B8A00FD08E2FE7854E4F208F208F208F2EB60067A007C0080047A107C008AA175C00065
:204BAA0043D6817AA67CFA8AD48CD575D60175A204E5A570FC75A2028EA48DA3AEA5EEB52E
:204BCA00A50280FA43C702EB60077B0075BE07800375BE06000000E5BE5403600875D7012C
:204BEA00004387010053C7FDE5BE30E5FB75BE00E5BE30E5FB75C679E5BE30E6FB7E007DCD
:1B4C0A0000000DBD80FB0EBE80F575C639E5C620E6FB75C63875BE04024B18DA
:0E75F700060606060606040707070707070430
:204C2500AF8275BB0074304FF5B575B473E5B420E6FBE5B430E7FBAEBA7F00ADBB7C009035
:204C4500FAB2EC4EF0ED4FA3F08FB522C21590FAB2E0FEA3E08E82C4C582C4540F6582C5E2
:204C650082540FC5826582C582F58374E2C0E07404C0E01243D8AC82AD83AEF0FF1581157C
:204C85008190FAB0E0FAA3E0FB74FFC0E07407C0E08A828B831243D8A882A983AAF0FB1587
:204CA500811581ECC398FCED99FDEE9AFEEF9BFF747DC0E08C828D838EF0EF124399AC82CB
:204CC500AD83AEF0FF1581EFC40354F8CEC403CE6ECE54F8CE6EFFEDC40354074EFEEDC438
:204CE5000354F8CCC403CC6CCC54F8CC6CFDEF30E70FD215C3E49CFCE49DFDE49EFEE49F8C
:204D0500FF90FAAEE0C0E0A3E0C0E08C828D838EF0EF1246E7AC82AD83AEF0FF15811581C3
:204D250074FF2CFC74033DFDE43EFEE43FFF74FFC0E07407C0E08C828D838EF0EF1246E7E8
:164D4500AC821581158190FAB4ECF030150790FAB4C3E49CF02205
:204D5B00E58620E0FB225390FD00225380FB0022E58620E0FB004390020022E58620E0FBFB
:204D7B00004380040022C007C006AF82BF64004027BF6A00502290DF097421F090DF0A7462
:204D9B003BF090DF0B7413F08F06EE249CFE90DF0675F003A4F0802F90DF097422F090DF0E
:204DBB000A74BBF090DF0B7413F0BFC8004013BFE100500EEF2438FF90DF0675F00CA4F022
:204DDB00800590DF06E4F0D006D00722C00775E10490DF3BE0B401FCD00722124DE77F0001
:204DFB008F057EDFEFC39074BF938D828E83F00FBF200040EB90DF237488F090DF247431C0
:204E1B00F090DF257409F090DF2E748EF075911075ED00759D0075EF0322C007AF82C3EF3A
:204E3B006480946250047FE2800EC3748A8FF063F08095F050027F0A741E2FC3139074DF4D
:204E5B009390DF2EF0D00722C007C006AE82AF838ED48FD575D6010000000000000000001D
:204E7B00D006D0072275D68100000000000000000022C007C006C005AE82AF83124E808F37
:204E9B000590FC78EDF090FC79EEF07E767FFC8E828F83124E63D005D006D00722C007C0AF
:204EBB0006C005AE82AF83124E808F0590FC7EEDF090FC7FEEF07E7E7FFC8E828F83124E6D
:204EDB0063D005D006D00722301604E5EF700122124DE753C0FE43B801E5ED75F080A4242D
:204EFB00B6F58274FA35F0F583124E8D75E1022253B8FE124E80124DE775D10053C0FE2250
:204F1B00AE82AF837CFF7DFF124F0B8E828F83124EB875E90075E103E5E920E42375820FC5
:204F3B00C005C004124C25D004D00590FAB2E0FEA3E0FFC3EE9CEF9D50DE8E048F0580D880
:204F5B00124E80C005C004124EE3D004D0057423C0E08C828D8312482D15817404C0E01245
:204F7B004376AC82AD83158190F0E7ECF0EDA3F022C025C0E0C0F0C082C083C007C006C07D
:204F9B0005C004C003C002C001C000C0D075D000E5D130E040E5ED75F080A424B6FE74FAAB
:204FBB0035F0FF53D1FE8E828F83E0FD248240200D0DED2EF582E43FF583E0FF30E711E558
:204FDB00ED04FF8FEDBF030375ED00E5EF14F5EF124EE3800F74F4C0E07474C0E01259A9E1
:204FFB001581158153C0FED0D0D000D001D002D003D004D005D006D007D083D082D0F0D0E8
:20501B00E0D02532201806124F0BC21622201605D216024EE322E59D75F080A424B6FE74FB
:20503B00FA35F0FF8E828F83E0FD7403B5EF047582FF228D037C0074022BF9E43CFAE92E2A
:20505B00F582EA3FF583E0FA747F5AD39494F4FABA7F0040047AFF8003EA2AFA90F0BFEA5D
:20507B00F00BBB00010CEB2EF582EC3FF583E0A2E71324B390F0C0F00EBE00010FC005C03B
:20509B0006C00790F95B1245B7158115811581E59D04FF8F9DBF0303759D00D21910AF0240
:2050BB00C219E5EFFF04F5EFA21992AFEF7007C005124EE3D0058D8222D21A10AF02C21A46
:1050DB00AFEF75EF03A21A92AFEF7003024EE3220C
:2074BF00D3917D044522000F0022BB131D3B1373A7650700181E1CC700B0B610EA2A001FAF
:2074DF00030506080B0E191C242527293855408D8A84CAC4C0646D612069727120756E65D4
:0974FF00787065637465640A008D
:10760500DFD900008080131A0000DFD9207E1342E5
:1700E10090FC477456F090FC487412F090FC4903F090FC4A7485F0AA
:2050EB00E58620E0FB225390FD00225380FB0022E58620E0FB004390020022E58620E0FB68
:20510B00004380040022C007C006C005C004C003C002C001C000E582785BF27E00C21C787F
:20512B005CE4F2C006785CE2C0E0901000124376AA82AB831581785DEAF2EB08F2785F74DA
:20514B0004F2E408F2785DE2FA08E2FBE4FCFE7404C0E0E4C0E0744BC0E074FCC0E08A82E5
:20516B008B838CF0EE1206E1E58124FCF5817404C0E07447C0E074FCC0E090FC4B12454BBB
:20518B00158115811581921DD006201D03025275785FE2FB08E2FCC394104003025275C0E7
:2051AB0006785D795FE3C5F0E225F0FB09E3C5F008E235F0FAE4FCFE7402C0E0E4C0E07411
:2051CB004BC0E074FCC0E08B828A838CF0EE1206E1E58124FCF58190FC4BE0F51A74FFB562
:2051EB001A05D006025275D006785BE2B51A5D90FC4CE0FCBC020040531C1C8C06785AC3CB
:20520B00E29C5004785AE2FCC0067B007858E2F51B08E2F51C785DE2FD08E2FF74022DFDC6
:20522B00E43FFF785FE22DFD08E23FFA7E007F00C004C003C01BC01C8D828A838EF0EF1265
:20524B0006E1E58124FCF581D21CD00690FC4CE0FF7D00785FE2FB08E2FCEF2BFBED3CFC94
:20526B00785FEBF2EC08F202519B785CE22401F2785CE2B40A00500302512E301C048E07A1
:20528B0080027FFF8F82D000D001D002D003D004D005D006D00722C007C001C000758204F1
:2052AB00C007C006C005C004C003C002C001C000121776D000D001D002D003D004D005D069
:2052CB0006D00778587461F274FC08F2785A7401F2758223125111E58230E70690FC617439
:2052EB0008F0785874AEF274FA08F2785A7402F2758212125111E58230E70A90FAAE74A6CE
:20530B00F07409A3F0785874B0F274FA08F2785A7402F2758209125111E582FF30E70A906F
:20532B00FAB074F3F07402A3F0C007C006C005C004C003C002C001C00012536C758204125E
:20534B0017AF758200125BB8D000D001D002D003D004D005D006D007D2AFD000D001D007CB
:20536B00227440C0E07401C0E0E4C0E090FDA212451F158115811581785874A2F274FD085B
:20538B00F2785A7407F275822A125111E582FF30E71D785874A2F274FD08F2785A7406F221
:2053AB00758201125111E582FF30E703D21B2290F9577444F090F9567467F090FDA4E0FFA5
:2053CB0090F953F090FDA5E0FE90F952F090FDA6E090F951F090FDA7E090F950F090FDA430
:2053EB00E4F07D007C00C006C005C007C00474A2C0E074FDC0E0E4C0E07408C0E07475C0AF
:20540B00E01259A9E58124F7F58190F950E0FF7E0090F951E0FD7C00C007C006C005C00417
:20542B007416C0E07475C0E01259A9E58124FAF58190FDA2E024BF90F955F090FDA3E024AC
:20544B00BF90F954F090F956E0FF7E0090F957E0FD7C00C007C006C005C0047420C0E07482
:20546B0075C0E07436C0E074FCC0E0125A22E58124F8F58190F954E0FF7E0090F955E0FD37
:20548B007C00C007C006C005C0047420C0E07475C0E0743AC0E074FCC0E0125A22E581243C
:2054AB00F8F58190F952E0FF7E0090F953E0FD7C00C007C006C005C0047420C0E07475C013
:2054CB00E0743EC0E074FCC0E0125A22E58124F8F58190F950E0FF7E0090F951E0FD7C0090
:2054EB00C007C006C005C0047420C0E07475C0E07442C0E074FCC0E0125A22E58124F8F563
:20550B0081229055187479C39582F5F02275F020C2ADC2AC43AE0100E5AE20E7FB05AD0572
:20552B00ADD5F0F09000008583AD8582ACA375AB2275F00275F900E5F830E1FB53F8FDE536
:20554B00F820E0FBC0F9D5F0EB43AE02E5AE20E6FBD0E0D0AFF5AFE5AE20E6FB53AEFDE513
:20556B00AE20E7FBE583B440BE75C90B80FEC007C006C005C004C00312550DAC82AD83AE36
:20558B00F0FF8E03C003C004C00590FDA21245B715811581158175D6FF75A80075C70390FF
:2055AB00FDA2E473D003D004D005D006D00722C007C00675A80075B800759A0075C7007508
:2055CB00BE00E5BE30E5FB75C679E5BE30E6FB7F007E00000EBE80FB0FBF80F575C639E507
:2055EB00C620E6FB75C63875BE04D006D0072243B404E5B4540C600280F8E5BC65BDF58258
:20560B00221255FAC0821255FAC0821255FAC0821255FAD083D0F0D0E022C0008582BC7833
:07562B0061E2F5BCD0002292
:20750800534E20257325303278253032780025303278253032780A00253032582530325846
:017528000062
:20563200E58620E0FB225390FD00225380FB0022E58620E0FB004390020022E58620E0FB1B
:20565200004380040022C007C083C082858107C004C003C002C001C00074F42581F886831D
:2056720018868218860018E0A36013B4250B7C007A00E0A36008B4251612593A80E9D000BA
:20569200D001D002D003D004D082D083D00722B4630518E61880E2FB4420B46D3AEB542063
:2056B20003F9C083C0821258D67C0874FF2C93C083C082FAC47B02540F29905969931259C5
:2056D2003AEADBF3D082D083DC06D082D0838097743A12593A80D4EBB42A09BA009B740140
:2056F2004CFC808EB43007BA0004740680F2FB24D0501224F6400E240AFB740A8AF0A42B04
:20571200FA740480DBBB6C0DEC54086004741080CF740880CBBB733CEC5408C083C0827089
:20573200051258DD80031258D6EC54047009E0A3609812593A80F7BA0002808EE0A3600A3D
:2057520012593ADAF7808302582A742012593ADAF90256DCEB4420B478EDC083C0821258A3
:20577200F3C083C082E5F023F90324FF2582F582E5833400F583E054F0701119E0700D1922
:205792001582E582B4FF021583D5F0EAB9000109EC5420600B09EC54026005742D12593A79
:2057B200EC54046018EAC39940136011FAEC5402C4032420F582E58212593ADAF9EC542014
:2057D200600B19EC54027005742D12593AEB542003FAD082D083E904C313FC142582F58244
:2057F200E5833400F583E954016005E079018005E07902FBC4540F2AC083C08290596993F0
:20581200D082D08312593AEBD9EB1582E582B4FF021583DCDB0256DCBB640674204CFC80C6
:2058320008BB75028003025679C083C0821258F3C0F07408C395F0244FF9E434FCFBE0A374
:2058520012592FF0A312592FD5F0F312592FF5F0EC54206028E5F054807006EC54DFFC8096
:205872001CD0F0C0F07408C395F0244FF582E434FCF583C3E0F9E499F0A3D5F0F775F00A79
:20589200E4F0A3D5F0FBD0E0C403FB90FC5775F00AE0F9540F24FBE950022403F954F024DD
:2058B200B0E950022430F0A3D5F0E690FC4FC375F012E033F0A3D5F0F9DBD090FC5775F0ED
:2058D2000A02577386831886821822E61860F5648060F164C0600585938380EA7583FF80F0
:2058F200E5EC5401701F88F07583FFEC5418600A5410600418181818181818888218E5F049
:20591200C398F5F022EC5418600E5410600575F00880B175F00480AC75F00280A7C583CBB0
:20593200C583C582C9C58222C083C082C001C0008F00868218868318181818860118860051
:2059520012595ED000D001D082D08322C082C0838500828501832230313233343536373879
:205972003941424344454630313233343536373839616263646566C007C006C005C004FFD0
:20599200BF0A0675820D1242E38F821242E3D004D005D006D00722C007C001C000A20B92A4
:2059B2001EE58124FAFF200B031242F7C007E58124F9F8E6C0E008E6C0E0E4C0E0C0E090B1
:2059D2005989125658E58124FBF581201E0312430CD000D001D00722C007C006C005C004C6
:2059F200C003C001AC82FF8C018F0487060987071974012EFBE43FFDA70309A7058E828FCB
:205A120083ECF0D001D003D004D005D006D00722C007C006C005C001C000E58124F6FFE5C2
:205A32008124F8FE7D00C007E58124F5F8E6C0E008E6C0E0C006C0059059EA125658E58166
:195A520024FBF58124F8F88682088683E4F0D000D001D005D006D0072260
:0200F800C21F25
:205A6B00E58620E0FB225390FD00225380FB0022E58620E0FB004390020022E58620E0FBDE
:205A8B00004380040022C007AF82E58620E0FB53807F008F82125C3F00E58620E0FB43807B
:205AAB0080D0072253BEFC32AE82AF838E828F83E493FD74012EFBE43FFCEDFA60525390F2
:205ACB00FD008B828C83E493FD0BBB00010CE58620E0FB53807F008D82125C3F00E586205C
:205AEB00E0FB438080EA14FDED6015E58620E0FB8B828C83E493F5C1A3AB82AC831D80E8ED
:205B0B008B068C07E58620E0FB0043900200809C22301F0122D21F758201125BB843900288
:205B2B005380BF43F42875C20075C5317586009000FDE4F5F01249694390049000FDE4F575
:205B4B00F01249692090FD907529125AB35390FD00E58620E0FB53807F00758204125C3F4C
:205B6B0000E58620E0FB4380803090FDE58620E0FB0043900200907535125AB35390FD0040
:205B8B00E58620E0FB53807F00758282125C3F00E58620E0FB43808090FC61E0FFF582121E
:205BAB005C3FE58620E0FB004390020022E582601690F953E054F0600122438FC143FDC1EE
:205BCB0043F62E43FE2E2253F4D790F953E0FF54F0600B53807E5390D100D2860022538FD9
:205BEB003A53FD3A53F6D153FED122201F01229075C1125AB3758200125BB8C21F22125BA5
:205C0B001C5390FD003020067E137F0080047E107F00E58620E0FB53807F008E82125C3F11
:205C2B0000E58620E0FB438080E58620E0FB004390020022C007AF82E58620E0FB8FC1D0D5
:205C4B0007227EFF7FFF74CEC0E07475C0E01259A9158115819075CBC007C006125AB3D01E
:205C6B0006D00720902F900032E4F5F0C007C0061249D81255BA75820F124C25D006D007BB
:205C8B0090FAB2E0FCA3E0FDC3EC9EED9F50D48C068D0780CE7423C0E08E828F8312482D10
:205CAB0015817404C0E0124376AC82AD83158190F0E9ECF0EDA3F0758201121776125BF6AD
:135CCB0012195474E0C0E07475C0E01259A9158115812268
:20752900050107000900040607070F0002008F046180012802302902501702820802602292
:20754900102001010103040906060A040419030409102101010103840986460A844419031A
:207569004409102201010143040986460A84441983040910250A0A0102140D141401000053
:207589000000000010264A4A0182540D54540100000000000010270A0A0102140D141401F3
:2075A900000000000000102401810183840986460A844419030409000282000501020000A8
:2075C90000000112005570646174696E6720646973706C61790A0055706461746520636FDE
:0875E9006D706C6574650A0009
:205CDE00AE82AF837C007D007B10EF235401FAEE2EFEEF33FFEC2CFCED33FDEA600343045F
:205CFE00017862C3E2F5F0EC95F008E2F5F0ED95F040117862D3E29CF4B3FCB308E29DF422
:0B5D1E00FD430601DBC48E828F832250
:205D2900AC82AD83AEF0FF33E433FB6013C3E49CF556E49DF557E49EF558E49FF559800824
:205D49008C568D578E588F59AC56AD57AE58AF597867E233E433FA60207864E2D3F4340054
:205D6900F55608E2F43400F55708E2F43400F55808E2F43400F55980117864E2F55608E22E
:205D8900F55708E2F55808E2F559786CE556F2E55708F2E55808F2E55908F28C828D838EDD
:205DA900F0EFC003C002125DFD7868C0E0E582F2E58308F2E5F008F2D0E008F2D002D003B1
:205DC900EA6B60207868E2D3F43400FA08E2F43400FB08E2F43400FE08E2F434008A828B68
:145DE900838EF0227868E2F58208E2F58308E2F5F008E2220D
:205DFD00AF82AE83ADF0FC7870EFF2EE08F2ED08F2EC08F27A007B007E007F007D20787393
:205E1D00E2235401FC7870E225E0F208E233F208E233F208E233F2EA2AFAEB33FBEE33FEDB
:205E3D00EF33FFEC6003430201786CC3E2F5F0EA95F008E2F5F0EB95F008E2F5F0EE95F031
:205E5D0008E2F5F0EF95F04022786CD3E29AF4B3FAB308E29BF4B3FBB308E29EF4B3FEB33F
:1D5E7D0008E29FF4FF7870E24401F2DD917870E2F58208E2F58308E2F5F008E2229F
:0600B200E478FFF6D8FD22
:200090007924E94400601B7A019075F178627593FCE493F2A308B800020593D9F4DAF27548
:0200B00093FFBC
:1B5E9A0020F71130F6138883A88220F509F6A8837583002280FEF280F5F02207
:205EB500AA83AB828BF090F075E0A4F8A9F08AF0E0A429F98BF0A3E0A429F583888222223D
:205ED500AF82AE83ADF0FC787BEFF2EE08F2ED08F2EC08F2787BE2FF7879E28FF0A4FFADB3
:205EF500F07881EFF208EDF2787BE2FF7877E28FF0A4FFADF0787FEFF208EDF27882E2FFDE
:205F1500787EE2FE7877E28EF0A42FFF7882F2787DE2FE7878E28EF0A42F7882F27881E2CA
:205F3500FE08E2FF787DE2FD7877E28DF0A4ABF02EFEEB3FFF7881EEF208EFF2787CE2FD1A
:205F55007878E28DF0A4ABF02EFEEB3FFF7881EEF208EFF2787CE2FF7879E28FF0A4787EC6
:205F7500F2787CE2FF7877E28FF0A4FFADF0787CEFF208EDF2787BE2FF787AE28FF0A478B6
:205F95007AF2787BE2FF7878E28FF0A4FFADF07878EFF208EDF27877E4F2787BF2787FE2E0
:205FB500F55A08E2F55B08E2F55C08E2F55D787BE2FA08E2FB08E2FE08E2FFEA255AF55A8F
:205FD500EB355BF55BEE355CF55CEF355DF55D787FE55AF208E55BF208E55CF208E55DF265
:205FF500787FE208E208E208E27877E2FC08E2FD08E2FE08E2FFEC255AFCED355BFDEE356C
:0C6015005CFEEF355D8C828D838EF022E6
:20602100AE82AF837D007C007884E2235401FB70357883E225E0F208E233F27883C3E2F596
:20604100F0EE95F008E2F5F0EF95F050147883E2F5F008E2C313C5F01318F2C5F008F280B2
:20606100050C8C0580C27883C3E2F5F0EE95F008E2F5F0EF95F0400E7883D3E29EF4B3FEBF
:20608100B308E29FF4FF7883E2F5F008E2C313C5F01318F2C5F008F28D041DEC70C88E82EB
:0360A1008F8322C8
:2060A400AD82AE83AFF07888E2F5F008E245F07004900000227888E2FB08E2FC1BBBFF0138
:2060C4001CEB4C6069C003C0048D5A8E5B8F5C855A82855B83855CF0126223FA7885E2F564
:2060E4005D08E2F55E08E2F55F855D82855E83855FF0126223FCEAB504028006D004D003C1
:20610400802C7401255AFAE4355BFBAC5C8A058B068C077401255DFAE4355EFBAC5F78854C
:20612400EAF2EB08F2EC08F2D004D003808E8D828E838FF0126223FD7F007885E2FB08E289
:1A614400FC08E2FE8B828C838EF0126223FB7E00EDC39BF582EF9EF58322CA
:20615E00AE82E583FF33E433FD6009C3E49EFBE49FFC80048E038F04788BE233E433FF60E5
:20617E0010788AE2D3F43400FA08E2F43400FE8007788AE2FA08E2FE7862EAF2EE08F28B92
:20619E00828C83C007C005125CDEAC82AE83D005D007EF6D600AC3E49CF582E49EF58322D1
:0561BE008C828E83229B
:2000B800788CE84400600A79007593F0E4F309D8FC78D6E8440B600C790C90F08CE4F0A370
:0400D800D8FCD9FA7D
:0F008100E47375816412623FE582600302007EC2
:2061C300758911758800758B00758D0020B0FD20B0FA20B0F720B0F420B0F130B0FDD28E8E
:2061E30020B0FD30B0FD20B0FD30B0FDC28EE58D25E0FFE58B2354014FF58DE58D25E0FF53
:20620300E58B232354014FF58DE58DF4F58DE58D04F58D858D8B7589217587807598522206
:1C62230020F71430F6148883A88220F507E6A88375830022E280F7E49322E0228A
:04623F007582002242
:00000001FF

Binary file not shown.

View File

@@ -1,996 +0,0 @@
:040000000200833245
:01000B0032C2
:0100130032BA
:01001B0032B2
:0100230032AA
:03002B00024A4343
:01003300329A
:01003B003292
:0300430002500563
:03004B0002496007
:01005300327A
:01005B003272
:01006300326A
:01006B003262
:01007300325A
:03007B00025B4CD9
:0300FA0002007E83
:03007E0002050672
:2000FD00E58620E0FB225390FD00225380FB0022E58620E0FB004390020022E58620E0FBA6
:20011D00004380040022AF8290F090E4F090F091F08F061FEE60767E0090F95AE0FDBD024E
:20013D000BEE9062AF93FDBDC800405990F95AE0FDBD010BEE9062AF93FDBDC8005046EEA9
:20015D0024AFFCE43462FD8C828D83E493F582C007C006C005C004121C5EE582D004D0057E
:20017D00D006D007601F90F090E0FB90F0BFE0FAC3EB9A501090F090EAF08C828D83E4930B
:20019D00FC90F091F00EBE0C005086808C90F091E0FFE06013BFC800400890F95A7402F030
:2001BD00800690F95A7401F090F091E0F5822290F0EDE0FEA3E0FFC3742C9E74019F40099F
:2001DD0090F0E3E0700330015E300A0920020690F0C6E0700930031E90F0C7E0601890FC37
:2001FD0063E0FFBFFF02800B7824E4F28F821227818003123CFA121E2AAD82AE83AFF09064
:20021D00F092EDF0EEA3F0EFA3F0ED4E602D90F0EDE4F0A3F010010090F0E3E06002D2013A
:20023D0090F0E3E4F08014121F15AD82AE83AFF090F092EDF0EEA3F0EFA3F01218BE90F037
:20025D0092E0FDA3E0FEA3E0FFED4E700990F0E1E4F0A3F08059740F2DFAE43EFB8F048AD6
:20027D00828B838CF012628FFAA312628FFB90F0E1EAF0EBA3F0740D2DFAE43EFB8F048A1C
:20029D00828B838CF012628F60168D828E838FF0123156E582701890F0E1E4F0A3F0800F3E
:2002BD0074C0C0E07462C0E0125A4615811581121909AE82AF8390F0EDE0FCA3E0FD90F01A
:2002DD00EDEE2CF0EF3DA3F0BE580CBF020990F0C5E06003C2002290FA5BE0600E90FA5BDB
:2002FD00E4F0900064E4F5F002180990F0E1E0FEA3E0FF4E603BEF30E71F8E048F055305E0
:20031D007F7877ECF2ED08F2E408F208F29003E8E4F5F0125F410218097877EEF2EF08F2E4
:20033D00E408F208F290EA60E4F5F0125F41021809121909AE82AF837877EEF2EF08F2E41E
:20035D0008F208F29003E8E4F5F0125F4102180990F0CEE0FF600D8F82121C5EE58290F94C
:20037D0059F0800C758202120123E58290F959F090F959E0700920030690F0C7E0701430E4
:20039D000A0920020690F0C6E0700890F0E4E0FFBF233690FC63E0FFBFFF02801A758202EB
:2003BD00123E9AE582702290FC63E0FF7824E4F28F82122781801290F0E4E0FFBF2300403B
:2003DD0005123E3B8003123DF890F959E0604890F0E4E4F090F0CEE0700F7582041217C46F
:2003FD001214C77582041217FD90F0E374FDF09000281217A1121909AE82AF837877EEF227
:20041D00EF08F2E408F208F29003E8E4F5F0125F41121809D20022758201121884AC82AD60
:20043D0083AEF0FF7877ECF2ED08F2EE08F2EF08F29003E8E4F5F0125F41021809E582FF7B
:20045D0024FA50030204EEEF2F2F90046B7302495C02047D0204940204C40204EE0204D003
:20047D0074CBC0E07462C0E0125A4615811581C20090F959E4F02290F959E0FE74D8C0E0E6
:20049D007462C0E0125A4615811581758204C0061217C41213811214C77582041217FDD0B9
:2004BD000690F959EEF022123A19900000E4F5F002180974E8C0E07462C0E0125A4615819C
:2004DD0015817582041217C412276D7582040217FD7E00C007C00674F8C0E07462C0E0122B
:2004FD005A46E58124FCF581227582011217C475820F124C9E90FAB2E0FEA3E0FF7423C047
:20051D00E08E828F831248A615817404C0E01243EFAC82AD83158190F0E5ECF0EDA3F09085
:20053D0062BBE493C0E0740193C0E09062BDE493C0E0740193C0E0740293C0E0740AC0E08D
:20055D007463C0E0125A46E58124F9F58112531B1219A212195A90F0E374FCF0AEBE530602
:20057D00187F00BE1009BF000690F0E374FEF0301B0C123E94900000E4F5F01218097436F5
:20059D00C0E074FCC0E0E4C0E07439C0E07463C0E0125A46E58124FBF58112374E900190E1
:2005BD00E4F5F01218097582041217C41213F312373590F0C2E060117441C0E07463C0E045
:2005DD00125A4615811581801B7452C0E07463C0E0125A4615811581123AC8902710E4F516
:2005FD00F012180990F959E0FFE0601F8F82121C5EE5827025745FC0E07463C0E0125A4666
:20061D001581158190F959E4F0800F747DC0E07463C0E0125A461581158190F959E0700331
:20063D0012036D90F959E06007123CFAD2008005123DF8C2007582041217C41214C7300045
:20065D00067E287F0080047E587F028E828F831217A130000A7C887D137E007F0080087CBC
:1E067D00C07DD47E017F008C828D838EF0EF1218093000051201CC80F812036D80F311
:2062AF00C864C965CA66CB67CC68CD6910008F63804E6F207570646174650A00434D445F8A
:2062CF00444F5F5343414E0A0052657365742073657474696E67730A0045726173696E6727
:2062EF0020696D616765730A00436D6420307825782069676E6F7265640A000A2573204F53
:20630F0045504C2076253034782C20636F6D70696C656420417567202037203230323420A1
:20632F0030393A32353A33320A004D41432025730A00446F696E67206661737420626F6FE9
:20634F00740A004E6F726D616C20626F6F740A004E6F20415020666F756E64206F6E20732F
:20636F0061766564206368616E6E656C0A004E6F207361766564206368616E6E656C0A0078
:09638F004368726F6D6132390040
:017671000117
:20069B00E58620E0FB225390FD00225380FB0022E58620E0FB004390020022E58620E0FB02
:2006BB00004380040022AC82AD83AEF0FF00C2A00075820312435C8E8212435C8D82124309
:2006DB005C8C8202435CC007C006C005C004C003C002C001C000AC82AD83AEF0FFE5812453
:2006FB00F5F8860208860300C2A00075820312435C8E8212435C8D8212435C8C8212435C8C
:20071B008A068B07E58124F3F886040886058C028D031CBCFF011DEA4B6015758200124301
:20073B005CAB828E828F83EBF0A3AE82AF8380DE00D2A000D000D001D002D003D004D00554
:20075B00D006D00722AF8200C2A0008F8212435C00D2A0002200C2A00075820512435C7542
:20077B00820012435CE58220E0F500D2A00022AC82AD83AEF0FF7803E2FA08E2FBC007C07D
:20079B0006C005C004C003C002120770758206120760D002D003D004D005D006D00700C26E
:2007BB00A00075820212435C8E8212435C8D8212435C8C8212435C8A068B077805E2FC080F
:2007DB00E2FD8C028D031CBCFF011DEA4B60128E828F83E0FBA3AE82AF838B8212435C8025
:2007FB00E100D2A000221207707582B9120760C20C227582AB12076075F034D5F0FDD20C73
:20081B0022C007C006C005C004C003C002C001C000C082C083C0F0C0E005810581E5812414
:20083B00EFF88605088604E58124EDF8E608467003020915C005C004E58124F9F8860208CF
:20085B007B00E58124FDF8E4C39AF674019B08F6E58124FDF8E58124EBF9C3E79609E70819
:20087B0096D004D005500EE58124EDF8A98119E6F708E609F77803EDF2EC08F2A881187949
:20089B0005E6F308E609F3E58124FBF886820886830886F008E6C007C006C005C004C0039A
:2008BB00C002C001C000C02512078AD025D000D001D002D003D004D005D006D007A8811880
:2008DB008602088603E4FEFFE58124FBF8EA26F6EB0836F6EE0836F6EF0836F6A88118E6F5
:2008FB002DFD08E63CFCE58124EDF8A98119E6C397F608E60997F6020842E58124FAF581DB
:20091B00D000D001D002D003D004D005D006D00722C007C006C005C004C003C002C001C0E2
:20093B0000C082C083C0F0C0E0E58124FDF88602088603EA7005EB540F6006758200020A19
:20095B002FE58124F1F8E608467003020A2C758206C007C006C005C004C003C002C001C0E2
:20097B0000C025120760D025D000D001D002D003D004D005D006D00700C2A000E58124F190
:20099B00F8860208860375822012435CE58124FDF80808868212435CE58124FDF80886828C
:2009BB0012435CE58124FDF8868212435C00D2A000C007C006C005C004C003C002C001C0A5
:2009DB0000C025120770D025D000D001D002D003D004D005D006D0077401C0E09010001236
:2009FB0043EFAC82AD83AEF0FF1581E58124FDF8EC26F6ED0836F6EE0836F6EF0836F61A12
:200A1B00BAFF011BE58124F1F8A60208A60302095C758201E58124FCF581D000D001D0024C
:0B0A3B00D003D004D005D006D0072265
:200A4600E58620E0FB225390FD00225380FB0022E58620E0FB004390020022E58620E0FB53
:200A6600004380040022C007C006C005C004AF82AE83ADF0FC90F0BBEFF0EEA3F0EDA3F05B
:200A8600ECA3F0C202C203D208758204C007C006C005C004C003C002C001C000C025121749
:200AA600C4D025D000D001D002D003D004D005D006D00790F0BBE0FCA3E0FDA3E0FEA3E040
:200AC600FF7416C0E0E4C0E074F3C0E074F0C0E08C828D838EF0EF1206E1E58124FCF581D8
:200AE60090F0BBE0FCA3E0FDA3E0FEA3E0FF90F0BB74162CF0E43DA3F0E43EA3F0E43FA346
:200B0600F090F103E0FFBF2004C207806A90F103E0FFBF2104D207805E90F103E0FF7E0007
:200B2600C007C0067480C0E07469C0E0125A46E58124FCF58190FA6E7416F0E4A3F090F0FA
:200B4600F375F000C007C006C005C004C003C002C001C000C025121B11D025758204C02523
:200B66001217FDD025D000D001D002D003D004D005D006D0078051C221C007C006C005C0F2
:200B860004C003C002C001C000C025125C75D025C025120BD7D025D221C025125C75D0250A
:200BA600C025120BD7D025758204C0251217FDD025C025125CB9D025D000D001D002D0031F
:200BC600D004D005D006D007D004D005D006D007227F807E0090F0ABE4F0A3F090F0A5F01D
:200BE600A3F05390FD007D00200803020C6A30211D20071A74A0C0E07404C0E0E4C0E090CD
:200C0600F0F3124598158115811581020CBAC00590F0BBE0FAA3E0FBA3E0FCA3E0FD74A007
:200C2600C0E07404C0E074F3C0E074F0C0E08A828B838CF0ED1206E1E58124FCF58190F0F3
:200C4600BBE0FAA3E0FBA3E0FCA3E0FD90F0BB74A02AF074043BA3F0E43CA3F0E43DA3F066
:200C6600D005805074A0C0E07404C0E0E4C0E090F0F31245981581158115817B4A7C00C054
:200C860007C006C005C004C0037807E2F58208E2F583120081D003D004D005D006D00790AF
:200CA600F0A5E02401F0A3E03400F01BBBFF011CEB4C70CB7B007C00EF60503021238E02FF
:200CC600EA2AFEEB24F3F582EC34F0F583E0FAEF5A7003430601EF30E02B8E82125CAB8048
:200CE600248E02EA2A25E0FEEB24F3F582EC34F0F583E0FAEF5A6003430603EF5411600597
:200D06008E82125CABEFC313FF80AD7F800BBB00010CC3EB94A0EC9404409D90F0ABE0FB98
:200D2600A3E0FC744A2BFBE43CFC90F0ABEBF0ECA3F00DBD04005003020BEEE58620E0FB27
:200D4600004390020022AE82AF83C202C203C208D207C2217807EEF2EF08F2125C75120BDD
:200D6600D7D221125C75120BD7025CB9C007C006C005C004C003C002C001C000AD82AE8339
:200D8600AFF0A204202101B3505090F09FE0F508A3E0F50974012DFAE43EFB8F048A828B13
:200DA600838CF012628FFA780CF2E408F2850882850983C007C006C005C004C003C002C062
:200DC60001C000121003E582D000D001D002D003D004D005D006D0076003020FA98D828E6A
:200DE600838FF0780912628FF290F0A1E0F508A3E0F5097809E2F50A750B00780EE50AF2AD
:200E0600E50B08F2850882850983C007C006C005C004C003C002C001C00012107AD000D06A
:200E260001D002D003D00490F0ADE0F508A3E0F50990F0B1E0FBA3E0FCEBC39508F582EC6E
:200E46009509F5837875E50AF2E50B08F2C002C001C000125F21AB82AC83D000D001D0021A
:200E6600D005D006D007ECC423CBC423541F6BCB541FCB6BCBFC90F0B7EBF0ECA3F0740245
:200E86002BFBE43CFCEB2DFDEC3EFE90F0A7E0FBA3E0FCEB5407700A7809E2540770030259
:200EA6000F5D5303078BF005F07B80E4FC3392D28008A2D2EC13FCEB13FBD5F0F5780AEB6A
:200EC600F2780B7480F28D828E838FF012628FFA74012DF50CE43EF50D8F0E7809E2F50A4F
:200EE600AC0A150AEC7003020FA9780BE25A6025C00290F0B5E0FAA3E0FCEA24F3FAEC344F
:200F0600F0FC8A828C83E0FB780AE242038A828C83EBF0D002780BE2C313F2780BE270195D
:200F2600850C82850D83850EF012628FFAA385820C85830D780B7480F2780AE2C313F2782B
:200F46000AE2709C780A7480F290F0B5E02401F0A3E03400F080897809E2604790F0B5E032
:200F6600FBA3E0FCEB24F3FBEC34F0FC8B828C83E0F50C8D828E838FF012628FFAA3AD827D
:200F8600AE83E50C42028B828C83EAF090F0B5E02401F0A3E03400F07809E2FC780924F822
:200FA600F280B4D000D001D002D003D004D005D006D0072290F0A7E0FEA3E0C423CEC42323
:200FC600541F6ECE541FCE6ECE30E40244E0FF90F0ABE0FCA3E0FD90F0B1E0FAA3E0FBEAAC
:200FE600C39CFCEB9DC454F0CCC4CC6CCC54F0CC6CFD90F0B5EC2EF0ED3FA3F022AE82AFF4
:201006008390F095EEF0EFA3F090F0AFEEF0EFA3F07427C39EFE74019FFF90F0A9EEF0EF40
:20102600A3F090F0A5E0FCA3E0FD90F0B1ECF0EDA3F0C3EE9CEF64808DF063F08095F040D4
:201046002F780CE22CFC08E23DFDC3EE9CEF9D501F780CD3E29EF4B3FEB308E29FF4FF0EA8
:20106600BE00010F90F0ADEEF0EFA3F07582002275820122AE82AF8390F0A7EEF0EFA3F0F3
:20108600780E90F097E22EF008E23FA3F0120FBA75820022C007C006C005C004C003C00262
:2010A600C001C000AC82AD83AEF0FF058105810581BF2000502C8F82C007C006C005C0049A
:2010C600C003C002C001C000C0251242A7D025D000D001D002D003D004D005D006D0070291
:2010E60013447E00EF24E0FFEE34FFFEEF2FFFEE33FEEF2498F582EE3463F583E493FEA391
:20110600E493FF90F0B7EEF0EFA3F0EFC4540FFE90F0B3F0300507EE2EFE90F0B3F090F08C
:2011260099E0FEA3E0FF90F0B9EEF0EFA3F090F0B3E0FDFB3395E0FC0BBB00010CEB2EFB81
:20114600EC3FFC90F099EBF0ECA3F0A204202101B3504190F0B9E0FEA3E0FF780CEDF2EDDA
:201166003395E008F28E828F83C007C006C005C004C003C002C001C000C025121003E58218
:20118600D025D000D001D002D003D004D005D006D007600302134490F09BE0FEA3E0FF90F1
:2011A600F0B4E0FD780EF2ED3395E008F28E828F83C007C006C005C004C003C002C001C063
:2011C60000C02512107AD025D000D001D002D003D004D005D006D00790F0B7E0FEA3E0FF60
:2011E60053070F90F0B7EEF0EFA3F0A8811818760008768090F0A7E0FCA3E05304078CF0BC
:2012060005F07C80E4FD3392D28008A2D2ED13FDEC13FCD5F0F5A881A60490F0B3E0FD903E
:20122600F0ADE0FAA3E0FB90F0A5E0FCA3E0FFECC39AFAEF9BFBED3395E0FFEDC39AFAEFA1
:201246009BFB1ABAFF011B90F0B9EAF0EBA3F030050FEBC313CA13CAFB90F0B9EAF0EBA32A
:20126600F090F0B9E0FEA3E0FF90F0B7E0FCA3E0FD90F0B7EE2CF0EF3DA3F090F0B7E0FE37
:20128600A3E0FFEE2EFEEF33FFEE2458F582EF3464F583E493FEA3E493FF90F0B9E4F0A36D
:2012A600F090F0B9E0FCA3E0FD90F0B4E0FB3395E0FAC3EC9BED9A4003021344A88118182C
:2012C600E65EFC08E65FFD4C602190F0B5E0FCA3E0FDEC24F3FCED34F0FD8C828D83E0FB1A
:2012E600A881E642038C828D83EBF030051A90F0B9E0FCA3E0FDEC30E01AA88118E618C39F
:2013060013C613C608F6800CA88118E618C313C613C608F6A881E6C313F6A881E6701090DF
:20132600F0B5E02401F0A3E03400F0A881768090F0B9E02401F0A3E03400F00212A7158121
:1513460015811581D000D001D002D003D004D005D006D00722A8
:206398000070071008500D9016601CA026A03010316037603D7044904D204F605520578020
:2063B8005F7066706D6073507880805085708C7093709A70A120A320A570AC80B470BB70B6
:2063D800C2A0CCA0D670DD80E570EC70F370FA8002710971105115811D7124812C7133813E
:2063F8003B7142814A7151715891617168A172A17CA186A1908198519D81A551AA81B2A1F2
:20641800BC21BE71C571CC71D371DA71E181E971F071F741FB51007207420B9214721B724A
:2064380022722972306236623C724362499252A25C8264A26E8276627C127D6283A28D728C
:206458000000000000000000000000000000D87F0078000000000000007880009804E005DC
:20647800801E9864E005801E80648004183808640842FCFF8841F040083810442044C04489
:2064980000397002880C881088207040E0001001083A08468845C84C3838180068008001E2
:2064B8000078E00718180C300420024002400240024004200C301818E00700100018000F1F
:2064D8000072000F001800104000400040004000F807400040004000400019001E00800045
:2064F800800080008000800080001800180002000C003000C0000003000C00300040C00F88
:2065180030300840084008403030C00F082008200820F87F0800080008001860284048408D
:2065380088400843083C0840084208420842F03DC0004003400440184020F87F40004000A3
:20655800087C084408441042E041E00F10320844084408441042E00100401840E040004351
:20657800004C00500060F038084508420842084590456038001E0821884088408840302154
:20659800C01F1806180619061E06C000C0002001200110021002080420012001200120010F
:2065B800200120012001200108041002100220012001C000C00000700040D8400041004202
:2065D80000640038C00F30181820C84728486850D851E03F2000200008007000C001400E72
:2065F8004018400C4003C00030000800F81F08110811081108118812700CC003300C1008FC
:2066180008100810081008100818F81F08100810081008101008E007F81F8810881088108D
:20663800881088100810F81F801080108010801080100010C003300C100808100810881024
:206658008810F818F81F80008000800080008000F81F081008100810F81F08100810081025
:206678000800081008100810F01FF81F0001800140022004200810100800F81F080008002D
:206698000800080008000800F81F001C8007E00060008003001CF81FF81F0008000680016C
:2066B80060001000F81FE007100808100810081008101008E007F81F801080108010801086
:2066D8000011000EE00710080810081008100C101208E207F81F80108010C0102011100EC7
:2066F8000800180E0812081108118810901070180010001000100010F81F001000100010C1
:206718000010E01F18000800080008001000E01F0010000C8003600018001800E000000301
:20673800000C00100018C0073800F0000007800370003800C0070018081010082004400277
:206758008001800140022004100808100010000800060001F8000001000200040008001053
:2067780018102810481088100811081208140818FE7F024002400240024000400030000C41
:206798000003C00030000C0002000240024002400240FE7F2000C0000007001C0070000EDA
:2067B800C0012000040004000400040004000400040004000400040000800040300048047C
:2067D800880488049004F8030800F87F10020804080408041006E001E00110020804080443
:2067F800080408040804E00118020804080408041002F87FE0019002880488048804880412
:20681800880300040004F83F00240044004400440044E00119020904090409041202FC0728
:20683800F87F00010002000400040004F803000400040064F8670100010401040164FE671F
:20685800F87F8000C0002001200210020804004000400040F87FF807000200040004F803CD
:20687800000200040004F803F80700030002000400040004F803E0011002080408040804D9
:206898001002E001FF0710020804080408041006E001E00118020804080408041002FF0783
:2068B800F8070001000200040004000718038804880448044804300400040004F01F08048D
:2068D800080408040804F0070800080008001000F807000480036000180008003000C00067
:2068F800000300040006E001180070008003800170001800E0010006080410022001C00098
:20691800C00020011002080401040103C10062001C001800600080000003000408041804F1
:20693800280448048804080508060804800080007C3F024002400240FE7F02400240024050
:206958007C3F80008000C000000100010001800080004000400040008001F8010803080450
:20697800080808040803F80164617461547970652030782578206E6F7420737570706F7204
:056998007465640A00B3
:20135B00E58620E0FB225390FD00225380FB0022E58620E0FB004390020022E58620E0FB35
:20137B0000438004002290F0C17401F090F0C2E4F090F0C3F090F0C4F090F0C5F090F0C6CB
:20139B0004F090F0C7F090F0C9E4F090F0C8F090F0CC7428F0E4A3F090F0CEF090F0CA7467
:2013BB0028F0740AA3F090F959E4F090F95AF022AD82AE8312628FFCBC011C7BC17CF08BD3
:2013DB00828C83740EC0E0C005C0061246301581158115810214C7227480C0E0E4C0E074DF
:2013FB00A2C0E074FDC0E0906000E4F5F01206E1E58124FCF581740EC0E07414C0E074FE15
:20141B00C0E090F0C112463015811581158190FDA2E0FCA3E0FDA3E0FEA3E0FFBCA513BDC7
:20143B005A10BEBA0DBFAB0A90FDA6E0FFBF0102803590FDA2E0FCA3E0FDA3E0FEA3E0FF17
:20145B0090FDA6E0FB7A00C004C005C006C007C003C002749DC0E07469C0E0125A46E58108
:20147B0024F8F58102138190FDA7E090F959F090FDA8E090F95AF074CBC0E07469C0E012ED
:20149B005A461581158112161990FDA2E4F004C0E0E4C0E074A2C0E074FDC0E0906000E45E
:2014BB00F5F012081CE58124FCF581227480C0E0E4C0E074A2C0E074FDC0E0906000E4F530
:2014DB00F01206E1E58124FCF58190FDA2E0FCA3E0FDA3E0FEA3E0FFBCA53EBD5A3BBEBA15
:2014FB0038BFAB35788574C1F274F008F2E408F27888740EF2E408F290FE1475F0001261CE
:20151B0010E5828583F045F0700F90FDA7E0FF90F959E0FEEFB506012290FE21E0FF90F0DF
:20153B00CEE0FEEFB50602803EEE603BBE6400502390FE21E0FF7D00C007C00574DDC0E0D4
:20155B007469C0E0125A46E58124FCF58190F0CEE4F08013BEC800400890F95A7402F080F9
:20157B000690F95A7401F07480C0E0E4C0E0C0E090FDA2124598158115811581740EC0E048
:20159B0074C1C0E074F0C0E090FE1412463015811581158190FDA274A5F0F4A3F074BAA3DB
:2015BB00F0C4A3F090FDA67401F090F959E090FDA7F090F95AE090FDA8F07401C0E0E4C0AA
:2015DB00E0906000E4F5F012092C158115817480C0E0E4C0E074A2C0E074FDC0E090600015
:2015FB00E4F5F012081CE58124FCF58174F6C0E07469C0E0125A461581158102161990F0BF
:20161B00C5E0FF7E00C007C0067407C0E0746AC0E0125A46E58124FCF58190F0CEE0FF7E0E
:20163B0000C007C0067420C0E0746AC0E0125A46E58124FCF58190F0CAE0FEA3E0FFC00632
:20165B00C0077433C0E0746AC0E0125A46E58124FCF58190F0C2E0FF7E00C007C00674474E
:20167B00C0E0746AC0E0125A46E58124FCF58190F959E0FF7E00C007C006745CC0E0746A69
:0C169B00C0E0125A46E58124FCF58122D3
:20699D004C6F616465642064656661756C74732073657474696E67735665722030782578F6
:2069BD00204D61676963203078256C780A004C6F616465642073657474696E67733A0A00C0
:2069DD0049676E6F7265642066697865644368616E6E656C2025640A0053617665642073B0
:2069FD00657474696E67733A0A0020205363616E2041667465722054696D656F7574202515
:206A1D00640A00202066697865644368616E6E656C2025640A0020206261744C6F77566FC1
:206A3D006C746167652025640A002020656E61626C6546617374426F6F742025640A0020DD
:0D6A5D00204C6173742063682025640A00DA
:2016A700E58620E0FB225390FD00225380FB0022E58620E0FB004390020022E58620E0FBE6
:2016C70000438004002275F10175805875FDDD75F33875904075FE6E75F4E875A00175FF76
:2016E70001227401C0E0E4C0E0900000E4F5F012092C158115817414C0E0E4C0E0746AC011
:20170700E0746AC0E090F0F31245F6E58124FCF5817414C0E0E4C0E074F3C0E074F0C0E0F1
:20172700900000E4F5F012081CE58124FCF58122C00775E40075FC0075F70075FE0290F9FA
:2017470053E0FF54F06002800DD291758F0075F60075FD008012758F8175F62F75FD8175C0
:14176700FE2F53807E5390D075F30075F40075F500D0072209
:146A6A005612098501084A41000000000904EC0212045A0A19
:027FFE00706AA7
:20177B00E58620E0FB225390FD00225380FB0022E58620E0FB004390020022E58620E0FB11
:20179B00004380040022AE82AF837D00BD08005017ED75F002A424CFF58274F035F0F583D7
:2017BB00EEF0EFA3F00D80E422E582FF30E025125657C0071249C9D2AF1216CD12435812A1
:2017DB004E6FD00775820A124EAE90F959E0FEF582124DFAEF30E209124385200C0302089E
:2017FB000D22E58230E206300C0302080122AF82AE83ADF0FC90F0EFEFF0EEA3F0EDA3F06A
:20181B00ECA3F090F0EFE0FCA3E0FDA3E0FEA3E0FFC004C005C006C007747EC0E0746AC01A
:20183B00E0125A46E58124FAF581300C16758204C007C006C005C0041217FDD004D005D0FF
:20185B0006D007C007C006C005C004125C62D004D005D006D0071217378C828D838EF0EF69
:20187B00124A517582010217C4E582FF601090F0E4E0FFBFFF00500690F0E4EF04F090F0D7
:20189B00E4E0FFBF18005007900E10E4F5F022BF24005007901C20E4F5F02290518075F0EC
:2018BB0001E42290F0E0E07875F2E408F2900230125F217862740EF2E408F2125D4AAE82A0
:2018DB00AF8374282EFEE43FFF90F0DFE054077D0025E0FCED33FDEC24CFF582ED34F0F540
:2018FB0083EEF0EFA3F090F0DFE02401F0227E007F007D00BD0800501DED75F002A424CFDD
:20191B00F58274F035F0F583E0FBA3E0FCEB2EFEEC3FFF0D80DEEFC423CEC423541F6ECEF4
:20193B00541FCE6ECEFF90F0CCE0FCA3E0FDC3EE9CEF9D50058C828D83228E828F83229026
:20195B00FAB4E0FF3395E0FEC007C0067493C0E0746AC0E0125A46E58124FCF58190F0BF9A
:20197B00E0FF7E0090F0C0E0FD3395E0FCC007C006C005C004749EC0E0746AC0E0125A4636
:20199B00E58124FAF5812275820E124C9E124CCA75820F124C9E90FAB2E0FEA3E0FF7423B2
:2019BB00C0E08E828F831248A615817404C0E01243EFAC82AD83158190F0EBECF0EDA3F09D
:2019DB00C20A90F0CAE0FEA3E0FFC3EC9EED9F5004D20A803A90F0E7E0FCA3E0FD4C601331
:2019FB00C3EC9EED9F500C90F0EBECF0EDA3F0D20A801C90F0E9E0FCA3E0FD4C6011C3EC27
:201A1B009EED9F500A90F0EBECF0EDA3F0D20A90F0E9E0C0E0A3E0C0E090F0E7E0C0E0A3EE
:201A3B00E0C0E090F0EBE0C0E0A3E0C0E090F0E5E0C0E0A3E0C0E074AFC0E0746AC0E012A2
:091A5B005A46E58124F6F58122CA
:206A7E00536C656570696E6720666F7220256C64206D730A0054656D7020256420430A008F
:206A9E00525353492025642C204C51492025640A00426174745620426F6F742025642C207F
:1A6ABE006E6F772025642C2054782025642C207570646174652025640A007E
:0500DC00781074FFF232
:201A6400E58620E0FB225390FD00225380FB0022E58620E0FB004390020022E58620E0FB25
:201A8400004380040022121AE0E582600790F96CE0F58222121AAAE582600790F970E0F59F
:201AA40082227582002290F95BE05407FFBF012890F95CE003035403FFBF031C90F95CE09B
:201AC40023235403FFBF031090F95BE023235401FFBF0104758201227582002290F95BE07B
:201AE4005407FFBF012390F95CE003035403FFBF021790F95CE023235403FFBF030B90F9F5
:201B04005BE020E6047582012275820022AFF0AE83E58290FA70F0EEA3F0EFA3F090FA702B
:201B2400E0FDA3E0FEA3E0FF90FA6EE0FBA3E0FC79007A00C3E99BEA9C5052E94A6016E97B
:201B4400540F6002800F74D8C0E0746AC0E0125A4615811581C003C004E92DF8EA3EFB8F9E
:201B64000488828B838CF012628FF87C00C000C00474DAC0E0746AC0E0125A46E58124FC2A
:201B8400F58109B900010AD004D00380A774D8C0E0746AC0E0125A461581158122AFF0AE79
:201BA40083E5827812F2EE08F2EF08F27815E4F27B017811C3E2F5F0EB95F050227812E2AA
:201BC400FA08E2FC08E2FFEB2AFAE43CFC8A828C838FF012628FFA7815E22AF20B80D37815
:201BE40012E2FD08E2FE08E2FF8D828E838FF012628FFD7815E2B50503D38001C3E433F531
:201C04008222AFF0AE83E5827817F2EE08F2EF08F2781AE4F27B017816C3E2F5F0EB95F027
:201C240050227817E2FA08E2FC08E2FFEB2AFAE43CFC8A828C838FF012628FFA781AE22A94
:201C4400F20B80D37817E2FD08E2FE08E2FF8D828E838FF0781AE2025F06E5812404F58173
:201C6400AF82C218C007125098D0078F82124DFAC00712514DD218125098D0077E01EE2490
:201C8400FC5003021D8890F9DB7414F0C007C00612379590F9ED74EDF090F9DB124F94D013
:201CA40006D007124981AA82AB83ACF0FD90FA7374A62AF0740E3BA3F0E43CA3F0E43DA37C
:201CC400F0C006124981AA82AB83ACF0FD90FA73E58124FCF8E0F6A3E008F6A3E008F6A385
:201CE400E008F6E58124FCF8C3EA96EB0896EC0896ED0896D0064003021D84C007C0061248
:201D040050AAAD82D006D007C374818DF063F08095F050AD90F971E0FDB507A5C007C0069A
:201D2400121A8AAD82D006D007BDEE95C007C006121AAAE582D006D00760867408C0E074E0
:201D440068C0E074F9C0E090F94612463015811581158190F95EE0FCA3E0FD90F94EECF05B
:201D6400EDA3F08F047D00C004C00574E0C0E0746AC0E0125A46E58124FCF5818F82802075
:201D84000E021C828F057E00C005C00674EAC0E0746AC0E0125A46E58124FCF581758200D3
:201DA400E58124FCF5812290F9DB742AF012379590F9ED74E5F090F9F47482F090F0E3E0CC
:201DC40090F9F5F090F0C0E090F9F0F090F0BFE090F9EFF090FAB4E090F9F1F090F0EBE0AE
:201DE400FEA3E0FF90F9F2EEF0EFA3F090F9F6E4F09062BB93FE740193FF90F9F7EEF0EF9F
:201E0400A3F090F959E090F9F9F090F0C9E090F9FAF078167415F290F9EE75F000121C0642
:201E240090F9DB024F94D2181250981219A212195A7F00781BE4F2781BE2B40E00400302BB
:201E44001F08C007121DABD007124981AA82AB83ACF0FD74882AF52674133BF527E43CF5DC
:201E640028E43DF529C007124981AC82AD83AEF0FFC3EC9526ED9527EE9528EF9529D00717
:201E84004003021EFBC0071250AAAE82D007C374818EF063F08095F050CBC007121A8AAE32
:201EA40082D007BEE6BF78117411F290F97175F000C007121BA1E582D00760A97408C0E00B
:201EC4007468C0E074F9C0E090F94612463015811581158190F95E75F00012628FFDA3125B
:201EE400628FFE90F94EEDF0EEA3F090F0E0EFF090F97175F00022781BE22401F2781BE2F9
:201F0400FF021E3B90F0E0740EF090000075F00022D2181250987F00781CE4F2781CE2B483
:201F24000E004003021FFC90F9DB7414F090F9ED74E3F0C00712379590F9DB124F94D007C1
:201F4400124981AA82AB83ACF0FD74882AF52A74133BF52BE43CF52CE43DF52DC0071249E1
:201F640081AC82AD83AEF0FFC3EC952AED952BEE952CEF952DD0075072C0071250AAAE82CA
:201F8400D007C374818EF063F08095F050CEC007121A8AAE82D007BEE6C278117411F29040
:201FA400F97175F000C007121BA1E582D00760AC7408C0E07468C0E074F9C0E090F94612E9
:201FC400463015811581158190F95E75F00012628FFDA312628FFE90F94EEDF0EEA3F09010
:201FE400F0E0EFF090F97175F00022781CE22401F2781CE2FF021F2090F0E0740EF0900008
:202004000075F00022AFF0AE83E582781DF2EE08F2EF08F2781DE22402FA08E23400FB08EE
:20202400E2FC8A828B838CF012628FF52E852E2F75300090FA5CE0F531AE317F00E52FC35A
:202044009EFEE5309FFF7875EEF2EF08F2900063C004C003C002125F21AE82AF83D002D0A5
:2020640003D0048E2F8F3090FA77E52FF0E530A3F0781DE22401FD08E23400FE08E2FF8D31
:20208400828E838FF012628FFD90F91FE0FFEDB50702800122E52E24D5500122C3E52E956B
:2020A400315001227463252FFEE43530FFC374239E74089F500122781DE2FD08E2FE08E23B
:2020C400FF78117466F28D828E838FF0C004C003C002121BA1E582D002D003D0047003029D
:2020E400217D781DE22403FD08E23400FE08E28D2F8E3090FA77E0FEA3E0FFEE24F3FEEFD0
:2021040034F0FF8E828F837463C0E0E4C0E0C02FC0301245F6E58124FCF5818A828B838CAD
:20212400F012628FFA7F00788A7408F2E408F28A828F83C007C0021261CAAD82AE83D002CB
:20214400D007ED2421FDEE34F9FE5302078AF005F07401800225E0D5F0FBF4FA8D828E83C7
:20216400E052028D828E83EAF074F7C0E0746AC0E0125A46158115812274F9C0E0746AC0F9
:20218400E0125A461581158122AF82AE83ADF0FC7820EFF2EE08F2ED08F2EC08F290FA5C4C
:2021A400E0FB7A0090F91FE0FF7E00C003C002C007C006740AC0E0746BC0E0125A46E581FA
:2021C40024FAF581D21812509812498185823285833385F034F53578207977E22414F308C3
:2021E400E2340009F308E2340009F308E2340009F3900019E4F5F0125F41AA82AB83AEF079
:20220400FFEA2532F532EB3533F533EE3534F534EF3535F535124981AA82AB83AEF0FFC33F
:20222400EA9532EB9533EE9534EF9535503C1250AAAF82C374818FF063F08095F050D61236
:202244001A8AAF82BFE8CE90F97175F0001220097F00EF2421FDE434F9FE8D828E83E07067
:20226400060FBF060040EBBF06AB74D8C0E0746AC0E0125A4615811581C218125098025176
:202284004D90F972E4F0A3F090F97175F00022742AC0E0E4C0E0C0E090F9DB1245981581BF
:2022A4001581158190F9DB742AF090F940E0600890F9F174E4F0800690F9F174E7F0740862
:2022C400C0E07450C0E074F9C0E090F9E91246301581158115817408C0E07446C0E074F94A
:2022E400C0E090F9E112463015811581158190F9DCE054F84401F090F9DCE054C74440F0EC
:2023040090F9DDE0440C54CF44C0F090F958E0FF04F090F9DEEFF090F94EE0FEA3E0FF904B
:20232400F9DFEEF0EFA3F07DF27EF98D828E837411C0E07416C0E074F9C0E01246301581E1
:20234400158115817DF27EF97F0078167411F28D828E838FF0121C0690F9DB024F94E58161
:202364002404F581D21812509812514D7F00BF1E004003022445C007122293D007124981DC
:20238400AB82AC83ADF0FE90FA7974642BF0749F3CA3F0740B3DA3F0E43EA3F0C00712503D
:2023A400AAAE82D007C374818EF063F08095F05051C007121A8AAE82D007BEE8028028BEA7
:2023C400E9028005BEEC33802978117403F290F97175F000C007121BA1E582D007602390CC
:2023E400F97175F0008063122285AC82AD83AEF0805890000075F000805090000075F000E0
:202404008048C007124981C8E58124FCC8A68208A68308A6F008F690FA79E0FAA3E0FDA342
:20242400E0FEA3E0FFE58124FCF8C3E69A08E69D08E69E08E69FD00750030223A00F0223B0
:2024440072122285AD82AE83AFF0E58124FCF58122741BC0E0E4C0E0C0E090F9DB1245988A
:2024640015811581158190F9DB7419F090F9F174EAF07408C0E07450C0E074F9C0E090F9D7
:20248400E91246301581158115817408C0E07446C0E074F9C0E090F9E11246301581158164
:2024A400158190F9DCE054F84401F090F9DCE054C74440F090F9DDE0440C54CF44C0F090AB
:2024C400F94EE0FEA3E0FF90F9DFEEF0EFA3F090F958E0FF04F090F9DEEFF090F9DB024FDA
:2024E40094D2181250987F00BF1000506CC007122455D00712498185823A85833B85F03C1C
:20250400F53D12498185823685833785F038F539E536C3953AFAE537953BFCE538953CFDD8
:20252400E539953DFEC3EA94A6EC940EED9400EE94005022C0071250AAAE82D007C374812D
:202544008EF063F08095F050B9C007121A8AAE82D007BEEBAD220F808F22AF82E4FDCD5429
:2025640003A2E0CD13CD13A2E0CD13CD13CDFCEF0303543F4DFDEF030354C0FE7F0074013A
:202584002DFDE43C8F828E838DF022AD82AE83AFF07C007B00BB0400400302261EC0048B9F
:2025A40082C007C006C005C00312255EA882A983AAF0FCD003D005D006D0077416C0E0E49C
:2025C400C0E074F3C0E074F0C0E0888289838AF0EC1206E1E58124FCF5817464C0E074FCF3
:2025E400C0E090F0FB12490315811581920ED004300E218D008E018F027408C0E0C000C016
:202604000190F0F31245C4158115811581920E50038C82220B8B040225997582FF22AF829F
:202624005307F87E007D00BD040040030226AAC0068D82C007C00512255EAA82AB83ACF087
:20264400FED005D0077416C0E0E4C0E074F3C0E074F0C0E08A828B838CF0EE1206E1E58130
:2026640024FCF5817464C0E074FCC0E090F0FB124903158115819228D006302823C00690D2
:20268400F108E0FC5304F87B008F027E00ECB50206EBB506028004D0068005D0068E822250
:2026A4000D8D0602262B7582FF2212255EAC82AD83AEF0FF7416C0E0E4C0E074F3C0E07452
:2026C400F0C0E08C828D838EF0EF1206E1E58124FCF58190F108E0F58222AF828F060EEE22
:2026E40024FB50027E00EEB507038E82228E82C007C00612255EAA82AB83ACF0FDD006D03D
:20270400077416C0E0E4C0E074F3C0E074F0C0E08A828B838CF0ED1206E1E58124FCF5817D
:202724007464C0E074FCC0E090F0FB12490315811581922850A890F108E0FD5305F87C0024
:20274400BD789BBC00988E822212255EAC82AD83AEF0FF7404C0E0E4C0E08C828D838EF057
:20276400EF12092C15811581227F00BF0400500C8F82C00712274DD0070F80EF22AF828F9E
:20278400057E00C005C0067419C0E0746BC0E0125A46E58124FCF5818F8212255E020A6CAF
:2027A4007825E4F208F208F208F27B00BB040040030228438B82C00312255E85823E858318
:2027C4003F85F040F541D0037416C0E0E4C0E074F3C0E074F0C0E0853E82853F838540F0FE
:2027E400E5411206E1E58124FCF5817464C0E074FCC0E090F0FB12490315811581920F503C
:202804003AC00390F104E0FAA3E0FBA3E0FEA3E0FF7825C3E29A08E29B08E29E08E29FD095
:2028240003501890F1047825E0F2A3E008F2A3E008F2A3E008F290F945EBF00B0227B078B9
:2028440025E2F58208E2F58308E2F5F008E222AF82AE83D21090F91FE0FD7C007B007A007F
:202864008C44EBC454F0C544C4C5446544C54454F0C5446544F545EDC4540F4544F544ED16
:20288400C454F0F543754200300D17782FE542F27470254308F2E4354408F2E4354508F234
:2028A40080497810E2F582C007C00612255E85824685834785F048F549D006D00774162555
:2028C40046F546E43547F547E43548F548E43549F549782FE5462542F2E547354308F2E5EB
:2028E40048354408F2E549354508F290FA807405F090FA5CE4F090F94004F07829EFF20803
:20290400EEF27406C0E0E4C0E0C0E090F92112459815811581158190FA80E0FB14F0EB70F6
:2029240003022C961010030229E57829E2FA08E2FB8A828B8378627463F2E408F2125D4AE3
:20294400AA8290FA7DEAF07829E2FB08E2FF8B828F8378837463F2E408F2C00212608DE598
:20296400828583F0D00245F0600690FA7DEA04F090FA7DE024EA500690FA7D7415F090FA32
:202984005CE0FB7A0090FA7DE0FFC3EA9F50528B067F00788A7408F2E408F28E828F83C06E
:2029A40007C006C003C0021261CAAC82AD83D002D003D006D007EC2421FCED34F9FD530637
:2029C400078EF005F07401800225E0D5F0FBFE8C828D83E0FF42068C828D83EEF00B0A80E9
:2029E400A4122362AA82AB83AFF0EA4B7003F582220ABA00010B8A828B838FF012628FFEF4
:202A0400A312628FFF4E60428E048F05C3EC9423ED9400501A7877EEF2EF08F2E408F20808
:202A2400F2900019E4F5F0125F411249E2801BEC24F6FCED34FFFD7F007E008C828D838FDB
:202A4400F0EE121809D218125098900122E4F5F012218D78337401F290FA5CE0FF7E00905C
:202A6400FA7DE0FDC3EE9D505E8F047D00788A7408F2E408F28C828D83C007C006C005C074
:202A8400041261CAAA82AB83D004D005D006D007EA2421F582EB34F9F5835304078CF0052C
:202AA400F07C017D008006EC2CFCED33FDD5F0F7E0FB7A005204EA5205EC4D60067833E49B
:202AC400F280040F0E80987833E27003022C5B90FA7DE07875F2E408F2900063125F21AEE7
:202AE40082AF83782DEEF2EF08F290FA8174F3F074F0A3F0E4A3F090FA5CE0704B90F0F3EC
:202B0400E0FCA3E0FD7829ECF208EDF290F0F5E0FCA3E0FD782BECF208EDF290FA7EE4F0DA
:202B2400A3F0782DE2FC08E2FDEC24FCFCED34FFFD782DECF2ED08F290FA81740424F3F07B
:202B4400E434F0A3F0E4A3F07829E2FC08E2FD782DC3E2F5F0EC95F008E2F5F0ED95F050C8
:202B64000A7829792DE2F308E209F37829E2FC08E2FD782DD3E29CF4B3FCB308E29DF4FD1B
:202B84007829ECF208EDF27582041217C490FA81E0F546A3E0F547A3E0F548AA46AF4778E0
:202BA4002DE2C0E008E2C0E0C002C007782FE2F58208E2F58308E2F5F008E212081CE58198
:202BC40024FCF5817582041217FD782DE2FA08E2FD7E007F00782FE22AF208E23DF208E22D
:202BE4003EF208E23FF2AD46AE47AF48782DE2F54608E2F547AA46AC47154674FFB5460211
:202C04001547EA4C60368D828E838FF012628FFCA3AD82AE838C4275430090FA7EE0FAA3DC
:202C2400E0FC8A4A8C4BAB42AC43EB254AFBEC354BFC90FA7EEBF0ECA3F080B990FA7DE0EE
:202C4400FF90FA5CE02FF07829E2FE08E2FF4E60067833E4F2D21090F940E4F07833E27071
:202C64000302291B782BE2FE08E2FF90FA7EE0FCA3E0FDEEB50406EFB5050280117433C0E7
:202C8400E0746BC0E0125A461581158180047582012275820022AFF0AE83E58290FA88F003
:202CA400EEA3F0EFA3F090FA88E0FDA3E0FEA3E00DBD00010E8D828E837408C0E07430C0A1
:202CC400E074F9C0E01245C41581158115819211501490F938E0FCA3E0FDA3E0FEA3E0FFFF
:202CE400EC4D4E4F707490F91FE4F090FA88E0FDA3E0FEA3E0FF74012DFAE43EFBC002C06D
:202D04000390F9171244C615811581740D2DFAE43EFB8F048A828B838CF012628FFA90F950
:202D240020F07411C0E0C005C00690F92F1246301581158115817408C0E0E4C0E09070002D
:202D4400E4F5F012092C1581158190F938E0FEA3E0FF90FA86EEF0EFA3F090F938E0FCA362
:202D6400E0FDA3E0FEA3E0FFEC4D4E4F7003022DF3C3E49C74109DE49EE49F500B90FA8432
:202D8400E4F07410A3F0800890FA84ECF0EDA3F0D20D90FA84E0FEA3E0FF8E828F831228A9
:202DA40053E582604690F91FE0FF0F90F91FEFF090F938E0FCA3E0FDA3E0FEA3E0FF90FAE8
:202DC40084E0FAA3E0FB8A008B01E4FAFBECC398FCED99FDEE9AFEEF9BFF90F938ECF0EDC5
:202DE400A3F0EEA3F0EFA3F0022D5E7582002275820122AFF0AE83E58290FA8DF0EEA3F0BA
:202E0400EFA3F090FA8DE0FDA3E0FEA3E0FF74012DFAE43EFB8F048A828B837408C0E0743F
:202E240030C0E074F9C0E01245C41581158115819212504090F93DE0FC740E2DFDE43EFE32
:202E44008D828E838FF012628FFDECB5052690F938E0FCA3E0FDA3E0FEA3E0FFEC4D4E4F0D
:202E64006012744BC0E0746BC0E0125A46158115810230017582041217C490F9457834E0AB
:202E8400F290FA8DE0FCA3E0FDA3E0FE740E2CFAE43DFB8E078A828B838FF012628FFA5405
:202EA400FC60317834E2FB7F00C003C007745EC0E0746BC0E0125A46E58124FCF58190FAC6
:202EC4006E7411F0E4A3F08C828D838EF0121B117834E4F290F945E02401F0FFBF04004073
:202EE4000590F945E4F090F945E0FF7834E2B507197582041217FD7482C0E0746BC0E012CF
:202F04005A4615811581758201228F8212255EAC82AD83AEF0FF7416C0E0E4C0E074F3C051
:202F2400E074F0C0E08C828D838EF0EF1206E1E58124FCF5817464C0E074FCC0E090F0FB26
:202F4400124903158115819212500890F108E054F8708190F945E0FF7810F28F8212255E74
:202F6400AC82AD83AEF0FF7404C0E0E4C0E08C828D838EF0EF12092C1581158175820412AB
:202F840017FD7810E2FE7F00C006C007748CC0E0746BC0E0125A46E58124FCF58190F91F30
:202FA400E4F090FA8DE0FDA3E0FEA3E0FF74012DFAE43EFBC002C00390F9171244C61581B2
:202FC4001581740D2DFAE43EFB8F048A828B838CF012628FFA90F920F07411C0E0C005C029
:202FE4000690F92F12463015811581158190F938E0FEA3E0FF90FA8BEEF0EFA3F090F9386E
:20300400E0FCA3E0FDA3E0FEA3E0FFEC4D4E4F7003023098C3E49C74109DE49EE49F500B76
:2030240090FA84E4F07410A3F0800890FA84ECF0EDA3F090FA84E0FEA3E0FF8E828F8312FF
:203044002853E582604A90F91FE0FF0F90F91FEFF090F938E0F54CA3E0F54DA3E0F54EA3B3
:20306400E0F54F90FA84E0FAA3E0FBE4FEFFE54CC39AFAE54D9BFBE54E9EFEE54F9FFF9060
:20308400F938EAF0EBA3F0EEA3F0EFA3F0023001758200227582041217C47430C0E074F9BB
:2030A400C0E090F0F31244C61581158190F0FB7421F07447A3F0744DA3F07447A3F090F938
:2030C40041E02401F0A3E03400F0A3E03400F0A3E03400F090F941E0FCA3E0FDA3E0FEA377
:2030E400E0FF90F104ECF0EDA3F0EEA3F0EFA3F090FA8BE0FEA3E0FF7D007C0090F0FFEE2E
:20310400F0EFA3F0EDA3F0ECA3F090F93CE090F103F090F93DE090F108F07810E2F582120F
:20312400255EAC82AD83AEF0FF7416C0E0E4C0E074F3C0E074F0C0E08C828D838EF0EF12B7
:20314400081CE58124FCF5817582041217FD75820122AFF0AE83E58290FA91F0EEA3F0EF5E
:20316400A3F0C20D90FA91E0F553A3E0F554A3E0F555740D2553FAE43554FBAC558A828B1A
:20318400838CF012628FFCBC02028024BC03030234DEBC10028019BC20028014BC210280BB
:2031A4000FBCA8030233D1BCAF030234BE02355390FA91E0FFA3E0FEA3E0FD75509075518D
:2031C400FA755200740E2FF553E43EF5548D558553828554838555F012628FFB855082858A
:2031E40051838552F0125F0690FA90E020E2030232B5758204C007C006C0051217C4D005C2
:20320400D006D00790FA90E0C423541FFB603CBB0F02806C8553828554838555F012628FD7
:20322400F582C007C006C005122622AB82D005D006D007BBFF0280488B82C007C006C005D5
:2032440012274DD005D006D007803574012FF553E43EF5548D558553828554838555F0C034
:2032640007C006C00512258FAB82D005D006D007BBFF02800B1224E578357401F20233CBCD
:20328400758204C007C006C0051217FDD005D006D0078F828E838DF0122DF7E582600B127C
:2032A40024E578357401F20233CB7835E4F20233CB74012FF553E43EF5548D558553508584
:2032C40054518555528550828551837408C0E07427C0E074F9C0E01245C415811581158128
:2032E4009213500B1224E578357401F20233CB758204C007C006C0051217C485538285542E
:20330400838555F012258FAC82758204C0041217FDD004D005D006D007BCFF028051C007D8
:20332400C006C005C0041224E5D004D005D006D0078F538E548D55AA53AB547411C0E0C042
:2033440002C00390F92F12463015811581158190F938E4F0A3F0A3F0A3F090FC63ECF090F9
:20336400FA90E054037824F28C82122781803D749AC0E0746BC0E0125A46158115818F8259
:203384008E838DF0122DF7E582601B1224E57810E2FB90FC63F090FA90E054037824F28BBA
:2033A4008212278180067835E4F2801B90F930E0FAA3E0FBC002C00390F9271244C6158131
:2033C400158178357401F27835E2F5822290F938E0FAA3E0FBA3E0FEA3E0FFEA4B4E4F70B9
:2033E4002F74012553FDE43554FEAF558D828E837408C0E07430C0E074F9C0E01245C41584
:203404008115811581921350071224E57582012290F91FE4F090FA91E0F550A3E0F551A3A2
:20342400E0F55274012550FAE43551FBC002C00390F9171244C615811581740D2550FDE4D4
:203444003551FEAF528D828E838FF012628F90F920F0AD50AE517411C0E0C005C00690F973
:203464002F12463015811581158174092550FDE43551FEAF528D828E838FF012628FFDA335
:2034840012628FFE8D828E83122853E582602790F938E4F0A3F0A3F0A3F07582041217C456
:2034A40090F0F775F0001213CB7582041217FD1224E575820122758200221224E5740E250B
:2034C40053FDE43554FEAF558D828E838FF012628FF58212045A758201227582041217C49E
:2034E4008553828554838555F0122C9AE582605B1224E57582041217C412356E300D111236
:203504003B03907019E4F5F01206C1125616805674A2C0E0746BC0E0125A461581158175D2
:2035240082041217FD90FA5B7401F090F0E374E0F0123B7C7408C0E0E4C0E0C0E090F92731
:20354400124598158115811581801B758200227F00C004C00774BFC0E0746BC0E0125A46F4
:20356400E58124FCF58175820022783AE4F208F208F208F2C20D7419C0E0E4C0E074A2C066
:20358400E074FDC0E0907000E4F5F01206E1E58124FCF58178367419F2747008F2E408F28F
:2035A40008F29062BD93FD740193FE7402937406C0E0C005C00690FDAB1245C4158115819B
:2035C40015819214500790F08F7405F0229062BDE493FD740193FE7402937409C0E0C005A6
:2035E400C00690FDAB1245C41581158115819214500790F08F7402F02290FDAAE0FFBF0182
:2036040002800790F08F7401F02290FDA8E0FEA3E0FFC3E49E74809F500790F08F7403F04D
:203624002290FDA8E0FEA3E0FF4E70030236E190FDA8E0FEA3E0FFC374239E74089F5004F9
:203644007E237F08C006C00774F3C0E074F0C0E07836E2F58208E2F58308E2F5F008E21272
:2036640006E1E58124FCF58190FA9474F3F074F0A3F0E4A3F090FA97EEF0EFA3F0783AE26B
:20368400F58208E2F58308E2F5F008E2C007C0061237BA783AC0E0E582F2E58308F2E5F022
:2036A40008F2D0E008F2D006D0078E028F037C007D007836E22AF208E23BF208E23CF208B7
:2036C400E23DF290FDA8E0FCA3E0FDECC39EFEED9FFF90FDA8EEF0EFA3F002362590FDA24D
:2036E400E0FCA3E0FDA3E0FEA3E0FF783AE2B5041108E2B5050C08E2B5060708E2B5070205
:20370400800790F08F7404F02290FDA6E0FEA3E0FF90F08DEEF0EFA3F0C006C00774DFC0E5
:20372400E0746BC0E0125A46E58124FCF581D20D221227A4AC82AD83AEF0FF90F941ECF0F9
:20374400EDA3F0EEA3F0EFA3F0227408C0E07450C0E074F9C0E090FA66124630158115818F
:20376400158190FA5DE054F84421F090FA5EE054F344C8F090FA607437F07413A3F090FA13
:203784006274FFF0A3F090FA647437F07413A3F0227411C0E0745DC0E074FAC0E090F9DCFF
:2037A40012463015811581158190F958E0FF04F090F9DEEFF022AC82AD83AEF0FF783EEC02
:2037C400F4F2EDF408F2EEF408F2EFF408F290FA94E0F55EA3E0F55FA3E0F56090FA97E06A
:2037E400F55AA3E0F55B855A5C855B5D155A74FFB55A02155BE55C455D70030238B8855E9D
:2038040082855F838560F012628FFEA385825E85835F8E047D007E007B00783EE26CF20870
:20382400E26DF208E26EF208E26BF27846E4F208F27846C3E2940808E26480948050A778D4
:203844003EE25401FA08E25400FB08E25400FC08E25400FE7842C3E49AF2E49B08F2E49C60
:2038640008F2E49E08F27841E2C313F56418E213F56318E213F56218E213F5617842E254E8
:2038840020FC08E25483FD08E254B8FE08E254EDFA783EEC6561F2ED656208F2EE6563086B
:2038A400F2EA656408F27846E22401F208E23400F2023835783EE2F4FB08E2F4FC08E2F4F0
:0B38C400FD08E2F48B828C838DF02263
:206AD8000A002530327820004150206F6E2025640A004E6F204150206F6E2025640A002EE8
:206AF80000636865636B435243206661696C65640A00524551202564207061727420256408
:206B18000044726177696E6720696D61676520696E20736C6F742025640A00626C6B206623
:206B380061696C65642076616C69646174696F6E210A0072657374617274696E6720696D8F
:206B58006720646C0A004368616E67696E67207374617274696E67536C6F742066726F6D9B
:206B780020256420746F20300A004E6F20736C6F74730A006E657720646C20746F202564F5
:206B98000A00646C20696D670A004F544120696D6167652076616C69646174696F6E2066C4
:206BB80061696C65640A00646174615479706520307825782069676E6F7265640A00436856
:206BD800726F6D613239004F54412076616C6964617465642C207570646174696E67207495
:0F6BF8006F2076657273696F6E202530780A0002
:05767200FF21474D4718
:2038CF00E58620E0FB225390FD00225380FB0022E58620E0FB004390020022E58620E0FB9C
:2038EF0000438004002290F09B7438F0E4A3F030050990F09B7430F0E4A3F02290F959E05A
:20390F00704590F0C7E0603FC20490F09F7410F0C4A3F090F0A17406F0E4A3F09071D9751C
:20392F00F080120D72D20490F09F7418F07401A3F090F0A1740DF0E4A3F09071FB75F08014
:20394F00120D72D2038002C203300A2690F0C6E06020C20490F09F7410F0C4A3F090F0A1D4
:20396F007470F0E4A3F090720575F080120D72D20222C20222123EBD742CC0E07472C0E0C1
:20398F0012416C15811581743FC0E07472C0E012416C1581158190F09BE0FEA3E0FF740872
:2039AF002EFEE43FFF90F09BEEF0EFA3F07452C0E07472C0E012416C158115817475C0E0CF
:2039CF007472C0E012416C158115817497C0E07472C0E012416C1581158190F09BE0FEA3AF
:2039EF00E0FF74082EFEE43FFF90F09BEEF0EFA3F090F09DE4F0A3F07427C0E07472C0E04F
:203A0F0012416C15811581023A39758205123E9AE58260012274B5C0E07472C0E0125A4666
:203A2F0015811581903984020D4C7436C0E074FCC0E0E4C0E074C1C0E07472C0E012416CAB
:203A4F00E58124FBF581229062BBE493C0E0740193C0E074CDC0E07472C0E012416CE58142
:203A6F0024FCF58122123EBD123ED974DCC0E07472C0E012416C15811581123A5690F0E5E1
:203A8F00E0C0E0A3E0C0E074EDC0E07472C0E012416CE58124FCF58190FAB4E0FF3395E06D
:203AAF00FEC007C00674FBC0E07472C0E012416CE58124FCF581023A39758201123E9AE5E0
:203ACF00826001221219A2903A74020D4C123EBD123ED9C2051238F590F08DE0C0E0A3E020
:203AEF00C0E0740EC0E07473C0E012416CE58124FCF58122903ADC020D4C123EBD123ED95A
:203B0F00D2057424C0E07473C0E012416C15811581D20490F08FE0FFBF02028018BF040231
:203B2F008023BF05307435C0E07473C0E012416C15811581227444C0E07473C0E012416C64
:203B4F0015811581227455C0E07473C0E012416C15811581227E00C007C0067460C0E07418
:203B6F0073C0E012416CE58124FCF58122903B09020D4C123EBD123ED9746FC0E07473C0B7
:203B8F00E012416C158115817487C0E07473C0E012416C1581158190F09BE0FEA3E0FF9033
:203BAF00F0A1EEF0EFA3F090F94CE0FF7E0090F94DE0FD7C00C007C006C005C00474A0C0BA
:203BCF00E07473C0E012416CE58124FAF58190F94AE0FF7E0090F94BE0FD7C00C007C006CC
:203BEF00C005C00474B2C0E07473C0E012416CE58124FAF58190F948E0FF7E0090F949E047
:203C0F00FD7C00C007C006C005C00474B2C0E07473C0E012416CE58124FAF58190F946E051
:203C2F00FF7E0090F947E0FD7C00C007C006C005C00474B2C0E07473C0E012416CE5812423
:203C4F00FAF58190F099E0FEA3E0FF8E02EFFB3395E0FCFD7428C39AF50F74019BF510E45B
:203C6F009CF511E49DF512906F2DE493FDE4FC3395E0FBFAE50FC39DFDE5109CFCE5119B7F
:203C8F00FBE5129AFA78647402F2E408F208F208F28D828C838BF0EAC007C006125D95AABB
:203CAF0082AB83D006D00790F09FEA2EF0EB3FA3F090F0BFE0FF7E0090F0C0E0FD3395E053
:203CCF00FC90F959E0FB7A00C007C006C005C004C003C00274BBC0E07473C0E012416CE50D
:203CEF008124F8F581123F5A023A56758203123E9AE5826001221219A2903B82020D4C1210
:203D0F003EBD123ED974D5C0E07473C0E012416C1581158174E8C0E07473C0E012416C15BE
:203D2F0081158190F099E0FEA3E0FF90FA99EEF0EFA3F090F09BE0FEA3E0FF90F0A1EEF0E7
:203D4F00EFA3F074FDC0E07473C0E012416C1581158190FA99E0FEA3E0FF8E02EFFB33958A
:203D6F00E0FCFD74F0C39AFAE49BFBE49CFCE49DFD78647402F2E408F208F208F28A828B7F
:203D8F00838CF0EDC007C006125D95AA82AB83D006D007EA2EFEEB3FFF90F09FEEF0EFA3C2
:203DAF00F0EE5407601574075EFC7D00EEC39CFEEF9DFF90F09FEEF0EFA3F0906F2D75F00E
:203DCF0080120D7290F0A1E0FEA3E0FF74082EFEE43FFF90F0A1EEF0EFA3F0D2049070B76A
:203DEF0075F080120D7202390B758204123E9AE582600122903D0E020D4C123EBD123ED9BD
:203E0F0090F09BE0FEA3E0FF74102EFEE43FFF90F09BEEF0EFA3F07411C0E07474C0E0120C
:203E2F00416C15811581123F5A02390B758205123E9AE582600122903E09020D4C123EBD9A
:203E4F00123ED97421C0E07474C0E012416C158115817435C0E07474C0E012416C15811547
:203E6F008190F09F747CF0E4A3F090F09BE0FEA3E0FF90F0A1EEF0EFA3F0D2049070B7753E
:203E8F00F080020D72903E4C020D4CE582C40354F8F582122622AF82BFFF02800D7824E464
:203EAF00F28F821227817582012275820022C206C204C20590F099E4F0A3F090F09DF0A37E
:203ECF00F090F09BF0A3F0C20922D20490F0A1E4F0A3F0906DAA93FF7E007428C39FFF74D2
:203EEF00019EFE90F09FEFF0EEA3F0906DA975F080120D72C204906C08E493FF7E0090F03D
:203F0F009FE0FCA3E0FDECC39FFFED9EFE90F09FEFF0EEA3F0906C0775F080120D72906ECB
:203F2F006CE493FF7E0090F09FE0FCA3E0FDECC39FFFED9EFE90F09FEFF0EEA3F0D20490DC
:203F4F006E6B75F080120D72C2042290F0E9E0FEA3E0FF4E601190F0E7E0FCA3E0FDC3EE1F
:203F6F009CEF9D5002800890F0E7E0FEA3E0FFC006C007744FC0E07474C0E012416CE581CC
:053F8F0024FCF5812275
:206C0700801AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000000000000000E3
:206C270000000000000000000000000000000000000000000000000000000000000000004D
:206C47000000000000000000000000000000000000001C000000001F9F800000000038702B
:206C670001C07F000000001F9FC000000000387001C07F000000001F9FE000000000387021
:206C870001C0F7800000001C1CE000000000380001C0E3800000001C1CE0000000003800F1
:206CA70001C0E39DC1C7701F9CE773B871D03873B9C7E39FE3E7F81F9FEFF3FCF9F03873E7
:206CC700FDCEE39FE777F81F9FCFF3FDDDF03873FDDCE39CE7F7381C1F8E739DFDC0387366
:206CE7009DF8E39CE7F7381C1C0E739DFDC038739DF8F79CE707381C1C0E739DC1C03873D5
:206D07009DDC7F1FE7F7381F9C0FF3FDFDC03F739DDC7F1FE3E7381F9C0FF3FCF9C03F73D9
:206D27009DCE1E1DC1C7381F9C0773B871C03F739DC7001C00000000000003800000000013
:206D47000000001C0000000000000380000000000000001C000000000000038000000000EE
:206D67000000001C000000000000038000000000000000000000000000000000000000006D
:206D8700000000000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFA
:206DA700FFFF800C000882A2AB55BFFFFFFF7DB4622800000010101176FF7BFFFF7FB7A9A1
:206DC70055505100002922966FF7BFFFFFFFEAE622AA08000002542ABF3F7FFFFFFFFD59BF
:206DE700B4102000002423B5B5DFFFFFFFFFF6AE48551000008890546AEFFFFFFFFFFBF51A
:206E0700A382000000012DA3B3FFFFFFFFFFF6BE4E5209000490020D55DFFFFFFFFFFDDDBD
:206E270068A9001000490CFBAB6FFFFFFFFFFEEB955A002000129122BFDFFFFFFFFFFFF579
:206E4700658140400028127DEFFFFFFFFFFFFFEFAB28000000420A9775FFFFFFFFFFFFF71A
:206E67004AC20400800C0008029CDFFFFFFFFFFFFF6A6A8D002000044D72AAFFFFFFFFFF07
:206E8700FFD5D57480000240128EDFFDFFFFFFFFFFAEAA0A11200020525FF57FFFFFFFFFC1
:206EA700FF7294AA240000010AAB6F77FFFFFFFFFDAF545488000004804D95EBFFFFFFFF37
:206EC7005B58B5514000000808A6B3F77FFFFFFFFFAD4AA0100000029641DCAEFFFFFFFFD1
:206EE700FDBFEA4802000000093EAB75EFFFFFFFFFD4B121080000000AC35DFF7FFFFFFFF6
:206F0700EFEF444A64800000A152A6EFEFFFFFFFD6CAF5101800000002154BD5DFFFFFF7DE
:206F2700EBD4D88500003838000000000000000000000000000000000000000000000000BE
:206F47000000000000000000000000000000000007C00000000001FFF0000000000FFFF075
:206F6700000000007FFFF000000001FFFFF000000007FFFFC00000001FFF80000000007FCB
:206F8700F80000000000FFE00000000001FF000000000007FE00000000000FF80000000007
:206FA700001FE000000000003FC00003E000007F80007FF00000FE0003FFF00001FC000F7F
:206FC700FFF00001F8003FFFF00003F800FFFF800007F001FFE000000FE003FF0000000F44
:206FE700C00FF80000001F801FF00000001F803FC00000003F003F800000003F007F0000BB
:2070070000007E00FE0007E0007E01FC001FF000FC01F8007FF000FC03F001FFF000F8033E
:20702700F003FFF001F807E007FF0001F807E00FF00001F00FC01FE00001F00FC03F800064
:2070470003F00F803F000003F01F807E000003E01F807E000003E01F00FC01E003E01F0077
:20706700FC07F803E01F00F80FFC03E03F00F80FFC03E03F01F81FFE03E03F01F81FFE0371
:20708700E03F01F81FFE03C03E01F01FFE01C01E00F00FFC00000000000FFC0000000000C0
:2070A70007F8000000000001E000000000000000303000001FF800000000FFFF0000000371
:2070C700FFFFE000000FFFFFF000003FFFFFFC00007FF00FFE0000FF8001FF0001FE00009B
:2070E7007F8003F800001FC007F000003FE00FE000007FF00FC00000FFF01F800001FFF8E7
:207107001F000003FFF83F000007FEFC3E00000FFC7C7E00001FF87E7C00003FF03E7C00D2
:20712700007FE03EFC0000FFC03FF80001FF801FF80003FF001FF80007FE001FF8000FFCE2
:20714700001FF8001FF8001FF8003FF0001FF8007FE0001FF800FFC0001FFC01FF80003F8E
:207167007C03FF00003E7C07FE00003E7E0FFC00007E3E1FF800007C3F3FF00000FC3F7F8D
:20718700E00000FC1FFFC00001F80FFF800003F00FFF000007F007FE00000FE003FC0000BC
:2071A7001FC001FE00007F8000FF8001FF00007FF00FFE00003FFFFFFC00000FFFFFF000BA
:2071C7000003FFFFE0000000FFFF000000001FF800001010000000000000000000007C0016
:2071E7008200000038004407007903811C0103810079000708080063773E1C3E77631010E9
:20720700000003C00FF0081008100810081008100810081008100BD00BD008100FF0000018
:207227000A000A0A0009084F70656E4550617065724C696E6B0A08006F70656E6570617051
:2072470065726C696E6B2E64650A0049276D0920666173742061736C656570202E202E2097
:207267002E20746F2077616B65206D653A000A52656D6F7665206261747465726965732C5B
:207287002073686F727420626174746572790A00636F6E74616374732C207265696E736541
:2072A7007274206261747465726965732E004465657020736C6565700A00546167204D4145
:2072C700433A202573004368726F6D613239207625303458005374617274696E67202E207C
:2072E7002E202E0A0A000A564261743A202564206D560A0054656D70657261747572653AE8
:20730700202564430A0A000C466C617368696E67207625303478202E202E202E000C4F54FE
:2073270041204641494C4544203A280A0A000C4E6F74204F544120696D616765000C577271
:207347006F6E67204F544120696D616765000C435243206572726F72000C4572726F722057
:20736700436F64652025640057616974696E6720666F722064617461202E202E202E0A00FA
:207387000A466F756E642074686520666F6C6C6F77696E672041503A000A4150204D414317
:2073A7003A202530325825303258002530325825303258000A43683A2025642052535349F7
:2073C7003A202564204C51493A2025640A00084E6F20415020666F756E64203A280A080A80
:2073E700005765276C6C2074727920616761696E20696E2061000A6C6974746C652077681D
:20740700696C65202E202E202E00087A7A5A5A5A202E202E202E0A080A000C454550524FAA
:207427004D204641494C4544203A280A0A000C536C656570696E6720666F72657665722021
:157447002E202E202E0A0A00564261743A202564206D560A0015
:203F9400C007C006C005C004C00390FAA2E0600302408890FAA3E0FF24FB5003024085EFC7
:203FB4002F2F903FBA73023FC9023FE702406802407F02408590FAA0744BF0E4A3F090FA55
:203FD400A2740BF090FAA37401F090FAA47468F002408890FA9D1248B0E582FF6045EF2417
:203FF400E0FFBF600040027F1F90FAA5E0FE0E90FAA5EEF0C0078E821243DAAD82AE83152C
:204014008190FAA4E0FC7B002DFDEB3EFE8D828E837467C0E01248ABAE82158190FAA4EEB3
:20403400F0800B90FAA37402F090FAA4E0FFEF75F002A4245CF582747435F0F583E493FE66
:20405400A3E493FF90FAA0EEF0EFA3F090FAA2740BF0802090FAA37403F090FAA074E3F069
:20407400741AA3F090FAA203F0800990FAA37404F0C3802D90FAA0E0FEA3E0FFEE5401246D
:20409400FFE433FDEFC313CE13CEFF90FAA0EEF0EFA3F090FAA2E0FF1F90FAA2EFF0ED24B6
:0C40B400FFD003D004D005D006D00722B6
:20745C009B01B3013303C90089019101990019013101930013012301CD01D90199039D0113
:20747C00B90139037302D30193033B017301B7039701A7012703370167016702DB001B0345
:20749C006303C500D10011038D00B10031028B00A3002302ED008D03B103DD001D0371035A
:2074BC0077038B03A303BB003B02BB03D70017034703B7003702C702F70213028F02650054
:2074DC00850169000903A10121034D000D01590019026101610243025300EF024301F1027B
:2074FC00E501E901C9033D01790179022F014F014F02DB037B036F03F500C503D103BD00B4
:0E751C003D02AF002F02DD03BD03D703AF0316
:2040C000C007C006C005C004C001C000AC82AD83AEF0FFBF20005031BF0A0302415F8F826F
:2040E000C007C006C005C004C003C002C001C000C0251242A7D025D000D001D002D003D0B9
:2041000004D005D006D00780567E00EF24E0FFEE34FFFEEF2FFFEE33FEEF2498F582EE3434
:2041200063F583E493A3E493C4540FFE90F0B3EEF0300507EE2EFE90F0B3F090F0B3E0FF52
:204140003395E0FE0FBF00010E90F099E0FCA3E0FDEF2CFFEE3DFE90F099EFF0EEA3F0D0DB
:2041600000D001D004D005D006D00722C007C006C005C004C003C001C000E58124F6FFC05D
:2041800007C006C005C004C003C002C001C000C02512425AD025D000D001D002D003D00421
:2041A000D005D006D007E58124F6F886050886068D828E83E493FCBC0C7290F099E4F0A389
:2041C000F0C007C005C006C0E0C0E09040C01256F5E58124FBF58190F099E0FDA3E0FE33CB
:2041E00095E0FCFB7428C39DFD74019EFEE49CFCE49BFB78647402F2E408F208F208F28DB0
:20420000828E838CF0EBC007C002C001C000C025125D95AB82AC83ADF0FED025D000D00124
:20422000D002D00790F099EBF0ECA3F0C007E58124F5F8E6C0E008E6C0E0E4C0E0C0E0905C
:20424000109A1256F5E58124FBF581D000D001D003D004D005D006D00722300625300506DA
:204260007E147F0080047E0A7F0090F0B4EEF03005067E207F0080047E107F0090F0B3EE86
:20428000F0223005067E207F0080047E107F0090F0B4EEF03005067E147F0080047E0A7F3A
:2042A0000090F0B3EEF022AF82BF08028018BF0902804EBF0A028013BF0B028055BF0C01D6
:2042C00022BF0D568038B20502425A12425A90F0B4E0FE3395E0FD90F09BE0FBA3E0FCEEC5
:2042E0002BFEED3CFD90F09BEEF0EDA3F090F09DE0FDA3E0FE90F099EDF0EEA3F022B2042C
:204300002290F099E0FDA3E0FE90F09DEDF0EEA3F02290F09DE4F0A3F0227E00C007C006B6
:12432000742AC0E07475C0E0125A46E58124FCF58122F4
:15752A00496E76616C69642063686172203078253032780A00F6
:20433200E58620E0FB225390FD00225380FB0022E58620E0FB004390020022E58620E0FB2E
:2043520000438004002275FB02228582F9E5F830E1FB53F8FDE5F820E0FB85F9822253F35D
:20437200C775FA2275FC0C75F8C043F4C043F102D20B2253F1FD53F43F75FA0075FC3175B0
:08439200F84043F338C20B228E
:20439A00858283D0F0D0E0D082C082C0E0C0F022C00074FB2581F8E5828682088683088628
:2043BA00F0D0002275F008C58213C58233D5F0F7C58222E583A2E713F583E58213F582220C
:2043DA00D083D0E0D0F0C0F0C0E0C083E582A4F58285F08322C000E58124FDF8E6F88582AD
:2043FA00F0A4F582E8A8F08583F0A428F583E5F03400F5F0E4D00022C000C001C0E0C0F047
:20441A0074FA2581F88600E58288F0A4F582A9F0E58388F0A429F583E5F03400F9D0E088FE
:20443A00F0A429C5F03400F9D0E0C0F088F0A429D0F0D001D00022C000C001C002E58124CE
:20445A00FBF8E6F918E6F88582F0A4C0E0AAF0E58388F0A42AF8E5F03400FAE98582F0A478
:20447A0028C0E0E5F03AFA74003400F8E98583F0A42AFAE5F0388AF0D083D082D002D00139
:20449A00D00022D0E0D0F0C000C001C002C0F0C0E074F82581F9E7F809E7F922D002D00175
:2044BA00D00022C9C583C9C8C582C82212449D75F0081244BDE0A31244BDF0A3D5F0F302C7
:2044DA0044B612449D75F0081244BDE493A31244BDF0A3D5F0F20244B612449DC375F008BF
:2044FA001244BDE0A3F5021244BDE03AF0A3D5F0EF0244B612449D75F0081244BDE0A3F5BA
:20451A00021244BDE05AF0A3D5F0EF0244B612449DC375F0081244BDE0A3F5021244BDE04C
:20453A009AF0A3D5F0EF0244B612449DC375F0081244BDE0A3F5021244BDE0A39AD5F0F0EF
:20455A000244B612449D75F0081244BDE0A3F5021244BDE0A36A7007D5F0EED30244B6C39C
:20457A000244B6C8C0E075F008E038F0A3D5F0F9D00022D3E402457DC374FF02457DC000C0
:20459A00C00174FA2581F8E6F5F0088601496015088600E8F0A374FF25F0F5F074FF39F505
:2045BA000145F070EED001D00022C000C001C00274F92581F9E7D3601CF5F0098700098700
:2045DA0001C3E0F502A31244BDE0A31244BD6A7004D5F0EED3D002D001D00022C000C00160
:2045FA00C00274F82581F9E7F5F00987024A601F0987000987011244BDE0A31244BDF0A350
:20461A0074FF25F0F5F074FF3AF50245F070E7D002D001D00022C000C001C00274F92581F8
:20463A00F9E76015F5F00987000987011244BDE0A31244BDF0A3D5F0F3D002D001D000227C
:20465A00C083C082E06003A380FAC3E582D0F095F0F582E583D0F095F0F58322C003C002A9
:20467A00C001C000C0E0C0F0C083C082A98174F62581F886F018860075020175030075829D
:20469A0011A2F74014C3E833F8E5F033F5F0C3EA33FAEB33FB058280E8E4C003C002C0E054
:2046BA00C0E0AA81C0F0C000C0E0C0E0A881C0E0C0E0C0E0C0E0AB81C000C001C375830450
:2046DA0086F018E71995F0D583F6D001D000402BC000C001C375830486F018E795F0F71909
:2046FA00D583F585020085030175830486F018E745F0F719D583F5D001D00074FC28F8C34C
:20471A0075830408E613F6D583F9C00074FC2AF8C375830408E613F6D583F9D000D5829823
:20473A0020D508D082D083D0F0D00074F42581F58130D508D082D083D0F0D000E8D000D0DF
:20475A0001D002D00322C2D5024676D2D5024676C003C002C001C000C0E0C0F0C083C082E2
:20477A00A98174F62581F886F07401758219A2F7400A23C5F023C5F0058280F2C0E0E4C022
:20479A00E0C0E0C0E0AA81C0F0C0E0C0E0C0E0A881C0E0C0E0C0E0C0E0AB81C000C001C30B
:2047BA0075830486F018E71995F0D583F6D001D000402BC000C001C375830486F018E7952C
:2047DA00F0F719D583F585020085030175830486F018E745F0F719D583F5D001D00074FC4E
:2047FA0028F8C375830408E613F6D583F9C00074FC2AF8C375830408E613F6D583F9D0004F
:20481A00D58298D082D083D0F0D00074F42581F581E8D000D001D002D00322C006C005C03B
:20483A0004C003C002C001C00074F72581F886F074017C09A2F7400923C5F023C5F00C80BD
:20485A00F3FBE4FAA9F0F88582F0FDFEC3E58298E583994011C3E58298F582E58399F58329
:20487A00EA4DFDEB4EFEC3E913F9E813F8C3EB13FBEA13FADCD620D5048D828E83D000D0EA
:20489A0001D002D003D004D005D00622C2D5024835D2D5024835E0C0E02401F0A3E0C0E0C3
:2048BA003400F0A3E0D083D0826014B4600AC000A882E2D000F582224009E493F58222E092
:2048DA00F58222C000A882E6D000F5822212449D75F004D31244BDE0FA3400F0EAA31244C9
:2048FA00BDF0A3D5F0EE0244B612449D75F004C31244BDE0FAA31244BDE0A36A7004D5F0B7
:20491A00EFD30244B612449DC3E0A398E0A399E0A39400E0A394000244B612449DC3E0A36F
:20493A0038E0A339E0A33400E0A334000244B675F004E07004A3D5F0F9F58222A3A3A3E07F
:02495A00332206
:04495C0075C90B22EC
:20496000C0E0C007C006C0D075D000AEDAAFDB74012EF5DAE43FF5DBD0D0D006D007D0E0C1
:2049800032C007C006C005C004C000AEDAAFDB784AEEF208EFF27848E5E2F27849E5E3F27E
:2049A000EEB5DAE7EFB5DBE37848E2FC08E2FD08E2FE08E28C828D838EF0D000D004D005C5
:2049C000D006D0072285E28222E4F5DAF5DBF5E4F5E5F5E6F5E7F5E275E40543D84043B885
:2049E0000222AF82AE83ADF0FC784CEFF2EE08F2ED08F2EC08F21249817850C0E0E582F2A1
:204A0000E58308F2E5F008F2D0E008F2124981AA82AB83AEF0FF7850D3E29AF4B3FAB30875
:204A2000E29BF4B3FBB308E29EF4B3FEB308E29FF4FF784CC3E29A08E29B08E29E08E29FAF
:034A400050CA2237
:204A430053C07F53A1FE53BEFC3243870122AF82AE83ADF0FC7854EFF2EE08F2ED08F2EC40
:204A630008F290FAA6E4F090FAA7F090FAA874DFF090FAA974BEF090FAAAE054E0F090FA88
:204A8300AAE0541FF090FAAB7407F090FAACE054E0F090FAACE0549F4420F090FAACE05485
:204AA3007FF090FAADE054FC4402F090FAADE054FBF090FAADE054F7F090FAADE054CFF015
:204AC30090FAADE0543F4440F07854E2F5F008E242F008E242F008E245F0701B7B0175133C
:204AE3006F7514FC85141590FAA6E515F07A6F90FAA7EAF0024B857854C3E2943F08E2946F
:204B03000008E2940008E29400500C7854743FF2E408F208F208F27854E225E0F51608E24F
:204B230033F51708E233F51808E233F519E5162516F516E51733F517E51833F518E51933F4
:204B4300F519747DC0E0E4C0E08516828517838518F0E5191247607854C0E0E582F2E58382
:204B630008F2E5F008F2D0E008F2158115817B007D687EFC8E0590FAA6EDF07E6890FAA702
:204B8300EEF053C07F53A1FE43A11075A8A0EB70147854E2F5F008E242F008E242F008E2DB
:204BA30045F070012253BEFBE5BE30E5FBE5C654384441F5C6E5C630E6FB43BE0453C67F9B
:204BC3007854C3E2F5F074F095F008E2F5F074FF95F008E2F5F0E495F008E2F5F0E495F05C
:204BE300501B7DF07EFF7854E22410F208E23400F208E234FFF208E234FFF280117854E21C
:204C0300FD08E2FE7854E4F208F208F208F2EB60067A007C0080047A107C008AA175C000EB
:204C230043D6817AA67CFA8AD48CD575D60175A204E5A570FC75A2028EA48DA3AEA5EEB5B4
:204C4300A50280FA43C702EB60077B0075BE07800375BE06000000E5BE5403600875D701B2
:204C6300004387010053C7FDE5BE30E5FB75BE00E5BE30E5FB75C679E5BE30E6FB7E007D53
:1B4C830000000DBD80FB0EBE80F575C639E5C620E6FB75C63875BE04024B91E8
:0E7677000606060606060407070707070704AF
:204C9E00AF8275BB0074304FF5B575B473E5B420E6FBE5B430E7FBAEBA7F00ADBB7C0090BC
:204CBE00FAB2EC4EF0ED4FA3F08FB522C21590FAB2E0FEA3E08E82C4C582C4540F6582C569
:204CDE0082540FC5826582C582F58374E2C0E07404C0E0124451AC82AD83AEF0FF15811589
:204CFE008190FAB0E0FAA3E0FB74FFC0E07407C0E08A828B83124451A882A983AAF0FB1594
:204D1E00811581ECC398FCED99FDEE9AFEEF9BFF747DC0E08C828D838EF0EF124412AC82D7
:204D3E00AD83AEF0FF1581EFC40354F8CEC403CE6ECE54F8CE6EFFEDC40354074EFEEDC4BE
:204D5E000354F8CCC403CC6CCC54F8CC6CFDEF30E70FD215C3E49CFCE49DFDE49EFEE49F12
:204D7E00FF90FAAEE0C0E0A3E0C0E08C828D838EF0EF124760AC82AD83AEF0FF15811581D0
:204D9E0074FF2CFC74033DFDE43EFEE43FFF74FFC0E07407C0E08C828D838EF0EF124760F5
:164DBE00AC821581158190FAB4ECF030150790FAB4C3E49CF0228C
:204DD400E58620E0FB225390FD00225380FB0022E58620E0FB004390020022E58620E0FB82
:204DF400004380040022C007C006AF82BF64004027BF6A00502290DF097421F090DF0A74E9
:204E14003BF090DF0B7413F08F06EE249CFE90DF0675F003A4F0802F90DF097422F090DF94
:204E34000A74BBF090DF0B7413F0BFC8004013BFE100500EEF2438FF90DF0675F00CA4F0A8
:204E5400800590DF06E4F0D006D00722C00775E10490DF3BE0B401FCD00722124E607F000D
:204E74008F057EDFEFC390753F938D828E83F00FBF200040EB90DF237488F090DF247431C5
:204E9400F090DF257409F090DF2E748EF075911075ED00759D0075EF0322C007AF82C3EFC1
:204EB4006480946250047FE2800EC3748A8FF063F08095F050027F0A741E2FC31390755F53
:204ED4009390DF2EF0D00722C007C006AE82AF838ED48FD575D601000000000000000000A4
:204EF400D006D0072275D68100000000000000000022C007C006C005AE82AF83124EF98F45
:204F14000590FC78EDF090FC79EEF07E767FFC8E828F83124EDCD005D006D00722C007C0BC
:204F340006C005AE82AF83124EF98F0590FC7EEDF090FC7FEEF07E7E7FFC8E828F83124E7A
:204F5400DCD005D006D00722301604E5EF700122124E6053C0FE43B801E5ED75F080A424C0
:204F7400B6F58274FA35F0F583124F0675E1022253B8FE124EF9124E6075D10053C0FE2269
:204F9400AE82AF837CFF7DFF124F848E828F83124F3175E90075E103E5E920E42375820F59
:204FB400C005C004124C9ED004D00590FAB2E0FEA3E0FFC3EE9CEF9D50DE8E048F0580D88E
:204FD400124EF9C005C004124F5CD004D0057423C0E08C828D831248A615817404C0E01260
:204FF40043EFAC82AD83158190F0E7ECF0EDA3F022C025C0E0C0F0C082C083C007C006C08B
:2050140005C004C003C002C001C000C0D075D000E5D130E040E5ED75F080A424B6FE74FA31
:2050340035F0FF53D1FE8E828F83E0FD248240200D0DED2EF582E43FF583E0FF30E711E5DE
:20505400ED04FF8FEDBF030375ED00E5EF14F5EF124F5C800F7474C0E07475C0E0125A46CE
:205074001581158153C0FED0D0D000D001D002D003D004D005D006D007D083D082D0F0D06E
:20509400E0D02532201806124F84C21622201605D216024F5C22E59D75F080A424B6FE748F
:2050B400FA35F0FF8E828F83E0FD7403B5EF047582FF228D037C0074022BF9E43CFAE92EB1
:2050D400F582EA3FF583E0FA747F5AD39494F4FABA7F0040047AFF8003EA2AFA90F0BFEAE4
:2050F400F00BBB00010CEB2EF582EC3FF583E0A2E71324B390F0C0F00EBE00010FC005C0C2
:2051140006C00790F95B124630158115811581E59D04FF8F9DBF0303759D00D21910AF024C
:20513400C219E5EFFF04F5EFA21992AFEF7007C005124F5CD0058D8222D21A10AF02C21A52
:10515400AFEF75EF03A21A92AFEF7003024F5C2218
:20753F00D3917D044522000F0022BB131D3B1373A7650700181E1CC700B0B610EA2A001F2E
:20755F00030506080B0E191C242527293855408D8A84CAC4C0646D612069727120756E6553
:09757F00787065637465640A000C
:10768500DFD900008080131A0000DFD9207E134265
:1700E10090FC477456F090FC487412F090FC4903F090FC4A7485F0AA
:20516400E58620E0FB225390FD00225380FB0022E58620E0FB004390020022E58620E0FBEE
:20518400004380040022C007C006C005C004C003C002C001C000E582785BF27E00C21C7806
:2051A4005CE4F2C006785CE2C0E09010001243EFAA82AB831581785DEAF2EB08F2785F74E8
:2051C40004F2E408F2785DE2FA08E2FBE4FCFE7404C0E0E4C0E0744BC0E074FCC0E08A826C
:2051E4008B838CF0EE1206E1E58124FCF5817404C0E07447C0E074FCC0E090FC4B1245C4C9
:20520400158115811581921DD006201D030252EE785FE2FB08E2FCC3941040030252EEC07B
:2052240006785D795FE3C5F0E225F0FB09E3C5F008E235F0FAE4FCFE7402C0E0E4C0E07497
:205244004BC0E074FCC0E08B828A838CF0EE1206E1E58124FCF58190FC4BE0F51A74FFB5E8
:205264001A05D0060252EED006785BE2B51A5D90FC4CE0FCBC020040531C1C8C06785AC3D8
:20528400E29C5004785AE2FCC0067B007858E2F51B08E2F51C785DE2FD08E2FF74022DFD4D
:2052A400E43FFF785FE22DFD08E23FFA7E007F00C004C003C01BC01C8D828A838EF0EF12EC
:2052C40006E1E58124FCF581D21CD00690FC4CE0FF7D00785FE2FB08E2FCEF2BFBED3CFC1B
:2052E400785FEBF2EC08F2025214785CE22401F2785CE2B40A0050030251A7301C048E0735
:2053040080027FFF8F82D000D001D002D003D004D005D006D00722758204C007C006C0056D
:20532400C004C003C002C001C0001217C412539CD000D001D002D003D004D005D006D00715
:20534400301B26C007C006C005C004C003C002C001C0001216E912539CD000D001D002D067
:2053640003D004D005D006D007758204C007C006C005C004C003C002C001C0001217FD751E
:205384008200125C24D000D001D002D003D004D005D006D007D2AF22D21B785874A2F2747D
:2053A400FD08F2785A7407F275822A12518AE582FF30E71B785874A2F274FD08F2785A7484
:2053C40006F275820112518AE582FF30E701227404C0E0E4C0E0C0E090FDB212459815814C
:2053E400158115817404C0E074B2C0E074FDC0E090FDA41245C4158115811581921E501D63
:205404007404C0E074B2C0E074FDC0E0906A721245C4158115811581921E40012290F9575D
:205424007444F090F9567467F090FDA4E0FF90F953F090FDA5E0FE90F952F090FDA6E090BC
:20544400F951F090FDA7E090F950F090FDA4E4F07D007C00C006C005C007C00474A2C0E067
:2054640074FDC0E0E4C0E07488C0E07475C0E0125A46E58124F7F58190F950E0FF7E0090FF
:20548400F951E0FD7C00C007C006C005C0047496C0E07475C0E0125A46E58124FAF58190E0
:2054A400FDA2E024BF90F955F090FDA3E024BF90F954F090F956E0FF7E0090F957E0FD7C83
:2054C40000C007C006C005C00474A0C0E07475C0E07436C0E074FCC0E0125ABFE58124F86E
:2054E400F58190F954E0FF7E0090F955E0FD7C00C007C006C005C00474A0C0E07475C0E06E
:20550400743AC0E074FCC0E0125ABFE58124F8F58190F952E0FF7E0090F953E0FD7C00C0D9
:2055240007C006C005C00474A0C0E07475C0E0743EC0E074FCC0E0125ABFE58124F8F5814F
:2055440090F950E0FF7E0090F951E0FD7C00C007C006C005C00474A0C0E07475C0E07442D5
:20556400C0E074FCC0E0125ABFE58124F8F581785874AEF274FA08F2785A7402F2758212C5
:2055840012518AE58230E70122785874B0F274FA08F2785A7402F275820912518AE582306D
:2055A400E70122C21B229055B57416C39582F5F02275F020C2ADC2AC43AE0100E5AE20E7EB
:2055C400FB05AD05ADD5F0F09000008583AD8582ACA375AB2275F00275F900E5F830E1FB18
:2055E40053F8FDE5F820E0FBC0F9D5F0EB43AE02E5AE20E6FBD0E0D0AFF5AFE5AE20E6FB30
:2056040053AEFDE5AE20E7FBE583B440BE75C90B80FEC007C006C005C004C0031255AAAC7C
:2056240082AD83AEF0FF8E03C003C004C00590FDA212463015811581158175D6FF75A8005A
:2056440075C70390FDA2E473D003D004D005D006D00722C007C00675A80075B800759A0050
:2056640075C70075BE00E5BE30E5FB75C679E5BE30E6FB7F007E00000EBE80FB0FBF80F515
:2056840075C639E5C620E6FB75C63875BE04D006D0072243B404E5B4540C600280F8E5BCFE
:2056A40065BDF58222125697C082125697C082125697C082125697D083D0F0D0E022C000C4
:0B56C4008582BC7861E2F5BCD00022BA
:20758800534E20257325303278253032780025303278253032780A002530325825303258C6
:0175A80000E2
:2056CF00E58620E0FB225390FD00225380FB0022E58620E0FB004390020022E58620E0FB7E
:2056EF00004380040022C007C083C082858107C004C003C002C001C00074F42581F8868380
:20570F0018868218860018E0A36013B4250B7C007A00E0A36008B425161259D780E9D0007F
:20572F00D001D002D003D004D082D083D00722B4630518E61880E2FB4420B46D3AEB5420C5
:20574F0003F9C083C0821259737C0874FF2C93C083C082FAC47B02540F29905A06931259EB
:20576F00D7EADBF3D082D083DC06D082D0838097743A1259D780D4EBB42A09BA009B740168
:20578F004CFC808EB43007BA0004740680F2FB24D0501224F6400E240AFB740A8AF0A42B66
:2057AF00FA740480DBBB6C0DEC54086004741080CF740880CBBB733CEC5408C083C08270EC
:2057CF000512597A8003125973EC54047009E0A360981259D780F7BA0002808EE0A3600AC7
:2057EF001259D7DAF780830258C774201259D7DAF9025779EB4420B478EDC083C082125990
:20580F0090C083C082E5F023F90324FF2582F582E5833400F583E054F0701119E0700D19E7
:20582F001582E582B4FF021583D5F0EAB9000109EC5420600B09EC54026005742D1259D73E
:20584F00EC54046018EAC39940136011FAEC5402C4032420F582E5821259D7DAF9EC5420D9
:20586F00600B19EC54027005742D1259D7EB542003FAD082D083E904C313FC142582F58209
:20588F00E5833400F583E954016005E079018005E07902FBC4540F2AC083C082905A0693B4
:2058AF00D082D0831259D7EBD9EB1582E582B4FF021583DCDB025779BB640674204CFC80EE
:2058CF0008BB75028003025716C083C082125990C0F07408C395F0244FF9E434FCFBE0A39B
:2058EF001259CCF0A31259CCD5F0F31259CCF5F0EC54206028E5F054807006EC54DFFC8022
:20590F001CD0F0C0F07408C395F0244FF582E434FCF583C3E0F9E499F0A3D5F0F775F00ADB
:20592F00E4F0A3D5F0FBD0E0C403FB90FC5775F00AE0F9540F24FBE950022403F954F0243F
:20594F00B0E950022430F0A3D5F0E690FC4FC375F012E033F0A3D5F0F9DBD090FC5775F04F
:20596F000A02581086831886821822E61860F5648060F164C0600585938380EA7583FF80B4
:20598F00E5EC5401701F88F07583FFEC5418600A5410600418181818181818888218E5F0AB
:2059AF00C398F5F022EC5418600E5410600575F00880B175F00480AC75F00280A7C583CB13
:2059CF00C583C582C9C58222C083C082C001C0008F008682188683181818188601188600B4
:2059EF001259FBD000D001D082D08322C082C083850082850183223031323334353637383F
:205A0F003941424344454630313233343536373839616263646566C007C006C005C004FF32
:205A2F00BF0A0675820D12435C8F8212435CD004D005D006D00722C007C001C000A20B9212
:205A4F001FE58124FAFF200B03124370C007E58124F9F8E6C0E008E6C0E0E4C0E0C0E09098
:205A6F005A261256F5E58124FBF581201F03124385D000D001D00722C007C006C005C00473
:205A8F00C003C001AC82FF8C018F0487060987071974012EFBE43FFDA70309A7058E828F2D
:205AAF0083ECF0D001D003D004D005D006D00722C007C006C005C001C000E58124F6FFE525
:205ACF008124F8FE7D00C007E58124F5F8E6C0E008E6C0E0C006C005905A871256F5E5818E
:195AEF0024FBF58124F8F88682088683E4F0D000D001D005D006D00722C3
:0200F800C22024
:205B0800E58620E0FB225390FD00225380FB0022E58620E0FB004390020022E58620E0FB40
:205B2800004380040022C007AF82E58620E0FB53807F008F82125CAB00E58620E0FB438071
:205B480080D0072253BEFC32AE82AF838E828F83E493FD74012EFBE43FFCEDFA6052539054
:205B6800FD008B828C83E493FD0BBB00010CE58620E0FB53807F008D82125CAB00E5862052
:205B8800E0FB438080EA14FDED6015E58620E0FB8B828C83E493F5C1A3AB82AC831D80E84F
:205BA8008B068C07E58620E0FB0043900200809C2230200122D220758201125C244390027C
:205BC8005380BF43F42875C20075C5317586009000FDE4F5F01249E24390049000FDE4F55F
:205BE800F01249E22090FD9075A9125B505390FD00E58620E0FB53807F00758204125CABAC
:205C080000E58620E0FB4380803090FDE58620E0FB00439002009075B5025B50E582601697
:205C280090F953E054F0600122438FC143FDC143F62E43FE2E2253F4D790F953E0FF54F030
:205C4800600B53807E5390D100D2860022538F3A53FD3A53F6D153FED122202001229076E5
:205C680041125B50758200125C24C22022125BB95390FD003021067E137F0080047E107F93
:205C880000E58620E0FB53807F008E82125CAB00E58620E0FB438080E58620E0FB00439039
:205CA800020022C007AF82E58620E0FB8FC1D007227EFF7FFF744EC0E07476C0E0125A4678
:205CC8001581158190764BC007C006125B50D006D00720902F900032E4F5F0C007C006123F
:205CE8004A5112565775820F124C9ED006D00790FAB2E0FCA3E0FDC3EC9EED9F50D48C066C
:205D08008D0780CE7423C0E08E828F831248A615817404C0E01243EFAC82AD83158190F0DA
:205D2800E9ECF0EDA3F07582011217C4125C621219A27460C0E07476C0E0125A4615811539
:025D48008122B6
:2075A900050107000900040607070F0002008F046180012802302902501702820802602212
:2075C900102001010103040906060A040419030409102101010103840986460A844419039A
:2075E9004409102201010143040986460A84441983040910250A0A0102140D1414010000D3
:207609000000000010264A4A0182540D54540100000000000010270A0A0102140D14140172
:20762900000000000000102401810183840986460A84441903040900028200050102000027
:2076490000000112005570646174696E6720646973706C61790A0055706461746520636F5D
:087669006D706C6574650A0088
:205D4A00AE82AF837C007D007B10EF235401FAEE2EFEEF33FFEC2CFCED33FDEA60034304F2
:205D6A00017862C3E2F5F0EC95F008E2F5F0ED95F040117862D3E29CF4B3FCB308E29DF4B5
:0B5D8A00FD430601DBC48E828F8322E4
:205D9500AC82AD83AEF0FF33E433FB6013C3E49CF556E49DF557E49EF558E49FF5598008B8
:205DB5008C568D578E588F59AC56AD57AE58AF597867E233E433FA60207864E2D3F43400E8
:205DD500F55608E2F43400F55708E2F43400F55808E2F43400F55980117864E2F55608E2C2
:205DF500F55708E2F55808E2F559786CE556F2E55708F2E55808F2E55908F28C828D838E71
:205E1500F0EFC003C002125E697868C0E0E582F2E58308F2E5F008F2D0E008F2D002D003D7
:205E3500EA6B60207868E2D3F43400FA08E2F43400FB08E2F43400FE08E2F434008A828BFB
:145E5500838EF0227868E2F58208E2F58308E2F5F008E222A0
:205E6900AF82AE83ADF0FC7870EFF2EE08F2ED08F2EC08F27A007B007E007F007D20787326
:205E8900E2235401FC7870E225E0F208E233F208E233F208E233F2EA2AFAEB33FBEE33FE6F
:205EA900EF33FFEC6003430201786CC3E2F5F0EA95F008E2F5F0EB95F008E2F5F0EE95F0C5
:205EC90008E2F5F0EF95F04022786CD3E29AF4B3FAB308E29BF4B3FBB308E29EF4B3FEB3D3
:1D5EE90008E29FF4FF7870E24401F2DD917870E2F58208E2F58308E2F5F008E22233
:0600B200E478FFF6D8FD22
:200090007924E94400601B7A0190767178627593FCE493F2A308B800020593D9F4DAF275C7
:0200B00093FFBC
:1B5F060020F71130F6138883A88220F509F6A8837583002280FEF280F5F0229A
:205F2100AA83AB828BF090F075E0A4F8A9F08AF0E0A429F98BF0A3E0A429F58388822222D0
:205F4100AF82AE83ADF0FC787BEFF2EE08F2ED08F2EC08F2787BE2FF7879E28FF0A4FFAD46
:205F6100F07881EFF208EDF2787BE2FF7877E28FF0A4FFADF0787FEFF208EDF27882E2FF71
:205F8100787EE2FE7877E28EF0A42FFF7882F2787DE2FE7878E28EF0A42F7882F27881E25E
:205FA100FE08E2FF787DE2FD7877E28DF0A4ABF02EFEEB3FFF7881EEF208EFF2787CE2FDAE
:205FC1007878E28DF0A4ABF02EFEEB3FFF7881EEF208EFF2787CE2FF7879E28FF0A4787E5A
:205FE100F2787CE2FF7877E28FF0A4FFADF0787CEFF208EDF2787BE2FF787AE28FF0A4784A
:206001007AF2787BE2FF7878E28FF0A4FFADF07878EFF208EDF27877E4F2787BF2787FE273
:20602100F55A08E2F55B08E2F55C08E2F55D787BE2FA08E2FB08E2FE08E2FFEA255AF55A22
:20604100EB355BF55BEE355CF55CEF355DF55D787FE55AF208E55BF208E55CF208E55DF2F8
:20606100787FE208E208E208E27877E2FC08E2FD08E2FE08E2FFEC255AFCED355BFDEE35FF
:0C6081005CFEEF355D8C828D838EF0227A
:20608D00AE82AF837D007C007884E2235401FB70357883E225E0F208E233F27883C3E2F52A
:2060AD00F0EE95F008E2F5F0EF95F050147883E2F5F008E2C313C5F01318F2C5F008F28046
:2060CD00050C8C0580C27883C3E2F5F0EE95F008E2F5F0EF95F0400E7883D3E29EF4B3FE53
:2060ED00B308E29FF4FF7883E2F5F008E2C313C5F01318F2C5F008F28D041DEC70C88E827F
:03610D008F83225B
:20611000AD82AE83AFF07888E2F5F008E245F07004900000227888E2FB08E2FC1BBBFF01CB
:206130001CEB4C6069C003C0048D5A8E5B8F5C855A82855B83855CF012628FFA7885E2F58B
:206150005D08E2F55E08E2F55F855D82855E83855FF012628FFCEAB504028006D004D003E8
:20617000802C7401255AFAE4355BFBAC5C8A058B068C077401255DFAE4355EFBAC5F7885E0
:20619000EAF2EB08F2EC08F2D004D003808E8D828E838FF012628FFD7F007885E2FB08E2B1
:1A61B000FC08E2FE8B828C838EF012628FFB7E00EDC39BF582EF9EF58322F2
:2061CA00AE82E583FF33E433FD6009C3E49EFBE49FFC80048E038F04788BE233E433FF6079
:2061EA0010788AE2D3F43400FA08E2F43400FE8007788AE2FA08E2FE7862EAF2EE08F28B26
:20620A00828C83C007C005125D4AAC82AE83D005D007EF6D600AC3E49CF582E49EF58322F7
:05622A008C828E83222E
:2000B800788CE84400600A79007593F0E4F309D8FC78D6E8440B600C790C90F08CE4F0A370
:0400D800D8FCD9FA7D
:0F008100E4737581641262ABE582600302007E56
:20622F00758911758800758B00758D0020B0FD20B0FA20B0F720B0F420B0F130B0FDD28E21
:20624F0020B0FD30B0FD20B0FD30B0FDC28EE58D25E0FFE58B2354014FF58DE58D25E0FFE6
:20626F00E58B232354014FF58DE58DF4F58DE58D04F58D858D8B758921758780759852229A
:1C628F0020F71430F6148883A88220F507E6A88375830022E280F7E49322E0221E
:0462AB0075820022D6
:00000001FF

Binary file not shown.

View File

@@ -0,0 +1,997 @@
:040000000200833245
:01000B0032C2
:0100130032BA
:01001B0032B2
:0100230032AA
:03002B00024AA9DD
:01003300329A
:01003B003292
:0300430002506BFD
:03004B000249C6A1
:01005300327A
:01005B003272
:01006300326A
:01006B003262
:01007300325A
:03007B00025BB273
:0300FA0002007E83
:03007E0002050672
:2000FD00E58620E0FB225390FD00225380FB0022E58620E0FB004390020022E58620E0FBA6
:20011D00004380040022AF8290F090E4F090F091F08F061FEE60767E0090F95AE0FDBD024E
:20013D000BEE90631593FDBDC800405990F95AE0FDBD010BEE90631593FDBDC8005046EEDB
:20015D002415FCE43463FD8C828D83E493F582C007C006C005C004121C58E582D004D0051D
:20017D00D006D007601F90F090E0FB90F0BFE0FAC3EB9A501090F090EAF08C828D83E4930B
:20019D00FC90F091F00EBE0C005086808C90F091E0FFE06013BFC800400890F95A7402F030
:2001BD00800690F95A7401F090F091E0F5822290F0EDE0FEA3E0FFC3742C9E74019F40099F
:2001DD0090F0E3E0700330015E300A0920020690F0C6E0700930031E90F0C7E0601890FC37
:2001FD0061E0FFBFFF02800B7824E4F28F8212277B8003123D60121E24AD82AE83AFF0900B
:20021D00F092EDF0EEA3F0EFA3F0ED4E602D90F0EDE4F0A3F010010090F0E3E06002D2013A
:20023D0090F0E3E4F08014121F0FAD82AE83AFF090F092EDF0EEA3F0EFA3F012189890F063
:20025D0092E0FDA3E0FEA3E0FFED4E700990F0E1E4F0A3F08059740F2DFAE43EFB8F048AD6
:20027D00828B838CF01262F5FAA31262F5FB90F0E1EAF0EBA3F0740D2DFAE43EFB8F048A50
:20029D00828B838CF01262F560168D828E838FF01231B6E582701890F0E1E4F0A3F0800F78
:2002BD007423C0E07463C0E0125AAC158115811218E3AE82AF8390F0EDE0FCA3E0FD90F077
:2002DD00EDEE2CF0EF3DA3F0BE580CBF020990F0C5E06003C2002290FA5BE0600E90FA5BDB
:2002FD00E4F0900064E4F5F00217E390F0E1E0FEA3E0FF4E603BEF30E71F8E048F05530507
:20031D007F7877ECF2ED08F2E408F208F29003E8E4F5F0125FA70217E37877EEF2EF08F2A5
:20033D00E408F208F290EA60E4F5F0125FA70217E31218E3AE82AF837877EEF2EF08F2E406
:20035D0008F208F29003E8E4F5F0125FA70217E390F0CEE0FF600D8F82121C58E58290F913
:20037D0059F0800C758202120123E58290F959F090F959E0700920030690F0C7E0701430E4
:20039D000A0920020690F0C6E0700890F0E4E0FFBF233690FC61E0FFBFFF02801A758202ED
:2003BD00123F00E582702290FC61E0FF7824E4F28F8212277B801290F0E4E0FFBF230040DC
:2003DD0005123EA18003123E5E90F959E0604890F0E4E4F090F0CEE0700F75820412179EC8
:2003FD001214B67582041217D790F0E374FDF090002812177B1218E3AE82AF837877EEF2AB
:20041D00EF08F2E408F208F29003E8E4F5F0125FA71217E3D2002275820112185EAC82AD47
:20043D0083AEF0FF7877ECF2ED08F2EE08F2EF08F29003E8E4F5F0125FA70217E3E582FF3C
:20045D0024FA50030204EEEF2F2F90046B730249C202047D0204940204C40204EE0204D09D
:20047D00742EC0E07463C0E0125AAC15811581C20090F959E4F02290F959E0FE743BC0E0B9
:20049D007463C0E0125AAC15811581758204C00612179E1213701214B67582041217D7D0C0
:2004BD000690F959EEF022123A7F900000E4F5F00217E3744BC0E07463C0E0125AAC158193
:2004DD00158175820412179E1227677582040217D77E00C007C006745BC0E07463C0E01219
:2004FD005AACE58124FCF5812275820112179E75820F124D0490FAB0E0FEA3E0FF7423C0A2
:20051D00E08E828F8312490C15817404C0E0124455AC82AD83158190F0E5ECF0EDA3F090B7
:20053D006321E493C0E0740193C0E0746DC0E07463C0E0125AACE58124FCF5811253811257
:20055D00197C12193490F0E374FCF0AEBE5306187F00BE1009BF000690F0E374FEF0301CBE
:20057D000C123EFA900000E4F5F01217E37434C0E074FCC0E0E4C0E074A2C0E07463C0E09A
:20059D00125AACE58124FBF5811237B4900190E4F5F01217E375820412179E1213E2123726
:2005BD009B90F0C2E0601174AAC0E07463C0E0125AAC15811581801B74BBC0E07463C0E096
:2005DD00125AAC15811581123B2E902710E4F5F01217E390F959E0FFE0601F8F82121C58EC
:2005FD00E582702574C8C0E07463C0E0125AAC1581158190F959E4F0800F74E6C0E0746335
:20061D00C0E0125AAC1581158190F959E0700312036D90F959E06007123D60D200800512E1
:20063D003E5EC20075820412179E1214B63000067E287F0080047E587F028E828F83121720
:20065D007B30000A7C887D137E007F0080087CC07DD47E017F008C828D838EF0EF1217E38D
:0D067D003000051201CC80F812036D80F3EF
:20631500C864C965CA66CB67CC68CD6915004E6F207570646174650A00434D445F444F5F9E
:206335005343414E0A0052657365742073657474696E67730A0045726173696E6720696DBC
:20635500616765730A00436D6420307825782069676E6F7265640A000A6368726F6D61323D
:2063750039204F45504C2076253034782C20636F6D70696C6564204A756C203137203230FA
:2063950032352031323A34373A30380A004D41432025730A00446F696E672066617374203B
:2063B500626F6F740A004E6F726D616C20626F6F740A004E6F20415020666F756E64206F8A
:2063D5006E207361766564206368616E6E656C0A004E6F207361766564206368616E6E6587
:0363F5006C0A002F
:0176A50001E3
:20068A00E58620E0FB225390FD00225380FB0022E58620E0FB004390020022E58620E0FB13
:2006AA00004380040022AC82AD83AEF0FF00C2A0007582031243C28E821243C28D8212434E
:2006CA00C28C820243C2C007C006C005C004C003C002C001C000AC82AD83AEF0FFE5812498
:2006EA00F5F8860208860300C2A0007582031243C28E821243C28D821243C28C821243C205
:20070A008A068B07E58124F3F886040886058C028D031CBCFF011DEA4B6015758200124312
:20072A00C2AB828E828F83EBF0A3AE82AF8380DE00D2A000D000D001D002D003D004D005FF
:20074A00D006D00722AF8200C2A0008F821243C200D2A0002200C2A0007582051243C27587
:20076A0082001243C2E58220E0F500D2A00022AC82AD83AEF0FF7803E2FA08E2FBC007C028
:20078A0006C005C004C003C00212075F75820612074FD002D003D004D005D006D00700C2A1
:2007AA00A0007582021243C28E821243C28D821243C28C821243C28A068B077805E2FC0888
:2007CA00E2FD8C028D031CBCFF011DEA4B60128E828F83E0FBA3AE82AF838B821243C280D0
:2007EA00E100D2A0002212075F7582B912074FC20C227582AB12074F75F034D5F0FDD20CB7
:20080A0022C007C006C005C004C003C002C001C000C082C083C0F0C0E005810581E5812425
:20082A00EFF88605088604E58124EDF8E608467003020904C005C004E58124F9F8860208F1
:20084A007B00E58124FDF8E4C39AF674019B08F6E58124FDF8E58124EBF9C3E79609E7082A
:20086A0096D004D005500EE58124EDF8A98119E6F708E609F77803EDF2EC08F2A88118795A
:20088A0005E6F308E609F3E58124FBF886820886830886F008E6C007C006C005C004C003AB
:2008AA00C002C001C000C025120779D025D000D001D002D003D004D005D006D007A88118A2
:2008CA008602088603E4FEFFE58124FBF8EA26F6EB0836F6EE0836F6EF0836F6A88118E606
:2008EA002DFD08E63CFCE58124EDF8A98119E6C397F608E60997F6020831E58124FAF581FD
:20090A00D000D001D002D003D004D005D006D00722C007C006C005C004C003C002C001C0F3
:20092A0000C082C083C0F0C0E0E58124FDF88602088603EA7005EB540F6006758200020A2A
:20094A001EE58124F1F8E608467003020A1B758206C007C006C005C004C003C002C001C015
:20096A0000C02512074FD025D000D001D002D003D004D005D006D00700C2A000E58124F1B2
:20098A00F886020886037582201243C2E58124FDF8080886821243C2E58124FDF8088682D1
:2009AA001243C2E58124FDF886821243C200D2A000C007C006C005C004C003C002C001C0EA
:2009CA0000C02512075FD025D000D001D002D003D004D005D006D0077401C0E09010001258
:2009EA004455AC82AD83AEF0FF1581E58124FDF8EC26F6ED0836F6EE0836F6EF0836F61ABC
:200A0A00BAFF011BE58124F1F8A60208A60302094B758201E58124FCF581D000D001D0026E
:0B0A2A00D003D004D005D006D0072276
:200A3500E58620E0FB225390FD00225380FB0022E58620E0FB004390020022E58620E0FB64
:200A5500004380040022C007C006C005C004AF82AE83ADF0FC90F0BBEFF0EEA3F0EDA3F06C
:200A7500ECA3F0C202C203D208758204C007C006C005C004C003C002C001C000C02512175A
:200A95009ED025D000D001D002D003D004D005D006D00790F0BBE0FCA3E0FDA3E0FEA3E077
:200AB500FF7416C0E0E4C0E074F3C0E074F0C0E08C828D838EF0EF1206D0E58124FCF581FA
:200AD50090F0BBE0FCA3E0FDA3E0FEA3E0FF90F0BB74162CF0E43DA3F0E43EA3F0E43FA357
:200AF500F090F103E0FFBF2004C207806A90F103E0FFBF2104D207805E90F103E0FF7E0019
:200B1500C007C00674E0C0E07469C0E0125AACE58124FCF58190FA6E7416F0E4A3F090F045
:200B3500F375F000C007C006C005C004C003C002C001C000C025121B0BD025758204C0253A
:200B55001217D7D025D000D001D002D003D004D005D006D0078051C222C007C006C005C028
:200B750004C003C002C001C000C025125CDBD025C025120BC6D025D222C025125CDBD0255F
:200B9500C025120BC6D025758204C0251217D7D025C025125D1FD025D000D001D002D00300
:200BB500D004D005D006D007D004D005D006D007227F807E0090F0ABE4F0A3F090F0A5F02E
:200BD500A3F05390FD007D00200803020C5930221D20071A74A0C0E07404C0E0E4C0E090EE
:200BF500F0F31245FE158115811581020CA9C00590F0BBE0FAA3E0FBA3E0FCA3E0FD74A0C4
:200C1500C0E07404C0E074F3C0E074F0C0E08A828B838CF0ED1206D0E58124FCF58190F015
:200C3500BBE0FAA3E0FBA3E0FCA3E0FD90F0BB74A02AF074043BA3F0E43CA3F0E43DA3F077
:200C5500D005805074A0C0E07404C0E0E4C0E090F0F31245FE1581158115817B4A7C00C0FF
:200C750007C006C005C004C0037807E2F58208E2F583120081D003D004D005D006D00790C0
:200C9500F0A5E02401F0A3E03400F01BBBFF011CEB4C70CB7B007C00EF60503022238E020F
:200CB500EA2AFEEB24F3F582EC34F0F583E0FAEF5A7003430601EF30E02B8E82125D1180F2
:200CD500248E02EA2A25E0FEEB24F3F582EC34F0F583E0FAEF5A6003430603EF54116005A8
:200CF5008E82125D11EFC313FF80AD7F800BBB00010CC3EB94A0EC9404409D90F0ABE0FB43
:200D1500A3E0FC744A2BFBE43CFC90F0ABEBF0ECA3F00DBD04005003020BDDE58620E0FB49
:200D3500004390020022AE82AF83C202C203C208D207C2227807EEF2EF08F2125CDB120B87
:200D5500C6D222125CDB120BC6025D1FC007C006C005C004C003C002C001C000AD82AE839E
:200D7500AFF0A204202201B3505090F09FE0F508A3E0F50974012DFAE43EFB8F048A828B23
:200D9500838CF01262F5FA780CF2E408F2850882850983C007C006C005C004C003C002C00D
:200DB50001C000120FF2E582D000D001D002D003D004D005D006D0076003020F988D828E9E
:200DD500838FF078091262F5F290F0A1E0F508A3E0F5097809E2F50A750B00780EE50AF258
:200DF500E50B08F2850882850983C007C006C005C004C003C002C001C000121069D000D08D
:200E150001D002D003D00490F0ADE0F508A3E0F50990F0B1E0FBA3E0FCEBC39508F582EC7F
:200E35009509F5837875E50AF2E50B08F2C002C001C000125F87AB82AC83D000D001D002C5
:200E5500D005D006D007ECC423CBC423541F6BCB541FCB6BCBFC90F0B7EBF0ECA3F0740256
:200E75002BFBE43CFCEB2DFDEC3EFE90F0A7E0FBA3E0FCEB5407700A7809E254077003026A
:200E95000F4C5303078BF005F07B80E4FC3392D28008A2D2EC13FCEB13FBD5F0F5780AEB8C
:200EB500F2780B7480F28D828E838FF01262F5FA74012DF50CE43EF50D8F0E7809E2F50AFA
:200ED500AC0A150AEC7003020F98780BE25A6025C00290F0B5E0FAA3E0FCEA24F3FAEC3471
:200EF500F0FC8A828C83E0FB780AE242038A828C83EBF0D002780BE2C313F2780BE270196F
:200F1500850C82850D83850EF01262F5FAA385820C85830D780B7480F2780AE2C313F278D6
:200F35000AE2709C780A7480F290F0B5E02401F0A3E03400F080897809E2604790F0B5E043
:200F5500FBA3E0FCEB24F3FBEC34F0FC8B828C83E0F50C8D828E838FF01262F5FAA3AD8228
:200F7500AE83E50C42028B828C83EAF090F0B5E02401F0A3E03400F07809E2FC780924F833
:200F9500F280B4D000D001D002D003D004D005D006D0072290F0A7E0FEA3E0C423CEC42334
:200FB500541F6ECE541FCE6ECE30E40244E0FF90F0ABE0FCA3E0FD90F0B1E0FAA3E0FBEABD
:200FD500C39CFCEB9DC454F0CCC4CC6CCC54F0CC6CFD90F0B5EC2EF0ED3FA3F022AE82AF05
:200FF5008390F095EEF0EFA3F090F0AFEEF0EFA3F07427C39EFE74019FFF90F0A9EEF0EF52
:20101500A3F090F0A5E0FCA3E0FD90F0B1ECF0EDA3F0C3EE9CEF64808DF063F08095F040E5
:201035002F780CE22CFC08E23DFDC3EE9CEF9D501F780CD3E29EF4B3FEB308E29FF4FF0EB9
:20105500BE00010F90F0ADEEF0EFA3F07582002275820122AE82AF8390F0A7EEF0EFA3F004
:20107500780E90F097E22EF008E23FA3F0120FA975820022C007C006C005C004C003C00284
:20109500C001C000AC82AD83AEF0FF058105810581BF2000502C8F82C007C006C005C004AB
:2010B500C003C002C001C000C02512430DD025D000D001D002D003D004D005D006D007023B
:2010D50013337E00EF24E0FFEE34FFFEEF2FFFEE33FEEF24F8F582EE3463F583E493FEA353
:2010F500E493FF90F0B7EEF0EFA3F0EFC4540FFE90F0B3F0300507EE2EFE90F0B3F090F09E
:2011150099E0FEA3E0FF90F0B9EEF0EFA3F090F0B3E0FDFB3395E0FC0BBB00010CEB2EFB92
:20113500EC3FFC90F099EBF0ECA3F0A204202201B3504190F0B9E0FEA3E0FF780CEDF2EDEA
:201155003395E008F28E828F83C007C006C005C004C003C002C001C000C025120FF2E5823B
:20117500D025D000D001D002D003D004D005D006D007600302133390F09BE0FEA3E0FF9013
:20119500F0B4E0FD780EF2ED3395E008F28E828F83C007C006C005C004C003C002C001C074
:2011B50000C025121069D025D000D001D002D003D004D005D006D00790F0B7E0FEA3E0FF82
:2011D50053070F90F0B7EEF0EFA3F0A8811818760008768090F0A7E0FCA3E05304078CF0CD
:2011F50005F07C80E4FD3392D28008A2D2ED13FDEC13FCD5F0F5A881A60490F0B3E0FD9050
:20121500F0ADE0FAA3E0FB90F0A5E0FCA3E0FFECC39AFAEF9BFBED3395E0FFEDC39AFAEFB2
:201235009BFB1ABAFF011B90F0B9EAF0EBA3F030050FEBC313CA13CAFB90F0B9EAF0EBA33B
:20125500F090F0B9E0FEA3E0FF90F0B7E0FCA3E0FD90F0B7EE2CF0EF3DA3F090F0B7E0FE48
:20127500A3E0FFEE2EFEEF33FFEE24B8F582EF3464F583E493FEA3E493FF90F0B9E4F0A31E
:20129500F090F0B9E0FCA3E0FD90F0B4E0FB3395E0FAC3EC9BED9A4003021333A88118184E
:2012B500E65EFC08E65FFD4C602190F0B5E0FCA3E0FDEC24F3FCED34F0FD8C828D83E0FB2B
:2012D500A881E642038C828D83EBF030051A90F0B9E0FCA3E0FDEC30E01AA88118E618C3B0
:2012F50013C613C608F6800CA88118E618C313C613C608F6A881E6C313F6A881E6701090F1
:20131500F0B5E02401F0A3E03400F0A881768090F0B9E02401F0A3E03400F0021296158143
:1513350015811581D000D001D002D003D004D005D006D00722B9
:2063F8000070071008500D9016601CA026A03010316037603D7044904D204F6055205780C0
:206418005F7066706D6073507880805085708C7093709A70A120A320A570AC80B470BB7055
:20643800C2A0CCA0D670DD80E570EC70F370FA8002710971105115811D7124812C713381DD
:206458003B7142814A7151715891617168A172A17CA186A1908198519D81A551AA81B2A191
:20647800BC21BE71C571CC71D371DA71E181E971F071F741FB51007207420B9214721B72EA
:2064980022722972306236623C724362499252A25C8264A26E8276627C127D6283A28D722C
:2064B8000000000000000000000000000000D87F0078000000000000007880009804E0057C
:2064D800801E9864E005801E80648004183808640842FCFF8841F040083810442044C04429
:2064F80000397002880C881088207040E0001001083A08468845C84C383818006800800182
:206518000078E00718180C300420024002400240024004200C301818E00700100018000FBE
:206538000072000F001800104000400040004000F807400040004000400019001E008000E4
:20655800800080008000800080001800180002000C003000C0000003000C00300040C00F27
:2065780030300840084008403030C00F082008200820F87F0800080008001860284048402D
:2065980088400843083C0840084208420842F03DC0004003400440184020F87F4000400043
:2065B800087C084408441042E041E00F10320844084408441042E00100401840E0400043F1
:2065D800004C00500060F038084508420842084590456038001E08218840884088403021F4
:2065F800C01F1806180619061E06C000C000200120011002100208042001200120012001AF
:20661800200120012001200108041002100220012001C000C00000700040D84000410042A1
:2066380000640038C00F30181820C84728486850D851E03F2000200008007000C001400E11
:206658004018400C4003C00030000800F81F08110811081108118812700CC003300C10089B
:2066780008100810081008100818F81F08100810081008101008E007F81F8810881088102D
:20669800881088100810F81F801080108010801080100010C003300C1008081008108810C4
:2066B8008810F818F81F80008000800080008000F81F081008100810F81F081008100810C5
:2066D8000800081008100810F01FF81F0001800140022004200810100800F81F08000800CD
:2066F8000800080008000800F81F001C8007E00060008003001CF81FF81F0008000680010C
:2067180060001000F81FE007100808100810081008101008E007F81F801080108010801025
:206738000011000EE00710080810081008100C101208E207F81F80108010C0102011100E66
:206758000800180E0812081108118810901070180010001000100010F81F00100010001060
:206778000010E01F18000800080008001000E01F0010000C8003600018001800E0000003A1
:20679800000C00100018C0073800F0000007800370003800C0070018081010082004400217
:2067B8008001800140022004100808100010000800060001F80000010002000400080010F3
:2067D80018102810481088100811081208140818FE7F024002400240024000400030000CE1
:2067F8000003C00030000C0002000240024002400240FE7F2000C0000007001C0070000E7A
:20681800C0012000040004000400040004000400040004000400040000800040300048041B
:20683800880488049004F8030800F87F10020804080408041006E001E001100208040804E2
:20685800080408040804E00118020804080408041002F87FE00190028804880488048804B1
:20687800880300040004F83F00240044004400440044E00119020904090409041202FC07C8
:20689800F87F00010002000400040004F803000400040064F8670100010401040164FE67BF
:2068B800F87F8000C0002001200210020804004000400040F87FF807000200040004F8036D
:2068D800000200040004F803F80700030002000400040004F803E001100208040804080479
:2068F8001002E001FF0710020804080408041006E001E00118020804080408041002FF0723
:20691800F8070001000200040004000718038804880448044804300400040004F01F08042C
:20693800080408040804F0070800080008001000F807000480036000180008003000C00006
:20695800000300040006E001180070008003800170001800E0010006080410022001C00037
:20697800C00020011002080401040103C10062001C00180060008000000300040804180491
:20699800280448048804080508060804800080007C3F024002400240FE7F024002400240F0
:2069B8007C3F80008000C000000100010001800080004000400040008001F80108030804F0
:2069D800080808040803F80164617461547970652030782578206E6F7420737570706F72A4
:0569F8007465640A0053
:20134A00E58620E0FB225390FD00225380FB0022E58620E0FB004390020022E58620E0FB46
:20136A0000438004002290F0C17401F090F0C2E4F090F0C3F090F0C4F090F0C5F090F0C6DC
:20138A0004F090F0C7F090F0C9E4F090F0C8F090F0CC7428F0E4A3F090F0CEF090F0CA7478
:2013AA0028F0740AA3F090F959E4F090F95AF022AD82AE831262F5FCBC011C7BC17CF08B7E
:2013CA00828C83740EC0E0C005C0061246961581158115810214B6227480C0E0E4C0E0749B
:2013EA00A2C0E074FDC0E0906000E4F5F01206D0E58124FCF581740EC0E07414C0E074FE37
:20140A00C0E090F0C112469615811581158190FDA2E0FCA3E0FDA3E0FEA3E0FFBCA513BD72
:20142A005A10BEBA0DBFAB0A90FDA6E0FFBF0102803590FDA2E0FCA3E0FDA3E0FEA3E0FF28
:20144A0090FDA6E0FB7A00C004C005C006C007C003C00274FDC0E07469C0E0125AACE58153
:20146A0024F8F58102137090FDA7E090F959F090FDA8E090F95AF07423C0E0746AC0E012B6
:20148A005AAC1581158112160890FDA2E4F004C0E0E4C0E074A2C0E074FDC0E0906000E41A
:2014AA00F5F012080BE58124FCF581227480C0E0E4C0E074A2C0E074FDC0E0906000E4F552
:2014CA00F01206D0E58124FCF58190FDA2E0FCA3E0FDA3E0FEA3E0FFBCA53EBD5A3BBEBA37
:2014EA0038BFAB35788574C1F274F008F2E408F27888740EF2E408F290FE1475F0001261DF
:20150A0076E5828583F045F0700F90FDA7E0FF90F959E0FEEFB506012290FE21E0FF90F08A
:20152A00CEE0FEEFB50602803EEE603BBE6400502390FE21E0FF7D00C007C0057435C0E08D
:20154A00746AC0E0125AACE58124FCF58190F0CEE4F08013BEC800400890F95A7402F080A3
:20156A000690F95A7401F07480C0E0E4C0E0C0E090FDA21245FE158115811581740EC0E0F3
:20158A0074C1C0E074F0C0E090FE1412469615811581158190FDA274A5F0F4A3F074BAA386
:2015AA00F0C4A3F090FDA67401F090F959E090FDA7F090F95AE090FDA8F07401C0E0E4C0BB
:2015CA00E0906000E4F5F012091B158115817480C0E0E4C0E074A2C0E074FDC0E090600037
:2015EA00E4F5F012080BE58124FCF581744EC0E0746AC0E0125AAC1581158102160890F033
:20160A00C5E0FF7E00C007C006745FC0E0746AC0E0125AACE58124FCF58190F0CEE0FF7E61
:20162A0000C007C0067478C0E0746AC0E0125AACE58124FCF58190F0CAE0FEA3E0FFC00685
:20164A00C007748BC0E0746AC0E0125AACE58124FCF58190F0C2E0FF7E00C007C006749F49
:20166A00C0E0746AC0E0125AACE58124FCF58190F959E0FF7E00C007C00674B4C0E0746ABC
:0C168A00C0E0125AACE58124FCF581227E
:2069FD004C6F616465642064656661756C7473205665722030782578204D616769632030B6
:206A1D0078256C780A004C6F616465642073657474696E67733A0A0049676E6F72656420C8
:206A3D0066697865644368616E6E656C2025640A0053617665642073657474696E67733AFF
:206A5D000A0020205363616E2041667465722054696D656F75742025640A002020666978F7
:206A7D0065644368616E6E656C2025640A0020206261744C6F77566F6C74616765202564A0
:206A9D000A002020656E61626C6546617374426F6F742025640A0020204C61737420636894
:056ABD002025640A0021
:20169600E58620E0FB225390FD00225380FB0022E58620E0FB004390020022E58620E0FBF7
:2016B60000438004002275F10175805875FDDD75F33875904075FE6E75F4E875A00175FF87
:2016D60001227401C0E0E4C0E0900000E4F5F012091B158115817414C0E0E4C0E074C2C0DB
:2016F600E0746AC0E0900000E4F5F012080BE58124FCF58122C00775E40075FC0075F700DD
:2017160075FE0290F953E0701890F952E0FF54F06002800DD291758F0075F60075FD008049
:1F17360012758F8175F62F75FD8175FE2F53807E5390D075F30075F40075F500D0072296
:146AC2005612098501084A41000000000904EC0212045A0AC1
:20175500E58620E0FB225390FD00225380FB0022E58620E0FB004390020022E58620E0FB37
:20177500004380040022AE82AF837D00BD08005017ED75F002A424CFF58274F035F0F583FD
:20179500EEF0EFA3F00D80E422E582FF30E0251256BDC007124A2FD2AF1216BC1243BE12A5
:2017B5004ED5D00775820A124F1490F959E0FEF582124E60EF30E2091243EB200C0302072B
:2017D500FC22E58230E206300C030207F022AF82AE83ADF0FC90F0EFEFF0EEA3F0EDA3F0B3
:2017F500ECA3F090F0EFE0FCA3E0FDA3E0FEA3E0FFC004C005C006C00774D6C0E0746AC0E9
:20181500E0125AACE58124FAF581300C16758204C007C006C005C0041217D7D004D005D0E5
:2018350006D007C007C006C005C004125CC8D004D005D006D00712170B8C828D838EF0EF55
:20185500124AB775820102179EE582FF601090F0E4E0FFBFFF00500690F0E4EF04F090F0BD
:20187500E4E0FFBF18005007900E10E4F5F022BF24005007901C20E4F5F02290518075F012
:2018950001E42290F0E0E07875F2E408F2900230125F877862740EF2E408F2125DB0AE82FA
:2018B500AF8374282EFEE43FFF90F0DFE054077D0025E0FCED33FDEC24CFF582ED34F0F566
:2018D50083EEF0EFA3F090F0DFE02401F0227E007F007D00BD0800501DED75F002A424CF03
:2018F500F58274F035F0F583E0FBA3E0FCEB2EFEEC3FFF0D80DEEFC423CEC423541F6ECE1B
:20191500541FCE6ECEFF90F0CCE0FCA3E0FDC3EE9CEF9D50058C828D83228E828F8322904C
:20193500FAB2E0FF3395E0FEC007C00674EBC0E0746AC0E0125AACE58124FCF58190F0BF04
:20195500E0FF7E0090F0C0E0FD3395E0FCC007C006C005C00474F6C0E0746AC0E0125AAC9E
:20197500E58124FAF5812275820E124D04124D3075820F124D0490FAB0E0FEA3E0FF7423A5
:20199500C0E08E828F8312490C15817404C0E0124455AC82AD83158190F0EBECF0EDA3F0F5
:2019B500C20A90F0CAE0FEA3E0FFC3EC9EED9F5004D20A803A90F0E7E0FCA3E0FD4C601357
:2019D500C3EC9EED9F500C90F0EBECF0EDA3F0D20A801C90F0E9E0FCA3E0FD4C6011C3EC4D
:2019F5009EED9F500A90F0EBECF0EDA3F0D20A90F0E9E0C0E0A3E0C0E090F0E7E0C0E0A315
:201A1500E0C0E090F0EBE0C0E0A3E0C0E090F0E5E0C0E0A3E0C0E07407C0E0746BC0E0126F
:091A35005AACE58124F6F581228A
:206AD600536C656570696E6720666F7220256C64206D730A0054656D7020256420430A0037
:206AF600525353492025642C204C51492025640A00426174745620426F6F742025642C2027
:1A6B16006E6F772025642C2054782025642C207570646174652025640A0025
:0500DC00781074FFF232
:201A3E00E58620E0FB225390FD00225380FB0022E58620E0FB004390020022E58620E0FB4B
:201A5E00004380040022121ADAE582600790F96CE0F58222121AA4E58260277408C0E074EF
:201A7E0050C0E074F9C0E090F96012462A158115811581920E500790F970E0F582227582BE
:201A9E0000227582002290F95BE05407FFBF012890F95CE003035403FFBF031C90F95CE023
:201ABE0023235403FFBF031090F95BE023235401FFBF0104758201227582002290F95BE081
:201ADE005407FFBF012390F95CE003035403FFBF021790F95CE023235403FFBF030B90F9FB
:201AFE005BE020E6047582012275820022AFF0AE83E58290FA70F0EEA3F0EFA3F090FA7032
:201B1E00E0FDA3E0FEA3E0FF90FA6EE0FBA3E0FC79007A00C3E99BEA9C5052E94A6016E981
:201B3E00540F6002800F7430C0E0746BC0E0125AAC15811581C003C004E92DF8EA3EFB8FE5
:201B5E000488828B838CF01262F5F87C00C000C0047432C0E0746BC0E0125AACE58124FC0B
:201B7E00F58109B900010AD004D00380A77430C0E0746BC0E0125AAC1581158122AFF0AEC0
:201B9E0083E5827812F2EE08F2EF08F27815E4F27B017811C3E2F5F0EB95F050227812E2B0
:201BBE00FA08E2FC08E2FFEB2AFAE43CFC8A828C838FF01262F5FA7815E22AF20B80D378B5
:201BDE0012E2FD08E2FE08E2FF8D828E838FF01262F5FD7815E2B50503D38001C3E433F5D1
:201BFE008222AFF0AE83E5827817F2EE08F2EF08F2781AE4F27B017816C3E2F5F0EB95F02E
:201C1E0050227817E2FA08E2FC08E2FFEB2AFAE43CFC8A828C838FF01262F5FA781AE22A34
:201C3E00F20B80D37817E2FD08E2FE08E2FF8D828E838FF0781AE2025F6CE5812404F58113
:201C5E00AF82C219C0071250FED0078F82124E60C0071251B3D2191250FED0077E01EE24FB
:201C7E00FC5003021D8290F9DB7414F0C007C0061237FB90F9ED74EDF090F9DB124FFAD053
:201C9E0006D0071249E7AA82AB83ACF0FD90FA7374A62AF0740E3BA3F0E43CA3F0E43DA31C
:201CBE00F0C0061249E7AA82AB83ACF0FD90FA73E58124FCF8E0F6A3E008F6A3E008F6A325
:201CDE00E008F6E58124FCF8C3EA96EB0896EC0896ED0896D0064003021D7EC007C0061254
:201CFE005110AD82D006D007C374818DF063F08095F050AD90F971E0FDB507A5C007C0063A
:201D1E00121A64AD82D006D007BDEE95C007C006121AA4E582D006D00760867408C0E07412
:201D3E0068C0E074F9C0E090F94612469615811581158190F95EE0FCA3E0FD90F94EECF0FB
:201D5E00EDA3F08F047D00C004C0057438C0E0746BC0E0125AACE58124FCF5818F828020BC
:201D7E000E021C7C8F057E00C005C0067442C0E0746BC0E0125AACE58124FCF58175820020
:201D9E00E58124FCF5812290F9DB742AF01237FB90F9ED74E5F090F9F47482F090F0E3E06C
:201DBE0090F9F5F090F0C0E090F9F0F090F0BFE090F9EFF090FAB2E090F9F1F090F0EBE0B6
:201DDE00FEA3E0FF90F9F2EEF0EFA3F090F9F6E4F090632193FE740193FF90F9F7EEF0EF3E
:201DFE00A3F090F959E090F9F9F090F0C9E090F9FAF078167415F290F9EE75F000121C004F
:201E1E0090F9DB024FFAD2191250FE12197C1219347F00781BE4F2781BE2B40E0040030240
:201E3E001F02C007121DA5D0071249E7AA82AB83ACF0FD74882AF52674133BF527E43CF588
:201E5E0028E43DF529C0071249E7AC82AD83AEF0FFC3EC9526ED9527EE9528EF9529D007B7
:201E7E004003021EF5C007125110AE82D007C374818EF063F08095F050CBC007121A64AEFD
:201E9E0082D007BEE6BF78117411F290F97175F000C007121B9BE582D00760A97408C0E017
:201EBE007468C0E074F9C0E090F94612469615811581158190F95E75F0001262F5FDA31295
:201EDE0062F5FE90F94EEDF0EEA3F090F0E0EFF090F97175F00022781BE22401F2781BE299
:201EFE00FF021E3590F0E0740EF090000075F00022D2191250FE7F00781CE4F2781CE2B429
:201F1E000E004003021FF690F9DB7414F090F9ED74E3F0C0071237FB90F9DB124FFAD00701
:201F3E001249E7AA82AB83ACF0FD74882AF52A74133BF52BE43CF52CE43DF52DC007124981
:201F5E00E7AC82AD83AEF0FFC3EC952AED952BEE952CEF952DD0075072C007125110AE8203
:201F7E00D007C374818EF063F08095F050CEC007121A64AE82D007BEE6C278117411F2906C
:201F9E00F97175F000C007121B9BE582D00760AC7408C0E07468C0E074F9C0E090F94612F5
:201FBE00469615811581158190F95E75F0001262F5FDA31262F5FE90F94EEDF0EEA3F090E4
:201FDE00F0E0EFF090F97175F00022781CE22401F2781CE2FF021F1A90F0E0740EF0900014
:201FFE000075F00022AFF0AE83E582781DF2EE08F2EF08F2781DE22402FA08E23400FB08F5
:20201E00E2FC8A828B838CF01262F5F52E852E2F75300090FA5CE0F531AE317F00E52FC3FA
:20203E009EFEE5309FFF7875EEF2EF08F2900063C004C003C002125F87AE82AF83D002D045
:20205E0003D0048E2F8F3090FA77E52FF0E530A3F0781DE22401FD08E23400FE08E2FF8D37
:20207E00828E838FF01262F5FD90F91FE0FFEDB50702800122E52E24D5500122C3E52E950B
:20209E00315001227463252FFEE43530FFC374239E74089F500122781DE2FD08E2FE08E241
:2020BE00FF78117466F28D828E838FF0C004C003C002121B9BE582D002D003D004700302A9
:2020DE002177781DE22403FD08E23400FE08E28D2F8E3090FA77E0FEA3E0FFEE24F3FEEFDC
:2020FE0034F0FF8E828F837463C0E0E4C0E0C02FC03012465CE58124FCF5818A828B838C4D
:20211E00F01262F5FA7F00788A7408F2E408F28A828F83C007C002126230AD82AE83D00204
:20213E00D007ED2421FDEE34F9FE5302078AF005F07401800225E0D5F0FBF4FA8D828E83CD
:20215E00E052028D828E83EAF0744FC0E0746BC0E0125AAC15811581227451C0E0746BC0E7
:20217E00E0125AAC1581158122AF82AE83ADF0FC7820EFF2EE08F2ED08F2EC08F290FA5CEC
:20219E00E0FB7A0090F91FE0FF7E00C003C002C007C0067462C0E0746BC0E0125AACE58142
:2021BE0024FAF581D2191250FE1249E785823285833385F034F53578207977E22414F308FC
:2021DE00E2340009F308E2340009F308E2340009F3900019E4F5F0125FA7AA82AB83AEF019
:2021FE00FFEA2532F532EB3533F533EE3534F534EF3535F5351249E7AA82AB83AEF0FFC3E0
:20221E00EA9532EB9533EE9534EF9535503C125110AF82C374818FF063F08095F050D612D5
:20223E001A64AF82BFE8CE90F97175F0001220037F00EF2421FDE434F9FE8D828E83E07099
:20225E00060FBF060040EBBF06AB7430C0E0746BC0E0125AAC15811581C2191250FE025156
:20227E00B390F972E4F0A3F090F97175F00022742AC0E0E4C0E0C0E090F9DB1245FE1581F9
:20229E001581158190F9DB742AF090F940E0600890F9F174E4F0800690F9F174E7F0740868
:2022BE00C0E07450C0E074F9C0E090F9E91246961581158115817408C0E07446C0E074F9EA
:2022DE00C0E090F9E112469615811581158190F9DCE054F84401F090F9DCE054C74440F08C
:2022FE0090F9DDE0440C54CF44C0F090F958E0FF04F090F9DEEFF090F94EE0FEA3E0FF9052
:20231E00F9DFEEF0EFA3F07DF27EF98D828E837411C0E07416C0E074F9C0E0124696158181
:20233E00158115817DF27EF97F0078167411F28D828E838FF0121C0090F9DB024FFAE58107
:20235E002404F581D2191250FE1251B37F00BF1E00400302243FC00712228DD0071249E7BB
:20237E00AB82AC83ADF0FE90FA7974642BF0749F3CA3F0740B3DA3F0E43EA3F0C007125142
:20239E0010AE82D007C374818EF063F08095F05051C007121A64AE82D007BEE8028028BE6D
:2023BE00E9028005BEEC33802978117403F290F97175F000C007121B9BE582D007602390D8
:2023DE00F97175F000806312227FAC82AD83AEF0805890000075F000805090000075F000EC
:2023FE008048C0071249E7C8E58124FCC8A68208A68308A6F008F690FA79E0FAA3E0FDA3E3
:20241E00E0FEA3E0FFE58124FCF8C3E69A08E69D08E69E08E69FD007500302239A0F0223BC
:20243E006C12227FAD82AE83AFF0E58124FCF58122741BC0E0E4C0E0C0E090F9DB1245FE36
:20245E0015811581158190F9DB7419F090F9F174EAF07408C0E07450C0E074F9C0E090F9DD
:20247E00E91246961581158115817408C0E07446C0E074F9C0E090F9E1124696158115819E
:20249E00158190F9DCE054F84401F090F9DCE054C74440F090F9DDE0440C54CF44C0F090B1
:2024BE00F94EE0FEA3E0FF90F9DFEEF0EFA3F090F958E0FF04F090F9DEEFF090F9DB024FE0
:2024DE00FAD2191250FE7F00BF1000506CC00712244FD0071249E785823A85833B85F03CF5
:2024FE00F53D1249E785823685833785F038F539E536C3953AFAE537953BFCE538953CFD79
:20251E00E539953DFEC3EA94A6EC940EED9400EE94005022C007125110AE82D007C37481CC
:20253E008EF063F08095F050B9C007121A64AE82D007BEEBAD220F808F22AF82E4FDCD5455
:20255E0003A2E0CD13CD13A2E0CD13CD13CDFCEF0303543F4DFDEF030354C0FE7F00740140
:20257E002DFDE43C8F828E838DF022AD82AE83AFF07C007B00BB04004003022618C0048BAB
:20259E0082C007C006C005C003122558A882A983AAF0FCD003D005D006D0077416C0E0E4A8
:2025BE00C0E074F3C0E074F0C0E0888289838AF0EC1206D0E58124FCF5817462C0E074FC0C
:2025DE00C0E090F0FB12496915811581920FD004300F218D008E018F027408C0E0C000C0B4
:2025FE000190F0F312462A158115811581920F50038C82220B8B040225937582FF22AF8244
:20261E005307F87E007D00BD040040030226A4C0068D82C007C005122558AA82AB83ACF099
:20263E00FED005D0077416C0E0E4C0E074F3C0E074F0C0E08A828B838CF0EE1206D0E58147
:20265E0024FCF5817462C0E074FCC0E090F0FB124969158115819228D006302823C0069074
:20267E00F108E0FC5304F87B008F027E00ECB50206EBB506028004D0068005D0068E822256
:20269E000D8D060226257582FF22122558AC82AD83AEF0FF7416C0E0E4C0E074F3C0E07464
:2026BE00F0C0E08C828D838EF0EF1206D0E58124FCF58190F108E0F58222AF828F060EEE39
:2026DE0024FB50027E00EEB507038E82228E82C007C006122558AA82AB83ACF0FDD006D049
:2026FE00077416C0E0E4C0E074F3C0E074F0C0E08A828B838CF0ED1206D0E58124FCF58195
:20271E007462C0E074FCC0E090F0FB12496915811581922850A890F108E0FD5305F87C00C6
:20273E00BD789BBC00988E8222122558AC82AD83AEF0FF7404C0E0E4C0E08C828D838EF063
:20275E00EF12091B15811581227F00BF0400500C8F82C007122747D0070F80EF22AF828FBB
:20277E00057E00C005C0067471C0E0746BC0E0125AACE58124FCF5818F82122558020A5B0E
:20279E007825E4F208F208F208F27B00BB0400400302283D8B82C00312255885823E85832A
:2027BE003F85F040F541D0037416C0E0E4C0E074F3C0E074F0C0E0853E82853F838540F004
:2027DE00E5411206D0E58124FCF5817462C0E074FCC0E090F0FB12496915811581921050EE
:2027FE003AC00390F104E0FAA3E0FBA3E0FEA3E0FF7825C3E29A08E29B08E29E08E29FD09C
:20281E0003501890F1047825E0F2A3E008F2A3E008F2A3E008F290F945EBF00B0227AA78C5
:20283E0025E2F58208E2F58308E2F5F008E222AF82AE83D21190F91FE0FD7C007B007A0084
:20285E008C44EBC454F0C544C4C5446544C54454F0C5446544F545EDC4540F4544F544ED1C
:20287E00C454F0F543754200300D17782FE542F27470254308F2E4354408F2E4354508F23A
:20289E0080497810E2F582C007C00612255885824685834785F048F549D006D00774162561
:2028BE0046F546E43547F547E43548F548E43549F549782FE5462542F2E547354308F2E5F1
:2028DE0048354408F2E549354508F290FA807405F090FA5CE4F090F94004F07829EFF20809
:2028FE00EEF27406C0E0E4C0E0C0E090F9211245FE15811581158190FA80E0FB14F0EB7097
:20291E0003022C901011030229DF7829E2FA08E2FB8A828B8378627463F2E408F2125DB08E
:20293E00AA8290FA7DEAF07829E2FB08E2FF8B828F8378837463F2E408F2C0021260F3E538
:20295E00828583F0D00245F0600690FA7DEA04F090FA7DE024EA500690FA7D7415F090FA38
:20297E005CE0FB7A0090FA7DE0FFC3EA9F50528B067F00788A7408F2E408F28E828F83C074
:20299E0007C006C003C002126230AC82AD83D002D003D006D007EC2421FCED34F9FD5306D6
:2029BE00078EF005F07401800225E0D5F0FBFE8C828D83E0FF42068C828D83EEF00B0A80EF
:2029DE00A412235CAA82AB83AFF0EA4B7003F582220ABA00010B8A828B838FF01262F5FE9A
:2029FE00A31262F5FF4E60428E048F05C3EC9423ED9400501A7877EEF2EF08F2E408F208A9
:202A1E00F2900019E4F5F0125FA7124A48801BEC24F6FCED34FFFD7F007E008C828D838F14
:202A3E00F0EE1217E3D2191250FE900122E4F5F012218778337401F290FA5CE0FF7E009028
:202A5E00FA7DE0FDC3EE9D505E8F047D00788A7408F2E408F28C828D83C007C006C005C07A
:202A7E0004126230AA82AB83D004D005D006D007EA2421F582EB34F9F5835304078CF005CB
:202A9E00F07C017D008006EC2CFCED33FDD5F0F7E0FB7A005204EA5205EC4D60067833E4A1
:202ABE00F280040F0E80987833E27003022C5590FA7DE07875F2E408F2900063125F87AE8D
:202ADE0082AF83782DEEF2EF08F290FA8174F3F074F0A3F0E4A3F090FA5CE0704B90F0F3F2
:202AFE00E0FCA3E0FD7829ECF208EDF290F0F5E0FCA3E0FD782BECF208EDF290FA7EE4F0E1
:202B1E00A3F0782DE2FC08E2FDEC24FCFCED34FFFD782DECF2ED08F290FA81740424F3F081
:202B3E00E434F0A3F0E4A3F07829E2FC08E2FD782DC3E2F5F0EC95F008E2F5F0ED95F050CE
:202B5E000A7829792DE2F308E209F37829E2FC08E2FD782DD3E29CF4B3FCB308E29DF4FD21
:202B7E007829ECF208EDF275820412179E90FA81E0F546A3E0F547A3E0F548AA46AF47780C
:202B9E002DE2C0E008E2C0E0C002C007782FE2F58208E2F58308E2F5F008E212080BE581AF
:202BBE0024FCF5817582041217D7782DE2FA08E2FD7E007F00782FE22AF208E23DF208E259
:202BDE003EF208E23FF2AD46AE47AF48782DE2F54608E2F547AA46AC47154674FFB5460217
:202BFE001547EA4C60368D828E838FF01262F5FCA3AD82AE838C4275430090FA7EE0FAA37D
:202C1E00E0FC8A4A8C4BAB42AC43EB254AFBEC354BFC90FA7EEBF0ECA3F080B990FA7DE0F4
:202C3E00FF90FA5CE02FF07829E2FE08E2FF4E60067833E4F2D21190F940E4F07833E27076
:202C5E0003022915782BE2FE08E2FF90FA7EE0FCA3E0FDEEB50406EFB505028011748BC09B
:202C7E00E0746BC0E0125AAC1581158180047582012275820022AFF0AE83E58290FA86F0A5
:202C9E00EEA3F0EFA3F090FA86E0FDA3E0FEA3E00DBD00010E8D828E837408C0E07430C0A9
:202CBE00E074F9C0E012462A1581158115819212501790F938E0FCA3E0FDA3E0FEA3E0FF9A
:202CDE00EC4D4E4F6003022D9490FA86E0FDA3E0FEA3E0FF74092DFCE43EFA8F038C828AFE
:202CFE00838BF01262F5F9A31262F5FAA31262F5FBA31262F5FCC3E49974809AE49BE49C74
:202D1E00501C1224DF90F08F7405F090FA5B7401F090F0E374E0F0123BE27582002290F9DA
:202D3E001FE4F0042DFAE43EFBC002C00390F91712452C15811581740D2DFAE43EFB8F040E
:202D5E008A828B838CF01262F5FA90F920F07411C0E0C005C00690F92F1246961581158141
:202D7E0015817409C0E0E4C0E0907000E4F5F012091B1581158190F938E0FCA3E0FDA3E033
:202D9E00FEA3E0FFEC4D4E4F7003022E29C3E49C74109DE49EE49F500B90FA84E4F07410C9
:202DBE00A3F0800890FA84ECF0EDA3F0D20D90FA84E0FEA3E0FF8E828F8312284DE58260B3
:202DDE004690F91FE0FF0F90F91FEFF090F938E0FCA3E0FDA3E0FEA3E0FF90FA84E0FAA3C7
:202DFE00E0FB8A008B01E4FAFBECC398FCED99FDEE9AFEEF9BFF90F938ECF0EDA3F0EEA368
:202E1E00F0EFA3F0022D94758200221224DF75820122AFF0AE83E58290FA8BF0EEA3F0EF6B
:202E3E00A3F090FA8BE0FDA3E0FEA3E0FF74012DFAE43EFB8F048A828B837408C0E07430C6
:202E5E00C0E074F9C0E012462A1581158115819213504090F93DE0FC740E2DFDE43EFE8D33
:202E7E00828E838FF01262F5FDECB5052690F938E0FCA3E0FDA3E0FEA3E0FFEC4D4E4F609A
:202E9E001274A3C0E0746BC0E0125AAC1581158102306175820412179E90F9457834E0F2E7
:202EBE0090FA8BE0FCA3E0FDA3E0FE740E2CFAE43DFB8E078A828B838FF01262F5FA54FC5D
:202EDE00601690FA6E7411F0E4A3F08C828D838EF0121B0B7834E4F290F945E02401F0FF62
:202EFE00BF0400400590F945E4F090F945E0FF7834E2B507197582041217D774B6C0E074C1
:202F1E006BC0E0125AAC15811581758201228F82122558AC82AD83AEF0FF7416C0E0E4C0C1
:202F3E00E074F3C0E074F0C0E08C828D838EF0EF1206D0E58124FCF5817462C0E074FCC073
:202F5E00E090F0FB124969158115819213500890F108E054F8708190F945E0F54C7810F2FC
:202F7E0090FA8BE0F54DA3E0F54EA3E0F54F7409254DFAE4354EFBAF4F8A828B838FF0127B
:202F9E0062F5FAA31262F5FBA31262F5FEA31262F5FFC3E49A74409BE49EE49F5007122484
:202FBE00DF75820022854C82122558AC82AD83AEF0FF7404C0E0E4C0E08C828D838EF0EFF7
:202FDE0012091B158115817582041217D77810E2FE7F00C006C00774C0C0E0746BC0E0129D
:202FFE005AACE58124FCF58190F91FE4F004254DFDE4354EFEC005C00690F91712452C159A
:20301E00811581740D254DFDE4354EFEAF4F8D828E838FF01262F590F920F0AD4DAE4E741D
:20303E0011C0E0C005C00690F92F12469615811581158190F938E0FEA3E0FF90FA89EEF0BC
:20305E00EFA3F090F938E0FCA3E0FDA3E0FEA3E0FFEC4D4E4F70030230F8C3E49C74109DD9
:20307E00E49EE49F500B90FA84E4F07410A3F0800890FA84ECF0EDA3F090FA84E0FEA3E078
:20309E00FF8E828F8312284DE582604A90F91FE0FF0F90F91FEFF090F938E0F550A3E0F5DE
:2030BE0051A3E0F552A3E0F55390FA84E0FAA3E0FBE4FEFFE550C39AFAE5519BFBE5529E98
:2030DE00FEE5539FFF90F938EAF0EBA3F0EEA3F0EFA3F00230617582002275820412179E74
:2030FE007430C0E074F9C0E090F0F312452C1581158190F0FB7421F07447A3F0744DA3F09D
:20311E007447A3F090F941E02401F0A3E03400F0A3E03400F0A3E03400F090F941E0FCA346
:20313E00E0FDA3E0FEA3E0FF90F104ECF0EDA3F0EEA3F0EFA3F090FA89E0FEA3E0FF7D00BD
:20315E007C0090F0FFEEF0EFA3F0EDA3F0ECA3F090F93CE090F103F090F93DE090F108F0BF
:20317E007810E2F582122558AC82AD83AEF0FF7416C0E0E4C0E074F3C0E074F0C0E08C82FF
:20319E008D838EF0EF12080BE58124FCF5817582041217D775820122AFF0AE83E58290FA9D
:2031BE008FF0EEA3F0EFA3F0C20D90FA8FE0F557A3E0F558A3E0F559740D2557FAE4355852
:2031DE00FBAC598A828B838CF01262F5FCBC02028024BC030302353EBC10028019BC2002F6
:2031FE008014BC2102800FBCA803023431BCAF0302351E0235B090FA8FE0FFA3E0FEA3E03B
:20321E00FD75548E7555FA755600740E2FF557E43EF5588D598557828558838559F012625B
:20323E00F5FB8554828555838556F0125F6C90FA8EE020E203023315758204C007C006C091
:20325E000512179ED005D006D00790FA8EE0C423541FFB603CBB0F02806C855782855883A3
:20327E008559F01262F5F582C007C006C00512261CAB82D005D006D007BBFF0280488B829C
:20329E00C007C006C005122747D005D006D007803574012FF557E43EF5588D5985578285DF
:2032BE0058838559F0C007C006C005122589AB82D005D006D007BBFF02800B1224DF78357D
:2032DE007401F202342B758204C007C006C0051217D7D005D006D0078F828E838DF0122E5A
:2032FE0030E582600B1224DF78357401F202342B7835E4F202342B74012FF557E43EF558E1
:20331E008D598557548558558559568554828555837408C0E07427C0E074F9C0E012462A75
:20333E001581158115819214500B1224DF78357401F202342B758204C007C006C0051217AC
:20335E009E8557828558838559F0122589AC82758204C0041217D7D004D005D006D007BC66
:20337E00FF028051C007C006C005C0041224DFD004D005D006D0078F578E588D59AA57AB7E
:20339E00587411C0E0C002C00390F92F12469615811581158190F938E4F0A3F0A3F0A3F057
:2033BE0090FC61ECF090FA8EE054037824F28C8212277B803D74CEC0E0746BC0E0125AAC51
:2033DE00158115818F828E838DF0122E30E582601B1224DF7810E2FB90FC61F090FA8EE063
:2033FE0054037824F28B8212277B80067835E4F2801B90F930E0FAA3E0FBC002C00390F946
:20341E002712452C1581158178357401F27835E2F5822290F938E0FAA3E0FBA3E0FEA3E05F
:20343E00FFEA4B4E4F702F74012557FDE43558FEAF598D828E837408C0E07430C0E074F9AC
:20345E00C0E012462A158115811581921450071224DF7582012290F91FE4F090FA8FE0F5D4
:20347E0054A3E0F555A3E0F55674012554FAE43555FBC002C00390F91712452C158115811A
:20349E00740D2554FDE43555FEAF568D828E838FF01262F590F920F0AD54AE557411C0E0DC
:2034BE00C005C00690F92F12469615811581158174092554FDE43555FEAF568D828E838FE8
:2034DE00F01262F5FDA31262F5FE8D828E8312284DE582602790F938E4F0A3F0A3F0A3F08B
:2034FE0075820412179E90F0F775F0001213BA7582041217D71224DF7582012275820022EE
:20351E001224DF740E2557FDE43558FEAF598D828E838FF01262F5F58212045A75820122FD
:20353E0075820412179E8557828558838559F0122C94E582605875820412179E1235CB302A
:20355E000D11123B69907019E4F5F01206B012567C805674D6C0E0746BC0E0125AAC1581FE
:20357E0015817582041217D790FA5B7401F090F0E374E0F0123BE27408C0E0E4C0E0C0E03C
:20359E0090F9271245FE158115811581801B758200227F00C004C00774F3C0E0746BC0E002
:2035BE00125AACE58124FCF58175820022783AE4F208F208F208F2C20D7419C0E0E4C0E0CA
:2035DE0074A2C0E074FDC0E0907000E4F5F01206D0E58124FCF58178367419F2747008F24E
:2035FE00E408F208F27406C0E0740AC0E0746CC0E090FDAB12462A158115811581921540BA
:20361E000790F08F7405F02290FDAB1246C0AE82AF83906C0A1246C0AC82AD83EEB5041EF8
:20363E00EFB5051AC006740AC0E0746CC0E090FDAB12462A1581158115819215400790F05B
:20365E008F7402F02290FDAAE0FFBF0102800790F08F7401F02290FDA8E0FEA3E0FFC3E404
:20367E009E74809F500790F08F7403F02290FDA8E0FEA3E0FF4E700302374790FDA8E0FE23
:20369E00A3E0FFC374239E74089F50047E237F08C006C00774F3C0E074F0C0E07836E2F5DE
:2036BE008208E2F58308E2F5F008E21206D0E58124FCF58190FA9274F3F074F0A3F0E4A37A
:2036DE00F090FA95EEF0EFA3F0783AE2F58208E2F58308E2F5F008E2C007C00612382078C8
:2036FE003AC0E0E582F2E58308F2E5F008F2D0E008F2D006D0078E028F037C007D00783628
:20371E00E22AF208E23BF208E23CF208E23DF290FDA8E0FCA3E0FDECC39EFEED9FFF90FD51
:20373E00A8EEF0EFA3F002368B90FDA2E0FCA3E0FDA3E0FEA3E0FF783AE2B5041108E2B515
:20375E00050C08E2B5060708E2B50702800790F08F7404F02290FDA6E0FEA3E0FF90F08D26
:20377E00EEF0EFA3F0C006C0077413C0E0746CC0E0125AACE58124FCF581D20D2212279EAB
:20379E00AC82AD83AEF0FF90F941ECF0EDA3F0EEA3F0EFA3F0227408C0E07450C0E074F9D8
:2037BE00C0E090FA6612469615811581158190FA5DE054F84421F090FA5EE054F344C8F038
:2037DE0090FA607437F07413A3F090FA6274FFF0A3F090FA647437F07413A3F0227411C040
:2037FE00E0745DC0E074FAC0E090F9DC12469615811581158190F958E0FF04F090F9DEEF2D
:20381E00F022AC82AD83AEF0FF783EECF4F2EDF408F2EEF408F2EFF408F290FA92E0F5620E
:20383E00A3E0F563A3E0F56490FA95E0F55EA3E0F55F855E60855F61155E74FFB55E0215F2
:20385E005FE5604561700302391E8562828563838564F01262F5FEA38582628583638E0417
:20387E007D007E007B00783EE26CF208E26DF208E26EF208E26BF27846E4F208F27846C3D5
:20389E00E2940808E26480948050A7783EE25401FA08E25400FB08E25400FC08E25400FE1D
:2038BE007842C3E49AF2E49B08F2E49C08F2E49E08F27841E2C313F56818E213F56718E25D
:2038DE0013F56618E213F5657842E25420FC08E25483FD08E254B8FE08E254EDFA783EEC70
:2038FE006565F2ED656608F2EE656708F2EA656808F27846E22401F208E23400F202389B3B
:17391E00783EE2F4FB08E2F4FC08E2F4FD08E2F48B828C838DF022BD
:206B30000A002530327820004150206F6E2025640A004E6F204150206F6E2025640A002E8F
:206B500000636865636B435243206661696C65640A005245512025642070617274202564AF
:206B70000044726177696E6720696D61676520696E20736C6F742025640A00626C6B2066CB
:206B900061696C65642076616C69646174696F6E210A0072657374617274696E6720696D37
:206BB0006720646C0A004E6F20736C6F74730A006E657720646C20746F2025640A00646C88
:206BD00020696D670A004F544120696D6167652076616C69646174696F6E206661696C65CB
:206BF000640A00646174615479706520307825782069676E6F7265640A006368726F6D61EA
:206C10003239004F54412076616C6964617465642C207570646174696E6720746F207665A1
:0B6C30007273696F6E202530780A0037
:0576A600FF21474D47E4
:20393500E58620E0FB225390FD00225380FB0022E58620E0FB004390020022E58620E0FB35
:2039550000438004002290F09B7438F0E4A3F030050990F09B7430F0E4A3F02290F959E0F3
:20397500704590F0C7E0603FC20490F09F7410F0C4A3F090F0A17406F0E4A3F090720D7581
:20399500F080120D61D20490F09F7418F07401A3F090F0A1740DF0E4A3F090722F75F0808A
:2039B500120D61D2038002C203300A2690F0C6E06020C20490F09F7410F0C4A3F090F0A17F
:2039D5007470F0E4A3F090723975F080120D61D20222C20222123F237460C0E07472C0E09D
:2039F5001241D2158115817473C0E07472C0E01241D21581158190F09BE0FEA3E0FF74080C
:203A15002EFEE43FFF90F09BEEF0EFA3F07486C0E07472C0E01241D21581158174A9C0E09A
:203A35007472C0E01241D21581158174CBC0E07472C0E01241D21581158190F09BE0FEA348
:203A5500E0FF74082EFEE43FFF90F09BEEF0EFA3F090F09DE4F0A3F0745BC0E07472C0E0B4
:203A75001241D215811581023A9F758205123F00E58260012274E9C0E07472C0E0125AAC33
:203A9500158115819039EA020D3B7434C0E074FCC0E0E4C0E074F5C0E07472C0E01241D258
:203AB500E58124FBF58122906321E493C0E0740193C0E07401C0E07473C0E01241D2E581DA
:203AD50024FCF58122123F23123F3F7410C0E07473C0E01241D215811581123ABC90F0E5AC
:203AF500E0C0E0A3E0C0E07421C0E07473C0E01241D2E58124FCF58190FAB2E0FF3395E06E
:203B1500FEC007C006742FC0E07473C0E01241D2E58124FCF581023A9F758201123F00E511
:203B35008260012212197C903ADA020D3B123F23123F3FC20512395B90F08DE0C0E0A3E055
:203B5500C0E07442C0E07473C0E01241D2E58124FCF58122903B42020D3B123F23123F3F35
:203B7500D2057458C0E07473C0E01241D215811581D20490F08FE0FFBF02028018BF040231
:203B95008023BF05307469C0E07473C0E01241D215811581227478C0E07473C0E01241D2CA
:203BB50015811581227489C0E07473C0E01241D215811581227E00C007C0067494C0E074E4
:203BD50073C0E01241D2E58124FCF58122903B6F020D3B123F23123F3F74A3C0E07473C094
:203BF500E01241D21581158174BBC0E07473C0E01241D21581158190F09BE0FEA3E0FF90CD
:203C1500F0A1EEF0EFA3F090F94CE0FF7E0090F94DE0FD7C00C007C006C005C00474D4C01F
:203C3500E07473C0E01241D2E58124FAF58190F94AE0FF7E0090F94BE0FD7C00C007C006FF
:203C5500C005C00474E6C0E07473C0E01241D2E58124FAF58190F948E0FF7E0090F949E046
:203C7500FD7C00C007C006C005C00474E6C0E07473C0E01241D2E58124FAF58190F946E051
:203C9500FF7E0090F947E0FD7C00C007C006C005C00474E6C0E07473C0E01241D2E5812423
:203CB500FAF58190F099E0FEA3E0FF8E02EFFB3395E0FCFD7428C39AF50F74019BF510E4F5
:203CD5009CF511E49DF512906F61E493FDE4FC3395E0FBFAE50FC39DFDE5109CFCE5119BE5
:203CF500FBE5129AFA78647402F2E408F208F208F28D828C838BF0EAC007C006125DFBAAEF
:203D150082AB83D006D00790F09FEA2EF0EB3FA3F090F0BFE0FF7E0090F0C0E0FD3395E0EC
:203D3500FC90F959E0FB7A00C007C006C005C004C003C00274EFC0E07473C0E01241D2E50C
:203D55008124F8F581123FC0023ABC758203123F00E58260012212197C903BE8020D3B1247
:203D75003F23123F3F7409C0E07474C0E01241D215811581741CC0E07474C0E01241D21554
:203D950081158190F099E0FEA3E0FF90FA97EEF0EFA3F090F09BE0FEA3E0FF90F0A1EEF083
:203DB500EFA3F07431C0E07474C0E01241D21581158190FA97E0FEA3E0FF8E02EFFB33958B
:203DD500E0FCFD74F0C39AFAE49BFBE49CFCE49DFD78647402F2E408F208F208F28A828B19
:203DF500838CF0EDC007C006125DFBAA82AB83D006D007EA2EFEEB3FFF90F09FEEF0EFA3F6
:203E1500F0EE5407601574075EFC7D00EEC39CFEEF9DFF90F09FEEF0EFA3F0906F6175F073
:203E350080120D6190F0A1E0FEA3E0FF74082EFEE43FFF90F0A1EEF0EFA3F0D2049070EBE0
:203E550075F080120D61023971758204123F00E582600122903D74020D3B123F23123F3F77
:203E750090F09BE0FEA3E0FF74102EFEE43FFF90F09BEEF0EFA3F07445C0E07474C0E01272
:203E950041D215811581123FC0023971758205123F00E582600122903E6F020D3B123F23DF
:203EB500123F3F7455C0E07474C0E01241D2158115817469C0E07474C0E01241D215811546
:203ED5008190F09F747CF0E4A3F090F09BE0FEA3E0FF90F0A1EEF0EFA3F0D2049070EB75A4
:203EF500F080020D61903EB2020D3BE582C40354F8F58212261CAF82BFFF02800D7824E4C0
:203F1500F28F8212277B7582012275820022C206C204C20590F099E4F0A3F090F09DF0A31D
:203F3500F090F09BF0A3F0C20922D20490F0A1E4F0A3F0906DDE93FF7E007428C39FFF7437
:203F5500019EFE90F09FEFF0EEA3F0906DDD75F080120D61C204906C3CE493FF7E0090F07F
:203F75009FE0FCA3E0FDECC39FFFED9EFE90F09FEFF0EEA3F0906C3B75F080120D61906E42
:203F9500A0E493FF7E0090F09FE0FCA3E0FDECC39FFFED9EFE90F09FEFF0EEA3F0D2049042
:203FB5006E9F75F080120D61C2042290F0E9E0FEA3E0FF4E601190F0E7E0FCA3E0FDC3EE96
:203FD5009CEF9D5002800890F0E7E0FEA3E0FFC006C0077483C0E07474C0E01241D2E581CC
:053FF50024FCF581220F
:206C3B00801AFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000000000000000AF
:206C5B00000000000000000000000000000000000000000000000000000000000000000019
:206C7B000000000000000000000000000000000000001C000000001F9F80000000003870F7
:206C9B0001C07F000000001F9FC000000000387001C07F000000001F9FE0000000003870ED
:206CBB0001C0F7800000001C1CE000000000380001C0E3800000001C1CE0000000003800BD
:206CDB0001C0E39DC1C7701F9CE773B871D03873B9C7E39FE3E7F81F9FEFF3FCF9F03873B3
:206CFB00FDCEE39FE777F81F9FCFF3FDDDF03873FDDCE39CE7F7381C1F8E739DFDC0387332
:206D1B009DF8E39CE7F7381C1C0E739DFDC038739DF8F79CE707381C1C0E739DC1C03873A0
:206D3B009DDC7F1FE7F7381F9C0FF3FDFDC03F739DDC7F1FE3E7381F9C0FF3FCF9C03F73A5
:206D5B009DCE1E1DC1C7381F9C0773B871C03F739DC7001C000000000000038000000000DF
:206D7B000000001C0000000000000380000000000000001C000000000000038000000000BA
:206D9B000000001C0000000000000380000000000000000000000000000000000000000039
:206DBB00000000000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFC6
:206DDB00FFFF800C000882A2AB55BFFFFFFF7DB4622800000010101176FF7BFFFF7FB7A96D
:206DFB0055505100002922966FF7BFFFFFFFEAE622AA08000002542ABF3F7FFFFFFFFD598B
:206E1B00B4102000002423B5B5DFFFFFFFFFF6AE48551000008890546AEFFFFFFFFFFBF5E5
:206E3B00A382000000012DA3B3FFFFFFFFFFF6BE4E5209000490020D55DFFFFFFFFFFDDD89
:206E5B0068A9001000490CFBAB6FFFFFFFFFFEEB955A002000129122BFDFFFFFFFFFFFF545
:206E7B00658140400028127DEFFFFFFFFFFFFFEFAB28000000420A9775FFFFFFFFFFFFF7E6
:206E9B004AC20400800C0008029CDFFFFFFFFFFFFF6A6A8D002000044D72AAFFFFFFFFFFD3
:206EBB00FFD5D57480000240128EDFFDFFFFFFFFFFAEAA0A11200020525FF57FFFFFFFFF8D
:206EDB00FF7294AA240000010AAB6F77FFFFFFFFFDAF545488000004804D95EBFFFFFFFF03
:206EFB005B58B5514000000808A6B3F77FFFFFFFFFAD4AA0100000029641DCAEFFFFFFFF9D
:206F1B00FDBFEA4802000000093EAB75EFFFFFFFFFD4B121080000000AC35DFF7FFFFFFFC1
:206F3B00EFEF444A64800000A152A6EFEFFFFFFFD6CAF5101800000002154BD5DFFFFFF7AA
:206F5B00EBD4D885000038380000000000000000000000000000000000000000000000008A
:206F7B000000000000000000000000000000000007C00000000001FFF0000000000FFFF041
:206F9B00000000007FFFF000000001FFFFF000000007FFFFC00000001FFF80000000007F97
:206FBB00F80000000000FFE00000000001FF000000000007FE00000000000FF800000000D3
:206FDB00001FE000000000003FC00003E000007F80007FF00000FE0003FFF00001FC000F4B
:206FFB00FFF00001F8003FFFF00003F800FFFF800007F001FFE000000FE003FF0000000F10
:20701B00C00FF80000001F801FF00000001F803FC00000003F003F800000003F007F000086
:20703B0000007E00FE0007E0007E01FC001FF000FC01F8007FF000FC03F001FFF000F8030A
:20705B00F003FFF001F807E007FF0001F807E00FF00001F00FC01FE00001F00FC03F800030
:20707B0003F00F803F000003F01F807E000003E01F807E000003E01F00FC01E003E01F0043
:20709B00FC07F803E01F00F80FFC03E03F00F80FFC03E03F01F81FFE03E03F01F81FFE033D
:2070BB00E03F01F81FFE03C03E01F01FFE01C01E00F00FFC00000000000FFC00000000008C
:2070DB0007F8000000000001E000000000000000303000001FF800000000FFFF000000033D
:2070FB00FFFFE000000FFFFFF000003FFFFFFC00007FF00FFE0000FF8001FF0001FE000067
:20711B007F8003F800001FC007F000003FE00FE000007FF00FC00000FFF01F800001FFF8B2
:20713B001F000003FFF83F000007FEFC3E00000FFC7C7E00001FF87E7C00003FF03E7C009E
:20715B00007FE03EFC0000FFC03FF80001FF801FF80003FF001FF80007FE001FF8000FFCAE
:20717B00001FF8001FF8001FF8003FF0001FF8007FE0001FF800FFC0001FFC01FF80003F5A
:20719B007C03FF00003E7C07FE00003E7E0FFC00007E3E1FF800007C3F3FF00000FC3F7F59
:2071BB00E00000FC1FFFC00001F80FFF800003F00FFF000007F007FE00000FE003FC000088
:2071DB001FC001FE00007F8000FF8001FF00007FF00FFE00003FFFFFFC00000FFFFFF00086
:2071FB000003FFFFE0000000FFFF000000001FF800001010000000000000000000007C00E2
:20721B008200000038004407007903811C0103810079000708080063773E1C3E77631010B4
:20723B00000003C00FF0081008100810081008100810081008100BD00BD008100FF00000E4
:20725B000A000A0A0009084F70656E4550617065724C696E6B0A08006F70656E657061701D
:20727B0065726C696E6B2E64650A0049276D0920666173742061736C656570202E202E2063
:20729B002E20746F2077616B65206D653A000A52656D6F7665206261747465726965732C27
:2072BB002073686F727420626174746572790A00636F6E74616374732C207265696E73650D
:2072DB007274206261747465726965732E004465657020736C6565700A00546167204D4111
:2072FB00433A202573006368726F6D613239207625303458005374617274696E67202E2028
:20731B002E202E0A0A000A564261743A202564206D560A0054656D70657261747572653AB3
:20733B00202564430A0A000C466C617368696E67207625303478202E202E202E000C4F54CA
:20735B0041204641494C4544203A280A0A000C4E6F74204F544120696D616765000C57723D
:20737B006F6E67204F544120696D616765000C435243206572726F72000C4572726F722023
:20739B00436F64652025640057616974696E6720666F722064617461202E202E202E0A00C6
:2073BB000A466F756E642074686520666F6C6C6F77696E672041503A000A4150204D4143E3
:2073DB003A202530325825303258002530325825303258000A43683A2025642052535349C3
:2073FB003A202564204C51493A2025640A00084E6F20415020666F756E64203A280A080A4C
:20741B00005765276C6C2074727920616761696E20696E2061000A6C6974746C65207768E8
:20743B00696C65202E202E202E00087A7A5A5A5A202E202E202E0A080A000C454550524F76
:20745B004D204641494C4544203A280A0A000C536C656570696E6720666F726576657220ED
:15747B002E202E202E0A0A00564261743A202564206D560A00E1
:203FFA00C007C006C005C004C00390FAA0E060030240EE90FAA1E0FF24FB50030240EBEF99
:20401A002F2F9040207302402F02404D0240CE0240E50240EB90FA9E744BF0E4A3F090FA89
:20403A00A0740BF090FAA17401F090FAA27468F00240EE90FA9B124916E582FF6045EF24EB
:20405A00E0FFBF600040027F1F90FAA3E0FE0E90FAA3EEF0C0078E82124440AD82AE831562
:20407A008190FAA2E0FC7B002DFDEB3EFE8D828E837467C0E0124911AE82158190FAA2EEEA
:20409A00F0800B90FAA17402F090FAA2E0FFEF75F002A42490F582747435F0F583E493FED0
:2040BA00A3E493FF90FA9EEEF0EFA3F090FAA0740BF0802090FAA17403F090FA9E74E3F00B
:2040DA00741AA3F090FAA003F0800990FAA17404F0C3802D90FA9EE0FEA3E0FFEE5401240D
:2040FA00FFE433FDEFC313CE13CEFF90FA9EEEF0EFA3F090FAA0E0FF1F90FAA0EFF0ED2456
:0C411A00FFD003D004D005D006D007224F
:207490009B01B3013303C90089019101990019013101930013012301CD01D90199039D01DF
:2074B000B90139037302D30193033B017301B7039701A7012703370167016702DB001B0311
:2074D0006303C500D10011038D00B10031028B00A3002302ED008D03B103DD001D03710326
:2074F00077038B03A303BB003B02BB03D70017034703B7003702C702F70213028F02650020
:20751000850169000903A10121034D000D01590019026101610243025300EF024301F10246
:20753000E501E901C9033D01790179022F014F014F02DB037B036F03F500C503D103BD007F
:0E7550003D02AF002F02DD03BD03D703AF03E2
:20412600C007C006C005C004C001C000AC82AD83AEF0FFBF20005031BF0A030241C58F82A2
:20414600C007C006C005C004C003C002C001C000C02512430DD025D000D001D002D003D0EB
:2041660004D005D006D00780567E00EF24E0FFEE34FFFEEF2FFFEE33FEEF24F8F582EE346E
:2041860063F583E493A3E493C4540FFE90F0B3EEF0300507EE2EFE90F0B3F090F0B3E0FFEC
:2041A6003395E0FE0FBF00010E90F099E0FCA3E0FDEF2CFFEE3DFE90F099EFF0EEA3F0D075
:2041C60000D001D004D005D006D00722C007C006C005C004C003C001C000E58124F6FFC0F7
:2041E60007C006C005C004C003C002C001C000C0251242C0D025D000D001D002D003D00455
:20420600D005D006D007E58124F6F886050886068D828E83E493FCBC0C7290F099E4F0A322
:20422600F0C007C005C006C0E0C0E090412612575BE58124FBF58190F099E0FDA3E0FE3396
:2042460095E0FCFB7428C39DFD74019EFEE49CFCE49BFB78647402F2E408F208F208F28D49
:20426600828E838CF0EBC007C002C001C000C025125DFBAB82AC83ADF0FED025D000D00158
:20428600D002D00790F099EBF0ECA3F0C007E58124F5F8E6C0E008E6C0E0E4C0E0C0E090F6
:2042A600108912575BE58124FBF581D000D001D003D004D005D006D007223006253005061E
:2042C6007E147F0080047E0A7F0090F0B4EEF03005067E207F0080047E107F0090F0B3EE20
:2042E600F0223005067E207F0080047E107F0090F0B4EEF03005067E147F0080047E0A7FD4
:204306000090F0B3EEF022AF82BF08028018BF0902804EBF0A028013BF0B028055BF0C016F
:2043260022BF0D568038B2050242C01242C090F0B4E0FE3395E0FD90F09BE0FBA3E0FCEE92
:204346002BFEED3CFD90F09BEEF0EDA3F090F09DE0FDA3E0FE90F099EDF0EEA3F022B204C5
:204366002290F099E0FDA3E0FE90F09DEDF0EEA3F02290F09DE4F0A3F0227E00C007C00650
:12438600745EC0E07475C0E0125AACE58124FCF58122F4
:15755E00496E76616C69642063686172203078253032780A00C2
:20439800E58620E0FB225390FD00225380FB0022E58620E0FB004390020022E58620E0FBC8
:2043B80000438004002275FB02228582F9E5F830E1FB53F8FDE5F820E0FB85F9822253F3F7
:2043D800C775FA2275FC0C75F8C043F4C043F102D20B2253F1FD53F43F75FA0075FC31754A
:0843F800F84043F338C20B2228
:20440000858283D0F0D0E0D082C082C0E0C0F022C00074FB2581F8E58286820886830886C1
:20442000F0D0002275F008C58213C58233D5F0F7C58222E583A2E713F583E58213F58222A5
:20444000D083D0E0D0F0C0F0C0E0C083E582A4F58285F08322C000E58124FDF8E6F8858246
:20446000F0A4F582E8A8F08583F0A428F583E5F03400F5F0E4D00022C000C001C0E0C0F0E0
:2044800074FA2581F88600E58288F0A4F582A9F0E58388F0A429F583E5F03400F9D0E08898
:2044A000F0A429C5F03400F9D0E0C0F088F0A429D0F0D001D00022C000C001C002E5812468
:2044C000FBF8E6F918E6F88582F0A4C0E0AAF0E58388F0A42AF8E5F03400FAE98582F0A412
:2044E00028C0E0E5F03AFA74003400F8E98583F0A42AFAE5F0388AF0D083D082D002D001D3
:20450000D00022D0E0D0F0C000C001C002C0F0C0E074F82581F9E7F809E7F922D002D0010E
:20452000D00022C9C583C9C8C582C82212450375F008124523E0A3124523F0A3D5F0F3022B
:20454000451C12450375F008124523E493A3124523F0A3D5F0F202451C124503C375F008EE
:20456000124523E0A3F502124523E03AF0A3D5F0EF02451C12450375F008124523E0A3F550
:2045800002124523E05AF0A3D5F0EF02451C124503C375F008124523E0A3F502124523E0E3
:2045A0009AF0A3D5F0EF02451C124503C375F008124523E0A3F502124523E0A39AD5F0F0ED
:2045C00002451C12450375F008124523E0A3F502124523E0A36A7007D5F0EED302451CC333
:2045E00002451CC8C0E075F008E038F0A3D5F0F9D00022D3E40245E3C374FF0245E3C00027
:20460000C00174FA2581F8E6F5F0088601496015088600E8F0A374FF25F0F5F074FF39F59E
:204620000145F070EED001D00022C000C001C00274F92581F9E7D3601CF5F0098700098799
:2046400001C3E0F502A3124523E0A31245236A7004D5F0EED3D002D001D00022C000C0012B
:20466000C00274F82581F9E7F5F00987024A601F098700098701124523E0A3124523F0A31B
:2046800074FF25F0F5F074FF3AF50245F070E7D002D001D00022C000C001C00274F9258192
:2046A000F9E76015F5F0098700098701124523E0A3124523F0A3D5F0F3D002D001D0002248
:2046C000C083C082E06003A380FAC3E582D0F095F0F582E583D0F095F0F58322C003C00243
:2046E000C001C000C0E0C0F0C083C082A98174F62581F886F0188600750201750300758237
:2047000011A2F74014C3E833F8E5F033F5F0C3EA33FAEB33FB058280E8E4C003C002C0E0ED
:20472000C0E0AA81C0F0C000C0E0C0E0A881C0E0C0E0C0E0C0E0AB81C000C001C3758304E9
:2047400086F018E71995F0D583F6D001D000402BC000C001C375830486F018E795F0F719A2
:20476000D583F585020085030175830486F018E745F0F719D583F5D001D00074FC28F8C3E5
:2047800075830408E613F6D583F9C00074FC2AF8C375830408E613F6D583F9D000D58298BD
:2047A00020D508D082D083D0F0D00074F42581F58130D508D082D083D0F0D000E8D000D079
:2047C00001D002D00322C2D50246DCD2D50246DCC003C002C001C000C0E0C0F0C083C082B0
:2047E000A98174F62581F886F07401758219A2F7400A23C5F023C5F0058280F2C0E0E4C0BC
:20480000E0C0E0C0E0AA81C0F0C0E0C0E0C0E0A881C0E0C0E0C0E0C0E0AB81C000C001C3A4
:2048200075830486F018E71995F0D583F6D001D000402BC000C001C375830486F018E795C5
:20484000F0F719D583F585020085030175830486F018E745F0F719D583F5D001D00074FCE7
:2048600028F8C375830408E613F6D583F9C00074FC2AF8C375830408E613F6D583F9D000E8
:20488000D58298D082D083D0F0D00074F42581F581E8D000D001D002D00322C006C005C0D5
:2048A00004C003C002C001C00074F72581F886F074017C09A2F7400923C5F023C5F00C8057
:2048C000F3FBE4FAA9F0F88582F0FDFEC3E58298E583994011C3E58298F582E58399F583C3
:2048E000EA4DFDEB4EFEC3E913F9E813F8C3EB13FBEA13FADCD620D5048D828E83D000D084
:2049000001D002D003D004D005D00622C2D502489BD2D502489BE0C0E02401F0A3E0C0E090
:204920003400F0A3E0D083D0826014B4600AC000A882E2D000F582224009E493F58222E02B
:20494000F58222C000A882E6D000F5822212450375F004D3124523E0FA3400F0EAA3124593
:2049600023F0A3D5F0EE02451C12450375F004C3124523E0FAA3124523E0A36A7004D5F04E
:20498000EFD302451C124503C3E0A398E0A399E0A39400E0A3940002451C124503C3E0A36D
:2049A00038E0A339E0A33400E0A3340002451C75F004E07004A3D5F0F9F58222A3A3A3E0B2
:0249C0003322A0
:0449C20075C90B2286
:2049C600C0E0C007C006C0D075D000AEDAAFDB74012EF5DAE43FF5DBD0D0D006D007D0E05B
:2049E60032C007C006C005C004C000AEDAAFDB784AEEF208EFF27848E5E2F27849E5E3F218
:204A0600EEB5DAE7EFB5DBE37848E2FC08E2FD08E2FE08E28C828D838EF0D000D004D0055E
:204A2600D006D0072285E28222E4F5DAF5DBF5E4F5E5F5E6F5E7F5E275E40543D84043B81E
:204A46000222AF82AE83ADF0FC784CEFF2EE08F2ED08F2EC08F21249E77850C0E0E582F2D4
:204A6600E58308F2E5F008F2D0E008F21249E7AA82AB83AEF0FF7850D3E29AF4B3FAB308A9
:204A8600E29BF4B3FBB308E29EF4B3FEB308E29FF4FF784CC3E29A08E29B08E29E08E29F49
:034AA60050CA22D1
:204AA90053C07F53A1FE53BEFC3243870122AF82AE83ADF0FC7854EFF2EE08F2ED08F2ECDA
:204AC90008F290FAA4E4F090FAA5F090FAA674DFF090FAA774BEF090FAA8E054E0F090FA2C
:204AE900A8E0541FF090FAA97407F090FAAAE054E0F090FAAAE0549F4420F090FAAAE05429
:204B09007FF090FAABE054FC4402F090FAABE054FBF090FAABE054F7F090FAABE054CFF0B6
:204B290090FAABE0543F4440F07854E2F5F008E242F008E242F008E245F0701B7B017513D7
:204B49006D7514FC85141590FAA4E515F07A6D90FAA5EAF0024BEB7854C3E2943F08E294AA
:204B69000008E2940008E29400500C7854743FF2E408F208F208F27854E225E0F51608E2E9
:204B890033F51708E233F51808E233F519E5162516F516E51733F517E51833F518E519338E
:204BA900F519747DC0E0E4C0E08516828517838518F0E5191247C67854C0E0E582F2E583B6
:204BC90008F2E5F008F2D0E008F2158115817B007D667EFC8E0590FAA4EDF07E6690FAA5A4
:204BE900EEF053C07F53A1FE43A11075A8A0EB70147854E2F5F008E242F008E242F008E275
:204C090045F070012253BEFBE5BE30E5FBE5C654384441F5C6E5C630E6FB43BE0453C67F34
:204C29007854C3E2F5F074F095F008E2F5F074FF95F008E2F5F0E495F008E2F5F0E495F0F5
:204C4900501B7DF07EFF7854E22410F208E23400F208E234FFF208E234FFF280117854E2B5
:204C6900FD08E2FE7854E4F208F208F208F2EB60067A007C0080047A107C008AA175C00085
:204C890043D6817AA47CFA8AD48CD575D60175A204E5A570FC75A2028EA48DA3AEA5EEB550
:204CA900A50280FA43C702EB60077B0075BE07800375BE06000000E5BE5403600875D7014C
:204CC900004387010053C7FDE5BE30E5FB75BE00E5BE30E5FB75C679E5BE30E6FB7E007DED
:1B4CE90000000DBD80FB0EBE80F575C639E5C620E6FB75C63875BE04024BF71C
:0E76AB0006060606060604070707070707047B
:204D0400AF8275BB0074304FF5B575B473E5B420E6FBE5B430E7FBAEBA7F00ADBB7C009055
:204D2400FAB0EC4EF0ED4FA3F08FB522C21690FAB0E0FEA3E08E82C4C582C4540F6582C505
:204D440082540FC5826582C582F58374E2C0E07404C0E01244B7AC82AD83AEF0FF158115BC
:204D64008190FAAEE0FAA3E0FB74FFC0E07407C0E08A828B831244B7A882A983AAF0FB15C9
:204D8400811581ECC398FCED99FDEE9AFEEF9BFF747DC0E08C828D838EF0EF124478AC820B
:204DA400AD83AEF0FF1581EFC40354F8CEC403CE6ECE54F8CE6EFFEDC40354074EFEEDC458
:204DC4000354F8CCC403CC6CCC54F8CC6CFDEF30E70FD216C3E49CFCE49DFDE49EFEE49FAB
:204DE400FF90FAACE0C0E0A3E0C0E08C828D838EF0EF1247C6AC82AD83AEF0FF1581158106
:204E040074FF2CFC74033DFDE43EFEE43FFF74FFC0E07407C0E08C828D838EF0EF1247C628
:164E2400AC821581158190FAB2ECF030160790FAB2C3E49CF02228
:204E3A00E58620E0FB225390FD00225380FB0022E58620E0FB004390020022E58620E0FB1B
:204E5A00004380040022C007C006AF82BF64004027BF6A00502290DF097421F090DF0A7482
:204E7A003BF090DF0B7413F08F06EE249CFE90DF0675F003A4F0802F90DF097422F090DF2E
:204E9A000A74BBF090DF0B7413F0BFC8004013BFE100500EEF2438FF90DF0675F00CA4F042
:204EBA00800590DF06E4F0D006D00722C00775E10490DF3BE0B401FCD00722124EC67F0041
:204EDA008F057EDFEFC3907573938D828E83F00FBF200040EB90DF237488F090DF2474312B
:204EFA00F090DF257409F090DF2E748EF075911075ED00759D0075EF0322C007AF82C3EF5B
:204F1A006480946250047FE2800EC3748A8FF063F08095F050027F0A741E2FC313907593B8
:204F3A009390DF2EF0D00722C007C006AE82AF838ED48FD575D6010000000000000000003D
:204F5A00D006D0072275D68100000000000000000022C007C006C005AE82AF83124F5F8F77
:204F7A000590FC76EDF090FC77EEF07E747FFC8E828F83124F42D005D006D00722C007C0F5
:204F9A0006C005AE82AF83124F5F8F0590FC7CEDF090FC7DEEF07E7C7FFC8E828F83124FB2
:204FBA0042D005D006D00722301704E5EF700122124EC653C0FE43B801E5ED75F080A4248D
:204FDA00B4F58274FA35F0F583124F6C75E1022253B8FE124F5F124EC675D10053C0FE22D2
:204FFA00AE82AF837CFF7DFF124FEA8E828F83124F9775E90075E103E5E920E42375820F27
:20501A00C005C004124D04D004D00590FAB0E0FEA3E0FFC3EE9CEF9D50DE8E048F0580D8C2
:20503A00124F5FC005C004124FC2D004D0057423C0E08C828D8312490C15817404C0E012C5
:20505A004455AC82AD83158190F0E7ECF0EDA3F022C025C0E0C0F0C082C083C007C006C0BD
:20507A0005C004C003C002C001C000C0D075D000E5D130E040E5ED75F080A424B4FE74FACD
:20509A0035F0FF53D1FE8E828F83E0FD248240200D0DED2EF582E43FF583E0FF30E711E578
:2050BA00ED04FF8FEDBF030375ED00E5EF14F5EF124FC2800F74A8C0E07475C0E0125AAC68
:2050DA001581158153C0FED0D0D000D001D002D003D004D005D006D007D083D082D0F0D008
:2050FA00E0D02532201906124FEAC21722201705D217024FC222E59D75F080A424B4FE745B
:20511A00FA35F0FF8E828F83E0FD7403B5EF047582FF228D037C0074022BF9E43CFAE92E4A
:20513A00F582EA3FF583E0FA747F5AD39494F4FABA7F0040047AFF8003EA2AFA90F0BFEA7D
:20515A00F00BBB00010CEB2EF582EC3FF583E0A2E71324B390F0C0F00EBE00010FC005C05B
:20517A0006C00790F95B124696158115811581E59D04FF8F9DBF0303759D00D21A10AF027F
:20519A00C21AE5EFFF04F5EFA21A92AFEF7007C005124FC2D0058D8222D21B10AF02C21B82
:1051BA00AFEF75EF03A21B92AFEF7003024FC2224B
:20757300D3917D044522000F0022BB131D3B1373A7650700181E1CC700B0B610EA2A001FFA
:20759300030506080B0E191C242527293855408D8A84CAC4C0646D612069727120756E651F
:0975B300787065637465640A00D8
:1076B900DFD900008080131A0000DFD9207E134231
:1700E10090FC457456F090FC467412F090FC4703F090FC487485F0B2
:2051CA00E58620E0FB225390FD00225380FB0022E58620E0FB004390020022E58620E0FB88
:2051EA00004380040022C007C006C005C004C003C002C001C000E582785BF27E00C21D789F
:20520A005CE4F2C006785CE2C0E0901000124455AA82AB831581785DEAF2EB08F2785F741A
:20522A0004F2E408F2785DE2FA08E2FBE4FCFE7404C0E0E4C0E07449C0E074FCC0E08A8207
:20524A008B838CF0EE1206D0E58124FCF5817404C0E07445C0E074FCC0E090FC4912462A10
:20526A00158115811581921ED006201E03025354785FE2FB08E2FCC394104003025354C045
:20528A0006785D795FE3C5F0E225F0FB09E3C5F008E235F0FAE4FCFE7402C0E0E4C0E07431
:2052AA0049C0E074FCC0E08B828A838CF0EE1206D0E58124FCF58190FC49E0F51A74FFB597
:2052CA001A05D006025354D006785BE2B51A5D90FC4AE0FCBC020040531C1C8C06785AC30D
:2052EA00E29C5004785AE2FCC0067B007858E2F51B08E2F51C785DE2FD08E2FF74022DFDE7
:20530A00E43FFF785FE22DFD08E23FFA7E007F00C004C003C01BC01C8D828A838EF0EF1285
:20532A0006D0E58124FCF581D21DD00690FC4AE0FF7D00785FE2FB08E2FCEF2BFBED3CFCC6
:20534A00785FEBF2EC08F202527A785CE22401F2785CE2B40A00500302520D301D048E0700
:20536A0080027FFF8F82D000D001D002D003D004D005D006D00722758204C007C006C00507
:20538A00C004C003C002C001C00012179E125402D000D001D002D003D004D005D006D0076E
:2053AA00301C26C007C006C005C004C003C002C001C0001216D8125402D000D001D002D0AA
:2053CA0003D004D005D006D007758204C007C006C005C004C003C002C001C0001217D775DE
:2053EA008200125C8AD000D001D002D003D004D005D006D007D2AF22D21C785874A2F274B0
:20540A00FD08F2785A7407F275822A1251F0E582FF30E71B785874A2F274FD08F2785A74B7
:20542A0006F27582011251F0E582FF30E701227404C0E0E4C0E0C0E090FDB21245FE158119
:20544A00158115817404C0E074B2C0E074FDC0E0906ACA12462A158115811581921F401D11
:20546A007404C0E074A4C0E074FDC0E0906ACA12462A158115811581921F40012290F95745
:20548A007444F090F9567467F090FDA4E0FF90F953F090FDA5E0FE90F952F090FDA6E09056
:2054AA00F951F090FDA7E090F950F090FDA4E4F07D007C00C006C005C007C00474A2C0E001
:2054CA0074FDC0E0E4C0E074BCC0E07475C0E0125AACE58124F7F58190F950E0FF7E0090FF
:2054EA00F951E0FD7C00C007C006C005C00474CAC0E07475C0E0125AACE58124FAF58190E0
:20550A00FDA2E024BF90F955F090FDA3E024BF90F954F090F956E0FF7E0090F957E0FD7C1C
:20552A0000C007C006C005C00474D4C0E07475C0E07434C0E074FCC0E0125B25E58124F86E
:20554A00F58190F954E0FF7E0090F955E0FD7C00C007C006C005C00474D4C0E07475C0E0D3
:20556A007438C0E074FCC0E0125B25E58124F8F58190F952E0FF7E0090F953E0FD7C00C00E
:20558A0007C006C005C00474D4C0E07475C0E0743CC0E074FCC0E0125B25E58124F8F58150
:2055AA0090F950E0FF7E0090F951E0FD7C00C007C006C005C00474D4C0E07475C0E074403D
:2055CA00C0E074FCC0E0125B25E58124F8F581785874ACF274FA08F2785A7402F2758212FA
:2055EA001251F0E58230E70122785874AEF274FA08F2785A7402F27582091251F0E582303D
:20560A00E70122C21C2290561B747CC39582F5F02275F020C2ADC2AC43AE0100E5AE20E7B6
:20562A00FB05AD05ADD5F0F09000008583AD8582ACA375AB2275F00275F900E5F830E1FBB1
:20564A0053F8FDE5F820E0FBC0F9D5F0EB43AE02E5AE20E6FBD0E0D0AFF5AFE5AE20E6FBC9
:20566A0053AEFDE5AE20E7FBE583B440BE75C90B80FEC007C006C005C004C003125610ACAF
:20568A0082AD83AEF0FF8E03C003C004C00590FDA212469615811581158175D6FF75A8008E
:2056AA0075C70390FDA2E473D003D004D005D006D00722C007C00675A80075B800759A00EA
:2056CA0075C70075BE00E5BE30E5FB75C679E5BE30E6FB7F007E00000EBE80FB0FBF80F5AF
:2056EA0075C639E5C620E6FB75C63875BE04D006D0072243B404E5B4540C600280F8E5BC98
:20570A0065BDF582221256FDC0821256FDC0821256FDC0821256FDD083D0F0D0E022C000C5
:0B572A008582BC7861E2F5BCD0002253
:2075BC00534E20257325303278253032780025303278253032780A00253032582530325892
:0175DC0000AE
:20573500E58620E0FB225390FD00225380FB0022E58620E0FB004390020022E58620E0FB17
:20575500004380040022C007C083C082858107C004C003C002C001C00074F42581F8868319
:2057750018868218860018E0A36013B4250B7C007A00E0A36008B42516125A3D80E9D000B2
:20579500D001D002D003D004D082D083D00722B4630518E61880E2FB4420B46D3AEB54205F
:2057B50003F9C083C0821259D97C0874FF2C93C083C082FAC47B02540F29905A6C93125AB8
:2057D5003DEADBF3D082D083DC06D082D0838097743A125A3D80D4EBB42A09BA009B740135
:2057F5004CFC808EB43007BA0004740680F2FB24D0501224F6400E240AFB740A8AF0A42B00
:20581500FA740480DBBB6C0DEC54086004741080CF740880CBBB733CEC5408C083C0827085
:20583500051259E080031259D9EC54047009E0A36098125A3D80F7BA0002808EE0A3600A2D
:20585500125A3DDAF7808302592D7420125A3DDAF90257DFEB4420B478EDC083C08212598E
:20587500F6C083C082E5F023F90324FF2582F582E5833400F583E054F0701119E0700D191B
:205895001582E582B4FF021583D5F0EAB9000109EC5420600B09EC54026005742D125A3D71
:2058B500EC54046018EAC39940136011FAEC5402C4032420F582E582125A3DDAF9EC54200C
:2058D500600B19EC54027005742D125A3DEB542003FAD082D083E904C313FC142582F5823C
:2058F500E5833400F583E954016005E079018005E07902FBC4540F2AC083C082905A6C93E8
:20591500D082D083125A3DEBD9EB1582E582B4FF021583DCDB0257DFBB640674204CFC80BA
:2059350008BB7502800302577CC083C0821259F6C0F07408C395F0244DF9E434FCFBE0A36A
:20595500125A32F0A3125A32D5F0F3125A32F5F0EC54206028E5F054807006EC54DFFC8086
:205975001CD0F0C0F07408C395F0244DF582E434FCF583C3E0F9E499F0A3D5F0F775F00A77
:20599500E4F0A3D5F0FBD0E0C403FB90FC5575F00AE0F9540F24FBE950022403F954F024DB
:2059B500B0E950022430F0A3D5F0E690FC4DC375F012E033F0A3D5F0F9DBD090FC5575F0ED
:2059D5000A02587686831886821822E61860F5648060F164C0600585938380EA7583FF80E8
:2059F500E5EC5401701F88F07583FFEC5418600A5410600418181818181818888218E5F045
:205A1500C398F5F022EC5418600E5410600575F00880B175F00480AC75F00280A7C583CBAC
:205A3500C583C582C9C58222C083C082C001C0008F0086821886831818181886011886004D
:205A5500125A61D000D001D082D08322C082C0838500828501832230313233343536373871
:205A75003941424344454630313233343536373839616263646566C007C006C005C004FFCC
:205A9500BF0A0675820D1243C28F821243C2D004D005D006D00722C007C001C000A20B92E0
:205AB50020E58124FAFF200B031243D6C007E58124F9F8E6C0E008E6C0E0E4C0E0C0E090CB
:205AD5005A8C12575BE58124FBF5812020031243EBD000D001D00722C007C006C005C004D9
:205AF500C003C001AC82FF8C018F0487060987071974012EFBE43FFDA70309A7058E828FC7
:205B150083ECF0D001D003D004D005D006D00722C007C006C005C001C000E58124F6FFE5BE
:205B35008124F8FE7D00C007E58124F5F8E6C0E008E6C0E0C006C005905AED12575BE5815A
:195B550024FBF58124F8F88682088683E4F0D000D001D005D006D007225C
:0200F800C22123
:205B6E00E58620E0FB225390FD00225380FB0022E58620E0FB004390020022E58620E0FBDA
:205B8E00004380040022C007AF82E58620E0FB53807F008F82125D1100E58620E0FB4380A4
:205BAE0080D0072253BEFC32AE82AF838E828F83E493FD74012EFBE43FFCEDFA60525390EE
:205BCE00FD008B828C83E493FD0BBB00010CE58620E0FB53807F008D82125D1100E5862085
:205BEE00E0FB438080EA14FDED6015E58620E0FB8B828C83E493F5C1A3AB82AC831D80E8E9
:205C0E008B068C07E58620E0FB0043900200809C2230210122D221758201125C8A439002AD
:205C2E005380BF43F42875C20075C5317586009000FDE4F5F0124A484390049000FDE4F591
:205C4E00F0124A482090FD9075DD125BB65390FD00E58620E0FB53807F00758204125D11DD
:205C6E0000E58620E0FB4380803090FDE58620E0FB00439002009075E9025BB6E582601697
:205C8E0090F953E054F0600122438FC143FDC143F62E43FE2E2253F4D790F953E0FF54F0CA
:205CAE00600B53807E5390D100D2860022538F3A53FD3A53F6D153FED1222021012290767E
:205CCE0075125BB6758200125C8AC22122125C1F5390FD003022067E137F0080047E107FC4
:205CEE0000E58620E0FB53807F008E82125D1100E58620E0FB438080E58620E0FB0043906C
:205D0E00020022C007AF82E58620E0FB8FC1D007227EFF7FFF7482C0E07476C0E0125AAC77
:205D2E001581158190767FC007C006125BB6D006D00720902F900032E4F5F0C007C006123E
:205D4E004AB71256BD75820F124D04D006D00790FAB0E0FCA3E0FDC3EC9EED9F50D48C06D4
:205D6E008D0780CE7423C0E08E828F8312490C15817404C0E0124455AC82AD83158190F0A6
:205D8E00E9ECF0EDA3F075820112179E125CC812197C7494C0E07476C0E0125AAC1581151F
:025DAE00812250
:2075DD00050107000900040607070F0002008F0461800128023029025017028208026022DE
:2075FD00102001010103040906060A040419030409102101010103840986460A8444190366
:20761D004409102201010143040986460A84441983040910250A0A0102140D14140100009E
:20763D000000000010264A4A0182540D54540100000000000010270A0A0102140D1414013E
:20765D00000000000000102401810183840986460A844419030409000282000501020000F3
:20767D0000000112005570646174696E6720646973706C61790A0055706461746520636F29
:08769D006D706C6574650A0054
:205DB000AE82AF837C007D007B10EF235401FAEE2EFEEF33FFEC2CFCED33FDEA600343048C
:205DD000017862C3E2F5F0EC95F008E2F5F0ED95F040117862D3E29CF4B3FCB308E29DF44F
:0B5DF000FD430601DBC48E828F83227E
:205DFB00AC82AD83AEF0FF33E433FB6013C3E49CF55AE49DF55BE49EF55CE49FF55D800842
:205E1B008C5A8D5B8E5C8F5DAC5AAD5BAE5CAF5D7867E233E433FA60207864E2D3F4340061
:205E3B00F55A08E2F43400F55B08E2F43400F55C08E2F43400F55D80117864E2F55A08E247
:205E5B00F55B08E2F55C08E2F55D786CE55AF2E55B08F2E55C08F2E55D08F28C828D838EEE
:205E7B00F0EFC003C002125ECF7868C0E0E582F2E58308F2E5F008F2D0E008F2D002D0030B
:205E9B00EA6B60207868E2D3F43400FA08E2F43400FB08E2F43400FE08E2F434008A828B95
:145EBB00838EF0227868E2F58208E2F58308E2F5F008E2223A
:205ECF00AF82AE83ADF0FC7870EFF2EE08F2ED08F2EC08F27A007B007E007F007D207873C0
:205EEF00E2235401FC7870E225E0F208E233F208E233F208E233F2EA2AFAEB33FBEE33FE09
:205F0F00EF33FFEC6003430201786CC3E2F5F0EA95F008E2F5F0EB95F008E2F5F0EE95F05E
:205F2F0008E2F5F0EF95F04022786CD3E29AF4B3FAB308E29BF4B3FBB308E29EF4B3FEB36C
:1D5F4F0008E29FF4FF7870E24401F2DD917870E2F58208E2F58308E2F5F008E222CC
:0600B200E478FFF6D8FD22
:200090007924E94400601B7A019076A578607593FCE493F2A308B800020593D9F4DAF27595
:0200B00093FFBC
:1B5F6C0020F71130F6138883A88220F509F6A8837583002280FEF280F5F02234
:205F8700AA83AB828BF090F075E0A4F8A9F08AF0E0A429F98BF0A3E0A429F583888222226A
:205FA700AF82AE83ADF0FC787BEFF2EE08F2ED08F2EC08F2787BE2FF7879E28FF0A4FFADE0
:205FC700F07881EFF208EDF2787BE2FF7877E28FF0A4FFADF0787FEFF208EDF27882E2FF0B
:205FE700787EE2FE7877E28EF0A42FFF7882F2787DE2FE7878E28EF0A42F7882F27881E2F8
:20600700FE08E2FF787DE2FD7877E28DF0A4ABF02EFEEB3FFF7881EEF208EFF2787CE2FD47
:206027007878E28DF0A4ABF02EFEEB3FFF7881EEF208EFF2787CE2FF7879E28FF0A4787EF3
:20604700F2787CE2FF7877E28FF0A4FFADF0787CEFF208EDF2787BE2FF787AE28FF0A478E3
:206067007AF2787BE2FF7878E28FF0A4FFADF07878EFF208EDF27877E4F2787BF2787FE20D
:20608700F55E08E2F55F08E2F56008E2F561787BE2FA08E2FB08E2FE08E2FFEA255EF55EA4
:2060A700EB355FF55FEE3560F560EF3561F561787FE55EF208E55FF208E560F208E561F26A
:2060C700787FE208E208E208E27877E2FC08E2FD08E2FE08E2FFEC255EFCED355FFDEE3591
:0C60E70060FEEF35618C828D838EF0220C
:2060F300AE82AF837D007C007884E2235401FB70357883E225E0F208E233F27883C3E2F5C4
:20611300F0EE95F008E2F5F0EF95F050147883E2F5F008E2C313C5F01318F2C5F008F280DF
:20613300050C8C0580C27883C3E2F5F0EE95F008E2F5F0EF95F0400E7883D3E29EF4B3FEEC
:20615300B308E29FF4FF7883E2F5F008E2C313C5F01318F2C5F008F28D041DEC70C88E8218
:036173008F8322F5
:20617600AD82AE83AFF07888E2F5F008E245F07004900000227888E2FB08E2FC1BBBFF0165
:206196001CEB4C6069C003C0048D5E8E5F8F60855E82855F838560F01262F5FA7885E2F5A7
:2061B6006108E2F56208E2F5638561828562838563F01262F5FCEAB504028006D004D00304
:2061D600802C7401255EFAE4355FFBAC608A058B068C0774012561FAE43562FBAC63788562
:2061F600EAF2EB08F2EC08F2D004D003808E8D828E838FF01262F5FD7F007885E2FB08E2E5
:1A621600FC08E2FE8B828C838EF01262F5FB7E00EDC39BF582EF9EF5832225
:20623000AE82E583FF33E433FD6009C3E49EFBE49FFC80048E038F04788BE233E433FF6012
:2062500010788AE2D3F43400FA08E2F43400FE8007788AE2FA08E2FE7862EAF2EE08F28BBF
:20627000828C83C007C005125DB0AC82AE83D005D007EF6D600AC3E49CF582E49EF583222B
:056290008C828E8322C8
:2000B800788CE84400600A79007593F0E4F309D8FC78D4E8440B600C790C90F08CE4F0A372
:0400D800D8FCD9FA7D
:0F008100E473758168126311E582600302007EEB
:20629500758911758800758B00758D0020B0FD20B0FA20B0F720B0F420B0F130B0FDD28EBB
:2062B50020B0FD30B0FD20B0FD30B0FDC28EE58D25E0FFE58B2354014FF58DE58D25E0FF80
:2062D500E58B232354014FF58DE58DF4F58DE58D04F58D858D8B7589217587807598522234
:1C62F50020F71430F6148883A88220F507E6A88375830022E280F7E49322E022B8
:04631100758200226F
:00000001FF

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@@ -123,12 +123,15 @@
"80": { "80": {
"type": "chroma74y_ota", "type": "chroma74y_ota",
"version": "0010", "version": "0010",
"md5": "4baff1e9eba6949c26ea11dbbd105039" "md5": "4baff1e9eba6949c26ea11dbbd105039",
"type_1": "chroma74r_ota",
"version_1": "0014",
"md5_1": "3c69d4414a1447b071f0628529a3e3c7"
}, },
"82": { "82": {
"type": "chroma29_ota", "type": "chroma29_ota",
"version": "0010", "version": "0015",
"md5": "0d4af3e5285ca20ac56926e6fdd71dbc", "md5": "293bb70fc5d8c6e2174cbb9b76943e4b",
"type_1": "chroma29_8151_ota", "type_1": "chroma29_8151_ota",
"version_1": "0013", "version_1": "0013",
"md5_1": "b3dffd044829449998edc1c91d537004" "md5_1": "b3dffd044829449998edc1c91d537004"

View File

@@ -1,6 +1,6 @@
# Google Calendar # Google Calendar
To use the 'clandar' content type, you need a helper script, using Google Apps Script. To use Google Apps Script to get all events for the next day and return them via JSON in a web app, you can follow these steps: To use the 'calendar' content type, you need a helper script, using Google Apps Script. To use Google Apps Script to get all events for the next day and return them via JSON in a web app, you can follow these steps:
* Create a new Google Apps Script project by going to [https://script.google.com](https://script.google.com) and clicking on "New project". * Create a new Google Apps Script project by going to [https://script.google.com](https://script.google.com) and clicking on "New project".
* Paste the content of the calendar.js file into the editor * Paste the content of the calendar.js file into the editor

View File

@@ -133,6 +133,9 @@
#define DATATYPE_TAG_CONFIG_DATA 0xA8 // Config data for tag #define DATATYPE_TAG_CONFIG_DATA 0xA8 // Config data for tag
#define DATATYPE_COMMAND_DATA 0xAF // Command for the tag to execute (contained in availableData Reply) #define DATATYPE_COMMAND_DATA 0xAF // Command for the tag to execute (contained in availableData Reply)
#define DATATYPE_CUSTOM_LUT_OTA 0xB0 // Custom OTA updated LUT #define DATATYPE_CUSTOM_LUT_OTA 0xB0 // Custom OTA updated LUT
#define DATATYPE_TIME_RAW_DATA 0xC0 // Used for showning the time and preparation for more data
#define DATATYPE_CONFIG_DATA_TEST 0xC1 // Used to receive Display configurations to test
#define DATATYPE_CONFIG_DATA_SAVE 0xC2 // Used to receive Display configurations to save in flash an reboot
#define CMD_DO_REBOOT 0 #define CMD_DO_REBOOT 0
#define CMD_DO_SCAN 1 #define CMD_DO_SCAN 1

View File

@@ -12,7 +12,7 @@
}, },
"g5_compression": "29", "g5_compression": "29",
"shortlut": 2, "shortlut": 2,
"options": [ "button", "customlut" ], "options": [ "button" ],
"contentids": [ 22, 23, 1, 2, 3, 4, 5, 7, 10, 14, 17, 18, 19, 20, 21, 27 ], "contentids": [ 22, 23, 1, 2, 3, 4, 5, 7, 10, 14, 17, 18, 19, 20, 21, 27 ],
"template": { "template": {
"1": { "1": {

View File

@@ -1,5 +1,5 @@
{ {
"version": 4, "version": 5,
"name": "M2 2.9\"", "name": "M2 2.9\"",
"width": 296, "width": 296,
"height": 128, "height": 128,
@@ -12,7 +12,7 @@
}, },
"g5_compression": "29", "g5_compression": "29",
"shortlut": 2, "shortlut": 2,
"options": [ "button", "customlut" ], "options": [ "button" ],
"contentids": [ 22, 23, 1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 16, 17, 18, 19, 20, 21, 27 ], "contentids": [ 22, 23, 1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 16, 17, 18, 19, 20, 21, 27 ],
"template": { "template": {
"1": { "1": {
@@ -43,7 +43,8 @@
"day": [ 30, 18, "fonts/twcondensed20", 41, 108 ], "day": [ 30, 18, "fonts/twcondensed20", 41, 108 ],
"icon": [ 30, 55, 30 ], "icon": [ 30, 55, 30 ],
"wind": [ 18, 26 ], "wind": [ 18, 26 ],
"line": [ 20, 128 ] "line": [ 20, 128 ],
"ts_option": 10
}, },
"9": { "9": {
"title": [ 2, 0, "bahnschrift20.vlw", 25 ], "title": [ 2, 0, "bahnschrift20.vlw", 25 ],

View File

@@ -12,7 +12,7 @@
}, },
"g5_compression": "29", "g5_compression": "29",
"shortlut": 2, "shortlut": 2,
"options": [ "button", "customlut" ], "options": [ "button" ],
"contentids": [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 14, 16, 17, 19, 20, 21, 22, 23, 27 ], "contentids": [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 14, 16, 17, 19, 20, 21, 22, 23, 27 ],
"template": { "template": {
"1": { "1": {

View File

@@ -12,7 +12,7 @@
}, },
"g5_compression": "29", "g5_compression": "29",
"shortlut": 2, "shortlut": 2,
"options": [ "button", "customlut" ], "options": [ "button" ],
"contentids": [ 22, 23, 1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 16, 17, 18, 19, 20, 21, 27 ], "contentids": [ 22, 23, 1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 16, 17, 18, 19, 20, 21, 27 ],
"template": { "template": {
"1": { "1": {

View File

@@ -11,7 +11,7 @@
}, },
"highlight_color": 5, "highlight_color": 5,
"shortlut": 0, "shortlut": 0,
"options": [ "button", "customlut" ], "options": [ "button" ],
"contentids": [ 22, 23, 1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 16, 17, 18, 19, 20, 21 ], "contentids": [ 22, 23, 1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 16, 17, 18, 19, 20, 21 ],
"usetemplate": 1 "usetemplate": 1
} }

View File

@@ -12,7 +12,7 @@
"g5_compression": "29", "g5_compression": "29",
"highlight_color": 5, "highlight_color": 5,
"shortlut": 0, "shortlut": 0,
"options": [ "button", "customlut" ], "options": [ "button" ],
"contentids": [ 22, 23, 1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 16, 17, 18, 19, 20, 21 ], "contentids": [ 22, 23, 1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 16, 17, 18, 19, 20, 21 ],
"usetemplate": 1 "usetemplate": 1
} }

View File

@@ -0,0 +1,25 @@
{
"version": 2,
"name": "M3 1.6\" BWRY",
"width": 168,
"height": 168,
"rotatebuffer": 0,
"bpp": 2,
"colortable": {
"white": [ 255, 255, 255 ],
"black": [ 0, 0, 0 ],
"red": [ 255, 0, 0 ],
"yellow": [ 255, 255, 0 ]
},
"perceptual": {
"white": [ 255, 255, 255 ],
"black": [ 0, 0, 0 ],
"red": [ 255, 0, 0 ],
"yellow": [ 255, 255, 0 ]
},
"shortlut": 2,
"zlib_compression": "27",
"options": [ "led" ],
"contentids": [ 22, 23, 1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 14, 16, 17, 18, 19, 20, 21, 27 ],
"usetemplate": 0
}

View File

@@ -0,0 +1,24 @@
{
"version": 1,
"name": "M3 2.4\" BWRY",
"width": 296,
"height": 168,
"rotatebuffer": 3,
"bpp": 2,
"colortable": {
"white": [ 255, 255, 255 ],
"black": [ 0, 0, 0 ],
"red": [ 255, 0, 0 ],
"yellow": [ 255, 255, 0 ]
},
"perceptual": {
"white": [ 255, 255, 255 ],
"black": [ 0, 0, 0 ],
"yellow": [ 200, 200, 0 ]
},
"shortlut": 2,
"zlib_compression": "27",
"options": [ "led" ],
"contentids": [ 22, 23, 1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 14, 16, 17, 18, 19, 20, 21, 27 ],
"usetemplate": 1
}

View File

@@ -0,0 +1,24 @@
{
"version": 1,
"name": "M3 3.0\" BWRY",
"width": 400,
"height": 168,
"rotatebuffer": 3,
"bpp": 2,
"colortable": {
"white": [ 255, 255, 255 ],
"black": [ 0, 0, 0 ],
"red": [ 255, 0, 0 ],
"yellow": [ 255, 255, 0 ]
},
"perceptual": {
"white": [ 255, 255, 255 ],
"black": [ 0, 0, 0 ],
"yellow": [ 200, 200, 0 ]
},
"shortlut": 2,
"zlib_compression": "27",
"options": [ "led" ],
"contentids": [ 22, 23, 1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 14, 16, 17, 18, 19, 20, 21, 27 ],
"usetemplate": 1
}

View File

@@ -0,0 +1,25 @@
{
"version": 1,
"name": "M3 2.9\" BWRY",
"width": 384,
"height": 168,
"rotatebuffer": 3,
"bpp": 2,
"colortable": {
"white": [ 255, 255, 255 ],
"black": [ 0, 0, 0 ],
"red": [ 255, 0, 0 ],
"yellow": [ 255, 255, 0 ]
},
"perceptual": {
"white": [ 255, 255, 255 ],
"black": [ 0, 0, 0 ],
"red": [ 255, 0, 0 ],
"yellow": [ 200, 200, 0 ]
},
"shortlut": 0,
"zlib_compression": "27",
"options": [ "led" ],
"contentids": [ 22, 23, 1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 14, 16, 17, 18, 19, 20, 21, 27 ],
"usetemplate": 51
}

View File

@@ -0,0 +1,25 @@
{
"version": 1,
"name": "M3 4.3\" BWRY",
"width": 522,
"height": 152,
"rotatebuffer": 3,
"bpp": 2,
"colortable": {
"white": [ 255, 255, 255 ],
"black": [ 0, 0, 0 ],
"red": [ 255, 0, 0 ],
"yellow": [ 255, 255, 0 ]
},
"perceptual": {
"white": [ 255, 255, 255 ],
"black": [ 0, 0, 0 ],
"red": [ 255, 0, 0 ],
"yellow": [ 200, 200, 0 ]
},
"shortlut": 0,
"zlib_compression": "27",
"options": [ "led" ],
"contentids": [ 22, 23, 1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 14, 16, 17, 18, 19, 20, 21, 27 ],
"usetemplate": 47
}

View File

@@ -12,7 +12,7 @@
}, },
"shortlut": 0, "shortlut": 0,
"zlib_compression": "27", "zlib_compression": "27",
"options": [ "button" ], "options": [ "button", "led" ],
"contentids": [ 22, 23, 1, 2, 3, 4, 5, 7, 8, 9, 11, 17, 18, 19, 20, 27 ], "contentids": [ 22, 23, 1, 2, 3, 4, 5, 7, 8, 9, 11, 17, 18, 19, 20, 27 ],
"usetemplate": 4, "usetemplate": 4,
"template": { "template": {

View File

@@ -1,5 +1,5 @@
{ {
"version": 4, "version": 5,
"name": "M3 7.5\"", "name": "M3 7.5\"",
"width": 800, "width": 800,
"height": 480, "height": 480,
@@ -21,12 +21,12 @@
"day": [ 400, 70, "Signika-SB.ttf", 280 ] "day": [ 400, 70, "Signika-SB.ttf", 280 ]
}, },
"4": { "4": {
"location": [ 20, 20, "fonts/calibrib30" ], "location": [ 20, 20, "fonts/calibrib50" ],
"wind": [ 90, 83, "fonts/calibrib30" ], "icon": [ 580, 20, 200, 2 ],
"temp": [ 20, 170, "fonts/calibrib30" ], "temp": [ 40, 180, "fonts/calibrib120" ],
"icon": [ 385, 0, 100, 2 ], "wind": [ 40, 370, "fonts/calibrib40" ],
"dir": [ 40, 50, 80 ], "dir": [ 250, 360, 80 ],
"umbrella": [ 325, 155, 78 ] "umbrella": [ 400, 360, 80 ]
}, },
"8": { "8": {
"location": [ 10, 0, "fonts/calibrib50" ], "location": [ 10, 0, "fonts/calibrib50" ],

View File

@@ -1,5 +1,5 @@
{ {
"version": 1, "version": 3,
"name": "M3 11.6\"", "name": "M3 11.6\"",
"width": 960, "width": 960,
"height": 640, "height": 640,
@@ -14,12 +14,26 @@
"zlib_compression": "27", "zlib_compression": "27",
"options": [ "button" ], "options": [ "button" ],
"contentids": [ 22, 23, 1, 5, 8, 9, 7, 19, 10, 11 ], "contentids": [ 22, 23, 1, 5, 8, 9, 7, 19, 10, 11 ],
"usetemplate": 1,
"template": { "template": {
"1": { "1": {
"weekday": [ 480, -5, "Signika-SB.ttf", 160 ], "weekday": [ 480, -5, "Signika-SB.ttf", 160 ],
"month": [ 480, 480, "Signika-SB.ttf", 160 ], "month": [ 480, 440, "Signika-SB.ttf", 160 ],
"day": [ 480, 110, "Signika-SB.ttf", 380 ] "day": [ 480, 85, "Signika-SB.ttf", 380 ]
},
"8": {
"location": [ 25, 0, "fonts/calibrib60" ],
"column": [ 7, 137 ],
"day": [ 68, 245, "fonts/calibrib42", 325, 540 ],
"rain": [ 72, 585 ],
"icon": [ 67, 390, 90 ],
"wind": [ 45, 290 ],
"line": [ 240, 672 ],
"currentwind": [ 670, 130, "fonts/calibrib60" ],
"temp": [ 25, 45, "fonts/calibrib150", 1 ],
"currenticon": [ 900, 0, 160, 2 ],
"dir": [ 600, 100, 90 ],
"umbrella": [ 630, 50, 60 ]
}, },
"9": { "9": {
"title": [ 6, 0, "Signika-SB.ttf", 32 ], "title": [ 6, 0, "Signika-SB.ttf", 32 ],
@@ -35,7 +49,7 @@
"rotate": 0, "rotate": 0,
"mode": 1, "mode": 1,
"days": 7, "days": 7,
"gridparam": [ 7, 19, 30, "calibrib16.vlw", "REFSAN12.vlw", 16 ] "gridparam": [ 3, 25, 40, "fonts/calibrib30", "REFSAN12.vlw", 16 ]
} }
} }
} }

View File

@@ -1,5 +1,5 @@
{ {
"version": 2, "version": 3,
"name": "M3 2.2 Lite\"", "name": "M3 2.2 Lite\"",
"width": 250, "width": 250,
"height": 128, "height": 128,
@@ -17,7 +17,7 @@
"template": { "template": {
"1": { "1": {
"weekday": [ 128, 3, "Signika-SB.ttf", 50 ], "weekday": [ 128, 3, "Signika-SB.ttf", 40 ],
"date": [ 128, 62, "Signika-SB.ttf", 40 ] "date": [ 128, 62, "Signika-SB.ttf", 40 ]
}, },
"2": { "2": {

View File

@@ -1,83 +1,91 @@
{ {
"version": 1, "version": 4,
"name": "M3 2.7\"", "name": "M3 2.7\"",
"width": 300, "width": 300,
"height": 200, "height": 200,
"rotatebuffer": 1, "rotatebuffer": 3,
"bpp": 2, "bpp": 2,
"colortable": { "colortable": {
"white": [ 255, 255, 255 ], "white": [ 255, 255, 255 ],
"black": [ 0, 0, 0 ], "black": [ 0, 0, 0 ],
"red": [ 255, 0, 0 ] "red": [ 255, 0, 0 ]
}, },
"g5_compression": "29", "zlib_compression": "27",
"shortlut": 0, "shortlut": 0,
"options": [ "button" ], "options": [ "button" ],
"contentids": [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 14, 16, 17, 19, 20, 21, 22, 23, 27 ], "contentids": [ 22, 23, 1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 17, 18, 19, 20, 21, 27 ],
"template": { "template": {
"1": { "1": {
"weekday": [ 106, 5, "fonts/calibrib40", 40 ], "weekday": [ 150, -5, "Signika-SB.ttf", 60 ],
"date": [ 106, 55, "fonts/calibrib30", 30 ] "day": [ 150, 37, "Signika-SB.ttf", 100 ],
"month": [ 150, 125, "Signika-SB.ttf", 60 ],
"altweekday": [ 150, -5, "Signika-SB.ttf", 60 ],
"altdate": [ 150, 65, "Signika-SB.ttf", 54 ],
"moonicon": [ 150, 115, 62 ],
"sunrise": [ 50, 140, "Signika-SB.ttf", 28 ],
"sunset": [ 220, 140, "Signika-SB.ttf", 28 ]
}, },
"2": { "2": {
"fonts": [ "Signika-SB.ttf", 135, 135, 100, 90, 70, 50 ], "fonts": [ "Signika-SB.ttf", 200, 200, 170, 120, 100, 80 ],
"xy": [ 106, 44 ] "xy": [ 150, 85 ]
},
"16": {
"location": [ 4, 10, "glasstown_nbp_tf" ],
"title": [ 165, 10, "glasstown_nbp_tf" ],
"cols": [ 4, 101, 8, "glasstown_nbp_tf" ],
"bars": [ 5, 90, 6 ]
}, },
"4": { "4": {
"location": [ 5, 3, "fonts/calibrib16.vlw" ], "location": [ 5, 15, "fonts/bahnschrift30" ],
"wind": [ 190, 5, "fonts/bahnschrift30" ], "wind": [ 280, 15, "fonts/bahnschrift30" ],
"temp": [ 5, 30, "fonts/calibrib70" ], "temp": [ 5, 96, "fonts/calibrib90" ],
"icon": [ 190, 25, 50, 2 ], "icon": [ 280, 65, 80, 2 ],
"dir": [ 165, -12, 40 ], "dir": [ 235, -2, 40 ],
"umbrella": [ 175, -50, 25 ] "umbrella": [ 190, -30, 25 ]
}, },
"8": { "8": {
"location": [ 5, 12, "t0_14b_tf" ], "location": [ 5, 10, "calibrib16.vlw" ],
"column": [ 4, 53 ], "column": [ 5, 60 ],
"day": [ 28, 18, "fonts/twcondensed20", 38, 88 ], "day": [ 30, 70, "bahnschrift20.vlw", 91, 155 ],
"icon": [ 28, 48, 25 ], "rain": [ 34, 176 ],
"wind": [ 18, 24 ], "icon": [ 30, 106, 30 ],
"line": [ 20, 100 ] "wind": [ 18, 76 ],
"line": [ 70, 200 ],
"currentwind": [ 195, 35, "fonts/calibrib24" ],
"temp": [ 5, 11, "fonts/calibrib50", 1 ],
"currenticon": [ 290, -3, 45, 2 ],
"dir": [ 207, 25, 36 ],
"umbrella": [ 200, 5, 25 ]
}, },
"9": { "9": {
"title": [ 3, 2, "fonts/calibrib16", 25 ], "title": [ 3, 2, "bahnschrift20.vlw", 25 ],
"items": 4, "items": 8,
"line": [ 3, 20, "tahoma9.vlw" ], "line": [ 3, 25, "REFSAN12.vlw" ],
"desc": [ 0, 5, "", 1 ] "desc": [ 0, 5, "", 1 ]
}, },
"10": { "10": {
"title": [ 106, 2, "calibrib16.vlw" ], "title": [ 150, 5, "fonts/bahnschrift20" ],
"pos": [ 106, 16 ] "pos": [ 150, 27 ]
}, },
"11": { "11": {
"mode": 0, "mode": 0,
"days": 1, "days": 1,
"title": [ 5, 2, "fonts/calibrib16.vlw" ], "title": [ 5, 2, "fonts/bahnschrift20" ],
"date": [ 205, 2 ], "date": [ 290, 2 ],
"items": 8, "items": 12,
"red": [ 0, 21, 211, 10 ], "red": [ 0, 21, 296, 14 ],
"line": [ 5, 21, 11, "tahoma9.vlw", 50 ] "line": [ 5, 32, 15, "t0_14b_tf", 50 ]
}, },
"21": [ "21": [
{ "text": [ 10, 5, "OpenEpaperLink AP", "bahnschrift20", 1, 0, 0 ] }, { "text": [ 5, 5, "OpenEpaperLink AP", "bahnschrift20", 1, 0, 0 ] },
{ "text": [ 10, 50, "IP address:", "t0_14b_tf", 1, 0, 0 ] }, { "text": [ 5, 50, "IP address:", "t0_14b_tf", 1, 0, 0 ] },
{ "text": [ 100, 50, "{ap_ip}", "t0_14b_tf", 1, 0, 0 ] }, { "text": [ 120, 50, "{ap_ip}", "t0_14b_tf", 1, 0, 0 ] },
{ "text": [ 10, 70, "Channel:", "t0_14b_tf", 1, 0, 0 ] }, { "text": [ 5, 70, "Channel:", "t0_14b_tf", 1, 0, 0 ] },
{ "text": [ 100, 70, "{ap_ch}", "t0_14b_tf", 1, 0, 0 ] }, { "text": [ 120, 70, "{ap_ch}", "t0_14b_tf", 1, 0, 0 ] },
{ "text": [ 10, 90, "Tag count:", "t0_14b_tf", 1, 0, 0 ] }, { "text": [ 5, 90, "Tag count:", "t0_14b_tf", 1, 0, 0 ] },
{ "text": [ 100, 90, "{ap_tagcount}", "t0_14b_tf", 1, 0, 0 ] } { "text": [ 120, 90, "{ap_tagcount}", "t0_14b_tf", 1, 0, 0 ] }
], ],
"27": { "27": {
"bars": [ 20, 180, 65, 12, 10 ], "bars": [ 12, 288, 130, 23, 20 ],
"time": [ "tahoma9.vlw" ], "time": [ "tahoma9.vlw" ],
"yaxis": [ "tahoma9.vlw", 2, 6 ], "yaxis": [ "tahoma9.vlw", 0, 6 ],
"head": [ "fonts/calibrib16.vlw" ] "head": [ "calibrib30.vlw" ]
} }
} }
} }

View File

@@ -0,0 +1,83 @@
{
"version": 2,
"name": "M3 5.81\" V2 BWR",
"width": 720,
"height": 256,
"rotatebuffer": 0,
"bpp": 2,
"colortable": {
"white": [ 255, 255, 255 ],
"black": [ 0, 0, 0 ],
"red": [ 255, 0, 0 ]
},
"shortlut": 0,
"zlib_compression": "27",
"options": [ ],
"contentids": [ 22, 23, 1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 16, 17, 18, 19, 20, 21, 27 ],
"template": {
"1": {
"weekday": [ 148, -3, "Signika-SB.ttf", 60 ],
"date": [ 148, 65, "Signika-SB.ttf", 48 ]
},
"2": {
"fonts": [ "Signika-SB.ttf", 150, 150, 150, 120, 100, 80 ],
"xy": [ 148, 53 ]
},
"16": {
"location": [ 5, 5, "fonts/bahnschrift30" ],
"title": [ 247, 11, "glasstown_nbp_tf" ],
"cols": [ 1, 125, 12, "glasstown_nbp_tf" ],
"bars": [ 5, 111, 10 ]
},
"4": {
"location": [ 5, 5, "fonts/bahnschrift30" ],
"wind": [ 280, 5, "fonts/bahnschrift30" ],
"temp": [ 5, 65, "fonts/bahnschrift70" ],
"icon": [ 285, 20, 70, 2 ],
"dir": [ 235, -12, 40 ],
"umbrella": [ 190, -50, 25 ]
},
"8": {
"location": [ 5, 12, "t0_14b_tf" ],
"column": [ 5, 59 ],
"day": [ 30, 18, "fonts/twcondensed20", 41, 108 ],
"icon": [ 30, 55, 30 ],
"wind": [ 18, 26 ],
"line": [ 20, 128 ]
},
"9": {
"title": [ 2, 0, "bahnschrift20.vlw", 25 ],
"items": 8,
"line": [ 1, 25, "REFSAN12.vlw" ],
"desc": [ 0, 5, "", 1 ]
},
"10": {
"title": [ 149, 5, "fonts/bahnschrift20" ],
"pos": [ 149, 27 ]
},
"11": {
"mode": 0,
"days": 1,
"title": [ 5, 2, "fonts/bahnschrift20" ],
"date": [ 290, 2 ],
"items": 7,
"red": [ 0, 21, 296, 14 ],
"line": [ 5, 32, 15, "t0_14b_tf", 50 ]
},
"21": [
{ "text": [ 5, 5, "OpenEpaperLink AP", "bahnschrift20", 1, 0, 0 ] },
{ "text": [ 5, 50, "IP address:", "t0_14b_tf", 1, 0, 0 ] },
{ "text": [ 120, 50, "{ap_ip}", "t0_14b_tf", 1, 0, 0 ] },
{ "text": [ 5, 70, "Channel:", "t0_14b_tf", 1, 0, 0 ] },
{ "text": [ 120, 70, "{ap_ch}", "t0_14b_tf", 1, 0, 0 ] },
{ "text": [ 5, 90, "Tag count:", "t0_14b_tf", 1, 0, 0 ] },
{ "text": [ 120, 90, "{ap_tagcount}", "t0_14b_tf", 1, 0, 0 ] }
],
"27": {
"bars": [ 9, 288, 90, 11 ],
"time": [ "tahoma9.vlw" ],
"yaxis": [ "tahoma9.vlw", 0, 6 ],
"head": [ "calibrib30.vlw" ]
}
}
}

View File

@@ -0,0 +1,25 @@
{
"version": 1,
"name": "M3 1.6\" 200px BWRY",
"width": 200,
"height": 200,
"rotatebuffer": 0,
"bpp": 2,
"colortable": {
"white": [ 255, 255, 255 ],
"black": [ 0, 0, 0 ],
"red": [ 255, 0, 0 ],
"yellow": [ 255, 255, 0 ]
},
"perceptual": {
"white": [ 255, 255, 255 ],
"black": [ 0, 0, 0 ],
"red": [ 255, 0, 0 ],
"yellow": [ 200, 200, 0 ]
},
"shortlut": 0,
"zlib_compression": "27",
"options": [ "led" ],
"contentids": [ 22, 23, 1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 14, 16, 17, 18, 19, 20, 21, 27 ],
"usetemplate": 48
}

View File

@@ -0,0 +1,25 @@
{
"version": 1,
"name": "M3 2.2\" BWRY",
"width": 296,
"height": 160,
"rotatebuffer": 3,
"bpp": 2,
"colortable": {
"white": [ 255, 255, 255 ],
"black": [ 0, 0, 0 ],
"red": [ 255, 0, 0 ],
"yellow": [ 255, 255, 0 ]
},
"perceptual": {
"white": [ 255, 255, 255 ],
"black": [ 0, 0, 0 ],
"red": [ 255, 0, 0 ],
"yellow": [ 200, 200, 0 ]
},
"shortlut": 0,
"zlib_compression": "27",
"options": [ "led" ],
"contentids": [ 22, 23, 1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 14, 16, 17, 18, 19, 20, 21, 27 ],
"usetemplate": 49
}

View File

@@ -0,0 +1,25 @@
{
"version": 1,
"name": "M3 7.5\" BWRY",
"width": 800,
"height": 480,
"rotatebuffer": 0,
"bpp": 2,
"colortable": {
"white": [ 255, 255, 255 ],
"black": [ 0, 0, 0 ],
"red": [ 255, 0, 0 ],
"yellow": [ 255, 255, 0 ]
},
"perceptual": {
"white": [ 255, 255, 255 ],
"black": [ 0, 0, 0 ],
"red": [ 255, 0, 0 ],
"yellow": [ 200, 200, 0 ]
},
"shortlut": 0,
"zlib_compression": "27",
"options": [ "led" ],
"contentids": [ 22, 23, 1, 4, 5, 7, 8, 9, 10, 11, 17, 18, 19, 20 ],
"usetemplate": 54
}

View File

@@ -0,0 +1,25 @@
{
"version": 3,
"name": "M3 11.6\" BWRY",
"width": 960,
"height": 640,
"rotatebuffer": 0,
"bpp": 2,
"colortable": {
"white": [ 255, 255, 255 ],
"black": [ 0, 0, 0 ],
"red": [ 255, 0, 0 ],
"yellow": [ 255, 255, 0 ]
},
"perceptual": {
"white": [ 255, 255, 255 ],
"black": [ 0, 0, 0 ],
"red": [ 255, 0, 0 ],
"yellow": [ 200, 200, 0 ]
},
"shortlut": 0,
"zlib_compression": "27",
"options": [ "led" ],
"contentids": [ 22, 23, 1, 4, 5, 7, 8, 9, 10, 11, 17, 18, 19, 20 ],
"usetemplate": 55
}

View File

@@ -0,0 +1,18 @@
{
"version": 2,
"name": "M3 2.6\" BW",
"width": 360,
"height": 184,
"rotatebuffer": 3,
"bpp": 1,
"colortable": {
"white": [ 255, 255, 255 ],
"black": [ 0, 0, 0 ]
},
"highlight_color": 5,
"shortlut": 0,
"zlib_compression": "27",
"options": [ "button", "led" ],
"contentids": [ 22, 23, 1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 16, 17, 18, 19, 20, 26, 27 ],
"usetemplate": 1
}

View File

@@ -1,5 +1,5 @@
{ {
"version": 3, "version": 4,
"name": "HS BW 2.13\"", "name": "HS BW 2.13\"",
"width": 256, "width": 256,
"height": 128, "height": 128,
@@ -12,7 +12,7 @@
"shortlut": 0, "shortlut": 0,
"zlib_compression": "27", "zlib_compression": "27",
"options": [ "led" ], "options": [ "led" ],
"contentids": [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 14, 16, 17, 19, 20, 21, 22, 23, 27 ], "contentids": [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 14, 16, 17, 19, 20, 21, 22, 23, 27, 29 ],
"template": { "template": {
"1": { "1": {

View File

@@ -1,5 +1,5 @@
{ {
"version": 4, "version": 5,
"name": "HS BWR 2.13\"", "name": "HS BWR 2.13\"",
"width": 256, "width": 256,
"height": 128, "height": 128,
@@ -13,7 +13,7 @@
"shortlut": 0, "shortlut": 0,
"zlib_compression": "27", "zlib_compression": "27",
"options": [ "led" ], "options": [ "led" ],
"contentids": [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 14, 16, 17, 19, 20, 21, 22, 23, 27 ], "contentids": [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 14, 16, 17, 19, 20, 21, 22, 23, 27, 29 ],
"template": { "template": {
"1": { "1": {

View File

@@ -1,5 +1,5 @@
{ {
"version": 5, "version": 6,
"name": "HS BWR 2.66\"", "name": "HS BWR 2.66\"",
"width": 296, "width": 296,
"height": 152, "height": 152,
@@ -13,7 +13,7 @@
"shortlut": 0, "shortlut": 0,
"zlib_compression": "27", "zlib_compression": "27",
"options": [ "led" ], "options": [ "led" ],
"contentids": [ 22, 23, 1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 16, 17, 18, 19, 20, 21, 27 ], "contentids": [ 22, 23, 1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 16, 17, 18, 19, 20, 21, 27, 29 ],
"template": { "template": {
"1": { "1": {
"weekday": [ 148, 9, "Signika-SB.ttf", 60 ], "weekday": [ 148, 9, "Signika-SB.ttf", 60 ],

View File

@@ -12,7 +12,7 @@
}, },
"shortlut": 2, "shortlut": 2,
"zlib_compression": "27", "zlib_compression": "27",
"options": ["button", "customlut"], "options": [ "button" ],
"contentids": [ 22, 23, 1, 2, 3, 4, 5, 7, 10, 14, 17, 18, 19, 20, 21], "contentids": [ 22, 23, 1, 2, 3, 4, 5, 7, 10, 14, 17, 18, 19, 20, 21],
"template": { "template": {
"1": { "1": {

View File

@@ -1,5 +1,5 @@
{ {
"version": 5, "version": 6,
"name": "HS BWY 3.5\"", "name": "HS BWY 3.5\"",
"width": 384, "width": 384,
"height": 184, "height": 184,
@@ -19,7 +19,7 @@
"shortlut": 0, "shortlut": 0,
"zlib_compression": "27", "zlib_compression": "27",
"options": [ "led" ], "options": [ "led" ],
"contentids": [ 22, 23, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 14, 17, 18, 19, 20, 27 ], "contentids": [ 22, 23, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 14, 17, 18, 19, 20, 27, 29 ],
"usetemplate": 51, "usetemplate": 51,
"template": { "template": {
"27": { "27": {

View File

@@ -1,5 +1,5 @@
{ {
"version": 3, "version": 4,
"name": "HS BWR 3.5\"", "name": "HS BWR 3.5\"",
"width": 384, "width": 384,
"height": 184, "height": 184,
@@ -13,6 +13,6 @@
"shortlut": 0, "shortlut": 0,
"zlib_compression": "27", "zlib_compression": "27",
"options": [ "led" ], "options": [ "led" ],
"contentids": [ 22, 23, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 14, 17, 18, 19, 20 ], "contentids": [ 22, 23, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 14, 17, 18, 19, 20, 29 ],
"usetemplate": 51 "usetemplate": 51
} }

View File

@@ -1,5 +1,5 @@
{ {
"version": 3, "version": 4,
"name": "HS BW 3.5\"", "name": "HS BW 3.5\"",
"width": 384, "width": 384,
"height": 184, "height": 184,
@@ -13,6 +13,6 @@
"shortlut": 0, "shortlut": 0,
"zlib_compression": "27", "zlib_compression": "27",
"options": [ "led" ], "options": [ "led" ],
"contentids": [ 22, 23, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 14, 17, 18, 19, 20 ], "contentids": [ 22, 23, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 14, 17, 18, 19, 20, 29 ],
"usetemplate": 51 "usetemplate": 51
} }

View File

@@ -1,5 +1,5 @@
{ {
"version": 5, "version": 6,
"name": "TLSR BWR 4.2\"", "name": "TLSR BWR 4.2\"",
"width": 400, "width": 400,
"height": 300, "height": 300,
@@ -13,71 +13,6 @@
"shortlut": 0, "shortlut": 0,
"zlib_compression": "27", "zlib_compression": "27",
"options": ["led"], "options": ["led"],
"contentids": [ 22, 23, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 14, 17, 18, 19, 20 ], "contentids": [ 22, 23, 1, 4, 5, 7, 8, 9, 10, 11, 17, 18, 19, 20, 27 ],
"usetemplate": 2
"template": {
"1": {
"weekday": [ 200, 0, "Signika-SB.ttf", 70 ],
"month": [ 200, 210, "Signika-SB.ttf", 70 ],
"day": [ 200, 45, "Signika-SB.ttf", 170 ]
},
"2": {
"fonts": [ "Signika-SB.ttf", 150, 150, 150, 120, 100, 80 ],
"xy": [ 148, 53 ]
},
"4": {
"location": [ 20, 20, "fonts/calibrib30" ],
"wind": [ 90, 83, "fonts/calibrib50" ],
"temp": [ 20, 170, "fonts/calibrib100" ],
"icon": [ 385, 0, 100, 2 ],
"dir": [ 40, 50, 80 ],
"umbrella": [ 325, 155, 78 ]
},
"8": {
"location": [ 10, 10, "fonts/calibrib30" ],
"column": [ 6, 66 ],
"day": [ 33, 60, "fonts/bahnschrift20", 104, 230 ],
"rain": [ 34, 260 ],
"icon": [ 32, 145, 30 ],
"wind": [ 17, 90 ],
"line": [ 50, 300 ]
},
"9": {
"title": [ 6, 0, "Signika-SB.ttf", 25 ],
"items": 4,
"line": [ 9, 40, "calibrib16.vlw" ],
"desc": [ 2, 8, "REFSAN12.vlw", 1.2 ]
},
"10": {
"title": [ 200, 10, "fonts/bahnschrift20" ],
"pos": [ 200, 35 ]
},
"11": {
"rotate": 0,
"mode": 1,
"days": 4,
"gridparam": [ 5, 17, 20, "calibrib16.vlw", "tahoma9.vlw", 14 ]
},
"16": {
"location": [ 5, 5, "fonts/bahnschrift30" ],
"title": [ 247, 11, "glasstown_nbp_tf" ],
"cols": [ 1, 125, 12, "glasstown_nbp_tf" ],
"bars": [ 5, 111, 10 ]
},
"27": {
"bars": [ 15, 385, 225, 20, 22 ],
"time": [ "calibrib16.vlw" ],
"yaxis": [ "tahoma9.vlw", 3, 6 ],
"head": [ "calibrib30.vlw" ]
},
"21": [
{ "text": [ 5, 5, "OpenEpaperLink AP", "bahnschrift20", 1, 0, 0 ] },
{ "text": [ 5, 50, "IP address:", "t0_14b_tf", 1, 0, 0 ] },
{ "text": [ 120, 50, "{ap_ip}", "t0_14b_tf", 1, 0, 0 ] },
{ "text": [ 5, 70, "Channel:", "t0_14b_tf", 1, 0, 0 ] },
{ "text": [ 120, 70, "{ap_ch}", "t0_14b_tf", 1, 0, 0 ] },
{ "text": [ 5, 90, "Tag count:", "t0_14b_tf", 1, 0, 0 ] },
{ "text": [ 120, 90, "{ap_tagcount}", "t0_14b_tf", 1, 0, 0 ] }
]
}
} }

View File

@@ -18,7 +18,7 @@
"highlight_color": 3, "highlight_color": 3,
"shortlut": 2, "shortlut": 2,
"zlib_compression": "27", "zlib_compression": "27",
"options": [ "button", "customlut" ], "options": [ "button" ],
"contentids": [ 22, 23, 1, 2, 3, 4, 5, 7, 10, 14, 17, 18, 19, 20, 21 ], "contentids": [ 22, 23, 1, 2, 3, 4, 5, 7, 10, 14, 17, 18, 19, 20, 21 ],
"template": { "template": {
"1": { "1": {

View File

@@ -1,5 +1,5 @@
{ {
"version": 3, "version": 4,
"name": "TLSR BW 2.13\"", "name": "TLSR BW 2.13\"",
"width": 250, "width": 250,
"height": 136, "height": 136,
@@ -12,7 +12,7 @@
"shortlut": 0, "shortlut": 0,
"zlib_compression": "27", "zlib_compression": "27",
"options": [ "led" ], "options": [ "led" ],
"contentids": [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 14, 16, 17, 19, 20, 21, 22, 23, 27 ], "contentids": [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 14, 16, 17, 19, 20, 21, 22, 23, 27, 29 ],
"template": { "template": {
"1": { "1": {

View File

@@ -0,0 +1,41 @@
{
"version": 1,
"name": "HS BWR 5,83\"",
"width": 648,
"height": 480,
"rotatebuffer": 0,
"bpp": 2,
"colortable": {
"white": [ 255, 255, 255 ],
"black": [ 0, 0, 0 ],
"red": [ 255, 0, 0 ]
},
"shortlut": 0,
"zlib_compression": "27",
"options": [ "button", "led" ],
"contentids": [ 22, 23, 1, 4, 5, 8, 9, 7, 19, 10, 11 ],
"usetemplate": 1,
"template": {
"1": {
"weekday": [ 300, 0, "Signika-SB.ttf", 110 ],
"month": [ 300, 310, "Signika-SB.ttf", 110 ],
"day": [ 300, 75, "Signika-SB.ttf", 250 ]
},
"10": {
"title": [ 300, 10, "fonts/bahnschrift30" ],
"pos": [ 300, 50 ]
},
"9": {
"title": [ 6, 0, "Signika-SB.ttf", 32 ],
"items": 6,
"line": [ 9, 40, "calibrib16.vlw" ],
"desc": [ 2, 8, "REFSAN12.vlw", 1.2 ]
},
"11": {
"rotate": 0,
"mode": 1,
"days": 7,
"gridparam": [ 7, 17, 30, "calibrib16.vlw", "tahoma9.vlw", 14 ]
}
}
}

View File

@@ -0,0 +1,25 @@
{
"version": 3,
"name": "HS BWRY 7,5\"",
"width": 800,
"height": 480,
"rotatebuffer": 2,
"bpp": 2,
"colortable": {
"white": [ 255, 255, 255 ],
"black": [ 0, 0, 0 ],
"red": [ 255, 0, 0 ],
"yellow": [ 255, 255, 0 ]
},
"perceptual": {
"white": [ 255, 255, 255 ],
"black": [ 0, 0, 0 ],
"red": [ 255, 0, 0 ],
"yellow": [ 255, 255, 0 ]
},
"shortlut": 0,
"zlib_compression": "27",
"options": [ "button", "led" ],
"contentids": [ 22, 23, 1, 4, 5, 7, 8, 9, 10, 11, 17, 18, 19, 20 ],
"usetemplate": 54
}

View File

@@ -0,0 +1,57 @@
{
"version": 3,
"name": "HS BWRY 2,00\"",
"width": 152,
"height": 200,
"rotatebuffer": 1,
"bpp": 2,
"colortable": {
"white": [ 255, 255, 255 ],
"black": [ 0, 0, 0 ],
"red": [ 255, 0, 0 ],
"yellow": [ 255, 255, 0 ]
},
"perceptual": {
"white": [ 255, 255, 255 ],
"black": [ 0, 0, 0 ],
"red": [ 255, 0, 0 ],
"yellow": [ 255, 255, 0 ]
},
"shortlut": 0,
"zlib_compression": "27",
"options": [ "button", "led" ],
"contentids": [ 22, 23, 1, 2, 3, 4, 5, 7, 10, 14, 17, 18, 19, 20, 21 ],
"template": {
"1": {
"weekday": [ 76, 9, "fonts/calibrib30" ],
"month": [ 76, 120, "fonts/calibrib30" ],
"day": [ 76, 13, "Signika-SB.ttf", 100 ]
},
"2": {
"fonts": [ "Signika-SB.ttf", 150, 110, 80, 60, 50, 40 ],
"xy": [ 76, 65 ]
},
"4": {
"location": [ 10, 145, "t0_14b_tf" ],
"wind": [ 140, 10, "fonts/bahnschrift30" ],
"temp": [ 10, 10, "fonts/bahnschrift30" ],
"icon": [ 75, 26, 70, 1 ],
"dir": [ 110, -12, 40 ],
"umbrella": [ 125, 110, 30 ]
},
"10": {
"title": [ 76, 15, "t0_14b_tf" ],
"pos": [ 76, 20 ]
},
"21": [
{ "text": [ 2, 5, "OpenEpaperLink", "bahnschrift20", 1, 0, 0 ] },
{ "text": [ 2, 25, "Access Point", "bahnschrift20", 1, 0, 0 ] },
{ "text": [ 3, 65, "IP address:", "glasstown_nbp_tf", 1, 0, 0 ] },
{ "text": [ 10, 80, "{ap_ip}", "t0_14b_tf", 1, 0, 0 ] },
{ "text": [ 3, 95, "Channel:", "glasstown_nbp_tf", 1, 0, 0 ] },
{ "text": [ 10, 110, "{ap_ch}", "t0_14b_tf", 1, 0, 0 ] },
{ "text": [ 3, 125, "Tag count:", "glasstown_nbp_tf", 1, 0, 0 ] },
{ "text": [ 10, 140, "{ap_tagcount}", "t0_14b_tf", 1, 0, 0 ] }
]
}
}

View File

@@ -0,0 +1,33 @@
{
"version": 3,
"name": "HS BWRY 3,5\"",
"width": 384,
"height": 184,
"rotatebuffer": 1,
"bpp": 2,
"colortable": {
"white": [ 255, 255, 255 ],
"black": [ 0, 0, 0 ],
"red": [ 255, 0, 0 ],
"yellow": [ 255, 255, 0 ]
},
"perceptual": {
"white": [ 255, 255, 255 ],
"black": [ 0, 0, 0 ],
"red": [ 255, 0, 0 ],
"yellow": [ 255, 255, 0 ]
},
"shortlut": 0,
"zlib_compression": "27",
"options": [ "button", "led" ],
"contentids": [ 22, 23, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 14, 17, 18, 19, 20, 27, 29 ],
"usetemplate": 51,
"template": {
"27": {
"bars": [ 12, 360, 125, 20 ],
"time": [ "calibrib16.vlw" ],
"yaxis": [ "tahoma9.vlw", 1, 6 ],
"head": [ "calibrib30.vlw" ]
}
}
}

View File

@@ -0,0 +1,24 @@
{
"version": 3,
"name": "HS BWRY 2,9\"",
"width": 296,
"height": 128,
"rotatebuffer": 1,
"bpp": 2,
"colortable": {
"white": [ 255, 255, 255 ],
"black": [ 0, 0, 0 ],
"red": [ 255, 0, 0 ],
"yellow": [ 255, 255, 0 ]
},
"perceptual": {
"white": [ 255, 255, 255 ],
"black": [ 0, 0, 0 ],
"red": [ 255, 0, 0 ],
"yellow": [ 255, 255, 0 ]
},
"zlib_compression": "27",
"options": [ "button", "led" ],
"contentids": [ 22, 23, 1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 16, 17, 18, 19, 20, 21, 27 ],
"usetemplate": 1
}

View File

@@ -0,0 +1,91 @@
{
"version": 2,
"name": "HS BWRY 2,60\"",
"width": 296,
"height": 152,
"rotatebuffer": 1,
"bpp": 2,
"colortable": {
"white": [ 255, 255, 255 ],
"black": [ 0, 0, 0 ],
"red": [ 255, 0, 0 ],
"yellow": [ 255, 255, 0 ]
},
"perceptual": {
"white": [ 255, 255, 255 ],
"black": [ 0, 0, 0 ],
"red": [ 255, 0, 0 ],
"yellow": [ 255, 255, 0 ]
},
"shortlut": 0,
"zlib_compression": "27",
"options": [ "button", "led" ],
"contentids": [ 22, 23, 1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 16, 17, 18, 19, 20, 21, 27, 29 ],
"template": {
"1": {
"weekday": [ 148, 9, "Signika-SB.ttf", 60 ],
"date": [ 148, 73, "Signika-SB.ttf", 48 ]
},
"2": {
"fonts": [ "Signika-SB.ttf", 170, 170, 170, 120, 100, 80 ],
"xy": [ 148, 62 ]
},
"16": {
"location": [ 5, 5, "fonts/bahnschrift30" ],
"title": [ 247, 11, "glasstown_nbp_tf" ],
"cols": [ 1, 149, 12, "glasstown_nbp_tf" ],
"bars": [ 5, 135, 10 ]
},
"4": {
"location": [ 5, 5, "fonts/bahnschrift30" ],
"wind": [ 280, 5, "fonts/bahnschrift30" ],
"temp": [ 5, 58, "fonts/calibrib90" ],
"icon": [ 280, 35, 80, 2 ],
"dir": [ 235, -12, 40 ],
"umbrella": [ 190, -30, 25 ]
},
"8": {
"location": [ 5, 12, "t0_14b_tf" ],
"column": [ 5, 59 ],
"day": [ 30, 20, "fonts/twcondensed20", 41, 105 ],
"rain": [ 34, 130 ],
"icon": [ 30, 55, 30 ],
"wind": [ 18, 26 ],
"line": [ 20, 150 ]
},
"9": {
"title": [ 3, 2, "bahnschrift20.vlw", 25 ],
"items": 8,
"line": [ 3, 25, "REFSAN12.vlw" ],
"desc": [ 0, 5, "", 1 ]
},
"10": {
"title": [ 149, 5, "fonts/bahnschrift20" ],
"pos": [ 149, 27 ]
},
"11": {
"mode": 0,
"days": 1,
"title": [ 5, 2, "fonts/bahnschrift20" ],
"date": [ 290, 2 ],
"items": 9,
"red": [ 0, 21, 296, 14 ],
"line": [ 5, 32, 15, "t0_14b_tf", 50 ]
},
"21": [
{ "text": [ 5, 5, "OpenEpaperLink AP", "bahnschrift20", 1, 0, 0 ] },
{ "text": [ 5, 50, "IP address:", "t0_14b_tf", 1, 0, 0 ] },
{ "text": [ 120, 50, "{ap_ip}", "t0_14b_tf", 1, 0, 0 ] },
{ "text": [ 5, 70, "Channel:", "t0_14b_tf", 1, 0, 0 ] },
{ "text": [ 120, 70, "{ap_ch}", "t0_14b_tf", 1, 0, 0 ] },
{ "text": [ 5, 90, "Tag count:", "t0_14b_tf", 1, 0, 0 ] },
{ "text": [ 120, 90, "{ap_tagcount}", "t0_14b_tf", 1, 0, 0 ] }
],
"27": {
"bars": [ 9, 288, 90, 11, 15 ],
"time": [ "tahoma9.vlw" ],
"yaxis": [ "tahoma9.vlw", 0, 6 ],
"head": [ "calibrib30.vlw" ]
}
}
}

5
resources/tagtypes/81.json Normal file → Executable file
View File

@@ -1,5 +1,5 @@
{ {
"version": 1, "version": 2,
"name": "Chroma Aeon 74 7.4\"", "name": "Chroma Aeon 74 7.4\"",
"width": 800, "width": 800,
"height": 480, "height": 480,
@@ -12,5 +12,6 @@
}, },
"shortlut": 0, "shortlut": 0,
"contentids": [ 22, 23, 1, 4, 5, 7, 8, 9, 10, 11, 17, 18, 19, 20 ], "contentids": [ 22, 23, 1, 4, 5, 7, 8, 9, 10, 11, 17, 18, 19, 20 ],
"usetemplate": 54 "usetemplate": 54,
"zlib_compression": "3"
} }

View File

@@ -10,7 +10,7 @@
"black": [ 0, 0, 0 ] "black": [ 0, 0, 0 ]
}, },
"shortlut": 0, "shortlut": 0,
"options": [ "button", "customlut" ], "options": [ "button" ],
"contentids": [ 22, 23, 1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 16, 17, 18, 19, 20, 21 ], "contentids": [ 22, 23, 1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 16, 17, 18, 19, 20, 21 ],
"usetemplate": 1 "usetemplate": 1
} }

View File

@@ -1,5 +1,5 @@
{ {
"version": 1, "version": 2,
"name": "TFT 320x172", "name": "TFT 320x172",
"width": 320, "width": 320,
"height": 172, "height": 172,
@@ -23,7 +23,8 @@
{ "text": [ 10, 95, "Channel:", "bahnschrift20", "#888888", 0, 0, 1 ] }, { "text": [ 10, 95, "Channel:", "bahnschrift20", "#888888", 0, 0, 1 ] },
{ "text": [ 120, 95, "{ap_ch}", "bahnschrift20", 0, 0, 0, "1" ] }, { "text": [ 120, 95, "{ap_ch}", "bahnschrift20", 0, 0, 0, "1" ] },
{ "text": [ 10, 120, "Tag count:", "bahnschrift20", "#888888", 0, 0, 1 ] }, { "text": [ 10, 120, "Tag count:", "bahnschrift20", "#888888", 0, 0, 1 ] },
{ "text": [ 120, 120, "{ap_tagcount}", "bahnschrift20", 0, 0, 0, "1" ] } { "text": [ 120, 120, "{ap_tagcount}", "bahnschrift20", 0, 0, 0, "1" ] },
{ "ts_option": 17}
] ]
} }
} }

View File

@@ -1,5 +1,5 @@
{ {
"version": 1, "version": 2,
"name": "TFT 160x80", "name": "TFT 160x80",
"width": 160, "width": 160,
"height": 80, "height": 80,
@@ -22,7 +22,8 @@
{ "text": [ 1, 45, "Ch:", "REFSAN12.vlw", "#888888", 0, 0, 1 ] }, { "text": [ 1, 45, "Ch:", "REFSAN12.vlw", "#888888", 0, 0, 1 ] },
{ "text": [ 45, 45, "{ap_ch}", "REFSAN12.vlw", 0, 0, 0, "1" ] }, { "text": [ 45, 45, "{ap_ch}", "REFSAN12.vlw", 0, 0, 0, "1" ] },
{ "text": [ 1, 62, "Tags:", "REFSAN12.vlw", "#888888", 0, 0, 1 ] }, { "text": [ 1, 62, "Tags:", "REFSAN12.vlw", "#888888", 0, 0, 1 ] },
{ "text": [ 45, 62, "{ap_tagcount}", "REFSAN12.vlw", 0, 0, 0, "1" ] } { "text": [ 45, 62, "{ap_tagcount}", "REFSAN12.vlw", 0, 0, 0, "1" ] },
{ "ts_option": 25}
] ]
} }
} }